test: add compile-time key-parity assertions for spec type checks (#1652)

Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
This commit is contained in:
Luis Reche 2026-03-30 22:20:44 +02:00 • committed by GitHub
commit a39a9eb485
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -763,6 +763,302 @@ const sdkTypeChecks = {
}
};
// ---------------------------------------------------------------------------
// Key-level assertions: verify that each SDK type and its corresponding spec
// type expose exactly the same set of named property keys. This catches cases
// where a Zod schema marks a field as `.optional()` but the spec does not (or
// vice-versa), which the mutual-assignability checks above cannot detect
// because optional fields satisfy structural subtyping in both directions.
// ---------------------------------------------------------------------------
/** Strip index signatures, keeping only explicitly-named keys. */
type KnownKeys<T> = keyof {
[K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K];
};
/**
* Assert that A and B have exactly the same set of known (named) keys.
* Resolves to `true` on match; a descriptive error type on mismatch.
*/
type AssertExactKeys<
A,
B,
Extra extends PropertyKey = Exclude<KnownKeys<A>, KnownKeys<B>>,
Missing extends PropertyKey = Exclude<KnownKeys<B>, KnownKeys<A>>
> = [Extra, Missing] extends [never, never] ? true : { _brand: 'KeyMismatch'; extra: Extra; missing: Missing };
/** Constraint: T must resolve to `true`. */
type Assert<T extends true> = T;
/*
* Excluded from key-level assertions (23 entries):
*
* Union types — KnownKeys cannot meaningfully enumerate their members (15):
* ClientRequest, ServerRequest, ClientNotification, ServerNotification,
* ClientResult, ServerResult, JSONRPCMessage, JSONRPCResponse, ContentBlock,
* SamplingMessageContentBlock, ElicitRequestParams, PrimitiveSchemaDefinition,
* SingleSelectEnumSchema, MultiSelectEnumSchema, EnumSchema
*
* Primitive type aliases — no object keys to compare (8):
* JSONValue, JSONArray, Role, LoggingLevel, ProgressToken, RequestId,
* Cursor, TaskStatus
*/
// -- Simple types (96) --
type _K_RequestParams = Assert<AssertExactKeys<SDKTypes.RequestParams, SpecTypes.RequestParams>>;
type _K_NotificationParams = Assert<AssertExactKeys<SDKTypes.NotificationParams, SpecTypes.NotificationParams>>;
type _K_CancelledNotificationParams = Assert<AssertExactKeys<SDKTypes.CancelledNotificationParams, SpecTypes.CancelledNotificationParams>>;
type _K_InitializeRequestParams = Assert<AssertExactKeys<SDKTypes.InitializeRequestParams, SpecTypes.InitializeRequestParams>>;
type _K_ProgressNotificationParams = Assert<AssertExactKeys<SDKTypes.ProgressNotificationParams, SpecTypes.ProgressNotificationParams>>;
type _K_ResourceRequestParams = Assert<AssertExactKeys<SDKTypes.ResourceRequestParams, SpecTypes.ResourceRequestParams>>;
type _K_ReadResourceRequestParams = Assert<AssertExactKeys<SDKTypes.ReadResourceRequestParams, SpecTypes.ReadResourceRequestParams>>;
type _K_SubscribeRequestParams = Assert<AssertExactKeys<SDKTypes.SubscribeRequestParams, SpecTypes.SubscribeRequestParams>>;
type _K_UnsubscribeRequestParams = Assert<AssertExactKeys<SDKTypes.UnsubscribeRequestParams, SpecTypes.UnsubscribeRequestParams>>;
type _K_ResourceUpdatedNotificationParams = Assert<
AssertExactKeys<SDKTypes.ResourceUpdatedNotificationParams, SpecTypes.ResourceUpdatedNotificationParams>
>;
type _K_GetPromptRequestParams = Assert<AssertExactKeys<SDKTypes.GetPromptRequestParams, SpecTypes.GetPromptRequestParams>>;
type _K_CallToolRequestParams = Assert<AssertExactKeys<SDKTypes.CallToolRequestParams, SpecTypes.CallToolRequestParams>>;
type _K_SetLevelRequestParams = Assert<AssertExactKeys<SDKTypes.SetLevelRequestParams, SpecTypes.SetLevelRequestParams>>;
type _K_LoggingMessageNotificationParams = Assert<
AssertExactKeys<SDKTypes.LoggingMessageNotificationParams, SpecTypes.LoggingMessageNotificationParams>
>;
type _K_CreateMessageRequestParams = Assert<AssertExactKeys<SDKTypes.CreateMessageRequestParams, SpecTypes.CreateMessageRequestParams>>;
type _K_CompleteRequestParams = Assert<AssertExactKeys<SDKTypes.CompleteRequestParams, SpecTypes.CompleteRequestParams>>;
type _K_ElicitRequestFormParams = Assert<AssertExactKeys<SDKTypes.ElicitRequestFormParams, SpecTypes.ElicitRequestFormParams>>;
type _K_ElicitRequestURLParams = Assert<AssertExactKeys<SDKTypes.ElicitRequestURLParams, SpecTypes.ElicitRequestURLParams>>;
type _K_PaginatedRequestParams = Assert<AssertExactKeys<SDKTypes.PaginatedRequestParams, SpecTypes.PaginatedRequestParams>>;
type _K_BaseMetadata = Assert<AssertExactKeys<SDKTypes.BaseMetadata, SpecTypes.BaseMetadata>>;
type _K_Implementation = Assert<AssertExactKeys<SDKTypes.Implementation, SpecTypes.Implementation>>;
type _K_PaginatedResult = Assert<AssertExactKeys<SDKTypes.PaginatedResult, SpecTypes.PaginatedResult>>;
type _K_ListRootsResult = Assert<AssertExactKeys<SDKTypes.ListRootsResult, SpecTypes.ListRootsResult>>;
type _K_Root = Assert<AssertExactKeys<SDKTypes.Root, SpecTypes.Root>>;
type _K_ElicitResult = Assert<AssertExactKeys<SDKTypes.ElicitResult, SpecTypes.ElicitResult>>;
type _K_CompleteResult = Assert<AssertExactKeys<SDKTypes.CompleteResult, SpecTypes.CompleteResult>>;
type _K_Request = Assert<AssertExactKeys<SDKTypes.Request, SpecTypes.Request>>;
type _K_Result = Assert<AssertExactKeys<SDKTypes.Result, SpecTypes.Result>>;
type _K_JSONRPCRequest = Assert<AssertExactKeys<SDKTypes.JSONRPCRequest, SpecTypes.JSONRPCRequest>>;
type _K_JSONRPCNotification = Assert<AssertExactKeys<SDKTypes.JSONRPCNotification, SpecTypes.JSONRPCNotification>>;
type _K_EmptyResult = Assert<AssertExactKeys<SDKTypes.EmptyResult, SpecTypes.EmptyResult>>;
type _K_Notification = Assert<AssertExactKeys<SDKTypes.Notification, SpecTypes.Notification>>;
type _K_ResourceTemplateReference = Assert<AssertExactKeys<SDKTypes.ResourceTemplateReference, SpecTypes.ResourceTemplateReference>>;
// @ts-expect-error Genuine mismatch: SDK PromptReference is missing 'title' from spec
type _K_PromptReference = Assert<AssertExactKeys<SDKTypes.PromptReference, SpecTypes.PromptReference>>;
type _K_ToolAnnotations = Assert<AssertExactKeys<SDKTypes.ToolAnnotations, SpecTypes.ToolAnnotations>>;
type _K_Tool = Assert<AssertExactKeys<SDKTypes.Tool, SpecTypes.Tool>>;
type _K_ListToolsResult = Assert<AssertExactKeys<SDKTypes.ListToolsResult, SpecTypes.ListToolsResult>>;
type _K_CallToolResult = Assert<AssertExactKeys<SDKTypes.CallToolResult, SpecTypes.CallToolResult>>;
type _K_ListResourcesResult = Assert<AssertExactKeys<SDKTypes.ListResourcesResult, SpecTypes.ListResourcesResult>>;
type _K_ListResourceTemplatesResult = Assert<AssertExactKeys<SDKTypes.ListResourceTemplatesResult, SpecTypes.ListResourceTemplatesResult>>;
type _K_ReadResourceResult = Assert<AssertExactKeys<SDKTypes.ReadResourceResult, SpecTypes.ReadResourceResult>>;
type _K_ResourceContents = Assert<AssertExactKeys<SDKTypes.ResourceContents, SpecTypes.ResourceContents>>;
type _K_TextResourceContents = Assert<AssertExactKeys<SDKTypes.TextResourceContents, SpecTypes.TextResourceContents>>;
type _K_BlobResourceContents = Assert<AssertExactKeys<SDKTypes.BlobResourceContents, SpecTypes.BlobResourceContents>>;
type _K_Resource = Assert<AssertExactKeys<SDKTypes.Resource, SpecTypes.Resource>>;
// @ts-expect-error Genuine mismatch: SDK PromptArgument is missing 'title' from spec
type _K_PromptArgument = Assert<AssertExactKeys<SDKTypes.PromptArgument, SpecTypes.PromptArgument>>;
type _K_Prompt = Assert<AssertExactKeys<SDKTypes.Prompt, SpecTypes.Prompt>>;
type _K_ListPromptsResult = Assert<AssertExactKeys<SDKTypes.ListPromptsResult, SpecTypes.ListPromptsResult>>;
type _K_GetPromptResult = Assert<AssertExactKeys<SDKTypes.GetPromptResult, SpecTypes.GetPromptResult>>;
type _K_TextContent = Assert<AssertExactKeys<SDKTypes.TextContent, SpecTypes.TextContent>>;
type _K_ImageContent = Assert<AssertExactKeys<SDKTypes.ImageContent, SpecTypes.ImageContent>>;
type _K_AudioContent = Assert<AssertExactKeys<SDKTypes.AudioContent, SpecTypes.AudioContent>>;
type _K_EmbeddedResource = Assert<AssertExactKeys<SDKTypes.EmbeddedResource, SpecTypes.EmbeddedResource>>;
type _K_ResourceLink = Assert<AssertExactKeys<SDKTypes.ResourceLink, SpecTypes.ResourceLink>>;
type _K_PromptMessage = Assert<AssertExactKeys<SDKTypes.PromptMessage, SpecTypes.PromptMessage>>;
type _K_BooleanSchema = Assert<AssertExactKeys<SDKTypes.BooleanSchema, SpecTypes.BooleanSchema>>;
type _K_StringSchema = Assert<AssertExactKeys<SDKTypes.StringSchema, SpecTypes.StringSchema>>;
type _K_NumberSchema = Assert<AssertExactKeys<SDKTypes.NumberSchema, SpecTypes.NumberSchema>>;
type _K_UntitledSingleSelectEnumSchema = Assert<
AssertExactKeys<SDKTypes.UntitledSingleSelectEnumSchema, SpecTypes.UntitledSingleSelectEnumSchema>
>;
type _K_TitledSingleSelectEnumSchema = Assert<
AssertExactKeys<SDKTypes.TitledSingleSelectEnumSchema, SpecTypes.TitledSingleSelectEnumSchema>
>;
type _K_UntitledMultiSelectEnumSchema = Assert<
AssertExactKeys<SDKTypes.UntitledMultiSelectEnumSchema, SpecTypes.UntitledMultiSelectEnumSchema>
>;
type _K_TitledMultiSelectEnumSchema = Assert<AssertExactKeys<SDKTypes.TitledMultiSelectEnumSchema, SpecTypes.TitledMultiSelectEnumSchema>>;
type _K_LegacyTitledEnumSchema = Assert<AssertExactKeys<SDKTypes.LegacyTitledEnumSchema, SpecTypes.LegacyTitledEnumSchema>>;
type _K_JSONRPCErrorResponse = Assert<AssertExactKeys<SDKTypes.JSONRPCErrorResponse, SpecTypes.JSONRPCErrorResponse>>;
type _K_JSONRPCResultResponse = Assert<AssertExactKeys<SDKTypes.JSONRPCResultResponse, SpecTypes.JSONRPCResultResponse>>;
type _K_InitializeResult = Assert<AssertExactKeys<SDKTypes.InitializeResult, SpecTypes.InitializeResult>>;
type _K_ClientCapabilities = Assert<AssertExactKeys<SDKTypes.ClientCapabilities, SpecTypes.ClientCapabilities>>;
type _K_ServerCapabilities = Assert<AssertExactKeys<SDKTypes.ServerCapabilities, SpecTypes.ServerCapabilities>>;
type _K_SamplingMessage = Assert<AssertExactKeys<SDKTypes.SamplingMessage, SpecTypes.SamplingMessage>>;
type _K_Icon = Assert<AssertExactKeys<SDKTypes.Icon, SpecTypes.Icon>>;
type _K_Icons = Assert<AssertExactKeys<SDKTypes.Icons, SpecTypes.Icons>>;
type _K_ModelHint = Assert<AssertExactKeys<SDKTypes.ModelHint, SpecTypes.ModelHint>>;
type _K_ModelPreferences = Assert<AssertExactKeys<SDKTypes.ModelPreferences, SpecTypes.ModelPreferences>>;
type _K_ToolChoice = Assert<AssertExactKeys<SDKTypes.ToolChoice, SpecTypes.ToolChoice>>;
type _K_ToolUseContent = Assert<AssertExactKeys<SDKTypes.ToolUseContent, SpecTypes.ToolUseContent>>;
type _K_ToolResultContent = Assert<AssertExactKeys<SDKTypes.ToolResultContent, SpecTypes.ToolResultContent>>;
type _K_Annotations = Assert<AssertExactKeys<SDKTypes.Annotations, SpecTypes.Annotations>>;
type _K_TaskAugmentedRequestParams = Assert<AssertExactKeys<SDKTypes.TaskAugmentedRequestParams, SpecTypes.TaskAugmentedRequestParams>>;
type _K_ToolExecution = Assert<AssertExactKeys<SDKTypes.ToolExecution, SpecTypes.ToolExecution>>;
type _K_TaskMetadata = Assert<AssertExactKeys<SDKTypes.TaskMetadata, SpecTypes.TaskMetadata>>;
type _K_RelatedTaskMetadata = Assert<AssertExactKeys<SDKTypes.RelatedTaskMetadata, SpecTypes.RelatedTaskMetadata>>;
type _K_Task = Assert<AssertExactKeys<SDKTypes.Task, SpecTypes.Task>>;
type _K_CreateTaskResult = Assert<AssertExactKeys<SDKTypes.CreateTaskResult, SpecTypes.CreateTaskResult>>;
type _K_GetTaskResult = Assert<AssertExactKeys<SDKTypes.GetTaskResult, SpecTypes.GetTaskResult>>;
type _K_ListTasksResult = Assert<AssertExactKeys<SDKTypes.ListTasksResult, SpecTypes.ListTasksResult>>;
type _K_CancelTaskResult = Assert<AssertExactKeys<SDKTypes.CancelTaskResult, SpecTypes.CancelTaskResult>>;
type _K_GetTaskPayloadResult = Assert<AssertExactKeys<SDKTypes.GetTaskPayloadResult, SpecTypes.GetTaskPayloadResult>>;
type _K_TaskStatusNotificationParams = Assert<
AssertExactKeys<SDKTypes.TaskStatusNotificationParams, SpecTypes.TaskStatusNotificationParams>
>;
type _K_JSONObject = Assert<AssertExactKeys<SDKTypes.JSONObject, SpecTypes.JSONObject>>;
type _K_MetaObject = Assert<AssertExactKeys<SDKTypes.MetaObject, SpecTypes.MetaObject>>;
// @ts-expect-error Genuine mismatch: SDK RequestMetaObject has extra 'io.modelcontextprotocol/related-task' not in spec
type _K_RequestMetaObject = Assert<AssertExactKeys<SDKTypes.RequestMetaObject, SpecTypes.RequestMetaObject>>;
type _K_ParseError = Assert<AssertExactKeys<SDKTypes.ParseError, SpecTypes.ParseError>>;
type _K_InvalidRequestError = Assert<AssertExactKeys<SDKTypes.InvalidRequestError, SpecTypes.InvalidRequestError>>;
type _K_MethodNotFoundError = Assert<AssertExactKeys<SDKTypes.MethodNotFoundError, SpecTypes.MethodNotFoundError>>;
type _K_InvalidParamsError = Assert<AssertExactKeys<SDKTypes.InvalidParamsError, SpecTypes.InvalidParamsError>>;
type _K_InternalError = Assert<AssertExactKeys<SDKTypes.InternalError, SpecTypes.InternalError>>;
// -- WithJSONRPC-wrapped notification types (11) --
// SDK notification types do not include `jsonrpc` — the spec types do. We wrap
// with WithJSONRPC<> to add the missing field before comparing keys.
type _K_ElicitationCompleteNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.ElicitationCompleteNotification>, SpecTypes.ElicitationCompleteNotification>
>;
type _K_CancelledNotification = Assert<AssertExactKeys<WithJSONRPC<SDKTypes.CancelledNotification>, SpecTypes.CancelledNotification>>;
type _K_ProgressNotification = Assert<AssertExactKeys<WithJSONRPC<SDKTypes.ProgressNotification>, SpecTypes.ProgressNotification>>;
type _K_ToolListChangedNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.ToolListChangedNotification>, SpecTypes.ToolListChangedNotification>
>;
type _K_ResourceListChangedNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.ResourceListChangedNotification>, SpecTypes.ResourceListChangedNotification>
>;
type _K_PromptListChangedNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.PromptListChangedNotification>, SpecTypes.PromptListChangedNotification>
>;
type _K_RootsListChangedNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.RootsListChangedNotification>, SpecTypes.RootsListChangedNotification>
>;
type _K_ResourceUpdatedNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.ResourceUpdatedNotification>, SpecTypes.ResourceUpdatedNotification>
>;
type _K_LoggingMessageNotification = Assert<
AssertExactKeys<WithJSONRPC<SDKTypes.LoggingMessageNotification>, SpecTypes.LoggingMessageNotification>
>;
type _K_InitializedNotification = Assert<AssertExactKeys<WithJSONRPC<SDKTypes.InitializedNotification>, SpecTypes.InitializedNotification>>;
type _K_TaskStatusNotification = Assert<AssertExactKeys<WithJSONRPC<SDKTypes.TaskStatusNotification>, SpecTypes.TaskStatusNotification>>;
// -- WithJSONRPCRequest-wrapped request types (21) --
// SDK request types do not include `jsonrpc` or `id` — the spec types do. We
// wrap with WithJSONRPCRequest<> to add the missing fields before comparing keys.
type _K_SubscribeRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.SubscribeRequest>, SpecTypes.SubscribeRequest>>;
type _K_UnsubscribeRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.UnsubscribeRequest>, SpecTypes.UnsubscribeRequest>>;
type _K_PaginatedRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.PaginatedRequest>, SpecTypes.PaginatedRequest>>;
type _K_ListRootsRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ListRootsRequest>, SpecTypes.ListRootsRequest>>;
type _K_ElicitRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ElicitRequest>, SpecTypes.ElicitRequest>>;
type _K_CompleteRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.CompleteRequest>, SpecTypes.CompleteRequest>>;
type _K_ListToolsRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ListToolsRequest>, SpecTypes.ListToolsRequest>>;
type _K_CallToolRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.CallToolRequest>, SpecTypes.CallToolRequest>>;
type _K_SetLevelRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.SetLevelRequest>, SpecTypes.SetLevelRequest>>;
type _K_PingRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.PingRequest>, SpecTypes.PingRequest>>;
type _K_ListResourcesRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ListResourcesRequest>, SpecTypes.ListResourcesRequest>>;
type _K_ListResourceTemplatesRequest = Assert<
AssertExactKeys<WithJSONRPCRequest<SDKTypes.ListResourceTemplatesRequest>, SpecTypes.ListResourceTemplatesRequest>
>;
type _K_ReadResourceRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ReadResourceRequest>, SpecTypes.ReadResourceRequest>>;
type _K_ListPromptsRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ListPromptsRequest>, SpecTypes.ListPromptsRequest>>;
type _K_GetPromptRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.GetPromptRequest>, SpecTypes.GetPromptRequest>>;
type _K_CreateMessageRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.CreateMessageRequest>, SpecTypes.CreateMessageRequest>>;
type _K_InitializeRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.InitializeRequest>, SpecTypes.InitializeRequest>>;
type _K_GetTaskPayloadRequest = Assert<
AssertExactKeys<WithJSONRPCRequest<SDKTypes.GetTaskPayloadRequest>, SpecTypes.GetTaskPayloadRequest>
>;
type _K_ListTasksRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.ListTasksRequest>, SpecTypes.ListTasksRequest>>;
type _K_CancelTaskRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.CancelTaskRequest>, SpecTypes.CancelTaskRequest>>;
type _K_GetTaskRequest = Assert<AssertExactKeys<WithJSONRPCRequest<SDKTypes.GetTaskRequest>, SpecTypes.GetTaskRequest>>;
// -- TypedResultResponse-wrapped types (21) --
// The spec defines typed *ResultResponse interfaces that pair JSONRPCResultResponse
// with a specific result. We compare TypedResultResponse<SDKInnerType> against the
// spec's combined type.
type _K_InitializeResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.InitializeResult>, SpecTypes.InitializeResultResponse>
>;
type _K_PingResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.EmptyResult>, SpecTypes.PingResultResponse>>;
type _K_ListResourcesResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.ListResourcesResult>, SpecTypes.ListResourcesResultResponse>
>;
type _K_ListResourceTemplatesResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.ListResourceTemplatesResult>, SpecTypes.ListResourceTemplatesResultResponse>
>;
type _K_ReadResourceResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.ReadResourceResult>, SpecTypes.ReadResourceResultResponse>
>;
type _K_SubscribeResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.EmptyResult>, SpecTypes.SubscribeResultResponse>>;
type _K_UnsubscribeResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.EmptyResult>, SpecTypes.UnsubscribeResultResponse>>;
type _K_ListPromptsResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.ListPromptsResult>, SpecTypes.ListPromptsResultResponse>
>;
type _K_GetPromptResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.GetPromptResult>, SpecTypes.GetPromptResultResponse>>;
type _K_ListToolsResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.ListToolsResult>, SpecTypes.ListToolsResultResponse>>;
type _K_CallToolResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.CallToolResult>, SpecTypes.CallToolResultResponse>>;
type _K_CreateTaskResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.CreateTaskResult>, SpecTypes.CreateTaskResultResponse>
>;
type _K_GetTaskResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.GetTaskResult>, SpecTypes.GetTaskResultResponse>>;
type _K_GetTaskPayloadResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.GetTaskPayloadResult>, SpecTypes.GetTaskPayloadResultResponse>
>;
type _K_CancelTaskResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.CancelTaskResult>, SpecTypes.CancelTaskResultResponse>
>;
type _K_ListTasksResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.ListTasksResult>, SpecTypes.ListTasksResultResponse>>;
type _K_SetLevelResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.EmptyResult>, SpecTypes.SetLevelResultResponse>>;
type _K_CreateMessageResultResponse = Assert<
AssertExactKeys<TypedResultResponse<SDKTypes.CreateMessageResultWithTools>, SpecTypes.CreateMessageResultResponse>
>;
type _K_CompleteResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.CompleteResult>, SpecTypes.CompleteResultResponse>>;
type _K_ListRootsResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.ListRootsResult>, SpecTypes.ListRootsResultResponse>>;
type _K_ElicitResultResponse = Assert<AssertExactKeys<TypedResultResponse<SDKTypes.ElicitResult>, SpecTypes.ElicitResultResponse>>;
// -- Name mismatches (2) --
// SDK exports these under different names than the spec.
type _K_CreateMessageResult = Assert<AssertExactKeys<SDKTypes.CreateMessageResultWithTools, SpecTypes.CreateMessageResult>>;
type _K_ResourceTemplate = Assert<AssertExactKeys<SDKTypes.ResourceTemplateType, SpecTypes.ResourceTemplate>>;
// Types excluded from the key-parity completeness guard: union types and primitive aliases
// that cannot have meaningful AssertExactKeys assertions.
const KEY_PARITY_EXCLUDED = [
// Union types (15)
'ClientRequest',
'ServerRequest',
'ClientNotification',
'ServerNotification',
'ClientResult',
'ServerResult',
'JSONRPCMessage',
'JSONRPCResponse',
'ContentBlock',
'SamplingMessageContentBlock',
'ElicitRequestParams',
'PrimitiveSchemaDefinition',
'SingleSelectEnumSchema',
'MultiSelectEnumSchema',
'EnumSchema',
// Primitive aliases (8)
'JSONValue',
'JSONArray',
'Role',
'LoggingLevel',
'ProgressToken',
'RequestId',
'Cursor',
'TaskStatus'
];
// This file is .gitignore'd, and fetched by `npm run fetch:spec-types` (called by `npm run test`)
const SPEC_TYPES_FILE = path.resolve(__dirname, '../src/types/spec.types.ts');
const SDK_TYPES_FILE = path.resolve(__dirname, '../src/types/types.ts');
@ -778,6 +1074,10 @@ function extractExportedTypes(source: string): string[] {
return matches.map(m => m[1]!);
}
function extractKeyParityTypes(source: string): string[] {
return [...source.matchAll(/^type _K_(\w+)\s*=/gm)].map(m => m[1]!);
}
describe('Spec Types', () => {
const specTypes = extractExportedTypes(fs.readFileSync(SPEC_TYPES_FILE, 'utf8'));
const sdkTypes = extractExportedTypes(fs.readFileSync(SDK_TYPES_FILE, 'utf8'));
@ -807,6 +1107,14 @@ describe('Spec Types', () => {
expect(missingTests).toHaveLength(0);
});
it('should have key-parity assertions for all non-excluded compatibility tests', () => {
const thisSource = fs.readFileSync(__filename, 'utf8');
const checked = new Set(extractKeyParityTypes(thisSource));
const excluded = new Set<string>(KEY_PARITY_EXCLUDED);
const missing = Object.keys(sdkTypeChecks).filter(name => !checked.has(name) && !excluded.has(name));
expect(missing).toHaveLength(0);
});
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();