@revisium/schema-toolkit 0.19.1 → 0.19.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 (33) hide show
  1. package/dist/{types-EHdxfQpd.d.cts → FormulaPathBuilder-8gmUFlgu.d.cts} +27 -2
  2. package/dist/{types-Dw9ba_YE.d.ts → FormulaPathBuilder-B6RyUFN7.d.ts} +27 -2
  3. package/dist/chunk-3FJZMVWA.js +3 -0
  4. package/dist/{chunk-Y2GYABV7.js.map → chunk-3FJZMVWA.js.map} +1 -1
  5. package/dist/{chunk-MKDGOOBV.cjs → chunk-CN74KAMA.cjs} +373 -66
  6. package/dist/chunk-CN74KAMA.cjs.map +1 -0
  7. package/dist/{chunk-R6VYCHY2.js → chunk-K7XZT2M4.js} +49 -310
  8. package/dist/chunk-K7XZT2M4.js.map +1 -0
  9. package/dist/chunk-L6HE7QPU.cjs +4 -0
  10. package/dist/{chunk-MLNKM67U.cjs.map → chunk-L6HE7QPU.cjs.map} +1 -1
  11. package/dist/{chunk-45UZ3CJN.js → chunk-T2JUOWMX.js} +313 -10
  12. package/dist/chunk-T2JUOWMX.js.map +1 -0
  13. package/dist/{chunk-U7N3EEQX.cjs → chunk-X2KLCGJ6.cjs} +51 -315
  14. package/dist/chunk-X2KLCGJ6.cjs.map +1 -0
  15. package/dist/core/index.cjs +70 -58
  16. package/dist/core/index.d.cts +2 -2
  17. package/dist/core/index.d.ts +2 -2
  18. package/dist/core/index.js +2 -2
  19. package/dist/index.cjs +115 -115
  20. package/dist/index.d.cts +2 -2
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +3 -3
  23. package/dist/model/index.cjs +58 -58
  24. package/dist/model/index.d.cts +4 -28
  25. package/dist/model/index.d.ts +4 -28
  26. package/dist/model/index.js +2 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-45UZ3CJN.js.map +0 -1
  29. package/dist/chunk-MKDGOOBV.cjs.map +0 -1
  30. package/dist/chunk-MLNKM67U.cjs +0 -4
  31. package/dist/chunk-R6VYCHY2.js.map +0 -1
  32. package/dist/chunk-U7N3EEQX.cjs.map +0 -1
  33. package/dist/chunk-Y2GYABV7.js +0 -3
@@ -1010,7 +1010,7 @@ var NodePathIndex = class {
1010
1010
  }
1011
1011
  };
1012
1012
 
1013
- // src/model/schema-formula/serialization/FormulaPathBuilder.ts
1013
+ // src/core/schema-formula/serialization/FormulaPathBuilder.ts
1014
1014
  var FormulaPathBuilder = class {
1015
1015
  buildWithArrayNotation(fromPath, toPath) {
1016
1016
  const fromSegments = fromPath.parent().segments();
@@ -1078,7 +1078,7 @@ var FormulaPathBuilder = class {
1078
1078
  }
1079
1079
  };
1080
1080
 
1081
- // src/model/schema-formula/core/FormulaError.ts
1081
+ // src/core/schema-formula/core/FormulaError.ts
1082
1082
  var FormulaError = class extends Error {
1083
1083
  constructor(message, nodeId, details) {
1084
1084
  super(message);
@@ -1088,7 +1088,7 @@ var FormulaError = class extends Error {
1088
1088
  }
1089
1089
  };
1090
1090
 
1091
- // src/model/schema-formula/serialization/FormulaSerializer.ts
1091
+ // src/core/schema-formula/serialization/FormulaSerializer.ts
1092
1092
  var FormulaSerializer = class _FormulaSerializer {
1093
1093
  constructor(tree, formulaNodeId, formula) {
1094
1094
  this.tree = tree;
@@ -1244,10 +1244,17 @@ function areFormulasEqual(currentFormula, baseFormula, currentNodeId, baseNodeId
1244
1244
  context.baseTree,
1245
1245
  baseNodeId
1246
1246
  );
1247
+ if (currentExpr === null || baseExpr === null) {
1248
+ return false;
1249
+ }
1247
1250
  return currentExpr === baseExpr;
1248
1251
  }
1249
1252
  function getSerializedExpression(formula, tree, nodeId) {
1250
- return FormulaSerializer.serializeExpression(tree, nodeId, formula, { strict: false });
1253
+ try {
1254
+ return FormulaSerializer.serializeExpression(tree, nodeId, formula, { strict: false });
1255
+ } catch {
1256
+ return null;
1257
+ }
1251
1258
  }
1252
1259
  function areObjectsEqual(current, base, context) {
1253
1260
  const propsCurrent = current.properties();
@@ -1501,7 +1508,7 @@ var SchemaDiff = class {
1501
1508
  }
1502
1509
  };
1503
1510
 
1504
- // src/model/schema-formula/core/FormulaDependency.ts
1511
+ // src/core/schema-formula/core/FormulaDependency.ts
1505
1512
  var ResolvedDependency = class {
1506
1513
  constructor(nodeId) {
1507
1514
  this.nodeId = nodeId;
@@ -1513,300 +1520,6 @@ var ResolvedDependency = class {
1513
1520
  return this.nodeId;
1514
1521
  }
1515
1522
  };
1516
- var ARRAY_NOTATION_REGEX = /^([^[]+)\[(?:\d+|\*)?\]$/;
1517
- var FormulaPath = class {
1518
- constructor(basePath, relativePath) {
1519
- this.basePath = basePath;
1520
- this.relativePath = relativePath;
1521
- }
1522
- resolve() {
1523
- let ast;
1524
- try {
1525
- const parseResult = formula.parseFormula(this.relativePath);
1526
- ast = parseResult.ast;
1527
- } catch {
1528
- return null;
1529
- }
1530
- return this.astToPath(ast, this.basePath);
1531
- }
1532
- astToPath(ast, base) {
1533
- switch (ast.type) {
1534
- case "Identifier":
1535
- return base.child(ast.name);
1536
- case "MemberExpression": {
1537
- const objectPath = this.astToPath(ast.object, base);
1538
- if (!objectPath) {
1539
- return null;
1540
- }
1541
- return objectPath.child(ast.property);
1542
- }
1543
- case "IndexExpression":
1544
- case "WildcardExpression": {
1545
- const objectPath = this.astToPath(ast.object, base);
1546
- if (!objectPath) {
1547
- return null;
1548
- }
1549
- return objectPath.childItems();
1550
- }
1551
- case "RelativePath":
1552
- return this.resolveRelativePathString(base, ast.path);
1553
- case "RootPath":
1554
- return this.resolveRootPath(ast.path);
1555
- default:
1556
- return null;
1557
- }
1558
- }
1559
- resolveRelativePathString(base, path) {
1560
- const parts = path.split("/");
1561
- let result = base;
1562
- for (const part of parts) {
1563
- if (part === "..") {
1564
- if (result.isEmpty()) {
1565
- return null;
1566
- }
1567
- result = result.parent();
1568
- } else if (part === ".") {
1569
- continue;
1570
- } else if (part) {
1571
- result = result.child(part);
1572
- }
1573
- }
1574
- return result;
1575
- }
1576
- resolveRootPath(rootPath) {
1577
- const path = rootPath.startsWith("/") ? rootPath.slice(1) : rootPath;
1578
- if (!path) {
1579
- return EMPTY_PATH;
1580
- }
1581
- try {
1582
- return this.parseFormulaPath(path);
1583
- } catch {
1584
- return null;
1585
- }
1586
- }
1587
- parseFormulaPath(formulaPath) {
1588
- const parts = formulaPath.split(".");
1589
- let result = EMPTY_PATH;
1590
- for (const part of parts) {
1591
- if (!part) {
1592
- throw new Error(`Invalid path: empty segment`);
1593
- }
1594
- const match = ARRAY_NOTATION_REGEX.exec(part);
1595
- if (match?.[1]) {
1596
- result = result.child(match[1]).childItems();
1597
- } else {
1598
- result = result.child(part);
1599
- }
1600
- }
1601
- return result;
1602
- }
1603
- };
1604
- var ParsedFormula = class {
1605
- _expression;
1606
- astNode;
1607
- deps;
1608
- astPathToNodeId;
1609
- constructor(tree, formulaNodeId, expression) {
1610
- this._expression = expression;
1611
- const parseResult = formula.parseFormula(expression);
1612
- this.astNode = parseResult.ast;
1613
- const formulaPath = tree.pathOf(formulaNodeId);
1614
- if (formulaPath.isEmpty() && tree.root().id() !== formulaNodeId) {
1615
- throw new FormulaError("Formula node not found in tree", formulaNodeId);
1616
- }
1617
- const deps = [];
1618
- const astPathToNodeId = /* @__PURE__ */ new Map();
1619
- for (const depPath of parseResult.dependencies) {
1620
- const targetNodeId = this.resolveDependencyPath(
1621
- tree,
1622
- formulaPath,
1623
- depPath
1624
- );
1625
- if (!targetNodeId) {
1626
- throw new FormulaError(
1627
- `Cannot resolve formula dependency: ${depPath}`,
1628
- formulaNodeId,
1629
- "Path not found in schema"
1630
- );
1631
- }
1632
- if (targetNodeId === formulaNodeId) {
1633
- throw new FormulaError(
1634
- "Formula cannot reference itself",
1635
- formulaNodeId,
1636
- "Self-reference detected"
1637
- );
1638
- }
1639
- deps.push(new ResolvedDependency(targetNodeId));
1640
- astPathToNodeId.set(depPath, targetNodeId);
1641
- }
1642
- this.deps = deps;
1643
- this.astPathToNodeId = astPathToNodeId;
1644
- }
1645
- version() {
1646
- return 1;
1647
- }
1648
- expression() {
1649
- return this._expression;
1650
- }
1651
- ast() {
1652
- return this.astNode;
1653
- }
1654
- dependencies() {
1655
- return this.deps;
1656
- }
1657
- getNodeIdForAstPath(astPath) {
1658
- return this.astPathToNodeId.get(astPath) ?? null;
1659
- }
1660
- astPaths() {
1661
- return Array.from(this.astPathToNodeId.keys());
1662
- }
1663
- resolveDependencyPath(tree, formulaNodePath, depPath) {
1664
- const basePath = this.getFormulaBasePath(formulaNodePath);
1665
- const depFormulaPath = new FormulaPath(basePath, depPath);
1666
- const targetPath = depFormulaPath.resolve();
1667
- if (!targetPath) {
1668
- return null;
1669
- }
1670
- const targetNode = tree.nodeAt(targetPath);
1671
- if (targetNode.isNull()) {
1672
- return null;
1673
- }
1674
- return targetNode.id();
1675
- }
1676
- getFormulaBasePath(formulaPath) {
1677
- let basePath = formulaPath;
1678
- while (!basePath.isEmpty()) {
1679
- const segs = basePath.segments();
1680
- const lastSeg = segs[segs.length - 1];
1681
- basePath = basePath.parent();
1682
- if (!lastSeg?.isItems()) {
1683
- break;
1684
- }
1685
- }
1686
- return basePath;
1687
- }
1688
- };
1689
-
1690
- // src/model/schema-formula/store/FormulaDependencyIndex.ts
1691
- var FormulaDependencyIndex = class {
1692
- dependentsMap = /* @__PURE__ */ new Map();
1693
- formulasByNodeId = /* @__PURE__ */ new Map();
1694
- registerFormula(formulaNodeId, formula) {
1695
- this.unregisterFormula(formulaNodeId);
1696
- this.formulasByNodeId.set(formulaNodeId, formula);
1697
- for (const dep of formula.dependencies()) {
1698
- const targetId = dep.targetNodeId();
1699
- let dependents = this.dependentsMap.get(targetId);
1700
- if (!dependents) {
1701
- dependents = /* @__PURE__ */ new Set();
1702
- this.dependentsMap.set(targetId, dependents);
1703
- }
1704
- dependents.add(formulaNodeId);
1705
- }
1706
- }
1707
- unregisterFormula(formulaNodeId) {
1708
- this.formulasByNodeId.delete(formulaNodeId);
1709
- for (const [targetId, dependents] of this.dependentsMap) {
1710
- dependents.delete(formulaNodeId);
1711
- if (dependents.size === 0) {
1712
- this.dependentsMap.delete(targetId);
1713
- }
1714
- }
1715
- }
1716
- getDependents(nodeId) {
1717
- const dependents = this.dependentsMap.get(nodeId);
1718
- return dependents ? Array.from(dependents) : [];
1719
- }
1720
- hasDependents(nodeId) {
1721
- const dependents = this.dependentsMap.get(nodeId);
1722
- return dependents !== void 0 && dependents.size > 0;
1723
- }
1724
- getFormula(nodeId) {
1725
- return this.formulasByNodeId.get(nodeId) ?? null;
1726
- }
1727
- hasFormula(nodeId) {
1728
- return this.formulasByNodeId.has(nodeId);
1729
- }
1730
- clear() {
1731
- this.dependentsMap.clear();
1732
- this.formulasByNodeId.clear();
1733
- }
1734
- forEachFormula(callback) {
1735
- for (const [nodeId, formula] of this.formulasByNodeId) {
1736
- callback(nodeId, formula);
1737
- }
1738
- }
1739
- size() {
1740
- return this.formulasByNodeId.size;
1741
- }
1742
- };
1743
-
1744
- // src/model/schema-formula/changes/FormulaChangeDetector.ts
1745
- var FormulaChangeDetector = class {
1746
- constructor(index, currentTree, baseTree) {
1747
- this.index = index;
1748
- this.currentTree = currentTree;
1749
- this.baseTree = baseTree;
1750
- }
1751
- detectIndirectChanges(changedNodeIds) {
1752
- const result = [];
1753
- const visited = /* @__PURE__ */ new Set();
1754
- for (const changedId of changedNodeIds) {
1755
- this.collectDependentChanges(changedId, result, visited, changedNodeIds);
1756
- }
1757
- return result;
1758
- }
1759
- collectDependentChanges(nodeId, result, visited, directlyChanged) {
1760
- const dependents = this.index.getDependents(nodeId);
1761
- for (const dependentId of dependents) {
1762
- if (visited.has(dependentId)) {
1763
- continue;
1764
- }
1765
- visited.add(dependentId);
1766
- if (directlyChanged.has(dependentId)) {
1767
- continue;
1768
- }
1769
- const change = this.detectFormulaChange(dependentId);
1770
- if (change) {
1771
- result.push(change);
1772
- }
1773
- this.collectDependentChanges(dependentId, result, visited, directlyChanged);
1774
- }
1775
- }
1776
- detectFormulaChange(nodeId) {
1777
- const currentNode = this.currentTree.nodeById(nodeId);
1778
- const baseNode = this.baseTree.nodeById(nodeId);
1779
- if (currentNode.isNull() || baseNode.isNull()) {
1780
- return null;
1781
- }
1782
- const currentFormula = currentNode.formula();
1783
- const baseFormula = baseNode.formula();
1784
- if (!currentFormula || !baseFormula) {
1785
- return null;
1786
- }
1787
- const fromExpression = this.getSerializedExpression(baseFormula, this.baseTree, nodeId);
1788
- const toExpression = this.getSerializedExpression(currentFormula, this.currentTree, nodeId);
1789
- if (fromExpression === null || toExpression === null) {
1790
- return null;
1791
- }
1792
- if (fromExpression === toExpression) {
1793
- return null;
1794
- }
1795
- return {
1796
- nodeId,
1797
- fromExpression,
1798
- toExpression
1799
- };
1800
- }
1801
- getSerializedExpression(formula, tree, nodeId) {
1802
- try {
1803
- const xFormula = FormulaSerializer.toXFormula(tree, nodeId, formula);
1804
- return xFormula.expression;
1805
- } catch {
1806
- return null;
1807
- }
1808
- }
1809
- };
1810
1523
 
1811
1524
  // src/core/schema-serializer/SchemaSerializer.ts
1812
1525
  var SchemaSerializer = class {
@@ -1939,7 +1652,11 @@ var SchemaSerializer = class {
1939
1652
  "Cannot serialize formula without tree context. Use serializeNode with tree."
1940
1653
  );
1941
1654
  }
1942
- return FormulaSerializer.toXFormula(this.tree, node.id(), formula);
1655
+ try {
1656
+ return FormulaSerializer.toXFormula(this.tree, node.id(), formula);
1657
+ } catch {
1658
+ return { version: 1, expression: "" };
1659
+ }
1943
1660
  }
1944
1661
  addMetadata(schema, node) {
1945
1662
  const meta = node.metadata();
@@ -2387,7 +2104,11 @@ var PatchEnricher = class {
2387
2104
  if (!formula || !node) {
2388
2105
  return void 0;
2389
2106
  }
2390
- return FormulaSerializer.serializeExpression(tree, node.id(), formula, { strict: false });
2107
+ try {
2108
+ return FormulaSerializer.serializeExpression(tree, node.id(), formula, { strict: false });
2109
+ } catch {
2110
+ return void 0;
2111
+ }
2391
2112
  },
2392
2113
  compare: (from, to) => from === to
2393
2114
  },
@@ -2887,17 +2608,12 @@ function collectValidationErrors(node, errors) {
2887
2608
  function createError(nodeId, type, message) {
2888
2609
  return { nodeId, type, message };
2889
2610
  }
2890
-
2891
- // src/core/validation/formula/FormulaValidator.ts
2892
2611
  function validateFormulas(tree) {
2893
2612
  const errors = [];
2894
2613
  collectFormulaErrors(tree.root(), tree, errors, "");
2895
2614
  return errors;
2896
2615
  }
2897
2616
  function collectFormulaErrors(node, tree, errors, fieldPath) {
2898
- if (node.isNull()) {
2899
- return;
2900
- }
2901
2617
  validateNodeFormula(node, tree, errors, fieldPath);
2902
2618
  collectChildErrors(node, tree, errors, fieldPath);
2903
2619
  }
@@ -2905,11 +2621,11 @@ function validateNodeFormula(node, tree, errors, fieldPath) {
2905
2621
  if (!node.isPrimitive() || !node.hasFormula()) {
2906
2622
  return;
2907
2623
  }
2908
- const formula = node.formula();
2909
- if (!formula) {
2624
+ const formula$1 = node.formula();
2625
+ if (!formula$1) {
2910
2626
  return;
2911
2627
  }
2912
- for (const dep of formula.dependencies()) {
2628
+ for (const dep of formula$1.dependencies()) {
2913
2629
  const targetNode = tree.nodeById(dep.targetNodeId());
2914
2630
  if (targetNode.isNull()) {
2915
2631
  errors.push({
@@ -2917,7 +2633,30 @@ function validateNodeFormula(node, tree, errors, fieldPath) {
2917
2633
  message: "Cannot resolve formula dependency: target node not found",
2918
2634
  fieldPath: fieldPath || node.name()
2919
2635
  });
2636
+ return;
2637
+ }
2638
+ }
2639
+ try {
2640
+ const expression = FormulaSerializer.serializeExpression(
2641
+ tree,
2642
+ node.id(),
2643
+ formula$1,
2644
+ { strict: false }
2645
+ );
2646
+ const result = formula.validateFormulaSyntax(expression);
2647
+ if (!result.isValid) {
2648
+ errors.push({
2649
+ nodeId: node.id(),
2650
+ message: `Invalid formula: ${result.error}`,
2651
+ fieldPath: fieldPath || node.name()
2652
+ });
2920
2653
  }
2654
+ } catch {
2655
+ errors.push({
2656
+ nodeId: node.id(),
2657
+ message: "Invalid formula expression",
2658
+ fieldPath: fieldPath || node.name()
2659
+ });
2921
2660
  }
2922
2661
  }
2923
2662
  function collectChildErrors(node, tree, errors, fieldPath) {
@@ -2947,9 +2686,7 @@ exports.EMPTY_PATH = EMPTY_PATH;
2947
2686
  exports.EnumValidator = EnumValidator;
2948
2687
  exports.FIELD_NAME_ERROR_MESSAGE = FIELD_NAME_ERROR_MESSAGE;
2949
2688
  exports.ForeignKeyValidator = ForeignKeyValidator;
2950
- exports.FormulaChangeDetector = FormulaChangeDetector;
2951
- exports.FormulaDependencyIndex = FormulaDependencyIndex;
2952
- exports.FormulaPath = FormulaPath;
2689
+ exports.FormulaError = FormulaError;
2953
2690
  exports.FormulaPathBuilder = FormulaPathBuilder;
2954
2691
  exports.FormulaSerializer = FormulaSerializer;
2955
2692
  exports.ItemsSegment = ItemsSegment;
@@ -2959,7 +2696,6 @@ exports.MinLengthValidator = MinLengthValidator;
2959
2696
  exports.MinimumValidator = MinimumValidator;
2960
2697
  exports.NULL_NODE = NULL_NODE;
2961
2698
  exports.NodePathIndex = NodePathIndex;
2962
- exports.ParsedFormula = ParsedFormula;
2963
2699
  exports.PatchBuilder = PatchBuilder;
2964
2700
  exports.PatchEnricher = PatchEnricher;
2965
2701
  exports.PatchGenerator = PatchGenerator;
@@ -3002,5 +2738,5 @@ exports.runInAction = runInAction;
3002
2738
  exports.setReactivityProvider = setReactivityProvider;
3003
2739
  exports.validateFormulas = validateFormulas;
3004
2740
  exports.validateSchema = validateSchema;
3005
- //# sourceMappingURL=chunk-U7N3EEQX.cjs.map
3006
- //# sourceMappingURL=chunk-U7N3EEQX.cjs.map
2741
+ //# sourceMappingURL=chunk-X2KLCGJ6.cjs.map
2742
+ //# sourceMappingURL=chunk-X2KLCGJ6.cjs.map