@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,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 [`rateLimited`]{@link rateLimited}.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* rateLimited({
|
|
12
|
-
* message: 'Too many requests. Please try again later.',
|
|
13
|
-
* })
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
17
|
-
*/
|
|
18
|
-
export interface RateLimitedInit<Code extends string = 'rate_limited'> extends Omit<
|
|
19
|
-
ProblemResponseInit<Code>,
|
|
20
|
-
'code' | 'status' | 'message'
|
|
21
|
-
> {
|
|
22
|
-
/**
|
|
23
|
-
* Machine-readable error code. Defaults to `'rate_limited'`.
|
|
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 `429`.
|
|
34
|
-
*/
|
|
35
|
-
status?: number | HttpStatus
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Create a standard 429 Too Many Requests problem response envelope.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* return rateLimited('Rate limit exceeded. Please wait 60 seconds.')
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @param message - Human-readable problem message.
|
|
47
|
-
* @param init - Optional extra problem response options.
|
|
48
|
-
* @returns Routekit logical response with a `'rate_limited'` [`ProblemResponse`]{@link ProblemResponse}.
|
|
49
|
-
*/
|
|
50
|
-
export function rateLimited(
|
|
51
|
-
message: string,
|
|
52
|
-
init?: Omit<RateLimitedInit<'rate_limited'>, 'message'>,
|
|
53
|
-
): RoutekitResponse<ProblemResponse<'rate_limited'>>
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Create a standard 429 Too Many Requests problem response envelope.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```ts
|
|
60
|
-
* return rateLimited({ message: 'Rate limit exceeded.' })
|
|
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 rateLimited<const Code extends string = 'rate_limited'>(
|
|
68
|
-
init?: RateLimitedInit<Code>,
|
|
69
|
-
): RoutekitResponse<ProblemResponse<Code>>
|
|
70
|
-
|
|
71
|
-
export function rateLimited<const Code extends string = 'rate_limited'>(
|
|
72
|
-
messageOrInit?: string | RateLimitedInit<Code>,
|
|
73
|
-
init?: Omit<RateLimitedInit<Code>, 'message'>,
|
|
74
|
-
): RoutekitResponse<ProblemResponse<Code>> {
|
|
75
|
-
if (typeof messageOrInit === 'string') {
|
|
76
|
-
return problem({
|
|
77
|
-
...init,
|
|
78
|
-
code: (init?.code ?? 'rate_limited') as Code,
|
|
79
|
-
message: messageOrInit,
|
|
80
|
-
status: init?.status ?? HttpStatus.TOO_MANY_REQUESTS,
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return problem({
|
|
85
|
-
...messageOrInit,
|
|
86
|
-
code: (messageOrInit?.code ?? 'rate_limited') as Code,
|
|
87
|
-
message: messageOrInit?.message ?? 'Rate limited',
|
|
88
|
-
status: messageOrInit?.status ?? HttpStatus.TOO_MANY_REQUESTS,
|
|
89
|
-
})
|
|
90
|
-
}
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { HttpStatus } from '@mpen/http'
|
|
2
|
-
import { response, type RoutekitResponse, type RoutekitResponseInit } from '../../core'
|
|
3
|
-
import type { SuccessResponse, ProblemIssue, ProblemResponse } from './types'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Default primary error code for validation problem responses.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* validationProblem([{ code: 'required', message: 'Name is required' }])
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
export const VALIDATION_PROBLEM_CODE = 'validation_failed'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Options accepted by [`ok`]{@link ok}.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* ok({ id: 'user_123' }, { meta: { requestId: 'req_123' } })
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* @typeParam Meta - Optional metadata payload type.
|
|
24
|
-
*/
|
|
25
|
-
export interface SuccessResponseInit<Meta = unknown> extends Omit<RoutekitResponseInit, 'status'> {
|
|
26
|
-
/**
|
|
27
|
-
* Optional response metadata.
|
|
28
|
-
*/
|
|
29
|
-
meta?: Meta
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Options accepted by [`problem`]{@link problem}.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* problem({
|
|
38
|
-
* code: 'not_found',
|
|
39
|
-
* status: 404,
|
|
40
|
-
* message: 'No user exists for the provided id.',
|
|
41
|
-
* title: 'User not found',
|
|
42
|
-
* })
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
46
|
-
* @typeParam Issue - Issue shape used for validation or business-rule details.
|
|
47
|
-
*/
|
|
48
|
-
export interface ProblemResponseInit<
|
|
49
|
-
Code extends string = string,
|
|
50
|
-
Issue extends ProblemIssue = ProblemIssue,
|
|
51
|
-
Status extends number = number,
|
|
52
|
-
> extends Omit<RoutekitResponseInit, 'status'> {
|
|
53
|
-
/**
|
|
54
|
-
* Machine-readable error code.
|
|
55
|
-
*/
|
|
56
|
-
code: Code
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Human-readable problem message clients can display by default.
|
|
60
|
-
*/
|
|
61
|
-
message: string
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* HTTP status code for this response.
|
|
65
|
-
*/
|
|
66
|
-
status: Status
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Optional short problem heading.
|
|
70
|
-
*/
|
|
71
|
-
title?: string
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Optional validation or business-rule issues.
|
|
75
|
-
*/
|
|
76
|
-
issues?: readonly Issue[]
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Options accepted by [`validationProblem`]{@link validationProblem}.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```ts
|
|
84
|
-
* validationProblem([{ code: 'invalid_type', message: 'Expected a string' }], {
|
|
85
|
-
* message: 'The request body was invalid.',
|
|
86
|
-
* })
|
|
87
|
-
* ```
|
|
88
|
-
*
|
|
89
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
90
|
-
* @typeParam Issue - Issue shape used for validation details.
|
|
91
|
-
*/
|
|
92
|
-
export interface ValidationProblemInit<
|
|
93
|
-
Code extends string = typeof VALIDATION_PROBLEM_CODE,
|
|
94
|
-
Issue extends ProblemIssue = ProblemIssue,
|
|
95
|
-
Status extends number = number,
|
|
96
|
-
> extends Omit<ProblemResponseInit<Code, Issue, Status>, 'code' | 'message' | 'status' | 'issues'> {
|
|
97
|
-
/**
|
|
98
|
-
* Machine-readable validation error code.
|
|
99
|
-
*/
|
|
100
|
-
code?: Code
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Human-readable validation summary.
|
|
104
|
-
*/
|
|
105
|
-
message?: string
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* HTTP status code for this response. Defaults to `400`.
|
|
109
|
-
*/
|
|
110
|
-
status?: Status
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function withDefinedOptional<Value extends object, Key extends string, Field>(
|
|
114
|
-
value: Value,
|
|
115
|
-
key: Key,
|
|
116
|
-
field: Field | undefined,
|
|
117
|
-
): Value | (Value & Record<Key, Field>) {
|
|
118
|
-
if (field === undefined) return value
|
|
119
|
-
return { ...value, [key]: field } as Value & Record<Key, Field>
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Create a `200 OK` standard response envelope.
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
|
-
* ```ts
|
|
127
|
-
* router.get('/users/:id', () => ok({ id: 'user_123' }))
|
|
128
|
-
* ```
|
|
129
|
-
*
|
|
130
|
-
* @param data - Successful response payload.
|
|
131
|
-
* @param init - Response headers and optional metadata.
|
|
132
|
-
* @returns Routekit logical response with an [`SuccessResponse`]{@link SuccessResponse} body.
|
|
133
|
-
* @typeParam Data - Successful response payload type.
|
|
134
|
-
* @typeParam Meta - Optional metadata payload type.
|
|
135
|
-
*/
|
|
136
|
-
export function ok<const Data, const Meta = unknown>(
|
|
137
|
-
data: Data,
|
|
138
|
-
init: SuccessResponseInit<Meta> = {},
|
|
139
|
-
): RoutekitResponse<SuccessResponse<Data, Meta>, HttpStatus.OK> {
|
|
140
|
-
const { meta, ...responseInit } = init
|
|
141
|
-
const body = withDefinedOptional(
|
|
142
|
-
{ success: true, data } as const,
|
|
143
|
-
'meta',
|
|
144
|
-
meta,
|
|
145
|
-
) as SuccessResponse<Data, Meta>
|
|
146
|
-
return response(body, { ...responseInit, status: HttpStatus.OK })
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Create a standard problem response envelope.
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```ts
|
|
154
|
-
* return problem({
|
|
155
|
-
* code: 'not_found',
|
|
156
|
-
* status: 404,
|
|
157
|
-
* message: 'No user exists for the provided id.',
|
|
158
|
-
* title: 'User not found',
|
|
159
|
-
* })
|
|
160
|
-
* ```
|
|
161
|
-
*
|
|
162
|
-
* @param init - Problem response data, headers, and status.
|
|
163
|
-
* @returns Routekit logical response with a [`ProblemResponse`]{@link ProblemResponse} body.
|
|
164
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
165
|
-
* @typeParam Issue - Issue shape used for validation or business-rule details.
|
|
166
|
-
*/
|
|
167
|
-
export function problem<
|
|
168
|
-
const Code extends string,
|
|
169
|
-
const Issue extends ProblemIssue = ProblemIssue,
|
|
170
|
-
const Status extends number = number,
|
|
171
|
-
>(
|
|
172
|
-
init: ProblemResponseInit<Code, Issue, Status>,
|
|
173
|
-
): RoutekitResponse<ProblemResponse<Code, Issue>, Status> {
|
|
174
|
-
const { code, message, status, title, issues, ...responseInit } = init
|
|
175
|
-
const error = withDefinedOptional(
|
|
176
|
-
{
|
|
177
|
-
code,
|
|
178
|
-
message,
|
|
179
|
-
},
|
|
180
|
-
'title',
|
|
181
|
-
title,
|
|
182
|
-
)
|
|
183
|
-
const body = withDefinedOptional({ success: false, error } as const, 'issues', issues)
|
|
184
|
-
|
|
185
|
-
return response(body as ProblemResponse<Code, Issue>, { ...responseInit, status })
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Create a standard validation problem response envelope.
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```ts
|
|
193
|
-
* return validationProblem([
|
|
194
|
-
* { code: 'required', message: 'Email is required', path: ['body', 'email'] },
|
|
195
|
-
* ])
|
|
196
|
-
* ```
|
|
197
|
-
*
|
|
198
|
-
* @param issues - Validation issues to include in the response.
|
|
199
|
-
* @param init - Optional problem response overrides and headers.
|
|
200
|
-
* @returns Routekit logical response with a validation [`ProblemResponse`]{@link ProblemResponse}.
|
|
201
|
-
* @typeParam Issue - Issue shape used for validation details.
|
|
202
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
203
|
-
*/
|
|
204
|
-
export function validationProblem<
|
|
205
|
-
const Issue extends ProblemIssue,
|
|
206
|
-
const Code extends string = typeof VALIDATION_PROBLEM_CODE,
|
|
207
|
-
const Status extends number = HttpStatus.BAD_REQUEST,
|
|
208
|
-
>(
|
|
209
|
-
issues: readonly Issue[],
|
|
210
|
-
init: ValidationProblemInit<Code, Issue, Status> = {},
|
|
211
|
-
): RoutekitResponse<ProblemResponse<Code, Issue>, Status | HttpStatus.BAD_REQUEST> {
|
|
212
|
-
return problem({
|
|
213
|
-
...init,
|
|
214
|
-
code: init.code ?? (VALIDATION_PROBLEM_CODE as Code),
|
|
215
|
-
message: init.message ?? 'Validation failed',
|
|
216
|
-
status: init.status ?? HttpStatus.BAD_REQUEST,
|
|
217
|
-
issues,
|
|
218
|
-
})
|
|
219
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { HttpStatus } from '@mpen/http'
|
|
2
|
-
import type { AnyContext, RouterExtension } from '../../../types'
|
|
3
|
-
import { problem } from './responses'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Install standard problem-envelope handlers for router-level errors.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* const router = new Router().install(problemRootErrors())
|
|
11
|
-
* ```
|
|
12
|
-
*
|
|
13
|
-
* @returns Router extension that registers not-found, method, media-type, and internal-error handlers.
|
|
14
|
-
* @typeParam Ctx - Context carried by the router being configured.
|
|
15
|
-
*/
|
|
16
|
-
export function problemRootErrors<Ctx extends object = AnyContext>(): RouterExtension<Ctx> {
|
|
17
|
-
return (router) => {
|
|
18
|
-
router
|
|
19
|
-
.onNotFound(() =>
|
|
20
|
-
problem({
|
|
21
|
-
code: 'not_found',
|
|
22
|
-
message: 'Not found',
|
|
23
|
-
status: HttpStatus.NOT_FOUND,
|
|
24
|
-
}),
|
|
25
|
-
)
|
|
26
|
-
.onMethodNotAllowed(() =>
|
|
27
|
-
problem({
|
|
28
|
-
code: 'method_not_allowed',
|
|
29
|
-
message: 'Method not allowed',
|
|
30
|
-
status: HttpStatus.METHOD_NOT_ALLOWED,
|
|
31
|
-
}),
|
|
32
|
-
)
|
|
33
|
-
.onUnsupportedMediaType(() =>
|
|
34
|
-
problem({
|
|
35
|
-
code: 'unsupported_media_type',
|
|
36
|
-
message: 'Unsupported media type',
|
|
37
|
-
status: HttpStatus.UNSUPPORTED_MEDIA_TYPE,
|
|
38
|
-
}),
|
|
39
|
-
)
|
|
40
|
-
.onInternalError(() =>
|
|
41
|
-
problem({
|
|
42
|
-
code: 'internal_server_error',
|
|
43
|
-
message: 'Internal server error',
|
|
44
|
-
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
45
|
-
}),
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -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 [`sessionExpired`]{@link sessionExpired}.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* sessionExpired({
|
|
12
|
-
* message: 'Your login session has expired. Please log in again.',
|
|
13
|
-
* })
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
17
|
-
*/
|
|
18
|
-
export interface SessionExpiredInit<Code extends string = 'session_expired'> extends Omit<
|
|
19
|
-
ProblemResponseInit<Code>,
|
|
20
|
-
'code' | 'status' | 'message'
|
|
21
|
-
> {
|
|
22
|
-
/**
|
|
23
|
-
* Machine-readable error code. Defaults to `'session_expired'`.
|
|
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 `401`.
|
|
34
|
-
*/
|
|
35
|
-
status?: number | HttpStatus
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Create a standard 401 Session Expired problem response envelope.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* return sessionExpired('Session has timed out.')
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @param message - Human-readable problem message.
|
|
47
|
-
* @param init - Optional extra problem response options.
|
|
48
|
-
* @returns Routekit logical response with a `'session_expired'` [`ProblemResponse`]{@link ProblemResponse}.
|
|
49
|
-
*/
|
|
50
|
-
export function sessionExpired(
|
|
51
|
-
message: string,
|
|
52
|
-
init?: Omit<SessionExpiredInit<'session_expired'>, 'message'>,
|
|
53
|
-
): RoutekitResponse<ProblemResponse<'session_expired'>>
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Create a standard 401 Session Expired problem response envelope.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```ts
|
|
60
|
-
* return sessionExpired({ message: 'Session expired.' })
|
|
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 sessionExpired<const Code extends string = 'session_expired'>(
|
|
68
|
-
init?: SessionExpiredInit<Code>,
|
|
69
|
-
): RoutekitResponse<ProblemResponse<Code>>
|
|
70
|
-
|
|
71
|
-
export function sessionExpired<const Code extends string = 'session_expired'>(
|
|
72
|
-
messageOrInit?: string | SessionExpiredInit<Code>,
|
|
73
|
-
init?: Omit<SessionExpiredInit<Code>, 'message'>,
|
|
74
|
-
): RoutekitResponse<ProblemResponse<Code>> {
|
|
75
|
-
if (typeof messageOrInit === 'string') {
|
|
76
|
-
return problem({
|
|
77
|
-
...init,
|
|
78
|
-
code: (init?.code ?? 'session_expired') as Code,
|
|
79
|
-
message: messageOrInit,
|
|
80
|
-
status: init?.status ?? HttpStatus.UNAUTHORIZED,
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return problem({
|
|
85
|
-
...messageOrInit,
|
|
86
|
-
code: (messageOrInit?.code ?? 'session_expired') as Code,
|
|
87
|
-
message: messageOrInit?.message ?? 'Session expired',
|
|
88
|
-
status: messageOrInit?.status ?? HttpStatus.UNAUTHORIZED,
|
|
89
|
-
})
|
|
90
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Path segment used to locate a validation or business-rule issue.
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```ts
|
|
6
|
-
* const path: ProblemIssuePathSegment[] = ['body', 'users', 0, 'email']
|
|
7
|
-
* ```
|
|
8
|
-
*/
|
|
9
|
-
export type ProblemIssuePathSegment = string | number
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* A single issue associated with a problem response.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* const issue: ProblemIssue<'required'> = {
|
|
17
|
-
* code: 'required',
|
|
18
|
-
* message: 'Email is required',
|
|
19
|
-
* path: ['body', 'email'],
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* @typeParam Code - Machine-readable issue code.
|
|
24
|
-
*/
|
|
25
|
-
export interface ProblemIssue<Code extends string = string> {
|
|
26
|
-
/**
|
|
27
|
-
* Machine-readable issue code.
|
|
28
|
-
*/
|
|
29
|
-
code: Code
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Human-readable issue message.
|
|
33
|
-
*/
|
|
34
|
-
message: string
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Structured path to the invalid value.
|
|
38
|
-
*/
|
|
39
|
-
path?: readonly ProblemIssuePathSegment[]
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Expected value description.
|
|
43
|
-
*/
|
|
44
|
-
expected?: string
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Received value description.
|
|
48
|
-
*/
|
|
49
|
-
received?: string
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Primary problem metadata that clients can switch on.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```ts
|
|
57
|
-
* const error: ProblemError<'not_found'> = {
|
|
58
|
-
* code: 'not_found',
|
|
59
|
-
* message: 'No user exists for the provided id.',
|
|
60
|
-
* title: 'User not found',
|
|
61
|
-
* }
|
|
62
|
-
* ```
|
|
63
|
-
*
|
|
64
|
-
* @typeParam Code - Machine-readable error code.
|
|
65
|
-
*/
|
|
66
|
-
export interface ProblemError<Code extends string = string> {
|
|
67
|
-
/**
|
|
68
|
-
* Machine-readable error code.
|
|
69
|
-
*/
|
|
70
|
-
code: Code
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Human-readable problem message clients can display by default.
|
|
74
|
-
*/
|
|
75
|
-
message: string
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Optional short problem heading.
|
|
79
|
-
*/
|
|
80
|
-
title?: string
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Successful standard response envelope.
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```ts
|
|
88
|
-
* const response: SuccessResponse<{ id: string }> = {
|
|
89
|
-
* success: true,
|
|
90
|
-
* data: { id: 'user_123' },
|
|
91
|
-
* }
|
|
92
|
-
* ```
|
|
93
|
-
*
|
|
94
|
-
* @typeParam Data - Successful response payload type.
|
|
95
|
-
* @typeParam Meta - Optional metadata payload type.
|
|
96
|
-
*/
|
|
97
|
-
export interface SuccessResponse<Data = unknown, Meta = unknown> {
|
|
98
|
-
/**
|
|
99
|
-
* Discriminator for successful responses.
|
|
100
|
-
*/
|
|
101
|
-
success: true
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Successful response payload.
|
|
105
|
-
*/
|
|
106
|
-
data: Data
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Optional response metadata.
|
|
110
|
-
*/
|
|
111
|
-
meta?: Meta
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Error standard response envelope.
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```ts
|
|
119
|
-
* const response: ProblemResponse<'validation_failed'> = {
|
|
120
|
-
* success: false,
|
|
121
|
-
* error: {
|
|
122
|
-
* code: 'validation_failed',
|
|
123
|
-
* message: 'Validation failed',
|
|
124
|
-
* },
|
|
125
|
-
* issues: [{ code: 'required', message: 'Email is required', path: ['body', 'email'] }],
|
|
126
|
-
* }
|
|
127
|
-
* ```
|
|
128
|
-
*
|
|
129
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
130
|
-
* @typeParam Issue - Issue shape used for validation or business-rule details.
|
|
131
|
-
*/
|
|
132
|
-
export interface ProblemResponse<
|
|
133
|
-
Code extends string = string,
|
|
134
|
-
Issue extends ProblemIssue = ProblemIssue,
|
|
135
|
-
> {
|
|
136
|
-
/**
|
|
137
|
-
* Discriminator for problem responses.
|
|
138
|
-
*/
|
|
139
|
-
success: false
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Primary error clients can switch on.
|
|
143
|
-
*/
|
|
144
|
-
error: ProblemError<Code>
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Optional validation or business-rule issues.
|
|
148
|
-
*/
|
|
149
|
-
issues?: readonly Issue[]
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Standard response union for successful and problem responses.
|
|
154
|
-
*
|
|
155
|
-
* @example
|
|
156
|
-
* ```ts
|
|
157
|
-
* type GetUserResponse = StandardResponse<{ id: string }, 'not_found'>
|
|
158
|
-
* ```
|
|
159
|
-
*
|
|
160
|
-
* @typeParam Data - Successful response payload type.
|
|
161
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
162
|
-
* @typeParam Issue - Issue shape used for validation or business-rule details.
|
|
163
|
-
* @typeParam Meta - Optional metadata payload type.
|
|
164
|
-
*/
|
|
165
|
-
export type StandardResponse<
|
|
166
|
-
Data = unknown,
|
|
167
|
-
Code extends string = string,
|
|
168
|
-
Issue extends ProblemIssue = ProblemIssue,
|
|
169
|
-
Meta = unknown,
|
|
170
|
-
> = SuccessResponse<Data, Meta> | ProblemResponse<Code, Issue>
|
|
@@ -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 [`unauthenticated`]{@link unauthenticated}.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* unauthenticated({
|
|
12
|
-
* message: 'You must be logged in to access this resource.',
|
|
13
|
-
* })
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* @typeParam Code - Machine-readable primary error code.
|
|
17
|
-
*/
|
|
18
|
-
export interface UnauthenticatedInit<Code extends string = 'unauthenticated'> extends Omit<
|
|
19
|
-
ProblemResponseInit<Code>,
|
|
20
|
-
'code' | 'status' | 'message'
|
|
21
|
-
> {
|
|
22
|
-
/**
|
|
23
|
-
* Machine-readable error code. Defaults to `'unauthenticated'`.
|
|
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 `401`.
|
|
34
|
-
*/
|
|
35
|
-
status?: number | HttpStatus
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Create a standard 401 Unauthenticated problem response envelope.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* return unauthenticated('Missing authorization token.')
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @param message - Human-readable problem message.
|
|
47
|
-
* @param init - Optional extra problem response options.
|
|
48
|
-
* @returns Routekit logical response with a `'unauthenticated'` [`ProblemResponse`]{@link ProblemResponse}.
|
|
49
|
-
*/
|
|
50
|
-
export function unauthenticated(
|
|
51
|
-
message: string,
|
|
52
|
-
init?: Omit<UnauthenticatedInit<'unauthenticated'>, 'message'>,
|
|
53
|
-
): RoutekitResponse<ProblemResponse<'unauthenticated'>>
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Create a standard 401 Unauthenticated problem response envelope.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```ts
|
|
60
|
-
* return unauthenticated({ message: 'Invalid credentials.' })
|
|
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 unauthenticated<const Code extends string = 'unauthenticated'>(
|
|
68
|
-
init?: UnauthenticatedInit<Code>,
|
|
69
|
-
): RoutekitResponse<ProblemResponse<Code>>
|
|
70
|
-
|
|
71
|
-
export function unauthenticated<const Code extends string = 'unauthenticated'>(
|
|
72
|
-
messageOrInit?: string | UnauthenticatedInit<Code>,
|
|
73
|
-
init?: Omit<UnauthenticatedInit<Code>, 'message'>,
|
|
74
|
-
): RoutekitResponse<ProblemResponse<Code>> {
|
|
75
|
-
if (typeof messageOrInit === 'string') {
|
|
76
|
-
return problem({
|
|
77
|
-
...init,
|
|
78
|
-
code: (init?.code ?? 'unauthenticated') as Code,
|
|
79
|
-
message: messageOrInit,
|
|
80
|
-
status: init?.status ?? HttpStatus.UNAUTHORIZED,
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return problem({
|
|
85
|
-
...messageOrInit,
|
|
86
|
-
code: (messageOrInit?.code ?? 'unauthenticated') as Code,
|
|
87
|
-
message: messageOrInit?.message ?? 'Unauthenticated',
|
|
88
|
-
status: messageOrInit?.status ?? HttpStatus.UNAUTHORIZED,
|
|
89
|
-
})
|
|
90
|
-
}
|