UNPKG

@croct/json-pointer

Version:

A RFC6901 compliant type-safe JSON pointer library to handle arbitrary structured data.

283 lines (282 loc) 9.92 kB
import { JsonConvertible } from '@croct/json'; /** * A value that can be converted to a JSON pointer. */ export type JsonPointerLike = JsonPointer | number | string | JsonPointerSegments; /** * A JSON pointer segment. */ export type JsonPointerSegment = string | number; /** * A list of JSON pointer segments. */ export type JsonPointerSegments = JsonPointerSegment[]; /** * A record or array representing the root of a structure. */ export type RootStructure = Record<string | number | symbol, any> | any[]; export type RootValue = any; /** * A union of all possible values in a structure. */ export type ReferencedValue<T> = NestedValue<T>; /** * A union of all possible values in a structure, excluding the given type. */ type NestedValue<T, U = never> = T | (T extends object ? T extends U ? NestedValue<Diff<T, U>, U> : T extends Array<infer I> ? NestedValue<I, U | T> : NestedValue<T[keyof T], U | T> : never); type Diff<T extends object, M> = M extends infer U ? T extends U ? Exclude<keyof T, keyof U> extends never ? never : Pick<T, Exclude<keyof T, keyof U>> : never : never; /** * An error indicating a problem related to JSON pointer operations. */ export declare class JsonPointerError extends Error { constructor(message: string); } /** * An error indicating a problem related to malformed JSON pointers. */ export declare class InvalidSyntaxError extends JsonPointerError { constructor(message: string); } /** * An error indicating an invalid reference for a given structure. */ export declare class InvalidReferenceError extends JsonPointerError { constructor(message: string); } /** * A key-value pair representing a JSON pointer segment and its value. */ export type Entry<T> = [JsonPointerSegment | null, T]; /** * An RFC 6901-compliant JSON pointer. * * @see https://tools.ietf.org/html/rfc6901 */ export declare class JsonPointer implements JsonConvertible { /** * A singleton representing the root pointer. */ private static readonly ROOT_SINGLETON; /** * The list of segments that form the pointer. */ private readonly segments; /** * Initializes a new pointer from a list of segments. * * @param segments A list of segments. */ private constructor(); /** * Returns a pointer referencing the root of the JSON object. * * Root pointers cannot be used to modify values. * * @returns A pointer referencing the root of the JSON object. */ static root(): JsonPointer; /** * Creates a pointer from any valid pointer-like value. * * The return is as follows: * * - Pointers are returned as given * - Numbers are used as single segments * - Arrays are assumed to be unescaped segments * - Strings are delegated to `JsonPointer.parse` and the result is returned * * @param path A pointer-like value. * * @returns The normalized pointer for the given value. * * @see JsonPointer.parse */ static from(path: JsonPointerLike): JsonPointer; /** * Creates a pointer from a list of unescaped segments. * * Numeric segments must be safe non-negative integers. * * @param {JsonPointerSegments} segments A list of unescaped segments. * * @returns {JsonPointer} The pointer to the value at the path specified by the segments. * * @throws {InvalidSyntaxError} If the segments are not valid. */ private static fromSegments; /** * Parses a string into a pointer. The string is split on the dot character and * segments composed solely of numbers are parsed as integers. * * @param {string} path The string representation of a pointer. * * @returns {JsonPointer} The pointer to the value at the specified path. * * @throws {InvalidSyntaxError} If the path is not a valid JSON Pointer. */ static parse(path: string): JsonPointer; /** * Checks whether the pointer references an array element. * * @returns {boolean} Whether the pointer references an array index. */ isIndex(): boolean; /** * Returns the depth of the pointer. * * The depth of a pointer is the number nesting from the root it contains. * * @example * // returns 2 * JsonPointer.from('/foo/bar').depth() * * @returns {number} The depth of the pointer. */ getDepth(): number; /** * Returns if the pointer is the root pointer. * * @returns {boolean} */ isRoot(): boolean; /** * Returns a pointer to the parent of the current pointer. * * @returns {JsonPointer} The parent pointer. */ getParent(): JsonPointer; /** * Returns the segments of the pointer. * * @returns {JsonPointerSegments} The segments of the pointer. */ getSegments(): JsonPointerSegments; /** * Returns a pointer truncated to the given depth. * * @param depth The depth of the pointer, where 0 represents the root */ truncatedAt(depth: number): JsonPointer; /** * Joins this pointer with another one and returns the result. * * The segments of the second pointer are appended to the segments of the first. * * These are equivalent: * * ```js * JsonPointer.from(['foo', 'bar']).joinedWith(JsonPointer.from(['baz'])) * JsonPointer.from(['foo', 'bar', 'baz']) * ``` * * @param {JsonPointer} other The pointer to append to this one. * * @returns {JsonPointer} A pointer with the segments of this and the other pointer joined. */ joinedWith(other: JsonPointerLike): JsonPointer; /** * Returns the value at the referenced location. * * @param {RootValue} value The value to read from. * * @returns {ReferencedValue} The value at the referenced location. * * @throws {InvalidReferenceError} If a numeric segment references a non-array value. * @throws {InvalidReferenceError} If a string segment references an array value. * @throws {InvalidReferenceError} If there is no value at any level of the pointer. */ get<T extends RootValue>(value: T): ReferencedValue<T>; /** * Checks whether the value at the referenced location exists. * * This method gracefully handles missing values by returning `false`. * * @param {RootValue} root The value to check if the reference exists in. * * @returns {boolean} Returns `true` if the value exists, `false` otherwise. */ has(root: RootValue): boolean; /** * Sets the value at the referenced location. * * @param {RootValue} root The value to write to. * @param {unknown} value The value to set at the referenced location. * * @throws {InvalidReferenceError} If the pointer references the root of the structure. * @throws {InvalidReferenceError} If a numeric segment references a non-array value. * @throws {InvalidReferenceError} If a string segment references an array value. * @throws {InvalidReferenceError} If there is no value at any level of the pointer. * @throws {InvalidReferenceError} If setting the value to an array would cause it to become * sparse. */ set<T extends RootValue>(root: T, value: unknown): void; /** * Unsets the value at the referenced location and returns the unset value. * * If the given location does not exist, the method returns `undefined`, meaning the call * is a no-op. Pointers referencing array elements remove the element while keeping * the array dense. * * @param {RootValue} root The value to write to. * * @returns {ReferencedValue|undefined} The unset value, or `undefined` if the referenced location * does not exist. * * @throws {InvalidReferenceError} If the pointer references the root of the root. */ unset<T extends RootValue>(root: T): ReferencedValue<T> | undefined; /** * Returns an iterator over the stack of values that the pointer references. * * @param {RootValue} root The value to traverse. * * @returns {Iterator<Entry<ReferencedValue<T>>} An iterator over the stack of values that the * pointer references. * * @throws {InvalidReferenceError} If a numeric segment references a non-array value. * @throws {InvalidReferenceError} If a string segment references an array value. * @throws {InvalidReferenceError} If there is no value at any level of the pointer. */ traverse<T extends RootValue>(root: T): Iterator<Entry<ReferencedValue<T>>>; /** * Checks whether the pointer is logically equivalent to another pointer. * * @param {any} other The pointer to check for equality. * * @returns {boolean} `true` if the pointers are logically equal, `false` otherwise. */ equals(other: unknown): other is JsonPointer; /** * Returns the string representation of the pointer. * * @returns {string} The string representation of the pointer */ toJSON(): string; /** * Returns the string representation of the pointer. * * @returns {string} The string representation of the pointer */ toString(): string; /** * Normalizes a pointer segments. * * @param segment The segment to normalize. * * @returns {string} The normalized segment. */ private static normalizeSegment; /** * Converts a segment to its normalized form. * * @param segment The escaped segment to convert into its normalized form. */ private static unescapeSegment; /** * Converts a segment to its normalized form. * * @param segment The escaped segment to convert into its normalized form. */ private static escapeSegment; } export {};