@ppabari/strio 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -0
- package/LICENSE +21 -0
- package/README.md +565 -0
- package/dist/bin/strio.js +1492 -0
- package/dist/index.cjs +1913 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +885 -0
- package/dist/index.d.ts +885 -0
- package/dist/index.js +1881 -0
- package/dist/index.js.map +1 -0
- package/dist/zod-CINbFpp9.d.cts +211 -0
- package/dist/zod-CINbFpp9.d.ts +211 -0
- package/dist/zod.cjs +165 -0
- package/dist/zod.cjs.map +1 -0
- package/dist/zod.d.cts +1 -0
- package/dist/zod.d.ts +1 -0
- package/dist/zod.js +163 -0
- package/dist/zod.js.map +1 -0
- package/package.json +98 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,885 @@
|
|
|
1
|
+
import { R as RandomStringOptions, E as EntropyResult, V as ValidateOptions, c as ValidationResult } from './zod-CINbFpp9.cjs';
|
|
2
|
+
export { a as RandomStringResult, b as RandomStringSchemaOptions, S as StartWith, r as randomStringSchema } from './zod-CINbFpp9.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* short-id.ts
|
|
6
|
+
* Collision-resistant short IDs with an optional checksum character.
|
|
7
|
+
*
|
|
8
|
+
* A checksum character (Luhn-style mod-N) is appended to the random
|
|
9
|
+
* portion so that single-character transcription errors are detectable
|
|
10
|
+
* without a database lookup. The checksum uses the same charset as the
|
|
11
|
+
* random portion — the output looks uniform.
|
|
12
|
+
*
|
|
13
|
+
* Format: [prefix_][random chars][checksum char]
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const id = generateId({ prefix: 'usr' });
|
|
17
|
+
* // → 'usr_K3xP9mQr2L4c' (10 random + 1 checksum = 11 chars after prefix)
|
|
18
|
+
*
|
|
19
|
+
* validateId('usr_K3xP9mQr2L4c', { prefix: 'usr' });
|
|
20
|
+
* // → { valid: true, ... }
|
|
21
|
+
*/
|
|
22
|
+
interface ShortIdOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Optional prefix string, e.g. `'usr'` → `'usr_K3xP9mQr'`.
|
|
25
|
+
* An underscore separator is added automatically between prefix and random part.
|
|
26
|
+
* Set `separator: ''` to disable.
|
|
27
|
+
*/
|
|
28
|
+
prefix?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Separator between prefix and random portion.
|
|
31
|
+
* @default '_'
|
|
32
|
+
*/
|
|
33
|
+
separator?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Length of the random portion (before checksum is added).
|
|
36
|
+
* Total random section = randomLength + 1 (checksum).
|
|
37
|
+
* @default 12
|
|
38
|
+
*/
|
|
39
|
+
randomLength?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Character pool for the random portion. Accepts a charset alias
|
|
42
|
+
* (e.g. `'base58'`) or a raw character string.
|
|
43
|
+
* @default base58 (no ambiguous chars)
|
|
44
|
+
*/
|
|
45
|
+
charset?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Whether to append a checksum character.
|
|
48
|
+
* Disable only if you need exact length control.
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
checksum?: boolean;
|
|
52
|
+
}
|
|
53
|
+
interface ShortIdValidateOptions {
|
|
54
|
+
/** Expected prefix (without separator). */
|
|
55
|
+
prefix?: string;
|
|
56
|
+
/** Separator used when the ID was generated. @default '_' */
|
|
57
|
+
separator?: string;
|
|
58
|
+
/** Charset used when the ID was generated. @default base58 */
|
|
59
|
+
charset?: string;
|
|
60
|
+
/** Whether the ID was generated with a checksum. @default true */
|
|
61
|
+
checksum?: boolean;
|
|
62
|
+
}
|
|
63
|
+
interface ShortIdValidateResult {
|
|
64
|
+
valid: boolean;
|
|
65
|
+
errors: string[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate a collision-resistant short ID.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* generateId() // → 'K3xP9mQr2L4Xc'
|
|
72
|
+
* generateId({ prefix: 'usr' }) // → 'usr_K3xP9mQr2L4Xc'
|
|
73
|
+
* generateId({ prefix: 'inv', randomLength: 8 }) // → 'inv_K3xP9mQrc'
|
|
74
|
+
* generateId({ charset: 'base62' }) // → '4jK9mQr2L4Xz3'
|
|
75
|
+
*/
|
|
76
|
+
declare function generateId(options?: ShortIdOptions): string;
|
|
77
|
+
/**
|
|
78
|
+
* Validate a short ID against a known config.
|
|
79
|
+
* Checks prefix, separator, and checksum integrity.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* validateId('usr_K3xP9mQr2L4Xc', { prefix: 'usr' })
|
|
83
|
+
* // → { valid: true, errors: [] }
|
|
84
|
+
*
|
|
85
|
+
* validateId('usr_K3xP9mQr2L4Xa', { prefix: 'usr' })
|
|
86
|
+
* // → { valid: false, errors: ['Checksum mismatch — ID may be corrupted or mistyped.'] }
|
|
87
|
+
*/
|
|
88
|
+
declare function validateId(id: string, options?: ShortIdValidateOptions): ShortIdValidateResult;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* expiring-token.ts
|
|
92
|
+
* Time-bound tokens with tamper-evident expiry encoding.
|
|
93
|
+
*
|
|
94
|
+
* Token format (base62-encoded, no separators):
|
|
95
|
+
* [8 chars: expiry epoch seconds in base62] + [random payload]
|
|
96
|
+
*
|
|
97
|
+
* The expiry is prepended to the random portion, then the whole thing
|
|
98
|
+
* is encoded so it looks like a uniform random string. A simple XOR
|
|
99
|
+
* checksum guards against accidental corruption (not cryptographic —
|
|
100
|
+
* use a signed JWT if you need HMAC-level tamper protection).
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const { token, expiresAt } = generateExpiringToken({ ttlSeconds: 900 });
|
|
104
|
+
* // later…
|
|
105
|
+
* const result = verifyToken(token);
|
|
106
|
+
* result.valid // true / false
|
|
107
|
+
* result.expiresAt // Date
|
|
108
|
+
* result.expired // boolean
|
|
109
|
+
*/
|
|
110
|
+
interface ExpiringTokenOptions {
|
|
111
|
+
/**
|
|
112
|
+
* How long (in seconds) before the token expires.
|
|
113
|
+
* @default 900 (15 minutes)
|
|
114
|
+
*/
|
|
115
|
+
ttlSeconds?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Length of the random payload (not counting the expiry prefix).
|
|
118
|
+
* Total token length = payloadLength + 8.
|
|
119
|
+
* @default 24
|
|
120
|
+
*/
|
|
121
|
+
payloadLength?: number;
|
|
122
|
+
}
|
|
123
|
+
interface ExpiringTokenResult {
|
|
124
|
+
/** The opaque token string to store / transmit. */
|
|
125
|
+
token: string;
|
|
126
|
+
/** When this token stops being valid. */
|
|
127
|
+
expiresAt: Date;
|
|
128
|
+
/** Total token length in characters. */
|
|
129
|
+
length: number;
|
|
130
|
+
}
|
|
131
|
+
interface TokenVerifyResult {
|
|
132
|
+
/** Whether the token is structurally valid AND not yet expired. */
|
|
133
|
+
valid: boolean;
|
|
134
|
+
/** Whether the token format could be parsed (regardless of expiry). */
|
|
135
|
+
parsed: boolean;
|
|
136
|
+
/** Whether the token has passed its expiry time. */
|
|
137
|
+
expired: boolean;
|
|
138
|
+
/** Expiry time, if the token could be parsed. */
|
|
139
|
+
expiresAt: Date | null;
|
|
140
|
+
/** Seconds remaining (negative if expired). */
|
|
141
|
+
secondsRemaining: number | null;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Generate a self-expiring token.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* // Password reset link (15 min)
|
|
148
|
+
* const { token } = generateExpiringToken({ ttlSeconds: 900 });
|
|
149
|
+
*
|
|
150
|
+
* // Magic login link (10 min), longer payload
|
|
151
|
+
* const { token, expiresAt } = generateExpiringToken({
|
|
152
|
+
* ttlSeconds: 600,
|
|
153
|
+
* payloadLength: 32,
|
|
154
|
+
* });
|
|
155
|
+
*/
|
|
156
|
+
declare function generateExpiringToken(options?: ExpiringTokenOptions): ExpiringTokenResult;
|
|
157
|
+
/**
|
|
158
|
+
* Verify an expiring token. Returns whether it's valid and unexpired.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* const result = verifyToken(token);
|
|
162
|
+
* if (!result.valid) {
|
|
163
|
+
* if (result.expired) throw new Error('Token expired');
|
|
164
|
+
* throw new Error('Invalid token');
|
|
165
|
+
* }
|
|
166
|
+
*/
|
|
167
|
+
declare function verifyToken(token: string): TokenVerifyResult;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* stream.ts
|
|
171
|
+
* Async generator (iterator) API for memory-efficient bulk generation.
|
|
172
|
+
*
|
|
173
|
+
* Unlike the `count` option (which allocates a Set of N strings upfront),
|
|
174
|
+
* the stream API yields strings one at a time — safe for generating
|
|
175
|
+
* hundreds of thousands of IDs without blowing the heap.
|
|
176
|
+
*
|
|
177
|
+
* @example Basic usage
|
|
178
|
+
* for await (const token of randomStringStream({ length: 24 })) {
|
|
179
|
+
* await db.insert({ token });
|
|
180
|
+
* }
|
|
181
|
+
* // Runs forever — break when done
|
|
182
|
+
*
|
|
183
|
+
* @example Generate exactly N
|
|
184
|
+
* import { take } from '@ppabari/strio';
|
|
185
|
+
* const ids = await take(randomStringStream({ length: 12 }), 10_000);
|
|
186
|
+
*
|
|
187
|
+
* @example Unique-only stream
|
|
188
|
+
* const stream = uniqueRandomStringStream({ length: 8, charset: 'base36' });
|
|
189
|
+
* for await (const id of stream) { ... }
|
|
190
|
+
*/
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Infinite async generator that yields random strings from the given options.
|
|
194
|
+
* Each value is independently generated (not deduplicated).
|
|
195
|
+
*
|
|
196
|
+
* Use `take()` or a `break` statement to stop the stream.
|
|
197
|
+
* For bulk operations, prefer `take(randomStringStream(opts), n)` over
|
|
198
|
+
* the `count` option — it avoids allocating a full Set upfront.
|
|
199
|
+
*/
|
|
200
|
+
declare function randomStringStream(options?: RandomStringOptions): AsyncGenerator<string, never, unknown>;
|
|
201
|
+
/**
|
|
202
|
+
* Infinite async generator that yields globally unique strings.
|
|
203
|
+
* Deduplication is maintained via an in-memory Set.
|
|
204
|
+
*
|
|
205
|
+
* ⚠️ Memory grows with consumption. For very large sets (>1M), consider
|
|
206
|
+
* a probabilistic structure (Bloom filter) or external dedup store instead.
|
|
207
|
+
*/
|
|
208
|
+
declare function uniqueRandomStringStream(options?: RandomStringOptions): AsyncGenerator<string, never, unknown>;
|
|
209
|
+
/**
|
|
210
|
+
* Collect the first `n` values from any async iterable into an array.
|
|
211
|
+
* Works with both `randomStringStream` and `uniqueRandomStringStream`.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const tokens = await take(randomStringStream({ length: 32 }), 500);
|
|
215
|
+
* // → string[] of 500 tokens
|
|
216
|
+
*/
|
|
217
|
+
declare function take<T>(iterable: AsyncIterable<T>, n: number): Promise<T[]>;
|
|
218
|
+
/**
|
|
219
|
+
* Like `take`, but filters values through a predicate.
|
|
220
|
+
* Pulls from the stream until `n` values satisfy `predicate`.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* // Get 10 tokens that start with a digit
|
|
224
|
+
* const tokens = await takeWhere(
|
|
225
|
+
* randomStringStream({ length: 12 }),
|
|
226
|
+
* 10,
|
|
227
|
+
* t => /^[0-9]/.test(t)
|
|
228
|
+
* );
|
|
229
|
+
*/
|
|
230
|
+
declare function takeWhere<T>(iterable: AsyncIterable<T>, n: number, predicate: (value: T) => boolean): Promise<T[]>;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* passphrase.ts
|
|
234
|
+
* Human-memorable passphrase generation using the EFF Large Wordlist.
|
|
235
|
+
*
|
|
236
|
+
* Each word is selected using cryptographically secure randomness.
|
|
237
|
+
* A 4-word passphrase gives ~51 bits of entropy; 6 words gives ~77 bits.
|
|
238
|
+
*
|
|
239
|
+
* The built-in wordlist is a curated 1296-word subset (6^4 = 1296) of the
|
|
240
|
+
* EFF Large Wordlist, suitable for 4-dice rolls. We use a 256-word subset
|
|
241
|
+
* here for bundle efficiency — for maximum entropy use the `customWords` option
|
|
242
|
+
* with the full EFF list.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* generatePassphrase()
|
|
246
|
+
* // → 'correct-horse-battery-staple'
|
|
247
|
+
*
|
|
248
|
+
* generatePassphrase({ words: 5, separator: ' ', capitalize: true })
|
|
249
|
+
* // → 'Correct Horse Battery Staple Fence'
|
|
250
|
+
*/
|
|
251
|
+
/**
|
|
252
|
+
* 512-word curated subset — common, unambiguous English words.
|
|
253
|
+
* Large enough for good entropy while keeping bundle size small.
|
|
254
|
+
* Each word is 3–8 characters, avoiding technical jargon and offensive terms.
|
|
255
|
+
*/
|
|
256
|
+
declare const WORD_LIST: readonly string[];
|
|
257
|
+
interface PassphraseOptions {
|
|
258
|
+
/**
|
|
259
|
+
* Number of words in the passphrase.
|
|
260
|
+
* More words = more entropy. 4 words ≈ 51 bits, 6 words ≈ 77 bits.
|
|
261
|
+
* @default 4
|
|
262
|
+
*/
|
|
263
|
+
words?: number;
|
|
264
|
+
/**
|
|
265
|
+
* Separator between words.
|
|
266
|
+
* @default '-'
|
|
267
|
+
*/
|
|
268
|
+
separator?: string;
|
|
269
|
+
/**
|
|
270
|
+
* Capitalize the first letter of each word.
|
|
271
|
+
* @default false
|
|
272
|
+
*/
|
|
273
|
+
capitalize?: boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Append a random digit to the end for services that require numbers.
|
|
276
|
+
* @default false
|
|
277
|
+
*/
|
|
278
|
+
appendDigit?: boolean;
|
|
279
|
+
/**
|
|
280
|
+
* Use a custom word list instead of the built-in list.
|
|
281
|
+
* Must contain at least 2 words.
|
|
282
|
+
*/
|
|
283
|
+
customWords?: readonly string[];
|
|
284
|
+
/**
|
|
285
|
+
* Prefix the passphrase with a fixed string.
|
|
286
|
+
*/
|
|
287
|
+
prefix?: string;
|
|
288
|
+
}
|
|
289
|
+
interface PassphraseResult {
|
|
290
|
+
/** The generated passphrase string. */
|
|
291
|
+
passphrase: string;
|
|
292
|
+
/** Number of words used. */
|
|
293
|
+
wordCount: number;
|
|
294
|
+
/** Entropy estimate in bits. */
|
|
295
|
+
entropyBits: number;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Generate a human-memorable passphrase from random dictionary words.
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* generatePassphrase()
|
|
302
|
+
* // → { passphrase: 'stone-river-proud-flame', wordCount: 4, entropyBits: 50.9 }
|
|
303
|
+
*
|
|
304
|
+
* generatePassphrase({ words: 5, separator: ' ', capitalize: true })
|
|
305
|
+
* // → { passphrase: 'Stone River Proud Flame Beach', wordCount: 5, entropyBits: 63.7 }
|
|
306
|
+
*/
|
|
307
|
+
declare function generatePassphrase(options?: PassphraseOptions): PassphraseResult;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* entropy.ts
|
|
311
|
+
* Estimate the Shannon entropy and strength of a random string configuration.
|
|
312
|
+
*/
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Estimates the entropy of strings generated by the given options.
|
|
316
|
+
*
|
|
317
|
+
* For pattern-based strings, each placeholder contributes independently.
|
|
318
|
+
* For length-based strings, entropy = log2(charsetSize) * effectiveLength.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* const e = estimateEntropy({ length: 32, uppercase: true, lowercase: true, numeric: true });
|
|
322
|
+
* console.log(e.bits); // ~190
|
|
323
|
+
* console.log(e.strength); // 'very-strong'
|
|
324
|
+
*/
|
|
325
|
+
declare function estimateEntropy(options?: RandomStringOptions): EntropyResult;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* validate.ts
|
|
329
|
+
* Validate that a string conforms to a given RandomStringOptions config.
|
|
330
|
+
*/
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Checks whether `str` satisfies the given validation rules.
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* const result = validateRandomString('abc123', {
|
|
337
|
+
* minLength: 6,
|
|
338
|
+
* requireNumeric: true,
|
|
339
|
+
* requireLowercase: true,
|
|
340
|
+
* });
|
|
341
|
+
* result.valid; // true
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* const result = validateRandomString('abc', { requireNumeric: true });
|
|
345
|
+
* result.valid; // false
|
|
346
|
+
* result.errors; // ['Must contain at least one numeric digit.']
|
|
347
|
+
*/
|
|
348
|
+
declare function validateRandomString(str: string, options?: ValidateOptions): ValidationResult;
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* charset-aliases.ts
|
|
352
|
+
* Named character set aliases for common encoding schemes.
|
|
353
|
+
* Pass any alias name as the `charset` option in generateRandomString.
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* import { generateRandomString, CHARSET_ALIASES } from '@ppabari/strio';
|
|
357
|
+
* generateRandomString({ charset: CHARSET_ALIASES.base58, length: 22 });
|
|
358
|
+
* // or via string shorthand:
|
|
359
|
+
* generateRandomString({ charset: 'base58', length: 22 });
|
|
360
|
+
*/
|
|
361
|
+
declare const CHARSET_ALIASES: Record<string, string>;
|
|
362
|
+
type CharsetAlias = keyof typeof CHARSET_ALIASES;
|
|
363
|
+
/**
|
|
364
|
+
* Resolve a charset value: if it matches a known alias, return the
|
|
365
|
+
* corresponding character string; otherwise return the value as-is.
|
|
366
|
+
*
|
|
367
|
+
* This is called inside buildCharset so alias names work transparently
|
|
368
|
+
* as the `charset` option.
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* resolveCharsetAlias('base58') // → '123456789ABCDEF...'
|
|
372
|
+
* resolveCharsetAlias('abc') // → 'abc'
|
|
373
|
+
*/
|
|
374
|
+
declare function resolveCharsetAlias(value: string): string;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* presets.ts
|
|
378
|
+
* Ready-to-use named presets for common use cases.
|
|
379
|
+
* Each preset is a plain `RandomStringOptions` object — pass it directly
|
|
380
|
+
* to `generateRandomString` or spread it to customise.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* import { generateRandomString, PRESETS } from 'secure-random-string';
|
|
384
|
+
* const token = generateRandomString(PRESETS.TOKEN);
|
|
385
|
+
* const longToken = generateRandomString({ ...PRESETS.TOKEN, length: 64 });
|
|
386
|
+
*/
|
|
387
|
+
declare const PRESETS: {
|
|
388
|
+
/**
|
|
389
|
+
* API token / session key.
|
|
390
|
+
* 32-char alphanumeric (no symbols), readable=false for max entropy.
|
|
391
|
+
* ~190 bits of entropy.
|
|
392
|
+
*/
|
|
393
|
+
readonly TOKEN: {
|
|
394
|
+
length: number;
|
|
395
|
+
numeric: true;
|
|
396
|
+
lowercase: true;
|
|
397
|
+
uppercase: true;
|
|
398
|
+
symbols: false;
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* Strong password.
|
|
402
|
+
* 20 chars, all character types including symbols.
|
|
403
|
+
* ~131 bits of entropy.
|
|
404
|
+
*/
|
|
405
|
+
readonly PASSWORD: {
|
|
406
|
+
length: number;
|
|
407
|
+
numeric: true;
|
|
408
|
+
lowercase: true;
|
|
409
|
+
uppercase: true;
|
|
410
|
+
symbols: true;
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* Human-readable token — no ambiguous characters (0/O/l/I/1).
|
|
414
|
+
* Safe to read aloud or transcribe from a screen.
|
|
415
|
+
* 16 chars, ~93 bits of entropy.
|
|
416
|
+
*/
|
|
417
|
+
readonly READABLE: {
|
|
418
|
+
length: number;
|
|
419
|
+
numeric: true;
|
|
420
|
+
lowercase: true;
|
|
421
|
+
uppercase: true;
|
|
422
|
+
symbols: false;
|
|
423
|
+
readable: true;
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* URL-safe slug identifier.
|
|
427
|
+
* Lowercase letters and digits only, starts with a letter.
|
|
428
|
+
* 12 chars, ~62 bits of entropy.
|
|
429
|
+
*/
|
|
430
|
+
readonly SLUG: {
|
|
431
|
+
length: number;
|
|
432
|
+
numeric: true;
|
|
433
|
+
lowercase: true;
|
|
434
|
+
uppercase: false;
|
|
435
|
+
symbols: false;
|
|
436
|
+
startWith: "alphabet";
|
|
437
|
+
};
|
|
438
|
+
/**
|
|
439
|
+
* Lowercase hex string.
|
|
440
|
+
* Compatible with UUID hex components, color codes, hash representations.
|
|
441
|
+
* 32 chars (128-bit equivalent), ~128 bits of entropy.
|
|
442
|
+
*/
|
|
443
|
+
readonly HEX: {
|
|
444
|
+
length: number;
|
|
445
|
+
charset: string;
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* Numeric PIN code. 6 digits, starts with a non-zero digit.
|
|
449
|
+
* ~17 bits of entropy — suitable for short-lived OTP codes.
|
|
450
|
+
*/
|
|
451
|
+
readonly PIN: {
|
|
452
|
+
length: number;
|
|
453
|
+
numeric: true;
|
|
454
|
+
lowercase: false;
|
|
455
|
+
uppercase: false;
|
|
456
|
+
symbols: false;
|
|
457
|
+
exclude: string;
|
|
458
|
+
startWith: "numeric";
|
|
459
|
+
};
|
|
460
|
+
/**
|
|
461
|
+
* UUID-like string (not RFC 4122 compliant, but same visual format).
|
|
462
|
+
* Uses `pattern` to produce 8-4-4-4-12 hex grouping.
|
|
463
|
+
* ~122 bits of entropy (same as UUIDv4).
|
|
464
|
+
*/
|
|
465
|
+
readonly UUID_LIKE: {
|
|
466
|
+
pattern: string;
|
|
467
|
+
charset: string;
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Short alphanumeric ID — suitable for database record IDs.
|
|
471
|
+
* 8 chars, uppercase alphanumeric, starts with a letter.
|
|
472
|
+
* ~41 bits — good for IDs when combined with a namespace/prefix.
|
|
473
|
+
*/
|
|
474
|
+
readonly SHORT_ID: {
|
|
475
|
+
length: number;
|
|
476
|
+
numeric: true;
|
|
477
|
+
lowercase: false;
|
|
478
|
+
uppercase: true;
|
|
479
|
+
symbols: false;
|
|
480
|
+
startWith: "alphabet";
|
|
481
|
+
};
|
|
482
|
+
/**
|
|
483
|
+
* Invitation / redemption code.
|
|
484
|
+
* 16 chars, readable (no ambiguous chars), pattern grouped for readability.
|
|
485
|
+
* @example 'KXPZ-9MR2-LQ4Y-8WVN'
|
|
486
|
+
*/
|
|
487
|
+
readonly INVITE_CODE: {
|
|
488
|
+
pattern: string;
|
|
489
|
+
readable: true;
|
|
490
|
+
};
|
|
491
|
+
};
|
|
492
|
+
type PresetName = keyof typeof PRESETS;
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* secrets.ts
|
|
496
|
+
* Cryptographic secret and key generation utilities.
|
|
497
|
+
*
|
|
498
|
+
* Covers the full lifecycle of secrets used in real applications:
|
|
499
|
+
* - Raw bytes → generateBytes()
|
|
500
|
+
* - Hex keys (AES, ChaCha20) → generateHexKey()
|
|
501
|
+
* - Base64 keys (cloud imports) → generateBase64Key()
|
|
502
|
+
* - JWT secrets (HS256/384/512) → generateJwtSecret()
|
|
503
|
+
* - Structured API keys → generateApiKey()
|
|
504
|
+
* - Numeric OTP codes → generateOtp()
|
|
505
|
+
* - Secret masking for logs → maskSecret()
|
|
506
|
+
* - Constant-time comparison → timingSafeEqual()
|
|
507
|
+
* - Framework secret helpers → generateCookieSecret() etc.
|
|
508
|
+
*
|
|
509
|
+
* All functions use crypto.getRandomValues() — the same bias-free
|
|
510
|
+
* engine as the rest of strio.
|
|
511
|
+
*/
|
|
512
|
+
/**
|
|
513
|
+
* Generate `n` cryptographically secure random bytes.
|
|
514
|
+
* Returns a `Uint8Array` — the native format accepted by Web Crypto,
|
|
515
|
+
* Node's `crypto`, and virtually every encryption library.
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* const key = generateBytes(32); // 32-byte (256-bit) key material
|
|
519
|
+
* await crypto.subtle.importKey('raw', key, 'AES-GCM', false, ['encrypt']);
|
|
520
|
+
*
|
|
521
|
+
* const iv = generateBytes(12); // AES-GCM initialisation vector
|
|
522
|
+
* const nonce = generateBytes(24); // XSalsa20 nonce
|
|
523
|
+
*/
|
|
524
|
+
declare function generateBytes(length: number): Uint8Array;
|
|
525
|
+
/**
|
|
526
|
+
* Generate a random key of `bits` length, returned as a lowercase hex string.
|
|
527
|
+
* The standard format for raw key material in most Node.js crypto libraries,
|
|
528
|
+
* Redis ACL passwords, database encryption keys, and many cloud services.
|
|
529
|
+
*
|
|
530
|
+
* @param bits - Key size in bits. Must be a positive multiple of 8.
|
|
531
|
+
* Common values: 128, 192, 256 (AES), 512 (HMAC-SHA512).
|
|
532
|
+
*
|
|
533
|
+
* @example
|
|
534
|
+
* generateHexKey(256) // → 64-char hex (AES-256 key)
|
|
535
|
+
* generateHexKey(128) // → 32-char hex (AES-128 key)
|
|
536
|
+
* generateHexKey(512) // → 128-char hex (HMAC-SHA512 key)
|
|
537
|
+
*
|
|
538
|
+
* // Use directly with Node crypto:
|
|
539
|
+
* const key = generateHexKey(256);
|
|
540
|
+
* const cipher = crypto.createCipheriv('aes-256-gcm', Buffer.from(key, 'hex'), iv);
|
|
541
|
+
*/
|
|
542
|
+
declare function generateHexKey(bits?: number): string;
|
|
543
|
+
type Base64Variant = 'standard' | 'url-safe' | 'url-safe-no-pad';
|
|
544
|
+
/**
|
|
545
|
+
* Generate a random key of `bits` length, returned as a base64 string.
|
|
546
|
+
*
|
|
547
|
+
* Three variants:
|
|
548
|
+
* - `'standard'` — includes `+`, `/`, `=` padding (AWS, most CLIs)
|
|
549
|
+
* - `'url-safe'` — replaces `+`→`-`, `/`→`_`, keeps `=` (cookies, headers)
|
|
550
|
+
* - `'url-safe-no-pad'` — same but no `=` padding (JWT, URL query params)
|
|
551
|
+
*
|
|
552
|
+
* @param bits - Key size in bits. Must be a positive multiple of 8.
|
|
553
|
+
* @param variant - Output encoding variant. Default: `'url-safe-no-pad'`.
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* generateBase64Key(256) // → url-safe, no padding (default)
|
|
557
|
+
* generateBase64Key(256, 'standard') // → standard base64 with padding
|
|
558
|
+
* generateBase64Key(256, 'url-safe') // → url-safe with padding
|
|
559
|
+
*
|
|
560
|
+
* // AWS KMS / GCP import format:
|
|
561
|
+
* const keyMaterial = generateBase64Key(256, 'standard');
|
|
562
|
+
*
|
|
563
|
+
* // Cookie signing secret (express-session, iron-session):
|
|
564
|
+
* const secret = generateBase64Key(256, 'url-safe-no-pad');
|
|
565
|
+
*/
|
|
566
|
+
declare function generateBase64Key(bits?: number, variant?: Base64Variant): string;
|
|
567
|
+
type JwtAlgorithm = 'HS256' | 'HS384' | 'HS512';
|
|
568
|
+
type JwtSecretFormat = 'base64url' | 'hex' | 'utf8-like';
|
|
569
|
+
interface JwtSecretOptions {
|
|
570
|
+
/**
|
|
571
|
+
* HMAC algorithm this secret will be used with.
|
|
572
|
+
* Determines the minimum key length enforced automatically.
|
|
573
|
+
* @default 'HS256'
|
|
574
|
+
*/
|
|
575
|
+
algorithm?: JwtAlgorithm;
|
|
576
|
+
/**
|
|
577
|
+
* Output format.
|
|
578
|
+
* - `'base64url'` — RFC 4648 §5, no padding. Default. Works with jsonwebtoken,
|
|
579
|
+
* jose, @auth/core, NextAuth, Fastify JWT, Lucia.
|
|
580
|
+
* - `'hex'` — lowercase hex. Works with jose when you import as `'oct'`.
|
|
581
|
+
* - `'utf8-like'` — base62 string. Usable directly as a string secret in older
|
|
582
|
+
* libraries that accept plain strings (not recommended for new code).
|
|
583
|
+
* @default 'base64url'
|
|
584
|
+
*/
|
|
585
|
+
format?: JwtSecretFormat;
|
|
586
|
+
/**
|
|
587
|
+
* Override the key size in bits. Must be ≥ the algorithm minimum.
|
|
588
|
+
* Defaults to the algorithm's minimum (256 / 384 / 512).
|
|
589
|
+
*/
|
|
590
|
+
bits?: number;
|
|
591
|
+
}
|
|
592
|
+
interface JwtSecretResult {
|
|
593
|
+
/** The secret value — pass this to your JWT library. */
|
|
594
|
+
secret: string;
|
|
595
|
+
/** Algorithm this secret was generated for. */
|
|
596
|
+
algorithm: JwtAlgorithm;
|
|
597
|
+
/** Actual key size in bits. */
|
|
598
|
+
bits: number;
|
|
599
|
+
/** Output format. */
|
|
600
|
+
format: JwtSecretFormat;
|
|
601
|
+
/**
|
|
602
|
+
* Usage example string for the most common library (jsonwebtoken).
|
|
603
|
+
* Handy for logging/debugging during setup.
|
|
604
|
+
*/
|
|
605
|
+
example: string;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Generate a cryptographically secure JWT signing secret.
|
|
609
|
+
*
|
|
610
|
+
* Enforces RFC 7518 minimum key lengths:
|
|
611
|
+
* - HS256 → minimum 256 bits (32 bytes)
|
|
612
|
+
* - HS384 → minimum 384 bits (48 bytes)
|
|
613
|
+
* - HS512 → minimum 512 bits (64 bytes)
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* // Default — HS256, base64url
|
|
617
|
+
* const { secret } = generateJwtSecret();
|
|
618
|
+
* jwt.sign(payload, secret, { algorithm: 'HS256' });
|
|
619
|
+
*
|
|
620
|
+
* // HS512 for maximum security
|
|
621
|
+
* const { secret } = generateJwtSecret({ algorithm: 'HS512' });
|
|
622
|
+
*
|
|
623
|
+
* // For jose / @auth/core
|
|
624
|
+
* const { secret } = generateJwtSecret({ algorithm: 'HS256', format: 'base64url' });
|
|
625
|
+
* // Set as AUTH_SECRET env var for NextAuth v5
|
|
626
|
+
*
|
|
627
|
+
* // For libraries expecting hex
|
|
628
|
+
* const { secret } = generateJwtSecret({ format: 'hex' });
|
|
629
|
+
*/
|
|
630
|
+
declare function generateJwtSecret(options?: JwtSecretOptions): JwtSecretResult;
|
|
631
|
+
interface ApiKeyOptions {
|
|
632
|
+
/**
|
|
633
|
+
* Key type prefix, e.g. `'sk'` (secret key), `'pk'` (public key), `'tok'`.
|
|
634
|
+
* @default 'sk'
|
|
635
|
+
*/
|
|
636
|
+
type?: string;
|
|
637
|
+
/**
|
|
638
|
+
* Environment prefix, e.g. `'live'`, `'test'`, `'dev'`.
|
|
639
|
+
* Omit to produce a key with no environment segment.
|
|
640
|
+
*/
|
|
641
|
+
environment?: 'live' | 'test' | 'dev' | string;
|
|
642
|
+
/**
|
|
643
|
+
* Entropy of the random portion in bits.
|
|
644
|
+
* @default 256
|
|
645
|
+
*/
|
|
646
|
+
bits?: number;
|
|
647
|
+
/**
|
|
648
|
+
* Charset for the random portion.
|
|
649
|
+
* @default 'base62'
|
|
650
|
+
*/
|
|
651
|
+
charset?: 'base62' | 'base58' | 'hex' | string;
|
|
652
|
+
/**
|
|
653
|
+
* Separator between segments.
|
|
654
|
+
* @default '_'
|
|
655
|
+
*/
|
|
656
|
+
separator?: string;
|
|
657
|
+
}
|
|
658
|
+
interface ApiKeyResult {
|
|
659
|
+
/** The full API key string. */
|
|
660
|
+
key: string;
|
|
661
|
+
/** The prefix segment, e.g. `'sk_live'`. */
|
|
662
|
+
prefix: string;
|
|
663
|
+
/** Character count of the random portion (not including prefix or separator). */
|
|
664
|
+
randomLength: number;
|
|
665
|
+
/** Entropy of the random portion in bits. */
|
|
666
|
+
bits: number;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Generate a structured API key in the style of Stripe, GitHub, or OpenAI.
|
|
670
|
+
*
|
|
671
|
+
* Format: `{type}_{environment}_{randomPortion}`
|
|
672
|
+
* e.g. `strio_live_K3xP9mQr2LzYw7NvTq8sHfGbJ5cD4eAK3xP9mQr2LzY`
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* generateApiKey()
|
|
676
|
+
* // → { key: 'strio_live_K3xP9mQr2LzYw7Nv...', prefix: 'sk_live', ... }
|
|
677
|
+
*
|
|
678
|
+
* generateApiKey({ type: 'sk', environment: 'test', bits: 256 })
|
|
679
|
+
* // → 'strio_test_K3xP9mQr...'
|
|
680
|
+
*
|
|
681
|
+
* generateApiKey({ type: 'tok', bits: 128 })
|
|
682
|
+
* // → 'tok_K3xP9mQr2LzYw7Nv'
|
|
683
|
+
*
|
|
684
|
+
* generateApiKey({ type: 'pk', environment: 'live', charset: 'hex' })
|
|
685
|
+
* // → 'pub_live_a3f7c2b9...'
|
|
686
|
+
*/
|
|
687
|
+
declare function generateApiKey(options?: ApiKeyOptions): ApiKeyResult;
|
|
688
|
+
interface OtpOptions {
|
|
689
|
+
/**
|
|
690
|
+
* Number of digits in the OTP.
|
|
691
|
+
* @default 6
|
|
692
|
+
*/
|
|
693
|
+
digits?: number;
|
|
694
|
+
/**
|
|
695
|
+
* Whether to allow a leading zero.
|
|
696
|
+
* Set to `false` to ensure the first digit is 1–9 (e.g. for display in SMS).
|
|
697
|
+
* @default true
|
|
698
|
+
*/
|
|
699
|
+
allowLeadingZero?: boolean;
|
|
700
|
+
}
|
|
701
|
+
interface OtpResult {
|
|
702
|
+
/** The OTP as a zero-padded string (e.g. `'048392'`). */
|
|
703
|
+
code: string;
|
|
704
|
+
/** The OTP as a number (e.g. `48392`). */
|
|
705
|
+
value: number;
|
|
706
|
+
/** Number of digits. */
|
|
707
|
+
digits: number;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Generate a cryptographically secure numeric OTP (one-time password).
|
|
711
|
+
* Uses modular arithmetic on a secure random integer — no modulo bias
|
|
712
|
+
* for digit counts up to 9 (10^9 < 2^30 < 2^32, safe in float64).
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* generateOtp() // → { code: '483920', value: 483920, digits: 6 }
|
|
716
|
+
* generateOtp({ digits: 8 }) // → { code: '04839201', value: 4839201, digits: 8 }
|
|
717
|
+
*
|
|
718
|
+
* // SMS-friendly (no leading zero)
|
|
719
|
+
* generateOtp({ allowLeadingZero: false })
|
|
720
|
+
*
|
|
721
|
+
* // Use just the code string
|
|
722
|
+
* const { code } = generateOtp();
|
|
723
|
+
* await sms.send(phone, `Your code is ${code}`);
|
|
724
|
+
*/
|
|
725
|
+
declare function generateOtp(options?: OtpOptions): OtpResult;
|
|
726
|
+
interface MaskSecretOptions {
|
|
727
|
+
/**
|
|
728
|
+
* Number of characters to reveal at the start of the secret.
|
|
729
|
+
* `0` reveals nothing (prefix only).
|
|
730
|
+
* @default 0 (show prefix only, mask everything else)
|
|
731
|
+
*/
|
|
732
|
+
visibleStart?: number;
|
|
733
|
+
/**
|
|
734
|
+
* Number of characters to reveal at the end.
|
|
735
|
+
* @default 4
|
|
736
|
+
*/
|
|
737
|
+
visibleEnd?: number;
|
|
738
|
+
/**
|
|
739
|
+
* Character used to mask the hidden portion.
|
|
740
|
+
* @default '*'
|
|
741
|
+
*/
|
|
742
|
+
maskChar?: string;
|
|
743
|
+
/**
|
|
744
|
+
* Minimum number of mask characters shown, regardless of secret length.
|
|
745
|
+
* Prevents inferring length from short secrets.
|
|
746
|
+
* @default 4
|
|
747
|
+
*/
|
|
748
|
+
minMaskLength?: number;
|
|
749
|
+
/**
|
|
750
|
+
* Maximum mask characters shown (caps a very long mask).
|
|
751
|
+
* @default 8
|
|
752
|
+
*/
|
|
753
|
+
maxMaskLength?: number;
|
|
754
|
+
/**
|
|
755
|
+
* Known prefix segments to preserve literally before masking begins.
|
|
756
|
+
* e.g. `['strio_live_', 'strio_test_']` — the prefix is kept, the rest is masked.
|
|
757
|
+
* If the secret starts with one of these, the prefix is shown and
|
|
758
|
+
* `visibleStart` is counted from after the prefix.
|
|
759
|
+
*/
|
|
760
|
+
knownPrefixes?: string[];
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Mask a secret string for safe logging, display, or debugging.
|
|
764
|
+
* Preserves enough context to identify the key without exposing it.
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* maskSecret('myapp_live_K3xP9mQr2LzYw7NvTq8sHfGb')
|
|
768
|
+
* // → 'strio_live_****...w7Nv' (auto-detects 'strio_live_' prefix)
|
|
769
|
+
*
|
|
770
|
+
* maskSecret('supersecretpassword')
|
|
771
|
+
* // → '****...word'
|
|
772
|
+
*
|
|
773
|
+
* maskSecret('eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.abc123')
|
|
774
|
+
* // → '****...123'
|
|
775
|
+
*
|
|
776
|
+
* // Custom reveal
|
|
777
|
+
* maskSecret('myapp_live_K3xP9mQr2LzY', { visibleEnd: 6 })
|
|
778
|
+
* // → 'strio_live_****...LzY'
|
|
779
|
+
*/
|
|
780
|
+
declare function maskSecret(secret: string, options?: MaskSecretOptions): string;
|
|
781
|
+
/**
|
|
782
|
+
* Compare two strings or byte arrays in constant time.
|
|
783
|
+
* Prevents timing attacks where an attacker infers secret content by
|
|
784
|
+
* measuring how long a comparison takes.
|
|
785
|
+
*
|
|
786
|
+
* **Always use this instead of `===` when comparing tokens, secrets,
|
|
787
|
+
* HMAC signatures, or any security-sensitive value.**
|
|
788
|
+
*
|
|
789
|
+
* The comparison time is proportional to `max(a.length, b.length)` —
|
|
790
|
+
* it does not short-circuit on mismatch.
|
|
791
|
+
*
|
|
792
|
+
* @returns `true` if the values are identical, `false` otherwise.
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* // Comparing incoming token against stored token
|
|
796
|
+
* if (!timingSafeEqual(incomingToken, storedToken)) {
|
|
797
|
+
* throw new Error('Invalid token');
|
|
798
|
+
* }
|
|
799
|
+
*
|
|
800
|
+
* // Also works with Uint8Array (e.g. HMAC comparison)
|
|
801
|
+
* const valid = timingSafeEqual(computedHmac, expectedHmac);
|
|
802
|
+
*/
|
|
803
|
+
declare function timingSafeEqual(a: string | Uint8Array, b: string | Uint8Array): boolean;
|
|
804
|
+
/**
|
|
805
|
+
* Generate a cookie signing secret for session libraries.
|
|
806
|
+
*
|
|
807
|
+
* Compatible with:
|
|
808
|
+
* - express-session (`secret` option)
|
|
809
|
+
* - iron-session (`password` option)
|
|
810
|
+
* - lucia (`sessionCookieOptions.password`)
|
|
811
|
+
* - cookie-signature
|
|
812
|
+
*
|
|
813
|
+
* Returns a 256-bit base64url string by default — long enough to resist
|
|
814
|
+
* brute force while remaining pasteable in .env files.
|
|
815
|
+
*
|
|
816
|
+
* @example
|
|
817
|
+
* // express-session
|
|
818
|
+
* app.use(session({ secret: generateCookieSecret() }));
|
|
819
|
+
*
|
|
820
|
+
* // iron-session
|
|
821
|
+
* const sessionOptions = { password: generateCookieSecret(), cookieName: 'session' };
|
|
822
|
+
*
|
|
823
|
+
* // .env usage
|
|
824
|
+
* console.log(`COOKIE_SECRET="${generateCookieSecret()}"`);
|
|
825
|
+
*/
|
|
826
|
+
declare function generateCookieSecret(bits?: number): string;
|
|
827
|
+
/**
|
|
828
|
+
* Generate an encryption key suitable for AES-GCM or AES-CBC.
|
|
829
|
+
*
|
|
830
|
+
* @param keySize - `128`, `192`, or `256` bits. Default: 256.
|
|
831
|
+
* @param format - `'hex'` (default) or `'base64'` or `'bytes'`.
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* generateAesKey() // → 64-char hex (AES-256)
|
|
835
|
+
* generateAesKey(128) // → 32-char hex (AES-128)
|
|
836
|
+
* generateAesKey(256, 'base64') // → base64url string
|
|
837
|
+
* generateAesKey(256, 'bytes') // → Uint8Array
|
|
838
|
+
*/
|
|
839
|
+
declare function generateAesKey(keySize?: 128 | 192 | 256, format?: 'hex' | 'base64' | 'bytes'): string | Uint8Array;
|
|
840
|
+
/**
|
|
841
|
+
* Generate a secret for Next.js / NextAuth / Auth.js.
|
|
842
|
+
* Sets AUTH_SECRET in your .env file — used to sign JWTs and cookies.
|
|
843
|
+
* Output matches what `npx auth secret` generates.
|
|
844
|
+
*
|
|
845
|
+
* @example
|
|
846
|
+
* const secret = generateNextAuthSecret();
|
|
847
|
+
* console.log(`AUTH_SECRET="${secret}"`);
|
|
848
|
+
*/
|
|
849
|
+
declare function generateNextAuthSecret(): string;
|
|
850
|
+
/**
|
|
851
|
+
* Generate a Django SECRET_KEY compatible string.
|
|
852
|
+
* Django expects a long random string of printable ASCII characters —
|
|
853
|
+
* at least 50 characters, no restrictions beyond that.
|
|
854
|
+
*
|
|
855
|
+
* @example
|
|
856
|
+
* const key = generateDjangoSecretKey();
|
|
857
|
+
* console.log(`SECRET_KEY="${key}"`);
|
|
858
|
+
*/
|
|
859
|
+
declare function generateDjangoSecretKey(): string;
|
|
860
|
+
/**
|
|
861
|
+
* Generate a Rails / rack secret_key_base compatible string.
|
|
862
|
+
* Rails expects a 128+ character hex string for its key base.
|
|
863
|
+
*
|
|
864
|
+
* @example
|
|
865
|
+
* const key = generateRailsSecretKeyBase();
|
|
866
|
+
* console.log(`SECRET_KEY_BASE="${key}"`);
|
|
867
|
+
*/
|
|
868
|
+
declare function generateRailsSecretKeyBase(): string;
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* @ppabari/strio
|
|
872
|
+
*
|
|
873
|
+
* Cryptographically secure string generation for Node.js and browsers.
|
|
874
|
+
* Zero dependencies. Fully typed. Bias-free.
|
|
875
|
+
*/
|
|
876
|
+
|
|
877
|
+
declare function generateRandomString(options?: RandomStringOptions & {
|
|
878
|
+
count?: 1;
|
|
879
|
+
}): string;
|
|
880
|
+
declare function generateRandomString(options: RandomStringOptions & {
|
|
881
|
+
count: number;
|
|
882
|
+
}): string[];
|
|
883
|
+
declare function generateRandomStringAsync(options?: RandomStringOptions): Promise<string | string[]>;
|
|
884
|
+
|
|
885
|
+
export { type ApiKeyOptions, type ApiKeyResult, WORD_LIST as BUILT_IN_WORD_LIST, type Base64Variant, CHARSET_ALIASES, type CharsetAlias, EntropyResult, type ExpiringTokenOptions, type ExpiringTokenResult, type JwtAlgorithm, type JwtSecretFormat, type JwtSecretOptions, type JwtSecretResult, type MaskSecretOptions, type OtpOptions, type OtpResult, PRESETS, type PassphraseOptions, type PassphraseResult, type PresetName, RandomStringOptions, type ShortIdOptions, type ShortIdValidateOptions, type ShortIdValidateResult, type TokenVerifyResult, ValidateOptions, ValidationResult, estimateEntropy, generateAesKey, generateApiKey, generateBase64Key, generateBytes, generateCookieSecret, generateDjangoSecretKey, generateExpiringToken, generateHexKey, generateId, generateJwtSecret, generateNextAuthSecret, generateOtp, generatePassphrase, generateRailsSecretKeyBase, generateRandomString, generateRandomStringAsync, maskSecret, randomStringStream, resolveCharsetAlias, take, takeWhere, timingSafeEqual, uniqueRandomStringStream, validateId, validateRandomString, verifyToken };
|