@astronautlabs/jsonpath
Version:
Query JavaScript objects with JSONPath expressions. Robust / safe JSONPath engine for Node.js.
286 lines • 11.4 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Handlers = void 0;
var aesprim = __importStar(require("./esprima"));
var slice_1 = require("./slice");
var _1 = require(".");
var static_eval_1 = __importDefault(require("static-eval"));
/**
* @internal
* @hidden
*/
function traverser(recurse) {
return function (partial, ref, passable, count) {
var value = partial.value;
var path = partial.path;
var results = [];
var descend = function (value, path) {
if (is_array(value)) {
value.forEach(function (element, index) {
if (results.length >= count) {
return;
}
if (passable(index, element, ref)) {
results.push({ path: path.concat(index), value: element });
}
});
value.forEach(function (element, index) {
if (results.length >= count) {
return;
}
if (recurse) {
descend(element, path.concat(index));
}
});
}
else if (is_object(value)) {
Object.keys(value).forEach(function (k) {
if (results.length >= count) {
return;
}
if (passable(k, value[k], ref)) {
results.push({ path: path.concat(k), value: value[k] });
}
});
Object.keys(value).forEach(function (k) {
if (results.length >= count) {
return;
}
if (recurse) {
descend(value[k], path.concat(k));
}
});
}
}.bind(this);
descend(value, path);
return results;
};
}
/**
* @internal
* @hidden
*/
function evaluate(ast, vars) {
try {
return (0, static_eval_1.default)(ast, vars);
}
catch (e) {
}
}
/**
* @internal
* @hidden
*/
function _descend(passable) {
return function (component, partial, count) {
return this.descend(partial, component.expression.value, passable, count);
};
}
/**
* @internal
* @hidden
*/
function _traverse(passable) {
return function (component, partial, count) {
return this.traverse(partial, component.expression.value, passable, count);
};
}
/**
* @internal
* @hidden
*/
function unique(results) {
results = results.filter(function (d) { return d; });
return uniq(results, function (r) { return r.path.map(function (c) { return String(c).replace('-', '--'); }).join('-'); });
}
/**
* @internal
* @hidden
*/
function _parse_nullable_int(val) {
var sval = String(val);
return sval.match(/^-?[0-9]+$/) ? parseInt(sval) : null;
}
/**
* @internal
* @hidden
*/
function is_array(val) {
return Array.isArray(val);
}
/**
* @internal
* @hidden
*/
function is_object(val) {
// is this a non-array, non-null object?
return val && !(val instanceof Array) && val instanceof Object;
}
/**
* @internal
* @hidden
*/
function eval_recurse(partial, src, template) {
var ast = aesprim.parse(src).body[0].expression;
var value = evaluate(ast, { '@': partial.value });
var path = template.replace(/\{\{\s*value\s*\}\}/g, value);
var results = _1.JSONPath.nodes(partial.value, path);
results.forEach(function (r) {
r.path = partial.path.concat(r.path.slice(1));
});
return results;
}
/**
* @internal
* @hidden
*/
var Handlers = /** @class */ (function () {
function Handlers() {
this._fns = {
'member-child-identifier': function (component, partial) {
var key = component.expression.value;
var value = partial.value;
if (value instanceof Object && key in value) {
return [{ value: value[key], path: partial.path.concat(key) }];
}
},
'member-descendant-identifier': _traverse(function (key, value, ref) { return key == ref; }),
'subscript-child-numeric_literal': _descend(function (key, value, ref) { return key === ref; }),
'member-child-numeric_literal': _descend(function (key, value, ref) { return String(key) === String(ref); }),
'subscript-descendant-numeric_literal': _traverse(function (key, value, ref) { return key === ref; }),
'member-child-wildcard': _descend(function () { return true; }),
'member-descendant-wildcard': _traverse(function () { return true; }),
'subscript-descendant-wildcard': _traverse(function () { return true; }),
'subscript-child-wildcard': _descend(function () { return true; }),
'subscript-child-slice': function (component, partial) {
if (is_array(partial.value)) {
var args = component.expression.value.split(':').map(_parse_nullable_int);
var values = partial.value.map(function (v, i) { return { value: v, path: partial.path.concat(i) }; });
return slice_1.slice.apply(null, [values].concat(args));
}
},
'subscript-child-union': function (component, partial) {
var results = [];
component.expression.value.forEach(function (component) {
var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
var handler = this.resolve(_component);
var _results = handler(_component, partial);
if (_results) {
results = results.concat(_results);
}
}, this);
return unique(results);
},
'subscript-descendant-union': function (component, partial, count) {
var self = this;
var results = [];
var nodes = _1.JSONPath.nodes(partial, '$..*').slice(1);
nodes.forEach(function (node) {
if (results.length >= count)
return;
component.expression.value.forEach(function (component) {
var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
var handler = self.resolve(_component);
var _results = handler(_component, node);
results = results.concat(_results);
});
});
return unique(results);
},
'subscript-child-filter_expression': function (component, partial, count) {
// slice out the expression from ?(expression)
var src = component.expression.value.slice(2, -1);
var ast = aesprim.parse(src).body[0].expression;
var passable = function (key, value) {
return evaluate(ast, { '@': value });
};
return this.descend(partial, null, passable, count);
},
'subscript-descendant-filter_expression': function (component, partial, count) {
// slice out the expression from ?(expression)
var src = component.expression.value.slice(2, -1);
var ast = aesprim.parse(src).body[0].expression;
var passable = function (key, value) {
return evaluate(ast, { '@': value });
};
return this.traverse(partial, null, passable, count);
},
'subscript-child-script_expression': function (component, partial) {
var exp = component.expression.value.slice(1, -1);
return eval_recurse(partial, exp, '$[{{value}}]');
},
'member-child-script_expression': function (component, partial) {
var exp = component.expression.value.slice(1, -1);
return eval_recurse(partial, exp, '$.{{value}}');
},
'member-descendant-script_expression': function (component, partial) {
var exp = component.expression.value.slice(1, -1);
return eval_recurse(partial, exp, '$..value');
}
};
this.initialize();
}
Handlers.prototype.initialize = function () {
this.traverse = traverser(true);
this.descend = traverser();
this._fns['subscript-child-string_literal'] =
this._fns['member-child-identifier'];
this._fns['member-descendant-numeric_literal'] =
this._fns['subscript-descendant-string_literal'] =
this._fns['member-descendant-identifier'];
};
Handlers.prototype.resolve = function (component) {
var key = [component.operation, component.scope, component.expression.type].join('-');
var method = this._fns[key];
if (!method)
throw new Error("couldn't resolve key: " + key);
return method.bind(this);
};
Handlers.prototype.register = function (key, handler) {
if (!(handler instanceof Function)) {
throw new Error("handler must be a function");
}
this._fns[key] = handler;
};
return Handlers;
}());
exports.Handlers = Handlers;
function uniq(array, iteratee) {
var result = [];
var seen = [];
for (var i = 0, length = array === null || array === void 0 ? void 0 : array.length; i < length; i++) {
var value = array[i], computed = iteratee ? iteratee(value, i) : value;
if (!seen.includes(computed)) {
seen.push(computed);
result.push(value);
}
}
return result;
}
//# sourceMappingURL=handlers.js.map
;