@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
|
@@ -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
|
+
};
|