reliable-node-utils 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.
- package/LICENSE +201 -0
- package/README.md +464 -0
- package/dist/index.cjs +1064 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +643 -0
- package/dist/index.d.ts +643 -0
- package/dist/index.js +1013 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link retry}.
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
interface RetryOptions {
|
|
6
|
+
/** Maximum number of attempts (including the first). Default: 3. */
|
|
7
|
+
maxAttempts?: number;
|
|
8
|
+
/** Base delay in ms for exponential backoff. Default: 1000. */
|
|
9
|
+
baseDelayMs?: number;
|
|
10
|
+
/** Maximum delay in ms. Default: 30000. */
|
|
11
|
+
maxDelayMs?: number;
|
|
12
|
+
/** If true, add random jitter to delays. Default: true. */
|
|
13
|
+
jitter?: boolean;
|
|
14
|
+
/** Called before each retry with attempt index (1-based) and error. */
|
|
15
|
+
onRetry?: (attempt: number, error: unknown) => void | Promise<void>;
|
|
16
|
+
/** When aborted, retry stops and rejects with AbortError. */
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Retry an async function with exponential backoff and optional jitter.
|
|
21
|
+
* Supports AbortSignal; calls onRetry before each retry.
|
|
22
|
+
*
|
|
23
|
+
* @param fn - Async function to run (no arguments). Return value is passed through.
|
|
24
|
+
* @param options - maxAttempts, baseDelayMs, maxDelayMs, jitter, onRetry, signal
|
|
25
|
+
* @returns Promise resolving to the return value of `fn`
|
|
26
|
+
* @throws {TypeError} When options are invalid
|
|
27
|
+
* @throws {AbortError} When `signal` is aborted
|
|
28
|
+
* @throws {RetryExhaustedError} When all attempts fail (last error as cause)
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { retry } from 'reliable-node-utils';
|
|
33
|
+
*
|
|
34
|
+
* const data = await retry(() => fetchJSON('/api/data'), {
|
|
35
|
+
* maxAttempts: 5,
|
|
36
|
+
* baseDelayMs: 500,
|
|
37
|
+
* onRetry: (attempt, err) => console.warn(`Attempt ${attempt} failed`, err),
|
|
38
|
+
* signal: controller.signal,
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```js
|
|
44
|
+
* const { retry } = require('reliable-node-utils');
|
|
45
|
+
* const result = await retry(async () => callExternalApi(), { maxAttempts: 3 });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Options for {@link withTimeout}.
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
interface WithTimeoutOptions {
|
|
55
|
+
/** AbortSignal to respect; when aborted, the timeout is cancelled and AbortError is thrown. */
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Run a promise or async function with a time limit.
|
|
60
|
+
* If the time limit is exceeded, the returned promise rejects with TimeoutError.
|
|
61
|
+
* Supports AbortSignal: aborting clears the timer and rejects with AbortError.
|
|
62
|
+
*
|
|
63
|
+
* @param promiseOrFn - A Promise or a function returning a Promise
|
|
64
|
+
* @param ms - Time limit in milliseconds
|
|
65
|
+
* @param options - Optional { signal }
|
|
66
|
+
* @returns Promise resolving to the same value as the input promise
|
|
67
|
+
* @throws {TypeError} When `ms` is negative or non-finite
|
|
68
|
+
* @throws {TimeoutError} When the operation exceeds `ms`
|
|
69
|
+
* @throws {AbortError} When `signal` is aborted
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { withTimeout } from 'reliable-node-utils';
|
|
74
|
+
*
|
|
75
|
+
* const data = await withTimeout(fetch('/api/data').then(r => r.json()), 5000);
|
|
76
|
+
* // or
|
|
77
|
+
* const data = await withTimeout(() => fetch('/api/data').then(r => r.json()), 5000, {
|
|
78
|
+
* signal: controller.signal,
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```js
|
|
84
|
+
* const { withTimeout } = require('reliable-node-utils');
|
|
85
|
+
* const result = await withTimeout(longRunningTask(), 3000);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function withTimeout<T>(promiseOrFn: Promise<T> | (() => Promise<T>), ms: number, options?: WithTimeoutOptions): Promise<T>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Concurrency limiter: run at most `concurrency` promises at a time.
|
|
92
|
+
* Queues additional calls and runs them when a slot frees up.
|
|
93
|
+
*
|
|
94
|
+
* @param concurrency - Maximum number of concurrent executions (>= 1)
|
|
95
|
+
* @returns A function that accepts an async function and its arguments, returning a Promise
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* import { pLimit } from 'reliable-node-utils';
|
|
100
|
+
*
|
|
101
|
+
* const limit = pLimit(2);
|
|
102
|
+
* const out = await Promise.all([
|
|
103
|
+
* limit(() => fetch('/a')),
|
|
104
|
+
* limit(() => fetch('/b')),
|
|
105
|
+
* limit(() => fetch('/c')), // waits until one of the first two finishes
|
|
106
|
+
* ]);
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```js
|
|
111
|
+
* const { pLimit } = require('reliable-node-utils');
|
|
112
|
+
* const limit = pLimit(5);
|
|
113
|
+
* const results = await Promise.all(urls.map(url => limit(() => fetch(url))));
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
declare function pLimit(concurrency: number): <T, A extends unknown[]>(fn: (...args: A) => Promise<T>, ...args: A) => Promise<T>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Options for {@link memoize}.
|
|
120
|
+
* @public
|
|
121
|
+
*/
|
|
122
|
+
interface MemoizeOptions<F extends (...args: unknown[]) => unknown> {
|
|
123
|
+
/** TTL in milliseconds; entries expire after this long. Omit for no expiry. */
|
|
124
|
+
ttlMs?: number;
|
|
125
|
+
/** Maximum number of entries to keep (LRU eviction). Omit for unbounded. */
|
|
126
|
+
maxSize?: number;
|
|
127
|
+
/** Custom key function. Default: `(...args) => JSON.stringify(args)`. */
|
|
128
|
+
keyFn?: (...args: Parameters<F>) => string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Memoize a function with optional TTL and size limit.
|
|
132
|
+
* Cache key is computed via keyFn (default: JSON.stringify of arguments).
|
|
133
|
+
* When maxSize is set, least-recently-used entries are evicted.
|
|
134
|
+
*
|
|
135
|
+
* @param fn - Function to memoize (any arity)
|
|
136
|
+
* @param options - ttlMs, maxSize, keyFn
|
|
137
|
+
* @returns Memoized function with the same signature
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { memoize } from 'reliable-node-utils';
|
|
142
|
+
*
|
|
143
|
+
* const getData = memoize(async (id: string) => fetch(`/api/${id}`).then(r => r.json()), {
|
|
144
|
+
* ttlMs: 60_000,
|
|
145
|
+
* maxSize: 100,
|
|
146
|
+
* keyFn: (id) => id,
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```js
|
|
152
|
+
* const { memoize } = require('reliable-node-utils');
|
|
153
|
+
* const heavy = memoize(function (x, y) { return x + y; }, { maxSize: 50 });
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
declare function memoize<F extends (...args: unknown[]) => unknown>(fn: F, options?: MemoizeOptions<F>): F;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Deep merge two values. Source `b` overrides `a`.
|
|
160
|
+
* - Plain objects are merged recursively; arrays and other values are replaced by `b`.
|
|
161
|
+
* - Primitives, dates, class instances: always use `b` when present (not merged).
|
|
162
|
+
* - `__proto__`, `prototype`, and `constructor` keys are ignored for safety.
|
|
163
|
+
*
|
|
164
|
+
* @param a - Base object
|
|
165
|
+
* @param b - Overrides (takes precedence)
|
|
166
|
+
* @returns New object; inputs are not mutated
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* import { deepMerge } from 'reliable-node-utils';
|
|
171
|
+
*
|
|
172
|
+
* const merged = deepMerge({ a: 1, nested: { x: 1 } }, { nested: { y: 2 } });
|
|
173
|
+
* // { a: 1, nested: { x: 1, y: 2 } }
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```js
|
|
178
|
+
* const { deepMerge } = require('reliable-node-utils');
|
|
179
|
+
* const config = deepMerge(defaults, userConfig);
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
declare function deepMerge<T extends object, U extends object>(a: T, b: U): T & U;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Runtime type guards. Use with TypeScript for correct narrowing.
|
|
186
|
+
* @module guards
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* Type predicate: narrows out `null` and `undefined`.
|
|
190
|
+
*
|
|
191
|
+
* @param value - Any value
|
|
192
|
+
* @returns `true` if value is not `null` and not `undefined`
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* const arr: (string | undefined)[] = ['a', undefined, 'b'];
|
|
197
|
+
* const defined: string[] = arr.filter(isDefined);
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```js
|
|
202
|
+
* const { isDefined } = require('reliable-node-utils');
|
|
203
|
+
* if (isDefined(maybe)) console.log(maybe.toUpperCase());
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
207
|
+
/**
|
|
208
|
+
* Type predicate: narrows to a non-empty string (length > 0).
|
|
209
|
+
* Rejects `null`, `undefined`, non-strings, and `""`.
|
|
210
|
+
*
|
|
211
|
+
* @param value - Any value
|
|
212
|
+
* @returns `true` if value is a string with at least one character
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* function greet(name: unknown) {
|
|
217
|
+
* if (isNonEmptyString(name)) return `Hello, ${name}`;
|
|
218
|
+
* return 'Hello, stranger';
|
|
219
|
+
* }
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```js
|
|
224
|
+
* const { isNonEmptyString } = require('reliable-node-utils');
|
|
225
|
+
* if (isNonEmptyString(input)) validate(input);
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
declare function isNonEmptyString(value: unknown): value is string;
|
|
229
|
+
/**
|
|
230
|
+
* Type predicate: narrows to a plain object (object created by `{}` or `Object.create(null)`).
|
|
231
|
+
* Rejects `null`, arrays, and class instances (e.g. Date, RegExp).
|
|
232
|
+
*
|
|
233
|
+
* @param value - Any value
|
|
234
|
+
* @returns `true` if value is a plain object (record-like)
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```ts
|
|
238
|
+
* function mergeConfig(config: unknown) {
|
|
239
|
+
* if (!isPlainObject(config)) throw new Error('Config must be an object');
|
|
240
|
+
* return deepMerge(defaults, config);
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```js
|
|
246
|
+
* const { isPlainObject } = require('reliable-node-utils');
|
|
247
|
+
* if (isPlainObject(obj)) Object.keys(obj).forEach(k => process(k, obj[k]));
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Replace `{key}` placeholders in a template string with quoted values.
|
|
254
|
+
*
|
|
255
|
+
* @param template - Input template containing placeholders like `{name}`
|
|
256
|
+
* @param replacements - Key/value mapping for placeholders
|
|
257
|
+
* @returns Formatted string with replacements wrapped in double quotes
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* const out = replaceTemplateValues("Hello {name}", { name: "Sam" });
|
|
262
|
+
* // Hello "Sam"
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
declare function replaceTemplateValues(template: string, replacements: Record<string, unknown>): string;
|
|
266
|
+
/**
|
|
267
|
+
* Split a string using a delimiter.
|
|
268
|
+
*/
|
|
269
|
+
declare function splitString(input: string, delimiter: string): string[];
|
|
270
|
+
/**
|
|
271
|
+
* Parse a strict boolean string (`true`/`false`, case-insensitive).
|
|
272
|
+
*
|
|
273
|
+
* @throws {Error} If input is empty or not a valid boolean string
|
|
274
|
+
*/
|
|
275
|
+
declare function parseBooleanString(input: string | undefined | null): boolean;
|
|
276
|
+
/**
|
|
277
|
+
* True when value is null/undefined/empty-after-trim.
|
|
278
|
+
*/
|
|
279
|
+
declare function isNullOrEmptyString(value: string | null | undefined): boolean;
|
|
280
|
+
/**
|
|
281
|
+
* Convert snake_case (or mixed case) string into PascalCase.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```ts
|
|
285
|
+
* snakeToPascalCase("user_name"); // UserName
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
declare function snakeToPascalCase(input: string): string;
|
|
289
|
+
/**
|
|
290
|
+
* Backward-compatible alias; output is PascalCase.
|
|
291
|
+
*/
|
|
292
|
+
declare const convertToCamelCase: typeof snakeToPascalCase;
|
|
293
|
+
/**
|
|
294
|
+
* Backward-compatible alias for legacy naming.
|
|
295
|
+
*/
|
|
296
|
+
declare const formatStringValue: typeof replaceTemplateValues;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Generate random alphanumeric string.
|
|
300
|
+
*/
|
|
301
|
+
declare function generateRandomAlphanumericString(length: number, options?: {
|
|
302
|
+
uppercase?: boolean;
|
|
303
|
+
rng?: () => number;
|
|
304
|
+
}): string;
|
|
305
|
+
/**
|
|
306
|
+
* Generate random N-digit integer (base-10).
|
|
307
|
+
*
|
|
308
|
+
* @throws {Error} If length is invalid
|
|
309
|
+
*/
|
|
310
|
+
declare function generateRandomNDigitNumber(length: number, options?: {
|
|
311
|
+
rng?: () => number;
|
|
312
|
+
}): number;
|
|
313
|
+
/**
|
|
314
|
+
* Generate random alphabetic string (letters only).
|
|
315
|
+
*/
|
|
316
|
+
declare function generateRandomAlphabeticString(length: number, options?: {
|
|
317
|
+
rng?: () => number;
|
|
318
|
+
}): string;
|
|
319
|
+
/**
|
|
320
|
+
* Backward-compatible alias for legacy naming.
|
|
321
|
+
*/
|
|
322
|
+
declare const getAlphaNumericString: typeof generateRandomAlphanumericString;
|
|
323
|
+
/**
|
|
324
|
+
* Backward-compatible alias for legacy naming.
|
|
325
|
+
*/
|
|
326
|
+
declare const generateRandomNumber: typeof generateRandomNDigitNumber;
|
|
327
|
+
/**
|
|
328
|
+
* Backward-compatible alias for legacy naming.
|
|
329
|
+
*/
|
|
330
|
+
declare const generateRandomString: typeof generateRandomAlphabeticString;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Parse JSON text and recursively update matching keys.
|
|
334
|
+
*
|
|
335
|
+
* @param jsonText - JSON string input
|
|
336
|
+
* @param updates - key/value map applied across nested objects and object arrays
|
|
337
|
+
* @returns Pretty-printed updated JSON text
|
|
338
|
+
*/
|
|
339
|
+
declare function updateJsonValues(jsonText: string, updates: Record<string, string>): string;
|
|
340
|
+
/**
|
|
341
|
+
* Backward-compatible alias for legacy naming.
|
|
342
|
+
*/
|
|
343
|
+
declare const updateJsonData: typeof updateJsonValues;
|
|
344
|
+
|
|
345
|
+
type RelativeDateToken = "Today" | "Yesterday" | "Year";
|
|
346
|
+
/**
|
|
347
|
+
* Get a formatted date for Today/Yesterday/Year(-1 year).
|
|
348
|
+
*
|
|
349
|
+
* @param token - Relative token
|
|
350
|
+
* @param format - Pattern (default `yyyy-MM-dd`)
|
|
351
|
+
* @param now - Optional injection point for tests
|
|
352
|
+
*/
|
|
353
|
+
declare function getRelativeDate(token: RelativeDateToken | string, format?: string, now?: Date): string;
|
|
354
|
+
/**
|
|
355
|
+
* Backward-compatible alias for legacy naming.
|
|
356
|
+
*/
|
|
357
|
+
declare const getDate: typeof getRelativeDate;
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Rename a key in a string map and strip wrapping quotes from its value.
|
|
361
|
+
*
|
|
362
|
+
* @returns true if key existed and was renamed, else false.
|
|
363
|
+
*/
|
|
364
|
+
declare function renameMapKey(data: Map<string, string>, oldKey: string, newKey: string): boolean;
|
|
365
|
+
/**
|
|
366
|
+
* Backward-compatible alias for legacy naming.
|
|
367
|
+
*/
|
|
368
|
+
declare const updateKey: typeof renameMapKey;
|
|
369
|
+
|
|
370
|
+
interface UniqueValueStore {
|
|
371
|
+
has(value: string): boolean | Promise<boolean>;
|
|
372
|
+
add(value: string): void | Promise<void>;
|
|
373
|
+
}
|
|
374
|
+
declare class InMemoryUniqueValueStore implements UniqueValueStore {
|
|
375
|
+
private readonly values;
|
|
376
|
+
has(value: string): boolean;
|
|
377
|
+
add(value: string): void;
|
|
378
|
+
}
|
|
379
|
+
declare function getScopedInMemoryStore(scope: string): InMemoryUniqueValueStore;
|
|
380
|
+
declare function clearScopedInMemoryStores(): void;
|
|
381
|
+
|
|
382
|
+
interface NameProvider {
|
|
383
|
+
firstName(options?: {
|
|
384
|
+
rng?: () => number;
|
|
385
|
+
}): string;
|
|
386
|
+
lastName(options?: {
|
|
387
|
+
rng?: () => number;
|
|
388
|
+
}): string;
|
|
389
|
+
}
|
|
390
|
+
interface FakerLike {
|
|
391
|
+
person: {
|
|
392
|
+
firstName: () => string;
|
|
393
|
+
lastName: () => string;
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Name provider backed by the in-repo curated dataset.
|
|
398
|
+
*/
|
|
399
|
+
declare class StaticDatasetNameProvider implements NameProvider {
|
|
400
|
+
firstName(options?: {
|
|
401
|
+
rng?: () => number;
|
|
402
|
+
}): string;
|
|
403
|
+
lastName(options?: {
|
|
404
|
+
rng?: () => number;
|
|
405
|
+
}): string;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Name provider backed by `@faker-js/faker`.
|
|
409
|
+
*
|
|
410
|
+
* Useful for large-scale synthetic name generation without maintaining
|
|
411
|
+
* in-repo name lists.
|
|
412
|
+
*/
|
|
413
|
+
declare class FakerNameProvider implements NameProvider {
|
|
414
|
+
private readonly faker;
|
|
415
|
+
constructor(options?: {
|
|
416
|
+
faker?: FakerLike;
|
|
417
|
+
});
|
|
418
|
+
firstName(): string;
|
|
419
|
+
lastName(): string;
|
|
420
|
+
}
|
|
421
|
+
declare const DEFAULT_NAME_PROVIDER: StaticDatasetNameProvider;
|
|
422
|
+
|
|
423
|
+
interface NameGenerationOptions {
|
|
424
|
+
/** Inject deterministic random source for tests. Default: Math.random. */
|
|
425
|
+
rng?: () => number;
|
|
426
|
+
/** Override name source (dataset/faker/custom). */
|
|
427
|
+
provider?: NameProvider;
|
|
428
|
+
}
|
|
429
|
+
interface UniqueNameOptions extends NameGenerationOptions {
|
|
430
|
+
/** Scope for in-memory uniqueness when no custom store is provided. */
|
|
431
|
+
scope?: string;
|
|
432
|
+
/** Custom persistence layer for cross-process uniqueness. */
|
|
433
|
+
store?: UniqueValueStore;
|
|
434
|
+
/** Maximum attempts to find an unused value. Default: 1000. */
|
|
435
|
+
maxAttempts?: number;
|
|
436
|
+
/** Normalize value before checking uniqueness. Default: lowercase trim. */
|
|
437
|
+
normalize?: (value: string) => string;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Generate a realistic first name from a curated common-name list.
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```ts
|
|
444
|
+
* const first = generateFirstName();
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
declare function generateFirstName(options?: NameGenerationOptions): string;
|
|
448
|
+
/**
|
|
449
|
+
* Generate a realistic last name from a curated common-name list.
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```ts
|
|
453
|
+
* const last = generateLastName();
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
declare function generateLastName(options?: NameGenerationOptions): string;
|
|
457
|
+
/**
|
|
458
|
+
* Generate a realistic full name.
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```ts
|
|
462
|
+
* const fullName = generateFullName();
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
declare function generateFullName(options?: NameGenerationOptions): string;
|
|
466
|
+
/**
|
|
467
|
+
* Generate a unique first name within a scope/store.
|
|
468
|
+
*/
|
|
469
|
+
declare function generateUniqueFirstName(options?: UniqueNameOptions): Promise<string>;
|
|
470
|
+
/**
|
|
471
|
+
* Generate a unique last name within a scope/store.
|
|
472
|
+
*/
|
|
473
|
+
declare function generateUniqueLastName(options?: UniqueNameOptions): Promise<string>;
|
|
474
|
+
/**
|
|
475
|
+
* Generate a unique full name within a scope/store.
|
|
476
|
+
*/
|
|
477
|
+
declare function generateUniqueFullName(options?: UniqueNameOptions): Promise<string>;
|
|
478
|
+
|
|
479
|
+
type SupportedCountryCode = "US" | "CA";
|
|
480
|
+
interface PostalCodeLookupRequest {
|
|
481
|
+
country: SupportedCountryCode;
|
|
482
|
+
postalCode: string;
|
|
483
|
+
signal?: AbortSignal;
|
|
484
|
+
}
|
|
485
|
+
interface AddressInput {
|
|
486
|
+
country: SupportedCountryCode;
|
|
487
|
+
postalCode: string;
|
|
488
|
+
city?: string;
|
|
489
|
+
stateProvince?: string;
|
|
490
|
+
addressLine1?: string;
|
|
491
|
+
addressLine2?: string;
|
|
492
|
+
signal?: AbortSignal;
|
|
493
|
+
}
|
|
494
|
+
interface ValidatedPostalCodeAddress {
|
|
495
|
+
country: SupportedCountryCode;
|
|
496
|
+
postalCode: string;
|
|
497
|
+
city: string;
|
|
498
|
+
stateProvince: string;
|
|
499
|
+
source: string;
|
|
500
|
+
uspsVerified: boolean;
|
|
501
|
+
}
|
|
502
|
+
interface VerifiedAddress {
|
|
503
|
+
country: SupportedCountryCode;
|
|
504
|
+
postalCode: string;
|
|
505
|
+
city: string;
|
|
506
|
+
stateProvince: string;
|
|
507
|
+
addressLine1?: string;
|
|
508
|
+
addressLine2?: string;
|
|
509
|
+
source: string;
|
|
510
|
+
uspsVerified: boolean;
|
|
511
|
+
}
|
|
512
|
+
interface AddressProvider {
|
|
513
|
+
readonly name: string;
|
|
514
|
+
supportsCountry(country: SupportedCountryCode): boolean;
|
|
515
|
+
lookupPostalCode(request: PostalCodeLookupRequest): Promise<ValidatedPostalCodeAddress>;
|
|
516
|
+
verifyAddress(request: AddressInput): Promise<VerifiedAddress>;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
interface GetValidAddressByPostalCodeOptions {
|
|
520
|
+
country: SupportedCountryCode;
|
|
521
|
+
postalCode: string;
|
|
522
|
+
providers: AddressProvider[];
|
|
523
|
+
signal?: AbortSignal;
|
|
524
|
+
/**
|
|
525
|
+
* When true, US lookups must use the USPS provider.
|
|
526
|
+
* Default: true
|
|
527
|
+
*/
|
|
528
|
+
requireUspsForUS?: boolean;
|
|
529
|
+
}
|
|
530
|
+
interface VerifyAddressOptions {
|
|
531
|
+
address: AddressInput;
|
|
532
|
+
providers: AddressProvider[];
|
|
533
|
+
/**
|
|
534
|
+
* When true, US verification must use the USPS provider.
|
|
535
|
+
* Default: true
|
|
536
|
+
*/
|
|
537
|
+
requireUspsForUS?: boolean;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Resolve a valid city/state-province for a postal code.
|
|
541
|
+
* For US, this can be configured to strictly require USPS.
|
|
542
|
+
*/
|
|
543
|
+
declare function getValidAddressByPostalCode(options: GetValidAddressByPostalCodeOptions): Promise<ValidatedPostalCodeAddress>;
|
|
544
|
+
/**
|
|
545
|
+
* Verify and normalize an address with the best provider for its country.
|
|
546
|
+
* For US, this can be configured to strictly require USPS.
|
|
547
|
+
*/
|
|
548
|
+
declare function verifyAddress(options: VerifyAddressOptions): Promise<VerifiedAddress>;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Custom error base for utilities. Enables `instanceof` checks and preserves cause.
|
|
552
|
+
* @internal
|
|
553
|
+
*/
|
|
554
|
+
declare class UtilsError extends Error {
|
|
555
|
+
readonly name: string;
|
|
556
|
+
constructor(message: string, options?: {
|
|
557
|
+
cause?: unknown;
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Thrown when an operation is aborted via AbortSignal.
|
|
562
|
+
* @public
|
|
563
|
+
*/
|
|
564
|
+
declare class AbortError extends UtilsError {
|
|
565
|
+
readonly name = "AbortError";
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Thrown when an operation exceeds its time limit (e.g. withTimeout).
|
|
569
|
+
* @public
|
|
570
|
+
*/
|
|
571
|
+
declare class TimeoutError extends UtilsError {
|
|
572
|
+
readonly name = "TimeoutError";
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Thrown when retry exhausts all attempts without success.
|
|
576
|
+
* @public
|
|
577
|
+
*/
|
|
578
|
+
declare class RetryExhaustedError extends UtilsError {
|
|
579
|
+
readonly attempt: number;
|
|
580
|
+
readonly lastError: unknown;
|
|
581
|
+
readonly name = "RetryExhaustedError";
|
|
582
|
+
constructor(message: string, attempt: number, lastError: unknown, options?: {
|
|
583
|
+
cause?: unknown;
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
declare class AddressProviderError extends UtilsError {
|
|
588
|
+
readonly name = "AddressProviderError";
|
|
589
|
+
}
|
|
590
|
+
declare class AddressVerificationError extends UtilsError {
|
|
591
|
+
readonly name = "AddressVerificationError";
|
|
592
|
+
}
|
|
593
|
+
declare class ProviderNotFoundError extends UtilsError {
|
|
594
|
+
readonly name = "ProviderNotFoundError";
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
interface UspsAddressProviderOptions {
|
|
598
|
+
userId: string;
|
|
599
|
+
endpoint?: string;
|
|
600
|
+
}
|
|
601
|
+
declare class UspsAddressProvider implements AddressProvider {
|
|
602
|
+
readonly name = "USPS";
|
|
603
|
+
private readonly endpoint;
|
|
604
|
+
private readonly userId;
|
|
605
|
+
constructor(options: UspsAddressProviderOptions);
|
|
606
|
+
supportsCountry(country: SupportedCountryCode): boolean;
|
|
607
|
+
lookupPostalCode(request: PostalCodeLookupRequest): Promise<ValidatedPostalCodeAddress>;
|
|
608
|
+
verifyAddress(request: AddressInput): Promise<VerifiedAddress>;
|
|
609
|
+
private callApi;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
interface ZippopotamAddressProviderOptions {
|
|
613
|
+
endpoint?: string;
|
|
614
|
+
}
|
|
615
|
+
declare class ZippopotamAddressProvider implements AddressProvider {
|
|
616
|
+
readonly name = "Zippopotam";
|
|
617
|
+
private readonly endpoint;
|
|
618
|
+
constructor(options?: ZippopotamAddressProviderOptions);
|
|
619
|
+
supportsCountry(country: SupportedCountryCode): boolean;
|
|
620
|
+
lookupPostalCode(request: PostalCodeLookupRequest): Promise<ValidatedPostalCodeAddress>;
|
|
621
|
+
verifyAddress(request: AddressInput): Promise<VerifiedAddress>;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
interface CanadaPostAddressProviderOptions {
|
|
625
|
+
key: string;
|
|
626
|
+
findEndpoint?: string;
|
|
627
|
+
retrieveEndpoint?: string;
|
|
628
|
+
}
|
|
629
|
+
declare class CanadaPostAddressProvider implements AddressProvider {
|
|
630
|
+
readonly name = "CanadaPost";
|
|
631
|
+
private readonly key;
|
|
632
|
+
private readonly findEndpoint;
|
|
633
|
+
private readonly retrieveEndpoint;
|
|
634
|
+
constructor(options: CanadaPostAddressProviderOptions);
|
|
635
|
+
supportsCountry(country: SupportedCountryCode): boolean;
|
|
636
|
+
lookupPostalCode(request: PostalCodeLookupRequest): Promise<ValidatedPostalCodeAddress>;
|
|
637
|
+
verifyAddress(request: AddressInput): Promise<VerifiedAddress>;
|
|
638
|
+
private findAndRetrieve;
|
|
639
|
+
private callFind;
|
|
640
|
+
private callRetrieve;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
export { AbortError, type AddressInput, type AddressProvider, AddressProviderError, AddressVerificationError, CanadaPostAddressProvider, type CanadaPostAddressProviderOptions, DEFAULT_NAME_PROVIDER, FakerNameProvider, type GetValidAddressByPostalCodeOptions, InMemoryUniqueValueStore, type MemoizeOptions, type NameGenerationOptions, type NameProvider, type PostalCodeLookupRequest, ProviderNotFoundError, type RelativeDateToken, RetryExhaustedError, type RetryOptions, StaticDatasetNameProvider, type SupportedCountryCode, TimeoutError, type UniqueNameOptions, type UniqueValueStore, UspsAddressProvider, type UspsAddressProviderOptions, type ValidatedPostalCodeAddress, type VerifiedAddress, type VerifyAddressOptions, type WithTimeoutOptions, ZippopotamAddressProvider, type ZippopotamAddressProviderOptions, clearScopedInMemoryStores, convertToCamelCase, deepMerge, formatStringValue, generateFirstName, generateFullName, generateLastName, generateRandomAlphabeticString, generateRandomAlphanumericString, generateRandomNDigitNumber, generateRandomNumber, generateRandomString, generateUniqueFirstName, generateUniqueFullName, generateUniqueLastName, getAlphaNumericString, getDate, getRelativeDate, getScopedInMemoryStore, getValidAddressByPostalCode, isDefined, isNonEmptyString, isNullOrEmptyString, isPlainObject, memoize, pLimit, parseBooleanString, renameMapKey, replaceTemplateValues, retry, snakeToPascalCase, splitString, updateJsonData, updateJsonValues, updateKey, verifyAddress, withTimeout };
|