@silkweave/nestjs 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  $ tsdown
2
- ℹ tsdown v0.21.8 powered by rolldown v1.0.0-rc.15
2
+ ℹ tsdown v0.21.10 powered by rolldown v1.0.0-rc.17
3
3
  ℹ config file: /Users/atomic/projects/silkweave/silkweave/packages/nestjs/tsdown.config.ts
4
4
  ℹ entry: src/index.ts
5
5
  ℹ tsconfig: tsconfig.json
@@ -9,9 +9,9 @@ $ tsdown
9
9
  See more at https://tsdown.dev/options/dependencies#deps-onlybundle
10
10
  Detected dependencies in bundle:
11
11
  - rxjs
12
- ℹ build/index.mjs 336.69 kB │ gzip: 48.97 kB
13
- ℹ build/index.mjs.map 574.23 kB │ gzip: 86.16 kB
14
- ℹ build/index.d.mts.map  2.82 kB │ gzip: 1.03 kB
15
- ℹ build/index.d.mts  14.64 kB │ gzip: 4.94 kB
16
- ℹ 4 files, total: 928.38 kB
17
- ✔ Build complete in 815ms
12
+ ℹ build/index.mjs 337.92 kB │ gzip: 49.52 kB
13
+ ℹ build/index.mjs.map 576.49 kB │ gzip: 87.36 kB
14
+ ℹ build/index.d.mts.map  2.98 kB │ gzip: 1.07 kB
15
+ ℹ build/index.d.mts  15.96 kB │ gzip: 5.58 kB
16
+ ℹ 4 files, total: 933.34 kB
17
+ ✔ Build complete in 1110ms
@@ -1,4 +1,3 @@
1
1
  $ pnpm lint && pnpm typecheck
2
2
  $ eslint
3
- [ELIFECYCLE] Command failed.
4
- [ELIFECYCLE] Command failed.
3
+ $ tsc --noEmit
@@ -0,0 +1,2 @@
1
+
2
+ $ eslint
@@ -0,0 +1,19 @@
1
+
2
+ $ pnpm clean && pnpm build
3
+ $ rimraf build
4
+ $ tsdown
5
+ ℹ tsdown v0.21.10 powered by rolldown v1.0.0-rc.17
6
+ ℹ config file: /Users/atomic/projects/silkweave/silkweave/packages/nestjs/tsdown.config.ts
7
+ ℹ entry: src/index.ts
8
+ ℹ tsconfig: tsconfig.json
9
+ ℹ Build start
10
+ ℹ Hint: consider adding deps.onlyBundle option to avoid unintended bundling of dependencies, or set deps.onlyBundle: false to disable this hint.
11
+ See more at https://tsdown.dev/options/dependencies#deps-onlybundle
12
+ Detected dependencies in bundle:
13
+ - rxjs
14
+ ℹ build/index.mjs 337.92 kB │ gzip: 49.52 kB
15
+ ℹ build/index.mjs.map 576.49 kB │ gzip: 87.36 kB
16
+ ℹ build/index.d.mts.map  2.98 kB │ gzip: 1.07 kB
17
+ ℹ build/index.d.mts  15.96 kB │ gzip: 5.58 kB
18
+ ℹ 4 files, total: 933.34 kB
19
+ ✔ Build complete in 828ms
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @silkweave/nestjs
2
2
 
3
- NestJS adapter for [Silkweave](https://github.com/silkweave/silkweave). Define actions as method decorators on Nest providers, then expose them simultaneously over REST, tRPC, and MCP Streamable HTTP all mounted on the running Nest HTTP server so Nest middleware, guards, and lifecycle hooks stay coherent.
3
+ NestJS adapter for [Silkweave](https://github.com/silkweave/silkweave). Define actions as method decorators on Nest providers, then expose them simultaneously over REST, tRPC, and MCP Streamable HTTP - all mounted on the running Nest HTTP server so Nest middleware, guards, and lifecycle hooks stay coherent.
4
4
 
5
5
  ## Install
6
6
 
@@ -73,7 +73,7 @@ import { UserActions } from './users.actions.js'
73
73
  adapters: [
74
74
  rest({ basePath: '/api' }),
75
75
  trpc({ basePath: '/trpc' }),
76
- mcp({ basePath: '/' })
76
+ mcp({ basePath: '/mcp' })
77
77
  ]
78
78
  })
79
79
  ],
@@ -109,11 +109,12 @@ The `users.list` and `users.get` actions are now reachable via:
109
109
  | `name` | `string` | kebab-cased method name | Override the action name. Joined with the class prefix via `.` |
110
110
  | `description` | `string` | *required* | Human-readable summary. Used as MCP tool description |
111
111
  | `input` | `z.ZodObject` | *required* | Zod object schema for the action's input |
112
- | `output` | `z.ZodObject` | | Optional output schema (used by tRPC type inference) |
112
+ | `output` | `z.ZodObject` | - | Optional output schema (used by tRPC type inference) |
113
+ | `chunk` | `z.ZodType` | - | Schema for chunks yielded by a streaming (`async function*`) method. **Required** when the method is an async generator |
113
114
  | `kind` | `'query' \| 'mutation'` | `'mutation'` | `'query'` → GET in REST, `.query()` in tRPC. `'mutation'` → POST / `.mutation()` |
114
115
  | `transports` | `('rest' \| 'trpc' \| 'mcp')[]` | all | Allowlist of transports that expose this action |
115
- | `isEnabled` | `(ctx) => boolean` | | Dynamic gate (AND-combined with `transports`) |
116
- | `toolResult` | `(response, ctx) => CallToolResult` | | Custom MCP `CallToolResult` formatter |
116
+ | `isEnabled` | `(ctx) => boolean` | - | Dynamic gate (AND-combined with `transports`) |
117
+ | `toolResult` | `(response, ctx) => CallToolResult` | - | Custom MCP `CallToolResult` formatter |
117
118
 
118
119
  ### `@Actions(prefix?)` (class decorator)
119
120
 
@@ -137,15 +138,15 @@ Maps actions to REST routes on the Nest HTTP server.
137
138
 
138
139
  | Option | Type | Default | Description |
139
140
  |--------|------|---------|-------------|
140
- | `basePath` | `string` | `'/'` | URL prefix joined to each action's path |
141
- | `auth` | `AuthConfig` | | `@silkweave/auth` bearer-token config |
141
+ | `basePath` | `string` | `'/api'` | URL prefix joined to each action's path |
142
+ | `auth` | `AuthConfig` | - | `@silkweave/auth` bearer-token config |
142
143
 
143
144
  Routes follow `{basePath}/{action-name-with-slashes}` where dots in action names become slashes:
144
145
 
145
146
  - `users.list` (query) → `GET /api/users/list`
146
147
  - `users.ban` (mutation) → `POST /api/users/ban`
147
148
 
148
- Input is parsed from `req.query` (queries) or `req.body` (mutations) and validated against the action's Zod schema; validation failures return HTTP 400 with the Zod issues.
149
+ Each action is registered as an individual route on Nest's HTTP adapter (not a sub-app). Input is parsed from `req.query` (queries) or `req.body` (mutations) and validated against the action's Zod schema; validation failures return HTTP 400 with the Zod issues.
149
150
 
150
151
  ### `trpc(options?)`
151
152
 
@@ -154,25 +155,45 @@ Mounts a tRPC HTTP handler built from `@silkweave/trpc`'s `buildRouter`.
154
155
  | Option | Type | Default | Description |
155
156
  |--------|------|---------|-------------|
156
157
  | `basePath` | `string` | `'/trpc'` | URL prefix the tRPC handler listens on |
157
- | `auth` | `AuthConfig` | | `@silkweave/auth` bearer-token config |
158
+ | `auth` | `AuthConfig` | - | `@silkweave/auth` bearer-token config |
158
159
 
159
- Action names with dots (e.g. `users.list`) collapse to camelCase procedure keys (`usersList`) flat router in v1.
160
+ Action names with dots (e.g. `users.list`) collapse to camelCase procedure keys (`usersList`) - flat router in v1.
161
+
162
+ **Streaming.** An `@Action` method declared as an `async function*` (with a `chunk` schema) is registered as a tRPC **subscription** that streams each yielded chunk over SSE - exactly like a standalone `createAction({ chunk, run: async function*(){…} })`. `@UseGuards()` guards still run before the first chunk. This is what `useChat` + `@silkweave/ai`'s `silkweaveTransport()` consume.
163
+
164
+ ```ts
165
+ @Action({
166
+ description: 'Stream a countdown',
167
+ input: z.object({ from: z.number().int() }),
168
+ chunk: z.object({ n: z.number().int() })
169
+ })
170
+ async *countdown(input: { from: number }) {
171
+ for (let n = input.from; n >= 0; n -= 1) {
172
+ await new Promise((r) => setTimeout(r, 200))
173
+ yield { n }
174
+ }
175
+ }
176
+ ```
177
+
178
+ Declaring an async-generator method without a `chunk` schema throws at discovery time - the schema is required for typegen/tRPC to expose the subscription.
160
179
 
161
180
  ### `mcp(options?)`
162
181
 
163
- Mounts MCP Streamable HTTP at `{basePath}/mcp`, plus optional OAuth routes when `auth.provider` is set. Reuses `@silkweave/mcp`'s `createMcpExpressHandler`.
182
+ Mounts the MCP Streamable HTTP transport directly at `basePath`, with sideload (`{basePath}/resource/:id`), well-known auth metadata (`{basePath}/.well-known/...`), and the OAuth proxy routes (`{basePath}/authorize`, `/token`, `/register`, `/auth/callback`) namespaced under the same prefix. Composes the handler primitives from `@silkweave/mcp` - no Express sub-app.
164
183
 
165
184
  | Option | Type | Default | Description |
166
185
  |--------|------|---------|-------------|
167
- | `basePath` | `string` | `'/'` | Mount point for the MCP sub-app |
168
- | `auth` | `AuthConfig` | | Bearer-token / OAuth 2.1 config |
169
- | `cors` | `CorsOptions \| boolean` | `true` | CORS config (see `@silkweave/mcp`) |
186
+ | `basePath` | `string` | `'/mcp'` | URL prefix; the MCP transport endpoint is at this exact path |
187
+ | `auth` | `AuthConfig` | - | Bearer-token / OAuth 2.1 config |
188
+ | `cors` | `CorsOptions \| boolean` | `true` | CORS config |
189
+ | `sideloadResources` | `boolean` | `true` | Mount `{basePath}/resource/:id` |
190
+ | `resourceDir` | `string` | `'resources'` | Directory the sideload route reads from |
170
191
 
171
192
  ## Guards & DI
172
193
 
173
194
  Native NestJS `@UseGuards()` and `@UseInterceptors()` on `@Action` methods run for every HTTP-backed transport. Guards receive an `ExecutionContext` with the HTTP request in `switchToHttp().getRequest()`. The `Reflector` is also wired up so guards can read custom metadata.
174
195
 
175
- Action methods are normal Nest provider methods inject services via the constructor as usual.
196
+ Action methods are normal Nest provider methods - inject services via the constructor as usual.
176
197
 
177
198
  ```ts
178
199
  @Injectable()
package/build/index.d.mts CHANGED
@@ -1,87 +1,106 @@
1
- import { CreateMcpExpressHandlerOptions } from "@silkweave/mcp";
2
- import { CanActivate, DynamicModule, OnApplicationBootstrap, OnApplicationShutdown, OnModuleInit, Type } from "@nestjs/common";
1
+ import { CanActivate, DynamicModule, MiddlewareConsumer, NestModule, Type } from "@nestjs/common";
3
2
  import { AuthConfig } from "@silkweave/auth";
4
- import { Action as Action$1, ActionKind, AdapterGenerator, Silkweave, SilkweaveContext, SilkweaveOptions } from "@silkweave/core";
3
+ import { Action as Action$1, ActionKind, SilkweaveContext, SilkweaveOptions } from "@silkweave/core";
5
4
  import z$1 from "zod/v4";
6
5
  import { InferTrpcRouter } from "@silkweave/trpc";
6
+ import { TypegenFormat } from "@silkweave/typegen";
7
7
  import { DiscoveryService, HttpAdapterHost, MetadataScanner, ModuleRef, Reflector } from "@nestjs/core";
8
+ import { CorsOptions } from "cors";
8
9
 
9
10
  //#region src/lib/types.d.ts
10
11
  /**
11
- * A Silkweave NestJS adapter. Each transport (REST, tRPC, MCP) implements this
12
- * shape: given a Nest `HttpAdapterHost`, it (a) immediately mounts a
13
- * placeholder middleware slot on Nest's running HTTP server during
14
- * `OnModuleInit` which is critical because Nest installs its 404 catch-all
15
- * later in `init()`, before `OnApplicationBootstrap` fires; routes registered
16
- * after the catch-all are unreachable — and (b) returns a core
17
- * `AdapterGenerator` whose `start(actions)` populates that slot with the real
18
- * handler.
19
- *
20
- * Adapters mount onto Nest's HTTP server instead of owning their own, so Nest
21
- * middleware, lifecycle hooks, and request scoping remain coherent.
12
+ * Context passed to a Nest Silkweave adapter when `SilkweaveModule` wires it
13
+ * up. Adapters register their routes directly on `httpAdapter` (no
14
+ * placeholder middleware, no `silkweave()` builder), so they only fire
15
+ * `register()` once and own the rest of their lifecycle implicitly through
16
+ * Nest.
17
+ */
18
+ interface NestAdapterRegisterContext {
19
+ /** Nest's underlying HTTP adapter (Express or Fastify). */
20
+ httpAdapter: NonNullable<HttpAdapterHost['httpAdapter']>;
21
+ /** Identity the adapter surfaces to clients (e.g. MCP server name). */
22
+ silkweaveOptions: SilkweaveOptions;
23
+ /** Per-adapter context - already forked with `{ adapter: adapter.name, ...userContext }`. */
24
+ baseContext: SilkweaveContext;
25
+ /** Actions filtered to those enabled on this adapter. */
26
+ actions: Action$1[];
27
+ }
28
+ /**
29
+ * A Silkweave Nest adapter. Each transport (REST, tRPC, MCP) implements this
30
+ * shape. `register()` is called from `SilkweaveModule.configure()` - which
31
+ * runs *before* Nest's controller routes are mapped - so adapter routes
32
+ * always sit ahead of any catch-all controllers in the framework's request
33
+ * pipeline.
22
34
  */
23
35
  interface NestSilkweaveAdapter {
24
- /** Adapter discriminator set on the silkweave context as `ctx.get('adapter')`. */
25
- readonly name: 'rest' | 'trpc' | 'mcp';
36
+ /** Adapter discriminator - set on the silkweave context as `ctx.get('adapter')`. */
37
+ readonly name: 'rest' | 'trpc' | 'mcp' | 'typegen';
26
38
  /**
27
- * Reserve the adapter's route prefix on the Nest HTTP server *now* (before
28
- * Nest's 404 catch-all is installed) and return the core `AdapterGenerator`
29
- * that will populate the slot during `silkweave().start()`.
39
+ * When `true`, the adapter receives every discovered action regardless of
40
+ * each action's `transports` allowlist / `isEnabled` gate. Used by
41
+ * non-runtime adapters like `typegen()` that emit types for the entire
42
+ * action surface.
30
43
  */
31
- install(host: HttpAdapterHost): AdapterGenerator;
44
+ readonly allActions?: boolean;
45
+ /** Register this adapter's routes on Nest's HTTP server. */
46
+ register(ctx: NestAdapterRegisterContext): void;
32
47
  }
33
48
  interface SilkweaveModuleOptions {
34
- /** Identity for the silkweave instance surfaced to MCP clients, OpenAPI, etc. */
49
+ /** Identity for the silkweave instance - surfaced to MCP clients, OpenAPI, etc. */
35
50
  silkweave: SilkweaveOptions;
36
51
  /** Adapters to mount. Examples: `rest()`, `trpc()`, `mcp()`. */
37
52
  adapters: NestSilkweaveAdapter[];
38
- /** Initial context keys (equivalent to chaining `.set(key, value)` on the builder). */
53
+ /** Initial context keys merged into every adapter's `baseContext`. */
39
54
  context?: Record<string, unknown>;
40
55
  }
41
56
  declare const SILKWEAVE_MODULE_OPTIONS = "__silkweave_module_options__";
42
57
  //#endregion
43
58
  //#region src/adapter/mcp.d.ts
44
- interface McpAdapterOptions extends Omit<CreateMcpExpressHandlerOptions, 'auth'> {
45
- /** URL prefix at which the MCP sub-app is mounted. Default `'/'` — the MCP transport then lives at `/mcp`, OAuth routes at `/authorize`, etc. */
59
+ interface McpAdapterOptions {
60
+ /** URL prefix the MCP namespace lives under - the transport itself is at this exact path. Default `'/mcp'`. */
46
61
  basePath?: string;
47
- /** Optional bearer-token / OAuth auth applied to MCP requests. Same shape as `@silkweave/mcp`'s `http()` auth. */
62
+ /** Optional bearer-token / OAuth 2.1 config. */
48
63
  auth?: AuthConfig;
64
+ /** CORS configuration. `false` to disable, `true`/omitted for permissive defaults, or a `CorsOptions` object. */
65
+ cors?: CorsOptions | boolean;
66
+ /** Mount the sideload resource route at `${basePath}/resource/:id`. Default `true`. */
67
+ sideloadResources?: boolean;
68
+ /** Directory the sideload route reads from. Default `'resources'`. */
69
+ resourceDir?: string;
49
70
  }
50
71
  /**
51
- * MCP Streamable HTTP adapter for `@silkweave/nestjs`. Builds the same Express
52
- * sub-app that `@silkweave/mcp`'s `http()` adapter uses internally (via
53
- * `createMcpExpressHandler`) and mounts it on Nest's running HTTP server at
54
- * the configured base path.
72
+ * MCP adapter for `@silkweave/nestjs`. Registers the MCP Streamable HTTP
73
+ * transport, sideload, well-known and OAuth routes individually on Nest's
74
+ * HTTP adapter at the configured `basePath` (default `/mcp`):
55
75
  *
56
- * Routes provided by the mounted sub-app:
57
- * - `POST /mcp`, `GET /mcp`, `DELETE /mcp` — MCP Streamable HTTP transport
58
- * - `GET /resource/:id` sideload resources (large MCP responses)
59
- * - `GET /.well-known/oauth-protected-resource` (when `auth.resourceUrl`/`auth.authorizationServers` set)
60
- * - `GET /authorize`, `POST /token`, `POST /register`, `GET /auth/callback` (when `auth.provider` set)
76
+ * - `POST/GET/DELETE ${basePath}` - Streamable HTTP transport
77
+ * - `GET ${basePath}/resource/:id` - sideload (`sideloadResources` opt-out)
78
+ * - `GET ${basePath}/.well-known/oauth-protected-resource` - RFC 9728 metadata (when `auth.resourceUrl`/`auth.authorizationServers` set)
79
+ * - `GET ${basePath}/authorize`, `POST ${basePath}/token`, `POST ${basePath}/register`, `GET ${basePath}${callbackPath}` (when `auth.provider` set)
61
80
  *
62
- * Note: this adapter mounts an Express sub-app. On `@nestjs/platform-fastify`,
63
- * register `@fastify/express` before this adapter so Nest can serve Express
64
- * middleware.
81
+ * Each route is a real Nest-level route - they show up in
82
+ * `RoutesResolver`'s log and there is no sub-app or middleware-slot
83
+ * indirection.
65
84
  */
66
85
  declare function mcp(options?: McpAdapterOptions): NestSilkweaveAdapter;
67
86
  //#endregion
68
87
  //#region src/adapter/rest.d.ts
69
88
  interface RestAdapterOptions {
70
- /** URL prefix at which the REST routes are mounted. e.g. `'/api'` → `POST /api/users/list`. Default: `'/'`. */
89
+ /** URL prefix joined to each action's path. e.g. `'/api'` → `POST /api/users/list`. Default: `'/api'`. */
71
90
  basePath?: string;
72
91
  /** Optional bearer-token auth applied to every REST action. */
73
92
  auth?: AuthConfig;
74
93
  }
75
94
  /**
76
- * REST adapter for `@silkweave/nestjs`. Mounts each discovered `@Action` as a
77
- * route on Nest's running HTTP server:
95
+ * REST adapter for `@silkweave/nestjs`. Registers each discovered `@Action`
96
+ * as an individual route on Nest's HTTP adapter:
78
97
  *
79
- * - `kind: 'query'` → `GET ${basePath}/${actionName-with-slashes}` (input read from query string)
80
- * - `kind: 'mutation'` → `POST ${basePath}/${actionName-with-slashes}` (input read from JSON body)
98
+ * - `kind: 'query'` → `GET ${basePath}/${actionName-with-slashes}` (input from query string)
99
+ * - `kind: 'mutation'` → `POST ${basePath}/${actionName-with-slashes}` (input from JSON body)
81
100
  *
82
- * Works on `@nestjs/platform-express` out of the box. For
83
- * `@nestjs/platform-fastify`, register `@fastify/express` before this adapter
84
- * so Nest can serve Express-style middleware.
101
+ * Routes show up in Nest's `RoutesResolver` logger and are eligible for
102
+ * `@nestjs/swagger` scanning. Works on `@nestjs/platform-express` out of the
103
+ * box. For `@nestjs/platform-fastify`, register `@fastify/express` first.
85
104
  */
86
105
  declare function rest(options?: RestAdapterOptions): NestSilkweaveAdapter;
87
106
  //#endregion
@@ -94,23 +113,51 @@ interface TrpcAdapterOptions {
94
113
  }
95
114
  /**
96
115
  * tRPC adapter for `@silkweave/nestjs`. Builds a tRPC router from discovered
97
- * `@Action` methods via `@silkweave/trpc`'s `buildRouter` and mounts the
98
- * resulting `createExpressMiddleware()` at the configured base path on Nest's
99
- * underlying HTTP server.
116
+ * `@Action` methods and mounts the resulting express middleware at
117
+ * `basePath` on Nest's HTTP adapter.
100
118
  *
101
119
  * Action names with dots (e.g. `users.list` from `@Actions('users')`) collapse
102
- * to camelCase procedure keys (`usersList`) for v1 — flat router only.
120
+ * to camelCase procedure keys (`usersList`).
103
121
  *
104
122
  * Works on `@nestjs/platform-express`. On `@nestjs/platform-fastify`, register
105
- * `@fastify/express` first so Nest can mount Express-style middleware.
123
+ * `@fastify/express` first so Nest can serve Express-style middleware.
106
124
  */
107
125
  declare function trpc(options?: TrpcAdapterOptions): NestSilkweaveAdapter;
108
126
  //#endregion
127
+ //#region src/adapter/typegen.d.ts
128
+ interface TypegenAdapterOptions {
129
+ /** Output file path for the generated `.d.ts` file. Resolved against `process.cwd()`. Parent directories are created automatically. */
130
+ path: string;
131
+ /**
132
+ * What to emit (default `'all'`):
133
+ * - `'interfaces'` - `{Name}Input` / `{Name}Output` interfaces per action
134
+ * - `'trpc-router'` - `AppRouter` type alias for `createTRPCClient<AppRouter>()`
135
+ * - `'all'` - both
136
+ */
137
+ format?: TypegenFormat;
138
+ /**
139
+ * Whether to write the file at all. Default: `process.env.NODE_ENV !== 'production'`.
140
+ * Server processes generally shouldn't write to disk in production deploys -
141
+ * leave it on the default unless you know you want otherwise.
142
+ */
143
+ enabled?: boolean;
144
+ }
145
+ /**
146
+ * Typegen adapter for `@silkweave/nestjs`. Discovers every `@Action`-decorated
147
+ * method (regardless of `transports` filtering) and writes a single `.d.ts`
148
+ * file with REST input/output interfaces and/or a tRPC `AppRouter` type alias.
149
+ *
150
+ * Designed for the monorepo pattern where the server (this app) is the source
151
+ * of truth for types and consumer apps import from `path` - e.g.
152
+ * `path: '../app/src/types/silkweave.ts'`.
153
+ */
154
+ declare function typegen(options: TypegenAdapterOptions): NestSilkweaveAdapter;
155
+ //#endregion
109
156
  //#region src/lib/metadata.d.ts
110
157
  declare const ACTION_METADATA = "__silkweave_action__";
111
158
  declare const ACTIONS_METADATA = "__silkweave_actions__";
112
159
  type Transport = 'rest' | 'trpc' | 'mcp';
113
- interface ActionMetadata<I extends object = object, O extends object = object> {
160
+ interface ActionMetadata<I extends object = object, O extends object = object, C = unknown> {
114
161
  /** Action name. Defaults to the kebab-cased method name. */
115
162
  name?: string;
116
163
  /** Human-readable description. Becomes the MCP tool description and REST OpenAPI summary. */
@@ -123,6 +170,13 @@ interface ActionMetadata<I extends object = object, O extends object = object> {
123
170
  output?: z$1.ZodType<O> & {
124
171
  shape: Record<string, z$1.ZodTypeAny>;
125
172
  };
173
+ /**
174
+ * Zod schema for individual chunks yielded by a streaming (async-generator)
175
+ * action method. Required when the decorated method is an `async function*`.
176
+ * Mirrors `Action.chunk` in @silkweave/core; typegen/trpc use it to expose
177
+ * the action as a tRPC subscription.
178
+ */
179
+ chunk?: z$1.ZodType<C>;
126
180
  /** `'query'` (GET in REST, `.query()` in tRPC) or `'mutation'` (POST in REST, `.mutation()` in tRPC). Default: `'mutation'`. */
127
181
  kind?: ActionKind;
128
182
  /** Allowlist of transports that should expose this action. Default: all registered transports. */
@@ -179,7 +233,7 @@ declare const ACTION_RESPONSE_KEY = "__silkweave_response__";
179
233
  * }
180
234
  * ```
181
235
  */
182
- declare function Action<I extends object = object, O extends object = object>(options: ActionMetadata<I, O>): MethodDecorator;
236
+ declare function Action<I extends object = object, O extends object = object, C = unknown>(options: ActionMetadata<I, O, C>): MethodDecorator;
183
237
  //#endregion
184
238
  //#region src/decorator/actions.d.ts
185
239
  /**
@@ -187,7 +241,7 @@ declare function Action<I extends object = object, O extends object = object>(op
187
241
  * prefix. The prefix is joined to each method's action name with a dot
188
242
  * (e.g. `@Actions('users')` + method `list` → action name `users.list`).
189
243
  *
190
- * The class itself remains a normal Nest provider add `@Injectable()`
244
+ * The class itself remains a normal Nest provider - add `@Injectable()`
191
245
  * separately so it can be resolved by the DI container.
192
246
  *
193
247
  * Accepts either a prefix string (shorthand) or a full options object:
@@ -253,17 +307,16 @@ declare function runGuards(guards: GuardRef[], moduleRef: ModuleRef, reflector:
253
307
  /**
254
308
  * Root module for `@silkweave/nestjs`.
255
309
  *
256
- * Discovers every `@Action`-decorated method across the Nest app via
257
- * `DiscoveryService`, builds core `Action` objects from them, and mounts the
258
- * configured adapters (`rest()`, `trpc()`, `mcp()`) onto Nest's running HTTP
259
- * server during `OnApplicationBootstrap`.
310
+ * Discovers every `@Action`-decorated method via `DiscoveryService` and
311
+ * registers the configured adapters (`rest()`, `trpc()`, `mcp()`) directly on
312
+ * Nest's HTTP adapter inside `configure()`. Because `configure()` runs during
313
+ * `registerModules` - before Nest's `registerRouter()` step - Silkweave's
314
+ * routes always sit ahead of every controller in the Express stack. There is
315
+ * no slot middleware, no race with Nest's 404 catch-all, and every route
316
+ * shows up in Nest's `RoutesResolver` logger.
260
317
  *
261
318
  * @example
262
319
  * ```ts
263
- * import { Module } from '@nestjs/common'
264
- * import { SilkweaveModule, rest, trpc, mcp } from '@silkweave/nestjs'
265
- * import { UsersModule } from './users.module.js'
266
- *
267
320
  * @Module({
268
321
  * imports: [
269
322
  * SilkweaveModule.forRoot({
@@ -273,43 +326,20 @@ declare function runGuards(guards: GuardRef[], moduleRef: ModuleRef, reflector:
273
326
  * trpc({ basePath: '/trpc' }),
274
327
  * mcp({ basePath: '/mcp' })
275
328
  * ]
276
- * }),
277
- * UsersModule
329
+ * })
278
330
  * ]
279
331
  * })
280
332
  * export class AppModule {}
281
333
  * ```
282
334
  */
283
- declare class SilkweaveModule {
284
- static forRoot(options: SilkweaveModuleOptions): DynamicModule;
285
- }
286
- //#endregion
287
- //#region src/lib/silkweave.service.d.ts
288
- /**
289
- * Coordinates the Nest lifecycle for `@silkweave/nestjs`:
290
- *
291
- * - `onModuleInit`: each configured adapter calls `install(host)` to reserve a
292
- * placeholder middleware slot at its base path. This must happen here, not
293
- * in `onApplicationBootstrap`, because Nest installs its 404 catch-all later
294
- * during `init()` — routes registered after the catch-all are unreachable.
295
- *
296
- * - `onApplicationBootstrap`: discovers every `@Action` method, then drives the
297
- * standard `silkweave().adapter(...).actions(...).start()` flow, which calls
298
- * each adapter's `start(actions)` to populate the slot reserved earlier.
299
- */
300
- declare class SilkweaveService implements OnModuleInit, OnApplicationBootstrap, OnApplicationShutdown {
335
+ declare class SilkweaveModule implements NestModule {
301
336
  private readonly options;
302
337
  private readonly discovery;
303
338
  private readonly httpAdapterHost;
304
- private builder?;
305
- private readonly generators;
306
339
  constructor(options: SilkweaveModuleOptions, discovery: ActionDiscovery, httpAdapterHost: HttpAdapterHost);
307
- onModuleInit(): void;
308
- onApplicationBootstrap(): Promise<void>;
309
- onApplicationShutdown(): Promise<void>;
310
- /** Access the underlying silkweave builder once bootstrap has completed. */
311
- getBuilder(): Silkweave | undefined;
340
+ static forRoot(options: SilkweaveModuleOptions): DynamicModule;
341
+ configure(_consumer: MiddlewareConsumer): void;
312
342
  }
313
343
  //#endregion
314
- export { ACTIONS_METADATA, ACTION_METADATA, ACTION_RESPONSE_KEY, Action, ActionDiscovery, ActionMetadata, Actions, type ActionsClassMetadata, AnyActionMetadata, type InferTrpcRouter, McpAdapterOptions, NestSilkweaveAdapter, RestAdapterOptions, ResultToolResult, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, SilkweaveModuleOptions, SilkweaveService, type Transport, TrpcAdapterOptions, buildIsEnabled, collectGuards, mcp, rest, runGuards, trpc };
344
+ export { ACTIONS_METADATA, ACTION_METADATA, ACTION_RESPONSE_KEY, Action, ActionDiscovery, ActionMetadata, Actions, type ActionsClassMetadata, AnyActionMetadata, type InferTrpcRouter, McpAdapterOptions, NestAdapterRegisterContext, NestSilkweaveAdapter, RestAdapterOptions, ResultToolResult, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, SilkweaveModuleOptions, type Transport, TrpcAdapterOptions, TypegenAdapterOptions, buildIsEnabled, collectGuards, mcp, rest, runGuards, trpc, typegen };
315
345
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/types.ts","../src/adapter/mcp.ts","../src/adapter/rest.ts","../src/adapter/trpc.ts","../src/lib/metadata.ts","../src/decorator/action.ts","../src/decorator/actions.ts","../src/lib/discovery.ts","../src/lib/filter.ts","../src/lib/guards.ts","../src/lib/silkweave.module.ts","../src/lib/silkweave.service.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/types.ts","../src/adapter/mcp.ts","../src/adapter/rest.ts","../src/adapter/trpc.ts","../src/adapter/typegen.ts","../src/lib/metadata.ts","../src/decorator/action.ts","../src/decorator/actions.ts","../src/lib/discovery.ts","../src/lib/filter.ts","../src/lib/guards.ts","../src/lib/silkweave.module.ts"],"mappings":";;;;;;;;;;;;;;;;;UAUiB,0BAAA;EAAA;EAEf,WAAA,EAAa,WAAA,CAAY,eAAA;;EAEzB,gBAAA,EAAkB,gBAAA;EAFL;EAIb,WAAA,EAAa,gBAAA;EAAA;EAEb,OAAA,EAAS,QAAA;AAAA;;;;;;;;UAUM,oBAAA;EAVf;EAAA,SAYS,IAAA;EAZM;;AAUjB;;;;EAViB,SAmBN,UAAA;EAAA;EAET,QAAA,CAAS,GAAA,EAAK,0BAAA;AAAA;AAAA,UAGC,sBAAA;EAHyB;EAKxC,SAAA,EAAW,gBAAA;EAFI;EAIf,QAAA,EAAU,oBAAA;;EAEV,OAAA,GAAU,MAAA;AAAA;AAAA,cAGC,wBAAA;;;UCtCI,iBAAA;;EAEf,QAAA;;EAEA,IAAA,GAAO,UAAA;;EAEP,IAAA,GAAO,WAAA;EDTQ;ECWf,iBAAA;;EAEA,WAAA;AAAA;;;;;;;;;;;;;;;iBA6Bc,GAAA,CAAI,OAAA,GAAS,iBAAA,GAAyB,oBAAA;;;UChCrC,kBAAA;;EAEf,QAAA;;EAEA,IAAA,GAAO,UAAA;AAAA;;;AFdT;;;;;;;;;iBEwIgB,IAAA,CAAK,OAAA,GAAS,kBAAA,GAA0B,oBAAA;;;UC5IvC,kBAAA;;EAEf,QAAA;;EAEA,IAAA,GAAO,UAAA;AAAA;;;AHAT;;;;;;;;;iBGcgB,IAAA,CAAK,OAAA,GAAS,kBAAA,GAA0B,oBAAA;;;UCnBvC,qBAAA;;EAEf,IAAA;;;;;;AJGF;EIIE,MAAA,GAAS,aAAA;;;;;;EAMT,OAAA;AAAA;;;;;;;;;;iBAYc,OAAA,CAAQ,OAAA,EAAS,qBAAA,GAAwB,oBAAA;;;cC7B5C,eAAA;AAAA,cACA,gBAAA;AAAA,KAED,SAAA;AAAA,UAEK,cAAA;;EAEf,IAAA;;EAEA,WAAA;ELFe;EKIf,KAAA,EAAO,GAAA,CAAE,OAAA,CAAQ,CAAA;IAAO,KAAA,EAAO,MAAA,SAAe,GAAA,CAAE,UAAA;EAAA;ELFnC;EKIb,MAAA,GAAS,GAAA,CAAE,OAAA,CAAQ,CAAA;IAAO,KAAA,EAAO,MAAA,SAAe,GAAA,CAAE,UAAA;EAAA;ELEnC;;;;;;EKKf,KAAA,GAAQ,GAAA,CAAE,OAAA,CAAQ,CAAA;ELPlB;EKSA,IAAA,GAAO,UAAA;ELPP;EKSA,UAAA,GAAa,SAAA;ELTE;EKWf,SAAA,IAAa,OAAA,EAAS,gBAAA;ELDP;EKGf,UAAA,GAAa,QAAA,CAAO,CAAA,EAAG,CAAA;;EAEvB,IAAA,UAAc,CAAA;ELHL;EKKT,WAAA;AAAA;AAAA,UAGe,oBAAA;ELCN;EKCT,MAAA;ELDwC;EKGxC,UAAA,GAAa,SAAA;AAAA;AAAA,UAGE,gBAAA;EACf,UAAA,GAAa,QAAA,SAAe,CAAA;AAAA;AAAA,KAGlB,iBAAA,GAAoB,cAAA,mBAAiC,gBAAA;AAAA,cAEpD,mBAAA;;;;;;;;;;;;ALzCb;;;;;;;;;;;;;;;;;;;;;iBMuBgB,MAAA,mEAAA,CACd,OAAA,EAAS,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,CAAA,IAC7B,eAAA;;;;;;;;;;;;ANzBH;;;;;iBOOgB,OAAA,CAAQ,eAAA,YAA0B,oBAAA,GAA4B,cAAA;;;cCEjE,eAAA;EAAA,iBAEQ,SAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;EAAA,iBACA,SAAA;cAHA,SAAA,EAAW,gBAAA,EACX,OAAA,EAAS,eAAA,EACT,SAAA,EAAW,SAAA,EACX,SAAA,EAAW,SAAA;;;ARdhC;;;;;;;EQ0BE,QAAA,CAAA,GAAY,QAAA;EAAA,QAqBJ,QAAA;AAAA;;;;;;;;;;;AR/CV;;iBSGgB,cAAA,CACd,UAAA,EAAY,SAAA,gBACZ,aAAA,IAAiB,GAAA,EAAK,gBAAA,8BACnB,GAAA,EAAK,gBAAA;;;KCVL,QAAA,GAAW,IAAA,CAAK,WAAA,IAAe,WAAA;;;;;;iBAOpB,aAAA,CACd,SAAA,EAAW,SAAA,EACX,QAAA,EAAU,IAAA,WACV,OAAA,MAAa,IAAA,0BACZ,QAAA;;AVPH;;;;;;;iBUgCsB,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,YACC,OAAA;;;;;;;;;AVxCH;;;;;;;;;;;;;;;;;;;;;AAkBA;cWOa,eAAA,YAA2B,UAAA;EAAA,iBAEe,OAAA;EAAA,iBAClC,SAAA;EAAA,iBACA,eAAA;cAFkC,OAAA,EAAS,sBAAA,EAC3C,SAAA,EAAW,eAAA,EACX,eAAA,EAAiB,eAAA;EAAA,OAG7B,OAAA,CAAQ,OAAA,EAAS,sBAAA,GAAyB,aAAA;EAajD,SAAA,CAAU,SAAA,EAAW,kBAAA;AAAA"}