@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.
- package/CHANGELOG.md +32 -0
- package/cjs/index.cjs +1 -0
- package/cjs/polyfills.cjs +25 -0
- package/dist/apidom-json-path.browser.js +1753 -652
- package/dist/apidom-json-path.browser.min.js +1 -1
- package/es/index.mjs +1 -0
- package/es/polyfills.mjs +21 -0
- package/package.json +6 -6
|
@@ -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
|
|
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(
|
|
6224
|
+
defineProperty(globalThis, key, { value: value, configurable: true, writable: true });
|
|
6224
6225
|
} catch (error) {
|
|
6225
|
-
|
|
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
|
|
6254
|
+
var globalThis = __webpack_require__(8900);
|
|
6254
6255
|
var isObject = __webpack_require__(262);
|
|
6255
6256
|
|
|
6256
|
-
var 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
|
-
/***/
|
|
6312
|
+
/***/ 9683:
|
|
6312
6313
|
/***/ ((module) => {
|
|
6313
6314
|
|
|
6314
6315
|
"use strict";
|
|
6315
6316
|
|
|
6316
|
-
|
|
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
|
-
/***/
|
|
6346
|
+
/***/ 5547:
|
|
6322
6347
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
6323
6348
|
|
|
6324
6349
|
"use strict";
|
|
6325
6350
|
|
|
6326
|
-
var
|
|
6327
|
-
var userAgent = __webpack_require__(
|
|
6351
|
+
var globalThis = __webpack_require__(8900);
|
|
6352
|
+
var userAgent = __webpack_require__(3531);
|
|
6328
6353
|
|
|
6329
|
-
var process =
|
|
6330
|
-
var 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
|
|
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 ?
|
|
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,
|
|
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
|
|
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(
|
|
6738
|
-
: path[namespace] && path[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
|
-
/***/
|
|
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
|
|
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 =
|
|
6978
|
-
var 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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
8103
|
+
var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {});
|
|
8092
8104
|
|
|
8093
|
-
|
|
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
|
-
|
|
8107
|
-
return store[key] || (store[key] = value
|
|
8108
|
-
}
|
|
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__(
|
|
8181
|
+
var V8_VERSION = __webpack_require__(5547);
|
|
8171
8182
|
var fails = __webpack_require__(1203);
|
|
8172
|
-
var
|
|
8183
|
+
var globalThis = __webpack_require__(8900);
|
|
8173
8184
|
|
|
8174
|
-
var $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
|
|
8457
|
+
var globalThis = __webpack_require__(8900);
|
|
8447
8458
|
var isCallable = __webpack_require__(2769);
|
|
8448
8459
|
|
|
8449
|
-
var 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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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
|
-
|
|
8887
|
-
|
|
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
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
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
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8952
|
+
/**
|
|
8953
|
+
* @implements {IPlugins}
|
|
8954
|
+
*/
|
|
8955
|
+
class Plugins {
|
|
8956
|
+
constructor(jsep) {
|
|
8957
|
+
this.jsep = jsep;
|
|
8958
|
+
this.registered = {};
|
|
8899
8959
|
}
|
|
8900
|
-
}
|
|
8901
8960
|
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8922
|
-
|
|
8923
|
-
|
|
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
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
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
|
-
|
|
8934
|
-
writable: false
|
|
8935
|
-
});
|
|
8936
|
-
if (superClass) _setPrototypeOf(subClass, superClass);
|
|
8937
|
-
}
|
|
9036
|
+
return Jsep;
|
|
9037
|
+
}
|
|
8938
9038
|
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
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
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
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
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
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
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
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
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8985
|
-
|
|
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
|
-
|
|
8989
|
-
|
|
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
|
-
|
|
8992
|
-
|
|
9127
|
+
/**
|
|
9128
|
+
* @method removeAllLiterals
|
|
9129
|
+
* @returns {Jsep}
|
|
9130
|
+
*/
|
|
9131
|
+
static removeAllLiterals() {
|
|
9132
|
+
Jsep.literals = {};
|
|
9133
|
+
return Jsep;
|
|
9134
|
+
}
|
|
9135
|
+
// ==================== END CONFIG ============================
|
|
8993
9136
|
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
9137
|
+
/**
|
|
9138
|
+
* @returns {string}
|
|
9139
|
+
*/
|
|
9140
|
+
get char() {
|
|
9141
|
+
return this.expr.charAt(this.index);
|
|
9142
|
+
}
|
|
8997
9143
|
|
|
8998
|
-
|
|
8999
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9005
|
-
|
|
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
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9041
|
-
|
|
9379
|
+
// If there wasn't a binary operator, just return the leftmost node
|
|
9380
|
+
if (!biop) {
|
|
9381
|
+
return left;
|
|
9382
|
+
}
|
|
9042
9383
|
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
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
|
-
|
|
9048
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9060
|
-
|
|
9061
|
-
}
|
|
9576
|
+
this.gobbleSpaces();
|
|
9577
|
+
ch = this.code;
|
|
9578
|
+
}
|
|
9579
|
+
return node;
|
|
9580
|
+
}
|
|
9062
9581
|
|
|
9063
|
-
|
|
9064
|
-
|
|
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
|
-
|
|
9068
|
-
|
|
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
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
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
|
-
|
|
9081
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9089
|
-
|
|
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
|
-
|
|
9093
|
-
|
|
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
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
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
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
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
|
-
|
|
10268
|
+
/* eslint-disable camelcase -- Convenient for escaping */
|
|
10269
|
+
|
|
10270
|
+
|
|
9150
10271
|
/**
|
|
9151
|
-
* @typedef {null|boolean|number|string|
|
|
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
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
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 {
|
|
10323
|
+
* @typedef {object} ReturnObject
|
|
9217
10324
|
* @property {string} path
|
|
9218
10325
|
* @property {JSONObject} value
|
|
9219
|
-
* @property {
|
|
10326
|
+
* @property {object|GenericArray} parent
|
|
9220
10327
|
* @property {string} parentProperty
|
|
9221
10328
|
*/
|
|
9222
10329
|
|
|
9223
10330
|
/**
|
|
9224
10331
|
* @callback JSONPathCallback
|
|
9225
|
-
* @param {string|
|
|
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 {
|
|
10342
|
+
* @param {object|GenericArray} parent
|
|
9236
10343
|
* @param {string} parentPropName
|
|
9237
10344
|
* @returns {boolean}
|
|
9238
10345
|
*/
|
|
9239
10346
|
|
|
9240
|
-
|
|
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 {
|
|
10367
|
+
* @typedef {object} JSONPathOptions
|
|
9244
10368
|
* @property {JSON} json
|
|
9245
10369
|
* @property {string|string[]} path
|
|
9246
|
-
* @property {"value"|"path"|"pointer"|"parent"|"parentProperty"|
|
|
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 {
|
|
9250
|
-
* @property {
|
|
9251
|
-
*
|
|
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 =
|
|
10425
|
+
this.wrap = Object.hasOwn(opts, 'wrap') ? opts.wrap : true;
|
|
9307
10426
|
this.sandbox = opts.sandbox || {};
|
|
9308
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
9337
|
-
|
|
10450
|
+
}
|
|
9338
10451
|
|
|
10452
|
+
// PUBLIC METHODS
|
|
9339
10453
|
JSONPath.prototype.evaluate = function (expr, json, callback, otherTypeCallback) {
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
|
|
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.
|
|
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
|
-
|
|
9364
|
-
|
|
9365
|
-
flatten =
|
|
9366
|
-
this.currResultType =
|
|
9367
|
-
this.currSandbox =
|
|
9368
|
-
wrap =
|
|
9369
|
-
this.
|
|
9370
|
-
callback =
|
|
9371
|
-
this.currOtherTypeCallback =
|
|
9372
|
-
currParent =
|
|
9373
|
-
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
|
-
|
|
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
|
-
};
|
|
10519
|
+
};
|
|
9420
10520
|
|
|
10521
|
+
// PRIVATE METHODS
|
|
9421
10522
|
|
|
9422
10523
|
JSONPath.prototype._getPreferredOutput = function (ea) {
|
|
9423
|
-
|
|
9424
|
-
|
|
10524
|
+
const resultType = this.currResultType;
|
|
9425
10525
|
switch (resultType) {
|
|
9426
10526
|
case 'all':
|
|
9427
10527
|
{
|
|
9428
|
-
|
|
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
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
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 {
|
|
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
|
-
|
|
9479
|
-
|
|
10569
|
+
let retObj;
|
|
9480
10570
|
if (!expr.length) {
|
|
9481
10571
|
retObj = {
|
|
9482
|
-
path
|
|
10572
|
+
path,
|
|
9483
10573
|
value: val,
|
|
9484
|
-
parent
|
|
10574
|
+
parent,
|
|
9485
10575
|
parentProperty: parentPropName,
|
|
9486
|
-
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
|
-
|
|
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(
|
|
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));
|
|
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,
|
|
9524
|
-
addRet(
|
|
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 (
|
|
10620
|
+
if (typeof val[m] === 'object') {
|
|
9535
10621
|
// Keep going with recursive descent on val's
|
|
9536
10622
|
// object children
|
|
9537
|
-
addRet(
|
|
10623
|
+
addRet(this._trace(expr.slice(), val[m], push(path, m), val, m, callback, true));
|
|
9538
10624
|
}
|
|
9539
|
-
});
|
|
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
|
|
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 (/^(
|
|
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.
|
|
10654
|
+
if (this.currEval === false) {
|
|
9571
10655
|
throw new Error('Eval [?(expr)] prevented in JSONPath expression.');
|
|
9572
10656
|
}
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
if
|
|
9578
|
-
|
|
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.
|
|
10680
|
+
if (this.currEval === false) {
|
|
9584
10681
|
throw new Error('Eval [(expr)] prevented in JSONPath expression.');
|
|
9585
|
-
}
|
|
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
|
-
|
|
9594
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
10744
|
+
path,
|
|
9671
10745
|
value: val,
|
|
9672
|
-
parent
|
|
10746
|
+
parent,
|
|
9673
10747
|
parentProperty: parentPropName
|
|
9674
10748
|
};
|
|
9675
|
-
|
|
9676
10749
|
this._handleCallback(retObj, callback, 'value');
|
|
9677
|
-
|
|
9678
10750
|
return retObj;
|
|
9679
|
-
}
|
|
9680
|
-
|
|
9681
|
-
} else if (loc[0] === '`' && val &&
|
|
9682
|
-
|
|
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
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
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 (
|
|
9711
|
-
|
|
9712
|
-
|
|
10771
|
+
for (let t = 0; t < ret.length; t++) {
|
|
10772
|
+
const rett = ret[t];
|
|
9713
10773
|
if (rett && rett.isParentSelector) {
|
|
9714
|
-
|
|
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
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
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
|
-
|
|
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 &&
|
|
9742
|
-
Object.keys(val).forEach(
|
|
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
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
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
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
};
|
|
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
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
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
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
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
|
-
|
|
9857
|
-
|
|
10912
|
+
const {
|
|
10913
|
+
cache
|
|
10914
|
+
} = JSONPath;
|
|
9858
10915
|
if (cache[expr]) {
|
|
9859
10916
|
return cache[expr].concat();
|
|
9860
10917
|
}
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
.
|
|
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
|
-
.
|
|
10924
|
+
.replaceAll(/[['](\??\(.*?\))[\]'](?!.\])/gu, function ($0, $1) {
|
|
9867
10925
|
return '[#' + (subx.push($1) - 1) + ']';
|
|
9868
|
-
})
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
.
|
|
9875
|
-
|
|
9876
|
-
.
|
|
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
|
-
})
|
|
9879
|
-
|
|
9880
|
-
.
|
|
9881
|
-
|
|
9882
|
-
|
|
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
|
-
|
|
9913
|
-
|
|
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
|
-
|
|
9933
|
-
_classCallCheck(this, Script);
|
|
9934
|
-
|
|
10999
|
+
constructor(expr) {
|
|
9935
11000
|
this.code = expr;
|
|
9936
11001
|
}
|
|
11002
|
+
|
|
9937
11003
|
/**
|
|
9938
|
-
* @param {
|
|
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
|
-
|
|
9945
|
-
|
|
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
|
-
|
|
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
|
|
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 ===
|
|
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
|
|
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,
|
|
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,
|
|
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] =
|
|
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,
|
|
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(
|
|
15222
|
+
const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), true);
|
|
14165
15223
|
if (typeof visitFn === 'function') {
|
|
14166
|
-
const result = visitFn.call(visitors[i],
|
|
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] ===
|
|
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,
|
|
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,
|
|
15273
|
+
const result = await visitFn.call(visitors[i], currentNode, key, parent, path, ancestors, linkProxy);
|
|
14209
15274
|
if (result === skipVisitingNodeSymbol) {
|
|
14210
|
-
skipping[i] =
|
|
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,
|
|
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(
|
|
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],
|
|
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] ===
|
|
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__;
|