UNPKG

31.6 kBJavaScriptView Raw
1function _typeof(obj) {
2 "@babel/helpers - typeof";
3
4 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
5 _typeof = function (obj) {
6 return typeof obj;
7 };
8 } else {
9 _typeof = function (obj) {
10 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
11 };
12 }
13
14 return _typeof(obj);
15}
16
17function _classCallCheck(instance, Constructor) {
18 if (!(instance instanceof Constructor)) {
19 throw new TypeError("Cannot call a class as a function");
20 }
21}
22
23function _inherits(subClass, superClass) {
24 if (typeof superClass !== "function" && superClass !== null) {
25 throw new TypeError("Super expression must either be null or a function");
26 }
27
28 subClass.prototype = Object.create(superClass && superClass.prototype, {
29 constructor: {
30 value: subClass,
31 writable: true,
32 configurable: true
33 }
34 });
35 if (superClass) _setPrototypeOf(subClass, superClass);
36}
37
38function _getPrototypeOf(o) {
39 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
40 return o.__proto__ || Object.getPrototypeOf(o);
41 };
42 return _getPrototypeOf(o);
43}
44
45function _setPrototypeOf(o, p) {
46 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
47 o.__proto__ = p;
48 return o;
49 };
50
51 return _setPrototypeOf(o, p);
52}
53
54function _isNativeReflectConstruct() {
55 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
56 if (Reflect.construct.sham) return false;
57 if (typeof Proxy === "function") return true;
58
59 try {
60 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
61 return true;
62 } catch (e) {
63 return false;
64 }
65}
66
67function _construct(Parent, args, Class) {
68 if (_isNativeReflectConstruct()) {
69 _construct = Reflect.construct;
70 } else {
71 _construct = function _construct(Parent, args, Class) {
72 var a = [null];
73 a.push.apply(a, args);
74 var Constructor = Function.bind.apply(Parent, a);
75 var instance = new Constructor();
76 if (Class) _setPrototypeOf(instance, Class.prototype);
77 return instance;
78 };
79 }
80
81 return _construct.apply(null, arguments);
82}
83
84function _isNativeFunction(fn) {
85 return Function.toString.call(fn).indexOf("[native code]") !== -1;
86}
87
88function _wrapNativeSuper(Class) {
89 var _cache = typeof Map === "function" ? new Map() : undefined;
90
91 _wrapNativeSuper = function _wrapNativeSuper(Class) {
92 if (Class === null || !_isNativeFunction(Class)) return Class;
93
94 if (typeof Class !== "function") {
95 throw new TypeError("Super expression must either be null or a function");
96 }
97
98 if (typeof _cache !== "undefined") {
99 if (_cache.has(Class)) return _cache.get(Class);
100
101 _cache.set(Class, Wrapper);
102 }
103
104 function Wrapper() {
105 return _construct(Class, arguments, _getPrototypeOf(this).constructor);
106 }
107
108 Wrapper.prototype = Object.create(Class.prototype, {
109 constructor: {
110 value: Wrapper,
111 enumerable: false,
112 writable: true,
113 configurable: true
114 }
115 });
116 return _setPrototypeOf(Wrapper, Class);
117 };
118
119 return _wrapNativeSuper(Class);
120}
121
122function _assertThisInitialized(self) {
123 if (self === void 0) {
124 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
125 }
126
127 return self;
128}
129
130function _possibleConstructorReturn(self, call) {
131 if (call && (typeof call === "object" || typeof call === "function")) {
132 return call;
133 }
134
135 return _assertThisInitialized(self);
136}
137
138function _createSuper(Derived) {
139 var hasNativeReflectConstruct = _isNativeReflectConstruct();
140
141 return function _createSuperInternal() {
142 var Super = _getPrototypeOf(Derived),
143 result;
144
145 if (hasNativeReflectConstruct) {
146 var NewTarget = _getPrototypeOf(this).constructor;
147
148 result = Reflect.construct(Super, arguments, NewTarget);
149 } else {
150 result = Super.apply(this, arguments);
151 }
152
153 return _possibleConstructorReturn(this, result);
154 };
155}
156
157function _toConsumableArray(arr) {
158 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
159}
160
161function _arrayWithoutHoles(arr) {
162 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
163}
164
165function _iterableToArray(iter) {
166 if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
167}
168
169function _unsupportedIterableToArray(o, minLen) {
170 if (!o) return;
171 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
172 var n = Object.prototype.toString.call(o).slice(8, -1);
173 if (n === "Object" && o.constructor) n = o.constructor.name;
174 if (n === "Map" || n === "Set") return Array.from(o);
175 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
176}
177
178function _arrayLikeToArray(arr, len) {
179 if (len == null || len > arr.length) len = arr.length;
180
181 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
182
183 return arr2;
184}
185
186function _nonIterableSpread() {
187 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
188}
189
190function _createForOfIteratorHelper(o, allowArrayLike) {
191 var it;
192
193 if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
194 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
195 if (it) o = it;
196 var i = 0;
197
198 var F = function () {};
199
200 return {
201 s: F,
202 n: function () {
203 if (i >= o.length) return {
204 done: true
205 };
206 return {
207 done: false,
208 value: o[i++]
209 };
210 },
211 e: function (e) {
212 throw e;
213 },
214 f: F
215 };
216 }
217
218 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
219 }
220
221 var normalCompletion = true,
222 didErr = false,
223 err;
224 return {
225 s: function () {
226 it = o[Symbol.iterator]();
227 },
228 n: function () {
229 var step = it.next();
230 normalCompletion = step.done;
231 return step;
232 },
233 e: function (e) {
234 didErr = true;
235 err = e;
236 },
237 f: function () {
238 try {
239 if (!normalCompletion && it.return != null) it.return();
240 } finally {
241 if (didErr) throw err;
242 }
243 }
244 };
245}
246
247var hasOwnProp = Object.prototype.hasOwnProperty;
248/**
249* @typedef {null|boolean|number|string|PlainObject|GenericArray} JSONObject
250*/
251
252/**
253 * Copies array and then pushes item into it.
254 * @param {GenericArray} arr Array to copy and into which to push
255 * @param {any} item Array item to add (to end)
256 * @returns {GenericArray} Copy of the original array
257 */
258
259function push(arr, item) {
260 arr = arr.slice();
261 arr.push(item);
262 return arr;
263}
264/**
265 * Copies array and then unshifts item into it.
266 * @param {any} item Array item to add (to beginning)
267 * @param {GenericArray} arr Array to copy and into which to unshift
268 * @returns {GenericArray} Copy of the original array
269 */
270
271
272function unshift(item, arr) {
273 arr = arr.slice();
274 arr.unshift(item);
275 return arr;
276}
277/**
278 * Caught when JSONPath is used without `new` but rethrown if with `new`
279 * @extends Error
280 */
281
282
283var NewError = /*#__PURE__*/function (_Error) {
284 _inherits(NewError, _Error);
285
286 var _super = _createSuper(NewError);
287
288 /**
289 * @param {any} value The evaluated scalar value
290 */
291 function NewError(value) {
292 var _this;
293
294 _classCallCheck(this, NewError);
295
296 _this = _super.call(this, 'JSONPath should not be called with "new" (it prevents return ' + 'of (unwrapped) scalar values)');
297 _this.avoidNew = true;
298 _this.value = value;
299 _this.name = 'NewError';
300 return _this;
301 }
302
303 return NewError;
304}( /*#__PURE__*/_wrapNativeSuper(Error));
305/**
306* @typedef {PlainObject} ReturnObject
307* @property {string} path
308* @property {JSONObject} value
309* @property {PlainObject|GenericArray} parent
310* @property {string} parentProperty
311*/
312
313/**
314* @callback JSONPathCallback
315* @param {string|PlainObject} preferredOutput
316* @param {"value"|"property"} type
317* @param {ReturnObject} fullRetObj
318* @returns {void}
319*/
320
321/**
322* @callback OtherTypeCallback
323* @param {JSONObject} val
324* @param {string} path
325* @param {PlainObject|GenericArray} parent
326* @param {string} parentPropName
327* @returns {boolean}
328*/
329
330/* eslint-disable max-len -- Can make multiline type after https://github.com/syavorsky/comment-parser/issues/109 */
331
332/**
333 * @typedef {PlainObject} JSONPathOptions
334 * @property {JSON} json
335 * @property {string|string[]} path
336 * @property {"value"|"path"|"pointer"|"parent"|"parentProperty"|"all"} [resultType="value"]
337 * @property {boolean} [flatten=false]
338 * @property {boolean} [wrap=true]
339 * @property {PlainObject} [sandbox={}]
340 * @property {boolean} [preventEval=false]
341 * @property {PlainObject|GenericArray|null} [parent=null]
342 * @property {string|null} [parentProperty=null]
343 * @property {JSONPathCallback} [callback]
344 * @property {OtherTypeCallback} [otherTypeCallback] Defaults to
345 * function which throws on encountering `@other`
346 * @property {boolean} [autostart=true]
347 */
348
349/* eslint-enable max-len -- Can make multiline type after https://github.com/syavorsky/comment-parser/issues/109 */
350
351/**
352 * @param {string|JSONPathOptions} opts If a string, will be treated as `expr`
353 * @param {string} [expr] JSON path to evaluate
354 * @param {JSON} [obj] JSON object to evaluate against
355 * @param {JSONPathCallback} [callback] Passed 3 arguments: 1) desired payload
356 * per `resultType`, 2) `"value"|"property"`, 3) Full returned object with
357 * all payloads
358 * @param {OtherTypeCallback} [otherTypeCallback] If `@other()` is at the end
359 * of one's query, this will be invoked with the value of the item, its
360 * path, its parent, and its parent's property name, and it should return
361 * a boolean indicating whether the supplied value belongs to the "other"
362 * type or not (or it may handle transformations and return `false`).
363 * @returns {JSONPath}
364 * @class
365 */
366
367
368function JSONPath(opts, expr, obj, callback, otherTypeCallback) {
369 // eslint-disable-next-line no-restricted-syntax
370 if (!(this instanceof JSONPath)) {
371 try {
372 return new JSONPath(opts, expr, obj, callback, otherTypeCallback);
373 } catch (e) {
374 if (!e.avoidNew) {
375 throw e;
376 }
377
378 return e.value;
379 }
380 }
381
382 if (typeof opts === 'string') {
383 otherTypeCallback = callback;
384 callback = obj;
385 obj = expr;
386 expr = opts;
387 opts = null;
388 }
389
390 var optObj = opts && _typeof(opts) === 'object';
391 opts = opts || {};
392 this.json = opts.json || obj;
393 this.path = opts.path || expr;
394 this.resultType = opts.resultType || 'value';
395 this.flatten = opts.flatten || false;
396 this.wrap = hasOwnProp.call(opts, 'wrap') ? opts.wrap : true;
397 this.sandbox = opts.sandbox || {};
398 this.preventEval = opts.preventEval || false;
399 this.parent = opts.parent || null;
400 this.parentProperty = opts.parentProperty || null;
401 this.callback = opts.callback || callback || null;
402
403 this.otherTypeCallback = opts.otherTypeCallback || otherTypeCallback || function () {
404 throw new TypeError('You must supply an otherTypeCallback callback option ' + 'with the @other() operator.');
405 };
406
407 if (opts.autostart !== false) {
408 var args = {
409 path: optObj ? opts.path : expr
410 };
411
412 if (!optObj) {
413 args.json = obj;
414 } else if ('json' in opts) {
415 args.json = opts.json;
416 }
417
418 var ret = this.evaluate(args);
419
420 if (!ret || _typeof(ret) !== 'object') {
421 throw new NewError(ret);
422 }
423
424 return ret;
425 }
426} // PUBLIC METHODS
427
428
429JSONPath.prototype.evaluate = function (expr, json, callback, otherTypeCallback) {
430 var _this2 = this;
431
432 var currParent = this.parent,
433 currParentProperty = this.parentProperty;
434 var flatten = this.flatten,
435 wrap = this.wrap;
436 this.currResultType = this.resultType;
437 this.currPreventEval = this.preventEval;
438 this.currSandbox = this.sandbox;
439 callback = callback || this.callback;
440 this.currOtherTypeCallback = otherTypeCallback || this.otherTypeCallback;
441 json = json || this.json;
442 expr = expr || this.path;
443
444 if (expr && _typeof(expr) === 'object' && !Array.isArray(expr)) {
445 if (!expr.path && expr.path !== '') {
446 throw new TypeError('You must supply a "path" property when providing an object ' + 'argument to JSONPath.evaluate().');
447 }
448
449 if (!hasOwnProp.call(expr, 'json')) {
450 throw new TypeError('You must supply a "json" property when providing an object ' + 'argument to JSONPath.evaluate().');
451 }
452
453 var _expr = expr;
454 json = _expr.json;
455 flatten = hasOwnProp.call(expr, 'flatten') ? expr.flatten : flatten;
456 this.currResultType = hasOwnProp.call(expr, 'resultType') ? expr.resultType : this.currResultType;
457 this.currSandbox = hasOwnProp.call(expr, 'sandbox') ? expr.sandbox : this.currSandbox;
458 wrap = hasOwnProp.call(expr, 'wrap') ? expr.wrap : wrap;
459 this.currPreventEval = hasOwnProp.call(expr, 'preventEval') ? expr.preventEval : this.currPreventEval;
460 callback = hasOwnProp.call(expr, 'callback') ? expr.callback : callback;
461 this.currOtherTypeCallback = hasOwnProp.call(expr, 'otherTypeCallback') ? expr.otherTypeCallback : this.currOtherTypeCallback;
462 currParent = hasOwnProp.call(expr, 'parent') ? expr.parent : currParent;
463 currParentProperty = hasOwnProp.call(expr, 'parentProperty') ? expr.parentProperty : currParentProperty;
464 expr = expr.path;
465 }
466
467 currParent = currParent || null;
468 currParentProperty = currParentProperty || null;
469
470 if (Array.isArray(expr)) {
471 expr = JSONPath.toPathString(expr);
472 }
473
474 if (!expr && expr !== '' || !json) {
475 return undefined;
476 }
477
478 var exprList = JSONPath.toPathArray(expr);
479
480 if (exprList[0] === '$' && exprList.length > 1) {
481 exprList.shift();
482 }
483
484 this._hasParentSelector = null;
485
486 var result = this._trace(exprList, json, ['$'], currParent, currParentProperty, callback).filter(function (ea) {
487 return ea && !ea.isParentSelector;
488 });
489
490 if (!result.length) {
491 return wrap ? [] : undefined;
492 }
493
494 if (!wrap && result.length === 1 && !result[0].hasArrExpr) {
495 return this._getPreferredOutput(result[0]);
496 }
497
498 return result.reduce(function (rslt, ea) {
499 var valOrPath = _this2._getPreferredOutput(ea);
500
501 if (flatten && Array.isArray(valOrPath)) {
502 rslt = rslt.concat(valOrPath);
503 } else {
504 rslt.push(valOrPath);
505 }
506
507 return rslt;
508 }, []);
509}; // PRIVATE METHODS
510
511
512JSONPath.prototype._getPreferredOutput = function (ea) {
513 var resultType = this.currResultType;
514
515 switch (resultType) {
516 case 'all':
517 {
518 var path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path);
519 ea.pointer = JSONPath.toPointer(path);
520 ea.path = typeof ea.path === 'string' ? ea.path : JSONPath.toPathString(ea.path);
521 return ea;
522 }
523
524 case 'value':
525 case 'parent':
526 case 'parentProperty':
527 return ea[resultType];
528
529 case 'path':
530 return JSONPath.toPathString(ea[resultType]);
531
532 case 'pointer':
533 return JSONPath.toPointer(ea.path);
534
535 default:
536 throw new TypeError('Unknown result type');
537 }
538};
539
540JSONPath.prototype._handleCallback = function (fullRetObj, callback, type) {
541 if (callback) {
542 var preferredOutput = this._getPreferredOutput(fullRetObj);
543
544 fullRetObj.path = typeof fullRetObj.path === 'string' ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path); // eslint-disable-next-line node/callback-return
545
546 callback(preferredOutput, type, fullRetObj);
547 }
548};
549/**
550 *
551 * @param {string} expr
552 * @param {JSONObject} val
553 * @param {string} path
554 * @param {PlainObject|GenericArray} parent
555 * @param {string} parentPropName
556 * @param {JSONPathCallback} callback
557 * @param {boolean} hasArrExpr
558 * @param {boolean} literalPriority
559 * @returns {ReturnObject|ReturnObject[]}
560 */
561
562
563JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) {
564 var _this3 = this;
565
566 // No expr to follow? return path and value as the result of
567 // this trace branch
568 var retObj;
569
570 if (!expr.length) {
571 retObj = {
572 path: path,
573 value: val,
574 parent: parent,
575 parentProperty: parentPropName,
576 hasArrExpr: hasArrExpr
577 };
578
579 this._handleCallback(retObj, callback, 'value');
580
581 return retObj;
582 }
583
584 var loc = expr[0],
585 x = expr.slice(1); // We need to gather the return value of recursive trace calls in order to
586 // do the parent sel computation.
587
588 var ret = [];
589 /**
590 *
591 * @param {ReturnObject|ReturnObject[]} elems
592 * @returns {void}
593 */
594
595 function addRet(elems) {
596 if (Array.isArray(elems)) {
597 // This was causing excessive stack size in Node (with or
598 // without Babel) against our performance test:
599 // `ret.push(...elems);`
600 elems.forEach(function (t) {
601 ret.push(t);
602 });
603 } else {
604 ret.push(elems);
605 }
606 }
607
608 if ((typeof loc !== 'string' || literalPriority) && val && hasOwnProp.call(val, loc)) {
609 // simple case--directly follow property
610 addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr));
611 } else if (loc === '*') {
612 // all child properties
613 this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
614 addRet(_this3._trace(unshift(m, _x), v, p, par, pr, cb, true, true));
615 });
616 } else if (loc === '..') {
617 // all descendent parent properties
618 // Check remaining expression with val's immediate children
619 addRet(this._trace(x, val, path, parent, parentPropName, callback, hasArrExpr));
620
621 this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
622 // We don't join m and x here because we only want parents,
623 // not scalar values
624 if (_typeof(v[m]) === 'object') {
625 // Keep going with recursive descent on val's
626 // object children
627 addRet(_this3._trace(unshift(l, _x), v[m], push(p, m), v, m, cb, true));
628 }
629 }); // The parent sel computation is handled in the frame above using the
630 // ancestor object of val
631
632 } else if (loc === '^') {
633 // This is not a final endpoint, so we do not invoke the callback here
634 this._hasParentSelector = true;
635 return {
636 path: path.slice(0, -1),
637 expr: x,
638 isParentSelector: true
639 };
640 } else if (loc === '~') {
641 // property name
642 retObj = {
643 path: push(path, loc),
644 value: parentPropName,
645 parent: parent,
646 parentProperty: null
647 };
648
649 this._handleCallback(retObj, callback, 'property');
650
651 return retObj;
652 } else if (loc === '$') {
653 // root only
654 addRet(this._trace(x, val, path, null, null, callback, hasArrExpr));
655 } else if (/^(\x2D?[0-9]*):(\x2D?[0-9]*):?([0-9]*)$/.test(loc)) {
656 // [start:end:step] Python slice syntax
657 addRet(this._slice(loc, x, val, path, parent, parentPropName, callback));
658 } else if (loc.indexOf('?(') === 0) {
659 // [?(expr)] (filtering)
660 if (this.currPreventEval) {
661 throw new Error('Eval [?(expr)] prevented in JSONPath expression.');
662 }
663
664 this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
665 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)) {
666 addRet(_this3._trace(unshift(m, _x), v, p, par, pr, cb, true));
667 }
668 });
669 } else if (loc[0] === '(') {
670 // [(expr)] (dynamic property/index)
671 if (this.currPreventEval) {
672 throw new Error('Eval [(expr)] prevented in JSONPath expression.');
673 } // As this will resolve to a property name (but we don't know it
674 // yet), property and parent information is relative to the
675 // parent of the property to which this expression will resolve
676
677
678 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));
679 } else if (loc[0] === '@') {
680 // value type: @boolean(), etc.
681 var addType = false;
682 var valueType = loc.slice(1, -2);
683
684 switch (valueType) {
685 case 'scalar':
686 if (!val || !['object', 'function'].includes(_typeof(val))) {
687 addType = true;
688 }
689
690 break;
691
692 case 'boolean':
693 case 'string':
694 case 'undefined':
695 case 'function':
696 // eslint-disable-next-line valid-typeof
697 if (_typeof(val) === valueType) {
698 addType = true;
699 }
700
701 break;
702
703 case 'integer':
704 if (Number.isFinite(val) && !(val % 1)) {
705 addType = true;
706 }
707
708 break;
709
710 case 'number':
711 if (Number.isFinite(val)) {
712 addType = true;
713 }
714
715 break;
716
717 case 'nonFinite':
718 if (typeof val === 'number' && !Number.isFinite(val)) {
719 addType = true;
720 }
721
722 break;
723
724 case 'object':
725 // eslint-disable-next-line valid-typeof
726 if (val && _typeof(val) === valueType) {
727 addType = true;
728 }
729
730 break;
731
732 case 'array':
733 if (Array.isArray(val)) {
734 addType = true;
735 }
736
737 break;
738
739 case 'other':
740 addType = this.currOtherTypeCallback(val, path, parent, parentPropName);
741 break;
742
743 case 'null':
744 if (val === null) {
745 addType = true;
746 }
747
748 break;
749
750 /* istanbul ignore next */
751
752 default:
753 throw new TypeError('Unknown value type ' + valueType);
754 }
755
756 if (addType) {
757 retObj = {
758 path: path,
759 value: val,
760 parent: parent,
761 parentProperty: parentPropName
762 };
763
764 this._handleCallback(retObj, callback, 'value');
765
766 return retObj;
767 } // `-escaped property
768
769 } else if (loc[0] === '`' && val && hasOwnProp.call(val, loc.slice(1))) {
770 var locProp = loc.slice(1);
771 addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true));
772 } else if (loc.includes(',')) {
773 // [name1,name2,...]
774 var parts = loc.split(',');
775
776 var _iterator = _createForOfIteratorHelper(parts),
777 _step;
778
779 try {
780 for (_iterator.s(); !(_step = _iterator.n()).done;) {
781 var part = _step.value;
782 addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));
783 } // simple case--directly follow property
784
785 } catch (err) {
786 _iterator.e(err);
787 } finally {
788 _iterator.f();
789 }
790 } else if (!literalPriority && val && hasOwnProp.call(val, loc)) {
791 addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true));
792 } // We check the resulting values for parent selections. For parent
793 // selections we discard the value object and continue the trace with the
794 // current val object
795
796
797 if (this._hasParentSelector) {
798 for (var t = 0; t < ret.length; t++) {
799 var rett = ret[t];
800
801 if (rett && rett.isParentSelector) {
802 var tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);
803
804 if (Array.isArray(tmp)) {
805 ret[t] = tmp[0];
806 var tl = tmp.length;
807
808 for (var tt = 1; tt < tl; tt++) {
809 t++;
810 ret.splice(t, 0, tmp[tt]);
811 }
812 } else {
813 ret[t] = tmp;
814 }
815 }
816 }
817 }
818
819 return ret;
820};
821
822JSONPath.prototype._walk = function (loc, expr, val, path, parent, parentPropName, callback, f) {
823 if (Array.isArray(val)) {
824 var n = val.length;
825
826 for (var i = 0; i < n; i++) {
827 f(i, loc, expr, val, path, parent, parentPropName, callback);
828 }
829 } else if (val && _typeof(val) === 'object') {
830 Object.keys(val).forEach(function (m) {
831 f(m, loc, expr, val, path, parent, parentPropName, callback);
832 });
833 }
834};
835
836JSONPath.prototype._slice = function (loc, expr, val, path, parent, parentPropName, callback) {
837 if (!Array.isArray(val)) {
838 return undefined;
839 }
840
841 var len = val.length,
842 parts = loc.split(':'),
843 step = parts[2] && Number.parseInt(parts[2]) || 1;
844 var start = parts[0] && Number.parseInt(parts[0]) || 0,
845 end = parts[1] && Number.parseInt(parts[1]) || len;
846 start = start < 0 ? Math.max(0, start + len) : Math.min(len, start);
847 end = end < 0 ? Math.max(0, end + len) : Math.min(len, end);
848 var ret = [];
849
850 for (var i = start; i < end; i += step) {
851 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
852 // ``unshift(i, expr)` passed in above would not be empty, nor `~`,
853 // nor begin with `@` (as could return objects)
854 // This was causing excessive stack size in Node (with or
855 // without Babel) against our performance test: `ret.push(...tmp);`
856
857
858 tmp.forEach(function (t) {
859 ret.push(t);
860 });
861 }
862
863 return ret;
864};
865
866JSONPath.prototype._eval = function (code, _v, _vname, path, parent, parentPropName) {
867 if (code.includes('@parentProperty')) {
868 this.currSandbox._$_parentProperty = parentPropName;
869 code = code.replace(/@parentProperty/g, '_$_parentProperty');
870 }
871
872 if (code.includes('@parent')) {
873 this.currSandbox._$_parent = parent;
874 code = code.replace(/@parent/g, '_$_parent');
875 }
876
877 if (code.includes('@property')) {
878 this.currSandbox._$_property = _vname;
879 code = code.replace(/@property/g, '_$_property');
880 }
881
882 if (code.includes('@path')) {
883 this.currSandbox._$_path = JSONPath.toPathString(path.concat([_vname]));
884 code = code.replace(/@path/g, '_$_path');
885 }
886
887 if (code.includes('@root')) {
888 this.currSandbox._$_root = this.json;
889 code = code.replace(/@root/g, '_$_root');
890 }
891
892 if (/@([\t-\r \)\.\[\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF])/.test(code)) {
893 this.currSandbox._$_v = _v;
894 code = code.replace(/@([\t-\r \)\.\[\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF])/g, '_$_v$1');
895 }
896
897 try {
898 return this.vm.runInNewContext(code, this.currSandbox);
899 } catch (e) {
900 // eslint-disable-next-line no-console
901 console.log(e);
902 throw new Error('jsonPath: ' + e.message + ': ' + code);
903 }
904}; // PUBLIC CLASS PROPERTIES AND METHODS
905// Could store the cache object itself
906
907
908JSONPath.cache = {};
909/**
910 * @param {string[]} pathArr Array to convert
911 * @returns {string} The path string
912 */
913
914JSONPath.toPathString = function (pathArr) {
915 var x = pathArr,
916 n = x.length;
917 var p = '$';
918
919 for (var i = 1; i < n; i++) {
920 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])) {
921 p += /^[\*0-9]+$/.test(x[i]) ? '[' + x[i] + ']' : "['" + x[i] + "']";
922 }
923 }
924
925 return p;
926};
927/**
928 * @param {string} pointer JSON Path
929 * @returns {string} JSON Pointer
930 */
931
932
933JSONPath.toPointer = function (pointer) {
934 var x = pointer,
935 n = x.length;
936 var p = '';
937
938 for (var i = 1; i < n; i++) {
939 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])) {
940 p += '/' + x[i].toString().replace(/~/g, '~0').replace(/\//g, '~1');
941 }
942 }
943
944 return p;
945};
946/**
947 * @param {string} expr Expression to convert
948 * @returns {string[]}
949 */
950
951
952JSONPath.toPathArray = function (expr) {
953 var cache = JSONPath.cache;
954
955 if (cache[expr]) {
956 return cache[expr].concat();
957 }
958
959 var subx = [];
960 var normalized = expr // Properties
961 .replace(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\(\)/g, ';$&;') // Parenthetical evaluations (filtering and otherwise), directly
962 // within brackets or single quotes
963 .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) {
964 return '[#' + (subx.push($1) - 1) + ']';
965 }) // Escape periods and tildes within properties
966 .replace(/\['((?:(?!['\]])[\s\S])*)'\]/g, function ($0, prop) {
967 return "['" + prop.replace(/\./g, '%@%').replace(/~/g, '%%@@%%') + "']";
968 }) // Properties operator
969 .replace(/~/g, ';~;') // Split by property boundaries
970 .replace(/'?\.'?(?!(?:(?!\[)[\s\S])*\])|\['?/g, ';') // Reinsert periods within properties
971 .replace(/%@%/g, '.') // Reinsert tildes within properties
972 .replace(/%%@@%%/g, '~') // Parent
973 .replace(/(?:;)?(\^+)(?:;)?/g, function ($0, ups) {
974 return ';' + ups.split('').join(';') + ';';
975 }) // Descendents
976 .replace(/;;;|;;/g, ';..;') // Remove trailing
977 .replace(/;$|'?\]|'$/g, '');
978 var exprList = normalized.split(';').map(function (exp) {
979 var match = exp.match(/#([0-9]+)/);
980 return !match || !match[1] ? exp : subx[match[1]];
981 });
982 cache[expr] = exprList;
983 return cache[expr].concat();
984};
985
986/**
987* @callback ConditionCallback
988* @param {any} item
989* @returns {boolean}
990*/
991
992/**
993 * Copy items out of one array into another.
994 * @param {GenericArray} source Array with items to copy
995 * @param {GenericArray} target Array to which to copy
996 * @param {ConditionCallback} conditionCb Callback passed the current item;
997 * will move item if evaluates to `true`
998 * @returns {void}
999 */
1000
1001var moveToAnotherArray = function moveToAnotherArray(source, target, conditionCb) {
1002 var il = source.length;
1003
1004 for (var i = 0; i < il; i++) {
1005 var item = source[i];
1006
1007 if (conditionCb(item)) {
1008 target.push(source.splice(i--, 1)[0]);
1009 }
1010 }
1011};
1012
1013JSONPath.prototype.vm = {
1014 /**
1015 * @param {string} expr Expression to evaluate
1016 * @param {PlainObject} context Object whose items will be added
1017 * to evaluation
1018 * @returns {any} Result of evaluated code
1019 */
1020 runInNewContext: function runInNewContext(expr, context) {
1021 var keys = Object.keys(context);
1022 var funcs = [];
1023 moveToAnotherArray(keys, funcs, function (key) {
1024 return typeof context[key] === 'function';
1025 });
1026 var values = keys.map(function (vr, i) {
1027 return context[vr];
1028 });
1029 var funcString = funcs.reduce(function (s, func) {
1030 var fString = context[func].toString();
1031
1032 if (!/function/.test(fString)) {
1033 fString = 'function ' + fString;
1034 }
1035
1036 return 'var ' + func + '=' + fString + ';' + s;
1037 }, '');
1038 expr = funcString + expr; // Mitigate http://perfectionkills.com/global-eval-what-are-the-options/#new_function
1039
1040 if (!/(["'])use strict\1/.test(expr) && !keys.includes('arguments')) {
1041 expr = 'var arguments = undefined;' + expr;
1042 } // Remove last semi so `return` will be inserted before
1043 // the previous one instead, allowing for the return
1044 // of a bare ending expression
1045
1046
1047 expr = expr.replace(/;[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*$/, ''); // Insert `return`
1048
1049 var lastStatementEnd = expr.lastIndexOf(';');
1050 var code = lastStatementEnd > -1 ? expr.slice(0, lastStatementEnd + 1) + ' return ' + expr.slice(lastStatementEnd + 1) : ' return ' + expr; // eslint-disable-next-line no-new-func
1051
1052 return _construct(Function, _toConsumableArray(keys).concat([code])).apply(void 0, _toConsumableArray(values));
1053 }
1054};
1055
1056export { JSONPath };