Generate mock query with `fragment-masking`
Is your feature request related to a problem? Please describe.
I want to generate mock data with fragment-masking and msw
related comminity plugin
- fragment-masking ( https://the-guild.dev/graphql/codegen/plugins/presets/preset-client )
- typescript-mock-data( https://the-guild.dev/graphql/codegen/plugins/typescript/typescript-mock-data )
Describe the solution you'd like
- add type for reveal fragment-masking sample code is here
type FragmentRef = { " $fragmentRefs"?: { [key in string]: any } } | null;
export type FragmentRevealer<T extends FragmentRef> = Omit<T, " $fragmentRefs"> & T extends {
" $fragmentRefs"?: { [key in string]: infer TFragment };
}
? TFragment extends { " $fragmentName"?: string }
? Omit<TFragment, " $fragmentName">
: TFragment
: T;
export type QueryRevealer<T extends { [key in string]: any }> = {
[Key in keyof T]: FragmentRevealer<T[Key]>;
};
// query wrapping
export const mockTeamCardQuery = (
resolver: ResponseResolver<
GraphQLRequest<TeamCardQueryVariables>,
GraphQLContext<QueryRevealer<TeamCardQuery>>,
any
>,
) => graphql.query<QueryRevealer<TeamCardQuery>, TeamCardQueryVariables>("TeamCard", resolver);
// I can define data without `$fragmentRef`
mockTeamCardQuery((req, res, ctx) => {
return res(
ctx.delay(1000),
ctx.data({
team: {
__typename: "Team",
id: 3,
uid: "11",
name: "Team",
},
currentUser: {
__typename: "User",
name: "User",
},
}),
);
}),
// if I don't use QueryRevealer, I need to define data like below
mockTeamCardQuery((req, res, ctx) => {
return res(
ctx.delay(1000),
ctx.data({
team: {
__typename: "Team",
id: 3,
" $fragmentRefs": {
TeamCardProfileFragment: {
__typename: "Team",
id: 1,
uid: "abc",
name: "TeamName",
},
},
},
currentUser: {
__typename: "User",
" $fragmentRefs": {
TeamCardUserFragment: {
__typename: "User",
name: "Me",
},
},
},
}),
);
}),
- add
fragment-revealeroption totypescript-mock-dataconfig add config if you adopt above typeQueryRevealertomockXXXQuerys type or not https://the-guild.dev/graphql/codegen/plugins/typescript/typescript-mock-data
Describe alternatives you've considered
No response
Is your feature request related to a problem? Please describe.
Thank you for amazing library!
I want to generate mock data for develop in local env by using msw.
To generate mock data, we can use below library typescript-mock-data.
https://the-guild.dev/graphql/codegen/plugins/typescript/typescript-mock-data
But, if I use the library with fragment-masking(including client-preset), I can't cache response because response type is different from defined type created by typescript-mock-data.
Generated mockQuery`s type is below
export type TeamCardProfileFragment = {
__typename?: "Team";
id: number;
uid: string;
name: string;
} & { " $fragmentName"?: "TeamCardProfileFragment" };
// query type
export type TeamCardQuery = {
__typename?: "Query";
team:
| ({ __typename?: "Team"; id: number } & {
" $fragmentRefs"?: { TeamCardProfileFragment: TeamCardProfileFragment };
})
| null;
};
// query mock
export const mockTeamCardQuery = (
resolver: ResponseResolver<
GraphQLRequest<TeamCardQueryVariables>,
GraphQLContext<TeamCardQuery>,
any
>,
) => graphql.query<TeamCardQuery, TeamCardQueryVariables>("TeamCard", resolver);
I can use query mock like below
mockTeamCardQuery((req, res, ctx) => {
return res(
ctx.delay(1000),
ctx.data({
team: {
__typename: "Team",
id: 3,
" $fragmentRefs": {
TeamCardProfileFragment: {
__typename: "Team",
id: 1,
uid: "abc",
name: "TeamName",
},
},
},
}),
);
}),
I can define mock like above, but graphql client ( urql ) doesn't cache mock response because the response is dfferent from expected response.
$fragmentRefs is used for improving type strictness on coding, so it is better to exclude $fragmentRefs from mock query's data.
To solve this problem, we need to fix some code in fragment-masking and typescript-mock-data.
I understand it might be a bit challenging, but I would appreciate it if you could consider it.
Did you manage to solve it by any chance ?