@phun-ky/defaults-deep 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -0
- package/dist/defaults-deep.cjs +70 -0
- package/dist/defaults-deep.cjs.map +1 -0
- package/dist/defaults-deep.d.ts +55 -0
- package/dist/defaults-deep.js +70 -0
- package/dist/defaults-deep.js.map +1 -0
- package/package.json +162 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @phun-ky/defaults-deep
|
|
2
|
+
|
|
3
|
+
[](http://commitizen.github.io/cz-cli/) [](http://makeapullrequest.com) [](http://semver.org/spec/v2.0.0.html)       [](https://codecov.io/gh/phun-ky/defaults-deep) [](https://github.com/phun-ky/defaults-deep/actions/workflows/check.yml)
|
|
4
|
+
|
|
5
|
+
## About
|
|
6
|
+
|
|
7
|
+
Similar to lodash's defaultsDeep, but without mutating the source object, and no merging of arrays, and no lodash as dependency!
|
|
8
|
+
|
|
9
|
+
## Table of Contents<!-- omit from toc -->- [defaults-deep](#defaults-deep)
|
|
10
|
+
|
|
11
|
+
- [@phun-ky/defaults-deep](#phun-kydefaults-deep)
|
|
12
|
+
- [About](#about)
|
|
13
|
+
- [Table of Contents- defaults-deep](#table-of-contents--defaults-deep)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Usage](#usage)
|
|
16
|
+
- [ESM](#esm)
|
|
17
|
+
- [CommonJS](#commonjs)
|
|
18
|
+
- [API](#api)
|
|
19
|
+
- [Parameters](#parameters)
|
|
20
|
+
- [Returns](#returns)
|
|
21
|
+
- [Examples](#examples)
|
|
22
|
+
- [Differences from lodash (`_.defaultsDeep` / `_.mergeWith` pattern)](#differences-from-lodash-_defaultsdeep--_mergewith-pattern)
|
|
23
|
+
- [Notice](#notice)
|
|
24
|
+
- [Contributing](#contributing)
|
|
25
|
+
- [License](#license)
|
|
26
|
+
- [Changelog](#changelog)
|
|
27
|
+
- [Sponsor me](#sponsor-me)
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Install the package via `npm`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm i --save @phun-ky/defaults-deep
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### ESM
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
import defaultsDeep from "@phun-ky/defaults-deep";
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### CommonJS
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
const defaultsDeep = require("@phun-ky/defaults-deep");
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
function defaultsDeep(...args): Record<PropertyKey, unknown>;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Deeply applies "defaults" from right-to-left sources into a new object, while preserving arrays.
|
|
58
|
+
|
|
59
|
+
This function mimics the common lodash pattern:
|
|
60
|
+
`_.toArray(arguments).reverse().forEach(x => _.mergeWith(output, x, customizer))`,
|
|
61
|
+
but implemented in vanilla TypeScript with a small, predictable merge core.
|
|
62
|
+
|
|
63
|
+
**Key behaviours**
|
|
64
|
+
|
|
65
|
+
- **Returns a new object** (the returned object is created inside the function).
|
|
66
|
+
- Sources are processed **right-to-left** (`reverse()`), meaning **earlier arguments win**:
|
|
67
|
+
values from the first argument are treated as "defaults" that should _not_ be overwritten
|
|
68
|
+
by later arguments (because later arguments are merged first).
|
|
69
|
+
- Only **object-like** sources participate in merging. Non-objects are skipped via `isObjectLoose`.
|
|
70
|
+
- Uses [mergeWith](utils/merge-with.md#mergewith) for the deep merge logic.
|
|
71
|
+
- **Arrays are preserved by replacement**: if a source value is an array, it replaces the
|
|
72
|
+
destination value at that key (rather than being merged element-by-element).
|
|
73
|
+
|
|
74
|
+
### Parameters
|
|
75
|
+
|
|
76
|
+
| Parameter | Type | Description |
|
|
77
|
+
| --------- | ------------ | ------------------------------------------------------------------------- |
|
|
78
|
+
| ...`args` | `unknown`\[] | A list of potential default/source values. Non-object values are ignored. |
|
|
79
|
+
|
|
80
|
+
### Returns
|
|
81
|
+
|
|
82
|
+
[`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`PropertyKey`, `unknown`>
|
|
83
|
+
|
|
84
|
+
A new object containing the merged result.
|
|
85
|
+
|
|
86
|
+
### Examples
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
defaultsDeep(
|
|
90
|
+
{ a: 1, nested: { x: 1 }, list: [1] },
|
|
91
|
+
{ a: 2, nested: { y: 2 }, list: [2] }
|
|
92
|
+
);
|
|
93
|
+
// => { a: 1, nested: { x: 1, y: 2 }, list: [1] }
|
|
94
|
+
// (earlier args win; arrays preserved by replacement)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
defaultsDeep({ opts: { retry: 3 } }, null, { opts: { timeout: 1000 } });
|
|
99
|
+
// => { opts: { retry: 3, timeout: 1000 } }
|
|
100
|
+
// (non-object sources are ignored)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Differences from lodash (`_.defaultsDeep` / `_.mergeWith` pattern)
|
|
104
|
+
|
|
105
|
+
This package is inspired by lodash's common `_.defaultsDeep` approach (often implemented as `_.toArray(arguments).reverse()` + `_.mergeWith(...)`), but it is **not a drop-in, byte-for-byte compatible clone**. The goal here is to cover the common "configuration defaults" use case with a much smaller, dependency-free implementation. For typical plain objects (JSON-like data) and arrays, the results should match what you expect from the lodash approach.
|
|
106
|
+
|
|
107
|
+
The biggest difference is the underlying merge engine. Lodash's `mergeWith` is a mature, highly general deep-merge with lots of special-case behaviour for many JavaScript value types and edge cases. This implementation intentionally keeps the default rules conservative: it only deep-merges **plain objects** and treats most other things as **replace-by-assignment**. That means values like arrays, dates, maps/sets, functions, class instances, and other non-plain objects are not recursively merged unless you explicitly handle them via a customizer.
|
|
108
|
+
|
|
109
|
+
Array behaviour is also deliberately simpler and more explicit. Lodash's merge behaviour around arrays can be nuanced depending on the function and scenario; in this implementation, arrays are **preserved by replacement** (the source array overwrites the destination array) rather than being merged element-by-element. This matches the "array preservation" intent for defaults/config objects, but if you expect lodash-style index-wise array merging or concatenation in some cases, you'll need to provide your own customizer.
|
|
110
|
+
|
|
111
|
+
Another difference is how non-object inputs are treated. Lodash tends to be extremely permissive about odd inputs and will try hard to produce "something reasonable" even when sources are primitives or exotic objects. This implementation focuses on predictable behaviour for configuration merging: non-object sources are typically ignored (or treated as simple replacements at a property level), and only "object-like" values participate meaningfully in deep merging. If you pass primitives/functions as top-level sources, don't expect identical behaviour to lodash across all cases.
|
|
112
|
+
|
|
113
|
+
Finally, because this package is written in TypeScript with a strict API surface, you may notice differences at compile time even when runtime behaviour is similar. The functions lean on explicit type guards and object-shape constraints rather than lodash's "accept almost anything" philosophy. The payoff is a smaller dependency footprint and clearer semantics for the common defaults use case, at the cost of not matching lodash's full breadth of type handling and edge-case compatibility.
|
|
114
|
+
|
|
115
|
+
## Notice
|
|
116
|
+
|
|
117
|
+
This project is a fork of <https://github.com/nodeutils/defaults-deep>. Original work © 2016 Drew Llewellyn, licensed ISC (see LICENSE-ISC). Modifications © 2026 Alexander Vassbotn Røyne-Helgesen, licensed MIT (see LICENSE-MIT).
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
Want to contribute? Please read the [CONTRIBUTING.md](https://github.com/phun-ky/defaults-deep/blob/main/CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](https://github.com/phun-ky/defaults-deep/blob/main/CODE_OF_CONDUCT.md)
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
This project is maintained by [Alexander Vassbotn Røyne-Helgesen](http://phun-ky.net) and is based on original work by Drew Llewellyn (<drew@drew.pro>, <https://drew.pro>). The original upstream code is licensed under the **ISC License**, and the modifications/changes in this fork are licensed under the **MIT License**.
|
|
126
|
+
|
|
127
|
+
## Changelog
|
|
128
|
+
|
|
129
|
+
See the [CHANGELOG.md](https://github.com/phun-ky/defaults-deep/blob/main/CHANGELOG.md) for details on the latest updates.
|
|
130
|
+
|
|
131
|
+
## Sponsor me
|
|
132
|
+
|
|
133
|
+
I'm an Open Source evangelist, creating stuff that does not exist yet to help get rid of secondary activities and to enhance systems already in place, be it documentation or web sites.
|
|
134
|
+
|
|
135
|
+
The sponsorship is an unique opportunity to alleviate more hours for me to maintain my projects, create new ones and contribute to the large community we're all part of :)
|
|
136
|
+
|
|
137
|
+
[Support me on GitHub Sponsors](https://github.com/sponsors/phun-ky).
|
|
138
|
+
|
|
139
|
+
p.s. **Ukraine is still under brutal Russian invasion. A lot of Ukrainian people are hurt, without shelter and need help**. You can help in various ways, for instance, directly helping refugees, spreading awareness, putting pressure on your local government or companies. You can also support Ukraine by donating e.g. to [Red Cross](https://www.icrc.org/en/donate/ukraine), [Ukraine humanitarian organisation](https://savelife.in.ua/en/donate-en/#donate-army-card-weekly) or [donate Ambulances for Ukraine](https://www.gofundme.com/f/help-to-save-the-lives-of-civilians-in-a-war-zone).
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @phun-ky/defaults-deep
|
|
3
|
+
* Like lodash's _.defaultsDeep, but with array preservation
|
|
4
|
+
* @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>
|
|
5
|
+
* @version 1.1.0
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright (c) 2026 Alexander Vassbotn Røyne-Helgesen
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
* in the Software without restriction, including without limitation the rights
|
|
12
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
* furnished to do so, subject to the following conditions:
|
|
15
|
+
*
|
|
16
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
* copies or substantial portions of the Software.
|
|
18
|
+
*
|
|
19
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
* SOFTWARE.
|
|
26
|
+
*
|
|
27
|
+
* @license
|
|
28
|
+
*
|
|
29
|
+
* Copyright © 2016 Drew Llewellyn
|
|
30
|
+
*
|
|
31
|
+
* Permission to use, copy, modify, and/or distribute this software for any
|
|
32
|
+
* purpose with or without fee is hereby granted, provided that the above
|
|
33
|
+
* copyright notice and this permission notice appear in all copies.
|
|
34
|
+
*
|
|
35
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
36
|
+
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
37
|
+
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
38
|
+
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
39
|
+
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
40
|
+
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
41
|
+
* PERFORMANCE OF THIS SOFTWARE.
|
|
42
|
+
*/
|
|
43
|
+
"use strict";
|
|
44
|
+
/**
|
|
45
|
+
* @phun-ky/typeof
|
|
46
|
+
* A set of JavaScript helper functions to check for types
|
|
47
|
+
* @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>
|
|
48
|
+
* @version 2.1.0
|
|
49
|
+
* @license
|
|
50
|
+
* Copyright (c) 2024 Alexander Vassbotn Røyne-Helgesen
|
|
51
|
+
*
|
|
52
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
53
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
54
|
+
* in the Software without restriction, including without limitation the rights
|
|
55
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
56
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
57
|
+
* furnished to do so, subject to the following conditions:
|
|
58
|
+
*
|
|
59
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
60
|
+
* copies or substantial portions of the Software.
|
|
61
|
+
*
|
|
62
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
63
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
64
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
65
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
66
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
67
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
68
|
+
* SOFTWARE.
|
|
69
|
+
*/function t(t){return!function(t){return void 0===t}(t)}function o(t){if("[object Object]"!==Object.prototype.toString.call(t))return!1;const o=Object.getPrototypeOf(t);return o===Object.prototype||null===o}function e(t){const o=typeof t;return null!==t&&("object"===o||"function"===o)}function n(t,...o){const e=o.at(-1),n="function"==typeof e?e:void 0;const r=n?o.slice(0,-1):o,i=new WeakMap;for(const o of r)c(t,o,n,i);return t}const c=(n,i,s,f)=>{if(e(i))for(const e of r(i)){const r=i[e],u=n[e],l=s?.(u,r,e,n,i,f);if(t(l))n[e]=l;else{if(o(u)&&o(r)){const t=f.get(r);if(t){n[e]=t;continue}f.set(r,u),c(u,r,s,f);continue}if(o(r)){const t=f.get(r);if(t){n[e]=t;continue}const i=o(u)?u:{};n[e]=i,f.set(r,i),c(i,r,s,f);continue}n[e]=r}}},r=t=>[...Object.keys(t),...Object.getOwnPropertySymbols(t).filter(o=>Object.prototype.propertyIsEnumerable.call(t,o))];module.exports=(...t)=>{const o={};for(const c of t.slice().reverse())e(c)&&n(o,c,(t,o)=>Array.isArray(o)?o:void 0);return o};
|
|
70
|
+
//# sourceMappingURL=defaults-deep.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults-deep.cjs","sources":["../node_modules/@phun-ky/typeof/dist/typeof.js","../src/utils/merge-with.ts","../src/main.ts"],"sourcesContent":["/**\n* @phun-ky/typeof\n* A set of JavaScript helper functions to check for types\n* @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>\n* @version 2.1.0\n* @license\n* Copyright (c) 2024 Alexander Vassbotn Røyne-Helgesen\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*/\nfunction t(t){return\"string\"==typeof t}function r(r){return!t(r)}function n(t){return\"number\"==typeof t}function e(t){return!n(t)}function o(t){return\"boolean\"==typeof t}function c(t){return!o(t)}function u(t){return void 0===t}function f(t){return!u(t)}function i(t){return!u(t)}function p(t){if(\"[object Object]\"!==Object.prototype.toString.call(t))return!1;const r=Object.getPrototypeOf(t);return r===Object.prototype||null===r}function y(t){if(\"object\"!=typeof t||null===t)return!1;if(\"[object Object]\"!==Object.prototype.toString.call(t))return!1;const r=Object.getPrototypeOf(t);if(null===r)return!0;const n=Object.prototype.hasOwnProperty.call(r,\"constructor\")?r.constructor:null;return\"function\"==typeof n&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(t)}function l(t){const r=typeof t;return null!==t&&(\"object\"===r||\"function\"===r)}function a(t){if(\"function\"!=typeof t)return!1;if(b(t))return!1;try{const r=Object.getOwnPropertyDescriptor(t,\"prototype\");return!!r&&!r.writable}catch{return!1}}function b(t){if(\"function\"!=typeof t)return!1;return[Object,Array,Function,String,Number,Boolean,Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError,Map,WeakMap,Set,WeakSet,Promise].includes(t)}const O=new Set([Object,Array,Function,String,Number,Boolean,Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError,Map,WeakMap,Set,WeakSet,Promise,BigInt,Symbol]);function j(t){return\"function\"==typeof t&&O.has(t)}function E(t){return\"object\"==typeof t&&null!==t&&Object.getPrototypeOf(t)!==Object.prototype&&null!==Object.getPrototypeOf(t)}function s(t){return\"function\"==typeof t}export{o as isBoolean,j as isBuiltInCallable,b as isBuiltInConstructor,a as isClass,i as isDefined,s as isFunction,E as isInstanceOfUnknownClass,c as isNotBoolean,e as isNotNumber,r as isNotString,f as isNotUndefined,n as isNumber,l as isObjectLoose,p as isObjectPlain,y as isObjectStrict,t as isString,u as isUndefined};\n//# sourceMappingURL=typeof.js.map\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n isFunction,\n isNotUndefined,\n isObjectLoose,\n isObjectPlain\n} from '@phun-ky/typeof';\n\n/* node:coverage disable */\n/**\n * Customizer function used by {@link mergeWith} to override merge behaviour.\n *\n * If the customizer returns `undefined`, {@link mergeWith} falls back to its default\n * deep-merge rules. Any other return value will be assigned to the destination key.\n *\n * @param objValue - Current value on the destination (`object`) for `key`.\n * @param srcValue - Incoming value from the current `source` for `key`.\n * @param key - Property key being merged (string or symbol).\n * @param object - Destination object being mutated/merged into.\n * @param source - Current source object being merged from.\n * @param stack - A `WeakMap` used internally to prevent infinite recursion on circular references.\n * @returns The value to assign for this key, or `undefined` to use default merge behaviour.\n *\n * @example\n * ```ts\n * import { mergeWith, type MergeWithCustomizer } from \"./mergeWith\";\n *\n * const concatArrays: MergeWithCustomizer = (objValue, srcValue) => {\n * if (Array.isArray(objValue) && Array.isArray(srcValue)) {\n * return objValue.concat(srcValue);\n * }\n * return undefined;\n * };\n *\n * const a = { list: [1] };\n * const b = { list: [2] };\n *\n * mergeWith(a, b, concatArrays);\n * // => { list: [1, 2] }\n * ```\n */\n/* node:coverage enable */\nexport type MergeWithCustomizer = (\n objValue: unknown,\n srcValue: unknown,\n key: string | symbol,\n object: Record<PropertyKey, unknown>,\n source: Record<PropertyKey, unknown>,\n stack: WeakMap<object, object>\n) => unknown;\n\ntype UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I\n) => void\n ? I\n : never;\n\ntype MergeResult<T, S extends readonly any[]> = T &\n UnionToIntersection<S[number]>;\n\n/**\n * Deep-merges one or more source objects into a destination object, with optional customization.\n *\n * This is a \"vanilla TS\" alternative to lodash's `mergeWith` with a deliberately conservative\n * default strategy:\n *\n * - **Mutates** and returns the destination `object`.\n * - Enumerates **own enumerable string keys** and **own enumerable symbol keys** from each source.\n * - When both destination and source values are **plain objects**, merges recursively.\n * - When the source value is a **plain object** but the destination is not, creates `{}` and merges into it.\n * - All other value types (arrays, dates, maps, sets, functions, primitives, class instances, etc.)\n * are assigned by **replacement** unless the customizer handles them.\n * - Circular references in **sources** are prevented from causing infinite recursion via a `WeakMap` stack.\n *\n * @typeParam T - Destination object type.\n * @typeParam S - Tuple/array of source object types.\n *\n * @param object - Destination object to merge into (will be mutated).\n * @param args - One or more source objects, optionally followed by a {@link MergeWithCustomizer}.\n * @returns The same `object` reference, now merged with all sources.\n *\n * @remarks\n * - The default merge behaviour only recurses into \"plain objects\", as determined by `isObjectPlain`.\n * - \"Loose objects\" are guarded using `isObjectLoose` to avoid attempting to merge non-object sources.\n * - If you want lodash-like array merging semantics (concat or index-wise), implement it via `customizer`.\n *\n * @example\n * ```ts\n * const target = { a: { x: 1 }, b: 1 };\n * const source = { a: { y: 2 }, b: 2 };\n *\n * mergeWith(target, source);\n * // => { a: { x: 1, y: 2 }, b: 2 }\n * // target is mutated\n * ```\n *\n * @example\n * ```ts\n * const target = { list: [1] };\n * const source = { list: [2] };\n *\n * mergeWith(target, source);\n * // => { list: [2] } (arrays replace by default)\n * ```\n *\n * @example\n * ```ts\n * const concatArrays: MergeWithCustomizer = (objValue, srcValue) => {\n * if (Array.isArray(objValue) && Array.isArray(srcValue)) {\n * return objValue.concat(srcValue);\n * }\n * };\n *\n * mergeWith({ list: [1] }, { list: [2] }, concatArrays);\n * // => { list: [1, 2] }\n * ```\n */\n\nexport function mergeWith<\n T extends Record<PropertyKey, any>,\n S extends readonly Record<PropertyKey, any>[]\n>(object: T, ...sources: S): MergeResult<T, S>;\n\nexport function mergeWith<\n T extends Record<PropertyKey, any>,\n S extends readonly Record<PropertyKey, any>[]\n>(\n object: T,\n ...args: [...sources: S, customizer: MergeWithCustomizer]\n): MergeResult<T, S>;\n\nexport function mergeWith(\n object: Record<PropertyKey, unknown>,\n ...args: (Record<PropertyKey, unknown> | MergeWithCustomizer)[]\n): Record<PropertyKey, unknown> {\n const maybeCustomizer = args.at(-1);\n const customizer = isFunction(maybeCustomizer)\n ? (maybeCustomizer as MergeWithCustomizer)\n : undefined;\n const sources = (customizer ? args.slice(0, -1) : args) as Record<\n PropertyKey,\n unknown\n >[];\n const stack = new WeakMap<object, object>();\n\n for (const source of sources) {\n baseMerge(\n object as Record<PropertyKey, unknown>,\n source,\n customizer,\n stack\n );\n }\n\n return object as any;\n}\n\n/**\n * Internal recursive merge implementation used by {@link mergeWith}.\n *\n * @param target - Destination object that is being mutated.\n * @param source - Current source object being merged in.\n * @param customizer - Optional custom merge override.\n * @param stack - Tracks visited source objects to avoid infinite recursion.\n */\nconst baseMerge = (\n target: Record<PropertyKey, unknown>,\n source: Record<PropertyKey, unknown>,\n customizer: MergeWithCustomizer | undefined,\n stack: WeakMap<object, object>\n): void => {\n if (!isObjectLoose(source)) return;\n\n for (const key of ownKeys(source)) {\n const srcValue = (source as any)[key];\n const objValue = (target as any)[key];\n const customized = customizer?.(\n objValue,\n srcValue,\n key,\n target,\n source,\n stack\n );\n\n if (isNotUndefined(customized)) {\n (target as any)[key] = customized;\n continue;\n }\n\n // Both are plain objects: merge into existing destination object.\n if (isObjectPlain(objValue) && isObjectPlain(srcValue)) {\n // If we've seen this src object before, reuse the prior destination.\n const cached = stack.get(srcValue as object);\n\n if (cached) {\n (target as any)[key] = cached;\n continue;\n }\n\n // Cache before recursing to handle cycles.\n stack.set(srcValue as object, objValue as object);\n\n baseMerge(\n objValue as Record<PropertyKey, unknown>,\n srcValue as Record<PropertyKey, unknown>,\n customizer,\n stack\n );\n continue;\n }\n\n // Source is a plain object but destination isn't: create destination object and merge into it.\n if (isObjectPlain(srcValue)) {\n const cached = stack.get(srcValue as object);\n\n if (cached) {\n (target as any)[key] = cached;\n continue;\n }\n\n const next: Record<PropertyKey, unknown> = isObjectPlain(objValue)\n ? (objValue as Record<PropertyKey, unknown>)\n : {};\n\n (target as any)[key] = next;\n\n // Cache before recursing to handle cycles and repeated refs.\n stack.set(srcValue as object, next as object);\n\n baseMerge(\n next,\n srcValue as Record<PropertyKey, unknown>,\n customizer,\n stack\n );\n continue;\n }\n\n // Arrays, primitives, dates, maps, sets, functions, etc. are assigned by replacement\n (target as any)[key] = srcValue;\n }\n};\n/**\n * Returns enumerable own property keys (string + symbol) for an object.\n *\n * This mirrors lodash's behaviour of considering both string keys and symbol keys,\n * but only those that are enumerable.\n *\n * @param obj - Object to inspect.\n * @returns Array of enumerable own keys (strings and symbols).\n *\n * @example\n * ```ts\n * const sym = Symbol(\"x\");\n * const o = { a: 1, [sym]: 2 };\n * Object.defineProperty(o, \"hidden\", { value: 3, enumerable: false });\n *\n * ownKeys(o);\n * // => [\"a\", Symbol(\"x\")]\n * ```\n */\nconst ownKeys = (obj: object): (string | symbol)[] => [\n ...Object.keys(obj),\n ...Object.getOwnPropertySymbols(obj).filter((s) =>\n Object.prototype.propertyIsEnumerable.call(obj, s)\n )\n];\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { isObjectLoose } from '@phun-ky/typeof';\n\nimport { mergeWith } from './utils/merge-with';\n\n/**\n * Deeply applies \"defaults\" from right-to-left sources into a new object, while preserving arrays.\n *\n * This function mimics the common lodash pattern:\n * `_.toArray(arguments).reverse().forEach(x => _.mergeWith(output, x, customizer))`,\n * but implemented in vanilla TypeScript with a small, predictable merge core.\n *\n * **Key behaviours**\n * - **Returns a new object** (the returned object is created inside the function).\n * - Sources are processed **right-to-left** (`reverse()`), meaning **earlier arguments win**:\n * values from the first argument are treated as \"defaults\" that should *not* be overwritten\n * by later arguments (because later arguments are merged first).\n * - Only **object-like** sources participate in merging. Non-objects are skipped via `isObjectLoose`.\n * - Uses {@link mergeWith} for the deep merge logic.\n * - **Arrays are preserved by replacement**: if a source value is an array, it replaces the\n * destination value at that key (rather than being merged element-by-element).\n *\n * @param args - A list of potential default/source values. Non-object values are ignored.\n * @returns A new object containing the merged result.\n *\n *\n * @example\n * ```ts\n * defaultsDeep(\n * { a: 1, nested: { x: 1 }, list: [1] },\n * { a: 2, nested: { y: 2 }, list: [2] }\n * );\n * // => { a: 1, nested: { x: 1, y: 2 }, list: [1] }\n * // (earlier args win; arrays preserved by replacement)\n * ```\n *\n * @example\n * ```ts\n * defaultsDeep(\n * { opts: { retry: 3 } },\n * null,\n * { opts: { timeout: 1000 } }\n * );\n * // => { opts: { retry: 3, timeout: 1000 } }\n * // (non-object sources are ignored)\n * ```\n *\n * @remarks\n *\n * - The customizer only checks the *source* value for arrays. If `s` is an array, it is returned\n * and assigned as-is. Otherwise returning `undefined` delegates merging to {@link mergeWith}'s\n * default behaviour (which deep-merges plain objects and replaces other value types).\n * - The output type is `Record<PropertyKey, unknown>` to keep the API broadly usable without\n * over-promising specific shapes.\n *\n */\nconst defaultsDeep = (...args: unknown[]) => {\n const output: Record<PropertyKey, unknown> = {};\n\n for (const item of args.slice().reverse()) {\n if (!isObjectLoose(item)) continue;\n\n mergeWith(output, item, (_o: any, s: any[] | undefined) =>\n Array.isArray(s) ? s : undefined\n );\n }\n\n return output;\n};\n\nexport default defaultsDeep;\n"],"names":["f","t","u","p","Object","prototype","toString","call","r","getPrototypeOf","l","mergeWith","object","args","maybeCustomizer","at","customizer","undefined","sources","slice","stack","WeakMap","source","baseMerge","target","isObjectLoose","key","ownKeys","srcValue","objValue","customized","isNotUndefined","isObjectPlain","cached","get","set","next","obj","keys","getOwnPropertySymbols","filter","s","propertyIsEnumerable","output","item","reverse","_o","Array","isArray"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BoO,SAASA,EAAEC,GAAG,OAA9C,SAAWA,GAAG,YAAO,IAASA,CAAC,CAAsBC,CAAED,EAAE,CAA2B,SAASE,EAAEF,GAAG,GAAG,oBAAoBG,OAAOC,UAAUC,SAASC,KAAKN,GAAG,SAAS,MAAMO,EAAEJ,OAAOK,eAAeR,GAAG,OAAOO,IAAIJ,OAAOC,WAAW,OAAOG,CAAC,CAAqW,SAASE,EAAET,GAAG,MAAMO,SAASP,EAAE,OAAO,OAAOA,IAAI,WAAWO,GAAG,aAAaA,EAAE,UCyGj1BG,EACdC,KACGC,GAEH,MAAMC,EAAkBD,EAAKE,OACvBC,ED9GwmD,mBC8GhlDF,EACzBA,OACDG,EACJ,MAAMC,EAAWF,EAAaH,EAAKM,MAAM,GAAG,GAAMN,EAI5CO,EAAQ,IAAIC,QAElB,IAAK,MAAMC,KAAUJ,EACnBK,EACEX,EACAU,EACAN,EACAI,GAIJ,OAAOR,CACT,CAUA,MAAMW,EAAY,CAChBC,EACAF,EACAN,EACAI,KAEA,GAAKK,EAAcH,GAEnB,IAAK,MAAMI,KAAOC,EAAQL,GAAS,CACjC,MAAMM,EAAYN,EAAeI,GAC3BG,EAAYL,EAAeE,GAC3BI,EAAad,IACjBa,EACAD,EACAF,EACAF,EACAF,EACAF,GAGF,GAAIW,EAAeD,GAChBN,EAAeE,GAAOI,MADzB,CAMA,GAAIE,EAAcH,IAAaG,EAAcJ,GAAW,CAEtD,MAAMK,EAASb,EAAMc,IAAIN,GAEzB,GAAIK,EAAQ,CACTT,EAAeE,GAAOO,EACvB,QACF,CAGAb,EAAMe,IAAIP,EAAoBC,GAE9BN,EACEM,EACAD,EACAZ,EACAI,GAEF,QACF,CAGA,GAAIY,EAAcJ,GAAW,CAC3B,MAAMK,EAASb,EAAMc,IAAIN,GAEzB,GAAIK,EAAQ,CACTT,EAAeE,GAAOO,EACvB,QACF,CAEA,MAAMG,EAAqCJ,EAAcH,GACpDA,EACD,CAAA,EAEHL,EAAeE,GAAOU,EAGvBhB,EAAMe,IAAIP,EAAoBQ,GAE9Bb,EACEa,EACAR,EACAZ,EACAI,GAEF,QACF,CAGCI,EAAeE,GAAOE,CApDvB,CAqDF,GAqBID,EAAWU,GAAqC,IACjDjC,OAAOkC,KAAKD,MACZjC,OAAOmC,sBAAsBF,GAAKG,OAAQC,GAC3CrC,OAAOC,UAAUqC,qBAAqBnC,KAAK8B,EAAKI,oBCjN/B,IAAI5B,KACvB,MAAM8B,EAAuC,CAAA,EAE7C,IAAK,MAAMC,KAAQ/B,EAAKM,QAAQ0B,UACzBpB,EAAcmB,IAEnBjC,EAAUgC,EAAQC,EAAM,CAACE,EAASL,IAChCM,MAAMC,QAAQP,GAAKA,OAAIxB,GAI3B,OAAO0B","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deeply applies "defaults" from right-to-left sources into a new object, while preserving arrays.
|
|
3
|
+
*
|
|
4
|
+
* This function mimics the common lodash pattern:
|
|
5
|
+
* `_.toArray(arguments).reverse().forEach(x => _.mergeWith(output, x, customizer))`,
|
|
6
|
+
* but implemented in vanilla TypeScript with a small, predictable merge core.
|
|
7
|
+
*
|
|
8
|
+
* **Key behaviours**
|
|
9
|
+
* - **Returns a new object** (the returned object is created inside the function).
|
|
10
|
+
* - Sources are processed **right-to-left** (`reverse()`), meaning **earlier arguments win**:
|
|
11
|
+
* values from the first argument are treated as "defaults" that should *not* be overwritten
|
|
12
|
+
* by later arguments (because later arguments are merged first).
|
|
13
|
+
* - Only **object-like** sources participate in merging. Non-objects are skipped via `isObjectLoose`.
|
|
14
|
+
* - Uses {@link mergeWith} for the deep merge logic.
|
|
15
|
+
* - **Arrays are preserved by replacement**: if a source value is an array, it replaces the
|
|
16
|
+
* destination value at that key (rather than being merged element-by-element).
|
|
17
|
+
*
|
|
18
|
+
* @param args - A list of potential default/source values. Non-object values are ignored.
|
|
19
|
+
* @returns A new object containing the merged result.
|
|
20
|
+
*
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* defaultsDeep(
|
|
25
|
+
* { a: 1, nested: { x: 1 }, list: [1] },
|
|
26
|
+
* { a: 2, nested: { y: 2 }, list: [2] }
|
|
27
|
+
* );
|
|
28
|
+
* // => { a: 1, nested: { x: 1, y: 2 }, list: [1] }
|
|
29
|
+
* // (earlier args win; arrays preserved by replacement)
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* defaultsDeep(
|
|
35
|
+
* { opts: { retry: 3 } },
|
|
36
|
+
* null,
|
|
37
|
+
* { opts: { timeout: 1000 } }
|
|
38
|
+
* );
|
|
39
|
+
* // => { opts: { retry: 3, timeout: 1000 } }
|
|
40
|
+
* // (non-object sources are ignored)
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @remarks
|
|
44
|
+
*
|
|
45
|
+
* - The customizer only checks the *source* value for arrays. If `s` is an array, it is returned
|
|
46
|
+
* and assigned as-is. Otherwise returning `undefined` delegates merging to {@link mergeWith}'s
|
|
47
|
+
* default behaviour (which deep-merges plain objects and replaces other value types).
|
|
48
|
+
* - The output type is `Record<PropertyKey, unknown>` to keep the API broadly usable without
|
|
49
|
+
* over-promising specific shapes.
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
declare const defaultsDeep: (...args: unknown[]) => Record<PropertyKey, unknown>;
|
|
53
|
+
//# sourceMappingURL=main.d.ts.map
|
|
54
|
+
|
|
55
|
+
export { defaultsDeep as default };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @phun-ky/defaults-deep
|
|
3
|
+
* Like lodash's _.defaultsDeep, but with array preservation
|
|
4
|
+
* @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>
|
|
5
|
+
* @version 1.1.0
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright (c) 2026 Alexander Vassbotn Røyne-Helgesen
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
* in the Software without restriction, including without limitation the rights
|
|
12
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
* furnished to do so, subject to the following conditions:
|
|
15
|
+
*
|
|
16
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
* copies or substantial portions of the Software.
|
|
18
|
+
*
|
|
19
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
* SOFTWARE.
|
|
26
|
+
*
|
|
27
|
+
* @license
|
|
28
|
+
*
|
|
29
|
+
* Copyright © 2016 Drew Llewellyn
|
|
30
|
+
*
|
|
31
|
+
* Permission to use, copy, modify, and/or distribute this software for any
|
|
32
|
+
* purpose with or without fee is hereby granted, provided that the above
|
|
33
|
+
* copyright notice and this permission notice appear in all copies.
|
|
34
|
+
*
|
|
35
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
36
|
+
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
37
|
+
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
38
|
+
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
39
|
+
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
40
|
+
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
41
|
+
* PERFORMANCE OF THIS SOFTWARE.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* @phun-ky/typeof
|
|
45
|
+
* A set of JavaScript helper functions to check for types
|
|
46
|
+
* @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>
|
|
47
|
+
* @version 2.1.0
|
|
48
|
+
* @license
|
|
49
|
+
* Copyright (c) 2024 Alexander Vassbotn Røyne-Helgesen
|
|
50
|
+
*
|
|
51
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
52
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
53
|
+
* in the Software without restriction, including without limitation the rights
|
|
54
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
55
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
56
|
+
* furnished to do so, subject to the following conditions:
|
|
57
|
+
*
|
|
58
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
59
|
+
* copies or substantial portions of the Software.
|
|
60
|
+
*
|
|
61
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
62
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
63
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
64
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
65
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
66
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
67
|
+
* SOFTWARE.
|
|
68
|
+
*/
|
|
69
|
+
function t(t){return!function(t){return void 0===t}(t)}function o(t){if("[object Object]"!==Object.prototype.toString.call(t))return!1;const o=Object.getPrototypeOf(t);return o===Object.prototype||null===o}function e(t){const o=typeof t;return null!==t&&("object"===o||"function"===o)}function n(t,...o){const e=o.at(-1),n="function"==typeof e?e:void 0;const r=n?o.slice(0,-1):o,i=new WeakMap;for(const o of r)c(t,o,n,i);return t}const c=(n,i,f,s)=>{if(e(i))for(const e of r(i)){const r=i[e],u=n[e],l=f?.(u,r,e,n,i,s);if(t(l))n[e]=l;else{if(o(u)&&o(r)){const t=s.get(r);if(t){n[e]=t;continue}s.set(r,u),c(u,r,f,s);continue}if(o(r)){const t=s.get(r);if(t){n[e]=t;continue}const i=o(u)?u:{};n[e]=i,s.set(r,i),c(i,r,f,s);continue}n[e]=r}}},r=t=>[...Object.keys(t),...Object.getOwnPropertySymbols(t).filter(o=>Object.prototype.propertyIsEnumerable.call(t,o))],i=(...t)=>{const o={};for(const c of t.slice().reverse())e(c)&&n(o,c,(t,o)=>Array.isArray(o)?o:void 0);return o};export{i as default};
|
|
70
|
+
//# sourceMappingURL=defaults-deep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults-deep.js","sources":["../node_modules/@phun-ky/typeof/dist/typeof.js","../src/utils/merge-with.ts","../src/main.ts"],"sourcesContent":["/**\n* @phun-ky/typeof\n* A set of JavaScript helper functions to check for types\n* @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>\n* @version 2.1.0\n* @license\n* Copyright (c) 2024 Alexander Vassbotn Røyne-Helgesen\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*/\nfunction t(t){return\"string\"==typeof t}function r(r){return!t(r)}function n(t){return\"number\"==typeof t}function e(t){return!n(t)}function o(t){return\"boolean\"==typeof t}function c(t){return!o(t)}function u(t){return void 0===t}function f(t){return!u(t)}function i(t){return!u(t)}function p(t){if(\"[object Object]\"!==Object.prototype.toString.call(t))return!1;const r=Object.getPrototypeOf(t);return r===Object.prototype||null===r}function y(t){if(\"object\"!=typeof t||null===t)return!1;if(\"[object Object]\"!==Object.prototype.toString.call(t))return!1;const r=Object.getPrototypeOf(t);if(null===r)return!0;const n=Object.prototype.hasOwnProperty.call(r,\"constructor\")?r.constructor:null;return\"function\"==typeof n&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(t)}function l(t){const r=typeof t;return null!==t&&(\"object\"===r||\"function\"===r)}function a(t){if(\"function\"!=typeof t)return!1;if(b(t))return!1;try{const r=Object.getOwnPropertyDescriptor(t,\"prototype\");return!!r&&!r.writable}catch{return!1}}function b(t){if(\"function\"!=typeof t)return!1;return[Object,Array,Function,String,Number,Boolean,Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError,Map,WeakMap,Set,WeakSet,Promise].includes(t)}const O=new Set([Object,Array,Function,String,Number,Boolean,Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError,Map,WeakMap,Set,WeakSet,Promise,BigInt,Symbol]);function j(t){return\"function\"==typeof t&&O.has(t)}function E(t){return\"object\"==typeof t&&null!==t&&Object.getPrototypeOf(t)!==Object.prototype&&null!==Object.getPrototypeOf(t)}function s(t){return\"function\"==typeof t}export{o as isBoolean,j as isBuiltInCallable,b as isBuiltInConstructor,a as isClass,i as isDefined,s as isFunction,E as isInstanceOfUnknownClass,c as isNotBoolean,e as isNotNumber,r as isNotString,f as isNotUndefined,n as isNumber,l as isObjectLoose,p as isObjectPlain,y as isObjectStrict,t as isString,u as isUndefined};\n//# sourceMappingURL=typeof.js.map\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n isFunction,\n isNotUndefined,\n isObjectLoose,\n isObjectPlain\n} from '@phun-ky/typeof';\n\n/* node:coverage disable */\n/**\n * Customizer function used by {@link mergeWith} to override merge behaviour.\n *\n * If the customizer returns `undefined`, {@link mergeWith} falls back to its default\n * deep-merge rules. Any other return value will be assigned to the destination key.\n *\n * @param objValue - Current value on the destination (`object`) for `key`.\n * @param srcValue - Incoming value from the current `source` for `key`.\n * @param key - Property key being merged (string or symbol).\n * @param object - Destination object being mutated/merged into.\n * @param source - Current source object being merged from.\n * @param stack - A `WeakMap` used internally to prevent infinite recursion on circular references.\n * @returns The value to assign for this key, or `undefined` to use default merge behaviour.\n *\n * @example\n * ```ts\n * import { mergeWith, type MergeWithCustomizer } from \"./mergeWith\";\n *\n * const concatArrays: MergeWithCustomizer = (objValue, srcValue) => {\n * if (Array.isArray(objValue) && Array.isArray(srcValue)) {\n * return objValue.concat(srcValue);\n * }\n * return undefined;\n * };\n *\n * const a = { list: [1] };\n * const b = { list: [2] };\n *\n * mergeWith(a, b, concatArrays);\n * // => { list: [1, 2] }\n * ```\n */\n/* node:coverage enable */\nexport type MergeWithCustomizer = (\n objValue: unknown,\n srcValue: unknown,\n key: string | symbol,\n object: Record<PropertyKey, unknown>,\n source: Record<PropertyKey, unknown>,\n stack: WeakMap<object, object>\n) => unknown;\n\ntype UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I\n) => void\n ? I\n : never;\n\ntype MergeResult<T, S extends readonly any[]> = T &\n UnionToIntersection<S[number]>;\n\n/**\n * Deep-merges one or more source objects into a destination object, with optional customization.\n *\n * This is a \"vanilla TS\" alternative to lodash's `mergeWith` with a deliberately conservative\n * default strategy:\n *\n * - **Mutates** and returns the destination `object`.\n * - Enumerates **own enumerable string keys** and **own enumerable symbol keys** from each source.\n * - When both destination and source values are **plain objects**, merges recursively.\n * - When the source value is a **plain object** but the destination is not, creates `{}` and merges into it.\n * - All other value types (arrays, dates, maps, sets, functions, primitives, class instances, etc.)\n * are assigned by **replacement** unless the customizer handles them.\n * - Circular references in **sources** are prevented from causing infinite recursion via a `WeakMap` stack.\n *\n * @typeParam T - Destination object type.\n * @typeParam S - Tuple/array of source object types.\n *\n * @param object - Destination object to merge into (will be mutated).\n * @param args - One or more source objects, optionally followed by a {@link MergeWithCustomizer}.\n * @returns The same `object` reference, now merged with all sources.\n *\n * @remarks\n * - The default merge behaviour only recurses into \"plain objects\", as determined by `isObjectPlain`.\n * - \"Loose objects\" are guarded using `isObjectLoose` to avoid attempting to merge non-object sources.\n * - If you want lodash-like array merging semantics (concat or index-wise), implement it via `customizer`.\n *\n * @example\n * ```ts\n * const target = { a: { x: 1 }, b: 1 };\n * const source = { a: { y: 2 }, b: 2 };\n *\n * mergeWith(target, source);\n * // => { a: { x: 1, y: 2 }, b: 2 }\n * // target is mutated\n * ```\n *\n * @example\n * ```ts\n * const target = { list: [1] };\n * const source = { list: [2] };\n *\n * mergeWith(target, source);\n * // => { list: [2] } (arrays replace by default)\n * ```\n *\n * @example\n * ```ts\n * const concatArrays: MergeWithCustomizer = (objValue, srcValue) => {\n * if (Array.isArray(objValue) && Array.isArray(srcValue)) {\n * return objValue.concat(srcValue);\n * }\n * };\n *\n * mergeWith({ list: [1] }, { list: [2] }, concatArrays);\n * // => { list: [1, 2] }\n * ```\n */\n\nexport function mergeWith<\n T extends Record<PropertyKey, any>,\n S extends readonly Record<PropertyKey, any>[]\n>(object: T, ...sources: S): MergeResult<T, S>;\n\nexport function mergeWith<\n T extends Record<PropertyKey, any>,\n S extends readonly Record<PropertyKey, any>[]\n>(\n object: T,\n ...args: [...sources: S, customizer: MergeWithCustomizer]\n): MergeResult<T, S>;\n\nexport function mergeWith(\n object: Record<PropertyKey, unknown>,\n ...args: (Record<PropertyKey, unknown> | MergeWithCustomizer)[]\n): Record<PropertyKey, unknown> {\n const maybeCustomizer = args.at(-1);\n const customizer = isFunction(maybeCustomizer)\n ? (maybeCustomizer as MergeWithCustomizer)\n : undefined;\n const sources = (customizer ? args.slice(0, -1) : args) as Record<\n PropertyKey,\n unknown\n >[];\n const stack = new WeakMap<object, object>();\n\n for (const source of sources) {\n baseMerge(\n object as Record<PropertyKey, unknown>,\n source,\n customizer,\n stack\n );\n }\n\n return object as any;\n}\n\n/**\n * Internal recursive merge implementation used by {@link mergeWith}.\n *\n * @param target - Destination object that is being mutated.\n * @param source - Current source object being merged in.\n * @param customizer - Optional custom merge override.\n * @param stack - Tracks visited source objects to avoid infinite recursion.\n */\nconst baseMerge = (\n target: Record<PropertyKey, unknown>,\n source: Record<PropertyKey, unknown>,\n customizer: MergeWithCustomizer | undefined,\n stack: WeakMap<object, object>\n): void => {\n if (!isObjectLoose(source)) return;\n\n for (const key of ownKeys(source)) {\n const srcValue = (source as any)[key];\n const objValue = (target as any)[key];\n const customized = customizer?.(\n objValue,\n srcValue,\n key,\n target,\n source,\n stack\n );\n\n if (isNotUndefined(customized)) {\n (target as any)[key] = customized;\n continue;\n }\n\n // Both are plain objects: merge into existing destination object.\n if (isObjectPlain(objValue) && isObjectPlain(srcValue)) {\n // If we've seen this src object before, reuse the prior destination.\n const cached = stack.get(srcValue as object);\n\n if (cached) {\n (target as any)[key] = cached;\n continue;\n }\n\n // Cache before recursing to handle cycles.\n stack.set(srcValue as object, objValue as object);\n\n baseMerge(\n objValue as Record<PropertyKey, unknown>,\n srcValue as Record<PropertyKey, unknown>,\n customizer,\n stack\n );\n continue;\n }\n\n // Source is a plain object but destination isn't: create destination object and merge into it.\n if (isObjectPlain(srcValue)) {\n const cached = stack.get(srcValue as object);\n\n if (cached) {\n (target as any)[key] = cached;\n continue;\n }\n\n const next: Record<PropertyKey, unknown> = isObjectPlain(objValue)\n ? (objValue as Record<PropertyKey, unknown>)\n : {};\n\n (target as any)[key] = next;\n\n // Cache before recursing to handle cycles and repeated refs.\n stack.set(srcValue as object, next as object);\n\n baseMerge(\n next,\n srcValue as Record<PropertyKey, unknown>,\n customizer,\n stack\n );\n continue;\n }\n\n // Arrays, primitives, dates, maps, sets, functions, etc. are assigned by replacement\n (target as any)[key] = srcValue;\n }\n};\n/**\n * Returns enumerable own property keys (string + symbol) for an object.\n *\n * This mirrors lodash's behaviour of considering both string keys and symbol keys,\n * but only those that are enumerable.\n *\n * @param obj - Object to inspect.\n * @returns Array of enumerable own keys (strings and symbols).\n *\n * @example\n * ```ts\n * const sym = Symbol(\"x\");\n * const o = { a: 1, [sym]: 2 };\n * Object.defineProperty(o, \"hidden\", { value: 3, enumerable: false });\n *\n * ownKeys(o);\n * // => [\"a\", Symbol(\"x\")]\n * ```\n */\nconst ownKeys = (obj: object): (string | symbol)[] => [\n ...Object.keys(obj),\n ...Object.getOwnPropertySymbols(obj).filter((s) =>\n Object.prototype.propertyIsEnumerable.call(obj, s)\n )\n];\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { isObjectLoose } from '@phun-ky/typeof';\n\nimport { mergeWith } from './utils/merge-with';\n\n/**\n * Deeply applies \"defaults\" from right-to-left sources into a new object, while preserving arrays.\n *\n * This function mimics the common lodash pattern:\n * `_.toArray(arguments).reverse().forEach(x => _.mergeWith(output, x, customizer))`,\n * but implemented in vanilla TypeScript with a small, predictable merge core.\n *\n * **Key behaviours**\n * - **Returns a new object** (the returned object is created inside the function).\n * - Sources are processed **right-to-left** (`reverse()`), meaning **earlier arguments win**:\n * values from the first argument are treated as \"defaults\" that should *not* be overwritten\n * by later arguments (because later arguments are merged first).\n * - Only **object-like** sources participate in merging. Non-objects are skipped via `isObjectLoose`.\n * - Uses {@link mergeWith} for the deep merge logic.\n * - **Arrays are preserved by replacement**: if a source value is an array, it replaces the\n * destination value at that key (rather than being merged element-by-element).\n *\n * @param args - A list of potential default/source values. Non-object values are ignored.\n * @returns A new object containing the merged result.\n *\n *\n * @example\n * ```ts\n * defaultsDeep(\n * { a: 1, nested: { x: 1 }, list: [1] },\n * { a: 2, nested: { y: 2 }, list: [2] }\n * );\n * // => { a: 1, nested: { x: 1, y: 2 }, list: [1] }\n * // (earlier args win; arrays preserved by replacement)\n * ```\n *\n * @example\n * ```ts\n * defaultsDeep(\n * { opts: { retry: 3 } },\n * null,\n * { opts: { timeout: 1000 } }\n * );\n * // => { opts: { retry: 3, timeout: 1000 } }\n * // (non-object sources are ignored)\n * ```\n *\n * @remarks\n *\n * - The customizer only checks the *source* value for arrays. If `s` is an array, it is returned\n * and assigned as-is. Otherwise returning `undefined` delegates merging to {@link mergeWith}'s\n * default behaviour (which deep-merges plain objects and replaces other value types).\n * - The output type is `Record<PropertyKey, unknown>` to keep the API broadly usable without\n * over-promising specific shapes.\n *\n */\nconst defaultsDeep = (...args: unknown[]) => {\n const output: Record<PropertyKey, unknown> = {};\n\n for (const item of args.slice().reverse()) {\n if (!isObjectLoose(item)) continue;\n\n mergeWith(output, item, (_o: any, s: any[] | undefined) =>\n Array.isArray(s) ? s : undefined\n );\n }\n\n return output;\n};\n\nexport default defaultsDeep;\n"],"names":["f","t","u","p","Object","prototype","toString","call","r","getPrototypeOf","l","mergeWith","object","args","maybeCustomizer","at","customizer","undefined","sources","slice","stack","WeakMap","source","baseMerge","target","isObjectLoose","key","ownKeys","srcValue","objValue","customized","isNotUndefined","isObjectPlain","cached","get","set","next","obj","keys","getOwnPropertySymbols","filter","s","propertyIsEnumerable","defaultsDeep","output","item","reverse","_o","Array","isArray"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BoO,SAASA,EAAEC,GAAG,OAA9C,SAAWA,GAAG,YAAO,IAASA,CAAC,CAAsBC,CAAED,EAAE,CAA2B,SAASE,EAAEF,GAAG,GAAG,oBAAoBG,OAAOC,UAAUC,SAASC,KAAKN,GAAG,SAAS,MAAMO,EAAEJ,OAAOK,eAAeR,GAAG,OAAOO,IAAIJ,OAAOC,WAAW,OAAOG,CAAC,CAAqW,SAASE,EAAET,GAAG,MAAMO,SAASP,EAAE,OAAO,OAAOA,IAAI,WAAWO,GAAG,aAAaA,EAAE,UCyGj1BG,EACdC,KACGC,GAEH,MAAMC,EAAkBD,EAAKE,OACvBC,ED9GwmD,mBC8GhlDF,EACzBA,OACDG,EACJ,MAAMC,EAAWF,EAAaH,EAAKM,MAAM,GAAG,GAAMN,EAI5CO,EAAQ,IAAIC,QAElB,IAAK,MAAMC,KAAUJ,EACnBK,EACEX,EACAU,EACAN,EACAI,GAIJ,OAAOR,CACT,CAUA,MAAMW,EAAY,CAChBC,EACAF,EACAN,EACAI,KAEA,GAAKK,EAAcH,GAEnB,IAAK,MAAMI,KAAOC,EAAQL,GAAS,CACjC,MAAMM,EAAYN,EAAeI,GAC3BG,EAAYL,EAAeE,GAC3BI,EAAad,IACjBa,EACAD,EACAF,EACAF,EACAF,EACAF,GAGF,GAAIW,EAAeD,GAChBN,EAAeE,GAAOI,MADzB,CAMA,GAAIE,EAAcH,IAAaG,EAAcJ,GAAW,CAEtD,MAAMK,EAASb,EAAMc,IAAIN,GAEzB,GAAIK,EAAQ,CACTT,EAAeE,GAAOO,EACvB,QACF,CAGAb,EAAMe,IAAIP,EAAoBC,GAE9BN,EACEM,EACAD,EACAZ,EACAI,GAEF,QACF,CAGA,GAAIY,EAAcJ,GAAW,CAC3B,MAAMK,EAASb,EAAMc,IAAIN,GAEzB,GAAIK,EAAQ,CACTT,EAAeE,GAAOO,EACvB,QACF,CAEA,MAAMG,EAAqCJ,EAAcH,GACpDA,EACD,CAAA,EAEHL,EAAeE,GAAOU,EAGvBhB,EAAMe,IAAIP,EAAoBQ,GAE9Bb,EACEa,EACAR,EACAZ,EACAI,GAEF,QACF,CAGCI,EAAeE,GAAOE,CApDvB,CAqDF,GAqBID,EAAWU,GAAqC,IACjDjC,OAAOkC,KAAKD,MACZjC,OAAOmC,sBAAsBF,GAAKG,OAAQC,GAC3CrC,OAAOC,UAAUqC,qBAAqBnC,KAAK8B,EAAKI,KCjN9CE,EAAe,IAAI9B,KACvB,MAAM+B,EAAuC,CAAA,EAE7C,IAAK,MAAMC,KAAQhC,EAAKM,QAAQ2B,UACzBrB,EAAcoB,IAEnBlC,EAAUiC,EAAQC,EAAM,CAACE,EAASN,IAChCO,MAAMC,QAAQR,GAAKA,OAAIxB,GAI3B,OAAO2B","x_google_ignoreList":[0]}
|
package/package.json
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phun-ky/defaults-deep",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Like lodash's _.defaultsDeep, but with array preservation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/defaults-deep.cjs",
|
|
7
|
+
"module": "./dist/defaults-deep.js",
|
|
8
|
+
"types": "./dist/defaults-deep.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"/dist/defaults-deep.js",
|
|
11
|
+
"/dist/defaults-deep.js.map",
|
|
12
|
+
"/dist/defaults-deep.cjs",
|
|
13
|
+
"/dist/defaults-deep.cjs.map",
|
|
14
|
+
"/dist/defaults-deep.d.ts"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/defaults-deep.d.ts",
|
|
19
|
+
"import": "./dist/defaults-deep.js",
|
|
20
|
+
"require": "./dist/defaults-deep.cjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "npm run clean && npm run rollup",
|
|
25
|
+
"clean": "rm -rf dist dts",
|
|
26
|
+
"commit": "npx git-cz",
|
|
27
|
+
"docs:gen": "node ./node_modules/.bin/typedoc",
|
|
28
|
+
"release": "npx release-it --ci",
|
|
29
|
+
"rollup": "rollup -c",
|
|
30
|
+
"prerollup:dev": "npm run clean",
|
|
31
|
+
"rollup:dev": "rollup -c -w",
|
|
32
|
+
"style:code": "npx putout src",
|
|
33
|
+
"style:format": "eslint -c ./eslint.config.mjs src/**/*.ts --fix --no-warn-ignored && ./node_modules/.bin/prettier --write ./eslint.config.mjs src",
|
|
34
|
+
"style:lint": "eslint -c ./eslint.config.mjs src/**/*.ts --no-warn-ignored && ./node_modules/.bin/prettier --check src",
|
|
35
|
+
"test": "glob-bin -c \"node --import tsx --import global-jsdom/register --test --no-warnings\" \"./src/**/__tests__/**/*.[jt]s\"",
|
|
36
|
+
"pretest:ci": "rm -rf coverage && mkdir -p coverage",
|
|
37
|
+
"test:ci": "glob-bin -c \"node --import tsx --import global-jsdom/register --test --no-warnings --experimental-test-coverage --test-reporter=cobertura --test-reporter-destination=coverage/cobertura-coverage.xml --test-reporter=spec --test-reporter-destination=stdout\" \"./src/**/__tests__/**/*.[jt]s\""
|
|
38
|
+
},
|
|
39
|
+
"funding": "https://github.com/phun-ky/defaults-deep?sponsor=1",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/phun-ky/defaults-deep.git"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"node-utils",
|
|
46
|
+
"node",
|
|
47
|
+
"javascript",
|
|
48
|
+
"typescript",
|
|
49
|
+
"esm",
|
|
50
|
+
"utility",
|
|
51
|
+
"utils",
|
|
52
|
+
"object",
|
|
53
|
+
"object-utils",
|
|
54
|
+
"object-merge",
|
|
55
|
+
"deep-merge",
|
|
56
|
+
"deepmerge",
|
|
57
|
+
"merge",
|
|
58
|
+
"mergeWith",
|
|
59
|
+
"merge-customizer",
|
|
60
|
+
"customizer",
|
|
61
|
+
"defaults",
|
|
62
|
+
"defaultsdeep",
|
|
63
|
+
"deep-defaults",
|
|
64
|
+
"config",
|
|
65
|
+
"configuration",
|
|
66
|
+
"settings",
|
|
67
|
+
"options",
|
|
68
|
+
"preset",
|
|
69
|
+
"overrides",
|
|
70
|
+
"override",
|
|
71
|
+
"assign",
|
|
72
|
+
"extend",
|
|
73
|
+
"mixin",
|
|
74
|
+
"combine",
|
|
75
|
+
"compose",
|
|
76
|
+
"nested",
|
|
77
|
+
"recursive",
|
|
78
|
+
"immutable",
|
|
79
|
+
"mutate",
|
|
80
|
+
"clone",
|
|
81
|
+
"array",
|
|
82
|
+
"arrays",
|
|
83
|
+
"array-merge",
|
|
84
|
+
"array-preserve",
|
|
85
|
+
"array-preservation",
|
|
86
|
+
"array-replace",
|
|
87
|
+
"array-overwrite",
|
|
88
|
+
"lodash",
|
|
89
|
+
"lodash-alternative",
|
|
90
|
+
"lodash-replacement",
|
|
91
|
+
"lodash-compat",
|
|
92
|
+
"lightweight"
|
|
93
|
+
],
|
|
94
|
+
"config": {
|
|
95
|
+
"commitizen": {
|
|
96
|
+
"path": "./node_modules/git-cz"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"author": {
|
|
100
|
+
"name": "Alexander Vassbotn Røyne-Helgesen",
|
|
101
|
+
"email": "alexander@phun-ky.net"
|
|
102
|
+
},
|
|
103
|
+
"contributors": [
|
|
104
|
+
"Drew Llewellyn <drew@drew.pro> (https://drew.pro)"
|
|
105
|
+
],
|
|
106
|
+
"maintainers": [
|
|
107
|
+
{
|
|
108
|
+
"name": "Alexander Vassbotn Røyne-Helgesen",
|
|
109
|
+
"email": "alexander@phun-ky.net"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"license": "MIT AND ISC",
|
|
113
|
+
"bugs": {
|
|
114
|
+
"url": "https://github.com/phun-ky/defaults-deep/issues"
|
|
115
|
+
},
|
|
116
|
+
"homepage": "https://github.com/phun-ky/defaults-deep#readme",
|
|
117
|
+
"devDependencies": {
|
|
118
|
+
"@release-it/conventional-changelog": "^10.0.0",
|
|
119
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
120
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
121
|
+
"@testing-library/dom": "^10.4.0",
|
|
122
|
+
"@testing-library/jest-dom": "^6.4.2",
|
|
123
|
+
"@types/node": "^24.3.0",
|
|
124
|
+
"cobertura": "^1.0.1",
|
|
125
|
+
"eslint": "^9.20.0",
|
|
126
|
+
"eslint-config-phun-ky": "^1.0.0",
|
|
127
|
+
"git-cz": "^4.9.0",
|
|
128
|
+
"glob-bin": "^1.0.0",
|
|
129
|
+
"global-jsdom": "^27.0.0",
|
|
130
|
+
"jsdom": "^27.0.0",
|
|
131
|
+
"prettier": "^3.5.1",
|
|
132
|
+
"putout": "^40.0.16",
|
|
133
|
+
"quibble": "^0.9.1",
|
|
134
|
+
"release-it": "^19.2.4",
|
|
135
|
+
"remark-github": "^12.0.0",
|
|
136
|
+
"remark-toc": "^9.0.0",
|
|
137
|
+
"rollup": "^4.12.0",
|
|
138
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
139
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
140
|
+
"tslib": "^2.3.1",
|
|
141
|
+
"tsx": "^4.7.1",
|
|
142
|
+
"typedoc": "^0.28.2",
|
|
143
|
+
"typedoc-plugin-frontmatter": "^1.0.0",
|
|
144
|
+
"typedoc-plugin-markdown": "^4.2.3",
|
|
145
|
+
"typedoc-plugin-mdn-links": "^5.0.1",
|
|
146
|
+
"typedoc-plugin-no-inherit": "^1.4.0",
|
|
147
|
+
"typedoc-plugin-remark": "^2.0.0",
|
|
148
|
+
"typedoc-plugin-rename-defaults": "^0.7.1",
|
|
149
|
+
"typescript": "^5.0.0",
|
|
150
|
+
"unified-prettier": "^2.0.1"
|
|
151
|
+
},
|
|
152
|
+
"engines": {
|
|
153
|
+
"node": "^20.9.0 || >=22.0.0",
|
|
154
|
+
"npm": ">=10.8.2"
|
|
155
|
+
},
|
|
156
|
+
"dependencies": {
|
|
157
|
+
"@phun-ky/typeof": "^2.1.0"
|
|
158
|
+
},
|
|
159
|
+
"publishConfig": {
|
|
160
|
+
"access": "public"
|
|
161
|
+
}
|
|
162
|
+
}
|