@revisium/schema-toolkit 0.16.4 → 0.17.0

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 (37) hide show
  1. package/dist/{chunk-YCJJVI3Z.js → chunk-6EAIJMZV.js} +238 -28
  2. package/dist/chunk-6EAIJMZV.js.map +1 -0
  3. package/dist/chunk-G6ZKEVVU.cjs +4 -0
  4. package/dist/chunk-G6ZKEVVU.cjs.map +1 -0
  5. package/dist/chunk-NY3H6C7K.js +3 -0
  6. package/dist/chunk-NY3H6C7K.js.map +1 -0
  7. package/dist/{chunk-YGTMLR3D.js → chunk-R4CFU33U.js} +2 -2
  8. package/dist/{chunk-YGTMLR3D.js.map → chunk-R4CFU33U.js.map} +1 -1
  9. package/dist/{chunk-PGR2S2BR.js → chunk-RTBMPBPC.js} +87 -42
  10. package/dist/chunk-RTBMPBPC.js.map +1 -0
  11. package/dist/{chunk-JJ2KGTZX.cjs → chunk-VGADCIBG.cjs} +2 -2
  12. package/dist/{chunk-JJ2KGTZX.cjs.map → chunk-VGADCIBG.cjs.map} +1 -1
  13. package/dist/{chunk-MAEGAVK4.cjs → chunk-YRKXZTRZ.cjs} +288 -71
  14. package/dist/chunk-YRKXZTRZ.cjs.map +1 -0
  15. package/dist/{chunk-VGB4YCGF.cjs → chunk-ZG7QX4I3.cjs} +87 -42
  16. package/dist/chunk-ZG7QX4I3.cjs.map +1 -0
  17. package/dist/core/index.cjs +57 -57
  18. package/dist/core/index.d.cts +15 -4
  19. package/dist/core/index.d.ts +15 -4
  20. package/dist/core/index.js +1 -1
  21. package/dist/index.cjs +189 -160
  22. package/dist/index.d.cts +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +4 -3
  25. package/dist/mocks/index.cjs +18 -17
  26. package/dist/mocks/index.js +2 -1
  27. package/dist/model/index.cjs +68 -39
  28. package/dist/model/index.d.cts +80 -5
  29. package/dist/model/index.d.ts +80 -5
  30. package/dist/model/index.js +3 -2
  31. package/dist/{types-bBnnfNxC.d.ts → types-6S07rMdY.d.ts} +1 -0
  32. package/dist/{types-BUiNI0oL.d.cts → types-DHlnrQKG.d.cts} +1 -0
  33. package/package.json +1 -1
  34. package/dist/chunk-MAEGAVK4.cjs.map +0 -1
  35. package/dist/chunk-PGR2S2BR.js.map +0 -1
  36. package/dist/chunk-VGB4YCGF.cjs.map +0 -1
  37. package/dist/chunk-YCJJVI3Z.js.map +0 -1
@@ -1,12 +1,15 @@
1
- import { AbstractBasePath, ParsedFormula, createRefNode, createObjectNode, createArrayNode, createStringNode, createNumberNode, createBooleanNode, makeAutoObservable, observable, makeObservable, runInAction, PatchBuilder, SchemaSerializer, FormulaDependencyIndex, createSchemaTree, FormulaSerializer, validateSchema, validateFormulas } from './chunk-PGR2S2BR.js';
1
+ import { AbstractBasePath, ParsedFormula, createRefNode, createObjectNode, createArrayNode, createStringNode, createNumberNode, createBooleanNode, makeAutoObservable, observable, makeObservable, runInAction, PatchBuilder, SchemaSerializer, FormulaDependencyIndex, createSchemaTree, FormulaSerializer, validateSchema, validateFormulas } from './chunk-RTBMPBPC.js';
2
+ import { obj, ref } from './chunk-R4CFU33U.js';
2
3
  import { nanoid } from 'nanoid';
3
4
 
4
5
  var SchemaParser = class {
5
6
  pendingFormulas = [];
6
7
  _parseErrors = [];
7
- parse(schema) {
8
+ _refSchemas = {};
9
+ parse(schema, refSchemas) {
8
10
  this.pendingFormulas = [];
9
11
  this._parseErrors = [];
12
+ this._refSchemas = refSchemas ?? {};
10
13
  return this.parseNode(schema, "root");
11
14
  }
12
15
  parseFormulas(tree) {
@@ -30,27 +33,32 @@ var SchemaParser = class {
30
33
  get parseErrors() {
31
34
  return this._parseErrors;
32
35
  }
33
- parseNode(schema, name) {
36
+ parseNode(schema, name, parentRef) {
34
37
  if ("$ref" in schema) {
35
- return createRefNode(nanoid(), name, schema.$ref, this.extractMetadata(schema));
38
+ const refValue = schema.$ref;
39
+ const resolvedSchema = this._refSchemas[refValue];
40
+ if (resolvedSchema) {
41
+ return this.parseNode(resolvedSchema, name, refValue);
42
+ }
43
+ return createRefNode(nanoid(), name, refValue, this.extractMetadata(schema));
36
44
  }
37
45
  const schemaWithType = schema;
38
46
  switch (schemaWithType.type) {
39
47
  case "object" /* Object */:
40
- return this.parseObject(schemaWithType, name);
48
+ return this.parseObject(schemaWithType, name, parentRef);
41
49
  case "array" /* Array */:
42
- return this.parseArray(schemaWithType, name);
50
+ return this.parseArray(schemaWithType, name, parentRef);
43
51
  case "string" /* String */:
44
- return this.parseString(schemaWithType, name);
52
+ return this.parseString(schemaWithType, name, parentRef);
45
53
  case "number" /* Number */:
46
- return this.parseNumber(schemaWithType, name);
54
+ return this.parseNumber(schemaWithType, name, parentRef);
47
55
  case "boolean" /* Boolean */:
48
- return this.parseBoolean(schemaWithType, name);
56
+ return this.parseBoolean(schemaWithType, name, parentRef);
49
57
  default:
50
58
  throw new Error(`Unknown schema type: ${schemaWithType.type}`);
51
59
  }
52
60
  }
53
- parseObject(schema, name) {
61
+ parseObject(schema, name, ref2) {
54
62
  const children = [];
55
63
  for (const propName of Object.keys(schema.properties).sort((a, b) => a.localeCompare(b))) {
56
64
  const propSchema = schema.properties[propName];
@@ -58,35 +66,44 @@ var SchemaParser = class {
58
66
  children.push(this.parseNode(propSchema, propName));
59
67
  }
60
68
  }
61
- return createObjectNode(nanoid(), name, children, this.extractMetadata(schema));
69
+ return createObjectNode(nanoid(), name, children, {
70
+ metadata: this.extractMetadata(schema),
71
+ ref: ref2
72
+ });
62
73
  }
63
- parseArray(schema, name) {
74
+ parseArray(schema, name, ref2) {
64
75
  const items = this.parseNode(schema.items, "items");
65
- return createArrayNode(nanoid(), name, items, this.extractMetadata(schema));
76
+ return createArrayNode(nanoid(), name, items, {
77
+ metadata: this.extractMetadata(schema),
78
+ ref: ref2
79
+ });
66
80
  }
67
- parseString(schema, name) {
81
+ parseString(schema, name, ref2) {
68
82
  const nodeId = nanoid();
69
83
  this.collectFormula(nodeId, schema["x-formula"]);
70
84
  return createStringNode(nodeId, name, {
71
85
  defaultValue: schema.default,
72
86
  foreignKey: schema.foreignKey,
73
- metadata: this.extractMetadata(schema)
87
+ metadata: this.extractMetadata(schema),
88
+ ref: ref2
74
89
  });
75
90
  }
76
- parseNumber(schema, name) {
91
+ parseNumber(schema, name, ref2) {
77
92
  const nodeId = nanoid();
78
93
  this.collectFormula(nodeId, schema["x-formula"]);
79
94
  return createNumberNode(nodeId, name, {
80
95
  defaultValue: schema.default,
81
- metadata: this.extractMetadata(schema)
96
+ metadata: this.extractMetadata(schema),
97
+ ref: ref2
82
98
  });
83
99
  }
84
- parseBoolean(schema, name) {
100
+ parseBoolean(schema, name, ref2) {
85
101
  const nodeId = nanoid();
86
102
  this.collectFormula(nodeId, schema["x-formula"]);
87
103
  return createBooleanNode(nodeId, name, {
88
104
  defaultValue: schema.default,
89
- metadata: this.extractMetadata(schema)
105
+ metadata: this.extractMetadata(schema),
106
+ ref: ref2
90
107
  });
91
108
  }
92
109
  extractMetadata(schema) {
@@ -224,6 +241,193 @@ function generateDefaultValue(schema, options = {}) {
224
241
  }
225
242
  return generateDefaultValueInternal(schema, options);
226
243
  }
244
+ var PrimitiveToArrayTransformer = class {
245
+ canTransform(ctx) {
246
+ const { sourceNode, targetSpec } = ctx;
247
+ return sourceNode.isPrimitive() && targetSpec.type === "array";
248
+ }
249
+ transform(ctx) {
250
+ const { sourceNode } = ctx;
251
+ const itemsNode = sourceNode.cloneWithId(nanoid());
252
+ itemsNode.setName("items");
253
+ const arrayNode = createArrayNode(nanoid(), sourceNode.name(), itemsNode);
254
+ return { node: arrayNode };
255
+ }
256
+ };
257
+ var ObjectToArrayTransformer = class {
258
+ canTransform(ctx) {
259
+ const { sourceNode, targetSpec } = ctx;
260
+ return sourceNode.isObject() && targetSpec.type === "array";
261
+ }
262
+ transform(ctx) {
263
+ const { sourceNode } = ctx;
264
+ const itemsNode = sourceNode.cloneWithId(nanoid());
265
+ itemsNode.setName("items");
266
+ const arrayNode = createArrayNode(nanoid(), sourceNode.name(), itemsNode);
267
+ return { node: arrayNode };
268
+ }
269
+ };
270
+ var ArrayToItemsTypeTransformer = class {
271
+ canTransform(ctx) {
272
+ const { sourceNode, targetSpec } = ctx;
273
+ if (!sourceNode.isArray()) {
274
+ return false;
275
+ }
276
+ const targetType = targetSpec.type;
277
+ if (!targetType || !this.isPrimitiveType(targetType)) {
278
+ return false;
279
+ }
280
+ const items = sourceNode.items();
281
+ return items.nodeType() === targetType;
282
+ }
283
+ transform(ctx) {
284
+ const { sourceNode } = ctx;
285
+ const items = sourceNode.items();
286
+ const newNode = items.cloneWithId(nanoid());
287
+ newNode.setName(sourceNode.name());
288
+ return { node: newNode };
289
+ }
290
+ isPrimitiveType(type) {
291
+ return type === "string" || type === "number" || type === "boolean";
292
+ }
293
+ };
294
+ var RefTransformer = class {
295
+ canTransform(ctx) {
296
+ return ctx.targetSpec.$ref !== void 0;
297
+ }
298
+ transform(ctx) {
299
+ const { sourceNode, targetSpec, refSchemas } = ctx;
300
+ const refUri = targetSpec.$ref;
301
+ const resolvedSchema = refSchemas?.[refUri];
302
+ if (resolvedSchema) {
303
+ const parser = new SchemaParser();
304
+ const wrapperSchema = obj({ temp: ref(refUri) });
305
+ const resolvedNode = parser.parse(wrapperSchema, refSchemas);
306
+ const tempNode = resolvedNode.property("temp");
307
+ const newNode = tempNode.cloneWithId(nanoid());
308
+ newNode.setName(sourceNode.name());
309
+ return { node: newNode };
310
+ }
311
+ const metadata = this.extractMetadata(targetSpec);
312
+ const node = createRefNode(nanoid(), sourceNode.name(), refUri, metadata);
313
+ return { node };
314
+ }
315
+ extractMetadata(spec) {
316
+ const meta = {};
317
+ let hasValue = false;
318
+ if (spec.title) {
319
+ meta.title = spec.title;
320
+ hasValue = true;
321
+ }
322
+ if (spec.description) {
323
+ meta.description = spec.description;
324
+ hasValue = true;
325
+ }
326
+ if (spec.deprecated) {
327
+ meta.deprecated = spec.deprecated;
328
+ hasValue = true;
329
+ }
330
+ return hasValue ? meta : void 0;
331
+ }
332
+ };
333
+ var DefaultTransformer = class {
334
+ canTransform(ctx) {
335
+ return ctx.targetSpec.type !== void 0;
336
+ }
337
+ transform(ctx) {
338
+ const { sourceNode, targetSpec } = ctx;
339
+ const type = targetSpec.type;
340
+ const metadata = this.extractMetadata(targetSpec);
341
+ const node = this.createNode(sourceNode.name(), type, targetSpec, metadata);
342
+ return { node };
343
+ }
344
+ createNode(name, type, spec, metadata) {
345
+ switch (type) {
346
+ case "string":
347
+ return createStringNode(nanoid(), name, {
348
+ defaultValue: spec.default ?? "",
349
+ foreignKey: spec.foreignKey,
350
+ metadata
351
+ });
352
+ case "number":
353
+ return createNumberNode(nanoid(), name, {
354
+ defaultValue: spec.default ?? 0,
355
+ metadata
356
+ });
357
+ case "boolean":
358
+ return createBooleanNode(nanoid(), name, {
359
+ defaultValue: spec.default ?? false,
360
+ metadata
361
+ });
362
+ case "object":
363
+ return createObjectNode(nanoid(), name, [], { metadata });
364
+ case "array":
365
+ return this.createArrayNode(name, metadata);
366
+ default:
367
+ throw new Error(`Unknown field type: ${type}`);
368
+ }
369
+ }
370
+ createArrayNode(name, metadata) {
371
+ const items = createStringNode(nanoid(), "items", { defaultValue: "" });
372
+ return createArrayNode(nanoid(), name, items, { metadata });
373
+ }
374
+ extractMetadata(spec) {
375
+ const meta = {};
376
+ let hasValue = false;
377
+ if (spec.title) {
378
+ meta.title = spec.title;
379
+ hasValue = true;
380
+ }
381
+ if (spec.description) {
382
+ meta.description = spec.description;
383
+ hasValue = true;
384
+ }
385
+ if (spec.deprecated) {
386
+ meta.deprecated = spec.deprecated;
387
+ hasValue = true;
388
+ }
389
+ return hasValue ? meta : void 0;
390
+ }
391
+ };
392
+
393
+ // src/model/type-transformer/TypeTransformChain.ts
394
+ var TypeTransformChain = class {
395
+ _transformers;
396
+ _refSchemas;
397
+ constructor(options = {}) {
398
+ this._refSchemas = options.refSchemas;
399
+ this._transformers = [
400
+ ...options.customTransformers ?? [],
401
+ new PrimitiveToArrayTransformer(),
402
+ new ObjectToArrayTransformer(),
403
+ new ArrayToItemsTypeTransformer(),
404
+ new RefTransformer(),
405
+ new DefaultTransformer()
406
+ ];
407
+ }
408
+ transform(sourceNode, spec) {
409
+ const normalizedSpec = this.normalizeSpec(spec);
410
+ const ctx = {
411
+ sourceNode,
412
+ targetSpec: normalizedSpec,
413
+ refSchemas: this._refSchemas
414
+ };
415
+ const transformer = this._transformers.find((t) => t.canTransform(ctx));
416
+ if (!transformer) {
417
+ throw new Error(`No transformer found for spec: ${JSON.stringify(spec)}`);
418
+ }
419
+ return transformer.transform(ctx);
420
+ }
421
+ normalizeSpec(spec) {
422
+ if (typeof spec === "string") {
423
+ return { type: spec };
424
+ }
425
+ return spec;
426
+ }
427
+ };
428
+ function createTypeTransformChain(options) {
429
+ return new TypeTransformChain(options);
430
+ }
227
431
 
228
432
  // src/model/schema-model/SchemaModelImpl.ts
229
433
  var SchemaModelImpl = class {
@@ -233,22 +437,28 @@ var SchemaModelImpl = class {
233
437
  _serializer = new SchemaSerializer();
234
438
  _nodeFactory = new NodeFactory();
235
439
  _formulaIndex = new FormulaDependencyIndex();
440
+ _transformChain;
236
441
  _formulaParseErrors = [];
237
442
  _refSchemas;
238
443
  constructor(schema, options) {
444
+ this._refSchemas = options?.refSchemas;
445
+ this._transformChain = new TypeTransformChain({
446
+ refSchemas: this._refSchemas,
447
+ customTransformers: options?.customTransformers
448
+ });
239
449
  const parser = new SchemaParser();
240
- const rootNode = parser.parse(schema);
450
+ const rootNode = parser.parse(schema, this._refSchemas);
241
451
  this._currentTree = createSchemaTree(rootNode);
242
452
  parser.parseFormulas(this._currentTree);
243
453
  this._formulaParseErrors = parser.parseErrors;
244
454
  this._buildFormulaIndex();
245
455
  this._baseTree = this._currentTree.clone();
246
- this._refSchemas = options?.refSchemas;
247
456
  makeAutoObservable(this, {
248
457
  _patchBuilder: false,
249
458
  _serializer: false,
250
459
  _nodeFactory: false,
251
460
  _formulaIndex: false,
461
+ _transformChain: false,
252
462
  _refSchemas: false,
253
463
  _currentTree: "observable.ref",
254
464
  _baseTree: "observable.ref",
@@ -292,10 +502,10 @@ var SchemaModelImpl = class {
292
502
  if (path.isEmpty()) {
293
503
  return node;
294
504
  }
295
- const newNode = this._nodeFactory.createNode(node.name(), newType);
296
- this._currentTree.setNodeAt(path, newNode);
297
- this._currentTree.trackReplacement(nodeId, newNode.id());
298
- return newNode;
505
+ const result = this._transformChain.transform(node, newType);
506
+ this._currentTree.setNodeAt(path, result.node);
507
+ this._currentTree.trackReplacement(nodeId, result.node.id());
508
+ return result.node;
299
509
  }
300
510
  updateMetadata(nodeId, meta) {
301
511
  const node = this._currentTree.nodeById(nodeId);
@@ -2244,6 +2454,6 @@ function createDataModel(options) {
2244
2454
  return new DataModelImpl(options);
2245
2455
  }
2246
2456
 
2247
- export { ArrayValueNode, BasePrimitiveValueNode, BaseValueNode, BooleanValueNode, DataModelImpl, ForeignKeyNotFoundError, ForeignKeyResolverImpl, ForeignKeyResolverNotConfiguredError, ForeignKeyValueNodeImpl, NodeFactory, NodeFactory2, NodeFactoryRegistry, NumberValueNode, ObjectValueNode, RowModelImpl, SchemaParser, StringValueNode, TableModelImpl, ValueType, createDataModel, createDefaultRegistry, createForeignKeyResolver, createNodeFactory, createSchemaModel, createTableModel, extractFormulaDefinition, generateDefaultValue, generateNodeId, isForeignKeyValueNode, resetNodeIdCounter };
2248
- //# sourceMappingURL=chunk-YCJJVI3Z.js.map
2249
- //# sourceMappingURL=chunk-YCJJVI3Z.js.map
2457
+ export { ArrayToItemsTypeTransformer, ArrayValueNode, BasePrimitiveValueNode, BaseValueNode, BooleanValueNode, DataModelImpl, DefaultTransformer, ForeignKeyNotFoundError, ForeignKeyResolverImpl, ForeignKeyResolverNotConfiguredError, ForeignKeyValueNodeImpl, NodeFactory, NodeFactory2, NodeFactoryRegistry, NumberValueNode, ObjectToArrayTransformer, ObjectValueNode, PrimitiveToArrayTransformer, RefTransformer, RowModelImpl, SchemaParser, StringValueNode, TableModelImpl, TypeTransformChain, ValueType, createDataModel, createDefaultRegistry, createForeignKeyResolver, createNodeFactory, createSchemaModel, createTableModel, createTypeTransformChain, extractFormulaDefinition, generateDefaultValue, generateNodeId, isForeignKeyValueNode, resetNodeIdCounter };
2458
+ //# sourceMappingURL=chunk-6EAIJMZV.js.map
2459
+ //# sourceMappingURL=chunk-6EAIJMZV.js.map