@revisium/schema-toolkit 0.16.0 → 0.16.2

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 (83) hide show
  1. package/dist/{chunk-IWRV6QAD.cjs → chunk-44ZEZUWU.cjs} +419 -86
  2. package/dist/chunk-44ZEZUWU.cjs.map +1 -0
  3. package/dist/{chunk-HY4VE7H2.js → chunk-55AMH44G.js} +3 -3
  4. package/dist/chunk-55AMH44G.js.map +1 -0
  5. package/dist/{chunk-TMWPWGUN.cjs → chunk-B3T6YB2D.cjs} +6 -6
  6. package/dist/chunk-B3T6YB2D.cjs.map +1 -0
  7. package/dist/{chunk-GAPLSVZN.cjs → chunk-J6SCHJKG.cjs} +2 -2
  8. package/dist/chunk-J6SCHJKG.cjs.map +1 -0
  9. package/dist/chunk-JJ2KGTZX.cjs +105 -0
  10. package/dist/chunk-JJ2KGTZX.cjs.map +1 -0
  11. package/dist/{chunk-S7GEDTSL.js → chunk-KLDN3IHB.js} +408 -88
  12. package/dist/chunk-KLDN3IHB.js.map +1 -0
  13. package/dist/chunk-MLNKM67U.cjs +4 -0
  14. package/dist/chunk-MLNKM67U.cjs.map +1 -0
  15. package/dist/{chunk-CYTPQYVM.js → chunk-MPF6VCB5.js} +2 -2
  16. package/dist/chunk-MPF6VCB5.js.map +1 -0
  17. package/dist/{chunk-OR2I3XOQ.cjs → chunk-OY5NX5DZ.cjs} +232 -288
  18. package/dist/chunk-OY5NX5DZ.cjs.map +1 -0
  19. package/dist/{chunk-2NRQPOQY.js → chunk-QEV4Q4TR.js} +3 -3
  20. package/dist/{chunk-2NRQPOQY.js.map → chunk-QEV4Q4TR.js.map} +1 -1
  21. package/dist/{chunk-XS47N22X.cjs → chunk-V6JTSET2.cjs} +13 -13
  22. package/dist/{chunk-XS47N22X.cjs.map → chunk-V6JTSET2.cjs.map} +1 -1
  23. package/dist/{chunk-LF6CGXRQ.js → chunk-VQZNN335.js} +216 -272
  24. package/dist/chunk-VQZNN335.js.map +1 -0
  25. package/dist/chunk-Y2GYABV7.js +3 -0
  26. package/dist/chunk-Y2GYABV7.js.map +1 -0
  27. package/dist/chunk-YGTMLR3D.js +88 -0
  28. package/dist/chunk-YGTMLR3D.js.map +1 -0
  29. package/dist/core/index.cjs +84 -70
  30. package/dist/core/index.cjs.map +1 -1
  31. package/dist/core/index.d.cts +69 -7
  32. package/dist/core/index.d.ts +69 -7
  33. package/dist/core/index.js +3 -24
  34. package/dist/core/index.js.map +1 -1
  35. package/dist/formula/index.d.cts +1 -1
  36. package/dist/formula/index.d.ts +1 -1
  37. package/dist/index.cjs +373 -112
  38. package/dist/index.d.cts +10 -10
  39. package/dist/index.d.ts +10 -10
  40. package/dist/index.js +7 -6
  41. package/dist/{json-patch.types-eltVqnWC.d.cts → json-patch.types-Cu0Medki.d.cts} +1 -1
  42. package/dist/{json-patch.types-DTUHS9SV.d.ts → json-patch.types-DY7k9hxy.d.ts} +1 -1
  43. package/dist/{json-string.store-DKlkc1u_.d.cts → json-string.store-DOZn38CI.d.cts} +2 -2
  44. package/dist/{json-string.store-DMrHPJ3v.d.ts → json-string.store-DRmQFKrp.d.ts} +2 -2
  45. package/dist/lib/index.cjs +40 -40
  46. package/dist/lib/index.d.cts +4 -4
  47. package/dist/lib/index.d.ts +4 -4
  48. package/dist/lib/index.js +3 -3
  49. package/dist/mocks/index.cjs +36 -12
  50. package/dist/mocks/index.d.cts +28 -9
  51. package/dist/mocks/index.d.ts +28 -9
  52. package/dist/mocks/index.js +2 -2
  53. package/dist/model/index.cjs +86 -58
  54. package/dist/model/index.d.cts +116 -47
  55. package/dist/model/index.d.ts +116 -47
  56. package/dist/model/index.js +4 -4
  57. package/dist/plugins/index.cjs +1 -1
  58. package/dist/plugins/index.d.cts +9 -9
  59. package/dist/plugins/index.d.ts +9 -9
  60. package/dist/plugins/index.js +1 -1
  61. package/dist/{schema.types-ZX5fUW1X.d.cts → schema.types-B5OgKLpV.d.cts} +3 -2
  62. package/dist/{schema.types-ZX5fUW1X.d.ts → schema.types-B5OgKLpV.d.ts} +3 -2
  63. package/dist/types/index.cjs +2 -2
  64. package/dist/types/index.d.cts +4 -4
  65. package/dist/types/index.d.ts +4 -4
  66. package/dist/types/index.js +1 -1
  67. package/dist/{types-DMzUCve0.d.cts → types-BUiNI0oL.d.cts} +29 -34
  68. package/dist/{types-Cnfj5nLO.d.ts → types-bBnnfNxC.d.ts} +29 -34
  69. package/package.json +4 -1
  70. package/dist/FormulaValidator-CKE2kT4C.d.cts +0 -10
  71. package/dist/FormulaValidator-DGGmwqDQ.d.ts +0 -10
  72. package/dist/chunk-AORPUIKD.js +0 -81
  73. package/dist/chunk-AORPUIKD.js.map +0 -1
  74. package/dist/chunk-CYTPQYVM.js.map +0 -1
  75. package/dist/chunk-EJYILFAK.cjs +0 -92
  76. package/dist/chunk-EJYILFAK.cjs.map +0 -1
  77. package/dist/chunk-GAPLSVZN.cjs.map +0 -1
  78. package/dist/chunk-HY4VE7H2.js.map +0 -1
  79. package/dist/chunk-IWRV6QAD.cjs.map +0 -1
  80. package/dist/chunk-LF6CGXRQ.js.map +0 -1
  81. package/dist/chunk-OR2I3XOQ.cjs.map +0 -1
  82. package/dist/chunk-S7GEDTSL.js.map +0 -1
  83. package/dist/chunk-TMWPWGUN.cjs.map +0 -1
@@ -81,9 +81,104 @@ var NullNodeImpl = class {
81
81
  }
82
82
  setForeignKey(_key) {
83
83
  }
84
+ contentMediaType() {
85
+ return void 0;
86
+ }
87
+ setContentMediaType(_mediaType) {
88
+ }
84
89
  };
85
90
  var NULL_NODE = new NullNodeImpl();
86
91
 
92
+ // src/core/reactivity/provider.ts
93
+ var noopProvider = {
94
+ makeObservable: (target) => target,
95
+ makeAutoObservable: (target) => target,
96
+ isObservable: () => false,
97
+ observable: {
98
+ map: () => /* @__PURE__ */ new Map(),
99
+ array: () => []
100
+ },
101
+ runInAction: (fn) => fn(),
102
+ reaction: () => () => {
103
+ }
104
+ };
105
+ var currentProvider = noopProvider;
106
+ function setReactivityProvider(provider) {
107
+ currentProvider = provider;
108
+ }
109
+ function getReactivityProvider() {
110
+ return currentProvider;
111
+ }
112
+ function resetReactivityProvider() {
113
+ currentProvider = noopProvider;
114
+ }
115
+
116
+ // src/core/reactivity/api.ts
117
+ function makeObservable(target, annotations) {
118
+ return getReactivityProvider().makeObservable(target, annotations);
119
+ }
120
+ function makeAutoObservable(target, overrides) {
121
+ return getReactivityProvider().makeAutoObservable(target, overrides ?? {});
122
+ }
123
+ var observable = {
124
+ map() {
125
+ return getReactivityProvider().observable.map();
126
+ },
127
+ array() {
128
+ return getReactivityProvider().observable.array();
129
+ }
130
+ };
131
+ function runInAction(fn) {
132
+ return getReactivityProvider().runInAction(fn);
133
+ }
134
+ function reaction(expression, effect) {
135
+ return getReactivityProvider().reaction(expression, effect);
136
+ }
137
+
138
+ // src/core/reactivity/mobx-provider.ts
139
+ function convertAnnotations(mobx, annotations) {
140
+ const result = {};
141
+ for (const [key, value] of Object.entries(annotations)) {
142
+ if (typeof value === "string") {
143
+ switch (value) {
144
+ case "observable":
145
+ result[key] = mobx.observable;
146
+ break;
147
+ case "observable.ref":
148
+ result[key] = mobx.observable.ref;
149
+ break;
150
+ case "observable.shallow":
151
+ result[key] = mobx.observable.shallow;
152
+ break;
153
+ case "action":
154
+ result[key] = mobx.action;
155
+ break;
156
+ case "computed":
157
+ result[key] = mobx.computed;
158
+ break;
159
+ default:
160
+ result[key] = value;
161
+ }
162
+ } else {
163
+ result[key] = value;
164
+ }
165
+ }
166
+ return result;
167
+ }
168
+ function createMobxProvider(mobx) {
169
+ return {
170
+ makeObservable: (target, annotations) => mobx.makeObservable(target, convertAnnotations(mobx, annotations)),
171
+ makeAutoObservable: (target, overrides) => mobx.makeAutoObservable(target, overrides ? convertAnnotations(mobx, overrides) : {}),
172
+ isObservable: mobx.isObservable,
173
+ observable: {
174
+ map: () => mobx.observable.map(),
175
+ array: () => mobx.observable.array()
176
+ },
177
+ runInAction: mobx.runInAction,
178
+ reaction: mobx.reaction
179
+ };
180
+ }
181
+
87
182
  // src/core/schema-node/BaseNode.ts
88
183
  var BaseNode = class {
89
184
  constructor(_id, name, metadata = EMPTY_METADATA) {
@@ -93,6 +188,14 @@ var BaseNode = class {
93
188
  }
94
189
  _name;
95
190
  _metadata;
191
+ initBaseObservable() {
192
+ makeObservable(this, {
193
+ _name: "observable",
194
+ _metadata: "observable.ref",
195
+ setName: "action",
196
+ setMetadata: "action"
197
+ });
198
+ }
96
199
  id() {
97
200
  return this._id;
98
201
  }
@@ -141,6 +244,9 @@ var BaseNode = class {
141
244
  foreignKey() {
142
245
  return void 0;
143
246
  }
247
+ contentMediaType() {
248
+ return void 0;
249
+ }
144
250
  setName(name) {
145
251
  this._name = name;
146
252
  }
@@ -163,6 +269,8 @@ var BaseNode = class {
163
269
  }
164
270
  setForeignKey(_key) {
165
271
  }
272
+ setContentMediaType(_mediaType) {
273
+ }
166
274
  };
167
275
 
168
276
  // src/core/schema-node/ObjectNode.ts
@@ -171,6 +279,13 @@ var ObjectNode = class _ObjectNode extends BaseNode {
171
279
  constructor(id, name, children = [], metadata = EMPTY_METADATA) {
172
280
  super(id, name, metadata);
173
281
  this._children = [...children];
282
+ this.initBaseObservable();
283
+ makeObservable(this, {
284
+ _children: "observable.shallow",
285
+ addChild: "action",
286
+ removeChild: "action",
287
+ replaceChild: "action"
288
+ });
174
289
  }
175
290
  nodeType() {
176
291
  return "object";
@@ -222,6 +337,11 @@ var ArrayNode = class _ArrayNode extends BaseNode {
222
337
  constructor(id, name, items, metadata = EMPTY_METADATA) {
223
338
  super(id, name, metadata);
224
339
  this._items = items;
340
+ this.initBaseObservable();
341
+ makeObservable(this, {
342
+ _items: "observable.ref",
343
+ setItems: "action"
344
+ });
225
345
  }
226
346
  nodeType() {
227
347
  return "array";
@@ -262,6 +382,20 @@ var PrimitiveNode = class extends BaseNode {
262
382
  this._foreignKey = options.foreignKey;
263
383
  this._formula = options.formula;
264
384
  }
385
+ initPrimitiveObservable() {
386
+ makeObservable(this, {
387
+ _name: "observable",
388
+ _metadata: "observable.ref",
389
+ _formula: "observable.ref",
390
+ _defaultValue: "observable",
391
+ _foreignKey: "observable",
392
+ setName: "action",
393
+ setMetadata: "action",
394
+ setFormula: "action",
395
+ setDefaultValue: "action",
396
+ setForeignKey: "action"
397
+ });
398
+ }
265
399
  isPrimitive() {
266
400
  return true;
267
401
  }
@@ -290,12 +424,25 @@ var PrimitiveNode = class extends BaseNode {
290
424
 
291
425
  // src/core/schema-node/StringNode.ts
292
426
  var StringNode = class _StringNode extends PrimitiveNode {
427
+ _contentMediaType;
293
428
  constructor(id, name, options = {}) {
294
429
  super(id, name, options);
430
+ this._contentMediaType = options.contentMediaType;
431
+ this.initPrimitiveObservable();
432
+ makeObservable(this, {
433
+ _contentMediaType: "observable",
434
+ setContentMediaType: "action"
435
+ });
295
436
  }
296
437
  nodeType() {
297
438
  return "string";
298
439
  }
440
+ contentMediaType() {
441
+ return this._contentMediaType;
442
+ }
443
+ setContentMediaType(mediaType) {
444
+ this._contentMediaType = mediaType;
445
+ }
299
446
  clone() {
300
447
  return new _StringNode(this.id(), this.name(), this.cloneOptions());
301
448
  }
@@ -304,7 +451,8 @@ var StringNode = class _StringNode extends PrimitiveNode {
304
451
  defaultValue: this._defaultValue,
305
452
  foreignKey: this._foreignKey,
306
453
  formula: this._formula,
307
- metadata: this._metadata
454
+ metadata: this._metadata,
455
+ contentMediaType: this._contentMediaType
308
456
  };
309
457
  }
310
458
  };
@@ -316,6 +464,7 @@ function createStringNode(id, name, options = {}) {
316
464
  var NumberNode = class _NumberNode extends PrimitiveNode {
317
465
  constructor(id, name, options = {}) {
318
466
  super(id, name, options);
467
+ this.initPrimitiveObservable();
319
468
  }
320
469
  nodeType() {
321
470
  return "number";
@@ -339,6 +488,7 @@ function createNumberNode(id, name, options = {}) {
339
488
  var BooleanNode = class _BooleanNode extends PrimitiveNode {
340
489
  constructor(id, name, options = {}) {
341
490
  super(id, name, options);
491
+ this.initPrimitiveObservable();
342
492
  }
343
493
  nodeType() {
344
494
  return "boolean";
@@ -367,6 +517,7 @@ var RefNode = class _RefNode extends BaseNode {
367
517
  throw new Error("RefNode requires a non-empty ref");
368
518
  }
369
519
  this._ref = ref;
520
+ this.initBaseObservable();
370
521
  }
371
522
  nodeType() {
372
523
  return "ref";
@@ -511,23 +662,25 @@ function jsonPointerToSegments(pointer) {
511
662
  if (pointer === "" || pointer === "/") {
512
663
  return [];
513
664
  }
514
- const parts = pointer.split("/").filter(Boolean);
665
+ const parts = pointer.startsWith("/") ? pointer.slice(1).split("/") : pointer.split("/");
515
666
  const segments = [];
516
667
  let i = 0;
517
668
  while (i < parts.length) {
518
669
  const part = parts[i];
519
670
  if (part === "properties") {
520
- const name = parts[i + 1];
521
- if (name === void 0 || name === "") {
522
- throw new Error(
523
- `Invalid path: 'properties' segment requires a name in path ${pointer}`
524
- );
671
+ const hasNextPart = i + 1 < parts.length;
672
+ if (hasNextPart) {
673
+ const name = parts[i + 1] ?? "";
674
+ segments.push(new PropertySegment(name));
675
+ i += 2;
676
+ } else {
677
+ i += 1;
525
678
  }
526
- segments.push(new PropertySegment(name));
527
- i += 2;
528
679
  } else if (part === "items") {
529
680
  segments.push(new ItemsSegment());
530
681
  i += 1;
682
+ } else if (part === "") {
683
+ i += 1;
531
684
  } else {
532
685
  throw new Error(`Invalid path segment: ${part} in path ${pointer}`);
533
686
  }
@@ -543,8 +696,14 @@ function jsonPointerToSimplePath(pointer) {
543
696
 
544
697
  // src/core/schema-tree/TreeNodeIndex.ts
545
698
  var TreeNodeIndex = class {
546
- nodeIndex = /* @__PURE__ */ new Map();
547
- pathIndex = /* @__PURE__ */ new Map();
699
+ nodeIndex = observable.map();
700
+ pathIndex = observable.map();
701
+ constructor() {
702
+ makeAutoObservable(this, {
703
+ nodeIndex: false,
704
+ pathIndex: false
705
+ });
706
+ }
548
707
  rebuild(rootNode) {
549
708
  this.nodeIndex.clear();
550
709
  this.pathIndex.clear();
@@ -556,7 +715,7 @@ var TreeNodeIndex = class {
556
715
  getPath(id) {
557
716
  return this.pathIndex.get(id) ?? EMPTY_PATH;
558
717
  }
559
- countNodes() {
718
+ get nodeCount() {
560
719
  return this.nodeIndex.size;
561
720
  }
562
721
  nodeIds() {
@@ -583,6 +742,11 @@ var SchemaTreeImpl = class _SchemaTreeImpl {
583
742
  constructor(rootNode) {
584
743
  this._rootNode = rootNode;
585
744
  this.index.rebuild(rootNode);
745
+ makeAutoObservable(this, {
746
+ index: false,
747
+ _replacements: false,
748
+ _rootNode: "observable.ref"
749
+ });
586
750
  }
587
751
  root() {
588
752
  return this._rootNode;
@@ -614,10 +778,11 @@ var SchemaTreeImpl = class _SchemaTreeImpl {
614
778
  return this.index.nodeIds();
615
779
  }
616
780
  countNodes() {
617
- return this.index.countNodes();
781
+ return this.index.nodeCount;
618
782
  }
619
783
  clone() {
620
- const cloned = new _SchemaTreeImpl(this._rootNode.clone());
784
+ const clonedRoot = this._rootNode.clone();
785
+ const cloned = new _SchemaTreeImpl(clonedRoot);
621
786
  for (const [oldId, newId] of this._replacements) {
622
787
  cloned._replacements.set(oldId, newId);
623
788
  }
@@ -775,16 +940,6 @@ var NodePathIndex = class {
775
940
  }
776
941
  };
777
942
 
778
- // src/model/schema-formula/core/FormulaError.ts
779
- var FormulaError = class extends Error {
780
- constructor(message, nodeId, details) {
781
- super(message);
782
- this.nodeId = nodeId;
783
- this.details = details;
784
- this.name = "FormulaError";
785
- }
786
- };
787
-
788
943
  // src/model/schema-formula/serialization/FormulaPathBuilder.ts
789
944
  var FormulaPathBuilder = class {
790
945
  buildWithArrayNotation(fromPath, toPath) {
@@ -853,6 +1008,16 @@ var FormulaPathBuilder = class {
853
1008
  }
854
1009
  };
855
1010
 
1011
+ // src/model/schema-formula/core/FormulaError.ts
1012
+ var FormulaError = class extends Error {
1013
+ constructor(message, nodeId, details) {
1014
+ super(message);
1015
+ this.nodeId = nodeId;
1016
+ this.details = details;
1017
+ this.name = "FormulaError";
1018
+ }
1019
+ };
1020
+
856
1021
  // src/model/schema-formula/serialization/FormulaSerializer.ts
857
1022
  var FormulaSerializer = class _FormulaSerializer {
858
1023
  constructor(tree, formulaNodeId, formula) {
@@ -1053,49 +1218,43 @@ var ChangeCollector = class {
1053
1218
  collectFromCurrentTree(changes) {
1054
1219
  for (const nodeId of this.currentTree.nodeIds()) {
1055
1220
  const currentNode = this.currentTree.nodeById(nodeId);
1056
- if (this.index.isReplacement(nodeId)) {
1057
- const originalId = this.index.getOriginalNodeId(nodeId);
1058
- if (originalId) {
1059
- const baseNode2 = this.baseTree.nodeById(originalId);
1060
- changes.push({
1061
- type: "modified",
1062
- baseNode: baseNode2,
1063
- currentNode
1064
- });
1065
- }
1066
- continue;
1067
- }
1068
- const basePath = this.index.getBasePath(nodeId);
1069
- if (!basePath) {
1070
- changes.push({
1071
- type: "added",
1072
- baseNode: null,
1073
- currentNode
1074
- });
1075
- continue;
1076
- }
1077
- const currentPath = this.currentTree.pathOf(nodeId);
1078
- const baseNode = this.baseTree.nodeById(nodeId);
1079
- if (!basePath.equals(currentPath)) {
1080
- changes.push({
1081
- type: "moved",
1082
- baseNode,
1083
- currentNode
1084
- });
1085
- if (!areNodesContentEqual(currentNode, baseNode, this.context)) {
1086
- changes.push({
1087
- type: "modified",
1088
- baseNode,
1089
- currentNode
1090
- });
1091
- }
1092
- } else if (!areNodesEqual(currentNode, baseNode, this.context)) {
1093
- changes.push({
1094
- type: "modified",
1095
- baseNode,
1096
- currentNode
1097
- });
1098
- }
1221
+ this.collectNodeChange(changes, nodeId, currentNode);
1222
+ }
1223
+ }
1224
+ collectNodeChange(changes, nodeId, currentNode) {
1225
+ if (this.index.isReplacement(nodeId)) {
1226
+ this.collectReplacementChange(changes, nodeId, currentNode);
1227
+ return;
1228
+ }
1229
+ const basePath = this.index.getBasePath(nodeId);
1230
+ if (!basePath) {
1231
+ changes.push({ type: "added", baseNode: null, currentNode });
1232
+ return;
1233
+ }
1234
+ const currentPath = this.currentTree.pathOf(nodeId);
1235
+ const baseNode = this.baseTree.nodeById(nodeId);
1236
+ if (!basePath.equals(currentPath)) {
1237
+ this.collectMovedChange(changes, baseNode, currentNode);
1238
+ } else if (!areNodesEqual(currentNode, baseNode, this.context)) {
1239
+ changes.push({ type: "modified", baseNode, currentNode });
1240
+ }
1241
+ }
1242
+ collectReplacementChange(changes, nodeId, currentNode) {
1243
+ const originalId = this.index.getOriginalNodeId(nodeId);
1244
+ if (!originalId) {
1245
+ return;
1246
+ }
1247
+ const baseNode = this.baseTree.nodeById(originalId);
1248
+ if (baseNode.isNull()) {
1249
+ changes.push({ type: "added", baseNode: null, currentNode });
1250
+ } else {
1251
+ changes.push({ type: "modified", baseNode, currentNode });
1252
+ }
1253
+ }
1254
+ collectMovedChange(changes, baseNode, currentNode) {
1255
+ changes.push({ type: "moved", baseNode, currentNode });
1256
+ if (!areNodesContentEqual(currentNode, baseNode, this.context)) {
1257
+ changes.push({ type: "modified", baseNode, currentNode });
1099
1258
  }
1100
1259
  }
1101
1260
  collectRemovedNodes(changes) {
@@ -1106,11 +1265,7 @@ var ChangeCollector = class {
1106
1265
  const currentNode = this.currentTree.nodeById(nodeId);
1107
1266
  if (currentNode.isNull()) {
1108
1267
  const baseNode = this.baseTree.nodeById(nodeId);
1109
- changes.push({
1110
- type: "removed",
1111
- baseNode,
1112
- currentNode: null
1113
- });
1268
+ changes.push({ type: "removed", baseNode, currentNode: null });
1114
1269
  }
1115
1270
  }
1116
1271
  }
@@ -1363,8 +1518,6 @@ var FormulaPath = class {
1363
1518
  return result;
1364
1519
  }
1365
1520
  };
1366
-
1367
- // src/model/schema-formula/parsing/ParsedFormula.ts
1368
1521
  var ParsedFormula = class {
1369
1522
  _expression;
1370
1523
  astNode;
@@ -1505,6 +1658,73 @@ var FormulaDependencyIndex = class {
1505
1658
  }
1506
1659
  };
1507
1660
 
1661
+ // src/model/schema-formula/changes/FormulaChangeDetector.ts
1662
+ var FormulaChangeDetector = class {
1663
+ constructor(index, currentTree, baseTree) {
1664
+ this.index = index;
1665
+ this.currentTree = currentTree;
1666
+ this.baseTree = baseTree;
1667
+ }
1668
+ detectIndirectChanges(changedNodeIds) {
1669
+ const result = [];
1670
+ const visited = /* @__PURE__ */ new Set();
1671
+ for (const changedId of changedNodeIds) {
1672
+ this.collectDependentChanges(changedId, result, visited, changedNodeIds);
1673
+ }
1674
+ return result;
1675
+ }
1676
+ collectDependentChanges(nodeId, result, visited, directlyChanged) {
1677
+ const dependents = this.index.getDependents(nodeId);
1678
+ for (const dependentId of dependents) {
1679
+ if (visited.has(dependentId)) {
1680
+ continue;
1681
+ }
1682
+ visited.add(dependentId);
1683
+ if (directlyChanged.has(dependentId)) {
1684
+ continue;
1685
+ }
1686
+ const change = this.detectFormulaChange(dependentId);
1687
+ if (change) {
1688
+ result.push(change);
1689
+ }
1690
+ this.collectDependentChanges(dependentId, result, visited, directlyChanged);
1691
+ }
1692
+ }
1693
+ detectFormulaChange(nodeId) {
1694
+ const currentNode = this.currentTree.nodeById(nodeId);
1695
+ const baseNode = this.baseTree.nodeById(nodeId);
1696
+ if (currentNode.isNull() || baseNode.isNull()) {
1697
+ return null;
1698
+ }
1699
+ const currentFormula = currentNode.formula();
1700
+ const baseFormula = baseNode.formula();
1701
+ if (!currentFormula || !baseFormula) {
1702
+ return null;
1703
+ }
1704
+ const fromExpression = this.getSerializedExpression(baseFormula, this.baseTree, nodeId);
1705
+ const toExpression = this.getSerializedExpression(currentFormula, this.currentTree, nodeId);
1706
+ if (fromExpression === null || toExpression === null) {
1707
+ return null;
1708
+ }
1709
+ if (fromExpression === toExpression) {
1710
+ return null;
1711
+ }
1712
+ return {
1713
+ nodeId,
1714
+ fromExpression,
1715
+ toExpression
1716
+ };
1717
+ }
1718
+ getSerializedExpression(formula, tree, nodeId) {
1719
+ try {
1720
+ const xFormula = FormulaSerializer.toXFormula(tree, nodeId, formula);
1721
+ return xFormula.expression;
1722
+ } catch {
1723
+ return null;
1724
+ }
1725
+ }
1726
+ };
1727
+
1508
1728
  // src/core/schema-serializer/SchemaSerializer.ts
1509
1729
  var SchemaSerializer = class {
1510
1730
  tree = null;
@@ -1598,6 +1818,10 @@ var SchemaSerializer = class {
1598
1818
  if (foreignKey) {
1599
1819
  result.foreignKey = foreignKey;
1600
1820
  }
1821
+ const contentMediaType = node.contentMediaType();
1822
+ if (contentMediaType && this.isValidContentMediaType(contentMediaType)) {
1823
+ result.contentMediaType = contentMediaType;
1824
+ }
1601
1825
  const formula = node.formula();
1602
1826
  if (formula) {
1603
1827
  result.readOnly = true;
@@ -1653,6 +1877,17 @@ var SchemaSerializer = class {
1653
1877
  shouldExclude(node) {
1654
1878
  return this.excludeNodeIds.has(node.id());
1655
1879
  }
1880
+ isValidContentMediaType(value) {
1881
+ const validTypes = [
1882
+ "text/plain",
1883
+ "text/markdown",
1884
+ "text/html",
1885
+ "application/json",
1886
+ "application/schema+json",
1887
+ "application/yaml"
1888
+ ];
1889
+ return validTypes.includes(value);
1890
+ }
1656
1891
  };
1657
1892
 
1658
1893
  // src/core/schema-patch/PatchGenerator.ts
@@ -1676,7 +1911,7 @@ var PatchGenerator = class {
1676
1911
  const childChangePaths = /* @__PURE__ */ new Set([
1677
1912
  ...addPatches.map((p) => p.path),
1678
1913
  ...removePatches.map((p) => p.path),
1679
- ...movePatches.flatMap((p) => [p.path, p.from ?? ""]).filter(Boolean)
1914
+ ...movePatches.flatMap((p) => [p.path, p.from]).filter(Boolean)
1680
1915
  ]);
1681
1916
  const replacePatches = this.generateReplacePatches(
1682
1917
  coalesced.modified,
@@ -1954,27 +2189,36 @@ var PatchEnricher = class {
1954
2189
  enrichAddPatch(patch, fieldName) {
1955
2190
  const currentNode = this.getNodeAtPath(this.currentTree, patch.path);
1956
2191
  if (!currentNode) {
1957
- return { patch, fieldName };
2192
+ return { patch, fieldName, metadataChanges: [] };
1958
2193
  }
2194
+ const metadata = this.computeAddMetadata(currentNode);
1959
2195
  return {
1960
2196
  patch,
1961
2197
  fieldName,
1962
- ...this.computeAddMetadata(currentNode)
2198
+ metadataChanges: this.computeMetadataChanges(metadata),
2199
+ ...metadata
1963
2200
  };
1964
2201
  }
1965
2202
  enrichRemovePatch(patch, fieldName) {
1966
- return { patch, fieldName };
2203
+ return { patch, fieldName, metadataChanges: [] };
1967
2204
  }
1968
2205
  enrichMovePatch(patch, fieldName) {
1969
- const fromPath = patch.from || "";
2206
+ const fromPath = patch.from;
1970
2207
  const isRename = this.isRenameMove(fromPath, patch.path);
2208
+ const movesIntoArray = this.movesIntoArrayBoundary(fromPath, patch.path);
1971
2209
  const baseNode = this.getNodeAtPath(this.baseTree, fromPath);
1972
2210
  const currentNode = this.getNodeAtPath(this.currentTree, patch.path);
1973
2211
  const formulaChange = this.computeFormulaChange(baseNode, currentNode);
2212
+ const metadataChanges = [];
2213
+ if (formulaChange) {
2214
+ metadataChanges.push("formula");
2215
+ }
1974
2216
  return {
1975
2217
  patch,
1976
2218
  fieldName,
2219
+ metadataChanges,
1977
2220
  isRename: isRename || void 0,
2221
+ movesIntoArray: movesIntoArray || void 0,
1978
2222
  formulaChange
1979
2223
  };
1980
2224
  }
@@ -1982,15 +2226,31 @@ var PatchEnricher = class {
1982
2226
  const baseNode = this.getNodeAtPath(this.baseTree, patch.path);
1983
2227
  const currentNode = this.getNodeAtPath(this.currentTree, patch.path);
1984
2228
  const isArrayMetadataPatch = baseNode?.isArray() && currentNode?.isArray();
2229
+ const formulaChange = this.computeFormulaChange(baseNode, currentNode);
2230
+ const defaultChange = isArrayMetadataPatch ? void 0 : this.computeDefaultChange(baseNode, currentNode);
2231
+ const descriptionChange = this.computeDescriptionChange(baseNode, currentNode);
2232
+ const deprecatedChange = this.computeDeprecatedChange(baseNode, currentNode);
2233
+ const foreignKeyChange = this.computeForeignKeyChange(baseNode, currentNode);
2234
+ const contentMediaTypeChange = this.computeContentMediaTypeChange(baseNode, currentNode);
2235
+ const metadataChanges = this.computeMetadataChanges({
2236
+ formulaChange,
2237
+ defaultChange,
2238
+ descriptionChange,
2239
+ deprecatedChange,
2240
+ foreignKeyChange,
2241
+ contentMediaTypeChange
2242
+ });
1985
2243
  return {
1986
2244
  patch,
1987
2245
  fieldName,
2246
+ metadataChanges,
1988
2247
  typeChange: this.computeTypeChange(baseNode, currentNode, isArrayMetadataPatch),
1989
- formulaChange: this.computeFormulaChange(baseNode, currentNode),
1990
- defaultChange: isArrayMetadataPatch ? void 0 : this.computeDefaultChange(baseNode, currentNode),
1991
- descriptionChange: this.computeDescriptionChange(baseNode, currentNode),
1992
- deprecatedChange: this.computeDeprecatedChange(baseNode, currentNode),
1993
- foreignKeyChange: this.computeForeignKeyChange(baseNode, currentNode)
2248
+ formulaChange,
2249
+ defaultChange,
2250
+ descriptionChange,
2251
+ deprecatedChange,
2252
+ foreignKeyChange,
2253
+ contentMediaTypeChange
1994
2254
  };
1995
2255
  }
1996
2256
  computeAddMetadata(node) {
@@ -2031,6 +2291,13 @@ var PatchEnricher = class {
2031
2291
  toForeignKey: foreignKey
2032
2292
  };
2033
2293
  }
2294
+ const contentMediaType = node.contentMediaType();
2295
+ if (contentMediaType) {
2296
+ result.contentMediaTypeChange = {
2297
+ fromContentMediaType: void 0,
2298
+ toContentMediaType: contentMediaType
2299
+ };
2300
+ }
2034
2301
  return result;
2035
2302
  }
2036
2303
  computeTypeChange(baseNode, currentNode, ignoreItems) {
@@ -2110,6 +2377,39 @@ var PatchEnricher = class {
2110
2377
  }
2111
2378
  return void 0;
2112
2379
  }
2380
+ computeContentMediaTypeChange(baseNode, currentNode) {
2381
+ const baseMediaType = baseNode?.contentMediaType();
2382
+ const currentMediaType = currentNode?.contentMediaType();
2383
+ if (baseMediaType !== currentMediaType) {
2384
+ return {
2385
+ fromContentMediaType: baseMediaType,
2386
+ toContentMediaType: currentMediaType
2387
+ };
2388
+ }
2389
+ return void 0;
2390
+ }
2391
+ computeMetadataChanges(changes) {
2392
+ const result = [];
2393
+ if (changes.formulaChange) {
2394
+ result.push("formula");
2395
+ }
2396
+ if (changes.defaultChange) {
2397
+ result.push("default");
2398
+ }
2399
+ if (changes.descriptionChange) {
2400
+ result.push("description");
2401
+ }
2402
+ if (changes.deprecatedChange) {
2403
+ result.push("deprecated");
2404
+ }
2405
+ if (changes.foreignKeyChange) {
2406
+ result.push("foreignKey");
2407
+ }
2408
+ if (changes.contentMediaTypeChange) {
2409
+ result.push("contentMediaType");
2410
+ }
2411
+ return result;
2412
+ }
2113
2413
  getNodeType(node) {
2114
2414
  if (node.isArray()) {
2115
2415
  const items = node.items();
@@ -2133,6 +2433,20 @@ var PatchEnricher = class {
2133
2433
  return false;
2134
2434
  }
2135
2435
  }
2436
+ movesIntoArrayBoundary(fromPointer, toPointer) {
2437
+ try {
2438
+ const fromPath = jsonPointerToPath(fromPointer);
2439
+ const toPath = jsonPointerToPath(toPointer);
2440
+ const fromArrayDepth = this.countArrayDepth(fromPath);
2441
+ const toArrayDepth = this.countArrayDepth(toPath);
2442
+ return toArrayDepth > fromArrayDepth;
2443
+ } catch {
2444
+ return false;
2445
+ }
2446
+ }
2447
+ countArrayDepth(path) {
2448
+ return path.segments().filter((seg) => seg.isItems()).length;
2449
+ }
2136
2450
  getNodeAtPath(tree, jsonPointer) {
2137
2451
  try {
2138
2452
  const path = jsonPointerToPath(jsonPointer);
@@ -2491,6 +2805,12 @@ function collectValidationErrors(node, errors) {
2491
2805
  if (node.isNull()) {
2492
2806
  return;
2493
2807
  }
2808
+ const foreignKey = node.foreignKey();
2809
+ if (foreignKey === "") {
2810
+ errors.push(
2811
+ createError(node.id(), "empty-foreign-key", "Foreign key table reference cannot be empty")
2812
+ );
2813
+ }
2494
2814
  if (node.isObject()) {
2495
2815
  const children = node.properties();
2496
2816
  const nameSet = /* @__PURE__ */ new Set();
@@ -2575,7 +2895,11 @@ exports.EMPTY_PATH = EMPTY_PATH;
2575
2895
  exports.EnumValidator = EnumValidator;
2576
2896
  exports.FIELD_NAME_ERROR_MESSAGE = FIELD_NAME_ERROR_MESSAGE;
2577
2897
  exports.ForeignKeyValidator = ForeignKeyValidator;
2898
+ exports.FormulaChangeDetector = FormulaChangeDetector;
2578
2899
  exports.FormulaDependencyIndex = FormulaDependencyIndex;
2900
+ exports.FormulaPath = FormulaPath;
2901
+ exports.FormulaPathBuilder = FormulaPathBuilder;
2902
+ exports.FormulaSerializer = FormulaSerializer;
2579
2903
  exports.ItemsSegment = ItemsSegment;
2580
2904
  exports.MaxLengthValidator = MaxLengthValidator;
2581
2905
  exports.MaximumValidator = MaximumValidator;
@@ -2590,6 +2914,7 @@ exports.PatchGenerator = PatchGenerator;
2590
2914
  exports.PatternValidator = PatternValidator;
2591
2915
  exports.PropertySegment = PropertySegment;
2592
2916
  exports.RequiredValidator = RequiredValidator;
2917
+ exports.ResolvedDependency = ResolvedDependency;
2593
2918
  exports.SchemaDiff = SchemaDiff;
2594
2919
  exports.SchemaPropertyRule = SchemaPropertyRule;
2595
2920
  exports.SchemaSerializer = SchemaSerializer;
@@ -2604,6 +2929,7 @@ exports.collectChanges = collectChanges;
2604
2929
  exports.createArrayNode = createArrayNode;
2605
2930
  exports.createBooleanNode = createBooleanNode;
2606
2931
  exports.createDefaultValidatorRegistry = createDefaultValidatorRegistry;
2932
+ exports.createMobxProvider = createMobxProvider;
2607
2933
  exports.createNumberNode = createNumberNode;
2608
2934
  exports.createObjectNode = createObjectNode;
2609
2935
  exports.createPath = createPath;
@@ -2615,7 +2941,14 @@ exports.isValidFieldName = isValidFieldName;
2615
2941
  exports.jsonPointerToPath = jsonPointerToPath;
2616
2942
  exports.jsonPointerToSegments = jsonPointerToSegments;
2617
2943
  exports.jsonPointerToSimplePath = jsonPointerToSimplePath;
2944
+ exports.makeAutoObservable = makeAutoObservable;
2945
+ exports.makeObservable = makeObservable;
2946
+ exports.observable = observable;
2947
+ exports.reaction = reaction;
2948
+ exports.resetReactivityProvider = resetReactivityProvider;
2949
+ exports.runInAction = runInAction;
2950
+ exports.setReactivityProvider = setReactivityProvider;
2618
2951
  exports.validateFormulas = validateFormulas;
2619
2952
  exports.validateSchema = validateSchema;
2620
- //# sourceMappingURL=chunk-IWRV6QAD.cjs.map
2621
- //# sourceMappingURL=chunk-IWRV6QAD.cjs.map
2953
+ //# sourceMappingURL=chunk-44ZEZUWU.cjs.map
2954
+ //# sourceMappingURL=chunk-44ZEZUWU.cjs.map