"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { plugin: () => plugin2 }); module.exports = __toCommonJS(src_exports); // node_modules/jsonpath-plus/dist/index-node-esm.js var import_vm = __toESM(require("vm"), 1); var Hooks = class { /** * @callback HookCallback * @this {*|Jsep} this * @param {Jsep} env * @returns: void */ /** * Adds the given callback to the list of callbacks for the given hook. * * The callback will be invoked when the hook it is registered for is run. * * One callback function can be registered to multiple hooks and the same hook multiple times. * * @param {string|object} name The name of the hook, or an object of callbacks keyed by name * @param {HookCallback|boolean} callback The callback function which is given environment variables. * @param {?boolean} [first=false] Will add the hook to the top of the list (defaults to the bottom) * @public */ add(name, callback, first) { if (typeof arguments[0] != "string") { for (let name2 in arguments[0]) { this.add(name2, arguments[0][name2], arguments[1]); } } else { (Array.isArray(name) ? name : [name]).forEach(function(name2) { this[name2] = this[name2] || []; if (callback) { this[name2][first ? "unshift" : "push"](callback); } }, this); } } /** * Runs a hook invoking all registered callbacks with the given environment variables. * * Callbacks will be invoked synchronously and in the order in which they were registered. * * @param {string} name The name of the hook. * @param {Object} env The environment variables of the hook passed to all callbacks registered. * @public */ run(name, env) { this[name] = this[name] || []; this[name].forEach(function(callback) { callback.call(env && env.context ? env.context : env, env); }); } }; var Plugins = class { constructor(jsep2) { this.jsep = jsep2; this.registered = {}; } /** * @callback PluginSetup * @this {Jsep} jsep * @returns: void */ /** * Adds the given plugin(s) to the registry * * @param {object} plugins * @param {string} plugins.name The name of the plugin * @param {PluginSetup} plugins.init The init function * @public */ register(...plugins) { plugins.forEach((plugin3) => { if (typeof plugin3 !== "object" || !plugin3.name || !plugin3.init) { throw new Error("Invalid JSEP plugin format"); } if (this.registered[plugin3.name]) { return; } plugin3.init(this.jsep); this.registered[plugin3.name] = plugin3; }); } }; var Jsep = class _Jsep { /** * @returns {string} */ static get version() { return "1.4.0"; } /** * @returns {string} */ static toString() { return "JavaScript Expression Parser (JSEP) v" + _Jsep.version; } // ==================== CONFIG ================================ /** * @method addUnaryOp * @param {string} op_name The name of the unary op to add * @returns {Jsep} */ static addUnaryOp(op_name) { _Jsep.max_unop_len = Math.max(op_name.length, _Jsep.max_unop_len); _Jsep.unary_ops[op_name] = 1; return _Jsep; } /** * @method jsep.addBinaryOp * @param {string} op_name The name of the binary op to add * @param {number} precedence The precedence of the binary op (can be a float). Higher number = higher precedence * @param {boolean} [isRightAssociative=false] whether operator is right-associative * @returns {Jsep} */ static addBinaryOp(op_name, precedence, isRightAssociative) { _Jsep.max_binop_len = Math.max(op_name.length, _Jsep.max_binop_len); _Jsep.binary_ops[op_name] = precedence; if (isRightAssociative) { _Jsep.right_associative.add(op_name); } else { _Jsep.right_associative.delete(op_name); } return _Jsep; } /** * @method addIdentifierChar * @param {string} char The additional character to treat as a valid part of an identifier * @returns {Jsep} */ static addIdentifierChar(char) { _Jsep.additional_identifier_chars.add(char); return _Jsep; } /** * @method addLiteral * @param {string} literal_name The name of the literal to add * @param {*} literal_value The value of the literal * @returns {Jsep} */ static addLiteral(literal_name, literal_value) { _Jsep.literals[literal_name] = literal_value; return _Jsep; } /** * @method removeUnaryOp * @param {string} op_name The name of the unary op to remove * @returns {Jsep} */ static removeUnaryOp(op_name) { delete _Jsep.unary_ops[op_name]; if (op_name.length === _Jsep.max_unop_len) { _Jsep.max_unop_len = _Jsep.getMaxKeyLen(_Jsep.unary_ops); } return _Jsep; } /** * @method removeAllUnaryOps * @returns {Jsep} */ static removeAllUnaryOps() { _Jsep.unary_ops = {}; _Jsep.max_unop_len = 0; return _Jsep; } /** * @method removeIdentifierChar * @param {string} char The additional character to stop treating as a valid part of an identifier * @returns {Jsep} */ static removeIdentifierChar(char) { _Jsep.additional_identifier_chars.delete(char); return _Jsep; } /** * @method removeBinaryOp * @param {string} op_name The name of the binary op to remove * @returns {Jsep} */ static removeBinaryOp(op_name) { delete _Jsep.binary_ops[op_name]; if (op_name.length === _Jsep.max_binop_len) { _Jsep.max_binop_len = _Jsep.getMaxKeyLen(_Jsep.binary_ops); } _Jsep.right_associative.delete(op_name); return _Jsep; } /** * @method removeAllBinaryOps * @returns {Jsep} */ static removeAllBinaryOps() { _Jsep.binary_ops = {}; _Jsep.max_binop_len = 0; return _Jsep; } /** * @method removeLiteral * @param {string} literal_name The name of the literal to remove * @returns {Jsep} */ static removeLiteral(literal_name) { delete _Jsep.literals[literal_name]; return _Jsep; } /** * @method removeAllLiterals * @returns {Jsep} */ static removeAllLiterals() { _Jsep.literals = {}; return _Jsep; } // ==================== END CONFIG ============================ /** * @returns {string} */ get char() { return this.expr.charAt(this.index); } /** * @returns {number} */ get code() { return this.expr.charCodeAt(this.index); } /** * @param {string} expr a string with the passed in express * @returns Jsep */ constructor(expr) { this.expr = expr; this.index = 0; } /** * static top-level parser * @returns {jsep.Expression} */ static parse(expr) { return new _Jsep(expr).parse(); } /** * Get the longest key length of any object * @param {object} obj * @returns {number} */ static getMaxKeyLen(obj) { return Math.max(0, ...Object.keys(obj).map((k) => k.length)); } /** * `ch` is a character code in the next three functions * @param {number} ch * @returns {boolean} */ static isDecimalDigit(ch) { return ch >= 48 && ch <= 57; } /** * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float. * @param {string} op_val * @returns {number} */ static binaryPrecedence(op_val) { return _Jsep.binary_ops[op_val] || 0; } /** * Looks for start of identifier * @param {number} ch * @returns {boolean} */ static isIdentifierStart(ch) { return ch >= 65 && ch <= 90 || // A...Z ch >= 97 && ch <= 122 || // a...z ch >= 128 && !_Jsep.binary_ops[String.fromCharCode(ch)] || // any non-ASCII that is not an operator _Jsep.additional_identifier_chars.has(String.fromCharCode(ch)); } /** * @param {number} ch * @returns {boolean} */ static isIdentifierPart(ch) { return _Jsep.isIdentifierStart(ch) || _Jsep.isDecimalDigit(ch); } /** * throw error at index of the expression * @param {string} message * @throws */ throwError(message) { const error = new Error(message + " at character " + this.index); error.index = this.index; error.description = message; throw error; } /** * Run a given hook * @param {string} name * @param {jsep.Expression|false} [node] * @returns {?jsep.Expression} */ runHook(name, node) { if (_Jsep.hooks[name]) { const env = { context: this, node }; _Jsep.hooks.run(name, env); return env.node; } return node; } /** * Runs a given hook until one returns a node * @param {string} name * @returns {?jsep.Expression} */ searchHook(name) { if (_Jsep.hooks[name]) { const env = { context: this }; _Jsep.hooks[name].find(function(callback) { callback.call(env.context, env); return env.node; }); return env.node; } } /** * Push `index` up to the next non-space character */ gobbleSpaces() { let ch = this.code; while (ch === _Jsep.SPACE_CODE || ch === _Jsep.TAB_CODE || ch === _Jsep.LF_CODE || ch === _Jsep.CR_CODE) { ch = this.expr.charCodeAt(++this.index); } this.runHook("gobble-spaces"); } /** * Top-level method to parse all expressions and returns compound or single node * @returns {jsep.Expression} */ parse() { this.runHook("before-all"); const nodes = this.gobbleExpressions(); const node = nodes.length === 1 ? nodes[0] : { type: _Jsep.COMPOUND, body: nodes }; return this.runHook("after-all", node); } /** * top-level parser (but can be reused within as well) * @param {number} [untilICode] * @returns {jsep.Expression[]} */ gobbleExpressions(untilICode) { let nodes = [], ch_i, node; while (this.index < this.expr.length) { ch_i = this.code; if (ch_i === _Jsep.SEMCOL_CODE || ch_i === _Jsep.COMMA_CODE) { this.index++; } else { if (node = this.gobbleExpression()) { nodes.push(node); } else if (this.index < this.expr.length) { if (ch_i === untilICode) { break; } this.throwError('Unexpected "' + this.char + '"'); } } } return nodes; } /** * The main parsing function. * @returns {?jsep.Expression} */ gobbleExpression() { const node = this.searchHook("gobble-expression") || this.gobbleBinaryExpression(); this.gobbleSpaces(); return this.runHook("after-expression", node); } /** * Search for the operation portion of the string (e.g. `+`, `===`) * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`) * and move down from 3 to 2 to 1 character until a matching binary operation is found * then, return that binary operation * @returns {string|boolean} */ gobbleBinaryOp() { this.gobbleSpaces(); let to_check = this.expr.substr(this.index, _Jsep.max_binop_len); let tc_len = to_check.length; while (tc_len > 0) { if (_Jsep.binary_ops.hasOwnProperty(to_check) && (!_Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !_Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) { this.index += tc_len; return to_check; } to_check = to_check.substr(0, --tc_len); } return false; } /** * This function is responsible for gobbling an individual expression, * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)` * @returns {?jsep.BinaryExpression} */ gobbleBinaryExpression() { let node, biop, prec, stack, biop_info, left, right, i, cur_biop; left = this.gobbleToken(); if (!left) { return left; } biop = this.gobbleBinaryOp(); if (!biop) { return left; } biop_info = { value: biop, prec: _Jsep.binaryPrecedence(biop), right_a: _Jsep.right_associative.has(biop) }; right = this.gobbleToken(); if (!right) { this.throwError("Expected expression after " + biop); } stack = [left, biop_info, right]; while (biop = this.gobbleBinaryOp()) { prec = _Jsep.binaryPrecedence(biop); if (prec === 0) { this.index -= biop.length; break; } biop_info = { value: biop, prec, right_a: _Jsep.right_associative.has(biop) }; cur_biop = biop; const comparePrev = (prev) => biop_info.right_a && prev.right_a ? prec > prev.prec : prec <= prev.prec; while (stack.length > 2 && comparePrev(stack[stack.length - 2])) { right = stack.pop(); biop = stack.pop().value; left = stack.pop(); node = { type: _Jsep.BINARY_EXP, operator: biop, left, right }; stack.push(node); } node = this.gobbleToken(); if (!node) { this.throwError("Expected expression after " + cur_biop); } stack.push(biop_info, node); } i = stack.length - 1; node = stack[i]; while (i > 1) { node = { type: _Jsep.BINARY_EXP, operator: stack[i - 1].value, left: stack[i - 2], right: node }; i -= 2; } return node; } /** * An individual part of a binary expression: * e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis) * @returns {boolean|jsep.Expression} */ gobbleToken() { let ch, to_check, tc_len, node; this.gobbleSpaces(); node = this.searchHook("gobble-token"); if (node) { return this.runHook("after-token", node); } ch = this.code; if (_Jsep.isDecimalDigit(ch) || ch === _Jsep.PERIOD_CODE) { return this.gobbleNumericLiteral(); } if (ch === _Jsep.SQUOTE_CODE || ch === _Jsep.DQUOTE_CODE) { node = this.gobbleStringLiteral(); } else if (ch === _Jsep.OBRACK_CODE) { node = this.gobbleArray(); } else { to_check = this.expr.substr(this.index, _Jsep.max_unop_len); tc_len = to_check.length; while (tc_len > 0) { if (_Jsep.unary_ops.hasOwnProperty(to_check) && (!_Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !_Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) { this.index += tc_len; const argument = this.gobbleToken(); if (!argument) { this.throwError("missing unaryOp argument"); } return this.runHook("after-token", { type: _Jsep.UNARY_EXP, operator: to_check, argument, prefix: true }); } to_check = to_check.substr(0, --tc_len); } if (_Jsep.isIdentifierStart(ch)) { node = this.gobbleIdentifier(); if (_Jsep.literals.hasOwnProperty(node.name)) { node = { type: _Jsep.LITERAL, value: _Jsep.literals[node.name], raw: node.name }; } else if (node.name === _Jsep.this_str) { node = { type: _Jsep.THIS_EXP }; } } else if (ch === _Jsep.OPAREN_CODE) { node = this.gobbleGroup(); } } if (!node) { return this.runHook("after-token", false); } node = this.gobbleTokenProperty(node); return this.runHook("after-token", node); } /** * Gobble properties of of identifiers/strings/arrays/groups. * e.g. `foo`, `bar.baz`, `foo['bar'].baz` * It also gobbles function calls: * e.g. `Math.acos(obj.angle)` * @param {jsep.Expression} node * @returns {jsep.Expression} */ gobbleTokenProperty(node) { this.gobbleSpaces(); let ch = this.code; while (ch === _Jsep.PERIOD_CODE || ch === _Jsep.OBRACK_CODE || ch === _Jsep.OPAREN_CODE || ch === _Jsep.QUMARK_CODE) { let optional; if (ch === _Jsep.QUMARK_CODE) { if (this.expr.charCodeAt(this.index + 1) !== _Jsep.PERIOD_CODE) { break; } optional = true; this.index += 2; this.gobbleSpaces(); ch = this.code; } this.index++; if (ch === _Jsep.OBRACK_CODE) { node = { type: _Jsep.MEMBER_EXP, computed: true, object: node, property: this.gobbleExpression() }; if (!node.property) { this.throwError('Unexpected "' + this.char + '"'); } this.gobbleSpaces(); ch = this.code; if (ch !== _Jsep.CBRACK_CODE) { this.throwError("Unclosed ["); } this.index++; } else if (ch === _Jsep.OPAREN_CODE) { node = { type: _Jsep.CALL_EXP, "arguments": this.gobbleArguments(_Jsep.CPAREN_CODE), callee: node }; } else if (ch === _Jsep.PERIOD_CODE || optional) { if (optional) { this.index--; } this.gobbleSpaces(); node = { type: _Jsep.MEMBER_EXP, computed: false, object: node, property: this.gobbleIdentifier() }; } if (optional) { node.optional = true; } this.gobbleSpaces(); ch = this.code; } return node; } /** * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to * keep track of everything in the numeric literal and then calling `parseFloat` on that string * @returns {jsep.Literal} */ gobbleNumericLiteral() { let number = "", ch, chCode; while (_Jsep.isDecimalDigit(this.code)) { number += this.expr.charAt(this.index++); } if (this.code === _Jsep.PERIOD_CODE) { number += this.expr.charAt(this.index++); while (_Jsep.isDecimalDigit(this.code)) { number += this.expr.charAt(this.index++); } } ch = this.char; if (ch === "e" || ch === "E") { number += this.expr.charAt(this.index++); ch = this.char; if (ch === "+" || ch === "-") { number += this.expr.charAt(this.index++); } while (_Jsep.isDecimalDigit(this.code)) { number += this.expr.charAt(this.index++); } if (!_Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1))) { this.throwError("Expected exponent (" + number + this.char + ")"); } } chCode = this.code; if (_Jsep.isIdentifierStart(chCode)) { this.throwError("Variable names cannot start with a number (" + number + this.char + ")"); } else if (chCode === _Jsep.PERIOD_CODE || number.length === 1 && number.charCodeAt(0) === _Jsep.PERIOD_CODE) { this.throwError("Unexpected period"); } return { type: _Jsep.LITERAL, value: parseFloat(number), raw: number }; } /** * Parses a string literal, staring with single or double quotes with basic support for escape codes * e.g. `"hello world"`, `'this is\nJSEP'` * @returns {jsep.Literal} */ gobbleStringLiteral() { let str = ""; const startIndex = this.index; const quote = this.expr.charAt(this.index++); let closed = false; while (this.index < this.expr.length) { let ch = this.expr.charAt(this.index++); if (ch === quote) { closed = true; break; } else if (ch === "\\") { ch = this.expr.charAt(this.index++); switch (ch) { case "n": str += "\n"; break; case "r": str += "\r"; break; case "t": str += " "; break; case "b": str += "\b"; break; case "f": str += "\f"; break; case "v": str += "\v"; break; default: str += ch; } } else { str += ch; } } if (!closed) { this.throwError('Unclosed quote after "' + str + '"'); } return { type: _Jsep.LITERAL, value: str, raw: this.expr.substring(startIndex, this.index) }; } /** * Gobbles only identifiers * e.g.: `foo`, `_value`, `$x1` * Also, this function checks if that identifier is a literal: * (e.g. `true`, `false`, `null`) or `this` * @returns {jsep.Identifier} */ gobbleIdentifier() { let ch = this.code, start = this.index; if (_Jsep.isIdentifierStart(ch)) { this.index++; } else { this.throwError("Unexpected " + this.char); } while (this.index < this.expr.length) { ch = this.code; if (_Jsep.isIdentifierPart(ch)) { this.index++; } else { break; } } return { type: _Jsep.IDENTIFIER, name: this.expr.slice(start, this.index) }; } /** * Gobbles a list of arguments within the context of a function call * or array literal. This function also assumes that the opening character * `(` or `[` has already been gobbled, and gobbles expressions and commas * until the terminator character `)` or `]` is encountered. * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]` * @param {number} termination * @returns {jsep.Expression[]} */ gobbleArguments(termination) { const args = []; let closed = false; let separator_count = 0; while (this.index < this.expr.length) { this.gobbleSpaces(); let ch_i = this.code; if (ch_i === termination) { closed = true; this.index++; if (termination === _Jsep.CPAREN_CODE && separator_count && separator_count >= args.length) { this.throwError("Unexpected token " + String.fromCharCode(termination)); } break; } else if (ch_i === _Jsep.COMMA_CODE) { this.index++; separator_count++; if (separator_count !== args.length) { if (termination === _Jsep.CPAREN_CODE) { this.throwError("Unexpected token ,"); } else if (termination === _Jsep.CBRACK_CODE) { for (let arg = args.length; arg < separator_count; arg++) { args.push(null); } } } } else if (args.length !== separator_count && separator_count !== 0) { this.throwError("Expected comma"); } else { const node = this.gobbleExpression(); if (!node || node.type === _Jsep.COMPOUND) { this.throwError("Expected comma"); } args.push(node); } } if (!closed) { this.throwError("Expected " + String.fromCharCode(termination)); } return args; } /** * Responsible for parsing a group of things within parentheses `()` * that have no identifier in front (so not a function call) * This function assumes that it needs to gobble the opening parenthesis * and then tries to gobble everything within that parenthesis, assuming * that the next thing it should see is the close parenthesis. If not, * then the expression probably doesn't have a `)` * @returns {boolean|jsep.Expression} */ gobbleGroup() { this.index++; let nodes = this.gobbleExpressions(_Jsep.CPAREN_CODE); if (this.code === _Jsep.CPAREN_CODE) { this.index++; if (nodes.length === 1) { return nodes[0]; } else if (!nodes.length) { return false; } else { return { type: _Jsep.SEQUENCE_EXP, expressions: nodes }; } } else { this.throwError("Unclosed ("); } } /** * Responsible for parsing Array literals `[1, 2, 3]` * This function assumes that it needs to gobble the opening bracket * and then tries to gobble the expressions as arguments. * @returns {jsep.ArrayExpression} */ gobbleArray() { this.index++; return { type: _Jsep.ARRAY_EXP, elements: this.gobbleArguments(_Jsep.CBRACK_CODE) }; } }; var hooks = new Hooks(); Object.assign(Jsep, { hooks, plugins: new Plugins(Jsep), // Node Types // ---------- // This is the full set of types that any JSEP node can be. // Store them here to save space when minified COMPOUND: "Compound", SEQUENCE_EXP: "SequenceExpression", IDENTIFIER: "Identifier", MEMBER_EXP: "MemberExpression", LITERAL: "Literal", THIS_EXP: "ThisExpression", CALL_EXP: "CallExpression", UNARY_EXP: "UnaryExpression", BINARY_EXP: "BinaryExpression", ARRAY_EXP: "ArrayExpression", TAB_CODE: 9, LF_CODE: 10, CR_CODE: 13, SPACE_CODE: 32, PERIOD_CODE: 46, // '.' COMMA_CODE: 44, // ',' SQUOTE_CODE: 39, // single quote DQUOTE_CODE: 34, // double quotes OPAREN_CODE: 40, // ( CPAREN_CODE: 41, // ) OBRACK_CODE: 91, // [ CBRACK_CODE: 93, // ] QUMARK_CODE: 63, // ? SEMCOL_CODE: 59, // ; COLON_CODE: 58, // : // Operations // ---------- // Use a quickly-accessible map to store all of the unary operators // Values are set to `1` (it really doesn't matter) unary_ops: { "-": 1, "!": 1, "~": 1, "+": 1 }, // Also use a map for the binary operations but set their values to their // binary precedence for quick reference (higher number = higher precedence) // see [Order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) binary_ops: { "||": 1, "??": 1, "&&": 2, "|": 3, "^": 4, "&": 5, "==": 6, "!=": 6, "===": 6, "!==": 6, "<": 7, ">": 7, "<=": 7, ">=": 7, "<<": 8, ">>": 8, ">>>": 8, "+": 9, "-": 9, "*": 10, "/": 10, "%": 10, "**": 11 }, // sets specific binary_ops as right-associative right_associative: /* @__PURE__ */ new Set(["**"]), // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char) additional_identifier_chars: /* @__PURE__ */ new Set(["$", "_"]), // Literals // ---------- // Store the values to return for the various literals we may encounter literals: { "true": true, "false": false, "null": null }, // Except for `this`, which is special. This could be changed to something like `'self'` as well this_str: "this" }); Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops); Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops); var jsep = (expr) => new Jsep(expr).parse(); var stdClassProps = Object.getOwnPropertyNames(class Test { }); Object.getOwnPropertyNames(Jsep).filter((prop) => !stdClassProps.includes(prop) && jsep[prop] === void 0).forEach((m) => { jsep[m] = Jsep[m]; }); jsep.Jsep = Jsep; var CONDITIONAL_EXP = "ConditionalExpression"; var ternary = { name: "ternary", init(jsep2) { jsep2.hooks.add("after-expression", function gobbleTernary(env) { if (env.node && this.code === jsep2.QUMARK_CODE) { this.index++; const test = env.node; const consequent = this.gobbleExpression(); if (!consequent) { this.throwError("Expected expression"); } this.gobbleSpaces(); if (this.code === jsep2.COLON_CODE) { this.index++; const alternate = this.gobbleExpression(); if (!alternate) { this.throwError("Expected expression"); } env.node = { type: CONDITIONAL_EXP, test, consequent, alternate }; if (test.operator && jsep2.binary_ops[test.operator] <= 0.9) { let newTest = test; while (newTest.right.operator && jsep2.binary_ops[newTest.right.operator] <= 0.9) { newTest = newTest.right; } env.node.test = newTest.right; newTest.right = env.node; env.node = test; } } else { this.throwError("Expected :"); } } }); } }; jsep.plugins.register(ternary); var FSLASH_CODE = 47; var BSLASH_CODE = 92; var index = { name: "regex", init(jsep2) { jsep2.hooks.add("gobble-token", function gobbleRegexLiteral(env) { if (this.code === FSLASH_CODE) { const patternIndex = ++this.index; let inCharSet = false; while (this.index < this.expr.length) { if (this.code === FSLASH_CODE && !inCharSet) { const pattern = this.expr.slice(patternIndex, this.index); let flags = ""; while (++this.index < this.expr.length) { const code = this.code; if (code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57) { flags += this.char; } else { break; } } let value; try { value = new RegExp(pattern, flags); } catch (e) { this.throwError(e.message); } env.node = { type: jsep2.LITERAL, value, raw: this.expr.slice(patternIndex - 1, this.index) }; env.node = this.gobbleTokenProperty(env.node); return env.node; } if (this.code === jsep2.OBRACK_CODE) { inCharSet = true; } else if (inCharSet && this.code === jsep2.CBRACK_CODE) { inCharSet = false; } this.index += this.code === BSLASH_CODE ? 2 : 1; } this.throwError("Unclosed Regex"); } }); } }; var PLUS_CODE = 43; var MINUS_CODE = 45; var plugin = { name: "assignment", assignmentOperators: /* @__PURE__ */ new Set(["=", "*=", "**=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", "||=", "&&=", "??="]), updateOperators: [PLUS_CODE, MINUS_CODE], assignmentPrecedence: 0.9, init(jsep2) { const updateNodeTypes = [jsep2.IDENTIFIER, jsep2.MEMBER_EXP]; plugin.assignmentOperators.forEach((op) => jsep2.addBinaryOp(op, plugin.assignmentPrecedence, true)); jsep2.hooks.add("gobble-token", function gobbleUpdatePrefix(env) { const code = this.code; if (plugin.updateOperators.some((c) => c === code && c === this.expr.charCodeAt(this.index + 1))) { this.index += 2; env.node = { type: "UpdateExpression", operator: code === PLUS_CODE ? "++" : "--", argument: this.gobbleTokenProperty(this.gobbleIdentifier()), prefix: true }; if (!env.node.argument || !updateNodeTypes.includes(env.node.argument.type)) { this.throwError(`Unexpected ${env.node.operator}`); } } }); jsep2.hooks.add("after-token", function gobbleUpdatePostfix(env) { if (env.node) { const code = this.code; if (plugin.updateOperators.some((c) => c === code && c === this.expr.charCodeAt(this.index + 1))) { if (!updateNodeTypes.includes(env.node.type)) { this.throwError(`Unexpected ${env.node.operator}`); } this.index += 2; env.node = { type: "UpdateExpression", operator: code === PLUS_CODE ? "++" : "--", argument: env.node, prefix: false }; } } }); jsep2.hooks.add("after-expression", function gobbleAssignment(env) { if (env.node) { updateBinariesToAssignments(env.node); } }); function updateBinariesToAssignments(node) { if (plugin.assignmentOperators.has(node.operator)) { node.type = "AssignmentExpression"; updateBinariesToAssignments(node.left); updateBinariesToAssignments(node.right); } else if (!node.operator) { Object.values(node).forEach((val) => { if (val && typeof val === "object") { updateBinariesToAssignments(val); } }); } } } }; jsep.plugins.register(index, plugin); jsep.addUnaryOp("typeof"); jsep.addLiteral("null", null); jsep.addLiteral("undefined", void 0); var BLOCKED_PROTO_PROPERTIES = /* @__PURE__ */ new Set(["constructor", "__proto__", "__defineGetter__", "__defineSetter__"]); var SafeEval = { /** * @param {jsep.Expression} ast * @param {Record} subs */ evalAst(ast, subs) { switch (ast.type) { case "BinaryExpression": case "LogicalExpression": return SafeEval.evalBinaryExpression(ast, subs); case "Compound": return SafeEval.evalCompound(ast, subs); case "ConditionalExpression": return SafeEval.evalConditionalExpression(ast, subs); case "Identifier": return SafeEval.evalIdentifier(ast, subs); case "Literal": return SafeEval.evalLiteral(ast, subs); case "MemberExpression": return SafeEval.evalMemberExpression(ast, subs); case "UnaryExpression": return SafeEval.evalUnaryExpression(ast, subs); case "ArrayExpression": return SafeEval.evalArrayExpression(ast, subs); case "CallExpression": return SafeEval.evalCallExpression(ast, subs); case "AssignmentExpression": return SafeEval.evalAssignmentExpression(ast, subs); default: throw SyntaxError("Unexpected expression", ast); } }, evalBinaryExpression(ast, subs) { const result = { "||": (a, b) => a || b(), "&&": (a, b) => a && b(), "|": (a, b) => a | b(), "^": (a, b) => a ^ b(), "&": (a, b) => a & b(), // eslint-disable-next-line eqeqeq -- API "==": (a, b) => a == b(), // eslint-disable-next-line eqeqeq -- API "!=": (a, b) => a != b(), "===": (a, b) => a === b(), "!==": (a, b) => a !== b(), "<": (a, b) => a < b(), ">": (a, b) => a > b(), "<=": (a, b) => a <= b(), ">=": (a, b) => a >= b(), "<<": (a, b) => a << b(), ">>": (a, b) => a >> b(), ">>>": (a, b) => a >>> b(), "+": (a, b) => a + b(), "-": (a, b) => a - b(), "*": (a, b) => a * b(), "/": (a, b) => a / b(), "%": (a, b) => a % b() }[ast.operator](SafeEval.evalAst(ast.left, subs), () => SafeEval.evalAst(ast.right, subs)); return result; }, evalCompound(ast, subs) { let last; for (let i = 0; i < ast.body.length; i++) { if (ast.body[i].type === "Identifier" && ["var", "let", "const"].includes(ast.body[i].name) && ast.body[i + 1] && ast.body[i + 1].type === "AssignmentExpression") { i += 1; } const expr = ast.body[i]; last = SafeEval.evalAst(expr, subs); } return last; }, evalConditionalExpression(ast, subs) { if (SafeEval.evalAst(ast.test, subs)) { return SafeEval.evalAst(ast.consequent, subs); } return SafeEval.evalAst(ast.alternate, subs); }, evalIdentifier(ast, subs) { if (Object.hasOwn(subs, ast.name)) { return subs[ast.name]; } throw ReferenceError(`${ast.name} is not defined`); }, evalLiteral(ast) { return ast.value; }, evalMemberExpression(ast, subs) { const prop = String( // NOTE: `String(value)` throws error when // value has overwritten the toString method to return non-string // i.e. `value = {toString: () => []}` ast.computed ? SafeEval.evalAst(ast.property) : ast.property.name // `object.property` property is Identifier ); const obj = SafeEval.evalAst(ast.object, subs); if (obj === void 0 || obj === null) { throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`); } if (!Object.hasOwn(obj, prop) && BLOCKED_PROTO_PROPERTIES.has(prop)) { throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`); } const result = obj[prop]; if (typeof result === "function") { return result.bind(obj); } return result; }, evalUnaryExpression(ast, subs) { const result = { "-": (a) => -SafeEval.evalAst(a, subs), "!": (a) => !SafeEval.evalAst(a, subs), "~": (a) => ~SafeEval.evalAst(a, subs), // eslint-disable-next-line no-implicit-coercion -- API "+": (a) => +SafeEval.evalAst(a, subs), typeof: (a) => typeof SafeEval.evalAst(a, subs) }[ast.operator](ast.argument); return result; }, evalArrayExpression(ast, subs) { return ast.elements.map((el) => SafeEval.evalAst(el, subs)); }, evalCallExpression(ast, subs) { const args = ast.arguments.map((arg) => SafeEval.evalAst(arg, subs)); const func = SafeEval.evalAst(ast.callee, subs); return func(...args); }, evalAssignmentExpression(ast, subs) { if (ast.left.type !== "Identifier") { throw SyntaxError("Invalid left-hand side in assignment"); } const id = ast.left.name; const value = SafeEval.evalAst(ast.right, subs); subs[id] = value; return subs[id]; } }; var SafeScript = class { /** * @param {string} expr Expression to evaluate */ constructor(expr) { this.code = expr; this.ast = jsep(this.code); } /** * @param {object} context Object whose items will be added * to evaluation * @returns {EvaluatedResult} Result of evaluated code */ runInNewContext(context) { const keyMap = Object.assign(/* @__PURE__ */ Object.create(null), context); return SafeEval.evalAst(this.ast, keyMap); } }; function push(arr, item) { arr = arr.slice(); arr.push(item); return arr; } function unshift(item, arr) { arr = arr.slice(); arr.unshift(item); return arr; } var NewError = class extends Error { /** * @param {AnyResult} value The evaluated scalar value */ constructor(value) { super('JSONPath should not be called with "new" (it prevents return of (unwrapped) scalar values)'); this.avoidNew = true; this.value = value; this.name = "NewError"; } }; function JSONPath(opts, expr, obj, callback, otherTypeCallback) { if (!(this instanceof JSONPath)) { try { return new JSONPath(opts, expr, obj, callback, otherTypeCallback); } catch (e) { if (!e.avoidNew) { throw e; } return e.value; } } if (typeof opts === "string") { otherTypeCallback = callback; callback = obj; obj = expr; expr = opts; opts = null; } const optObj = opts && typeof opts === "object"; opts = opts || {}; this.json = opts.json || obj; this.path = opts.path || expr; this.resultType = opts.resultType || "value"; this.flatten = opts.flatten || false; this.wrap = Object.hasOwn(opts, "wrap") ? opts.wrap : true; this.sandbox = opts.sandbox || {}; this.eval = opts.eval === void 0 ? "safe" : opts.eval; this.ignoreEvalErrors = typeof opts.ignoreEvalErrors === "undefined" ? false : opts.ignoreEvalErrors; this.parent = opts.parent || null; this.parentProperty = opts.parentProperty || null; this.callback = opts.callback || callback || null; this.otherTypeCallback = opts.otherTypeCallback || otherTypeCallback || function() { throw new TypeError("You must supply an otherTypeCallback callback option with the @other() operator."); }; if (opts.autostart !== false) { const args = { path: optObj ? opts.path : expr }; if (!optObj) { args.json = obj; } else if ("json" in opts) { args.json = opts.json; } const ret = this.evaluate(args); if (!ret || typeof ret !== "object") { throw new NewError(ret); } return ret; } } JSONPath.prototype.evaluate = function(expr, json, callback, otherTypeCallback) { let currParent = this.parent, currParentProperty = this.parentProperty; let { flatten, wrap } = this; this.currResultType = this.resultType; this.currEval = this.eval; this.currSandbox = this.sandbox; callback = callback || this.callback; this.currOtherTypeCallback = otherTypeCallback || this.otherTypeCallback; json = json || this.json; expr = expr || this.path; if (expr && typeof expr === "object" && !Array.isArray(expr)) { if (!expr.path && expr.path !== "") { throw new TypeError('You must supply a "path" property when providing an object argument to JSONPath.evaluate().'); } if (!Object.hasOwn(expr, "json")) { throw new TypeError('You must supply a "json" property when providing an object argument to JSONPath.evaluate().'); } ({ json } = expr); flatten = Object.hasOwn(expr, "flatten") ? expr.flatten : flatten; this.currResultType = Object.hasOwn(expr, "resultType") ? expr.resultType : this.currResultType; this.currSandbox = Object.hasOwn(expr, "sandbox") ? expr.sandbox : this.currSandbox; wrap = Object.hasOwn(expr, "wrap") ? expr.wrap : wrap; this.currEval = Object.hasOwn(expr, "eval") ? expr.eval : this.currEval; callback = Object.hasOwn(expr, "callback") ? expr.callback : callback; this.currOtherTypeCallback = Object.hasOwn(expr, "otherTypeCallback") ? expr.otherTypeCallback : this.currOtherTypeCallback; currParent = Object.hasOwn(expr, "parent") ? expr.parent : currParent; currParentProperty = Object.hasOwn(expr, "parentProperty") ? expr.parentProperty : currParentProperty; expr = expr.path; } currParent = currParent || null; currParentProperty = currParentProperty || null; if (Array.isArray(expr)) { expr = JSONPath.toPathString(expr); } if (!expr && expr !== "" || !json) { return void 0; } const exprList = JSONPath.toPathArray(expr); if (exprList[0] === "$" && exprList.length > 1) { exprList.shift(); } this._hasParentSelector = null; const result = this._trace(exprList, json, ["$"], currParent, currParentProperty, callback).filter(function(ea) { return ea && !ea.isParentSelector; }); if (!result.length) { return wrap ? [] : void 0; } if (!wrap && result.length === 1 && !result[0].hasArrExpr) { return this._getPreferredOutput(result[0]); } return result.reduce((rslt, ea) => { const valOrPath = this._getPreferredOutput(ea); if (flatten && Array.isArray(valOrPath)) { rslt = rslt.concat(valOrPath); } else { rslt.push(valOrPath); } return rslt; }, []); }; JSONPath.prototype._getPreferredOutput = function(ea) { const resultType = this.currResultType; switch (resultType) { case "all": { const path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path); ea.pointer = JSONPath.toPointer(path); ea.path = typeof ea.path === "string" ? ea.path : JSONPath.toPathString(ea.path); return ea; } case "value": case "parent": case "parentProperty": return ea[resultType]; case "path": return JSONPath.toPathString(ea[resultType]); case "pointer": return JSONPath.toPointer(ea.path); default: throw new TypeError("Unknown result type"); } }; JSONPath.prototype._handleCallback = function(fullRetObj, callback, type) { if (callback) { const preferredOutput = this._getPreferredOutput(fullRetObj); fullRetObj.path = typeof fullRetObj.path === "string" ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path); callback(preferredOutput, type, fullRetObj); } }; JSONPath.prototype._trace = function(expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) { let retObj; if (!expr.length) { retObj = { path, value: val, parent, parentProperty: parentPropName, hasArrExpr }; this._handleCallback(retObj, callback, "value"); return retObj; } const loc = expr[0], x = expr.slice(1); const ret = []; function addRet(elems) { if (Array.isArray(elems)) { elems.forEach((t) => { ret.push(t); }); } else { ret.push(elems); } } if ((typeof loc !== "string" || literalPriority) && val && Object.hasOwn(val, loc)) { addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr)); } else if (loc === "*") { this._walk(val, (m) => { addRet(this._trace(x, val[m], push(path, m), val, m, callback, true, true)); }); } else if (loc === "..") { addRet(this._trace(x, val, path, parent, parentPropName, callback, hasArrExpr)); this._walk(val, (m) => { if (typeof val[m] === "object") { addRet(this._trace(expr.slice(), val[m], push(path, m), val, m, callback, true)); } }); } else if (loc === "^") { this._hasParentSelector = true; return { path: path.slice(0, -1), expr: x, isParentSelector: true }; } else if (loc === "~") { retObj = { path: push(path, loc), value: parentPropName, parent, parentProperty: null }; this._handleCallback(retObj, callback, "property"); return retObj; } else if (loc === "$") { addRet(this._trace(x, val, path, null, null, callback, hasArrExpr)); } else if (/^(-?\d*):(-?\d*):?(\d*)$/u.test(loc)) { addRet(this._slice(loc, x, val, path, parent, parentPropName, callback)); } else if (loc.indexOf("?(") === 0) { if (this.currEval === false) { throw new Error("Eval [?(expr)] prevented in JSONPath expression."); } const safeLoc = loc.replace(/^\?\((.*?)\)$/u, "$1"); const nested = /@.?([^?]*)[['](\??\(.*?\))(?!.\)\])[\]']/gu.exec(safeLoc); if (nested) { this._walk(val, (m) => { const npath = [nested[2]]; const nvalue = nested[1] ? val[m][nested[1]] : val[m]; const filterResults = this._trace(npath, nvalue, path, parent, parentPropName, callback, true); if (filterResults.length > 0) { addRet(this._trace(x, val[m], push(path, m), val, m, callback, true)); } }); } else { this._walk(val, (m) => { if (this._eval(safeLoc, val[m], m, path, parent, parentPropName)) { addRet(this._trace(x, val[m], push(path, m), val, m, callback, true)); } }); } } else if (loc[0] === "(") { if (this.currEval === false) { throw new Error("Eval [(expr)] prevented in JSONPath expression."); } addRet(this._trace(unshift(this._eval(loc, val, path.at(-1), path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr)); } else if (loc[0] === "@") { let addType = false; const valueType = loc.slice(1, -2); switch (valueType) { case "scalar": if (!val || !["object", "function"].includes(typeof val)) { addType = true; } break; case "boolean": case "string": case "undefined": case "function": if (typeof val === valueType) { addType = true; } break; case "integer": if (Number.isFinite(val) && !(val % 1)) { addType = true; } break; case "number": if (Number.isFinite(val)) { addType = true; } break; case "nonFinite": if (typeof val === "number" && !Number.isFinite(val)) { addType = true; } break; case "object": if (val && typeof val === valueType) { addType = true; } break; case "array": if (Array.isArray(val)) { addType = true; } break; case "other": addType = this.currOtherTypeCallback(val, path, parent, parentPropName); break; case "null": if (val === null) { addType = true; } break; default: throw new TypeError("Unknown value type " + valueType); } if (addType) { retObj = { path, value: val, parent, parentProperty: parentPropName }; this._handleCallback(retObj, callback, "value"); return retObj; } } else if (loc[0] === "`" && val && Object.hasOwn(val, loc.slice(1))) { const locProp = loc.slice(1); addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true)); } else if (loc.includes(",")) { const parts = loc.split(","); for (const part of parts) { addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true)); } } else if (!literalPriority && val && Object.hasOwn(val, loc)) { addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true)); } if (this._hasParentSelector) { for (let t = 0; t < ret.length; t++) { const rett = ret[t]; if (rett && rett.isParentSelector) { const tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr); if (Array.isArray(tmp)) { ret[t] = tmp[0]; const tl = tmp.length; for (let tt = 1; tt < tl; tt++) { t++; ret.splice(t, 0, tmp[tt]); } } else { ret[t] = tmp; } } } } return ret; }; JSONPath.prototype._walk = function(val, f) { if (Array.isArray(val)) { const n = val.length; for (let i = 0; i < n; i++) { f(i); } } else if (val && typeof val === "object") { Object.keys(val).forEach((m) => { f(m); }); } }; JSONPath.prototype._slice = function(loc, expr, val, path, parent, parentPropName, callback) { if (!Array.isArray(val)) { return void 0; } const len = val.length, parts = loc.split(":"), step = parts[2] && Number.parseInt(parts[2]) || 1; let start = parts[0] && Number.parseInt(parts[0]) || 0, end = parts[1] && Number.parseInt(parts[1]) || len; start = start < 0 ? Math.max(0, start + len) : Math.min(len, start); end = end < 0 ? Math.max(0, end + len) : Math.min(len, end); const ret = []; for (let i = start; i < end; i += step) { const tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true); tmp.forEach((t) => { ret.push(t); }); } return ret; }; JSONPath.prototype._eval = function(code, _v, _vname, path, parent, parentPropName) { this.currSandbox._$_parentProperty = parentPropName; this.currSandbox._$_parent = parent; this.currSandbox._$_property = _vname; this.currSandbox._$_root = this.json; this.currSandbox._$_v = _v; const containsPath = code.includes("@path"); if (containsPath) { this.currSandbox._$_path = JSONPath.toPathString(path.concat([_vname])); } const scriptCacheKey = this.currEval + "Script:" + code; if (!JSONPath.cache[scriptCacheKey]) { let script = code.replaceAll("@parentProperty", "_$_parentProperty").replaceAll("@parent", "_$_parent").replaceAll("@property", "_$_property").replaceAll("@root", "_$_root").replaceAll(/@([.\s)[])/gu, "_$_v$1"); if (containsPath) { script = script.replaceAll("@path", "_$_path"); } if (this.currEval === "safe" || this.currEval === true || this.currEval === void 0) { JSONPath.cache[scriptCacheKey] = new this.safeVm.Script(script); } else if (this.currEval === "native") { JSONPath.cache[scriptCacheKey] = new this.vm.Script(script); } else if (typeof this.currEval === "function" && this.currEval.prototype && Object.hasOwn(this.currEval.prototype, "runInNewContext")) { const CurrEval = this.currEval; JSONPath.cache[scriptCacheKey] = new CurrEval(script); } else if (typeof this.currEval === "function") { JSONPath.cache[scriptCacheKey] = { runInNewContext: (context) => this.currEval(script, context) }; } else { throw new TypeError(`Unknown "eval" property "${this.currEval}"`); } } try { return JSONPath.cache[scriptCacheKey].runInNewContext(this.currSandbox); } catch (e) { if (this.ignoreEvalErrors) { return false; } throw new Error("jsonPath: " + e.message + ": " + code); } }; JSONPath.cache = {}; JSONPath.toPathString = function(pathArr) { const x = pathArr, n = x.length; let p = "$"; for (let i = 1; i < n; i++) { if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) { p += /^[0-9*]+$/u.test(x[i]) ? "[" + x[i] + "]" : "['" + x[i] + "']"; } } return p; }; JSONPath.toPointer = function(pointer) { const x = pointer, n = x.length; let p = ""; for (let i = 1; i < n; i++) { if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) { p += "/" + x[i].toString().replaceAll("~", "~0").replaceAll("/", "~1"); } } return p; }; JSONPath.toPathArray = function(expr) { const { cache } = JSONPath; if (cache[expr]) { return cache[expr].concat(); } const subx = []; const normalized = expr.replaceAll(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/gu, ";$&;").replaceAll(/[['](\??\(.*?\))[\]'](?!.\])/gu, function($0, $1) { return "[#" + (subx.push($1) - 1) + "]"; }).replaceAll(/\[['"]([^'\]]*)['"]\]/gu, function($0, prop) { return "['" + prop.replaceAll(".", "%@%").replaceAll("~", "%%@@%%") + "']"; }).replaceAll("~", ";~;").replaceAll(/['"]?\.['"]?(?![^[]*\])|\[['"]?/gu, ";").replaceAll("%@%", ".").replaceAll("%%@@%%", "~").replaceAll(/(?:;)?(\^+)(?:;)?/gu, function($0, ups) { return ";" + ups.split("").join(";") + ";"; }).replaceAll(/;;;|;;/gu, ";..;").replaceAll(/;$|'?\]|'$/gu, ""); const exprList = normalized.split(";").map(function(exp) { const match = exp.match(/#(\d+)/u); return !match || !match[1] ? exp : subx[match[1]]; }); cache[expr] = exprList; return cache[expr].concat(); }; JSONPath.prototype.safeVm = { Script: SafeScript }; JSONPath.prototype.vm = import_vm.default; // src/index.ts var plugin2 = { templateFunctions: [ { name: "json.jsonpath", description: "Filter JSON-formatted text using JSONPath syntax", args: [ { type: "text", name: "input", label: "Input", multiLine: true, placeholder: '{ "foo": "bar" }' }, { type: "text", name: "query", label: "Query", placeholder: "$..foo" }, { type: "checkbox", name: "formatted", label: "Format Output" } ], async onRender(_ctx, args) { try { const parsed = JSON.parse(String(args.values.input)); const query = String(args.values.query ?? "$").trim(); let filtered = JSONPath({ path: query, json: parsed }); if (Array.isArray(filtered)) { filtered = filtered[0]; } if (args.values.formatted) { return JSON.stringify(filtered, null, 2); } else { return JSON.stringify(filtered); } } catch (e) { return null; } } }, { name: "json.escape", description: "Escape a JSON string, useful when using the output in JSON values", args: [ { type: "text", name: "input", label: "Input", multiLine: true, placeholder: 'Hello "World"' } ], async onRender(_ctx, args) { const input = String(args.values.input ?? ""); return input.replace(/\\/g, "\\\\").replace(/"/g, '\\"'); } } ] }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { plugin });