@revisium/schema-toolkit 0.16.1 → 0.16.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.
Files changed (83) hide show
  1. package/dist/{chunk-HY4VE7H2.js → chunk-55AMH44G.js} +3 -3
  2. package/dist/chunk-55AMH44G.js.map +1 -0
  3. package/dist/{chunk-KQWWRWGB.cjs → chunk-62TO7J76.cjs} +216 -279
  4. package/dist/chunk-62TO7J76.cjs.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-MLNKM67U.cjs +4 -0
  12. package/dist/chunk-MLNKM67U.cjs.map +1 -0
  13. package/dist/{chunk-CYTPQYVM.js → chunk-MPF6VCB5.js} +2 -2
  14. package/dist/chunk-MPF6VCB5.js.map +1 -0
  15. package/dist/{chunk-S7GEDTSL.js → chunk-PGR2S2BR.js} +411 -88
  16. package/dist/chunk-PGR2S2BR.js.map +1 -0
  17. package/dist/{chunk-2NRQPOQY.js → chunk-QEV4Q4TR.js} +3 -3
  18. package/dist/{chunk-2NRQPOQY.js.map → chunk-QEV4Q4TR.js.map} +1 -1
  19. package/dist/{chunk-KTCH6INZ.js → chunk-R66AFTGQ.js} +200 -263
  20. package/dist/chunk-R66AFTGQ.js.map +1 -0
  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-IWRV6QAD.cjs → chunk-VGB4YCGF.cjs} +422 -86
  24. package/dist/chunk-VGB4YCGF.cjs.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 +108 -40
  55. package/dist/model/index.d.ts +108 -40
  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-DmsYGLDX.d.ts → types-BUiNI0oL.d.cts} +18 -23
  68. package/dist/{types-BWeurwlH.d.cts → types-bBnnfNxC.d.ts} +18 -23
  69. package/package.json +3 -1
  70. package/dist/FormulaValidator-Bl6lav9r.d.ts +0 -10
  71. package/dist/FormulaValidator-DTT8T1OM.d.cts +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-KQWWRWGB.cjs.map +0 -1
  81. package/dist/chunk-KTCH6INZ.js.map +0 -1
  82. package/dist/chunk-S7GEDTSL.js.map +0 -1
  83. package/dist/chunk-TMWPWGUN.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { parseFormula, replaceDependencies, serializeAst } from '@revisium/formula';
1
+ import { replaceDependencies, serializeAst, parseFormula } from '@revisium/formula';
2
2
 
3
3
  // src/core/schema-node/types.ts
4
4
  var EMPTY_METADATA = Object.freeze({});
@@ -79,9 +79,104 @@ var NullNodeImpl = class {
79
79
  }
80
80
  setForeignKey(_key) {
81
81
  }
82
+ contentMediaType() {
83
+ return void 0;
84
+ }
85
+ setContentMediaType(_mediaType) {
86
+ }
82
87
  };
83
88
  var NULL_NODE = new NullNodeImpl();
84
89
 
90
+ // src/core/reactivity/provider.ts
91
+ var noopProvider = {
92
+ makeObservable: (target) => target,
93
+ makeAutoObservable: (target) => target,
94
+ isObservable: () => false,
95
+ observable: {
96
+ map: () => /* @__PURE__ */ new Map(),
97
+ array: () => []
98
+ },
99
+ runInAction: (fn) => fn(),
100
+ reaction: () => () => {
101
+ }
102
+ };
103
+ var currentProvider = noopProvider;
104
+ function setReactivityProvider(provider) {
105
+ currentProvider = provider;
106
+ }
107
+ function getReactivityProvider() {
108
+ return currentProvider;
109
+ }
110
+ function resetReactivityProvider() {
111
+ currentProvider = noopProvider;
112
+ }
113
+
114
+ // src/core/reactivity/api.ts
115
+ function makeObservable(target, annotations) {
116
+ return getReactivityProvider().makeObservable(target, annotations);
117
+ }
118
+ function makeAutoObservable(target, overrides) {
119
+ return getReactivityProvider().makeAutoObservable(target, overrides ?? {});
120
+ }
121
+ var observable = {
122
+ map() {
123
+ return getReactivityProvider().observable.map();
124
+ },
125
+ array() {
126
+ return getReactivityProvider().observable.array();
127
+ }
128
+ };
129
+ function runInAction(fn) {
130
+ return getReactivityProvider().runInAction(fn);
131
+ }
132
+ function reaction(expression, effect) {
133
+ return getReactivityProvider().reaction(expression, effect);
134
+ }
135
+
136
+ // src/core/reactivity/mobx-provider.ts
137
+ function convertAnnotations(mobx, annotations) {
138
+ const result = {};
139
+ for (const [key, value] of Object.entries(annotations)) {
140
+ if (typeof value === "string") {
141
+ switch (value) {
142
+ case "observable":
143
+ result[key] = mobx.observable;
144
+ break;
145
+ case "observable.ref":
146
+ result[key] = mobx.observable.ref;
147
+ break;
148
+ case "observable.shallow":
149
+ result[key] = mobx.observable.shallow;
150
+ break;
151
+ case "action":
152
+ result[key] = mobx.action;
153
+ break;
154
+ case "computed":
155
+ result[key] = mobx.computed;
156
+ break;
157
+ default:
158
+ result[key] = value;
159
+ }
160
+ } else {
161
+ result[key] = value;
162
+ }
163
+ }
164
+ return result;
165
+ }
166
+ function createMobxProvider(mobx) {
167
+ return {
168
+ makeObservable: (target, annotations) => mobx.makeObservable(target, convertAnnotations(mobx, annotations)),
169
+ makeAutoObservable: (target, overrides) => mobx.makeAutoObservable(target, overrides ? convertAnnotations(mobx, overrides) : {}),
170
+ isObservable: mobx.isObservable,
171
+ observable: {
172
+ map: () => mobx.observable.map(),
173
+ array: () => mobx.observable.array()
174
+ },
175
+ runInAction: mobx.runInAction,
176
+ reaction: mobx.reaction
177
+ };
178
+ }
179
+
85
180
  // src/core/schema-node/BaseNode.ts
86
181
  var BaseNode = class {
87
182
  constructor(_id, name, metadata = EMPTY_METADATA) {
@@ -91,6 +186,14 @@ var BaseNode = class {
91
186
  }
92
187
  _name;
93
188
  _metadata;
189
+ initBaseObservable() {
190
+ makeObservable(this, {
191
+ _name: "observable",
192
+ _metadata: "observable.ref",
193
+ setName: "action",
194
+ setMetadata: "action"
195
+ });
196
+ }
94
197
  id() {
95
198
  return this._id;
96
199
  }
@@ -139,6 +242,9 @@ var BaseNode = class {
139
242
  foreignKey() {
140
243
  return void 0;
141
244
  }
245
+ contentMediaType() {
246
+ return void 0;
247
+ }
142
248
  setName(name) {
143
249
  this._name = name;
144
250
  }
@@ -161,6 +267,8 @@ var BaseNode = class {
161
267
  }
162
268
  setForeignKey(_key) {
163
269
  }
270
+ setContentMediaType(_mediaType) {
271
+ }
164
272
  };
165
273
 
166
274
  // src/core/schema-node/ObjectNode.ts
@@ -169,6 +277,13 @@ var ObjectNode = class _ObjectNode extends BaseNode {
169
277
  constructor(id, name, children = [], metadata = EMPTY_METADATA) {
170
278
  super(id, name, metadata);
171
279
  this._children = [...children];
280
+ this.initBaseObservable();
281
+ makeObservable(this, {
282
+ _children: "observable.shallow",
283
+ addChild: "action",
284
+ removeChild: "action",
285
+ replaceChild: "action"
286
+ });
172
287
  }
173
288
  nodeType() {
174
289
  return "object";
@@ -220,6 +335,11 @@ var ArrayNode = class _ArrayNode extends BaseNode {
220
335
  constructor(id, name, items, metadata = EMPTY_METADATA) {
221
336
  super(id, name, metadata);
222
337
  this._items = items;
338
+ this.initBaseObservable();
339
+ makeObservable(this, {
340
+ _items: "observable.ref",
341
+ setItems: "action"
342
+ });
223
343
  }
224
344
  nodeType() {
225
345
  return "array";
@@ -260,6 +380,20 @@ var PrimitiveNode = class extends BaseNode {
260
380
  this._foreignKey = options.foreignKey;
261
381
  this._formula = options.formula;
262
382
  }
383
+ initPrimitiveObservable() {
384
+ makeObservable(this, {
385
+ _name: "observable",
386
+ _metadata: "observable.ref",
387
+ _formula: "observable.ref",
388
+ _defaultValue: "observable",
389
+ _foreignKey: "observable",
390
+ setName: "action",
391
+ setMetadata: "action",
392
+ setFormula: "action",
393
+ setDefaultValue: "action",
394
+ setForeignKey: "action"
395
+ });
396
+ }
263
397
  isPrimitive() {
264
398
  return true;
265
399
  }
@@ -288,12 +422,25 @@ var PrimitiveNode = class extends BaseNode {
288
422
 
289
423
  // src/core/schema-node/StringNode.ts
290
424
  var StringNode = class _StringNode extends PrimitiveNode {
425
+ _contentMediaType;
291
426
  constructor(id, name, options = {}) {
292
427
  super(id, name, options);
428
+ this._contentMediaType = options.contentMediaType;
429
+ this.initPrimitiveObservable();
430
+ makeObservable(this, {
431
+ _contentMediaType: "observable",
432
+ setContentMediaType: "action"
433
+ });
293
434
  }
294
435
  nodeType() {
295
436
  return "string";
296
437
  }
438
+ contentMediaType() {
439
+ return this._contentMediaType;
440
+ }
441
+ setContentMediaType(mediaType) {
442
+ this._contentMediaType = mediaType;
443
+ }
297
444
  clone() {
298
445
  return new _StringNode(this.id(), this.name(), this.cloneOptions());
299
446
  }
@@ -302,7 +449,8 @@ var StringNode = class _StringNode extends PrimitiveNode {
302
449
  defaultValue: this._defaultValue,
303
450
  foreignKey: this._foreignKey,
304
451
  formula: this._formula,
305
- metadata: this._metadata
452
+ metadata: this._metadata,
453
+ contentMediaType: this._contentMediaType
306
454
  };
307
455
  }
308
456
  };
@@ -314,6 +462,7 @@ function createStringNode(id, name, options = {}) {
314
462
  var NumberNode = class _NumberNode extends PrimitiveNode {
315
463
  constructor(id, name, options = {}) {
316
464
  super(id, name, options);
465
+ this.initPrimitiveObservable();
317
466
  }
318
467
  nodeType() {
319
468
  return "number";
@@ -337,6 +486,7 @@ function createNumberNode(id, name, options = {}) {
337
486
  var BooleanNode = class _BooleanNode extends PrimitiveNode {
338
487
  constructor(id, name, options = {}) {
339
488
  super(id, name, options);
489
+ this.initPrimitiveObservable();
340
490
  }
341
491
  nodeType() {
342
492
  return "boolean";
@@ -365,6 +515,7 @@ var RefNode = class _RefNode extends BaseNode {
365
515
  throw new Error("RefNode requires a non-empty ref");
366
516
  }
367
517
  this._ref = ref;
518
+ this.initBaseObservable();
368
519
  }
369
520
  nodeType() {
370
521
  return "ref";
@@ -509,23 +660,25 @@ function jsonPointerToSegments(pointer) {
509
660
  if (pointer === "" || pointer === "/") {
510
661
  return [];
511
662
  }
512
- const parts = pointer.split("/").filter(Boolean);
663
+ const parts = pointer.startsWith("/") ? pointer.slice(1).split("/") : pointer.split("/");
513
664
  const segments = [];
514
665
  let i = 0;
515
666
  while (i < parts.length) {
516
667
  const part = parts[i];
517
668
  if (part === "properties") {
518
- const name = parts[i + 1];
519
- if (name === void 0 || name === "") {
520
- throw new Error(
521
- `Invalid path: 'properties' segment requires a name in path ${pointer}`
522
- );
669
+ const hasNextPart = i + 1 < parts.length;
670
+ if (hasNextPart) {
671
+ const name = parts[i + 1] ?? "";
672
+ segments.push(new PropertySegment(name));
673
+ i += 2;
674
+ } else {
675
+ i += 1;
523
676
  }
524
- segments.push(new PropertySegment(name));
525
- i += 2;
526
677
  } else if (part === "items") {
527
678
  segments.push(new ItemsSegment());
528
679
  i += 1;
680
+ } else if (part === "") {
681
+ i += 1;
529
682
  } else {
530
683
  throw new Error(`Invalid path segment: ${part} in path ${pointer}`);
531
684
  }
@@ -541,8 +694,14 @@ function jsonPointerToSimplePath(pointer) {
541
694
 
542
695
  // src/core/schema-tree/TreeNodeIndex.ts
543
696
  var TreeNodeIndex = class {
544
- nodeIndex = /* @__PURE__ */ new Map();
545
- pathIndex = /* @__PURE__ */ new Map();
697
+ nodeIndex = observable.map();
698
+ pathIndex = observable.map();
699
+ constructor() {
700
+ makeAutoObservable(this, {
701
+ nodeIndex: false,
702
+ pathIndex: false
703
+ });
704
+ }
546
705
  rebuild(rootNode) {
547
706
  this.nodeIndex.clear();
548
707
  this.pathIndex.clear();
@@ -554,7 +713,7 @@ var TreeNodeIndex = class {
554
713
  getPath(id) {
555
714
  return this.pathIndex.get(id) ?? EMPTY_PATH;
556
715
  }
557
- countNodes() {
716
+ get nodeCount() {
558
717
  return this.nodeIndex.size;
559
718
  }
560
719
  nodeIds() {
@@ -581,6 +740,11 @@ var SchemaTreeImpl = class _SchemaTreeImpl {
581
740
  constructor(rootNode) {
582
741
  this._rootNode = rootNode;
583
742
  this.index.rebuild(rootNode);
743
+ makeAutoObservable(this, {
744
+ index: false,
745
+ _replacements: false,
746
+ _rootNode: "observable.ref"
747
+ });
584
748
  }
585
749
  root() {
586
750
  return this._rootNode;
@@ -612,10 +776,11 @@ var SchemaTreeImpl = class _SchemaTreeImpl {
612
776
  return this.index.nodeIds();
613
777
  }
614
778
  countNodes() {
615
- return this.index.countNodes();
779
+ return this.index.nodeCount;
616
780
  }
617
781
  clone() {
618
- const cloned = new _SchemaTreeImpl(this._rootNode.clone());
782
+ const clonedRoot = this._rootNode.clone();
783
+ const cloned = new _SchemaTreeImpl(clonedRoot);
619
784
  for (const [oldId, newId] of this._replacements) {
620
785
  cloned._replacements.set(oldId, newId);
621
786
  }
@@ -773,16 +938,6 @@ var NodePathIndex = class {
773
938
  }
774
939
  };
775
940
 
776
- // src/model/schema-formula/core/FormulaError.ts
777
- var FormulaError = class extends Error {
778
- constructor(message, nodeId, details) {
779
- super(message);
780
- this.nodeId = nodeId;
781
- this.details = details;
782
- this.name = "FormulaError";
783
- }
784
- };
785
-
786
941
  // src/model/schema-formula/serialization/FormulaPathBuilder.ts
787
942
  var FormulaPathBuilder = class {
788
943
  buildWithArrayNotation(fromPath, toPath) {
@@ -851,6 +1006,16 @@ var FormulaPathBuilder = class {
851
1006
  }
852
1007
  };
853
1008
 
1009
+ // src/model/schema-formula/core/FormulaError.ts
1010
+ var FormulaError = class extends Error {
1011
+ constructor(message, nodeId, details) {
1012
+ super(message);
1013
+ this.nodeId = nodeId;
1014
+ this.details = details;
1015
+ this.name = "FormulaError";
1016
+ }
1017
+ };
1018
+
854
1019
  // src/model/schema-formula/serialization/FormulaSerializer.ts
855
1020
  var FormulaSerializer = class _FormulaSerializer {
856
1021
  constructor(tree, formulaNodeId, formula) {
@@ -1051,49 +1216,43 @@ var ChangeCollector = class {
1051
1216
  collectFromCurrentTree(changes) {
1052
1217
  for (const nodeId of this.currentTree.nodeIds()) {
1053
1218
  const currentNode = this.currentTree.nodeById(nodeId);
1054
- if (this.index.isReplacement(nodeId)) {
1055
- const originalId = this.index.getOriginalNodeId(nodeId);
1056
- if (originalId) {
1057
- const baseNode2 = this.baseTree.nodeById(originalId);
1058
- changes.push({
1059
- type: "modified",
1060
- baseNode: baseNode2,
1061
- currentNode
1062
- });
1063
- }
1064
- continue;
1065
- }
1066
- const basePath = this.index.getBasePath(nodeId);
1067
- if (!basePath) {
1068
- changes.push({
1069
- type: "added",
1070
- baseNode: null,
1071
- currentNode
1072
- });
1073
- continue;
1074
- }
1075
- const currentPath = this.currentTree.pathOf(nodeId);
1076
- const baseNode = this.baseTree.nodeById(nodeId);
1077
- if (!basePath.equals(currentPath)) {
1078
- changes.push({
1079
- type: "moved",
1080
- baseNode,
1081
- currentNode
1082
- });
1083
- if (!areNodesContentEqual(currentNode, baseNode, this.context)) {
1084
- changes.push({
1085
- type: "modified",
1086
- baseNode,
1087
- currentNode
1088
- });
1089
- }
1090
- } else if (!areNodesEqual(currentNode, baseNode, this.context)) {
1091
- changes.push({
1092
- type: "modified",
1093
- baseNode,
1094
- currentNode
1095
- });
1096
- }
1219
+ this.collectNodeChange(changes, nodeId, currentNode);
1220
+ }
1221
+ }
1222
+ collectNodeChange(changes, nodeId, currentNode) {
1223
+ if (this.index.isReplacement(nodeId)) {
1224
+ this.collectReplacementChange(changes, nodeId, currentNode);
1225
+ return;
1226
+ }
1227
+ const basePath = this.index.getBasePath(nodeId);
1228
+ if (!basePath) {
1229
+ changes.push({ type: "added", baseNode: null, currentNode });
1230
+ return;
1231
+ }
1232
+ const currentPath = this.currentTree.pathOf(nodeId);
1233
+ const baseNode = this.baseTree.nodeById(nodeId);
1234
+ if (!basePath.equals(currentPath)) {
1235
+ this.collectMovedChange(changes, baseNode, currentNode);
1236
+ } else if (!areNodesEqual(currentNode, baseNode, this.context)) {
1237
+ changes.push({ type: "modified", baseNode, currentNode });
1238
+ }
1239
+ }
1240
+ collectReplacementChange(changes, nodeId, currentNode) {
1241
+ const originalId = this.index.getOriginalNodeId(nodeId);
1242
+ if (!originalId) {
1243
+ return;
1244
+ }
1245
+ const baseNode = this.baseTree.nodeById(originalId);
1246
+ if (baseNode.isNull()) {
1247
+ changes.push({ type: "added", baseNode: null, currentNode });
1248
+ } else {
1249
+ changes.push({ type: "modified", baseNode, currentNode });
1250
+ }
1251
+ }
1252
+ collectMovedChange(changes, baseNode, currentNode) {
1253
+ changes.push({ type: "moved", baseNode, currentNode });
1254
+ if (!areNodesContentEqual(currentNode, baseNode, this.context)) {
1255
+ changes.push({ type: "modified", baseNode, currentNode });
1097
1256
  }
1098
1257
  }
1099
1258
  collectRemovedNodes(changes) {
@@ -1104,11 +1263,7 @@ var ChangeCollector = class {
1104
1263
  const currentNode = this.currentTree.nodeById(nodeId);
1105
1264
  if (currentNode.isNull()) {
1106
1265
  const baseNode = this.baseTree.nodeById(nodeId);
1107
- changes.push({
1108
- type: "removed",
1109
- baseNode,
1110
- currentNode: null
1111
- });
1266
+ changes.push({ type: "removed", baseNode, currentNode: null });
1112
1267
  }
1113
1268
  }
1114
1269
  }
@@ -1192,6 +1347,9 @@ var ChangeCoalescer = class {
1192
1347
  continue;
1193
1348
  }
1194
1349
  }
1350
+ if (change.type === "moved" && other.type === "added") {
1351
+ continue;
1352
+ }
1195
1353
  const otherPath = this.getChangePath(other);
1196
1354
  if (path.isChildOf(otherPath)) {
1197
1355
  return true;
@@ -1361,8 +1519,6 @@ var FormulaPath = class {
1361
1519
  return result;
1362
1520
  }
1363
1521
  };
1364
-
1365
- // src/model/schema-formula/parsing/ParsedFormula.ts
1366
1522
  var ParsedFormula = class {
1367
1523
  _expression;
1368
1524
  astNode;
@@ -1503,6 +1659,73 @@ var FormulaDependencyIndex = class {
1503
1659
  }
1504
1660
  };
1505
1661
 
1662
+ // src/model/schema-formula/changes/FormulaChangeDetector.ts
1663
+ var FormulaChangeDetector = class {
1664
+ constructor(index, currentTree, baseTree) {
1665
+ this.index = index;
1666
+ this.currentTree = currentTree;
1667
+ this.baseTree = baseTree;
1668
+ }
1669
+ detectIndirectChanges(changedNodeIds) {
1670
+ const result = [];
1671
+ const visited = /* @__PURE__ */ new Set();
1672
+ for (const changedId of changedNodeIds) {
1673
+ this.collectDependentChanges(changedId, result, visited, changedNodeIds);
1674
+ }
1675
+ return result;
1676
+ }
1677
+ collectDependentChanges(nodeId, result, visited, directlyChanged) {
1678
+ const dependents = this.index.getDependents(nodeId);
1679
+ for (const dependentId of dependents) {
1680
+ if (visited.has(dependentId)) {
1681
+ continue;
1682
+ }
1683
+ visited.add(dependentId);
1684
+ if (directlyChanged.has(dependentId)) {
1685
+ continue;
1686
+ }
1687
+ const change = this.detectFormulaChange(dependentId);
1688
+ if (change) {
1689
+ result.push(change);
1690
+ }
1691
+ this.collectDependentChanges(dependentId, result, visited, directlyChanged);
1692
+ }
1693
+ }
1694
+ detectFormulaChange(nodeId) {
1695
+ const currentNode = this.currentTree.nodeById(nodeId);
1696
+ const baseNode = this.baseTree.nodeById(nodeId);
1697
+ if (currentNode.isNull() || baseNode.isNull()) {
1698
+ return null;
1699
+ }
1700
+ const currentFormula = currentNode.formula();
1701
+ const baseFormula = baseNode.formula();
1702
+ if (!currentFormula || !baseFormula) {
1703
+ return null;
1704
+ }
1705
+ const fromExpression = this.getSerializedExpression(baseFormula, this.baseTree, nodeId);
1706
+ const toExpression = this.getSerializedExpression(currentFormula, this.currentTree, nodeId);
1707
+ if (fromExpression === null || toExpression === null) {
1708
+ return null;
1709
+ }
1710
+ if (fromExpression === toExpression) {
1711
+ return null;
1712
+ }
1713
+ return {
1714
+ nodeId,
1715
+ fromExpression,
1716
+ toExpression
1717
+ };
1718
+ }
1719
+ getSerializedExpression(formula, tree, nodeId) {
1720
+ try {
1721
+ const xFormula = FormulaSerializer.toXFormula(tree, nodeId, formula);
1722
+ return xFormula.expression;
1723
+ } catch {
1724
+ return null;
1725
+ }
1726
+ }
1727
+ };
1728
+
1506
1729
  // src/core/schema-serializer/SchemaSerializer.ts
1507
1730
  var SchemaSerializer = class {
1508
1731
  tree = null;
@@ -1596,6 +1819,10 @@ var SchemaSerializer = class {
1596
1819
  if (foreignKey) {
1597
1820
  result.foreignKey = foreignKey;
1598
1821
  }
1822
+ const contentMediaType = node.contentMediaType();
1823
+ if (contentMediaType && this.isValidContentMediaType(contentMediaType)) {
1824
+ result.contentMediaType = contentMediaType;
1825
+ }
1599
1826
  const formula = node.formula();
1600
1827
  if (formula) {
1601
1828
  result.readOnly = true;
@@ -1651,6 +1878,17 @@ var SchemaSerializer = class {
1651
1878
  shouldExclude(node) {
1652
1879
  return this.excludeNodeIds.has(node.id());
1653
1880
  }
1881
+ isValidContentMediaType(value) {
1882
+ const validTypes = [
1883
+ "text/plain",
1884
+ "text/markdown",
1885
+ "text/html",
1886
+ "application/json",
1887
+ "application/schema+json",
1888
+ "application/yaml"
1889
+ ];
1890
+ return validTypes.includes(value);
1891
+ }
1654
1892
  };
1655
1893
 
1656
1894
  // src/core/schema-patch/PatchGenerator.ts
@@ -1674,7 +1912,7 @@ var PatchGenerator = class {
1674
1912
  const childChangePaths = /* @__PURE__ */ new Set([
1675
1913
  ...addPatches.map((p) => p.path),
1676
1914
  ...removePatches.map((p) => p.path),
1677
- ...movePatches.flatMap((p) => [p.path, p.from ?? ""]).filter(Boolean)
1915
+ ...movePatches.flatMap((p) => [p.path, p.from]).filter(Boolean)
1678
1916
  ]);
1679
1917
  const replacePatches = this.generateReplacePatches(
1680
1918
  coalesced.modified,
@@ -1952,27 +2190,36 @@ var PatchEnricher = class {
1952
2190
  enrichAddPatch(patch, fieldName) {
1953
2191
  const currentNode = this.getNodeAtPath(this.currentTree, patch.path);
1954
2192
  if (!currentNode) {
1955
- return { patch, fieldName };
2193
+ return { patch, fieldName, metadataChanges: [] };
1956
2194
  }
2195
+ const metadata = this.computeAddMetadata(currentNode);
1957
2196
  return {
1958
2197
  patch,
1959
2198
  fieldName,
1960
- ...this.computeAddMetadata(currentNode)
2199
+ metadataChanges: this.computeMetadataChanges(metadata),
2200
+ ...metadata
1961
2201
  };
1962
2202
  }
1963
2203
  enrichRemovePatch(patch, fieldName) {
1964
- return { patch, fieldName };
2204
+ return { patch, fieldName, metadataChanges: [] };
1965
2205
  }
1966
2206
  enrichMovePatch(patch, fieldName) {
1967
- const fromPath = patch.from || "";
2207
+ const fromPath = patch.from;
1968
2208
  const isRename = this.isRenameMove(fromPath, patch.path);
2209
+ const movesIntoArray = this.movesIntoArrayBoundary(fromPath, patch.path);
1969
2210
  const baseNode = this.getNodeAtPath(this.baseTree, fromPath);
1970
2211
  const currentNode = this.getNodeAtPath(this.currentTree, patch.path);
1971
2212
  const formulaChange = this.computeFormulaChange(baseNode, currentNode);
2213
+ const metadataChanges = [];
2214
+ if (formulaChange) {
2215
+ metadataChanges.push("formula");
2216
+ }
1972
2217
  return {
1973
2218
  patch,
1974
2219
  fieldName,
2220
+ metadataChanges,
1975
2221
  isRename: isRename || void 0,
2222
+ movesIntoArray: movesIntoArray || void 0,
1976
2223
  formulaChange
1977
2224
  };
1978
2225
  }
@@ -1980,15 +2227,31 @@ var PatchEnricher = class {
1980
2227
  const baseNode = this.getNodeAtPath(this.baseTree, patch.path);
1981
2228
  const currentNode = this.getNodeAtPath(this.currentTree, patch.path);
1982
2229
  const isArrayMetadataPatch = baseNode?.isArray() && currentNode?.isArray();
2230
+ const formulaChange = this.computeFormulaChange(baseNode, currentNode);
2231
+ const defaultChange = isArrayMetadataPatch ? void 0 : this.computeDefaultChange(baseNode, currentNode);
2232
+ const descriptionChange = this.computeDescriptionChange(baseNode, currentNode);
2233
+ const deprecatedChange = this.computeDeprecatedChange(baseNode, currentNode);
2234
+ const foreignKeyChange = this.computeForeignKeyChange(baseNode, currentNode);
2235
+ const contentMediaTypeChange = this.computeContentMediaTypeChange(baseNode, currentNode);
2236
+ const metadataChanges = this.computeMetadataChanges({
2237
+ formulaChange,
2238
+ defaultChange,
2239
+ descriptionChange,
2240
+ deprecatedChange,
2241
+ foreignKeyChange,
2242
+ contentMediaTypeChange
2243
+ });
1983
2244
  return {
1984
2245
  patch,
1985
2246
  fieldName,
2247
+ metadataChanges,
1986
2248
  typeChange: this.computeTypeChange(baseNode, currentNode, isArrayMetadataPatch),
1987
- formulaChange: this.computeFormulaChange(baseNode, currentNode),
1988
- defaultChange: isArrayMetadataPatch ? void 0 : this.computeDefaultChange(baseNode, currentNode),
1989
- descriptionChange: this.computeDescriptionChange(baseNode, currentNode),
1990
- deprecatedChange: this.computeDeprecatedChange(baseNode, currentNode),
1991
- foreignKeyChange: this.computeForeignKeyChange(baseNode, currentNode)
2249
+ formulaChange,
2250
+ defaultChange,
2251
+ descriptionChange,
2252
+ deprecatedChange,
2253
+ foreignKeyChange,
2254
+ contentMediaTypeChange
1992
2255
  };
1993
2256
  }
1994
2257
  computeAddMetadata(node) {
@@ -2029,6 +2292,13 @@ var PatchEnricher = class {
2029
2292
  toForeignKey: foreignKey
2030
2293
  };
2031
2294
  }
2295
+ const contentMediaType = node.contentMediaType();
2296
+ if (contentMediaType) {
2297
+ result.contentMediaTypeChange = {
2298
+ fromContentMediaType: void 0,
2299
+ toContentMediaType: contentMediaType
2300
+ };
2301
+ }
2032
2302
  return result;
2033
2303
  }
2034
2304
  computeTypeChange(baseNode, currentNode, ignoreItems) {
@@ -2108,6 +2378,39 @@ var PatchEnricher = class {
2108
2378
  }
2109
2379
  return void 0;
2110
2380
  }
2381
+ computeContentMediaTypeChange(baseNode, currentNode) {
2382
+ const baseMediaType = baseNode?.contentMediaType();
2383
+ const currentMediaType = currentNode?.contentMediaType();
2384
+ if (baseMediaType !== currentMediaType) {
2385
+ return {
2386
+ fromContentMediaType: baseMediaType,
2387
+ toContentMediaType: currentMediaType
2388
+ };
2389
+ }
2390
+ return void 0;
2391
+ }
2392
+ computeMetadataChanges(changes) {
2393
+ const result = [];
2394
+ if (changes.formulaChange) {
2395
+ result.push("formula");
2396
+ }
2397
+ if (changes.defaultChange) {
2398
+ result.push("default");
2399
+ }
2400
+ if (changes.descriptionChange) {
2401
+ result.push("description");
2402
+ }
2403
+ if (changes.deprecatedChange) {
2404
+ result.push("deprecated");
2405
+ }
2406
+ if (changes.foreignKeyChange) {
2407
+ result.push("foreignKey");
2408
+ }
2409
+ if (changes.contentMediaTypeChange) {
2410
+ result.push("contentMediaType");
2411
+ }
2412
+ return result;
2413
+ }
2111
2414
  getNodeType(node) {
2112
2415
  if (node.isArray()) {
2113
2416
  const items = node.items();
@@ -2131,6 +2434,20 @@ var PatchEnricher = class {
2131
2434
  return false;
2132
2435
  }
2133
2436
  }
2437
+ movesIntoArrayBoundary(fromPointer, toPointer) {
2438
+ try {
2439
+ const fromPath = jsonPointerToPath(fromPointer);
2440
+ const toPath = jsonPointerToPath(toPointer);
2441
+ const fromArrayDepth = this.countArrayDepth(fromPath);
2442
+ const toArrayDepth = this.countArrayDepth(toPath);
2443
+ return toArrayDepth > fromArrayDepth;
2444
+ } catch {
2445
+ return false;
2446
+ }
2447
+ }
2448
+ countArrayDepth(path) {
2449
+ return path.segments().filter((seg) => seg.isItems()).length;
2450
+ }
2134
2451
  getNodeAtPath(tree, jsonPointer) {
2135
2452
  try {
2136
2453
  const path = jsonPointerToPath(jsonPointer);
@@ -2489,6 +2806,12 @@ function collectValidationErrors(node, errors) {
2489
2806
  if (node.isNull()) {
2490
2807
  return;
2491
2808
  }
2809
+ const foreignKey = node.foreignKey();
2810
+ if (foreignKey === "") {
2811
+ errors.push(
2812
+ createError(node.id(), "empty-foreign-key", "Foreign key table reference cannot be empty")
2813
+ );
2814
+ }
2492
2815
  if (node.isObject()) {
2493
2816
  const children = node.properties();
2494
2817
  const nameSet = /* @__PURE__ */ new Set();
@@ -2564,6 +2887,6 @@ function buildArrayItemsPath(parentPath) {
2564
2887
  return parentPath ? `${parentPath}[*]` : "[*]";
2565
2888
  }
2566
2889
 
2567
- export { AbstractBasePath, ChangeCoalescer, ChangeCollector, CompositeRule, EMPTY_METADATA, EMPTY_PATH, EnumValidator, FIELD_NAME_ERROR_MESSAGE, ForeignKeyValidator, FormulaDependencyIndex, ItemsSegment, MaxLengthValidator, MaximumValidator, MinLengthValidator, MinimumValidator, NULL_NODE, NodePathIndex, ParsedFormula, PatchBuilder, PatchEnricher, PatchGenerator, PatternValidator, PropertySegment, RequiredValidator, SchemaDiff, SchemaPropertyRule, SchemaSerializer, SchemaTruthyRule, ValidationEngine, ValidatorRegistry, ValidatorResolver, areNodesContentEqual, areNodesEqual, coalesceChanges, collectChanges, createArrayNode, createBooleanNode, createDefaultValidatorRegistry, createNumberNode, createObjectNode, createPath, createRefNode, createSchemaTree, createStringNode, createValidationEngine, isValidFieldName, jsonPointerToPath, jsonPointerToSegments, jsonPointerToSimplePath, validateFormulas, validateSchema };
2568
- //# sourceMappingURL=chunk-S7GEDTSL.js.map
2569
- //# sourceMappingURL=chunk-S7GEDTSL.js.map
2890
+ export { AbstractBasePath, ChangeCoalescer, ChangeCollector, CompositeRule, EMPTY_METADATA, EMPTY_PATH, EnumValidator, FIELD_NAME_ERROR_MESSAGE, ForeignKeyValidator, FormulaChangeDetector, FormulaDependencyIndex, FormulaPath, FormulaPathBuilder, FormulaSerializer, ItemsSegment, MaxLengthValidator, MaximumValidator, MinLengthValidator, MinimumValidator, NULL_NODE, NodePathIndex, ParsedFormula, PatchBuilder, PatchEnricher, PatchGenerator, PatternValidator, PropertySegment, RequiredValidator, ResolvedDependency, SchemaDiff, SchemaPropertyRule, SchemaSerializer, SchemaTruthyRule, ValidationEngine, ValidatorRegistry, ValidatorResolver, areNodesContentEqual, areNodesEqual, coalesceChanges, collectChanges, createArrayNode, createBooleanNode, createDefaultValidatorRegistry, createMobxProvider, createNumberNode, createObjectNode, createPath, createRefNode, createSchemaTree, createStringNode, createValidationEngine, isValidFieldName, jsonPointerToPath, jsonPointerToSegments, jsonPointerToSimplePath, makeAutoObservable, makeObservable, observable, reaction, resetReactivityProvider, runInAction, setReactivityProvider, validateFormulas, validateSchema };
2891
+ //# sourceMappingURL=chunk-PGR2S2BR.js.map
2892
+ //# sourceMappingURL=chunk-PGR2S2BR.js.map