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,35 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "bun:test";
|
|
2
|
-
import { validateStatusCode } from "../../utils/validate";
|
|
3
|
-
|
|
4
|
-
describe("validateStatusCode", () => {
|
|
5
|
-
it("returns the same code for valid error status codes", () => {
|
|
6
|
-
expect(validateStatusCode(400)).toBe(400);
|
|
7
|
-
expect(validateStatusCode(404)).toBe(404);
|
|
8
|
-
expect(validateStatusCode(500)).toBe(500);
|
|
9
|
-
expect(validateStatusCode(503)).toBe(503);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it("returns 500 for status codes below 400", () => {
|
|
13
|
-
expect(validateStatusCode(100)).toBe(500);
|
|
14
|
-
expect(validateStatusCode(200)).toBe(500);
|
|
15
|
-
expect(validateStatusCode(300)).toBe(500);
|
|
16
|
-
expect(validateStatusCode(399)).toBe(500);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("returns 500 for status codes at or above 600", () => {
|
|
20
|
-
expect(validateStatusCode(600)).toBe(500);
|
|
21
|
-
expect(validateStatusCode(700)).toBe(500);
|
|
22
|
-
expect(validateStatusCode(999)).toBe(500);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("handles edge cases", () => {
|
|
26
|
-
// @ts-expect-error - Testing with invalid input
|
|
27
|
-
expect(validateStatusCode(null)).toBe(500);
|
|
28
|
-
// @ts-expect-error - Testing with invalid input
|
|
29
|
-
expect(validateStatusCode(undefined)).toBe(500);
|
|
30
|
-
// @ts-expect-error - Testing with invalid input
|
|
31
|
-
expect(validateStatusCode("400")).toBe(500);
|
|
32
|
-
|
|
33
|
-
expect(validateStatusCode(NaN)).toBe(500);
|
|
34
|
-
});
|
|
35
|
-
});
|
package/src/constants/index.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP status code constants
|
|
3
|
-
* @module hono-ban/constants/status-codes
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ErrorStatusCode } from "../types/error";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Map of HTTP error status codes to their default messages
|
|
10
|
-
*/
|
|
11
|
-
export const STATUS_CODES: Record<ErrorStatusCode, string> = {
|
|
12
|
-
400: "Bad Request",
|
|
13
|
-
401: "Unauthorized",
|
|
14
|
-
402: "Payment Required",
|
|
15
|
-
403: "Forbidden",
|
|
16
|
-
404: "Not Found",
|
|
17
|
-
405: "Method Not Allowed",
|
|
18
|
-
406: "Not Acceptable",
|
|
19
|
-
407: "Proxy Authentication Required",
|
|
20
|
-
408: "Request Timeout",
|
|
21
|
-
409: "Conflict",
|
|
22
|
-
410: "Gone",
|
|
23
|
-
411: "Length Required",
|
|
24
|
-
412: "Precondition Failed",
|
|
25
|
-
413: "Payload Too Large",
|
|
26
|
-
414: "URI Too Long",
|
|
27
|
-
415: "Unsupported Media Type",
|
|
28
|
-
416: "Range Not Satisfiable",
|
|
29
|
-
417: "Expectation Failed",
|
|
30
|
-
418: "I'm a teapot",
|
|
31
|
-
421: "Misdirected Request",
|
|
32
|
-
422: "Unprocessable Entity",
|
|
33
|
-
423: "Locked",
|
|
34
|
-
424: "Failed Dependency",
|
|
35
|
-
425: "Too Early",
|
|
36
|
-
426: "Upgrade Required",
|
|
37
|
-
428: "Precondition Required",
|
|
38
|
-
429: "Too Many Requests",
|
|
39
|
-
431: "Request Header Fields Too Large",
|
|
40
|
-
451: "Unavailable For Legal Reasons",
|
|
41
|
-
500: "Internal Server Error",
|
|
42
|
-
501: "Not Implemented",
|
|
43
|
-
502: "Bad Gateway",
|
|
44
|
-
503: "Service Unavailable",
|
|
45
|
-
504: "Gateway Timeout",
|
|
46
|
-
505: "HTTP Version Not Supported",
|
|
47
|
-
506: "Variant Also Negotiates",
|
|
48
|
-
507: "Insufficient Storage",
|
|
49
|
-
508: "Loop Detected",
|
|
50
|
-
510: "Not Extended",
|
|
51
|
-
511: "Network Authentication Required",
|
|
52
|
-
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error conversion utilities
|
|
3
|
-
* @module hono-ban/core/convert-error
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { BanError, BanOptions } from "../types";
|
|
7
|
-
import { createError } from "./create-error";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Type guard to check if a value is a BanError
|
|
11
|
-
* @param err - Value to check
|
|
12
|
-
* @param statusCode - Optional status code to match
|
|
13
|
-
*/
|
|
14
|
-
export function isBanError(err: unknown, statusCode?: number): err is BanError {
|
|
15
|
-
return (
|
|
16
|
-
typeof err === "object" &&
|
|
17
|
-
err !== null &&
|
|
18
|
-
"isBan" in err &&
|
|
19
|
-
err.isBan === true &&
|
|
20
|
-
(!statusCode || (err as BanError).status === statusCode)
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Convert any error into a BanError
|
|
26
|
-
* @param err - Error to convert
|
|
27
|
-
* @param options - Additional options
|
|
28
|
-
*/
|
|
29
|
-
export function convertToBanError<T = unknown>(
|
|
30
|
-
err: unknown,
|
|
31
|
-
options: BanOptions<T> = {}
|
|
32
|
-
): BanError<T> {
|
|
33
|
-
// If already a BanError, merge options
|
|
34
|
-
if (isBanError(err)) {
|
|
35
|
-
const merged: BanError<T> = {
|
|
36
|
-
status: options.statusCode ?? err.status,
|
|
37
|
-
message: options.message ?? err.message,
|
|
38
|
-
isBan: true,
|
|
39
|
-
data: (options.data !== undefined ? options.data : err.data) as
|
|
40
|
-
| T
|
|
41
|
-
| undefined,
|
|
42
|
-
headers: {
|
|
43
|
-
...err.headers,
|
|
44
|
-
...options.headers,
|
|
45
|
-
},
|
|
46
|
-
allow: options.allow
|
|
47
|
-
? Array.isArray(options.allow)
|
|
48
|
-
? [...options.allow]
|
|
49
|
-
: [options.allow]
|
|
50
|
-
: err.allow,
|
|
51
|
-
cause: options.cause ?? err.cause,
|
|
52
|
-
stack: err.stack,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return merged;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Convert Error instance
|
|
59
|
-
if (err instanceof Error) {
|
|
60
|
-
return createError<T>({
|
|
61
|
-
...options,
|
|
62
|
-
message: options.message ?? err.message,
|
|
63
|
-
cause: err,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Handle unknown error types
|
|
68
|
-
return createError<T>({
|
|
69
|
-
...options,
|
|
70
|
-
message:
|
|
71
|
-
options.message ?? (typeof err === "string" ? err : "Unknown error"),
|
|
72
|
-
cause: err,
|
|
73
|
-
});
|
|
74
|
-
}
|
package/src/core/create-error.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error creation utilities
|
|
3
|
-
* @module hono-ban/core/create-error
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { STATUS_CODES } from "../constants/status-codes";
|
|
7
|
-
import type { BanError, BanOptions } from "../types";
|
|
8
|
-
import { validateStatusCode } from "../utils/validate";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Create a new error object with the given options
|
|
12
|
-
* @param options - Error creation options
|
|
13
|
-
* @returns A BanError object
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* // Basic usage
|
|
17
|
-
* const error = createError({ statusCode: 404, message: "User not found" });
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // With custom data
|
|
21
|
-
* const error = createError({
|
|
22
|
-
* statusCode: 400,
|
|
23
|
-
* message: "Validation failed",
|
|
24
|
-
* data: { field: "email", issue: "invalid format" }
|
|
25
|
-
* });
|
|
26
|
-
*/
|
|
27
|
-
export function createError<T = unknown>(options: BanOptions<T>): BanError<T> {
|
|
28
|
-
// Validate and normalize status code
|
|
29
|
-
const status = validateStatusCode(options.statusCode ?? 500);
|
|
30
|
-
|
|
31
|
-
// Create the error object
|
|
32
|
-
const error: BanError<T> = {
|
|
33
|
-
status,
|
|
34
|
-
message: options.message ?? STATUS_CODES[status],
|
|
35
|
-
isBan: true,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// Add optional properties
|
|
39
|
-
if (options.data !== undefined) {
|
|
40
|
-
error.data = options.data;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (options.headers) {
|
|
44
|
-
error.headers = { ...options.headers };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (options.allow) {
|
|
48
|
-
error.allow = Array.isArray(options.allow)
|
|
49
|
-
? [...options.allow]
|
|
50
|
-
: [options.allow];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (options.cause) {
|
|
54
|
-
error.cause = options.cause;
|
|
55
|
-
// Keep cause stack separately rather than overwriting the main stack
|
|
56
|
-
if (options.cause instanceof Error) {
|
|
57
|
-
error.causeStack = options.cause.stack;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Always capture a fresh stack trace for the BanError itself
|
|
62
|
-
Error.captureStackTrace(error, createError);
|
|
63
|
-
|
|
64
|
-
return error;
|
|
65
|
-
}
|
package/src/core/format-error.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error formatting utilities
|
|
3
|
-
* @module hono-ban/core/format-error
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { STATUS_CODES } from "../constants";
|
|
7
|
-
import type { BanError, ErrorFormatter, FormatOptions } from "../types";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Format an error using the provided formatter
|
|
11
|
-
* @param error - Error to format
|
|
12
|
-
* @param formatter - Formatter to use
|
|
13
|
-
* @param options - Formatting options
|
|
14
|
-
*/
|
|
15
|
-
export function formatError(
|
|
16
|
-
error: BanError,
|
|
17
|
-
formatter: ErrorFormatter,
|
|
18
|
-
options: FormatOptions = {}
|
|
19
|
-
): unknown {
|
|
20
|
-
// Directly format the error without caching
|
|
21
|
-
return formatter.format(
|
|
22
|
-
error,
|
|
23
|
-
options.headers,
|
|
24
|
-
options.sanitize,
|
|
25
|
-
options.includeStackTrace
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Create a Response object from a formatted error
|
|
31
|
-
* @param error - Error to create response from
|
|
32
|
-
* @param formatted - Formatted error output
|
|
33
|
-
*/
|
|
34
|
-
export function createErrorResponse(
|
|
35
|
-
error: BanError,
|
|
36
|
-
formatted: unknown
|
|
37
|
-
): Response {
|
|
38
|
-
const headers = new Headers({
|
|
39
|
-
"Content-Type": "application/json",
|
|
40
|
-
...error.headers,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (error.allow?.length) {
|
|
44
|
-
headers.set("Allow", error.allow.join(", "));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Check if this is a developer error in production
|
|
48
|
-
const isDeveloperError =
|
|
49
|
-
error.data &&
|
|
50
|
-
typeof error.data === "object" &&
|
|
51
|
-
"isDeveloperError" in error.data &&
|
|
52
|
-
error.data.isDeveloperError === true;
|
|
53
|
-
|
|
54
|
-
// Sanitize developer errors in production
|
|
55
|
-
if (isDeveloperError && process.env.NODE_ENV === "production") {
|
|
56
|
-
// Create a sanitized version without sensitive data
|
|
57
|
-
const sanitizedFormatted = {
|
|
58
|
-
statusCode: error.status,
|
|
59
|
-
payload: {
|
|
60
|
-
statusCode: error.status,
|
|
61
|
-
error: STATUS_CODES[error.status],
|
|
62
|
-
message: "An internal server error occurred",
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
return new Response(JSON.stringify(sanitizedFormatted), {
|
|
67
|
-
status: error.status,
|
|
68
|
-
headers,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return new Response(JSON.stringify(formatted), {
|
|
73
|
-
status: error.status,
|
|
74
|
-
headers,
|
|
75
|
-
});
|
|
76
|
-
}
|