renommage de lib, rendre buildable

This commit is contained in:
Tykayn 2025-08-08 10:57:00 +02:00 committed by tykayn
parent 1706c64713
commit a89007a81b
9896 changed files with 478996 additions and 496 deletions

View file

@ -0,0 +1,619 @@
'use strict';
/**
* Special values that tell deepmerge to perform a certain action.
*/
const actions = {
defaultMerge: Symbol("deepmerge-ts: default merge"),
skip: Symbol("deepmerge-ts: skip"),
};
/**
* Special values that tell deepmergeInto to perform a certain action.
*/
const actionsInto = {
defaultMerge: actions.defaultMerge,
};
/**
* The default function to update meta data.
*
* It doesn't update the meta data.
*/
function defaultMetaDataUpdater(previousMeta, metaMeta) {
return metaMeta;
}
/**
* The default function to filter values.
*
* It filters out undefined values.
*/
function defaultFilterValues(values, meta) {
return values.filter((value) => value !== undefined);
}
/**
* The different types of objects deepmerge-ts support.
*/
var ObjectType;
(function (ObjectType) {
ObjectType[ObjectType["NOT"] = 0] = "NOT";
ObjectType[ObjectType["RECORD"] = 1] = "RECORD";
ObjectType[ObjectType["ARRAY"] = 2] = "ARRAY";
ObjectType[ObjectType["SET"] = 3] = "SET";
ObjectType[ObjectType["MAP"] = 4] = "MAP";
ObjectType[ObjectType["OTHER"] = 5] = "OTHER";
})(ObjectType || (ObjectType = {}));
/**
* Get the type of the given object.
*
* @param object - The object to get the type of.
* @returns The type of the given object.
*/
function getObjectType(object) {
if (typeof object !== "object" || object === null) {
return 0 /* ObjectType.NOT */;
}
if (Array.isArray(object)) {
return 2 /* ObjectType.ARRAY */;
}
if (isRecord(object)) {
return 1 /* ObjectType.RECORD */;
}
if (object instanceof Set) {
return 3 /* ObjectType.SET */;
}
if (object instanceof Map) {
return 4 /* ObjectType.MAP */;
}
return 5 /* ObjectType.OTHER */;
}
/**
* Get the keys of the given objects including symbol keys.
*
* Note: Only keys to enumerable properties are returned.
*
* @param objects - An array of objects to get the keys of.
* @returns A set containing all the keys of all the given objects.
*/
function getKeys(objects) {
const keys = new Set();
for (const object of objects) {
for (const key of [...Object.keys(object), ...Object.getOwnPropertySymbols(object)]) {
keys.add(key);
}
}
return keys;
}
/**
* Does the given object have the given property.
*
* @param object - The object to test.
* @param property - The property to test.
* @returns Whether the object has the property.
*/
function objectHasProperty(object, property) {
return typeof object === "object" && Object.prototype.propertyIsEnumerable.call(object, property);
}
/**
* Get an iterable object that iterates over the given iterables.
*/
function getIterableOfIterables(iterables) {
let mut_iterablesIndex = 0;
let mut_iterator = iterables[0]?.[Symbol.iterator]();
return {
[Symbol.iterator]() {
return {
next() {
do {
if (mut_iterator === undefined) {
return { done: true, value: undefined };
}
const result = mut_iterator.next();
if (result.done === true) {
mut_iterablesIndex += 1;
mut_iterator = iterables[mut_iterablesIndex]?.[Symbol.iterator]();
continue;
}
return {
done: false,
value: result.value,
};
} while (true);
},
};
},
};
}
// eslint-disable-next-line unicorn/prefer-set-has -- Array is more performant for a low number of elements.
const validRecordToStringValues = ["[object Object]", "[object Module]"];
/**
* Does the given object appear to be a record.
*/
function isRecord(value) {
// All records are objects.
if (!validRecordToStringValues.includes(Object.prototype.toString.call(value))) {
return false;
}
const { constructor } = value;
// If has modified constructor.
// eslint-disable-next-line ts/no-unnecessary-condition
if (constructor === undefined) {
return true;
}
const prototype = constructor.prototype;
// If has modified prototype.
if (prototype === null ||
typeof prototype !== "object" ||
!validRecordToStringValues.includes(Object.prototype.toString.call(prototype))) {
return false;
}
// If constructor does not have an Object-specific method.
// eslint-disable-next-line sonar/prefer-single-boolean-return, no-prototype-builtins
if (!prototype.hasOwnProperty("isPrototypeOf")) {
return false;
}
// Most likely a record.
return true;
}
/**
* The default strategy to merge records.
*
* @param values - The records.
*/
function mergeRecords$1(values, utils, meta) {
const result = {};
for (const key of getKeys(values)) {
const propValues = [];
for (const value of values) {
if (objectHasProperty(value, key)) {
propValues.push(value[key]);
}
}
if (propValues.length === 0) {
continue;
}
const updatedMeta = utils.metaDataUpdater(meta, {
key,
parents: values,
});
const propertyResult = mergeUnknowns(propValues, utils, updatedMeta);
if (propertyResult === actions.skip) {
continue;
}
if (key === "__proto__") {
Object.defineProperty(result, key, {
value: propertyResult,
configurable: true,
enumerable: true,
writable: true,
});
}
else {
result[key] = propertyResult;
}
}
return result;
}
/**
* The default strategy to merge arrays.
*
* @param values - The arrays.
*/
function mergeArrays$1(values) {
return values.flat();
}
/**
* The default strategy to merge sets.
*
* @param values - The sets.
*/
function mergeSets$1(values) {
return new Set(getIterableOfIterables(values));
}
/**
* The default strategy to merge maps.
*
* @param values - The maps.
*/
function mergeMaps$1(values) {
return new Map(getIterableOfIterables(values));
}
/**
* Get the last value in the given array.
*/
function mergeOthers$1(values) {
return values.at(-1);
}
/**
* The merge functions.
*/
const mergeFunctions = {
mergeRecords: mergeRecords$1,
mergeArrays: mergeArrays$1,
mergeSets: mergeSets$1,
mergeMaps: mergeMaps$1,
mergeOthers: mergeOthers$1,
};
/**
* Deeply merge objects.
*
* @param objects - The objects to merge.
*/
function deepmerge(...objects) {
return deepmergeCustom({})(...objects);
}
function deepmergeCustom(options, rootMetaData) {
const utils = getUtils(options, customizedDeepmerge);
/**
* The customized deepmerge function.
*/
function customizedDeepmerge(...objects) {
return mergeUnknowns(objects, utils, rootMetaData);
}
return customizedDeepmerge;
}
/**
* The the utils that are available to the merge functions.
*
* @param options - The options the user specified
*/
function getUtils(options, customizedDeepmerge) {
return {
defaultMergeFunctions: mergeFunctions,
mergeFunctions: {
...mergeFunctions,
...Object.fromEntries(Object.entries(options)
.filter(([key, option]) => Object.hasOwn(mergeFunctions, key))
.map(([key, option]) => (option === false ? [key, mergeFunctions.mergeOthers] : [key, option]))),
},
metaDataUpdater: (options.metaDataUpdater ?? defaultMetaDataUpdater),
deepmerge: customizedDeepmerge,
useImplicitDefaultMerging: options.enableImplicitDefaultMerging ?? false,
filterValues: options.filterValues === false ? undefined : (options.filterValues ?? defaultFilterValues),
actions,
};
}
/**
* Merge unknown things.
*
* @param values - The values.
*/
function mergeUnknowns(values, utils, meta) {
const filteredValues = utils.filterValues?.(values, meta) ?? values;
if (filteredValues.length === 0) {
return undefined;
}
if (filteredValues.length === 1) {
return mergeOthers(filteredValues, utils, meta);
}
const type = getObjectType(filteredValues[0]);
if (type !== 0 /* ObjectType.NOT */ && type !== 5 /* ObjectType.OTHER */) {
for (let mut_index = 1; mut_index < filteredValues.length; mut_index++) {
if (getObjectType(filteredValues[mut_index]) === type) {
continue;
}
return mergeOthers(filteredValues, utils, meta);
}
}
switch (type) {
case 1 /* ObjectType.RECORD */: {
return mergeRecords(filteredValues, utils, meta);
}
case 2 /* ObjectType.ARRAY */: {
return mergeArrays(filteredValues, utils, meta);
}
case 3 /* ObjectType.SET */: {
return mergeSets(filteredValues, utils, meta);
}
case 4 /* ObjectType.MAP */: {
return mergeMaps(filteredValues, utils, meta);
}
default: {
return mergeOthers(filteredValues, utils, meta);
}
}
}
/**
* Merge records.
*
* @param values - The records.
*/
function mergeRecords(values, utils, meta) {
const result = utils.mergeFunctions.mergeRecords(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeRecords !== utils.defaultMergeFunctions.mergeRecords)) {
return utils.defaultMergeFunctions.mergeRecords(values, utils, meta);
}
return result;
}
/**
* Merge arrays.
*
* @param values - The arrays.
*/
function mergeArrays(values, utils, meta) {
const result = utils.mergeFunctions.mergeArrays(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeArrays !== utils.defaultMergeFunctions.mergeArrays)) {
return utils.defaultMergeFunctions.mergeArrays(values);
}
return result;
}
/**
* Merge sets.
*
* @param values - The sets.
*/
function mergeSets(values, utils, meta) {
const result = utils.mergeFunctions.mergeSets(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeSets !== utils.defaultMergeFunctions.mergeSets)) {
return utils.defaultMergeFunctions.mergeSets(values);
}
return result;
}
/**
* Merge maps.
*
* @param values - The maps.
*/
function mergeMaps(values, utils, meta) {
const result = utils.mergeFunctions.mergeMaps(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeMaps !== utils.defaultMergeFunctions.mergeMaps)) {
return utils.defaultMergeFunctions.mergeMaps(values);
}
return result;
}
/**
* Merge other things.
*
* @param values - The other things.
*/
function mergeOthers(values, utils, meta) {
const result = utils.mergeFunctions.mergeOthers(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeOthers !== utils.defaultMergeFunctions.mergeOthers)) {
return utils.defaultMergeFunctions.mergeOthers(values);
}
return result;
}
/**
* The default strategy to merge records into a target record.
*
* @param mut_target - The result will be mutated into this record
* @param values - The records (including the target's value if there is one).
*/
function mergeRecordsInto$1(mut_target, values, utils, meta) {
for (const key of getKeys(values)) {
const propValues = [];
for (const value of values) {
if (objectHasProperty(value, key)) {
propValues.push(value[key]);
}
}
if (propValues.length === 0) {
continue;
}
const updatedMeta = utils.metaDataUpdater(meta, {
key,
parents: values,
});
const propertyTarget = { value: propValues[0] };
mergeUnknownsInto(propertyTarget, propValues, utils, updatedMeta);
if (key === "__proto__") {
Object.defineProperty(mut_target.value, key, {
value: propertyTarget.value,
configurable: true,
enumerable: true,
writable: true,
});
}
else {
mut_target.value[key] = propertyTarget.value;
}
}
}
/**
* The default strategy to merge arrays into a target array.
*
* @param mut_target - The result will be mutated into this array
* @param values - The arrays (including the target's value if there is one).
*/
function mergeArraysInto$1(mut_target, values) {
mut_target.value.push(...values.slice(1).flat());
}
/**
* The default strategy to merge sets into a target set.
*
* @param mut_target - The result will be mutated into this set
* @param values - The sets (including the target's value if there is one).
*/
function mergeSetsInto$1(mut_target, values) {
for (const value of getIterableOfIterables(values.slice(1))) {
mut_target.value.add(value);
}
}
/**
* The default strategy to merge maps into a target map.
*
* @param mut_target - The result will be mutated into this map
* @param values - The maps (including the target's value if there is one).
*/
function mergeMapsInto$1(mut_target, values) {
for (const [key, value] of getIterableOfIterables(values.slice(1))) {
mut_target.value.set(key, value);
}
}
/**
* Set the target to the last value.
*/
function mergeOthersInto$1(mut_target, values) {
mut_target.value = values.at(-1);
}
/**
* The merge functions.
*/
const mergeIntoFunctions = {
mergeRecords: mergeRecordsInto$1,
mergeArrays: mergeArraysInto$1,
mergeSets: mergeSetsInto$1,
mergeMaps: mergeMapsInto$1,
mergeOthers: mergeOthersInto$1,
};
function deepmergeInto(target, ...objects) {
return void deepmergeIntoCustom({})(target, ...objects);
}
function deepmergeIntoCustom(options, rootMetaData) {
const utils = getIntoUtils(options, customizedDeepmergeInto);
/**
* The customized deepmerge function.
*/
function customizedDeepmergeInto(target, ...objects) {
mergeUnknownsInto({ value: target }, [target, ...objects], utils, rootMetaData);
}
return customizedDeepmergeInto;
}
/**
* The the utils that are available to the merge functions.
*
* @param options - The options the user specified
*/
function getIntoUtils(options, customizedDeepmergeInto) {
return {
defaultMergeFunctions: mergeIntoFunctions,
mergeFunctions: {
...mergeIntoFunctions,
...Object.fromEntries(Object.entries(options)
.filter(([key, option]) => Object.hasOwn(mergeIntoFunctions, key))
.map(([key, option]) => (option === false ? [key, mergeIntoFunctions.mergeOthers] : [key, option]))),
},
metaDataUpdater: (options.metaDataUpdater ?? defaultMetaDataUpdater),
deepmergeInto: customizedDeepmergeInto,
filterValues: options.filterValues === false ? undefined : (options.filterValues ?? defaultFilterValues),
actions: actionsInto,
};
}
/**
* Merge unknown things into a target.
*
* @param mut_target - The target to merge into.
* @param values - The values.
*/
function mergeUnknownsInto(mut_target, values, utils, meta) {
const filteredValues = utils.filterValues?.(values, meta) ?? values;
if (filteredValues.length === 0) {
return;
}
if (filteredValues.length === 1) {
return void mergeOthersInto(mut_target, filteredValues, utils, meta);
}
const type = getObjectType(mut_target.value);
if (type !== 0 /* ObjectType.NOT */ && type !== 5 /* ObjectType.OTHER */) {
for (let mut_index = 1; mut_index < filteredValues.length; mut_index++) {
if (getObjectType(filteredValues[mut_index]) === type) {
continue;
}
return void mergeOthersInto(mut_target, filteredValues, utils, meta);
}
}
switch (type) {
case 1 /* ObjectType.RECORD */: {
return void mergeRecordsInto(mut_target, filteredValues, utils, meta);
}
case 2 /* ObjectType.ARRAY */: {
return void mergeArraysInto(mut_target, filteredValues, utils, meta);
}
case 3 /* ObjectType.SET */: {
return void mergeSetsInto(mut_target, filteredValues, utils, meta);
}
case 4 /* ObjectType.MAP */: {
return void mergeMapsInto(mut_target, filteredValues, utils, meta);
}
default: {
return void mergeOthersInto(mut_target, filteredValues, utils, meta);
}
}
}
/**
* Merge records into a target record.
*
* @param mut_target - The target to merge into.
* @param values - The records.
*/
function mergeRecordsInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeRecords(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeRecords(mut_target, values, utils, meta);
}
}
/**
* Merge arrays into a target array.
*
* @param mut_target - The target to merge into.
* @param values - The arrays.
*/
function mergeArraysInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeArrays(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeArrays(mut_target, values);
}
}
/**
* Merge sets into a target set.
*
* @param mut_target - The target to merge into.
* @param values - The sets.
*/
function mergeSetsInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeSets(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeSets(mut_target, values);
}
}
/**
* Merge maps into a target map.
*
* @param mut_target - The target to merge into.
* @param values - The maps.
*/
function mergeMapsInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeMaps(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeMaps(mut_target, values);
}
}
/**
* Merge other things into a target.
*
* @param mut_target - The target to merge into.
* @param values - The other things.
*/
function mergeOthersInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeOthers(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge || mut_target.value === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeOthers(mut_target, values);
}
}
exports.deepmerge = deepmerge;
exports.deepmergeCustom = deepmergeCustom;
exports.deepmergeInto = deepmergeInto;
exports.deepmergeIntoCustom = deepmergeIntoCustom;
exports.getKeys = getKeys;
exports.getObjectType = getObjectType;
exports.objectHasProperty = objectHasProperty;

View file

@ -0,0 +1,832 @@
// Generated by dts-bundle-generator v9.5.1
/**
* Simplify a complex type such as a union or intersection of objects into a
* single object.
*/
export type SimplifyObject<T extends {}> = {
[K in keyof T]: T[K];
} & {};
/**
* Flatten a collection of tuples of tuples into a collection of tuples.
*/
export type FlattenTuples<T> = {
[I in keyof T]: FlattenTuple<T[I]>;
};
/**
* Flatten a tuple of tuples into a single tuple.
*/
export type FlattenTuple<T> = T extends readonly [
] ? [
] : T extends readonly [
infer T0
] ? [
...FlattenTuple<T0>
] : T extends readonly [
infer T0,
...infer Ts
] ? [
...FlattenTuple<T0>,
...FlattenTuple<Ts>
] : [
T
];
/**
* Safely test whether or not the first given types extends the second.
*
* Needed in particular for testing if a type is "never".
*/
export type Is<T1, T2> = [
T1
] extends [
T2
] ? true : false;
/**
* Safely test whether or not the given type is "never".
*/
export type IsNever<T> = Is<T, never>;
/**
* And operator for types.
*/
export type And<T1 extends boolean, T2 extends boolean> = T1 extends false ? false : T2;
/**
* Not operator for types.
*/
export type Not<T extends boolean> = T extends true ? false : true;
/**
* Check if a key is optional in the given object.
*/
export type KeyIsOptional<K extends PropertyKey, O extends {
[Key in K]?: unknown;
}> = O extends {
[Key in K]: unknown;
} ? false : true;
/**
* Returns whether or not the given type a record.
*
* Note: Does not pass for interfaces.
*/
export type IsRecord<T> = And<Not<IsNever<T>>, T extends Readonly<Record<PropertyKey, unknown>> ? true : false>;
/**
* Returns whether or not all the given types are records.
*/
export type EveryIsRecord<Ts extends ReadonlyArray<unknown>> = Ts extends readonly [
infer Head,
...infer Rest
] ? IsRecord<Head> extends true ? Rest extends ReadonlyArray<unknown> ? EveryIsRecord<Rest> : true : false : true;
/**
* Returns whether or not the given type is an array.
*/
export type IsArray<T> = And<Not<IsNever<T>>, T extends ReadonlyArray<unknown> ? true : false>;
/**
* Returns whether or not all the given types are arrays.
*/
export type EveryIsArray<Ts extends ReadonlyArray<unknown>> = Ts extends readonly [
infer T1
] ? IsArray<T1> : Ts extends readonly [
infer Head,
...infer Rest
] ? IsArray<Head> extends true ? Rest extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? EveryIsArray<Rest> : false : false : false;
/**
* Returns whether or not the given type is an set.
*
* Note: This may also return true for Maps.
*/
export type IsSet<T> = And<Not<IsNever<T>>, T extends Readonly<ReadonlySet<unknown>> ? true : false>;
/**
* Returns whether or not all the given types are sets.
*
* Note: This may also return true if all are maps.
*/
export type EveryIsSet<Ts extends ReadonlyArray<unknown>> = Ts extends Readonly<readonly [
infer T1
]> ? IsSet<T1> : Ts extends readonly [
infer Head,
...infer Rest
] ? IsSet<Head> extends true ? Rest extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? EveryIsSet<Rest> : false : false : false;
/**
* Returns whether or not the given type is an map.
*/
export type IsMap<T> = And<Not<IsNever<T>>, T extends Readonly<ReadonlyMap<unknown, unknown>> ? true : false>;
/**
* Returns whether or not all the given types are maps.
*/
export type EveryIsMap<Ts extends ReadonlyArray<unknown>> = Ts extends Readonly<readonly [
infer T1
]> ? IsMap<T1> : Ts extends readonly [
infer Head,
...infer Rest
] ? IsMap<Head> extends true ? Rest extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? EveryIsMap<Rest> : false : false : false;
/**
* Union of the sets' values' types
*/
export type UnionSetValues<Ts extends ReadonlyArray<unknown>> = UnionSetValuesHelper<Ts, never>;
/**
* Tail-recursive helper type for UnionSetValues.
*/
export type UnionSetValuesHelper<Ts extends ReadonlyArray<unknown>, Acc> = Ts extends readonly [
infer Head,
...infer Rest
] ? Head extends Readonly<ReadonlySet<infer V1>> ? Rest extends ReadonlyArray<unknown> ? UnionSetValuesHelper<Rest, Acc | V1> : Acc | V1 : never : Acc;
/**
* Union of the maps' values' types
*/
export type UnionMapKeys<Ts extends ReadonlyArray<unknown>> = UnionMapKeysHelper<Ts, never>;
/**
* Tail-recursive helper type for UnionMapKeys.
*/
export type UnionMapKeysHelper<Ts extends ReadonlyArray<unknown>, Acc> = Ts extends readonly [
infer Head,
...infer Rest
] ? Head extends Readonly<ReadonlyMap<infer K1, unknown>> ? Rest extends readonly [
] ? Acc | K1 : UnionMapKeysHelper<Rest, Acc | K1> : never : Acc;
/**
* Union of the maps' keys' types
*/
export type UnionMapValues<Ts extends ReadonlyArray<unknown>> = UnionMapValuesHelper<Ts, never>;
/**
* Tail-recursive helper type for UnionMapValues.
*/
export type UnionMapValuesHelper<Ts extends ReadonlyArray<unknown>, Acc> = Ts extends readonly [
infer Head,
...infer Rest
] ? Head extends Readonly<ReadonlyMap<unknown, infer V1>> ? Rest extends readonly [
] ? Acc | V1 : UnionMapValuesHelper<Rest, Acc | V1> : never : Acc;
/**
* Use the more precise type if the types are compatible.
* Otherwise, union them.
*/
export type PreciseOrUnion<A, B> = A extends B ? A : B extends A ? B : A | B;
/**
* Filter out U from a tuple.
*/
export type FilterOut<T extends ReadonlyArray<unknown>, U> = FilterOutHelper<T, U, [
]>;
/**
* Tail-recursive helper type for FilterOut.
*/
export type FilterOutHelper<T extends ReadonlyArray<unknown>, U, Acc extends ReadonlyArray<unknown>> = T extends readonly [
] ? Acc : T extends readonly [
infer Head,
...infer Rest
] ? Is<Head, U> extends true ? FilterOutHelper<Rest, U, Acc> : FilterOutHelper<Rest, U, [
...Acc,
Head
]> : T;
/**
* Filter out nevers from a tuple.
*/
export type FilterOutNever<T> = T extends ReadonlyArray<unknown> ? FilterOut<T, never> : never;
/**
* Is the type a tuple?
*/
export type IsTuple<T extends ReadonlyArray<unknown>> = T extends readonly [
] ? true : T extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? true : false;
/**
* Perfrom a transpose operation on a 2D tuple.
*/
export type TransposeTuple<T> = T extends readonly [
...(readonly [
...unknown[]
])
] ? T extends readonly [
] ? [
] : T extends readonly [
infer X extends ReadonlyArray<unknown>
] ? TransposeTupleSimpleCase<X> : T extends readonly [
infer X extends ReadonlyArray<unknown>,
...infer XS extends ReadonlyArray<ReadonlyArray<unknown>>
] ? PrependCol<X, TransposeTuple<XS>> : T : never;
export type PrependCol<T extends ReadonlyArray<unknown>, S extends ReadonlyArray<ReadonlyArray<unknown>>> = T extends readonly [
] ? S extends readonly [
] ? [
] : never : T extends readonly [
infer X,
...infer XS
] ? S extends readonly [
readonly [
...infer Y
],
...infer YS extends ReadonlyArray<ReadonlyArray<unknown>>
] ? [
[
X,
...Y
],
...PrependCol<XS, YS>
] : never : never;
export type TransposeTupleSimpleCase<T extends readonly [
...unknown[]
]> = T extends readonly [
] ? [
] : T extends readonly [
infer X,
...infer XS
] ? [
[
X
],
...TransposeTupleSimpleCase<XS>
] : never;
/**
* Convert a tuple to an intersection of each of its types.
*/
export type TupleToIntersection<T extends ReadonlyArray<unknown>> = {
[K in keyof T]: (x: T[K]) => void;
} extends Record<number, (x: infer I) => void> ? I : never;
/**
* Convert a union to a tuple.
*
* Warning: The order of the elements is non-deterministic.
* Warning 2: The union maybe me modified by the TypeScript engine before convertion.
* Warning 3: This implementation relies on a hack/limitation in TypeScript.
*/
export type UnionToTuple<T, L = LastOf<T>> = IsNever<T> extends true ? [
] : [
...UnionToTuple<Exclude<T, L>>,
L
];
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
export type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never;
/**
* Convert a tuple of tuples to a tuple of unions.
*/
export type TupleTupleToTupleUnion<T extends ReadonlyArray<ReadonlyArray<unknown>>> = {
[I in keyof T]: TupleToUnion<T[I]>;
};
/**
* Convert a tuple to a union.
*/
export type TupleToUnion<T extends ReadonlyArray<unknown>> = T extends readonly [
] ? never : T extends readonly [
infer Head,
...infer Rest
] ? Head | TupleToUnion<Rest> : never;
/**
* Assert that a type is of a given type.
*/
export type AssertType<Expected, T> = T extends Expected ? T : never;
/**
* Mapping of merge function URIs to the merge function type.
*/
export interface DeepMergeFunctionURItoKind<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, in out M> {
readonly DeepMergeLeafURI: DeepMergeLeaf<Ts, Fs, M>;
readonly DeepMergeRecordsDefaultURI: DeepMergeRecordsDefaultHKT<Ts, Fs, M>;
readonly DeepMergeArraysDefaultURI: DeepMergeArraysDefaultHKT<Ts, Fs, M>;
readonly DeepMergeSetsDefaultURI: DeepMergeSetsDefaultHKT<Ts>;
readonly DeepMergeMapsDefaultURI: DeepMergeMapsDefaultHKT<Ts>;
readonly DeepMergeFilterValuesDefaultURI: DeepMergeFilterValuesDefaultHKT<Ts>;
readonly DeepMergeNoFilteringURI: Ts;
}
/**
* Get the type of the given merge function via its URI.
*/
export type DeepMergeFunctionKind<URI extends DeepMergeFunctionURIs, Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionURItoKind<Ts, Fs, M>[URI];
/**
* A union of all valid merge function URIs.
*/
export type DeepMergeFunctionURIs = keyof DeepMergeFunctionURItoKind<ReadonlyArray<unknown>, DeepMergeFunctionsURIs, unknown>;
/**
* The merge functions to use when deep merging.
*/
export type DeepMergeFunctionsURIs = Readonly<{
/**
* The merge function to merge records with.
*/
DeepMergeRecordsURI: DeepMergeFunctionURIs;
/**
* The merge function to merge arrays with.
*/
DeepMergeArraysURI: DeepMergeFunctionURIs;
/**
* The merge function to merge sets with.
*/
DeepMergeSetsURI: DeepMergeFunctionURIs;
/**
* The merge function to merge maps with.
*/
DeepMergeMapsURI: DeepMergeFunctionURIs;
/**
* The merge function to merge other things with.
*/
DeepMergeOthersURI: DeepMergeFunctionURIs;
/**
* The function to filter values.
*/
DeepMergeFilterValuesURI: DeepMergeFunctionURIs;
}>;
/**
* Deep merge types.
*/
export type DeepMergeHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = IsTuple<Ts> extends true ? Ts extends readonly [
] ? undefined : DeepMergeHKTHelper<FilterValuesHKT<Ts, Fs, M>, Fs, M> : unknown;
export type DeepMergeHKTHelper<Ts, Fs extends DeepMergeFunctionsURIs, M> = Ts extends ReadonlyArray<unknown> ? IsTuple<Ts> extends true ? Ts extends readonly [
] ? unknown : Ts extends readonly [
infer T1
] ? T1 : EveryIsArray<Ts> extends true ? DeepMergeArraysHKT<Ts, Fs, M> : EveryIsMap<Ts> extends true ? DeepMergeMapsHKT<Ts, Fs, M> : EveryIsSet<Ts> extends true ? DeepMergeSetsHKT<Ts, Fs, M> : EveryIsRecord<Ts> extends true ? DeepMergeRecordsHKT<Ts, Fs, M> : DeepMergeOthersHKT<Ts, Fs, M> : unknown : never;
/**
* Deep merge records.
*/
export type DeepMergeRecordsHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeRecordsURI"], Ts, Fs, M>;
/**
* Deep merge arrays.
*/
export type DeepMergeArraysHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeArraysURI"], Ts, Fs, M>;
/**
* Deep merge sets.
*/
export type DeepMergeSetsHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeSetsURI"], Ts, Fs, M>;
/**
* Deep merge maps.
*/
export type DeepMergeMapsHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeMapsURI"], Ts, Fs, M>;
/**
* Deep merge other things.
*/
export type DeepMergeOthersHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeOthersURI"], Ts, Fs, M>;
/**
* Filter values.
*/
export type FilterValuesHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeFilterValuesURI"], Ts, Fs, M>;
/**
* The merge function that returns a leaf.
*/
export type DeepMergeLeafURI = "DeepMergeLeafURI";
/**
* Don't filter values.
*/
export type DeepMergeNoFilteringURI = "DeepMergeNoFilteringURI";
/**
* Get the leaf type from many types that can't be merged.
*/
export type DeepMergeLeaf<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = Ts extends readonly [
] ? never : Ts extends readonly [
infer T
] ? T : Ts extends readonly [
...infer Rest,
infer Tail
] ? IsNever<Tail> extends true ? Rest extends ReadonlyArray<unknown> ? DeepMergeLeaf<Rest, Fs, M> : never : DeepMergeLeafApplyFilter<Ts, AssertType<ReadonlyArray<unknown>, TupleTupleToTupleUnion<AssertType<ReadonlyArray<ReadonlyArray<unknown>>, {
[I in keyof Ts]: FilterValuesHKT<UnionToTuple<Ts[I]>, Fs, M>;
}>>>> : never;
export type DeepMergeLeafApplyFilter<Original extends ReadonlyArray<unknown>, Filtered extends ReadonlyArray<unknown>> = Original extends readonly [
...infer OriginalRest,
infer OriginalTail
] ? Filtered extends readonly [
...infer FilteredRest,
infer FilteredTail
] ? OriginalTail extends FilteredTail ? FilteredTail : FilteredTail | DeepMergeLeafApplyFilter<OriginalRest, FilteredRest> : never : never;
/**
* The meta data deepmerge is able to provide.
*/
export type DeepMergeBuiltInMetaData = Readonly<{
key: PropertyKey;
parents: ReadonlyArray<Readonly<Record<PropertyKey, unknown>>>;
}>;
/**
* The default merge function to merge records with.
*/
export type DeepMergeRecordsDefaultURI = "DeepMergeRecordsDefaultURI";
/**
* The default merge function to merge arrays with.
*/
export type DeepMergeArraysDefaultURI = "DeepMergeArraysDefaultURI";
/**
* The default merge function to merge sets with.
*/
export type DeepMergeSetsDefaultURI = "DeepMergeSetsDefaultURI";
/**
* The default merge function to merge maps with.
*/
export type DeepMergeMapsDefaultURI = "DeepMergeMapsDefaultURI";
/**
* The default filter values function.
*/
export type DeepMergeFilterValuesDefaultURI = "DeepMergeFilterValuesDefaultURI";
/**
* The default merge functions to use when deep merging.
*/
export type DeepMergeFunctionsDefaultURIs = Readonly<{
DeepMergeRecordsURI: DeepMergeRecordsDefaultURI;
DeepMergeArraysURI: DeepMergeArraysDefaultURI;
DeepMergeSetsURI: DeepMergeSetsDefaultURI;
DeepMergeMapsURI: DeepMergeMapsDefaultURI;
DeepMergeOthersURI: DeepMergeLeafURI;
DeepMergeFilterValuesURI: DeepMergeFilterValuesDefaultURI;
}>;
export type RecordEntries<T extends Record<PropertyKey, unknown>> = FilterOut<UnionToTuple<{
[K in keyof T]: [
K,
T[K]
];
}[keyof T]>, undefined>;
export type RecordMeta = Record<PropertyKey, RecordPropertyMeta>;
export type RecordPropertyMeta<Key extends PropertyKey = PropertyKey, Value = unknown, Optional extends boolean = boolean> = {
key: Key;
value: Value;
optional: Optional;
};
export type RecordsToRecordMeta<Ts extends ReadonlyArray<Record<PropertyKey, unknown>>> = FilterOutNever<{
[I in keyof Ts]: RecordToRecordMeta<Ts[I]>;
}>;
export type RecordToRecordMeta<T extends Record<PropertyKey, unknown>> = {
[K in keyof T]-?: {
key: K;
value: Required<T>[K];
optional: KeyIsOptional<K, T>;
};
};
/**
* Deep merge records.
*/
export type DeepMergeRecordsDefaultHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = Ts extends ReadonlyArray<Record<PropertyKey, unknown>> ? SimplifyObject<DeepMergeRecordMetaDefaultHKTProps<RecordsToRecordMeta<Ts>, Fs, M>> : never;
/**
* Deep merge record props.
*/
export type DeepMergeRecordMetaDefaultHKTProps<RecordMetas, Fs extends DeepMergeFunctionsURIs, M> = RecordMetas extends ReadonlyArray<RecordMeta> ? CreateRecordFromMeta<MergeRecordMeta<RecordMetas>, Fs, M> : never;
export type MergeRecordMeta<RecordMetas extends ReadonlyArray<RecordMeta>> = GroupValuesByKey<FlattenTuples<TransposeTuple<FilterOut<{
[I in keyof RecordMetas]: TransposeTuple<RecordEntries<RecordMetas[I]>>;
}, readonly [
]>>>>;
export type GroupValuesByKey<Ts> = Ts extends readonly [
infer Keys extends ReadonlyArray<PropertyKey>,
infer Values
] ? {
[I in keyof Keys]: DeepMergeRecordPropertyMetaDefaultHKTGetPossible<Keys[I], FilterOutNever<{
[J in keyof Values]: Values[J] extends {
key: Keys[I];
} ? Values[J] : never;
}>>;
} : never;
export type CreateRecordFromMeta<Ts, Fs extends DeepMergeFunctionsURIs, M> = Ts extends ReadonlyArray<unknown> ? TupleToIntersection<{
[I in keyof Ts]: Ts[I] extends {
key: infer Key extends PropertyKey;
values: infer Values extends ReadonlyArray<unknown>;
optional: infer O extends boolean;
} ? CreateRecordForKeyFromMeta<Key, Values, O, Fs, M> : never;
}> : never;
export type CreateRecordForKeyFromMeta<Key extends PropertyKey, Values extends ReadonlyArray<unknown>, Optional extends boolean, Fs extends DeepMergeFunctionsURIs, M> = Optional extends true ? {
[k in Key]+?: DeepMergeHKT<Values, Fs, M>;
} : {
[k in Key]-?: DeepMergeHKT<Values, Fs, M>;
};
/**
* Get the possible types of a property.
*/
export type DeepMergeRecordPropertyMetaDefaultHKTGetPossible<Key extends PropertyKey, Ts> = Ts extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Ts, {
key: Key;
values: [
];
optional: never;
}> : never;
/**
* Tail-recursive helper type for DeepMergeRecordPropertyMetaDefaultHKTGetPossible.
*/
export type DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Ts extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
], Acc extends {
key: PropertyKey;
values: ReadonlyArray<unknown>;
optional: boolean;
}> = Ts extends [
...infer Rest,
{
key: infer K extends PropertyKey;
value: infer V;
optional: infer O extends boolean;
}
] ? Acc["optional"] extends true ? Acc extends {
values: [
infer Head,
...infer AccRest
];
} ? Rest extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Rest, {
key: K;
values: [
PreciseOrUnion<V, Head>,
...AccRest
];
optional: O;
}> : {
key: K;
values: [
PreciseOrUnion<V, Head>,
...AccRest
];
optional: O;
} : Rest extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Rest, {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
}> : {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
} : Rest extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Rest, {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
}> : {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
} : never;
/**
* Deep merge arrays.
*/
export type DeepMergeArraysDefaultHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeArraysDefaultHKTHelper<Ts, Fs, M, [
]>;
/**
* Tail-recursive helper type for DeepMergeArraysDefaultHKT.
*/
export type DeepMergeArraysDefaultHKTHelper<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M, Acc extends ReadonlyArray<unknown>> = Ts extends readonly [
infer Head extends ReadonlyArray<unknown>,
...infer Rest
] ? Rest extends readonly [
ReadonlyArray<unknown>,
...ReadonlyArray<ReadonlyArray<unknown>>
] ? DeepMergeArraysDefaultHKTHelper<Rest, Fs, M, [
...Acc,
...Head
]> : [
...Acc,
...Head
] : never;
/**
* Deep merge sets.
*/
export type DeepMergeSetsDefaultHKT<Ts extends ReadonlyArray<unknown>> = Set<UnionSetValues<Ts>>;
/**
* Deep merge maps.
*/
export type DeepMergeMapsDefaultHKT<Ts extends ReadonlyArray<unknown>> = Map<UnionMapKeys<Ts>, UnionMapValues<Ts>>;
/**
* Filter out undefined values.
*/
export type DeepMergeFilterValuesDefaultHKT<Ts extends ReadonlyArray<unknown>> = FilterOut<Ts, undefined>;
/**
* Get the merge functions with defaults apply from the given subset.
*/
export type GetDeepMergeFunctionsURIs<PMF extends Partial<DeepMergeFunctionsURIs>> = Readonly<{
DeepMergeRecordsURI: PMF["DeepMergeRecordsURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeRecordsURI"] : DeepMergeRecordsDefaultURI;
DeepMergeArraysURI: PMF["DeepMergeArraysURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeArraysURI"] : DeepMergeArraysDefaultURI;
DeepMergeSetsURI: PMF["DeepMergeSetsURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeSetsURI"] : DeepMergeSetsDefaultURI;
DeepMergeMapsURI: PMF["DeepMergeMapsURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeMapsURI"] : DeepMergeMapsDefaultURI;
DeepMergeOthersURI: PMF["DeepMergeOthersURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeOthersURI"] : DeepMergeLeafURI;
DeepMergeFilterValuesURI: PMF["DeepMergeFilterValuesURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeFilterValuesURI"] : DeepMergeFilterValuesDefaultURI;
}>;
/**
* The default merge functions.
*/
type MergeFunctions = {
mergeRecords: typeof mergeRecordsInto;
mergeArrays: typeof mergeArraysInto;
mergeSets: typeof mergeSetsInto;
mergeMaps: typeof mergeMapsInto;
mergeOthers: typeof mergeOthersInto;
};
declare function mergeRecordsInto<Ts extends ReadonlyArray<Record<PropertyKey, unknown>>, U extends DeepMergeIntoFunctionUtils<M, MM>, M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(mut_target: Reference<Record<PropertyKey, unknown>>, values: Ts, utils: U, meta: M | undefined): void;
declare function mergeArraysInto<Ts extends ReadonlyArray<ReadonlyArray<unknown>>>(mut_target: Reference<unknown[]>, values: Ts): void;
declare function mergeSetsInto<Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>>(mut_target: Reference<Set<unknown>>, values: Ts): void;
declare function mergeMapsInto<Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>>(mut_target: Reference<Map<unknown, unknown>>, values: Ts): void;
declare function mergeOthersInto<Ts extends ReadonlyArray<unknown>>(mut_target: Reference<unknown>, values: Ts): void;
/**
* The default merge functions.
*/
type MergeFunctions$1 = {
mergeRecords: typeof mergeRecords;
mergeArrays: typeof mergeArrays;
mergeSets: typeof mergeSets;
mergeMaps: typeof mergeMaps;
mergeOthers: typeof mergeOthers;
};
declare function mergeRecords<Ts extends ReadonlyArray<Record<PropertyKey, unknown>>, U extends DeepMergeUtils<M, MM>, Fs extends DeepMergeFunctionsURIs, M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(values: Ts, utils: U, meta: M | undefined): DeepMergeRecordsDefaultHKT<Ts, Fs, M>;
declare function mergeArrays<Ts extends ReadonlyArray<ReadonlyArray<unknown>>, Fs extends DeepMergeFunctionsURIs, M>(values: Ts): DeepMergeArraysDefaultHKT<Ts, Fs, M>;
declare function mergeSets<Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>>(values: Ts): DeepMergeSetsDefaultHKT<Ts>;
declare function mergeMaps<Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>>(values: Ts): DeepMergeMapsDefaultHKT<Ts>;
declare function mergeOthers<Ts extends ReadonlyArray<unknown>>(values: Ts): unknown;
/**
* The options the user can pass to customize deepmerge.
*/
export type DeepMergeOptions<in out M, MM extends Readonly<Record<PropertyKey, unknown>> = {}> = Partial<DeepMergeOptionsFull<M, MM & DeepMergeBuiltInMetaData>>;
/**
* The options the user can pass to customize deepmergeInto.
*/
export type DeepMergeIntoOptions<in out M, MM extends Readonly<Record<PropertyKey, unknown>> = {}> = Partial<DeepMergeIntoOptionsFull<M, MM & DeepMergeBuiltInMetaData>>;
export type MetaDataUpdater<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = (previousMeta: M | undefined, metaMeta: Readonly<Partial<MM>>) => M;
/**
* All the options the user can pass to customize deepmerge.
*/
export type DeepMergeOptionsFull<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: DeepMergeFunctions<M, MM>["mergeRecords"] | false;
mergeArrays: DeepMergeFunctions<M, MM>["mergeArrays"] | false;
mergeMaps: DeepMergeFunctions<M, MM>["mergeMaps"] | false;
mergeSets: DeepMergeFunctions<M, MM>["mergeSets"] | false;
mergeOthers: DeepMergeFunctions<M, MM>["mergeOthers"];
metaDataUpdater: MetaDataUpdater<M, MM>;
enableImplicitDefaultMerging: boolean;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | false;
}>;
/**
* All the options the user can pass to customize deepmergeInto.
*/
export type DeepMergeIntoOptionsFull<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: DeepMergeIntoFunctions<M, MM>["mergeRecords"] | false;
mergeArrays: DeepMergeIntoFunctions<M, MM>["mergeArrays"] | false;
mergeMaps: DeepMergeIntoFunctions<M, MM>["mergeMaps"] | false;
mergeSets: DeepMergeIntoFunctions<M, MM>["mergeSets"] | false;
mergeOthers: DeepMergeIntoFunctions<M, MM>["mergeOthers"];
metaDataUpdater: MetaDataUpdater<M, MM>;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | false;
}>;
/**
* An object that has a reference to a value.
*/
type Reference<T> = {
value: T;
};
/**
* All the utility functions that can be overridden.
*/
export type DeepMergeUtilityFunctions<in M> = Readonly<{
filterValues: <Ts extends ReadonlyArray<unknown>>(values: Ts, meta: M | undefined) => unknown[];
}>;
/**
* All the merge functions that deepmerge uses.
*/
export type DeepMergeFunctions<in M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: <Ts extends ReadonlyArray<Readonly<Record<PropertyKey, unknown>>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeArrays: <Ts extends ReadonlyArray<ReadonlyArray<unknown>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeMaps: <Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeSets: <Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeOthers: <Ts extends ReadonlyArray<unknown>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
}>;
export type DeepMergeIntoFunctionsReturnType = void | symbol;
/**
* All the merge functions that deepmerge uses.
*/
export type DeepMergeIntoFunctions<in M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: <Ts extends ReadonlyArray<Readonly<Record<PropertyKey, unknown>>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<Record<PropertyKey, unknown>>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeArrays: <Ts extends ReadonlyArray<ReadonlyArray<unknown>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<unknown[]>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeMaps: <Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<Map<unknown, unknown>>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeSets: <Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<Set<unknown>>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeOthers: <Ts extends ReadonlyArray<unknown>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<unknown>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
}>;
/**
* The utils provided to the merge functions.
*/
export type DeepMergeUtils<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeFunctions: DeepMergeFunctions<M, MM>;
defaultMergeFunctions: MergeFunctions$1;
metaDataUpdater: MetaDataUpdater<M, MM>;
deepmerge: <Ts extends ReadonlyArray<unknown>>(...values: Ts) => unknown;
useImplicitDefaultMerging: boolean;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | undefined;
actions: Readonly<{
defaultMerge: symbol;
skip: symbol;
}>;
}>;
/**
* The utils provided to the merge functions.
*/
export type DeepMergeIntoFunctionUtils<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeFunctions: DeepMergeIntoFunctions<M, MM>;
defaultMergeFunctions: MergeFunctions;
metaDataUpdater: MetaDataUpdater<M, MM>;
deepmergeInto: <Target extends object, Ts extends ReadonlyArray<unknown>>(target: Target, ...values: Ts) => void;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | undefined;
actions: Readonly<{
defaultMerge: symbol;
}>;
}>;
/**
* Deeply merge objects.
*
* @param objects - The objects to merge.
*/
export declare function deepmerge<Ts extends Readonly<ReadonlyArray<unknown>>>(...objects: readonly [
...Ts
]): DeepMergeHKT<Ts, DeepMergeFunctionsDefaultURIs, DeepMergeBuiltInMetaData>;
/**
* Deeply merge two or more objects using the given options.
*
* @param options - The options on how to customize the merge function.
*/
export declare function deepmergeCustom<BaseTs = unknown, PMF extends Partial<DeepMergeFunctionsURIs> = {}>(options: DeepMergeOptions<DeepMergeBuiltInMetaData, DeepMergeBuiltInMetaData>): <Ts extends ReadonlyArray<BaseTs>>(...objects: Ts) => DeepMergeHKT<Ts, GetDeepMergeFunctionsURIs<PMF>, DeepMergeBuiltInMetaData>;
/**
* Deeply merge two or more objects using the given options and meta data.
*
* @param options - The options on how to customize the merge function.
* @param rootMetaData - The meta data passed to the root items' being merged.
*/
export declare function deepmergeCustom<BaseTs = unknown, PMF extends Partial<DeepMergeFunctionsURIs> = {}, MetaData = DeepMergeBuiltInMetaData, MetaMetaData extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(options: DeepMergeOptions<MetaData, MetaMetaData>, rootMetaData?: MetaData): <Ts extends ReadonlyArray<BaseTs>>(...objects: Ts) => DeepMergeHKT<Ts, GetDeepMergeFunctionsURIs<PMF>, MetaData>;
/**
* Deeply merge objects into a target.
*
* @param target - This object will be mutated with the merge result.
* @param objects - The objects to merge into the target.
*/
export declare function deepmergeInto<T extends object>(target: T, ...objects: ReadonlyArray<T>): void;
/**
* Deeply merge objects into a target.
*
* @param target - This object will be mutated with the merge result.
* @param objects - The objects to merge into the target.
*/
export declare function deepmergeInto<Target extends object, Ts extends ReadonlyArray<unknown>>(target: Target, ...objects: Ts): asserts target is SimplifyObject<Target & DeepMergeHKT<[
Target,
...Ts
], DeepMergeFunctionsDefaultURIs, DeepMergeBuiltInMetaData>>;
/**
* Deeply merge two or more objects using the given options.
*
* @param options - The options on how to customize the merge function.
*/
export declare function deepmergeIntoCustom<BaseTs = unknown>(options: DeepMergeIntoOptions<DeepMergeBuiltInMetaData, DeepMergeBuiltInMetaData>): <Target extends object, Ts extends ReadonlyArray<BaseTs>>(target: Target, ...objects: Ts) => void;
/**
* Deeply merge two or more objects using the given options and meta data.
*
* @param options - The options on how to customize the merge function.
* @param rootMetaData - The meta data passed to the root items' being merged.
*/
export declare function deepmergeIntoCustom<BaseTs = unknown, MetaData = DeepMergeBuiltInMetaData, MetaMetaData extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(options: DeepMergeIntoOptions<MetaData, MetaMetaData>, rootMetaData?: MetaData): <Target extends object, Ts extends ReadonlyArray<BaseTs>>(target: Target, ...objects: Ts) => void;
/**
* The different types of objects deepmerge-ts support.
*/
export declare const enum ObjectType {
NOT = 0,
RECORD = 1,
ARRAY = 2,
SET = 3,
MAP = 4,
OTHER = 5
}
/**
* Get the type of the given object.
*
* @param object - The object to get the type of.
* @returns The type of the given object.
*/
export declare function getObjectType(object: unknown): ObjectType;
/**
* Get the keys of the given objects including symbol keys.
*
* Note: Only keys to enumerable properties are returned.
*
* @param objects - An array of objects to get the keys of.
* @returns A set containing all the keys of all the given objects.
*/
export declare function getKeys(objects: ReadonlyArray<object>): Set<PropertyKey>;
/**
* Does the given object have the given property.
*
* @param object - The object to test.
* @param property - The property to test.
* @returns Whether the object has the property.
*/
export declare function objectHasProperty(object: object, property: PropertyKey): boolean;
export {
MergeFunctions as DeepMergeIntoFunctionsDefaults,
MergeFunctions$1 as DeepMergeFunctionsDefaults,
Reference as DeepMergeValueReference,
};
export {};

View file

@ -0,0 +1,832 @@
// Generated by dts-bundle-generator v9.5.1
/**
* Simplify a complex type such as a union or intersection of objects into a
* single object.
*/
export type SimplifyObject<T extends {}> = {
[K in keyof T]: T[K];
} & {};
/**
* Flatten a collection of tuples of tuples into a collection of tuples.
*/
export type FlattenTuples<T> = {
[I in keyof T]: FlattenTuple<T[I]>;
};
/**
* Flatten a tuple of tuples into a single tuple.
*/
export type FlattenTuple<T> = T extends readonly [
] ? [
] : T extends readonly [
infer T0
] ? [
...FlattenTuple<T0>
] : T extends readonly [
infer T0,
...infer Ts
] ? [
...FlattenTuple<T0>,
...FlattenTuple<Ts>
] : [
T
];
/**
* Safely test whether or not the first given types extends the second.
*
* Needed in particular for testing if a type is "never".
*/
export type Is<T1, T2> = [
T1
] extends [
T2
] ? true : false;
/**
* Safely test whether or not the given type is "never".
*/
export type IsNever<T> = Is<T, never>;
/**
* And operator for types.
*/
export type And<T1 extends boolean, T2 extends boolean> = T1 extends false ? false : T2;
/**
* Not operator for types.
*/
export type Not<T extends boolean> = T extends true ? false : true;
/**
* Check if a key is optional in the given object.
*/
export type KeyIsOptional<K extends PropertyKey, O extends {
[Key in K]?: unknown;
}> = O extends {
[Key in K]: unknown;
} ? false : true;
/**
* Returns whether or not the given type a record.
*
* Note: Does not pass for interfaces.
*/
export type IsRecord<T> = And<Not<IsNever<T>>, T extends Readonly<Record<PropertyKey, unknown>> ? true : false>;
/**
* Returns whether or not all the given types are records.
*/
export type EveryIsRecord<Ts extends ReadonlyArray<unknown>> = Ts extends readonly [
infer Head,
...infer Rest
] ? IsRecord<Head> extends true ? Rest extends ReadonlyArray<unknown> ? EveryIsRecord<Rest> : true : false : true;
/**
* Returns whether or not the given type is an array.
*/
export type IsArray<T> = And<Not<IsNever<T>>, T extends ReadonlyArray<unknown> ? true : false>;
/**
* Returns whether or not all the given types are arrays.
*/
export type EveryIsArray<Ts extends ReadonlyArray<unknown>> = Ts extends readonly [
infer T1
] ? IsArray<T1> : Ts extends readonly [
infer Head,
...infer Rest
] ? IsArray<Head> extends true ? Rest extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? EveryIsArray<Rest> : false : false : false;
/**
* Returns whether or not the given type is an set.
*
* Note: This may also return true for Maps.
*/
export type IsSet<T> = And<Not<IsNever<T>>, T extends Readonly<ReadonlySet<unknown>> ? true : false>;
/**
* Returns whether or not all the given types are sets.
*
* Note: This may also return true if all are maps.
*/
export type EveryIsSet<Ts extends ReadonlyArray<unknown>> = Ts extends Readonly<readonly [
infer T1
]> ? IsSet<T1> : Ts extends readonly [
infer Head,
...infer Rest
] ? IsSet<Head> extends true ? Rest extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? EveryIsSet<Rest> : false : false : false;
/**
* Returns whether or not the given type is an map.
*/
export type IsMap<T> = And<Not<IsNever<T>>, T extends Readonly<ReadonlyMap<unknown, unknown>> ? true : false>;
/**
* Returns whether or not all the given types are maps.
*/
export type EveryIsMap<Ts extends ReadonlyArray<unknown>> = Ts extends Readonly<readonly [
infer T1
]> ? IsMap<T1> : Ts extends readonly [
infer Head,
...infer Rest
] ? IsMap<Head> extends true ? Rest extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? EveryIsMap<Rest> : false : false : false;
/**
* Union of the sets' values' types
*/
export type UnionSetValues<Ts extends ReadonlyArray<unknown>> = UnionSetValuesHelper<Ts, never>;
/**
* Tail-recursive helper type for UnionSetValues.
*/
export type UnionSetValuesHelper<Ts extends ReadonlyArray<unknown>, Acc> = Ts extends readonly [
infer Head,
...infer Rest
] ? Head extends Readonly<ReadonlySet<infer V1>> ? Rest extends ReadonlyArray<unknown> ? UnionSetValuesHelper<Rest, Acc | V1> : Acc | V1 : never : Acc;
/**
* Union of the maps' values' types
*/
export type UnionMapKeys<Ts extends ReadonlyArray<unknown>> = UnionMapKeysHelper<Ts, never>;
/**
* Tail-recursive helper type for UnionMapKeys.
*/
export type UnionMapKeysHelper<Ts extends ReadonlyArray<unknown>, Acc> = Ts extends readonly [
infer Head,
...infer Rest
] ? Head extends Readonly<ReadonlyMap<infer K1, unknown>> ? Rest extends readonly [
] ? Acc | K1 : UnionMapKeysHelper<Rest, Acc | K1> : never : Acc;
/**
* Union of the maps' keys' types
*/
export type UnionMapValues<Ts extends ReadonlyArray<unknown>> = UnionMapValuesHelper<Ts, never>;
/**
* Tail-recursive helper type for UnionMapValues.
*/
export type UnionMapValuesHelper<Ts extends ReadonlyArray<unknown>, Acc> = Ts extends readonly [
infer Head,
...infer Rest
] ? Head extends Readonly<ReadonlyMap<unknown, infer V1>> ? Rest extends readonly [
] ? Acc | V1 : UnionMapValuesHelper<Rest, Acc | V1> : never : Acc;
/**
* Use the more precise type if the types are compatible.
* Otherwise, union them.
*/
export type PreciseOrUnion<A, B> = A extends B ? A : B extends A ? B : A | B;
/**
* Filter out U from a tuple.
*/
export type FilterOut<T extends ReadonlyArray<unknown>, U> = FilterOutHelper<T, U, [
]>;
/**
* Tail-recursive helper type for FilterOut.
*/
export type FilterOutHelper<T extends ReadonlyArray<unknown>, U, Acc extends ReadonlyArray<unknown>> = T extends readonly [
] ? Acc : T extends readonly [
infer Head,
...infer Rest
] ? Is<Head, U> extends true ? FilterOutHelper<Rest, U, Acc> : FilterOutHelper<Rest, U, [
...Acc,
Head
]> : T;
/**
* Filter out nevers from a tuple.
*/
export type FilterOutNever<T> = T extends ReadonlyArray<unknown> ? FilterOut<T, never> : never;
/**
* Is the type a tuple?
*/
export type IsTuple<T extends ReadonlyArray<unknown>> = T extends readonly [
] ? true : T extends readonly [
unknown,
...ReadonlyArray<unknown>
] ? true : false;
/**
* Perfrom a transpose operation on a 2D tuple.
*/
export type TransposeTuple<T> = T extends readonly [
...(readonly [
...unknown[]
])
] ? T extends readonly [
] ? [
] : T extends readonly [
infer X extends ReadonlyArray<unknown>
] ? TransposeTupleSimpleCase<X> : T extends readonly [
infer X extends ReadonlyArray<unknown>,
...infer XS extends ReadonlyArray<ReadonlyArray<unknown>>
] ? PrependCol<X, TransposeTuple<XS>> : T : never;
export type PrependCol<T extends ReadonlyArray<unknown>, S extends ReadonlyArray<ReadonlyArray<unknown>>> = T extends readonly [
] ? S extends readonly [
] ? [
] : never : T extends readonly [
infer X,
...infer XS
] ? S extends readonly [
readonly [
...infer Y
],
...infer YS extends ReadonlyArray<ReadonlyArray<unknown>>
] ? [
[
X,
...Y
],
...PrependCol<XS, YS>
] : never : never;
export type TransposeTupleSimpleCase<T extends readonly [
...unknown[]
]> = T extends readonly [
] ? [
] : T extends readonly [
infer X,
...infer XS
] ? [
[
X
],
...TransposeTupleSimpleCase<XS>
] : never;
/**
* Convert a tuple to an intersection of each of its types.
*/
export type TupleToIntersection<T extends ReadonlyArray<unknown>> = {
[K in keyof T]: (x: T[K]) => void;
} extends Record<number, (x: infer I) => void> ? I : never;
/**
* Convert a union to a tuple.
*
* Warning: The order of the elements is non-deterministic.
* Warning 2: The union maybe me modified by the TypeScript engine before convertion.
* Warning 3: This implementation relies on a hack/limitation in TypeScript.
*/
export type UnionToTuple<T, L = LastOf<T>> = IsNever<T> extends true ? [
] : [
...UnionToTuple<Exclude<T, L>>,
L
];
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
export type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never;
/**
* Convert a tuple of tuples to a tuple of unions.
*/
export type TupleTupleToTupleUnion<T extends ReadonlyArray<ReadonlyArray<unknown>>> = {
[I in keyof T]: TupleToUnion<T[I]>;
};
/**
* Convert a tuple to a union.
*/
export type TupleToUnion<T extends ReadonlyArray<unknown>> = T extends readonly [
] ? never : T extends readonly [
infer Head,
...infer Rest
] ? Head | TupleToUnion<Rest> : never;
/**
* Assert that a type is of a given type.
*/
export type AssertType<Expected, T> = T extends Expected ? T : never;
/**
* Mapping of merge function URIs to the merge function type.
*/
export interface DeepMergeFunctionURItoKind<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, in out M> {
readonly DeepMergeLeafURI: DeepMergeLeaf<Ts, Fs, M>;
readonly DeepMergeRecordsDefaultURI: DeepMergeRecordsDefaultHKT<Ts, Fs, M>;
readonly DeepMergeArraysDefaultURI: DeepMergeArraysDefaultHKT<Ts, Fs, M>;
readonly DeepMergeSetsDefaultURI: DeepMergeSetsDefaultHKT<Ts>;
readonly DeepMergeMapsDefaultURI: DeepMergeMapsDefaultHKT<Ts>;
readonly DeepMergeFilterValuesDefaultURI: DeepMergeFilterValuesDefaultHKT<Ts>;
readonly DeepMergeNoFilteringURI: Ts;
}
/**
* Get the type of the given merge function via its URI.
*/
export type DeepMergeFunctionKind<URI extends DeepMergeFunctionURIs, Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionURItoKind<Ts, Fs, M>[URI];
/**
* A union of all valid merge function URIs.
*/
export type DeepMergeFunctionURIs = keyof DeepMergeFunctionURItoKind<ReadonlyArray<unknown>, DeepMergeFunctionsURIs, unknown>;
/**
* The merge functions to use when deep merging.
*/
export type DeepMergeFunctionsURIs = Readonly<{
/**
* The merge function to merge records with.
*/
DeepMergeRecordsURI: DeepMergeFunctionURIs;
/**
* The merge function to merge arrays with.
*/
DeepMergeArraysURI: DeepMergeFunctionURIs;
/**
* The merge function to merge sets with.
*/
DeepMergeSetsURI: DeepMergeFunctionURIs;
/**
* The merge function to merge maps with.
*/
DeepMergeMapsURI: DeepMergeFunctionURIs;
/**
* The merge function to merge other things with.
*/
DeepMergeOthersURI: DeepMergeFunctionURIs;
/**
* The function to filter values.
*/
DeepMergeFilterValuesURI: DeepMergeFunctionURIs;
}>;
/**
* Deep merge types.
*/
export type DeepMergeHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = IsTuple<Ts> extends true ? Ts extends readonly [
] ? undefined : DeepMergeHKTHelper<FilterValuesHKT<Ts, Fs, M>, Fs, M> : unknown;
export type DeepMergeHKTHelper<Ts, Fs extends DeepMergeFunctionsURIs, M> = Ts extends ReadonlyArray<unknown> ? IsTuple<Ts> extends true ? Ts extends readonly [
] ? unknown : Ts extends readonly [
infer T1
] ? T1 : EveryIsArray<Ts> extends true ? DeepMergeArraysHKT<Ts, Fs, M> : EveryIsMap<Ts> extends true ? DeepMergeMapsHKT<Ts, Fs, M> : EveryIsSet<Ts> extends true ? DeepMergeSetsHKT<Ts, Fs, M> : EveryIsRecord<Ts> extends true ? DeepMergeRecordsHKT<Ts, Fs, M> : DeepMergeOthersHKT<Ts, Fs, M> : unknown : never;
/**
* Deep merge records.
*/
export type DeepMergeRecordsHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeRecordsURI"], Ts, Fs, M>;
/**
* Deep merge arrays.
*/
export type DeepMergeArraysHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeArraysURI"], Ts, Fs, M>;
/**
* Deep merge sets.
*/
export type DeepMergeSetsHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeSetsURI"], Ts, Fs, M>;
/**
* Deep merge maps.
*/
export type DeepMergeMapsHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeMapsURI"], Ts, Fs, M>;
/**
* Deep merge other things.
*/
export type DeepMergeOthersHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeOthersURI"], Ts, Fs, M>;
/**
* Filter values.
*/
export type FilterValuesHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeFunctionKind<Fs["DeepMergeFilterValuesURI"], Ts, Fs, M>;
/**
* The merge function that returns a leaf.
*/
export type DeepMergeLeafURI = "DeepMergeLeafURI";
/**
* Don't filter values.
*/
export type DeepMergeNoFilteringURI = "DeepMergeNoFilteringURI";
/**
* Get the leaf type from many types that can't be merged.
*/
export type DeepMergeLeaf<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = Ts extends readonly [
] ? never : Ts extends readonly [
infer T
] ? T : Ts extends readonly [
...infer Rest,
infer Tail
] ? IsNever<Tail> extends true ? Rest extends ReadonlyArray<unknown> ? DeepMergeLeaf<Rest, Fs, M> : never : DeepMergeLeafApplyFilter<Ts, AssertType<ReadonlyArray<unknown>, TupleTupleToTupleUnion<AssertType<ReadonlyArray<ReadonlyArray<unknown>>, {
[I in keyof Ts]: FilterValuesHKT<UnionToTuple<Ts[I]>, Fs, M>;
}>>>> : never;
export type DeepMergeLeafApplyFilter<Original extends ReadonlyArray<unknown>, Filtered extends ReadonlyArray<unknown>> = Original extends readonly [
...infer OriginalRest,
infer OriginalTail
] ? Filtered extends readonly [
...infer FilteredRest,
infer FilteredTail
] ? OriginalTail extends FilteredTail ? FilteredTail : FilteredTail | DeepMergeLeafApplyFilter<OriginalRest, FilteredRest> : never : never;
/**
* The meta data deepmerge is able to provide.
*/
export type DeepMergeBuiltInMetaData = Readonly<{
key: PropertyKey;
parents: ReadonlyArray<Readonly<Record<PropertyKey, unknown>>>;
}>;
/**
* The default merge function to merge records with.
*/
export type DeepMergeRecordsDefaultURI = "DeepMergeRecordsDefaultURI";
/**
* The default merge function to merge arrays with.
*/
export type DeepMergeArraysDefaultURI = "DeepMergeArraysDefaultURI";
/**
* The default merge function to merge sets with.
*/
export type DeepMergeSetsDefaultURI = "DeepMergeSetsDefaultURI";
/**
* The default merge function to merge maps with.
*/
export type DeepMergeMapsDefaultURI = "DeepMergeMapsDefaultURI";
/**
* The default filter values function.
*/
export type DeepMergeFilterValuesDefaultURI = "DeepMergeFilterValuesDefaultURI";
/**
* The default merge functions to use when deep merging.
*/
export type DeepMergeFunctionsDefaultURIs = Readonly<{
DeepMergeRecordsURI: DeepMergeRecordsDefaultURI;
DeepMergeArraysURI: DeepMergeArraysDefaultURI;
DeepMergeSetsURI: DeepMergeSetsDefaultURI;
DeepMergeMapsURI: DeepMergeMapsDefaultURI;
DeepMergeOthersURI: DeepMergeLeafURI;
DeepMergeFilterValuesURI: DeepMergeFilterValuesDefaultURI;
}>;
export type RecordEntries<T extends Record<PropertyKey, unknown>> = FilterOut<UnionToTuple<{
[K in keyof T]: [
K,
T[K]
];
}[keyof T]>, undefined>;
export type RecordMeta = Record<PropertyKey, RecordPropertyMeta>;
export type RecordPropertyMeta<Key extends PropertyKey = PropertyKey, Value = unknown, Optional extends boolean = boolean> = {
key: Key;
value: Value;
optional: Optional;
};
export type RecordsToRecordMeta<Ts extends ReadonlyArray<Record<PropertyKey, unknown>>> = FilterOutNever<{
[I in keyof Ts]: RecordToRecordMeta<Ts[I]>;
}>;
export type RecordToRecordMeta<T extends Record<PropertyKey, unknown>> = {
[K in keyof T]-?: {
key: K;
value: Required<T>[K];
optional: KeyIsOptional<K, T>;
};
};
/**
* Deep merge records.
*/
export type DeepMergeRecordsDefaultHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = Ts extends ReadonlyArray<Record<PropertyKey, unknown>> ? SimplifyObject<DeepMergeRecordMetaDefaultHKTProps<RecordsToRecordMeta<Ts>, Fs, M>> : never;
/**
* Deep merge record props.
*/
export type DeepMergeRecordMetaDefaultHKTProps<RecordMetas, Fs extends DeepMergeFunctionsURIs, M> = RecordMetas extends ReadonlyArray<RecordMeta> ? CreateRecordFromMeta<MergeRecordMeta<RecordMetas>, Fs, M> : never;
export type MergeRecordMeta<RecordMetas extends ReadonlyArray<RecordMeta>> = GroupValuesByKey<FlattenTuples<TransposeTuple<FilterOut<{
[I in keyof RecordMetas]: TransposeTuple<RecordEntries<RecordMetas[I]>>;
}, readonly [
]>>>>;
export type GroupValuesByKey<Ts> = Ts extends readonly [
infer Keys extends ReadonlyArray<PropertyKey>,
infer Values
] ? {
[I in keyof Keys]: DeepMergeRecordPropertyMetaDefaultHKTGetPossible<Keys[I], FilterOutNever<{
[J in keyof Values]: Values[J] extends {
key: Keys[I];
} ? Values[J] : never;
}>>;
} : never;
export type CreateRecordFromMeta<Ts, Fs extends DeepMergeFunctionsURIs, M> = Ts extends ReadonlyArray<unknown> ? TupleToIntersection<{
[I in keyof Ts]: Ts[I] extends {
key: infer Key extends PropertyKey;
values: infer Values extends ReadonlyArray<unknown>;
optional: infer O extends boolean;
} ? CreateRecordForKeyFromMeta<Key, Values, O, Fs, M> : never;
}> : never;
export type CreateRecordForKeyFromMeta<Key extends PropertyKey, Values extends ReadonlyArray<unknown>, Optional extends boolean, Fs extends DeepMergeFunctionsURIs, M> = Optional extends true ? {
[k in Key]+?: DeepMergeHKT<Values, Fs, M>;
} : {
[k in Key]-?: DeepMergeHKT<Values, Fs, M>;
};
/**
* Get the possible types of a property.
*/
export type DeepMergeRecordPropertyMetaDefaultHKTGetPossible<Key extends PropertyKey, Ts> = Ts extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Ts, {
key: Key;
values: [
];
optional: never;
}> : never;
/**
* Tail-recursive helper type for DeepMergeRecordPropertyMetaDefaultHKTGetPossible.
*/
export type DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Ts extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
], Acc extends {
key: PropertyKey;
values: ReadonlyArray<unknown>;
optional: boolean;
}> = Ts extends [
...infer Rest,
{
key: infer K extends PropertyKey;
value: infer V;
optional: infer O extends boolean;
}
] ? Acc["optional"] extends true ? Acc extends {
values: [
infer Head,
...infer AccRest
];
} ? Rest extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Rest, {
key: K;
values: [
PreciseOrUnion<V, Head>,
...AccRest
];
optional: O;
}> : {
key: K;
values: [
PreciseOrUnion<V, Head>,
...AccRest
];
optional: O;
} : Rest extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Rest, {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
}> : {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
} : Rest extends readonly [
RecordPropertyMeta,
...ReadonlyArray<RecordPropertyMeta>
] ? DeepMergeRecordPropertyMetaDefaultHKTGetPossibleHelper<Rest, {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
}> : {
key: K;
values: [
V,
...Acc["values"]
];
optional: O;
} : never;
/**
* Deep merge arrays.
*/
export type DeepMergeArraysDefaultHKT<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M> = DeepMergeArraysDefaultHKTHelper<Ts, Fs, M, [
]>;
/**
* Tail-recursive helper type for DeepMergeArraysDefaultHKT.
*/
export type DeepMergeArraysDefaultHKTHelper<Ts extends ReadonlyArray<unknown>, Fs extends DeepMergeFunctionsURIs, M, Acc extends ReadonlyArray<unknown>> = Ts extends readonly [
infer Head extends ReadonlyArray<unknown>,
...infer Rest
] ? Rest extends readonly [
ReadonlyArray<unknown>,
...ReadonlyArray<ReadonlyArray<unknown>>
] ? DeepMergeArraysDefaultHKTHelper<Rest, Fs, M, [
...Acc,
...Head
]> : [
...Acc,
...Head
] : never;
/**
* Deep merge sets.
*/
export type DeepMergeSetsDefaultHKT<Ts extends ReadonlyArray<unknown>> = Set<UnionSetValues<Ts>>;
/**
* Deep merge maps.
*/
export type DeepMergeMapsDefaultHKT<Ts extends ReadonlyArray<unknown>> = Map<UnionMapKeys<Ts>, UnionMapValues<Ts>>;
/**
* Filter out undefined values.
*/
export type DeepMergeFilterValuesDefaultHKT<Ts extends ReadonlyArray<unknown>> = FilterOut<Ts, undefined>;
/**
* Get the merge functions with defaults apply from the given subset.
*/
export type GetDeepMergeFunctionsURIs<PMF extends Partial<DeepMergeFunctionsURIs>> = Readonly<{
DeepMergeRecordsURI: PMF["DeepMergeRecordsURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeRecordsURI"] : DeepMergeRecordsDefaultURI;
DeepMergeArraysURI: PMF["DeepMergeArraysURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeArraysURI"] : DeepMergeArraysDefaultURI;
DeepMergeSetsURI: PMF["DeepMergeSetsURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeSetsURI"] : DeepMergeSetsDefaultURI;
DeepMergeMapsURI: PMF["DeepMergeMapsURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeMapsURI"] : DeepMergeMapsDefaultURI;
DeepMergeOthersURI: PMF["DeepMergeOthersURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeOthersURI"] : DeepMergeLeafURI;
DeepMergeFilterValuesURI: PMF["DeepMergeFilterValuesURI"] extends keyof DeepMergeFunctionURItoKind<any, any, any> ? PMF["DeepMergeFilterValuesURI"] : DeepMergeFilterValuesDefaultURI;
}>;
/**
* The default merge functions.
*/
type MergeFunctions = {
mergeRecords: typeof mergeRecordsInto;
mergeArrays: typeof mergeArraysInto;
mergeSets: typeof mergeSetsInto;
mergeMaps: typeof mergeMapsInto;
mergeOthers: typeof mergeOthersInto;
};
declare function mergeRecordsInto<Ts extends ReadonlyArray<Record<PropertyKey, unknown>>, U extends DeepMergeIntoFunctionUtils<M, MM>, M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(mut_target: Reference<Record<PropertyKey, unknown>>, values: Ts, utils: U, meta: M | undefined): void;
declare function mergeArraysInto<Ts extends ReadonlyArray<ReadonlyArray<unknown>>>(mut_target: Reference<unknown[]>, values: Ts): void;
declare function mergeSetsInto<Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>>(mut_target: Reference<Set<unknown>>, values: Ts): void;
declare function mergeMapsInto<Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>>(mut_target: Reference<Map<unknown, unknown>>, values: Ts): void;
declare function mergeOthersInto<Ts extends ReadonlyArray<unknown>>(mut_target: Reference<unknown>, values: Ts): void;
/**
* The default merge functions.
*/
type MergeFunctions$1 = {
mergeRecords: typeof mergeRecords;
mergeArrays: typeof mergeArrays;
mergeSets: typeof mergeSets;
mergeMaps: typeof mergeMaps;
mergeOthers: typeof mergeOthers;
};
declare function mergeRecords<Ts extends ReadonlyArray<Record<PropertyKey, unknown>>, U extends DeepMergeUtils<M, MM>, Fs extends DeepMergeFunctionsURIs, M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(values: Ts, utils: U, meta: M | undefined): DeepMergeRecordsDefaultHKT<Ts, Fs, M>;
declare function mergeArrays<Ts extends ReadonlyArray<ReadonlyArray<unknown>>, Fs extends DeepMergeFunctionsURIs, M>(values: Ts): DeepMergeArraysDefaultHKT<Ts, Fs, M>;
declare function mergeSets<Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>>(values: Ts): DeepMergeSetsDefaultHKT<Ts>;
declare function mergeMaps<Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>>(values: Ts): DeepMergeMapsDefaultHKT<Ts>;
declare function mergeOthers<Ts extends ReadonlyArray<unknown>>(values: Ts): unknown;
/**
* The options the user can pass to customize deepmerge.
*/
export type DeepMergeOptions<in out M, MM extends Readonly<Record<PropertyKey, unknown>> = {}> = Partial<DeepMergeOptionsFull<M, MM & DeepMergeBuiltInMetaData>>;
/**
* The options the user can pass to customize deepmergeInto.
*/
export type DeepMergeIntoOptions<in out M, MM extends Readonly<Record<PropertyKey, unknown>> = {}> = Partial<DeepMergeIntoOptionsFull<M, MM & DeepMergeBuiltInMetaData>>;
export type MetaDataUpdater<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = (previousMeta: M | undefined, metaMeta: Readonly<Partial<MM>>) => M;
/**
* All the options the user can pass to customize deepmerge.
*/
export type DeepMergeOptionsFull<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: DeepMergeFunctions<M, MM>["mergeRecords"] | false;
mergeArrays: DeepMergeFunctions<M, MM>["mergeArrays"] | false;
mergeMaps: DeepMergeFunctions<M, MM>["mergeMaps"] | false;
mergeSets: DeepMergeFunctions<M, MM>["mergeSets"] | false;
mergeOthers: DeepMergeFunctions<M, MM>["mergeOthers"];
metaDataUpdater: MetaDataUpdater<M, MM>;
enableImplicitDefaultMerging: boolean;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | false;
}>;
/**
* All the options the user can pass to customize deepmergeInto.
*/
export type DeepMergeIntoOptionsFull<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: DeepMergeIntoFunctions<M, MM>["mergeRecords"] | false;
mergeArrays: DeepMergeIntoFunctions<M, MM>["mergeArrays"] | false;
mergeMaps: DeepMergeIntoFunctions<M, MM>["mergeMaps"] | false;
mergeSets: DeepMergeIntoFunctions<M, MM>["mergeSets"] | false;
mergeOthers: DeepMergeIntoFunctions<M, MM>["mergeOthers"];
metaDataUpdater: MetaDataUpdater<M, MM>;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | false;
}>;
/**
* An object that has a reference to a value.
*/
type Reference<T> = {
value: T;
};
/**
* All the utility functions that can be overridden.
*/
export type DeepMergeUtilityFunctions<in M> = Readonly<{
filterValues: <Ts extends ReadonlyArray<unknown>>(values: Ts, meta: M | undefined) => unknown[];
}>;
/**
* All the merge functions that deepmerge uses.
*/
export type DeepMergeFunctions<in M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: <Ts extends ReadonlyArray<Readonly<Record<PropertyKey, unknown>>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeArrays: <Ts extends ReadonlyArray<ReadonlyArray<unknown>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeMaps: <Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeSets: <Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
mergeOthers: <Ts extends ReadonlyArray<unknown>, U extends DeepMergeUtils<M, MM>>(values: Ts, utils: U, meta: M | undefined) => unknown;
}>;
export type DeepMergeIntoFunctionsReturnType = void | symbol;
/**
* All the merge functions that deepmerge uses.
*/
export type DeepMergeIntoFunctions<in M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeRecords: <Ts extends ReadonlyArray<Readonly<Record<PropertyKey, unknown>>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<Record<PropertyKey, unknown>>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeArrays: <Ts extends ReadonlyArray<ReadonlyArray<unknown>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<unknown[]>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeMaps: <Ts extends ReadonlyArray<Readonly<ReadonlyMap<unknown, unknown>>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<Map<unknown, unknown>>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeSets: <Ts extends ReadonlyArray<Readonly<ReadonlySet<unknown>>>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<Set<unknown>>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
mergeOthers: <Ts extends ReadonlyArray<unknown>, U extends DeepMergeIntoFunctionUtils<M, MM>>(mut_target: Reference<unknown>, values: Ts, utils: U, meta: M | undefined) => DeepMergeIntoFunctionsReturnType;
}>;
/**
* The utils provided to the merge functions.
*/
export type DeepMergeUtils<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeFunctions: DeepMergeFunctions<M, MM>;
defaultMergeFunctions: MergeFunctions$1;
metaDataUpdater: MetaDataUpdater<M, MM>;
deepmerge: <Ts extends ReadonlyArray<unknown>>(...values: Ts) => unknown;
useImplicitDefaultMerging: boolean;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | undefined;
actions: Readonly<{
defaultMerge: symbol;
skip: symbol;
}>;
}>;
/**
* The utils provided to the merge functions.
*/
export type DeepMergeIntoFunctionUtils<in out M, MM extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData> = Readonly<{
mergeFunctions: DeepMergeIntoFunctions<M, MM>;
defaultMergeFunctions: MergeFunctions;
metaDataUpdater: MetaDataUpdater<M, MM>;
deepmergeInto: <Target extends object, Ts extends ReadonlyArray<unknown>>(target: Target, ...values: Ts) => void;
filterValues: DeepMergeUtilityFunctions<M>["filterValues"] | undefined;
actions: Readonly<{
defaultMerge: symbol;
}>;
}>;
/**
* Deeply merge objects.
*
* @param objects - The objects to merge.
*/
export declare function deepmerge<Ts extends Readonly<ReadonlyArray<unknown>>>(...objects: readonly [
...Ts
]): DeepMergeHKT<Ts, DeepMergeFunctionsDefaultURIs, DeepMergeBuiltInMetaData>;
/**
* Deeply merge two or more objects using the given options.
*
* @param options - The options on how to customize the merge function.
*/
export declare function deepmergeCustom<BaseTs = unknown, PMF extends Partial<DeepMergeFunctionsURIs> = {}>(options: DeepMergeOptions<DeepMergeBuiltInMetaData, DeepMergeBuiltInMetaData>): <Ts extends ReadonlyArray<BaseTs>>(...objects: Ts) => DeepMergeHKT<Ts, GetDeepMergeFunctionsURIs<PMF>, DeepMergeBuiltInMetaData>;
/**
* Deeply merge two or more objects using the given options and meta data.
*
* @param options - The options on how to customize the merge function.
* @param rootMetaData - The meta data passed to the root items' being merged.
*/
export declare function deepmergeCustom<BaseTs = unknown, PMF extends Partial<DeepMergeFunctionsURIs> = {}, MetaData = DeepMergeBuiltInMetaData, MetaMetaData extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(options: DeepMergeOptions<MetaData, MetaMetaData>, rootMetaData?: MetaData): <Ts extends ReadonlyArray<BaseTs>>(...objects: Ts) => DeepMergeHKT<Ts, GetDeepMergeFunctionsURIs<PMF>, MetaData>;
/**
* Deeply merge objects into a target.
*
* @param target - This object will be mutated with the merge result.
* @param objects - The objects to merge into the target.
*/
export declare function deepmergeInto<T extends object>(target: T, ...objects: ReadonlyArray<T>): void;
/**
* Deeply merge objects into a target.
*
* @param target - This object will be mutated with the merge result.
* @param objects - The objects to merge into the target.
*/
export declare function deepmergeInto<Target extends object, Ts extends ReadonlyArray<unknown>>(target: Target, ...objects: Ts): asserts target is SimplifyObject<Target & DeepMergeHKT<[
Target,
...Ts
], DeepMergeFunctionsDefaultURIs, DeepMergeBuiltInMetaData>>;
/**
* Deeply merge two or more objects using the given options.
*
* @param options - The options on how to customize the merge function.
*/
export declare function deepmergeIntoCustom<BaseTs = unknown>(options: DeepMergeIntoOptions<DeepMergeBuiltInMetaData, DeepMergeBuiltInMetaData>): <Target extends object, Ts extends ReadonlyArray<BaseTs>>(target: Target, ...objects: Ts) => void;
/**
* Deeply merge two or more objects using the given options and meta data.
*
* @param options - The options on how to customize the merge function.
* @param rootMetaData - The meta data passed to the root items' being merged.
*/
export declare function deepmergeIntoCustom<BaseTs = unknown, MetaData = DeepMergeBuiltInMetaData, MetaMetaData extends DeepMergeBuiltInMetaData = DeepMergeBuiltInMetaData>(options: DeepMergeIntoOptions<MetaData, MetaMetaData>, rootMetaData?: MetaData): <Target extends object, Ts extends ReadonlyArray<BaseTs>>(target: Target, ...objects: Ts) => void;
/**
* The different types of objects deepmerge-ts support.
*/
export declare const enum ObjectType {
NOT = 0,
RECORD = 1,
ARRAY = 2,
SET = 3,
MAP = 4,
OTHER = 5
}
/**
* Get the type of the given object.
*
* @param object - The object to get the type of.
* @returns The type of the given object.
*/
export declare function getObjectType(object: unknown): ObjectType;
/**
* Get the keys of the given objects including symbol keys.
*
* Note: Only keys to enumerable properties are returned.
*
* @param objects - An array of objects to get the keys of.
* @returns A set containing all the keys of all the given objects.
*/
export declare function getKeys(objects: ReadonlyArray<object>): Set<PropertyKey>;
/**
* Does the given object have the given property.
*
* @param object - The object to test.
* @param property - The property to test.
* @returns Whether the object has the property.
*/
export declare function objectHasProperty(object: object, property: PropertyKey): boolean;
export {
MergeFunctions as DeepMergeIntoFunctionsDefaults,
MergeFunctions$1 as DeepMergeFunctionsDefaults,
Reference as DeepMergeValueReference,
};
export {};

View file

@ -0,0 +1,611 @@
/**
* Special values that tell deepmerge to perform a certain action.
*/
const actions = {
defaultMerge: Symbol("deepmerge-ts: default merge"),
skip: Symbol("deepmerge-ts: skip"),
};
/**
* Special values that tell deepmergeInto to perform a certain action.
*/
const actionsInto = {
defaultMerge: actions.defaultMerge,
};
/**
* The default function to update meta data.
*
* It doesn't update the meta data.
*/
function defaultMetaDataUpdater(previousMeta, metaMeta) {
return metaMeta;
}
/**
* The default function to filter values.
*
* It filters out undefined values.
*/
function defaultFilterValues(values, meta) {
return values.filter((value) => value !== undefined);
}
/**
* The different types of objects deepmerge-ts support.
*/
var ObjectType;
(function (ObjectType) {
ObjectType[ObjectType["NOT"] = 0] = "NOT";
ObjectType[ObjectType["RECORD"] = 1] = "RECORD";
ObjectType[ObjectType["ARRAY"] = 2] = "ARRAY";
ObjectType[ObjectType["SET"] = 3] = "SET";
ObjectType[ObjectType["MAP"] = 4] = "MAP";
ObjectType[ObjectType["OTHER"] = 5] = "OTHER";
})(ObjectType || (ObjectType = {}));
/**
* Get the type of the given object.
*
* @param object - The object to get the type of.
* @returns The type of the given object.
*/
function getObjectType(object) {
if (typeof object !== "object" || object === null) {
return 0 /* ObjectType.NOT */;
}
if (Array.isArray(object)) {
return 2 /* ObjectType.ARRAY */;
}
if (isRecord(object)) {
return 1 /* ObjectType.RECORD */;
}
if (object instanceof Set) {
return 3 /* ObjectType.SET */;
}
if (object instanceof Map) {
return 4 /* ObjectType.MAP */;
}
return 5 /* ObjectType.OTHER */;
}
/**
* Get the keys of the given objects including symbol keys.
*
* Note: Only keys to enumerable properties are returned.
*
* @param objects - An array of objects to get the keys of.
* @returns A set containing all the keys of all the given objects.
*/
function getKeys(objects) {
const keys = new Set();
for (const object of objects) {
for (const key of [...Object.keys(object), ...Object.getOwnPropertySymbols(object)]) {
keys.add(key);
}
}
return keys;
}
/**
* Does the given object have the given property.
*
* @param object - The object to test.
* @param property - The property to test.
* @returns Whether the object has the property.
*/
function objectHasProperty(object, property) {
return typeof object === "object" && Object.prototype.propertyIsEnumerable.call(object, property);
}
/**
* Get an iterable object that iterates over the given iterables.
*/
function getIterableOfIterables(iterables) {
let mut_iterablesIndex = 0;
let mut_iterator = iterables[0]?.[Symbol.iterator]();
return {
[Symbol.iterator]() {
return {
next() {
do {
if (mut_iterator === undefined) {
return { done: true, value: undefined };
}
const result = mut_iterator.next();
if (result.done === true) {
mut_iterablesIndex += 1;
mut_iterator = iterables[mut_iterablesIndex]?.[Symbol.iterator]();
continue;
}
return {
done: false,
value: result.value,
};
} while (true);
},
};
},
};
}
// eslint-disable-next-line unicorn/prefer-set-has -- Array is more performant for a low number of elements.
const validRecordToStringValues = ["[object Object]", "[object Module]"];
/**
* Does the given object appear to be a record.
*/
function isRecord(value) {
// All records are objects.
if (!validRecordToStringValues.includes(Object.prototype.toString.call(value))) {
return false;
}
const { constructor } = value;
// If has modified constructor.
// eslint-disable-next-line ts/no-unnecessary-condition
if (constructor === undefined) {
return true;
}
const prototype = constructor.prototype;
// If has modified prototype.
if (prototype === null ||
typeof prototype !== "object" ||
!validRecordToStringValues.includes(Object.prototype.toString.call(prototype))) {
return false;
}
// If constructor does not have an Object-specific method.
// eslint-disable-next-line sonar/prefer-single-boolean-return, no-prototype-builtins
if (!prototype.hasOwnProperty("isPrototypeOf")) {
return false;
}
// Most likely a record.
return true;
}
/**
* The default strategy to merge records.
*
* @param values - The records.
*/
function mergeRecords$1(values, utils, meta) {
const result = {};
for (const key of getKeys(values)) {
const propValues = [];
for (const value of values) {
if (objectHasProperty(value, key)) {
propValues.push(value[key]);
}
}
if (propValues.length === 0) {
continue;
}
const updatedMeta = utils.metaDataUpdater(meta, {
key,
parents: values,
});
const propertyResult = mergeUnknowns(propValues, utils, updatedMeta);
if (propertyResult === actions.skip) {
continue;
}
if (key === "__proto__") {
Object.defineProperty(result, key, {
value: propertyResult,
configurable: true,
enumerable: true,
writable: true,
});
}
else {
result[key] = propertyResult;
}
}
return result;
}
/**
* The default strategy to merge arrays.
*
* @param values - The arrays.
*/
function mergeArrays$1(values) {
return values.flat();
}
/**
* The default strategy to merge sets.
*
* @param values - The sets.
*/
function mergeSets$1(values) {
return new Set(getIterableOfIterables(values));
}
/**
* The default strategy to merge maps.
*
* @param values - The maps.
*/
function mergeMaps$1(values) {
return new Map(getIterableOfIterables(values));
}
/**
* Get the last value in the given array.
*/
function mergeOthers$1(values) {
return values.at(-1);
}
/**
* The merge functions.
*/
const mergeFunctions = {
mergeRecords: mergeRecords$1,
mergeArrays: mergeArrays$1,
mergeSets: mergeSets$1,
mergeMaps: mergeMaps$1,
mergeOthers: mergeOthers$1,
};
/**
* Deeply merge objects.
*
* @param objects - The objects to merge.
*/
function deepmerge(...objects) {
return deepmergeCustom({})(...objects);
}
function deepmergeCustom(options, rootMetaData) {
const utils = getUtils(options, customizedDeepmerge);
/**
* The customized deepmerge function.
*/
function customizedDeepmerge(...objects) {
return mergeUnknowns(objects, utils, rootMetaData);
}
return customizedDeepmerge;
}
/**
* The the utils that are available to the merge functions.
*
* @param options - The options the user specified
*/
function getUtils(options, customizedDeepmerge) {
return {
defaultMergeFunctions: mergeFunctions,
mergeFunctions: {
...mergeFunctions,
...Object.fromEntries(Object.entries(options)
.filter(([key, option]) => Object.hasOwn(mergeFunctions, key))
.map(([key, option]) => (option === false ? [key, mergeFunctions.mergeOthers] : [key, option]))),
},
metaDataUpdater: (options.metaDataUpdater ?? defaultMetaDataUpdater),
deepmerge: customizedDeepmerge,
useImplicitDefaultMerging: options.enableImplicitDefaultMerging ?? false,
filterValues: options.filterValues === false ? undefined : (options.filterValues ?? defaultFilterValues),
actions,
};
}
/**
* Merge unknown things.
*
* @param values - The values.
*/
function mergeUnknowns(values, utils, meta) {
const filteredValues = utils.filterValues?.(values, meta) ?? values;
if (filteredValues.length === 0) {
return undefined;
}
if (filteredValues.length === 1) {
return mergeOthers(filteredValues, utils, meta);
}
const type = getObjectType(filteredValues[0]);
if (type !== 0 /* ObjectType.NOT */ && type !== 5 /* ObjectType.OTHER */) {
for (let mut_index = 1; mut_index < filteredValues.length; mut_index++) {
if (getObjectType(filteredValues[mut_index]) === type) {
continue;
}
return mergeOthers(filteredValues, utils, meta);
}
}
switch (type) {
case 1 /* ObjectType.RECORD */: {
return mergeRecords(filteredValues, utils, meta);
}
case 2 /* ObjectType.ARRAY */: {
return mergeArrays(filteredValues, utils, meta);
}
case 3 /* ObjectType.SET */: {
return mergeSets(filteredValues, utils, meta);
}
case 4 /* ObjectType.MAP */: {
return mergeMaps(filteredValues, utils, meta);
}
default: {
return mergeOthers(filteredValues, utils, meta);
}
}
}
/**
* Merge records.
*
* @param values - The records.
*/
function mergeRecords(values, utils, meta) {
const result = utils.mergeFunctions.mergeRecords(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeRecords !== utils.defaultMergeFunctions.mergeRecords)) {
return utils.defaultMergeFunctions.mergeRecords(values, utils, meta);
}
return result;
}
/**
* Merge arrays.
*
* @param values - The arrays.
*/
function mergeArrays(values, utils, meta) {
const result = utils.mergeFunctions.mergeArrays(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeArrays !== utils.defaultMergeFunctions.mergeArrays)) {
return utils.defaultMergeFunctions.mergeArrays(values);
}
return result;
}
/**
* Merge sets.
*
* @param values - The sets.
*/
function mergeSets(values, utils, meta) {
const result = utils.mergeFunctions.mergeSets(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeSets !== utils.defaultMergeFunctions.mergeSets)) {
return utils.defaultMergeFunctions.mergeSets(values);
}
return result;
}
/**
* Merge maps.
*
* @param values - The maps.
*/
function mergeMaps(values, utils, meta) {
const result = utils.mergeFunctions.mergeMaps(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeMaps !== utils.defaultMergeFunctions.mergeMaps)) {
return utils.defaultMergeFunctions.mergeMaps(values);
}
return result;
}
/**
* Merge other things.
*
* @param values - The other things.
*/
function mergeOthers(values, utils, meta) {
const result = utils.mergeFunctions.mergeOthers(values, utils, meta);
if (result === actions.defaultMerge ||
(utils.useImplicitDefaultMerging &&
result === undefined &&
utils.mergeFunctions.mergeOthers !== utils.defaultMergeFunctions.mergeOthers)) {
return utils.defaultMergeFunctions.mergeOthers(values);
}
return result;
}
/**
* The default strategy to merge records into a target record.
*
* @param mut_target - The result will be mutated into this record
* @param values - The records (including the target's value if there is one).
*/
function mergeRecordsInto$1(mut_target, values, utils, meta) {
for (const key of getKeys(values)) {
const propValues = [];
for (const value of values) {
if (objectHasProperty(value, key)) {
propValues.push(value[key]);
}
}
if (propValues.length === 0) {
continue;
}
const updatedMeta = utils.metaDataUpdater(meta, {
key,
parents: values,
});
const propertyTarget = { value: propValues[0] };
mergeUnknownsInto(propertyTarget, propValues, utils, updatedMeta);
if (key === "__proto__") {
Object.defineProperty(mut_target.value, key, {
value: propertyTarget.value,
configurable: true,
enumerable: true,
writable: true,
});
}
else {
mut_target.value[key] = propertyTarget.value;
}
}
}
/**
* The default strategy to merge arrays into a target array.
*
* @param mut_target - The result will be mutated into this array
* @param values - The arrays (including the target's value if there is one).
*/
function mergeArraysInto$1(mut_target, values) {
mut_target.value.push(...values.slice(1).flat());
}
/**
* The default strategy to merge sets into a target set.
*
* @param mut_target - The result will be mutated into this set
* @param values - The sets (including the target's value if there is one).
*/
function mergeSetsInto$1(mut_target, values) {
for (const value of getIterableOfIterables(values.slice(1))) {
mut_target.value.add(value);
}
}
/**
* The default strategy to merge maps into a target map.
*
* @param mut_target - The result will be mutated into this map
* @param values - The maps (including the target's value if there is one).
*/
function mergeMapsInto$1(mut_target, values) {
for (const [key, value] of getIterableOfIterables(values.slice(1))) {
mut_target.value.set(key, value);
}
}
/**
* Set the target to the last value.
*/
function mergeOthersInto$1(mut_target, values) {
mut_target.value = values.at(-1);
}
/**
* The merge functions.
*/
const mergeIntoFunctions = {
mergeRecords: mergeRecordsInto$1,
mergeArrays: mergeArraysInto$1,
mergeSets: mergeSetsInto$1,
mergeMaps: mergeMapsInto$1,
mergeOthers: mergeOthersInto$1,
};
function deepmergeInto(target, ...objects) {
return void deepmergeIntoCustom({})(target, ...objects);
}
function deepmergeIntoCustom(options, rootMetaData) {
const utils = getIntoUtils(options, customizedDeepmergeInto);
/**
* The customized deepmerge function.
*/
function customizedDeepmergeInto(target, ...objects) {
mergeUnknownsInto({ value: target }, [target, ...objects], utils, rootMetaData);
}
return customizedDeepmergeInto;
}
/**
* The the utils that are available to the merge functions.
*
* @param options - The options the user specified
*/
function getIntoUtils(options, customizedDeepmergeInto) {
return {
defaultMergeFunctions: mergeIntoFunctions,
mergeFunctions: {
...mergeIntoFunctions,
...Object.fromEntries(Object.entries(options)
.filter(([key, option]) => Object.hasOwn(mergeIntoFunctions, key))
.map(([key, option]) => (option === false ? [key, mergeIntoFunctions.mergeOthers] : [key, option]))),
},
metaDataUpdater: (options.metaDataUpdater ?? defaultMetaDataUpdater),
deepmergeInto: customizedDeepmergeInto,
filterValues: options.filterValues === false ? undefined : (options.filterValues ?? defaultFilterValues),
actions: actionsInto,
};
}
/**
* Merge unknown things into a target.
*
* @param mut_target - The target to merge into.
* @param values - The values.
*/
function mergeUnknownsInto(mut_target, values, utils, meta) {
const filteredValues = utils.filterValues?.(values, meta) ?? values;
if (filteredValues.length === 0) {
return;
}
if (filteredValues.length === 1) {
return void mergeOthersInto(mut_target, filteredValues, utils, meta);
}
const type = getObjectType(mut_target.value);
if (type !== 0 /* ObjectType.NOT */ && type !== 5 /* ObjectType.OTHER */) {
for (let mut_index = 1; mut_index < filteredValues.length; mut_index++) {
if (getObjectType(filteredValues[mut_index]) === type) {
continue;
}
return void mergeOthersInto(mut_target, filteredValues, utils, meta);
}
}
switch (type) {
case 1 /* ObjectType.RECORD */: {
return void mergeRecordsInto(mut_target, filteredValues, utils, meta);
}
case 2 /* ObjectType.ARRAY */: {
return void mergeArraysInto(mut_target, filteredValues, utils, meta);
}
case 3 /* ObjectType.SET */: {
return void mergeSetsInto(mut_target, filteredValues, utils, meta);
}
case 4 /* ObjectType.MAP */: {
return void mergeMapsInto(mut_target, filteredValues, utils, meta);
}
default: {
return void mergeOthersInto(mut_target, filteredValues, utils, meta);
}
}
}
/**
* Merge records into a target record.
*
* @param mut_target - The target to merge into.
* @param values - The records.
*/
function mergeRecordsInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeRecords(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeRecords(mut_target, values, utils, meta);
}
}
/**
* Merge arrays into a target array.
*
* @param mut_target - The target to merge into.
* @param values - The arrays.
*/
function mergeArraysInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeArrays(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeArrays(mut_target, values);
}
}
/**
* Merge sets into a target set.
*
* @param mut_target - The target to merge into.
* @param values - The sets.
*/
function mergeSetsInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeSets(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeSets(mut_target, values);
}
}
/**
* Merge maps into a target map.
*
* @param mut_target - The target to merge into.
* @param values - The maps.
*/
function mergeMapsInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeMaps(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeMaps(mut_target, values);
}
}
/**
* Merge other things into a target.
*
* @param mut_target - The target to merge into.
* @param values - The other things.
*/
function mergeOthersInto(mut_target, values, utils, meta) {
const action = utils.mergeFunctions.mergeOthers(mut_target, values, utils, meta);
if (action === actionsInto.defaultMerge || mut_target.value === actionsInto.defaultMerge) {
utils.defaultMergeFunctions.mergeOthers(mut_target, values);
}
}
export { deepmerge, deepmergeCustom, deepmergeInto, deepmergeIntoCustom, getKeys, getObjectType, objectHasProperty };