Repository navigation
Update to Zod 4.5 - #19
Merged
Merged
Conversation
…iss, as zod 4.5 does
zod 4.5 installs the English locale on the first schema construction, so a module-scope z.config().localeError is undefined and every harness that passed it as __zcMsg lost its messages (or, for hosted recursive validators, formatted them after the inner finalizer had already stripped input). Export the production __zcMsg from parity-harness and use it everywhere. Also repair tests/compat.mjs, whose Function params never matched the finalizer's bindings.
… stranded zod 4.4 moved parse/safeParse/parseAsync/safeParseAsync/~standard to the prototype: each is a getter that binds the method on first read and installs the bound copy as an own property, so a fresh schema has no own descriptor to snapshot. The accessor's fallback answered that empty snapshot with undefined, which left a frozen schema, a target that refused every rollback, and two copies of jit() on one schema with `safeParse is not a function`. The fallback now reads the prototype getter with the schema as receiver, which also hands the stranded slot over to zod's own copy where the target allows it, and binds through a stand-in that inherits from the schema where it does not (frozen, or a wrapper that vetoes defineProperty). A write to a pending slot runs zod's own setter once the accessor is gone, instead of defining a copy by hand. Tests now describe both shapes a schema arrives in — untouched, or already carrying zod's own copies — and the register fixtures expect the `bound safeParse` an uninstrumented schema shows after one read.
…nd non-finite received String length checks now measure Unicode code points the way zod 4.5 does, paying for the count only inside the band of UTF-16 lengths where the verdict is in doubt, so an ordinary ASCII string never reaches the new `__zcCpl` helper and `min(1)` still compiles to `length>=1`. `z.url()` reproduces `parseURLObject`: an http(s)-protocol check without `normalize` rejects input lacking `://` with `note: "Invalid URL format"` before the parser runs, and the returned value has tabs and newlines deleted (`stripTabAndNewline`). `z.partialRecord()` is extracted from `def.partial` — the key schema keeps its values in 4.5 — and a partial record whose key schema declares a finite set reports a stray key as one `unrecognized_keys` after the walk, as `$ZodRecord` does, rather than `invalid_key`. A non-finite number reports `received: String(input)`, so `-Infinity` reads as such. Test pins updated for the 4.5 `httpUrl` issue shapes, the root `$ref` `z.toJSONSchema()` emits for a schema with an id, and the locale that zod now installs on first schema construction (read per call, as production does).
zod 4.5 skips a declared `__proto__` shape key outright, so the extractor stores a placeholder for it and every property loop (eager walk, fast check, build pass) skips it; the catchall passes skip an undeclared `__proto__` the same way, while the strict pass still reports it. `unrecognized_keys` now carries `continue: true` upstream, so it leaves the aborting-code list: an object's own refine runs after it and a union no longer counts a strict option as aborted. `.catch()` hands its callback the raw input it was given rather than the inner's partially built value, so the compiled catch snapshots its input before the inner runs. A check stamps its owning schema onto every issue it raises, so a schema-level `error` now covers that schema's own checks after the check's own message: every emitter resolves `check.message ?? typeMsg`, and the superRefine helper takes the schema message as an extra argument. Records: zod now filters non-enumerable keys, so that known divergence becomes a parity pin and the README row names the one that remains (symbol keys). The raw `ctx.issues` pin gains the `schema` key zod adds.
# Conflicts: # tests/zod-parity.test.ts
# Conflicts: # src/core/codegen/emit-issue.ts # src/core/codegen/schemas/tuple.ts # tests/zod-parity.test.ts
Owner
|
@colinhacks only started reviewing this a second ago. Any reason for closing it? |
Contributor
Author
|
No, sorry! But if you want to close and handle all this yourself go ahead! I asked an agent to update your benchmarks against Zod 4.5 but it did the whole migration...😅 |
BREAKING CHANGE: zod-compiler now requires zod >=4.5.0. The compiled output mirrors 4.5 semantics (code-point string lengths, symbol-keyed shapes, tuple issue order, credit-card Luhn validation), so it misvalidates against 4.0-4.4. The peer range moved from ^4.0.0 to ^4.5.0; stay on 1.x for older Zod. Claude-Session: https://claude.ai/code/session_01BAeQcFL8SyrYLNKKzppmUA
|
🎉 This PR is included in version 2.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Zod 4.5 is out now. Spun up a PR to update
zod-compilerwith some of the changes. Feel free to use it as a starting point (or close and do your own thing 👍).