tsoa
This commit is contained in:
119
node_modules/ts-deepmerge/README.md
generated
vendored
Normal file
119
node_modules/ts-deepmerge/README.md
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
[](https://www.npmjs.com/package/ts-deepmerge)
|
||||
|
||||
TypeScript Deep Merge
|
||||
=====================
|
||||
|
||||
A deep merge function that automatically infers the return type based on your input,
|
||||
without mutating the source objects.
|
||||
|
||||
Objects and arrays will be merged, but values such as numbers and strings will be overwritten.
|
||||
|
||||
All merging/overwriting occurs in the order of the arguments you provide the function with.
|
||||
|
||||
Both ESM and CommonJS are supported by this package.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
```typescript jsx
|
||||
import { merge } from "ts-deepmerge";
|
||||
|
||||
const obj1 = {
|
||||
a: {
|
||||
a: 1
|
||||
}
|
||||
};
|
||||
|
||||
const obj2 = {
|
||||
b: {
|
||||
a: 2,
|
||||
b: 2
|
||||
}
|
||||
};
|
||||
|
||||
const obj3 = {
|
||||
a: {
|
||||
b: 3
|
||||
},
|
||||
b: {
|
||||
b: 3,
|
||||
c: 3
|
||||
},
|
||||
c: 3
|
||||
};
|
||||
|
||||
const result = merge(obj1, obj2, obj3);
|
||||
```
|
||||
|
||||
The value of the above `result` is:
|
||||
```json
|
||||
{
|
||||
"a": {
|
||||
"a": 1,
|
||||
"b": 3
|
||||
},
|
||||
"b": {
|
||||
"a": 2,
|
||||
"b": 3,
|
||||
"c": 3
|
||||
},
|
||||
"c": 3
|
||||
}
|
||||
```
|
||||
|
||||
### With options
|
||||
|
||||
If you would like to provide options to change the merge behaviour, you can use the `.withOptions` method:
|
||||
```typescript
|
||||
import { merge } from "ts-deepmerge";
|
||||
|
||||
const obj1 = {
|
||||
array: ["A"],
|
||||
};
|
||||
|
||||
const obj2 = {
|
||||
array: ["B"],
|
||||
}
|
||||
|
||||
const result = merge.withOptions(
|
||||
{ mergeArrays: false },
|
||||
obj1,
|
||||
obj2
|
||||
);
|
||||
```
|
||||
|
||||
The value of the above `result` is:
|
||||
```json
|
||||
{
|
||||
"array": ["B"]
|
||||
}
|
||||
```
|
||||
|
||||
All options have JSDoc descriptions [in its source](/src/index.ts#L87).
|
||||
|
||||
|
||||
### When working with generic declared types/interfaces
|
||||
|
||||
There's currently a limitation with the inferred return type that `ts-deepmerge` offers, where it's
|
||||
unable to take the order of the objects/properties into consideration due to the nature of accepting
|
||||
an infinite number of objects to merge as args and what TypeScript currently offers to infer the types.
|
||||
The primary use case for the inferred return type is for basic object primitives, to offer something
|
||||
more useful as the return type, which does work for a lot of cases.
|
||||
|
||||
If you're working with generic declared types though, this can cause the inferred return type to not align
|
||||
with what you may expect, as it currently detects every possible value and combines them as a union type.
|
||||
When working with declared types, and you know what the final type will align to, simply use the `as` keyword
|
||||
as shown in the example below:
|
||||
```typescript
|
||||
interface IObj {
|
||||
a: string;
|
||||
b: string;
|
||||
}
|
||||
|
||||
const obj1: IObj = { a: "1", b: "2", };
|
||||
const obj2: Partial<IObj> = { a: "1" };
|
||||
|
||||
const result = merge(obj1, obj2) as IObj;
|
||||
```
|
||||
|
||||
More context can be found in [this issue](https://github.com/voodoocreation/ts-deepmerge/issues/30).
|
||||
44
node_modules/ts-deepmerge/cjs/index.d.ts
generated
vendored
Normal file
44
node_modules/ts-deepmerge/cjs/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
type TAllKeys<T> = T extends any ? keyof T : never;
|
||||
type TIndexValue<T, K extends PropertyKey, D = never> = T extends any ? K extends keyof T ? T[K] : D : never;
|
||||
type TPartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>> extends infer O ? {
|
||||
[P in keyof O]: O[P];
|
||||
} : never;
|
||||
type TFunction = (...a: any[]) => any;
|
||||
type TPrimitives = string | number | boolean | bigint | symbol | Date | TFunction;
|
||||
type TMerged<T> = [T] extends [Array<any>] ? {
|
||||
[K in keyof T]: TMerged<T[K]>;
|
||||
} : [T] extends [TPrimitives] ? T : [T] extends [object] ? TPartialKeys<{
|
||||
[K in TAllKeys<T>]: TMerged<TIndexValue<T, K>>;
|
||||
}, never> : T;
|
||||
interface IObject {
|
||||
[key: string]: any;
|
||||
}
|
||||
export declare const merge: {
|
||||
<T extends IObject[]>(...objects: T): TMerged<T[number]>;
|
||||
options: IOptions;
|
||||
withOptions<T extends IObject[]>(options: Partial<IOptions>, ...objects: T): TMerged<T[number]>;
|
||||
};
|
||||
interface IOptions {
|
||||
/**
|
||||
* When `true`, values explicitly provided as `undefined` will override existing values, though properties that are simply omitted won't affect anything.
|
||||
* When `false`, values explicitly provided as `undefined` won't override existing values.
|
||||
*
|
||||
* Default: `true`
|
||||
*/
|
||||
allowUndefinedOverrides: boolean;
|
||||
/**
|
||||
* When `true` it will merge array properties.
|
||||
* When `false` it will replace array properties with the last instance entirely instead of merging their contents.
|
||||
*
|
||||
* Default: `true`
|
||||
*/
|
||||
mergeArrays: boolean;
|
||||
/**
|
||||
* When `true` it will ensure there are no duplicate array items.
|
||||
* When `false` it will allow duplicates when merging arrays.
|
||||
*
|
||||
* Default: `true`
|
||||
*/
|
||||
uniqueArrayItems: boolean;
|
||||
}
|
||||
export {};
|
||||
62
node_modules/ts-deepmerge/cjs/index.js
generated
vendored
Normal file
62
node_modules/ts-deepmerge/cjs/index.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.merge = void 0;
|
||||
// istanbul ignore next
|
||||
const isObject = (obj) => {
|
||||
if (typeof obj === "object" && obj !== null) {
|
||||
if (typeof Object.getPrototypeOf === "function") {
|
||||
const prototype = Object.getPrototypeOf(obj);
|
||||
return prototype === Object.prototype || prototype === null;
|
||||
}
|
||||
return Object.prototype.toString.call(obj) === "[object Object]";
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const merge = (...objects) => objects.reduce((result, current) => {
|
||||
if (current === undefined) {
|
||||
return result;
|
||||
}
|
||||
if (Array.isArray(current)) {
|
||||
throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays.");
|
||||
}
|
||||
Object.keys(current).forEach((key) => {
|
||||
if (["__proto__", "constructor", "prototype"].includes(key)) {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(result[key]) && Array.isArray(current[key])) {
|
||||
result[key] = exports.merge.options.mergeArrays
|
||||
? exports.merge.options.uniqueArrayItems
|
||||
? Array.from(new Set(result[key].concat(current[key])))
|
||||
: [...result[key], ...current[key]]
|
||||
: current[key];
|
||||
}
|
||||
else if (isObject(result[key]) && isObject(current[key])) {
|
||||
result[key] = (0, exports.merge)(result[key], current[key]);
|
||||
}
|
||||
else if (!isObject(result[key]) && isObject(current[key])) {
|
||||
result[key] = (0, exports.merge)(current[key], undefined);
|
||||
}
|
||||
else {
|
||||
result[key] =
|
||||
current[key] === undefined
|
||||
? exports.merge.options.allowUndefinedOverrides
|
||||
? current[key]
|
||||
: result[key]
|
||||
: current[key];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}, {});
|
||||
exports.merge = merge;
|
||||
const defaultOptions = {
|
||||
allowUndefinedOverrides: true,
|
||||
mergeArrays: true,
|
||||
uniqueArrayItems: true,
|
||||
};
|
||||
exports.merge.options = defaultOptions;
|
||||
exports.merge.withOptions = (options, ...objects) => {
|
||||
exports.merge.options = Object.assign(Object.assign({}, defaultOptions), options);
|
||||
const result = (0, exports.merge)(...objects);
|
||||
exports.merge.options = defaultOptions;
|
||||
return result;
|
||||
};
|
||||
3
node_modules/ts-deepmerge/cjs/package.json
generated
vendored
Normal file
3
node_modules/ts-deepmerge/cjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
44
node_modules/ts-deepmerge/esm/index.d.ts
generated
vendored
Normal file
44
node_modules/ts-deepmerge/esm/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
type TAllKeys<T> = T extends any ? keyof T : never;
|
||||
type TIndexValue<T, K extends PropertyKey, D = never> = T extends any ? K extends keyof T ? T[K] : D : never;
|
||||
type TPartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>> extends infer O ? {
|
||||
[P in keyof O]: O[P];
|
||||
} : never;
|
||||
type TFunction = (...a: any[]) => any;
|
||||
type TPrimitives = string | number | boolean | bigint | symbol | Date | TFunction;
|
||||
type TMerged<T> = [T] extends [Array<any>] ? {
|
||||
[K in keyof T]: TMerged<T[K]>;
|
||||
} : [T] extends [TPrimitives] ? T : [T] extends [object] ? TPartialKeys<{
|
||||
[K in TAllKeys<T>]: TMerged<TIndexValue<T, K>>;
|
||||
}, never> : T;
|
||||
interface IObject {
|
||||
[key: string]: any;
|
||||
}
|
||||
export declare const merge: {
|
||||
<T extends IObject[]>(...objects: T): TMerged<T[number]>;
|
||||
options: IOptions;
|
||||
withOptions<T extends IObject[]>(options: Partial<IOptions>, ...objects: T): TMerged<T[number]>;
|
||||
};
|
||||
interface IOptions {
|
||||
/**
|
||||
* When `true`, values explicitly provided as `undefined` will override existing values, though properties that are simply omitted won't affect anything.
|
||||
* When `false`, values explicitly provided as `undefined` won't override existing values.
|
||||
*
|
||||
* Default: `true`
|
||||
*/
|
||||
allowUndefinedOverrides: boolean;
|
||||
/**
|
||||
* When `true` it will merge array properties.
|
||||
* When `false` it will replace array properties with the last instance entirely instead of merging their contents.
|
||||
*
|
||||
* Default: `true`
|
||||
*/
|
||||
mergeArrays: boolean;
|
||||
/**
|
||||
* When `true` it will ensure there are no duplicate array items.
|
||||
* When `false` it will allow duplicates when merging arrays.
|
||||
*
|
||||
* Default: `true`
|
||||
*/
|
||||
uniqueArrayItems: boolean;
|
||||
}
|
||||
export {};
|
||||
58
node_modules/ts-deepmerge/esm/index.js
generated
vendored
Normal file
58
node_modules/ts-deepmerge/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// istanbul ignore next
|
||||
const isObject = (obj) => {
|
||||
if (typeof obj === "object" && obj !== null) {
|
||||
if (typeof Object.getPrototypeOf === "function") {
|
||||
const prototype = Object.getPrototypeOf(obj);
|
||||
return prototype === Object.prototype || prototype === null;
|
||||
}
|
||||
return Object.prototype.toString.call(obj) === "[object Object]";
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const merge = (...objects) => objects.reduce((result, current) => {
|
||||
if (current === undefined) {
|
||||
return result;
|
||||
}
|
||||
if (Array.isArray(current)) {
|
||||
throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays.");
|
||||
}
|
||||
Object.keys(current).forEach((key) => {
|
||||
if (["__proto__", "constructor", "prototype"].includes(key)) {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(result[key]) && Array.isArray(current[key])) {
|
||||
result[key] = merge.options.mergeArrays
|
||||
? merge.options.uniqueArrayItems
|
||||
? Array.from(new Set(result[key].concat(current[key])))
|
||||
: [...result[key], ...current[key]]
|
||||
: current[key];
|
||||
}
|
||||
else if (isObject(result[key]) && isObject(current[key])) {
|
||||
result[key] = merge(result[key], current[key]);
|
||||
}
|
||||
else if (!isObject(result[key]) && isObject(current[key])) {
|
||||
result[key] = merge(current[key], undefined);
|
||||
}
|
||||
else {
|
||||
result[key] =
|
||||
current[key] === undefined
|
||||
? merge.options.allowUndefinedOverrides
|
||||
? current[key]
|
||||
: result[key]
|
||||
: current[key];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}, {});
|
||||
const defaultOptions = {
|
||||
allowUndefinedOverrides: true,
|
||||
mergeArrays: true,
|
||||
uniqueArrayItems: true,
|
||||
};
|
||||
merge.options = defaultOptions;
|
||||
merge.withOptions = (options, ...objects) => {
|
||||
merge.options = Object.assign(Object.assign({}, defaultOptions), options);
|
||||
const result = merge(...objects);
|
||||
merge.options = defaultOptions;
|
||||
return result;
|
||||
};
|
||||
73
node_modules/ts-deepmerge/package.json
generated
vendored
Normal file
73
node_modules/ts-deepmerge/package.json
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "ts-deepmerge",
|
||||
"type": "module",
|
||||
"license": "ISC",
|
||||
"version": "7.0.3",
|
||||
"scripts": {
|
||||
"clean": "rimraf ./{cjs,esm}/!(package.json)",
|
||||
"compile": "yarn clean && yarn compile:esm && yarn compile:cjs",
|
||||
"compile:watch": "yarn clean && concurrently --kill-others \"yarn compile:esm --watch\" \"yarn compile:cjs --watch\"",
|
||||
"compile:esm": "yarn tsc --project tsconfig.esm.json",
|
||||
"compile:cjs": "yarn tsc --project tsconfig.cjs.json",
|
||||
"prepack": "yarn compile",
|
||||
"format": "prettier --write \"**/*.{json,ts,tsx}\"",
|
||||
"lint": "eslint \"./src/**/*.ts?(x)\"",
|
||||
"lint:fix": "yarn format && yarn lint --fix",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
|
||||
"test:all": "yarn lint:fix && yarn typecheck && yarn test --coverage"
|
||||
},
|
||||
"author": "Raice Hannay <voodoocreation@gmail.com>",
|
||||
"description": "A TypeScript deep merge function.",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"deep",
|
||||
"merge",
|
||||
"types",
|
||||
"ts-merge",
|
||||
"ts-deepmerge",
|
||||
"merging",
|
||||
"deep",
|
||||
"deepmerge",
|
||||
"deep-merge",
|
||||
"recursive",
|
||||
"recursive-merge"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:voodoocreation/ts-deepmerge.git"
|
||||
},
|
||||
"bugs": "https://github.com/voodoocreation/ts-deepmerge/issues",
|
||||
"homepage": "https://github.com/voodoocreation/ts-deepmerge#readme",
|
||||
"engines": {
|
||||
"node": ">=14.13.1"
|
||||
},
|
||||
"exports": {
|
||||
"import": "./esm/index.js",
|
||||
"require": "./cjs/index.js"
|
||||
},
|
||||
"files": [
|
||||
"**/package.json",
|
||||
"**/index.js",
|
||||
"**/*.d.ts"
|
||||
],
|
||||
"types": "./cjs/index.d.ts",
|
||||
"main": "./cjs/index.js",
|
||||
"module": "./esm/index.js",
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.14",
|
||||
"concurrently": "^9.1.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-config-voodoocreation": "^7.0.1",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jest": "^28.9.0",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"prettier": "^3.3.3",
|
||||
"rimraf": "^6.0.1",
|
||||
"ts-jest": "^29.2.5",
|
||||
"typescript": "^5.6.3"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user