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,324 @@
1
+ import { init_constants, COMMON_PASSWORD_PATTERNS } from './chunk-ETWGPOPY.js';
2
+
3
+ // src/security/password.ts
4
+ init_constants();
5
+ var DEFAULT_OPTIONS = {
6
+ minLength: 8,
7
+ requireUppercase: true,
8
+ requireLowercase: true,
9
+ requireNumber: true,
10
+ requireSymbol: false
11
+ };
12
+ function checkPasswordStrength(password, options = {}) {
13
+ const opts = { ...DEFAULT_OPTIONS, ...options };
14
+ const suggestions = [];
15
+ const requirements = {
16
+ minLength: password.length >= (opts.minLength || 8),
17
+ hasUppercase: /[A-Z]/.test(password),
18
+ hasLowercase: /[a-z]/.test(password),
19
+ hasNumber: /[0-9]/.test(password),
20
+ hasSymbol: /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password),
21
+ noCommonPatterns: !COMMON_PASSWORD_PATTERNS.some((pattern) => pattern.test(password))
22
+ };
23
+ if (!requirements.minLength) {
24
+ suggestions.push(`Use at least ${opts.minLength} characters`);
25
+ }
26
+ if (!requirements.hasUppercase && opts.requireUppercase) {
27
+ suggestions.push("Add uppercase letters");
28
+ }
29
+ if (!requirements.hasLowercase && opts.requireLowercase) {
30
+ suggestions.push("Add lowercase letters");
31
+ }
32
+ if (!requirements.hasNumber && opts.requireNumber) {
33
+ suggestions.push("Add numbers");
34
+ }
35
+ if (!requirements.hasSymbol) {
36
+ suggestions.push("Add special characters (!@#$%^&*)");
37
+ }
38
+ if (!requirements.noCommonPatterns) {
39
+ suggestions.push("Avoid common password patterns");
40
+ }
41
+ let rawScore = 0;
42
+ if (password.length >= 8) rawScore += 1;
43
+ if (password.length >= 12) rawScore += 1;
44
+ if (password.length >= 16) rawScore += 1;
45
+ const varietyScore = (requirements.hasUppercase ? 1 : 0) + (requirements.hasLowercase ? 1 : 0) + (requirements.hasNumber ? 1 : 0) + (requirements.hasSymbol ? 1 : 0);
46
+ if (varietyScore >= 3) rawScore += 1;
47
+ if (varietyScore >= 4) rawScore += 1;
48
+ if (!requirements.noCommonPatterns) {
49
+ rawScore = Math.max(0, rawScore - 2);
50
+ }
51
+ const score = Math.min(4, Math.max(0, rawScore));
52
+ const entropy = calculatePasswordEntropy(password);
53
+ const labels = {
54
+ 0: "very-weak",
55
+ 1: "weak",
56
+ 2: "fair",
57
+ 3: "strong",
58
+ 4: "very-strong"
59
+ };
60
+ const crackTime = estimateCrackTime(entropy);
61
+ return {
62
+ score,
63
+ label: labels[score],
64
+ suggestions,
65
+ requirements,
66
+ crackTime
67
+ };
68
+ }
69
+ function calculatePasswordEntropy(password) {
70
+ if (!password) return 0;
71
+ let charsetSize = 0;
72
+ if (/[a-z]/.test(password)) charsetSize += 26;
73
+ if (/[A-Z]/.test(password)) charsetSize += 26;
74
+ if (/[0-9]/.test(password)) charsetSize += 10;
75
+ if (/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) charsetSize += 32;
76
+ if (/[^\x00-\x7F]/.test(password)) charsetSize += 100;
77
+ if (charsetSize === 0) return 0;
78
+ return password.length * Math.log2(charsetSize);
79
+ }
80
+ function estimateCrackTime(entropy) {
81
+ if (entropy <= 0) return "Instantly";
82
+ const guessesPerSecondLog2 = 33.22;
83
+ const secondsLog2 = entropy - guessesPerSecondLog2;
84
+ if (secondsLog2 < 0) return "Instantly";
85
+ if (secondsLog2 < 6) return "Less than a minute";
86
+ if (secondsLog2 < 10) return "Minutes";
87
+ if (secondsLog2 < 14) return "Hours";
88
+ if (secondsLog2 < 17) return "Days";
89
+ if (secondsLog2 < 20) return "Weeks";
90
+ if (secondsLog2 < 22) return "Months";
91
+ if (secondsLog2 < 25) return "Years";
92
+ if (secondsLog2 < 35) return "Decades";
93
+ if (secondsLog2 < 45) return "Centuries";
94
+ return "Millennia+";
95
+ }
96
+ function meetsRequirements(password, requirements) {
97
+ const result = checkPasswordStrength(password, requirements);
98
+ if (requirements.minLength && !result.requirements.minLength) return false;
99
+ if (requirements.requireUppercase && !result.requirements.hasUppercase) return false;
100
+ if (requirements.requireLowercase && !result.requirements.hasLowercase) return false;
101
+ if (requirements.requireNumber && !result.requirements.hasNumber) return false;
102
+ if (requirements.requireSymbol && !result.requirements.hasSymbol) return false;
103
+ return true;
104
+ }
105
+ function isStrongPassword(password, minScore = 3) {
106
+ const result = checkPasswordStrength(password);
107
+ return result.score >= minScore;
108
+ }
109
+ function getPasswordFeedback(password) {
110
+ const result = checkPasswordStrength(password);
111
+ if (result.score === 0) {
112
+ return "This password is very weak and can be cracked instantly.";
113
+ }
114
+ if (result.score === 1) {
115
+ return "This password is weak. " + result.suggestions.slice(0, 2).join(". ") + ".";
116
+ }
117
+ if (result.score === 2) {
118
+ return "This password is fair but could be stronger. " + result.suggestions[0] + ".";
119
+ }
120
+ if (result.score === 3) {
121
+ return "This password is strong.";
122
+ }
123
+ return "This password is very strong!";
124
+ }
125
+
126
+ // src/security/hash.ts
127
+ async function hashSHA256(data) {
128
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
129
+ const encoder = new TextEncoder();
130
+ const dataBuffer = encoder.encode(data);
131
+ const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", dataBuffer);
132
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
133
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
134
+ }
135
+ try {
136
+ const crypto = await import('crypto');
137
+ return crypto.createHash("sha256").update(data).digest("hex");
138
+ } catch {
139
+ throw new Error("SHA-256 hashing is not available in this environment");
140
+ }
141
+ }
142
+ async function hashSHA512(data) {
143
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
144
+ const encoder = new TextEncoder();
145
+ const dataBuffer = encoder.encode(data);
146
+ const hashBuffer = await globalThis.crypto.subtle.digest("SHA-512", dataBuffer);
147
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
148
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
149
+ }
150
+ try {
151
+ const crypto = await import('crypto');
152
+ return crypto.createHash("sha512").update(data).digest("hex");
153
+ } catch {
154
+ throw new Error("SHA-512 hashing is not available in this environment");
155
+ }
156
+ }
157
+ async function hashMD5(data) {
158
+ console.warn(
159
+ "[utilitify] MD5 is cryptographically broken and should not be used for security purposes. Use hashSHA256() instead. MD5 should only be used for checksums or legacy compatibility."
160
+ );
161
+ try {
162
+ const crypto = await import('crypto');
163
+ return crypto.createHash("md5").update(data).digest("hex");
164
+ } catch {
165
+ throw new Error("MD5 hashing is not available in this environment");
166
+ }
167
+ }
168
+ async function hashBcrypt(password, rounds = 10) {
169
+ try {
170
+ const bcrypt = await import('bcryptjs');
171
+ const salt = await bcrypt.genSalt(rounds);
172
+ return bcrypt.hash(password, salt);
173
+ } catch {
174
+ throw new Error(
175
+ "bcryptjs is not installed. Install it with: npm install bcryptjs"
176
+ );
177
+ }
178
+ }
179
+ async function verifyBcrypt(password, hash) {
180
+ try {
181
+ const bcrypt = await import('bcryptjs');
182
+ return bcrypt.compare(password, hash);
183
+ } catch {
184
+ throw new Error(
185
+ "bcryptjs is not installed. Install it with: npm install bcryptjs"
186
+ );
187
+ }
188
+ }
189
+ async function hmacSHA256(data, key) {
190
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
191
+ const encoder = new TextEncoder();
192
+ const keyData = encoder.encode(key);
193
+ const dataBuffer = encoder.encode(data);
194
+ const cryptoKey = await globalThis.crypto.subtle.importKey(
195
+ "raw",
196
+ keyData,
197
+ { name: "HMAC", hash: "SHA-256" },
198
+ false,
199
+ ["sign"]
200
+ );
201
+ const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, dataBuffer);
202
+ const hashArray = Array.from(new Uint8Array(signature));
203
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
204
+ }
205
+ try {
206
+ const crypto = await import('crypto');
207
+ return crypto.createHmac("sha256", key).update(data).digest("hex");
208
+ } catch {
209
+ throw new Error("HMAC-SHA256 is not available in this environment");
210
+ }
211
+ }
212
+ function timingSafeCompare(a, b) {
213
+ const maxLength = Math.max(a.length, b.length);
214
+ const paddedA = a.padEnd(maxLength, "\0");
215
+ const paddedB = b.padEnd(maxLength, "\0");
216
+ let result = 0;
217
+ for (let i = 0; i < maxLength; i++) {
218
+ result |= paddedA.charCodeAt(i) ^ paddedB.charCodeAt(i);
219
+ }
220
+ result |= a.length ^ b.length;
221
+ return result === 0;
222
+ }
223
+
224
+ // src/security/token.ts
225
+ function generateUUID() {
226
+ if (typeof globalThis.crypto?.randomUUID === "function") {
227
+ return globalThis.crypto.randomUUID();
228
+ }
229
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
230
+ const bytes = new Uint8Array(16);
231
+ globalThis.crypto.getRandomValues(bytes);
232
+ bytes[6] = bytes[6] & 15 | 64;
233
+ bytes[8] = bytes[8] & 63 | 128;
234
+ const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
235
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
236
+ }
237
+ throw new Error(
238
+ "Crypto API not available. UUID generation requires a secure random source. Ensure you are running in a modern browser or Node.js 15.0.0+."
239
+ );
240
+ }
241
+ function generateUUIDv7() {
242
+ const now = Date.now();
243
+ const timestampHex = now.toString(16).padStart(12, "0");
244
+ const randomHex = generateRandomHex(20);
245
+ const variantIndex = parseInt(randomHex.charAt(0), 16) % 4;
246
+ const variants = ["8", "9", "a", "b"];
247
+ return timestampHex.slice(0, 8) + "-" + timestampHex.slice(8, 12) + "-7" + randomHex.slice(0, 3) + "-" + variants[variantIndex] + randomHex.slice(3, 6) + "-" + randomHex.slice(6, 18);
248
+ }
249
+ function generateToken(length = 32) {
250
+ return generateRandomHex(length * 2);
251
+ }
252
+ function generateSecureToken(length = 32) {
253
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
254
+ const bytes = new Uint8Array(length);
255
+ globalThis.crypto.getRandomValues(bytes);
256
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
257
+ }
258
+ return generateRandomHex(length * 2);
259
+ }
260
+ function generateBase64Token(length = 32) {
261
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
262
+ const bytes = new Uint8Array(length);
263
+ globalThis.crypto.getRandomValues(bytes);
264
+ if (typeof btoa === "function") {
265
+ return btoa(String.fromCharCode(...bytes));
266
+ }
267
+ return Buffer.from(bytes).toString("base64");
268
+ }
269
+ const hex = generateRandomHex(length * 2);
270
+ if (typeof btoa === "function") {
271
+ return btoa(
272
+ hex.match(/.{2}/g).map((byte) => String.fromCharCode(parseInt(byte, 16))).join("")
273
+ );
274
+ }
275
+ return Buffer.from(hex, "hex").toString("base64");
276
+ }
277
+ function generateUrlSafeToken(length = 32) {
278
+ const base64 = generateBase64Token(length);
279
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
280
+ }
281
+ function isValidUUID(uuid) {
282
+ if (!uuid || typeof uuid !== "string") return false;
283
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
284
+ return uuidRegex.test(uuid);
285
+ }
286
+ function getUUIDv7Timestamp(uuid) {
287
+ if (!isValidUUID(uuid)) return null;
288
+ if (uuid[14] !== "7") return null;
289
+ try {
290
+ const timestampHex = uuid.replace(/-/g, "").slice(0, 12);
291
+ const timestamp = parseInt(timestampHex, 16);
292
+ return new Date(timestamp);
293
+ } catch {
294
+ return null;
295
+ }
296
+ }
297
+ function generateShortId() {
298
+ return generateRandomHex(8);
299
+ }
300
+ function generateNanoId(length = 21) {
301
+ const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
302
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
303
+ const bytes = new Uint8Array(length);
304
+ globalThis.crypto.getRandomValues(bytes);
305
+ return Array.from(bytes).map((b) => alphabet[b % alphabet.length]).join("");
306
+ }
307
+ throw new Error(
308
+ "Crypto API not available. NanoID generation requires a secure random source. Ensure you are running in a modern browser or Node.js 15.0.0+."
309
+ );
310
+ }
311
+ function generateRandomHex(length) {
312
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
313
+ const bytes = new Uint8Array(Math.ceil(length / 2));
314
+ globalThis.crypto.getRandomValues(bytes);
315
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, length);
316
+ }
317
+ throw new Error(
318
+ "Crypto API not available. Secure random generation requires crypto.getRandomValues. Ensure you are running in a modern browser or Node.js 15.0.0+."
319
+ );
320
+ }
321
+
322
+ export { checkPasswordStrength, generateBase64Token, generateNanoId, generateSecureToken, generateShortId, generateToken, generateUUID, generateUUIDv7, generateUrlSafeToken, getPasswordFeedback, getUUIDv7Timestamp, hashBcrypt, hashMD5, hashSHA256, hashSHA512, hmacSHA256, isStrongPassword, isValidUUID, meetsRequirements, timingSafeCompare, verifyBcrypt };
323
+ //# sourceMappingURL=chunk-SD6P3WEJ.js.map
324
+ //# sourceMappingURL=chunk-SD6P3WEJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/security/password.ts","../src/security/hash.ts","../src/security/token.ts"],"names":[],"mappings":"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","file":"chunk-SD6P3WEJ.js","sourcesContent":["import { COMMON_PASSWORD_PATTERNS } from '../utils/constants';\r\n\r\n/**\r\n * Password strength result\r\n */\r\nexport interface PasswordStrength {\r\n /** Score from 0-4 (0 = very weak, 4 = very strong) */\r\n score: 0 | 1 | 2 | 3 | 4;\r\n /** Human-readable strength label */\r\n label: 'very-weak' | 'weak' | 'fair' | 'strong' | 'very-strong';\r\n /** Improvement suggestions */\r\n suggestions: string[];\r\n /** Requirements met */\r\n requirements: {\r\n minLength: boolean;\r\n hasUppercase: boolean;\r\n hasLowercase: boolean;\r\n hasNumber: boolean;\r\n hasSymbol: boolean;\r\n noCommonPatterns: boolean;\r\n };\r\n /** Estimated crack time description */\r\n crackTime: string;\r\n}\r\n\r\n/**\r\n * Password strength options\r\n */\r\nexport interface PasswordStrengthOptions {\r\n /** Minimum length (default: 8) */\r\n minLength?: number;\r\n /** Require uppercase (default: true) */\r\n requireUppercase?: boolean;\r\n /** Require lowercase (default: true) */\r\n requireLowercase?: boolean;\r\n /** Require number (default: true) */\r\n requireNumber?: boolean;\r\n /** Require symbol (default: false) */\r\n requireSymbol?: boolean;\r\n}\r\n\r\n/**\r\n * Default options\r\n */\r\nconst DEFAULT_OPTIONS: PasswordStrengthOptions = {\r\n minLength: 8,\r\n requireUppercase: true,\r\n requireLowercase: true,\r\n requireNumber: true,\r\n requireSymbol: false,\r\n};\r\n\r\n/**\r\n * Check password strength\r\n *\r\n * @param password - Password to check\r\n * @param options - Strength options\r\n * @returns Password strength result\r\n * @since 1.0.0\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = checkPasswordStrength('MyP@ssw0rd!');\r\n * console.log(result.score); // 4\r\n * console.log(result.label); // 'very-strong'\r\n * ```\r\n */\r\nexport function checkPasswordStrength(\r\n password: string,\r\n options: PasswordStrengthOptions = {}\r\n): PasswordStrength {\r\n const opts = { ...DEFAULT_OPTIONS, ...options };\r\n const suggestions: string[] = [];\r\n\r\n // Check requirements\r\n const requirements = {\r\n minLength: password.length >= (opts.minLength || 8),\r\n hasUppercase: /[A-Z]/.test(password),\r\n hasLowercase: /[a-z]/.test(password),\r\n hasNumber: /[0-9]/.test(password),\r\n hasSymbol: /[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]/.test(password),\r\n noCommonPatterns: !COMMON_PASSWORD_PATTERNS.some(pattern => pattern.test(password)),\r\n };\r\n\r\n // Build suggestions\r\n if (!requirements.minLength) {\r\n suggestions.push(`Use at least ${opts.minLength} characters`);\r\n }\r\n if (!requirements.hasUppercase && opts.requireUppercase) {\r\n suggestions.push('Add uppercase letters');\r\n }\r\n if (!requirements.hasLowercase && opts.requireLowercase) {\r\n suggestions.push('Add lowercase letters');\r\n }\r\n if (!requirements.hasNumber && opts.requireNumber) {\r\n suggestions.push('Add numbers');\r\n }\r\n if (!requirements.hasSymbol) {\r\n suggestions.push('Add special characters (!@#$%^&*)');\r\n }\r\n if (!requirements.noCommonPatterns) {\r\n suggestions.push('Avoid common password patterns');\r\n }\r\n\r\n // Calculate score\r\n let rawScore = 0;\r\n\r\n // Length scoring\r\n if (password.length >= 8) rawScore += 1;\r\n if (password.length >= 12) rawScore += 1;\r\n if (password.length >= 16) rawScore += 1;\r\n\r\n // Character variety scoring\r\n const varietyScore =\r\n (requirements.hasUppercase ? 1 : 0) +\r\n (requirements.hasLowercase ? 1 : 0) +\r\n (requirements.hasNumber ? 1 : 0) +\r\n (requirements.hasSymbol ? 1 : 0);\r\n\r\n if (varietyScore >= 3) rawScore += 1;\r\n if (varietyScore >= 4) rawScore += 1;\r\n\r\n // Penalty for common patterns\r\n if (!requirements.noCommonPatterns) {\r\n rawScore = Math.max(0, rawScore - 2);\r\n }\r\n\r\n // Ensure score is in range and cast to proper type\r\n const score = Math.min(4, Math.max(0, rawScore)) as 0 | 1 | 2 | 3 | 4;\r\n\r\n // Calculate entropy for more accurate strength assessment\r\n const entropy = calculatePasswordEntropy(password);\r\n\r\n // Determine label based on entropy\r\n const labels: Record<number, PasswordStrength['label']> = {\r\n 0: 'very-weak',\r\n 1: 'weak',\r\n 2: 'fair',\r\n 3: 'strong',\r\n 4: 'very-strong',\r\n };\r\n\r\n // Calculate crack time based on entropy\r\n // Assuming 10 billion guesses per second (modern GPU cracking)\r\n const crackTime = estimateCrackTime(entropy);\r\n\r\n return {\r\n score,\r\n label: labels[score],\r\n suggestions,\r\n requirements,\r\n crackTime,\r\n };\r\n}\r\n\r\n/**\r\n * Calculate password entropy in bits\r\n * \r\n * @param password - Password to analyze\r\n * @returns Entropy in bits\r\n */\r\nfunction calculatePasswordEntropy(password: string): number {\r\n if (!password) return 0;\r\n\r\n let charsetSize = 0;\r\n\r\n // Calculate character set size\r\n if (/[a-z]/.test(password)) charsetSize += 26;\r\n if (/[A-Z]/.test(password)) charsetSize += 26;\r\n if (/[0-9]/.test(password)) charsetSize += 10;\r\n if (/[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]/.test(password)) charsetSize += 32;\r\n if (/[^\\x00-\\x7F]/.test(password)) charsetSize += 100; // Unicode characters\r\n\r\n // Entropy = log2(charsetSize^length) = length * log2(charsetSize)\r\n if (charsetSize === 0) return 0;\r\n\r\n return password.length * Math.log2(charsetSize);\r\n}\r\n\r\n/**\r\n * Estimate crack time based on entropy\r\n * Assumes 10 billion guesses per second (modern GPU)\r\n * \r\n * @param entropy - Entropy in bits\r\n * @returns Human-readable crack time\r\n */\r\nfunction estimateCrackTime(entropy: number): string {\r\n if (entropy <= 0) return 'Instantly';\r\n\r\n // 2^entropy = number of possible combinations\r\n // Time = combinations / guesses_per_second\r\n // Using log to avoid overflow: log2(seconds) = entropy - log2(guesses_per_second)\r\n const guessesPerSecondLog2 = 33.22; // log2(10 billion) ≈ 33.22\r\n const secondsLog2 = entropy - guessesPerSecondLog2;\r\n\r\n if (secondsLog2 < 0) return 'Instantly';\r\n if (secondsLog2 < 6) return 'Less than a minute';\r\n if (secondsLog2 < 10) return 'Minutes';\r\n if (secondsLog2 < 14) return 'Hours';\r\n if (secondsLog2 < 17) return 'Days';\r\n if (secondsLog2 < 20) return 'Weeks';\r\n if (secondsLog2 < 22) return 'Months';\r\n if (secondsLog2 < 25) return 'Years';\r\n if (secondsLog2 < 35) return 'Decades';\r\n if (secondsLog2 < 45) return 'Centuries';\r\n return 'Millennia+';\r\n}\r\n\r\n/**\r\n * Check if password meets requirements\r\n *\r\n * @param password - Password to check\r\n * @param requirements - Requirements to check\r\n * @returns true if all requirements met\r\n */\r\nexport function meetsRequirements(\r\n password: string,\r\n requirements: Partial<PasswordStrengthOptions>\r\n): boolean {\r\n const result = checkPasswordStrength(password, requirements);\r\n\r\n if (requirements.minLength && !result.requirements.minLength) return false;\r\n if (requirements.requireUppercase && !result.requirements.hasUppercase) return false;\r\n if (requirements.requireLowercase && !result.requirements.hasLowercase) return false;\r\n if (requirements.requireNumber && !result.requirements.hasNumber) return false;\r\n if (requirements.requireSymbol && !result.requirements.hasSymbol) return false;\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Check if password is strong enough\r\n *\r\n * @param password - Password to check\r\n * @param minScore - Minimum score (default: 3)\r\n * @returns true if strong enough\r\n */\r\nexport function isStrongPassword(password: string, minScore: number = 3): boolean {\r\n const result = checkPasswordStrength(password);\r\n return result.score >= minScore;\r\n}\r\n\r\n/**\r\n * Get password feedback message\r\n *\r\n * @param password - Password to check\r\n * @returns Feedback message\r\n */\r\nexport function getPasswordFeedback(password: string): string {\r\n const result = checkPasswordStrength(password);\r\n\r\n if (result.score === 0) {\r\n return 'This password is very weak and can be cracked instantly.';\r\n }\r\n if (result.score === 1) {\r\n return 'This password is weak. ' + result.suggestions.slice(0, 2).join('. ') + '.';\r\n }\r\n if (result.score === 2) {\r\n return 'This password is fair but could be stronger. ' + result.suggestions[0] + '.';\r\n }\r\n if (result.score === 3) {\r\n return 'This password is strong.';\r\n }\r\n return 'This password is very strong!';\r\n}\r\n","/**\r\n * Hash a string using SHA-256\r\n * Uses Web Crypto API for browser compatibility\r\n *\r\n * @param data - String to hash\r\n * @returns SHA-256 hash as hex string\r\n *\r\n * @example\r\n * ```typescript\r\n * const hash = await hashSHA256('hello world');\r\n * // 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'\r\n * ```\r\n */\r\nexport async function hashSHA256(data: string): Promise<string> {\r\n // Node.js environment\r\n if (typeof globalThis.crypto?.subtle !== 'undefined') {\r\n const encoder = new TextEncoder();\r\n const dataBuffer = encoder.encode(data);\r\n const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', dataBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n // Fallback for Node.js without Web Crypto\r\n try {\r\n const crypto = await import('crypto');\r\n return crypto.createHash('sha256').update(data).digest('hex');\r\n } catch {\r\n throw new Error('SHA-256 hashing is not available in this environment');\r\n }\r\n}\r\n\r\n/**\r\n * Hash a string using SHA-512\r\n *\r\n * @param data - String to hash\r\n * @returns SHA-512 hash as hex string\r\n */\r\nexport async function hashSHA512(data: string): Promise<string> {\r\n if (typeof globalThis.crypto?.subtle !== 'undefined') {\r\n const encoder = new TextEncoder();\r\n const dataBuffer = encoder.encode(data);\r\n const hashBuffer = await globalThis.crypto.subtle.digest('SHA-512', dataBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n try {\r\n const crypto = await import('crypto');\r\n return crypto.createHash('sha512').update(data).digest('hex');\r\n } catch {\r\n throw new Error('SHA-512 hashing is not available in this environment');\r\n }\r\n}\r\n\r\n/**\r\n * Hash a string using MD5 (NOT SECURE - use for checksums only)\r\n *\r\n * @deprecated MD5 is cryptographically broken. Use SHA-256 for security-sensitive hashing.\r\n * @param data - String to hash\r\n * @returns MD5 hash as hex string\r\n */\r\nexport async function hashMD5(data: string): Promise<string> {\r\n console.warn(\r\n '[utilitify] MD5 is cryptographically broken and should not be used for security purposes. ' +\r\n 'Use hashSHA256() instead. MD5 should only be used for checksums or legacy compatibility.'\r\n );\r\n try {\r\n const crypto = await import('crypto');\r\n return crypto.createHash('md5').update(data).digest('hex');\r\n } catch {\r\n throw new Error('MD5 hashing is not available in this environment');\r\n }\r\n}\r\n\r\n/**\r\n * Hash password using bcrypt (requires bcryptjs)\r\n *\r\n * @param password - Password to hash\r\n * @param rounds - Salt rounds (default: 10)\r\n * @returns Bcrypt hash\r\n */\r\nexport async function hashBcrypt(password: string, rounds: number = 10): Promise<string> {\r\n try {\r\n const bcrypt = await import('bcryptjs');\r\n const salt = await bcrypt.genSalt(rounds);\r\n return bcrypt.hash(password, salt);\r\n } catch {\r\n throw new Error(\r\n 'bcryptjs is not installed. Install it with: npm install bcryptjs'\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Verify password against bcrypt hash\r\n *\r\n * @param password - Password to verify\r\n * @param hash - Bcrypt hash\r\n * @returns true if password matches\r\n */\r\nexport async function verifyBcrypt(password: string, hash: string): Promise<boolean> {\r\n try {\r\n const bcrypt = await import('bcryptjs');\r\n return bcrypt.compare(password, hash);\r\n } catch {\r\n throw new Error(\r\n 'bcryptjs is not installed. Install it with: npm install bcryptjs'\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Hash with HMAC-SHA256\r\n *\r\n * @param data - Data to hash\r\n * @param key - Secret key\r\n * @returns HMAC hash\r\n */\r\nexport async function hmacSHA256(data: string, key: string): Promise<string> {\r\n if (typeof globalThis.crypto?.subtle !== 'undefined') {\r\n const encoder = new TextEncoder();\r\n const keyData = encoder.encode(key);\r\n const dataBuffer = encoder.encode(data);\r\n\r\n const cryptoKey = await globalThis.crypto.subtle.importKey(\r\n 'raw',\r\n keyData,\r\n { name: 'HMAC', hash: 'SHA-256' },\r\n false,\r\n ['sign']\r\n );\r\n\r\n const signature = await globalThis.crypto.subtle.sign('HMAC', cryptoKey, dataBuffer);\r\n const hashArray = Array.from(new Uint8Array(signature));\r\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n try {\r\n const crypto = await import('crypto');\r\n return crypto.createHmac('sha256', key).update(data).digest('hex');\r\n } catch {\r\n throw new Error('HMAC-SHA256 is not available in this environment');\r\n }\r\n}\r\n\r\n/**\r\n * Compare two strings in constant time (timing-safe)\r\n * This prevents timing attacks that could leak information about the string contents.\r\n *\r\n * @param a - First string\r\n * @param b - Second string\r\n * @returns true if equal\r\n */\r\nexport function timingSafeCompare(a: string, b: string): boolean {\r\n // Use the longer length to ensure constant-time comparison\r\n const maxLength = Math.max(a.length, b.length);\r\n\r\n // Pad both strings to the same length to prevent length-based timing attacks\r\n const paddedA = a.padEnd(maxLength, '\\0');\r\n const paddedB = b.padEnd(maxLength, '\\0');\r\n\r\n let result = 0;\r\n\r\n // XOR all characters - this takes constant time regardless of differences\r\n for (let i = 0; i < maxLength; i++) {\r\n result |= paddedA.charCodeAt(i) ^ paddedB.charCodeAt(i);\r\n }\r\n\r\n // Also check if lengths match (constant time)\r\n result |= a.length ^ b.length;\r\n\r\n return result === 0;\r\n}\r\n","/**\r\n * Generate UUID v4 (random)\r\n *\r\n * @returns UUID v4 string\r\n * @throws Error if crypto API is not available\r\n *\r\n * @example\r\n * ```typescript\r\n * generateUUID(); // '550e8400-e29b-41d4-a716-446655440000'\r\n * ```\r\n */\r\nexport function generateUUID(): string {\r\n // Use crypto.randomUUID if available (best option)\r\n if (typeof globalThis.crypto?.randomUUID === 'function') {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n\r\n // Fallback using getRandomValues (still secure)\r\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\r\n const bytes = new Uint8Array(16);\r\n globalThis.crypto.getRandomValues(bytes);\r\n // Set version (4) and variant (RFC 4122)\r\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\r\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\r\n\r\n const hex = Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('');\r\n\r\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;\r\n }\r\n\r\n throw new Error(\r\n 'Crypto API not available. UUID generation requires a secure random source. ' +\r\n 'Ensure you are running in a modern browser or Node.js 15.0.0+.'\r\n );\r\n}\r\n\r\n/**\r\n * Generate UUID v7 (time-sortable)\r\n * Based on Unix Epoch timestamp\r\n *\r\n * @returns UUID v7 string\r\n */\r\nexport function generateUUIDv7(): string {\r\n const now = Date.now();\r\n\r\n // Convert timestamp to hex (48 bits = 12 hex chars)\r\n const timestampHex = now.toString(16).padStart(12, '0');\r\n\r\n // Generate random bytes for the rest\r\n const randomHex = generateRandomHex(20);\r\n\r\n // Format: tttttttt-tttt-7xxx-yxxx-xxxxxxxxxxxx\r\n // t = timestamp, 7 = version, y = variant (8, 9, a, or b)\r\n // Use first byte of random for variant selection\r\n const variantIndex = parseInt(randomHex.charAt(0), 16) % 4;\r\n const variants = ['8', '9', 'a', 'b'];\r\n\r\n return (\r\n timestampHex.slice(0, 8) +\r\n '-' +\r\n timestampHex.slice(8, 12) +\r\n '-7' +\r\n randomHex.slice(0, 3) +\r\n '-' +\r\n variants[variantIndex] +\r\n randomHex.slice(3, 6) +\r\n '-' +\r\n randomHex.slice(6, 18)\r\n );\r\n}\r\n\r\n/**\r\n * Generate a secure random token\r\n *\r\n * @param length - Token length in bytes (default: 32)\r\n * @returns Hex-encoded token\r\n */\r\nexport function generateToken(length: number = 32): string {\r\n return generateRandomHex(length * 2);\r\n}\r\n\r\n/**\r\n * Generate a cryptographically secure token\r\n *\r\n * @param length - Token length in bytes\r\n * @returns Hex-encoded secure token\r\n */\r\nexport function generateSecureToken(length: number = 32): string {\r\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\r\n const bytes = new Uint8Array(length);\r\n globalThis.crypto.getRandomValues(bytes);\r\n return Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('');\r\n }\r\n\r\n // Fallback to less secure method\r\n return generateRandomHex(length * 2);\r\n}\r\n\r\n/**\r\n * Generate a Base64 encoded token\r\n *\r\n * @param length - Token length in bytes\r\n * @returns Base64-encoded token\r\n */\r\nexport function generateBase64Token(length: number = 32): string {\r\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\r\n const bytes = new Uint8Array(length);\r\n globalThis.crypto.getRandomValues(bytes);\r\n\r\n // Convert to base64\r\n if (typeof btoa === 'function') {\r\n return btoa(String.fromCharCode(...bytes));\r\n }\r\n\r\n // Node.js fallback\r\n return Buffer.from(bytes).toString('base64');\r\n }\r\n\r\n // Fallback\r\n const hex = generateRandomHex(length * 2);\r\n if (typeof btoa === 'function') {\r\n return btoa(\r\n hex\r\n .match(/.{2}/g)!\r\n .map(byte => String.fromCharCode(parseInt(byte, 16)))\r\n .join('')\r\n );\r\n }\r\n return Buffer.from(hex, 'hex').toString('base64');\r\n}\r\n\r\n/**\r\n * Generate URL-safe token\r\n *\r\n * @param length - Token length\r\n * @returns URL-safe token\r\n */\r\nexport function generateUrlSafeToken(length: number = 32): string {\r\n const base64 = generateBase64Token(length);\r\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\r\n}\r\n\r\n/**\r\n * Validate UUID format\r\n *\r\n * @param uuid - String to validate\r\n * @returns true if valid UUID\r\n */\r\nexport function isValidUUID(uuid: string): boolean {\r\n if (!uuid || typeof uuid !== 'string') return false;\r\n const uuidRegex =\r\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\r\n return uuidRegex.test(uuid);\r\n}\r\n\r\n/**\r\n * Extract timestamp from UUID v7\r\n *\r\n * @param uuid - UUID v7 string\r\n * @returns Date or null\r\n */\r\nexport function getUUIDv7Timestamp(uuid: string): Date | null {\r\n if (!isValidUUID(uuid)) return null;\r\n\r\n // Check if it's v7\r\n if (uuid[14] !== '7') return null;\r\n\r\n try {\r\n const timestampHex = uuid.replace(/-/g, '').slice(0, 12);\r\n const timestamp = parseInt(timestampHex, 16);\r\n return new Date(timestamp);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Generate short ID (8 characters)\r\n *\r\n * @returns Short ID\r\n */\r\nexport function generateShortId(): string {\r\n return generateRandomHex(8);\r\n}\r\n\r\n/**\r\n * Generate nano ID style token\r\n *\r\n * @param length - Length (default: 21)\r\n * @returns NanoID-style token\r\n */\r\nexport function generateNanoId(length: number = 21): string {\r\n const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_';\r\n\r\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\r\n const bytes = new Uint8Array(length);\r\n globalThis.crypto.getRandomValues(bytes);\r\n return Array.from(bytes)\r\n .map(b => alphabet[b % alphabet.length])\r\n .join('');\r\n }\r\n\r\n throw new Error(\r\n 'Crypto API not available. NanoID generation requires a secure random source. ' +\r\n 'Ensure you are running in a modern browser or Node.js 15.0.0+.'\r\n );\r\n}\r\n\r\n/**\r\n * Generate random hex string\r\n */\r\nfunction generateRandomHex(length: number): string {\r\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\r\n const bytes = new Uint8Array(Math.ceil(length / 2));\r\n globalThis.crypto.getRandomValues(bytes);\r\n return Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .slice(0, length);\r\n }\r\n\r\n throw new Error(\r\n 'Crypto API not available. Secure random generation requires crypto.getRandomValues. ' +\r\n 'Ensure you are running in a modern browser or Node.js 15.0.0+.'\r\n );\r\n}\r\n"]}