@silkweave/nestjs 2.4.0 → 2.5.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 +139 -6
- package/build/index-C1W-O7EX.d.mts +46 -0
- package/build/index-C1W-O7EX.d.mts.map +1 -0
- package/build/index.d.mts +126 -203
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +285 -8729
- package/build/index.mjs.map +1 -1
- package/build/mcp.d.mts +35 -0
- package/build/mcp.d.mts.map +1 -0
- package/build/mcp.mjs +61 -0
- package/build/mcp.mjs.map +1 -0
- package/build/trpc.d.mts +39 -0
- package/build/trpc.d.mts.map +1 -0
- package/build/trpc.mjs +59 -0
- package/build/trpc.mjs.map +1 -0
- package/build/typegen.d.mts +32 -0
- package/build/typegen.d.mts.map +1 -0
- package/build/typegen.mjs +36 -0
- package/build/typegen.mjs.map +1 -0
- package/build/types-ByWkPWx2.d.mts +162 -0
- package/build/types-ByWkPWx2.d.mts.map +1 -0
- package/package.json +41 -6
package/build/mcp.d.mts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { n as NestSilkweaveAdapter } from "./types-ByWkPWx2.mjs";
|
|
2
|
+
import { t as AuthConfig } from "./index-C1W-O7EX.mjs";
|
|
3
|
+
import { CorsOptions } from "cors";
|
|
4
|
+
|
|
5
|
+
//#region src/adapter/mcp.d.ts
|
|
6
|
+
interface McpAdapterOptions {
|
|
7
|
+
/** URL prefix the MCP namespace lives under - the transport itself is at this exact path. Default `'/mcp'`. */
|
|
8
|
+
basePath?: string;
|
|
9
|
+
/** Optional bearer-token / OAuth 2.1 config. */
|
|
10
|
+
auth?: AuthConfig;
|
|
11
|
+
/** CORS configuration. `false` to disable, `true`/omitted for permissive defaults, or a `CorsOptions` object. */
|
|
12
|
+
cors?: CorsOptions | boolean;
|
|
13
|
+
/** Mount the sideload resource route at `${basePath}/resource/:id`. Default `true`. */
|
|
14
|
+
sideloadResources?: boolean;
|
|
15
|
+
/** Directory the sideload route reads from. Default `'resources'`. */
|
|
16
|
+
resourceDir?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* MCP adapter for `@silkweave/nestjs`. Registers the MCP Streamable HTTP
|
|
20
|
+
* transport, sideload, well-known and OAuth routes individually on Nest's
|
|
21
|
+
* HTTP adapter at the configured `basePath` (default `/mcp`):
|
|
22
|
+
*
|
|
23
|
+
* - `POST/GET/DELETE ${basePath}` - Streamable HTTP transport
|
|
24
|
+
* - `GET ${basePath}/resource/:id` - sideload (`sideloadResources` opt-out)
|
|
25
|
+
* - `GET ${basePath}/.well-known/oauth-protected-resource` - RFC 9728 metadata (when `auth.resourceUrl`/`auth.authorizationServers` set)
|
|
26
|
+
* - `GET ${basePath}/authorize`, `POST ${basePath}/token`, `POST ${basePath}/register`, `GET ${basePath}${callbackPath}` (when `auth.provider` set)
|
|
27
|
+
*
|
|
28
|
+
* Each route is a real Nest-level route - they show up in
|
|
29
|
+
* `RoutesResolver`'s log and there is no sub-app or middleware-slot
|
|
30
|
+
* indirection.
|
|
31
|
+
*/
|
|
32
|
+
declare function mcp(options?: McpAdapterOptions): NestSilkweaveAdapter;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { McpAdapterOptions, mcp };
|
|
35
|
+
//# sourceMappingURL=mcp.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.mts","names":[],"sources":["../src/adapter/mcp.ts"],"mappings":";;;;;UAaiB,iBAAA;;EAEf,QAAA;EAFgC;EAIhC,IAAA,GAAO,UAAA;EAEW;EAAlB,IAAA,GAAO,WAAA;EAFP;EAIA,iBAAA;EAFA;EAIA,WAAA;AAAA;;;;AA6BF;;;;;;;;;;;iBAAgB,GAAA,CAAI,OAAA,GAAS,iBAAA,GAAyB,oBAAA"}
|
package/build/mcp.mjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { authMiddleware, mcpCors, mcpTransport, oauthRoutes, protectedResourceMetadata, sideloadResource } from "@silkweave/mcp";
|
|
2
|
+
import express from "express";
|
|
3
|
+
//#region src/adapter/mcp.ts
|
|
4
|
+
function compose(...handlers) {
|
|
5
|
+
return (req, res, next) => {
|
|
6
|
+
let i = 0;
|
|
7
|
+
const dispatch = () => {
|
|
8
|
+
const h = handlers[i++];
|
|
9
|
+
if (!h) return next();
|
|
10
|
+
h(req, res, (err) => err ? next(err) : dispatch());
|
|
11
|
+
};
|
|
12
|
+
dispatch();
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* MCP adapter for `@silkweave/nestjs`. Registers the MCP Streamable HTTP
|
|
17
|
+
* transport, sideload, well-known and OAuth routes individually on Nest's
|
|
18
|
+
* HTTP adapter at the configured `basePath` (default `/mcp`):
|
|
19
|
+
*
|
|
20
|
+
* - `POST/GET/DELETE ${basePath}` - Streamable HTTP transport
|
|
21
|
+
* - `GET ${basePath}/resource/:id` - sideload (`sideloadResources` opt-out)
|
|
22
|
+
* - `GET ${basePath}/.well-known/oauth-protected-resource` - RFC 9728 metadata (when `auth.resourceUrl`/`auth.authorizationServers` set)
|
|
23
|
+
* - `GET ${basePath}/authorize`, `POST ${basePath}/token`, `POST ${basePath}/register`, `GET ${basePath}${callbackPath}` (when `auth.provider` set)
|
|
24
|
+
*
|
|
25
|
+
* Each route is a real Nest-level route - they show up in
|
|
26
|
+
* `RoutesResolver`'s log and there is no sub-app or middleware-slot
|
|
27
|
+
* indirection.
|
|
28
|
+
*/
|
|
29
|
+
function mcp(options = {}) {
|
|
30
|
+
return {
|
|
31
|
+
name: "mcp",
|
|
32
|
+
register({ httpAdapter, silkweaveOptions, baseContext, actions }) {
|
|
33
|
+
const basePath = (options.basePath ?? "/mcp").replace(/\/$/, "");
|
|
34
|
+
if (!basePath) throw new Error("@silkweave/nestjs mcp(): basePath cannot be empty or \"/\" - pick a path like \"/mcp\".");
|
|
35
|
+
const adapter = httpAdapter;
|
|
36
|
+
const corsHandler = mcpCors(options.cors ?? true);
|
|
37
|
+
const auth = options.auth;
|
|
38
|
+
const guard = auth ? authMiddleware(auth, baseContext) : null;
|
|
39
|
+
const prefix = (...handlers) => handlers.filter((h) => Boolean(h));
|
|
40
|
+
if (auth?.authorizationServers?.length && auth.resourceUrl) adapter.get(`${basePath}/.well-known/oauth-protected-resource`, ...prefix(corsHandler, protectedResourceMetadata(auth)));
|
|
41
|
+
if (auth?.provider) {
|
|
42
|
+
const oauth = oauthRoutes(auth);
|
|
43
|
+
adapter.get(`${basePath}/.well-known/oauth-authorization-server`, ...prefix(corsHandler, oauth.wellKnownAuthServer));
|
|
44
|
+
adapter.get(`${basePath}/authorize`, ...prefix(corsHandler, oauth.authorize));
|
|
45
|
+
adapter.get(`${basePath}${oauth.callbackPath}`, ...prefix(corsHandler, oauth.callback));
|
|
46
|
+
adapter.post(`${basePath}/token`, ...prefix(corsHandler, ...oauth.token));
|
|
47
|
+
adapter.post(`${basePath}/register`, ...prefix(corsHandler, ...oauth.register));
|
|
48
|
+
}
|
|
49
|
+
const protect = guard ? (h) => compose(guard, h) : (h) => h;
|
|
50
|
+
if (options.sideloadResources !== false) adapter.get(`${basePath}/resource/:id`, ...prefix(corsHandler, protect(sideloadResource({ resourceDir: options.resourceDir }))));
|
|
51
|
+
const transport = mcpTransport(silkweaveOptions, baseContext, actions);
|
|
52
|
+
adapter.post(basePath, ...prefix(corsHandler, express.json(), protect(transport.post)));
|
|
53
|
+
adapter.get(basePath, ...prefix(corsHandler, protect(transport.stream)));
|
|
54
|
+
adapter.delete(basePath, ...prefix(corsHandler, protect(transport.stream)));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { mcp };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=mcp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.mjs","names":[],"sources":["../src/adapter/mcp.ts"],"sourcesContent":["import { AuthConfig } from '@silkweave/auth'\nimport {\n authMiddleware,\n mcpCors,\n mcpTransport,\n oauthRoutes,\n protectedResourceMetadata,\n sideloadResource\n} from '@silkweave/mcp'\nimport { type CorsOptions } from 'cors'\nimport express, { type RequestHandler } from 'express'\nimport type { NestAdapterRegisterContext, NestSilkweaveAdapter } from '../lib/types.js'\n\nexport interface McpAdapterOptions {\n /** URL prefix the MCP namespace lives under - the transport itself is at this exact path. Default `'/mcp'`. */\n basePath?: string\n /** Optional bearer-token / OAuth 2.1 config. */\n auth?: AuthConfig\n /** CORS configuration. `false` to disable, `true`/omitted for permissive defaults, or a `CorsOptions` object. */\n cors?: CorsOptions | boolean\n /** Mount the sideload resource route at `${basePath}/resource/:id`. Default `true`. */\n sideloadResources?: boolean\n /** Directory the sideload route reads from. Default `'resources'`. */\n resourceDir?: string\n}\n\nfunction compose(...handlers: RequestHandler[]): RequestHandler {\n return (req, res, next) => {\n let i = 0\n const dispatch: () => void = () => {\n const h = handlers[i++]\n if (!h) { return next() }\n h(req, res, (err) => err ? next(err) : dispatch())\n }\n dispatch()\n }\n}\n\n/**\n * MCP adapter for `@silkweave/nestjs`. Registers the MCP Streamable HTTP\n * transport, sideload, well-known and OAuth routes individually on Nest's\n * HTTP adapter at the configured `basePath` (default `/mcp`):\n *\n * - `POST/GET/DELETE ${basePath}` - Streamable HTTP transport\n * - `GET ${basePath}/resource/:id` - sideload (`sideloadResources` opt-out)\n * - `GET ${basePath}/.well-known/oauth-protected-resource` - RFC 9728 metadata (when `auth.resourceUrl`/`auth.authorizationServers` set)\n * - `GET ${basePath}/authorize`, `POST ${basePath}/token`, `POST ${basePath}/register`, `GET ${basePath}${callbackPath}` (when `auth.provider` set)\n *\n * Each route is a real Nest-level route - they show up in\n * `RoutesResolver`'s log and there is no sub-app or middleware-slot\n * indirection.\n */\nexport function mcp(options: McpAdapterOptions = {}): NestSilkweaveAdapter {\n return {\n name: 'mcp',\n register({ httpAdapter, silkweaveOptions, baseContext, actions }: NestAdapterRegisterContext): void {\n const basePath = (options.basePath ?? '/mcp').replace(/\\/$/, '')\n if (!basePath) { throw new Error('@silkweave/nestjs mcp(): basePath cannot be empty or \"/\" - pick a path like \"/mcp\".') }\n\n const adapter = httpAdapter as unknown as {\n get: (path: string, ...h: RequestHandler[]) => unknown\n post: (path: string, ...h: RequestHandler[]) => unknown\n delete: (path: string, ...h: RequestHandler[]) => unknown\n }\n\n const corsHandler = mcpCors(options.cors ?? true)\n const auth = options.auth\n const guard = auth ? authMiddleware(auth, baseContext) : null\n const prefix = (...handlers: (RequestHandler | null)[]): RequestHandler[] =>\n handlers.filter((h): h is RequestHandler => Boolean(h))\n\n // Public auth-discovery / OAuth routes - registered first so they're\n // never inadvertently guarded by the auth middleware.\n if (auth?.authorizationServers?.length && auth.resourceUrl) {\n adapter.get(\n `${basePath}/.well-known/oauth-protected-resource`,\n ...prefix(corsHandler, protectedResourceMetadata(auth))\n )\n }\n if (auth?.provider) {\n const oauth = oauthRoutes(auth)\n adapter.get(`${basePath}/.well-known/oauth-authorization-server`, ...prefix(corsHandler, oauth.wellKnownAuthServer))\n adapter.get(`${basePath}/authorize`, ...prefix(corsHandler, oauth.authorize))\n adapter.get(`${basePath}${oauth.callbackPath}`, ...prefix(corsHandler, oauth.callback))\n adapter.post(`${basePath}/token`, ...prefix(corsHandler, ...oauth.token))\n adapter.post(`${basePath}/register`, ...prefix(corsHandler, ...oauth.register))\n }\n\n // Protected routes - wrapped with auth middleware (when configured).\n const protect = guard ? (h: RequestHandler) => compose(guard, h) : (h: RequestHandler) => h\n\n if (options.sideloadResources !== false) {\n adapter.get(`${basePath}/resource/:id`, ...prefix(corsHandler, protect(sideloadResource({ resourceDir: options.resourceDir }))))\n }\n\n const transport = mcpTransport(silkweaveOptions, baseContext, actions)\n adapter.post(basePath, ...prefix(corsHandler, express.json(), protect(transport.post)))\n adapter.get(basePath, ...prefix(corsHandler, protect(transport.stream)))\n adapter.delete(basePath, ...prefix(corsHandler, protect(transport.stream)))\n }\n }\n}\n"],"mappings":";;;AA0BA,SAAS,QAAQ,GAAG,UAA4C;AAC9D,SAAQ,KAAK,KAAK,SAAS;EACzB,IAAI,IAAI;EACR,MAAM,iBAA6B;GACjC,MAAM,IAAI,SAAS;AACnB,OAAI,CAAC,EAAK,QAAO,MAAM;AACvB,KAAE,KAAK,MAAM,QAAQ,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC;;AAEpD,YAAU;;;;;;;;;;;;;;;;;AAkBd,SAAgB,IAAI,UAA6B,EAAE,EAAwB;AACzE,QAAO;EACL,MAAM;EACN,SAAS,EAAE,aAAa,kBAAkB,aAAa,WAA6C;GAClG,MAAM,YAAY,QAAQ,YAAY,QAAQ,QAAQ,OAAO,GAAG;AAChE,OAAI,CAAC,SAAY,OAAM,IAAI,MAAM,0FAAsF;GAEvH,MAAM,UAAU;GAMhB,MAAM,cAAc,QAAQ,QAAQ,QAAQ,KAAK;GACjD,MAAM,OAAO,QAAQ;GACrB,MAAM,QAAQ,OAAO,eAAe,MAAM,YAAY,GAAG;GACzD,MAAM,UAAU,GAAG,aACjB,SAAS,QAAQ,MAA2B,QAAQ,EAAE,CAAC;AAIzD,OAAI,MAAM,sBAAsB,UAAU,KAAK,YAC7C,SAAQ,IACN,GAAG,SAAS,wCACZ,GAAG,OAAO,aAAa,0BAA0B,KAAK,CAAC,CACxD;AAEH,OAAI,MAAM,UAAU;IAClB,MAAM,QAAQ,YAAY,KAAK;AAC/B,YAAQ,IAAI,GAAG,SAAS,0CAA0C,GAAG,OAAO,aAAa,MAAM,oBAAoB,CAAC;AACpH,YAAQ,IAAI,GAAG,SAAS,aAAa,GAAG,OAAO,aAAa,MAAM,UAAU,CAAC;AAC7E,YAAQ,IAAI,GAAG,WAAW,MAAM,gBAAgB,GAAG,OAAO,aAAa,MAAM,SAAS,CAAC;AACvF,YAAQ,KAAK,GAAG,SAAS,SAAS,GAAG,OAAO,aAAa,GAAG,MAAM,MAAM,CAAC;AACzE,YAAQ,KAAK,GAAG,SAAS,YAAY,GAAG,OAAO,aAAa,GAAG,MAAM,SAAS,CAAC;;GAIjF,MAAM,UAAU,SAAS,MAAsB,QAAQ,OAAO,EAAE,IAAI,MAAsB;AAE1F,OAAI,QAAQ,sBAAsB,MAChC,SAAQ,IAAI,GAAG,SAAS,gBAAgB,GAAG,OAAO,aAAa,QAAQ,iBAAiB,EAAE,aAAa,QAAQ,aAAa,CAAC,CAAC,CAAC,CAAC;GAGlI,MAAM,YAAY,aAAa,kBAAkB,aAAa,QAAQ;AACtE,WAAQ,KAAK,UAAU,GAAG,OAAO,aAAa,QAAQ,MAAM,EAAE,QAAQ,UAAU,KAAK,CAAC,CAAC;AACvF,WAAQ,IAAI,UAAU,GAAG,OAAO,aAAa,QAAQ,UAAU,OAAO,CAAC,CAAC;AACxE,WAAQ,OAAO,UAAU,GAAG,OAAO,aAAa,QAAQ,UAAU,OAAO,CAAC,CAAC;;EAE9E"}
|
package/build/trpc.d.mts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { n as NestSilkweaveAdapter } from "./types-ByWkPWx2.mjs";
|
|
2
|
+
import { t as AuthConfig } from "./index-C1W-O7EX.mjs";
|
|
3
|
+
import { CorsOptions } from "cors";
|
|
4
|
+
|
|
5
|
+
//#region src/adapter/trpc.d.ts
|
|
6
|
+
interface TrpcAdapterOptions {
|
|
7
|
+
/** URL prefix the tRPC handler mounts on. Default `'/trpc'`. */
|
|
8
|
+
basePath?: string;
|
|
9
|
+
/**
|
|
10
|
+
* CORS configuration. `false` to disable, `true`/omitted for permissive
|
|
11
|
+
* defaults, or a `CorsOptions` object. For cookie-based auth set
|
|
12
|
+
* `{ origin: '<spa-origin>', credentials: true }` so the browser sends the
|
|
13
|
+
* session cookie (`credentials: 'include'` / `withCredentials`).
|
|
14
|
+
*/
|
|
15
|
+
cors?: CorsOptions | boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Optional bearer-token / OAuth 2.1 config. Usually omitted - `@Trpc` routes
|
|
18
|
+
* authenticate with their own `@UseGuards()` reading the real Express request
|
|
19
|
+
* (cookies/headers), so no separate auth config is needed. Provide this only
|
|
20
|
+
* to additionally validate an `Authorization` bearer at the transport edge.
|
|
21
|
+
*/
|
|
22
|
+
auth?: AuthConfig;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* tRPC adapter for `@silkweave/nestjs`. Mounts a single tRPC HTTP handler (httpBatch
|
|
26
|
+
* for queries/mutations, SSE for subscriptions) on Nest's HTTP adapter at the
|
|
27
|
+
* configured `basePath` (default `/trpc`), built from every `@Trpc`-decorated
|
|
28
|
+
* controller method.
|
|
29
|
+
*
|
|
30
|
+
* Each procedure runs the method's `@UseGuards()` first, with the guard receiving
|
|
31
|
+
* a real `ExecutionContext` whose `switchToHttp().getRequest()` is the **actual
|
|
32
|
+
* Express request** (cookies/headers/`req.user`) - so cookie-session auth works
|
|
33
|
+
* with no separate auth config. A denying guard surfaces to the client as a
|
|
34
|
+
* `TRPCError` whose `data.httpStatus` is the guard's HTTP status (401/403).
|
|
35
|
+
*/
|
|
36
|
+
declare function trpc(options?: TrpcAdapterOptions): NestSilkweaveAdapter;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { TrpcAdapterOptions, trpc };
|
|
39
|
+
//# sourceMappingURL=trpc.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trpc.d.mts","names":[],"sources":["../src/adapter/trpc.ts"],"mappings":";;;;;UAQiB,kBAAA;;EAEf,QAAA;EAFiC;;;;;;EASjC,IAAA,GAAO,WAAA;EAOA;;;AAqBT;;;EArBE,IAAA,GAAO,UAAA;AAAA;;;;;;;;;;;;;iBAqBO,IAAA,CAAK,OAAA,GAAS,kBAAA,GAA0B,oBAAA"}
|
package/build/trpc.mjs
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { buildRouter, createActionLogger, resolveAuth } from "@silkweave/trpc";
|
|
2
|
+
import { createExpressMiddleware } from "@trpc/server/adapters/express";
|
|
3
|
+
import { TRPCError } from "@trpc/server";
|
|
4
|
+
import cors from "cors";
|
|
5
|
+
//#region src/adapter/trpc.ts
|
|
6
|
+
function resolveCors(config) {
|
|
7
|
+
if (config === false) return null;
|
|
8
|
+
return cors({
|
|
9
|
+
origin: "*",
|
|
10
|
+
...config === true || config === void 0 ? {} : config
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* tRPC adapter for `@silkweave/nestjs`. Mounts a single tRPC HTTP handler (httpBatch
|
|
15
|
+
* for queries/mutations, SSE for subscriptions) on Nest's HTTP adapter at the
|
|
16
|
+
* configured `basePath` (default `/trpc`), built from every `@Trpc`-decorated
|
|
17
|
+
* controller method.
|
|
18
|
+
*
|
|
19
|
+
* Each procedure runs the method's `@UseGuards()` first, with the guard receiving
|
|
20
|
+
* a real `ExecutionContext` whose `switchToHttp().getRequest()` is the **actual
|
|
21
|
+
* Express request** (cookies/headers/`req.user`) - so cookie-session auth works
|
|
22
|
+
* with no separate auth config. A denying guard surfaces to the client as a
|
|
23
|
+
* `TRPCError` whose `data.httpStatus` is the guard's HTTP status (401/403).
|
|
24
|
+
*/
|
|
25
|
+
function trpc(options = {}) {
|
|
26
|
+
return {
|
|
27
|
+
name: "trpc",
|
|
28
|
+
register({ httpAdapter, baseContext, actions }) {
|
|
29
|
+
const basePath = (options.basePath ?? "/trpc").replace(/\/$/, "");
|
|
30
|
+
if (!basePath) throw new Error("@silkweave/nestjs trpc(): basePath cannot be empty or \"/\" - pick a path like \"/trpc\".");
|
|
31
|
+
const router = buildRouter(actions);
|
|
32
|
+
const logger = createActionLogger();
|
|
33
|
+
const middleware = createExpressMiddleware({
|
|
34
|
+
router,
|
|
35
|
+
createContext: async ({ req, res }) => {
|
|
36
|
+
const resolved = await resolveAuth(options.auth, req.headers.authorization, baseContext.fork({ request: req }));
|
|
37
|
+
if (resolved.kind === "error") throw new TRPCError({
|
|
38
|
+
code: "UNAUTHORIZED",
|
|
39
|
+
message: resolved.error.body.error_description
|
|
40
|
+
});
|
|
41
|
+
return { silkweaveContext: baseContext.fork({
|
|
42
|
+
logger,
|
|
43
|
+
request: req,
|
|
44
|
+
response: res,
|
|
45
|
+
...resolved.authInfo ? { auth: resolved.authInfo } : {}
|
|
46
|
+
}) };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const adapter = httpAdapter;
|
|
50
|
+
const corsHandler = resolveCors(options.cors ?? true);
|
|
51
|
+
const handlers = corsHandler ? [corsHandler, middleware] : [middleware];
|
|
52
|
+
adapter.use(basePath, ...handlers);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { trpc };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=trpc.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trpc.mjs","names":[],"sources":["../src/adapter/trpc.ts"],"sourcesContent":["import { AuthConfig } from '@silkweave/auth'\nimport { buildRouter, createActionLogger, resolveAuth, type TrpcHandlerContext } from '@silkweave/trpc'\nimport { createExpressMiddleware } from '@trpc/server/adapters/express'\nimport { TRPCError } from '@trpc/server'\nimport cors, { type CorsOptions } from 'cors'\nimport type { Request, RequestHandler, Response } from 'express'\nimport type { NestAdapterRegisterContext, NestSilkweaveAdapter } from '../lib/types.js'\n\nexport interface TrpcAdapterOptions {\n /** URL prefix the tRPC handler mounts on. Default `'/trpc'`. */\n basePath?: string\n /**\n * CORS configuration. `false` to disable, `true`/omitted for permissive\n * defaults, or a `CorsOptions` object. For cookie-based auth set\n * `{ origin: '<spa-origin>', credentials: true }` so the browser sends the\n * session cookie (`credentials: 'include'` / `withCredentials`).\n */\n cors?: CorsOptions | boolean\n /**\n * Optional bearer-token / OAuth 2.1 config. Usually omitted - `@Trpc` routes\n * authenticate with their own `@UseGuards()` reading the real Express request\n * (cookies/headers), so no separate auth config is needed. Provide this only\n * to additionally validate an `Authorization` bearer at the transport edge.\n */\n auth?: AuthConfig\n}\n\nfunction resolveCors(config: CorsOptions | boolean | undefined): RequestHandler | null {\n if (config === false) { return null }\n const userConfig = config === true || config === undefined ? {} : config\n return cors({ origin: '*', ...userConfig }) as RequestHandler\n}\n\n/**\n * tRPC adapter for `@silkweave/nestjs`. Mounts a single tRPC HTTP handler (httpBatch\n * for queries/mutations, SSE for subscriptions) on Nest's HTTP adapter at the\n * configured `basePath` (default `/trpc`), built from every `@Trpc`-decorated\n * controller method.\n *\n * Each procedure runs the method's `@UseGuards()` first, with the guard receiving\n * a real `ExecutionContext` whose `switchToHttp().getRequest()` is the **actual\n * Express request** (cookies/headers/`req.user`) - so cookie-session auth works\n * with no separate auth config. A denying guard surfaces to the client as a\n * `TRPCError` whose `data.httpStatus` is the guard's HTTP status (401/403).\n */\nexport function trpc(options: TrpcAdapterOptions = {}): NestSilkweaveAdapter {\n return {\n name: 'trpc',\n register({ httpAdapter, baseContext, actions }: NestAdapterRegisterContext): void {\n const basePath = (options.basePath ?? '/trpc').replace(/\\/$/, '')\n if (!basePath) { throw new Error('@silkweave/nestjs trpc(): basePath cannot be empty or \"/\" - pick a path like \"/trpc\".') }\n\n const router = buildRouter(actions)\n const logger = createActionLogger()\n\n const middleware = createExpressMiddleware({\n router,\n createContext: async ({ req, res }: { req: Request; res: Response }): Promise<TrpcHandlerContext> => {\n const resolved = await resolveAuth(options.auth, req.headers.authorization, baseContext.fork({ request: req }))\n if (resolved.kind === 'error') {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: resolved.error.body.error_description })\n }\n return {\n silkweaveContext: baseContext.fork({\n logger,\n request: req,\n response: res,\n ...(resolved.authInfo ? { auth: resolved.authInfo } : {})\n })\n }\n }\n }) as unknown as RequestHandler\n\n const adapter = httpAdapter as unknown as { use: (path: string, ...handlers: RequestHandler[]) => unknown }\n const corsHandler = resolveCors(options.cors ?? true)\n const handlers = corsHandler ? [corsHandler, middleware] : [middleware]\n adapter.use(basePath, ...handlers)\n }\n }\n}\n"],"mappings":";;;;;AA2BA,SAAS,YAAY,QAAkE;AACrF,KAAI,WAAW,MAAS,QAAO;AAE/B,QAAO,KAAK;EAAE,QAAQ;EAAK,GADR,WAAW,QAAQ,WAAW,KAAA,IAAY,EAAE,GAAG;EACxB,CAAC;;;;;;;;;;;;;;AAe7C,SAAgB,KAAK,UAA8B,EAAE,EAAwB;AAC3E,QAAO;EACL,MAAM;EACN,SAAS,EAAE,aAAa,aAAa,WAA6C;GAChF,MAAM,YAAY,QAAQ,YAAY,SAAS,QAAQ,OAAO,GAAG;AACjE,OAAI,CAAC,SAAY,OAAM,IAAI,MAAM,4FAAwF;GAEzH,MAAM,SAAS,YAAY,QAAQ;GACnC,MAAM,SAAS,oBAAoB;GAEnC,MAAM,aAAa,wBAAwB;IACzC;IACA,eAAe,OAAO,EAAE,KAAK,UAAwE;KACnG,MAAM,WAAW,MAAM,YAAY,QAAQ,MAAM,IAAI,QAAQ,eAAe,YAAY,KAAK,EAAE,SAAS,KAAK,CAAC,CAAC;AAC/G,SAAI,SAAS,SAAS,QACpB,OAAM,IAAI,UAAU;MAAE,MAAM;MAAgB,SAAS,SAAS,MAAM,KAAK;MAAmB,CAAC;AAE/F,YAAO,EACL,kBAAkB,YAAY,KAAK;MACjC;MACA,SAAS;MACT,UAAU;MACV,GAAI,SAAS,WAAW,EAAE,MAAM,SAAS,UAAU,GAAG,EAAE;MACzD,CAAC,EACH;;IAEJ,CAAC;GAEF,MAAM,UAAU;GAChB,MAAM,cAAc,YAAY,QAAQ,QAAQ,KAAK;GACrD,MAAM,WAAW,cAAc,CAAC,aAAa,WAAW,GAAG,CAAC,WAAW;AACvE,WAAQ,IAAI,UAAU,GAAG,SAAS;;EAErC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { n as NestSilkweaveAdapter } from "./types-ByWkPWx2.mjs";
|
|
2
|
+
import { TypegenFormat } from "@silkweave/typegen";
|
|
3
|
+
|
|
4
|
+
//#region src/adapter/typegen.d.ts
|
|
5
|
+
interface TypegenAdapterOptions {
|
|
6
|
+
/** Output file path for the generated `.d.ts`/`.ts` file. Resolved against `process.cwd()`. Parent dirs are created. */
|
|
7
|
+
path: string;
|
|
8
|
+
/**
|
|
9
|
+
* What to emit. Defaults to `'trpc-router'` - an `AppRouter` type alias
|
|
10
|
+
* (`TRPCBuiltRouter`) for `createTRPCClient<AppRouter>()`, with one
|
|
11
|
+
* `TRPCQueryProcedure`/`TRPCMutationProcedure`/`TRPCSubscriptionProcedure` per
|
|
12
|
+
* `@Trpc` route keyed by camelCase name, carrying precise input/output types.
|
|
13
|
+
* Use `'interfaces'` for `{Name}Input`/`{Name}Output` interfaces, or `'all'` for both.
|
|
14
|
+
*/
|
|
15
|
+
format?: TypegenFormat;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Type-generation adapter for `@silkweave/nestjs`. On module bootstrap it writes
|
|
19
|
+
* a `.ts` file containing the tRPC `AppRouter` type covering every `@Trpc`
|
|
20
|
+
* procedure - the exact `TRPCBuiltRouter` contract `createTRPCClient<AppRouter>()`
|
|
21
|
+
* + `inferRouterInputs`/`inferRouterOutputs` consume. It only sees `@Trpc`
|
|
22
|
+
* actions (MCP tools are gated out), so the emitted router matches what the
|
|
23
|
+
* `trpc()` adapter serves at runtime.
|
|
24
|
+
*
|
|
25
|
+
* `@silkweave/typegen` (which pulls in the TypeScript compiler API) is imported
|
|
26
|
+
* lazily inside `register()`, so MCP-only apps that never use this adapter don't
|
|
27
|
+
* load it.
|
|
28
|
+
*/
|
|
29
|
+
declare function typegen(options: TypegenAdapterOptions): NestSilkweaveAdapter;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { TypegenAdapterOptions, typegen };
|
|
32
|
+
//# sourceMappingURL=typegen.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typegen.d.mts","names":[],"sources":["../src/adapter/typegen.ts"],"mappings":";;;;UAKiB,qBAAA;;EAEf,IAAA;EAFoC;;;;;;;EAUpC,MAAA,GAAS,aAAA;AAAA;;;;;;;;;;;;;iBAeK,OAAA,CAAQ,OAAA,EAAS,qBAAA,GAAwB,oBAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { dirname, resolve } from "node:path";
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
//#region src/adapter/typegen.ts
|
|
4
|
+
/**
|
|
5
|
+
* Type-generation adapter for `@silkweave/nestjs`. On module bootstrap it writes
|
|
6
|
+
* a `.ts` file containing the tRPC `AppRouter` type covering every `@Trpc`
|
|
7
|
+
* procedure - the exact `TRPCBuiltRouter` contract `createTRPCClient<AppRouter>()`
|
|
8
|
+
* + `inferRouterInputs`/`inferRouterOutputs` consume. It only sees `@Trpc`
|
|
9
|
+
* actions (MCP tools are gated out), so the emitted router matches what the
|
|
10
|
+
* `trpc()` adapter serves at runtime.
|
|
11
|
+
*
|
|
12
|
+
* `@silkweave/typegen` (which pulls in the TypeScript compiler API) is imported
|
|
13
|
+
* lazily inside `register()`, so MCP-only apps that never use this adapter don't
|
|
14
|
+
* load it.
|
|
15
|
+
*/
|
|
16
|
+
function typegen(options) {
|
|
17
|
+
return {
|
|
18
|
+
name: "typegen",
|
|
19
|
+
register({ actions }) {
|
|
20
|
+
const target = resolve(options.path);
|
|
21
|
+
(async () => {
|
|
22
|
+
const { renderTypegen } = await import("@silkweave/typegen");
|
|
23
|
+
const output = renderTypegen(actions, options.format ?? "trpc-router");
|
|
24
|
+
await mkdir(dirname(target), { recursive: true });
|
|
25
|
+
await writeFile(target, output, "utf-8");
|
|
26
|
+
console.info(`@silkweave/nestjs typegen: wrote ${actions.length} tRPC procedure types to ${target}`);
|
|
27
|
+
})().catch((error) => {
|
|
28
|
+
console.error(`@silkweave/nestjs typegen: failed to write ${target}:`, error);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { typegen };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=typegen.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typegen.mjs","names":[],"sources":["../src/adapter/typegen.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport type { TypegenFormat } from '@silkweave/typegen'\nimport type { NestAdapterRegisterContext, NestSilkweaveAdapter } from '../lib/types.js'\n\nexport interface TypegenAdapterOptions {\n /** Output file path for the generated `.d.ts`/`.ts` file. Resolved against `process.cwd()`. Parent dirs are created. */\n path: string\n /**\n * What to emit. Defaults to `'trpc-router'` - an `AppRouter` type alias\n * (`TRPCBuiltRouter`) for `createTRPCClient<AppRouter>()`, with one\n * `TRPCQueryProcedure`/`TRPCMutationProcedure`/`TRPCSubscriptionProcedure` per\n * `@Trpc` route keyed by camelCase name, carrying precise input/output types.\n * Use `'interfaces'` for `{Name}Input`/`{Name}Output` interfaces, or `'all'` for both.\n */\n format?: TypegenFormat\n}\n\n/**\n * Type-generation adapter for `@silkweave/nestjs`. On module bootstrap it writes\n * a `.ts` file containing the tRPC `AppRouter` type covering every `@Trpc`\n * procedure - the exact `TRPCBuiltRouter` contract `createTRPCClient<AppRouter>()`\n * + `inferRouterInputs`/`inferRouterOutputs` consume. It only sees `@Trpc`\n * actions (MCP tools are gated out), so the emitted router matches what the\n * `trpc()` adapter serves at runtime.\n *\n * `@silkweave/typegen` (which pulls in the TypeScript compiler API) is imported\n * lazily inside `register()`, so MCP-only apps that never use this adapter don't\n * load it.\n */\nexport function typegen(options: TypegenAdapterOptions): NestSilkweaveAdapter {\n return {\n name: 'typegen',\n register({ actions }: NestAdapterRegisterContext): void {\n const target = resolve(options.path)\n void (async () => {\n const { renderTypegen } = await import('@silkweave/typegen')\n const output = renderTypegen(actions, options.format ?? 'trpc-router')\n await mkdir(dirname(target), { recursive: true })\n await writeFile(target, output, 'utf-8')\n console.info(`@silkweave/nestjs typegen: wrote ${actions.length} tRPC procedure types to ${target}`)\n })().catch((error: unknown) => {\n console.error(`@silkweave/nestjs typegen: failed to write ${target}:`, error)\n })\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA8BA,SAAgB,QAAQ,SAAsD;AAC5E,QAAO;EACL,MAAM;EACN,SAAS,EAAE,WAA6C;GACtD,MAAM,SAAS,QAAQ,QAAQ,KAAK;AACpC,IAAM,YAAY;IAChB,MAAM,EAAE,kBAAkB,MAAM,OAAO;IACvC,MAAM,SAAS,cAAc,SAAS,QAAQ,UAAU,cAAc;AACtE,UAAM,MAAM,QAAQ,OAAO,EAAE,EAAE,WAAW,MAAM,CAAC;AACjD,UAAM,UAAU,QAAQ,QAAQ,QAAQ;AACxC,YAAQ,KAAK,oCAAoC,QAAQ,OAAO,2BAA2B,SAAS;OAClG,CAAC,OAAO,UAAmB;AAC7B,YAAQ,MAAM,8CAA8C,OAAO,IAAI,MAAM;KAC7E;;EAEL"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { CanActivate, Type } from "@nestjs/common";
|
|
2
|
+
import { HttpAdapterHost } from "@nestjs/core";
|
|
3
|
+
import { Action, SilkweaveContext, SilkweaveOptions } from "@silkweave/core";
|
|
4
|
+
import { z } from "zod/v4";
|
|
5
|
+
|
|
6
|
+
//#region src/lib/reflect/schema.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* A transport-neutral description of a single input field. Every metadata
|
|
9
|
+
* source (swagger decorators, class-validator, an OpenAPI document, TypeScript
|
|
10
|
+
* `design:type`) is mapped to this shape, the shapes are merged by precedence,
|
|
11
|
+
* and the result is converted to Zod once. Keeping a single intermediate keeps
|
|
12
|
+
* the per-source mappers small and the Zod construction in one place.
|
|
13
|
+
*/
|
|
14
|
+
interface FieldDesc {
|
|
15
|
+
type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'unknown';
|
|
16
|
+
required?: boolean;
|
|
17
|
+
description?: string;
|
|
18
|
+
enum?: (string | number)[];
|
|
19
|
+
items?: FieldDesc;
|
|
20
|
+
min?: number;
|
|
21
|
+
max?: number;
|
|
22
|
+
minLength?: number;
|
|
23
|
+
maxLength?: number;
|
|
24
|
+
format?: string;
|
|
25
|
+
default?: unknown;
|
|
26
|
+
}
|
|
27
|
+
/** Merge `over` onto `base` - defined keys of `over` win. */
|
|
28
|
+
declare function mergeField(base: FieldDesc, over: FieldDesc): FieldDesc;
|
|
29
|
+
/** Convert a merged {@link FieldDesc} to a Zod schema. */
|
|
30
|
+
declare function fieldToZod(d: FieldDesc): z.ZodType;
|
|
31
|
+
/** Normalise a TS-enum object or an array literal to a flat value list. */
|
|
32
|
+
declare function normalizeEnum(value: unknown): (string | number)[] | undefined;
|
|
33
|
+
/** Map a swagger/`design:type` type token (constructor, `[Type]`, or string) to a base type. */
|
|
34
|
+
declare function typeTokenToBase(type: unknown): FieldDesc['type'] | undefined;
|
|
35
|
+
/** From the constructor TypeScript emits via `emitDecoratorMetadata`. */
|
|
36
|
+
declare function designTypeToField(ctor: unknown): FieldDesc;
|
|
37
|
+
/** From an `@ApiParam`/`@ApiQuery` entry stored under `swagger/apiParameters`. */
|
|
38
|
+
declare function swaggerParamToField(p: Record<string, any>): FieldDesc;
|
|
39
|
+
/** From an `@ApiProperty` options object stored under `swagger/apiModelProperties`. */
|
|
40
|
+
declare function apiPropertyToField(o: Record<string, any>): FieldDesc;
|
|
41
|
+
/** From an array of `class-validator` validation-metadata entries for one property. */
|
|
42
|
+
declare function classValidatorToField(metas: Array<{
|
|
43
|
+
type?: string;
|
|
44
|
+
name?: string;
|
|
45
|
+
constraints?: unknown[];
|
|
46
|
+
}>): FieldDesc;
|
|
47
|
+
/** From an OpenAPI Schema Object (used by both the doc and `@ApiParam({ schema })`). */
|
|
48
|
+
declare function openapiSchemaToField(schema: Record<string, any>): FieldDesc;
|
|
49
|
+
/**
|
|
50
|
+
* Reflect a whole-DTO class (`@Body() dto: CreateDto`) into per-property
|
|
51
|
+
* {@link FieldDesc}s. Property names are the union of `@ApiProperty` and
|
|
52
|
+
* `class-validator` decorated fields; each field merges `design:type` (base),
|
|
53
|
+
* then `class-validator` constraints, then `@ApiProperty` (highest). Properties
|
|
54
|
+
* default to required unless a source marks them optional.
|
|
55
|
+
*/
|
|
56
|
+
declare function reflectDtoFields(dtoType: any): Record<string, FieldDesc>;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/lib/reflect/openapi.d.ts
|
|
59
|
+
/**
|
|
60
|
+
* A minimal view of an OpenAPI document - the subset we read. Matches the shape
|
|
61
|
+
* `SwaggerModule.createDocument()` returns, but typed loosely so callers can
|
|
62
|
+
* pass any compatible object without a hard `@nestjs/swagger` dependency.
|
|
63
|
+
*/
|
|
64
|
+
interface OpenApiDocument {
|
|
65
|
+
paths?: Record<string, Record<string, any>>;
|
|
66
|
+
components?: {
|
|
67
|
+
schemas?: Record<string, any>;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
interface OpenApiLookup {
|
|
71
|
+
doc: OpenApiDocument;
|
|
72
|
+
/** `${METHOD} ${path}` → operation object. */
|
|
73
|
+
operations: Map<string, any>;
|
|
74
|
+
}
|
|
75
|
+
/** Index a document's operations by `${METHOD} ${path}` for fast matching. */
|
|
76
|
+
declare function buildOpenApiLookup(doc: OpenApiDocument): OpenApiLookup;
|
|
77
|
+
/**
|
|
78
|
+
* Resolve the per-field descriptors for a route from an ingested OpenAPI
|
|
79
|
+
* document. Merges `parameters` (path/query/header) and the JSON request-body
|
|
80
|
+
* schema's properties into a single field map. Returns `{}` when the operation
|
|
81
|
+
* isn't found - callers fall back to decorator reflection.
|
|
82
|
+
*/
|
|
83
|
+
declare function openApiFields(lookup: OpenApiLookup, method: string, openapiPath: string): Record<string, FieldDesc>;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/lib/types.d.ts
|
|
86
|
+
/**
|
|
87
|
+
* Context passed to a Nest Silkweave adapter when `SilkweaveModule` wires it
|
|
88
|
+
* up. Adapters register their routes directly on `httpAdapter` (no
|
|
89
|
+
* placeholder middleware, no `silkweave()` builder), so they only fire
|
|
90
|
+
* `register()` once and own the rest of their lifecycle implicitly through
|
|
91
|
+
* Nest.
|
|
92
|
+
*/
|
|
93
|
+
interface NestAdapterRegisterContext {
|
|
94
|
+
/** Nest's underlying HTTP adapter (Express or Fastify). */
|
|
95
|
+
httpAdapter: NonNullable<HttpAdapterHost['httpAdapter']>;
|
|
96
|
+
/** Identity the adapter surfaces to clients (e.g. MCP server name). */
|
|
97
|
+
silkweaveOptions: SilkweaveOptions;
|
|
98
|
+
/** Per-adapter context - already forked with `{ adapter: adapter.name, ...userContext }`. */
|
|
99
|
+
baseContext: SilkweaveContext;
|
|
100
|
+
/** Actions filtered to those enabled on this adapter. */
|
|
101
|
+
actions: Action[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A Silkweave Nest adapter. Each transport (REST, tRPC, MCP) implements this
|
|
105
|
+
* shape. `register()` is called from `SilkweaveModule.configure()` - which
|
|
106
|
+
* runs *before* Nest's controller routes are mapped - so adapter routes
|
|
107
|
+
* always sit ahead of any catch-all controllers in the framework's request
|
|
108
|
+
* pipeline.
|
|
109
|
+
*/
|
|
110
|
+
interface NestSilkweaveAdapter {
|
|
111
|
+
/** Adapter discriminator - set on the silkweave context as `ctx.get('adapter')`. */
|
|
112
|
+
readonly name: 'mcp' | 'trpc' | 'typegen';
|
|
113
|
+
/** URL prefix the adapter mounts on (e.g. `'/mcp'`). Surfaced for introspection. */
|
|
114
|
+
readonly basePath?: string;
|
|
115
|
+
/**
|
|
116
|
+
* When `true`, the adapter receives every discovered action regardless of
|
|
117
|
+
* each action's `isEnabled` gate. Reserved for non-runtime adapters that need
|
|
118
|
+
* the entire action surface.
|
|
119
|
+
*/
|
|
120
|
+
readonly allActions?: boolean;
|
|
121
|
+
/** Register this adapter's routes on Nest's HTTP server. */
|
|
122
|
+
register(ctx: NestAdapterRegisterContext): void;
|
|
123
|
+
}
|
|
124
|
+
interface SilkweaveModuleOptions {
|
|
125
|
+
/** Identity for the silkweave instance - surfaced to MCP clients, OpenAPI, etc. */
|
|
126
|
+
silkweave: SilkweaveOptions;
|
|
127
|
+
/** Adapters to mount - any of `mcp()`, `trpc()`, `typegen()`. */
|
|
128
|
+
adapters: NestSilkweaveAdapter[];
|
|
129
|
+
/** Initial context keys merged into every adapter's `baseContext`. */
|
|
130
|
+
context?: Record<string, unknown>;
|
|
131
|
+
/**
|
|
132
|
+
* Optional OpenAPI document (e.g. from `SwaggerModule.createDocument(app, cfg)`)
|
|
133
|
+
* used as an authoritative source when reflecting `@Mcp` tool input schemas.
|
|
134
|
+
* Matched to each method by HTTP verb + path; falls back to decorator
|
|
135
|
+
* reflection when an operation or field isn't present.
|
|
136
|
+
*/
|
|
137
|
+
openapi?: OpenApiDocument;
|
|
138
|
+
/**
|
|
139
|
+
* Opt-in allow-list of app-global guard classes (registered via
|
|
140
|
+
* `app.useGlobalGuards()` or `{ provide: APP_GUARD, useClass }`) to run on
|
|
141
|
+
* every MCP tool call, before each method/class `@UseGuards`. Listed by
|
|
142
|
+
* class - a blanket "run all globals" is deliberately not offered, since
|
|
143
|
+
* unrelated globals (e.g. a `ThrottlerGuard` that needs a writable response)
|
|
144
|
+
* would misbehave over MCP. Empty/omitted ⇒ no global guards run.
|
|
145
|
+
*
|
|
146
|
+
* Note: over MCP the request stand-in is headers-only (`params`/`query` are
|
|
147
|
+
* empty), so per-session or IP-derived guard logic won't apply; header-based
|
|
148
|
+
* authentication still works.
|
|
149
|
+
*/
|
|
150
|
+
globalGuards?: Type<CanActivate>[];
|
|
151
|
+
/**
|
|
152
|
+
* Default MCP result format for every `@Mcp` tool - `'json'` (compact JSON,
|
|
153
|
+
* `jsonToolResult`) or `'smart'` (inline small / embedded-resource large,
|
|
154
|
+
* `smartToolResult`). Defaults to `'smart'`. A per-method `@Mcp({ result })`
|
|
155
|
+
* overrides this, and a client's per-call `_meta.disposition` overrides both.
|
|
156
|
+
*/
|
|
157
|
+
defaultResult?: 'json' | 'smart';
|
|
158
|
+
}
|
|
159
|
+
declare const SILKWEAVE_MODULE_OPTIONS = "__silkweave_module_options__";
|
|
160
|
+
//#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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silkweave/nestjs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Silkweave NestJS Adapter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.silkweave.dev",
|
|
@@ -23,18 +23,50 @@
|
|
|
23
23
|
"@silkweave/source": "./src/index.ts",
|
|
24
24
|
"types": "./build/index.d.mts",
|
|
25
25
|
"default": "./build/index.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./mcp": {
|
|
28
|
+
"@silkweave/source": "./src/mcp.ts",
|
|
29
|
+
"types": "./build/mcp.d.mts",
|
|
30
|
+
"default": "./build/mcp.mjs"
|
|
31
|
+
},
|
|
32
|
+
"./trpc": {
|
|
33
|
+
"@silkweave/source": "./src/trpc.ts",
|
|
34
|
+
"types": "./build/trpc.d.mts",
|
|
35
|
+
"default": "./build/trpc.mjs"
|
|
36
|
+
},
|
|
37
|
+
"./typegen": {
|
|
38
|
+
"@silkweave/source": "./src/typegen.ts",
|
|
39
|
+
"types": "./build/typegen.d.mts",
|
|
40
|
+
"default": "./build/typegen.mjs"
|
|
26
41
|
}
|
|
27
42
|
},
|
|
28
43
|
"peerDependencies": {
|
|
29
44
|
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
30
45
|
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
31
46
|
"@nestjs/swagger": "^7.0.0 || ^8.0.0 || ^11.0.0",
|
|
32
|
-
"
|
|
47
|
+
"rxjs": "^7.0.0",
|
|
48
|
+
"@trpc/server": "^11.7.1",
|
|
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"
|
|
33
53
|
},
|
|
34
54
|
"peerDependenciesMeta": {
|
|
35
55
|
"@nestjs/swagger": {
|
|
36
56
|
"optional": true
|
|
37
57
|
},
|
|
58
|
+
"@silkweave/mcp": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"@silkweave/trpc": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"@silkweave/typegen": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"@trpc/server": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
38
70
|
"class-validator": {
|
|
39
71
|
"optional": true
|
|
40
72
|
}
|
|
@@ -43,9 +75,7 @@
|
|
|
43
75
|
"cors": "^2.8.6",
|
|
44
76
|
"express": "^5.2.1",
|
|
45
77
|
"zod": "^3.25.0",
|
|
46
|
-
"@silkweave/
|
|
47
|
-
"@silkweave/core": "2.4.0",
|
|
48
|
-
"@silkweave/mcp": "2.4.0"
|
|
78
|
+
"@silkweave/core": "2.5.0"
|
|
49
79
|
},
|
|
50
80
|
"devDependencies": {
|
|
51
81
|
"@eslint/js": "^10.0.1",
|
|
@@ -53,6 +83,7 @@
|
|
|
53
83
|
"@nestjs/core": "^11.0.0",
|
|
54
84
|
"@nestjs/swagger": "^11.0.0",
|
|
55
85
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
86
|
+
"@trpc/server": "^11.7.1",
|
|
56
87
|
"@types/cors": "^2.8.19",
|
|
57
88
|
"@types/express": "^5.0.6",
|
|
58
89
|
"@types/node": "^22.0.0",
|
|
@@ -63,7 +94,11 @@
|
|
|
63
94
|
"tsdown": "^0.21.8",
|
|
64
95
|
"tsx": "^4.21.0",
|
|
65
96
|
"typescript": "^5.9.3",
|
|
66
|
-
"typescript-eslint": "^8.56.1"
|
|
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"
|
|
67
102
|
},
|
|
68
103
|
"scripts": {
|
|
69
104
|
"clean": "rimraf build",
|