json-diff-ts
Version:
A JSON diff tool for JavaScript written in TypeScript.
122 lines (119 loc) • 6.13 kB
TypeScript
type FunctionKey = (obj: any, shouldReturnKeyName?: boolean) => any;
type EmbeddedObjKeysType = Record<string, string | FunctionKey>;
type EmbeddedObjKeysMapType = Map<string | RegExp, string | FunctionKey>;
declare enum Operation {
REMOVE = "REMOVE",
ADD = "ADD",
UPDATE = "UPDATE"
}
interface IChange {
type: Operation;
key: string;
embeddedKey?: string | FunctionKey;
value?: any;
oldValue?: any;
changes?: IChange[];
}
type Changeset = IChange[];
interface IAtomicChange {
type: Operation;
key: string;
path: string;
valueType: string | null;
value?: any;
oldValue?: any;
}
interface Options {
embeddedObjKeys?: EmbeddedObjKeysType | EmbeddedObjKeysMapType;
keysToSkip?: string[];
treatTypeChangeAsReplace?: boolean;
}
/**
* Computes the difference between two objects.
*
* @param {any} oldObj - The original object.
* @param {any} newObj - The updated object.
* @param {Options} options - An optional parameter specifying keys of embedded objects and keys to skip.
* @returns {IChange[]} - An array of changes that transform the old object into the new object.
*/
declare function diff(oldObj: any, newObj: any, options?: Options): IChange[];
/**
* Applies all changes in the changeset to the object.
*
* @param {any} obj - The object to apply changes to.
* @param {Changeset} changeset - The changeset to apply.
* @returns {any} - The object after the changes from the changeset have been applied.
*
* The function first checks if a changeset is provided. If so, it iterates over each change in the changeset.
* If the change value is not null or undefined, or if the change type is REMOVE, or if the value is null and the type is ADD,
* it applies the change to the object directly.
* Otherwise, it applies the change to the corresponding branch of the object.
*/
declare const applyChangeset: (obj: any, changeset: Changeset) => any;
/**
* Reverts the changes made to an object based on a given changeset.
*
* @param {any} obj - The object on which to revert changes.
* @param {Changeset} changeset - The changeset to revert.
* @returns {any} - The object after the changes from the changeset have been reverted.
*
* The function first checks if a changeset is provided. If so, it reverses the changeset to start reverting from the last change.
* It then iterates over each change in the changeset. If the change does not have any nested changes, or if the value is null and
* the type is REMOVE (which would be reverting an ADD operation), it reverts the change on the object directly.
* If the change does have nested changes, it reverts the changes on the corresponding branch of the object.
*/
declare const revertChangeset: (obj: any, changeset: Changeset) => any;
/**
* Atomize a changeset into an array of single changes.
*
* @param {Changeset | IChange} obj - The changeset or change to flatten.
* @param {string} [path='$'] - The current path in the changeset.
* @param {string | FunctionKey} [embeddedKey] - The key to use for embedded objects.
* @returns {IAtomicChange[]} - An array of atomic changes.
*
* The function first checks if the input is an array. If so, it recursively atomize each change in the array.
* If the input is not an array, it checks if the change has nested changes or an embedded key.
* If so, it updates the path and recursively flattens the nested changes or the embedded object.
* If the change does not have nested changes or an embedded key, it creates a atomic change and returns it in an array.
*/
declare const atomizeChangeset: (obj: Changeset | IChange, path?: string, embeddedKey?: string | FunctionKey) => IAtomicChange[];
/**
* Transforms an atomized changeset into a nested changeset.
*
* @param {IAtomicChange | IAtomicChange[]} changes - The atomic changeset to unflatten.
* @returns {IChange[]} - The unflattened changeset.
*
* The function first checks if the input is a single change or an array of changes.
* It then iterates over each change and splits its path into segments.
* For each segment, it checks if it represents an array or a leaf node.
* If it represents an array, it creates a new change object and updates the pointer to this new object.
* If it represents a leaf node, it sets the key, type, value, and oldValue of the current change object.
* Finally, it pushes the unflattened change object into the changes array.
*/
declare const unatomizeChangeset: (changes: IAtomicChange | IAtomicChange[]) => IChange[];
/**
* Determines the type of a given object.
*
* @param {any} obj - The object whose type is to be determined.
* @returns {string | null} - The type of the object, or null if the object is null.
*
* This function first checks if the object is undefined or null, and returns 'undefined' or null respectively.
* If the object is neither undefined nor null, it uses Object.prototype.toString to get the object's type.
* The type is extracted from the string returned by Object.prototype.toString using a regular expression.
*/
declare const getTypeOfObj: (obj: any) => string;
declare enum CompareOperation {
CONTAINER = "CONTAINER",
UNCHANGED = "UNCHANGED"
}
interface IComparisonEnrichedNode {
type: Operation | CompareOperation;
value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];
oldValue?: any;
}
declare const createValue: (value: any) => IComparisonEnrichedNode;
declare const createContainer: (value: object | []) => IComparisonEnrichedNode;
declare const enrich: (object: any) => IComparisonEnrichedNode;
declare const applyChangelist: (object: IComparisonEnrichedNode, changelist: IAtomicChange[]) => IComparisonEnrichedNode;
declare const compare: (oldObject: any, newObject: any) => IComparisonEnrichedNode;
export { type Changeset, CompareOperation, type EmbeddedObjKeysMapType, type EmbeddedObjKeysType, type IAtomicChange, type IChange, type IComparisonEnrichedNode, Operation, type Options, applyChangelist, applyChangeset, atomizeChangeset, compare, createContainer, createValue, diff, enrich, getTypeOfObj, revertChangeset, unatomizeChangeset };