@player-tools/xlr-sdk 0.4.1 → 0.4.2--canary.63.1250
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/dist/index.cjs.js +21 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +22 -17
- package/package.json +4 -4
- package/src/sdk.ts +16 -4
- package/src/validator.ts +13 -20
package/dist/index.cjs.js
CHANGED
|
@@ -126,7 +126,10 @@ class XLRValidator {
|
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
} else if (xlrNode.type === "template") {
|
|
129
|
-
this.validateTemplate(rootNode, xlrNode);
|
|
129
|
+
const error = this.validateTemplate(rootNode, xlrNode);
|
|
130
|
+
if (error) {
|
|
131
|
+
validationIssues.push(error);
|
|
132
|
+
}
|
|
130
133
|
} else if (xlrNode.type === "or") {
|
|
131
134
|
for (const potentialType of xlrNode.or) {
|
|
132
135
|
const potentialErrors = this.validateType(rootNode, potentialType);
|
|
@@ -226,34 +229,29 @@ class XLRValidator {
|
|
|
226
229
|
validateObject(xlrNode, node) {
|
|
227
230
|
const issues = [];
|
|
228
231
|
const objectProps = xlrUtils.makePropertyMap(node);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const extendedNode = this.getRefType(xlrNode.extends);
|
|
232
|
-
effectiveXLRNode = xlrUtils.computeEffectiveObject(extendedNode, xlrNode);
|
|
233
|
-
}
|
|
234
|
-
for (const prop in effectiveXLRNode.properties) {
|
|
235
|
-
const expectedType = effectiveXLRNode.properties[prop];
|
|
232
|
+
for (const prop in xlrNode.properties) {
|
|
233
|
+
const expectedType = xlrNode.properties[prop];
|
|
236
234
|
const valueNode = objectProps.get(prop);
|
|
237
235
|
if (expectedType.required && valueNode === void 0) {
|
|
238
236
|
issues.push({
|
|
239
237
|
type: "missing",
|
|
240
238
|
node,
|
|
241
|
-
message: `Property '${prop}' missing from type '${
|
|
239
|
+
message: `Property '${prop}' missing from type '${xlrNode.name}'`
|
|
242
240
|
});
|
|
243
241
|
}
|
|
244
242
|
if (valueNode) {
|
|
245
243
|
issues.push(...this.validateType(valueNode, expectedType.node));
|
|
246
244
|
}
|
|
247
245
|
}
|
|
248
|
-
const extraKeys = Array.from(objectProps.keys()).filter((key) =>
|
|
249
|
-
if (
|
|
246
|
+
const extraKeys = Array.from(objectProps.keys()).filter((key) => xlrNode.properties[key] === void 0);
|
|
247
|
+
if (xlrNode.additionalProperties === false && extraKeys.length > 0) {
|
|
250
248
|
issues.push({
|
|
251
249
|
type: "value",
|
|
252
250
|
node,
|
|
253
|
-
message: `Unexpected properties on '${
|
|
251
|
+
message: `Unexpected properties on '${xlrNode.name}': ${extraKeys.join(", ")}`
|
|
254
252
|
});
|
|
255
253
|
} else {
|
|
256
|
-
issues.push(...extraKeys.flatMap((key) => this.validateType(objectProps.get(key),
|
|
254
|
+
issues.push(...extraKeys.flatMap((key) => this.validateType(objectProps.get(key), xlrNode.additionalProperties)));
|
|
257
255
|
}
|
|
258
256
|
return issues;
|
|
259
257
|
}
|
|
@@ -518,9 +516,11 @@ class XLRSDK {
|
|
|
518
516
|
this.registry = customRegistry != null ? customRegistry : new BasicXLRRegistry();
|
|
519
517
|
this.validator = new XLRValidator(this.getType.bind(this));
|
|
520
518
|
this.tsWriter = new xlrConverters.TSWriter();
|
|
519
|
+
this.computedNodeCache = new Map();
|
|
521
520
|
}
|
|
522
521
|
loadDefinitionsFromDisk(inputPath, filters, transforms) {
|
|
523
522
|
var _a;
|
|
523
|
+
this.computedNodeCache.clear();
|
|
524
524
|
const manifest = JSON.parse(fs__default["default"].readFileSync(path__default["default"].join(inputPath, "xlr", "manifest.json")).toString(), (key, value) => {
|
|
525
525
|
if (typeof value === "object" && value !== null) {
|
|
526
526
|
if (key === "capabilities") {
|
|
@@ -545,6 +545,7 @@ class XLRSDK {
|
|
|
545
545
|
loadDefinitionsFromModule(manifest, filters, transforms) {
|
|
546
546
|
return __async(this, null, function* () {
|
|
547
547
|
var _a;
|
|
548
|
+
this.computedNodeCache.clear();
|
|
548
549
|
(_a = Object.keys(manifest.capabilities)) == null ? void 0 : _a.forEach((capabilityName) => {
|
|
549
550
|
if ((filters == null ? void 0 : filters.capabilityFilter) && capabilityName.match(filters == null ? void 0 : filters.capabilityFilter))
|
|
550
551
|
return;
|
|
@@ -564,8 +565,12 @@ class XLRSDK {
|
|
|
564
565
|
if ((options == null ? void 0 : options.getRawType) === true || !type) {
|
|
565
566
|
return type;
|
|
566
567
|
}
|
|
567
|
-
|
|
568
|
-
|
|
568
|
+
if (this.computedNodeCache.has(id)) {
|
|
569
|
+
return this.computedNodeCache.get(id);
|
|
570
|
+
}
|
|
571
|
+
type = xlrUtils.fillInGenerics(this.resolveType(type));
|
|
572
|
+
this.computedNodeCache.set(id, type);
|
|
573
|
+
return type;
|
|
569
574
|
}
|
|
570
575
|
hasType(id) {
|
|
571
576
|
return this.registry.has(id);
|
|
@@ -577,7 +582,7 @@ class XLRSDK {
|
|
|
577
582
|
return this.registry.info(id);
|
|
578
583
|
}
|
|
579
584
|
validateByName(typeName, rootNode) {
|
|
580
|
-
const xlr = this.getType(typeName
|
|
585
|
+
const xlr = this.getType(typeName);
|
|
581
586
|
if (!xlr) {
|
|
582
587
|
throw new Error(`Type ${typeName} does not exist in registry, can't validate`);
|
|
583
588
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isPrimitiveTypeNode, resolveConditional, makePropertyMap,
|
|
1
|
+
import { isPrimitiveTypeNode, resolveConditional, makePropertyMap, resolveReferenceNode, computeEffectiveObject, fillInGenerics } from '@player-tools/xlr-utils';
|
|
2
2
|
import { TSWriter } from '@player-tools/xlr-converters';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
@@ -116,7 +116,10 @@ class XLRValidator {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
} else if (xlrNode.type === "template") {
|
|
119
|
-
this.validateTemplate(rootNode, xlrNode);
|
|
119
|
+
const error = this.validateTemplate(rootNode, xlrNode);
|
|
120
|
+
if (error) {
|
|
121
|
+
validationIssues.push(error);
|
|
122
|
+
}
|
|
120
123
|
} else if (xlrNode.type === "or") {
|
|
121
124
|
for (const potentialType of xlrNode.or) {
|
|
122
125
|
const potentialErrors = this.validateType(rootNode, potentialType);
|
|
@@ -216,34 +219,29 @@ class XLRValidator {
|
|
|
216
219
|
validateObject(xlrNode, node) {
|
|
217
220
|
const issues = [];
|
|
218
221
|
const objectProps = makePropertyMap(node);
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const extendedNode = this.getRefType(xlrNode.extends);
|
|
222
|
-
effectiveXLRNode = computeEffectiveObject(extendedNode, xlrNode);
|
|
223
|
-
}
|
|
224
|
-
for (const prop in effectiveXLRNode.properties) {
|
|
225
|
-
const expectedType = effectiveXLRNode.properties[prop];
|
|
222
|
+
for (const prop in xlrNode.properties) {
|
|
223
|
+
const expectedType = xlrNode.properties[prop];
|
|
226
224
|
const valueNode = objectProps.get(prop);
|
|
227
225
|
if (expectedType.required && valueNode === void 0) {
|
|
228
226
|
issues.push({
|
|
229
227
|
type: "missing",
|
|
230
228
|
node,
|
|
231
|
-
message: `Property '${prop}' missing from type '${
|
|
229
|
+
message: `Property '${prop}' missing from type '${xlrNode.name}'`
|
|
232
230
|
});
|
|
233
231
|
}
|
|
234
232
|
if (valueNode) {
|
|
235
233
|
issues.push(...this.validateType(valueNode, expectedType.node));
|
|
236
234
|
}
|
|
237
235
|
}
|
|
238
|
-
const extraKeys = Array.from(objectProps.keys()).filter((key) =>
|
|
239
|
-
if (
|
|
236
|
+
const extraKeys = Array.from(objectProps.keys()).filter((key) => xlrNode.properties[key] === void 0);
|
|
237
|
+
if (xlrNode.additionalProperties === false && extraKeys.length > 0) {
|
|
240
238
|
issues.push({
|
|
241
239
|
type: "value",
|
|
242
240
|
node,
|
|
243
|
-
message: `Unexpected properties on '${
|
|
241
|
+
message: `Unexpected properties on '${xlrNode.name}': ${extraKeys.join(", ")}`
|
|
244
242
|
});
|
|
245
243
|
} else {
|
|
246
|
-
issues.push(...extraKeys.flatMap((key) => this.validateType(objectProps.get(key),
|
|
244
|
+
issues.push(...extraKeys.flatMap((key) => this.validateType(objectProps.get(key), xlrNode.additionalProperties)));
|
|
247
245
|
}
|
|
248
246
|
return issues;
|
|
249
247
|
}
|
|
@@ -508,9 +506,11 @@ class XLRSDK {
|
|
|
508
506
|
this.registry = customRegistry != null ? customRegistry : new BasicXLRRegistry();
|
|
509
507
|
this.validator = new XLRValidator(this.getType.bind(this));
|
|
510
508
|
this.tsWriter = new TSWriter();
|
|
509
|
+
this.computedNodeCache = new Map();
|
|
511
510
|
}
|
|
512
511
|
loadDefinitionsFromDisk(inputPath, filters, transforms) {
|
|
513
512
|
var _a;
|
|
513
|
+
this.computedNodeCache.clear();
|
|
514
514
|
const manifest = JSON.parse(fs.readFileSync(path.join(inputPath, "xlr", "manifest.json")).toString(), (key, value) => {
|
|
515
515
|
if (typeof value === "object" && value !== null) {
|
|
516
516
|
if (key === "capabilities") {
|
|
@@ -535,6 +535,7 @@ class XLRSDK {
|
|
|
535
535
|
loadDefinitionsFromModule(manifest, filters, transforms) {
|
|
536
536
|
return __async(this, null, function* () {
|
|
537
537
|
var _a;
|
|
538
|
+
this.computedNodeCache.clear();
|
|
538
539
|
(_a = Object.keys(manifest.capabilities)) == null ? void 0 : _a.forEach((capabilityName) => {
|
|
539
540
|
if ((filters == null ? void 0 : filters.capabilityFilter) && capabilityName.match(filters == null ? void 0 : filters.capabilityFilter))
|
|
540
541
|
return;
|
|
@@ -554,8 +555,12 @@ class XLRSDK {
|
|
|
554
555
|
if ((options == null ? void 0 : options.getRawType) === true || !type) {
|
|
555
556
|
return type;
|
|
556
557
|
}
|
|
557
|
-
|
|
558
|
-
|
|
558
|
+
if (this.computedNodeCache.has(id)) {
|
|
559
|
+
return this.computedNodeCache.get(id);
|
|
560
|
+
}
|
|
561
|
+
type = fillInGenerics(this.resolveType(type));
|
|
562
|
+
this.computedNodeCache.set(id, type);
|
|
563
|
+
return type;
|
|
559
564
|
}
|
|
560
565
|
hasType(id) {
|
|
561
566
|
return this.registry.has(id);
|
|
@@ -567,7 +572,7 @@ class XLRSDK {
|
|
|
567
572
|
return this.registry.info(id);
|
|
568
573
|
}
|
|
569
574
|
validateByName(typeName, rootNode) {
|
|
570
|
-
const xlr = this.getType(typeName
|
|
575
|
+
const xlr = this.getType(typeName);
|
|
571
576
|
if (!xlr) {
|
|
572
577
|
throw new Error(`Type ${typeName} does not exist in registry, can't validate`);
|
|
573
578
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@player-tools/xlr-sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2--canary.63.1250",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"typescript": "4.8.4"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@player-tools/xlr": "0.4.
|
|
13
|
-
"@player-tools/xlr-utils": "0.4.
|
|
14
|
-
"@player-tools/xlr-converters": "0.4.
|
|
12
|
+
"@player-tools/xlr": "0.4.2--canary.63.1250",
|
|
13
|
+
"@player-tools/xlr-utils": "0.4.2--canary.63.1250",
|
|
14
|
+
"@player-tools/xlr-converters": "0.4.2--canary.63.1250",
|
|
15
15
|
"jsonc-parser": "^2.3.1",
|
|
16
16
|
"@types/node": "^16.11.12",
|
|
17
17
|
"@types/fs-extra": "^9.0.13",
|
package/src/sdk.ts
CHANGED
|
@@ -36,11 +36,13 @@ export class XLRSDK {
|
|
|
36
36
|
private registry: XLRRegistry;
|
|
37
37
|
private validator: XLRValidator;
|
|
38
38
|
private tsWriter: TSWriter;
|
|
39
|
+
private computedNodeCache: Map<string, NodeType>;
|
|
39
40
|
|
|
40
41
|
constructor(customRegistry?: XLRRegistry) {
|
|
41
42
|
this.registry = customRegistry ?? new BasicXLRRegistry();
|
|
42
43
|
this.validator = new XLRValidator(this.getType.bind(this));
|
|
43
44
|
this.tsWriter = new TSWriter();
|
|
45
|
+
this.computedNodeCache = new Map();
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
/**
|
|
@@ -55,6 +57,8 @@ export class XLRSDK {
|
|
|
55
57
|
filters?: Omit<Filters, 'pluginFilter'>,
|
|
56
58
|
transforms?: Array<TransformFunction>
|
|
57
59
|
) {
|
|
60
|
+
this.computedNodeCache.clear();
|
|
61
|
+
|
|
58
62
|
const manifest = JSON.parse(
|
|
59
63
|
fs.readFileSync(path.join(inputPath, 'xlr', 'manifest.json')).toString(),
|
|
60
64
|
(key: unknown, value: unknown) => {
|
|
@@ -112,6 +116,8 @@ export class XLRSDK {
|
|
|
112
116
|
filters?: Omit<Filters, 'pluginFilter'>,
|
|
113
117
|
transforms?: Array<TransformFunction>
|
|
114
118
|
) {
|
|
119
|
+
this.computedNodeCache.clear();
|
|
120
|
+
|
|
115
121
|
Object.keys(manifest.capabilities)?.forEach((capabilityName) => {
|
|
116
122
|
if (
|
|
117
123
|
filters?.capabilityFilter &&
|
|
@@ -156,9 +162,15 @@ export class XLRSDK {
|
|
|
156
162
|
return type;
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
|
|
165
|
+
if (this.computedNodeCache.has(id)) {
|
|
166
|
+
return this.computedNodeCache.get(id) as NamedType<NodeType> | undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
type = fillInGenerics(this.resolveType(type)) as NamedType;
|
|
170
|
+
|
|
171
|
+
this.computedNodeCache.set(id, type);
|
|
160
172
|
|
|
161
|
-
return
|
|
173
|
+
return type;
|
|
162
174
|
}
|
|
163
175
|
|
|
164
176
|
/**
|
|
@@ -199,7 +211,7 @@ export class XLRSDK {
|
|
|
199
211
|
* @returns `Array<ValidationErrors>`
|
|
200
212
|
*/
|
|
201
213
|
public validateByName(typeName: string, rootNode: Node) {
|
|
202
|
-
const xlr = this.getType(typeName
|
|
214
|
+
const xlr = this.getType(typeName);
|
|
203
215
|
if (!xlr) {
|
|
204
216
|
throw new Error(
|
|
205
217
|
`Type ${typeName} does not exist in registry, can't validate`
|
|
@@ -258,7 +270,7 @@ export class XLRSDK {
|
|
|
258
270
|
throw new Error(`Unknown export format ${exportType}`);
|
|
259
271
|
}
|
|
260
272
|
|
|
261
|
-
private resolveType(type: NodeType) {
|
|
273
|
+
private resolveType(type: NodeType): NamedType {
|
|
262
274
|
return simpleTransformGenerator('object', 'any', (objectNode) => {
|
|
263
275
|
if (objectNode.extends) {
|
|
264
276
|
const refName = objectNode.extends.ref.split('<')[0];
|
package/src/validator.ts
CHANGED
|
@@ -57,7 +57,10 @@ export class XLRValidator {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
} else if (xlrNode.type === 'template') {
|
|
60
|
-
this.validateTemplate(rootNode, xlrNode);
|
|
60
|
+
const error = this.validateTemplate(rootNode, xlrNode);
|
|
61
|
+
if (error) {
|
|
62
|
+
validationIssues.push(error);
|
|
63
|
+
}
|
|
61
64
|
} else if (xlrNode.type === 'or') {
|
|
62
65
|
// eslint-disable-next-line no-restricted-syntax
|
|
63
66
|
for (const potentialType of xlrNode.or) {
|
|
@@ -193,22 +196,15 @@ export class XLRValidator {
|
|
|
193
196
|
const issues: Array<ValidationError> = [];
|
|
194
197
|
const objectProps = makePropertyMap(node);
|
|
195
198
|
|
|
196
|
-
let effectiveXLRNode = xlrNode;
|
|
197
|
-
|
|
198
|
-
if (xlrNode.extends) {
|
|
199
|
-
const extendedNode = this.getRefType(xlrNode.extends) as ObjectType;
|
|
200
|
-
effectiveXLRNode = computeEffectiveObject(extendedNode, xlrNode);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
199
|
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
|
204
|
-
for (const prop in
|
|
205
|
-
const expectedType =
|
|
200
|
+
for (const prop in xlrNode.properties) {
|
|
201
|
+
const expectedType = xlrNode.properties[prop];
|
|
206
202
|
const valueNode = objectProps.get(prop);
|
|
207
203
|
if (expectedType.required && valueNode === undefined) {
|
|
208
204
|
issues.push({
|
|
209
205
|
type: 'missing',
|
|
210
206
|
node,
|
|
211
|
-
message: `Property '${prop}' missing from type '${
|
|
207
|
+
message: `Property '${prop}' missing from type '${xlrNode.name}'`,
|
|
212
208
|
});
|
|
213
209
|
}
|
|
214
210
|
|
|
@@ -221,25 +217,22 @@ export class XLRValidator {
|
|
|
221
217
|
|
|
222
218
|
// Check if unknown keys are allowed and if they are - do the violate the constraint
|
|
223
219
|
const extraKeys = Array.from(objectProps.keys()).filter(
|
|
224
|
-
(key) =>
|
|
220
|
+
(key) => xlrNode.properties[key] === undefined
|
|
225
221
|
);
|
|
226
|
-
if (
|
|
227
|
-
effectiveXLRNode.additionalProperties === false &&
|
|
228
|
-
extraKeys.length > 0
|
|
229
|
-
) {
|
|
222
|
+
if (xlrNode.additionalProperties === false && extraKeys.length > 0) {
|
|
230
223
|
issues.push({
|
|
231
224
|
type: 'value',
|
|
232
225
|
node,
|
|
233
|
-
message: `Unexpected properties on '${
|
|
234
|
-
|
|
235
|
-
|
|
226
|
+
message: `Unexpected properties on '${xlrNode.name}': ${extraKeys.join(
|
|
227
|
+
', '
|
|
228
|
+
)}`,
|
|
236
229
|
});
|
|
237
230
|
} else {
|
|
238
231
|
issues.push(
|
|
239
232
|
...extraKeys.flatMap((key) =>
|
|
240
233
|
this.validateType(
|
|
241
234
|
objectProps.get(key) as Node,
|
|
242
|
-
|
|
235
|
+
xlrNode.additionalProperties as NodeType
|
|
243
236
|
)
|
|
244
237
|
)
|
|
245
238
|
);
|