Skip to content

feat(web_core)!: remove Zod 3 support - #42

Closed
louis-bompart wants to merge 1 commit into
claude/zod-scope/theme-zod4from
claude/zod-scope/remove-zod3
Closed

louis-bompart wants to merge 1 commit into
claude/zod-scope/theme-zod4from
claude/zod-scope/remove-zod3

Conversation

@louis-bompart

Copy link
Copy Markdown
Collaborator

Description

This PR removes Zod 3 support, stacked on #41. It's the last step of the plan: no source or test in the repository imports zod/v3 any more, and web_core no longer depends on zod-to-json-schema.

Removed, with their replacements:

Removed Replacement
A Zod 3 schema as an EntrySchema an A2uiSchema: Zod 4, another Standard JSON Schema library, or JSON Schema
@a2ui/web_core/zod3, fromZod3 not needed
spec() .meta(specMeta(...))
specDef() .meta(specMeta({defName}))
exclusiveUnion z.xor()
markChildRef, childRefKindOf, ChildRefKind .meta({$ref}) to ComponentId or ChildList

SpecMixin is now a name, and JsonSpecAnnotation is SpecAnnotation. RefSchemaOptions stays, for componentId() and childList().

Zod 3 paths removed from the core:

  • the JSON Schema view: the zod-to-json-schema conversion, the REF: and markChildRef handling, and the spec-view facts it added;
  • the serializer and validation schema generator;
  • the entry schemas (zodSchemaFor, themeSchemaOf, validateEntry);
  • the catalog constructor's theme argument;
  • the function invoker's and data context's ZodError handling;
  • formatZodIssue, which now formats Zod 4 issues only.

Fixed along the way. getKnownSchemaKeys treated only additionalProperties: true as open. Zod 4 writes a loose object as additionalProperties: {}, so a function whose arguments were a Zod 4 loose object had its unknown arguments rejected. Both forms now count as open. A test found it once its loose object was Zod 4.

Behavior the tests now pin:

  • Zod 4 merges metadata shallowly, so an outer specMeta() replaces the annotation of the schema it wraps rather than merging with it. The generated catalogs set one annotation per node, so their documents don't change.
  • Zod 4's .strict() returns a copy that drops metadata set before it, so .describe() goes after .strict(), or you use z.strictObject.

Tests.

  • Tests of Zod 3 behavior are removed, except where a Zod 4 counterpart exists. Removed: REF: markers in views, markChildRef stamps, Zod 3 issue shapes in the formatter, typing a Zod 3 schema.
  • Tests that used Zod 3 as a convenient schema library now use Zod 4. A small parser rewrote spec() to specMeta(), specDef() to specMeta({defName}), exclusiveUnion to z.xor and REF: markers to .meta({$ref}).
  • schema_generators.test.ts, which checks the generator's output text, is unchanged.
  • Tests that relied on a Zod 3 schema being returned as is now check that a schema without a document is read through one of its own.

Also:

  • The renderers' tests, the agent SDK's pruning test, the composer and six docs pages import zod/v4.
  • The README drops the deprecated APIs.
  • yarn.lock drops web_core's zod-to-json-schema entry. Other packages still use it.

Not in this PR: the generator scripts still write Zod 3 text internally and convert it to Zod 4 with toZod4Code. Nothing imports Zod 3 at runtime there; making them write Zod 4 directly is a cleanup for later.

Validation

  • yarn build from clean
  • node --test "dist/**/*.test.js": 1448 passing, 0 failing, 40 todo
  • node tests/conformance/conformance_test.mjs: all vectors passing
  • yarn lint: 0 errors, five warnings fewer
  • yarn format:check
  • Dependents:
    • yarn test passes in typescript/catalogs/{mcp,vegachart}, typescript/renderers/{lit,react,markdown-it}, typescript/agents/a2ui_agent (plus its 478 conformance tests), the Lit and React explorers and tools/composer, which also builds.
    • Angular: builds, test:unit (328) and test:integration (222) pass. test:closure-compiler needs Java 21.
  • Compared before and after, all identical:
    • every code catalog's toJson() and validationSchema, byte for byte;
    • the binding views (5,625 results);
    • catalog entry validation (10,695 payloads), messages included;
    • theme validation (36 themes);
    • all 69 protocol message schemas over 345,602 payloads.

Part of a2ui-project#2160

Pre-launch Checklist

One time:

For this PR:

  • I have updated the relevant CHANGELOG.md file.
  • I updated/added relevant documentation.
  • My code changes (if any) have tests.
  • If my branch is on a fork, I have verified that scripts/e2e_test.sh passes.

🤖 Generated with Claude Code

EntrySchema no longer accepts a Zod 3 schema, and the zod3 entry point,
fromZod3, spec(), specDef(), exclusiveUnion, markChildRef and
childRefKindOf are removed, with their Zod 4 replacements in place. The
JSON Schema view, serializer, generator, entry schemas and issue formatter
lose their Zod 3 paths, and web_core drops zod-to-json-schema.

getKnownSchemaKeys reads Zod 4's additionalProperties: {} as open. Tests,
renderers, the agent SDK, the composer and the docs import zod/v4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@louis-bompart

Copy link
Copy Markdown
Collaborator Author

Superseded by the regrouped stack on upstream main: this change is now part of #54 (series #45 to #54). The branch is kept for reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant