Compare commits

..

22 Commits

Author SHA1 Message Date
Rainer Killinger
db347bf324 0.54.0 2021-11-17 11:37:56 +01:00
Rainer Killinger
7a2e0f20d1 feat: add SCAssessment 2021-11-16 10:56:28 +01:00
Jovan Krunić
b2d18da82a docs: update changelog 2021-10-19 16:09:46 +02:00
Jovan Krunić
fae7395cf0 0.53.0 2021-10-19 16:09:45 +02:00
Jovan Krunić
0745b1af72 refactor: adjust http status of feedback route 2021-10-12 16:50:19 +02:00
Jovan Krunić
a2b2cefe8e refactor: adjust depricated use of http-status-codes 2021-10-12 16:48:42 +02:00
wulkanat@gmail.com
04b21a7c5d docs: update changelog 2021-09-28 16:02:23 +02:00
wulkanat@gmail.com
ca7626db17 0.52.0 2021-09-28 16:02:14 +02:00
Wieland Schöbl
e8d492a18a test: add test to make sure there are no duplicate names 2021-09-27 09:06:40 +00:00
Wieland Schöbl
aa294c4e29 feat: add about config 2021-09-23 12:40:50 +00:00
Jovan Krunić
369bb906c1 docs: update changelog 2021-09-10 14:15:06 +02:00
Jovan Krunić
aa38fef293 0.51.0 2021-09-10 14:15:05 +02:00
Jovan Krunić
ded8e7dfd5 fix: add physicalobject to book categories 2021-09-10 14:13:28 +02:00
Jovan Krunić
d47897c7e8 docs: update changelog 2021-09-01 13:56:46 +02:00
Jovan Krunić
9ab5280b2e 0.50.0 2021-09-01 13:56:44 +02:00
Wieland Schöbl
596788f3a1 test: migrate schema.spec.ts from TypeDoc to Easy AST 2021-09-01 11:40:32 +00:00
Rainer Killinger
70271a4849 docs: update changelog 2021-08-27 17:27:23 +02:00
Rainer Killinger
98ab64403f 0.49.5 2021-08-27 17:27:21 +02:00
Rainer Killinger
3d1bb6ef13 docs: update changelog 2021-08-27 17:25:06 +02:00
Rainer Killinger
d5f39517e8 0.49.4 2021-08-27 17:20:40 +02:00
Rainer Killinger
dfe35d71a3 fix: test resources from hds2 2021-08-27 17:19:25 +02:00
wulkanat@gmail.com
cdaa83122f docs: update changelog 2021-08-18 09:57:29 +02:00
47 changed files with 1455 additions and 702 deletions

View File

@@ -1,3 +1,42 @@
# [0.53.0](https://gitlab.com/openstapps/core/compare/v0.52.0...v0.53.0) (2021-10-19)
# [0.52.0](https://gitlab.com/openstapps/core/compare/v0.51.0...v0.52.0) (2021-09-28)
### Features
* add about config ([aa294c4](https://gitlab.com/openstapps/core/commit/aa294c4e29e9191bef6d79487b0b321fbc34f6fb))
# [0.51.0](https://gitlab.com/openstapps/core/compare/v0.50.0...v0.51.0) (2021-09-10)
### Bug Fixes
* add physicalobject to book categories ([ded8e7d](https://gitlab.com/openstapps/core/commit/ded8e7dfd51094c02a86e1383a4e94c069c10e64))
# [0.50.0](https://gitlab.com/openstapps/core/compare/v0.49.5...v0.50.0) (2021-09-01)
## [0.49.5](https://gitlab.com/openstapps/core/compare/v0.49.3...v0.49.5) (2021-08-27)
### Bug Fixes
* test resources from hds2 ([dfe35d7](https://gitlab.com/openstapps/core/commit/dfe35d71a38c35064726365f99714abff3b30ba6))
## [0.49.3](https://gitlab.com/openstapps/core/compare/v0.49.2...v0.49.3) (2021-08-18)
## [0.49.2](https://gitlab.com/openstapps/core/compare/v0.49.1...v0.49.2) (2021-08-17) ## [0.49.2](https://gitlab.com/openstapps/core/compare/v0.49.1...v0.49.2) (2021-08-17)

805
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "@openstapps/core", "name": "@openstapps/core",
"version": "0.49.3", "version": "0.54.0",
"description": "StAppsCore - Generalized model of data", "description": "StAppsCore - Generalized model of data",
"keywords": [ "keywords": [
"Model", "Model",
@@ -45,7 +45,7 @@
"Wieland Schöbl" "Wieland Schöbl"
], ],
"dependencies": { "dependencies": {
"@openstapps/core-tools": "0.23.2", "@openstapps/core-tools": "0.25.0",
"@types/geojson": "1.0.6", "@types/geojson": "1.0.6",
"@types/json-patch": "0.0.30", "@types/json-patch": "0.0.30",
"@types/json-schema": "7.0.9", "@types/json-schema": "7.0.9",
@@ -62,11 +62,14 @@
"@openstapps/es-mapping-generator": "0.0.3", "@openstapps/es-mapping-generator": "0.0.3",
"@openstapps/logger": "0.7.0", "@openstapps/logger": "0.7.0",
"@testdeck/mocha": "0.1.2", "@testdeck/mocha": "0.1.2",
"@types/lodash": "4.14.172",
"@types/chai": "4.2.21", "@types/chai": "4.2.21",
"@types/rimraf": "3.0.1", "@types/rimraf": "3.0.1",
"@types/mocha": "8.2.3",
"chai": "4.3.4", "chai": "4.3.4",
"conditional-type-checks": "1.0.5", "conditional-type-checks": "1.0.5",
"conventional-changelog-cli": "2.1.1", "conventional-changelog-cli": "2.1.1",
"lodash": "4.17.21",
"mocha": "8.4.0", "mocha": "8.4.0",
"nyc": "15.1.0", "nyc": "15.1.0",
"rimraf": "3.0.2", "rimraf": "3.0.2",
@@ -74,7 +77,7 @@
"surge": "0.23.0", "surge": "0.23.0",
"ts-node": "9.1.1", "ts-node": "9.1.1",
"tslint": "6.1.3", "tslint": "6.1.3",
"typedoc": "0.21.5", "typedoc": "0.21.6",
"typescript": "4.3.5" "typescript": "4.3.5"
}, },
"nyc": { "nyc": {

View File

@@ -15,6 +15,7 @@
// tslint:disable-next-line:no-implicit-dependencies // tslint:disable-next-line:no-implicit-dependencies
import {Polygon} from 'geojson'; import {Polygon} from 'geojson';
import {SCTranslations} from '../general/i18n'; import {SCTranslations} from '../general/i18n';
import {SCMap} from '../general/map';
import {SCLanguageSetting, SCSetting, SCUserGroupSetting} from '../things/setting'; import {SCLanguageSetting, SCSetting, SCUserGroupSetting} from '../things/setting';
/** /**
@@ -80,6 +81,13 @@ export interface SCAppConfigurationMenuCategory {
* An app configuration * An app configuration
*/ */
export interface SCAppConfiguration { export interface SCAppConfiguration {
/**
* The about page
*
* Mapping route -> page config
*/
aboutPages: SCMap<SCAboutPage>;
/** /**
* Polygon that encapsulates the main campus * Polygon that encapsulates the main campus
*/ */
@@ -174,3 +182,147 @@ export interface SCAppConfigurationMenuCategoryTranslationName {
*/ */
name: string; name: string;
} }
export enum SCAboutPageContentType {
SECTION = 'section',
ROUTER_LINK = 'router link',
TABLE = 'table',
MARKDOWN = 'markdown',
}
export interface SCAboutPageTranslationTitle {
/**
* Translation of the title
*/
title: string;
}
export interface SCAboutPageTranslationValue {
/**
* Translation of the value
*/
value: string;
}
/**
* A (mostly) self-contained section, akin to markdown `# Title`
*/
export interface SCAboutPageSection {
/**
* If the section should be contained in a card
*/
card?: true;
/**
* The content of the section
*/
content: SCAboutPageContent;
/**
* The title of the section
*/
title: string;
/**
* Translations
*/
translations: SCTranslations<SCAboutPageTranslationTitle>;
/**
* Type
*/
type: SCAboutPageContentType.SECTION;
}
/**
* A router link that can lead to a new page
*
* For external links, prefer markdown `[destination](link)`
*/
export interface SCAboutPageRouterLink {
/**
* Icon of the destination
*/
icon?: string;
/**
* Router link
*/
link: string;
/**
* Title of the destination
*/
title: string;
/**
* Translations
*/
translations: SCTranslations<SCAboutPageTranslationTitle>;
/**
* Type
*/
type: SCAboutPageContentType.ROUTER_LINK;
}
/**
* A simple table element
*/
export interface SCAboutPageTable {
/**
* Rows of the table
*/
rows: SCAboutPageContent[][];
/**
* Type
*/
type: SCAboutPageContentType.TABLE;
}
/**
* A markdown element
*/
export interface SCAboutPageMarkdown {
/**
* Translations
*/
translations: SCTranslations<SCAboutPageTranslationValue>;
/**
* Type
*/
type: SCAboutPageContentType.MARKDOWN;
/**
* Value (Markdown)
*/
value: string;
}
export type SCAboutPageContent =
| SCAboutPageMarkdown
| SCAboutPageTable
| SCAboutPageSection
| SCAboutPageRouterLink;
/**
* Root of the about page
*/
export interface SCAboutPage {
/**
* Content of the page
*/
content: SCAboutPageContent[];
/**
* Header (title) of the page
*/
title: string;
/**
* Translations
*/
translations: SCTranslations<SCAboutPageTranslationTitle>;
}

View File

@@ -15,11 +15,12 @@
import {SCThingType} from './things/abstract/thing'; import {SCThingType} from './things/abstract/thing';
import {SCAcademicEvent, SCAcademicEventMeta, SCAcademicEventWithoutReferences} from './things/academic-event'; import {SCAcademicEvent, SCAcademicEventMeta, SCAcademicEventWithoutReferences} from './things/academic-event';
import {SCArticle, SCArticleMeta, SCArticleWithoutReferences} from './things/article'; import {SCArticle, SCArticleMeta, SCArticleWithoutReferences} from './things/article';
import {SCAssessment, SCAssessmentMeta, SCAssessmentWithoutReferences} from './things/assessment';
import {SCBook, SCBookMeta, SCBookWithoutReferences} from './things/book'; import {SCBook, SCBookMeta, SCBookWithoutReferences} from './things/book';
import {SCBuilding, SCBuildingMeta, SCBuildingWithoutReferences} from './things/building'; import {SCBuilding, SCBuildingMeta, SCBuildingWithoutReferences} from './things/building';
import {SCCatalog, SCCatalogMeta, SCCatalogWithoutReferences} from './things/catalog'; import {SCCatalog, SCCatalogMeta, SCCatalogWithoutReferences} from './things/catalog';
import {SCContactPoint, SCContactPointMeta, SCContactPointWithoutReferences} from './things/contact-point'; import {SCContactPoint, SCContactPointMeta, SCContactPointWithoutReferences} from './things/contact-point';
import {SCCourseOfStudies, SCCourseOfStudiesMeta, SCCourseOfStudiesWithoutReferences} from './things/course-of-studies'; import {SCCourseOfStudy, SCCourseOfStudyMeta, SCCourseOfStudyWithoutReferences} from './things/course-of-study';
import {SCDateSeries, SCDateSeriesMeta, SCDateSeriesWithoutReferences} from './things/date-series'; import {SCDateSeries, SCDateSeriesMeta, SCDateSeriesWithoutReferences} from './things/date-series';
import {SCDiff, SCDiffMeta, SCDiffWithoutReferences} from './things/diff'; import {SCDiff, SCDiffMeta, SCDiffWithoutReferences} from './things/diff';
import {SCDish, SCDishMeta, SCDishWithoutReferences} from './things/dish'; import {SCDish, SCDishMeta, SCDishWithoutReferences} from './things/dish';
@@ -51,13 +52,14 @@ import {SCVideo, SCVideoMeta, SCVideoWithoutReferences} from './things/video';
*/ */
export const SCClasses: { [K in SCThingType]: object } = { export const SCClasses: { [K in SCThingType]: object } = {
/* tslint:enable */ /* tslint:enable */
'assessment': SCAssessmentMeta,
'academic event': SCAcademicEventMeta, 'academic event': SCAcademicEventMeta,
'article': SCArticleMeta, 'article': SCArticleMeta,
'book': SCBookMeta, 'book': SCBookMeta,
'building': SCBuildingMeta, 'building': SCBuildingMeta,
'catalog': SCCatalogMeta, 'catalog': SCCatalogMeta,
'contact point': SCContactPointMeta, 'contact point': SCContactPointMeta,
'course of studies': SCCourseOfStudiesMeta, 'course of study': SCCourseOfStudyMeta,
'date series': SCDateSeriesMeta, 'date series': SCDateSeriesMeta,
'diff': SCDiffMeta, 'diff': SCDiffMeta,
'dish': SCDishMeta, 'dish': SCDishMeta,
@@ -81,13 +83,14 @@ export const SCClasses: { [K in SCThingType]: object } = {
}; };
export type SCIndexableThings = export type SCIndexableThings =
SCAcademicEvent SCAssessment
| SCAcademicEvent
| SCArticle | SCArticle
| SCBook | SCBook
| SCBuilding | SCBuilding
| SCCatalog | SCCatalog
| SCContactPoint | SCContactPoint
| SCCourseOfStudies | SCCourseOfStudy
| SCDateSeries | SCDateSeries
| SCDish | SCDish
| SCFloor | SCFloor
@@ -122,64 +125,66 @@ export type SCThingsField = keyof SCThings | string;
* Thing without references for a thing * Thing without references for a thing
*/ */
export type SCAssociatedThingWithoutReferences<THING extends SCThings> = export type SCAssociatedThingWithoutReferences<THING extends SCThings> =
THING extends SCAcademicEvent ? SCAcademicEventWithoutReferences : THING extends SCAssessment ? SCAssessmentWithoutReferences :
THING extends SCArticle ? SCArticleWithoutReferences : THING extends SCAcademicEvent ? SCAcademicEventWithoutReferences :
THING extends SCBook ? SCBookWithoutReferences : THING extends SCArticle ? SCArticleWithoutReferences :
THING extends SCBuilding ? SCBuildingWithoutReferences : THING extends SCBook ? SCBookWithoutReferences :
THING extends SCCatalog ? SCCatalogWithoutReferences : THING extends SCBuilding ? SCBuildingWithoutReferences :
THING extends SCContactPoint ? SCContactPointWithoutReferences : THING extends SCCatalog ? SCCatalogWithoutReferences :
THING extends SCCourseOfStudies ? SCCourseOfStudiesWithoutReferences : THING extends SCContactPoint ? SCContactPointWithoutReferences :
THING extends SCDateSeries ? SCDateSeriesWithoutReferences : THING extends SCCourseOfStudy ? SCCourseOfStudyWithoutReferences :
THING extends SCDiff ? SCDiffWithoutReferences : THING extends SCDateSeries ? SCDateSeriesWithoutReferences :
THING extends SCDish ? SCDishWithoutReferences : THING extends SCDiff ? SCDiffWithoutReferences :
THING extends SCFavorite ? SCFavoriteWithoutReferences : THING extends SCDish ? SCDishWithoutReferences :
THING extends SCFloor ? SCFloorWithoutReferences : THING extends SCFavorite ? SCFavoriteWithoutReferences :
THING extends SCMessage ? SCMessageWithoutReferences : THING extends SCFloor ? SCFloorWithoutReferences :
THING extends SCOrganization ? SCOrganizationWithoutReferences : THING extends SCMessage ? SCMessageWithoutReferences :
THING extends SCPeriodical ? SCPeriodicalWithoutReferences : THING extends SCOrganization ? SCOrganizationWithoutReferences :
THING extends SCPerson ? SCPersonWithoutReferences : THING extends SCPeriodical ? SCPeriodicalWithoutReferences :
THING extends SCPointOfInterest ? SCPointOfInterestWithoutReferences : THING extends SCPerson ? SCPersonWithoutReferences :
THING extends SCPublicationEvent ? SCPublicationEventWithoutReferences : THING extends SCPointOfInterest ? SCPointOfInterestWithoutReferences :
THING extends SCRoom ? SCRoomWithoutReferences : THING extends SCPublicationEvent ? SCPublicationEventWithoutReferences :
THING extends SCSemester ? SCSemesterWithoutReferences : THING extends SCRoom ? SCRoomWithoutReferences :
THING extends SCSetting ? SCSettingWithoutReferences : THING extends SCSemester ? SCSemesterWithoutReferences :
THING extends SCSportCourse ? SCSportCourseWithoutReferences : THING extends SCSetting ? SCSettingWithoutReferences :
THING extends SCStudyModule ? SCStudyModuleWithoutReferences : THING extends SCSportCourse ? SCSportCourseWithoutReferences :
THING extends SCTicket ? SCTicketWithoutReferences : THING extends SCStudyModule ? SCStudyModuleWithoutReferences :
THING extends SCToDo ? SCToDoWithoutReferences : THING extends SCTicket ? SCTicketWithoutReferences :
THING extends SCTour ? SCTourWithoutReferences : THING extends SCToDo ? SCToDoWithoutReferences :
THING extends SCVideo ? SCVideoWithoutReferences : THING extends SCTour ? SCTourWithoutReferences :
never; THING extends SCVideo ? SCVideoWithoutReferences :
never;
/** /**
* Thing for a thing without references * Thing for a thing without references
*/ */
export type SCAssociatedThing<THING extends SCThings> = export type SCAssociatedThing<THING extends SCThings> =
THING extends SCAcademicEventWithoutReferences ? SCAcademicEvent : THING extends SCAssessmentWithoutReferences ? SCAssessment :
THING extends SCArticleWithoutReferences ? SCArticle : THING extends SCAcademicEventWithoutReferences ? SCAcademicEvent :
THING extends SCBookWithoutReferences ? SCBook : THING extends SCArticleWithoutReferences ? SCArticle :
THING extends SCBuildingWithoutReferences ? SCBuilding : THING extends SCBookWithoutReferences ? SCBook :
THING extends SCCatalogWithoutReferences ? SCCatalog : THING extends SCBuildingWithoutReferences ? SCBuilding :
THING extends SCContactPointWithoutReferences ? SCContactPoint : THING extends SCCatalogWithoutReferences ? SCCatalog :
THING extends SCCourseOfStudiesWithoutReferences ? SCCourseOfStudies : THING extends SCContactPointWithoutReferences ? SCContactPoint :
THING extends SCDateSeriesWithoutReferences ? SCDateSeries : THING extends SCCourseOfStudyWithoutReferences ? SCCourseOfStudy :
THING extends SCDiffWithoutReferences ? SCDiff : THING extends SCDateSeriesWithoutReferences ? SCDateSeries :
THING extends SCDishWithoutReferences ? SCDish : THING extends SCDiffWithoutReferences ? SCDiff :
THING extends SCFavoriteWithoutReferences ? SCFavorite : THING extends SCDishWithoutReferences ? SCDish :
THING extends SCFloorWithoutReferences ? SCFloor : THING extends SCFavoriteWithoutReferences ? SCFavorite :
THING extends SCMessageWithoutReferences ? SCMessage : THING extends SCFloorWithoutReferences ? SCFloor :
THING extends SCOrganizationWithoutReferences ? SCOrganization : THING extends SCMessageWithoutReferences ? SCMessage :
THING extends SCPeriodicalWithoutReferences ? SCPeriodical : THING extends SCOrganizationWithoutReferences ? SCOrganization :
THING extends SCPersonWithoutReferences ? SCPerson : THING extends SCPeriodicalWithoutReferences ? SCPeriodical :
THING extends SCPointOfInterestWithoutReferences ? SCPointOfInterest : THING extends SCPersonWithoutReferences ? SCPerson :
THING extends SCPublicationEventWithoutReferences ? SCPublicationEvent : THING extends SCPointOfInterestWithoutReferences ? SCPointOfInterest :
THING extends SCRoomWithoutReferences ? SCRoom : THING extends SCPublicationEventWithoutReferences ? SCPublicationEvent :
THING extends SCSemesterWithoutReferences ? SCSemester : THING extends SCRoomWithoutReferences ? SCRoom :
THING extends SCSettingWithoutReferences ? SCSetting : THING extends SCSemesterWithoutReferences ? SCSemester :
THING extends SCSportCourseWithoutReferences ? SCSportCourse : THING extends SCSettingWithoutReferences ? SCSetting :
THING extends SCStudyModuleWithoutReferences ? SCStudyModule : THING extends SCSportCourseWithoutReferences ? SCSportCourse :
THING extends SCTicketWithoutReferences ? SCTicket : THING extends SCStudyModuleWithoutReferences ? SCStudyModule :
THING extends SCToDoWithoutReferences ? SCToDo : THING extends SCTicketWithoutReferences ? SCTicket :
THING extends SCTourWithoutReferences ? SCTour : THING extends SCToDoWithoutReferences ? SCToDo :
THING extends SCVideoWithoutReferences ? SCVideo : THING extends SCTourWithoutReferences ? SCTour :
never; THING extends SCVideoWithoutReferences ? SCVideo :
never;

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {BAD_GATEWAY} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -34,7 +34,7 @@ export class SCInternalServerErrorResponse extends SCError {
* and the internal server error should be displayed to the client * and the internal server error should be displayed to the client
*/ */
constructor(err?: Error, stack = false) { constructor(err?: Error, stack = false) {
super('InternalServerError', 'Internal server error', BAD_GATEWAY, stack); super('InternalServerError', 'Internal server error', StatusCodes.BAD_GATEWAY, stack);
if (stack) { if (stack) {
this.additionalData = err; this.additionalData = err;

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {METHOD_NOT_ALLOWED} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -27,6 +27,6 @@ export class SCMethodNotAllowedErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(stack?: boolean) { constructor(stack?: boolean) {
super('MethodNotAllowedError', 'HTTP method is not allowed on this route', METHOD_NOT_ALLOWED, stack); super('MethodNotAllowedError', 'HTTP method is not allowed on this route', StatusCodes.METHOD_NOT_ALLOWED, stack);
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {NOT_FOUND} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -27,6 +27,6 @@ export class SCNotFoundErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(stack?: boolean) { constructor(stack?: boolean) {
super('NotFoundError', 'Resource not found', NOT_FOUND, stack); super('NotFoundError', 'Resource not found', StatusCodes.NOT_FOUND, stack);
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {NOT_ACCEPTABLE} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -29,6 +29,6 @@ export class SCParametersNotAcceptable extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(message: string, stack?: boolean) { constructor(message: string, stack?: boolean) {
super('ParametersNotAcceptable', message, NOT_ACCEPTABLE, stack); super('ParametersNotAcceptable', message, StatusCodes.NOT_ACCEPTABLE, stack);
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {CONFLICT} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
import {SCPluginMetaData} from '../routes/plugin-register'; import {SCPluginMetaData} from '../routes/plugin-register';
@@ -38,7 +38,7 @@ export class SCPluginAlreadyRegisteredErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(message: string, plugin: SCPluginMetaData, stack = false) { constructor(message: string, plugin: SCPluginMetaData, stack = false) {
super('SCPluginAlreadyRegisteredError', message, CONFLICT, stack); super('SCPluginAlreadyRegisteredError', message, StatusCodes.CONFLICT, stack);
if (stack) { if (stack) {
this.additionalData = plugin; this.additionalData = plugin;
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {INTERNAL_SERVER_ERROR} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -28,6 +28,6 @@ export class SCPluginRegisteringFailedErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(message: string, stack?: boolean) { constructor(message: string, stack?: boolean) {
super('PluginRegisteringFailedError', message, INTERNAL_SERVER_ERROR, stack); super('PluginRegisteringFailedError', message, StatusCodes.INTERNAL_SERVER_ERROR, stack);
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {REQUEST_TOO_LONG} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -27,6 +27,6 @@ export class SCRequestBodyTooLargeErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(stack?: boolean) { constructor(stack?: boolean) {
super('RequestBodyTooLargeError', 'The request body is too large.', REQUEST_TOO_LONG, stack); super('RequestBodyTooLargeError', 'The request body is too large.', StatusCodes.REQUEST_TOO_LONG, stack);
} }
} }

View File

@@ -12,12 +12,12 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {BAD_REQUEST} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
* An error that is returned whenever there is a syntax error * An error that is returned whenever there is a syntax error
* *
* @validatable * @validatable
*/ */
export class SCSyntaxErrorResponse extends SCError { export class SCSyntaxErrorResponse extends SCError {
@@ -28,6 +28,6 @@ export class SCSyntaxErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(message: string, stack?: boolean) { constructor(message: string, stack?: boolean) {
super('SyntaxError', message, BAD_REQUEST, stack); super('SyntaxError', message, StatusCodes.BAD_REQUEST, stack);
} }
} }

View File

@@ -12,12 +12,12 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {TOO_MANY_REQUESTS} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
* An error that is returned, when to many request are submitted at once * An error that is returned, when to many request are submitted at once
* *
* @validatable * @validatable
*/ */
export class SCTooManyRequestsErrorResponse extends SCError { export class SCTooManyRequestsErrorResponse extends SCError {
@@ -30,7 +30,7 @@ export class SCTooManyRequestsErrorResponse extends SCError {
super( super(
'TooManyRequestsError', 'TooManyRequestsError',
'Too many requests. You can not submit more than 5 queries an once', 'Too many requests. You can not submit more than 5 queries an once',
TOO_MANY_REQUESTS, StatusCodes.TOO_MANY_REQUESTS,
stack, stack,
); );
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {UNSUPPORTED_MEDIA_TYPE} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -27,6 +27,6 @@ export class SCUnsupportedMediaTypeErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(stack?: boolean) { constructor(stack?: boolean) {
super('UnsupportedMediaTypeError', 'Unsupported media type', UNSUPPORTED_MEDIA_TYPE, stack); super('UnsupportedMediaTypeError', 'Unsupported media type', StatusCodes.UNSUPPORTED_MEDIA_TYPE, stack);
} }
} }

View File

@@ -12,8 +12,8 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {ValidationError} from '@openstapps/core-tools/lib/common'; import {ValidationError} from '@openstapps/core-tools/lib/types/validator';
import {BAD_REQUEST} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCError} from '../error'; import {SCError} from '../error';
/** /**
@@ -34,7 +34,7 @@ export class SCValidationErrorResponse extends SCError {
* @param stack Set to true if a stack trace should be created * @param stack Set to true if a stack trace should be created
*/ */
constructor(errors: ValidationError[], stack?: boolean) { constructor(errors: ValidationError[], stack?: boolean) {
super('ValidationError', 'Validation of request failed', BAD_REQUEST, stack); super('ValidationError', 'Validation of request failed', StatusCodes.BAD_REQUEST, stack);
this.additionalData = errors; this.additionalData = errors;
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCUuid} from '../../general/uuid'; import {SCUuid} from '../../general/uuid';
import {SCAcademicPriceGroup, SCThingThatCanBeOfferedOffer} from '../../things/abstract/thing-that-can-be-offered'; import {SCAcademicPriceGroup, SCThingThatCanBeOfferedOffer} from '../../things/abstract/thing-that-can-be-offered';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
@@ -88,7 +88,7 @@ export class SCBookAvailabilityRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCBookAvailabilityRequest'; this.requestBodyName = 'SCBookAvailabilityRequest';
this.responseBodyName = 'SCBookAvailabilityResponse'; this.responseBodyName = 'SCBookAvailabilityResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/bookAvailability'; this.urlFragment = '/bookAvailability';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {CREATED} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCThings} from '../../meta'; import {SCThings} from '../../meta';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
@@ -59,7 +59,7 @@ export class SCBulkAddRoute extends SCAbstractRoute {
}; };
this.requestBodyName = 'SCBulkAddRequest'; this.requestBodyName = 'SCBulkAddRequest';
this.responseBodyName = 'SCBulkAddResponse'; this.responseBodyName = 'SCBulkAddResponse';
this.statusCodeSuccess = CREATED; this.statusCodeSuccess = StatusCodes.CREATED;
this.urlFragment = '/bulk/:UID'; this.urlFragment = '/bulk/:UID';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {NO_CONTENT} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
import {SCNotFoundErrorResponse} from '../errors/not-found'; import {SCNotFoundErrorResponse} from '../errors/not-found';
@@ -59,7 +59,7 @@ export class SCBulkDoneRoute extends SCAbstractRoute {
}; };
this.requestBodyName = 'SCBulkDoneRequest'; this.requestBodyName = 'SCBulkDoneRequest';
this.responseBodyName = 'SCBulkDoneResponse'; this.responseBodyName = 'SCBulkDoneResponse';
this.statusCodeSuccess = NO_CONTENT; this.statusCodeSuccess = StatusCodes.NO_CONTENT;
this.urlFragment = '/bulk/:UID/done'; this.urlFragment = '/bulk/:UID/done';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCISO8601Date} from '../../general/time'; import {SCISO8601Date} from '../../general/time';
import {SCUuid} from '../../general/uuid'; import {SCUuid} from '../../general/uuid';
import {SCThingType} from '../../things/abstract/thing'; import {SCThingType} from '../../things/abstract/thing';
@@ -98,7 +98,7 @@ export class SCBulkRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCBulkRequest'; this.requestBodyName = 'SCBulkRequest';
this.responseBodyName = 'SCBulkResponse'; this.responseBodyName = 'SCBulkResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/bulk'; this.urlFragment = '/bulk';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {NO_CONTENT} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCMessage} from '../../things/message'; import {SCMessage} from '../../things/message';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
@@ -59,7 +59,7 @@ export class SCFeedbackRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCFeedbackRequest'; this.requestBodyName = 'SCFeedbackRequest';
this.responseBodyName = 'SCFeedbackResponse'; this.responseBodyName = 'SCFeedbackResponse';
this.statusCodeSuccess = NO_CONTENT; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/feedback'; this.urlFragment = '/feedback';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCAppConfiguration} from '../../config/app'; import {SCAppConfiguration} from '../../config/app';
import {SCBackendConfiguration} from '../../config/backend'; import {SCBackendConfiguration} from '../../config/backend';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
@@ -65,7 +65,7 @@ export class SCIndexRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCIndexRequest'; this.requestBodyName = 'SCIndexRequest';
this.responseBodyName = 'SCIndexResponse'; this.responseBodyName = 'SCIndexResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/'; this.urlFragment = '/';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {JSONSchema7} from 'json-schema'; import {JSONSchema7} from 'json-schema';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
@@ -122,7 +122,7 @@ export class SCPluginRegisterRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCPluginRegisterRequest'; this.requestBodyName = 'SCPluginRegisterRequest';
this.responseBodyName = 'SCPluginRegisterResponse'; this.responseBodyName = 'SCPluginRegisterResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/plugin/register'; this.urlFragment = '/plugin/register';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCMap} from '../../general/map'; import {SCMap} from '../../general/map';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
@@ -63,7 +63,7 @@ export class SCMultiSearchRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCMultiSearchRequest'; this.requestBodyName = 'SCMultiSearchRequest';
this.responseBodyName = 'SCMultiSearchResponse'; this.responseBodyName = 'SCMultiSearchResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/search/multi'; this.urlFragment = '/search/multi';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
import {SCRequestBodyTooLargeErrorResponse} from '../errors/request-body-too-large'; import {SCRequestBodyTooLargeErrorResponse} from '../errors/request-body-too-large';
@@ -56,7 +56,7 @@ export class SCSearchRoute extends SCAbstractRoute {
this.method = SCRouteHttpVerbs.POST; this.method = SCRouteHttpVerbs.POST;
this.requestBodyName = 'SCSearchRequest'; this.requestBodyName = 'SCSearchRequest';
this.responseBodyName = 'SCSearchResponse'; this.responseBodyName = 'SCSearchResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/search'; this.urlFragment = '/search';
} }
} }

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {OK} from 'http-status-codes'; import {StatusCodes} from 'http-status-codes';
import {SCThings} from '../../meta'; import {SCThings} from '../../meta';
import {SCInternalServerErrorResponse} from '../errors/internal-server-error'; import {SCInternalServerErrorResponse} from '../errors/internal-server-error';
import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed'; import {SCMethodNotAllowedErrorResponse} from '../errors/method-not-allowed';
@@ -60,7 +60,7 @@ export class SCThingUpdateRoute extends SCAbstractRoute {
}; };
this.requestBodyName = 'SCThingUpdateRequest'; this.requestBodyName = 'SCThingUpdateRequest';
this.responseBodyName = 'SCThingUpdateResponse'; this.responseBodyName = 'SCThingUpdateResponse';
this.statusCodeSuccess = OK; this.statusCodeSuccess = StatusCodes.OK;
this.urlFragment = '/:TYPE/:UID'; this.urlFragment = '/:TYPE/:UID';
} }
} }

View File

@@ -22,26 +22,25 @@ export interface SCAcademicDegreeWithoutReferences
extends SCThingWithoutReferences { extends SCThingWithoutReferences {
/** /**
* The achievable academic degree * The achievable academic degree
*
* @filterable
* @sortable ducet
*/ */
academicDegree: SCGermanAcademicDegree; academicDegree: string;
/** /**
* The achievable academic degree with academic field specification * The achievable academic degree with academic field specification
* (eg. Master of Science) * (eg. Master of Science)
* *
* @filterable
* @keyword
*/ */
academicDegreewithField: string; academicDegreewithField?: string;
/** /**
* The achievable academic degree with academic field specification * The achievable academic degree with academic field specification
* shorted (eg. M.Sc.). * shorted (eg. M.Sc.).
* *
* @filterable
* @keyword
*/ */
academicDegreewithFieldShort: string; academicDegreewithFieldShort?: string;
} }
/** /**
@@ -63,9 +62,9 @@ export class SCAcademicDegreeMeta
fieldTranslations = { fieldTranslations = {
de: { de: {
...SCThingMeta.getInstance<SCThingMeta>().fieldTranslations.de, ...SCThingMeta.getInstance<SCThingMeta>().fieldTranslations.de,
academicDegree: 'Hochschulgrad', academicDegree: 'Abschlussgrad',
academicDegreewithField: 'Abschlussbezeichnungen', academicDegreewithField: 'Abschlussbezeichnung',
academicDegreewithFieldShort: 'Abschlussbezeichnungen (kurz)', academicDegreewithFieldShort: 'Abschlussbezeichnung (kurz)',
}, },
en: { en: {
...SCThingMeta.getInstance<SCThingMeta>().fieldTranslations.en, ...SCThingMeta.getInstance<SCThingMeta>().fieldTranslations.en,
@@ -81,32 +80,9 @@ export class SCAcademicDegreeMeta
fieldValueTranslations = { fieldValueTranslations = {
de: { de: {
...SCThingMeta.getInstance<SCThingMeta>().fieldValueTranslations.de, ...SCThingMeta.getInstance<SCThingMeta>().fieldValueTranslations.de,
academicDegree: {
'bachelor': 'Bachelor',
'diploma': 'Diplom',
'doctor': 'Doktor',
'licentiate': 'Lizenziat',
'magister': 'Magister',
'master': 'Master',
'masterstudent': 'Meisterschüler',
'state examination': 'Staatsexamen',
},
}, },
en: { en: {
...SCThingMeta.getInstance<SCThingMeta>().fieldValueTranslations.en, ...SCThingMeta.getInstance<SCThingMeta>().fieldValueTranslations.en,
}, },
}; };
} }
/**
* Types of (german) academic degrees
*/
export type SCGermanAcademicDegree =
'bachelor'
| 'diploma'
| 'doctor'
| 'licentiate'
| 'magister'
| 'master'
| 'master pupil'
| 'state examination' ;

View File

@@ -23,6 +23,7 @@ import {SCPersonWithoutReferences} from '../person';
* Types a thing can be * Types a thing can be
*/ */
export enum SCThingType { export enum SCThingType {
Assessment = 'assessment',
AcademicEvent = 'academic event', AcademicEvent = 'academic event',
Article = 'article', Article = 'article',
Book = 'book', Book = 'book',
@@ -30,7 +31,7 @@ export enum SCThingType {
Building = 'building', Building = 'building',
Catalog = 'catalog', Catalog = 'catalog',
ContactPoint = 'contact point', ContactPoint = 'contact point',
CourseOfStudies = 'course of studies', CourseOfStudy = 'course of study',
DateSeries = 'date series', DateSeries = 'date series',
Diff = 'diff', Diff = 'diff',
Dish = 'dish', Dish = 'dish',

162
src/things/assessment.ts Normal file
View File

@@ -0,0 +1,162 @@
/*
* Copyright (C) 2019-2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {SCMetaTranslations, SCTranslations} from '../general/i18n';
import {SCISO8601Date} from '../general/time';
import {SCThing, SCThingMeta, SCThingType} from './abstract/thing';
import {SCThingWithCategories, SCThingWithCategoriesSpecificValues, SCThingWithCategoriesTranslatableProperties, SCThingWithCategoriesWithoutReferences, SCThingWithCategoriesWithoutReferencesMeta} from './abstract/thing-with-categories';
import {SCCourseOfStudyWithoutReferences} from './course-of-study';
/**
* Categories of assessments
*/
export type SCAssessmentCategories = 'university assessment';
/**
* An assessment without references
*
*/
export interface SCAssessmentWithoutReferences
extends SCThingWithCategoriesWithoutReferences<SCAssessmentCategories, SCThingWithCategoriesSpecificValues> {
/**
* Number of attempts
*
* @integer
*/
attempt?: number;
/**
* Date assessment was taken or graded
*/
date?: SCISO8601Date;
/**
* ECTS (credit-points)
*
* @float
*/
ects?: number;
/**
* Grade
*/
grade: string;
/**
* Current status
*/
status?: string;
/**
* Translated fields of an assessment
*/
translations?: SCTranslations<SCAssessmentTranslatableProperties>;
/**
* Type of an assessment
*/
type: SCThingType.Assessment;
}
/**
* An assessment
*
* @validatable
*/
export interface SCAssessment
extends SCAssessmentWithoutReferences, SCThing,
SCThingWithCategories<SCAssessmentCategories, SCThingWithCategoriesSpecificValues> {
/**
* Course of study the assessment was taken for
*/
courseOfStudy?: SCCourseOfStudyWithoutReferences;
/**
* An array of assessments from the 'level 0' (root) assessment to the direct parent
*/
superAssessments?: SCAssessmentWithoutReferences[];
/**
* Translated fields of an assessment
*/
translations?: SCTranslations<SCAssessmentTranslatableProperties>;
/**
* Type of an assessment
*/
type: SCThingType.Assessment;
}
export interface SCAssessmentTranslatableProperties
extends SCThingWithCategoriesTranslatableProperties {
/**
* @see SCAssessmentWithoutReferences.status
*/
status?: string;
}
/**
* Study module meta data
*/
export class SCAssessmentMeta
extends SCThingMeta
implements SCMetaTranslations<SCAssessment> {
/**
* Translations of fields
*/
fieldTranslations = {
de: {
...SCThingWithCategoriesWithoutReferencesMeta.getInstance<SCAssessmentCategories,
SCThingWithCategoriesSpecificValues>().fieldTranslations.de,
attempt: 'Versuch',
courseOfStudy: 'Studiengang',
date: 'Datum',
ects: 'ECTS-Punkte',
grade: 'Note',
status: 'Status',
superAssessments: 'übergeordnete Prüfungen',
},
en: {
...SCThingWithCategoriesWithoutReferencesMeta.getInstance<SCAssessmentCategories,
SCThingWithCategoriesSpecificValues>().fieldTranslations.en,
attempt: 'attempt',
courseOfStudy: 'course of study',
date: 'date',
ects: 'ECTS points',
grade: 'grade',
status: 'status',
superAssessments: 'parent assessments',
},
};
/**
* Translations of values of fields
*/
fieldValueTranslations = {
de: {
...SCThingWithCategoriesWithoutReferencesMeta.getInstance<SCAssessmentCategories,
SCThingWithCategoriesSpecificValues>().fieldValueTranslations.de,
type: 'Prüfung',
},
en: {
...SCThingWithCategoriesWithoutReferencesMeta.getInstance<SCAssessmentCategories,
SCThingWithCategoriesSpecificValues>().fieldValueTranslations.en,
type: SCThingType.Assessment,
},
};
}

View File

@@ -43,6 +43,7 @@ export type SCBookCategories = 'audio'
| 'microfilm' | 'microfilm'
| 'musicalscore' | 'musicalscore'
| 'photo' | 'photo'
| 'physicalobject'
| 'retro' | 'retro'
| 'sensorimage' | 'sensorimage'
| 'unknown' | 'unknown'

View File

@@ -26,94 +26,90 @@ import {SCDateSeriesWithoutReferences} from './date-series';
import {SCOrganizationWithoutReferences} from './organization'; import {SCOrganizationWithoutReferences} from './organization';
/** /**
* A course of studies without references * A course of study without references
*/ */
export interface SCCourseOfStudiesWithoutReferences export interface SCCourseOfStudyWithoutReferences
extends SCAcademicDegreeWithoutReferences, SCThingThatCanBeOfferedWithoutReferences { extends SCAcademicDegreeWithoutReferences, SCThingThatCanBeOfferedWithoutReferences {
/** /**
* The main language in which the course of studies * The main language in which the course of study
* is beeing offered * is beeing offered
*/ */
mainLanguage: SCLanguage; mainLanguage?: SCLanguage;
/** /**
* Actual major of the course of studies (eg. physics) * The modes the course of study is offered in
* *
* @filterable * @filterable
* @keyword
*/ */
major: string; mode?: SCCourseOfStudyMode;
/** /**
* The modes the course of studies is offered in * The time modes the course of study is offered in
*
* @filterable
*/ */
mode: SCCourseOfStudiesMode; timeMode?: SCCourseOfStudyTimeMode;
/**
* The time modes the course of studies is offered in
*/
timeMode: SCCourseOfStudiesTimeMode;
/** /**
* Translated fields of a dish * Translated fields of a dish
*/ */
translations?: SCTranslations<SCCourseOfStudiesTranslatableProperties>; translations?: SCTranslations<SCCourseOfStudyTranslatableProperties>;
/** /**
* Type of the course of studies * Type of the course of study
*/ */
type: SCThingType.CourseOfStudies; type: SCThingType.CourseOfStudy;
} }
/** /**
* A course of studies * A course of study
* *
* @validatable * @validatable
* @indexable * @indexable
*/ */
export interface SCCourseOfStudies export interface SCCourseOfStudy
extends SCCourseOfStudiesWithoutReferences, SCThingThatCanBeOffered<SCAcademicPriceGroup>, SCAcademicDegree { extends SCCourseOfStudyWithoutReferences, SCThingThatCanBeOffered<SCAcademicPriceGroup>, SCAcademicDegree {
/** /**
* The department that manages the course of studies * The department that manages the course of study
*/ */
department: SCOrganizationWithoutReferences; department?: SCOrganizationWithoutReferences;
/** /**
* The secretary that administers requests and * The secretary that administers requests and
* questions concerning the course of studies * questions concerning the course of study
*/ */
secretary: SCOrganizationWithoutReferences; secretary?: SCOrganizationWithoutReferences;
/** /**
* Dates at which the course of studies is planned to start * Dates at which the course of study is planned to start
*/ */
startDates?: SCDateSeriesWithoutReferences[]; startDates?: SCDateSeriesWithoutReferences[];
/** /**
* Translated fields of a course of studies * Translated fields of a course of study
*/ */
translations?: SCTranslations<SCCourseOfStudiesTranslatableProperties>; translations?: SCTranslations<SCCourseOfStudyTranslatableProperties>;
/** /**
* Type of the course of studies * Type of the course of study
*/ */
type: SCThingType.CourseOfStudies; type: SCThingType.CourseOfStudy;
} }
/** /**
* Translatable properties of a course of studies * Translatable properties of a course of study
*/ */
export interface SCCourseOfStudiesTranslatableProperties export interface SCCourseOfStudyTranslatableProperties
extends SCThingThatCanBeOfferedTranslatableProperties { extends SCThingThatCanBeOfferedTranslatableProperties {
// noop // noop
} }
/** /**
* Meta information about a course of studies * Meta information about a course of study
*/ */
export class SCCourseOfStudiesMeta export class SCCourseOfStudyMeta
extends SCThingMeta extends SCThingMeta
implements SCMetaTranslations<SCCourseOfStudies> { implements SCMetaTranslations<SCCourseOfStudy> {
/** /**
* Translations of fields * Translations of fields
*/ */
@@ -125,7 +121,6 @@ export class SCCourseOfStudiesMeta
.fieldTranslations.de, .fieldTranslations.de,
department: 'Fachbereich', department: 'Fachbereich',
mainLanguage: 'Unterrichtssprache', mainLanguage: 'Unterrichtssprache',
major: 'Studienfach',
mode: 'Studiengangsart', mode: 'Studiengangsart',
secretary: 'Sekretariat', secretary: 'Sekretariat',
startDates: 'Startdatum', startDates: 'Startdatum',
@@ -138,7 +133,6 @@ export class SCCourseOfStudiesMeta
.fieldTranslations.de, .fieldTranslations.de,
department: 'department', department: 'department',
mainLanguage: 'main language', mainLanguage: 'main language',
major: 'major',
mode: 'mode', mode: 'mode',
secretary: 'secretary', secretary: 'secretary',
startDates: 'start dates', startDates: 'start dates',
@@ -167,30 +161,30 @@ export class SCCourseOfStudiesMeta
en: { en: {
...SCAcademicDegreeMeta.getInstance().fieldValueTranslations.en, ...SCAcademicDegreeMeta.getInstance().fieldValueTranslations.en,
modes: { modes: {
combination: 'combination course of studies', combination: 'combination course of study',
'double-degree': 'double degree course of studies', 'double-degree': 'double degree course of study',
dual: 'dual course of studies', dual: 'dual course of study',
standard: 'course of studies', standard: 'course of study',
}, },
timeMode: { timeMode: {
fulltime: 'full-time', fulltime: 'full-time',
parttime: 'part-time', parttime: 'part-time',
}, },
type: SCThingType.CourseOfStudies, type: SCThingType.CourseOfStudy,
}, },
}; };
} }
/** /**
* Types of (german) course of studies modes * Types of (german) course of study modes
*/ */
export type SCCourseOfStudiesMode = 'combination' export type SCCourseOfStudyMode = 'combination'
| 'dual' | 'dual'
| 'double-degree' | 'double-degree'
| 'standard' ; | 'standard' ;
/** /**
* Types of (german) course of studies time modes * Types of (german) course of study time modes
*/ */
export type SCCourseOfStudiesTimeMode = 'fulltime' export type SCCourseOfStudyTimeMode = 'fulltime'
| 'parttime' ; | 'parttime' ;

View File

@@ -281,7 +281,7 @@ export class SCThingTranslator {
* Given a SCThingType this function returns an object with the same basic structure as the corresponding SCThing * Given a SCThingType this function returns an object with the same basic structure as the corresponding SCThing
* All the values will be set to the known translations of the property/key name * All the values will be set to the known translations of the property/key name
* @example * @example
* const translatedMetaDish = translator.translatedPropertyNames<SCCourseOfStudies>(SCThingType.CourseOfStudies); * const translatedMetaDish = translator.translatedPropertyNames<SCCourseOfStudy>(SCThingType.CourseOfStudy);
* @param type The type whose property names will be translated * @param type The type whose property names will be translated
* @returns An object with the properties of the SCThingType where the values are the known property tranlations * @returns An object with the properties of the SCThingType where the values are the known property tranlations
*/ */

44
test/compat.spec.ts Normal file
View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {lightweightProjectFromPath} from '@openstapps/core-tools/lib/easy-ast/easy-ast';
import {LightweightProject} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-project';
import {expect} from 'chai';
import {reduce} from 'lodash';
process.on('unhandledRejection', (err) => {
throw err;
});
describe('Mapping Compatibility', () => {
let project: LightweightProject;
before(function () {
this.timeout(15000);
this.slow(10000);
project = lightweightProjectFromPath('src');
});
it('non-exported definitions should not have duplicate names across files', () => {
reduce(project, (result, file) => reduce(file, (result2, _, key) => {
expect(result2[key]).to.be.undefined;
return {
[key]: true,
...result2,
};
}, result), {} as Record<string, boolean>);
});
});

140
test/features.spec.ts Normal file
View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2018 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {isLightweightClass, isLightweightEnum, isUnionType} from '@openstapps/core-tools/lib/easy-ast/ast-util';
import {LightweightAliasDefinition} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-alias-definition';
import {LightweightProjectWithIndex} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-project';
import {LightweightType} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-type';
import {LightweightClassDefinition} from '@openstapps/core-tools/src/easy-ast/types/lightweight-class-definition';
import {LightweightDefinition} from '@openstapps/core-tools/src/easy-ast/types/lightweight-definition';
import {LightweightProperty} from '@openstapps/core-tools/src/easy-ast/types/lightweight-property';
import {expect} from 'chai';
import {assign, chain, clone, flatMap, isNil, reduce, reject, some} from 'lodash';
process.on('unhandledRejection', (err) => {
throw err;
});
describe('Features', () => {
let project: LightweightProjectWithIndex;
let thingNames: string[];
let things: LightweightClassDefinition[];
let thingsWithoutReferences: LightweightClassDefinition[];
before(function () {
this.timeout(15000);
this.slow(10000);
project = new LightweightProjectWithIndex('src');
const thingsReflection = project.definitions['SCIndexableThings'] as LightweightAliasDefinition;
expect(isLightweightEnum(thingsReflection)).to.be.true;
expect(isUnionType(thingsReflection.type!)).to.be.true;
thingsReflection.type!.specificationTypes!.push({
flags: 524_288,
referenceName: 'SCDiff',
});
// tslint:disable-next-line:no-unused-expression
expect(thingsReflection.type?.specificationTypes?.every(it => typeof it.referenceName !== 'undefined')).to.be.true;
thingNames = thingsReflection.type?.specificationTypes?.map(type => type.referenceName!) ?? [];
things = thingNames
.map(it => project.definitions[it])
.filter(isLightweightClass);
thingsWithoutReferences = thingNames
.map(it => project.definitions[`${it}WithoutReferences`])
.filter(isLightweightClass);
});
const inheritedProperties = function (classLike: LightweightClassDefinition):
Record<string, LightweightProperty> | undefined {
return reduce(
[...(classLike.implementedDefinitions ?? []), ...(classLike.extendedDefinitions ?? [])],
(obj, extension) => {
const object = project.definitions[extension.referenceName ?? ''];
return assign(obj, isLightweightClass(object)
? inheritedProperties(object)
: obj);
},
clone(classLike.properties)
);
};
it('should have an origin', () => {
for (const thing of things) {
expect(inheritedProperties(thing)?.['origin']).not.to.be.undefined;
}
});
it('should not have duplicate names', () => {
reduce(project.files, (fileResult, file) =>
reduce(file, (definitionResult, definition: LightweightDefinition) => {
expect(definitionResult[definition.name]).to.be.undefined;
definitionResult[definition.name] = true; // something that's not undefined
return definitionResult;
}, fileResult), {} as Record<string, true>);
});
it('should not have properties referencing SCThing', () => {
const allPropertyReferenceNames: (property: LightweightProperty) => string[] = property => reject([
property.type.referenceName!,
...flatMap(property.properties, allPropertyReferenceNames),
], isNil);
const typeHasSCThingReferences: (type?: LightweightType) => boolean = type => type?.referenceName
? hasSCThingReferences(project.definitions[type.referenceName])
: some(type?.specificationTypes, typeHasSCThingReferences);
const hasSCThingReferences: (definition?: LightweightDefinition) => boolean = definition =>
isLightweightClass(definition)
? chain(inheritedProperties(definition))
.flatMap(it => flatMap(it.properties, allPropertyReferenceNames))
.map(it => project.definitions[it] as LightweightDefinition)
.some(it => it.name === 'SCThing' || hasSCThingReferences(it))
.value()
: definition ? typeHasSCThingReferences(definition.type) : false;
for (const thing of things) {
expect(hasSCThingReferences(thing)).to.be.false;
}
});
function extendsSCThing(definition?: LightweightDefinition): boolean {
return isLightweightClass(definition)
? chain([
...(definition as LightweightClassDefinition).extendedDefinitions ?? [],
...(definition as LightweightClassDefinition).implementedDefinitions ?? [],
])
.map(it => it.referenceName)
.reject(isNil)
.some(it => it === 'SCThing' || extendsSCThing(project.definitions[it!]))
.value()
: false;
}
it('should extend SCThing if it is an SCThing', () => {
for (const thing of things) {
expect(extendsSCThing(thing)).to.be.true;
}
});
it('should not extend SCThing if it is an SCThingWithoutReferences', () => {
for (const thingWithoutReferences of thingsWithoutReferences) {
expect(extendsSCThing(thingWithoutReferences)).to.be.false;
}
});
});

View File

@@ -22,7 +22,7 @@
"name": "HeBIS HDS", "name": "HeBIS HDS",
"originalId": "HEB198305427", "originalId": "HEB198305427",
"type": "remote", "type": "remote",
"url": "https://hds2test.hebis.de/ubffm/" "url": "https://hds2.hebis.de/ubffm/"
}, },
"isPartOf": { "isPartOf": {
"uid": "bc5e5399-a24c-5c01-9c1b-0c8b83272087", "uid": "bc5e5399-a24c-5c01-9c1b-0c8b83272087",

View File

@@ -22,7 +22,7 @@
"name": "HeBIS HDS", "name": "HeBIS HDS",
"originalId": "HEB107025590", "originalId": "HEB107025590",
"type": "remote", "type": "remote",
"url": "https://hds2test.hebis.de/ubffm/" "url": "https://hds2.hebis.de/ubffm/"
}, },
"isPartOf": { "isPartOf": {
"uid": "f84c1851-042e-542f-ba7a-158b32dfb82f", "uid": "f84c1851-042e-542f-ba7a-158b32dfb82f",

View File

@@ -0,0 +1,36 @@
{
"errorNames": [],
"instance": {
"attempt": 1,
"date": "2020-04-01",
"ects": 20,
"grade": "N/A",
"status": "ongoing",
"uid": "681a59a1-23c2-5d78-861a-8c86a3abf404",
"name": "Introductory courses extreme math",
"categories": [
"university assessment"
],
"courseOfStudy": {
"academicDegree": "bachelor",
"academicDegreewithField": "Bachelor of Arts",
"academicDegreewithFieldShort": "B.A.",
"mainLanguage": {
"code": "de",
"name": "german"
},
"mode": "dual",
"name": "Astroturfing",
"timeMode": "parttime",
"type": "course of study",
"uid": "4c6f0a18-343d-5175-9fb1-62d28545c2aa"
},
"origin": {
"indexed": "2020-04-11T12:30:00Z",
"name": "Dummy",
"type": "remote"
},
"type": "assessment"
},
"schema": "SCAssessment"
}

View File

@@ -0,0 +1,51 @@
{
"errorNames": [],
"instance": {
"attempt": 1,
"date": "2020-04-01",
"ects": 6,
"grade": "very much 1.0",
"status": "passed",
"uid": "681a59a1-23c2-5d78-861a-8c86a3abf303",
"name": "Mathe 9001",
"categories": [
"university assessment"
],
"superAssessments": [
{
"attempt": 1,
"date": "2020-04-01",
"ects": 20,
"grade": "N/A",
"status": "ongoing",
"uid": "681a59a1-23c2-5d78-861a-8c86a3abf404",
"name": "Introductory courses extreme math",
"categories": [
"university assessment"
],
"type": "assessment"
}
],
"courseOfStudy": {
"academicDegree": "bachelor",
"academicDegreewithField": "Bachelor of Arts",
"academicDegreewithFieldShort": "B.A.",
"mainLanguage": {
"code": "de",
"name": "german"
},
"mode": "dual",
"name": "Astroturfing",
"timeMode": "parttime",
"type": "course of study",
"uid": "4c6f0a18-343d-5175-9fb1-62d28545c2aa"
},
"origin": {
"indexed": "2020-04-11T12:30:00Z",
"name": "Dummy",
"type": "remote"
},
"type": "assessment"
},
"schema": "SCAssessment"
}

View File

@@ -33,7 +33,7 @@
"name": "HeBIS HDS", "name": "HeBIS HDS",
"originalId": "HEB022992618", "originalId": "HEB022992618",
"type": "remote", "type": "remote",
"url": "https://hds2test.hebis.de/ubffm/" "url": "https://hds2.hebis.de/ubffm/"
} }
}, },
"schema": "SCBook" "schema": "SCBook"

View File

@@ -18,7 +18,7 @@
"firstPublished": "2001", "firstPublished": "2001",
"publications": [ "publications": [
{ {
"uid": "603a6574-8910-588a-9e83-cd26e6988c74", "uid": "6333427c-0725-5398-9a04-11604680dae3",
"type": "publication event", "type": "publication event",
"locations": [ "locations": [
"Paris" "Paris"
@@ -36,7 +36,7 @@
"name": "HeBIS HDS", "name": "HeBIS HDS",
"originalId": "HEB102248788", "originalId": "HEB102248788",
"type": "remote", "type": "remote",
"url": "https://hds2test.hebis.de/ubffm/" "url": "https://hds2.hebis.de/ubffm/"
} }
}, },
"schema": "SCBook" "schema": "SCBook"

View File

@@ -13,9 +13,8 @@
"code": "de", "code": "de",
"name": "german" "name": "german"
}, },
"major": "Astroturfing",
"mode": "dual", "mode": "dual",
"name": "Astroturfing Bachelor", "name": "Astroturfing",
"origin": { "origin": {
"indexed": "2018-09-11T12:30:00Z", "indexed": "2018-09-11T12:30:00Z",
"name": "Dummy", "name": "Dummy",
@@ -27,8 +26,8 @@
"uid": "b0f878fd-8fda-53b8-b065-a8d854c3d0d2" "uid": "b0f878fd-8fda-53b8-b065-a8d854c3d0d2"
}, },
"timeMode": "parttime", "timeMode": "parttime",
"type": "course of studies", "type": "course of study",
"uid": "4c6f0a18-343d-5175-9fb1-62d28545c2aa" "uid": "4c6f0a18-343d-5175-9fb1-62d28545c2aa"
}, },
"schema": "SCCourseOfStudies" "schema": "SCCourseOfStudy"
} }

View File

@@ -1,6 +1,6 @@
{ {
"errorNames": [ "errorNames": [
"enum" "const"
], ],
"instance": { "instance": {
"type": "invalid-value-in-schema", "type": "invalid-value-in-schema",

View File

@@ -28,7 +28,7 @@
"name": "HeBIS HDS", "name": "HeBIS HDS",
"originalId": "HEB046847146", "originalId": "HEB046847146",
"type": "remote", "type": "remote",
"url": "https://hds2test.hebis.de/ubffm/" "url": "https://hds2.hebis.de/ubffm/"
} }
}, },
"schema": "SCPeriodical" "schema": "SCPeriodical"

View File

@@ -25,7 +25,7 @@
"name": "HeBIS HDS", "name": "HeBIS HDS",
"originalId": "HEB048624853", "originalId": "HEB048624853",
"type": "remote", "type": "remote",
"url": "https://hds2test.hebis.de/ubffm/" "url": "https://hds2.hebis.de/ubffm/"
} }
}, },
"schema": "SCPeriodical" "schema": "SCPeriodical"

View File

@@ -1,321 +1,11 @@
/*
* Copyright (C) 2018 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {getTsconfigPath} from '@openstapps/core-tools/lib/common';
import {validateFiles, writeReport} from '@openstapps/core-tools/lib/validate'; import {validateFiles, writeReport} from '@openstapps/core-tools/lib/validate';
import {Logger} from '@openstapps/logger';
import {fail} from 'assert';
import {expect} from 'chai';
import {mkdirSync, PathLike} from 'fs';
import {slow, suite, test, timeout} from '@testdeck/mocha'; import {slow, suite, test, timeout} from '@testdeck/mocha';
import {expect} from 'chai';
import {mkdirSync} from 'fs';
import {join, resolve} from 'path'; import {join, resolve} from 'path';
import {Application, DeclarationReflection, ProjectReflection, TSConfigReader} from 'typedoc';
import {ArrayType, IntrinsicType, ReferenceType, LiteralType, Type, UnionType} from 'typedoc/dist/lib/models';
process.on('unhandledRejection', (err) => {
throw err;
});
/**
* Get a project reflection from a path
*
* @param srcPath Path to get reflection from
* @param excludeExternals Exclude external dependencies
*/
export function getProjectReflection(srcPath: PathLike, excludeExternals = true): ProjectReflection {
Logger.info(`Generating project reflection for ${srcPath.toString()}.`);
const tsconfigPath = getTsconfigPath(srcPath.toString());
let inputFilePath = srcPath;
if (inputFilePath === tsconfigPath) {
inputFilePath = join(tsconfigPath, 'src');
}
// initialize new Typedoc application
const app = new Application();
app.options.addReader(new TSConfigReader());
app.bootstrap({
entryPoints: [inputFilePath.toString()],
excludeExternals: excludeExternals,
tsconfig: join(tsconfigPath, 'tsconfig.json'),
});
// get project reflection from input files
const result = app.convert();
if (typeof result === 'undefined') {
throw new Error('Project reflection could not be generated.');
}
return result;
}
/**
* Check if type is a union type
*
* @param type Type to check
*/
function isUnionType(type: Type): type is UnionType {
return type.type === 'union';
}
/**
* Check if a type is reference type
*
* @param type Type to check
*/
function isReferenceType(type: Type): type is ReferenceType {
return type.type === 'reference';
}
/**
* Check if a type is an array type
*
* @param type Type to check
*/
function isArrayType(type: Type): type is ArrayType {
return type.type === 'array';
}
/**
* Check if a type is an intrinsic type
*
* @param type Type to check
*/
function isIntrinsicType(type: Type): type is IntrinsicType {
return type.type === 'intrinsic';
}
/**
* Check if a type is a string literal type
*
* @param type Type to check
*/
function isLiteralType(type: Type): type is LiteralType {
return type.type === 'literal';
}
/**
* Get extended types of a declaration reflection
* @param thingReflection Reflection of the thing
* @param objects Map of reflections by name
*/
function getExtendedTypes(thingReflection: DeclarationReflection,
objects: { [name: string]: DeclarationReflection }): string[] {
const extendedTypes: string[] = [];
if (Array.isArray(thingReflection.extendedTypes)) {
const typesToCheck = thingReflection.extendedTypes.slice();
while (typesToCheck.length > 0) {
const extendedType = typesToCheck.splice(0, 1)[0];
extendedTypes.push((extendedType as unknown as ReferenceType).name);
const extendedObject = objects[(extendedType as unknown as ReferenceType).name];
if (typeof extendedObject !== 'undefined') {
if (Array.isArray(extendedObject.extendedTypes)) {
typesToCheck.push.apply(typesToCheck, extendedObject.extendedTypes);
}
}
}
}
return extendedTypes;
}
@suite(timeout(15000), slow(10000)) @suite(timeout(15000), slow(10000))
export class SchemaSpec { export class SchemaSpec {
static objects: { [name: string]: DeclarationReflection } = {};
static reflection: ProjectReflection;
static thingNames: string[];
static before() {
SchemaSpec.reflection = getProjectReflection(resolve(__dirname, '..', 'src'));
if (Array.isArray(SchemaSpec.reflection.children)) {
for (const module of SchemaSpec.reflection.children) {
if (Array.isArray(module.children)) {
for (const object of module.children) {
SchemaSpec.objects[object.name] = object;
}
}
}
}
const thingsReflection = SchemaSpec.objects.SCIndexableThings;
// tslint:disable-next-line:no-unused-expression
expect(thingsReflection).not.to.be.undefined;
// tslint:disable-next-line:no-unused-expression
expect(isUnionType(thingsReflection.type!)).to.be.true;
(thingsReflection.type! as UnionType).types.push({
'id': 0,
'name': 'SCDiff',
'type': 'reference',
} as unknown as ReferenceType);
// tslint:disable-next-line:no-unused-expression
expect((thingsReflection.type! as UnionType).types.every(isReferenceType)).to.be.true;
SchemaSpec.thingNames = (thingsReflection.type! as UnionType).types.map((type) => {
return (type as ReferenceType).name;
});
}
@test
'all things have an origin'() {
for (const thingName of SchemaSpec.thingNames) {
const thingReflection = SchemaSpec.objects[`${thingName}`];
let originFound = false;
if (Array.isArray(thingReflection.children)) {
for (const property of thingReflection.children) {
if (property.name === 'origin') {
originFound = true;
break;
}
}
}
// tslint:disable-next-line:no-unused-expression
expect(originFound).to.be.equal(true, `'${thingName}' must have property 'origin'.`);
}
}
@test
'does not have duplicate names'() {
const names: string[] = [];
if (Array.isArray(SchemaSpec.reflection.children)) {
for (const module of SchemaSpec.reflection.children) {
if (Array.isArray(module.children)) {
for (const object of module.children) {
expect(names).not.to.contain(object.name);
names.push(object.name);
}
}
}
}
}
@test
'no property is an SCThing'() {
const handleUnionType = (type: UnionType, thingName: string, property: DeclarationReflection) => {
for (const nestedType of type.types) {
if (isIntrinsicType(nestedType) || isLiteralType(nestedType)) {
continue;
} else if (isReferenceType(nestedType)) {
expect(SchemaSpec.thingNames).not.to.contain(
nestedType.name,
`Union property '${property.name}' on type '${thingName}' contains type '${nestedType.name}'.`,
);
} else {
// tslint:disable-next-line:max-line-length
fail(`'${thingName}'#'${property.name}' union type '${nestedType.type}' is not handled by this test!`);
}
}
};
for (const thingName of SchemaSpec.thingNames) {
const thingReflection = SchemaSpec.objects[`${thingName}`];
if (Array.isArray(thingReflection.children)) {
for (const property of thingReflection.children) {
if (typeof property.type === 'undefined') {
Logger.error(thingName, property.name);
continue;
}
let type = property.type!;
if (isIntrinsicType(type)) {
continue;
} else if (isArrayType(type)) {
const elementType = type.elementType;
if (isIntrinsicType(elementType) || isLiteralType(elementType)) {
continue;
} else if (isUnionType(elementType)) {
handleUnionType(elementType, thingName, property);
} else if (isReferenceType(elementType)) {
expect(SchemaSpec.thingNames).not.to.contain(
elementType.name,
`Array property '${property.name}' on type '${thingName}' has element type '${elementType.name}'.`,
);
} else {
// tslint:disable-next-line:max-line-length
fail(`'${thingName}'#'${property.name}' element type '${elementType.type}' is not handled by this test!`);
}
} else if (isReferenceType(type)) {
do {
expect(SchemaSpec.thingNames).not.to.contain(
type.name,
`Property '${property.name}' on type '${thingName}' has element type '${type.name}'.`,
);
const referencedObject = SchemaSpec.objects[type.name];
if (typeof referencedObject !== 'undefined') {
const referencedType = referencedObject.type;
if (typeof referencedType !== 'undefined') {
type = referencedType;
} else {
break;
}
} else {
break;
}
} while (isReferenceType(type));
} else if (isUnionType(type)) {
handleUnionType(type, thingName, property);
} else {
// tslint:disable-next-line:max-line-length
fail(`'${thingName}'#'${property.name}' with type '${type.type}' is not handled by this test!`);
}
}
}
}
}
@test
'things extend SCThing'() {
for (const thingName of SchemaSpec.thingNames) {
const thingReflection = SchemaSpec.objects[`${thingName}`];
expect(getExtendedTypes(thingReflection, SchemaSpec.objects)).to.contain(
'SCThing',
`'${thingName}' neither extends 'SCThing' transitively nor directly.`,
);
}
}
@test
'things without references do not extend SCThing'() {
for (const thingName of SchemaSpec.thingNames) {
const thingWithoutReferencesReflection = SchemaSpec.objects[`${thingName}WithoutReferences`];
expect(getExtendedTypes(thingWithoutReferencesReflection, SchemaSpec.objects)).not.to.contain(
'SCThing',
`'${thingName}WithoutReferences' extends 'SCThing' either transitively or directly.`,
);
}
}
@test @test
async 'validate against test files'() { async 'validate against test files'() {
const errorsPerFile = { const errorsPerFile = {

View File

@@ -16,11 +16,12 @@ import {assert, Has, IsAny, IsNever, NotHas} from 'conditional-type-checks';
import {SCThing, SCThingWithoutReferences} from '../src/things/abstract/thing'; import {SCThing, SCThingWithoutReferences} from '../src/things/abstract/thing';
import {SCAcademicEvent, SCAcademicEventWithoutReferences} from '../src/things/academic-event'; import {SCAcademicEvent, SCAcademicEventWithoutReferences} from '../src/things/academic-event';
import {SCArticle, SCArticleWithoutReferences} from '../src/things/article'; import {SCArticle, SCArticleWithoutReferences} from '../src/things/article';
import {SCAssessment, SCAssessmentWithoutReferences} from '../src/things/assessment';
import {SCBook, SCBookWithoutReferences} from '../src/things/book'; import {SCBook, SCBookWithoutReferences} from '../src/things/book';
import {SCBuilding, SCBuildingWithoutReferences} from '../src/things/building'; import {SCBuilding, SCBuildingWithoutReferences} from '../src/things/building';
import {SCCatalog, SCCatalogWithoutReferences} from '../src/things/catalog'; import {SCCatalog, SCCatalogWithoutReferences} from '../src/things/catalog';
import {SCContactPoint, SCContactPointWithoutReferences} from '../src/things/contact-point'; import {SCContactPoint, SCContactPointWithoutReferences} from '../src/things/contact-point';
import {SCCourseOfStudies, SCCourseOfStudiesWithoutReferences} from '../src/things/course-of-studies'; import {SCCourseOfStudy, SCCourseOfStudyWithoutReferences} from '../src/things/course-of-study';
import {SCDateSeries, SCDateSeriesWithoutReferences} from '../src/things/date-series'; import {SCDateSeries, SCDateSeriesWithoutReferences} from '../src/things/date-series';
import {SCDiff, SCDiffWithoutReferences} from '../src/things/diff'; import {SCDiff, SCDiffWithoutReferences} from '../src/things/diff';
import {SCDish, SCDishWithoutReferences} from '../src/things/dish'; import {SCDish, SCDishWithoutReferences} from '../src/things/dish';
@@ -107,6 +108,17 @@ assert<Has<SCArticlePropertyTypes, SCThing>>(false);
assert<Extends<SCArticleWithoutReferences, SCThing>>(false); assert<Extends<SCArticleWithoutReferences, SCThing>>(false);
assert<Extends<SCArticle, SCThing>>(true); assert<Extends<SCArticle, SCThing>>(true);
/**
* Types of properties of SCAssessment
*/
type SCAssessmentPropertyTypes = PropertyTypesNested<SCAssessment>;
assert<NotHas<SCAssessmentPropertyTypes, SCThingWithoutReferences>>(false);
assert<Has<SCAssessmentPropertyTypes, SCThingWithoutReferences>>(true);
assert<NotHas<SCAssessmentPropertyTypes, SCThing>>(true);
assert<Has<SCAssessmentPropertyTypes, SCThing>>(false);
assert<Extends<SCAssessmentWithoutReferences, SCThing>>(false);
assert<Extends<SCAssessment, SCThing>>(true);
/** /**
* Types of properties of SCBook * Types of properties of SCBook
*/ */
@@ -152,15 +164,15 @@ assert<Extends<SCCatalogWithoutReferences, SCThing>>(false);
assert<Extends<SCCatalog, SCThing>>(true); assert<Extends<SCCatalog, SCThing>>(true);
/** /**
* Types of properties of SCCourseOfStudies * Types of properties of SCCourseOfStudy
*/ */
type SCCourseOfStudiesPropertyTypes = PropertyTypesNested<SCCourseOfStudies>; type SCCourseOfStudyPropertyTypes = PropertyTypesNested<SCCourseOfStudy>;
assert<NotHas<SCCourseOfStudiesPropertyTypes, SCThingWithoutReferences>>(false); assert<NotHas<SCCourseOfStudyPropertyTypes, SCThingWithoutReferences>>(false);
assert<Has<SCCourseOfStudiesPropertyTypes, SCThingWithoutReferences>>(true); assert<Has<SCCourseOfStudyPropertyTypes, SCThingWithoutReferences>>(true);
assert<NotHas<SCCourseOfStudiesPropertyTypes, SCThing>>(true); assert<NotHas<SCCourseOfStudyPropertyTypes, SCThing>>(true);
assert<Has<SCCourseOfStudiesPropertyTypes, SCThing>>(false); assert<Has<SCCourseOfStudyPropertyTypes, SCThing>>(false);
assert<Extends<SCCourseOfStudiesWithoutReferences, SCThing>>(false); assert<Extends<SCCourseOfStudyWithoutReferences, SCThing>>(false);
assert<Extends<SCCourseOfStudies, SCThing>>(true); assert<Extends<SCCourseOfStudy, SCThing>>(true);
/** /**
* Types of properties of SCDateSeries * Types of properties of SCDateSeries

View File

@@ -1,6 +1,7 @@
{ {
"extends": "./node_modules/@openstapps/configuration/tslint.json", "extends": "./node_modules/@openstapps/configuration/tslint.json",
"rules": { "rules": {
"no-empty-interface": false "no-empty-interface": false,
"no-redundant-jsdoc": false
} }
} }