Skip to content

feat(core): add runtimeValidation both strategy for Zod-backed clients - #3650

Open
the-ult wants to merge 11 commits into
orval-labs:masterfrom
the-ult:feat/runtime-validation-strategy-both
Open

feat(core): add runtimeValidation both strategy for Zod-backed clients#3650
the-ult wants to merge 11 commits into
orval-labs:masterfrom
the-ult:feat/runtime-validation-strategy-both

Conversation

@the-ult

@the-ult the-ult commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Closes #3110.

What

Adds a per-client runtimeValidation strategy option for Zod-backed clients (angular HttpClient, angular httpResource, angular-query, fetch):

type RuntimeValidation = boolean | { strategy: 'throw' | 'both' };
strategy generated behaviour return type
throw (default, == true) Schema.parse(data)identical to today Output
both safeParseconsole.error('[orval] <op> response validation failed', error)throw Output

true/false keep their exact current meaning, so existing configs are untouched. Because both still throws, the generated return type stays the Zod Output type — no type widening, no soundness change. The raw ZodError is passed to console.error (no prettifyError/flatten), so it's Zod 3/4 agnostic.

How

Strategy support needs the same safeParse → log → throw branch 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.

  • New packages/core/src/generators/runtime-validation.ts
    • emitResponseValidation({ schemaRef, operationName, strategy, context }) — one function, four emit contexts: rxjs-map, clone-expression, fetch-assign, parse-fn. Expression contexts IIFE-wrap the both body; parse-fn emits a bare Schema.parse reference for throw and an arrow function for both. 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.
  • All four client generators route through the emitter; the ~10 boolean gates became .enabled.

The non-throwing log variant and fallback/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:

  • Hand-written surface is small: runtime-validation.ts + its unit test, the four generator call-sites, types.ts, the options normalizer, and the docs.
  • Everything else is regenerated tests/__snapshots__/** and tests/configs fixtures. The existing throw/boolean snapshots regenerate byte-identical (the regression net below); the only net-new generated files are the both fixtures.

Tests & verification

  • Emitter unit tests — 4 contexts × {throw, both} exact-string assertions, plus normalizeRuntimeValidation cases. The interface is the test surface.
  • Byte-identical regression net — all existing throw/boolean snapshots regenerate with zero diff (proves the migration changes nothing for current users).
  • New both fixturestests/configs/runtime-validation.config.ts covers fetch + angular HttpClient + angular httpResource; snapshotted and typechecked alongside all other generated clients.
  • Sample runtime testssamples/angular-app feeds an invalid payload to a both-configured client and asserts the raw ZodError is logged via console.error and surfaces through the RxJS error channel; a valid payload passes through (with Zod output defaults applied) without logging.
  • Full package unit suite, lint, format, typecheck, and ng build all pass locally.

Docs

Updated the angular / angular-query / fetch runtimeValidation reference entries to document the object form and both semantics.

Related issues & PRs

Backward compatibility

Fully backward compatible. runtimeValidation: true/false are unchanged; { strategy: 'throw' } is the canonical form of true. both is purely additive.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Runtime response validation now accepts an object configuration: { enabled: boolean, strategy: 'throw' | 'both' } (legacy true maps to { strategy: 'throw' }).
  • Documentation
    • Updated runtimeValidation guides and the runtime-validation support matrix for Angular query, Angular output, and fetch, including { strategy: 'both' } behavior.
  • Bug Fixes
    • Validation enablement is now consistently applied only when enabled: true, and { strategy: 'both' } logs validation errors before proceeding with the normal failure path.
  • Tests
    • Expanded generator/unit tests and fixtures to cover both strategies and affected validation contexts.

Copilot AI review requested due to automatic review settings June 24, 2026 17:36
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds object-form runtime validation strategies for Zod-backed clients, normalizes configuration into { enabled, strategy }, routes generators through shared validation emitters, and updates documentation, fixtures, sample applications, and tests.

Changes

Runtime validation strategy extension

Layer / File(s) Summary
Core types and validation emitter
packages/core/src/types.ts, packages/core/src/generators/*
Defines runtime validation types, normalization, and shared strategy-specific validation code generation with unit coverage.
Option normalization and client generators
packages/orval/src/utils/options.ts, packages/fetch/src/*, packages/query/src/*, packages/angular/src/http-client.ts
Normalizes runtime validation configuration and applies emitted validation code to fetch, Angular Query, and Angular HttpClient generation.
Angular httpResource validation
packages/angular/src/http-resource.ts, packages/angular/src/http-resource.test.ts, packages/angular/src/utils.test.ts
Uses shared validation emission for resource parse functions and updates structured runtime validation fixtures.
Fixtures and sample coverage
tests/configs/runtime-validation.config.ts, samples/angular-app/src/api/endpoints-zod-both/*, samples/angular-app/src/app/endpoints-zod-both.spec.ts
Adds multi-client runtime-validation generation fixtures and an Angular Petstore sample covering logging and throwing behavior.
Documentation
docs/content/docs/guides/*, docs/content/docs/reference/configuration/output.mdx, docs/content/docs/versions/v8.mdx, docs/content/docs/zh/reference/configuration/output.mdx
Documents boolean shorthand, object strategies, error behavior, and client-specific validation applicability.
Generated route output
docs/src/routeTree.gen.ts
Updates generated route formatting without changing route mappings.

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
Loading

Possibly related PRs

Suggested labels: enhancement, angular, fetch, tanstack-query, documentation

Suggested reviewers: melloware, snebjorn

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes are on target, but docs/src/routeTree.gen.ts is a generated router formatting update unrelated to runtimeValidation. Remove the routeTree.gen.ts formatting-only change or split it into a separate PR unless it is required by this feature.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: adding the both runtimeValidation strategy for Zod clients.
Linked Issues check ✅ Passed The PR implements the requested boolean/object strategy, both-mode logging, shared emitter, client integrations, tests, and docs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 both strategy.

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.

Comment thread tests/configs/runtime-validation.config.ts
Comment thread packages/query/src/client.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Honor disabled runtime validation before returning an explicit Zod schema.

Line 560 returns an isZodSchema import before Line 563 checks runtimeValidation.enabled, so { enabled: false } can still emit a parse: option for httpResource. Move the disabled guard immediately after the factory check so false consistently 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 win

Add an operation/tag query inheritance regression here.

These cases only cover top-level normalization. Please add one where global override.query.runtimeValidation is disabled/omitted and an override.operations.*.query or override.tags.*.query block omits its own runtimeValidation; 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 win

Add 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

📥 Commits

Reviewing files that changed from the base of the PR and between 46e9a49 and 7094c42.

⛔ Files ignored due to path filters (57)
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/index.msw.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/createPetsBody.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/error.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/index.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/listPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pet.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pets.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/searchPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.msw.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.service.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/endpoints.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/cat.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/createPetsBody.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/createPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/createPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/dachshund.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/dog.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/error.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/labradoodle.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/listPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/listPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/pet.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/petWithTag.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-client-both/model/pets.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/endpoints.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/cat.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/createPetsBody.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/createPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/createPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/dachshund.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/dog.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/error.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/labradoodle.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/listPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/listPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/pet.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/petWithTag.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/angular-http-resource-both/model/pets.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/endpoints.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/cat.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/createPetsBody.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/createPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/createPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/dachshund.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/dog.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/error.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/labradoodle.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/listPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/listPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/pet.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/petWithTag.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/runtime-validation/fetch-both/model/pets.zod.ts is excluded by !**/__snapshots__/**
📒 Files selected for processing (35)
  • docs/content/docs/reference/configuration/output.mdx
  • packages/angular/src/http-client.test.ts
  • packages/angular/src/http-client.ts
  • packages/angular/src/http-resource.test.ts
  • packages/angular/src/http-resource.ts
  • packages/angular/src/utils.test.ts
  • packages/core/src/generators/index.ts
  • packages/core/src/generators/runtime-validation.test.ts
  • packages/core/src/generators/runtime-validation.ts
  • packages/core/src/test-utils/context.ts
  • packages/core/src/types.ts
  • packages/fetch/src/index.ts
  • packages/mock/src/faker/getters/combine.test.ts
  • packages/orval/src/utils/options.test.ts
  • packages/orval/src/utils/options.ts
  • packages/query/src/client.ts
  • packages/query/src/index.ts
  • packages/solid-start/src/index.test.ts
  • samples/angular-app/orval.config.ts
  • samples/angular-app/src/api/endpoints-zod-both/index.msw.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/createPetsBody.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/error.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/index.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/listPetsParams.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/pet.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/pets.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/searchPetsParams.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/pets/pets.msw.ts
  • samples/angular-app/src/api/endpoints-zod-both/pets/pets.service.ts
  • samples/angular-app/src/app/endpoints-zod-both.spec.ts
  • tests/api-generation.spec.ts
  • tests/configs/runtime-validation.config.ts
  • tests/package.json

Comment thread docs/content/docs/reference/configuration/output.mdx Outdated
Comment thread docs/content/docs/reference/configuration/output.mdx Outdated
Comment thread packages/orval/src/utils/options.ts Outdated
@the-ult
the-ult force-pushed the feat/runtime-validation-strategy-both branch from 8827535 to 71714ee Compare June 24, 2026 17:49
@the-ult

the-ult commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Correctness (CodeRabbit, major) — the per-operation/per-tag query merge no longer round-trips the already-normalized inherited runtimeValidation through normalizeRuntimeValidation. It now preserves the inherited normalized value and only normalizes a raw per-operation override. Belt-and-suspenders: normalizeRuntimeValidation is also now idempotent. Added a regression test (options.test.ts) for an operation query override that omits runtimeValidation while the global is disabled.

Coverage (Copilot) — added an angular-query both fixture + snapshot (tests/configs/runtime-validation.config.tsangular-query-both), so all four supporting clients (fetch, angular HttpClient, angular httpResource, angular-query) now exercise the both path end-to-end. The config comment is now accurate.

Docs (CodeRabbit, minor) — clarified that runtime validation is disabled by default and that Schema.parse() describes the throw strategy rather than the universal implementation.

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.

@the-ult
the-ult force-pushed the feat/runtime-validation-strategy-both branch from a6afa1d to 609c290 Compare June 24, 2026 17:59
@the-ult
the-ult marked this pull request as draft June 24, 2026 18:04
@the-ult
the-ult requested a review from Copilot June 24, 2026 18:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 107 out of 107 changed files in this pull request and generated no new comments.

@melloware

Copy link
Copy Markdown
Collaborator

I think there is another open PR for Zod And Fetch which has gotten a lot of feedback from @soartec-lab and @zeriong

@melloware melloware added the zod Zod schema client related issue label Jun 25, 2026
@the-ult

the-ult commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

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:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 the AngularHttpResponse and validates event.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.

Comment thread docs/content/docs/reference/configuration/output.mdx Outdated
@melloware
melloware force-pushed the feat/runtime-validation-strategy-both branch from 67ce611 to 7bebf1f Compare June 30, 2026 19:41
@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

@orval/angular

bun add https://pkg.pr.new/@orval/angular@5f81f4b

@orval/axios

bun add https://pkg.pr.new/@orval/axios@5f81f4b

@orval/core

bun add https://pkg.pr.new/@orval/core@5f81f4b

@orval/effect

bun add https://pkg.pr.new/@orval/effect@5f81f4b

@orval/fetch

bun add https://pkg.pr.new/@orval/fetch@5f81f4b

@orval/hono

bun add https://pkg.pr.new/@orval/hono@5f81f4b

@orval/mcp

bun add https://pkg.pr.new/@orval/mcp@5f81f4b

@orval/mock

bun add https://pkg.pr.new/@orval/mock@5f81f4b

orval

bun add https://pkg.pr.new/orval@5f81f4b

@orval/query

bun add https://pkg.pr.new/@orval/query@5f81f4b

@orval/solid-start

bun add https://pkg.pr.new/@orval/solid-start@5f81f4b

@orval/swr

bun add https://pkg.pr.new/@orval/swr@5f81f4b

@orval/zod

bun add https://pkg.pr.new/@orval/zod@5f81f4b

commit: 5f81f4b

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 the AngularHttpResponse and validates event.body / response.body). This section should not list observe as 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.

Comment thread packages/core/src/generators/runtime-validation.ts Outdated
the-ult added a commit to the-ult/orval that referenced this pull request Jul 10, 2026
…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>
@the-ult
the-ult marked this pull request as ready for review July 10, 2026 20:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 both strategy from the Setup config above.

The config at line 575 sets runtimeValidation: { strategy: 'both' }, but the simplified generated code at lines 594-606 shows the throw strategy (Pet.parse(data) and parse: Pet.parse). A reader who follows the Setup section would expect to see safeParse + console.error + re-throw in the generated output.

Consider either showing the both strategy output to match the config, or adding a brief note that the simplified example illustrates the throw strategy 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

📥 Commits

Reviewing files that changed from the base of the PR and between 609c290 and 81aceb7.

⛔ Files ignored due to path filters (13)
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/index.msw.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/createPetsBody.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/error.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/index.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/listPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pet.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/pets.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/searchPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.msw.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/endpoints-zod-both/pets/pets.service.ts is excluded by !**/__snapshots__/**
  • samples/angular-query/__snapshots__/api/endpoints-zod/pets/pets.ts is excluded by !**/__snapshots__/**
📒 Files selected for processing (37)
  • docs/content/docs/guides/angular-query.mdx
  • docs/content/docs/guides/angular.mdx
  • docs/content/docs/reference/configuration/output.mdx
  • docs/content/docs/versions/v8.mdx
  • docs/content/docs/zh/reference/configuration/output.mdx
  • docs/src/routeTree.gen.ts
  • packages/angular/src/http-client.test.ts
  • packages/angular/src/http-client.ts
  • packages/angular/src/http-resource.test.ts
  • packages/angular/src/http-resource.ts
  • packages/angular/src/utils.test.ts
  • packages/core/src/generators/index.ts
  • packages/core/src/generators/runtime-validation.test.ts
  • packages/core/src/generators/runtime-validation.ts
  • packages/core/src/test-utils/context.ts
  • packages/core/src/types.ts
  • packages/fetch/src/index.ts
  • packages/mock/src/faker/getters/combine.test.ts
  • packages/orval/src/utils/options.test.ts
  • packages/orval/src/utils/options.ts
  • packages/query/src/client.ts
  • packages/query/src/index.ts
  • packages/solid-start/src/index.test.ts
  • samples/angular-app/orval.config.ts
  • samples/angular-app/src/api/endpoints-zod-both/index.msw.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/createPetsBody.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/error.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/index.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/listPetsParams.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/patchPetByIdBody.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/pet.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/pets.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/searchPetsParams.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/model/updatePetByIdBody.zod.ts
  • samples/angular-app/src/api/endpoints-zod-both/pets/pets.msw.ts
  • samples/angular-app/src/api/endpoints-zod-both/pets/pets.service.ts
  • samples/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

the-ult added a commit to the-ult/orval that referenced this pull request Aug 4, 2026
…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>
@the-ult
the-ult force-pushed the feat/runtime-validation-strategy-both branch from 81aceb7 to d168a27 Compare August 4, 2026 15:14
the-ult and others added 2 commits August 4, 2026 11:56
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>
the-ult and others added 9 commits August 4, 2026 11:56
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

zod Zod schema client related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(zod): configurable runtime validation strategy for Zod-backed clients (throw / log / both)

3 participants