Skip to content

Commit

Permalink
fix: prevent duplicate operations (#6662)
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloSzx authored Sep 11, 2021
1 parent cc37961 commit 5394f19
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changeset/smooth-otters-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-codegen/gql-tag-operations': patch
'@graphql-codegen/gql-tag-operations-preset': patch
---

prevent duplicate operations
12 changes: 6 additions & 6 deletions packages/plugins/typescript/gql-tag-operations/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,29 @@ export const plugin: PluginFunction<{
};

function getDocumentRegistryChunk(sourcesWithOperations: Array<SourceWithOperations> = []) {
const lines: Array<string> = [];
lines.push(`const documents = {\n`);
const lines = new Set<string>();
lines.add(`const documents = {\n`);

for (const { operations, ...rest } of sourcesWithOperations) {
const originalString = rest.source.rawSDL!;
const operation = operations[0];

lines.push(` ${JSON.stringify(originalString)}: graphql.${operation.initialName},\n`);
lines.add(` ${JSON.stringify(originalString)}: graphql.${operation.initialName},\n`);
}

lines.push(`};\n`);
lines.add(`};\n`);

return lines;
}

function getGqlOverloadChunk(sourcesWithOperations: Array<SourceWithOperations>) {
const lines: Array<string> = [];
const lines = new Set<string>();

// We intentionally don't use a <T extends keyof typeof documents> generic, because TS
// would print very long `gql` function signatures (duplicating the source).
for (const { operations, ...rest } of sourcesWithOperations) {
const originalString = rest.source.rawSDL!;
lines.push(
lines.add(
`export function gql(source: ${JSON.stringify(originalString)}): (typeof documents)[${JSON.stringify(
originalString
)}];\n`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-disable @typescript-eslint/no-unused-vars-experimental, @typescript-eslint/ban-ts-comment */
//@ts-ignore
import gql from 'gql';

//@ts-ignore
const A1 = gql`
query a {
a
}
`;

//@ts-ignore
const A2 = gql`
query a {
a
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,85 @@ export const CDocument = {\\"kind\\":\\"Document\\",\\"definitions\\":[{\\"kind\
"import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'"
);
});

it('prevent duplicate operations', async () => {
const result = await executeCodegen({
schema: [
/* GraphQL */ `
type Query {
a: String
}
`,
],
documents: path.join(__dirname, 'fixtures/duplicate-operation.ts'),
generates: {
'out1.ts': {
preset,
plugins: [],
},
},
config: {
useTypeImports: true,
},
});

expect(result.length).toBe(2);

expect(result[0].content).toMatchInlineSnapshot(`
"/* eslint-disable */
import * as graphql from './graphql';
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
const documents = {
\\"\\\\n query a {\\\\n a\\\\n }\\\\n\\": graphql.ADocument,
};
export function gql(source: \\"\\\\n query a {\\\\n a\\\\n }\\\\n\\"): (typeof documents)[\\"\\\\n query a {\\\\n a\\\\n }\\\\n\\"];
export function gql(source: string): unknown;
export function gql(source: string) {
return (documents as any)[source] ?? {};
}
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode<
infer TType,
any
>
? TType
: never;
"
`);

expect(result[1].content).toMatchInlineSnapshot(`
"/* eslint-disable */
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};
export type Query = {
__typename?: 'Query';
a?: Maybe<Scalars['String']>;
};
export type AQueryVariables = Exact<{ [key: string]: never; }>;
export type AQuery = { __typename?: 'Query', a?: Maybe<string> };
export const ADocument = {\\"kind\\":\\"Document\\",\\"definitions\\":[{\\"kind\\":\\"OperationDefinition\\",\\"operation\\":\\"query\\",\\"name\\":{\\"kind\\":\\"Name\\",\\"value\\":\\"a\\"},\\"selectionSet\\":{\\"kind\\":\\"SelectionSet\\",\\"selections\\":[{\\"kind\\":\\"Field\\",\\"name\\":{\\"kind\\":\\"Name\\",\\"value\\":\\"a\\"}}]}}]} as unknown as DocumentNode<AQuery, AQueryVariables>;"
`);

expect(result[0].content.match(/query a {/g).length).toBe(3);
});
});

0 comments on commit 5394f19

Please sign in to comment.