@swagger-api/apidom-json-path 1.0.0-alpha.1 → 1.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6018,6 +6018,7 @@ var createMethod = function (IS_INCLUDES) {
6018
6018
  return function ($this, el, fromIndex) {
6019
6019
  var O = toIndexedObject($this);
6020
6020
  var length = lengthOfArrayLike(O);
6021
+ if (length === 0) return !IS_INCLUDES && -1;
6021
6022
  var index = toAbsoluteIndex(fromIndex, length);
6022
6023
  var value;
6023
6024
  // Array#includes uses SameValueZero equality algorithm
@@ -6213,16 +6214,16 @@ module.exports = function (target, key, value, options) {
6213
6214
 
6214
6215
  "use strict";
6215
6216
 
6216
- var global = __webpack_require__(1063);
6217
+ var globalThis = __webpack_require__(8900);
6217
6218
 
6218
6219
  // eslint-disable-next-line es/no-object-defineproperty -- safe
6219
6220
  var defineProperty = Object.defineProperty;
6220
6221
 
6221
6222
  module.exports = function (key, value) {
6222
6223
  try {
6223
- defineProperty(global, key, { value: value, configurable: true, writable: true });
6224
+ defineProperty(globalThis, key, { value: value, configurable: true, writable: true });
6224
6225
  } catch (error) {
6225
- global[key] = value;
6226
+ globalThis[key] = value;
6226
6227
  } return value;
6227
6228
  };
6228
6229
 
@@ -6250,10 +6251,10 @@ module.exports = !fails(function () {
6250
6251
 
6251
6252
  "use strict";
6252
6253
 
6253
- var global = __webpack_require__(1063);
6254
+ var globalThis = __webpack_require__(8900);
6254
6255
  var isObject = __webpack_require__(262);
6255
6256
 
6256
- var document = global.document;
6257
+ var document = globalThis.document;
6257
6258
  // typeof document.createElement is 'object' in old IE
6258
6259
  var EXISTS = isObject(document) && isObject(document.createElement);
6259
6260
 
@@ -6308,26 +6309,50 @@ module.exports = {
6308
6309
 
6309
6310
  /***/ }),
6310
6311
 
6311
- /***/ 7868:
6312
+ /***/ 9683:
6312
6313
  /***/ ((module) => {
6313
6314
 
6314
6315
  "use strict";
6315
6316
 
6316
- module.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';
6317
+ // IE8- don't enum bug keys
6318
+ module.exports = [
6319
+ 'constructor',
6320
+ 'hasOwnProperty',
6321
+ 'isPrototypeOf',
6322
+ 'propertyIsEnumerable',
6323
+ 'toLocaleString',
6324
+ 'toString',
6325
+ 'valueOf'
6326
+ ];
6327
+
6328
+
6329
+ /***/ }),
6330
+
6331
+ /***/ 3531:
6332
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
6333
+
6334
+ "use strict";
6335
+
6336
+ var globalThis = __webpack_require__(8900);
6337
+
6338
+ var navigator = globalThis.navigator;
6339
+ var userAgent = navigator && navigator.userAgent;
6340
+
6341
+ module.exports = userAgent ? String(userAgent) : '';
6317
6342
 
6318
6343
 
6319
6344
  /***/ }),
6320
6345
 
6321
- /***/ 4432:
6346
+ /***/ 5547:
6322
6347
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
6323
6348
 
6324
6349
  "use strict";
6325
6350
 
6326
- var global = __webpack_require__(1063);
6327
- var userAgent = __webpack_require__(7868);
6351
+ var globalThis = __webpack_require__(8900);
6352
+ var userAgent = __webpack_require__(3531);
6328
6353
 
6329
- var process = global.process;
6330
- var Deno = global.Deno;
6354
+ var process = globalThis.process;
6355
+ var Deno = globalThis.Deno;
6331
6356
  var versions = process && process.versions || Deno && Deno.version;
6332
6357
  var v8 = versions && versions.v8;
6333
6358
  var match, version;
@@ -6352,25 +6377,6 @@ if (!version && userAgent) {
6352
6377
  module.exports = version;
6353
6378
 
6354
6379
 
6355
- /***/ }),
6356
-
6357
- /***/ 9683:
6358
- /***/ ((module) => {
6359
-
6360
- "use strict";
6361
-
6362
- // IE8- don't enum bug keys
6363
- module.exports = [
6364
- 'constructor',
6365
- 'hasOwnProperty',
6366
- 'isPrototypeOf',
6367
- 'propertyIsEnumerable',
6368
- 'toLocaleString',
6369
- 'toString',
6370
- 'valueOf'
6371
- ];
6372
-
6373
-
6374
6380
  /***/ }),
6375
6381
 
6376
6382
  /***/ 3885:
@@ -6443,7 +6449,7 @@ module.exports = !fails(function () {
6443
6449
 
6444
6450
  "use strict";
6445
6451
 
6446
- var global = __webpack_require__(1063);
6452
+ var globalThis = __webpack_require__(8900);
6447
6453
  var apply = __webpack_require__(7013);
6448
6454
  var uncurryThis = __webpack_require__(9344);
6449
6455
  var isCallable = __webpack_require__(2769);
@@ -6453,6 +6459,8 @@ var path = __webpack_require__(8099);
6453
6459
  var bind = __webpack_require__(4572);
6454
6460
  var createNonEnumerableProperty = __webpack_require__(3999);
6455
6461
  var hasOwn = __webpack_require__(701);
6462
+ // add debugging info
6463
+ __webpack_require__(3753);
6456
6464
 
6457
6465
  var wrapConstructor = function (NativeConstructor) {
6458
6466
  var Wrapper = function (a, b, c) {
@@ -6489,7 +6497,7 @@ module.exports = function (options, source) {
6489
6497
  var STATIC = options.stat;
6490
6498
  var PROTO = options.proto;
6491
6499
 
6492
- var nativeSource = GLOBAL ? global : STATIC ? global[TARGET] : global[TARGET] && global[TARGET].prototype;
6500
+ var nativeSource = GLOBAL ? globalThis : STATIC ? globalThis[TARGET] : globalThis[TARGET] && globalThis[TARGET].prototype;
6493
6501
 
6494
6502
  var target = GLOBAL ? path : path[TARGET] || createNonEnumerableProperty(path, TARGET, {})[TARGET];
6495
6503
  var targetPrototype = target.prototype;
@@ -6515,7 +6523,7 @@ module.exports = function (options, source) {
6515
6523
  if (!FORCED && !PROTO && typeof targetProperty == typeof sourceProperty) continue;
6516
6524
 
6517
6525
  // bind methods to global for calling from export context
6518
- if (options.bind && USE_NATIVE) resultProperty = bind(sourceProperty, global);
6526
+ if (options.bind && USE_NATIVE) resultProperty = bind(sourceProperty, globalThis);
6519
6527
  // wrap global constructors for prevent changes in this version
6520
6528
  else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty);
6521
6529
  // make static versions for prototype methods
@@ -6726,7 +6734,7 @@ module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {
6726
6734
  "use strict";
6727
6735
 
6728
6736
  var path = __webpack_require__(8099);
6729
- var global = __webpack_require__(1063);
6737
+ var globalThis = __webpack_require__(8900);
6730
6738
  var isCallable = __webpack_require__(2769);
6731
6739
 
6732
6740
  var aFunction = function (variable) {
@@ -6734,8 +6742,8 @@ var aFunction = function (variable) {
6734
6742
  };
6735
6743
 
6736
6744
  module.exports = function (namespace, method) {
6737
- return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global[namespace])
6738
- : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];
6745
+ return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(globalThis[namespace])
6746
+ : path[namespace] && path[namespace][method] || globalThis[namespace] && globalThis[namespace][method];
6739
6747
  };
6740
6748
 
6741
6749
 
@@ -6803,7 +6811,7 @@ module.exports = function (V, P) {
6803
6811
 
6804
6812
  /***/ }),
6805
6813
 
6806
- /***/ 1063:
6814
+ /***/ 8900:
6807
6815
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
6808
6816
 
6809
6817
  "use strict";
@@ -6965,7 +6973,7 @@ module.exports = function (O, options) {
6965
6973
  "use strict";
6966
6974
 
6967
6975
  var NATIVE_WEAK_MAP = __webpack_require__(1314);
6968
- var global = __webpack_require__(1063);
6976
+ var globalThis = __webpack_require__(8900);
6969
6977
  var isObject = __webpack_require__(262);
6970
6978
  var createNonEnumerableProperty = __webpack_require__(3999);
6971
6979
  var hasOwn = __webpack_require__(701);
@@ -6974,8 +6982,8 @@ var sharedKey = __webpack_require__(4275);
6974
6982
  var hiddenKeys = __webpack_require__(5241);
6975
6983
 
6976
6984
  var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
6977
- var TypeError = global.TypeError;
6978
- var WeakMap = global.WeakMap;
6985
+ var TypeError = globalThis.TypeError;
6986
+ var WeakMap = globalThis.WeakMap;
6979
6987
  var set, get, has;
6980
6988
 
6981
6989
  var enforce = function (it) {
@@ -7572,7 +7580,8 @@ var NullProtoObjectViaActiveX = function (activeXDocument) {
7572
7580
  activeXDocument.write(scriptTag(''));
7573
7581
  activeXDocument.close();
7574
7582
  var temp = activeXDocument.parentWindow.Object;
7575
- activeXDocument = null; // avoid memory leak
7583
+ // eslint-disable-next-line no-useless-assignment -- avoid memory leak
7584
+ activeXDocument = null;
7576
7585
  return temp;
7577
7586
  };
7578
7587
 
@@ -7894,7 +7903,8 @@ exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
7894
7903
 
7895
7904
  /* eslint-disable no-proto -- safe */
7896
7905
  var uncurryThisAccessor = __webpack_require__(3574);
7897
- var anObject = __webpack_require__(7235);
7906
+ var isObject = __webpack_require__(262);
7907
+ var requireObjectCoercible = __webpack_require__(5426);
7898
7908
  var aPossiblePrototype = __webpack_require__(1966);
7899
7909
 
7900
7910
  // `Object.setPrototypeOf` method
@@ -7911,8 +7921,9 @@ module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () {
7911
7921
  CORRECT_SETTER = test instanceof Array;
7912
7922
  } catch (error) { /* empty */ }
7913
7923
  return function setPrototypeOf(O, proto) {
7914
- anObject(O);
7924
+ requireObjectCoercible(O);
7915
7925
  aPossiblePrototype(proto);
7926
+ if (!isObject(O)) return O;
7916
7927
  if (CORRECT_SETTER) setter(O, proto);
7917
7928
  else O.__proto__ = proto;
7918
7929
  return O;
@@ -8084,13 +8095,20 @@ module.exports = function (key) {
8084
8095
 
8085
8096
  "use strict";
8086
8097
 
8087
- var global = __webpack_require__(1063);
8098
+ var IS_PURE = __webpack_require__(4871);
8099
+ var globalThis = __webpack_require__(8900);
8088
8100
  var defineGlobalProperty = __webpack_require__(7525);
8089
8101
 
8090
8102
  var SHARED = '__core-js_shared__';
8091
- var store = global[SHARED] || defineGlobalProperty(SHARED, {});
8103
+ var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {});
8092
8104
 
8093
- module.exports = store;
8105
+ (store.versions || (store.versions = [])).push({
8106
+ version: '3.38.1',
8107
+ mode: IS_PURE ? 'pure' : 'global',
8108
+ copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',
8109
+ license: 'https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE',
8110
+ source: 'https://github.com/zloirock/core-js'
8111
+ });
8094
8112
 
8095
8113
 
8096
8114
  /***/ }),
@@ -8100,18 +8118,11 @@ module.exports = store;
8100
8118
 
8101
8119
  "use strict";
8102
8120
 
8103
- var IS_PURE = __webpack_require__(4871);
8104
8121
  var store = __webpack_require__(3753);
8105
8122
 
8106
- (module.exports = function (key, value) {
8107
- return store[key] || (store[key] = value !== undefined ? value : {});
8108
- })('versions', []).push({
8109
- version: '3.35.1',
8110
- mode: IS_PURE ? 'pure' : 'global',
8111
- copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',
8112
- license: 'https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE',
8113
- source: 'https://github.com/zloirock/core-js'
8114
- });
8123
+ module.exports = function (key, value) {
8124
+ return store[key] || (store[key] = value || {});
8125
+ };
8115
8126
 
8116
8127
 
8117
8128
  /***/ }),
@@ -8167,11 +8178,11 @@ module.exports = {
8167
8178
  "use strict";
8168
8179
 
8169
8180
  /* eslint-disable es/no-symbol -- required for testing */
8170
- var V8_VERSION = __webpack_require__(4432);
8181
+ var V8_VERSION = __webpack_require__(5547);
8171
8182
  var fails = __webpack_require__(1203);
8172
- var global = __webpack_require__(1063);
8183
+ var globalThis = __webpack_require__(8900);
8173
8184
 
8174
- var $String = global.String;
8185
+ var $String = globalThis.String;
8175
8186
 
8176
8187
  // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
8177
8188
  module.exports = !!Object.getOwnPropertySymbols && !fails(function () {
@@ -8443,10 +8454,10 @@ module.exports = DESCRIPTORS && fails(function () {
8443
8454
 
8444
8455
  "use strict";
8445
8456
 
8446
- var global = __webpack_require__(1063);
8457
+ var globalThis = __webpack_require__(8900);
8447
8458
  var isCallable = __webpack_require__(2769);
8448
8459
 
8449
- var WeakMap = global.WeakMap;
8460
+ var WeakMap = globalThis.WeakMap;
8450
8461
 
8451
8462
  module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));
8452
8463
 
@@ -8458,14 +8469,14 @@ module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));
8458
8469
 
8459
8470
  "use strict";
8460
8471
 
8461
- var global = __webpack_require__(1063);
8472
+ var globalThis = __webpack_require__(8900);
8462
8473
  var shared = __webpack_require__(8141);
8463
8474
  var hasOwn = __webpack_require__(701);
8464
8475
  var uid = __webpack_require__(1268);
8465
8476
  var NATIVE_SYMBOL = __webpack_require__(4603);
8466
8477
  var USE_SYMBOL_AS_UID = __webpack_require__(7460);
8467
8478
 
8468
- var Symbol = global.Symbol;
8479
+ var Symbol = globalThis.Symbol;
8469
8480
  var WellKnownSymbolsStore = shared('wks');
8470
8481
  var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;
8471
8482
 
@@ -8697,7 +8708,7 @@ module.exports = defineIterator(Array, 'Array', function (iterated, kind) {
8697
8708
  var target = state.target;
8698
8709
  var index = state.index++;
8699
8710
  if (!target || index >= target.length) {
8700
- state.target = undefined;
8711
+ state.target = null;
8701
8712
  return createIterResultObject(undefined, true);
8702
8713
  }
8703
8714
  switch (state.kind) {
@@ -8731,12 +8742,12 @@ if (!IS_PURE && DESCRIPTORS && values.name !== 'values') try {
8731
8742
 
8732
8743
  /* eslint-disable no-unused-vars -- required for functions `.length` */
8733
8744
  var $ = __webpack_require__(9098);
8734
- var global = __webpack_require__(1063);
8745
+ var globalThis = __webpack_require__(8900);
8735
8746
  var apply = __webpack_require__(7013);
8736
8747
  var wrapErrorConstructorWithCause = __webpack_require__(6453);
8737
8748
 
8738
8749
  var WEB_ASSEMBLY = 'WebAssembly';
8739
- var WebAssembly = global[WEB_ASSEMBLY];
8750
+ var WebAssembly = globalThis[WEB_ASSEMBLY];
8740
8751
 
8741
8752
  // eslint-disable-next-line es/no-error-cause -- feature detection
8742
8753
  var FORCED = new Error('e', { cause: 7 }).cause !== 7;
@@ -8847,12 +8858,12 @@ __webpack_require__(5695);
8847
8858
 
8848
8859
  __webpack_require__(9828);
8849
8860
  var DOMIterables = __webpack_require__(1100);
8850
- var global = __webpack_require__(1063);
8861
+ var globalThis = __webpack_require__(8900);
8851
8862
  var setToStringTag = __webpack_require__(1811);
8852
8863
  var Iterators = __webpack_require__(6625);
8853
8864
 
8854
8865
  for (var COLLECTION_NAME in DOMIterables) {
8855
- setToStringTag(global[COLLECTION_NAME], COLLECTION_NAME);
8866
+ setToStringTag(globalThis[COLLECTION_NAME], COLLECTION_NAME);
8856
8867
  Iterators[COLLECTION_NAME] = Iterators.Array;
8857
8868
  }
8858
8869
 
@@ -8883,272 +8894,1382 @@ __webpack_require__.r(__webpack_exports__);
8883
8894
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
8884
8895
  /* harmony export */ JSONPath: () => (/* binding */ JSONPath)
8885
8896
  /* harmony export */ });
8886
- function _typeof(obj) {
8887
- "@babel/helpers - typeof";
8897
+ /**
8898
+ * @implements {IHooks}
8899
+ */
8900
+ class Hooks {
8901
+ /**
8902
+ * @callback HookCallback
8903
+ * @this {*|Jsep} this
8904
+ * @param {Jsep} env
8905
+ * @returns: void
8906
+ */
8907
+ /**
8908
+ * Adds the given callback to the list of callbacks for the given hook.
8909
+ *
8910
+ * The callback will be invoked when the hook it is registered for is run.
8911
+ *
8912
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
8913
+ *
8914
+ * @param {string|object} name The name of the hook, or an object of callbacks keyed by name
8915
+ * @param {HookCallback|boolean} callback The callback function which is given environment variables.
8916
+ * @param {?boolean} [first=false] Will add the hook to the top of the list (defaults to the bottom)
8917
+ * @public
8918
+ */
8919
+ add(name, callback, first) {
8920
+ if (typeof arguments[0] != 'string') {
8921
+ // Multiple hook callbacks, keyed by name
8922
+ for (let name in arguments[0]) {
8923
+ this.add(name, arguments[0][name], arguments[1]);
8924
+ }
8925
+ } else {
8926
+ (Array.isArray(name) ? name : [name]).forEach(function (name) {
8927
+ this[name] = this[name] || [];
8928
+ if (callback) {
8929
+ this[name][first ? 'unshift' : 'push'](callback);
8930
+ }
8931
+ }, this);
8932
+ }
8933
+ }
8888
8934
 
8889
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
8890
- return typeof obj;
8891
- } : function (obj) {
8892
- return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
8893
- }, _typeof(obj);
8935
+ /**
8936
+ * Runs a hook invoking all registered callbacks with the given environment variables.
8937
+ *
8938
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
8939
+ *
8940
+ * @param {string} name The name of the hook.
8941
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
8942
+ * @public
8943
+ */
8944
+ run(name, env) {
8945
+ this[name] = this[name] || [];
8946
+ this[name].forEach(function (callback) {
8947
+ callback.call(env && env.context ? env.context : env, env);
8948
+ });
8949
+ }
8894
8950
  }
8895
8951
 
8896
- function _classCallCheck(instance, Constructor) {
8897
- if (!(instance instanceof Constructor)) {
8898
- throw new TypeError("Cannot call a class as a function");
8952
+ /**
8953
+ * @implements {IPlugins}
8954
+ */
8955
+ class Plugins {
8956
+ constructor(jsep) {
8957
+ this.jsep = jsep;
8958
+ this.registered = {};
8899
8959
  }
8900
- }
8901
8960
 
8902
- function _defineProperties(target, props) {
8903
- for (var i = 0; i < props.length; i++) {
8904
- var descriptor = props[i];
8905
- descriptor.enumerable = descriptor.enumerable || false;
8906
- descriptor.configurable = true;
8907
- if ("value" in descriptor) descriptor.writable = true;
8908
- Object.defineProperty(target, descriptor.key, descriptor);
8961
+ /**
8962
+ * @callback PluginSetup
8963
+ * @this {Jsep} jsep
8964
+ * @returns: void
8965
+ */
8966
+ /**
8967
+ * Adds the given plugin(s) to the registry
8968
+ *
8969
+ * @param {object} plugins
8970
+ * @param {string} plugins.name The name of the plugin
8971
+ * @param {PluginSetup} plugins.init The init function
8972
+ * @public
8973
+ */
8974
+ register() {
8975
+ for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
8976
+ plugins[_key] = arguments[_key];
8977
+ }
8978
+ plugins.forEach(plugin => {
8979
+ if (typeof plugin !== 'object' || !plugin.name || !plugin.init) {
8980
+ throw new Error('Invalid JSEP plugin format');
8981
+ }
8982
+ if (this.registered[plugin.name]) {
8983
+ // already registered. Ignore.
8984
+ return;
8985
+ }
8986
+ plugin.init(this.jsep);
8987
+ this.registered[plugin.name] = plugin;
8988
+ });
8909
8989
  }
8910
8990
  }
8911
8991
 
8912
- function _createClass(Constructor, protoProps, staticProps) {
8913
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
8914
- if (staticProps) _defineProperties(Constructor, staticProps);
8915
- Object.defineProperty(Constructor, "prototype", {
8916
- writable: false
8917
- });
8918
- return Constructor;
8919
- }
8992
+ // JavaScript Expression Parser (JSEP) 1.3.9
8920
8993
 
8921
- function _inherits(subClass, superClass) {
8922
- if (typeof superClass !== "function" && superClass !== null) {
8923
- throw new TypeError("Super expression must either be null or a function");
8994
+ class Jsep {
8995
+ /**
8996
+ * @returns {string}
8997
+ */
8998
+ static get version() {
8999
+ // To be filled in by the template
9000
+ return '1.3.9';
9001
+ }
9002
+
9003
+ /**
9004
+ * @returns {string}
9005
+ */
9006
+ static toString() {
9007
+ return 'JavaScript Expression Parser (JSEP) v' + Jsep.version;
9008
+ }
9009
+ // ==================== CONFIG ================================
9010
+ /**
9011
+ * @method addUnaryOp
9012
+ * @param {string} op_name The name of the unary op to add
9013
+ * @returns {Jsep}
9014
+ */
9015
+ static addUnaryOp(op_name) {
9016
+ Jsep.max_unop_len = Math.max(op_name.length, Jsep.max_unop_len);
9017
+ Jsep.unary_ops[op_name] = 1;
9018
+ return Jsep;
8924
9019
  }
8925
9020
 
8926
- subClass.prototype = Object.create(superClass && superClass.prototype, {
8927
- constructor: {
8928
- value: subClass,
8929
- writable: true,
8930
- configurable: true
9021
+ /**
9022
+ * @method jsep.addBinaryOp
9023
+ * @param {string} op_name The name of the binary op to add
9024
+ * @param {number} precedence The precedence of the binary op (can be a float). Higher number = higher precedence
9025
+ * @param {boolean} [isRightAssociative=false] whether operator is right-associative
9026
+ * @returns {Jsep}
9027
+ */
9028
+ static addBinaryOp(op_name, precedence, isRightAssociative) {
9029
+ Jsep.max_binop_len = Math.max(op_name.length, Jsep.max_binop_len);
9030
+ Jsep.binary_ops[op_name] = precedence;
9031
+ if (isRightAssociative) {
9032
+ Jsep.right_associative.add(op_name);
9033
+ } else {
9034
+ Jsep.right_associative.delete(op_name);
8931
9035
  }
8932
- });
8933
- Object.defineProperty(subClass, "prototype", {
8934
- writable: false
8935
- });
8936
- if (superClass) _setPrototypeOf(subClass, superClass);
8937
- }
9036
+ return Jsep;
9037
+ }
8938
9038
 
8939
- function _getPrototypeOf(o) {
8940
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
8941
- return o.__proto__ || Object.getPrototypeOf(o);
8942
- };
8943
- return _getPrototypeOf(o);
8944
- }
9039
+ /**
9040
+ * @method addIdentifierChar
9041
+ * @param {string} char The additional character to treat as a valid part of an identifier
9042
+ * @returns {Jsep}
9043
+ */
9044
+ static addIdentifierChar(char) {
9045
+ Jsep.additional_identifier_chars.add(char);
9046
+ return Jsep;
9047
+ }
8945
9048
 
8946
- function _setPrototypeOf(o, p) {
8947
- _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
8948
- o.__proto__ = p;
8949
- return o;
8950
- };
8951
- return _setPrototypeOf(o, p);
8952
- }
9049
+ /**
9050
+ * @method addLiteral
9051
+ * @param {string} literal_name The name of the literal to add
9052
+ * @param {*} literal_value The value of the literal
9053
+ * @returns {Jsep}
9054
+ */
9055
+ static addLiteral(literal_name, literal_value) {
9056
+ Jsep.literals[literal_name] = literal_value;
9057
+ return Jsep;
9058
+ }
8953
9059
 
8954
- function _isNativeReflectConstruct() {
8955
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
8956
- if (Reflect.construct.sham) return false;
8957
- if (typeof Proxy === "function") return true;
9060
+ /**
9061
+ * @method removeUnaryOp
9062
+ * @param {string} op_name The name of the unary op to remove
9063
+ * @returns {Jsep}
9064
+ */
9065
+ static removeUnaryOp(op_name) {
9066
+ delete Jsep.unary_ops[op_name];
9067
+ if (op_name.length === Jsep.max_unop_len) {
9068
+ Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);
9069
+ }
9070
+ return Jsep;
9071
+ }
8958
9072
 
8959
- try {
8960
- Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
8961
- return true;
8962
- } catch (e) {
8963
- return false;
9073
+ /**
9074
+ * @method removeAllUnaryOps
9075
+ * @returns {Jsep}
9076
+ */
9077
+ static removeAllUnaryOps() {
9078
+ Jsep.unary_ops = {};
9079
+ Jsep.max_unop_len = 0;
9080
+ return Jsep;
8964
9081
  }
8965
- }
8966
9082
 
8967
- function _construct(Parent, args, Class) {
8968
- if (_isNativeReflectConstruct()) {
8969
- _construct = Reflect.construct.bind();
8970
- } else {
8971
- _construct = function _construct(Parent, args, Class) {
8972
- var a = [null];
8973
- a.push.apply(a, args);
8974
- var Constructor = Function.bind.apply(Parent, a);
8975
- var instance = new Constructor();
8976
- if (Class) _setPrototypeOf(instance, Class.prototype);
8977
- return instance;
8978
- };
9083
+ /**
9084
+ * @method removeIdentifierChar
9085
+ * @param {string} char The additional character to stop treating as a valid part of an identifier
9086
+ * @returns {Jsep}
9087
+ */
9088
+ static removeIdentifierChar(char) {
9089
+ Jsep.additional_identifier_chars.delete(char);
9090
+ return Jsep;
8979
9091
  }
8980
9092
 
8981
- return _construct.apply(null, arguments);
8982
- }
9093
+ /**
9094
+ * @method removeBinaryOp
9095
+ * @param {string} op_name The name of the binary op to remove
9096
+ * @returns {Jsep}
9097
+ */
9098
+ static removeBinaryOp(op_name) {
9099
+ delete Jsep.binary_ops[op_name];
9100
+ if (op_name.length === Jsep.max_binop_len) {
9101
+ Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);
9102
+ }
9103
+ Jsep.right_associative.delete(op_name);
9104
+ return Jsep;
9105
+ }
8983
9106
 
8984
- function _isNativeFunction(fn) {
8985
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
8986
- }
9107
+ /**
9108
+ * @method removeAllBinaryOps
9109
+ * @returns {Jsep}
9110
+ */
9111
+ static removeAllBinaryOps() {
9112
+ Jsep.binary_ops = {};
9113
+ Jsep.max_binop_len = 0;
9114
+ return Jsep;
9115
+ }
8987
9116
 
8988
- function _wrapNativeSuper(Class) {
8989
- var _cache = typeof Map === "function" ? new Map() : undefined;
9117
+ /**
9118
+ * @method removeLiteral
9119
+ * @param {string} literal_name The name of the literal to remove
9120
+ * @returns {Jsep}
9121
+ */
9122
+ static removeLiteral(literal_name) {
9123
+ delete Jsep.literals[literal_name];
9124
+ return Jsep;
9125
+ }
8990
9126
 
8991
- _wrapNativeSuper = function _wrapNativeSuper(Class) {
8992
- if (Class === null || !_isNativeFunction(Class)) return Class;
9127
+ /**
9128
+ * @method removeAllLiterals
9129
+ * @returns {Jsep}
9130
+ */
9131
+ static removeAllLiterals() {
9132
+ Jsep.literals = {};
9133
+ return Jsep;
9134
+ }
9135
+ // ==================== END CONFIG ============================
8993
9136
 
8994
- if (typeof Class !== "function") {
8995
- throw new TypeError("Super expression must either be null or a function");
8996
- }
9137
+ /**
9138
+ * @returns {string}
9139
+ */
9140
+ get char() {
9141
+ return this.expr.charAt(this.index);
9142
+ }
8997
9143
 
8998
- if (typeof _cache !== "undefined") {
8999
- if (_cache.has(Class)) return _cache.get(Class);
9144
+ /**
9145
+ * @returns {number}
9146
+ */
9147
+ get code() {
9148
+ return this.expr.charCodeAt(this.index);
9149
+ }
9150
+ /**
9151
+ * @param {string} expr a string with the passed in express
9152
+ * @returns Jsep
9153
+ */
9154
+ constructor(expr) {
9155
+ // `index` stores the character number we are currently at
9156
+ // All of the gobbles below will modify `index` as we move along
9157
+ this.expr = expr;
9158
+ this.index = 0;
9159
+ }
9160
+
9161
+ /**
9162
+ * static top-level parser
9163
+ * @returns {jsep.Expression}
9164
+ */
9165
+ static parse(expr) {
9166
+ return new Jsep(expr).parse();
9167
+ }
9168
+
9169
+ /**
9170
+ * Get the longest key length of any object
9171
+ * @param {object} obj
9172
+ * @returns {number}
9173
+ */
9174
+ static getMaxKeyLen(obj) {
9175
+ return Math.max(0, ...Object.keys(obj).map(k => k.length));
9176
+ }
9177
+
9178
+ /**
9179
+ * `ch` is a character code in the next three functions
9180
+ * @param {number} ch
9181
+ * @returns {boolean}
9182
+ */
9183
+ static isDecimalDigit(ch) {
9184
+ return ch >= 48 && ch <= 57; // 0...9
9185
+ }
9186
+
9187
+ /**
9188
+ * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float.
9189
+ * @param {string} op_val
9190
+ * @returns {number}
9191
+ */
9192
+ static binaryPrecedence(op_val) {
9193
+ return Jsep.binary_ops[op_val] || 0;
9194
+ }
9000
9195
 
9001
- _cache.set(Class, Wrapper);
9196
+ /**
9197
+ * Looks for start of identifier
9198
+ * @param {number} ch
9199
+ * @returns {boolean}
9200
+ */
9201
+ static isIdentifierStart(ch) {
9202
+ return ch >= 65 && ch <= 90 ||
9203
+ // A...Z
9204
+ ch >= 97 && ch <= 122 ||
9205
+ // a...z
9206
+ ch >= 128 && !Jsep.binary_ops[String.fromCharCode(ch)] ||
9207
+ // any non-ASCII that is not an operator
9208
+ Jsep.additional_identifier_chars.has(String.fromCharCode(ch)); // additional characters
9209
+ }
9210
+
9211
+ /**
9212
+ * @param {number} ch
9213
+ * @returns {boolean}
9214
+ */
9215
+ static isIdentifierPart(ch) {
9216
+ return Jsep.isIdentifierStart(ch) || Jsep.isDecimalDigit(ch);
9217
+ }
9218
+
9219
+ /**
9220
+ * throw error at index of the expression
9221
+ * @param {string} message
9222
+ * @throws
9223
+ */
9224
+ throwError(message) {
9225
+ const error = new Error(message + ' at character ' + this.index);
9226
+ error.index = this.index;
9227
+ error.description = message;
9228
+ throw error;
9229
+ }
9230
+
9231
+ /**
9232
+ * Run a given hook
9233
+ * @param {string} name
9234
+ * @param {jsep.Expression|false} [node]
9235
+ * @returns {?jsep.Expression}
9236
+ */
9237
+ runHook(name, node) {
9238
+ if (Jsep.hooks[name]) {
9239
+ const env = {
9240
+ context: this,
9241
+ node
9242
+ };
9243
+ Jsep.hooks.run(name, env);
9244
+ return env.node;
9002
9245
  }
9246
+ return node;
9247
+ }
9003
9248
 
9004
- function Wrapper() {
9005
- return _construct(Class, arguments, _getPrototypeOf(this).constructor);
9249
+ /**
9250
+ * Runs a given hook until one returns a node
9251
+ * @param {string} name
9252
+ * @returns {?jsep.Expression}
9253
+ */
9254
+ searchHook(name) {
9255
+ if (Jsep.hooks[name]) {
9256
+ const env = {
9257
+ context: this
9258
+ };
9259
+ Jsep.hooks[name].find(function (callback) {
9260
+ callback.call(env.context, env);
9261
+ return env.node;
9262
+ });
9263
+ return env.node;
9006
9264
  }
9265
+ }
9007
9266
 
9008
- Wrapper.prototype = Object.create(Class.prototype, {
9009
- constructor: {
9010
- value: Wrapper,
9011
- enumerable: false,
9012
- writable: true,
9013
- configurable: true
9014
- }
9015
- });
9016
- return _setPrototypeOf(Wrapper, Class);
9017
- };
9267
+ /**
9268
+ * Push `index` up to the next non-space character
9269
+ */
9270
+ gobbleSpaces() {
9271
+ let ch = this.code;
9272
+ // Whitespace
9273
+ while (ch === Jsep.SPACE_CODE || ch === Jsep.TAB_CODE || ch === Jsep.LF_CODE || ch === Jsep.CR_CODE) {
9274
+ ch = this.expr.charCodeAt(++this.index);
9275
+ }
9276
+ this.runHook('gobble-spaces');
9277
+ }
9018
9278
 
9019
- return _wrapNativeSuper(Class);
9020
- }
9279
+ /**
9280
+ * Top-level method to parse all expressions and returns compound or single node
9281
+ * @returns {jsep.Expression}
9282
+ */
9283
+ parse() {
9284
+ this.runHook('before-all');
9285
+ const nodes = this.gobbleExpressions();
9286
+
9287
+ // If there's only one expression just try returning the expression
9288
+ const node = nodes.length === 1 ? nodes[0] : {
9289
+ type: Jsep.COMPOUND,
9290
+ body: nodes
9291
+ };
9292
+ return this.runHook('after-all', node);
9293
+ }
9021
9294
 
9022
- function _assertThisInitialized(self) {
9023
- if (self === void 0) {
9024
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
9295
+ /**
9296
+ * top-level parser (but can be reused within as well)
9297
+ * @param {number} [untilICode]
9298
+ * @returns {jsep.Expression[]}
9299
+ */
9300
+ gobbleExpressions(untilICode) {
9301
+ let nodes = [],
9302
+ ch_i,
9303
+ node;
9304
+ while (this.index < this.expr.length) {
9305
+ ch_i = this.code;
9306
+
9307
+ // Expressions can be separated by semicolons, commas, or just inferred without any
9308
+ // separators
9309
+ if (ch_i === Jsep.SEMCOL_CODE || ch_i === Jsep.COMMA_CODE) {
9310
+ this.index++; // ignore separators
9311
+ } else {
9312
+ // Try to gobble each expression individually
9313
+ if (node = this.gobbleExpression()) {
9314
+ nodes.push(node);
9315
+ // If we weren't able to find a binary expression and are out of room, then
9316
+ // the expression passed in probably has too much
9317
+ } else if (this.index < this.expr.length) {
9318
+ if (ch_i === untilICode) {
9319
+ break;
9320
+ }
9321
+ this.throwError('Unexpected "' + this.char + '"');
9322
+ }
9323
+ }
9324
+ }
9325
+ return nodes;
9025
9326
  }
9026
9327
 
9027
- return self;
9028
- }
9328
+ /**
9329
+ * The main parsing function.
9330
+ * @returns {?jsep.Expression}
9331
+ */
9332
+ gobbleExpression() {
9333
+ const node = this.searchHook('gobble-expression') || this.gobbleBinaryExpression();
9334
+ this.gobbleSpaces();
9335
+ return this.runHook('after-expression', node);
9336
+ }
9029
9337
 
9030
- function _possibleConstructorReturn(self, call) {
9031
- if (call && (typeof call === "object" || typeof call === "function")) {
9032
- return call;
9033
- } else if (call !== void 0) {
9034
- throw new TypeError("Derived constructors may only return object or undefined");
9338
+ /**
9339
+ * Search for the operation portion of the string (e.g. `+`, `===`)
9340
+ * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`)
9341
+ * and move down from 3 to 2 to 1 character until a matching binary operation is found
9342
+ * then, return that binary operation
9343
+ * @returns {string|boolean}
9344
+ */
9345
+ gobbleBinaryOp() {
9346
+ this.gobbleSpaces();
9347
+ let to_check = this.expr.substr(this.index, Jsep.max_binop_len);
9348
+ let tc_len = to_check.length;
9349
+ while (tc_len > 0) {
9350
+ // Don't accept a binary op when it is an identifier.
9351
+ // Binary ops that start with a identifier-valid character must be followed
9352
+ // by a non identifier-part valid character
9353
+ 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)))) {
9354
+ this.index += tc_len;
9355
+ return to_check;
9356
+ }
9357
+ to_check = to_check.substr(0, --tc_len);
9358
+ }
9359
+ return false;
9035
9360
  }
9036
9361
 
9037
- return _assertThisInitialized(self);
9038
- }
9362
+ /**
9363
+ * This function is responsible for gobbling an individual expression,
9364
+ * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)`
9365
+ * @returns {?jsep.BinaryExpression}
9366
+ */
9367
+ gobbleBinaryExpression() {
9368
+ let node, biop, prec, stack, biop_info, left, right, i, cur_biop;
9369
+
9370
+ // First, try to get the leftmost thing
9371
+ // Then, check to see if there's a binary operator operating on that leftmost thing
9372
+ // Don't gobbleBinaryOp without a left-hand-side
9373
+ left = this.gobbleToken();
9374
+ if (!left) {
9375
+ return left;
9376
+ }
9377
+ biop = this.gobbleBinaryOp();
9039
9378
 
9040
- function _createSuper(Derived) {
9041
- var hasNativeReflectConstruct = _isNativeReflectConstruct();
9379
+ // If there wasn't a binary operator, just return the leftmost node
9380
+ if (!biop) {
9381
+ return left;
9382
+ }
9042
9383
 
9043
- return function _createSuperInternal() {
9044
- var Super = _getPrototypeOf(Derived),
9045
- result;
9384
+ // Otherwise, we need to start a stack to properly place the binary operations in their
9385
+ // precedence structure
9386
+ biop_info = {
9387
+ value: biop,
9388
+ prec: Jsep.binaryPrecedence(biop),
9389
+ right_a: Jsep.right_associative.has(biop)
9390
+ };
9391
+ right = this.gobbleToken();
9392
+ if (!right) {
9393
+ this.throwError("Expected expression after " + biop);
9394
+ }
9395
+ stack = [left, biop_info, right];
9046
9396
 
9047
- if (hasNativeReflectConstruct) {
9048
- var NewTarget = _getPrototypeOf(this).constructor;
9397
+ // Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm)
9398
+ while (biop = this.gobbleBinaryOp()) {
9399
+ prec = Jsep.binaryPrecedence(biop);
9400
+ if (prec === 0) {
9401
+ this.index -= biop.length;
9402
+ break;
9403
+ }
9404
+ biop_info = {
9405
+ value: biop,
9406
+ prec,
9407
+ right_a: Jsep.right_associative.has(biop)
9408
+ };
9409
+ cur_biop = biop;
9410
+
9411
+ // Reduce: make a binary expression from the three topmost entries.
9412
+ const comparePrev = prev => biop_info.right_a && prev.right_a ? prec > prev.prec : prec <= prev.prec;
9413
+ while (stack.length > 2 && comparePrev(stack[stack.length - 2])) {
9414
+ right = stack.pop();
9415
+ biop = stack.pop().value;
9416
+ left = stack.pop();
9417
+ node = {
9418
+ type: Jsep.BINARY_EXP,
9419
+ operator: biop,
9420
+ left,
9421
+ right
9422
+ };
9423
+ stack.push(node);
9424
+ }
9425
+ node = this.gobbleToken();
9426
+ if (!node) {
9427
+ this.throwError("Expected expression after " + cur_biop);
9428
+ }
9429
+ stack.push(biop_info, node);
9430
+ }
9431
+ i = stack.length - 1;
9432
+ node = stack[i];
9433
+ while (i > 1) {
9434
+ node = {
9435
+ type: Jsep.BINARY_EXP,
9436
+ operator: stack[i - 1].value,
9437
+ left: stack[i - 2],
9438
+ right: node
9439
+ };
9440
+ i -= 2;
9441
+ }
9442
+ return node;
9443
+ }
9049
9444
 
9050
- result = Reflect.construct(Super, arguments, NewTarget);
9445
+ /**
9446
+ * An individual part of a binary expression:
9447
+ * e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis)
9448
+ * @returns {boolean|jsep.Expression}
9449
+ */
9450
+ gobbleToken() {
9451
+ let ch, to_check, tc_len, node;
9452
+ this.gobbleSpaces();
9453
+ node = this.searchHook('gobble-token');
9454
+ if (node) {
9455
+ return this.runHook('after-token', node);
9456
+ }
9457
+ ch = this.code;
9458
+ if (Jsep.isDecimalDigit(ch) || ch === Jsep.PERIOD_CODE) {
9459
+ // Char code 46 is a dot `.` which can start off a numeric literal
9460
+ return this.gobbleNumericLiteral();
9461
+ }
9462
+ if (ch === Jsep.SQUOTE_CODE || ch === Jsep.DQUOTE_CODE) {
9463
+ // Single or double quotes
9464
+ node = this.gobbleStringLiteral();
9465
+ } else if (ch === Jsep.OBRACK_CODE) {
9466
+ node = this.gobbleArray();
9051
9467
  } else {
9052
- result = Super.apply(this, arguments);
9468
+ to_check = this.expr.substr(this.index, Jsep.max_unop_len);
9469
+ tc_len = to_check.length;
9470
+ while (tc_len > 0) {
9471
+ // Don't accept an unary op when it is an identifier.
9472
+ // Unary ops that start with a identifier-valid character must be followed
9473
+ // by a non identifier-part valid character
9474
+ 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)))) {
9475
+ this.index += tc_len;
9476
+ const argument = this.gobbleToken();
9477
+ if (!argument) {
9478
+ this.throwError('missing unaryOp argument');
9479
+ }
9480
+ return this.runHook('after-token', {
9481
+ type: Jsep.UNARY_EXP,
9482
+ operator: to_check,
9483
+ argument,
9484
+ prefix: true
9485
+ });
9486
+ }
9487
+ to_check = to_check.substr(0, --tc_len);
9488
+ }
9489
+ if (Jsep.isIdentifierStart(ch)) {
9490
+ node = this.gobbleIdentifier();
9491
+ if (Jsep.literals.hasOwnProperty(node.name)) {
9492
+ node = {
9493
+ type: Jsep.LITERAL,
9494
+ value: Jsep.literals[node.name],
9495
+ raw: node.name
9496
+ };
9497
+ } else if (node.name === Jsep.this_str) {
9498
+ node = {
9499
+ type: Jsep.THIS_EXP
9500
+ };
9501
+ }
9502
+ } else if (ch === Jsep.OPAREN_CODE) {
9503
+ // open parenthesis
9504
+ node = this.gobbleGroup();
9505
+ }
9506
+ }
9507
+ if (!node) {
9508
+ return this.runHook('after-token', false);
9053
9509
  }
9510
+ node = this.gobbleTokenProperty(node);
9511
+ return this.runHook('after-token', node);
9512
+ }
9054
9513
 
9055
- return _possibleConstructorReturn(this, result);
9056
- };
9057
- }
9514
+ /**
9515
+ * Gobble properties of of identifiers/strings/arrays/groups.
9516
+ * e.g. `foo`, `bar.baz`, `foo['bar'].baz`
9517
+ * It also gobbles function calls:
9518
+ * e.g. `Math.acos(obj.angle)`
9519
+ * @param {jsep.Expression} node
9520
+ * @returns {jsep.Expression}
9521
+ */
9522
+ gobbleTokenProperty(node) {
9523
+ this.gobbleSpaces();
9524
+ let ch = this.code;
9525
+ while (ch === Jsep.PERIOD_CODE || ch === Jsep.OBRACK_CODE || ch === Jsep.OPAREN_CODE || ch === Jsep.QUMARK_CODE) {
9526
+ let optional;
9527
+ if (ch === Jsep.QUMARK_CODE) {
9528
+ if (this.expr.charCodeAt(this.index + 1) !== Jsep.PERIOD_CODE) {
9529
+ break;
9530
+ }
9531
+ optional = true;
9532
+ this.index += 2;
9533
+ this.gobbleSpaces();
9534
+ ch = this.code;
9535
+ }
9536
+ this.index++;
9537
+ if (ch === Jsep.OBRACK_CODE) {
9538
+ node = {
9539
+ type: Jsep.MEMBER_EXP,
9540
+ computed: true,
9541
+ object: node,
9542
+ property: this.gobbleExpression()
9543
+ };
9544
+ if (!node.property) {
9545
+ this.throwError('Unexpected "' + this.char + '"');
9546
+ }
9547
+ this.gobbleSpaces();
9548
+ ch = this.code;
9549
+ if (ch !== Jsep.CBRACK_CODE) {
9550
+ this.throwError('Unclosed [');
9551
+ }
9552
+ this.index++;
9553
+ } else if (ch === Jsep.OPAREN_CODE) {
9554
+ // A function call is being made; gobble all the arguments
9555
+ node = {
9556
+ type: Jsep.CALL_EXP,
9557
+ 'arguments': this.gobbleArguments(Jsep.CPAREN_CODE),
9558
+ callee: node
9559
+ };
9560
+ } else if (ch === Jsep.PERIOD_CODE || optional) {
9561
+ if (optional) {
9562
+ this.index--;
9563
+ }
9564
+ this.gobbleSpaces();
9565
+ node = {
9566
+ type: Jsep.MEMBER_EXP,
9567
+ computed: false,
9568
+ object: node,
9569
+ property: this.gobbleIdentifier()
9570
+ };
9571
+ }
9572
+ if (optional) {
9573
+ node.optional = true;
9574
+ } // else leave undefined for compatibility with esprima
9058
9575
 
9059
- function _toConsumableArray(arr) {
9060
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
9061
- }
9576
+ this.gobbleSpaces();
9577
+ ch = this.code;
9578
+ }
9579
+ return node;
9580
+ }
9062
9581
 
9063
- function _arrayWithoutHoles(arr) {
9064
- if (Array.isArray(arr)) return _arrayLikeToArray(arr);
9065
- }
9582
+ /**
9583
+ * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to
9584
+ * keep track of everything in the numeric literal and then calling `parseFloat` on that string
9585
+ * @returns {jsep.Literal}
9586
+ */
9587
+ gobbleNumericLiteral() {
9588
+ let number = '',
9589
+ ch,
9590
+ chCode;
9591
+ while (Jsep.isDecimalDigit(this.code)) {
9592
+ number += this.expr.charAt(this.index++);
9593
+ }
9594
+ if (this.code === Jsep.PERIOD_CODE) {
9595
+ // can start with a decimal marker
9596
+ number += this.expr.charAt(this.index++);
9597
+ while (Jsep.isDecimalDigit(this.code)) {
9598
+ number += this.expr.charAt(this.index++);
9599
+ }
9600
+ }
9601
+ ch = this.char;
9602
+ if (ch === 'e' || ch === 'E') {
9603
+ // exponent marker
9604
+ number += this.expr.charAt(this.index++);
9605
+ ch = this.char;
9606
+ if (ch === '+' || ch === '-') {
9607
+ // exponent sign
9608
+ number += this.expr.charAt(this.index++);
9609
+ }
9610
+ while (Jsep.isDecimalDigit(this.code)) {
9611
+ // exponent itself
9612
+ number += this.expr.charAt(this.index++);
9613
+ }
9614
+ if (!Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1))) {
9615
+ this.throwError('Expected exponent (' + number + this.char + ')');
9616
+ }
9617
+ }
9618
+ chCode = this.code;
9066
9619
 
9067
- function _iterableToArray(iter) {
9068
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
9069
- }
9620
+ // Check to make sure this isn't a variable name that start with a number (123abc)
9621
+ if (Jsep.isIdentifierStart(chCode)) {
9622
+ this.throwError('Variable names cannot start with a number (' + number + this.char + ')');
9623
+ } else if (chCode === Jsep.PERIOD_CODE || number.length === 1 && number.charCodeAt(0) === Jsep.PERIOD_CODE) {
9624
+ this.throwError('Unexpected period');
9625
+ }
9626
+ return {
9627
+ type: Jsep.LITERAL,
9628
+ value: parseFloat(number),
9629
+ raw: number
9630
+ };
9631
+ }
9070
9632
 
9071
- function _unsupportedIterableToArray(o, minLen) {
9072
- if (!o) return;
9073
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
9074
- var n = Object.prototype.toString.call(o).slice(8, -1);
9075
- if (n === "Object" && o.constructor) n = o.constructor.name;
9076
- if (n === "Map" || n === "Set") return Array.from(o);
9077
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
9078
- }
9633
+ /**
9634
+ * Parses a string literal, staring with single or double quotes with basic support for escape codes
9635
+ * e.g. `"hello world"`, `'this is\nJSEP'`
9636
+ * @returns {jsep.Literal}
9637
+ */
9638
+ gobbleStringLiteral() {
9639
+ let str = '';
9640
+ const startIndex = this.index;
9641
+ const quote = this.expr.charAt(this.index++);
9642
+ let closed = false;
9643
+ while (this.index < this.expr.length) {
9644
+ let ch = this.expr.charAt(this.index++);
9645
+ if (ch === quote) {
9646
+ closed = true;
9647
+ break;
9648
+ } else if (ch === '\\') {
9649
+ // Check for all of the common escape codes
9650
+ ch = this.expr.charAt(this.index++);
9651
+ switch (ch) {
9652
+ case 'n':
9653
+ str += '\n';
9654
+ break;
9655
+ case 'r':
9656
+ str += '\r';
9657
+ break;
9658
+ case 't':
9659
+ str += '\t';
9660
+ break;
9661
+ case 'b':
9662
+ str += '\b';
9663
+ break;
9664
+ case 'f':
9665
+ str += '\f';
9666
+ break;
9667
+ case 'v':
9668
+ str += '\x0B';
9669
+ break;
9670
+ default:
9671
+ str += ch;
9672
+ }
9673
+ } else {
9674
+ str += ch;
9675
+ }
9676
+ }
9677
+ if (!closed) {
9678
+ this.throwError('Unclosed quote after "' + str + '"');
9679
+ }
9680
+ return {
9681
+ type: Jsep.LITERAL,
9682
+ value: str,
9683
+ raw: this.expr.substring(startIndex, this.index)
9684
+ };
9685
+ }
9079
9686
 
9080
- function _arrayLikeToArray(arr, len) {
9081
- if (len == null || len > arr.length) len = arr.length;
9687
+ /**
9688
+ * Gobbles only identifiers
9689
+ * e.g.: `foo`, `_value`, `$x1`
9690
+ * Also, this function checks if that identifier is a literal:
9691
+ * (e.g. `true`, `false`, `null`) or `this`
9692
+ * @returns {jsep.Identifier}
9693
+ */
9694
+ gobbleIdentifier() {
9695
+ let ch = this.code,
9696
+ start = this.index;
9697
+ if (Jsep.isIdentifierStart(ch)) {
9698
+ this.index++;
9699
+ } else {
9700
+ this.throwError('Unexpected ' + this.char);
9701
+ }
9702
+ while (this.index < this.expr.length) {
9703
+ ch = this.code;
9704
+ if (Jsep.isIdentifierPart(ch)) {
9705
+ this.index++;
9706
+ } else {
9707
+ break;
9708
+ }
9709
+ }
9710
+ return {
9711
+ type: Jsep.IDENTIFIER,
9712
+ name: this.expr.slice(start, this.index)
9713
+ };
9714
+ }
9082
9715
 
9083
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
9716
+ /**
9717
+ * Gobbles a list of arguments within the context of a function call
9718
+ * or array literal. This function also assumes that the opening character
9719
+ * `(` or `[` has already been gobbled, and gobbles expressions and commas
9720
+ * until the terminator character `)` or `]` is encountered.
9721
+ * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]`
9722
+ * @param {number} termination
9723
+ * @returns {jsep.Expression[]}
9724
+ */
9725
+ gobbleArguments(termination) {
9726
+ const args = [];
9727
+ let closed = false;
9728
+ let separator_count = 0;
9729
+ while (this.index < this.expr.length) {
9730
+ this.gobbleSpaces();
9731
+ let ch_i = this.code;
9732
+ if (ch_i === termination) {
9733
+ // done parsing
9734
+ closed = true;
9735
+ this.index++;
9736
+ if (termination === Jsep.CPAREN_CODE && separator_count && separator_count >= args.length) {
9737
+ this.throwError('Unexpected token ' + String.fromCharCode(termination));
9738
+ }
9739
+ break;
9740
+ } else if (ch_i === Jsep.COMMA_CODE) {
9741
+ // between expressions
9742
+ this.index++;
9743
+ separator_count++;
9744
+ if (separator_count !== args.length) {
9745
+ // missing argument
9746
+ if (termination === Jsep.CPAREN_CODE) {
9747
+ this.throwError('Unexpected token ,');
9748
+ } else if (termination === Jsep.CBRACK_CODE) {
9749
+ for (let arg = args.length; arg < separator_count; arg++) {
9750
+ args.push(null);
9751
+ }
9752
+ }
9753
+ }
9754
+ } else if (args.length !== separator_count && separator_count !== 0) {
9755
+ // NOTE: `&& separator_count !== 0` allows for either all commas, or all spaces as arguments
9756
+ this.throwError('Expected comma');
9757
+ } else {
9758
+ const node = this.gobbleExpression();
9759
+ if (!node || node.type === Jsep.COMPOUND) {
9760
+ this.throwError('Expected comma');
9761
+ }
9762
+ args.push(node);
9763
+ }
9764
+ }
9765
+ if (!closed) {
9766
+ this.throwError('Expected ' + String.fromCharCode(termination));
9767
+ }
9768
+ return args;
9769
+ }
9084
9770
 
9085
- return arr2;
9086
- }
9771
+ /**
9772
+ * Responsible for parsing a group of things within parentheses `()`
9773
+ * that have no identifier in front (so not a function call)
9774
+ * This function assumes that it needs to gobble the opening parenthesis
9775
+ * and then tries to gobble everything within that parenthesis, assuming
9776
+ * that the next thing it should see is the close parenthesis. If not,
9777
+ * then the expression probably doesn't have a `)`
9778
+ * @returns {boolean|jsep.Expression}
9779
+ */
9780
+ gobbleGroup() {
9781
+ this.index++;
9782
+ let nodes = this.gobbleExpressions(Jsep.CPAREN_CODE);
9783
+ if (this.code === Jsep.CPAREN_CODE) {
9784
+ this.index++;
9785
+ if (nodes.length === 1) {
9786
+ return nodes[0];
9787
+ } else if (!nodes.length) {
9788
+ return false;
9789
+ } else {
9790
+ return {
9791
+ type: Jsep.SEQUENCE_EXP,
9792
+ expressions: nodes
9793
+ };
9794
+ }
9795
+ } else {
9796
+ this.throwError('Unclosed (');
9797
+ }
9798
+ }
9087
9799
 
9088
- function _nonIterableSpread() {
9089
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
9800
+ /**
9801
+ * Responsible for parsing Array literals `[1, 2, 3]`
9802
+ * This function assumes that it needs to gobble the opening bracket
9803
+ * and then tries to gobble the expressions as arguments.
9804
+ * @returns {jsep.ArrayExpression}
9805
+ */
9806
+ gobbleArray() {
9807
+ this.index++;
9808
+ return {
9809
+ type: Jsep.ARRAY_EXP,
9810
+ elements: this.gobbleArguments(Jsep.CBRACK_CODE)
9811
+ };
9812
+ }
9090
9813
  }
9091
9814
 
9092
- function _createForOfIteratorHelper(o, allowArrayLike) {
9093
- var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
9815
+ // Static fields:
9816
+ const hooks = new Hooks();
9817
+ Object.assign(Jsep, {
9818
+ hooks,
9819
+ plugins: new Plugins(Jsep),
9820
+ // Node Types
9821
+ // ----------
9822
+ // This is the full set of types that any JSEP node can be.
9823
+ // Store them here to save space when minified
9824
+ COMPOUND: 'Compound',
9825
+ SEQUENCE_EXP: 'SequenceExpression',
9826
+ IDENTIFIER: 'Identifier',
9827
+ MEMBER_EXP: 'MemberExpression',
9828
+ LITERAL: 'Literal',
9829
+ THIS_EXP: 'ThisExpression',
9830
+ CALL_EXP: 'CallExpression',
9831
+ UNARY_EXP: 'UnaryExpression',
9832
+ BINARY_EXP: 'BinaryExpression',
9833
+ ARRAY_EXP: 'ArrayExpression',
9834
+ TAB_CODE: 9,
9835
+ LF_CODE: 10,
9836
+ CR_CODE: 13,
9837
+ SPACE_CODE: 32,
9838
+ PERIOD_CODE: 46,
9839
+ // '.'
9840
+ COMMA_CODE: 44,
9841
+ // ','
9842
+ SQUOTE_CODE: 39,
9843
+ // single quote
9844
+ DQUOTE_CODE: 34,
9845
+ // double quotes
9846
+ OPAREN_CODE: 40,
9847
+ // (
9848
+ CPAREN_CODE: 41,
9849
+ // )
9850
+ OBRACK_CODE: 91,
9851
+ // [
9852
+ CBRACK_CODE: 93,
9853
+ // ]
9854
+ QUMARK_CODE: 63,
9855
+ // ?
9856
+ SEMCOL_CODE: 59,
9857
+ // ;
9858
+ COLON_CODE: 58,
9859
+ // :
9860
+
9861
+ // Operations
9862
+ // ----------
9863
+ // Use a quickly-accessible map to store all of the unary operators
9864
+ // Values are set to `1` (it really doesn't matter)
9865
+ unary_ops: {
9866
+ '-': 1,
9867
+ '!': 1,
9868
+ '~': 1,
9869
+ '+': 1
9870
+ },
9871
+ // Also use a map for the binary operations but set their values to their
9872
+ // binary precedence for quick reference (higher number = higher precedence)
9873
+ // see [Order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)
9874
+ binary_ops: {
9875
+ '||': 1,
9876
+ '&&': 2,
9877
+ '|': 3,
9878
+ '^': 4,
9879
+ '&': 5,
9880
+ '==': 6,
9881
+ '!=': 6,
9882
+ '===': 6,
9883
+ '!==': 6,
9884
+ '<': 7,
9885
+ '>': 7,
9886
+ '<=': 7,
9887
+ '>=': 7,
9888
+ '<<': 8,
9889
+ '>>': 8,
9890
+ '>>>': 8,
9891
+ '+': 9,
9892
+ '-': 9,
9893
+ '*': 10,
9894
+ '/': 10,
9895
+ '%': 10
9896
+ },
9897
+ // sets specific binary_ops as right-associative
9898
+ right_associative: new Set(),
9899
+ // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char)
9900
+ additional_identifier_chars: new Set(['$', '_']),
9901
+ // Literals
9902
+ // ----------
9903
+ // Store the values to return for the various literals we may encounter
9904
+ literals: {
9905
+ 'true': true,
9906
+ 'false': false,
9907
+ 'null': null
9908
+ },
9909
+ // Except for `this`, which is special. This could be changed to something like `'self'` as well
9910
+ this_str: 'this'
9911
+ });
9912
+ Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);
9913
+ Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);
9914
+
9915
+ // Backward Compatibility:
9916
+ const jsep = expr => new Jsep(expr).parse();
9917
+ const stdClassProps = Object.getOwnPropertyNames(class Test {});
9918
+ Object.getOwnPropertyNames(Jsep).filter(prop => !stdClassProps.includes(prop) && jsep[prop] === undefined).forEach(m => {
9919
+ jsep[m] = Jsep[m];
9920
+ });
9921
+ jsep.Jsep = Jsep; // allows for const { Jsep } = require('jsep');
9922
+
9923
+ const CONDITIONAL_EXP = 'ConditionalExpression';
9924
+ var ternary = {
9925
+ name: 'ternary',
9926
+ init(jsep) {
9927
+ // Ternary expression: test ? consequent : alternate
9928
+ jsep.hooks.add('after-expression', function gobbleTernary(env) {
9929
+ if (env.node && this.code === jsep.QUMARK_CODE) {
9930
+ this.index++;
9931
+ const test = env.node;
9932
+ const consequent = this.gobbleExpression();
9933
+ if (!consequent) {
9934
+ this.throwError('Expected expression');
9935
+ }
9936
+ this.gobbleSpaces();
9937
+ if (this.code === jsep.COLON_CODE) {
9938
+ this.index++;
9939
+ const alternate = this.gobbleExpression();
9940
+ if (!alternate) {
9941
+ this.throwError('Expected expression');
9942
+ }
9943
+ env.node = {
9944
+ type: CONDITIONAL_EXP,
9945
+ test,
9946
+ consequent,
9947
+ alternate
9948
+ };
9094
9949
 
9095
- if (!it) {
9096
- if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
9097
- if (it) o = it;
9098
- var i = 0;
9950
+ // check for operators of higher priority than ternary (i.e. assignment)
9951
+ // jsep sets || at 1, and assignment at 0.9, and conditional should be between them
9952
+ if (test.operator && jsep.binary_ops[test.operator] <= 0.9) {
9953
+ let newTest = test;
9954
+ while (newTest.right.operator && jsep.binary_ops[newTest.right.operator] <= 0.9) {
9955
+ newTest = newTest.right;
9956
+ }
9957
+ env.node.test = newTest.right;
9958
+ newTest.right = env.node;
9959
+ env.node = test;
9960
+ }
9961
+ } else {
9962
+ this.throwError('Expected :');
9963
+ }
9964
+ }
9965
+ });
9966
+ }
9967
+ };
9099
9968
 
9100
- var F = function () {};
9969
+ // Add default plugins:
9970
+
9971
+ jsep.plugins.register(ternary);
9972
+
9973
+ const FSLASH_CODE = 47; // '/'
9974
+ const BSLASH_CODE = 92; // '\\'
9975
+
9976
+ var index = {
9977
+ name: 'regex',
9978
+ init(jsep) {
9979
+ // Regex literal: /abc123/ig
9980
+ jsep.hooks.add('gobble-token', function gobbleRegexLiteral(env) {
9981
+ if (this.code === FSLASH_CODE) {
9982
+ const patternIndex = ++this.index;
9983
+ let inCharSet = false;
9984
+ while (this.index < this.expr.length) {
9985
+ if (this.code === FSLASH_CODE && !inCharSet) {
9986
+ const pattern = this.expr.slice(patternIndex, this.index);
9987
+ let flags = '';
9988
+ while (++this.index < this.expr.length) {
9989
+ const code = this.code;
9990
+ if (code >= 97 && code <= 122 // a...z
9991
+ || code >= 65 && code <= 90 // A...Z
9992
+ || code >= 48 && code <= 57) {
9993
+ // 0-9
9994
+ flags += this.char;
9995
+ } else {
9996
+ break;
9997
+ }
9998
+ }
9999
+ let value;
10000
+ try {
10001
+ value = new RegExp(pattern, flags);
10002
+ } catch (e) {
10003
+ this.throwError(e.message);
10004
+ }
10005
+ env.node = {
10006
+ type: jsep.LITERAL,
10007
+ value,
10008
+ raw: this.expr.slice(patternIndex - 1, this.index)
10009
+ };
10010
+
10011
+ // allow . [] and () after regex: /regex/.test(a)
10012
+ env.node = this.gobbleTokenProperty(env.node);
10013
+ return env.node;
10014
+ }
10015
+ if (this.code === jsep.OBRACK_CODE) {
10016
+ inCharSet = true;
10017
+ } else if (inCharSet && this.code === jsep.CBRACK_CODE) {
10018
+ inCharSet = false;
10019
+ }
10020
+ this.index += this.code === BSLASH_CODE ? 2 : 1;
10021
+ }
10022
+ this.throwError('Unclosed Regex');
10023
+ }
10024
+ });
10025
+ }
10026
+ };
9101
10027
 
9102
- return {
9103
- s: F,
9104
- n: function () {
9105
- if (i >= o.length) return {
9106
- done: true
9107
- };
9108
- return {
9109
- done: false,
9110
- value: o[i++]
10028
+ const PLUS_CODE = 43; // +
10029
+ const MINUS_CODE = 45; // -
10030
+
10031
+ const plugin = {
10032
+ name: 'assignment',
10033
+ assignmentOperators: new Set(['=', '*=', '**=', '/=', '%=', '+=', '-=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']),
10034
+ updateOperators: [PLUS_CODE, MINUS_CODE],
10035
+ assignmentPrecedence: 0.9,
10036
+ init(jsep) {
10037
+ const updateNodeTypes = [jsep.IDENTIFIER, jsep.MEMBER_EXP];
10038
+ plugin.assignmentOperators.forEach(op => jsep.addBinaryOp(op, plugin.assignmentPrecedence, true));
10039
+ jsep.hooks.add('gobble-token', function gobbleUpdatePrefix(env) {
10040
+ const code = this.code;
10041
+ if (plugin.updateOperators.some(c => c === code && c === this.expr.charCodeAt(this.index + 1))) {
10042
+ this.index += 2;
10043
+ env.node = {
10044
+ type: 'UpdateExpression',
10045
+ operator: code === PLUS_CODE ? '++' : '--',
10046
+ argument: this.gobbleTokenProperty(this.gobbleIdentifier()),
10047
+ prefix: true
10048
+ };
10049
+ if (!env.node.argument || !updateNodeTypes.includes(env.node.argument.type)) {
10050
+ this.throwError(`Unexpected ${env.node.operator}`);
10051
+ }
10052
+ }
10053
+ });
10054
+ jsep.hooks.add('after-token', function gobbleUpdatePostfix(env) {
10055
+ if (env.node) {
10056
+ const code = this.code;
10057
+ if (plugin.updateOperators.some(c => c === code && c === this.expr.charCodeAt(this.index + 1))) {
10058
+ if (!updateNodeTypes.includes(env.node.type)) {
10059
+ this.throwError(`Unexpected ${env.node.operator}`);
10060
+ }
10061
+ this.index += 2;
10062
+ env.node = {
10063
+ type: 'UpdateExpression',
10064
+ operator: code === PLUS_CODE ? '++' : '--',
10065
+ argument: env.node,
10066
+ prefix: false
9111
10067
  };
9112
- },
9113
- e: function (e) {
9114
- throw e;
9115
- },
9116
- f: F
9117
- };
10068
+ }
10069
+ }
10070
+ });
10071
+ jsep.hooks.add('after-expression', function gobbleAssignment(env) {
10072
+ if (env.node) {
10073
+ // Note: Binaries can be chained in a single expression to respect
10074
+ // operator precedence (i.e. a = b = 1 + 2 + 3)
10075
+ // Update all binary assignment nodes in the tree
10076
+ updateBinariesToAssignments(env.node);
10077
+ }
10078
+ });
10079
+ function updateBinariesToAssignments(node) {
10080
+ if (plugin.assignmentOperators.has(node.operator)) {
10081
+ node.type = 'AssignmentExpression';
10082
+ updateBinariesToAssignments(node.left);
10083
+ updateBinariesToAssignments(node.right);
10084
+ } else if (!node.operator) {
10085
+ Object.values(node).forEach(val => {
10086
+ if (val && typeof val === 'object') {
10087
+ updateBinariesToAssignments(val);
10088
+ }
10089
+ });
10090
+ }
10091
+ }
10092
+ }
10093
+ };
10094
+
10095
+ /* eslint-disable no-bitwise -- Convenient */
10096
+
10097
+ // register plugins
10098
+ jsep.plugins.register(index, plugin);
10099
+ const SafeEval = {
10100
+ /**
10101
+ * @param {jsep.Expression} ast
10102
+ * @param {Record<string, any>} subs
10103
+ */
10104
+ evalAst(ast, subs) {
10105
+ switch (ast.type) {
10106
+ case 'BinaryExpression':
10107
+ case 'LogicalExpression':
10108
+ return SafeEval.evalBinaryExpression(ast, subs);
10109
+ case 'Compound':
10110
+ return SafeEval.evalCompound(ast, subs);
10111
+ case 'ConditionalExpression':
10112
+ return SafeEval.evalConditionalExpression(ast, subs);
10113
+ case 'Identifier':
10114
+ return SafeEval.evalIdentifier(ast, subs);
10115
+ case 'Literal':
10116
+ return SafeEval.evalLiteral(ast, subs);
10117
+ case 'MemberExpression':
10118
+ return SafeEval.evalMemberExpression(ast, subs);
10119
+ case 'UnaryExpression':
10120
+ return SafeEval.evalUnaryExpression(ast, subs);
10121
+ case 'ArrayExpression':
10122
+ return SafeEval.evalArrayExpression(ast, subs);
10123
+ case 'CallExpression':
10124
+ return SafeEval.evalCallExpression(ast, subs);
10125
+ case 'AssignmentExpression':
10126
+ return SafeEval.evalAssignmentExpression(ast, subs);
10127
+ default:
10128
+ throw SyntaxError('Unexpected expression', ast);
10129
+ }
10130
+ },
10131
+ evalBinaryExpression(ast, subs) {
10132
+ const result = {
10133
+ '||': (a, b) => a || b(),
10134
+ '&&': (a, b) => a && b(),
10135
+ '|': (a, b) => a | b(),
10136
+ '^': (a, b) => a ^ b(),
10137
+ '&': (a, b) => a & b(),
10138
+ // eslint-disable-next-line eqeqeq -- API
10139
+ '==': (a, b) => a == b(),
10140
+ // eslint-disable-next-line eqeqeq -- API
10141
+ '!=': (a, b) => a != b(),
10142
+ '===': (a, b) => a === b(),
10143
+ '!==': (a, b) => a !== b(),
10144
+ '<': (a, b) => a < b(),
10145
+ '>': (a, b) => a > b(),
10146
+ '<=': (a, b) => a <= b(),
10147
+ '>=': (a, b) => a >= b(),
10148
+ '<<': (a, b) => a << b(),
10149
+ '>>': (a, b) => a >> b(),
10150
+ '>>>': (a, b) => a >>> b(),
10151
+ '+': (a, b) => a + b(),
10152
+ '-': (a, b) => a - b(),
10153
+ '*': (a, b) => a * b(),
10154
+ '/': (a, b) => a / b(),
10155
+ '%': (a, b) => a % b()
10156
+ }[ast.operator](SafeEval.evalAst(ast.left, subs), () => SafeEval.evalAst(ast.right, subs));
10157
+ return result;
10158
+ },
10159
+ evalCompound(ast, subs) {
10160
+ let last;
10161
+ for (let i = 0; i < ast.body.length; i++) {
10162
+ if (ast.body[i].type === 'Identifier' && ['var', 'let', 'const'].includes(ast.body[i].name) && ast.body[i + 1] && ast.body[i + 1].type === 'AssignmentExpression') {
10163
+ // var x=2; is detected as
10164
+ // [{Identifier var}, {AssignmentExpression x=2}]
10165
+ // eslint-disable-next-line @stylistic/max-len -- Long
10166
+ // eslint-disable-next-line sonarjs/updated-loop-counter -- Convenient
10167
+ i += 1;
10168
+ }
10169
+ const expr = ast.body[i];
10170
+ last = SafeEval.evalAst(expr, subs);
10171
+ }
10172
+ return last;
10173
+ },
10174
+ evalConditionalExpression(ast, subs) {
10175
+ if (SafeEval.evalAst(ast.test, subs)) {
10176
+ return SafeEval.evalAst(ast.consequent, subs);
10177
+ }
10178
+ return SafeEval.evalAst(ast.alternate, subs);
10179
+ },
10180
+ evalIdentifier(ast, subs) {
10181
+ if (ast.name in subs) {
10182
+ return subs[ast.name];
10183
+ }
10184
+ throw ReferenceError(`${ast.name} is not defined`);
10185
+ },
10186
+ evalLiteral(ast) {
10187
+ return ast.value;
10188
+ },
10189
+ evalMemberExpression(ast, subs) {
10190
+ const prop = ast.computed ? SafeEval.evalAst(ast.property) // `object[property]`
10191
+ : ast.property.name; // `object.property` property is Identifier
10192
+ const obj = SafeEval.evalAst(ast.object, subs);
10193
+ const result = obj[prop];
10194
+ if (typeof result === 'function') {
10195
+ if (obj === Function && prop === 'bind') {
10196
+ throw new Error('Function.prototype.bind is disabled');
10197
+ }
10198
+ if (obj === Function && (prop === 'call' || prop === 'apply')) {
10199
+ throw new Error('Function.prototype.call and ' + 'Function.prototype.apply are disabled');
10200
+ }
10201
+ if (result === Function) {
10202
+ return result; // Don't bind so can identify and throw later
10203
+ }
10204
+ return result.bind(obj); // arrow functions aren't affected by bind.
10205
+ }
10206
+ return result;
10207
+ },
10208
+ evalUnaryExpression(ast, subs) {
10209
+ const result = {
10210
+ '-': a => -SafeEval.evalAst(a, subs),
10211
+ '!': a => !SafeEval.evalAst(a, subs),
10212
+ '~': a => ~SafeEval.evalAst(a, subs),
10213
+ // eslint-disable-next-line no-implicit-coercion -- API
10214
+ '+': a => +SafeEval.evalAst(a, subs)
10215
+ }[ast.operator](ast.argument);
10216
+ return result;
10217
+ },
10218
+ evalArrayExpression(ast, subs) {
10219
+ return ast.elements.map(el => SafeEval.evalAst(el, subs));
10220
+ },
10221
+ evalCallExpression(ast, subs) {
10222
+ const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
10223
+ const func = SafeEval.evalAst(ast.callee, subs);
10224
+ if (func === Function) {
10225
+ throw new Error('Function constructor is disabled');
10226
+ }
10227
+ return func(...args);
10228
+ },
10229
+ evalAssignmentExpression(ast, subs) {
10230
+ if (ast.left.type !== 'Identifier') {
10231
+ throw SyntaxError('Invalid left-hand side in assignment');
10232
+ }
10233
+ const id = ast.left.name;
10234
+ if (id === '__proto__') {
10235
+ throw new Error('Assignment to __proto__ is disabled');
9118
10236
  }
10237
+ const value = SafeEval.evalAst(ast.right, subs);
10238
+ subs[id] = value;
10239
+ return subs[id];
10240
+ }
10241
+ };
9119
10242
 
9120
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
10243
+ /**
10244
+ * A replacement for NodeJS' VM.Script which is also {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | Content Security Policy} friendly.
10245
+ */
10246
+ class SafeScript {
10247
+ /**
10248
+ * @param {string} expr Expression to evaluate
10249
+ */
10250
+ constructor(expr) {
10251
+ this.code = expr;
10252
+ this.ast = jsep(this.code);
9121
10253
  }
9122
10254
 
9123
- var normalCompletion = true,
9124
- didErr = false,
9125
- err;
9126
- return {
9127
- s: function () {
9128
- it = it.call(o);
9129
- },
9130
- n: function () {
9131
- var step = it.next();
9132
- normalCompletion = step.done;
9133
- return step;
9134
- },
9135
- e: function (e) {
9136
- didErr = true;
9137
- err = e;
9138
- },
9139
- f: function () {
9140
- try {
9141
- if (!normalCompletion && it.return != null) it.return();
9142
- } finally {
9143
- if (didErr) throw err;
9144
- }
9145
- }
9146
- };
10255
+ /**
10256
+ * @param {object} context Object whose items will be added
10257
+ * to evaluation
10258
+ * @returns {EvaluatedResult} Result of evaluated code
10259
+ */
10260
+ runInNewContext(context) {
10261
+ const keyMap = {
10262
+ ...context
10263
+ };
10264
+ return SafeEval.evalAst(this.ast, keyMap);
10265
+ }
9147
10266
  }
9148
10267
 
9149
- var hasOwnProp = Object.prototype.hasOwnProperty;
10268
+ /* eslint-disable camelcase -- Convenient for escaping */
10269
+
10270
+
9150
10271
  /**
9151
- * @typedef {null|boolean|number|string|PlainObject|GenericArray} JSONObject
10272
+ * @typedef {null|boolean|number|string|object|GenericArray} JSONObject
9152
10273
  */
9153
10274
 
9154
10275
  /**
@@ -9165,7 +10286,6 @@ var hasOwnProp = Object.prototype.hasOwnProperty;
9165
10286
  * @param {AnyItem} item Array item to add (to end)
9166
10287
  * @returns {GenericArray} Copy of the original array
9167
10288
  */
9168
-
9169
10289
  function push(arr, item) {
9170
10290
  arr = arr.slice();
9171
10291
  arr.push(item);
@@ -9177,52 +10297,39 @@ function push(arr, item) {
9177
10297
  * @param {GenericArray} arr Array to copy and into which to unshift
9178
10298
  * @returns {GenericArray} Copy of the original array
9179
10299
  */
9180
-
9181
-
9182
10300
  function unshift(item, arr) {
9183
10301
  arr = arr.slice();
9184
10302
  arr.unshift(item);
9185
10303
  return arr;
9186
10304
  }
10305
+
9187
10306
  /**
9188
10307
  * Caught when JSONPath is used without `new` but rethrown if with `new`
9189
10308
  * @extends Error
9190
10309
  */
9191
-
9192
-
9193
- var NewError = /*#__PURE__*/function (_Error) {
9194
- _inherits(NewError, _Error);
9195
-
9196
- var _super = _createSuper(NewError);
9197
-
10310
+ class NewError extends Error {
9198
10311
  /**
9199
10312
  * @param {AnyResult} value The evaluated scalar value
9200
10313
  */
9201
- function NewError(value) {
9202
- var _this;
9203
-
9204
- _classCallCheck(this, NewError);
9205
-
9206
- _this = _super.call(this, 'JSONPath should not be called with "new" (it prevents return ' + 'of (unwrapped) scalar values)');
9207
- _this.avoidNew = true;
9208
- _this.value = value;
9209
- _this.name = 'NewError';
9210
- return _this;
10314
+ constructor(value) {
10315
+ super('JSONPath should not be called with "new" (it prevents return ' + 'of (unwrapped) scalar values)');
10316
+ this.avoidNew = true;
10317
+ this.value = value;
10318
+ this.name = 'NewError';
9211
10319
  }
10320
+ }
9212
10321
 
9213
- return _createClass(NewError);
9214
- }( /*#__PURE__*/_wrapNativeSuper(Error));
9215
10322
  /**
9216
- * @typedef {PlainObject} ReturnObject
10323
+ * @typedef {object} ReturnObject
9217
10324
  * @property {string} path
9218
10325
  * @property {JSONObject} value
9219
- * @property {PlainObject|GenericArray} parent
10326
+ * @property {object|GenericArray} parent
9220
10327
  * @property {string} parentProperty
9221
10328
  */
9222
10329
 
9223
10330
  /**
9224
10331
  * @callback JSONPathCallback
9225
- * @param {string|PlainObject} preferredOutput
10332
+ * @param {string|object} preferredOutput
9226
10333
  * @param {"value"|"property"} type
9227
10334
  * @param {ReturnObject} fullRetObj
9228
10335
  * @returns {void}
@@ -9232,23 +10339,42 @@ var NewError = /*#__PURE__*/function (_Error) {
9232
10339
  * @callback OtherTypeCallback
9233
10340
  * @param {JSONObject} val
9234
10341
  * @param {string} path
9235
- * @param {PlainObject|GenericArray} parent
10342
+ * @param {object|GenericArray} parent
9236
10343
  * @param {string} parentPropName
9237
10344
  * @returns {boolean}
9238
10345
  */
9239
10346
 
9240
- /* eslint-disable max-len -- Can make multiline type after https://github.com/syavorsky/comment-parser/issues/109 */
10347
+ /**
10348
+ * @typedef {any} ContextItem
10349
+ */
10350
+
10351
+ /**
10352
+ * @typedef {any} EvaluatedResult
10353
+ */
10354
+
10355
+ /**
10356
+ * @callback EvalCallback
10357
+ * @param {string} code
10358
+ * @param {ContextItem} context
10359
+ * @returns {EvaluatedResult}
10360
+ */
10361
+
10362
+ /**
10363
+ * @typedef {typeof SafeScript} EvalClass
10364
+ */
9241
10365
 
9242
10366
  /**
9243
- * @typedef {PlainObject} JSONPathOptions
10367
+ * @typedef {object} JSONPathOptions
9244
10368
  * @property {JSON} json
9245
10369
  * @property {string|string[]} path
9246
- * @property {"value"|"path"|"pointer"|"parent"|"parentProperty"|"all"} [resultType="value"]
10370
+ * @property {"value"|"path"|"pointer"|"parent"|"parentProperty"|
10371
+ * "all"} [resultType="value"]
9247
10372
  * @property {boolean} [flatten=false]
9248
10373
  * @property {boolean} [wrap=true]
9249
- * @property {PlainObject} [sandbox={}]
9250
- * @property {boolean} [preventEval=false]
9251
- * @property {PlainObject|GenericArray|null} [parent=null]
10374
+ * @property {object} [sandbox={}]
10375
+ * @property {EvalCallback|EvalClass|'safe'|'native'|
10376
+ * boolean} [eval = 'safe']
10377
+ * @property {object|GenericArray|null} [parent=null]
9252
10378
  * @property {string|null} [parentProperty=null]
9253
10379
  * @property {JSONPathCallback} [callback]
9254
10380
  * @property {OtherTypeCallback} [otherTypeCallback] Defaults to
@@ -9256,8 +10382,6 @@ var NewError = /*#__PURE__*/function (_Error) {
9256
10382
  * @property {boolean} [autostart=true]
9257
10383
  */
9258
10384
 
9259
- /* eslint-enable max-len -- Can make multiline type after https://github.com/syavorsky/comment-parser/issues/109 */
9260
-
9261
10385
  /**
9262
10386
  * @param {string|JSONPathOptions} opts If a string, will be treated as `expr`
9263
10387
  * @param {string} [expr] JSON path to evaluate
@@ -9273,10 +10397,8 @@ var NewError = /*#__PURE__*/function (_Error) {
9273
10397
  * @returns {JSONPath}
9274
10398
  * @class
9275
10399
  */
9276
-
9277
-
9278
10400
  function JSONPath(opts, expr, obj, callback, otherTypeCallback) {
9279
- // eslint-disable-next-line no-restricted-syntax
10401
+ // eslint-disable-next-line no-restricted-syntax -- Allow for pseudo-class
9280
10402
  if (!(this instanceof JSONPath)) {
9281
10403
  try {
9282
10404
  return new JSONPath(opts, expr, obj, callback, otherTypeCallback);
@@ -9284,11 +10406,9 @@ function JSONPath(opts, expr, obj, callback, otherTypeCallback) {
9284
10406
  if (!e.avoidNew) {
9285
10407
  throw e;
9286
10408
  }
9287
-
9288
10409
  return e.value;
9289
10410
  }
9290
10411
  }
9291
-
9292
10412
  if (typeof opts === 'string') {
9293
10413
  otherTypeCallback = callback;
9294
10414
  callback = obj;
@@ -9296,249 +10416,215 @@ function JSONPath(opts, expr, obj, callback, otherTypeCallback) {
9296
10416
  expr = opts;
9297
10417
  opts = null;
9298
10418
  }
9299
-
9300
- var optObj = opts && _typeof(opts) === 'object';
10419
+ const optObj = opts && typeof opts === 'object';
9301
10420
  opts = opts || {};
9302
10421
  this.json = opts.json || obj;
9303
10422
  this.path = opts.path || expr;
9304
10423
  this.resultType = opts.resultType || 'value';
9305
10424
  this.flatten = opts.flatten || false;
9306
- this.wrap = hasOwnProp.call(opts, 'wrap') ? opts.wrap : true;
10425
+ this.wrap = Object.hasOwn(opts, 'wrap') ? opts.wrap : true;
9307
10426
  this.sandbox = opts.sandbox || {};
9308
- this.preventEval = opts.preventEval || false;
10427
+ this.eval = opts.eval === undefined ? 'safe' : opts.eval;
10428
+ this.ignoreEvalErrors = typeof opts.ignoreEvalErrors === 'undefined' ? false : opts.ignoreEvalErrors;
9309
10429
  this.parent = opts.parent || null;
9310
10430
  this.parentProperty = opts.parentProperty || null;
9311
10431
  this.callback = opts.callback || callback || null;
9312
-
9313
10432
  this.otherTypeCallback = opts.otherTypeCallback || otherTypeCallback || function () {
9314
10433
  throw new TypeError('You must supply an otherTypeCallback callback option ' + 'with the @other() operator.');
9315
10434
  };
9316
-
9317
10435
  if (opts.autostart !== false) {
9318
- var args = {
10436
+ const args = {
9319
10437
  path: optObj ? opts.path : expr
9320
10438
  };
9321
-
9322
10439
  if (!optObj) {
9323
10440
  args.json = obj;
9324
10441
  } else if ('json' in opts) {
9325
10442
  args.json = opts.json;
9326
10443
  }
9327
-
9328
- var ret = this.evaluate(args);
9329
-
9330
- if (!ret || _typeof(ret) !== 'object') {
10444
+ const ret = this.evaluate(args);
10445
+ if (!ret || typeof ret !== 'object') {
9331
10446
  throw new NewError(ret);
9332
10447
  }
9333
-
9334
10448
  return ret;
9335
10449
  }
9336
- } // PUBLIC METHODS
9337
-
10450
+ }
9338
10451
 
10452
+ // PUBLIC METHODS
9339
10453
  JSONPath.prototype.evaluate = function (expr, json, callback, otherTypeCallback) {
9340
- var _this2 = this;
9341
-
9342
- var currParent = this.parent,
9343
- currParentProperty = this.parentProperty;
9344
- var flatten = this.flatten,
9345
- wrap = this.wrap;
10454
+ let currParent = this.parent,
10455
+ currParentProperty = this.parentProperty;
10456
+ let {
10457
+ flatten,
10458
+ wrap
10459
+ } = this;
9346
10460
  this.currResultType = this.resultType;
9347
- this.currPreventEval = this.preventEval;
10461
+ this.currEval = this.eval;
9348
10462
  this.currSandbox = this.sandbox;
9349
10463
  callback = callback || this.callback;
9350
10464
  this.currOtherTypeCallback = otherTypeCallback || this.otherTypeCallback;
9351
10465
  json = json || this.json;
9352
10466
  expr = expr || this.path;
9353
-
9354
- if (expr && _typeof(expr) === 'object' && !Array.isArray(expr)) {
10467
+ if (expr && typeof expr === 'object' && !Array.isArray(expr)) {
9355
10468
  if (!expr.path && expr.path !== '') {
9356
10469
  throw new TypeError('You must supply a "path" property when providing an object ' + 'argument to JSONPath.evaluate().');
9357
10470
  }
9358
-
9359
- if (!hasOwnProp.call(expr, 'json')) {
10471
+ if (!Object.hasOwn(expr, 'json')) {
9360
10472
  throw new TypeError('You must supply a "json" property when providing an object ' + 'argument to JSONPath.evaluate().');
9361
10473
  }
9362
-
9363
- var _expr = expr;
9364
- json = _expr.json;
9365
- flatten = hasOwnProp.call(expr, 'flatten') ? expr.flatten : flatten;
9366
- this.currResultType = hasOwnProp.call(expr, 'resultType') ? expr.resultType : this.currResultType;
9367
- this.currSandbox = hasOwnProp.call(expr, 'sandbox') ? expr.sandbox : this.currSandbox;
9368
- wrap = hasOwnProp.call(expr, 'wrap') ? expr.wrap : wrap;
9369
- this.currPreventEval = hasOwnProp.call(expr, 'preventEval') ? expr.preventEval : this.currPreventEval;
9370
- callback = hasOwnProp.call(expr, 'callback') ? expr.callback : callback;
9371
- this.currOtherTypeCallback = hasOwnProp.call(expr, 'otherTypeCallback') ? expr.otherTypeCallback : this.currOtherTypeCallback;
9372
- currParent = hasOwnProp.call(expr, 'parent') ? expr.parent : currParent;
9373
- currParentProperty = hasOwnProp.call(expr, 'parentProperty') ? expr.parentProperty : currParentProperty;
10474
+ ({
10475
+ json
10476
+ } = expr);
10477
+ flatten = Object.hasOwn(expr, 'flatten') ? expr.flatten : flatten;
10478
+ this.currResultType = Object.hasOwn(expr, 'resultType') ? expr.resultType : this.currResultType;
10479
+ this.currSandbox = Object.hasOwn(expr, 'sandbox') ? expr.sandbox : this.currSandbox;
10480
+ wrap = Object.hasOwn(expr, 'wrap') ? expr.wrap : wrap;
10481
+ this.currEval = Object.hasOwn(expr, 'eval') ? expr.eval : this.currEval;
10482
+ callback = Object.hasOwn(expr, 'callback') ? expr.callback : callback;
10483
+ this.currOtherTypeCallback = Object.hasOwn(expr, 'otherTypeCallback') ? expr.otherTypeCallback : this.currOtherTypeCallback;
10484
+ currParent = Object.hasOwn(expr, 'parent') ? expr.parent : currParent;
10485
+ currParentProperty = Object.hasOwn(expr, 'parentProperty') ? expr.parentProperty : currParentProperty;
9374
10486
  expr = expr.path;
9375
10487
  }
9376
-
9377
10488
  currParent = currParent || null;
9378
10489
  currParentProperty = currParentProperty || null;
9379
-
9380
10490
  if (Array.isArray(expr)) {
9381
10491
  expr = JSONPath.toPathString(expr);
9382
10492
  }
9383
-
9384
10493
  if (!expr && expr !== '' || !json) {
9385
10494
  return undefined;
9386
10495
  }
9387
-
9388
- var exprList = JSONPath.toPathArray(expr);
9389
-
10496
+ const exprList = JSONPath.toPathArray(expr);
9390
10497
  if (exprList[0] === '$' && exprList.length > 1) {
9391
10498
  exprList.shift();
9392
10499
  }
9393
-
9394
10500
  this._hasParentSelector = null;
9395
-
9396
- var result = this._trace(exprList, json, ['$'], currParent, currParentProperty, callback).filter(function (ea) {
10501
+ const result = this._trace(exprList, json, ['$'], currParent, currParentProperty, callback).filter(function (ea) {
9397
10502
  return ea && !ea.isParentSelector;
9398
10503
  });
9399
-
9400
10504
  if (!result.length) {
9401
10505
  return wrap ? [] : undefined;
9402
10506
  }
9403
-
9404
10507
  if (!wrap && result.length === 1 && !result[0].hasArrExpr) {
9405
10508
  return this._getPreferredOutput(result[0]);
9406
10509
  }
9407
-
9408
- return result.reduce(function (rslt, ea) {
9409
- var valOrPath = _this2._getPreferredOutput(ea);
9410
-
10510
+ return result.reduce((rslt, ea) => {
10511
+ const valOrPath = this._getPreferredOutput(ea);
9411
10512
  if (flatten && Array.isArray(valOrPath)) {
9412
10513
  rslt = rslt.concat(valOrPath);
9413
10514
  } else {
9414
10515
  rslt.push(valOrPath);
9415
10516
  }
9416
-
9417
10517
  return rslt;
9418
10518
  }, []);
9419
- }; // PRIVATE METHODS
10519
+ };
9420
10520
 
10521
+ // PRIVATE METHODS
9421
10522
 
9422
10523
  JSONPath.prototype._getPreferredOutput = function (ea) {
9423
- var resultType = this.currResultType;
9424
-
10524
+ const resultType = this.currResultType;
9425
10525
  switch (resultType) {
9426
10526
  case 'all':
9427
10527
  {
9428
- var path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path);
10528
+ const path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path);
9429
10529
  ea.pointer = JSONPath.toPointer(path);
9430
10530
  ea.path = typeof ea.path === 'string' ? ea.path : JSONPath.toPathString(ea.path);
9431
10531
  return ea;
9432
10532
  }
9433
-
9434
10533
  case 'value':
9435
10534
  case 'parent':
9436
10535
  case 'parentProperty':
9437
10536
  return ea[resultType];
9438
-
9439
10537
  case 'path':
9440
10538
  return JSONPath.toPathString(ea[resultType]);
9441
-
9442
10539
  case 'pointer':
9443
10540
  return JSONPath.toPointer(ea.path);
9444
-
9445
10541
  default:
9446
10542
  throw new TypeError('Unknown result type');
9447
10543
  }
9448
10544
  };
9449
-
9450
10545
  JSONPath.prototype._handleCallback = function (fullRetObj, callback, type) {
9451
10546
  if (callback) {
9452
- var preferredOutput = this._getPreferredOutput(fullRetObj);
9453
-
9454
- fullRetObj.path = typeof fullRetObj.path === 'string' ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path); // eslint-disable-next-line n/callback-return
9455
-
10547
+ const preferredOutput = this._getPreferredOutput(fullRetObj);
10548
+ fullRetObj.path = typeof fullRetObj.path === 'string' ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path);
10549
+ // eslint-disable-next-line n/callback-return -- No need to return
9456
10550
  callback(preferredOutput, type, fullRetObj);
9457
10551
  }
9458
10552
  };
10553
+
9459
10554
  /**
9460
10555
  *
9461
10556
  * @param {string} expr
9462
10557
  * @param {JSONObject} val
9463
10558
  * @param {string} path
9464
- * @param {PlainObject|GenericArray} parent
10559
+ * @param {object|GenericArray} parent
9465
10560
  * @param {string} parentPropName
9466
10561
  * @param {JSONPathCallback} callback
9467
10562
  * @param {boolean} hasArrExpr
9468
10563
  * @param {boolean} literalPriority
9469
10564
  * @returns {ReturnObject|ReturnObject[]}
9470
10565
  */
9471
-
9472
-
9473
10566
  JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) {
9474
- var _this3 = this;
9475
-
9476
10567
  // No expr to follow? return path and value as the result of
9477
10568
  // this trace branch
9478
- var retObj;
9479
-
10569
+ let retObj;
9480
10570
  if (!expr.length) {
9481
10571
  retObj = {
9482
- path: path,
10572
+ path,
9483
10573
  value: val,
9484
- parent: parent,
10574
+ parent,
9485
10575
  parentProperty: parentPropName,
9486
- hasArrExpr: hasArrExpr
10576
+ hasArrExpr
9487
10577
  };
9488
-
9489
10578
  this._handleCallback(retObj, callback, 'value');
9490
-
9491
10579
  return retObj;
9492
10580
  }
10581
+ const loc = expr[0],
10582
+ x = expr.slice(1);
9493
10583
 
9494
- var loc = expr[0],
9495
- x = expr.slice(1); // We need to gather the return value of recursive trace calls in order to
10584
+ // We need to gather the return value of recursive trace calls in order to
9496
10585
  // do the parent sel computation.
9497
-
9498
- var ret = [];
10586
+ const ret = [];
9499
10587
  /**
9500
10588
  *
9501
10589
  * @param {ReturnObject|ReturnObject[]} elems
9502
10590
  * @returns {void}
9503
10591
  */
9504
-
9505
10592
  function addRet(elems) {
9506
10593
  if (Array.isArray(elems)) {
9507
10594
  // This was causing excessive stack size in Node (with or
9508
10595
  // without Babel) against our performance test:
9509
10596
  // `ret.push(...elems);`
9510
- elems.forEach(function (t) {
10597
+ elems.forEach(t => {
9511
10598
  ret.push(t);
9512
10599
  });
9513
10600
  } else {
9514
10601
  ret.push(elems);
9515
10602
  }
9516
10603
  }
9517
-
9518
- if ((typeof loc !== 'string' || literalPriority) && val && hasOwnProp.call(val, loc)) {
10604
+ if ((typeof loc !== 'string' || literalPriority) && val && Object.hasOwn(val, loc)) {
9519
10605
  // simple case--directly follow property
9520
- addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr)); // eslint-disable-next-line unicorn/prefer-switch -- Part of larger `if`
10606
+ addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr));
10607
+ // eslint-disable-next-line unicorn/prefer-switch -- Part of larger `if`
9521
10608
  } else if (loc === '*') {
9522
10609
  // all child properties
9523
- this._walk(val, function (m) {
9524
- addRet(_this3._trace(x, val[m], push(path, m), val, m, callback, true, true));
10610
+ this._walk(val, m => {
10611
+ addRet(this._trace(x, val[m], push(path, m), val, m, callback, true, true));
9525
10612
  });
9526
10613
  } else if (loc === '..') {
9527
10614
  // all descendent parent properties
9528
10615
  // Check remaining expression with val's immediate children
9529
10616
  addRet(this._trace(x, val, path, parent, parentPropName, callback, hasArrExpr));
9530
-
9531
- this._walk(val, function (m) {
10617
+ this._walk(val, m => {
9532
10618
  // We don't join m and x here because we only want parents,
9533
10619
  // not scalar values
9534
- if (_typeof(val[m]) === 'object') {
10620
+ if (typeof val[m] === 'object') {
9535
10621
  // Keep going with recursive descent on val's
9536
10622
  // object children
9537
- addRet(_this3._trace(expr.slice(), val[m], push(path, m), val, m, callback, true));
10623
+ addRet(this._trace(expr.slice(), val[m], push(path, m), val, m, callback, true));
9538
10624
  }
9539
- }); // The parent sel computation is handled in the frame above using the
10625
+ });
10626
+ // The parent sel computation is handled in the frame above using the
9540
10627
  // ancestor object of val
9541
-
9542
10628
  } else if (loc === '^') {
9543
10629
  // This is not a final endpoint, so we do not invoke the callback here
9544
10630
  this._hasParentSelector = true;
@@ -9552,172 +10638,146 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
9552
10638
  retObj = {
9553
10639
  path: push(path, loc),
9554
10640
  value: parentPropName,
9555
- parent: parent,
10641
+ parent,
9556
10642
  parentProperty: null
9557
10643
  };
9558
-
9559
10644
  this._handleCallback(retObj, callback, 'property');
9560
-
9561
10645
  return retObj;
9562
10646
  } else if (loc === '$') {
9563
10647
  // root only
9564
10648
  addRet(this._trace(x, val, path, null, null, callback, hasArrExpr));
9565
- } else if (/^(\x2D?[0-9]*):(\x2D?[0-9]*):?([0-9]*)$/.test(loc)) {
10649
+ } else if (/^(-?\d*):(-?\d*):?(\d*)$/u.test(loc)) {
9566
10650
  // [start:end:step] Python slice syntax
9567
10651
  addRet(this._slice(loc, x, val, path, parent, parentPropName, callback));
9568
10652
  } else if (loc.indexOf('?(') === 0) {
9569
10653
  // [?(expr)] (filtering)
9570
- if (this.currPreventEval) {
10654
+ if (this.currEval === false) {
9571
10655
  throw new Error('Eval [?(expr)] prevented in JSONPath expression.');
9572
10656
  }
9573
-
9574
- var safeLoc = loc.replace(/^\?\(((?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?)\)$/, '$1');
9575
-
9576
- this._walk(val, function (m) {
9577
- if (_this3._eval(safeLoc, val[m], m, path, parent, parentPropName)) {
9578
- addRet(_this3._trace(x, val[m], push(path, m), val, m, callback, true));
9579
- }
9580
- });
10657
+ const safeLoc = loc.replace(/^\?\((.*?)\)$/u, '$1');
10658
+ // check for a nested filter expression
10659
+ const nested = /@.?([^?]*)[['](\??\(.*?\))(?!.\)\])[\]']/gu.exec(safeLoc);
10660
+ if (nested) {
10661
+ // find if there are matches in the nested expression
10662
+ // add them to the result set if there is at least one match
10663
+ this._walk(val, m => {
10664
+ const npath = [nested[2]];
10665
+ const nvalue = nested[1] ? val[m][nested[1]] : val[m];
10666
+ const filterResults = this._trace(npath, nvalue, path, parent, parentPropName, callback, true);
10667
+ if (filterResults.length > 0) {
10668
+ addRet(this._trace(x, val[m], push(path, m), val, m, callback, true));
10669
+ }
10670
+ });
10671
+ } else {
10672
+ this._walk(val, m => {
10673
+ if (this._eval(safeLoc, val[m], m, path, parent, parentPropName)) {
10674
+ addRet(this._trace(x, val[m], push(path, m), val, m, callback, true));
10675
+ }
10676
+ });
10677
+ }
9581
10678
  } else if (loc[0] === '(') {
9582
10679
  // [(expr)] (dynamic property/index)
9583
- if (this.currPreventEval) {
10680
+ if (this.currEval === false) {
9584
10681
  throw new Error('Eval [(expr)] prevented in JSONPath expression.');
9585
- } // As this will resolve to a property name (but we don't know it
10682
+ }
10683
+ // As this will resolve to a property name (but we don't know it
9586
10684
  // yet), property and parent information is relative to the
9587
10685
  // parent of the property to which this expression will resolve
9588
-
9589
-
9590
- addRet(this._trace(unshift(this._eval(loc, val, path[path.length - 1], path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr));
10686
+ addRet(this._trace(unshift(this._eval(loc, val, path.at(-1), path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr));
9591
10687
  } else if (loc[0] === '@') {
9592
10688
  // value type: @boolean(), etc.
9593
- var addType = false;
9594
- var valueType = loc.slice(1, -2);
9595
-
10689
+ let addType = false;
10690
+ const valueType = loc.slice(1, -2);
9596
10691
  switch (valueType) {
9597
10692
  case 'scalar':
9598
- if (!val || !['object', 'function'].includes(_typeof(val))) {
10693
+ if (!val || !['object', 'function'].includes(typeof val)) {
9599
10694
  addType = true;
9600
10695
  }
9601
-
9602
10696
  break;
9603
-
9604
10697
  case 'boolean':
9605
10698
  case 'string':
9606
10699
  case 'undefined':
9607
10700
  case 'function':
9608
- // eslint-disable-next-line valid-typeof
9609
- if (_typeof(val) === valueType) {
10701
+ if (typeof val === valueType) {
9610
10702
  addType = true;
9611
10703
  }
9612
-
9613
10704
  break;
9614
-
9615
10705
  case 'integer':
9616
10706
  if (Number.isFinite(val) && !(val % 1)) {
9617
10707
  addType = true;
9618
10708
  }
9619
-
9620
10709
  break;
9621
-
9622
10710
  case 'number':
9623
10711
  if (Number.isFinite(val)) {
9624
10712
  addType = true;
9625
10713
  }
9626
-
9627
10714
  break;
9628
-
9629
10715
  case 'nonFinite':
9630
10716
  if (typeof val === 'number' && !Number.isFinite(val)) {
9631
10717
  addType = true;
9632
10718
  }
9633
-
9634
10719
  break;
9635
-
9636
10720
  case 'object':
9637
- // eslint-disable-next-line valid-typeof
9638
- if (val && _typeof(val) === valueType) {
10721
+ if (val && typeof val === valueType) {
9639
10722
  addType = true;
9640
10723
  }
9641
-
9642
10724
  break;
9643
-
9644
10725
  case 'array':
9645
10726
  if (Array.isArray(val)) {
9646
10727
  addType = true;
9647
10728
  }
9648
-
9649
10729
  break;
9650
-
9651
10730
  case 'other':
9652
10731
  addType = this.currOtherTypeCallback(val, path, parent, parentPropName);
9653
10732
  break;
9654
-
9655
10733
  case 'null':
9656
10734
  if (val === null) {
9657
10735
  addType = true;
9658
10736
  }
9659
-
9660
10737
  break;
9661
-
9662
10738
  /* c8 ignore next 2 */
9663
-
9664
10739
  default:
9665
10740
  throw new TypeError('Unknown value type ' + valueType);
9666
10741
  }
9667
-
9668
10742
  if (addType) {
9669
10743
  retObj = {
9670
- path: path,
10744
+ path,
9671
10745
  value: val,
9672
- parent: parent,
10746
+ parent,
9673
10747
  parentProperty: parentPropName
9674
10748
  };
9675
-
9676
10749
  this._handleCallback(retObj, callback, 'value');
9677
-
9678
10750
  return retObj;
9679
- } // `-escaped property
9680
-
9681
- } else if (loc[0] === '`' && val && hasOwnProp.call(val, loc.slice(1))) {
9682
- var locProp = loc.slice(1);
10751
+ }
10752
+ // `-escaped property
10753
+ } else if (loc[0] === '`' && val && Object.hasOwn(val, loc.slice(1))) {
10754
+ const locProp = loc.slice(1);
9683
10755
  addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true));
9684
10756
  } else if (loc.includes(',')) {
9685
10757
  // [name1,name2,...]
9686
- var parts = loc.split(',');
9687
-
9688
- var _iterator = _createForOfIteratorHelper(parts),
9689
- _step;
9690
-
9691
- try {
9692
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
9693
- var part = _step.value;
9694
- addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));
9695
- } // simple case--directly follow property
9696
-
9697
- } catch (err) {
9698
- _iterator.e(err);
9699
- } finally {
9700
- _iterator.f();
10758
+ const parts = loc.split(',');
10759
+ for (const part of parts) {
10760
+ addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));
9701
10761
  }
9702
- } else if (!literalPriority && val && hasOwnProp.call(val, loc)) {
10762
+ // simple case--directly follow property
10763
+ } else if (!literalPriority && val && Object.hasOwn(val, loc)) {
9703
10764
  addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true));
9704
- } // We check the resulting values for parent selections. For parent
10765
+ }
10766
+
10767
+ // We check the resulting values for parent selections. For parent
9705
10768
  // selections we discard the value object and continue the trace with the
9706
10769
  // current val object
9707
-
9708
-
9709
10770
  if (this._hasParentSelector) {
9710
- for (var t = 0; t < ret.length; t++) {
9711
- var rett = ret[t];
9712
-
10771
+ for (let t = 0; t < ret.length; t++) {
10772
+ const rett = ret[t];
9713
10773
  if (rett && rett.isParentSelector) {
9714
- var tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);
9715
-
10774
+ const tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);
9716
10775
  if (Array.isArray(tmp)) {
9717
10776
  ret[t] = tmp[0];
9718
- var tl = tmp.length;
9719
-
9720
- for (var tt = 1; tt < tl; tt++) {
10777
+ const tl = tmp.length;
10778
+ for (let tt = 1; tt < tl; tt++) {
10779
+ // eslint-disable-next-line @stylistic/max-len -- Long
10780
+ // eslint-disable-next-line sonarjs/updated-loop-counter -- Convenient
9721
10781
  t++;
9722
10782
  ret.splice(t, 0, tmp[tt]);
9723
10783
  }
@@ -9727,164 +10787,173 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
9727
10787
  }
9728
10788
  }
9729
10789
  }
9730
-
9731
10790
  return ret;
9732
10791
  };
9733
-
9734
10792
  JSONPath.prototype._walk = function (val, f) {
9735
10793
  if (Array.isArray(val)) {
9736
- var n = val.length;
9737
-
9738
- for (var i = 0; i < n; i++) {
10794
+ const n = val.length;
10795
+ for (let i = 0; i < n; i++) {
9739
10796
  f(i);
9740
10797
  }
9741
- } else if (val && _typeof(val) === 'object') {
9742
- Object.keys(val).forEach(function (m) {
10798
+ } else if (val && typeof val === 'object') {
10799
+ Object.keys(val).forEach(m => {
9743
10800
  f(m);
9744
10801
  });
9745
10802
  }
9746
10803
  };
9747
-
9748
10804
  JSONPath.prototype._slice = function (loc, expr, val, path, parent, parentPropName, callback) {
9749
10805
  if (!Array.isArray(val)) {
9750
10806
  return undefined;
9751
10807
  }
9752
-
9753
- var len = val.length,
9754
- parts = loc.split(':'),
9755
- step = parts[2] && Number.parseInt(parts[2]) || 1;
9756
- var start = parts[0] && Number.parseInt(parts[0]) || 0,
9757
- end = parts[1] && Number.parseInt(parts[1]) || len;
10808
+ const len = val.length,
10809
+ parts = loc.split(':'),
10810
+ step = parts[2] && Number.parseInt(parts[2]) || 1;
10811
+ let start = parts[0] && Number.parseInt(parts[0]) || 0,
10812
+ end = parts[1] && Number.parseInt(parts[1]) || len;
9758
10813
  start = start < 0 ? Math.max(0, start + len) : Math.min(len, start);
9759
10814
  end = end < 0 ? Math.max(0, end + len) : Math.min(len, end);
9760
- var ret = [];
9761
-
9762
- for (var i = start; i < end; i += step) {
9763
- var tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true); // Should only be possible to be an array here since first part of
10815
+ const ret = [];
10816
+ for (let i = start; i < end; i += step) {
10817
+ const tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true);
10818
+ // Should only be possible to be an array here since first part of
9764
10819
  // ``unshift(i, expr)` passed in above would not be empty, nor `~`,
9765
10820
  // nor begin with `@` (as could return objects)
9766
10821
  // This was causing excessive stack size in Node (with or
9767
10822
  // without Babel) against our performance test: `ret.push(...tmp);`
9768
-
9769
-
9770
- tmp.forEach(function (t) {
10823
+ tmp.forEach(t => {
9771
10824
  ret.push(t);
9772
10825
  });
9773
10826
  }
9774
-
9775
10827
  return ret;
9776
10828
  };
9777
-
9778
10829
  JSONPath.prototype._eval = function (code, _v, _vname, path, parent, parentPropName) {
9779
10830
  this.currSandbox._$_parentProperty = parentPropName;
9780
10831
  this.currSandbox._$_parent = parent;
9781
10832
  this.currSandbox._$_property = _vname;
9782
10833
  this.currSandbox._$_root = this.json;
9783
10834
  this.currSandbox._$_v = _v;
9784
- var containsPath = code.includes('@path');
9785
-
10835
+ const containsPath = code.includes('@path');
9786
10836
  if (containsPath) {
9787
10837
  this.currSandbox._$_path = JSONPath.toPathString(path.concat([_vname]));
9788
10838
  }
9789
-
9790
- var scriptCacheKey = 'script:' + code;
9791
-
10839
+ const scriptCacheKey = this.currEval + 'Script:' + code;
9792
10840
  if (!JSONPath.cache[scriptCacheKey]) {
9793
- var script = code.replace(/@parentProperty/g, '_$_parentProperty').replace(/@parent/g, '_$_parent').replace(/@property/g, '_$_property').replace(/@root/g, '_$_root').replace(/@([\t-\r \)\.\[\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF])/g, '_$_v$1');
9794
-
10841
+ let script = code.replaceAll('@parentProperty', '_$_parentProperty').replaceAll('@parent', '_$_parent').replaceAll('@property', '_$_property').replaceAll('@root', '_$_root').replaceAll(/@([.\s)[])/gu, '_$_v$1');
9795
10842
  if (containsPath) {
9796
- script = script.replace(/@path/g, '_$_path');
10843
+ script = script.replaceAll('@path', '_$_path');
10844
+ }
10845
+ if (this.currEval === 'safe' || this.currEval === true || this.currEval === undefined) {
10846
+ JSONPath.cache[scriptCacheKey] = new this.safeVm.Script(script);
10847
+ } else if (this.currEval === 'native') {
10848
+ JSONPath.cache[scriptCacheKey] = new this.vm.Script(script);
10849
+ } else if (typeof this.currEval === 'function' && this.currEval.prototype && Object.hasOwn(this.currEval.prototype, 'runInNewContext')) {
10850
+ const CurrEval = this.currEval;
10851
+ JSONPath.cache[scriptCacheKey] = new CurrEval(script);
10852
+ } else if (typeof this.currEval === 'function') {
10853
+ JSONPath.cache[scriptCacheKey] = {
10854
+ runInNewContext: context => this.currEval(script, context)
10855
+ };
10856
+ } else {
10857
+ throw new TypeError(`Unknown "eval" property "${this.currEval}"`);
9797
10858
  }
9798
-
9799
- JSONPath.cache[scriptCacheKey] = new this.vm.Script(script);
9800
10859
  }
9801
-
9802
10860
  try {
9803
10861
  return JSONPath.cache[scriptCacheKey].runInNewContext(this.currSandbox);
9804
10862
  } catch (e) {
10863
+ if (this.ignoreEvalErrors) {
10864
+ return false;
10865
+ }
9805
10866
  throw new Error('jsonPath: ' + e.message + ': ' + code);
9806
10867
  }
9807
- }; // PUBLIC CLASS PROPERTIES AND METHODS
9808
- // Could store the cache object itself
10868
+ };
9809
10869
 
10870
+ // PUBLIC CLASS PROPERTIES AND METHODS
9810
10871
 
10872
+ // Could store the cache object itself
9811
10873
  JSONPath.cache = {};
10874
+
9812
10875
  /**
9813
10876
  * @param {string[]} pathArr Array to convert
9814
10877
  * @returns {string} The path string
9815
10878
  */
9816
-
9817
10879
  JSONPath.toPathString = function (pathArr) {
9818
- var x = pathArr,
9819
- n = x.length;
9820
- var p = '$';
9821
-
9822
- for (var i = 1; i < n; i++) {
9823
- if (!/^(~|\^|@(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?\(\))$/.test(x[i])) {
9824
- p += /^[\*0-9]+$/.test(x[i]) ? '[' + x[i] + ']' : "['" + x[i] + "']";
10880
+ const x = pathArr,
10881
+ n = x.length;
10882
+ let p = '$';
10883
+ for (let i = 1; i < n; i++) {
10884
+ if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) {
10885
+ p += /^[0-9*]+$/u.test(x[i]) ? '[' + x[i] + ']' : "['" + x[i] + "']";
9825
10886
  }
9826
10887
  }
9827
-
9828
10888
  return p;
9829
10889
  };
10890
+
9830
10891
  /**
9831
10892
  * @param {string} pointer JSON Path
9832
10893
  * @returns {string} JSON Pointer
9833
10894
  */
9834
-
9835
-
9836
10895
  JSONPath.toPointer = function (pointer) {
9837
- var x = pointer,
9838
- n = x.length;
9839
- var p = '';
9840
-
9841
- for (var i = 1; i < n; i++) {
9842
- if (!/^(~|\^|@(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?\(\))$/.test(x[i])) {
9843
- p += '/' + x[i].toString().replace(/~/g, '~0').replace(/\//g, '~1');
10896
+ const x = pointer,
10897
+ n = x.length;
10898
+ let p = '';
10899
+ for (let i = 1; i < n; i++) {
10900
+ if (!/^(~|\^|@.*?\(\))$/u.test(x[i])) {
10901
+ p += '/' + x[i].toString().replaceAll('~', '~0').replaceAll('/', '~1');
9844
10902
  }
9845
10903
  }
9846
-
9847
10904
  return p;
9848
10905
  };
10906
+
9849
10907
  /**
9850
10908
  * @param {string} expr Expression to convert
9851
10909
  * @returns {string[]}
9852
10910
  */
9853
-
9854
-
9855
10911
  JSONPath.toPathArray = function (expr) {
9856
- var cache = JSONPath.cache;
9857
-
10912
+ const {
10913
+ cache
10914
+ } = JSONPath;
9858
10915
  if (cache[expr]) {
9859
10916
  return cache[expr].concat();
9860
10917
  }
9861
-
9862
- var subx = [];
9863
- var normalized = expr // Properties
9864
- .replace(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/g, ';$&;') // Parenthetical evaluations (filtering and otherwise), directly
10918
+ const subx = [];
10919
+ const normalized = expr
10920
+ // Properties
10921
+ .replaceAll(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/gu, ';$&;')
10922
+ // Parenthetical evaluations (filtering and otherwise), directly
9865
10923
  // within brackets or single quotes
9866
- .replace(/['\[](\??\((?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?\))['\]]/g, function ($0, $1) {
10924
+ .replaceAll(/[['](\??\(.*?\))[\]'](?!.\])/gu, function ($0, $1) {
9867
10925
  return '[#' + (subx.push($1) - 1) + ']';
9868
- }) // Escape periods and tildes within properties
9869
- .replace(/\[["']((?:(?!['\]])[\s\S])*)["']\]/g, function ($0, prop) {
9870
- return "['" + prop.replace(/\./g, '%@%').replace(/~/g, '%%@@%%') + "']";
9871
- }) // Properties operator
9872
- .replace(/~/g, ';~;') // Split by property boundaries
9873
- .replace(/["']?\.["']?(?!(?:(?!\[)[\s\S])*\])|\[["']?/g, ';') // Reinsert periods within properties
9874
- .replace(/%@%/g, '.') // Reinsert tildes within properties
9875
- .replace(/%%@@%%/g, '~') // Parent
9876
- .replace(/(?:;)?(\^+)(?:;)?/g, function ($0, ups) {
10926
+ })
10927
+ // Escape periods and tildes within properties
10928
+ .replaceAll(/\[['"]([^'\]]*)['"]\]/gu, function ($0, prop) {
10929
+ return "['" + prop.replaceAll('.', '%@%').replaceAll('~', '%%@@%%') + "']";
10930
+ })
10931
+ // Properties operator
10932
+ .replaceAll('~', ';~;')
10933
+ // Split by property boundaries
10934
+ .replaceAll(/['"]?\.['"]?(?![^[]*\])|\[['"]?/gu, ';')
10935
+ // Reinsert periods within properties
10936
+ .replaceAll('%@%', '.')
10937
+ // Reinsert tildes within properties
10938
+ .replaceAll('%%@@%%', '~')
10939
+ // Parent
10940
+ .replaceAll(/(?:;)?(\^+)(?:;)?/gu, function ($0, ups) {
9877
10941
  return ';' + ups.split('').join(';') + ';';
9878
- }) // Descendents
9879
- .replace(/;;;|;;/g, ';..;') // Remove trailing
9880
- .replace(/;$|'?\]|'$/g, '');
9881
- var exprList = normalized.split(';').map(function (exp) {
9882
- var match = exp.match(/#([0-9]+)/);
10942
+ })
10943
+ // Descendents
10944
+ .replaceAll(/;;;|;;/gu, ';..;')
10945
+ // Remove trailing
10946
+ .replaceAll(/;$|'?\]|'$/gu, '');
10947
+ const exprList = normalized.split(';').map(function (exp) {
10948
+ const match = exp.match(/#(\d+)/u);
9883
10949
  return !match || !match[1] ? exp : subx[match[1]];
9884
10950
  });
9885
10951
  cache[expr] = exprList;
9886
10952
  return cache[expr].concat();
9887
10953
  };
10954
+ JSONPath.prototype.safeVm = {
10955
+ Script: SafeScript
10956
+ };
9888
10957
 
9889
10958
  /**
9890
10959
  * @typedef {any} ContextItem
@@ -9908,83 +10977,73 @@ JSONPath.toPathArray = function (expr) {
9908
10977
  * will move item if evaluates to `true`
9909
10978
  * @returns {void}
9910
10979
  */
9911
-
9912
- var moveToAnotherArray = function moveToAnotherArray(source, target, conditionCb) {
9913
- var il = source.length;
9914
-
9915
- for (var i = 0; i < il; i++) {
9916
- var item = source[i];
9917
-
10980
+ const moveToAnotherArray = function (source, target, conditionCb) {
10981
+ const il = source.length;
10982
+ for (let i = 0; i < il; i++) {
10983
+ const item = source[i];
9918
10984
  if (conditionCb(item)) {
10985
+ // eslint-disable-next-line @stylistic/max-len -- Long
10986
+ // eslint-disable-next-line sonarjs/updated-loop-counter -- Convenient
9919
10987
  target.push(source.splice(i--, 1)[0]);
9920
10988
  }
9921
10989
  }
9922
10990
  };
10991
+
9923
10992
  /**
9924
10993
  * In-browser replacement for NodeJS' VM.Script.
9925
10994
  */
9926
-
9927
-
9928
- var Script = /*#__PURE__*/function () {
10995
+ class Script {
9929
10996
  /**
9930
10997
  * @param {string} expr Expression to evaluate
9931
10998
  */
9932
- function Script(expr) {
9933
- _classCallCheck(this, Script);
9934
-
10999
+ constructor(expr) {
9935
11000
  this.code = expr;
9936
11001
  }
11002
+
9937
11003
  /**
9938
- * @param {PlainObject} context Object whose items will be added
11004
+ * @param {object} context Object whose items will be added
9939
11005
  * to evaluation
9940
11006
  * @returns {EvaluatedResult} Result of evaluated code
9941
11007
  */
11008
+ runInNewContext(context) {
11009
+ let expr = this.code;
11010
+ const keys = Object.keys(context);
11011
+ const funcs = [];
11012
+ moveToAnotherArray(keys, funcs, key => {
11013
+ return typeof context[key] === 'function';
11014
+ });
11015
+ const values = keys.map(vr => {
11016
+ return context[vr];
11017
+ });
11018
+ const funcString = funcs.reduce((s, func) => {
11019
+ let fString = context[func].toString();
11020
+ if (!/function/u.test(fString)) {
11021
+ fString = 'function ' + fString;
11022
+ }
11023
+ return 'var ' + func + '=' + fString + ';' + s;
11024
+ }, '');
11025
+ expr = funcString + expr;
9942
11026
 
9943
-
9944
- _createClass(Script, [{
9945
- key: "runInNewContext",
9946
- value: function runInNewContext(context) {
9947
- var expr = this.code;
9948
- var keys = Object.keys(context);
9949
- var funcs = [];
9950
- moveToAnotherArray(keys, funcs, function (key) {
9951
- return typeof context[key] === 'function';
9952
- });
9953
- var values = keys.map(function (vr, i) {
9954
- return context[vr];
9955
- });
9956
- var funcString = funcs.reduce(function (s, func) {
9957
- var fString = context[func].toString();
9958
-
9959
- if (!/function/.test(fString)) {
9960
- fString = 'function ' + fString;
9961
- }
9962
-
9963
- return 'var ' + func + '=' + fString + ';' + s;
9964
- }, '');
9965
- expr = funcString + expr; // Mitigate http://perfectionkills.com/global-eval-what-are-the-options/#new_function
9966
-
9967
- if (!/(["'])use strict\1/.test(expr) && !keys.includes('arguments')) {
9968
- expr = 'var arguments = undefined;' + expr;
9969
- } // Remove last semi so `return` will be inserted before
9970
- // the previous one instead, allowing for the return
9971
- // of a bare ending expression
9972
-
9973
-
9974
- expr = expr.replace(/;[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*$/, ''); // Insert `return`
9975
-
9976
- var lastStatementEnd = expr.lastIndexOf(';');
9977
- var code = lastStatementEnd > -1 ? expr.slice(0, lastStatementEnd + 1) + ' return ' + expr.slice(lastStatementEnd + 1) : ' return ' + expr; // eslint-disable-next-line no-new-func
9978
-
9979
- return _construct(Function, keys.concat([code])).apply(void 0, _toConsumableArray(values));
11027
+ // Mitigate http://perfectionkills.com/global-eval-what-are-the-options/#new_function
11028
+ if (!/(['"])use strict\1/u.test(expr) && !keys.includes('arguments')) {
11029
+ expr = 'var arguments = undefined;' + expr;
9980
11030
  }
9981
- }]);
9982
11031
 
9983
- return Script;
9984
- }();
11032
+ // Remove last semi so `return` will be inserted before
11033
+ // the previous one instead, allowing for the return
11034
+ // of a bare ending expression
11035
+ expr = expr.replace(/;\s*$/u, '');
9985
11036
 
11037
+ // Insert `return`
11038
+ const lastStatementEnd = expr.lastIndexOf(';');
11039
+ const code = lastStatementEnd > -1 ? expr.slice(0, lastStatementEnd + 1) + ' return ' + expr.slice(lastStatementEnd + 1) : ' return ' + expr;
11040
+
11041
+ // eslint-disable-next-line no-new-func -- User's choice
11042
+ return new Function(...keys, code)(...values);
11043
+ }
11044
+ }
9986
11045
  JSONPath.prototype.vm = {
9987
- Script: Script
11046
+ Script
9988
11047
  };
9989
11048
 
9990
11049
 
@@ -12418,10 +13477,8 @@ __webpack_require__.r(__webpack_exports__);
12418
13477
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
12419
13478
  /* harmony export */ "default": () => (/* binding */ _isPlaceholder)
12420
13479
  /* harmony export */ });
12421
- /* harmony import */ var _placeholder_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(231);
12422
-
12423
13480
  function _isPlaceholder(a) {
12424
- return a === _placeholder_js__WEBPACK_IMPORTED_MODULE_0__["default"];
13481
+ return a != null && typeof a === 'object' && a['@@functional/placeholder'] === true;
12425
13482
  }
12426
13483
 
12427
13484
  /***/ }),
@@ -12532,20 +13589,6 @@ function _pipe(f, g) {
12532
13589
 
12533
13590
  /***/ }),
12534
13591
 
12535
- /***/ 231:
12536
- /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
12537
-
12538
- "use strict";
12539
- __webpack_require__.r(__webpack_exports__);
12540
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
12541
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
12542
- /* harmony export */ });
12543
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
12544
- '@@functional/placeholder': true
12545
- });
12546
-
12547
- /***/ }),
12548
-
12549
13592
  /***/ 9569:
12550
13593
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
12551
13594
 
@@ -14109,7 +15152,7 @@ const cloneNode = node => Object.create(Object.getPrototypeOf(node), Object.getO
14109
15152
  * parallel. Each visitor will be visited for each node before moving on.
14110
15153
  *
14111
15154
  * If a prior visitor edits a node, no following visitors will see that node.
14112
- * `exposeEdits=true` can be used to exoise the edited node from the previous visitors.
15155
+ * `exposeEdits=true` can be used to expose the edited node from the previous visitors.
14113
15156
  */
14114
15157
 
14115
15158
  const mergeAll = (visitors, {
@@ -14123,14 +15166,21 @@ const mergeAll = (visitors, {
14123
15166
  const skipSymbol = Symbol('skip');
14124
15167
  const skipping = new Array(visitors.length).fill(skipSymbol);
14125
15168
  return {
14126
- enter(node, ...rest) {
15169
+ enter(node, key, parent, path, ancestors, link) {
14127
15170
  let currentNode = node;
14128
15171
  let hasChanged = false;
15172
+ const linkProxy = {
15173
+ ...link,
15174
+ replaceWith(newNode, replacer) {
15175
+ link.replaceWith(newNode, replacer);
15176
+ currentNode = newNode;
15177
+ }
15178
+ };
14129
15179
  for (let i = 0; i < visitors.length; i += 1) {
14130
15180
  if (skipping[i] === skipSymbol) {
14131
15181
  const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), false);
14132
15182
  if (typeof visitFn === 'function') {
14133
- const result = visitFn.call(visitors[i], currentNode, ...rest);
15183
+ const result = visitFn.call(visitors[i], currentNode, key, parent, path, ancestors, linkProxy);
14134
15184
 
14135
15185
  // check if the visitor is async
14136
15186
  if (typeof (result === null || result === void 0 ? void 0 : result.then) === 'function') {
@@ -14140,7 +15190,7 @@ const mergeAll = (visitors, {
14140
15190
  });
14141
15191
  }
14142
15192
  if (result === skipVisitingNodeSymbol) {
14143
- skipping[i] = node;
15193
+ skipping[i] = currentNode;
14144
15194
  } else if (result === breakSymbol) {
14145
15195
  skipping[i] = breakSymbol;
14146
15196
  } else if (result === deleteNodeSymbol) {
@@ -14158,12 +15208,20 @@ const mergeAll = (visitors, {
14158
15208
  }
14159
15209
  return hasChanged ? currentNode : undefined;
14160
15210
  },
14161
- leave(node, ...rest) {
15211
+ leave(node, key, parent, path, ancestors, link) {
15212
+ let currentNode = node;
15213
+ const linkProxy = {
15214
+ ...link,
15215
+ replaceWith(newNode, replacer) {
15216
+ link.replaceWith(newNode, replacer);
15217
+ currentNode = newNode;
15218
+ }
15219
+ };
14162
15220
  for (let i = 0; i < visitors.length; i += 1) {
14163
15221
  if (skipping[i] === skipSymbol) {
14164
- const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(node), true);
15222
+ const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), true);
14165
15223
  if (typeof visitFn === 'function') {
14166
- const result = visitFn.call(visitors[i], node, ...rest);
15224
+ const result = visitFn.call(visitors[i], currentNode, key, parent, path, ancestors, linkProxy);
14167
15225
 
14168
15226
  // check if the visitor is async
14169
15227
  if (typeof (result === null || result === void 0 ? void 0 : result.then) === 'function') {
@@ -14178,7 +15236,7 @@ const mergeAll = (visitors, {
14178
15236
  return result;
14179
15237
  }
14180
15238
  }
14181
- } else if (skipping[i] === node) {
15239
+ } else if (skipping[i] === currentNode) {
14182
15240
  skipping[i] = skipSymbol;
14183
15241
  }
14184
15242
  }
@@ -14197,17 +15255,24 @@ const mergeAllAsync = (visitors, {
14197
15255
  const skipSymbol = Symbol('skip');
14198
15256
  const skipping = new Array(visitors.length).fill(skipSymbol);
14199
15257
  return {
14200
- async enter(node, ...rest) {
15258
+ async enter(node, key, parent, path, ancestors, link) {
14201
15259
  let currentNode = node;
14202
15260
  let hasChanged = false;
15261
+ const linkProxy = {
15262
+ ...link,
15263
+ replaceWith(newNode, replacer) {
15264
+ link.replaceWith(newNode, replacer);
15265
+ currentNode = newNode;
15266
+ }
15267
+ };
14203
15268
  for (let i = 0; i < visitors.length; i += 1) {
14204
15269
  if (skipping[i] === skipSymbol) {
14205
15270
  const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), false);
14206
15271
  if (typeof visitFn === 'function') {
14207
15272
  // eslint-disable-next-line no-await-in-loop
14208
- const result = await visitFn.call(visitors[i], currentNode, ...rest);
15273
+ const result = await visitFn.call(visitors[i], currentNode, key, parent, path, ancestors, linkProxy);
14209
15274
  if (result === skipVisitingNodeSymbol) {
14210
- skipping[i] = node;
15275
+ skipping[i] = currentNode;
14211
15276
  } else if (result === breakSymbol) {
14212
15277
  skipping[i] = breakSymbol;
14213
15278
  } else if (result === deleteNodeSymbol) {
@@ -14225,20 +15290,28 @@ const mergeAllAsync = (visitors, {
14225
15290
  }
14226
15291
  return hasChanged ? currentNode : undefined;
14227
15292
  },
14228
- async leave(node, ...rest) {
15293
+ async leave(node, key, parent, path, ancestors, link) {
15294
+ let currentNode = node;
15295
+ const linkProxy = {
15296
+ ...link,
15297
+ replaceWith(newNode, replacer) {
15298
+ link.replaceWith(newNode, replacer);
15299
+ currentNode = newNode;
15300
+ }
15301
+ };
14229
15302
  for (let i = 0; i < visitors.length; i += 1) {
14230
15303
  if (skipping[i] === skipSymbol) {
14231
- const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(node), true);
15304
+ const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), true);
14232
15305
  if (typeof visitFn === 'function') {
14233
15306
  // eslint-disable-next-line no-await-in-loop
14234
- const result = await visitFn.call(visitors[i], node, ...rest);
15307
+ const result = await visitFn.call(visitors[i], currentNode, key, parent, path, ancestors, linkProxy);
14235
15308
  if (result === breakSymbol) {
14236
15309
  skipping[i] = breakSymbol;
14237
15310
  } else if (result !== undefined && result !== skipVisitingNodeSymbol) {
14238
15311
  return result;
14239
15312
  }
14240
15313
  }
14241
- } else if (skipping[i] === node) {
15314
+ } else if (skipping[i] === currentNode) {
14242
15315
  skipping[i] = skipSymbol;
14243
15316
  }
14244
15317
  }
@@ -14434,8 +15507,22 @@ visitor, {
14434
15507
  for (const [stateKey, stateValue] of Object.entries(state)) {
14435
15508
  visitor[stateKey] = stateValue;
14436
15509
  }
15510
+ const link = {
15511
+ // eslint-disable-next-line @typescript-eslint/no-loop-func
15512
+ replaceWith(newNode, replacer) {
15513
+ if (typeof replacer === 'function') {
15514
+ replacer(newNode, node, key, parent, path, ancestors);
15515
+ } else if (parent) {
15516
+ parent[key] = newNode;
15517
+ }
15518
+ if (!isLeaving) {
15519
+ node = newNode;
15520
+ }
15521
+ }
15522
+ };
15523
+
14437
15524
  // retrieve result
14438
- result = visitFn.call(visitor, node, key, parent, path, ancestors);
15525
+ result = visitFn.call(visitor, node, key, parent, path, ancestors, link);
14439
15526
  }
14440
15527
 
14441
15528
  // check if the visitor is async
@@ -14592,9 +15679,22 @@ visitor, {
14592
15679
  for (const [stateKey, stateValue] of Object.entries(state)) {
14593
15680
  visitor[stateKey] = stateValue;
14594
15681
  }
15682
+ const link = {
15683
+ // eslint-disable-next-line @typescript-eslint/no-loop-func
15684
+ replaceWith(newNode, replacer) {
15685
+ if (typeof replacer === 'function') {
15686
+ replacer(newNode, node, key, parent, path, ancestors);
15687
+ } else if (parent) {
15688
+ parent[key] = newNode;
15689
+ }
15690
+ if (!isLeaving) {
15691
+ node = newNode;
15692
+ }
15693
+ }
15694
+ };
14595
15695
 
14596
15696
  // retrieve result
14597
- result = await visitFn.call(visitor, node, key, parent, path, ancestors); // eslint-disable-line no-await-in-loop
15697
+ result = await visitFn.call(visitor, node, key, parent, path, ancestors, link); // eslint-disable-line no-await-in-loop
14598
15698
  }
14599
15699
  if (result === breakSymbol) {
14600
15700
  break;
@@ -15984,6 +17084,7 @@ __webpack_require__.r(__webpack_exports__);
15984
17084
 
15985
17085
 
15986
17086
 
17087
+
15987
17088
  })();
15988
17089
 
15989
17090
  /******/ return __webpack_exports__;