fix(zod): escape newlines in $ref description with generateReusableSchemas#3528
Conversation
…hemas
When `generateReusableSchemas: true` and an object property is a $ref with a
multi-line `description` sibling, the description was emitted as
`Name.describe("…raw text…")` via `escape()`, which only escapes quote chars.
Multi-line descriptions produced literal newlines inside a double-quoted string
literal, generating invalid TypeScript (TS1002 unterminated string literal).
Use the same single-quoted, fully JS-escaped form as the primitive description
path (`jsStringEscape`), so `$ref` siblings and primitive fields are escaped
identically.
Fixes orval-labs#3517
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe PR fixes a TypeScript compilation error when ChangesZod $ref description escaping
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR updates how .describe(...) is emitted for $ref schemas with a sibling description, ensuring multiline descriptions are properly JS-escaped (preventing raw newlines from breaking the generated TS).
Changes:
- Switch
$refsiblingdescriptionemission fromescape(...)+ double quotes tojsStringEscape(...)+ single quotes. - Add a regression test covering multiline
$refsibling descriptions and update an existing expectation to match the new quoting.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/zod/src/index.ts | Fixes $ref sibling description string escaping to avoid emitting raw newlines in generated code. |
| packages/zod/src/zod.test.ts | Updates/extends tests to assert correct single-quoted, newline-escaped .describe(...) output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (typeof siblingSchema.description === 'string') { | ||
| functions.push(['describe', `"${escape(siblingSchema.description)}"`]); | ||
| // Use the same single-quoted, fully JS-escaped form as the primitive | ||
| // description path (see `pushDescriptionOrMeta`). `escape` only escapes | ||
| // quote chars, so a multi-line description would emit raw newlines and | ||
| // break the generated string literal (TS1002). | ||
| functions.push([ | ||
| 'describe', | ||
| `'${jsStringEscape(siblingSchema.description)}'`, | ||
| ]); | ||
| } |
Summary
Fixes #3517.
With
output.override.zod.generateReusableSchemas: true, when an object property is a$refto a reusable component and carries a multi-linedescription, orval emittedReferencedSchema.describe("…")using double quotes around the raw, unescaped description. The literal newlines broke the string literal, producing invalid TypeScript:Sibling primitive fields with the same multi-line description were emitted correctly (single-quoted,
\n-escaped) — orval already had a working escaper; the$ref+.describe()path just wasn't using it.Root cause
packages/zod/src/index.ts— the chainable-sibling path for$refs used:escape()only escapes quote characters, not newlines, and the result was wrapped in double quotes. This construct is only produced ingenerateReusableSchemasmode, which is why it didn't surface before.Fix
Use the same single-quoted, fully JS-escaped form as the primitive description path (
pushDescriptionOrMeta):Now
$refsiblings and primitive fields are escaped identically:Tests
$refdescription test to expect the single-quoted form.escapes newlines in a multi-line description sibling on a $ref (#3517), verified to fail before the fix and pass after.@orval/zodsuite passes (204 tests).🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests