Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ff18a6d
refactor(core): split GlobalMockOptions into MswMockOptions and Faker…
jakiestfu May 20, 2026
d3c181a
refactor(core): add isMswMock and isFakerMock type guards
jakiestfu May 20, 2026
8613e9a
feat(mock): add faker generator and dispatch by OutputMockType
jakiestfu May 20, 2026
bcf19a4
refactor(core): emit one mock file per generators entry in writers
jakiestfu May 20, 2026
c8ed0cc
refactor(orval): normalize output.mocks and dispatch per generator entry
jakiestfu May 20, 2026
720f946
refactor(integrations): read output.mocks instead of output.mock
jakiestfu May 20, 2026
6c17dce
chore(configs): migrate test and sample configs from mock to mocks
jakiestfu May 20, 2026
48b530b
fix(core): collapse inline mock outputs to drop duplicate faker facto…
jakiestfu May 20, 2026
d86f99d
chore(snapshots): add faker mock snapshots for samples and tests
jakiestfu May 20, 2026
9e32055
test(mock): add faker generator tests and discriminated union type gu…
jakiestfu May 20, 2026
f4182bb
docs: rewrite mock configuration reference and msw guide for output.m…
jakiestfu May 20, 2026
9d27f72
fix(lint): resolve eslint errors in mock index and core writers
jakiestfu May 20, 2026
f09ccb5
refactor(core): rename output.mocks option key back to output.mock
jakiestfu May 20, 2026
1eead06
chore(configs): rename mocks to mock in all test and sample configs
jakiestfu May 20, 2026
6401c6e
docs: rename mocks to mock in all doc examples, fix stale comments, a…
jakiestfu May 20, 2026
c16f788
refactor(core): fix stale mocks: true comment references to mock: true
jakiestfu May 20, 2026
74fe6d6
fix(core): reject duplicate mock generator types during normalization
jakiestfu May 20, 2026
60bb3ba
docs(v8): rewrite mock migration section to reference actual v7 API s…
jakiestfu May 20, 2026
2b7e01c
fix(core): rename mocks to mock in remaining package test files
jakiestfu May 20, 2026
d02ce24
fix(docs): fix stale mocks.indexMockFiles reference and update type c…
jakiestfu May 20, 2026
8e70924
fix(core): look up mock generators by type instead of index in writers
jakiestfu May 20, 2026
881e03c
fix(core): reject function mock generators early in tags-split mode
jakiestfu May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/content/docs/guides/client-with-zod.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ src/api/
│ └── pets/
│ ├── pets.ts # SWR hooks
│ ├── pets.msw.ts # MSW mocks
│ ├── pets.faker.ts # Faker mocks
│ └── pets.zod.ts # Zod schemas
└── models/
└── ...
Expand Down
48 changes: 36 additions & 12 deletions docs/content/docs/guides/msw.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,12 @@ export default defineConfig({
petstore: {
output: {
mock: {
type: 'msw',
preferredContentType: 'application/json',
generators: [
{
type: 'msw',
preferredContentType: 'application/json',
},
],
},
},
},
Expand Down Expand Up @@ -213,15 +217,19 @@ expect(mockFn).toHaveBeenCalledWith('123');

## Base URL

By default, handlers use a wildcard `*` prefix (e.g. `*/pets/:petId`) so they match any host. To use a specific base URL, set `mock.baseUrl`:
By default, handlers use a wildcard `*` prefix (e.g. `*/pets/:petId`) so they match any host. To use a specific base URL, set `baseUrl` on the MSW generator entry:

```ts title="orval.config.ts"
export default defineConfig({
petstore: {
output: {
mock: {
type: 'msw',
baseUrl: 'https://api.example.com',
generators: [
{
type: 'msw',
baseUrl: 'https://api.example.com',
},
],
},
},
},
Expand All @@ -232,7 +240,21 @@ This produces handlers like `http.get('https://api.example.com/pets/:petId', ...

## Dynamic Imports

Enable `indexMockFiles` to dynamically import all handlers:
Enable `mock.indexMockFiles` to emit a root-level `index.<ext>.ts` file for each generator entry in `tags-split` mode. The MSW entry produces an `index.msw.ts` that can be dynamically imported:

```ts title="orval.config.ts"
export default defineConfig({
petstore: {
output: {
mode: 'tags-split',
mock: {
indexMockFiles: true,
generators: [{ type: 'msw' }],
},
},
},
});
```

```ts
// node.ts
Expand All @@ -245,31 +267,33 @@ const server = setupServer(...handlers);
export { server };
```

## Data Generators Only
If both `msw` and `faker` generators are configured with `indexMockFiles: true`, you also get an `index.faker.ts` alongside `index.msw.ts`.

## Faker-only Output

If you only need mock data factories without MSW request handlers, set `generateHandlers` to `false`:
If you only need mock data factories without MSW request handlers, use a `faker` generator entry. It emits the same `get<OperationId>ResponseMock` factory functions, but with no `msw` import or HTTP handler code:

```ts title="orval.config.ts"
export default defineConfig({
petstore: {
output: {
mock: {
type: 'msw',
generateHandlers: false,
generators: [{ type: 'faker' }],
},
},
},
});
```

This generates only the `get<OperationId>ResponseMock` functions (powered by Faker.js) — no MSW handlers, no aggregated handler array, and no `msw` dependency in the output. Your project only needs `@faker-js/faker` as a dependency.
The output is written to `<filename>.faker.ts` and only depends on `@faker-js/faker`. Useful for:

This is useful when you want mock data for:
- Unit tests with custom assertion libraries
- Storybook stories
- Seed scripts
- Any test setup that doesn't use MSW

You can combine both generators (e.g. `generators: [{ type: 'msw' }, { type: 'faker' }]`) to emit both files in the same run.

## MSW Best Practices

The generated code follows [MSW best practices](https://mswjs.io/docs/best-practices):
Expand Down
82 changes: 46 additions & 36 deletions docs/content/docs/reference/configuration/output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ export default defineConfig({
**Type:** `Boolean | Object | Function`
**Default:** `false`

Generate MSW mocks with Faker.js:
Configures one or more mock generators. The shorthand `mock: true` enables both MSW and Faker mock files with default options:

```ts title="orval.config.ts"
export default defineConfig({
Expand All @@ -355,19 +355,30 @@ export default defineConfig({
});
```

### Mock Options
Each entry in `mock.generators` produces its own file (`<filename>.msw.ts`, `<filename>.faker.ts`, ...). Set `mock: false` (or omit it) to disable mock generation entirely.

### Mocks Options

```ts title="orval.config.ts"
export default defineConfig({
petstore: {
output: {
mock: {
type: 'msw',
delay: 1000,
useExamples: false,
generateEachHttpStatus: false,
baseUrl: '/api',
locale: 'en',
indexMockFiles: true,
generators: [
{
type: 'msw',
delay: 1000,
useExamples: false,
generateEachHttpStatus: false,
baseUrl: '/api',
locale: 'en',
},
{
type: 'faker',
useExamples: false,
},
],
},
},
},
Expand All @@ -376,41 +387,40 @@ export default defineConfig({

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `type` | `'msw'` | `'msw'` | Mock type |
| `generateHandlers` | `Boolean` | `true` | Generate MSW request handlers. Set to `false` for data generators only (no `msw` dependency needed). |
| `delay` | `Number \| Function \| false` | `false` | Response delay in ms |
| `delayFunctionLazyExecute` | `Boolean` | `false` | Execute delay function at runtime |
| `useExamples` | `Boolean` | `false` | Use OpenAPI examples |
| `generateEachHttpStatus` | `Boolean` | `false` | Generate mocks for all status codes |
| `baseUrl` | `String` | `''` | Base URL for handlers |
| `locale` | `String` | `'en'` | Faker.js locale |
| `indexMockFiles` | `Boolean` | `false` | In `tags-split` mode, emit one root-level `index.<ext>.ts` file per generator entry that re-exports the per-tag mocks (e.g. `index.msw.ts`, `index.faker.ts`). |
| `generators` | `Array<MockOptions \| Function>` | `[]` | One entry per output mock file. Each entry can be an object (`MockOptions`) or a custom `ClientMockBuilder` function. |

## indexFiles
### MSW generator (`type: 'msw'`)

**Type:** `Boolean`
**Default:** `true`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `type` | `'msw'` | required | Discriminator for MSW handler generation. |
| `delay` | `Number \| Function \| false` | `false` | Response delay in ms. |
| `delayFunctionLazyExecute` | `Boolean` | `false` | Execute delay function at runtime instead of at build time. |
| `baseUrl` | `String` | `''` | Base URL for the generated MSW handlers. |
| `useExamples` | `Boolean` | `false` | Use OpenAPI examples to seed response values. |
| `generateEachHttpStatus` | `Boolean` | `false` | Generate response factories for every documented status code. |
| `locale` | `String` | `'en'` | Faker.js locale. |
| `preferredContentType` | `String` | `undefined` | Preferred content type when an operation lists more than one. |

Generate `index.ts` files for schemas.
### Faker generator (`type: 'faker'`)

## indexMockFiles
The Faker generator emits the same `get<Op>ResponseMock` factories MSW would emit, but without any `msw` dependency or HTTP handler code. Useful for tests or stories that only need fake response data.

**Type:** `Boolean`
**Default:** `false`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `type` | `'faker'` | required | Discriminator for Faker-only output. |
| `useExamples` | `Boolean` | `false` | Use OpenAPI examples to seed response values. |
| `generateEachHttpStatus` | `Boolean` | `false` | Generate response factories for every documented status code. |
| `locale` | `String` | `'en'` | Faker.js locale. |
| `preferredContentType` | `String` | `undefined` | Preferred content type when an operation lists more than one. |

When `true` and `mode` is `tags-split`, creates an `index.msw.ts` with all mock exports:
## indexFiles

```ts title="orval.config.ts"
export default defineConfig({
petstore: {
output: {
mode: 'tags-split',
mock: {
indexMockFiles: true,
},
},
},
});
```
**Type:** `Boolean`
**Default:** `true`

Generate `index.ts` files for schemas.

## docs

Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/reference/integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const globalOptions: GlobalOptions = {

// Mock data generation
mock: true, // Enable mock data generation
// mock: { type: 'msw', delay: 1000 }, // Configure mock options
// mock: { generators: [{ type: 'msw', delay: 1000 }] }, // Configure mock options

// TypeScript configuration
tsconfig: './tsconfig.json', // Custom tsconfig path
Expand Down
50 changes: 50 additions & 0 deletions docs/content/docs/versions/v8.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,56 @@ export default defineConfig({
});
```

### 10. `output.mock` now uses a `generators` array

Previously, `output.mock` accepted either `true` or a flat options object (`{ type: 'msw', delay: 1000, locale: 'fr', ... }`). All options lived on a single object and `type: 'msw'` was the only supported type.

Now, `output.mock` wraps generator entries in a `generators` array. Each entry produces its own output file (e.g. `.msw.ts`, `.faker.ts`). This enables multiple independent mock generators from a single config.

#### `mock: true` behavior change

`mock: true` previously emitted only MSW handlers. It now emits **both** MSW handlers (`.msw.ts`) and Faker data factories (`.faker.ts`). To keep the old behavior (MSW only), use the explicit form:

```ts
output: {
mock: { generators: [{ type: 'msw' }] },
}
```

#### Migrating a flat options object

All per-generator options (`delay`, `useExamples`, `locale`, `baseUrl`, etc.) move inside the generator entry:

```diff
output: {
- mock: { type: 'msw', delay: 1000, useExamples: true, locale: 'fr' },
+ mock: {
+ generators: [{ type: 'msw', delay: 1000, useExamples: true, locale: 'fr' }],
+ },
}
```

#### `indexMockFiles` moves to the wrapper

`indexMockFiles` is now a collection-level option rather than a per-generator option:

```diff
output: {
- mock: { type: 'msw', indexMockFiles: true },
+ mock: { indexMockFiles: true, generators: [{ type: 'msw' }] },
}
```

#### New: Faker-only output

To generate only Faker data factories without MSW handlers:

```ts
output: {
mock: { generators: [{ type: 'faker' }] },
}
```

## Other Improvements

### Variable Expansion in Fetch Client Headers
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/src/http-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const createOutput = (
namingConvention: 'camelCase',
fileExtension: '.ts',
mode: 'single',
mock: undefined,
mock: { indexMockFiles: false, generators: [] },
override: {
operations: {},
tags: {},
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/src/http-resource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const createOutput = (
namingConvention: 'camelCase',
fileExtension: '.ts',
mode: 'single',
mock: undefined,
mock: { indexMockFiles: false, generators: [] },
override: {
operations: {},
tags: {},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/test-utils/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function createTestContextSpec({
namingConvention: NamingConvention.CAMEL_CASE,
fileExtension: '.ts',
mode: OutputMode.SINGLE,
mock: { indexMockFiles: false, generators: [] },
client: OutputClient.FETCH,
httpClient: OutputHttpClient.FETCH,
clean: false,
Expand Down
16 changes: 13 additions & 3 deletions packages/core/src/test-utils/split-modes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
NamingConvention,
type NormalizedOutputOptions,
OutputClient,
OutputMockType,
OutputMode,
type WriteSpecBuilder,
} from '../types';
Expand All @@ -18,9 +19,18 @@ export const createSplitModeOperation = (
overrides: Partial<GeneratorOperation> = {},
): GeneratorOperation => ({
imports: [],
importsMock: [],
implementation: '',
implementationMock: { function: '', handler: '', handlerName: 'mockHandler' },
mockOutputs: [
{
type: OutputMockType.MSW,
implementation: {
function: '',
handler: '',
handlerName: 'mockHandler',
},
imports: [],
},
],
tags: ['pets'],
operationName: 'listPets',
...overrides,
Expand Down Expand Up @@ -54,7 +64,7 @@ export const createSplitModeOutput = (
client: OutputClient.AXIOS,
httpClient: 'axios',
schemas: undefined,
mock: false,
mock: { indexMockFiles: false, generators: [] },
clean: false,
docs: false,
headers: false,
Expand Down
Loading
Loading