Skip to content

feat(orval): add output.artifacts for runtime-safe artifact output groups - #3707

Draft
the-ult wants to merge 5 commits into
orval-labs:masterfrom
the-ult:feat/3704-angular-artifact-groups
Draft

feat(orval): add output.artifacts for runtime-safe artifact output groups#3707
the-ult wants to merge 5 commits into
orval-labs:masterfrom
the-ult:feat/3704-angular-artifact-groups

Conversation

@the-ult

@the-ult the-ult commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Note

This PR is being retired (2026-08-05). Current master already provides the runtime-safe artifact separation this proposed — verified by import-graph inspection, see the comment below. The two real remaining gaps are split out as #3813 (Angular resource files honour schemas.importPath / splitByTags) and #3815 (tags-split barrel re-exports *.resource.ts — the one genuinely-new capability here), with #3814 as related hygiene. Kept open until those merge.


Summary

Closes #3704.

Adds an opt-in output.artifacts option that emits independently importable artifact groups — Zod/TS schemas, the client (services + Angular *.resource.ts), and msw/faker mocks — each with its own group barrel, so a Node-based MSW consumer never evaluates Angular client modules (and vice versa).

output: {
  mode: 'tags-split',
  target: 'src/generated/client/api.ts',
  client: 'angular',
  artifacts: {
    schemas: 'src/generated/schemas',
    msw: 'src/generated/msw',
    faker: 'src/generated/faker',
  },
}

Design: sugar over existing primitives, one new writer step

A triage pass over the codebase showed most of this already exists: output.schemas gives an independent schemas barrel, and mock.generators[].path + indexMockFiles: true already produce dedicated msw/faker dirs with index.msw.ts / index.faker.ts barrels. The genuine gap was a complete client-group barrel (in tags-split mode nothing re-exports the per-tag services together with Angular *.resource.ts extra files — the reason consumers hand-roll the unsafe root barrel this issue describes).

So the implementation is deliberately thin:

  • output.artifacts normalizes onto the existing options (output.schemas, mock.generators[].path, forced indexMockFiles: true) — no parallel pipeline.
  • One new writer step, writeClientGroupBarrel in write-specs.ts, emits <clientDir>/index.ts from the actual written implementation + builder.extraFiles paths (never derived from tag names), composing append-only with the tagsSplitDeduplication barrel.
  • v1 requires mode: 'tags-split' and errors loudly on conflicts (workspace, indexFiles: false, duplicate schemas config, conflicting explicit generator paths, overlapping group dirs).
  • The docs first show the existing-primitives recipe (usable today on any orval version), then output.artifacts as the ergonomic wrapper. If maintainers prefer docs-only + the client-barrel fix, the sugar layer is cleanly separable — happy to split the PR.

One real bug was caught by the generated-output typecheck gate during verification: Angular's httpResource generator duplicates helper boilerplate (OrvalHttpResourceOptions, ResourceState, toResourceState) into every .resource.ts, which makes naive export * barrels fail with TS2308. The barrel now re-exports those names explicitly from one canonical file before the wildcards (registry-based; extend DUPLICATED_BOILERPLATE_EXPORTS_BY_CLIENT if future generators duplicate boilerplate).

Runtime-safety guarantees (tested)

New tests/api-generation.spec.ts assertions walk transitive relative imports and prove:

  • msw/faker group entries never reach a .service.ts/.resource.ts file nor any @angular/* import;
  • the client barrel never reaches .msw.ts/.faker.ts nor imports msw/@faker-js/faker;
  • the client barrel re-exports both services and resources.

Backwards compatibility

100% opt-in: artifacts is undefined by default and normalization is byte-identical without it. Full regeneration confirmed zero modified existing snapshots — 101 new files only (new test configs artifactGroups, artifactGroupsZod, client-agnostic artifactGroupsFetch, plus a new samples/angular-app artifact-groups target that CI compiles).

Verification

  • Unit: core 2100 ✓, orval 208 ✓ (1 pre-existing macOS-only /tmp flake), angular 222 ✓, mock 297 ✓
  • Snapshots: 5375/5375 ✓ (non-update re-run green), angular-app sample 93/93 ✓
  • vp lint --type-aware --type-check ✓; all 16 generated clients typecheck ✓

Docs

  • docs/content/docs/guides/angular.mdx: new “Runtime-safe artifact groups” section (problem, recipe with existing options, artifacts config, generated tree, monorepo package.json#exports mapping, caveats)
  • docs/content/docs/reference/configuration/output.mdx: new artifacts reference

Related issues

Sibling cluster: #3702, #3705, #3706, #3700. Prior art this builds on: #3537 (separate mock/faker output paths), #3318 (MSW barrel breaking vitest/jsdom — the failure mode fixed here), #3553 / #3624 (root barrels in split modes), #3592 (tags-split schemas), #2912 (indexFiles import paths), #3333 (rule-based output paths).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added output.artifacts for generating independently importable groups (schemas, client, MSW, Faker) with per-group barrels in tags-split mode, including Angular per-tag client re-exports.
  • Documentation
    • Expanded Angular “runtime-safe artifact groups” guidance and documented output.artifacts constraints/behavior; added tips to Faker and MSW guides.
  • Bug Fixes
    • Improved cleanup to also remove generated files in configured MSW/Faker artifact directories.
  • Tests
    • Added coverage for output.artifacts option normalization/validation, barrel generation behavior, and runtime import-graph separation.

Copilot AI review requested due to automatic review settings July 11, 2026 08:34
@coderabbitai

coderabbitai Bot commented Jul 11, 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 output.artifacts configuration for separate schemas, client, MSW, and Faker outputs, including normalization, validation, barrel generation, documentation, generated Angular fixtures, and runtime-safety tests.

Changes

Artifact group generation

Layer / File(s) Summary
Configuration and normalization
docs/content/docs/..., packages/core/src/types.ts, packages/orval/src/utils/options.ts, packages/orval/src/utils/options.test.ts, packages/orval/src/generate-spec.ts
Defines and documents output.artifacts, normalizes group directories and mock generators, validates configuration constraints, and cleans configured mock directories.
Barrel composition and cleanup
packages/orval/src/write-specs.ts, packages/orval/src/write-specs.test.ts
Adds deduplicated barrel helpers, generates client group barrels, and integrates them into implementation paths.
Generated artifact fixtures
samples/angular-app/orval.config.ts, samples/angular-app/src/api/artifact-groups/...
Adds Angular service/resource client output, schemas, MSW handlers, mock barrels, and client re-exports for an artifact-group configuration.
Runtime boundary validation
tests/configs/*.ts, tests/api-generation.spec.ts
Adds Angular, Zod, and multiple client configurations and verifies transitive import separation and expected client barrel exports.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Config
  participant normalizeOptions
  participant writeSpecs
  participant ArtifactBarrels
  participant RuntimeTests
  Config->>normalizeOptions: provide output.artifacts settings
  normalizeOptions->>writeSpecs: return normalized artifact directories and mock generators
  writeSpecs->>ArtifactBarrels: generate client group barrel
  ArtifactBarrels-->>RuntimeTests: expose separated client, MSW, Faker, and schema entry points
  RuntimeTests->>ArtifactBarrels: traverse relative imports and validate boundaries
Loading

Possibly related issues

Possibly related PRs

Suggested labels: angular, mock, msw, enhancement, documentation

Suggested reviewers: snebjorn, melloware, anymaniax, soartec-lab

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the new output.artifacts feature for runtime-safe artifact groups.
✨ 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 an opt-in output.artifacts configuration that normalizes to existing output primitives (schemas output + mock generator paths/barrels) and introduces a single additional writer step to emit a runtime-safe client-group barrel in tags-split mode, preventing cross-runtime transitive imports (Angular vs MSW/Faker). This is reinforced by new tests that walk transitive relative-import graphs to prove runtime-safe boundaries.

Changes:

  • Add output.artifacts normalization (constraints + conflict detection + auto-wiring MSW/Faker generator paths and indexMockFiles).
  • Add a new client-group barrel writer (writeClientGroupBarrel) that composes with tagsSplitDeduplication barrels and avoids TS2308 conflicts for duplicated Angular httpResource boilerplate.
  • Add integration coverage: new configs, runtime-safety import-walker tests, updated/new snapshots, and docs updates.

Reviewed changes

Copilot reviewed 113 out of 113 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/configs/mock.config.ts Adds artifactGroupsFetch test config using output.artifacts with fetch client.
tests/configs/angular.config.ts Adds artifactGroups and artifactGroupsZod configs exercising Angular + artifacts (incl. both + zod schemas).
tests/api-generation.spec.ts Adds transitive relative-import graph walker tests asserting runtime-safe artifact group boundaries.
tests/snapshots/mock/artifact-groups-fetch/schemas/petWithTag.ts New snapshot for schemas group output (fetch artifacts).
tests/snapshots/mock/artifact-groups-fetch/schemas/pets.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/petCountry.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/petCallingCode.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/pet.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/listPetsSort.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/listPetsParams.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/labradoodleBreed.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/labradoodle.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/index.ts New snapshot for schemas barrel in schemas group.
tests/snapshots/mock/artifact-groups-fetch/schemas/error.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/dogType.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/dog.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/dachshundBreed.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/dachshund.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/createPetsSort.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/createPetsParams.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/createPetsBody.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/catType.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/schemas/cat.ts New snapshot for schemas group output.
tests/snapshots/mock/artifact-groups-fetch/msw/pets/pets.msw.ts New snapshot for MSW group output (fetch artifacts).
tests/snapshots/mock/artifact-groups-fetch/msw/index.msw.ts New snapshot for MSW barrel in msw group.
tests/snapshots/mock/artifact-groups-fetch/msw/health/health.msw.ts New snapshot for MSW group output.
tests/snapshots/mock/artifact-groups-fetch/faker/pets/pets.faker.ts New snapshot for Faker group output (fetch artifacts).
tests/snapshots/mock/artifact-groups-fetch/faker/index.faker.ts New snapshot for Faker barrel in faker group.
tests/snapshots/mock/artifact-groups-fetch/faker/health/health.faker.ts New snapshot for Faker group output.
tests/snapshots/mock/artifact-groups-fetch/client/pets/pets.ts New snapshot for client group output (fetch artifacts).
tests/snapshots/mock/artifact-groups-fetch/client/index.ts New snapshot for client group barrel (fetch artifacts).
tests/snapshots/mock/artifact-groups-fetch/client/health/health.ts New snapshot for client group output.
tests/snapshots/mock/artifact-groups-fetch/client/common-types.ts New snapshot for deduplicated common types used by client barrel.
tests/snapshots/angular/artifact-groups/schemas/searchPetsBodyStatus.ts New snapshot for Angular artifacts schemas output.
tests/snapshots/angular/artifact-groups/schemas/searchPetsBody.ts New snapshot for Angular artifacts schemas output.
tests/snapshots/angular/artifact-groups/schemas/pets.ts New snapshot for Angular artifacts schemas output.
tests/snapshots/angular/artifact-groups/schemas/pet.ts New snapshot for Angular artifacts schemas output.
tests/snapshots/angular/artifact-groups/schemas/index.ts New snapshot for Angular artifacts schemas barrel.
tests/snapshots/angular/artifact-groups/schemas/error.ts New snapshot for Angular artifacts schemas output.
tests/snapshots/angular/artifact-groups/schemas/createPetsBody.ts New snapshot for Angular artifacts schemas output.
tests/snapshots/angular/artifact-groups/msw/pets/pets.msw.ts New snapshot for Angular artifacts MSW group output.
tests/snapshots/angular/artifact-groups/msw/index.msw.ts New snapshot for Angular artifacts MSW barrel.
tests/snapshots/angular/artifact-groups/msw/health/health.msw.ts New snapshot for Angular artifacts MSW group output.
tests/snapshots/angular/artifact-groups/faker/pets/pets.faker.ts New snapshot for Angular artifacts Faker group output.
tests/snapshots/angular/artifact-groups/faker/index.faker.ts New snapshot for Angular artifacts Faker barrel.
tests/snapshots/angular/artifact-groups/faker/health/health.faker.ts New snapshot for Angular artifacts Faker group output.
tests/snapshots/angular/artifact-groups/client/pets/pets.service.ts New snapshot for Angular client group service output.
tests/snapshots/angular/artifact-groups/client/pets/pets.resource.ts New snapshot for Angular client group resource output (httpResource).
tests/snapshots/angular/artifact-groups/client/index.ts New snapshot for Angular client group barrel (handles TS2308 boilerplate exports).
tests/snapshots/angular/artifact-groups/client/health/health.service.ts New snapshot for Angular client group service output.
tests/snapshots/angular/artifact-groups/client/health/health.resource.ts New snapshot for Angular client group resource output (canonical boilerplate export source).
tests/snapshots/angular/artifact-groups-zod/schemas/petWithTag.zod.ts New snapshot for artifacts schemas when schemas.type = zod.
tests/snapshots/angular/artifact-groups-zod/schemas/pets.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/pet.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/listPetsParams.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/listPetsHeaders.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/labradoodle.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/index.ts New snapshot for zod schemas barrel.
tests/snapshots/angular/artifact-groups-zod/schemas/error.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/dog.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/dachshund.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/createPetsParams.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/createPetsHeaders.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/createPetsBody.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/schemas/cat.zod.ts New snapshot for zod schemas group output.
tests/snapshots/angular/artifact-groups-zod/msw/index.msw.ts New snapshot for artifacts MSW barrel in zod case.
tests/snapshots/angular/artifact-groups-zod/msw/health/health.msw.ts New snapshot for artifacts MSW output in zod case.
tests/snapshots/angular/artifact-groups-zod/faker/pets/pets.faker.ts New snapshot for artifacts Faker output in zod case.
tests/snapshots/angular/artifact-groups-zod/faker/index.faker.ts New snapshot for artifacts Faker barrel in zod case.
tests/snapshots/angular/artifact-groups-zod/faker/health/health.faker.ts New snapshot for artifacts Faker output in zod case.
tests/snapshots/angular/artifact-groups-zod/client/pets/pets.service.ts New snapshot for Angular client output when schemas are zod.
tests/snapshots/angular/artifact-groups-zod/client/index.ts New snapshot for client group barrel in zod case.
tests/snapshots/angular/artifact-groups-zod/client/health/health.service.ts New snapshot for Angular client output in zod case.
samples/angular-app/src/api/artifact-groups/schemas/searchPetsStatus.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/searchPetsParams.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/petStatus.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/pets.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/pet.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/listPetsParams.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/index.ts Adds sample generated schemas barrel (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/error.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/createPetsBodyStatus.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/schemas/createPetsBody.ts Adds sample generated schemas group output (angular-app).
samples/angular-app/src/api/artifact-groups/msw/index.msw.ts Adds sample generated MSW barrel group output (angular-app).
samples/angular-app/src/api/artifact-groups/client/pets/pets.resource.ts Adds sample generated Angular httpResource client output (angular-app).
samples/angular-app/src/api/artifact-groups/client/index.ts Adds sample generated client barrel group output (angular-app).
samples/angular-app/orval.config.ts Adds petstoreArtifactGroups sample config using output.artifacts.
samples/angular-app/snapshots/api/artifact-groups/schemas/searchPetsStatus.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/searchPetsParams.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/petStatus.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/pets.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/pet.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/listPetsParams.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/index.ts Snapshot for sample generated schemas barrel.
samples/angular-app/snapshots/api/artifact-groups/schemas/error.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/createPetsBodyStatus.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/schemas/createPetsBody.ts Snapshot for sample generated schemas group output.
samples/angular-app/snapshots/api/artifact-groups/msw/index.msw.ts Snapshot for sample generated MSW barrel.
samples/angular-app/snapshots/api/artifact-groups/client/pets/pets.resource.ts Snapshot for sample generated client resource output.
samples/angular-app/snapshots/api/artifact-groups/client/index.ts Snapshot for sample generated client barrel.
packages/orval/src/write-specs.ts Adds reusable barrel appender + client group barrel emission and integrates it into the write pipeline.
packages/orval/src/write-specs.test.ts Adds unit tests for appendOrCreateBarrel and writeClientGroupBarrel.
packages/orval/src/utils/options.ts Normalizes output.artifacts, validates constraints, merges schemas, and applies mock generator overrides.
packages/orval/src/utils/options.test.ts Adds normalization tests for output.artifacts behavior and conflict rules.
packages/orval/src/generate-spec.ts Extends clean-up logic to include artifacts MSW/Faker directories.
packages/core/src/types.ts Adds public config + normalized types for output.artifacts and artifacts groups.
docs/content/docs/reference/configuration/output.mdx Documents output.artifacts API, constraints, and interaction with mock options.
docs/content/docs/guides/angular.mdx Adds Angular guide section explaining runtime-safe artifact groups and output.artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/orval/src/write-specs.test.ts Outdated

@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

🧹 Nitpick comments (1)
packages/orval/src/utils/options.test.ts (1)

1837-2116: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Good coverage overall; consider adding tests for the two edge cases flagged in options.ts.

This suite doesn't exercise { schemas: false, artifacts: { schemas: '...' } } or a function-form mock.generators entry combined with artifacts.msw/artifacts.faker — both currently fail silently instead of throwing (see the corresponding comments on packages/orval/src/utils/options.ts). Worth adding regression tests once those are fixed, so this suite locks in the corrected behavior.

🤖 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 1837 - 2116, Add
regression tests in the `output.artifacts normalization` suite for the two
validation gaps in `normalizeOptions`: verify `{ schemas: false, artifacts: {
schemas: '...' } }` throws, and verify function-form entries in
`mock.generators` throw when combined with `artifacts.msw` or `artifacts.faker`.
First update the corresponding validation logic in `normalizeOptions` so both
invalid configurations fail explicitly, then assert the expected errors in these
tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/orval/src/utils/options.ts`:
- Around line 262-317: Update applyArtifactsMockOverrides so function-form
entries for the current mock type are detected before appending a default
generator, causing the existing conflict error to be raised when
output.artifacts.msw or output.artifacts.faker is configured. Adjust the
generator lookup/branching around existingIndex so object-form generators still
receive the artifact path and unrelated generator types remain unchanged.

In `@samples/angular-app/src/api/artifact-groups/client/pets/pets.resource.ts`:
- Around line 173-177: Update the pets resource factory around the request
construction and HttpResourceRequest setup so `version()` and `params()` are
evaluated inside the `httpResource` callback rather than when the factory runs.
Ensure each callback rebuilds the URL and filtered parameters from the current
signal values, matching the pattern used by `searchPetsResource` and the other
resource helpers, so signal updates refresh the request.

In `@samples/angular-app/src/api/artifact-groups/client/pets/pets.service.ts`:
- Around line 193-196: Update the filterParams call in the pets service method
to enable preservation of required nullable query parameters by passing true for
preserveRequiredNullables, while retaining requirednullableString and
requirednullableStringTwo in the existing set. Ensure null values for these
fields remain in the request.

---

Nitpick comments:
In `@packages/orval/src/utils/options.test.ts`:
- Around line 1837-2116: Add regression tests in the `output.artifacts
normalization` suite for the two validation gaps in `normalizeOptions`: verify
`{ schemas: false, artifacts: { schemas: '...' } }` throws, and verify
function-form entries in `mock.generators` throw when combined with
`artifacts.msw` or `artifacts.faker`. First update the corresponding validation
logic in `normalizeOptions` so both invalid configurations fail explicitly, then
assert the expected errors in these tests.
🪄 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: 5eebfb89-6643-4211-b0c9-1617d5a13b20

📥 Commits

Reviewing files that changed from the base of the PR and between c082bb4 and 617581a.

⛔ Files ignored due to path filters (86)
  • samples/angular-app/__snapshots__/api/artifact-groups/client/index.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/client/pets/pets.resource.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/client/pets/pets.service.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/msw/index.msw.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/msw/pets/pets.msw.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/createPetsBody.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/createPetsBodyStatus.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/error.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/index.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/listPetsParams.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/pet.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/petStatus.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/pets.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/searchPetsParams.ts is excluded by !**/__snapshots__/**
  • samples/angular-app/__snapshots__/api/artifact-groups/schemas/searchPetsStatus.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/client/health/health.service.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/client/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/client/pets/pets.service.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/faker/health/health.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/faker/index.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/faker/pets/pets.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/msw/health/health.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/msw/index.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/msw/pets/pets.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/cat.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/createPetsBody.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/createPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/createPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/dachshund.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/dog.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/error.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/labradoodle.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/listPetsHeaders.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/listPetsParams.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/pet.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/petWithTag.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups-zod/schemas/pets.zod.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/client/health/health.resource.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/client/health/health.service.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/client/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/client/pets/pets.resource.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/client/pets/pets.service.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/faker/health/health.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/faker/index.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/faker/pets/pets.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/msw/health/health.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/msw/index.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/msw/pets/pets.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/createPetsBody.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/error.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/pet.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/pets.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/searchPetsBody.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/angular/artifact-groups/schemas/searchPetsBodyStatus.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/client/common-types.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/client/health/health.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/client/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/client/pets/pets.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/faker/health/health.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/faker/index.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/faker/pets/pets.faker.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/msw/health/health.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/msw/index.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/msw/pets/pets.msw.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/cat.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/catType.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/createPetsBody.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/createPetsParams.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/createPetsSort.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/dachshund.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/dachshundBreed.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/dog.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/dogType.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/error.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/index.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/labradoodle.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/labradoodleBreed.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/listPetsParams.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/listPetsSort.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/pet.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/petCallingCode.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/petCountry.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/petWithTag.ts is excluded by !**/__snapshots__/**
  • tests/__snapshots__/mock/artifact-groups-fetch/schemas/pets.ts is excluded by !**/__snapshots__/**
📒 Files selected for processing (27)
  • docs/content/docs/guides/angular.mdx
  • docs/content/docs/reference/configuration/output.mdx
  • packages/core/src/types.ts
  • packages/orval/src/generate-spec.ts
  • packages/orval/src/utils/options.test.ts
  • packages/orval/src/utils/options.ts
  • packages/orval/src/write-specs.test.ts
  • packages/orval/src/write-specs.ts
  • samples/angular-app/orval.config.ts
  • samples/angular-app/src/api/artifact-groups/client/index.ts
  • samples/angular-app/src/api/artifact-groups/client/pets/pets.resource.ts
  • samples/angular-app/src/api/artifact-groups/client/pets/pets.service.ts
  • samples/angular-app/src/api/artifact-groups/msw/index.msw.ts
  • samples/angular-app/src/api/artifact-groups/msw/pets/pets.msw.ts
  • samples/angular-app/src/api/artifact-groups/schemas/createPetsBody.ts
  • samples/angular-app/src/api/artifact-groups/schemas/createPetsBodyStatus.ts
  • samples/angular-app/src/api/artifact-groups/schemas/error.ts
  • samples/angular-app/src/api/artifact-groups/schemas/index.ts
  • samples/angular-app/src/api/artifact-groups/schemas/listPetsParams.ts
  • samples/angular-app/src/api/artifact-groups/schemas/pet.ts
  • samples/angular-app/src/api/artifact-groups/schemas/petStatus.ts
  • samples/angular-app/src/api/artifact-groups/schemas/pets.ts
  • samples/angular-app/src/api/artifact-groups/schemas/searchPetsParams.ts
  • samples/angular-app/src/api/artifact-groups/schemas/searchPetsStatus.ts
  • tests/api-generation.spec.ts
  • tests/configs/angular.config.ts
  • tests/configs/mock.config.ts

Comment thread packages/orval/src/utils/options.ts
Comment thread samples/angular-app/src/api/artifact-groups/client/pets/pets.resource.ts Outdated
@pkg-pr-new

pkg-pr-new Bot commented Jul 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@orval/angular

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

@orval/axios

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

@orval/core

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

@orval/effect

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

@orval/fetch

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

@orval/hono

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

@orval/mcp

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

@orval/mock

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

orval

bun add https://pkg.pr.new/orval@2205314

@orval/query

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

@orval/solid-start

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

@orval/swr

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

@orval/zod

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

commit: 2205314

@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.

🧹 Nitpick comments (1)
packages/orval/src/write-specs.test.ts (1)

212-215: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding a test for partial path-prefix collision in appendOrCreateBarrel.

The appendOrCreateBarrel implementation uses data.includes(export * from '${imp}') to detect already-declared imports. This is a substring check, so if an existing barrel contains export * from './bc'; and a new import './b' is appended, the check would incorrectly skip it because export * from './b' is a substring of export * from './bc'. A test covering this edge case would help guard against missing exports in generated barrels.

🤖 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/write-specs.test.ts` around lines 212 - 215, Add a test
covering appendOrCreateBarrel when an existing export path is a longer prefix of
a new path, such as './bc' versus './b'. Verify the generated barrel preserves
the existing export and appends the new distinct export, preventing substring
matching from suppressing it.
🤖 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.

Nitpick comments:
In `@packages/orval/src/write-specs.test.ts`:
- Around line 212-215: Add a test covering appendOrCreateBarrel when an existing
export path is a longer prefix of a new path, such as './bc' versus './b'.
Verify the generated barrel preserves the existing export and appends the new
distinct export, preventing substring matching from suppressing it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: eb8a9f86-516a-4b8c-bb75-be2f96758f57

📥 Commits

Reviewing files that changed from the base of the PR and between 617581a and 894a52f.

📒 Files selected for processing (4)
  • packages/orval/src/utils/options.test.ts
  • packages/orval/src/utils/options.ts
  • packages/orval/src/write-specs.test.ts
  • packages/orval/src/write-specs.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/orval/src/utils/options.test.ts
  • packages/orval/src/write-specs.ts
  • packages/orval/src/utils/options.ts

@the-ult

the-ult commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

Review feedback addressed:

  • Copilot — write-specs.test.ts 'sorted' test name: fixed in 894a52f (renamed; sorting intentionally lives in writeClientGroupBarrel via .toSorted(localeCompare), the helper preserves caller order — also added newline-separator + dedupe guards to the append path with tests).
  • CodeRabbit — function-form mock.generators bypassing the artifacts conflict guard: fixed in f9fd859 — the guard is hoisted before type-matching and rejects any function-form entry (its type/path can't be inspected), with a regression test.
  • CodeRabbit — sample pets.resource.ts reads signals outside the httpResource callback: pre-existing generator behavior for the multi-content-type resource shape, byte-identical in the existing master samples (samples/angular-app/src/api/http-resource/pets/pets.service.ts:202, http-resource-zod:211) — the new artifact-groups sample just reproduces it. Real finding, but orthogonal to this PR; deserves its own issue against the Angular httpResource generator.
  • CodeRabbit — preserveRequiredNullables not passed in sample pets.service.ts: likewise pre-existing — the identical 2-arg filterParams call ships in master's samples/angular-app/src/api/http-client/pets/pets.service.ts:195. Same suggestion: separate issue for the generator default.

@the-ult the-ult changed the title feat: add output.artifacts for runtime-safe artifact output groups feat(orval): add output.artifacts for runtime-safe artifact output groups Jul 11, 2026
@the-ult

the-ult commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

Broadened test coverage in d1418e0, per review discussion: added one artifactGroups* config per remaining client package (axios, react-query, swr, vue-query, svelte-query — Angular and fetch were already covered), parametrized the runtime-safety import-graph tests over all of them (now 12 tests total, +178 new snapshot files, zero diffs to any pre-existing snapshot), and cross-linked the feature from msw.mdx/faker.mdx since those are the docs that motivated the original runtime-safety concern.

solid-start was evaluated and deliberately left out: wiring it through this config is the first time solid-start-flavored output has ever run through tests' generated-output typecheck gate (its own solid-start.config.ts isn't part of generate-api's run-p 'generate:*'), and doing so surfaces two pre-existing solid-start generator defects unrelated to output.artifacts: a missing @solidjs/router devDependency (TS2307) and a genuine TS2395 merged-declaration error in generated Pets types — both reproducible from solid-start.config.ts's own existing entries in isolation, nothing to do with this PR. Happy to file that as a separate issue if useful.

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 264 out of 264 changed files in this pull request and generated no new comments.

@melloware

Copy link
Copy Markdown
Collaborator

@aqeelat @wadakatu would like your opinion on this feature?

@aqeelat

aqeelat commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

What's the use case? How are these artifacts going to be consumed by the generated clients? Can it be easily done via a post processor?

@melloware

Copy link
Copy Markdown
Collaborator

@aqeelat sent you one more i forgot to send you: GHSA-cxq5-97v7-87j8

@melloware
melloware marked this pull request as draft July 12, 2026 15:01
@the-ult

the-ult commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Artifacts might not be the correct naming.

The idea was in an nx repo.
We have a data-access folder/library and sometimes a models as well, to prevent Circular dependencies.
We als have a separate mocks library.
So it would be nice to be able to config where to generate the output.
And in in different folders/libraries if possible.
Or something like data-access with multiple secondary entry points (/data-access/msw, /data-access/models, data-access/services)

(Going on vacation now, will dive in it further when I get back. With improved examples, output, etc)

@the-ult

the-ult commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Sorry for the radio silence — back from vacation now.

Use case, concretely: in an Nx-style monorepo you want independently-importable libraries so consumers don't pull unrelated runtime code across a boundary — e.g. a data-access lib whose consumers only need types/services, and a separate mocks lib that only test/storybook targets import. Today tags-split mode's only complete barrel is the workspace one, which re-exports everything — client code and mock code together. The moment a Node-based MSW handler imports that barrel (because it's the only complete entry point), it drags in Angular HttpClient/httpResource modules, and vice versa. That's the exact failure in #3318 (MSW barrel breaking vitest/jsdom), and what #3553/#3624/#3700/#3702/#3705/#3706 are all circling from different angles. So this isn't a new capability — it's making the existing split-mode file layout safely consumable without everyone hand-rolling (and getting wrong) their own root barrel.

How consumers use it: nothing changes for the generated client's own imports. What's new is a second, orthogonal barrel per artifact group — <clientDir>/index.ts re-exports every service/resource, <schemasDir>/index.ts re-exports schemas (already existed), <mswDir>/index.msw.ts / <fakerDir>/index.faker.ts re-export mocks (also already existed via mock.generators[].path + indexMockFiles). A consumer imports the barrel for what they need, and the runtime-safety tests in this PR prove those import graphs never cross.

Why not a post-processor: the barrel content isn't derivable from static config — it has to reflect what orval actually wrote (tags-split's file layout, Angular's extra *.resource.ts files, wherever mock.generators[].path sends mocks). A post-processor would have to re-walk the output directory and re-derive all of that from the outside — including the TS2308 dedup this PR already handles for Angular's httpResource boilerplate. Doing it in write-specs.ts, which already has the list of files it just wrote, is strictly less work and less fragile than re-deriving it externally.

On the naming/Nx idea from before vacation: I still think artifacts is the wrong word — it doesn't say why you'd reach for it. Directionally, mapping your data-access/mocks/models example onto today's config:

output: {
  mode: 'tags-split',
  target: 'libs/data-access/src/lib/generated/client/api.ts',
  client: 'angular',
  schemas: 'libs/models/src/lib/generated/schemas',
  artifacts: {
    msw: 'libs/mocks/src/lib/generated/msw',
    faker: 'libs/mocks/src/lib/generated/faker',
  },
}

produces:

libs/
├── data-access/
│   └── src/lib/generated/
│       └── client/
│           ├── index.ts              # import { listPets } from '@myorg/data-access'
│           ├── common-types.ts
│           └── pets/
│               ├── pets.service.ts
│               └── pets.resource.ts
├── models/
│   └── src/lib/generated/
│       └── schemas/
│           ├── index.ts              # import { Pet } from '@myorg/models'
│           ├── pet.ts
│           └── pets.ts
└── mocks/
    └── src/lib/generated/
        ├── msw/
        │   ├── index.msw.ts          # import { petsHandlers } from '@myorg/mocks/msw'
        │   └── pets/
        │       └── pets.msw.ts
        └── faker/
            ├── index.faker.ts        # import { getPetMock } from '@myorg/mocks/faker'
            └── pets/
                └── pets.faker.ts

Each folder is a normal Nx lib today, so data-access never imports MSW/Faker (nothing in it references msw/@faker-js/faker) and mocks never imports @angular/* — the runtime-safety tests in this PR assert exactly that boundary, per group. What's still missing to make each folder a real Nx secondary entry point is the scaffolding — ng-package.json / project.json / package.json#exports per lib — which is a one-time project-setup step, not something regenerated on every orval run; the docs section already shows the package.json#exports wiring for that by hand.

@the-ult
the-ult force-pushed the feat/3704-angular-artifact-groups branch from 2205314 to 5291d7f Compare August 4, 2026 15:14
@aqeelat

aqeelat commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

We recently added a couple of enhancements around this. In our nx repo, we do put schemas in a separate library than clients. We do use split-tags. I need to check if fakers and msw have the same configs.

Check recent releases and let me know if we're still not fully satisfying your requirements. If not, I'll help you get this PR to the finish line.

the-ult and others added 3 commits August 4, 2026 11:59
…rval-labs#3704)

Adds output.artifacts, an opt-in tags-split option that routes schemas,
mock (msw/faker), and client files into separate directories with their
own barrels, so consumers can import a client bundle without pulling in
msw/faker (and vice versa). Angular's httpResource generator duplicates
identical helper boilerplate (OrvalHttpResourceOptions, ResourceState,
toResourceState) into every .resource.ts file, so the new client barrel
re-exports those names explicitly from one canonical file before its
wildcard exports, avoiding a TS2308 ambiguous-export error whenever
'both' retrieval mode multi-tag output is combined with the new barrel.

100% backward compatible: artifacts is undefined by default, and all
existing snapshots are unchanged.

Fixes orval-labs#3704

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Addresses Copilot review on the artifacts barrel helper: appending to an
existing index now inserts a separating newline when the file lacks a
trailing one and dedupes named re-exports; the misleading 'sorted' test
name is corrected (the caller sorts, the helper preserves order) and the
new edge cases are covered by tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts mocks

CodeRabbit review: the type-matching findIndex skipped function-form
generators, making the conflict guard dead code — a generators array with
only a function-form entry silently gained an appended default generator.
The guard is now hoisted before matching and rejects any function-form
entry, since its type/path cannot be inspected or redirected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
the-ult and others added 2 commits August 4, 2026 11:59
…client packages

Adds one artifactGroups* test config per remaining client (axios,
react-query, swr, vue-query, svelte-query) alongside the existing Angular
and fetch coverage, parametrizes the runtime-safety import-graph tests
over all of them, and cross-links the feature from msw.mdx/faker.mdx —
the docs that motivated the original runtime-safety concern in orval-labs#3704 but
previously had no pointer to the fix.

solid-start was evaluated and deliberately excluded: wiring it through
this config was the first time solid-start-flavored output has ever run
through the generated-output typecheck gate (its own solid-start.config.ts
has no generate:solid-start script and isn't part of generate-api), and
doing so surfaces pre-existing solid-start generator defects unrelated to
output.artifacts (missing @solidjs/router devDependency, a genuine TS2395
merged-declaration bug in generated Pets types, both reproducible from
solid-start.config.ts's own existing entries in isolation). Left as a
documented follow-up rather than folded into this PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ase onto master

The 3-way merge on write-specs.ts's import block silently dropped
`import { unique } from 'remeda';` during the rebase conflict
resolution even though the function is still used by
appendOrCreateBarrel/writeClientGroupBarrel. Master also picked up
~55 commits since this branch was cut, including a typedoc bump
(HTML -> Markdown docs output) and generator improvements (e.g. MSW
handlers now importing from a sibling faker module instead of
duplicating it inline) that regenerate this PR's own fixtures
differently. Regenerated all snapshots against current master to
match.
@the-ult

the-ult commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

@aqeelat Thanks — I checked, and you were right: recent releases do cover most of it. I verified the import graph on current master with schemas.path + mock.generators[].path + indexMockFiles: true, angular tags-split, retrievalClient: 'both':

client/pets/pets.service.ts   client/pets/pets.resource.ts
models/index.ts  models/pet.ts  models/index.faker.ts
msw/index.msw.ts   msw/pets/pets.msw.ts
faker/index.faker.ts  faker/pets/pets.faker.ts
  • msw/index.msw.tspets.msw imports msw, ../../faker/…, and type-only ../../models. It never reaches client/, and there is no @angular/* anywhere in that graph.
  • faker/index.faker.tspets.faker imports @faker-js/faker and type-only ../../models.
  • models/index.ts is export * from './pet' only — it does not re-export index.faker, so the production type barrel stays free of faker.

So the runtime-safety core of #3704 — a Node MSW consumer never evaluating Angular — already works today. That's the answer to your question, and it's why I'm retiring this PR: output.artifacts was mostly sugar over primitives that now exist.

Two genuine gaps remained, both now standalone PRs:

Plus #3814, adjacent hygiene rather than a #3704 requirement: clean never pruned configured mock paths, so a separate mocks library accumulated orphaned *.msw.ts / *.faker.ts for endpoints the spec no longer has.

One open question before I'd propose anything further. With faker: { path: './faker', schemas: true }, the schema-level factories are written to <schemas-dir>/index.faker.ts — the schemas directory — regardless of faker.path. It isn't a safety leak (models/index.ts doesn't re-export it), but it does mean a models library's source imports @faker-js/faker while its public barrel never exposes it, which I'd expect to trip dependency-check lint rules in an Nx setup. schemasImportPath changes the specifier consumers import by, not where the file is written, so it doesn't help here. Is the current placement intentional — factories sitting next to the schemas they mock — or would honouring faker.path be welcome? Happy to do it if you'd take it; not going to build it speculatively.

Keeping this PR open until those three land, then closing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(anglar): configurable artifact output groups and runtime-safe entry points

4 participants