diff --git a/src/spec.types.test.ts b/src/spec.types.test.ts index 5aa497f4a..816dba4cd 100644 --- a/src/spec.types.test.ts +++ b/src/spec.types.test.ts @@ -17,9 +17,11 @@ type RemovePassthrough = T extends object ? T extends Array ? Array> : T extends Function - ? T - : {[K in keyof T as string extends K ? never : K]: RemovePassthrough} - : T; + ? T + : { + [K in keyof T as string extends K ? never : K]: RemovePassthrough; + } + : T; // Adds the `jsonrpc` property to a type, to match the on-wire format of notifications. type WithJSONRPC = T & { jsonrpc: "2.0" }; @@ -27,694 +29,696 @@ type WithJSONRPC = T & { jsonrpc: "2.0" }; // Adds the `jsonrpc` and `id` properties to a type, to match the on-wire format of requests. type WithJSONRPCRequest = T & { jsonrpc: "2.0"; id: SDKTypes.RequestId }; -type IsUnknown = [unknown] extends [T] ? [T] extends [unknown] ? true : false : false; +type IsUnknown = [unknown] extends [T] + ? [T] extends [unknown] + ? true + : false + : false; // Turns {x?: unknown} into {x: unknown} but keeps {_meta?: unknown} unchanged (and leaves other optional properties unchanged, e.g. {x?: string}). // This works around an apparent quirk of ZodObject.unknown() (makes fields optional) -type MakeUnknownsNotOptional = - IsUnknown extends true - ? unknown - : (T extends object - ? (T extends Array - ? Array> - : (T extends Function - ? T - : Pick & { - // Start with empty object to avoid duplicates - // Make unknown properties required (except _meta) - [K in keyof T as '_meta' extends K ? never : IsUnknown extends true ? K : never]-?: unknown; - } & - Pick = IsUnknown extends true + ? unknown + : T extends object + ? T extends Array + ? Array> + : T extends Function + ? T + : Pick & { + // Start with empty object to avoid duplicates + // Make unknown properties required (except _meta) + [K in keyof T as "_meta" extends K + ? never + : IsUnknown extends true + ? K + : never]-?: unknown; + } & Pick< + T, + { // Pick all _meta and non-unknown properties with original modifiers - [K in keyof T]: '_meta' extends K ? K : IsUnknown extends true ? never : K - }[keyof T]> & { - // Recurse on the picked properties - [K in keyof Pick extends true ? never : K}[keyof T]>]: MakeUnknownsNotOptional - })) - : T); + [K in keyof T]: "_meta" extends K + ? K + : IsUnknown extends true + ? never + : K; + }[keyof T] + > & { + // Recurse on the picked properties + [K in keyof Pick< + T, + { + [K in keyof T]: "_meta" extends K + ? K + : IsUnknown extends true + ? never + : K; + }[keyof T] + >]: MakeUnknownsNotOptional; + } + : T; -function checkCancelledNotification( - sdk: WithJSONRPC, - spec: SpecTypes.CancelledNotification -) { - sdk = spec; - spec = sdk; -} -function checkBaseMetadata( - sdk: RemovePassthrough, - spec: SpecTypes.BaseMetadata -) { - sdk = spec; - spec = sdk; -} -function checkImplementation( - sdk: RemovePassthrough, - spec: SpecTypes.Implementation -) { - sdk = spec; - spec = sdk; -} -function checkProgressNotification( - sdk: WithJSONRPC, - spec: SpecTypes.ProgressNotification -) { - sdk = spec; - spec = sdk; -} - -function checkSubscribeRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.SubscribeRequest -) { - sdk = spec; - spec = sdk; -} -function checkUnsubscribeRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.UnsubscribeRequest -) { - sdk = spec; - spec = sdk; -} -function checkPaginatedRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.PaginatedRequest -) { - sdk = spec; - spec = sdk; -} -function checkPaginatedResult( - sdk: SDKTypes.PaginatedResult, - spec: SpecTypes.PaginatedResult -) { - sdk = spec; - spec = sdk; -} -function checkListRootsRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ListRootsRequest -) { - sdk = spec; - spec = sdk; -} -function checkListRootsResult( - sdk: RemovePassthrough, - spec: SpecTypes.ListRootsResult -) { - sdk = spec; - spec = sdk; -} -function checkRoot( - sdk: RemovePassthrough, - spec: SpecTypes.Root -) { - sdk = spec; - spec = sdk; -} -function checkElicitRequest( - sdk: WithJSONRPCRequest>, - spec: SpecTypes.ElicitRequest -) { - sdk = spec; - spec = sdk; -} -function checkElicitResult( - sdk: RemovePassthrough, - spec: SpecTypes.ElicitResult -) { - sdk = spec; - spec = sdk; -} -function checkCompleteRequest( - sdk: WithJSONRPCRequest>, - spec: SpecTypes.CompleteRequest -) { - sdk = spec; - spec = sdk; -} -function checkCompleteResult( - sdk: SDKTypes.CompleteResult, - spec: SpecTypes.CompleteResult -) { - sdk = spec; - spec = sdk; -} -function checkProgressToken( - sdk: SDKTypes.ProgressToken, - spec: SpecTypes.ProgressToken -) { - sdk = spec; - spec = sdk; -} -function checkCursor( - sdk: SDKTypes.Cursor, - spec: SpecTypes.Cursor -) { - sdk = spec; - spec = sdk; -} -function checkRequest( - sdk: SDKTypes.Request, - spec: SpecTypes.Request -) { - sdk = spec; - spec = sdk; -} -function checkResult( - sdk: SDKTypes.Result, - spec: SpecTypes.Result -) { - sdk = spec; - spec = sdk; -} -function checkRequestId( - sdk: SDKTypes.RequestId, - spec: SpecTypes.RequestId -) { - sdk = spec; - spec = sdk; -} -function checkJSONRPCRequest( - sdk: SDKTypes.JSONRPCRequest, - spec: SpecTypes.JSONRPCRequest -) { - sdk = spec; - spec = sdk; -} -function checkJSONRPCNotification( - sdk: SDKTypes.JSONRPCNotification, - spec: SpecTypes.JSONRPCNotification -) { - sdk = spec; - spec = sdk; -} -function checkJSONRPCResponse( - sdk: SDKTypes.JSONRPCResponse, - spec: SpecTypes.JSONRPCResponse -) { - sdk = spec; - spec = sdk; -} -function checkEmptyResult( - sdk: SDKTypes.EmptyResult, - spec: SpecTypes.EmptyResult -) { - sdk = spec; - spec = sdk; -} -function checkNotification( - sdk: SDKTypes.Notification, - spec: SpecTypes.Notification -) { - sdk = spec; - spec = sdk; -} -function checkClientResult( - sdk: SDKTypes.ClientResult, - spec: SpecTypes.ClientResult -) { - sdk = spec; - spec = sdk; -} -function checkClientNotification( - sdk: WithJSONRPC, - spec: SpecTypes.ClientNotification -) { - sdk = spec; - spec = sdk; -} -function checkServerResult( - sdk: SDKTypes.ServerResult, - spec: SpecTypes.ServerResult -) { - sdk = spec; - spec = sdk; -} -function checkResourceTemplateReference( - sdk: RemovePassthrough, - spec: SpecTypes.ResourceTemplateReference -) { - sdk = spec; - spec = sdk; -} -function checkPromptReference( - sdk: RemovePassthrough, - spec: SpecTypes.PromptReference -) { - sdk = spec; - spec = sdk; -} -function checkToolAnnotations( - sdk: RemovePassthrough, - spec: SpecTypes.ToolAnnotations -) { - sdk = spec; - spec = sdk; -} -function checkTool( - sdk: RemovePassthrough, - spec: SpecTypes.Tool -) { - sdk = spec; - spec = sdk; -} -function checkListToolsRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ListToolsRequest -) { - sdk = spec; - spec = sdk; -} -function checkListToolsResult( - sdk: RemovePassthrough, - spec: SpecTypes.ListToolsResult -) { - sdk = spec; - spec = sdk; -} -function checkCallToolResult( - sdk: RemovePassthrough, - spec: SpecTypes.CallToolResult -) { - sdk = spec; - spec = sdk; -} -function checkCallToolRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.CallToolRequest -) { - sdk = spec; - spec = sdk; -} -function checkToolListChangedNotification( - sdk: WithJSONRPC, - spec: SpecTypes.ToolListChangedNotification -) { - sdk = spec; - spec = sdk; -} -function checkResourceListChangedNotification( - sdk: WithJSONRPC, - spec: SpecTypes.ResourceListChangedNotification -) { - sdk = spec; - spec = sdk; -} -function checkPromptListChangedNotification( - sdk: WithJSONRPC, - spec: SpecTypes.PromptListChangedNotification -) { - sdk = spec; - spec = sdk; -} -function checkRootsListChangedNotification( - sdk: WithJSONRPC, - spec: SpecTypes.RootsListChangedNotification -) { - sdk = spec; - spec = sdk; -} -function checkResourceUpdatedNotification( - sdk: WithJSONRPC, - spec: SpecTypes.ResourceUpdatedNotification -) { - sdk = spec; - spec = sdk; -} -function checkSamplingMessage( - sdk: RemovePassthrough, - spec: SpecTypes.SamplingMessage -) { - sdk = spec; - spec = sdk; -} -function checkCreateMessageResult( - sdk: RemovePassthrough, - spec: SpecTypes.CreateMessageResult -) { - sdk = spec; - spec = sdk; -} -function checkSetLevelRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.SetLevelRequest -) { - sdk = spec; - spec = sdk; -} -function checkPingRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.PingRequest -) { - sdk = spec; - spec = sdk; -} -function checkInitializedNotification( - sdk: WithJSONRPC, - spec: SpecTypes.InitializedNotification -) { - sdk = spec; - spec = sdk; -} -function checkListResourcesRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ListResourcesRequest -) { - sdk = spec; - spec = sdk; -} -function checkListResourcesResult( - sdk: RemovePassthrough, - spec: SpecTypes.ListResourcesResult -) { - sdk = spec; - spec = sdk; -} -function checkListResourceTemplatesRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ListResourceTemplatesRequest -) { - sdk = spec; - spec = sdk; -} -function checkListResourceTemplatesResult( - sdk: RemovePassthrough, - spec: SpecTypes.ListResourceTemplatesResult -) { - sdk = spec; - spec = sdk; -} -function checkReadResourceRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ReadResourceRequest -) { - sdk = spec; - spec = sdk; -} -function checkReadResourceResult( - sdk: RemovePassthrough, - spec: SpecTypes.ReadResourceResult -) { - sdk = spec; - spec = sdk; -} -function checkResourceContents( - sdk: RemovePassthrough, - spec: SpecTypes.ResourceContents -) { - sdk = spec; - spec = sdk; -} -function checkTextResourceContents( - sdk: RemovePassthrough, - spec: SpecTypes.TextResourceContents -) { - sdk = spec; - spec = sdk; -} -function checkBlobResourceContents( - sdk: RemovePassthrough, - spec: SpecTypes.BlobResourceContents -) { - sdk = spec; - spec = sdk; -} -function checkResource( - sdk: RemovePassthrough, - spec: SpecTypes.Resource -) { - sdk = spec; - spec = sdk; -} -function checkResourceTemplate( - sdk: RemovePassthrough, - spec: SpecTypes.ResourceTemplate -) { - sdk = spec; - spec = sdk; -} -function checkPromptArgument( - sdk: RemovePassthrough, - spec: SpecTypes.PromptArgument -) { - sdk = spec; - spec = sdk; -} -function checkPrompt( - sdk: RemovePassthrough, - spec: SpecTypes.Prompt -) { - sdk = spec; - spec = sdk; -} -function checkListPromptsRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ListPromptsRequest -) { - sdk = spec; - spec = sdk; -} -function checkListPromptsResult( - sdk: RemovePassthrough, - spec: SpecTypes.ListPromptsResult -) { - sdk = spec; - spec = sdk; -} -function checkGetPromptRequest( - sdk: WithJSONRPCRequest, - spec: SpecTypes.GetPromptRequest -) { - sdk = spec; - spec = sdk; -} -function checkTextContent( - sdk: RemovePassthrough, - spec: SpecTypes.TextContent -) { - sdk = spec; - spec = sdk; -} -function checkImageContent( - sdk: RemovePassthrough, - spec: SpecTypes.ImageContent -) { - sdk = spec; - spec = sdk; -} -function checkAudioContent( - sdk: RemovePassthrough, - spec: SpecTypes.AudioContent -) { - sdk = spec; - spec = sdk; -} -function checkEmbeddedResource( - sdk: RemovePassthrough, - spec: SpecTypes.EmbeddedResource -) { - sdk = spec; - spec = sdk; -} -function checkResourceLink( - sdk: RemovePassthrough, - spec: SpecTypes.ResourceLink -) { - sdk = spec; - spec = sdk; -} -function checkContentBlock( - sdk: RemovePassthrough, - spec: SpecTypes.ContentBlock -) { - sdk = spec; - spec = sdk; -} -function checkPromptMessage( - sdk: RemovePassthrough, - spec: SpecTypes.PromptMessage -) { - sdk = spec; - spec = sdk; -} -function checkGetPromptResult( - sdk: RemovePassthrough, - spec: SpecTypes.GetPromptResult -) { - sdk = spec; - spec = sdk; -} -function checkBooleanSchema( - sdk: RemovePassthrough, - spec: SpecTypes.BooleanSchema -) { - sdk = spec; - spec = sdk; -} -function checkStringSchema( - sdk: RemovePassthrough, - spec: SpecTypes.StringSchema -) { - sdk = spec; - spec = sdk; -} -function checkNumberSchema( - sdk: RemovePassthrough, - spec: SpecTypes.NumberSchema -) { - sdk = spec; - spec = sdk; -} -function checkEnumSchema( - sdk: RemovePassthrough, - spec: SpecTypes.EnumSchema -) { - sdk = spec; - spec = sdk; -} -function checkPrimitiveSchemaDefinition( - sdk: RemovePassthrough, - spec: SpecTypes.PrimitiveSchemaDefinition -) { - sdk = spec; - spec = sdk; -} -function checkJSONRPCError( - sdk: SDKTypes.JSONRPCError, - spec: SpecTypes.JSONRPCError -) { - sdk = spec; - spec = sdk; -} -function checkJSONRPCMessage( - sdk: SDKTypes.JSONRPCMessage, - spec: SpecTypes.JSONRPCMessage -) { - sdk = spec; - spec = sdk; -} -function checkCreateMessageRequest( - sdk: WithJSONRPCRequest>, - spec: SpecTypes.CreateMessageRequest -) { - sdk = spec; - spec = sdk; -} -function checkInitializeRequest( - sdk: WithJSONRPCRequest>, - spec: SpecTypes.InitializeRequest -) { - sdk = spec; - spec = sdk; -} -function checkInitializeResult( - sdk: RemovePassthrough, - spec: SpecTypes.InitializeResult -) { - sdk = spec; - spec = sdk; -} -function checkClientCapabilities( - sdk: RemovePassthrough, - spec: SpecTypes.ClientCapabilities -) { - sdk = spec; - spec = sdk; -} -function checkServerCapabilities( - sdk: RemovePassthrough, - spec: SpecTypes.ServerCapabilities -) { - sdk = spec; - spec = sdk; -} -function checkClientRequest( - sdk: WithJSONRPCRequest>, - spec: SpecTypes.ClientRequest -) { - sdk = spec; - spec = sdk; -} -function checkServerRequest( - sdk: WithJSONRPCRequest>, - spec: SpecTypes.ServerRequest -) { - sdk = spec; - spec = sdk; -} -function checkLoggingMessageNotification( - sdk: MakeUnknownsNotOptional>, - spec: SpecTypes.LoggingMessageNotification -) { - sdk = spec; - spec = sdk; -} -function checkServerNotification( - sdk: MakeUnknownsNotOptional>, - spec: SpecTypes.ServerNotification -) { - sdk = spec; - spec = sdk; -} -function checkLoggingLevel( - sdk: SDKTypes.LoggingLevel, - spec: SpecTypes.LoggingLevel -) { - sdk = spec; - spec = sdk; -} -function checkIcon( - sdk: RemovePassthrough, - spec: SpecTypes.Icon -) { - sdk = spec; - spec = sdk; -} +const sdkTypeChecks = { + CancelledNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.CancelledNotification + ) => { + sdk = spec; + spec = sdk; + }, + BaseMetadata: ( + sdk: RemovePassthrough, + spec: SpecTypes.BaseMetadata + ) => { + sdk = spec; + spec = sdk; + }, + Implementation: ( + sdk: RemovePassthrough, + spec: SpecTypes.Implementation + ) => { + sdk = spec; + spec = sdk; + }, + ProgressNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.ProgressNotification + ) => { + sdk = spec; + spec = sdk; + }, + SubscribeRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.SubscribeRequest + ) => { + sdk = spec; + spec = sdk; + }, + UnsubscribeRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.UnsubscribeRequest + ) => { + sdk = spec; + spec = sdk; + }, + PaginatedRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.PaginatedRequest + ) => { + sdk = spec; + spec = sdk; + }, + PaginatedResult: ( + sdk: SDKTypes.PaginatedResult, + spec: SpecTypes.PaginatedResult + ) => { + sdk = spec; + spec = sdk; + }, + ListRootsRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.ListRootsRequest + ) => { + sdk = spec; + spec = sdk; + }, + ListRootsResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ListRootsResult + ) => { + sdk = spec; + spec = sdk; + }, + Root: (sdk: RemovePassthrough, spec: SpecTypes.Root) => { + sdk = spec; + spec = sdk; + }, + ElicitRequest: ( + sdk: WithJSONRPCRequest>, + spec: SpecTypes.ElicitRequest + ) => { + sdk = spec; + spec = sdk; + }, + ElicitResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ElicitResult + ) => { + sdk = spec; + spec = sdk; + }, + CompleteRequest: ( + sdk: WithJSONRPCRequest>, + spec: SpecTypes.CompleteRequest + ) => { + sdk = spec; + spec = sdk; + }, + CompleteResult: ( + sdk: SDKTypes.CompleteResult, + spec: SpecTypes.CompleteResult + ) => { + sdk = spec; + spec = sdk; + }, + ProgressToken: ( + sdk: SDKTypes.ProgressToken, + spec: SpecTypes.ProgressToken + ) => { + sdk = spec; + spec = sdk; + }, + Cursor: (sdk: SDKTypes.Cursor, spec: SpecTypes.Cursor) => { + sdk = spec; + spec = sdk; + }, + Request: (sdk: SDKTypes.Request, spec: SpecTypes.Request) => { + sdk = spec; + spec = sdk; + }, + Result: (sdk: SDKTypes.Result, spec: SpecTypes.Result) => { + sdk = spec; + spec = sdk; + }, + RequestId: (sdk: SDKTypes.RequestId, spec: SpecTypes.RequestId) => { + sdk = spec; + spec = sdk; + }, + JSONRPCRequest: ( + sdk: SDKTypes.JSONRPCRequest, + spec: SpecTypes.JSONRPCRequest + ) => { + sdk = spec; + spec = sdk; + }, + JSONRPCNotification: ( + sdk: SDKTypes.JSONRPCNotification, + spec: SpecTypes.JSONRPCNotification + ) => { + sdk = spec; + spec = sdk; + }, + JSONRPCResponse: ( + sdk: SDKTypes.JSONRPCResponse, + spec: SpecTypes.JSONRPCResponse + ) => { + sdk = spec; + spec = sdk; + }, + EmptyResult: (sdk: SDKTypes.EmptyResult, spec: SpecTypes.EmptyResult) => { + sdk = spec; + spec = sdk; + }, + Notification: (sdk: SDKTypes.Notification, spec: SpecTypes.Notification) => { + sdk = spec; + spec = sdk; + }, + ClientResult: (sdk: SDKTypes.ClientResult, spec: SpecTypes.ClientResult) => { + sdk = spec; + spec = sdk; + }, + ClientNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.ClientNotification + ) => { + sdk = spec; + spec = sdk; + }, + ServerResult: (sdk: SDKTypes.ServerResult, spec: SpecTypes.ServerResult) => { + sdk = spec; + spec = sdk; + }, + ResourceTemplateReference: ( + sdk: RemovePassthrough, + spec: SpecTypes.ResourceTemplateReference + ) => { + sdk = spec; + spec = sdk; + }, + PromptReference: ( + sdk: RemovePassthrough, + spec: SpecTypes.PromptReference + ) => { + sdk = spec; + spec = sdk; + }, + ToolAnnotations: ( + sdk: RemovePassthrough, + spec: SpecTypes.ToolAnnotations + ) => { + sdk = spec; + spec = sdk; + }, + Tool: (sdk: RemovePassthrough, spec: SpecTypes.Tool) => { + sdk = spec; + spec = sdk; + }, + ListToolsRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.ListToolsRequest + ) => { + sdk = spec; + spec = sdk; + }, + ListToolsResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ListToolsResult + ) => { + sdk = spec; + spec = sdk; + }, + CallToolResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.CallToolResult + ) => { + sdk = spec; + spec = sdk; + }, + CallToolRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.CallToolRequest + ) => { + sdk = spec; + spec = sdk; + }, + ToolListChangedNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.ToolListChangedNotification + ) => { + sdk = spec; + spec = sdk; + }, + ResourceListChangedNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.ResourceListChangedNotification + ) => { + sdk = spec; + spec = sdk; + }, + PromptListChangedNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.PromptListChangedNotification + ) => { + sdk = spec; + spec = sdk; + }, + RootsListChangedNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.RootsListChangedNotification + ) => { + sdk = spec; + spec = sdk; + }, + ResourceUpdatedNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.ResourceUpdatedNotification + ) => { + sdk = spec; + spec = sdk; + }, + SamplingMessage: ( + sdk: RemovePassthrough, + spec: SpecTypes.SamplingMessage + ) => { + sdk = spec; + spec = sdk; + }, + CreateMessageResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.CreateMessageResult + ) => { + sdk = spec; + spec = sdk; + }, + SetLevelRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.SetLevelRequest + ) => { + sdk = spec; + spec = sdk; + }, + PingRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.PingRequest + ) => { + sdk = spec; + spec = sdk; + }, + InitializedNotification: ( + sdk: WithJSONRPC, + spec: SpecTypes.InitializedNotification + ) => { + sdk = spec; + spec = sdk; + }, + ListResourcesRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.ListResourcesRequest + ) => { + sdk = spec; + spec = sdk; + }, + ListResourcesResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ListResourcesResult + ) => { + sdk = spec; + spec = sdk; + }, + ListResourceTemplatesRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.ListResourceTemplatesRequest + ) => { + sdk = spec; + spec = sdk; + }, + ListResourceTemplatesResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ListResourceTemplatesResult + ) => { + sdk = spec; + spec = sdk; + }, + ReadResourceRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.ReadResourceRequest + ) => { + sdk = spec; + spec = sdk; + }, + ReadResourceResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ReadResourceResult + ) => { + sdk = spec; + spec = sdk; + }, + ResourceContents: ( + sdk: RemovePassthrough, + spec: SpecTypes.ResourceContents + ) => { + sdk = spec; + spec = sdk; + }, + TextResourceContents: ( + sdk: RemovePassthrough, + spec: SpecTypes.TextResourceContents + ) => { + sdk = spec; + spec = sdk; + }, + BlobResourceContents: ( + sdk: RemovePassthrough, + spec: SpecTypes.BlobResourceContents + ) => { + sdk = spec; + spec = sdk; + }, + Resource: ( + sdk: RemovePassthrough, + spec: SpecTypes.Resource + ) => { + sdk = spec; + spec = sdk; + }, + ResourceTemplate: ( + sdk: RemovePassthrough, + spec: SpecTypes.ResourceTemplate + ) => { + sdk = spec; + spec = sdk; + }, + PromptArgument: ( + sdk: RemovePassthrough, + spec: SpecTypes.PromptArgument + ) => { + sdk = spec; + spec = sdk; + }, + Prompt: (sdk: RemovePassthrough, spec: SpecTypes.Prompt) => { + sdk = spec; + spec = sdk; + }, + ListPromptsRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.ListPromptsRequest + ) => { + sdk = spec; + spec = sdk; + }, + ListPromptsResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.ListPromptsResult + ) => { + sdk = spec; + spec = sdk; + }, + GetPromptRequest: ( + sdk: WithJSONRPCRequest, + spec: SpecTypes.GetPromptRequest + ) => { + sdk = spec; + spec = sdk; + }, + TextContent: ( + sdk: RemovePassthrough, + spec: SpecTypes.TextContent + ) => { + sdk = spec; + spec = sdk; + }, + ImageContent: ( + sdk: RemovePassthrough, + spec: SpecTypes.ImageContent + ) => { + sdk = spec; + spec = sdk; + }, + AudioContent: ( + sdk: RemovePassthrough, + spec: SpecTypes.AudioContent + ) => { + sdk = spec; + spec = sdk; + }, + EmbeddedResource: ( + sdk: RemovePassthrough, + spec: SpecTypes.EmbeddedResource + ) => { + sdk = spec; + spec = sdk; + }, + ResourceLink: ( + sdk: RemovePassthrough, + spec: SpecTypes.ResourceLink + ) => { + sdk = spec; + spec = sdk; + }, + ContentBlock: ( + sdk: RemovePassthrough, + spec: SpecTypes.ContentBlock + ) => { + sdk = spec; + spec = sdk; + }, + PromptMessage: ( + sdk: RemovePassthrough, + spec: SpecTypes.PromptMessage + ) => { + sdk = spec; + spec = sdk; + }, + GetPromptResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.GetPromptResult + ) => { + sdk = spec; + spec = sdk; + }, + BooleanSchema: ( + sdk: RemovePassthrough, + spec: SpecTypes.BooleanSchema + ) => { + sdk = spec; + spec = sdk; + }, + StringSchema: ( + sdk: RemovePassthrough, + spec: SpecTypes.StringSchema + ) => { + sdk = spec; + spec = sdk; + }, + NumberSchema: ( + sdk: RemovePassthrough, + spec: SpecTypes.NumberSchema + ) => { + sdk = spec; + spec = sdk; + }, + EnumSchema: ( + sdk: RemovePassthrough, + spec: SpecTypes.EnumSchema + ) => { + sdk = spec; + spec = sdk; + }, + PrimitiveSchemaDefinition: ( + sdk: RemovePassthrough, + spec: SpecTypes.PrimitiveSchemaDefinition + ) => { + sdk = spec; + spec = sdk; + }, + JSONRPCError: (sdk: SDKTypes.JSONRPCError, spec: SpecTypes.JSONRPCError) => { + sdk = spec; + spec = sdk; + }, + JSONRPCMessage: ( + sdk: SDKTypes.JSONRPCMessage, + spec: SpecTypes.JSONRPCMessage + ) => { + sdk = spec; + spec = sdk; + }, + CreateMessageRequest: ( + sdk: WithJSONRPCRequest>, + spec: SpecTypes.CreateMessageRequest + ) => { + sdk = spec; + spec = sdk; + }, + InitializeRequest: ( + sdk: WithJSONRPCRequest>, + spec: SpecTypes.InitializeRequest + ) => { + sdk = spec; + spec = sdk; + }, + InitializeResult: ( + sdk: RemovePassthrough, + spec: SpecTypes.InitializeResult + ) => { + sdk = spec; + spec = sdk; + }, + ClientCapabilities: ( + sdk: RemovePassthrough, + spec: SpecTypes.ClientCapabilities + ) => { + sdk = spec; + spec = sdk; + }, + ServerCapabilities: ( + sdk: RemovePassthrough, + spec: SpecTypes.ServerCapabilities + ) => { + sdk = spec; + spec = sdk; + }, + ClientRequest: ( + sdk: WithJSONRPCRequest>, + spec: SpecTypes.ClientRequest + ) => { + sdk = spec; + spec = sdk; + }, + ServerRequest: ( + sdk: WithJSONRPCRequest>, + spec: SpecTypes.ServerRequest + ) => { + sdk = spec; + spec = sdk; + }, + LoggingMessageNotification: ( + sdk: MakeUnknownsNotOptional< + WithJSONRPC + >, + spec: SpecTypes.LoggingMessageNotification + ) => { + sdk = spec; + spec = sdk; + }, + ServerNotification: ( + sdk: MakeUnknownsNotOptional>, + spec: SpecTypes.ServerNotification + ) => { + sdk = spec; + spec = sdk; + }, + LoggingLevel: (sdk: SDKTypes.LoggingLevel, spec: SpecTypes.LoggingLevel) => { + sdk = spec; + spec = sdk; + }, + Icon: (sdk: RemovePassthrough, spec: SpecTypes.Icon) => { + sdk = spec; + spec = sdk; + }, + Icons: (sdk: RemovePassthrough, spec: SpecTypes.Icons) => { + sdk = spec; + spec = sdk; + }, +}; // This file is .gitignore'd, and fetched by `npm run fetch:spec-types` (called by `npm run test`) -const SPEC_TYPES_FILE = 'spec.types.ts'; -const SDK_TYPES_FILE = 'src/types.ts'; +const SPEC_TYPES_FILE = "spec.types.ts"; +const SDK_TYPES_FILE = "src/types.ts"; const MISSING_SDK_TYPES = [ // These are inlined in the SDK: - 'Role', - 'Error', // The inner error object of a JSONRPCError + "Role", + "Error", // The inner error object of a JSONRPCError // These aren't supported by the SDK yet: // TODO: Add definitions to the SDK - 'Annotations', - 'ModelHint', - 'ModelPreferences', - 'Icons', -] + "Annotations", + "ModelHint", + "ModelPreferences", +]; function extractExportedTypes(source: string): string[] { - return [...source.matchAll(/export\s+(?:interface|class|type)\s+(\w+)\b/g)].map(m => m[1]); + return [ + ...source.matchAll(/export\s+(?:interface|class|type)\s+(\w+)\b/g), + ].map((m) => m[1]); } -describe('Spec Types', () => { - const specTypes = extractExportedTypes(fs.readFileSync(SPEC_TYPES_FILE, 'utf-8')); - const sdkTypes = extractExportedTypes(fs.readFileSync(SDK_TYPES_FILE, 'utf-8')); - const testSource = fs.readFileSync(__filename, 'utf-8'); +describe("Spec Types", () => { + const specTypes = extractExportedTypes( + fs.readFileSync(SPEC_TYPES_FILE, "utf-8") + ); + const sdkTypes = extractExportedTypes( + fs.readFileSync(SDK_TYPES_FILE, "utf-8") + ); + const typesToCheck = specTypes.filter( + (type) => !MISSING_SDK_TYPES.includes(type) + ); - it('should define some expected types', () => { - expect(specTypes).toContain('JSONRPCNotification'); - expect(specTypes).toContain('ElicitResult'); + it("should define some expected types", () => { + expect(specTypes).toContain("JSONRPCNotification"); + expect(specTypes).toContain("ElicitResult"); expect(specTypes).toHaveLength(94); }); - it('should have up to date list of missing sdk types', () => { + it("should have up to date list of missing sdk types", () => { for (const typeName of MISSING_SDK_TYPES) { expect(sdkTypes).not.toContain(typeName); } }); - for (const type of specTypes) { - if (MISSING_SDK_TYPES.includes(type)) { - continue; // Skip missing SDK types - } - it(`${type} should have a compatibility test`, () => { - expect(testSource).toContain(`function check${type}(`); + describe("Compatibility tests", () => { + it.each(typesToCheck)("%s should have a compatibility test", (type) => { + expect(sdkTypeChecks[type as keyof typeof sdkTypeChecks]).toBeDefined(); }); - } + }); + + describe("Missing SDK Types", () => { + it.each(MISSING_SDK_TYPES)( + "%s should not be present in MISSING_SDK_TYPES if it has a compatibility test", + (type) => { + expect( + sdkTypeChecks[type as keyof typeof sdkTypeChecks] + ).toBeUndefined(); + } + ); + }); }); diff --git a/src/types.ts b/src/types.ts index 9ca4e4d8a..ee2ceb5ed 100644 --- a/src/types.ts +++ b/src/types.ts @@ -215,13 +215,33 @@ export const IconSchema = z mimeType: z.optional(z.string()), /** * Optional array of strings that specify sizes at which the icon can be used. - * Each string should be in WxH format (e.g., "48x48", "96x96") or "any" for scalable formats like SVG. + * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG. + * * If not provided, the client should assume that the icon can be used at any size. */ sizes: z.optional(z.array(z.string())), }) .passthrough(); +/** + * Base schema to add `icons` property. + * + */ +export const IconsSchema = z.object({ + /** + * Optional set of sized icons that the client can display in a user interface. + * + * Clients that support rendering icons MUST support at least the following MIME types: + * - `image/png` - PNG images (safe, universal compatibility) + * - `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility) + * + * Clients that support rendering icons SHOULD also support: + * - `image/svg+xml` - SVG images (scalable but requires security precautions) + * - `image/webp` - WebP images (modern, efficient format) + */ + icons: z.array(IconSchema).optional(), +}).passthrough(); + /** * Base metadata interface for common properties across resources, tools, prompts, and implementations. */ @@ -251,16 +271,7 @@ export const ImplementationSchema = BaseMetadataSchema.extend({ * An optional URL of the website for this implementation. */ websiteUrl: z.optional(z.string()), - /** - * An optional list of icons for this implementation. - * This can be used by clients to display the implementation in a user interface. - * Each icon should have a `kind` property that specifies whether it is a data representation or a URL source, a `src` property that points to the icon file or data representation, and may also include a `mimeType` and `sizes` property. - * The `mimeType` property should be a valid MIME type for the icon file, such as "image/png" or "image/svg+xml". - * The `sizes` property should be a string that specifies one or more sizes at which the icon file can be used, such as "48x48" or "any" for scalable formats like SVG. - * The `sizes` property is optional, and if not provided, the client should assume that the icon can be used at any size. - */ - icons: z.optional(z.array(IconSchema)), -}); +}).merge(IconsSchema); /** * Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities. @@ -541,17 +552,12 @@ export const ResourceSchema = BaseMetadataSchema.extend({ */ mimeType: z.optional(z.string()), - /** - * An optional list of icons for this resource. - */ - icons: z.optional(z.array(IconSchema)), - /** * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields) * for notes on _meta usage. */ _meta: z.optional(z.object({}).passthrough()), -}); +}).merge(IconsSchema); /** * A template description for resources available on the server. @@ -579,7 +585,7 @@ export const ResourceTemplateSchema = BaseMetadataSchema.extend({ * for notes on _meta usage. */ _meta: z.optional(z.object({}).passthrough()), -}); +}).merge(IconsSchema); /** * Sent from the client to request a list of resources the server has. @@ -712,16 +718,12 @@ export const PromptSchema = BaseMetadataSchema.extend({ * A list of arguments to use for templating the prompt. */ arguments: z.optional(z.array(PromptArgumentSchema)), - /** - * An optional list of icons for this prompt. - */ - icons: z.optional(z.array(IconSchema)), /** * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields) * for notes on _meta usage. */ _meta: z.optional(z.object({}).passthrough()), -}); +}).merge(IconsSchema); /** * Sent from the client to request a list of prompts and prompt templates the server has. @@ -974,17 +976,12 @@ export const ToolSchema = BaseMetadataSchema.extend({ */ annotations: z.optional(ToolAnnotationsSchema), - /** - * An optional list of icons for this tool. - */ - icons: z.optional(z.array(IconSchema)), - /** * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields) * for notes on _meta usage. */ _meta: z.optional(z.object({}).passthrough()), -}); +}).merge(IconsSchema); /** * Sent from the client to request a list of tools the server has. @@ -1585,6 +1582,7 @@ export type CancelledNotification = Infer; /* Base Metadata */ export type Icon = Infer; +export type Icons = Infer; export type BaseMetadata = Infer; /* Initialization */