@revisium/formula 0.7.0 → 0.9.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.
- package/README.md +27 -0
- package/dist/__tests__/array-context.spec.d.ts +2 -0
- package/dist/__tests__/array-context.spec.d.ts.map +1 -0
- package/dist/__tests__/dependency-graph.spec.d.ts +2 -0
- package/dist/__tests__/dependency-graph.spec.d.ts.map +1 -0
- package/dist/__tests__/evaluate-complex.spec.d.ts +2 -0
- package/dist/__tests__/evaluate-complex.spec.d.ts.map +1 -0
- package/dist/__tests__/parse-formula.spec.d.ts +2 -0
- package/dist/__tests__/parse-formula.spec.d.ts.map +1 -0
- package/dist/__tests__/parser.spec.d.ts +2 -0
- package/dist/__tests__/parser.spec.d.ts.map +1 -0
- package/dist/__tests__/replace-dependencies.spec.d.ts +2 -0
- package/dist/__tests__/replace-dependencies.spec.d.ts.map +1 -0
- package/dist/__tests__/serialize-ast.spec.d.ts +2 -0
- package/dist/__tests__/serialize-ast.spec.d.ts.map +1 -0
- package/dist/__tests__/validate-syntax.spec.d.ts +2 -0
- package/dist/__tests__/validate-syntax.spec.d.ts.map +1 -0
- package/dist/dependency-graph.d.ts +17 -0
- package/dist/dependency-graph.d.ts.map +1 -0
- package/dist/editor/index.cjs +4 -19
- package/dist/editor/index.d.ts +8 -1
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.mjs +3 -0
- package/dist/formula-spec.cjs +808 -535
- package/dist/formula-spec.cjs.map +1 -1
- package/dist/formula-spec.d.ts +10 -5
- package/dist/formula-spec.d.ts.map +1 -0
- package/dist/formula-spec.mjs +1039 -0
- package/dist/formula-spec.mjs.map +1 -0
- package/dist/index.cjs +121 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -20
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +130 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ohm/core/parser.d.ts +30 -0
- package/dist/ohm/core/parser.d.ts.map +1 -0
- package/dist/ohm/core/replace-dependencies.d.ts +3 -0
- package/dist/ohm/core/replace-dependencies.d.ts.map +1 -0
- package/dist/ohm/core/serialize-ast.d.ts +3 -0
- package/dist/ohm/core/serialize-ast.d.ts.map +1 -0
- package/dist/ohm/core/types.d.ts +78 -0
- package/dist/ohm/core/types.d.ts.map +1 -0
- package/dist/ohm/grammar/index.d.ts +3 -0
- package/dist/ohm/grammar/index.d.ts.map +1 -0
- package/dist/ohm/index.d.ts +8 -0
- package/dist/ohm/index.d.ts.map +1 -0
- package/dist/ohm/semantics/index.d.ts +2 -0
- package/dist/ohm/semantics/index.d.ts.map +1 -0
- package/dist/parse-formula.d.ts +9 -0
- package/dist/parse-formula.d.ts.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/validate-syntax-BGrLewnG.cjs +1502 -0
- package/dist/validate-syntax-BGrLewnG.cjs.map +1 -0
- package/dist/validate-syntax-CmqnFrsc.mjs +1421 -0
- package/dist/validate-syntax-CmqnFrsc.mjs.map +1 -0
- package/dist/validate-syntax.d.ts +9 -0
- package/dist/validate-syntax.d.ts.map +1 -0
- package/package.json +12 -11
- package/dist/chunk-5TM76LGI.js +0 -1216
- package/dist/chunk-5TM76LGI.js.map +0 -1
- package/dist/chunk-IM22W645.cjs +0 -1244
- package/dist/chunk-IM22W645.cjs.map +0 -1
- package/dist/editor/index.cjs.map +0 -1
- package/dist/editor/index.d.cts +0 -1
- package/dist/editor/index.js +0 -3
- package/dist/editor/index.js.map +0 -1
- package/dist/formula-spec.d.cts +0 -68
- package/dist/formula-spec.js +0 -765
- package/dist/formula-spec.js.map +0 -1
- package/dist/index-CPsOPCQ6.d.cts +0 -166
- package/dist/index-CPsOPCQ6.d.ts +0 -166
- package/dist/index.d.cts +0 -20
- package/dist/index.js +0 -111
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-syntax-CmqnFrsc.mjs","names":[],"sources":["../src/ohm/grammar/index.ts","../src/ohm/semantics/index.ts","../src/ohm/core/parser.ts","../src/ohm/core/serialize-ast.ts","../src/ohm/core/replace-dependencies.ts","../src/parse-formula.ts","../src/validate-syntax.ts"],"sourcesContent":["import * as ohm from 'ohm-js';\n\n// Using String.raw to avoid double-escaping backslashes in Ohm grammar\n// In Ohm grammar, we need single backslashes for escape sequences\nconst grammarText = String.raw`Formula {\n Expression = Ternary\n\n // Ternary: condition ? then : else\n Ternary\n = LogicalOr \"?\" Ternary \":\" Ternary -- ternary\n | LogicalOr\n\n // Logical OR: a || b\n LogicalOr\n = LogicalOr \"||\" LogicalAnd -- or\n | LogicalAnd\n\n // Logical AND: a && b\n LogicalAnd\n = LogicalAnd \"&&\" Equality -- and\n | Equality\n\n // Equality: a == b, a != b\n Equality\n = Equality \"==\" Comparison -- eq\n | Equality \"!=\" Comparison -- neq\n | Comparison\n\n // Comparison: a > b, a < b, a >= b, a <= b\n Comparison\n = Comparison \">=\" Additive -- gte\n | Comparison \"<=\" Additive -- lte\n | Comparison \">\" Additive -- gt\n | Comparison \"<\" Additive -- lt\n | Additive\n\n // Additive: a + b, a - b\n Additive\n = Additive \"+\" Multiplicative -- plus\n | Additive \"-\" Multiplicative -- minus\n | Multiplicative\n\n // Multiplicative: a * b, a / b, a % b\n Multiplicative\n = Multiplicative \"*\" Unary -- times\n | Multiplicative \"/\" Unary -- div\n | Multiplicative \"%\" Unary -- mod\n | Unary\n\n // Unary: -a, !a\n Unary\n = \"-\" Unary -- neg\n | \"!\" Unary -- not\n | Postfix\n\n // Postfix: function calls, property access, array access\n Postfix\n = Postfix \"(\" Arguments? \")\" -- call\n | Postfix \".\" identifier -- property\n | Postfix \"[\" Expression \"]\" -- index\n | Postfix \"[\" \"*\" \"]\" -- wildcard\n | Primary\n\n // Arguments for function calls\n Arguments\n = Expression (\",\" Expression)*\n\n // Primary expressions\n Primary\n = \"(\" Expression \")\" -- paren\n | \"[\" string \"]\" -- bracketedField\n | number\n | string\n | boolean\n | null\n | rootPath\n | relativePath\n | contextToken\n | identifier\n\n // Literals\n number\n = \"-\"? digit+ \".\" digit+ -- float\n | \"-\"? digit+ -- int\n\n string\n = \"\\\"\" doubleStringChar* \"\\\"\"\n | \"'\" singleStringChar* \"'\"\n\n doubleStringChar\n = ~(\"\\\"\" | \"\\\\\") any -- regular\n | \"\\\\\" any -- escape\n\n singleStringChar\n = ~(\"'\" | \"\\\\\") any -- regular\n | \"\\\\\" any -- escape\n\n boolean\n = \"true\" ~identifierPart -- true\n | \"false\" ~identifierPart -- false\n\n null = \"null\" ~identifierPart\n\n // Identifiers and paths\n identifier = ~reserved identifierStart identifierPart*\n\n identifierStart = letter | \"_\"\n identifierPart = letter | digit | \"_\"\n\n // Special paths\n rootPath = \"/\" identifierPart+\n\n relativePathPrefix = \"..\" \"/\"\n relativePath = relativePathPrefix+ identifierPart+\n\n contextToken\n = \"@\" contextPath -- at\n | \"#\" contextPath -- hash\n\n contextPath\n = \"parent\" \".\" contextPath -- parent\n | \"root\" \".\" contextPathEnd -- root\n | contextPathEnd -- simple\n\n contextPathEnd = identifierPart+\n\n // Reserved words (cannot be used as identifiers)\n reserved\n = (\"true\" | \"false\" | \"null\") ~identifierPart\n\n // Whitespace (implicit, Ohm handles automatically)\n}`;\n\nexport const grammar = ohm.grammar(grammarText);\n","import type { NonterminalNode, TerminalNode, IterationNode } from 'ohm-js';\nimport { grammar } from '../grammar';\nimport type { ASTNode } from '../core/types';\nimport type { FormulaFeature } from '../../types';\n\ntype OhmNode = NonterminalNode | TerminalNode | IterationNode;\n\nfunction isSafePropertyName(name: string): boolean {\n return name !== '__proto__';\n}\n\nfunction childrenToAST(children: OhmNode[]): ASTNode[] {\n return children\n .filter((c): c is NonterminalNode => 'toAST' in c)\n .map((c) => c.toAST() as ASTNode);\n}\n\nfunction childrenDependencies(children: OhmNode[]): string[] {\n return children\n .filter((c): c is NonterminalNode => 'dependencies' in c)\n .flatMap((c) => c.dependencies() as string[]);\n}\n\nfunction childrenFeatures(children: OhmNode[]): FormulaFeature[] {\n return children\n .filter((c): c is NonterminalNode => 'features' in c)\n .flatMap((c) => c.features() as FormulaFeature[]);\n}\n\nexport const semantics = grammar.createSemantics();\n\n// ============ toAST Operation ============\nsemantics.addOperation<ASTNode>('toAST', {\n Expression(e) {\n return e.toAST();\n },\n\n Ternary_ternary(cond, _q, cons, _c, alt) {\n return {\n type: 'TernaryOp',\n condition: cond.toAST(),\n consequent: cons.toAST(),\n alternate: alt.toAST(),\n };\n },\n Ternary(e) {\n return e.toAST();\n },\n\n LogicalOr_or(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '||',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n LogicalOr(e) {\n return e.toAST();\n },\n\n LogicalAnd_and(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '&&',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n LogicalAnd(e) {\n return e.toAST();\n },\n\n Equality_eq(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '==',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Equality_neq(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '!=',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Equality(e) {\n return e.toAST();\n },\n\n Comparison_gte(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '>=',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison_lte(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '<=',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison_gt(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '>',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison_lt(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '<',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison(e) {\n return e.toAST();\n },\n\n Additive_plus(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '+',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Additive_minus(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '-',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Additive(e) {\n return e.toAST();\n },\n\n Multiplicative_times(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '*',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Multiplicative_div(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '/',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Multiplicative_mod(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '%',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Multiplicative(e) {\n return e.toAST();\n },\n\n Unary_neg(_op, expr) {\n return { type: 'UnaryOp', op: '-', argument: expr.toAST() };\n },\n Unary_not(_op, expr) {\n return { type: 'UnaryOp', op: '!', argument: expr.toAST() };\n },\n Unary(e) {\n return e.toAST();\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const firstArg = args.children[0];\n const argList = firstArg ? firstArg.toAST() : [];\n return {\n type: 'CallExpression',\n callee: callee.toAST(),\n arguments: Array.isArray(argList) ? argList : [argList],\n };\n },\n Postfix_property(obj, _dot, prop) {\n return {\n type: 'MemberExpression',\n object: obj.toAST(),\n property: prop.sourceString,\n };\n },\n Postfix_index(obj, _lb, index, _rb) {\n const indexAST = index.toAST() as ASTNode;\n if (indexAST.type === 'StringLiteral') {\n return {\n type: 'BracketedMemberExpression',\n object: obj.toAST(),\n property: indexAST.value,\n };\n }\n return {\n type: 'IndexExpression',\n object: obj.toAST(),\n index: indexAST,\n };\n },\n Postfix_wildcard(obj, _lb, _star, _rb) {\n return {\n type: 'WildcardExpression',\n object: obj.toAST(),\n };\n },\n Postfix(e) {\n return e.toAST();\n },\n\n // Returns an array of arguments, not a single ASTNode\n // @ts-expect-error - intentionally returns array for function arguments\n Arguments(first, _comma, rest) {\n return [first.toAST(), ...rest.children.map((c) => c.toAST())];\n },\n\n Primary_paren(_lp, expr, _rp) {\n return expr.toAST();\n },\n Primary_bracketedField(_lb, str, _rb) {\n const strAST = str.toAST() as { type: 'StringLiteral'; value: string };\n return { type: 'BracketedIdentifier', name: strAST.value };\n },\n Primary(e) {\n return e.toAST();\n },\n\n number_float(_neg, _int, _dot, _frac) {\n return {\n type: 'NumberLiteral',\n value: Number.parseFloat(this.sourceString),\n };\n },\n number_int(_neg, _digits) {\n return {\n type: 'NumberLiteral',\n value: Number.parseInt(this.sourceString, 10),\n };\n },\n\n string(_open, chars, _close) {\n const raw = chars.sourceString;\n return { type: 'StringLiteral', value: raw.replaceAll(/\\\\(.)/g, '$1') };\n },\n\n boolean_true(_) {\n return { type: 'BooleanLiteral', value: true };\n },\n boolean_false(_) {\n return { type: 'BooleanLiteral', value: false };\n },\n\n null(_) {\n return { type: 'NullLiteral' };\n },\n\n identifier(_start, _rest) {\n return { type: 'Identifier', name: this.sourceString };\n },\n\n rootPath(_slash, _path) {\n return { type: 'RootPath', path: this.sourceString };\n },\n\n relativePath(_dotSlashes, _parts) {\n return { type: 'RelativePath', path: this.sourceString };\n },\n\n contextToken_at(_at, _path) {\n return { type: 'ContextToken', name: this.sourceString };\n },\n contextToken_hash(_hash, _path) {\n return { type: 'ContextToken', name: this.sourceString };\n },\n\n // @ts-expect-error - _iter returns array for iteration nodes\n _iter(...children) {\n return childrenToAST(children);\n },\n\n _terminal() {\n return { type: 'Identifier', name: this.sourceString };\n },\n});\n\n// ============ dependencies Operation ============\nsemantics.addOperation<string[]>('dependencies', {\n identifier(_start, _rest) {\n return [this.sourceString];\n },\n\n Primary_bracketedField(_lb, _str, _rb) {\n return [this.sourceString];\n },\n\n rootPath(_slash, _path) {\n return [this.sourceString];\n },\n\n relativePath(_dotSlashes, _parts) {\n return [this.sourceString];\n },\n\n contextToken_at(_at, _path) {\n return [];\n },\n contextToken_hash(_hash, _path) {\n return [];\n },\n\n Postfix_property(obj, _dot, prop) {\n const objDeps = obj.dependencies() as string[];\n if (objDeps.length === 1) {\n return [`${objDeps[0]}.${prop.sourceString}`];\n }\n return objDeps;\n },\n\n Postfix_index(obj, _lb, index, _rb) {\n const objDeps = obj.dependencies() as string[];\n const indexNode = index.toAST() as ASTNode;\n\n if (indexNode.type === 'StringLiteral') {\n const strValue = indexNode.value;\n const quote = this.sourceString.includes('\"') ? '\"' : \"'\";\n if (objDeps.length === 1) {\n return [`${objDeps[0]}[${quote}${strValue}${quote}]`];\n }\n return objDeps;\n }\n\n const getNumericIndex = (node: ASTNode): number | null => {\n if (node.type === 'NumberLiteral') {\n return node.value;\n }\n if (\n node.type === 'UnaryOp' &&\n node.op === '-' &&\n node.argument.type === 'NumberLiteral'\n ) {\n return -node.argument.value;\n }\n return null;\n };\n\n const numericIndex = getNumericIndex(indexNode);\n if (objDeps.length === 1 && numericIndex !== null) {\n return [`${objDeps[0]}[${numericIndex}]`];\n }\n return [...objDeps, ...(index.dependencies() as string[])];\n },\n\n Postfix_wildcard(obj, _lb, _star, _rb) {\n const objDeps = obj.dependencies() as string[];\n if (objDeps.length === 1) {\n return [`${objDeps[0]}[*]`];\n }\n return objDeps;\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const calleeDeps = callee.dependencies() as string[];\n const calleeAST = callee.toAST() as ASTNode;\n const argDeps = childrenDependencies(args.children);\n\n if (calleeAST.type === 'Identifier') {\n return argDeps;\n }\n return [...calleeDeps, ...argDeps];\n },\n\n number_float(_neg, _int, _dot, _frac) {\n return [];\n },\n number_int(_neg, _digits) {\n return [];\n },\n\n string(_open, _chars, _close) {\n return [];\n },\n\n boolean_true(_) {\n return [];\n },\n boolean_false(_) {\n return [];\n },\n\n null(_) {\n return [];\n },\n\n _nonterminal(...children) {\n return childrenDependencies(children);\n },\n\n _iter(...children) {\n return childrenDependencies(children);\n },\n\n _terminal() {\n return [];\n },\n});\n\n// ============ features Operation ============\nconst ARRAY_FUNCTIONS = new Set([\n 'sum',\n 'avg',\n 'count',\n 'first',\n 'last',\n 'join',\n 'includes',\n]);\n\nsemantics.addOperation<FormulaFeature[]>('features', {\n Primary_bracketedField(_lb, _str, _rb) {\n return ['bracket_notation'];\n },\n\n rootPath(_slash, _path) {\n const path = this.sourceString;\n const features: FormulaFeature[] = ['root_path'];\n if (path.includes('.')) {\n features.push('nested_path');\n }\n return features;\n },\n\n relativePath(_dotSlashes, _parts) {\n const path = this.sourceString;\n const features: FormulaFeature[] = ['relative_path'];\n const withoutPrefix = path.replace(/^(\\.\\.\\/)+/, '');\n if (withoutPrefix.includes('.')) {\n features.push('nested_path');\n }\n return features;\n },\n\n contextToken_at(_at, _path) {\n return ['context_token'];\n },\n contextToken_hash(_hash, _path) {\n return ['context_token'];\n },\n\n Postfix_property(obj, _dot, _prop) {\n const objFeatures = obj.features() as FormulaFeature[];\n return [...objFeatures, 'nested_path'];\n },\n\n Postfix_index(obj, _lb, index, _rb) {\n const objFeatures = obj.features() as FormulaFeature[];\n const indexFeatures = index.features() as FormulaFeature[];\n const indexNode = index.toAST() as ASTNode;\n if (indexNode.type === 'StringLiteral') {\n return [...objFeatures, ...indexFeatures, 'bracket_notation'];\n }\n return [...objFeatures, ...indexFeatures, 'array_index'];\n },\n\n Postfix_wildcard(obj, _lb, _star, _rb) {\n const objFeatures = obj.features() as FormulaFeature[];\n return [...objFeatures, 'array_wildcard'];\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const calleeAST = callee.toAST() as ASTNode;\n const argFeatures = childrenFeatures(args.children);\n\n if (\n calleeAST.type === 'Identifier' &&\n ARRAY_FUNCTIONS.has(calleeAST.name.toLowerCase())\n ) {\n return [...argFeatures, 'array_function'];\n }\n return argFeatures;\n },\n\n _nonterminal(...children) {\n return childrenFeatures(children);\n },\n\n _iter(...children) {\n return childrenFeatures(children);\n },\n\n _terminal() {\n return [];\n },\n});\n\n// ============ eval Operation ============\nconst BUILTINS: Record<string, (...args: unknown[]) => unknown> = {\n // Logical\n and: (a, b) => Boolean(a) && Boolean(b),\n or: (a, b) => Boolean(a) || Boolean(b),\n not: (a) => !a,\n\n // String\n concat: (...args) => args.map(String).join(''),\n upper: (s) => String(s).toUpperCase(),\n lower: (s) => String(s).toLowerCase(),\n trim: (s) => String(s).trim(),\n left: (s, n) => String(s).slice(0, Math.max(0, Math.floor(Number(n)))),\n right: (s, n) => {\n const str = String(s);\n const count = Math.max(0, Math.floor(Number(n)));\n return count === 0 ? '' : str.slice(-count);\n },\n replace: (s, search, repl) => String(s).replace(String(search), String(repl)),\n tostring: String,\n length: (s) => {\n if (Array.isArray(s)) return s.length;\n if (typeof s === 'string') return s.length;\n if (s !== null && typeof s === 'object') return Object.keys(s).length;\n return String(s).length;\n },\n contains: (s, search) => String(s).includes(String(search)),\n startswith: (s, search) => String(s).startsWith(String(search)),\n endswith: (s, search) => String(s).endsWith(String(search)),\n join: (arr: unknown, sep: unknown) => {\n if (!Array.isArray(arr)) return '';\n if (sep === undefined || sep === null) return arr.join(',');\n if (typeof sep !== 'string' && typeof sep !== 'number') {\n return arr.join(',');\n }\n return arr.join(String(sep));\n },\n\n // Numeric\n tonumber: Number,\n toboolean: Boolean,\n isnull: (v) => v === null || v === undefined,\n coalesce: (...args) =>\n args.find((v) => v !== null && v !== undefined) ?? null,\n round: (n, dec) => {\n const factor = 10 ** (dec === undefined ? 0 : Number(dec));\n return Math.round(Number(n) * factor) / factor;\n },\n floor: (n) => Math.floor(Number(n)),\n ceil: (n) => Math.ceil(Number(n)),\n abs: (n) => Math.abs(Number(n)),\n sqrt: (n) => Math.sqrt(Number(n)),\n pow: (base, exp) => Math.pow(Number(base), Number(exp)),\n min: (...args) =>\n args.length === 0 ? Number.NaN : Math.min(...args.map(Number)),\n max: (...args) =>\n args.length === 0 ? Number.NaN : Math.max(...args.map(Number)),\n log: (n) => Math.log(Number(n)),\n log10: (n) => Math.log10(Number(n)),\n exp: (n) => Math.exp(Number(n)),\n sign: (n) => Math.sign(Number(n)),\n\n // Array\n sum: (arr) =>\n Array.isArray(arr) ? arr.reduce((a, b) => a + Number(b), 0) : 0,\n avg: (arr) =>\n Array.isArray(arr) && arr.length > 0\n ? arr.reduce((a, b) => a + Number(b), 0) / arr.length\n : 0,\n count: (arr) => (Array.isArray(arr) ? arr.length : 0),\n first: (arr) => (Array.isArray(arr) ? arr[0] : undefined),\n last: (arr) => (Array.isArray(arr) ? arr.at(-1) : undefined),\n includes: (arr, val) => (Array.isArray(arr) ? arr.includes(val) : false),\n\n // Conditional\n if: (cond, ifTrue, ifFalse) => (cond ? ifTrue : ifFalse),\n};\n\nfunction getByPath(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current = obj;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\nsemantics.addOperation<unknown>('eval(ctx)', {\n Expression(e) {\n return e.eval(this.args.ctx);\n },\n\n Ternary_ternary(cond, _q, cons, _c, alt) {\n return cond.eval(this.args.ctx)\n ? cons.eval(this.args.ctx)\n : alt.eval(this.args.ctx);\n },\n Ternary(e) {\n return e.eval(this.args.ctx);\n },\n\n LogicalOr_or(left, _op, right) {\n return left.eval(this.args.ctx) || right.eval(this.args.ctx);\n },\n LogicalOr(e) {\n return e.eval(this.args.ctx);\n },\n\n LogicalAnd_and(left, _op, right) {\n return left.eval(this.args.ctx) && right.eval(this.args.ctx);\n },\n LogicalAnd(e) {\n return e.eval(this.args.ctx);\n },\n\n Equality_eq(left, _op, right) {\n return left.eval(this.args.ctx) == right.eval(this.args.ctx);\n },\n Equality_neq(left, _op, right) {\n return left.eval(this.args.ctx) != right.eval(this.args.ctx);\n },\n Equality(e) {\n return e.eval(this.args.ctx);\n },\n\n Comparison_gte(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) >=\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison_lte(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) <=\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison_gt(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) >\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison_lt(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) <\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison(e) {\n return e.eval(this.args.ctx);\n },\n\n Additive_plus(left, _op, right): unknown {\n const l = left.eval(this.args.ctx);\n const r = right.eval(this.args.ctx);\n if (typeof l === 'string' || typeof r === 'string') {\n return String(l) + String(r);\n }\n return (l as number) + (r as number);\n },\n Additive_minus(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) -\n (right.eval(this.args.ctx) as number)\n );\n },\n Additive(e) {\n return e.eval(this.args.ctx);\n },\n\n Multiplicative_times(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) *\n (right.eval(this.args.ctx) as number)\n );\n },\n Multiplicative_div(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) /\n (right.eval(this.args.ctx) as number)\n );\n },\n Multiplicative_mod(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) %\n (right.eval(this.args.ctx) as number)\n );\n },\n Multiplicative(e) {\n return e.eval(this.args.ctx);\n },\n\n Unary_neg(_op, expr) {\n return -(expr.eval(this.args.ctx) as number);\n },\n Unary_not(_op, expr) {\n return !expr.eval(this.args.ctx);\n },\n Unary(e) {\n return e.eval(this.args.ctx);\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const calleeAST = callee.toAST() as ASTNode;\n\n const getArgValues = (): unknown[] => {\n const argsNode = args.children[0];\n if (!argsNode) {\n return [];\n }\n return argsNode.eval(this.args.ctx) as unknown[];\n };\n\n if (calleeAST.type === 'Identifier') {\n const fnName = calleeAST.name.toLowerCase();\n const builtinFn = BUILTINS[fnName];\n if (builtinFn) {\n return builtinFn(...getArgValues());\n }\n }\n\n const fn = callee.eval(this.args.ctx);\n if (typeof fn === 'function') {\n return fn(...getArgValues());\n }\n\n const calleeName =\n calleeAST.type === 'Identifier' ? calleeAST.name : 'expression';\n throw new Error(`'${calleeName}' is not a function`);\n },\n Postfix_property(obj, _dot, prop) {\n const objVal = obj.eval(this.args.ctx) as Record<string, unknown>;\n return objVal?.[prop.sourceString];\n },\n Postfix_index(obj, _lb, index, _rb) {\n const objVal = obj.eval(this.args.ctx);\n const idx = index.eval(this.args.ctx);\n if (typeof idx === 'string') {\n if (!isSafePropertyName(idx)) {\n return undefined;\n }\n return (objVal as Record<string, unknown>)?.[idx];\n }\n const numIdx = idx as number;\n if (numIdx < 0) {\n return (objVal as unknown[])?.[(objVal as unknown[]).length + numIdx];\n }\n return (objVal as unknown[])?.[numIdx];\n },\n Postfix_wildcard(obj, _lb, _star, _rb) {\n return obj.eval(this.args.ctx);\n },\n Postfix(e) {\n return e.eval(this.args.ctx);\n },\n\n Arguments(first, _comma, rest) {\n return [\n first.eval(this.args.ctx),\n ...rest.children.map((c) => c.eval(this.args.ctx)),\n ];\n },\n\n Primary_paren(_lp, expr, _rp) {\n return expr.eval(this.args.ctx);\n },\n Primary_bracketedField(_lb, str, _rb) {\n const fieldName = str.eval(this.args.ctx) as string;\n if (!isSafePropertyName(fieldName)) {\n return undefined;\n }\n return this.args.ctx[fieldName];\n },\n Primary(e) {\n return e.eval(this.args.ctx);\n },\n\n number_float(_neg, _int, _dot, _frac) {\n return Number.parseFloat(this.sourceString);\n },\n number_int(_neg, _digits) {\n return Number.parseInt(this.sourceString, 10);\n },\n\n string(_open, chars, _close) {\n return chars.sourceString.replaceAll(/\\\\(.)/g, '$1');\n },\n\n boolean_true(_) {\n return true;\n },\n boolean_false(_) {\n return false;\n },\n\n null(_) {\n return null;\n },\n\n identifier(_start, _rest) {\n const name = this.sourceString;\n return this.args.ctx[name];\n },\n\n rootPath(_slash, _path) {\n const fullPath = this.sourceString;\n if (fullPath in this.args.ctx) {\n return this.args.ctx[fullPath];\n }\n const parts = fullPath.slice(1).split('.');\n const firstPart = parts[0];\n if (!firstPart) return undefined;\n const rootKey = '/' + firstPart;\n let value = this.args.ctx[rootKey];\n for (let i = 1; i < parts.length; i++) {\n if (value === null || value === undefined) return undefined;\n const part = parts[i];\n if (!part) continue;\n value = (value as Record<string, unknown>)[part];\n }\n return value;\n },\n\n relativePath(_dotSlashes, _parts) {\n const fullPath = this.sourceString;\n if (fullPath in this.args.ctx) {\n return this.args.ctx[fullPath];\n }\n const path = fullPath.replace(/^(\\.\\.\\/)+/, '');\n return getByPath(this.args.ctx, path);\n },\n\n contextToken_at(_at, _path) {\n return this.args.ctx[this.sourceString];\n },\n contextToken_hash(_hash, _path) {\n return this.args.ctx[this.sourceString];\n },\n\n _nonterminal(...children) {\n const ctx = this.args.ctx;\n for (const child of children) {\n if ('eval' in child) {\n return child.eval(ctx);\n }\n }\n return undefined;\n },\n\n _iter(...children) {\n return children.map((c) => c.eval(this.args.ctx));\n },\n\n _terminal() {\n return undefined;\n },\n});\n","import { grammar } from '../grammar';\nimport { semantics } from '../semantics';\nimport type { ASTNode } from './types';\nimport type {\n ArrayContext,\n ArrayLevelContext,\n FormulaFeature,\n FormulaMinorVersion,\n} from '../../types';\n\nfunction detectMinVersion(features: FormulaFeature[]): FormulaMinorVersion {\n if (features.includes('context_token')) {\n return '1.2';\n }\n if (features.length > 0) {\n return '1.1';\n }\n return '1.0';\n}\n\nexport interface ParseResult {\n ast: ASTNode;\n dependencies: string[];\n features: FormulaFeature[];\n minVersion: FormulaMinorVersion;\n}\n\nexport function parseFormula(expression: string): ParseResult {\n const trimmed = expression.trim();\n if (!trimmed) {\n throw new Error('Empty expression');\n }\n\n const matchResult = grammar.match(trimmed);\n if (matchResult.failed()) {\n throw new Error(matchResult.message ?? 'Parse error');\n }\n\n const adapter = semantics(matchResult);\n const ast = adapter.toAST() as ASTNode;\n const dependencies = [...new Set(adapter.dependencies() as string[])];\n const allFeatures = adapter.features() as FormulaFeature[];\n const features = [...new Set(allFeatures)];\n const minVersion: FormulaMinorVersion = detectMinVersion(features);\n\n return { ast, dependencies, features, minVersion };\n}\n\nexport function validateSyntax(\n expression: string,\n): { isValid: true } | { isValid: false; error: string; position?: number } {\n const trimmed = expression.trim();\n if (!trimmed) {\n return { isValid: false, error: 'Empty expression' };\n }\n\n const matchResult = grammar.match(trimmed);\n if (matchResult.failed()) {\n const pos = matchResult.getRightmostFailurePosition?.();\n return {\n isValid: false,\n error: matchResult.message ?? 'Parse error',\n position: pos,\n };\n }\n\n return { isValid: true };\n}\n\nexport function evaluate(\n expression: string,\n context: Record<string, unknown>,\n): unknown {\n const trimmed = expression.trim();\n if (!trimmed) {\n throw new Error('Empty expression');\n }\n\n const matchResult = grammar.match(trimmed);\n if (matchResult.failed()) {\n throw new Error(matchResult.message ?? 'Parse error');\n }\n\n const safeContext: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(context)) {\n if (typeof value !== 'function') {\n safeContext[key] = value;\n }\n }\n\n return semantics(matchResult).eval(safeContext);\n}\n\nexport interface EvaluateContextOptions {\n rootData: Record<string, unknown>;\n itemData?: Record<string, unknown>;\n currentPath?: string;\n arrayContext?: ArrayContext;\n}\n\nfunction parseCurrentPath(currentPath: string): string[] {\n const segments: string[] = [];\n let current = '';\n let inBracket = false;\n\n for (const char of currentPath) {\n if (char === '[') {\n inBracket = true;\n current += char;\n } else if (char === ']') {\n inBracket = false;\n current += char;\n } else if (char === '.' && !inBracket) {\n if (current) {\n segments.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n segments.push(current);\n }\n\n return segments;\n}\n\nfunction getValueByPath(data: Record<string, unknown>, path: string): unknown {\n const segments = parseCurrentPath(path);\n let current: unknown = data;\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined;\n }\n if (typeof current !== 'object') {\n return undefined;\n }\n\n const bracketMatch = /^([^[]+)\\[(\\d+)\\]$/.exec(segment);\n if (bracketMatch?.[1] && bracketMatch[2]) {\n const fieldName = bracketMatch[1];\n const index = Number.parseInt(bracketMatch[2], 10);\n const arr = (current as Record<string, unknown>)[fieldName];\n if (!Array.isArray(arr)) {\n return undefined;\n }\n current = arr[index];\n } else {\n current = (current as Record<string, unknown>)[segment];\n }\n }\n\n return current;\n}\n\nfunction extractRootField(fieldPath: string): string {\n const dotIndex = fieldPath.indexOf('.');\n const bracketIndex = fieldPath.indexOf('[');\n\n if (dotIndex === -1 && bracketIndex === -1) {\n return fieldPath;\n }\n if (dotIndex === -1) {\n return fieldPath.slice(0, bracketIndex);\n }\n if (bracketIndex === -1) {\n return fieldPath.slice(0, dotIndex);\n }\n return fieldPath.slice(0, Math.min(dotIndex, bracketIndex));\n}\n\nfunction countParentLevels(path: string): number {\n let count = 0;\n let remaining = path;\n while (remaining.startsWith('../')) {\n count++;\n remaining = remaining.slice(3);\n }\n return count;\n}\n\nfunction getPathAfterParents(path: string): string {\n return path.replace(/^(\\.\\.\\/)+/, '');\n}\n\nfunction resolveRelativePath(\n rootData: Record<string, unknown>,\n currentPath: string | undefined,\n relativePath: string,\n): unknown {\n const parentLevels = countParentLevels(relativePath);\n const fieldPath = getPathAfterParents(relativePath);\n\n if (!currentPath) {\n return getValueByPath(rootData, fieldPath);\n }\n\n const pathSegments = parseCurrentPath(currentPath);\n const targetLevel = pathSegments.length - parentLevels;\n\n if (targetLevel <= 0) {\n return getValueByPath(rootData, fieldPath);\n }\n\n const basePath = pathSegments.slice(0, targetLevel).join('.');\n const fullPath = basePath ? `${basePath}.${fieldPath}` : fieldPath;\n\n return getValueByPath(rootData, fullPath);\n}\n\nfunction extractRelativeBase(relativePath: string): string {\n const pathAfterParents = getPathAfterParents(relativePath);\n const baseField = extractRootField(pathAfterParents);\n const prefix = relativePath.slice(\n 0,\n relativePath.length - pathAfterParents.length,\n );\n return prefix + baseField;\n}\n\nfunction buildArrayContextTokens(\n arrayContext: ArrayContext | undefined,\n): Record<string, unknown> {\n if (!arrayContext || arrayContext.levels.length === 0) {\n return {};\n }\n\n const tokens: Record<string, unknown> = {};\n const levels = arrayContext.levels;\n\n const buildLevelTokens = (level: ArrayLevelContext, prefix: string): void => {\n tokens[`${prefix}index`] = level.index;\n tokens[`${prefix}length`] = level.length;\n tokens[`${prefix}first`] = level.index === 0;\n tokens[`${prefix}last`] = level.index === level.length - 1;\n };\n\n const buildNeighborTokens = (\n level: ArrayLevelContext,\n prefix: string,\n ): void => {\n tokens[`${prefix}prev`] = level.prev;\n tokens[`${prefix}next`] = level.next;\n };\n\n if (levels[0]) {\n buildLevelTokens(levels[0], '#');\n buildNeighborTokens(levels[0], '@');\n }\n\n let parentPrefix = '#parent.';\n let atParentPrefix = '@parent.';\n for (let i = 1; i < levels.length; i++) {\n const level = levels[i];\n if (level) {\n buildLevelTokens(level, parentPrefix);\n buildNeighborTokens(level, atParentPrefix);\n }\n parentPrefix = '#parent.' + parentPrefix.slice(1);\n atParentPrefix = '@parent.' + atParentPrefix.slice(1);\n }\n\n const rootLevel = levels.at(-1);\n if (rootLevel) {\n tokens['#root.index'] = rootLevel.index;\n tokens['#root.length'] = rootLevel.length;\n tokens['#root.first'] = rootLevel.index === 0;\n tokens['#root.last'] = rootLevel.index === rootLevel.length - 1;\n tokens['@root.prev'] = rootLevel.prev;\n tokens['@root.next'] = rootLevel.next;\n }\n\n return tokens;\n}\n\nfunction buildPathReferences(\n rootData: Record<string, unknown>,\n dependencies: string[],\n currentPath?: string,\n): Record<string, unknown> {\n const refs: Record<string, unknown> = {};\n\n for (const dep of dependencies) {\n if (dep.startsWith('/')) {\n const fieldPath = dep.slice(1);\n const rootField = extractRootField(fieldPath);\n const contextKey = '/' + rootField;\n if (!(contextKey in refs)) {\n refs[contextKey] = getValueByPath(rootData, rootField);\n }\n } else if (dep.startsWith('../')) {\n const contextKey = extractRelativeBase(dep);\n if (!(contextKey in refs)) {\n refs[contextKey] = resolveRelativePath(\n rootData,\n currentPath,\n contextKey,\n );\n }\n }\n }\n\n return refs;\n}\n\nexport function evaluateWithContext(\n expression: string,\n options: EvaluateContextOptions,\n): unknown {\n const { rootData, itemData, currentPath, arrayContext } = options;\n const trimmed = expression.trim();\n\n if (!trimmed) {\n throw new Error('Empty expression');\n }\n\n const parsed = parseFormula(trimmed);\n const pathRefs = buildPathReferences(\n rootData,\n parsed.dependencies,\n currentPath,\n );\n const arrayTokens = buildArrayContextTokens(arrayContext);\n\n const context: Record<string, unknown> = {\n ...rootData,\n ...itemData,\n ...pathRefs,\n ...arrayTokens,\n };\n\n return evaluate(trimmed, context);\n}\n\nexport type InferredType = 'number' | 'boolean' | 'string' | 'unknown';\n\nexport interface FieldTypes {\n [fieldName: string]: 'number' | 'string' | 'boolean' | 'object' | 'array';\n}\n\nconst ARITHMETIC_OPS = new Set(['+', '-', '*', '/', '%']);\nconst COMPARISON_OPS = new Set(['<', '>', '<=', '>=', '==', '!=']);\nconst LOGICAL_OPS = new Set(['&&', '||', '!']);\nconst NUMERIC_FUNCTIONS = new Set([\n 'round',\n 'floor',\n 'ceil',\n 'abs',\n 'sqrt',\n 'pow',\n 'min',\n 'max',\n 'log',\n 'log10',\n 'exp',\n 'sign',\n 'sum',\n 'avg',\n 'count',\n 'tonumber',\n 'length',\n]);\nconst STRING_FUNCTIONS = new Set([\n 'concat',\n 'upper',\n 'lower',\n 'trim',\n 'left',\n 'right',\n 'replace',\n 'tostring',\n 'join',\n]);\nconst BOOLEAN_FUNCTIONS = new Set([\n 'and',\n 'or',\n 'not',\n 'contains',\n 'startswith',\n 'endswith',\n 'isnull',\n 'toboolean',\n 'includes',\n]);\n\nfunction getFieldType(path: string, fieldTypes: FieldTypes): InferredType {\n const rootField = path.split('.')[0]?.split('[')[0] || path;\n const schemaType = fieldTypes[rootField];\n if (schemaType === 'number') return 'number';\n if (schemaType === 'string') return 'string';\n if (schemaType === 'boolean') return 'boolean';\n return 'unknown';\n}\n\nfunction inferLiteralType(node: ASTNode): InferredType | null {\n switch (node.type) {\n case 'NumberLiteral':\n return 'number';\n case 'BooleanLiteral':\n return 'boolean';\n case 'StringLiteral':\n return 'string';\n case 'NullLiteral':\n return 'unknown';\n default:\n return null;\n }\n}\n\nfunction inferBinaryOpType(\n node: ASTNode & { type: 'BinaryOp' },\n fieldTypes: FieldTypes,\n): InferredType {\n const { op } = node;\n if (op === '+') {\n const leftType = inferTypeFromAST(node.left, fieldTypes);\n const rightType = inferTypeFromAST(node.right, fieldTypes);\n if (leftType === 'string' || rightType === 'string') return 'string';\n if (leftType === 'unknown' || rightType === 'unknown') return 'unknown';\n return 'number';\n }\n if (ARITHMETIC_OPS.has(op)) return 'number';\n if (COMPARISON_OPS.has(op)) return 'boolean';\n if (LOGICAL_OPS.has(op)) return 'boolean';\n return 'unknown';\n}\n\nfunction inferCallExpressionType(\n node: ASTNode & { type: 'CallExpression' },\n fieldTypes: FieldTypes,\n): InferredType {\n const funcName =\n node.callee.type === 'Identifier' ? node.callee.name.toLowerCase() : '';\n if (NUMERIC_FUNCTIONS.has(funcName)) return 'number';\n if (STRING_FUNCTIONS.has(funcName)) return 'string';\n if (BOOLEAN_FUNCTIONS.has(funcName)) return 'boolean';\n if (funcName === 'if' && node.arguments.length >= 3) {\n const thenArg = node.arguments[1];\n const elseArg = node.arguments[2];\n if (thenArg && elseArg) {\n const thenType = inferTypeFromAST(thenArg, fieldTypes);\n const elseType = inferTypeFromAST(elseArg, fieldTypes);\n if (thenType === elseType) return thenType;\n }\n }\n return 'unknown';\n}\n\nfunction inferTypeFromAST(node: ASTNode, fieldTypes: FieldTypes): InferredType {\n const literalType = inferLiteralType(node);\n if (literalType !== null) return literalType;\n\n switch (node.type) {\n case 'Identifier':\n return getFieldType(node.name, fieldTypes);\n case 'RootPath':\n case 'RelativePath':\n case 'ContextToken':\n case 'IndexExpression':\n case 'WildcardExpression':\n return 'unknown';\n case 'MemberExpression': {\n const objectType = inferTypeFromAST(node.object, fieldTypes);\n if (objectType !== 'unknown') return objectType;\n if (node.object.type === 'Identifier') {\n return getFieldType(`${node.object.name}.${node.property}`, fieldTypes);\n }\n return 'unknown';\n }\n case 'BinaryOp':\n return inferBinaryOpType(node, fieldTypes);\n case 'UnaryOp': {\n if (node.op === '-') return 'number';\n if (node.op === '!') return 'boolean';\n return 'unknown';\n }\n case 'TernaryOp': {\n const thenType = inferTypeFromAST(node.consequent, fieldTypes);\n const elseType = inferTypeFromAST(node.alternate, fieldTypes);\n return thenType === elseType ? thenType : 'unknown';\n }\n case 'CallExpression':\n return inferCallExpressionType(node, fieldTypes);\n default:\n return 'unknown';\n }\n}\n\nexport function inferFormulaType(\n expression: string,\n fieldTypes: FieldTypes = {},\n): InferredType {\n const trimmed = expression.trim();\n if (!trimmed) {\n return 'unknown';\n }\n\n try {\n const { ast } = parseFormula(trimmed);\n return inferTypeFromAST(ast, fieldTypes);\n } catch {\n return 'unknown';\n }\n}\n","import type { ASTNode } from './types';\n\nfunction escapeDoubleQuoted(value: string): string {\n let result = '';\n for (const char of value) {\n switch (char) {\n case '\\\\':\n result += String.raw`\\\\`;\n break;\n case '\"':\n result += String.raw`\\\"`;\n break;\n case '\\n':\n result += String.raw`\\n`;\n break;\n case '\\r':\n result += String.raw`\\r`;\n break;\n case '\\t':\n result += String.raw`\\t`;\n break;\n default:\n result += char;\n }\n }\n return result;\n}\n\nconst PRECEDENCE: Record<string, number> = {\n '||': 1,\n '&&': 2,\n '==': 3,\n '!=': 3,\n '>': 4,\n '<': 4,\n '>=': 4,\n '<=': 4,\n '+': 5,\n '-': 5,\n '*': 6,\n '/': 6,\n '%': 6,\n};\n\nfunction serializeBinaryOp(node: ASTNode & { type: 'BinaryOp' }): string {\n const prec = PRECEDENCE[node.op] ?? 0;\n\n const wrapLeft = (child: ASTNode): string => {\n const s = serializeNode(child);\n if (child.type === 'BinaryOp') {\n const childPrec = PRECEDENCE[child.op] ?? 0;\n if (childPrec < prec) {\n return `(${s})`;\n }\n }\n if (child.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n };\n\n const wrapRight = (child: ASTNode): string => {\n const s = serializeNode(child);\n if (child.type === 'BinaryOp') {\n const childPrec = PRECEDENCE[child.op] ?? 0;\n if (childPrec <= prec) {\n return `(${s})`;\n }\n }\n if (child.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n };\n\n return `${wrapLeft(node.left)} ${node.op} ${wrapRight(node.right)}`;\n}\n\nfunction serializeNode(node: ASTNode): string {\n switch (node.type) {\n case 'NumberLiteral':\n return String(node.value);\n case 'StringLiteral':\n return `\"${escapeDoubleQuoted(node.value)}\"`;\n case 'BooleanLiteral':\n return String(node.value);\n case 'NullLiteral':\n return 'null';\n case 'Identifier':\n return node.name;\n case 'BracketedIdentifier':\n return `[\"${escapeDoubleQuoted(node.name)}\"]`;\n case 'RootPath':\n return node.path;\n case 'RelativePath':\n return node.path;\n case 'ContextToken':\n return node.name;\n case 'BinaryOp':\n return serializeBinaryOp(node);\n case 'UnaryOp':\n return `${node.op}${serializeUnaryArgument(node)}`;\n case 'TernaryOp':\n return `${serializeTernaryCondition(node.condition)} ? ${serializeNode(node.consequent)} : ${serializeNode(node.alternate)}`;\n case 'CallExpression':\n return `${serializeNode(node.callee)}(${node.arguments.map(serializeNode).join(', ')})`;\n case 'MemberExpression':\n return `${serializePostfixObject(node.object)}.${node.property}`;\n case 'BracketedMemberExpression':\n return `${serializePostfixObject(node.object)}[\"${escapeDoubleQuoted(node.property)}\"]`;\n case 'IndexExpression':\n return `${serializePostfixObject(node.object)}[${serializeNode(node.index)}]`;\n case 'WildcardExpression':\n return `${serializePostfixObject(node.object)}[*]`;\n }\n}\n\nfunction serializeUnaryArgument(node: ASTNode & { type: 'UnaryOp' }): string {\n const s = serializeNode(node.argument);\n if (node.argument.type === 'BinaryOp' || node.argument.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n}\n\nfunction serializeTernaryCondition(node: ASTNode): string {\n const s = serializeNode(node);\n if (node.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n}\n\nfunction serializePostfixObject(node: ASTNode): string {\n const s = serializeNode(node);\n if (\n node.type === 'BinaryOp' ||\n node.type === 'TernaryOp' ||\n node.type === 'UnaryOp'\n ) {\n return `(${s})`;\n }\n return s;\n}\n\nexport function serializeAst(ast: ASTNode): string {\n return serializeNode(ast);\n}\n","import type { ASTNode } from './types';\nimport { parseFormula } from './parser';\n\nfunction collectDependencyPath(node: ASTNode): string | null {\n switch (node.type) {\n case 'Identifier':\n return node.name;\n case 'BracketedIdentifier':\n return `[\"${node.name}\"]`;\n case 'RootPath':\n return node.path;\n case 'RelativePath':\n return node.path;\n case 'MemberExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n return `${objPath}.${node.property}`;\n }\n case 'BracketedMemberExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n const quote = '\"';\n return `${objPath}[${quote}${node.property}${quote}]`;\n }\n case 'IndexExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n const numericIndex = getNumericIndex(node.index);\n if (numericIndex !== null) {\n return `${objPath}[${numericIndex}]`;\n }\n return null;\n }\n case 'WildcardExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n return `${objPath}[*]`;\n }\n default:\n return null;\n }\n}\n\nfunction getNumericIndex(node: ASTNode): number | null {\n if (node.type === 'NumberLiteral') {\n return node.value;\n }\n if (\n node.type === 'UnaryOp' &&\n node.op === '-' &&\n node.argument.type === 'NumberLiteral'\n ) {\n return -node.argument.value;\n }\n return null;\n}\n\nfunction findMatch(\n node: ASTNode,\n replacements: Record<string, string>,\n): string | null {\n const fullPath = collectDependencyPath(node);\n if (fullPath !== null) {\n const value = replacements[fullPath];\n if (value !== undefined) {\n return value;\n }\n }\n return null;\n}\n\nfunction pathToAst(path: string): ASTNode {\n const { ast } = parseFormula(path);\n return ast;\n}\n\nfunction replaceNode(\n node: ASTNode,\n replacements: Record<string, string>,\n): ASTNode {\n const replacement = findMatch(node, replacements);\n if (replacement !== null) {\n return pathToAst(replacement);\n }\n\n switch (node.type) {\n case 'NumberLiteral':\n case 'StringLiteral':\n case 'BooleanLiteral':\n case 'NullLiteral':\n case 'Identifier':\n case 'BracketedIdentifier':\n case 'RootPath':\n case 'RelativePath':\n case 'ContextToken':\n return node;\n\n case 'BinaryOp':\n return {\n ...node,\n left: replaceNode(node.left, replacements),\n right: replaceNode(node.right, replacements),\n };\n\n case 'UnaryOp':\n return {\n ...node,\n argument: replaceNode(node.argument, replacements),\n };\n\n case 'TernaryOp':\n return {\n ...node,\n condition: replaceNode(node.condition, replacements),\n consequent: replaceNode(node.consequent, replacements),\n alternate: replaceNode(node.alternate, replacements),\n };\n\n case 'CallExpression': {\n const isSimpleFunctionCall = node.callee.type === 'Identifier';\n return {\n ...node,\n callee: isSimpleFunctionCall\n ? node.callee\n : replaceNode(node.callee, replacements),\n arguments: node.arguments.map((arg) => replaceNode(arg, replacements)),\n };\n }\n\n case 'MemberExpression':\n case 'BracketedMemberExpression':\n case 'WildcardExpression':\n return {\n ...node,\n object: replaceNode(node.object, replacements),\n };\n\n case 'IndexExpression':\n return {\n ...node,\n object: replaceNode(node.object, replacements),\n index: replaceNode(node.index, replacements),\n };\n }\n}\n\nexport function replaceDependencies(\n ast: ASTNode,\n replacements: Record<string, string>,\n): ASTNode {\n return replaceNode(ast, replacements);\n}\n","import { FormulaFeature, FormulaMinorVersion } from './types';\nimport { parseFormula } from './ohm';\n\nexport interface ParsedExpression {\n expression: string;\n dependencies: string[];\n minVersion: FormulaMinorVersion;\n features: FormulaFeature[];\n}\n\n/**\n * Parse a formula expression string\n *\n * @param expression - Formula expression string\n * @returns Parsed expression with dependencies and version info\n *\n * @example\n * parseExpression('price * 1.1')\n * // { expression: 'price * 1.1', dependencies: ['price'], minVersion: '1.0', features: [] }\n *\n * parseExpression('stats.damage * multiplier')\n * // { expression: '...', dependencies: ['stats.damage', 'multiplier'], minVersion: '1.1', features: ['nested_path'] }\n */\nexport function parseExpression(expression: string): ParsedExpression {\n const result = parseFormula(expression);\n return {\n expression,\n dependencies: result.dependencies,\n minVersion: result.minVersion,\n features: result.features,\n };\n}\n","import { validateSyntax } from './ohm';\n\nexport type SyntaxValidationResult =\n | { isValid: true }\n | { isValid: false; error: string; position?: number };\n\n/**\n * Validate formula expression syntax\n *\n * @param expression - Formula expression string\n * @returns Validation result with error details if invalid\n *\n * @example\n * validateFormulaSyntax('price * 1.1')\n * // { isValid: true }\n *\n * validateFormulaSyntax('price * (1.1')\n * // { isValid: false, error: 'Unclosed (', position: 8 }\n */\nexport function validateFormulaSyntax(\n expression: string,\n): SyntaxValidationResult {\n const result = validateSyntax(expression);\n\n if (result.isValid) {\n return { isValid: true };\n }\n\n return {\n isValid: false,\n error: result.error,\n position: result.position,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type SyntaxValidationResult = {
|
|
2
|
+
isValid: true;
|
|
3
|
+
} | {
|
|
4
|
+
isValid: false;
|
|
5
|
+
error: string;
|
|
6
|
+
position?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function validateFormulaSyntax(expression: string): SyntaxValidationResult;
|
|
9
|
+
//# sourceMappingURL=validate-syntax.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-syntax.d.ts","sourceRoot":"","sources":["../src/validate-syntax.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,sBAAsB,GAC9B;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAezD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAYxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revisium/formula",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Formula expression parser and evaluator for Revisium",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"formula",
|
|
@@ -21,36 +21,36 @@
|
|
|
21
21
|
".": {
|
|
22
22
|
"import": {
|
|
23
23
|
"types": "./dist/index.d.ts",
|
|
24
|
-
"default": "./dist/index.
|
|
24
|
+
"default": "./dist/index.mjs"
|
|
25
25
|
},
|
|
26
26
|
"require": {
|
|
27
|
-
"types": "./dist/index.d.
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
28
|
"default": "./dist/index.cjs"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"./editor": {
|
|
32
32
|
"import": {
|
|
33
33
|
"types": "./dist/editor/index.d.ts",
|
|
34
|
-
"default": "./dist/editor/index.
|
|
34
|
+
"default": "./dist/editor/index.mjs"
|
|
35
35
|
},
|
|
36
36
|
"require": {
|
|
37
|
-
"types": "./dist/editor/index.d.
|
|
37
|
+
"types": "./dist/editor/index.d.ts",
|
|
38
38
|
"default": "./dist/editor/index.cjs"
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"./spec": {
|
|
42
42
|
"import": {
|
|
43
43
|
"types": "./dist/formula-spec.d.ts",
|
|
44
|
-
"default": "./dist/formula-spec.
|
|
44
|
+
"default": "./dist/formula-spec.mjs"
|
|
45
45
|
},
|
|
46
46
|
"require": {
|
|
47
|
-
"types": "./dist/formula-spec.d.
|
|
47
|
+
"types": "./dist/formula-spec.d.ts",
|
|
48
48
|
"default": "./dist/formula-spec.cjs"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"main": "./dist/index.cjs",
|
|
53
|
-
"module": "./dist/index.
|
|
53
|
+
"module": "./dist/index.mjs",
|
|
54
54
|
"types": "./dist/index.d.ts",
|
|
55
55
|
"typesVersions": {
|
|
56
56
|
"*": {
|
|
@@ -67,8 +67,9 @@
|
|
|
67
67
|
],
|
|
68
68
|
"scripts": {
|
|
69
69
|
"generate:spec": "tsx scripts/generate-spec-md.ts",
|
|
70
|
-
"build": "
|
|
71
|
-
"
|
|
70
|
+
"build": "tsdown && npm run build:dts",
|
|
71
|
+
"build:dts": "tsc --emitDeclarationOnly --outDir dist --declaration --declarationMap",
|
|
72
|
+
"dev": "tsdown --watch",
|
|
72
73
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
|
73
74
|
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch",
|
|
74
75
|
"test:cov": "NODE_OPTIONS=--experimental-vm-modules jest --coverage --silent",
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
"jest": "^29.7.0",
|
|
93
94
|
"prettier": "^3.4.2",
|
|
94
95
|
"ts-jest": "^29.2.5",
|
|
95
|
-
"
|
|
96
|
+
"tsdown": "^0.20.1",
|
|
96
97
|
"tsx": "^4.21.0",
|
|
97
98
|
"typescript": "^5.7.2",
|
|
98
99
|
"typescript-eslint": "^8.15.0"
|