componentsjs 5.0.0-beta.2 → 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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ <a name="v5.0.0-beta.3"></a>
5
+ ## [v5.0.0-beta.3](https://github.com/LinkedSoftwareDependencies/Components.js/compare/v5.0.0-beta.2...v5.0.0-beta.3) - 2022-01-17
6
+
7
+ ### Added
8
+ * [Add support for wildcard parameter ranges](https://github.com/LinkedSoftwareDependencies/Components.js/commit/83238a9fa08877f29326be562d7d3d5fff860c69)
9
+ * Improve error reporting:
10
+ * [Add causes for param check failures in error messages](https://github.com/LinkedSoftwareDependencies/Components.js/commit/9be1fd0899ffb8a77ea99e5fb86e661526ef6d1a)
11
+ * [Improve error message on invalid generic type instantiations](https://github.com/LinkedSoftwareDependencies/Components.js/commit/6ecb9798eeb84f09fece68b3a47454fa8c857ba4)
12
+ * [Move error context to error state file](https://github.com/LinkedSoftwareDependencies/Components.js/commit/dbf26e072bdc63168814ef4d503777efaf4745eb)
13
+
14
+ ### Fixed
15
+ * Resolve several issues related to generics:
16
+ * [Throw error on invalid ParameterRangeGenericComponent](https://github.com/LinkedSoftwareDependencies/Components.js/commit/c692ab6175ce466fb32fbe38b973644e2601b2e6)
17
+ * [Fix generic components not accepting specific types](https://github.com/LinkedSoftwareDependencies/Components.js/commit/c7739182fddcb92d46a86fe3e33d6e29fd1134b6)
18
+ * [Support generic type instantiation during component extension](https://github.com/LinkedSoftwareDependencies/Components.js/commit/98f70e350cc3f9bf8a4ea632db546f74624ddda7)
19
+ * [Support generic components in params with fixed generics](https://github.com/LinkedSoftwareDependencies/Components.js/commit/d8b30972e1306e9fe9db391d4693aa6000917e60)
20
+ * [Use GenericComponentExtension to refer to wrapped generic comp extensions](https://github.com/LinkedSoftwareDependencies/Components.js/commit/239895accfdb7f09a7ac8454928bd3e0be5e5f15)
21
+ * [Fix invalid range display with multiple generics](https://github.com/LinkedSoftwareDependencies/Components.js/commit/b98baf0bcf4546b60299ae548f929693345292bc)
22
+ * [Handle range merging if left or right is union](https://github.com/LinkedSoftwareDependencies/Components.js/commit/637e140106691b95f0f546cf88eb39f3f80dc61d)
23
+ * [Handle sub-types when merging param ranges](https://github.com/LinkedSoftwareDependencies/Components.js/commit/43290525b2e244f5fbb6d5f344760b863329c31b)
24
+ * [Allow merging of generic component param types](https://github.com/LinkedSoftwareDependencies/Components.js/commit/ee8de7d9b8d18bf6968a17078e493946e5fca8cd)
25
+ * [Allow param range merging with generic components](https://github.com/LinkedSoftwareDependencies/Components.js/commit/bcea7dcff288ce7068ee244c49c12134208c89da)
26
+ * [Fix generics crash when doing repeated param type checking](https://github.com/LinkedSoftwareDependencies/Components.js/commit/237572cb8a9c546b098582041ccd7a457b41aecd)
27
+
4
28
  <a name="v5.0.0-beta.2"></a>
5
29
  ## [v5.0.0-beta.2](https://github.com/LinkedSoftwareDependencies/Components.js/compare/v5.0.0-beta.1...v5.0.0-beta.2) - 2021-12-09
6
30
 
package/README.md CHANGED
@@ -202,6 +202,22 @@ const myInstance = await manager.instantiate('http://example.org/myInstance');
202
202
  [RDF]: https://www.w3.org/RDF/
203
203
  [JSON-LD]: https://json-ld.org/
204
204
 
205
+ ## Cite
206
+
207
+ If you are using or extending Components.js as part of a scientific publication,
208
+ we would appreciate a citation of our [article](https://linkedsoftwaredependencies.github.io/Article-System-Components/).
209
+
210
+ ```bibtex
211
+ @article{taelman_swj_componentsjs_2022,
212
+ author = {Taelman, Ruben and Van Herwegen, Joachim and Vander Sande, Miel and Verborgh, Ruben},
213
+ title = {Components.js: Semantic Dependency Injection},
214
+ journal = {Semantic Web Journal},
215
+ year = {2022},
216
+ month = jan,
217
+ url = {https://linkedsoftwaredependencies.github.io/Article-System-Components/}
218
+ }
219
+ ```
220
+
205
221
  ## License
206
222
  Components.js is written by [Ruben Taelman](http://www.rubensworks.net/).
207
223
 
@@ -2,6 +2,9 @@
2
2
  "@context": {
3
3
  "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
4
4
  "xsd": "http://www.w3.org/2001/XMLSchema#",
5
+ "type": {
6
+ "@id": "rdf:type"
7
+ },
5
8
  "types": {
6
9
  "@id": "rdf:type"
7
10
  },
@@ -77,6 +80,9 @@
77
80
  "ParameterRangeUndefined": {
78
81
  "@id": "oo:ParameterRangeUndefined"
79
82
  },
83
+ "ParameterRangeWildcard": {
84
+ "@id": "oo:ParameterRangeWildcard"
85
+ },
80
86
  "ParameterRangeArray": {
81
87
  "@id": "oo:ParameterRangeArray"
82
88
  },
@@ -116,6 +122,10 @@
116
122
  "ParameterRangeGenericComponent": {
117
123
  "@id": "oo:ParameterRangeGenericComponent"
118
124
  },
125
+ "genericTypeInstancesComponentScope": {
126
+ "@id": "oo:genericTypeInstancesComponentScope",
127
+ "@type": "@id"
128
+ },
119
129
  "genericTypeInstances": {
120
130
  "@id": "oo:genericTypeInstance",
121
131
  "@type": "@id"
@@ -131,6 +141,9 @@
131
141
  "@id": "oo:parameterRangeGenericBindings",
132
142
  "@type": "@id"
133
143
  },
144
+ "GenericComponentExtension": {
145
+ "@id": "oo:GenericComponentExtension"
146
+ },
134
147
 
135
148
  "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
136
149
  "comment": {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ComponentsManager = void 0;
4
4
  const fs = require("fs");
5
5
  const ComponentsManagerBuilder_1 = require("./loading/ComponentsManagerBuilder");
6
+ const ErrorResourcesContext_1 = require("./util/ErrorResourcesContext");
6
7
  /**
7
8
  * A components manager can instantiate components.
8
9
  * This manager should be created using {@link ComponentsManager.build}.
@@ -51,17 +52,14 @@ class ComponentsManager {
51
52
  */
52
53
  generateErrorLog(error) {
53
54
  if (this.dumpErrorState) {
54
- const contents = JSON.stringify({
55
- componentTypes: Object.keys(this.componentResources),
56
- moduleState: {
55
+ const contents = JSON.stringify(Object.assign(Object.assign({}, error instanceof ErrorResourcesContext_1.ErrorResourcesContext ? error.exportContext() : {}), { componentTypes: Object.keys(this.componentResources), moduleState: {
57
56
  mainModulePath: this.moduleState.mainModulePath,
58
57
  componentModules: this.moduleState.componentModules,
59
58
  importPaths: this.moduleState.importPaths,
60
59
  contexts: this.moduleState.contexts,
61
60
  nodeModuleImportPaths: this.moduleState.nodeModuleImportPaths,
62
61
  nodeModulePaths: this.moduleState.nodeModulePaths,
63
- },
64
- }, null, ' ');
62
+ } }), null, ' ');
65
63
  fs.writeFileSync('componentsjs-error-state.json', contents, 'utf8');
66
64
  this.logger.error(`Detected fatal error. Generated 'componentsjs-error-state.json' with more information.`);
67
65
  }
@@ -41,7 +41,13 @@ class ComponentRegistryFinalizer {
41
41
  * @param superComponents The components to inherit from.
42
42
  */
43
43
  inheritParameters(component, superComponents) {
44
- for (const superComponent of superComponents) {
44
+ var _a;
45
+ for (let superComponent of superComponents) {
46
+ // Check if the super component is wrapped in a generic component instantiation
47
+ if (((_a = superComponent.property.type) === null || _a === void 0 ? void 0 : _a.value) === this.objectLoader.contextResolved
48
+ .expandTerm('oo:GenericComponentExtension')) {
49
+ superComponent = superComponent.property.component;
50
+ }
45
51
  this.componentRegistry.requireValidComponent(superComponent, component);
46
52
  for (const parameter of superComponent.properties.parameters) {
47
53
  if (!component.properties.parameters.includes(parameter)) {
@@ -89,20 +89,16 @@ class ConfigPreprocessorComponent {
89
89
  return configRaw;
90
90
  }
91
91
  createGenericsContext(handleResponse, config) {
92
+ // Create a new generics context for the component's generic type parameters
92
93
  const genericsContext = new GenericsContext_1.GenericsContext(this.objectLoader, handleResponse.component.properties.genericTypeParameters);
93
- // Populate with manually defined generic type bindings
94
- const genericTypesInner = handleResponse.component.properties.genericTypeParameters;
95
- if (genericTypesInner.length < config.properties.genericTypeInstances.length) {
96
- throw new ErrorResourcesContext_1.ErrorResourcesContext(`Invalid generic type instantiations: more generic types are passed than are defined on the component.`, {
97
- config,
98
- component: handleResponse.component,
99
- });
100
- }
101
- for (const [i, genericTypeInstance] of config.properties.genericTypeInstances.entries()) {
102
- // Remap generic type IRI to inner generic type IRI
103
- const genericTypeIdInner = genericTypesInner[i].value;
104
- genericsContext.bindings[genericTypeIdInner] = genericTypeInstance.properties.parameterRangeGenericBindings;
105
- genericsContext.genericTypeIds[genericTypeIdInner] = true;
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 }));
106
102
  }
107
103
  return genericsContext;
108
104
  }
@@ -1,30 +1,74 @@
1
+ import type * as RDF from '@rdfjs/types';
1
2
  import type { Resource, RdfObjectLoader } from 'rdf-object';
3
+ import type { IParamValueConflict } from './parameterproperty/ParameterPropertyHandlerRange';
2
4
  /**
3
5
  * Context for binding generic types to a concrete range value.
4
6
  */
5
7
  export declare class GenericsContext {
8
+ private static readonly XSD_INHERITANCE_TABLE;
6
9
  private readonly objectLoader;
7
10
  /**
8
11
  * Set of generic type ids.
9
12
  * @private
10
13
  */
11
- readonly genericTypeIds: Record<string, boolean>;
14
+ genericTypeIds: Record<string, boolean>;
12
15
  /**
13
16
  * Mapping of generic type id to the resolved range.
14
17
  * @private
15
18
  */
16
- readonly bindings: Record<string, Resource[]>;
19
+ bindings: Record<string, Resource>;
17
20
  constructor(objectLoader: RdfObjectLoader, genericTypeParameters: Resource[]);
18
21
  /**
19
22
  * Try to to bind the given value to the given generic.
20
23
  * @param genericTypeId IRI of the generic to bind.
21
24
  * @param value The value to bind to.
22
- * @param typeValidator Callback for validating values against types.
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.
23
28
  */
24
- bindGenericTypeToValue(genericTypeId: string, value: Resource | undefined, typeValidator: (subValue: Resource | undefined, subType: Resource) => boolean): boolean;
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;
25
38
  /**
26
39
  * Infer the parameter range of the given value.
27
40
  * @param value A value.
28
41
  */
29
- inferValueRange(value: Resource | undefined): Resource[];
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;
30
74
  }
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GenericsContext = void 0;
4
+ const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
5
+ const ParameterPropertyHandlerRange_1 = require("./parameterproperty/ParameterPropertyHandlerRange");
4
6
  /**
5
7
  * Context for binding generic types to a concrete range value.
6
8
  */
@@ -12,7 +14,7 @@ class GenericsContext {
12
14
  this.bindings = {};
13
15
  for (const genericTypeParameter of genericTypeParameters) {
14
16
  if (genericTypeParameter.property.range) {
15
- this.bindings[genericTypeParameter.value] = genericTypeParameter.properties.range;
17
+ this.bindings[genericTypeParameter.value] = genericTypeParameter.property.range;
16
18
  }
17
19
  }
18
20
  }
@@ -20,27 +22,68 @@ class GenericsContext {
20
22
  * Try to to bind the given value to the given generic.
21
23
  * @param genericTypeId IRI of the generic to bind.
22
24
  * @param value The value to bind to.
23
- * @param typeValidator Callback for validating values against types.
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.
24
28
  */
25
- bindGenericTypeToValue(genericTypeId, value, typeValidator) {
29
+ bindGenericTypeToValue(genericTypeId, value, valueTypeValidator, typeTypeValidator) {
26
30
  // Fail if an unknown generic type is referenced
27
31
  if (!(genericTypeId in this.genericTypeIds)) {
28
- return false;
32
+ return {
33
+ description: `unknown generic <${genericTypeId}> is being referenced`,
34
+ context: { value },
35
+ };
29
36
  }
30
37
  // If the generic was already bound to a range, validate it
31
38
  const existingRange = this.bindings[genericTypeId];
32
- if (existingRange && existingRange.some(existingRangeElement => !typeValidator(value, existingRangeElement))) {
33
- return false;
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
+ }
34
48
  }
35
49
  // Infer type of value
36
50
  const valueRange = this.inferValueRange(value);
37
- if (valueRange.length > 0) {
38
- // If we already had a range, try to align them
39
- // TODO: this will be needed for resources with common inheritance hierarchies
40
- // Save inferred type
41
- this.bindings[genericTypeId] = valueRange;
51
+ if (!valueRange) {
52
+ return;
42
53
  }
43
- return true;
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;
44
87
  }
45
88
  /**
46
89
  * Infer the parameter range of the given value.
@@ -49,15 +92,235 @@ class GenericsContext {
49
92
  inferValueRange(value) {
50
93
  // Value is undefined
51
94
  if (!value) {
52
- return [this.objectLoader.createCompactedResource({ type: 'ParameterRangeUndefined' })];
95
+ return this.objectLoader.createCompactedResource({ '@type': 'ParameterRangeUndefined' });
53
96
  }
54
97
  // Value is a literal
55
98
  if (value.term.termType === 'Literal') {
56
- return [this.objectLoader.createCompactedResource(value.term.datatype)];
99
+ return this.objectLoader.createCompactedResource(value.term.datatype);
57
100
  }
58
101
  // Value is a named node
59
- return value.properties.type;
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
+ }
60
291
  }
61
292
  }
62
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
+ };
63
326
  //# sourceMappingURL=GenericsContext.js.map
@@ -1,11 +1,13 @@
1
1
  import type { RdfObjectLoader, Resource } from 'rdf-object';
2
2
  import type { GenericsContext } from './GenericsContext';
3
+ import { ParameterPropertyHandlerRange } from './parameterproperty/ParameterPropertyHandlerRange';
3
4
  /**
4
5
  * Handles component parameters in the context of a config.
5
6
  */
6
7
  export declare class ParameterHandler {
7
8
  private readonly objectLoader;
8
9
  private readonly parameterPropertyHandlers;
10
+ readonly parameterPropertyHandlerRange: ParameterPropertyHandlerRange;
9
11
  constructor(options: IParameterHandlerOptions);
10
12
  /**
11
13
  * Obtain the values of the given parameter in the context of the given config.
@@ -17,7 +17,7 @@ class ParameterHandler {
17
17
  new ParameterPropertyHandlerDefaultScoped_1.ParameterPropertyHandlerDefaultScoped(this.objectLoader),
18
18
  new ParameterPropertyHandlerDefault_1.ParameterPropertyHandlerDefault(this.objectLoader),
19
19
  new ParameterPropertyHandlerFixed_1.ParameterPropertyHandlerFixed(this.objectLoader),
20
- new ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange(this.objectLoader),
20
+ this.parameterPropertyHandlerRange = new ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange(this.objectLoader),
21
21
  new ParameterPropertyHandlerLazy_1.ParameterPropertyHandlerLazy(),
22
22
  ];
23
23
  }