UNPKG

@aedart/support

Version:

The Ion support package

684 lines (660 loc) 28.2 kB
/** * @aedart/support * * BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>. */ import * as lodash from 'lodash'; import { Key } from '@aedart/contracts/support'; import { ObjectsMerger, SourceKeysCallback, MergeException, MergeOptions, SkipKeyCallback, MergeCallback, NextCallback, Cloneable } from '@aedart/contracts/support/objects'; import { ArrayMergeOptions } from '@aedart/contracts/support/arrays'; /** * Remove value in object at given path * (Alias for Lodash' [unset]{@link import('lodash').unset}) method * * @type {(object: any, path: import('@aedart/contracts/support').Key) => boolean} */ declare const forget: (object: any, path: lodash.PropertyPath) => boolean; /** * Remove all values in object that match given paths * * @template T * * @param {T} object Target object * @param {...Key} paths Property path(s) */ declare function forgetAll<T>(object: T, ...paths: (Key)[]): void; /** * @typedef {import('lodash').PropertyPath} PropertyPath * @typedef {import('lodash').NumericDictionary} NumericDictionary * @typedef {import('lodash').GetFieldType} GetFieldType */ /** * Get value from object that matches given path * (Alias for Lodash' [get]{@link import('lodash').get}) method * * @type {{<TObject extends object, TKey extends keyof TObject>(object: TObject, path: ([TKey] | TKey)): TObject[TKey], <TObject extends object, TKey extends keyof TObject>(object: (TObject | null | undefined), path: ([TKey] | TKey)): (TObject[TKey] | undefined), <TObject extends object, TKey extends keyof TObject, TDefault>(object: (TObject | null | undefined), path: ([TKey] | TKey), defaultValue: TDefault): (Exclude<TObject[TKey], undefined> | TDefault), <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1]>(object: TObject, path: [TKey1, TKey2]): TObject[TKey1][TKey2], <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1]>(object: (TObject | null | undefined), path: [TKey1, TKey2]): (TObject[TKey1][TKey2] | undefined), <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TDefault>(object: (TObject | null | undefined), path: [TKey1, TKey2], defaultValue: TDefault): (Exclude<TObject[TKey1][TKey2], undefined> | TDefault), <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2]>(object: TObject, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3], <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2]>(object: (TObject | null | undefined), path: [TKey1, TKey2, TKey3]): (TObject[TKey1][TKey2][TKey3] | undefined), <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2], TDefault>(object: (TObject | null | undefined), path: [TKey1, TKey2, TKey3], defaultValue: TDefault): (Exclude<TObject[TKey1][TKey2][TKey3], undefined> | TDefault), <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2], TKey4 extends keyof TObject[TKey1][TKey2][TKey3]>(object: TObject, path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4], <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2], TKey4 extends keyof TObject[TKey1][TKey2][TKey3]>(object: (TObject | null | undefined), path: [TKey1, TKey2, TKey3, TKey4]): (TObject[TKey1][TKey2][TKey3][TKey4] | undefined), <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2], TKey4 extends keyof TObject[TKey1][TKey2][TKey3], TDefault>(object: (TObject | null | undefined), path: [TKey1, TKey2, TKey3, TKey4], defaultValue: TDefault): (Exclude<TObject[TKey1][TKey2][TKey3][TKey4], undefined> | TDefault), <T>(object: NumericDictionary<T>, path: number): T, <T>(object: (NumericDictionary<T> | null | undefined), path: number): (T | undefined), <T, TDefault>(object: (NumericDictionary<T> | null | undefined), path: number, defaultValue: TDefault): (T | TDefault), <TDefault>(object: (null | undefined), path: PropertyPath, defaultValue: TDefault): TDefault, (object: (null | undefined), path: PropertyPath): undefined, <TObject, TPath extends string>(data: TObject, path: TPath): string extends TPath ? any : GetFieldType<TObject, TPath>, <TObject, TPath extends string, TDefault=GetFieldType<TObject, TPath>>(data: TObject, path: TPath, defaultValue: TDefault): (Exclude<GetFieldType<TObject, TPath>, null | undefined> | TDefault), (object: any, path: PropertyPath, defaultValue?: any): any}} */ declare const get: { <TObject extends object, TKey extends keyof TObject>(object: TObject, path: TKey | [TKey]): TObject[TKey]; <TObject extends object, TKey extends keyof TObject>(object: TObject | null | undefined, path: TKey | [TKey]): TObject[TKey] | undefined; <TObject extends object, TKey extends keyof TObject, TDefault>(object: TObject | null | undefined, path: TKey | [TKey], defaultValue: TDefault): Exclude<TObject[TKey], undefined> | TDefault; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1]>(object: TObject, path: [TKey1, TKey2]): TObject[TKey1][TKey2]; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof NonNullable<TObject[TKey1]>>(object: TObject | null | undefined, path: [TKey1, TKey2]): NonNullable<TObject[TKey1]>[TKey2] | undefined; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof NonNullable<TObject[TKey1]>, TDefault>(object: TObject | null | undefined, path: [TKey1, TKey2], defaultValue: TDefault): Exclude<NonNullable<TObject[TKey1]>[TKey2], undefined> | TDefault; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2]>(object: TObject, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof NonNullable<TObject[TKey1]>, TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>>(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3]): NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3] | undefined; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof NonNullable<TObject[TKey1]>, TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>, TDefault>(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3], defaultValue: TDefault): Exclude<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3], undefined> | TDefault; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2], TKey4 extends keyof TObject[TKey1][TKey2][TKey3]>(object: TObject, path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof NonNullable<TObject[TKey1]>, TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>, TKey4 extends keyof NonNullable<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]>>(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3, TKey4]): NonNullable<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]>[TKey4] | undefined; <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof NonNullable<TObject[TKey1]>, TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>, TKey4 extends keyof NonNullable<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]>, TDefault>(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3, TKey4], defaultValue: TDefault): Exclude<NonNullable<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]>[TKey4], undefined> | TDefault; <T>(object: lodash.NumericDictionary<T>, path: number): T; <T>(object: lodash.NumericDictionary<T> | null | undefined, path: number): T | undefined; <T, TDefault>(object: lodash.NumericDictionary<T> | null | undefined, path: number, defaultValue: TDefault): T | TDefault; <TDefault>(object: null | undefined, path: lodash.PropertyPath, defaultValue: TDefault): TDefault; (object: null | undefined, path: lodash.PropertyPath): undefined; <TObject, TPath extends string>(data: TObject, path: TPath): string extends TPath ? any : lodash.GetFieldType<TObject, TPath>; <TObject, TPath extends string, TDefault = lodash.GetFieldType<TObject, TPath, "Path">>(data: TObject, path: TPath, defaultValue: TDefault): Exclude<lodash.GetFieldType<TObject, TPath>, null | undefined> | TDefault; (object: any, path: lodash.PropertyPath, defaultValue?: any): any; }; /** * Determine if path is a property of given object * * (Alias for Lodash' [hasIn]{@link import('lodash').hasIn}) method * * @type {<T>(object: T, path: import('@aedart/contracts/support').Key) => boolean} */ declare const has: <T>(object: T, path: lodash.PropertyPath) => boolean; /** * Determine if all paths are properties of given object * @template T * * @param {T} object Target object * @param {...Key} paths Property path(s) * * @returns {boolean} */ declare function hasAll<T>(object: T, ...paths: (Key)[]): boolean; /** * Determine if any paths are properties of given object * @template T * * @param {T} object Target object * @param {...Key} paths Property path(s) * * @returns {boolean} */ declare function hasAny<T>(object: T, ...paths: (Key)[]): boolean; /** * Object ID * * Utility that is able to return a numeric ID for objects. * * Source is heavily inspired by Nicolas Gehlert's blog post: * "Get object reference IDs in JavaScript/TypeScript" (September 28, 2022) * @see https://developapa.com/object-ids/ * @see https://github.com/ngehlert/developapa/blob/master/content/blog/object-ids/index.md */ declare class ObjectId { /** * Internal counter * * @type {number} * * @protected * @static */ protected static _count: number; /** * Weak Map of objects and their associated id * * @type {WeakMap<object, number>} * * @protected * @readonly */ protected static _map: WeakMap<object, number>; /** * Returns a unique ID for target object. * * If no ID exists for the given object, then a new ID is * generated and returned. Subsequent calls to this method using * the same object will return the same ID. * * @param {object} target * @returns {number} */ static get(target: object): number; /** * Determine if a unique ID exists for target object * * @param {object} target * * @returns {boolean} */ static has(target: object): boolean; } /** * Alias for {@link ObjectId.has} */ declare const hasUniqueId: typeof ObjectId.has; /** * Determine if target object is cloneable. * * **Note**: _Method assumes that target is cloneable if it implements the * [Cloneable]{@link import('@aedart/constracts/support/objects').Cloneable} interface._ * * @param {object} target * * @return {boolean} */ declare function isCloneable(target: object): boolean; /** * Determine if target is populatable * * **Note**: _Method assumes that target is populatable if it implements the * [Populatable]{@link import('@aedart/constracts/support/objects').Populatable} interface._ * * @param {object} target * * @return {boolean} */ declare function isPopulatable(target: object): boolean; /** * Determine if properties at given paths are declared, and their values are not undefined or null * * @template T * * @param {T} object * @param {...Key} paths * * @returns {boolean} */ declare function isset<T>(object: T, ...paths: (Key)[]): boolean; /** * Returns a new Object Merger instance * * @return {ObjectsMerger} */ declare function merge(): ObjectsMerger; /** * Returns a merger of given source objects * * **Note**: _This method is responsible for returning [deep copy]{@link https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy} * of all given sources._ * * @template SourceA extends object * * @param {SourceA} a * * @returns {SourceA} * * @throws {MergeError} */ declare function merge<SourceA extends object>(a: SourceA): SourceA; /** * Returns a merger of given source objects * * **Note**: _This method is responsible for returning [deep copy]{@link https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy} * of all given sources._ * * @template SourceA extends object * @template SourceB extends object * * @param {SourceA} a * @param {SourceB} b * * @returns {SourceA & SourceB} * * @throws {MergeError} */ declare function merge<SourceA extends object, SourceB extends object>(a: SourceA, b: SourceB): SourceA & SourceB; /** * Returns a merger of given source objects * * **Note**: _This method is responsible for returning [deep copy]{@link https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy} * of all given sources._ * * @template SourceA extends object * @template SourceB extends object * @template SourceC extends object * * @param {SourceA} a * @param {SourceB} b * @param {SourceC} c * * @returns {SourceA & SourceB & SourceC} * * @throws {MergeError} */ declare function merge<SourceA extends object, SourceB extends object, SourceC extends object>(a: SourceA, b: SourceB, c: SourceC): SourceA & SourceB & SourceC; /** * Returns a merger of given source objects * * **Note**: _This method is responsible for returning [deep copy]{@link https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy} * of all given sources._ * * @template SourceA extends object * @template SourceB extends object * @template SourceC extends object * @template SourceD extends object * * @param {SourceA} a * @param {SourceB} b * @param {SourceC} c * @param {SourceD} d * * @returns {SourceA & SourceB & SourceC & SourceD} * * @throws {MergeError} */ declare function merge<SourceA extends object, SourceB extends object, SourceC extends object, SourceD extends object>(a: SourceA, b: SourceB, c: SourceC, d: SourceD): SourceA & SourceB & SourceC & SourceD; /** * Returns a merger of given source objects * * **Note**: _This method is responsible for returning [deep copy]{@link https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy} * of all given sources._ * * @template SourceA extends object * @template SourceB extends object * @template SourceC extends object * @template SourceD extends object * @template SourceE extends object * * @param {SourceA} a * @param {SourceB} b * @param {SourceC} c * @param {SourceD} d * @param {SourceE} e * * @returns {SourceA & SourceB & SourceC & SourceD & SourceE} * * @throws {MergeError} */ declare function merge<SourceA extends object, SourceB extends object, SourceC extends object, SourceD extends object, SourceE extends object>(a: SourceA, b: SourceB, c: SourceC, d: SourceD, e: SourceE): SourceA & SourceB & SourceC & SourceD & SourceE; /** * Returns a merger of given source objects * * **Note**: _This method is responsible for returning [deep copy]{@link https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy} * of all given sources._ * * @template SourceA extends object * @template SourceB extends object * @template SourceC extends object * @template SourceD extends object * @template SourceE extends object * @template SourceF extends object * * @param {SourceA} a * @param {SourceB} b * @param {SourceC} c * @param {SourceD} d * @param {SourceE} e * @param {SourceF} f * * @returns {SourceA & SourceB & SourceC & SourceD & SourceE & SourceF} * * @throws {MergeError} */ declare function merge<SourceA extends object, SourceB extends object, SourceC extends object, SourceD extends object, SourceE extends object, SourceF extends object>(a: SourceA, b: SourceB, c: SourceC, d: SourceD, e: SourceE, f: SourceF): SourceA & SourceB & SourceC & SourceD & SourceE & SourceF; /** * Populate target object with the properties from source object * * **Warning**: _This method performs a shallow copy of properties in source object!_ * * **Warning**: _`target` object is mutated!_ * * **Note**: _Properties that are [unsafe]{@link import('@aedart/support/reflections').isKeyUnsafe} are always disregarded!_ * * @template TargetObj extends object = object * @template SourceObj extends object = object * * @param {object} target * @param {object} source * @param {PropertyKey | PropertyKey[] | SourceKeysCallback} [keys='*'] Keys to select and copy from `source` object. * If wildcard (`*`) given, then all properties from the `source` * are selected. If a callback is given, then that callback must return * key or keys to select from `source`. * @param {boolean} [safe=true] When `true`, properties must exist in target (_must be defined in target_), * before they are shallow copied. * * @returns {object} The populated target * * @throws {TypeError} If a key does not exist in `target` (_when `safe = true`_). * Or, if key does not exist in `source` (_regardless of `safe` flag_). */ declare function populate<TargetObj extends object = object, SourceObj extends object = object>(target: TargetObj, source: SourceObj, keys?: PropertyKey | PropertyKey[] | SourceKeysCallback, safe?: boolean): TargetObj; /** * @typedef {import('@aedart/contracts/support').Key} Key */ /** * Set value in object at given path * (Alias for Lodash' [set]{@link import('lodash').set}) method * * @type {{<T extends object>(object: T, path: Key, value: any): T, <TResult>(object: object, path: Key, value: any): TResult}} */ declare const set: { <T extends object>(object: T, path: lodash.PropertyPath, value: any): T; <TResult>(object: object, path: lodash.PropertyPath, value: any): TResult; }; /** * Alias for {@link ObjectId.get} */ declare const uniqueId: typeof ObjectId.get; /** * Merge Error * * @see MergeException */ declare class MergeError extends Error implements MergeException { /** * Create a new Merge Error instance * * @param {string} [message] * @param {ErrorOptions} [options] */ constructor(message?: string, options?: ErrorOptions); } /** * Default Merge Options * * @see MergeOptions */ declare class DefaultMergeOptions implements MergeOptions { /** * The maximum merge depth * * **Note**: _Value must be greater than or equal zero._ * * **Note**: _Defaults to [DEFAULT_MAX_MERGE_DEPTH]{@link import('@aedart/contracts/support/objects').DEFAULT_MAX_MERGE_DEPTH} * when not specified._ * * @type {number} */ depth: number; /** * Property Keys that must not be merged. * * **Note**: [DANGEROUS_PROPERTIES]{@link import('@aedart/contracts/support/objects').DANGEROUS_PROPERTIES} * are always skipped, regardless of specified keys._ * * **Callback**: _A callback can be specified to determine if a given key, * in a source object should be skipped._ * * **Example:** * ```js * const a = { 'foo': true }; * const b = { 'bar': true, 'zar': true }; * * merge().using({ skip: [ 'zar' ] }).of(a, b); // { 'foo': true, 'bar': true } * * merge().using({ skip: (key, source) => { * return key === 'bar' && Reflect.has(source, key); * } }).of(a, b); // { 'foo': true, 'zar': true } * ``` * * @type {PropertyKey[] | SkipKeyCallback} */ skip: PropertyKey[] | SkipKeyCallback; /** * Flag, overwrite property values with `undefined`. * * **When `true` (_default behaviour_)**: _If an existing property value is not `undefined`, it will be overwritten * with new value, even if the new value is `undefined`._ * * **When `false`**: _If an existing property value is not `undefined`, it will NOT be overwritten * with new value, if the new value is `undefined`._ * * **Example:** * ```js * const a = { 'foo': true }; * const b = { 'foo': undefined }; * * merge(a, b); // { 'foo': undefined } * * merge().using({ overwriteWithUndefined: false }).of(a, b) // { 'foo': true } * ``` * * @type {boolean} */ overwriteWithUndefined: boolean; /** * Flag, if source object is [`Cloneable`]{@link import('@aedart/contracts/support/objects').Cloneable}, then the * resulting object from the `clone()` method is used. * * **When `true` (_default behaviour_)**: _If source object is cloneable then the resulting object from `clone()` * method is used. Its properties are then iterated by the merge function._ * * **When `false`**: _Cloneable objects are treated like any other objects, the `clone()` method is ignored._ * * **Example:** * ```js * const a = { 'foo': { 'name': 'John Doe' } }; * const b = { 'foo': { * 'name': 'Jane Doe', * clone() { * return { * 'name': 'Rick Doe', * 'age': 26 * } * } * } }; * * merge(a, b); // { 'foo': { 'name': 'Rick Doe', 'age': 26 } } * * merge().using({ useCloneable: false }).of(a, b); // { 'foo': { 'name': 'Jane Doe', clone() {...} } } * ``` * * @see [`Cloneable`]{@link import('@aedart/contracts/support/objects').Cloneable} * * @type {boolean} */ useCloneable: boolean; /** * Flag, whether to merge array, array-like, and [concat spreadable]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable} * properties or not. * * **When `true`**: _existing property is merged with new property value._ * * **When `false` (_default behaviour_)**: _existing property is overwritten with new property value_ * * **Example:** * ```js * const a = { 'foo': [ 1, 2, 3 ] }; * const b = { 'foo': [ 4, 5, 6 ] }; * * merge([ a, b ]); // { 'foo': [ 4, 5, 6 ] } * merge([ a, b ], { mergeArrays: true }); // { 'foo': [ 1, 2, 3, 4, 5, 6 ] } * ``` * * **Note**: _`String()` (object) and [Typed Arrays]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray} * are not merged, even though they are considered to be "array-like" (they offer a `length` property). * You need to manually handle these, via a custom [callback]{@link MergeCallback}, if such value types must be merged._ * * @see [merge (array)]{@link import('@aedart/support/arrays').merge} * * @type {boolean} */ mergeArrays: boolean; /** * Merge Options for arrays * * @type {ArrayMergeOptions} */ arrayMergeOptions: ArrayMergeOptions; /** * The merge callback that must be applied * * **Note**: _When no callback is provided, then the merge function's default * callback is used._ * * @type {MergeCallback} */ callback: MergeCallback; /** * Creates a new Merge Options instance * * @param {MergeCallback | MergeOptions} [options] */ constructor(options?: MergeCallback | MergeOptions); /** * Create new default merge options from given options * * @param {MergeCallback | MergeOptions} [options] * * @return {DefaultMergeOptions} * * @throws {MergeError} */ static from(options?: MergeCallback | MergeOptions): Readonly<DefaultMergeOptions>; } /** * Objects Merger * * @see ObjectsMerger */ declare class Merger implements ObjectsMerger { /** * The merge options to be applied * * @type {Readonly<DefaultMergeOptions | MergeOptions>} * * @protected */ protected _options: Readonly<DefaultMergeOptions | MergeOptions>; /** * Callback to perform the merging of nested objects. * * @type {NextCallback} * * @protected * @readonly */ protected readonly _next: NextCallback; /** * Create a new objects merger instance * * @param {MergeCallback | MergeOptions} [options] * * @throws {MergeError} */ constructor(options?: MergeCallback | MergeOptions); /** * Returns the merge options that are to be applied * * @return {Readonly<DefaultMergeOptions | MergeOptions>} */ get options(): Readonly<DefaultMergeOptions | MergeOptions>; /** * Returns the "next" callback that performs merging of nested objects. */ get nextCallback(): NextCallback; /** * Use the following merge options or merge callback * * @param {MergeCallback | MergeOptions} [options] * * @return {this} * * @throws {MergeError} */ using(options?: MergeCallback | MergeOptions): this; of(...sources: object[]): object; /** * Merge given source objects into a single object * * @param {object[]} sources * @param {Readonly<MergeOptions>} options * @param {number} [depth] Current recursion depth * * @return {object} * * @throws {MergeError} */ merge(sources: object[], options: Readonly<MergeOptions>, depth?: number): object; /** * Resolves the source object * * @param {object} source * @param {MergeOptions} options * * @protected * * @return {object} */ protected resolveSourceObject(source: object, options: MergeOptions): object; /** * Invokes the "clone()" method on given cloneable object * * @param {Cloneable} source * * @protected * * @return {object} * * @return {MergeError} If unable to */ protected cloneSource(source: Cloneable): object; /** * Resolves provided merge options * * @param {MergeCallback | MergeOptions} [options] * * @protected * * @return {Readonly<DefaultMergeOptions | MergeOptions>} * * @throws {MergeError} */ protected resolveOptions(options?: MergeCallback | MergeOptions): Readonly<DefaultMergeOptions | MergeOptions>; /** * Assert that current recursion depth has now exceeded the maximum depth * * @param {number} currentDepth * @param {object[]} sources * @param {MergeOptions} [options] Defaults to this Merger's options when none given * * @protected * * @throws {MergeError} */ protected assertMaxDepthNotExceeded(currentDepth: number, sources: object[], options?: MergeOptions): void; /** * Assert given source is a valid object * * @param {unknown} source * @param {number} index * @param {number} currentDepth * * @protected * * @throws {MergeError} */ protected assertSourceObject(source: unknown, index: number, currentDepth: number): void; } /** * Determine if an object value can be cloned via `structuredClone()` * * @see https://developer.mozilla.org/en-US/docs/Web/API/structuredClone * * @internal * * @param {object} value * * @return {boolean} */ declare function canCloneUsingStructuredClone(value: object): boolean; /** * The default merge callback * * @type {MergeCallback} */ declare const defaultMergeCallback: MergeCallback; /** * Returns a new skip callback for given property keys * * @param {PropertyKey[]} keys * * @return {SkipKeyCallback} */ declare function makeSkipCallback(keys: PropertyKey[]): SkipKeyCallback; export { DefaultMergeOptions, MergeError, Merger, ObjectId, canCloneUsingStructuredClone, defaultMergeCallback, forget, forgetAll, get, has, hasAll, hasAny, hasUniqueId, isCloneable, isPopulatable, isset, makeSkipCallback, merge, populate, set, uniqueId };