Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions .changeset/eager-mice-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-codegen/typed-document-node': patch
'@graphql-codegen/visitor-plugin-common': patch
---

Fix fragments not getting deduped when documentMode=graphQLTag
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export class ClientSideBaseVisitor<
return fragmentNames.map(document => this.getFragmentVariableName(document));
}

protected _includeFragments(fragments: string[]): string {
protected _includeFragments(fragments: string[], nodeKind: 'FragmentDefinition' | 'OperationDefinition'): string {
if (fragments && fragments.length > 0) {
if (this.config.documentMode === DocumentMode.documentNode || this.config.documentMode === DocumentMode.string) {
return Array.from(this._fragments.values())
Expand All @@ -334,6 +334,9 @@ export class ClientSideBaseVisitor<
if (this.config.documentMode === DocumentMode.documentNodeImportFragments) {
return '';
}
if (nodeKind !== 'OperationDefinition') {
return '';
}
return String(fragments.map(name => '${' + name + '}').join('\n'));
}

Expand All @@ -346,13 +349,15 @@ export class ClientSideBaseVisitor<

protected _gql(node: FragmentDefinitionNode | OperationDefinitionNode): string {
const includeNestedFragments =
this.config.documentMode === DocumentMode.documentNode || this.config.documentMode === DocumentMode.string;
this.config.documentMode === DocumentMode.documentNode ||
this.config.documentMode === DocumentMode.string ||
node.kind === 'OperationDefinition';
const fragmentNames = this._extractFragments(node, includeNestedFragments);
const fragments = this._transformFragments(fragmentNames);

const doc = this._prepareDocument(`
${print(node).split('\\').join('\\\\') /* Re-escape escaped values in GraphQL syntax */}
${this._includeFragments(fragments)}`);
${this._includeFragments(fragments, node.kind)}`);

if (this.config.documentMode === DocumentMode.documentNode) {
let gqlObj = gqlTag([doc]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Types } from '@graphql-codegen/plugin-helpers';
import { mergeOutputs, Types } from '@graphql-codegen/plugin-helpers';
import { DocumentMode } from '@graphql-codegen/visitor-plugin-common';
import { buildSchema, parse } from 'graphql';
import { plugin } from '../src/index.js';

Expand All @@ -9,6 +10,77 @@ describe('TypedDocumentNode', () => {
expect(result.prepend.length).toBe(0);
});

it('dedupes fragments automatically when documentMode=graphQLTag', async () => {
const schema = buildSchema(/* GraphQL */ `
type Query {
person(id: ID!): Person!
}
type Person {
id: ID!
name: String!
children: [Person!]
}
`);

const document = parse(/* GraphQL */ `
query Person {
person(id: 1) {
...PersonDetails
children {
...BasePersonDetails
}
}
}

fragment PersonDetails on Person {
...BasePersonDetails
name
}

fragment BasePersonDetails on Person {
id
}
`);

const result = mergeOutputs([
await plugin(
schema,
[{ document }],
{
documentMode: DocumentMode.graphQLTag,
},
{ outputFile: '' }
),
]);

expect(result).toMatchInlineSnapshot(`
"import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
import gql from 'graphql-tag';
export const BasePersonDetailsFragmentDoc = gql\`
fragment BasePersonDetails on Person {
id
}
\` as unknown as DocumentNode<BasePersonDetailsFragment, unknown>;
export const PersonDetailsFragmentDoc = gql\`
fragment PersonDetails on Person {
...BasePersonDetails
name
}
\` as unknown as DocumentNode<PersonDetailsFragment, unknown>;
export const PersonDocument = gql\`
query Person {
person(id: 1) {
...PersonDetails
children {
...BasePersonDetails
}
}
}
\${PersonDetailsFragmentDoc}
\${BasePersonDetailsFragmentDoc}\` as unknown as DocumentNode<PersonQuery, PersonQueryVariables>;"
`);
});

describe('addTypenameToSelectionSets', () => {
it('Check is add __typename to typed document', async () => {
const schema = buildSchema(/* GraphQL */ `
Expand Down