dotansimha / dotansimha/graphql-code-generator

Generate mock query with `fragment-masking`

Open
#9,687 1 comment 7 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
11.3k
Forks
1.4k
Avg merge
1d 1h
Merged PRs (30d)
23

Description

### 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

1. add type for reveal fragment-masking
sample code is here
```ts
type FragmentRef = { " $fragmentRefs"?: { [key in string]: any } } | null;

export type FragmentRevealer = Omit & T extends {
" $fragmentRefs"?: { [key in string]: infer TFragment };
}
? TFragment extends { " $fragmentName"?: string }
? Omit
: TFragment
: T;

export type QueryRevealer = {
[Key in keyof T]: FragmentRevealer;
};

// query wrapping
export const mockTeamCardQuery = (
resolver: ResponseResolver<
GraphQLRequest,
GraphQLContext>,
any
>,
) => graphql.query, 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",
},
},
},
}),
);
}),
```

2. add `fragment-revealer` option to `typescript-mock-data` config
add config if you adopt above type `QueryRevealer` to `mockXXXQuery`s 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
```ts
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,
GraphQLContext,
any
>,
) => graphql.query("TeamCard", resolver);
```

I can use query mock like below
```ts
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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.