feat(core): add runtimeValidation both strategy for Zod-backed clients - #3650
feat(core): add runtimeValidation both strategy for Zod-backed clients#3650the-ult wants to merge 11 commits into
both strategy for Zod-backed clients#3650Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds object-form runtime validation strategies for Zod-backed clients, normalizes configuration into ChangesRuntime validation strategy extension
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Config
participant Normalizer
participant Generator
participant GeneratedClient
participant Zod
Config->>Normalizer: runtimeValidation configuration
Normalizer-->>Generator: normalized enabled and strategy
Generator->>GeneratedClient: emit response validation code
GeneratedClient->>Zod: parse or safeParse response
Zod-->>GeneratedClient: validated output or ZodError
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ 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
Adds a backward-compatible runtimeValidation strategy option for Zod-backed generated clients, enabling a new both mode that logs validation failures via console.error while still throwing to preserve existing return types and failure semantics. This also centralizes validation snippet generation into a shared core emitter to avoid scattered per-client logic.
Changes:
- Introduces
RuntimeValidation(boolean | { strategy: 'throw' | 'both' }) plus normalization to a canonical{ enabled, strategy }shape. - Adds a shared
emitResponseValidation(...)generator used by Angular (HttpClient,httpResource), Angular-query, and fetch clients. - Adds unit tests for the emitter/normalizer plus new fixtures/snapshots and an Angular sample runtime test for the
bothstrategy.
Reviewed changes
Copilot reviewed 92 out of 92 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/package.json | Adds a dedicated generation script for the new runtime-validation fixtures. |
| tests/configs/runtime-validation.config.ts | New fixtures to snapshot strategy: 'both' output for fetch + Angular clients. |
| tests/api-generation.spec.ts | Includes the new runtime-validation snapshot suite in the test runner. |
| tests/snapshots/runtime-validation/fetch-both/model/cat.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/createPetsBody.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/createPetsHeaders.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/createPetsParams.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/dachshund.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/dog.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/error.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/index.ts | Snapshot barrel export for fetch both fixture models. |
| tests/snapshots/runtime-validation/fetch-both/model/labradoodle.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/listPetsHeaders.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/listPetsParams.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/pet.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/pets.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/model/petWithTag.zod.ts | Snapshot for Zod model output used by fetch both fixture. |
| tests/snapshots/runtime-validation/fetch-both/endpoints.ts | Snapshot showing fetch client both emission (safeParse + console.error + throw). |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/cat.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/createPetsBody.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/createPetsHeaders.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/createPetsParams.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/dachshund.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/dog.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/error.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/index.ts | Snapshot barrel export for Angular httpResource both fixture models. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/labradoodle.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/listPetsHeaders.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/listPetsParams.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/pet.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/pets.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/model/petWithTag.zod.ts | Snapshot for Zod model output used by Angular httpResource both fixture. |
| tests/snapshots/runtime-validation/angular-http-resource-both/endpoints.ts | Snapshot showing Angular httpResource parse: emission for both. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/cat.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/createPetsBody.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/createPetsHeaders.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/createPetsParams.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/dachshund.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/dog.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/error.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/index.ts | Snapshot barrel export for Angular HttpClient both fixture models. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/labradoodle.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/listPetsHeaders.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/listPetsParams.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/pet.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/pets.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/model/petWithTag.zod.ts | Snapshot for Zod model output used by Angular HttpClient both fixture. |
| tests/snapshots/runtime-validation/angular-http-client-both/endpoints.ts | Snapshot showing Angular HttpClient rxjs-map/clone validation emission for both. |
| samples/angular-app/src/app/endpoints-zod-both.spec.ts | Runtime behavior test asserting console.error + thrown ZodError for Angular HttpClient both. |
| samples/angular-app/src/api/endpoints-zod-both/pets/pets.service.ts | Generated sample client demonstrating emitted both validation logic. |
| samples/angular-app/src/api/endpoints-zod-both/pets/pets.msw.ts | Generated MSW mocks for the new sample output. |
| samples/angular-app/src/api/endpoints-zod-both/model/createPetsBody.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/error.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/index.ts | Generated sample Zod model barrel exports. |
| samples/angular-app/src/api/endpoints-zod-both/model/listPetsParams.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/pet.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/pets.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/searchPetsParams.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts | Generated sample Zod model output. |
| samples/angular-app/src/api/endpoints-zod-both/index.msw.ts | Generated sample MSW index export. |
| samples/angular-app/orval.config.ts | Adds a new sample output config using runtimeValidation: { strategy: 'both' }. |
| samples/angular-app/snapshots/api/endpoints-zod-both/pets/pets.service.ts | Snapshot for the generated Angular sample service. |
| samples/angular-app/snapshots/api/endpoints-zod-both/pets/pets.msw.ts | Snapshot for the generated Angular sample MSW mocks. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/createPetsBody.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/error.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/index.ts | Snapshot for the generated Angular sample model exports. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/listPetsParams.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/pet.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/pets.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/searchPetsParams.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts | Snapshot for the generated Angular sample model. |
| samples/angular-app/snapshots/api/endpoints-zod-both/index.msw.ts | Snapshot for the generated Angular sample MSW index. |
| packages/solid-start/src/index.test.ts | Updates expected normalized override shape (runtimeValidation now canonical object). |
| packages/query/src/index.ts | Switches runtimeValidation gate to .enabled for normalized config. |
| packages/query/src/client.ts | Uses shared emitter to generate validation code and supports strategy. |
| packages/orval/src/utils/options.ts | Normalizes per-client + query runtimeValidation to canonical { enabled, strategy }. |
| packages/orval/src/utils/options.test.ts | Updates/extends tests to validate new normalization behavior and spread ordering. |
| packages/mock/src/faker/getters/combine.test.ts | Updates test context overrides for the normalized runtimeValidation shape. |
| packages/fetch/src/index.ts | Routes fetch response validation emission through shared emitter and strategy support. |
| packages/core/src/types.ts | Adds runtimeValidation types (RuntimeValidationStrategy, RuntimeValidation, normalized form) and updates option shapes. |
| packages/core/src/test-utils/context.ts | Updates test context defaults to canonical runtimeValidation object. |
| packages/core/src/generators/runtime-validation.ts | New shared emitter + normalization helper. |
| packages/core/src/generators/runtime-validation.test.ts | Unit tests for emitter output across contexts and normalization rules. |
| packages/core/src/generators/index.ts | Exports the new runtime-validation generator utilities from core. |
| packages/angular/src/utils.test.ts | Updates Angular generator test setup for canonical runtimeValidation object. |
| packages/angular/src/http-resource.ts | Routes httpResource parse emission through shared emitter + .enabled checks. |
| packages/angular/src/http-resource.test.ts | Updates tests for new normalized runtimeValidation shape in Angular httpResource generator. |
| packages/angular/src/http-client.ts | Uses shared emitter for rxjs-map / clone-expression validation snippets and .enabled gating. |
| packages/angular/src/http-client.test.ts | Updates tests for new normalized runtimeValidation shape in Angular HttpClient generator. |
| docs/content/docs/reference/configuration/output.mdx | Documents the new object form and both strategy semantics for supported clients. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/angular/src/http-resource.ts (1)
558-563: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winHonor disabled runtime validation before returning an explicit Zod schema.
Line 560 returns an
isZodSchemaimport before Line 563 checksruntimeValidation.enabled, so{ enabled: false }can still emit aparse:option forhttpResource. Move the disabled guard immediately after the factory check sofalseconsistently disables runtime parsing.Proposed fix
if (factory !== 'httpResource') return undefined; + // Check if runtime validation is disabled + if (!output.override.angular.runtimeValidation.enabled) return undefined; + // Explicit isZodSchema flag on imports (forward-compatible) const zodSchema = response.imports.find((imp) => imp.isZodSchema); if (zodSchema) return zodSchema.name; - // Check if runtime validation is disabled - if (!output.override.angular.runtimeValidation.enabled) return undefined; - // Auto-detect: when schemas.type === 'zod', use the response type as the schema name🤖 Prompt for 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. In `@packages/angular/src/http-resource.ts` around lines 558 - 563, The explicit Zod schema branch in httpResource is being returned before the runtime validation disabled check, so disabled validation can still produce a parse option. Update the logic in the http-resource response mapping so the runtimeValidation.enabled guard is checked immediately after the factory/feature gate and before resolving any isZodSchema import, ensuring { enabled: false } always returns undefined. Use the existing httpResource response handling and the zodSchema lookup as the main symbols to relocate this condition.
🧹 Nitpick comments (2)
packages/orval/src/utils/options.test.ts (1)
189-220: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd an operation/tag query inheritance regression here.
These cases only cover top-level normalization. Please add one where global
override.query.runtimeValidationis disabled/omitted and anoverride.operations.*.queryoroverride.tags.*.queryblock omits its ownruntimeValidation; that would catch the re-normalization bug at Line 1345.🤖 Prompt for 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. In `@packages/orval/src/utils/options.test.ts` around lines 189 - 220, Add a regression test for query inheritance normalization in normalizeOptions, since the current coverage only checks top-level fetch normalization. Extend the options tests to cover an override.query.runtimeValidation set to disabled or omitted, then verify that an override.operations.*.query or override.tags.*.query block without its own runtimeValidation is re-normalized correctly instead of keeping a stale value. Use normalizeOptions, override.query, override.operations, and override.tags in the test to target the re-normalization path and catch the bug around the spread/merge logic.tests/configs/runtime-validation.config.ts (1)
3-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd snapshot coverage for the query generator path.
This fixture set currently covers fetch and the two Angular retrieval modes, but not the query generator path that was also changed for
runtimeValidation: { strategy: 'both' }. Adding a query fixture here (or narrowing the comment) would keep the new snapshot suite aligned with the stated support surface.🤖 Prompt for 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. In `@tests/configs/runtime-validation.config.ts` around lines 3 - 7, The runtimeValidation fixture set currently claims coverage for every client that supports the “both” strategy, but it is missing the query generator path. Update the snapshot coverage in the runtime-validation config by adding a query generator fixture alongside the existing fetch and Angular retrieval fixtures, or adjust the comment in runtimeValidation config to match the actual supported surface; use the runtime-validation fixture definitions and query generator path entry points to locate the change.
🤖 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 `@docs/content/docs/reference/configuration/output.mdx`:
- Around line 1288-1290: The docs text for the Angular query response validation
section still overstates that validation always happens via Schema.parse/parse:
Schema.parse, which is only true for the throw strategy. Update the wording in
the affected configuration docs sections and related references to describe
validation more generally as “validated against the schema,” and distinguish
that { strategy: 'both' } uses the safe-parse/log-then-throw path while true
maps to { strategy: 'throw' }. Use the existing Angular response validation
wording and strategy examples as the anchor points when revising the text.
- Line 2028: The config docs for the supporting clients currently describe the
object form in a way that makes `throw` sound like the default runtime behavior,
which conflicts with the documented `false` default. Update the wording in the
relevant section to say `throw` is the default strategy only when validation is
enabled, and keep the explanation of `both` as the variant that also logs the
raw `ZodError` before re-throwing. Refer to the supporting-clients config
wording so it’s clear the default boolean remains `false`.
In `@packages/orval/src/utils/options.ts`:
- Around line 1345-1349: The runtimeValidation fallback in the query options
merge is re-normalizing an already normalized inherited value, which can change
the default inherited setting unexpectedly. Update the logic around the
runtimeValidation assignment in options.ts so that when
queryOptions.runtimeValidation is absent it uses globalOptions.runtimeValidation
as-is, and only calls normalizeRuntimeValidation for raw user-provided query
values; use the existing NormalizedQueryOptions flow and the
runtimeValidation-related helpers to keep inherited query/tag/operation
overrides from enabling validation unintentionally.
---
Outside diff comments:
In `@packages/angular/src/http-resource.ts`:
- Around line 558-563: The explicit Zod schema branch in httpResource is being
returned before the runtime validation disabled check, so disabled validation
can still produce a parse option. Update the logic in the http-resource response
mapping so the runtimeValidation.enabled guard is checked immediately after the
factory/feature gate and before resolving any isZodSchema import, ensuring {
enabled: false } always returns undefined. Use the existing httpResource
response handling and the zodSchema lookup as the main symbols to relocate this
condition.
---
Nitpick comments:
In `@packages/orval/src/utils/options.test.ts`:
- Around line 189-220: Add a regression test for query inheritance normalization
in normalizeOptions, since the current coverage only checks top-level fetch
normalization. Extend the options tests to cover an
override.query.runtimeValidation set to disabled or omitted, then verify that an
override.operations.*.query or override.tags.*.query block without its own
runtimeValidation is re-normalized correctly instead of keeping a stale value.
Use normalizeOptions, override.query, override.operations, and override.tags in
the test to target the re-normalization path and catch the bug around the
spread/merge logic.
In `@tests/configs/runtime-validation.config.ts`:
- Around line 3-7: The runtimeValidation fixture set currently claims coverage
for every client that supports the “both” strategy, but it is missing the query
generator path. Update the snapshot coverage in the runtime-validation config by
adding a query generator fixture alongside the existing fetch and Angular
retrieval fixtures, or adjust the comment in runtimeValidation config to match
the actual supported surface; use the runtime-validation fixture definitions and
query generator path entry points to locate the change.
🪄 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: a31657da-ec15-4979-bdfd-396621dcfeec
⛔ Files ignored due to path filters (57)
samples/angular-app/__snapshots__/api/endpoints-zod-both/index.msw.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/createPetsBody.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/error.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/index.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/listPetsParams.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/patchPetByIdBody.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pet.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pets.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/searchPetsParams.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/updatePetByIdBody.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.msw.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.service.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/endpoints.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/cat.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/createPetsBody.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/createPetsHeaders.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/createPetsParams.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/dachshund.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/dog.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/error.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/index.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/labradoodle.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/listPetsHeaders.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/listPetsParams.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/pet.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/petWithTag.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-client-both/model/pets.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/endpoints.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/cat.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/createPetsBody.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/createPetsHeaders.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/createPetsParams.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/dachshund.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/dog.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/error.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/index.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/labradoodle.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/listPetsHeaders.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/listPetsParams.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/pet.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/petWithTag.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/angular-http-resource-both/model/pets.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/endpoints.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/cat.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/createPetsBody.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/createPetsHeaders.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/createPetsParams.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/dachshund.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/dog.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/error.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/index.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/labradoodle.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/listPetsHeaders.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/listPetsParams.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/pet.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/petWithTag.zod.tsis excluded by!**/__snapshots__/**tests/__snapshots__/runtime-validation/fetch-both/model/pets.zod.tsis excluded by!**/__snapshots__/**
📒 Files selected for processing (35)
docs/content/docs/reference/configuration/output.mdxpackages/angular/src/http-client.test.tspackages/angular/src/http-client.tspackages/angular/src/http-resource.test.tspackages/angular/src/http-resource.tspackages/angular/src/utils.test.tspackages/core/src/generators/index.tspackages/core/src/generators/runtime-validation.test.tspackages/core/src/generators/runtime-validation.tspackages/core/src/test-utils/context.tspackages/core/src/types.tspackages/fetch/src/index.tspackages/mock/src/faker/getters/combine.test.tspackages/orval/src/utils/options.test.tspackages/orval/src/utils/options.tspackages/query/src/client.tspackages/query/src/index.tspackages/solid-start/src/index.test.tssamples/angular-app/orval.config.tssamples/angular-app/src/api/endpoints-zod-both/index.msw.tssamples/angular-app/src/api/endpoints-zod-both/model/createPetsBody.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/error.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/index.tssamples/angular-app/src/api/endpoints-zod-both/model/listPetsParams.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/patchPetByIdBody.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/pet.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/pets.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/searchPetsParams.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/updatePetByIdBody.zod.tssamples/angular-app/src/api/endpoints-zod-both/pets/pets.msw.tssamples/angular-app/src/api/endpoints-zod-both/pets/pets.service.tssamples/angular-app/src/app/endpoints-zod-both.spec.tstests/api-generation.spec.tstests/configs/runtime-validation.config.tstests/package.json
8827535 to
71714ee
Compare
|
Correctness (CodeRabbit, major) — the per-operation/per-tag Coverage (Copilot) — added an Docs (CodeRabbit, minor) — clarified that runtime validation is disabled by default and that Snapshot version — the earlier CI failure was a version skew: the branch was based on 8.18.0 and master had bumped to 8.19.0 (#3649). Rebased onto master and regenerated all added fixtures/snapshots at v8.19.0. |
a6afa1d to
609c290
Compare
|
I think there is another open PR for Zod And Fetch which has gotten a lot of feedback from @soartec-lab and @zeriong |
|
Thanks @melloware — I think you're remembering #3226 (pass zod schema to custom fetch response, reviewed by @soartec-lab) and #3308 (@zeriong's fetch explode fix, also @soartec-lab). I went through both:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 116 out of 116 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
docs/content/docs/reference/configuration/output.mdx:1697
- The docs claim runtime validation is skipped for
observe: 'events' | 'response', but the generated Angular HttpClient code validates those modes too (it clones theAngularHttpResponseand validatesevent.body/response.body). This section should be updated to avoid misleading users about when validation runs.
Validation is skipped for primitive types, non-JSON responses,
`observe: 'events' | 'response'`, and custom mutator paths that bypass the
generated validation flow.
67ce611 to
7bebf1f
Compare
@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: |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 116 out of 116 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
docs/content/docs/reference/configuration/output.mdx:1730
- The docs say runtime validation is skipped for
observe: 'events' | 'response', but the Angular HttpClient generator validates those modes too (it clones theAngularHttpResponseand validatesevent.body/response.body). This section should not listobserveas a skip case, otherwise readers will think validation is disabled when it is actually applied.
Validation is skipped for primitive types, non-JSON responses,
`observe: 'events' | 'response'`, and custom mutator paths that bypass the
generated validation flow.
…uard Address Copilot review comments on orval-labs#3650: - Escape backslashes and single quotes in `operationName` before interpolating it into the generated `console.error(...)` string literal. The default is a sanitized camelCase identifier, but `override.operationName` can return arbitrary strings; unescaped quotes/backslashes produced syntactically invalid generated output. Byte-identical output for sanitized names, so existing snapshots are unchanged. Adds a regression test. - Correct the runtime-validation docs matrix and prose: Angular `HttpClient` validates `observe: 'events'/'response'` responses by cloning the response and validating its body — previously (incorrectly) documented as skipped. - Regenerate runtime-validation fixtures at v8.20.0 after merging master. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/content/docs/guides/angular.mdx (1)
592-607: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win"How It Works" code example doesn't match the
bothstrategy from the Setup config above.The config at line 575 sets
runtimeValidation: { strategy: 'both' }, but the simplified generated code at lines 594-606 shows thethrowstrategy (Pet.parse(data)andparse: Pet.parse). A reader who follows the Setup section would expect to seesafeParse+console.error+ re-throw in the generated output.Consider either showing the
bothstrategy output to match the config, or adding a brief note that the simplified example illustrates thethrowstrategy for clarity.🤖 Prompt for 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. In `@docs/content/docs/guides/angular.mdx` around lines 592 - 607, Update the Angular guide’s “How It Works” example to align with the Setup configuration’s runtimeValidation strategy of “both”: show safeParse, console.error, and re-throw behavior in both generated paths, including the Observable mapping and httpResource parse callback; alternatively, explicitly note that the simplified snippet demonstrates the throw strategy instead.
🤖 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.
Outside diff comments:
In `@docs/content/docs/guides/angular.mdx`:
- Around line 592-607: Update the Angular guide’s “How It Works” example to
align with the Setup configuration’s runtimeValidation strategy of “both”: show
safeParse, console.error, and re-throw behavior in both generated paths,
including the Observable mapping and httpResource parse callback; alternatively,
explicitly note that the simplified snippet demonstrates the throw strategy
instead.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: bbf62617-1cd8-444c-946a-d9087c91fa2a
⛔ Files ignored due to path filters (13)
samples/angular-app/__snapshots__/api/endpoints-zod-both/index.msw.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/createPetsBody.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/error.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/index.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/listPetsParams.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/patchPetByIdBody.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pet.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pets.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/searchPetsParams.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/model/updatePetByIdBody.zod.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.msw.tsis excluded by!**/__snapshots__/**samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.service.tsis excluded by!**/__snapshots__/**samples/angular-query/__snapshots__/api/endpoints-zod/pets/pets.tsis excluded by!**/__snapshots__/**
📒 Files selected for processing (37)
docs/content/docs/guides/angular-query.mdxdocs/content/docs/guides/angular.mdxdocs/content/docs/reference/configuration/output.mdxdocs/content/docs/versions/v8.mdxdocs/content/docs/zh/reference/configuration/output.mdxdocs/src/routeTree.gen.tspackages/angular/src/http-client.test.tspackages/angular/src/http-client.tspackages/angular/src/http-resource.test.tspackages/angular/src/http-resource.tspackages/angular/src/utils.test.tspackages/core/src/generators/index.tspackages/core/src/generators/runtime-validation.test.tspackages/core/src/generators/runtime-validation.tspackages/core/src/test-utils/context.tspackages/core/src/types.tspackages/fetch/src/index.tspackages/mock/src/faker/getters/combine.test.tspackages/orval/src/utils/options.test.tspackages/orval/src/utils/options.tspackages/query/src/client.tspackages/query/src/index.tspackages/solid-start/src/index.test.tssamples/angular-app/orval.config.tssamples/angular-app/src/api/endpoints-zod-both/index.msw.tssamples/angular-app/src/api/endpoints-zod-both/model/createPetsBody.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/error.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/index.tssamples/angular-app/src/api/endpoints-zod-both/model/listPetsParams.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/patchPetByIdBody.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/pet.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/pets.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/searchPetsParams.zod.tssamples/angular-app/src/api/endpoints-zod-both/model/updatePetByIdBody.zod.tssamples/angular-app/src/api/endpoints-zod-both/pets/pets.msw.tssamples/angular-app/src/api/endpoints-zod-both/pets/pets.service.tssamples/angular-app/src/app/endpoints-zod-both.spec.ts
✅ Files skipped from review due to trivial changes (15)
- samples/angular-app/src/api/endpoints-zod-both/index.msw.ts
- docs/content/docs/zh/reference/configuration/output.mdx
- samples/angular-app/src/api/endpoints-zod-both/model/listPetsParams.zod.ts
- samples/angular-app/src/api/endpoints-zod-both/model/searchPetsParams.zod.ts
- samples/angular-app/src/api/endpoints-zod-both/model/index.ts
- samples/angular-app/src/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts
- docs/content/docs/versions/v8.mdx
- samples/angular-app/src/api/endpoints-zod-both/model/pet.zod.ts
- samples/angular-app/src/api/endpoints-zod-both/model/createPetsBody.zod.ts
- samples/angular-app/src/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts
- docs/src/routeTree.gen.ts
- samples/angular-app/src/api/endpoints-zod-both/model/pets.zod.ts
- docs/content/docs/reference/configuration/output.mdx
- samples/angular-app/src/api/endpoints-zod-both/pets/pets.service.ts
- samples/angular-app/src/api/endpoints-zod-both/pets/pets.msw.ts
🚧 Files skipped from review as they are similar to previous changes (20)
- packages/mock/src/faker/getters/combine.test.ts
- packages/angular/src/utils.test.ts
- packages/core/src/generators/index.ts
- samples/angular-app/src/api/endpoints-zod-both/model/error.zod.ts
- packages/core/src/test-utils/context.ts
- packages/solid-start/src/index.test.ts
- packages/core/src/generators/runtime-validation.test.ts
- packages/query/src/index.ts
- samples/angular-app/src/app/endpoints-zod-both.spec.ts
- samples/angular-app/orval.config.ts
- packages/query/src/client.ts
- packages/angular/src/http-resource.test.ts
- packages/orval/src/utils/options.test.ts
- packages/orval/src/utils/options.ts
- packages/core/src/generators/runtime-validation.ts
- packages/core/src/types.ts
- packages/angular/src/http-resource.ts
- packages/angular/src/http-client.test.ts
- packages/angular/src/http-client.ts
- packages/fetch/src/index.ts
…uard Address Copilot review comments on orval-labs#3650: - Escape backslashes and single quotes in `operationName` before interpolating it into the generated `console.error(...)` string literal. The default is a sanitized camelCase identifier, but `override.operationName` can return arbitrary strings; unescaped quotes/backslashes produced syntactically invalid generated output. Byte-identical output for sanitized names, so existing snapshots are unchanged. Adds a regression test. - Correct the runtime-validation docs matrix and prose: Angular `HttpClient` validates `observe: 'events'/'response'` responses by cloning the response and validating its body — previously (incorrectly) documented as skipped. - Regenerate runtime-validation fixtures at v8.20.0 after merging master. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
81aceb7 to
d168a27
Compare
Introduce a per-client `runtimeValidation: boolean | { strategy: 'throw' | 'both' }`
option for Zod-backed clients. `throw` (== `true`) is byte-identical to today's
`Schema.parse(data)`; `both` runs `safeParse`, `console.error`s the raw ZodError
for production visibility, then re-throws — so the failure still surfaces through
each client's native error channel and the return type stays the Zod `Output`
(no widening).
Validation was previously emitted inline at ~10 scattered sites across four
packages. Those are now centralized into a single deep emitter,
`emitResponseValidation`, with four emit contexts (rxjs-map, clone-expression,
fetch-assign, parse-fn). Config is normalized once at the orval boundary into a
canonical `{ enabled, strategy }` object via `normalizeRuntimeValidation`.
The non-throwing `log` variant and `fallback`/`mode`/global keys are intentionally
out of scope.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a dedicated `runtime-validation` generation config exercising
`{ strategy: 'both' }` on the fetch, angular HttpClient, and angular httpResource
clients (the rxjs-map, clone-expression, fetch-assign and parse-fn emit contexts),
plus its generated snapshots. All existing throw/boolean snapshots regenerate
byte-identically.
Add angular-app sample runtime tests that feed an invalid payload to a
`both`-configured HttpClient service and assert the raw ZodError is logged via
console.error AND surfaces through the RxJS error channel, while a valid payload
passes through (with Zod output defaults applied) without logging.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update the angular, angular-query and fetch `runtimeValidation` reference entries
to document the object form `{ strategy: 'throw' | 'both' }` and the
log-then-throw behaviour of `both`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per-operation and per-tag `query` overrides inherit the already-normalized global
query options. The query merge fed that inherited `{ enabled, strategy }` object
back through `normalizeRuntimeValidation`, which treated any truthy object as
enabled — silently flipping a disabled global (`runtimeValidation: false`) to
`enabled: true` for any operation/tag with a `query` override block.
Make `normalizeRuntimeValidation` idempotent: an already-normalized value is
returned unchanged. Add a regression test for the per-operation inheritance path
and an idempotency unit test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebased onto the v8.19.0 release bump (orval-labs#3649); regenerate the added runtime-validation fixtures and sample so their orval version headers match the workspace version. Header-only changes — no behavioural difference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Make the per-operation/per-tag query merge explicit: preserve the already- normalized inherited `runtimeValidation` instead of round-tripping it through `normalizeRuntimeValidation` (clearer intent alongside the idempotency guard). - Add an `angular-query` `both` fixture + snapshot so the angular-query rxjs-map `both` emission is exercised end-to-end (all four supporting clients now covered). - Clarify docs: runtime validation is disabled by default; `Schema.parse()` describes the `throw` strategy, not the universal implementation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch the angular-query sample runtimeValidation config to { strategy: 'both' } and
assert the invalid-response path both logs the raw ZodError and throws.
Clarify throw vs both semantics in Angular, Angular Query, and configuration
reference docs so examples and behavior notes match generated output.
Refs orval-labs#3110
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The angular-query `endpoints-zod` target generates the `both` runtime-validation strategy (safeParse + console.error + throw), but its stored snapshot still held the old `Schema.parse()` output, failing `pr-checks` on ubuntu and windows. Sync the snapshot to the generated source. Also reword the Angular HttpClient/httpResource docs bullets so `Schema.parse()` is no longer presented as the universal implementation (CodeRabbit), clarifying that `throw` parses directly while `both` uses a safe-parse wrapper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uard Address Copilot review comments on orval-labs#3650: - Escape backslashes and single quotes in `operationName` before interpolating it into the generated `console.error(...)` string literal. The default is a sanitized camelCase identifier, but `override.operationName` can return arbitrary strings; unescaped quotes/backslashes produced syntactically invalid generated output. Byte-identical output for sanitized names, so existing snapshots are unchanged. Adds a regression test. - Correct the runtime-validation docs matrix and prose: Angular `HttpClient` validates `observe: 'events'/'response'` responses by cloning the response and validating its body — previously (incorrectly) documented as skipped. - Regenerate runtime-validation fixtures at v8.20.0 after merging master. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…v8.20.0 The merge of master bumped orval to v8.20.0, but the angular-app `endpoints-zod-both` sample outputs and their snapshots were still stamped v8.19.0, failing both `check-snapshot-versions` and the `pr-checks` snapshot verification. Regenerated via `update-samples` + `test:snapshots:update`; only the `Generated by orval vX.Y.Z` header changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Master picked up ~65 commits since this branch was cut, including a typedoc bump (HTML -> Markdown docs output), the orval-labs#3712 fix for preserveRequiredNullables/filterParams, and other generator-fixture drift unrelated to runtimeValidation. Regenerated all snapshots against current master to match.
d168a27 to
5f81f4b
Compare
Closes #3110.
What
Adds a per-client
runtimeValidationstrategy option for Zod-backed clients (angularHttpClient, angularhttpResource,angular-query,fetch):throw(default,== true)Schema.parse(data)— identical to todayOutputbothsafeParse→console.error('[orval] <op> response validation failed', error)→ throwOutputtrue/falsekeep their exact current meaning, so existing configs are untouched. Becausebothstill throws, the generated return type stays the ZodOutputtype — no type widening, no soundness change. The rawZodErroris passed toconsole.error(noprettifyError/flatten), so it's Zod 3/4 agnostic.How
Strategy support needs the same
safeParse → log → throwbranch at every place validation is emitted — today that's ~10 inline.parse()sites across four packages. Rather than duplicate the strategy branch 10× (the thing that would actually rot), the branching logic lives once in a single emitter; the call sites just ask for the snippet they need. This is dedup of new behaviour, not relocation of existing code.packages/core/src/generators/runtime-validation.tsemitResponseValidation({ schemaRef, operationName, strategy, context })— one function, four emit contexts:rxjs-map,clone-expression,fetch-assign,parse-fn. Expression contexts IIFE-wrap thebothbody;parse-fnemits a bareSchema.parsereference forthrowand an arrow function forboth.schemaRef-based (never hardcodes.parse), leaving the door open to Standard Schema (~standard) for Valibot/ArkType later.normalizeRuntimeValidation()maps the user surface to a canonical{ enabled, strategy }object, normalized once at the orval boundary..enabled.The non-throwing
logvariant andfallback/mode/global keys are intentionally out of scope (additive, non-breaking to add later if demand appears — see #3110 for the rationale).Scope of the diff
The line count is large but almost entirely generated:
runtime-validation.ts+ its unit test, the four generator call-sites,types.ts, the options normalizer, and the docs.tests/__snapshots__/**andtests/configsfixtures. The existingthrow/boolean snapshots regenerate byte-identical (the regression net below); the only net-new generated files are thebothfixtures.Tests & verification
throw,both} exact-string assertions, plusnormalizeRuntimeValidationcases. The interface is the test surface.throw/boolean snapshots regenerate with zero diff (proves the migration changes nothing for current users).bothfixtures —tests/configs/runtime-validation.config.tscovers fetch + angular HttpClient + angular httpResource; snapshotted and typechecked alongside all other generated clients.samples/angular-appfeeds an invalid payload to aboth-configured client and asserts the rawZodErroris logged viaconsole.errorand surfaces through the RxJS error channel; a valid payload passes through (with Zod output defaults applied) without logging.ng buildall pass locally.Docs
Updated the angular / angular-query / fetch
runtimeValidationreference entries to document the object form andbothsemantics.Related issues & PRs
throw/log/both) #3110 — the design discussion (per-client only, "log then throw",console.errorover build-timeverbose, deferringlog) lives there.index.zodimport bug — separate).packages/fetch/src/index.ts: feat: pass zod schema to custom fetch response implementation #3226 (pass zod schema to custom fetch response — closest in spirit), fix(fetch): respect OpenAPI default explode: true for array query parameters (#3231) #3308 (explode default), fix: implement style:deepObject query parameter serialization #3193 (deepObject serialization).packages/core/src/types.ts: feat: add throwOnError option to generate function #3362 (throwOnErroroption — adjacent error-handling surface), feat: pass zod schema to custom fetch response implementation #3226.Backward compatibility
Fully backward compatible.
runtimeValidation: true/falseare unchanged;{ strategy: 'throw' }is the canonical form oftrue.bothis purely additive.🤖 Generated with Claude Code
Summary by CodeRabbit
{ enabled: boolean, strategy: 'throw' | 'both' }(legacytruemaps to{ strategy: 'throw' }).{ strategy: 'both' }behavior.enabled: true, and{ strategy: 'both' }logs validation errors before proceeding with the normal failure path.