@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
@@ -0,0 +1,253 @@
1
+ // src/number.ts
2
+ var Numberable = class {
3
+ /**
4
+ * Create a new Numberable instance.
5
+ *
6
+ * @param {unknown} value The initial value
7
+ */
8
+ constructor(value) {
9
+ this.value = Number(value ?? 0);
10
+ if (isNaN(this.value)) {
11
+ this.value = 0;
12
+ }
13
+ }
14
+ /**
15
+ * Get the raw number value.
16
+ *
17
+ * @returns {number} The raw value
18
+ */
19
+ toNumber() {
20
+ return this.value;
21
+ }
22
+ /**
23
+ * Alias for toNumber().
24
+ *
25
+ * @returns {number} The raw value
26
+ */
27
+ get() {
28
+ return this.value;
29
+ }
30
+ /**
31
+ * Format the number with locale-specific formatting.
32
+ *
33
+ * @param {number} [decimals=0] The number of decimal points
34
+ * @param {string} [locale='en-US'] The locale to use for formatting
35
+ * @returns {string} The formatted number
36
+ */
37
+ format(decimals = 0, locale = "en-US") {
38
+ return new Intl.NumberFormat(locale, {
39
+ minimumFractionDigits: decimals,
40
+ maximumFractionDigits: decimals
41
+ }).format(this.value);
42
+ }
43
+ /**
44
+ * Format the number as currency.
45
+ *
46
+ * @param {string} [currency='USD'] The currency code (e.g., 'USD', 'EUR')
47
+ * @param {string} [locale='en-US'] The locale to use for formatting
48
+ * @returns {string} The formatted currency string
49
+ */
50
+ currency(currency = "USD", locale = "en-US") {
51
+ return new Intl.NumberFormat(locale, {
52
+ style: "currency",
53
+ currency
54
+ }).format(this.value);
55
+ }
56
+ /**
57
+ * Format the number as a percentage.
58
+ *
59
+ * @param {number} [decimals=0] The number of decimal points
60
+ * @param {string} [locale='en-US'] The locale to use for formatting
61
+ * @returns {string} The formatted percentage string
62
+ */
63
+ percentage(decimals = 0, locale = "en-US") {
64
+ return new Intl.NumberFormat(locale, {
65
+ style: "percent",
66
+ minimumFractionDigits: decimals,
67
+ maximumFractionDigits: decimals
68
+ }).format(this.value / 100);
69
+ }
70
+ /**
71
+ * Format the number as a human-readable file size.
72
+ *
73
+ * @param {number} [precision=2] The number of decimal points
74
+ * @returns {string} The formatted file size (e.g., "1.50 MB")
75
+ */
76
+ fileSize(precision = 2) {
77
+ if (0 === this.value) {
78
+ return "0 B";
79
+ }
80
+ const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
81
+ const i = Math.floor(Math.log(this.value) / Math.log(1024));
82
+ return `${parseFloat((this.value / Math.pow(1024, i)).toFixed(precision))} ${units[i]}`;
83
+ }
84
+ /**
85
+ * Abbreviate the number (e.g., 1K, 1M, 1B).
86
+ *
87
+ * @param {number} [precision=1] The number of decimal points
88
+ * @returns {string} The abbreviated number
89
+ */
90
+ abbreviate(precision = 1) {
91
+ if (1e3 > this.value) {
92
+ return String(this.value);
93
+ }
94
+ const units = ["", "K", "M", "B", "T"];
95
+ const i = Math.floor(Math.log10(this.value) / 3);
96
+ return `${parseFloat((this.value / Math.pow(1e3, i)).toFixed(precision))}${units[i]}`;
97
+ }
98
+ /**
99
+ * Add an ordinal suffix to the number (e.g., 1st, 2nd, 3rd).
100
+ *
101
+ * @returns {string} The number with its ordinal suffix
102
+ */
103
+ ordinal() {
104
+ const s = ["th", "st", "nd", "rd"];
105
+ const v = this.value % 100;
106
+ return this.value + (s[(v - 20) % 10] || s[v] || s[0]);
107
+ }
108
+ /**
109
+ * Clamp the number between a minimum and maximum value.
110
+ *
111
+ * @param {number} min The minimum value
112
+ * @param {number} max The maximum value
113
+ * @returns {this} The Numberable instance
114
+ */
115
+ clamp(min, max) {
116
+ this.value = Math.min(Math.max(this.value, min), max);
117
+ return this;
118
+ }
119
+ /**
120
+ * Check if the number is between a minimum and maximum value.
121
+ *
122
+ * @param {number} min The minimum value
123
+ * @param {number} max The maximum value
124
+ * @param {boolean} [inclusive=true] Whether to include the boundaries
125
+ * @returns {boolean} True if the number is between min and max
126
+ */
127
+ isBetween(min, max, inclusive = true) {
128
+ return inclusive ? this.value >= min && this.value <= max : this.value > min && this.value < max;
129
+ }
130
+ /**
131
+ * Add a value to the current number.
132
+ *
133
+ * @param {number} value The value to add
134
+ * @returns {this} The Numberable instance
135
+ */
136
+ add(value) {
137
+ this.value += value;
138
+ return this;
139
+ }
140
+ /**
141
+ * Subtract a value from the current number.
142
+ *
143
+ * @param {number} value The value to subtract
144
+ * @returns {this} The Numberable instance
145
+ */
146
+ sub(value) {
147
+ this.value -= value;
148
+ return this;
149
+ }
150
+ /**
151
+ * Multiply the current number by a value.
152
+ *
153
+ * @param {number} value The value to multiply by
154
+ * @returns {this} The Numberable instance
155
+ */
156
+ mul(value) {
157
+ this.value *= value;
158
+ return this;
159
+ }
160
+ /**
161
+ * Divide the current number by a value.
162
+ *
163
+ * @param {number} value The value to divide by
164
+ * @returns {this} The Numberable instance
165
+ */
166
+ div(value) {
167
+ if (0 !== value) {
168
+ this.value /= value;
169
+ }
170
+ return this;
171
+ }
172
+ /**
173
+ * Round the number to a specified precision.
174
+ *
175
+ * @param {number} [precision=0] The number of decimal points
176
+ * @returns {this} The Numberable instance
177
+ */
178
+ round(precision = 0) {
179
+ const factor = Math.pow(10, precision);
180
+ this.value = Math.round(this.value * factor) / factor;
181
+ return this;
182
+ }
183
+ /**
184
+ * Round the number up to a specified precision.
185
+ *
186
+ * @param {number} [precision=0] The number of decimal points
187
+ * @returns {this} The Numberable instance
188
+ */
189
+ ceil(precision = 0) {
190
+ const factor = Math.pow(10, precision);
191
+ this.value = Math.ceil(this.value * factor) / factor;
192
+ return this;
193
+ }
194
+ /**
195
+ * Round the number down to a specified precision.
196
+ *
197
+ * @param {number} [precision=0] The number of decimal points
198
+ * @returns {this} The Numberable instance
199
+ */
200
+ floor(precision = 0) {
201
+ const factor = Math.pow(10, precision);
202
+ this.value = Math.floor(this.value * factor) / factor;
203
+ return this;
204
+ }
205
+ /**
206
+ * Pipe the current Numberable instance to a callback.
207
+ *
208
+ * @param {Function} callback The callback to execute
209
+ * @returns {U} The result of the callback
210
+ */
211
+ pipe(callback) {
212
+ return callback(this);
213
+ }
214
+ /**
215
+ * Execute a callback if a condition is met.
216
+ *
217
+ * @param {boolean | Function} condition The condition to check
218
+ * @param {Function} callback The callback to execute if condition is true
219
+ * @returns {this} The Numberable instance
220
+ */
221
+ when(condition, callback) {
222
+ const shouldExecute = "function" === typeof condition ? condition() : condition;
223
+ if (shouldExecute) {
224
+ callback(this);
225
+ }
226
+ return this;
227
+ }
228
+ };
229
+ var num = (value) => {
230
+ return new Numberable(value);
231
+ };
232
+ var NumberHelper = {
233
+ /** Create a new Numberable instance */
234
+ of: (value) => new Numberable(value),
235
+ /** Format the number with locale-specific formatting */
236
+ format: (value, decimals = 0, locale = "en-US") => new Numberable(value).format(decimals, locale),
237
+ /** Format the number as currency */
238
+ currency: (value, currency = "USD", locale = "en-US") => new Numberable(value).currency(currency, locale),
239
+ /** Format the number as a percentage */
240
+ percentage: (value, decimals = 0, locale = "en-US") => new Numberable(value).percentage(decimals, locale),
241
+ /** Format the number as a human-readable file size */
242
+ fileSize: (value, precision = 2) => new Numberable(value).fileSize(precision),
243
+ /** Abbreviate the number */
244
+ abbreviate: (value, precision = 1) => new Numberable(value).abbreviate(precision),
245
+ /** Add an ordinal suffix to the number */
246
+ ordinal: (value) => new Numberable(value).ordinal()
247
+ };
248
+
249
+ export {
250
+ Numberable,
251
+ num,
252
+ NumberHelper
253
+ };
@@ -0,0 +1,136 @@
1
+ import {
2
+ diff,
3
+ isEqual
4
+ } from "./chunk-LDSWHSRX.js";
5
+
6
+ // src/validator.ts
7
+ import { z } from "zod";
8
+ var Validator = class {
9
+ /**
10
+ * Create a new validation instance
11
+ *
12
+ * @param {unknown} data The data to validate
13
+ * @param {T | z.ZodObject<T>} rules The validation rules (Zod shape or object)
14
+ * @returns {ValidationInstance<z.ZodObject<T>>} A new ValidationInstance
15
+ */
16
+ static make(data, rules) {
17
+ const schema = rules instanceof z.ZodObject ? rules : z.object(rules);
18
+ return new ValidationInstance(data, schema);
19
+ }
20
+ /**
21
+ * Validate data against rules and throw if it fails
22
+ *
23
+ * @param {unknown} data The data to validate
24
+ * @param {T | z.ZodObject<T>} rules The validation rules (Zod shape or object)
25
+ * @returns {z.infer<z.ZodObject<T>>} The validated data
26
+ * @throws {z.ZodError} If validation fails
27
+ */
28
+ static validate(data, rules) {
29
+ const schema = rules instanceof z.ZodObject ? rules : z.object(rules);
30
+ return schema.parse(data);
31
+ }
32
+ /**
33
+ * Compare two objects for equality
34
+ *
35
+ * @param {unknown} a First object
36
+ * @param {unknown} b Second object
37
+ * @returns {boolean} True if the objects are equal
38
+ */
39
+ static isEqual(a, b) {
40
+ return isEqual(a, b);
41
+ }
42
+ /**
43
+ * Get the differences between two objects
44
+ *
45
+ * @param {unknown} a First object
46
+ * @param {unknown} b Second object
47
+ * @returns {GenericRecord} An object containing the differences
48
+ */
49
+ static diff(a, b) {
50
+ return diff(a, b);
51
+ }
52
+ };
53
+ var ValidationInstance = class {
54
+ constructor(data, schema) {
55
+ this.data = data;
56
+ this.schema = schema;
57
+ this.result = this.schema.safeParse(this.data);
58
+ }
59
+ /**
60
+ * Check if validation failed
61
+ *
62
+ * @returns {boolean} True if validation failed
63
+ */
64
+ fails() {
65
+ return !this.result.success;
66
+ }
67
+ /**
68
+ * Check if validation passed
69
+ *
70
+ * @returns {boolean} True if validation passed
71
+ */
72
+ passes() {
73
+ return this.result.success;
74
+ }
75
+ /**
76
+ * Get validation errors
77
+ *
78
+ * @returns {Record<string, string[]>} An object with field names as keys and arrays of error messages as values
79
+ */
80
+ errors() {
81
+ if (this.result.success) {
82
+ return {};
83
+ }
84
+ const errors = {};
85
+ this.result.error.issues.forEach((err) => {
86
+ const path = err.path.join(".") || "root";
87
+ if (!errors[path]) {
88
+ errors[path] = [];
89
+ }
90
+ errors[path].push(err.message);
91
+ });
92
+ return errors;
93
+ }
94
+ /**
95
+ * Get the first error message for a given field
96
+ *
97
+ * @param {string} field The field name
98
+ * @returns {string | undefined} The first error message or undefined
99
+ */
100
+ firstError(field) {
101
+ const fieldErrors = this.errors()[field];
102
+ return fieldErrors ? fieldErrors[0] : void 0;
103
+ }
104
+ /**
105
+ * Get the validated data
106
+ *
107
+ * @returns {z.infer<T>} The validated data
108
+ * @throws {Error} If validation failed
109
+ */
110
+ validated() {
111
+ if (!this.result.success) {
112
+ throw new Error("Validation failed");
113
+ }
114
+ return this.result.data;
115
+ }
116
+ /**
117
+ * Get all error messages as a flat array
118
+ *
119
+ * @returns {string[]} An array of all error messages
120
+ */
121
+ allErrors() {
122
+ if (this.result.success) {
123
+ return [];
124
+ }
125
+ return this.result.error.issues.map((err) => `${err.path.join(".")}: ${err.message}`);
126
+ }
127
+ };
128
+ var validator = (data, rules) => {
129
+ return Validator.make(data, rules);
130
+ };
131
+
132
+ export {
133
+ Validator,
134
+ ValidationInstance,
135
+ validator
136
+ };
@@ -0,0 +1,96 @@
1
+ // src/equals.ts
2
+ var isEqual = (a, b) => {
3
+ if (a === b) {
4
+ return true;
5
+ }
6
+ if (a && b && "object" === typeof a && "object" === typeof b) {
7
+ if (a.constructor !== b.constructor) {
8
+ return false;
9
+ }
10
+ if (Array.isArray(a)) {
11
+ if (a.length !== b.length) {
12
+ return false;
13
+ }
14
+ for (let i = 0; i < a.length; i++) {
15
+ if (!isEqual(a[i], b[i])) {
16
+ return false;
17
+ }
18
+ }
19
+ return true;
20
+ }
21
+ if (a instanceof Map && b instanceof Map) {
22
+ if (a.size !== b.size) {
23
+ return false;
24
+ }
25
+ for (const [key, val] of a) {
26
+ if (!b.has(key) || !isEqual(val, b.get(key))) {
27
+ return false;
28
+ }
29
+ }
30
+ return true;
31
+ }
32
+ if (a instanceof Set && b instanceof Set) {
33
+ if (a.size !== b.size) {
34
+ return false;
35
+ }
36
+ for (const val of a) {
37
+ if (!b.has(val)) {
38
+ return false;
39
+ }
40
+ }
41
+ return true;
42
+ }
43
+ if (a.constructor === RegExp) {
44
+ return a.source === b.source && a.flags === b.flags;
45
+ }
46
+ if (a.valueOf !== Object.prototype.valueOf) {
47
+ return a.valueOf() === b.valueOf();
48
+ }
49
+ if (a.toString !== Object.prototype.toString) {
50
+ return a.toString() === b.toString();
51
+ }
52
+ const keys = Object.keys(a);
53
+ if (keys.length !== Object.keys(b).length) {
54
+ return false;
55
+ }
56
+ const bObj = b;
57
+ const aObj = a;
58
+ for (const key of keys) {
59
+ if (!Object.prototype.hasOwnProperty.call(bObj, key)) {
60
+ return false;
61
+ }
62
+ if (!isEqual(aObj[key], bObj[key])) {
63
+ return false;
64
+ }
65
+ }
66
+ return true;
67
+ }
68
+ return a !== a && b !== b;
69
+ };
70
+ var diff = (original, current) => {
71
+ const result = {};
72
+ if (isEqual(original, current)) {
73
+ return result;
74
+ }
75
+ if (!original || !current || "object" !== typeof original || "object" !== typeof current) {
76
+ return current || {};
77
+ }
78
+ const originalObj = original;
79
+ const currentObj = current;
80
+ const keys = /* @__PURE__ */ new Set([...Object.keys(originalObj), ...Object.keys(currentObj)]);
81
+ for (const key of keys) {
82
+ if (!isEqual(originalObj[key], currentObj[key])) {
83
+ if (originalObj[key] && currentObj[key] && "object" === typeof originalObj[key] && "object" === typeof currentObj[key] && !Array.isArray(originalObj[key])) {
84
+ result[key] = diff(originalObj[key], currentObj[key]);
85
+ } else {
86
+ result[key] = currentObj[key];
87
+ }
88
+ }
89
+ }
90
+ return result;
91
+ };
92
+
93
+ export {
94
+ isEqual,
95
+ diff
96
+ };