honestjs 0.1.0 → 0.1.2

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,5 +1,3 @@
1
- # Honest Framework
2
-
3
1
  <p align="center">
4
2
  <a href="https://github.com/honestjs/" target="blank"><img src="https://avatars.githubusercontent.com/u/197956909" width="120" alt="Honest Logo" /></a>
5
3
  </p>
@@ -124,4 +122,4 @@ export default hono
124
122
 
125
123
  ## License
126
124
 
127
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
125
+ MIT © [Orkhan Karimov](https://github.com/kerimovok)
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import"reflect-metadata";import{Hono as s}from"hono";class w{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 P(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 j=Q.statusCode||Q.status,z=X?.status||j;return{response:{status:z,message:X?.title||Q.message,timestamp:Y,path:$,requestId:Z,code:X?.code||Q.name,details:X?.additionalDetails,...X?.detail&&{detail:X.detail}},status:z}}let J=X?.status||500;return{response:{status:J,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:J}}class B{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 N{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 E(Q){return(W="",X={})=>{return(Y,Z,$)=>{let J=Y.constructor;B.addRoute(J,{path:W,method:Q,handlerName:Z,parameterMetadata:[],version:X.version})}}}function _(Q,W){return(X)=>{return(Y,Z,$)=>{let J=Y.constructor;if(!B.getParameters(J).size)B.setParameterMap(J,new Map);let U=B.getParameters(J);if(!U.has(Z))U.set(Z,[]);let z=Reflect.getMetadata("design:paramtypes",Y,Z)?.[$];if(U.get(Z).push({index:$,name:Q,data:X,factory:W,metatype:z}),Q==="context"){if(!B.getContextIndices(J).size)B.setContextIndices(J,new Map);B.getContextIndices(J).set(Z,$)}}}}class f{static handle(){return async(Q,W)=>{return W.json(P(Q,W))}}}class M{static handle(){return async(Q)=>{return Q.json({message:`Not Found - ${Q.req.path}`},404)}}}var S=(Q)=>Q!==null&&typeof Q==="object";class q{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)=>{B.registerGlobal(Q,X)})}static registerController(Q,W,...X){X.forEach((Y)=>{B.registerController(Q,W,Y)})}static registerHandler(Q,W,X,...Y){let Z=`${W.name}:${String(X)}`;Y.forEach(($)=>{B.registerHandler(Q,Z,$)})}static getComponents(Q,W,X){let Y=`${W.name}:${String(X)}`,Z=B.getHandler(Q,Y),$=B.getController(Q,W);return[...Array.from(B.getGlobal(Q)),...$,...Z]}static resolveMiddleware(Q){return Q.map((W)=>{if(S(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(B.getGlobal("middleware"));return this.resolveMiddleware(Q)}static resolveGuards(Q){return Q.map((W)=>{if(S(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(S(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 $=B.getHandler("filter",`${X.name}:${Y}`);if($.length>0){let J=await this.executeFilters($,Q,W);if(J)return J}}if(X){let $=B.getController("filter",X);if($.length>0){let J=await this.executeFilters($,Q,W);if(J)return J}}let Z=Array.from(B.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(P(Q,W))}static async executeFilters(Q,W,X){for(let Y of Q){let Z;if(S(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=B.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 bQ=(Q)=>typeof Q==="undefined",O=(Q)=>Q===null||typeof Q==="undefined",I=(Q)=>Q!==null&&typeof Q==="object",NQ=(Q)=>{if(!I(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",C=(Q)=>typeof Q==="string",KQ=(Q)=>typeof Q==="number",RQ=(Q)=>Q.length===0,TQ=(Q)=>typeof Q==="symbol",PQ=(Q)=>typeof Q==="string"?Q.charAt(0)!=="/"?"/"+Q:Q:"",v=(Q)=>Q?Q.startsWith("/")?("/"+Q.replace(/\/+$/,"")).replace(/\/+/g,"/"):"/"+Q.replace(/\/+$/,""):"/",SQ=(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 y{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=q.getGlobalMiddleware();for(let W of Q)this.hono.use("*",W)}normalizePath(Q){if(C(Q))return v(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 v(`${Q}${W}${X}${Y}`)}formatVersionSegment(Q){if(O(Q))return"";return Q===x?"":`/v${String(Q)}`}async registerController(Q){let W=B.getControllerPath(Q)||"",X=B.getControllerOptions(Q)||{},Y=B.getRoutes(Q)||[],Z=B.getParameters(Q)||new Map,$=B.getContextIndices(Q)||new Map,J=this.container.resolve(Q),U=!O(X.prefix)?X.prefix:this.globalPrefix,j=!O(U)?this.normalizePath(U):"",z=this.normalizePath(W),L=X.version!==void 0?X.version:this.globalVersion;for(let G of Y){let{path:K,method:F,handlerName:u,version:R}=G,A=R!==void 0?R:L,D=this.normalizePath(K);if(O(A)){this.registerRoute(J,G,Z,$,Q,j,"",z,D,F);continue}if(A===x){this.registerRoute(J,G,Z,$,Q,j,"",z,D,F),this.registerRoute(J,G,Z,$,Q,j,"/:version{v[0-9]+}",z,D,F);continue}if(Array.isArray(A)){for(let H of A){let T=this.formatVersionSegment(H);this.registerRoute(J,G,Z,$,Q,j,T,z,D,F)}continue}let k=this.formatVersionSegment(A);this.registerRoute(J,G,Z,$,Q,j,k,z,D,F)}}registerRoute(Q,W,X,Y,Z,$,J,U,j,z){let{handlerName:L}=W,G=this.buildRoutePath($,J,U,j),K=Q[L].bind(Q),F=X.get(L)||[],u=Y.get(L),R=q.getHandlerMiddleware(Z,L),A=q.getHandlerPipes(Z,L);N.registerRoute({controller:Z.name,handler:L,method:z,prefix:$,version:J,route:U,path:j,fullPath:G,parameters:F});let D=async(k)=>{try{k.set("controllerClass",Z),k.set("handlerName",String(L));let H=q.getHandlerGuards(Z,L);for(let V of H)if(!await V.canActivate(k))throw new p(403,{message:"Forbidden"});let T=new Array(K.length);for(let V of F){let g=V.factory(V.data,k),c=await q.executePipes(g,{type:V.type,metatype:V.metatype,data:V.data},A);T[V.index]=c}let b=await K(...T);if(u!==void 0)return b;if(O(b))return k.json(null);if(C(b))return k.text(b);return k.json(b)}catch(H){return q.handleException(H,k)}};this.registerRouteHandler(z,G,R,D)}}class d{hono;container;routeManager;options;constructor(Q={}){this.options=I(Q)?Q:{},this.hono=new s(this.options.hono),this.container=this.options.container||new w,this.routeManager=new y(this.hono,this.container,{prefix:this.options.routing?.prefix,version:this.options.routing?.version}),this.setupComponents(),this.setupErrorHandlers()}setupComponents(){q.init(this.container),q.setupGlobalComponents(this.options)}setupErrorHandlers(){this.hono.notFound(this.options.notFound||M.handle()),this.hono.onError(this.options.onError||f.handle())}resolvePlugin(Q){if(m(Q))return new Q;return Q}async register(Q){let W=await q.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 N.getRoutes()}}function rQ(Q="",W={}){return(X)=>{B.setControllerPath(X,Q),B.setControllerOptions(X,W)}}var eQ=E("get"),QW=E("post"),WW=E("put"),XW=E("delete"),YW=E("patch"),ZW=E("options"),$W=E("all");function qW(Q={}){return(W)=>{B.setModuleOptions(W,Q)}}var jW=_("body",async(Q,W)=>{let X=await W.req.json();return Q?X[Q]:X}),LW=_("param",(Q,W)=>{return Q?W.req.param(Q):W.req.param()}),UW=_("query",(Q,W)=>{return Q?W.req.query(Q):W.req.query()}),GW=_("header",(Q,W)=>{return Q?W.req.header(Q):W.req.header()}),kW=_("request",(Q,W)=>W.req),FW=_("request",(Q,W)=>W.req),VW=_("response",(Q,W)=>W.res),EW=_("response",(Q,W)=>W.res),AW=_("context",(Q,W)=>W),DW=_("context",(Q,W)=>W),OW=_("variable",(Q,W)=>W.get(Q)),HW=_("variable",(Q,W)=>W.get(Q));function KW(){return(Q)=>{B.addService(Q)}}function PW(Q,...W){return(X,Y)=>{if(Y){let Z=X.constructor;q.registerHandler(Q,Z,Y,...W)}else q.registerController(Q,X,...W)}}function fW(...Q){return(W,X)=>{if(X){let Y=W.constructor;q.registerHandler("filter",Y,X,...Q)}else q.registerController("filter",W,...Q)}}function IW(...Q){return(W,X)=>{if(X){let Y=W.constructor;q.registerHandler("guard",Y,X,...Q)}else q.registerController("guard",W,...Q)}}function yW(...Q){return(W,X)=>{if(X){let Y=W.constructor;q.registerHandler("middleware",Y,X,...Q)}else q.registerController("middleware",W,...Q)}}function hW(...Q){return(W,X)=>{if(X){let Y=W.constructor;q.registerHandler("pipe",Y,X,...Q)}else q.registerController("pipe",W,...Q)}}export{SQ as stripEndSlash,v as normalizePath,bQ as isUndefined,TQ as isSymbol,C as isString,NQ as isPlainObject,I as isObject,KQ as isNumber,O as isNil,h as isFunction,RQ as isEmpty,m as isConstructor,_ as createParamDecorator,E as createHttpMethodDecorator,P as createErrorResponse,PQ as addLeadingSlash,HW as Variable,OW as Var,x as VERSION_NEUTRAL,hW as UsePipes,yW as UseMiddleware,IW as UseGuards,fW as UseFilters,PW as UseComponent,KW as Service,N as RouteRegistry,y as RouteManager,EW as Response,VW as Res,FW as Request,kW as Req,UW as Query,WW as Put,QW as Post,YW as Patch,LW as Param,ZW as Options,M as NotFoundHandler,qW as Module,B as MetadataRegistry,GW as Header,eQ as Get,f as ErrorHandler,XW as Delete,AW as Ctx,rQ as Controller,DW as Context,w as Container,q as ComponentManager,jW as Body,d as Application,$W as All};
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,13 +1,38 @@
1
1
  import type { VERSION_NEUTRAL } from '../constants';
2
2
  /**
3
- * Options for HTTP method decorators
3
+ * Options for HTTP method decorators (@Get, @Post, @Put, @Delete, etc.)
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * @Get('users', { prefix: 'api', version: 2 })
8
+ * getUsers() {
9
+ * // ...
10
+ * }
11
+ * ```
4
12
  */
5
13
  export interface HttpMethodOptions {
6
14
  /**
7
- * API version for this specific route, overrides controller and global version
8
- * Set to null to explicitly opt out of versioning
9
- * Set to VERSION_NEUTRAL to make the route accessible both with and without version prefix
10
- * Set to an array of numbers to make the route available at multiple versions
15
+ * Optional prefix for this specific route, overrides controller and global prefix.
16
+ * Set to null to explicitly remove any prefix for this route.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * @Get('users', { prefix: 'api' }) // -> /api/users
21
+ * @Get('users', { prefix: null }) // -> /users (no prefix)
22
+ * @Get('users', { prefix: 'v2/api' }) // -> /v2/api/users
23
+ * ```
24
+ */
25
+ prefix?: string | null;
26
+ /**
27
+ * API version for this specific route, overrides controller and global version.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * @Get('users', { version: 1 }) // -> /v1/users
32
+ * @Get('users', { version: null }) // -> /users (no version)
33
+ * @Get('users', { version: VERSION_NEUTRAL }) // -> Both /users and /v1/users
34
+ * @Get('users', { version: [1, 2] }) // -> Both /v1/users and /v2/users
35
+ * ```
11
36
  */
12
37
  version?: number | null | typeof VERSION_NEUTRAL | number[];
13
38
  }
@@ -1,30 +1,57 @@
1
1
  import type { VERSION_NEUTRAL } from '../constants';
2
2
  import type { ParameterMetadata } from '../interfaces';
3
3
  /**
4
- * Metadata for defining a route
4
+ * Internal metadata for defining a route. This interface is used by the framework
5
+ * to store route information collected from decorators.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Internal representation of:
10
+ * @Controller('users')
11
+ * class UsersController {
12
+ * @Get(':id')
13
+ * getUser(@Param('id') id: string) {}
14
+ * }
15
+ * ```
5
16
  */
6
17
  export interface RouteDefinition {
7
18
  /**
8
- * Route path
19
+ * Route path relative to the controller's base path.
20
+ * Supports path parameters using colon syntax.
21
+ *
22
+ * @example ':id' | 'users/:userId/posts/:postId' | ''
9
23
  */
10
24
  path: string;
11
25
  /**
12
- * HTTP method
26
+ * HTTP method for the route (GET, POST, PUT, DELETE, etc.)
13
27
  */
14
28
  method: string;
15
29
  /**
16
- * Handler method name
30
+ * Name of the method in the controller class that handles this route
17
31
  */
18
32
  handlerName: string | symbol;
19
33
  /**
20
- * Parameter metadata for the handler
34
+ * Metadata about the parameters of the handler method,
35
+ * including decorators like @Body(), @Param(), @Query(), etc.
21
36
  */
22
37
  parameterMetadata: ParameterMetadata[];
23
38
  /**
24
- * Route-specific API version, overrides controller and global version
25
- * Set to null to explicitly opt out of versioning
26
- * Set to VERSION_NEUTRAL to make the route accessible both with and without version prefix
27
- * Set to an array of numbers to make the route available at multiple versions
39
+ * Route-specific API version, overrides controller and global version.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * version: 1 // -> /v1/...
44
+ * version: null // -> /... (no version)
45
+ * version: VERSION_NEUTRAL // -> Both /... and /v1/...
46
+ * version: [1, 2] // -> Both /v1/... and /v2/...
47
+ * ```
28
48
  */
29
49
  version?: number | null | typeof VERSION_NEUTRAL | number[];
50
+ /**
51
+ * Route-specific prefix that overrides controller and global prefix.
52
+ * Set to null to explicitly remove any prefix.
53
+ *
54
+ * @example 'api' | 'v2/api' | null
55
+ */
56
+ prefix?: string | null;
30
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "honestjs",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "author": "Orkhan Karimov <karimovok1@gmail.com> (https://github.com/kerimovok)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,7 +17,7 @@
17
17
  "typescript": "^5",
18
18
  "reflect-metadata": "^0.2.2"
19
19
  },
20
- "description": "Nest.js inspired framework for Hono.js",
20
+ "description": "HonestJS - a modern web framework built on top of Hono",
21
21
  "files": [
22
22
  "dist"
23
23
  ],