UNPKG

aws-local-stepfunctions

Version:
1,427 lines (1,426 loc) 1.2 MB
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 __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; 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); // node_modules/jsonpath-plus/dist/index-browser-esm.js var index_browser_esm_exports = {}; __export(index_browser_esm_exports, { JSONPath: () => JSONPath }); function push(arr, item) { arr = arr.slice(); arr.push(item); return arr; } function unshift(item, arr) { arr = arr.slice(); arr.unshift(item); return arr; } function JSONPath(opts, expr, obj, callback, otherTypeCallback) { if (!(this instanceof JSONPath)) { try { return new JSONPath(opts, expr, obj, callback, otherTypeCallback); } catch (e3) { if (!e3.avoidNew) { throw e3; } return e3.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; } } var Hooks, Plugins, Jsep, hooks, jsep, stdClassProps, CONDITIONAL_EXP, ternary, FSLASH_CODE, BSLASH_CODE, index, PLUS_CODE, MINUS_CODE, plugin, BLOCKED_PROTO_PROPERTIES, SafeEval, SafeScript, NewError, moveToAnotherArray, Script; var init_index_browser_esm = __esm({ "node_modules/jsonpath-plus/dist/index-browser-esm.js"() { "use strict"; 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<string, any>} 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); }); } }; 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() { for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { plugins[_key] = arguments[_key]; } plugins.forEach((plugin2) => { if (typeof plugin2 !== "object" || !plugin2.name || !plugin2.init) { throw new Error("Invalid JSEP plugin format"); } if (this.registered[plugin2.name]) { return; } plugin2.init(this.jsep); this.registered[plugin2.name] = plugin2; }); } }; 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((k3) => k3.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, i3, 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); } i3 = stack.length - 1; node = stack[i3]; while (i3 > 1) { node = { type: _Jsep.BINARY_EXP, operator: stack[i3 - 1].value, left: stack[i3 - 2], right: node }; i3 -= 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) }; } }; 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); jsep = (expr) => new Jsep(expr).parse(); stdClassProps = Object.getOwnPropertyNames(class Test { }); Object.getOwnPropertyNames(Jsep).filter((prop) => !stdClassProps.includes(prop) && jsep[prop] === void 0).forEach((m3) => { jsep[m3] = Jsep[m3]; }); jsep.Jsep = Jsep; CONDITIONAL_EXP = "ConditionalExpression"; 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); FSLASH_CODE = 47; BSLASH_CODE = 92; 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 (e3) { this.throwError(e3.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"); } }); } }; PLUS_CODE = 43; MINUS_CODE = 45; 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((c3) => c3 === code && c3 === 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((c3) => c3 === code && c3 === 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((val2) => { if (val2 && typeof val2 === "object") { updateBinariesToAssignments(val2); } }); } } } }; jsep.plugins.register(index, plugin); jsep.addUnaryOp("typeof"); jsep.addLiteral("null", null); jsep.addLiteral("undefined", void 0); BLOCKED_PROTO_PROPERTIES = /* @__PURE__ */ new Set(["constructor", "__proto__", "__defineGetter__", "__defineSetter__"]); SafeEval = { /** * @param {jsep.Expression} ast * @param {Record<string, any>} 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 = { "||": (a3, b3) => a3 || b3(), "&&": (a3, b3) => a3 && b3(), "|": (a3, b3) => a3 | b3(), "^": (a3, b3) => a3 ^ b3(), "&": (a3, b3) => a3 & b3(), // eslint-disable-next-line eqeqeq -- API "==": (a3, b3) => a3 == b3(), // eslint-disable-next-line eqeqeq -- API "!=": (a3, b3) => a3 != b3(), "===": (a3, b3) => a3 === b3(), "!==": (a3, b3) => a3 !== b3(), "<": (a3, b3) => a3 < b3(), ">": (a3, b3) => a3 > b3(), "<=": (a3, b3) => a3 <= b3(), ">=": (a3, b3) => a3 >= b3(), "<<": (a3, b3) => a3 << b3(), ">>": (a3, b3) => a3 >> b3(), ">>>": (a3, b3) => a3 >>> b3(), "+": (a3, b3) => a3 + b3(), "-": (a3, b3) => a3 - b3(), "*": (a3, b3) => a3 * b3(), "/": (a3, b3) => a3 / b3(), "%": (a3, b3) => a3 % b3() }[ast.operator](SafeEval.evalAst(ast.left, subs), () => SafeEval.evalAst(ast.right, subs)); return result; }, evalCompound(ast, subs) { let last; for (let i3 = 0; i3 < ast.body.length; i3++) { if (ast.body[i3].type === "Identifier" && ["var", "let", "const"].includes(ast.body[i3].name) && ast.body[i3 + 1] && ast.body[i3 + 1].type === "AssignmentExpression") { i3 += 1; } const expr = ast.body[i3]; 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 = ast.computed ? SafeEval.evalAst(ast.property) : ast.property.name; 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 = { "-": (a3) => -SafeEval.evalAst(a3, subs), "!": (a3) => !SafeEval.evalAst(a3, subs), "~": (a3) => ~SafeEval.evalAst(a3, subs), // eslint-disable-next-line no-implicit-coercion -- API "+": (a3) => +SafeEval.evalAst(a3, subs), typeof: (a3) => typeof SafeEval.evalAst(a3, 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]; } }; 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); } }; 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"; } }; 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 fullRe