@zairakai/js-utils 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +270 -0
- package/dist/arrays.cjs +210 -0
- package/dist/arrays.d.cts +119 -0
- package/dist/arrays.d.ts +119 -0
- package/dist/arrays.js +32 -0
- package/dist/chunk-27YHP2CK.js +407 -0
- package/dist/chunk-3WNRYKPG.js +37 -0
- package/dist/chunk-42CHLXT7.js +214 -0
- package/dist/chunk-6F4PWJZI.js +0 -0
- package/dist/chunk-7SXRFZBB.js +173 -0
- package/dist/chunk-F6RSTW65.js +156 -0
- package/dist/chunk-G7ZJ23DW.js +253 -0
- package/dist/chunk-IPP7PA6H.js +136 -0
- package/dist/chunk-LDSWHSRX.js +96 -0
- package/dist/chunk-TY75OOIQ.js +700 -0
- package/dist/chunk-W6JEMFAF.js +54 -0
- package/dist/chunk-XEJLBAXE.js +164 -0
- package/dist/chunk-Z7G3SIQH.js +270 -0
- package/dist/chunk-ZJPKS2MQ.js +101 -0
- package/dist/collections.cjs +797 -0
- package/dist/collections.d.cts +353 -0
- package/dist/collections.d.ts +353 -0
- package/dist/collections.js +17 -0
- package/dist/datetime.cjs +80 -0
- package/dist/datetime.d.cts +75 -0
- package/dist/datetime.d.ts +75 -0
- package/dist/datetime.js +24 -0
- package/dist/equals.cjs +121 -0
- package/dist/equals.d.cts +24 -0
- package/dist/equals.d.ts +24 -0
- package/dist/equals.js +8 -0
- package/dist/formatters.cjs +201 -0
- package/dist/formatters.d.cts +180 -0
- package/dist/formatters.d.ts +180 -0
- package/dist/formatters.js +48 -0
- package/dist/index.cjs +2906 -0
- package/dist/index.d.cts +120 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +348 -0
- package/dist/number.cjs +279 -0
- package/dist/number.d.cts +177 -0
- package/dist/number.d.ts +177 -0
- package/dist/number.js +10 -0
- package/dist/obj.cjs +427 -0
- package/dist/obj.d.cts +177 -0
- package/dist/obj.d.ts +177 -0
- package/dist/obj.js +12 -0
- package/dist/php-arrays.cjs +954 -0
- package/dist/php-arrays.d.cts +256 -0
- package/dist/php-arrays.d.ts +256 -0
- package/dist/php-arrays.js +70 -0
- package/dist/runtime.cjs +134 -0
- package/dist/runtime.d.cts +90 -0
- package/dist/runtime.d.ts +90 -0
- package/dist/runtime.js +24 -0
- package/dist/schemas.cjs +86 -0
- package/dist/schemas.d.cts +108 -0
- package/dist/schemas.d.ts +108 -0
- package/dist/schemas.js +22 -0
- package/dist/str.cjs +499 -0
- package/dist/str.d.cts +282 -0
- package/dist/str.d.ts +282 -0
- package/dist/str.js +11 -0
- package/dist/types.cjs +18 -0
- package/dist/types.d.cts +13 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +1 -0
- package/dist/validator.cjs +251 -0
- package/dist/validator.d.cts +99 -0
- package/dist/validator.d.ts +99 -0
- package/dist/validator.js +11 -0
- package/dist/validators.cjs +217 -0
- package/dist/validators.d.cts +216 -0
- package/dist/validators.d.ts +216 -0
- package/dist/validators.js +64 -0
- package/package.json +180 -0
- package/src/arrays.ts +316 -0
- package/src/collections.ts +866 -0
- package/src/datetime.ts +103 -0
- package/src/equals.ts +134 -0
- package/src/formatters.ts +342 -0
- package/src/index.ts +36 -0
- package/src/number.ts +281 -0
- package/src/obj.ts +303 -0
- package/src/php-arrays.ts +445 -0
- package/src/pipe.ts +29 -0
- package/src/runtime.ts +194 -0
- package/src/schemas.ts +136 -0
- package/src/str.ts +438 -0
- package/src/types.ts +13 -0
- package/src/validator.ts +157 -0
- package/src/validators.ts +359 -0
package/src/arrays.ts
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Array manipulation and utility functions
|
|
3
|
+
* Inspired by Laravel's array helpers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Add an element to an array or record at a specific key.
|
|
8
|
+
*
|
|
9
|
+
* @param {T[] | Record<string, T>} array The source array or record
|
|
10
|
+
* @param {string} key The key to add the value at
|
|
11
|
+
* @param {T} value The value to add
|
|
12
|
+
* @returns {Record<string, unknown>} The resulting record
|
|
13
|
+
*/
|
|
14
|
+
export const arrayAdd = <T>(array: T[] | Record<string, T>, key: string, value: T): Record<string, unknown> => {
|
|
15
|
+
const result: Record<string, unknown> = Array.isArray(array)
|
|
16
|
+
? (Object.fromEntries(array.map((v, i) => [i, v])) as Record<string, unknown>)
|
|
17
|
+
: { ...(array as Record<string, T>) }
|
|
18
|
+
result[key] = value
|
|
19
|
+
return result
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Collapse an array of arrays into a single array.
|
|
24
|
+
*
|
|
25
|
+
* @param {T[][]} array The array of arrays to collapse
|
|
26
|
+
* @returns {T[]} The collapsed array
|
|
27
|
+
*/
|
|
28
|
+
export const arrayCollapse = <T>(array: T[][]): T[] => {
|
|
29
|
+
if (!Array.isArray(array)) {
|
|
30
|
+
return []
|
|
31
|
+
}
|
|
32
|
+
return array.reduce((flat, item) => {
|
|
33
|
+
if (Array.isArray(item)) {
|
|
34
|
+
return flat.concat(item)
|
|
35
|
+
}
|
|
36
|
+
return flat.concat([item as unknown as T])
|
|
37
|
+
}, [] as T[])
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Divide an array into two arrays: one with keys (indices) and one with values.
|
|
42
|
+
*
|
|
43
|
+
* @param {T[]} array The array to divide
|
|
44
|
+
* @returns {[string[], T[]]} A tuple containing keys and values
|
|
45
|
+
*/
|
|
46
|
+
export const arrayDivide = <T>(array: T[]): [string[], T[]] => {
|
|
47
|
+
if (!Array.isArray(array)) {
|
|
48
|
+
return [[], []]
|
|
49
|
+
}
|
|
50
|
+
const keys = array.map((_, index) => index.toString())
|
|
51
|
+
const values = [...array]
|
|
52
|
+
return [keys, values]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Flatten a multi-dimensional record into a single-level record using dot notation.
|
|
57
|
+
*
|
|
58
|
+
* @param {Record<string, unknown>} array The record to flatten
|
|
59
|
+
* @param {string} prepend The string to prepend to keys
|
|
60
|
+
* @returns {Record<string, unknown>} The flattened record
|
|
61
|
+
*/
|
|
62
|
+
export const arrayDot = (array: Record<string, unknown>, prepend = ''): Record<string, unknown> => {
|
|
63
|
+
const result: Record<string, unknown> = {}
|
|
64
|
+
|
|
65
|
+
for (const [key, value] of Object.entries(array)) {
|
|
66
|
+
const newKey = prepend ? `${prepend}.${key}` : key
|
|
67
|
+
|
|
68
|
+
if (value && 'object' === typeof value && !Array.isArray(value)) {
|
|
69
|
+
Object.assign(result, arrayDot(value as Record<string, unknown>, newKey))
|
|
70
|
+
} else {
|
|
71
|
+
result[newKey] = value
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return result
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get all of the given array except for a specified array of keys (indices).
|
|
80
|
+
*
|
|
81
|
+
* @param {T[]} array The source array
|
|
82
|
+
* @param {string[]} keys The keys to exclude
|
|
83
|
+
* @returns {T[]} The filtered array
|
|
84
|
+
*/
|
|
85
|
+
export const arrayExcept = <T>(array: T[], keys: string[]): T[] => {
|
|
86
|
+
if (!Array.isArray(array) || !Array.isArray(keys)) {
|
|
87
|
+
return array
|
|
88
|
+
}
|
|
89
|
+
return array.filter((_, index) => !keys.includes(index.toString()))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Return the first element in an array passing a given truth test.
|
|
94
|
+
*
|
|
95
|
+
* @param {T[]} array The source array
|
|
96
|
+
* @param {Function} [callback] Optional callback for truth test
|
|
97
|
+
* @param {T} [defaultValue] Optional default value if no element found
|
|
98
|
+
* @returns {T | undefined} The first matching element or default value
|
|
99
|
+
*/
|
|
100
|
+
export const arrayFirst = <T>(
|
|
101
|
+
array: T[],
|
|
102
|
+
callback?: (item: T, index: number) => boolean,
|
|
103
|
+
defaultValue?: T
|
|
104
|
+
): T | undefined => {
|
|
105
|
+
if (!Array.isArray(array)) {
|
|
106
|
+
return defaultValue
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!callback) {
|
|
110
|
+
return 0 < array.length ? array[0] : defaultValue
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < array.length; i++) {
|
|
114
|
+
if (callback(array[i], i)) {
|
|
115
|
+
return array[i]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return defaultValue
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Flatten a multi-dimensional array into a single level.
|
|
124
|
+
*
|
|
125
|
+
* @param {unknown[]} array The array to flatten
|
|
126
|
+
* @param {number} [depth=Infinity] The depth to flatten to
|
|
127
|
+
* @returns {T[]} The flattened array
|
|
128
|
+
*/
|
|
129
|
+
export const arrayFlatten = <T>(array: unknown[], depth = Infinity): T[] => {
|
|
130
|
+
if (!Array.isArray(array)) {
|
|
131
|
+
return []
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const flatten = (arr: unknown[], currentDepth: number): T[] => {
|
|
135
|
+
const result: T[] = []
|
|
136
|
+
|
|
137
|
+
for (const item of arr) {
|
|
138
|
+
if (Array.isArray(item) && 0 < currentDepth) {
|
|
139
|
+
result.push(...flatten(item, currentDepth - 1))
|
|
140
|
+
} else {
|
|
141
|
+
result.push(item as T)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return result
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return flatten(array, depth)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get an item from a record using dot notation.
|
|
153
|
+
*
|
|
154
|
+
* @param {Record<string, unknown>} array The source record
|
|
155
|
+
* @param {string} key The key to retrieve
|
|
156
|
+
* @param {unknown} [defaultValue] The default value if key not found
|
|
157
|
+
* @returns {unknown} The value at the key or default value
|
|
158
|
+
*/
|
|
159
|
+
export const arrayGet = (array: Record<string, unknown>, key: string, defaultValue?: unknown): unknown => {
|
|
160
|
+
if (!array || 'object' !== typeof array) {
|
|
161
|
+
return defaultValue
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const keys = key.split('.')
|
|
165
|
+
let current: unknown = array
|
|
166
|
+
|
|
167
|
+
for (const k of keys) {
|
|
168
|
+
if (
|
|
169
|
+
null === current ||
|
|
170
|
+
current === undefined ||
|
|
171
|
+
'object' !== typeof current ||
|
|
172
|
+
!(k in (current as Record<string, unknown>))
|
|
173
|
+
) {
|
|
174
|
+
return defaultValue
|
|
175
|
+
}
|
|
176
|
+
current = (current as Record<string, unknown>)[k]
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return current
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Check if an item or items exist in a record using "dot" notation.
|
|
184
|
+
*
|
|
185
|
+
* @param {Record<string, unknown>} array The source record
|
|
186
|
+
* @param {string | string[]} keys The key or keys to check
|
|
187
|
+
* @returns {boolean} True if all keys exist, false otherwise
|
|
188
|
+
*/
|
|
189
|
+
export const arrayHas = (array: Record<string, unknown>, keys: string | string[]): boolean => {
|
|
190
|
+
if (!array || 'object' !== typeof array) {
|
|
191
|
+
return false
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const keyArray = Array.isArray(keys) ? keys : [keys]
|
|
195
|
+
|
|
196
|
+
return keyArray.every((key) => {
|
|
197
|
+
const keyParts = key.split('.')
|
|
198
|
+
let current: unknown = array
|
|
199
|
+
|
|
200
|
+
for (const part of keyParts) {
|
|
201
|
+
if (
|
|
202
|
+
null === current ||
|
|
203
|
+
current === undefined ||
|
|
204
|
+
'object' !== typeof current ||
|
|
205
|
+
!(part in (current as Record<string, unknown>))
|
|
206
|
+
) {
|
|
207
|
+
return false
|
|
208
|
+
}
|
|
209
|
+
current = (current as Record<string, unknown>)[part]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return true
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get a subset of the array's elements specified by keys (indices).
|
|
218
|
+
*
|
|
219
|
+
* @param {T[]} array The source array
|
|
220
|
+
* @param {string[]} keys The keys to include
|
|
221
|
+
* @returns {T[]} The filtered array
|
|
222
|
+
*/
|
|
223
|
+
export const arrayOnly = <T>(array: T[], keys: string[]): T[] => {
|
|
224
|
+
if (!Array.isArray(array) || !Array.isArray(keys)) {
|
|
225
|
+
return []
|
|
226
|
+
}
|
|
227
|
+
return array.filter((_, index) => keys.includes(index.toString()))
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Advanced array helpers
|
|
231
|
+
/**
|
|
232
|
+
* Filter the array using the given callback.
|
|
233
|
+
*
|
|
234
|
+
* @param {T[]} array The source array
|
|
235
|
+
* @param {Function} callback The callback to use for filtering
|
|
236
|
+
* @returns {T[]} The filtered array
|
|
237
|
+
*/
|
|
238
|
+
export const arrayWhere = <T>(array: T[], callback: (item: T, index: number) => boolean): T[] => {
|
|
239
|
+
if (!Array.isArray(array)) {
|
|
240
|
+
return []
|
|
241
|
+
}
|
|
242
|
+
return array.filter(callback)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Pluck an array of values from an array of objects.
|
|
247
|
+
*
|
|
248
|
+
* @param {T[]} array The source array
|
|
249
|
+
* @param {K} key The key to pluck
|
|
250
|
+
* @returns {T[K][]} The plucked values
|
|
251
|
+
*/
|
|
252
|
+
export const arrayPluck = <T, K extends keyof T>(array: T[], key: K): T[K][] => {
|
|
253
|
+
if (!Array.isArray(array)) {
|
|
254
|
+
return []
|
|
255
|
+
}
|
|
256
|
+
return array
|
|
257
|
+
.map((item) => (item && 'object' === typeof item ? item[key] : undefined))
|
|
258
|
+
.filter((value) => value !== undefined) as T[K][]
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Group an array's items by a given key or callback.
|
|
263
|
+
*
|
|
264
|
+
* @param {T[]} array The source array
|
|
265
|
+
* @param {keyof T | Function} keyOrFn The key or callback to group by
|
|
266
|
+
* @returns {Record<string, T[]>} The grouped items
|
|
267
|
+
*/
|
|
268
|
+
export const arrayGroupBy = <T>(array: T[], keyOrFn: keyof T | ((item: T) => string | number)): Record<string, T[]> => {
|
|
269
|
+
if (!Array.isArray(array)) {
|
|
270
|
+
return {}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return array.reduce(
|
|
274
|
+
(groups, item) => {
|
|
275
|
+
const key =
|
|
276
|
+
'function' === typeof keyOrFn
|
|
277
|
+
? String(keyOrFn(item))
|
|
278
|
+
: String(item && 'object' === typeof item ? item[keyOrFn] : item)
|
|
279
|
+
|
|
280
|
+
if (!groups[key]) {
|
|
281
|
+
groups[key] = []
|
|
282
|
+
}
|
|
283
|
+
groups[key].push(item)
|
|
284
|
+
|
|
285
|
+
return groups
|
|
286
|
+
},
|
|
287
|
+
{} as Record<string, T[]>
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Filter the array to only unique elements.
|
|
293
|
+
*
|
|
294
|
+
* @param {T[]} array The source array
|
|
295
|
+
* @param {keyof T} [key] Optional key to use for uniqueness
|
|
296
|
+
* @returns {T[]} The array with unique elements
|
|
297
|
+
*/
|
|
298
|
+
export const arrayUnique = <T>(array: T[], key?: keyof T): T[] => {
|
|
299
|
+
if (!Array.isArray(array)) {
|
|
300
|
+
return []
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!key) {
|
|
304
|
+
return [...new Set(array)]
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const seen = new Set()
|
|
308
|
+
return array.filter((item) => {
|
|
309
|
+
const value = item && 'object' === typeof item ? item[key] : item
|
|
310
|
+
if (seen.has(value)) {
|
|
311
|
+
return false
|
|
312
|
+
}
|
|
313
|
+
seen.add(value)
|
|
314
|
+
return true
|
|
315
|
+
})
|
|
316
|
+
}
|