@homer0/object-utils 6.0.2 → 6.0.5

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/dist/index.d.ts CHANGED
@@ -1,127 +1,118 @@
1
+ //#region src/fns/copy.d.ts
1
2
  /**
2
3
  * Creates a deep copy of a given object.
3
4
  *
4
- * @param target The object to copy.
5
- * @template T The type of the input object, which will be the same as the one
6
- * returned.
5
+ * @template T The type of the input object, which will be the same as the one returned.
6
+ * @param target The object to copy.
7
7
  */
8
8
  declare const copy: <T>(target: T) => T;
9
-
9
+ //#endregion
10
+ //#region src/fns/formatKeys.d.ts
10
11
  /**
11
12
  * The callback that will be used to replace a key.
12
13
  *
13
- * @param substring The captured string to replace.
14
- * @param args The list of groups captured by the expression.
14
+ * @param substring The captured string to replace.
15
+ * @param args The list of groups captured by the expression.
15
16
  */
16
17
  type FormatKeysReplaceFn = (substring: string, ...args: string[]) => string;
17
18
  type FormatKeysOptions = {
18
- /**
19
- * The object to transform.
20
- */
21
- target: unknown;
22
- /**
23
- * A regular expression to match the keys to transform.
24
- */
25
- search: RegExp;
26
- /**
27
- * The callback that will be used to replace the matched substring. Think of `search` and
28
- * `replace` as the parameters of `String.replace`.
29
- */
30
- replace: FormatKeysReplaceFn;
31
- /**
32
- * A list of keys or paths where the transformation will be made. If not specified, the
33
- * function will use all the keys from the object.
34
- */
35
- include?: string[];
36
- /**
37
- * A list of keys or paths where the transformation won't be made.
38
- */
39
- exclude?: string[];
40
- /**
41
- * The delimiter that will separate the path components for both `include` and `exclude`.
42
- */
43
- pathDelimiter?: string;
19
+ /** The object to transform. */
20
+ target: unknown;
21
+ /** A regular expression to match the keys to transform. */
22
+ search: RegExp;
23
+ /**
24
+ * The callback that will be used to replace the matched substring. Think of `search`
25
+ * and `replace` as the parameters of `String.replace`.
26
+ */
27
+ replace: FormatKeysReplaceFn;
28
+ /**
29
+ * A list of keys or paths where the transformation will be made. If not specified, the
30
+ * function will use all the keys from the object.
31
+ */
32
+ include?: string[];
33
+ /** A list of keys or paths where the transformation won't be made. */
34
+ exclude?: string[];
35
+ /**
36
+ * The delimiter that will separate the path components for both `include` and
37
+ * `exclude`.
38
+ */
39
+ pathDelimiter?: string;
44
40
  };
45
41
  type FormatKeysExtensionOptions = Omit<FormatKeysOptions, 'search' | 'replace'>;
46
42
  /**
47
43
  * Formats all the keys on an object using a way similar to `.replace(regexp, ...)` but
48
44
  * that also works recursively and with _"object paths"_.
49
45
  *
50
- * @param options The set of options to customize the transformation.
51
- * @template T The type of the returned object.
52
46
  * @example
53
- *
54
47
  * const target = {
55
- * prop_one: 'Charito!',
48
+ * prop_one: 'Charito!',
56
49
  * };
57
50
  * console.log(
58
- * formatKeys({
59
- * target,
60
- * // Find all the keys with snake case.
61
- * search: /([a-z])_([a-z])/g,
62
- * // Using the same .replace style callback, replace it with lower camel case.
63
- * replace: (_, firstLetter, secondLetter) => {
64
- * const newSecondLetter = secondLetter.toUpperCase();
65
- * return `${firstLetter}${newSecondLetter}`;
66
- * },
67
- * }),
51
+ * formatKeys({
52
+ * target,
53
+ * // Find all the keys with snake case.
54
+ * search: /([a-z])_([a-z])/g,
55
+ * // Using the same .replace style callback, replace it with lower camel case.
56
+ * replace: (_, firstLetter, secondLetter) => {
57
+ * const newSecondLetter = secondLetter.toUpperCase();
58
+ * return `${firstLetter}${newSecondLetter}`;
59
+ * },
60
+ * }),
68
61
  * );
69
62
  * // Will output { propOne: 'Charito!}.
70
63
  *
64
+ * @template T The type of the returned object.
65
+ * @param options The set of options to customize the transformation.
71
66
  */
72
67
  declare const formatKeys: <T = Record<string, unknown>>(options: FormatKeysOptions) => T;
73
-
68
+ //#endregion
69
+ //#region src/fns/dashToLowerCamelKeys.d.ts
74
70
  /**
75
- * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case`
76
- * to `lowerCamelCase`.
71
+ * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case` to
72
+ * `lowerCamelCase`.
77
73
  *
78
- * @param options The options to use.
79
- * @template T The type of the returned object.
74
+ * @template T The type of the returned object.
75
+ * @param options The options to use.
80
76
  */
81
77
  declare const dashToLowerCamelKeys: <T>(options: FormatKeysExtensionOptions) => T;
82
-
78
+ //#endregion
79
+ //#region src/fns/dashToSnakeKeys.d.ts
83
80
  /**
84
- * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case`
85
- * to `snake_case`.
81
+ * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case` to
82
+ * `snake_case`.
86
83
  *
87
- * @param options The options to use.
88
- * @template T The type of the returned object.
84
+ * @template T The type of the returned object.
85
+ * @param options The options to use.
89
86
  */
90
87
  declare const dashToSnakeKeys: <T>(options: FormatKeysExtensionOptions) => T;
91
-
88
+ //#endregion
89
+ //#region src/fns/extract.d.ts
92
90
  /**
93
- * Used in the {@link extract} function to specify a path for a property, or an "origin path"
94
- * and an "extraction path".
91
+ * Used in the {@link extract} function to specify a path for a property, or an "origin
92
+ * path" and an "extraction path".
95
93
  */
96
94
  type extractionPath = string | Record<string, string>;
97
95
  type ExtractOptions = {
98
- /**
99
- * The object from where the property/properties will be extracted.
100
- */
101
- target: unknown;
102
- /**
103
- * This can be a single path or a list of them. And for this method, the paths are not
104
- * only strings but can also be an object with a single key, that would be the path to
105
- * where to "do the extraction", and the value the path on the target object.
106
- */
107
- paths: extractionPath | extractionPath[];
108
- /**
109
- * The delimiter that will separate the path components.
110
- */
111
- pathDelimiter?: string;
112
- /**
113
- * Whether or not to throw an error when the path is invalid. If this is `false`, the
114
- * method will silently fail an empty object.
115
- */
116
- failWithError?: boolean;
96
+ /** The object from where the property/properties will be extracted. */
97
+ target: unknown;
98
+ /**
99
+ * This can be a single path or a list of them. And for this method, the paths are not
100
+ * only strings but can also be an object with a single key, that would be the path to
101
+ * where to "do the extraction", and the value the path on the target object.
102
+ */
103
+ paths: extractionPath | extractionPath[];
104
+ /** The delimiter that will separate the path components. */
105
+ pathDelimiter?: string;
106
+ /**
107
+ * Whether or not to throw an error when the path is invalid. If this is `false`, the
108
+ * method will silently fail an empty object.
109
+ */
110
+ failWithError?: boolean;
117
111
  };
118
112
  /**
119
113
  * Extracts a property or properties from an object in order to create a new one.
120
114
  *
121
- * @param options The options to use.
122
- * @template T The type of the returned object.
123
115
  * @example
124
- *
125
116
  * const target = {
126
117
  * name: {
127
118
  * first: 'Pilar',
@@ -140,83 +131,72 @@ type ExtractOptions = {
140
131
  * );
141
132
  * // Will output { name: 'Pilar', age: 3, address: { planet: 'earth' } }
142
133
  *
134
+ * @template T The type of the returned object.
135
+ * @param options The options to use.
143
136
  */
144
137
  declare const extract: <T = Record<string, unknown>>(options: ExtractOptions) => T | undefined;
145
-
138
+ //#endregion
139
+ //#region src/fns/flat.d.ts
146
140
  /**
147
141
  * Checks whether a key for an array or an Object should be flattened.
148
142
  *
149
- * @param key The key to check inside its parent.
150
- * @param value The value of the key.
143
+ * @param key The key to check inside its parent.
144
+ * @param value The value of the key.
151
145
  */
152
146
  type ShouldFlattenFn = (key: string, value: unknown) => boolean;
153
147
  type FlatOptions = {
154
- /**
155
- * The object to transform.
156
- */
157
- target: unknown;
158
- /**
159
- * A custom prefix to be added before the name of the properties. This can be used on
160
- * custom cases and it's also used when the method calls itself in order to flatten a
161
- * sub object.
162
- */
163
- prefix?: string;
164
- /**
165
- * The delimiter that will separate the path components.
166
- */
167
- pathDelimiter?: string;
168
- /**
169
- * A custom function that can be used in order to tell the function whether an Object or
170
- * an Array property should be flatten or not.
171
- */
172
- shouldFlatten?: ShouldFlattenFn;
148
+ /** The object to transform. */
149
+ target: unknown;
150
+ /**
151
+ * A custom prefix to be added before the name of the properties. This can be used on
152
+ * custom cases and it's also used when the method calls itself in order to flatten a
153
+ * sub object.
154
+ */
155
+ prefix?: string;
156
+ /** The delimiter that will separate the path components. */
157
+ pathDelimiter?: string;
158
+ /**
159
+ * A custom function that can be used in order to tell the function whether an Object or
160
+ * an Array property should be flatten or not.
161
+ */
162
+ shouldFlatten?: ShouldFlattenFn;
173
163
  };
174
164
  /**
175
165
  * Flattens an object properties into a single level dictionary.
176
166
  *
177
- * @param options The options to use.
178
- * @template T The type of the returned object.
179
167
  * @example
168
+ * const target = {
169
+ * propOne: {
170
+ * propOneSub: 'Charito!',
171
+ * },
172
+ * propTwo: '!!!',
173
+ * };
174
+ * console.log(flat({ target });
175
+ * // Will output { 'propOne.propOneSub': 'Charito!', propTwo: '!!!' }
180
176
  *
181
- * const target = {
182
- * propOne: {
183
- * propOneSub: 'Charito!',
184
- * },
185
- * propTwo: '!!!',
186
- * };
187
- * console.log(flat({ target });
188
- * // Will output { 'propOne.propOneSub': 'Charito!', propTwo: '!!!' }
189
- *
177
+ * @template T The type of the returned object.
178
+ * @param options The options to use.
190
179
  */
191
180
  declare const flat: <T = Record<string, unknown>>(options: FlatOptions) => T;
192
-
181
+ //#endregion
182
+ //#region src/fns/get.d.ts
193
183
  type GetOptions = {
194
- /**
195
- * The object from where the property will be read.
196
- */
197
- target: unknown;
198
- /**
199
- * The path to the property.
200
- */
201
- path: string;
202
- /**
203
- * The delimiter that will separate the path components.
204
- */
205
- pathDelimiter?: string;
206
- /**
207
- * Whether or not to throw an error when the path is invalid. If this is `false`,
208
- * the method will silently fail and return `undefined`.
209
- */
210
- failWithError?: boolean;
184
+ /** The object from where the property will be read. */
185
+ target: unknown;
186
+ /** The path to the property. */
187
+ path: string;
188
+ /** The delimiter that will separate the path components. */
189
+ pathDelimiter?: string;
190
+ /**
191
+ * Whether or not to throw an error when the path is invalid. If this is `false`, the
192
+ * method will silently fail and return `undefined`.
193
+ */
194
+ failWithError?: boolean;
211
195
  };
212
196
  /**
213
197
  * Returns the value of an object property using a path.
214
198
  *
215
- * @param options The options to use.
216
- * @template T The type of the returned object.
217
- * @throws {Error} If the path is invalid and `failWithError` is set to `true`.
218
199
  * @example
219
- *
220
200
  * const obj = {
221
201
  * propOne: {
222
202
  * propOneSub: 'Charito!',
@@ -226,83 +206,79 @@ type GetOptions = {
226
206
  * console.log(get({ target: obj, path: 'propOne.propOneSub' }));
227
207
  * // Will output 'Charito!'
228
208
  *
209
+ * @template T The type of the returned object.
210
+ * @param options The options to use.
211
+ * @throws {Error} If the path is invalid and `failWithError` is set to `true`.
229
212
  */
230
213
  declare function get<T>(options: GetOptions): T | undefined;
231
214
  declare function get<T>(options: unknown, path: string): T | undefined;
232
-
215
+ //#endregion
216
+ //#region src/fns/lowerCamelToDashKeys.d.ts
233
217
  /**
234
- * A shorthand method for {@link formatKeys} that transforms the keys from
235
- * `lowerCamelCase` to `dash-case`.
218
+ * A shorthand method for {@link formatKeys} that transforms the keys from `lowerCamelCase`
219
+ * to `dash-case`.
236
220
  *
237
- * @param options The options to use.
238
- * @template T The type of the returned object.
221
+ * @template T The type of the returned object.
222
+ * @param options The options to use.
239
223
  */
240
224
  declare const lowerCamelToDashKeys: <T>(options: FormatKeysExtensionOptions) => T;
241
-
225
+ //#endregion
226
+ //#region src/fns/lowerCamelToSnakeKeys.d.ts
242
227
  /**
243
228
  * A shorthand method for {@link formatKeys} that transforms the keys from
244
229
  * `lowerCamelCase` to `snake_case`.
245
230
  *
246
- * @param options The options to use.
247
- * @template T The type of the returned object.
231
+ * @template T The type of the returned object.
232
+ * @param options The options to use.
248
233
  */
249
234
  declare const lowerCamelToSnakeKeys: <T>(options: FormatKeysExtensionOptions) => T;
250
-
235
+ //#endregion
236
+ //#region src/fns/merge.d.ts
251
237
  /**
252
238
  * This method makes a deep merge of a list of objects into a new one. The method also
253
239
  * supports arrays: if the first element is an array, it will be merged into an array,
254
240
  * otherwise, it will be an object.
255
241
  *
256
- * @param targets The list of objects to merge.
257
- * @template T The type of the merged object that will be returned.
258
242
  * @example
259
- *
260
243
  * const objA = { a: 'first' };
261
244
  * const objB = { b: 'second' };
262
245
  * console.log(merge(objA, objB));
263
246
  * // Will output { a: 'first', b: 'second' }
264
247
  *
265
248
  * @example
266
- *
267
249
  * const arrA = [{ a: 'first' }];
268
250
  * const arrB = [{ b: 'second' }];
269
251
  * console.log(merge(objA, objB));
270
252
  * // Will output [{ a: 'first', b: 'second' }]
271
253
  *
254
+ * @template T The type of the merged object that will be returned.
255
+ * @param targets The list of objects to merge.
272
256
  */
273
257
  declare const merge: <T = unknown>(...targets: unknown[]) => T;
274
-
258
+ //#endregion
259
+ //#region src/fns/remove.d.ts
275
260
  type RemoveOptions = {
276
- /**
277
- * The object from where the property will be removed.
278
- */
279
- target: unknown;
280
- /**
281
- * The path to the property.
282
- */
283
- path: string;
284
- /**
285
- * The delimiter that will separate the path components.
286
- */
287
- pathDelimiter?: string;
288
- /**
289
- * Whether or not to throw an error when the path is invalid. If this is `false`, the
290
- * function will silently fail.
291
- */
292
- failWithError?: boolean;
293
- /**
294
- * If this flag is `true` and after removing the property the parent object is empty,
295
- * it will remove it recursively until a non empty parent object is found.
296
- */
297
- cleanEmptyProperties?: boolean;
261
+ /** The object from where the property will be removed. */
262
+ target: unknown;
263
+ /** The path to the property. */
264
+ path: string;
265
+ /** The delimiter that will separate the path components. */
266
+ pathDelimiter?: string;
267
+ /**
268
+ * Whether or not to throw an error when the path is invalid. If this is `false`, the
269
+ * function will silently fail.
270
+ */
271
+ failWithError?: boolean;
272
+ /**
273
+ * If this flag is `true` and after removing the property the parent object is empty, it
274
+ * will remove it recursively until a non empty parent object is found.
275
+ */
276
+ cleanEmptyProperties?: boolean;
298
277
  };
299
278
  /**
300
279
  * Deletes a property of an object using a path.
301
280
  *
302
- * @param options The options to use.
303
- * @template T The type of the returned object.
304
281
  * @example
305
- *
306
282
  * const target = {
307
283
  * propOne: {
308
284
  * propOneSub: 'Charito!',
@@ -312,87 +288,77 @@ type RemoveOptions = {
312
288
  * console.log(remove({ target, path: 'propOne.propOneSub' }));
313
289
  * // Will output { propTwo: '!!!' }
314
290
  *
291
+ * @template T The type of the returned object.
292
+ * @param options The options to use.
315
293
  */
316
294
  declare function remove<T = unknown>(options: RemoveOptions): T | undefined;
317
295
  declare function remove<T = unknown>(options: unknown, path: string): T | undefined;
318
-
296
+ //#endregion
297
+ //#region src/fns/set.d.ts
319
298
  type SetOptions = {
320
- /**
321
- * The object where the property will be set.
322
- */
323
- target: unknown;
324
- /**
325
- * The path for the property.
326
- */
327
- path: string;
328
- /**
329
- * The value to set on the property.
330
- */
331
- value: unknown;
332
- /**
333
- * The delimiter that will separate the path components.
334
- */
335
- pathDelimiter?: string;
336
- /**
337
- * Whether or not to throw an error when the path is invalid. If this is `false`, the method
338
- * will silently fail and return `undefined`.
339
- */
340
- failWithError?: boolean;
299
+ /** The object where the property will be set. */
300
+ target: unknown;
301
+ /** The path for the property. */
302
+ path: string;
303
+ /** The value to set on the property. */
304
+ value: unknown;
305
+ /** The delimiter that will separate the path components. */
306
+ pathDelimiter?: string;
307
+ /**
308
+ * Whether or not to throw an error when the path is invalid. If this is `false`, the
309
+ * method will silently fail and return `undefined`.
310
+ */
311
+ failWithError?: boolean;
341
312
  };
342
313
  /**
343
314
  * Sets a property on an object using a path. If the path doesn't exist, it will be
344
315
  * created.
345
316
  *
346
- * @param options The options to use.
347
- * @template T The type of the returned object.
348
- * @throws {Error} If one of the path components is for a non-object property and
349
- * `failWithError` is set to `true`.
350
317
  * @example
351
- *
352
318
  * const target = {};
353
319
  * console.log(set({ target, path: 'some.prop.path', value: 'some-value' }));
354
320
  * // Will output { some: { prop: { path: 'some-value' } } }
355
321
  *
322
+ * @template T The type of the returned object.
323
+ * @param options The options to use.
324
+ * @throws {Error} If one of the path components is for a non-object property and
325
+ * `failWithError` is set to `true`.
356
326
  */
357
327
  declare function set<T = Record<string, unknown>>(options: SetOptions): T | undefined;
358
328
  declare function set<T = Record<string, unknown>>(options: SetOptions | unknown, path: string, value: unknown): T | undefined;
359
-
329
+ //#endregion
330
+ //#region src/fns/snakeToDashKeys.d.ts
360
331
  /**
361
332
  * A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to
362
333
  * `dash-case`.
363
334
  *
364
- * @param options The options to use.
365
- * @template T The type of the returned object.
335
+ * @template T The type of the returned object.
336
+ * @param options The options to use.
366
337
  */
367
338
  declare const snakeToDashKeys: <T>(options: FormatKeysExtensionOptions) => T;
368
-
339
+ //#endregion
340
+ //#region src/fns/snakeToLowerCamelKeys.d.ts
369
341
  /**
370
342
  * A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to
371
343
  * `lowerCamelCase`.
372
344
  *
373
- * @param options The options to use.
374
- * @template T The type of the returned object.
345
+ * @template T The type of the returned object.
346
+ * @param options The options to use.
375
347
  */
376
348
  declare const snakeToLowerCamelKeys: <T>(options: FormatKeysExtensionOptions) => T;
377
-
349
+ //#endregion
350
+ //#region src/fns/unflat.d.ts
378
351
  type UnflatOptions = {
379
- /**
380
- * The object to transform.
381
- */
382
- target: unknown;
383
- /**
384
- * The delimiter that will separate the path components.
385
- */
386
- pathDelimiter?: string;
352
+ /** The object to transform. */
353
+ target: unknown;
354
+ /** The delimiter that will separate the path components. */
355
+ pathDelimiter?: string;
387
356
  };
388
357
  /**
389
358
  * This method does the exact opposite from `flat`: It takes an already flatten object and
390
359
  * restores it structure.
391
360
  *
392
- * @param options The options to use.
393
- * @template T The type of the returned object.
394
361
  * @example
395
- *
396
362
  * const target = {
397
363
  * 'propOne.propOneSub': 'Charito!',
398
364
  * propTwo: '!!!',
@@ -400,7 +366,10 @@ type UnflatOptions = {
400
366
  * console.log(unflat({ target }));
401
367
  * // Will output { propOne: { propOneSub: 'Charito!' }, 'propTwo': '!!!' }
402
368
  *
369
+ * @template T The type of the returned object.
370
+ * @param options The options to use.
403
371
  */
404
372
  declare const unflat: <T = Record<string, unknown>>(options: UnflatOptions) => T;
405
-
406
- export { type ExtractOptions, type FlatOptions, type FormatKeysExtensionOptions, type FormatKeysOptions, type FormatKeysReplaceFn, type GetOptions, type RemoveOptions, type SetOptions, type ShouldFlattenFn, type UnflatOptions, copy, dashToLowerCamelKeys, dashToSnakeKeys, extract, type extractionPath, flat, formatKeys, get, lowerCamelToDashKeys, lowerCamelToSnakeKeys, merge, remove, set, snakeToDashKeys, snakeToLowerCamelKeys, unflat };
373
+ //#endregion
374
+ export { ExtractOptions, FlatOptions, FormatKeysExtensionOptions, FormatKeysOptions, FormatKeysReplaceFn, GetOptions, RemoveOptions, SetOptions, ShouldFlattenFn, UnflatOptions, copy, dashToLowerCamelKeys, dashToSnakeKeys, extract, extractionPath, flat, formatKeys, get, lowerCamelToDashKeys, lowerCamelToSnakeKeys, merge, remove, set, snakeToDashKeys, snakeToLowerCamelKeys, unflat };
375
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import $ from"extend";var E=(...n)=>{let[i]=n,e=Array.isArray(i)?[]:{};return $(!0,e,...n)};var k=n=>E(n);var y=n=>{let{target:i,search:e,replace:r,include:a=[],exclude:c=[],pathDelimiter:o="."}=n,f=i,p=Object.keys(i),s={};p.forEach(l=>{let u=f[l];s[l]=!!(u&&typeof u=="object"&&u!==null&&!Array.isArray(u)&&Object.keys(u))});let t=o.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),g=new RegExp(`^${t}`,"i"),m=new RegExp(`${t}$`,"i"),h={},w;a.length?w=a.map(l=>{let u=l.replace(g,"").replace(m,""),d;if(u.includes(o)){let T=u.split(o),x=T.shift();d="",h[x]||(h[x]=[]),h[x].push(T.join(o))}else d=u;return d}).filter(l=>l):w=p;let O={};if(c.length){let l=[];c.forEach(u=>{let d=u.replace(g,"").replace(m,"");if(d.includes(o)){let T=d.split(o),x=T.shift();O[x]||(O[x]=[]),O[x].push(T.join(o))}else s[d]=!1,l.push(d)}),w=w.filter(u=>u&&!l.includes(u))}return p.reduce((l,u)=>{let d,T,x=f[u];return w.includes(u)?d=u.replace(e,r):d=u,s[u]?T=y({target:x,search:e,replace:r,include:h[u]||[],exclude:O[u]||[],pathDelimiter:o}):T=x,{...l,[d]:T}},{})};var j=n=>y({...n,search:/([a-z])-([a-z])/g,replace:(i,e,r)=>{let a=r.toUpperCase();return`${e}${a}`}});var W=n=>y({...n,search:/([a-z])-([a-z])/g,replace:(i,e,r)=>`${e}_${r}`});function R(n,i){let e;typeof i=="string"?e={target:n,path:i}:e=n;let{target:r,path:a,pathDelimiter:c=".",failWithError:o=!1}=e,f=r,p=a.split(c),s=p.shift(),t=f[s];if(typeof t>"u"){if(o)throw new Error(`There's nothing on '${a}'`);return}if(!p.length)return t;let g=s;return p.some(m=>{let h=!1;if(g+=`${c}${m}`,t=t[m],typeof t>"u"){if(o)throw new Error(`There's nothing on '${g}'`);h=!0}return h}),t}var F=["__proto__","prototype","constructor"];function K(n,i,e){let r;typeof i=="string"?r={target:n,path:i,value:e}:r=n;let{target:a,path:c,value:o,pathDelimiter:f=".",failWithError:p=!1}=r,s=k(a);if(!c.includes(f))return!c||F.includes(c.toLowerCase())?void 0:(s[c]=o,s);let t=c.split(f);if(t.some(l=>!l||F.includes(l.toLowerCase())))return;let m=t.pop(),h=s,w="",O=!1;if(t.forEach(l=>{w+=`${f}${l}`;let d=typeof h[l];if(d==="undefined")h[l]={},h=h[l];else if(d==="object")h=h[l];else{let T=w.substring(f.length);if(p)throw new Error(`There's already an element of type '${d}' on '${T}'`);O=!0}}),!O)return h[m]=o,s}var N=n=>{let{target:i,paths:e,pathDelimiter:r=".",failWithError:a=!1}=n,c=k(i),o={},f=!1;if((Array.isArray(e)?e:[e]).reduce((p,s)=>{let t,g;if(typeof s=="string")t=s,g=s;else{let[m]=Object.keys(s);t=m,g=s[t]}return p.push({origin:g,customDest:t.includes(r),dest:t}),p},[]).some(p=>{let s=!1,t=R({target:c,path:p.origin,pathDelimiter:r,failWithError:a});if(typeof t<"u")if(p.customDest){let g=K({target:o,path:p.dest,value:t,pathDelimiter:r,failWithError:a});typeof g>"u"?(s=!0,f=!0):o=g}else o[p.dest]=t;return s}),!f)return o};var v=n=>{let{target:i,shouldFlatten:e,pathDelimiter:r=".",prefix:a=""}=n,c=i,o={},f=a?`${a}${r}`:"";return Object.keys(c).forEach(p=>{let s=`${f}${p}`,t=c[p],m=typeof t==="object"&&t!==null;m&&(!e||e(p,t))?o=E(o,v({target:t,pathDelimiter:r,prefix:s,shouldFlatten:e})):o[s]=m?k(t):t}),o};var Y=n=>y({...n,search:/([a-z])([A-Z])/g,replace:(i,e,r)=>{let a=r.toLowerCase();return`${e}-${a}`}});var ne=n=>y({...n,search:/([a-z])([A-Z])/g,replace:(i,e,r)=>{let a=r.toLowerCase();return`${e}_${a}`}});function D(n,i){let e;typeof i=="string"?e={target:n,path:i}:e=n;let{target:r,path:a,pathDelimiter:c=".",cleanEmptyProperties:o=!0,failWithError:f=!1}=e,p=a.split(c),s=p.pop(),t=k(r);if(!p.length)return delete t[s],t;let g=p.join(c),m=R({target:t,path:g,pathDelimiter:c,failWithError:f});if(!(typeof m>"u"))return delete m[s],o&&!Object.keys(m).length?D({target:t,path:g,pathDelimiter:c,failWithError:f,cleanEmptyProperties:o}):t}var pe=n=>y({...n,search:/([a-z])_([a-z])/g,replace:(i,e,r)=>`${e}-${r}`});var le=n=>y({...n,search:/([a-z])_([a-z])/g,replace:(i,e,r)=>{let a=r.toUpperCase();return`${e}${a}`}});var me=n=>{let{target:i,pathDelimiter:e="."}=n,r=i;return Object.keys(r).reduce((a,c)=>K({target:a,path:c,value:r[c],pathDelimiter:e}),{})};export{k as copy,j as dashToLowerCamelKeys,W as dashToSnakeKeys,N as extract,v as flat,y as formatKeys,R as get,Y as lowerCamelToDashKeys,ne as lowerCamelToSnakeKeys,E as merge,D as remove,K as set,pe as snakeToDashKeys,le as snakeToLowerCamelKeys,me as unflat};
1
+ import e from"extend";const t=(...t)=>{let[n]=t;return e(!0,Array.isArray(n)?[]:{},...t)},n=e=>t(e),r=e=>{let{target:t,search:n,replace:i,include:a=[],exclude:o=[],pathDelimiter:s=`.`}=e,c=t,l=Object.keys(t),u={};l.forEach(e=>{let t=c[e];u[e]=!!(t&&typeof t==`object`&&t&&!Array.isArray(t)&&Object.keys(t))});let d=s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),f=RegExp(`^${d}`,`i`),p=RegExp(`${d}$`,`i`),m={},h;h=a.length?a.map(e=>{let t=e.replace(f,``).replace(p,``),n;if(t.includes(s)){let e=t.split(s),r=e.shift();n=``,m[r]||(m[r]=[]),m[r].push(e.join(s))}else n=t;return n}).filter(e=>e):l;let g={};if(o.length){let e=[];o.forEach(t=>{let n=t.replace(f,``).replace(p,``);if(n.includes(s)){let e=n.split(s),t=e.shift();g[t]||(g[t]=[]),g[t].push(e.join(s))}else u[n]=!1,e.push(n)}),h=h.filter(t=>t&&!e.includes(t))}return l.reduce((e,t)=>{let a,o,l=c[t];return a=h.includes(t)?t.replace(n,i):t,o=u[t]?r({target:l,search:n,replace:i,include:m[t]||[],exclude:g[t]||[],pathDelimiter:s}):l,{...e,[a]:o}},{})},i=e=>r({...e,search:/([a-z])-([a-z])/g,replace:(e,t,n)=>`${t}${n.toUpperCase()}`}),a=e=>r({...e,search:/([a-z])-([a-z])/g,replace:(e,t,n)=>`${t}_${n}`});function o(e,t){let n;n=typeof t==`string`?{target:e,path:t}:e;let{target:r,path:i,pathDelimiter:a=`.`,failWithError:o=!1}=n,s=r,c=i.split(a),l=c.shift(),u=s[l];if(u===void 0){if(o)throw Error(`There's nothing on '${i}'`);return}if(!c.length)return u;let d=l;return c.some(e=>{let t=!1;if(d+=`${a}${e}`,u=u[e],u===void 0){if(o)throw Error(`There's nothing on '${d}'`);t=!0}return t}),u}const s=[`__proto__`,`prototype`,`constructor`];function c(e,t,r){let i;i=typeof t==`string`?{target:e,path:t,value:r}:e;let{target:a,path:o,value:c,pathDelimiter:l=`.`,failWithError:u=!1}=i,d=n(a);if(!o.includes(l))return!o||s.includes(o.toLowerCase())?void 0:(d[o]=c,d);let f=o.split(l);if(f.some(e=>!e||s.includes(e.toLowerCase())))return;let p=f.pop(),m=d,h=``,g=!1;if(f.forEach(e=>{h+=`${l}${e}`;let t=typeof m[e];if(t===`undefined`)m[e]={},m=m[e];else if(t===`object`)m=m[e];else{let e=h.substring(l.length);if(u)throw Error(`There's already an element of type '${t}' on '${e}'`);g=!0}}),!g)return m[p]=c,d}const l=e=>{let{target:t,paths:r,pathDelimiter:i=`.`,failWithError:a=!1}=e,s=n(t),l={},u=!1;if((Array.isArray(r)?r:[r]).reduce((e,t)=>{let n,r;if(typeof t==`string`)n=t,r=t;else{let[e]=Object.keys(t);n=e,r=t[n]}return e.push({origin:r,customDest:n.includes(i),dest:n}),e},[]).some(e=>{let t=!1,n=o({target:s,path:e.origin,pathDelimiter:i,failWithError:a});if(n!==void 0)if(e.customDest){let r=c({target:l,path:e.dest,value:n,pathDelimiter:i,failWithError:a});r===void 0?(t=!0,u=!0):l=r}else l[e.dest]=n;return t}),!u)return l},u=e=>{let{target:r,shouldFlatten:i,pathDelimiter:a=`.`,prefix:o=``}=e,s=r,c={},l=o?`${o}${a}`:``;return Object.keys(s).forEach(e=>{let r=`${l}${e}`,o=s[e],d=typeof o==`object`&&!!o;d&&(!i||i(e,o))?c=t(c,u({target:o,pathDelimiter:a,prefix:r,shouldFlatten:i})):c[r]=d?n(o):o}),c},d=e=>r({...e,search:/([a-z])([A-Z])/g,replace:(e,t,n)=>`${t}-${n.toLowerCase()}`}),f=e=>r({...e,search:/([a-z])([A-Z])/g,replace:(e,t,n)=>`${t}_${n.toLowerCase()}`});function p(e,t){let r;r=typeof t==`string`?{target:e,path:t}:e;let{target:i,path:a,pathDelimiter:s=`.`,cleanEmptyProperties:c=!0,failWithError:l=!1}=r,u=a.split(s),d=u.pop(),f=n(i);if(!u.length)return delete f[d],f;let m=u.join(s),h=o({target:f,path:m,pathDelimiter:s,failWithError:l});if(h!==void 0)return delete h[d],c&&!Object.keys(h).length?p({target:f,path:m,pathDelimiter:s,failWithError:l,cleanEmptyProperties:c}):f}const m=e=>r({...e,search:/([a-z])_([a-z])/g,replace:(e,t,n)=>`${t}-${n}`}),h=e=>r({...e,search:/([a-z])_([a-z])/g,replace:(e,t,n)=>`${t}${n.toUpperCase()}`}),g=e=>{let{target:t,pathDelimiter:n=`.`}=e,r=t;return Object.keys(r).reduce((e,t)=>c({target:e,path:t,value:r[t],pathDelimiter:n}),{})};export{n as copy,i as dashToLowerCamelKeys,a as dashToSnakeKeys,l as extract,u as flat,r as formatKeys,o as get,d as lowerCamelToDashKeys,f as lowerCamelToSnakeKeys,t as merge,p as remove,c as set,m as snakeToDashKeys,h as snakeToLowerCamelKeys,g as unflat};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fns/merge.ts","../src/fns/copy.ts","../src/fns/formatKeys.ts","../src/fns/dashToLowerCamelKeys.ts","../src/fns/dashToSnakeKeys.ts","../src/fns/get.ts","../src/fns/set.ts","../src/fns/extract.ts","../src/fns/flat.ts","../src/fns/lowerCamelToDashKeys.ts","../src/fns/lowerCamelToSnakeKeys.ts","../src/fns/remove.ts","../src/fns/snakeToDashKeys.ts","../src/fns/snakeToLowerCamelKeys.ts","../src/fns/unflat.ts"],"sourcesContent":["import extend from 'extend';\n\n/**\n * This method makes a deep merge of a list of objects into a new one. The method also\n * supports arrays: if the first element is an array, it will be merged into an array,\n * otherwise, it will be an object.\n *\n * @param targets The list of objects to merge.\n * @template T The type of the merged object that will be returned.\n * @example\n *\n * const objA = { a: 'first' };\n * const objB = { b: 'second' };\n * console.log(merge(objA, objB));\n * // Will output { a: 'first', b: 'second' }\n *\n * @example\n *\n * const arrA = [{ a: 'first' }];\n * const arrB = [{ b: 'second' }];\n * console.log(merge(objA, objB));\n * // Will output [{ a: 'first', b: 'second' }]\n *\n */\nexport const merge = <T = unknown>(...targets: unknown[]): T => {\n const [firstTarget] = targets;\n const base = Array.isArray(firstTarget) ? [] : {};\n return extend(true, base, ...targets) as T;\n};\n","import { merge } from './merge.js';\n\n/**\n * Creates a deep copy of a given object.\n *\n * @param target The object to copy.\n * @template T The type of the input object, which will be the same as the one\n * returned.\n */\nexport const copy = <T>(target: T): T => merge(target);\n","/**\n * The callback that will be used to replace a key.\n *\n * @param substring The captured string to replace.\n * @param args The list of groups captured by the expression.\n */\nexport type FormatKeysReplaceFn = (substring: string, ...args: string[]) => string;\n\nexport type FormatKeysOptions = {\n /**\n * The object to transform.\n */\n target: unknown;\n /**\n * A regular expression to match the keys to transform.\n */\n search: RegExp;\n /**\n * The callback that will be used to replace the matched substring. Think of `search` and\n * `replace` as the parameters of `String.replace`.\n */\n replace: FormatKeysReplaceFn;\n /**\n * A list of keys or paths where the transformation will be made. If not specified, the\n * function will use all the keys from the object.\n */\n include?: string[];\n /**\n * A list of keys or paths where the transformation won't be made.\n */\n exclude?: string[];\n /**\n * The delimiter that will separate the path components for both `include` and `exclude`.\n */\n pathDelimiter?: string;\n};\n\nexport type FormatKeysExtensionOptions = Omit<FormatKeysOptions, 'search' | 'replace'>;\n\n/**\n * Formats all the keys on an object using a way similar to `.replace(regexp, ...)` but\n * that also works recursively and with _\"object paths\"_.\n *\n * @param options The set of options to customize the transformation.\n * @template T The type of the returned object.\n * @example\n *\n * const target = {\n * prop_one: 'Charito!',\n * };\n * console.log(\n * formatKeys({\n * target,\n * // Find all the keys with snake case.\n * search: /([a-z])_([a-z])/g,\n * // Using the same .replace style callback, replace it with lower camel case.\n * replace: (_, firstLetter, secondLetter) => {\n * const newSecondLetter = secondLetter.toUpperCase();\n * return `${firstLetter}${newSecondLetter}`;\n * },\n * }),\n * );\n * // Will output { propOne: 'Charito!}.\n *\n */\nexport const formatKeys = <T = Record<string, unknown>>(\n options: FormatKeysOptions,\n): T => {\n const {\n target,\n search,\n replace,\n include = [],\n exclude = [],\n pathDelimiter = '.',\n } = options;\n // Re-case target.\n const useTarget = target as Record<string, unknown>;\n // First of all, get all the keys from the target.\n const keys = Object.keys(target as Record<string, unknown>);\n /**\n * Then, check which keys are parent to other objects.\n * This is saved on a dictionary not only because it makes it easier to check if the\n * method should make a recursive call for a key, but also because when parsing the\n * `exclude`\n * parameter, if one of items is a key (and not an specific path), the method won't make\n * the recursive call.\n *\n * @ignore\n */\n const hasChildrenByKey: Record<string, unknown> = {};\n keys.forEach((key) => {\n const value = useTarget[key];\n hasChildrenByKey[key] = !!(\n value &&\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value)\n );\n });\n /**\n * Escape the path delimiter and create two regular expression: One that removes the path\n * delimiter from the start of a path and one that removes it from the end.\n * They are later used to normalize paths in order to avoid \"incomplete paths\" (paths that\n * end or start with the delimiter).\n */\n const escapedPathDelimiter = pathDelimiter.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n const cleanPathStartExpression = new RegExp(`^${escapedPathDelimiter}`, 'i');\n const cleanPathEndExpression = new RegExp(`${escapedPathDelimiter}$`, 'i');\n /**\n * This dictionary will be used to save the `include` parameter that will be sent for specific\n * keys on recursive calls.\n * If `include` has a path like `myKey.mySubKey`, `myKey` is not transformed, but `mySubKey`\n * is saved on this dictionary (`{ myKey: ['mySubKey']}`) and when the method applies the\n * formatting to the object, if `myKey` has an object, it will make a recursive all and\n * send `['mySubKey]` as its `include` parameter.\n */\n const subIncludeByKey: Record<string, string[]> = {};\n /**\n * This will be an array containing the final list of `keys` that should be tranformed.\n * To be clear, these keys will be from the top level, so, they won't be paths.\n * Thd following blocks will parse `include` and `exclude` in order to extract the real keys,\n * prepare the `include` and `exclude` for recursive calls, and save the actual keys\n * from the object \"at the current level of this call\" (no, it's not thinking about the\n * children :P).\n */\n let keysToFormat: string[];\n // If the `include` parameter has paths/keys...\n if (include.length) {\n keysToFormat = include\n .map((includePath) => {\n // Normalize the path/key.\n const useIncludePath = includePath\n .replace(cleanPathStartExpression, '')\n .replace(cleanPathEndExpression, '');\n // Define the variable that will, eventually, have the real key.\n let key;\n // If the value is a path...\n if (useIncludePath.includes(pathDelimiter)) {\n // Split all its components.\n const pathParts = useIncludePath.split(pathDelimiter);\n // Get the first component, a.k.a. the real key.\n const pathKey = pathParts.shift()!;\n /**\n * This is very important: Since the path was specified with sub components\n * (like `myProp.mySubProp`), the method won't format the key, but the sub\n * key(s)\n * (`mySubProp`).\n * The `key` is set to `''` so it will be later removed using `.filter`.\n *\n * @ignore\n */\n key = '';\n /**\n * If there's no array for the key on the \"`include` dictionary for recursive calls\",\n * create an empty one.\n */\n if (!subIncludeByKey[pathKey]) {\n subIncludeByKey[pathKey] = [];\n }\n // Save the rest of the path to be sent on the recursive call as `include`.\n subIncludeByKey[pathKey]!.push(pathParts.join(pathDelimiter));\n } else {\n // If the value wasn't a path, assume it's a key, and set it to be returned.\n key = useIncludePath;\n }\n\n return key;\n })\n // Remove any _empty keys_.\n .filter((key) => key);\n } else {\n // There's nothing on the `include` parameter, so use all the keys.\n keysToFormat = keys;\n }\n /**\n * Similar to `subIncludeByKey`, this dictionary will be used to save the `exclude` parameter\n * that will be sent for specific keys on recursive calls.\n * If `exclude` has a path like `myKey.mySubKey`, `myKey` will be transformed, but `mySubKey`\n * is saved on this dictionary (`{ myKey: ['mySubKey']}`) and when the method applies the\n * formatting to the object, if `myKey` has an object, it will make a recursive all and\n * send `['mySubKey]` as its `exclude` parameter.\n */\n const subExcludeByKey: Record<string, string[]> = {};\n // If the `include` parameter has paths/keys...\n if (exclude.length) {\n /**\n * Create a dictionary of keys that should be removed from `keysToFormat`.\n * It's easier to have them on a list and use `.filter` than actually call `.splice` for\n * every key that should be removed.\n */\n const keysToRemove: string[] = [];\n exclude.forEach((excludePath) => {\n // Normalize the path/key.\n const useExcludePath = excludePath\n .replace(cleanPathStartExpression, '')\n .replace(cleanPathEndExpression, '');\n // If the value is a path...\n if (useExcludePath.includes(pathDelimiter)) {\n // Split all its components.\n const pathParts = useExcludePath.split(pathDelimiter);\n // Get the first component, a.k.a. the real key.\n const pathKey = pathParts.shift()!;\n /**\n * If there's no array for the key on the \"`exclude` dictionary for recursive calls\",\n * create an empty one.\n */\n if (!subExcludeByKey[pathKey]) {\n subExcludeByKey[pathKey] = [];\n }\n // Save the rest of the path to be sent on the recursive call as `exclude`.\n subExcludeByKey[pathKey]!.push(pathParts.join(pathDelimiter));\n } else {\n /**\n * If the value wasn't a path, assume it's a key, turn the flag on the \"children\n * dictionary\" to `false`, to prevent recursive calls, and add the key to the list\n * of keys that will be removed from `keysToFormat`.\n * Basically: If it's a key, don't format it and don't make recursive calls for\n * it.\n *\n * @ignore\n */\n hasChildrenByKey[useExcludePath] = false;\n keysToRemove.push(useExcludePath);\n }\n });\n // Remove keys that should be excluded.\n keysToFormat = keysToFormat.filter((key) => key && !keysToRemove.includes(key));\n }\n // \"Finally\", reduce all the keys from the object and create the new one...\n return keys.reduce<Record<string, unknown>>((newObj, key) => {\n /**\n * Define the new key and value for the object property. Depending on the validations,\n * they may be replaced with formatted ones.\n */\n let newKey;\n let newValue;\n /**\n * Get the current value for the key, in case it's needed for a recursive call or just\n * to send it back because it didn't need any change.\n */\n const value = useTarget[key];\n // If the key should be formatted, apply the formatting; otherwise, keep the original.\n if (keysToFormat.includes(key)) {\n newKey = key.replace(search, replace);\n } else {\n newKey = key;\n }\n /**\n * If the paths/keys on `exclude` didn't modify the \"children dictionary\" for the key and\n * the value is another object, make a recursive call; otherwise, just use the original\n * value.\n */\n if (hasChildrenByKey[key]) {\n newValue = formatKeys({\n target: value,\n search,\n replace,\n include: subIncludeByKey[key] || [],\n exclude: subExcludeByKey[key] || [],\n pathDelimiter,\n });\n } else {\n newValue = value;\n }\n // \"Done\", return the new object with the \"new key\" and the \"new value\".\n return { ...newObj, [newKey]: newValue };\n }, {}) as T;\n};\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case`\n * to `lowerCamelCase`.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n */\nexport const dashToLowerCamelKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])-([a-z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toUpperCase();\n return `${firstLetter}${newSecondLetter}`;\n },\n });\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case`\n * to `snake_case`.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n */\nexport const dashToSnakeKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])-([a-z])/g,\n replace: (_, firstLetter, secondLetter) => `${firstLetter}_${secondLetter}`,\n });\n","export type GetOptions = {\n /**\n * The object from where the property will be read.\n */\n target: unknown;\n /**\n * The path to the property.\n */\n path: string;\n /**\n * The delimiter that will separate the path components.\n */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`,\n * the method will silently fail and return `undefined`.\n */\n failWithError?: boolean;\n};\n\n/**\n * Returns the value of an object property using a path.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n * @throws {Error} If the path is invalid and `failWithError` is set to `true`.\n * @example\n *\n * const obj = {\n * propOne: {\n * propOneSub: 'Charito!',\n * },\n * propTwo: '!!!',\n * };\n * console.log(get({ target: obj, path: 'propOne.propOneSub' }));\n * // Will output 'Charito!'\n *\n */\nfunction get<T>(options: GetOptions): T | undefined;\nfunction get<T>(options: unknown, path: string): T | undefined;\nfunction get<T>(options: GetOptions | unknown, path?: string): T | undefined {\n let useOptions: GetOptions;\n if (typeof path === 'string') {\n useOptions = {\n target: options,\n path,\n };\n } else {\n useOptions = options as GetOptions;\n }\n\n const {\n target,\n path: usePath,\n pathDelimiter = '.',\n failWithError = false,\n } = useOptions;\n const useTarget = target as Record<string, unknown>;\n const parts = usePath.split(pathDelimiter);\n const first = parts.shift()!;\n let currentElement = useTarget[first] as Record<string, unknown>;\n if (typeof currentElement === 'undefined') {\n if (failWithError) {\n throw new Error(`There's nothing on '${usePath}'`);\n }\n\n return undefined;\n }\n\n if (!parts.length) {\n return currentElement as T;\n }\n\n let currentPath = first;\n parts.some((currentPart) => {\n let breakLoop = false;\n currentPath += `${pathDelimiter}${currentPart}`;\n currentElement = currentElement[currentPart] as Record<string, unknown>;\n if (typeof currentElement === 'undefined') {\n if (failWithError) {\n throw new Error(`There's nothing on '${currentPath}'`);\n } else {\n breakLoop = true;\n }\n }\n\n return breakLoop;\n });\n\n return currentElement as T;\n}\n\nexport { get };\n","import { copy } from './copy.js';\n\n/**\n * List of paths that are forbidden to use on the `set` function, as they could lead to\n * security issues.\n *\n * @access protected\n */\nconst FORBIDDEN_PATHS = ['__proto__', 'prototype', 'constructor'];\n\nexport type SetOptions = {\n /**\n * The object where the property will be set.\n */\n target: unknown;\n /**\n * The path for the property.\n */\n path: string;\n /**\n * The value to set on the property.\n */\n value: unknown;\n /**\n * The delimiter that will separate the path components.\n */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the method\n * will silently fail and return `undefined`.\n */\n failWithError?: boolean;\n};\n/**\n * Sets a property on an object using a path. If the path doesn't exist, it will be\n * created.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n * @throws {Error} If one of the path components is for a non-object property and\n * `failWithError` is set to `true`.\n * @example\n *\n * const target = {};\n * console.log(set({ target, path: 'some.prop.path', value: 'some-value' }));\n * // Will output { some: { prop: { path: 'some-value' } } }\n *\n */\nfunction set<T = Record<string, unknown>>(options: SetOptions): T | undefined;\nfunction set<T = Record<string, unknown>>(\n options: SetOptions | unknown,\n path: string,\n value: unknown,\n): T | undefined;\nfunction set<T = Record<string, unknown>>(\n options: SetOptions | unknown,\n path?: string,\n value?: unknown,\n): T | undefined {\n let useOptions: SetOptions;\n if (typeof path === 'string') {\n useOptions = {\n target: options,\n path,\n value,\n };\n } else {\n useOptions = options as SetOptions;\n }\n\n const {\n target,\n path: usePath,\n value: useValue,\n pathDelimiter = '.',\n failWithError = false,\n } = useOptions;\n const result = copy(target) as Record<string, unknown>;\n if (!usePath.includes(pathDelimiter)) {\n if (!usePath || FORBIDDEN_PATHS.includes(usePath.toLowerCase())) {\n return undefined;\n }\n\n result[usePath] = useValue;\n return result as T;\n }\n\n const parts = usePath.split(pathDelimiter);\n const isInvalid = parts.some(\n (part) => !part || FORBIDDEN_PATHS.includes(part.toLowerCase()),\n );\n\n if (isInvalid) {\n return undefined;\n }\n\n // Path validation ensures that every component is defined and non-empty.\n const last = parts.pop()!;\n let currentElement = result;\n let currentPath = '';\n let foundInvalid = false;\n parts.forEach((part) => {\n currentPath += `${pathDelimiter}${part}`;\n const element = currentElement[part];\n const elementType = typeof element;\n if (elementType === 'undefined') {\n currentElement[part] = {};\n currentElement = currentElement[part] as Record<string, unknown>;\n } else if (elementType === 'object') {\n currentElement = currentElement[part] as Record<string, unknown>;\n } else {\n const errorPath = currentPath.substring(pathDelimiter.length);\n if (failWithError) {\n throw new Error(\n `There's already an element of type '${elementType}' on '${errorPath}'`,\n );\n } else {\n foundInvalid = true;\n }\n }\n });\n\n if (foundInvalid) return undefined;\n\n currentElement[last] = useValue;\n\n return result as T | undefined;\n}\n\nexport { set };\n","import { get } from './get.js';\nimport { set } from './set.js';\nimport { copy } from './copy.js';\n/**\n * Used in the {@link extract} function to specify a path for a property, or an \"origin path\"\n * and an \"extraction path\".\n */\nexport type extractionPath = string | Record<string, string>;\n\nexport type ExtractOptions = {\n /**\n * The object from where the property/properties will be extracted.\n */\n target: unknown;\n /**\n * This can be a single path or a list of them. And for this method, the paths are not\n * only strings but can also be an object with a single key, that would be the path to\n * where to \"do the extraction\", and the value the path on the target object.\n */\n paths: extractionPath | extractionPath[];\n /**\n * The delimiter that will separate the path components.\n */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the\n * method will silently fail an empty object.\n */\n failWithError?: boolean;\n};\n/**\n * Extracts a property or properties from an object in order to create a new one.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n * @example\n *\n * const target = {\n * name: {\n * first: 'Pilar',\n * },\n * age: 3,\n * address: {\n * planet: 'earth',\n * something: 'else',\n * },\n * };\n * console.log(\n * extract({\n * target: obj,\n * paths: [{ name: 'name.first' }, 'age', 'address.planet'],\n * }),\n * );\n * // Will output { name: 'Pilar', age: 3, address: { planet: 'earth' } }\n *\n */\nexport const extract = <T = Record<string, unknown>>(\n options: ExtractOptions,\n): T | undefined => {\n const { target, paths, pathDelimiter = '.', failWithError = false } = options;\n const copied = copy(target) as Record<string, unknown>;\n let result: Record<string, unknown> = {};\n let failed = false;\n (Array.isArray(paths) ? paths : [paths])\n .reduce<Array<{ origin: string; customDest: boolean; dest: string }>>(\n (acc, objPath) => {\n let destPath: string;\n let originPath: string;\n if (typeof objPath === 'string') {\n destPath = objPath;\n originPath = objPath;\n } else {\n const [firstKey] = Object.keys(objPath);\n destPath = firstKey!;\n originPath = objPath[destPath]!;\n }\n\n acc.push({\n origin: originPath,\n customDest: destPath.includes(pathDelimiter),\n dest: destPath,\n });\n return acc;\n },\n [],\n )\n .some((pathInfo) => {\n let breakLoop = false;\n const value = get({\n target: copied,\n path: pathInfo.origin,\n pathDelimiter,\n failWithError,\n });\n if (typeof value !== 'undefined') {\n if (pathInfo.customDest) {\n const withCustomProp = set({\n target: result,\n path: pathInfo.dest,\n value,\n pathDelimiter,\n failWithError,\n });\n if (typeof withCustomProp === 'undefined') {\n breakLoop = true;\n failed = true;\n } else {\n result = withCustomProp;\n }\n } else {\n result[pathInfo.dest] = value;\n }\n }\n\n return breakLoop;\n });\n\n if (failed) return undefined;\n return result as T;\n};\n","import { copy } from './copy.js';\nimport { merge } from './merge.js';\n\n/**\n * Checks whether a key for an array or an Object should be flattened.\n *\n * @param key The key to check inside its parent.\n * @param value The value of the key.\n */\nexport type ShouldFlattenFn = (key: string, value: unknown) => boolean;\n\nexport type FlatOptions = {\n /**\n * The object to transform.\n */\n target: unknown;\n /**\n * A custom prefix to be added before the name of the properties. This can be used on\n * custom cases and it's also used when the method calls itself in order to flatten a\n * sub object.\n */\n prefix?: string;\n /**\n * The delimiter that will separate the path components.\n */\n pathDelimiter?: string;\n /**\n * A custom function that can be used in order to tell the function whether an Object or\n * an Array property should be flatten or not.\n */\n shouldFlatten?: ShouldFlattenFn;\n};\n/**\n * Flattens an object properties into a single level dictionary.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n * @example\n *\n * const target = {\n * propOne: {\n * propOneSub: 'Charito!',\n * },\n * propTwo: '!!!',\n * };\n * console.log(flat({ target });\n * // Will output { 'propOne.propOneSub': 'Charito!', propTwo: '!!!' }\n *\n */\nexport const flat = <T = Record<string, unknown>>(options: FlatOptions): T => {\n const { target, shouldFlatten, pathDelimiter = '.', prefix = '' } = options;\n const useTarget = target as Record<string, unknown>;\n let result: Record<string, unknown> = {};\n const namePrefix = prefix ? `${prefix}${pathDelimiter}` : '';\n Object.keys(useTarget).forEach((key) => {\n const name = `${namePrefix}${key}`;\n const value = useTarget[key] as unknown;\n const valueType = typeof value;\n const isObject = valueType === 'object' && value !== null;\n if (isObject && (!shouldFlatten || shouldFlatten(key, value))) {\n result = merge(\n result,\n flat({ target: value, pathDelimiter, prefix: name, shouldFlatten }),\n );\n } else {\n result[name] = isObject ? copy(value) : value;\n }\n });\n\n return result as T;\n};\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from\n * `lowerCamelCase` to `dash-case`.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n */\nexport const lowerCamelToDashKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])([A-Z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toLowerCase();\n return `${firstLetter}-${newSecondLetter}`;\n },\n });\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from\n * `lowerCamelCase` to `snake_case`.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n */\nexport const lowerCamelToSnakeKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])([A-Z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toLowerCase();\n return `${firstLetter}_${newSecondLetter}`;\n },\n });\n","import { copy } from './copy.js';\nimport { get } from './get.js';\n\nexport type RemoveOptions = {\n /**\n * The object from where the property will be removed.\n */\n target: unknown;\n /**\n * The path to the property.\n */\n path: string;\n /**\n * The delimiter that will separate the path components.\n */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the\n * function will silently fail.\n */\n failWithError?: boolean;\n /**\n * If this flag is `true` and after removing the property the parent object is empty,\n * it will remove it recursively until a non empty parent object is found.\n */\n cleanEmptyProperties?: boolean;\n};\n/**\n * Deletes a property of an object using a path.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n * @example\n *\n * const target = {\n * propOne: {\n * propOneSub: 'Charito!',\n * },\n * propTwo: '!!!',\n * };\n * console.log(remove({ target, path: 'propOne.propOneSub' }));\n * // Will output { propTwo: '!!!' }\n *\n */\nfunction remove<T = unknown>(options: RemoveOptions): T | undefined;\nfunction remove<T = unknown>(options: unknown, path: string): T | undefined;\nfunction remove<T = unknown>(\n options: RemoveOptions | unknown,\n path?: string,\n): T | undefined {\n let useOptions: RemoveOptions;\n if (typeof path === 'string') {\n useOptions = {\n target: options,\n path,\n };\n } else {\n useOptions = options as RemoveOptions;\n }\n\n const {\n target,\n path: usePath,\n pathDelimiter = '.',\n cleanEmptyProperties = true,\n failWithError = false,\n } = useOptions;\n\n const parts = usePath.split(pathDelimiter);\n const last = parts.pop()!;\n const result = copy(target) as Record<string, unknown>;\n if (!parts.length) {\n delete result[last];\n return result as T;\n }\n const parentPath = parts.join(pathDelimiter);\n const parentObj = get<Record<string, unknown>>({\n target: result,\n path: parentPath,\n pathDelimiter,\n failWithError,\n });\n\n if (typeof parentObj === 'undefined') {\n return undefined;\n }\n\n delete parentObj[last];\n if (cleanEmptyProperties && !Object.keys(parentObj).length) {\n return remove({\n target: result,\n path: parentPath,\n pathDelimiter,\n failWithError,\n cleanEmptyProperties,\n }) as T;\n }\n\n return result as T;\n}\n\nexport { remove };\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to\n * `dash-case`.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n */\nexport const snakeToDashKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])_([a-z])/g,\n replace: (_, firstLetter, secondLetter) => `${firstLetter}-${secondLetter}`,\n });\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to\n * `lowerCamelCase`.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n */\nexport const snakeToLowerCamelKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])_([a-z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toUpperCase();\n return `${firstLetter}${newSecondLetter}`;\n },\n });\n","import { set } from './set.js';\n\nexport type UnflatOptions = {\n /**\n * The object to transform.\n */\n target: unknown;\n /**\n * The delimiter that will separate the path components.\n */\n pathDelimiter?: string;\n};\n/**\n * This method does the exact opposite from `flat`: It takes an already flatten object and\n * restores it structure.\n *\n * @param options The options to use.\n * @template T The type of the returned object.\n * @example\n *\n * const target = {\n * 'propOne.propOneSub': 'Charito!',\n * propTwo: '!!!',\n * };\n * console.log(unflat({ target }));\n * // Will output { propOne: { propOneSub: 'Charito!' }, 'propTwo': '!!!' }\n *\n */\nexport const unflat = <T = Record<string, unknown>>(options: UnflatOptions): T => {\n const { target, pathDelimiter = '.' } = options;\n const useTarget = target as Record<string, unknown>;\n return Object.keys(useTarget).reduce<Record<string, unknown>>(\n (current, key) =>\n set({ target: current, path: key, value: useTarget[key], pathDelimiter })!,\n {},\n ) as T;\n};\n"],"mappings":"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","names":["extend","merge","targets","firstTarget","base","copy","target","merge","formatKeys","options","target","search","replace","include","exclude","pathDelimiter","useTarget","keys","hasChildrenByKey","key","value","escapedPathDelimiter","cleanPathStartExpression","cleanPathEndExpression","subIncludeByKey","keysToFormat","includePath","useIncludePath","pathParts","pathKey","subExcludeByKey","keysToRemove","excludePath","useExcludePath","newObj","newKey","newValue","dashToLowerCamelKeys","options","formatKeys","_","firstLetter","secondLetter","newSecondLetter","dashToSnakeKeys","options","formatKeys","_","firstLetter","secondLetter","get","options","path","useOptions","target","usePath","pathDelimiter","failWithError","useTarget","parts","first","currentElement","currentPath","currentPart","breakLoop","FORBIDDEN_PATHS","set","options","path","value","useOptions","target","usePath","useValue","pathDelimiter","failWithError","result","copy","parts","part","last","currentElement","currentPath","foundInvalid","elementType","errorPath","extract","options","target","paths","pathDelimiter","failWithError","copied","copy","result","failed","acc","objPath","destPath","originPath","firstKey","pathInfo","breakLoop","value","get","withCustomProp","set","flat","options","target","shouldFlatten","pathDelimiter","prefix","useTarget","result","namePrefix","key","name","value","isObject","merge","copy","lowerCamelToDashKeys","options","formatKeys","_","firstLetter","secondLetter","newSecondLetter","lowerCamelToSnakeKeys","options","formatKeys","_","firstLetter","secondLetter","newSecondLetter","remove","options","path","useOptions","target","usePath","pathDelimiter","cleanEmptyProperties","failWithError","parts","last","result","copy","parentPath","parentObj","get","snakeToDashKeys","options","formatKeys","_","firstLetter","secondLetter","snakeToLowerCamelKeys","options","formatKeys","_","firstLetter","secondLetter","newSecondLetter","unflat","options","target","pathDelimiter","useTarget","current","key","set"]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/fns/merge.ts","../src/fns/copy.ts","../src/fns/formatKeys.ts","../src/fns/dashToLowerCamelKeys.ts","../src/fns/dashToSnakeKeys.ts","../src/fns/get.ts","../src/fns/set.ts","../src/fns/extract.ts","../src/fns/flat.ts","../src/fns/lowerCamelToDashKeys.ts","../src/fns/lowerCamelToSnakeKeys.ts","../src/fns/remove.ts","../src/fns/snakeToDashKeys.ts","../src/fns/snakeToLowerCamelKeys.ts","../src/fns/unflat.ts"],"sourcesContent":["import extend from 'extend';\n\n/**\n * This method makes a deep merge of a list of objects into a new one. The method also\n * supports arrays: if the first element is an array, it will be merged into an array,\n * otherwise, it will be an object.\n *\n * @example\n * const objA = { a: 'first' };\n * const objB = { b: 'second' };\n * console.log(merge(objA, objB));\n * // Will output { a: 'first', b: 'second' }\n *\n * @example\n * const arrA = [{ a: 'first' }];\n * const arrB = [{ b: 'second' }];\n * console.log(merge(objA, objB));\n * // Will output [{ a: 'first', b: 'second' }]\n *\n * @template T The type of the merged object that will be returned.\n * @param targets The list of objects to merge.\n */\nexport const merge = <T = unknown>(...targets: unknown[]): T => {\n const [firstTarget] = targets;\n const base = Array.isArray(firstTarget) ? [] : {};\n return extend(true, base, ...targets) as T;\n};\n","import { merge } from './merge.js';\n\n/**\n * Creates a deep copy of a given object.\n *\n * @template T The type of the input object, which will be the same as the one returned.\n * @param target The object to copy.\n */\nexport const copy = <T>(target: T): T => merge(target);\n","/**\n * The callback that will be used to replace a key.\n *\n * @param substring The captured string to replace.\n * @param args The list of groups captured by the expression.\n */\nexport type FormatKeysReplaceFn = (substring: string, ...args: string[]) => string;\n\nexport type FormatKeysOptions = {\n /** The object to transform. */\n target: unknown;\n /** A regular expression to match the keys to transform. */\n search: RegExp;\n /**\n * The callback that will be used to replace the matched substring. Think of `search`\n * and `replace` as the parameters of `String.replace`.\n */\n replace: FormatKeysReplaceFn;\n /**\n * A list of keys or paths where the transformation will be made. If not specified, the\n * function will use all the keys from the object.\n */\n include?: string[];\n /** A list of keys or paths where the transformation won't be made. */\n exclude?: string[];\n /**\n * The delimiter that will separate the path components for both `include` and\n * `exclude`.\n */\n pathDelimiter?: string;\n};\n\nexport type FormatKeysExtensionOptions = Omit<FormatKeysOptions, 'search' | 'replace'>;\n\n/**\n * Formats all the keys on an object using a way similar to `.replace(regexp, ...)` but\n * that also works recursively and with _\"object paths\"_.\n *\n * @example\n * const target = {\n * prop_one: 'Charito!',\n * };\n * console.log(\n * formatKeys({\n * target,\n * // Find all the keys with snake case.\n * search: /([a-z])_([a-z])/g,\n * // Using the same .replace style callback, replace it with lower camel case.\n * replace: (_, firstLetter, secondLetter) => {\n * const newSecondLetter = secondLetter.toUpperCase();\n * return `${firstLetter}${newSecondLetter}`;\n * },\n * }),\n * );\n * // Will output { propOne: 'Charito!}.\n *\n * @template T The type of the returned object.\n * @param options The set of options to customize the transformation.\n */\nexport const formatKeys = <T = Record<string, unknown>>(\n options: FormatKeysOptions,\n): T => {\n const {\n target,\n search,\n replace,\n include = [],\n exclude = [],\n pathDelimiter = '.',\n } = options;\n // Re-case target.\n const useTarget = target as Record<string, unknown>;\n // First of all, get all the keys from the target.\n const keys = Object.keys(target as Record<string, unknown>);\n /**\n * Then, check which keys are parent to other objects. This is saved on a dictionary not\n * only because it makes it easier to check if the method should make a recursive call\n * for a key, but also because when parsing the `exclude` parameter, if one of items is\n * a key (and not an specific path), the method won't make the recursive call.\n *\n * @ignore\n */\n const hasChildrenByKey: Record<string, unknown> = {};\n keys.forEach((key) => {\n const value = useTarget[key];\n hasChildrenByKey[key] = !!(\n value &&\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value)\n );\n });\n /**\n * Escape the path delimiter and create two regular expression: One that removes the\n * path delimiter from the start of a path and one that removes it from the end. They\n * are later used to normalize paths in order to avoid \"incomplete paths\" (paths that\n * end or start with the delimiter).\n */\n const escapedPathDelimiter = pathDelimiter.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n const cleanPathStartExpression = new RegExp(`^${escapedPathDelimiter}`, 'i');\n const cleanPathEndExpression = new RegExp(`${escapedPathDelimiter}$`, 'i');\n /**\n * This dictionary will be used to save the `include` parameter that will be sent for\n * specific keys on recursive calls. If `include` has a path like `myKey.mySubKey`,\n * `myKey` is not transformed, but `mySubKey` is saved on this dictionary (`{ myKey:\n * ['mySubKey']}`) and when the method applies the formatting to the object, if `myKey`\n * has an object, it will make a recursive all and send `['mySubKey]` as its `include`\n * parameter.\n */\n const subIncludeByKey: Record<string, string[]> = {};\n /**\n * This will be an array containing the final list of `keys` that should be tranformed.\n * To be clear, these keys will be from the top level, so, they won't be paths. Thd\n * following blocks will parse `include` and `exclude` in order to extract the real\n * keys, prepare the `include` and `exclude` for recursive calls, and save the actual\n * keys from the object \"at the current level of this call\" (no, it's not thinking about\n * the children :P).\n */\n let keysToFormat: string[];\n // If the `include` parameter has paths/keys...\n if (include.length) {\n keysToFormat = include\n .map((includePath) => {\n // Normalize the path/key.\n const useIncludePath = includePath\n .replace(cleanPathStartExpression, '')\n .replace(cleanPathEndExpression, '');\n // Define the variable that will, eventually, have the real key.\n let key;\n // If the value is a path...\n if (useIncludePath.includes(pathDelimiter)) {\n // Split all its components.\n const pathParts = useIncludePath.split(pathDelimiter);\n // Get the first component, a.k.a. the real key.\n const pathKey = pathParts.shift()!;\n /**\n * This is very important: Since the path was specified with sub components\n * (like `myProp.mySubProp`), the method won't format the key, but the sub\n * key(s) (`mySubProp`). The `key` is set to `''` so it will be later removed\n * using `.filter`.\n *\n * @ignore\n */\n key = '';\n /**\n * If there's no array for the key on the \"`include` dictionary for recursive\n * calls\", create an empty one.\n */\n if (!subIncludeByKey[pathKey]) {\n subIncludeByKey[pathKey] = [];\n }\n // Save the rest of the path to be sent on the recursive call as `include`.\n subIncludeByKey[pathKey]!.push(pathParts.join(pathDelimiter));\n } else {\n // If the value wasn't a path, assume it's a key, and set it to be returned.\n key = useIncludePath;\n }\n\n return key;\n })\n // Remove any _empty keys_.\n .filter((key) => key);\n } else {\n // There's nothing on the `include` parameter, so use all the keys.\n keysToFormat = keys;\n }\n /**\n * Similar to `subIncludeByKey`, this dictionary will be used to save the `exclude`\n * parameter that will be sent for specific keys on recursive calls. If `exclude` has a\n * path like `myKey.mySubKey`, `myKey` will be transformed, but `mySubKey` is saved on\n * this dictionary (`{ myKey: ['mySubKey']}`) and when the method applies the formatting\n * to the object, if `myKey` has an object, it will make a recursive all and send\n * `['mySubKey]` as its `exclude` parameter.\n */\n const subExcludeByKey: Record<string, string[]> = {};\n // If the `include` parameter has paths/keys...\n if (exclude.length) {\n /**\n * Create a dictionary of keys that should be removed from `keysToFormat`. It's easier\n * to have them on a list and use `.filter` than actually call `.splice` for every key\n * that should be removed.\n */\n const keysToRemove: string[] = [];\n exclude.forEach((excludePath) => {\n // Normalize the path/key.\n const useExcludePath = excludePath\n .replace(cleanPathStartExpression, '')\n .replace(cleanPathEndExpression, '');\n // If the value is a path...\n if (useExcludePath.includes(pathDelimiter)) {\n // Split all its components.\n const pathParts = useExcludePath.split(pathDelimiter);\n // Get the first component, a.k.a. the real key.\n const pathKey = pathParts.shift()!;\n /**\n * If there's no array for the key on the \"`exclude` dictionary for recursive\n * calls\", create an empty one.\n */\n if (!subExcludeByKey[pathKey]) {\n subExcludeByKey[pathKey] = [];\n }\n // Save the rest of the path to be sent on the recursive call as `exclude`.\n subExcludeByKey[pathKey]!.push(pathParts.join(pathDelimiter));\n } else {\n /**\n * If the value wasn't a path, assume it's a key, turn the flag on the \"children\n * dictionary\" to `false`, to prevent recursive calls, and add the key to the list\n * of keys that will be removed from `keysToFormat`. Basically: If it's a key,\n * don't format it and don't make recursive calls for it.\n *\n * @ignore\n */\n hasChildrenByKey[useExcludePath] = false;\n keysToRemove.push(useExcludePath);\n }\n });\n // Remove keys that should be excluded.\n keysToFormat = keysToFormat.filter((key) => key && !keysToRemove.includes(key));\n }\n // \"Finally\", reduce all the keys from the object and create the new one...\n return keys.reduce<Record<string, unknown>>((newObj, key) => {\n /**\n * Define the new key and value for the object property. Depending on the validations,\n * they may be replaced with formatted ones.\n */\n let newKey;\n let newValue;\n /**\n * Get the current value for the key, in case it's needed for a recursive call or just\n * to send it back because it didn't need any change.\n */\n const value = useTarget[key];\n // If the key should be formatted, apply the formatting; otherwise, keep the original.\n if (keysToFormat.includes(key)) {\n newKey = key.replace(search, replace);\n } else {\n newKey = key;\n }\n /**\n * If the paths/keys on `exclude` didn't modify the \"children dictionary\" for the key\n * and the value is another object, make a recursive call; otherwise, just use the\n * original value.\n */\n if (hasChildrenByKey[key]) {\n newValue = formatKeys({\n target: value,\n search,\n replace,\n include: subIncludeByKey[key] || [],\n exclude: subExcludeByKey[key] || [],\n pathDelimiter,\n });\n } else {\n newValue = value;\n }\n // \"Done\", return the new object with the \"new key\" and the \"new value\".\n return { ...newObj, [newKey]: newValue };\n }, {}) as T;\n};\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case` to\n * `lowerCamelCase`.\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const dashToLowerCamelKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])-([a-z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toUpperCase();\n return `${firstLetter}${newSecondLetter}`;\n },\n });\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `dash-case` to\n * `snake_case`.\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const dashToSnakeKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])-([a-z])/g,\n replace: (_, firstLetter, secondLetter) => `${firstLetter}_${secondLetter}`,\n });\n","export type GetOptions = {\n /** The object from where the property will be read. */\n target: unknown;\n /** The path to the property. */\n path: string;\n /** The delimiter that will separate the path components. */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the\n * method will silently fail and return `undefined`.\n */\n failWithError?: boolean;\n};\n\n/**\n * Returns the value of an object property using a path.\n *\n * @example\n * const obj = {\n * propOne: {\n * propOneSub: 'Charito!',\n * },\n * propTwo: '!!!',\n * };\n * console.log(get({ target: obj, path: 'propOne.propOneSub' }));\n * // Will output 'Charito!'\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n * @throws {Error} If the path is invalid and `failWithError` is set to `true`.\n */\nfunction get<T>(options: GetOptions): T | undefined;\nfunction get<T>(options: unknown, path: string): T | undefined;\nfunction get<T>(options: GetOptions | unknown, path?: string): T | undefined {\n let useOptions: GetOptions;\n if (typeof path === 'string') {\n useOptions = {\n target: options,\n path,\n };\n } else {\n useOptions = options as GetOptions;\n }\n\n const {\n target,\n path: usePath,\n pathDelimiter = '.',\n failWithError = false,\n } = useOptions;\n const useTarget = target as Record<string, unknown>;\n const parts = usePath.split(pathDelimiter);\n const first = parts.shift()!;\n let currentElement = useTarget[first] as Record<string, unknown>;\n if (typeof currentElement === 'undefined') {\n if (failWithError) {\n throw new Error(`There's nothing on '${usePath}'`);\n }\n\n return undefined;\n }\n\n if (!parts.length) {\n return currentElement as T;\n }\n\n let currentPath = first;\n parts.some((currentPart) => {\n let breakLoop = false;\n currentPath += `${pathDelimiter}${currentPart}`;\n currentElement = currentElement[currentPart] as Record<string, unknown>;\n if (typeof currentElement === 'undefined') {\n if (failWithError) {\n throw new Error(`There's nothing on '${currentPath}'`);\n } else {\n breakLoop = true;\n }\n }\n\n return breakLoop;\n });\n\n return currentElement as T;\n}\n\nexport { get };\n","import { copy } from './copy.js';\n\n/**\n * List of paths that are forbidden to use on the `set` function, as they could lead to\n * security issues.\n *\n * @access protected\n */\nconst FORBIDDEN_PATHS = ['__proto__', 'prototype', 'constructor'];\n\nexport type SetOptions = {\n /** The object where the property will be set. */\n target: unknown;\n /** The path for the property. */\n path: string;\n /** The value to set on the property. */\n value: unknown;\n /** The delimiter that will separate the path components. */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the\n * method will silently fail and return `undefined`.\n */\n failWithError?: boolean;\n};\n/**\n * Sets a property on an object using a path. If the path doesn't exist, it will be\n * created.\n *\n * @example\n * const target = {};\n * console.log(set({ target, path: 'some.prop.path', value: 'some-value' }));\n * // Will output { some: { prop: { path: 'some-value' } } }\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n * @throws {Error} If one of the path components is for a non-object property and\n * `failWithError` is set to `true`.\n */\nfunction set<T = Record<string, unknown>>(options: SetOptions): T | undefined;\nfunction set<T = Record<string, unknown>>(\n options: SetOptions | unknown,\n path: string,\n value: unknown,\n): T | undefined;\nfunction set<T = Record<string, unknown>>(\n options: SetOptions | unknown,\n path?: string,\n value?: unknown,\n): T | undefined {\n let useOptions: SetOptions;\n if (typeof path === 'string') {\n useOptions = {\n target: options,\n path,\n value,\n };\n } else {\n useOptions = options as SetOptions;\n }\n\n const {\n target,\n path: usePath,\n value: useValue,\n pathDelimiter = '.',\n failWithError = false,\n } = useOptions;\n const result = copy(target) as Record<string, unknown>;\n if (!usePath.includes(pathDelimiter)) {\n if (!usePath || FORBIDDEN_PATHS.includes(usePath.toLowerCase())) {\n return undefined;\n }\n\n result[usePath] = useValue;\n return result as T;\n }\n\n const parts = usePath.split(pathDelimiter);\n const isInvalid = parts.some(\n (part) => !part || FORBIDDEN_PATHS.includes(part.toLowerCase()),\n );\n\n if (isInvalid) {\n return undefined;\n }\n\n // Path validation ensures that every component is defined and non-empty.\n const last = parts.pop()!;\n let currentElement = result;\n let currentPath = '';\n let foundInvalid = false;\n parts.forEach((part) => {\n currentPath += `${pathDelimiter}${part}`;\n const element = currentElement[part];\n const elementType = typeof element;\n if (elementType === 'undefined') {\n currentElement[part] = {};\n currentElement = currentElement[part] as Record<string, unknown>;\n } else if (elementType === 'object') {\n currentElement = currentElement[part] as Record<string, unknown>;\n } else {\n const errorPath = currentPath.substring(pathDelimiter.length);\n if (failWithError) {\n throw new Error(\n `There's already an element of type '${elementType}' on '${errorPath}'`,\n );\n } else {\n foundInvalid = true;\n }\n }\n });\n\n if (foundInvalid) return undefined;\n\n currentElement[last] = useValue;\n\n return result as T | undefined;\n}\n\nexport { set };\n","import { copy } from './copy.js';\nimport { get } from './get.js';\nimport { set } from './set.js';\n/**\n * Used in the {@link extract} function to specify a path for a property, or an \"origin\n * path\" and an \"extraction path\".\n */\nexport type extractionPath = string | Record<string, string>;\n\nexport type ExtractOptions = {\n /** The object from where the property/properties will be extracted. */\n target: unknown;\n /**\n * This can be a single path or a list of them. And for this method, the paths are not\n * only strings but can also be an object with a single key, that would be the path to\n * where to \"do the extraction\", and the value the path on the target object.\n */\n paths: extractionPath | extractionPath[];\n /** The delimiter that will separate the path components. */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the\n * method will silently fail an empty object.\n */\n failWithError?: boolean;\n};\n/**\n * Extracts a property or properties from an object in order to create a new one.\n *\n * @example\n * const target = {\n * name: {\n * first: 'Pilar',\n * },\n * age: 3,\n * address: {\n * planet: 'earth',\n * something: 'else',\n * },\n * };\n * console.log(\n * extract({\n * target: obj,\n * paths: [{ name: 'name.first' }, 'age', 'address.planet'],\n * }),\n * );\n * // Will output { name: 'Pilar', age: 3, address: { planet: 'earth' } }\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const extract = <T = Record<string, unknown>>(\n options: ExtractOptions,\n): T | undefined => {\n const { target, paths, pathDelimiter = '.', failWithError = false } = options;\n const copied = copy(target) as Record<string, unknown>;\n let result: Record<string, unknown> = {};\n let failed = false;\n (Array.isArray(paths) ? paths : [paths])\n .reduce<Array<{ origin: string; customDest: boolean; dest: string }>>(\n (acc, objPath) => {\n let destPath: string;\n let originPath: string;\n if (typeof objPath === 'string') {\n destPath = objPath;\n originPath = objPath;\n } else {\n const [firstKey] = Object.keys(objPath);\n destPath = firstKey!;\n originPath = objPath[destPath]!;\n }\n\n acc.push({\n origin: originPath,\n customDest: destPath.includes(pathDelimiter),\n dest: destPath,\n });\n return acc;\n },\n [],\n )\n .some((pathInfo) => {\n let breakLoop = false;\n const value = get({\n target: copied,\n path: pathInfo.origin,\n pathDelimiter,\n failWithError,\n });\n if (typeof value !== 'undefined') {\n if (pathInfo.customDest) {\n const withCustomProp = set({\n target: result,\n path: pathInfo.dest,\n value,\n pathDelimiter,\n failWithError,\n });\n if (typeof withCustomProp === 'undefined') {\n breakLoop = true;\n failed = true;\n } else {\n result = withCustomProp;\n }\n } else {\n result[pathInfo.dest] = value;\n }\n }\n\n return breakLoop;\n });\n\n if (failed) return undefined;\n return result as T;\n};\n","import { copy } from './copy.js';\nimport { merge } from './merge.js';\n\n/**\n * Checks whether a key for an array or an Object should be flattened.\n *\n * @param key The key to check inside its parent.\n * @param value The value of the key.\n */\nexport type ShouldFlattenFn = (key: string, value: unknown) => boolean;\n\nexport type FlatOptions = {\n /** The object to transform. */\n target: unknown;\n /**\n * A custom prefix to be added before the name of the properties. This can be used on\n * custom cases and it's also used when the method calls itself in order to flatten a\n * sub object.\n */\n prefix?: string;\n /** The delimiter that will separate the path components. */\n pathDelimiter?: string;\n /**\n * A custom function that can be used in order to tell the function whether an Object or\n * an Array property should be flatten or not.\n */\n shouldFlatten?: ShouldFlattenFn;\n};\n/**\n * Flattens an object properties into a single level dictionary.\n *\n * @example\n * const target = {\n * propOne: {\n * propOneSub: 'Charito!',\n * },\n * propTwo: '!!!',\n * };\n * console.log(flat({ target });\n * // Will output { 'propOne.propOneSub': 'Charito!', propTwo: '!!!' }\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const flat = <T = Record<string, unknown>>(options: FlatOptions): T => {\n const { target, shouldFlatten, pathDelimiter = '.', prefix = '' } = options;\n const useTarget = target as Record<string, unknown>;\n let result: Record<string, unknown> = {};\n const namePrefix = prefix ? `${prefix}${pathDelimiter}` : '';\n Object.keys(useTarget).forEach((key) => {\n const name = `${namePrefix}${key}`;\n const value = useTarget[key] as unknown;\n const valueType = typeof value;\n const isObject = valueType === 'object' && value !== null;\n if (isObject && (!shouldFlatten || shouldFlatten(key, value))) {\n result = merge(\n result,\n flat({ target: value, pathDelimiter, prefix: name, shouldFlatten }),\n );\n } else {\n result[name] = isObject ? copy(value) : value;\n }\n });\n\n return result as T;\n};\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `lowerCamelCase`\n * to `dash-case`.\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const lowerCamelToDashKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])([A-Z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toLowerCase();\n return `${firstLetter}-${newSecondLetter}`;\n },\n });\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from\n * `lowerCamelCase` to `snake_case`.\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const lowerCamelToSnakeKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])([A-Z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toLowerCase();\n return `${firstLetter}_${newSecondLetter}`;\n },\n });\n","import { copy } from './copy.js';\nimport { get } from './get.js';\n\nexport type RemoveOptions = {\n /** The object from where the property will be removed. */\n target: unknown;\n /** The path to the property. */\n path: string;\n /** The delimiter that will separate the path components. */\n pathDelimiter?: string;\n /**\n * Whether or not to throw an error when the path is invalid. If this is `false`, the\n * function will silently fail.\n */\n failWithError?: boolean;\n /**\n * If this flag is `true` and after removing the property the parent object is empty, it\n * will remove it recursively until a non empty parent object is found.\n */\n cleanEmptyProperties?: boolean;\n};\n/**\n * Deletes a property of an object using a path.\n *\n * @example\n * const target = {\n * propOne: {\n * propOneSub: 'Charito!',\n * },\n * propTwo: '!!!',\n * };\n * console.log(remove({ target, path: 'propOne.propOneSub' }));\n * // Will output { propTwo: '!!!' }\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nfunction remove<T = unknown>(options: RemoveOptions): T | undefined;\nfunction remove<T = unknown>(options: unknown, path: string): T | undefined;\nfunction remove<T = unknown>(\n options: RemoveOptions | unknown,\n path?: string,\n): T | undefined {\n let useOptions: RemoveOptions;\n if (typeof path === 'string') {\n useOptions = {\n target: options,\n path,\n };\n } else {\n useOptions = options as RemoveOptions;\n }\n\n const {\n target,\n path: usePath,\n pathDelimiter = '.',\n cleanEmptyProperties = true,\n failWithError = false,\n } = useOptions;\n\n const parts = usePath.split(pathDelimiter);\n const last = parts.pop()!;\n const result = copy(target) as Record<string, unknown>;\n if (!parts.length) {\n delete result[last];\n return result as T;\n }\n const parentPath = parts.join(pathDelimiter);\n const parentObj = get<Record<string, unknown>>({\n target: result,\n path: parentPath,\n pathDelimiter,\n failWithError,\n });\n\n if (typeof parentObj === 'undefined') {\n return undefined;\n }\n\n delete parentObj[last];\n if (cleanEmptyProperties && !Object.keys(parentObj).length) {\n return remove({\n target: result,\n path: parentPath,\n pathDelimiter,\n failWithError,\n cleanEmptyProperties,\n }) as T;\n }\n\n return result as T;\n}\n\nexport { remove };\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to\n * `dash-case`.\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const snakeToDashKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])_([a-z])/g,\n replace: (_, firstLetter, secondLetter) => `${firstLetter}-${secondLetter}`,\n });\n","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys.js';\n\n/**\n * A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to\n * `lowerCamelCase`.\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const snakeToLowerCamelKeys = <T>(options: FormatKeysExtensionOptions): T =>\n formatKeys<T>({\n ...options,\n search: /([a-z])_([a-z])/g,\n replace: (_, firstLetter, secondLetter) => {\n const newSecondLetter = secondLetter.toUpperCase();\n return `${firstLetter}${newSecondLetter}`;\n },\n });\n","import { set } from './set.js';\n\nexport type UnflatOptions = {\n /** The object to transform. */\n target: unknown;\n /** The delimiter that will separate the path components. */\n pathDelimiter?: string;\n};\n/**\n * This method does the exact opposite from `flat`: It takes an already flatten object and\n * restores it structure.\n *\n * @example\n * const target = {\n * 'propOne.propOneSub': 'Charito!',\n * propTwo: '!!!',\n * };\n * console.log(unflat({ target }));\n * // Will output { propOne: { propOneSub: 'Charito!' }, 'propTwo': '!!!' }\n *\n * @template T The type of the returned object.\n * @param options The options to use.\n */\nexport const unflat = <T = Record<string, unknown>>(options: UnflatOptions): T => {\n const { target, pathDelimiter = '.' } = options;\n const useTarget = target as Record<string, unknown>;\n return Object.keys(useTarget).reduce<Record<string, unknown>>(\n (current, key) =>\n set({ target: current, path: key, value: useTarget[key], pathDelimiter })!,\n {},\n ) as T;\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@homer0/object-utils",
3
3
  "description": "A small collection of utility methods to work with objects.",
4
- "version": "6.0.2",
4
+ "version": "6.0.5",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/homer0/packages.git",
@@ -37,12 +37,12 @@
37
37
  "extend": "^3.0.2"
38
38
  },
39
39
  "devDependencies": {
40
- "@homer0/oxlint-config": "0.3.0",
41
- "@homer0/tsconfig": "5.0.0",
40
+ "@homer0/oxlint-config": "1.0.3",
41
+ "@homer0/tsconfig": "5.0.1",
42
42
  "@types/extend": "^3.0.4",
43
43
  "@vitest/coverage-v8": "catalog:",
44
44
  "oxlint": "catalog:",
45
- "tsup": "catalog:",
45
+ "tsdown": "catalog:",
46
46
  "typescript": "catalog:",
47
47
  "unplugin-swc": "catalog:",
48
48
  "vitest": "catalog:"
@@ -56,8 +56,8 @@
56
56
  "lint:file": "oxlint $@",
57
57
  "test": "vitest run $@",
58
58
  "types:check": "tsc --noEmit && tsc --noEmit --project ./tests/tsconfig.json",
59
- "build": "tsup",
59
+ "build": "tsdown",
60
60
  "prepublishOnly": "pnpm run build"
61
61
  },
62
- "gitHead": "07328e8a7b1f1b73c46837692c8821a7badca190"
62
+ "gitHead": "27e773cc888ac2ffe26fabd5976a45ea7fdfaae8"
63
63
  }