hono-ban 0.2.8 → 0.2.9

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/README.md CHANGED
@@ -306,7 +306,7 @@ hono-ban includes several built-in formatters for common error response formats.
306
306
 
307
307
  ### Default Formatter
308
308
 
309
- The default formatter produces a simple JSON structure with status code, error name, and optional message and data.
309
+ The default formatter produces a clean, flat JSON structure with status code, error name, and optional message and data.
310
310
 
311
311
  ```typescript
312
312
  import { defaultFormatter } from "hono-ban";
@@ -314,12 +314,9 @@ import { defaultFormatter } from "hono-ban";
314
314
  // Example output:
315
315
  // {
316
316
  // "statusCode": 400,
317
- // "payload": {
318
- // "statusCode": 400,
319
- // "error": "Bad Request",
320
- // "message": "Invalid input",
321
- // "data": { "field": "email" }
322
- // }
317
+ // "error": "Bad Request",
318
+ // "message": "Invalid input",
319
+ // "data": { "field": "email" }
323
320
  // }
324
321
  ```
325
322
 
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- var V={400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",421:"Misdirected Request",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required"};function N(x){if(typeof x!=="number"||isNaN(x))return 500;if(x<400||x>=600)return 500;return x}function J(x){let f=N(x.statusCode??500),K={status:f,message:x.message??V[f],isBan:!0};if(x.data!==void 0)K.data=x.data;if(x.headers)K.headers={...x.headers};if(x.allow)K.allow=Array.isArray(x.allow)?[...x.allow]:[x.allow];if(x.cause){if(K.cause=x.cause,x.cause instanceof Error)K.causeStack=x.cause.stack}return Error.captureStackTrace(K,J),K}function D(x,f){return typeof x==="object"&&x!==null&&"isBan"in x&&x.isBan===!0&&(!f||x.status===f)}function L(x,f={}){if(D(x))return{status:f.statusCode??x.status,message:f.message??x.message,isBan:!0,data:f.data!==void 0?f.data:x.data,headers:{...x.headers,...f.headers},allow:f.allow?Array.isArray(f.allow)?[...f.allow]:[f.allow]:x.allow,cause:f.cause??x.cause,stack:x.stack};if(x instanceof Error)return J({...f,message:f.message??x.message,cause:x});return J({...f,message:f.message??(typeof x==="string"?x:"Unknown error"),cause:x})}function R(x,f,K={}){return f.format(x,K.headers,K.sanitize,K.includeStackTrace)}function _(x,f){let K=new Headers({"Content-Type":"application/json",...x.headers});if(x.allow?.length)K.set("Allow",x.allow.join(", "));let j=x.data&&typeof x.data==="object"&&"isDeveloperError"in x.data&&x.data.isDeveloperError===!0;return new Response(JSON.stringify(f),{status:x.status,headers:K})}function b(x,f){if(!f.length)return x;if(Array.isArray(x))return x.map((K)=>b(K,f));if(x!==null&&typeof x==="object")return Object.entries(x).reduce((K,[j,Y])=>{if(f.includes(j))return K;return K[j]=b(Y,f),K},{});return x}var I={contentType:"application/json",format(x,f={},K=[],j=!1){let{status:Y,message:Z,data:X}=x,$={statusCode:Y,error:V[Y]||"Unknown Error"};if(typeof Z==="string")$.message=Z;let U=X&&typeof X==="object"&&"isDeveloperError"in X&&X.isDeveloperError===!0;if(j||U){if(x.stack)$.stack=x.stack;if(x.causeStack)$.causeStack=x.causeStack}if(X!==void 0)$.data=X;return{statusCode:Y,payload:b($,K)}}};import{z as G}from"@hono/zod-openapi";var q=G.object({name:G.string().openapi({example:"username",description:"The field name that failed validation"}),reason:G.string().openapi({example:"String must contain at least 3 character(s)",description:"The reason for validation failure"})}),w=G.object({name:G.string().openapi({example:"email",description:"The field name that violated a constraint"}),reason:G.string().openapi({example:"Email already exists",description:"The reason for the constraint violation"}),resource:G.string().openapi({example:"user",description:"The resource type that contains the constraint"}),constraint:G.string().openapi({example:"unique",description:"The type of constraint that was violated"})}),A=G.object({"invalid-params":G.array(q).optional(),violations:G.array(w).optional()}),H=G.object({type:G.string().url().openapi({example:"https://api.example.com/problems/validation-error",description:"A URI reference that identifies the problem type"}),title:G.string().openapi({example:"Validation Failed",description:"A short, human-readable summary of the problem type"}),status:G.number().int().min(400).max(599).openapi({example:400,description:"The HTTP status code"}),detail:G.string().optional().openapi({example:"The request contains invalid fields",description:"A human-readable explanation specific to this occurrence of the problem"}),instance:G.string().url().optional().openapi({example:"urn:uuid:6b56944d-5e89-4b4d-9ca7-c1be3d1f0e3f",description:"A URI reference that identifies the specific occurrence of the problem"}),timestamp:G.string().datetime().optional().openapi({example:"2025-02-26T12:34:56.789Z",description:"When the error occurred"})}).merge(A);function z(x={}){let f=x.baseUrl||"https://api.example.com/problems";return{contentType:"application/problem+json",format(K){let j={type:`${f}/${K.status}`,title:V[K.status]||"Unknown Error",status:K.status,detail:K.message,instance:`urn:uuid:${crypto.randomUUID()}`,timestamp:new Date().toISOString()};if(K.data?.["invalid-params"])return H.parse({...j,"invalid-params":K.data["invalid-params"]});if(K.data?.violations)return H.parse({...j,violations:K.data.violations});return H.parse(j)}}}function v(x){return{"invalid-params":q.array().parse(x)}}function y(x){return{"invalid-params":q.array().parse(x.errors.map((f)=>({name:f.path.join("."),reason:f.message})))}}function T(x,f,K,j="unique"){return{violations:w.array().parse([{name:x,reason:f,resource:K,constraint:j}])}}import{ZodError as C}from"zod";function M(x,f,K){if(typeof f==="string")return J({...K,statusCode:x,message:f});return J({...f,...K,statusCode:x})}function F(x,f){return M(400,x,f)}function x7(x,f){return M(401,x,f)}function f7(x,f){return M(402,x,f)}function K7(x,f){return M(403,x,f)}function M7(x,f){return M(404,x,f)}function j7(x,f){return M(405,x,f)}function G7(x,f){return M(406,x,f)}function J7(x,f){return M(407,x,f)}function Q7(x,f){return M(408,x,f)}function X7(x,f){return M(409,x,f)}function Y7(x,f){return M(410,x,f)}function $7(x,f){return M(411,x,f)}function V7(x,f){return M(412,x,f)}function Z7(x,f){return M(413,x,f)}function q7(x,f){return M(414,x,f)}function H7(x,f){return M(415,x,f)}function b7(x,f){return M(416,x,f)}function w7(x,f){return M(417,x,f)}function k7(x,f){return M(418,x,f)}function y7(x,f){return M(421,x,f)}function B7(x,f){return M(422,x,f)}function N7(x,f){return M(423,x,f)}function L7(x,f){return M(424,x,f)}function R7(x,f){return M(425,x,f)}function _7(x,f){return M(426,x,f)}function I7(x,f){return M(428,x,f)}function A7(x,f){return M(429,x,f)}function F7(x,f){return M(431,x,f)}function P7(x,f){return M(451,x,f)}function Q(x,f,K){if(typeof f==="string")return J({...K,statusCode:x,message:f});return J({...f,...K,statusCode:x})}function z7(x,f){return Q(500,x,f)}function v7(x,f){return Q(501,x,f)}function T7(x,f){return Q(502,x,f)}function C7(x,f){return Q(503,x,f)}function l7(x,f){return Q(504,x,f)}function W7(x,f){return Q(505,x,f)}function h7(x,f){return Q(506,x,f)}function S7(x,f){return Q(507,x,f)}function E7(x,f){return Q(508,x,f)}function u7(x,f){return Q(510,x,f)}function d7(x,f){return Q(511,x,f)}function c7(x,f){let K=typeof x==="string"?{...f,message:x}:{...x,...f},j={isDeveloperError:!0,...K.data||{}};return J({...K,statusCode:500,data:j})}function P(x){return(f,K)=>{if(!f.success&&"error"in f&&f.error instanceof C){let j=y(f.error);throw F({message:x?.message||"Validation Error",data:j,formatter:x?.formatter,headers:x?.headers,sanitize:x?.sanitize,includeStackTrace:x?.includeStackTrace})}}}var l=P();var k={formatter:I,sanitize:[],includeStackTrace:!1,headers:{}};function B(x={}){let f={...k,...x,formatter:x.formatter?x.formatter:k.formatter,headers:{...k.headers,...x.headers},sanitize:[...k.sanitize,...x.sanitize||[]]};return async(K,j)=>{try{await j()}catch(Y){let Z=f.formatter,X=L(Y,{formatter:Z,headers:f.headers,sanitize:f.sanitize,includeStackTrace:f.includeStackTrace}),$=R(X,Z,{headers:f.headers,sanitize:f.sanitize,includeStackTrace:f.includeStackTrace});return _(X,$)}}}var Yx=B;export{h7 as variantAlsoNegotiates,q7 as uriTooLong,_7 as upgradeRequired,H7 as unsupportedMediaType,x7 as unauthorized,A7 as tooManyRequests,R7 as tooEarly,k7 as teapot,C7 as serverUnavailable,l as rfc7807Hook,Y7 as resourceGone,b7 as rangeNotSatisfiable,J7 as proxyAuthRequired,I7 as preconditionRequired,V7 as preconditionFailed,f7 as paymentRequired,v7 as notImplemented,M7 as notFound,u7 as notExtended,G7 as notAcceptable,d7 as networkAuthRequired,y7 as misdirectedRequest,j7 as methodNotAllowed,E7 as loopDetected,N7 as locked,$7 as lengthRequired,D as isBanError,z7 as internal,S7 as insufficientStorage,P7 as illegal,W7 as httpVersionNotSupported,F7 as headerFieldsTooLarge,l7 as gatewayTimeout,R as formatError,K7 as forbidden,L7 as failedDependency,w7 as expectationFailed,Z7 as entityTooLarge,I as defaultFormatter,Yx as default,y as createRFC7807ZodValidationError,v as createRFC7807ValidationError,P as createRFC7807Hook,z as createRFC7807Formatter,T as createRFC7807ConstraintViolation,_ as createErrorResponse,J as createError,L as convertToBanError,X7 as conflict,Q7 as clientTimeout,F as badRequest,c7 as badImplementation,T7 as badGateway,B7 as badData,V as STATUS_CODES,q as RFC7807ValidationParamSchema,A as RFC7807ErrorDataSchema,H as RFC7807DetailsSchema,w as RFC7807ConstraintViolationSchema};
1
+ var Y={400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",421:"Misdirected Request",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required"};function N(x){if(typeof x!=="number"||isNaN(x))return 500;if(x<400||x>=600)return 500;return x}function G(x){let f=N(x.statusCode??500),y={status:f,message:x.message??Y[f],isBan:!0};if(x.data!==void 0)y.data=x.data;if(x.headers)y.headers={...x.headers};if(x.allow)y.allow=Array.isArray(x.allow)?[...x.allow]:[x.allow];if(x.cause){if(y.cause=x.cause,x.cause instanceof Error)y.causeStack=x.cause.stack}return Error.captureStackTrace(y,G),y}function D(x,f){return typeof x==="object"&&x!==null&&"isBan"in x&&x.isBan===!0&&(!f||x.status===f)}function L(x,f={}){if(D(x))return{status:f.statusCode??x.status,message:f.message??x.message,isBan:!0,data:f.data!==void 0?f.data:x.data,headers:{...x.headers,...f.headers},allow:f.allow?Array.isArray(f.allow)?[...f.allow]:[f.allow]:x.allow,cause:f.cause??x.cause,stack:x.stack};if(x instanceof Error)return G({...f,message:f.message??x.message,cause:x});return G({...f,message:f.message??(typeof x==="string"?x:"Unknown error"),cause:x})}function R(x,f,y={}){return f.format(x,y.headers,y.sanitize,y.includeStackTrace)}function _(x,f){let y=new Headers({"Content-Type":"application/json",...x.headers});if(x.allow?.length)y.set("Allow",x.allow.join(", "));let M=x.data&&typeof x.data==="object"&&"isDeveloperError"in x.data&&x.data.isDeveloperError===!0;return new Response(JSON.stringify(f),{status:x.status,headers:y})}function Z(x,f){if(!f.length)return x;if(Array.isArray(x))return x.map((y)=>Z(y,f));if(x!==null&&typeof x==="object")return Object.entries(x).reduce((y,[M,Q])=>{if(f.includes(M))return y;return y[M]=Z(Q,f),y},{});return x}var I={contentType:"application/json",format(x,f={},y=[],M=!1){let{status:Q,message:$,data:J}=x,X={statusCode:Q,error:Y[Q]||"Unknown Error"};if(typeof $==="string")X.message=$;let U=J&&typeof J==="object"&&"isDeveloperError"in J&&J.isDeveloperError===!0;if(M||U){if(x.stack)X.stack=x.stack;if(x.causeStack)X.causeStack=x.causeStack}if(J!==void 0)X.data=J;return Z(X,y)}};import{z as j}from"@hono/zod-openapi";var b=j.object({name:j.string().openapi({example:"username",description:"The field name that failed validation"}),reason:j.string().openapi({example:"String must contain at least 3 character(s)",description:"The reason for validation failure"})}),q=j.object({name:j.string().openapi({example:"email",description:"The field name that violated a constraint"}),reason:j.string().openapi({example:"Email already exists",description:"The reason for the constraint violation"}),resource:j.string().openapi({example:"user",description:"The resource type that contains the constraint"}),constraint:j.string().openapi({example:"unique",description:"The type of constraint that was violated"})}),P=j.object({"invalid-params":j.array(b).optional(),violations:j.array(q).optional()}),V=j.object({type:j.string().url().openapi({example:"https://api.example.com/problems/validation-error",description:"A URI reference that identifies the problem type"}),title:j.string().openapi({example:"Validation Failed",description:"A short, human-readable summary of the problem type"}),status:j.number().int().min(400).max(599).openapi({example:400,description:"The HTTP status code"}),detail:j.string().optional().openapi({example:"The request contains invalid fields",description:"A human-readable explanation specific to this occurrence of the problem"}),instance:j.string().url().optional().openapi({example:"urn:uuid:6b56944d-5e89-4b4d-9ca7-c1be3d1f0e3f",description:"A URI reference that identifies the specific occurrence of the problem"}),timestamp:j.string().datetime().optional().openapi({example:"2025-02-26T12:34:56.789Z",description:"When the error occurred"})}).merge(P);function v(x={}){let f=x.baseUrl||"https://api.example.com/problems";return{contentType:"application/problem+json",format(y){let M={type:`${f}/${y.status}`,title:Y[y.status]||"Unknown Error",status:y.status,detail:y.message,instance:`urn:uuid:${crypto.randomUUID()}`,timestamp:new Date().toISOString()};if(y.data?.["invalid-params"])return V.parse({...M,"invalid-params":y.data["invalid-params"]});if(y.data?.violations)return V.parse({...M,violations:y.data.violations});return V.parse(M)}}}function z(x){return{"invalid-params":b.array().parse(x)}}function B(x){return{"invalid-params":b.array().parse(x.errors.map((f)=>({name:f.path.join("."),reason:f.message})))}}function T(x,f,y,M="unique"){return{violations:q.array().parse([{name:x,reason:f,resource:y,constraint:M}])}}import{ZodError as C}from"zod";function K(x,f,y){if(typeof f==="string")return G({...y,statusCode:x,message:f});return G({...f,...y,statusCode:x})}function A(x,f){return K(400,x,f)}function o(x,f){return K(401,x,f)}function x7(x,f){return K(402,x,f)}function f7(x,f){return K(403,x,f)}function y7(x,f){return K(404,x,f)}function K7(x,f){return K(405,x,f)}function M7(x,f){return K(406,x,f)}function j7(x,f){return K(407,x,f)}function G7(x,f){return K(408,x,f)}function H7(x,f){return K(409,x,f)}function J7(x,f){return K(410,x,f)}function Q7(x,f){return K(411,x,f)}function X7(x,f){return K(412,x,f)}function Y7(x,f){return K(413,x,f)}function $7(x,f){return K(414,x,f)}function b7(x,f){return K(415,x,f)}function V7(x,f){return K(416,x,f)}function Z7(x,f){return K(417,x,f)}function q7(x,f){return K(418,x,f)}function w7(x,f){return K(421,x,f)}function B7(x,f){return K(422,x,f)}function k7(x,f){return K(423,x,f)}function N7(x,f){return K(424,x,f)}function L7(x,f){return K(425,x,f)}function R7(x,f){return K(426,x,f)}function _7(x,f){return K(428,x,f)}function I7(x,f){return K(429,x,f)}function P7(x,f){return K(431,x,f)}function A7(x,f){return K(451,x,f)}function H(x,f,y){if(typeof f==="string")return G({...y,statusCode:x,message:f});return G({...f,...y,statusCode:x})}function D7(x,f){return H(500,x,f)}function v7(x,f){return H(501,x,f)}function z7(x,f){return H(502,x,f)}function T7(x,f){return H(503,x,f)}function C7(x,f){return H(504,x,f)}function l7(x,f){return H(505,x,f)}function W7(x,f){return H(506,x,f)}function h7(x,f){return H(507,x,f)}function S7(x,f){return H(508,x,f)}function d7(x,f){return H(510,x,f)}function E7(x,f){return H(511,x,f)}function u7(x,f){let y=typeof x==="string"?{...f,message:x}:{...x,...f},M={isDeveloperError:!0,...y.data||{}};return G({...y,statusCode:500,data:M})}function F(x){return(f,y)=>{if(!f.success&&"error"in f&&f.error instanceof C){let M=B(f.error);throw A({message:x?.message||"Validation Error",data:M,formatter:x?.formatter,headers:x?.headers,sanitize:x?.sanitize,includeStackTrace:x?.includeStackTrace})}}}var l=F();var w={formatter:I,sanitize:[],includeStackTrace:!1,headers:{}};function k(x={}){let f={...w,...x,formatter:x.formatter?x.formatter:w.formatter,headers:{...w.headers,...x.headers},sanitize:[...w.sanitize,...x.sanitize||[]]};return async(y,M)=>{try{await M()}catch(Q){let $=f.formatter,J=L(Q,{formatter:$,headers:f.headers,sanitize:f.sanitize,includeStackTrace:f.includeStackTrace}),X=R(J,$,{headers:f.headers,sanitize:f.sanitize,includeStackTrace:f.includeStackTrace});return _(J,X)}}}var Jx=k;export{W7 as variantAlsoNegotiates,$7 as uriTooLong,R7 as upgradeRequired,b7 as unsupportedMediaType,o as unauthorized,I7 as tooManyRequests,L7 as tooEarly,q7 as teapot,T7 as serverUnavailable,l as rfc7807Hook,J7 as resourceGone,V7 as rangeNotSatisfiable,j7 as proxyAuthRequired,_7 as preconditionRequired,X7 as preconditionFailed,x7 as paymentRequired,v7 as notImplemented,y7 as notFound,d7 as notExtended,M7 as notAcceptable,E7 as networkAuthRequired,w7 as misdirectedRequest,K7 as methodNotAllowed,S7 as loopDetected,k7 as locked,Q7 as lengthRequired,D as isBanError,D7 as internal,h7 as insufficientStorage,A7 as illegal,l7 as httpVersionNotSupported,P7 as headerFieldsTooLarge,C7 as gatewayTimeout,R as formatError,f7 as forbidden,N7 as failedDependency,Z7 as expectationFailed,Y7 as entityTooLarge,I as defaultFormatter,Jx as default,B as createRFC7807ZodValidationError,z as createRFC7807ValidationError,F as createRFC7807Hook,v as createRFC7807Formatter,T as createRFC7807ConstraintViolation,_ as createErrorResponse,G as createError,L as convertToBanError,H7 as conflict,G7 as clientTimeout,A as badRequest,u7 as badImplementation,z7 as badGateway,B7 as badData,Y as STATUS_CODES,b as RFC7807ValidationParamSchema,P as RFC7807ErrorDataSchema,V as RFC7807DetailsSchema,q as RFC7807ConstraintViolationSchema};
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { BanError, DefaultErrorOutput, Headers } from "../../types";
6
6
  /**
7
- * Default JSON formatter maintaining backward compatibility
7
+ * Default JSON formatter with a clean, flat structure
8
8
  */
9
9
  export declare const defaultFormatter: {
10
10
  contentType: string;
@@ -6,27 +6,25 @@ import type { BanError } from "./error";
6
6
  import type { Headers } from "./common";
7
7
  /**
8
8
  * Default error output structure
9
+ *
10
+ * A simple, flat structure for error responses that follows common API practices
11
+ * while remaining minimal and extensible.
9
12
  */
10
13
  export interface DefaultErrorOutput {
11
14
  /** HTTP status code */
12
15
  statusCode: number;
13
- /** Formatted error payload */
14
- payload: {
15
- /** HTTP status code */
16
- statusCode: number;
17
- /** Error name from status code */
18
- error: string;
19
- /** Error message if provided */
20
- message?: string;
21
- /** Stack trace if enabled */
22
- stack?: string;
23
- /** Cause stack trace if available */
24
- causeStack?: string;
25
- /** Additional error data */
26
- data?: unknown;
27
- /** Any other properties */
28
- [key: string]: unknown;
29
- };
16
+ /** Error name from status code */
17
+ error: string;
18
+ /** Error message if provided */
19
+ message?: string;
20
+ /** Stack trace if enabled */
21
+ stack?: string;
22
+ /** Cause stack trace if available */
23
+ causeStack?: string;
24
+ /** Additional error data */
25
+ data?: unknown;
26
+ /** Any other properties */
27
+ [key: string]: unknown;
30
28
  }
31
29
  /**
32
30
  * Error formatter interface
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono-ban",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "HTTP-friendly error objects for Hono, inspired by Boom",
5
5
  "type": "module",
6
6
  "main": "dist/esm/index.js",