@revisium/formula 0.3.0 → 0.4.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.
@@ -294,6 +294,125 @@ token("*", 200, (a) => {
294
294
  if (!a) return createWildcardLiteral();
295
295
  return void 0;
296
296
  });
297
+ token("/", 200, (a) => {
298
+ if (a) return;
299
+ const name = next2(isIdChar);
300
+ if (!name) return;
301
+ return "/" + name;
302
+ });
303
+ var isRelativePathChar = (c) => isIdChar(c) || c === 47 || c === 46 ? 1 : 0;
304
+ token(".", 200, (a) => {
305
+ if (a) return;
306
+ const second = next2((c) => c === 46 ? 1 : 0);
307
+ if (!second) return;
308
+ const rest = next2(isRelativePathChar);
309
+ if (!rest) return;
310
+ return ".." + rest;
311
+ });
312
+ var BUILTIN_FUNCTIONS = {
313
+ and: (a, b) => Boolean(a) && Boolean(b),
314
+ or: (a, b) => Boolean(a) || Boolean(b),
315
+ not: (a) => !a,
316
+ concat: (...args) => args.map(String).join(""),
317
+ upper: (s) => String(s).toUpperCase(),
318
+ lower: (s) => String(s).toLowerCase(),
319
+ trim: (s) => String(s).trim(),
320
+ left: (s, n) => {
321
+ const count = Math.max(0, Math.floor(Number(n)));
322
+ return String(s).slice(0, count);
323
+ },
324
+ right: (s, n) => {
325
+ const str = String(s);
326
+ const count = Math.max(0, Math.floor(Number(n)));
327
+ return count === 0 ? "" : str.slice(-count);
328
+ },
329
+ replace: (s, search, replacement) => String(s).replace(String(search), String(replacement)),
330
+ tostring: String,
331
+ length: (s) => {
332
+ if (Array.isArray(s)) return s.length;
333
+ if (typeof s === "string") return s.length;
334
+ if (s !== null && typeof s === "object") return Object.keys(s).length;
335
+ return String(s).length;
336
+ },
337
+ contains: (s, search) => String(s).includes(String(search)),
338
+ startswith: (s, search) => String(s).startsWith(String(search)),
339
+ endswith: (s, search) => String(s).endsWith(String(search)),
340
+ tonumber: Number,
341
+ toboolean: Boolean,
342
+ isnull: (v) => v === null || v === void 0,
343
+ coalesce: (...args) => args.find((v) => v !== null && v !== void 0) ?? null,
344
+ round: (n, decimals) => {
345
+ const num2 = Number(n);
346
+ const dec = decimals === void 0 ? 0 : Number(decimals);
347
+ const factor = 10 ** dec;
348
+ return Math.round(num2 * factor) / factor;
349
+ },
350
+ floor: (n) => Math.floor(Number(n)),
351
+ ceil: (n) => Math.ceil(Number(n)),
352
+ abs: (n) => Math.abs(Number(n)),
353
+ sqrt: (n) => Math.sqrt(Number(n)),
354
+ pow: (base, exp) => Math.pow(Number(base), Number(exp)),
355
+ min: (...args) => args.length === 0 ? Number.NaN : Math.min(...args.map(Number)),
356
+ max: (...args) => args.length === 0 ? Number.NaN : Math.max(...args.map(Number)),
357
+ log: (n) => Math.log(Number(n)),
358
+ log10: (n) => Math.log10(Number(n)),
359
+ exp: (n) => Math.exp(Number(n)),
360
+ sign: (n) => Math.sign(Number(n)),
361
+ sum: (arr) => Array.isArray(arr) ? arr.reduce((a, b) => a + Number(b), 0) : 0,
362
+ avg: (arr) => Array.isArray(arr) && arr.length > 0 ? arr.reduce((a, b) => a + Number(b), 0) / arr.length : 0,
363
+ count: (arr) => Array.isArray(arr) ? arr.length : 0,
364
+ first: (arr) => Array.isArray(arr) ? arr[0] : void 0,
365
+ last: (arr) => Array.isArray(arr) ? arr.at(-1) : void 0,
366
+ join: (arr, separator) => {
367
+ if (!Array.isArray(arr)) return "";
368
+ if (separator === void 0) return arr.join(",");
369
+ if (typeof separator === "string") return arr.join(separator);
370
+ if (typeof separator === "number") return arr.join(String(separator));
371
+ return arr.join(",");
372
+ },
373
+ includes: (arr, value) => Array.isArray(arr) ? arr.includes(value) : false,
374
+ if: (condition, ifTrue, ifFalse) => condition ? ifTrue : ifFalse
375
+ };
376
+ function extractCallArgs(argsNode) {
377
+ if (!argsNode) return [];
378
+ if (!Array.isArray(argsNode)) return [argsNode];
379
+ if (argsNode[0] === ",") {
380
+ return argsNode.slice(1);
381
+ }
382
+ return [argsNode];
383
+ }
384
+ function compileNode(node) {
385
+ return compile(node);
386
+ }
387
+ function createGroupingEvaluator(fn) {
388
+ const compiledExpr = compileNode(fn);
389
+ return (ctx) => compiledExpr(ctx);
390
+ }
391
+ function createFunctionCallEvaluator(fn, argsNode) {
392
+ const args = extractCallArgs(argsNode);
393
+ const compiledArgs = args.map((arg) => compileNode(arg));
394
+ return (ctx) => {
395
+ const argValues = compiledArgs.map((a) => a(ctx));
396
+ if (typeof fn === "string") {
397
+ const builtinFn = BUILTIN_FUNCTIONS[fn.toLowerCase()];
398
+ if (builtinFn) {
399
+ return builtinFn(...argValues);
400
+ }
401
+ }
402
+ const fnValue = compileNode(fn)(ctx);
403
+ if (typeof fnValue === "function") {
404
+ return fnValue(...argValues);
405
+ }
406
+ const fnName = typeof fn === "string" ? fn : String(fn);
407
+ throw new Error(`'${fnName}' is not a function`);
408
+ };
409
+ }
410
+ operator("()", (fn, argsNode) => {
411
+ if (argsNode === void 0) {
412
+ return createGroupingEvaluator(fn);
413
+ }
414
+ return createFunctionCallEvaluator(fn, argsNode);
415
+ });
297
416
  var KEYWORDS = /* @__PURE__ */ new Set([
298
417
  "true",
299
418
  "false",
@@ -302,9 +421,6 @@ var KEYWORDS = /* @__PURE__ */ new Set([
302
421
  "or",
303
422
  "not",
304
423
  "if",
305
- "constructor",
306
- "__proto__",
307
- "prototype",
308
424
  "round",
309
425
  "floor",
310
426
  "ceil",
@@ -359,6 +475,12 @@ function isArrayFunction(name) {
359
475
  function isContextToken(name) {
360
476
  return name.startsWith("@") || name.startsWith("#");
361
477
  }
478
+ function isRootPath(name) {
479
+ return name.startsWith("/");
480
+ }
481
+ function isRelativePath(name) {
482
+ return name.startsWith("..");
483
+ }
362
484
  function isValidIdentifierRoot(rootName) {
363
485
  return !isKeyword(rootName) && !isContextToken(rootName);
364
486
  }
@@ -371,6 +493,10 @@ function addPathIfValid(path, identifiers) {
371
493
  }
372
494
  }
373
495
  function collectStringIdentifier(node, identifiers) {
496
+ if (isRootPath(node) || isRelativePath(node)) {
497
+ identifiers.add(node);
498
+ return;
499
+ }
374
500
  if (!isContextToken(node) && !isKeyword(node)) {
375
501
  identifiers.add(node);
376
502
  }
@@ -403,6 +529,9 @@ function collectIdentifiers(node, identifiers) {
403
529
  if (!Array.isArray(node)) {
404
530
  return;
405
531
  }
532
+ if (isLiteralArray(node)) {
533
+ return;
534
+ }
406
535
  const [op, ...args] = node;
407
536
  if (op === "." || op === "[]") {
408
537
  collectPathOrFallback(node, identifiers);
@@ -500,16 +629,25 @@ function detectFunctionCallFeatures(funcName, features) {
500
629
  features.add("array_function");
501
630
  }
502
631
  }
503
- function detectFeatures(node, features) {
504
- if (typeof node === "string") {
505
- if (isContextToken(node)) {
506
- features.add("context_token");
632
+ function detectStringFeatures(node, features) {
633
+ if (isContextToken(node)) {
634
+ features.add("context_token");
635
+ }
636
+ if (isRootPath(node)) {
637
+ features.add("root_path");
638
+ if (node.includes(".")) {
639
+ features.add("nested_path");
507
640
  }
508
- return;
509
641
  }
510
- if (!Array.isArray(node) || isLiteralArray(node)) {
511
- return;
642
+ if (isRelativePath(node)) {
643
+ features.add("relative_path");
644
+ const withoutPrefix = node.replace(/^(\.\.\/)+/, "");
645
+ if (withoutPrefix.includes(".")) {
646
+ features.add("nested_path");
647
+ }
512
648
  }
649
+ }
650
+ function detectOperatorFeatures(node, features) {
513
651
  const op = node[0];
514
652
  if (op === ".") {
515
653
  features.add("nested_path");
@@ -520,6 +658,16 @@ function detectFeatures(node, features) {
520
658
  if (op === "()") {
521
659
  detectFunctionCallFeatures(node[1], features);
522
660
  }
661
+ }
662
+ function detectFeatures(node, features) {
663
+ if (typeof node === "string") {
664
+ detectStringFeatures(node, features);
665
+ return;
666
+ }
667
+ if (!Array.isArray(node) || isLiteralArray(node)) {
668
+ return;
669
+ }
670
+ detectOperatorFeatures(node, features);
523
671
  for (let i = 1; i < node.length; i++) {
524
672
  detectFeatures(node[i], features);
525
673
  }
@@ -562,77 +710,13 @@ function validateSyntax(expression) {
562
710
  };
563
711
  }
564
712
  }
565
- var BUILTIN_FUNCTIONS = {
566
- and: (a, b) => Boolean(a) && Boolean(b),
567
- or: (a, b) => Boolean(a) || Boolean(b),
568
- not: (a) => !a,
569
- concat: (...args) => args.map(String).join(""),
570
- upper: (s) => String(s).toUpperCase(),
571
- lower: (s) => String(s).toLowerCase(),
572
- trim: (s) => String(s).trim(),
573
- left: (s, n) => {
574
- const count = Math.max(0, Math.floor(Number(n)));
575
- return String(s).slice(0, count);
576
- },
577
- right: (s, n) => {
578
- const str = String(s);
579
- const count = Math.max(0, Math.floor(Number(n)));
580
- return count === 0 ? "" : str.slice(-count);
581
- },
582
- replace: (s, search, replacement) => String(s).replace(String(search), String(replacement)),
583
- tostring: String,
584
- length: (s) => {
585
- if (Array.isArray(s)) return s.length;
586
- if (typeof s === "string") return s.length;
587
- if (s !== null && typeof s === "object") return Object.keys(s).length;
588
- return String(s).length;
589
- },
590
- contains: (s, search) => String(s).includes(String(search)),
591
- startswith: (s, search) => String(s).startsWith(String(search)),
592
- endswith: (s, search) => String(s).endsWith(String(search)),
593
- tonumber: Number,
594
- toboolean: Boolean,
595
- isnull: (v) => v === null || v === void 0,
596
- coalesce: (...args) => args.find((v) => v !== null && v !== void 0) ?? null,
597
- round: (n, decimals) => {
598
- const num2 = Number(n);
599
- const dec = decimals === void 0 ? 0 : Number(decimals);
600
- const factor = 10 ** dec;
601
- return Math.round(num2 * factor) / factor;
602
- },
603
- floor: (n) => Math.floor(Number(n)),
604
- ceil: (n) => Math.ceil(Number(n)),
605
- abs: (n) => Math.abs(Number(n)),
606
- sqrt: (n) => Math.sqrt(Number(n)),
607
- pow: (base, exp) => Math.pow(Number(base), Number(exp)),
608
- min: (...args) => args.length === 0 ? Number.NaN : Math.min(...args.map(Number)),
609
- max: (...args) => args.length === 0 ? Number.NaN : Math.max(...args.map(Number)),
610
- log: (n) => Math.log(Number(n)),
611
- log10: (n) => Math.log10(Number(n)),
612
- exp: (n) => Math.exp(Number(n)),
613
- sign: (n) => Math.sign(Number(n)),
614
- sum: (arr) => Array.isArray(arr) ? arr.reduce((a, b) => a + Number(b), 0) : 0,
615
- avg: (arr) => Array.isArray(arr) && arr.length > 0 ? arr.reduce((a, b) => a + Number(b), 0) / arr.length : 0,
616
- count: (arr) => Array.isArray(arr) ? arr.length : 0,
617
- first: (arr) => Array.isArray(arr) ? arr[0] : void 0,
618
- last: (arr) => Array.isArray(arr) ? arr.at(-1) : void 0,
619
- join: (arr, separator) => {
620
- if (!Array.isArray(arr)) return "";
621
- if (separator === void 0) return arr.join(",");
622
- if (typeof separator === "string") return arr.join(separator);
623
- if (typeof separator === "number") return arr.join(String(separator));
624
- return arr.join(",");
625
- },
626
- includes: (arr, value) => Array.isArray(arr) ? arr.includes(value) : false,
627
- if: (condition, ifTrue, ifFalse) => condition ? ifTrue : ifFalse
628
- };
629
713
  function evaluate(expression, context) {
630
714
  const trimmed = expression.trim();
631
715
  if (!trimmed) {
632
716
  throw new Error("Empty expression");
633
717
  }
634
718
  const fn = subscript_default(trimmed);
635
- const safeContext = { ...BUILTIN_FUNCTIONS };
719
+ const safeContext = {};
636
720
  for (const [key, value] of Object.entries(context)) {
637
721
  if (typeof value !== "function") {
638
722
  safeContext[key] = value;
@@ -640,6 +724,52 @@ function evaluate(expression, context) {
640
724
  }
641
725
  return fn(safeContext);
642
726
  }
727
+ function getValueByPath(data, path) {
728
+ const segments = path.split(".");
729
+ let current = data;
730
+ for (const segment of segments) {
731
+ if (current === null || current === void 0) {
732
+ return void 0;
733
+ }
734
+ if (typeof current !== "object") {
735
+ return void 0;
736
+ }
737
+ current = current[segment];
738
+ }
739
+ return current;
740
+ }
741
+ function buildPathReferences(rootData, dependencies) {
742
+ const refs = {};
743
+ for (const dep of dependencies) {
744
+ if (dep.startsWith("/")) {
745
+ const fieldPath = dep.slice(1);
746
+ const rootField = fieldPath.split(".")[0] ?? fieldPath;
747
+ const contextKey = "/" + rootField;
748
+ if (!(contextKey in refs)) {
749
+ refs[contextKey] = getValueByPath(rootData, rootField);
750
+ }
751
+ } else if (dep.startsWith("../")) {
752
+ const fieldPath = dep.slice(3);
753
+ refs[dep] = getValueByPath(rootData, fieldPath);
754
+ }
755
+ }
756
+ return refs;
757
+ }
758
+ function evaluateWithContext(expression, options) {
759
+ const { rootData, itemData } = options;
760
+ const trimmed = expression.trim();
761
+ if (!trimmed) {
762
+ throw new Error("Empty expression");
763
+ }
764
+ const parsed = parseFormula(trimmed);
765
+ const pathRefs = buildPathReferences(rootData, parsed.dependencies);
766
+ const context = {
767
+ ...rootData,
768
+ ...itemData ?? {},
769
+ ...pathRefs
770
+ };
771
+ return evaluate(trimmed, context);
772
+ }
643
773
  var ARITHMETIC_OPS = /* @__PURE__ */ new Set(["+", "-", "*", "/", "%"]);
644
774
  var COMPARISON_OPS = /* @__PURE__ */ new Set(["<", ">", "<=", ">=", "==", "!="]);
645
775
  var LOGICAL_OPS = /* @__PURE__ */ new Set(["&&", "||", "!"]);
@@ -893,21 +1023,104 @@ function processQueue(queue, graph, inDegree) {
893
1023
  // src/extract-schema.ts
894
1024
  function extractSchemaFormulas(schema) {
895
1025
  const formulas = [];
1026
+ extractFormulasRecursive(schema, "", formulas);
1027
+ return formulas;
1028
+ }
1029
+ function extractFormulasRecursive(schema, pathPrefix, formulas) {
1030
+ if (schema.type === "array" && schema.items) {
1031
+ extractFormulasRecursive(schema.items, `${pathPrefix}[]`, formulas);
1032
+ return;
1033
+ }
896
1034
  const properties = schema.properties ?? {};
897
1035
  for (const [fieldName, fieldSchema] of Object.entries(properties)) {
1036
+ const fullPath = pathPrefix ? `${pathPrefix}.${fieldName}` : fieldName;
898
1037
  const xFormula = fieldSchema["x-formula"];
899
1038
  if (xFormula) {
900
1039
  formulas.push({
901
- fieldName,
1040
+ fieldName: fullPath,
902
1041
  expression: xFormula.expression,
903
1042
  fieldType: fieldSchema.type ?? "string"
904
1043
  });
905
1044
  }
1045
+ if (fieldSchema.type === "object" && fieldSchema.properties) {
1046
+ extractFormulasRecursive(fieldSchema, fullPath, formulas);
1047
+ }
1048
+ if (fieldSchema.type === "array" && fieldSchema.items) {
1049
+ extractFormulasRecursive(fieldSchema.items, `${fullPath}[]`, formulas);
1050
+ }
906
1051
  }
907
- return formulas;
908
1052
  }
909
1053
 
910
1054
  // src/validate-schema.ts
1055
+ function resolveSubSchema(schema, fieldPath) {
1056
+ if (!fieldPath) {
1057
+ return schema;
1058
+ }
1059
+ const segments = parsePathSegments(fieldPath);
1060
+ let current = schema;
1061
+ for (const segment of segments) {
1062
+ if (segment === "[]") {
1063
+ if (current.type === "array" && current.items) {
1064
+ current = current.items;
1065
+ } else {
1066
+ return null;
1067
+ }
1068
+ } else {
1069
+ if (current.properties?.[segment]) {
1070
+ current = current.properties[segment];
1071
+ } else {
1072
+ return null;
1073
+ }
1074
+ }
1075
+ }
1076
+ return current;
1077
+ }
1078
+ function parsePathSegments(path) {
1079
+ const segments = [];
1080
+ let current = "";
1081
+ let inBracket = false;
1082
+ for (const char of path) {
1083
+ if (char === "[") {
1084
+ if (current) {
1085
+ segments.push(current);
1086
+ current = "";
1087
+ }
1088
+ inBracket = true;
1089
+ } else if (char === "]") {
1090
+ inBracket = false;
1091
+ segments.push("[]");
1092
+ } else if (char === "." && !inBracket) {
1093
+ if (current) {
1094
+ segments.push(current);
1095
+ current = "";
1096
+ }
1097
+ } else if (!inBracket) {
1098
+ current += char;
1099
+ }
1100
+ }
1101
+ if (current) {
1102
+ segments.push(current);
1103
+ }
1104
+ return segments;
1105
+ }
1106
+ function getParentPath(fieldPath) {
1107
+ const lastDotIndex = fieldPath.lastIndexOf(".");
1108
+ const lastBracketIndex = fieldPath.lastIndexOf("[");
1109
+ const splitIndex = Math.max(lastDotIndex, lastBracketIndex);
1110
+ if (splitIndex <= 0) {
1111
+ return "";
1112
+ }
1113
+ return fieldPath.substring(0, splitIndex);
1114
+ }
1115
+ function getFieldName(fieldPath) {
1116
+ const lastDotIndex = fieldPath.lastIndexOf(".");
1117
+ const lastBracketIndex = fieldPath.lastIndexOf("]");
1118
+ const splitIndex = Math.max(lastDotIndex, lastBracketIndex);
1119
+ if (splitIndex === -1) {
1120
+ return fieldPath;
1121
+ }
1122
+ return fieldPath.substring(splitIndex + 1);
1123
+ }
911
1124
  function getSchemaFields(schema) {
912
1125
  const fields = /* @__PURE__ */ new Set();
913
1126
  const properties = schema.properties ?? {};
@@ -942,44 +1155,56 @@ function extractFieldRoot(dependency) {
942
1155
  const root = dependency.split(".")[0]?.split("[")[0];
943
1156
  return root || dependency;
944
1157
  }
945
- function validateFormulaAgainstSchema(expression, fieldName, schema) {
1158
+ function validateFormulaInContext(expression, fieldPath, rootSchema) {
946
1159
  const syntaxResult = validateFormulaSyntax(expression);
947
1160
  if (!syntaxResult.isValid) {
948
1161
  return {
949
- field: fieldName,
1162
+ field: fieldPath,
950
1163
  error: syntaxResult.error,
951
1164
  position: syntaxResult.position
952
1165
  };
953
1166
  }
1167
+ const parentPath = getParentPath(fieldPath);
1168
+ const localFieldName = getFieldName(fieldPath);
1169
+ const contextSchema = resolveSubSchema(rootSchema, parentPath);
1170
+ if (!contextSchema) {
1171
+ return {
1172
+ field: fieldPath,
1173
+ error: `Cannot resolve schema context for path '${parentPath}'`
1174
+ };
1175
+ }
954
1176
  const parseResult = parseExpression(expression);
955
- const schemaFields = getSchemaFields(schema);
1177
+ const schemaFields = getSchemaFields(contextSchema);
956
1178
  for (const dep of parseResult.dependencies) {
957
1179
  const rootField = extractFieldRoot(dep);
958
1180
  if (!schemaFields.has(rootField)) {
959
1181
  return {
960
- field: fieldName,
1182
+ field: fieldPath,
961
1183
  error: `Unknown field '${rootField}' in formula`
962
1184
  };
963
1185
  }
964
1186
  }
965
- if (parseResult.dependencies.some((d) => extractFieldRoot(d) === fieldName)) {
1187
+ if (parseResult.dependencies.some((d) => extractFieldRoot(d) === localFieldName)) {
966
1188
  return {
967
- field: fieldName,
1189
+ field: fieldPath,
968
1190
  error: `Formula cannot reference itself`
969
1191
  };
970
1192
  }
971
- const fieldSchema = schema.properties?.[fieldName];
1193
+ const fieldSchema = contextSchema.properties?.[localFieldName];
972
1194
  const expectedType = schemaTypeToInferred(fieldSchema?.type);
973
- const fieldTypes = getSchemaFieldTypes(schema);
1195
+ const fieldTypes = getSchemaFieldTypes(contextSchema);
974
1196
  const inferredType = inferFormulaType(expression, fieldTypes);
975
1197
  if (!isTypeCompatible(inferredType, expectedType)) {
976
1198
  return {
977
- field: fieldName,
1199
+ field: fieldPath,
978
1200
  error: `Type mismatch: formula returns '${inferredType}' but field expects '${expectedType}'`
979
1201
  };
980
1202
  }
981
1203
  return null;
982
1204
  }
1205
+ function validateFormulaAgainstSchema(expression, fieldName, schema) {
1206
+ return validateFormulaInContext(expression, fieldName, schema);
1207
+ }
983
1208
  function validateSchemaFormulas(schema) {
984
1209
  const errors = [];
985
1210
  const formulas = extractSchemaFormulas(schema);
@@ -999,7 +1224,12 @@ function validateSchemaFormulas(schema) {
999
1224
  const dependencies = {};
1000
1225
  for (const formula of formulas) {
1001
1226
  const parseResult = parseExpression(formula.expression);
1002
- dependencies[formula.fieldName] = parseResult.dependencies.map(extractFieldRoot);
1227
+ const parentPath = getParentPath(formula.fieldName);
1228
+ const prefix = parentPath ? `${parentPath}.` : "";
1229
+ dependencies[formula.fieldName] = parseResult.dependencies.map((dep) => {
1230
+ const rootField = extractFieldRoot(dep);
1231
+ return `${prefix}${rootField}`;
1232
+ });
1003
1233
  }
1004
1234
  const graph = buildDependencyGraph(dependencies);
1005
1235
  const circularCheck = detectCircularDependencies(graph);
@@ -1017,6 +1247,6 @@ function validateSchemaFormulas(schema) {
1017
1247
  return { isValid: true, errors: [] };
1018
1248
  }
1019
1249
 
1020
- export { buildDependencyGraph, detectCircularDependencies, evaluate, extractSchemaFormulas, getTopologicalOrder, inferFormulaType, parseExpression, parseFormula, validateFormulaAgainstSchema, validateFormulaSyntax, validateSchemaFormulas, validateSyntax };
1021
- //# sourceMappingURL=chunk-4JNGUHMF.js.map
1022
- //# sourceMappingURL=chunk-4JNGUHMF.js.map
1250
+ export { buildDependencyGraph, detectCircularDependencies, evaluate, evaluateWithContext, extractSchemaFormulas, getTopologicalOrder, inferFormulaType, parseExpression, parseFormula, validateFormulaAgainstSchema, validateFormulaSyntax, validateSchemaFormulas, validateSyntax };
1251
+ //# sourceMappingURL=chunk-FDIJPOVQ.js.map
1252
+ //# sourceMappingURL=chunk-FDIJPOVQ.js.map