@mpen/routekit 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.d.mts +4 -0
- package/dist/client/react.d.mts +178 -0
- package/dist/client/react.mjs +142 -0
- package/dist/client.d.mts +433 -0
- package/dist/client.mjs +264 -0
- package/dist/content-BuDOmhH_.mjs +102 -0
- package/dist/core-CzUCxvGk.d.mts +140 -0
- package/dist/core-DbmQauwS.mjs +81 -0
- package/dist/handlers.d.mts +72 -0
- package/dist/handlers.mjs +153 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +1152 -0
- package/dist/middleware.d.mts +388 -0
- package/dist/middleware.mjs +1222 -0
- package/dist/request-Dn0zc-xm.mjs +1025 -0
- package/dist/response/content.d.mts +79 -0
- package/dist/response/content.mjs +2 -0
- package/dist/response/json-rpc.d.mts +1 -0
- package/dist/response/json-rpc.mjs +1 -0
- package/dist/response/problem/valibot.d.mts +230 -0
- package/dist/response/problem/valibot.mjs +258 -0
- package/dist/response/problem.d.mts +415 -0
- package/dist/response/problem.mjs +183 -0
- package/dist/response/status.d.mts +45 -0
- package/dist/response/status.mjs +2 -0
- package/dist/responses-B379Ep9Y.d.mts +296 -0
- package/dist/responses-BpVrgeYi.mjs +101 -0
- package/dist/router-Cwb7ak0J.d.mts +1819 -0
- package/dist/routes.d.mts +282 -0
- package/dist/routes.mjs +311 -0
- package/dist/status-C-8mw-FB.mjs +59 -0
- package/dist/valibot-D7liFYyB.d.mts +290 -0
- package/dist/valibot-Du97X-TS.mjs +326 -0
- package/package.json +8 -2
- package/src/bin/gen-api-client.test.ts +0 -70
- package/src/bin/gen-api-client.ts +0 -986
- package/src/client/headers.ts +0 -31
- package/src/client/index.ts +0 -8
- package/src/client/promise.ts +0 -11
- package/src/client/react/index.test.tsx +0 -266
- package/src/client/react/index.ts +0 -431
- package/src/client/responses.test.ts +0 -151
- package/src/client/responses.ts +0 -278
- package/src/client/transport.ts +0 -74
- package/src/client/transports/body-codec.ts +0 -61
- package/src/client/transports/fetch.ts +0 -113
- package/src/client/tsconfig.json +0 -9
- package/src/client/types.ts +0 -15
- package/src/client/url.ts +0 -31
- package/src/index.ts +0 -63
- package/src/router/fetch-types.ts +0 -13
- package/src/router/handlers/index.ts +0 -2
- package/src/router/handlers/openapi/index.ts +0 -2
- package/src/router/handlers/openapi/openapi.ts +0 -293
- package/src/router/integration/zod-openapi.test.ts +0 -74
- package/src/router/lib/charset.test.ts +0 -22
- package/src/router/lib/charset.ts +0 -133
- package/src/router/lib/collections.ts +0 -3
- package/src/router/lib/format.test.ts +0 -67
- package/src/router/lib/format.ts +0 -35
- package/src/router/lib/host.ts +0 -4
- package/src/router/lib/json-schema.ts +0 -6
- package/src/router/lib/media-type.test.ts +0 -122
- package/src/router/lib/media-type.ts +0 -289
- package/src/router/lib/pathname.test.ts +0 -18
- package/src/router/lib/pathname.ts +0 -19
- package/src/router/lib/route-names.ts +0 -70
- package/src/router/lib/route-normalize.test.ts +0 -36
- package/src/router/lib/route-normalize.ts +0 -67
- package/src/router/lib/schema-merge.ts +0 -56
- package/src/router/middleware/accept-ctx.test.ts +0 -33
- package/src/router/middleware/accept-ctx.ts +0 -12
- package/src/router/middleware/body-limit.test.ts +0 -112
- package/src/router/middleware/body-limit.ts +0 -121
- package/src/router/middleware/content-type-context.ts +0 -0
- package/src/router/middleware/cors.test.ts +0 -269
- package/src/router/middleware/cors.ts +0 -490
- package/src/router/middleware/csrf.test.ts +0 -106
- package/src/router/middleware/csrf.ts +0 -192
- package/src/router/middleware/define.ts +0 -249
- package/src/router/middleware/index.ts +0 -34
- package/src/router/middleware/jsxhtml-response.ts +0 -0
- package/src/router/middleware/oas-swagger.ts +0 -0
- package/src/router/middleware/rate-limit.test.ts +0 -886
- package/src/router/middleware/rate-limit.ts +0 -920
- package/src/router/middleware/request-id-ctx.test.ts +0 -183
- package/src/router/middleware/request-id-ctx.ts +0 -135
- package/src/router/middleware/request-logger-format.test.ts +0 -16
- package/src/router/middleware/request-logger-format.ts +0 -269
- package/src/router/middleware/request-logger.test.ts +0 -267
- package/src/router/middleware/request-logger.ts +0 -131
- package/src/router/middleware/start-time-ctx.ts +0 -5
- package/src/router/request.ts +0 -611
- package/src/router/response/core.ts +0 -181
- package/src/router/response/directives.ts +0 -233
- package/src/router/response/formats/content/bodyless.ts +0 -54
- package/src/router/response/formats/content/content.ts +0 -79
- package/src/router/response/formats/content/index.ts +0 -2
- package/src/router/response/formats/json-rpc/index.ts +0 -2
- package/src/router/response/formats/problem/badRequest.ts +0 -90
- package/src/router/response/formats/problem/conflict.ts +0 -90
- package/src/router/response/formats/problem/created.ts +0 -40
- package/src/router/response/formats/problem/index.ts +0 -27
- package/src/router/response/formats/problem/notFound.ts +0 -90
- package/src/router/response/formats/problem/permissionDenied.ts +0 -90
- package/src/router/response/formats/problem/problem.test.ts +0 -888
- package/src/router/response/formats/problem/rateLimited.ts +0 -90
- package/src/router/response/formats/problem/responses.ts +0 -219
- package/src/router/response/formats/problem/root-errors.ts +0 -48
- package/src/router/response/formats/problem/sessionExpired.ts +0 -90
- package/src/router/response/formats/problem/types.ts +0 -170
- package/src/router/response/formats/problem/unauthenticated.ts +0 -90
- package/src/router/response/formats/problem/valibot.ts +0 -410
- package/src/router/response/formats/status/index.ts +0 -1
- package/src/router/response/formats/status/responses.ts +0 -59
- package/src/router/response/formats/status/status.test.ts +0 -21
- package/src/router/response/framers.ts +0 -85
- package/src/router/response/index.ts +0 -28
- package/src/router/response/openapi.test.ts +0 -96
- package/src/router/response/openapi.ts +0 -1
- package/src/router/response/serializers.ts +0 -66
- package/src/router/response/stream.ts +0 -35
- package/src/router/router.test.ts +0 -1571
- package/src/router/router.ts +0 -1965
- package/src/router/routes/index.ts +0 -46
- package/src/router/routes/valibot/index.ts +0 -18
- package/src/router/routes/valibot/valibot.ts +0 -1393
- package/src/router/routes/valibot.test.ts +0 -286
- package/src/router/routes/zod/index.ts +0 -18
- package/src/router/routes/zod/zod.ts +0 -1318
- package/src/router/routes/zod.test.ts +0 -280
- package/src/router/server-interface.ts +0 -31
- package/src/router/types.ts +0 -657
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { E as OneOrMany, O as RequestContext, a as MiddlewareResponseDeclaration, c as AcceptMediaRange, h as HandlerContext, i as MiddlewareControls, k as RequestMiddleware, n as DeclaredMiddleware, o as MiddlewareResponseDeclarations, p as ContextMiddleware, r as DefineMiddlewareOptions, s as defineMiddleware, u as AnyContext, y as MaybePromise } from "./router-Cwb7ak0J.mjs";
|
|
2
|
+
import { HttpMethod, HttpMethod as HttpMethod$1 } from "@mpen/http";
|
|
3
|
+
import { LogLevel, LogRecordTransform, TerminalLogRecordFormatter } from "@mpen/logger";
|
|
4
|
+
|
|
5
|
+
//#region src/router/middleware/request-id-ctx.d.ts
|
|
6
|
+
declare global {
|
|
7
|
+
var _reloadCounter: number;
|
|
8
|
+
var _globalRequestCounter: number;
|
|
9
|
+
}
|
|
10
|
+
interface ExtraContext {
|
|
11
|
+
prefix: string;
|
|
12
|
+
/**
|
|
13
|
+
* Number of times this server has been hot-reloaded.
|
|
14
|
+
*/
|
|
15
|
+
hotReloadCounter: number;
|
|
16
|
+
/**
|
|
17
|
+
* Sequential request number for this middleware instance.
|
|
18
|
+
*/
|
|
19
|
+
requestCounter: number;
|
|
20
|
+
/**
|
|
21
|
+
* Sequential request number across request id middleware instances.
|
|
22
|
+
*/
|
|
23
|
+
globalRequestCounter: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options for [`requestIdCtx`]{@link requestIdCtx}.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const options: RequestIdCtxOptions = {
|
|
31
|
+
* writeHeaderName: 'x-request-id',
|
|
32
|
+
* generate: () => crypto.randomUUID(),
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @typeParam Ctx - Context available before request id generation.
|
|
37
|
+
*/
|
|
38
|
+
interface RequestIdCtxOptions<Ctx extends object = AnyContext> {
|
|
39
|
+
/**
|
|
40
|
+
* Prefix used by the default generator. Defaults to an empty string.
|
|
41
|
+
*/
|
|
42
|
+
prefix?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Header(s) to check for a request id. Defaults to common request/trace headers.
|
|
45
|
+
* Set to `null` or an empty array to disable header reads.
|
|
46
|
+
*/
|
|
47
|
+
readHeaderName?: OneOrMany<string> | null;
|
|
48
|
+
/**
|
|
49
|
+
* Response header name to write the request id into.
|
|
50
|
+
*/
|
|
51
|
+
writeHeaderName?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Custom request id generator used when no read header is present.
|
|
54
|
+
*
|
|
55
|
+
* @param ctx - Current request context.
|
|
56
|
+
* @param extra - Prefix and counter values maintained by this middleware.
|
|
57
|
+
* @returns Request identifier.
|
|
58
|
+
*/
|
|
59
|
+
generate?: (ctx: HandlerContext<Ctx>, extra: ExtraContext) => string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Attach a correlated request id to every final response and contextual logger record.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* router.useRequest(requestIdCtx({
|
|
67
|
+
* readHeaderName: ['x-request-id', 'x-trace-id'],
|
|
68
|
+
* writeHeaderName: 'x-request-id',
|
|
69
|
+
* generate: () => crypto.randomUUID(),
|
|
70
|
+
* }))
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @param options - Configuration for reading, generating, and writing request ids.
|
|
74
|
+
* @returns Request-boundary middleware that populates `requestId` and logger context.
|
|
75
|
+
* @typeParam Ctx - Context available before request id generation.
|
|
76
|
+
*/
|
|
77
|
+
declare function requestIdCtx<Ctx extends object = AnyContext>(options?: RequestIdCtxOptions<Ctx>): RequestMiddleware<{
|
|
78
|
+
requestId: string;
|
|
79
|
+
}, Ctx>;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/router/middleware/request-logger.d.ts
|
|
82
|
+
/**
|
|
83
|
+
* Options for [`requestLogger`]{@link requestLogger}.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const options: RequestLoggerOptions = {
|
|
88
|
+
* completionLevel: response => response.status >= 500 ? LogLevel.ERROR : LogLevel.INFO,
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
interface RequestLoggerOptions {
|
|
93
|
+
/**
|
|
94
|
+
* Activity label used for start and completion records.
|
|
95
|
+
* @defaultValue `'request'`
|
|
96
|
+
*/
|
|
97
|
+
activityName?: string;
|
|
98
|
+
/**
|
|
99
|
+
* Completion severity or a function selecting severity from the final response.
|
|
100
|
+
*/
|
|
101
|
+
completionLevel?: LogLevel | ((response: Response) => LogLevel);
|
|
102
|
+
/**
|
|
103
|
+
* Header containing a trusted proxy-provided original client address.
|
|
104
|
+
*
|
|
105
|
+
* Only configure this when direct clients cannot provide or alter this header. For
|
|
106
|
+
* `x-forwarded-for`, the first comma-separated address is recorded as `client.address`.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* requestLogger({ trustedClientAddressHeader: 'x-forwarded-for' })
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
trustedClientAddressHeader?: string;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Log a timed request activity through the request's contextual logger.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* router.useRequest(requestIdCtx())
|
|
121
|
+
* router.useRequest(requestLogger())
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @param options - Request activity naming and severity options.
|
|
125
|
+
* @returns Request-boundary middleware that logs final status and duration.
|
|
126
|
+
* @typeParam Ctx - Context containing the correlated request identifier.
|
|
127
|
+
*/
|
|
128
|
+
declare function requestLogger<Ctx extends {
|
|
129
|
+
requestId: string;
|
|
130
|
+
} & object = AnyContext & {
|
|
131
|
+
requestId: string;
|
|
132
|
+
}>(options?: RequestLoggerOptions): RequestMiddleware<{}, Ctx>;
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/router/middleware/request-logger-format.d.ts
|
|
135
|
+
/**
|
|
136
|
+
* Transform Routekit request activity records into production JSON access logs.
|
|
137
|
+
*
|
|
138
|
+
* Removes the fallback activity message from `http.server.request` records while preserving
|
|
139
|
+
* normal application log messages written through the same contextual logger.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* import { JsonLogger } from '@mpen/logger'
|
|
144
|
+
* import { transformRoutekitJsonLogRecord } from '@mpen/routekit/middleware'
|
|
145
|
+
*
|
|
146
|
+
* const logger = new JsonLogger({
|
|
147
|
+
* transformRecord: transformRoutekitJsonLogRecord,
|
|
148
|
+
* })
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* @param record - Record emitted by a logger.
|
|
152
|
+
* @returns The transformed record, or `undefined` to use the original record.
|
|
153
|
+
*/
|
|
154
|
+
declare const transformRoutekitJsonLogRecord: LogRecordTransform;
|
|
155
|
+
/**
|
|
156
|
+
* Format Routekit request context for terminal logs.
|
|
157
|
+
*
|
|
158
|
+
* Renders compact request start/completion lines, color-correlated request identifiers, status
|
|
159
|
+
* codes, elapsed time, and response sizes while leaving unrelated records to
|
|
160
|
+
* [`TerminalLogger`]{@link import('@mpen/logger').TerminalLogger}'s default renderer.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* import { TerminalLogger } from '@mpen/logger'
|
|
165
|
+
* import { formatRoutekitTerminalLogRecord } from '@mpen/routekit/middleware'
|
|
166
|
+
*
|
|
167
|
+
* const logger = new TerminalLogger({
|
|
168
|
+
* formatRecord: formatRoutekitTerminalLogRecord,
|
|
169
|
+
* })
|
|
170
|
+
* ```
|
|
171
|
+
*
|
|
172
|
+
* @param record - Record emitted by a logger.
|
|
173
|
+
* @param terminal - Terminal formatting helpers.
|
|
174
|
+
* @returns Formatted terminal output, or `undefined` to use the default renderer.
|
|
175
|
+
*/
|
|
176
|
+
declare const formatRoutekitTerminalLogRecord: TerminalLogRecordFormatter;
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/router/middleware/body-limit.d.ts
|
|
179
|
+
interface MaxContentSizeOptions {
|
|
180
|
+
maxSize: number;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Enforce a maximum request body size while preserving access to the incoming stream.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* router.use(bodyLimit({maxSize: 1024 * 1024}))
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @param options - Configuration for maximum request body size enforcement.
|
|
191
|
+
* @returns Middleware that rejects oversized bodies and mismatched Content-Length values.
|
|
192
|
+
*/
|
|
193
|
+
declare function bodyLimit<Ctx extends object = AnyContext>(options: MaxContentSizeOptions): DeclaredMiddleware<{}, Ctx>;
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/router/middleware/start-time-ctx.d.ts
|
|
196
|
+
declare const startTimeCtx: () => ContextMiddleware<{
|
|
197
|
+
startTime: number;
|
|
198
|
+
}>;
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/router/middleware/accept-ctx.d.ts
|
|
201
|
+
/**
|
|
202
|
+
* Attach parsed Accept header values to the request context.
|
|
203
|
+
*
|
|
204
|
+
* @returns Middleware that adds `accept` to the request context.
|
|
205
|
+
*/
|
|
206
|
+
declare const acceptCtx: () => ContextMiddleware<{
|
|
207
|
+
accept: AcceptMediaRange[];
|
|
208
|
+
}>;
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region src/router/middleware/cors.d.ts
|
|
211
|
+
type CorsOriginResolver<Ctx extends object> = (origin: string | null, ctx: RequestContext<Ctx>) => MaybePromise<string | null | undefined | false>;
|
|
212
|
+
type CorsMethodsResolver<Ctx extends object> = (origin: string | null, ctx: RequestContext<Ctx>) => MaybePromise<OneOrMany<string>>;
|
|
213
|
+
interface CorsOptions<Ctx extends object = AnyContext> {
|
|
214
|
+
/**
|
|
215
|
+
* Allowed origin(s) for cross-origin requests.
|
|
216
|
+
* Use `'*'` to allow all origins.
|
|
217
|
+
*/
|
|
218
|
+
origin: OneOrMany<string | URL | RegExp> | CorsOriginResolver<Ctx>;
|
|
219
|
+
/**
|
|
220
|
+
* Allowed methods to echo in preflight responses.
|
|
221
|
+
*/
|
|
222
|
+
allowMethods?: OneOrMany<string> | CorsMethodsResolver<Ctx>;
|
|
223
|
+
/**
|
|
224
|
+
* Allowed headers to echo in preflight responses.
|
|
225
|
+
*/
|
|
226
|
+
allowHeaders?: OneOrMany<string>;
|
|
227
|
+
/**
|
|
228
|
+
* Response headers that should be exposed to the browser.
|
|
229
|
+
*/
|
|
230
|
+
exposeHeaders?: OneOrMany<string>;
|
|
231
|
+
/**
|
|
232
|
+
* Max age (seconds) for caching preflight responses.
|
|
233
|
+
*/
|
|
234
|
+
maxAge?: number;
|
|
235
|
+
/**
|
|
236
|
+
* Whether to set Access-Control-Allow-Credentials.
|
|
237
|
+
*/
|
|
238
|
+
credentials?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Allow localhost and loopback origins for local development.
|
|
241
|
+
*/
|
|
242
|
+
allowLocalhost?: boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Convenience flag that enables localhost allowances.
|
|
245
|
+
*/
|
|
246
|
+
dev?: boolean;
|
|
247
|
+
/**
|
|
248
|
+
* HTTP status to use for preflight responses.
|
|
249
|
+
*/
|
|
250
|
+
preflightStatus?: number;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Attach CORS response headers and handle OPTIONS preflight requests.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* router.use(cors({origin: '*'}))
|
|
258
|
+
* router.use(cors({origin: ['https://app.example.com'], credentials: true}))
|
|
259
|
+
* router.use(cors({origin: 'https://app.example.com', dev: true}))
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* @param options - Configuration for origin, preflight, and header behavior.
|
|
263
|
+
* @returns Middleware that applies CORS headers to matching requests.
|
|
264
|
+
*/
|
|
265
|
+
declare function cors<Ctx extends object = AnyContext>(options: CorsOptions<Ctx>): DeclaredMiddleware<{}, Ctx>;
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/router/middleware/rate-limit.d.ts
|
|
268
|
+
interface RateBucket {
|
|
269
|
+
windowMs: number;
|
|
270
|
+
scale: number;
|
|
271
|
+
}
|
|
272
|
+
interface AsnRecord {
|
|
273
|
+
asn: number;
|
|
274
|
+
organization: string;
|
|
275
|
+
}
|
|
276
|
+
interface RateLimitIdentityInput {
|
|
277
|
+
userId: string | number | null | undefined;
|
|
278
|
+
ipAddress: string;
|
|
279
|
+
}
|
|
280
|
+
type MethodLimit = number | Partial<Record<HttpMethod$1, number>>;
|
|
281
|
+
interface EndpointLimit {
|
|
282
|
+
pattern: string | URLPattern | ConstructorParameters<typeof URLPattern>;
|
|
283
|
+
/**
|
|
284
|
+
* Max requests per baseWindowMs before bucket expansion.
|
|
285
|
+
*/
|
|
286
|
+
limit: MethodLimit;
|
|
287
|
+
}
|
|
288
|
+
type AsnClass = 'cloud' | 'hosting' | 'cdn' | 'residential' | 'mobile' | 'unknown' | (string & {});
|
|
289
|
+
interface FixedWindowCounter {
|
|
290
|
+
resetAtMs: number;
|
|
291
|
+
count: number;
|
|
292
|
+
}
|
|
293
|
+
interface RateLimitStorage<C> {
|
|
294
|
+
/**
|
|
295
|
+
* Return null/undefined if missing or expired.
|
|
296
|
+
*/
|
|
297
|
+
readCounter(ctx: C, key: string): Promise<FixedWindowCounter | null | undefined>;
|
|
298
|
+
/**
|
|
299
|
+
* ttlMs MUST be respected by the implementation.
|
|
300
|
+
* Redis implementations should set key expiry accordingly.
|
|
301
|
+
*/
|
|
302
|
+
writeCounter(ctx: C, key: string, counter: FixedWindowCounter, ttlMs: number): Promise<void>;
|
|
303
|
+
}
|
|
304
|
+
interface RateLimitOptions<C> {
|
|
305
|
+
getUserId(ctx: C): Promise<string | number | null | undefined>;
|
|
306
|
+
/**
|
|
307
|
+
* Default implementation:
|
|
308
|
+
* - X-Forwarded-For (first IP)
|
|
309
|
+
* - else X-Real-IP
|
|
310
|
+
*/
|
|
311
|
+
getIpAddress?: (ctx: C) => Promise<string>;
|
|
312
|
+
/**
|
|
313
|
+
* Used to scale country + ASN caps.
|
|
314
|
+
* Called once during initialization.
|
|
315
|
+
*/
|
|
316
|
+
getGlobalPeakConcurrentUsers(ctx: C): Promise<number>;
|
|
317
|
+
baseWindowMs: number;
|
|
318
|
+
baseMaxRequestsPerBaseWindow: number;
|
|
319
|
+
/**
|
|
320
|
+
* Applied when userId is falsy and identity falls back to IP.
|
|
321
|
+
*/
|
|
322
|
+
anonymousIpMultiplier: number;
|
|
323
|
+
addRetryAfterHeader: boolean;
|
|
324
|
+
buckets: RateBucket[];
|
|
325
|
+
normalizeQuery?: (url: URL) => string;
|
|
326
|
+
endpointLimits: EndpointLimit[];
|
|
327
|
+
includeQueryInEndpointKey: boolean;
|
|
328
|
+
maxmindAsnDatabase?: string;
|
|
329
|
+
maxmindCountryDatabase?: string;
|
|
330
|
+
getAsn?(ctx: C, input: RateLimitIdentityInput): Promise<AsnRecord | null>;
|
|
331
|
+
getCountryCode?(ctx: C, input: RateLimitIdentityInput): Promise<string | null>;
|
|
332
|
+
asnToClass?: (asn: number, organization: string) => AsnClass;
|
|
333
|
+
scales: {
|
|
334
|
+
country?: Record<string, number> & {
|
|
335
|
+
unknown: number;
|
|
336
|
+
other: number;
|
|
337
|
+
};
|
|
338
|
+
asnClass?: Record<string, number> & {
|
|
339
|
+
unknown: number;
|
|
340
|
+
};
|
|
341
|
+
subnet: {
|
|
342
|
+
ipv4: number;
|
|
343
|
+
ipv6: number;
|
|
344
|
+
byAsnClass?: Record<string, number> & {
|
|
345
|
+
unknown: number;
|
|
346
|
+
};
|
|
347
|
+
ipv4Prefix?: number;
|
|
348
|
+
ipv6Prefix?: number;
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* If omitted, use in-memory LRU store.
|
|
353
|
+
*/
|
|
354
|
+
storage?: RateLimitStorage<C>;
|
|
355
|
+
inMemory?: {
|
|
356
|
+
maxEntries?: number;
|
|
357
|
+
/**
|
|
358
|
+
* Extra retention (ms) after the fixed window reset before eviction.
|
|
359
|
+
* Defaults to 1000ms for a small safety buffer.
|
|
360
|
+
*/
|
|
361
|
+
ttlMs?: number;
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Enforce per-identity, subnet, ASN, country, and endpoint rate limits using fixed-window buckets.
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```ts
|
|
369
|
+
* router.use(rateLimit({
|
|
370
|
+
* getUserId: async ({user}) => user?.id,
|
|
371
|
+
* getGlobalPeakConcurrentUsers: async () => 5000,
|
|
372
|
+
* baseWindowMs: 60_000,
|
|
373
|
+
* baseMaxRequestsPerBaseWindow: 120,
|
|
374
|
+
* anonymousIpMultiplier: 0.5,
|
|
375
|
+
* addRetryAfterHeader: true,
|
|
376
|
+
* buckets: [{windowMs: 60_000, scale: 1}],
|
|
377
|
+
* endpointLimits: [{pattern: '/login', limit: {POST: 10}}],
|
|
378
|
+
* includeQueryInEndpointKey: false,
|
|
379
|
+
* scales: {subnet: {ipv4: 2, ipv6: 1}},
|
|
380
|
+
* }))
|
|
381
|
+
* ```
|
|
382
|
+
*
|
|
383
|
+
* @param options - Configuration for identity sources, buckets, scaling, and storage.
|
|
384
|
+
* @returns Middleware that enforces rate limits and returns 429 responses when exceeded.
|
|
385
|
+
*/
|
|
386
|
+
declare function rateLimit<Ctx extends object = AnyContext>(options: RateLimitOptions<RequestContext<Ctx>>): DeclaredMiddleware<{}, Ctx>;
|
|
387
|
+
//#endregion
|
|
388
|
+
export { type AsnClass, type AsnRecord, type CorsOptions, type DeclaredMiddleware, type DefineMiddlewareOptions, type EndpointLimit, type FixedWindowCounter, type HttpMethod, type MethodLimit, type MiddlewareControls, type MiddlewareResponseDeclaration, type MiddlewareResponseDeclarations, type RateBucket, type RateLimitIdentityInput, type RateLimitOptions, type RateLimitStorage, type RequestIdCtxOptions, type RequestLoggerOptions, acceptCtx, bodyLimit, cors, defineMiddleware, formatRoutekitTerminalLogRecord, rateLimit, requestIdCtx, requestLogger, startTimeCtx, transformRoutekitJsonLogRecord };
|