export type DeepAssignArrayMode = 'merge' | 'shallowMerge' | 'concat' | 'overwrite'; export type DeepAssignOptions = { /** * Defines how array assignments should be handled. */ arrayMode?: DeepAssignArrayMode; }; /** * A function that makes a deep merge (and copy) of a list of objects and/or arrays. */ export type DeepAssignFn = (...targets: any[]) => any | any[]; /** * @module shared/deepAssign */ /** * @typedef {'merge' | 'shallowMerge' | 'concat' | 'overwrite'} DeepAssignArrayMode * @enum {string} * @parent module:shared/deepAssign */ /** * @typedef {Object} DeepAssignOptions * @property {DeepAssignArrayMode} [arrayMode='merge'] * Defines how array assignments should be handled. * @parent module:shared/deepAssign */ /** * A function that makes a deep merge (and copy) of a list of objects and/or arrays. * * @callback DeepAssignFn * @param {...*} targets The objects to merge; if one of them is not an object nor an * array, it will be ignored. * @returns {Object | Array} * @parent module:shared/deepAssign */ /** * It allows for deep merge (and copy) of objects and arrays using native spread syntax. * * This class exists just to scope the different functionalities and options needed for * {@link DeepAssign#assign} method to work. * * @parent module:shared/deepAssign */ export class DeepAssign { /** * @param {Partial} options Custom options for how * {@link DeepAssign#assign} * it's going to work. * @throws {Error} If `options.arrayMode` is not a valid {@link DeepAssignArrayMode}. */ constructor(options?: Partial); /** * The options that define how {@link DeepAssign#assign} works. * * @type {DeepAssignOptions} * @access protected * @ignore */ _options: DeepAssignOptions; /** * Makes a deep merge of a list of objects and/or arrays. * * @param {...*} targets The objects to merge; if one of them is not an object nor an * array, it will be ignored. * @returns {Object | Array} */ assign(...targets: any[]): any | any[]; /** * The options that define how {@link DeepAssign#assign} works. * * @type {Readonly} */ get options(): Readonly; /** * Checks if an object is a plain `Object` and not an instance of some class. * * @param {*} obj The object to validate. * @returns {boolean} * @access protected * @ignore */ _isPlainObject(obj: any): boolean; /** * Checks if an object can be used on a merge: only arrays and plain objects are * supported. * * @param {*} obj The object to validate. * @returns {boolean} * @access protected * @ignore */ _isValidItem(obj: any): boolean; /** * Merges two arrays into a new one. If the `concatArrays` option was set to `true` on * the constructor, the result will just be a concatenation with new references for the * items; but if the option was set to `false`, then the arrays will be merged over * their indexes. * * @param {Array} source The base array. * @param {Array} target The array that will be merged on top of * `source`. * @param {DeepAssignArrayMode} mode The assignment strategy. * @returns {Array} * @access protected * @ignore */ _mergeArrays(source: any[], target: any[], mode: DeepAssignArrayMode): any[]; /** * Merges two plain objects and their children. * * @param {Object} source The base object. * @param {Object} target The object which properties will be merged in top of * `source`. * @returns {Object} * @access protected * @ignore */ _mergeObjects(source: any, target: any): any; /** * This is the method the class calls when it has to merge two objects and it doesn't * know which types they are; the method takes care of validating compatibility and * calling either {@link DeepAssign#_mergeObjects} or {@link DeepAssign#_mergeArrays}. * If the objects are not compatible, or `source` is not defined, it will return a copy * of `target`. * * @param {*} source The base object. * @param {*} target The object that will be merged in top of * `source`. * @param {boolean} [ignoreArrayMode=false] Whether or not to ignore the option that * tells the class how array assignments * should be handled. This parameter exists * because, when called directly from * {@link DeepAssign#_assign}, it doesn't make * sense to use a strategy different than * 'merge'. * @returns {*} * @access protected * @ignore */ _resolve(source: any, target: any, ignoreArrayMode?: boolean): any; /** * This method is a helper for {@link DeepAssign#_resolve}, and it's used for when the * class has the `target` but not the `source`: depending on the type of the `target`, * it calls resolves with an empty object of the same type; if the `target` can't be * merged, it just returns it as it was received, which means that is a type that * doesn't hold references. * * @param {*} target The target to copy. * @param {boolean} [ignoreArrayMode=false] Whether or not to ignore the option that * tells the class how array assignments * should be handled. This parameter exists * because, when called directly from * {@link DeepAssign#_assign}, it doesn't make * sense to use a strategy different than * 'merge'. * @returns {*} * @access protected * @ignore */ _resolveFromEmpty(target: any, ignoreArrayMode?: boolean): any; } /** * Shortcut method for `new DeepAssign().assign(...)`. * * @type {DeepAssignFn} * @see {@link DeepAssign#assign} . */ export const deepAssign: DeepAssignFn; /** * Shortcut method for `new DeepAssign({ arrayMode: 'concat' }).assign(...)`. * * @type {DeepAssignFn} * @see {@link DeepAssign#assign} . */ export const deepAssignWithConcat: DeepAssignFn; /** * Shortcut method for `new DeepAssign({ arrayMode: 'overwrite' }).assign(...)`. * * @type {DeepAssignFn} * @see {@link DeepAssign#assign} . */ export const deepAssignWithOverwrite: DeepAssignFn; /** * Shortcut method for `new DeepAssign({ arrayMode: 'shallowMerge' }).assign(...)`. * * @type {DeepAssignFn} * @see {@link DeepAssign#assign} . */ export const deepAssignWithShallowMerge: DeepAssignFn;