22/* eslint-disable no-constant-binary-expression */
33/* eslint-disable @typescript-eslint/no-unused-expressions */
44import { Client , getSupportedElicitationModes } from './index.js' ;
5- import * as z from 'zod/v4' ;
65import {
76 RequestSchema ,
87 NotificationSchema ,
@@ -21,6 +20,165 @@ import {
2120import { Transport } from '../shared/transport.js' ;
2221import { Server } from '../server/index.js' ;
2322import { InMemoryTransport } from '../inMemory.js' ;
23+ import * as z3 from 'zod/v3' ;
24+ import * as z4 from 'zod/v4' ;
25+
26+ describe ( 'Zod v4' , ( ) => {
27+ /***
28+ * Test: Type Checking
29+ * Test that custom request/notification/result schemas can be used with the Client class.
30+ */
31+ test ( 'should typecheck' , ( ) => {
32+ const GetWeatherRequestSchema = RequestSchema . extend ( {
33+ method : z4 . literal ( 'weather/get' ) ,
34+ params : z4 . object ( {
35+ city : z4 . string ( )
36+ } )
37+ } ) ;
38+
39+ const GetForecastRequestSchema = RequestSchema . extend ( {
40+ method : z4 . literal ( 'weather/forecast' ) ,
41+ params : z4 . object ( {
42+ city : z4 . string ( ) ,
43+ days : z4 . number ( )
44+ } )
45+ } ) ;
46+
47+ const WeatherForecastNotificationSchema = NotificationSchema . extend ( {
48+ method : z4 . literal ( 'weather/alert' ) ,
49+ params : z4 . object ( {
50+ severity : z4 . enum ( [ 'warning' , 'watch' ] ) ,
51+ message : z4 . string ( )
52+ } )
53+ } ) ;
54+
55+ const WeatherRequestSchema = GetWeatherRequestSchema . or ( GetForecastRequestSchema ) ;
56+ const WeatherNotificationSchema = WeatherForecastNotificationSchema ;
57+ const WeatherResultSchema = ResultSchema . extend ( {
58+ temperature : z4 . number ( ) ,
59+ conditions : z4 . string ( )
60+ } ) ;
61+
62+ type WeatherRequest = z4 . infer < typeof WeatherRequestSchema > ;
63+ type WeatherNotification = z4 . infer < typeof WeatherNotificationSchema > ;
64+ type WeatherResult = z4 . infer < typeof WeatherResultSchema > ;
65+
66+ // Create a typed Client for weather data
67+ const weatherClient = new Client < WeatherRequest , WeatherNotification , WeatherResult > (
68+ {
69+ name : 'WeatherClient' ,
70+ version : '1.0.0'
71+ } ,
72+ {
73+ capabilities : {
74+ sampling : { }
75+ }
76+ }
77+ ) ;
78+
79+ // Typecheck that only valid weather requests/notifications/results are allowed
80+ false &&
81+ weatherClient . request (
82+ {
83+ method : 'weather/get' ,
84+ params : {
85+ city : 'Seattle'
86+ }
87+ } ,
88+ WeatherResultSchema
89+ ) ;
90+
91+ false &&
92+ weatherClient . notification ( {
93+ method : 'weather/alert' ,
94+ params : {
95+ severity : 'warning' ,
96+ message : 'Storm approaching'
97+ }
98+ } ) ;
99+ } ) ;
100+ } ) ;
101+
102+ describe ( 'Zod v3' , ( ) => {
103+ /***
104+ * Test: Type Checking
105+ * Test that custom request/notification/result schemas can be used with the Client class.
106+ */
107+ test ( 'should typecheck' , ( ) => {
108+ const GetWeatherRequestSchema = z3 . object ( {
109+ ...RequestSchema . shape ,
110+ method : z3 . literal ( 'weather/get' ) ,
111+ params : z3 . object ( {
112+ city : z3 . string ( )
113+ } )
114+ } ) ;
115+
116+ const GetForecastRequestSchema = z3 . object ( {
117+ ...RequestSchema . shape ,
118+ method : z3 . literal ( 'weather/forecast' ) ,
119+ params : z3 . object ( {
120+ city : z3 . string ( ) ,
121+ days : z3 . number ( )
122+ } )
123+ } ) ;
124+
125+ const WeatherForecastNotificationSchema = z3 . object ( {
126+ ...NotificationSchema . shape ,
127+ method : z3 . literal ( 'weather/alert' ) ,
128+ params : z3 . object ( {
129+ severity : z3 . enum ( [ 'warning' , 'watch' ] ) ,
130+ message : z3 . string ( )
131+ } )
132+ } ) ;
133+
134+ const WeatherRequestSchema = GetWeatherRequestSchema . or ( GetForecastRequestSchema ) ;
135+ const WeatherNotificationSchema = WeatherForecastNotificationSchema ;
136+ const WeatherResultSchema = z3 . object ( {
137+ ...ResultSchema . shape ,
138+ _meta : z3 . record ( z3 . string ( ) , z3 . unknown ( ) ) . optional ( ) ,
139+ temperature : z3 . number ( ) ,
140+ conditions : z3 . string ( )
141+ } ) ;
142+
143+ type WeatherRequest = z3 . infer < typeof WeatherRequestSchema > ;
144+ type WeatherNotification = z3 . infer < typeof WeatherNotificationSchema > ;
145+ type WeatherResult = z3 . infer < typeof WeatherResultSchema > ;
146+
147+ // Create a typed Client for weather data
148+ const weatherClient = new Client < WeatherRequest , WeatherNotification , WeatherResult > (
149+ {
150+ name : 'WeatherClient' ,
151+ version : '1.0.0'
152+ } ,
153+ {
154+ capabilities : {
155+ sampling : { }
156+ }
157+ }
158+ ) ;
159+
160+ // Typecheck that only valid weather requests/notifications/results are allowed
161+ false &&
162+ weatherClient . request (
163+ {
164+ method : 'weather/get' ,
165+ params : {
166+ city : 'Seattle'
167+ }
168+ } ,
169+ WeatherResultSchema
170+ ) ;
171+
172+ false &&
173+ weatherClient . notification ( {
174+ method : 'weather/alert' ,
175+ params : {
176+ severity : 'warning' ,
177+ message : 'Storm approaching'
178+ }
179+ } ) ;
180+ } ) ;
181+ } ) ;
24182
25183/***
26184 * Test: Initialize with Matching Protocol Version
@@ -906,80 +1064,6 @@ test('should apply defaults for form-mode elicitation when applyDefaults is enab
9061064 await client . close ( ) ;
9071065} ) ;
9081066
909- /***
910- * Test: Type Checking
911- * Test that custom request/notification/result schemas can be used with the Client class.
912- */
913- test ( 'should typecheck' , ( ) => {
914- const GetWeatherRequestSchema = RequestSchema . extend ( {
915- method : z . literal ( 'weather/get' ) ,
916- params : z . object ( {
917- city : z . string ( )
918- } )
919- } ) ;
920-
921- const GetForecastRequestSchema = RequestSchema . extend ( {
922- method : z . literal ( 'weather/forecast' ) ,
923- params : z . object ( {
924- city : z . string ( ) ,
925- days : z . number ( )
926- } )
927- } ) ;
928-
929- const WeatherForecastNotificationSchema = NotificationSchema . extend ( {
930- method : z . literal ( 'weather/alert' ) ,
931- params : z . object ( {
932- severity : z . enum ( [ 'warning' , 'watch' ] ) ,
933- message : z . string ( )
934- } )
935- } ) ;
936-
937- const WeatherRequestSchema = GetWeatherRequestSchema . or ( GetForecastRequestSchema ) ;
938- const WeatherNotificationSchema = WeatherForecastNotificationSchema ;
939- const WeatherResultSchema = ResultSchema . extend ( {
940- temperature : z . number ( ) ,
941- conditions : z . string ( )
942- } ) ;
943-
944- type WeatherRequest = z . infer < typeof WeatherRequestSchema > ;
945- type WeatherNotification = z . infer < typeof WeatherNotificationSchema > ;
946- type WeatherResult = z . infer < typeof WeatherResultSchema > ;
947-
948- // Create a typed Client for weather data
949- const weatherClient = new Client < WeatherRequest , WeatherNotification , WeatherResult > (
950- {
951- name : 'WeatherClient' ,
952- version : '1.0.0'
953- } ,
954- {
955- capabilities : {
956- sampling : { }
957- }
958- }
959- ) ;
960-
961- // Typecheck that only valid weather requests/notifications/results are allowed
962- false &&
963- weatherClient . request (
964- {
965- method : 'weather/get' ,
966- params : {
967- city : 'Seattle'
968- }
969- } ,
970- WeatherResultSchema
971- ) ;
972-
973- false &&
974- weatherClient . notification ( {
975- method : 'weather/alert' ,
976- params : {
977- severity : 'warning' ,
978- message : 'Storm approaching'
979- }
980- } ) ;
981- } ) ;
982-
9831067/***
9841068 * Test: Handle Client Cancelling a Request
9851069 */
0 commit comments