@hichchi/utils 0.0.1-alpha.1 → 0.0.1-beta.1

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.
Files changed (106) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +6236 -1032
  3. package/constants/constants.d.ts +223 -0
  4. package/constants/constants.js +227 -0
  5. package/constants/constants.js.map +1 -0
  6. package/constants/english-inflection-rules.d.ts +53 -0
  7. package/constants/english-inflection-rules.js +360 -0
  8. package/constants/english-inflection-rules.js.map +1 -0
  9. package/constants/index.d.ts +2 -0
  10. package/constants/index.js +6 -0
  11. package/constants/index.js.map +1 -0
  12. package/enums/index.d.ts +1 -0
  13. package/{src → enums}/index.js +1 -1
  14. package/enums/index.js.map +1 -0
  15. package/enums/template-tag.enum.d.ts +33 -0
  16. package/enums/template-tag.enum.js +39 -0
  17. package/enums/template-tag.enum.js.map +1 -0
  18. package/index.d.ts +5 -0
  19. package/index.js +9 -0
  20. package/index.js.map +1 -0
  21. package/interfaces/index.d.ts +3 -0
  22. package/interfaces/index.js +7 -0
  23. package/interfaces/index.js.map +1 -0
  24. package/interfaces/infinite-object.interface.d.ts +45 -0
  25. package/interfaces/infinite-object.interface.js +3 -0
  26. package/interfaces/infinite-object.interface.js.map +1 -0
  27. package/interfaces/inflection-rule.interfaces.d.ts +142 -0
  28. package/interfaces/inflection-rule.interfaces.js +3 -0
  29. package/interfaces/inflection-rule.interfaces.js.map +1 -0
  30. package/interfaces/path-value-set.interface.d.ts +79 -0
  31. package/interfaces/path-value-set.interface.js +3 -0
  32. package/interfaces/path-value-set.interface.js.map +1 -0
  33. package/package.json +4 -4
  34. package/readme-top.md +182 -6
  35. package/types/deep-partial.type.d.ts +47 -0
  36. package/types/deep-partial.type.js +3 -0
  37. package/types/deep-partial.type.js.map +1 -0
  38. package/types/index.d.ts +34 -0
  39. package/types/index.js +38 -0
  40. package/types/index.js.map +1 -0
  41. package/types/is-already-in-path.type.d.ts +24 -0
  42. package/types/is-already-in-path.type.js +3 -0
  43. package/types/is-already-in-path.type.js.map +1 -0
  44. package/types/is-empty.type.d.ts +25 -0
  45. package/types/is-empty.type.js +3 -0
  46. package/types/is-empty.type.js.map +1 -0
  47. package/types/is-primitive.type.d.ts +27 -0
  48. package/types/is-primitive.type.js +4 -0
  49. package/types/is-primitive.type.js.map +1 -0
  50. package/types/literal-object.type.d.ts +49 -0
  51. package/types/literal-object.type.js +3 -0
  52. package/types/literal-object.type.js.map +1 -0
  53. package/{src/lib/types.d.ts → types/loose-autocomplete.type.d.ts} +18 -6
  54. package/types/loose-autocomplete.type.js +3 -0
  55. package/types/loose-autocomplete.type.js.map +1 -0
  56. package/types/partial-with-null.type.d.ts +27 -0
  57. package/types/partial-with-null.type.js +3 -0
  58. package/types/partial-with-null.type.js.map +1 -0
  59. package/types/prettify.type.d.ts +23 -0
  60. package/types/prettify.type.js +3 -0
  61. package/types/prettify.type.js.map +1 -0
  62. package/types/type.type.d.ts +21 -0
  63. package/{src/lib/interfaces.js → types/type.type.js} +1 -1
  64. package/types/type.type.js.map +1 -0
  65. package/utils/assertions.utils.d.ts +150 -0
  66. package/utils/assertions.utils.js +163 -0
  67. package/utils/assertions.utils.js.map +1 -0
  68. package/utils/file.utils.d.ts +87 -0
  69. package/{src/lib → utils}/file.utils.js +78 -26
  70. package/utils/file.utils.js.map +1 -0
  71. package/{src/lib → utils}/index.d.ts +3 -5
  72. package/{src/lib → utils}/index.js +3 -5
  73. package/utils/index.js.map +1 -0
  74. package/utils/object.utils.d.ts +912 -0
  75. package/utils/object.utils.js +1069 -0
  76. package/utils/object.utils.js.map +1 -0
  77. package/utils/string-template.utils.d.ts +169 -0
  78. package/utils/string-template.utils.js +269 -0
  79. package/utils/string-template.utils.js.map +1 -0
  80. package/utils/string.utils.d.ts +932 -0
  81. package/utils/string.utils.js +1255 -0
  82. package/utils/string.utils.js.map +1 -0
  83. package/utils/url.utils.d.ts +99 -0
  84. package/utils/url.utils.js +112 -0
  85. package/utils/url.utils.js.map +1 -0
  86. package/src/index.d.ts +0 -1
  87. package/src/index.js.map +0 -1
  88. package/src/lib/assertions.utils.d.ts +0 -55
  89. package/src/lib/assertions.utils.js +0 -68
  90. package/src/lib/assertions.utils.js.map +0 -1
  91. package/src/lib/file.utils.d.ts +0 -25
  92. package/src/lib/file.utils.js.map +0 -1
  93. package/src/lib/index.js.map +0 -1
  94. package/src/lib/interfaces.d.ts +0 -6
  95. package/src/lib/interfaces.js.map +0 -1
  96. package/src/lib/object.utils.d.ts +0 -265
  97. package/src/lib/object.utils.js +0 -414
  98. package/src/lib/object.utils.js.map +0 -1
  99. package/src/lib/string-template.utils.d.ts +0 -25
  100. package/src/lib/string-template.utils.js +0 -40
  101. package/src/lib/string-template.utils.js.map +0 -1
  102. package/src/lib/string.utils.d.ts +0 -217
  103. package/src/lib/string.utils.js +0 -314
  104. package/src/lib/string.utils.js.map +0 -1
  105. package/src/lib/types.js +0 -4
  106. package/src/lib/types.js.map +0 -1
@@ -0,0 +1,912 @@
1
+ import { InfiniteObject, PathValueSet } from "../interfaces";
2
+ import { LiteralObject, PartialWithNull } from "../types";
3
+ /**
4
+ * Deep copy an object.
5
+ * @template T Type of the object.
6
+ * @param {T} obj Object to copy.
7
+ * @returns {T} Copied object.
8
+ *
9
+ * @example
10
+ * ```TypeScript
11
+ * // Example usage
12
+ * const object = {
13
+ * name: "John Doe"
14
+ * }
15
+ *
16
+ * const copiedObject = deepCopy(object);
17
+ * ```
18
+ */
19
+ export declare function deepCopy<T>(obj: T): T;
20
+ /**
21
+ * Get the key of a map by value.
22
+ * @param {Map<string, unknown>} map Map to get key from.
23
+ * @param {unknown} value Value to get key for.
24
+ * @returns {string | undefined} Key of the map.
25
+ *
26
+ * @example
27
+ * ```TypeScript
28
+ * // Example usage
29
+ * const user = new Map<string, string>([
30
+ * ["firstName", "John"],
31
+ * ["lastName", "Doe"],
32
+ * ["preferredName", "John"],
33
+ * ["age", 30],
34
+ * ]);
35
+ *
36
+ * const key = getMapKey(user, "value2");
37
+ *
38
+ * // Example output: "firstName"
39
+ * ```
40
+ */
41
+ export declare function getMapKey(map: Map<string, unknown>, value: unknown): string | undefined;
42
+ /**
43
+ * Retrieves all keys from a Map where the corresponding values contain a specified substring.
44
+ *
45
+ * This utility function searches through a Map's values and returns an array of keys
46
+ * whose associated values include the provided partial string. The search is case-sensitive
47
+ * and uses JavaScript's native string.includes() method for matching.
48
+ *
49
+ * This is particularly useful for implementing search functionality, filtering operations,
50
+ * or finding related entries in configuration maps, user preference stores, or any
51
+ * key-value data structure where you need to locate entries by partial value matching.
52
+ *
53
+ * @param {Map<string, string>} map - The Map to search through for matching values
54
+ * @param {string} partialValue - The substring to search for within the Map's values
55
+ * @returns {string[]} An array of keys whose corresponding values contain the partial value
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * // Search user preferences for entries containing "John"
60
+ * const userPreferences = new Map<string, string>([
61
+ * ["displayName", "John Doe"],
62
+ * ["firstName", "John"],
63
+ * ["lastName", "Doe"],
64
+ * ["preferredName", "Johnny"],
65
+ * ["email", "john.doe@example.com"]
66
+ * ]);
67
+ *
68
+ * const johnKeys = getMapKeys(userPreferences, "John");
69
+ * // Returns: ["displayName", "firstName", "email"]
70
+ * ```
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Find configuration keys related to database settings
75
+ * const config = new Map<string, string>([
76
+ * ["db_host", "localhost"],
77
+ * ["db_port", "5432"],
78
+ * ["cache_host", "redis-server"],
79
+ * ["db_name", "myapp_database"],
80
+ * ["log_level", "debug"]
81
+ * ]);
82
+ *
83
+ * const dbKeys = getMapKeys(config, "db");
84
+ * // Returns: ["db_name"] (only values containing "db", not keys)
85
+ * ```
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * // Search in a translations map
90
+ * const translations = new Map<string, string>([
91
+ * ["welcome_message", "Welcome to our application"],
92
+ * ["error_message", "An error occurred"],
93
+ * ["success_message", "Operation completed successfully"],
94
+ * ["info_message", "Please check your information"]
95
+ * ]);
96
+ *
97
+ * const messageKeys = getMapKeys(translations, "message");
98
+ * // Returns: ["welcome_message", "error_message", "success_message", "info_message"]
99
+ * ```
100
+ *
101
+ * @remarks
102
+ * - The search is case-sensitive; "John" will not match "john"
103
+ * - Returns an empty array if no matches are found
104
+ * - The function iterates through all Map entries, so performance scales with Map size
105
+ * - Only works with Maps that have string values; other value types will cause runtime errors
106
+ */
107
+ export declare const getMapKeys: (map: Map<string, string>, partialValue: string) => string[];
108
+ /**
109
+ * Groups an array of objects into a Map based on a key extraction function.
110
+ *
111
+ * This utility function takes an array of objects and organizes them into groups
112
+ * based on a common key or property. The grouping is performed using a key extraction
113
+ * function that you provide, which determines how each object should be categorized.
114
+ * The result is a Map where each key represents a group and the value is an array
115
+ * of objects belonging to that group.
116
+ *
117
+ * This is particularly useful for data analysis, reporting, organizing collections
118
+ * for display purposes, or preparing data for further processing where items need
119
+ * to be categorized by shared characteristics.
120
+ *
121
+ * @template K - The type of the grouping key (can be string, number, boolean, etc.)
122
+ * @template V - The type of the objects being grouped
123
+ * @param {Array<V>} list - The array of objects to group
124
+ * @param {(input: V) => K} keyGetter - A function that extracts the grouping key from each object.
125
+ * This function receives an object and should return the value
126
+ * to group by. If the function returns null or undefined,
127
+ * the object will be grouped under a null key.
128
+ * @returns {Map<K | null, Array<V>>} A Map where keys are the grouping values and values are arrays
129
+ * of objects that share that grouping key
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * // Group users by age
134
+ * interface User {
135
+ * name: string;
136
+ * age: number;
137
+ * department: string;
138
+ * }
139
+ *
140
+ * const users: User[] = [
141
+ * { name: "John", age: 30, department: "Engineering" },
142
+ * { name: "Jane", age: 25, department: "Marketing" },
143
+ * { name: "Bob", age: 30, department: "Engineering" },
144
+ * { name: "Alice", age: 25, department: "Sales" },
145
+ * { name: "Charlie", age: 35, department: "Engineering" }
146
+ * ];
147
+ *
148
+ * const usersByAge = groupBy(users, user => user.age);
149
+ * // Returns:
150
+ * // Map {
151
+ * // 30 => [
152
+ * // { name: "John", age: 30, department: "Engineering" },
153
+ * // { name: "Bob", age: 30, department: "Engineering" }
154
+ * // ],
155
+ * // 25 => [
156
+ * // { name: "Jane", age: 25, department: "Marketing" },
157
+ * // { name: "Alice", age: 25, department: "Sales" }
158
+ * // ],
159
+ * // 35 => [
160
+ * // { name: "Charlie", age: 35, department: "Engineering" }
161
+ * // ]
162
+ * // }
163
+ * ```
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * // Group products by category
168
+ * interface Product {
169
+ * id: number;
170
+ * name: string;
171
+ * category: string;
172
+ * price: number;
173
+ * }
174
+ *
175
+ * const products: Product[] = [
176
+ * { id: 1, name: "Laptop", category: "Electronics", price: 999 },
177
+ * { id: 2, name: "Book", category: "Education", price: 29 },
178
+ * { id: 3, name: "Phone", category: "Electronics", price: 699 },
179
+ * { id: 4, name: "Pen", category: "Office", price: 5 }
180
+ * ];
181
+ *
182
+ * const productsByCategory = groupBy(products, product => product.category);
183
+ * // Useful for creating category-based product listings
184
+ * ```
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * // Group tasks by completion status with boolean keys
189
+ * interface Task {
190
+ * id: number;
191
+ * title: string;
192
+ * completed: boolean;
193
+ * }
194
+ *
195
+ * const tasks: Task[] = [
196
+ * { id: 1, title: "Review code", completed: true },
197
+ * { id: 2, title: "Write tests", completed: false },
198
+ * { id: 3, title: "Deploy app", completed: true },
199
+ * { id: 4, title: "Update docs", completed: false }
200
+ * ];
201
+ *
202
+ * const tasksByStatus = groupBy(tasks, task => task.completed);
203
+ * // Returns Map with boolean keys: true and false
204
+ * ```
205
+ *
206
+ * @remarks
207
+ * - The function preserves the original order of objects within each group
208
+ * - If the keyGetter function returns null or undefined, those objects will be grouped under a null key
209
+ * - The Map structure allows for efficient lookups and iteration over groups
210
+ * - Works with any type of grouping key (string, number, boolean, objects, etc.)
211
+ * - Empty arrays will return an empty Map
212
+ */
213
+ export declare const groupBy: <K, V>(list: Array<V>, keyGetter: (input: V) => K) => Map<K | null, Array<V>>;
214
+ /**
215
+ * Retrieves all values from a Map that contain a specified substring.
216
+ *
217
+ * This utility function searches through a Map's values and returns an array of all values
218
+ * that include the provided partial string. The search is case-sensitive and uses JavaScript's
219
+ * native string.includes() method for matching. This is the counterpart to getMapKeys(),
220
+ * but instead of returning the keys, it returns the actual values that match.
221
+ *
222
+ * This is particularly useful for implementing search functionality where you need to find
223
+ * and display matching content, filtering data for autocomplete features, or extracting
224
+ * related values from configuration maps, user data, or any key-value store where you
225
+ * need to locate entries by partial content matching.
226
+ *
227
+ * @param {Map<string, string>} map - The Map to search through for matching values
228
+ * @param {string} partialValue - The substring to search for within the Map's values
229
+ * @returns {string[]} An array of values that contain the specified partial value
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * // Search user information for values containing "John"
234
+ * const userInfo = new Map<string, string>([
235
+ * ["fullName", "John Doe"],
236
+ * ["firstName", "John"],
237
+ * ["lastName", "Doe"],
238
+ * ["nickname", "Johnny"],
239
+ * ["email", "john.doe@example.com"],
240
+ * ["phone", "555-0123"]
241
+ * ]);
242
+ *
243
+ * const johnValues = searchMapValues(userInfo, "John");
244
+ * // Returns: ["John Doe", "John", "Johnny", "john.doe@example.com"]
245
+ * ```
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * // Find error messages containing specific keywords
250
+ * const errorMessages = new Map<string, string>([
251
+ * ["auth_failed", "Authentication failed. Please check your credentials."],
252
+ * ["network_error", "Network connection failed. Please try again."],
253
+ * ["validation_error", "Validation failed for the provided data."],
254
+ * ["timeout_error", "Request timeout. The server took too long to respond."],
255
+ * ["permission_denied", "Access denied. You don't have permission."]
256
+ * ]);
257
+ *
258
+ * const failedMessages = searchMapValues(errorMessages, "failed");
259
+ * // Returns: ["Authentication failed. Please check your credentials.",
260
+ * // "Network connection failed. Please try again.",
261
+ * // "Validation failed for the provided data."]
262
+ * ```
263
+ *
264
+ * @example
265
+ * ```typescript
266
+ * // Search configuration values for environment-specific settings
267
+ * const config = new Map<string, string>([
268
+ * ["api_url", "https://api.production.example.com"],
269
+ * ["db_host", "production-db.example.com"],
270
+ * ["cache_url", "redis://production-cache.example.com"],
271
+ * ["log_level", "error"],
272
+ * ["debug_mode", "false"]
273
+ * ]);
274
+ *
275
+ * const productionValues = searchMapValues(config, "production");
276
+ * // Returns: ["https://api.production.example.com",
277
+ * // "production-db.example.com",
278
+ * // "redis://production-cache.example.com"]
279
+ * ```
280
+ *
281
+ * @remarks
282
+ * - The search is case-sensitive; "John" will not match "john"
283
+ * - Returns an empty array if no matches are found
284
+ * - The function iterates through all Map entries, so performance scales with Map size
285
+ * - Only works with Maps that have string values; other value types will cause runtime errors
286
+ * - Values are returned in the order they appear in the Map iteration
287
+ *
288
+ * @see {@link getMapKeys} Function to get keys whose values contain a substring
289
+ */
290
+ export declare const searchMapValues: (map: Map<string, string>, partialValue: string) => string[];
291
+ /**
292
+ * Gets a value from a nested object using a dot-notation path string.
293
+ *
294
+ * This function safely traverses a deeply nested object structure using a string path
295
+ * with dot notation. It handles both object properties and array indices within the path.
296
+ *
297
+ * @template T - Type of the value to be returned.
298
+ * @param {InfiniteObject} obj - The object to retrieve the value from.
299
+ * @param {string} path - The dot-notation path to the desired value.
300
+ * - Use dots to navigate through nested objects: 'user.profile.address'
301
+ * - Use array notation for accessing array elements: 'items[0]' or 'users[2].name'
302
+ * @returns {T | undefined} - The value at the specified path, or undefined if:
303
+ * - Any part of the path doesn't exist
304
+ * - An array index is out of bounds
305
+ * - The path format is invalid
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * // Simple nested object property
310
+ * const user = {
311
+ * profile: {
312
+ * name: "John Doe",
313
+ * contact: { email: "john@example.com" }
314
+ * }
315
+ * };
316
+ * const email = getValueByPath<string>(user, "profile.contact.email");
317
+ * // Returns: "john@example.com"
318
+ * ```
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * // Accessing array elements
323
+ * const data = {
324
+ * users: [
325
+ * { id: 1, name: "Alice" },
326
+ * { id: 2, name: "Bob" }
327
+ * ]
328
+ * };
329
+ * const name = getValueByPath<string>(data, "users[1].name");
330
+ * // Returns: "Bob"
331
+ * ```
332
+ */
333
+ export declare const getValueByPath: <T>(obj: InfiniteObject, path: string) => T | undefined;
334
+ /**
335
+ * Converts a nested object into a flattened PathValueSet representation.
336
+ *
337
+ * This function transforms a hierarchical object structure into a flat key-value map
338
+ * where keys represent paths to values in the original object using dot notation.
339
+ *
340
+ * The function recursively traverses the object and flattens nested properties,
341
+ * converting object hierarchies like `{ user: { name: 'John' } }` into
342
+ * path-based entries like `{ 'user.name': 'John' }`.
343
+ *
344
+ * @param {LiteralObject} obj - The nested object to flatten
345
+ * @returns {PathValueSet} - A flattened representation where:
346
+ * - Keys are dot-notation paths to values in the original object
347
+ * - Values are primitive values (strings, numbers, booleans) from the original object
348
+ *
349
+ * @remarks
350
+ * - Array values will be preserved as-is (not flattened into separate paths)
351
+ * - Only primitive values (string, number, boolean) are supported as leaf values
352
+ * - Circular references are not handled and will cause a stack overflow
353
+ *
354
+ * @see {@link pathValueSetToObject} The inverse operation to convert a PathValueSet back to a nested object
355
+ * @see {@link PathValueSet} The interface for the returned flattened object
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * // Flatten a nested user object
360
+ * const user = {
361
+ * id: 123,
362
+ * name: "John Doe",
363
+ * isActive: true,
364
+ * profile: {
365
+ * age: 30,
366
+ * address: {
367
+ * city: "New York",
368
+ * zip: "10001"
369
+ * }
370
+ * }
371
+ * };
372
+ *
373
+ * const flattened = objectToPathValueSet(user);
374
+ *
375
+ * // Result:
376
+ * // {
377
+ * // "id": 123,
378
+ * // "name": "John Doe",
379
+ * // "isActive": true,
380
+ * // "profile.age": 30,
381
+ * // "profile.address.city": "New York",
382
+ * // "profile.address.zip": "10001"
383
+ * // }
384
+ * ```
385
+ */
386
+ export declare function objectToPathValueSet(obj: LiteralObject): PathValueSet;
387
+ /**
388
+ * Converts a flattened PathValueSet back into a nested object structure.
389
+ *
390
+ * This function is the inverse of `objectToPathValueSet`. It takes a flat map of
391
+ * dot-notation paths to values and reconstructs a hierarchical object structure.
392
+ *
393
+ * Each key in the input PathValueSet represents a path through the object hierarchy,
394
+ * with dots separating each level. The function builds a nested object structure by
395
+ * parsing these paths and placing values at the appropriate locations.
396
+ *
397
+ * @template R - The type of the returned object (defaults to object)
398
+ * @param {PathValueSet} pathValueSet - A flattened object with dot-notation path keys
399
+ * @returns {R} - A reconstructed nested object with the original hierarchy
400
+ *
401
+ * @remarks
402
+ * - Paths are validated for safety to prevent injection attacks
403
+ * - Invalid paths are silently skipped (not included in the result)
404
+ * - Path components should contain only alphanumeric characters, underscores, hyphens, and dots
405
+ *
406
+ * @see {@link objectToPathValueSet} The inverse operation to convert an object to PathValueSet
407
+ * @see {@link PathValueSet} The interface for the input flattened object
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * // Convert a flat PathValueSet to a nested object
412
+ * const flatData = {
413
+ * "id": 123,
414
+ * "name": "John Doe",
415
+ * "profile.age": 30,
416
+ * "profile.address.city": "New York",
417
+ * "profile.address.zip": "10001"
418
+ * };
419
+ *
420
+ * const nestedObject = pathValueSetToObject(flatData);
421
+ *
422
+ * Result:
423
+ * // {
424
+ * // id: 123,
425
+ * // name: "John Doe",
426
+ * // profile: {
427
+ * // age: 30,
428
+ * // address: {
429
+ * // city: "New York",
430
+ * // zip: "10001"
431
+ * // }
432
+ * // }
433
+ * // }
434
+ * ```
435
+ *
436
+ * @example
437
+ * ```typescript
438
+ * // Typed return value
439
+ * interface User {
440
+ * id: number;
441
+ * name: string;
442
+ * profile: {
443
+ * age: number;
444
+ * address: {
445
+ * city: string;
446
+ * zip: string;
447
+ * };
448
+ * };
449
+ * }
450
+ *
451
+ * const userData = pathValueSetToObject<User>(flatData);
452
+ * // Returns object with User type
453
+ * ```
454
+ */
455
+ export declare function pathValueSetToObject<R = object>(pathValueSet: Record<string, any>): R;
456
+ /**
457
+ * Creates a new object by omitting specified properties and undefined values from the original object.
458
+ *
459
+ * This utility function performs a selective copy of an object, excluding both explicitly
460
+ * specified properties and any properties with undefined values. The function modifies
461
+ * the original object in-place by deleting the unwanted properties, making it useful for
462
+ * cleaning up objects before serialization, API calls, or data processing.
463
+ *
464
+ * This is particularly useful for preparing data for API requests where you need to remove
465
+ * sensitive fields, clean up form data, or exclude certain properties from being sent to
466
+ * external services. It's also helpful for removing undefined values that might cause
467
+ * issues in JSON serialization or database operations.
468
+ *
469
+ * @template T - The type of the object being processed
470
+ * @param {Partial<T>} obj - The object to process and remove properties from.
471
+ * This object will be modified in-place.
472
+ * @param {(keyof T)[]} [keys] - Optional array of property keys to omit from the object.
473
+ * If not provided, only undefined properties will be removed.
474
+ * @returns {Partial<T>} The same object reference with specified properties and undefined values removed
475
+ *
476
+ * @example
477
+ * ```typescript
478
+ * // Remove specific properties and undefined values
479
+ * interface User {
480
+ * id: number;
481
+ * name: string;
482
+ * email: string;
483
+ * role: string;
484
+ * address?: string;
485
+ * phone?: string;
486
+ * }
487
+ *
488
+ * const user: Partial<User> = {
489
+ * id: 123,
490
+ * name: "John Doe",
491
+ * email: "john@example.com",
492
+ * role: "admin",
493
+ * address: undefined,
494
+ * phone: "555-0123"
495
+ * };
496
+ *
497
+ * const cleanUser = omit(user, ["role"]);
498
+ * // Returns: { id: 123, name: "John Doe", email: "john@example.com", phone: "555-0123" }
499
+ * // Note: 'role' and 'address' (undefined) are removed
500
+ * ```
501
+ *
502
+ * @example
503
+ * ```typescript
504
+ * // Remove only undefined values (no specific keys)
505
+ * const formData = {
506
+ * firstName: "John",
507
+ * lastName: "Doe",
508
+ * middleName: undefined,
509
+ * email: "john@example.com",
510
+ * phone: undefined
511
+ * };
512
+ *
513
+ * const cleanFormData = omit(formData);
514
+ * // Returns: { firstName: "John", lastName: "Doe", email: "john@example.com" }
515
+ * ```
516
+ *
517
+ * @example
518
+ * ```typescript
519
+ * // Prepare data for API request by removing sensitive fields
520
+ * interface UserProfile {
521
+ * id: number;
522
+ * username: string;
523
+ * email: string;
524
+ * password: string;
525
+ * internalNotes: string;
526
+ * createdAt: Date;
527
+ * }
528
+ *
529
+ * const userProfile: Partial<UserProfile> = {
530
+ * id: 1,
531
+ * username: "johndoe",
532
+ * email: "john@example.com",
533
+ * password: "secret123",
534
+ * internalNotes: "VIP customer",
535
+ * createdAt: new Date()
536
+ * };
537
+ *
538
+ * const publicProfile = omit(userProfile, ["password", "internalNotes"]);
539
+ * // Safe to send to client: { id: 1, username: "johndoe", email: "john@example.com", createdAt: Date }
540
+ * ```
541
+ *
542
+ * @remarks
543
+ * - This function modifies the original object in-place rather than creating a copy
544
+ * - Both explicitly specified keys and undefined properties are removed
545
+ * - If the input object is falsy (null, undefined), it's returned as-is
546
+ * - The function uses delete operator, which may affect object performance in some JavaScript engines
547
+ * - Properties with null values are preserved (only undefined values are automatically removed)
548
+ *
549
+ * @see {@link prune} Function for more comprehensive object cleaning including null and empty values
550
+ */
551
+ export declare const omit: <T extends {
552
+ [key: string]: unknown;
553
+ }>(obj: Partial<T>, keys?: (keyof T)[]) => Partial<T>;
554
+ /**
555
+ * Creates a deep copy of an object with all empty, null, undefined, and optionally prototype properties removed.
556
+ *
557
+ * This utility function recursively traverses an object and creates a clean copy by excluding
558
+ * properties that are null, undefined, or empty strings. It performs a deep cleaning operation,
559
+ * processing nested objects recursively to ensure that the entire object hierarchy is pruned
560
+ * of unwanted values.
561
+ *
562
+ * This is particularly useful for preparing data for serialization, cleaning up API responses,
563
+ * removing empty form fields, or ensuring that only meaningful data is processed or stored.
564
+ * The function is especially valuable when working with deeply nested objects that may contain
565
+ * sparse data or when you need to eliminate all traces of empty values from complex data structures.
566
+ *
567
+ * @template T - The type of the object being pruned
568
+ * @param {PartialWithNull<T>} obj - The object to prune. Can contain null, undefined, or empty values.
569
+ * @param {boolean} [omitPrototype=false] - Whether to exclude inherited properties from the prototype chain.
570
+ * If true, only own properties will be included in the result.
571
+ * If false (default), inherited enumerable properties will be processed.
572
+ * @returns {T} A new object with all empty, null, and undefined properties recursively removed
573
+ *
574
+ * @example
575
+ * ```typescript
576
+ * // Clean up a user profile with nested empty values
577
+ * interface UserProfile {
578
+ * id: number;
579
+ * name: string;
580
+ * contact: {
581
+ * email: string;
582
+ * phone?: string;
583
+ * address?: {
584
+ * street: string;
585
+ * city: string;
586
+ * zip?: string;
587
+ * };
588
+ * };
589
+ * preferences: {
590
+ * theme: string;
591
+ * notifications?: boolean;
592
+ * };
593
+ * }
594
+ *
595
+ * const userProfile = {
596
+ * id: 123,
597
+ * name: "John Doe",
598
+ * contact: {
599
+ * email: "john@example.com",
600
+ * phone: "",
601
+ * address: {
602
+ * street: "123 Main St",
603
+ * city: "New York",
604
+ * zip: null
605
+ * }
606
+ * },
607
+ * preferences: {
608
+ * theme: "dark",
609
+ * notifications: undefined
610
+ * }
611
+ * };
612
+ *
613
+ * const cleanProfile = prune(userProfile);
614
+ * // Returns:
615
+ * // {
616
+ * // id: 123,
617
+ * // name: "John Doe",
618
+ * // contact: {
619
+ * // email: "john@example.com",
620
+ * // address: {
621
+ * // street: "123 Main St",
622
+ * // city: "New York"
623
+ * // }
624
+ * // },
625
+ * // preferences: {
626
+ * // theme: "dark"
627
+ * // }
628
+ * // }
629
+ * ```
630
+ *
631
+ * @example
632
+ * ```typescript
633
+ * // Clean up form data before submission
634
+ * const formData = {
635
+ * firstName: "John",
636
+ * lastName: "Doe",
637
+ * middleName: "",
638
+ * email: "john@example.com",
639
+ * phone: null,
640
+ * address: {
641
+ * street: "123 Main St",
642
+ * apartment: "",
643
+ * city: "New York",
644
+ * state: undefined,
645
+ * zip: "10001"
646
+ * },
647
+ * emergencyContact: {
648
+ * name: "",
649
+ * phone: null
650
+ * }
651
+ * };
652
+ *
653
+ * const cleanFormData = prune(formData);
654
+ * // Returns only fields with meaningful values:
655
+ * // {
656
+ * // firstName: "John",
657
+ * // lastName: "Doe",
658
+ * // email: "john@example.com",
659
+ * // address: {
660
+ * // street: "123 Main St",
661
+ * // city: "New York",
662
+ * // zip: "10001"
663
+ * // }
664
+ * // }
665
+ * // Note: emergencyContact object is completely removed as all its properties were empty
666
+ * ```
667
+ *
668
+ * @example
669
+ * ```typescript
670
+ * // Control prototype property inclusion
671
+ * class BaseUser {
672
+ * role = "user";
673
+ * }
674
+ *
675
+ * class ExtendedUser extends BaseUser {
676
+ * name = "John";
677
+ * email = "";
678
+ * }
679
+ *
680
+ * const user = new ExtendedUser();
681
+ *
682
+ * const prunedWithPrototype = prune(user, false);
683
+ * // Includes inherited 'role' property: { role: "user", name: "John" }
684
+ *
685
+ * const prunedOwnOnly = prune(user, true);
686
+ * // Only own properties: { name: "John" }
687
+ * ```
688
+ *
689
+ * @remarks
690
+ * - Creates a new object rather than modifying the original (unlike the omit function)
691
+ * - Recursively processes nested objects to ensure deep cleaning
692
+ * - Removes properties with values: null, undefined, or empty string ("")
693
+ * - Preserves properties with falsy but meaningful values like 0, false
694
+ * - If a nested object becomes empty after pruning, it will be excluded from the result
695
+ * - Non-object types are returned as an empty object of the target type
696
+ * - The function preserves the type structure while removing empty values
697
+ *
698
+ * @see {@link omit} Function for selective property removal without deep cleaning
699
+ */
700
+ export declare const prune: <T>(obj: PartialWithNull<T>, omitPrototype?: boolean) => T;
701
+ /**
702
+ * Checks if an object has all specified properties as its own properties (not inherited).
703
+ *
704
+ * This utility function verifies that an object contains all the properties listed in the
705
+ * provided array as direct (own) properties, not inherited from the prototype chain.
706
+ * It uses the modern Object.hasOwn() method for reliable property existence checking,
707
+ * making it safer than using hasOwnProperty() directly.
708
+ *
709
+ * This is particularly useful for validating object structures, ensuring required properties
710
+ * exist before processing, implementing type guards, or verifying that objects conform to
711
+ * expected interfaces. It's commonly used in data validation, API request validation,
712
+ * and ensuring objects have all necessary properties before performing operations.
713
+ *
714
+ * @param {Record<PropertyKey, unknown>} obj - The object to check for property existence
715
+ * @param {PropertyKey[]} props - Array of property keys to verify exist on the object.
716
+ * PropertyKey includes string, number, and symbol types.
717
+ * @returns {boolean} True if the object has all specified properties as own properties, false otherwise
718
+ *
719
+ * @example
720
+ * ```typescript
721
+ * // Validate that a user object has required properties
722
+ * interface User {
723
+ * id: number;
724
+ * name: string;
725
+ * email: string;
726
+ * }
727
+ *
728
+ * const user = {
729
+ * id: 123,
730
+ * name: "John Doe",
731
+ * email: "john@example.com",
732
+ * role: "admin"
733
+ * };
734
+ *
735
+ * const hasRequiredProps = hasOwnAll(user, ["id", "name", "email"]);
736
+ * // Returns: true
737
+ *
738
+ * const hasAllProps = hasOwnAll(user, ["id", "name", "email", "phone"]);
739
+ * // Returns: false (missing 'phone' property)
740
+ * ```
741
+ *
742
+ * @example
743
+ * ```typescript
744
+ * // Validate API request payload
745
+ * function processUserUpdate(payload: unknown): User | null {
746
+ * if (typeof payload === 'object' && payload !== null) {
747
+ * const requiredFields = ['id', 'name', 'email'];
748
+ *
749
+ * if (hasOwnAll(payload as Record<string, unknown>, requiredFields)) {
750
+ * // Safe to process as we know all required fields exist
751
+ * return updateUser(payload as User);
752
+ * }
753
+ * }
754
+ *
755
+ * throw new Error('Invalid payload: missing required fields');
756
+ * }
757
+ * ```
758
+ *
759
+ * @example
760
+ * ```typescript
761
+ * // Check configuration object completeness
762
+ * interface DatabaseConfig {
763
+ * host: string;
764
+ * port: number;
765
+ * database: string;
766
+ * username: string;
767
+ * password: string;
768
+ * }
769
+ *
770
+ * const config = {
771
+ * host: "localhost",
772
+ * port: 5432,
773
+ * database: "myapp",
774
+ * username: "admin"
775
+ * // password is missing
776
+ * };
777
+ *
778
+ * const requiredConfigKeys = ['host', 'port', 'database', 'username', 'password'];
779
+ * const isConfigComplete = hasOwnAll(config, requiredConfigKeys);
780
+ * // Returns: false
781
+ *
782
+ * if (!isConfigComplete) {
783
+ * throw new Error('Database configuration is incomplete');
784
+ * }
785
+ * ```
786
+ *
787
+ * @example
788
+ * ```typescript
789
+ * // Work with symbol properties
790
+ * const symbolKey = Symbol('secret');
791
+ * const obj = {
792
+ * name: "test",
793
+ * [symbolKey]: "hidden value"
794
+ * };
795
+ *
796
+ * const hasSymbolProp = hasOwnAll(obj, ['name', symbolKey]);
797
+ * // Returns: true
798
+ * ```
799
+ *
800
+ * @remarks
801
+ * - Uses Object.hasOwn() which is more reliable than hasOwnProperty()
802
+ * - Only checks for own properties, not inherited properties from the prototype chain
803
+ * - Returns false immediately if any property is missing (short-circuit evaluation)
804
+ * - Works with string, number, and symbol property keys
805
+ * - Returns true for an empty properties array (vacuous truth)
806
+ * - Does not check property values, only existence
807
+ *
808
+ * @see {@link Object.hasOwn} The underlying method used for property checking
809
+ */
810
+ export declare function hasOwnAll(obj: Record<PropertyKey, unknown>, props: PropertyKey[]): boolean;
811
+ /**
812
+ * Extracts all values from a TypeScript enum, handling both string and numeric enum types correctly.
813
+ *
814
+ * This utility function safely retrieves the actual values from TypeScript enums, accounting for
815
+ * the different internal representations of string and numeric enums. For numeric enums, TypeScript
816
+ * creates reverse mappings (value → key), so this function filters out the reverse mapping entries
817
+ * to return only the actual enum values. For string enums, it returns all values directly.
818
+ *
819
+ * This is particularly useful when you need to iterate over enum values, validate input against
820
+ * enum values, create dropdown options from enums, or perform any operation that requires access
821
+ * to the actual enum values rather than the keys.
822
+ *
823
+ * @template T - The enum type extending object
824
+ * @param {T} e - The enum object to extract values from
825
+ * @returns {T[keyof T][]} An array containing all the actual values of the enum
826
+ *
827
+ * @example
828
+ * ```typescript
829
+ * // String enum example
830
+ * enum Color {
831
+ * RED = "red",
832
+ * GREEN = "green",
833
+ * BLUE = "blue"
834
+ * }
835
+ *
836
+ * const colorValues = getEnumValues(Color);
837
+ * // Returns: ["red", "green", "blue"]
838
+ *
839
+ * // Use for validation
840
+ * function isValidColor(value: string): value is Color {
841
+ * return getEnumValues(Color).includes(value as Color);
842
+ * }
843
+ * ```
844
+ *
845
+ * @example
846
+ * ```typescript
847
+ * // Numeric enum example
848
+ * enum Status {
849
+ * PENDING, // 0
850
+ * APPROVED, // 1
851
+ * REJECTED // 2
852
+ * }
853
+ *
854
+ * const statusValues = getEnumValues(Status);
855
+ * // Returns: [0, 1, 2] (not ["PENDING", "APPROVED", "REJECTED", 0, 1, 2])
856
+ *
857
+ * // Use for creating select options
858
+ * const statusOptions = getEnumValues(Status).map(value => ({
859
+ * value,
860
+ * label: Status[value] // Get the key name for display
861
+ * }));
862
+ * ```
863
+ *
864
+ * @example
865
+ * ```typescript
866
+ * // Mixed numeric enum example
867
+ * enum HttpStatus {
868
+ * OK = 200,
869
+ * NOT_FOUND = 404,
870
+ * SERVER_ERROR = 500
871
+ * }
872
+ *
873
+ * const httpStatusValues = getEnumValues(HttpStatus);
874
+ * // Returns: [200, 404, 500]
875
+ *
876
+ * // Use for status code validation
877
+ * function isValidHttpStatus(code: number): code is HttpStatus {
878
+ * return getEnumValues(HttpStatus).includes(code as HttpStatus);
879
+ * }
880
+ * ```
881
+ *
882
+ * @example
883
+ * ```typescript
884
+ * // Creating dropdown options from enum
885
+ * enum UserRole {
886
+ * ADMIN = "admin",
887
+ * USER = "user",
888
+ * MODERATOR = "moderator"
889
+ * }
890
+ *
891
+ * const roleOptions = getEnumValues(UserRole).map(role => ({
892
+ * value: role,
893
+ * label: role.charAt(0).toUpperCase() + role.slice(1)
894
+ * }));
895
+ * // Returns: [
896
+ * // { value: "admin", label: "Admin" },
897
+ * // { value: "user", label: "User" },
898
+ * // { value: "moderator", label: "Moderator" }
899
+ * // ]
900
+ * ```
901
+ *
902
+ * @remarks
903
+ * - Automatically detects numeric vs string enums and handles them appropriately
904
+ * - For numeric enums, filters out reverse mapping entries that TypeScript automatically creates
905
+ * - For string enums, returns all values as-is since there are no reverse mappings
906
+ * - Works with mixed numeric enums (enums with explicit numeric values)
907
+ * - The returned array maintains the order of enum declaration
908
+ * - Type-safe: the return type is correctly inferred as an array of the enum's value types
909
+ *
910
+ * @see {@link Object.values} The underlying method used to extract enum entries
911
+ */
912
+ export declare function getEnumValues<T extends object>(e: T): T[keyof T][];