@fgrzl/fetch 1.1.0-alpha.7 → 1.1.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/CHANGELOG.md +50 -0
- package/CONTRIBUTING.md +327 -0
- package/README.md +50 -21
- package/dist/cjs/index.js +1110 -105
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +2 -0
- package/dist/cjs/index.min.js.map +1 -0
- package/dist/index.d.ts +1381 -10
- package/dist/index.js +1066 -91
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +2 -0
- package/dist/index.min.js.map +1 -0
- package/package.json +14 -5
- package/dist/cjs/client/fetch-client.d.ts +0 -189
- package/dist/cjs/client/fetch-client.d.ts.map +0 -1
- package/dist/cjs/client/fetch-client.js +0 -339
- package/dist/cjs/client/fetch-client.js.map +0 -1
- package/dist/cjs/client/index.d.ts +0 -11
- package/dist/cjs/client/index.d.ts.map +0 -1
- package/dist/cjs/client/index.js +0 -14
- package/dist/cjs/client/index.js.map +0 -1
- package/dist/cjs/client/types.d.ts +0 -63
- package/dist/cjs/client/types.d.ts.map +0 -1
- package/dist/cjs/client/types.js +0 -9
- package/dist/cjs/client/types.js.map +0 -1
- package/dist/cjs/errors/index.d.ts +0 -64
- package/dist/cjs/errors/index.d.ts.map +0 -1
- package/dist/cjs/errors/index.js +0 -79
- package/dist/cjs/errors/index.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -65
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/cjs/middleware/authentication/authentication.d.ts +0 -31
- package/dist/cjs/middleware/authentication/authentication.d.ts.map +0 -1
- package/dist/cjs/middleware/authentication/authentication.js +0 -93
- package/dist/cjs/middleware/authentication/authentication.js.map +0 -1
- package/dist/cjs/middleware/authentication/index.d.ts +0 -37
- package/dist/cjs/middleware/authentication/index.d.ts.map +0 -1
- package/dist/cjs/middleware/authentication/index.js +0 -42
- package/dist/cjs/middleware/authentication/index.js.map +0 -1
- package/dist/cjs/middleware/authentication/types.d.ts +0 -73
- package/dist/cjs/middleware/authentication/types.d.ts.map +0 -1
- package/dist/cjs/middleware/authentication/types.js +0 -6
- package/dist/cjs/middleware/authentication/types.js.map +0 -1
- package/dist/cjs/middleware/authorization/authorization.d.ts +0 -30
- package/dist/cjs/middleware/authorization/authorization.d.ts.map +0 -1
- package/dist/cjs/middleware/authorization/authorization.js +0 -82
- package/dist/cjs/middleware/authorization/authorization.js.map +0 -1
- package/dist/cjs/middleware/authorization/index.d.ts +0 -36
- package/dist/cjs/middleware/authorization/index.d.ts.map +0 -1
- package/dist/cjs/middleware/authorization/index.js +0 -41
- package/dist/cjs/middleware/authorization/index.js.map +0 -1
- package/dist/cjs/middleware/authorization/types.d.ts +0 -67
- package/dist/cjs/middleware/authorization/types.d.ts.map +0 -1
- package/dist/cjs/middleware/authorization/types.js +0 -6
- package/dist/cjs/middleware/authorization/types.js.map +0 -1
- package/dist/cjs/middleware/cache/cache.d.ts +0 -41
- package/dist/cjs/middleware/cache/cache.d.ts.map +0 -1
- package/dist/cjs/middleware/cache/cache.js +0 -191
- package/dist/cjs/middleware/cache/cache.js.map +0 -1
- package/dist/cjs/middleware/cache/index.d.ts +0 -44
- package/dist/cjs/middleware/cache/index.d.ts.map +0 -1
- package/dist/cjs/middleware/cache/index.js +0 -50
- package/dist/cjs/middleware/cache/index.js.map +0 -1
- package/dist/cjs/middleware/cache/types.d.ts +0 -89
- package/dist/cjs/middleware/cache/types.d.ts.map +0 -1
- package/dist/cjs/middleware/cache/types.js +0 -6
- package/dist/cjs/middleware/cache/types.js.map +0 -1
- package/dist/cjs/middleware/csrf/csrf.d.ts +0 -34
- package/dist/cjs/middleware/csrf/csrf.d.ts.map +0 -1
- package/dist/cjs/middleware/csrf/csrf.js +0 -94
- package/dist/cjs/middleware/csrf/csrf.js.map +0 -1
- package/dist/cjs/middleware/csrf/index.d.ts +0 -57
- package/dist/cjs/middleware/csrf/index.d.ts.map +0 -1
- package/dist/cjs/middleware/csrf/index.js +0 -62
- package/dist/cjs/middleware/csrf/index.js.map +0 -1
- package/dist/cjs/middleware/csrf/types.d.ts +0 -57
- package/dist/cjs/middleware/csrf/types.d.ts.map +0 -1
- package/dist/cjs/middleware/csrf/types.js +0 -6
- package/dist/cjs/middleware/csrf/types.js.map +0 -1
- package/dist/cjs/middleware/index.d.ts +0 -115
- package/dist/cjs/middleware/index.d.ts.map +0 -1
- package/dist/cjs/middleware/index.js +0 -153
- package/dist/cjs/middleware/index.js.map +0 -1
- package/dist/cjs/middleware/logging/index.d.ts +0 -42
- package/dist/cjs/middleware/logging/index.d.ts.map +0 -1
- package/dist/cjs/middleware/logging/index.js +0 -47
- package/dist/cjs/middleware/logging/index.js.map +0 -1
- package/dist/cjs/middleware/logging/logging.d.ts +0 -29
- package/dist/cjs/middleware/logging/logging.d.ts.map +0 -1
- package/dist/cjs/middleware/logging/logging.js +0 -171
- package/dist/cjs/middleware/logging/logging.js.map +0 -1
- package/dist/cjs/middleware/logging/types.d.ts +0 -90
- package/dist/cjs/middleware/logging/types.d.ts.map +0 -1
- package/dist/cjs/middleware/logging/types.js +0 -6
- package/dist/cjs/middleware/logging/types.js.map +0 -1
- package/dist/cjs/middleware/rate-limit/index.d.ts +0 -16
- package/dist/cjs/middleware/rate-limit/index.d.ts.map +0 -1
- package/dist/cjs/middleware/rate-limit/index.js +0 -21
- package/dist/cjs/middleware/rate-limit/index.js.map +0 -1
- package/dist/cjs/middleware/rate-limit/rate-limit.d.ts +0 -14
- package/dist/cjs/middleware/rate-limit/rate-limit.d.ts.map +0 -1
- package/dist/cjs/middleware/rate-limit/rate-limit.js +0 -87
- package/dist/cjs/middleware/rate-limit/rate-limit.js.map +0 -1
- package/dist/cjs/middleware/rate-limit/types.d.ts +0 -97
- package/dist/cjs/middleware/rate-limit/types.d.ts.map +0 -1
- package/dist/cjs/middleware/rate-limit/types.js +0 -6
- package/dist/cjs/middleware/rate-limit/types.js.map +0 -1
- package/dist/cjs/middleware/retry/index.d.ts +0 -6
- package/dist/cjs/middleware/retry/index.d.ts.map +0 -1
- package/dist/cjs/middleware/retry/index.js +0 -11
- package/dist/cjs/middleware/retry/index.js.map +0 -1
- package/dist/cjs/middleware/retry/retry.d.ts +0 -39
- package/dist/cjs/middleware/retry/retry.d.ts.map +0 -1
- package/dist/cjs/middleware/retry/retry.js +0 -144
- package/dist/cjs/middleware/retry/retry.js.map +0 -1
- package/dist/cjs/middleware/retry/types.d.ts +0 -61
- package/dist/cjs/middleware/retry/types.d.ts.map +0 -1
- package/dist/cjs/middleware/retry/types.js +0 -6
- package/dist/cjs/middleware/retry/types.js.map +0 -1
- package/dist/client/fetch-client.d.ts +0 -189
- package/dist/client/fetch-client.d.ts.map +0 -1
- package/dist/client/fetch-client.js +0 -335
- package/dist/client/fetch-client.js.map +0 -1
- package/dist/client/index.d.ts +0 -11
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -10
- package/dist/client/index.js.map +0 -1
- package/dist/client/types.d.ts +0 -63
- package/dist/client/types.d.ts.map +0 -1
- package/dist/client/types.js +0 -8
- package/dist/client/types.js.map +0 -1
- package/dist/errors/index.d.ts +0 -64
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -73
- package/dist/errors/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/middleware/authentication/authentication.d.ts +0 -31
- package/dist/middleware/authentication/authentication.d.ts.map +0 -1
- package/dist/middleware/authentication/authentication.js +0 -90
- package/dist/middleware/authentication/authentication.js.map +0 -1
- package/dist/middleware/authentication/index.d.ts +0 -37
- package/dist/middleware/authentication/index.d.ts.map +0 -1
- package/dist/middleware/authentication/index.js +0 -37
- package/dist/middleware/authentication/index.js.map +0 -1
- package/dist/middleware/authentication/types.d.ts +0 -73
- package/dist/middleware/authentication/types.d.ts.map +0 -1
- package/dist/middleware/authentication/types.js +0 -5
- package/dist/middleware/authentication/types.js.map +0 -1
- package/dist/middleware/authorization/authorization.d.ts +0 -30
- package/dist/middleware/authorization/authorization.d.ts.map +0 -1
- package/dist/middleware/authorization/authorization.js +0 -79
- package/dist/middleware/authorization/authorization.js.map +0 -1
- package/dist/middleware/authorization/index.d.ts +0 -36
- package/dist/middleware/authorization/index.d.ts.map +0 -1
- package/dist/middleware/authorization/index.js +0 -36
- package/dist/middleware/authorization/index.js.map +0 -1
- package/dist/middleware/authorization/types.d.ts +0 -67
- package/dist/middleware/authorization/types.d.ts.map +0 -1
- package/dist/middleware/authorization/types.js +0 -5
- package/dist/middleware/authorization/types.js.map +0 -1
- package/dist/middleware/cache/cache.d.ts +0 -41
- package/dist/middleware/cache/cache.d.ts.map +0 -1
- package/dist/middleware/cache/cache.js +0 -186
- package/dist/middleware/cache/cache.js.map +0 -1
- package/dist/middleware/cache/index.d.ts +0 -44
- package/dist/middleware/cache/index.d.ts.map +0 -1
- package/dist/middleware/cache/index.js +0 -44
- package/dist/middleware/cache/index.js.map +0 -1
- package/dist/middleware/cache/types.d.ts +0 -89
- package/dist/middleware/cache/types.d.ts.map +0 -1
- package/dist/middleware/cache/types.js +0 -5
- package/dist/middleware/cache/types.js.map +0 -1
- package/dist/middleware/csrf/csrf.d.ts +0 -34
- package/dist/middleware/csrf/csrf.d.ts.map +0 -1
- package/dist/middleware/csrf/csrf.js +0 -91
- package/dist/middleware/csrf/csrf.js.map +0 -1
- package/dist/middleware/csrf/index.d.ts +0 -57
- package/dist/middleware/csrf/index.d.ts.map +0 -1
- package/dist/middleware/csrf/index.js +0 -57
- package/dist/middleware/csrf/index.js.map +0 -1
- package/dist/middleware/csrf/types.d.ts +0 -57
- package/dist/middleware/csrf/types.d.ts.map +0 -1
- package/dist/middleware/csrf/types.js +0 -5
- package/dist/middleware/csrf/types.js.map +0 -1
- package/dist/middleware/index.d.ts +0 -115
- package/dist/middleware/index.d.ts.map +0 -1
- package/dist/middleware/index.js +0 -134
- package/dist/middleware/index.js.map +0 -1
- package/dist/middleware/logging/index.d.ts +0 -42
- package/dist/middleware/logging/index.d.ts.map +0 -1
- package/dist/middleware/logging/index.js +0 -42
- package/dist/middleware/logging/index.js.map +0 -1
- package/dist/middleware/logging/logging.d.ts +0 -29
- package/dist/middleware/logging/logging.d.ts.map +0 -1
- package/dist/middleware/logging/logging.js +0 -168
- package/dist/middleware/logging/logging.js.map +0 -1
- package/dist/middleware/logging/types.d.ts +0 -90
- package/dist/middleware/logging/types.d.ts.map +0 -1
- package/dist/middleware/logging/types.js +0 -5
- package/dist/middleware/logging/types.js.map +0 -1
- package/dist/middleware/rate-limit/index.d.ts +0 -16
- package/dist/middleware/rate-limit/index.d.ts.map +0 -1
- package/dist/middleware/rate-limit/index.js +0 -16
- package/dist/middleware/rate-limit/index.js.map +0 -1
- package/dist/middleware/rate-limit/rate-limit.d.ts +0 -14
- package/dist/middleware/rate-limit/rate-limit.d.ts.map +0 -1
- package/dist/middleware/rate-limit/rate-limit.js +0 -84
- package/dist/middleware/rate-limit/rate-limit.js.map +0 -1
- package/dist/middleware/rate-limit/types.d.ts +0 -97
- package/dist/middleware/rate-limit/types.d.ts.map +0 -1
- package/dist/middleware/rate-limit/types.js +0 -5
- package/dist/middleware/rate-limit/types.js.map +0 -1
- package/dist/middleware/retry/index.d.ts +0 -6
- package/dist/middleware/retry/index.d.ts.map +0 -1
- package/dist/middleware/retry/index.js +0 -6
- package/dist/middleware/retry/index.js.map +0 -1
- package/dist/middleware/retry/retry.d.ts +0 -39
- package/dist/middleware/retry/retry.d.ts.map +0 -1
- package/dist/middleware/retry/retry.js +0 -141
- package/dist/middleware/retry/retry.js.map +0 -1
- package/dist/middleware/retry/types.d.ts +0 -61
- package/dist/middleware/retry/types.d.ts.map +0 -1
- package/dist/middleware/retry/types.js +0 -5
- package/dist/middleware/retry/types.js.map +0 -1
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Logging middleware types and configuration.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Log levels for filtering log output.
|
|
6
|
-
*/
|
|
7
|
-
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
8
|
-
/**
|
|
9
|
-
* Log entry structure.
|
|
10
|
-
*/
|
|
11
|
-
export interface LogEntry {
|
|
12
|
-
level: LogLevel;
|
|
13
|
-
timestamp: number;
|
|
14
|
-
method: string;
|
|
15
|
-
url: string;
|
|
16
|
-
status?: number;
|
|
17
|
-
duration?: number;
|
|
18
|
-
error?: Error;
|
|
19
|
-
requestHeaders?: Record<string, string>;
|
|
20
|
-
responseHeaders?: Record<string, string>;
|
|
21
|
-
requestBody?: unknown;
|
|
22
|
-
responseBody?: unknown;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Custom logger interface.
|
|
26
|
-
*/
|
|
27
|
-
export interface Logger {
|
|
28
|
-
debug(message: string, data?: unknown): void;
|
|
29
|
-
info(message: string, data?: unknown): void;
|
|
30
|
-
warn(message: string, data?: unknown): void;
|
|
31
|
-
error(message: string, data?: unknown): void;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Logging configuration options - optimized for "pit of success".
|
|
35
|
-
*
|
|
36
|
-
* Smart defaults:
|
|
37
|
-
* - Logs to console
|
|
38
|
-
* - Info level by default
|
|
39
|
-
* - Excludes request/response bodies by default
|
|
40
|
-
* - Includes timing information
|
|
41
|
-
*/
|
|
42
|
-
export interface LoggingOptions {
|
|
43
|
-
/**
|
|
44
|
-
* Minimum log level to output (default: 'info')
|
|
45
|
-
* Logs at this level and above will be output
|
|
46
|
-
*/
|
|
47
|
-
level?: LogLevel;
|
|
48
|
-
/**
|
|
49
|
-
* Custom logger implementation (default: console)
|
|
50
|
-
* Can be replaced with winston, pino, etc.
|
|
51
|
-
*/
|
|
52
|
-
logger?: Logger;
|
|
53
|
-
/**
|
|
54
|
-
* Include request headers in logs (default: false)
|
|
55
|
-
* May contain sensitive information
|
|
56
|
-
*/
|
|
57
|
-
includeRequestHeaders?: boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Include response headers in logs (default: false)
|
|
60
|
-
* May contain sensitive information
|
|
61
|
-
*/
|
|
62
|
-
includeResponseHeaders?: boolean;
|
|
63
|
-
/**
|
|
64
|
-
* Include request body in logs (default: false)
|
|
65
|
-
* May contain sensitive information and increase log size
|
|
66
|
-
*/
|
|
67
|
-
includeRequestBody?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Include response body in logs (default: false)
|
|
70
|
-
* May contain sensitive information and increase log size
|
|
71
|
-
*/
|
|
72
|
-
includeResponseBody?: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Skip logging for requests matching these URL patterns
|
|
75
|
-
* Useful for health checks, metrics endpoints, etc.
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* skipPatterns: ['/health', '/metrics', /\/static\//]
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
skipPatterns?: (RegExp | string)[];
|
|
83
|
-
/**
|
|
84
|
-
* Custom log formatter function
|
|
85
|
-
* Allows complete customization of log output
|
|
86
|
-
*/
|
|
87
|
-
formatter?: (entry: LogEntry) => string;
|
|
88
|
-
}
|
|
89
|
-
export {};
|
|
90
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/middleware/logging/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEnC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,MAAM,CAAC;CACzC;AAGD,OAAO,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/middleware/logging/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Rate limiting middleware - specialized use cases.
|
|
3
|
-
*/
|
|
4
|
-
import type { FetchClient } from '../../client/fetch-client';
|
|
5
|
-
import type { RateLimitOptions } from './types';
|
|
6
|
-
export type { RateLimitOptions, RateLimitAlgorithm } from './types';
|
|
7
|
-
export { createRateLimitMiddleware } from './rate-limit';
|
|
8
|
-
/**
|
|
9
|
-
* Rate limiting middleware - mainly for API quota management.
|
|
10
|
-
* Note: This is primarily useful for specific scenarios like:
|
|
11
|
-
* - Respecting third-party API limits
|
|
12
|
-
* - Bulk operations that need throttling
|
|
13
|
-
* - Pay-per-request API cost management
|
|
14
|
-
*/
|
|
15
|
-
export declare function useRateLimit(client: FetchClient, options?: RateLimitOptions): FetchClient;
|
|
16
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/rate-limit/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIhD,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,gBAAqB,GAC7B,WAAW,CAEb"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Rate limiting middleware - specialized use cases.
|
|
3
|
-
*/
|
|
4
|
-
import { createRateLimitMiddleware } from './rate-limit';
|
|
5
|
-
export { createRateLimitMiddleware } from './rate-limit';
|
|
6
|
-
/**
|
|
7
|
-
* Rate limiting middleware - mainly for API quota management.
|
|
8
|
-
* Note: This is primarily useful for specific scenarios like:
|
|
9
|
-
* - Respecting third-party API limits
|
|
10
|
-
* - Bulk operations that need throttling
|
|
11
|
-
* - Pay-per-request API cost management
|
|
12
|
-
*/
|
|
13
|
-
export function useRateLimit(client, options = {}) {
|
|
14
|
-
return client.use(createRateLimitMiddleware(options));
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/middleware/rate-limit/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAIzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAmB,EACnB,UAA4B,EAAE;IAE9B,OAAO,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Rate limiting middleware implementation.
|
|
3
|
-
*/
|
|
4
|
-
import type { FetchMiddleware } from '../../client/fetch-client';
|
|
5
|
-
import type { RateLimitOptions } from './types';
|
|
6
|
-
/**
|
|
7
|
-
* Creates rate limiting middleware - mainly for API quota management.
|
|
8
|
-
* Note: Rate limiting is typically a server concern, but this can help with:
|
|
9
|
-
* - Respecting API provider limits
|
|
10
|
-
* - Preventing runaway requests in bulk operations
|
|
11
|
-
* - Cost management for pay-per-request APIs
|
|
12
|
-
*/
|
|
13
|
-
export declare function createRateLimitMiddleware(options?: RateLimitOptions): FetchMiddleware;
|
|
14
|
-
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../src/middleware/rate-limit/rate-limit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAyChD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CA6DjB"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Rate limiting middleware implementation.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Simple token bucket implementation for rate limiting.
|
|
6
|
-
*/
|
|
7
|
-
class TokenBucket {
|
|
8
|
-
constructor(maxTokens, refillRate, // tokens per millisecond
|
|
9
|
-
timeProvider = () => Date.now()) {
|
|
10
|
-
this.maxTokens = maxTokens;
|
|
11
|
-
this.refillRate = refillRate;
|
|
12
|
-
this.timeProvider = timeProvider;
|
|
13
|
-
this.tokens = maxTokens;
|
|
14
|
-
this.lastRefill = this.timeProvider();
|
|
15
|
-
}
|
|
16
|
-
tryConsume() {
|
|
17
|
-
this.refill();
|
|
18
|
-
if (this.tokens >= 1) {
|
|
19
|
-
this.tokens--;
|
|
20
|
-
return { allowed: true };
|
|
21
|
-
}
|
|
22
|
-
// Calculate when next token will be available
|
|
23
|
-
const retryAfter = (1 - this.tokens) / this.refillRate;
|
|
24
|
-
return { allowed: false, retryAfter: Math.ceil(retryAfter) };
|
|
25
|
-
}
|
|
26
|
-
refill() {
|
|
27
|
-
const now = this.timeProvider();
|
|
28
|
-
const timePassed = now - this.lastRefill;
|
|
29
|
-
const tokensToAdd = timePassed * this.refillRate;
|
|
30
|
-
this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
|
|
31
|
-
this.lastRefill = now;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Creates rate limiting middleware - mainly for API quota management.
|
|
36
|
-
* Note: Rate limiting is typically a server concern, but this can help with:
|
|
37
|
-
* - Respecting API provider limits
|
|
38
|
-
* - Preventing runaway requests in bulk operations
|
|
39
|
-
* - Cost management for pay-per-request APIs
|
|
40
|
-
*/
|
|
41
|
-
export function createRateLimitMiddleware(options = {}) {
|
|
42
|
-
const { maxRequests = 60, windowMs = 60000, keyGenerator = () => 'default', skipPatterns = [], onRateLimitExceeded, } = options;
|
|
43
|
-
const buckets = new Map();
|
|
44
|
-
const refillRate = maxRequests / windowMs;
|
|
45
|
-
return async (request, next) => {
|
|
46
|
-
const url = request.url || '';
|
|
47
|
-
// Skip rate limiting if URL matches skip patterns
|
|
48
|
-
if (skipPatterns.some((pattern) => typeof pattern === 'string' ? url.includes(pattern) : pattern.test(url))) {
|
|
49
|
-
return next(request);
|
|
50
|
-
}
|
|
51
|
-
const key = keyGenerator(request);
|
|
52
|
-
if (!buckets.has(key)) {
|
|
53
|
-
buckets.set(key, new TokenBucket(maxRequests, refillRate));
|
|
54
|
-
}
|
|
55
|
-
const bucket = buckets.get(key);
|
|
56
|
-
const result = bucket.tryConsume();
|
|
57
|
-
if (!result.allowed) {
|
|
58
|
-
if (onRateLimitExceeded) {
|
|
59
|
-
const customResponse = await onRateLimitExceeded(result.retryAfter || 0, request);
|
|
60
|
-
// If the custom handler returns a response, use it
|
|
61
|
-
if (customResponse) {
|
|
62
|
-
return customResponse;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// Return a 429 Too Many Requests response instead of throwing
|
|
66
|
-
return {
|
|
67
|
-
data: null,
|
|
68
|
-
status: 429,
|
|
69
|
-
statusText: 'Too Many Requests',
|
|
70
|
-
headers: new Headers({
|
|
71
|
-
'Retry-After': Math.ceil((result.retryAfter || 0) / 1000).toString(),
|
|
72
|
-
}),
|
|
73
|
-
url: request.url || '',
|
|
74
|
-
ok: false,
|
|
75
|
-
error: {
|
|
76
|
-
message: `Rate limit exceeded. Retry after ${result.retryAfter}ms`,
|
|
77
|
-
body: { retryAfter: result.retryAfter },
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return next(request);
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../../src/middleware/rate-limit/rate-limit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Rate limiting middleware types and configuration.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Rate limiting algorithm types.
|
|
6
|
-
*/
|
|
7
|
-
export type RateLimitAlgorithm = 'token-bucket' | 'sliding-window' | 'fixed-window';
|
|
8
|
-
/**
|
|
9
|
-
* Rate limiting configuration options - optimized for "pit of success".
|
|
10
|
-
*
|
|
11
|
-
* Smart defaults:
|
|
12
|
-
* - 60 requests per minute
|
|
13
|
-
* - Token bucket algorithm
|
|
14
|
-
* - Per-client limiting
|
|
15
|
-
* - Graceful handling when rate limit exceeded
|
|
16
|
-
*/
|
|
17
|
-
export interface RateLimitOptions {
|
|
18
|
-
/**
|
|
19
|
-
* Maximum number of requests allowed (default: 60)
|
|
20
|
-
*/
|
|
21
|
-
maxRequests?: number;
|
|
22
|
-
/**
|
|
23
|
-
* Time window in milliseconds (default: 60000 = 1 minute)
|
|
24
|
-
*/
|
|
25
|
-
windowMs?: number;
|
|
26
|
-
/**
|
|
27
|
-
* Rate limiting algorithm (default: 'token-bucket')
|
|
28
|
-
* - 'token-bucket': Allows bursts up to maxRequests, refills over time
|
|
29
|
-
* - 'sliding-window': Smooth rate limiting over rolling window
|
|
30
|
-
* - 'fixed-window': Fixed number of requests per fixed time window
|
|
31
|
-
*/
|
|
32
|
-
algorithm?: RateLimitAlgorithm;
|
|
33
|
-
/**
|
|
34
|
-
* Custom key generator for rate limiting scope
|
|
35
|
-
* Default: single global rate limit for all requests
|
|
36
|
-
*
|
|
37
|
-
* @example Per-endpoint rate limiting:
|
|
38
|
-
* ```typescript
|
|
39
|
-
* keyGenerator: (request) => request.url || 'default'
|
|
40
|
-
* ```
|
|
41
|
-
*
|
|
42
|
-
* @example Per-user rate limiting:
|
|
43
|
-
* ```typescript
|
|
44
|
-
* keyGenerator: (request) => {
|
|
45
|
-
* const auth = request.headers?.get('Authorization');
|
|
46
|
-
* return auth ? `user:${auth}` : 'anonymous';
|
|
47
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
keyGenerator?: (request: RequestInit & {
|
|
51
|
-
url?: string;
|
|
52
|
-
}) => string;
|
|
53
|
-
/**
|
|
54
|
-
* Skip rate limiting for requests matching these URL patterns
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```typescript
|
|
58
|
-
* skipPatterns: ['/health', /^\/public\//]
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
skipPatterns?: (RegExp | string)[];
|
|
62
|
-
/**
|
|
63
|
-
* Custom handler called when rate limit is exceeded
|
|
64
|
-
* Can return a custom response or void to use default behavior
|
|
65
|
-
*
|
|
66
|
-
* @param retryAfter - Milliseconds until next request is allowed
|
|
67
|
-
* @param request - The rate-limited request
|
|
68
|
-
* @returns Custom response or void for default behavior
|
|
69
|
-
*/
|
|
70
|
-
onRateLimitExceeded?: (retryAfter: number, request: RequestInit & {
|
|
71
|
-
url?: string;
|
|
72
|
-
}) => void | Promise<void> | {
|
|
73
|
-
data: unknown;
|
|
74
|
-
status: number;
|
|
75
|
-
statusText: string;
|
|
76
|
-
headers: Headers;
|
|
77
|
-
url: string;
|
|
78
|
-
ok: boolean;
|
|
79
|
-
error?: {
|
|
80
|
-
message: string;
|
|
81
|
-
body?: unknown;
|
|
82
|
-
};
|
|
83
|
-
} | Promise<{
|
|
84
|
-
data: unknown;
|
|
85
|
-
status: number;
|
|
86
|
-
statusText: string;
|
|
87
|
-
headers: Headers;
|
|
88
|
-
url: string;
|
|
89
|
-
ok: boolean;
|
|
90
|
-
error?: {
|
|
91
|
-
message: string;
|
|
92
|
-
body?: unknown;
|
|
93
|
-
};
|
|
94
|
-
}>;
|
|
95
|
-
}
|
|
96
|
-
export {};
|
|
97
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/middleware/rate-limit/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,gBAAgB,GAChB,cAAc,CAAC;AAEnB;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAE/B;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;IAEnE;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEnC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,CACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,WAAW,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,KACpC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG;QAC1B,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KAC7C,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KAC7C,CAAC,CAAC;CACJ;AAGD,OAAO,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/middleware/rate-limit/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { FetchClient } from '../../client/fetch-client';
|
|
2
|
-
import type { RetryOptions } from './types';
|
|
3
|
-
export type { RetryOptions } from './types';
|
|
4
|
-
export { createRetryMiddleware } from './retry';
|
|
5
|
-
export declare function useRetry(client: FetchClient, options?: RetryOptions): FetchClient;
|
|
6
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/retry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,QAAQ,CACtB,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,YAAiB,GACzB,WAAW,CAEb"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/middleware/retry/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,MAAM,UAAU,QAAQ,CACtB,MAAmB,EACnB,UAAwB,EAAE;IAE1B,OAAO,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Retry middleware implementation with enhanced architecture.
|
|
3
|
-
*/
|
|
4
|
-
import type { FetchMiddleware } from '../../client/fetch-client';
|
|
5
|
-
import type { RetryOptions } from './types';
|
|
6
|
-
/**
|
|
7
|
-
* Creates a retry middleware with smart defaults.
|
|
8
|
-
*
|
|
9
|
-
* 🎯 PIT OF SUCCESS: Works great with no config, customizable when needed.
|
|
10
|
-
*
|
|
11
|
-
* Features:
|
|
12
|
-
* - ✅ Preserves full middleware chain on retries (unlike old implementation)
|
|
13
|
-
* - ✅ Exponential backoff with jitter
|
|
14
|
-
* - ✅ Smart retry conditions (network errors + 5xx)
|
|
15
|
-
* - ✅ Configurable but sensible defaults
|
|
16
|
-
* - ✅ Type-safe configuration
|
|
17
|
-
*
|
|
18
|
-
* @param options - Retry configuration (all optional)
|
|
19
|
-
* @returns Middleware function
|
|
20
|
-
*
|
|
21
|
-
* @example Basic usage:
|
|
22
|
-
* ```typescript
|
|
23
|
-
* const client = new FetchClient();
|
|
24
|
-
* client.use(createRetryMiddleware()); // 3 retries with exponential backoff
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* @example Custom configuration:
|
|
28
|
-
* ```typescript
|
|
29
|
-
* const client = new FetchClient();
|
|
30
|
-
* client.use(createRetryMiddleware({
|
|
31
|
-
* maxRetries: 5,
|
|
32
|
-
* delay: 500,
|
|
33
|
-
* backoff: 'linear',
|
|
34
|
-
* onRetry: (attempt, delay) => console.log(`Retry ${attempt} in ${delay}ms`)
|
|
35
|
-
* }));
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export declare function createRetryMiddleware(options?: RetryOptions): FetchMiddleware;
|
|
39
|
-
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/middleware/retry/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAgD5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,YAAiB,GACzB,eAAe,CAgGjB"}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Retry middleware implementation with enhanced architecture.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Default retry condition - retry on network errors and 5xx server errors.
|
|
6
|
-
*/
|
|
7
|
-
const defaultShouldRetry = (response) => {
|
|
8
|
-
// Network errors (status 0) or server errors (5xx)
|
|
9
|
-
return (response.status === 0 || (response.status >= 500 && response.status < 600));
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Calculate delay for retry attempt based on backoff strategy.
|
|
13
|
-
*/
|
|
14
|
-
const calculateDelay = (attempt, baseDelay, backoff, maxDelay) => {
|
|
15
|
-
let delay;
|
|
16
|
-
switch (backoff) {
|
|
17
|
-
case 'exponential':
|
|
18
|
-
delay = baseDelay * Math.pow(2, attempt - 1);
|
|
19
|
-
break;
|
|
20
|
-
case 'linear':
|
|
21
|
-
delay = baseDelay * attempt;
|
|
22
|
-
break;
|
|
23
|
-
case 'fixed':
|
|
24
|
-
default:
|
|
25
|
-
delay = baseDelay;
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
return Math.min(delay, maxDelay);
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Sleep for specified duration.
|
|
32
|
-
*/
|
|
33
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
34
|
-
/**
|
|
35
|
-
* Creates a retry middleware with smart defaults.
|
|
36
|
-
*
|
|
37
|
-
* 🎯 PIT OF SUCCESS: Works great with no config, customizable when needed.
|
|
38
|
-
*
|
|
39
|
-
* Features:
|
|
40
|
-
* - ✅ Preserves full middleware chain on retries (unlike old implementation)
|
|
41
|
-
* - ✅ Exponential backoff with jitter
|
|
42
|
-
* - ✅ Smart retry conditions (network errors + 5xx)
|
|
43
|
-
* - ✅ Configurable but sensible defaults
|
|
44
|
-
* - ✅ Type-safe configuration
|
|
45
|
-
*
|
|
46
|
-
* @param options - Retry configuration (all optional)
|
|
47
|
-
* @returns Middleware function
|
|
48
|
-
*
|
|
49
|
-
* @example Basic usage:
|
|
50
|
-
* ```typescript
|
|
51
|
-
* const client = new FetchClient();
|
|
52
|
-
* client.use(createRetryMiddleware()); // 3 retries with exponential backoff
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* @example Custom configuration:
|
|
56
|
-
* ```typescript
|
|
57
|
-
* const client = new FetchClient();
|
|
58
|
-
* client.use(createRetryMiddleware({
|
|
59
|
-
* maxRetries: 5,
|
|
60
|
-
* delay: 500,
|
|
61
|
-
* backoff: 'linear',
|
|
62
|
-
* onRetry: (attempt, delay) => console.log(`Retry ${attempt} in ${delay}ms`)
|
|
63
|
-
* }));
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export function createRetryMiddleware(options = {}) {
|
|
67
|
-
const { maxRetries = 3, delay = 1000, backoff = 'exponential', maxDelay = 30000, shouldRetry = defaultShouldRetry, onRetry, } = options;
|
|
68
|
-
return async (request, next) => {
|
|
69
|
-
let lastResponse;
|
|
70
|
-
let attempt = 0;
|
|
71
|
-
while (attempt <= maxRetries) {
|
|
72
|
-
try {
|
|
73
|
-
// Execute the request through the middleware chain
|
|
74
|
-
const response = await next(request);
|
|
75
|
-
// If successful, return immediately
|
|
76
|
-
if (response.ok) {
|
|
77
|
-
return response;
|
|
78
|
-
}
|
|
79
|
-
// Check if we should retry this response with current attempt count
|
|
80
|
-
if (!shouldRetry({ status: response.status, ok: response.ok }, attempt + 1)) {
|
|
81
|
-
return response;
|
|
82
|
-
}
|
|
83
|
-
// If we've reached max retries, return the response
|
|
84
|
-
if (attempt >= maxRetries) {
|
|
85
|
-
return response;
|
|
86
|
-
}
|
|
87
|
-
// Store the failed response and increment attempt counter
|
|
88
|
-
lastResponse = response;
|
|
89
|
-
attempt++;
|
|
90
|
-
// Calculate delay for next attempt
|
|
91
|
-
const retryDelay = calculateDelay(attempt, delay, backoff, maxDelay);
|
|
92
|
-
// Call onRetry callback if provided
|
|
93
|
-
if (onRetry) {
|
|
94
|
-
onRetry(attempt, retryDelay, {
|
|
95
|
-
status: response.status,
|
|
96
|
-
statusText: response.statusText,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
// Wait before retrying
|
|
100
|
-
await sleep(retryDelay);
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
// Handle unexpected errors - treat as network error (status 0)
|
|
104
|
-
const errorResponse = {
|
|
105
|
-
data: null,
|
|
106
|
-
status: 0,
|
|
107
|
-
statusText: 'Network Error',
|
|
108
|
-
headers: new Headers(),
|
|
109
|
-
url: request.url || '',
|
|
110
|
-
ok: false,
|
|
111
|
-
error: {
|
|
112
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
113
|
-
body: error,
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
// If shouldn't retry, return error immediately
|
|
117
|
-
if (!shouldRetry(errorResponse, attempt + 1)) {
|
|
118
|
-
return errorResponse;
|
|
119
|
-
}
|
|
120
|
-
// If we've reached max retries, return the error
|
|
121
|
-
if (attempt >= maxRetries) {
|
|
122
|
-
return errorResponse;
|
|
123
|
-
}
|
|
124
|
-
lastResponse = errorResponse;
|
|
125
|
-
attempt++;
|
|
126
|
-
// Calculate delay for next attempt
|
|
127
|
-
const retryDelay = calculateDelay(attempt, delay, backoff, maxDelay);
|
|
128
|
-
if (onRetry) {
|
|
129
|
-
onRetry(attempt, retryDelay, {
|
|
130
|
-
status: errorResponse.status,
|
|
131
|
-
statusText: errorResponse.statusText,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
await sleep(retryDelay);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
// Return the last response if we've exhausted all retries
|
|
138
|
-
return lastResponse;
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
//# sourceMappingURL=retry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/middleware/retry/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Retry middleware types and configuration.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Retry configuration options - optimized for "pit of success".
|
|
6
|
-
*
|
|
7
|
-
* Smart defaults:
|
|
8
|
-
* - 3 retries (4 total attempts)
|
|
9
|
-
* - Exponential backoff starting at 1000ms
|
|
10
|
-
* - Only retry on network errors and 5xx status codes
|
|
11
|
-
*/
|
|
12
|
-
export interface RetryOptions {
|
|
13
|
-
/**
|
|
14
|
-
* Maximum number of retry attempts (default: 3)
|
|
15
|
-
* Total attempts will be maxRetries + 1
|
|
16
|
-
*/
|
|
17
|
-
maxRetries?: number;
|
|
18
|
-
/**
|
|
19
|
-
* Initial delay in milliseconds (default: 1000)
|
|
20
|
-
* Subsequent delays use exponential backoff
|
|
21
|
-
*/
|
|
22
|
-
delay?: number;
|
|
23
|
-
/**
|
|
24
|
-
* Backoff strategy (default: 'exponential')
|
|
25
|
-
* - 'exponential': delay * (2 ^ attempt)
|
|
26
|
-
* - 'linear': delay * attempt
|
|
27
|
-
* - 'fixed': always use delay
|
|
28
|
-
*/
|
|
29
|
-
backoff?: 'exponential' | 'linear' | 'fixed';
|
|
30
|
-
/**
|
|
31
|
-
* Maximum delay cap in milliseconds (default: 30000 = 30s)
|
|
32
|
-
* Prevents exponential backoff from getting too large
|
|
33
|
-
*/
|
|
34
|
-
maxDelay?: number;
|
|
35
|
-
/**
|
|
36
|
-
* Custom function to determine if a response should be retried
|
|
37
|
-
* Default: retry on network errors (status 0) and server errors (5xx)
|
|
38
|
-
*
|
|
39
|
-
* @param response - The fetch response or error
|
|
40
|
-
* @param attempt - Current attempt number (1-based)
|
|
41
|
-
* @returns true if request should be retried
|
|
42
|
-
*/
|
|
43
|
-
shouldRetry?: (response: {
|
|
44
|
-
status: number;
|
|
45
|
-
ok: boolean;
|
|
46
|
-
}, attempt: number) => boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Optional callback called before each retry attempt
|
|
49
|
-
* Useful for logging or analytics
|
|
50
|
-
*
|
|
51
|
-
* @param attempt - Current attempt number (1-based)
|
|
52
|
-
* @param delay - Delay before this retry in ms
|
|
53
|
-
* @param lastResponse - The failed response that triggered the retry
|
|
54
|
-
*/
|
|
55
|
-
onRetry?: (attempt: number, delay: number, lastResponse: {
|
|
56
|
-
status: number;
|
|
57
|
-
statusText: string;
|
|
58
|
-
}) => void;
|
|
59
|
-
}
|
|
60
|
-
export {};
|
|
61
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/middleware/retry/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;IAE7C;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,CACZ,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,EACzC,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAEb;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KACjD,IAAI,CAAC;CACX;AAGD,OAAO,EAAE,CAAC"}
|