@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
package/src/router/types.ts
DELETED
|
@@ -1,657 +0,0 @@
|
|
|
1
|
-
import type { HttpMethod } from '@mpen/http'
|
|
2
|
-
import type { Logger } from '@mpen/logger'
|
|
3
|
-
import type { Router } from './router'
|
|
4
|
-
import type { RouterBodyInit } from './fetch-types'
|
|
5
|
-
import type { DeclaredMiddleware } from './middleware/define'
|
|
6
|
-
import type { RequestBodyParser, RoutekitRequest } from './request'
|
|
7
|
-
import type {
|
|
8
|
-
ResponseBodySerializer,
|
|
9
|
-
RoutekitBody,
|
|
10
|
-
RoutekitResponse,
|
|
11
|
-
RoutekitYield,
|
|
12
|
-
} from './response'
|
|
13
|
-
|
|
14
|
-
export type NonEmptyArray<T> = [T, ...T[]]
|
|
15
|
-
export type OneOrMany<T> = T | NonEmptyArray<T>
|
|
16
|
-
export type MaybePromise<T> = T | Promise<T>
|
|
17
|
-
export type RoutePath = string | URLPattern
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* JSON Schema value used for runtime request and response metadata.
|
|
21
|
-
*/
|
|
22
|
-
export type JsonSchema = boolean | Record<string, unknown>
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* JSON Schema object used for path and query parameter declarations.
|
|
26
|
-
*/
|
|
27
|
-
export type JsonObjectSchema = Record<string, unknown>
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Schema metadata used to describe route request inputs and response bodies.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```ts
|
|
34
|
-
* const schema: RouteSchema = {
|
|
35
|
-
* request: {
|
|
36
|
-
* query: {
|
|
37
|
-
* type: 'object',
|
|
38
|
-
* properties: {
|
|
39
|
-
* page: {type: 'integer'},
|
|
40
|
-
* },
|
|
41
|
-
* },
|
|
42
|
-
* path: {
|
|
43
|
-
* type: 'object',
|
|
44
|
-
* properties: {
|
|
45
|
-
* id: {type: 'string'},
|
|
46
|
-
* },
|
|
47
|
-
* required: ['id'],
|
|
48
|
-
* },
|
|
49
|
-
* body: {
|
|
50
|
-
* type: 'object',
|
|
51
|
-
* properties: {
|
|
52
|
-
* name: {type: 'string'},
|
|
53
|
-
* },
|
|
54
|
-
* required: ['name'],
|
|
55
|
-
* },
|
|
56
|
-
* },
|
|
57
|
-
* response: {
|
|
58
|
-
* body: {
|
|
59
|
-
* 200: {
|
|
60
|
-
* type: 'object',
|
|
61
|
-
* properties: {
|
|
62
|
-
* ok: {type: 'boolean'},
|
|
63
|
-
* },
|
|
64
|
-
* required: ['ok'],
|
|
65
|
-
* },
|
|
66
|
-
* },
|
|
67
|
-
* },
|
|
68
|
-
* }
|
|
69
|
-
* ```
|
|
70
|
-
*/
|
|
71
|
-
export interface RouteSchema {
|
|
72
|
-
request?: {
|
|
73
|
-
query?: JsonObjectSchema
|
|
74
|
-
path?: JsonObjectSchema
|
|
75
|
-
body?: JsonSchema
|
|
76
|
-
}
|
|
77
|
-
response?: {
|
|
78
|
-
body?: Partial<Record<number | 'default', JsonSchema>>
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Custom request matcher used when a route needs logic beyond pathname, method, or `accept`.
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* ```ts
|
|
87
|
-
* const match: RouteMatch = request => request.headers.get('x-internal') === 'true'
|
|
88
|
-
* ```
|
|
89
|
-
*
|
|
90
|
-
* @param request - Incoming request to test.
|
|
91
|
-
* @returns `true` when the route should handle the request.
|
|
92
|
-
*/
|
|
93
|
-
export type RouteMatch = (request: RoutekitRequest) => boolean
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Route metadata used by tooling like OpenAPI generation.
|
|
97
|
-
*/
|
|
98
|
-
export interface RouteMeta {
|
|
99
|
-
/**
|
|
100
|
-
* OpenAPI operation metadata for this route.
|
|
101
|
-
*/
|
|
102
|
-
openapi?: Record<string, unknown>
|
|
103
|
-
[key: string]: unknown
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
type AddedContextOf<Middleware> =
|
|
107
|
-
Exclude<Middleware, null | undefined | false> extends DeclaredMiddleware<infer AddedCtx, any>
|
|
108
|
-
? AddedCtx
|
|
109
|
-
: Exclude<Middleware, null | undefined | false> extends ContextMiddleware<
|
|
110
|
-
infer AddedCtx,
|
|
111
|
-
any
|
|
112
|
-
>
|
|
113
|
-
? AddedCtx
|
|
114
|
-
: Exclude<Middleware, null | undefined | false> extends RequestMiddleware<
|
|
115
|
-
infer AddedCtx,
|
|
116
|
-
any
|
|
117
|
-
>
|
|
118
|
-
? AddedCtx
|
|
119
|
-
: {}
|
|
120
|
-
|
|
121
|
-
type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends (
|
|
122
|
-
value: infer Intersection,
|
|
123
|
-
) => void
|
|
124
|
-
? Intersection
|
|
125
|
-
: never
|
|
126
|
-
|
|
127
|
-
type AddedContextFromList<List extends readonly unknown[]> = List extends readonly [
|
|
128
|
-
infer First,
|
|
129
|
-
...infer Rest,
|
|
130
|
-
]
|
|
131
|
-
? AddedContextOf<First> & AddedContextFromList<Rest>
|
|
132
|
-
: number extends List['length']
|
|
133
|
-
? UnionToIntersection<AddedContextOf<List[number]>>
|
|
134
|
-
: {}
|
|
135
|
-
|
|
136
|
-
type ContextOf<Middleware> =
|
|
137
|
-
Exclude<Middleware, null | undefined | false> extends DeclaredMiddleware<any, infer Ctx>
|
|
138
|
-
? Ctx
|
|
139
|
-
: Exclude<Middleware, null | undefined | false> extends ContextMiddleware<any, infer Ctx>
|
|
140
|
-
? Ctx
|
|
141
|
-
: Exclude<Middleware, null | undefined | false> extends RequestMiddleware<any, infer Ctx>
|
|
142
|
-
? Ctx
|
|
143
|
-
: object
|
|
144
|
-
|
|
145
|
-
type ContextFromList<List extends readonly unknown[]> = List extends readonly [
|
|
146
|
-
infer First,
|
|
147
|
-
...infer Rest,
|
|
148
|
-
]
|
|
149
|
-
? ContextOf<First> & ContextFromList<Rest>
|
|
150
|
-
: number extends List['length']
|
|
151
|
-
? UnionToIntersection<ContextOf<List[number]>>
|
|
152
|
-
: object
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Context added by a middleware value or middleware list.
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```ts
|
|
159
|
-
* type AuthContext = AddedContextFromMiddlewareInput<typeof requireAuth>
|
|
160
|
-
* ```
|
|
161
|
-
*
|
|
162
|
-
* @typeParam Middleware - Middleware value or list whose added context should be inferred.
|
|
163
|
-
*/
|
|
164
|
-
export type AddedContextFromMiddlewareInput<Middleware> = Middleware extends readonly unknown[]
|
|
165
|
-
? AddedContextFromList<Middleware>
|
|
166
|
-
: AddedContextOf<Middleware>
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Base context expected by a middleware value or middleware list.
|
|
170
|
-
*
|
|
171
|
-
* @example
|
|
172
|
-
* ```ts
|
|
173
|
-
* type ServicesContext = ContextFromMiddlewareInput<typeof requireAuth>
|
|
174
|
-
* ```
|
|
175
|
-
*
|
|
176
|
-
* @typeParam Middleware - Middleware value or list whose base context should be inferred.
|
|
177
|
-
*/
|
|
178
|
-
export type ContextFromMiddlewareInput<Middleware> = Middleware extends readonly unknown[]
|
|
179
|
-
? ContextFromList<Middleware>
|
|
180
|
-
: ContextOf<Middleware>
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Declarative route definition that the router can normalize and register.
|
|
184
|
-
*
|
|
185
|
-
* @example
|
|
186
|
-
* ```ts
|
|
187
|
-
* const route: Route = {
|
|
188
|
-
* name: 'user.detail',
|
|
189
|
-
* method: HttpMethod.GET,
|
|
190
|
-
* path: '/users/:id',
|
|
191
|
-
* handler: async ({request}) => new Response(await request.body.text()),
|
|
192
|
-
* }
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
export interface Route<
|
|
196
|
-
Ctx extends object = AnyContext,
|
|
197
|
-
RouteMiddleware extends MiddlewareInput<Ctx> = undefined,
|
|
198
|
-
HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>,
|
|
199
|
-
> {
|
|
200
|
-
name?: OneOrMany<string>
|
|
201
|
-
/**
|
|
202
|
-
* Path pattern matched by the default route matcher.
|
|
203
|
-
*/
|
|
204
|
-
path: RoutePath
|
|
205
|
-
handler: Handler<any, HandlerCtx>
|
|
206
|
-
method?: OneOrMany<HttpMethod>
|
|
207
|
-
/**
|
|
208
|
-
* Middleware applied only to this route after router and mount middleware.
|
|
209
|
-
*
|
|
210
|
-
* @example
|
|
211
|
-
* ```ts
|
|
212
|
-
* const route: Route = {
|
|
213
|
-
* path: '/me',
|
|
214
|
-
* middleware: auth(),
|
|
215
|
-
* handler: ({userId}) => new Response(userId),
|
|
216
|
-
* }
|
|
217
|
-
* ```
|
|
218
|
-
*/
|
|
219
|
-
middleware?: RouteMiddleware
|
|
220
|
-
/**
|
|
221
|
-
* Optional custom matcher. When omitted, the router matches using `path`, `method`, and `accept`.
|
|
222
|
-
*/
|
|
223
|
-
match?: RouteMatch
|
|
224
|
-
/**
|
|
225
|
-
* Arbitrary metadata attached to the route.
|
|
226
|
-
*
|
|
227
|
-
* @example
|
|
228
|
-
* ```ts
|
|
229
|
-
* const route: Route = {
|
|
230
|
-
* path: '/pets',
|
|
231
|
-
* method: HttpMethod.GET,
|
|
232
|
-
* meta: {
|
|
233
|
-
* openapi: {
|
|
234
|
-
* description: 'Returns all pets from the system that the user has access to',
|
|
235
|
-
* responses: {
|
|
236
|
-
* 200: {description: 'A list of pets'},
|
|
237
|
-
* },
|
|
238
|
-
* },
|
|
239
|
-
* },
|
|
240
|
-
* handler: () => new Response('ok'),
|
|
241
|
-
* }
|
|
242
|
-
* ```
|
|
243
|
-
*/
|
|
244
|
-
meta?: RouteMeta
|
|
245
|
-
/**
|
|
246
|
-
* Expected media type(s) for the incoming request body. When provided, the router compares each
|
|
247
|
-
* entry against the incoming `Content-Type` header.
|
|
248
|
-
*
|
|
249
|
-
* @example
|
|
250
|
-
* ```ts
|
|
251
|
-
* const route: Route = {
|
|
252
|
-
* path: '/upload',
|
|
253
|
-
* method: HttpMethod.POST,
|
|
254
|
-
* accept: ['multipart/form-data', {type: 'application/json'}],
|
|
255
|
-
* handler: async () => new Response('ok'),
|
|
256
|
-
* }
|
|
257
|
-
* ```
|
|
258
|
-
*/
|
|
259
|
-
accept?: OneOrMany<string | MediaType>
|
|
260
|
-
/**
|
|
261
|
-
* Runtime request and response schemas used by tooling such as OpenAPI generation and API client codegen.
|
|
262
|
-
*/
|
|
263
|
-
schema?: RouteSchema
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Route definition fields accepted by method-specific router helpers.
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* ```ts
|
|
271
|
-
* const options: RouteOptions = {
|
|
272
|
-
* name: 'user.detail',
|
|
273
|
-
* handler: async ({request}) => new Response(request.url),
|
|
274
|
-
* }
|
|
275
|
-
* router.get('/users/:id', options)
|
|
276
|
-
* ```
|
|
277
|
-
*/
|
|
278
|
-
export type RouteOptions<
|
|
279
|
-
Ctx extends object = AnyContext,
|
|
280
|
-
RouteMiddleware extends MiddlewareInput<Ctx> = undefined,
|
|
281
|
-
HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>,
|
|
282
|
-
> = Omit<Route<Ctx, RouteMiddleware, HandlerCtx>, 'method' | 'path'>
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Normalized route metadata used internally by the router.
|
|
286
|
-
*
|
|
287
|
-
* @example
|
|
288
|
-
* ```ts
|
|
289
|
-
* const route: NormalizedRoute = {
|
|
290
|
-
* name: ['user', 'detail'],
|
|
291
|
-
* method: HttpMethod.GET,
|
|
292
|
-
* path: new URLPattern({pathname: '/users/:id'}),
|
|
293
|
-
* handler: async ({request}) => new Response(await request.body.text()),
|
|
294
|
-
* }
|
|
295
|
-
* ```
|
|
296
|
-
*/
|
|
297
|
-
export interface NormalizedRoute<Ctx extends object = AnyContext> {
|
|
298
|
-
name: string[]
|
|
299
|
-
path: URLPattern
|
|
300
|
-
handler: Handler<any, Ctx>
|
|
301
|
-
method?: HttpMethod | HttpMethod[]
|
|
302
|
-
accept?: MediaType[]
|
|
303
|
-
match?: RouteMatch
|
|
304
|
-
meta?: RouteMeta
|
|
305
|
-
schema?: RouteSchema
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Parameterized HTTP `Content-Type` media type.
|
|
310
|
-
*
|
|
311
|
-
* @example
|
|
312
|
-
* ```ts
|
|
313
|
-
* const contentType: ContentType = {type: 'application/json', charset: 'utf-8'}
|
|
314
|
-
* ```
|
|
315
|
-
*/
|
|
316
|
-
export type ContentType = {
|
|
317
|
-
type: string
|
|
318
|
-
charset?: string
|
|
319
|
-
boundary?: string
|
|
320
|
-
parameters?: Record<string, string>
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Backwards-compatible alias for a concrete media type.
|
|
325
|
-
*
|
|
326
|
-
* @example
|
|
327
|
-
* ```ts
|
|
328
|
-
* const media: MediaType = {type: 'application/json'}
|
|
329
|
-
* ```
|
|
330
|
-
*/
|
|
331
|
-
export type MediaType = ContentType
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Media range parsed from an HTTP `Accept` header.
|
|
335
|
-
*
|
|
336
|
-
* @example
|
|
337
|
-
* ```ts
|
|
338
|
-
* const accept: AcceptMediaRange = {type: 'application/json', q: 1}
|
|
339
|
-
* ```
|
|
340
|
-
*/
|
|
341
|
-
export type AcceptMediaRange = ContentType & {
|
|
342
|
-
q: number
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Generic context dictionary used when no custom context type is provided.
|
|
347
|
-
*
|
|
348
|
-
* @example
|
|
349
|
-
* ```ts
|
|
350
|
-
* const ctx: AnyContext = {featureFlag: true}
|
|
351
|
-
* ```
|
|
352
|
-
*/
|
|
353
|
-
export type AnyContext = Record<string, any>
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Extension hook that intentionally configures a router instance.
|
|
357
|
-
*
|
|
358
|
-
* @example
|
|
359
|
-
* ```ts
|
|
360
|
-
* const extension: RouterExtension = router => {
|
|
361
|
-
* router.onNotFound(() => new Response('missing', {status: 404}))
|
|
362
|
-
* }
|
|
363
|
-
*
|
|
364
|
-
* new Router().install(extension)
|
|
365
|
-
* ```
|
|
366
|
-
*
|
|
367
|
-
* @typeParam Ctx - Context carried by the router being configured.
|
|
368
|
-
*/
|
|
369
|
-
export type RouterExtension<Ctx extends object = AnyContext> = (router: Router<Ctx>) => void
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Request context made available to middleware.
|
|
373
|
-
* Extended data can be attached by middleware via the generic parameter.
|
|
374
|
-
*
|
|
375
|
-
* @example
|
|
376
|
-
* ```ts
|
|
377
|
-
* const middleware: ContextMiddleware<{userId: string}> = ctx => {
|
|
378
|
-
* ctx.userId = 'user-123'
|
|
379
|
-
* }
|
|
380
|
-
* ```
|
|
381
|
-
*/
|
|
382
|
-
export type RequestContext<Ctx extends object = AnyContext> = {
|
|
383
|
-
/**
|
|
384
|
-
* Routekit request wrapper for the current request.
|
|
385
|
-
*/
|
|
386
|
-
request: RoutekitRequest
|
|
387
|
-
/**
|
|
388
|
-
* Contextual logger selected for the current request.
|
|
389
|
-
*/
|
|
390
|
-
logger: Logger
|
|
391
|
-
} & Ctx
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Context object provided to route handlers.
|
|
395
|
-
* Includes request metadata as well as any context extensions added by middleware.
|
|
396
|
-
*
|
|
397
|
-
* @example
|
|
398
|
-
* ```ts
|
|
399
|
-
* const handler: HandlerContext = {
|
|
400
|
-
* request,
|
|
401
|
-
* url: new URL('https://example.com/users/123'),
|
|
402
|
-
* path: {id: '123'},
|
|
403
|
-
* }
|
|
404
|
-
* ```
|
|
405
|
-
*/
|
|
406
|
-
export type HandlerContext<Ctx extends object = AnyContext> = RequestContext<Ctx> & {
|
|
407
|
-
/**
|
|
408
|
-
* Parsed request URL for convenience.
|
|
409
|
-
*/
|
|
410
|
-
url: URL
|
|
411
|
-
/**
|
|
412
|
-
* Route path parameters extracted from the matched URL pattern.
|
|
413
|
-
*/
|
|
414
|
-
path: unknown
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Values yielded by generator-style handlers.
|
|
419
|
-
*
|
|
420
|
-
* @example
|
|
421
|
-
* ```ts
|
|
422
|
-
* async function* handler() {
|
|
423
|
-
* yield head(HttpStatus.OK, {'cache-control': 'no-store'})
|
|
424
|
-
* return {ok: true}
|
|
425
|
-
* }
|
|
426
|
-
* ```
|
|
427
|
-
*/
|
|
428
|
-
export type HandlerYield = RoutekitYield
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Native body value that can be passed to the Fetch [`Response`]{@link Response} constructor.
|
|
432
|
-
*
|
|
433
|
-
* @example
|
|
434
|
-
* ```ts
|
|
435
|
-
* const body: HandlerBody = 'ok'
|
|
436
|
-
* ```
|
|
437
|
-
*/
|
|
438
|
-
export type HandlerBody = RouterBodyInit | null | undefined
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Final value a handler or generator may return.
|
|
442
|
-
*/
|
|
443
|
-
export type HandlerFinalResult<TOkRes = unknown> =
|
|
444
|
-
| Response
|
|
445
|
-
| RoutekitResponse<TOkRes>
|
|
446
|
-
| RoutekitBody<TOkRes>
|
|
447
|
-
| TOkRes
|
|
448
|
-
| HandlerBody
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
* Allowed handler return values.
|
|
452
|
-
*
|
|
453
|
-
* @example
|
|
454
|
-
* ```ts
|
|
455
|
-
* const handler: Handler = async ({request}) => new Response(await request.body.text())
|
|
456
|
-
* ```
|
|
457
|
-
*/
|
|
458
|
-
export type HandlerResult<TOkRes = unknown> =
|
|
459
|
-
| HandlerFinalResult<TOkRes>
|
|
460
|
-
| Promise<HandlerFinalResult<TOkRes> | AsyncGenerator<HandlerYield, HandlerFinalResult<TOkRes>>>
|
|
461
|
-
| AsyncGenerator<HandlerYield, HandlerFinalResult<TOkRes>>
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Route handler signature that preserves generic type parameters for API generation.
|
|
465
|
-
*
|
|
466
|
-
* @example
|
|
467
|
-
* ```ts
|
|
468
|
-
* const handler: Handler = ({path}) => {
|
|
469
|
-
* return JSON.stringify(path)
|
|
470
|
-
* }
|
|
471
|
-
* ```
|
|
472
|
-
*
|
|
473
|
-
* The handler is invoked with `this` bound to the active [`Router`]{@link Router}.
|
|
474
|
-
*
|
|
475
|
-
* @param ctx - Handler context containing the incoming [`RoutekitRequest`]{@link RoutekitRequest}, parsed [`URL`]{@link URL}, path parameters, and middleware extensions.
|
|
476
|
-
* @returns A response, a serializable value handled by middleware, or a streaming generator that yields response metadata.
|
|
477
|
-
*/
|
|
478
|
-
export type Handler<TOkRes = unknown, Ctx extends object = AnyContext> = (
|
|
479
|
-
this: Router<any>,
|
|
480
|
-
ctx: HandlerContext<Ctx>,
|
|
481
|
-
) => HandlerResult<TOkRes>
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* Middleware that extends request context and then continues routing.
|
|
485
|
-
*
|
|
486
|
-
* @example
|
|
487
|
-
* ```ts
|
|
488
|
-
* const addRequestId = (): ContextMiddleware<{requestId: number}> => ctx => {
|
|
489
|
-
* ctx.requestId = 123
|
|
490
|
-
* }
|
|
491
|
-
* ```
|
|
492
|
-
*
|
|
493
|
-
* @param ctx - Request context for the current request, including any added fields.
|
|
494
|
-
* @returns Nothing, or a promise resolved after context initialization.
|
|
495
|
-
*/
|
|
496
|
-
export type ContextMiddleware<
|
|
497
|
-
AddedCtx extends object = AnyContext,
|
|
498
|
-
Ctx extends object = AnyContext,
|
|
499
|
-
> = (ctx: RequestContext<Ctx & AddedCtx>) => void | Promise<void>
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Middleware that surrounds final response production for every incoming request.
|
|
503
|
-
*
|
|
504
|
-
* @example
|
|
505
|
-
* ```ts
|
|
506
|
-
* const timing: RequestMiddleware = async (ctx, next) => {
|
|
507
|
-
* const started = performance.now()
|
|
508
|
-
* const response = await next()
|
|
509
|
-
* ctx.logger.info('completed', {duration: performance.now() - started})
|
|
510
|
-
* return response
|
|
511
|
-
* }
|
|
512
|
-
* ```
|
|
513
|
-
*
|
|
514
|
-
* @param ctx - Request context shared with downstream middleware and handlers.
|
|
515
|
-
* @param next - Continue processing and obtain the final response.
|
|
516
|
-
* @returns The final response, optionally decorated by the middleware.
|
|
517
|
-
* @typeParam AddedCtx - Context fields made available to downstream processing.
|
|
518
|
-
* @typeParam Ctx - Context required before this middleware executes.
|
|
519
|
-
*/
|
|
520
|
-
export type RequestMiddleware<AddedCtx extends object = {}, Ctx extends object = AnyContext> = (
|
|
521
|
-
ctx: HandlerContext<Ctx & AddedCtx>,
|
|
522
|
-
next: () => Promise<Response>,
|
|
523
|
-
) => Response | Promise<Response>
|
|
524
|
-
|
|
525
|
-
/**
|
|
526
|
-
* Middleware entry accepted inside typed middleware lists.
|
|
527
|
-
*
|
|
528
|
-
* @example
|
|
529
|
-
* ```ts
|
|
530
|
-
* const middleware = [auth(), false] satisfies MiddlewareEntry[]
|
|
531
|
-
* ```
|
|
532
|
-
*
|
|
533
|
-
* @typeParam Ctx - Base context available before this middleware runs.
|
|
534
|
-
*/
|
|
535
|
-
export type MiddlewareEntry<Ctx extends object = AnyContext> =
|
|
536
|
-
| ContextMiddleware<any, Ctx>
|
|
537
|
-
| DeclaredMiddleware<any, Ctx>
|
|
538
|
-
| null
|
|
539
|
-
| undefined
|
|
540
|
-
| false
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Middleware that performs context-only request initialization.
|
|
544
|
-
*
|
|
545
|
-
* @example
|
|
546
|
-
* ```ts
|
|
547
|
-
* const middleware: Middleware = ctx => {
|
|
548
|
-
* ctx.request.headers.get('accept')
|
|
549
|
-
* }
|
|
550
|
-
* ```
|
|
551
|
-
*
|
|
552
|
-
* @param ctx - Request context for the current request.
|
|
553
|
-
* @returns Nothing, or a promise resolved after context initialization.
|
|
554
|
-
*/
|
|
555
|
-
export type Middleware<Ctx extends object = AnyContext> = ContextMiddleware<{}, Ctx>
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Middleware list container for registering multiple middleware entries.
|
|
559
|
-
*
|
|
560
|
-
* @example
|
|
561
|
-
* ```ts
|
|
562
|
-
* const middleware: MiddlewareList = [auth(), logging()]
|
|
563
|
-
* ```
|
|
564
|
-
*
|
|
565
|
-
* @param list - Collection of middleware entries, optionally including falsy values.
|
|
566
|
-
* @returns A list of middleware compatible with `Router.use`.
|
|
567
|
-
*/
|
|
568
|
-
export type MiddlewareList<Ctx extends object = AnyContext> = ReadonlyArray<MiddlewareEntry<Ctx>>
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Middleware value accepted by router middleware registration APIs.
|
|
572
|
-
*
|
|
573
|
-
* @example
|
|
574
|
-
* ```ts
|
|
575
|
-
* const input: MiddlewareInput = [auth(), logging()]
|
|
576
|
-
* ```
|
|
577
|
-
*
|
|
578
|
-
* @typeParam Ctx - Base context available before this middleware runs.
|
|
579
|
-
*/
|
|
580
|
-
export type MiddlewareInput<Ctx extends object = AnyContext> =
|
|
581
|
-
| OneOrMany<MiddlewareEntry<Ctx>>
|
|
582
|
-
| MiddlewareList<Ctx>
|
|
583
|
-
| null
|
|
584
|
-
| undefined
|
|
585
|
-
| false
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Request-boundary middleware entry accepted by [`Router.useRequest`]{@link Router#useRequest}.
|
|
589
|
-
*
|
|
590
|
-
* @typeParam Ctx - Base context available before this middleware runs.
|
|
591
|
-
*/
|
|
592
|
-
export type RequestMiddlewareEntry<Ctx extends object = AnyContext> =
|
|
593
|
-
| RequestMiddleware<any, Ctx>
|
|
594
|
-
| null
|
|
595
|
-
| undefined
|
|
596
|
-
| false
|
|
597
|
-
|
|
598
|
-
/**
|
|
599
|
-
* Request-boundary middleware input accepted by [`Router.useRequest`]{@link Router#useRequest}.
|
|
600
|
-
*
|
|
601
|
-
* @typeParam Ctx - Base context available before this middleware runs.
|
|
602
|
-
*/
|
|
603
|
-
export type RequestMiddlewareInput<Ctx extends object = AnyContext> =
|
|
604
|
-
| OneOrMany<RequestMiddlewareEntry<Ctx>>
|
|
605
|
-
| ReadonlyArray<RequestMiddlewareEntry<Ctx>>
|
|
606
|
-
| null
|
|
607
|
-
| undefined
|
|
608
|
-
| false
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* Request body parser value accepted by router request body parser APIs.
|
|
612
|
-
*
|
|
613
|
-
* @example
|
|
614
|
-
* ```ts
|
|
615
|
-
* const input: RequestBodyParserInput = [jsonRequestBodyParser()]
|
|
616
|
-
* ```
|
|
617
|
-
*/
|
|
618
|
-
export type RequestBodyParserInput =
|
|
619
|
-
| RequestBodyParser
|
|
620
|
-
| ReadonlyArray<RequestBodyParser | null | undefined | false>
|
|
621
|
-
| null
|
|
622
|
-
| undefined
|
|
623
|
-
| false
|
|
624
|
-
|
|
625
|
-
/**
|
|
626
|
-
* Response body serializer value accepted by router response body serializer APIs.
|
|
627
|
-
*
|
|
628
|
-
* @example
|
|
629
|
-
* ```ts
|
|
630
|
-
* const input: ResponseBodySerializerInput = [jsonResponseBodySerializer()]
|
|
631
|
-
* ```
|
|
632
|
-
*/
|
|
633
|
-
export type ResponseBodySerializerInput =
|
|
634
|
-
| ResponseBodySerializer
|
|
635
|
-
| ReadonlyArray<ResponseBodySerializer | null | undefined | false>
|
|
636
|
-
| null
|
|
637
|
-
| undefined
|
|
638
|
-
| false
|
|
639
|
-
|
|
640
|
-
/**
|
|
641
|
-
* Options for mounting a router or configuring a scoped inline router.
|
|
642
|
-
*
|
|
643
|
-
* @example
|
|
644
|
-
* ```ts
|
|
645
|
-
* const options: RouterMountOptions = {prefix: '/admin', middleware: auth()}
|
|
646
|
-
* ```
|
|
647
|
-
*/
|
|
648
|
-
export interface RouterMountOptions<Ctx extends object = AnyContext> {
|
|
649
|
-
/**
|
|
650
|
-
* Optional pathname prefix for the mounted routes.
|
|
651
|
-
*/
|
|
652
|
-
prefix?: string
|
|
653
|
-
/**
|
|
654
|
-
* Middleware applied to the mounted router scope.
|
|
655
|
-
*/
|
|
656
|
-
middleware?: MiddlewareInput<Ctx>
|
|
657
|
-
}
|