honestjs 0.1.2 → 0.1.3

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
@@ -1,12 +1,47 @@
1
1
  <p align="center">
2
2
  <a href="https://github.com/honestjs/" target="blank"><img src="https://avatars.githubusercontent.com/u/197956909" width="120" alt="Honest Logo" /></a>
3
3
  </p>
4
+
4
5
  <p align="center">
5
6
  A modern, TypeScript-first web framework built on top of <a href="https://hono.dev/" target="blank">Hono</a>, designed for building scalable and
6
7
  maintainable web applications. Honest combines the elegance and architecture of <a href="https://nestjs.com/" target="blank">Nest</a> with the
7
8
  ultra-fast performance of Hono, giving you the best of both worlds.
8
9
  </p>
9
10
 
11
+ <p align="center">
12
+ <a href="https://github.com/honestjs/examples">
13
+ <u>examples</u>
14
+ </a>
15
+ |
16
+ <a href="https://github.com/honestjs/templates">
17
+ <u>templates</u>
18
+ </a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <a href="https://github.com/honestjs/middleware">
23
+ <u>middleware</u>
24
+ </a>
25
+ |
26
+ <a href="https://github.com/honestjs/guards">
27
+ <u>guards</u>
28
+ </a>
29
+ |
30
+ <a href="https://github.com/honestjs/pipes">
31
+ <u>pipes</u>
32
+ </a>
33
+ |
34
+ <a href="https://github.com/honestjs/filters">
35
+ <u>filters</u>
36
+ </a>
37
+ </p>
38
+
39
+ <p align="center">
40
+ <a href="https://github.com/honestjs/http-essentials">
41
+ <u>http-essentials</u>
42
+ </a>
43
+ </p>
44
+
10
45
  > ⚠️ **Early Development Warning**
11
46
  >
12
47
  > Honest is currently in early development (pre-v1.0.0). Please be aware that:
@@ -0,0 +1 @@
1
+ export * from './layout.component';
@@ -0,0 +1,31 @@
1
+ import type { PropsWithChildren } from 'hono/jsx';
2
+ export type HtmlAttributes = Record<string, string | number | boolean>;
3
+ export interface MetaTag {
4
+ property: string;
5
+ content: string;
6
+ name?: string;
7
+ prefix?: string;
8
+ }
9
+ export interface SiteData {
10
+ title: string;
11
+ description?: string;
12
+ image?: string;
13
+ url?: string;
14
+ locale?: string;
15
+ type?: string;
16
+ siteName?: string;
17
+ customMeta?: MetaTag[];
18
+ scripts?: (string | {
19
+ src: string;
20
+ async?: boolean;
21
+ defer?: boolean;
22
+ })[];
23
+ stylesheets?: string[];
24
+ favicon?: string;
25
+ twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player';
26
+ csp?: string;
27
+ htmlAttributes?: HtmlAttributes;
28
+ headAttributes?: HtmlAttributes;
29
+ bodyAttributes?: HtmlAttributes;
30
+ }
31
+ export declare const Layout: (props: PropsWithChildren<SiteData>) => import("hono/utils/html").HtmlEscapedString | Promise<import("hono/utils/html").HtmlEscapedString>;
@@ -1,6 +1,7 @@
1
1
  export * from './controller.decorator';
2
2
  export * from './http-method.decorator';
3
3
  export * from './module.decorator';
4
+ export * from './mvc.decorator';
4
5
  export * from './parameter.decorator';
5
6
  export * from './service.decorator';
6
7
  export * from './use-component.decorator';
@@ -0,0 +1,26 @@
1
+ import type { ControllerOptions, ModuleOptions } from '../interfaces';
2
+ import type { Constructor } from '../types';
3
+ /**
4
+ * Decorator that marks a class as a controller
5
+ * Controllers are responsible for handling incoming requests and returning responses
6
+ * @param route - The base route for all endpoints in this controller
7
+ * @param options - Configuration options for the controller
8
+ * @returns A class decorator function
9
+ */
10
+ export declare function View(route?: string, options?: ControllerOptions): ClassDecorator;
11
+ /**
12
+ * GET method decorator
13
+ * The GET method requests a representation of the specified resource.
14
+ * Requests using GET should only retrieve data and should not contain a request content.
15
+ * @param path - The route path
16
+ */
17
+ export declare const Page: (path?: string, options?: import("..").HttpMethodOptions) => MethodDecorator;
18
+ /**
19
+ * Decorator that marks a class as a module
20
+ * Modules are used to organize the application structure and dependencies
21
+ * @param options - Configuration options for the module
22
+ * @returns A class decorator function
23
+ */
24
+ export declare function MvcModule(options?: ModuleOptions & {
25
+ views?: Constructor[];
26
+ }): ClassDecorator;
@@ -11,9 +11,10 @@ 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
14
15
  * @returns An instance of the target class
15
16
  */
16
- resolve<T>(target: Constructor<T>): T;
17
+ resolve<T>(target: Constructor<T>, resolving?: Set<Constructor>): T;
17
18
  /**
18
19
  * Registers a pre-created instance for a class
19
20
  * @param target - The class constructor to register
@@ -1 +1 @@
1
- export * from './contrainer';
1
+ export * from './container';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import 'reflect-metadata';
2
2
  export * from './application';
3
+ export * from './components';
3
4
  export * from './constants';
4
5
  export * from './decorators';
5
6
  export * from './di';
@@ -10,10 +11,3 @@ export * from './managers';
10
11
  export * from './registries';
11
12
  export * from './types';
12
13
  export * from './utils';
13
- declare global {
14
- namespace Reflect {
15
- function getMetadata(metadataKey: string, target: object): any;
16
- function defineMetadata(metadataKey: string, metadataValue: any, target: object): void;
17
- function hasMetadata(metadataKey: string, target: object): boolean;
18
- }
19
- }
package/dist/index.js CHANGED
@@ -1 +1,46 @@
1
- import"reflect-metadata";import{Hono as s}from"hono";class f{instances=new Map;resolve(Q){if(this.instances.has(Q))return this.instances.get(Q);let X=(Reflect.getMetadata("design:paramtypes",Q)||[]).map((Z)=>{return this.resolve(Z)}),Y=new Q(...X);return this.instances.set(Q,Y),Y}register(Q,W){this.instances.set(Q,W)}}import{HTTPException as i}from"hono/http-exception";function T(Q,W,X){let Y=new Date().toISOString(),Z=W.get("requestId"),$=W.req.path;if(Q instanceof i)return{response:{status:X?.status||Q.status,message:X?.title||Q.message,timestamp:Y,path:$,requestId:Z,code:X?.code,details:X?.additionalDetails,...X?.detail&&{detail:X.detail}},status:X?.status||Q.status};if(Q.statusCode||Q.status){let G=Q.statusCode||Q.status,U=X?.status||G;return{response:{status:U,message:X?.title||Q.message,timestamp:Y,path:$,requestId:Z,code:X?.code||Q.name,details:X?.additionalDetails,...X?.detail&&{detail:X.detail}},status:U}}let q=X?.status||500;return{response:{status:q,message:X?.title||Q.message,timestamp:Y,path:$,requestId:Z,code:X?.code||Q.name,details:X?.additionalDetails||{stack:Q.stack},...X?.detail&&{detail:X.detail}},status:q}}class J{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(Q){return this.routes.get(Q)||[]}static setRoutes(Q,W){this.routes.set(Q,W)}static addRoute(Q,W){if(!this.routes.has(Q))this.routes.set(Q,[]);this.routes.get(Q).push(W)}static getControllerPath(Q){return this.controllers.get(Q)||""}static setControllerPath(Q,W){this.controllers.set(Q,W)}static getControllerOptions(Q){return this.controllerOptions.get(Q)||{}}static setControllerOptions(Q,W){this.controllerOptions.set(Q,W)}static isService(Q){return this.services.has(Q)}static addService(Q){this.services.add(Q)}static getAllServices(){return this.services}static getModuleOptions(Q){return this.modules.get(Q)}static setModuleOptions(Q,W){this.modules.set(Q,W)}static getParameters(Q){return this.parameters.get(Q)||new Map}static setParameterMap(Q,W){this.parameters.set(Q,W)}static getContextIndices(Q){return this.contextIndices.get(Q)||new Map}static setContextIndices(Q,W){this.contextIndices.set(Q,W)}static registerGlobal(Q,W){this.global.get(Q).add(W)}static getGlobal(Q){return this.global.get(Q)}static registerController(Q,W,X){let Y=this.controller.get(Q);if(!Y.has(W))Y.set(W,[]);Y.get(W).push(X)}static getController(Q,W){return this.controller.get(Q).get(W)||[]}static registerHandler(Q,W,X){let Y=this.handler.get(Q);if(!Y.has(W))Y.set(W,[]);Y.get(W).push(X)}static getHandler(Q,W){return this.handler.get(Q).get(W)||[]}}class H{static routes=[];static registerRoute(Q){this.routes.push(Q)}static getRoutes(){return this.routes}static getRoutesByController(Q){return this.routes.filter((W)=>W.controller===Q)}static getRoutesByMethod(Q){return this.routes.filter((W)=>W.method.toUpperCase()===Q.toUpperCase())}static getRoutesByPath(Q){return this.routes.filter((W)=>Q.test(W.fullPath))}static clear(){this.routes.length=0}}function V(Q){return(W="",X={})=>{return(Y,Z,$)=>{let q=Y.constructor;J.addRoute(q,{path:W,method:Q,handlerName:Z,parameterMetadata:[],version:X.version,prefix:X.prefix})}}}function j(Q,W){return(X)=>{return(Y,Z,$)=>{let q=Y.constructor;if(!J.getParameters(q).size)J.setParameterMap(q,new Map);let L=J.getParameters(q);if(!L.has(Z))L.set(Z,[]);let U=Reflect.getMetadata("design:paramtypes",Y,Z)?.[$];if(L.get(Z).push({index:$,name:Q,data:X,factory:W,metatype:U}),Q==="context"){if(!J.getContextIndices(q).size)J.setContextIndices(q,new Map);J.getContextIndices(q).set(Z,$)}}}}class M{static handle(){return async(Q,W)=>{return W.json(T(Q,W))}}}class I{static handle(){return async(Q)=>{return Q.json({message:`Not Found - ${Q.req.path}`},404)}}}var w=(Q)=>Q!==null&&typeof Q==="object";class _{static container;static init(Q){this.container=Q}static setupGlobalComponents(Q){let W=Q.components||{};if(W.middleware)this.registerGlobal("middleware",...W.middleware);if(W.guards)this.registerGlobal("guard",...W.guards);if(W.pipes)this.registerGlobal("pipe",...W.pipes);if(W.filters)this.registerGlobal("filter",...W.filters)}static registerGlobal(Q,...W){W.forEach((X)=>{J.registerGlobal(Q,X)})}static registerController(Q,W,...X){X.forEach((Y)=>{J.registerController(Q,W,Y)})}static registerHandler(Q,W,X,...Y){let Z=`${W.name}:${String(X)}`;Y.forEach(($)=>{J.registerHandler(Q,Z,$)})}static getComponents(Q,W,X){let Y=`${W.name}:${String(X)}`,Z=J.getHandler(Q,Y),$=J.getController(Q,W);return[...Array.from(J.getGlobal(Q)),...$,...Z]}static resolveMiddleware(Q){return Q.map((W)=>{if(w(W)&&"use"in W)return W.use.bind(W);let X=this.container.resolve(W);return X.use.bind(X)})}static getHandlerMiddleware(Q,W){let X=this.getComponents("middleware",Q,W);return this.resolveMiddleware(X)}static getGlobalMiddleware(){let Q=Array.from(J.getGlobal("middleware"));return this.resolveMiddleware(Q)}static resolveGuards(Q){return Q.map((W)=>{if(w(W)&&"canActivate"in W)return W;return this.container.resolve(W)})}static getHandlerGuards(Q,W){let X=this.getComponents("guard",Q,W);return this.resolveGuards(X)}static resolvePipes(Q){return Q.map((W)=>{if(w(W)&&"transform"in W)return W;return this.container.resolve(W)})}static getHandlerPipes(Q,W){let X=this.getComponents("pipe",Q,W);return this.resolvePipes(X)}static async executePipes(Q,W,X){let Y=Q;for(let Z of X)Y=await Z.transform(Y,W);return Y}static async handleException(Q,W){let X=W.get("controllerClass"),Y=W.get("handlerName");if(X&&Y){let $=J.getHandler("filter",`${X.name}:${Y}`);if($.length>0){let q=await this.executeFilters($,Q,W);if(q)return q}}if(X){let $=J.getController("filter",X);if($.length>0){let q=await this.executeFilters($,Q,W);if(q)return q}}let Z=Array.from(J.getGlobal("filter"));if(Z.length>0){let $=await this.executeFilters(Z,Q,W);if($)return $}return console.log("No filter handled the exception, creating default response"),W.json(T(Q,W))}static async executeFilters(Q,W,X){for(let Y of Q){let Z;if(w(Y)&&"catch"in Y)Z=Y;else Z=this.container.resolve(Y);try{let $=await Z.catch(W,X);if($!==void 0)return $}catch($){console.error("Error in exception filter:",$)}}return}static async registerModule(Q,W){let X=J.getModuleOptions(Q);if(!X)throw new Error(`Module ${Q.name} is not properly decorated with @Module()`);let Y=[];if(X.imports&&X.imports.length>0)for(let Z of X.imports){let $=await this.registerModule(Z,W);Y.push(...$)}if(X.services&&X.services.length>0)for(let Z of X.services)W.resolve(Z);if(X.controllers&&X.controllers.length>0)Y.push(...X.controllers);return Y}}import{HTTPException as p}from"hono/http-exception";var x=Symbol("VERSION_NEUTRAL");var HQ=(Q)=>typeof Q==="undefined",O=(Q)=>Q===null||typeof Q==="undefined",C=(Q)=>Q!==null&&typeof Q==="object",NQ=(Q)=>{if(!C(Q))return!1;let W=Object.getPrototypeOf(Q);if(W===null)return!0;let X=Object.prototype.hasOwnProperty.call(W,"constructor")&&W.constructor;return typeof X==="function"&&X instanceof X&&Function.prototype.toString.call(X)===Function.prototype.toString.call(Object)},h=(Q)=>typeof Q==="function",v=(Q)=>typeof Q==="string",KQ=(Q)=>typeof Q==="number",RQ=(Q)=>Q.length===0,SQ=(Q)=>typeof Q==="symbol",TQ=(Q)=>typeof Q==="string"?Q.charAt(0)!=="/"?"/"+Q:Q:"",y=(Q)=>Q?Q.startsWith("/")?("/"+Q.replace(/\/+$/,"")).replace(/\/+/g,"/"):"/"+Q.replace(/\/+$/,""):"/",wQ=(Q)=>Q.endsWith("/")?Q.slice(0,-1):Q,m=(Q)=>{return h(Q)&&!O(Q.prototype)&&!h(Q.prototype)&&Object.getOwnPropertyNames(Q.prototype).length>1};class u{hono;container;globalPrefix;globalVersion;constructor(Q,W,X={}){this.hono=Q,this.container=W,this.globalPrefix=X.prefix!==void 0?this.normalizePath(X.prefix):void 0,this.globalVersion=X.version,this.applyGlobalMiddleware()}applyGlobalMiddleware(){let Q=_.getGlobalMiddleware();for(let W of Q)this.hono.use("*",W)}normalizePath(Q){if(v(Q))return y(Q);return Q?`/${Q}`:""}registerRouteHandler(Q,W,X,Y){if(X.length>0)this.hono.on(Q.toUpperCase(),W,...X,Y);else this.hono.on(Q.toUpperCase(),W,Y)}buildRoutePath(Q,W,X,Y){return y(`${Q}${W}${X}${Y}`)}formatVersionSegment(Q){if(O(Q))return"";return Q===x?"":`/v${String(Q)}`}async registerController(Q){let W=J.getControllerPath(Q)||"",X=J.getControllerOptions(Q)||{},Y=J.getRoutes(Q)||[],Z=J.getParameters(Q)||new Map,$=J.getContextIndices(Q)||new Map,q=this.normalizePath(W),L=this.container.resolve(Q),G=X.prefix!==void 0?X.prefix:this.globalPrefix,U=X.version!==void 0?X.version:this.globalVersion;for(let z of Y){let{path:b,method:E,handlerName:P,version:N,prefix:K}=z,R=K!==void 0?K:G,A=!O(R)?this.normalizePath(R):"",B=N!==void 0?N:U,F=this.normalizePath(b);if(O(B)){this.registerRoute(L,z,Z,$,Q,A,"",q,F,E);continue}if(B===x){this.registerRoute(L,z,Z,$,Q,A,"",q,F,E),this.registerRoute(L,z,Z,$,Q,A,"/:version{v[0-9]+}",q,F,E);continue}if(Array.isArray(B)){for(let D of B){let k=this.formatVersionSegment(D);this.registerRoute(L,z,Z,$,Q,A,k,q,F,E)}continue}let S=this.formatVersionSegment(B);this.registerRoute(L,z,Z,$,Q,A,S,q,F,E)}}registerRoute(Q,W,X,Y,Z,$,q,L,G,U){let{handlerName:z}=W,b=this.buildRoutePath($,q,L,G),E=Q[z].bind(Q),P=X.get(z)||[],N=Y.get(z),K=_.getHandlerMiddleware(Z,z),R=_.getHandlerPipes(Z,z);H.registerRoute({controller:Z.name,handler:z,method:U,prefix:$,version:q,route:L,path:G,fullPath:b,parameters:P});let A=async(B)=>{try{B.set("controllerClass",Z),B.set("handlerName",String(z));let F=_.getHandlerGuards(Z,z);for(let k of F)if(!await k.canActivate(B))throw new p(403,{message:"Forbidden"});let S=new Array(E.length);for(let k of P){let g=k.factory(k.data,B),c=await _.executePipes(g,{type:k.type,metatype:k.metatype,data:k.data},R);S[k.index]=c}let D=await E(...S);if(N!==void 0)return D;if(O(D))return B.json(null);if(v(D))return B.text(D);return B.json(D)}catch(F){return _.handleException(F,B)}};this.registerRouteHandler(U,b,K,A)}}class d{hono;container;routeManager;options;constructor(Q={}){this.options=C(Q)?Q:{},this.hono=new s(this.options.hono),this.container=this.options.container||new f,this.setupComponents(),this.setupErrorHandlers(),this.routeManager=new u(this.hono,this.container,{prefix:this.options.routing?.prefix,version:this.options.routing?.version})}setupComponents(){_.init(this.container),_.setupGlobalComponents(this.options)}setupErrorHandlers(){this.hono.notFound(this.options.notFound||I.handle()),this.hono.onError(this.options.onError||M.handle())}resolvePlugin(Q){if(m(Q))return new Q;return Q}async register(Q){let W=await _.registerModule(Q,this.container);for(let X of W)await this.routeManager.registerController(X);return this}static async create(Q,W={}){let X=new d(W),Y=(W.plugins||[]).map((Z)=>X.resolvePlugin(Z));for(let Z of Y)if(Z.beforeModulesRegistered)await Z.beforeModulesRegistered(X,X.hono);await X.register(Q);for(let Z of Y)if(Z.afterModulesRegistered)await Z.afterModulesRegistered(X,X.hono);return{app:X,hono:X.getApp()}}getApp(){return this.hono}getRoutes(){return H.getRoutes()}}function oQ(Q="",W={}){return(X)=>{J.setControllerPath(X,Q),J.setControllerOptions(X,W)}}var eQ=V("get"),QW=V("post"),WW=V("put"),XW=V("delete"),YW=V("patch"),ZW=V("options"),$W=V("all");function _W(Q={}){return(W)=>{J.setModuleOptions(W,Q)}}var LW=j("body",async(Q,W)=>{let X=await W.req.json();return Q?X[Q]:X}),jW=j("param",(Q,W)=>{return Q?W.req.param(Q):W.req.param()}),kW=j("query",(Q,W)=>{return Q?W.req.query(Q):W.req.query()}),UW=j("header",(Q,W)=>{return Q?W.req.header(Q):W.req.header()}),FW=j("request",(Q,W)=>W.req),GW=j("request",(Q,W)=>W.req),EW=j("response",(Q,W)=>W.res),VW=j("response",(Q,W)=>W.res),AW=j("context",(Q,W)=>W),DW=j("context",(Q,W)=>W),OW=j("variable",(Q,W)=>W.get(Q)),bW=j("variable",(Q,W)=>W.get(Q));function KW(){return(Q)=>{J.addService(Q)}}function TW(Q,...W){return(X,Y)=>{if(Y){let Z=X.constructor;_.registerHandler(Q,Z,Y,...W)}else _.registerController(Q,X,...W)}}function fW(...Q){return(W,X)=>{if(X){let Y=W.constructor;_.registerHandler("filter",Y,X,...Q)}else _.registerController("filter",W,...Q)}}function xW(...Q){return(W,X)=>{if(X){let Y=W.constructor;_.registerHandler("guard",Y,X,...Q)}else _.registerController("guard",W,...Q)}}function yW(...Q){return(W,X)=>{if(X){let Y=W.constructor;_.registerHandler("middleware",Y,X,...Q)}else _.registerController("middleware",W,...Q)}}function hW(...Q){return(W,X)=>{if(X){let Y=W.constructor;_.registerHandler("pipe",Y,X,...Q)}else _.registerController("pipe",W,...Q)}}export{wQ as stripEndSlash,y as normalizePath,HQ as isUndefined,SQ as isSymbol,v as isString,NQ as isPlainObject,C as isObject,KQ as isNumber,O as isNil,h as isFunction,RQ as isEmpty,m as isConstructor,j as createParamDecorator,V as createHttpMethodDecorator,T as createErrorResponse,TQ as addLeadingSlash,bW as Variable,OW as Var,x as VERSION_NEUTRAL,hW as UsePipes,yW as UseMiddleware,xW as UseGuards,fW as UseFilters,TW as UseComponent,KW as Service,H as RouteRegistry,u as RouteManager,VW as Response,EW as Res,GW as Request,FW as Req,kW as Query,WW as Put,QW as Post,YW as Patch,jW as Param,ZW as Options,I as NotFoundHandler,_W as Module,J as MetadataRegistry,UW as Header,eQ as Get,M as ErrorHandler,XW as Delete,AW as Ctx,oQ as Controller,DW as Context,f as Container,_ as ComponentManager,LW as Body,d as Application,$W as All};
1
+ import"reflect-metadata";import{Hono as e}from"hono";class x{instances=new Map;resolve($,_=new Set){if(this.instances.has($))return this.instances.get($);if(_.has($))throw new Error(`Circular dependency detected: ${[..._.keys(),$].map((X)=>X.name).join(" -> ")}`);_.add($);let q=(Reflect.getMetadata("design:paramtypes",$)||[]).map((X)=>{return this.resolve(X,new Set(_))}),Q=new $(...q);return this.instances.set($,Q),Q}register($,_){this.instances.set($,_)}}import{HTTPException as a}from"hono/http-exception";function f($,_,Y){let q=new Date().toISOString(),Q=_.get("requestId"),X=_.req.path;if($ instanceof a)return{response:{status:Y?.status||$.status,message:Y?.title||$.message,timestamp:q,path:X,requestId:Q,code:Y?.code,details:Y?.additionalDetails,...Y?.detail&&{detail:Y.detail}},status:Y?.status||$.status};if($.statusCode||$.status){let A=$.statusCode||$.status,k=Y?.status||A;return{response:{status:k,message:Y?.title||$.message,timestamp:q,path:X,requestId:Q,code:Y?.code||$.name,details:Y?.additionalDetails,...Y?.detail&&{detail:Y.detail}},status:k}}let W=Y?.status||500;return{response:{status:W,message:Y?.title||$.message,timestamp:q,path:X,requestId:Q,code:Y?.code||$.name,details:Y?.additionalDetails||{stack:$.stack},...Y?.detail&&{detail:Y.detail}},status:W}}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 global=new Map([["middleware",new Set],["guard",new Set],["pipe",new Set],["filter",new Set]]);static globalWithPath=new Map([["middleware",[]],["guard",[]],["pipe",[]],["filter",[]]]);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 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 registerGlobalWithPath($,_){this.globalWithPath.get($).push(_)}static getGlobal($){return this.global.get($)}static getGlobalWithPath($){return this.globalWithPath.get($)||[]}static registerController($,_,Y){let q=this.controller.get($);if(!q.has(_))q.set(_,[]);q.get(_).push(Y)}static getController($,_){return this.controller.get($).get(_)||[]}static registerHandler($,_,Y){let q=this.handler.get($);if(!q.has(_))q.set(_,[]);q.get(_).push(Y)}static getHandler($,_){return this.handler.get($).get(_)||[]}}class S{static routes=[];static registerRoute($){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 V($){return(_="",Y={})=>{return(q,Q,X)=>{let W=q.constructor;Z.addRoute(W,{path:_,method:$,handlerName:Q,parameterMetadata:[],version:Y.version,prefix:Y.prefix})}}}function j($,_){return(Y)=>{return(q,Q,X)=>{let W=q.constructor;if(!Z.getParameters(W).size)Z.setParameterMap(W,new Map);let L=Z.getParameters(W);if(!L.has(Q))L.set(Q,[]);let k=Reflect.getMetadata("design:paramtypes",q,Q)?.[X];if(L.get(Q).push({index:X,name:$,data:Y,factory:_,metatype:k}),$==="context"){if(!Z.getContextIndices(W).size)Z.setContextIndices(W,new Map);Z.getContextIndices(W).set(Q,X)}}}}class I{static handle(){return async($,_)=>{return _.json(f($,_))}}}class C{static handle(){return async($)=>{return $.json({message:`Not Found - ${$.req.path}`},404)}}}var S$=($)=>typeof $==="undefined",O=($)=>$===null||typeof $==="undefined",v=($)=>$!==null&&typeof $==="object",N$=($)=>{if(!v($))return!1;let _=Object.getPrototypeOf($);if(_===null)return!0;let Y=Object.prototype.hasOwnProperty.call(_,"constructor")&&_.constructor;return typeof Y==="function"&&Y instanceof Y&&Function.prototype.toString.call(Y)===Function.prototype.toString.call(Object)},c=($)=>typeof $==="function",y=($)=>typeof $==="string",w$=($)=>typeof $==="number",K$=($)=>$.length===0,R$=($)=>typeof $==="symbol",P$=($)=>typeof $==="string"?$.charAt(0)!=="/"?"/"+$:$:"",T=($)=>$?$.startsWith("/")?("/"+$.replace(/\/+$/,"")).replace(/\/+/g,"/"):"/"+$.replace(/\/+$/,""):"/",f$=($)=>$.endsWith("/")?$.slice(0,-1):$,i=($)=>{return c($)&&!O($.prototype)&&!c($.prototype)&&Object.getOwnPropertyNames($.prototype).length>1};var N=($)=>$!==null&&typeof $==="object";function o($){return N($)&&"path"in $&&"component"in $}class J{static container;static init($){this.container=$}static setupGlobalComponents($){let _=$.components||{},Y=(q,Q)=>{for(let X of Q)if(o(X))Z.registerGlobalWithPath(q,X);else Z.registerGlobal(q,X)};if(_.middleware)Y("middleware",_.middleware);if(_.guards)Y("guard",_.guards);if(_.pipes)Y("pipe",_.pipes);if(_.filters)Y("filter",_.filters)}static registerController($,_,...Y){Y.forEach((q)=>{Z.registerController($,_,q)})}static registerHandler($,_,Y,...q){let Q=`${_.name}:${String(Y)}`;q.forEach((X)=>{Z.registerHandler($,Q,X)})}static getComponents($,_,Y,q){let Q=`${_.name}:${String(Y)}`,X=Z.getHandler($,Q),W=Z.getController($,_);if($==="middleware")return[...W,...X];let L=Array.from(Z.getGlobal($)),k=Z.getGlobalWithPath($).filter((B)=>q.startsWith(T(B.path))).map((B)=>B.component);return[...L,...k,...W,...X]}static resolveMiddleware($){return $.map((_)=>{if(N(_)&&"use"in _)return _.use.bind(_);let Y=this.container.resolve(_);return Y.use.bind(Y)})}static getHandlerMiddleware($,_){let Y=this.getComponents("middleware",$,_,"");return this.resolveMiddleware(Y)}static getGlobalMiddleware(){let $=Array.from(Z.getGlobal("middleware"));return this.resolveMiddleware($)}static getGlobalMiddlewareWithPath(){return Z.getGlobalWithPath("middleware").map((_)=>({path:_.path,middleware:this.resolveMiddleware([_.component])[0]}))}static resolveGuards($){return $.map((_)=>{if(N(_)&&"canActivate"in _)return _;return this.container.resolve(_)})}static getHandlerGuards($,_,Y){let q=this.getComponents("guard",$,_,Y);return this.resolveGuards(q)}static resolvePipes($){return $.map((_)=>{if(N(_)&&"transform"in _)return _;return this.container.resolve(_)})}static getHandlerPipes($,_,Y){let q=this.getComponents("pipe",$,_,Y);return this.resolvePipes(q)}static async executePipes($,_,Y){let q=$;for(let Q of Y)q=await Q.transform(q,_);return q}static async handleException($,_){let Y=_.get("controllerClass"),q=_.get("handlerName"),Q=_.req.path;if(Y&&q){let A=Z.getHandler("filter",`${Y.name}:${q}`);if(A.length>0){let k=await this.executeFilters(A,$,_);if(k)return k}}if(Y){let A=Z.getController("filter",Y);if(A.length>0){let k=await this.executeFilters(A,$,_);if(k)return k}}let X=Array.from(Z.getGlobal("filter")),W=Z.getGlobalWithPath("filter").filter((A)=>Q.startsWith(T(A.path))).map((A)=>A.component),L=[...X,...W];if(L.length>0){let A=await this.executeFilters(L,$,_);if(A)return A}return console.log("No filter handled the exception, creating default response"),_.json(f($,_))}static async executeFilters($,_,Y){for(let q of $){let Q;if(N(q)&&"catch"in q)Q=q;else Q=this.container.resolve(q);try{let X=await Q.catch(_,Y);if(X!==void 0)return X}catch(X){console.error("Error in exception filter:",X)}}return}static async registerModule($,_){let Y=Z.getModuleOptions($);if(!Y)throw new Error(`Module ${$.name} is not properly decorated with @Module()`);let q=[];if(Y.imports&&Y.imports.length>0)for(let Q of Y.imports){let X=await this.registerModule(Q,_);q.push(...X)}if(Y.services&&Y.services.length>0)for(let Q of Y.services)_.resolve(Q);if(Y.controllers&&Y.controllers.length>0)q.push(...Y.controllers);return q}}import{HTTPException as t}from"hono/http-exception";var u=Symbol("VERSION_NEUTRAL");class g{hono;container;globalPrefix;globalVersion;constructor($,_,Y={}){this.hono=$,this.container=_,this.globalPrefix=Y.prefix!==void 0?this.normalizePath(Y.prefix):void 0,this.globalVersion=Y.version,this.applyGlobalMiddleware()}applyGlobalMiddleware(){let $=J.getGlobalMiddleware();for(let Y of $)this.hono.use("*",Y);let _=J.getGlobalMiddlewareWithPath();for(let Y of _)this.hono.use(Y.path,Y.middleware)}normalizePath($){if(y($))return T($);return $?`/${$}`:""}registerRouteHandler($,_,Y,q){if(Y.length>0)this.hono.on($.toUpperCase(),_,...Y,q);else this.hono.on($.toUpperCase(),_,q)}buildRoutePath($,_,Y,q){return T(`${$}${_}${Y}${q}`)}formatVersionSegment($){if(O($))return"";return $===u?"":`/v${String($)}`}async registerController($){let _=Z.getControllerPath($)||"",Y=Z.getControllerOptions($)||{},q=Z.getRoutes($)||[],Q=Z.getParameters($)||new Map,X=Z.getContextIndices($)||new Map,W=this.normalizePath(_),L=this.container.resolve($),A=Y.prefix!==void 0?Y.prefix:this.globalPrefix,k=Y.version!==void 0?Y.version:this.globalVersion;for(let B of q){let{path:H,method:F,handlerName:M,version:w,prefix:K}=B,R=K!==void 0?K:A,b=!O(R)?this.normalizePath(R):"",z=w!==void 0?w:k,G=this.normalizePath(H);if(O(z)){this.registerRoute(L,B,Q,X,$,b,"",W,G,F);continue}if(z===u){this.registerRoute(L,B,Q,X,$,b,"",W,G,F),this.registerRoute(L,B,Q,X,$,b,"/:version{v[0-9]+}",W,G,F);continue}if(Array.isArray(z)){for(let D of z){let E=this.formatVersionSegment(D);this.registerRoute(L,B,Q,X,$,b,E,W,G,F)}continue}let P=this.formatVersionSegment(z);this.registerRoute(L,B,Q,X,$,b,P,W,G,F)}}registerRoute($,_,Y,q,Q,X,W,L,A,k){let{handlerName:B}=_,H=this.buildRoutePath(X,W,L,A),F=$[B].bind($),M=Y.get(B)||[],w=q.get(B),K=J.getHandlerMiddleware(Q,B),R=J.getHandlerPipes(Q,B,H);S.registerRoute({controller:Q.name,handler:B,method:k,prefix:X,version:W,route:L,path:A,fullPath:H,parameters:M});let b=async(z)=>{try{z.set("controllerClass",Q),z.set("handlerName",String(B));let G=J.getHandlerGuards(Q,B,z.req.routePath);for(let E of G)if(!await E.canActivate(z))throw new t(403,{message:"Forbidden"});let P=new Array(F.length);for(let E of M){let d=E.factory(E.data,z),r=await J.executePipes(d,{type:E.type,metatype:E.metatype,data:E.data},R);P[E.index]=r}let D=await F(...P);if(w!==void 0)return D;if(O(D))return z.json(null);if(y(D))return z.text(D);return z.json(D)}catch(G){return J.handleException(G,z)}};this.registerRouteHandler(k,H,K,b)}}class p{hono;container;routeManager;options;constructor($={}){this.options=v($)?$:{},this.hono=new e(this.options.hono),this.container=this.options.container||new x,this.setupComponents(),this.setupErrorHandlers(),this.routeManager=new g(this.hono,this.container,{prefix:this.options.routing?.prefix,version:this.options.routing?.version})}setupComponents(){J.init(this.container),J.setupGlobalComponents(this.options)}setupErrorHandlers(){this.hono.notFound(this.options.notFound||C.handle()),this.hono.onError(this.options.onError||I.handle())}resolvePlugin($){if(i($))return new $;return $}async register($){let _=await J.registerModule($,this.container);for(let Y of _)await this.routeManager.registerController(Y);return this}static async create($,_={}){let Y=new p(_),q=(_.plugins||[]).map((Q)=>Y.resolvePlugin(Q));for(let Q of q)if(Q.beforeModulesRegistered)await Q.beforeModulesRegistered(Y,Y.hono);await Y.register($);for(let Q of q)if(Q.afterModulesRegistered)await Q.afterModulesRegistered(Y,Y.hono);return{app:Y,hono:Y.getApp()}}getApp(){return this.hono}getRoutes(){return S.getRoutes()}}import{html as U,raw as h}from"hono/html";var $$={type:"website",locale:"en_US"},m=($)=>{if(!$)return"";return Object.entries($).map(([_,Y])=>{if(typeof Y==="boolean")return Y?_:"";let q=String(Y).replace(/"/g,"&quot;");return`${_}="${q}"`}).filter(Boolean).join(" ")},X_=($)=>{let _={...$$,...$};return U`
2
+ <!DOCTYPE html>
3
+ <html lang="${_.locale?.split("_")[0]||"en"}" ${h(m(_.htmlAttributes))}>
4
+ <head ${h(m(_.headAttributes))}>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ ${_.csp?U`<meta http-equiv="Content-Security-Policy" content="${_.csp}" />`:""}
8
+ <title>${_.title}</title>
9
+ ${_.description?U`<meta name="description" content="${_.description}" />`:""}
10
+
11
+ <!-- Open Graph / Facebook -->
12
+ <meta prefix="og: http://ogp.me/ns#" />
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}" />`:""}
20
+
21
+ <!-- Twitter -->
22
+ <meta
23
+ name="twitter:card"
24
+ content="${_.twitterCard||(_.image?"summary_large_image":"summary")}"
25
+ />
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}" />`:""}
29
+
30
+ <!-- Custom Meta Tags -->
31
+ ${_.customMeta?_.customMeta.map((Y)=>{let q=Y.name?`name="${Y.name}"`:"",Q=Y.property?`property="${Y.property}"`:"";return U`<meta ${q} ${Q} content="${Y.content}" />`}):""}
32
+
33
+ <!-- Favicon -->
34
+ ${_.favicon?U`<link rel="icon" href="${_.favicon}" />`:""}
35
+
36
+ <!-- Stylesheets -->
37
+ ${_.stylesheets?_.stylesheets.map((Y)=>U`<link rel="stylesheet" href="${Y}" />`):""}
38
+
39
+ <!-- Scripts -->
40
+ ${_.scripts?_.scripts.map((Y)=>{if(typeof Y==="string")return U`<script src="${Y}"></script>`;let{src:q,async:Q,defer:X}=Y;if(Q&&X)return U`<script src="${q}" async defer></script>`;if(Q)return U`<script src="${q}" async></script>`;if(X)return U`<script src="${q}" defer></script>`;return U`<script src="${q}"></script>`}):""}
41
+ </head>
42
+ <body ${h(m(_.bodyAttributes))}>
43
+ ${_.children}
44
+ </body>
45
+ </html>
46
+ `};function s($="",_={}){return(Y)=>{Z.setControllerPath(Y,$),Z.setControllerOptions(Y,_)}}var l=V("get"),L_=V("post"),k_=V("put"),z_=V("delete"),j_=V("patch"),E_=V("options"),G_=V("all");function n($={}){return(_)=>{Z.setModuleOptions(_,$)}}function T_($="",_={}){return s($,_)}var S_=l;function N_($={}){return n({imports:$.imports,services:$.services,controllers:($.views||[]).concat($.controllers||[])})}var R_=j("body",async($,_)=>{let Y=await _.req.json();return $?Y[$]:Y}),P_=j("param",($,_)=>{return $?_.req.param($):_.req.param()}),f_=j("query",($,_)=>{return $?_.req.query($):_.req.query()}),M_=j("header",($,_)=>{return $?_.req.header($):_.req.header()}),x_=j("request",($,_)=>_.req),I_=j("request",($,_)=>_.req),C_=j("response",($,_)=>_.res),v_=j("response",($,_)=>_.res),y_=j("context",($,_)=>_),u_=j("context",($,_)=>_),g_=j("variable",($,_)=>_.get($)),h_=j("variable",($,_)=>_.get($));function c_(){return($)=>{Z.addService($)}}function s_($,..._){return(Y,q)=>{if(q){let Q=Y.constructor;J.registerHandler($,Q,q,..._)}else J.registerController($,Y,..._)}}function r_(...$){return(_,Y)=>{if(Y){let q=_.constructor;J.registerHandler("filter",q,Y,...$)}else J.registerController("filter",_,...$)}}function t_(...$){return(_,Y)=>{if(Y){let q=_.constructor;J.registerHandler("guard",q,Y,...$)}else J.registerController("guard",_,...$)}}function _Y(...$){return(_,Y)=>{if(Y){let q=_.constructor;J.registerHandler("middleware",q,Y,...$)}else J.registerController("middleware",_,...$)}}function QY(...$){return(_,Y)=>{if(Y){let q=_.constructor;J.registerHandler("pipe",q,Y,...$)}else J.registerController("pipe",_,...$)}}export{f$ as stripEndSlash,T as normalizePath,S$ as isUndefined,R$ as isSymbol,y as isString,N$ as isPlainObject,v as isObject,w$ as isNumber,O as isNil,c as isFunction,K$ as isEmpty,i as isConstructor,j as createParamDecorator,V as createHttpMethodDecorator,f as createErrorResponse,P$ as addLeadingSlash,T_ as View,h_ as Variable,g_ as Var,u as VERSION_NEUTRAL,QY as UsePipes,_Y as UseMiddleware,t_ as UseGuards,r_ as UseFilters,s_ as UseComponent,c_ as Service,S as RouteRegistry,g as RouteManager,v_ as Response,C_ as Res,I_ as Request,x_ as Req,f_ as Query,k_ as Put,L_ as Post,j_ as Patch,P_ as Param,S_ as Page,E_ as Options,C as NotFoundHandler,N_ as MvcModule,n as Module,Z as MetadataRegistry,X_ as Layout,M_ as Header,l as Get,I as ErrorHandler,z_ as Delete,y_ as Ctx,s as Controller,u_ as Context,x as Container,J as ComponentManager,R_ as Body,p as Application,G_ as All};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Configuration for a component with a path
3
+ */
4
+ export interface ComponentWithpath<T> {
5
+ path: string;
6
+ component: T;
7
+ }
@@ -1,7 +1,8 @@
1
1
  import type { Context } from 'hono';
2
2
  import type { VERSION_NEUTRAL } from '../constants';
3
- import type { FilterType, GuardType, MiddlewareType, PipeType, PluginType } from '../interfaces';
3
+ import type { ComponentWithpath } from './component-with-path.interface';
4
4
  import type { DiContainer } from './di-container.interface';
5
+ import type { FilterType, GuardType, MiddlewareType, PipeType, PluginType } from './index';
5
6
  /**
6
7
  * Options for configuring the Honest application
7
8
  */
@@ -49,19 +50,19 @@ export interface HonestOptions {
49
50
  /**
50
51
  * Global middleware to apply to all routes
51
52
  */
52
- middleware?: MiddlewareType[];
53
+ middleware?: (MiddlewareType | ComponentWithpath<MiddlewareType>)[];
53
54
  /**
54
55
  * Global guards to apply to all routes
55
56
  */
56
- guards?: GuardType[];
57
+ guards?: (GuardType | ComponentWithpath<GuardType>)[];
57
58
  /**
58
59
  * Global pipes to apply to all routes
59
60
  */
60
- pipes?: PipeType[];
61
+ pipes?: (PipeType | ComponentWithpath<PipeType>)[];
61
62
  /**
62
63
  * Global exception filters to apply to all routes
63
64
  */
64
- filters?: FilterType[];
65
+ filters?: (FilterType | ComponentWithpath<FilterType>)[];
65
66
  };
66
67
  /**
67
68
  * Plugins for extending the application functionality
@@ -1,5 +1,6 @@
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
+ import type { ComponentWithpath } from '../interfaces/component-with-path.interface';
3
4
  import { type ComponentType, type ComponentTypeMap } from '../registries';
4
5
  import type { Constructor } from '../types';
5
6
  /**
@@ -28,18 +29,12 @@ export declare class ComponentManager {
28
29
  */
29
30
  static setupGlobalComponents(options: {
30
31
  components?: {
31
- middleware?: any[];
32
- guards?: any[];
33
- pipes?: any[];
34
- filters?: any[];
32
+ middleware?: (MiddlewareType | ComponentWithpath<MiddlewareType>)[];
33
+ guards?: (GuardType | ComponentWithpath<GuardType>)[];
34
+ pipes?: (PipeType | ComponentWithpath<PipeType>)[];
35
+ filters?: (FilterType | ComponentWithpath<FilterType>)[];
35
36
  };
36
37
  }): 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
38
  /**
44
39
  * Registers a component at the controller level
45
40
  * @param type - The type of component to register
@@ -60,9 +55,10 @@ export declare class ComponentManager {
60
55
  * @param type - The type of component to get
61
56
  * @param controller - The controller class
62
57
  * @param handlerName - The handler method name
58
+ * @param routePath - The route path
63
59
  * ..returns An array of component instances
64
60
  */
65
- static getComponents<T extends ComponentType>(type: T, controller: Constructor, handlerName: string | symbol): ComponentTypeMap[T][];
61
+ static getComponents<T extends ComponentType>(type: T, controller: Constructor, handlerName: string | symbol, routePath: string): ComponentTypeMap[T][];
66
62
  /**
67
63
  * Resolves middleware classes or instances to middleware functions
68
64
  * @param middlewareItems - The middleware classes or instances to resolve
@@ -73,6 +69,7 @@ export declare class ComponentManager {
73
69
  * Gets middleware for a specific handler
74
70
  * @param controller - The controller class
75
71
  * @param handlerName - The handler method name
72
+ * @param routePath - The route path
76
73
  * ..returns An array of middleware functions
77
74
  */
78
75
  static getHandlerMiddleware(controller: Constructor, handlerName: string | symbol): ((c: Context, next: Next) => Promise<Response | void>)[];
@@ -81,6 +78,14 @@ export declare class ComponentManager {
81
78
  * ..returns An array of middleware functions
82
79
  */
83
80
  static getGlobalMiddleware(): ((c: Context, next: Next) => Promise<Response | void>)[];
81
+ /**
82
+ * Gets global middleware with their paths
83
+ * @returns An array of objects with path and middleware function
84
+ */
85
+ static getGlobalMiddlewareWithPath(): {
86
+ path: string;
87
+ middleware: (c: Context, next: Next) => Promise<void | Response>;
88
+ }[];
84
89
  /**
85
90
  * Resolves guard classes or instances to guard instances
86
91
  * @param guardItems - The guard classes or instances to resolve
@@ -91,9 +96,10 @@ export declare class ComponentManager {
91
96
  * Gets guards for a specific handler
92
97
  * @param controller - The controller class
93
98
  * @param handlerName - The handler method name
99
+ * @param routePath - The route path
94
100
  * ..returns An array of guard instances
95
101
  */
96
- static getHandlerGuards(controller: Constructor, handlerName: string | symbol): IGuard[];
102
+ static getHandlerGuards(controller: Constructor, handlerName: string | symbol, routePath: string): IGuard[];
97
103
  /**
98
104
  * Resolves pipe classes or instances to pipe instances
99
105
  * @param pipeItems - The pipe classes or instances to resolve
@@ -104,9 +110,10 @@ export declare class ComponentManager {
104
110
  * Gets pipes for a specific handler
105
111
  * @param controller - The controller class
106
112
  * @param handlerName - The handler method name
113
+ * @param routePath - The route path
107
114
  * ..returns An array of pipe instances
108
115
  */
109
- static getHandlerPipes(controller: Constructor, handlerName: string | symbol): IPipe[];
116
+ static getHandlerPipes(controller: Constructor, handlerName: string | symbol, routePath: string): IPipe[];
110
117
  /**
111
118
  * Executes a series of pipes on a value
112
119
  * Pipes are executed in sequence, with each pipe's output feeding into the next pipe
@@ -1,4 +1,5 @@
1
1
  import type { ControllerOptions, FilterType, GuardType, MiddlewareType, ModuleOptions, ParameterMetadata, PipeType, RouteDefinition } from '../interfaces';
2
+ import type { ComponentWithpath } from '../interfaces/component-with-path.interface';
2
3
  import type { Constructor } from '../types';
3
4
  /**
4
5
  * Available component types that can be registered at different levels in the application
@@ -69,6 +70,11 @@ export declare class MetadataRegistry {
69
70
  * Components registered here apply to all routes
70
71
  */
71
72
  private static readonly global;
73
+ /**
74
+ * Registry for global-level components with a path
75
+ * Components registered here apply to routes matching the path
76
+ */
77
+ private static readonly globalWithPath;
72
78
  /**
73
79
  * Registry for controller-level components
74
80
  * Components registered here apply to all routes in a specific controller
@@ -149,10 +155,18 @@ export declare class MetadataRegistry {
149
155
  * Register a component at the global level
150
156
  */
151
157
  static registerGlobal<T extends ComponentType>(type: T, component: ComponentTypeMap[T]): void;
158
+ /**
159
+ * Register a component with a path at the global level
160
+ */
161
+ static registerGlobalWithPath<T extends ComponentType>(type: T, component: ComponentWithpath<ComponentTypeMap[T]>): void;
152
162
  /**
153
163
  * Get all global components of a specific type
154
164
  */
155
165
  static getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
166
+ /**
167
+ * Get all global components with a path of a specific type
168
+ */
169
+ static getGlobalWithPath<T extends ComponentType>(type: T): ComponentWithpath<ComponentTypeMap[T]>[];
156
170
  /**
157
171
  * Register a component at the controller level
158
172
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "honestjs",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "author": "Orkhan Karimov <karimovok1@gmail.com> (https://github.com/kerimovok)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,8 +9,15 @@
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/index.js",
11
11
  "devDependencies": {
12
+ "@eslint/js": "^9.30.1",
12
13
  "@types/bun": "latest",
13
- "prettier": "3.5.3"
14
+ "eslint": "^9.30.1",
15
+ "eslint-config-prettier": "^10.1.5",
16
+ "globals": "^16.3.0",
17
+ "husky": "^9.1.7",
18
+ "lint-staged": "^16.1.2",
19
+ "prettier": "3.5.3",
20
+ "typescript-eslint": "^8.35.1"
14
21
  },
15
22
  "peerDependencies": {
16
23
  "hono": "^4",
@@ -41,11 +48,20 @@
41
48
  },
42
49
  "scripts": {
43
50
  "clean": "rm -rf dist",
51
+ "prepare": "husky",
44
52
  "build": "bun run clean && bun build ./src/index.ts --outdir=dist --target=node --minify --external hono --external reflect-metadata && bun run build:types",
45
53
  "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
54
+ "lint": "eslint .",
55
+ "lint:fix": "eslint . --fix",
46
56
  "format": "prettier --write .",
47
57
  "format:check": "prettier --check ."
48
58
  },
59
+ "lint-staged": {
60
+ "**/*.{js,mjs,cjs,ts,mts,cts}": [
61
+ "eslint --fix",
62
+ "prettier --write"
63
+ ]
64
+ },
49
65
  "type": "module",
50
66
  "types": "dist/index.d.ts"
51
67
  }