Skip to content

Commit f06563b

Browse files
authored
fix(mock): use indexed access types for inline enum properties in MSW mocks (orval-labs#3224)
When enumGenerationType is 'enum', MSW mock generator imported inline enum properties using the raw property name (e.g., countryCode) which did not exist in the model. The model generates PascalCase enum names (e.g., UserCountryCode), causing TS2305 compilation errors. The fix conditionally propagates the response's isRef flag to getMockScalar only when enumGenerationType is 'enum'. This ensures the parent type name is added to existingReferencedProperties, so getEnum() generates indexed access types (e.g., User['countryCode']) instead of using the non-existent property name as a type. The condition is scoped to enumGenerationType 'enum' to avoid affecting circular reference detection in default (const) mode. Fixes: orval-labs#3223
1 parent f0dd0f3 commit f06563b

14 files changed

Lines changed: 361 additions & 1 deletion

File tree

packages/mock/src/msw/mocks.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export function getResponsesMockDefinition({
204204
};
205205

206206
for (const response of responses) {
207-
const { value: definition, example, examples, imports } = response;
207+
const { value: definition, example, examples, imports, isRef } = response;
208208
let { originalSchema } = response;
209209

210210
if (context.output.override.mock?.useExamples || mockOptions?.useExamples) {
@@ -246,6 +246,9 @@ export function getResponsesMockDefinition({
246246
item: {
247247
...(resolvedSchema as Record<string, unknown>),
248248
name: definition,
249+
...(context.output.override.enumGenerationType === 'enum' && isRef
250+
? { isRef: true }
251+
: {}),
249252
},
250253
imports,
251254
mockOptions: mockOptionsWithoutFunc,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
9+
export * from './template';
10+
export * from './templateCategory';
11+
export * from './templateStatus';
12+
export * from './user';
13+
export * from './userCountryCode';
14+
export * from './userLanguage';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
import type { TemplateCategory } from './templateCategory';
9+
import type { TemplateStatus } from './templateStatus';
10+
11+
export interface Template {
12+
id: number;
13+
status?: TemplateStatus;
14+
category?: TemplateCategory;
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
9+
export enum TemplateCategory {
10+
SOFTWARE = 'SOFTWARE',
11+
CREATIVE = 'CREATIVE',
12+
BUSINESS = 'BUSINESS',
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
9+
export enum TemplateStatus {
10+
DRAFT = 'DRAFT',
11+
PUBLISHED = 'PUBLISHED',
12+
ARCHIVED = 'ARCHIVED',
13+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
import type { UserCountryCode } from './userCountryCode';
9+
import type { UserLanguage } from './userLanguage';
10+
11+
export interface User {
12+
id: number;
13+
name: string;
14+
/** country code */
15+
countryCode?: UserCountryCode;
16+
language?: UserLanguage;
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
9+
/**
10+
* country code
11+
*/
12+
export enum UserCountryCode {
13+
US = 'US',
14+
JP = 'JP',
15+
DE = 'DE',
16+
FR = 'FR',
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
9+
export enum UserLanguage {
10+
EN = 'EN',
11+
JP = 'JP',
12+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
import { faker } from '@faker-js/faker';
9+
10+
import { HttpResponse, http } from 'msw';
11+
import type { RequestHandlerOptions } from 'msw';
12+
13+
import type { Template } from '../model';
14+
15+
export const getGetTemplateResponseMock = (
16+
overrideResponse: Partial<Extract<Template, object>> = {},
17+
): Template => ({
18+
id: faker.number.int(),
19+
status: faker.helpers.arrayElement([
20+
faker.helpers.arrayElement([
21+
'DRAFT',
22+
'PUBLISHED',
23+
'ARCHIVED',
24+
] as Template['status'][]),
25+
undefined,
26+
]),
27+
category: faker.helpers.arrayElement([
28+
faker.helpers.arrayElement([
29+
'SOFTWARE',
30+
'CREATIVE',
31+
'BUSINESS',
32+
] as Template['category'][]),
33+
undefined,
34+
]),
35+
...overrideResponse,
36+
});
37+
38+
export const getGetTemplateMockHandler = (
39+
overrideResponse?:
40+
| Template
41+
| ((
42+
info: Parameters<Parameters<typeof http.get>[1]>[0],
43+
) => Promise<Template> | Template),
44+
options?: RequestHandlerOptions,
45+
) => {
46+
return http.get(
47+
'*/api/template',
48+
async (info: Parameters<Parameters<typeof http.get>[1]>[0]) => {
49+
return HttpResponse.json(
50+
overrideResponse !== undefined
51+
? typeof overrideResponse === 'function'
52+
? await overrideResponse(info)
53+
: overrideResponse
54+
: getGetTemplateResponseMock(),
55+
{ status: 200 },
56+
);
57+
},
58+
options,
59+
);
60+
};
61+
export const getTemplateMock = () => [getGetTemplateMockHandler()];
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Generated by orval v8.7.0 🍺
3+
* Do not edit manually.
4+
* Enums Inline
5+
* Test spec with inline (dereferenced) enum properties
6+
* OpenAPI spec version: 1.0.0
7+
*/
8+
import axios from 'axios';
9+
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
10+
11+
import type { Template } from '../model';
12+
13+
/**
14+
* @summary get template
15+
*/
16+
export const getTemplate = (
17+
options?: AxiosRequestConfig,
18+
): Promise<AxiosResponse<Template>> => {
19+
return axios.get(`/api/template`, options);
20+
};
21+
export type GetTemplateResult = AxiosResponse<Template>;

0 commit comments

Comments
 (0)