diff --git a/src/client/index.ts b/src/client/index.ts index 03a6b40b5c..ae0e698ec3 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -53,15 +53,7 @@ import { } from '../types.js'; import { AjvJsonSchemaValidator } from '../validation/ajv-provider.js'; import type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator } from '../validation/types.js'; -import { - AnyObjectSchema, - SchemaOutput, - getObjectShape, - isZ4Schema, - safeParse, - type ZodV3Internal, - type ZodV4Internal -} from '../server/zod-compat.js'; +import { AnyObjectSchema, SchemaOutput, getLiteralValue, getObjectShape, safeParse } from '../server/zod-compat.js'; import type { RequestHandlerExtra } from '../shared/protocol.js'; import { ExperimentalClientTasks } from '../experimental/tasks/client.js'; import { assertToolsCallTaskCapability, assertClientRequestTaskCapability } from '../experimental/tasks/helpers.js'; @@ -339,18 +331,7 @@ export class Client< throw new Error('Schema is missing a method literal'); } - // Extract literal value using type-safe property access - let methodValue: unknown; - if (isZ4Schema(methodSchema)) { - const v4Schema = methodSchema as unknown as ZodV4Internal; - const v4Def = v4Schema._zod?.def; - methodValue = v4Def?.value ?? v4Schema.value; - } else { - const v3Schema = methodSchema as unknown as ZodV3Internal; - const legacyDef = v3Schema._def; - methodValue = legacyDef?.value ?? v3Schema.value; - } - + const methodValue = getLiteralValue(methodSchema); if (typeof methodValue !== 'string') { throw new Error('Schema method literal must be a string'); } diff --git a/src/server/index.ts b/src/server/index.ts index 531a559dd5..cd75e5954a 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -44,15 +44,7 @@ import { } from '../types.js'; import { AjvJsonSchemaValidator } from '../validation/ajv-provider.js'; import type { JsonSchemaType, jsonSchemaValidator } from '../validation/types.js'; -import { - AnyObjectSchema, - getObjectShape, - isZ4Schema, - safeParse, - SchemaOutput, - type ZodV3Internal, - type ZodV4Internal -} from './zod-compat.js'; +import { AnyObjectSchema, getLiteralValue, getObjectShape, safeParse, SchemaOutput } from './zod-compat.js'; import { RequestHandlerExtra } from '../shared/protocol.js'; import { ExperimentalServerTasks } from '../experimental/tasks/server.js'; import { assertToolsCallTaskCapability, assertClientRequestTaskCapability } from '../experimental/tasks/helpers.js'; @@ -228,18 +220,7 @@ export class Server< throw new Error('Schema is missing a method literal'); } - // Extract literal value using type-safe property access - let methodValue: unknown; - if (isZ4Schema(methodSchema)) { - const v4Schema = methodSchema as unknown as ZodV4Internal; - const v4Def = v4Schema._zod?.def; - methodValue = v4Def?.value ?? v4Schema.value; - } else { - const v3Schema = methodSchema as unknown as ZodV3Internal; - const legacyDef = v3Schema._def; - methodValue = legacyDef?.value ?? v3Schema.value; - } - + const methodValue = getLiteralValue(methodSchema); if (typeof methodValue !== 'string') { throw new Error('Schema method literal must be a string'); } diff --git a/test/issues/test_1380_zod325_literal.test.ts b/test/issues/test_1380_zod325_literal.test.ts new file mode 100644 index 0000000000..56936c2a16 --- /dev/null +++ b/test/issues/test_1380_zod325_literal.test.ts @@ -0,0 +1,73 @@ +import { Client } from '../../src/client/index.js'; +import { Server } from '../../src/server/index.js'; +import type { AnyObjectSchema, AnySchema } from '../../src/server/zod-compat.js'; +import { getLiteralValue } from '../../src/server/zod-compat.js'; + +function requestSchemaWithValuesLiteral(method: string): AnyObjectSchema { + return { + _zod: { + def: { + type: 'object', + shape: { + method: { + _zod: { + def: { + type: 'literal', + values: [method] + } + } + } + } + } + } + } as unknown as AnyObjectSchema; +} + +describe('Issue #1380: Zod 3.25.x v4 literal value shape', () => { + test('extracts literal values stored in _zod.def.values', () => { + const methodSchema = { + _zod: { + def: { + type: 'literal', + values: ['ping'] + } + } + } as unknown as AnySchema; + + expect(getLiteralValue(methodSchema)).toBe('ping'); + }); + + test('registers server request handlers when the method literal uses _zod.def.values', () => { + const server = new Server( + { name: 'test server', version: '1.0' }, + { + capabilities: { + tools: {} + } + } + ); + + expect(() => { + server.setRequestHandler(requestSchemaWithValuesLiteral('tools/call'), () => ({ + content: [] + })); + }).not.toThrow(); + }); + + test('registers client request handlers when the method literal uses _zod.def.values', () => { + const client = new Client( + { name: 'test client', version: '1.0' }, + { + capabilities: { + elicitation: {} + } + } + ); + + expect(() => { + client.setRequestHandler(requestSchemaWithValuesLiteral('elicitation/create'), () => ({ + action: 'cancel' + })); + }).not.toThrow(); + }); +});