14
14
15
15
import { z , ZodRawShape , ZodTypeAny , ZodObject } from 'zod' ;
16
16
17
- // Define All Interfaces
18
-
19
- interface BaseParameter {
20
- name : string ;
21
- description : string ;
22
- authSources ?: string [ ] ;
23
- required ?: boolean ;
24
- }
25
-
26
- interface StringParameter extends BaseParameter {
17
+ // Type Definitions
18
+ interface StringType {
27
19
type : 'string' ;
28
20
}
29
-
30
- interface IntegerParameter extends BaseParameter {
21
+ interface IntegerType {
31
22
type : 'integer' ;
32
23
}
33
-
34
- interface FloatParameter extends BaseParameter {
24
+ interface FloatType {
35
25
type : 'float' ;
36
26
}
37
-
38
- interface BooleanParameter extends BaseParameter {
27
+ interface BooleanType {
39
28
type : 'boolean' ;
40
29
}
41
-
42
- interface ArrayParameter extends BaseParameter {
30
+ interface ArrayType {
43
31
type : 'array' ;
44
- items : ParameterSchema ; // Recursive reference to the ParameterSchema type
32
+ items : TypeSchema ; // Recursive
33
+ }
34
+ interface ObjectType {
35
+ type : 'object' ;
36
+ additionalProperties ?: boolean | TypeSchema ; // Recursive
45
37
}
46
38
47
- export type ParameterSchema =
48
- | StringParameter
49
- | IntegerParameter
50
- | FloatParameter
51
- | BooleanParameter
52
- | ArrayParameter ;
39
+ // Union of all pure type definitions.
40
+ export type TypeSchema =
41
+ | StringType
42
+ | IntegerType
43
+ | FloatType
44
+ | BooleanType
45
+ | ArrayType
46
+ | ObjectType ;
53
47
54
- // Get all Zod schema types
48
+ // The base properties of a named parameter.
49
+ interface BaseParameter {
50
+ name : string ;
51
+ description : string ;
52
+ authSources ?: string [ ] ;
53
+ required ?: boolean ;
54
+ }
55
+
56
+ export type ParameterSchema = BaseParameter & TypeSchema ;
55
57
58
+ // Zod schema for the pure type definitions. This must be lazy for recursion.
59
+ const ZodTypeSchema : z . ZodType < TypeSchema > = z . lazy ( ( ) =>
60
+ z . discriminatedUnion ( 'type' , [
61
+ z . object ( { type : z . literal ( 'string' ) } ) ,
62
+ z . object ( { type : z . literal ( 'integer' ) } ) ,
63
+ z . object ( { type : z . literal ( 'float' ) } ) ,
64
+ z . object ( { type : z . literal ( 'boolean' ) } ) ,
65
+ z . object ( { type : z . literal ( 'array' ) , items : ZodTypeSchema } ) ,
66
+ z . object ( {
67
+ type : z . literal ( 'object' ) ,
68
+ additionalProperties : z . union ( [ z . boolean ( ) , ZodTypeSchema ] ) . optional ( ) ,
69
+ } ) ,
70
+ ] ) ,
71
+ ) ;
72
+
73
+ // Zod schema for the base properties.
56
74
const ZodBaseParameter = z . object ( {
57
75
name : z . string ( ) . min ( 1 , 'Parameter name cannot be empty' ) ,
58
76
description : z . string ( ) ,
59
77
authSources : z . array ( z . string ( ) ) . optional ( ) ,
60
78
required : z . boolean ( ) . optional ( ) ,
61
79
} ) ;
62
80
63
- export const ZodParameterSchema = z . lazy ( ( ) =>
64
- z . discriminatedUnion ( 'type' , [
65
- ZodBaseParameter . extend ( {
66
- type : z . literal ( 'string' ) ,
67
- } ) ,
68
- ZodBaseParameter . extend ( {
69
- type : z . literal ( 'integer' ) ,
70
- } ) ,
71
- ZodBaseParameter . extend ( {
72
- type : z . literal ( 'float' ) ,
73
- } ) ,
74
- ZodBaseParameter . extend ( {
75
- type : z . literal ( 'boolean' ) ,
76
- } ) ,
77
- ZodBaseParameter . extend ( {
78
- type : z . literal ( 'array' ) ,
79
- items : ZodParameterSchema , // Recursive reference for the item's definition
80
- } ) ,
81
- ] ) ,
82
- ) as z . ZodType < ParameterSchema > ;
81
+ export const ZodParameterSchema : z . ZodType < ParameterSchema > =
82
+ ZodBaseParameter . and ( ZodTypeSchema ) ;
83
83
84
84
export const ZodToolSchema = z . object ( {
85
85
description : z . string ( ) . min ( 1 , 'Tool description cannot be empty' ) ,
@@ -97,52 +97,44 @@ export const ZodManifestSchema = z.object({
97
97
98
98
export type ZodManifest = z . infer < typeof ZodManifestSchema > ;
99
99
100
- /**
101
- * Recursively builds a Zod schema for a single parameter based on its TypeScript definition.
102
- * @param param The ParameterSchema (TypeScript type) to convert.
103
- * @returns A ZodTypeAny representing the schema for this parameter.
104
- */
105
- function buildZodShapeFromParam ( param : ParameterSchema ) : ZodTypeAny {
106
- let schema : ZodTypeAny ;
107
- switch ( param . type ) {
100
+ function buildZodShapeFromTypeSchema ( typeSchema : TypeSchema ) : ZodTypeAny {
101
+ switch ( typeSchema . type ) {
108
102
case 'string' :
109
- schema = z . string ( ) ;
110
- break ;
103
+ return z . string ( ) ;
111
104
case 'integer' :
112
- schema = z . number ( ) . int ( ) ;
113
- break ;
105
+ return z . number ( ) . int ( ) ;
114
106
case 'float' :
115
- schema = z . number ( ) ;
116
- break ;
107
+ return z . number ( ) ;
117
108
case 'boolean' :
118
- schema = z . boolean ( ) ;
119
- break ;
109
+ return z . boolean ( ) ;
120
110
case 'array' :
121
- // Recursively build the schema for array items
122
- // Array items inherit the 'required' status of the parent array.
123
- param . items . required = param . required ;
124
- schema = z . array ( buildZodShapeFromParam ( param . items ) ) ;
125
- break ;
111
+ return z . array ( buildZodShapeFromTypeSchema ( typeSchema . items ) ) ;
112
+ case 'object' :
113
+ if ( typeof typeSchema . additionalProperties === 'object' ) {
114
+ return z . record (
115
+ z . string ( ) ,
116
+ buildZodShapeFromTypeSchema ( typeSchema . additionalProperties ) ,
117
+ ) ;
118
+ } else if ( typeSchema . additionalProperties === false ) {
119
+ return z . object ( { } ) ;
120
+ } else {
121
+ return z . record ( z . string ( ) , z . any ( ) ) ;
122
+ }
126
123
default : {
127
- // This ensures exhaustiveness at compile time if ParameterSchema is a discriminated union
128
- const _exhaustiveCheck : never = param ;
124
+ const _exhaustiveCheck : never = typeSchema ;
129
125
throw new Error ( `Unknown parameter type: ${ _exhaustiveCheck [ 'type' ] } ` ) ;
130
126
}
131
127
}
128
+ }
132
129
130
+ function buildZodShapeFromParam ( param : ParameterSchema ) : ZodTypeAny {
131
+ const schema = buildZodShapeFromTypeSchema ( param ) ;
133
132
if ( param . required === false ) {
134
133
return schema . nullish ( ) ;
135
134
}
136
-
137
135
return schema ;
138
136
}
139
137
140
- /**
141
- * Creates a ZodObject schema from an array of ParameterSchema (TypeScript types).
142
- * This combined schema is used by ToolboxTool to validate its call arguments.
143
- * @param params Array of ParameterSchema objects.
144
- * @returns A ZodObject schema.
145
- */
146
138
export function createZodSchemaFromParams (
147
139
params : ParameterSchema [ ] ,
148
140
) : ZodObject < ZodRawShape > {
0 commit comments