@ix-xs/node-comfort 1.1.31 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +190 -0
  2. package/LICENSE +21 -0
  3. package/README.md +210 -748
  4. package/index.js +84 -13
  5. package/package.json +201 -21
  6. package/src/Arr.js +901 -0
  7. package/src/Async.js +585 -0
  8. package/src/Cache.js +329 -0
  9. package/src/Checker.js +979 -188
  10. package/src/Cli.js +1034 -0
  11. package/src/Color.js +415 -0
  12. package/src/Crypto.js +707 -0
  13. package/src/Emitter.js +289 -0
  14. package/src/Env.js +555 -0
  15. package/src/FS.js +1483 -768
  16. package/src/Func.js +692 -0
  17. package/src/Http.js +538 -0
  18. package/src/Id.js +418 -0
  19. package/src/Logger.js +739 -307
  20. package/src/Num.js +849 -0
  21. package/src/Obj.js +904 -0
  22. package/src/SQLite.js +1308 -994
  23. package/src/Schema.js +1586 -0
  24. package/src/Str.js +999 -0
  25. package/src/Sys.js +511 -0
  26. package/src/Time.js +1323 -0
  27. package/src/Utils.js +321 -325
  28. package/src/errors.js +292 -0
  29. package/types/index.d.ts +693 -120
  30. package/types/src/Arr.d.ts +562 -0
  31. package/types/src/Arr.d.ts.map +1 -0
  32. package/types/src/Async.d.ts +321 -0
  33. package/types/src/Async.d.ts.map +1 -0
  34. package/types/src/Cache.d.ts +195 -0
  35. package/types/src/Cache.d.ts.map +1 -0
  36. package/types/src/Checker.d.ts +609 -81
  37. package/types/src/Checker.d.ts.map +1 -1
  38. package/types/src/Cli.d.ts +582 -0
  39. package/types/src/Cli.d.ts.map +1 -0
  40. package/types/src/Color.d.ts +294 -0
  41. package/types/src/Color.d.ts.map +1 -0
  42. package/types/src/Crypto.d.ts +534 -0
  43. package/types/src/Crypto.d.ts.map +1 -0
  44. package/types/src/Emitter.d.ts +170 -0
  45. package/types/src/Emitter.d.ts.map +1 -0
  46. package/types/src/Env.d.ts +382 -0
  47. package/types/src/Env.d.ts.map +1 -0
  48. package/types/src/FS.d.ts +709 -201
  49. package/types/src/FS.d.ts.map +1 -1
  50. package/types/src/Func.d.ts +455 -0
  51. package/types/src/Func.d.ts.map +1 -0
  52. package/types/src/Http.d.ts +374 -0
  53. package/types/src/Http.d.ts.map +1 -0
  54. package/types/src/Id.d.ts +200 -0
  55. package/types/src/Id.d.ts.map +1 -0
  56. package/types/src/Logger.d.ts +374 -24
  57. package/types/src/Logger.d.ts.map +1 -1
  58. package/types/src/Num.d.ts +578 -0
  59. package/types/src/Num.d.ts.map +1 -0
  60. package/types/src/Obj.d.ts +475 -0
  61. package/types/src/Obj.d.ts.map +1 -0
  62. package/types/src/SQLite.d.ts +647 -305
  63. package/types/src/SQLite.d.ts.map +1 -1
  64. package/types/src/Schema.d.ts +940 -0
  65. package/types/src/Schema.d.ts.map +1 -0
  66. package/types/src/Str.d.ts +696 -0
  67. package/types/src/Str.d.ts.map +1 -0
  68. package/types/src/Sys.d.ts +269 -0
  69. package/types/src/Sys.d.ts.map +1 -0
  70. package/types/src/Time.d.ts +664 -0
  71. package/types/src/Time.d.ts.map +1 -0
  72. package/types/src/Utils.d.ts +154 -102
  73. package/types/src/Utils.d.ts.map +1 -1
  74. package/types/src/errors.d.ts +292 -0
  75. package/types/src/errors.d.ts.map +1 -0
  76. package/tsconfig.json +0 -18
  77. package/types/index.d.ts.map +0 -1
@@ -0,0 +1,534 @@
1
+ /**
2
+ * Text encodings for digests.
3
+ */
4
+ export type DigestEncoding = "hex" | "base64" | "base64url";
5
+ /**
6
+ * Options for `hash()` and `hmac()`.
7
+ */
8
+ export type HashOptions = {
9
+ /**
10
+ * Any algorithm OpenSSL supports. Defaults to `"sha256"`.
11
+ */
12
+ algorithm?: (string & {}) | "sha256" | "sha384" | "sha512" | "sha1" | "md5" | "sha3-256" | "sha3-512" | undefined;
13
+ /**
14
+ * Defaults to `"hex"`.
15
+ */
16
+ encoding?: DigestEncoding | undefined;
17
+ };
18
+ /**
19
+ * Options for `hashPassword()`.
20
+ */
21
+ export type HashPasswordOptions = {
22
+ /**
23
+ * Work factor as a power of two; each +1 doubles the time. Defaults to `15`.
24
+ */
25
+ cost?: number | undefined;
26
+ /**
27
+ * scrypt `r`. Defaults to `8`.
28
+ */
29
+ blockSize?: number | undefined;
30
+ /**
31
+ * scrypt `p`. Defaults to `1`.
32
+ */
33
+ parallelization?: number | undefined;
34
+ /**
35
+ * In bytes. Defaults to `16`.
36
+ */
37
+ saltLength?: number | undefined;
38
+ /**
39
+ * In bytes. Defaults to `32`.
40
+ */
41
+ keyLength?: number | undefined;
42
+ };
43
+ /**
44
+ * Options for `encrypt()`.
45
+ */
46
+ export type EncryptOptions = {
47
+ /**
48
+ * Data that's authenticated but not encrypted, like a user id. Pass the same value to `decrypt()`.
49
+ */
50
+ associatedData?: string | Buffer<ArrayBufferLike> | undefined;
51
+ };
52
+ /**
53
+ * Options for `decrypt()`.
54
+ */
55
+ export type DecryptOptions = {
56
+ /**
57
+ * The value given to `encrypt()`, if any.
58
+ */
59
+ associatedData?: string | Buffer<ArrayBufferLike> | undefined;
60
+ /**
61
+ * Get a string or a `Buffer`. Defaults to `"utf8"`.
62
+ */
63
+ output?: "utf8" | "buffer" | undefined;
64
+ };
65
+ /**
66
+ * Standard JWT claims.
67
+ */
68
+ export type JWTClaims = {
69
+ /**
70
+ * Issuer.
71
+ */
72
+ iss?: string | undefined;
73
+ /**
74
+ * Subject, usually the user id.
75
+ */
76
+ sub?: string | undefined;
77
+ /**
78
+ * Audience.
79
+ */
80
+ aud?: string | string[] | undefined;
81
+ /**
82
+ * Expiry, in Unix seconds.
83
+ */
84
+ exp?: number | undefined;
85
+ /**
86
+ * Not valid before, in Unix seconds.
87
+ */
88
+ nbf?: number | undefined;
89
+ /**
90
+ * Issued at, in Unix seconds.
91
+ */
92
+ iat?: number | undefined;
93
+ /**
94
+ * Unique token id.
95
+ */
96
+ jti?: string | undefined;
97
+ };
98
+ /**
99
+ * Supported JWT algorithms.
100
+ */
101
+ export type JWTAlgorithm = "HS256" | "HS384" | "HS512";
102
+ /**
103
+ * Options for `signJWT()`.
104
+ */
105
+ export type SignJWTOptions = {
106
+ /**
107
+ * Defaults to `"HS256"`.
108
+ */
109
+ algorithm?: JWTAlgorithm | undefined;
110
+ /**
111
+ * Lifetime in seconds or as a duration like `"15m"`. Sets `exp`.
112
+ */
113
+ expiresIn?: string | number | undefined;
114
+ /**
115
+ * Delay before the token is valid. Sets `nbf`.
116
+ */
117
+ notBefore?: string | number | undefined;
118
+ /**
119
+ * Sets `iss`.
120
+ */
121
+ issuer?: string | undefined;
122
+ /**
123
+ * Sets `sub`.
124
+ */
125
+ subject?: string | undefined;
126
+ /**
127
+ * Sets `aud`.
128
+ */
129
+ audience?: string | string[] | undefined;
130
+ /**
131
+ * Sets `jti`, handy for revocation lists.
132
+ */
133
+ jwtId?: string | undefined;
134
+ /**
135
+ * Don't add `iat`.
136
+ */
137
+ noTimestamp?: boolean | undefined;
138
+ /**
139
+ * Extra header fields, like `{ kid: "2024-key" }`.
140
+ */
141
+ header?: Record<string, unknown> | undefined;
142
+ };
143
+ /**
144
+ * Options for `verifyJWT()`.
145
+ */
146
+ export type VerifyJWTOptions = {
147
+ /**
148
+ * Accepted algorithms. Defaults to all three HMAC ones.
149
+ */
150
+ algorithms?: JWTAlgorithm[] | undefined;
151
+ /**
152
+ * Required issuer.
153
+ */
154
+ issuer?: string | string[] | undefined;
155
+ /**
156
+ * Required audience; one match is enough.
157
+ */
158
+ audience?: string | string[] | undefined;
159
+ /**
160
+ * Required subject.
161
+ */
162
+ subject?: string | undefined;
163
+ /**
164
+ * Seconds of slack for `exp` and `nbf` when server clocks differ.
165
+ */
166
+ clockTolerance?: number | undefined;
167
+ /**
168
+ * Reject tokens issued longer ago than this.
169
+ */
170
+ maxAge?: string | number | undefined;
171
+ /**
172
+ * Skip the `exp` check.
173
+ */
174
+ ignoreExpiration?: boolean | undefined;
175
+ /**
176
+ * What time it is. Defaults to now.
177
+ */
178
+ now?: number | Date | undefined;
179
+ };
180
+ /**
181
+ * A decoded JWT.
182
+ */
183
+ export type DecodedJWT<P = Record<string, unknown>> = {
184
+ header: {
185
+ alg: string;
186
+ typ?: string;
187
+ [key: string]: unknown;
188
+ };
189
+ payload: P & JWTClaims;
190
+ /**
191
+ * Base64URL.
192
+ */
193
+ signature: string;
194
+ };
195
+ /**
196
+ * Options for `totp()` and `verifyTOTP()`.
197
+ */
198
+ export type TOTPOptions = {
199
+ /**
200
+ * Defaults to `6`.
201
+ */
202
+ digits?: number | undefined;
203
+ /**
204
+ * How long a code lasts, in seconds. Defaults to `30`.
205
+ */
206
+ period?: number | undefined;
207
+ /**
208
+ * Defaults to `"SHA1"`, which is what authenticator apps expect.
209
+ */
210
+ algorithm?: "SHA1" | "SHA256" | "SHA512" | undefined;
211
+ /**
212
+ * Compute the code for this moment. Defaults to now.
213
+ */
214
+ time?: number | Date | undefined;
215
+ };
216
+ /**
217
+ * Options for `verifyTOTP()`. `window` is how many periods before and after
218
+ * now are accepted (defaults to `1`).
219
+ */
220
+ export type VerifyTOTPOptions = TOTPOptions & {
221
+ window?: number;
222
+ };
223
+ /**
224
+ * Options for `totpURI()`.
225
+ */
226
+ export type TOTPURIOptions = {
227
+ /**
228
+ * The account shown in the app, usually the email.
229
+ */
230
+ label: string;
231
+ /**
232
+ * Your app's name.
233
+ */
234
+ issuer?: string | undefined;
235
+ /**
236
+ * Defaults to `6`.
237
+ */
238
+ digits?: number | undefined;
239
+ /**
240
+ * Defaults to `30`.
241
+ */
242
+ period?: number | undefined;
243
+ /**
244
+ * Defaults to `"SHA1"`.
245
+ */
246
+ algorithm?: "SHA1" | "SHA256" | "SHA512" | undefined;
247
+ };
248
+ /**
249
+ * Hashes data, SHA-256 in hex by default.
250
+ *
251
+ * @example
252
+ * crypto.hash("hello");
253
+ * crypto.hash("hello", { algorithm: "sha512", encoding: "base64url" });
254
+ *
255
+ * @param {string | Buffer | Uint8Array} data Strings are read as UTF-8.
256
+ * @param {HashOptions} [options]
257
+ * @returns {string}
258
+ */
259
+ export function hash(data: string | Buffer | Uint8Array, options?: HashOptions): string;
260
+ /**
261
+ * An HMAC signature: a hash keyed with a secret. The usual way to sign and
262
+ * check webhooks.
263
+ *
264
+ * @example
265
+ * const signature = crypto.hmac(rawBody, process.env.WEBHOOK_SECRET);
266
+ * crypto.safeEqual(signature, req.headers["x-signature"]);
267
+ *
268
+ * @param {string | Buffer | Uint8Array} data
269
+ * @param {string | Buffer | Uint8Array} secret
270
+ * @param {HashOptions} [options]
271
+ * @returns {string}
272
+ */
273
+ export function hmac(data: string | Buffer | Uint8Array, secret: string | Buffer | Uint8Array, options?: HashOptions): string;
274
+ /**
275
+ * Compares two secrets in constant time, so the comparison can't leak
276
+ * anything through timing. Use it instead of `===` for tokens, signatures
277
+ * and API keys.
278
+ *
279
+ * @example
280
+ * if (!crypto.safeEqual(providedKey, process.env.API_KEY)) throw new Error("Forbidden");
281
+ *
282
+ * @param {string | Buffer | Uint8Array} a
283
+ * @param {string | Buffer | Uint8Array} b
284
+ * @returns {boolean}
285
+ */
286
+ export function safeEqual(a: string | Buffer | Uint8Array, b: string | Buffer | Uint8Array): boolean;
287
+ /**
288
+ * Hashes a password with scrypt and a random salt. The result records its
289
+ * own settings, so you can raise the cost later without breaking old
290
+ * hashes.
291
+ *
292
+ * @example
293
+ * const stored = await crypto.hashPassword(password);
294
+ * // "$scrypt$ln=15,r=8,p=1$4xY...$kq9...", store this
295
+ *
296
+ * @param {string} password
297
+ * @param {HashPasswordOptions} [options]
298
+ * @returns {Promise<string>}
299
+ */
300
+ export function hashPassword(password: string, options?: HashPasswordOptions): Promise<string>;
301
+ /**
302
+ * Checks a password against a stored hash, in constant time. A wrong
303
+ * password or a broken hash gives `false`, never an error.
304
+ *
305
+ * @example
306
+ * if (!(await crypto.verifyPassword(input, user.passwordHash))) throw new Error("Invalid credentials");
307
+ *
308
+ * @param {string} password
309
+ * @param {string} stored
310
+ * @returns {Promise<boolean>}
311
+ */
312
+ export function verifyPassword(password: string, stored: string): Promise<boolean>;
313
+ /**
314
+ * Was this hash made with weaker settings than yours? If so, re-hash the
315
+ * password right after a successful login.
316
+ *
317
+ * @example
318
+ * if (await crypto.verifyPassword(input, user.hash) && crypto.needsRehash(user.hash, { cost: 16 })) {
319
+ * user.hash = await crypto.hashPassword(input, { cost: 16 });
320
+ * }
321
+ *
322
+ * @param {string} stored
323
+ * @param {HashPasswordOptions} [options] The settings you use today.
324
+ * @returns {boolean}
325
+ */
326
+ export function needsRehash(stored: string, options?: HashPasswordOptions): boolean;
327
+ /**
328
+ * A random 256-bit key for `encrypt()`, as text you can put in an
329
+ * environment variable.
330
+ *
331
+ * @returns {string}
332
+ */
333
+ export function generateKey(): string;
334
+ /**
335
+ * Encrypts data with AES-256-GCM, which also detects tampering. Every call
336
+ * uses a fresh salt and nonce, so the same text never encrypts the same way
337
+ * twice.
338
+ *
339
+ * Use a key from `generateKey()` or another long random secret, not a
340
+ * password someone typed: that would be easy to brute-force.
341
+ *
342
+ * @example
343
+ * const box = crypto.encrypt(JSON.stringify(card), process.env.ENCRYPTION_KEY);
344
+ * const card = JSON.parse(crypto.decrypt(box, process.env.ENCRYPTION_KEY));
345
+ *
346
+ * @param {string | Buffer | Uint8Array} data
347
+ * @param {string | Buffer | Uint8Array} secret
348
+ * @param {EncryptOptions} [options]
349
+ * @returns {string} A compact, URL-safe string.
350
+ */
351
+ export function encrypt(data: string | Buffer | Uint8Array, secret: string | Buffer | Uint8Array, options?: EncryptOptions): string;
352
+ /**
353
+ * Decrypts what `encrypt()` produced. Throws if the secret is wrong or the
354
+ * data was changed.
355
+ *
356
+ * @example
357
+ * const text = crypto.decrypt(box, SECRET);
358
+ * const bytes = crypto.decrypt(box, SECRET, { output: "buffer" });
359
+ *
360
+ * @overload
361
+ * @param {string} payload
362
+ * @param {string | Buffer | Uint8Array} secret
363
+ * @param {DecryptOptions & { output: "buffer" }} options
364
+ * @returns {Buffer}
365
+ */
366
+ export function decrypt(payload: string, secret: string | Buffer | Uint8Array, options: DecryptOptions & {
367
+ output: "buffer";
368
+ }): Buffer;
369
+ /**
370
+ * Decrypts what `encrypt()` produced, as text.
371
+ *
372
+ * @overload
373
+ * @param {string} payload
374
+ * @param {string | Buffer | Uint8Array} secret
375
+ * @param {DecryptOptions} [options]
376
+ * @returns {string}
377
+ */
378
+ export function decrypt(payload: string, secret: string | Buffer | Uint8Array, options?: DecryptOptions | undefined): string;
379
+ /**
380
+ * Creates a signed JSON Web Token. `iat` is added for you.
381
+ *
382
+ * @example
383
+ * const token = crypto.signJWT({ sub: String(user.id), role: user.role }, process.env.JWT_SECRET, {
384
+ * expiresIn: "15m",
385
+ * issuer: "api.example.com",
386
+ * });
387
+ *
388
+ * @param {Record<string, unknown>} payload
389
+ * @param {string | Buffer} secret At least 32 random bytes.
390
+ * @param {SignJWTOptions} [options]
391
+ * @returns {string}
392
+ */
393
+ export function signJWT(payload: Record<string, unknown>, secret: string | Buffer, options?: SignJWTOptions): string;
394
+ /**
395
+ * Reads a JWT without checking it. Fine for display; call `verifyJWT()`
396
+ * before trusting anything in it.
397
+ *
398
+ * @example
399
+ * crypto.decodeJWT(token).payload.exp;
400
+ *
401
+ * @template [P=Record<string, unknown>]
402
+ * @param {string} token
403
+ * @returns {DecodedJWT<P>}
404
+ * @throws {JWTError} With code `ERR_JWT_MALFORMED` if the token can't be read.
405
+ */
406
+ export function decodeJWT<P = Record<string, unknown>>(token: string): DecodedJWT<P>;
407
+ /**
408
+ * Verifies a JWT: algorithm, signature, expiry, and whichever claims you
409
+ * require. Returns the payload, or throws a `JWTError` whose `code` says
410
+ * what's wrong.
411
+ *
412
+ * @example
413
+ * try {
414
+ * const { sub } = crypto.verifyJWT(token, process.env.JWT_SECRET, { issuer: "api.example.com" });
415
+ * } catch (error) {
416
+ * res.status(401).json({ error: error.code }); // "ERR_JWT_EXPIRED"...
417
+ * }
418
+ *
419
+ * @template [P=Record<string, unknown>]
420
+ * @param {string} token
421
+ * @param {string | Buffer} secret
422
+ * @param {VerifyJWTOptions} [options]
423
+ * @returns {P & JWTClaims}
424
+ * @throws {JWTError}
425
+ */
426
+ export function verifyJWT<P = Record<string, unknown>>(token: string, secret: string | Buffer, options?: VerifyJWTOptions): P & JWTClaims;
427
+ /**
428
+ * A new two-factor secret, in the Base32 format authenticator apps expect.
429
+ * Store it encrypted.
430
+ *
431
+ * @example
432
+ * user.totpSecret = crypto.totpSecret();
433
+ *
434
+ * @param {number} [bytes=20]
435
+ * @returns {string}
436
+ */
437
+ export function totpSecret(bytes?: number): string;
438
+ /**
439
+ * The current 6-digit code for a two-factor secret, as shown by
440
+ * authenticator apps.
441
+ *
442
+ * @example
443
+ * crypto.totp(user.totpSecret); // "492039"
444
+ *
445
+ * @param {string} secret
446
+ * @param {TOTPOptions} [options]
447
+ * @returns {string}
448
+ */
449
+ export function totp(secret: string, options?: TOTPOptions): string;
450
+ /**
451
+ * Checks a code typed by a user. Codes from the neighbouring periods are
452
+ * accepted too, to cope with clock drift.
453
+ *
454
+ * @example
455
+ * if (!crypto.verifyTOTP(req.body.code, user.totpSecret)) throw new Error("Invalid code");
456
+ *
457
+ * @param {string} token Spaces are ignored.
458
+ * @param {string} secret
459
+ * @param {VerifyTOTPOptions} [options]
460
+ * @returns {boolean}
461
+ */
462
+ export function verifyTOTP(token: string, secret: string, options?: VerifyTOTPOptions): boolean;
463
+ /**
464
+ * The `otpauth://` link to show as a QR code when a user turns on 2FA.
465
+ *
466
+ * @example
467
+ * const uri = crypto.totpURI(user.totpSecret, { label: user.email, issuer: "My App" });
468
+ *
469
+ * @param {string} secret
470
+ * @param {TOTPURIOptions} options
471
+ * @returns {string}
472
+ */
473
+ export function totpURI(secret: string, options: TOTPURIOptions): string;
474
+ /**
475
+ * Secure random bytes.
476
+ *
477
+ * @param {number} size
478
+ * @returns {Buffer}
479
+ */
480
+ export function randomBytes(size: number): Buffer;
481
+ /**
482
+ * A secure random integer from `min` to `max`, both included, with no bias.
483
+ * For anything that has to be fair or unpredictable.
484
+ *
485
+ * @example
486
+ * crypto.randomInt(1, 6); // a fair dice roll
487
+ * crypto.randomInt(0, 999_999); // a 6-digit code
488
+ *
489
+ * @param {number} min
490
+ * @param {number} max
491
+ * @returns {number}
492
+ */
493
+ export function randomInt(min: number, max: number): number;
494
+ /**
495
+ * Encodes to Base64, or URL-safe Base64.
496
+ *
497
+ * @example
498
+ * crypto.toBase64("héllo"); // "aMOpbGxv"
499
+ * crypto.toBase64("héllo", { urlSafe: true });
500
+ *
501
+ * @param {string | Buffer | Uint8Array} data
502
+ * @param {{ urlSafe?: boolean }} [options]
503
+ * @returns {string}
504
+ */
505
+ export function toBase64(data: string | Buffer | Uint8Array, options?: {
506
+ urlSafe?: boolean;
507
+ }): string;
508
+ /**
509
+ * Decodes Base64 or URL-safe Base64.
510
+ *
511
+ * @example
512
+ * crypto.fromBase64("aMOpbGxv"); // "héllo"
513
+ * crypto.fromBase64("aMOpbGxv", { output: "buffer" }); // <Buffer 68 c3 a9 6c 6c 6f>
514
+ *
515
+ * @overload
516
+ * @param {string} text
517
+ * @param {{ output: "buffer" }} options
518
+ * @returns {Buffer}
519
+ */
520
+ export function fromBase64(text: string, options: {
521
+ output: "buffer";
522
+ }): Buffer;
523
+ /**
524
+ * Decodes Base64 or URL-safe Base64 into text.
525
+ *
526
+ * @overload
527
+ * @param {string} text
528
+ * @param {{ output?: "utf8" }} [options]
529
+ * @returns {string}
530
+ */
531
+ export function fromBase64(text: string, options?: {
532
+ output?: "utf8";
533
+ } | undefined): string;
534
+ //# sourceMappingURL=Crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ export = Emitter;
2
+ /**
3
+ * Event names mapped to their arguments, like
4
+ * `{ ready: [], data: [chunk: Buffer], error: [error: Error] }`.
5
+ * @typedef {Record<string, any[]>} EventMap
6
+ */
7
+ /**
8
+ * Options for `waitFor()`.
9
+ * @template {any[]} A
10
+ * @typedef {object} WaitForOptions
11
+ * @property {number | string} [timeout] Reject with a `TimeoutError` after this long.
12
+ * @property {AbortSignal} [signal] Reject with an `AbortError` when aborted.
13
+ * @property {(...args: A) => boolean} [filter] Only resolve for events that pass this test.
14
+ */
15
+ /**
16
+ * A typed event emitter. In JavaScript, give the variable a JSDoc type such
17
+ * as `import("@ix-xs/node-comfort").Emitter<{ ready: [port: number] }>`.
18
+ *
19
+ * @template {EventMap} [Events=EventMap]
20
+ */
21
+ declare class Emitter<Events extends EventMap = EventMap> {
22
+ /**
23
+ * Listens to an event.
24
+ *
25
+ * @example
26
+ * const off = emitter.on("data", (chunk) => chunks.push(chunk));
27
+ * off(); // stop listening
28
+ *
29
+ * @template {keyof Events & string} K
30
+ * @param {K} event
31
+ * @param {(...args: Events[K]) => unknown} listener
32
+ * @returns {() => void} Removes the listener.
33
+ */
34
+ on<K extends keyof Events & string>(event: K, listener: (...args: Events[K]) => unknown): () => void;
35
+ /**
36
+ * Listens to an event once.
37
+ *
38
+ * @template {keyof Events & string} K
39
+ * @param {K} event
40
+ * @param {(...args: Events[K]) => unknown} listener
41
+ * @returns {() => void} Removes the listener if it hasn't run yet.
42
+ */
43
+ once<K extends keyof Events & string>(event: K, listener: (...args: Events[K]) => unknown): () => void;
44
+ /**
45
+ * Listens to every event; the listener gets the event name first. Handy for
46
+ * logging.
47
+ *
48
+ * @example
49
+ * emitter.onAny((event, ...args) => nc.debug(event, args));
50
+ *
51
+ * @param {(event: keyof Events & string, ...args: any[]) => unknown} listener
52
+ * @returns {() => void} Removes the listener.
53
+ */
54
+ onAny(listener: (event: keyof Events & string, ...args: any[]) => unknown): () => void;
55
+ /**
56
+ * Removes a listener, or all listeners of the event if you don't pass one.
57
+ *
58
+ * @template {keyof Events & string} K
59
+ * @param {K} event
60
+ * @param {(...args: Events[K]) => unknown} [listener]
61
+ * @returns {this}
62
+ */
63
+ off<K extends keyof Events & string>(event: K, listener?: (...args: Events[K]) => unknown): this;
64
+ /**
65
+ * Calls the event's listeners right away, in the order they were added.
66
+ * If one throws, the error propagates, as with Node's `EventEmitter`.
67
+ *
68
+ * @example
69
+ * emitter.emit("message", "hello", "ada");
70
+ *
71
+ * @template {keyof Events & string} K
72
+ * @param {K} event
73
+ * @param {Events[K]} args
74
+ * @returns {boolean} `true` if anyone was listening.
75
+ */
76
+ emit<K extends keyof Events & string>(event: K, ...args: Events[K]): boolean;
77
+ /**
78
+ * Calls the listeners one at a time, waiting for each, and resolves with
79
+ * what they returned. Good for hooks that may be async.
80
+ *
81
+ * @example
82
+ * await hooks.emitAsync("beforeSave", record);
83
+ *
84
+ * @template {keyof Events & string} K
85
+ * @param {K} event
86
+ * @param {Events[K]} args
87
+ * @returns {Promise<unknown[]>}
88
+ */
89
+ emitAsync<K extends keyof Events & string>(event: K, ...args: Events[K]): Promise<unknown[]>;
90
+ /**
91
+ * Waits for the next time the event fires and resolves with its arguments.
92
+ *
93
+ * @example
94
+ * const [code] = await child.waitFor("exit", { timeout: "30s" });
95
+ * const [text] = await chat.waitFor("message", { filter: (text, from) => from === "ada" });
96
+ *
97
+ * @template {keyof Events & string} K
98
+ * @param {K} event
99
+ * @param {WaitForOptions<Events[K]>} [options]
100
+ * @returns {Promise<Events[K]>}
101
+ * @throws {TimeoutError}
102
+ * @throws {AbortError}
103
+ */
104
+ waitFor<K extends keyof Events & string>(event: K, options?: WaitForOptions<Events[K]>): Promise<Events[K]>;
105
+ /**
106
+ * Loops over an event with `for await`. Events that fire while your loop
107
+ * body runs are queued, and leaving the loop removes the listener.
108
+ *
109
+ * @example
110
+ * for await (const [job] of queue.iterate("job")) {
111
+ * await process(job);
112
+ * }
113
+ *
114
+ * @template {keyof Events & string} K
115
+ * @param {K} event
116
+ * @param {{ signal?: AbortSignal }} [options] Ends the loop when aborted.
117
+ * @returns {AsyncIterableIterator<Events[K]>}
118
+ */
119
+ iterate<K extends keyof Events & string>(event: K, options?: {
120
+ signal?: AbortSignal;
121
+ }): AsyncIterableIterator<Events[K]>;
122
+ /**
123
+ * How many listeners an event has, or all events together. `onAny`
124
+ * listeners aren't counted.
125
+ *
126
+ * @param {keyof Events & string} [event]
127
+ * @returns {number}
128
+ */
129
+ listenerCount(event?: keyof Events & string): number;
130
+ /**
131
+ * The events that have listeners.
132
+ *
133
+ * @returns {Array<keyof Events & string>}
134
+ */
135
+ eventNames(): Array<keyof Events & string>;
136
+ /**
137
+ * Removes all listeners of an event, or everything if you don't name one.
138
+ *
139
+ * @param {keyof Events & string} [event]
140
+ * @returns {this}
141
+ */
142
+ clear(event?: keyof Events & string): this;
143
+ #private;
144
+ }
145
+ declare namespace Emitter {
146
+ export { EventMap, WaitForOptions };
147
+ }
148
+ /**
149
+ * Event names mapped to their arguments, like
150
+ * `{ ready: [], data: [chunk: Buffer], error: [error: Error] }`.
151
+ */
152
+ type EventMap = Record<string, any[]>;
153
+ /**
154
+ * Options for `waitFor()`.
155
+ */
156
+ type WaitForOptions<A extends any[]> = {
157
+ /**
158
+ * Reject with a `TimeoutError` after this long.
159
+ */
160
+ timeout?: string | number | undefined;
161
+ /**
162
+ * Reject with an `AbortError` when aborted.
163
+ */
164
+ signal?: AbortSignal | undefined;
165
+ /**
166
+ * Only resolve for events that pass this test.
167
+ */
168
+ filter?: ((...args: A) => boolean) | undefined;
169
+ };
170
+ //# sourceMappingURL=Emitter.d.ts.map