@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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +270 -0
  3. package/dist/arrays.cjs +210 -0
  4. package/dist/arrays.d.cts +119 -0
  5. package/dist/arrays.d.ts +119 -0
  6. package/dist/arrays.js +32 -0
  7. package/dist/chunk-27YHP2CK.js +407 -0
  8. package/dist/chunk-3WNRYKPG.js +37 -0
  9. package/dist/chunk-42CHLXT7.js +214 -0
  10. package/dist/chunk-6F4PWJZI.js +0 -0
  11. package/dist/chunk-7SXRFZBB.js +173 -0
  12. package/dist/chunk-F6RSTW65.js +156 -0
  13. package/dist/chunk-G7ZJ23DW.js +253 -0
  14. package/dist/chunk-IPP7PA6H.js +136 -0
  15. package/dist/chunk-LDSWHSRX.js +96 -0
  16. package/dist/chunk-TY75OOIQ.js +700 -0
  17. package/dist/chunk-W6JEMFAF.js +54 -0
  18. package/dist/chunk-XEJLBAXE.js +164 -0
  19. package/dist/chunk-Z7G3SIQH.js +270 -0
  20. package/dist/chunk-ZJPKS2MQ.js +101 -0
  21. package/dist/collections.cjs +797 -0
  22. package/dist/collections.d.cts +353 -0
  23. package/dist/collections.d.ts +353 -0
  24. package/dist/collections.js +17 -0
  25. package/dist/datetime.cjs +80 -0
  26. package/dist/datetime.d.cts +75 -0
  27. package/dist/datetime.d.ts +75 -0
  28. package/dist/datetime.js +24 -0
  29. package/dist/equals.cjs +121 -0
  30. package/dist/equals.d.cts +24 -0
  31. package/dist/equals.d.ts +24 -0
  32. package/dist/equals.js +8 -0
  33. package/dist/formatters.cjs +201 -0
  34. package/dist/formatters.d.cts +180 -0
  35. package/dist/formatters.d.ts +180 -0
  36. package/dist/formatters.js +48 -0
  37. package/dist/index.cjs +2906 -0
  38. package/dist/index.d.cts +120 -0
  39. package/dist/index.d.ts +120 -0
  40. package/dist/index.js +348 -0
  41. package/dist/number.cjs +279 -0
  42. package/dist/number.d.cts +177 -0
  43. package/dist/number.d.ts +177 -0
  44. package/dist/number.js +10 -0
  45. package/dist/obj.cjs +427 -0
  46. package/dist/obj.d.cts +177 -0
  47. package/dist/obj.d.ts +177 -0
  48. package/dist/obj.js +12 -0
  49. package/dist/php-arrays.cjs +954 -0
  50. package/dist/php-arrays.d.cts +256 -0
  51. package/dist/php-arrays.d.ts +256 -0
  52. package/dist/php-arrays.js +70 -0
  53. package/dist/runtime.cjs +134 -0
  54. package/dist/runtime.d.cts +90 -0
  55. package/dist/runtime.d.ts +90 -0
  56. package/dist/runtime.js +24 -0
  57. package/dist/schemas.cjs +86 -0
  58. package/dist/schemas.d.cts +108 -0
  59. package/dist/schemas.d.ts +108 -0
  60. package/dist/schemas.js +22 -0
  61. package/dist/str.cjs +499 -0
  62. package/dist/str.d.cts +282 -0
  63. package/dist/str.d.ts +282 -0
  64. package/dist/str.js +11 -0
  65. package/dist/types.cjs +18 -0
  66. package/dist/types.d.cts +13 -0
  67. package/dist/types.d.ts +13 -0
  68. package/dist/types.js +1 -0
  69. package/dist/validator.cjs +251 -0
  70. package/dist/validator.d.cts +99 -0
  71. package/dist/validator.d.ts +99 -0
  72. package/dist/validator.js +11 -0
  73. package/dist/validators.cjs +217 -0
  74. package/dist/validators.d.cts +216 -0
  75. package/dist/validators.d.ts +216 -0
  76. package/dist/validators.js +64 -0
  77. package/package.json +180 -0
  78. package/src/arrays.ts +316 -0
  79. package/src/collections.ts +866 -0
  80. package/src/datetime.ts +103 -0
  81. package/src/equals.ts +134 -0
  82. package/src/formatters.ts +342 -0
  83. package/src/index.ts +36 -0
  84. package/src/number.ts +281 -0
  85. package/src/obj.ts +303 -0
  86. package/src/php-arrays.ts +445 -0
  87. package/src/pipe.ts +29 -0
  88. package/src/runtime.ts +194 -0
  89. package/src/schemas.ts +136 -0
  90. package/src/str.ts +438 -0
  91. package/src/types.ts +13 -0
  92. package/src/validator.ts +157 -0
  93. 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
+ }