UNPKG

@stryke/json

Version:

A package containing JSON parsing/stringify utilities used by Storm Software.

67 lines (65 loc) 2.26 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); let _stryke_type_checks_is_set_object = require("@stryke/type-checks/is-set-object"); let _stryke_type_checks_is_string = require("@stryke/type-checks/is-string"); //#region src/pointer/find-reference.ts const { isArray } = Array; /** * Finds a target in document specified by JSON Pointer. Also returns the * object containing the target and key used to reference that object. * * Throws Error('NOT_FOUND') if pointer does not result into a value in the middle * of the path. If the last element of the path does not result into a value, the * lookup succeeds with `val` set to `undefined`. It can be used to discriminate * missing values, because `undefined` is not a valid JSON value. * * If last element in array is targeted using "-", e.g. "/arr/-", use * `isArrayEnd` to verify that: * * ```js * const ref = find({arr: [1, 2, 3], ['arr', '-']}); * if (isArrayReference(ref)) { * if (isArrayEnd(ref)) { * // ... * } * } * ``` * * @param val - Document to search in. * @param path - JSON Pointer path. * @returns Reference to the target. */ const find = (val, path) => { const pathLength = path.length; if (!pathLength) return { val }; let obj; let key; for (let i = 0; i < pathLength; i++) { obj = val; key = path[i]; if (isArray(obj)) { const length = obj.length; if (key === "-") key = length; else if ((0, _stryke_type_checks_is_string.isString)(key)) { const key2 = Math.trunc(Number.parseInt(key)); if (String(key2) !== key) throw new Error("INVALID_INDEX"); key = key2; if (key < 0) throw new Error("INVALID_INDEX"); } if (key) val = obj[key]; } else if ((0, _stryke_type_checks_is_set_object.isSetObject)(obj)) val = key && key in obj ? obj[key] : void 0; else throw new Error("NOT_FOUND"); } return { val, obj, key }; }; const isArrayReference = (ref) => isArray(ref.obj) && typeof ref.key === "number"; const isArrayEnd = (ref) => ref.obj.length === ref.key; const isObjectReference = (ref) => typeof ref.obj === "object" && typeof ref.key === "string"; //#endregion exports.find = find; exports.isArrayEnd = isArrayEnd; exports.isArrayReference = isArrayReference; exports.isObjectReference = isObjectReference;