toolbox-x 1.2.0 → 2.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 (126) hide show
  1. package/dist/{Color-Dsut0Bex.d.cts → Color-B8MR8Vp0.d.cts} +1 -1
  2. package/dist/{Color-DCfoQk_-.d.mts → Color-D2MfZx7L.d.mts} +1 -1
  3. package/dist/{Stylog-DXZtHAbp.d.mts → Stylog-CSbLtqrZ.d.mts} +5 -5
  4. package/dist/{Stylog-TyLCTRtT.d.cts → Stylog-DF0CWtZb.d.cts} +5 -5
  5. package/dist/{area-CvSC96va.d.mts → area-C4tDXnGC.d.mts} +3 -3
  6. package/dist/{area-CcRQ6TfR.d.cts → area-CMJZ0gVm.d.cts} +3 -3
  7. package/dist/{array-B6jWzJ4F.d.mts → array-26Vs2HCs.d.mts} +1 -1
  8. package/dist/{array-CqDu610k.d.cts → array-DJAq9Qj8.d.cts} +1 -1
  9. package/dist/{basics-K8BDSYD6.cjs → basics-CJmdhXoo.cjs} +567 -14
  10. package/dist/{basics-1_M7UvCn.mjs → basics-CebgkY-n.mjs} +449 -16
  11. package/dist/{basics-KobRNhV-.d.cts → basics-Cis9Ej6c.d.mts} +5 -5
  12. package/dist/{basics-V5M2oltn.d.mts → basics-D4yU0NQ_.d.cts} +5 -5
  13. package/dist/{case-uKFzt5TY.cjs → case-Bd7QLHYw.cjs} +3 -3
  14. package/dist/{case-KdrBKjjK.d.mts → case-ChRzRBnY.d.mts} +12 -12
  15. package/dist/{case-BQwn5N-k.mjs → case-DBC4Rj0h.mjs} +3 -3
  16. package/dist/{case--Vjea9DS.d.cts → case-DkYSKSeV.d.cts} +12 -12
  17. package/dist/change-case.cjs +1 -1
  18. package/dist/change-case.d.cts +1 -1
  19. package/dist/change-case.d.mts +1 -1
  20. package/dist/change-case.mjs +1 -1
  21. package/dist/colors.d.cts +2 -2
  22. package/dist/colors.d.mts +2 -2
  23. package/dist/constants.d.cts +1 -1
  24. package/dist/constants.d.mts +1 -1
  25. package/dist/converter.cjs +2 -2
  26. package/dist/converter.d.cts +2 -2
  27. package/dist/converter.d.mts +2 -2
  28. package/dist/converter.mjs +2 -2
  29. package/dist/date.cjs +10 -10
  30. package/dist/date.d.cts +4 -4
  31. package/dist/date.d.mts +4 -4
  32. package/dist/date.mjs +10 -10
  33. package/dist/dom.cjs +5 -6
  34. package/dist/dom.d.cts +3 -3
  35. package/dist/dom.d.mts +3 -3
  36. package/dist/dom.mjs +4 -5
  37. package/dist/{form-DoQGMTOc.d.mts → form-Cp1OyCRI.d.cts} +2 -2
  38. package/dist/{form-mP-nl8EC.d.cts → form-DPdS2AhM.d.mts} +2 -2
  39. package/dist/guards-B2s2wlVN.mjs +425 -0
  40. package/dist/{guards-Cp6KAkVI.mjs → guards-BK1QuvFZ.mjs} +3 -3
  41. package/dist/{guards-DP5k4_Mm.cjs → guards-Bsh6Bfdq.cjs} +3 -3
  42. package/dist/{guards-0VjySrPM.cjs → guards-DMJcjPDt.cjs} +279 -3
  43. package/dist/guards.cjs +9 -9
  44. package/dist/guards.d.cts +6 -5
  45. package/dist/guards.d.mts +6 -5
  46. package/dist/guards.mjs +5 -5
  47. package/dist/{hash-BcoFHSu1.d.cts → hash-DfhOK0Fi.d.mts} +1 -1
  48. package/dist/{hash-GYRx2ee_.d.mts → hash-IdZN0mIe.d.cts} +1 -1
  49. package/dist/hash.cjs +8 -8
  50. package/dist/hash.d.cts +8 -8
  51. package/dist/hash.d.mts +8 -8
  52. package/dist/hash.mjs +4 -5
  53. package/dist/{http-status-xrlR-LlB.d.mts → http-status-B-yBZr-J.d.mts} +1 -1
  54. package/dist/{http-status-C0DOpCDf.d.cts → http-status-Dq_hoSG6.d.cts} +1 -1
  55. package/dist/http-status.cjs +4 -4
  56. package/dist/http-status.d.cts +6 -6
  57. package/dist/http-status.d.mts +6 -6
  58. package/dist/http-status.mjs +4 -4
  59. package/dist/index-C5FoCCbF.d.cts +292 -0
  60. package/dist/index-CIJWxnDS.d.mts +292 -0
  61. package/dist/index.cjs +67 -248
  62. package/dist/index.d.cts +25 -280
  63. package/dist/index.d.mts +25 -280
  64. package/dist/index.mjs +11 -194
  65. package/dist/{object-ChFVh95z.d.cts → object-X5fSMx-I.d.cts} +13 -1
  66. package/dist/{object-ChFVh95z.d.mts → object-X5fSMx-I.d.mts} +13 -1
  67. package/dist/{objectify-CfXtS_E0.mjs → objectify-CQa8gQib.mjs} +3 -4
  68. package/dist/{objectify-CZJr9hwg.cjs → objectify-xQvZS3UI.cjs} +5 -6
  69. package/dist/paginator.d.cts +1 -1
  70. package/dist/paginator.d.mts +1 -1
  71. package/dist/{parse-BpUlILVi.cjs → parse-DT7jbWx7.cjs} +5 -5
  72. package/dist/{parse-rcJRAOJl.mjs → parse-erxBG2hd.mjs} +5 -5
  73. package/dist/{pluralizer-CdG-VJ6t.d.cts → pluralizer-B8vuljyy.d.cts} +1 -1
  74. package/dist/{pluralizer-D2Lh8CdU.d.mts → pluralizer-DOdDskzF.d.mts} +1 -1
  75. package/dist/pluralizer.cjs +6 -6
  76. package/dist/pluralizer.d.cts +6 -6
  77. package/dist/pluralizer.d.mts +6 -6
  78. package/dist/pluralizer.mjs +6 -6
  79. package/dist/{specials-Cye93-uo.mjs → specials-Hq5Ncd6y.mjs} +2 -2
  80. package/dist/{specials-BM6cx43o.cjs → specials-dkYP1Nh2.cjs} +2 -2
  81. package/dist/{string-CkwTVFeL.d.mts → string-C51m7T6d.d.mts} +4 -2
  82. package/dist/{string-Dq2b8rcN.d.cts → string-CO7HP50i.d.cts} +4 -2
  83. package/dist/stylog.cjs +5 -5
  84. package/dist/stylog.d.cts +2 -2
  85. package/dist/stylog.d.mts +2 -2
  86. package/dist/stylog.mjs +5 -5
  87. package/dist/types/array.d.cts +1 -1
  88. package/dist/types/array.d.mts +1 -1
  89. package/dist/types/colors.d.cts +1 -1
  90. package/dist/types/colors.d.mts +1 -1
  91. package/dist/types/converter.d.cts +1 -1
  92. package/dist/types/converter.d.mts +1 -1
  93. package/dist/types/date.d.cts +1 -1
  94. package/dist/types/date.d.mts +1 -1
  95. package/dist/types/form.d.cts +1 -1
  96. package/dist/types/form.d.mts +1 -1
  97. package/dist/types/hash.d.cts +1 -1
  98. package/dist/types/hash.d.mts +1 -1
  99. package/dist/types/http-status.d.cts +1 -1
  100. package/dist/types/http-status.d.mts +1 -1
  101. package/dist/types/index.d.cts +2 -2
  102. package/dist/types/index.d.mts +2 -2
  103. package/dist/types/number.d.cts +1 -1
  104. package/dist/types/number.d.mts +1 -1
  105. package/dist/types/object.d.cts +2 -2
  106. package/dist/types/object.d.mts +2 -2
  107. package/dist/types/pluralizer.d.cts +1 -1
  108. package/dist/types/pluralizer.d.mts +1 -1
  109. package/dist/types/string.d.cts +2 -2
  110. package/dist/types/string.d.mts +2 -2
  111. package/dist/types/stylog.d.cts +1 -1
  112. package/dist/types/stylog.d.mts +1 -1
  113. package/dist/types/utils.d.cts +1 -1
  114. package/dist/types/utils.d.mts +1 -1
  115. package/dist/{utilities-CzyXCRHM.cjs → utilities-CWV1GPGY.cjs} +1 -1
  116. package/dist/{utilities-B9axOvOX.mjs → utilities-DPscNbS1.mjs} +1 -1
  117. package/dist/{uuid-DgTBxcVu.d.cts → uuid-BUI3Jt8n.d.cts} +3 -3
  118. package/dist/{uuid-Yc3Uu8qr.d.mts → uuid-mEiy14sf.d.mts} +3 -3
  119. package/dist/verbalizer.cjs +3 -3
  120. package/dist/verbalizer.d.cts +3 -3
  121. package/dist/verbalizer.d.mts +3 -3
  122. package/dist/verbalizer.mjs +3 -3
  123. package/package.json +7 -6
  124. package/dist/guards-DeO4ukiK.mjs +0 -221
  125. package/dist/utils-CFyEFj2Y.cjs +0 -568
  126. package/dist/utils-CN3ocK98.mjs +0 -449
@@ -1,449 +0,0 @@
1
- /**
2
- * Copyright 2026 - present Nazmul Hassan
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
-
17
- import { a as isNonEmptyString, c as isNumber, d as isString, n as isBoolean, u as isPrimitive } from "./primitives-Djsevc69.mjs";
18
- import { C as isMethodDescriptor, T as isObject, d as isNumericString, g as isArrayOfType, h as isArray, j as isValidArray, w as isNotEmptyObject } from "./specials-Cye93-uo.mjs";
19
- import { a as normalizeNumber } from "./utilities-B9axOvOX.mjs";
20
- import { t as isDateLike } from "./guards-Cp6KAkVI.mjs";
21
-
22
- //#region src/array/helpers.ts
23
- /**
24
- * Safely resolves nested keys from a dot-separated string like "user.city".
25
- *
26
- * @param obj - The source object
27
- * @param path - The nested path string (e.g. "user.city")
28
- * @returns The resolved value or `undefined`
29
- */
30
- function _resolveNestedKey(obj, path) {
31
- if (isNotEmptyObject(obj)) return path?.split(".").reduce((acc, key) => {
32
- if (isNotEmptyObject(acc)) return acc[key];
33
- }, obj);
34
- }
35
- /**
36
- * Retrieves a numeric value from a nested property in dot notation.
37
- * Falls back to 0 if value is not a number or numeric string.
38
- *
39
- * @param obj - The source object to read from.
40
- * @param path - The path string like 'user.income.tax'.
41
- * @returns The numeric value at that path, or 0 if not valid.
42
- */
43
- function _getNumericProp(obj, path) {
44
- if (isNotEmptyObject(obj)) {
45
- const value = path?.split(".").reduce((acc, key) => {
46
- if (isNotEmptyObject(acc)) return acc[key];
47
- }, obj);
48
- return normalizeNumber(value) ?? 0;
49
- } else return 0;
50
- }
51
-
52
- //#endregion
53
- //#region src/array/sort.ts
54
- /**
55
- * Compare two strings using natural sorting (e.g., `"file2"` < `"file10"`).
56
- * - Optionally supports case-insensitive and locale-aware string chunk comparisons.
57
- *
58
- * @param a - The first string to compare.
59
- * @param b - The second string to compare.
60
- * @param options - Optional settings to configure comparison behavior.
61
- * @returns A negative number if `a` comes before `b`, a positive number if `a` comes after `b`, or 0 if equal.
62
- */
63
- function naturalSort(a, b, options) {
64
- const { caseInsensitive = true, localeAware = false } = options || {};
65
- /**
66
- * * Splits a string into an array of number and non-number chunks.
67
- * @param str - The string to split.
68
- * @returns An array of string and number parts.
69
- */
70
- const _createChunks = (str) => {
71
- const chunks = [];
72
- let current = "";
73
- let isNumeric = false;
74
- for (const char of str) {
75
- const charIsNum = !Number.isNaN(Number(char));
76
- if (current?.length === 0) {
77
- current = char;
78
- isNumeric = charIsNum;
79
- continue;
80
- }
81
- if (charIsNum === isNumeric) current += char;
82
- else {
83
- chunks?.push(isNumeric ? Number(current) : current);
84
- current = char;
85
- isNumeric = charIsNum;
86
- }
87
- }
88
- if (current?.length > 0) chunks?.push(isNumeric ? Number(current) : current);
89
- return chunks;
90
- };
91
- const aChunks = _createChunks(a);
92
- const bChunks = _createChunks(b);
93
- for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
94
- let aChunk = aChunks[i];
95
- let bChunk = bChunks[i];
96
- if (caseInsensitive && isString(aChunk) && isString(bChunk)) {
97
- aChunk = aChunk?.toLowerCase();
98
- bChunk = bChunk?.toLowerCase();
99
- }
100
- if (typeof aChunk !== typeof bChunk) return isString(aChunk) ? 1 : -1;
101
- if (aChunk !== bChunk) {
102
- if (isNumber(aChunk) && isNumber(bChunk)) return aChunk - bChunk;
103
- if (isString(aChunk) && isString(bChunk)) {
104
- if (localeAware) {
105
- const cmp = aChunk.localeCompare(bChunk, void 0, { sensitivity: caseInsensitive ? "accent" : "variant" });
106
- if (cmp !== 0) return cmp;
107
- }
108
- return aChunk < bChunk ? -1 : 1;
109
- }
110
- }
111
- }
112
- return aChunks?.length - bChunks?.length;
113
- }
114
- /**
115
- * * Sorts an array of strings, numbers, booleans, or objects based on the provided options.
116
- *
117
- * @param array - The array to sort.
118
- * @param options - Sorting options.
119
- * @returns The sorted array.
120
- */
121
- function sortAnArray(array, options) {
122
- if (!isValidArray(array)) return array;
123
- if (isArrayOfType(array, isString)) return [...array].sort((a, b) => options?.sortOrder === "desc" ? naturalSort(b, a) : naturalSort(a, b));
124
- if (isArrayOfType(array, isNumber)) return [...array].sort((a, b) => options?.sortOrder === "desc" ? b - a : a - b);
125
- if (isArrayOfType(array, isBoolean)) return [...array].sort((a, b) => options?.sortOrder === "desc" ? Number(b) - Number(a) : Number(a) - Number(b));
126
- if (isArrayOfType(array, isObject) && options && "sortByField" in options) return [...array].sort((a, b) => {
127
- const _getKeyValue = (obj, path) => {
128
- return path.split(".").reduce((acc, key) => acc?.[key], obj);
129
- };
130
- const keyA = _getKeyValue(a, options?.sortByField);
131
- const keyB = _getKeyValue(b, options?.sortByField);
132
- if (keyA == null || keyB == null) return keyA == null ? 1 : -1;
133
- if (isString(keyA) && isString(keyB)) return options?.sortOrder === "desc" ? naturalSort(keyB, keyA) : naturalSort(keyA, keyB);
134
- if (isNumber(keyA) && isNumber(keyB)) return options?.sortOrder === "desc" ? keyB - keyA : keyA - keyB;
135
- if (isBoolean(keyA) && isBoolean(keyB)) return options?.sortOrder === "desc" ? Number(keyB) - Number(keyA) : Number(keyA) - Number(keyB);
136
- return 0;
137
- });
138
- return [...array];
139
- }
140
-
141
- //#endregion
142
- //#region src/utils/index.ts
143
- /**
144
- * * Deeply compare two values (arrays, objects, or primitive values).
145
- *
146
- * @param a First value to compare.
147
- * @param b Second value to compare.
148
- * @returns Whether the values are deeply equal.
149
- */
150
- const isDeepEqual = (a, b) => {
151
- if (a === b) return true;
152
- if (typeof a !== typeof b) return false;
153
- if (a === null || b === null) return a === b;
154
- if (isArray(a) && isArray(b)) {
155
- if (a?.length !== b?.length) return false;
156
- return a?.every((element, index) => isDeepEqual(element, b?.[index]));
157
- }
158
- if (isObject(a) && isObject(b)) {
159
- const aKeys = Object.keys(a);
160
- const bKeys = Object.keys(b);
161
- if (aKeys?.length !== bKeys?.length) return false;
162
- return aKeys?.every((key) => isDeepEqual(a?.[key], b?.[key]));
163
- }
164
- return false;
165
- };
166
- /**
167
- * * Converts an array of primitive values or objects to a string using a separator or target key.
168
- *
169
- * @param array Array to convert.
170
- * @param options Options for separator or key extraction from objects.
171
- * @returns String representation of array values.
172
- */
173
- function convertArrayToString(array, options) {
174
- if (!isValidArray(array)) return "";
175
- const { separator = ", " } = options ?? {};
176
- if (isArrayOfType(array, isPrimitive)) return array?.join(separator);
177
- else if (isArrayOfType(array, isNotEmptyObject)) if (options && "target" in options) return array?.map((el) => _resolveNestedKey(el, options?.target))?.join(separator);
178
- else return "";
179
- return "";
180
- }
181
- /**
182
- * * A generic debounce function that delays the execution of a callback.
183
- *
184
- * @param callback - The function to debounce.
185
- * @param delay - The delay in milliseconds. Default is `300ms`.
186
- * @returns A debounced version of the callback function.
187
- *
188
- * @example
189
- * const debouncedSearch = debounceAction((query: string) => {
190
- * console.log(`Searching for: ${query}`);
191
- * }, 300);
192
- *
193
- * debouncedSearch('laptop'); // Executes after 300ms of inactivity.
194
- */
195
- function debounceAction(callback, delay = 300) {
196
- let timeoutId;
197
- return (...args) => {
198
- clearTimeout(timeoutId);
199
- timeoutId = setTimeout(() => {
200
- callback(...args);
201
- }, delay);
202
- };
203
- }
204
- /**
205
- * * A generic throttle function that ensures a callback is executed at most once per specified interval.
206
- *
207
- * @param callback - The function to throttle.
208
- * @param delay - The delay in milliseconds. Default is `150ms`.
209
- * @returns A throttled version of the callback function.
210
- *
211
- * @example
212
- * const throttledResize = throttleAction(() => {
213
- * console.log('Resized');
214
- * }, 300);
215
- *
216
- * window.addEventListener('resize', throttledResize);
217
- */
218
- function throttleAction(callback, delay = 150) {
219
- let lastCall = 0;
220
- return (...args) => {
221
- const now = Date.now();
222
- if (now - lastCall >= delay) {
223
- lastCall = now;
224
- callback(...args);
225
- }
226
- };
227
- }
228
- /**
229
- * * Retrieves the names of all instance methods defined directly on a class prototype.
230
- *
231
- * @param cls - The class constructor (not an instance).
232
- * @returns A sorted array of instance method names.
233
- */
234
- function getInstanceMethodNames(cls) {
235
- const prototype = cls.prototype;
236
- return sortAnArray(Object.getOwnPropertyNames(prototype).filter((method) => {
237
- if (method === "constructor") return false;
238
- return isMethodDescriptor(Object.getOwnPropertyDescriptor(prototype, method));
239
- }));
240
- }
241
- /**
242
- * * Retrieves the names of all static methods defined directly on a class constructor.
243
- *
244
- * @param cls - The class constructor (not an instance).
245
- * @returns A sorted array of static method names.
246
- */
247
- function getStaticMethodNames(cls) {
248
- return sortAnArray(Object.getOwnPropertyNames(cls).filter((method) => {
249
- return method !== "prototype" && method !== "name" && method !== "length";
250
- }));
251
- }
252
- /**
253
- * * Counts the number of instance methods defined directly on a class prototype.
254
- *
255
- * @param cls - The class constructor (not an instance).
256
- * @returns The number of instance methods defined on the class prototype.
257
- */
258
- function countInstanceMethods(cls) {
259
- return getInstanceMethodNames(cls)?.length;
260
- }
261
- /**
262
- * * Counts the number of static methods defined directly on a class constructor.
263
- *
264
- * @param cls - The class constructor (not an instance).
265
- * @returns The number of static methods defined on the class constructor.
266
- */
267
- function countStaticMethods(cls) {
268
- return getStaticMethodNames(cls)?.length;
269
- }
270
- /**
271
- * * Retrieves the names of all instance getters defined directly on a class prototype.
272
- *
273
- * @param cls - The class constructor (not an instance).
274
- * @returns A sorted array of instance getter names.
275
- */
276
- function getInstanceGetterNames(cls) {
277
- const descriptors = Object.getOwnPropertyDescriptors(cls.prototype);
278
- return sortAnArray(Object.entries(descriptors).filter(([key, desc]) => typeof desc.get === "function" && key !== "constructor").map(([key]) => key));
279
- }
280
- /**
281
- * * Retrieves the names of all static getters defined directly on a class constructor.
282
- *
283
- * @param cls - The class constructor (not an instance).
284
- * @returns A sorted array of static getter names.
285
- */
286
- function getStaticGetterNames(cls) {
287
- return sortAnArray(Object.entries(Object.getOwnPropertyDescriptors(cls)).filter(([key, desc]) => typeof desc.get === "function" && key !== "prototype").map(([key]) => key));
288
- }
289
- /**
290
- * * Gathers detailed information about the instance and static methods of a class.
291
- *
292
- * @param cls - The class constructor (not an instance).
293
- * @returns An object containing names and counts of instance and static methods.
294
- */
295
- function getClassDetails(cls) {
296
- const instanceNames = getInstanceMethodNames(cls);
297
- const staticNames = getStaticMethodNames(cls);
298
- const instanceGetters = getInstanceGetterNames(cls);
299
- const staticGetters = getStaticGetterNames(cls);
300
- return {
301
- instanceMethods: instanceNames,
302
- staticMethods: staticNames,
303
- instanceGetters,
304
- staticGetters,
305
- instanceCount: instanceNames?.length,
306
- staticCount: staticNames?.length,
307
- totalGetters: instanceGetters?.length + staticGetters?.length,
308
- totalMethods: instanceNames?.length + staticNames?.length
309
- };
310
- }
311
- /**
312
- * * Create a deterministic JSON string representation of any value.
313
- * - The output format matches standard JSON but with guaranteed sorted keys.
314
- *
315
- * @remarks
316
- * - This function guarantees **stable, repeatable output** by:
317
- * - Sorting all object keys alphabetically.
318
- * - Recursively stabilizing nested objects and arrays.
319
- * - Converting all `undefined` values into `null` so the output remains valid JSON.
320
- * - Converting date-like objects (`Date`, `Chronos`, `Moment.js`, `Day.js`, `Luxon`, `JS-Joda`, `Temporal`) **in the same way that {@link JSON.stringify} would serialize them**, ensuring predictable and JSON-compliant output.
321
- * - Falling back to native JSON serialization for primitives.
322
- *
323
- * - **Useful for:**
324
- * - Hash generation (e.g., signatures, cache keys)
325
- * - Deep equality checks
326
- * - Producing predictable output across environments
327
- *
328
- * @param obj - The value to stringify into a deterministic JSON string.
329
- * @returns A stable, deterministic string representation of the input.
330
- */
331
- function stableStringify(obj) {
332
- const _replacer = (_, v) => v === void 0 ? null : v;
333
- if (isNotEmptyObject(obj)) return "{" + Object.keys(obj).sort().map((k) => JSON.stringify(k, _replacer) + ":" + (isDateLike(obj[k]) ? JSON.stringify(obj[k]) : stableStringify(obj[k]))).join(",") + "}";
334
- if (isValidArray(obj)) return "[" + obj.map((v) => stableStringify(v)).join(",") + "]";
335
- return JSON.stringify(obj, _replacer);
336
- }
337
- /**
338
- * * Remove trailing or leading garbage characters **after/before JSON object or array**.
339
- * @param str String to sanitize/strip.
340
- * @returns Sanitized/stripped JSON string.
341
- */
342
- function stripJsonEdgeGarbage(str) {
343
- if (!isNonEmptyString(str)) return "";
344
- const lastIdx = Math.max(str.lastIndexOf("}"), str.lastIndexOf("]"));
345
- const _idxOf = (sym) => str.indexOf(sym) !== -1 ? str.indexOf(sym) : Infinity;
346
- const firstIdx = Math.min(_idxOf("{"), _idxOf("["));
347
- if (lastIdx === -1 || firstIdx === Infinity) return str;
348
- return str.slice(firstIdx, lastIdx + 1);
349
- }
350
- /**
351
- * * Parses any valid JSON string, optionally converting stringified primitives inside (nested) arrays or objects.
352
- *
353
- * @typeParam T - Expected return type (default is unknown).
354
- * @param value - The JSON string to parse.
355
- * @param parsePrimitives - Whether to convert stringified primitives (default: `true`).
356
- * @returns The parsed JSON value typed as `T`, or the original parsed value with optional primitive conversion.
357
- * - Returns `{}` if parsing fails, such as when the input is malformed or invalid JSON or passing single quoted string.
358
- *
359
- * - *Unlike {@link https://toolbox-x.nazmul-nhb.dev/docs/utilities/object/parseJsonToObject parseJsonToObject}, which ensures the root value is an object,
360
- * this function returns any valid JSON structure such as arrays, strings, numbers, or objects.*
361
- *
362
- * This is useful when you're not sure of the root structure of the JSON, or when you expect something other than an object.
363
- *
364
- * @see {@link https://toolbox-x.nazmul-nhb.dev/docs/utilities/object/parseJsonToObject parseJsonToObject} for strict object-only parsing.
365
- */
366
- const parseJSON = (value, parsePrimitives = true) => {
367
- try {
368
- const parsed = JSON.parse(value);
369
- return parsePrimitives ? deepParsePrimitives(parsed) : parsed;
370
- } catch {
371
- return {};
372
- }
373
- };
374
- /**
375
- * * Recursively parses primitive values inside objects and arrays.
376
- *
377
- * @typeParam T - Expected return type after parsing (default is unknown).
378
- * @param input - Any input value to parse recursively.
379
- * @returns Input with primitives (strings like "true", "123") converted, typed as `T`.
380
- */
381
- function deepParsePrimitives(input) {
382
- if (Array.isArray(input)) return input?.map(deepParsePrimitives);
383
- if (isObject(input)) {
384
- const result = {};
385
- for (const [key, value] of Object.entries(input)) result[key] = deepParsePrimitives(value);
386
- return result;
387
- }
388
- if (isString(input)) {
389
- if (/^(true|false)$/i.test(input)) return input?.toLowerCase() === "true";
390
- if (isNumericString(input)) return Number(input);
391
- if (input === "null") return null;
392
- if (input === "undefined") return;
393
- return input;
394
- }
395
- return input;
396
- }
397
- /**
398
- * * Defines a method on any prototype — including built-in prototypes — in a safe, idempotent manner.
399
- * - The method is non-enumerable by default and will not overwrite an existing method unless explicitly allowed.
400
- *
401
- * @param proto The target prototype object (e.g., String.prototype).
402
- * @param name The method name to define on the prototype.
403
- * @param impl The function implementation for the method.
404
- * @param options Optional property-descriptor settings and overwrite rules.
405
- *
406
- * @example
407
- * // Safely augment prototype methods by extending the global interface:
408
- * declare global {
409
- * interface String {
410
- * toBang(): string;
411
- * }
412
- * }
413
- *
414
- * // Define a custom method on String.prototype
415
- * definePrototypeMethod(String.prototype, 'toBang', function (this: String) {
416
- * return this.toString().concat('!');
417
- * // or
418
- * // return this.concat('!');
419
- * });
420
- *
421
- * "Hi".toBang(); // "Hi!"
422
- *
423
- * // Attempting to redefine without overwrite option is ignored
424
- * definePrototypeMethod(String.prototype, 'toBang', () => 'x'); // ignored
425
- *
426
- * // Overwrite intentionally using the overwrite option
427
- * definePrototypeMethod(
428
- * String.prototype,
429
- * 'toBang',
430
- * function (this: String) { return this.concat('!!!'); },
431
- * { overwrite: true }
432
- * );
433
- *
434
- * "Hi".toBang(); // "Hi!!!"
435
- */
436
- function definePrototypeMethod(proto, name, impl, options) {
437
- if (Object.hasOwn(proto, name) && !options?.overwrite) return;
438
- Object.defineProperty(proto, name, {
439
- value: function(...args) {
440
- return impl.apply(this, args);
441
- },
442
- enumerable: options?.enumerable ?? false,
443
- configurable: options?.configurable ?? false,
444
- writable: options?.writable ?? true
445
- });
446
- }
447
-
448
- //#endregion
449
- export { naturalSort as _, deepParsePrimitives as a, _resolveNestedKey as b, getInstanceGetterNames as c, getStaticMethodNames as d, isDeepEqual as f, throttleAction as g, stripJsonEdgeGarbage as h, debounceAction as i, getInstanceMethodNames as l, stableStringify as m, countInstanceMethods as n, definePrototypeMethod as o, parseJSON as p, countStaticMethods as r, getClassDetails as s, convertArrayToString as t, getStaticGetterNames as u, sortAnArray as v, _getNumericProp as y };