@silkweave/nestjs 1.9.1 → 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.
- package/.turbo/turbo-build.log +17 -17
- package/.turbo/turbo-prepack.log +6 -6
- package/README.md +19 -0
- package/build/index.d.mts +9 -2
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +26 -5
- package/build/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/decorator/action.ts +2 -2
- package/src/lib/discovery.ts +33 -6
- package/src/lib/metadata.ts +8 -1
- 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.10.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/
|
|
24
|
-
"@silkweave/trpc": "1.
|
|
25
|
-
"@silkweave/
|
|
26
|
-
"@silkweave/
|
|
27
|
-
"@silkweave/
|
|
22
|
+
"@silkweave/auth": "1.10.0",
|
|
23
|
+
"@silkweave/core": "1.10.0",
|
|
24
|
+
"@silkweave/trpc": "1.10.0",
|
|
25
|
+
"@silkweave/mcp": "1.10.0",
|
|
26
|
+
"@silkweave/logger": "1.10.0",
|
|
27
|
+
"@silkweave/typegen": "1.10.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@eslint/js": "^10.0.1",
|
package/src/decorator/action.ts
CHANGED
|
@@ -31,8 +31,8 @@ import { ACTION_METADATA, type ActionMetadata } from '../lib/metadata.js'
|
|
|
31
31
|
* }
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
|
-
export function Action<I extends object = object, O extends object = object>(
|
|
35
|
-
options: ActionMetadata<I, O>
|
|
34
|
+
export function Action<I extends object = object, O extends object = object, C = unknown>(
|
|
35
|
+
options: ActionMetadata<I, O, C>
|
|
36
36
|
): MethodDecorator {
|
|
37
37
|
return SetMetadata(ACTION_METADATA, options)
|
|
38
38
|
}
|
package/src/lib/discovery.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
import { Injectable, type Type } from '@nestjs/common'
|
|
3
3
|
import { DiscoveryService, MetadataScanner, ModuleRef, Reflector } from '@nestjs/core'
|
|
4
|
-
import { createAction, type Action, type SilkweaveContext } from '@silkweave/core'
|
|
4
|
+
import { createAction, type Action, type ActionKind, type SilkweaveContext, type StreamingActionInput } from '@silkweave/core'
|
|
5
5
|
import { kebabCase } from 'change-case'
|
|
6
6
|
import { buildIsEnabled } from './filter.js'
|
|
7
7
|
import { collectGuards, runGuards } from './guards.js'
|
|
@@ -64,9 +64,40 @@ export class ActionDiscovery {
|
|
|
64
64
|
const moduleRef = this.moduleRef
|
|
65
65
|
const reflector = this.reflector
|
|
66
66
|
|
|
67
|
+
const applyGuards = async (context: SilkweaveContext): Promise<void> => {
|
|
68
|
+
if (guards.length === 0) { return }
|
|
69
|
+
const request = context.getOptional<unknown>('request')
|
|
70
|
+
const response = context.getOptional<unknown>('response')
|
|
71
|
+
await runGuards(guards, moduleRef, reflector, d.classRef, d.method, request, response)
|
|
72
|
+
}
|
|
73
|
+
|
|
67
74
|
// Cast at the createAction boundary to bridge dual-zod-version installs
|
|
68
75
|
// (zod@3.25 + zod@4.x can both be present transitively). Runtime is fine -
|
|
69
76
|
// they share the same /v4 surface - but the structural types are distinct.
|
|
77
|
+
const streaming = d.method.constructor?.name === 'AsyncGeneratorFunction'
|
|
78
|
+
|
|
79
|
+
if (streaming) {
|
|
80
|
+
if (!d.meta.chunk) {
|
|
81
|
+
throw new Error(`@Action "${name}" is an async generator but has no \`chunk\` schema`)
|
|
82
|
+
}
|
|
83
|
+
const method = d.method
|
|
84
|
+
const instance = d.instance
|
|
85
|
+
return createAction({
|
|
86
|
+
name,
|
|
87
|
+
description: d.meta.description,
|
|
88
|
+
input: d.meta.input,
|
|
89
|
+
chunk: d.meta.chunk,
|
|
90
|
+
kind: d.meta.kind ?? 'mutation',
|
|
91
|
+
args: d.meta.args,
|
|
92
|
+
isEnabled,
|
|
93
|
+
toolResult: d.meta.toolResult,
|
|
94
|
+
run: async function* (input: object, context: SilkweaveContext) {
|
|
95
|
+
await applyGuards(context)
|
|
96
|
+
yield* (method.call(instance, input, context) as AsyncGenerator<object, void, void>)
|
|
97
|
+
}
|
|
98
|
+
} as StreamingActionInput<object, unknown, string, ActionKind>) as Action
|
|
99
|
+
}
|
|
100
|
+
|
|
70
101
|
return createAction({
|
|
71
102
|
name,
|
|
72
103
|
description: d.meta.description,
|
|
@@ -77,11 +108,7 @@ export class ActionDiscovery {
|
|
|
77
108
|
isEnabled,
|
|
78
109
|
toolResult: d.meta.toolResult,
|
|
79
110
|
run: async (input: object, context: SilkweaveContext): Promise<object> => {
|
|
80
|
-
|
|
81
|
-
const request = context.getOptional<unknown>('request')
|
|
82
|
-
const response = context.getOptional<unknown>('response')
|
|
83
|
-
await runGuards(guards, moduleRef, reflector, d.classRef, d.method, request, response)
|
|
84
|
-
}
|
|
111
|
+
await applyGuards(context)
|
|
85
112
|
const result = await (d.method.call(d.instance, input, context) as Promise<object>)
|
|
86
113
|
return result
|
|
87
114
|
}
|
package/src/lib/metadata.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const ACTIONS_METADATA = '__silkweave_actions__'
|
|
|
6
6
|
|
|
7
7
|
export type Transport = 'rest' | 'trpc' | 'mcp'
|
|
8
8
|
|
|
9
|
-
export interface ActionMetadata<I extends object = object, O extends object = object> {
|
|
9
|
+
export interface ActionMetadata<I extends object = object, O extends object = object, C = unknown> {
|
|
10
10
|
/** Action name. Defaults to the kebab-cased method name. */
|
|
11
11
|
name?: string
|
|
12
12
|
/** Human-readable description. Becomes the MCP tool description and REST OpenAPI summary. */
|
|
@@ -15,6 +15,13 @@ export interface ActionMetadata<I extends object = object, O extends object = ob
|
|
|
15
15
|
input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }
|
|
16
16
|
/** Optional Zod object schema for the action's output (used by tRPC type inference). */
|
|
17
17
|
output?: z.ZodType<O> & { shape: Record<string, z.ZodTypeAny> }
|
|
18
|
+
/**
|
|
19
|
+
* Zod schema for individual chunks yielded by a streaming (async-generator)
|
|
20
|
+
* action method. Required when the decorated method is an `async function*`.
|
|
21
|
+
* Mirrors `Action.chunk` in @silkweave/core; typegen/trpc use it to expose
|
|
22
|
+
* the action as a tRPC subscription.
|
|
23
|
+
*/
|
|
24
|
+
chunk?: z.ZodType<C>
|
|
18
25
|
/** `'query'` (GET in REST, `.query()` in tRPC) or `'mutation'` (POST in REST, `.mutation()` in tRPC). Default: `'mutation'`. */
|
|
19
26
|
kind?: ActionKind
|
|
20
27
|
/** Allowlist of transports that should expose this action. Default: all registered transports. */
|