From 9f4764cd417e11bc3167c2e8a6817b40e3c40ec7 Mon Sep 17 00:00:00 2001 From: pandego <7780875+pandego@users.noreply.github.com> Date: Tue, 24 Feb 2026 02:28:34 +0100 Subject: [PATCH] fix(plugins): guard legacy zod schemas without toJSONSchema --- src/channels/plugins/config-schema.test.ts | 17 +++++++++++++++ src/channels/plugins/config-schema.ts | 24 ++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/channels/plugins/config-schema.test.ts diff --git a/src/channels/plugins/config-schema.test.ts b/src/channels/plugins/config-schema.test.ts new file mode 100644 index 000000000..2abd11e53 --- /dev/null +++ b/src/channels/plugins/config-schema.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; +import { z } from "zod"; +import { buildChannelConfigSchema } from "./config-schema.js"; + +describe("buildChannelConfigSchema", () => { + it("builds json schema when toJSONSchema is available", () => { + const schema = z.object({ enabled: z.boolean().default(true) }); + const result = buildChannelConfigSchema(schema); + expect(result.schema).toMatchObject({ type: "object" }); + }); + + it("falls back when toJSONSchema is missing (zod v3 plugin compatibility)", () => { + const legacySchema = {} as unknown as Parameters[0]; + const result = buildChannelConfigSchema(legacySchema); + expect(result.schema).toEqual({ type: "object", additionalProperties: true }); + }); +}); diff --git a/src/channels/plugins/config-schema.ts b/src/channels/plugins/config-schema.ts index 50b81e83b..75074ae56 100644 --- a/src/channels/plugins/config-schema.ts +++ b/src/channels/plugins/config-schema.ts @@ -1,11 +1,27 @@ import type { ZodTypeAny } from "zod"; import type { ChannelConfigSchema } from "./types.plugin.js"; +type ZodSchemaWithToJsonSchema = ZodTypeAny & { + toJSONSchema?: (params?: Record) => unknown; +}; + export function buildChannelConfigSchema(schema: ZodTypeAny): ChannelConfigSchema { + const schemaWithJson = schema as ZodSchemaWithToJsonSchema; + if (typeof schemaWithJson.toJSONSchema === "function") { + return { + schema: schemaWithJson.toJSONSchema({ + target: "draft-07", + unrepresentable: "any", + }) as Record, + }; + } + + // Compatibility fallback for plugins built against Zod v3 schemas, + // where `.toJSONSchema()` is unavailable. return { - schema: schema.toJSONSchema({ - target: "draft-07", - unrepresentable: "any", - }) as Record, + schema: { + type: "object", + additionalProperties: true, + }, }; }