@croct/json-pointer
Version:
A RFC6901 compliant type-safe JSON pointer library to handle arbitrary structured data.
283 lines (282 loc) • 9.92 kB
TypeScript
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 {};