@ajke/core 0.1.0
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/LICENSE +21 -0
- package/README.md +357 -0
- package/dist/chunk-AT2R2CGV.js +234 -0
- package/dist/chunk-AT2R2CGV.js.map +1 -0
- package/dist/chunk-EUXUH3YW.js +15 -0
- package/dist/chunk-EUXUH3YW.js.map +1 -0
- package/dist/chunk-YUBEJL4T.cjs +234 -0
- package/dist/chunk-YUBEJL4T.cjs.map +1 -0
- package/dist/chunk-ZBDE64SD.cjs +15 -0
- package/dist/chunk-ZBDE64SD.cjs.map +1 -0
- package/dist/config.cjs +10 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +13 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -0
- package/dist/index.cjs +974 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +255 -0
- package/dist/index.d.ts +255 -0
- package/dist/index.js +974 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/index.cjs +10 -0
- package/dist/middleware/index.cjs.map +1 -0
- package/dist/middleware/index.d.cts +18 -0
- package/dist/middleware/index.d.ts +18 -0
- package/dist/middleware/index.js +10 -0
- package/dist/middleware/index.js.map +1 -0
- package/package.json +56 -0
- package/src/README.md +285 -0
- package/src/config.ts +14 -0
- package/src/context/execution-context.ts +36 -0
- package/src/context/index.ts +1 -0
- package/src/decorators/core/exception-filters.decorator.ts +24 -0
- package/src/decorators/core/index.ts +6 -0
- package/src/decorators/core/injectable.decorator.ts +41 -0
- package/src/decorators/core/optional.decorator.ts +9 -0
- package/src/decorators/core/set-metadata.decorator.ts +20 -0
- package/src/decorators/core/use-guards.decorator.ts +14 -0
- package/src/decorators/core/use-interceptors.decorator.ts +16 -0
- package/src/decorators/http/controller.decorator.ts +230 -0
- package/src/decorators/http/header.decorator.ts +11 -0
- package/src/decorators/http/http-code.decorator.ts +8 -0
- package/src/decorators/http/index.ts +6 -0
- package/src/decorators/http/redirect.decorator.ts +13 -0
- package/src/decorators/http/route-mapping.decorator.ts +22 -0
- package/src/decorators/http/route-params.decorator.ts +60 -0
- package/src/decorators/index.ts +3 -0
- package/src/decorators/modules/global.decorator.ts +8 -0
- package/src/decorators/modules/index.ts +2 -0
- package/src/decorators/modules/module.decorator.ts +16 -0
- package/src/exceptions/http-exception.ts +17 -0
- package/src/exceptions/http-exceptions.ts +85 -0
- package/src/exceptions/index.ts +2 -0
- package/src/index.ts +11 -0
- package/src/injector/index.ts +1 -0
- package/src/injector/injector.ts +103 -0
- package/src/injector/module-compiler.ts +48 -0
- package/src/injector/module.factory.ts +74 -0
- package/src/interfaces/core/filter.interface.ts +5 -0
- package/src/interfaces/core/guard.interface.ts +5 -0
- package/src/interfaces/core/index.ts +5 -0
- package/src/interfaces/core/interceptor.interface.ts +9 -0
- package/src/interfaces/core/lifecycle.interface.ts +19 -0
- package/src/interfaces/core/pipe.interface.ts +9 -0
- package/src/interfaces/http/index.ts +1 -0
- package/src/interfaces/http/response.interface.ts +27 -0
- package/src/interfaces/index.ts +3 -0
- package/src/interfaces/modules/index.ts +1 -0
- package/src/interfaces/modules/module.interface.ts +17 -0
- package/src/middleware/error-handler.middleware.ts +63 -0
- package/src/middleware/index.ts +2 -0
- package/src/middleware/request-logger.middleware.ts +17 -0
- package/src/pipes/index.ts +3 -0
- package/src/pipes/validate.pipe.ts +79 -0
- package/src/pipes/zod-query.pipe.ts +42 -0
- package/src/pipes/zod-validate.pipe.ts +49 -0
- package/src/services/index.ts +1 -0
- package/src/services/reflector.service.ts +24 -0
- package/src/utils/apply-decorators.util.ts +17 -0
- package/src/utils/forward-ref.util.ts +14 -0
- package/src/utils/index.ts +22 -0
- package/src/utils/logger.util.ts +189 -0
- package/src/utils/response.util.ts +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/decorators/core/injectable.decorator.ts","../src/utils/forward-ref.util.ts","../src/decorators/core/set-metadata.decorator.ts","../src/decorators/core/use-guards.decorator.ts","../src/decorators/core/use-interceptors.decorator.ts","../src/decorators/core/exception-filters.decorator.ts","../src/decorators/core/optional.decorator.ts","../src/decorators/http/controller.decorator.ts","../src/context/execution-context.ts","../src/decorators/http/header.decorator.ts","../src/decorators/http/http-code.decorator.ts","../src/decorators/http/redirect.decorator.ts","../src/decorators/http/route-params.decorator.ts","../src/exceptions/http-exceptions.ts","../src/decorators/http/route-mapping.decorator.ts","../src/decorators/modules/module.decorator.ts","../src/decorators/modules/global.decorator.ts","../src/injector/module.factory.ts","../src/injector/module-compiler.ts","../src/injector/injector.ts","../src/pipes/validate.pipe.ts","../src/pipes/zod-validate.pipe.ts","../src/pipes/zod-query.pipe.ts","../src/services/reflector.service.ts","../src/utils/response.util.ts","../src/utils/apply-decorators.util.ts"],"sourcesContent":["import { injectable, inject as tsyringeInject } from \"tsyringe\";\nimport { isForwardRef } from \"../../utils/forward-ref.util\";\n\nexport const INJECT_CUSTOM_TOKENS_KEY = \"wilt:inject:custom:tokens\";\n\nexport function Injectable() {\n\treturn (target: any) => {\n\t\tinjectable()(target);\n\t};\n}\n\nexport function Inject(token?: any) {\n\treturn (\n\t\ttarget: any,\n\t\tpropertyKey: string | symbol | undefined,\n\t\tparameterIndex: number\n\t) => {\n\t\tif (isForwardRef(token)) {\n\t\t\tconst existing: Record<number, any> =\n\t\t\t\tReflect.getMetadata(INJECT_CUSTOM_TOKENS_KEY, target) || {};\n\t\t\texisting[parameterIndex] = token;\n\t\t\tReflect.defineMetadata(INJECT_CUSTOM_TOKENS_KEY, existing, target);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!token) {\n\t\t\tconst paramTypes = Reflect.getMetadata(\"design:paramtypes\", target) || [];\n\t\t\tconst paramType = paramTypes[parameterIndex];\n\t\t\tif (paramType) {\n\t\t\t\treturn tsyringeInject(paramType)(target, propertyKey, parameterIndex);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst existing: Record<number, any> =\n\t\t\tReflect.getMetadata(INJECT_CUSTOM_TOKENS_KEY, target) || {};\n\t\texisting[parameterIndex] = token;\n\t\tReflect.defineMetadata(INJECT_CUSTOM_TOKENS_KEY, existing, target);\n\t\treturn tsyringeInject(token)(target, propertyKey, parameterIndex);\n\t};\n}\n","import type { ForwardReference } from \"../interfaces/modules/module.interface\";\n\nexport function forwardRef<T = any>(fn: () => T): ForwardReference<T> {\n\treturn { forwardRef: fn };\n}\n\nexport function isForwardRef(val: any): val is ForwardReference {\n\treturn (\n\t\tval !== null &&\n\t\tval !== undefined &&\n\t\ttypeof val === \"object\" &&\n\t\ttypeof val.forwardRef === \"function\"\n\t);\n}\n","export interface CustomDecorator<TKey = string> {\n\t(target: any, key?: any, descriptor?: any): any;\n\tKEY: TKey;\n}\n\nexport function SetMetadata<K = string, V = any>(\n\tmetadataKey: K,\n\tmetadataValue: V\n): CustomDecorator<K> {\n\tconst decoratorFactory = (target: any, key?: any, descriptor?: PropertyDescriptor): any => {\n\t\tif (descriptor) {\n\t\t\tReflect.defineMetadata(metadataKey as string, metadataValue, descriptor.value);\n\t\t\treturn descriptor;\n\t\t}\n\t\tReflect.defineMetadata(metadataKey as string, metadataValue, target);\n\t\treturn target;\n\t};\n\t(decoratorFactory as any).KEY = metadataKey;\n\treturn decoratorFactory as CustomDecorator<K>;\n}\n","export const GUARDS_METADATA = \"wilt:guards\";\n\nexport function UseGuards(...guards: (new (...args: any[]) => any)[]): MethodDecorator & ClassDecorator {\n\treturn (target: any, key?: any, descriptor?: PropertyDescriptor): any => {\n\t\tif (descriptor) {\n\t\t\tconst existing: any[] = Reflect.getMetadata(GUARDS_METADATA, descriptor.value) || [];\n\t\t\tReflect.defineMetadata(GUARDS_METADATA, [...existing, ...guards], descriptor.value);\n\t\t\treturn descriptor;\n\t\t}\n\t\tconst existing: any[] = Reflect.getMetadata(GUARDS_METADATA, target) || [];\n\t\tReflect.defineMetadata(GUARDS_METADATA, [...existing, ...guards], target);\n\t\treturn target;\n\t};\n}\n","export const INTERCEPTORS_METADATA = \"wilt:interceptors\";\n\nexport function UseInterceptors(\n\t...interceptors: (new (...args: any[]) => any)[]\n): MethodDecorator & ClassDecorator {\n\treturn (target: any, key?: any, descriptor?: PropertyDescriptor): any => {\n\t\tif (descriptor) {\n\t\t\tconst existing: any[] = Reflect.getMetadata(INTERCEPTORS_METADATA, descriptor.value) || [];\n\t\t\tReflect.defineMetadata(INTERCEPTORS_METADATA, [...existing, ...interceptors], descriptor.value);\n\t\t\treturn descriptor;\n\t\t}\n\t\tconst existing: any[] = Reflect.getMetadata(INTERCEPTORS_METADATA, target) || [];\n\t\tReflect.defineMetadata(INTERCEPTORS_METADATA, [...existing, ...interceptors], target);\n\t\treturn target;\n\t};\n}\n","export const FILTERS_METADATA = \"wilt:filters\";\nexport const CATCH_METADATA = \"wilt:catch\";\n\nexport function Catch(...exceptions: (new (...args: any[]) => any)[]): ClassDecorator {\n\treturn (target: any) => {\n\t\tReflect.defineMetadata(CATCH_METADATA, exceptions, target);\n\t\treturn target;\n\t};\n}\n\nexport function UseFilters(\n\t...filters: (new (...args: any[]) => any)[]\n): MethodDecorator & ClassDecorator {\n\treturn (target: any, key?: any, descriptor?: PropertyDescriptor): any => {\n\t\tif (descriptor) {\n\t\t\tconst existing: any[] = Reflect.getMetadata(FILTERS_METADATA, descriptor.value) || [];\n\t\t\tReflect.defineMetadata(FILTERS_METADATA, [...existing, ...filters], descriptor.value);\n\t\t\treturn descriptor;\n\t\t}\n\t\tconst existing: any[] = Reflect.getMetadata(FILTERS_METADATA, target) || [];\n\t\tReflect.defineMetadata(FILTERS_METADATA, [...existing, ...filters], target);\n\t\treturn target;\n\t};\n}\n","export const OPTIONAL_METADATA = \"wilt:optional\";\n\nexport function Optional(): ParameterDecorator {\n\treturn (target, _key, parameterIndex) => {\n\t\tconst existing: number[] = Reflect.getMetadata(OPTIONAL_METADATA, target) || [];\n\t\texisting.push(parameterIndex);\n\t\tReflect.defineMetadata(OPTIONAL_METADATA, existing, target);\n\t};\n}\n","import type { Context } from \"hono\";\nimport type { Hono } from \"hono\";\nimport { injectable } from \"tsyringe\";\nimport { createArgumentsHost, createExecutionContext } from \"../../context/execution-context\";\nimport { CATCH_METADATA, FILTERS_METADATA } from \"../core/exception-filters.decorator\";\nimport { GUARDS_METADATA } from \"../core/use-guards.decorator\";\nimport { INTERCEPTORS_METADATA } from \"../core/use-interceptors.decorator\";\nimport { HEADER_METADATA } from \"./header.decorator\";\nimport { HTTP_CODE_METADATA } from \"./http-code.decorator\";\nimport { REDIRECT_METADATA, type RedirectMetadata } from \"./redirect.decorator\";\nimport { ROUTE_PARAMS_METADATA, TOTAL_PARAMS_METADATA, type RouteParamMetadata } from \"./route-params.decorator\";\nimport { ForbiddenException } from \"../../exceptions/http-exceptions\";\nimport type { RouteMetadata } from \"../../interfaces/modules/module.interface\";\n\nexport function Controller(prefix: string = \"\") {\n\treturn (target: any) => {\n\t\tinjectable()(target);\n\t\ttarget.prototype.prefix = prefix;\n\t\ttarget.prototype.constructorParams = target.prototype.constructorParams || [];\n\t\ttarget.prototype.constructorClass = target;\n\t};\n}\n\nfunction resolveFromRegistry(\n\tClassOrInstance: any,\n\tinstanceRegistry?: Map<any, any>\n): any {\n\tif (typeof ClassOrInstance !== \"function\") return ClassOrInstance;\n\tif (instanceRegistry?.has(ClassOrInstance)) return instanceRegistry.get(ClassOrInstance);\n\treturn new ClassOrInstance();\n}\n\nasync function resolveParamArgs(\n\tparamMeta: RouteParamMetadata[],\n\tc: Context,\n\ttotalParams: number\n): Promise<any[]> {\n\tconst maxIndex = Math.max(totalParams - 1, ...paramMeta.map((p) => p.index));\n\tconst args = new Array(maxIndex + 1).fill(undefined);\n\tconst filledIndices = new Set(paramMeta.map((p) => p.index));\n\n\tlet body: any;\n\tconst needsBody = paramMeta.some((p) => p.type === \"body\");\n\tif (needsBody) {\n\t\tconst ct = c.req.header(\"content-type\") || \"\";\n\t\tif (ct.includes(\"multipart/form-data\")) {\n\t\t\tconst fd = await c.req.formData();\n\t\t\tbody = {};\n\t\t\tfd.forEach((v, k) => { body[k] = v; });\n\t\t} else {\n\t\t\tbody = await c.req.json().catch(() => ({}));\n\t\t}\n\t}\n\n\tfor (const p of paramMeta) {\n\t\tswitch (p.type) {\n\t\t\tcase \"body\":\n\t\t\t\targs[p.index] = p.data ? body?.[p.data] : body;\n\t\t\t\tbreak;\n\t\t\tcase \"param\":\n\t\t\t\targs[p.index] = p.data ? c.req.param(p.data) : c.req.param();\n\t\t\t\tbreak;\n\t\t\tcase \"query\":\n\t\t\t\targs[p.index] = p.data ? c.req.query(p.data) : c.req.query();\n\t\t\t\tbreak;\n\t\t\tcase \"headers\":\n\t\t\t\targs[p.index] = p.data\n\t\t\t\t\t? c.req.header(p.data)\n\t\t\t\t\t: Object.fromEntries((c.req.raw.headers as any).entries());\n\t\t\t\tbreak;\n\t\t\tcase \"ip\":\n\t\t\t\targs[p.index] =\n\t\t\t\t\tc.req.header(\"cf-connecting-ip\") ||\n\t\t\t\t\tc.req.header(\"x-forwarded-for\") ||\n\t\t\t\t\t\"\";\n\t\t\t\tbreak;\n\t\t\tcase \"req\":\n\t\t\t\targs[p.index] = c;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Any slot not covered by a decorator receives the raw Hono context\n\tfor (let i = 0; i <= maxIndex; i++) {\n\t\tif (!filledIndices.has(i)) args[i] = c;\n\t}\n\n\treturn args;\n}\n\nexport function registerControllerRoutes(\n\trouter: Hono<{ Bindings: any }>,\n\tcontroller: any,\n\tprefix: string = \"\",\n\tinstanceRegistry?: Map<any, any>\n) {\n\tconst routes: RouteMetadata[] = (controller.constructor as any).prototype.routes || [];\n\tconst controllerClass = controller.constructor;\n\n\tfor (const route of routes) {\n\t\tconst handlerFn = controller[route.handler as keyof typeof controller] as Function;\n\t\tconst fullPath = prefix + route.path;\n\t\tconst proto = controllerClass.prototype;\n\n\t\tconst classGuards: any[] = Reflect.getMetadata(GUARDS_METADATA, controllerClass) || [];\n\t\tconst methodGuards: any[] = Reflect.getMetadata(GUARDS_METADATA, handlerFn) || [];\n\t\tconst guards = [...classGuards, ...methodGuards];\n\n\t\tconst classInterceptors: any[] = Reflect.getMetadata(INTERCEPTORS_METADATA, controllerClass) || [];\n\t\tconst methodInterceptors: any[] = Reflect.getMetadata(INTERCEPTORS_METADATA, handlerFn) || [];\n\t\tconst interceptors = [...classInterceptors, ...methodInterceptors];\n\n\t\tconst classFilters: any[] = Reflect.getMetadata(FILTERS_METADATA, controllerClass) || [];\n\t\tconst methodFilters: any[] = Reflect.getMetadata(FILTERS_METADATA, handlerFn) || [];\n\t\tconst filters = [...classFilters, ...methodFilters];\n\n\t\tconst httpCode: number | undefined = Reflect.getMetadata(HTTP_CODE_METADATA, handlerFn);\n\t\tconst headersToSet: { name: string; value: string }[] =\n\t\t\tReflect.getMetadata(HEADER_METADATA, handlerFn) || [];\n\t\tconst redirectMeta: RedirectMetadata | undefined = Reflect.getMetadata(REDIRECT_METADATA, handlerFn);\n\t\tconst paramMeta: RouteParamMetadata[] =\n\t\t\tReflect.getMetadata(ROUTE_PARAMS_METADATA, proto, route.handler) || [];\n\t\tconst totalParams: number =\n\t\t\tReflect.getMetadata(TOTAL_PARAMS_METADATA, proto, route.handler) ?? 0;\n\t\tconst methodMiddlewares: any[] = (handlerFn as any).middlewares || [];\n\n\t\tconst finalHandler = async (c: Context): Promise<Response> => {\n\t\t\tconst execCtx = createExecutionContext(c, controllerClass, handlerFn);\n\n\t\t\tconst runCore = async (): Promise<Response> => {\n\t\t\t\t// Guards\n\t\t\t\tfor (const G of guards) {\n\t\t\t\t\tconst guard = resolveFromRegistry(G, instanceRegistry);\n\t\t\t\t\tconst ok = await guard.canActivate(execCtx);\n\t\t\t\t\tif (!ok) throw new ForbiddenException();\n\t\t\t\t}\n\n\t\t\t\t// Build the actual call\n\t\t\t\tconst callHandler = async (): Promise<Response> => {\n\t\t\t\t\tlet result: any;\n\t\t\t\t\tif (paramMeta.length > 0) {\n\t\t\t\t\t\tconst args = await resolveParamArgs(paramMeta, c, totalParams);\n\t\t\t\t\t\tresult = await handlerFn.call(controller, ...args);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = await handlerFn.call(controller, c);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set response headers\n\t\t\t\t\tfor (const { name, value } of headersToSet) {\n\t\t\t\t\t\tc.header(name, value);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Redirect takes precedence\n\t\t\t\t\tif (redirectMeta) {\n\t\t\t\t\t\tconst url =\n\t\t\t\t\t\t\tresult && typeof result === \"object\" && \"url\" in result\n\t\t\t\t\t\t\t\t? (result as any).url\n\t\t\t\t\t\t\t\t: redirectMeta.url;\n\t\t\t\t\t\tconst code =\n\t\t\t\t\t\t\tresult && typeof result === \"object\" && \"statusCode\" in result\n\t\t\t\t\t\t\t\t? (result as any).statusCode\n\t\t\t\t\t\t\t\t: redirectMeta.statusCode;\n\t\t\t\t\t\treturn c.redirect(url, code as any);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Auto-serialize non-Response returns\n\t\t\t\t\tif (result instanceof Response) return result;\n\t\t\t\t\tif (result !== undefined && result !== null) {\n\t\t\t\t\t\treturn c.json(result, (httpCode ?? 200) as any);\n\t\t\t\t\t}\n\t\t\t\t\treturn new Response(null, { status: httpCode ?? 204 });\n\t\t\t\t};\n\n\t\t\t\t// Method-level legacy middlewares\n\t\t\t\tif (methodMiddlewares.length > 0) {\n\t\t\t\t\tlet idx = 0;\n\t\t\t\t\tconst next = async (): Promise<Response | void> => {\n\t\t\t\t\t\tif (idx < methodMiddlewares.length) {\n\t\t\t\t\t\t\treturn await methodMiddlewares[idx++](c, next);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn callHandler();\n\t\t\t\t\t};\n\t\t\t\t\treturn (await next()) as Response;\n\t\t\t\t}\n\n\t\t\t\treturn callHandler();\n\t\t\t};\n\n\t\t\t// Interceptors wrap the core call\n\t\t\tconst runWithInterceptors = async (): Promise<Response> => {\n\t\t\t\tif (interceptors.length === 0) return runCore();\n\n\t\t\t\tlet chain = runCore;\n\t\t\t\tfor (let i = interceptors.length - 1; i >= 0; i--) {\n\t\t\t\t\tconst interceptor = resolveFromRegistry(interceptors[i], instanceRegistry);\n\t\t\t\t\tconst inner = chain;\n\t\t\t\t\tchain = () => interceptor.intercept(execCtx, { handle: inner });\n\t\t\t\t}\n\t\t\t\treturn chain();\n\t\t\t};\n\n\t\t\t// Exception filters wrap everything\n\t\t\tif (filters.length === 0) return runWithInterceptors();\n\n\t\t\ttry {\n\t\t\t\treturn await runWithInterceptors();\n\t\t\t} catch (err) {\n\t\t\t\tfor (const F of filters) {\n\t\t\t\t\tconst filter = resolveFromRegistry(F, instanceRegistry);\n\t\t\t\t\tconst catchTypes: any[] =\n\t\t\t\t\t\tReflect.getMetadata(CATCH_METADATA, filter.constructor ?? F) || [];\n\t\t\t\t\tif (catchTypes.length === 0 || catchTypes.some((T) => err instanceof T)) {\n\t\t\t\t\t\tconst host = createArgumentsHost(c);\n\t\t\t\t\t\tconst res = await filter.catch(err, host);\n\t\t\t\t\t\tif (res instanceof Response) return res;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\n\t\tswitch (route.method) {\n\t\t\tcase \"GET\": router.get(fullPath, finalHandler); break;\n\t\t\tcase \"POST\": router.post(fullPath, finalHandler); break;\n\t\t\tcase \"PUT\": router.put(fullPath, finalHandler); break;\n\t\t\tcase \"DELETE\": router.delete(fullPath, finalHandler); break;\n\t\t\tcase \"PATCH\": router.patch(fullPath, finalHandler); break;\n\t\t}\n\t}\n}\n","import type { Context } from \"hono\";\n\nexport interface HttpArgumentsHost {\n\tgetRequest<T = Context>(): T;\n}\n\nexport interface ArgumentsHost {\n\tswitchToHttp(): HttpArgumentsHost;\n}\n\nexport interface ExecutionContext extends ArgumentsHost {\n\tgetClass<T = any>(): new (...args: any[]) => T;\n\tgetHandler(): Function;\n}\n\nexport function createExecutionContext(\n\tc: Context,\n\tcontrollerClass: any,\n\thandler: Function\n): ExecutionContext {\n\treturn {\n\t\tgetClass: () => controllerClass,\n\t\tgetHandler: () => handler,\n\t\tswitchToHttp: () => ({\n\t\t\tgetRequest: <T = Context>() => c as unknown as T,\n\t\t}),\n\t};\n}\n\nexport function createArgumentsHost(c: Context): ArgumentsHost {\n\treturn {\n\t\tswitchToHttp: () => ({\n\t\t\tgetRequest: <T = Context>() => c as unknown as T,\n\t\t}),\n\t};\n}\n","export const HEADER_METADATA = \"wilt:response-headers\";\n\nexport function Header(name: string, value: string): MethodDecorator {\n\treturn (_target, _key, descriptor: PropertyDescriptor) => {\n\t\tconst existing: { name: string; value: string }[] =\n\t\t\tReflect.getMetadata(HEADER_METADATA, descriptor.value) || [];\n\t\texisting.push({ name, value });\n\t\tReflect.defineMetadata(HEADER_METADATA, existing, descriptor.value);\n\t\treturn descriptor;\n\t};\n}\n","export const HTTP_CODE_METADATA = \"wilt:http-code\";\n\nexport function HttpCode(statusCode: number): MethodDecorator {\n\treturn (_target, _key, descriptor: PropertyDescriptor) => {\n\t\tReflect.defineMetadata(HTTP_CODE_METADATA, statusCode, descriptor.value);\n\t\treturn descriptor;\n\t};\n}\n","export const REDIRECT_METADATA = \"wilt:redirect\";\n\nexport interface RedirectMetadata {\n\turl: string;\n\tstatusCode: number;\n}\n\nexport function Redirect(url: string, statusCode: number = 302): MethodDecorator {\n\treturn (_target, _key, descriptor: PropertyDescriptor) => {\n\t\tReflect.defineMetadata(REDIRECT_METADATA, { url, statusCode }, descriptor.value);\n\t\treturn descriptor;\n\t};\n}\n","export const ROUTE_PARAMS_METADATA = \"wilt:route-params\";\nexport const TOTAL_PARAMS_METADATA = \"wilt:total-params\";\n\nexport type RouteParamType = \"body\" | \"param\" | \"query\" | \"headers\" | \"ip\" | \"req\";\n\nexport interface RouteParamMetadata {\n\tindex: number;\n\ttype: RouteParamType;\n\tdata?: string;\n}\n\nfunction recordTotalParams(target: any, key: string) {\n\tif (!Reflect.hasMetadata(TOTAL_PARAMS_METADATA, target, key)) {\n\t\tconst fn = target[key];\n\t\tif (typeof fn === \"function\") {\n\t\t\tReflect.defineMetadata(TOTAL_PARAMS_METADATA, fn.length, target, key);\n\t\t}\n\t}\n}\n\nfunction createParamDecorator(type: RouteParamType) {\n\treturn (data?: string): ParameterDecorator =>\n\t\t(target, propertyKey, parameterIndex) => {\n\t\t\tconst key = propertyKey as string;\n\t\t\tconst existing: RouteParamMetadata[] =\n\t\t\t\tReflect.getMetadata(ROUTE_PARAMS_METADATA, target, key) || [];\n\t\t\texisting.push({ index: parameterIndex, type, data });\n\t\t\tReflect.defineMetadata(ROUTE_PARAMS_METADATA, existing, target, key);\n\t\t\trecordTotalParams(target, key);\n\t\t};\n}\n\nexport const Body = createParamDecorator(\"body\");\nexport const Param = createParamDecorator(\"param\");\nexport const Query = createParamDecorator(\"query\");\nexport const Headers = createParamDecorator(\"headers\");\n\nexport function Ip(): ParameterDecorator {\n\treturn (target, propertyKey, parameterIndex) => {\n\t\tconst key = propertyKey as string;\n\t\tconst existing: RouteParamMetadata[] =\n\t\t\tReflect.getMetadata(ROUTE_PARAMS_METADATA, target, key) || [];\n\t\texisting.push({ index: parameterIndex, type: \"ip\" });\n\t\tReflect.defineMetadata(ROUTE_PARAMS_METADATA, existing, target, key);\n\t\trecordTotalParams(target, key);\n\t};\n}\n\nexport function Req(): ParameterDecorator {\n\treturn (target, propertyKey, parameterIndex) => {\n\t\tconst key = propertyKey as string;\n\t\tconst existing: RouteParamMetadata[] =\n\t\t\tReflect.getMetadata(ROUTE_PARAMS_METADATA, target, key) || [];\n\t\texisting.push({ index: parameterIndex, type: \"req\" });\n\t\tReflect.defineMetadata(ROUTE_PARAMS_METADATA, existing, target, key);\n\t\trecordTotalParams(target, key);\n\t};\n}\n\nexport { Req as Request };\n","import { HttpException } from \"./http-exception\";\n\nexport class BadRequestException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Bad Request\") {\n\t\tsuper(message, 400);\n\t\tthis.name = \"BadRequestException\";\n\t}\n}\n\nexport class UnauthorizedException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Unauthorized\") {\n\t\tsuper(message, 401);\n\t\tthis.name = \"UnauthorizedException\";\n\t}\n}\n\nexport class ForbiddenException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Forbidden\") {\n\t\tsuper(message, 403);\n\t\tthis.name = \"ForbiddenException\";\n\t}\n}\n\nexport class NotFoundException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Not Found\") {\n\t\tsuper(message, 404);\n\t\tthis.name = \"NotFoundException\";\n\t}\n}\n\nexport class MethodNotAllowedException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Method Not Allowed\") {\n\t\tsuper(message, 405);\n\t\tthis.name = \"MethodNotAllowedException\";\n\t}\n}\n\nexport class ConflictException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Conflict\") {\n\t\tsuper(message, 409);\n\t\tthis.name = \"ConflictException\";\n\t}\n}\n\nexport class GoneException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Gone\") {\n\t\tsuper(message, 410);\n\t\tthis.name = \"GoneException\";\n\t}\n}\n\nexport class UnprocessableEntityException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Unprocessable Entity\") {\n\t\tsuper(message, 422);\n\t\tthis.name = \"UnprocessableEntityException\";\n\t}\n}\n\nexport class TooManyRequestsException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Too Many Requests\") {\n\t\tsuper(message, 429);\n\t\tthis.name = \"TooManyRequestsException\";\n\t}\n}\n\nexport class InternalServerErrorException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Internal Server Error\") {\n\t\tsuper(message, 500);\n\t\tthis.name = \"InternalServerErrorException\";\n\t}\n}\n\nexport class NotImplementedException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Not Implemented\") {\n\t\tsuper(message, 501);\n\t\tthis.name = \"NotImplementedException\";\n\t}\n}\n\nexport class ServiceUnavailableException extends HttpException {\n\tconstructor(message: string | Record<string, any> = \"Service Unavailable\") {\n\t\tsuper(message, 503);\n\t\tthis.name = \"ServiceUnavailableException\";\n\t}\n}\n","function createMethodDecorator(\n\tmethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\"\n) {\n\treturn (path: string = \"\") =>\n\t\t(target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n\t\t\tif (!target.constructor.prototype.routes) {\n\t\t\t\ttarget.constructor.prototype.routes = [];\n\t\t\t}\n\t\t\ttarget.constructor.prototype.routes.push({\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\thandler: propertyKey,\n\t\t\t});\n\t\t\treturn descriptor;\n\t\t};\n}\n\nexport const Get = createMethodDecorator(\"GET\");\nexport const Post = createMethodDecorator(\"POST\");\nexport const Put = createMethodDecorator(\"PUT\");\nexport const Delete = createMethodDecorator(\"DELETE\");\nexport const Patch = createMethodDecorator(\"PATCH\");\n","import { injectable } from \"tsyringe\";\nimport type { ModuleMetadata } from \"../../interfaces/modules/module.interface\";\n\nexport function Module(config: ModuleMetadata) {\n\treturn (target: any) => {\n\t\ttarget.prototype.moduleConfig = config;\n\n\t\tif (config.providers) {\n\t\t\tconfig.providers.forEach((ProviderClass: any) => {\n\t\t\t\tif (ProviderClass && typeof ProviderClass === \"function\") {\n\t\t\t\t\tinjectable()(ProviderClass);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n}\n","export const GLOBAL_MODULE_METADATA = \"wilt:global\";\n\nexport function Global(): ClassDecorator {\n\treturn (target: any) => {\n\t\tReflect.defineMetadata(GLOBAL_MODULE_METADATA, true, target);\n\t\treturn target;\n\t};\n}\n","import { Hono } from \"hono\";\nimport { registerControllerRoutes } from \"../decorators/http/controller.decorator\";\nimport { GLOBAL_MODULE_METADATA } from \"../decorators/modules/global.decorator\";\nimport { logger } from \"../utils/logger.util\";\nimport { collectModuleTree } from \"./module-compiler\";\nimport { resolveInstance } from \"./injector\";\n\nexport function createModule<B extends object = Record<string, unknown>>(\n\tmoduleClass: any,\n\t{ middlewares = [] }: { middlewares?: any[] } = {}\n): Hono<{ Bindings: B }> {\n\tconst router = new Hono<{ Bindings: B }>();\n\n\tlogger.info(`Creating module: ${moduleClass.name}`, \"ModuleFactory\");\n\n\tmiddlewares.forEach((middleware) => router.use(\"*\", middleware));\n\n\tconst controllers: any[] = [];\n\tconst providers: any[] = [];\n\tconst globalProviders: any[] = [];\n\n\tcollectModuleTree(moduleClass, new Set(), new Set(), controllers, providers, globalProviders);\n\n\tlogger.info(\n\t\t`Resolved ${providers.length} providers, ${controllers.length} controllers`,\n\t\t\"ModuleFactory\"\n\t);\n\n\tconst instanceRegistry = new Map<any, any>();\n\tconst inProgress = new Set<any>();\n\n\t// Global providers are resolved first so they're available to all modules\n\tfor (const ProviderClass of globalProviders) {\n\t\tresolveInstance(ProviderClass, instanceRegistry, inProgress);\n\t}\n\n\tfor (const ProviderClass of providers) {\n\t\tresolveInstance(ProviderClass, instanceRegistry, inProgress);\n\t}\n\n\tfor (const ControllerClass of controllers) {\n\t\ttry {\n\t\t\tresolveInstance(ControllerClass, instanceRegistry, inProgress);\n\t\t\tconst controller = instanceRegistry.get(ControllerClass);\n\t\t\tconst prefix = (controller.constructor as any).prototype.prefix || \"\";\n\t\t\tregisterControllerRoutes(router, controller, prefix, instanceRegistry);\n\t\t\tlogger.debug(\n\t\t\t\t`Registered controller: ${ControllerClass.name} at \"${prefix}\"`,\n\t\t\t\t\"ModuleFactory\"\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tlogger.error(\n\t\t\t\t`Failed to create controller \"${ControllerClass.name}\": ${error}`,\n\t\t\t\t\"ModuleFactory\"\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Call onModuleInit on all instances that implement it\n\tfor (const instance of instanceRegistry.values()) {\n\t\tif (typeof instance?.onModuleInit === \"function\") {\n\t\t\tconst result = instance.onModuleInit();\n\t\t\tif (result instanceof Promise) {\n\t\t\t\tresult.catch((err) =>\n\t\t\t\t\tlogger.error(`onModuleInit failed for ${instance.constructor?.name}: ${err}`, \"ModuleFactory\")\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tlogger.info(`Module \"${moduleClass.name}\" created successfully`, \"ModuleFactory\");\n\treturn router;\n}\n","import { GLOBAL_MODULE_METADATA } from \"../decorators/modules/global.decorator\";\nimport { isForwardRef } from \"../utils/forward-ref.util\";\n\nexport function collectModuleTree(\n\tmoduleClass: any,\n\tvisiting: Set<any>,\n\tvisited: Set<any>,\n\tcontrollers: any[],\n\tproviders: any[],\n\tglobalProviders: any[] = []\n): void {\n\tif (visited.has(moduleClass)) return;\n\n\tvisiting.add(moduleClass);\n\n\tconst instance = new moduleClass();\n\tconst config = instance.moduleConfig || {};\n\tconst isGlobal = Reflect.getMetadata(GLOBAL_MODULE_METADATA, moduleClass) === true;\n\n\tfor (const c of config.controllers ?? []) {\n\t\tif (!controllers.includes(c)) controllers.push(c);\n\t}\n\tfor (const p of config.providers ?? []) {\n\t\tif (!providers.includes(p)) providers.push(p);\n\t\tif (isGlobal && !globalProviders.includes(p)) globalProviders.push(p);\n\t}\n\n\tfor (const importRef of config.imports ?? []) {\n\t\tconst isRef = isForwardRef(importRef);\n\t\tconst ImportedClass = isRef ? importRef.forwardRef() : importRef;\n\n\t\tif (visiting.has(ImportedClass)) {\n\t\t\tif (!isRef) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`[Wilt DI] Circular module dependency detected: \"${moduleClass.name}\" imports \"${ImportedClass.name}\" ` +\n\t\t\t\t\t\t`without forwardRef. Wrap it with forwardRef(() => ${ImportedClass.name}) ` +\n\t\t\t\t\t\t`in \"${moduleClass.name}\" imports array, and do the same in \"${ImportedClass.name}\".`\n\t\t\t\t);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcollectModuleTree(ImportedClass, visiting, visited, controllers, providers, globalProviders);\n\t}\n\n\tvisiting.delete(moduleClass);\n\tvisited.add(moduleClass);\n}\n","import { INJECT_CUSTOM_TOKENS_KEY } from \"../decorators/core/injectable.decorator\";\nimport { OPTIONAL_METADATA } from \"../decorators/core/optional.decorator\";\nimport { isForwardRef } from \"../utils/forward-ref.util\";\nimport { logger } from \"../utils/logger.util\";\n\nfunction createCircularProxy(registry: Map<any, any>, tokenClass: any): any {\n\treturn new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget(_target, prop) {\n\t\t\t\tconst instance = registry.get(tokenClass);\n\t\t\t\tif (!instance) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`[Wilt DI] Circular dependency proxy for \"${tokenClass.name}\" ` +\n\t\t\t\t\t\t\t`was accessed before the real instance was created. ` +\n\t\t\t\t\t\t\t`Make sure both sides use @Inject(forwardRef(() => ...)).`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst val = (instance as any)[prop];\n\t\t\t\treturn typeof val === \"function\" ? val.bind(instance) : val;\n\t\t\t},\n\t\t\tset(_target, prop, value) {\n\t\t\t\tconst instance = registry.get(tokenClass);\n\t\t\t\tif (instance) (instance as any)[prop] = value;\n\t\t\t\treturn true;\n\t\t\t},\n\t\t}\n\t);\n}\n\nexport function resolveInstance(\n\tProviderClass: any,\n\tinstanceRegistry: Map<any, any>,\n\tinProgress: Set<any>\n): any {\n\tif (instanceRegistry.has(ProviderClass)) {\n\t\treturn instanceRegistry.get(ProviderClass);\n\t}\n\n\tif (inProgress.has(ProviderClass)) {\n\t\tlogger.warn(\n\t\t\t`Circular dependency detected for \"${ProviderClass.name}\". ` +\n\t\t\t\t`Injecting a lazy proxy — ensure forwardRef() is used on both sides.`,\n\t\t\t\"ModuleFactory\"\n\t\t);\n\t\treturn createCircularProxy(instanceRegistry, ProviderClass);\n\t}\n\n\tinProgress.add(ProviderClass);\n\n\tconst paramTypes: any[] =\n\t\tReflect.getMetadata(\"design:paramtypes\", ProviderClass) || [];\n\tconst customTokens: Record<number, any> =\n\t\tReflect.getMetadata(INJECT_CUSTOM_TOKENS_KEY, ProviderClass) || {};\n\tconst optionalIndices: number[] =\n\t\tReflect.getMetadata(OPTIONAL_METADATA, ProviderClass) || [];\n\n\tconst customIndices = Object.keys(customTokens).map(Number);\n\tconst paramCount = Math.max(\n\t\tparamTypes.length,\n\t\tcustomIndices.length > 0 ? Math.max(...customIndices) + 1 : 0\n\t);\n\n\tconst deps = Array.from({ length: paramCount }, (_, i) => {\n\t\tconst customToken = customTokens[i];\n\t\tconst paramType = paramTypes[i];\n\t\tconst isOptional = optionalIndices.includes(i);\n\n\t\tlet actualClass: any;\n\t\tif (customToken) {\n\t\t\tactualClass = isForwardRef(customToken)\n\t\t\t\t? customToken.forwardRef()\n\t\t\t\t: customToken;\n\t\t} else {\n\t\t\tactualClass = paramType;\n\t\t}\n\n\t\tif (!actualClass || actualClass === Object || actualClass === Function) {\n\t\t\tif (!isOptional) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Cannot resolve param[${i}] for \"${ProviderClass.name}\": ` +\n\t\t\t\t\t\t`no type info. Use @Inject(TheClass) to specify it explicitly.`,\n\t\t\t\t\t\"ModuleFactory\"\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\n\t\ttry {\n\t\t\treturn resolveInstance(actualClass, instanceRegistry, inProgress);\n\t\t} catch (err) {\n\t\t\tif (isOptional) return undefined;\n\t\t\tthrow err;\n\t\t}\n\t});\n\n\tconst instance = new ProviderClass(...deps);\n\tinstanceRegistry.set(ProviderClass, instance);\n\tinProgress.delete(ProviderClass);\n\n\tlogger.debug(`Created instance: ${ProviderClass.name}`, \"ModuleFactory\");\n\treturn instance;\n}\n","import type { Context } from \"hono\";\n\nexport interface ValidationRule {\n\tfield: string;\n\trequired?: boolean;\n\ttype?: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\";\n\tminLength?: number;\n\tmaxLength?: number;\n\tpattern?: RegExp;\n\tcustom?: (value: any) => boolean;\n}\n\nexport function Validate(rules: ValidationRule[]) {\n\treturn function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n\t\tconst originalMethod = descriptor.value;\n\n\t\tdescriptor.value = async function (...args: any[]) {\n\t\t\tconst c: Context = args.find((a: any) => a != null && typeof a.json === \"function\" && a.req != null) ?? args[0];\n\t\t\tconst body = await c.req.json().catch(() => ({}));\n\t\t\tconst errors: string[] = [];\n\n\t\t\tfor (const rule of rules) {\n\t\t\t\tconst value = body[rule.field];\n\n\t\t\t\tif (rule.required && (value === undefined || value === null || value === \"\")) {\n\t\t\t\t\terrors.push(`${rule.field} is required`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (rule.type) {\n\t\t\t\t\tconst actualType = Array.isArray(value) ? \"array\" : typeof value;\n\t\t\t\t\tif (actualType !== rule.type) {\n\t\t\t\t\t\terrors.push(`${rule.field} must be of type ${rule.type}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (rule.type === \"string\" || typeof value === \"string\") {\n\t\t\t\t\tif (rule.minLength && value.length < rule.minLength) {\n\t\t\t\t\t\terrors.push(`${rule.field} must be at least ${rule.minLength} characters long`);\n\t\t\t\t\t}\n\t\t\t\t\tif (rule.maxLength && value.length > rule.maxLength) {\n\t\t\t\t\t\terrors.push(`${rule.field} must be at most ${rule.maxLength} characters long`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (rule.pattern && typeof value === \"string\" && !rule.pattern.test(value)) {\n\t\t\t\t\terrors.push(`${rule.field} format is invalid`);\n\t\t\t\t}\n\n\t\t\t\tif (rule.custom && !rule.custom(value)) {\n\t\t\t\t\terrors.push(`${rule.field} validation failed`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\t\t\tmessage: \"Validation failed\",\n\t\t\t\t\t\t\tdetails: errors,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn originalMethod.call(this, ...args);\n\t\t};\n\n\t\treturn descriptor;\n\t};\n}\n","import type { Context } from \"hono\";\nimport { z } from \"zod\";\n\nexport function ZodValidate(schema: z.ZodSchema) {\n\treturn function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n\t\tconst originalMethod = descriptor.value;\n\n\t\tdescriptor.value = async function (...args: any[]) {\n\t\t\tconst c: Context = args.find((a: any) => a != null && typeof a.json === \"function\" && a.req != null) ?? args[0];\n\t\t\ttry {\n\t\t\t\tconst contentType = c.req.header(\"content-type\") || \"\";\n\t\t\t\tlet input: any = {};\n\n\t\t\t\tif (contentType.includes(\"multipart/form-data\")) {\n\t\t\t\t\tconst formData = await c.req.formData();\n\t\t\t\t\tformData.forEach((val, key) => {\n\t\t\t\t\t\tinput[key] = val;\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tinput = await c.req.json().catch(() => ({}));\n\t\t\t\t}\n\n\t\t\t\tconst validatedData = schema.parse(input);\n\t\t\t\tc.set(\"validatedData\", validatedData);\n\t\t\t\treturn originalMethod.call(this, ...args);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\t\tconst errors = error.issues.map((err) => ({\n\t\t\t\t\t\tfield: err.path.join(\".\"),\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t\tcode: err.code,\n\t\t\t\t\t}));\n\t\t\t\t\treturn c.json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: \"Validation failed\", details: errors },\n\t\t\t\t\t\t\tmessage: errors[0].message ?? \"Validation failed\",\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t};\n\n\t\treturn descriptor;\n\t};\n}\n","import type { Context } from \"hono\";\nimport { z } from \"zod\";\n\nexport function QueryValidate(schema: z.ZodSchema) {\n\treturn function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n\t\tconst originalMethod = descriptor.value;\n\n\t\tdescriptor.value = async function (...args: any[]) {\n\t\t\tconst c: Context = args.find((a: any) => a != null && typeof a.json === \"function\" && a.req != null) ?? args[0];\n\t\t\ttry {\n\t\t\t\tconst queryParams = c.req.query();\n\t\t\t\tconst validatedData = schema.parse(queryParams);\n\t\t\t\tc.set(\"validatedQuery\", validatedData);\n\t\t\t\treturn originalMethod.call(this, ...args);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\t\tconst errors = error.issues.map((err: z.ZodIssue) => ({\n\t\t\t\t\t\tfield: err.path.join(\".\"),\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t\tcode: err.code,\n\t\t\t\t\t}));\n\t\t\t\t\treturn c.json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\t\t\t\tmessage: \"Query validation failed\",\n\t\t\t\t\t\t\t\tdetails: errors,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmessage: errors[0].message ?? \"Validation failed\",\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t};\n\n\t\treturn descriptor;\n\t};\n}\n","import { Injectable } from \"../decorators/core/injectable.decorator\";\n\n@Injectable()\nexport class Reflector {\n\tget<T = any>(metadataKey: string, target: Function): T {\n\t\treturn Reflect.getMetadata(metadataKey, target) as T;\n\t}\n\n\tgetAllAndOverride<T = any>(metadataKey: string, targets: Function[]): T {\n\t\tfor (const target of targets) {\n\t\t\tconst value = Reflect.getMetadata(metadataKey, target);\n\t\t\tif (value !== undefined) return value as T;\n\t\t}\n\t\treturn undefined as unknown as T;\n\t}\n\n\tgetAllAndMerge<T extends any[] = any[]>(metadataKey: string, targets: Function[]): T {\n\t\treturn targets.reduce<any[]>((acc, target) => {\n\t\t\tconst value = Reflect.getMetadata(metadataKey, target);\n\t\t\tif (Array.isArray(value)) return [...acc, ...value];\n\t\t\treturn acc;\n\t\t}, []) as T;\n\t}\n}\n","import type { Context } from \"hono\";\nimport type {\n\tBaseResponse,\n\tHttpStatusCode,\n\tPaginatedResponse,\n} from \"../interfaces/http/response.interface\";\n\nexport class _ResponseUtil {\n\tprivate static instance: _ResponseUtil;\n\tprivate logger: Console = console;\n\n\tprivate constructor() { } // Prevent direct instantiation\n\n\tstatic getInstance(): _ResponseUtil {\n\t\tif (!_ResponseUtil.instance) {\n\t\t\t_ResponseUtil.instance = new _ResponseUtil();\n\t\t}\n\t\treturn _ResponseUtil.instance;\n\t}\n\n\tsuccess<T>(c: Context, data: T, message?: string, status: HttpStatusCode = 200): Response {\n\t\tconst response: BaseResponse<T> = {\n\t\t\tsuccess: true,\n\t\t\tdata,\n\t\t\tmessage,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\treturn c.json(response, status);\n\t}\n\n\terror(c: Context, message: string, status: HttpStatusCode = 400): Response {\n\t\tconst response = {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tmessage,\n\t\t\t},\n\t\t\tmessage: message,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\treturn c.json(response, status);\n\t}\n\n\tpaginated<T>(\n\t\tc: Context,\n\t\tdata: T[],\n\t\tpage: number,\n\t\tlimit: number,\n\t\ttotal: number,\n\t\tmessage?: string,\n\t): Response {\n\t\tconst totalPages = Math.ceil(total / limit) ?? 1;\n\n\t\tconst response: PaginatedResponse<T> = {\n\t\t\tsuccess: true,\n\t\t\tdata,\n\t\t\tmessage,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tpagination: {\n\t\t\t\tpage,\n\t\t\t\tlimit,\n\t\t\t\ttotal,\n\t\t\t\ttotalPages,\n\t\t\t},\n\t\t};\n\n\t\treturn c.json(response);\n\t}\n}\n\nexport const ResponseUtil = _ResponseUtil.getInstance();\n","export function applyDecorators(\n\t...decorators: (ClassDecorator | MethodDecorator | PropertyDecorator)[]\n): (...args: any[]) => any {\n\treturn (target: any, key?: any, descriptor?: any): any => {\n\t\tfor (const decorator of decorators.reverse()) {\n\t\t\tconst result = (decorator as any)(target, key, descriptor);\n\t\t\tif (result !== undefined) {\n\t\t\t\tif (descriptor !== undefined) {\n\t\t\t\t\tdescriptor = result as PropertyDescriptor;\n\t\t\t\t} else {\n\t\t\t\t\ttarget = result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn descriptor ?? target;\n\t};\n}\n"],"mappings":"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","names":["existing","existing","existing","existing","injectable","injectable","injectable","z"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkYUBEJL4Tcjs = require('../chunk-YUBEJL4T.cjs');
|
|
5
|
+
require('../chunk-ZBDE64SD.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.errorHandler = _chunkYUBEJL4Tcjs.errorHandler; exports.requestLogger = _chunkYUBEJL4Tcjs.requestLogger;
|
|
10
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/sohanfahad/Documents/workspaces/cf-worker-workpace/cf-hono-starter/packages/core/dist/middleware/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACA;AACF,+GAAC","file":"/Users/sohanfahad/Documents/workspaces/cf-worker-workpace/cf-hono-starter/packages/core/dist/middleware/index.cjs"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as hono from 'hono';
|
|
2
|
+
import { Context, Next } from 'hono';
|
|
3
|
+
|
|
4
|
+
declare function errorHandler(c: Context, next: Next): Promise<(Response & hono.TypedResponse<{
|
|
5
|
+
success: boolean;
|
|
6
|
+
error: {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
timestamp: string;
|
|
11
|
+
} | {
|
|
12
|
+
timestamp: string;
|
|
13
|
+
success: boolean;
|
|
14
|
+
}, any, "json">) | undefined>;
|
|
15
|
+
|
|
16
|
+
declare function requestLogger(c: Context, next: Next): Promise<void>;
|
|
17
|
+
|
|
18
|
+
export { errorHandler, requestLogger };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as hono from 'hono';
|
|
2
|
+
import { Context, Next } from 'hono';
|
|
3
|
+
|
|
4
|
+
declare function errorHandler(c: Context, next: Next): Promise<(Response & hono.TypedResponse<{
|
|
5
|
+
success: boolean;
|
|
6
|
+
error: {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
timestamp: string;
|
|
11
|
+
} | {
|
|
12
|
+
timestamp: string;
|
|
13
|
+
success: boolean;
|
|
14
|
+
}, any, "json">) | undefined>;
|
|
15
|
+
|
|
16
|
+
declare function requestLogger(c: Context, next: Next): Promise<void>;
|
|
17
|
+
|
|
18
|
+
export { errorHandler, requestLogger };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ajke/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "NestJS-like framework core for Cloudflare Workers with Hono",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"cloudflare",
|
|
8
|
+
"workers",
|
|
9
|
+
"hono",
|
|
10
|
+
"framework",
|
|
11
|
+
"nestjs",
|
|
12
|
+
"typescript"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"main": "./dist/index.cjs",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"require": "./dist/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./middleware": {
|
|
25
|
+
"types": "./dist/middleware/index.d.ts",
|
|
26
|
+
"import": "./dist/middleware/index.js",
|
|
27
|
+
"require": "./dist/middleware/index.cjs"
|
|
28
|
+
},
|
|
29
|
+
"./config": {
|
|
30
|
+
"types": "./dist/config.d.ts",
|
|
31
|
+
"import": "./dist/config.js",
|
|
32
|
+
"require": "./dist/config.cjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"src"
|
|
38
|
+
],
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"hono": ">=4",
|
|
41
|
+
"reflect-metadata": ">=0.2",
|
|
42
|
+
"tsyringe": ">=4",
|
|
43
|
+
"zod": ">=3"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^25.7.0",
|
|
47
|
+
"rimraf": "^6.1.3",
|
|
48
|
+
"tsup": "^8.5.1",
|
|
49
|
+
"typescript": "^6.0.3"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup --config tsup.config.ts",
|
|
53
|
+
"prebuild": "rimraf dist",
|
|
54
|
+
"check": "tsc --noEmit"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Wilt — NestJS-like Framework for Cloudflare Workers
|
|
2
|
+
|
|
3
|
+
A lightweight, NestJS-inspired framework for building modular APIs on Cloudflare Workers using Hono as the HTTP layer.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Concepts
|
|
8
|
+
|
|
9
|
+
| Concept | Decorator / API | Purpose |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Module | `@Module` | Group controllers and providers |
|
|
12
|
+
| Global Module | `@Global` | Make a module's providers available everywhere |
|
|
13
|
+
| Controller | `@Controller` | Handle HTTP routes |
|
|
14
|
+
| Provider | `@Injectable` | Injectable service |
|
|
15
|
+
| Custom injection | `@Inject` | Explicit token injection |
|
|
16
|
+
| Optional dep | `@Optional` | Inject `undefined` if provider not registered |
|
|
17
|
+
| Guards | `@UseGuards` | Authorization — block requests early |
|
|
18
|
+
| Interceptors | `@UseInterceptors` | Transform requests/responses (logging, caching) |
|
|
19
|
+
| Exception filters | `@UseFilters` / `@Catch` | Handle specific thrown exceptions |
|
|
20
|
+
| Metadata | `@SetMetadata` + `Reflector` | Attach and read custom metadata |
|
|
21
|
+
| Lifecycle hooks | `OnModuleInit` | Run code after DI wiring |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## HTTP Decorators
|
|
26
|
+
|
|
27
|
+
### Route mapping
|
|
28
|
+
```typescript
|
|
29
|
+
@Get(path?) @Post(path?) @Put(path?) @Delete(path?) @Patch(path?)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Parameter decorators
|
|
33
|
+
Extract values directly as handler arguments — no manual `c.req` parsing needed.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
@Body(property?) // entire body, or body[property]
|
|
37
|
+
@Param(name?) // route param :name, or all params
|
|
38
|
+
@Query(name?) // query string ?name=, or all queries
|
|
39
|
+
@Headers(name?) // single header, or all headers as object
|
|
40
|
+
@Ip() // client IP (CF-Connecting-IP / X-Forwarded-For)
|
|
41
|
+
@Req() // full Hono Context — escape hatch
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Response decorators
|
|
45
|
+
```typescript
|
|
46
|
+
@HttpCode(201) // override default 200/204
|
|
47
|
+
@Header('Cache-Control', 'no-store') // set response header
|
|
48
|
+
@Redirect('/new-url', 301) // redirect (handler can return { url, statusCode } to override)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Validation
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
@ZodValidate(schema) // validate request body with Zod; result in c.get('validatedData')
|
|
57
|
+
@QueryValidate(schema) // validate query params with Zod; result in c.get('validatedQuery')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Guards
|
|
63
|
+
|
|
64
|
+
Implement `CanActivate` and decorate with `@UseGuards`.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { Injectable, CanActivate, ExecutionContext, UseGuards } from 'wilt';
|
|
68
|
+
|
|
69
|
+
@Injectable()
|
|
70
|
+
export class AuthGuard implements CanActivate {
|
|
71
|
+
canActivate(context: ExecutionContext): boolean {
|
|
72
|
+
const c = context.switchToHttp().getRequest();
|
|
73
|
+
return !!c.req.header('authorization');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Controller('/users')
|
|
78
|
+
@UseGuards(AuthGuard)
|
|
79
|
+
export class UsersController { ... }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
A guard returning `false` (or throwing) causes Wilt to throw `ForbiddenException` automatically.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Interceptors
|
|
87
|
+
|
|
88
|
+
Implement `NestInterceptor`. Useful for logging, response transformation, caching.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, UseInterceptors } from 'wilt';
|
|
92
|
+
|
|
93
|
+
@Injectable()
|
|
94
|
+
export class LoggingInterceptor implements NestInterceptor {
|
|
95
|
+
async intercept(context: ExecutionContext, next: CallHandler) {
|
|
96
|
+
const start = Date.now();
|
|
97
|
+
const result = await next.handle();
|
|
98
|
+
console.log(`Took ${Date.now() - start}ms`);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Get()
|
|
104
|
+
@UseInterceptors(LoggingInterceptor)
|
|
105
|
+
async getAll() { ... }
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Exception Filters
|
|
111
|
+
|
|
112
|
+
Implement `ExceptionFilter` and mark the exception types to catch with `@Catch`.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { Catch, ExceptionFilter, ArgumentsHost, HttpException, UseFilters } from 'wilt';
|
|
116
|
+
import type { Context } from 'hono';
|
|
117
|
+
|
|
118
|
+
@Catch(HttpException)
|
|
119
|
+
export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
|
|
120
|
+
catch(exception: HttpException, host: ArgumentsHost): Response {
|
|
121
|
+
const c = host.switchToHttp().getRequest<Context>();
|
|
122
|
+
return c.json({
|
|
123
|
+
statusCode: exception.getStatus(),
|
|
124
|
+
message: exception.getResponse(),
|
|
125
|
+
}, exception.getStatus() as any);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@Controller('/users')
|
|
130
|
+
@UseFilters(HttpExceptionFilter)
|
|
131
|
+
export class UsersController { ... }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## HTTP Exceptions
|
|
137
|
+
|
|
138
|
+
Throw these anywhere — the built-in `errorHandler` middleware catches them and returns the right status automatically.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
throw new BadRequestException('Invalid input');
|
|
142
|
+
throw new UnauthorizedException();
|
|
143
|
+
throw new ForbiddenException('Insufficient permissions');
|
|
144
|
+
throw new NotFoundException('User not found');
|
|
145
|
+
throw new ConflictException('Email already exists');
|
|
146
|
+
throw new UnprocessableEntityException({ message: 'Validation failed', errors: [...] });
|
|
147
|
+
throw new TooManyRequestsException();
|
|
148
|
+
throw new InternalServerErrorException();
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
All extend `HttpException`. You can extend it yourself:
|
|
152
|
+
```typescript
|
|
153
|
+
export class CustomException extends HttpException {
|
|
154
|
+
constructor() { super('Custom error', 418); }
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## SetMetadata + Reflector
|
|
161
|
+
|
|
162
|
+
Attach arbitrary metadata to a handler or class, then read it inside a guard or interceptor.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Define a helper decorator
|
|
166
|
+
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
|
|
167
|
+
|
|
168
|
+
// Use it on a route
|
|
169
|
+
@Roles('admin')
|
|
170
|
+
@Get()
|
|
171
|
+
async adminRoute() { ... }
|
|
172
|
+
|
|
173
|
+
// Read it in a guard
|
|
174
|
+
@Injectable()
|
|
175
|
+
export class RolesGuard implements CanActivate {
|
|
176
|
+
constructor(private reflector: Reflector) {}
|
|
177
|
+
|
|
178
|
+
canActivate(context: ExecutionContext): boolean {
|
|
179
|
+
const handler = context.getHandler();
|
|
180
|
+
const cls = context.getClass();
|
|
181
|
+
const required = this.reflector.getAllAndOverride<string[]>('roles', [handler, cls]);
|
|
182
|
+
if (!required) return true;
|
|
183
|
+
// ... check user roles
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Lifecycle Hooks
|
|
191
|
+
|
|
192
|
+
Implement `OnModuleInit` to run code after all DI wiring is done.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { Injectable, OnModuleInit } from 'wilt';
|
|
196
|
+
|
|
197
|
+
@Injectable()
|
|
198
|
+
export class DatabaseService implements OnModuleInit {
|
|
199
|
+
async onModuleInit() {
|
|
200
|
+
await this.connect();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Dependency Injection
|
|
208
|
+
|
|
209
|
+
### Basic injection
|
|
210
|
+
```typescript
|
|
211
|
+
@Injectable()
|
|
212
|
+
class ServiceA { }
|
|
213
|
+
|
|
214
|
+
@Injectable()
|
|
215
|
+
class ServiceB {
|
|
216
|
+
constructor(private a: ServiceA) {}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Explicit token
|
|
221
|
+
```typescript
|
|
222
|
+
constructor(@Inject(MyService) private svc: MyService) {}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Circular dependencies
|
|
226
|
+
```typescript
|
|
227
|
+
constructor(@Inject(forwardRef(() => ServiceB)) private b: ServiceB) {}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Optional
|
|
231
|
+
```typescript
|
|
232
|
+
constructor(@Optional() private cache?: CacheService) {}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Auto-Serialization
|
|
238
|
+
|
|
239
|
+
When parameter decorators (`@Body`, `@Param`, etc.) are used on a handler, Wilt automatically serializes the return value:
|
|
240
|
+
|
|
241
|
+
- `Response` object → returned as-is
|
|
242
|
+
- Plain object / array → `c.json(result, 200)` (or `@HttpCode` value)
|
|
243
|
+
- `undefined` / `null` → `204 No Content`
|
|
244
|
+
|
|
245
|
+
Without parameter decorators the handler receives the raw Hono `Context` as the first argument (backward-compatible with existing code).
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Module Setup
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// src/index.ts
|
|
253
|
+
import { createModule } from 'wilt';
|
|
254
|
+
import { errorHandler, requestLogger } from 'wilt';
|
|
255
|
+
import { AppModule } from './app.module';
|
|
256
|
+
|
|
257
|
+
const app = createModule(AppModule, {
|
|
258
|
+
middlewares: [errorHandler, requestLogger],
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
export default { fetch: app.fetch };
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## File Structure
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
src/wilt/
|
|
270
|
+
├── context/ # ExecutionContext, ArgumentsHost
|
|
271
|
+
├── decorators/
|
|
272
|
+
│ ├── core/ # @Injectable, @Inject, @Optional, @SetMetadata, @UseGuards, @UseInterceptors, @UseFilters, @Catch
|
|
273
|
+
│ ├── http/ # @Controller, @Get…@Patch, @Body…@Req, @HttpCode, @Header, @Redirect
|
|
274
|
+
│ └── modules/ # @Module, @Global
|
|
275
|
+
├── exceptions/ # HttpException + BadRequestException, NotFoundException, etc.
|
|
276
|
+
├── injector/ # createModule, resolveInstance, collectModuleTree
|
|
277
|
+
├── interfaces/
|
|
278
|
+
│ ├── core/ # CanActivate, NestInterceptor, ExceptionFilter, PipeTransform, lifecycle hooks
|
|
279
|
+
│ ├── http/ # BaseResponse, PaginatedResponse, ErrorResponse
|
|
280
|
+
│ └── modules/ # ModuleMetadata, RouteMetadata, ForwardReference
|
|
281
|
+
├── middleware/ # errorHandler, requestLogger
|
|
282
|
+
├── pipes/ # @ZodValidate, @QueryValidate, @Validate
|
|
283
|
+
├── services/ # Reflector
|
|
284
|
+
└── utils/ # ResponseUtil, Logger, forwardRef, applyDecorators
|
|
285
|
+
```
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface WiltConfig {
|
|
2
|
+
/** Directory where generated modules are placed. Default: "src/modules/app" */
|
|
3
|
+
modulesDir?: string;
|
|
4
|
+
/** Source directory. Default: "src" */
|
|
5
|
+
srcDir?: string;
|
|
6
|
+
/** Defaults applied when running `wilt generate module` */
|
|
7
|
+
generate?: {
|
|
8
|
+
files?: Array<"module" | "controller" | "service" | "dto" | "entity">;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function defineConfig(config: WiltConfig): WiltConfig {
|
|
13
|
+
return config;
|
|
14
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
|
|
3
|
+
export interface HttpArgumentsHost {
|
|
4
|
+
getRequest<T = Context>(): T;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ArgumentsHost {
|
|
8
|
+
switchToHttp(): HttpArgumentsHost;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ExecutionContext extends ArgumentsHost {
|
|
12
|
+
getClass<T = any>(): new (...args: any[]) => T;
|
|
13
|
+
getHandler(): Function;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createExecutionContext(
|
|
17
|
+
c: Context,
|
|
18
|
+
controllerClass: any,
|
|
19
|
+
handler: Function
|
|
20
|
+
): ExecutionContext {
|
|
21
|
+
return {
|
|
22
|
+
getClass: () => controllerClass,
|
|
23
|
+
getHandler: () => handler,
|
|
24
|
+
switchToHttp: () => ({
|
|
25
|
+
getRequest: <T = Context>() => c as unknown as T,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function createArgumentsHost(c: Context): ArgumentsHost {
|
|
31
|
+
return {
|
|
32
|
+
switchToHttp: () => ({
|
|
33
|
+
getRequest: <T = Context>() => c as unknown as T,
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./execution-context";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const FILTERS_METADATA = "wilt:filters";
|
|
2
|
+
export const CATCH_METADATA = "wilt:catch";
|
|
3
|
+
|
|
4
|
+
export function Catch(...exceptions: (new (...args: any[]) => any)[]): ClassDecorator {
|
|
5
|
+
return (target: any) => {
|
|
6
|
+
Reflect.defineMetadata(CATCH_METADATA, exceptions, target);
|
|
7
|
+
return target;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function UseFilters(
|
|
12
|
+
...filters: (new (...args: any[]) => any)[]
|
|
13
|
+
): MethodDecorator & ClassDecorator {
|
|
14
|
+
return (target: any, key?: any, descriptor?: PropertyDescriptor): any => {
|
|
15
|
+
if (descriptor) {
|
|
16
|
+
const existing: any[] = Reflect.getMetadata(FILTERS_METADATA, descriptor.value) || [];
|
|
17
|
+
Reflect.defineMetadata(FILTERS_METADATA, [...existing, ...filters], descriptor.value);
|
|
18
|
+
return descriptor;
|
|
19
|
+
}
|
|
20
|
+
const existing: any[] = Reflect.getMetadata(FILTERS_METADATA, target) || [];
|
|
21
|
+
Reflect.defineMetadata(FILTERS_METADATA, [...existing, ...filters], target);
|
|
22
|
+
return target;
|
|
23
|
+
};
|
|
24
|
+
}
|