Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
3 changes: 3 additions & 0 deletions docs/content/docs/reference/configuration/output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ export default defineConfig({
|--------|------|---------|-------------|
| `type` | `'msw'` | required | Discriminator for MSW handler generation. |
| `path` | `String` | `undefined` | Output directory for this generator's mock files. Overrides the shared `mock.path` when set. When provided in `single` or `tags` mode, mock code is written to separate files (relative to `path`) instead of being inlined into the implementation file. |
| `operationResponses` | `Boolean` | `true` | Emit `get<Op>ResponseMock` factories in the MSW output. Set to `false` to generate handlers only, response fallbacks become `undefined`. No effect when a Faker generator also emits the factories, the handlers then import them from the `.faker` file. Honored in `split` and `tags-split` modes. |
| `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. |
Expand All @@ -631,6 +632,8 @@ export default defineConfig({

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.

In `split` and `tags-split` modes, configuring Faker alongside MSW moves the `get<Op>ResponseMock` factories to the `.faker` file. The `.msw` file only contains the handlers and imports (and re-exports) the factories instead of duplicating them.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `type` | `'faker'` | required | Discriminator for Faker-only output. |
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,10 @@ export interface CommonMockOptions {

export interface MswMockOptions extends CommonMockOptions {
type: typeof OutputMockType.MSW;
// Emit faker responses in MSW handler output, defaults to true. Disable to
// generate handlers only which require passing in mock responses, falls back
// to `undefined` if no mock response passed to handler.
operationResponses?: boolean;
// Base URL prefix for the generated MSW route matchers
baseUrl?: string;
// Response delay before MSW handlers resolve (false disables delay)
Expand Down
110 changes: 110 additions & 0 deletions packages/core/src/writers/generate-imports-for-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,116 @@ describe('generateImportsForBuilder', () => {
});
});

describe('imports with explicit importPath', () => {
it('should group imports with the same importPath into a single dependency', () => {
const output = createMockOutput({ indexFiles: false });
const imports: GeneratorImport[] = [
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
{
name: 'getUserResponseMock',
values: true,
importPath: './pets.faker',
},
];

const result = generateImportsForBuilder(output, imports, '../models');

expect(result).toEqual([
{
exports: [
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
{
name: 'getUserResponseMock',
values: true,
importPath: './pets.faker',
},
],
dependency: './pets.faker',
},
]);
});

it('should separate imports with different importPaths into different dependencies', () => {
const output = createMockOutput({ indexFiles: false });
const imports: GeneratorImport[] = [
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
{
name: 'getHealthResponseMock',
values: true,
importPath: './health.faker',
},
];

const result = generateImportsForBuilder(output, imports, '../models');

expect(result).toEqual([
{
exports: [
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
],
dependency: './pets.faker',
},
{
exports: [
{
name: 'getHealthResponseMock',
values: true,
importPath: './health.faker',
},
],
dependency: './health.faker',
},
]);
});

it('should deduplicate imports with the same name and importPath', () => {
const output = createMockOutput({ indexFiles: false });
const imports: GeneratorImport[] = [
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
];

const result = generateImportsForBuilder(output, imports, '../models');

expect(result).toEqual([
{
exports: [
{
name: 'getPetResponseMock',
values: true,
importPath: './pets.faker',
},
],
dependency: './pets.faker',
},
]);
});
});

describe('with importPath (package import specifier)', () => {
it('should use package import path with indexFiles', () => {
const output = createMockOutput({
Expand Down
23 changes: 16 additions & 7 deletions packages/core/src/writers/generate-imports-for-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,26 @@ export function generateImportsForBuilder(
);
}

const otherImports = uniqueBy(
const otherImportsMap = new Map<string, GeneratorImport[]>();
for (const imp of uniqueBy(
imports.filter(
(i): i is GeneratorImport & { importPath: string } => !!i.importPath,
),
(x) => x.name + x.importPath,
).map<GeneratorDependency>((i) => {
return {
exports: [i],
dependency: i.importPath,
};
});
)) {
const existing = otherImportsMap.get(imp.importPath);
if (existing) {
existing.push(imp);
} else {
otherImportsMap.set(imp.importPath, [imp]);
}
}
const otherImports = [...otherImportsMap.entries()].map<GeneratorDependency>(
([dependency, exports]) => ({
exports,
dependency,
}),
);

return [...schemaImports, ...schemaFactoryDeps, ...otherImports];
}
Expand Down
Loading