@hn3000/json-ref
Version:
simple resolver for json reference and json pointer
255 lines • 8.58 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonPointer = void 0;
function isSimpleObj(val) {
return ((null == val)
|| (val instanceof Date)
|| (val instanceof String)
|| (val instanceof RegExp));
}
function maybeArrayIndex(val) {
if ('-' == val)
return true;
var n = parseFloat(val);
return !(isNaN(n) || Math.floor(n) !== n);
}
var JsonPointer = /** @class */ (function () {
function JsonPointer(ref, extraUnquoted) {
if (typeof ref === 'string') {
this._keypath = (ref || "").split('/').slice(1).map(JsonPointer.unquote);
}
else if (Array.isArray(ref)) {
this._keypath = ref.slice();
}
else {
this._keypath = ref._keypath.slice();
}
if (null != extraUnquoted) {
this._keypath.push(extraUnquoted);
}
}
/**
* Returns a JsonPointer object from a string or JsonPointer.
* Used to allow clients to pass in either a string or a JsonPointer without having
* to deal with the difference.
*
* @param path string or JsonPointer
*/
JsonPointer.get = function (path) {
if (path instanceof JsonPointer) {
return path;
}
return new JsonPointer(path);
};
/**
* Collects all paths to objects deemed interesting by the predicated passed in.
*
* @param obj object to walk
* @param pred predicate to decide whether an object's path should be returned
*/
JsonPointer.paths = function (obj, pred) {
var result = [];
if (typeof pred === 'function') {
JsonPointer.walkObject(obj, function (v, p) { return (pred(v, p) && result.push(p.toString()), false); });
}
else {
JsonPointer.walkObject(obj, function (_, p) { return (result.push(p.toString()), false); });
}
return result;
};
/**
* Collects all pointers to objects deemed interesting by the predicated passed in.
*
* @param obj object to walk
* @param pred predicate to decide whether an object's path should be returned
*/
JsonPointer.pointers = function (obj, pred) {
var result = [];
if (typeof pred === 'function') {
JsonPointer.walkObject(obj, function (v, p) { return (pred(v, p) && result.push(p), false); });
}
else {
JsonPointer.walkObject(obj, function (_, p) { return (result.push(p), false); });
}
return result;
};
/**
* Walk obj and pass all values and their paths to the walker function.
*
* Stops descending into sub-objects if the walker returns true.
*/
JsonPointer.walkObject = function (obj, walker) {
var queue = [];
if (null != obj) {
queue.push({ val: obj, path: new JsonPointer('') });
}
while (0 != queue.length) {
var _a = queue.shift(), val = _a.val, path = _a.path;
var keys = Object.keys(val);
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var k = keys_1[_i];
var thisVal = val[k];
var thisPath = path.add(k);
var more = !walker(thisVal, thisPath);
var thisType = typeof (thisVal);
if ((thisType === 'object') && more && !isSimpleObj(thisVal)) {
//console.log(`descend into ${thisPath.asString()}`);
queue.push({ val: thisVal, path: thisPath });
}
}
}
};
JsonPointer.deref = function (p, obj) {
return new JsonPointer(p).getValue(obj);
};
JsonPointer.prototype.add = function (extraUnquoted) {
return new JsonPointer(this, extraUnquoted);
};
JsonPointer.prototype.hasParent = function () {
return this._keypath.length != 0;
};
Object.defineProperty(JsonPointer.prototype, "parent", {
get: function () {
var kp = this._keypath;
var len = kp.length;
if (len == 0) {
return null;
}
return new JsonPointer(kp.slice(0, len - 1));
},
enumerable: false,
configurable: true
});
JsonPointer.prototype.get = function (segment) {
var keypath = this._keypath;
return keypath[segment + (segment < 0 ? keypath.length : 0)];
};
JsonPointer.unquote = function (s) {
var result = s.replace(/~1/g, '/');
result = result.replace(/~0/g, '~');
return result;
};
JsonPointer.quote = function (s) {
var result = s.replace(/~/g, '~0');
result = result.replace(/\//g, '~1');
return result;
};
JsonPointer._deref = function (o, k) {
var isDash = k == '-';
if (isDash) {
var isArray = Array.isArray(o);
if (isArray) {
return o[o.length];
}
}
return o && o[k];
};
JsonPointer._set = function (o, k, v) {
var i = k;
if ((k === '-') && Array.isArray(o)) {
i = o.length;
}
o[i] = v;
};
JsonPointer.prototype.getValue = function (obj) {
return this._keypath.reduce(JsonPointer._deref, obj);
};
JsonPointer.prototype.setValue = function (obj, val, createPath) {
if (createPath === void 0) { createPath = false; }
return this._changeValue(obj, val, createPath, useMutable);
};
JsonPointer.prototype.withValue = function (obj, val, createPath) {
if (createPath === void 0) { createPath = false; }
return this._changeValue(obj, val, createPath, copyImmutable);
};
JsonPointer.prototype._changeValue = function (obj, val, createPath, makeMutable) {
var keys = this._keypath;
if (keys.length == 0) {
return val;
}
var start = makeMutable(obj || (maybeArrayIndex(keys[0]) ? [] : {}));
var tmp = start;
var i = 0;
for (var n = keys.length - 1; i < n; ++i) {
var k = keys[i];
var kval = JsonPointer._deref(tmp, k);
var ntmp = kval;
if (null == kval) {
if (createPath || null == obj) {
ntmp = maybeArrayIndex(keys[i + 1]) ? [] : {};
}
else {
tmp = null;
break;
}
}
else {
ntmp = makeMutable(kval);
}
if (null != ntmp && kval !== ntmp) {
JsonPointer._set(tmp, k, ntmp);
}
tmp = ntmp;
}
if (null != tmp) {
JsonPointer._set(tmp, keys[i], val);
}
return start;
};
JsonPointer.prototype.deleteValue = function (obj) {
var last = this.get(-1);
var parent = this.parent.getValue(obj);
if (null != parent) {
delete parent[last];
}
};
JsonPointer.prototype.asString = function () {
return [''].concat(this._keypath.map(JsonPointer.quote)).join('/');
};
JsonPointer.prototype.toString = function () {
return this.asString();
};
Object.defineProperty(JsonPointer.prototype, "keys", {
get: function () {
return this._keypath;
},
enumerable: false,
configurable: true
});
return JsonPointer;
}());
exports.JsonPointer = JsonPointer;
function copyImmutable(ntmp) {
var tmp;
if (Array.isArray(ntmp)) {
tmp = __spreadArray([], ntmp, true);
}
else {
tmp = __assign({}, ntmp);
}
return tmp;
}
function useMutable(ntmp) {
return ntmp;
}
//# sourceMappingURL=json-ptr.js.map