zod icon indicating copy to clipboard operation
zod copied to clipboard

Add `z.fromJSONSchema()`, `z.looseRecord()`,`z.xor()`

Open colinhacks opened this issue 1 week ago • 5 comments

  • Initial version of z.fromJSONSchema
  • Add z.fromJSONSchema

colinhacks avatar Dec 14 '25 02:12 colinhacks

cc @pullfrog

colinhacks avatar Dec 14 '25 02:12 colinhacks

Review complete! I've analyzed the implementation of fromJSONSchema() and looseRecord().

Summary:

  • ✅ All tests pass (84 tests)
  • ✅ Build succeeds
  • ✅ Core functionality works correctly
  • ⚠️ 14 issues identified (see review comments)

Main concerns:

  1. PR title mentions z.xor() but it's not implemented (it's actually z.union([...], { exclusive: true }))
  2. Several unrelated files included (play.ts, zod-locale.ts, zod-string.ts)
  3. Type safety issues with as any casts
  4. Potential bug with overlapping patternProperties
  5. Poor error messages for tuple length validation

The implementation is solid overall, but needs cleanup and bug fixes before merging.

Pullfrog  | Triggered by Pullfrog | Using Claude CodeView workflow runpullfrog.com𝕏

pullfrog[bot] avatar Dec 14 '25 02:12 pullfrog[bot]

cc @coderabbitai review this

colinhacks avatar Dec 14 '25 02:12 colinhacks

@colinhacks: I'll review the changes for you!

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot] avatar Dec 14 '25 02:12 coderabbitai[bot]

[!NOTE]

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This pull request introduces several new features and refinements to Zod. A new fromJSONSchema function enables converting JSON Schema definitions to Zod types with support for references, composite keywords, and constraints. A new looseRecord API allows record validation to pass through non-matching keys unchanged. Union handling gains an exclusive option for stricter disjunction validation. Export paths are reorganized for toJSONSchema and fromJSONSchema to use dedicated modules. Invalid union error types are refactored into a discriminated union distinguishing no-match from multiple-match scenarios. Record definitions now support a mode field controlling key validation behavior. Comprehensive documentation and test suites cover the new functionality.

Pre-merge checks

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description only mentions z.fromJSONSchema and omits z.looseRecord and exclusive union changes, making it incomplete relative to the changeset. Expand the description to include z.looseRecord() and the exclusive union feature (xor/inclusive flag) for clarity.
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the three main features added: fromJSONSchema conversion function, looseRecord variant, and exclusive union (xor) support.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Dec 14 '25 02:12 coderabbitai[bot]

cc @pullfrog review with a focus on the XOR stuff

colinhacks avatar Dec 14 '25 23:12 colinhacks

Review Complete - XOR Implementation Focus

Reviewed the PR with specific attention to the XOR functionality as requested. Here's what I found:

XOR Implementation (z.xor())

  • ✅ Core logic is solid - correctly evaluates all options to detect multiple matches
  • ✅ Good separation of concerns with handleExclusiveUnionResults helper
  • ✅ Proper error handling distinguishing zero matches vs multiple matches via inclusive: false
  • 💡 Suggested adding comments explaining why XOR can't early-return like regular unions

JSON Schema Integration

  • ✅ Correctly maps JSON Schema oneOf to z.xor()
  • ✅ Proper handling of intersection when combined with explicit types
  • ✅ Pattern matching correctly preserves JSON Schema semantics (not implicitly anchored)

Documentation & Tests

  • ✅ Clear examples in api.mdx showing both success and failure cases
  • ✅ Good test coverage including edge cases
  • 💡 Suggested showing error messages in docs to help users debug XOR failures

Overall: The XOR implementation is well-designed and correctly implements exclusive union semantics. The integration with fromJSONSchema properly maps JSON Schema's oneOf behavior. No blocking issues found.

Pullfrog  | Triggered by Pullfrog | Using Claude CodeView workflow runpullfrog.com𝕏

pullfrog[bot] avatar Dec 14 '25 23:12 pullfrog[bot]

The release notes use xor() without an array:

z.xor(
  z.object({ type: "user", name: z.string() }),
  z.object({ type: "admin", role: z.string() })
)

...whicha appears to be an error?

brettz9 avatar Dec 15 '25 08:12 brettz9