@forinda/kickjs 5.16.0 → 5.18.0-alpha.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 (123) hide show
  1. package/dist/adapter-D_uzU-QA.d.mts +2121 -0
  2. package/dist/adapter-D_uzU-QA.d.mts.map +1 -0
  3. package/dist/{context-decorator-DDZ30BIW.d.mts → app-module-CuAS6hJC.d.mts} +184 -4
  4. package/dist/app-module-CuAS6hJC.d.mts.map +1 -0
  5. package/dist/application-BU5N6o_M.mjs +12 -0
  6. package/dist/application-BU5N6o_M.mjs.map +1 -0
  7. package/dist/{application-CAnpDQ8d.d.mts → application-pbx53JnX.d.mts} +31 -5
  8. package/dist/application-pbx53JnX.d.mts.map +1 -0
  9. package/dist/{bootstrap-CFK2aAjA.mjs → bootstrap-CFog4v_L.mjs} +3 -3
  10. package/dist/{bootstrap-CFK2aAjA.mjs.map → bootstrap-CFog4v_L.mjs.map} +1 -1
  11. package/dist/{bootstrap-8DDzBjhx.d.mts → bootstrap-DzfBj6Ja.d.mts} +2 -2
  12. package/dist/{bootstrap-8DDzBjhx.d.mts.map → bootstrap-DzfBj6Ja.d.mts.map} +1 -1
  13. package/dist/config/index.mjs +2 -2
  14. package/dist/{config-BW5taOVX.mjs → config-Di3HlRTS.mjs} +3 -3
  15. package/dist/{config-BW5taOVX.mjs.map → config-Di3HlRTS.mjs.map} +1 -1
  16. package/dist/{container-D1gfs6__.mjs → container-BiGimG12.mjs} +3 -3
  17. package/dist/{container-D1gfs6__.mjs.map → container-BiGimG12.mjs.map} +1 -1
  18. package/dist/context-leZajQAj.mjs +12 -0
  19. package/dist/context-leZajQAj.mjs.map +1 -0
  20. package/dist/core/adapter.d.mts +1 -1
  21. package/dist/core/adapter.mjs +1 -1
  22. package/dist/core/app-module.d.mts +1 -1
  23. package/dist/core/app-module.mjs +1 -1
  24. package/dist/core/cache.mjs +1 -1
  25. package/dist/core/container.mjs +2 -2
  26. package/dist/core/cron.mjs +2 -2
  27. package/dist/core/decorators.mjs +2 -2
  28. package/dist/core/errors.d.mts +1 -1
  29. package/dist/core/errors.mjs +2 -2
  30. package/dist/core/errors.mjs.map +1 -1
  31. package/dist/core/interfaces.mjs +1 -1
  32. package/dist/core/logger.mjs +1 -1
  33. package/dist/core/path.mjs +1 -1
  34. package/dist/core/plugin.d.mts +1 -1
  35. package/dist/core/plugin.mjs +1 -1
  36. package/dist/core/reactivity.mjs +1 -1
  37. package/dist/{core-Db2uyqtM.mjs → core-Y_xSqZ7v.mjs} +3 -3
  38. package/dist/{core-Db2uyqtM.mjs.map → core-Y_xSqZ7v.mjs.map} +1 -1
  39. package/dist/{env-nwsfCpdy.mjs → env-BoMBrGWs.mjs} +3 -3
  40. package/dist/{env-nwsfCpdy.mjs.map → env-BoMBrGWs.mjs.map} +1 -1
  41. package/dist/{errors-CRCTjEUK.d.mts → errors-n0H96eEz.d.mts} +3 -1
  42. package/dist/errors-n0H96eEz.d.mts.map +1 -0
  43. package/dist/http/application.d.mts +1 -1
  44. package/dist/http/application.mjs +2 -2
  45. package/dist/http/bootstrap.d.mts +1 -1
  46. package/dist/http/bootstrap.mjs +2 -2
  47. package/dist/http/context.d.mts +2 -2
  48. package/dist/http/context.mjs +2 -2
  49. package/dist/http/middleware/cors.mjs +1 -1
  50. package/dist/http/middleware/csrf.mjs +1 -1
  51. package/dist/http/middleware/error-handler.mjs +2 -2
  52. package/dist/http/middleware/helmet.mjs +1 -1
  53. package/dist/http/middleware/rate-limit.mjs +1 -1
  54. package/dist/http/middleware/request-id.mjs +1 -1
  55. package/dist/http/middleware/request-logger.mjs +2 -2
  56. package/dist/http/middleware/session.mjs +1 -1
  57. package/dist/http/middleware/spa.d.mts +1 -1
  58. package/dist/http/middleware/spa.mjs +2 -2
  59. package/dist/http/middleware/upload.d.mts +2 -2
  60. package/dist/http/middleware/upload.mjs +3 -3
  61. package/dist/http/middleware/upload.mjs.map +1 -1
  62. package/dist/http/middleware/validate.mjs +2 -2
  63. package/dist/http/middleware/views.d.mts +1 -1
  64. package/dist/http/middleware/views.mjs +2 -2
  65. package/dist/http/query/index.d.mts +2 -2
  66. package/dist/http/query/index.mjs +2 -2
  67. package/dist/http/router-builder.d.mts +2 -2
  68. package/dist/http/router-builder.mjs +2 -2
  69. package/dist/http/router-builder.mjs.map +1 -1
  70. package/dist/http/runtimes/fastify.d.mts +66 -0
  71. package/dist/http/runtimes/fastify.d.mts.map +1 -0
  72. package/dist/http/runtimes/fastify.mjs +13 -0
  73. package/dist/http/runtimes/fastify.mjs.map +1 -0
  74. package/dist/http/runtimes/h3.d.mts +29 -0
  75. package/dist/http/runtimes/h3.d.mts.map +1 -0
  76. package/dist/http/runtimes/h3.mjs +12 -0
  77. package/dist/http/runtimes/h3.mjs.map +1 -0
  78. package/dist/{index-kEmG8nWU.d.mts → index-BtWJ9SLP.d.mts} +53 -7
  79. package/dist/{index-kEmG8nWU.d.mts.map → index-BtWJ9SLP.d.mts.map} +1 -1
  80. package/dist/index.d.mts +12 -17
  81. package/dist/index.mjs +2 -2
  82. package/dist/index.mjs.map +1 -1
  83. package/dist/{metadata-Cll3P0N0.mjs → metadata-Pvgc-K8a.mjs} +2 -2
  84. package/dist/{metadata-Cll3P0N0.mjs.map → metadata-Pvgc-K8a.mjs.map} +1 -1
  85. package/dist/query-B3PhfU6M.mjs +12 -0
  86. package/dist/query-B3PhfU6M.mjs.map +1 -0
  87. package/dist/request-scope-BaM8_e_8.mjs +12 -0
  88. package/dist/request-scope-BaM8_e_8.mjs.map +1 -0
  89. package/dist/router-builder-Bh3qSiDz.d.mts +39 -0
  90. package/dist/router-builder-Bh3qSiDz.d.mts.map +1 -0
  91. package/dist/{spa-IRFC2eMN.d.mts → spa-BdvZFXJz.d.mts} +3 -2
  92. package/dist/spa-BdvZFXJz.d.mts.map +1 -0
  93. package/dist/{upload-D6edAELH.d.mts → upload-Bc_rBRtE.d.mts} +37 -2
  94. package/dist/upload-Bc_rBRtE.d.mts.map +1 -0
  95. package/dist/{views-BCl-mETX.d.mts → views-DcTVDiOh.d.mts} +31 -7
  96. package/dist/views-DcTVDiOh.d.mts.map +1 -0
  97. package/package.json +29 -1
  98. package/dist/adapter-CkpcZwzZ.d.mts +0 -407
  99. package/dist/adapter-CkpcZwzZ.d.mts.map +0 -1
  100. package/dist/app-module-BTzb-Vd6.d.mts +0 -92
  101. package/dist/app-module-BTzb-Vd6.d.mts.map +0 -1
  102. package/dist/application-CAnpDQ8d.d.mts.map +0 -1
  103. package/dist/application-DnnqoDWx.mjs +0 -12
  104. package/dist/application-DnnqoDWx.mjs.map +0 -1
  105. package/dist/context-Dnt2Di7p.d.mts +0 -434
  106. package/dist/context-Dnt2Di7p.d.mts.map +0 -1
  107. package/dist/context-MD7Mc_o_.mjs +0 -12
  108. package/dist/context-MD7Mc_o_.mjs.map +0 -1
  109. package/dist/context-decorator-DDZ30BIW.d.mts.map +0 -1
  110. package/dist/errors-CRCTjEUK.d.mts.map +0 -1
  111. package/dist/execution-context-B4cfhivz.d.mts +0 -98
  112. package/dist/execution-context-B4cfhivz.d.mts.map +0 -1
  113. package/dist/index-frSEHiL_.d.mts +0 -796
  114. package/dist/index-frSEHiL_.d.mts.map +0 -1
  115. package/dist/plugin-BQCn6zyj.d.mts +0 -260
  116. package/dist/plugin-BQCn6zyj.d.mts.map +0 -1
  117. package/dist/query-D-FiLfmd.mjs +0 -12
  118. package/dist/query-D-FiLfmd.mjs.map +0 -1
  119. package/dist/router-builder-oQpcQMWl.d.mts +0 -31
  120. package/dist/router-builder-oQpcQMWl.d.mts.map +0 -1
  121. package/dist/spa-IRFC2eMN.d.mts.map +0 -1
  122. package/dist/upload-D6edAELH.d.mts.map +0 -1
  123. package/dist/views-BCl-mETX.d.mts.map +0 -1
@@ -0,0 +1,66 @@
1
+
2
+ import { f as HttpRuntime } from "../../adapter-D_uzU-QA.mjs";
3
+ import { IncomingMessage, ServerResponse } from "node:http";
4
+
5
+ //#region src/http/runtimes/fastify.d.ts
6
+ interface FastifyReplyLike {
7
+ code(statusCode: number): FastifyReplyLike;
8
+ send(payload?: unknown): FastifyReplyLike;
9
+ header(name: string, value: unknown): FastifyReplyLike;
10
+ type(contentType: string): FastifyReplyLike;
11
+ hijack(): void;
12
+ readonly sent: boolean;
13
+ readonly raw: ServerResponse;
14
+ }
15
+ interface FastifyRequestLike {
16
+ raw: IncomingMessage;
17
+ body?: unknown;
18
+ params?: unknown;
19
+ query?: unknown;
20
+ /** Present once @fastify/multipart is registered — async iterator of parts. */
21
+ parts?: () => AsyncIterableIterator<MultipartPart>;
22
+ isMultipart?: () => boolean;
23
+ }
24
+ type FastifyHandler = (request: FastifyRequestLike, reply: FastifyReplyLike) => void | Promise<void>;
25
+ interface FastifyAppLike {
26
+ register(plugin: unknown, opts?: unknown): Promise<void> | FastifyAppLike;
27
+ use(path: unknown, mw?: unknown): unknown;
28
+ route(opts: {
29
+ method: string;
30
+ url: string;
31
+ handler: FastifyHandler;
32
+ }): unknown;
33
+ setNotFoundHandler(handler: FastifyHandler): unknown;
34
+ setErrorHandler(handler: (err: unknown, req: FastifyRequestLike, reply: FastifyReplyLike) => void): unknown;
35
+ ready(): Promise<void>;
36
+ routing(req: IncomingMessage, res: ServerResponse): void;
37
+ }
38
+ interface MultipartPart {
39
+ type: 'file' | 'field';
40
+ fieldname: string;
41
+ filename?: string;
42
+ mimetype?: string;
43
+ value?: unknown;
44
+ toBuffer?: () => Promise<Buffer>;
45
+ }
46
+ /**
47
+ * The Fastify HTTP runtime. Pass to `bootstrap({ runtime: fastifyRuntime() })`.
48
+ * Per spec §10: Fastify's built-in pino logger is disabled (`logger: false`) so
49
+ * the kickjs `requestLogger` middleware stays the single log format.
50
+ */
51
+ declare function fastifyRuntime(): HttpRuntime<FastifyAppLike>;
52
+ /**
53
+ * The Fastify runtime's engine-native types — what the runtime-typed escape
54
+ * hatches resolve to once the `kick/runtime` typegen emits a `KickRuntimeRegister`
55
+ * augmentation pointing here (spec §4.3b). `AdapterContext.app` / `getRuntimeApp()`
56
+ * become `FastifyInstance`; `ctx.req` / `ctx.res` the Fastify request / reply.
57
+ * Mirrors {@link import('../runtime').ExpressRuntimeTypes} for the default engine.
58
+ */
59
+ interface FastifyRuntimeTypes {
60
+ request: import('fastify').FastifyRequest;
61
+ response: import('fastify').FastifyReply;
62
+ app: import('fastify').FastifyInstance;
63
+ }
64
+ //#endregion
65
+ export { FastifyRuntimeTypes, fastifyRuntime };
66
+ //# sourceMappingURL=fastify.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.d.mts","names":[],"sources":["../../../src/http/runtimes/fastify.ts"],"mappings":";;;;;UA4CU,gBAAA;EACR,IAAA,CAAK,UAAA,WAAqB,gBAAA;EAC1B,IAAA,CAAK,OAAA,aAAoB,gBAAA;EACzB,MAAA,CAAO,IAAA,UAAc,KAAA,YAAiB,gBAAA;EACtC,IAAA,CAAK,WAAA,WAAsB,gBAAA;EAC3B,MAAA;EAAA,SACS,IAAA;EAAA,SACA,GAAA,EAAK,cAAA;AAAA;AAAA,UAEN,kBAAA;EACR,GAAA,EAAK,eAAA;EACL,IAAA;EACA,MAAA;EACA,KAAA;EAZ0B;EAc1B,KAAA,SAAc,qBAAA,CAAsB,aAAA;EACpC,WAAA;AAAA;AAAA,KAEG,cAAA,IAAkB,OAAA,EAAS,kBAAA,EAAoB,KAAA,EAAO,gBAAA,YAA4B,OAAA;AAAA,UAC7E,cAAA;EACR,QAAA,CAAS,MAAA,WAAiB,IAAA,aAAiB,OAAA,SAAgB,cAAA;EAC3D,GAAA,CAAI,IAAA,WAAe,EAAA;EACnB,KAAA,CAAM,IAAA;IAAQ,MAAA;IAAgB,GAAA;IAAa,OAAA,EAAS,cAAA;EAAA;EACpD,kBAAA,CAAmB,OAAA,EAAS,cAAA;EAC5B,eAAA,CACE,OAAA,GAAU,GAAA,WAAc,GAAA,EAAK,kBAAA,EAAoB,KAAA,EAAO,gBAAA;EAE1D,KAAA,IAAS,OAAA;EACT,OAAA,CAAQ,GAAA,EAAK,eAAA,EAAiB,GAAA,EAAK,cAAA;AAAA;AAAA,UAY3B,aAAA;EACR,IAAA;EACA,SAAA;EACA,QAAA;EACA,QAAA;EACA,KAAA;EACA,QAAA,SAAiB,OAAO,CAAC,MAAA;AAAA;;;;;;iBAoKX,cAAA,IAAkB,WAAW,CAAC,cAAA;;;;AAlMjC;AAAA;;;UAmUI,mBAAA;EACf,OAAA,oBAA2B,cAAA;EAC3B,QAAA,oBAA4B,YAAA;EAC5B,GAAA,oBAAuB,eAAA;AAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @forinda/kickjs v5.18.0-alpha.0
3
+ *
4
+ * Copyright (c) Felix Orinda
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import{i as requestStore,t as RequestContext}from"../../context-leZajQAj.mjs";import{t as createRequestStore}from"../../request-scope-BaM8_e_8.mjs";import{validate}from"../middleware/validate.mjs";import{applyUploadConfig}from"../middleware/upload.mjs";import{createRequire}from"node:module";const peerRequire=createRequire(import.meta.url),loadPeer=name=>{let mod=peerRequire(name);return mod&&mod.__esModule&&mod.default?mod.default:mod.default??mod},QUEUE=Symbol(`kickjs.fastify.connectQueue`),READY=Symbol(`kickjs.fastify.ready`),NEXT=Symbol(`kickjs.fastify.next`),NEEDS_MULTIPART=Symbol(`kickjs.fastify.needsMultipart`),NOOP_NEXT=()=>{};function replyDriver(reply){let driver={status(code){return reply.code(code),driver},json(data){return reply.send(data),driver},send(data){return reply.send(data),driver},type(contentType){return reply.type(contentType),driver},setHeader(name,value){return reply.header(name,value),driver},render(){throw Error(`ctx.render() is not supported on the Fastify runtime (no view engine).`)},writeHead(statusCode,headers){return reply.hijack(),reply.raw.writeHead(statusCode,headers),driver},flushHeaders(){return reply.raw.flushHeaders?.(),driver},write(chunk){return reply.raw.write(chunk)},end(data){return reply.raw.end(data),driver},once(event,listener){return reply.raw.once(event,listener),driver},get headersSent(){return reply.sent||reply.raw.headersSent}};return driver}function routeHandler(entry){return async(request,reply)=>{let raw=request.raw;if(raw.body=request.body,raw.params=request.params,raw.query=request.query,entry.meta.upload&&entry.meta.upload.mode!==`none`){if(typeof request.parts!=`function`)throw Error(`@forinda/kickjs: @FileUpload on the Fastify runtime requires '@fastify/multipart'.
12
+ Install it as a peer dependency: pnpm add @fastify/multipart.`);let rawParts=[],fields={};for await(let part of request.parts())part.type===`file`&&part.toBuffer?rawParts.push({fieldname:part.fieldname,filename:part.filename??``,mimetype:part.mimetype??`application/octet-stream`,buffer:await part.toBuffer()}):fields[part.fieldname]=part.value;let{file,files}=applyUploadConfig(rawParts,entry.meta.upload);raw.file=file,raw.files=files,raw.body={...raw.body,...fields}}let headerId=raw.headers[`x-request-id`],store=createRequestStore((Array.isArray(headerId)?headerId[0]:headerId)||raw.requestId);raw.requestId=store.requestId,await requestStore.run(store,async()=>{let ctx=new RequestContext(raw,reply,NOOP_NEXT,replyDriver(reply));if(entry.meta.validation){let v=validate(entry.meta.validation);await new Promise((resolve,reject)=>{v(raw,void 0,err=>err?reject(err):resolve())})}for(let mw of entry.middlewares){let advanced=!1;if(await new Promise((resolve,reject)=>{Promise.resolve(mw(ctx,err=>{advanced=!0,err?reject(err):resolve()})).catch(reject)}),!advanced||reply.sent)return}entry.contributorRunner&&await entry.contributorRunner(ctx),!reply.sent&&await entry.handler(ctx)})}}function fastifyRuntime(){return{name:`fastify`,createApp(options={}){let app=loadPeer(`fastify`)({logger:!1,trustProxy:typeof options.trustProxy==`function`?!1:options.trustProxy});return app[QUEUE]=[],app},nodeHandler(app){let state=app;state[READY]||(state[READY]=(async()=>{if(state[NEEDS_MULTIPART]){let multipart=loadPeer(`@fastify/multipart`);await app.register(multipart,{limits:{fileSize:2**53-1}})}let middie=loadPeer(`@fastify/middie`);await app.register(middie);for(let{mw,opts}of state[QUEUE]??[])opts?.path===void 0?app.use(mw):app.use(opts.path,mw);await app.ready()})());let readyP=state[READY];return(req,res,next)=>{next&&(req[NEXT]=next),readyP.then(()=>app.routing(req,res)).catch(err=>{next&&next(err)})}},mountRoutes(app,table){for(let{mountPath,routes}of table)for(let entry of routes){entry.meta.upload&&(app[NEEDS_MULTIPART]=!0);let url=joinPath(mountPath,entry.path);app.route({method:entry.method,url,handler:routeHandler(entry)})}},useConnect(app,mw,opts){app[QUEUE]?.push({mw,opts})},serveStatic(app,prefix,dir){let expressStatic=loadPeer(`express`).static;this.useConnect(app,expressStatic(dir),{path:prefix})},setNotFound(app,mw){app.setNotFoundHandler((request,reply)=>{let next=request.raw[NEXT];if(next){reply.hijack(),next();return}mw(request.raw,replyDriver(reply),NOOP_NEXT)})},setErrorHandler(app,mw){app.setErrorHandler((err,request,reply)=>{mw(err,request.raw,replyDriver(reply),NOOP_NEXT)})},capabilities:{render:!1,uploads:!0,connectMiddleware:!0,nativeBodyParsing:!0}}}function joinPath(mountPath,path){let a=mountPath.endsWith(`/`)?mountPath.slice(0,-1):mountPath;return path===`/`||path===``?a===``?`/`:a:`${a}${path.startsWith(`/`)?path:`/${path}`}`}export{fastifyRuntime};
13
+ //# sourceMappingURL=fastify.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.mjs","names":[],"sources":["../../../src/http/runtimes/fastify.ts"],"sourcesContent":["// The Fastify runtime — `@forinda/kickjs/fastify`.\n//\n// Implements the same HttpRuntime contract as expressRuntime, over Fastify 5.\n// KickJS still owns decorators → RouteTable, the contributor pipeline, and the\n// RequestContext surface; this runtime materializes routes as NATIVE Fastify\n// routes and wraps `reply` in a RuntimeResponse so `ctx.json` / `ctx.html` /\n// `ctx.sse` work unchanged.\n//\n// `fastify`, `@fastify/middie` are optional peers — install them alongside\n// `@forinda/kickjs` to use this subpath.\n//\n// Lifecycle note: Fastify registration (`register` / `use` / `route`) is\n// deferred until `ready()`. Connect middleware needs `@fastify/middie`\n// registered first, so `useConnect` only QUEUES middleware; `nodeHandler`\n// registers middie, then the queued middleware, then awaits `ready()`.\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { createRequire } from 'node:module'\n\nimport { RequestContext } from '../context'\nimport { requestStore } from '../request-store'\nimport { createRequestStore } from '../middleware/request-scope'\nimport { validate } from '../middleware/validate'\nimport { applyUploadConfig, type RawUploadPart } from '../middleware/upload'\nimport type {\n ConnectMiddleware,\n HttpRuntime,\n RouteEntry,\n RouteTable,\n RuntimeAppOptions,\n RuntimeResponse,\n UseConnectOptions,\n} from '../runtime'\n\n// ESM-safe require for the optional peers (fastify / @fastify/middie / express),\n// resolved from wherever this module is installed.\nconst peerRequire = createRequire(import.meta.url)\nconst loadPeer = (name: string): any => {\n const mod = peerRequire(name)\n return mod && mod.__esModule && mod.default ? mod.default : (mod.default ?? mod)\n}\n\n// Minimal structural surface we use from Fastify — avoids a hard type dep so\n// the root package never needs `fastify` installed to typecheck.\ninterface FastifyReplyLike {\n code(statusCode: number): FastifyReplyLike\n send(payload?: unknown): FastifyReplyLike\n header(name: string, value: unknown): FastifyReplyLike\n type(contentType: string): FastifyReplyLike\n hijack(): void\n readonly sent: boolean\n readonly raw: ServerResponse\n}\ninterface FastifyRequestLike {\n raw: IncomingMessage\n body?: unknown\n params?: unknown\n query?: unknown\n /** Present once @fastify/multipart is registered — async iterator of parts. */\n parts?: () => AsyncIterableIterator<MultipartPart>\n isMultipart?: () => boolean\n}\ntype FastifyHandler = (request: FastifyRequestLike, reply: FastifyReplyLike) => void | Promise<void>\ninterface FastifyAppLike {\n register(plugin: unknown, opts?: unknown): Promise<void> | FastifyAppLike\n use(path: unknown, mw?: unknown): unknown\n route(opts: { method: string; url: string; handler: FastifyHandler }): unknown\n setNotFoundHandler(handler: FastifyHandler): unknown\n setErrorHandler(\n handler: (err: unknown, req: FastifyRequestLike, reply: FastifyReplyLike) => void,\n ): unknown\n ready(): Promise<void>\n routing(req: IncomingMessage, res: ServerResponse): void\n}\n\nconst QUEUE = Symbol('kickjs.fastify.connectQueue')\nconst READY = Symbol('kickjs.fastify.ready')\nconst NEXT = Symbol('kickjs.fastify.next')\n// Set during mountRoutes when any route carries @FileUpload metadata, so\n// nodeHandler knows to register @fastify/multipart before ready().\nconst NEEDS_MULTIPART = Symbol('kickjs.fastify.needsMultipart')\nconst NOOP_NEXT = (): void => {}\n\n// A @fastify/multipart part as we consume it from `request.parts()`.\ninterface MultipartPart {\n type: 'file' | 'field'\n fieldname: string\n filename?: string\n mimetype?: string\n value?: unknown\n toBuffer?: () => Promise<Buffer>\n}\n\n/** Wrap a Fastify reply so the RequestContext response helpers drive it. */\nfunction replyDriver(reply: FastifyReplyLike): RuntimeResponse {\n const driver: RuntimeResponse = {\n status(code) {\n reply.code(code)\n return driver\n },\n json(data) {\n reply.send(data)\n return driver\n },\n send(data) {\n reply.send(data)\n return driver\n },\n type(contentType) {\n reply.type(contentType)\n return driver\n },\n setHeader(name, value) {\n reply.header(name, value)\n return driver\n },\n render() {\n throw new Error('ctx.render() is not supported on the Fastify runtime (no view engine).')\n },\n writeHead(statusCode, headers) {\n // Streaming / SSE: take over the raw socket so Fastify doesn't try to\n // serialize a reply we're writing by hand.\n reply.hijack()\n reply.raw.writeHead(statusCode, headers)\n return driver\n },\n flushHeaders() {\n ;(reply.raw as ServerResponse & { flushHeaders?: () => void }).flushHeaders?.()\n return driver\n },\n write(chunk) {\n return reply.raw.write(chunk)\n },\n end(data) {\n reply.raw.end(data)\n return driver\n },\n once(event, listener) {\n reply.raw.once(event, listener)\n return driver\n },\n get headersSent() {\n return reply.sent || reply.raw.headersSent\n },\n }\n return driver\n}\n\n/** Build the Fastify per-route handler that runs the kickjs pipeline. */\nfunction routeHandler(entry: RouteEntry): FastifyHandler {\n return async (request, reply) => {\n // Fastify runs the route handler OUTSIDE the connect-middleware chain, so\n // (unlike Express) the requestScopeMiddleware ALS frame isn't active here.\n // Establish it around the pipeline so REQUEST-scoped DI, contributors, and\n // ctx.set/get work. Reuse the inbound x-request-id, or the id a connect\n // middleware (requestId / requestScope, run earlier via middie) already\n // stamped on the raw request, before generating a fresh one.\n // Use the raw node request as `ctx.req`: it natively provides the stream\n // events (`on('close')` / `once`) that SSE and `ctx.signal` need — Fastify's\n // request object doesn't. Copy Fastify's parsed body/params/query onto it so\n // `ctx.body` / `ctx.params` / `ctx.query` keep working.\n const raw = request.raw as IncomingMessage & {\n requestId?: string\n body?: unknown\n params?: unknown\n query?: unknown\n file?: unknown\n files?: unknown\n }\n raw.body = request.body\n raw.params = request.params\n raw.query = request.query\n\n // @FileUpload: buffer multipart parts into the multer-shaped file(s) that\n // `ctx.file` / `ctx.files` expose. Fastify doesn't parse multipart natively\n // — @fastify/multipart (registered in nodeHandler when any route needs it)\n // provides `request.parts()`. Non-file fields are merged onto `raw.body` so\n // validation / `ctx.body` see them, matching multer's req.body behavior.\n if (entry.meta.upload && entry.meta.upload.mode !== 'none') {\n if (typeof request.parts !== 'function') {\n throw new Error(\n \"@forinda/kickjs: @FileUpload on the Fastify runtime requires '@fastify/multipart'.\\n\" +\n 'Install it as a peer dependency: pnpm add @fastify/multipart.',\n )\n }\n const rawParts: RawUploadPart[] = []\n const fields: Record<string, unknown> = {}\n for await (const part of request.parts()) {\n if (part.type === 'file' && part.toBuffer) {\n rawParts.push({\n fieldname: part.fieldname,\n filename: part.filename ?? '',\n mimetype: part.mimetype ?? 'application/octet-stream',\n buffer: await part.toBuffer(),\n })\n } else {\n fields[part.fieldname] = part.value\n }\n }\n const { file, files } = applyUploadConfig(rawParts, entry.meta.upload)\n raw.file = file\n raw.files = files\n raw.body = { ...(raw.body as Record<string, unknown> | undefined), ...fields }\n }\n\n const headerId = raw.headers['x-request-id']\n const requestId = (Array.isArray(headerId) ? headerId[0] : headerId) || raw.requestId\n const store = createRequestStore(requestId)\n // Propagate the resolved id back onto the raw request so anything reading\n // `req.requestId` inside the frame (e.g. request-logger) matches the store\n // and the X-Request-Id response header — parity with Express.\n raw.requestId = store.requestId\n\n await requestStore.run(store, async () => {\n const ctx = new RequestContext(raw as never, reply as never, NOOP_NEXT, replyDriver(reply))\n\n // Validation (from @Get(path, schema) / route.validation). `validate` is a\n // connect-style middleware that mutates req.body/query/params to the parsed\n // value and calls next(err) on failure — it never touches `res`, so it runs\n // cleanly here. A rejection propagates to the error handler (422).\n if (entry.meta.validation) {\n const v = validate(entry.meta.validation)\n await new Promise<void>((resolve, reject) => {\n v(raw as never, undefined as never, (err?: unknown) => (err ? reject(err) : resolve()))\n })\n }\n\n // Class + method middleware — `(ctx, next)`; await each, stop if it ended\n // the response or called next(err).\n for (const mw of entry.middlewares) {\n let advanced = false\n await new Promise<void>((resolve, reject) => {\n const next = (err?: unknown): void => {\n advanced = true\n if (err) reject(err)\n else resolve()\n }\n Promise.resolve(mw(ctx, next)).catch(reject)\n })\n if (!advanced || reply.sent) return\n }\n\n if (entry.contributorRunner) await entry.contributorRunner(ctx)\n if (reply.sent) return\n await entry.handler(ctx)\n })\n }\n}\n\n/**\n * The Fastify HTTP runtime. Pass to `bootstrap({ runtime: fastifyRuntime() })`.\n * Per spec §10: Fastify's built-in pino logger is disabled (`logger: false`) so\n * the kickjs `requestLogger` middleware stays the single log format.\n */\nexport function fastifyRuntime(): HttpRuntime<FastifyAppLike> {\n return {\n name: 'fastify',\n\n createApp(options: RuntimeAppOptions = {}): FastifyAppLike {\n const Fastify = loadPeer('fastify')\n const app = Fastify({\n logger: false,\n // trustProxy passed through for now; core X-Forwarded-For\n // normalization (spec §10 Q1) is a follow-up.\n trustProxy: typeof options.trustProxy === 'function' ? false : options.trustProxy,\n }) as FastifyAppLike & {\n [QUEUE]?: Array<{ mw: ConnectMiddleware; opts?: UseConnectOptions }>\n }\n app[QUEUE] = []\n return app\n },\n\n nodeHandler(app) {\n // Register middie + queued connect middleware + finalize `ready()` exactly\n // ONCE per app, even though Application may call nodeHandler per request.\n const state = app as {\n [QUEUE]?: Array<{ mw: ConnectMiddleware; opts?: UseConnectOptions }>\n [READY]?: Promise<void>\n [NEEDS_MULTIPART]?: boolean\n }\n if (!state[READY]) {\n state[READY] = (async () => {\n // Register @fastify/multipart first when any route uses @FileUpload so\n // `request.parts()` is available. Our applyUploadConfig enforces the\n // real per-file maxSize, so give the plugin a generous fileSize ceiling\n // (its 1MB default would silently truncate larger uploads first).\n if (state[NEEDS_MULTIPART]) {\n const multipart = loadPeer('@fastify/multipart')\n await app.register(multipart, { limits: { fileSize: Number.MAX_SAFE_INTEGER } })\n }\n const middie = loadPeer('@fastify/middie')\n await app.register(middie)\n for (const { mw, opts } of state[QUEUE] ?? []) {\n if (opts?.path !== undefined)\n (app.use as (p: unknown, m: unknown) => void)(opts.path, mw)\n else (app.use as (m: unknown) => void)(mw)\n }\n await app.ready()\n })()\n }\n const readyP = state[READY]\n\n return (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => {\n if (next) (req as IncomingMessage & { [NEXT]?: (err?: unknown) => void })[NEXT] = next\n readyP\n .then(() => app.routing(req, res))\n .catch((err) => {\n if (next) next(err)\n })\n }\n },\n\n mountRoutes(app, table: RouteTable) {\n for (const { mountPath, routes } of table) {\n for (const entry of routes) {\n if (entry.meta.upload) (app as { [NEEDS_MULTIPART]?: boolean })[NEEDS_MULTIPART] = true\n const url = joinPath(mountPath, entry.path)\n app.route({ method: entry.method, url, handler: routeHandler(entry) })\n }\n }\n },\n\n useConnect(app, mw: ConnectMiddleware, opts?: UseConnectOptions) {\n const queue = (\n app as { [QUEUE]?: Array<{ mw: ConnectMiddleware; opts?: UseConnectOptions }> }\n )[QUEUE]\n queue?.push({ mw, opts })\n },\n\n serveStatic(app, prefix, dir) {\n // Serve via express.static as a connect middleware, queued like any other.\n const expressStatic = loadPeer('express').static\n this.useConnect(app, expressStatic(dir) as ConnectMiddleware, { path: prefix })\n },\n\n setNotFound(app, mw: ConnectMiddleware) {\n app.setNotFoundHandler((request, reply) => {\n const next = (request.raw as IncomingMessage & { [NEXT]?: (err?: unknown) => void })[NEXT]\n if (next) {\n // Vite dev fall-through: hand the request back to the outer chain.\n reply.hijack()\n next()\n return\n }\n // Pass the reply DRIVER (not raw res) so the connect-style\n // notFoundHandler's `res.status().json()` lands on the Fastify reply.\n ;(mw as (req: unknown, res: unknown, next: () => void) => void)(\n request.raw,\n replyDriver(reply),\n NOOP_NEXT,\n )\n })\n },\n\n setErrorHandler(app, mw: ConnectMiddleware) {\n app.setErrorHandler((err, request, reply) => {\n // Reply driver (not raw res) so the connect-style errorHandler's\n // `res.status().json()` / `setHeader` land on the Fastify reply.\n ;(mw as (e: unknown, req: unknown, res: unknown, next: () => void) => void)(\n err,\n request.raw,\n replyDriver(reply),\n NOOP_NEXT,\n )\n })\n },\n\n capabilities: {\n render: false,\n uploads: true,\n connectMiddleware: true,\n nativeBodyParsing: true,\n },\n }\n}\n\n/**\n * The Fastify runtime's engine-native types — what the runtime-typed escape\n * hatches resolve to once the `kick/runtime` typegen emits a `KickRuntimeRegister`\n * augmentation pointing here (spec §4.3b). `AdapterContext.app` / `getRuntimeApp()`\n * become `FastifyInstance`; `ctx.req` / `ctx.res` the Fastify request / reply.\n * Mirrors {@link import('../runtime').ExpressRuntimeTypes} for the default engine.\n */\nexport interface FastifyRuntimeTypes {\n request: import('fastify').FastifyRequest\n response: import('fastify').FastifyReply\n app: import('fastify').FastifyInstance\n}\n\n/** Join a mount prefix and a route path into one URL, collapsing slashes. */\nfunction joinPath(mountPath: string, path: string): string {\n const a = mountPath.endsWith('/') ? mountPath.slice(0, -1) : mountPath\n // A root route path ('/' or '') maps to the mount prefix itself — otherwise a\n // controller `@Post('/')` would register at `${prefix}/`, and a request to\n // `${prefix}` (no trailing slash) wouldn't match under Fastify's strict router.\n if (path === '/' || path === '') return a === '' ? '/' : a\n const b = path.startsWith('/') ? path : `/${path}`\n return `${a}${b}`\n}\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+
2
+ import { f as HttpRuntime } from "../../adapter-D_uzU-QA.mjs";
3
+
4
+ //#region src/http/runtimes/h3.d.ts
5
+ interface H3AppLike {
6
+ use(arg1: unknown, arg2?: unknown): unknown;
7
+ handler: unknown;
8
+ }
9
+ /**
10
+ * The h3 HTTP runtime. Pass to `bootstrap({ runtime: h3Runtime() })`.
11
+ * h3 parses bodies itself (`readBody`), so the Application skips its default
12
+ * `express.json()` (see `nativeBodyParsing`).
13
+ */
14
+ declare function h3Runtime(): HttpRuntime<H3AppLike>;
15
+ /**
16
+ * The h3 runtime's engine-native types — what the runtime-typed escape hatches
17
+ * resolve to once the `kick/runtime` typegen emits a `KickRuntimeRegister`
18
+ * augmentation pointing here (spec §4.3b). `AdapterContext.app` / `getRuntimeApp()`
19
+ * become the h3 `App`; `ctx.req` / `ctx.res` the per-request `H3Event` (h3 v1
20
+ * routes everything through the event). Mirrors `ExpressRuntimeTypes`.
21
+ */
22
+ interface H3RuntimeTypes {
23
+ request: import('h3').H3Event;
24
+ response: import('h3').H3Event;
25
+ app: import('h3').App;
26
+ }
27
+ //#endregion
28
+ export { H3RuntimeTypes, h3Runtime };
29
+ //# sourceMappingURL=h3.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h3.d.mts","names":[],"sources":["../../../src/http/runtimes/h3.ts"],"mappings":";;;;UA2CU,SAAA;EACR,GAAA,CAAI,IAAA,WAAe,IAAA;EACnB,OAAA;AAAA;;;;;;iBAoJc,SAAA,IAAa,WAAW,CAAC,SAAA;;AApJhC;AAoJT;;;;AAAkD;UAiGjC,cAAA;EACf,OAAA,eAAsB,OAAA;EACtB,QAAA,eAAuB,OAAA;EACvB,GAAA,eAAkB,GAAA;AAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @forinda/kickjs v5.18.0-alpha.0
3
+ *
4
+ * Copyright (c) Felix Orinda
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import{i as requestStore,t as RequestContext}from"../../context-leZajQAj.mjs";import{t as createRequestStore}from"../../request-scope-BaM8_e_8.mjs";import{validate}from"../middleware/validate.mjs";import{applyUploadConfig}from"../middleware/upload.mjs";import{createRequire}from"node:module";const peerRequire=createRequire(import.meta.url),h3=()=>peerRequire(`h3`),NEXT=Symbol(`kickjs.h3.next`),ERROR_MW=Symbol(`kickjs.h3.errorMw`),NOOP_NEXT=()=>{},BODY_METHODS=new Set([`POST`,`PUT`,`PATCH`,`DELETE`]);function resDriver(res){let driver={status(code){return res.statusCode=code,driver},json(data){return res.headersSent||res.setHeader(`content-type`,`application/json; charset=utf-8`),res.end(JSON.stringify(data)),driver},send(data){return res.end(data),driver},type(contentType){return res.setHeader(`content-type`,contentType),driver},setHeader(name,value){return res.setHeader(name,value),driver},render(){throw Error(`ctx.render() is not supported on the h3 runtime (no view engine).`)},writeHead(statusCode,headers){return res.writeHead(statusCode,headers),driver},flushHeaders(){return res.flushHeaders(),driver},write(chunk){return res.write(chunk)},end(data){return res.end(data),driver},once(event,listener){return res.once(event,listener),driver},get headersSent(){return res.headersSent}};return driver}function makeEventHandler(entry){let{getRouterParams,getQuery,readBody,readMultipartFormData}=h3(),upload=entry.meta.upload;return async event=>{let req=event.node.req,res=event.node.res;if(req.params=getRouterParams(event)??{},req.query=getQuery(event)??{},upload&&upload.mode!==`none`){let form=await readMultipartFormData(event).catch(()=>void 0),rawParts=[],fields={};for(let part of form??[])part.filename?rawParts.push({fieldname:part.name??``,filename:part.filename,mimetype:part.type??`application/octet-stream`,buffer:part.data}):part.name&&(fields[part.name]=part.data.toString(`utf-8`));let{file,files}=applyUploadConfig(rawParts,upload);req.file=file,req.files=files,req.body=fields}else BODY_METHODS.has(req.method??`GET`)&&(req.body=await readBody(event).catch(()=>void 0));let headerId=req.headers[`x-request-id`],store=createRequestStore((Array.isArray(headerId)?headerId[0]:headerId)||req.requestId);req.requestId=store.requestId,await requestStore.run(store,async()=>{let ctx=new RequestContext(req,res,NOOP_NEXT,resDriver(res));if(entry.meta.validation){let v=validate(entry.meta.validation);await new Promise((resolve,reject)=>{v(req,void 0,err=>err?reject(err):resolve())})}for(let mw of entry.middlewares){let advanced=!1;if(await new Promise((resolve,reject)=>{Promise.resolve(mw(ctx,err=>{advanced=!0,err?reject(err):resolve()})).catch(reject)}),!advanced||res.writableEnded)return}entry.contributorRunner&&await entry.contributorRunner(ctx),!res.writableEnded&&await entry.handler(ctx)})}}function h3Runtime(){return{name:`h3`,createApp(_options={}){let{createApp}=h3(),app=createApp({onError:(error,event)=>{let mw=app[ERROR_MW];mw&&!event.node.res.writableEnded&&mw(error,event.node.req,resDriver(event.node.res),NOOP_NEXT)}});return app},nodeHandler(app){let{toNodeListener}=h3(),listener=toNodeListener(app);return(req,res,next)=>{next&&(req[NEXT]=next),Promise.resolve(listener(req,res)).catch(err=>{next&&next(err)})}},mountRoutes(app,table){let{createRouter,eventHandler}=h3(),router=createRouter();for(let{mountPath,routes}of table)for(let entry of routes){let url=joinPath(mountPath,entry.path);router[entry.method.toLowerCase()](url,eventHandler(makeEventHandler(entry)))}app.use(router)},useConnect(app,mw,opts){let{fromNodeMiddleware}=h3(),handler=fromNodeMiddleware(mw);opts?.path===void 0?app.use(handler):app.use(opts.path,handler)},serveStatic(app,prefix,dir){let expressStatic=peerRequire(`express`).static;this.useConnect(app,expressStatic(dir),{path:prefix})},setNotFound(app,mw){let{eventHandler}=h3();app.use(eventHandler(event=>{let next=event.node.req[NEXT];if(next){next();return}mw(event.node.req,resDriver(event.node.res),NOOP_NEXT)}))},setErrorHandler(app,mw){app[ERROR_MW]=mw},capabilities:{render:!1,uploads:!0,connectMiddleware:!0,nativeBodyParsing:!0}}}function joinPath(mountPath,path){let a=mountPath.endsWith(`/`)?mountPath.slice(0,-1):mountPath;return path===`/`||path===``?a===``?`/`:a:`${a}${path.startsWith(`/`)?path:`/${path}`}`}export{h3Runtime};
12
+ //# sourceMappingURL=h3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h3.mjs","names":[],"sources":["../../../src/http/runtimes/h3.ts"],"sourcesContent":["// The h3 runtime — `@forinda/kickjs/h3`.\n//\n// h3 (unjs) is the HTTP layer behind Nitro / Nuxt. This binds it to the same\n// HttpRuntime contract as Express and Fastify: routes become native h3 router\n// routes, and the node `ServerResponse` (h3 exposes it as `event.node.res`) is\n// wrapped in a RuntimeResponse so `ctx.json` / `ctx.html` / `ctx.sse` work\n// unchanged.\n//\n// Targets h3 **v1** (stable, node-based: `createApp` / `createRouter` /\n// `toNodeListener`, with `event.node.req` / `event.node.res`). `h3` is an\n// optional peer pinned to `^1`.\n//\n// h3 v2 (https://h3.dev/migration) moves to a web-standard `Request`/`Response`\n// core. Adopting it is the spec's §8 \"web-standard driver\" — `RuntimeResponse`\n// was shaped so a future `webRuntime()` can implement it over WHATWG streams,\n// at which point h3 v2 (and edge/Bun/Deno) become a driver swap rather than a\n// rewrite. Until that lands, this binding uses the node-compatible v1 surface.\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { createRequire } from 'node:module'\n\nimport { RequestContext } from '../context'\nimport { requestStore } from '../request-store'\nimport { createRequestStore } from '../middleware/request-scope'\nimport { validate } from '../middleware/validate'\nimport { applyUploadConfig, type RawUploadPart } from '../middleware/upload'\nimport type {\n ConnectMiddleware,\n HttpRuntime,\n RouteEntry,\n RouteTable,\n RuntimeAppOptions,\n RuntimeResponse,\n UseConnectOptions,\n} from '../runtime'\n\nconst peerRequire = createRequire(import.meta.url)\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst h3 = (): any => peerRequire('h3')\n\ninterface H3EventLike {\n node: { req: IncomingMessage; res: ServerResponse }\n}\ninterface H3AppLike {\n use(arg1: unknown, arg2?: unknown): unknown\n handler: unknown\n}\n\nconst NEXT = Symbol('kickjs.h3.next')\nconst ERROR_MW = Symbol('kickjs.h3.errorMw')\nconst NOOP_NEXT = (): void => {}\nconst BODY_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE'])\n\n/** Wrap a node ServerResponse (from `event.node.res`) as a RuntimeResponse. */\nfunction resDriver(res: ServerResponse): RuntimeResponse {\n const driver: RuntimeResponse = {\n status(code) {\n res.statusCode = code\n return driver\n },\n json(data) {\n if (!res.headersSent) res.setHeader('content-type', 'application/json; charset=utf-8')\n res.end(JSON.stringify(data))\n return driver\n },\n send(data) {\n res.end(data as never)\n return driver\n },\n type(contentType) {\n res.setHeader('content-type', contentType)\n return driver\n },\n setHeader(name, value) {\n res.setHeader(name, value as never)\n return driver\n },\n render() {\n throw new Error('ctx.render() is not supported on the h3 runtime (no view engine).')\n },\n writeHead(statusCode, headers) {\n res.writeHead(statusCode, headers)\n return driver\n },\n flushHeaders() {\n res.flushHeaders()\n return driver\n },\n write(chunk) {\n return res.write(chunk)\n },\n end(data) {\n res.end(data as never)\n return driver\n },\n once(event, listener) {\n res.once(event, listener)\n return driver\n },\n get headersSent() {\n return res.headersSent\n },\n }\n return driver\n}\n\n/** Build the h3 event handler that runs the kickjs pipeline for one route. */\nfunction makeEventHandler(entry: RouteEntry): (event: H3EventLike) => Promise<void> {\n const { getRouterParams, getQuery, readBody, readMultipartFormData } = h3()\n const upload = entry.meta.upload\n return async (event: H3EventLike) => {\n const req = event.node.req as IncomingMessage & {\n requestId?: string\n body?: unknown\n params?: unknown\n query?: unknown\n file?: unknown\n files?: unknown\n }\n const res = event.node.res\n\n // Populate the express-shaped request fields h3 keeps elsewhere.\n req.params = getRouterParams(event) ?? {}\n req.query = getQuery(event) ?? {}\n if (upload && upload.mode !== 'none') {\n // @FileUpload: read the multipart body once (readBody would consume the\n // same stream, so the two are mutually exclusive). File parts → the\n // multer-shaped ctx.file/ctx.files; non-file fields → req.body.\n const form = (await readMultipartFormData(event).catch(() => undefined)) as\n | Array<{ name?: string; filename?: string; type?: string; data: Buffer }>\n | undefined\n const rawParts: RawUploadPart[] = []\n const fields: Record<string, unknown> = {}\n for (const part of form ?? []) {\n if (part.filename) {\n rawParts.push({\n fieldname: part.name ?? '',\n filename: part.filename,\n mimetype: part.type ?? 'application/octet-stream',\n buffer: part.data,\n })\n } else if (part.name) {\n fields[part.name] = part.data.toString('utf-8')\n }\n }\n const { file, files } = applyUploadConfig(rawParts, upload)\n req.file = file\n req.files = files\n req.body = fields\n } else if (BODY_METHODS.has(req.method ?? 'GET')) {\n req.body = await readBody(event).catch(() => undefined)\n }\n\n const headerId = req.headers['x-request-id']\n const requestId = (Array.isArray(headerId) ? headerId[0] : headerId) || req.requestId\n const store = createRequestStore(requestId)\n req.requestId = store.requestId\n\n await requestStore.run(store, async () => {\n const ctx = new RequestContext(req as never, res as never, NOOP_NEXT, resDriver(res))\n\n if (entry.meta.validation) {\n const v = validate(entry.meta.validation)\n await new Promise<void>((resolve, reject) => {\n v(req as never, undefined as never, (err?: unknown) => (err ? reject(err) : resolve()))\n })\n }\n\n for (const mw of entry.middlewares) {\n let advanced = false\n await new Promise<void>((resolve, reject) => {\n const next = (err?: unknown): void => {\n advanced = true\n if (err) reject(err)\n else resolve()\n }\n Promise.resolve(mw(ctx, next)).catch(reject)\n })\n if (!advanced || res.writableEnded) return\n }\n\n if (entry.contributorRunner) await entry.contributorRunner(ctx)\n if (res.writableEnded) return\n await entry.handler(ctx)\n })\n }\n}\n\n/**\n * The h3 HTTP runtime. Pass to `bootstrap({ runtime: h3Runtime() })`.\n * h3 parses bodies itself (`readBody`), so the Application skips its default\n * `express.json()` (see `nativeBodyParsing`).\n */\nexport function h3Runtime(): HttpRuntime<H3AppLike> {\n return {\n name: 'h3',\n\n createApp(_options: RuntimeAppOptions = {}): H3AppLike {\n const { createApp } = h3()\n const app = createApp({\n onError: (error: unknown, event: H3EventLike) => {\n const mw = (app as { [ERROR_MW]?: ConnectMiddleware })[ERROR_MW]\n if (mw && !event.node.res.writableEnded) {\n ;(mw as (e: unknown, req: unknown, res: unknown, next: () => void) => void)(\n error,\n event.node.req,\n resDriver(event.node.res),\n NOOP_NEXT,\n )\n }\n },\n })\n return app as H3AppLike\n },\n\n nodeHandler(app) {\n const { toNodeListener } = h3()\n const listener = toNodeListener(app)\n return (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => {\n if (next) (req as IncomingMessage & { [NEXT]?: (err?: unknown) => void })[NEXT] = next\n Promise.resolve(listener(req, res)).catch((err) => {\n if (next) next(err)\n })\n }\n },\n\n mountRoutes(app, table: RouteTable) {\n const { createRouter, eventHandler } = h3()\n const router = createRouter()\n for (const { mountPath, routes } of table) {\n for (const entry of routes) {\n const url = joinPath(mountPath, entry.path)\n const method = entry.method.toLowerCase() as 'get' | 'post' | 'put' | 'delete' | 'patch'\n router[method](url, eventHandler(makeEventHandler(entry)))\n }\n }\n app.use(router)\n },\n\n useConnect(app, mw: ConnectMiddleware, opts?: UseConnectOptions) {\n const { fromNodeMiddleware } = h3()\n const handler = fromNodeMiddleware(mw)\n if (opts?.path !== undefined) app.use(opts.path, handler)\n else app.use(handler)\n },\n\n serveStatic(app, prefix, dir) {\n const expressStatic = peerRequire('express').static\n this.useConnect(app, expressStatic(dir) as ConnectMiddleware, { path: prefix })\n },\n\n setNotFound(app, mw: ConnectMiddleware) {\n const { eventHandler } = h3()\n // Registered after the router, so it only runs when nothing matched.\n app.use(\n eventHandler((event: H3EventLike) => {\n const next = (event.node.req as IncomingMessage & { [NEXT]?: () => void })[NEXT]\n if (next) {\n next()\n return\n }\n ;(mw as (req: unknown, res: unknown, next: () => void) => void)(\n event.node.req,\n resDriver(event.node.res),\n NOOP_NEXT,\n )\n }),\n )\n },\n\n setErrorHandler(app, mw: ConnectMiddleware) {\n ;(app as { [ERROR_MW]?: ConnectMiddleware })[ERROR_MW] = mw\n },\n\n capabilities: {\n render: false,\n uploads: true,\n connectMiddleware: true,\n nativeBodyParsing: true,\n },\n }\n}\n\n/**\n * The h3 runtime's engine-native types — what the runtime-typed escape hatches\n * resolve to once the `kick/runtime` typegen emits a `KickRuntimeRegister`\n * augmentation pointing here (spec §4.3b). `AdapterContext.app` / `getRuntimeApp()`\n * become the h3 `App`; `ctx.req` / `ctx.res` the per-request `H3Event` (h3 v1\n * routes everything through the event). Mirrors `ExpressRuntimeTypes`.\n */\nexport interface H3RuntimeTypes {\n request: import('h3').H3Event\n response: import('h3').H3Event\n app: import('h3').App\n}\n\n/** Join a mount prefix and a route path; a root path maps to the prefix itself. */\nfunction joinPath(mountPath: string, path: string): string {\n const a = mountPath.endsWith('/') ? mountPath.slice(0, -1) : mountPath\n if (path === '/' || path === '') return a === '' ? '/' : a\n const b = path.startsWith('/') ? path : `/${path}`\n return `${a}${b}`\n}\n"],"mappings":"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"}
@@ -137,17 +137,62 @@ interface QueryBuilderAdapter<TResult = any, TConfig = any> {
137
137
  }
138
138
  //#endregion
139
139
  //#region src/http/query/parse-query.d.ts
140
+ /**
141
+ * Why a rejected field/value was dropped. Surfaced through
142
+ * {@link ParseQueryOptions.onReject} so a caller can warn, count, or
143
+ * return a 400 instead of the historical silent drop.
144
+ */
145
+ type QueryRejectReason = 'field-not-allowed' | 'unknown-operator' | 'truncated';
146
+ interface QueryRejection {
147
+ kind: 'filter' | 'sort' | 'search';
148
+ field: string;
149
+ reason: QueryRejectReason;
150
+ }
151
+ interface ParseQueryOptions {
152
+ /** Hard cap on `limit`. Default: global (100, override via {@link setQueryParsingDefaults}). */
153
+ maxLimit?: number;
154
+ /** `limit` when the query omits one. Default: global (20). */
155
+ defaultLimit?: number;
156
+ /** Max `q` length before truncation. Default: global (200). */
157
+ maxSearchLength?: number;
158
+ /**
159
+ * Called once per dropped filter/sort field or truncated search.
160
+ * The historical behaviour is a silent drop; wire this to a logger or
161
+ * a 400 to make over-broad / typo'd queries visible.
162
+ */
163
+ onReject?: (rejection: QueryRejection) => void;
164
+ }
165
+ interface QueryParsingDefaults {
166
+ maxLimit: number;
167
+ defaultLimit: number;
168
+ maxSearchLength: number;
169
+ defaultPage: number;
170
+ }
171
+ /**
172
+ * Globally override the query-parsing limits — call once at bootstrap.
173
+ * Per-call {@link ParseQueryOptions} still take precedence over these.
174
+ */
175
+ declare function setQueryParsingDefaults(partial: Partial<Omit<QueryParsingDefaults, 'defaultPage'>>): void;
176
+ /** Read the current global query-parsing defaults (a copy). */
177
+ declare function getQueryParsingDefaults(): Readonly<QueryParsingDefaults>;
178
+ /**
179
+ * Restore the built-in query-parsing defaults (maxLimit 100, defaultLimit
180
+ * 20, maxSearchLength 200). Useful in test teardown after a
181
+ * {@link setQueryParsingDefaults} override so global state can't leak
182
+ * between tests.
183
+ */
184
+ declare function resetQueryParsingDefaults(): void;
140
185
  /** Parse filter strings like "status:eq:active" into structured objects */
141
- declare function parseFilters(filterParam: string | string[] | undefined, allowedFields?: string[]): FilterItem[];
186
+ declare function parseFilters(filterParam: string | string[] | undefined, allowedFields?: string[], options?: Pick<ParseQueryOptions, 'onReject'>): FilterItem[];
142
187
  /** Parse sort strings like "firstName:asc" into structured objects */
143
- declare function parseSort(sortParam: string | string[] | undefined, allowedFields?: string[]): SortItem[];
188
+ declare function parseSort(sortParam: string | string[] | undefined, allowedFields?: string[], options?: Pick<ParseQueryOptions, 'onReject'>): SortItem[];
144
189
  /** Parse page/limit into pagination with computed offset */
145
190
  declare function parsePagination(params: {
146
191
  page?: string | number;
147
192
  limit?: string | number;
148
- }): PaginationParams;
193
+ }, options?: Pick<ParseQueryOptions, 'maxLimit' | 'defaultLimit'>): PaginationParams;
149
194
  /** Sanitize and truncate search query */
150
- declare function parseSearchQuery(q: string | undefined): string;
195
+ declare function parseSearchQuery(q: string | undefined, options?: Pick<ParseQueryOptions, 'maxSearchLength' | 'onReject'>): string;
151
196
  /**
152
197
  * Parse a raw Express query object into a structured, ORM-agnostic ParsedQuery.
153
198
  *
@@ -155,6 +200,7 @@ declare function parseSearchQuery(q: string | undefined): string;
155
200
  * @param fieldConfig - Optional field restrictions (whitelist filterable/sortable/searchable).
156
201
  * Accepts both string-based configs (`{ filterable, sortable, searchable }`) and
157
202
  * column-object configs (`{ columns, sortable, searchColumns }`).
203
+ * @param options - Limits + an `onReject` hook for dropped/truncated input.
158
204
  *
159
205
  * @example
160
206
  * ```ts
@@ -176,9 +222,9 @@ declare function parseSearchQuery(q: string | undefined): string;
176
222
  *
177
223
  * Filter operators: eq, neq, gt, gte, lt, lte, between, in, contains, starts, ends
178
224
  */
179
- declare function parseQuery<TConfig extends QueryFieldConfig | undefined = undefined>(query: Record<string, any>, fieldConfig?: TConfig): TypedParsedQuery<TConfig>;
225
+ declare function parseQuery<TConfig extends QueryFieldConfig | undefined = undefined>(query: Record<string, any>, fieldConfig?: TConfig, options?: ParseQueryOptions): TypedParsedQuery<TConfig>;
180
226
  /** Convert ParsedQuery back into query string parameters */
181
227
  declare function buildQueryParams(parsed: Partial<ParsedQuery>): Record<string, string | string[] | number>;
182
228
  //#endregion
183
- export { SortItem as _, parseSearchQuery as a, FILTER_OPERATORS as c, FilterOperator as d, PaginatedResponse as f, QueryFieldConfig as g, QueryBuilderAdapter as h, parseQuery as i, FieldsOf as l, ParsedQuery as m, parseFilters as n, parseSort as o, PaginationParams as p, parsePagination as r, ColumnQueryFieldConfig as s, buildQueryParams as t, FilterItem as u, StringQueryFieldConfig as v, TypedParsedQuery as y };
184
- //# sourceMappingURL=index-kEmG8nWU.d.mts.map
229
+ export { SortItem as C, QueryFieldConfig as S, TypedParsedQuery as T, FilterOperator as _, getQueryParsingDefaults as a, ParsedQuery as b, parseQuery as c, resetQueryParsingDefaults as d, setQueryParsingDefaults as f, FilterItem as g, FieldsOf as h, buildQueryParams as i, parseSearchQuery as l, FILTER_OPERATORS as m, QueryRejectReason as n, parseFilters as o, ColumnQueryFieldConfig as p, QueryRejection as r, parsePagination as s, ParseQueryOptions as t, parseSort as u, PaginatedResponse as v, StringQueryFieldConfig as w, QueryBuilderAdapter as x, PaginationParams as y };
230
+ //# sourceMappingURL=index-BtWJ9SLP.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-kEmG8nWU.d.mts","names":[],"sources":["../src/http/query/types.ts","../src/http/query/parse-query.ts"],"mappings":";;;KACY,cAAA;AAAA,cAaC,gBAAA,EAAgB,GAAA;AAAA,UAcZ,UAAA;EACf,KAAA;EACA,QAAA,EAAU,cAAc;EACxB,KAAA;AAAA;AAAA,UAGe,QAAA;EACf,KAAA;EACA,SAAS;AAAA;AAAA,UAGM,gBAAA;EACf,IAAA;EACA,KAAA;EACA,MAAA;AAAA;;;;AAXK;AAGP;UAgBiB,WAAA;EACf,OAAA,EAAS,UAAA;EACT,IAAA,EAAM,QAAA;EACN,UAAA,EAAY,gBAAA;EACZ,MAAA;AAAA;;;;;;;AAZM;AAQR;KAeY,QAAA,iBACM,gBAAA,oEAEd,OAAA,0BAAiC,CAAA,4BACjC,CAAA,kBACE,CAAA,YAEF,OAAA;EAAkB,OAAA;AAAA,IAChB,CAAA,8BACQ,CAAA;;;;;;;;;;;AApBN;AAWR;;;;;;UA8BiB,gBAAA,iBACC,gBAAA,sBACR,WAAA;EACR,OAAA,EAAS,KAAA,CAAM,UAAA;IAAe,KAAA,EAAO,QAAA,CAAS,OAAA;EAAA;EAC9C,IAAA,EAAM,KAAA,CAAM,QAAA;IAAa,KAAA,EAAO,QAAA,CAAS,OAAA;EAAA;AAAA;;;;;;;;;;;KAa/B,gBAAA,GAAmB,sBAAA,GAAyB,sBAAsB;AAAA,UAE7D,sBAAA;EACf,UAAA;EACA,QAAA;EACA,UAAA;AAAA;;;;;UAOe,sBAAA;EACf,OAAA,EAAS,MAAA;EACT,QAAA,GAAW,MAAM;EACjB,aAAA;EAAA,CACC,GAAA;AAAA;;UAIc,iBAAA;EACf,IAAA,EAAM,CAAC;EACP,IAAA;IACE,IAAA;IACA,KAAA;IACA,KAAA;IACA,UAAA;IACA,OAAA;IACA,OAAA;EAAA;AAAA;;;;;;;AAzC8C;AAalD;;;;AAA8E;AAE9E;;;;;;;;AAGY;AAOZ;;UA2CiB,mBAAA;EAzCE;EAAA,SA2CR,IAAA;EA5CA;;;;;EAmDT,KAAA,CAAM,MAAA,EAAQ,WAAA,EAAa,MAAA,EAAQ,OAAA,GAAU,OAAA;AAAA;;;AA/K/C;AAAA,iBCmBgB,YAAA,CACd,WAAA,iCACA,aAAA,cACC,UAAU;;iBA8BG,SAAA,CACd,SAAA,iCACA,aAAA,cACC,QAAQ;ADvDe;AAAA,iBCiFV,eAAA,CAAgB,MAAA;EAC9B,IAAA;EACA,KAAA;AAAA,IACE,gBAAgB;ADvES;AAAA,iBCyFb,gBAAA,CAAiB,CAAqB;;;;;;;;;ADxE/C;AAGP;;;;AAEW;AAGX;;;;;;;;AAGQ;AAQR;;;;;iBC+GgB,UAAA,iBAA2B,gBAAA,0BACzC,KAAA,EAAO,MAAA,eACP,WAAA,GAAc,OAAA,GACb,gBAAA,CAAiB,OAAA;;iBAaJ,gBAAA,CACd,MAAA,EAAQ,OAAA,CAAQ,WAAA,IACf,MAAA"}
1
+ {"version":3,"file":"index-BtWJ9SLP.d.mts","names":[],"sources":["../src/http/query/types.ts","../src/http/query/parse-query.ts"],"mappings":";;;KACY,cAAA;AAAA,cAaC,gBAAA,EAAgB,GAAA;AAAA,UAcZ,UAAA;EACf,KAAA;EACA,QAAA,EAAU,cAAc;EACxB,KAAA;AAAA;AAAA,UAGe,QAAA;EACf,KAAA;EACA,SAAS;AAAA;AAAA,UAGM,gBAAA;EACf,IAAA;EACA,KAAA;EACA,MAAA;AAAA;;;;AAXK;AAGP;UAgBiB,WAAA;EACf,OAAA,EAAS,UAAA;EACT,IAAA,EAAM,QAAA;EACN,UAAA,EAAY,gBAAA;EACZ,MAAA;AAAA;;;;;;;AAZM;AAQR;KAeY,QAAA,iBACM,gBAAA,oEAEd,OAAA,0BAAiC,CAAA,4BACjC,CAAA,kBACE,CAAA,YAEF,OAAA;EAAkB,OAAA;AAAA,IAChB,CAAA,8BACQ,CAAA;;;;;;;;;;;AApBN;AAWR;;;;;;UA8BiB,gBAAA,iBACC,gBAAA,sBACR,WAAA;EACR,OAAA,EAAS,KAAA,CAAM,UAAA;IAAe,KAAA,EAAO,QAAA,CAAS,OAAA;EAAA;EAC9C,IAAA,EAAM,KAAA,CAAM,QAAA;IAAa,KAAA,EAAO,QAAA,CAAS,OAAA;EAAA;AAAA;;;;;;;;;;;KAa/B,gBAAA,GAAmB,sBAAA,GAAyB,sBAAsB;AAAA,UAE7D,sBAAA;EACf,UAAA;EACA,QAAA;EACA,UAAA;AAAA;;;;;UAOe,sBAAA;EACf,OAAA,EAAS,MAAA;EACT,QAAA,GAAW,MAAM;EACjB,aAAA;EAAA,CACC,GAAA;AAAA;;UAIc,iBAAA;EACf,IAAA,EAAM,CAAC;EACP,IAAA;IACE,IAAA;IACA,KAAA;IACA,KAAA;IACA,UAAA;IACA,OAAA;IACA,OAAA;EAAA;AAAA;;;;;;;AAzC8C;AAalD;;;;AAA8E;AAE9E;;;;;;;;AAGY;AAOZ;;UA2CiB,mBAAA;EAzCE;EAAA,SA2CR,IAAA;EA5CA;;;;;EAmDT,KAAA,CAAM,MAAA,EAAQ,WAAA,EAAa,MAAA,EAAQ,OAAA,GAAU,OAAA;AAAA;;;AA/K/C;;;;AAA0B;AAA1B,KCkBY,iBAAA;AAAA,UAEK,cAAA;EACf,IAAA;EACA,KAAA;EACA,MAAA,EAAQ,iBAAiB;AAAA;AAAA,UAGV,iBAAA;;EAEf,QAAA;EDAA;ECEA,YAAA;EDDU;ECGV,eAAA;EDFK;AAAA;AAGP;;;ECKE,QAAA,IAAY,SAAA,EAAW,cAAc;AAAA;AAAA,UAG7B,oBAAA;EACR,QAAA;EACA,YAAA;EACA,eAAA;EACA,WAAA;AAAA;;;ADJM;AAQR;iBCYgB,uBAAA,CACd,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,oBAAA;;iBAQR,uBAAA,IAA2B,QAAQ,CAAC,oBAAA;;;;;;;iBAUpC,yBAAA;;iBAOA,YAAA,CACd,WAAA,iCACA,aAAA,aACA,OAAA,GAAU,IAAA,CAAK,iBAAA,gBACd,UAAA;;iBAqCa,SAAA,CACd,SAAA,iCACA,aAAA,aACA,OAAA,GAAU,IAAA,CAAK,iBAAA,gBACd,QAAA;;iBA8Ba,eAAA,CACd,MAAA;EACE,IAAA;EACA,KAAA;AAAA,GAEF,OAAA,GAAU,IAAA,CAAK,iBAAA,iCACd,gBAAA;;iBAqBa,gBAAA,CACd,CAAA,sBACA,OAAA,GAAU,IAAI,CAAC,iBAAA;;;;;;;;;;;;;;;;;;;;;;ADtHF;AAqBf;;;;;;;iBCmKgB,UAAA,iBAA2B,gBAAA,0BACzC,KAAA,EAAO,MAAA,eACP,WAAA,GAAc,OAAA,EACd,OAAA,GAAU,iBAAA,GACT,gBAAA,CAAiB,OAAA;;iBAcJ,gBAAA,CACd,MAAA,EAAQ,OAAA,CAAQ,WAAA,IACf,MAAA"}
package/dist/index.d.mts CHANGED
@@ -3,22 +3,17 @@ import { a as METADATA, c as Scope, i as Constructor, l as ServiceOptions, n as
3
3
  import { a as tokenName, c as createToken, i as KickJsRegistry, l as isInjectionToken, n as ContainerChangeEvent, o as INJECTION_TOKEN, r as ContainerChangeListener, s as InjectionToken, t as Container } from "./container-TWOUyR_0.mjs";
4
4
  import { A as Value, B as useAssets, C as Post, D as Repository, E as Put, F as KickAssets, I as UnknownAssetError, L as assets, M as withBuilder, N as ASSETS, O as RouteDefinition, P as ASSET_MANIFEST_VERSION, R as clearAssetCache, S as Patch, _ as Get, a as Autowired, b as Middleware, c as ColumnApiQueryParamsConfig, d as Delete, f as Env, g as FileUploadConfig, h as FileUpload, i as AssetKey, j as normalizeApiQueryParamsConfig, k as Service, l as Component, m as FileTypeFilter, n as ApiQueryParamsConfig, o as BaseUploadOptions, p as EnvKey, r as Asset, s as Builder, t as ApiQueryParams, u as Controller, v as Inject, w as PostConstruct, x as MiddlewareHandler, y as Injectable, z as resolveAsset } from "./decorators-ejABLo9H.mjs";
5
5
  import { a as baseEnvSchema, c as loadEnv, d as resetEnvCache, l as loadEnvFromSchema, n as TypedConfigService, o as defineEnv, r as createConfigService, s as getEnv, t as ConfigService, u as reloadEnv } from "./index-zIcb4wjg.mjs";
6
- import { i as MetaValue, n as ContextMeta, r as ExecutionContext, t as ContextKeys } from "./execution-context-B4cfhivz.mjs";
7
- import { a as ContextMetaKey, c as DepValue, i as ContextDecoratorTarget, l as ResolvedDeps, n as ContextDecorator, o as ContributorRegistration, r as ContextDecoratorSpec, s as ContributorRegistrations, t as AnyContributorRegistration, u as defineContextDecorator } from "./context-decorator-DDZ30BIW.mjs";
8
- import { a as MiddlewarePath, c as KickJsPluginName, d as IntrospectFn, f as IntrospectionKind, i as AppAdapterClass, l as KickJsPluginRegistry, n as AdapterMiddleware, o as MiddlewarePhase, p as IntrospectionSnapshot, r as AppAdapter, s as AugmentationMeta, t as AdapterContext, u as defineAugmentation } from "./adapter-CkpcZwzZ.mjs";
9
- import { i as ModuleRoutes, n as AppModuleClass, r as AppModuleEntry, t as AppModule } from "./app-module-BTzb-Vd6.mjs";
10
- import { a as Cacheable, c as setCacheProvider, i as CacheProvider, n as CacheEvict, o as MemoryCacheProvider, r as CacheOptions, s as getCacheProvider } from "./cache-BSFDtsEG.mjs";
6
+ import { _ as ExecutionContext, a as AnyContributorRegistration, c as ContextDecoratorTarget, d as ContributorRegistrations, f as DepValue, g as ContextMeta, h as ContextKeys, i as ModuleRoutes, l as ContextMetaKey, m as defineContextDecorator, n as AppModuleClass, o as ContextDecorator, p as ResolvedDeps, r as AppModuleEntry, s as ContextDecoratorSpec, t as AppModule, u as ContributorRegistration, v as MetaValue } from "./app-module-CuAS6hJC.mjs";
7
+ import { $ as CircuitBreaker, A as GroupAssetKeysResult, At as definePlugin, B as MountKind, Bt as IntrospectionSnapshot, C as Ctx, Ct as DefineModuleOptions, D as AssetKeyPair, Dt as DefinePluginOptions, E as RouteShape, Et as BuildContext, F as DefineAdapterOptions, Ft as KickJsPluginName, G as BuildPipelineOptions, H as mountSort, I as defineAdapter, It as KickJsPluginRegistry, J as SourcedRegistration, K as ContributorPipeline, L as DuplicateMountNameError, Lt as defineAugmentation, M as stripExt, Mt as ModuleRegistry, N as AdapterAsyncOptions, Nt as MutableModuleRegistry, O as AssetKeyStrategy, Ot as PluginAsyncOptions, P as AdapterFactory, Pt as AugmentationMeta, Q as MissingContributorError, R as MissingMountDepError, Rt as IntrospectFn, S as UseConnectOptions, St as defineModules, T as RequestContext, Tt as defineModule, U as RunContributorsOptions, V as MountSortItem, W as runContributors, X as ContributorCycleError, Y as buildPipeline, Z as DuplicateContributorError, _ as RouteTable, _t as FormatKickErrorOptions, a as MiddlewarePath, at as getClassMetaOrUndefined, b as RuntimeResponse, bt as formatKickError, c as AdapterHttp, ct as getMethodMeta, d as ExpressRuntimeTypes, dt as pushClassMeta, et as CircuitBreakerOptions, f as HttpRuntime, ft as pushMethodMeta, g as RouteMethod, gt as setMethodMeta, h as RouteMeta, ht as setInMetaRecord, i as AppAdapterClass, it as getClassMeta, j as groupAssetKeys, jt as KickPlugin, k as GroupAssetKeysOptions, kt as PluginFactory, l as ConnectMiddleware, lt as getMethodMetaOrUndefined, m as RouteEntry, mt as setInMetaMap, n as AdapterMiddleware, nt as CircuitBreakerStats, o as MiddlewarePhase, ot as getMetaMap, p as KickRuntimeRegister, pt as setClassMeta, q as ContributorSource, r as AppAdapter, rt as CircuitOpenError, s as ActiveRuntime, st as getMetaRecord, t as AdapterContext, tt as CircuitBreakerState, u as CtxHandler, ut as hasClassMeta, v as RuntimeAppOptions, vt as KickError, w as DeepReadonly, wt as ModuleFactory, x as RuntimeTypeMap, xt as ModuleList, y as RuntimeCapabilities, yt as KickErrorInit, z as MountCycleError, zt as IntrospectionKind } from "./adapter-D_uzU-QA.mjs";
11
8
  import { i as getCronJobs, n as Cron, r as CronJobMeta, t as CRON_META } from "./cron-DOOtTY4q.mjs";
12
- import { a as ProblemException, c as defaultProblemTitle, i as ProblemDetails, l as normalizeProblem, n as HttpStatus, o as Problems, r as HttpStatusCode, s as ValidationError, t as HttpException } from "./errors-CRCTjEUK.mjs";
9
+ import { a as Cacheable, c as setCacheProvider, i as CacheProvider, n as CacheEvict, o as MemoryCacheProvider, r as CacheOptions, s as getCacheProvider } from "./cache-BSFDtsEG.mjs";
13
10
  import { i as createLogger, n as Logger, r as LoggerProvider, t as ConsoleLoggerProvider } from "./logger-COlEkn_C.mjs";
11
+ import { a as ProblemException, c as defaultProblemTitle, i as ProblemDetails, l as normalizeProblem, n as HttpStatus, o as Problems, r as HttpStatusCode, s as ValidationError, t as HttpException } from "./errors-n0H96eEz.mjs";
14
12
  import { n as normalizePath, t as joinPaths } from "./path-BVA9MfN1.mjs";
15
- import { n as ModuleRegistry, r as MutableModuleRegistry, t as KickPlugin } from "./plugin-BQCn6zyj.mjs";
16
13
  import { a as isRef, c as toRefs, i as computed, l as unref, n as Ref, o as reactive, r as WatchOptions, s as ref, t as ComputedRef, u as watch } from "./reactivity-DWmLcN0A.mjs";
17
- import { $ as defineModule, A as CircuitBreakerStats, B as pushMethodMeta, C as buildPipeline, D as CircuitBreaker, E as MissingContributorError, F as getMetaRecord, G as FormatKickErrorOptions, H as setInMetaMap, I as getMethodMeta, J as formatKickError, K as KickError, L as getMethodMetaOrUndefined, M as getClassMeta, N as getClassMetaOrUndefined, O as CircuitBreakerOptions, P as getMetaMap, Q as ModuleFactory, R as hasClassMeta, S as SourcedRegistration, T as DuplicateContributorError, U as setInMetaRecord, V as setClassMeta, W as setMethodMeta, X as defineModules, Y as ModuleList, Z as DefineModuleOptions, _ as RunContributorsOptions, a as groupAssetKeys, b as ContributorPipeline, c as AdapterFactory, d as DuplicateMountNameError, et as BuildContext, f as MissingMountDepError, g as mountSort, h as MountSortItem, i as GroupAssetKeysResult, it as definePlugin, j as CircuitOpenError, k as CircuitBreakerState, l as DefineAdapterOptions, m as MountKind, n as AssetKeyStrategy, nt as PluginAsyncOptions, o as stripExt, p as MountCycleError, q as KickErrorInit, r as GroupAssetKeysOptions, rt as PluginFactory, s as AdapterAsyncOptions, t as AssetKeyPair, tt as DefinePluginOptions, u as defineAdapter, v as runContributors, w as ContributorCycleError, x as ContributorSource, y as BuildPipelineOptions, z as pushClassMeta } from "./index-frSEHiL_.mjs";
18
- import { n as ApplicationOptions, r as MiddlewareEntry, t as Application } from "./application-CAnpDQ8d.mjs";
19
- import { t as bootstrap } from "./bootstrap-8DDzBjhx.mjs";
20
- import { _ as SortItem, a as parseSearchQuery, c as FILTER_OPERATORS, d as FilterOperator, f as PaginatedResponse, g as QueryFieldConfig, h as QueryBuilderAdapter, i as parseQuery, l as FieldsOf, m as ParsedQuery, n as parseFilters, o as parseSort, p as PaginationParams, r as parsePagination, t as buildQueryParams, u as FilterItem, y as TypedParsedQuery } from "./index-kEmG8nWU.mjs";
21
- import { i as RouteShape, n as DeepReadonly, r as RequestContext, t as Ctx } from "./context-Dnt2Di7p.mjs";
14
+ import { C as SortItem, S as QueryFieldConfig, T as TypedParsedQuery, _ as FilterOperator, a as getQueryParsingDefaults, b as ParsedQuery, c as parseQuery, d as resetQueryParsingDefaults, f as setQueryParsingDefaults, g as FilterItem, h as FieldsOf, i as buildQueryParams, l as parseSearchQuery, m as FILTER_OPERATORS, n as QueryRejectReason, o as parseFilters, r as QueryRejection, s as parsePagination, t as ParseQueryOptions, u as parseSort, v as PaginatedResponse, x as QueryBuilderAdapter, y as PaginationParams } from "./index-BtWJ9SLP.mjs";
15
+ import { n as ApplicationOptions, r as MiddlewareEntry, t as Application } from "./application-pbx53JnX.mjs";
16
+ import { t as bootstrap } from "./bootstrap-DzfBj6Ja.mjs";
22
17
  import { n as cors, t as CorsOptions } from "./cors-C4aSCD3J.mjs";
23
18
  import { n as csrf, t as CsrfOptions } from "./csrf-7nUXGTuz.mjs";
24
19
  import { n as notFoundHandler, t as errorHandler } from "./error-handler-3ih4E-QZ.mjs";
@@ -27,9 +22,9 @@ import { n as RateLimitStore, r as rateLimit, t as RateLimitOptions } from "./ra
27
22
  import { n as requestId, t as REQUEST_ID_HEADER } from "./request-id-IDobbxU-.mjs";
28
23
  import { n as requestLogger, t as RequestLoggerOptions } from "./request-logger-DZVW6VNI.mjs";
29
24
  import { a as session, i as SessionStore, n as SessionData, r as SessionOptions, t as Session } from "./session-DSRA-PUX.mjs";
30
- import { n as SpaAdapterOptions, t as SpaAdapter } from "./spa-IRFC2eMN.mjs";
31
- import { a as upload, i as resolveMimeTypes, n as buildUploadMiddleware, r as cleanupFiles, t as UploadOptions } from "./upload-D6edAELH.mjs";
25
+ import { n as SpaAdapterOptions, t as SpaAdapter } from "./spa-BdvZFXJz.mjs";
26
+ import { c as resolveMimeTypes, l as upload, n as UploadOptions, o as buildUploadMiddleware, s as cleanupFiles } from "./upload-Bc_rBRtE.mjs";
32
27
  import { n as validate } from "./validate-DoZDOhCi.mjs";
33
- import { a as TraceContextOptions, c as requestScopeMiddleware, d as getRequestValue, f as requestStore, h as isClusterPrimary, i as TraceContext, l as RequestStore, m as ClusterOptions, n as ViewAdapterOptions, o as parseTraceparent, p as defineHttpContextDecorator, r as TRACEPARENT_HEADER, s as traceContext, t as ViewAdapter, u as getRequestStore } from "./views-BCl-mETX.mjs";
34
- import { r as buildRoutes } from "./router-builder-oQpcQMWl.mjs";
35
- export { ASSETS, ASSET_MANIFEST_VERSION, type AdapterAsyncOptions, type AdapterContext, type AdapterFactory, type AdapterMiddleware, type AnyContributorRegistration, ApiQueryParams, type ApiQueryParamsConfig, type ApiQueryParamsConfig as QueryParamsConfig, type AppAdapter, type AppAdapterClass, type AppModule, type AppModuleClass, type AppModuleEntry, Application, type ApplicationOptions, Asset, type AssetKey, type AssetKeyPair, type AssetKeyStrategy, type AugmentationMeta, Autowired, type BaseUploadOptions, type BuildContext, type BuildPipelineOptions, type Buildable, Builder, type BuilderOf, CRON_META, CacheEvict, type CacheOptions, type CacheProvider, Cacheable, CircuitBreaker, type CircuitBreakerOptions, type CircuitBreakerState, type CircuitBreakerStats, CircuitOpenError, type ClassKind, type ClusterOptions, type ColumnApiQueryParamsConfig, Component, type ComputedRef, ConfigService, ConsoleLoggerProvider, type Constructor, Container, type ContainerChangeEvent, type ContainerChangeListener, type ContextDecorator, type ContextDecoratorSpec, type ContextDecoratorTarget, type ContextKeys, type ContextMeta, type ContextMetaKey, ContributorCycleError, type ContributorPipeline, type ContributorRegistration, type ContributorRegistrations, type ContributorSource, Controller, type CorsOptions, Cron, type CronJobMeta, type CsrfOptions, type Ctx, type DeepReadonly, type DefineAdapterOptions, type DefineModuleOptions, type DefinePluginOptions, Delete, type DepValue, DuplicateContributorError, DuplicateMountNameError, type Env, type EnvKey, type ExecutionContext, FILTER_OPERATORS, type FieldsOf, type FileTypeFilter, FileUpload, type FileUploadConfig, type FilterItem, type FilterOperator, type FormatKickErrorOptions, Get, type GroupAssetKeysOptions, type GroupAssetKeysResult, type HelmetOptions, HttpException, HttpStatus, type HttpStatusCode, INJECTION_TOKEN, Inject, Injectable, type InjectionToken, type IntrospectFn, type IntrospectionKind, type IntrospectionSnapshot, type KickAssets, KickError, type KickErrorInit, type KickJsPluginName, type KickJsPluginRegistry, type KickJsRegistry, type KickPlugin, Logger, type LoggerProvider, METADATA, type MaybePromise, MemoryCacheProvider, type MetaValue, Middleware, type MiddlewareEntry, type MiddlewareHandler, type MiddlewarePath, type MiddlewarePhase, MissingContributorError, MissingMountDepError, type ModuleFactory, ModuleList, type ModuleRegistry, type ModuleRoutes, MountCycleError, type MountKind, type MountSortItem, MutableModuleRegistry, type PaginatedResponse, type PaginationParams, type ParsedQuery, Patch, type PluginAsyncOptions, type PluginFactory, Post, PostConstruct, type PostConstructStatus, type ProblemDetails, ProblemException, Problems, Put, type QueryBuilderAdapter, type QueryFieldConfig, REQUEST_ID_HEADER, type RateLimitOptions, type RateLimitStore, type Ref, Repository, RequestContext, type RequestLoggerOptions, type RequestStore, type ResolvedDeps, type RouteDefinition, type RouteShape, type RunContributorsOptions, Scope, Service, type ServiceOptions, type Session, type SessionData, type SessionOptions, type SessionStore, type SortItem, type SourcedRegistration, SpaAdapter, type SpaAdapterOptions, TRACEPARENT_HEADER, type TraceContext, type TraceContextOptions, type TypedConfigService, type TypedParsedQuery, UnknownAssetError, type UploadOptions, type ValidationError, Value, ViewAdapter, type ViewAdapterOptions, type WatchOptions, assets, baseEnvSchema, bootstrap, buildPipeline, buildQueryParams, buildRoutes, buildUploadMiddleware, cleanupFiles, clearAssetCache, computed, cors, createConfigService, createLogger, createToken, csrf, defaultProblemTitle, defineAdapter, defineAugmentation, defineContextDecorator, defineEnv, defineHttpContextDecorator, defineModule, defineModules, definePlugin, errorHandler, formatKickError, getCacheProvider, getClassMeta, getClassMetaOrUndefined, getCronJobs, getEnv, getMetaMap, getMetaRecord, getMethodMeta, getMethodMetaOrUndefined, getRequestStore, getRequestValue, groupAssetKeys, hasClassMeta, helmet, isClusterPrimary, isInjectionToken, isRef, joinPaths, loadEnv, loadEnvFromSchema, mountSort, normalizeApiQueryParamsConfig, normalizePath, normalizeProblem, notFoundHandler, parseFilters, parsePagination, parseQuery, parseSearchQuery, parseSort, parseTraceparent, pushClassMeta, pushMethodMeta, rateLimit, reactive, ref, reloadEnv, requestId, requestLogger, requestScopeMiddleware, requestStore, resetEnvCache, resolveAsset, resolveMimeTypes, runContributors, session, setCacheProvider, setClassMeta, setInMetaMap, setInMetaRecord, setMethodMeta, stripExt, toRefs, tokenName, traceContext, unref, upload, useAssets, validate, watch, withBuilder };
28
+ import { _ as ClusterOptions, a as TraceContextOptions, c as requestScopeMiddleware, d as getRequestValue, f as requestStore, g as defineHttpContextDecorator, h as materializeRouter, i as TraceContext, l as RequestStore, m as expressRuntime, n as ViewAdapterOptions, o as parseTraceparent, p as buildRoutes, r as TRACEPARENT_HEADER, s as traceContext, t as ViewAdapter, u as getRequestStore, v as isClusterPrimary } from "./views-DcTVDiOh.mjs";
29
+ import { r as buildRouteTable, t as BuildRoutesOptions } from "./router-builder-Bh3qSiDz.mjs";
30
+ export { ASSETS, ASSET_MANIFEST_VERSION, type ActiveRuntime, type AdapterAsyncOptions, type AdapterContext, type AdapterFactory, type AdapterHttp, type AdapterMiddleware, type AnyContributorRegistration, ApiQueryParams, type ApiQueryParamsConfig, type ApiQueryParamsConfig as QueryParamsConfig, type AppAdapter, type AppAdapterClass, type AppModule, type AppModuleClass, type AppModuleEntry, Application, type ApplicationOptions, Asset, type AssetKey, type AssetKeyPair, type AssetKeyStrategy, type AugmentationMeta, Autowired, type BaseUploadOptions, type BuildContext, type BuildPipelineOptions, type BuildRoutesOptions, type Buildable, Builder, type BuilderOf, CRON_META, CacheEvict, type CacheOptions, type CacheProvider, Cacheable, CircuitBreaker, type CircuitBreakerOptions, type CircuitBreakerState, type CircuitBreakerStats, CircuitOpenError, type ClassKind, type ClusterOptions, type ColumnApiQueryParamsConfig, Component, type ComputedRef, ConfigService, type ConnectMiddleware, ConsoleLoggerProvider, type Constructor, Container, type ContainerChangeEvent, type ContainerChangeListener, type ContextDecorator, type ContextDecoratorSpec, type ContextDecoratorTarget, type ContextKeys, type ContextMeta, type ContextMetaKey, ContributorCycleError, type ContributorPipeline, type ContributorRegistration, type ContributorRegistrations, type ContributorSource, Controller, type CorsOptions, Cron, type CronJobMeta, type CsrfOptions, type Ctx, type CtxHandler, type DeepReadonly, type DefineAdapterOptions, type DefineModuleOptions, type DefinePluginOptions, Delete, type DepValue, DuplicateContributorError, DuplicateMountNameError, type Env, type EnvKey, type ExecutionContext, type ExpressRuntimeTypes, FILTER_OPERATORS, type FieldsOf, type FileTypeFilter, FileUpload, type FileUploadConfig, type FilterItem, type FilterOperator, type FormatKickErrorOptions, Get, type GroupAssetKeysOptions, type GroupAssetKeysResult, type HelmetOptions, HttpException, type HttpRuntime, HttpStatus, type HttpStatusCode, INJECTION_TOKEN, Inject, Injectable, type InjectionToken, type IntrospectFn, type IntrospectionKind, type IntrospectionSnapshot, type KickAssets, KickError, type KickErrorInit, type KickJsPluginName, type KickJsPluginRegistry, type KickJsRegistry, type KickPlugin, type KickRuntimeRegister, Logger, type LoggerProvider, METADATA, type MaybePromise, MemoryCacheProvider, type MetaValue, Middleware, type MiddlewareEntry, type MiddlewareHandler, type MiddlewarePath, type MiddlewarePhase, MissingContributorError, MissingMountDepError, type ModuleFactory, ModuleList, type ModuleRegistry, type ModuleRoutes, MountCycleError, type MountKind, type MountSortItem, MutableModuleRegistry, type PaginatedResponse, type PaginationParams, type ParseQueryOptions, type ParsedQuery, Patch, type PluginAsyncOptions, type PluginFactory, Post, PostConstruct, type PostConstructStatus, type ProblemDetails, ProblemException, Problems, Put, type QueryBuilderAdapter, type QueryFieldConfig, type QueryRejectReason, type QueryRejection, REQUEST_ID_HEADER, type RateLimitOptions, type RateLimitStore, type Ref, Repository, RequestContext, type RequestLoggerOptions, type RequestStore, type ResolvedDeps, type RouteDefinition, type RouteEntry, type RouteMeta, type RouteMethod, type RouteShape, type RouteTable, type RunContributorsOptions, type RuntimeAppOptions, type RuntimeCapabilities, type RuntimeResponse, type RuntimeTypeMap, Scope, Service, type ServiceOptions, type Session, type SessionData, type SessionOptions, type SessionStore, type SortItem, type SourcedRegistration, SpaAdapter, type SpaAdapterOptions, TRACEPARENT_HEADER, type TraceContext, type TraceContextOptions, type TypedConfigService, type TypedParsedQuery, UnknownAssetError, type UploadOptions, type UseConnectOptions, type ValidationError, Value, ViewAdapter, type ViewAdapterOptions, type WatchOptions, assets, baseEnvSchema, bootstrap, buildPipeline, buildQueryParams, buildRouteTable, buildRoutes, buildUploadMiddleware, cleanupFiles, clearAssetCache, computed, cors, createConfigService, createLogger, createToken, csrf, defaultProblemTitle, defineAdapter, defineAugmentation, defineContextDecorator, defineEnv, defineHttpContextDecorator, defineModule, defineModules, definePlugin, errorHandler, expressRuntime, formatKickError, getCacheProvider, getClassMeta, getClassMetaOrUndefined, getCronJobs, getEnv, getMetaMap, getMetaRecord, getMethodMeta, getMethodMetaOrUndefined, getQueryParsingDefaults, getRequestStore, getRequestValue, groupAssetKeys, hasClassMeta, helmet, isClusterPrimary, isInjectionToken, isRef, joinPaths, loadEnv, loadEnvFromSchema, materializeRouter, mountSort, normalizeApiQueryParamsConfig, normalizePath, normalizeProblem, notFoundHandler, parseFilters, parsePagination, parseQuery, parseSearchQuery, parseSort, parseTraceparent, pushClassMeta, pushMethodMeta, rateLimit, reactive, ref, reloadEnv, requestId, requestLogger, requestScopeMiddleware, requestStore, resetEnvCache, resetQueryParsingDefaults, resolveAsset, resolveMimeTypes, runContributors, session, setCacheProvider, setClassMeta, setInMetaMap, setInMetaRecord, setMethodMeta, setQueryParsingDefaults, stripExt, toRefs, tokenName, traceContext, unref, upload, useAssets, validate, watch, withBuilder };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.16.0
2
+ * @forinda/kickjs v5.18.0-alpha.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{_ as isInjectionToken,a as formatKickError,c as UnknownAssetError,d as resolveAsset,f as useAssets,g as createToken,h as INJECTION_TOKEN,i as KickError,l as assets,m as stripExt,n as tokenName,o as ASSETS,p as groupAssetKeys,s as ASSET_MANIFEST_VERSION,t as Container,u as clearAssetCache}from"./container-D1gfs6__.mjs";import{METADATA,Scope}from"./core/interfaces.mjs";import{ConsoleLoggerProvider,Logger,createLogger}from"./core/logger.mjs";import{a as getMethodMeta,c as pushClassMeta,d as setInMetaMap,f as setInMetaRecord,i as getMetaRecord,l as pushMethodMeta,n as getClassMetaOrUndefined,o as getMethodMetaOrUndefined,p as setMethodMeta,r as getMetaMap,s as hasClassMeta,t as getClassMeta,u as setClassMeta}from"./metadata-Cll3P0N0.mjs";import{ApiQueryParams,Asset,Autowired,Builder,Component,Controller,Delete,FileUpload,Get,Inject,Injectable,Middleware,Patch,Post,PostConstruct,Put,Repository,Service,Value,normalizeApiQueryParamsConfig,withBuilder}from"./core/decorators.mjs";import{_ as ModuleList,a as MissingMountDepError,c as runContributors,d as DuplicateContributorError,f as MissingContributorError,g as MutableModuleRegistry,h as CircuitOpenError,i as DuplicateMountNameError,l as buildPipeline,m as CircuitBreaker,n as defineAdapter,o as MountCycleError,p as defineContextDecorator,r as definePlugin,s as mountSort,t as defineAugmentation,u as ContributorCycleError,v as defineModules,y as defineModule}from"./core-Db2uyqtM.mjs";import{CRON_META,Cron,getCronJobs}from"./core/cron.mjs";import{CacheEvict,Cacheable,MemoryCacheProvider,getCacheProvider,setCacheProvider}from"./core/cache.mjs";import{HttpException,HttpStatus,ProblemException,Problems,defaultProblemTitle,normalizeProblem}from"./core/errors.mjs";import{joinPaths,normalizePath}from"./core/path.mjs";import{computed,isRef,reactive,ref,toRefs,unref,watch}from"./core/reactivity.mjs";import{REQUEST_ID_HEADER,requestId}from"./http/middleware/request-id.mjs";import{errorHandler,notFoundHandler}from"./http/middleware/error-handler.mjs";import{i as requestStore,n as getRequestStore,r as getRequestValue,t as RequestContext}from"./context-MD7Mc_o_.mjs";import{n as requestScopeMiddleware,t as Application}from"./application-DnnqoDWx.mjs";import{a as parseSearchQuery,i as parseQuery,n as parseFilters,o as parseSort,r as parsePagination,s as FILTER_OPERATORS,t as buildQueryParams}from"./query-D-FiLfmd.mjs";import{validate}from"./http/middleware/validate.mjs";import{buildUploadMiddleware,cleanupFiles,resolveMimeTypes,upload}from"./http/middleware/upload.mjs";import{buildRoutes}from"./http/router-builder.mjs";import{a as loadEnvFromSchema,i as loadEnv,n as defineEnv,o as reloadEnv,r as getEnv,s as resetEnvCache,t as baseEnvSchema}from"./env-nwsfCpdy.mjs";import{n as isClusterPrimary,t as bootstrap}from"./bootstrap-CFK2aAjA.mjs";import{csrf}from"./http/middleware/csrf.mjs";import{requestLogger}from"./http/middleware/request-logger.mjs";import{helmet}from"./http/middleware/helmet.mjs";import{cors}from"./http/middleware/cors.mjs";import{rateLimit}from"./http/middleware/rate-limit.mjs";import{session}from"./http/middleware/session.mjs";import{ViewAdapter}from"./http/middleware/views.mjs";import{SpaAdapter}from"./http/middleware/spa.mjs";import{n as createConfigService,t as ConfigService}from"./config-BW5taOVX.mjs";import crypto from"node:crypto";function defineHttpContextDecoratorImpl(spec){return defineContextDecorator(spec)}const defineHttpContextDecorator=Object.freeze(Object.assign(defineHttpContextDecoratorImpl,{withParams:()=>spec=>defineHttpContextDecoratorImpl(spec)})),TRACEPARENT_HEADER=`traceparent`,TRACEPARENT_RE=/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;function generateTraceId(){return crypto.randomBytes(16).toString(`hex`)}function generateSpanId(){return crypto.randomBytes(8).toString(`hex`)}function parseTraceparent(header){let match=TRACEPARENT_RE.exec(header.trim().toLowerCase());if(!match)return null;let version=match[1],traceId=match[2],parentSpanId=match[3],flags=match[4];return version===`ff`||traceId===`00000000000000000000000000000000`||parentSpanId===`0000000000000000`?null:{version,traceId,parentSpanId,flags}}function traceContext(options={}){return(req,res,next)=>{let store=requestStore.getStore(),traceparentHeader=req.headers[TRACEPARENT_HEADER],raw=Array.isArray(traceparentHeader)?traceparentHeader[0]:traceparentHeader,parsed=raw?parseTraceparent(raw):null,traceId=parsed?.traceId??generateTraceId(),spanId=generateSpanId();store&&(store.values.set(`traceId`,traceId),store.values.set(`spanId`,spanId),parsed&&(store.values.set(`parentSpanId`,parsed.parentSpanId),store.values.set(`traceFlags`,parsed.flags),store.values.set(`traceVersion`,parsed.version))),req.traceId=traceId,req.spanId=spanId,options.propagateResponse&&res.setHeader(`traceresponse`,traceId),next()}}export{ASSETS,ASSET_MANIFEST_VERSION,ApiQueryParams,Application,Asset,Autowired,Builder,CRON_META,CacheEvict,Cacheable,CircuitBreaker,CircuitOpenError,Component,ConfigService,ConsoleLoggerProvider,Container,ContributorCycleError,Controller,Cron,Delete,DuplicateContributorError,DuplicateMountNameError,FILTER_OPERATORS,FileUpload,Get,HttpException,HttpStatus,INJECTION_TOKEN,Inject,Injectable,KickError,Logger,METADATA,MemoryCacheProvider,Middleware,MissingContributorError,MissingMountDepError,ModuleList,MountCycleError,MutableModuleRegistry,Patch,Post,PostConstruct,ProblemException,Problems,Put,REQUEST_ID_HEADER,Repository,RequestContext,Scope,Service,SpaAdapter,TRACEPARENT_HEADER,UnknownAssetError,Value,ViewAdapter,assets,baseEnvSchema,bootstrap,buildPipeline,buildQueryParams,buildRoutes,buildUploadMiddleware,cleanupFiles,clearAssetCache,computed,cors,createConfigService,createLogger,createToken,csrf,defaultProblemTitle,defineAdapter,defineAugmentation,defineContextDecorator,defineEnv,defineHttpContextDecorator,defineModule,defineModules,definePlugin,errorHandler,formatKickError,getCacheProvider,getClassMeta,getClassMetaOrUndefined,getCronJobs,getEnv,getMetaMap,getMetaRecord,getMethodMeta,getMethodMetaOrUndefined,getRequestStore,getRequestValue,groupAssetKeys,hasClassMeta,helmet,isClusterPrimary,isInjectionToken,isRef,joinPaths,loadEnv,loadEnvFromSchema,mountSort,normalizeApiQueryParamsConfig,normalizePath,normalizeProblem,notFoundHandler,parseFilters,parsePagination,parseQuery,parseSearchQuery,parseSort,parseTraceparent,pushClassMeta,pushMethodMeta,rateLimit,reactive,ref,reloadEnv,requestId,requestLogger,requestScopeMiddleware,requestStore,resetEnvCache,resolveAsset,resolveMimeTypes,runContributors,session,setCacheProvider,setClassMeta,setInMetaMap,setInMetaRecord,setMethodMeta,stripExt,toRefs,tokenName,traceContext,unref,upload,useAssets,validate,watch,withBuilder};
11
+ import{_ as isInjectionToken,a as formatKickError,c as UnknownAssetError,d as resolveAsset,f as useAssets,g as createToken,h as INJECTION_TOKEN,i as KickError,l as assets,m as stripExt,n as tokenName,o as ASSETS,p as groupAssetKeys,s as ASSET_MANIFEST_VERSION,t as Container,u as clearAssetCache}from"./container-BiGimG12.mjs";import{METADATA,Scope}from"./core/interfaces.mjs";import{ConsoleLoggerProvider,Logger,createLogger}from"./core/logger.mjs";import{a as getMethodMeta,c as pushClassMeta,d as setInMetaMap,f as setInMetaRecord,i as getMetaRecord,l as pushMethodMeta,n as getClassMetaOrUndefined,o as getMethodMetaOrUndefined,p as setMethodMeta,r as getMetaMap,s as hasClassMeta,t as getClassMeta,u as setClassMeta}from"./metadata-Pvgc-K8a.mjs";import{ApiQueryParams,Asset,Autowired,Builder,Component,Controller,Delete,FileUpload,Get,Inject,Injectable,Middleware,Patch,Post,PostConstruct,Put,Repository,Service,Value,normalizeApiQueryParamsConfig,withBuilder}from"./core/decorators.mjs";import{_ as ModuleList,a as MissingMountDepError,c as runContributors,d as DuplicateContributorError,f as MissingContributorError,g as MutableModuleRegistry,h as CircuitOpenError,i as DuplicateMountNameError,l as buildPipeline,m as CircuitBreaker,n as defineAdapter,o as MountCycleError,p as defineContextDecorator,r as definePlugin,s as mountSort,t as defineAugmentation,u as ContributorCycleError,v as defineModules,y as defineModule}from"./core-Y_xSqZ7v.mjs";import{CRON_META,Cron,getCronJobs}from"./core/cron.mjs";import{CacheEvict,Cacheable,MemoryCacheProvider,getCacheProvider,setCacheProvider}from"./core/cache.mjs";import{HttpException,HttpStatus,ProblemException,Problems,defaultProblemTitle,normalizeProblem}from"./core/errors.mjs";import{joinPaths,normalizePath}from"./core/path.mjs";import{computed,isRef,reactive,ref,toRefs,unref,watch}from"./core/reactivity.mjs";import{REQUEST_ID_HEADER,requestId}from"./http/middleware/request-id.mjs";import{errorHandler,notFoundHandler}from"./http/middleware/error-handler.mjs";import{i as requestStore,n as getRequestStore,r as getRequestValue,t as RequestContext}from"./context-leZajQAj.mjs";import{r as requestScopeMiddleware}from"./request-scope-BaM8_e_8.mjs";import{buildRouteTable}from"./http/router-builder.mjs";import{a as parseQuery,c as resetQueryParsingDefaults,i as parsePagination,l as setQueryParsingDefaults,n as getQueryParsingDefaults,o as parseSearchQuery,r as parseFilters,s as parseSort,t as buildQueryParams,u as FILTER_OPERATORS}from"./query-B3PhfU6M.mjs";import{validate}from"./http/middleware/validate.mjs";import{buildUploadMiddleware,cleanupFiles,resolveMimeTypes,upload}from"./http/middleware/upload.mjs";import{i as materializeRouter,n as buildRoutes,r as expressRuntime,t as Application}from"./application-BU5N6o_M.mjs";import{a as loadEnvFromSchema,i as loadEnv,n as defineEnv,o as reloadEnv,r as getEnv,s as resetEnvCache,t as baseEnvSchema}from"./env-BoMBrGWs.mjs";import{n as isClusterPrimary,t as bootstrap}from"./bootstrap-CFog4v_L.mjs";import{csrf}from"./http/middleware/csrf.mjs";import{requestLogger}from"./http/middleware/request-logger.mjs";import{helmet}from"./http/middleware/helmet.mjs";import{cors}from"./http/middleware/cors.mjs";import{rateLimit}from"./http/middleware/rate-limit.mjs";import{session}from"./http/middleware/session.mjs";import{ViewAdapter}from"./http/middleware/views.mjs";import{SpaAdapter}from"./http/middleware/spa.mjs";import{n as createConfigService,t as ConfigService}from"./config-Di3HlRTS.mjs";import crypto from"node:crypto";function defineHttpContextDecoratorImpl(spec){return defineContextDecorator(spec)}const defineHttpContextDecorator=Object.freeze(Object.assign(defineHttpContextDecoratorImpl,{withParams:()=>spec=>defineHttpContextDecoratorImpl(spec)})),TRACEPARENT_HEADER=`traceparent`,TRACEPARENT_RE=/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;function generateTraceId(){return crypto.randomBytes(16).toString(`hex`)}function generateSpanId(){return crypto.randomBytes(8).toString(`hex`)}function parseTraceparent(header){let match=TRACEPARENT_RE.exec(header.trim().toLowerCase());if(!match)return null;let version=match[1],traceId=match[2],parentSpanId=match[3],flags=match[4];return version===`ff`||traceId===`00000000000000000000000000000000`||parentSpanId===`0000000000000000`?null:{version,traceId,parentSpanId,flags}}function traceContext(options={}){return(req,res,next)=>{let store=requestStore.getStore(),traceparentHeader=req.headers[TRACEPARENT_HEADER],raw=Array.isArray(traceparentHeader)?traceparentHeader[0]:traceparentHeader,parsed=raw?parseTraceparent(raw):null,traceId=parsed?.traceId??generateTraceId(),spanId=generateSpanId();store&&(store.values.set(`traceId`,traceId),store.values.set(`spanId`,spanId),parsed&&(store.values.set(`parentSpanId`,parsed.parentSpanId),store.values.set(`traceFlags`,parsed.flags),store.values.set(`traceVersion`,parsed.version))),req.traceId=traceId,req.spanId=spanId,options.propagateResponse&&res.setHeader(`traceresponse`,traceId),next()}}export{ASSETS,ASSET_MANIFEST_VERSION,ApiQueryParams,Application,Asset,Autowired,Builder,CRON_META,CacheEvict,Cacheable,CircuitBreaker,CircuitOpenError,Component,ConfigService,ConsoleLoggerProvider,Container,ContributorCycleError,Controller,Cron,Delete,DuplicateContributorError,DuplicateMountNameError,FILTER_OPERATORS,FileUpload,Get,HttpException,HttpStatus,INJECTION_TOKEN,Inject,Injectable,KickError,Logger,METADATA,MemoryCacheProvider,Middleware,MissingContributorError,MissingMountDepError,ModuleList,MountCycleError,MutableModuleRegistry,Patch,Post,PostConstruct,ProblemException,Problems,Put,REQUEST_ID_HEADER,Repository,RequestContext,Scope,Service,SpaAdapter,TRACEPARENT_HEADER,UnknownAssetError,Value,ViewAdapter,assets,baseEnvSchema,bootstrap,buildPipeline,buildQueryParams,buildRouteTable,buildRoutes,buildUploadMiddleware,cleanupFiles,clearAssetCache,computed,cors,createConfigService,createLogger,createToken,csrf,defaultProblemTitle,defineAdapter,defineAugmentation,defineContextDecorator,defineEnv,defineHttpContextDecorator,defineModule,defineModules,definePlugin,errorHandler,expressRuntime,formatKickError,getCacheProvider,getClassMeta,getClassMetaOrUndefined,getCronJobs,getEnv,getMetaMap,getMetaRecord,getMethodMeta,getMethodMetaOrUndefined,getQueryParsingDefaults,getRequestStore,getRequestValue,groupAssetKeys,hasClassMeta,helmet,isClusterPrimary,isInjectionToken,isRef,joinPaths,loadEnv,loadEnvFromSchema,materializeRouter,mountSort,normalizeApiQueryParamsConfig,normalizePath,normalizeProblem,notFoundHandler,parseFilters,parsePagination,parseQuery,parseSearchQuery,parseSort,parseTraceparent,pushClassMeta,pushMethodMeta,rateLimit,reactive,ref,reloadEnv,requestId,requestLogger,requestScopeMiddleware,requestStore,resetEnvCache,resetQueryParsingDefaults,resolveAsset,resolveMimeTypes,runContributors,session,setCacheProvider,setClassMeta,setInMetaMap,setInMetaRecord,setMethodMeta,setQueryParsingDefaults,stripExt,toRefs,tokenName,traceContext,unref,upload,useAssets,validate,watch,withBuilder};
12
12
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/http/define-http-context-decorator.ts","../src/http/middleware/trace-context.ts"],"sourcesContent":["/**\n * HTTP-flavoured wrapper around {@link defineContextDecorator}.\n *\n * The core factory leaves `Ctx` defaulted to {@link ExecutionContext} so the\n * Context Contributor pipeline stays transport-agnostic — future WebSocket,\n * queue, and cron contexts share the same primitive. The cost is that the\n * vast majority of contributors (which are HTTP) have to spell the fourth\n * generic by hand to get `ctx.req` / `ctx.headers` typing:\n *\n * ```ts\n * // Verbose: spell every generic, including the params shape `P`.\n * defineContextDecorator<'tenant', Record<string, never>, Record<string, never>, RequestContext>({\n * key: 'tenant',\n * resolve: (ctx) => ({ id: ctx.req.headers['x-tenant-id'] as string }),\n * })\n * ```\n *\n * `defineHttpContextDecorator` removes that ceremony — the spec is typed\n * against `RequestContext` from the start, so resolvers can read `ctx.req`,\n * `ctx.headers`, `ctx.params`, etc. without a cast or generic dance:\n *\n * ```ts\n * import { defineHttpContextDecorator } from '@forinda/kickjs'\n *\n * const LoadTenant = defineHttpContextDecorator({\n * key: 'tenant',\n * resolve: (ctx) => ({ id: ctx.req.headers['x-tenant-id'] as string }),\n * })\n *\n * // Parameterised — the positional form forces you to also spell `K`\n * // and `D`, which loses automatic `deps` inference. Prefer the curried\n * // `.withParams<P>()` entry point below.\n * const LoadTenantParameterised = defineHttpContextDecorator<\n * 'tenant',\n * Record<string, never>,\n * { source: 'header' | 'subdomain' }\n * >({\n * key: 'tenant',\n * paramDefaults: { source: 'header' },\n * resolve: (ctx, _deps, params) => {\n * // params.source narrows inside `if` branches.\n * },\n * })\n *\n * // Parameterised + deps — only `P` is spelled; `K` and `D` infer from\n * // the spec, so `deps.repo` is fully typed in the resolver.\n * const LoadTenantWithRepo = defineHttpContextDecorator.withParams<{\n * source: 'header' | 'subdomain'\n * }>()({\n * key: 'tenant',\n * deps: { repo: TENANT_REPO },\n * paramDefaults: { source: 'header' },\n * resolve: (ctx, { repo }, params) =>\n * repo.findFor(ctx.req.headers['x-tenant-id'] as string, params.source),\n * })\n * ```\n *\n * Use {@link defineContextDecorator} directly when authoring contributors\n * for non-HTTP transports or when you want to share one contributor across\n * HTTP + WS + queue (the resolver then has to stick to the\n * `ExecutionContext` surface — `ctx.get` / `ctx.set` / `ctx.requestId`).\n */\n\nimport {\n defineContextDecorator,\n type ContextDecorator,\n type ContextDecoratorSpec,\n type DepValue,\n} from '../core/context-decorator'\nimport type { RequestContext } from './context'\n\n/**\n * Curried form returned by {@link DefineHttpContextDecoratorFn.withParams}.\n * Spell only the per-call params shape `P`; `K` and `D` are inferred\n * from the spec, and `Ctx` is locked to `RequestContext`.\n */\nexport interface DefineHttpContextDecoratorWithParams<P extends Record<string, unknown>> {\n <K extends string, D extends Record<string, DepValue> = Record<string, never>>(\n spec: ContextDecoratorSpec<K, D, P, RequestContext>,\n ): ContextDecorator<K, D, P, RequestContext>\n}\n\n/**\n * Public shape of {@link defineHttpContextDecorator} — the positional\n * call signature plus the curried `.withParams<P>()` helper that fixes\n * partial-inference for the parameterised case.\n */\nexport interface DefineHttpContextDecoratorFn {\n <\n K extends string,\n D extends Record<string, DepValue> = Record<string, never>,\n P extends Record<string, unknown> = Record<string, never>,\n >(\n spec: ContextDecoratorSpec<K, D, P, RequestContext>,\n ): ContextDecorator<K, D, P, RequestContext>\n\n /**\n * Curried entry point. Spell only `P`; `K` and `D` infer from the\n * spec. `Ctx` is locked to `RequestContext`.\n *\n * ```ts\n * const LoadTenant = defineHttpContextDecorator.withParams<{\n * source: 'header' | 'subdomain'\n * }>()({\n * key: 'tenant',\n * deps: { repo: TENANT_REPO }, // D inferred\n * paramDefaults: { source: 'header' },\n * resolve: (ctx, { repo }, params) => repo.findFor(ctx, params),\n * })\n * ```\n */\n withParams<P extends Record<string, unknown>>(): DefineHttpContextDecoratorWithParams<P>\n}\n\nfunction defineHttpContextDecoratorImpl<\n K extends string,\n D extends Record<string, DepValue> = Record<string, never>,\n P extends Record<string, unknown> = Record<string, never>,\n>(spec: ContextDecoratorSpec<K, D, P, RequestContext>): ContextDecorator<K, D, P, RequestContext> {\n return defineContextDecorator<K, D, P, RequestContext>(spec)\n}\n\nexport const defineHttpContextDecorator: DefineHttpContextDecoratorFn = Object.freeze(\n Object.assign(defineHttpContextDecoratorImpl, {\n withParams: <P extends Record<string, unknown>>(): DefineHttpContextDecoratorWithParams<P> => {\n return <K extends string, D extends Record<string, DepValue> = Record<string, never>>(\n spec: ContextDecoratorSpec<K, D, P, RequestContext>,\n ): ContextDecorator<K, D, P, RequestContext> => defineHttpContextDecoratorImpl<K, D, P>(spec)\n },\n }),\n) as DefineHttpContextDecoratorFn\n","import crypto from 'node:crypto'\nimport type { Request, Response, NextFunction } from 'express'\nimport { requestStore } from '../request-store'\n\n/**\n * W3C Trace Context header name.\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nexport const TRACEPARENT_HEADER = 'traceparent'\n\n/** Regex for a valid W3C traceparent: {version}-{trace-id}-{parent-id}-{flags} */\nconst TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/\n\nexport interface TraceContextOptions {\n /**\n * When true, respond with a `traceresponse` header containing the trace ID.\n * Useful for debugging. Default: false.\n */\n propagateResponse?: boolean\n}\n\n/**\n * Parsed W3C trace context fields.\n */\nexport interface TraceContext {\n /** W3C traceparent version (usually '00') */\n version: string\n /** 32-hex-char distributed trace ID */\n traceId: string\n /** 16-hex-char parent span ID */\n parentSpanId: string\n /** 2-hex-char trace flags */\n flags: string\n}\n\n/**\n * Generate a random 32-hex-character trace ID.\n */\nfunction generateTraceId(): string {\n return crypto.randomBytes(16).toString('hex')\n}\n\n/**\n * Generate a random 16-hex-character span ID.\n */\nfunction generateSpanId(): string {\n return crypto.randomBytes(8).toString('hex')\n}\n\n/**\n * Parse a W3C traceparent header value.\n * Returns null if the format is invalid.\n */\nexport function parseTraceparent(header: string): TraceContext | null {\n const match = TRACEPARENT_RE.exec(header.trim().toLowerCase())\n if (!match) return null\n\n const version = match[1]\n const traceId = match[2]\n const parentSpanId = match[3]\n const flags = match[4]\n\n // W3C spec: version ff is invalid, all-zero trace-id and parent-id are invalid\n if (\n version === 'ff' ||\n traceId === '00000000000000000000000000000000' ||\n parentSpanId === '0000000000000000'\n ) {\n return null\n }\n\n return { version, traceId, parentSpanId, flags }\n}\n\n/**\n * Middleware that extracts W3C `traceparent` header and stores trace context\n * in the request's AsyncLocalStorage store.\n *\n * If no valid `traceparent` header is present, a new traceId is generated\n * so that every request always has a trace ID available for correlation.\n *\n * Must be mounted **after** `requestScopeMiddleware()` (which creates the store).\n *\n * @example\n * ```ts\n * bootstrap({\n * middleware: [\n * requestScopeMiddleware(),\n * traceContext(), // extracts or generates traceId\n * requestLogger(),\n * express.json(),\n * ],\n * })\n * ```\n */\nexport function traceContext(options: TraceContextOptions = {}) {\n return (req: Request, res: Response, next: NextFunction) => {\n const store = requestStore.getStore()\n\n const traceparentHeader = req.headers[TRACEPARENT_HEADER]\n const raw = Array.isArray(traceparentHeader) ? traceparentHeader[0] : traceparentHeader\n const parsed = raw ? parseTraceparent(raw) : null\n\n const traceId = parsed?.traceId ?? generateTraceId()\n const spanId = generateSpanId()\n\n // Attach to the request store so logger + downstream code can access it\n if (store) {\n store.values.set('traceId', traceId)\n store.values.set('spanId', spanId)\n if (parsed) {\n store.values.set('parentSpanId', parsed.parentSpanId)\n store.values.set('traceFlags', parsed.flags)\n store.values.set('traceVersion', parsed.version)\n }\n }\n\n // Also expose on req for convenience\n ;(req as any).traceId = traceId\n ;(req as any).spanId = spanId\n\n if (options.propagateResponse) {\n res.setHeader('traceresponse', traceId)\n }\n\n next()\n }\n}\n"],"mappings":";;;;;;;;;;ixGAkHA,SAAS,+BAIP,KAAgG,CAChG,OAAO,uBAAgD,IAAI,CAC7D,CAEA,MAAa,2BAA2D,OAAO,OAC7E,OAAO,OAAO,+BAAgC,CAC5C,eAEI,MAC8C,+BAAwC,IAAI,CAEhG,CAAC,CACH,EC1Ha,mBAAqB,cAG5B,eAAiB,8DA2BvB,SAAS,iBAA0B,CACjC,OAAO,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK,CAC9C,CAKA,SAAS,gBAAyB,CAChC,OAAO,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,KAAK,CAC7C,CAMA,SAAgB,iBAAiB,OAAqC,CACpE,IAAM,MAAQ,eAAe,KAAK,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,EAC7D,GAAI,CAAC,MAAO,OAAO,KAEnB,IAAM,QAAU,MAAM,GAChB,QAAU,MAAM,GAChB,aAAe,MAAM,GACrB,MAAQ,MAAM,GAWpB,OAPE,UAAY,MACZ,UAAY,oCACZ,eAAiB,mBAEV,KAGF,CAAE,QAAS,QAAS,aAAc,KAAM,CACjD,CAuBA,SAAgB,aAAa,QAA+B,CAAC,EAAG,CAC9D,OAAQ,IAAc,IAAe,OAAuB,CAC1D,IAAM,MAAQ,aAAa,SAAS,EAE9B,kBAAoB,IAAI,QAAQ,oBAChC,IAAM,MAAM,QAAQ,iBAAiB,EAAI,kBAAkB,GAAK,kBAChE,OAAS,IAAM,iBAAiB,GAAG,EAAI,KAEvC,QAAU,QAAQ,SAAW,gBAAgB,EAC7C,OAAS,eAAe,EAG1B,QACF,MAAM,OAAO,IAAI,UAAW,OAAO,EACnC,MAAM,OAAO,IAAI,SAAU,MAAM,EAC7B,SACF,MAAM,OAAO,IAAI,eAAgB,OAAO,YAAY,EACpD,MAAM,OAAO,IAAI,aAAc,OAAO,KAAK,EAC3C,MAAM,OAAO,IAAI,eAAgB,OAAO,OAAO,IAKlD,IAAa,QAAU,QACvB,IAAa,OAAS,OAEnB,QAAQ,mBACV,IAAI,UAAU,gBAAiB,OAAO,EAGxC,KAAK,CACP,CACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/http/define-http-context-decorator.ts","../src/http/middleware/trace-context.ts"],"sourcesContent":["/**\n * HTTP-flavoured wrapper around {@link defineContextDecorator}.\n *\n * The core factory leaves `Ctx` defaulted to {@link ExecutionContext} so the\n * Context Contributor pipeline stays transport-agnostic — future WebSocket,\n * queue, and cron contexts share the same primitive. The cost is that the\n * vast majority of contributors (which are HTTP) have to spell the fourth\n * generic by hand to get `ctx.req` / `ctx.headers` typing:\n *\n * ```ts\n * // Verbose: spell every generic, including the params shape `P`.\n * defineContextDecorator<'tenant', Record<string, never>, Record<string, never>, RequestContext>({\n * key: 'tenant',\n * resolve: (ctx) => ({ id: ctx.req.headers['x-tenant-id'] as string }),\n * })\n * ```\n *\n * `defineHttpContextDecorator` removes that ceremony — the spec is typed\n * against `RequestContext` from the start, so resolvers can read `ctx.req`,\n * `ctx.headers`, `ctx.params`, etc. without a cast or generic dance:\n *\n * ```ts\n * import { defineHttpContextDecorator } from '@forinda/kickjs'\n *\n * const LoadTenant = defineHttpContextDecorator({\n * key: 'tenant',\n * resolve: (ctx) => ({ id: ctx.req.headers['x-tenant-id'] as string }),\n * })\n *\n * // Parameterised — the positional form forces you to also spell `K`\n * // and `D`, which loses automatic `deps` inference. Prefer the curried\n * // `.withParams<P>()` entry point below.\n * const LoadTenantParameterised = defineHttpContextDecorator<\n * 'tenant',\n * Record<string, never>,\n * { source: 'header' | 'subdomain' }\n * >({\n * key: 'tenant',\n * paramDefaults: { source: 'header' },\n * resolve: (ctx, _deps, params) => {\n * // params.source narrows inside `if` branches.\n * },\n * })\n *\n * // Parameterised + deps — only `P` is spelled; `K` and `D` infer from\n * // the spec, so `deps.repo` is fully typed in the resolver.\n * const LoadTenantWithRepo = defineHttpContextDecorator.withParams<{\n * source: 'header' | 'subdomain'\n * }>()({\n * key: 'tenant',\n * deps: { repo: TENANT_REPO },\n * paramDefaults: { source: 'header' },\n * resolve: (ctx, { repo }, params) =>\n * repo.findFor(ctx.req.headers['x-tenant-id'] as string, params.source),\n * })\n * ```\n *\n * Use {@link defineContextDecorator} directly when authoring contributors\n * for non-HTTP transports or when you want to share one contributor across\n * HTTP + WS + queue (the resolver then has to stick to the\n * `ExecutionContext` surface — `ctx.get` / `ctx.set` / `ctx.requestId`).\n */\n\nimport {\n defineContextDecorator,\n type ContextDecorator,\n type ContextDecoratorSpec,\n type DepValue,\n} from '../core/context-decorator'\nimport type { RequestContext } from './context'\n\n/**\n * Curried form returned by {@link DefineHttpContextDecoratorFn.withParams}.\n * Spell only the per-call params shape `P`; `K` and `D` are inferred\n * from the spec, and `Ctx` is locked to `RequestContext`.\n */\nexport interface DefineHttpContextDecoratorWithParams<P extends Record<string, unknown>> {\n <K extends string, D extends Record<string, DepValue> = Record<string, never>>(\n spec: ContextDecoratorSpec<K, D, P, RequestContext>,\n ): ContextDecorator<K, D, P, RequestContext>\n}\n\n/**\n * Public shape of {@link defineHttpContextDecorator} — the positional\n * call signature plus the curried `.withParams<P>()` helper that fixes\n * partial-inference for the parameterised case.\n */\nexport interface DefineHttpContextDecoratorFn {\n <\n K extends string,\n D extends Record<string, DepValue> = Record<string, never>,\n P extends Record<string, unknown> = Record<string, never>,\n >(\n spec: ContextDecoratorSpec<K, D, P, RequestContext>,\n ): ContextDecorator<K, D, P, RequestContext>\n\n /**\n * Curried entry point. Spell only `P`; `K` and `D` infer from the\n * spec. `Ctx` is locked to `RequestContext`.\n *\n * ```ts\n * const LoadTenant = defineHttpContextDecorator.withParams<{\n * source: 'header' | 'subdomain'\n * }>()({\n * key: 'tenant',\n * deps: { repo: TENANT_REPO }, // D inferred\n * paramDefaults: { source: 'header' },\n * resolve: (ctx, { repo }, params) => repo.findFor(ctx, params),\n * })\n * ```\n */\n withParams<P extends Record<string, unknown>>(): DefineHttpContextDecoratorWithParams<P>\n}\n\nfunction defineHttpContextDecoratorImpl<\n K extends string,\n D extends Record<string, DepValue> = Record<string, never>,\n P extends Record<string, unknown> = Record<string, never>,\n>(spec: ContextDecoratorSpec<K, D, P, RequestContext>): ContextDecorator<K, D, P, RequestContext> {\n return defineContextDecorator<K, D, P, RequestContext>(spec)\n}\n\nexport const defineHttpContextDecorator: DefineHttpContextDecoratorFn = Object.freeze(\n Object.assign(defineHttpContextDecoratorImpl, {\n withParams: <P extends Record<string, unknown>>(): DefineHttpContextDecoratorWithParams<P> => {\n return <K extends string, D extends Record<string, DepValue> = Record<string, never>>(\n spec: ContextDecoratorSpec<K, D, P, RequestContext>,\n ): ContextDecorator<K, D, P, RequestContext> => defineHttpContextDecoratorImpl<K, D, P>(spec)\n },\n }),\n) as DefineHttpContextDecoratorFn\n","import crypto from 'node:crypto'\nimport type { Request, Response, NextFunction } from 'express'\nimport { requestStore } from '../request-store'\n\n/**\n * W3C Trace Context header name.\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nexport const TRACEPARENT_HEADER = 'traceparent'\n\n/** Regex for a valid W3C traceparent: {version}-{trace-id}-{parent-id}-{flags} */\nconst TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/\n\nexport interface TraceContextOptions {\n /**\n * When true, respond with a `traceresponse` header containing the trace ID.\n * Useful for debugging. Default: false.\n */\n propagateResponse?: boolean\n}\n\n/**\n * Parsed W3C trace context fields.\n */\nexport interface TraceContext {\n /** W3C traceparent version (usually '00') */\n version: string\n /** 32-hex-char distributed trace ID */\n traceId: string\n /** 16-hex-char parent span ID */\n parentSpanId: string\n /** 2-hex-char trace flags */\n flags: string\n}\n\n/**\n * Generate a random 32-hex-character trace ID.\n */\nfunction generateTraceId(): string {\n return crypto.randomBytes(16).toString('hex')\n}\n\n/**\n * Generate a random 16-hex-character span ID.\n */\nfunction generateSpanId(): string {\n return crypto.randomBytes(8).toString('hex')\n}\n\n/**\n * Parse a W3C traceparent header value.\n * Returns null if the format is invalid.\n */\nexport function parseTraceparent(header: string): TraceContext | null {\n const match = TRACEPARENT_RE.exec(header.trim().toLowerCase())\n if (!match) return null\n\n const version = match[1]\n const traceId = match[2]\n const parentSpanId = match[3]\n const flags = match[4]\n\n // W3C spec: version ff is invalid, all-zero trace-id and parent-id are invalid\n if (\n version === 'ff' ||\n traceId === '00000000000000000000000000000000' ||\n parentSpanId === '0000000000000000'\n ) {\n return null\n }\n\n return { version, traceId, parentSpanId, flags }\n}\n\n/**\n * Middleware that extracts W3C `traceparent` header and stores trace context\n * in the request's AsyncLocalStorage store.\n *\n * If no valid `traceparent` header is present, a new traceId is generated\n * so that every request always has a trace ID available for correlation.\n *\n * Must be mounted **after** `requestScopeMiddleware()` (which creates the store).\n *\n * @example\n * ```ts\n * bootstrap({\n * middleware: [\n * requestScopeMiddleware(),\n * traceContext(), // extracts or generates traceId\n * requestLogger(),\n * express.json(),\n * ],\n * })\n * ```\n */\nexport function traceContext(options: TraceContextOptions = {}) {\n return (req: Request, res: Response, next: NextFunction) => {\n const store = requestStore.getStore()\n\n const traceparentHeader = req.headers[TRACEPARENT_HEADER]\n const raw = Array.isArray(traceparentHeader) ? traceparentHeader[0] : traceparentHeader\n const parsed = raw ? parseTraceparent(raw) : null\n\n const traceId = parsed?.traceId ?? generateTraceId()\n const spanId = generateSpanId()\n\n // Attach to the request store so logger + downstream code can access it\n if (store) {\n store.values.set('traceId', traceId)\n store.values.set('spanId', spanId)\n if (parsed) {\n store.values.set('parentSpanId', parsed.parentSpanId)\n store.values.set('traceFlags', parsed.flags)\n store.values.set('traceVersion', parsed.version)\n }\n }\n\n // Also expose on req for convenience\n ;(req as any).traceId = traceId\n ;(req as any).spanId = spanId\n\n if (options.propagateResponse) {\n res.setHeader('traceresponse', traceId)\n }\n\n next()\n }\n}\n"],"mappings":";;;;;;;;;;o9GAkHA,SAAS,+BAIP,KAAgG,CAChG,OAAO,uBAAgD,IAAI,CAC7D,CAEA,MAAa,2BAA2D,OAAO,OAC7E,OAAO,OAAO,+BAAgC,CAC5C,eAEI,MAC8C,+BAAwC,IAAI,CAEhG,CAAC,CACH,EC1Ha,mBAAqB,cAG5B,eAAiB,8DA2BvB,SAAS,iBAA0B,CACjC,OAAO,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK,CAC9C,CAKA,SAAS,gBAAyB,CAChC,OAAO,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,KAAK,CAC7C,CAMA,SAAgB,iBAAiB,OAAqC,CACpE,IAAM,MAAQ,eAAe,KAAK,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,EAC7D,GAAI,CAAC,MAAO,OAAO,KAEnB,IAAM,QAAU,MAAM,GAChB,QAAU,MAAM,GAChB,aAAe,MAAM,GACrB,MAAQ,MAAM,GAWpB,OAPE,UAAY,MACZ,UAAY,oCACZ,eAAiB,mBAEV,KAGF,CAAE,QAAS,QAAS,aAAc,KAAM,CACjD,CAuBA,SAAgB,aAAa,QAA+B,CAAC,EAAG,CAC9D,OAAQ,IAAc,IAAe,OAAuB,CAC1D,IAAM,MAAQ,aAAa,SAAS,EAE9B,kBAAoB,IAAI,QAAQ,oBAChC,IAAM,MAAM,QAAQ,iBAAiB,EAAI,kBAAkB,GAAK,kBAChE,OAAS,IAAM,iBAAiB,GAAG,EAAI,KAEvC,QAAU,QAAQ,SAAW,gBAAgB,EAC7C,OAAS,eAAe,EAG1B,QACF,MAAM,OAAO,IAAI,UAAW,OAAO,EACnC,MAAM,OAAO,IAAI,SAAU,MAAM,EAC7B,SACF,MAAM,OAAO,IAAI,eAAgB,OAAO,YAAY,EACpD,MAAM,OAAO,IAAI,aAAc,OAAO,KAAK,EAC3C,MAAM,OAAO,IAAI,eAAgB,OAAO,OAAO,IAKlD,IAAa,QAAU,QACvB,IAAa,OAAS,OAEnB,QAAQ,mBACV,IAAI,UAAU,gBAAiB,OAAO,EAGxC,KAAK,CACP,CACF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.16.0
2
+ * @forinda/kickjs v5.18.0-alpha.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -9,4 +9,4 @@
9
9
  * @license MIT
10
10
  */
11
11
  import"reflect-metadata";function setClassMeta(key,value,target){Reflect.defineMetadata(key,value,target)}function setMethodMeta(key,value,target,method){Reflect.defineMetadata(key,value,target,method)}function getClassMeta(key,target,fallback){return Reflect.getMetadata(key,target)??fallback}function getMethodMeta(key,target,method,fallback){return Reflect.getMetadata(key,target,method)??fallback}function hasClassMeta(key,target){return Reflect.hasMetadata(key,target)}function getClassMetaOrUndefined(key,target){return Reflect.getMetadata(key,target)}function getMethodMetaOrUndefined(key,target,method){return Reflect.getMetadata(key,target,method)}function pushClassMeta(key,target,...items){let existing=Reflect.getOwnMetadata(key,target)??[];Reflect.defineMetadata(key,[...existing,...items],target)}function pushMethodMeta(key,target,method,...items){let existing=Reflect.getOwnMetadata(key,target,method)??[];Reflect.defineMetadata(key,[...existing,...items],target,method)}function setInMetaMap(key,target,mapKey,mapValue){let inherited=Reflect.getOwnMetadata(key,target),map=inherited?new Map(inherited):new Map;map.set(mapKey,mapValue),Reflect.defineMetadata(key,map,target)}function getMetaMap(key,target){return Reflect.getMetadata(key,target)??new Map}function setInMetaRecord(key,target,recKey,recValue){let inherited=Reflect.getOwnMetadata(key,target),rec=inherited?{...inherited}:{};rec[recKey]=recValue,Reflect.defineMetadata(key,rec,target)}function getMetaRecord(key,target){return Reflect.getMetadata(key,target)??{}}export{getMethodMeta as a,pushClassMeta as c,setInMetaMap as d,setInMetaRecord as f,getMetaRecord as i,pushMethodMeta as l,getClassMetaOrUndefined as n,getMethodMetaOrUndefined as o,setMethodMeta as p,getMetaMap as r,hasClassMeta as s,getClassMeta as t,setClassMeta as u};
12
- //# sourceMappingURL=metadata-Cll3P0N0.mjs.map
12
+ //# sourceMappingURL=metadata-Pvgc-K8a.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata-Cll3P0N0.mjs","names":[],"sources":["../src/core/metadata.ts"],"sourcesContent":["import 'reflect-metadata'\nimport type { InjectionToken } from './token'\n\n/**\n * Typed utilities for reflect-metadata operations.\n *\n * Replaces scattered Reflect.defineMetadata/getMetadata calls with a single\n * source of truth. If we later move to Stage 3 decorators or a WeakMap-based\n * store, only this file changes — all 24+ consumer files stay untouched.\n *\n * Keys may be symbols, strings, or `InjectionToken<T>` objects produced by\n * `createToken()`. Using `createToken` is the preferred pattern because the\n * token's phantom type flows through the helpers, enabling type-safe reads.\n */\n\ntype MetaKey = symbol | string | InjectionToken<unknown>\n\n// ── Setters ─────────────────────────────────────────────────────\n\n/** Set metadata on a class (or prototype for property decorators) */\nexport function setClassMeta<T>(key: MetaKey, value: T, target: object): void {\n Reflect.defineMetadata(key, value, target)\n}\n\n/** Set metadata on a specific method */\nexport function setMethodMeta<T>(key: MetaKey, value: T, target: object, method: string): void {\n Reflect.defineMetadata(key, value, target, method)\n}\n\n// ── Getters ─────────────────────────────────────────────────────\n\n/** Get metadata from a class, returning `fallback` if not set */\nexport function getClassMeta<T>(key: MetaKey, target: object, fallback: T): T {\n return (Reflect.getMetadata(key, target) as T) ?? fallback\n}\n\n/** Get metadata from a specific method, returning `fallback` if not set */\nexport function getMethodMeta<T>(key: MetaKey, target: object, method: string, fallback: T): T {\n return (Reflect.getMetadata(key, target, method) as T) ?? fallback\n}\n\n/** Check if metadata exists on a class */\nexport function hasClassMeta(key: MetaKey, target: object): boolean {\n return Reflect.hasMetadata(key, target)\n}\n\n/** Get metadata from a class with no default (returns undefined if absent) */\nexport function getClassMetaOrUndefined<T>(key: MetaKey, target: object): T | undefined {\n return Reflect.getMetadata(key, target) as T | undefined\n}\n\n/** Get metadata from a method with no default (returns undefined if absent) */\nexport function getMethodMetaOrUndefined<T>(\n key: MetaKey,\n target: object,\n method: string,\n): T | undefined {\n return Reflect.getMetadata(key, target, method) as T | undefined\n}\n\n// ── Accumulate: Arrays ──────────────────────────────────────────\n\n/** Append items to an array stored in class metadata */\nexport function pushClassMeta<T>(key: MetaKey, target: object, ...items: T[]): void {\n const existing: T[] = Reflect.getOwnMetadata(key, target) ?? []\n Reflect.defineMetadata(key, [...existing, ...items], target)\n}\n\n/** Append items to an array stored in method metadata */\nexport function pushMethodMeta<T>(\n key: MetaKey,\n target: object,\n method: string,\n ...items: T[]\n): void {\n const existing: T[] = Reflect.getOwnMetadata(key, target, method) ?? []\n Reflect.defineMetadata(key, [...existing, ...items], target, method)\n}\n\n// ── Accumulate: Maps ────────────────────────────────────────────\n\n/** Set a key/value in a Map stored in class metadata */\nexport function setInMetaMap<K, V>(key: MetaKey, target: object, mapKey: K, mapValue: V): void {\n const inherited: Map<K, V> | undefined = Reflect.getOwnMetadata(key, target)\n const map = inherited ? new Map(inherited) : new Map<K, V>()\n map.set(mapKey, mapValue)\n Reflect.defineMetadata(key, map, target)\n}\n\n/** Get a Map from class metadata (returns empty Map if absent) */\nexport function getMetaMap<K, V>(key: MetaKey, target: object): Map<K, V> {\n return Reflect.getMetadata(key, target) ?? new Map()\n}\n\n// ── Accumulate: Records ─────────────────────────────────────────\n\n/** Set a key/value in a Record stored in class metadata */\nexport function setInMetaRecord<V>(\n key: MetaKey,\n target: object,\n recKey: string | number,\n recValue: V,\n): void {\n const inherited: Record<string | number, V> | undefined = Reflect.getOwnMetadata(key, target)\n const rec = inherited ? { ...inherited } : {}\n rec[recKey] = recValue\n Reflect.defineMetadata(key, rec, target)\n}\n\n/** Get a Record from class metadata (returns empty object if absent) */\nexport function getMetaRecord<V>(key: MetaKey, target: object): Record<string | number, V> {\n return Reflect.getMetadata(key, target) ?? {}\n}\n"],"mappings":";;;;;;;;;;yBAoBA,SAAgB,aAAgB,IAAc,MAAU,OAAsB,CAC5E,QAAQ,eAAe,IAAK,MAAO,MAAM,CAC3C,CAGA,SAAgB,cAAiB,IAAc,MAAU,OAAgB,OAAsB,CAC7F,QAAQ,eAAe,IAAK,MAAO,OAAQ,MAAM,CACnD,CAKA,SAAgB,aAAgB,IAAc,OAAgB,SAAgB,CAC5E,OAAQ,QAAQ,YAAY,IAAK,MAAM,GAAW,QACpD,CAGA,SAAgB,cAAiB,IAAc,OAAgB,OAAgB,SAAgB,CAC7F,OAAQ,QAAQ,YAAY,IAAK,OAAQ,MAAM,GAAW,QAC5D,CAGA,SAAgB,aAAa,IAAc,OAAyB,CAClE,OAAO,QAAQ,YAAY,IAAK,MAAM,CACxC,CAGA,SAAgB,wBAA2B,IAAc,OAA+B,CACtF,OAAO,QAAQ,YAAY,IAAK,MAAM,CACxC,CAGA,SAAgB,yBACd,IACA,OACA,OACe,CACf,OAAO,QAAQ,YAAY,IAAK,OAAQ,MAAM,CAChD,CAKA,SAAgB,cAAiB,IAAc,OAAgB,GAAG,MAAkB,CAClF,IAAM,SAAgB,QAAQ,eAAe,IAAK,MAAM,GAAK,CAAC,EAC9D,QAAQ,eAAe,IAAK,CAAC,GAAG,SAAU,GAAG,KAAK,EAAG,MAAM,CAC7D,CAGA,SAAgB,eACd,IACA,OACA,OACA,GAAG,MACG,CACN,IAAM,SAAgB,QAAQ,eAAe,IAAK,OAAQ,MAAM,GAAK,CAAC,EACtE,QAAQ,eAAe,IAAK,CAAC,GAAG,SAAU,GAAG,KAAK,EAAG,OAAQ,MAAM,CACrE,CAKA,SAAgB,aAAmB,IAAc,OAAgB,OAAW,SAAmB,CAC7F,IAAM,UAAmC,QAAQ,eAAe,IAAK,MAAM,EACrE,IAAM,UAAY,IAAI,IAAI,SAAS,EAAI,IAAI,IACjD,IAAI,IAAI,OAAQ,QAAQ,EACxB,QAAQ,eAAe,IAAK,IAAK,MAAM,CACzC,CAGA,SAAgB,WAAiB,IAAc,OAA2B,CACxE,OAAO,QAAQ,YAAY,IAAK,MAAM,GAAK,IAAI,GACjD,CAKA,SAAgB,gBACd,IACA,OACA,OACA,SACM,CACN,IAAM,UAAoD,QAAQ,eAAe,IAAK,MAAM,EACtF,IAAM,UAAY,CAAE,GAAG,SAAU,EAAI,CAAC,EAC5C,IAAI,QAAU,SACd,QAAQ,eAAe,IAAK,IAAK,MAAM,CACzC,CAGA,SAAgB,cAAiB,IAAc,OAA4C,CACzF,OAAO,QAAQ,YAAY,IAAK,MAAM,GAAK,CAAC,CAC9C"}
1
+ {"version":3,"file":"metadata-Pvgc-K8a.mjs","names":[],"sources":["../src/core/metadata.ts"],"sourcesContent":["import 'reflect-metadata'\nimport type { InjectionToken } from './token'\n\n/**\n * Typed utilities for reflect-metadata operations.\n *\n * Replaces scattered Reflect.defineMetadata/getMetadata calls with a single\n * source of truth. If we later move to Stage 3 decorators or a WeakMap-based\n * store, only this file changes — all 24+ consumer files stay untouched.\n *\n * Keys may be symbols, strings, or `InjectionToken<T>` objects produced by\n * `createToken()`. Using `createToken` is the preferred pattern because the\n * token's phantom type flows through the helpers, enabling type-safe reads.\n */\n\ntype MetaKey = symbol | string | InjectionToken<unknown>\n\n// ── Setters ─────────────────────────────────────────────────────\n\n/** Set metadata on a class (or prototype for property decorators) */\nexport function setClassMeta<T>(key: MetaKey, value: T, target: object): void {\n Reflect.defineMetadata(key, value, target)\n}\n\n/** Set metadata on a specific method */\nexport function setMethodMeta<T>(key: MetaKey, value: T, target: object, method: string): void {\n Reflect.defineMetadata(key, value, target, method)\n}\n\n// ── Getters ─────────────────────────────────────────────────────\n\n/** Get metadata from a class, returning `fallback` if not set */\nexport function getClassMeta<T>(key: MetaKey, target: object, fallback: T): T {\n return (Reflect.getMetadata(key, target) as T) ?? fallback\n}\n\n/** Get metadata from a specific method, returning `fallback` if not set */\nexport function getMethodMeta<T>(key: MetaKey, target: object, method: string, fallback: T): T {\n return (Reflect.getMetadata(key, target, method) as T) ?? fallback\n}\n\n/** Check if metadata exists on a class */\nexport function hasClassMeta(key: MetaKey, target: object): boolean {\n return Reflect.hasMetadata(key, target)\n}\n\n/** Get metadata from a class with no default (returns undefined if absent) */\nexport function getClassMetaOrUndefined<T>(key: MetaKey, target: object): T | undefined {\n return Reflect.getMetadata(key, target) as T | undefined\n}\n\n/** Get metadata from a method with no default (returns undefined if absent) */\nexport function getMethodMetaOrUndefined<T>(\n key: MetaKey,\n target: object,\n method: string,\n): T | undefined {\n return Reflect.getMetadata(key, target, method) as T | undefined\n}\n\n// ── Accumulate: Arrays ──────────────────────────────────────────\n\n/** Append items to an array stored in class metadata */\nexport function pushClassMeta<T>(key: MetaKey, target: object, ...items: T[]): void {\n const existing: T[] = Reflect.getOwnMetadata(key, target) ?? []\n Reflect.defineMetadata(key, [...existing, ...items], target)\n}\n\n/** Append items to an array stored in method metadata */\nexport function pushMethodMeta<T>(\n key: MetaKey,\n target: object,\n method: string,\n ...items: T[]\n): void {\n const existing: T[] = Reflect.getOwnMetadata(key, target, method) ?? []\n Reflect.defineMetadata(key, [...existing, ...items], target, method)\n}\n\n// ── Accumulate: Maps ────────────────────────────────────────────\n\n/** Set a key/value in a Map stored in class metadata */\nexport function setInMetaMap<K, V>(key: MetaKey, target: object, mapKey: K, mapValue: V): void {\n const inherited: Map<K, V> | undefined = Reflect.getOwnMetadata(key, target)\n const map = inherited ? new Map(inherited) : new Map<K, V>()\n map.set(mapKey, mapValue)\n Reflect.defineMetadata(key, map, target)\n}\n\n/** Get a Map from class metadata (returns empty Map if absent) */\nexport function getMetaMap<K, V>(key: MetaKey, target: object): Map<K, V> {\n return Reflect.getMetadata(key, target) ?? new Map()\n}\n\n// ── Accumulate: Records ─────────────────────────────────────────\n\n/** Set a key/value in a Record stored in class metadata */\nexport function setInMetaRecord<V>(\n key: MetaKey,\n target: object,\n recKey: string | number,\n recValue: V,\n): void {\n const inherited: Record<string | number, V> | undefined = Reflect.getOwnMetadata(key, target)\n const rec = inherited ? { ...inherited } : {}\n rec[recKey] = recValue\n Reflect.defineMetadata(key, rec, target)\n}\n\n/** Get a Record from class metadata (returns empty object if absent) */\nexport function getMetaRecord<V>(key: MetaKey, target: object): Record<string | number, V> {\n return Reflect.getMetadata(key, target) ?? {}\n}\n"],"mappings":";;;;;;;;;;yBAoBA,SAAgB,aAAgB,IAAc,MAAU,OAAsB,CAC5E,QAAQ,eAAe,IAAK,MAAO,MAAM,CAC3C,CAGA,SAAgB,cAAiB,IAAc,MAAU,OAAgB,OAAsB,CAC7F,QAAQ,eAAe,IAAK,MAAO,OAAQ,MAAM,CACnD,CAKA,SAAgB,aAAgB,IAAc,OAAgB,SAAgB,CAC5E,OAAQ,QAAQ,YAAY,IAAK,MAAM,GAAW,QACpD,CAGA,SAAgB,cAAiB,IAAc,OAAgB,OAAgB,SAAgB,CAC7F,OAAQ,QAAQ,YAAY,IAAK,OAAQ,MAAM,GAAW,QAC5D,CAGA,SAAgB,aAAa,IAAc,OAAyB,CAClE,OAAO,QAAQ,YAAY,IAAK,MAAM,CACxC,CAGA,SAAgB,wBAA2B,IAAc,OAA+B,CACtF,OAAO,QAAQ,YAAY,IAAK,MAAM,CACxC,CAGA,SAAgB,yBACd,IACA,OACA,OACe,CACf,OAAO,QAAQ,YAAY,IAAK,OAAQ,MAAM,CAChD,CAKA,SAAgB,cAAiB,IAAc,OAAgB,GAAG,MAAkB,CAClF,IAAM,SAAgB,QAAQ,eAAe,IAAK,MAAM,GAAK,CAAC,EAC9D,QAAQ,eAAe,IAAK,CAAC,GAAG,SAAU,GAAG,KAAK,EAAG,MAAM,CAC7D,CAGA,SAAgB,eACd,IACA,OACA,OACA,GAAG,MACG,CACN,IAAM,SAAgB,QAAQ,eAAe,IAAK,OAAQ,MAAM,GAAK,CAAC,EACtE,QAAQ,eAAe,IAAK,CAAC,GAAG,SAAU,GAAG,KAAK,EAAG,OAAQ,MAAM,CACrE,CAKA,SAAgB,aAAmB,IAAc,OAAgB,OAAW,SAAmB,CAC7F,IAAM,UAAmC,QAAQ,eAAe,IAAK,MAAM,EACrE,IAAM,UAAY,IAAI,IAAI,SAAS,EAAI,IAAI,IACjD,IAAI,IAAI,OAAQ,QAAQ,EACxB,QAAQ,eAAe,IAAK,IAAK,MAAM,CACzC,CAGA,SAAgB,WAAiB,IAAc,OAA2B,CACxE,OAAO,QAAQ,YAAY,IAAK,MAAM,GAAK,IAAI,GACjD,CAKA,SAAgB,gBACd,IACA,OACA,OACA,SACM,CACN,IAAM,UAAoD,QAAQ,eAAe,IAAK,MAAM,EACtF,IAAM,UAAY,CAAE,GAAG,SAAU,EAAI,CAAC,EAC5C,IAAI,QAAU,SACd,QAAQ,eAAe,IAAK,IAAK,MAAM,CACzC,CAGA,SAAgB,cAAiB,IAAc,OAA4C,CACzF,OAAO,QAAQ,YAAY,IAAK,MAAM,GAAK,CAAC,CAC9C"}