componentsjs 4.5.0 → 5.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/README.md +16 -0
  3. package/components/context.jsonld +87 -2
  4. package/lib/ComponentsManager.js +3 -5
  5. package/lib/construction/ConfigConstructor.js +7 -14
  6. package/lib/construction/argument/ArgumentConstructorHandlerHash.js +3 -2
  7. package/lib/construction/strategy/ConstructionStrategyCommonJsString.js +3 -0
  8. package/lib/construction/strategy/IConstructionStrategy.d.ts +2 -2
  9. package/lib/loading/ComponentRegistry.js +1 -1
  10. package/lib/loading/ComponentRegistryFinalizer.js +25 -4
  11. package/lib/preprocess/ConfigPreprocessorComponent.d.ts +3 -1
  12. package/lib/preprocess/ConfigPreprocessorComponent.js +34 -12
  13. package/lib/preprocess/ConfigPreprocessorComponentMapped.d.ts +4 -3
  14. package/lib/preprocess/ConfigPreprocessorComponentMapped.js +17 -18
  15. package/lib/preprocess/GenericsContext.d.ts +74 -0
  16. package/lib/preprocess/GenericsContext.js +326 -0
  17. package/lib/preprocess/ParameterHandler.d.ts +6 -2
  18. package/lib/preprocess/ParameterHandler.js +23 -21
  19. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerCollectEntries.d.ts +3 -2
  20. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerCollectEntries.js +24 -10
  21. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerElements.d.ts +2 -1
  22. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerElements.js +8 -5
  23. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerFields.d.ts +2 -1
  24. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerFields.js +16 -9
  25. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerKeyValue.d.ts +4 -3
  26. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerKeyValue.js +12 -12
  27. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerList.d.ts +2 -1
  28. package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerList.js +9 -22
  29. package/lib/preprocess/constructorargumentsmapping/IConstructorArgumentsElementMappingHandler.d.ts +5 -2
  30. package/lib/preprocess/constructorargumentsmapping/IConstructorArgumentsMapper.d.ts +5 -2
  31. package/lib/preprocess/parameterproperty/IParameterPropertyHandler.d.ts +5 -2
  32. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefault.d.ts +6 -3
  33. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefault.js +20 -3
  34. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefaultScoped.d.ts +2 -2
  35. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefaultScoped.js +16 -5
  36. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerFixed.d.ts +5 -3
  37. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerFixed.js +25 -2
  38. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerLazy.d.ts +2 -2
  39. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerLazy.js +10 -3
  40. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.d.ts +38 -4
  41. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.js +412 -31
  42. package/lib/rdf/RdfParser.d.ts +1 -1
  43. package/lib/rdf/RdfParser.js +16 -4
  44. package/lib/rdf/RdfStreamIncluder.js +1 -1
  45. package/lib/util/ErrorResourcesContext.d.ts +11 -14
  46. package/lib/util/ErrorResourcesContext.js +44 -22
  47. package/package.json +2 -2
  48. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRequired.d.ts +0 -11
  49. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRequired.js +0 -23
  50. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerUnique.d.ts +0 -12
  51. package/lib/preprocess/parameterproperty/ParameterPropertyHandlerUnique.js +0 -34
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConfigPreprocessorComponent = void 0;
4
4
  const Iris_1 = require("../rdf/Iris");
5
5
  const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
6
+ const GenericsContext_1 = require("./GenericsContext");
6
7
  /**
7
8
  * Handles config that refer to a component as type.
8
9
  * The component may have parameters that can be applied on the config.
@@ -82,34 +83,55 @@ class ConfigPreprocessorComponent {
82
83
  if (requireElement) {
83
84
  configRaw.property.requireElement = requireElement;
84
85
  }
85
- configRaw.properties.arguments = this.transformConstructorArguments(config, handleResponse);
86
+ configRaw.property.arguments = this.transformConstructorArguments(config, handleResponse);
86
87
  // Validate the input config
87
88
  this.validateConfig(config, handleResponse);
88
89
  return configRaw;
89
90
  }
91
+ createGenericsContext(handleResponse, config) {
92
+ // Create a new generics context for the component's generic type parameters
93
+ const genericsContext = new GenericsContext_1.GenericsContext(this.objectLoader, handleResponse.component.properties.genericTypeParameters);
94
+ // If the config has a genericTypeInstancesComponentScope, it will also have genericTypeInstances.
95
+ // In that case, we bind these instances to the component's generic type parameters within the context.
96
+ // (these values may have been set during generic param type-checking in
97
+ // ParameterPropertyHandlerRange#hasParamValueValidType)
98
+ if (config.property.genericTypeInstancesComponentScope &&
99
+ handleResponse.component.value === config.property.genericTypeInstancesComponentScope.value) {
100
+ genericsContext.bindComponentGenericTypes(handleResponse.component, config.properties.genericTypeInstances, { config }, (subType, superType) => this.parameterHandler.parameterPropertyHandlerRange
101
+ .hasType(subType, superType, genericsContext, config.property.genericTypeInstancesComponentScope, config.properties.genericTypeInstances, { config }));
102
+ }
103
+ return genericsContext;
104
+ }
90
105
  /**
91
106
  * Determine the constructor arguments of the given config.
92
107
  * @param config A config.
93
108
  * @param handleResponse Return value of the {#canHandle}.
94
109
  */
95
110
  transformConstructorArguments(config, handleResponse) {
96
- // Create a single-arg hash constructor, and add all params as key-value pairs
97
- const param0 = this.objectLoader.createCompactedResource({
98
- // Hack to enforce ArgumentConstructorHandlerHash
99
- hasFields: '"true"',
100
- });
111
+ const entries = [];
112
+ const genericsContext = this.createGenericsContext(handleResponse, config);
101
113
  for (const fieldData of handleResponse.component.properties.parameters) {
102
114
  const field = this.objectLoader.createCompactedResource({});
103
115
  field.property.key = this.objectLoader.createCompactedResource(`"${fieldData.term.value}"`);
104
- for (const value of this.parameterHandler.applyParameterValues(handleResponse.component, fieldData, config)) {
105
- field.properties.value.push(value);
116
+ const value = this.parameterHandler
117
+ .applyParameterValues(handleResponse.component, fieldData, config, genericsContext);
118
+ if (value) {
119
+ field.property.value = value;
106
120
  }
107
- param0.properties.fields.push(field);
121
+ entries.push(field);
108
122
  }
123
+ // Create a single-arg hash constructor, and add all params as key-value pairs
124
+ const param0 = this.objectLoader.createCompactedResource({
125
+ fields: {
126
+ list: entries,
127
+ },
128
+ });
109
129
  // Create constructor arguments list
110
- const args = this.objectLoader.createCompactedResource({});
111
- args.list = [param0];
112
- return [args];
130
+ return this.objectLoader.createCompactedResource({
131
+ list: [
132
+ param0,
133
+ ],
134
+ });
113
135
  }
114
136
  /**
115
137
  * Let this config inherit parameter values from previously instantiated configs.
@@ -2,6 +2,7 @@ import type { Resource } from 'rdf-object';
2
2
  import type { IComponentConfigPreprocessorHandleResponse } from './ConfigPreprocessorComponent';
3
3
  import { ConfigPreprocessorComponent } from './ConfigPreprocessorComponent';
4
4
  import type { IConstructorArgumentsMapper } from './constructorargumentsmapping/IConstructorArgumentsMapper';
5
+ import type { GenericsContext } from './GenericsContext';
5
6
  /**
6
7
  * Handles config that refer to a component as type.
7
8
  * The component may have parameters that can be applied on the config.
@@ -10,7 +11,7 @@ import type { IConstructorArgumentsMapper } from './constructorargumentsmapping/
10
11
  export declare class ConfigPreprocessorComponentMapped extends ConfigPreprocessorComponent implements IConstructorArgumentsMapper {
11
12
  private readonly mappingHandlers;
12
13
  canHandle(config: Resource): IComponentConfigPreprocessorHandleResponse | undefined;
13
- transformConstructorArguments(config: Resource, handleResponse: IComponentConfigPreprocessorHandleResponse): Resource[];
14
- applyConstructorArgumentsParameters(configRoot: Resource, constructorArgs: Resource, configElement: Resource): Resource[];
15
- getParameterValue(configRoot: Resource, parameter: Resource, configElement: Resource, rawValue: boolean): Resource[];
14
+ transformConstructorArguments(config: Resource, handleResponse: IComponentConfigPreprocessorHandleResponse): Resource;
15
+ applyConstructorArgumentsParameters(configRoot: Resource, constructorArgs: Resource, configElement: Resource, genericsContext: GenericsContext): Resource;
16
+ getParameterValue(configRoot: Resource, parameter: Resource, configElement: Resource, rawValue: boolean, genericsContext: GenericsContext): Resource | undefined;
16
17
  }
@@ -33,39 +33,38 @@ class ConfigPreprocessorComponentMapped extends ConfigPreprocessorComponent_1.Co
33
33
  }
34
34
  transformConstructorArguments(config, handleResponse) {
35
35
  const constructorArgs = handleResponse.component.property.constructorArguments;
36
- return this.applyConstructorArgumentsParameters(config, constructorArgs, config);
36
+ const genericsContext = this.createGenericsContext(handleResponse, config);
37
+ return this.applyConstructorArgumentsParameters(config, constructorArgs, config, genericsContext);
37
38
  }
38
- applyConstructorArgumentsParameters(configRoot, constructorArgs, configElement) {
39
+ applyConstructorArgumentsParameters(configRoot, constructorArgs, configElement, genericsContext) {
39
40
  // Check if this constructor args resource can be handled by one of the built-in handlers.
40
41
  for (const handler of this.mappingHandlers) {
41
- if (handler.canHandle(configRoot, constructorArgs, configElement, this)) {
42
- return handler.handle(configRoot, constructorArgs, configElement, this);
42
+ if (handler.canHandle(configRoot, constructorArgs, configElement, this, genericsContext)) {
43
+ return handler.handle(configRoot, constructorArgs, configElement, this, genericsContext);
43
44
  }
44
45
  }
45
46
  // Fallback to original constructor args
46
- return [constructorArgs];
47
+ return constructorArgs;
47
48
  }
48
- getParameterValue(configRoot, parameter, configElement, rawValue) {
49
- var _a;
49
+ getParameterValue(configRoot, parameter, configElement, rawValue, genericsContext) {
50
50
  let valueOut;
51
51
  if (parameter.type === 'NamedNode' && parameter.value === Iris_1.IRIS_RDF.subject) {
52
- valueOut = [this.objectLoader.createCompactedResource(`"${configElement.value}"`)];
53
- valueOut[0].property.unique = this.objectLoader.createCompactedResource('"true"');
52
+ valueOut = this.objectLoader.createCompactedResource(`"${configElement.value}"`);
54
53
  }
55
- else if (parameter.type === 'NamedNode') {
56
- valueOut = this.parameterHandler.applyParameterValues(configRoot, parameter, configElement);
54
+ else if (parameter.type === 'NamedNode' && !parameter.property.fields) {
55
+ valueOut = this.parameterHandler
56
+ .applyParameterValues(configRoot, parameter, configElement, genericsContext);
57
57
  }
58
58
  else {
59
- valueOut = this.applyConstructorArgumentsParameters(configRoot, parameter, configElement);
59
+ valueOut = this.applyConstructorArgumentsParameters(configRoot, parameter, configElement, genericsContext);
60
60
  }
61
61
  // If the referenced IRI should become a plain string
62
62
  if (rawValue) {
63
- const unique = ((_a = valueOut[0].property.unique) === null || _a === void 0 ? void 0 : _a.value) === 'true';
64
- valueOut = [this.objectLoader.createCompactedResource(`"${valueOut[0].value}"`)];
65
- // Make sure to inherit the original param's unique flag
66
- if (unique) {
67
- valueOut[0].property.unique = this.objectLoader.createCompactedResource('"true"');
68
- }
63
+ valueOut = (valueOut === null || valueOut === void 0 ? void 0 : valueOut.list) ?
64
+ this.objectLoader.createCompactedResource({
65
+ list: valueOut.list.map(valueOutSub => `"${valueOutSub.value}"`),
66
+ }) :
67
+ this.objectLoader.createCompactedResource(`"${valueOut ? valueOut.value : 'undefined'}"`);
69
68
  }
70
69
  return valueOut;
71
70
  }
@@ -0,0 +1,74 @@
1
+ import type * as RDF from '@rdfjs/types';
2
+ import type { Resource, RdfObjectLoader } from 'rdf-object';
3
+ import type { IParamValueConflict } from './parameterproperty/ParameterPropertyHandlerRange';
4
+ /**
5
+ * Context for binding generic types to a concrete range value.
6
+ */
7
+ export declare class GenericsContext {
8
+ private static readonly XSD_INHERITANCE_TABLE;
9
+ private readonly objectLoader;
10
+ /**
11
+ * Set of generic type ids.
12
+ * @private
13
+ */
14
+ genericTypeIds: Record<string, boolean>;
15
+ /**
16
+ * Mapping of generic type id to the resolved range.
17
+ * @private
18
+ */
19
+ bindings: Record<string, Resource>;
20
+ constructor(objectLoader: RdfObjectLoader, genericTypeParameters: Resource[]);
21
+ /**
22
+ * Try to to bind the given value to the given generic.
23
+ * @param genericTypeId IRI of the generic to bind.
24
+ * @param value The value to bind to.
25
+ * @param valueTypeValidator Callback for validating values against types.
26
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
27
+ * @return boolean True if the binding was valid and took place.
28
+ */
29
+ bindGenericTypeToValue(genericTypeId: string, value: Resource | undefined, valueTypeValidator: (subValue: Resource | undefined, subType: Resource) => IParamValueConflict | undefined, typeTypeValidator: (subValue: Resource, subType: Resource) => IParamValueConflict | undefined): IParamValueConflict | undefined;
30
+ /**
31
+ * Try to bind the given range to the given generic.
32
+ * @param genericTypeId IRI of the generic to bind.
33
+ * @param range The range to bind to.
34
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
35
+ * @return boolean True if the binding was valid and took place.
36
+ */
37
+ bindGenericTypeToRange(genericTypeId: string, range: Resource, typeTypeValidator: (subType: Resource, superType: Resource) => IParamValueConflict | undefined): IParamValueConflict | undefined;
38
+ /**
39
+ * Infer the parameter range of the given value.
40
+ * @param value A value.
41
+ */
42
+ inferValueRange(value: Resource | undefined): Resource | undefined;
43
+ /**
44
+ * Merge the given ranges into a new range.
45
+ * This will return undefined in the ranges are incompatible.
46
+ *
47
+ * If one type is more specific than the other, it will return the narrowest type.
48
+ *
49
+ * @param rangeA A first range.
50
+ * @param rangeB A second range.
51
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
52
+ */
53
+ mergeRanges(rangeA: Resource, rangeB: Resource, typeTypeValidator: (subType: Resource, superType: Resource) => IParamValueConflict | undefined): Resource | undefined;
54
+ protected mergeUnion(rangeUnion: Resource, rangeOther: Resource, typeValidator: (subType: Resource, superType: Resource) => IParamValueConflict | undefined): Resource | undefined;
55
+ /**
56
+ * Check if the given type is a subtype of the given super type.
57
+ * @param type A type node.
58
+ * @param potentialSuperType A potential super type node.
59
+ */
60
+ isXsdSubType(type: RDF.Term, potentialSuperType: RDF.Term): boolean;
61
+ /**
62
+ * Apply the give generic type instances for the given component's generic type parameters.
63
+ *
64
+ * This will throw if the number of passed instances does not match with
65
+ * the number of generic type parameters on the component.
66
+ *
67
+ * @param component The component
68
+ * @param genericTypeInstances The generic type instances to apply.
69
+ * @param errorContext The context for error reporting.
70
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
71
+ * @return boolean False if the application failed due to a binding error. True otherwise
72
+ */
73
+ bindComponentGenericTypes(component: Resource, genericTypeInstances: Resource[], errorContext: Record<string, Resource | Resource[] | string>, typeTypeValidator: (subValue: Resource, subType: Resource) => IParamValueConflict | undefined): IParamValueConflict | undefined;
74
+ }
@@ -0,0 +1,326 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GenericsContext = void 0;
4
+ const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
5
+ const ParameterPropertyHandlerRange_1 = require("./parameterproperty/ParameterPropertyHandlerRange");
6
+ /**
7
+ * Context for binding generic types to a concrete range value.
8
+ */
9
+ class GenericsContext {
10
+ constructor(objectLoader, genericTypeParameters) {
11
+ this.objectLoader = objectLoader;
12
+ this.genericTypeIds = Object.fromEntries(genericTypeParameters
13
+ .map(genericTypeParameter => [genericTypeParameter.value, true]));
14
+ this.bindings = {};
15
+ for (const genericTypeParameter of genericTypeParameters) {
16
+ if (genericTypeParameter.property.range) {
17
+ this.bindings[genericTypeParameter.value] = genericTypeParameter.property.range;
18
+ }
19
+ }
20
+ }
21
+ /**
22
+ * Try to to bind the given value to the given generic.
23
+ * @param genericTypeId IRI of the generic to bind.
24
+ * @param value The value to bind to.
25
+ * @param valueTypeValidator Callback for validating values against types.
26
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
27
+ * @return boolean True if the binding was valid and took place.
28
+ */
29
+ bindGenericTypeToValue(genericTypeId, value, valueTypeValidator, typeTypeValidator) {
30
+ // Fail if an unknown generic type is referenced
31
+ if (!(genericTypeId in this.genericTypeIds)) {
32
+ return {
33
+ description: `unknown generic <${genericTypeId}> is being referenced`,
34
+ context: { value },
35
+ };
36
+ }
37
+ // If the generic was already bound to a range, validate it
38
+ const existingRange = this.bindings[genericTypeId];
39
+ if (existingRange) {
40
+ const subConflict = valueTypeValidator(value, existingRange);
41
+ if (subConflict) {
42
+ return {
43
+ description: `generic <${genericTypeId}> with existing range "${ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange.rangeToDisplayString(existingRange, this)}" can not contain the given value`,
44
+ context: { existingRange, value },
45
+ causes: [subConflict],
46
+ };
47
+ }
48
+ }
49
+ // Infer type of value
50
+ const valueRange = this.inferValueRange(value);
51
+ if (!valueRange) {
52
+ return;
53
+ }
54
+ // Save inferred type
55
+ return this.bindGenericTypeToRange(genericTypeId, valueRange, typeTypeValidator);
56
+ }
57
+ /**
58
+ * Try to bind the given range to the given generic.
59
+ * @param genericTypeId IRI of the generic to bind.
60
+ * @param range The range to bind to.
61
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
62
+ * @return boolean True if the binding was valid and took place.
63
+ */
64
+ bindGenericTypeToRange(genericTypeId, range, typeTypeValidator) {
65
+ // Fail if an unknown generic type is referenced
66
+ if (!(genericTypeId in this.genericTypeIds)) {
67
+ return {
68
+ description: `unknown generic <${genericTypeId}> is being referenced`,
69
+ context: {},
70
+ };
71
+ }
72
+ // If we already had a range, check if they match
73
+ if (this.bindings[genericTypeId]) {
74
+ const mergedRange = this.mergeRanges(this.bindings[genericTypeId], range, typeTypeValidator);
75
+ if (!mergedRange) {
76
+ return {
77
+ description: `generic <${genericTypeId}> with existing range "${ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange.rangeToDisplayString(this.bindings[genericTypeId], this)}" can not be bound to range "${ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange.rangeToDisplayString(range, this)}"`,
78
+ context: {
79
+ existingRange: this.bindings[genericTypeId],
80
+ newRange: range,
81
+ },
82
+ };
83
+ }
84
+ range = mergedRange;
85
+ }
86
+ this.bindings[genericTypeId] = range;
87
+ }
88
+ /**
89
+ * Infer the parameter range of the given value.
90
+ * @param value A value.
91
+ */
92
+ inferValueRange(value) {
93
+ // Value is undefined
94
+ if (!value) {
95
+ return this.objectLoader.createCompactedResource({ '@type': 'ParameterRangeUndefined' });
96
+ }
97
+ // Value is a literal
98
+ if (value.term.termType === 'Literal') {
99
+ return this.objectLoader.createCompactedResource(value.term.datatype);
100
+ }
101
+ // Value is a named node
102
+ const types = value.properties.type;
103
+ if (types.length > 1) {
104
+ return this.objectLoader.createCompactedResource({
105
+ '@type': 'ParameterRangeUnion',
106
+ parameterRangeElements: types,
107
+ });
108
+ }
109
+ return types[0];
110
+ }
111
+ /**
112
+ * Merge the given ranges into a new range.
113
+ * This will return undefined in the ranges are incompatible.
114
+ *
115
+ * If one type is more specific than the other, it will return the narrowest type.
116
+ *
117
+ * @param rangeA A first range.
118
+ * @param rangeB A second range.
119
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
120
+ */
121
+ mergeRanges(rangeA, rangeB, typeTypeValidator) {
122
+ var _a, _b;
123
+ // Check if one is a subtype of the other (and return the most specific type)
124
+ if (!typeTypeValidator(rangeA, rangeB)) {
125
+ return rangeA;
126
+ }
127
+ if (!typeTypeValidator(rangeB, rangeA)) {
128
+ return rangeB;
129
+ }
130
+ // Check XSD inheritance relationship
131
+ if (this.isXsdSubType(rangeA.term, rangeB.term)) {
132
+ return rangeA;
133
+ }
134
+ if (this.isXsdSubType(rangeB.term, rangeA.term)) {
135
+ return rangeB;
136
+ }
137
+ // If a range is a wildcard, return the other type
138
+ if (rangeA.isA('ParameterRangeWildcard')) {
139
+ return rangeB;
140
+ }
141
+ if (rangeB.isA('ParameterRangeWildcard')) {
142
+ return rangeA;
143
+ }
144
+ // Ranges always match with generic references
145
+ if (rangeA.isA('ParameterRangeGenericTypeReference')) {
146
+ return rangeB;
147
+ }
148
+ if (rangeB.isA('ParameterRangeGenericTypeReference')) {
149
+ return rangeA;
150
+ }
151
+ // Check parameter range types
152
+ if ((_a = rangeA.property.type) === null || _a === void 0 ? void 0 : _a.term.equals((_b = rangeB.property.type) === null || _b === void 0 ? void 0 : _b.term)) {
153
+ // Check sub-value for specific param range cases
154
+ if (rangeA.isA('ParameterRangeArray') ||
155
+ rangeA.isA('ParameterRangeRest') ||
156
+ rangeA.isA('ParameterRangeKeyof')) {
157
+ const valueA = rangeA.property.parameterRangeValue;
158
+ const valueB = rangeB.property.parameterRangeValue;
159
+ const merged = this.mergeRanges(valueA, valueB, typeTypeValidator);
160
+ if (!merged) {
161
+ return;
162
+ }
163
+ return this.objectLoader.createCompactedResource({
164
+ '@type': rangeA.property.type,
165
+ parameterRangeValue: merged,
166
+ });
167
+ }
168
+ // Check sub-values for specific param range cases
169
+ if (rangeA.isA('ParameterRangeUnion') ||
170
+ rangeA.isA('ParameterRangeIntersection') ||
171
+ rangeA.isA('ParameterRangeTuple')) {
172
+ const valuesA = rangeA.properties.parameterRangeElements;
173
+ const valuesB = rangeB.properties.parameterRangeElements;
174
+ if (valuesA.length !== valuesB.length) {
175
+ return;
176
+ }
177
+ const merged = valuesA.map((valueA, i) => this.mergeRanges(valueA, valuesB[i], typeTypeValidator));
178
+ if (merged.some(subValue => !subValue)) {
179
+ return;
180
+ }
181
+ return this.objectLoader.createCompactedResource({
182
+ '@type': rangeA.property.type,
183
+ parameterRangeElements: merged,
184
+ });
185
+ }
186
+ // Check sub-values for generic components
187
+ if (rangeA.isA('ParameterRangeGenericComponent')) {
188
+ const mergedComponent = this.mergeRanges(rangeA.property.component, rangeB.property.component, typeTypeValidator);
189
+ if (!mergedComponent) {
190
+ return;
191
+ }
192
+ const valuesA = rangeA.properties.genericTypeInstances;
193
+ const valuesB = rangeB.properties.genericTypeInstances;
194
+ if (valuesA.length !== valuesB.length) {
195
+ return;
196
+ }
197
+ const merged = valuesA.map((valueA, i) => this.mergeRanges(valueA, valuesB[i], typeTypeValidator));
198
+ if (merged.some(subValue => !subValue)) {
199
+ return;
200
+ }
201
+ return this.objectLoader.createCompactedResource({
202
+ '@type': 'ParameterRangeGenericComponent',
203
+ component: mergedComponent,
204
+ genericTypeInstances: merged,
205
+ });
206
+ }
207
+ return rangeA;
208
+ }
209
+ // Handle left or right being a union
210
+ if (rangeA.isA('ParameterRangeUnion')) {
211
+ return this.mergeUnion(rangeA, rangeB, typeTypeValidator);
212
+ }
213
+ if (rangeB.isA('ParameterRangeUnion')) {
214
+ return this.mergeUnion(rangeB, rangeA, typeTypeValidator);
215
+ }
216
+ // Check if the range refers to a component with a generic type
217
+ // TODO: somehow pass the range's component and genericTypeInstances (like in ParameterPropertyHandlerRange)?
218
+ if (rangeA.isA('ParameterRangeGenericComponent')) {
219
+ return this.mergeRanges(rangeA.property.component, rangeB, typeTypeValidator);
220
+ }
221
+ if (rangeB.isA('ParameterRangeGenericComponent')) {
222
+ return this.mergeRanges(rangeB.property.component, rangeA, typeTypeValidator);
223
+ }
224
+ }
225
+ mergeUnion(rangeUnion, rangeOther, typeValidator) {
226
+ const elements = rangeUnion.properties.parameterRangeElements;
227
+ const mergedValues = elements
228
+ .map(element => this.mergeRanges(rangeOther, element, typeValidator))
229
+ .filter(Boolean);
230
+ if (mergedValues.length === 0) {
231
+ return;
232
+ }
233
+ if (mergedValues.length === 1) {
234
+ return mergedValues[0];
235
+ }
236
+ return this.objectLoader.createCompactedResource({
237
+ '@type': 'ParameterRangeUnion',
238
+ parameterRangeElements: mergedValues,
239
+ });
240
+ }
241
+ /**
242
+ * Check if the given type is a subtype of the given super type.
243
+ * @param type A type node.
244
+ * @param potentialSuperType A potential super type node.
245
+ */
246
+ isXsdSubType(type, potentialSuperType) {
247
+ const values = GenericsContext.XSD_INHERITANCE_TABLE[potentialSuperType.value];
248
+ return values && values.has(type.value);
249
+ }
250
+ /**
251
+ * Apply the give generic type instances for the given component's generic type parameters.
252
+ *
253
+ * This will throw if the number of passed instances does not match with
254
+ * the number of generic type parameters on the component.
255
+ *
256
+ * @param component The component
257
+ * @param genericTypeInstances The generic type instances to apply.
258
+ * @param errorContext The context for error reporting.
259
+ * @param typeTypeValidator Callback for validating sub-types against super-types.
260
+ * @return boolean False if the application failed due to a binding error. True otherwise
261
+ */
262
+ bindComponentGenericTypes(component, genericTypeInstances, errorContext, typeTypeValidator) {
263
+ const genericTypeParameters = component.properties.genericTypeParameters;
264
+ // Don't do anything if no generic type instances are passed.
265
+ if (genericTypeInstances.length === 0) {
266
+ return {
267
+ description: `no generic type instances are passed`,
268
+ context: errorContext,
269
+ };
270
+ }
271
+ // Throw if an unexpected number of generic type instances are passed.
272
+ if (genericTypeParameters.length !== genericTypeInstances.length) {
273
+ throw new ErrorResourcesContext_1.ErrorResourcesContext(`Invalid generic type instantiation: a different amount of generic types are passed (${genericTypeInstances.length}) than are defined on the component (${genericTypeParameters.length}).`, Object.assign({ passedGenerics: genericTypeInstances, definedGenerics: genericTypeParameters, component }, errorContext));
274
+ }
275
+ // Populate with manually defined generic type bindings
276
+ for (const [i, genericTypeInstance] of genericTypeInstances.entries()) {
277
+ // Remap generic type IRI to inner generic type IRI
278
+ const genericTypeIdInner = genericTypeParameters[i].value;
279
+ if (genericTypeInstance.property.parameterRangeGenericBindings) {
280
+ const subConflict = this.bindGenericTypeToRange(genericTypeIdInner, genericTypeInstance.property.parameterRangeGenericBindings, typeTypeValidator);
281
+ if (subConflict) {
282
+ return {
283
+ description: `invalid binding for generic <${genericTypeIdInner}>`,
284
+ context: errorContext,
285
+ causes: [subConflict],
286
+ };
287
+ }
288
+ }
289
+ this.genericTypeIds[genericTypeIdInner] = true;
290
+ }
291
+ }
292
+ }
293
+ exports.GenericsContext = GenericsContext;
294
+ GenericsContext.XSD_INHERITANCE_TABLE = {
295
+ 'http://www.w3.org/2001/XMLSchema#number': new Set([
296
+ 'http://www.w3.org/2001/XMLSchema#integer',
297
+ 'http://www.w3.org/2001/XMLSchema#long',
298
+ 'http://www.w3.org/2001/XMLSchema#int',
299
+ 'http://www.w3.org/2001/XMLSchema#byte',
300
+ 'http://www.w3.org/2001/XMLSchema#short',
301
+ 'http://www.w3.org/2001/XMLSchema#negativeInteger',
302
+ 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger',
303
+ 'http://www.w3.org/2001/XMLSchema#nonPositiveInteger',
304
+ 'http://www.w3.org/2001/XMLSchema#positiveInteger',
305
+ 'http://www.w3.org/2001/XMLSchema#unsignedByte',
306
+ 'http://www.w3.org/2001/XMLSchema#unsignedInt',
307
+ 'http://www.w3.org/2001/XMLSchema#unsignedLong',
308
+ 'http://www.w3.org/2001/XMLSchema#unsignedShort',
309
+ 'http://www.w3.org/2001/XMLSchema#double',
310
+ 'http://www.w3.org/2001/XMLSchema#decimal',
311
+ 'http://www.w3.org/2001/XMLSchema#float',
312
+ ]),
313
+ 'http://www.w3.org/2001/XMLSchema#string': new Set([
314
+ 'http://www.w3.org/2001/XMLSchema#normalizedString',
315
+ 'http://www.w3.org/2001/XMLSchema#anyURI',
316
+ 'http://www.w3.org/2001/XMLSchema#base64Binary',
317
+ 'http://www.w3.org/2001/XMLSchema#language',
318
+ 'http://www.w3.org/2001/XMLSchema#Name',
319
+ 'http://www.w3.org/2001/XMLSchema#NCName',
320
+ 'http://www.w3.org/2001/XMLSchema#NMTOKEN',
321
+ 'http://www.w3.org/2001/XMLSchema#token',
322
+ 'http://www.w3.org/2001/XMLSchema#hexBinary',
323
+ 'http://www.w3.org/2001/XMLSchema#langString',
324
+ ]),
325
+ };
326
+ //# sourceMappingURL=GenericsContext.js.map
@@ -1,19 +1,23 @@
1
1
  import type { RdfObjectLoader, Resource } from 'rdf-object';
2
+ import type { GenericsContext } from './GenericsContext';
3
+ import { ParameterPropertyHandlerRange } from './parameterproperty/ParameterPropertyHandlerRange';
2
4
  /**
3
5
  * Handles component parameters in the context of a config.
4
6
  */
5
7
  export declare class ParameterHandler {
6
8
  private readonly objectLoader;
7
9
  private readonly parameterPropertyHandlers;
10
+ readonly parameterPropertyHandlerRange: ParameterPropertyHandlerRange;
8
11
  constructor(options: IParameterHandlerOptions);
9
12
  /**
10
13
  * Obtain the values of the given parameter in the context of the given config.
11
14
  * @param configRoot The root config resource that we are working in.
12
15
  * @param parameter The parameter resource to get the value for.
13
16
  * @param configElement Part of the config resource to look for parameter instantiations as predicates.
14
- * @return The parameter value(s)
17
+ * @param genericsContext Context for generic types.
18
+ * @return - The parameter value
15
19
  */
16
- applyParameterValues(configRoot: Resource, parameter: Resource, configElement: Resource): Resource[];
20
+ applyParameterValues(configRoot: Resource, parameter: Resource, configElement: Resource, genericsContext: GenericsContext): Resource | undefined;
17
21
  }
18
22
  export interface IParameterHandlerOptions {
19
23
  objectLoader: RdfObjectLoader;
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ParameterHandler = void 0;
4
+ const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
4
5
  const ParameterPropertyHandlerDefault_1 = require("./parameterproperty/ParameterPropertyHandlerDefault");
5
6
  const ParameterPropertyHandlerDefaultScoped_1 = require("./parameterproperty/ParameterPropertyHandlerDefaultScoped");
6
7
  const ParameterPropertyHandlerFixed_1 = require("./parameterproperty/ParameterPropertyHandlerFixed");
7
8
  const ParameterPropertyHandlerLazy_1 = require("./parameterproperty/ParameterPropertyHandlerLazy");
8
9
  const ParameterPropertyHandlerRange_1 = require("./parameterproperty/ParameterPropertyHandlerRange");
9
- const ParameterPropertyHandlerRequired_1 = require("./parameterproperty/ParameterPropertyHandlerRequired");
10
- const ParameterPropertyHandlerUnique_1 = require("./parameterproperty/ParameterPropertyHandlerUnique");
11
10
  /**
12
11
  * Handles component parameters in the context of a config.
13
12
  */
@@ -16,11 +15,9 @@ class ParameterHandler {
16
15
  this.objectLoader = options.objectLoader;
17
16
  this.parameterPropertyHandlers = [
18
17
  new ParameterPropertyHandlerDefaultScoped_1.ParameterPropertyHandlerDefaultScoped(this.objectLoader),
19
- new ParameterPropertyHandlerDefault_1.ParameterPropertyHandlerDefault(),
20
- new ParameterPropertyHandlerRequired_1.ParameterPropertyHandlerRequired(this.objectLoader),
21
- new ParameterPropertyHandlerFixed_1.ParameterPropertyHandlerFixed(),
22
- new ParameterPropertyHandlerUnique_1.ParameterPropertyHandlerUnique(this.objectLoader),
23
- new ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange(this.objectLoader),
18
+ new ParameterPropertyHandlerDefault_1.ParameterPropertyHandlerDefault(this.objectLoader),
19
+ new ParameterPropertyHandlerFixed_1.ParameterPropertyHandlerFixed(this.objectLoader),
20
+ this.parameterPropertyHandlerRange = new ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange(this.objectLoader),
24
21
  new ParameterPropertyHandlerLazy_1.ParameterPropertyHandlerLazy(),
25
22
  ];
26
23
  }
@@ -29,25 +26,30 @@ class ParameterHandler {
29
26
  * @param configRoot The root config resource that we are working in.
30
27
  * @param parameter The parameter resource to get the value for.
31
28
  * @param configElement Part of the config resource to look for parameter instantiations as predicates.
32
- * @return The parameter value(s)
29
+ * @param genericsContext Context for generic types.
30
+ * @return - The parameter value
33
31
  */
34
- applyParameterValues(configRoot, parameter, configElement) {
35
- // Obtain the parameter's value in the given config, and flatten RDF lists
36
- let value = [];
37
- for (const element of configElement.properties[parameter.value]) {
38
- if (element.list) {
39
- for (const subElement of element.list) {
40
- value.push(subElement);
41
- }
42
- }
43
- else {
44
- value.push(element);
32
+ applyParameterValues(configRoot, parameter, configElement, genericsContext) {
33
+ // Make sure that we always have a single value with list elements in it.
34
+ const values = configElement.properties[parameter.value];
35
+ let value;
36
+ if (values.length === 1) {
37
+ value = values[0];
38
+ }
39
+ else if (values.length > 0) {
40
+ if (values.some(subValue => !subValue.list)) {
41
+ throw new ErrorResourcesContext_1.ErrorResourcesContext(`Detected multiple values for parameter ${parameter.value}. RDF lists should be used for defining multiple values.`, {
42
+ arguments: values,
43
+ });
45
44
  }
45
+ value = this.objectLoader.createCompactedResource({
46
+ list: values.flatMap(subValue => subValue.list),
47
+ });
46
48
  }
47
49
  // Run the value through all applicable parameters property handlers.
48
50
  for (const handler of this.parameterPropertyHandlers) {
49
- if (handler.canHandle(value, configRoot, parameter, configElement)) {
50
- value = handler.handle(value, configRoot, parameter, configElement);
51
+ if (handler.canHandle(value, configRoot, parameter, configElement, genericsContext)) {
52
+ value = handler.handle(value, configRoot, parameter, configElement, genericsContext);
51
53
  }
52
54
  }
53
55
  return value;