@silkweave/nestjs 1.10.0 → 1.11.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/.turbo/turbo-build.log +6 -6
- package/README.md +10 -5
- package/build/index.d.mts +11 -5
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +20 -8
- package/build/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/lib/discovery.ts +13 -5
- package/src/lib/guards.ts +9 -3
- package/tsconfig.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silkweave/nestjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Silkweave NestJS Adapter",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"cors": "^2.8.6",
|
|
20
20
|
"express": "^5.2.1",
|
|
21
21
|
"zod": "^3.25.0",
|
|
22
|
-
"@silkweave/auth": "1.
|
|
23
|
-
"@silkweave/core": "1.
|
|
24
|
-
"@silkweave/
|
|
25
|
-
"@silkweave/
|
|
26
|
-
"@silkweave/
|
|
27
|
-
"@silkweave/
|
|
22
|
+
"@silkweave/auth": "1.11.0",
|
|
23
|
+
"@silkweave/core": "1.11.0",
|
|
24
|
+
"@silkweave/mcp": "1.11.0",
|
|
25
|
+
"@silkweave/logger": "1.11.0",
|
|
26
|
+
"@silkweave/typegen": "1.11.0",
|
|
27
|
+
"@silkweave/trpc": "1.11.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@eslint/js": "^10.0.1",
|
package/src/lib/discovery.ts
CHANGED
|
@@ -30,9 +30,10 @@ export class ActionDiscovery {
|
|
|
30
30
|
* a list of core `Action` objects ready to feed into `silkweave().actions()`.
|
|
31
31
|
*
|
|
32
32
|
* Action invocation is wrapped to (a) run `@UseGuards` guards declared on the
|
|
33
|
-
* method or its class against the incoming
|
|
34
|
-
* `ctx.get('request')
|
|
35
|
-
*
|
|
33
|
+
* method or its class against the incoming request (read from
|
|
34
|
+
* `ctx.get('request')`, populated by REST/tRPC and by MCP-over-HTTP from the
|
|
35
|
+
* SDK's `extra.requestInfo`) and (b) bind `this` to the resolved Nest provider
|
|
36
|
+
* so DI-injected dependencies remain available.
|
|
36
37
|
*/
|
|
37
38
|
discover(): Action[] {
|
|
38
39
|
const discovered: DiscoveredAction[] = []
|
|
@@ -66,9 +67,16 @@ export class ActionDiscovery {
|
|
|
66
67
|
|
|
67
68
|
const applyGuards = async (context: SilkweaveContext): Promise<void> => {
|
|
68
69
|
if (guards.length === 0) { return }
|
|
70
|
+
// REST and tRPC populate `request`/`response`; MCP-over-HTTP populates
|
|
71
|
+
// `request` (a `{ headers, url, params, query }` stand-in built from the
|
|
72
|
+
// SDK's `extra.requestInfo`). Transports with no HTTP request at all (e.g.
|
|
73
|
+
// MCP stdio) get a header-less stand-in so guards reading `req.headers`
|
|
74
|
+
// degrade gracefully (deny) instead of dereferencing `undefined`.
|
|
69
75
|
const request = context.getOptional<unknown>('request')
|
|
70
|
-
const response = context.getOptional<unknown>('response')
|
|
71
|
-
|
|
76
|
+
const response = context.getOptional<unknown>('response') ?? null
|
|
77
|
+
const hasRequest = request != null
|
|
78
|
+
const guardRequest = hasRequest ? request : { headers: {}, params: {}, query: {} }
|
|
79
|
+
await runGuards(guards, moduleRef, reflector, d.classRef, d.method, guardRequest, response, hasRequest ? 'http' : 'rpc')
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
// Cast at the createAction boundary to bridge dual-zod-version installs
|
package/src/lib/guards.ts
CHANGED
|
@@ -33,12 +33,17 @@ async function resolveGuard(ref: GuardRef, moduleRef: ModuleRef): Promise<CanAct
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* Run the configured guards against
|
|
36
|
+
* Run the configured guards against a request. Throws `ForbiddenException`
|
|
37
37
|
* if any guard rejects, mirroring Nest's HTTP request-pipeline behavior.
|
|
38
38
|
*
|
|
39
39
|
* Pass `null` for `response` when running on top of a tRPC or MCP request that
|
|
40
40
|
* doesn't surface a raw response object; guards that introspect the response
|
|
41
41
|
* will receive `null`.
|
|
42
|
+
*
|
|
43
|
+
* `contextType` is reflected through `ExecutionContext.getType()` so guards can
|
|
44
|
+
* branch on the transport. It is `'http'` for REST/tRPC and for MCP-over-HTTP
|
|
45
|
+
* (where a header-bearing request stand-in is available); transports without any
|
|
46
|
+
* HTTP request (e.g. MCP stdio) pass `'rpc'`.
|
|
42
47
|
*/
|
|
43
48
|
export async function runGuards(
|
|
44
49
|
guards: GuardRef[],
|
|
@@ -47,10 +52,11 @@ export async function runGuards(
|
|
|
47
52
|
classRef: Type<unknown>,
|
|
48
53
|
handler: (...args: unknown[]) => unknown,
|
|
49
54
|
request: unknown,
|
|
50
|
-
response: unknown
|
|
55
|
+
response: unknown,
|
|
56
|
+
contextType: 'http' | 'rpc' = 'http'
|
|
51
57
|
): Promise<void> {
|
|
52
58
|
if (guards.length === 0) { return }
|
|
53
|
-
const context = new SilkweaveExecutionContext([request, response], classRef, handler,
|
|
59
|
+
const context = new SilkweaveExecutionContext([request, response], classRef, handler, contextType)
|
|
54
60
|
for (const ref of guards) {
|
|
55
61
|
const guard = await resolveGuard(ref, moduleRef)
|
|
56
62
|
const result = guard.canActivate(context)
|