@silkweave/nestjs 1.12.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -165
- package/build/index.d.mts +218 -267
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +690 -509
- package/build/index.mjs.map +1 -1
- package/package.json +9 -10
- package/src/decorator/mcp.ts +39 -0
- package/src/index.ts +5 -9
- package/src/lib/controllerDiscovery.ts +201 -0
- package/src/lib/metadata.ts +32 -52
- package/src/lib/rebind.ts +117 -0
- package/src/lib/reflect/classValidator.ts +56 -0
- package/src/lib/reflect/openapi.ts +87 -0
- package/src/lib/reflect/params.ts +63 -0
- package/src/lib/reflect/route.ts +58 -0
- package/src/lib/reflect/schema.ts +270 -0
- package/src/lib/reflect/swagger.ts +39 -0
- package/src/lib/silkweave.module.ts +17 -17
- package/src/lib/types.ts +13 -10
- package/tsconfig.tsbuildinfo +1 -1
- package/src/adapter/rest.ts +0 -173
- package/src/adapter/trpc.ts +0 -58
- package/src/adapter/typegen.ts +0 -55
- package/src/decorator/action.ts +0 -38
- package/src/decorator/actions.ts +0 -25
- package/src/lib/discovery.ts +0 -131
- package/src/lib/filter.ts +0 -26
- package/src/lib/openapi.ts +0 -116
- package/src/lib/swagger.ts +0 -74
package/build/index.d.mts
CHANGED
|
@@ -1,13 +1,89 @@
|
|
|
1
|
-
import { CanActivate, DynamicModule,
|
|
2
|
-
import { AuthConfig } from "@silkweave/auth";
|
|
3
|
-
import { Action as Action$1, ActionKind, HttpMethod, SilkweaveContext, SilkweaveOptions } from "@silkweave/core";
|
|
4
|
-
import z$1 from "zod/v4";
|
|
5
|
-
import { InferTrpcRouter } from "@silkweave/trpc";
|
|
6
|
-
import { TypegenFormat } from "@silkweave/typegen";
|
|
1
|
+
import { CanActivate, DynamicModule, MiddlewareConsumer, NestModule, Type } from "@nestjs/common";
|
|
7
2
|
import { DiscoveryService, HttpAdapterHost, MetadataScanner, ModuleRef, Reflector } from "@nestjs/core";
|
|
3
|
+
import { Action, SilkweaveContext, SilkweaveOptions } from "@silkweave/core";
|
|
4
|
+
import { z } from "zod/v4";
|
|
5
|
+
import { AuthConfig } from "@silkweave/auth";
|
|
8
6
|
import { CorsOptions } from "cors";
|
|
9
|
-
import { OpenAPIObject } from "@nestjs/swagger";
|
|
10
7
|
|
|
8
|
+
//#region src/lib/reflect/schema.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* A transport-neutral description of a single input field. Every metadata
|
|
11
|
+
* source (swagger decorators, class-validator, an OpenAPI document, TypeScript
|
|
12
|
+
* `design:type`) is mapped to this shape, the shapes are merged by precedence,
|
|
13
|
+
* and the result is converted to Zod once. Keeping a single intermediate keeps
|
|
14
|
+
* the per-source mappers small and the Zod construction in one place.
|
|
15
|
+
*/
|
|
16
|
+
interface FieldDesc {
|
|
17
|
+
type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'unknown';
|
|
18
|
+
required?: boolean;
|
|
19
|
+
description?: string;
|
|
20
|
+
enum?: (string | number)[];
|
|
21
|
+
items?: FieldDesc;
|
|
22
|
+
min?: number;
|
|
23
|
+
max?: number;
|
|
24
|
+
minLength?: number;
|
|
25
|
+
maxLength?: number;
|
|
26
|
+
format?: string;
|
|
27
|
+
default?: unknown;
|
|
28
|
+
}
|
|
29
|
+
/** Merge `over` onto `base` - defined keys of `over` win. */
|
|
30
|
+
declare function mergeField(base: FieldDesc, over: FieldDesc): FieldDesc;
|
|
31
|
+
/** Convert a merged {@link FieldDesc} to a Zod schema. */
|
|
32
|
+
declare function fieldToZod(d: FieldDesc): z.ZodType;
|
|
33
|
+
/** Normalise a TS-enum object or an array literal to a flat value list. */
|
|
34
|
+
declare function normalizeEnum(value: unknown): (string | number)[] | undefined;
|
|
35
|
+
/** Map a swagger/`design:type` type token (constructor, `[Type]`, or string) to a base type. */
|
|
36
|
+
declare function typeTokenToBase(type: unknown): FieldDesc['type'] | undefined;
|
|
37
|
+
/** From the constructor TypeScript emits via `emitDecoratorMetadata`. */
|
|
38
|
+
declare function designTypeToField(ctor: unknown): FieldDesc;
|
|
39
|
+
/** From an `@ApiParam`/`@ApiQuery` entry stored under `swagger/apiParameters`. */
|
|
40
|
+
declare function swaggerParamToField(p: Record<string, any>): FieldDesc;
|
|
41
|
+
/** From an `@ApiProperty` options object stored under `swagger/apiModelProperties`. */
|
|
42
|
+
declare function apiPropertyToField(o: Record<string, any>): FieldDesc;
|
|
43
|
+
/** From an array of `class-validator` validation-metadata entries for one property. */
|
|
44
|
+
declare function classValidatorToField(metas: Array<{
|
|
45
|
+
type?: string;
|
|
46
|
+
name?: string;
|
|
47
|
+
constraints?: unknown[];
|
|
48
|
+
}>): FieldDesc;
|
|
49
|
+
/** From an OpenAPI Schema Object (used by both the doc and `@ApiParam({ schema })`). */
|
|
50
|
+
declare function openapiSchemaToField(schema: Record<string, any>): FieldDesc;
|
|
51
|
+
/**
|
|
52
|
+
* Reflect a whole-DTO class (`@Body() dto: CreateDto`) into per-property
|
|
53
|
+
* {@link FieldDesc}s. Property names are the union of `@ApiProperty` and
|
|
54
|
+
* `class-validator` decorated fields; each field merges `design:type` (base),
|
|
55
|
+
* then `class-validator` constraints, then `@ApiProperty` (highest). Properties
|
|
56
|
+
* default to required unless a source marks them optional.
|
|
57
|
+
*/
|
|
58
|
+
declare function reflectDtoFields(dtoType: any): Record<string, FieldDesc>;
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/lib/reflect/openapi.d.ts
|
|
61
|
+
/**
|
|
62
|
+
* A minimal view of an OpenAPI document - the subset we read. Matches the shape
|
|
63
|
+
* `SwaggerModule.createDocument()` returns, but typed loosely so callers can
|
|
64
|
+
* pass any compatible object without a hard `@nestjs/swagger` dependency.
|
|
65
|
+
*/
|
|
66
|
+
interface OpenApiDocument {
|
|
67
|
+
paths?: Record<string, Record<string, any>>;
|
|
68
|
+
components?: {
|
|
69
|
+
schemas?: Record<string, any>;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
interface OpenApiLookup {
|
|
73
|
+
doc: OpenApiDocument;
|
|
74
|
+
/** `${METHOD} ${path}` → operation object. */
|
|
75
|
+
operations: Map<string, any>;
|
|
76
|
+
}
|
|
77
|
+
/** Index a document's operations by `${METHOD} ${path}` for fast matching. */
|
|
78
|
+
declare function buildOpenApiLookup(doc: OpenApiDocument): OpenApiLookup;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the per-field descriptors for a route from an ingested OpenAPI
|
|
81
|
+
* document. Merges `parameters` (path/query/header) and the JSON request-body
|
|
82
|
+
* schema's properties into a single field map. Returns `{}` when the operation
|
|
83
|
+
* isn't found - callers fall back to decorator reflection.
|
|
84
|
+
*/
|
|
85
|
+
declare function openApiFields(lookup: OpenApiLookup, method: string, openapiPath: string): Record<string, FieldDesc>;
|
|
86
|
+
//#endregion
|
|
11
87
|
//#region src/lib/types.d.ts
|
|
12
88
|
/**
|
|
13
89
|
* Context passed to a Nest Silkweave adapter when `SilkweaveModule` wires it
|
|
@@ -24,7 +100,7 @@ interface NestAdapterRegisterContext {
|
|
|
24
100
|
/** Per-adapter context - already forked with `{ adapter: adapter.name, ...userContext }`. */
|
|
25
101
|
baseContext: SilkweaveContext;
|
|
26
102
|
/** Actions filtered to those enabled on this adapter. */
|
|
27
|
-
actions: Action
|
|
103
|
+
actions: Action[];
|
|
28
104
|
}
|
|
29
105
|
/**
|
|
30
106
|
* A Silkweave Nest adapter. Each transport (REST, tRPC, MCP) implements this
|
|
@@ -35,18 +111,13 @@ interface NestAdapterRegisterContext {
|
|
|
35
111
|
*/
|
|
36
112
|
interface NestSilkweaveAdapter {
|
|
37
113
|
/** Adapter discriminator - set on the silkweave context as `ctx.get('adapter')`. */
|
|
38
|
-
readonly name: '
|
|
39
|
-
/**
|
|
40
|
-
* URL prefix the adapter mounts on (e.g. `'/api'`). Surfaced for introspection
|
|
41
|
-
* tooling such as `addSilkweaveActions()` (OpenAPI/Swagger), which reads it to
|
|
42
|
-
* keep generated docs aligned with the live routes.
|
|
43
|
-
*/
|
|
114
|
+
readonly name: 'mcp';
|
|
115
|
+
/** URL prefix the adapter mounts on (e.g. `'/mcp'`). Surfaced for introspection. */
|
|
44
116
|
readonly basePath?: string;
|
|
45
117
|
/**
|
|
46
118
|
* When `true`, the adapter receives every discovered action regardless of
|
|
47
|
-
* each action's `
|
|
48
|
-
*
|
|
49
|
-
* action surface.
|
|
119
|
+
* each action's `isEnabled` gate. Reserved for non-runtime adapters that need
|
|
120
|
+
* the entire action surface.
|
|
50
121
|
*/
|
|
51
122
|
readonly allActions?: boolean;
|
|
52
123
|
/** Register this adapter's routes on Nest's HTTP server. */
|
|
@@ -55,10 +126,17 @@ interface NestSilkweaveAdapter {
|
|
|
55
126
|
interface SilkweaveModuleOptions {
|
|
56
127
|
/** Identity for the silkweave instance - surfaced to MCP clients, OpenAPI, etc. */
|
|
57
128
|
silkweave: SilkweaveOptions;
|
|
58
|
-
/** Adapters to mount.
|
|
129
|
+
/** Adapters to mount. Currently `mcp()`. */
|
|
59
130
|
adapters: NestSilkweaveAdapter[];
|
|
60
131
|
/** Initial context keys merged into every adapter's `baseContext`. */
|
|
61
132
|
context?: Record<string, unknown>;
|
|
133
|
+
/**
|
|
134
|
+
* Optional OpenAPI document (e.g. from `SwaggerModule.createDocument(app, cfg)`)
|
|
135
|
+
* used as an authoritative source when reflecting `@Mcp` tool input schemas.
|
|
136
|
+
* Matched to each method by HTTP verb + path; falls back to decorator
|
|
137
|
+
* reflection when an operation or field isn't present.
|
|
138
|
+
*/
|
|
139
|
+
openapi?: OpenApiDocument;
|
|
62
140
|
}
|
|
63
141
|
declare const SILKWEAVE_MODULE_OPTIONS = "__silkweave_module_options__";
|
|
64
142
|
//#endregion
|
|
@@ -91,219 +169,99 @@ interface McpAdapterOptions {
|
|
|
91
169
|
*/
|
|
92
170
|
declare function mcp(options?: McpAdapterOptions): NestSilkweaveAdapter;
|
|
93
171
|
//#endregion
|
|
94
|
-
//#region src/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
basePath?: string;
|
|
98
|
-
/** Optional bearer-token auth applied to every REST action. */
|
|
99
|
-
auth?: AuthConfig;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* REST adapter for `@silkweave/nestjs`. Registers each discovered `@Action`
|
|
103
|
-
* as an individual route on Nest's HTTP adapter:
|
|
104
|
-
*
|
|
105
|
-
* - HTTP verb comes from `method`, else `GET` for `kind: 'query'`, else `POST`.
|
|
106
|
-
* - Path comes from `path` (joined to `basePath`, may contain `:param`
|
|
107
|
-
* placeholders), else `${basePath}/${actionName-with-slashes}`.
|
|
108
|
-
* - Input is merged from the request body, the `queryParams` query-string
|
|
109
|
-
* fields, and any `:param` path placeholders (see `resolveActionInput`).
|
|
110
|
-
*
|
|
111
|
-
* Routes show up in Nest's `RoutesResolver` logger. They are registered
|
|
112
|
-
* directly on the HTTP adapter (not as Nest controllers), so `@nestjs/swagger`'s
|
|
113
|
-
* controller scanner does not see them - use `addSilkweaveActions()` to add them
|
|
114
|
-
* to the OpenAPI document. Works on `@nestjs/platform-express` out of the box.
|
|
115
|
-
* For `@nestjs/platform-fastify`, register `@fastify/express` first.
|
|
116
|
-
*/
|
|
117
|
-
declare function rest(options?: RestAdapterOptions): NestSilkweaveAdapter;
|
|
118
|
-
//#endregion
|
|
119
|
-
//#region src/adapter/trpc.d.ts
|
|
120
|
-
interface TrpcAdapterOptions {
|
|
121
|
-
/** URL prefix at which the tRPC handler is mounted. Default `'/trpc'`. */
|
|
122
|
-
basePath?: string;
|
|
123
|
-
/** Optional bearer-token auth applied to every tRPC procedure. */
|
|
124
|
-
auth?: AuthConfig;
|
|
125
|
-
}
|
|
172
|
+
//#region src/lib/metadata.d.ts
|
|
173
|
+
/** Reflect-metadata key carrying `@Mcp` options on a controller method. */
|
|
174
|
+
declare const MCP_METADATA = "__silkweave_mcp__";
|
|
126
175
|
/**
|
|
127
|
-
*
|
|
128
|
-
* `@
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* Works on `@nestjs/platform-express`. On `@nestjs/platform-fastify`, register
|
|
135
|
-
* `@fastify/express` first so Nest can serve Express-style middleware.
|
|
176
|
+
* Options for the `@Mcp()` method decorator. Every field is optional - an empty
|
|
177
|
+
* `@Mcp()` exposes the decorated controller route as an MCP tool with its name,
|
|
178
|
+
* description, and input schema fully reflected from the method's route
|
|
179
|
+
* (`@Get`/`@Post`/...), parameter decorators (`@Param`/`@Query`/`@Body`), and
|
|
180
|
+
* any `@nestjs/swagger` (`@ApiOperation`/`@ApiParam`/`@ApiProperty`) or
|
|
181
|
+
* `class-validator` metadata it carries.
|
|
136
182
|
*/
|
|
137
|
-
|
|
138
|
-
//#endregion
|
|
139
|
-
//#region src/adapter/typegen.d.ts
|
|
140
|
-
interface TypegenAdapterOptions {
|
|
141
|
-
/** Output file path for the generated `.d.ts` file. Resolved against `process.cwd()`. Parent directories are created automatically. */
|
|
142
|
-
path: string;
|
|
183
|
+
interface McpMetadata {
|
|
143
184
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* - `'trpc-router'` - `AppRouter` type alias for `createTRPCClient<AppRouter>()`
|
|
147
|
-
* - `'all'` - both
|
|
185
|
+
* MCP tool name override. When unset it is derived from the controller class
|
|
186
|
+
* and method name (e.g. `ChannelsController.findOne` → `ChannelsFindOne`).
|
|
148
187
|
*/
|
|
149
|
-
|
|
188
|
+
name?: string;
|
|
150
189
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* leave it on the default unless you know you want otherwise.
|
|
190
|
+
* Tool description override. When unset it falls back to the method's
|
|
191
|
+
* `@ApiOperation({ summary | description })`, then a generated default.
|
|
154
192
|
*/
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Typegen adapter for `@silkweave/nestjs`. Discovers every `@Action`-decorated
|
|
159
|
-
* method (regardless of `transports` filtering) and writes a single `.d.ts`
|
|
160
|
-
* file with REST input/output interfaces and/or a tRPC `AppRouter` type alias.
|
|
161
|
-
*
|
|
162
|
-
* Designed for the monorepo pattern where the server (this app) is the source
|
|
163
|
-
* of truth for types and consumer apps import from `path` - e.g.
|
|
164
|
-
* `path: '../app/src/types/silkweave.ts'`.
|
|
165
|
-
*/
|
|
166
|
-
declare function typegen(options: TypegenAdapterOptions): NestSilkweaveAdapter;
|
|
167
|
-
//#endregion
|
|
168
|
-
//#region src/lib/metadata.d.ts
|
|
169
|
-
declare const ACTION_METADATA = "__silkweave_action__";
|
|
170
|
-
declare const ACTIONS_METADATA = "__silkweave_actions__";
|
|
171
|
-
type Transport = 'rest' | 'trpc' | 'mcp';
|
|
172
|
-
interface ActionMetadata<I extends object = object, O extends object = object, C = unknown> {
|
|
173
|
-
/** Action name. Defaults to the kebab-cased method name. */
|
|
174
|
-
name?: string;
|
|
175
|
-
/** Human-readable description. Becomes the MCP tool description and REST OpenAPI summary. */
|
|
176
|
-
description: string;
|
|
177
|
-
/** Zod object schema for the action's input. */
|
|
178
|
-
input: z$1.ZodType<I> & {
|
|
179
|
-
shape: Record<string, z$1.ZodTypeAny>;
|
|
180
|
-
};
|
|
181
|
-
/** Optional Zod object schema for the action's output (used by tRPC type inference). */
|
|
182
|
-
output?: z$1.ZodType<O> & {
|
|
183
|
-
shape: Record<string, z$1.ZodTypeAny>;
|
|
184
|
-
};
|
|
193
|
+
description?: string;
|
|
185
194
|
/**
|
|
186
|
-
* Zod
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* the action as a tRPC subscription.
|
|
195
|
+
* Zod raw-shape override merged over the reflected input fields (override
|
|
196
|
+
* wins per field). The escape hatch for shapes reflection can't express
|
|
197
|
+
* losslessly - discriminated unions, custom validators, `@Transform`, etc.
|
|
190
198
|
*/
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
queryParams?: (keyof I)[];
|
|
200
|
-
/** Allowlist of transports that should expose this action. Default: all registered transports. */
|
|
201
|
-
transports?: Transport[];
|
|
202
|
-
/** Dynamic enable check (in addition to `transports`). AND-combined with the transports filter. */
|
|
203
|
-
isEnabled?: (context: SilkweaveContext) => boolean;
|
|
204
|
-
/** Custom MCP `CallToolResult` formatter. See `@silkweave/mcp`'s `smartToolResult`. */
|
|
205
|
-
toolResult?: Action$1<I, O>['toolResult'];
|
|
206
|
-
/** CLI positional-argument keys (unused for HTTP-only adapters, kept for parity with `createAction`). */
|
|
207
|
-
args?: (keyof I)[];
|
|
208
|
-
/** Custom MCP tool name override. If unset, derived from action name as PascalCase. */
|
|
209
|
-
mcpToolName?: string;
|
|
210
|
-
}
|
|
211
|
-
interface ActionsClassMetadata {
|
|
212
|
-
/** Prefix joined to the method-level action name with a dot. e.g. `Actions('users')` + method `list` → `users.list`. */
|
|
213
|
-
prefix?: string;
|
|
214
|
-
/** Class-level transports allowlist. Method-level `transports` overrides; otherwise inherits this. */
|
|
215
|
-
transports?: Transport[];
|
|
216
|
-
}
|
|
217
|
-
interface ResultToolResult<O extends object = object> {
|
|
218
|
-
toolResult?: Action$1<object, O>['toolResult'];
|
|
199
|
+
input?: Record<string, z.ZodType>;
|
|
200
|
+
/**
|
|
201
|
+
* Whether to apply the controller method's parameter-bound pipes
|
|
202
|
+
* (`@Param('id', ParseIntPipe)`) when re-binding the call. Default `'apply'`.
|
|
203
|
+
* Global/`ValidationPipe`, interceptors, and exception filters never run -
|
|
204
|
+
* the method is invoked directly, not through Nest's HTTP request pipeline.
|
|
205
|
+
*/
|
|
206
|
+
pipes?: 'apply' | 'skip';
|
|
219
207
|
}
|
|
220
|
-
type AnyActionMetadata = ActionMetadata<object, object> & ResultToolResult<object>;
|
|
221
|
-
declare const ACTION_RESPONSE_KEY = "__silkweave_response__";
|
|
222
208
|
//#endregion
|
|
223
|
-
//#region src/decorator/
|
|
209
|
+
//#region src/decorator/mcp.d.ts
|
|
224
210
|
/**
|
|
225
|
-
* Method decorator that
|
|
211
|
+
* Method decorator that exposes an existing NestJS controller route as an MCP
|
|
212
|
+
* tool. It is **additive** - the route keeps serving HTTP exactly as before;
|
|
213
|
+
* `@Mcp()` just opts the method into MCP discovery.
|
|
226
214
|
*
|
|
227
|
-
* The
|
|
228
|
-
*
|
|
229
|
-
*
|
|
215
|
+
* The tool's name, description, and input schema are reflected from the
|
|
216
|
+
* method's own metadata:
|
|
217
|
+
* - **fields** from the parameter decorators (`@Param`/`@Query`/`@Body`) - a
|
|
218
|
+
* `@Param('id')` becomes an `id` field; a whole-DTO `@Body() dto: CreateDto`
|
|
219
|
+
* is flattened to its properties,
|
|
220
|
+
* - **types/constraints/descriptions** from `@nestjs/swagger`
|
|
221
|
+
* (`@ApiParam`/`@ApiQuery`/`@ApiProperty`/`@ApiOperation`) and, when present,
|
|
222
|
+
* `class-validator` decorators on the DTOs,
|
|
223
|
+
* - optionally refined by an OpenAPI document passed to `SilkweaveModule`.
|
|
230
224
|
*
|
|
231
|
-
*
|
|
232
|
-
* and
|
|
233
|
-
* `auth`). The class instance is a normal Nest provider, so other services can
|
|
234
|
-
* be injected via the constructor.
|
|
225
|
+
* On a tool call the input is split back into the method's positional arguments
|
|
226
|
+
* and the method is invoked directly (with `@UseGuards` guards applied first).
|
|
235
227
|
*
|
|
236
228
|
* @example
|
|
237
229
|
* ```ts
|
|
238
|
-
* @
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* @
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* })
|
|
248
|
-
* list(input: { limit?: number }, ctx: SilkweaveContext) {
|
|
249
|
-
* return this.db.listUsers(input.limit)
|
|
230
|
+
* @Controller('sessions/:sessionId/channels')
|
|
231
|
+
* export class ChannelsController {
|
|
232
|
+
* @Get(':channelId')
|
|
233
|
+
* @ApiOperation({ summary: 'Get a specific channel by ID' })
|
|
234
|
+
* @ApiParam({ name: 'sessionId', description: 'Session ID' })
|
|
235
|
+
* @ApiParam({ name: 'channelId', description: 'Channel ID' })
|
|
236
|
+
* @Mcp()
|
|
237
|
+
* findOne(@Param('sessionId') sessionId: string, @Param('channelId') channelId: string) {
|
|
238
|
+
* return this.service.get(sessionId, channelId)
|
|
250
239
|
* }
|
|
251
240
|
* }
|
|
252
241
|
* ```
|
|
253
242
|
*/
|
|
254
|
-
declare function
|
|
243
|
+
declare function Mcp(options?: McpMetadata): MethodDecorator;
|
|
255
244
|
//#endregion
|
|
256
|
-
//#region src/
|
|
257
|
-
|
|
258
|
-
* Class decorator that groups a provider's `@Action` methods under a common
|
|
259
|
-
* prefix. The prefix is joined to each method's action name with a dot
|
|
260
|
-
* (e.g. `@Actions('users')` + method `list` → action name `users.list`).
|
|
261
|
-
*
|
|
262
|
-
* The class itself remains a normal Nest provider - add `@Injectable()`
|
|
263
|
-
* separately so it can be resolved by the DI container.
|
|
264
|
-
*
|
|
265
|
-
* Accepts either a prefix string (shorthand) or a full options object:
|
|
266
|
-
* ```ts
|
|
267
|
-
* @Actions('users')
|
|
268
|
-
* @Actions({ prefix: 'users', transports: ['rest', 'trpc'] })
|
|
269
|
-
* ```
|
|
270
|
-
*/
|
|
271
|
-
declare function Actions(prefixOrOptions?: string | ActionsClassMetadata): ClassDecorator;
|
|
272
|
-
//#endregion
|
|
273
|
-
//#region src/lib/discovery.d.ts
|
|
274
|
-
declare class ActionDiscovery {
|
|
245
|
+
//#region src/lib/controllerDiscovery.d.ts
|
|
246
|
+
declare class ControllerDiscovery {
|
|
275
247
|
private readonly discovery;
|
|
276
248
|
private readonly scanner;
|
|
277
249
|
private readonly reflector;
|
|
278
250
|
private readonly moduleRef;
|
|
279
251
|
constructor(discovery: DiscoveryService, scanner: MetadataScanner, reflector: Reflector, moduleRef: ModuleRef);
|
|
280
252
|
/**
|
|
281
|
-
* Walk every Nest provider, find methods annotated with `@
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* `ctx.get('request')`, populated by REST/tRPC and by MCP-over-HTTP from the
|
|
287
|
-
* SDK's `extra.requestInfo`) and (b) bind `this` to the resolved Nest provider
|
|
288
|
-
* so DI-injected dependencies remain available.
|
|
253
|
+
* Walk every Nest provider/controller, find methods annotated with `@Mcp`,
|
|
254
|
+
* and build a core `Action` per method whose input schema is reflected from
|
|
255
|
+
* the route + parameter decorators (+ optional OpenAPI document) and whose
|
|
256
|
+
* `run` re-binds the validated input back into the method's positional
|
|
257
|
+
* arguments (with `@UseGuards` guards applied first).
|
|
289
258
|
*/
|
|
290
|
-
discover(): Action
|
|
259
|
+
discover(openapi?: OpenApiDocument): Action[];
|
|
291
260
|
private toAction;
|
|
261
|
+
/** Build the merged Zod input shape and the per-argument re-bind plan. */
|
|
262
|
+
private buildInput;
|
|
292
263
|
}
|
|
293
264
|
//#endregion
|
|
294
|
-
//#region src/lib/filter.d.ts
|
|
295
|
-
/**
|
|
296
|
-
* Compile a `transports` allowlist + optional user `isEnabled` into a single
|
|
297
|
-
* `(ctx) => boolean` callback compatible with `Action.isEnabled`.
|
|
298
|
-
*
|
|
299
|
-
* - If `transports` is omitted, the action runs on every adapter.
|
|
300
|
-
* - If `transports` is set, the action is gated on `ctx.get<string>('adapter')`
|
|
301
|
-
* matching one of the listed transports. Each adapter in `@silkweave/nestjs`
|
|
302
|
-
* forks its context with `{ adapter: 'rest' | 'trpc' | 'mcp' }`.
|
|
303
|
-
* - If both `transports` and `userIsEnabled` are set, they are AND-combined.
|
|
304
|
-
*/
|
|
305
|
-
declare function buildIsEnabled(transports: Transport[] | undefined, userIsEnabled: ((ctx: SilkweaveContext) => boolean) | undefined): ((ctx: SilkweaveContext) => boolean) | undefined;
|
|
306
|
-
//#endregion
|
|
307
265
|
//#region src/lib/guards.d.ts
|
|
308
266
|
type GuardRef = Type<CanActivate> | CanActivate;
|
|
309
267
|
/**
|
|
@@ -327,33 +285,69 @@ declare function collectGuards(reflector: Reflector, classRef: Type<unknown>, ha
|
|
|
327
285
|
*/
|
|
328
286
|
declare function runGuards(guards: GuardRef[], moduleRef: ModuleRef, reflector: Reflector, classRef: Type<unknown>, handler: (...args: unknown[]) => unknown, request: unknown, response: unknown, contextType?: 'http' | 'rpc'): Promise<void>;
|
|
329
287
|
//#endregion
|
|
330
|
-
//#region src/lib/
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
288
|
+
//#region src/lib/rebind.d.ts
|
|
289
|
+
/**
|
|
290
|
+
* Instruction for reconstructing one positional handler argument from the flat
|
|
291
|
+
* MCP tool input. Built at discovery time, consumed by {@link invokeRebound}.
|
|
292
|
+
*/
|
|
293
|
+
type Binding = {
|
|
294
|
+
kind: 'value';
|
|
295
|
+
field: string;
|
|
296
|
+
source: 'path' | 'query' | 'body';
|
|
297
|
+
metatype?: unknown;
|
|
298
|
+
pipes?: unknown[];
|
|
299
|
+
} | {
|
|
300
|
+
kind: 'object';
|
|
301
|
+
source: 'query' | 'body';
|
|
302
|
+
fields: string[];
|
|
303
|
+
metatype?: unknown;
|
|
304
|
+
pipes?: unknown[];
|
|
305
|
+
} | {
|
|
306
|
+
kind: 'params';
|
|
307
|
+
fields: string[];
|
|
308
|
+
} | {
|
|
309
|
+
kind: 'request';
|
|
310
|
+
} | {
|
|
311
|
+
kind: 'response';
|
|
312
|
+
} | {
|
|
313
|
+
kind: 'headers';
|
|
314
|
+
data?: string;
|
|
315
|
+
} | {
|
|
316
|
+
kind: 'ip';
|
|
317
|
+
} | {
|
|
318
|
+
kind: 'host';
|
|
319
|
+
data?: string;
|
|
320
|
+
} | {
|
|
321
|
+
kind: 'missing';
|
|
322
|
+
};
|
|
323
|
+
interface RequestLike {
|
|
324
|
+
headers?: Record<string, unknown>;
|
|
325
|
+
ip?: unknown;
|
|
326
|
+
hosts?: Record<string, unknown>;
|
|
336
327
|
}
|
|
337
328
|
/**
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
* `
|
|
341
|
-
* field split (`pathParamNames` + `queryParams`). Schemas are inlined from the
|
|
342
|
-
* Zod input/output via `z.toJSONSchema`; no shared components are emitted.
|
|
329
|
+
* Reconstruct the controller method's positional arguments from the validated
|
|
330
|
+
* tool `input` (and the request stand-in for `@Req`/`@Headers`/...), then call
|
|
331
|
+
* it. `applyParamPipes` controls whether parameter-bound pipes run.
|
|
343
332
|
*/
|
|
344
|
-
declare function
|
|
333
|
+
declare function invokeRebound(method: (...args: any[]) => any, instance: object, input: Record<string, unknown>, bindings: Binding[], request: RequestLike | undefined, applyParamPipes: boolean): Promise<unknown>;
|
|
334
|
+
/** Map a non-input parameter slot (`@Req`/`@Headers`/`@Ip`/...) to its runtime binding. */
|
|
335
|
+
declare function specialBinding(paramtype: number, data: string | undefined): Binding | null;
|
|
345
336
|
//#endregion
|
|
346
337
|
//#region src/lib/silkweave.module.d.ts
|
|
347
338
|
/**
|
|
348
339
|
* Root module for `@silkweave/nestjs`.
|
|
349
340
|
*
|
|
350
|
-
* Discovers every `@
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
341
|
+
* Discovers every `@Mcp`-decorated **controller method** via `DiscoveryService`,
|
|
342
|
+
* reflects each into a Silkweave action (input schema from the route + parameter
|
|
343
|
+
* decorators + optional OpenAPI document; invocation by re-binding the validated
|
|
344
|
+
* input back into the method), and registers the configured adapter(s) - `mcp()` -
|
|
345
|
+
* directly on Nest's HTTP adapter inside `configure()`.
|
|
346
|
+
*
|
|
347
|
+
* Because `configure()` runs during `registerModules` - before Nest's
|
|
348
|
+
* `registerRouter()` step - Silkweave's routes always sit ahead of every
|
|
349
|
+
* controller in the Express stack. The controllers keep serving HTTP exactly as
|
|
350
|
+
* before; `@Mcp` is purely additive.
|
|
357
351
|
*
|
|
358
352
|
* @example
|
|
359
353
|
* ```ts
|
|
@@ -361,13 +355,10 @@ declare function buildActionPaths(actions: Action$1[], options?: ActionPathsOpti
|
|
|
361
355
|
* imports: [
|
|
362
356
|
* SilkweaveModule.forRoot({
|
|
363
357
|
* silkweave: { name: 'app', description: 'My App', version: '1.0.0' },
|
|
364
|
-
* adapters: [
|
|
365
|
-
* rest({ basePath: '/api' }),
|
|
366
|
-
* trpc({ basePath: '/trpc' }),
|
|
367
|
-
* mcp({ basePath: '/mcp' })
|
|
368
|
-
* ]
|
|
358
|
+
* adapters: [mcp({ basePath: '/mcp' })]
|
|
369
359
|
* })
|
|
370
|
-
* ]
|
|
360
|
+
* ],
|
|
361
|
+
* controllers: [ChannelsController]
|
|
371
362
|
* })
|
|
372
363
|
* export class AppModule {}
|
|
373
364
|
* ```
|
|
@@ -376,50 +367,10 @@ declare class SilkweaveModule implements NestModule {
|
|
|
376
367
|
private readonly options;
|
|
377
368
|
private readonly discovery;
|
|
378
369
|
private readonly httpAdapterHost;
|
|
379
|
-
constructor(options: SilkweaveModuleOptions, discovery:
|
|
370
|
+
constructor(options: SilkweaveModuleOptions, discovery: ControllerDiscovery, httpAdapterHost: HttpAdapterHost);
|
|
380
371
|
static forRoot(options: SilkweaveModuleOptions): DynamicModule;
|
|
381
372
|
configure(_consumer: MiddlewareConsumer): void;
|
|
382
373
|
}
|
|
383
374
|
//#endregion
|
|
384
|
-
|
|
385
|
-
interface SilkweaveSwaggerOptions {
|
|
386
|
-
/**
|
|
387
|
-
* URL prefix the `rest()` adapter mounts on. Defaults to the configured
|
|
388
|
-
* `rest()` adapter's `basePath`, falling back to `'/api'`.
|
|
389
|
-
*/
|
|
390
|
-
basePath?: string;
|
|
391
|
-
/** OpenAPI tag the actions are grouped under. Default `'Actions'`. */
|
|
392
|
-
tag?: string;
|
|
393
|
-
/**
|
|
394
|
-
* Include actions that are *not* enabled on the REST transport (gated out via
|
|
395
|
-
* `transports` / `isEnabled`). Default `false` - the document mirrors the
|
|
396
|
-
* routes the `rest()` adapter actually registers.
|
|
397
|
-
*/
|
|
398
|
-
includeDisabled?: boolean;
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Merge every REST-exposed Silkweave `@Action` into a NestJS Swagger
|
|
402
|
-
* `OpenAPIObject`.
|
|
403
|
-
*
|
|
404
|
-
* `@nestjs/swagger` builds its document by scanning **controllers**, but
|
|
405
|
-
* Silkweave registers action routes directly on the HTTP adapter (so they sit
|
|
406
|
-
* ahead of controllers in the request pipeline) - which means the scanner never
|
|
407
|
-
* sees them. This helper closes that gap: it discovers the actions through the
|
|
408
|
-
* same `ActionDiscovery` provider the `rest()` adapter uses, builds OpenAPI
|
|
409
|
-
* paths with the same routing logic (`buildActionPaths`), and merges them into
|
|
410
|
-
* the document. The result stays in sync with the live routes without any
|
|
411
|
-
* dynamic controllers.
|
|
412
|
-
*
|
|
413
|
-
* Call it between `SwaggerModule.createDocument()` and `SwaggerModule.setup()`:
|
|
414
|
-
*
|
|
415
|
-
* @example
|
|
416
|
-
* ```ts
|
|
417
|
-
* const document = SwaggerModule.createDocument(app, config)
|
|
418
|
-
* addSilkweaveActions(app, document)
|
|
419
|
-
* SwaggerModule.setup('api/docs', app, document)
|
|
420
|
-
* ```
|
|
421
|
-
*/
|
|
422
|
-
declare function addSilkweaveActions(app: INestApplication, document: OpenAPIObject, options?: SilkweaveSwaggerOptions): OpenAPIObject;
|
|
423
|
-
//#endregion
|
|
424
|
-
export { ACTIONS_METADATA, ACTION_METADATA, ACTION_RESPONSE_KEY, Action, ActionDiscovery, ActionMetadata, ActionPathsOptions, Actions, type ActionsClassMetadata, AnyActionMetadata, type InferTrpcRouter, McpAdapterOptions, NestAdapterRegisterContext, NestSilkweaveAdapter, RestAdapterOptions, ResultToolResult, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, SilkweaveModuleOptions, SilkweaveSwaggerOptions, type Transport, TrpcAdapterOptions, TypegenAdapterOptions, addSilkweaveActions, buildActionPaths, buildIsEnabled, collectGuards, mcp, rest, runGuards, trpc, typegen };
|
|
375
|
+
export { Binding, ControllerDiscovery, FieldDesc, MCP_METADATA, Mcp, McpAdapterOptions, McpMetadata, NestAdapterRegisterContext, NestSilkweaveAdapter, OpenApiDocument, OpenApiLookup, SILKWEAVE_MODULE_OPTIONS, SilkweaveModule, SilkweaveModuleOptions, apiPropertyToField, buildOpenApiLookup, classValidatorToField, collectGuards, designTypeToField, fieldToZod, invokeRebound, mcp, mergeField, normalizeEnum, openApiFields, openapiSchemaToField, reflectDtoFields, runGuards, specialBinding, swaggerParamToField, typeTokenToBase };
|
|
425
376
|
//# sourceMappingURL=index.d.mts.map
|
package/build/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/reflect/schema.ts","../src/lib/reflect/openapi.ts","../src/lib/types.ts","../src/adapter/mcp.ts","../src/lib/metadata.ts","../src/decorator/mcp.ts","../src/lib/controllerDiscovery.ts","../src/lib/guards.ts","../src/lib/rebind.ts","../src/lib/silkweave.module.ts"],"mappings":"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"}
|