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
package/dist/cjs/index.js
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
var exports_src = {};
|
|
3
|
-
__export(exports_src, {
|
|
4
|
-
variantAlsoNegotiates: () => variantAlsoNegotiates,
|
|
5
|
-
uriTooLong: () => uriTooLong,
|
|
6
|
-
upgradeRequired: () => upgradeRequired,
|
|
7
|
-
unsupportedMediaType: () => unsupportedMediaType,
|
|
8
|
-
unauthorized: () => unauthorized,
|
|
9
|
-
tooManyRequests: () => tooManyRequests,
|
|
10
|
-
tooEarly: () => tooEarly,
|
|
11
|
-
teapot: () => teapot,
|
|
12
|
-
serverUnavailable: () => serverUnavailable,
|
|
13
|
-
rfc7807Hook: () => rfc7807Hook,
|
|
14
|
-
resourceGone: () => resourceGone,
|
|
15
|
-
rangeNotSatisfiable: () => rangeNotSatisfiable,
|
|
16
|
-
proxyAuthRequired: () => proxyAuthRequired,
|
|
17
|
-
preconditionRequired: () => preconditionRequired,
|
|
18
|
-
preconditionFailed: () => preconditionFailed,
|
|
19
|
-
paymentRequired: () => paymentRequired,
|
|
20
|
-
notImplemented: () => notImplemented,
|
|
21
|
-
notFound: () => notFound,
|
|
22
|
-
notExtended: () => notExtended,
|
|
23
|
-
notAcceptable: () => notAcceptable,
|
|
24
|
-
networkAuthRequired: () => networkAuthRequired,
|
|
25
|
-
misdirectedRequest: () => misdirectedRequest,
|
|
26
|
-
methodNotAllowed: () => methodNotAllowed,
|
|
27
|
-
loopDetected: () => loopDetected,
|
|
28
|
-
locked: () => locked,
|
|
29
|
-
lengthRequired: () => lengthRequired,
|
|
30
|
-
isBanError: () => isBanError,
|
|
31
|
-
internal: () => internal,
|
|
32
|
-
insufficientStorage: () => insufficientStorage,
|
|
33
|
-
illegal: () => illegal,
|
|
34
|
-
httpVersionNotSupported: () => httpVersionNotSupported,
|
|
35
|
-
headerFieldsTooLarge: () => headerFieldsTooLarge,
|
|
36
|
-
gatewayTimeout: () => gatewayTimeout,
|
|
37
|
-
formatError: () => formatError,
|
|
38
|
-
forbidden: () => forbidden,
|
|
39
|
-
failedDependency: () => failedDependency,
|
|
40
|
-
expectationFailed: () => expectationFailed,
|
|
41
|
-
entityTooLarge: () => entityTooLarge,
|
|
42
|
-
defaultFormatter: () => defaultFormatter,
|
|
43
|
-
default: () => src_default,
|
|
44
|
-
createRFC7807ZodValidationError: () => createRFC7807ZodValidationError,
|
|
45
|
-
createRFC7807ValidationError: () => createRFC7807ValidationError,
|
|
46
|
-
createRFC7807Hook: () => createRFC7807Hook,
|
|
47
|
-
createRFC7807Formatter: () => createRFC7807Formatter,
|
|
48
|
-
createRFC7807ConstraintViolation: () => createRFC7807ConstraintViolation,
|
|
49
|
-
createErrorResponse: () => createErrorResponse,
|
|
50
|
-
createError: () => createError,
|
|
51
|
-
convertToBanError: () => convertToBanError,
|
|
52
|
-
conflict: () => conflict,
|
|
53
|
-
clientTimeout: () => clientTimeout,
|
|
54
|
-
badRequest: () => badRequest,
|
|
55
|
-
badImplementation: () => badImplementation,
|
|
56
|
-
badGateway: () => badGateway,
|
|
57
|
-
badData: () => badData,
|
|
58
|
-
STATUS_CODES: () => STATUS_CODES,
|
|
59
|
-
RFC7807ValidationParamSchema: () => RFC7807ValidationParamSchema,
|
|
60
|
-
RFC7807ErrorDataSchema: () => RFC7807ErrorDataSchema,
|
|
61
|
-
RFC7807DetailsSchema: () => RFC7807DetailsSchema,
|
|
62
|
-
RFC7807ConstraintViolationSchema: () => RFC7807ConstraintViolationSchema
|
|
63
|
-
});
|
|
64
|
-
module.exports = __toCommonJS(exports_src);
|
|
65
|
-
|
|
66
|
-
// src/core/convert-error.ts
|
|
67
|
-
function isBanError(err, statusCode) {
|
|
68
|
-
return typeof err === "object" && err !== null && "isBan" in err && err.isBan === true && (!statusCode || err.status === statusCode);
|
|
69
|
-
}
|
|
70
|
-
function convertToBanError(err, options = {}) {
|
|
71
|
-
if (isBanError(err)) {
|
|
72
|
-
const merged = {
|
|
73
|
-
status: options.statusCode ?? err.status,
|
|
74
|
-
message: options.message ?? err.message,
|
|
75
|
-
isBan: true,
|
|
76
|
-
data: options.data !== undefined ? options.data : err.data,
|
|
77
|
-
headers: {
|
|
78
|
-
...err.headers,
|
|
79
|
-
...options.headers
|
|
80
|
-
},
|
|
81
|
-
allow: options.allow ? Array.isArray(options.allow) ? [...options.allow] : [options.allow] : err.allow,
|
|
82
|
-
cause: options.cause ?? err.cause,
|
|
83
|
-
stack: err.stack
|
|
84
|
-
};
|
|
85
|
-
return merged;
|
|
86
|
-
}
|
|
87
|
-
if (err instanceof Error) {
|
|
88
|
-
return createError({
|
|
89
|
-
...options,
|
|
90
|
-
message: options.message ?? err.message,
|
|
91
|
-
cause: err
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return createError({
|
|
95
|
-
...options,
|
|
96
|
-
message: options.message ?? (typeof err === "string" ? err : "Unknown error"),
|
|
97
|
-
cause: err
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// src/core/format-error.ts
|
|
102
|
-
function formatError(error, formatter, options = {}) {
|
|
103
|
-
return formatter.format(error, options.headers, options.sanitize, options.includeStackTrace);
|
|
104
|
-
}
|
|
105
|
-
function createErrorResponse(error, formatted) {
|
|
106
|
-
const headers = new Headers({
|
|
107
|
-
"Content-Type": "application/json",
|
|
108
|
-
...error.headers
|
|
109
|
-
});
|
|
110
|
-
if (error.allow?.length) {
|
|
111
|
-
headers.set("Allow", error.allow.join(", "));
|
|
112
|
-
}
|
|
113
|
-
const isDeveloperError = error.data && typeof error.data === "object" && "isDeveloperError" in error.data && error.data.isDeveloperError === true;
|
|
114
|
-
if (isDeveloperError && false) {
|
|
115
|
-
}
|
|
116
|
-
return new Response(JSON.stringify(formatted), {
|
|
117
|
-
status: error.status,
|
|
118
|
-
headers
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
// src/utils/sanitize.ts
|
|
122
|
-
function sanitizeObject(obj, keysToRemove) {
|
|
123
|
-
if (!keysToRemove.length) {
|
|
124
|
-
return obj;
|
|
125
|
-
}
|
|
126
|
-
if (Array.isArray(obj)) {
|
|
127
|
-
return obj.map((item) => sanitizeObject(item, keysToRemove));
|
|
128
|
-
}
|
|
129
|
-
if (obj !== null && typeof obj === "object") {
|
|
130
|
-
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
131
|
-
if (keysToRemove.includes(key)) {
|
|
132
|
-
return acc;
|
|
133
|
-
}
|
|
134
|
-
acc[key] = sanitizeObject(value, keysToRemove);
|
|
135
|
-
return acc;
|
|
136
|
-
}, {});
|
|
137
|
-
}
|
|
138
|
-
return obj;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// src/formatters/default/index.ts
|
|
142
|
-
var defaultFormatter = {
|
|
143
|
-
contentType: "application/json",
|
|
144
|
-
format(error, headers = {}, sanitize = [], includeStackTrace = false) {
|
|
145
|
-
const { status, message, data } = error;
|
|
146
|
-
const payload = {
|
|
147
|
-
statusCode: status,
|
|
148
|
-
error: STATUS_CODES[status] || "Unknown Error"
|
|
149
|
-
};
|
|
150
|
-
if (typeof message === "string") {
|
|
151
|
-
payload.message = message;
|
|
152
|
-
}
|
|
153
|
-
const isDeveloperError = data && typeof data === "object" && "isDeveloperError" in data && data.isDeveloperError === true;
|
|
154
|
-
if (includeStackTrace || isDeveloperError) {
|
|
155
|
-
if (error.stack) {
|
|
156
|
-
payload.stack = error.stack;
|
|
157
|
-
}
|
|
158
|
-
if (error.causeStack) {
|
|
159
|
-
payload.causeStack = error.causeStack;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (data !== undefined) {
|
|
163
|
-
payload.data = data;
|
|
164
|
-
}
|
|
165
|
-
const output = {
|
|
166
|
-
statusCode: status,
|
|
167
|
-
payload: sanitizeObject(payload, sanitize)
|
|
168
|
-
};
|
|
169
|
-
return output;
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// src/factories/server-errors.ts
|
|
174
|
-
function createErrorWithStatus(statusCode, messageOrOptions, options) {
|
|
175
|
-
if (typeof messageOrOptions === "string") {
|
|
176
|
-
return createError({
|
|
177
|
-
...options,
|
|
178
|
-
statusCode,
|
|
179
|
-
message: messageOrOptions
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
return createError({ ...messageOrOptions, ...options, statusCode });
|
|
183
|
-
}
|
|
184
|
-
function internal(messageOrOptions, options) {
|
|
185
|
-
return createErrorWithStatus(500, messageOrOptions, options);
|
|
186
|
-
}
|
|
187
|
-
function notImplemented(messageOrOptions, options) {
|
|
188
|
-
return createErrorWithStatus(501, messageOrOptions, options);
|
|
189
|
-
}
|
|
190
|
-
function badGateway(messageOrOptions, options) {
|
|
191
|
-
return createErrorWithStatus(502, messageOrOptions, options);
|
|
192
|
-
}
|
|
193
|
-
function serverUnavailable(messageOrOptions, options) {
|
|
194
|
-
return createErrorWithStatus(503, messageOrOptions, options);
|
|
195
|
-
}
|
|
196
|
-
function gatewayTimeout(messageOrOptions, options) {
|
|
197
|
-
return createErrorWithStatus(504, messageOrOptions, options);
|
|
198
|
-
}
|
|
199
|
-
function httpVersionNotSupported(messageOrOptions, options) {
|
|
200
|
-
return createErrorWithStatus(505, messageOrOptions, options);
|
|
201
|
-
}
|
|
202
|
-
function variantAlsoNegotiates(messageOrOptions, options) {
|
|
203
|
-
return createErrorWithStatus(506, messageOrOptions, options);
|
|
204
|
-
}
|
|
205
|
-
function insufficientStorage(messageOrOptions, options) {
|
|
206
|
-
return createErrorWithStatus(507, messageOrOptions, options);
|
|
207
|
-
}
|
|
208
|
-
function loopDetected(messageOrOptions, options) {
|
|
209
|
-
return createErrorWithStatus(508, messageOrOptions, options);
|
|
210
|
-
}
|
|
211
|
-
function notExtended(messageOrOptions, options) {
|
|
212
|
-
return createErrorWithStatus(510, messageOrOptions, options);
|
|
213
|
-
}
|
|
214
|
-
function networkAuthRequired(messageOrOptions, options) {
|
|
215
|
-
return createErrorWithStatus(511, messageOrOptions, options);
|
|
216
|
-
}
|
|
217
|
-
function badImplementation(messageOrOptions, options) {
|
|
218
|
-
const mergedOptions = typeof messageOrOptions === "string" ? { ...options, message: messageOrOptions } : { ...messageOrOptions, ...options };
|
|
219
|
-
const mergedData = {
|
|
220
|
-
isDeveloperError: true,
|
|
221
|
-
...mergedOptions.data || {}
|
|
222
|
-
};
|
|
223
|
-
return createError({
|
|
224
|
-
...mergedOptions,
|
|
225
|
-
statusCode: 500,
|
|
226
|
-
data: mergedData
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
// src/middleware/ban-middleware.ts
|
|
230
|
-
var DEFAULT_OPTIONS = {
|
|
231
|
-
formatter: defaultFormatter,
|
|
232
|
-
sanitize: [],
|
|
233
|
-
includeStackTrace: false,
|
|
234
|
-
headers: {}
|
|
235
|
-
};
|
|
236
|
-
function ban(options = {}) {
|
|
237
|
-
const resolvedOptions = {
|
|
238
|
-
...DEFAULT_OPTIONS,
|
|
239
|
-
...options,
|
|
240
|
-
formatter: options.formatter ? options.formatter : DEFAULT_OPTIONS.formatter,
|
|
241
|
-
headers: {
|
|
242
|
-
...DEFAULT_OPTIONS.headers,
|
|
243
|
-
...options.headers
|
|
244
|
-
},
|
|
245
|
-
sanitize: [...DEFAULT_OPTIONS.sanitize, ...options.sanitize || []]
|
|
246
|
-
};
|
|
247
|
-
return async (_, next) => {
|
|
248
|
-
try {
|
|
249
|
-
await next();
|
|
250
|
-
} catch (err) {
|
|
251
|
-
const formatter = resolvedOptions.formatter;
|
|
252
|
-
const error = convertToBanError(err, {
|
|
253
|
-
formatter,
|
|
254
|
-
headers: resolvedOptions.headers,
|
|
255
|
-
sanitize: resolvedOptions.sanitize,
|
|
256
|
-
includeStackTrace: resolvedOptions.includeStackTrace
|
|
257
|
-
});
|
|
258
|
-
const formatted = formatError(error, formatter, {
|
|
259
|
-
headers: resolvedOptions.headers,
|
|
260
|
-
sanitize: resolvedOptions.sanitize,
|
|
261
|
-
includeStackTrace: resolvedOptions.includeStackTrace
|
|
262
|
-
});
|
|
263
|
-
return createErrorResponse(error, formatted);
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
// src/index.ts
|
|
268
|
-
var src_default = ban;
|
|
269
|
-
|
|
270
|
-
//# debugId=63EAD7F7C48ADEFA64756E2164756E21
|
|
271
|
-
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/core/convert-error.ts", "../../src/core/format-error.ts", "../../src/utils/sanitize.ts", "../../src/formatters/default/index.ts", "../../src/factories/server-errors.ts", "../../src/middleware/ban-middleware.ts", "../../src/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Error conversion utilities\n * @module hono-ban/core/convert-error\n */\n\nimport type { BanError, BanOptions } from \"../types\";\nimport { createError } from \"./create-error\";\n\n/**\n * Type guard to check if a value is a BanError\n * @param err - Value to check\n * @param statusCode - Optional status code to match\n */\nexport function isBanError(err: unknown, statusCode?: number): err is BanError {\n return (\n typeof err === \"object\" &&\n err !== null &&\n \"isBan\" in err &&\n err.isBan === true &&\n (!statusCode || (err as BanError).status === statusCode)\n );\n}\n\n/**\n * Convert any error into a BanError\n * @param err - Error to convert\n * @param options - Additional options\n */\nexport function convertToBanError<T = unknown>(\n err: unknown,\n options: BanOptions<T> = {}\n): BanError<T> {\n // If already a BanError, merge options\n if (isBanError(err)) {\n const merged: BanError<T> = {\n status: options.statusCode ?? err.status,\n message: options.message ?? err.message,\n isBan: true,\n data: (options.data !== undefined ? options.data : err.data) as\n | T\n | undefined,\n headers: {\n ...err.headers,\n ...options.headers,\n },\n allow: options.allow\n ? Array.isArray(options.allow)\n ? [...options.allow]\n : [options.allow]\n : err.allow,\n cause: options.cause ?? err.cause,\n stack: err.stack,\n };\n\n return merged;\n }\n\n // Convert Error instance\n if (err instanceof Error) {\n return createError<T>({\n ...options,\n message: options.message ?? err.message,\n cause: err,\n });\n }\n\n // Handle unknown error types\n return createError<T>({\n ...options,\n message:\n options.message ?? (typeof err === \"string\" ? err : \"Unknown error\"),\n cause: err,\n });\n}\n",
|
|
6
|
-
"/**\n * Error formatting utilities\n * @module hono-ban/core/format-error\n */\n\nimport { STATUS_CODES } from \"../constants\";\nimport type { BanError, ErrorFormatter, FormatOptions } from \"../types\";\n\n/**\n * Format an error using the provided formatter\n * @param error - Error to format\n * @param formatter - Formatter to use\n * @param options - Formatting options\n */\nexport function formatError(\n error: BanError,\n formatter: ErrorFormatter,\n options: FormatOptions = {}\n): unknown {\n // Directly format the error without caching\n return formatter.format(\n error,\n options.headers,\n options.sanitize,\n options.includeStackTrace\n );\n}\n\n/**\n * Create a Response object from a formatted error\n * @param error - Error to create response from\n * @param formatted - Formatted error output\n */\nexport function createErrorResponse(\n error: BanError,\n formatted: unknown\n): Response {\n const headers = new Headers({\n \"Content-Type\": \"application/json\",\n ...error.headers,\n });\n\n if (error.allow?.length) {\n headers.set(\"Allow\", error.allow.join(\", \"));\n }\n\n // Check if this is a developer error in production\n const isDeveloperError =\n error.data &&\n typeof error.data === \"object\" &&\n \"isDeveloperError\" in error.data &&\n error.data.isDeveloperError === true;\n\n // Sanitize developer errors in production\n if (isDeveloperError && process.env.NODE_ENV === \"production\") {\n // Create a sanitized version without sensitive data\n const sanitizedFormatted = {\n statusCode: error.status,\n payload: {\n statusCode: error.status,\n error: STATUS_CODES[error.status],\n message: \"An internal server error occurred\",\n },\n };\n\n return new Response(JSON.stringify(sanitizedFormatted), {\n status: error.status,\n headers,\n });\n }\n\n return new Response(JSON.stringify(formatted), {\n status: error.status,\n headers,\n });\n}\n",
|
|
7
|
-
"/**\n * Sanitization utilities\n * @module hono-ban/utils/sanitize\n */\n\n/**\n * Recursively sanitize an object by removing specified keys\n * @param obj - Object to sanitize\n * @param keysToRemove - Keys to remove from object\n */\nexport function sanitizeObject(\n obj: unknown,\n keysToRemove: readonly string[]\n): unknown {\n if (!keysToRemove.length) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sanitizeObject(item, keysToRemove));\n }\n\n if (obj !== null && typeof obj === \"object\") {\n return Object.entries(obj).reduce((acc, [key, value]) => {\n if (keysToRemove.includes(key)) {\n return acc;\n }\n acc[key] = sanitizeObject(value, keysToRemove);\n return acc;\n }, {} as Record<string, unknown>);\n }\n\n return obj;\n}\n",
|
|
8
|
-
"/**\n * Default error formatter implementation\n * @module hono-ban/formatters/default\n */\n\nimport { STATUS_CODES } from \"../../constants\";\nimport type { BanError, DefaultErrorOutput, Headers } from \"../../types\";\nimport { sanitizeObject } from \"../../utils\";\n\n/**\n * Default JSON formatter maintaining backward compatibility\n */\nexport const defaultFormatter = {\n contentType: \"application/json\",\n\n /**\n * Format an error into a standardized output structure\n * @param error - Error to format\n * @param headers - Headers for HTTP response (not included in response body)\n * @param sanitize - Fields to remove from output\n * @param includeStackTrace - Whether to include stack traces\n */\n format(\n error: BanError,\n headers: Headers = {}, // Headers are used for HTTP headers, not included in response body\n sanitize: readonly string[] = [],\n includeStackTrace = false\n ): DefaultErrorOutput {\n const { status, message, data } = error;\n\n // Build base payload\n const payload: DefaultErrorOutput[\"payload\"] = {\n statusCode: status,\n error: STATUS_CODES[status] || \"Unknown Error\",\n };\n\n // Add optional fields\n if (typeof message === \"string\") {\n payload.message = message;\n }\n\n const isDeveloperError =\n data &&\n typeof data === \"object\" &&\n \"isDeveloperError\" in data &&\n data.isDeveloperError === true;\n\n if (includeStackTrace || isDeveloperError) {\n if (error.stack) {\n payload.stack = error.stack;\n }\n if (error.causeStack) {\n payload.causeStack = error.causeStack;\n }\n }\n\n if (data !== undefined) {\n payload.data = data;\n }\n\n // Create output structure\n const output: DefaultErrorOutput = {\n statusCode: status,\n payload: sanitizeObject(\n payload,\n sanitize\n ) as DefaultErrorOutput[\"payload\"],\n };\n\n return output;\n },\n};\n",
|
|
9
|
-
"/**\n * Server error factory functions (5xx)\n * @module hono-ban/factories/server-errors\n */\n\nimport type { BanError, BanOptions, ErrorStatusCode } from \"../types\";\nimport { createError } from \"../core\";\n\n/**\n * Helper function to reduce duplication\n * @param statusCode - HTTP status code\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nfunction createErrorWithStatus<T>(\n statusCode: ErrorStatusCode,\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n if (typeof messageOrOptions === \"string\") {\n return createError<T>({\n ...options,\n statusCode,\n message: messageOrOptions,\n });\n }\n return createError<T>({ ...messageOrOptions, ...options, statusCode });\n}\n\n/**\n * Create a 500 Internal Server Error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function internal<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 500 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 501 Not Implemented error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function notImplemented<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 501 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 502 Bad Gateway error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function badGateway<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 502 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 503 Service Unavailable error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function serverUnavailable<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 503 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 504 Gateway Timeout error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function gatewayTimeout<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 504 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 505 HTTP Version Not Supported error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function httpVersionNotSupported<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 505 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 506 Variant Also Negotiates error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function variantAlsoNegotiates<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 506 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 507 Insufficient Storage error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function insufficientStorage<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 507 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 508 Loop Detected error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function loopDetected<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 508 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 510 Not Extended error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function notExtended<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 510 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 511 Network Authentication Required error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function networkAuthRequired<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n return createErrorWithStatus(\n 511 as ErrorStatusCode,\n messageOrOptions,\n options\n );\n}\n\n/**\n * Create a 500 Internal Server Error marked as a developer error\n * @param messageOrOptions - Error message or options\n * @param options - Additional options\n */\nexport function badImplementation<T = unknown>(\n messageOrOptions?: string | Partial<BanOptions<T>>,\n options?: Partial<BanOptions<T>>\n): BanError<T> {\n const mergedOptions =\n typeof messageOrOptions === \"string\"\n ? { ...options, message: messageOrOptions }\n : { ...messageOrOptions, ...options };\n\n const mergedData = {\n isDeveloperError: true,\n ...((mergedOptions.data as Record<string, unknown>) || {}),\n } as unknown as T;\n\n return createError<T>({\n ...mergedOptions,\n statusCode: 500 as ErrorStatusCode,\n data: mergedData,\n });\n}\n",
|
|
10
|
-
"/**\n * Error handling middleware\n * @module hono-ban/middleware/ban-middleware\n */\n\nimport type { MiddlewareHandler } from \"hono\";\nimport { convertToBanError, formatError, createErrorResponse } from \"../core\";\nimport { defaultFormatter } from \"../formatters\";\nimport type { BanMiddlewareOptions } from \"../types\";\n\n/**\n * Default middleware options\n */\nconst DEFAULT_OPTIONS: Required<BanMiddlewareOptions> = {\n formatter: defaultFormatter,\n sanitize: [],\n includeStackTrace: false,\n headers: {},\n};\n\n/**\n * Create error handling middleware\n * @param options - Middleware configuration options\n *\n * @example\n * // Simple usage\n * app.use(ban());\n *\n * @example\n * // Advanced usage\n * app.use(ban({\n * formatter: customFormatter,\n * sanitize: ['password', 'token'],\n * includeStackTrace: process.env.NODE_ENV !== 'production'\n * }));\n */\nexport function ban(options: BanMiddlewareOptions = {}): MiddlewareHandler {\n const resolvedOptions: Required<BanMiddlewareOptions> = {\n ...DEFAULT_OPTIONS,\n ...options,\n formatter: options.formatter\n ? options.formatter\n : DEFAULT_OPTIONS.formatter,\n headers: {\n ...DEFAULT_OPTIONS.headers,\n ...options.headers,\n },\n sanitize: [...DEFAULT_OPTIONS.sanitize, ...(options.sanitize || [])],\n };\n\n // Return the middleware function that uses the pre-merged options\n return async (_, next) => {\n try {\n await next();\n } catch (err) {\n // Get the pre-resolved formatter instance\n const formatter = resolvedOptions.formatter;\n\n const error = convertToBanError(err, {\n formatter,\n headers: resolvedOptions.headers,\n sanitize: resolvedOptions.sanitize,\n includeStackTrace: resolvedOptions.includeStackTrace,\n });\n\n // Format the error using pre-resolved options\n const formatted = formatError(error, formatter, {\n headers: resolvedOptions.headers,\n sanitize: resolvedOptions.sanitize,\n includeStackTrace: resolvedOptions.includeStackTrace,\n });\n\n // Create and return response\n return createErrorResponse(error, formatted);\n }\n };\n}\n",
|
|
11
|
-
"/**\n * Main entry point for hono-ban\n * @module hono-ban\n */\n\n// Export core functionality\nexport * from \"./core\";\n\n// Export formatters\nexport * from \"./formatters\";\n\n// Export error factories\nexport * from \"./factories\";\n\n// Export constants\nexport * from \"./constants\";\n\n// Export types\nexport * from \"./types\";\n\n// Export middleware as default\nimport { ban } from \"./middleware\";\nexport default ban;\n"
|
|
12
|
-
],
|
|
13
|
-
"mappings": "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",
|
|
14
|
-
"debugId": "63EAD7F7C48ADEFA64756E2164756E21",
|
|
15
|
-
"names": []
|
|
16
|
-
}
|
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
// src/constants/status-codes.ts
|
|
2
|
-
var STATUS_CODES = {
|
|
3
|
-
400: "Bad Request",
|
|
4
|
-
401: "Unauthorized",
|
|
5
|
-
402: "Payment Required",
|
|
6
|
-
403: "Forbidden",
|
|
7
|
-
404: "Not Found",
|
|
8
|
-
405: "Method Not Allowed",
|
|
9
|
-
406: "Not Acceptable",
|
|
10
|
-
407: "Proxy Authentication Required",
|
|
11
|
-
408: "Request Timeout",
|
|
12
|
-
409: "Conflict",
|
|
13
|
-
410: "Gone",
|
|
14
|
-
411: "Length Required",
|
|
15
|
-
412: "Precondition Failed",
|
|
16
|
-
413: "Payload Too Large",
|
|
17
|
-
414: "URI Too Long",
|
|
18
|
-
415: "Unsupported Media Type",
|
|
19
|
-
416: "Range Not Satisfiable",
|
|
20
|
-
417: "Expectation Failed",
|
|
21
|
-
418: "I'm a teapot",
|
|
22
|
-
421: "Misdirected Request",
|
|
23
|
-
422: "Unprocessable Entity",
|
|
24
|
-
423: "Locked",
|
|
25
|
-
424: "Failed Dependency",
|
|
26
|
-
425: "Too Early",
|
|
27
|
-
426: "Upgrade Required",
|
|
28
|
-
428: "Precondition Required",
|
|
29
|
-
429: "Too Many Requests",
|
|
30
|
-
431: "Request Header Fields Too Large",
|
|
31
|
-
451: "Unavailable For Legal Reasons",
|
|
32
|
-
500: "Internal Server Error",
|
|
33
|
-
501: "Not Implemented",
|
|
34
|
-
502: "Bad Gateway",
|
|
35
|
-
503: "Service Unavailable",
|
|
36
|
-
504: "Gateway Timeout",
|
|
37
|
-
505: "HTTP Version Not Supported",
|
|
38
|
-
506: "Variant Also Negotiates",
|
|
39
|
-
507: "Insufficient Storage",
|
|
40
|
-
508: "Loop Detected",
|
|
41
|
-
510: "Not Extended",
|
|
42
|
-
511: "Network Authentication Required"
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// src/formatters/rfc7807/schemas.ts
|
|
46
|
-
import { z } from "@hono/zod-openapi";
|
|
47
|
-
var RFC7807ValidationParamSchema = z.object({
|
|
48
|
-
name: z.string().openapi({
|
|
49
|
-
example: "username",
|
|
50
|
-
description: "The field name that failed validation"
|
|
51
|
-
}),
|
|
52
|
-
reason: z.string().openapi({
|
|
53
|
-
example: "String must contain at least 3 character(s)",
|
|
54
|
-
description: "The reason for validation failure"
|
|
55
|
-
})
|
|
56
|
-
});
|
|
57
|
-
var RFC7807ConstraintViolationSchema = z.object({
|
|
58
|
-
name: z.string().openapi({
|
|
59
|
-
example: "email",
|
|
60
|
-
description: "The field name that violated a constraint"
|
|
61
|
-
}),
|
|
62
|
-
reason: z.string().openapi({
|
|
63
|
-
example: "Email already exists",
|
|
64
|
-
description: "The reason for the constraint violation"
|
|
65
|
-
}),
|
|
66
|
-
resource: z.string().openapi({
|
|
67
|
-
example: "user",
|
|
68
|
-
description: "The resource type that contains the constraint"
|
|
69
|
-
}),
|
|
70
|
-
constraint: z.string().openapi({
|
|
71
|
-
example: "unique",
|
|
72
|
-
description: "The type of constraint that was violated"
|
|
73
|
-
})
|
|
74
|
-
});
|
|
75
|
-
var RFC7807ErrorDataSchema = z.object({
|
|
76
|
-
"invalid-params": z.array(RFC7807ValidationParamSchema).optional(),
|
|
77
|
-
violations: z.array(RFC7807ConstraintViolationSchema).optional()
|
|
78
|
-
});
|
|
79
|
-
var RFC7807DetailsSchema = z.object({
|
|
80
|
-
type: z.string().url().openapi({
|
|
81
|
-
example: "https://api.example.com/problems/validation-error",
|
|
82
|
-
description: "A URI reference that identifies the problem type"
|
|
83
|
-
}),
|
|
84
|
-
title: z.string().openapi({
|
|
85
|
-
example: "Validation Failed",
|
|
86
|
-
description: "A short, human-readable summary of the problem type"
|
|
87
|
-
}),
|
|
88
|
-
status: z.number().int().min(400).max(599).openapi({
|
|
89
|
-
example: 400,
|
|
90
|
-
description: "The HTTP status code"
|
|
91
|
-
}),
|
|
92
|
-
detail: z.string().optional().openapi({
|
|
93
|
-
example: "The request contains invalid fields",
|
|
94
|
-
description: "A human-readable explanation specific to this occurrence of the problem"
|
|
95
|
-
}),
|
|
96
|
-
instance: z.string().url().optional().openapi({
|
|
97
|
-
example: "urn:uuid:6b56944d-5e89-4b4d-9ca7-c1be3d1f0e3f",
|
|
98
|
-
description: "A URI reference that identifies the specific occurrence of the problem"
|
|
99
|
-
}),
|
|
100
|
-
timestamp: z.string().datetime().optional().openapi({
|
|
101
|
-
example: "2025-02-26T12:34:56.789Z",
|
|
102
|
-
description: "When the error occurred"
|
|
103
|
-
})
|
|
104
|
-
}).merge(RFC7807ErrorDataSchema);
|
|
105
|
-
|
|
106
|
-
// src/formatters/rfc7807/formatter.ts
|
|
107
|
-
function createRFC7807Formatter(options = {}) {
|
|
108
|
-
const baseUrl = options.baseUrl || "https://api.example.com/problems";
|
|
109
|
-
return {
|
|
110
|
-
contentType: "application/problem+json",
|
|
111
|
-
format(error) {
|
|
112
|
-
const base = {
|
|
113
|
-
type: `${baseUrl}/${error.status}`,
|
|
114
|
-
title: STATUS_CODES[error.status] || "Unknown Error",
|
|
115
|
-
status: error.status,
|
|
116
|
-
detail: error.message,
|
|
117
|
-
instance: `urn:uuid:${crypto.randomUUID()}`,
|
|
118
|
-
timestamp: new Date().toISOString()
|
|
119
|
-
};
|
|
120
|
-
if (error.data?.["invalid-params"]) {
|
|
121
|
-
return RFC7807DetailsSchema.parse({
|
|
122
|
-
...base,
|
|
123
|
-
"invalid-params": error.data["invalid-params"]
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
if (error.data?.violations) {
|
|
127
|
-
return RFC7807DetailsSchema.parse({
|
|
128
|
-
...base,
|
|
129
|
-
violations: error.data.violations
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
return RFC7807DetailsSchema.parse(base);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function createRFC7807ValidationError(params) {
|
|
137
|
-
return {
|
|
138
|
-
"invalid-params": RFC7807ValidationParamSchema.array().parse(params)
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
function createRFC7807ZodValidationError(error) {
|
|
142
|
-
return {
|
|
143
|
-
"invalid-params": RFC7807ValidationParamSchema.array().parse(error.errors.map((e) => ({
|
|
144
|
-
name: e.path.join("."),
|
|
145
|
-
reason: e.message
|
|
146
|
-
})))
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
function createRFC7807ConstraintViolation(name, reason, resource, constraint = "unique") {
|
|
150
|
-
return {
|
|
151
|
-
violations: RFC7807ConstraintViolationSchema.array().parse([
|
|
152
|
-
{
|
|
153
|
-
name,
|
|
154
|
-
reason,
|
|
155
|
-
resource,
|
|
156
|
-
constraint
|
|
157
|
-
}
|
|
158
|
-
])
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
// src/formatters/rfc7807/hooks.ts
|
|
162
|
-
import { ZodError } from "zod";
|
|
163
|
-
|
|
164
|
-
// src/utils/validate.ts
|
|
165
|
-
function validateStatusCode(code) {
|
|
166
|
-
if (typeof code !== "number" || isNaN(code)) {
|
|
167
|
-
return 500;
|
|
168
|
-
}
|
|
169
|
-
if (code < 400 || code >= 600) {
|
|
170
|
-
return 500;
|
|
171
|
-
}
|
|
172
|
-
return code;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// src/core/create-error.ts
|
|
176
|
-
function createError(options) {
|
|
177
|
-
const status = validateStatusCode(options.statusCode ?? 500);
|
|
178
|
-
const error = {
|
|
179
|
-
status,
|
|
180
|
-
message: options.message ?? STATUS_CODES[status],
|
|
181
|
-
isBan: true
|
|
182
|
-
};
|
|
183
|
-
if (options.data !== undefined) {
|
|
184
|
-
error.data = options.data;
|
|
185
|
-
}
|
|
186
|
-
if (options.headers) {
|
|
187
|
-
error.headers = { ...options.headers };
|
|
188
|
-
}
|
|
189
|
-
if (options.allow) {
|
|
190
|
-
error.allow = Array.isArray(options.allow) ? [...options.allow] : [options.allow];
|
|
191
|
-
}
|
|
192
|
-
if (options.cause) {
|
|
193
|
-
error.cause = options.cause;
|
|
194
|
-
if (options.cause instanceof Error) {
|
|
195
|
-
error.causeStack = options.cause.stack;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
Error.captureStackTrace(error, createError);
|
|
199
|
-
return error;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// src/factories/client-errors.ts
|
|
203
|
-
function createErrorWithStatus(statusCode, messageOrOptions, options) {
|
|
204
|
-
if (typeof messageOrOptions === "string") {
|
|
205
|
-
return createError({
|
|
206
|
-
...options,
|
|
207
|
-
statusCode,
|
|
208
|
-
message: messageOrOptions
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
return createError({ ...messageOrOptions, ...options, statusCode });
|
|
212
|
-
}
|
|
213
|
-
function badRequest(messageOrOptions, options) {
|
|
214
|
-
return createErrorWithStatus(400, messageOrOptions, options);
|
|
215
|
-
}
|
|
216
|
-
function unauthorized(messageOrOptions, options) {
|
|
217
|
-
return createErrorWithStatus(401, messageOrOptions, options);
|
|
218
|
-
}
|
|
219
|
-
function paymentRequired(messageOrOptions, options) {
|
|
220
|
-
return createErrorWithStatus(402, messageOrOptions, options);
|
|
221
|
-
}
|
|
222
|
-
function forbidden(messageOrOptions, options) {
|
|
223
|
-
return createErrorWithStatus(403, messageOrOptions, options);
|
|
224
|
-
}
|
|
225
|
-
function notFound(messageOrOptions, options) {
|
|
226
|
-
return createErrorWithStatus(404, messageOrOptions, options);
|
|
227
|
-
}
|
|
228
|
-
function methodNotAllowed(messageOrOptions, options) {
|
|
229
|
-
return createErrorWithStatus(405, messageOrOptions, options);
|
|
230
|
-
}
|
|
231
|
-
function notAcceptable(messageOrOptions, options) {
|
|
232
|
-
return createErrorWithStatus(406, messageOrOptions, options);
|
|
233
|
-
}
|
|
234
|
-
function proxyAuthRequired(messageOrOptions, options) {
|
|
235
|
-
return createErrorWithStatus(407, messageOrOptions, options);
|
|
236
|
-
}
|
|
237
|
-
function clientTimeout(messageOrOptions, options) {
|
|
238
|
-
return createErrorWithStatus(408, messageOrOptions, options);
|
|
239
|
-
}
|
|
240
|
-
function conflict(messageOrOptions, options) {
|
|
241
|
-
return createErrorWithStatus(409, messageOrOptions, options);
|
|
242
|
-
}
|
|
243
|
-
function resourceGone(messageOrOptions, options) {
|
|
244
|
-
return createErrorWithStatus(410, messageOrOptions, options);
|
|
245
|
-
}
|
|
246
|
-
function lengthRequired(messageOrOptions, options) {
|
|
247
|
-
return createErrorWithStatus(411, messageOrOptions, options);
|
|
248
|
-
}
|
|
249
|
-
function preconditionFailed(messageOrOptions, options) {
|
|
250
|
-
return createErrorWithStatus(412, messageOrOptions, options);
|
|
251
|
-
}
|
|
252
|
-
function entityTooLarge(messageOrOptions, options) {
|
|
253
|
-
return createErrorWithStatus(413, messageOrOptions, options);
|
|
254
|
-
}
|
|
255
|
-
function uriTooLong(messageOrOptions, options) {
|
|
256
|
-
return createErrorWithStatus(414, messageOrOptions, options);
|
|
257
|
-
}
|
|
258
|
-
function unsupportedMediaType(messageOrOptions, options) {
|
|
259
|
-
return createErrorWithStatus(415, messageOrOptions, options);
|
|
260
|
-
}
|
|
261
|
-
function rangeNotSatisfiable(messageOrOptions, options) {
|
|
262
|
-
return createErrorWithStatus(416, messageOrOptions, options);
|
|
263
|
-
}
|
|
264
|
-
function expectationFailed(messageOrOptions, options) {
|
|
265
|
-
return createErrorWithStatus(417, messageOrOptions, options);
|
|
266
|
-
}
|
|
267
|
-
function teapot(messageOrOptions, options) {
|
|
268
|
-
return createErrorWithStatus(418, messageOrOptions, options);
|
|
269
|
-
}
|
|
270
|
-
function misdirectedRequest(messageOrOptions, options) {
|
|
271
|
-
return createErrorWithStatus(421, messageOrOptions, options);
|
|
272
|
-
}
|
|
273
|
-
function badData(messageOrOptions, options) {
|
|
274
|
-
return createErrorWithStatus(422, messageOrOptions, options);
|
|
275
|
-
}
|
|
276
|
-
function locked(messageOrOptions, options) {
|
|
277
|
-
return createErrorWithStatus(423, messageOrOptions, options);
|
|
278
|
-
}
|
|
279
|
-
function failedDependency(messageOrOptions, options) {
|
|
280
|
-
return createErrorWithStatus(424, messageOrOptions, options);
|
|
281
|
-
}
|
|
282
|
-
function tooEarly(messageOrOptions, options) {
|
|
283
|
-
return createErrorWithStatus(425, messageOrOptions, options);
|
|
284
|
-
}
|
|
285
|
-
function upgradeRequired(messageOrOptions, options) {
|
|
286
|
-
return createErrorWithStatus(426, messageOrOptions, options);
|
|
287
|
-
}
|
|
288
|
-
function preconditionRequired(messageOrOptions, options) {
|
|
289
|
-
return createErrorWithStatus(428, messageOrOptions, options);
|
|
290
|
-
}
|
|
291
|
-
function tooManyRequests(messageOrOptions, options) {
|
|
292
|
-
return createErrorWithStatus(429, messageOrOptions, options);
|
|
293
|
-
}
|
|
294
|
-
function headerFieldsTooLarge(messageOrOptions, options) {
|
|
295
|
-
return createErrorWithStatus(431, messageOrOptions, options);
|
|
296
|
-
}
|
|
297
|
-
function illegal(messageOrOptions, options) {
|
|
298
|
-
return createErrorWithStatus(451, messageOrOptions, options);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// src/formatters/rfc7807/hooks.ts
|
|
302
|
-
function createRFC7807Hook(options) {
|
|
303
|
-
return (result, c) => {
|
|
304
|
-
if (!result.success && "error" in result && result.error instanceof ZodError) {
|
|
305
|
-
const validationData = createRFC7807ZodValidationError(result.error);
|
|
306
|
-
throw badRequest({
|
|
307
|
-
message: options?.message || "Validation Error",
|
|
308
|
-
data: validationData,
|
|
309
|
-
formatter: options?.formatter,
|
|
310
|
-
headers: options?.headers,
|
|
311
|
-
sanitize: options?.sanitize,
|
|
312
|
-
includeStackTrace: options?.includeStackTrace
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
var rfc7807Hook = createRFC7807Hook();
|
|
318
|
-
export {
|
|
319
|
-
rfc7807Hook,
|
|
320
|
-
createRFC7807ZodValidationError,
|
|
321
|
-
createRFC7807ValidationError,
|
|
322
|
-
createRFC7807Hook,
|
|
323
|
-
createRFC7807Formatter,
|
|
324
|
-
createRFC7807ConstraintViolation,
|
|
325
|
-
RFC7807ValidationParamSchema,
|
|
326
|
-
RFC7807ErrorDataSchema,
|
|
327
|
-
RFC7807DetailsSchema,
|
|
328
|
-
RFC7807ConstraintViolationSchema
|
|
329
|
-
};
|
|
330
|
-
export { STATUS_CODES, createError, RFC7807ValidationParamSchema, RFC7807ConstraintViolationSchema, RFC7807ErrorDataSchema, RFC7807DetailsSchema, createRFC7807Formatter, createRFC7807ValidationError, createRFC7807ZodValidationError, createRFC7807ConstraintViolation, badRequest, unauthorized, paymentRequired, forbidden, notFound, methodNotAllowed, notAcceptable, proxyAuthRequired, clientTimeout, conflict, resourceGone, lengthRequired, preconditionFailed, entityTooLarge, uriTooLong, unsupportedMediaType, rangeNotSatisfiable, expectationFailed, teapot, misdirectedRequest, badData, locked, failedDependency, tooEarly, upgradeRequired, preconditionRequired, tooManyRequests, headerFieldsTooLarge, illegal, createRFC7807Hook, rfc7807Hook };
|
|
331
|
-
|
|
332
|
-
//# debugId=70213BB604F8C2D564756E2164756E21
|
|
333
|
-
//# sourceMappingURL=index.js.map
|