utilitify-core 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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +338 -0
  3. package/dist/async.cjs +25 -0
  4. package/dist/async.cjs.map +1 -0
  5. package/dist/async.d.cts +104 -0
  6. package/dist/async.d.ts +104 -0
  7. package/dist/async.js +4 -0
  8. package/dist/async.js.map +1 -0
  9. package/dist/chunk-2ICNRTSN.cjs +346 -0
  10. package/dist/chunk-2ICNRTSN.cjs.map +1 -0
  11. package/dist/chunk-3DPF72DY.js +170 -0
  12. package/dist/chunk-3DPF72DY.js.map +1 -0
  13. package/dist/chunk-4CV4JOE5.js +24 -0
  14. package/dist/chunk-4CV4JOE5.js.map +1 -0
  15. package/dist/chunk-4SLYNSLH.cjs +783 -0
  16. package/dist/chunk-4SLYNSLH.cjs.map +1 -0
  17. package/dist/chunk-5WP7DWCG.js +1285 -0
  18. package/dist/chunk-5WP7DWCG.js.map +1 -0
  19. package/dist/chunk-BMQ6YPKV.js +876 -0
  20. package/dist/chunk-BMQ6YPKV.js.map +1 -0
  21. package/dist/chunk-BZCMWUKS.cjs +479 -0
  22. package/dist/chunk-BZCMWUKS.cjs.map +1 -0
  23. package/dist/chunk-C5R744DY.cjs +173 -0
  24. package/dist/chunk-C5R744DY.cjs.map +1 -0
  25. package/dist/chunk-C75J62CV.cjs +913 -0
  26. package/dist/chunk-C75J62CV.cjs.map +1 -0
  27. package/dist/chunk-CZLDE2OZ.cjs +28 -0
  28. package/dist/chunk-CZLDE2OZ.cjs.map +1 -0
  29. package/dist/chunk-DSMB6AF6.cjs +193 -0
  30. package/dist/chunk-DSMB6AF6.cjs.map +1 -0
  31. package/dist/chunk-ETWGPOPY.js +426 -0
  32. package/dist/chunk-ETWGPOPY.js.map +1 -0
  33. package/dist/chunk-FQBPVN63.cjs +403 -0
  34. package/dist/chunk-FQBPVN63.cjs.map +1 -0
  35. package/dist/chunk-G4GYQGTW.cjs +178 -0
  36. package/dist/chunk-G4GYQGTW.cjs.map +1 -0
  37. package/dist/chunk-GFDMZDMI.js +486 -0
  38. package/dist/chunk-GFDMZDMI.js.map +1 -0
  39. package/dist/chunk-HOTOYIPB.js +171 -0
  40. package/dist/chunk-HOTOYIPB.js.map +1 -0
  41. package/dist/chunk-HYADH4ZX.js +176 -0
  42. package/dist/chunk-HYADH4ZX.js.map +1 -0
  43. package/dist/chunk-JBN7C5WE.js +255 -0
  44. package/dist/chunk-JBN7C5WE.js.map +1 -0
  45. package/dist/chunk-JNCTPFTD.cjs +25 -0
  46. package/dist/chunk-JNCTPFTD.cjs.map +1 -0
  47. package/dist/chunk-N3BH3BV7.js +21 -0
  48. package/dist/chunk-N3BH3BV7.js.map +1 -0
  49. package/dist/chunk-NFPGAVRQ.js +749 -0
  50. package/dist/chunk-NFPGAVRQ.js.map +1 -0
  51. package/dist/chunk-OFFRGRBN.cjs +1332 -0
  52. package/dist/chunk-OFFRGRBN.cjs.map +1 -0
  53. package/dist/chunk-OZLKYIZL.cjs +490 -0
  54. package/dist/chunk-OZLKYIZL.cjs.map +1 -0
  55. package/dist/chunk-P3NUK46X.js +145 -0
  56. package/dist/chunk-P3NUK46X.js.map +1 -0
  57. package/dist/chunk-P7P2B7ZI.cjs +429 -0
  58. package/dist/chunk-P7P2B7ZI.cjs.map +1 -0
  59. package/dist/chunk-PB6SKSJN.cjs +150 -0
  60. package/dist/chunk-PB6SKSJN.cjs.map +1 -0
  61. package/dist/chunk-R3IXCJR7.js +378 -0
  62. package/dist/chunk-R3IXCJR7.js.map +1 -0
  63. package/dist/chunk-SD6P3WEJ.js +324 -0
  64. package/dist/chunk-SD6P3WEJ.js.map +1 -0
  65. package/dist/chunk-YSCHP26P.js +451 -0
  66. package/dist/chunk-YSCHP26P.js.map +1 -0
  67. package/dist/chunk-ZLMPRPCY.cjs +274 -0
  68. package/dist/chunk-ZLMPRPCY.cjs.map +1 -0
  69. package/dist/common-CBDYNJeh.d.cts +48 -0
  70. package/dist/common-CBDYNJeh.d.ts +48 -0
  71. package/dist/constants.cjs +42 -0
  72. package/dist/constants.cjs.map +1 -0
  73. package/dist/constants.d.cts +60 -0
  74. package/dist/constants.d.ts +60 -0
  75. package/dist/constants.js +5 -0
  76. package/dist/constants.js.map +1 -0
  77. package/dist/country/index.cjs +154 -0
  78. package/dist/country/index.cjs.map +1 -0
  79. package/dist/country/index.d.cts +1 -0
  80. package/dist/country/index.d.ts +1 -0
  81. package/dist/country/index.js +5 -0
  82. package/dist/country/index.js.map +1 -0
  83. package/dist/date/index.cjs +117 -0
  84. package/dist/date/index.cjs.map +1 -0
  85. package/dist/date/index.d.cts +283 -0
  86. package/dist/date/index.d.ts +283 -0
  87. package/dist/date/index.js +4 -0
  88. package/dist/date/index.js.map +1 -0
  89. package/dist/environment/index.cjs +73 -0
  90. package/dist/environment/index.cjs.map +1 -0
  91. package/dist/environment/index.d.cts +127 -0
  92. package/dist/environment/index.d.ts +127 -0
  93. package/dist/environment/index.js +4 -0
  94. package/dist/environment/index.js.map +1 -0
  95. package/dist/form/index.cjs +81 -0
  96. package/dist/form/index.cjs.map +1 -0
  97. package/dist/form/index.d.cts +227 -0
  98. package/dist/form/index.d.ts +227 -0
  99. package/dist/form/index.js +4 -0
  100. package/dist/form/index.js.map +1 -0
  101. package/dist/i18n.cjs +37 -0
  102. package/dist/i18n.cjs.map +1 -0
  103. package/dist/i18n.d.cts +102 -0
  104. package/dist/i18n.d.ts +102 -0
  105. package/dist/i18n.js +4 -0
  106. package/dist/i18n.js.map +1 -0
  107. package/dist/index-BXBmBHyL.d.ts +718 -0
  108. package/dist/index-BYsUCP3u.d.cts +718 -0
  109. package/dist/index-Cl26FrAZ.d.cts +362 -0
  110. package/dist/index-Cl26FrAZ.d.ts +362 -0
  111. package/dist/index.cjs +1265 -0
  112. package/dist/index.cjs.map +1 -0
  113. package/dist/index.d.cts +205 -0
  114. package/dist/index.d.ts +205 -0
  115. package/dist/index.js +277 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/schema.cjs +13 -0
  118. package/dist/schema.cjs.map +1 -0
  119. package/dist/schema.d.cts +84 -0
  120. package/dist/schema.d.ts +84 -0
  121. package/dist/schema.js +4 -0
  122. package/dist/schema.js.map +1 -0
  123. package/dist/security/index.cjs +94 -0
  124. package/dist/security/index.cjs.map +1 -0
  125. package/dist/security/index.d.cts +216 -0
  126. package/dist/security/index.d.ts +216 -0
  127. package/dist/security/index.js +5 -0
  128. package/dist/security/index.js.map +1 -0
  129. package/dist/string/index.cjs +153 -0
  130. package/dist/string/index.cjs.map +1 -0
  131. package/dist/string/index.d.cts +471 -0
  132. package/dist/string/index.d.ts +471 -0
  133. package/dist/string/index.js +4 -0
  134. package/dist/string/index.js.map +1 -0
  135. package/dist/transform/index.cjs +105 -0
  136. package/dist/transform/index.cjs.map +1 -0
  137. package/dist/transform/index.d.cts +271 -0
  138. package/dist/transform/index.d.ts +271 -0
  139. package/dist/transform/index.js +4 -0
  140. package/dist/transform/index.js.map +1 -0
  141. package/dist/validators/index.cjs +195 -0
  142. package/dist/validators/index.cjs.map +1 -0
  143. package/dist/validators/index.d.cts +2 -0
  144. package/dist/validators/index.d.ts +2 -0
  145. package/dist/validators/index.js +6 -0
  146. package/dist/validators/index.js.map +1 -0
  147. package/package.json +229 -0
@@ -0,0 +1,876 @@
1
+ // src/string/case.ts
2
+ function toCamelCase(str) {
3
+ if (!str || typeof str !== "string") return "";
4
+ const normalized = /^[A-Z_\s-]+$/.test(str.trim()) ? str.toLowerCase() : str;
5
+ return normalized.trim().replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^[A-Z]/, (char) => char.toLowerCase());
6
+ }
7
+ function toPascalCase(str) {
8
+ if (!str || typeof str !== "string") return "";
9
+ const camel = toCamelCase(str);
10
+ return camel.charAt(0).toUpperCase() + camel.slice(1);
11
+ }
12
+ function toSnakeCase(str) {
13
+ if (!str || typeof str !== "string") return "";
14
+ return str.trim().replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase();
15
+ }
16
+ function toKebabCase(str) {
17
+ if (!str || typeof str !== "string") return "";
18
+ return str.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[_\s]+/g, "-").toLowerCase();
19
+ }
20
+ function toTitleCase(str) {
21
+ if (!str || typeof str !== "string") return "";
22
+ const smallWords = /* @__PURE__ */ new Set([
23
+ "a",
24
+ "an",
25
+ "and",
26
+ "as",
27
+ "at",
28
+ "but",
29
+ "by",
30
+ "for",
31
+ "in",
32
+ "nor",
33
+ "of",
34
+ "on",
35
+ "or",
36
+ "so",
37
+ "the",
38
+ "to",
39
+ "up",
40
+ "yet"
41
+ ]);
42
+ return str.toLowerCase().split(/\s+/).map((word, index) => {
43
+ if (index === 0) {
44
+ return word.charAt(0).toUpperCase() + word.slice(1);
45
+ }
46
+ if (smallWords.has(word)) {
47
+ return word;
48
+ }
49
+ return word.charAt(0).toUpperCase() + word.slice(1);
50
+ }).join(" ");
51
+ }
52
+ function toConstantCase(str) {
53
+ if (!str || typeof str !== "string") return "";
54
+ return toSnakeCase(str).toUpperCase();
55
+ }
56
+ function toSentenceCase(str) {
57
+ if (!str || typeof str !== "string") return "";
58
+ const lower = str.toLowerCase().trim();
59
+ return lower.charAt(0).toUpperCase() + lower.slice(1);
60
+ }
61
+ function toDotCase(str) {
62
+ if (!str || typeof str !== "string") return "";
63
+ return str.trim().replace(/([a-z])([A-Z])/g, "$1.$2").replace(/[-_\s]+/g, ".").toLowerCase();
64
+ }
65
+ function capitalize(str) {
66
+ if (!str || typeof str !== "string") return "";
67
+ return str.charAt(0).toUpperCase() + str.slice(1);
68
+ }
69
+ function uncapitalize(str) {
70
+ if (!str || typeof str !== "string") return "";
71
+ return str.charAt(0).toLowerCase() + str.slice(1);
72
+ }
73
+ function swapCase(str) {
74
+ if (!str || typeof str !== "string") return "";
75
+ return [...str].map((char) => {
76
+ if (char === char.toUpperCase()) {
77
+ return char.toLowerCase();
78
+ }
79
+ return char.toUpperCase();
80
+ }).join("");
81
+ }
82
+
83
+ // src/string/slug.ts
84
+ var TRANSLITERATION_MAP = {
85
+ // Latin Extended
86
+ "à": "a",
87
+ "á": "a",
88
+ "â": "a",
89
+ "ã": "a",
90
+ "ä": "a",
91
+ "å": "a",
92
+ "æ": "ae",
93
+ "ç": "c",
94
+ "è": "e",
95
+ "é": "e",
96
+ "ê": "e",
97
+ "ë": "e",
98
+ "ì": "i",
99
+ "í": "i",
100
+ "î": "i",
101
+ "ï": "i",
102
+ "ð": "d",
103
+ "ñ": "n",
104
+ "ò": "o",
105
+ "ó": "o",
106
+ "ô": "o",
107
+ "õ": "o",
108
+ "ö": "o",
109
+ "ø": "o",
110
+ "ù": "u",
111
+ "ú": "u",
112
+ "û": "u",
113
+ "ü": "u",
114
+ "ý": "y",
115
+ "ÿ": "y",
116
+ "þ": "th",
117
+ "ß": "ss",
118
+ // Polish
119
+ "ą": "a",
120
+ "ć": "c",
121
+ "ę": "e",
122
+ "ł": "l",
123
+ "ń": "n",
124
+ "ś": "s",
125
+ "ź": "z",
126
+ "ż": "z",
127
+ // Czech/Slovak
128
+ "č": "c",
129
+ "ď": "d",
130
+ "ě": "e",
131
+ "ň": "n",
132
+ "ř": "r",
133
+ "š": "s",
134
+ "ť": "t",
135
+ "ů": "u",
136
+ "ž": "z",
137
+ // German
138
+ "Ä": "Ae",
139
+ "Ö": "Oe",
140
+ "Ü": "Ue",
141
+ // Turkish
142
+ "ğ": "g",
143
+ "ı": "i",
144
+ "ş": "s",
145
+ // Romanian
146
+ "ă": "a",
147
+ "ș": "s",
148
+ "ț": "t",
149
+ // Symbols
150
+ "©": "c",
151
+ "®": "r",
152
+ "™": "tm",
153
+ "&": "and",
154
+ "@": "at"
155
+ };
156
+ var STOP_WORDS = /* @__PURE__ */ new Set([
157
+ "a",
158
+ "an",
159
+ "and",
160
+ "are",
161
+ "as",
162
+ "at",
163
+ "be",
164
+ "by",
165
+ "for",
166
+ "from",
167
+ "has",
168
+ "he",
169
+ "in",
170
+ "is",
171
+ "it",
172
+ "its",
173
+ "of",
174
+ "on",
175
+ "that",
176
+ "the",
177
+ "to",
178
+ "was",
179
+ "were",
180
+ "will",
181
+ "with"
182
+ ]);
183
+ var DEFAULT_OPTIONS = {
184
+ lowercase: true,
185
+ separator: "-",
186
+ transliterate: true,
187
+ removeStopWords: false
188
+ };
189
+ function toSlug(str, options = {}) {
190
+ if (!str || typeof str !== "string") return "";
191
+ const opts = { ...DEFAULT_OPTIONS, ...options };
192
+ let result = str.trim();
193
+ if (opts.transliterate) {
194
+ result = transliterate(result);
195
+ }
196
+ if (opts.lowercase) {
197
+ result = result.toLowerCase();
198
+ }
199
+ if (opts.removeStopWords) {
200
+ result = result.split(/\s+/).filter((word) => !STOP_WORDS.has(word.toLowerCase())).join(" ");
201
+ }
202
+ result = result.replace(/[^\w\s-]/g, "").replace(/[\s_]+/g, opts.separator || "-").replace(new RegExp(`${opts.separator}+`, "g"), opts.separator || "-").replace(new RegExp(`^${opts.separator}|${opts.separator}$`, "g"), "");
203
+ if (opts.maxLength && result.length > opts.maxLength) {
204
+ result = result.slice(0, opts.maxLength);
205
+ const lastSep = result.lastIndexOf(opts.separator || "-");
206
+ if (lastSep > opts.maxLength * 0.5) {
207
+ result = result.slice(0, lastSep);
208
+ }
209
+ }
210
+ return result;
211
+ }
212
+ function transliterate(str) {
213
+ if (!str || typeof str !== "string") return "";
214
+ return [...str].map((char) => {
215
+ const lower = char.toLowerCase();
216
+ if (TRANSLITERATION_MAP[lower]) {
217
+ const replacement = TRANSLITERATION_MAP[lower];
218
+ if (char === char.toUpperCase()) {
219
+ return replacement.charAt(0).toUpperCase() + replacement.slice(1);
220
+ }
221
+ return replacement;
222
+ }
223
+ return char;
224
+ }).join("");
225
+ }
226
+ function slugify(str) {
227
+ return toSlug(str);
228
+ }
229
+ function uniqueSlug(str, existingSlugs, options = {}) {
230
+ const existing = existingSlugs instanceof Set ? existingSlugs : new Set(existingSlugs);
231
+ const baseSlug = toSlug(str, options);
232
+ if (!existing.has(baseSlug)) {
233
+ return baseSlug;
234
+ }
235
+ let counter = 1;
236
+ let uniqueSlugStr = `${baseSlug}${options.separator || "-"}${counter}`;
237
+ while (existing.has(uniqueSlugStr)) {
238
+ counter++;
239
+ uniqueSlugStr = `${baseSlug}${options.separator || "-"}${counter}`;
240
+ }
241
+ return uniqueSlugStr;
242
+ }
243
+ function isValidSlug(str) {
244
+ if (!str || typeof str !== "string") return false;
245
+ return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str);
246
+ }
247
+
248
+ // src/string/mask.ts
249
+ var DEFAULT_OPTIONS2 = {
250
+ maskChar: "*",
251
+ minLength: 4
252
+ };
253
+ function maskEmail(email, options = {}) {
254
+ if (!email || typeof email !== "string") return "";
255
+ const [localPart, domain] = email.split("@");
256
+ if (!localPart || !domain) return email;
257
+ const maskChar = options.maskChar || "*";
258
+ const visibleStart = options.visibleStart ?? 1;
259
+ if (localPart.length <= visibleStart) {
260
+ return `${maskChar.repeat(3)}@${domain}`;
261
+ }
262
+ const visible = localPart.slice(0, visibleStart);
263
+ const masked = maskChar.repeat(Math.min(localPart.length - visibleStart, 5));
264
+ return `${visible}${masked}@${domain}`;
265
+ }
266
+ function maskPhone(phone, options = {}) {
267
+ if (!phone || typeof phone !== "string") return "";
268
+ const maskChar = options.maskChar || "*";
269
+ const visibleStart = options.visibleStart ?? 3;
270
+ const visibleEnd = options.visibleEnd ?? 4;
271
+ const digits = phone.replace(/\D/g, "");
272
+ if (digits.length < visibleStart + visibleEnd) {
273
+ return phone;
274
+ }
275
+ let result = "";
276
+ let digitIndex = 0;
277
+ for (const char of phone) {
278
+ if (/\d/.test(char)) {
279
+ if (digitIndex < visibleStart || digitIndex >= digits.length - visibleEnd) {
280
+ result += char;
281
+ } else {
282
+ result += maskChar;
283
+ }
284
+ digitIndex++;
285
+ } else {
286
+ result += char;
287
+ }
288
+ }
289
+ return result;
290
+ }
291
+ function maskCreditCard(card, options = {}) {
292
+ if (!card || typeof card !== "string") return "";
293
+ const maskChar = options.maskChar || "*";
294
+ const visibleEnd = options.visibleEnd ?? 4;
295
+ const digits = card.replace(/\D/g, "");
296
+ if (digits.length < visibleEnd + 1) {
297
+ return card;
298
+ }
299
+ let result = "";
300
+ let digitIndex = 0;
301
+ for (const char of card) {
302
+ if (/\d/.test(char)) {
303
+ if (digitIndex >= digits.length - visibleEnd) {
304
+ result += char;
305
+ } else {
306
+ result += maskChar;
307
+ }
308
+ digitIndex++;
309
+ } else {
310
+ result += char;
311
+ }
312
+ }
313
+ return result;
314
+ }
315
+ function maskString(str, options = {}) {
316
+ if (!str || typeof str !== "string") return "";
317
+ const opts = { ...DEFAULT_OPTIONS2, ...options };
318
+ if (str.length < (opts.minLength || 4)) {
319
+ return str;
320
+ }
321
+ const visibleStart = opts.visibleStart ?? 0;
322
+ const visibleEnd = opts.visibleEnd ?? 0;
323
+ if (str.length <= visibleStart + visibleEnd) {
324
+ return str;
325
+ }
326
+ const start = str.slice(0, visibleStart);
327
+ const end = str.slice(-visibleEnd || str.length);
328
+ const maskLength = str.length - visibleStart - visibleEnd;
329
+ return `${start}${(opts.maskChar || "*").repeat(maskLength)}${visibleEnd > 0 ? end : ""}`;
330
+ }
331
+ function maskIP(ip) {
332
+ if (!ip || typeof ip !== "string") return "";
333
+ const parts = ip.split(".");
334
+ if (parts.length !== 4) return ip;
335
+ return `${parts[0]}.${parts[1]}.***.***`;
336
+ }
337
+ function maskName(name) {
338
+ if (!name || typeof name !== "string") return "";
339
+ return name.split(" ").map((part) => {
340
+ if (part.length <= 1) return part;
341
+ return part[0] + "*".repeat(Math.min(part.length - 1, 3));
342
+ }).join(" ");
343
+ }
344
+
345
+ // src/string/random.ts
346
+ var CHAR_SETS = {
347
+ uppercase: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
348
+ uppercaseUnambiguous: "ABCDEFGHJKLMNPQRSTUVWXYZ",
349
+ lowercase: "abcdefghijklmnopqrstuvwxyz",
350
+ lowercaseUnambiguous: "abcdefghjkmnpqrstuvwxyz",
351
+ numbers: "0123456789",
352
+ numbersUnambiguous: "23456789",
353
+ symbols: "!@#$%^&*()_+-=[]{}|;:,.<>?"
354
+ };
355
+ var DEFAULT_PASSWORD_OPTIONS = {
356
+ length: 16,
357
+ uppercase: true,
358
+ lowercase: true,
359
+ numbers: true,
360
+ symbols: true,
361
+ excludeAmbiguous: false,
362
+ minOfEachType: 1
363
+ };
364
+ function generatePassword(options = {}) {
365
+ const opts = { ...DEFAULT_PASSWORD_OPTIONS, ...options };
366
+ const length = Math.max(4, opts.length || 16);
367
+ let charset = "";
368
+ const requiredChars = [];
369
+ if (opts.uppercase) {
370
+ const chars = opts.excludeAmbiguous ? CHAR_SETS.uppercaseUnambiguous : CHAR_SETS.uppercase;
371
+ charset += chars;
372
+ for (let i = 0; i < (opts.minOfEachType || 1); i++) {
373
+ requiredChars.push(getRandomChar(chars));
374
+ }
375
+ }
376
+ if (opts.lowercase) {
377
+ const chars = opts.excludeAmbiguous ? CHAR_SETS.lowercaseUnambiguous : CHAR_SETS.lowercase;
378
+ charset += chars;
379
+ for (let i = 0; i < (opts.minOfEachType || 1); i++) {
380
+ requiredChars.push(getRandomChar(chars));
381
+ }
382
+ }
383
+ if (opts.numbers) {
384
+ const chars = opts.excludeAmbiguous ? CHAR_SETS.numbersUnambiguous : CHAR_SETS.numbers;
385
+ charset += chars;
386
+ for (let i = 0; i < (opts.minOfEachType || 1); i++) {
387
+ requiredChars.push(getRandomChar(chars));
388
+ }
389
+ }
390
+ if (opts.symbols) {
391
+ charset += CHAR_SETS.symbols;
392
+ for (let i = 0; i < (opts.minOfEachType || 1); i++) {
393
+ requiredChars.push(getRandomChar(CHAR_SETS.symbols));
394
+ }
395
+ }
396
+ if (opts.customChars) {
397
+ charset += opts.customChars;
398
+ }
399
+ if (!charset) {
400
+ charset = CHAR_SETS.lowercase + CHAR_SETS.numbers;
401
+ }
402
+ const passwordChars = [...requiredChars];
403
+ while (passwordChars.length < length) {
404
+ passwordChars.push(getRandomChar(charset));
405
+ }
406
+ if (passwordChars.length > length) {
407
+ passwordChars.length = length;
408
+ }
409
+ return shuffleArray(passwordChars).join("");
410
+ }
411
+ function generateRandomString(length = 16, charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
412
+ if (length <= 0) return "";
413
+ if (!charset) charset = "abcdefghijklmnopqrstuvwxyz0123456789";
414
+ let result = "";
415
+ for (let i = 0; i < length; i++) {
416
+ result += getRandomChar(charset);
417
+ }
418
+ return result;
419
+ }
420
+ function generateOTP(length = 6) {
421
+ return generateRandomString(length, "0123456789");
422
+ }
423
+ function generatePassphrase(wordCount = 4, separator = "-") {
424
+ const words = [
425
+ // Nature & Weather (32)
426
+ "apple",
427
+ "banana",
428
+ "cherry",
429
+ "dragon",
430
+ "eagle",
431
+ "forest",
432
+ "garden",
433
+ "harbor",
434
+ "island",
435
+ "jungle",
436
+ "kitten",
437
+ "lemon",
438
+ "mountain",
439
+ "nature",
440
+ "ocean",
441
+ "planet",
442
+ "river",
443
+ "sunset",
444
+ "thunder",
445
+ "umbrella",
446
+ "violet",
447
+ "window",
448
+ "yellow",
449
+ "zebra",
450
+ "anchor",
451
+ "bridge",
452
+ "castle",
453
+ "dolphin",
454
+ "ember",
455
+ "falcon",
456
+ "glacier",
457
+ "horizon",
458
+ // Objects & Places (32)
459
+ "ivory",
460
+ "jasmine",
461
+ "kingdom",
462
+ "lantern",
463
+ "meadow",
464
+ "nebula",
465
+ "orchid",
466
+ "phoenix",
467
+ "quartz",
468
+ "rainbow",
469
+ "shadow",
470
+ "tornado",
471
+ "unicorn",
472
+ "volcano",
473
+ "whisper",
474
+ "crystal",
475
+ "diamond",
476
+ "eclipse",
477
+ "feather",
478
+ "granite",
479
+ "helmet",
480
+ "jigsaw",
481
+ "kayak",
482
+ "ladder",
483
+ "magnet",
484
+ "needle",
485
+ "orange",
486
+ "panther",
487
+ "puzzle",
488
+ "rabbit",
489
+ "saddle",
490
+ "tablet",
491
+ // Actions & Concepts (32)
492
+ "beacon",
493
+ "candle",
494
+ "dancer",
495
+ "flight",
496
+ "golden",
497
+ "hunter",
498
+ "insect",
499
+ "jacket",
500
+ "keeper",
501
+ "leader",
502
+ "master",
503
+ "native",
504
+ "offset",
505
+ "parade",
506
+ "radius",
507
+ "sailor",
508
+ "target",
509
+ "uplift",
510
+ "vector",
511
+ "walker",
512
+ "zenith",
513
+ "arctic",
514
+ "basket",
515
+ "camera",
516
+ "dinner",
517
+ "escape",
518
+ "finger",
519
+ "guitar",
520
+ "hammer",
521
+ "ignite",
522
+ "jacket",
523
+ "kernel",
524
+ // Animals (32)
525
+ "lizard",
526
+ "monkey",
527
+ "narwhal",
528
+ "oyster",
529
+ "parrot",
530
+ "quiver",
531
+ "racoon",
532
+ "salmon",
533
+ "turtle",
534
+ "urchin",
535
+ "viking",
536
+ "walrus",
537
+ "jaguar",
538
+ "badger",
539
+ "condor",
540
+ "donkey",
541
+ "ferret",
542
+ "gopher",
543
+ "hornet",
544
+ "iguana",
545
+ "jackal",
546
+ "kitten",
547
+ "llama",
548
+ "marmot",
549
+ "newt",
550
+ "osprey",
551
+ "panda",
552
+ "quail",
553
+ "raven",
554
+ "spider",
555
+ "toucan",
556
+ "vampire",
557
+ // Food & Drinks (32)
558
+ "waffle",
559
+ "yogurt",
560
+ "almond",
561
+ "butter",
562
+ "celery",
563
+ "donut",
564
+ "endive",
565
+ "fennel",
566
+ "ginger",
567
+ "hazel",
568
+ "icecap",
569
+ "jelly",
570
+ "kimchi",
571
+ "lentil",
572
+ "mango",
573
+ "noodle",
574
+ "olive",
575
+ "papaya",
576
+ "quinoa",
577
+ "radish",
578
+ "sesame",
579
+ "tomato",
580
+ "umami",
581
+ "vanilla",
582
+ "wasabi",
583
+ "xylose",
584
+ "yeast",
585
+ "zephyr",
586
+ "acorn",
587
+ "breeze",
588
+ "clover",
589
+ "dahlia",
590
+ // Colors & Materials (32)
591
+ "silver",
592
+ "bronze",
593
+ "copper",
594
+ "purple",
595
+ "maroon",
596
+ "indigo",
597
+ "scarlet",
598
+ "crimson",
599
+ "velvet",
600
+ "cotton",
601
+ "denim",
602
+ "linen",
603
+ "marble",
604
+ "bamboo",
605
+ "cedar",
606
+ "maple",
607
+ "willow",
608
+ "birch",
609
+ "coral",
610
+ "pearl",
611
+ "amber",
612
+ "topaz",
613
+ "garnet",
614
+ "onyx",
615
+ "jasper",
616
+ "opal",
617
+ "ruby",
618
+ "sapphire",
619
+ "cobalt",
620
+ "chrome",
621
+ "steel",
622
+ "brass",
623
+ // Technology & Science (32)
624
+ "binary",
625
+ "cipher",
626
+ "domain",
627
+ "engine",
628
+ "filter",
629
+ "gadget",
630
+ "hybrid",
631
+ "index",
632
+ "joystick",
633
+ "kernel",
634
+ "lambda",
635
+ "module",
636
+ "neural",
637
+ "output",
638
+ "pixel",
639
+ "quantum",
640
+ "router",
641
+ "sensor",
642
+ "toggle",
643
+ "upload",
644
+ "vertex",
645
+ "widget",
646
+ "system",
647
+ "crypto",
648
+ "buffer",
649
+ "cache",
650
+ "delta",
651
+ "epoch",
652
+ "format",
653
+ "global",
654
+ "header",
655
+ "input",
656
+ // Misc & Abstract (32)
657
+ "action",
658
+ "balance",
659
+ "center",
660
+ "design",
661
+ "energy",
662
+ "focus",
663
+ "growth",
664
+ "health",
665
+ "impact",
666
+ "justice",
667
+ "knight",
668
+ "legacy",
669
+ "motion",
670
+ "nexus",
671
+ "origin",
672
+ "prime",
673
+ "quest",
674
+ "reward",
675
+ "spirit",
676
+ "talent",
677
+ "unity",
678
+ "vision",
679
+ "wisdom",
680
+ "expert",
681
+ "factor",
682
+ "giant",
683
+ "humble",
684
+ "jovial",
685
+ "kinetic",
686
+ "lunar",
687
+ "metric",
688
+ "novel"
689
+ ];
690
+ const result = [];
691
+ for (let i = 0; i < wordCount; i++) {
692
+ result.push(words[getSecureRandomIndex(words.length)]);
693
+ }
694
+ return result.join(separator);
695
+ }
696
+ function generateHexString(length = 16) {
697
+ return generateRandomString(length * 2, "0123456789abcdef");
698
+ }
699
+ function generateBase64String(length = 16) {
700
+ const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
701
+ return generateRandomString(length, charset);
702
+ }
703
+ function generateUrlSafeString(length = 16) {
704
+ const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
705
+ return generateRandomString(length, charset);
706
+ }
707
+ function getSecureRandomIndex(max) {
708
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
709
+ const array = new Uint32Array(1);
710
+ globalThis.crypto.getRandomValues(array);
711
+ return array[0] % max;
712
+ }
713
+ const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
714
+ if (isProduction) {
715
+ throw new Error(
716
+ "[utilitify] Web Crypto API not available. Cannot generate secure random values in production. Ensure you are running in an environment with crypto support (Node.js 15+, modern browsers)."
717
+ );
718
+ }
719
+ console.warn(
720
+ "[utilitify] Using Math.random() fallback - NOT CRYPTOGRAPHICALLY SECURE. This is only acceptable for development/testing. Install with crypto support for production."
721
+ );
722
+ return Math.floor(Math.random() * max);
723
+ }
724
+ function getRandomChar(charset) {
725
+ return charset[getSecureRandomIndex(charset.length)];
726
+ }
727
+ function shuffleArray(array) {
728
+ const result = [...array];
729
+ for (let i = result.length - 1; i > 0; i--) {
730
+ const j = getSecureRandomIndex(i + 1);
731
+ [result[i], result[j]] = [result[j], result[i]];
732
+ }
733
+ return result;
734
+ }
735
+
736
+ // src/string/truncate.ts
737
+ var DEFAULT_OPTIONS3 = {
738
+ suffix: "...",
739
+ preserveWords: true,
740
+ position: "end",
741
+ graphemeAware: false
742
+ };
743
+ function truncate(str, length, options = {}) {
744
+ if (!str || typeof str !== "string") return "";
745
+ if (length < 0) {
746
+ throw new RangeError("maxLength must be a non-negative number");
747
+ }
748
+ if (length === 0) return "";
749
+ const opts = { ...DEFAULT_OPTIONS3, ...options };
750
+ const suffix = opts.suffix ?? "...";
751
+ const strLength = opts.graphemeAware ? getGraphemeLength(str) : str.length;
752
+ if (strLength <= length) return str;
753
+ const maxContentLength = length - (opts.graphemeAware ? getGraphemeLength(suffix) : suffix.length);
754
+ if (maxContentLength <= 0) {
755
+ return opts.graphemeAware ? sliceGraphemes(suffix, 0, length) : suffix.slice(0, length);
756
+ }
757
+ switch (opts.position) {
758
+ case "start":
759
+ return opts.graphemeAware ? truncateStartGrapheme(str, maxContentLength, suffix) : truncateStart(str, maxContentLength, suffix);
760
+ case "middle":
761
+ return opts.graphemeAware ? truncateMiddleGrapheme(str, length, suffix) : truncateMiddle(str, length, suffix);
762
+ default:
763
+ return opts.graphemeAware ? truncateEndGrapheme(str, maxContentLength, suffix, opts.preserveWords ?? true) : truncateEnd(str, maxContentLength, suffix, opts.preserveWords ?? true);
764
+ }
765
+ }
766
+ function truncateEnd(str, maxContentLength, suffix, preserveWords) {
767
+ let truncated = str.slice(0, maxContentLength);
768
+ if (preserveWords) {
769
+ const lastSpace = truncated.lastIndexOf(" ");
770
+ if (lastSpace > maxContentLength * 0.3) {
771
+ truncated = truncated.slice(0, lastSpace);
772
+ }
773
+ }
774
+ truncated = truncated.replace(/[\s.,!?;:]+$/, "");
775
+ return truncated + suffix;
776
+ }
777
+ function truncateStart(str, maxContentLength, suffix) {
778
+ return suffix + str.slice(-maxContentLength);
779
+ }
780
+ function truncateMiddle(str, totalLength, suffix) {
781
+ if (str.length <= totalLength) return str;
782
+ const contentLength = totalLength - suffix.length;
783
+ if (contentLength <= 0) return suffix.slice(0, totalLength);
784
+ const startLength = Math.ceil(contentLength / 2);
785
+ const endLength = Math.floor(contentLength / 2);
786
+ return str.slice(0, startLength) + suffix + str.slice(-endLength);
787
+ }
788
+ function truncateWords(str, wordCount, suffix = "...") {
789
+ if (!str || typeof str !== "string") return "";
790
+ if (wordCount <= 0) return "";
791
+ const words = str.trim().split(/\s+/);
792
+ if (words.length <= wordCount) return str;
793
+ return words.slice(0, wordCount).join(" ") + suffix;
794
+ }
795
+ function truncateSentences(str, sentenceCount, suffix = "") {
796
+ if (!str || typeof str !== "string") return "";
797
+ if (sentenceCount <= 0) return "";
798
+ const sentences = str.match(/[^.!?]+[.!?]+/g) || [];
799
+ if (sentences.length <= sentenceCount) return str;
800
+ return sentences.slice(0, sentenceCount).join("").trim() + suffix;
801
+ }
802
+ function truncateFilename(filename, length, separator = "...") {
803
+ if (!filename || typeof filename !== "string") return "";
804
+ if (filename.length <= length) return filename;
805
+ const lastDot = filename.lastIndexOf(".");
806
+ if (lastDot === -1 || lastDot === 0) {
807
+ return truncateMiddle(filename, length, separator);
808
+ }
809
+ const name = filename.slice(0, lastDot);
810
+ const ext = filename.slice(lastDot);
811
+ const availableForName = length - ext.length - separator.length;
812
+ if (availableForName <= 0) {
813
+ return truncateMiddle(filename, length, separator);
814
+ }
815
+ const startLength = Math.ceil(availableForName / 2);
816
+ const endLength = Math.floor(availableForName / 2);
817
+ return name.slice(0, startLength) + separator + name.slice(-endLength) + ext;
818
+ }
819
+ function ellipsis(str, length) {
820
+ return truncate(str, length, { suffix: "…", preserveWords: false });
821
+ }
822
+ function truncateHtml(html, length, suffix = "...") {
823
+ if (!html || typeof html !== "string") return "";
824
+ const text = html.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
825
+ return truncate(text, length, { suffix, preserveWords: true });
826
+ }
827
+ function needsTruncation(str, length) {
828
+ if (!str || typeof str !== "string") return false;
829
+ return str.length > length;
830
+ }
831
+ function getGraphemeLength(str) {
832
+ if (!str) return 0;
833
+ if (typeof Intl !== "undefined" && "Segmenter" in Intl) {
834
+ const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
835
+ return [...segmenter.segment(str)].length;
836
+ }
837
+ return [...str].length;
838
+ }
839
+ function sliceGraphemes(str, start, end) {
840
+ if (!str) return "";
841
+ if (typeof Intl !== "undefined" && "Segmenter" in Intl) {
842
+ const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
843
+ const segments = [...segmenter.segment(str)].map((s) => s.segment);
844
+ return segments.slice(start, end).join("");
845
+ }
846
+ return [...str].slice(start, end).join("");
847
+ }
848
+ function truncateEndGrapheme(str, maxContentLength, suffix, preserveWords) {
849
+ let truncated = sliceGraphemes(str, 0, maxContentLength);
850
+ if (preserveWords) {
851
+ const lastSpace = truncated.lastIndexOf(" ");
852
+ if (lastSpace > maxContentLength * 0.3) {
853
+ truncated = truncated.slice(0, lastSpace);
854
+ }
855
+ }
856
+ truncated = truncated.replace(/[\s.,!?;:]+$/, "");
857
+ return truncated + suffix;
858
+ }
859
+ function truncateStartGrapheme(str, maxContentLength, suffix) {
860
+ const graphemeLength = getGraphemeLength(str);
861
+ return suffix + sliceGraphemes(str, graphemeLength - maxContentLength);
862
+ }
863
+ function truncateMiddleGrapheme(str, totalLength, suffix) {
864
+ const graphemeLength = getGraphemeLength(str);
865
+ if (graphemeLength <= totalLength) return str;
866
+ const suffixLength = getGraphemeLength(suffix);
867
+ const contentLength = totalLength - suffixLength;
868
+ if (contentLength <= 0) return sliceGraphemes(suffix, 0, totalLength);
869
+ const startLength = Math.ceil(contentLength / 2);
870
+ const endLength = Math.floor(contentLength / 2);
871
+ return sliceGraphemes(str, 0, startLength) + suffix + sliceGraphemes(str, graphemeLength - endLength);
872
+ }
873
+
874
+ export { capitalize, ellipsis, generateBase64String, generateHexString, generateOTP, generatePassphrase, generatePassword, generateRandomString, generateUrlSafeString, isValidSlug, maskCreditCard, maskEmail, maskIP, maskName, maskPhone, maskString, needsTruncation, slugify, swapCase, toCamelCase, toConstantCase, toDotCase, toKebabCase, toPascalCase, toSentenceCase, toSlug, toSnakeCase, toTitleCase, transliterate, truncate, truncateFilename, truncateHtml, truncateSentences, truncateWords, uncapitalize, uniqueSlug };
875
+ //# sourceMappingURL=chunk-BMQ6YPKV.js.map
876
+ //# sourceMappingURL=chunk-BMQ6YPKV.js.map