Skip to content

- Fix: wrap: false returning inconsistent data types #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions dist/index-es.js
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ JSONPath.prototype.evaluate = function (expr, json, callback, otherTypeCallback)
return wrap ? [] : undefined;
}

if (result.length === 1 && !wrap && !Array.isArray(result[0].value)) {
if (!wrap && result.length === 1 && !result[0].hasArrExpr) {
return this._getPreferredOutput(result[0]);
}

Expand Down Expand Up @@ -541,11 +541,12 @@ JSONPath.prototype._handleCallback = function (fullRetObj, callback, type) {
* @param {string} parentPropName
* @param {JSONPathCallback} callback
* @param {boolean} literalPriority
* @param {boolean} hasArrExpr
* @returns {ReturnObject|ReturnObject[]}
*/


JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, literalPriority) {
JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) {
// No expr to follow? return path and value as the result of
// this trace branch
var retObj;
Expand All @@ -556,7 +557,8 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
path: path,
value: val,
parent: parent,
parentProperty: parentPropName
parentProperty: parentPropName,
hasArrExpr: hasArrExpr
};

this._handleCallback(retObj, callback, 'value');
Expand Down Expand Up @@ -590,24 +592,24 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c

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));
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(that._trace(unshift(m, _x), v, p, par, pr, cb, true));
addRet(that._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));
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(that._trace(unshift(l, _x), v[m], push(p, m), v, m, cb));
addRet(that._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
Expand All @@ -634,7 +636,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
return retObj;
} else if (loc === '$') {
// root only
addRet(this._trace(x, val, path, null, null, callback));
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));
Expand All @@ -646,7 +648,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c

this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
if (that._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(that._trace(unshift(m, _x), v, p, par, pr, cb));
addRet(that._trace(unshift(m, _x), v, p, par, pr, cb, true));
}
});
} else if (loc[0] === '(') {
Expand All @@ -658,7 +660,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
// 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));
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;
Expand Down Expand Up @@ -750,7 +752,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c

} 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, true));
addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true));
} else if (loc.includes(',')) {
// [name1,name2,...]
var parts = loc.split(',');
Expand All @@ -761,7 +763,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
try {
for (var _iterator = parts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var part = _step.value;
addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback));
addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));
} // simple case--directly follow property

} catch (err) {
Expand All @@ -779,7 +781,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
}
}
} else if (!literalPriority && val && hasOwnProp.call(val, loc)) {
addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, true));
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
Expand All @@ -790,7 +792,7 @@ JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, c
var rett = ret[t];

if (rett.isParentSelector) {
var tmp = that._trace(rett.expr, val, rett.path, parent, parentPropName, callback);
var tmp = that._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);

if (Array.isArray(tmp)) {
ret[t] = tmp[0];
Expand Down Expand Up @@ -841,7 +843,7 @@ JSONPath.prototype._slice = function (loc, expr, val, path, parent, parentPropNa
var ret = [];

for (var i = start; i < end; i += step) {
var tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback);
var tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true);

if (Array.isArray(tmp)) {
// This was causing excessive stack size in Node (with or
Expand Down
2 changes: 1 addition & 1 deletion dist/index-es.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index-es.min.js.map

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions dist/index-umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@
return wrap ? [] : undefined;
}

if (result.length === 1 && !wrap && !Array.isArray(result[0].value)) {
if (!wrap && result.length === 1 && !result[0].hasArrExpr) {
return this._getPreferredOutput(result[0]);
}

Expand Down Expand Up @@ -547,11 +547,12 @@
* @param {string} parentPropName
* @param {JSONPathCallback} callback
* @param {boolean} literalPriority
* @param {boolean} hasArrExpr
* @returns {ReturnObject|ReturnObject[]}
*/


JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, literalPriority) {
JSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) {
// No expr to follow? return path and value as the result of
// this trace branch
var retObj;
Expand All @@ -562,7 +563,8 @@
path: path,
value: val,
parent: parent,
parentProperty: parentPropName
parentProperty: parentPropName,
hasArrExpr: hasArrExpr
};

this._handleCallback(retObj, callback, 'value');
Expand Down Expand Up @@ -596,24 +598,24 @@

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));
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(that._trace(unshift(m, _x), v, p, par, pr, cb, true));
addRet(that._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));
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(that._trace(unshift(l, _x), v[m], push(p, m), v, m, cb));
addRet(that._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
Expand All @@ -640,7 +642,7 @@
return retObj;
} else if (loc === '$') {
// root only
addRet(this._trace(x, val, path, null, null, callback));
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));
Expand All @@ -652,7 +654,7 @@

this._walk(loc, x, val, path, parent, parentPropName, callback, function (m, l, _x, v, p, par, pr, cb) {
if (that._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(that._trace(unshift(m, _x), v, p, par, pr, cb));
addRet(that._trace(unshift(m, _x), v, p, par, pr, cb, true));
}
});
} else if (loc[0] === '(') {
Expand All @@ -664,7 +666,7 @@
// 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));
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;
Expand Down Expand Up @@ -756,7 +758,7 @@

} 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, true));
addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true));
} else if (loc.includes(',')) {
// [name1,name2,...]
var parts = loc.split(',');
Expand All @@ -767,7 +769,7 @@
try {
for (var _iterator = parts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var part = _step.value;
addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback));
addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));
} // simple case--directly follow property

} catch (err) {
Expand All @@ -785,7 +787,7 @@
}
}
} else if (!literalPriority && val && hasOwnProp.call(val, loc)) {
addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, true));
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
Expand All @@ -796,7 +798,7 @@
var rett = ret[t];

if (rett.isParentSelector) {
var tmp = that._trace(rett.expr, val, rett.path, parent, parentPropName, callback);
var tmp = that._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);

if (Array.isArray(tmp)) {
ret[t] = tmp[0];
Expand Down Expand Up @@ -847,7 +849,7 @@
var ret = [];

for (var i = start; i < end; i += step) {
var tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback);
var tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true);

if (Array.isArray(tmp)) {
// This was causing excessive stack size in Node (with or
Expand Down
Loading