Skip to content

feat(mock): add faker schema mock generation - #3426

Merged
melloware merged 7 commits into
orval-labs:masterfrom
jakiestfu:feat/faker-schema-mocks
May 23, 2026
Merged

feat(mock): add faker schema mock generation#3426
melloware merged 7 commits into
orval-labs:masterfrom
jakiestfu:feat/faker-schema-mocks

Conversation

@jakiestfu

@jakiestfu jakiestfu commented May 22, 2026

Copy link
Copy Markdown
Contributor

Note on diff size: The +2,155 / -64 delta is dominated by new snapshot and generated test-fixture files (tests/__snapshots__/** and tests/generated/**). The actual source change is ~+814 / -64 across 13 files.

Summary

Adds two options to the faker mock generator so users can opt into mock-data factories for components/schemas, independent of operation responses:

  • schemas (default false) — emit one get<SchemaName>Mock() factory per components/schemas entry into a consolidated index.faker.ts next to the generated schema types.
  • operationResponses (default true) — toggles the existing per-operation get<OperationId>ResponseMock factories.

When both are enabled, the per-operation factories delegate to the schema-level factories instead of re-inlining schema bodies. Operation- or tag-level override.mock rules that touch a property of the referenced schema fall back to inlining so existing override semantics keep working.

Example usage

import { defineConfig } from 'orval';

export default defineConfig({
  petstore: {
    output: {
      target: './src/api/petstore.ts',
      schemas: './src/api/model',
      mock: {
        generators: [
          {
            type: 'faker',
            schemas: true,             // emit components/schemas factories
            operationResponses: true,  // emit per-operation response factories
          },
        ],
      },
    },
    input: { target: './petstore.yaml' },
  },
});

Example output

./src/api/model/index.faker.ts — one factory per components/schemas entry:

import { faker } from '@faker-js/faker';
import type { Cat, Dog, Pet, Pets } from '.';

export const getDogMock = (overrideResponse: Partial<Dog> = {}): Dog => ({
  barksPerMinute: faker.number.int(),
  type: 'dog',
  ...overrideResponse,
});

export const getCatMock = (overrideResponse: Partial<Cat> = {}): Cat => ({
  petsRequested: faker.number.int(),
  type: 'cat',
  ...overrideResponse,
});

export const getPetMock = (overrideResponse: Partial<Pet> = {}): Pet => ({
  ...faker.helpers.arrayElement([{ ...getDogMock() }, { ...getCatMock() }]),
  id: faker.number.int(),
  name: faker.string.alpha({ length: { min: 10, max: 20 } }),
  ...overrideResponse,
});

export const getPetsMock = (): Pets =>
  Array.from(
    { length: faker.number.int({ min: 1, max: 10 }) },
    () => getPetMock(),
  );

./src/api/petstore.ts (operation-response factories, now delegating):

import { getCatMock, getDogMock, getPetMock } from './model/index.faker';

export const getListPetsResponseMock = (): Pets =>
  Array.from(
    { length: faker.number.int({ min: 1, max: 10 }) },
    () => ({ ...getPetMock() }),
  );

export const getShowPetByIdResponseMock = (): Pet => ({
  ...faker.helpers.arrayElement([{ ...getDogMock() }, { ...getCatMock() }]),
  id: faker.number.int(),
  name: faker.string.alpha({ length: { min: 10, max: 20 } }),
});

export const getShowPetWithOwnerResponseMock = (
  overrideResponse: Partial<Extract<PetWithTag, object>> = {},
): PetWithTag => ({
  tag: faker.string.alpha({ length: { min: 10, max: 20 } }),
  pet: faker.helpers.arrayElement([{ ...getPetMock() }, null]),
  ...overrideResponse,
});

Consumer:

import { getPetMock } from './api/model/index.faker';
import { getListPetsResponseMock } from './api/petstore';

const buddy = getPetMock({ name: 'Buddy' });
// => { id: 4823, name: 'Buddy', type: 'dog', barksPerMinute: 17 }

const pets = getListPetsResponseMock();
// => [{ id: 8201, name: 'qWfXz...', type: 'cat', petsRequested: 3 }, ...]

Override fallback

When override.mock.operations.<opId>.properties (or the tag-level equivalent) names a property that exists on the referenced schema, that one ref falls back to inlining so the override actually applies. The same matching rules used elsewhere in orval are honored — bare property names, regex (/pattern/), and exact path (#.foo.bar):

override: {
  mock: {
    operations: {
      listPets: {
        properties: {
          name: "'Snowball'",         // bare name
          '/.*Id$/': () => 'uuid-x',  // regex
          '#.pet.email': () => 'test@example.com', // exact path
        },
      },
    },
  },
}

Any matching key on the referenced schema makes getListPetsResponseMock inline Pet's body (so the override actually lands) instead of calling getPetMock().

NodeNext / Node16 compatibility

Schema-factory imports emit with the appropriate runtime extension when output.tsconfig.compilerOptions.moduleResolution is NodeNext or Node16:

import { getDisplayColorMock } from './model/index.faker.js';

Docs

Splits the existing "MSW" guide into separate MSW and Faker pages under Validation & Mocking, with the new options (schemas, operationResponses) documented on the Faker page including a "Schema Factories" subsection.

Bug fix included

A separate fix bundled in this PR addresses TS1361: 'X' cannot be used as a value because it was imported using 'import type' in the consolidated index.faker.ts. When a schema is used both as a type and as a runtime value (e.g. via Object.values(EnumName) for a string-typed enum component), the file now emits a unified import { X } line that works in both positions, while types-only schemas continue to emit import type { X }.

Test plan

  • Workspace lint, typecheck, and @orval/core + orval unit tests (1801 + 91)
  • tests/configs/mock.config.ts — three new configs (petstoreFakerSchemas, petstoreFakerSchemasAndOps, stringEnumRefFakerSchemasTagsSplit) plus tests/specifications/faker-schemas-string-enum-ref.yaml
  • node tests/scripts/typecheck-generated.mjs — all 15 clients pass
  • Verified default behavior unchanged for configs that don't set the new fields (no unrelated snapshot diff)
  • NodeNext smoke test confirms getImportExtension is applied to the consolidated faker dependency

Summary by CodeRabbit

  • New Features

    • Emit consolidated per-schema Faker factories and per-operation response factories (configurable via new schemas / operationResponses options).
    • Added deterministic seeding, partial-overrides, locale/content-type controls, and an index/aggregator for schema faker files (supports tags-split dynamic imports).
  • Documentation

    • New Faker guide with configuration, filename/output conventions, override scoping, usage examples (tests, Storybook, seed scripts).
    • MSW guide updated to reference Faker usage and preferred mock.generators form.

Review Change Stack

Adds `schemas` and `operationResponses` options to the faker mock
generator. When `schemas: true`, orval emits a consolidated
`index.faker.ts` alongside the generated schema types with one
`get<SchemaName>Mock()` factory per `components/schemas` entry —
useful for unit tests, Storybook stories, and seed scripts that
don't need MSW handlers. Splits the Validation & Mocking docs into
separate MSW and Faker pages.
@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3ddd672d-59b5-4ea5-bb3f-bdc72db34f08

📥 Commits

Reviewing files that changed from the base of the PR and between 0801597 and 4177de8.

📒 Files selected for processing (4)
  • docs/content/docs/guides/faker.mdx
  • packages/core/src/writers/generate-imports-for-builder.ts
  • packages/mock/src/faker/resolvers/value.ts
  • packages/orval/src/write-specs.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/content/docs/guides/faker.mdx

📝 Walkthrough

Walkthrough

Adds Faker generator docs, new FakerMockOptions flags, a generateFakerForSchemas API, $ref delegation to schema-level faker factories, import/writer routing for consolidated schema factories, write-pipeline integration, client filtering for operationResponses, and test fixtures/snapshots demonstrating output.

Changes

Faker Schema Mock Generation Feature

Layer / File(s) Summary
Documentation and Type Contracts
docs/content/docs/guides/faker.mdx, docs/content/docs/guides/msw.mdx, docs/content/docs/guides/meta.json, packages/core/src/types.ts
Adds Faker guide and MSW pointer; FakerMockOptions gains schemas and operationResponses; GeneratorImport gains schemaFactory flag.
Faker Generation Core API
packages/mock/src/faker/index.ts, packages/mock/src/index.ts
Adds generateFakerForSchemas and GenerateFakerForSchemasResult; updates DEFAULT_FAKER_OPTIONS and re-exports generator APIs.
Mock Value Resolution and Schema Delegation
packages/mock/src/faker/resolvers/value.ts
resolveMockValue can delegate $ref to consolidated get<SchemaName>Mock factories when schemas are emitted and overrides do not target referenced-schema properties; handles object-like spread, nullability wrapping, and import registration.
Import Consolidation and Writer Helpers
packages/core/src/writers/generate-imports-for-builder.ts, packages/core/src/writers/index.ts
Collects schemaFactory imports and consolidates them into an index.faker dependency; adds barrel export for ./file.
Write Pipeline Integration & Client Filtering
packages/orval/src/write-specs.ts, packages/orval/src/client.ts
Adds writeFakerSchemaMocks to emit consolidated schema faker files and reroute imports; generateOperations filters faker generators when operationResponses === false.
Test Configs & Fixtures
tests/configs/mock.config.ts, tests/specifications/faker-schemas-string-enum-ref.yaml
Adds three mock configurations and an OpenAPI fixture demonstrating enum $ref behavior for faker generation.
Generated Test Snapshots
tests/__snapshots__/mock/petstore-faker-schemas*/, tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/
Many generated snapshots showing clients, models, and faker schema factories (e.g., getPetMock, index.faker.ts, per-tag files).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • melloware

Poem

🐰 In meadows of types the faker hops,

factories bloom with tiny props.
From $ref to schema, mock seeds sow,
deterministic carrots in neat rows. 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.54% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main feature being added: faker schema mock generation with new configuration options.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@melloware melloware added the mock Related to mock generation label May 22, 2026
@melloware melloware added this to the 8.13.0 milestone May 22, 2026
jakiestfu added 5 commits May 22, 2026 12:09
When `schemas: true` and `operationResponses: true` are both set on the
faker generator, operation-response factories now call `get<X>Mock()`
for every `#/components/schemas/X` they reference instead of inlining
the body. Falls back to inlining when an operation- or tag-level
override touches a property of the referenced schema, so existing
override semantics keep working.

Also delegates `oneOf` discriminator arms that are themselves
top-level schema refs (e.g. `Dog`/`Cat`) — those now resolve to
`getDogMock()`/`getCatMock()` rather than emitting per-operation
helper factories.
When a schema referenced via \$ref is a string-typed enum, the
faker generator emits a runtime call (Object.values(EnumName)) for
its value. The consolidated schemas-faker file was importing such
names as type-only, producing TS1361 ('X' cannot be used as a value
because it was imported using 'import type').

Two fixes in the schemas-faker emission path:

- generateFakerForSchemas: dedupe imports by name+alias with an
  "any value wins" merge so a value-position usage upgrades a
  type-only push to a value import. addDependency then emits a
  single `import { Foo }` line that works in both annotation and
  runtime positions.

- writeFakerSchemaMocks: route value-flagged imports through the
  same schemaImportPath as type imports so they reach
  generateDependencyImports with the correct dependency string.

Also drops self-import of `get<Schema>Mock` when the delegation
logic references a factory defined in the same file.

Adds a tags-split repro config exercising the failure mode.
@jakiestfu
jakiestfu marked this pull request as ready for review May 22, 2026 21:32
@jakiestfu

Copy link
Copy Markdown
Contributor Author

@melloware This PR is ready for review. I will listen to the rabbit.

It allows optional schema mock data generation. In addition, if schema and operation mocks are both being generated, the operations will reuse the schema mock generator functions under-the-hood.

@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: 6

🧹 Nitpick comments (3)
tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/index.faker.ts (1)

77-81: 💤 Low value

Consider simplifying the array generation pattern.

The getPetsMock function creates an intermediate array of numbers that are immediately discarded. Array.from accepts a mapFn as its second parameter, so you can generate pets directly:

 export const getPetsMock = (): Pets =>
   Array.from(
     { length: faker.number.int({ min: 1, max: 10 }) },
-    (_, i) => i + 1,
-  ).map(() => ({ ...getPetMock() }));
+    () => ({ ...getPetMock() })
+  );

Since this is generated test code, the performance impact is negligible—this is purely a stylistic simplification.

🤖 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/__snapshots__/mock/petstore-faker-schemas-and-ops/model/index.faker.ts`
around lines 77 - 81, The getPetsMock function currently builds an intermediate
numeric array then maps to pets; simplify by using Array.from's mapFn directly
to produce pet objects without creating and discarding the index array—update
getPetsMock to call Array.from with the same length from faker.number.int and
provide a mapFn that returns {...getPetMock()} (keeping the return type Pets) so
the implementation is more concise while preserving behavior.
tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/default/default.faker.ts (1)

20-23: 💤 Low value

Consider optimizing the nested arrayElement pattern in the generator.

The nested faker.helpers.arrayElement calls could be flattened to faker.helpers.arrayElement([...Object.values(DisplayColor), undefined]) for better readability and performance. Since this is generated test code validating the feature's behavior, the current pattern is acceptable, but the generator could potentially be optimized.

🤖 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/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/default/default.faker.ts`
around lines 20 - 23, The code uses a nested faker.helpers.arrayElement call for
generating "color" which is unnecessary; replace the nested pattern
(faker.helpers.arrayElement([
faker.helpers.arrayElement(Object.values(DisplayColor)), undefined, ])) with a
single flattening call that picks from the combined list (i.e., use
faker.helpers.arrayElement over an array containing
...Object.values(DisplayColor) and undefined) so the generator uses
faker.helpers.arrayElement once and directly references DisplayColor values for
clarity and minor perf gain.
tests/__snapshots__/mock/petstore-faker-schemas/model/pet.ts (1)

12-30: 💤 Low value

Consider optimizing the generator to factor out common intersection properties.

Both union arms intersect with identical properties, creating duplication. The type could be simplified to (Dog | Cat) & { common props }. Since this is a generated test snapshot, the current output may be intentional for validation, but the generator could potentially be optimized to produce more concise types when union arms share identical intersections.

🤖 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/__snapshots__/mock/petstore-faker-schemas/model/pet.ts` around lines 12
- 30, The generated Pet type repeats the same intersection properties for both
union arms (Dog & {...} and Cat & {...}); update the generator logic that builds
the Pet type so it detects identical intersection property sets and factors them
out into a single intersection: (Dog | Cat) & { '`@id`'?: string; id: number;
name: string; tag?: string; email?: string; callingCode?: PetCallingCode;
country?: PetCountry; }; locate the code that assembles union members for the
Pet model (where Dog and Cat are combined) and change it to compute the shared
property intersection and emit one combined type instead of duplicating the same
object literal for each union arm.
🤖 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/guides/faker.mdx`:
- Around line 46-49: Update the "Response Factories" section that currently
asserts Orval always emits get<OperationId>ResponseMock factories to reflect the
new faker options: document the two new toggles named schemas and
operationResponses under the faker options table and explain that per-operation
response factory emission is conditional on operationResponses (and schema-based
generation is affected by schemas). Add a short example or note showing how to
enable/disable these options and update the same wording in the repeated block
(lines referenced 88-94) so users can discover and configure schemas and
operationResponses.

In `@packages/core/src/writers/generate-imports-for-builder.ts`:
- Around line 21-33: The schemaFactory branch currently hardcodes the dependency
path to upath.joinSafe(relativeSchemasPath, 'index.faker') which omits the
runtime file extension used by getImportExtension(); update the
schemaFactoryDeps construction (where schemaFactoryImports and schemaFactoryDeps
are defined) to append the result of getImportExtension() (same way the
per-schema branch does) to the 'index.faker' filename so the dependency passed
into from '${dependency}' includes the correct NodeNext/Node16 extension for
ESM/Node compatibility.

In `@packages/mock/src/faker/resolvers/value.ts`:
- Around line 67-77: The function shouldDelegateToSchemaFactories incorrectly
bases delegation on any faker generator in context.output.mock.generators;
change it to consult only the active faker entry for the current
resolveMockValue invocation (or enforce a single faker entry) so that delegation
respects the current entry's schemas flag and locale/options; update
shouldDelegateToSchemaFactories to accept the current generator or resolver
context (instead of scanning context.output.mock.generators), check that the
current generator has type OutputMockType.FAKER and schemas === true, and return
false otherwise; adjust call sites (e.g., resolveMockValue) to pass the active
generator or validate there that multiple faker entries are disallowed.
- Around line 99-128: hasOverrideTouchingSchema currently only checks bare
property names and regex keys, so overrides that target a referenced property by
exact-path (the "#.<path>" form) won't be detected; update
hasOverrideTouchingSchema to accept the current schema path (string) or
otherwise obtain the same path used by resolveMockOverride and, when iterating
override bucket keys, also treat keys that start with "#." as exact-path matches
using the same matching logic as resolveMockOverride (i.e., compare "#."+keyPath
=== path or the same normalization used there) before returning false so
path-targeted overrides are detected and prevent delegation to get<Schema>Mock.

In `@packages/orval/src/write-specs.ts`:
- Around line 157-163: The current logic picks the first Faker generator via the
finder assigned to fakerEntry and returns undefined unless that first entry has
schemas:true, which mismatches the resolver and generateOperations that expect
any faker entry with schemas:true; update the lookup to find the first generator
where g.type === OutputMockType.FAKER and g.schemas === true (instead of the
first FAKER regardless of schemas) so refs only delegate when an opted-in faker
is present, or alternatively enforce/validate that only one faker generator is
allowed; update the code referencing fakerEntry, OutputMockType.FAKER, schemas,
and the get<Schema>Mock()/generateOperations() workflow to use the found
opted-in entry.
- Around line 198-206: The fallback logic in write-specs.ts sets
schemaImportPath = `./${targetInfo.filename}` using a filename that has had its
extension stripped by getFileInfo(..., { extension: fileExtension }), which
yields extensionless local imports that break NodeNext/Node16; fix by importing
getImportExtension from '`@orval/core`' and append
getImportExtension(fileExtension, output.tsconfig) to schemaImportPath when
targetInfo exists (i.e., compute schemaImportPath =
`./${targetInfo.filename}${getImportExtension(fileExtension, output.tsconfig)}`)
so the generated import includes the correct extension.

---

Nitpick comments:
In
`@tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/index.faker.ts`:
- Around line 77-81: The getPetsMock function currently builds an intermediate
numeric array then maps to pets; simplify by using Array.from's mapFn directly
to produce pet objects without creating and discarding the index array—update
getPetsMock to call Array.from with the same length from faker.number.int and
provide a mapFn that returns {...getPetMock()} (keeping the return type Pets) so
the implementation is more concise while preserving behavior.

In `@tests/__snapshots__/mock/petstore-faker-schemas/model/pet.ts`:
- Around line 12-30: The generated Pet type repeats the same intersection
properties for both union arms (Dog & {...} and Cat & {...}); update the
generator logic that builds the Pet type so it detects identical intersection
property sets and factors them out into a single intersection: (Dog | Cat) & {
'`@id`'?: string; id: number; name: string; tag?: string; email?: string;
callingCode?: PetCallingCode; country?: PetCountry; }; locate the code that
assembles union members for the Pet model (where Dog and Cat are combined) and
change it to compute the shared property intersection and emit one combined type
instead of duplicating the same object literal for each union arm.

In
`@tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/default/default.faker.ts`:
- Around line 20-23: The code uses a nested faker.helpers.arrayElement call for
generating "color" which is unnecessary; replace the nested pattern
(faker.helpers.arrayElement([
faker.helpers.arrayElement(Object.values(DisplayColor)), undefined, ])) with a
single flattening call that picks from the combined list (i.e., use
faker.helpers.arrayElement over an array containing
...Object.values(DisplayColor) and undefined) so the generator uses
faker.helpers.arrayElement once and directly references DisplayColor values for
clarity and minor perf gain.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 70885d25-173f-44a6-85d6-9a3d7f86a4c0

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc03f3 and 0801597.

📒 Files selected for processing (62)
  • docs/content/docs/guides/faker.mdx
  • docs/content/docs/guides/meta.json
  • docs/content/docs/guides/msw.mdx
  • packages/core/src/types.ts
  • packages/core/src/writers/generate-imports-for-builder.ts
  • packages/core/src/writers/index.ts
  • packages/mock/src/faker/index.ts
  • packages/mock/src/faker/resolvers/value.ts
  • packages/mock/src/index.ts
  • packages/orval/src/client.ts
  • packages/orval/src/write-specs.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/endpoints.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/cat.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/catType.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/createPetsBody.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/createPetsParams.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/createPetsSort.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/dachshund.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/dachshundBreed.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/dog.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/dogType.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/error.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/index.faker.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/index.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/labradoodle.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/labradoodleBreed.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/listPetsParams.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/listPetsSort.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/pet.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/petCallingCode.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/petCountry.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/petWithTag.ts
  • tests/__snapshots__/mock/petstore-faker-schemas-and-ops/model/pets.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/endpoints.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/cat.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/catType.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/createPetsBody.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/createPetsParams.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/createPetsSort.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/dachshund.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/dachshundBreed.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/dog.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/dogType.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/error.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/index.faker.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/index.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/labradoodle.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/labradoodleBreed.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/listPetsParams.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/listPetsSort.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/pet.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/petCallingCode.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/petCountry.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/petWithTag.ts
  • tests/__snapshots__/mock/petstore-faker-schemas/model/pets.ts
  • tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/default/default.faker.ts
  • tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/default/default.ts
  • tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/index.schemas.ts
  • tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/index.ts
  • tests/__snapshots__/mock/string-enum-ref-faker-schemas-tags-split/schemas.faker.ts
  • tests/configs/mock.config.ts
  • tests/specifications/faker-schemas-string-enum-ref.yaml

Comment thread docs/content/docs/guides/faker.mdx
Comment thread packages/core/src/writers/generate-imports-for-builder.ts
Comment thread packages/mock/src/faker/resolvers/value.ts Outdated
Comment thread packages/mock/src/faker/resolvers/value.ts
Comment thread packages/orval/src/write-specs.ts
Comment thread packages/orval/src/write-specs.ts Outdated
- Append getImportExtension to the consolidated index.faker dependency
  so NodeNext/Node16 resolution gets the local-file extension. Also
  fix the same omission on the fallback schemaImportPath when
  output.schemas isn't configured.
- Reuse resolveMockOverride in hasOverrideTouchingSchema so #.path-form
  overrides (e.g. '#.color.value') block delegation, mirroring the
  matching rules the rest of the faker pipeline already honors.
- Tighten the fakerEntry lookup in writeFakerSchemaMocks and
  shouldDelegateToSchemaFactories to find the opted-in faker entry
  (schemas: true) directly rather than the first faker entry, so the
  resolver and writer stay aligned even if the duplicate-type guard
  in normalizeMocksOption ever loosens.
- Document the new schemas and operationResponses options in the
  Faker guide, including a Schema Factories subsection and table rows.
@jakiestfu

Copy link
Copy Markdown
Contributor Author

Re: CodeRabbit nitpicks

Skipping the 3 nitpicks from the review body — they all target output that's emitted by orval's core mock pipeline, not anything this PR introduces. Changing them would churn unrelated snapshots and belongs in a separate PR.

1. Array.from({length}, (_, i) => i + 1).map(() => ...)Array.from({length}, () => ...)
(tests/__snapshots__/.../petstore-faker-schemas-and-ops/model/index.faker.ts:77-81)

This pattern is emitted by getMockScalar for every array-shaped OpenAPI schema across orval, not just the new schemas-faker output. Changing the generator would update dozens of unrelated .faker.ts / .msw.ts snapshots and is out of scope.

2. (Dog & {...}) | (Cat & {...})(Dog | Cat) & {...} factoring
(tests/__snapshots__/.../petstore-faker-schemas/model/pet.ts:12-30)

This is the generated TypeScript schema type for Pet, not faker output. It comes from orval's core type generator, which is completely outside the faker pipeline this PR touches.

3. arrayElement([arrayElement(Object.values(X)), undefined])arrayElement([...Object.values(X), undefined])
(tests/__snapshots__/.../string-enum-ref-faker-schemas-tags-split/default/default.faker.ts:20-23)

The nested-arrayElement pattern is how getMockScalar represents nullable/optional $ref'd enums project-wide. Same churn argument as #1 — flattening it would touch unrelated faker snapshots.

Happy to file follow-up issues for any of these if maintainers think they're worth pursuing.

@jakiestfu

Copy link
Copy Markdown
Contributor Author

We've done some initial implementation at Turo as a proof-of-concept of using the schema mocks to replace hard-coded fixtures in our tests, it works very well 🎉

@melloware
melloware merged commit d5df441 into orval-labs:master May 23, 2026
6 checks passed
@jakiestfu

Copy link
Copy Markdown
Contributor Author

@melloware Any thoughts as to when this will land in the NPM registry? Erhm, 8.13.0?

@melloware

Copy link
Copy Markdown
Collaborator

@jakiestfu I will do it tomorrow!

@jakiestfu

Copy link
Copy Markdown
Contributor Author

@jakiestfu I will do it tomorrow!

Happy Memorial Day, thanks!

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

Labels

mock Related to mock generation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants