UNPKG

@stryke/json

Version:

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

81 lines (79 loc) 2.42 kB
import { isString } from "@stryke/type-checks/is-string"; import { isNumber } from "@stryke/type-checks/is-number"; //#region src/pointer/parse.ts const TILDE_ONE = /~1/g; const TILDE_ZERO = /~0/g; const TILDE = /~/g; const FORWARD_SLASH = /\//g; /** * Escapes a JSON pointer path segment. * * @param segment - JSON pointer path segment. * @returns Escaped JSON pointer path segment. */ function escapePointerSegment(segment) { if (!segment.includes("/") && !segment.includes("~")) return segment; return segment.replace(TILDE, "~0").replace(FORWARD_SLASH, "~1"); } /** * Unescapes a JSON pointer path segment. * * @param segment - JSON pointer path segment. * @returns Unescaped JSON pointer path segment. */ function unescapePointerSegment(segment) { if (!segment.includes("~")) return segment; return segment.replace(TILDE_ONE, "/").replace(TILDE_ZERO, "~"); } /** * Convert JSON pointer like "/foo/bar" to array like ["", "foo", "bar"], while * also un-escaping reserved characters. */ function parseJsonPointer(pointer) { if (!pointer) return []; return pointer.slice(1).split("/").map((segment) => unescapePointerSegment(segment)); } /** * Escape and format a path array like ["", "foo", "bar"] to JSON pointer * like "/foo/bar". */ function formatJsonPointer(path) { if (isRoot(path)) return ""; return `/${path.map((segment) => escapePointerSegment(String(segment))).join("/")}`; } /** * Returns true if JSON Pointer points to root value, false otherwise. */ const isRoot = (path) => isString(path) ? path === "" : isNumber(path) ? path === 0 : Array.isArray(path) && path.length === 0; /** * Returns parent path, e.g. for ['foo', 'bar', 'baz'] returns ['foo', 'bar']. */ function parent(path) { if (path.length === 0) throw new Error("NO_PARENT"); return path.slice(0, -1); } /** * Check if path component can be a valid array index. */ function isValidIndex(index) { if (isNumber(index)) return true; const n = Number.parseInt(index, 10); return String(n) === index && n >= 0; } const isInteger = (str) => { const len = str.length; let i = 0; let charCode; while (i < len) { charCode = str.codePointAt(i); if (charCode >= 48 && charCode <= 57) { i++; continue; } return false; } return true; }; //#endregion export { escapePointerSegment, formatJsonPointer, isInteger, isRoot, isValidIndex, parent, parseJsonPointer, unescapePointerSegment }; //# sourceMappingURL=parse.mjs.map