UNPKG

@hn3000/json-ref

Version:

simple resolver for json reference and json pointer

255 lines 8.58 kB
"use strict"; 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