diff --git a/README.md b/README.md index d39a96e..f17fa26 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # @fastify/deepmerge -![CI](https://github.com/fastify/deepmerge/workflows/CI/badge.svg) +[![CI](https://github.com/fastify/deepmerge/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/fastify/deepmerge/actions/workflows/ci.yml) [![NPM version](https://img.shields.io/npm/v/@fastify/deepmerge.svg?style=flat)](https://www.npmjs.com/package/@fastify/deepmerge) -[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) +[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard) Merges the enumerable properties of two or more objects deeply. Fastest implementation of deepmerge, see section 'Benchmarks'. diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..89fd678 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,6 @@ +'use strict' + +module.exports = require('neostandard')({ + ignores: require('neostandard').resolveIgnoresFromGitignore(), + ts: true +}) diff --git a/package.json b/package.json index 42e606d..4c1f3cf 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "type": "commonjs", "types": "types/index.d.ts", "scripts": { - "lint": "standard", - "lint:fix": "standard --fix", + "lint": "eslint", + "lint:fix": "eslint --fix", "test": "npm run test:unit && npm run test:typescript", "test:unit": "tap", "test:typescript": "tsd" @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/fastify/deepmerge#readme", "devDependencies": { - "standard": "^17.1.0", + "neostandard": "^0.11.9", "tap": "^21.0.0", "tape": "^5.7.5", "tsd": "^0.31.1" diff --git a/types/index.d.ts b/types/index.d.ts index ba22615..fe88d62 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,5 +1,5 @@ -type DeepMergeFn = (target: T1, source: T2) => DeepMerge; -type DeepMergeAllFn = >(...targets: T) => DeepMergeAll<{}, T>; +type DeepMergeFn = (target: T1, source: T2) => DeepMerge +type DeepMergeAllFn = >(...targets: T) => DeepMergeAll<{}, T> type Primitive = | null @@ -8,14 +8,14 @@ type Primitive = | number | boolean | symbol - | bigint; + | bigint -type BuiltIns = Primitive | Date | RegExp; +type BuiltIns = Primitive | Date | RegExp type MergeArrays = T extends readonly any[] ? U extends readonly any[] - ? [...T, ...U] - : never + ? [...T, ...U] + : never : never type DifferenceKeys< @@ -37,19 +37,22 @@ type DeepMergeHelper< type DeepMerge = U extends BuiltIns - ? U - : [T, U] extends [readonly any[], readonly any[]] - ? MergeArrays - : [T, U] extends [{ [key: string]: unknown }, { [key: string]: unknown }] - ? DeepMergeHelper - : U - -type First = T extends [infer _I, ...infer _Rest] ? _I : never; + ? U + : [T, U] extends [readonly any[], readonly any[]] + ? MergeArrays + : [T, U] extends [{ [key: string]: unknown }, { [key: string]: unknown }] + ? DeepMergeHelper + : U + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type First = T extends [infer _I, ...infer _Rest] ? _I : never + +// eslint-disable-next-line @typescript-eslint/no-unused-vars type Rest = T extends [infer _I, ...infer _Rest] ? _Rest : never type DeepMergeAll = First extends never ? R - : DeepMergeAll>, Rest>; + : DeepMergeAll>, Rest> type MergeArrayFnOptions = { clone: (value: any) => any; @@ -74,7 +77,7 @@ declare namespace deepmerge { export { deepmerge as default } } -declare function deepmerge(options: Options & { all: true }): DeepMergeAllFn; -declare function deepmerge(options?: Options): DeepMergeFn; +declare function deepmerge (options: Options & { all: true }): DeepMergeAllFn +declare function deepmerge (options?: Options): DeepMergeFn export = deepmerge diff --git a/types/index.test-d.ts b/types/index.test-d.ts index 78df804..f86a89d 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -1,5 +1,5 @@ -import { expectAssignable, expectError, expectType } from "tsd"; -import { deepmerge } from "."; +import { expectAssignable, expectError, expectType } from 'tsd' +import { deepmerge } from '.' expectType(deepmerge()({ a: 'a' }, { b: 'b' }).a) expectType(deepmerge()({ a: 'a' }, { b: 'b' }).b) @@ -31,26 +31,26 @@ expectType<{ a: number }>(deepmerge()({ a: { a: 'string' } }, { a: { a: 1 } }).a expectType<{ a: number, b: string }>(deepmerge()({ a: { a: 'string' } }, { a: { a: 1, b: 'string' } }).a) expectType<{ a: number, b: string }>(deepmerge()({ a: { a: { a: 'string' } } }, { a: { a: 1, b: 'string' } }).a) expectType<{ a: { a: string, b: string } }>(deepmerge()({ a: { a: { a: 'string' } } }, { a: { a: { b: 'string' } } }).a) -expectType(deepmerge()({ a: [1,2,3,4] }, { a: 'string' }).a) -expectType(deepmerge()({ a: [1,2,3,4] }, { a: [1,2,3,4] }).a) -expectType<(number|string)[]>(deepmerge()({ a: [1,2,3,4] }, { a: ['a'] }).a) -expectType<(number|string)[]>(deepmerge()({ a: [1,2,3,4] as readonly number[] }, { a: ['a'] }).a) -expectType<[1,2,3,4,'a']>(deepmerge()({ a: [1,2,3,4] as const }, { a: ['a'] as const }).a) +expectType(deepmerge()({ a: [1, 2, 3, 4] }, { a: 'string' }).a) +expectType(deepmerge()({ a: [1, 2, 3, 4] }, { a: [1, 2, 3, 4] }).a) +expectType<(number | string)[]>(deepmerge()({ a: [1, 2, 3, 4] }, { a: ['a'] }).a) +expectType<(number | string)[]>(deepmerge()({ a: [1, 2, 3, 4] as readonly number[] }, { a: ['a'] }).a) +expectType<[1, 2, 3, 4, 'a']>(deepmerge()({ a: [1, 2, 3, 4] as const }, { a: ['a'] as const }).a) expectType>(deepmerge()({ a: [1] }, { a: [2] }).a) -expectType<{b: number[]}>(deepmerge()({ a: {b: {}} }, { a: {b: [2]} }).a) -expectType<{b: Date}>(deepmerge()({ a: {b: {}} }, { a: {b: new Date()} }).a) -expectType<{b: RegExp}>(deepmerge()({ a: {b: {}} }, { a: {b: /abc/g } }).a) -expectType(deepmerge()({ a: {b: {}} }, new Date())) -expectType>(deepmerge()({ a: {b: {}} }, new Map())) +expectType<{ b: number[] }>(deepmerge()({ a: { b: {} } }, { a: { b: [2] } }).a) +expectType<{ b: Date }>(deepmerge()({ a: { b: {} } }, { a: { b: new Date() } }).a) +expectType<{ b: RegExp }>(deepmerge()({ a: { b: {} } }, { a: { b: /abc/g } }).a) +expectType(deepmerge()({ a: { b: {} } }, new Date())) +expectType>(deepmerge()({ a: { b: {} } }, new Map())) expectAssignable(deepmerge({ all: true })) expectAssignable(deepmerge({ all: true, symbols: true })) -expectType(deepmerge({all: true, symbols: true})({a: 'a'}).a) -expectType(deepmerge({all: true, symbols: true})({a: 'a'}, {b: 'a'}).a) -expectType(deepmerge({all: true, symbols: true})({a: 'a'}, {b: 'a'}).b) -expectType(deepmerge({all: true, symbols: true})({a: 'a'}, {a: 2}).a) -expectType(deepmerge({all: true, symbols: true})({a: 'a'}, 2)) -expectType(deepmerge({all: true, symbols: true})({a: 'a'}, 'string')) +expectType(deepmerge({ all: true, symbols: true })({ a: 'a' }).a) +expectType(deepmerge({ all: true, symbols: true })({ a: 'a' }, { b: 'a' }).a) +expectType(deepmerge({ all: true, symbols: true })({ a: 'a' }, { b: 'a' }).b) +expectType(deepmerge({ all: true, symbols: true })({ a: 'a' }, { a: 2 }).a) +expectType(deepmerge({ all: true, symbols: true })({ a: 'a' }, 2)) +expectType(deepmerge({ all: true, symbols: true })({ a: 'a' }, 'string')) expectError(deepmerge({ mergeArray: function () { } })) expectError(deepmerge({ mergeArray: function () { return () => 'test' } })) @@ -69,4 +69,4 @@ deepmerge({ return source } } -}) \ No newline at end of file +})