@ix-xs/node-comfort 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +340 -0
  2. package/README.md +137 -548
  3. package/index.js +80 -35
  4. package/package.json +161 -33
  5. package/src/Arr.js +1050 -418
  6. package/src/Async.js +817 -0
  7. package/src/Cache.js +433 -0
  8. package/src/Checker.js +1202 -539
  9. package/src/Cli.js +1293 -0
  10. package/src/Color.js +556 -0
  11. package/src/Crypto.js +1082 -0
  12. package/src/Emitter.js +356 -0
  13. package/src/Env.js +689 -0
  14. package/src/FS.js +1626 -894
  15. package/src/Func.js +823 -356
  16. package/src/Http.js +700 -0
  17. package/src/Id.js +568 -200
  18. package/src/Logger.js +963 -378
  19. package/src/Num.js +965 -360
  20. package/src/Obj.js +1077 -379
  21. package/src/SQLite.js +1629 -1005
  22. package/src/Schema.js +2101 -0
  23. package/src/Str.js +1209 -432
  24. package/src/Sys.js +654 -0
  25. package/src/Time.js +1533 -440
  26. package/src/Utils.js +342 -325
  27. package/src/errors.js +335 -0
  28. package/src/internal/shared.js +415 -0
  29. package/types/index.d.ts +735 -526
  30. package/types/src/Arr.d.ts +533 -145
  31. package/types/src/Arr.d.ts.map +1 -1
  32. package/types/src/Async.d.ts +372 -0
  33. package/types/src/Async.d.ts.map +1 -0
  34. package/types/src/Cache.d.ts +221 -0
  35. package/types/src/Cache.d.ts.map +1 -0
  36. package/types/src/Checker.d.ts +651 -232
  37. package/types/src/Checker.d.ts.map +1 -1
  38. package/types/src/Cli.d.ts +664 -0
  39. package/types/src/Cli.d.ts.map +1 -0
  40. package/types/src/Color.d.ts +300 -0
  41. package/types/src/Color.d.ts.map +1 -0
  42. package/types/src/Crypto.d.ts +620 -0
  43. package/types/src/Crypto.d.ts.map +1 -0
  44. package/types/src/Emitter.d.ts +189 -0
  45. package/types/src/Emitter.d.ts.map +1 -0
  46. package/types/src/Env.d.ts +412 -0
  47. package/types/src/Env.d.ts.map +1 -0
  48. package/types/src/FS.d.ts +717 -238
  49. package/types/src/FS.d.ts.map +1 -1
  50. package/types/src/Func.d.ts +508 -135
  51. package/types/src/Func.d.ts.map +1 -1
  52. package/types/src/Http.d.ts +444 -0
  53. package/types/src/Http.d.ts.map +1 -0
  54. package/types/src/Id.d.ts +199 -66
  55. package/types/src/Id.d.ts.map +1 -1
  56. package/types/src/Logger.d.ts +414 -46
  57. package/types/src/Logger.d.ts.map +1 -1
  58. package/types/src/Num.d.ts +514 -137
  59. package/types/src/Num.d.ts.map +1 -1
  60. package/types/src/Obj.d.ts +453 -104
  61. package/types/src/Obj.d.ts.map +1 -1
  62. package/types/src/SQLite.d.ts +754 -308
  63. package/types/src/SQLite.d.ts.map +1 -1
  64. package/types/src/Schema.d.ts +1189 -0
  65. package/types/src/Schema.d.ts.map +1 -0
  66. package/types/src/Str.d.ts +617 -166
  67. package/types/src/Str.d.ts.map +1 -1
  68. package/types/src/Sys.d.ts +314 -0
  69. package/types/src/Sys.d.ts.map +1 -0
  70. package/types/src/Time.d.ts +759 -204
  71. package/types/src/Time.d.ts.map +1 -1
  72. package/types/src/Utils.d.ts +158 -102
  73. package/types/src/Utils.d.ts.map +1 -1
  74. package/types/src/errors.d.ts +316 -0
  75. package/types/src/errors.d.ts.map +1 -0
  76. package/types/src/internal/shared.d.ts +123 -0
  77. package/types/src/internal/shared.d.ts.map +1 -0
  78. package/types/index.d.ts.map +0 -1
@@ -1,252 +1,640 @@
1
1
  /**
2
- * Splits an array into chunks of a given size.
2
+ * How to get a value out of an item: a property name, or a function
3
+ * `(item, index) => value`.
4
+ */
5
+ export type Iteratee<T> = (T extends object ? keyof T & (string | number) : never) | ((item: T, index: number) => unknown);
6
+ /**
7
+ * A sort key for `sortBy()`: an iteratee, or `[iteratee, "asc" | "desc"]`
8
+ * to give that key its own direction.
9
+ */
10
+ export type SortKey<T> = Iteratee<T> | [Iteratee<T>, "asc" | "desc"];
11
+ /**
12
+ * Options for `sortBy()`.
13
+ */
14
+ export type SortByOptions = {
15
+ /**
16
+ * Direction for keys that don't set their own. Defaults to `"asc"`.
17
+ */
18
+ order?: "asc" | "desc" | undefined;
19
+ /**
20
+ * Sort text like a person would: ignore case, respect accents, `"item2"` before `"item10"`.
21
+ */
22
+ natural?: boolean | undefined;
23
+ /**
24
+ * Language used by `natural`. Defaults to the system's.
25
+ */
26
+ locale?: string | undefined;
27
+ };
28
+ /**
29
+ * A page returned by `paginate()`.
30
+ */
31
+ export type Page<T> = {
32
+ /**
33
+ * The items on this page.
34
+ */
35
+ items: T[];
36
+ /**
37
+ * The page number, starting at 1.
38
+ */
39
+ page: number;
40
+ perPage: number;
41
+ /**
42
+ * Total number of items.
43
+ */
44
+ total: number;
45
+ /**
46
+ * Number of pages, at least 1.
47
+ */
48
+ pages: number;
49
+ hasPrev: boolean;
50
+ hasNext: boolean;
51
+ };
52
+ /**
53
+ * Options for `toSentence()`.
54
+ */
55
+ export type ToSentenceOptions = {
56
+ /**
57
+ * Language of the joining word. Defaults to `"en"`.
58
+ */
59
+ locale?: string | undefined;
60
+ /**
61
+ * `"conjunction"` joins with "and", `"disjunction"` with "or", `"unit"` with commas only. Defaults to `"conjunction"`.
62
+ */
63
+ type?: "conjunction" | "disjunction" | "unit" | undefined;
64
+ /**
65
+ * Defaults to `"long"`.
66
+ */
67
+ style?: "long" | "short" | "narrow" | undefined;
68
+ };
69
+ /**
70
+ * Splits an array into groups of `size` items. The last group can be shorter.
71
+ *
72
+ * @example
73
+ * arr.chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
74
+ * arr.chunk(emails, 100).forEach(sendBatch);
75
+ *
76
+ * @template T
77
+ * @param {readonly T[]} array
78
+ * @param {number} size
79
+ * @returns {T[][]}
80
+ */
81
+ export function chunk<T>(array: readonly T[], size: number): T[][];
82
+ /**
83
+ * Sliding windows of `size` items, moving by `step`. Good for moving
84
+ * averages and comparing neighbours.
85
+ *
86
+ * @example
87
+ * arr.windows([1, 2, 3, 4], 2); // [[1, 2], [2, 3], [3, 4]]
88
+ * arr.windows([1, 2, 3, 4, 5], 3, 2); // [[1, 2, 3], [3, 4, 5]]
89
+ *
90
+ * @template T
91
+ * @param {readonly T[]} array
92
+ * @param {number} size
93
+ * @param {number} [step=1]
94
+ * @returns {T[][]}
95
+ */
96
+ export function windows<T>(array: readonly T[], size: number, step?: number): T[][];
97
+ /**
98
+ * The first item, or the first `n` items.
99
+ *
100
+ * @example
101
+ * arr.first([1, 2, 3]); // 1
102
+ * arr.first([1, 2, 3], 2); // [1, 2]
103
+ *
104
+ * @template T
105
+ * @overload
106
+ * @param {readonly T[]} array
107
+ * @returns {T | undefined}
108
+ */
109
+ export function first<T>(array: readonly T[]): T | undefined;
110
+ /**
111
+ * The first `n` items.
112
+ *
113
+ * @template T
114
+ * @overload
115
+ * @param {readonly T[]} array
116
+ * @param {number} n
117
+ * @returns {T[]}
118
+ */
119
+ export function first<T>(array: readonly T[], n: number): T[];
120
+ /**
121
+ * The last item, or the last `n` items.
122
+ *
123
+ * @example
124
+ * arr.last([1, 2, 3]); // 3
125
+ * arr.last([1, 2, 3], 2); // [2, 3]
126
+ *
127
+ * @template T
128
+ * @overload
129
+ * @param {readonly T[]} array
130
+ * @returns {T | undefined}
131
+ */
132
+ export function last<T>(array: readonly T[]): T | undefined;
133
+ /**
134
+ * The last `n` items.
135
+ *
136
+ * @template T
137
+ * @overload
138
+ * @param {readonly T[]} array
139
+ * @param {number} n
140
+ * @returns {T[]}
141
+ */
142
+ export function last<T>(array: readonly T[], n: number): T[];
143
+ /**
144
+ * One page of an array, with what you need to draw pagination controls.
145
+ * Pages start at 1; an out-of-range page is brought back into range.
146
+ *
147
+ * @example
148
+ * arr.paginate(products, 2, 20);
149
+ * // { items: [...], page: 2, perPage: 20, total: 95, pages: 5, hasPrev: true, hasNext: true }
150
+ *
151
+ * @template T
152
+ * @param {readonly T[]} array
153
+ * @param {number} [page=1]
154
+ * @param {number} [perPage=20]
155
+ * @returns {Page<T>}
156
+ */
157
+ export function paginate<T>(array: readonly T[], page?: number, perPage?: number): Page<T>;
158
+ /**
159
+ * Removes duplicates. With an iteratee, items that give the same value are
160
+ * duplicates; the first one is kept.
161
+ *
162
+ * @example
163
+ * arr.unique([1, 1, 2, 3]); // [1, 2, 3]
164
+ * arr.unique(users, "email"); // one user per email
165
+ * arr.unique(tags, (t) => t.toLowerCase());
166
+ *
167
+ * @template T
168
+ * @param {readonly T[]} array
169
+ * @param {Iteratee<T>} [iteratee]
170
+ * @returns {T[]}
171
+ */
172
+ export function unique<T>(array: readonly T[], iteratee?: Iteratee<T>): T[];
173
+ /**
174
+ * Groups items by key.
175
+ *
176
+ * @example
177
+ * arr.groupBy(users, "role"); // { admin: [...], user: [...] }
178
+ * arr.groupBy([1, 2, 3, 4], (n) => (n % 2 ? "odd" : "even")); // { odd: [1, 3], even: [2, 4] }
179
+ *
180
+ * @template T
181
+ * @param {readonly T[]} array
182
+ * @param {Iteratee<T>} iteratee
183
+ * @returns {Record<string, T[]>}
184
+ */
185
+ export function groupBy<T>(array: readonly T[], iteratee: Iteratee<T>): Record<string, T[]>;
186
+ /**
187
+ * Indexes items by key. If two items share a key, the last one wins.
188
+ *
189
+ * @example
190
+ * const byId = arr.keyBy(users, "id");
191
+ * byId[42]; // user 42
192
+ *
193
+ * @template T
194
+ * @param {readonly T[]} array
195
+ * @param {Iteratee<T>} iteratee
196
+ * @returns {Record<string, T>}
197
+ */
198
+ export function keyBy<T>(array: readonly T[], iteratee: Iteratee<T>): Record<string, T>;
199
+ /**
200
+ * Builds a `Map` from an array. Unlike `keyBy()`, keys keep their type.
201
+ *
202
+ * @example
203
+ * arr.toMap(users, "id"); // Map<number, User>
204
+ * arr.toMap(users, "id", (u) => u.name); // Map<number, string>
205
+ *
206
+ * @template T
207
+ * @template [V=T]
208
+ * @param {readonly T[]} array
209
+ * @param {Iteratee<T>} key
210
+ * @param {(item: T, index: number) => V} [value] The value to store. Defaults to the item.
211
+ * @returns {Map<any, V>}
212
+ */
213
+ export function toMap<T, V = T>(array: readonly T[], key: Iteratee<T>, value?: (item: T, index: number) => V): Map<any, V>;
214
+ /**
215
+ * Counts items per key.
216
+ *
217
+ * @example
218
+ * arr.countBy(["a", "b", "a"]); // { a: 2, b: 1 }
219
+ * arr.countBy(users, "country"); // { FR: 12, US: 7 }
220
+ *
221
+ * @template T
222
+ * @param {readonly T[]} array
223
+ * @param {Iteratee<T>} [iteratee] Defaults to the item itself.
224
+ * @returns {Record<string, number>}
225
+ */
226
+ export function countBy<T>(array: readonly T[], iteratee?: Iteratee<T>): Record<string, number>;
227
+ /**
228
+ * Counts the items that pass a test.
229
+ *
230
+ * @example
231
+ * arr.count(users, (u) => u.active);
232
+ *
233
+ * @template T
234
+ * @param {readonly T[]} array
235
+ * @param {(item: T, index: number) => unknown} predicate
236
+ * @returns {number}
237
+ */
238
+ export function count<T>(array: readonly T[], predicate: (item: T, index: number) => unknown): number;
239
+ /**
240
+ * Splits items into those that pass a test and those that don't.
241
+ *
242
+ * @example
243
+ * const [adults, minors] = arr.partition(people, (p) => p.age >= 18);
244
+ *
245
+ * @template T
246
+ * @param {readonly T[]} array
247
+ * @param {(item: T, index: number) => unknown} predicate
248
+ * @returns {[T[], T[]]}
249
+ */
250
+ export function partition<T>(array: readonly T[], predicate: (item: T, index: number) => unknown): [T[], T[]];
251
+ /**
252
+ * Takes one property from every item.
253
+ *
254
+ * @example
255
+ * arr.pluck(users, "email"); // ["ada@x.io", "bob@x.io"]
256
+ *
257
+ * @template T
258
+ * @template {keyof T} K
259
+ * @param {readonly T[]} array
260
+ * @param {K} key
261
+ * @returns {Array<T[K]>}
262
+ */
263
+ export function pluck<T, K extends keyof T>(array: readonly T[], key: K): Array<T[K]>;
264
+ /**
265
+ * Sorts by one or more keys, each with its own direction if you like.
266
+ * The sort is stable and `null`/`undefined` always go last.
3
267
  *
4
268
  * @example
5
- * nodeComfort.arr.chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
269
+ * arr.sortBy(users, "age"); // youngest first
270
+ * arr.sortBy(users, "age", "desc"); // oldest first
271
+ * arr.sortBy(users, [["age", "desc"], "lastName"]);
272
+ * arr.sortBy(files, "name", { natural: true }); // "file2" before "file10"
273
+ *
274
+ * @template T
275
+ * @param {readonly T[]} array
276
+ * @param {SortKey<T> | Array<SortKey<T>>} keys
277
+ * @param {"asc" | "desc" | SortByOptions} [order="asc"]
278
+ * @returns {T[]}
279
+ */
280
+ export function sortBy<T>(array: readonly T[], keys: SortKey<T> | Array<SortKey<T>>, order?: "asc" | "desc" | SortByOptions): T[];
281
+ /**
282
+ * A shuffled copy (Fisher-Yates).
6
283
  *
7
- * @param {any[]} array - Source array.
8
- * @param {number} size - Chunk size (must be >= 1).
9
- * @returns {any[][]} The chunked array.
284
+ * @template T
285
+ * @param {readonly T[]} array
286
+ * @returns {T[]}
10
287
  */
11
- export function chunk(array: any[], size: number): any[][];
288
+ export function shuffle<T>(array: readonly T[]): T[];
12
289
  /**
13
- * Returns a new array with duplicate values removed.
290
+ * One random item, or `undefined` if the array is empty.
14
291
  *
15
- * Pass an `iteratee` to de-duplicate by a derived key.
292
+ * @template T
293
+ * @param {readonly T[]} array
294
+ * @returns {T | undefined}
295
+ */
296
+ export function sample<T>(array: readonly T[]): T | undefined;
297
+ /**
298
+ * `n` random items, never the same one twice.
299
+ *
300
+ * @example
301
+ * arr.sampleSize(players, 3);
302
+ *
303
+ * @template T
304
+ * @param {readonly T[]} array
305
+ * @param {number} n
306
+ * @returns {T[]}
307
+ */
308
+ export function sampleSize<T>(array: readonly T[], n: number): T[];
309
+ /**
310
+ * Rotates items. Positive `n` moves items from the start to the end,
311
+ * negative `n` the other way.
312
+ *
313
+ * @example
314
+ * arr.rotate([1, 2, 3, 4], 1); // [2, 3, 4, 1]
315
+ * arr.rotate([1, 2, 3, 4], -1); // [4, 1, 2, 3]
316
+ *
317
+ * @template T
318
+ * @param {readonly T[]} array
319
+ * @param {number} [n=1]
320
+ * @returns {T[]}
321
+ */
322
+ export function rotate<T>(array: readonly T[], n?: number): T[];
323
+ /**
324
+ * Moves one item to another position. Negative indexes count from the end.
16
325
  *
17
326
  * @example
18
- * nodeComfort.arr.unique([1, 1, 2, 3]); // [1, 2, 3]
19
- * nodeComfort.arr.unique([{ id: 1 }, { id: 1 }], "id"); // [{ id: 1 }]
327
+ * arr.move(["a", "b", "c"], 0, 2); // ["b", "c", "a"]
20
328
  *
21
- * @param {any[]} array - Source array.
22
- * @param {string|((item: any) => any)} [iteratee] - Key or function to compare by.
23
- * @returns {any[]} The de-duplicated array.
329
+ * @template T
330
+ * @param {readonly T[]} array
331
+ * @param {number} from
332
+ * @param {number} to
333
+ * @returns {T[]}
24
334
  */
25
- export function unique(array: any[], iteratee?: string | ((item: any) => any)): any[];
335
+ export function move<T>(array: readonly T[], from: number, to: number): T[];
26
336
  /**
27
- * Groups the items of an array by a key or function.
337
+ * Swaps two items.
28
338
  *
29
339
  * @example
30
- * nodeComfort.arr.groupBy([1, 2, 3, 4], (n) => (n % 2 ? "odd" : "even"));
31
- * // { odd: [1, 3], even: [2, 4] }
340
+ * arr.swap(["a", "b", "c"], 0, 2); // ["c", "b", "a"]
32
341
  *
33
- * @param {any[]} array - Source array.
34
- * @param {string|((item: any) => any)} iteratee - Key or function to group by.
35
- * @returns {Record<string, any[]>} The grouped object.
342
+ * @template T
343
+ * @param {readonly T[]} array
344
+ * @param {number} i
345
+ * @param {number} j
346
+ * @returns {T[]}
36
347
  */
37
- export function groupBy(array: any[], iteratee: string | ((item: any) => any)): Record<string, any[]>;
348
+ export function swap<T>(array: readonly T[], i: number, j: number): T[];
38
349
  /**
39
- * Builds an object keyed by a derived value, mapping each key to the
40
- * (last) matching item.
350
+ * Items of `array` that appear in none of the others.
41
351
  *
42
352
  * @example
43
- * nodeComfort.arr.keyBy([{ id: "a" }, { id: "b" }], "id");
44
- * // { a: { id: "a" }, b: { id: "b" } }
353
+ * arr.difference([1, 2, 3, 4], [2, 4]); // [1, 3]
45
354
  *
46
- * @param {any[]} array - Source array.
47
- * @param {string|((item: any) => any)} iteratee - Key or function.
48
- * @returns {Record<string, any>} The keyed object.
355
+ * @template T
356
+ * @param {readonly T[]} array
357
+ * @param {...ReadonlyArray<T>} others
358
+ * @returns {T[]}
49
359
  */
50
- export function keyBy(array: any[], iteratee: string | ((item: any) => any)): Record<string, any>;
360
+ export function difference<T>(array: readonly T[], ...others: ReadonlyArray<T>[]): T[];
51
361
  /**
52
- * Partitions an array into two groups based on a predicate:
53
- * `[matching, notMatching]`.
362
+ * Items present in every array, without duplicates.
54
363
  *
55
364
  * @example
56
- * nodeComfort.arr.partition([1, 2, 3, 4], (n) => n % 2 === 0);
57
- * // [[2, 4], [1, 3]]
365
+ * arr.intersection([1, 2, 3], [2, 3, 4], [3, 2]); // [2, 3]
58
366
  *
59
- * @param {any[]} array - Source array.
60
- * @param {(item: any, index: number) => boolean} predicate - Test function.
61
- * @returns {[any[], any[]]} The two partitions.
367
+ * @template T
368
+ * @param {...ReadonlyArray<T>} arrays
369
+ * @returns {T[]}
62
370
  */
63
- export function partition(array: any[], predicate: (item: any, index: number) => boolean): [any[], any[]];
371
+ export function intersection<T>(...arrays: ReadonlyArray<T>[]): T[];
64
372
  /**
65
- * Recursively flattens a nested array up to a given depth.
373
+ * Items present in any array, without duplicates.
66
374
  *
67
375
  * @example
68
- * nodeComfort.arr.flatten([1, [2, [3, [4]]]]); // [1, 2, 3, [4]]
69
- * nodeComfort.arr.flatten([1, [2, [3]]], Infinity); // [1, 2, 3]
376
+ * arr.union([1, 2], [2, 3], [3, 4]); // [1, 2, 3, 4]
70
377
  *
71
- * @param {any[]} array - Source array.
72
- * @param {number} [depth=1] - Maximum depth to flatten.
73
- * @returns {any[]} The flattened array.
378
+ * @template T
379
+ * @param {...ReadonlyArray<T>} arrays
380
+ * @returns {T[]}
74
381
  */
75
- export function flatten(array: any[], depth?: number): any[];
382
+ export function union<T>(...arrays: ReadonlyArray<T>[]): T[];
76
383
  /**
77
- * Returns a shuffled copy of an array (Fisher–Yates).
384
+ * A copy without the given values. `NaN` works too.
78
385
  *
79
- * Uses `Math.random` • not cryptographically secure.
386
+ * @example
387
+ * arr.without([1, 2, 3, 2], 2); // [1, 3]
80
388
  *
81
- * @param {any[]} array - Source array.
82
- * @returns {any[]} A new shuffled array.
389
+ * @template T
390
+ * @param {readonly T[]} array
391
+ * @param {...T} values
392
+ * @returns {T[]}
83
393
  */
84
- export function shuffle(array: any[]): any[];
394
+ export function without<T>(array: readonly T[], ...values: T[]): T[];
85
395
  /**
86
- * Returns a random element from an array.
396
+ * A copy without the items that pass the test.
397
+ *
398
+ * @example
399
+ * arr.remove([1, 2, 3, 4], (n) => n % 2 === 0); // [1, 3]
87
400
  *
88
- * @param {any[]} array - Source array.
89
- * @returns {any} A random element, or undefined if empty.
401
+ * @template T
402
+ * @param {readonly T[]} array
403
+ * @param {(item: T, index: number) => unknown} predicate
404
+ * @returns {T[]}
90
405
  */
91
- export function sample(array: any[]): any;
406
+ export function remove<T>(array: readonly T[], predicate: (item: T, index: number) => unknown): T[];
92
407
  /**
93
- * Returns `n` random elements from an array (without repetition).
408
+ * Removes falsy values (`false`, `null`, `undefined`, `0`, `""`, `NaN`).
94
409
  *
95
- * @param {any[]} array - Source array.
96
- * @param {number} n - Number of elements to pick.
97
- * @returns {any[]} The sampled elements.
410
+ * @example
411
+ * arr.compact([0, 1, false, 2, "", 3, null]); // [1, 2, 3]
412
+ *
413
+ * @template T
414
+ * @param {readonly T[]} array
415
+ * @returns {Array<Exclude<T, false | 0 | 0n | "" | null | undefined>>}
98
416
  */
99
- export function sampleSize(array: any[], n: number): any[];
417
+ export function compact<T>(array: readonly T[]): Array<Exclude<T, false | 0 | 0n | "" | null | undefined>>;
100
418
  /**
101
- * Sorts an array by one or more iteratees, ascending by default.
419
+ * Adds the item if it's missing, removes it if it's there. Handy for
420
+ * multi-select state.
102
421
  *
103
- * Does not mutate the input.
422
+ * @example
423
+ * arr.toggle(["a", "b"], "b"); // ["a"]
424
+ * arr.toggle(["a"], "b"); // ["a", "b"]
425
+ *
426
+ * @template T
427
+ * @param {readonly T[]} array
428
+ * @param {T} item
429
+ * @returns {T[]}
430
+ */
431
+ export function toggle<T>(array: readonly T[], item: T): T[];
432
+ /**
433
+ * Replaces the item with the same identity, or appends it if there's none.
104
434
  *
105
435
  * @example
106
- * nodeComfort.arr.sortBy(users, "age");
107
- * nodeComfort.arr.sortBy(users, [(u) => u.age, "name"]);
436
+ * arr.upsert(users, { id: 2, name: "Bob" }, "id");
108
437
  *
109
- * @param {any[]} array - Source array.
110
- * @param {string|((item: any) => any)|Array<string|((item: any) => any)>} iteratees - Sort key(s).
111
- * @param {"asc"|"desc"} [direction="asc"] - Sort direction.
112
- * @returns {any[]} A new sorted array.
438
+ * @template T
439
+ * @param {readonly T[]} array
440
+ * @param {T} item
441
+ * @param {Iteratee<T>} identity What makes two items "the same", like `"id"`.
442
+ * @returns {T[]}
113
443
  */
114
- export function sortBy(array: any[], iteratees: string | ((item: any) => any) | Array<string | ((item: any) => any)>, direction?: "asc" | "desc"): any[];
444
+ export function upsert<T>(array: readonly T[], item: T, identity: Iteratee<T>): T[];
115
445
  /**
116
- * Returns the elements present in the first array but not in the others.
446
+ * Inserts items at an index. Negative indexes count from the end.
117
447
  *
118
448
  * @example
119
- * nodeComfort.arr.difference([1, 2, 3, 4], [2, 4]); // [1, 3]
449
+ * arr.insert(["a", "d"], 1, "b", "c"); // ["a", "b", "c", "d"]
120
450
  *
121
- * @param {any[]} array - Source array.
122
- * @param {...any[]} others - Arrays to subtract.
123
- * @returns {any[]} The difference.
451
+ * @template T
452
+ * @param {readonly T[]} array
453
+ * @param {number} index
454
+ * @param {...T} items
455
+ * @returns {T[]}
124
456
  */
125
- export function difference(array: any[], ...others: any[][]): any[];
457
+ export function insert<T>(array: readonly T[], index: number, ...items: T[]): T[];
126
458
  /**
127
- * Returns the elements common to all provided arrays.
459
+ * Flattens nested arrays, one level by default.
128
460
  *
129
461
  * @example
130
- * nodeComfort.arr.intersection([1, 2, 3], [2, 3, 4]); // [2, 3]
462
+ * arr.flatten([1, [2, [3, [4]]]]); // [1, 2, [3, [4]]]
463
+ * arr.flatten([1, [2, [3, [4]]]], Infinity); // [1, 2, 3, 4]
464
+ *
465
+ * @template T
466
+ * @template {number} [D=1]
467
+ * @param {readonly T[]} array
468
+ * @param {D} [depth]
469
+ * @returns {FlatArray<T[], D>[]}
470
+ */
471
+ export function flatten<T, D extends number = 1>(array: readonly T[], depth?: D): FlatArray<T[], D>[];
472
+ /**
473
+ * Pairs items by position. Shorter arrays leave `undefined` holes.
131
474
  *
132
- * @param {...any[]} arrays - Arrays to intersect.
133
- * @returns {any[]} The intersection.
475
+ * @example
476
+ * arr.zip(["a", "b"], [1, 2]); // [["a", 1], ["b", 2]]
477
+ *
478
+ * @template T
479
+ * @param {...ReadonlyArray<T>} arrays
480
+ * @returns {Array<Array<T | undefined>>}
134
481
  */
135
- export function intersection(...arrays: any[][]): any[];
482
+ export function zip<T>(...arrays: ReadonlyArray<T>[]): Array<Array<T | undefined>>;
136
483
  /**
137
- * Returns the union (unique values) of all provided arrays.
484
+ * The opposite of `zip()`: rows become columns.
138
485
  *
139
486
  * @example
140
- * nodeComfort.arr.union([1, 2], [2, 3], [3, 4]); // [1, 2, 3, 4]
487
+ * arr.unzip([["a", 1], ["b", 2]]); // [["a", "b"], [1, 2]]
141
488
  *
142
- * @param {...any[]} arrays - Arrays to unite.
143
- * @returns {any[]} The union.
489
+ * @template T
490
+ * @param {ReadonlyArray<ReadonlyArray<T>>} tuples
491
+ * @returns {Array<Array<T | undefined>>}
144
492
  */
145
- export function union(...arrays: any[][]): any[];
493
+ export function unzip<T>(tuples: ReadonlyArray<ReadonlyArray<T>>): Array<Array<T | undefined>>;
146
494
  /**
147
- * Zips multiple arrays together into an array of tuples.
495
+ * Takes items from each array in turn, then appends the rest.
148
496
  *
149
497
  * @example
150
- * nodeComfort.arr.zip(["a", "b"], [1, 2]); // [["a", 1], ["b", 2]]
498
+ * arr.interleave([1, 3, 5], [2, 4]); // [1, 2, 3, 4, 5]
151
499
  *
152
- * @param {...any[]} arrays - Arrays to zip.
153
- * @returns {any[][]} The zipped tuples.
500
+ * @template T
501
+ * @param {...ReadonlyArray<T>} arrays
502
+ * @returns {T[]}
154
503
  */
155
- export function zip(...arrays: any[][]): any[][];
504
+ export function interleave<T>(...arrays: ReadonlyArray<T>[]): T[];
156
505
  /**
157
- * Splits an array into `matching` and removes falsy values.
506
+ * Every combination of one item from each array.
507
+ *
508
+ * @example
509
+ * arr.cartesian(["S", "M"], ["red", "blue"]);
510
+ * // [["S", "red"], ["S", "blue"], ["M", "red"], ["M", "blue"]]
158
511
  *
159
- * Removes `false`, `null`, `0`, `""`, `undefined` and `NaN`.
512
+ * @template T
513
+ * @param {...ReadonlyArray<T>} arrays
514
+ * @returns {T[][]}
515
+ */
516
+ export function cartesian<T>(...arrays: ReadonlyArray<T>[]): T[][];
517
+ /**
518
+ * An array of `n` items, from a value or a function of the index.
160
519
  *
161
520
  * @example
162
- * nodeComfort.arr.compact([0, 1, false, 2, "", 3, null]); // [1, 2, 3]
521
+ * arr.times(3, "x"); // ["x", "x", "x"]
522
+ * arr.times(3, (i) => i * 2); // [0, 2, 4]
163
523
  *
164
- * @param {any[]} array - Source array.
165
- * @returns {any[]} The compacted array.
524
+ * @template T
525
+ * @param {number} n
526
+ * @param {T | ((index: number) => T)} [value]
527
+ * @returns {T[]}
166
528
  */
167
- export function compact(array: any[]): any[];
529
+ export function times<T>(n: number, value?: T | ((index: number) => T)): T[];
168
530
  /**
169
- * Returns the first element (or the first `n` elements) of an array.
531
+ * Adds up a number from each item. Non-numbers count as 0.
532
+ *
533
+ * @example
534
+ * arr.sumBy(cart, "price");
535
+ * arr.sumBy(cart, (item) => item.price * item.quantity);
170
536
  *
171
- * @param {any[]} array - Source array.
172
- * @param {number} [n] - How many elements to take.
173
- * @returns {any} The first element, or the first `n` elements when `n` is given.
537
+ * @template T
538
+ * @param {readonly T[]} array
539
+ * @param {Iteratee<T>} [iteratee]
540
+ * @returns {number}
174
541
  */
175
- export function first(array: any[], n?: number): any;
542
+ export function sumBy<T>(array: readonly T[], iteratee?: Iteratee<T>): number;
176
543
  /**
177
- * Returns the last element (or the last `n` elements) of an array.
544
+ * The average of a number from each item, or `0` for an empty array.
545
+ *
546
+ * @example
547
+ * arr.averageBy(reviews, "rating"); // 4.3
178
548
  *
179
- * @param {any[]} array - Source array.
180
- * @param {number} [n] - How many elements to take.
181
- * @returns {any} The last element, or the last `n` elements when `n` is given.
549
+ * @template T
550
+ * @param {readonly T[]} array
551
+ * @param {Iteratee<T>} [iteratee]
552
+ * @returns {number}
182
553
  */
183
- export function last(array: any[], n?: number): any;
554
+ export function averageBy<T>(array: readonly T[], iteratee?: Iteratee<T>): number;
184
555
  /**
185
- * Removes items from an array where the predicate is true, returning a new array.
556
+ * The item with the highest value.
186
557
  *
187
- * @param {any[]} array - Source array.
188
- * @param {(item: any, index: number) => boolean} predicate - Removal test.
189
- * @returns {any[]} A new array without the removed items.
558
+ * @example
559
+ * arr.maxBy(players, "score");
560
+ *
561
+ * @template T
562
+ * @param {readonly T[]} array
563
+ * @param {Iteratee<T>} [iteratee]
564
+ * @returns {T | undefined}
190
565
  */
191
- export function remove(array: any[], predicate: (item: any, index: number) => boolean): any[];
566
+ export function maxBy<T>(array: readonly T[], iteratee?: Iteratee<T>): T | undefined;
192
567
  /**
193
- * Moves an element from one index to another (returns a new array).
568
+ * The item with the lowest value.
569
+ *
570
+ * @example
571
+ * arr.minBy(products, "price");
194
572
  *
195
- * @param {any[]} array - Source array.
196
- * @param {number} from - Source index.
197
- * @param {number} to - Destination index.
198
- * @returns {any[]} The reordered array.
573
+ * @template T
574
+ * @param {readonly T[]} array
575
+ * @param {Iteratee<T>} [iteratee]
576
+ * @returns {T | undefined}
199
577
  */
200
- export function move(array: any[], from: number, to: number): any[];
578
+ export function minBy<T>(array: readonly T[], iteratee?: Iteratee<T>): T | undefined;
201
579
  /**
202
- * Counts occurrences of each derived key in an array.
580
+ * The items that appear more than once, each listed once.
203
581
  *
204
582
  * @example
205
- * nodeComfort.arr.countBy(["a", "b", "a"]); // { a: 2, b: 1 }
206
- * nodeComfort.arr.countBy([1.1, 2.3, 1.7], Math.floor); // { 1: 2, 2: 1 }
583
+ * arr.duplicates([1, 2, 2, 3, 3, 3]); // [2, 3]
584
+ * arr.duplicates(users, "email"); // users whose email is taken by an earlier one
207
585
  *
208
- * @param {any[]} array - Source array.
209
- * @param {string|((item: any) => any)} [iteratee] - Key or function.
210
- * @returns {Record<string, number>} The counts.
586
+ * @template T
587
+ * @param {readonly T[]} array
588
+ * @param {Iteratee<T>} [iteratee] What makes two items "the same". Defaults to the item itself.
589
+ * @returns {T[]} For each repeated value, its second occurrence.
211
590
  */
212
- export function countBy(array: any[], iteratee?: string | ((item: any) => any)): Record<string, number>;
591
+ export function duplicates<T>(array: readonly T[], iteratee?: Iteratee<T>): T[];
213
592
  /**
214
- * Sums an array by a numeric iteratee (or the values themselves).
593
+ * Items found in exactly one of the arrays, without duplicates.
215
594
  *
216
595
  * @example
217
- * nodeComfort.arr.sumBy([{ n: 1 }, { n: 2 }], "n"); // 3
596
+ * arr.xor([1, 2, 3], [2, 3, 4]); // [1, 4]
218
597
  *
219
- * @param {any[]} array - Source array.
220
- * @param {string|((item: any) => number)} [iteratee] - Key or function returning a number.
221
- * @returns {number} The sum.
598
+ * @template T
599
+ * @param {...ReadonlyArray<T>} arrays
600
+ * @returns {T[]}
222
601
  */
223
- export function sumBy(array: any[], iteratee?: string | ((item: any) => number)): number;
602
+ export function xor<T>(...arrays: ReadonlyArray<T>[]): T[];
224
603
  /**
225
- * Returns the item with the maximum derived value.
604
+ * The items from the start, up to the first one that fails the test.
226
605
  *
227
- * @param {any[]} array - Source array.
228
- * @param {string|((item: any) => number)} [iteratee] - Key or function.
229
- * @returns {any} The item, or undefined if the array is empty.
606
+ * @example
607
+ * arr.takeWhile([1, 2, 5, 1], (n) => n < 3); // [1, 2]
608
+ *
609
+ * @template T
610
+ * @param {readonly T[]} array
611
+ * @param {(item: T, index: number) => unknown} predicate
612
+ * @returns {T[]}
230
613
  */
231
- export function maxBy(array: any[], iteratee?: string | ((item: any) => number)): any;
614
+ export function takeWhile<T>(array: readonly T[], predicate: (item: T, index: number) => unknown): T[];
232
615
  /**
233
- * Returns the item with the minimum derived value.
616
+ * Skips items from the start while they pass the test, and returns the rest.
617
+ *
618
+ * @example
619
+ * arr.dropWhile([1, 2, 5, 1], (n) => n < 3); // [5, 1]
234
620
  *
235
- * @param {any[]} array - Source array.
236
- * @param {string|((item: any) => number)} [iteratee] - Key or function.
237
- * @returns {any} The item, or undefined if the array is empty.
621
+ * @template T
622
+ * @param {readonly T[]} array
623
+ * @param {(item: T, index: number) => unknown} predicate
624
+ * @returns {T[]}
238
625
  */
239
- export function minBy(array: any[], iteratee?: string | ((item: any) => number)): any;
626
+ export function dropWhile<T>(array: readonly T[], predicate: (item: T, index: number) => unknown): T[];
240
627
  /**
241
- * Creates an array of a given length, filled by a value or generator function.
628
+ * Joins items the way a sentence would, in any language.
242
629
  *
243
630
  * @example
244
- * nodeComfort.arr.times(3, "x"); // ["x", "x", "x"]
245
- * nodeComfort.arr.times(3, (i) => i * 2); // [0, 2, 4]
631
+ * arr.toSentence(["Ada", "Bob", "Cy"]); // "Ada, Bob, and Cy"
632
+ * arr.toSentence(["Ada", "Bob"], { locale: "fr" }); // "Ada et Bob"
633
+ * arr.toSentence(["red", "blue"], { type: "disjunction" }); // "red or blue"
246
634
  *
247
- * @param {number} n - Number of items.
248
- * @param {any|((index: number) => any)} [value] - Fill value or generator.
249
- * @returns {any[]} The generated array.
635
+ * @param {Iterable<unknown>} items
636
+ * @param {ToSentenceOptions} [options]
637
+ * @returns {string}
250
638
  */
251
- export function times(n: number, value?: any | ((index: number) => any)): any[];
639
+ export function toSentence(items: Iterable<unknown>, options?: ToSentenceOptions): string;
252
640
  //# sourceMappingURL=Arr.d.ts.map