@stryke/json
Version:
A package containing JSON parsing/stringify utilities used by Storm Software.
81 lines (79 loc) • 2.42 kB
JavaScript
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