hono-ban 0.2.4 → 0.2.6
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/esm/formatters/index.js +1 -0
- package/dist/esm/index.js +1 -311
- package/package.json +9 -24
- package/dist/cjs/formatters/rfc7807/index.js +0 -364
- package/dist/cjs/formatters/rfc7807/index.js.map +0 -16
- package/dist/cjs/index.js +0 -271
- package/dist/cjs/index.js.map +0 -16
- package/dist/esm/formatters/rfc7807/index.js +0 -333
- package/dist/esm/formatters/rfc7807/index.js.map +0 -16
- package/dist/esm/index.js.map +0 -16
- package/src/__tests__/core/convert-error.test.ts +0 -158
- package/src/__tests__/core/create-error.test.ts +0 -113
- package/src/__tests__/core/format-error.test.ts +0 -162
- package/src/__tests__/factories/factories.test.ts +0 -380
- package/src/__tests__/formatters/default-formatter.test.ts +0 -117
- package/src/__tests__/middleware/README.md +0 -49
- package/src/__tests__/middleware/ban-middleware.test.ts.disabled +0 -23
- package/src/__tests__/utils/sanitize.test.ts +0 -117
- package/src/__tests__/utils/validate.test.ts +0 -35
- package/src/constants/index.ts +0 -6
- package/src/constants/status-codes.ts +0 -52
- package/src/core/convert-error.ts +0 -74
- package/src/core/create-error.ts +0 -65
- package/src/core/format-error.ts +0 -76
- package/src/core/index.ts +0 -8
- package/src/factories/client-errors.ts +0 -492
- package/src/factories/index.ts +0 -7
- package/src/factories/server-errors.ts +0 -230
- package/src/formatters/default/index.ts +0 -72
- package/src/formatters/index.ts +0 -13
- package/src/formatters/interfaces.ts +0 -7
- package/src/formatters/rfc7807/formatter.ts +0 -105
- package/src/formatters/rfc7807/hooks.ts +0 -73
- package/src/formatters/rfc7807/index.ts +0 -20
- package/src/formatters/rfc7807/schemas.ts +0 -88
- package/src/index.ts +0 -23
- package/src/middleware/ban-middleware.ts +0 -77
- package/src/middleware/index.ts +0 -6
- package/src/types/common.ts +0 -14
- package/src/types/error.ts +0 -46
- package/src/types/formatter.ts +0 -61
- package/src/types/index.ts +0 -11
- package/src/types/options.ts +0 -71
- package/src/types/rfc7807.ts +0 -93
- package/src/utils/index.ts +0 -7
- package/src/utils/sanitize.ts +0 -34
- package/src/utils/validate.ts +0 -24
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server error factory functions (5xx)
|
|
3
|
-
* @module hono-ban/factories/server-errors
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { BanError, BanOptions, ErrorStatusCode } from "../types";
|
|
7
|
-
import { createError } from "../core";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Helper function to reduce duplication
|
|
11
|
-
* @param statusCode - HTTP status code
|
|
12
|
-
* @param messageOrOptions - Error message or options
|
|
13
|
-
* @param options - Additional options
|
|
14
|
-
*/
|
|
15
|
-
function createErrorWithStatus<T>(
|
|
16
|
-
statusCode: ErrorStatusCode,
|
|
17
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
18
|
-
options?: Partial<BanOptions<T>>
|
|
19
|
-
): BanError<T> {
|
|
20
|
-
if (typeof messageOrOptions === "string") {
|
|
21
|
-
return createError<T>({
|
|
22
|
-
...options,
|
|
23
|
-
statusCode,
|
|
24
|
-
message: messageOrOptions,
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
return createError<T>({ ...messageOrOptions, ...options, statusCode });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create a 500 Internal Server Error
|
|
32
|
-
* @param messageOrOptions - Error message or options
|
|
33
|
-
* @param options - Additional options
|
|
34
|
-
*/
|
|
35
|
-
export function internal<T = unknown>(
|
|
36
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
37
|
-
options?: Partial<BanOptions<T>>
|
|
38
|
-
): BanError<T> {
|
|
39
|
-
return createErrorWithStatus(
|
|
40
|
-
500 as ErrorStatusCode,
|
|
41
|
-
messageOrOptions,
|
|
42
|
-
options
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Create a 501 Not Implemented error
|
|
48
|
-
* @param messageOrOptions - Error message or options
|
|
49
|
-
* @param options - Additional options
|
|
50
|
-
*/
|
|
51
|
-
export function notImplemented<T = unknown>(
|
|
52
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
53
|
-
options?: Partial<BanOptions<T>>
|
|
54
|
-
): BanError<T> {
|
|
55
|
-
return createErrorWithStatus(
|
|
56
|
-
501 as ErrorStatusCode,
|
|
57
|
-
messageOrOptions,
|
|
58
|
-
options
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Create a 502 Bad Gateway error
|
|
64
|
-
* @param messageOrOptions - Error message or options
|
|
65
|
-
* @param options - Additional options
|
|
66
|
-
*/
|
|
67
|
-
export function badGateway<T = unknown>(
|
|
68
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
69
|
-
options?: Partial<BanOptions<T>>
|
|
70
|
-
): BanError<T> {
|
|
71
|
-
return createErrorWithStatus(
|
|
72
|
-
502 as ErrorStatusCode,
|
|
73
|
-
messageOrOptions,
|
|
74
|
-
options
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Create a 503 Service Unavailable error
|
|
80
|
-
* @param messageOrOptions - Error message or options
|
|
81
|
-
* @param options - Additional options
|
|
82
|
-
*/
|
|
83
|
-
export function serverUnavailable<T = unknown>(
|
|
84
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
85
|
-
options?: Partial<BanOptions<T>>
|
|
86
|
-
): BanError<T> {
|
|
87
|
-
return createErrorWithStatus(
|
|
88
|
-
503 as ErrorStatusCode,
|
|
89
|
-
messageOrOptions,
|
|
90
|
-
options
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Create a 504 Gateway Timeout error
|
|
96
|
-
* @param messageOrOptions - Error message or options
|
|
97
|
-
* @param options - Additional options
|
|
98
|
-
*/
|
|
99
|
-
export function gatewayTimeout<T = unknown>(
|
|
100
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
101
|
-
options?: Partial<BanOptions<T>>
|
|
102
|
-
): BanError<T> {
|
|
103
|
-
return createErrorWithStatus(
|
|
104
|
-
504 as ErrorStatusCode,
|
|
105
|
-
messageOrOptions,
|
|
106
|
-
options
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Create a 505 HTTP Version Not Supported error
|
|
112
|
-
* @param messageOrOptions - Error message or options
|
|
113
|
-
* @param options - Additional options
|
|
114
|
-
*/
|
|
115
|
-
export function httpVersionNotSupported<T = unknown>(
|
|
116
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
117
|
-
options?: Partial<BanOptions<T>>
|
|
118
|
-
): BanError<T> {
|
|
119
|
-
return createErrorWithStatus(
|
|
120
|
-
505 as ErrorStatusCode,
|
|
121
|
-
messageOrOptions,
|
|
122
|
-
options
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Create a 506 Variant Also Negotiates error
|
|
128
|
-
* @param messageOrOptions - Error message or options
|
|
129
|
-
* @param options - Additional options
|
|
130
|
-
*/
|
|
131
|
-
export function variantAlsoNegotiates<T = unknown>(
|
|
132
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
133
|
-
options?: Partial<BanOptions<T>>
|
|
134
|
-
): BanError<T> {
|
|
135
|
-
return createErrorWithStatus(
|
|
136
|
-
506 as ErrorStatusCode,
|
|
137
|
-
messageOrOptions,
|
|
138
|
-
options
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Create a 507 Insufficient Storage error
|
|
144
|
-
* @param messageOrOptions - Error message or options
|
|
145
|
-
* @param options - Additional options
|
|
146
|
-
*/
|
|
147
|
-
export function insufficientStorage<T = unknown>(
|
|
148
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
149
|
-
options?: Partial<BanOptions<T>>
|
|
150
|
-
): BanError<T> {
|
|
151
|
-
return createErrorWithStatus(
|
|
152
|
-
507 as ErrorStatusCode,
|
|
153
|
-
messageOrOptions,
|
|
154
|
-
options
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Create a 508 Loop Detected error
|
|
160
|
-
* @param messageOrOptions - Error message or options
|
|
161
|
-
* @param options - Additional options
|
|
162
|
-
*/
|
|
163
|
-
export function loopDetected<T = unknown>(
|
|
164
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
165
|
-
options?: Partial<BanOptions<T>>
|
|
166
|
-
): BanError<T> {
|
|
167
|
-
return createErrorWithStatus(
|
|
168
|
-
508 as ErrorStatusCode,
|
|
169
|
-
messageOrOptions,
|
|
170
|
-
options
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Create a 510 Not Extended error
|
|
176
|
-
* @param messageOrOptions - Error message or options
|
|
177
|
-
* @param options - Additional options
|
|
178
|
-
*/
|
|
179
|
-
export function notExtended<T = unknown>(
|
|
180
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
181
|
-
options?: Partial<BanOptions<T>>
|
|
182
|
-
): BanError<T> {
|
|
183
|
-
return createErrorWithStatus(
|
|
184
|
-
510 as ErrorStatusCode,
|
|
185
|
-
messageOrOptions,
|
|
186
|
-
options
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Create a 511 Network Authentication Required error
|
|
192
|
-
* @param messageOrOptions - Error message or options
|
|
193
|
-
* @param options - Additional options
|
|
194
|
-
*/
|
|
195
|
-
export function networkAuthRequired<T = unknown>(
|
|
196
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
197
|
-
options?: Partial<BanOptions<T>>
|
|
198
|
-
): BanError<T> {
|
|
199
|
-
return createErrorWithStatus(
|
|
200
|
-
511 as ErrorStatusCode,
|
|
201
|
-
messageOrOptions,
|
|
202
|
-
options
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Create a 500 Internal Server Error marked as a developer error
|
|
208
|
-
* @param messageOrOptions - Error message or options
|
|
209
|
-
* @param options - Additional options
|
|
210
|
-
*/
|
|
211
|
-
export function badImplementation<T = unknown>(
|
|
212
|
-
messageOrOptions?: string | Partial<BanOptions<T>>,
|
|
213
|
-
options?: Partial<BanOptions<T>>
|
|
214
|
-
): BanError<T> {
|
|
215
|
-
const mergedOptions =
|
|
216
|
-
typeof messageOrOptions === "string"
|
|
217
|
-
? { ...options, message: messageOrOptions }
|
|
218
|
-
: { ...messageOrOptions, ...options };
|
|
219
|
-
|
|
220
|
-
const mergedData = {
|
|
221
|
-
isDeveloperError: true,
|
|
222
|
-
...((mergedOptions.data as Record<string, unknown>) || {}),
|
|
223
|
-
} as unknown as T;
|
|
224
|
-
|
|
225
|
-
return createError<T>({
|
|
226
|
-
...mergedOptions,
|
|
227
|
-
statusCode: 500 as ErrorStatusCode,
|
|
228
|
-
data: mergedData,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default error formatter implementation
|
|
3
|
-
* @module hono-ban/formatters/default
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { STATUS_CODES } from "../../constants";
|
|
7
|
-
import type { BanError, DefaultErrorOutput, Headers } from "../../types";
|
|
8
|
-
import { sanitizeObject } from "../../utils";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Default JSON formatter maintaining backward compatibility
|
|
12
|
-
*/
|
|
13
|
-
export const defaultFormatter = {
|
|
14
|
-
contentType: "application/json",
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Format an error into a standardized output structure
|
|
18
|
-
* @param error - Error to format
|
|
19
|
-
* @param headers - Headers for HTTP response (not included in response body)
|
|
20
|
-
* @param sanitize - Fields to remove from output
|
|
21
|
-
* @param includeStackTrace - Whether to include stack traces
|
|
22
|
-
*/
|
|
23
|
-
format(
|
|
24
|
-
error: BanError,
|
|
25
|
-
headers: Headers = {}, // Headers are used for HTTP headers, not included in response body
|
|
26
|
-
sanitize: readonly string[] = [],
|
|
27
|
-
includeStackTrace = false
|
|
28
|
-
): DefaultErrorOutput {
|
|
29
|
-
const { status, message, data } = error;
|
|
30
|
-
|
|
31
|
-
// Build base payload
|
|
32
|
-
const payload: DefaultErrorOutput["payload"] = {
|
|
33
|
-
statusCode: status,
|
|
34
|
-
error: STATUS_CODES[status] || "Unknown Error",
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// Add optional fields
|
|
38
|
-
if (typeof message === "string") {
|
|
39
|
-
payload.message = message;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const isDeveloperError =
|
|
43
|
-
data &&
|
|
44
|
-
typeof data === "object" &&
|
|
45
|
-
"isDeveloperError" in data &&
|
|
46
|
-
data.isDeveloperError === true;
|
|
47
|
-
|
|
48
|
-
if (includeStackTrace || isDeveloperError) {
|
|
49
|
-
if (error.stack) {
|
|
50
|
-
payload.stack = error.stack;
|
|
51
|
-
}
|
|
52
|
-
if (error.causeStack) {
|
|
53
|
-
payload.causeStack = error.causeStack;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (data !== undefined) {
|
|
58
|
-
payload.data = data;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Create output structure
|
|
62
|
-
const output: DefaultErrorOutput = {
|
|
63
|
-
statusCode: status,
|
|
64
|
-
payload: sanitizeObject(
|
|
65
|
-
payload,
|
|
66
|
-
sanitize
|
|
67
|
-
) as DefaultErrorOutput["payload"],
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
return output;
|
|
71
|
-
},
|
|
72
|
-
};
|
package/src/formatters/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Formatters exports
|
|
3
|
-
* @module hono-ban/formatters
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Export formatter interfaces
|
|
7
|
-
export * from "./interfaces";
|
|
8
|
-
|
|
9
|
-
// Export default formatter
|
|
10
|
-
export * from "./default";
|
|
11
|
-
|
|
12
|
-
// Export RFC7807 formatter
|
|
13
|
-
export * from "./rfc7807";
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RFC 7807 Problem Details formatter implementation
|
|
3
|
-
* @module hono-ban/formatters/rfc7807/formatter
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { z } from "@hono/zod-openapi";
|
|
7
|
-
import { STATUS_CODES } from "../../constants";
|
|
8
|
-
import type { BanError, ErrorFormatter } from "../../types";
|
|
9
|
-
import type {
|
|
10
|
-
RFC7807Details,
|
|
11
|
-
RFC7807ErrorData,
|
|
12
|
-
RFC7807ValidationParam,
|
|
13
|
-
RFC7807FormatterOptions as RFC7807Options,
|
|
14
|
-
} from "../../types";
|
|
15
|
-
import {
|
|
16
|
-
RFC7807ConstraintViolationSchema,
|
|
17
|
-
RFC7807DetailsSchema,
|
|
18
|
-
RFC7807ValidationParamSchema,
|
|
19
|
-
} from "./schemas";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Create an RFC 7807 Problem Details formatter
|
|
23
|
-
*/
|
|
24
|
-
export function createRFC7807Formatter(
|
|
25
|
-
options: RFC7807Options = {}
|
|
26
|
-
): ErrorFormatter {
|
|
27
|
-
const baseUrl = options.baseUrl || "https://api.example.com/problems";
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
contentType: "application/problem+json",
|
|
31
|
-
|
|
32
|
-
format<T extends RFC7807ErrorData>(error: BanError<T>): RFC7807Details {
|
|
33
|
-
const base = {
|
|
34
|
-
type: `${baseUrl}/${error.status}`,
|
|
35
|
-
title: STATUS_CODES[error.status] || "Unknown Error",
|
|
36
|
-
status: error.status,
|
|
37
|
-
detail: error.message,
|
|
38
|
-
instance: `urn:uuid:${crypto.randomUUID()}`,
|
|
39
|
-
timestamp: new Date().toISOString(),
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// Handle validation errors
|
|
43
|
-
if (error.data?.["invalid-params"]) {
|
|
44
|
-
return RFC7807DetailsSchema.parse({
|
|
45
|
-
...base,
|
|
46
|
-
"invalid-params": error.data["invalid-params"],
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Handle constraint violations
|
|
51
|
-
if (error.data?.violations) {
|
|
52
|
-
return RFC7807DetailsSchema.parse({
|
|
53
|
-
...base,
|
|
54
|
-
violations: error.data.violations,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return RFC7807DetailsSchema.parse(base);
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create validation error data in RFC 7807 format
|
|
65
|
-
*/
|
|
66
|
-
export function createRFC7807ValidationError(params: RFC7807ValidationParam[]) {
|
|
67
|
-
return {
|
|
68
|
-
"invalid-params": RFC7807ValidationParamSchema.array().parse(params),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Convert Zod validation errors to RFC 7807 format
|
|
74
|
-
*/
|
|
75
|
-
export function createRFC7807ZodValidationError(error: z.ZodError) {
|
|
76
|
-
return {
|
|
77
|
-
"invalid-params": RFC7807ValidationParamSchema.array().parse(
|
|
78
|
-
error.errors.map((e) => ({
|
|
79
|
-
name: e.path.join("."),
|
|
80
|
-
reason: e.message,
|
|
81
|
-
}))
|
|
82
|
-
),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Create constraint violation data in RFC 7807 format
|
|
88
|
-
*/
|
|
89
|
-
export function createRFC7807ConstraintViolation(
|
|
90
|
-
name: string,
|
|
91
|
-
reason: string,
|
|
92
|
-
resource: string,
|
|
93
|
-
constraint: string = "unique"
|
|
94
|
-
) {
|
|
95
|
-
return {
|
|
96
|
-
violations: RFC7807ConstraintViolationSchema.array().parse([
|
|
97
|
-
{
|
|
98
|
-
name,
|
|
99
|
-
reason,
|
|
100
|
-
resource,
|
|
101
|
-
constraint,
|
|
102
|
-
},
|
|
103
|
-
]),
|
|
104
|
-
};
|
|
105
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RFC 7807 Problem Details hooks for Hono applications
|
|
3
|
-
* @module hono-ban/formatters/rfc7807/hooks
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ZodError } from "zod";
|
|
7
|
-
import { Hook } from "@hono/zod-openapi";
|
|
8
|
-
import { Env } from "hono";
|
|
9
|
-
import { badRequest } from "../../factories";
|
|
10
|
-
import type {
|
|
11
|
-
RFC7807FormatterOptions as RFC7807Options,
|
|
12
|
-
BanOptions,
|
|
13
|
-
} from "../../types";
|
|
14
|
-
import { createRFC7807ZodValidationError } from "./formatter";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Create a Hono hook that formats validation errors using RFC 7807
|
|
18
|
-
*
|
|
19
|
-
* This hook throws a badRequest error that will be caught and processed by the ban middleware.
|
|
20
|
-
* You can provide options to override the default behavior of the middleware.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* // Basic usage - inherits all settings from middleware
|
|
24
|
-
* app.openapi(route, handler, { onError: createRFC7807Hook() });
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* // With custom message
|
|
28
|
-
* app.openapi(route, handler, {
|
|
29
|
-
* onError: createRFC7807Hook({ message: "Custom validation error" })
|
|
30
|
-
* });
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* // With custom formatter and sanitization
|
|
34
|
-
* app.openapi(route, handler, {
|
|
35
|
-
* onError: createRFC7807Hook({
|
|
36
|
-
* formatter: customFormatter,
|
|
37
|
-
* sanitize: ['password', 'token']
|
|
38
|
-
* })
|
|
39
|
-
* });
|
|
40
|
-
*/
|
|
41
|
-
export function createRFC7807Hook<E extends Env = Env>(
|
|
42
|
-
options?: RFC7807Options & Partial<BanOptions>
|
|
43
|
-
): Hook<any, E, any, any> {
|
|
44
|
-
return (result, c) => {
|
|
45
|
-
if (
|
|
46
|
-
!result.success &&
|
|
47
|
-
"error" in result &&
|
|
48
|
-
result.error instanceof ZodError
|
|
49
|
-
) {
|
|
50
|
-
// Create the validation error data
|
|
51
|
-
const validationData = createRFC7807ZodValidationError(result.error);
|
|
52
|
-
|
|
53
|
-
// Throw badRequest with both the validation data and any override options
|
|
54
|
-
throw badRequest({
|
|
55
|
-
message: options?.message || "Validation Error",
|
|
56
|
-
data: validationData,
|
|
57
|
-
// Pass through any override options
|
|
58
|
-
formatter: options?.formatter,
|
|
59
|
-
headers: options?.headers,
|
|
60
|
-
sanitize: options?.sanitize,
|
|
61
|
-
includeStackTrace: options?.includeStackTrace,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Pre-configured RFC 7807 hook with default options
|
|
69
|
-
*
|
|
70
|
-
* This is a convenience export that uses the default options.
|
|
71
|
-
* It will throw a badRequest error that will be caught and processed by the ban middleware.
|
|
72
|
-
*/
|
|
73
|
-
export const rfc7807Hook = createRFC7807Hook<Env>();
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RFC 7807 Problem Details implementation for Hono Ban
|
|
3
|
-
* @module hono-ban/formatters/rfc7807
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
createRFC7807Formatter,
|
|
8
|
-
createRFC7807ValidationError,
|
|
9
|
-
createRFC7807ZodValidationError,
|
|
10
|
-
createRFC7807ConstraintViolation,
|
|
11
|
-
} from "./formatter";
|
|
12
|
-
|
|
13
|
-
export { createRFC7807Hook, rfc7807Hook } from "./hooks";
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
RFC7807ValidationParamSchema,
|
|
17
|
-
RFC7807ConstraintViolationSchema,
|
|
18
|
-
RFC7807ErrorDataSchema,
|
|
19
|
-
RFC7807DetailsSchema,
|
|
20
|
-
} from "./schemas";
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zod schemas for RFC 7807 Problem Details
|
|
3
|
-
* @module hono-ban/formatters/rfc7807/schemas
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { z } from "@hono/zod-openapi";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Schema for RFC 7807 validation error parameters
|
|
10
|
-
*/
|
|
11
|
-
export const RFC7807ValidationParamSchema = z.object({
|
|
12
|
-
name: z.string().openapi({
|
|
13
|
-
example: "username",
|
|
14
|
-
description: "The field name that failed validation",
|
|
15
|
-
}),
|
|
16
|
-
reason: z.string().openapi({
|
|
17
|
-
example: "String must contain at least 3 character(s)",
|
|
18
|
-
description: "The reason for validation failure",
|
|
19
|
-
}),
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Schema for RFC 7807 constraint violations
|
|
24
|
-
*/
|
|
25
|
-
export const RFC7807ConstraintViolationSchema = z.object({
|
|
26
|
-
name: z.string().openapi({
|
|
27
|
-
example: "email",
|
|
28
|
-
description: "The field name that violated a constraint",
|
|
29
|
-
}),
|
|
30
|
-
reason: z.string().openapi({
|
|
31
|
-
example: "Email already exists",
|
|
32
|
-
description: "The reason for the constraint violation",
|
|
33
|
-
}),
|
|
34
|
-
resource: z.string().openapi({
|
|
35
|
-
example: "user",
|
|
36
|
-
description: "The resource type that contains the constraint",
|
|
37
|
-
}),
|
|
38
|
-
constraint: z.string().openapi({
|
|
39
|
-
example: "unique",
|
|
40
|
-
description: "The type of constraint that was violated",
|
|
41
|
-
}),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Schema for additional error data in RFC 7807 problem details
|
|
46
|
-
*/
|
|
47
|
-
export const RFC7807ErrorDataSchema = z.object({
|
|
48
|
-
"invalid-params": z.array(RFC7807ValidationParamSchema).optional(),
|
|
49
|
-
violations: z.array(RFC7807ConstraintViolationSchema).optional(),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Schema for complete RFC 7807 problem details
|
|
54
|
-
*/
|
|
55
|
-
export const RFC7807DetailsSchema = z
|
|
56
|
-
.object({
|
|
57
|
-
type: z.string().url().openapi({
|
|
58
|
-
example: "https://api.example.com/problems/validation-error",
|
|
59
|
-
description: "A URI reference that identifies the problem type",
|
|
60
|
-
}),
|
|
61
|
-
title: z.string().openapi({
|
|
62
|
-
example: "Validation Failed",
|
|
63
|
-
description: "A short, human-readable summary of the problem type",
|
|
64
|
-
}),
|
|
65
|
-
status: z.number().int().min(400).max(599).openapi({
|
|
66
|
-
example: 400,
|
|
67
|
-
description: "The HTTP status code",
|
|
68
|
-
}),
|
|
69
|
-
|
|
70
|
-
// Optional fields per RFC7807
|
|
71
|
-
detail: z.string().optional().openapi({
|
|
72
|
-
example: "The request contains invalid fields",
|
|
73
|
-
description:
|
|
74
|
-
"A human-readable explanation specific to this occurrence of the problem",
|
|
75
|
-
}),
|
|
76
|
-
instance: z.string().url().optional().openapi({
|
|
77
|
-
example: "urn:uuid:6b56944d-5e89-4b4d-9ca7-c1be3d1f0e3f",
|
|
78
|
-
description:
|
|
79
|
-
"A URI reference that identifies the specific occurrence of the problem",
|
|
80
|
-
}),
|
|
81
|
-
|
|
82
|
-
// Extensions for validation errors
|
|
83
|
-
timestamp: z.string().datetime().optional().openapi({
|
|
84
|
-
example: "2025-02-26T12:34:56.789Z",
|
|
85
|
-
description: "When the error occurred",
|
|
86
|
-
}),
|
|
87
|
-
})
|
|
88
|
-
.merge(RFC7807ErrorDataSchema);
|
package/src/index.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main entry point for hono-ban
|
|
3
|
-
* @module hono-ban
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Export core functionality
|
|
7
|
-
export * from "./core";
|
|
8
|
-
|
|
9
|
-
// Export formatters
|
|
10
|
-
export * from "./formatters";
|
|
11
|
-
|
|
12
|
-
// Export error factories
|
|
13
|
-
export * from "./factories";
|
|
14
|
-
|
|
15
|
-
// Export constants
|
|
16
|
-
export * from "./constants";
|
|
17
|
-
|
|
18
|
-
// Export types
|
|
19
|
-
export * from "./types";
|
|
20
|
-
|
|
21
|
-
// Export middleware as default
|
|
22
|
-
import { ban } from "./middleware";
|
|
23
|
-
export default ban;
|