@silkweave/nestjs 2.5.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -130,7 +130,7 @@ Exposes the decorated controller route as an MCP tool. Every option is optional.
130
130
  |--------|------|---------|-------------|
131
131
  | `name` | `string` | `${ControllerBase}${MethodName}` (e.g. `UsersGet`) | MCP tool name override |
132
132
  | `description` | `string` | `@ApiOperation` summary/description, else generated | Tool description |
133
- | `input` | `Record<string, z.ZodType>` | - | Zod raw-shape override merged over the reflected fields (per-field). The escape hatch for shapes reflection can't express - discriminated unions, custom validators, `@Transform` |
133
+ | `input` | `Record<string, z.ZodType> \| z.ZodObject` | - | Zod override merged over the reflected fields (per-field). A raw shape (`{ field: z.string() }`) **or** a whole `z.object({ ... })` (its `.shape` is unwrapped). The escape hatch for shapes reflection can't express - discriminated unions, custom validators, `@Transform`. It **adds to** the reflected fields; it does not replace them (see the warning below) |
134
134
  | `pipes` | `'apply' \| 'skip'` | `'apply'` | Whether to run parameter-bound pipes (`@Param('id', ParseIntPipe)`) when re-binding |
135
135
  | `result` | `'json' \| 'smart'` | `'smart'` | Default MCP result format - `'json'` returns compact JSON text (`jsonToolResult`); `'smart'` inlines small payloads and offloads large ones to an embedded resource (`smartToolResult`). A client that sends `_meta.disposition` on the call overrides it |
136
136
 
@@ -156,7 +156,7 @@ For each `@Mcp` method the adapter builds **one flat Zod input object** by mergi
156
156
  2. `class-validator` decorators (`@IsString`, `@MinLength`, `@IsOptional`, `@IsEnum`, ...) - **optional** peer
157
157
  3. `@nestjs/swagger` decorators - `@ApiParam`/`@ApiQuery` for scalar path/query params, `@ApiProperty` for whole-DTO properties - **optional** peer
158
158
  4. An ingested OpenAPI document, matched by HTTP verb + path (`SilkweaveModule.forRoot({ openapi })`)
159
- 5. `@Mcp({ input })` raw-shape override
159
+ 5. `@Mcp({ input })` override (a raw shape or a `z.object({ ... })`)
160
160
 
161
161
  Field sources are derived from the parameter decorators:
162
162
 
@@ -168,10 +168,17 @@ Field sources are derived from the parameter decorators:
168
168
  | `@Query() dto: ListDto` | each property of `ListDto`, flattened to top level |
169
169
  | `@Body('x') x` | scalar field `x` |
170
170
  | `@Body() dto: CreateDto` | each property of `CreateDto`, flattened to top level |
171
- | `@Req`/`@Res`/`@Headers`/`@Ip`/`@Session`/files | not exposed; bound at call time (headers/req from the MCP request stand-in, the rest `undefined`) |
171
+ | `@Req`/`@Headers`/`@Ip`/`@Session`/files | not exposed; bound at call time (headers/req from the MCP request stand-in, the rest `undefined`) |
172
+ | `@Res() res` | not exposed; bound to the **real Express response over tRPC** (so `@Res({ passthrough: true })` can set cookies/headers), `undefined` over MCP (no HTTP response) |
172
173
 
173
174
  On a tool call the validated input is split back into the handler's positional arguments per the same parameter map, parameter-bound pipes run (unless `pipes: 'skip'`), and the method is invoked directly.
174
175
 
176
+ > **Unreflectable parameter warning.** A whole-DTO `@Body()`/`@Query()` whose type can't be reflected logs a `Silkweave` warning at boot naming the controller method and parameter. The usual cause is an **intersection/union** type (e.g. `@Body() input: CreateDto & z.infer<typeof Extra>`): TypeScript erases it to `Object` under `design:type`, so the DTO class reference is lost and **none** of its `@ApiProperty`/`class-validator` fields reflect. A `@Mcp`/`@Trpc({ input })` override on the same method does **not** silence this - the override *adds* fields, it doesn't recover the dropped ones. Fix it by using a single DTO class, or by declaring every field via `({ input })`.
177
+
178
+ ### Nullable fields
179
+
180
+ `@ApiProperty({ nullable: true })` (and OpenAPI `nullable: true`) reflect to a `.nullable()` Zod field (`string | null`). `class-validator`'s `@IsOptional()` only yields `string | undefined` (optional, not nullable) - it has no `null` signal - so for a `string | null` field add `@ApiProperty({ nullable: true })` or override the field via `({ input })`.
181
+
175
182
  ### Optional OpenAPI ingestion
176
183
 
177
184
  Pass a pre-built OpenAPI document (e.g. a committed `openapi.json`, or one built in a two-phase bootstrap) to use it as the authoritative schema source. It is matched to each `@Mcp` method by verb + path and overrides decorator reflection for the fields it covers; unmatched operations/fields fall back to reflection.
@@ -230,7 +237,7 @@ export class UsersController {
230
237
  |--------|------|---------|-------------|
231
238
  | `name` | `string` | `${ControllerBase}.${MethodName}` | Procedure-name override (before camelCasing) |
232
239
  | `description` | `string` | `@ApiOperation` summary/description, else generated | Procedure description |
233
- | `input` | `Record<string, z.ZodType>` | - | Zod raw-shape override merged over reflected fields (same as `@Mcp({ input })`) |
240
+ | `input` | `Record<string, z.ZodType> \| z.ZodObject` | - | Zod override merged over reflected fields - a raw shape or a `z.object({ ... })` (same as `@Mcp({ input })`) |
234
241
  | `output` | `z.ZodType \| DtoClass \| Record<string, z.ZodType>` | reflected from `@ApiOkResponse` | Explicit output schema driving the generated output type (wins over reflection) |
235
242
  | `chunk` | `z.ZodType \| DtoClass` | `unknown` | Element type for a subscription's `async *` stream |
236
243
  | `kind` | `'query' \| 'mutation' \| 'subscription'` | inferred | `@Get` ⇒ query, others ⇒ mutation, `async *` ⇒ subscription |
@@ -247,6 +254,12 @@ tRPC carries output types end-to-end, so the generated `AppRouter` needs them. I
247
254
  1. **`@ApiOkResponse({ type: Dto })`** (or any 2xx `@ApiResponse`) - the response DTO is flattened like an input DTO into the procedure's output type.
248
255
  2. **`@Trpc({ output })`** - an explicit Zod schema, DTO class, or raw shape. Wins over reflection. Use it when the return shape can't be reflected losslessly (e.g. **nested** DTOs and `Dto[]` arrays degrade to `unknown`/`unknown[]` - reflection is one level deep). For a precise nested shape, hand `@Trpc({ output })` a Zod schema.
249
256
 
257
+ When a reflected output field degrades to `unknown`/`unknown[]`, the adapter logs a `Silkweave` warning at boot naming the controller method and the field(s) - so a silently-`unknown` grid/list/report output is visible instead of surfacing only at the client. The warning fires only for **reflected** outputs; an explicit `@Trpc({ output })` Zod schema is your own typing and is never flagged.
258
+
259
+ ### zod v3 / v4 interop
260
+
261
+ The reflector builds schemas with Zod v4 internally, but `@Trpc({ input })`/`@Trpc({ output })`/`@Trpc({ chunk })` (and the `@Mcp({ input })` override) accept a schema from **either** Zod v3 or v4 - including `zod/v4` schemas from an app already migrated off Zod v3. The generated `AppRouter` input/output types resolve correctly across the boundary. Override detection is duck-typed (`safeParse`/`.shape`), so it does not depend on a shared Zod instance.
262
+
250
263
  ### Subscriptions (`async *` ⇒ SSE)
251
264
 
252
265
  An `async *` method is registered as a tRPC **subscription** served over SSE. It needs no HTTP verb - a verb-less `@Trpc({ kind: 'subscription', chunk })` exposes it over tRPC **without** creating a public REST route (see [tRPC/MCP without REST](#trpcmcp-without-a-public-rest-route)). Guards run before the first chunk.
package/build/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as reflectDtoFields, a as OpenApiDocument, c as openApiFields, d as classValidatorToField, f as designTypeToField, g as openapiSchemaToField, h as normalizeEnum, i as SilkweaveModuleOptions, l as FieldDesc, m as mergeField, n as NestSilkweaveAdapter, o as OpenApiLookup, p as fieldToZod, r as SILKWEAVE_MODULE_OPTIONS, s as buildOpenApiLookup, t as NestAdapterRegisterContext, u as apiPropertyToField, v as swaggerParamToField, y as typeTokenToBase } from "./types-ByWkPWx2.mjs";
1
+ import { _ as reflectDtoFields, a as OpenApiDocument, b as unreflectedFields, c as openApiFields, d as classValidatorToField, f as designTypeToField, g as openapiSchemaToField, h as normalizeEnum, i as SilkweaveModuleOptions, l as FieldDesc, m as mergeField, n as NestSilkweaveAdapter, o as OpenApiLookup, p as fieldToZod, r as SILKWEAVE_MODULE_OPTIONS, s as buildOpenApiLookup, t as NestAdapterRegisterContext, u as apiPropertyToField, v as swaggerParamToField, y as typeTokenToBase } from "./types-wmI5n_7i.mjs";
2
2
  import { CanActivate, DynamicModule, MiddlewareConsumer, NestModule, Type } from "@nestjs/common";
3
3
  import { ApplicationConfig, DiscoveryService, HttpAdapterHost, MetadataScanner, ModuleRef, Reflector } from "@nestjs/core";
4
4
  import { Action } from "@silkweave/core";
@@ -29,11 +29,16 @@ interface McpMetadata {
29
29
  */
30
30
  description?: string;
31
31
  /**
32
- * Zod raw-shape override merged over the reflected input fields (override
33
- * wins per field). The escape hatch for shapes reflection can't express
34
- * losslessly - discriminated unions, custom validators, `@Transform`, etc.
32
+ * Zod override merged over the reflected input fields (override wins per
33
+ * field). Accepts either a raw shape (`{ field: z.string() }`) or a whole
34
+ * `z.object({ ... })` - the object's `.shape` is unwrapped. The escape hatch
35
+ * for shapes reflection can't express losslessly - discriminated unions,
36
+ * custom validators, `@Transform`, etc. Note it *adds to* the reflected
37
+ * fields; it does not replace them, so a field reflection silently dropped
38
+ * (see the unreflectable-param warning) is not recovered by listing the
39
+ * others here.
35
40
  */
36
- input?: Record<string, z.ZodType>;
41
+ input?: Record<string, z.ZodType> | z.ZodObject;
37
42
  /**
38
43
  * Whether to apply the controller method's parameter-bound pipes
39
44
  * (`@Param('id', ParseIntPipe)`) when re-binding the call. Default `'apply'`.
@@ -75,10 +80,12 @@ interface TrpcMetadata {
75
80
  */
76
81
  description?: string;
77
82
  /**
78
- * Zod raw-shape override merged over the reflected input fields (override wins
79
- * per field). Same escape hatch as `@Mcp({ input })`.
83
+ * Zod override merged over the reflected input fields (override wins per
84
+ * field). Accepts a raw shape (`{ field: z.string() }`) or a whole
85
+ * `z.object({ ... })` (its `.shape` is unwrapped). Same escape hatch as
86
+ * `@Mcp({ input })`.
80
87
  */
81
- input?: Record<string, z.ZodType>;
88
+ input?: Record<string, z.ZodType> | z.ZodObject;
82
89
  /**
83
90
  * Explicit output schema driving the generated procedure's output type - a Zod
84
91
  * type, a DTO class (reflected like `@ApiOkResponse`), or a raw shape (wrapped
@@ -299,7 +306,7 @@ interface RequestLike {
299
306
  * tool `input` (and the request stand-in for `@Req`/`@Headers`/...), then call
300
307
  * it. `applyParamPipes` controls whether parameter-bound pipes run.
301
308
  */
302
- declare function invokeRebound(method: (...args: any[]) => any, instance: object, input: Record<string, unknown>, bindings: Binding[], request: RequestLike | undefined, applyParamPipes: boolean): Promise<unknown>;
309
+ declare function invokeRebound(method: (...args: any[]) => any, instance: object, input: Record<string, unknown>, bindings: Binding[], request: RequestLike | undefined, response: unknown, applyParamPipes: boolean): Promise<unknown>;
303
310
  /** Map a non-input parameter slot (`@Req`/`@Headers`/`@Ip`/...) to its runtime binding. */
304
311
  declare function specialBinding(paramtype: number, data: string | undefined): Binding | null;
305
312
  //#endregion
@@ -342,5 +349,5 @@ declare class SilkweaveModule implements NestModule {
342
349
  configure(_consumer: MiddlewareConsumer): void;
343
350
  }
344
351
  //#endregion
345
- export { Binding, ControllerDiscovery, DiscoverOptions, FieldDesc, MCP_METADATA, Mcp, McpMetadata, NestAdapterRegisterContext, NestSilkweaveAdapter, OpenApiDocument, OpenApiLookup, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, SilkweaveModuleOptions, TRPC_METADATA, Trpc, TrpcKind, TrpcMetadata, apiPropertyToField, buildOpenApiLookup, classValidatorToField, collectGlobalGuards, collectGuards, designTypeToField, fieldToZod, invokeRebound, mergeField, normalizeEnum, openApiFields, openapiSchemaToField, reflectDtoFields, runGuards, specialBinding, swaggerParamToField, typeTokenToBase };
352
+ export { Binding, ControllerDiscovery, DiscoverOptions, FieldDesc, MCP_METADATA, Mcp, McpMetadata, NestAdapterRegisterContext, NestSilkweaveAdapter, OpenApiDocument, OpenApiLookup, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, SilkweaveModuleOptions, TRPC_METADATA, Trpc, TrpcKind, TrpcMetadata, apiPropertyToField, buildOpenApiLookup, classValidatorToField, collectGlobalGuards, collectGuards, designTypeToField, fieldToZod, invokeRebound, mergeField, normalizeEnum, openApiFields, openapiSchemaToField, reflectDtoFields, runGuards, specialBinding, swaggerParamToField, typeTokenToBase, unreflectedFields };
346
353
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/metadata.ts","../src/decorator/mcp.ts","../src/decorator/trpc.ts","../src/lib/controllerDiscovery.ts","../src/lib/guards.ts","../src/lib/rebind.ts","../src/lib/silkweave.module.ts"],"mappings":";;;;;;;;cAIa,YAAA;;cAGA,aAAA;;AAHb;;;;;AAGA;;UAUiB,WAAA;EAVS;;AAU1B;;EAKE,IAAA;EAWc;;;;EANd,WAAA;EAMuB;;;;;EAAvB,KAAA,GAAQ,MAAA,SAAe,CAAA,CAAE,OAAA;EAmBf;;;;;AAYZ;EAxBE,KAAA;;;;;;;;EAQA,MAAA;AAAA;;KAIU,QAAA;;;;;;;;;;;UAYK,YAAA;EAuBa;;;;;EAjB5B,IAAA;EAwBoB;;;;EAnBpB,WAAA;EAgCK;;;;EA3BL,KAAA,GAAQ,MAAA,SAAe,CAAA,CAAE,OAAA;EC5CR;;;;;;EDmDjB,MAAA,GAAS,CAAA,CAAE,OAAA,GAAU,IAAA,GAAO,MAAA,SAAe,CAAA,CAAE,OAAA;ECnDgB;;;;ACA/D;;EF0DE,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,IAAA;EE1D2C;;;;;;;EFkE/D,IAAA,GAAO,QAAA;;AG7DT;;;EHkEE,KAAA;AAAA;;;;;;;;;AAvGF;;;;;AAGA;;;;;AAUA;;;;;;;;;;;;;;AAmCA;;;iBChBgB,GAAA,CAAI,OAAA,GAAS,WAAA,GAAmB,eAAA;;;;;;;;;ADhChD;;;;;AAGA;;;;;AAUA;;;;;;;;;;;;;;AAmCA;;;iBEhBgB,IAAA,CAAK,OAAA,GAAS,YAAA,GAAoB,eAAA;;;UCKjC,eAAA;EACf,OAAA,GAAU,eAAA;EACV,YAAA,GAAe,IAAA,CAAK,WAAA;EACpB,aAAA;AAAA;AAAA,cAIW,mBAAA;EAAA,iBAEQ,SAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;EAAA,iBACA,SAAA;EAAA,iBACA,SAAA;cAJA,SAAA,EAAW,gBAAA,EACX,OAAA,EAAS,eAAA,EACT,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,iBAAA;EH/CN;AAU1B;;;;;;;;;EGkDE,QAAA,CAAS,OAAA,GAAS,eAAA,GAAuB,MAAA;EH3BzC;EAAA,QGyDQ,OAAA;EHjDF;EAAA,QGuEE,WAAA;EHnEE;EAAA,QGsFF,SAAA;;UA8BA,UAAA;AAAA;;;KClKL,QAAA,GAAW,IAAA,CAAK,WAAA,IAAe,WAAA;;;;;AJFpC;;;;;AAGA;;;;;AAUA;;iBIOgB,mBAAA,CACd,SAAA,EAAW,iBAAA,EACX,SAAA,EAAW,IAAA,CAAK,WAAA,MACf,WAAA;;;;;;iBAca,aAAA,CACd,SAAA,EAAW,SAAA,EACX,QAAA,EAAU,IAAA,WACV,OAAA,MAAa,IAAA,0BACZ,QAAA;;;;;;AJOH;;;;;AAYA;;;iBIWsB,SAAA,CACpB,MAAA,EAAQ,QAAA,IACR,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,SAAA,EACX,QAAA,EAAU,IAAA,WACV,OAAA,MAAa,IAAA,yBACb,OAAA,WACA,QAAA,WACA,WAAA,oBACC,OAAA;;;;;;;KC7ES,OAAA;EACN,IAAA;EAAe,KAAA;EAAe,MAAA;EAAmC,QAAA;EAAoB,KAAA;AAAA;EACrF,IAAA;EAAgB,MAAA;EAA0B,MAAA;EAAkB,QAAA;EAAoB,KAAA;AAAA;EAChF,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAiB,IAAA;AAAA;EACjB,IAAA;AAAA;EACA,IAAA;EAAc,IAAA;AAAA;EACd,IAAA;AAAA;AAAA,UAEI,WAAA;EACR,OAAA,GAAU,MAAA;EACV,EAAA;EACA,KAAA,GAAQ,MAAA;AAAA;;;;;;iBAiEY,aAAA,CACpB,MAAA,MAAY,IAAA,iBACZ,QAAA,UACA,KAAA,EAAO,MAAA,mBACP,QAAA,EAAU,OAAA,IACV,OAAA,EAAS,WAAA,cACT,eAAA,YACC,OAAA;;iBASa,cAAA,CAAe,SAAA,UAAmB,IAAA,uBAA2B,OAAA;;;;;;ALlG7E;;;;;AAGA;;;;;AAUA;;;;;;;;;;;;;;AAmCA;;cMhBa,eAAA,YAA2B,UAAA;EAAA,iBAEe,OAAA;EAAA,iBAClC,SAAA;EAAA,iBACA,eAAA;cAFkC,OAAA,EAAS,sBAAA,EAC3C,SAAA,EAAW,mBAAA,EACX,eAAA,EAAiB,eAAA;EAAA,OAG7B,OAAA,CAAQ,OAAA,EAAS,sBAAA,GAAyB,aAAA;EAajD,SAAA,CAAU,SAAA,EAAW,kBAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/metadata.ts","../src/decorator/mcp.ts","../src/decorator/trpc.ts","../src/lib/controllerDiscovery.ts","../src/lib/guards.ts","../src/lib/rebind.ts","../src/lib/silkweave.module.ts"],"mappings":";;;;;;;;cAIa,YAAA;;cAGA,aAAA;;AAHb;;;;;AAGA;;UAUiB,WAAA;EAVS;;AAU1B;;EAKE,IAAA;EAgByB;;;;EAXzB,WAAA;EALA;;;;;;;;;;EAgBA,KAAA,GAAQ,MAAA,SAAe,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,SAAA;EAehC;AAIR;;;;;EAZE,KAAA;EAwB2B;;;;;;;EAhB3B,MAAA;AAAA;;KAIU,QAAA;;;;;;;;;;;UAYK,YAAA;EAyBf;;;;;EAnBA,IAAA;EAmB6C;;;;EAd7C,WAAA;EA6BA;;;;;;EAtBA,KAAA,GAAQ,MAAA,SAAe,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,SAAA;;ACnDxC;;;;;ED0DE,MAAA,GAAS,CAAA,CAAE,OAAA,GAAU,IAAA,GAAO,MAAA,SAAe,CAAA,CAAE,OAAA;EC1DC;;;;;;EDiE9C,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,IAAA;EEjEF;;;;;;;EFyElB,IAAA,GAAO,QAAA;;;;AG/DT;EHoEE,KAAA;AAAA;;;;;;;;;AA9GF;;;;;AAGA;;;;;AAUA;;;;;;;;;;;;;;;;;iBCmBgB,GAAA,CAAI,OAAA,GAAS,WAAA,GAAmB,eAAA;;;;;;;;;ADhChD;;;;;AAGA;;;;;AAUA;;;;;;;;;;;;;;;;;iBEmBgB,IAAA,CAAK,OAAA,GAAS,YAAA,GAAoB,eAAA;;;UCUjC,eAAA;EACf,OAAA,GAAU,eAAA;EACV,YAAA,GAAe,IAAA,CAAK,WAAA;EACpB,aAAA;AAAA;AAAA,cAIW,mBAAA;EAAA,iBAEQ,SAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;EAAA,iBACA,SAAA;EAAA,iBACA,SAAA;cAJA,SAAA,EAAW,gBAAA,EACX,OAAA,EAAS,eAAA,EACT,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,iBAAA;EHpDN;AAU1B;;;;;;;;;EGuDE,QAAA,CAAS,OAAA,GAAS,eAAA,GAAuB,MAAA;EHlCzC;EAAA,QGgEQ,OAAA;EHhEe;EAAA,QGuFf,WAAA;EHvF4B;EAAA,QG0G5B,SAAA;EHnGR;EAAA,QGkIQ,UAAA;AAAA;;;KCzKL,QAAA,GAAW,IAAA,CAAK,WAAA,IAAe,WAAA;;;;;AJFpC;;;;;AAGA;;;;;AAUA;;iBIOgB,mBAAA,CACd,SAAA,EAAW,iBAAA,EACX,SAAA,EAAW,IAAA,CAAK,WAAA,MACf,WAAA;;;;;;iBAca,aAAA,CACd,SAAA,EAAW,SAAA,EACX,QAAA,EAAU,IAAA,WACV,OAAA,MAAa,IAAA,0BACZ,QAAA;;;;;;;;;;;;AJYH;;iBIkBsB,SAAA,CACpB,MAAA,EAAQ,QAAA,IACR,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,SAAA,EACX,QAAA,EAAU,IAAA,WACV,OAAA,MAAa,IAAA,yBACb,OAAA,WACA,QAAA,WACA,WAAA,oBACC,OAAA;;;;;;;KC7ES,OAAA;EACN,IAAA;EAAe,KAAA;EAAe,MAAA;EAAmC,QAAA;EAAoB,KAAA;AAAA;EACrF,IAAA;EAAgB,MAAA;EAA0B,MAAA;EAAkB,QAAA;EAAoB,KAAA;AAAA;EAChF,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAiB,IAAA;AAAA;EACjB,IAAA;AAAA;EACA,IAAA;EAAc,IAAA;AAAA;EACd,IAAA;AAAA;AAAA,UAEI,WAAA;EACR,OAAA,GAAU,MAAA;EACV,EAAA;EACA,KAAA,GAAQ,MAAA;AAAA;;;;ALgDV;;iBKsBsB,aAAA,CACpB,MAAA,MAAY,IAAA,iBACZ,QAAA,UACA,KAAA,EAAO,MAAA,mBACP,QAAA,EAAU,OAAA,IACV,OAAA,EAAS,WAAA,cACT,QAAA,WACA,eAAA,YACC,OAAA;;iBASa,cAAA,CAAe,SAAA,UAAmB,IAAA,uBAA2B,OAAA;;;;;;ALxG7E;;;;;AAGA;;;;;AAUA;;;;;;;;;;;;;;;;cMmBa,eAAA,YAA2B,UAAA;EAAA,iBAEe,OAAA;EAAA,iBAClC,SAAA;EAAA,iBACA,eAAA;cAFkC,OAAA,EAAS,sBAAA,EAC3C,SAAA,EAAW,mBAAA,EACX,eAAA,EAAiB,eAAA;EAAA,OAG7B,OAAA,CAAQ,OAAA,EAAS,sBAAA,GAAyB,aAAA;EAajD,SAAA,CAAU,SAAA,EAAW,kBAAA;AAAA"}
package/build/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
- import { ForbiddenException, HttpException, Inject, Injectable, Module, SetMetadata } from "@nestjs/common";
2
+ import { ForbiddenException, HttpException, Inject, Injectable, Logger, Module, SetMetadata } from "@nestjs/common";
3
3
  import { ApplicationConfig, DiscoveryModule, DiscoveryService, HttpAdapterHost, MetadataScanner, ModuleRef, Reflector } from "@nestjs/core";
4
4
  import { SilkweaveError, createContext } from "@silkweave/core";
5
5
  import { z } from "zod/v4";
@@ -273,7 +273,7 @@ function pickFields(input, fields) {
273
273
  return obj;
274
274
  }
275
275
  /** Resolve a single positional argument from one binding. */
276
- async function resolveArg(b, input, request, applyParamPipes) {
276
+ async function resolveArg(b, input, request, response, applyParamPipes) {
277
277
  switch (b.kind) {
278
278
  case "value": {
279
279
  const raw = input[b.field];
@@ -287,6 +287,7 @@ async function resolveArg(b, input, request, applyParamPipes) {
287
287
  case "params": return pickFields(input, b.fields);
288
288
  case "headers": return b.data ? request?.headers?.[b.data.toLowerCase()] : request?.headers ?? {};
289
289
  case "request": return request ?? { headers: {} };
290
+ case "response": return response;
290
291
  case "ip": return request?.ip;
291
292
  case "host": return b.data ? request?.hosts?.[b.data] : request?.hosts;
292
293
  default: return;
@@ -297,9 +298,9 @@ async function resolveArg(b, input, request, applyParamPipes) {
297
298
  * tool `input` (and the request stand-in for `@Req`/`@Headers`/...), then call
298
299
  * it. `applyParamPipes` controls whether parameter-bound pipes run.
299
300
  */
300
- async function invokeRebound(method, instance, input, bindings, request, applyParamPipes) {
301
+ async function invokeRebound(method, instance, input, bindings, request, response, applyParamPipes) {
301
302
  const args = [];
302
- for (let i = 0; i < bindings.length; i += 1) args[i] = await resolveArg(bindings[i], input, request, applyParamPipes);
303
+ for (let i = 0; i < bindings.length; i += 1) args[i] = await resolveArg(bindings[i], input, request, response, applyParamPipes);
303
304
  return await method.apply(instance, args);
304
305
  }
305
306
  /** Map a non-input parameter slot (`@Req`/`@Headers`/`@Ip`/...) to its runtime binding. */
@@ -425,6 +426,7 @@ function baseToZod(d) {
425
426
  function fieldToZod(d) {
426
427
  let schema = d.enum?.length ? enumToZod(d.enum) : baseToZod(d);
427
428
  if (d.description) schema = schema.describe(d.description);
429
+ if (d.nullable) schema = schema.nullable();
428
430
  if (d.default !== void 0) schema = schema.default(d.default);
429
431
  else if (d.required === false) schema = schema.optional();
430
432
  return schema;
@@ -486,6 +488,7 @@ function apiPropertyToField(o) {
486
488
  if (o["minLength"] != null) f.minLength = o["minLength"];
487
489
  if (o["maxLength"] != null) f.maxLength = o["maxLength"];
488
490
  if (o["format"]) f.format = o["format"];
491
+ if (o["nullable"] === true) f.nullable = true;
489
492
  if (o["default"] !== void 0) f.default = o["default"];
490
493
  return f;
491
494
  }
@@ -561,6 +564,7 @@ function openapiSchemaToField(schema) {
561
564
  if (schema["minLength"] != null) f.minLength = schema["minLength"];
562
565
  if (schema["maxLength"] != null) f.maxLength = schema["maxLength"];
563
566
  if (schema["format"]) f.format = schema["format"];
567
+ if (schema["nullable"] === true) f.nullable = true;
564
568
  if (schema["default"] !== void 0) f.default = schema["default"];
565
569
  if (schema["items"] && typeof schema["items"] === "object") f.items = openapiSchemaToField(schema["items"]);
566
570
  return f;
@@ -595,6 +599,22 @@ function reflectDtoFields(dtoType) {
595
599
  }
596
600
  return out;
597
601
  }
602
+ /**
603
+ * Names of fields that could not be reflected into a concrete type - they will
604
+ * become `z.unknown()` (or `z.array(z.unknown())`). This is how a nested DTO or a
605
+ * `Dto[]` property silently degrades (reflection is one level deep), so the
606
+ * adapters surface these as a build-time warning pointing at `@Trpc({ output })`
607
+ * / `@Mcp({ input })`. Enum and `object` (record) fields are not degraded.
608
+ */
609
+ function unreflectedFields(fields) {
610
+ const out = [];
611
+ for (const [name, f] of Object.entries(fields)) {
612
+ if (f.enum?.length) continue;
613
+ if (!f.type || f.type === "unknown") out.push(name);
614
+ else if (f.type === "array" && (!f.items?.type || f.items.type === "unknown")) out.push(name);
615
+ }
616
+ return out;
617
+ }
598
618
  //#endregion
599
619
  //#region src/lib/reflect/openapi.ts
600
620
  /** Index a document's operations by `${METHOD} ${path}` for fast matching. */
@@ -669,6 +689,13 @@ const SUCCESS_KEYS = [
669
689
  "2XX",
670
690
  "default"
671
691
  ];
692
+ /** The 2xx (or first) `@ApiResponse` entry for a method, if any. */
693
+ function successEntry(method) {
694
+ const responses = Reflect.getMetadata(API_RESPONSE, method);
695
+ if (!responses) return;
696
+ const key = SUCCESS_KEYS.find((k) => responses[k]) ?? Object.keys(responses)[0];
697
+ return key ? responses[key] : void 0;
698
+ }
672
699
  /**
673
700
  * Reflect a `@Trpc` procedure's output schema from the method's
674
701
  * `@ApiOkResponse({ type: Dto })` (or any 2xx `@ApiResponse`) metadata. The
@@ -680,10 +707,7 @@ const SUCCESS_KEYS = [
680
707
  * explicit `@Trpc({ output })` or an `unknown` output type.
681
708
  */
682
709
  function reflectResponseSchema(method) {
683
- const responses = Reflect.getMetadata(API_RESPONSE, method);
684
- if (!responses) return;
685
- const key = SUCCESS_KEYS.find((k) => responses[k]) ?? Object.keys(responses)[0];
686
- const entry = key ? responses[key] : void 0;
710
+ const entry = successEntry(method);
687
711
  const dtoType = entry?.type;
688
712
  if (typeof dtoType !== "function") return;
689
713
  const schema = reflectDtoSchema(dtoType);
@@ -691,6 +715,17 @@ function reflectResponseSchema(method) {
691
715
  return entry?.isArray ? z.array(schema) : schema;
692
716
  }
693
717
  /**
718
+ * The reflected `FieldDesc` map for a method's response DTO (the same fields
719
+ * {@link reflectResponseSchema} builds its schema from), or `undefined` when
720
+ * there is no DTO to reflect. Used to detect fields that degraded to `unknown`
721
+ * (nested DTO / `Dto[]`) so the caller can warn.
722
+ */
723
+ function reflectResponseFields(method) {
724
+ const dtoType = successEntry(method)?.type;
725
+ if (typeof dtoType !== "function") return;
726
+ return reflectDtoFields(dtoType);
727
+ }
728
+ /**
694
729
  * Reflect a DTO class (its `@ApiProperty`/`class-validator`-decorated properties)
695
730
  * into a Zod object schema. Returns `undefined` when the type isn't a class or
696
731
  * has no reflectable properties. Used for `@Trpc({ output })`/`@Trpc({ chunk })`
@@ -789,6 +824,8 @@ function __decorate(decorators, target, key, desc) {
789
824
  //#endregion
790
825
  //#region src/lib/controllerDiscovery.ts
791
826
  var _ref$1, _ref2$1, _ref3, _ref4, _ref5;
827
+ /** Discovery-time diagnostics (unreflectable params, degraded outputs). */
828
+ const logger = new Logger("Silkweave");
792
829
  let ControllerDiscovery = class ControllerDiscovery {
793
830
  constructor(discovery, scanner, reflector, moduleRef, appConfig) {
794
831
  this.discovery = discovery;
@@ -848,7 +885,8 @@ let ControllerDiscovery = class ControllerDiscovery {
848
885
  const slots = readParamSlots(d.classRef, d.methodName, proto);
849
886
  const operation = reflectOperation(d.method);
850
887
  const docFields = lookup ? openApiFields(lookup, route.method, route.openapiPath) : {};
851
- const { shape, bindings } = buildInput(proto, d.methodName, route.pathParams, slots, operation.params, docFields);
888
+ const { shape, bindings, warnings } = buildInput(proto, d.methodName, route.pathParams, slots, operation.params, docFields);
889
+ for (const w of warnings) logger.warn(`${d.classRef.name}.${d.methodName}: ${w}`);
852
890
  return {
853
891
  route,
854
892
  base: d.classRef.name.replace(/Controller$/, ""),
@@ -885,7 +923,7 @@ let ControllerDiscovery = class ControllerDiscovery {
885
923
  const meta = d.mcp;
886
924
  const shape = {
887
925
  ...shared.baseShape,
888
- ...meta.input ?? {}
926
+ ...inputShape(meta.input)
889
927
  };
890
928
  const name = meta.name ?? `${shared.base}.${d.methodName}`;
891
929
  const description = meta.description ?? shared.description ?? `${d.methodName} (${shared.route.method} /${shared.route.path})`;
@@ -904,7 +942,7 @@ let ControllerDiscovery = class ControllerDiscovery {
904
942
  run: streamingRun(applyGuards, method, instance, bindings, applyParamPipes, false)
905
943
  } : { run: async (input, context) => {
906
944
  await applyGuards(context, input);
907
- return await invokeRebound(method, instance, input, bindings, context.getOptional("request"), applyParamPipes) ?? {};
945
+ return await invokeRebound(method, instance, input, bindings, context.getOptional("request"), context.getOptional("response"), applyParamPipes) ?? {};
908
946
  } }
909
947
  };
910
948
  }
@@ -913,7 +951,7 @@ let ControllerDiscovery = class ControllerDiscovery {
913
951
  const meta = d.trpc;
914
952
  const shape = {
915
953
  ...shared.baseShape,
916
- ...meta.input ?? {}
954
+ ...inputShape(meta.input)
917
955
  };
918
956
  const name = meta.name ?? `${shared.base}.${d.methodName}`;
919
957
  const description = meta.description ?? shared.description ?? `${d.methodName} (${shared.route.method} /${shared.route.path})`;
@@ -935,6 +973,8 @@ let ControllerDiscovery = class ControllerDiscovery {
935
973
  };
936
974
  const kind = meta.kind === "query" || meta.kind === "mutation" ? meta.kind : shared.route.method === "GET" ? "query" : "mutation";
937
975
  const output = resolveOutput(meta, method);
976
+ const degraded = outputDegradedFields(meta, method);
977
+ if (output && degraded.length > 0) logger.warn(`${d.classRef.name}.${d.methodName}: tRPC output field(s) ${degraded.join(", ")} reflected to 'unknown' (nested DTO or Dto[] - reflection is one level deep). Supply @Trpc({ output }) with a Zod schema for precise types.`);
938
978
  return {
939
979
  name,
940
980
  description,
@@ -945,7 +985,7 @@ let ControllerDiscovery = class ControllerDiscovery {
945
985
  run: async (input, context) => {
946
986
  try {
947
987
  await applyGuards(context, input);
948
- return await invokeRebound(method, instance, input, bindings, context.getOptional("request"), applyParamPipes) ?? {};
988
+ return await invokeRebound(method, instance, input, bindings, context.getOptional("request"), context.getOptional("response"), applyParamPipes) ?? {};
949
989
  } catch (error) {
950
990
  throw toSilkweaveError(error);
951
991
  }
@@ -965,7 +1005,7 @@ function streamingRun(applyGuards, method, instance, bindings, applyParamPipes,
965
1005
  return async function* (input, context) {
966
1006
  try {
967
1007
  await applyGuards(context, input);
968
- const gen = await invokeRebound(method, instance, input, bindings, context.getOptional("request"), applyParamPipes);
1008
+ const gen = await invokeRebound(method, instance, input, bindings, context.getOptional("request"), context.getOptional("response"), applyParamPipes);
969
1009
  for await (const chunk of gen) yield chunk;
970
1010
  } catch (error) {
971
1011
  throw mapErrors ? toSilkweaveError(error) : error;
@@ -977,6 +1017,27 @@ function resolveOutput(meta, method) {
977
1017
  return resolveSchema(meta.output) ?? reflectResponseSchema(method);
978
1018
  }
979
1019
  /**
1020
+ * Output field names that reflected to `unknown` (nested DTO / `Dto[]`). Only the
1021
+ * reflected paths are inspected - an explicit Zod or raw-shape `@Trpc({ output })`
1022
+ * is the caller's own typing and is never flagged.
1023
+ */
1024
+ function outputDegradedFields(meta, method) {
1025
+ if (meta.output != null && isZodSchema(meta.output)) return [];
1026
+ const fields = typeof meta.output === "function" ? reflectDtoFields(meta.output) : meta.output != null ? void 0 : reflectResponseFields(method);
1027
+ return fields ? unreflectedFields(fields) : [];
1028
+ }
1029
+ /**
1030
+ * Normalise an `@Mcp`/`@Trpc({ input })` override to a raw Zod shape. Accepts a
1031
+ * plain `Record<string, ZodType>` or a whole `z.object({ ... })` (duck-typed by
1032
+ * `safeParse` + `shape`, so a different zod copy's object still unwraps).
1033
+ */
1034
+ function inputShape(input) {
1035
+ if (!input) return {};
1036
+ const maybe = input;
1037
+ if (typeof maybe.safeParse === "function" && maybe.shape != null && typeof maybe.shape === "object") return maybe.shape;
1038
+ return input;
1039
+ }
1040
+ /**
980
1041
  * Coerce an `output`/`chunk` override to a Zod schema: a Zod schema passes
981
1042
  * through, a DTO class is reflected, and a raw shape is wrapped in `z.object`.
982
1043
  */
@@ -1011,6 +1072,7 @@ function toSilkweaveError(error) {
1011
1072
  function buildInput(proto, methodName, pathParams, slots, operationParams, docFields) {
1012
1073
  const designTypes = Reflect.getMetadata("design:paramtypes", proto, methodName) ?? [];
1013
1074
  const fields = {};
1075
+ const warnings = [];
1014
1076
  const maxIndex = slots.reduce((m, s) => Math.max(m, s.index), -1);
1015
1077
  const bindings = Array.from({ length: maxIndex + 1 }, () => ({ kind: "missing" }));
1016
1078
  const addField = (name, desc) => {
@@ -1020,6 +1082,10 @@ function buildInput(proto, methodName, pathParams, slots, operationParams, docFi
1020
1082
  const { binding, fields: contributed } = contributeSlot(slot, pathParams, designTypes);
1021
1083
  bindings[slot.index] = binding;
1022
1084
  for (const [name, desc] of Object.entries(contributed)) addField(name, desc);
1085
+ if (binding.kind === "object" && binding.fields.length === 0) {
1086
+ const typeName = designTypes[slot.index]?.name ?? "unknown";
1087
+ warnings.push(`whole-${binding.source} parameter #${slot.index} (type '${typeName}') reflected no input fields. If it is an intersection/union (e.g. 'A & B'), TypeScript erases it to '${typeName}' so the DTO is lost - use a single DTO class or declare the fields via @Mcp/@Trpc({ input }).`);
1088
+ }
1023
1089
  }
1024
1090
  for (const [name, desc] of Object.entries(operationParams)) if (name in fields) fields[name] = mergeField(fields[name], desc);
1025
1091
  for (const [name, desc] of Object.entries(docFields)) if (name in fields) fields[name] = mergeField(fields[name], desc);
@@ -1027,7 +1093,8 @@ function buildInput(proto, methodName, pathParams, slots, operationParams, docFi
1027
1093
  for (const [name, desc] of Object.entries(fields)) shape[name] = fieldToZod(desc);
1028
1094
  return {
1029
1095
  shape,
1030
- bindings
1096
+ bindings,
1097
+ warnings
1031
1098
  };
1032
1099
  }
1033
1100
  /** Input field names that originate from the URL path (`@Param`), per the re-bind plan. */
@@ -1182,6 +1249,6 @@ SilkweaveModule = _SilkweaveModule = __decorate([
1182
1249
  ])
1183
1250
  ], SilkweaveModule);
1184
1251
  //#endregion
1185
- export { ControllerDiscovery, MCP_METADATA, Mcp, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, TRPC_METADATA, Trpc, apiPropertyToField, buildOpenApiLookup, classValidatorToField, collectGlobalGuards, collectGuards, designTypeToField, fieldToZod, invokeRebound, mergeField, normalizeEnum, openApiFields, openapiSchemaToField, reflectDtoFields, runGuards, specialBinding, swaggerParamToField, typeTokenToBase };
1252
+ export { ControllerDiscovery, MCP_METADATA, Mcp, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, TRPC_METADATA, Trpc, apiPropertyToField, buildOpenApiLookup, classValidatorToField, collectGlobalGuards, collectGuards, designTypeToField, fieldToZod, invokeRebound, mergeField, normalizeEnum, openApiFields, openapiSchemaToField, reflectDtoFields, runGuards, specialBinding, swaggerParamToField, typeTokenToBase, unreflectedFields };
1186
1253
 
1187
1254
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/metadata.ts","../src/decorator/mcp.ts","../src/decorator/trpc.ts","../src/lib/executionContext.ts","../src/lib/guards.ts","../src/lib/reflect/params.ts","../src/lib/rebind.ts","../src/lib/reflect/classValidator.ts","../src/lib/reflect/schema.ts","../src/lib/reflect/openapi.ts","../src/lib/reflect/response.ts","../src/lib/reflect/route.ts","../src/lib/reflect/swagger.ts","../src/lib/controllerDiscovery.ts","../src/lib/types.ts","../src/lib/silkweave.module.ts"],"sourcesContent":["import type { Type } from '@nestjs/common'\nimport type { z } from 'zod/v4'\n\n/** Reflect-metadata key carrying `@Mcp` options on a controller method. */\nexport const MCP_METADATA = '__silkweave_mcp__'\n\n/** Reflect-metadata key carrying `@Trpc` options on a controller method. */\nexport const TRPC_METADATA = '__silkweave_trpc__'\n\n/**\n * Options for the `@Mcp()` method decorator. Every field is optional - an empty\n * `@Mcp()` exposes the decorated controller route as an MCP tool with its name,\n * description, and input schema fully reflected from the method's route\n * (`@Get`/`@Post`/...), parameter decorators (`@Param`/`@Query`/`@Body`), and\n * any `@nestjs/swagger` (`@ApiOperation`/`@ApiParam`/`@ApiProperty`) or\n * `class-validator` metadata it carries.\n */\nexport interface McpMetadata {\n /**\n * MCP tool name override. When unset it is derived from the controller class\n * and method name (e.g. `ChannelsController.findOne` → `ChannelsFindOne`).\n */\n name?: string\n /**\n * Tool description override. When unset it falls back to the method's\n * `@ApiOperation({ summary | description })`, then a generated default.\n */\n description?: string\n /**\n * Zod raw-shape override merged over the reflected input fields (override\n * wins per field). The escape hatch for shapes reflection can't express\n * losslessly - discriminated unions, custom validators, `@Transform`, etc.\n */\n input?: Record<string, z.ZodType>\n /**\n * Whether to apply the controller method's parameter-bound pipes\n * (`@Param('id', ParseIntPipe)`) when re-binding the call. Default `'apply'`.\n * Global/`ValidationPipe`, interceptors, and exception filters never run -\n * the method is invoked directly, not through Nest's HTTP request pipeline.\n */\n pipes?: 'apply' | 'skip'\n /**\n * Default MCP result format for this tool. `'json'` returns compact JSON text\n * (`jsonToolResult`); `'smart'` (the default when unset) inlines small\n * payloads and offloads large ones to an embedded resource (`smartToolResult`).\n * This is only a default - a client that sends `_meta.disposition` on the tool\n * call overrides it.\n */\n result?: 'json' | 'smart'\n}\n\n/** tRPC procedure kind for a `@Trpc`-decorated route. */\nexport type TrpcKind = 'query' | 'mutation' | 'subscription'\n\n/**\n * Options for the `@Trpc()` method decorator - the tRPC sibling of `@Mcp`. An\n * empty `@Trpc()` exposes the decorated controller route as a tRPC procedure\n * with its key, input schema, and kind reflected from the route + parameter\n * decorators + swagger/class-validator metadata (identically to `@Mcp`).\n *\n * Unlike MCP, tRPC carries precise *output* types into the generated router, so\n * `@Trpc` adds an `output`/`chunk` hatch and a `kind` override on top of the\n * shared reflection. The two decorators compose on the same method.\n */\nexport interface TrpcMetadata {\n /**\n * Procedure-name override (before camelCasing). When unset it is derived from\n * the controller class + method name (e.g. `UsersController.listBySpace` →\n * `Users.listBySpace`, camelCased by the router to `usersListBySpace`).\n */\n name?: string\n /**\n * Procedure description override. When unset it falls back to the method's\n * `@ApiOperation({ summary | description })`, then a generated default.\n */\n description?: string\n /**\n * Zod raw-shape override merged over the reflected input fields (override wins\n * per field). Same escape hatch as `@Mcp({ input })`.\n */\n input?: Record<string, z.ZodType>\n /**\n * Explicit output schema driving the generated procedure's output type - a Zod\n * type, a DTO class (reflected like `@ApiOkResponse`), or a raw shape (wrapped\n * in `z.object`). Wins over `@ApiOkResponse` reflection. The biggest reason to\n * set this is when the return shape can't be reflected losslessly from a DTO.\n */\n output?: z.ZodType | Type | Record<string, z.ZodType>\n /**\n * Chunk schema for an async-generator route exposed as a tRPC **subscription**.\n * A Zod type or a DTO class. Drives the emitted\n * `TRPCSubscriptionProcedure<{ output }>` type. When unset the chunk type falls\n * back to `unknown`.\n */\n chunk?: z.ZodType | Type\n /**\n * Procedure kind. When unset it is inferred: an `async *` route ⇒\n * `'subscription'`, a `@Get` route ⇒ `'query'`, anything else ⇒ `'mutation'`.\n * Set this to expose a verb-less route (no `@Get`/`@Post`) as a query or\n * subscription - `@Trpc({ kind })` works without an HTTP-verb decorator, so the\n * route is served over tRPC (and/or MCP) without becoming a public REST route.\n */\n kind?: TrpcKind\n /**\n * Whether to apply the method's parameter-bound pipes when re-binding the call.\n * Default `'apply'`. Same semantics as `@Mcp({ pipes })`.\n */\n pipes?: 'apply' | 'skip'\n}\n","import { SetMetadata } from '@nestjs/common'\nimport { MCP_METADATA, type McpMetadata } from '../lib/metadata.js'\n\n/**\n * Method decorator that exposes an existing NestJS controller route as an MCP\n * tool. It is **additive** - the route keeps serving HTTP exactly as before;\n * `@Mcp()` just opts the method into MCP discovery.\n *\n * The tool's name, description, and input schema are reflected from the\n * method's own metadata:\n * - **fields** from the parameter decorators (`@Param`/`@Query`/`@Body`) - a\n * `@Param('id')` becomes an `id` field; a whole-DTO `@Body() dto: CreateDto`\n * is flattened to its properties,\n * - **types/constraints/descriptions** from `@nestjs/swagger`\n * (`@ApiParam`/`@ApiQuery`/`@ApiProperty`/`@ApiOperation`) and, when present,\n * `class-validator` decorators on the DTOs,\n * - optionally refined by an OpenAPI document passed to `SilkweaveModule`.\n *\n * On a tool call the input is split back into the method's positional arguments\n * and the method is invoked directly (with `@UseGuards` guards applied first).\n *\n * @example\n * ```ts\n * @Controller('sessions/:sessionId/channels')\n * export class ChannelsController {\n * @Get(':channelId')\n * @ApiOperation({ summary: 'Get a specific channel by ID' })\n * @ApiParam({ name: 'sessionId', description: 'Session ID' })\n * @ApiParam({ name: 'channelId', description: 'Channel ID' })\n * @Mcp()\n * findOne(@Param('sessionId') sessionId: string, @Param('channelId') channelId: string) {\n * return this.service.get(sessionId, channelId)\n * }\n * }\n * ```\n */\nexport function Mcp(options: McpMetadata = {}): MethodDecorator {\n return SetMetadata(MCP_METADATA, options)\n}\n","import { SetMetadata } from '@nestjs/common'\nimport { TRPC_METADATA, type TrpcMetadata } from '../lib/metadata.js'\n\n/**\n * Method decorator that exposes a NestJS controller route as a **tRPC\n * procedure** - the sibling of `@Mcp`. Like `@Mcp` it is additive and reflects\n * the procedure's input from the method's own metadata (route + `@Param`/\n * `@Query`/`@Body` + swagger/class-validator), so a single method can carry both\n * `@Trpc()` and `@Mcp()` and `@UseGuards()`.\n *\n * Two things differ from MCP because tRPC consumers need them:\n * - **kind** - inferred from the route (`@Get` ⇒ query, others ⇒ mutation) or an\n * `async *` body (⇒ subscription); override with `@Trpc({ kind })`.\n * - **output** - the generated `AppRouter` carries precise output types. Drive\n * them with `@ApiOkResponse({ type: Dto })` reflection or `@Trpc({ output })`.\n *\n * `@Trpc()` works **without** an HTTP-verb decorator: with no `@Get`/`@Post` the\n * route is never mapped as REST, so `@Trpc({ kind })` exposes it over tRPC (and\n * `@Mcp` over MCP) while keeping it off the public REST surface.\n *\n * @example\n * ```ts\n * @Controller('users')\n * export class UsersController {\n * @Get('list-by-space')\n * @ApiOperation({ summary: 'List users in a space' })\n * @ApiOkResponse({ type: ListUsersResponse }) // drives the output type\n * @UseGuards(AuthGuard)\n * @Trpc() // → procedure `usersListBySpace` (query)\n * @Mcp() // → MCP tool `UsersListBySpace`\n * listBySpace(@Query() q: ListBySpaceQuery, @Req() req: AppRequest) {\n * return this.service.list(req.user, q.spaceId)\n * }\n * }\n * ```\n */\nexport function Trpc(options: TrpcMetadata = {}): MethodDecorator {\n return SetMetadata(TRPC_METADATA, options)\n}\n","import type { ArgumentsHost, ContextType, ExecutionContext, Type } from '@nestjs/common'\n\n/** Subset of `HttpArgumentsHost` we need - re-declared inline to avoid deep `@nestjs/common/interfaces` imports. */\ninterface HttpHost {\n getRequest<T = unknown>(): T\n getResponse<T = unknown>(): T\n getNext<T = unknown>(): T\n}\n\ninterface RpcHost {\n getData<T = unknown>(): T\n getContext<T = unknown>(): T\n}\n\ninterface WsHost {\n getClient<T = unknown>(): T\n getData<T = unknown>(): T\n getPattern(): string\n}\n\n/**\n * Minimal `ExecutionContext` impl Nest guards can consume. We only need\n * `switchToHttp()` to work for our HTTP-backed transports; the RPC/WS shims are\n * stubbed so guards that introspect type can still call them without crashing.\n */\nexport class SilkweaveExecutionContext implements ExecutionContext, ArgumentsHost {\n constructor(\n private readonly args: unknown[],\n private readonly classRef: Type<unknown>,\n private readonly handler: (...handlerArgs: unknown[]) => unknown,\n private readonly contextType = 'http'\n ) { }\n\n getType<T extends string = ContextType>(): T {\n return this.contextType as T\n }\n\n getClass<T = unknown>(): Type<T> {\n return this.classRef as Type<T>\n }\n\n getHandler(): (...handlerArgs: unknown[]) => unknown {\n return this.handler\n }\n\n getArgs<T extends unknown[] = unknown[]>(): T {\n return this.args as T\n }\n\n getArgByIndex<T = unknown>(index: number): T {\n return this.args[index] as T\n }\n\n switchToHttp(): HttpHost {\n return {\n getRequest: <T = unknown>(): T => this.args[0] as T,\n getResponse: <T = unknown>(): T => this.args[1] as T,\n getNext: <T = unknown>(): T => this.args[2] as T\n }\n }\n\n switchToRpc(): RpcHost {\n return {\n getData: <T = unknown>(): T => this.args[0] as T,\n getContext: <T = unknown>(): T => this.args[1] as T\n }\n }\n\n switchToWs(): WsHost {\n return {\n getClient: <T = unknown>(): T => this.args[0] as T,\n getData: <T = unknown>(): T => this.args[1] as T,\n getPattern: (): string => ''\n }\n }\n}\n","import { ForbiddenException, type CanActivate, type Type } from '@nestjs/common'\nimport { GUARDS_METADATA } from '@nestjs/common/constants.js'\nimport { ApplicationConfig, ModuleRef, Reflector } from '@nestjs/core'\nimport { isObservable, lastValueFrom } from 'rxjs'\nimport { SilkweaveExecutionContext } from './executionContext.js'\n\ntype GuardRef = Type<CanActivate> | CanActivate\n\n/**\n * Collect the app's global guards that match an opt-in allow-list of classes.\n *\n * Reads both registration styles Nest exposes via `ApplicationConfig`:\n * `useGlobalGuards(new X())` instances (`getGlobalGuards()`) and\n * `{ provide: APP_GUARD, useClass }` DI guards (`getGlobalRequestGuards()`,\n * which yields `InstanceWrapper`s - we read `.instance` off each).\n *\n * The allow-list is intentionally explicit-by-class: a blanket \"run every\n * global\" would also fire unrelated globals (e.g. a `ThrottlerGuard` that\n * assumes a writable response) on every tool call. An empty allow-list runs\n * no globals, preserving the prior behavior.\n *\n * Call this at tool-call time, not at discovery time: `APP_GUARD` instances\n * aren't populated until `app.init()` finishes.\n */\nexport function collectGlobalGuards(\n appConfig: ApplicationConfig,\n allowList: Type<CanActivate>[]\n): CanActivate[] {\n if (allowList.length === 0) { return [] }\n const globals: CanActivate[] = [\n ...appConfig.getGlobalGuards(),\n ...appConfig.getGlobalRequestGuards().map((w) => w.instance)\n ].filter((g): g is CanActivate => g != null)\n return globals.filter((g) => allowList.some((c) => g instanceof c))\n}\n\n/**\n * Read `@UseGuards(...)` metadata for both the method and its class and merge\n * the two lists. Method-level guards run AFTER class-level guards (matching\n * Nest's own behavior).\n */\nexport function collectGuards(\n reflector: Reflector,\n classRef: Type<unknown>,\n handler: (...args: unknown[]) => unknown\n): GuardRef[] {\n const classGuards = reflector.get<GuardRef[]>(GUARDS_METADATA, classRef) ?? []\n const methodGuards = reflector.get<GuardRef[]>(GUARDS_METADATA, handler) ?? []\n return [...classGuards, ...methodGuards]\n}\n\nasync function resolveGuard(ref: GuardRef, moduleRef: ModuleRef): Promise<CanActivate> {\n if (typeof ref === 'function') {\n try {\n return await moduleRef.get(ref, { strict: false })\n } catch {\n return moduleRef.create(ref)\n }\n }\n return ref\n}\n\n/**\n * Run the configured guards against a request. Throws `ForbiddenException`\n * if any guard rejects, mirroring Nest's HTTP request-pipeline behavior.\n *\n * Pass `null` for `response` when running on top of a tRPC or MCP request that\n * doesn't surface a raw response object; guards that introspect the response\n * will receive `null`.\n *\n * `contextType` is reflected through `ExecutionContext.getType()` so guards can\n * branch on the transport. It is `'http'` for REST/tRPC and for MCP-over-HTTP\n * (where a header-bearing request stand-in is available); transports without any\n * HTTP request (e.g. MCP stdio) pass `'rpc'`.\n */\nexport async function runGuards(\n guards: GuardRef[],\n moduleRef: ModuleRef,\n reflector: Reflector,\n classRef: Type<unknown>,\n handler: (...args: unknown[]) => unknown,\n request: unknown,\n response: unknown,\n contextType: 'http' | 'rpc' = 'http'\n): Promise<void> {\n if (guards.length === 0) { return }\n const context = new SilkweaveExecutionContext([request, response], classRef, handler, contextType)\n for (const ref of guards) {\n const guard = await resolveGuard(ref, moduleRef)\n const result = guard.canActivate(context)\n const allowed = isObservable(result) ? await lastValueFrom(result) : await Promise.resolve(result)\n if (!allowed) {\n throw new ForbiddenException('Forbidden resource')\n }\n }\n // Reflector kept in the signature for future use (e.g., per-guard metadata) - unused here.\n void reflector\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { ROUTE_ARGS_METADATA } from '@nestjs/common/constants.js'\n\n/**\n * `RouteParamtypes` numeric values from `@nestjs/common` (re-declared to avoid a\n * value import of an internal enum). These are how `@Param`/`@Query`/`@Body`/...\n * tag each handler argument in `ROUTE_ARGS_METADATA`.\n */\nexport const PARAMTYPE = {\n REQUEST: 0,\n RESPONSE: 1,\n NEXT: 2,\n BODY: 3,\n QUERY: 4,\n PARAM: 5,\n HEADERS: 6,\n SESSION: 7,\n FILE: 8,\n FILES: 9,\n HOST: 10,\n IP: 11,\n RAW_BODY: 12\n} as const\n\nexport interface ParamSlot {\n /** `PARAMTYPE` value - which decorator tagged this argument. */\n paramtype: number\n /** Handler argument position. */\n index: number\n /** Decorator sub-key: `@Param('id')` → `'id'`; a bare `@Body()` → `undefined`. */\n data?: string\n /** Parameter-bound pipes (`@Param('id', ParseIntPipe)`). */\n pipes: unknown[]\n /** TypeScript-emitted constructor at this position (e.g. `String`, `CreateDto`). */\n designType?: unknown\n}\n\n/**\n * Read and normalise the route-argument metadata for a controller method.\n * Returns one {@link ParamSlot} per decorated handler argument, sorted by\n * argument index.\n */\nexport function readParamSlots(classRef: any, methodName: string, proto: any): ParamSlot[] {\n const raw = Reflect.getMetadata(ROUTE_ARGS_METADATA, classRef, methodName) as\n Record<string, { index: number; data?: unknown; pipes?: unknown[] }> | undefined\n if (!raw) { return [] }\n const designTypes = (Reflect.getMetadata('design:paramtypes', proto, methodName) as unknown[] | undefined) ?? []\n\n const slots: ParamSlot[] = []\n for (const key of Object.keys(raw)) {\n const entry = raw[key]\n const paramtype = Number(key.split(':')[0])\n if (Number.isNaN(paramtype)) { continue }\n slots.push({\n paramtype,\n index: entry.index,\n data: typeof entry.data === 'string' ? entry.data : undefined,\n pipes: entry.pipes ?? [],\n designType: designTypes[entry.index]\n })\n }\n return slots.sort((a, b) => a.index - b.index)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */\nimport { PARAMTYPE } from './reflect/params.js'\n\n/**\n * Instruction for reconstructing one positional handler argument from the flat\n * MCP tool input. Built at discovery time, consumed by {@link invokeRebound}.\n */\nexport type Binding =\n | { kind: 'value'; field: string; source: 'path' | 'query' | 'body'; metatype?: unknown; pipes?: unknown[] }\n | { kind: 'object'; source: 'query' | 'body'; fields: string[]; metatype?: unknown; pipes?: unknown[] }\n | { kind: 'params'; fields: string[] }\n | { kind: 'request' }\n | { kind: 'response' }\n | { kind: 'headers'; data?: string }\n | { kind: 'ip' }\n | { kind: 'host'; data?: string }\n | { kind: 'missing' }\n\ninterface RequestLike {\n headers?: Record<string, unknown>\n ip?: unknown\n hosts?: Record<string, unknown>\n}\n\nfunction newInstance(P: any): any | null {\n try { return new P() } catch { return null }\n}\n\nasync function applyPipes(value: unknown, pipes: unknown[] | undefined, metatype: unknown, type: 'param' | 'query' | 'body', data: string | undefined): Promise<unknown> {\n if (!pipes || pipes.length === 0) { return value }\n let current = value\n for (const p of pipes) {\n const pipe = typeof p === 'function' ? newInstance(p) : p\n if (pipe && typeof (pipe).transform === 'function') {\n current = await (pipe).transform(current, { type, metatype, data })\n }\n }\n return current\n}\n\n/** Pick a subset of keys (skipping `undefined`) into a fresh object. */\nfunction pickFields(input: Record<string, unknown>, fields: string[]): Record<string, unknown> {\n const obj: Record<string, unknown> = {}\n for (const f of fields) {\n if (input[f] !== undefined) { obj[f] = input[f] }\n }\n return obj\n}\n\n/** Resolve a single positional argument from one binding. */\nasync function resolveArg(\n b: Binding,\n input: Record<string, unknown>,\n request: RequestLike | undefined,\n applyParamPipes: boolean\n): Promise<unknown> {\n switch (b.kind) {\n case 'value': {\n const raw = input[b.field]\n const type = b.source === 'path' ? 'param' : b.source\n return applyParamPipes ? applyPipes(raw, b.pipes, b.metatype, type, b.field) : raw\n }\n case 'object': {\n const obj = pickFields(input, b.fields)\n return applyParamPipes ? applyPipes(obj, b.pipes, b.metatype, b.source, undefined) : obj\n }\n case 'params':\n return pickFields(input, b.fields)\n case 'headers':\n return b.data ? request?.headers?.[b.data.toLowerCase()] : (request?.headers ?? {})\n case 'request':\n return request ?? { headers: {} }\n case 'ip':\n return request?.ip\n case 'host':\n return b.data ? request?.hosts?.[b.data] : request?.hosts\n default:\n return undefined\n }\n}\n\n/**\n * Reconstruct the controller method's positional arguments from the validated\n * tool `input` (and the request stand-in for `@Req`/`@Headers`/...), then call\n * it. `applyParamPipes` controls whether parameter-bound pipes run.\n */\nexport async function invokeRebound(\n method: (...args: any[]) => any,\n instance: object,\n input: Record<string, unknown>,\n bindings: Binding[],\n request: RequestLike | undefined,\n applyParamPipes: boolean\n): Promise<unknown> {\n const args: unknown[] = []\n for (let i = 0; i < bindings.length; i += 1) {\n args[i] = await resolveArg(bindings[i], input, request, applyParamPipes)\n }\n return await method.apply(instance, args)\n}\n\n/** Map a non-input parameter slot (`@Req`/`@Headers`/`@Ip`/...) to its runtime binding. */\nexport function specialBinding(paramtype: number, data: string | undefined): Binding | null {\n switch (paramtype) {\n case PARAMTYPE.REQUEST: return { kind: 'request' }\n case PARAMTYPE.RESPONSE:\n case PARAMTYPE.NEXT: return { kind: 'response' }\n case PARAMTYPE.HEADERS: return { kind: 'headers', data }\n case PARAMTYPE.IP: return { kind: 'ip' }\n case PARAMTYPE.HOST: return { kind: 'host', data }\n case PARAMTYPE.SESSION:\n case PARAMTYPE.FILE:\n case PARAMTYPE.FILES:\n case PARAMTYPE.RAW_BODY: return { kind: 'missing' }\n default: return null\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */\nimport { createRequire } from 'node:module'\nimport { join } from 'node:path'\n\nlet cached: any | null | undefined\n\n/**\n * Lazily resolve the optional `class-validator` peer; `null` when not installed.\n * Resolution is attempted both from this package and from the app's working\n * directory - the latter is what finds it in a pnpm install where the optional\n * peer lives in the consumer app rather than alongside `@silkweave/nestjs`. A\n * pnpm-deduped install shares one physical copy, so the metadata singleton the\n * app's decorators wrote to is the same one we read.\n */\nfunction loadClassValidator(): any | null {\n if (cached !== undefined) { return cached }\n for (const base of [import.meta.url, join(process.cwd(), 'noop.js')]) {\n try {\n cached = createRequire(base)('class-validator')\n return cached\n } catch { /* try the next resolution base */ }\n }\n cached = null\n return cached\n}\n\nexport interface ValidationMeta {\n /** `ValidationTypes` discriminator (e.g. `customValidation`, `conditionalValidation`). */\n type?: string\n /** Validator name - the actionable identity for built-ins (`isString`, `minLength`, ...). */\n name?: string\n constraints?: unknown[]\n}\n\n/**\n * Read `class-validator` metadata for a DTO class, grouped by property name.\n * Returns an empty map when `class-validator` is not installed or the class\n * carries no validation decorators - so callers degrade gracefully to swagger /\n * `design:type` reflection.\n */\nexport function classValidatorMetas(dtoType: any): Record<string, ValidationMeta[]> {\n const cv = loadClassValidator()\n if (!cv?.getMetadataStorage) { return {} }\n let metas: Array<{ propertyName?: string; type?: string; name?: string; constraints?: unknown[] }>\n try {\n metas = cv.getMetadataStorage().getTargetValidationMetadatas(dtoType, null, false, false)\n } catch {\n return {}\n }\n const out: Record<string, ValidationMeta[]> = {}\n for (const m of metas) {\n if (!m.propertyName) { continue }\n (out[m.propertyName] ??= []).push({ type: m.type, name: m.name, constraints: m.constraints })\n }\n return out\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */\nimport { z } from 'zod/v4'\nimport { classValidatorMetas } from './classValidator.js'\n\n/** `@nestjs/swagger` reflect-metadata keys. Read directly so swagger stays an optional peer. */\nconst API_MODEL_PROPERTIES = 'swagger/apiModelProperties'\nconst API_MODEL_PROPERTIES_ARRAY = 'swagger/apiModelPropertiesArray'\n\n/**\n * A transport-neutral description of a single input field. Every metadata\n * source (swagger decorators, class-validator, an OpenAPI document, TypeScript\n * `design:type`) is mapped to this shape, the shapes are merged by precedence,\n * and the result is converted to Zod once. Keeping a single intermediate keeps\n * the per-source mappers small and the Zod construction in one place.\n */\nexport interface FieldDesc {\n type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'unknown'\n required?: boolean\n description?: string\n enum?: (string | number)[]\n items?: FieldDesc\n min?: number\n max?: number\n minLength?: number\n maxLength?: number\n format?: string\n default?: unknown\n}\n\n/** Strip `undefined` values so a later source never clobbers an earlier one with a hole. */\nfunction defined<T extends object>(obj: T): Partial<T> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) { out[k] = v }\n }\n return out as Partial<T>\n}\n\n/** Merge `over` onto `base` - defined keys of `over` win. */\nexport function mergeField(base: FieldDesc, over: FieldDesc): FieldDesc {\n return { ...base, ...defined(over) }\n}\n\nfunction enumToZod(values: (string | number)[]): z.ZodType {\n const strings = values.filter((v): v is string => typeof v === 'string')\n if (strings.length === values.length && strings.length > 0) {\n return z.enum(strings as [string, ...string[]])\n }\n const literals = values.map((v) => z.literal(v))\n if (literals.length === 0) { return z.unknown() }\n if (literals.length === 1) { return literals[0] }\n return z.union(literals as unknown as [z.ZodType, z.ZodType, ...z.ZodType[]])\n}\n\nfunction baseToZod(d: FieldDesc): z.ZodType {\n switch (d.type) {\n case 'string': {\n let s = z.string()\n if (d.minLength != null) { s = s.min(d.minLength) }\n if (d.maxLength != null) { s = s.max(d.maxLength) }\n return s\n }\n case 'integer':\n case 'number': {\n let n = z.number()\n if (d.type === 'integer') { n = n.int() }\n if (d.min != null) { n = n.min(d.min) }\n if (d.max != null) { n = n.max(d.max) }\n return n\n }\n case 'boolean':\n return z.boolean()\n case 'array':\n return z.array(d.items ? fieldToZod({ ...d.items, required: true }) : z.unknown())\n case 'object':\n return z.record(z.string(), z.unknown())\n default:\n return z.unknown()\n }\n}\n\n/** Convert a merged {@link FieldDesc} to a Zod schema. */\nexport function fieldToZod(d: FieldDesc): z.ZodType {\n let schema = (d.enum?.length) ? enumToZod(d.enum) : baseToZod(d)\n if (d.description) { schema = schema.describe(d.description) }\n if (d.default !== undefined) {\n schema = (schema as any).default(d.default)\n } else if (d.required === false) {\n schema = schema.optional()\n }\n return schema\n}\n\n// --- per-source mappers ---------------------------------------------------\n\n/** Normalise a TS-enum object or an array literal to a flat value list. */\nexport function normalizeEnum(value: unknown): (string | number)[] | undefined {\n if (Array.isArray(value)) {\n return value.filter((v): v is string | number => typeof v === 'string' || typeof v === 'number')\n }\n if (value && typeof value === 'object') {\n return Object.values(value).filter((v): v is string | number => typeof v === 'string' || typeof v === 'number')\n }\n return undefined\n}\n\n/** Map a swagger/`design:type` type token (constructor, `[Type]`, or string) to a base type. */\nexport function typeTokenToBase(type: unknown): FieldDesc['type'] | undefined {\n if (type == null) { return undefined }\n if (type === String) { return 'string' }\n if (type === Number) { return 'number' }\n if (type === Boolean) { return 'boolean' }\n if (type === Array) { return 'array' }\n if (type === Date) { return 'string' }\n if (Array.isArray(type)) { return 'array' }\n if (typeof type === 'string') {\n const t = type.toLowerCase()\n if (t === 'string' || t === 'number' || t === 'integer' || t === 'boolean' || t === 'array' || t === 'object') {\n return t\n }\n }\n return undefined\n}\n\n/** From the constructor TypeScript emits via `emitDecoratorMetadata`. */\nexport function designTypeToField(ctor: unknown): FieldDesc {\n const type = typeTokenToBase(ctor)\n const f: FieldDesc = {}\n if (type) { f.type = type }\n return f\n}\n\n/** From an `@ApiParam`/`@ApiQuery` entry stored under `swagger/apiParameters`. */\nexport function swaggerParamToField(p: Record<string, any>): FieldDesc {\n const f: FieldDesc = {}\n if (p['description']) { f.description = p['description'] }\n if (typeof p['required'] === 'boolean') { f.required = p['required'] }\n const type = typeTokenToBase(p['type'])\n if (type) { f.type = type }\n if (p['isArray']) { f.type = 'array' }\n const en = normalizeEnum(p['enum'])\n if (en) { f.enum = en }\n if (p['schema'] && typeof p['schema'] === 'object') {\n return mergeField(f, openapiSchemaToField(p['schema']))\n }\n return f\n}\n\n/** From an `@ApiProperty` options object stored under `swagger/apiModelProperties`. */\nexport function apiPropertyToField(o: Record<string, any>): FieldDesc {\n const f: FieldDesc = {}\n if (o['description']) { f.description = o['description'] }\n if (typeof o['required'] === 'boolean') { f.required = o['required'] }\n const type = typeTokenToBase(o['type'])\n if (type) { f.type = type }\n if (o['isArray']) {\n f.items = { type: type && type !== 'array' ? type : 'unknown' }\n f.type = 'array'\n }\n const en = normalizeEnum(o['enum'])\n if (en) { f.enum = en }\n if (o['minimum'] != null) { f.min = o['minimum'] }\n if (o['maximum'] != null) { f.max = o['maximum'] }\n if (o['minLength'] != null) { f.minLength = o['minLength'] }\n if (o['maxLength'] != null) { f.maxLength = o['maxLength'] }\n if (o['format']) { f.format = o['format'] }\n if (o['default'] !== undefined) { f.default = o['default'] }\n return f\n}\n\n/** `class-validator` decorator type → field base type. */\nconst CV_TYPE: Record<string, FieldDesc['type']> = {\n isString: 'string',\n isInt: 'integer',\n isBoolean: 'boolean',\n isArray: 'array'\n}\n\n/** `class-validator` decorator type → numeric-constraint field key. */\nconst CV_NUMERIC: Record<string, 'min' | 'max' | 'minLength' | 'maxLength'> = {\n min: 'min',\n max: 'max',\n minLength: 'minLength',\n maxLength: 'maxLength'\n}\n\n/**\n * Fold one `class-validator` metadata entry into the field descriptor. Built-in\n * validators record their identity in `name` (`isString`, `minLength`, ...) with\n * `type: 'customValidation'`; `@IsOptional` uses `name: 'isOptional'`. We key off\n * `name`, falling back to `type`.\n */\nfunction applyValidationMeta(f: FieldDesc, meta: { type?: string; name?: string; constraints?: unknown[] }): void {\n const key = meta.name ?? meta.type\n if (!key) { return }\n if (key in CV_TYPE) { f.type = CV_TYPE[key]; return }\n const c0 = meta.constraints?.[0]\n if (key in CV_NUMERIC) {\n if (typeof c0 === 'number') { f[CV_NUMERIC[key]] = c0 }\n return\n }\n if (key === 'isNumber') { if (!f.type) { f.type = 'number' } return }\n if (key === 'isEmail') { if (!f.type) { f.type = 'string' } f.format = 'email'; return }\n if (key === 'isDate' || key === 'isDateString') { f.type = 'string'; f.format = 'date-time'; return }\n if (key === 'isEnum') { const e = normalizeEnum(c0); if (e) { f.enum = e } return }\n if (key === 'isOptional') { f.required = false }\n}\n\n/** From an array of `class-validator` validation-metadata entries for one property. */\nexport function classValidatorToField(metas: Array<{ type?: string; name?: string; constraints?: unknown[] }>): FieldDesc {\n const f: FieldDesc = {}\n for (const meta of metas) { applyValidationMeta(f, meta) }\n return f\n}\n\n/** From an OpenAPI Schema Object (used by both the doc and `@ApiParam({ schema })`). */\nexport function openapiSchemaToField(schema: Record<string, any>): FieldDesc {\n const f: FieldDesc = {}\n const type = typeof schema['type'] === 'string' ? schema['type'].toLowerCase() : undefined\n if (type === 'string' || type === 'number' || type === 'integer' || type === 'boolean' || type === 'array' || type === 'object') {\n f.type = type\n }\n if (schema['description']) { f.description = schema['description'] }\n const en = normalizeEnum(schema['enum'])\n if (en) { f.enum = en }\n if (schema['minimum'] != null) { f.min = schema['minimum'] }\n if (schema['maximum'] != null) { f.max = schema['maximum'] }\n if (schema['minLength'] != null) { f.minLength = schema['minLength'] }\n if (schema['maxLength'] != null) { f.maxLength = schema['maxLength'] }\n if (schema['format']) { f.format = schema['format'] }\n if (schema['default'] !== undefined) { f.default = schema['default'] }\n if (schema['items'] && typeof schema['items'] === 'object') {\n f.items = openapiSchemaToField(schema['items'])\n }\n return f\n}\n\n/**\n * Reflect a whole-DTO class (`@Body() dto: CreateDto`) into per-property\n * {@link FieldDesc}s. Property names are the union of `@ApiProperty` and\n * `class-validator` decorated fields; each field merges `design:type` (base),\n * then `class-validator` constraints, then `@ApiProperty` (highest). Properties\n * default to required unless a source marks them optional.\n */\nexport function reflectDtoFields(dtoType: any): Record<string, FieldDesc> {\n const proto = dtoType?.prototype\n if (!proto) { return {} }\n const cvMetas = classValidatorMetas(dtoType)\n\n const names = new Set<string>()\n const swaggerArray = (Reflect.getMetadata(API_MODEL_PROPERTIES_ARRAY, proto) as string[] | undefined) ?? []\n for (const entry of swaggerArray) { names.add(entry.replace(/^:/, '')) }\n for (const name of Object.keys(cvMetas)) { names.add(name) }\n\n const out: Record<string, FieldDesc> = {}\n for (const name of names) {\n let f = designTypeToField(Reflect.getMetadata('design:type', proto, name))\n if (cvMetas[name]) { f = mergeField(f, classValidatorToField(cvMetas[name])) }\n const apiProp = Reflect.getMetadata(API_MODEL_PROPERTIES, proto, name) as Record<string, any> | undefined\n if (apiProp) {\n const fromApi = apiPropertyToField(apiProp)\n // `@ApiProperty` is required unless `required: false` is explicit.\n if (fromApi.required === undefined && apiProp['required'] === undefined) { fromApi.required = true }\n f = mergeField(f, fromApi)\n }\n if (f.required === undefined) { f.required = true }\n out[name] = f\n }\n return out\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */\nimport { type FieldDesc, mergeField, openapiSchemaToField } from './schema.js'\n\n/**\n * A minimal view of an OpenAPI document - the subset we read. Matches the shape\n * `SwaggerModule.createDocument()` returns, but typed loosely so callers can\n * pass any compatible object without a hard `@nestjs/swagger` dependency.\n */\nexport interface OpenApiDocument {\n paths?: Record<string, Record<string, any>>\n components?: { schemas?: Record<string, any> }\n}\n\nexport interface OpenApiLookup {\n doc: OpenApiDocument\n /** `${METHOD} ${path}` → operation object. */\n operations: Map<string, any>\n}\n\n/** Index a document's operations by `${METHOD} ${path}` for fast matching. */\nexport function buildOpenApiLookup(doc: OpenApiDocument): OpenApiLookup {\n const operations = new Map<string, any>()\n for (const [path, item] of Object.entries(doc.paths ?? {})) {\n for (const [verb, op] of Object.entries(item ?? {})) {\n operations.set(`${verb.toUpperCase()} ${path}`, op)\n }\n }\n return { doc, operations }\n}\n\n/** Locate the operation for a route, tolerating a global path prefix on the document side. */\nfunction findOperation(lookup: OpenApiLookup, method: string, openapiPath: string): any | undefined {\n const exact = lookup.operations.get(`${method} ${openapiPath}`)\n if (exact) { return exact }\n // Fall back to a suffix match so a `setGlobalPrefix('api')` document still resolves.\n for (const [key, op] of lookup.operations) {\n const [verb, path] = key.split(' ')\n if (verb === method && (path.endsWith(openapiPath) || openapiPath.endsWith(path))) { return op }\n }\n return undefined\n}\n\nfunction resolveRef(doc: OpenApiDocument, schema: any): any {\n let current = schema\n let guard = 0\n while (current && typeof current === 'object' && typeof current['$ref'] === 'string' && guard < 10) {\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(current['$ref'])\n if (!match) { break }\n current = doc.components?.schemas?.[match[1]]\n guard += 1\n }\n return current\n}\n\n/**\n * Resolve the per-field descriptors for a route from an ingested OpenAPI\n * document. Merges `parameters` (path/query/header) and the JSON request-body\n * schema's properties into a single field map. Returns `{}` when the operation\n * isn't found - callers fall back to decorator reflection.\n */\nexport function openApiFields(lookup: OpenApiLookup, method: string, openapiPath: string): Record<string, FieldDesc> {\n const op = findOperation(lookup, method, openapiPath)\n if (!op) { return {} }\n const out: Record<string, FieldDesc> = {}\n\n for (const param of (op['parameters'] as Array<Record<string, any>> | undefined) ?? []) {\n const name = typeof param['name'] === 'string' ? param['name'] : undefined\n if (!name) { continue }\n const schema = param['schema'] ? resolveRef(lookup.doc, param['schema']) : undefined\n let field = schema ? openapiSchemaToField(schema) : {}\n if (param['description']) { field = mergeField(field, { description: param['description'] }) }\n if (typeof param['required'] === 'boolean') { field = mergeField(field, { required: param['required'] }) }\n out[name] = field\n }\n\n const bodySchema = resolveRef(lookup.doc, op['requestBody']?.['content']?.['application/json']?.['schema'])\n if (bodySchema && typeof bodySchema === 'object' && bodySchema['properties']) {\n const required = new Set<string>(Array.isArray(bodySchema['required']) ? bodySchema['required'] : [])\n for (const [name, propSchema] of Object.entries(bodySchema['properties'] as Record<string, any>)) {\n const field = openapiSchemaToField(resolveRef(lookup.doc, propSchema))\n field.required = required.has(name)\n out[name] = field\n }\n }\n\n return out\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from 'zod/v4'\nimport { fieldToZod, reflectDtoFields } from './schema.js'\n\n/** `@nestjs/swagger` response metadata key (read directly - swagger is an optional peer). */\nconst API_RESPONSE = 'swagger/apiResponse'\n\n/** Status keys we treat as the \"success\" response, in preference order. */\nconst SUCCESS_KEYS = ['200', '201', '202', '204', '2XX', 'default']\n\n/**\n * Reflect a `@Trpc` procedure's output schema from the method's\n * `@ApiOkResponse({ type: Dto })` (or any 2xx `@ApiResponse`) metadata. The\n * response DTO is flattened with {@link reflectDtoFields} into a Zod object,\n * wrapped in `z.array(...)` when the response is `isArray`.\n *\n * Returns `undefined` when there is no response DTO to reflect (e.g. a primitive\n * return type or no `@ApiResponse` decorator) - the caller then falls back to an\n * explicit `@Trpc({ output })` or an `unknown` output type.\n */\nexport function reflectResponseSchema(method: (...args: any[]) => any): z.ZodType | undefined {\n const responses = Reflect.getMetadata(API_RESPONSE, method) as Record<string, { type?: unknown; isArray?: boolean }> | undefined\n if (!responses) { return undefined }\n\n const key = SUCCESS_KEYS.find((k) => responses[k]) ?? Object.keys(responses)[0]\n const entry = key ? responses[key] : undefined\n const dtoType = entry?.type\n if (typeof dtoType !== 'function') { return undefined }\n\n const schema = reflectDtoSchema(dtoType)\n if (!schema) { return undefined }\n return entry?.isArray ? z.array(schema) : schema\n}\n\n/**\n * Reflect a DTO class (its `@ApiProperty`/`class-validator`-decorated properties)\n * into a Zod object schema. Returns `undefined` when the type isn't a class or\n * has no reflectable properties. Used for `@Trpc({ output })`/`@Trpc({ chunk })`\n * when given a DTO class instead of a Zod schema.\n */\nexport function reflectDtoSchema(dtoType: unknown): z.ZodType | undefined {\n if (typeof dtoType !== 'function') { return undefined }\n const fields = reflectDtoFields(dtoType)\n const names = Object.keys(fields)\n if (names.length === 0) { return undefined }\n const shape: Record<string, z.ZodType> = {}\n for (const name of names) { shape[name] = fieldToZod(fields[name]) }\n return z.object(shape)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { PATH_METADATA, METHOD_METADATA } from '@nestjs/common/constants.js'\n\n/**\n * `RequestMethod` numeric values (from `@nestjs/common`) mapped to verbs. We\n * map our own table rather than importing the enum to avoid pulling a value\n * import for a handful of constants.\n */\nconst REQUEST_METHOD: Record<number, string> = {\n 0: 'GET',\n 1: 'POST',\n 2: 'PUT',\n 3: 'DELETE',\n 4: 'PATCH',\n 6: 'OPTIONS',\n 7: 'HEAD'\n}\n\nexport interface RouteInfo {\n /** HTTP verb (`GET`/`POST`/...). `PATCH` and others outside the REST set fall back to `POST`-ish handling by callers. */\n method: string\n /** Full route template in Nest form, e.g. `sessions/:sessionId/channels/:channelId` (no leading slash). */\n path: string\n /** Full route template in OpenAPI form, e.g. `/sessions/{sessionId}/channels/{channelId}`. */\n openapiPath: string\n /** Names of the `:param` placeholders across controller + method path. */\n pathParams: string[]\n}\n\nfunction normalizeSegment(value: unknown): string {\n if (typeof value !== 'string') { return '' }\n return value.replace(/^\\/+/, '').replace(/\\/+$/, '')\n}\n\nfunction joinPath(...segments: string[]): string {\n return segments.map(normalizeSegment).filter(Boolean).join('/')\n}\n\n/**\n * Resolve the composed route (controller prefix + method path), HTTP verb, and\n * path-param names for a decorated controller method, reading Nest's own\n * `PATH_METADATA`/`METHOD_METADATA` reflection.\n */\nexport function reflectRoute(classRef: any, method: (...args: any[]) => any): RouteInfo {\n const classPath = Reflect.getMetadata(PATH_METADATA, classRef) as string | string[] | undefined\n const methodPath = Reflect.getMetadata(PATH_METADATA, method) as string | string[] | undefined\n const verbCode = Reflect.getMetadata(METHOD_METADATA, method) as number | undefined\n\n const classSeg = Array.isArray(classPath) ? (classPath[0] ?? '') : (classPath ?? '')\n const methodSeg = Array.isArray(methodPath) ? (methodPath[0] ?? '') : (methodPath ?? '')\n const path = joinPath(classSeg, methodSeg)\n const httpMethod = REQUEST_METHOD[verbCode ?? 0] ?? 'GET'\n\n const pathParams = [...path.matchAll(/:([A-Za-z0-9_]+)/g)].map((m) => m[1])\n const openapiPath = `/${path.replace(/:([A-Za-z0-9_]+)/g, '{$1}')}`\n\n return { method: httpMethod, path, openapiPath, pathParams }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { FieldDesc } from './schema.js'\nimport { swaggerParamToField } from './schema.js'\n\n/** `@nestjs/swagger` reflect-metadata keys (read directly - swagger is an optional peer). */\nconst API_OPERATION = 'swagger/apiOperation'\nconst API_PARAMETERS = 'swagger/apiParameters'\n\nexport interface OperationMeta {\n /** Tool-description candidate from `@ApiOperation({ summary | description })`. */\n description?: string\n /** Per-name `FieldDesc` reflected from `@ApiParam`/`@ApiQuery` entries. */\n params: Record<string, FieldDesc>\n}\n\n/**\n * Read operation-level `@nestjs/swagger` metadata off a controller method:\n * `@ApiOperation` (summary/description) and the `@ApiParam`/`@ApiQuery` array\n * (each describing one path/query field). Returns empty data when swagger\n * decorators are absent.\n */\nexport function reflectOperation(method: (...args: any[]) => any): OperationMeta {\n const operation = Reflect.getMetadata(API_OPERATION, method) as Record<string, any> | undefined\n const description = operation\n ? (typeof operation['summary'] === 'string' && operation['summary']\n ? operation['summary']\n : (typeof operation['description'] === 'string' ? operation['description'] : undefined))\n : undefined\n\n const parameters = (Reflect.getMetadata(API_PARAMETERS, method) as Array<Record<string, any>> | undefined) ?? []\n const params: Record<string, FieldDesc> = {}\n for (const p of parameters) {\n const name = typeof p['name'] === 'string' ? p['name'] : undefined\n if (!name) { continue }\n params[name] = swaggerParamToField(p)\n }\n\n return { description, params }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { HttpException, Injectable, type CanActivate, type Type } from '@nestjs/common'\nimport { ApplicationConfig, DiscoveryService, MetadataScanner, ModuleRef, Reflector } from '@nestjs/core'\nimport { SilkweaveError, type Action, type ActionKind, type SilkweaveContext } from '@silkweave/core'\nimport { z } from 'zod/v4'\nimport { collectGlobalGuards, collectGuards, runGuards } from './guards.js'\nimport { MCP_METADATA, TRPC_METADATA, type McpMetadata, type TrpcMetadata } from './metadata.js'\nimport { invokeRebound, specialBinding, type Binding } from './rebind.js'\nimport { buildOpenApiLookup, openApiFields, type OpenApiDocument, type OpenApiLookup } from './reflect/openapi.js'\nimport { PARAMTYPE, type ParamSlot, readParamSlots } from './reflect/params.js'\nimport { reflectDtoSchema, reflectResponseSchema } from './reflect/response.js'\nimport { reflectRoute, type RouteInfo } from './reflect/route.js'\nimport { type FieldDesc, fieldToZod, mergeField, reflectDtoFields } from './reflect/schema.js'\nimport { reflectOperation } from './reflect/swagger.js'\n\ninterface Discovered {\n instance: object\n classRef: Type<unknown>\n method: (...args: unknown[]) => unknown\n methodName: string\n mcp?: McpMetadata\n trpc?: TrpcMetadata\n}\n\ninterface BuiltInput {\n shape: Record<string, z.ZodType>\n bindings: Binding[]\n}\n\n/** Shared reflection computed once per discovered method, reused across targets. */\ninterface Reflected {\n route: RouteInfo\n base: string\n description?: string\n baseShape: Record<string, z.ZodType>\n bindings: Binding[]\n guards: ReturnType<typeof collectGuards>\n pathFields: string[]\n streaming: boolean\n}\n\nexport interface DiscoverOptions {\n openapi?: OpenApiDocument\n globalGuards?: Type<CanActivate>[]\n defaultResult?: 'json' | 'smart'\n}\n\n@Injectable()\nexport class ControllerDiscovery {\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly scanner: MetadataScanner,\n private readonly reflector: Reflector,\n private readonly moduleRef: ModuleRef,\n private readonly appConfig: ApplicationConfig\n ) { }\n\n /**\n * Walk every Nest provider/controller, find methods annotated with `@Mcp`\n * and/or `@Trpc`, and build a core `Action` per decorator present on each\n * method. The input schema is reflected from the route + parameter decorators\n * (+ optional OpenAPI document) and the `run` re-binds the validated input back\n * into the method's positional arguments (with `@UseGuards` guards applied\n * first). A method carrying both decorators yields two actions - one gated to\n * the `mcp` adapter, one to the `trpc`/`typegen` adapters - sharing the same\n * reflected input, bindings, and guards.\n */\n discover(options: DiscoverOptions = {}): Action[] {\n const lookup = options.openapi ? buildOpenApiLookup(options.openapi) : undefined\n const discovered: Discovered[] = []\n for (const wrapper of this.discovery.getProviders().concat(this.discovery.getControllers())) {\n const { instance } = wrapper\n if (!instance || typeof instance !== 'object') { continue }\n const proto = Object.getPrototypeOf(instance) as object | null\n if (!proto) { continue }\n const classRef = instance.constructor as Type<unknown>\n for (const methodName of this.scanner.getAllMethodNames(proto)) {\n const method = (proto as Record<string, unknown>)[methodName] as ((...args: unknown[]) => unknown) | undefined\n if (typeof method !== 'function') { continue }\n const mcp = this.reflector.get<McpMetadata>(MCP_METADATA, method)\n const trpc = this.reflector.get<TrpcMetadata>(TRPC_METADATA, method)\n if (!mcp && !trpc) { continue }\n discovered.push({ instance, classRef, method, methodName, mcp, trpc })\n }\n }\n\n const globalGuards = options.globalGuards ?? []\n const actions: Action[] = []\n for (const d of discovered) {\n const shared = this.reflect(d, lookup)\n if (d.mcp) { actions.push(this.mcpAction(d, shared, globalGuards, options.defaultResult)) }\n if (d.trpc) { actions.push(this.trpcAction(d, shared, globalGuards)) }\n }\n return actions\n }\n\n /** Compute the per-method reflection shared by the `mcp` and `trpc` builders. */\n private reflect(d: Discovered, lookup: OpenApiLookup | undefined): Reflected {\n const proto = Object.getPrototypeOf(d.instance) as object\n const route = reflectRoute(d.classRef, d.method)\n const slots = readParamSlots(d.classRef, d.methodName, proto)\n const operation = reflectOperation(d.method)\n const docFields = lookup ? openApiFields(lookup, route.method, route.openapiPath) : {}\n\n const { shape, bindings } = buildInput(proto, d.methodName, route.pathParams, slots, operation.params, docFields)\n\n return {\n route,\n base: d.classRef.name.replace(/Controller$/, ''),\n description: operation.description,\n baseShape: shape,\n bindings,\n guards: collectGuards(this.reflector, d.classRef, d.method),\n pathFields: pathParamFields(bindings),\n streaming: isAsyncGeneratorFn(d.method)\n }\n }\n\n /** Build a guard-application closure shared by both run shapes. */\n private guardRunner(d: Discovered, shared: Reflected, globalGuards: Type<CanActivate>[]) {\n const { moduleRef, reflector, appConfig } = this\n const { guards, pathFields } = shared\n const { classRef, method } = d\n return async (context: SilkweaveContext, input: object): Promise<void> => {\n // Resolved at call time - `APP_GUARD` instances aren't populated until\n // `app.init()` finishes. Globals run before the route/class guards.\n const all = [...collectGlobalGuards(appConfig, globalGuards), ...guards]\n if (all.length === 0) { return }\n const request = context.getOptional<unknown>('request')\n const response = context.getOptional<unknown>('response') ?? null\n const hasRequest = request != null\n const guardRequest = hasRequest ? request : { headers: {}, params: {}, query: {} }\n populatePathParams(guardRequest, pathFields, input as Record<string, unknown>)\n await runGuards(all, moduleRef, reflector, classRef, method, guardRequest, response, hasRequest ? 'http' : 'rpc')\n }\n }\n\n /** Synthesize the MCP-targeted action (unchanged behavior from v2.4). */\n private mcpAction(d: Discovered, shared: Reflected, globalGuards: Type<CanActivate>[], defaultResult?: 'json' | 'smart'): Action {\n const meta = d.mcp!\n const shape = { ...shared.baseShape, ...(meta.input ?? {}) }\n const name = meta.name ?? `${shared.base}.${d.methodName}`\n const description = meta.description ?? shared.description ?? `${d.methodName} (${shared.route.method} /${shared.route.path})`\n const applyParamPipes = meta.pipes !== 'skip'\n const applyGuards = this.guardRunner(d, shared, globalGuards)\n const { method, instance } = d\n const { bindings, streaming } = shared\n\n return {\n name,\n description,\n input: z.object(shape),\n ...((meta.result ?? defaultResult) ? { disposition: meta.result ?? defaultResult } : {}),\n isEnabled: (ctx) => ctx.getOptional<string>('adapter') === 'mcp',\n ...(streaming\n ? { chunk: z.unknown(), run: streamingRun(applyGuards, method, instance, bindings, applyParamPipes, false) }\n : {\n run: async (input: object, context: SilkweaveContext): Promise<object> => {\n await applyGuards(context, input)\n const request = context.getOptional<{ headers?: Record<string, unknown> }>('request')\n const result = await invokeRebound(method, instance, input as Record<string, unknown>, bindings, request, applyParamPipes)\n return result ?? {}\n }\n })\n } as Action\n }\n\n /** Synthesize the tRPC-targeted action (kind/output/subscription + httpStatus errors). */\n private trpcAction(d: Discovered, shared: Reflected, globalGuards: Type<CanActivate>[]): Action {\n const meta = d.trpc!\n const shape = { ...shared.baseShape, ...(meta.input ?? {}) }\n const name = meta.name ?? `${shared.base}.${d.methodName}`\n const description = meta.description ?? shared.description ?? `${d.methodName} (${shared.route.method} /${shared.route.path})`\n const applyParamPipes = meta.pipes !== 'skip'\n const applyGuards = this.guardRunner(d, shared, globalGuards)\n const { method, instance } = d\n const { bindings, streaming } = shared\n\n // tRPC and typegen both consume `@Trpc` actions; MCP never does.\n const isEnabled = (ctx: SilkweaveContext): boolean => {\n const adapter = ctx.getOptional<string>('adapter')\n return adapter === 'trpc' || adapter === 'typegen'\n }\n\n if (streaming) {\n return {\n name,\n description,\n input: z.object(shape),\n chunk: resolveSchema(meta.chunk) ?? z.unknown(),\n isEnabled,\n run: streamingRun(applyGuards, method, instance, bindings, applyParamPipes, true)\n } as Action\n }\n\n const kind: ActionKind = meta.kind === 'query' || meta.kind === 'mutation'\n ? meta.kind\n : (shared.route.method === 'GET' ? 'query' : 'mutation')\n const output = resolveOutput(meta, method)\n\n return {\n name,\n description,\n input: z.object(shape),\n ...(output ? { output } : {}),\n kind,\n isEnabled,\n run: async (input: object, context: SilkweaveContext): Promise<object> => {\n try {\n await applyGuards(context, input)\n const request = context.getOptional<{ headers?: Record<string, unknown> }>('request')\n const result = await invokeRebound(method, instance, input as Record<string, unknown>, bindings, request, applyParamPipes)\n return result ?? {}\n } catch (error) {\n throw toSilkweaveError(error)\n }\n }\n } as Action\n }\n}\n\n/** Build a streaming (`async *`) run that applies guards then yields the method's chunks. */\nfunction streamingRun(\n applyGuards: (context: SilkweaveContext, input: object) => Promise<void>,\n method: (...args: unknown[]) => unknown,\n instance: object,\n bindings: Binding[],\n applyParamPipes: boolean,\n mapErrors: boolean\n) {\n return async function* (input: object, context: SilkweaveContext): AsyncGenerator<unknown, void, void> {\n try {\n await applyGuards(context, input)\n const request = context.getOptional<{ headers?: Record<string, unknown> }>('request')\n const gen = await invokeRebound(method, instance, input as Record<string, unknown>, bindings, request, applyParamPipes) as AsyncIterable<unknown>\n for await (const chunk of gen) { yield chunk }\n } catch (error) {\n throw mapErrors ? toSilkweaveError(error) : error\n }\n }\n}\n\n/** Resolve a `@Trpc` action's output schema: explicit override wins over `@ApiOkResponse` reflection. */\nfunction resolveOutput(meta: TrpcMetadata, method: (...args: unknown[]) => unknown): z.ZodType | undefined {\n return resolveSchema(meta.output) ?? reflectResponseSchema(method)\n}\n\n/**\n * Coerce an `output`/`chunk` override to a Zod schema: a Zod schema passes\n * through, a DTO class is reflected, and a raw shape is wrapped in `z.object`.\n */\nfunction resolveSchema(value: TrpcMetadata['output']): z.ZodType | undefined {\n if (value == null) { return undefined }\n if (isZodSchema(value)) { return value }\n if (typeof value === 'function') { return reflectDtoSchema(value) }\n return z.object(value)\n}\n\nfunction isZodSchema(value: unknown): value is z.ZodType {\n return Boolean(value) && typeof value === 'object' && typeof (value as { safeParse?: unknown }).safeParse === 'function'\n}\n\nfunction isAsyncGeneratorFn(fn: unknown): boolean {\n return typeof fn === 'function' && (fn as { constructor?: { name?: string } }).constructor?.name === 'AsyncGeneratorFunction'\n}\n\n/**\n * Convert a thrown Nest `HttpException` into a `SilkweaveError` carrying its HTTP\n * status, so the tRPC adapter's `mapError` maps it to the right `TRPCError` code\n * (and `data.httpStatus`) - e.g. a denying `AuthGuard`'s `UnauthorizedException`\n * surfaces to the client as a `401`. Non-HTTP errors pass through unchanged.\n */\nfunction toSilkweaveError(error: unknown): unknown {\n if (error instanceof HttpException) {\n const status = error.getStatus()\n const response = error.getResponse()\n const raw = typeof response === 'string'\n ? response\n : (response as { message?: unknown })?.message ?? error.message\n const message = Array.isArray(raw) ? raw.join(', ') : String(raw)\n return new SilkweaveError(message, 'http_error', status)\n }\n return error\n}\n\n/** Build the merged Zod input shape and the per-argument re-bind plan. */\nfunction buildInput(\n proto: object,\n methodName: string,\n pathParams: string[],\n slots: ReturnType<typeof readParamSlots>,\n operationParams: Record<string, FieldDesc>,\n docFields: Record<string, FieldDesc>\n): BuiltInput {\n const designTypes = (Reflect.getMetadata('design:paramtypes', proto, methodName) as unknown[] | undefined) ?? []\n const fields: Record<string, FieldDesc> = {}\n const maxIndex = slots.reduce((m, s) => Math.max(m, s.index), -1)\n const bindings: Binding[] = Array.from({ length: maxIndex + 1 }, () => ({ kind: 'missing' as const }))\n\n const addField = (name: string, desc: FieldDesc): void => {\n fields[name] = name in fields ? mergeField(fields[name], desc) : desc\n }\n\n for (const slot of slots) {\n const { binding, fields: contributed } = contributeSlot(slot, pathParams, designTypes)\n bindings[slot.index] = binding\n for (const [name, desc] of Object.entries(contributed)) { addField(name, desc) }\n }\n\n // Layer operation-level (`@ApiParam`/`@ApiQuery`) then OpenAPI-document\n // metadata over the structural fields (later sources win per field).\n for (const [name, desc] of Object.entries(operationParams)) {\n if (name in fields) { fields[name] = mergeField(fields[name], desc) }\n }\n for (const [name, desc] of Object.entries(docFields)) {\n if (name in fields) { fields[name] = mergeField(fields[name], desc) }\n }\n\n const shape: Record<string, z.ZodType> = {}\n for (const [name, desc] of Object.entries(fields)) { shape[name] = fieldToZod(desc) }\n\n return { shape, bindings }\n}\n\n/** Input field names that originate from the URL path (`@Param`), per the re-bind plan. */\nfunction pathParamFields(bindings: Binding[]): string[] {\n const fields: string[] = []\n for (const b of bindings) {\n if (b.kind === 'params') { fields.push(...b.fields) } else if (b.kind === 'value' && b.source === 'path') { fields.push(b.field) }\n }\n return fields\n}\n\n/**\n * Fill `request.params` with the reflected path fields from the validated input,\n * matching what Express would populate over REST (raw string values). Only adds\n * keys that are absent, so a real REST request's params are never overwritten.\n */\nfunction populatePathParams(request: unknown, pathFields: string[], input: Record<string, unknown>): void {\n if (pathFields.length === 0 || typeof request !== 'object' || request === null) { return }\n const params = ((request as { params?: Record<string, unknown> }).params ??= {})\n for (const field of pathFields) {\n if (!(field in params) && input[field] !== undefined) {\n params[field] = String(input[field])\n }\n }\n}\n\nfunction designTypeAt(designTypes: unknown[], index: number): FieldDesc {\n const ctor = designTypes[index]\n if (ctor === String) { return { type: 'string' } }\n if (ctor === Number) { return { type: 'number' } }\n if (ctor === Boolean) { return { type: 'boolean' } }\n return {}\n}\n\ninterface SlotContribution {\n binding: Binding\n /** Input fields this slot contributes, keyed by field name. */\n fields: Record<string, FieldDesc>\n}\n\n/** A `@Param('id')` scalar or a bare `@Param()` covering all path params. */\nfunction paramContribution(slot: ParamSlot, pathParams: string[]): SlotContribution {\n if (slot.data) {\n return {\n binding: { kind: 'value', field: slot.data, source: 'path', metatype: slot.designType, pipes: slot.pipes },\n fields: { [slot.data]: { type: 'string', required: true } }\n }\n }\n const fields: Record<string, FieldDesc> = {}\n for (const p of pathParams) { fields[p] = { type: 'string', required: true } }\n return { binding: { kind: 'params', fields: pathParams }, fields }\n}\n\n/** A `@Query('x')`/`@Body('x')` scalar or a whole-DTO `@Query()`/`@Body()`. */\nfunction bodyOrQueryContribution(slot: ParamSlot, source: 'query' | 'body', requiredScalar: boolean, designTypes: unknown[]): SlotContribution {\n if (slot.data) {\n return {\n binding: { kind: 'value', field: slot.data, source, metatype: slot.designType, pipes: slot.pipes },\n fields: { [slot.data]: mergeField(designTypeAt(designTypes, slot.index), { required: requiredScalar }) }\n }\n }\n const dtoFields = reflectDtoFields(slot.designType)\n return {\n binding: { kind: 'object', source, fields: Object.keys(dtoFields), metatype: slot.designType, pipes: slot.pipes },\n fields: dtoFields\n }\n}\n\n/** Map one parameter slot to its input-field contribution and re-bind instruction. */\nfunction contributeSlot(slot: ParamSlot, pathParams: string[], designTypes: unknown[]): SlotContribution {\n switch (slot.paramtype) {\n case PARAMTYPE.PARAM: return paramContribution(slot, pathParams)\n case PARAMTYPE.QUERY: return bodyOrQueryContribution(slot, 'query', false, designTypes)\n case PARAMTYPE.BODY: return bodyOrQueryContribution(slot, 'body', true, designTypes)\n default: return { binding: specialBinding(slot.paramtype, slot.data) ?? { kind: 'missing' }, fields: {} }\n }\n}\n","import type { CanActivate, Type } from '@nestjs/common'\nimport type { HttpAdapterHost } from '@nestjs/core'\nimport type { Action, SilkweaveContext, SilkweaveOptions } from '@silkweave/core'\nimport type { OpenApiDocument } from './reflect/openapi.js'\n\n/**\n * Context passed to a Nest Silkweave adapter when `SilkweaveModule` wires it\n * up. Adapters register their routes directly on `httpAdapter` (no\n * placeholder middleware, no `silkweave()` builder), so they only fire\n * `register()` once and own the rest of their lifecycle implicitly through\n * Nest.\n */\nexport interface NestAdapterRegisterContext {\n /** Nest's underlying HTTP adapter (Express or Fastify). */\n httpAdapter: NonNullable<HttpAdapterHost['httpAdapter']>\n /** Identity the adapter surfaces to clients (e.g. MCP server name). */\n silkweaveOptions: SilkweaveOptions\n /** Per-adapter context - already forked with `{ adapter: adapter.name, ...userContext }`. */\n baseContext: SilkweaveContext\n /** Actions filtered to those enabled on this adapter. */\n actions: Action[]\n}\n\n/**\n * A Silkweave Nest adapter. Each transport (REST, tRPC, MCP) implements this\n * shape. `register()` is called from `SilkweaveModule.configure()` - which\n * runs *before* Nest's controller routes are mapped - so adapter routes\n * always sit ahead of any catch-all controllers in the framework's request\n * pipeline.\n */\nexport interface NestSilkweaveAdapter {\n /** Adapter discriminator - set on the silkweave context as `ctx.get('adapter')`. */\n readonly name: 'mcp' | 'trpc' | 'typegen'\n /** URL prefix the adapter mounts on (e.g. `'/mcp'`). Surfaced for introspection. */\n readonly basePath?: string\n /**\n * When `true`, the adapter receives every discovered action regardless of\n * each action's `isEnabled` gate. Reserved for non-runtime adapters that need\n * the entire action surface.\n */\n readonly allActions?: boolean\n /** Register this adapter's routes on Nest's HTTP server. */\n register(ctx: NestAdapterRegisterContext): void\n}\n\nexport interface SilkweaveModuleOptions {\n /** Identity for the silkweave instance - surfaced to MCP clients, OpenAPI, etc. */\n silkweave: SilkweaveOptions\n /** Adapters to mount - any of `mcp()`, `trpc()`, `typegen()`. */\n adapters: NestSilkweaveAdapter[]\n /** Initial context keys merged into every adapter's `baseContext`. */\n context?: Record<string, unknown>\n /**\n * Optional OpenAPI document (e.g. from `SwaggerModule.createDocument(app, cfg)`)\n * used as an authoritative source when reflecting `@Mcp` tool input schemas.\n * Matched to each method by HTTP verb + path; falls back to decorator\n * reflection when an operation or field isn't present.\n */\n openapi?: OpenApiDocument\n /**\n * Opt-in allow-list of app-global guard classes (registered via\n * `app.useGlobalGuards()` or `{ provide: APP_GUARD, useClass }`) to run on\n * every MCP tool call, before each method/class `@UseGuards`. Listed by\n * class - a blanket \"run all globals\" is deliberately not offered, since\n * unrelated globals (e.g. a `ThrottlerGuard` that needs a writable response)\n * would misbehave over MCP. Empty/omitted ⇒ no global guards run.\n *\n * Note: over MCP the request stand-in is headers-only (`params`/`query` are\n * empty), so per-session or IP-derived guard logic won't apply; header-based\n * authentication still works.\n */\n globalGuards?: Type<CanActivate>[]\n /**\n * Default MCP result format for every `@Mcp` tool - `'json'` (compact JSON,\n * `jsonToolResult`) or `'smart'` (inline small / embedded-resource large,\n * `smartToolResult`). Defaults to `'smart'`. A per-method `@Mcp({ result })`\n * overrides this, and a client's per-call `_meta.disposition` overrides both.\n */\n defaultResult?: 'json' | 'smart'\n}\n\nexport const SILKWEAVE_MODULE_OPTIONS = '__silkweave_module_options__'\n","import { Inject, Module, type DynamicModule, type MiddlewareConsumer, type NestModule } from '@nestjs/common'\nimport { DiscoveryModule, HttpAdapterHost } from '@nestjs/core'\nimport { createContext } from '@silkweave/core'\nimport { ControllerDiscovery } from './controllerDiscovery.js'\nimport { SILKWEAVE_MODULE_OPTIONS, type SilkweaveModuleOptions } from './types.js'\n\n/**\n * Root module for `@silkweave/nestjs`.\n *\n * Discovers every `@Mcp`/`@Trpc`-decorated **controller method** via\n * `DiscoveryService`, reflects each into a Silkweave action (input schema from\n * the route + parameter decorators + optional OpenAPI document; invocation by\n * re-binding the validated input back into the method), and registers the\n * configured adapter(s) - `mcp()`, `trpc()`, `typegen()` - directly on Nest's\n * HTTP adapter inside `configure()`.\n *\n * Because `configure()` runs during `registerModules` - before Nest's\n * `registerRouter()` step - Silkweave's routes always sit ahead of every\n * controller in the Express stack. The controllers keep serving HTTP exactly as\n * before; `@Mcp` is purely additive.\n *\n * @example\n * ```ts\n * @Module({\n * imports: [\n * SilkweaveModule.forRoot({\n * silkweave: { name: 'app', description: 'My App', version: '1.0.0' },\n * adapters: [mcp({ basePath: '/mcp' })]\n * })\n * ],\n * controllers: [ChannelsController]\n * })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class SilkweaveModule implements NestModule {\n constructor(\n @Inject(SILKWEAVE_MODULE_OPTIONS) private readonly options: SilkweaveModuleOptions,\n private readonly discovery: ControllerDiscovery,\n private readonly httpAdapterHost: HttpAdapterHost\n ) { }\n\n static forRoot(options: SilkweaveModuleOptions): DynamicModule {\n return {\n module: SilkweaveModule,\n global: true,\n imports: [DiscoveryModule],\n providers: [\n { provide: SILKWEAVE_MODULE_OPTIONS, useValue: options },\n ControllerDiscovery\n ],\n exports: []\n }\n }\n\n configure(_consumer: MiddlewareConsumer): void {\n const httpAdapter = this.httpAdapterHost.httpAdapter\n if (!httpAdapter) {\n throw new Error('@silkweave/nestjs: HttpAdapterHost.httpAdapter is not available.')\n }\n const allActions = this.discovery.discover({\n openapi: this.options.openapi,\n globalGuards: this.options.globalGuards,\n defaultResult: this.options.defaultResult\n })\n for (const adapter of this.options.adapters) {\n const baseContext = createContext({ ...(this.options.context ?? {}), adapter: adapter.name })\n const actions = adapter.allActions\n ? allActions\n : allActions.filter((a) => !a.isEnabled || a.isEnabled(baseContext))\n adapter.register({\n httpAdapter,\n silkweaveOptions: this.options.silkweave,\n baseContext,\n actions\n })\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/metadata.ts","../src/decorator/mcp.ts","../src/decorator/trpc.ts","../src/lib/executionContext.ts","../src/lib/guards.ts","../src/lib/reflect/params.ts","../src/lib/rebind.ts","../src/lib/reflect/classValidator.ts","../src/lib/reflect/schema.ts","../src/lib/reflect/openapi.ts","../src/lib/reflect/response.ts","../src/lib/reflect/route.ts","../src/lib/reflect/swagger.ts","../src/lib/controllerDiscovery.ts","../src/lib/types.ts","../src/lib/silkweave.module.ts"],"sourcesContent":["import type { Type } from '@nestjs/common'\nimport type { z } from 'zod/v4'\n\n/** Reflect-metadata key carrying `@Mcp` options on a controller method. */\nexport const MCP_METADATA = '__silkweave_mcp__'\n\n/** Reflect-metadata key carrying `@Trpc` options on a controller method. */\nexport const TRPC_METADATA = '__silkweave_trpc__'\n\n/**\n * Options for the `@Mcp()` method decorator. Every field is optional - an empty\n * `@Mcp()` exposes the decorated controller route as an MCP tool with its name,\n * description, and input schema fully reflected from the method's route\n * (`@Get`/`@Post`/...), parameter decorators (`@Param`/`@Query`/`@Body`), and\n * any `@nestjs/swagger` (`@ApiOperation`/`@ApiParam`/`@ApiProperty`) or\n * `class-validator` metadata it carries.\n */\nexport interface McpMetadata {\n /**\n * MCP tool name override. When unset it is derived from the controller class\n * and method name (e.g. `ChannelsController.findOne` → `ChannelsFindOne`).\n */\n name?: string\n /**\n * Tool description override. When unset it falls back to the method's\n * `@ApiOperation({ summary | description })`, then a generated default.\n */\n description?: string\n /**\n * Zod override merged over the reflected input fields (override wins per\n * field). Accepts either a raw shape (`{ field: z.string() }`) or a whole\n * `z.object({ ... })` - the object's `.shape` is unwrapped. The escape hatch\n * for shapes reflection can't express losslessly - discriminated unions,\n * custom validators, `@Transform`, etc. Note it *adds to* the reflected\n * fields; it does not replace them, so a field reflection silently dropped\n * (see the unreflectable-param warning) is not recovered by listing the\n * others here.\n */\n input?: Record<string, z.ZodType> | z.ZodObject\n /**\n * Whether to apply the controller method's parameter-bound pipes\n * (`@Param('id', ParseIntPipe)`) when re-binding the call. Default `'apply'`.\n * Global/`ValidationPipe`, interceptors, and exception filters never run -\n * the method is invoked directly, not through Nest's HTTP request pipeline.\n */\n pipes?: 'apply' | 'skip'\n /**\n * Default MCP result format for this tool. `'json'` returns compact JSON text\n * (`jsonToolResult`); `'smart'` (the default when unset) inlines small\n * payloads and offloads large ones to an embedded resource (`smartToolResult`).\n * This is only a default - a client that sends `_meta.disposition` on the tool\n * call overrides it.\n */\n result?: 'json' | 'smart'\n}\n\n/** tRPC procedure kind for a `@Trpc`-decorated route. */\nexport type TrpcKind = 'query' | 'mutation' | 'subscription'\n\n/**\n * Options for the `@Trpc()` method decorator - the tRPC sibling of `@Mcp`. An\n * empty `@Trpc()` exposes the decorated controller route as a tRPC procedure\n * with its key, input schema, and kind reflected from the route + parameter\n * decorators + swagger/class-validator metadata (identically to `@Mcp`).\n *\n * Unlike MCP, tRPC carries precise *output* types into the generated router, so\n * `@Trpc` adds an `output`/`chunk` hatch and a `kind` override on top of the\n * shared reflection. The two decorators compose on the same method.\n */\nexport interface TrpcMetadata {\n /**\n * Procedure-name override (before camelCasing). When unset it is derived from\n * the controller class + method name (e.g. `UsersController.listBySpace` →\n * `Users.listBySpace`, camelCased by the router to `usersListBySpace`).\n */\n name?: string\n /**\n * Procedure description override. When unset it falls back to the method's\n * `@ApiOperation({ summary | description })`, then a generated default.\n */\n description?: string\n /**\n * Zod override merged over the reflected input fields (override wins per\n * field). Accepts a raw shape (`{ field: z.string() }`) or a whole\n * `z.object({ ... })` (its `.shape` is unwrapped). Same escape hatch as\n * `@Mcp({ input })`.\n */\n input?: Record<string, z.ZodType> | z.ZodObject\n /**\n * Explicit output schema driving the generated procedure's output type - a Zod\n * type, a DTO class (reflected like `@ApiOkResponse`), or a raw shape (wrapped\n * in `z.object`). Wins over `@ApiOkResponse` reflection. The biggest reason to\n * set this is when the return shape can't be reflected losslessly from a DTO.\n */\n output?: z.ZodType | Type | Record<string, z.ZodType>\n /**\n * Chunk schema for an async-generator route exposed as a tRPC **subscription**.\n * A Zod type or a DTO class. Drives the emitted\n * `TRPCSubscriptionProcedure<{ output }>` type. When unset the chunk type falls\n * back to `unknown`.\n */\n chunk?: z.ZodType | Type\n /**\n * Procedure kind. When unset it is inferred: an `async *` route ⇒\n * `'subscription'`, a `@Get` route ⇒ `'query'`, anything else ⇒ `'mutation'`.\n * Set this to expose a verb-less route (no `@Get`/`@Post`) as a query or\n * subscription - `@Trpc({ kind })` works without an HTTP-verb decorator, so the\n * route is served over tRPC (and/or MCP) without becoming a public REST route.\n */\n kind?: TrpcKind\n /**\n * Whether to apply the method's parameter-bound pipes when re-binding the call.\n * Default `'apply'`. Same semantics as `@Mcp({ pipes })`.\n */\n pipes?: 'apply' | 'skip'\n}\n","import { SetMetadata } from '@nestjs/common'\nimport { MCP_METADATA, type McpMetadata } from '../lib/metadata.js'\n\n/**\n * Method decorator that exposes an existing NestJS controller route as an MCP\n * tool. It is **additive** - the route keeps serving HTTP exactly as before;\n * `@Mcp()` just opts the method into MCP discovery.\n *\n * The tool's name, description, and input schema are reflected from the\n * method's own metadata:\n * - **fields** from the parameter decorators (`@Param`/`@Query`/`@Body`) - a\n * `@Param('id')` becomes an `id` field; a whole-DTO `@Body() dto: CreateDto`\n * is flattened to its properties,\n * - **types/constraints/descriptions** from `@nestjs/swagger`\n * (`@ApiParam`/`@ApiQuery`/`@ApiProperty`/`@ApiOperation`) and, when present,\n * `class-validator` decorators on the DTOs,\n * - optionally refined by an OpenAPI document passed to `SilkweaveModule`.\n *\n * On a tool call the input is split back into the method's positional arguments\n * and the method is invoked directly (with `@UseGuards` guards applied first).\n *\n * @example\n * ```ts\n * @Controller('sessions/:sessionId/channels')\n * export class ChannelsController {\n * @Get(':channelId')\n * @ApiOperation({ summary: 'Get a specific channel by ID' })\n * @ApiParam({ name: 'sessionId', description: 'Session ID' })\n * @ApiParam({ name: 'channelId', description: 'Channel ID' })\n * @Mcp()\n * findOne(@Param('sessionId') sessionId: string, @Param('channelId') channelId: string) {\n * return this.service.get(sessionId, channelId)\n * }\n * }\n * ```\n */\nexport function Mcp(options: McpMetadata = {}): MethodDecorator {\n return SetMetadata(MCP_METADATA, options)\n}\n","import { SetMetadata } from '@nestjs/common'\nimport { TRPC_METADATA, type TrpcMetadata } from '../lib/metadata.js'\n\n/**\n * Method decorator that exposes a NestJS controller route as a **tRPC\n * procedure** - the sibling of `@Mcp`. Like `@Mcp` it is additive and reflects\n * the procedure's input from the method's own metadata (route + `@Param`/\n * `@Query`/`@Body` + swagger/class-validator), so a single method can carry both\n * `@Trpc()` and `@Mcp()` and `@UseGuards()`.\n *\n * Two things differ from MCP because tRPC consumers need them:\n * - **kind** - inferred from the route (`@Get` ⇒ query, others ⇒ mutation) or an\n * `async *` body (⇒ subscription); override with `@Trpc({ kind })`.\n * - **output** - the generated `AppRouter` carries precise output types. Drive\n * them with `@ApiOkResponse({ type: Dto })` reflection or `@Trpc({ output })`.\n *\n * `@Trpc()` works **without** an HTTP-verb decorator: with no `@Get`/`@Post` the\n * route is never mapped as REST, so `@Trpc({ kind })` exposes it over tRPC (and\n * `@Mcp` over MCP) while keeping it off the public REST surface.\n *\n * @example\n * ```ts\n * @Controller('users')\n * export class UsersController {\n * @Get('list-by-space')\n * @ApiOperation({ summary: 'List users in a space' })\n * @ApiOkResponse({ type: ListUsersResponse }) // drives the output type\n * @UseGuards(AuthGuard)\n * @Trpc() // → procedure `usersListBySpace` (query)\n * @Mcp() // → MCP tool `UsersListBySpace`\n * listBySpace(@Query() q: ListBySpaceQuery, @Req() req: AppRequest) {\n * return this.service.list(req.user, q.spaceId)\n * }\n * }\n * ```\n */\nexport function Trpc(options: TrpcMetadata = {}): MethodDecorator {\n return SetMetadata(TRPC_METADATA, options)\n}\n","import type { ArgumentsHost, ContextType, ExecutionContext, Type } from '@nestjs/common'\n\n/** Subset of `HttpArgumentsHost` we need - re-declared inline to avoid deep `@nestjs/common/interfaces` imports. */\ninterface HttpHost {\n getRequest<T = unknown>(): T\n getResponse<T = unknown>(): T\n getNext<T = unknown>(): T\n}\n\ninterface RpcHost {\n getData<T = unknown>(): T\n getContext<T = unknown>(): T\n}\n\ninterface WsHost {\n getClient<T = unknown>(): T\n getData<T = unknown>(): T\n getPattern(): string\n}\n\n/**\n * Minimal `ExecutionContext` impl Nest guards can consume. We only need\n * `switchToHttp()` to work for our HTTP-backed transports; the RPC/WS shims are\n * stubbed so guards that introspect type can still call them without crashing.\n */\nexport class SilkweaveExecutionContext implements ExecutionContext, ArgumentsHost {\n constructor(\n private readonly args: unknown[],\n private readonly classRef: Type<unknown>,\n private readonly handler: (...handlerArgs: unknown[]) => unknown,\n private readonly contextType = 'http'\n ) { }\n\n getType<T extends string = ContextType>(): T {\n return this.contextType as T\n }\n\n getClass<T = unknown>(): Type<T> {\n return this.classRef as Type<T>\n }\n\n getHandler(): (...handlerArgs: unknown[]) => unknown {\n return this.handler\n }\n\n getArgs<T extends unknown[] = unknown[]>(): T {\n return this.args as T\n }\n\n getArgByIndex<T = unknown>(index: number): T {\n return this.args[index] as T\n }\n\n switchToHttp(): HttpHost {\n return {\n getRequest: <T = unknown>(): T => this.args[0] as T,\n getResponse: <T = unknown>(): T => this.args[1] as T,\n getNext: <T = unknown>(): T => this.args[2] as T\n }\n }\n\n switchToRpc(): RpcHost {\n return {\n getData: <T = unknown>(): T => this.args[0] as T,\n getContext: <T = unknown>(): T => this.args[1] as T\n }\n }\n\n switchToWs(): WsHost {\n return {\n getClient: <T = unknown>(): T => this.args[0] as T,\n getData: <T = unknown>(): T => this.args[1] as T,\n getPattern: (): string => ''\n }\n }\n}\n","import { ForbiddenException, type CanActivate, type Type } from '@nestjs/common'\nimport { GUARDS_METADATA } from '@nestjs/common/constants.js'\nimport { ApplicationConfig, ModuleRef, Reflector } from '@nestjs/core'\nimport { isObservable, lastValueFrom } from 'rxjs'\nimport { SilkweaveExecutionContext } from './executionContext.js'\n\ntype GuardRef = Type<CanActivate> | CanActivate\n\n/**\n * Collect the app's global guards that match an opt-in allow-list of classes.\n *\n * Reads both registration styles Nest exposes via `ApplicationConfig`:\n * `useGlobalGuards(new X())` instances (`getGlobalGuards()`) and\n * `{ provide: APP_GUARD, useClass }` DI guards (`getGlobalRequestGuards()`,\n * which yields `InstanceWrapper`s - we read `.instance` off each).\n *\n * The allow-list is intentionally explicit-by-class: a blanket \"run every\n * global\" would also fire unrelated globals (e.g. a `ThrottlerGuard` that\n * assumes a writable response) on every tool call. An empty allow-list runs\n * no globals, preserving the prior behavior.\n *\n * Call this at tool-call time, not at discovery time: `APP_GUARD` instances\n * aren't populated until `app.init()` finishes.\n */\nexport function collectGlobalGuards(\n appConfig: ApplicationConfig,\n allowList: Type<CanActivate>[]\n): CanActivate[] {\n if (allowList.length === 0) { return [] }\n const globals: CanActivate[] = [\n ...appConfig.getGlobalGuards(),\n ...appConfig.getGlobalRequestGuards().map((w) => w.instance)\n ].filter((g): g is CanActivate => g != null)\n return globals.filter((g) => allowList.some((c) => g instanceof c))\n}\n\n/**\n * Read `@UseGuards(...)` metadata for both the method and its class and merge\n * the two lists. Method-level guards run AFTER class-level guards (matching\n * Nest's own behavior).\n */\nexport function collectGuards(\n reflector: Reflector,\n classRef: Type<unknown>,\n handler: (...args: unknown[]) => unknown\n): GuardRef[] {\n const classGuards = reflector.get<GuardRef[]>(GUARDS_METADATA, classRef) ?? []\n const methodGuards = reflector.get<GuardRef[]>(GUARDS_METADATA, handler) ?? []\n return [...classGuards, ...methodGuards]\n}\n\nasync function resolveGuard(ref: GuardRef, moduleRef: ModuleRef): Promise<CanActivate> {\n if (typeof ref === 'function') {\n try {\n return await moduleRef.get(ref, { strict: false })\n } catch {\n return moduleRef.create(ref)\n }\n }\n return ref\n}\n\n/**\n * Run the configured guards against a request. Throws `ForbiddenException`\n * if any guard rejects, mirroring Nest's HTTP request-pipeline behavior.\n *\n * Pass `null` for `response` when running on top of a tRPC or MCP request that\n * doesn't surface a raw response object; guards that introspect the response\n * will receive `null`.\n *\n * `contextType` is reflected through `ExecutionContext.getType()` so guards can\n * branch on the transport. It is `'http'` for REST/tRPC and for MCP-over-HTTP\n * (where a header-bearing request stand-in is available); transports without any\n * HTTP request (e.g. MCP stdio) pass `'rpc'`.\n */\nexport async function runGuards(\n guards: GuardRef[],\n moduleRef: ModuleRef,\n reflector: Reflector,\n classRef: Type<unknown>,\n handler: (...args: unknown[]) => unknown,\n request: unknown,\n response: unknown,\n contextType: 'http' | 'rpc' = 'http'\n): Promise<void> {\n if (guards.length === 0) { return }\n const context = new SilkweaveExecutionContext([request, response], classRef, handler, contextType)\n for (const ref of guards) {\n const guard = await resolveGuard(ref, moduleRef)\n const result = guard.canActivate(context)\n const allowed = isObservable(result) ? await lastValueFrom(result) : await Promise.resolve(result)\n if (!allowed) {\n throw new ForbiddenException('Forbidden resource')\n }\n }\n // Reflector kept in the signature for future use (e.g., per-guard metadata) - unused here.\n void reflector\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { ROUTE_ARGS_METADATA } from '@nestjs/common/constants.js'\n\n/**\n * `RouteParamtypes` numeric values from `@nestjs/common` (re-declared to avoid a\n * value import of an internal enum). These are how `@Param`/`@Query`/`@Body`/...\n * tag each handler argument in `ROUTE_ARGS_METADATA`.\n */\nexport const PARAMTYPE = {\n REQUEST: 0,\n RESPONSE: 1,\n NEXT: 2,\n BODY: 3,\n QUERY: 4,\n PARAM: 5,\n HEADERS: 6,\n SESSION: 7,\n FILE: 8,\n FILES: 9,\n HOST: 10,\n IP: 11,\n RAW_BODY: 12\n} as const\n\nexport interface ParamSlot {\n /** `PARAMTYPE` value - which decorator tagged this argument. */\n paramtype: number\n /** Handler argument position. */\n index: number\n /** Decorator sub-key: `@Param('id')` → `'id'`; a bare `@Body()` → `undefined`. */\n data?: string\n /** Parameter-bound pipes (`@Param('id', ParseIntPipe)`). */\n pipes: unknown[]\n /** TypeScript-emitted constructor at this position (e.g. `String`, `CreateDto`). */\n designType?: unknown\n}\n\n/**\n * Read and normalise the route-argument metadata for a controller method.\n * Returns one {@link ParamSlot} per decorated handler argument, sorted by\n * argument index.\n */\nexport function readParamSlots(classRef: any, methodName: string, proto: any): ParamSlot[] {\n const raw = Reflect.getMetadata(ROUTE_ARGS_METADATA, classRef, methodName) as\n Record<string, { index: number; data?: unknown; pipes?: unknown[] }> | undefined\n if (!raw) { return [] }\n const designTypes = (Reflect.getMetadata('design:paramtypes', proto, methodName) as unknown[] | undefined) ?? []\n\n const slots: ParamSlot[] = []\n for (const key of Object.keys(raw)) {\n const entry = raw[key]\n const paramtype = Number(key.split(':')[0])\n if (Number.isNaN(paramtype)) { continue }\n slots.push({\n paramtype,\n index: entry.index,\n data: typeof entry.data === 'string' ? entry.data : undefined,\n pipes: entry.pipes ?? [],\n designType: designTypes[entry.index]\n })\n }\n return slots.sort((a, b) => a.index - b.index)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */\nimport { PARAMTYPE } from './reflect/params.js'\n\n/**\n * Instruction for reconstructing one positional handler argument from the flat\n * MCP tool input. Built at discovery time, consumed by {@link invokeRebound}.\n */\nexport type Binding =\n | { kind: 'value'; field: string; source: 'path' | 'query' | 'body'; metatype?: unknown; pipes?: unknown[] }\n | { kind: 'object'; source: 'query' | 'body'; fields: string[]; metatype?: unknown; pipes?: unknown[] }\n | { kind: 'params'; fields: string[] }\n | { kind: 'request' }\n | { kind: 'response' }\n | { kind: 'headers'; data?: string }\n | { kind: 'ip' }\n | { kind: 'host'; data?: string }\n | { kind: 'missing' }\n\ninterface RequestLike {\n headers?: Record<string, unknown>\n ip?: unknown\n hosts?: Record<string, unknown>\n}\n\nfunction newInstance(P: any): any | null {\n try { return new P() } catch { return null }\n}\n\nasync function applyPipes(value: unknown, pipes: unknown[] | undefined, metatype: unknown, type: 'param' | 'query' | 'body', data: string | undefined): Promise<unknown> {\n if (!pipes || pipes.length === 0) { return value }\n let current = value\n for (const p of pipes) {\n const pipe = typeof p === 'function' ? newInstance(p) : p\n if (pipe && typeof (pipe).transform === 'function') {\n current = await (pipe).transform(current, { type, metatype, data })\n }\n }\n return current\n}\n\n/** Pick a subset of keys (skipping `undefined`) into a fresh object. */\nfunction pickFields(input: Record<string, unknown>, fields: string[]): Record<string, unknown> {\n const obj: Record<string, unknown> = {}\n for (const f of fields) {\n if (input[f] !== undefined) { obj[f] = input[f] }\n }\n return obj\n}\n\n/** Resolve a single positional argument from one binding. */\nasync function resolveArg(\n b: Binding,\n input: Record<string, unknown>,\n request: RequestLike | undefined,\n response: unknown,\n applyParamPipes: boolean\n): Promise<unknown> {\n switch (b.kind) {\n case 'value': {\n const raw = input[b.field]\n const type = b.source === 'path' ? 'param' : b.source\n return applyParamPipes ? applyPipes(raw, b.pipes, b.metatype, type, b.field) : raw\n }\n case 'object': {\n const obj = pickFields(input, b.fields)\n return applyParamPipes ? applyPipes(obj, b.pipes, b.metatype, b.source, undefined) : obj\n }\n case 'params':\n return pickFields(input, b.fields)\n case 'headers':\n return b.data ? request?.headers?.[b.data.toLowerCase()] : (request?.headers ?? {})\n case 'request':\n return request ?? { headers: {} }\n case 'response':\n // The real Express response over tRPC (so `@Res({ passthrough: true })`\n // can set cookies/headers); `undefined` over MCP (no HTTP response).\n return response\n case 'ip':\n return request?.ip\n case 'host':\n return b.data ? request?.hosts?.[b.data] : request?.hosts\n default:\n return undefined\n }\n}\n\n/**\n * Reconstruct the controller method's positional arguments from the validated\n * tool `input` (and the request stand-in for `@Req`/`@Headers`/...), then call\n * it. `applyParamPipes` controls whether parameter-bound pipes run.\n */\nexport async function invokeRebound(\n method: (...args: any[]) => any,\n instance: object,\n input: Record<string, unknown>,\n bindings: Binding[],\n request: RequestLike | undefined,\n response: unknown,\n applyParamPipes: boolean\n): Promise<unknown> {\n const args: unknown[] = []\n for (let i = 0; i < bindings.length; i += 1) {\n args[i] = await resolveArg(bindings[i], input, request, response, applyParamPipes)\n }\n return await method.apply(instance, args)\n}\n\n/** Map a non-input parameter slot (`@Req`/`@Headers`/`@Ip`/...) to its runtime binding. */\nexport function specialBinding(paramtype: number, data: string | undefined): Binding | null {\n switch (paramtype) {\n case PARAMTYPE.REQUEST: return { kind: 'request' }\n case PARAMTYPE.RESPONSE:\n case PARAMTYPE.NEXT: return { kind: 'response' }\n case PARAMTYPE.HEADERS: return { kind: 'headers', data }\n case PARAMTYPE.IP: return { kind: 'ip' }\n case PARAMTYPE.HOST: return { kind: 'host', data }\n case PARAMTYPE.SESSION:\n case PARAMTYPE.FILE:\n case PARAMTYPE.FILES:\n case PARAMTYPE.RAW_BODY: return { kind: 'missing' }\n default: return null\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */\nimport { createRequire } from 'node:module'\nimport { join } from 'node:path'\n\nlet cached: any | null | undefined\n\n/**\n * Lazily resolve the optional `class-validator` peer; `null` when not installed.\n * Resolution is attempted both from this package and from the app's working\n * directory - the latter is what finds it in a pnpm install where the optional\n * peer lives in the consumer app rather than alongside `@silkweave/nestjs`. A\n * pnpm-deduped install shares one physical copy, so the metadata singleton the\n * app's decorators wrote to is the same one we read.\n */\nfunction loadClassValidator(): any | null {\n if (cached !== undefined) { return cached }\n for (const base of [import.meta.url, join(process.cwd(), 'noop.js')]) {\n try {\n cached = createRequire(base)('class-validator')\n return cached\n } catch { /* try the next resolution base */ }\n }\n cached = null\n return cached\n}\n\nexport interface ValidationMeta {\n /** `ValidationTypes` discriminator (e.g. `customValidation`, `conditionalValidation`). */\n type?: string\n /** Validator name - the actionable identity for built-ins (`isString`, `minLength`, ...). */\n name?: string\n constraints?: unknown[]\n}\n\n/**\n * Read `class-validator` metadata for a DTO class, grouped by property name.\n * Returns an empty map when `class-validator` is not installed or the class\n * carries no validation decorators - so callers degrade gracefully to swagger /\n * `design:type` reflection.\n */\nexport function classValidatorMetas(dtoType: any): Record<string, ValidationMeta[]> {\n const cv = loadClassValidator()\n if (!cv?.getMetadataStorage) { return {} }\n let metas: Array<{ propertyName?: string; type?: string; name?: string; constraints?: unknown[] }>\n try {\n metas = cv.getMetadataStorage().getTargetValidationMetadatas(dtoType, null, false, false)\n } catch {\n return {}\n }\n const out: Record<string, ValidationMeta[]> = {}\n for (const m of metas) {\n if (!m.propertyName) { continue }\n (out[m.propertyName] ??= []).push({ type: m.type, name: m.name, constraints: m.constraints })\n }\n return out\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */\nimport { z } from 'zod/v4'\nimport { classValidatorMetas } from './classValidator.js'\n\n/** `@nestjs/swagger` reflect-metadata keys. Read directly so swagger stays an optional peer. */\nconst API_MODEL_PROPERTIES = 'swagger/apiModelProperties'\nconst API_MODEL_PROPERTIES_ARRAY = 'swagger/apiModelPropertiesArray'\n\n/**\n * A transport-neutral description of a single input field. Every metadata\n * source (swagger decorators, class-validator, an OpenAPI document, TypeScript\n * `design:type`) is mapped to this shape, the shapes are merged by precedence,\n * and the result is converted to Zod once. Keeping a single intermediate keeps\n * the per-source mappers small and the Zod construction in one place.\n */\nexport interface FieldDesc {\n type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'unknown'\n required?: boolean\n /** Field accepts `null` (`@ApiProperty({ nullable: true })` / OpenAPI `nullable`). */\n nullable?: boolean\n description?: string\n enum?: (string | number)[]\n items?: FieldDesc\n min?: number\n max?: number\n minLength?: number\n maxLength?: number\n format?: string\n default?: unknown\n}\n\n/** Strip `undefined` values so a later source never clobbers an earlier one with a hole. */\nfunction defined<T extends object>(obj: T): Partial<T> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) { out[k] = v }\n }\n return out as Partial<T>\n}\n\n/** Merge `over` onto `base` - defined keys of `over` win. */\nexport function mergeField(base: FieldDesc, over: FieldDesc): FieldDesc {\n return { ...base, ...defined(over) }\n}\n\nfunction enumToZod(values: (string | number)[]): z.ZodType {\n const strings = values.filter((v): v is string => typeof v === 'string')\n if (strings.length === values.length && strings.length > 0) {\n return z.enum(strings as [string, ...string[]])\n }\n const literals = values.map((v) => z.literal(v))\n if (literals.length === 0) { return z.unknown() }\n if (literals.length === 1) { return literals[0] }\n return z.union(literals as unknown as [z.ZodType, z.ZodType, ...z.ZodType[]])\n}\n\nfunction baseToZod(d: FieldDesc): z.ZodType {\n switch (d.type) {\n case 'string': {\n let s = z.string()\n if (d.minLength != null) { s = s.min(d.minLength) }\n if (d.maxLength != null) { s = s.max(d.maxLength) }\n return s\n }\n case 'integer':\n case 'number': {\n let n = z.number()\n if (d.type === 'integer') { n = n.int() }\n if (d.min != null) { n = n.min(d.min) }\n if (d.max != null) { n = n.max(d.max) }\n return n\n }\n case 'boolean':\n return z.boolean()\n case 'array':\n return z.array(d.items ? fieldToZod({ ...d.items, required: true }) : z.unknown())\n case 'object':\n return z.record(z.string(), z.unknown())\n default:\n return z.unknown()\n }\n}\n\n/** Convert a merged {@link FieldDesc} to a Zod schema. */\nexport function fieldToZod(d: FieldDesc): z.ZodType {\n let schema = (d.enum?.length) ? enumToZod(d.enum) : baseToZod(d)\n if (d.description) { schema = schema.describe(d.description) }\n if (d.nullable) { schema = schema.nullable() }\n if (d.default !== undefined) {\n schema = (schema as any).default(d.default)\n } else if (d.required === false) {\n schema = schema.optional()\n }\n return schema\n}\n\n// --- per-source mappers ---------------------------------------------------\n\n/** Normalise a TS-enum object or an array literal to a flat value list. */\nexport function normalizeEnum(value: unknown): (string | number)[] | undefined {\n if (Array.isArray(value)) {\n return value.filter((v): v is string | number => typeof v === 'string' || typeof v === 'number')\n }\n if (value && typeof value === 'object') {\n return Object.values(value).filter((v): v is string | number => typeof v === 'string' || typeof v === 'number')\n }\n return undefined\n}\n\n/** Map a swagger/`design:type` type token (constructor, `[Type]`, or string) to a base type. */\nexport function typeTokenToBase(type: unknown): FieldDesc['type'] | undefined {\n if (type == null) { return undefined }\n if (type === String) { return 'string' }\n if (type === Number) { return 'number' }\n if (type === Boolean) { return 'boolean' }\n if (type === Array) { return 'array' }\n if (type === Date) { return 'string' }\n if (Array.isArray(type)) { return 'array' }\n if (typeof type === 'string') {\n const t = type.toLowerCase()\n if (t === 'string' || t === 'number' || t === 'integer' || t === 'boolean' || t === 'array' || t === 'object') {\n return t\n }\n }\n return undefined\n}\n\n/** From the constructor TypeScript emits via `emitDecoratorMetadata`. */\nexport function designTypeToField(ctor: unknown): FieldDesc {\n const type = typeTokenToBase(ctor)\n const f: FieldDesc = {}\n if (type) { f.type = type }\n return f\n}\n\n/** From an `@ApiParam`/`@ApiQuery` entry stored under `swagger/apiParameters`. */\nexport function swaggerParamToField(p: Record<string, any>): FieldDesc {\n const f: FieldDesc = {}\n if (p['description']) { f.description = p['description'] }\n if (typeof p['required'] === 'boolean') { f.required = p['required'] }\n const type = typeTokenToBase(p['type'])\n if (type) { f.type = type }\n if (p['isArray']) { f.type = 'array' }\n const en = normalizeEnum(p['enum'])\n if (en) { f.enum = en }\n if (p['schema'] && typeof p['schema'] === 'object') {\n return mergeField(f, openapiSchemaToField(p['schema']))\n }\n return f\n}\n\n/** From an `@ApiProperty` options object stored under `swagger/apiModelProperties`. */\nexport function apiPropertyToField(o: Record<string, any>): FieldDesc {\n const f: FieldDesc = {}\n if (o['description']) { f.description = o['description'] }\n if (typeof o['required'] === 'boolean') { f.required = o['required'] }\n const type = typeTokenToBase(o['type'])\n if (type) { f.type = type }\n if (o['isArray']) {\n f.items = { type: type && type !== 'array' ? type : 'unknown' }\n f.type = 'array'\n }\n const en = normalizeEnum(o['enum'])\n if (en) { f.enum = en }\n if (o['minimum'] != null) { f.min = o['minimum'] }\n if (o['maximum'] != null) { f.max = o['maximum'] }\n if (o['minLength'] != null) { f.minLength = o['minLength'] }\n if (o['maxLength'] != null) { f.maxLength = o['maxLength'] }\n if (o['format']) { f.format = o['format'] }\n if (o['nullable'] === true) { f.nullable = true }\n if (o['default'] !== undefined) { f.default = o['default'] }\n return f\n}\n\n/** `class-validator` decorator type → field base type. */\nconst CV_TYPE: Record<string, FieldDesc['type']> = {\n isString: 'string',\n isInt: 'integer',\n isBoolean: 'boolean',\n isArray: 'array'\n}\n\n/** `class-validator` decorator type → numeric-constraint field key. */\nconst CV_NUMERIC: Record<string, 'min' | 'max' | 'minLength' | 'maxLength'> = {\n min: 'min',\n max: 'max',\n minLength: 'minLength',\n maxLength: 'maxLength'\n}\n\n/**\n * Fold one `class-validator` metadata entry into the field descriptor. Built-in\n * validators record their identity in `name` (`isString`, `minLength`, ...) with\n * `type: 'customValidation'`; `@IsOptional` uses `name: 'isOptional'`. We key off\n * `name`, falling back to `type`.\n */\nfunction applyValidationMeta(f: FieldDesc, meta: { type?: string; name?: string; constraints?: unknown[] }): void {\n const key = meta.name ?? meta.type\n if (!key) { return }\n if (key in CV_TYPE) { f.type = CV_TYPE[key]; return }\n const c0 = meta.constraints?.[0]\n if (key in CV_NUMERIC) {\n if (typeof c0 === 'number') { f[CV_NUMERIC[key]] = c0 }\n return\n }\n if (key === 'isNumber') { if (!f.type) { f.type = 'number' } return }\n if (key === 'isEmail') { if (!f.type) { f.type = 'string' } f.format = 'email'; return }\n if (key === 'isDate' || key === 'isDateString') { f.type = 'string'; f.format = 'date-time'; return }\n if (key === 'isEnum') { const e = normalizeEnum(c0); if (e) { f.enum = e } return }\n if (key === 'isOptional') { f.required = false }\n}\n\n/** From an array of `class-validator` validation-metadata entries for one property. */\nexport function classValidatorToField(metas: Array<{ type?: string; name?: string; constraints?: unknown[] }>): FieldDesc {\n const f: FieldDesc = {}\n for (const meta of metas) { applyValidationMeta(f, meta) }\n return f\n}\n\n/** From an OpenAPI Schema Object (used by both the doc and `@ApiParam({ schema })`). */\nexport function openapiSchemaToField(schema: Record<string, any>): FieldDesc {\n const f: FieldDesc = {}\n const type = typeof schema['type'] === 'string' ? schema['type'].toLowerCase() : undefined\n if (type === 'string' || type === 'number' || type === 'integer' || type === 'boolean' || type === 'array' || type === 'object') {\n f.type = type\n }\n if (schema['description']) { f.description = schema['description'] }\n const en = normalizeEnum(schema['enum'])\n if (en) { f.enum = en }\n if (schema['minimum'] != null) { f.min = schema['minimum'] }\n if (schema['maximum'] != null) { f.max = schema['maximum'] }\n if (schema['minLength'] != null) { f.minLength = schema['minLength'] }\n if (schema['maxLength'] != null) { f.maxLength = schema['maxLength'] }\n if (schema['format']) { f.format = schema['format'] }\n if (schema['nullable'] === true) { f.nullable = true }\n if (schema['default'] !== undefined) { f.default = schema['default'] }\n if (schema['items'] && typeof schema['items'] === 'object') {\n f.items = openapiSchemaToField(schema['items'])\n }\n return f\n}\n\n/**\n * Reflect a whole-DTO class (`@Body() dto: CreateDto`) into per-property\n * {@link FieldDesc}s. Property names are the union of `@ApiProperty` and\n * `class-validator` decorated fields; each field merges `design:type` (base),\n * then `class-validator` constraints, then `@ApiProperty` (highest). Properties\n * default to required unless a source marks them optional.\n */\nexport function reflectDtoFields(dtoType: any): Record<string, FieldDesc> {\n const proto = dtoType?.prototype\n if (!proto) { return {} }\n const cvMetas = classValidatorMetas(dtoType)\n\n const names = new Set<string>()\n const swaggerArray = (Reflect.getMetadata(API_MODEL_PROPERTIES_ARRAY, proto) as string[] | undefined) ?? []\n for (const entry of swaggerArray) { names.add(entry.replace(/^:/, '')) }\n for (const name of Object.keys(cvMetas)) { names.add(name) }\n\n const out: Record<string, FieldDesc> = {}\n for (const name of names) {\n let f = designTypeToField(Reflect.getMetadata('design:type', proto, name))\n if (cvMetas[name]) { f = mergeField(f, classValidatorToField(cvMetas[name])) }\n const apiProp = Reflect.getMetadata(API_MODEL_PROPERTIES, proto, name) as Record<string, any> | undefined\n if (apiProp) {\n const fromApi = apiPropertyToField(apiProp)\n // `@ApiProperty` is required unless `required: false` is explicit.\n if (fromApi.required === undefined && apiProp['required'] === undefined) { fromApi.required = true }\n f = mergeField(f, fromApi)\n }\n if (f.required === undefined) { f.required = true }\n out[name] = f\n }\n return out\n}\n\n/**\n * Names of fields that could not be reflected into a concrete type - they will\n * become `z.unknown()` (or `z.array(z.unknown())`). This is how a nested DTO or a\n * `Dto[]` property silently degrades (reflection is one level deep), so the\n * adapters surface these as a build-time warning pointing at `@Trpc({ output })`\n * / `@Mcp({ input })`. Enum and `object` (record) fields are not degraded.\n */\nexport function unreflectedFields(fields: Record<string, FieldDesc>): string[] {\n const out: string[] = []\n for (const [name, f] of Object.entries(fields)) {\n if (f.enum?.length) { continue }\n if (!f.type || f.type === 'unknown') { out.push(name) } else if (f.type === 'array' && (!f.items?.type || f.items.type === 'unknown')) { out.push(name) }\n }\n return out\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */\nimport { type FieldDesc, mergeField, openapiSchemaToField } from './schema.js'\n\n/**\n * A minimal view of an OpenAPI document - the subset we read. Matches the shape\n * `SwaggerModule.createDocument()` returns, but typed loosely so callers can\n * pass any compatible object without a hard `@nestjs/swagger` dependency.\n */\nexport interface OpenApiDocument {\n paths?: Record<string, Record<string, any>>\n components?: { schemas?: Record<string, any> }\n}\n\nexport interface OpenApiLookup {\n doc: OpenApiDocument\n /** `${METHOD} ${path}` → operation object. */\n operations: Map<string, any>\n}\n\n/** Index a document's operations by `${METHOD} ${path}` for fast matching. */\nexport function buildOpenApiLookup(doc: OpenApiDocument): OpenApiLookup {\n const operations = new Map<string, any>()\n for (const [path, item] of Object.entries(doc.paths ?? {})) {\n for (const [verb, op] of Object.entries(item ?? {})) {\n operations.set(`${verb.toUpperCase()} ${path}`, op)\n }\n }\n return { doc, operations }\n}\n\n/** Locate the operation for a route, tolerating a global path prefix on the document side. */\nfunction findOperation(lookup: OpenApiLookup, method: string, openapiPath: string): any | undefined {\n const exact = lookup.operations.get(`${method} ${openapiPath}`)\n if (exact) { return exact }\n // Fall back to a suffix match so a `setGlobalPrefix('api')` document still resolves.\n for (const [key, op] of lookup.operations) {\n const [verb, path] = key.split(' ')\n if (verb === method && (path.endsWith(openapiPath) || openapiPath.endsWith(path))) { return op }\n }\n return undefined\n}\n\nfunction resolveRef(doc: OpenApiDocument, schema: any): any {\n let current = schema\n let guard = 0\n while (current && typeof current === 'object' && typeof current['$ref'] === 'string' && guard < 10) {\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(current['$ref'])\n if (!match) { break }\n current = doc.components?.schemas?.[match[1]]\n guard += 1\n }\n return current\n}\n\n/**\n * Resolve the per-field descriptors for a route from an ingested OpenAPI\n * document. Merges `parameters` (path/query/header) and the JSON request-body\n * schema's properties into a single field map. Returns `{}` when the operation\n * isn't found - callers fall back to decorator reflection.\n */\nexport function openApiFields(lookup: OpenApiLookup, method: string, openapiPath: string): Record<string, FieldDesc> {\n const op = findOperation(lookup, method, openapiPath)\n if (!op) { return {} }\n const out: Record<string, FieldDesc> = {}\n\n for (const param of (op['parameters'] as Array<Record<string, any>> | undefined) ?? []) {\n const name = typeof param['name'] === 'string' ? param['name'] : undefined\n if (!name) { continue }\n const schema = param['schema'] ? resolveRef(lookup.doc, param['schema']) : undefined\n let field = schema ? openapiSchemaToField(schema) : {}\n if (param['description']) { field = mergeField(field, { description: param['description'] }) }\n if (typeof param['required'] === 'boolean') { field = mergeField(field, { required: param['required'] }) }\n out[name] = field\n }\n\n const bodySchema = resolveRef(lookup.doc, op['requestBody']?.['content']?.['application/json']?.['schema'])\n if (bodySchema && typeof bodySchema === 'object' && bodySchema['properties']) {\n const required = new Set<string>(Array.isArray(bodySchema['required']) ? bodySchema['required'] : [])\n for (const [name, propSchema] of Object.entries(bodySchema['properties'] as Record<string, any>)) {\n const field = openapiSchemaToField(resolveRef(lookup.doc, propSchema))\n field.required = required.has(name)\n out[name] = field\n }\n }\n\n return out\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from 'zod/v4'\nimport { type FieldDesc, fieldToZod, reflectDtoFields } from './schema.js'\n\n/** `@nestjs/swagger` response metadata key (read directly - swagger is an optional peer). */\nconst API_RESPONSE = 'swagger/apiResponse'\n\n/** Status keys we treat as the \"success\" response, in preference order. */\nconst SUCCESS_KEYS = ['200', '201', '202', '204', '2XX', 'default']\n\n/** The 2xx (or first) `@ApiResponse` entry for a method, if any. */\nfunction successEntry(method: (...args: any[]) => any): { type?: unknown; isArray?: boolean } | undefined {\n const responses = Reflect.getMetadata(API_RESPONSE, method) as Record<string, { type?: unknown; isArray?: boolean }> | undefined\n if (!responses) { return undefined }\n const key = SUCCESS_KEYS.find((k) => responses[k]) ?? Object.keys(responses)[0]\n return key ? responses[key] : undefined\n}\n\n/**\n * Reflect a `@Trpc` procedure's output schema from the method's\n * `@ApiOkResponse({ type: Dto })` (or any 2xx `@ApiResponse`) metadata. The\n * response DTO is flattened with {@link reflectDtoFields} into a Zod object,\n * wrapped in `z.array(...)` when the response is `isArray`.\n *\n * Returns `undefined` when there is no response DTO to reflect (e.g. a primitive\n * return type or no `@ApiResponse` decorator) - the caller then falls back to an\n * explicit `@Trpc({ output })` or an `unknown` output type.\n */\nexport function reflectResponseSchema(method: (...args: any[]) => any): z.ZodType | undefined {\n const entry = successEntry(method)\n const dtoType = entry?.type\n if (typeof dtoType !== 'function') { return undefined }\n\n const schema = reflectDtoSchema(dtoType)\n if (!schema) { return undefined }\n return entry?.isArray ? z.array(schema) : schema\n}\n\n/**\n * The reflected `FieldDesc` map for a method's response DTO (the same fields\n * {@link reflectResponseSchema} builds its schema from), or `undefined` when\n * there is no DTO to reflect. Used to detect fields that degraded to `unknown`\n * (nested DTO / `Dto[]`) so the caller can warn.\n */\nexport function reflectResponseFields(method: (...args: any[]) => any): Record<string, FieldDesc> | undefined {\n const dtoType = successEntry(method)?.type\n if (typeof dtoType !== 'function') { return undefined }\n return reflectDtoFields(dtoType)\n}\n\n/**\n * Reflect a DTO class (its `@ApiProperty`/`class-validator`-decorated properties)\n * into a Zod object schema. Returns `undefined` when the type isn't a class or\n * has no reflectable properties. Used for `@Trpc({ output })`/`@Trpc({ chunk })`\n * when given a DTO class instead of a Zod schema.\n */\nexport function reflectDtoSchema(dtoType: unknown): z.ZodType | undefined {\n if (typeof dtoType !== 'function') { return undefined }\n const fields = reflectDtoFields(dtoType)\n const names = Object.keys(fields)\n if (names.length === 0) { return undefined }\n const shape: Record<string, z.ZodType> = {}\n for (const name of names) { shape[name] = fieldToZod(fields[name]) }\n return z.object(shape)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { PATH_METADATA, METHOD_METADATA } from '@nestjs/common/constants.js'\n\n/**\n * `RequestMethod` numeric values (from `@nestjs/common`) mapped to verbs. We\n * map our own table rather than importing the enum to avoid pulling a value\n * import for a handful of constants.\n */\nconst REQUEST_METHOD: Record<number, string> = {\n 0: 'GET',\n 1: 'POST',\n 2: 'PUT',\n 3: 'DELETE',\n 4: 'PATCH',\n 6: 'OPTIONS',\n 7: 'HEAD'\n}\n\nexport interface RouteInfo {\n /** HTTP verb (`GET`/`POST`/...). `PATCH` and others outside the REST set fall back to `POST`-ish handling by callers. */\n method: string\n /** Full route template in Nest form, e.g. `sessions/:sessionId/channels/:channelId` (no leading slash). */\n path: string\n /** Full route template in OpenAPI form, e.g. `/sessions/{sessionId}/channels/{channelId}`. */\n openapiPath: string\n /** Names of the `:param` placeholders across controller + method path. */\n pathParams: string[]\n}\n\nfunction normalizeSegment(value: unknown): string {\n if (typeof value !== 'string') { return '' }\n return value.replace(/^\\/+/, '').replace(/\\/+$/, '')\n}\n\nfunction joinPath(...segments: string[]): string {\n return segments.map(normalizeSegment).filter(Boolean).join('/')\n}\n\n/**\n * Resolve the composed route (controller prefix + method path), HTTP verb, and\n * path-param names for a decorated controller method, reading Nest's own\n * `PATH_METADATA`/`METHOD_METADATA` reflection.\n */\nexport function reflectRoute(classRef: any, method: (...args: any[]) => any): RouteInfo {\n const classPath = Reflect.getMetadata(PATH_METADATA, classRef) as string | string[] | undefined\n const methodPath = Reflect.getMetadata(PATH_METADATA, method) as string | string[] | undefined\n const verbCode = Reflect.getMetadata(METHOD_METADATA, method) as number | undefined\n\n const classSeg = Array.isArray(classPath) ? (classPath[0] ?? '') : (classPath ?? '')\n const methodSeg = Array.isArray(methodPath) ? (methodPath[0] ?? '') : (methodPath ?? '')\n const path = joinPath(classSeg, methodSeg)\n const httpMethod = REQUEST_METHOD[verbCode ?? 0] ?? 'GET'\n\n const pathParams = [...path.matchAll(/:([A-Za-z0-9_]+)/g)].map((m) => m[1])\n const openapiPath = `/${path.replace(/:([A-Za-z0-9_]+)/g, '{$1}')}`\n\n return { method: httpMethod, path, openapiPath, pathParams }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { FieldDesc } from './schema.js'\nimport { swaggerParamToField } from './schema.js'\n\n/** `@nestjs/swagger` reflect-metadata keys (read directly - swagger is an optional peer). */\nconst API_OPERATION = 'swagger/apiOperation'\nconst API_PARAMETERS = 'swagger/apiParameters'\n\nexport interface OperationMeta {\n /** Tool-description candidate from `@ApiOperation({ summary | description })`. */\n description?: string\n /** Per-name `FieldDesc` reflected from `@ApiParam`/`@ApiQuery` entries. */\n params: Record<string, FieldDesc>\n}\n\n/**\n * Read operation-level `@nestjs/swagger` metadata off a controller method:\n * `@ApiOperation` (summary/description) and the `@ApiParam`/`@ApiQuery` array\n * (each describing one path/query field). Returns empty data when swagger\n * decorators are absent.\n */\nexport function reflectOperation(method: (...args: any[]) => any): OperationMeta {\n const operation = Reflect.getMetadata(API_OPERATION, method) as Record<string, any> | undefined\n const description = operation\n ? (typeof operation['summary'] === 'string' && operation['summary']\n ? operation['summary']\n : (typeof operation['description'] === 'string' ? operation['description'] : undefined))\n : undefined\n\n const parameters = (Reflect.getMetadata(API_PARAMETERS, method) as Array<Record<string, any>> | undefined) ?? []\n const params: Record<string, FieldDesc> = {}\n for (const p of parameters) {\n const name = typeof p['name'] === 'string' ? p['name'] : undefined\n if (!name) { continue }\n params[name] = swaggerParamToField(p)\n }\n\n return { description, params }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { HttpException, Injectable, Logger, type CanActivate, type Type } from '@nestjs/common'\nimport { ApplicationConfig, DiscoveryService, MetadataScanner, ModuleRef, Reflector } from '@nestjs/core'\nimport { SilkweaveError, type Action, type ActionKind, type SilkweaveContext } from '@silkweave/core'\nimport { z } from 'zod/v4'\nimport { collectGlobalGuards, collectGuards, runGuards } from './guards.js'\nimport { MCP_METADATA, TRPC_METADATA, type McpMetadata, type TrpcMetadata } from './metadata.js'\nimport { invokeRebound, specialBinding, type Binding } from './rebind.js'\nimport { buildOpenApiLookup, openApiFields, type OpenApiDocument, type OpenApiLookup } from './reflect/openapi.js'\nimport { PARAMTYPE, type ParamSlot, readParamSlots } from './reflect/params.js'\nimport { reflectDtoSchema, reflectResponseFields, reflectResponseSchema } from './reflect/response.js'\nimport { reflectRoute, type RouteInfo } from './reflect/route.js'\nimport { type FieldDesc, fieldToZod, mergeField, reflectDtoFields, unreflectedFields } from './reflect/schema.js'\nimport { reflectOperation } from './reflect/swagger.js'\n\n/** Discovery-time diagnostics (unreflectable params, degraded outputs). */\nconst logger = new Logger('Silkweave')\n\ninterface Discovered {\n instance: object\n classRef: Type<unknown>\n method: (...args: unknown[]) => unknown\n methodName: string\n mcp?: McpMetadata\n trpc?: TrpcMetadata\n}\n\ninterface BuiltInput {\n shape: Record<string, z.ZodType>\n bindings: Binding[]\n /** Human-readable notes about params reflection could not turn into fields. */\n warnings: string[]\n}\n\n/** Shared reflection computed once per discovered method, reused across targets. */\ninterface Reflected {\n route: RouteInfo\n base: string\n description?: string\n baseShape: Record<string, z.ZodType>\n bindings: Binding[]\n guards: ReturnType<typeof collectGuards>\n pathFields: string[]\n streaming: boolean\n}\n\nexport interface DiscoverOptions {\n openapi?: OpenApiDocument\n globalGuards?: Type<CanActivate>[]\n defaultResult?: 'json' | 'smart'\n}\n\n@Injectable()\nexport class ControllerDiscovery {\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly scanner: MetadataScanner,\n private readonly reflector: Reflector,\n private readonly moduleRef: ModuleRef,\n private readonly appConfig: ApplicationConfig\n ) { }\n\n /**\n * Walk every Nest provider/controller, find methods annotated with `@Mcp`\n * and/or `@Trpc`, and build a core `Action` per decorator present on each\n * method. The input schema is reflected from the route + parameter decorators\n * (+ optional OpenAPI document) and the `run` re-binds the validated input back\n * into the method's positional arguments (with `@UseGuards` guards applied\n * first). A method carrying both decorators yields two actions - one gated to\n * the `mcp` adapter, one to the `trpc`/`typegen` adapters - sharing the same\n * reflected input, bindings, and guards.\n */\n discover(options: DiscoverOptions = {}): Action[] {\n const lookup = options.openapi ? buildOpenApiLookup(options.openapi) : undefined\n const discovered: Discovered[] = []\n for (const wrapper of this.discovery.getProviders().concat(this.discovery.getControllers())) {\n const { instance } = wrapper\n if (!instance || typeof instance !== 'object') { continue }\n const proto = Object.getPrototypeOf(instance) as object | null\n if (!proto) { continue }\n const classRef = instance.constructor as Type<unknown>\n for (const methodName of this.scanner.getAllMethodNames(proto)) {\n const method = (proto as Record<string, unknown>)[methodName] as ((...args: unknown[]) => unknown) | undefined\n if (typeof method !== 'function') { continue }\n const mcp = this.reflector.get<McpMetadata>(MCP_METADATA, method)\n const trpc = this.reflector.get<TrpcMetadata>(TRPC_METADATA, method)\n if (!mcp && !trpc) { continue }\n discovered.push({ instance, classRef, method, methodName, mcp, trpc })\n }\n }\n\n const globalGuards = options.globalGuards ?? []\n const actions: Action[] = []\n for (const d of discovered) {\n const shared = this.reflect(d, lookup)\n if (d.mcp) { actions.push(this.mcpAction(d, shared, globalGuards, options.defaultResult)) }\n if (d.trpc) { actions.push(this.trpcAction(d, shared, globalGuards)) }\n }\n return actions\n }\n\n /** Compute the per-method reflection shared by the `mcp` and `trpc` builders. */\n private reflect(d: Discovered, lookup: OpenApiLookup | undefined): Reflected {\n const proto = Object.getPrototypeOf(d.instance) as object\n const route = reflectRoute(d.classRef, d.method)\n const slots = readParamSlots(d.classRef, d.methodName, proto)\n const operation = reflectOperation(d.method)\n const docFields = lookup ? openApiFields(lookup, route.method, route.openapiPath) : {}\n\n const { shape, bindings, warnings } = buildInput(proto, d.methodName, route.pathParams, slots, operation.params, docFields)\n for (const w of warnings) { logger.warn(`${d.classRef.name}.${d.methodName}: ${w}`) }\n\n return {\n route,\n base: d.classRef.name.replace(/Controller$/, ''),\n description: operation.description,\n baseShape: shape,\n bindings,\n guards: collectGuards(this.reflector, d.classRef, d.method),\n pathFields: pathParamFields(bindings),\n streaming: isAsyncGeneratorFn(d.method)\n }\n }\n\n /** Build a guard-application closure shared by both run shapes. */\n private guardRunner(d: Discovered, shared: Reflected, globalGuards: Type<CanActivate>[]) {\n const { moduleRef, reflector, appConfig } = this\n const { guards, pathFields } = shared\n const { classRef, method } = d\n return async (context: SilkweaveContext, input: object): Promise<void> => {\n // Resolved at call time - `APP_GUARD` instances aren't populated until\n // `app.init()` finishes. Globals run before the route/class guards.\n const all = [...collectGlobalGuards(appConfig, globalGuards), ...guards]\n if (all.length === 0) { return }\n const request = context.getOptional<unknown>('request')\n const response = context.getOptional<unknown>('response') ?? null\n const hasRequest = request != null\n const guardRequest = hasRequest ? request : { headers: {}, params: {}, query: {} }\n populatePathParams(guardRequest, pathFields, input as Record<string, unknown>)\n await runGuards(all, moduleRef, reflector, classRef, method, guardRequest, response, hasRequest ? 'http' : 'rpc')\n }\n }\n\n /** Synthesize the MCP-targeted action (unchanged behavior from v2.4). */\n private mcpAction(d: Discovered, shared: Reflected, globalGuards: Type<CanActivate>[], defaultResult?: 'json' | 'smart'): Action {\n const meta = d.mcp!\n const shape = { ...shared.baseShape, ...inputShape(meta.input) }\n const name = meta.name ?? `${shared.base}.${d.methodName}`\n const description = meta.description ?? shared.description ?? `${d.methodName} (${shared.route.method} /${shared.route.path})`\n const applyParamPipes = meta.pipes !== 'skip'\n const applyGuards = this.guardRunner(d, shared, globalGuards)\n const { method, instance } = d\n const { bindings, streaming } = shared\n\n return {\n name,\n description,\n input: z.object(shape),\n ...((meta.result ?? defaultResult) ? { disposition: meta.result ?? defaultResult } : {}),\n isEnabled: (ctx) => ctx.getOptional<string>('adapter') === 'mcp',\n ...(streaming\n ? { chunk: z.unknown(), run: streamingRun(applyGuards, method, instance, bindings, applyParamPipes, false) }\n : {\n run: async (input: object, context: SilkweaveContext): Promise<object> => {\n await applyGuards(context, input)\n const request = context.getOptional<{ headers?: Record<string, unknown> }>('request')\n const response = context.getOptional<unknown>('response')\n const result = await invokeRebound(method, instance, input as Record<string, unknown>, bindings, request, response, applyParamPipes)\n return result ?? {}\n }\n })\n } as Action\n }\n\n /** Synthesize the tRPC-targeted action (kind/output/subscription + httpStatus errors). */\n private trpcAction(d: Discovered, shared: Reflected, globalGuards: Type<CanActivate>[]): Action {\n const meta = d.trpc!\n const shape = { ...shared.baseShape, ...inputShape(meta.input) }\n const name = meta.name ?? `${shared.base}.${d.methodName}`\n const description = meta.description ?? shared.description ?? `${d.methodName} (${shared.route.method} /${shared.route.path})`\n const applyParamPipes = meta.pipes !== 'skip'\n const applyGuards = this.guardRunner(d, shared, globalGuards)\n const { method, instance } = d\n const { bindings, streaming } = shared\n\n // tRPC and typegen both consume `@Trpc` actions; MCP never does.\n const isEnabled = (ctx: SilkweaveContext): boolean => {\n const adapter = ctx.getOptional<string>('adapter')\n return adapter === 'trpc' || adapter === 'typegen'\n }\n\n if (streaming) {\n return {\n name,\n description,\n input: z.object(shape),\n chunk: resolveSchema(meta.chunk) ?? z.unknown(),\n isEnabled,\n run: streamingRun(applyGuards, method, instance, bindings, applyParamPipes, true)\n } as Action\n }\n\n const kind: ActionKind = meta.kind === 'query' || meta.kind === 'mutation'\n ? meta.kind\n : (shared.route.method === 'GET' ? 'query' : 'mutation')\n const output = resolveOutput(meta, method)\n\n // Reflection is one level deep, so a nested DTO or `Dto[]` output property\n // degrades to `unknown`/`unknown[]`. Surface it - the fix is `@Trpc({ output })`.\n const degraded = outputDegradedFields(meta, method)\n if (output && degraded.length > 0) {\n logger.warn(\n `${d.classRef.name}.${d.methodName}: tRPC output field(s) ${degraded.join(', ')} reflected to 'unknown' ` +\n '(nested DTO or Dto[] - reflection is one level deep). Supply @Trpc({ output }) with a Zod schema for precise types.'\n )\n }\n\n return {\n name,\n description,\n input: z.object(shape),\n ...(output ? { output } : {}),\n kind,\n isEnabled,\n run: async (input: object, context: SilkweaveContext): Promise<object> => {\n try {\n await applyGuards(context, input)\n const request = context.getOptional<{ headers?: Record<string, unknown> }>('request')\n const response = context.getOptional<unknown>('response')\n const result = await invokeRebound(method, instance, input as Record<string, unknown>, bindings, request, response, applyParamPipes)\n return result ?? {}\n } catch (error) {\n throw toSilkweaveError(error)\n }\n }\n } as Action\n }\n}\n\n/** Build a streaming (`async *`) run that applies guards then yields the method's chunks. */\nfunction streamingRun(\n applyGuards: (context: SilkweaveContext, input: object) => Promise<void>,\n method: (...args: unknown[]) => unknown,\n instance: object,\n bindings: Binding[],\n applyParamPipes: boolean,\n mapErrors: boolean\n) {\n return async function* (input: object, context: SilkweaveContext): AsyncGenerator<unknown, void, void> {\n try {\n await applyGuards(context, input)\n const request = context.getOptional<{ headers?: Record<string, unknown> }>('request')\n const response = context.getOptional<unknown>('response')\n const gen = await invokeRebound(method, instance, input as Record<string, unknown>, bindings, request, response, applyParamPipes) as AsyncIterable<unknown>\n for await (const chunk of gen) { yield chunk }\n } catch (error) {\n throw mapErrors ? toSilkweaveError(error) : error\n }\n }\n}\n\n/** Resolve a `@Trpc` action's output schema: explicit override wins over `@ApiOkResponse` reflection. */\nfunction resolveOutput(meta: TrpcMetadata, method: (...args: unknown[]) => unknown): z.ZodType | undefined {\n return resolveSchema(meta.output) ?? reflectResponseSchema(method)\n}\n\n/**\n * Output field names that reflected to `unknown` (nested DTO / `Dto[]`). Only the\n * reflected paths are inspected - an explicit Zod or raw-shape `@Trpc({ output })`\n * is the caller's own typing and is never flagged.\n */\nfunction outputDegradedFields(meta: TrpcMetadata, method: (...args: unknown[]) => unknown): string[] {\n if (meta.output != null && isZodSchema(meta.output)) { return [] }\n const fields = typeof meta.output === 'function'\n ? reflectDtoFields(meta.output)\n : meta.output != null ? undefined : reflectResponseFields(method)\n return fields ? unreflectedFields(fields) : []\n}\n\n/**\n * Normalise an `@Mcp`/`@Trpc({ input })` override to a raw Zod shape. Accepts a\n * plain `Record<string, ZodType>` or a whole `z.object({ ... })` (duck-typed by\n * `safeParse` + `shape`, so a different zod copy's object still unwraps).\n */\nfunction inputShape(input: McpMetadata['input']): Record<string, z.ZodType> {\n if (!input) { return {} }\n const maybe = input as { safeParse?: unknown; shape?: unknown }\n if (typeof maybe.safeParse === 'function' && maybe.shape != null && typeof maybe.shape === 'object') {\n return maybe.shape as Record<string, z.ZodType>\n }\n return input as Record<string, z.ZodType>\n}\n\n/**\n * Coerce an `output`/`chunk` override to a Zod schema: a Zod schema passes\n * through, a DTO class is reflected, and a raw shape is wrapped in `z.object`.\n */\nfunction resolveSchema(value: TrpcMetadata['output']): z.ZodType | undefined {\n if (value == null) { return undefined }\n if (isZodSchema(value)) { return value }\n if (typeof value === 'function') { return reflectDtoSchema(value) }\n return z.object(value)\n}\n\nfunction isZodSchema(value: unknown): value is z.ZodType {\n return Boolean(value) && typeof value === 'object' && typeof (value as { safeParse?: unknown }).safeParse === 'function'\n}\n\nfunction isAsyncGeneratorFn(fn: unknown): boolean {\n return typeof fn === 'function' && (fn as { constructor?: { name?: string } }).constructor?.name === 'AsyncGeneratorFunction'\n}\n\n/**\n * Convert a thrown Nest `HttpException` into a `SilkweaveError` carrying its HTTP\n * status, so the tRPC adapter's `mapError` maps it to the right `TRPCError` code\n * (and `data.httpStatus`) - e.g. a denying `AuthGuard`'s `UnauthorizedException`\n * surfaces to the client as a `401`. Non-HTTP errors pass through unchanged.\n */\nfunction toSilkweaveError(error: unknown): unknown {\n if (error instanceof HttpException) {\n const status = error.getStatus()\n const response = error.getResponse()\n const raw = typeof response === 'string'\n ? response\n : (response as { message?: unknown })?.message ?? error.message\n const message = Array.isArray(raw) ? raw.join(', ') : String(raw)\n return new SilkweaveError(message, 'http_error', status)\n }\n return error\n}\n\n/** Build the merged Zod input shape and the per-argument re-bind plan. */\nfunction buildInput(\n proto: object,\n methodName: string,\n pathParams: string[],\n slots: ReturnType<typeof readParamSlots>,\n operationParams: Record<string, FieldDesc>,\n docFields: Record<string, FieldDesc>\n): BuiltInput {\n const designTypes = (Reflect.getMetadata('design:paramtypes', proto, methodName) as unknown[] | undefined) ?? []\n const fields: Record<string, FieldDesc> = {}\n const warnings: string[] = []\n const maxIndex = slots.reduce((m, s) => Math.max(m, s.index), -1)\n const bindings: Binding[] = Array.from({ length: maxIndex + 1 }, () => ({ kind: 'missing' as const }))\n\n const addField = (name: string, desc: FieldDesc): void => {\n fields[name] = name in fields ? mergeField(fields[name], desc) : desc\n }\n\n for (const slot of slots) {\n const { binding, fields: contributed } = contributeSlot(slot, pathParams, designTypes)\n bindings[slot.index] = binding\n for (const [name, desc] of Object.entries(contributed)) { addField(name, desc) }\n // A whole-DTO `@Body()`/`@Query()` that reflected to zero fields: the type\n // was unreflectable (an interface, or an intersection/union TypeScript\n // erases to `Object`/`Array` under `design:type`). Its fields are silently\n // absent unless declared via `@Mcp`/`@Trpc({ input })`.\n if (binding.kind === 'object' && binding.fields.length === 0) {\n const typeName = (designTypes[slot.index] as { name?: string } | undefined)?.name ?? 'unknown'\n warnings.push(\n `whole-${binding.source} parameter #${slot.index} (type '${typeName}') reflected no input fields. ` +\n `If it is an intersection/union (e.g. 'A & B'), TypeScript erases it to '${typeName}' so the DTO is lost - ` +\n 'use a single DTO class or declare the fields via @Mcp/@Trpc({ input }).'\n )\n }\n }\n\n // Layer operation-level (`@ApiParam`/`@ApiQuery`) then OpenAPI-document\n // metadata over the structural fields (later sources win per field).\n for (const [name, desc] of Object.entries(operationParams)) {\n if (name in fields) { fields[name] = mergeField(fields[name], desc) }\n }\n for (const [name, desc] of Object.entries(docFields)) {\n if (name in fields) { fields[name] = mergeField(fields[name], desc) }\n }\n\n const shape: Record<string, z.ZodType> = {}\n for (const [name, desc] of Object.entries(fields)) { shape[name] = fieldToZod(desc) }\n\n return { shape, bindings, warnings }\n}\n\n/** Input field names that originate from the URL path (`@Param`), per the re-bind plan. */\nfunction pathParamFields(bindings: Binding[]): string[] {\n const fields: string[] = []\n for (const b of bindings) {\n if (b.kind === 'params') { fields.push(...b.fields) } else if (b.kind === 'value' && b.source === 'path') { fields.push(b.field) }\n }\n return fields\n}\n\n/**\n * Fill `request.params` with the reflected path fields from the validated input,\n * matching what Express would populate over REST (raw string values). Only adds\n * keys that are absent, so a real REST request's params are never overwritten.\n */\nfunction populatePathParams(request: unknown, pathFields: string[], input: Record<string, unknown>): void {\n if (pathFields.length === 0 || typeof request !== 'object' || request === null) { return }\n const params = ((request as { params?: Record<string, unknown> }).params ??= {})\n for (const field of pathFields) {\n if (!(field in params) && input[field] !== undefined) {\n params[field] = String(input[field])\n }\n }\n}\n\nfunction designTypeAt(designTypes: unknown[], index: number): FieldDesc {\n const ctor = designTypes[index]\n if (ctor === String) { return { type: 'string' } }\n if (ctor === Number) { return { type: 'number' } }\n if (ctor === Boolean) { return { type: 'boolean' } }\n return {}\n}\n\ninterface SlotContribution {\n binding: Binding\n /** Input fields this slot contributes, keyed by field name. */\n fields: Record<string, FieldDesc>\n}\n\n/** A `@Param('id')` scalar or a bare `@Param()` covering all path params. */\nfunction paramContribution(slot: ParamSlot, pathParams: string[]): SlotContribution {\n if (slot.data) {\n return {\n binding: { kind: 'value', field: slot.data, source: 'path', metatype: slot.designType, pipes: slot.pipes },\n fields: { [slot.data]: { type: 'string', required: true } }\n }\n }\n const fields: Record<string, FieldDesc> = {}\n for (const p of pathParams) { fields[p] = { type: 'string', required: true } }\n return { binding: { kind: 'params', fields: pathParams }, fields }\n}\n\n/** A `@Query('x')`/`@Body('x')` scalar or a whole-DTO `@Query()`/`@Body()`. */\nfunction bodyOrQueryContribution(slot: ParamSlot, source: 'query' | 'body', requiredScalar: boolean, designTypes: unknown[]): SlotContribution {\n if (slot.data) {\n return {\n binding: { kind: 'value', field: slot.data, source, metatype: slot.designType, pipes: slot.pipes },\n fields: { [slot.data]: mergeField(designTypeAt(designTypes, slot.index), { required: requiredScalar }) }\n }\n }\n const dtoFields = reflectDtoFields(slot.designType)\n return {\n binding: { kind: 'object', source, fields: Object.keys(dtoFields), metatype: slot.designType, pipes: slot.pipes },\n fields: dtoFields\n }\n}\n\n/** Map one parameter slot to its input-field contribution and re-bind instruction. */\nfunction contributeSlot(slot: ParamSlot, pathParams: string[], designTypes: unknown[]): SlotContribution {\n switch (slot.paramtype) {\n case PARAMTYPE.PARAM: return paramContribution(slot, pathParams)\n case PARAMTYPE.QUERY: return bodyOrQueryContribution(slot, 'query', false, designTypes)\n case PARAMTYPE.BODY: return bodyOrQueryContribution(slot, 'body', true, designTypes)\n default: return { binding: specialBinding(slot.paramtype, slot.data) ?? { kind: 'missing' }, fields: {} }\n }\n}\n","import type { CanActivate, Type } from '@nestjs/common'\nimport type { HttpAdapterHost } from '@nestjs/core'\nimport type { Action, SilkweaveContext, SilkweaveOptions } from '@silkweave/core'\nimport type { OpenApiDocument } from './reflect/openapi.js'\n\n/**\n * Context passed to a Nest Silkweave adapter when `SilkweaveModule` wires it\n * up. Adapters register their routes directly on `httpAdapter` (no\n * placeholder middleware, no `silkweave()` builder), so they only fire\n * `register()` once and own the rest of their lifecycle implicitly through\n * Nest.\n */\nexport interface NestAdapterRegisterContext {\n /** Nest's underlying HTTP adapter (Express or Fastify). */\n httpAdapter: NonNullable<HttpAdapterHost['httpAdapter']>\n /** Identity the adapter surfaces to clients (e.g. MCP server name). */\n silkweaveOptions: SilkweaveOptions\n /** Per-adapter context - already forked with `{ adapter: adapter.name, ...userContext }`. */\n baseContext: SilkweaveContext\n /** Actions filtered to those enabled on this adapter. */\n actions: Action[]\n}\n\n/**\n * A Silkweave Nest adapter. Each transport (REST, tRPC, MCP) implements this\n * shape. `register()` is called from `SilkweaveModule.configure()` - which\n * runs *before* Nest's controller routes are mapped - so adapter routes\n * always sit ahead of any catch-all controllers in the framework's request\n * pipeline.\n */\nexport interface NestSilkweaveAdapter {\n /** Adapter discriminator - set on the silkweave context as `ctx.get('adapter')`. */\n readonly name: 'mcp' | 'trpc' | 'typegen'\n /** URL prefix the adapter mounts on (e.g. `'/mcp'`). Surfaced for introspection. */\n readonly basePath?: string\n /**\n * When `true`, the adapter receives every discovered action regardless of\n * each action's `isEnabled` gate. Reserved for non-runtime adapters that need\n * the entire action surface.\n */\n readonly allActions?: boolean\n /** Register this adapter's routes on Nest's HTTP server. */\n register(ctx: NestAdapterRegisterContext): void\n}\n\nexport interface SilkweaveModuleOptions {\n /** Identity for the silkweave instance - surfaced to MCP clients, OpenAPI, etc. */\n silkweave: SilkweaveOptions\n /** Adapters to mount - any of `mcp()`, `trpc()`, `typegen()`. */\n adapters: NestSilkweaveAdapter[]\n /** Initial context keys merged into every adapter's `baseContext`. */\n context?: Record<string, unknown>\n /**\n * Optional OpenAPI document (e.g. from `SwaggerModule.createDocument(app, cfg)`)\n * used as an authoritative source when reflecting `@Mcp` tool input schemas.\n * Matched to each method by HTTP verb + path; falls back to decorator\n * reflection when an operation or field isn't present.\n */\n openapi?: OpenApiDocument\n /**\n * Opt-in allow-list of app-global guard classes (registered via\n * `app.useGlobalGuards()` or `{ provide: APP_GUARD, useClass }`) to run on\n * every MCP tool call, before each method/class `@UseGuards`. Listed by\n * class - a blanket \"run all globals\" is deliberately not offered, since\n * unrelated globals (e.g. a `ThrottlerGuard` that needs a writable response)\n * would misbehave over MCP. Empty/omitted ⇒ no global guards run.\n *\n * Note: over MCP the request stand-in is headers-only (`params`/`query` are\n * empty), so per-session or IP-derived guard logic won't apply; header-based\n * authentication still works.\n */\n globalGuards?: Type<CanActivate>[]\n /**\n * Default MCP result format for every `@Mcp` tool - `'json'` (compact JSON,\n * `jsonToolResult`) or `'smart'` (inline small / embedded-resource large,\n * `smartToolResult`). Defaults to `'smart'`. A per-method `@Mcp({ result })`\n * overrides this, and a client's per-call `_meta.disposition` overrides both.\n */\n defaultResult?: 'json' | 'smart'\n}\n\nexport const SILKWEAVE_MODULE_OPTIONS = '__silkweave_module_options__'\n","import { Inject, Module, type DynamicModule, type MiddlewareConsumer, type NestModule } from '@nestjs/common'\nimport { DiscoveryModule, HttpAdapterHost } from '@nestjs/core'\nimport { createContext } from '@silkweave/core'\nimport { ControllerDiscovery } from './controllerDiscovery.js'\nimport { SILKWEAVE_MODULE_OPTIONS, type SilkweaveModuleOptions } from './types.js'\n\n/**\n * Root module for `@silkweave/nestjs`.\n *\n * Discovers every `@Mcp`/`@Trpc`-decorated **controller method** via\n * `DiscoveryService`, reflects each into a Silkweave action (input schema from\n * the route + parameter decorators + optional OpenAPI document; invocation by\n * re-binding the validated input back into the method), and registers the\n * configured adapter(s) - `mcp()`, `trpc()`, `typegen()` - directly on Nest's\n * HTTP adapter inside `configure()`.\n *\n * Because `configure()` runs during `registerModules` - before Nest's\n * `registerRouter()` step - Silkweave's routes always sit ahead of every\n * controller in the Express stack. The controllers keep serving HTTP exactly as\n * before; `@Mcp` is purely additive.\n *\n * @example\n * ```ts\n * @Module({\n * imports: [\n * SilkweaveModule.forRoot({\n * silkweave: { name: 'app', description: 'My App', version: '1.0.0' },\n * adapters: [mcp({ basePath: '/mcp' })]\n * })\n * ],\n * controllers: [ChannelsController]\n * })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class SilkweaveModule implements NestModule {\n constructor(\n @Inject(SILKWEAVE_MODULE_OPTIONS) private readonly options: SilkweaveModuleOptions,\n private readonly discovery: ControllerDiscovery,\n private readonly httpAdapterHost: HttpAdapterHost\n ) { }\n\n static forRoot(options: SilkweaveModuleOptions): DynamicModule {\n return {\n module: SilkweaveModule,\n global: true,\n imports: [DiscoveryModule],\n providers: [\n { provide: SILKWEAVE_MODULE_OPTIONS, useValue: options },\n ControllerDiscovery\n ],\n exports: []\n }\n }\n\n configure(_consumer: MiddlewareConsumer): void {\n const httpAdapter = this.httpAdapterHost.httpAdapter\n if (!httpAdapter) {\n throw new Error('@silkweave/nestjs: HttpAdapterHost.httpAdapter is not available.')\n }\n const allActions = this.discovery.discover({\n openapi: this.options.openapi,\n globalGuards: this.options.globalGuards,\n defaultResult: this.options.defaultResult\n })\n for (const adapter of this.options.adapters) {\n const baseContext = createContext({ ...(this.options.context ?? {}), adapter: adapter.name })\n const actions = adapter.allActions\n ? allActions\n : allActions.filter((a) => !a.isEnabled || a.isEnabled(baseContext))\n adapter.register({\n httpAdapter,\n silkweaveOptions: this.options.silkweave,\n baseContext,\n actions\n })\n }\n }\n}\n"],"mappings":"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"}
package/build/mcp.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as NestSilkweaveAdapter } from "./types-ByWkPWx2.mjs";
1
+ import { n as NestSilkweaveAdapter } from "./types-wmI5n_7i.mjs";
2
2
  import { t as AuthConfig } from "./index-C1W-O7EX.mjs";
3
3
  import { CorsOptions } from "cors";
4
4
 
package/build/trpc.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as NestSilkweaveAdapter } from "./types-ByWkPWx2.mjs";
1
+ import { n as NestSilkweaveAdapter } from "./types-wmI5n_7i.mjs";
2
2
  import { t as AuthConfig } from "./index-C1W-O7EX.mjs";
3
3
  import { CorsOptions } from "cors";
4
4
 
@@ -1,4 +1,4 @@
1
- import { n as NestSilkweaveAdapter } from "./types-ByWkPWx2.mjs";
1
+ import { n as NestSilkweaveAdapter } from "./types-wmI5n_7i.mjs";
2
2
  import { TypegenFormat } from "@silkweave/typegen";
3
3
 
4
4
  //#region src/adapter/typegen.d.ts
@@ -14,6 +14,8 @@ import { z } from "zod/v4";
14
14
  interface FieldDesc {
15
15
  type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'unknown';
16
16
  required?: boolean;
17
+ /** Field accepts `null` (`@ApiProperty({ nullable: true })` / OpenAPI `nullable`). */
18
+ nullable?: boolean;
17
19
  description?: string;
18
20
  enum?: (string | number)[];
19
21
  items?: FieldDesc;
@@ -54,6 +56,14 @@ declare function openapiSchemaToField(schema: Record<string, any>): FieldDesc;
54
56
  * default to required unless a source marks them optional.
55
57
  */
56
58
  declare function reflectDtoFields(dtoType: any): Record<string, FieldDesc>;
59
+ /**
60
+ * Names of fields that could not be reflected into a concrete type - they will
61
+ * become `z.unknown()` (or `z.array(z.unknown())`). This is how a nested DTO or a
62
+ * `Dto[]` property silently degrades (reflection is one level deep), so the
63
+ * adapters surface these as a build-time warning pointing at `@Trpc({ output })`
64
+ * / `@Mcp({ input })`. Enum and `object` (record) fields are not degraded.
65
+ */
66
+ declare function unreflectedFields(fields: Record<string, FieldDesc>): string[];
57
67
  //#endregion
58
68
  //#region src/lib/reflect/openapi.d.ts
59
69
  /**
@@ -158,5 +168,5 @@ interface SilkweaveModuleOptions {
158
168
  }
159
169
  declare const SILKWEAVE_MODULE_OPTIONS = "__silkweave_module_options__";
160
170
  //#endregion
161
- export { reflectDtoFields as _, OpenApiDocument as a, openApiFields as c, classValidatorToField as d, designTypeToField as f, openapiSchemaToField as g, normalizeEnum as h, SilkweaveModuleOptions as i, FieldDesc as l, mergeField as m, NestSilkweaveAdapter as n, OpenApiLookup as o, fieldToZod as p, SILKWEAVE_MODULE_OPTIONS as r, buildOpenApiLookup as s, NestAdapterRegisterContext as t, apiPropertyToField as u, swaggerParamToField as v, typeTokenToBase as y };
162
- //# sourceMappingURL=types-ByWkPWx2.d.mts.map
171
+ export { reflectDtoFields as _, OpenApiDocument as a, unreflectedFields as b, openApiFields as c, classValidatorToField as d, designTypeToField as f, openapiSchemaToField as g, normalizeEnum as h, SilkweaveModuleOptions as i, FieldDesc as l, mergeField as m, NestSilkweaveAdapter as n, OpenApiLookup as o, fieldToZod as p, SILKWEAVE_MODULE_OPTIONS as r, buildOpenApiLookup as s, NestAdapterRegisterContext as t, apiPropertyToField as u, swaggerParamToField as v, typeTokenToBase as y };
172
+ //# sourceMappingURL=types-wmI5n_7i.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-wmI5n_7i.d.mts","names":[],"sources":["../src/lib/reflect/schema.ts","../src/lib/reflect/openapi.ts","../src/lib/types.ts"],"mappings":";;;;;;;;;;;AAeA;;UAAiB,SAAA;EACf,IAAA;EACA,QAAA;EAAA;EAEA,QAAA;EACA,WAAA;EACA,IAAA;EACA,KAAA,GAAQ,SAAA;EACR,GAAA;EACA,GAAA;EACA,SAAA;EACA,SAAA;EACA,MAAA;EACA,OAAA;AAAA;;iBAac,UAAA,CAAW,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,GAAY,SAAA;AAA9D;AAAA,iBA2CgB,UAAA,CAAW,CAAA,EAAG,SAAA,GAAY,CAAA,CAAE,OAAA;;iBAe5B,aAAA,CAAc,KAAA;;iBAWd,eAAA,CAAgB,IAAA,YAAgB,SAAA;;iBAkBhC,iBAAA,CAAkB,IAAA,YAAgB,SAAA;;iBAQlC,mBAAA,CAAoB,CAAA,EAAG,MAAA,gBAAsB,SAAA;;iBAgB7C,kBAAA,CAAmB,CAAA,EAAG,MAAA,gBAAsB,SAAA;;iBA6D5C,qBAAA,CAAsB,KAAA,EAAO,KAAA;EAAQ,IAAA;EAAe,IAAA;EAAe,WAAA;AAAA,KAA6B,SAAA;;iBAOhG,oBAAA,CAAqB,MAAA,EAAQ,MAAA,gBAAsB,SAAA;;;;;;AAzHnE;;iBAsJgB,gBAAA,CAAiB,OAAA,QAAe,MAAA,SAAe,SAAA;;;AA3I/D;;;;;iBA6KgB,iBAAA,CAAkB,MAAA,EAAQ,MAAA,SAAe,SAAA;;;;;;;;UCnRxC,eAAA;EACf,KAAA,GAAQ,MAAA,SAAe,MAAA;EACvB,UAAA;IAAe,OAAA,GAAU,MAAA;EAAA;AAAA;AAAA,UAGV,aAAA;EACf,GAAA,EAAK,eAAA;EDOL;ECLA,UAAA,EAAY,GAAA;AAAA;;iBAIE,kBAAA,CAAmB,GAAA,EAAK,eAAA,GAAkB,aAAA;;;;;;;iBAwC1C,aAAA,CAAc,MAAA,EAAQ,aAAA,EAAe,MAAA,UAAgB,WAAA,WAAsB,MAAA,SAAe,SAAA;;;;;AD7C1G;;;;;UEHiB,0BAAA;EFOf;EELA,WAAA,EAAa,WAAA,CAAY,eAAA;EFOzB;EELA,gBAAA,EAAkB,gBAAA;EFMV;EEJR,WAAA,EAAa,gBAAA;EFMb;EEJA,OAAA,EAAS,MAAA;AAAA;;;;;AFqBX;;;UEXiB,oBAAA;EFWiC;EAAA,SETvC,IAAA;EFS4D;EAAA,SEP5D,QAAA;EFOsB;;;;;EAAA,SEDtB,UAAA;EFC4D;EECrE,QAAA,CAAS,GAAA,EAAK,0BAAA;AAAA;AAAA,UAGC,sBAAA;EFuCkC;EErCjD,SAAA,EAAW,gBAAA;EFqCc;EEnCzB,QAAA,EAAU,oBAAA;EFmCgC;EEjC1C,OAAA,GAAU,MAAA;EFiCuC;AAenD;;;;;EEzCE,OAAA,GAAU,eAAA;EFoDmB;;;;AAkB/B;;;;;AAQA;;;EEjEE,YAAA,GAAe,IAAA,CAAK,WAAA;EFiEiB;;;;;AAgBvC;EE1EE,aAAA;AAAA;AAAA,cAGW,wBAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silkweave/nestjs",
3
- "version": "2.5.0",
3
+ "version": "2.6.1",
4
4
  "description": "Silkweave NestJS Adapter",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.silkweave.dev",
@@ -47,9 +47,9 @@
47
47
  "rxjs": "^7.0.0",
48
48
  "@trpc/server": "^11.7.1",
49
49
  "class-validator": "^0.14.0 || ^0.15.0",
50
- "@silkweave/mcp": "^2.5.0",
51
- "@silkweave/typegen": "^2.5.0",
52
- "@silkweave/trpc": "^2.5.0"
50
+ "@silkweave/mcp": "^2.6.1",
51
+ "@silkweave/typegen": "^2.6.1",
52
+ "@silkweave/trpc": "^2.6.1"
53
53
  },
54
54
  "peerDependenciesMeta": {
55
55
  "@nestjs/swagger": {
@@ -75,7 +75,7 @@
75
75
  "cors": "^2.8.6",
76
76
  "express": "^5.2.1",
77
77
  "zod": "^3.25.0",
78
- "@silkweave/core": "2.5.0"
78
+ "@silkweave/core": "2.6.1"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@eslint/js": "^10.0.1",
@@ -95,10 +95,10 @@
95
95
  "tsx": "^4.21.0",
96
96
  "typescript": "^5.9.3",
97
97
  "typescript-eslint": "^8.56.1",
98
- "@silkweave/auth": "2.5.0",
99
- "@silkweave/mcp": "2.5.0",
100
- "@silkweave/typegen": "2.5.0",
101
- "@silkweave/trpc": "2.5.0"
98
+ "@silkweave/auth": "2.6.1",
99
+ "@silkweave/mcp": "2.6.1",
100
+ "@silkweave/trpc": "2.6.1",
101
+ "@silkweave/typegen": "2.6.1"
102
102
  },
103
103
  "scripts": {
104
104
  "clean": "rimraf build",
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-ByWkPWx2.d.mts","names":[],"sources":["../src/lib/reflect/schema.ts","../src/lib/reflect/openapi.ts","../src/lib/types.ts"],"mappings":";;;;;;;;;;;AAeA;;UAAiB,SAAA;EACf,IAAA;EACA,QAAA;EACA,WAAA;EACA,IAAA;EACA,KAAA,GAAQ,SAAA;EACR,GAAA;EACA,GAAA;EACA,SAAA;EACA,SAAA;EACA,MAAA;EACA,OAAA;AAAA;;iBAac,UAAA,CAAW,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,GAAY,SAAA;;iBA2C9C,UAAA,CAAW,CAAA,EAAG,SAAA,GAAY,CAAA,CAAE,OAAA;;iBAc5B,aAAA,CAAc,KAAA;;iBAWd,eAAA,CAAgB,IAAA,YAAgB,SAAA;;iBAkBhC,iBAAA,CAAkB,IAAA,YAAgB,SAAA;;iBAQlC,mBAAA,CAAoB,CAAA,EAAG,MAAA,gBAAsB,SAAA;;iBAgB7C,kBAAA,CAAmB,CAAA,EAAG,MAAA,gBAAsB,SAAA;;iBA4D5C,qBAAA,CAAsB,KAAA,EAAO,KAAA;EAAQ,IAAA;EAAe,IAAA;EAAe,WAAA;AAAA,KAA6B,SAAA;;iBAOhG,oBAAA,CAAqB,MAAA,EAAQ,MAAA,gBAAsB,SAAA;;;;;;;AAxHnE;iBAoJgB,gBAAA,CAAiB,OAAA,QAAe,MAAA,SAAe,SAAA;;;;;;;;UC5O9C,eAAA;EACf,KAAA,GAAQ,MAAA,SAAe,MAAA;EACvB,UAAA;IAAe,OAAA,GAAU,MAAA;EAAA;AAAA;AAAA,UAGV,aAAA;EACf,GAAA,EAAK,eAAA;EDML;ECJA,UAAA,EAAY,GAAA;AAAA;;iBAIE,kBAAA,CAAmB,GAAA,EAAK,eAAA,GAAkB,aAAA;;;;;;ADmB1D;iBCqBgB,aAAA,CAAc,MAAA,EAAQ,aAAA,EAAe,MAAA,UAAgB,WAAA,WAAsB,MAAA,SAAe,SAAA;;;;;AD7C1G;;;;;UEHiB,0BAAA;EFMf;EEJA,WAAA,EAAa,WAAA,CAAY,eAAA;EFMzB;EEJA,gBAAA,EAAkB,gBAAA;EFKlB;EEHA,WAAA,EAAa,gBAAA;EFKb;EEHA,OAAA,EAAS,MAAA;AAAA;;;;AFmBX;;;;UETiB,oBAAA;EFS6C;EAAA,SEPnD,IAAA;EFO4D;EAAA,SEL5D,QAAA;EFKgB;;;;;EAAA,SEChB,UAAA;EF0CK;EExCd,QAAA,CAAS,GAAA,EAAK,0BAAA;AAAA;AAAA,UAGC,sBAAA;EFqCa;EEnC5B,SAAA,EAAW,gBAAA;EFmC6B;EEjCxC,QAAA,EAAU,oBAAA;EFiCuC;EE/BjD,OAAA,GAAU,MAAA;EF6CI;;;;;AAWhB;EEjDE,OAAA,GAAU,eAAA;;;;AFmEZ;;;;;AAQA;;;;EE9DE,YAAA,GAAe,IAAA,CAAK,WAAA;EF8Dc;;;;AAgBpC;;EEvEE,aAAA;AAAA;AAAA,cAGW,wBAAA"}