@theokit/http 0.5.4 → 0.7.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.
Files changed (37) hide show
  1. package/LICENSE +201 -0
  2. package/dist/app.d.ts +16 -0
  3. package/dist/app.js +3 -3
  4. package/dist/{chunk-34KOKJ5M.js → chunk-CMPP4ULU.js} +3 -3
  5. package/dist/{chunk-U46H4CGF.js → chunk-ELCXHPAD.js} +2 -2
  6. package/dist/{chunk-NDD7ANXZ.js → chunk-GXTGOPRU.js} +124 -6
  7. package/dist/chunk-GXTGOPRU.js.map +1 -0
  8. package/dist/{chunk-QGB5YC4T.js → chunk-JQMJK47T.js} +31 -4
  9. package/dist/chunk-JQMJK47T.js.map +1 -0
  10. package/dist/{chunk-3PGQVQWG.js → chunk-KPC7AIVC.js} +3 -1
  11. package/dist/chunk-KPC7AIVC.js.map +1 -0
  12. package/dist/{chunk-LKNI6QEP.js → chunk-MQAJWR3K.js} +1 -1
  13. package/dist/chunk-MQAJWR3K.js.map +1 -0
  14. package/dist/chunk-OBHHOS6E.js +257 -0
  15. package/dist/chunk-OBHHOS6E.js.map +1 -0
  16. package/dist/exception-filter-chain-V2MFO4WV.js +10 -0
  17. package/dist/index.d.ts +343 -8
  18. package/dist/index.js +230 -23
  19. package/dist/index.js.map +1 -1
  20. package/dist/interceptor-chain-ELSL6KZT.js +9 -0
  21. package/dist/{middleware-consumer-ljxK1fU_.d.ts → middleware-consumer-DcaksawH.d.ts} +1 -1
  22. package/dist/theokit-plugin.d.ts +1 -1
  23. package/dist/theokit-plugin.js +7 -167
  24. package/dist/theokit-plugin.js.map +1 -1
  25. package/package.json +19 -17
  26. package/dist/chunk-3PGQVQWG.js.map +0 -1
  27. package/dist/chunk-LKNI6QEP.js.map +0 -1
  28. package/dist/chunk-LWCNTZN6.js +0 -87
  29. package/dist/chunk-LWCNTZN6.js.map +0 -1
  30. package/dist/chunk-NDD7ANXZ.js.map +0 -1
  31. package/dist/chunk-QGB5YC4T.js.map +0 -1
  32. package/dist/exception-filter-chain-BCSQ3MZ2.js +0 -10
  33. package/dist/interceptor-chain-6S3PUV7J.js +0 -9
  34. /package/dist/{chunk-34KOKJ5M.js.map → chunk-CMPP4ULU.js.map} +0 -0
  35. /package/dist/{chunk-U46H4CGF.js.map → chunk-ELCXHPAD.js.map} +0 -0
  36. /package/dist/{exception-filter-chain-BCSQ3MZ2.js.map → exception-filter-chain-V2MFO4WV.js.map} +0 -0
  37. /package/dist/{interceptor-chain-6S3PUV7J.js.map → interceptor-chain-ELSL6KZT.js.map} +0 -0
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  CONTROLLER_PREFIX,
3
+ EXPOSE_AGENT,
3
4
  ROUTE_HEADERS,
4
5
  ROUTE_METHODS,
5
6
  ROUTE_PARAMS,
@@ -9,7 +10,7 @@ import {
9
10
  USE_GUARDS,
10
11
  USE_INTERCEPTORS,
11
12
  getMeta
12
- } from "./chunk-3PGQVQWG.js";
13
+ } from "./chunk-KPC7AIVC.js";
13
14
  import {
14
15
  __name
15
16
  } from "./chunk-7QVYU63E.js";
@@ -110,8 +111,34 @@ function walkControllerMetadata(ControllerClass) {
110
111
  filters: getMeta(USE_FILTERS, ControllerClass, m.propertyKey) ?? classFilters
111
112
  };
112
113
  });
113
- walkCache.set(ControllerClass, result);
114
- return result;
114
+ const exposeEntries = getMeta(EXPOSE_AGENT, ControllerClass) ?? [];
115
+ const agentResults = exposeEntries.map((e) => {
116
+ const memberGuards = getMeta(USE_GUARDS, ControllerClass, e.propertyKey) ?? [];
117
+ const verb = "POST";
118
+ return {
119
+ verb,
120
+ fullPath: joinPath(prefix, String(e.propertyKey)),
121
+ propertyKey: e.propertyKey,
122
+ paramEntries: [],
123
+ headers: [],
124
+ guards: [
125
+ ...classGuards,
126
+ ...memberGuards
127
+ ],
128
+ interceptors: [],
129
+ filters: classFilters,
130
+ agent: {
131
+ module: e.agent,
132
+ opts: e.opts
133
+ }
134
+ };
135
+ });
136
+ const all = [
137
+ ...result,
138
+ ...agentResults
139
+ ];
140
+ walkCache.set(ControllerClass, all);
141
+ return all;
115
142
  }
116
143
  __name(walkControllerMetadata, "walkControllerMetadata");
117
144
 
@@ -122,4 +149,4 @@ export {
122
149
  joinPath,
123
150
  walkControllerMetadata
124
151
  };
125
- //# sourceMappingURL=chunk-QGB5YC4T.js.map
152
+ //# sourceMappingURL=chunk-JQMJK47T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridge/execution-context.ts","../src/bridge/dto-zod.ts","../src/bridge/errors.ts","../src/bridge/walk-metadata.ts"],"sourcesContent":["/**\n * ExecutionContext — Web Standard Request-based context passed to guards.\n *\n * Per ADR D460: the pipeline operates on Web Standard Request/Response.\n * node:http types live ONLY in the runtime adapter (runtime/node.ts).\n *\n * Guards access request headers via request.headers.get('x-role'),\n * NOT via req.headers['x-role'].\n */\n\n/**\n * Execution context available in guards during request processing.\n * Uses Web Standard Request (works on Node, Bun, Deno, CF Workers).\n */\nexport interface ExecutionContext {\n /** The Web Standard Request object. */\n getRequest(): Request\n /** Parsed URL (convenience — avoids re-parsing). */\n getUrl(): URL\n /** The controller class constructor. */\n getClass(): Function\n /** The handler method name (property key on the controller). */\n getMethodName(): string | symbol\n}\n\n/**\n * Interface for guard classes (bound via @UseGuards).\n *\n * @example\n * ```ts\n * class RolesGuard implements CanActivate {\n * canActivate(context: ExecutionContext): boolean {\n * const request = context.getRequest()\n * const role = request.headers.get('x-role')\n * return role === 'admin'\n * }\n * }\n * ```\n */\nexport interface CanActivate {\n canActivate(context: ExecutionContext): boolean | Promise<boolean>\n}\n\n/** Create an ExecutionContext from a Web Standard Request. */\nexport function createExecutionContext(\n request: Request,\n controllerClass: Function,\n methodName: string | symbol,\n): ExecutionContext {\n const url = new URL(request.url)\n return {\n getRequest: () => request,\n getUrl: () => url,\n getClass: () => controllerClass,\n getMethodName: () => methodName,\n }\n}\n","import type { z } from 'zod'\n\n/**\n * Resolves a Zod schema from a DTO class via the `static schema` convention (Pattern D2).\n * Returns undefined when the class doesn't carry a compatible schema.\n */\nexport function resolveDtoSchema(dtoClass: unknown): z.ZodType | undefined {\n if (typeof dtoClass !== 'function') return undefined\n const maybe = (dtoClass as unknown as Record<string, unknown>).schema\n if (\n maybe !== null &&\n maybe !== undefined &&\n typeof (maybe as Record<string, unknown>).safeParse === 'function'\n ) {\n return maybe as z.ZodType\n }\n return undefined\n}\n","/**\n * Configuration error thrown by the bridge when decorator setup is incomplete.\n * Carries actionable messages pointing consumers to the migration guide.\n */\nexport class HttpDecoratorsConfigError extends Error {\n override readonly name = 'HttpDecoratorsConfigError'\n\n constructor(message: string) {\n super(message)\n }\n}\n","import 'reflect-metadata'\nimport type { z } from 'zod'\n\nimport type { ControllerMeta } from '../decorators/controller.js'\nimport type { ExposeEntry, ExposeOptions } from '../decorators/expose.js'\nimport type { RouteMethodEntry, HttpVerb } from '../decorators/methods.js'\nimport type { ParamEntry } from '../decorators/params.js'\nimport type { RedirectMeta } from '../decorators/response.js'\nimport {\n getMeta,\n CONTROLLER_PREFIX,\n EXPOSE_AGENT,\n ROUTE_METHODS,\n ROUTE_PARAMS,\n ROUTE_STATUS,\n ROUTE_HEADERS,\n ROUTE_REDIRECT,\n USE_GUARDS,\n USE_INTERCEPTORS,\n USE_FILTERS,\n} from '../metadata/index.js'\n\nimport { resolveDtoSchema } from './dto-zod.js'\nimport { HttpDecoratorsConfigError } from './errors.js'\n\nexport interface WalkResult {\n verb: HttpVerb\n fullPath: string\n propertyKey: string | symbol\n bodySchema?: z.ZodType\n querySchema?: z.ZodType\n paramsSchema?: z.ZodType\n paramEntries: ParamEntry[]\n status?: number\n headers: [string, string][]\n redirect?: RedirectMeta\n guards: Function[]\n interceptors: Function[]\n filters: Function[]\n /**\n * M47 — set when the member is bound via `@Expose(agent, opts)`. The dispatcher delegates such routes to\n * the agent runtime (`mountAgent`) instead of invoking a JSON handler. `undefined` for normal verb routes.\n */\n agent?: { module: unknown; opts: ExposeOptions }\n}\n\n/**\n * Normalize a joined path: strip doubles, trim trailing, ensure leading.\n * (EC-3)\n */\nexport function joinPath(prefix: string, path: string): string {\n return ('/' + prefix + '/' + path).replace(/\\/+/g, '/').replace(/\\/$/, '') || '/'\n}\n\n/**\n * Resolve the Zod body schema for a method's @Body() param entry.\n *\n * Priority: explicit @Body(zodSchema) > design:paramtypes + DTO static schema.\n * EC-4 relaxed: warns (not throws) when paramtypes missing — @Body(zodSchema) is the fix.\n */\nfunction resolveBodySchema(\n paramEntries: ParamEntry[],\n ControllerClass: Function,\n propertyKey: string | symbol,\n): z.ZodType | undefined {\n const bodyParam = paramEntries.find((p) => p.source === 'body' && !p.key)\n if (!bodyParam) return undefined\n\n // Priority 1: explicit Zod schema from @Body(zodSchema)\n if (bodyParam.schema) return bodyParam.schema\n\n // Priority 2: design:paramtypes + DTO static schema (requires emitDecoratorMetadata)\n const paramTypes: Function[] =\n Reflect.getMetadata('design:paramtypes', ControllerClass.prototype, propertyKey) ?? []\n if (paramTypes.length > 0) {\n return resolveDtoSchema(paramTypes[bodyParam.index])\n }\n\n // EC-4 relaxed: warn when @Body() has no schema and no paramtypes\n console.warn(\n `[@theokit/http] method ${String(propertyKey)} on ` +\n `${ControllerClass.name}: @Body() without explicit schema and ` +\n `emitDecoratorMetadata is not active. Body will be passed raw (no validation). ` +\n `Fix: use @Body(zodSchema) for validation without metadata emission.`,\n )\n return undefined\n}\n\n/** WeakMap cache — metadata is immutable; walk once, reuse forever. */\nconst walkCache = new WeakMap<Function, WalkResult[]>()\n\n/**\n * Walk all decorator metadata on a controller class and produce\n * a structured list of route descriptors. Memoized per class via WeakMap.\n */\nexport function walkControllerMetadata(ControllerClass: Function): WalkResult[] {\n const cached = walkCache.get(ControllerClass)\n if (cached) return cached\n // EC-2: throw when @Controller decorator is missing\n const controllerMeta = getMeta<ControllerMeta>(CONTROLLER_PREFIX, ControllerClass)\n if (!controllerMeta) {\n throw new HttpDecoratorsConfigError(\n `Controller class ${ControllerClass.name} is missing @Controller() decorator. ` +\n `Add @Controller('prefix') to the class declaration.`,\n )\n }\n const { prefix, host } = controllerMeta\n\n // Q4: host captured but enforcement deferred to v0.2.0\n if (host) {\n console.warn(\n `[@theokit/http] @Controller host '${host}' captured but enforcement deferred to v0.2.0`,\n )\n }\n\n const methods = getMeta<RouteMethodEntry[]>(ROUTE_METHODS, ControllerClass) ?? []\n const paramsMap =\n getMeta<Map<string | symbol, ParamEntry[]>>(ROUTE_PARAMS, ControllerClass) ?? new Map()\n\n // Class-level guards/interceptors\n const classGuards = getMeta<Function[]>(USE_GUARDS, ControllerClass) ?? []\n const classInterceptors = getMeta<Function[]>(USE_INTERCEPTORS, ControllerClass) ?? []\n const classFilters = getMeta<Function[]>(USE_FILTERS, ControllerClass) ?? []\n\n const result = methods.map((m) => {\n const paramEntries = paramsMap.get(m.propertyKey) ?? []\n const bodySchema = resolveBodySchema(paramEntries, ControllerClass, m.propertyKey)\n\n // Method-level guards/interceptors (composed: class FIRST per NestJS convention — EC-9)\n const methodGuards = getMeta<Function[]>(USE_GUARDS, ControllerClass, m.propertyKey) ?? []\n const methodInterceptors =\n getMeta<Function[]>(USE_INTERCEPTORS, ControllerClass, m.propertyKey) ?? []\n\n return {\n verb: m.verb,\n fullPath: joinPath(prefix, m.path),\n propertyKey: m.propertyKey,\n bodySchema,\n paramEntries: [...paramEntries].sort((a, b) => a.index - b.index),\n status: getMeta<number>(ROUTE_STATUS, ControllerClass, m.propertyKey),\n headers: getMeta<[string, string][]>(ROUTE_HEADERS, ControllerClass, m.propertyKey) ?? [],\n redirect: getMeta<RedirectMeta>(ROUTE_REDIRECT, ControllerClass, m.propertyKey),\n guards: [...classGuards, ...methodGuards],\n interceptors: [...classInterceptors, ...methodInterceptors],\n filters: getMeta<Function[]>(USE_FILTERS, ControllerClass, m.propertyKey) ?? classFilters,\n }\n })\n\n // M47 — @Expose-bound members have no verb decorator, so they are absent from `methods`. Produce an\n // agent-serving WalkResult per binding: verb POST (agents are POST), path = prefix + member name (this\n // MUST be the agent's convention route so the generated handle's path matches — see ExposeOptions), the\n // agent module carried for the dispatcher, guards composed class-first (G5 shared guards). Interceptors\n // do NOT run for agent routes — the dispatcher delegates straight to `mountAgent` before the interceptor\n // chain — so they are intentionally not collected here (documented on `@Expose`).\n const exposeEntries = getMeta<ExposeEntry[]>(EXPOSE_AGENT, ControllerClass) ?? []\n const agentResults: WalkResult[] = exposeEntries.map((e) => {\n const memberGuards = getMeta<Function[]>(USE_GUARDS, ControllerClass, e.propertyKey) ?? []\n const verb: HttpVerb = 'POST'\n return {\n verb,\n fullPath: joinPath(prefix, String(e.propertyKey)),\n propertyKey: e.propertyKey,\n paramEntries: [],\n headers: [],\n guards: [...classGuards, ...memberGuards],\n interceptors: [],\n filters: classFilters,\n agent: { module: e.agent, opts: e.opts },\n }\n })\n\n const all = [...result, ...agentResults]\n walkCache.set(ControllerClass, all)\n return all\n}\n"],"mappings":"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","names":["createExecutionContext","request","controllerClass","methodName","url","URL","getRequest","getUrl","getClass","getMethodName","resolveDtoSchema","dtoClass","undefined","maybe","schema","safeParse","HttpDecoratorsConfigError","Error","name","message","joinPath","prefix","path","replace","resolveBodySchema","paramEntries","ControllerClass","propertyKey","bodyParam","find","p","source","key","undefined","schema","paramTypes","Reflect","getMetadata","prototype","length","resolveDtoSchema","index","console","warn","String","name","walkCache","WeakMap","walkControllerMetadata","cached","get","controllerMeta","getMeta","CONTROLLER_PREFIX","HttpDecoratorsConfigError","host","methods","ROUTE_METHODS","paramsMap","ROUTE_PARAMS","Map","classGuards","USE_GUARDS","classInterceptors","USE_INTERCEPTORS","classFilters","USE_FILTERS","result","map","m","bodySchema","methodGuards","methodInterceptors","verb","fullPath","sort","a","b","status","ROUTE_STATUS","headers","ROUTE_HEADERS","redirect","ROUTE_REDIRECT","guards","interceptors","filters","exposeEntries","EXPOSE_AGENT","agentResults","e","memberGuards","agent","module","opts","all","set"]}
@@ -13,6 +13,7 @@ var USE_GUARDS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:use-guards"
13
13
  var USE_INTERCEPTORS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:use-interceptors");
14
14
  var USE_FILTERS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:use-filters");
15
15
  var CATCH_EXCEPTIONS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:catch-exceptions");
16
+ var EXPOSE_AGENT = /* @__PURE__ */ Symbol.for("theokit:http-decorators:expose-agent");
16
17
 
17
18
  // src/metadata/storage.ts
18
19
  import "reflect-metadata";
@@ -247,6 +248,7 @@ export {
247
248
  USE_INTERCEPTORS,
248
249
  USE_FILTERS,
249
250
  CATCH_EXCEPTIONS,
251
+ EXPOSE_AGENT,
250
252
  setMeta,
251
253
  getMeta,
252
254
  HttpException,
@@ -273,4 +275,4 @@ export {
273
275
  TooManyRequestsException,
274
276
  HttpStatus
275
277
  };
276
- //# sourceMappingURL=chunk-3PGQVQWG.js.map
278
+ //# sourceMappingURL=chunk-KPC7AIVC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/metadata/keys.ts","../src/metadata/storage.ts","../src/exceptions/http-exception.ts"],"sourcesContent":["/**\n * Global Symbol-keyed metadata namespace constants for @theokit/http.\n *\n * Uses Symbol.for() (global Symbol registry) instead of Symbol() (local) because\n * the SWC loader imports controller files as separate module instances. With local\n * Symbols, the decorator-set metadata keys would be different Symbol instances from\n * the keys used by walkControllerMetadata — making metadata lookup silently fail.\n *\n * Symbol.for() ensures the SAME Symbol instance across module boundaries, which is\n * exactly how reflect-metadata keys should work in a multi-module decorator system.\n */\n\nexport const CONTROLLER_PREFIX = Symbol.for('theokit:http-decorators:controller-prefix')\nexport const ROUTE_METHODS = Symbol.for('theokit:http-decorators:route-methods')\nexport const ROUTE_PARAMS = Symbol.for('theokit:http-decorators:route-params')\nexport const ROUTE_STATUS = Symbol.for('theokit:http-decorators:route-status')\nexport const ROUTE_HEADERS = Symbol.for('theokit:http-decorators:route-headers')\nexport const ROUTE_REDIRECT = Symbol.for('theokit:http-decorators:route-redirect')\nexport const USE_GUARDS = Symbol.for('theokit:http-decorators:use-guards')\nexport const USE_INTERCEPTORS = Symbol.for('theokit:http-decorators:use-interceptors')\nexport const USE_FILTERS = Symbol.for('theokit:http-decorators:use-filters')\nexport const CATCH_EXCEPTIONS = Symbol.for('theokit:http-decorators:catch-exceptions')\nexport const EXPOSE_AGENT = Symbol.for('theokit:http-decorators:expose-agent')\n","import 'reflect-metadata'\n\n/**\n * Typed facade over Reflect.defineMetadata / Reflect.getMetadata.\n * Centralizes all reflect-metadata calls so decorators + bridge\n * never call Reflect.* directly (single import point for the polyfill).\n */\n\nexport function setMeta<T>(\n key: symbol,\n target: object,\n value: T,\n propertyKey?: string | symbol,\n): void {\n if (propertyKey !== undefined) {\n Reflect.defineMetadata(key, value, target, propertyKey)\n } else {\n Reflect.defineMetadata(key, value, target)\n }\n}\n\nexport function getMeta<T>(\n key: symbol,\n target: object,\n propertyKey?: string | symbol,\n): T | undefined {\n if (propertyKey !== undefined) {\n return Reflect.getMetadata(key, target, propertyKey) as T | undefined\n }\n return Reflect.getMetadata(key, target) as T | undefined\n}\n","/**\n * HttpException hierarchy for @theokit/http.\n *\n * Per ADR D2: response shape {error: {code, message, statusCode}} matches\n * existing guard (401) and validation (422) format.\n */\n\nconst STATUS_CODES: Record<number, string> = {\n 400: 'BAD_REQUEST',\n 401: 'UNAUTHORIZED',\n 403: 'FORBIDDEN',\n 404: 'NOT_FOUND',\n 405: 'METHOD_NOT_ALLOWED',\n 406: 'NOT_ACCEPTABLE',\n 408: 'REQUEST_TIMEOUT',\n 409: 'CONFLICT',\n 410: 'GONE',\n 412: 'PRECONDITION_FAILED',\n 413: 'PAYLOAD_TOO_LARGE',\n 415: 'UNSUPPORTED_MEDIA_TYPE',\n 418: 'IM_A_TEAPOT',\n 422: 'UNPROCESSABLE_ENTITY',\n 429: 'TOO_MANY_REQUESTS',\n 500: 'INTERNAL_SERVER_ERROR',\n 501: 'NOT_IMPLEMENTED',\n 502: 'BAD_GATEWAY',\n 503: 'SERVICE_UNAVAILABLE',\n 504: 'GATEWAY_TIMEOUT',\n 505: 'HTTP_VERSION_NOT_SUPPORTED',\n}\n\nexport interface HttpExceptionOptions {\n cause?: Error\n description?: string\n}\n\nexport class HttpException extends Error {\n public readonly statusCode: number\n public readonly code: string\n public readonly description?: string\n\n constructor(message: string, statusCode: number, options?: HttpExceptionOptions) {\n super(message, options?.cause ? { cause: options.cause } : undefined)\n this.name = this.constructor.name\n this.statusCode = statusCode\n this.code = STATUS_CODES[statusCode] ?? 'INTERNAL_SERVER_ERROR'\n this.description = options?.description\n }\n\n toJSON() {\n return {\n error: {\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n ...(this.description ? { description: this.description } : {}),\n },\n }\n }\n}\n\nfunction factory(status: number, defaultMsg: string) {\n return class extends HttpException {\n constructor(message = defaultMsg, options?: HttpExceptionOptions) {\n super(message, status, options)\n this.name = this.constructor.name\n }\n }\n}\n\nexport class BadRequestException extends factory(400, 'Bad Request') {}\nexport class UnauthorizedException extends factory(401, 'Unauthorized') {}\nexport class ForbiddenException extends factory(403, 'Forbidden') {}\nexport class NotFoundException extends factory(404, 'Not Found') {}\nexport class MethodNotAllowedException extends factory(405, 'Method Not Allowed') {}\nexport class NotAcceptableException extends factory(406, 'Not Acceptable') {}\nexport class RequestTimeoutException extends factory(408, 'Request Timeout') {}\nexport class ConflictException extends factory(409, 'Conflict') {}\nexport class GoneException extends factory(410, 'Gone') {}\nexport class PreconditionFailedException extends factory(412, 'Precondition Failed') {}\nexport class PayloadTooLargeException extends factory(413, 'Payload Too Large') {}\nexport class UnsupportedMediaTypeException extends factory(415, 'Unsupported Media Type') {}\nexport class ImATeapotException extends factory(418, \"I'm a Teapot\") {}\nexport class UnprocessableEntityException extends factory(422, 'Unprocessable Entity') {}\nexport class InternalServerErrorException extends factory(500, 'Internal Server Error') {}\nexport class NotImplementedException extends factory(501, 'Not Implemented') {}\nexport class BadGatewayException extends factory(502, 'Bad Gateway') {}\nexport class ServiceUnavailableException extends factory(503, 'Service Unavailable') {}\nexport class GatewayTimeoutException extends factory(504, 'Gateway Timeout') {}\nexport class HttpVersionNotSupportedException extends factory(505, 'HTTP Version Not Supported') {}\nexport class TooManyRequestsException extends factory(429, 'Too Many Requests') {}\n\n/**\n * HttpStatus enum — all standard HTTP status codes as named constants.\n *\n * @example\n * ```ts\n * import { HttpStatus } from '@theokit/http'\n *\n * @HttpCode(HttpStatus.CREATED)\n * @Post()\n * create() { ... }\n *\n * if (res.status === HttpStatus.NOT_FOUND) { ... }\n * ```\n */\nexport const HttpStatus = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Error\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n UNSUPPORTED_MEDIA_TYPE: 415,\n IM_A_TEAPOT: 418,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n // 5xx Server Error\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus]\n"],"mappings":"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","names":["CONTROLLER_PREFIX","Symbol","for","ROUTE_METHODS","ROUTE_PARAMS","ROUTE_STATUS","ROUTE_HEADERS","ROUTE_REDIRECT","USE_GUARDS","USE_INTERCEPTORS","USE_FILTERS","CATCH_EXCEPTIONS","EXPOSE_AGENT","setMeta","key","target","value","propertyKey","undefined","Reflect","defineMetadata","getMeta","getMetadata","STATUS_CODES","HttpException","Error","statusCode","code","description","message","options","cause","undefined","name","toJSON","error","factory","status","defaultMsg","BadRequestException","UnauthorizedException","ForbiddenException","NotFoundException","MethodNotAllowedException","NotAcceptableException","RequestTimeoutException","ConflictException","GoneException","PreconditionFailedException","PayloadTooLargeException","UnsupportedMediaTypeException","ImATeapotException","UnprocessableEntityException","InternalServerErrorException","NotImplementedException","BadGatewayException","ServiceUnavailableException","GatewayTimeoutException","HttpVersionNotSupportedException","TooManyRequestsException","HttpStatus","OK","CREATED","ACCEPTED","NO_CONTENT","MOVED_PERMANENTLY","FOUND","NOT_MODIFIED","TEMPORARY_REDIRECT","PERMANENT_REDIRECT","BAD_REQUEST","UNAUTHORIZED","PAYMENT_REQUIRED","FORBIDDEN","NOT_FOUND","METHOD_NOT_ALLOWED","NOT_ACCEPTABLE","REQUEST_TIMEOUT","CONFLICT","GONE","PRECONDITION_FAILED","PAYLOAD_TOO_LARGE","UNSUPPORTED_MEDIA_TYPE","IM_A_TEAPOT","UNPROCESSABLE_ENTITY","TOO_MANY_REQUESTS","INTERNAL_SERVER_ERROR","NOT_IMPLEMENTED","BAD_GATEWAY","SERVICE_UNAVAILABLE","GATEWAY_TIMEOUT"]}
@@ -17,4 +17,4 @@ __name(resolveOrNew, "resolveOrNew");
17
17
  export {
18
18
  resolveOrNew
19
19
  };
20
- //# sourceMappingURL=chunk-LKNI6QEP.js.map
20
+ //# sourceMappingURL=chunk-MQAJWR3K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridge/di-resolve.ts"],"sourcesContent":["/**\n * Shared DI resolution helper for guards, interceptors, and middleware.\n * Extracted to avoid DRY violation (EC-3) — was duplicated in create-server.ts\n * and theokit-plugin.ts.\n */\n\n/** DI container interface — structural match for @theokit/di Container. */\nexport interface DiContainer {\n resolve(token: Function): unknown\n}\n\n/**\n * Resolve a class via DI container if provided; otherwise fall back to bare `new`.\n * Guards, interceptors, and middleware classes all use this pattern.\n */\nexport function resolveOrNew(Ctor: Function, container?: DiContainer): object {\n if (container) {\n try {\n return container.resolve(Ctor) as object\n } catch {\n // MissingInjectableError or similar — fall back to bare new\n }\n }\n return new (Ctor as new () => object)()\n}\n"],"mappings":";;;;;AAeO,SAASA,aAAaC,MAAgBC,WAAuB;AAClE,MAAIA,WAAW;AACb,QAAI;AACF,aAAOA,UAAUC,QAAQF,IAAAA;IAC3B,QAAQ;IAER;EACF;AACA,SAAO,IAAKA,KAAAA;AACd;AATgBD;","names":["resolveOrNew","Ctor","container","resolve"]}
@@ -0,0 +1,257 @@
1
+ import {
2
+ HttpDecoratorsConfigError
3
+ } from "./chunk-JQMJK47T.js";
4
+ import {
5
+ resolveOrNew
6
+ } from "./chunk-MQAJWR3K.js";
7
+ import {
8
+ __name
9
+ } from "./chunk-7QVYU63E.js";
10
+
11
+ // src/bridge/middleware-consumer.ts
12
+ var MiddlewareConsumerImpl = class {
13
+ static {
14
+ __name(this, "MiddlewareConsumerImpl");
15
+ }
16
+ entries = [];
17
+ container;
18
+ constructor(container) {
19
+ this.container = container;
20
+ }
21
+ apply(...middleware) {
22
+ const resolved = middleware.map((m) => this.resolveMiddleware(m));
23
+ const excludePatterns = [];
24
+ const proxy = {
25
+ exclude: /* @__PURE__ */ __name((...routes) => {
26
+ for (const r of routes) excludePatterns.push(typeof r === "string" ? r : r.path);
27
+ return proxy;
28
+ }, "exclude"),
29
+ forRoutes: /* @__PURE__ */ __name((...routes) => {
30
+ const routePatterns = routes.map((r) => typeof r === "string" ? r : r.path);
31
+ for (const handler of resolved) {
32
+ this.entries.push({
33
+ handler,
34
+ routePatterns: [
35
+ ...routePatterns
36
+ ],
37
+ excludePatterns: [
38
+ ...excludePatterns
39
+ ]
40
+ });
41
+ }
42
+ return this;
43
+ }, "forRoutes")
44
+ };
45
+ return proxy;
46
+ }
47
+ getEntries() {
48
+ return this.entries;
49
+ }
50
+ resolveMiddleware(m) {
51
+ if (typeof m === "function" && !m.prototype?.use) {
52
+ return m;
53
+ }
54
+ const instance = resolveOrNew(m, this.container);
55
+ return (request, next) => instance.use(request, next);
56
+ }
57
+ };
58
+ function middlewareMatchesPath(entry, requestPath) {
59
+ for (const pattern of entry.excludePatterns) {
60
+ if (pathMatches(requestPath, pattern)) return false;
61
+ }
62
+ for (const pattern of entry.routePatterns) {
63
+ if (pathMatches(requestPath, pattern)) return true;
64
+ }
65
+ return false;
66
+ }
67
+ __name(middlewareMatchesPath, "middlewareMatchesPath");
68
+ function pathMatches(requestPath, pattern) {
69
+ if (pattern === "*") return true;
70
+ const normPath = ("/" + requestPath).replace(/\/+/g, "/").replace(/\/$/, "");
71
+ const normPattern = ("/" + pattern).replace(/\/+/g, "/").replace(/\/$/, "");
72
+ return normPath === normPattern || normPath.startsWith(normPattern + "/");
73
+ }
74
+ __name(pathMatches, "pathMatches");
75
+ async function runMiddleware(entries, request, requestPath) {
76
+ for (const entry of entries) {
77
+ if (!middlewareMatchesPath(entry, requestPath)) continue;
78
+ const response = await entry.handler(request, () => Promise.resolve(null));
79
+ if (response) return response;
80
+ }
81
+ return null;
82
+ }
83
+ __name(runMiddleware, "runMiddleware");
84
+
85
+ // src/bridge/swc-loader.ts
86
+ import "reflect-metadata";
87
+ import { readFileSync, writeFileSync, unlinkSync, readdirSync } from "fs";
88
+ import { createRequire } from "module";
89
+ import { resolve, dirname, join, relative } from "path";
90
+ import { pathToFileURL, fileURLToPath } from "url";
91
+ function getSwcrcTarget(swcrc) {
92
+ if (!swcrc) return "es2022";
93
+ const jsc = swcrc.jsc;
94
+ if (typeof jsc !== "object" || jsc === null) return "es2022";
95
+ const target = jsc.target;
96
+ return typeof target === "string" ? target : "es2022";
97
+ }
98
+ __name(getSwcrcTarget, "getSwcrcTarget");
99
+ var consumerSwcrcCache;
100
+ function readConsumerSwcrc(startDir) {
101
+ if (consumerSwcrcCache !== void 0) return consumerSwcrcCache;
102
+ let dir = startDir;
103
+ const root = dirname(dir);
104
+ while (dir !== root) {
105
+ const candidate = join(dir, ".swcrc");
106
+ try {
107
+ const raw = readFileSync(candidate, "utf-8");
108
+ const parsed = JSON.parse(raw);
109
+ delete parsed.$schema;
110
+ consumerSwcrcCache = parsed;
111
+ return parsed;
112
+ } catch {
113
+ }
114
+ const parent = dirname(dir);
115
+ if (parent === dir) break;
116
+ dir = parent;
117
+ }
118
+ consumerSwcrcCache = null;
119
+ return null;
120
+ }
121
+ __name(readConsumerSwcrc, "readConsumerSwcrc");
122
+ var swcCoreCache;
123
+ async function loadSwcCore() {
124
+ if (swcCoreCache !== void 0) return swcCoreCache;
125
+ try {
126
+ swcCoreCache = await import("@swc/core");
127
+ } catch {
128
+ try {
129
+ const thisDir = dirname(fileURLToPath(import.meta.url));
130
+ const req = createRequire(resolve(thisDir, "index.js"));
131
+ const resolved = req.resolve("@swc/core");
132
+ swcCoreCache = await import(pathToFileURL(resolved).href);
133
+ } catch {
134
+ swcCoreCache = null;
135
+ }
136
+ }
137
+ return swcCoreCache;
138
+ }
139
+ __name(loadSwcCore, "loadSwcCore");
140
+ async function transformControllerSource(source, filename, loadSwc = loadSwcCore) {
141
+ const swc = await loadSwc();
142
+ if (!swc) {
143
+ throw new HttpDecoratorsConfigError(`@swc/core is required for parameter decorators (@Body, @Param, @Query). Install it:
144
+
145
+ pnpm add -D @swc/core
146
+
147
+ esbuild (used by tsx/Vite) cannot parse parameter decorators. SWC handles them correctly with full metadata emission.`);
148
+ }
149
+ const consumerSwcrc = readConsumerSwcrc(dirname(filename));
150
+ const consumerJsc = consumerSwcrc?.jsc && typeof consumerSwcrc.jsc === "object" ? consumerSwcrc.jsc : null;
151
+ const { code } = swc.transformSync(source, {
152
+ filename,
153
+ jsc: {
154
+ parser: {
155
+ syntax: "typescript",
156
+ decorators: true,
157
+ ...consumerJsc?.parser
158
+ },
159
+ transform: {
160
+ ...consumerJsc?.transform,
161
+ // NON-NEGOTIABLE — always enforce decorator metadata emission
162
+ // regardless of consumer .swcrc overrides
163
+ legacyDecorator: true,
164
+ decoratorMetadata: true
165
+ },
166
+ target: getSwcrcTarget(consumerSwcrc)
167
+ },
168
+ module: {
169
+ type: "es6"
170
+ },
171
+ sourceMaps: false
172
+ });
173
+ return code;
174
+ }
175
+ __name(transformControllerSource, "transformControllerSource");
176
+ async function loadControllerWithSwc(absoluteFilePath) {
177
+ const source = readFileSync(absoluteFilePath, "utf-8");
178
+ const code = await transformControllerSource(source, absoluteFilePath);
179
+ const tmpPath = absoluteFilePath.replace(/\.ts$/, ".__decorated__.mjs");
180
+ writeFileSync(tmpPath, code, "utf-8");
181
+ try {
182
+ const url = pathToFileURL(tmpPath).href + `?t=${Date.now()}`;
183
+ return await import(url);
184
+ } finally {
185
+ try {
186
+ unlinkSync(tmpPath);
187
+ } catch {
188
+ }
189
+ }
190
+ }
191
+ __name(loadControllerWithSwc, "loadControllerWithSwc");
192
+ async function loadControllersFromGlob(rootDir, pattern) {
193
+ const files = scanControllerFiles(rootDir, pattern);
194
+ if (files.length === 0) {
195
+ console.warn(`[@theokit/http] No controller files found matching "${pattern}" in ${rootDir}. Ensure files match the pattern and export @Controller classes.`);
196
+ return [];
197
+ }
198
+ const controllers = [];
199
+ for (const file of files) {
200
+ const absPath = resolve(rootDir, file);
201
+ const mod = await loadControllerWithSwc(absPath);
202
+ for (const exported of Object.values(mod)) {
203
+ if (typeof exported === "function" && isControllerClass(exported)) {
204
+ controllers.push(exported);
205
+ }
206
+ }
207
+ }
208
+ return controllers;
209
+ }
210
+ __name(loadControllersFromGlob, "loadControllersFromGlob");
211
+ function isControllerClass(fn) {
212
+ try {
213
+ return Reflect.hasMetadata(/* @__PURE__ */ Symbol.for("theokit:http-decorators:controller-prefix"), fn);
214
+ } catch {
215
+ return false;
216
+ }
217
+ }
218
+ __name(isControllerClass, "isControllerClass");
219
+ function scanControllerFiles(rootDir, pattern) {
220
+ const parts = pattern.split("/");
221
+ const dirParts = [];
222
+ for (const part of parts) {
223
+ if (part.includes("*")) break;
224
+ dirParts.push(part);
225
+ }
226
+ const baseDir = join(rootDir, ...dirParts);
227
+ const lastPart = parts[parts.length - 1];
228
+ const suffix = lastPart.replace(/\*/g, "");
229
+ const files = [];
230
+ function walk(dir) {
231
+ try {
232
+ for (const entry of readdirSync(dir, {
233
+ withFileTypes: true
234
+ })) {
235
+ const full = join(dir, entry.name);
236
+ if (entry.isDirectory()) walk(full);
237
+ else if (entry.name.endsWith(suffix)) files.push(relative(rootDir, full));
238
+ }
239
+ } catch {
240
+ }
241
+ }
242
+ __name(walk, "walk");
243
+ walk(baseDir);
244
+ return files;
245
+ }
246
+ __name(scanControllerFiles, "scanControllerFiles");
247
+
248
+ export {
249
+ MiddlewareConsumerImpl,
250
+ middlewareMatchesPath,
251
+ runMiddleware,
252
+ transformControllerSource,
253
+ loadControllerWithSwc,
254
+ loadControllersFromGlob,
255
+ isControllerClass
256
+ };
257
+ //# sourceMappingURL=chunk-OBHHOS6E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridge/middleware-consumer.ts","../src/bridge/swc-loader.ts"],"sourcesContent":["/**\n * NestJS-style Middleware support — Web Standard Request/Response.\n *\n * Middleware runs BEFORE guards: middleware → guards → interceptors → handler\n *\n * Supports class middleware (NestMiddleware) and functional middleware.\n * Returns a Response to short-circuit, or null to continue.\n */\nimport { resolveOrNew, type DiContainer } from './di-resolve.js'\n\n/** NestJS-compatible middleware interface — Web Standard. */\nexport interface NestMiddleware {\n use(\n request: Request,\n next: () => Promise<Response | null>,\n ): Response | null | Promise<Response | null>\n}\n\n/** Functional middleware. */\nexport type MiddlewareFn = (\n request: Request,\n next: () => Promise<Response | null>,\n) => Response | null | Promise<Response | null>\n\nexport interface ResolvedMiddleware {\n handler: MiddlewareFn\n routePatterns: string[]\n excludePatterns: string[]\n}\n\nexport type RouteInfo = string | { path: string; method?: string }\n\nexport interface MiddlewareConfigProxy {\n forRoutes(...routes: RouteInfo[]): MiddlewareConsumerImpl\n exclude(...routes: RouteInfo[]): MiddlewareConfigProxy\n}\n\nexport class MiddlewareConsumerImpl {\n private entries: ResolvedMiddleware[] = []\n private container?: DiContainer\n\n constructor(container?: DiContainer) {\n this.container = container\n }\n\n apply(...middleware: (Function | MiddlewareFn)[]): MiddlewareConfigProxy {\n const resolved = middleware.map((m) => this.resolveMiddleware(m))\n const excludePatterns: string[] = []\n\n const proxy: MiddlewareConfigProxy = {\n exclude: (...routes: RouteInfo[]) => {\n for (const r of routes) excludePatterns.push(typeof r === 'string' ? r : r.path)\n return proxy\n },\n forRoutes: (...routes: RouteInfo[]) => {\n const routePatterns = routes.map((r) => (typeof r === 'string' ? r : r.path))\n for (const handler of resolved) {\n this.entries.push({ handler, routePatterns: [...routePatterns], excludePatterns: [...excludePatterns] })\n }\n return this\n },\n }\n return proxy\n }\n\n getEntries(): ResolvedMiddleware[] {\n return this.entries\n }\n\n private resolveMiddleware(m: Function | MiddlewareFn): MiddlewareFn {\n if (typeof m === 'function' && !m.prototype?.use) {\n return m as MiddlewareFn\n }\n const instance = resolveOrNew(m, this.container) as NestMiddleware\n return (request, next) => instance.use(request, next)\n }\n}\n\nexport function middlewareMatchesPath(entry: ResolvedMiddleware, requestPath: string): boolean {\n for (const pattern of entry.excludePatterns) {\n if (pathMatches(requestPath, pattern)) return false\n }\n for (const pattern of entry.routePatterns) {\n if (pathMatches(requestPath, pattern)) return true\n }\n return false\n}\n\nfunction pathMatches(requestPath: string, pattern: string): boolean {\n if (pattern === '*') return true\n const normPath = ('/' + requestPath).replace(/\\/+/g, '/').replace(/\\/$/, '')\n const normPattern = ('/' + pattern).replace(/\\/+/g, '/').replace(/\\/$/, '')\n return normPath === normPattern || normPath.startsWith(normPattern + '/')\n}\n\n/**\n * Run all matching middleware. Returns a Response if any short-circuited, null otherwise.\n */\nexport async function runMiddleware(\n entries: ResolvedMiddleware[],\n request: Request,\n requestPath: string,\n): Promise<Response | null> {\n for (const entry of entries) {\n if (!middlewareMatchesPath(entry, requestPath)) continue\n const response = await entry.handler(request, () => Promise.resolve(null))\n if (response) return response // short-circuit\n }\n return null\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * The SWC loader reads/writes controller files by absolute path derived\n * from developer-authored glob patterns in theo.config.ts, not from HTTP\n * input. The file paths come from scanControllerFiles() which walks the\n * project's own source tree. No injection vector.\n */\n/**\n * SWC-powered module loader for controller files with parameter decorators.\n *\n * esbuild (used by tsx/Vite SSR) fundamentally cannot parse TypeScript\n * parameter decorators (`@Body()`, `@Param()`, `@Query()`). This loader\n * uses @swc/core to transform controller files with full decorator support\n * (legacyDecorator + decoratorMetadata), then imports them via a temp .mjs\n * file written in the SAME directory (preserving relative import resolution).\n *\n * Pattern: follows Next.js's approach (read tsconfig → configure SWC)\n * but scoped to the http-decorators package, not the framework core.\n *\n * @see references/next.js/packages/next/src/build/swc/options.ts\n */\nimport 'reflect-metadata'\nimport { readFileSync, writeFileSync, unlinkSync, readdirSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { resolve, dirname, join, relative } from 'node:path'\nimport { pathToFileURL, fileURLToPath } from 'node:url'\n\nimport { HttpDecoratorsConfigError } from './errors.js'\n\n/** Extract jsc.target from parsed .swcrc or fall back to es2022. */\nfunction getSwcrcTarget(swcrc: Record<string, unknown> | null): string {\n if (!swcrc) return 'es2022'\n const jsc = swcrc.jsc\n if (typeof jsc !== 'object' || jsc === null) return 'es2022'\n const target = (jsc as Record<string, unknown>).target\n return typeof target === 'string' ? target : 'es2022'\n}\n\n/** Cached consumer .swcrc — read once per process. */\nlet consumerSwcrcCache: Record<string, unknown> | null | undefined\n\n/**\n * Walk up from the controller file's directory to find a .swcrc.\n * Returns the parsed JSON or null if none found.\n * Caches the result — .swcrc doesn't change at runtime.\n */\nfunction readConsumerSwcrc(startDir: string): Record<string, unknown> | null {\n if (consumerSwcrcCache !== undefined) return consumerSwcrcCache\n\n let dir = startDir\n const root = dirname(dir) // stop at filesystem root\n while (dir !== root) {\n const candidate = join(dir, '.swcrc')\n try {\n const raw = readFileSync(candidate, 'utf-8')\n const parsed = JSON.parse(raw) as Record<string, unknown>\n // Strip $schema — not an SWC transform option\n delete parsed.$schema\n consumerSwcrcCache = parsed\n return parsed\n } catch {\n // File doesn't exist or invalid JSON — walk up\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n\n consumerSwcrcCache = null\n return null\n}\n\nexport interface SwcCore {\n transformSync: (src: string, opts: unknown) => { code: string }\n}\n\n/** Cached @swc/core instance — loaded once, reused across all controller files. */\nlet swcCoreCache: SwcCore | null | undefined\n\n/**\n * Dynamically load @swc/core with singleton cache.\n *\n * Handles pnpm strict node_modules: @swc/core is only directly importable\n * from the package that declares it as a dependency. We use createRequire\n * rooted at THIS package's directory to resolve correctly.\n *\n * The cache ensures the ~50ms dynamic import() cost is paid ONCE,\n * not per-controller-file.\n */\nasync function loadSwcCore(): Promise<SwcCore | null> {\n if (swcCoreCache !== undefined) return swcCoreCache\n\n try {\n swcCoreCache = (await import('@swc/core')) as SwcCore\n } catch {\n try {\n const thisDir = dirname(fileURLToPath(import.meta.url))\n const req = createRequire(resolve(thisDir, 'index.js'))\n const resolved = req.resolve('@swc/core')\n swcCoreCache = (await import(pathToFileURL(resolved).href)) as SwcCore\n } catch {\n swcCoreCache = null\n }\n }\n return swcCoreCache\n}\n\n/**\n * Transform TypeScript controller SOURCE (with parameter decorators) into\n * ESM code, emitting the `design:paramtypes` / decorator metadata that esbuild\n * cannot produce. Pure code→code — no file I/O, no module load — so it is\n * reusable both by {@link loadControllerWithSwc} (which then temp-writes +\n * imports) and by a build-tool transform hook that returns `{ code }` directly.\n *\n * The `@swc/core` loader is injectable (`loadSwc`) for testability; it defaults\n * to the cached singleton.\n *\n * @throws HttpDecoratorsConfigError when @swc/core is unavailable.\n */\nexport async function transformControllerSource(\n source: string,\n filename: string,\n loadSwc: () => Promise<SwcCore | null> = loadSwcCore,\n): Promise<string> {\n const swc = await loadSwc()\n if (!swc) {\n throw new HttpDecoratorsConfigError(\n `@swc/core is required for parameter decorators (@Body, @Param, @Query). ` +\n `Install it:\\n\\n pnpm add -D @swc/core\\n\\n` +\n `esbuild (used by tsx/Vite) cannot parse parameter decorators. ` +\n `SWC handles them correctly with full metadata emission.`,\n )\n }\n\n const consumerSwcrc = readConsumerSwcrc(dirname(filename))\n const consumerJsc =\n consumerSwcrc?.jsc && typeof consumerSwcrc.jsc === 'object'\n ? (consumerSwcrc.jsc as Record<string, unknown>)\n : null\n const { code } = swc.transformSync(source, {\n filename,\n jsc: {\n parser: {\n syntax: 'typescript',\n decorators: true,\n ...(consumerJsc?.parser as Record<string, unknown> | undefined),\n },\n transform: {\n ...(consumerJsc?.transform as Record<string, unknown> | undefined),\n // NON-NEGOTIABLE — always enforce decorator metadata emission\n // regardless of consumer .swcrc overrides\n legacyDecorator: true,\n decoratorMetadata: true,\n },\n target: getSwcrcTarget(consumerSwcrc),\n },\n module: { type: 'es6' },\n sourceMaps: false,\n })\n return code\n}\n\n/**\n * Load a TypeScript controller file using @swc/core for decorator support.\n *\n * Strategy:\n * 1. Read source .ts file\n * 2. Transform via {@link transformControllerSource} (legacyDecorator + metadata)\n * 3. Write temp .mjs in SAME directory (relative imports resolve correctly)\n * 4. Dynamic import() the .mjs — transitive .ts imports go through\n * tsx/Vite's global hook (they don't have parameter decorators)\n * 5. Cleanup temp file\n */\nexport async function loadControllerWithSwc(\n absoluteFilePath: string,\n): Promise<Record<string, unknown>> {\n const source = readFileSync(absoluteFilePath, 'utf-8')\n const code = await transformControllerSource(source, absoluteFilePath)\n\n // Write temp .mjs in SAME directory so relative imports resolve identically.\n // .mjs = Node treats as ESM regardless of package.json type field.\n // Transitive .ts imports go through tsx's global hook (no param decorators there).\n const tmpPath = absoluteFilePath.replace(/\\.ts$/, '.__decorated__.mjs')\n writeFileSync(tmpPath, code, 'utf-8')\n try {\n const url = pathToFileURL(tmpPath).href + `?t=${Date.now()}`\n return (await import(url)) as Record<string, unknown>\n } finally {\n try {\n unlinkSync(tmpPath)\n } catch {\n // Best-effort cleanup\n }\n }\n}\n\n/**\n * Scan a glob pattern for controller files and load them all via SWC.\n * Returns an array of controller class constructors found.\n */\nexport async function loadControllersFromGlob(\n rootDir: string,\n pattern: string,\n): Promise<Function[]> {\n const files = scanControllerFiles(rootDir, pattern)\n if (files.length === 0) {\n console.warn(\n `[@theokit/http] No controller files found matching \"${pattern}\" ` +\n `in ${rootDir}. Ensure files match the pattern and export @Controller classes.`,\n )\n return []\n }\n\n const controllers: Function[] = []\n for (const file of files) {\n const absPath = resolve(rootDir, file)\n const mod = await loadControllerWithSwc(absPath)\n for (const exported of Object.values(mod)) {\n if (typeof exported === 'function' && isControllerClass(exported)) {\n controllers.push(exported)\n }\n }\n }\n\n return controllers\n}\n\n/**\n * Check if a function has @Controller metadata.\n * Uses Symbol.for() global registry key — same Symbol instance across\n * module boundaries (SWC-loaded controllers share the global registry).\n */\nexport function isControllerClass(fn: Function): boolean {\n try {\n return Reflect.hasMetadata(Symbol.for('theokit:http-decorators:controller-prefix'), fn)\n } catch {\n return false\n }\n}\n\n/**\n * Scan for files matching a controller glob pattern.\n * Extracts the static directory prefix and file suffix from the pattern,\n * then recursively walks the directory.\n */\nfunction scanControllerFiles(rootDir: string, pattern: string): string[] {\n const parts = pattern.split('/')\n const dirParts: string[] = []\n for (const part of parts) {\n if (part.includes('*')) break\n dirParts.push(part)\n }\n const baseDir = join(rootDir, ...dirParts)\n\n // Extract file suffix (e.g., '*.controller.ts' → '.controller.ts')\n const lastPart = parts[parts.length - 1]\n const suffix = lastPart.replace(/\\*/g, '')\n\n const files: string[] = []\n function walk(dir: string) {\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) walk(full)\n else if (entry.name.endsWith(suffix)) files.push(relative(rootDir, full))\n }\n } catch {\n // Directory doesn't exist\n }\n }\n walk(baseDir)\n return files\n}\n"],"mappings":"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","names":["MiddlewareConsumerImpl","entries","container","apply","middleware","resolved","map","m","resolveMiddleware","excludePatterns","proxy","exclude","routes","r","push","path","forRoutes","routePatterns","handler","getEntries","prototype","use","instance","resolveOrNew","request","next","middlewareMatchesPath","entry","requestPath","pattern","pathMatches","normPath","replace","normPattern","startsWith","runMiddleware","response","Promise","resolve","readFileSync","writeFileSync","unlinkSync","readdirSync","createRequire","resolve","dirname","join","relative","pathToFileURL","fileURLToPath","getSwcrcTarget","swcrc","jsc","target","consumerSwcrcCache","readConsumerSwcrc","startDir","undefined","dir","root","dirname","candidate","join","raw","readFileSync","parsed","JSON","parse","$schema","parent","swcCoreCache","loadSwcCore","thisDir","fileURLToPath","url","req","createRequire","resolve","resolved","pathToFileURL","href","transformControllerSource","source","filename","loadSwc","swc","HttpDecoratorsConfigError","consumerSwcrc","consumerJsc","code","transformSync","parser","syntax","decorators","transform","legacyDecorator","decoratorMetadata","module","type","sourceMaps","loadControllerWithSwc","absoluteFilePath","tmpPath","replace","writeFileSync","Date","now","unlinkSync","loadControllersFromGlob","rootDir","pattern","files","scanControllerFiles","length","console","warn","controllers","file","absPath","mod","exported","Object","values","isControllerClass","push","fn","Reflect","hasMetadata","Symbol","for","parts","split","dirParts","part","includes","baseDir","lastPart","suffix","walk","entry","readdirSync","withFileTypes","full","name","isDirectory","endsWith","relative"]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ runExceptionFilters
3
+ } from "./chunk-CMPP4ULU.js";
4
+ import "./chunk-KPC7AIVC.js";
5
+ import "./chunk-MQAJWR3K.js";
6
+ import "./chunk-7QVYU63E.js";
7
+ export {
8
+ runExceptionFilters
9
+ };
10
+ //# sourceMappingURL=exception-filter-chain-V2MFO4WV.js.map