Breaking Changes¶
This document lists breaking changes between versions of @pro-fa/expreszo.
Audience: Developers upgrading between versions
For detailed migration instructions, see the Migration Guide.
Version 7.0.0¶
AST Replaces Stack-Based Bytecode¶
The internal representation changed from RPN instruction tokens to an immutable AST. This removes two public surface areas:
Expression.tokens— No longer exists. The AST is private. Useexpr.accept(visitor)to inspect expression structure.Instructiontype — Removed from the public API.
toJSFunction() Removed¶
Expression.toJSFunction() has been removed. It used new Function() with with statements, which is incompatible with strict mode and CSP.
Migration: Replace with a closure over evaluate():
Static Parser.parse() / Parser.evaluate() Removed¶
Create an instance instead:
Parser Recursion Depth Limit¶
The parser now enforces a maximum nesting depth of 256. Extremely deep expressions (300+ nested parentheses) will throw ParseError.
New APIs (Non-Breaking)¶
defineParser(config)— Descriptor-driven, tree-shakeable parser creation- Composable presets:
coreParser,withMath,withString,withArray,withObject,withComparison,withLogical,withTypeCheck,withUtility,fullParser - Subpath exports:
@pro-fa/expreszo/core,/math,/string, etc. Expression.accept(visitor)— AST visitor pattern- Types:
ParserConfig,ParserPreset
Version 6.0.0¶
Null Comparison Behavior¶
What Changed: Null comparisons now follow JavaScript semantics more closely. Previously, null == undefined returned true, but other null comparisons may have behaved unexpectedly.
Migration: Review expressions that compare values to null or undefined. Use the ?? (coalesce) operator for null/undefined fallback values.
Version 5.0.0¶
registerFunction Deprecated¶
What Changed: registerFunction() is deprecated. Use direct assignment to parser.functions instead.
Before:
After:
Protected Properties¶
Access to the following properties is now blocked to prevent prototype pollution attacks:
- __proto__
- prototype
- constructor
Attempting to access these properties in variable names or member expressions will throw an AccessError.
Example:
// These will throw AccessError
parser.evaluate('x.__proto__', { x: {} });
parser.evaluate('__proto__', { __proto__: {} });
Version 4.0.0¶
Concatenation Operator Changed from || to |¶
What Changed: The || operator was repurposed for logical OR (JavaScript-style). A new | (pipe) operator was introduced for array and string concatenation. Additionally, the && operator was added for logical AND.
Before (original expr-eval 2.x):
// || was used for concatenation
parser.evaluate('"hello" || " world"'); // "hello world"
parser.evaluate('[1, 2] || [3, 4]'); // [1, 2, 3, 4]
After (v4.0.0+):
// | is now used for concatenation
parser.evaluate('"hello" | " world"'); // "hello world"
parser.evaluate('[1, 2] | [3, 4]'); // [1, 2, 3, 4]
// || is now logical OR
parser.evaluate('true || false'); // true
parser.evaluate('false || true'); // true
// && is logical AND (new)
parser.evaluate('true && false'); // false
parser.evaluate('true && true'); // true
Migration Guide:
- Find concatenation usage: Search your expressions for
||used with strings or arrays - Replace with pipe: Change
||to|for concatenation operations - Review logical operations: If you were using
orkeyword, you can now also use||
Package Renamed¶
The package was renamed from expr-eval to @pro-fa/expreszo and ported to TypeScript.
Update imports: