feat: allow zod discriminatedUnion generation - #3698
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
✅ Files skipped from review due to trivial changes (5)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughAdds an opt-in ChangesZod discriminated union generation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Config
participant ZodGenerator
participant BranchValidator
participant ZodRenderer
Config->>ZodGenerator: enable generateDiscriminatedUnion
ZodGenerator->>BranchValidator: validate discriminator-bearing branches
BranchValidator-->>ZodGenerator: return eligible or fallback result
ZodGenerator->>ZodRenderer: pass discriminator-aware union marker
ZodRenderer-->>Config: render discriminatedUnion or union
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/zod/src/index.ts`:
- Around line 241-252: Escape discriminator property names before storing them
in the internal marker, using a collision-safe encoding that safely handles the
discriminator marker itself, and decode that payload in
decodeDiscriminatorSeparator. Update the generated TypeScript rendering paths at
the referenced discriminator handling sites to emit the decoded property via
JSON.stringify or equivalent string-literal escaping, including names containing
apostrophes or marker text; keep encode/decode behavior consistent across all
call sites.
- Around line 1475-1494: When flattening allOf schemas, update the helpers that
build mergedProperties to preserve constraints for duplicate property keys
instead of allowing Object.assign to overwrite earlier definitions. Merge
overlapping ZodValidationSchemaDefinition values using the existing
schema-combination approach, or skip flattening when property sets overlap, and
apply the same behavior consistently to both helpers handling
object/strictObject functions.
- Around line 619-631: Update the discriminated-union eligibility logic around
discriminatorProperty and isDiscriminatableMember to collect all discriminator
values from every schema branch, detect duplicates across branches (including
const and enum values), and require the combined values to be unique; otherwise
disable discriminatedUnion generation so the code falls back to zod.union.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b52bbaf5-f239-4081-b445-523c462b56f5
📒 Files selected for processing (11)
docs/content/docs/guides/zod.mdxdocs/content/docs/reference/configuration/output.mdxpackages/angular/src/http-client.test.tspackages/angular/src/http-resource.test.tspackages/core/src/test-utils/context.tspackages/core/src/types.tspackages/mock/src/faker/getters/combine.test.tspackages/orval/src/utils/options.tspackages/solid-start/src/index.test.tspackages/zod/src/index.tspackages/zod/src/zod.test.ts
@orval/angular
@orval/axios
@orval/core
@orval/effect
@orval/fetch
@orval/hono
@orval/mcp
@orval/mock
orval
@orval/query
@orval/solid-start
@orval/swr
@orval/zod
commit: |
5d97b1d to
b136d52
Compare
|
@melloware @Georgegriff tagging you since you were involved a lot in the previous discussions around the topic. |
|
This seems reasonable to me! |
Summary
Adds an opt-in
override.zod.generateDiscriminatedUnionflag that emitsz.discriminatedUnion(key, [...])for aoneOf/anyOfcarrying an OpenAPIdiscriminator, instead of a plainz.union([...]).This reintroduces #1907 (reverted in #2118 due to #2085) but avoids the crash
that forced the revert.
Why the previous attempt was reverted
z.discriminatedUniononly accepts object options. An inheritance branch (allOf) was rendered asz.object().and(...)which zod rejects at construction, crashing the generated module (#2085).Approach
const/enum) discriminator.allOfbranches are flattened into a single object (reusing the existing strict-mode object-merge) so they stay valid optionsz.unionwhenever a branch can't be an object: nested unions, non-object members, non-literal discriminators, or (withgenerateReusableSchemas) a branch that$refs anallOfschema. The generator never emits code that throws at construction.falseSummary by CodeRabbit
New Features
generateDiscriminatedUnionsetting for Zod output.zod.discriminatedUnionfor discriminator-basedoneOf/anyOf, with safe fallback tozod.union.Documentation
override.zoddocs with the new option and clarified that operation/tag-level usage is ignored.Tests