mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-10 19:52:53 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
321e4f6f24 | ||
|
|
8510f11d7b | ||
|
|
68aa377fe2 | ||
|
|
29f2c77ecc | ||
|
|
29bc00616e | ||
|
|
02920af4a4 | ||
|
|
0c14b0f1a0 | ||
|
|
db0a239761 | ||
|
|
377f55bbbe | ||
|
|
8d7a0e10c6 | ||
|
|
4865f911d1 | ||
|
|
15ae5e0873 | ||
|
|
a246bdea84 | ||
|
|
8641bfc877 | ||
|
|
d34e66fbbc |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,8 +1,28 @@
|
||||
# [0.38.0](https://gitlab.com/openstapps/core/compare/v0.37.0...v0.38.0) (2020-10-30)
|
||||
# [0.40.0](https://gitlab.com/openstapps/core/compare/v0.39.0...v0.40.0) (2021-02-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Replaced `jsonschema` package for `json-schema`
|
||||
* add range filter, date sorting support ([29bc006](https://gitlab.com/openstapps/core/commit/29bc00616e87a8d346d8c304fab2e3818921c75e))
|
||||
|
||||
|
||||
|
||||
# [0.39.0](https://gitlab.com/openstapps/core/compare/v0.38.1...v0.39.0) (2020-12-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* extend property value translation retrival ([a246bde](https://gitlab.com/openstapps/core/commit/a246bdea84e0ca390be6ab38723d637626db87d2))
|
||||
|
||||
|
||||
|
||||
## [0.38.1](https://gitlab.com/openstapps/core/compare/v0.38.0...v0.38.1) (2020-11-02)
|
||||
|
||||
|
||||
|
||||
# [0.38.0](https://gitlab.com/openstapps/core/compare/v0.37.0...v0.38.0) (2020-10-30)
|
||||
|
||||
|
||||
|
||||
# [0.37.0](https://gitlab.com/openstapps/core/compare/v0.36.0...v0.37.0) (2020-09-23)
|
||||
|
||||
|
||||
24
README.md
24
README.md
@@ -35,16 +35,18 @@ node --require ts-node/register src/cli.ts routes PATH/TO/ROUTES.md
|
||||
Annotations are used to add additional informations to fields, which are used to autogenerate mappings from the core objects.
|
||||
External dependencies can not be covered by the annotations. Documentation about some of the annotations can be found in: [typedoc](https://typedoc.org/guides/doccomments/)
|
||||
|
||||
| annotation | description | parameters |
|
||||
|-------------------|-------------------------------------------|---------------|
|
||||
| annotation | description | parameters |
|
||||
|-------------------|-------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
|
||||
| `@aggregatable` | used for generating of aggregations of the field if the core schema is used to put data into a database/key-value store | whether the property is being used on the top type or across all types: `global` |
|
||||
| `@float` | number field is interpreted as float | |
|
||||
| `@indexable` | marks the type as indexable if the core schema is used to put data into a database/key-value store| |
|
||||
| `@integer` | number field is interpreted as integer | |
|
||||
| `@keyword` | string field is interpreted as keyword | |
|
||||
| `@sortable` | field is sortable if the core schema is used to put data into a database/key-value store | sort method to be used: `ducet`, `price`, `distance` |
|
||||
| `@text` | string field is interpreted as text | |
|
||||
| `@validatable` | marks the type as validatable if the core schema is used to put data into a database/key-value store | |
|
||||
| `@filterable` | non-object/nested field is filterable if the core schema is used to put data into a database/key-value store | |
|
||||
|
||||
| `@float` | number field is interpreted as float | |
|
||||
| `@indexable` | marks the type as indexable if the core schema is used to put data into a database/key-value store | |
|
||||
| `@integer` | number field is interpreted as integer | |
|
||||
| `@keyword` | string field is interpreted as keyword | |
|
||||
| `@sortable` | field is sortable if the core schema is used to put data into a database/key-value store. Fields are always sortable through generic sort, even without annotation. | sort method to be used: `ducet`, `price`, `distance` |
|
||||
| `@text` | string field is interpreted as text | |
|
||||
| `@date` | string field is interpreted as a date field | |
|
||||
| `@validatable` | marks the type as validatable if the core schema is used to put data into a database/key-value store | |
|
||||
| `@filterable` | non-object/nested field is filterable if the core schema is used to put data into a database/key-value store | |
|
||||
| `@inheritTags` | inherit all tags from another field | `[SCThingType]::[field]` |
|
||||
|
||||
*Note: tags ignore casing, but for consistency they should use the variants proposed here.*
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openstapps/core",
|
||||
"version": "0.38.1",
|
||||
"version": "0.41.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openstapps/core",
|
||||
"version": "0.38.1",
|
||||
"version": "0.41.0",
|
||||
"description": "StAppsCore - Generalized model of data",
|
||||
"keywords": [
|
||||
"Model",
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*
|
||||
* @pattern ^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$
|
||||
* @see https://gist.github.com/philipashlock/8830168
|
||||
*
|
||||
* @date
|
||||
*/
|
||||
export type SCISO8601Date = string;
|
||||
/* tslint:enable */
|
||||
|
||||
@@ -19,6 +19,7 @@ import {SCMap} from '../../general/map';
|
||||
import {SCSearchAvailabilityFilter} from './filters/availability';
|
||||
import {SCSearchBooleanFilter} from './filters/boolean';
|
||||
import {SCSearchDistanceFilter} from './filters/distance';
|
||||
import {SCSearchDateRangeFilter, SCSearchNumericRangeFilter} from './filters/range';
|
||||
import {SCSearchValueFilter} from './filters/value';
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,9 @@ export type SCSearchFilterType =
|
||||
'availability'
|
||||
| 'boolean'
|
||||
| 'distance'
|
||||
| 'value';
|
||||
| 'value'
|
||||
| 'date range'
|
||||
| 'numeric range';
|
||||
|
||||
/**
|
||||
* Structure of a filter instruction
|
||||
@@ -57,4 +60,6 @@ export type SCSearchFilter =
|
||||
SCSearchAvailabilityFilter
|
||||
| SCSearchBooleanFilter
|
||||
| SCSearchDistanceFilter
|
||||
| SCSearchValueFilter;
|
||||
| SCSearchValueFilter
|
||||
| SCSearchNumericRangeFilter
|
||||
| SCSearchDateRangeFilter;
|
||||
|
||||
112
src/protocol/search/filters/range.ts
Normal file
112
src/protocol/search/filters/range.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 {SCThingsField} from '../../../meta';
|
||||
import {SCSearchAbstractFilter, SCSearchAbstractFilterArguments} from '../filter';
|
||||
|
||||
/**
|
||||
* A date range filter
|
||||
*
|
||||
* Filter for documents with a date field that satisfies the given constraints
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-range-query.html#_date_format_in_range_queries
|
||||
*/
|
||||
export interface SCSearchDateRangeFilter extends SCSearchAbstractFilter<SCDateRangeFilterArguments> {
|
||||
/**
|
||||
* @see SCSearchAbstractFilter.type
|
||||
*/
|
||||
type: 'date range';
|
||||
}
|
||||
|
||||
/**
|
||||
* A distance filter
|
||||
*
|
||||
* Filter for documents with a numeric field that satisfies the given constraints
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-range-query.html#query-dsl-range-query
|
||||
*/
|
||||
export interface SCSearchNumericRangeFilter extends SCSearchAbstractFilter<SCNumericRangeFilterArguments> {
|
||||
/**
|
||||
* @see SCSearchAbstractFilter.type
|
||||
*/
|
||||
type: 'numeric range';
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional arguments for date range filters
|
||||
*
|
||||
* Filter uses a plain string to allow for date math expressions
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/date-math-expressions.html
|
||||
*/
|
||||
export interface SCDateRangeFilterArguments extends SCRangeFilterArguments<string> {
|
||||
/**
|
||||
* Optional date format specifier
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-range-query.html#_date_format_in_range_queries
|
||||
*/
|
||||
format?: string;
|
||||
|
||||
/**
|
||||
* Optional timezone specifier
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-range-query.html#_time_zone_in_range_queries
|
||||
*/
|
||||
timeZone?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional arguments for numeric range filters
|
||||
*/
|
||||
export type SCNumericRangeFilterArguments = SCRangeFilterArguments<number>;
|
||||
|
||||
/**
|
||||
* Additional arguments for range filters
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-range-query.html#query-dsl-range-query
|
||||
*/
|
||||
export interface SCRangeFilterArguments<T> extends SCSearchAbstractFilterArguments {
|
||||
/**
|
||||
* Bounds of the range
|
||||
*/
|
||||
bounds: Bounds<T>;
|
||||
|
||||
/**
|
||||
* Field where the filter will be applied
|
||||
*/
|
||||
field: SCThingsField;
|
||||
}
|
||||
|
||||
export interface Bounds<T> {
|
||||
/**
|
||||
* The lower bound
|
||||
*/
|
||||
lowerBound?: Bound<T>;
|
||||
|
||||
/**
|
||||
* The upper bound
|
||||
*/
|
||||
upperBound?: Bound<T>;
|
||||
}
|
||||
|
||||
export interface Bound<T> {
|
||||
/**
|
||||
* Limit of the bound
|
||||
*/
|
||||
limit: T;
|
||||
|
||||
/**
|
||||
* Bound mode
|
||||
*/
|
||||
mode: 'inclusive' | 'exclusive';
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* Copyright (C) 2019, 2020 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.
|
||||
@@ -16,6 +16,7 @@ import {SCMap} from '../../general/map';
|
||||
import {SCThingsField} from '../../meta';
|
||||
import {SCDistanceSort} from './sorts/distance';
|
||||
import {SCDucetSort} from './sorts/ducet';
|
||||
import {SCGenericSort} from './sorts/generic';
|
||||
import {SCPriceSort} from './sorts/price';
|
||||
|
||||
/**
|
||||
@@ -51,9 +52,9 @@ export interface SCSearchAbstractSortArguments extends SCMap<unknown> {
|
||||
/**
|
||||
* Type of a sort instruction
|
||||
*/
|
||||
export type SCSearchSortType = 'distance' | 'price' | 'ducet';
|
||||
export type SCSearchSortType = 'distance' | 'price' | 'ducet' | 'generic';
|
||||
|
||||
/**
|
||||
* A sort instruction
|
||||
*/
|
||||
export type SCSearchSort = SCDistanceSort | SCPriceSort | SCDucetSort;
|
||||
export type SCSearchSort = SCDistanceSort | SCPriceSort | SCDucetSort | SCGenericSort;
|
||||
|
||||
25
src/protocol/search/sorts/generic.ts
Normal file
25
src/protocol/search/sorts/generic.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 {SCSearchAbstractSort, SCSearchAbstractSortArguments} from '../sort';
|
||||
|
||||
/**
|
||||
* Sort instruction for generic sort such as date
|
||||
*/
|
||||
export interface SCGenericSort extends SCSearchAbstractSort<SCSearchAbstractSortArguments> {
|
||||
/**
|
||||
* @see SCSearchAbstractSort.type
|
||||
*/
|
||||
type: 'generic';
|
||||
}
|
||||
@@ -91,6 +91,13 @@ export interface SCDish
|
||||
|
||||
export interface SCDishTranslatableProperties
|
||||
extends SCThingWithCategoriesTranslatableProperties, SCThingThatCanBeOfferedTranslatableProperties {
|
||||
/**
|
||||
* Additives of the dish
|
||||
*
|
||||
* @filterable
|
||||
* @keyword
|
||||
*/
|
||||
additives?: string[];
|
||||
/**
|
||||
* Characteristics of the dish
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface SCSemesterWithoutReferences
|
||||
* The short name of the semester, using the given pattern.
|
||||
*
|
||||
* @filterable
|
||||
* @pattern ^(WS|SS) [0-9]{4}(/[0-9]{2})?$
|
||||
* @pattern ^(WS|SS|WiSe|SoSe) [0-9]{4}(/[0-9]{2})?$
|
||||
* @keyword
|
||||
*/
|
||||
acronym: string;
|
||||
|
||||
@@ -224,29 +224,27 @@ export class SCThingTranslator {
|
||||
*/
|
||||
public translatedPropertyNames<T extends SCThing>(type: SCThingType,
|
||||
language?: keyof SCTranslations<T>): T | undefined {
|
||||
const targetLanguage = (typeof language !== 'undefined') ? language : this.language;
|
||||
|
||||
return this.getAllMetaFieldTranslations(type, targetLanguage) as T;
|
||||
return this.getAllMetaFieldTranslations(type, language ?? this.language) as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a SCThingType this function will translate it
|
||||
*
|
||||
* @param type The type that will be translated
|
||||
* @param language The language the type will be translated to
|
||||
* @returns Known translation of type parameter
|
||||
* Given a SCThingType and a corresponding property name it returns the known property value translation
|
||||
* Access pattern to the meta object containing the translation can be thought of as type.field[key] with key being optional
|
||||
* @example
|
||||
* const translatedMetaDish = translator.translatedPropertyNames(SCThingType.Dish, 'categories', 'main dish');
|
||||
* @param type The type for whose property values a translation is required
|
||||
* @param field The property for which a translation is required
|
||||
* @param key If specified tries to access the field with this key
|
||||
* @param language The language all property names will be translated to
|
||||
* @returns Known translation for the property
|
||||
*/
|
||||
public translatedThingType<T extends unknown>(type: SCThingType,
|
||||
language?: keyof SCTranslations<T>): string {
|
||||
const targetLanguage = (typeof language !== 'undefined') ? language : this.language;
|
||||
const metaClass = this.getMetaClassInstance(type);
|
||||
public translatedPropertyValue<T extends unknown>(type: SCThingType,
|
||||
field: string,
|
||||
key?: string,
|
||||
language?: keyof SCTranslations<T>): string | undefined {
|
||||
const fieldTranslation = this.getMetaClassInstance(type).fieldValueTranslations[language ?? this.language]?.[field];
|
||||
|
||||
if (typeof metaClass.fieldValueTranslations[targetLanguage] !== 'undefined' &&
|
||||
typeof metaClass.fieldValueTranslations[targetLanguage].type !== 'undefined') {
|
||||
return metaClass.fieldValueTranslations[targetLanguage].type as string ;
|
||||
}
|
||||
|
||||
return type;
|
||||
return fieldTranslation?.[key ?? ''] ?? key ?? fieldTranslation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"uid": "7cebbc3e-0a21-5371-ab0d-f7ba12f53dbd",
|
||||
"type": "semester",
|
||||
"name": "Sommersemester 2018",
|
||||
"acronym": "SS 2018",
|
||||
"acronym": "SoSe 2018",
|
||||
"alternateNames": [
|
||||
"SoSe 2018"
|
||||
"Sommer 2018"
|
||||
],
|
||||
"startDate": "2018-04-01",
|
||||
"endDate": "2018-09-30",
|
||||
|
||||
@@ -269,13 +269,23 @@ export class MetaTranslationSpec {
|
||||
}
|
||||
|
||||
@test
|
||||
public retrieveTranslatedThingType() {
|
||||
const dishTypeDE = translator.translatedThingType(dish.type);
|
||||
const dishTypeEN = translator.translatedThingType(dish.type, 'en');
|
||||
const dishTypeBASE = translatorWithFallback.translatedThingType(dish.type);
|
||||
public retrieveTranslatedPropertyValueType() {
|
||||
const dishTypeDE = translator.translatedPropertyValue(dish.type, 'type');
|
||||
const dishTypeEN = translator.translatedPropertyValue(dish.type, 'type', undefined, 'en');
|
||||
const dishTypeBASE = translatorWithFallback.translatedPropertyValue(dish.type, 'type');
|
||||
expect(dishTypeDE).to.deep.equal(SCDishMeta.getInstance().fieldValueTranslations.de.type);
|
||||
expect(dishTypeEN).to.deep.equal(SCDishMeta.getInstance().fieldValueTranslations.en.type);
|
||||
expect(dishTypeBASE).to.deep.equal(SCDishMeta.getInstance().fieldValueTranslations.en.type);
|
||||
expect(dishTypeBASE).to.be.undefined;
|
||||
}
|
||||
|
||||
@test
|
||||
public retrieveTranslatedPropertyValueNested() {
|
||||
const dishTypeDE = translator.translatedPropertyValue<SCDish>(dish.type, 'categories', 'main dish');
|
||||
const dishTypeEN = translator.translatedPropertyValue<SCDish>(dish.type, 'categories', 'main dish', 'en');
|
||||
const dishTypeBASE = translatorWithFallback.translatedPropertyValue(dish.type, 'categories', 'main dish');
|
||||
expect(dishTypeDE).to.deep.equal(SCDishMeta.getInstance<SCDishMeta>().fieldValueTranslations.de.categories['main dish']);
|
||||
expect(dishTypeEN).to.deep.equal(dish.categories[0]);
|
||||
expect(dishTypeBASE).to.deep.equal(dish.categories[0]);
|
||||
}
|
||||
|
||||
@test
|
||||
|
||||
Reference in New Issue
Block a user