@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
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { CommonHeaders, HttpStatus } from '@mpen/http'
|
|
2
|
-
import type { RouterBodyInit, RouterHeadersInit } from '../fetch-types'
|
|
3
|
-
|
|
4
|
-
const routekitResponseBrand: unique symbol = Symbol('RoutekitResponse')
|
|
5
|
-
const routekitBodyBrand: unique symbol = Symbol('RoutekitBody')
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Logical route result used by Routekit before it is finalized into a native [`Response`]{@link Response}.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```ts
|
|
12
|
-
* const result = ok({payload: 'ready'})
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
export interface RoutekitResponse<T = unknown, Status extends number = number> {
|
|
16
|
-
readonly [routekitResponseBrand]: true
|
|
17
|
-
/**
|
|
18
|
-
* HTTP status code to use for the finalized response.
|
|
19
|
-
*/
|
|
20
|
-
status: Status
|
|
21
|
-
/**
|
|
22
|
-
* Headers to include in the finalized response.
|
|
23
|
-
*/
|
|
24
|
-
headers: Headers
|
|
25
|
-
/**
|
|
26
|
-
* Logical or represented response body.
|
|
27
|
-
*/
|
|
28
|
-
body: T
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Options accepted by logical response helpers.
|
|
33
|
-
*/
|
|
34
|
-
export interface RoutekitResponseInit<Status extends number = number> {
|
|
35
|
-
/**
|
|
36
|
-
* HTTP status code for the response. Defaults to `200`.
|
|
37
|
-
*/
|
|
38
|
-
status?: Status
|
|
39
|
-
/**
|
|
40
|
-
* Headers to include in the finalized response.
|
|
41
|
-
*/
|
|
42
|
-
headers?: RouterHeadersInit
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Final body wrapper returned from a handler or generator.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* return body({payload: 'done'})
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
export interface RoutekitBody<T = unknown> {
|
|
54
|
-
readonly [routekitBodyBrand]: true
|
|
55
|
-
/**
|
|
56
|
-
* Logical response body value.
|
|
57
|
-
*/
|
|
58
|
-
value: T
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function hasContentType(headers: Headers): boolean {
|
|
62
|
-
return headers.has(CommonHeaders.CONTENT_TYPE)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function isArrayBufferView(value: unknown): value is ArrayBufferView {
|
|
66
|
-
return ArrayBuffer.isView(value)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Test whether a value can be passed directly to the native [`Response`]{@link Response} constructor.
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* ```ts
|
|
74
|
-
* isResponseBodyInit('ok')
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* @param value - Value to inspect.
|
|
78
|
-
* @returns Whether `value` is a native response body.
|
|
79
|
-
*/
|
|
80
|
-
export function isResponseBodyInit(value: unknown): value is RouterBodyInit | null | undefined {
|
|
81
|
-
return (
|
|
82
|
-
value == null ||
|
|
83
|
-
typeof value === 'string' ||
|
|
84
|
-
value instanceof ReadableStream ||
|
|
85
|
-
value instanceof Blob ||
|
|
86
|
-
value instanceof FormData ||
|
|
87
|
-
value instanceof URLSearchParams ||
|
|
88
|
-
value instanceof ArrayBuffer ||
|
|
89
|
-
isArrayBufferView(value)
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Test whether a value is a Routekit logical response.
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```ts
|
|
98
|
-
* if (isRoutekitResponse(result)) result.headers.set('x-request-id', id)
|
|
99
|
-
* ```
|
|
100
|
-
*
|
|
101
|
-
* @param value - Value to inspect.
|
|
102
|
-
* @returns Whether `value` was created by a Routekit response helper.
|
|
103
|
-
*/
|
|
104
|
-
export function isRoutekitResponse(value: unknown): value is RoutekitResponse {
|
|
105
|
-
return !!value && (value as RoutekitResponse)[routekitResponseBrand] === true
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Test whether a value is a final body wrapper.
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```ts
|
|
113
|
-
* const value = isRoutekitBody(result) ? result.value : result
|
|
114
|
-
* ```
|
|
115
|
-
*
|
|
116
|
-
* @param value - Value to inspect.
|
|
117
|
-
* @returns Whether `value` was created by [`body`]{@link body}.
|
|
118
|
-
*/
|
|
119
|
-
export function isRoutekitBody(value: unknown): value is RoutekitBody {
|
|
120
|
-
return !!value && (value as RoutekitBody)[routekitBodyBrand] === true
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Create a logical response.
|
|
125
|
-
*
|
|
126
|
-
* If `headers` contains `Content-Type`, the body must be compatible with the native
|
|
127
|
-
* [`Response`]{@link Response} constructor because the router will skip negotiation.
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* ```ts
|
|
131
|
-
* return response({ok: true}, {status: 202})
|
|
132
|
-
* ```
|
|
133
|
-
*
|
|
134
|
-
* @param responseBody - Logical or represented response body.
|
|
135
|
-
* @param init - Response status and headers.
|
|
136
|
-
* @returns Routekit logical response.
|
|
137
|
-
*/
|
|
138
|
-
export function response<const T>(responseBody: T): RoutekitResponse<T, HttpStatus.OK>
|
|
139
|
-
export function response<const T>(
|
|
140
|
-
responseBody: T,
|
|
141
|
-
init: Omit<RoutekitResponseInit, 'status'>,
|
|
142
|
-
): RoutekitResponse<T, HttpStatus.OK>
|
|
143
|
-
export function response<const T, const Status extends number>(
|
|
144
|
-
responseBody: T,
|
|
145
|
-
init: RoutekitResponseInit<Status> & { status: Status },
|
|
146
|
-
): RoutekitResponse<T, Status>
|
|
147
|
-
export function response<const T>(
|
|
148
|
-
responseBody: T,
|
|
149
|
-
init: RoutekitResponseInit = {},
|
|
150
|
-
): RoutekitResponse<T, number> {
|
|
151
|
-
const responseHeaders = new Headers(init.headers)
|
|
152
|
-
if (hasContentType(responseHeaders) && !isResponseBodyInit(responseBody)) {
|
|
153
|
-
throw new TypeError(
|
|
154
|
-
'Routekit response has Content-Type set, so body must be a native Response body.',
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
[routekitResponseBrand]: true,
|
|
159
|
-
status: init.status ?? HttpStatus.OK,
|
|
160
|
-
headers: responseHeaders,
|
|
161
|
-
body: responseBody,
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Wrap a returned value as the final response body.
|
|
167
|
-
*
|
|
168
|
-
* @example
|
|
169
|
-
* ```ts
|
|
170
|
-
* return body({payload: 'done'})
|
|
171
|
-
* ```
|
|
172
|
-
*
|
|
173
|
-
* @param value - Logical response body.
|
|
174
|
-
* @returns Final body wrapper.
|
|
175
|
-
*/
|
|
176
|
-
export function body<const T>(value: T): RoutekitBody<T> {
|
|
177
|
-
return {
|
|
178
|
-
[routekitBodyBrand]: true,
|
|
179
|
-
value,
|
|
180
|
-
}
|
|
181
|
-
}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import type { HttpStatus } from '@mpen/http'
|
|
2
|
-
import type { RouterHeadersInit } from '../fetch-types'
|
|
3
|
-
import type { StreamFramer } from './framers'
|
|
4
|
-
|
|
5
|
-
const routekitDirectiveBrand: unique symbol = Symbol('RoutekitDirective')
|
|
6
|
-
|
|
7
|
-
interface BaseDirective {
|
|
8
|
-
readonly [routekitDirectiveBrand]: true
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Generator directive that sets the response status.
|
|
13
|
-
*/
|
|
14
|
-
export interface StatusDirective extends BaseDirective {
|
|
15
|
-
kind: 'status'
|
|
16
|
-
status: number | HttpStatus
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Generator directive that merges response headers.
|
|
21
|
-
*/
|
|
22
|
-
export interface HeadersDirective extends BaseDirective {
|
|
23
|
-
kind: 'headers'
|
|
24
|
-
headers: Headers
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generator directive that sets response status and merges response headers.
|
|
29
|
-
*/
|
|
30
|
-
export interface HeadDirective extends BaseDirective {
|
|
31
|
-
kind: 'head'
|
|
32
|
-
status: number | HttpStatus
|
|
33
|
-
headers: Headers
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Generator directive that starts structured streaming with a framer.
|
|
38
|
-
*/
|
|
39
|
-
export interface StreamDirective<T = unknown> extends BaseDirective {
|
|
40
|
-
kind: 'stream'
|
|
41
|
-
framer: StreamFramer<T>
|
|
42
|
-
headers: Headers
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Generator directive that emits one stream chunk.
|
|
47
|
-
*/
|
|
48
|
-
export interface ChunkDirective<T = unknown> extends BaseDirective {
|
|
49
|
-
kind: 'chunk'
|
|
50
|
-
value: T
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Values that generator-style handlers may yield.
|
|
55
|
-
*/
|
|
56
|
-
export type RoutekitYield =
|
|
57
|
-
| StatusDirective
|
|
58
|
-
| HeadersDirective
|
|
59
|
-
| HeadDirective
|
|
60
|
-
| StreamDirective
|
|
61
|
-
| ChunkDirective
|
|
62
|
-
| undefined
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Test whether a value is a generator directive.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* if (isRoutekitDirective(value)) console.log(value.kind)
|
|
70
|
-
* ```
|
|
71
|
-
*
|
|
72
|
-
* @param value - Value to inspect.
|
|
73
|
-
* @returns Whether `value` is a Routekit generator directive.
|
|
74
|
-
*/
|
|
75
|
-
export function isRoutekitDirective(value: unknown): value is Exclude<RoutekitYield, undefined> {
|
|
76
|
-
return !!value && (value as BaseDirective)[routekitDirectiveBrand] === true
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Test whether a value is a status directive.
|
|
81
|
-
*
|
|
82
|
-
* @param value - Value to inspect.
|
|
83
|
-
* @returns Whether `value` was created by [`status`]{@link status}.
|
|
84
|
-
*/
|
|
85
|
-
export function isStatusDirective(value: unknown): value is StatusDirective {
|
|
86
|
-
return isRoutekitDirective(value) && value.kind === 'status'
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Test whether a value is a headers directive.
|
|
91
|
-
*
|
|
92
|
-
* @param value - Value to inspect.
|
|
93
|
-
* @returns Whether `value` was created by [`headers`]{@link headers}.
|
|
94
|
-
*/
|
|
95
|
-
export function isHeadersDirective(value: unknown): value is HeadersDirective {
|
|
96
|
-
return isRoutekitDirective(value) && value.kind === 'headers'
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Test whether a value is a head directive.
|
|
101
|
-
*
|
|
102
|
-
* @param value - Value to inspect.
|
|
103
|
-
* @returns Whether `value` was created by [`head`]{@link head}.
|
|
104
|
-
*/
|
|
105
|
-
export function isHeadDirective(value: unknown): value is HeadDirective {
|
|
106
|
-
return isRoutekitDirective(value) && value.kind === 'head'
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Test whether a value is a stream directive.
|
|
111
|
-
*
|
|
112
|
-
* @param value - Value to inspect.
|
|
113
|
-
* @returns Whether `value` was created by [`stream`]{@link stream}.
|
|
114
|
-
*/
|
|
115
|
-
export function isStreamDirective(value: unknown): value is StreamDirective {
|
|
116
|
-
return isRoutekitDirective(value) && value.kind === 'stream'
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Test whether a value is a chunk directive.
|
|
121
|
-
*
|
|
122
|
-
* @param value - Value to inspect.
|
|
123
|
-
* @returns Whether `value` was created by [`chunk`]{@link chunk}.
|
|
124
|
-
*/
|
|
125
|
-
export function isChunkDirective(value: unknown): value is ChunkDirective {
|
|
126
|
-
return isRoutekitDirective(value) && value.kind === 'chunk'
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function makeDirective<T extends BaseDirective>(directive: Omit<T, typeof routekitDirectiveBrand>) {
|
|
130
|
-
return {
|
|
131
|
-
[routekitDirectiveBrand]: true,
|
|
132
|
-
...directive,
|
|
133
|
-
} as T
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Create a generator directive that sets the response status.
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```ts
|
|
141
|
-
* yield status(HttpStatus.ACCEPTED)
|
|
142
|
-
* ```
|
|
143
|
-
*
|
|
144
|
-
* @param statusCode - HTTP status code to use.
|
|
145
|
-
* @returns Status directive.
|
|
146
|
-
*/
|
|
147
|
-
export function status(statusCode: number | HttpStatus): StatusDirective {
|
|
148
|
-
return makeDirective<StatusDirective>({
|
|
149
|
-
kind: 'status',
|
|
150
|
-
status: statusCode,
|
|
151
|
-
})
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Create a generator directive that merges response headers.
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```ts
|
|
159
|
-
* yield headers({'cache-control': 'no-store'})
|
|
160
|
-
* ```
|
|
161
|
-
*
|
|
162
|
-
* @param init - Headers to merge into the response.
|
|
163
|
-
* @returns Headers directive.
|
|
164
|
-
*/
|
|
165
|
-
export function headers(init: RouterHeadersInit): HeadersDirective {
|
|
166
|
-
return makeDirective<HeadersDirective>({
|
|
167
|
-
kind: 'headers',
|
|
168
|
-
headers: new Headers(init),
|
|
169
|
-
})
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Create a generator directive that sets response status and headers.
|
|
174
|
-
*
|
|
175
|
-
* @example
|
|
176
|
-
* ```ts
|
|
177
|
-
* yield head(HttpStatus.OK, {'cache-control': 'no-store'})
|
|
178
|
-
* ```
|
|
179
|
-
*
|
|
180
|
-
* @param statusCode - HTTP status code to use.
|
|
181
|
-
* @param init - Headers to merge into the response.
|
|
182
|
-
* @returns Head directive.
|
|
183
|
-
*/
|
|
184
|
-
export function head(statusCode: number | HttpStatus, init: RouterHeadersInit = {}): HeadDirective {
|
|
185
|
-
return makeDirective<HeadDirective>({
|
|
186
|
-
kind: 'head',
|
|
187
|
-
status: statusCode,
|
|
188
|
-
headers: new Headers(init),
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Create a generator directive that selects a structured stream framer.
|
|
194
|
-
*
|
|
195
|
-
* @example
|
|
196
|
-
* ```ts
|
|
197
|
-
* yield stream(sseFramer())
|
|
198
|
-
* ```
|
|
199
|
-
*
|
|
200
|
-
* @param framer - Stream framer to use for subsequent chunks.
|
|
201
|
-
* @param init - Additional stream headers.
|
|
202
|
-
* @returns Stream directive.
|
|
203
|
-
*/
|
|
204
|
-
export function stream<const T>(
|
|
205
|
-
framer: StreamFramer<T>,
|
|
206
|
-
init: RouterHeadersInit = {},
|
|
207
|
-
): StreamDirective<T> {
|
|
208
|
-
const streamHeaders = new Headers(framer.headers)
|
|
209
|
-
new Headers(init).forEach((value, key) => streamHeaders.set(key, value))
|
|
210
|
-
return makeDirective<StreamDirective<T>>({
|
|
211
|
-
kind: 'stream',
|
|
212
|
-
framer,
|
|
213
|
-
headers: streamHeaders,
|
|
214
|
-
})
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Create a generator directive that emits one stream chunk.
|
|
219
|
-
*
|
|
220
|
-
* @example
|
|
221
|
-
* ```ts
|
|
222
|
-
* yield chunk({event: 'ready'})
|
|
223
|
-
* ```
|
|
224
|
-
*
|
|
225
|
-
* @param value - Chunk value to stream.
|
|
226
|
-
* @returns Chunk directive.
|
|
227
|
-
*/
|
|
228
|
-
export function chunk<const T>(value: T): ChunkDirective<T> {
|
|
229
|
-
return makeDirective<ChunkDirective<T>>({
|
|
230
|
-
kind: 'chunk',
|
|
231
|
-
value,
|
|
232
|
-
})
|
|
233
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { HttpStatus } from '@mpen/http'
|
|
2
|
-
import { response, type RoutekitResponse, type RoutekitResponseInit } from '../../core'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Create an empty response with the provided status.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* return empty(HttpStatus.ACCEPTED)
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* @param statusCode - HTTP status code to use.
|
|
13
|
-
* @param init - Response headers.
|
|
14
|
-
* @returns Routekit logical response with no body.
|
|
15
|
-
*/
|
|
16
|
-
export function empty<const Status extends number = HttpStatus.NO_CONTENT>(
|
|
17
|
-
statusCode: Status = HttpStatus.NO_CONTENT as Status,
|
|
18
|
-
init: Omit<RoutekitResponseInit, 'status'> = {},
|
|
19
|
-
): RoutekitResponse<undefined, Status> {
|
|
20
|
-
return response(undefined, { ...init, status: statusCode })
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Create a `204 No Content` response.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* return noContent()
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @returns Routekit logical response with no body.
|
|
32
|
-
*/
|
|
33
|
-
export function noContent(): RoutekitResponse<undefined, HttpStatus.NO_CONTENT> {
|
|
34
|
-
return empty(HttpStatus.NO_CONTENT)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Create a redirect response.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```ts
|
|
42
|
-
* return redirect('/login')
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* @param url - Redirect target URL.
|
|
46
|
-
* @param statusCode - Redirect status code. Defaults to `302`.
|
|
47
|
-
* @returns Routekit logical response with a `Location` header.
|
|
48
|
-
*/
|
|
49
|
-
export function redirect<const Status extends number = HttpStatus.FOUND>(
|
|
50
|
-
url: string,
|
|
51
|
-
statusCode: Status = HttpStatus.FOUND as Status,
|
|
52
|
-
): RoutekitResponse<undefined, Status> {
|
|
53
|
-
return empty(statusCode, { headers: { Location: url } })
|
|
54
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { CommonContentTypes, CommonHeaders, HttpStatus } from '@mpen/http'
|
|
2
|
-
import { fullWide } from '../../../lib/format'
|
|
3
|
-
import { response, type RoutekitResponse, type RoutekitResponseInit } from '../../core'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Create a represented `text/plain` response.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* return text('pong')
|
|
11
|
-
* ```
|
|
12
|
-
*
|
|
13
|
-
* @param value - Text response body.
|
|
14
|
-
* @param init - Response status and headers.
|
|
15
|
-
* @returns Routekit logical response with `Content-Type` set.
|
|
16
|
-
*/
|
|
17
|
-
export function text(value: string): RoutekitResponse<string, HttpStatus.OK>
|
|
18
|
-
export function text(
|
|
19
|
-
value: string,
|
|
20
|
-
init: Omit<RoutekitResponseInit, 'status'>,
|
|
21
|
-
): RoutekitResponse<string, HttpStatus.OK>
|
|
22
|
-
export function text<const Status extends number>(
|
|
23
|
-
value: string,
|
|
24
|
-
init: RoutekitResponseInit<Status> & { status: Status },
|
|
25
|
-
): RoutekitResponse<string, Status>
|
|
26
|
-
export function text(
|
|
27
|
-
value: string,
|
|
28
|
-
init: RoutekitResponseInit<number> = {},
|
|
29
|
-
): RoutekitResponse<string, number> {
|
|
30
|
-
const responseHeaders = new Headers(init.headers)
|
|
31
|
-
responseHeaders.set(CommonHeaders.CONTENT_TYPE, CommonContentTypes.PLAIN_TEXT)
|
|
32
|
-
responseHeaders.set(
|
|
33
|
-
CommonHeaders.CONTENT_LENGTH,
|
|
34
|
-
fullWide(new TextEncoder().encode(value).length),
|
|
35
|
-
)
|
|
36
|
-
return response(value, {
|
|
37
|
-
...init,
|
|
38
|
-
headers: responseHeaders,
|
|
39
|
-
status: init.status ?? HttpStatus.OK,
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Create a represented `text/html` response.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* ```ts
|
|
48
|
-
* return html('<h1>Hello</h1>')
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
* @param value - HTML response body.
|
|
52
|
-
* @param init - Response status and headers.
|
|
53
|
-
* @returns Routekit logical response with `Content-Type` set.
|
|
54
|
-
*/
|
|
55
|
-
export function html(value: string): RoutekitResponse<string, HttpStatus.OK>
|
|
56
|
-
export function html(
|
|
57
|
-
value: string,
|
|
58
|
-
init: Omit<RoutekitResponseInit, 'status'>,
|
|
59
|
-
): RoutekitResponse<string, HttpStatus.OK>
|
|
60
|
-
export function html<const Status extends number>(
|
|
61
|
-
value: string,
|
|
62
|
-
init: RoutekitResponseInit<Status> & { status: Status },
|
|
63
|
-
): RoutekitResponse<string, Status>
|
|
64
|
-
export function html(
|
|
65
|
-
value: string,
|
|
66
|
-
init: RoutekitResponseInit<number> = {},
|
|
67
|
-
): RoutekitResponse<string, number> {
|
|
68
|
-
const responseHeaders = new Headers(init.headers)
|
|
69
|
-
responseHeaders.set(CommonHeaders.CONTENT_TYPE, CommonContentTypes.HTML)
|
|
70
|
-
responseHeaders.set(
|
|
71
|
-
CommonHeaders.CONTENT_LENGTH,
|
|
72
|
-
fullWide(new TextEncoder().encode(value).length),
|
|
73
|
-
)
|
|
74
|
-
return response(value, {
|
|
75
|
-
...init,
|
|
76
|
-
headers: responseHeaders,
|
|
77
|
-
status: init.status ?? HttpStatus.OK,
|
|
78
|
-
})
|
|
79
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { HttpStatus } from '@mpen/http'
|
|
2
|
-
import type { RoutekitResponse } from '../../core'
|
|
3
|
-
import { problem, type ProblemResponseInit } from './responses'
|
|
4
|
-
import type { ProblemResponse } from './types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Options accepted by [`badRequest`]{@link badRequest}.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* badRequest({
|
|
12
|
-
* message: 'The request is malformed.',
|
|
13
|
-
* })
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
17
|
-
*/
|
|
18
|
-
export interface BadRequestInit<Code extends string = 'bad_request'> extends Omit<
|
|
19
|
-
ProblemResponseInit<Code>,
|
|
20
|
-
'code' | 'status' | 'message'
|
|
21
|
-
> {
|
|
22
|
-
/**
|
|
23
|
-
* Machine-readable error code. Defaults to `'bad_request'`.
|
|
24
|
-
*/
|
|
25
|
-
code?: Code
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Human-readable problem message.
|
|
29
|
-
*/
|
|
30
|
-
message?: string
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* HTTP status code for this response. Defaults to `400`.
|
|
34
|
-
*/
|
|
35
|
-
status?: number | HttpStatus
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Create a standard 400 Bad Request problem response envelope.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* return badRequest('Invalid query parameter format.')
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @param message - Human-readable problem message.
|
|
47
|
-
* @param init - Optional extra problem response options.
|
|
48
|
-
* @returns Routekit logical response with a `'bad_request'` [`ProblemResponse`]{@link ProblemResponse}.
|
|
49
|
-
*/
|
|
50
|
-
export function badRequest(
|
|
51
|
-
message: string,
|
|
52
|
-
init?: Omit<BadRequestInit<'bad_request'>, 'message'>,
|
|
53
|
-
): RoutekitResponse<ProblemResponse<'bad_request'>>
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Create a standard 400 Bad Request problem response envelope.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```ts
|
|
60
|
-
* return badRequest({ message: 'Malformed payload.' })
|
|
61
|
-
* ```
|
|
62
|
-
*
|
|
63
|
-
* @param init - Optional problem response options.
|
|
64
|
-
* @returns Routekit logical response with a [`ProblemResponse`]{@link ProblemResponse}.
|
|
65
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
66
|
-
*/
|
|
67
|
-
export function badRequest<const Code extends string = 'bad_request'>(
|
|
68
|
-
init?: BadRequestInit<Code>,
|
|
69
|
-
): RoutekitResponse<ProblemResponse<Code>>
|
|
70
|
-
|
|
71
|
-
export function badRequest<const Code extends string = 'bad_request'>(
|
|
72
|
-
messageOrInit?: string | BadRequestInit<Code>,
|
|
73
|
-
init?: Omit<BadRequestInit<Code>, 'message'>,
|
|
74
|
-
): RoutekitResponse<ProblemResponse<Code>> {
|
|
75
|
-
if (typeof messageOrInit === 'string') {
|
|
76
|
-
return problem({
|
|
77
|
-
...init,
|
|
78
|
-
code: (init?.code ?? 'bad_request') as Code,
|
|
79
|
-
message: messageOrInit,
|
|
80
|
-
status: init?.status ?? HttpStatus.BAD_REQUEST,
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return problem({
|
|
85
|
-
...messageOrInit,
|
|
86
|
-
code: (messageOrInit?.code ?? 'bad_request') as Code,
|
|
87
|
-
message: messageOrInit?.message ?? 'Bad request',
|
|
88
|
-
status: messageOrInit?.status ?? HttpStatus.BAD_REQUEST,
|
|
89
|
-
})
|
|
90
|
-
}
|