Musique/node_modules/jsonpath-plus/dist/index-browser-esm.js

1056 lines
31 KiB
JavaScript

function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _construct(Parent, args, Class) {
if (_isNativeReflectConstruct()) {
_construct = Reflect.construct;
} else {
_construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) _setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
_wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !_isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return _construct(Class, arguments, _getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return _setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _createForOfIteratorHelper(o, allowArrayLike) {
var it;
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
var F = function () {};
return {
s: F,
n: function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
},
e: function (e) {
throw e;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var normalCompletion = true,
didErr = false,
err;
return {
s: function () {
it = o[Symbol.iterator]();
},
n: function () {
var step = it.next();
normalCompletion = step.done;
return step;
},
e: function (e) {
didErr = true;
err = e;
},
f: function () {
try {
if (!normalCompletion && it.return != null) it.return();
} finally {
if (didErr) throw err;
}
}
};
}
var hasOwnProp = Object.prototype.hasOwnProperty;
/**
* @typedef {null|boolean|number|string|PlainObject|GenericArray} JSONObject
*/
/**
* Copies array and then pushes item into it.
* @param {GenericArray} arr Array to copy and into which to push
* @param {any} item Array item to add (to end)
* @returns {GenericArray} Copy of the original array
*/
function push(arr, item) {
arr = arr.slice();
arr.push(item);
return arr;
}
/**
* Copies array and then unshifts item into it.
* @param {any} item Array item to add (to beginning)
* @param {GenericArray} arr Array to copy and into which to unshift
* @returns {GenericArray} Copy of the original array
*/
function unshift(item, arr) {
arr = arr.slice();
arr.unshift(item);
return arr;
}
/**
* Caught when JSONPath is used without `new` but rethrown if with `new`
* @extends Error
*/
var NewError = /*#__PURE__*/function (_Error) {
_inherits(NewError, _Error);
var _super = _createSuper(NewError);
/**
* @param {any} value The evaluated scalar value
*/
function NewError(value) {
var _this;
_classCallCheck(this, NewError);
_this = _super.call(this, 'JSONPath should not be called with "new" (it prevents return ' + 'of (unwrapped) scalar values)');
_this.avoidNew = true;
_this.value = value;
_this.name = 'NewError';
return _this;
}
return NewError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
/**
* @typedef {PlainObject} ReturnObject
* @property {string} path
* @property {JSONObject} value
* @property {PlainObject|GenericArray} parent
* @property {string} parentProperty
*/
/**
* @callback JSONPathCallback
* @param {string|PlainObject} preferredOutput
* @param {"value"|"property"} type
* @param {ReturnObject} fullRetObj
* @returns {void}
*/
/**
* @callback OtherTypeCallback
* @param {JSONObject} val
* @param {string} path
* @param {PlainObject|GenericArray} parent
* @param {string} parentPropName
* @returns {boolean}
*/
/* eslint-disable max-len -- Can make multiline type after https://github.com/syavorsky/comment-parser/issues/109 */
/**
* @typedef {PlainObject} JSONPathOptions
* @property {JSON} json
* @property {string|string[]} path
* @property {"value"|"path"|"pointer"|"parent"|"parentProperty"|"all"} [resultType="value"]
* @property {boolean} [flatten=false]
* @property {boolean} [wrap=true]
* @property {PlainObject} [sandbox={}]
* @property {boolean} [preventEval=false]
* @property {PlainObject|GenericArray|null} [parent=null]
* @property {string|null} [parentProperty=null]
* @property {JSONPathCallback} [callback]
* @property {OtherTypeCallback} [otherTypeCallback] Defaults to
* function which throws on encountering `@other`
* @property {boolean} [autostart=true]
*/
/* eslint-enable max-len -- Can make multiline type after https://github.com/syavorsky/comment-parser/issues/109 */
/**
* @param {string|JSONPathOptions} opts If a string, will be treated as `expr`
* @param {string} [expr] JSON path to evaluate
* @param {JSON} [obj] JSON object to evaluate against
* @param {JSONPathCallback} [callback] Passed 3 arguments: 1) desired payload
* per `resultType`, 2) `"value"|"property"`, 3) Full returned object with
* all payloads
* @param {OtherTypeCallback} [otherTypeCallback] If `@other()` is at the end
* of one's query, this will be invoked with the value of the item, its
* path, its parent, and its parent's property name, and it should return
* a boolean indicating whether the supplied value belongs to the "other"
* type or not (or it may handle transformations and return `false`).
* @returns {JSONPath}
* @class
*/
function JSONPath(opts, expr, obj, callback, otherTypeCallback) {
// eslint-disable-next-line no-restricted-syntax
if (!(this instanceof JSONPath)) {
try {
return new JSONPath(opts, expr, obj, callback, otherTypeCallback);
} catch (e) {
if (!e.avoidNew) {
throw e;
}
return e.value;
}
}
if (typeof opts === 'string') {
otherTypeCallback = callback;
callback = obj;
obj = expr;
expr = opts;
opts = null;
}
var optObj = opts && _typeof(opts) === 'object';
opts = opts || {};
this.json = opts.json || obj;
this.path = opts.path || expr;
this.resultType = opts.resultType || 'value';
this.flatten = opts.flatten || false;
this.wrap = hasOwnProp.call(opts, 'wrap') ? opts.wrap : true;
this.sandbox = opts.sandbox || {};
this.preventEval = opts.preventEval || false;
this.parent = opts.parent || null;
this.parentProperty = opts.parentProperty || null;
this.callback = opts.callback || callback || null;
this.otherTypeCallback = opts.otherTypeCallback || otherTypeCallback || function () {
throw new TypeError('You must supply an otherTypeCallback callback option ' + 'with the @other() operator.');
};
if (opts.autostart !== false) {
var args = {
path: optObj ? opts.path : expr
};
if (!optObj) {
args.json = obj;
} else if ('json' in opts) {
args.json = opts.json;
}
var ret = this.evaluate(args);
if (!ret || _typeof(ret) !== 'object') {
throw new NewError(ret);
}
return ret;
}
} // PUBLIC METHODS
JSONPath.prototype.evaluate = function (expr, json, callback, otherTypeCallback) {
var _this2 = this;
var currParent = this.parent,
currParentProperty = this.parentProperty;
var flatten = this.flatten,
wrap = this.wrap;
this.currResultType = this.resultType;
this.currPreventEval = this.preventEval;
this.currSandbox = this.sandbox;
callback = callback || this.callback;
this.currOtherTypeCallback = otherTypeCallback || this.otherTypeCallback;
json = json || this.json;
expr = expr || this.path;
if (expr && _typeof(expr) === 'object' && !Array.isArray(expr)) {
if (!expr.path && expr.path !== '') {
throw new TypeError('You must supply a "path" property when providing an object ' + 'argument to JSONPath.evaluate().');
}
if (!hasOwnProp.call(expr, 'json')) {
throw new TypeError('You must supply a "json" property when providing an object ' + 'argument to JSONPath.evaluate().');
}
var _expr = expr;
json = _expr.json;
flatten = hasOwnProp.call(expr, 'flatten') ? expr.flatten : flatten;
this.currResultType = hasOwnProp.call(expr, 'resultType') ? expr.resultType : this.currResultType;
this.currSandbox = hasOwnProp.call(expr, 'sandbox') ? expr.sandbox : this.currSandbox;
wrap = hasOwnProp.call(expr, 'wrap') ? expr.wrap : wrap;
this.currPreventEval = hasOwnProp.call(expr, 'preventEval') ? expr.preventEval : this.currPreventEval;
callback = hasOwnProp.call(expr, 'callback') ? expr.callback : callback;
this.currOtherTypeCallback = hasOwnProp.call(expr, 'otherTypeCallback') ? expr.otherTypeCallback : this.currOtherTypeCallback;
currParent = hasOwnProp.call(expr, 'parent') ? expr.parent : currParent;
currParentProperty = hasOwnProp.call(expr, 'parentProperty') ? expr.parentProperty : currParentProperty;
expr = expr.path;
}
currParent = currParent || null;
currParentProperty = currParentProperty || null;
if (Array.isArray(expr)) {
expr = JSONPath.toPathString(expr);
}
if (!expr && expr !== '' || !json) {
return undefined;
}
var exprList = JSONPath.toPathArray(expr);
if (exprList[0] === '$' && exprList.length > 1) {
exprList.shift();
}
this._hasParentSelector = null;
var result = this._trace(exprList, json, ['$'], currParent, currParentProperty, callback).filter(function (ea) {
return ea && !ea.isParentSelector;
});
if (!result.length) {
return wrap ? [] : undefined;
}
if (!wrap && result.length === 1 && !result[0].hasArrExpr) {
return this._getPreferredOutput(result[0]);
}
return result.reduce(function (rslt, ea) {
var valOrPath = _this2._getPreferredOutput(ea);
if (flatten && Array.isArray(valOrPath)) {
rslt = rslt.concat(valOrPath);
} else {
rslt.push(valOrPath);
}
return rslt;
}, []);
}; // PRIVATE METHODS
JSONPath.prototype._getPreferredOutput = function (ea) {
var resultType = this.currResultType;
switch (resultType) {
case 'all':
{
var path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path);
ea.pointer = JSONPath.toPointer(path);
ea.path = typeof ea.path === 'string' ? ea.path : JSONPath.toPathString(ea.path);
return ea;
}
case 'value':
case 'parent':
case 'parentProperty':
return ea[resultType];
case 'path':
return JSONPath.toPathString(ea[resultType]);
case 'pointer':
return JSONPath.toPointer(ea.path);
default:
throw new TypeError('Unknown result type');
}
};
JSONPath.prototype._handleCallback = function (fullRetObj, callback, type) {
if (callback) {
var preferredOutput = this._getPreferredOutput(fullRetObj);
fullRetObj.path = typeof fullRetObj.path === 'string' ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path); // eslint-disable-next-line node/callback-return
callback(preferredOutput, type, fullRetObj);
}
};
/**
*
* @param {string} expr
* @param {JSONObject} val
* @param {string} path
* @param {PlainObject|GenericArray} parent
* @param {string} parentPropName
* @param {JSONPathCallback} callback
* @param {boolean} hasArrExpr
* @param {boolean} literalPriority
* @returns {ReturnObject|ReturnObject[]}
*/
JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) {
var _this3 = this;
// No expr to follow? return path and value as the result of
// this trace branch
var retObj;
if (!expr.length) {
retObj = {
path: path,
value: val,
parent: parent,
parentProperty: parentPropName,
hasArrExpr: hasArrExpr
};
this._handleCallback(retObj, callback, 'value');
return retObj;
}
var loc = expr[0],
x = expr.slice(1); // We need to gather the return value of recursive trace calls in order to
// do the parent sel computation.
var ret = [];
/**
*
* @param {ReturnObject|ReturnObject[]} elems
* @returns {void}
*/
function addRet(elems) {
if (Array.isArray(elems)) {
// This was causing excessive stack size in Node (with or
// without Babel) against our performance test:
// `ret.push(...elems);`
elems.forEach(function (t) {
ret.push(t);
});
} else {
ret.push(elems);
}
}
if ((typeof loc !== 'string' || literalPriority) && val && hasOwnProp.call(val, loc)) {
// simple case--directly follow property
addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr));
} else if (loc === '*') {
// all child properties
this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
addRet(_this3._trace(unshift(m, _x), v, p, par, pr, cb, true, true));
});
} else if (loc === '..') {
// all descendent parent properties
// Check remaining expression with val's immediate children
addRet(this._trace(x, val, path, parent, parentPropName, callback, hasArrExpr));
this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
// We don't join m and x here because we only want parents,
// not scalar values
if (_typeof(v[m]) === 'object') {
// Keep going with recursive descent on val's
// object children
addRet(_this3._trace(unshift(l, _x), v[m], push(p, m), v, m, cb, true));
}
}); // The parent sel computation is handled in the frame above using the
// ancestor object of val
} else if (loc === '^') {
// This is not a final endpoint, so we do not invoke the callback here
this._hasParentSelector = true;
return {
path: path.slice(0, -1),
expr: x,
isParentSelector: true
};
} else if (loc === '~') {
// property name
retObj = {
path: push(path, loc),
value: parentPropName,
parent: parent,
parentProperty: null
};
this._handleCallback(retObj, callback, 'property');
return retObj;
} else if (loc === '$') {
// root only
addRet(this._trace(x, val, path, null, null, callback, hasArrExpr));
} else if (/^(\x2D?[0-9]*):(\x2D?[0-9]*):?([0-9]*)$/.test(loc)) {
// [start:end:step] Python slice syntax
addRet(this._slice(loc, x, val, path, parent, parentPropName, callback));
} else if (loc.indexOf('?(') === 0) {
// [?(expr)] (filtering)
if (this.currPreventEval) {
throw new Error('Eval [?(expr)] prevented in JSONPath expression.');
}
this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
if (_this3._eval(l.replace(/^\?\(((?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?)\)$/, '$1'), v[m], m, p, par, pr)) {
addRet(_this3._trace(unshift(m, _x), v, p, par, pr, cb, true));
}
});
} else if (loc[0] === '(') {
// [(expr)] (dynamic property/index)
if (this.currPreventEval) {
throw new Error('Eval [(expr)] prevented in JSONPath expression.');
} // As this will resolve to a property name (but we don't know it
// yet), property and parent information is relative to the
// parent of the property to which this expression will resolve
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));
} else if (loc[0] === '@') {
// value type: @boolean(), etc.
var addType = false;
var valueType = loc.slice(1, -2);
switch (valueType) {
case 'scalar':
if (!val || !['object', 'function'].includes(_typeof(val))) {
addType = true;
}
break;
case 'boolean':
case 'string':
case 'undefined':
case 'function':
// eslint-disable-next-line valid-typeof
if (_typeof(val) === valueType) {
addType = true;
}
break;
case 'integer':
if (Number.isFinite(val) && !(val % 1)) {
addType = true;
}
break;
case 'number':
if (Number.isFinite(val)) {
addType = true;
}
break;
case 'nonFinite':
if (typeof val === 'number' && !Number.isFinite(val)) {
addType = true;
}
break;
case 'object':
// eslint-disable-next-line valid-typeof
if (val && _typeof(val) === valueType) {
addType = true;
}
break;
case 'array':
if (Array.isArray(val)) {
addType = true;
}
break;
case 'other':
addType = this.currOtherTypeCallback(val, path, parent, parentPropName);
break;
case 'null':
if (val === null) {
addType = true;
}
break;
/* istanbul ignore next */
default:
throw new TypeError('Unknown value type ' + valueType);
}
if (addType) {
retObj = {
path: path,
value: val,
parent: parent,
parentProperty: parentPropName
};
this._handleCallback(retObj, callback, 'value');
return retObj;
} // `-escaped property
} else if (loc[0] === '`' && val && hasOwnProp.call(val, loc.slice(1))) {
var locProp = loc.slice(1);
addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true));
} else if (loc.includes(',')) {
// [name1,name2,...]
var parts = loc.split(',');
var _iterator = _createForOfIteratorHelper(parts),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var part = _step.value;
addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));
} // simple case--directly follow property
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
} else if (!literalPriority && val && hasOwnProp.call(val, loc)) {
addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true));
} // We check the resulting values for parent selections. For parent
// selections we discard the value object and continue the trace with the
// current val object
if (this._hasParentSelector) {
for (var t = 0; t < ret.length; t++) {
var rett = ret[t];
if (rett && rett.isParentSelector) {
var tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);
if (Array.isArray(tmp)) {
ret[t] = tmp[0];
var tl = tmp.length;
for (var tt = 1; tt < tl; tt++) {
t++;
ret.splice(t, 0, tmp[tt]);
}
} else {
ret[t] = tmp;
}
}
}
}
return ret;
};
JSONPath.prototype._walk = function (loc, expr, val, path, parent, parentPropName, callback, f) {
if (Array.isArray(val)) {
var n = val.length;
for (var i = 0; i < n; i++) {
f(i, loc, expr, val, path, parent, parentPropName, callback);
}
} else if (val && _typeof(val) === 'object') {
Object.keys(val).forEach(function (m) {
f(m, loc, expr, val, path, parent, parentPropName, callback);
});
}
};
JSONPath.prototype._slice = function (loc, expr, val, path, parent, parentPropName, callback) {
if (!Array.isArray(val)) {
return undefined;
}
var len = val.length,
parts = loc.split(':'),
step = parts[2] && Number.parseInt(parts[2]) || 1;
var start = parts[0] && Number.parseInt(parts[0]) || 0,
end = parts[1] && Number.parseInt(parts[1]) || len;
start = start < 0 ? Math.max(0, start + len) : Math.min(len, start);
end = end < 0 ? Math.max(0, end + len) : Math.min(len, end);
var ret = [];
for (var i = start; i < end; i += step) {
var tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true); // Should only be possible to be an array here since first part of
// ``unshift(i, expr)` passed in above would not be empty, nor `~`,
// nor begin with `@` (as could return objects)
// This was causing excessive stack size in Node (with or
// without Babel) against our performance test: `ret.push(...tmp);`
tmp.forEach(function (t) {
ret.push(t);
});
}
return ret;
};
JSONPath.prototype._eval = function (code, _v, _vname, path, parent, parentPropName) {
if (code.includes('@parentProperty')) {
this.currSandbox._$_parentProperty = parentPropName;
code = code.replace(/@parentProperty/g, '_$_parentProperty');
}
if (code.includes('@parent')) {
this.currSandbox._$_parent = parent;
code = code.replace(/@parent/g, '_$_parent');
}
if (code.includes('@property')) {
this.currSandbox._$_property = _vname;
code = code.replace(/@property/g, '_$_property');
}
if (code.includes('@path')) {
this.currSandbox._$_path = JSONPath.toPathString(path.concat([_vname]));
code = code.replace(/@path/g, '_$_path');
}
if (code.includes('@root')) {
this.currSandbox._$_root = this.json;
code = code.replace(/@root/g, '_$_root');
}
if (/@([\t-\r \)\.\[\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF])/.test(code)) {
this.currSandbox._$_v = _v;
code = code.replace(/@([\t-\r \)\.\[\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF])/g, '_$_v$1');
}
try {
return this.vm.runInNewContext(code, this.currSandbox);
} catch (e) {
// eslint-disable-next-line no-console
console.log(e);
throw new Error('jsonPath: ' + e.message + ': ' + code);
}
}; // PUBLIC CLASS PROPERTIES AND METHODS
// Could store the cache object itself
JSONPath.cache = {};
/**
* @param {string[]} pathArr Array to convert
* @returns {string} The path string
*/
JSONPath.toPathString = function (pathArr) {
var x = pathArr,
n = x.length;
var p = '$';
for (var i = 1; i < n; i++) {
if (!/^(~|\^|@(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?\(\))$/.test(x[i])) {
p += /^[\*0-9]+$/.test(x[i]) ? '[' + x[i] + ']' : "['" + x[i] + "']";
}
}
return p;
};
/**
* @param {string} pointer JSON Path
* @returns {string} JSON Pointer
*/
JSONPath.toPointer = function (pointer) {
var x = pointer,
n = x.length;
var p = '';
for (var i = 1; i < n; i++) {
if (!/^(~|\^|@(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?\(\))$/.test(x[i])) {
p += '/' + x[i].toString().replace(/~/g, '~0').replace(/\//g, '~1');
}
}
return p;
};
/**
* @param {string} expr Expression to convert
* @returns {string[]}
*/
JSONPath.toPathArray = function (expr) {
var cache = JSONPath.cache;
if (cache[expr]) {
return cache[expr].concat();
}
var subx = [];
var normalized = expr // Properties
.replace(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/g, ';$&;') // Parenthetical evaluations (filtering and otherwise), directly
// within brackets or single quotes
.replace(/['\[](\??\((?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*?\))['\]]/g, function ($0, $1) {
return '[#' + (subx.push($1) - 1) + ']';
}) // Escape periods and tildes within properties
.replace(/\['((?:(?!['\]])[\s\S])*)'\]/g, function ($0, prop) {
return "['" + prop.replace(/\./g, '%@%').replace(/~/g, '%%@@%%') + "']";
}) // Properties operator
.replace(/~/g, ';~;') // Split by property boundaries
.replace(/'?\.'?(?!(?:(?!\[)[\s\S])*\])|\['?/g, ';') // Reinsert periods within properties
.replace(/%@%/g, '.') // Reinsert tildes within properties
.replace(/%%@@%%/g, '~') // Parent
.replace(/(?:;)?(\^+)(?:;)?/g, function ($0, ups) {
return ';' + ups.split('').join(';') + ';';
}) // Descendents
.replace(/;;;|;;/g, ';..;') // Remove trailing
.replace(/;$|'?\]|'$/g, '');
var exprList = normalized.split(';').map(function (exp) {
var match = exp.match(/#([0-9]+)/);
return !match || !match[1] ? exp : subx[match[1]];
});
cache[expr] = exprList;
return cache[expr].concat();
};
/**
* @callback ConditionCallback
* @param {any} item
* @returns {boolean}
*/
/**
* Copy items out of one array into another.
* @param {GenericArray} source Array with items to copy
* @param {GenericArray} target Array to which to copy
* @param {ConditionCallback} conditionCb Callback passed the current item;
* will move item if evaluates to `true`
* @returns {void}
*/
var moveToAnotherArray = function moveToAnotherArray(source, target, conditionCb) {
var il = source.length;
for (var i = 0; i < il; i++) {
var item = source[i];
if (conditionCb(item)) {
target.push(source.splice(i--, 1)[0]);
}
}
};
JSONPath.prototype.vm = {
/**
* @param {string} expr Expression to evaluate
* @param {PlainObject} context Object whose items will be added
* to evaluation
* @returns {any} Result of evaluated code
*/
runInNewContext: function runInNewContext(expr, context) {
var keys = Object.keys(context);
var funcs = [];
moveToAnotherArray(keys, funcs, function (key) {
return typeof context[key] === 'function';
});
var values = keys.map(function (vr, i) {
return context[vr];
});
var funcString = funcs.reduce(function (s, func) {
var fString = context[func].toString();
if (!/function/.test(fString)) {
fString = 'function ' + fString;
}
return 'var ' + func + '=' + fString + ';' + s;
}, '');
expr = funcString + expr; // Mitigate http://perfectionkills.com/global-eval-what-are-the-options/#new_function
if (!/(["'])use strict\1/.test(expr) && !keys.includes('arguments')) {
expr = 'var arguments = undefined;' + expr;
} // Remove last semi so `return` will be inserted before
// the previous one instead, allowing for the return
// of a bare ending expression
expr = expr.replace(/;[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*$/, ''); // Insert `return`
var lastStatementEnd = expr.lastIndexOf(';');
var code = lastStatementEnd > -1 ? expr.slice(0, lastStatementEnd + 1) + ' return ' + expr.slice(lastStatementEnd + 1) : ' return ' + expr; // eslint-disable-next-line no-new-func
return _construct(Function, _toConsumableArray(keys).concat([code])).apply(void 0, _toConsumableArray(values));
}
};
export { JSONPath };