diff --git a/.changeset/strange-eggs-attack.md b/.changeset/strange-eggs-attack.md new file mode 100644 index 00000000000..65bed4b3d37 --- /dev/null +++ b/.changeset/strange-eggs-attack.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/client-preset': patch +--- + +Include nested fragments in string documentMode diff --git a/packages/plugins/other/visitor-plugin-common/src/client-side-base-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/client-side-base-visitor.ts index 423cc70a127..bd2e001dbdf 100644 --- a/packages/plugins/other/visitor-plugin-common/src/client-side-base-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/client-side-base-visitor.ts @@ -358,6 +358,7 @@ export class ClientSideBaseVisitor< protected _gql(node: FragmentDefinitionNode | OperationDefinitionNode): string { const includeNestedFragments = this.config.documentMode === DocumentMode.documentNode || + this.config.documentMode === DocumentMode.string || (this.config.dedupeFragments && node.kind === 'OperationDefinition'); const fragmentNames = this._extractFragments(node, includeNestedFragments); const fragments = this._transformFragments(fragmentNames); diff --git a/packages/presets/client/tests/client-preset.spec.ts b/packages/presets/client/tests/client-preset.spec.ts index 9d92a26301b..4e074a72f0e 100644 --- a/packages/presets/client/tests/client-preset.spec.ts +++ b/packages/presets/client/tests/client-preset.spec.ts @@ -2423,5 +2423,94 @@ export * from "./gql.js";`); " `); }); + + it('correctly resolves nested fragments', async () => { + const result = await executeCodegen({ + schema: [ + /* GraphQL */ ` + scalar Date + + type Query { + video(id: ID!): Video! + } + + interface Video { + id: ID! + title: String! + } + + type Movie implements Video { + id: ID! + title: String! + releaseDate: Date! + collection: Collection + } + + type Collection { + id: ID! + title: String! + } + + type Episode implements Video { + id: ID! + title: String! + show: Show! + releaseDate: Date! + } + + type Show { + id: ID! + title: String! + releaseDate: Date! + } + `, + ], + documents: path.join(__dirname, 'fixtures/with-nested-fragment.ts'), + generates: { + 'out1/': { + preset, + config: { + documentMode: 'string', + }, + }, + }, + }); + + const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); + expect(graphqlFile.content).toBeSimilarStringTo(` + export const VideoDocument = new TypedDocumentString(\` + query Video($id: ID!) { + video(id: $id) { + ...DetailsFragment + __typename + } + } + fragment EpisodeFragment on Episode { + id + title + show { + id + title + } + releaseDate + __typename + } + fragment MovieFragment on Movie { + id + title + collection { + id + } + releaseDate + __typename + } + fragment DetailsFragment on Video { + title + __typename + ...MovieFragment + ...EpisodeFragment + }\`) as unknown as TypedDocumentString; + `); + }); }); }); diff --git a/packages/presets/client/tests/fixtures/with-nested-fragment.ts b/packages/presets/client/tests/fixtures/with-nested-fragment.ts new file mode 100644 index 00000000000..375aea7679f --- /dev/null +++ b/packages/presets/client/tests/fixtures/with-nested-fragment.ts @@ -0,0 +1,48 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +//@ts-ignore +const episodeFragment = gql(/* GraphQL */ ` + fragment EpisodeFragment on Episode { + id + title + show { + id + title + } + releaseDate + __typename + } +`); + +//@ts-ignore +const movieFragment = gql(/* GraphQL */ ` + fragment MovieFragment on Movie { + id + title + collection { + id + } + releaseDate + __typename + } +`); + +//@ts-ignore +const videoDetailsFragment = gql(/* GraphQL */ ` + fragment DetailsFragment on Video { + title + __typename + ...MovieFragment + ...EpisodeFragment + } +`); + +//@ts-ignore +const videoQueryDocument = gql(/* GraphQL */ ` + query Video($id: ID!) { + video(id: $id) { + ...DetailsFragment + __typename + } + } +`);