@homer0/object-utils 1.0.2 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/dist/esm/index.js +88 -38
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +92 -39
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -64,13 +64,21 @@ const obj = {
|
|
|
64
64
|
propTwo: '!!!',
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
+
console.log(get(obj, 'propOne.propOneSub'));
|
|
68
|
+
// Will output 'Charito!'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
You can also use an options object to specify things like the `pathDelimiter`:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
67
74
|
console.log(
|
|
68
75
|
get({
|
|
69
76
|
target: obj,
|
|
70
77
|
path: 'propOne.propOneSub',
|
|
78
|
+
pathDelimiter: '.',
|
|
71
79
|
}),
|
|
72
80
|
);
|
|
73
|
-
// Will output 'Charito!'
|
|
81
|
+
// Will also output 'Charito!'
|
|
74
82
|
```
|
|
75
83
|
|
|
76
84
|
#### `set`
|
|
@@ -82,14 +90,22 @@ import { set } from '@homer0/object-utils';
|
|
|
82
90
|
|
|
83
91
|
const target = {};
|
|
84
92
|
|
|
93
|
+
console.log(set(target, 'some.prop.path', 'some-value'));
|
|
94
|
+
// Will output { some: { prop: { path: 'some-value' } } }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
And just like `get`, you can also use an options object:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
85
100
|
console.log(
|
|
86
101
|
set({
|
|
87
102
|
target,
|
|
88
103
|
path: 'some.prop.path',
|
|
89
104
|
value: 'some-value',
|
|
105
|
+
pathDelimiter: '.',
|
|
90
106
|
}),
|
|
91
107
|
);
|
|
92
|
-
// Will output { some: { prop: { path: 'some-value' } } }
|
|
108
|
+
// Will also output { some: { prop: { path: 'some-value' } } }
|
|
93
109
|
```
|
|
94
110
|
|
|
95
111
|
#### `extract`
|
|
@@ -133,13 +149,20 @@ const target = {
|
|
|
133
149
|
propTwo: '!!!',
|
|
134
150
|
};
|
|
135
151
|
|
|
152
|
+
console.log(remove(target, 'propOne.propOneSub'));
|
|
153
|
+
// Will output { propTwo: '!!!' }
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
You can also use an options object instead of the target and the path:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
136
159
|
console.log(
|
|
137
160
|
remove({
|
|
138
161
|
target,
|
|
139
162
|
path: 'propOne.propOneSub',
|
|
140
163
|
}),
|
|
141
164
|
);
|
|
142
|
-
// Will output { propTwo: '!!!' }
|
|
165
|
+
// Will also output { propTwo: '!!!' }
|
|
143
166
|
```
|
|
144
167
|
|
|
145
168
|
#### `flat`
|
package/dist/esm/index.js
CHANGED
|
@@ -113,15 +113,29 @@ var dashToSnakeKeys = (options) => formatKeys({
|
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
// src/fns/get.ts
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
function get(options, path) {
|
|
117
|
+
let useOptions;
|
|
118
|
+
if (typeof path === "string") {
|
|
119
|
+
useOptions = {
|
|
120
|
+
target: options,
|
|
121
|
+
path
|
|
122
|
+
};
|
|
123
|
+
} else {
|
|
124
|
+
useOptions = options;
|
|
125
|
+
}
|
|
126
|
+
const {
|
|
127
|
+
target,
|
|
128
|
+
path: usePath,
|
|
129
|
+
pathDelimiter = ".",
|
|
130
|
+
failWithError = false
|
|
131
|
+
} = useOptions;
|
|
118
132
|
const useTarget = target;
|
|
119
|
-
const parts =
|
|
133
|
+
const parts = usePath.split(pathDelimiter);
|
|
120
134
|
const first = parts.shift();
|
|
121
135
|
let currentElement = useTarget[first];
|
|
122
136
|
if (typeof currentElement === "undefined") {
|
|
123
137
|
if (failWithError) {
|
|
124
|
-
throw new Error(`There's nothing on '${
|
|
138
|
+
throw new Error(`There's nothing on '${usePath}'`);
|
|
125
139
|
}
|
|
126
140
|
return void 0;
|
|
127
141
|
}
|
|
@@ -143,17 +157,33 @@ var get = (options) => {
|
|
|
143
157
|
return breakLoop;
|
|
144
158
|
});
|
|
145
159
|
return currentElement;
|
|
146
|
-
}
|
|
160
|
+
}
|
|
147
161
|
|
|
148
162
|
// src/fns/set.ts
|
|
149
|
-
|
|
150
|
-
|
|
163
|
+
function set(options, path, value) {
|
|
164
|
+
let useOptions;
|
|
165
|
+
if (typeof path === "string") {
|
|
166
|
+
useOptions = {
|
|
167
|
+
target: options,
|
|
168
|
+
path,
|
|
169
|
+
value
|
|
170
|
+
};
|
|
171
|
+
} else {
|
|
172
|
+
useOptions = options;
|
|
173
|
+
}
|
|
174
|
+
const {
|
|
175
|
+
target,
|
|
176
|
+
path: usePath,
|
|
177
|
+
value: useValue,
|
|
178
|
+
pathDelimiter = ".",
|
|
179
|
+
failWithError = false
|
|
180
|
+
} = useOptions;
|
|
151
181
|
const result = copy(target);
|
|
152
|
-
if (!
|
|
153
|
-
result[
|
|
182
|
+
if (!usePath.includes(pathDelimiter)) {
|
|
183
|
+
result[usePath] = useValue;
|
|
154
184
|
return result;
|
|
155
185
|
}
|
|
156
|
-
const parts =
|
|
186
|
+
const parts = usePath.split(pathDelimiter);
|
|
157
187
|
const last = parts.pop();
|
|
158
188
|
let currentElement = result;
|
|
159
189
|
let currentPath = "";
|
|
@@ -170,7 +200,9 @@ var set = (options) => {
|
|
|
170
200
|
} else {
|
|
171
201
|
const errorPath = currentPath.substring(pathDelimiter.length);
|
|
172
202
|
if (failWithError) {
|
|
173
|
-
throw new Error(
|
|
203
|
+
throw new Error(
|
|
204
|
+
`There's already an element of type '${elementType}' on '${errorPath}'`
|
|
205
|
+
);
|
|
174
206
|
} else {
|
|
175
207
|
foundInvalid = true;
|
|
176
208
|
}
|
|
@@ -179,10 +211,10 @@ var set = (options) => {
|
|
|
179
211
|
if (foundInvalid)
|
|
180
212
|
return void 0;
|
|
181
213
|
if (result && last) {
|
|
182
|
-
currentElement[last] =
|
|
214
|
+
currentElement[last] = useValue;
|
|
183
215
|
}
|
|
184
216
|
return result;
|
|
185
|
-
}
|
|
217
|
+
}
|
|
186
218
|
|
|
187
219
|
// src/fns/extract.ts
|
|
188
220
|
var extract = (options) => {
|
|
@@ -190,24 +222,27 @@ var extract = (options) => {
|
|
|
190
222
|
const copied = copy(target);
|
|
191
223
|
let result = {};
|
|
192
224
|
let failed = false;
|
|
193
|
-
(Array.isArray(paths) ? paths : [paths]).reduce(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
225
|
+
(Array.isArray(paths) ? paths : [paths]).reduce(
|
|
226
|
+
(acc, objPath) => {
|
|
227
|
+
let destPath;
|
|
228
|
+
let originPath;
|
|
229
|
+
if (typeof objPath === "string") {
|
|
230
|
+
destPath = objPath;
|
|
231
|
+
originPath = objPath;
|
|
232
|
+
} else {
|
|
233
|
+
const [firstKey] = Object.keys(objPath);
|
|
234
|
+
destPath = firstKey;
|
|
235
|
+
originPath = objPath[destPath];
|
|
236
|
+
}
|
|
237
|
+
acc.push({
|
|
238
|
+
origin: originPath,
|
|
239
|
+
customDest: destPath.includes(pathDelimiter),
|
|
240
|
+
dest: destPath
|
|
241
|
+
});
|
|
242
|
+
return acc;
|
|
243
|
+
},
|
|
244
|
+
[]
|
|
245
|
+
).some((pathInfo) => {
|
|
211
246
|
let breakLoop = false;
|
|
212
247
|
const value = get({
|
|
213
248
|
target: copied,
|
|
@@ -253,7 +288,10 @@ var flat = (options) => {
|
|
|
253
288
|
const valueType = typeof value;
|
|
254
289
|
const isObject = valueType === "object" && value !== null;
|
|
255
290
|
if (isObject && (!shouldFlatten || shouldFlatten(key, value))) {
|
|
256
|
-
result = merge(
|
|
291
|
+
result = merge(
|
|
292
|
+
result,
|
|
293
|
+
flat({ target: value, pathDelimiter, prefix: name, shouldFlatten })
|
|
294
|
+
);
|
|
257
295
|
} else {
|
|
258
296
|
result[name] = isObject ? copy(value) : value;
|
|
259
297
|
}
|
|
@@ -282,15 +320,24 @@ var lowerCamelToSnakeKeys = (options) => formatKeys({
|
|
|
282
320
|
});
|
|
283
321
|
|
|
284
322
|
// src/fns/remove.ts
|
|
285
|
-
|
|
323
|
+
function remove(options, path) {
|
|
324
|
+
let useOptions;
|
|
325
|
+
if (typeof path === "string") {
|
|
326
|
+
useOptions = {
|
|
327
|
+
target: options,
|
|
328
|
+
path
|
|
329
|
+
};
|
|
330
|
+
} else {
|
|
331
|
+
useOptions = options;
|
|
332
|
+
}
|
|
286
333
|
const {
|
|
287
334
|
target,
|
|
288
|
-
path,
|
|
335
|
+
path: usePath,
|
|
289
336
|
pathDelimiter = ".",
|
|
290
337
|
cleanEmptyProperties = true,
|
|
291
338
|
failWithError = false
|
|
292
|
-
} =
|
|
293
|
-
const parts =
|
|
339
|
+
} = useOptions;
|
|
340
|
+
const parts = usePath.split(pathDelimiter);
|
|
294
341
|
const last = parts.pop();
|
|
295
342
|
const result = copy(target);
|
|
296
343
|
if (!parts.length) {
|
|
@@ -318,7 +365,7 @@ var remove = (options) => {
|
|
|
318
365
|
});
|
|
319
366
|
}
|
|
320
367
|
return result;
|
|
321
|
-
}
|
|
368
|
+
}
|
|
322
369
|
|
|
323
370
|
// src/fns/snakeToDashKeys.ts
|
|
324
371
|
var snakeToDashKeys = (options) => formatKeys({
|
|
@@ -341,7 +388,10 @@ var snakeToLowerCamelKeys = (options) => formatKeys({
|
|
|
341
388
|
var unflat = (options) => {
|
|
342
389
|
const { target, pathDelimiter = "." } = options;
|
|
343
390
|
const useTarget = target;
|
|
344
|
-
return Object.keys(useTarget).reduce(
|
|
391
|
+
return Object.keys(useTarget).reduce(
|
|
392
|
+
(current, key) => set({ target: current, path: key, value: useTarget[key], pathDelimiter }),
|
|
393
|
+
{}
|
|
394
|
+
);
|
|
345
395
|
};
|
|
346
396
|
export {
|
|
347
397
|
copy,
|
package/dist/esm/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';\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';\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';\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 */\nexport const get = <T>(options: GetOptions): T | undefined => {\n const { target, path, pathDelimiter = '.', failWithError = false } = options;\n const useTarget = target as Record<string, unknown>;\n const parts = path.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 '${path}'`);\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","import { copy } from './copy';\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 */\nexport const set = <T = Record<string, unknown>>(options: SetOptions): T | undefined => {\n const { target, path, value, pathDelimiter = '.', failWithError = false } = options;\n const result = copy(target) as Record<string, unknown>;\n if (!path.includes(pathDelimiter)) {\n result[path] = value;\n return result as T;\n }\n\n const parts = path.split(pathDelimiter);\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 if (result && last) {\n currentElement[last] = value;\n }\n\n return result as T | undefined;\n};\n","import { get } from './get';\nimport { set } from './set';\nimport { copy } from './copy';\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';\nimport { merge } from './merge';\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';\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';\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';\nimport { get } from './get';\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 */\nexport const remove = <T = unknown>(options: RemoveOptions): T | undefined => {\n const {\n target,\n path,\n pathDelimiter = '.',\n cleanEmptyProperties = true,\n failWithError = false,\n } = options;\n\n const parts = path.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","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys';\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';\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';\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":[]}
|
|
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';\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';\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';\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';\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 result[usePath] = useValue;\n return result as T;\n }\n\n const parts = usePath.split(pathDelimiter);\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 if (result && last) {\n currentElement[last] = useValue;\n }\n\n return result as T | undefined;\n}\n\nexport { set };\n","import { get } from './get';\nimport { set } from './set';\nimport { copy } from './copy';\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';\nimport { merge } from './merge';\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';\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';\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';\nimport { get } from './get';\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';\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';\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';\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":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -227,7 +227,8 @@ declare type GetOptions = {
|
|
|
227
227
|
* // Will output 'Charito!'
|
|
228
228
|
*
|
|
229
229
|
*/
|
|
230
|
-
declare
|
|
230
|
+
declare function get<T>(options: GetOptions): T | undefined;
|
|
231
|
+
declare function get<T>(options: unknown, path: string): T | undefined;
|
|
231
232
|
|
|
232
233
|
/**
|
|
233
234
|
* A shorthand method for {@link formatKeys} that transforms the keys from
|
|
@@ -312,7 +313,8 @@ declare type RemoveOptions = {
|
|
|
312
313
|
* // Will output { propTwo: '!!!' }
|
|
313
314
|
*
|
|
314
315
|
*/
|
|
315
|
-
declare
|
|
316
|
+
declare function remove<T = unknown>(options: RemoveOptions): T | undefined;
|
|
317
|
+
declare function remove<T = unknown>(options: unknown, path: string): T | undefined;
|
|
316
318
|
|
|
317
319
|
declare type SetOptions = {
|
|
318
320
|
/**
|
|
@@ -352,7 +354,8 @@ declare type SetOptions = {
|
|
|
352
354
|
* // Will output { some: { prop: { path: 'some-value' } } }
|
|
353
355
|
*
|
|
354
356
|
*/
|
|
355
|
-
declare
|
|
357
|
+
declare function set<T = Record<string, unknown>>(options: SetOptions): T | undefined;
|
|
358
|
+
declare function set<T = Record<string, unknown>>(options: SetOptions | unknown, path: string, value: unknown): T | undefined;
|
|
356
359
|
|
|
357
360
|
/**
|
|
358
361
|
* A shorthand method for {@link formatKeys} that transforms the keys from `snake_case` to
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
}
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
21
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
25
|
|
|
23
26
|
// src/index.ts
|
|
@@ -156,15 +159,29 @@ var dashToSnakeKeys = (options) => formatKeys({
|
|
|
156
159
|
});
|
|
157
160
|
|
|
158
161
|
// src/fns/get.ts
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
function get(options, path) {
|
|
163
|
+
let useOptions;
|
|
164
|
+
if (typeof path === "string") {
|
|
165
|
+
useOptions = {
|
|
166
|
+
target: options,
|
|
167
|
+
path
|
|
168
|
+
};
|
|
169
|
+
} else {
|
|
170
|
+
useOptions = options;
|
|
171
|
+
}
|
|
172
|
+
const {
|
|
173
|
+
target,
|
|
174
|
+
path: usePath,
|
|
175
|
+
pathDelimiter = ".",
|
|
176
|
+
failWithError = false
|
|
177
|
+
} = useOptions;
|
|
161
178
|
const useTarget = target;
|
|
162
|
-
const parts =
|
|
179
|
+
const parts = usePath.split(pathDelimiter);
|
|
163
180
|
const first = parts.shift();
|
|
164
181
|
let currentElement = useTarget[first];
|
|
165
182
|
if (typeof currentElement === "undefined") {
|
|
166
183
|
if (failWithError) {
|
|
167
|
-
throw new Error(`There's nothing on '${
|
|
184
|
+
throw new Error(`There's nothing on '${usePath}'`);
|
|
168
185
|
}
|
|
169
186
|
return void 0;
|
|
170
187
|
}
|
|
@@ -186,17 +203,33 @@ var get = (options) => {
|
|
|
186
203
|
return breakLoop;
|
|
187
204
|
});
|
|
188
205
|
return currentElement;
|
|
189
|
-
}
|
|
206
|
+
}
|
|
190
207
|
|
|
191
208
|
// src/fns/set.ts
|
|
192
|
-
|
|
193
|
-
|
|
209
|
+
function set(options, path, value) {
|
|
210
|
+
let useOptions;
|
|
211
|
+
if (typeof path === "string") {
|
|
212
|
+
useOptions = {
|
|
213
|
+
target: options,
|
|
214
|
+
path,
|
|
215
|
+
value
|
|
216
|
+
};
|
|
217
|
+
} else {
|
|
218
|
+
useOptions = options;
|
|
219
|
+
}
|
|
220
|
+
const {
|
|
221
|
+
target,
|
|
222
|
+
path: usePath,
|
|
223
|
+
value: useValue,
|
|
224
|
+
pathDelimiter = ".",
|
|
225
|
+
failWithError = false
|
|
226
|
+
} = useOptions;
|
|
194
227
|
const result = copy(target);
|
|
195
|
-
if (!
|
|
196
|
-
result[
|
|
228
|
+
if (!usePath.includes(pathDelimiter)) {
|
|
229
|
+
result[usePath] = useValue;
|
|
197
230
|
return result;
|
|
198
231
|
}
|
|
199
|
-
const parts =
|
|
232
|
+
const parts = usePath.split(pathDelimiter);
|
|
200
233
|
const last = parts.pop();
|
|
201
234
|
let currentElement = result;
|
|
202
235
|
let currentPath = "";
|
|
@@ -213,7 +246,9 @@ var set = (options) => {
|
|
|
213
246
|
} else {
|
|
214
247
|
const errorPath = currentPath.substring(pathDelimiter.length);
|
|
215
248
|
if (failWithError) {
|
|
216
|
-
throw new Error(
|
|
249
|
+
throw new Error(
|
|
250
|
+
`There's already an element of type '${elementType}' on '${errorPath}'`
|
|
251
|
+
);
|
|
217
252
|
} else {
|
|
218
253
|
foundInvalid = true;
|
|
219
254
|
}
|
|
@@ -222,10 +257,10 @@ var set = (options) => {
|
|
|
222
257
|
if (foundInvalid)
|
|
223
258
|
return void 0;
|
|
224
259
|
if (result && last) {
|
|
225
|
-
currentElement[last] =
|
|
260
|
+
currentElement[last] = useValue;
|
|
226
261
|
}
|
|
227
262
|
return result;
|
|
228
|
-
}
|
|
263
|
+
}
|
|
229
264
|
|
|
230
265
|
// src/fns/extract.ts
|
|
231
266
|
var extract = (options) => {
|
|
@@ -233,24 +268,27 @@ var extract = (options) => {
|
|
|
233
268
|
const copied = copy(target);
|
|
234
269
|
let result = {};
|
|
235
270
|
let failed = false;
|
|
236
|
-
(Array.isArray(paths) ? paths : [paths]).reduce(
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
271
|
+
(Array.isArray(paths) ? paths : [paths]).reduce(
|
|
272
|
+
(acc, objPath) => {
|
|
273
|
+
let destPath;
|
|
274
|
+
let originPath;
|
|
275
|
+
if (typeof objPath === "string") {
|
|
276
|
+
destPath = objPath;
|
|
277
|
+
originPath = objPath;
|
|
278
|
+
} else {
|
|
279
|
+
const [firstKey] = Object.keys(objPath);
|
|
280
|
+
destPath = firstKey;
|
|
281
|
+
originPath = objPath[destPath];
|
|
282
|
+
}
|
|
283
|
+
acc.push({
|
|
284
|
+
origin: originPath,
|
|
285
|
+
customDest: destPath.includes(pathDelimiter),
|
|
286
|
+
dest: destPath
|
|
287
|
+
});
|
|
288
|
+
return acc;
|
|
289
|
+
},
|
|
290
|
+
[]
|
|
291
|
+
).some((pathInfo) => {
|
|
254
292
|
let breakLoop = false;
|
|
255
293
|
const value = get({
|
|
256
294
|
target: copied,
|
|
@@ -296,7 +334,10 @@ var flat = (options) => {
|
|
|
296
334
|
const valueType = typeof value;
|
|
297
335
|
const isObject = valueType === "object" && value !== null;
|
|
298
336
|
if (isObject && (!shouldFlatten || shouldFlatten(key, value))) {
|
|
299
|
-
result = merge(
|
|
337
|
+
result = merge(
|
|
338
|
+
result,
|
|
339
|
+
flat({ target: value, pathDelimiter, prefix: name, shouldFlatten })
|
|
340
|
+
);
|
|
300
341
|
} else {
|
|
301
342
|
result[name] = isObject ? copy(value) : value;
|
|
302
343
|
}
|
|
@@ -325,15 +366,24 @@ var lowerCamelToSnakeKeys = (options) => formatKeys({
|
|
|
325
366
|
});
|
|
326
367
|
|
|
327
368
|
// src/fns/remove.ts
|
|
328
|
-
|
|
369
|
+
function remove(options, path) {
|
|
370
|
+
let useOptions;
|
|
371
|
+
if (typeof path === "string") {
|
|
372
|
+
useOptions = {
|
|
373
|
+
target: options,
|
|
374
|
+
path
|
|
375
|
+
};
|
|
376
|
+
} else {
|
|
377
|
+
useOptions = options;
|
|
378
|
+
}
|
|
329
379
|
const {
|
|
330
380
|
target,
|
|
331
|
-
path,
|
|
381
|
+
path: usePath,
|
|
332
382
|
pathDelimiter = ".",
|
|
333
383
|
cleanEmptyProperties = true,
|
|
334
384
|
failWithError = false
|
|
335
|
-
} =
|
|
336
|
-
const parts =
|
|
385
|
+
} = useOptions;
|
|
386
|
+
const parts = usePath.split(pathDelimiter);
|
|
337
387
|
const last = parts.pop();
|
|
338
388
|
const result = copy(target);
|
|
339
389
|
if (!parts.length) {
|
|
@@ -361,7 +411,7 @@ var remove = (options) => {
|
|
|
361
411
|
});
|
|
362
412
|
}
|
|
363
413
|
return result;
|
|
364
|
-
}
|
|
414
|
+
}
|
|
365
415
|
|
|
366
416
|
// src/fns/snakeToDashKeys.ts
|
|
367
417
|
var snakeToDashKeys = (options) => formatKeys({
|
|
@@ -384,7 +434,10 @@ var snakeToLowerCamelKeys = (options) => formatKeys({
|
|
|
384
434
|
var unflat = (options) => {
|
|
385
435
|
const { target, pathDelimiter = "." } = options;
|
|
386
436
|
const useTarget = target;
|
|
387
|
-
return Object.keys(useTarget).reduce(
|
|
437
|
+
return Object.keys(useTarget).reduce(
|
|
438
|
+
(current, key) => set({ target: current, path: key, value: useTarget[key], pathDelimiter }),
|
|
439
|
+
{}
|
|
440
|
+
);
|
|
388
441
|
};
|
|
389
442
|
// Annotate the CommonJS export names for ESM import in node:
|
|
390
443
|
0 && (module.exports = {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../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":["export * from './fns/copy';\nexport * from './fns/dashToLowerCamelKeys';\nexport * from './fns/dashToSnakeKeys';\nexport * from './fns/extract';\nexport * from './fns/flat';\nexport * from './fns/formatKeys';\nexport * from './fns/get';\nexport * from './fns/lowerCamelToDashKeys';\nexport * from './fns/lowerCamelToSnakeKeys';\nexport * from './fns/merge';\nexport * from './fns/remove';\nexport * from './fns/set';\nexport * from './fns/snakeToDashKeys';\nexport * from './fns/snakeToLowerCamelKeys';\nexport * from './fns/unflat';\n","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';\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';\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';\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 */\nexport const get = <T>(options: GetOptions): T | undefined => {\n const { target, path, pathDelimiter = '.', failWithError = false } = options;\n const useTarget = target as Record<string, unknown>;\n const parts = path.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 '${path}'`);\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","import { copy } from './copy';\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 */\nexport const set = <T = Record<string, unknown>>(options: SetOptions): T | undefined => {\n const { target, path, value, pathDelimiter = '.', failWithError = false } = options;\n const result = copy(target) as Record<string, unknown>;\n if (!path.includes(pathDelimiter)) {\n result[path] = value;\n return result as T;\n }\n\n const parts = path.split(pathDelimiter);\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 if (result && last) {\n currentElement[last] = value;\n }\n\n return result as T | undefined;\n};\n","import { get } from './get';\nimport { set } from './set';\nimport { copy } from './copy';\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';\nimport { merge } from './merge';\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';\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';\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';\nimport { get } from './get';\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 */\nexport const remove = <T = unknown>(options: RemoveOptions): T | undefined => {\n const {\n target,\n path,\n pathDelimiter = '.',\n cleanEmptyProperties = true,\n failWithError = false,\n } = options;\n\n const parts = path.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","import { formatKeys, type FormatKeysExtensionOptions } from './formatKeys';\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';\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';\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":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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":["export * from './fns/copy';\nexport * from './fns/dashToLowerCamelKeys';\nexport * from './fns/dashToSnakeKeys';\nexport * from './fns/extract';\nexport * from './fns/flat';\nexport * from './fns/formatKeys';\nexport * from './fns/get';\nexport * from './fns/lowerCamelToDashKeys';\nexport * from './fns/lowerCamelToSnakeKeys';\nexport * from './fns/merge';\nexport * from './fns/remove';\nexport * from './fns/set';\nexport * from './fns/snakeToDashKeys';\nexport * from './fns/snakeToLowerCamelKeys';\nexport * from './fns/unflat';\n","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';\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';\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';\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';\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 result[usePath] = useValue;\n return result as T;\n }\n\n const parts = usePath.split(pathDelimiter);\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 if (result && last) {\n currentElement[last] = useValue;\n }\n\n return result as T | undefined;\n}\n\nexport { set };\n","import { get } from './get';\nimport { set } from './set';\nimport { copy } from './copy';\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';\nimport { merge } from './merge';\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';\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';\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';\nimport { get } from './get';\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';\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';\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';\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"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homer0/object-utils",
|
|
3
|
-
"description": "A small collection of utility methods to work with objects",
|
|
4
|
-
"version": "1.
|
|
3
|
+
"description": "A small collection of utility methods to work with objects.",
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/homer0/packages.git",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/extend": "^3.0.1",
|
|
30
|
-
"jest": "^
|
|
31
|
-
"ts-jest": "^
|
|
32
|
-
"tsup": "^6.
|
|
33
|
-
"typescript": "^4.
|
|
30
|
+
"jest": "^29.2.1",
|
|
31
|
+
"ts-jest": "^29.0.3",
|
|
32
|
+
"tsup": "^6.3.0",
|
|
33
|
+
"typescript": "^4.8.4"
|
|
34
34
|
},
|
|
35
35
|
"engine-strict": true,
|
|
36
36
|
"engines": {
|
|
@@ -40,10 +40,11 @@
|
|
|
40
40
|
"module": "./dist/esm/index.js",
|
|
41
41
|
"types": "./dist/index.d.ts",
|
|
42
42
|
"scripts": {
|
|
43
|
+
"lint": "eslint .",
|
|
43
44
|
"test": "jest -c ./.jestrc.js",
|
|
44
45
|
"types:check": "tsc --noEmit && tsc --noEmit --project ./tests/tsconfig.json",
|
|
45
46
|
"build": "tsup src/index.ts",
|
|
46
47
|
"prepublishOnly": "npm run build"
|
|
47
48
|
},
|
|
48
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "e584e4ef93ede1065a91a1d3e88e070662acb66e"
|
|
49
50
|
}
|