honestjs 0.1.11 → 0.1.12

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.
@@ -2,143 +2,30 @@ import { Hono } from 'hono';
2
2
  import type { HonestOptions, IApplicationContext, RouteInfo } from './interfaces';
3
3
  import type { Constructor } from './types';
4
4
  /**
5
- * Main application class for the Honest framework
6
- * Serves as the entry point for creating and configuring web applications
5
+ * Main application class for the Honest framework.
7
6
  *
8
- * Features:
9
- * - Module-based architecture for organizing application components
10
- * - Dependency injection container integration
11
- * - Plugin system for extending functionality
12
- * - Route management with versioning support
13
- * - Global error handling
14
- *
15
- * @example
16
- * ```ts
17
- * const { app } = await Application.create(AppModule, {
18
- * routing: { prefix: '/api', version: 1 },
19
- * plugins: [new LoggerPlugin()]
20
- * });
21
- * ```
7
+ * All per-app runtime state (routes, global components, DI container) is
8
+ * instance-based. Static decorator metadata lives in MetadataRegistry and
9
+ * is shared across all Application instances in the same process.
22
10
  */
23
11
  export declare class Application {
24
12
  private readonly hono;
25
13
  private readonly container;
26
14
  private readonly context;
15
+ private readonly routeRegistry;
16
+ private readonly componentManager;
27
17
  private readonly routeManager;
28
18
  private readonly options;
29
- /**
30
- * Creates a new Application instance with the specified configuration
31
- * @param options - Configuration options for the application
32
- * @param options.routing - Route configuration (prefix, versioning)
33
- * @param options.plugins - Array of plugins to extend functionality
34
- * @param options.container - Custom dependency injection container
35
- * @param options.hono - Hono-specific configuration options
36
- * @throws {Error} If options are invalid or initialization fails
37
- */
38
19
  constructor(options?: HonestOptions);
39
- /**
40
- * Sets up global components from application options
41
- * Initializes the component manager and registers global middleware,
42
- * guards, pipes, and filters
43
- * @private
44
- */
45
- private setupComponents;
46
- /**
47
- * Sets up global error handlers for the application
48
- * Configures handlers for 404 Not Found and general error cases
49
- * @private
50
- */
51
20
  private setupErrorHandlers;
52
- /**
53
- * Resolves a plugin from either a constructor or instance
54
- * @param pluginType - Plugin constructor or instance
55
- * @returns Resolved plugin instance
56
- * @private
57
- * @throws {Error} If plugin instantiation fails
58
- */
59
21
  private resolvePlugin;
60
- /**
61
- * Normalizes a plugin entry to a resolved plugin with pre/post processor arrays.
62
- * @param entry - Plugin entry (plain plugin or object with plugin and processors)
63
- * @returns Normalized entry with plugin instance and processor arrays
64
- * @private
65
- */
66
22
  private normalizePluginEntry;
67
- /**
68
- * Registers a module with the application
69
- * Processes the module's metadata and registers its controllers
70
- *
71
- * @param moduleClass - The module class to register
72
- * @returns The application instance for method chaining
73
- * @throws {Error} If module registration fails
74
- *
75
- * @example
76
- * ```ts
77
- * const app = new Application();
78
- * await app.register(UsersModule)
79
- * .register(AuthModule);
80
- * ```
81
- */
82
23
  register(moduleClass: Constructor): Promise<Application>;
83
- /**
84
- * Creates and initializes a new application with a root module
85
- *
86
- * Process:
87
- * 1. Creates application instance with provided options
88
- * 2. Initializes and runs plugin lifecycle hooks
89
- * 3. Registers the root module
90
- * 4. Returns both the application and Hono instances
91
- *
92
- * @param rootModule - The root module class for the application
93
- * @param options - Application configuration options
94
- * @returns Object containing the application and Hono instances
95
- * @throws {Error} If application creation or module registration fails
96
- *
97
- * @example
98
- * ```ts
99
- * const { app, hono } = await Application.create(AppModule, {
100
- * routing: { prefix: '/api' }
101
- * });
102
- * ```
103
- */
104
24
  static create(rootModule: Constructor, options?: HonestOptions): Promise<{
105
25
  app: Application;
106
26
  hono: Hono;
107
27
  }>;
108
- /**
109
- * Gets the underlying Hono instance for direct access
110
- * Use this method when you need to access Hono-specific features
111
- *
112
- * @returns The Hono application instance
113
- * @example
114
- * ```ts
115
- * const hono = app.getApp();
116
- * hono.use(someHonoMiddleware());
117
- * ```
118
- */
119
28
  getApp(): Hono;
120
- /**
121
- * Gets the app-level registry (context) where your app can publish and read pipeline data by key.
122
- * Use namespaced keys (e.g. 'app.config', 'openapi.spec') and document contracts in your app.
123
- *
124
- * @returns The application context instance
125
- * @example
126
- * ```ts
127
- * app.getContext().set('app.config', { env: process.env.NODE_ENV })
128
- * const config = app.getContext().get<{ env: string }>('app.config')
129
- * ```
130
- */
131
29
  getContext(): IApplicationContext;
132
- /**
133
- * Gets information about all registered routes in the application
134
- * Useful for documentation and debugging purposes
135
- *
136
- * @returns Array of route information objects (read-only)
137
- * @example
138
- * ```ts
139
- * const routes = app.getRoutes();
140
- * console.log(routes.map(r => r.path));
141
- * ```
142
- */
143
30
  getRoutes(): ReadonlyArray<RouteInfo>;
144
31
  }
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
@@ -11,14 +11,19 @@ export declare class Container implements DiContainer {
11
11
  /**
12
12
  * Resolves a class instance, creating it if necessary and injecting its dependencies
13
13
  * @param target - The class constructor to resolve
14
- * @param resolving - A set of classes currently being resolved, for circular dependency detection
15
14
  * @returns An instance of the target class
16
15
  */
17
- resolve<T>(target: Constructor<T>, resolving?: Set<Constructor>): T;
16
+ resolve<T>(target: Constructor<T>): T;
17
+ /**
18
+ * Internal recursive resolver with circular dependency tracking
19
+ */
20
+ private resolveWithTracking;
18
21
  /**
19
22
  * Registers a pre-created instance for a class
20
23
  * @param target - The class constructor to register
21
24
  * @param instance - The instance to register
22
25
  */
23
26
  register<T>(target: Constructor<T>, instance: T): void;
27
+ has<T>(target: Constructor<T>): boolean;
28
+ clear(): void;
24
29
  }
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
- import"reflect-metadata";import{Hono as t}from"hono";class M{store=new Map;get($){return this.store.get($)}set($,_){this.store.set($,_)}has($){return this.store.has($)}delete($){return this.store.delete($)}keys(){return this.store.keys()}}class C{instances=new Map;resolve($,_=new Set){if(this.instances.has($))return this.instances.get($);if(_.has($))throw Error(`Circular dependency detected: ${[..._.keys(),$].map((Q)=>Q.name).join(" -> ")}`);_.add($);let W=Reflect.getMetadata("design:paramtypes",$)||[];if($.length>0&&W.length===0)throw Error(`Cannot resolve dependencies for ${$.name}: constructor metadata is missing. Ensure 'reflect-metadata' is imported and 'emitDecoratorMetadata' is enabled.`);let Y=W.map((Q,B)=>{if(!Q||Q===Object||Q===Array||Q===Function)throw Error(`Cannot resolve dependency at index ${B} of ${$.name}. Use concrete class types for constructor dependencies.`);return this.resolve(Q,new Set(_))}),q=new $(...Y);return this.instances.set($,q),q}register($,_){this.instances.set($,_)}}import{HTTPException as r}from"hono/http-exception";function R($,_,W){let Y=new Date().toISOString(),q=_.get("requestId"),Q=_.req.path;if($ instanceof r)return{response:{status:W?.status||$.status,message:W?.title||$.message,timestamp:Y,path:Q,requestId:q,code:W?.code,details:W?.additionalDetails,...W?.detail&&{detail:W.detail}},status:W?.status||$.status};if($.statusCode||$.status){let L=$.statusCode||$.status,A=W?.status||L;return{response:{status:A,message:W?.title||$.message,timestamp:Y,path:Q,requestId:q,code:W?.code||$.name,details:W?.additionalDetails,...W?.detail&&{detail:W.detail}},status:A}}let B=W?.status||500;return{response:{status:B,message:W?.title||$.message,timestamp:Y,path:Q,requestId:q,code:W?.code||$.name,details:W?.additionalDetails||{stack:$.stack},...W?.detail&&{detail:W.detail}},status:B}}class X{static routes=new Map;static controllers=new Map;static controllerOptions=new Map;static services=new Set;static modules=new Map;static parameters=new Map;static contextIndices=new Map;static global=new Map([["middleware",new Set],["guard",new Set],["pipe",new Set],["filter",new Set]]);static controller=new Map([["middleware",new Map],["guard",new Map],["pipe",new Map],["filter",new Map]]);static handler=new Map([["middleware",new Map],["guard",new Map],["pipe",new Map],["filter",new Map]]);static getRoutes($){return this.routes.get($)||[]}static setRoutes($,_){this.routes.set($,_)}static addRoute($,_){if(!this.routes.has($))this.routes.set($,[]);this.routes.get($).push(_)}static getControllerPath($){return this.controllers.get($)||""}static hasController($){return this.controllers.has($)}static setControllerPath($,_){this.controllers.set($,_)}static getControllerOptions($){return this.controllerOptions.get($)||{}}static setControllerOptions($,_){this.controllerOptions.set($,_)}static isService($){return this.services.has($)}static addService($){this.services.add($)}static getAllServices(){return this.services}static getModuleOptions($){return this.modules.get($)}static setModuleOptions($,_){this.modules.set($,_)}static getParameters($){return this.parameters.get($)||new Map}static setParameterMap($,_){this.parameters.set($,_)}static getContextIndices($){return this.contextIndices.get($)||new Map}static setContextIndices($,_){this.contextIndices.set($,_)}static registerGlobal($,_){this.global.get($).add(_)}static getGlobal($){return this.global.get($)}static registerController($,_,W){let Y=this.controller.get($);if(!Y.has(_))Y.set(_,[]);Y.get(_).push(W)}static getController($,_){return this.controller.get($).get(_)||[]}static registerHandler($,_,W){let Y=this.handler.get($);if(!Y.has(_))Y.set(_,[]);Y.get(_).push(W)}static getHandler($,_){return this.handler.get($).get(_)||[]}static clear(){this.routes.clear(),this.controllers.clear(),this.controllerOptions.clear(),this.services.clear(),this.modules.clear(),this.parameters.clear(),this.contextIndices.clear();for(let $ of this.global.values())$.clear();for(let $ of this.controller.values())$.clear();for(let $ of this.handler.values())$.clear()}}class T{static routes=[];static registerRoute($){if(!$)throw Error("Route info is required");if(!$.controller)throw Error("Route controller is required");if(!$.handler)throw Error("Route handler is required");if(!$.method)throw Error("Route method is required");if(!$.fullPath)throw Error("Route fullPath is required");if(this.routes.some((W)=>W.fullPath===$.fullPath&&W.method.toUpperCase()===$.method.toUpperCase()))throw Error(`Duplicate route detected: ${$.method.toUpperCase()} ${$.fullPath} (${String($.controller)}.${String($.handler)})`);this.routes.push($)}static getRoutes(){return this.routes}static getRoutesByController($){return this.routes.filter((_)=>_.controller===$)}static getRoutesByMethod($){return this.routes.filter((_)=>_.method.toUpperCase()===$.toUpperCase())}static getRoutesByPath($){return this.routes.filter((_)=>$.test(_.fullPath))}static clear(){this.routes.length=0}}function H($){return(_="",W={})=>{return(Y,q,Q)=>{let B=Y.constructor;X.addRoute(B,{path:_,method:$,handlerName:q,parameterMetadata:[],version:W.version,prefix:W.prefix})}}}function E($,_){let W=(Y,q)=>{if(Y===void 0)return q;return q.get(Y)};return(Y)=>{return(q,Q,B)=>{let Z=q.constructor;if(!X.getParameters(Z).size)X.setParameterMap(Z,new Map);let L=X.getParameters(Z);if(!L.has(Q))L.set(Q,[]);let z=Reflect.getMetadata("design:paramtypes",q,Q)?.[B];if(L.get(Q).push({index:B,name:$,data:Y,factory:_||W,metatype:z}),$==="context"){if(!X.getContextIndices(Z).size)X.setContextIndices(Z,new Map);X.getContextIndices(Z).set(Q,B)}}}}class x{static handle(){return async($,_)=>{let{response:W,status:Y}=R($,_);return _.json(W,Y)}}}class I{static handle(){return async($)=>{return $.json({message:`Not Found - ${$.req.path}`},404)}}}var N$=($)=>typeof $>"u",N=($)=>$===null||typeof $>"u",O=($)=>$!==null&&typeof $==="object",b$=($)=>{if(!O($))return!1;let _=Object.getPrototypeOf($);if(_===null)return!0;let W=Object.prototype.hasOwnProperty.call(_,"constructor")&&_.constructor;return typeof W==="function"&&W instanceof W&&Function.prototype.toString.call(W)===Function.prototype.toString.call(Object)},i=($)=>typeof $==="function",v=($)=>typeof $==="string",w$=($)=>typeof $==="number",P$=($)=>$.length===0,K$=($)=>typeof $==="symbol",R$=($)=>typeof $==="string"?$.charAt(0)!=="/"?"/"+$:$:"",y=($)=>$?$.startsWith("/")?("/"+$.replace(/\/+$/,"")).replace(/\/+/g,"/"):"/"+$.replace(/\/+$/,""):"/",f$=($)=>$.endsWith("/")?$.slice(0,-1):$,c=($)=>{return i($)&&!N($.prototype)&&!i($.prototype)&&Object.getOwnPropertyNames($.prototype).length>=1};class J{static container;static init($){this.container=$}static setupGlobalComponents($){let _=$.components||{};if(_.middleware)this.registerGlobal("middleware",..._.middleware);if(_.guards)this.registerGlobal("guard",..._.guards);if(_.pipes)this.registerGlobal("pipe",..._.pipes);if(_.filters)this.registerGlobal("filter",..._.filters)}static registerGlobal($,..._){_.forEach((W)=>{X.registerGlobal($,W)})}static registerController($,_,...W){W.forEach((Y)=>{X.registerController($,_,Y)})}static registerHandler($,_,W,...Y){let q=`${_.name}:${String(W)}`;Y.forEach((Q)=>{X.registerHandler($,q,Q)})}static getComponents($,_,W){let Y=`${_.name}:${String(W)}`,q=X.getHandler($,Y),Q=X.getController($,_);return[...Array.from(X.getGlobal($)),...Q,...q]}static resolveMiddleware($){return $.map((_)=>{if(O(_)&&"use"in _)return _.use.bind(_);let W=this.container.resolve(_);return W.use.bind(W)})}static getHandlerMiddleware($,_){let W=this.getComponents("middleware",$,_);return this.resolveMiddleware(W)}static getGlobalMiddleware(){let $=Array.from(X.getGlobal("middleware"));return this.resolveMiddleware($)}static resolveGuards($){return $.map((_)=>{if(O(_)&&"canActivate"in _)return _;return this.container.resolve(_)})}static getHandlerGuards($,_){let W=this.getComponents("guard",$,_);return this.resolveGuards(W)}static resolvePipes($){return $.map((_)=>{if(O(_)&&"transform"in _)return _;return this.container.resolve(_)})}static getHandlerPipes($,_){let W=this.getComponents("pipe",$,_);return this.resolvePipes(W)}static async executePipes($,_,W){let Y=$;for(let q of W)Y=await q.transform(Y,_);return Y}static async handleException($,_){let W=_.get("controllerClass"),Y=_.get("handlerName");if(W&&Y){let Z=X.getHandler("filter",`${W.name}:${Y}`);if(Z.length>0){let L=await this.executeFilters(Z,$,_);if(L)return L}}if(W){let Z=X.getController("filter",W);if(Z.length>0){let L=await this.executeFilters(Z,$,_);if(L)return L}}let q=Array.from(X.getGlobal("filter"));if(q.length>0){let Z=await this.executeFilters(q,$,_);if(Z)return Z}let{response:Q,status:B}=R($,_);return _.json(Q,B)}static async executeFilters($,_,W){for(let Y of $){let q;if(O(Y)&&"catch"in Y)q=Y;else q=this.container.resolve(Y);try{let Q=await q.catch(_,W);if(Q!==void 0)return Q}catch(Q){console.error("Error in exception filter:",Q)}}return}static async registerModule($,_){let W=X.getModuleOptions($);if(!W)throw Error(`Module ${$.name} is not properly decorated with @Module()`);let Y=[];if(W.imports&&W.imports.length>0)for(let q of W.imports){let Q=await this.registerModule(q,_);Y.push(...Q)}if(W.services&&W.services.length>0)for(let q of W.services)_.resolve(q);if(W.controllers&&W.controllers.length>0)Y.push(...W.controllers);return Y}}import{HTTPException as o}from"hono/http-exception";var h=Symbol("VERSION_NEUTRAL");class g{hono;container;globalPrefix;globalVersion;constructor($,_,W={}){this.hono=$,this.container=_,this.globalPrefix=W.prefix!==void 0?this.normalizePath(W.prefix):void 0,this.globalVersion=W.version,this.applyGlobalMiddleware()}applyGlobalMiddleware(){let $=J.getGlobalMiddleware();for(let _ of $)this.hono.use("*",_)}normalizePath($){if(v($))return y($);return $?`/${$}`:""}registerRouteHandler($,_,W,Y){if(W.length>0)this.hono.on($.toUpperCase(),_,...W,Y);else this.hono.on($.toUpperCase(),_,Y)}buildRoutePath($,_,W,Y){return y(`${$}${_}${W}${Y}`)}formatVersionSegment($){if(N($))return"";return $===h?"":`/v${String($)}`}async registerController($){if(!X.hasController($))throw Error(`Controller ${$.name} is not decorated with @Controller()`);let _=X.getControllerPath($)||"",W=X.getControllerOptions($)||{},Y=X.getRoutes($)||[],q=X.getParameters($)||new Map,Q=X.getContextIndices($)||new Map,B=this.normalizePath(_),Z=this.container.resolve($),L=W.prefix!==void 0?W.prefix:this.globalPrefix,A=W.version!==void 0?W.version:this.globalVersion;if(Y.length===0)throw Error(`Controller ${$.name} has no route handlers. Add HTTP method decorators like @Get()`);for(let z of Y){let{path:j,method:V,handlerName:f,version:b,prefix:w}=z,P=w!==void 0?w:L,S=!N(P)?this.normalizePath(P):"",G=b!==void 0?b:A,k=this.normalizePath(j);if(N(G)){this.registerRoute(Z,z,q,Q,$,S,"",B,k,V);continue}if(G===h){this.registerRoute(Z,z,q,Q,$,S,"",B,k,V),this.registerRoute(Z,z,q,Q,$,S,"/:version{v[0-9]+}",B,k,V);continue}if(Array.isArray(G)){for(let D of G){let F=this.formatVersionSegment(D);this.registerRoute(Z,z,q,Q,$,S,F,B,k,V)}continue}let K=this.formatVersionSegment(G);this.registerRoute(Z,z,q,Q,$,S,K,B,k,V)}}registerRoute($,_,W,Y,q,Q,B,Z,L,A){let{handlerName:z}=_,j=this.buildRoutePath(Q,B,Z,L),V=$[z].bind($),f=W.get(z)||[],b=Y.get(z),w=J.getHandlerMiddleware(q,z),P=J.getHandlerPipes(q,z);T.registerRoute({controller:q.name,handler:z,method:A,prefix:Q,version:B,route:Z,path:L,fullPath:j,parameters:f});let S=async(G)=>{try{G.set("controllerClass",q),G.set("handlerName",String(z));let k=J.getHandlerGuards(q,z);for(let F of k)if(!await F.canActivate(G))throw new o(403,{message:`Forbidden by ${F.constructor?.name||"UnknownGuard"} at ${q.name}.${String(z)}`});let K=Array(V.length);for(let F of f){if(typeof F.factory!=="function")throw Error(`Invalid parameter decorator metadata for ${q.name}.${String(z)}`);let d=F.factory(F.data,G),a=await J.executePipes(d,{type:F.name,metatype:F.metatype,data:F.data},P);K[F.index]=a}let D=await V(...K);if(b!==void 0)return D;if(D instanceof Response)return D;if(N(D))return G.json(null);if(v(D))return G.text(D);return G.json(D)}catch(k){return J.handleException(k,G)}};this.registerRouteHandler(A,j,w,S)}}class p{hono;container;context;routeManager;options;constructor($={}){if(this.options=O($)?$:{},T.clear(),this.hono=new t(this.options.hono),this.container=this.options.container||new C,this.context=new M,this.setupComponents(),this.setupErrorHandlers(),this.routeManager=new g(this.hono,this.container,{prefix:this.options.routing?.prefix,version:this.options.routing?.version}),this.options.deprecations?.printPreV1Warning)console.warn("[HonestJS] Pre-v1 warning: APIs may change before 1.0.0.")}setupComponents(){J.init(this.container),J.setupGlobalComponents(this.options)}setupErrorHandlers(){this.hono.notFound(this.options.notFound||I.handle()),this.hono.onError(this.options.onError||x.handle())}resolvePlugin($){if(c($))return new $;return $}normalizePluginEntry($){if($&&typeof $==="object"&&"plugin"in $){let _=$;return{plugin:this.resolvePlugin(_.plugin),preProcessors:_.preProcessors??[],postProcessors:_.postProcessors??[]}}return{plugin:this.resolvePlugin($),preProcessors:[],postProcessors:[]}}async register($){let _=await J.registerModule($,this.container);for(let W of _)await this.routeManager.registerController(W);return this}static async create($,_={}){let W=new p(_),Y=(_.plugins||[]).map((A)=>W.normalizePluginEntry(A)),q=W.getContext(),Q=_.debug,B=Q===!0||typeof Q==="object"&&Q.plugins,Z=Q===!0||typeof Q==="object"&&Q.routes;if(B&&Y.length>0)console.info("[HonestJS] Plugin order:",Y.map(({plugin:A})=>A.constructor?.name||"AnonymousPlugin").join(" -> "));for(let{plugin:A,preProcessors:z}of Y){for(let j of z)await j(W,W.hono,q);if(A.beforeModulesRegistered)await A.beforeModulesRegistered(W,W.hono)}await W.register($);let L=W.getRoutes();if(_.strict?.requireRoutes&&L.length===0)throw Error("Strict mode: no routes were registered. Check your module/controller decorators.");if(Z)console.info("[HonestJS] Registered routes:",L.map((A)=>`${A.method.toUpperCase()} ${A.fullPath}`));for(let{plugin:A,postProcessors:z}of Y){if(A.afterModulesRegistered)await A.afterModulesRegistered(W,W.hono);for(let j of z)await j(W,W.hono,q)}return{app:W,hono:W.getApp()}}getApp(){return this.hono}getContext(){return this.context}getRoutes(){return T.getRoutes()}}import{html as U,raw as u}from"hono/html";var e={type:"website",locale:"en_US"},m=($)=>{if(!$)return"";return Object.entries($).map(([_,W])=>{if(typeof W==="boolean")return W?_:"";let Y=String(W).replace(/"/g,"&quot;");return`${_}="${Y}"`}).filter(Boolean).join(" ")},X_=($)=>{let _={...e,...$};return U`
1
+ import"reflect-metadata";import{Hono as $$}from"hono";class C{store=new Map;get($){return this.store.get($)}set($,_){this.store.set($,_)}has($){return this.store.has($)}delete($){return this.store.delete($)}keys(){return this.store.keys()}}class Z{static routes=new Map;static controllers=new Map;static controllerOptions=new Map;static services=new Set;static modules=new Map;static parameters=new Map;static contextIndices=new Map;static controller=new Map([["middleware",new Map],["guard",new Map],["pipe",new Map],["filter",new Map]]);static handler=new Map([["middleware",new Map],["guard",new Map],["pipe",new Map],["filter",new Map]]);static getRoutes($){return this.routes.get($)||[]}static setRoutes($,_){this.routes.set($,_)}static addRoute($,_){if(!this.routes.has($))this.routes.set($,[]);this.routes.get($).push(_)}static getControllerPath($){return this.controllers.get($)||""}static hasController($){return this.controllers.has($)}static setControllerPath($,_){this.controllers.set($,_)}static getControllerOptions($){return this.controllerOptions.get($)||{}}static setControllerOptions($,_){this.controllerOptions.set($,_)}static isService($){return this.services.has($)}static addService($){this.services.add($)}static getAllServices(){return this.services}static getModuleOptions($){return this.modules.get($)}static setModuleOptions($,_){this.modules.set($,_)}static getParameters($){return this.parameters.get($)||new Map}static setParameterMap($,_){this.parameters.set($,_)}static getContextIndices($){return this.contextIndices.get($)||new Map}static setContextIndices($,_){this.contextIndices.set($,_)}static registerController($,_,W){let Y=this.controller.get($);if(!Y.has(_))Y.set(_,[]);Y.get(_).push(W)}static getController($,_){return this.controller.get($).get(_)||[]}static registerHandler($,_,W){let Y=this.handler.get($);if(!Y.has(_))Y.set(_,[]);Y.get(_).push(W)}static getHandler($,_){return this.handler.get($).get(_)||[]}static clear(){this.routes.clear(),this.controllers.clear(),this.controllerOptions.clear(),this.services.clear(),this.modules.clear(),this.parameters.clear(),this.contextIndices.clear();for(let $ of this.controller.values())$.clear();for(let $ of this.handler.values())$.clear()}}class M{routes=[];registerRoute($){if(!$)throw Error("Route info is required");if(!$.controller)throw Error("Route controller is required");if(!$.handler)throw Error("Route handler is required");if(!$.method)throw Error("Route method is required");if(!$.fullPath)throw Error("Route fullPath is required");if(this.routes.some((W)=>W.fullPath===$.fullPath&&W.method.toUpperCase()===$.method.toUpperCase()))throw Error(`Duplicate route detected: ${$.method.toUpperCase()} ${$.fullPath} (${String($.controller)}.${String($.handler)})`);this.routes.push($)}getRoutes(){return this.routes}getRoutesByController($){return this.routes.filter((_)=>_.controller===$)}getRoutesByMethod($){return this.routes.filter((_)=>_.method.toUpperCase()===$.toUpperCase())}getRoutesByPath($){return this.routes.filter((_)=>$.test(_.fullPath))}clear(){this.routes.length=0}}class f{instances=new Map;resolve($){return this.resolveWithTracking($,new Set)}resolveWithTracking($,_){if(this.instances.has($))return this.instances.get($);if(_.has($))throw Error(`Circular dependency detected: ${[..._.keys(),$].map((X)=>X.name).join(" -> ")}`);_.add($);let W=Reflect.getMetadata("design:paramtypes",$)||[];if($.length>0&&W.length===0){if(!Z.isService($))throw Error(`Cannot resolve ${$.name}: it is not decorated with @Service(). Did you forget to add @Service() to the class?`);throw Error(`Cannot resolve dependencies for ${$.name}: constructor metadata is missing. Ensure 'reflect-metadata' is imported and 'emitDecoratorMetadata' is enabled.`)}let Y=W.map((X,B)=>{if(!X||X===Object||X===Array||X===Function)throw Error(`Cannot resolve dependency at index ${B} of ${$.name}. Use concrete class types for constructor dependencies.`);return this.resolveWithTracking(X,new Set(_))}),Q=new $(...Y);return this.instances.set($,Q),Q}register($,_){this.instances.set($,_)}has($){return this.instances.has($)}clear(){this.instances.clear()}}import{HTTPException as t}from"hono/http-exception";function b($,_,W){let Y=new Date().toISOString(),Q=_.get("requestId"),X=_.req.path;if($ instanceof t)return{response:{status:W?.status||$.status,message:W?.title||$.message,timestamp:Y,path:X,requestId:Q,code:W?.code,details:W?.additionalDetails,...W?.detail&&{detail:W.detail}},status:W?.status||$.status};if($.statusCode||$.status){let q=$.statusCode||$.status,z=W?.status||q;return{response:{status:z,message:W?.title||$.message,timestamp:Y,path:X,requestId:Q,code:W?.code||$.name,details:W?.additionalDetails,...W?.detail&&{detail:W.detail}},status:z}}let B=W?.status||500;return{response:{status:B,message:W?.title||$.message,timestamp:Y,path:X,requestId:Q,code:W?.code||$.name,details:W?.additionalDetails||{stack:$.stack},...W?.detail&&{detail:W.detail}},status:B}}function k($){return(_="",W={})=>{return(Y,Q,X)=>{let B=Y.constructor;Z.addRoute(B,{path:_,method:$,handlerName:Q,version:W.version,prefix:W.prefix})}}}function j($,_){let W=(Y,Q)=>{if(Y===void 0)return Q;return Q.get(Y)};return(Y)=>{return(Q,X,B)=>{let J=Q.constructor;if(!Z.getParameters(J).size)Z.setParameterMap(J,new Map);let q=Z.getParameters(J);if(!q.has(X))q.set(X,[]);let U=Reflect.getMetadata("design:paramtypes",Q,X)?.[B];if(q.get(X).push({index:B,name:$,data:Y,factory:_||W,metatype:U}),$==="context"){if(!Z.getContextIndices(J).size)Z.setContextIndices(J,new Map);Z.getContextIndices(J).set(X,B)}}}}class x{static handle(){return async($,_)=>{let{response:W,status:Y}=b($,_);return _.json(W,Y)}}}class I{static handle(){return async($)=>{return $.json({message:`Not Found - ${$.req.path}`},404)}}}var K$=($)=>typeof $>"u",T=($)=>$===null||typeof $>"u",O=($)=>$!==null&&typeof $==="object",w$=($)=>{if(!O($))return!1;let _=Object.getPrototypeOf($);if(_===null)return!0;let W=Object.prototype.hasOwnProperty.call(_,"constructor")&&_.constructor;return typeof W==="function"&&W instanceof W&&Function.prototype.toString.call(W)===Function.prototype.toString.call(Object)},p=($)=>typeof $==="function",v=($)=>typeof $==="string",R$=($)=>typeof $==="number",C$=($)=>$.length===0,M$=($)=>typeof $==="symbol",f$=($)=>typeof $==="string"?$.charAt(0)!=="/"?"/"+$:$:"",y=($)=>$?$.startsWith("/")?("/"+$.replace(/\/+$/,"")).replace(/\/+/g,"/"):"/"+$.replace(/\/+$/,""):"/",x$=($)=>$.endsWith("/")?$.slice(0,-1):$,s=($)=>{return p($)&&!T($.prototype)&&!p($.prototype)&&Object.getOwnPropertyNames($.prototype).length>=1};class g{container;globalComponents=new Map([["middleware",new Set],["guard",new Set],["pipe",new Set],["filter",new Set]]);constructor($){this.container=$}setupGlobalComponents($){let _=$.components||{};if(_.middleware)this.registerGlobal("middleware",..._.middleware);if(_.guards)this.registerGlobal("guard",..._.guards);if(_.pipes)this.registerGlobal("pipe",..._.pipes);if(_.filters)this.registerGlobal("filter",..._.filters)}registerGlobal($,..._){_.forEach((W)=>{this.globalComponents.get($).add(W)})}getGlobal($){return this.globalComponents.get($)}getComponents($,_,W){let Y=`${_.name}:${String(W)}`,Q=Z.getHandler($,Y),X=Z.getController($,_);return[...Array.from(this.globalComponents.get($)||[]),...X,...Q]}resolveMiddleware($){return $.map((_)=>{if(O(_)&&"use"in _)return _.use.bind(_);let W=this.container.resolve(_);return W.use.bind(W)})}getHandlerMiddleware($,_){let W=this.getComponents("middleware",$,_);return this.resolveMiddleware(W)}getGlobalMiddleware(){let $=Array.from(this.globalComponents.get("middleware")||[]);return this.resolveMiddleware($)}resolveGuards($){return $.map((_)=>{if(O(_)&&"canActivate"in _)return _;return this.container.resolve(_)})}getHandlerGuards($,_){let W=this.getComponents("guard",$,_);return this.resolveGuards(W)}resolvePipes($){return $.map((_)=>{if(O(_)&&"transform"in _)return _;return this.container.resolve(_)})}getHandlerPipes($,_){let W=this.getComponents("pipe",$,_);return this.resolvePipes(W)}async executePipes($,_,W){let Y=$;for(let Q of W)Y=await Q.transform(Y,_);return Y}async handleException($,_){let W=_.get("__honest_controllerClass"),Y=_.get("__honest_handlerName");if(W&&Y){let J=Z.getHandler("filter",`${W.name}:${Y}`);if(J.length>0){let q=await this.executeFilters(J,$,_);if(q)return q}}if(W){let J=Z.getController("filter",W);if(J.length>0){let q=await this.executeFilters(J,$,_);if(q)return q}}let Q=Array.from(this.globalComponents.get("filter")||[]);if(Q.length>0){let J=await this.executeFilters(Q,$,_);if(J)return J}let{response:X,status:B}=b($,_);return _.json(X,B)}async executeFilters($,_,W){for(let Y of $){let Q;if(O(Y)&&"catch"in Y)Q=Y;else Q=this.container.resolve(Y);try{let X=await Q.catch(_,W);if(X!==void 0)return X}catch(X){let B=Q.constructor?.name||"UnknownFilter";console.error(`Error in exception filter ${B}:`,X);let{response:J,status:q}=b(X,W);return W.json(J,q)}}return}async registerModule($,_=new Set){if(_.has($))return[];_.add($);let W=Z.getModuleOptions($);if(!W)throw Error(`Module ${$.name} is not properly decorated with @Module()`);let Y=[];if(W.imports&&W.imports.length>0)for(let Q of W.imports){let X=await this.registerModule(Q,_);Y.push(...X)}if(W.services&&W.services.length>0)for(let Q of W.services)this.container.resolve(Q);if(W.controllers&&W.controllers.length>0)Y.push(...W.controllers);return Y}}import{HTTPException as e}from"hono/http-exception";var h=Symbol("VERSION_NEUTRAL");class m{hono;container;routeRegistry;componentManager;globalPrefix;globalVersion;constructor($,_,W,Y,Q={}){this.hono=$,this.container=_,this.routeRegistry=W,this.componentManager=Y,this.globalPrefix=Q.prefix!==void 0?this.normalizePath(Q.prefix):void 0,this.globalVersion=Q.version,this.applyGlobalMiddleware()}applyGlobalMiddleware(){let $=this.componentManager.getGlobalMiddleware();for(let _ of $)this.hono.use("*",_)}normalizePath($){if(!v($))throw Error(`Invalid path: expected a string but received ${typeof $}. Check your @Controller() and route decorator arguments.`);return y($)}registerRouteHandler($,_,W,Y){if(W.length>0)this.hono.on($.toUpperCase(),_,...W,Y);else this.hono.on($.toUpperCase(),_,Y)}buildRoutePath($,_,W,Y){return y(`${$}${_}${W}${Y}`)}formatVersionSegment($){if(T($))return"";return $===h?"":`/v${String($)}`}async registerController($){if(!Z.hasController($))throw Error(`Controller ${$.name} is not decorated with @Controller()`);let _=Z.getControllerPath($)||"",W=Z.getControllerOptions($)||{},Y=Z.getRoutes($)||[],Q=Z.getParameters($)||new Map,X=Z.getContextIndices($)||new Map,B=this.normalizePath(_),J=this.container.resolve($),q=W.prefix!==void 0?W.prefix:this.globalPrefix,z=W.version!==void 0?W.version:this.globalVersion;if(Y.length===0)throw Error(`Controller ${$.name} has no route handlers. Add HTTP method decorators like @Get()`);for(let U of Y){let{path:E,method:V,version:H,prefix:K}=U,w=K!==void 0?K:q,D=!T(w)?this.normalizePath(w):"",A=H!==void 0?H:z,S=this.normalizePath(E);if(T(A)){this.registerRoute(J,U,Q,X,$,D,"",B,S,V);continue}if(A===h){this.registerRoute(J,U,Q,X,$,D,"",B,S,V),this.registerRoute(J,U,Q,X,$,D,"/:version{v[0-9]+}",B,S,V);continue}if(Array.isArray(A)){for(let P of A){let R=this.formatVersionSegment(P);this.registerRoute(J,U,Q,X,$,D,R,B,S,V)}continue}let F=this.formatVersionSegment(A);this.registerRoute(J,U,Q,X,$,D,F,B,S,V)}}registerRoute($,_,W,Y,Q,X,B,J,q,z){let{handlerName:U}=_,E=this.buildRoutePath(X,B,J,q),V=$[U].bind($),H=W.get(U)||[],K=Y.get(U),w=this.componentManager.getHandlerMiddleware(Q,U),D=this.componentManager.getHandlerPipes(Q,U);this.routeRegistry.registerRoute({controller:Q.name,handler:U,method:z,prefix:X,version:B,route:J,path:q,fullPath:E,parameters:H});let A=this.componentManager,S=async(F)=>{try{F.set("__honest_controllerClass",Q),F.set("__honest_handlerName",String(U));let P=A.getHandlerGuards(Q,U);for(let G of P)if(!await G.canActivate(F))throw new e(403,{message:`Forbidden by ${G.constructor?.name||"UnknownGuard"} at ${Q.name}.${String(U)}`});let R=H.length>0?Math.max(...H.map((G)=>G.index)):-1,c=Array(Math.max(V.length,R+1));for(let G of H){if(typeof G.factory!=="function")throw Error(`Invalid parameter decorator metadata for ${Q.name}.${String(U)}`);let i=G.factory(G.data,F),r=await A.executePipes(i,{type:G.name,metatype:G.metatype,data:G.data},D);c[G.index]=r}let N=await V(...c);if(K!==void 0)return N;if(N instanceof Response)return N;if(T(N))return F.json(null);if(v(N))return F.text(N);return F.json(N)}catch(P){return A.handleException(P,F)}};this.registerRouteHandler(z,E,w,S)}}class l{hono;container;context;routeRegistry;componentManager;routeManager;options;constructor($={}){if(this.options=O($)?$:{},this.hono=new $$(this.options.hono),this.container=this.options.container||new f,this.context=new C,this.routeRegistry=new M,this.componentManager=new g(this.container),this.componentManager.setupGlobalComponents(this.options),this.setupErrorHandlers(),this.routeManager=new m(this.hono,this.container,this.routeRegistry,this.componentManager,{prefix:this.options.routing?.prefix,version:this.options.routing?.version}),this.options.deprecations?.printPreV1Warning)console.warn("[HonestJS] Pre-v1 warning: APIs may change before 1.0.0.")}setupErrorHandlers(){this.hono.notFound(this.options.notFound||I.handle()),this.hono.onError(this.options.onError||x.handle())}resolvePlugin($){if(s($))return new $;return $}normalizePluginEntry($){if($&&typeof $==="object"&&"plugin"in $){let _=$;return{plugin:this.resolvePlugin(_.plugin),preProcessors:_.preProcessors??[],postProcessors:_.postProcessors??[]}}return{plugin:this.resolvePlugin($),preProcessors:[],postProcessors:[]}}async register($){let _=await this.componentManager.registerModule($);for(let W of _)await this.routeManager.registerController(W);return this}static async create($,_={}){let W=new l(_),Y=(_.plugins||[]).map((z)=>W.normalizePluginEntry(z)),Q=W.getContext(),X=_.debug,B=X===!0||typeof X==="object"&&X.plugins,J=X===!0||typeof X==="object"&&X.routes;if(B&&Y.length>0)console.info("[HonestJS] Plugin order:",Y.map(({plugin:z})=>z.constructor?.name||"AnonymousPlugin").join(" -> "));for(let{plugin:z,preProcessors:U}of Y){for(let E of U)await E(W,W.hono,Q);if(z.beforeModulesRegistered)await z.beforeModulesRegistered(W,W.hono)}await W.register($);let q=W.getRoutes();if(_.strict?.requireRoutes&&q.length===0)throw Error("Strict mode: no routes were registered. Check your module/controller decorators.");if(J)console.info("[HonestJS] Registered routes:",q.map((z)=>`${z.method.toUpperCase()} ${z.fullPath}`));for(let{plugin:z,postProcessors:U}of Y){if(z.afterModulesRegistered)await z.afterModulesRegistered(W,W.hono);for(let E of U)await E(W,W.hono,Q)}return{app:W,hono:W.getApp()}}getApp(){return this.hono}getContext(){return this.context}getRoutes(){return this.routeRegistry.getRoutes()}}import{html as L,raw as u}from"hono/html";var _$={type:"website",locale:"en_US"},d=($)=>{if(!$)return"";return Object.entries($).map(([_,W])=>{if(typeof W==="boolean")return W?_:"";let Y=String(W).replace(/"/g,"&quot;");return`${_}="${Y}"`}).filter(Boolean).join(" ")},B_=($)=>{let _={..._$,...$};return L`
2
2
  <!DOCTYPE html>
3
- <html lang="${_.locale?.split("_")[0]||"en"}" ${u(m(_.htmlAttributes))}>
4
- <head ${u(m(_.headAttributes))}>
3
+ <html lang="${_.locale?.split("_")[0]||"en"}" ${u(d(_.htmlAttributes))}>
4
+ <head ${u(d(_.headAttributes))}>
5
5
  <meta charset="UTF-8" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- ${_.csp?U`<meta http-equiv="Content-Security-Policy" content="${_.csp}" />`:""}
7
+ ${_.csp?L`<meta http-equiv="Content-Security-Policy" content="${_.csp}" />`:""}
8
8
  <title>${_.title}</title>
9
- ${_.description?U`<meta name="description" content="${_.description}" />`:""}
9
+ ${_.description?L`<meta name="description" content="${_.description}" />`:""}
10
10
 
11
11
  <!-- Open Graph / Facebook -->
12
12
  <meta prefix="og: http://ogp.me/ns#" />
13
13
  <meta property="og:title" content="${_.title}" />
14
- ${_.description?U`<meta property="og:description" content="${_.description}" />`:""}
15
- ${_.image?U`<meta property="og:image" content="${_.image}" />`:""}
16
- ${_.url?U`<meta property="og:url" content="${_.url}" />`:""}
17
- ${_.locale?U`<meta property="og:locale" content="${_.locale}" />`:""}
18
- ${_.type?U`<meta property="og:type" content="${_.type}" />`:""}
19
- ${_.siteName?U`<meta property="og:site_name" content="${_.siteName}" />`:""}
14
+ ${_.description?L`<meta property="og:description" content="${_.description}" />`:""}
15
+ ${_.image?L`<meta property="og:image" content="${_.image}" />`:""}
16
+ ${_.url?L`<meta property="og:url" content="${_.url}" />`:""}
17
+ ${_.locale?L`<meta property="og:locale" content="${_.locale}" />`:""}
18
+ ${_.type?L`<meta property="og:type" content="${_.type}" />`:""}
19
+ ${_.siteName?L`<meta property="og:site_name" content="${_.siteName}" />`:""}
20
20
 
21
21
  <!-- Twitter -->
22
22
  <meta
@@ -24,23 +24,23 @@ import"reflect-metadata";import{Hono as t}from"hono";class M{store=new Map;get($
24
24
  content="${_.twitterCard||(_.image?"summary_large_image":"summary")}"
25
25
  />
26
26
  <meta name="twitter:title" content="${_.title}" />
27
- ${_.description?U`<meta name="twitter:description" content="${_.description}" />`:""}
28
- ${_.image?U`<meta name="twitter:image" content="${_.image}" />`:""}
27
+ ${_.description?L`<meta name="twitter:description" content="${_.description}" />`:""}
28
+ ${_.image?L`<meta name="twitter:image" content="${_.image}" />`:""}
29
29
 
30
30
  <!-- Custom Meta Tags -->
31
- ${_.customMeta?_.customMeta.map((W)=>{let Y=W.name?`name="${W.name}"`:"",q=W.property?`property="${W.property}"`:"";return U`<meta ${Y} ${q} content="${W.content}" />`}):""}
31
+ ${_.customMeta?_.customMeta.map((W)=>{let Y=W.name?`name="${W.name}"`:"",Q=W.property?`property="${W.property}"`:"";return L`<meta ${Y} ${Q} content="${W.content}" />`}):""}
32
32
 
33
33
  <!-- Favicon -->
34
- ${_.favicon?U`<link rel="icon" href="${_.favicon}" />`:""}
34
+ ${_.favicon?L`<link rel="icon" href="${_.favicon}" />`:""}
35
35
 
36
36
  <!-- Stylesheets -->
37
- ${_.stylesheets?_.stylesheets.map((W)=>U`<link rel="stylesheet" href="${W}" />`):""}
37
+ ${_.stylesheets?_.stylesheets.map((W)=>L`<link rel="stylesheet" href="${W}" />`):""}
38
38
 
39
39
  <!-- Scripts -->
40
- ${_.scripts?_.scripts.map((W)=>{if(typeof W==="string")return U`<script src="${W}"></script>`;let{src:Y,async:q,defer:Q}=W;if(q&&Q)return U`<script src="${Y}" async defer></script>`;if(q)return U`<script src="${Y}" async></script>`;if(Q)return U`<script src="${Y}" defer></script>`;return U`<script src="${Y}"></script>`}):""}
40
+ ${_.scripts?_.scripts.map((W)=>{if(typeof W==="string")return L`<script src="${W}"></script>`;let{src:Y,async:Q,defer:X}=W;if(Q&&X)return L`<script src="${Y}" async defer></script>`;if(Q)return L`<script src="${Y}" async></script>`;if(X)return L`<script src="${Y}" defer></script>`;return L`<script src="${Y}"></script>`}):""}
41
41
  </head>
42
- <body ${u(m(_.bodyAttributes))}>
42
+ <body ${u(d(_.bodyAttributes))}>
43
43
  ${_.children}
44
44
  </body>
45
45
  </html>
46
- `};function s($="",_={}){return(W)=>{X.setControllerPath(W,$),X.setControllerOptions(W,_)}}var l=H("get"),U_=H("post"),G_=H("put"),E_=H("delete"),F_=H("patch"),j_=H("options"),V_=H("all");function n($={}){return(_)=>{X.setModuleOptions(_,$)}}function N_($="",_={prefix:null,version:null}){return s($,_)}var b_=l;function w_($={}){return n({imports:$.imports,services:$.services,controllers:($.views||[]).concat($.controllers||[])})}var R_=E("body",async($,_)=>{let W=_.get("__honest.body.cache");if(W===void 0)W=await _.req.json(),_.set("__honest.body.cache",W);if($&&W&&typeof W==="object")return W[String($)];return W}),f_=E("param",($,_)=>{return $?_.req.param($):_.req.param()}),M_=E("query",($,_)=>{return $?_.req.query($):_.req.query()}),C_=E("header",($,_)=>{return $?_.req.header($):_.req.header()}),x_=E("request",($,_)=>_.req),I_=E("request",($,_)=>_.req),v_=E("response",($,_)=>_.res),y_=E("response",($,_)=>_.res),h_=E("context",($,_)=>_),g_=E("context",($,_)=>_),u_=E("variable",($,_)=>_.get($)),m_=E("variable",($,_)=>_.get($));function c_(){return($)=>{X.addService($)}}function l_($,..._){return(W,Y)=>{if(Y){let q=W.constructor;J.registerHandler($,q,Y,..._)}else J.registerController($,W,..._)}}function r_(...$){return(_,W)=>{if(W){let Y=_.constructor;J.registerHandler("filter",Y,W,...$)}else J.registerController("filter",_,...$)}}function e_(...$){return(_,W)=>{if(W){let Y=_.constructor;J.registerHandler("guard",Y,W,...$)}else J.registerController("guard",_,...$)}}function WW(...$){return(_,W)=>{if(W){let Y=_.constructor;J.registerHandler("middleware",Y,W,...$)}else J.registerController("middleware",_,...$)}}function QW(...$){return(_,W)=>{if(W){let Y=_.constructor;J.registerHandler("pipe",Y,W,...$)}else J.registerController("pipe",_,...$)}}export{f$ as stripEndSlash,y as normalizePath,N$ as isUndefined,K$ as isSymbol,v as isString,b$ as isPlainObject,O as isObject,w$ as isNumber,N as isNil,i as isFunction,P$ as isEmpty,c as isConstructor,E as createParamDecorator,H as createHttpMethodDecorator,R as createErrorResponse,R$ as addLeadingSlash,N_ as View,m_ as Variable,u_ as Var,h as VERSION_NEUTRAL,QW as UsePipes,WW as UseMiddleware,e_ as UseGuards,r_ as UseFilters,l_ as UseComponent,c_ as Service,T as RouteRegistry,y_ as Response,v_ as Res,I_ as Request,x_ as Req,M_ as Query,G_ as Put,U_ as Post,F_ as Patch,f_ as Param,b_ as Page,j_ as Options,I as NotFoundHandler,w_ as MvcModule,n as Module,X as MetadataRegistry,X_ as Layout,C_ as Header,l as Get,x as ErrorHandler,E_ as Delete,h_ as Ctx,s as Controller,g_ as Context,C as Container,R_ as Body,M as ApplicationContext,p as Application,V_ as All};
46
+ `};function n($="",_={}){return(W)=>{Z.setControllerPath(W,$),Z.setControllerOptions(W,_)}}var a=k("get"),F_=k("post"),E_=k("put"),V_=k("delete"),A_=k("patch"),k_=k("options"),O_=k("all");function o($={}){return(_)=>{Z.setModuleOptions(_,$)}}function b_($="",_={prefix:null,version:null}){return n($,_)}var K_=a;function w_($={}){return o({imports:$.imports,services:$.services,controllers:($.views||[]).concat($.controllers||[])})}var M_=j("body",async($,_)=>{let W=_.get("__honest.body.cache");if(W===void 0)W=await _.req.json(),_.set("__honest.body.cache",W);if($&&W&&typeof W==="object")return W[String($)];return W}),f_=j("param",($,_)=>{return $?_.req.param($):_.req.param()}),x_=j("query",($,_)=>{return $?_.req.query($):_.req.query()}),I_=j("header",($,_)=>{return $?_.req.header($):_.req.header()}),v_=j("request",($,_)=>_.req),y_=j("request",($,_)=>_.req),g_=j("response",($,_)=>_.res),h_=j("response",($,_)=>_.res),m_=j("context",($,_)=>_),u_=j("context",($,_)=>_),d_=j("variable",($,_)=>_.get($)),c_=j("variable",($,_)=>_.get($));function s_(){return($)=>{Z.addService($)}}function a_($,..._){return(W,Y)=>{if(Y){let X=`${W.constructor.name}:${String(Y)}`;_.forEach((B)=>Z.registerHandler($,X,B))}else _.forEach((Q)=>Z.registerController($,W,Q))}}function t_(...$){return(_,W)=>{if(W){let Q=`${_.constructor.name}:${String(W)}`;$.forEach((X)=>Z.registerHandler("filter",Q,X))}else $.forEach((Y)=>Z.registerController("filter",_,Y))}}function _W(...$){return(_,W)=>{if(W){let Q=`${_.constructor.name}:${String(W)}`;$.forEach((X)=>Z.registerHandler("guard",Q,X))}else $.forEach((Y)=>Z.registerController("guard",_,Y))}}function QW(...$){return(_,W)=>{if(W){let Q=`${_.constructor.name}:${String(W)}`;$.forEach((X)=>Z.registerHandler("middleware",Q,X))}else $.forEach((Y)=>Z.registerController("middleware",_,Y))}}function JW(...$){return(_,W)=>{if(W){let Q=`${_.constructor.name}:${String(W)}`;$.forEach((X)=>Z.registerHandler("pipe",Q,X))}else $.forEach((Y)=>Z.registerController("pipe",_,Y))}}export{x$ as stripEndSlash,y as normalizePath,K$ as isUndefined,M$ as isSymbol,v as isString,w$ as isPlainObject,O as isObject,R$ as isNumber,T as isNil,p as isFunction,C$ as isEmpty,s as isConstructor,j as createParamDecorator,k as createHttpMethodDecorator,b as createErrorResponse,f$ as addLeadingSlash,b_ as View,c_ as Variable,d_ as Var,h as VERSION_NEUTRAL,JW as UsePipes,QW as UseMiddleware,_W as UseGuards,t_ as UseFilters,a_ as UseComponent,s_ as Service,M as RouteRegistry,h_ as Response,g_ as Res,y_ as Request,v_ as Req,x_ as Query,E_ as Put,F_ as Post,A_ as Patch,f_ as Param,K_ as Page,k_ as Options,I as NotFoundHandler,w_ as MvcModule,o as Module,Z as MetadataRegistry,B_ as Layout,I_ as Header,a as Get,x as ErrorHandler,V_ as Delete,m_ as Ctx,n as Controller,u_ as Context,f as Container,M_ as Body,C as ApplicationContext,l as Application,O_ as All};
@@ -21,4 +21,15 @@ export interface DiContainer {
21
21
  * @throws {Error} If registration fails
22
22
  */
23
23
  register<T>(target: Constructor<T>, instance: T): void;
24
+ /**
25
+ * Checks whether the container already holds an instance for the given class
26
+ * @param target - The class constructor to check
27
+ * @returns true if an instance has been resolved or registered
28
+ */
29
+ has<T>(target: Constructor<T>): boolean;
30
+ /**
31
+ * Removes all cached instances from the container
32
+ * Useful for resetting state between tests
33
+ */
34
+ clear(): void;
24
35
  }
@@ -1,5 +1,4 @@
1
1
  import type { VERSION_NEUTRAL } from '../constants';
2
- import type { ParameterMetadata } from '../interfaces';
3
2
  /**
4
3
  * Internal metadata for defining a route. This interface is used by the framework
5
4
  * to store route information collected from decorators.
@@ -30,11 +29,6 @@ export interface RouteDefinition {
30
29
  * Name of the method in the controller class that handles this route
31
30
  */
32
31
  handlerName: string | symbol;
33
- /**
34
- * Metadata about the parameters of the handler method,
35
- * including decorators like @Body(), @Param(), @Query(), etc.
36
- */
37
- parameterMetadata: ParameterMetadata[];
38
32
  /**
39
33
  * Route-specific API version, overrides controller and global version.
40
34
  *
@@ -1,143 +1,46 @@
1
1
  import type { Context, Next } from 'hono';
2
- import type { ArgumentMetadata, DiContainer, GuardType, IGuard, IPipe, MiddlewareType, PipeType } from '../interfaces';
2
+ import type { ArgumentMetadata, DiContainer, FilterType, GuardType, IGuard, IPipe, MiddlewareType, PipeType } from '../interfaces';
3
3
  import { type ComponentType, type ComponentTypeMap } from '../registries';
4
4
  import type { Constructor } from '../types';
5
5
  /**
6
- * Manager class for handling all component types in the Honest framework
7
- * Provides unified management of middleware, guards, pipes, and filters
8
- * Handles component registration, resolution, and execution at global, controller, and handler levels
9
- * Works with the dependency injection container to resolve component instances
6
+ * Manager class for handling all component types in the Honest framework.
7
+ *
8
+ * Each Application instance owns a ComponentManager, which holds per-app
9
+ * global components and a reference to the DI container. Controller-level
10
+ * and handler-level components remain in MetadataRegistry (static, set at
11
+ * class-definition time by decorators).
10
12
  */
11
13
  export declare class ComponentManager {
12
- private static container;
14
+ private readonly container;
15
+ private readonly globalComponents;
16
+ constructor(container: DiContainer);
13
17
  /**
14
- * Initializes the ComponentManager with a dependency injection container
15
- * Must be called before using any other ComponentManager methods
16
- * @param container - The dependency injection container to use for resolving components
18
+ * Configures global components from application options.
17
19
  */
18
- static init(container: DiContainer): void;
19
- /**
20
- * Configures global components from application options
21
- * Global components are applied to all routes in the application
22
- * @param options - Application options containing component configurations
23
- * @param options.components - Optional component configuration object
24
- * @param options.components.middleware - Optional array of global middleware
25
- * @param options.components.guards - Optional array of global guards
26
- * @param options.components.pipes - Optional array of global pipes
27
- * @param options.components.filters - Optional array of global filters
28
- */
29
- static setupGlobalComponents(options: {
20
+ setupGlobalComponents(options: {
30
21
  components?: {
31
- middleware?: any[];
32
- guards?: any[];
33
- pipes?: any[];
34
- filters?: any[];
22
+ middleware?: MiddlewareType[];
23
+ guards?: GuardType[];
24
+ pipes?: PipeType[];
25
+ filters?: FilterType[];
35
26
  };
36
27
  }): void;
37
- /**
38
- * Registers a component at the global level
39
- * @param type - The type of component to register
40
- * @param components - The component classes or instances to register
41
- */
42
- static registerGlobal<T extends ComponentType>(type: T, ...components: ComponentTypeMap[T][]): void;
43
- /**
44
- * Registers a component at the controller level
45
- * @param type - The type of component to register
46
- * @param controller - The controller class to register the component for
47
- * @param components - The component classes or instances to register
48
- */
49
- static registerController<T extends ComponentType>(type: T, controller: Constructor, ...components: ComponentTypeMap[T][]): void;
50
- /**
51
- * Registers a component at the handler level
52
- * @param type - The type of component to register
53
- * @param controller - The controller class
54
- * @param handlerName - The handler method name
55
- * @param components - The component classes or instances to register
56
- */
57
- static registerHandler<T extends ComponentType>(type: T, controller: Constructor, handlerName: string | symbol, ...components: ComponentTypeMap[T][]): void;
58
- /**
59
- * Gets all components of a specific type for a handler
60
- * @param type - The type of component to get
61
- * @param controller - The controller class
62
- * @param handlerName - The handler method name
63
- * @returns An array of component instances
64
- */
65
- static getComponents<T extends ComponentType>(type: T, controller: Constructor, handlerName: string | symbol): ComponentTypeMap[T][];
66
- /**
67
- * Resolves middleware classes or instances to middleware functions
68
- * @param middlewareItems - The middleware classes or instances to resolve
69
- * @returns An array of middleware functions
70
- */
71
- static resolveMiddleware(middlewareItems: MiddlewareType[]): ((c: Context, next: Next) => Promise<Response | void>)[];
72
- /**
73
- * Gets middleware for a specific handler
74
- * @param controller - The controller class
75
- * @param handlerName - The handler method name
76
- * @returns An array of middleware functions
77
- */
78
- static getHandlerMiddleware(controller: Constructor, handlerName: string | symbol): ((c: Context, next: Next) => Promise<Response | void>)[];
79
- /**
80
- * Gets global middleware
81
- * @returns An array of middleware functions
82
- */
83
- static getGlobalMiddleware(): ((c: Context, next: Next) => Promise<Response | void>)[];
84
- /**
85
- * Resolves guard classes or instances to guard instances
86
- * @param guardItems - The guard classes or instances to resolve
87
- * @returns An array of guard instances
88
- */
89
- static resolveGuards(guardItems: GuardType[]): IGuard[];
90
- /**
91
- * Gets guards for a specific handler
92
- * @param controller - The controller class
93
- * @param handlerName - The handler method name
94
- * @returns An array of guard instances
95
- */
96
- static getHandlerGuards(controller: Constructor, handlerName: string | symbol): IGuard[];
97
- /**
98
- * Resolves pipe classes or instances to pipe instances
99
- * @param pipeItems - The pipe classes or instances to resolve
100
- * @returns An array of pipe instances
101
- */
102
- static resolvePipes(pipeItems: PipeType[]): IPipe[];
103
- /**
104
- * Gets pipes for a specific handler
105
- * @param controller - The controller class
106
- * @param handlerName - The handler method name
107
- * @returns An array of pipe instances
108
- */
109
- static getHandlerPipes(controller: Constructor, handlerName: string | symbol): IPipe[];
110
- /**
111
- * Executes a series of pipes on a value
112
- * Pipes are executed in sequence, with each pipe's output feeding into the next pipe
113
- * @param value - The initial value to transform
114
- * @param metadata - Metadata about the parameter being transformed
115
- * @param pipes - Array of pipes to execute
116
- * @returns The final transformed value after all pipes have executed
117
- * @throws {Error} If any pipe transformation fails
118
- */
119
- static executePipes(value: any, metadata: ArgumentMetadata, pipes: IPipe[]): Promise<any>;
120
- /**
121
- * Handles an exception by passing it through registered exception filters
122
- * Filters are executed in sequence until one returns a response
123
- * @param exception - The error to handle
124
- * @param context - The Hono context object
125
- * @returns A Response object if a filter handles the exception, undefined otherwise
126
- */
127
- static handleException(exception: Error, context: Context): Promise<Response | undefined>;
128
- /**
129
- * Executes a list of exception filters
130
- * @param filterItems - The exception filter classes or instances to execute
131
- * @param exception - The exception that was thrown
132
- * @param context - The Hono context object
133
- * @returns The response from the first filter that handles the exception or undefined if no filter handled it
134
- */
135
- private static executeFilters;
136
- /**
137
- * Registers a module and its dependencies with the container
138
- * @param moduleClass - The module class to register
139
- * @param container - The dependency injection container
140
- * @returns An array of controller classes registered from this module
141
- */
142
- static registerModule(moduleClass: Constructor, container: DiContainer): Promise<Constructor[]>;
28
+ registerGlobal<T extends ComponentType>(type: T, ...components: ComponentTypeMap[T][]): void;
29
+ getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
30
+ /**
31
+ * Gets all components of a specific type for a handler.
32
+ * Merges: instance global → static controller → static handler.
33
+ */
34
+ getComponents<T extends ComponentType>(type: T, controller: Constructor, handlerName: string | symbol): ComponentTypeMap[T][];
35
+ resolveMiddleware(middlewareItems: MiddlewareType[]): ((c: Context, next: Next) => Promise<Response | void>)[];
36
+ getHandlerMiddleware(controller: Constructor, handlerName: string | symbol): ((c: Context, next: Next) => Promise<Response | void>)[];
37
+ getGlobalMiddleware(): ((c: Context, next: Next) => Promise<Response | void>)[];
38
+ resolveGuards(guardItems: GuardType[]): IGuard[];
39
+ getHandlerGuards(controller: Constructor, handlerName: string | symbol): IGuard[];
40
+ resolvePipes(pipeItems: PipeType[]): IPipe[];
41
+ getHandlerPipes(controller: Constructor, handlerName: string | symbol): IPipe[];
42
+ executePipes(value: any, metadata: ArgumentMetadata, pipes: IPipe[]): Promise<any>;
43
+ handleException(exception: Error, context: Context): Promise<Response | undefined>;
44
+ private executeFilters;
45
+ registerModule(moduleClass: Constructor, registered?: Set<Constructor>): Promise<Constructor[]>;
143
46
  }
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
@@ -1,109 +1,31 @@
1
1
  import type { Hono } from 'hono';
2
2
  import { VERSION_NEUTRAL } from '../constants';
3
3
  import type { DiContainer } from '../interfaces';
4
+ import { ComponentManager } from './component.manager';
5
+ import { RouteRegistry } from '../registries/route.registry';
4
6
  import type { Constructor } from '../types';
5
7
  /**
6
- * Manager class for handling route registration in the Honest framework
7
- * Responsible for:
8
- * - Registering controller routes with the Hono application
9
- * - Managing route versioning and prefixing
10
- * - Applying middleware and guards to routes
11
- * - Handling parameter transformation and validation
8
+ * Manager class for handling route registration in the Honest framework.
12
9
  *
13
- * Versioning features:
14
- * - Global version setting can be overridden at controller or method level
15
- * - Controllers can opt out of versioning by setting version to null
16
- * - Routes can use VERSION_NEUTRAL to be accessible with and without version prefix
17
- * - Routes can specify an array of versions to support multiple versions
18
- *
19
- * Path handling:
20
- * - Global prefix can be overridden at controller level
21
- * - Paths are automatically normalized
22
- * - Final path structure: prefix/version/controller-path/method-path
10
+ * Receives all per-app dependencies (Hono, Container, RouteRegistry,
11
+ * ComponentManager) via constructor no static state.
23
12
  */
24
13
  export declare class RouteManager {
25
14
  private hono;
26
15
  private container;
16
+ private routeRegistry;
17
+ private componentManager;
27
18
  private globalPrefix?;
28
19
  private globalVersion?;
29
- /**
30
- * Creates a new RouteManager instance
31
- * @param hono - The Hono application instance for route registration
32
- * @param container - The dependency injection container for resolving controllers and dependencies
33
- * @param options - Configuration options for the route manager
34
- * @param options.prefix - Optional global prefix for all routes
35
- * @param options.version - Optional global version or version array for all routes
36
- */
37
- constructor(hono: Hono, container: DiContainer, options?: {
20
+ constructor(hono: Hono, container: DiContainer, routeRegistry: RouteRegistry, componentManager: ComponentManager, options?: {
38
21
  prefix?: string;
39
22
  version?: number | typeof VERSION_NEUTRAL | number[];
40
23
  });
41
- /**
42
- * Applies global middleware to the application
43
- */
44
24
  private applyGlobalMiddleware;
45
- /**
46
- * Normalizes a path segment for route registration
47
- * @param path - The path segment to normalize
48
- * @returns The normalized path segment
49
- */
50
25
  private normalizePath;
51
- /**
52
- * Registers a wrapper handler with middleware for a route
53
- * @param method - HTTP method
54
- * @param path - Full path for the route
55
- * @param handlerMiddleware - Middleware for the handler
56
- * @param wrapperHandler - The wrapper handler function
57
- */
58
26
  private registerRouteHandler;
59
- /**
60
- * Builds a route path with the correct order: prefix, version, controller path, method path
61
- * @param prefix - Global or controller-specific prefix
62
- * @param version - Version string (e.g., '/v1') or empty string if no version
63
- * @param controllerPath - Controller path
64
- * @param methodPath - Method-specific path
65
- * @returns Properly formatted full path
66
- */
67
27
  private buildRoutePath;
68
- /**
69
- * Formats a version number or VERSION_NEUTRAL into a path segment
70
- * @param version - Version number or VERSION_NEUTRAL
71
- * @returns Formatted version string (e.g., '/v1') or empty string if null
72
- */
73
28
  private formatVersionSegment;
74
- /**
75
- * Registers a controller and all its routes with the application
76
- * Handles versioning, prefixing, and middleware application
77
- *
78
- * @param controllerClass - The controller class to register
79
- * @throws {Error} If controller registration fails or if required dependencies cannot be resolved
80
- *
81
- * Route registration process:
82
- * 1. Resolves controller instance and metadata
83
- * 2. Processes controller-level options (prefix, version)
84
- * 3. Registers each route with appropriate:
85
- * - Path construction (prefix/version/controller-path/method-path)
86
- * - Middleware application
87
- * - Parameter processing
88
- * - Guard validation
89
- */
90
29
  registerController(controllerClass: Constructor): Promise<void>;
91
- /**
92
- * Registers a specific route with the application
93
- * Handles middleware setup, parameter processing, and response handling
94
- *
95
- * @param controllerInstance - Instance of the controller containing the route handler
96
- * @param route - Route metadata including path and HTTP method
97
- * @param parameterMetadata - Metadata for parameter processing
98
- * @param contextIndices - Map of context parameter indices
99
- * @param controllerClass - The controller class
100
- * @param prefix - Route prefix
101
- * @param versionSegment - Version segment of the path
102
- * @param controllerSegment - Controller path segment
103
- * @param methodSegment - Method-specific path segment
104
- * @param method - HTTP method for the route
105
- *
106
- * @throws {Error} If route registration fails
107
- */
108
30
  private registerRoute;
109
31
  }
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
@@ -1,19 +1,7 @@
1
1
  import type { ControllerOptions, FilterType, GuardType, MiddlewareType, ModuleOptions, ParameterMetadata, PipeType, RouteDefinition } from '../interfaces';
2
2
  import type { Constructor } from '../types';
3
- /**
4
- * Available component types that can be registered at different levels in the application
5
- * Each type corresponds to a specific aspect of request processing
6
- */
7
3
  export type ComponentType = 'middleware' | 'guard' | 'pipe' | 'filter';
8
- /**
9
- * Union type of all possible component instances
10
- * Represents any type of component that can be registered in the application
11
- */
12
4
  export type ComponentInstance = MiddlewareType | GuardType | PipeType | FilterType;
13
- /**
14
- * Maps component type identifiers to their specific instance types
15
- * Used for type-safe component registration and retrieval
16
- */
17
5
  export interface ComponentTypeMap {
18
6
  middleware: MiddlewareType;
19
7
  guard: GuardType;
@@ -64,11 +52,6 @@ export declare class MetadataRegistry {
64
52
  * Used for optimizing context injection
65
53
  */
66
54
  private static readonly contextIndices;
67
- /**
68
- * Registry for global-level components
69
- * Components registered here apply to all routes
70
- */
71
- private static readonly global;
72
55
  /**
73
56
  * Registry for controller-level components
74
57
  * Components registered here apply to all routes in a specific controller
@@ -149,14 +132,6 @@ export declare class MetadataRegistry {
149
132
  * Set context indices
150
133
  */
151
134
  static setContextIndices(controller: Constructor, indices: Map<string | symbol, number>): void;
152
- /**
153
- * Register a component at the global level
154
- */
155
- static registerGlobal<T extends ComponentType>(type: T, component: ComponentTypeMap[T]): void;
156
- /**
157
- * Get all global components of a specific type
158
- */
159
- static getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
160
135
  /**
161
136
  * Register a component at the controller level
162
137
  */
@@ -174,9 +149,8 @@ export declare class MetadataRegistry {
174
149
  */
175
150
  static getHandler<T extends ComponentType>(type: T, handlerKey: string): ComponentTypeMap[T][];
176
151
  /**
177
- * Clears all registered metadata from the registry
178
- * Primarily used for testing and development purposes
179
- * Use with caution in production environments
152
+ * Clears all registered decorator metadata.
153
+ * Primarily used for testing.
180
154
  */
181
155
  static clear(): void;
182
156
  }
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
@@ -1,63 +1,16 @@
1
1
  import type { RouteInfo } from '../interfaces';
2
2
  /**
3
- * Registry for managing and querying route information in the application
3
+ * Registry for managing and querying route information in the application.
4
4
  *
5
- * Provides functionality to:
6
- * - Register new routes with their metadata
7
- * - Query routes by various criteria (controller, method, path)
8
- * - Access route information for documentation and debugging
9
- * - Manage route lifecycle (registration and cleanup)
10
- *
11
- * The registry maintains a read-only view of routes to prevent unintended modifications
5
+ * Each Application instance owns its own RouteRegistry, ensuring routes
6
+ * from one app never leak into another.
12
7
  */
13
8
  export declare class RouteRegistry {
14
- /**
15
- * Internal storage for registered routes
16
- * Maintains the complete list of routes in registration order
17
- */
18
- private static readonly routes;
19
- /**
20
- * Registers a new route in the application
21
- * @param routeInfo - Complete route information including path, method, and handler details
22
- * @throws {Error} If the route information is invalid or incomplete
23
- */
24
- static registerRoute(routeInfo: RouteInfo): void;
25
- /**
26
- * Retrieves all registered routes in the application
27
- * @returns A read-only array of all route information
28
- * Routes are returned in their registration order
29
- */
30
- static getRoutes(): ReadonlyArray<RouteInfo>;
31
- /**
32
- * Retrieves all routes registered for a specific controller
33
- * @param controllerName - Name or symbol identifying the controller
34
- * @returns A read-only array of routes belonging to the specified controller
35
- * Returns an empty array if no routes are found for the controller
36
- */
37
- static getRoutesByController(controllerName: string | symbol): ReadonlyArray<RouteInfo>;
38
- /**
39
- * Retrieves all routes registered for a specific HTTP method
40
- * @param method - HTTP method to filter by (case-insensitive)
41
- * @returns A read-only array of routes handling the specified HTTP method
42
- * Returns an empty array if no routes are found for the method
43
- */
44
- static getRoutesByMethod(method: string): ReadonlyArray<RouteInfo>;
45
- /**
46
- * Retrieves routes matching a specific path pattern
47
- * @param pattern - Regular expression to match against route paths
48
- * @returns A read-only array of routes whose paths match the pattern
49
- * Returns an empty array if no matching routes are found
50
- * @example
51
- * ```ts
52
- * // Find all routes containing 'users'
53
- * const userRoutes = RouteRegistry.getRoutesByPath(/users/);
54
- * ```
55
- */
56
- static getRoutesByPath(pattern: RegExp): ReadonlyArray<RouteInfo>;
57
- /**
58
- * Removes all registered routes from the registry
59
- * Primarily used for testing and development purposes
60
- * Use with caution in production environments
61
- */
62
- static clear(): void;
9
+ private readonly routes;
10
+ registerRoute(routeInfo: RouteInfo): void;
11
+ getRoutes(): ReadonlyArray<RouteInfo>;
12
+ getRoutesByController(controllerName: string | symbol): ReadonlyArray<RouteInfo>;
13
+ getRoutesByMethod(method: string): ReadonlyArray<RouteInfo>;
14
+ getRoutesByPath(pattern: RegExp): ReadonlyArray<RouteInfo>;
15
+ clear(): void;
63
16
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "honestjs",
3
3
  "description": "HonestJS - a modern web framework built on top of Hono",
4
- "version": "0.1.11",
4
+ "version": "0.1.12",
5
5
  "author": "Orkhan Karimov <karimovok1@gmail.com> (https://github.com/kerimovok)",
6
6
  "repository": {
7
7
  "type": "git",
@@ -12,15 +12,15 @@
12
12
  "type": "module",
13
13
  "types": "dist/index.d.ts",
14
14
  "devDependencies": {
15
- "@eslint/js": "^9.39.3",
16
- "@types/bun": "^1.3.9",
17
- "eslint": "^9.39.3",
15
+ "@eslint/js": "^9.39.4",
16
+ "@types/bun": "^1.3.10",
17
+ "eslint": "^9.39.4",
18
18
  "eslint-config-prettier": "^10.1.8",
19
19
  "globals": "^16.5.0",
20
20
  "husky": "^9.1.7",
21
- "lint-staged": "^16.3.0",
21
+ "lint-staged": "^16.4.0",
22
22
  "prettier": "3.6.2",
23
- "typescript-eslint": "^8.56.1"
23
+ "typescript-eslint": "^8.57.0"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "hono": "^4.8.5",