UNPKG

@andreasnicolaou/typescript-expression-language

Version:
895 lines (870 loc) 26.5 kB
import { LRUCache } from 'lru-cache'; /** * Represents a node in an abstract syntax tree (AST) for an expression language. * @class Node * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class Node { nodes: Record<string, Node>; attributes: Record<string, any>; constructor(nodes?: Record<string, Node>, attributes?: Record<string, any>); /** * Converts the Node instance to a string representation. * @returns The string representation of the Node. * @memberof Node */ toString(): string; /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof Node */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The attribute value. * @memberof Node */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof Node */ toArray(): any[]; /** * Dumps the node as a string. * @returns The dumped string representation. * @memberof Node */ dump(): string; /** * Escapes a string for use in dump output. * @param value - The string to escape. * @returns The escaped string. * @memberof Node */ protected dumpString(value: string): string; /** * Determines whether an array is a hash (non-sequential keys). * @param value - The array to check. * @returns True if the array is a hash, false otherwise. * @memberof Node */ protected isHash(value: Record<string | number, any>): boolean; } /** * Represents a compiler for an expression language. * @class Compiler * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class Compiler { private readonly functions; private source; constructor(functions: Record<string, any>); /** * Gets function * @param name * @returns function * @memberof Compiler */ getFunction(name: string): any; /** * Gets the current source code after compilation. * @returns string * @memberof Compiler */ getSource(): string; /** * Resets the state of the compiler. * @returns this * @memberof Compiler */ reset(): this; /** * Compiles a node. * @returns this * @memberof Compiler */ compile(node: Node): this; subcompile(node: Node): string; /** * Adds a raw string to the compiled code. * @returns this * @memberof Compiler */ raw(string: string): this; /** * Adds a quoted string to the compiled code. * @returns this * @memberof Compiler */ string(value: string): this; /** * Returns a representation of a given value. * @returns this * @memberof Compiler */ repr(value: any, isIdentifier?: boolean): this; } /** * Represents an array-like structure of an abstract syntax tree (AST) in the expression language. * @class ArrayNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class ArrayNode extends Node { protected index: number; protected keyIndex: number; protected arrayNodeType: 'Array' | 'Object'; constructor(); /** * Adds an element to the node. * @param value - The value node to add. * @param key - Optional key node. * @memberof ArrayNode */ addElement(value: Node, key?: Node | null): void; /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof ArrayNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The evaluated value. * @memberof ArrayNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any[] | Record<any, any>; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof ArrayNode */ toArray(): (string | Node)[]; /** * Retrieves key-value pairs from the node. * @returns An array of key-value pair objects. * @memberof ArrayNode */ protected getKeyValuePairs(): { key: Node; value: Node; }[]; /** * Compiles the node's arguments. * @param compiler - The Compiler instance. * @param withKeys - Whether to include keys in the compiled output. * @memberof ArrayNode */ protected compileArguments(compiler: Compiler, withKeys?: boolean): void; } /** * Represents a node for arguments of an abstract syntax tree (AST) in the expression language. * @class ArgumentsNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class ArgumentsNode extends ArrayNode { /** * Compiles the arguments * @param compiler - The Compiler instance to compile the node. * @memberof ArgumentsNode */ compile(compiler: Compiler): void; /** * Converts the arguments node into an array representation. * @returns An array of the node's arguments. * @memberof ArgumentsNode */ toArray(): (string | Node)[]; } /** * Represents a binary node in an abstract syntax tree (AST) for an expression language. * @class BinaryNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class BinaryNode extends Node { private static readonly OPERATORS; private static readonly FUNCTIONS; constructor(operator: string, left: Node, right: Node); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof BinaryNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The evaluated value. * @memberof ArrayNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof BinaryNode */ toArray(): (string | Node)[]; /** * Evaluates matches * @param regexp * @param str * @returns true if matches * @memberof BinaryNode */ private evaluateMatches; private pow; private range; private inArray; private notInArray; private strContains; private strStartsWith; private strEndsWith; } /** * Represents a conditional node in an abstract syntax tree (AST) for an expression language. * @class ConditionalNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class ConditionalNode extends Node { constructor(expr1: Node, expr2: Node, expr3: Node); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof ConditionalNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The evaluated value. * @memberof ConditionalNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof ConditionalNode */ toArray(): (string | Node)[]; } /** * Represents a constant node in an abstract syntax tree (AST) for an expression language. * @class ConstantNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class ConstantNode extends Node { isNullSafe: boolean; isIdentifier: boolean; constructor(value: any, isIdentifier?: boolean, isNullSafe?: boolean); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof ConstantNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param _functions - The available functions for evaluation. * @param _values - The current values for evaluation. * @returns The attribute value. * @memberof ConstantNode */ evaluate(_functions?: Record<string, any>, _values?: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof ConstantNode */ toArray(): (string | Node | number | bigint)[]; } /** * Represents a function node in an abstract syntax tree (AST) for an expression language. * @class FunctionNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class FunctionNode extends Node { constructor(name: string | number | null, argumentsNode: Node); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof FunctionNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The evaluated value. * @memberof FunctionNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof FunctionNode */ toArray(): (string | number | Node)[]; } /** * Represents a attribute node in an abstract syntax tree (AST) for an expression language. * @class GetAttrNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class GetAttrNode extends Node { static readonly PROPERTY_CALL = 1; static readonly METHOD_CALL = 2; static readonly ARRAY_CALL = 3; constructor(node: Node, attribute: Node, argumentsNode: ArrayNode, type: number); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof GetAttrNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The evaluated value. * @memberof GetAttrNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof GetAttrNode */ toArray(): (string | Node)[]; /** * Determines short circuited * @returns true if short circuited * @memberof GetAttrNode */ private isShortCircuited; } /** * Represents a name node in an abstract syntax tree (AST) for an expression language. * @class NameNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class NameNode extends Node { constructor(name: string | number | null); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof NameNode */ compile(compile: Compiler): void; /** * Evaluates the node. * @param _functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The attribute value. * @memberof NameNode */ evaluate(_functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof NameNode */ toArray(): string[]; } /** * Represents a null-coalesce in an abstract syntax tree (AST) for an expression language. * @class NullCoalesceNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class NullCoalesceNode extends Node { constructor(expr1: Node, expr2: Node); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof NullCoalesceNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The attribute value. * @memberof NullCoalesceNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof NullCoalesceNode */ toArray(): (string | Node)[]; /** * Adds null coalesce attribute to get attr nodes * @param node * @returns null coalesce attribute to get attr nodes * @memberof NullCoalesceNode */ private addNullCoalesceAttributeToGetAttrNodes; } /** * Represents a null-coalesced-name in an abstract syntax tree (AST) for an expression language. * @class NullCoalescedNameNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class NullCoalescedNameNode extends Node { constructor(name: string | number | null); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof NullCoalescedNameNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param _functions - The available functions for evaluation. * @param _values - The current values for evaluation. * @returns null. * @memberof NullCoalescedNameNode */ evaluate(_functions: Record<string, any>, _values: Record<string, any>): null; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof NullCoalescedNameNode */ toArray(): string[]; } /** * Represents a unary node in an abstract syntax tree (AST) for an expression language. * @class UnaryNode * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class UnaryNode extends Node { static readonly OPERATORS: Record<string, string>; constructor(operator: string | number | null, node: Node); /** * Compiles the node. * @param compiler - The Compiler instance. * @memberof UnaryNode */ compile(compiler: Compiler): void; /** * Evaluates the node. * @param functions - The available functions for evaluation. * @param values - The current values for evaluation. * @returns The attribute value. * @memberof UnaryNode */ evaluate(functions: Record<string, any>, values: Record<string, any>): any; /** * Converts the node to an array representation. * @returns The array representation of the node. * @memberof UnaryNode */ toArray(): (string | Node)[]; } /** * Represents an expression. * @class Expression * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class Expression { protected expression: string; constructor(expression: string); /** * Gets the expression. * @returns The string representation of the expression * @memberof Expression */ toString(): string; } /** * Represents an expression function in an expression language. * @class ExpressionFunction * @author Andreas Nicolaou <anicolaou66@gmail.com> */ type Callable = (...args: any[]) => any; declare class ExpressionFunction { private readonly name; private readonly compiler; private readonly evaluator; constructor(name: string, compiler: Callable, evaluator: Callable); /** * Creates an ExpressionFunction from a JavaScript function name. * @param jsFunctionName The JavaScript function name * @param expressionFunctionName The expression function name (optional) * @throws Error if the JavaScript function does not exist. * @memberof ExpressionFunction */ static fromJs(jsFunctionName: string, customFunction?: Callable, expressionFunctionName?: string): ExpressionFunction; /** * Gets name * @returns name * @memberof ExpressionFunction */ getName(): string; /** * Gets compiler * @returns compiler * @memberof ExpressionFunction */ getCompiler(): Callable; /** * Gets evaluator * @returns evaluator * @memberof ExpressionFunction */ getEvaluator(): Callable; /** * Resolves js function * @param jsFunctionName * @returns js function * @memberof ExpressionFunction */ protected static resolveJsFunction(jsFunctionName: string): unknown; } /** * Represents an already parsed expression. * @class ParsedExpression * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class ParsedExpression extends Expression { private readonly nodes; constructor(expression: string, nodes: Node); /** * Gets nodes * @returns nodes * @memberof ParsedExpression */ getNodes(): Node; } interface ExpressionFunctionProvider { getFunctions(): ExpressionFunction[]; } /** * Represents an expression language. * @class ExpressionLanguage * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class ExpressionLanguage { readonly cache: LRUCache<string, ParsedExpression>; private lexer?; private parser?; private compiler?; private functions; constructor(cache?: LRUCache<string, ParsedExpression>, providers?: Iterable<ExpressionFunctionProvider>); /** * Compiles an expression source code. * @param expression * @param names * @returns compile * @memberof ExpressionLanguage */ compile(expression: Expression | string, names: (string | Record<string, any>)[]): string; /** * Evaluates an expression. * @param expression * @param values * @returns evaluate * @memberof ExpressionLanguage */ evaluate(expression: Expression | string, values?: Record<string, any>): ParsedExpression; /** * Parses an expression. * @param expression * @param names * @param [flags] * @returns parse * @memberof ExpressionLanguage */ parse(expression: Expression | string, names: (string | Record<string, any>)[], flags?: number): ParsedExpression; /** * Validates the syntax of an expression. * @param expression * @param names * @param [flags] * @returns lint * @memberof ExpressionLanguage */ lint(expression: Expression | string, names: string[] | null, flags?: number): void; /** * Registers a function. * @param name * @param expressionFn * @memberof ExpressionLanguage */ register(name: string, expressionFn: ExpressionFunction): void; /** * Adds function. * @param functionObj * @memberof ExpressionLanguage */ addFunction(functionObj: ExpressionFunction): void; /** * Registers provider. * @param provider * @memberof ExpressionLanguage */ registerProvider(provider: ExpressionFunctionProvider): void; /** * Registers functions. * @memberof ExpressionLanguage */ private registerFunctions; /** * Gets the lexer. * @returns lexer * @memberof ExpressionLanguage */ private getLexer; /** * Gets the parser. * @returns parser * @memberof ExpressionLanguage */ private getParser; /** * Gets the compiler * @returns compiler * @memberof ExpressionLanguage */ private getCompiler; } /** * Represents a token. * @class Token * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class Token { type: string; value: string | number | null; cursor?: number | undefined; static readonly EOF_TYPE = "end of expression"; static readonly NAME_TYPE = "name"; static readonly NUMBER_TYPE = "number"; static readonly STRING_TYPE = "string"; static readonly OPERATOR_TYPE = "operator"; static readonly PUNCTUATION_TYPE = "punctuation"; constructor(type: string, value: string | number | null, cursor?: number | undefined); /** * A string representation of the token * @returns string * @memberof Token */ toString(): string; /** * Tests token for type and value * @param type * @param [value] * @returns true if test * @memberof Token */ test(type: string, value?: string | null): boolean; } /** * Represents a token stream. * @class TokenStream * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class TokenStream { readonly tokens: Token[]; readonly expression: string; current: Token; position: number; constructor(tokens: Token[], expression?: string); /** * Returns a string representation of the token stream. * @returns string * @memberof TokenStream */ toString(): string; /** * Sets the pointer to the next token and updates the current token. * @memberof TokenStream */ next(): void; /** * Checks if the current token matches the expected type and value. * Throws an error if it doesn't. * @param type * @param [value] * @param [message] * @memberof TokenStream */ expect(type: string, value?: string | null, message?: string | null): void; /** * Checks if the end of the token stream is reached. * @returns true if eof * @memberof TokenStream */ isEOF(): boolean; /** * Returns the original expression for debugging or internal use. * @returns expression * @memberof TokenStream */ getExpression(): string; } /** * Represents a lexer for an expression language. * @class Lexer * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class Lexer { private static readonly OPERATORS; private static readonly NUMBER_REGEX; private static readonly STRING_REGEX; private static readonly COMMENT_REGEX; private static readonly NAME_REGEX; /** * Tokenizes an expression. * @param expression * @returns tokenize * @throws SyntaxError * @memberof Lexer */ tokenize(expression: string): TokenStream; /** * Extracts the operator from the given string. * @private * @param {string} str * @param {string} originalExpression * @param {number} cursor * @return {*} {(string | null)} * @memberof Lexer */ private extractOperator; } /** * Represents a parser for an expression language. * @class Parser * @author Andreas Nicolaou <anicolaou66@gmail.com> */ type NameType = string | number | Record<string, any>; declare class Parser { private readonly functions; static readonly OPERATOR_LEFT = 1; static readonly OPERATOR_RIGHT = 2; static readonly IGNORE_UNKNOWN_VARIABLES = 1; static readonly IGNORE_UNKNOWN_FUNCTIONS = 2; private static readonly unaryOperators; private static readonly binaryOperators; private stream; private names; private flags; constructor(functions: Record<string, any>); /** * Converts a token stream to a node tree. * @param stream * @param [names] * @param [flags] * @returns parse * @throws SyntaxError * @memberof Parser */ parse(stream: TokenStream, names?: NameType[], flags?: number): Node; /** * Validates the syntax of an expression. * The syntax of the passed expression will be checked, but not parsed. * If you want to skip checking dynamic variable names, pass `Parser.IGNORE_UNKNOWN_VARIABLES` instead of the array. * @param stream * @param [names] * @param [flags] * @throws SyntaxError * @memberof Parser */ lint(stream: TokenStream, names?: string[] | null, flags?: number): void; /** * Parses the expression * @param [precedence] * @returns node expression * @memberof Parser */ parseExpression(precedence?: number): Node; /** * Parses primary expression * @returns primary expression * @memberof Parser */ parsePrimaryExpression(): Node; /** * Parses array expression * @returns array expression * @memberof Parser */ parseArrayExpression(): Node; /** * Parses hash expression * @returns hash expression * @memberof Parser */ parseHashExpression(): Node; /** * Parses postfix expression * @param node * @returns postfix expression * @memberof Parser */ parsePostfixExpression(node: Node): Node; /** * Parses arguments * @returns arguments * @memberof Parser */ parseArguments(): Node; /** * Parse the given expression * @param stream * @param names * @param flags * @returns parse * @throws SyntaxError * @memberof Parse */ private doParse; /** * Gets the primary node * @returns primary node * @memberof Parse */ private getPrimary; /** * Parses conditional expression * @param expr * @returns conditional expression * @memberof Parser */ private parseConditionalExpression; } /** * Represents an already serialized parsed expression. * @class SerializedParsedExpression * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class SerializedParsedExpression { readonly expression: string; private readonly nodes; constructor(expression: string, nodes: string); /** * Deserializes and returns the nodes. * @returns nodes * @memberof SerializedParsedExpression */ getNodes(): Node; } /** * Represents a syntax error in an expression. * @author Andreas Nicolaou <anicolaou66@gmail.com> */ declare class SyntaxError extends Error { constructor(message: string, cursor?: number | null, expression?: string, subject?: string | number | null, proposals?: (string | number)[] | null); } export { ArgumentsNode, ArrayNode, BinaryNode, Compiler, ConditionalNode, ConstantNode, Expression, ExpressionFunction, ExpressionLanguage, FunctionNode, GetAttrNode, Lexer, NameNode, Node, NullCoalesceNode, NullCoalescedNameNode, ParsedExpression, Parser, SerializedParsedExpression, SyntaxError, Token, TokenStream, UnaryNode }; export type { ExpressionFunctionProvider };