@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 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
- let effectiveXLRNode = xlrNode;
230
- if (xlrNode.extends) {
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 '${effectiveXLRNode.name}'`
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) => effectiveXLRNode.properties[key] === void 0);
249
- if (effectiveXLRNode.additionalProperties === false && extraKeys.length > 0) {
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 '${effectiveXLRNode.name}': ${extraKeys.join(", ")}`
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), effectiveXLRNode.additionalProperties)));
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
- type = this.resolveType(type);
568
- return xlrUtils.fillInGenerics(type);
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, { getRawType: true });
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
@@ -61,6 +61,7 @@ declare class XLRSDK {
61
61
  private registry;
62
62
  private validator;
63
63
  private tsWriter;
64
+ private computedNodeCache;
64
65
  constructor(customRegistry?: XLRRegistry);
65
66
  /**
66
67
  * Loads definitions from a path on the filesystem
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isPrimitiveTypeNode, resolveConditional, makePropertyMap, computeEffectiveObject, resolveReferenceNode, fillInGenerics } from '@player-tools/xlr-utils';
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
- let effectiveXLRNode = xlrNode;
220
- if (xlrNode.extends) {
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 '${effectiveXLRNode.name}'`
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) => effectiveXLRNode.properties[key] === void 0);
239
- if (effectiveXLRNode.additionalProperties === false && extraKeys.length > 0) {
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 '${effectiveXLRNode.name}': ${extraKeys.join(", ")}`
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), effectiveXLRNode.additionalProperties)));
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
- type = this.resolveType(type);
558
- return fillInGenerics(type);
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, { getRawType: true });
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.1",
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.1",
13
- "@player-tools/xlr-utils": "0.4.1",
14
- "@player-tools/xlr-converters": "0.4.1",
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
- type = this.resolveType(type);
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 fillInGenerics(type) as NamedType;
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, { getRawType: true });
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 effectiveXLRNode.properties) {
205
- const expectedType = effectiveXLRNode.properties[prop];
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 '${effectiveXLRNode.name}'`,
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) => effectiveXLRNode.properties[key] === undefined
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
- effectiveXLRNode.name
235
- }': ${extraKeys.join(', ')}`,
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
- effectiveXLRNode.additionalProperties as NodeType
235
+ xlrNode.additionalProperties as NodeType
243
236
  )
244
237
  )
245
238
  );