Skip to content

Commit 03e64aa

Browse files
committed
test: embed metadata in document node
1 parent a9062d9 commit 03e64aa

File tree

2 files changed

+256
-97
lines changed

2 files changed

+256
-97
lines changed

packages/presets/client/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export type ClientPresetConfig = {
6767
* Generate metadata for a executable document node and embed it in the emitted code.
6868
*/
6969
onDocumentNode?: (documentNode: DocumentNode) => void | Record<string, unknown>;
70-
/** Persisted operations */
70+
/** Persisted operations configuration. */
7171
persistedOperations?:
7272
| boolean
7373
| {

packages/presets/client/tests/client-preset.spec.ts

Lines changed: 255 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -535,49 +535,49 @@ export * from "./fragment-masking";`);
535535
expect(result.length).toBe(4);
536536
const gqlFile = result.find(file => file.filename === 'out1/gql.ts');
537537
expect(gqlFile.content).toMatchInlineSnapshot(`
538-
"/* eslint-disable */
539-
import * as types from './graphql';
540-
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
541-
542-
/**
543-
* Map of all GraphQL operations in the project.
544-
*
545-
* This map has several performance disadvantages:
546-
* 1. It is not tree-shakeable, so it will include all operations in the project.
547-
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
548-
* 3. It does not support dead code elimination, so it will add unused operations.
549-
*
550-
* Therefore it is highly recommended to use the babel-plugin for production.
551-
*/
552-
const documents = {
553-
"\\n query a {\\n a\\n }\\n": types.ADocument,
554-
};
555-
556-
/**
557-
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
558-
*
559-
*
560-
* @example
561-
* \`\`\`ts
562-
* const query = gql(\`query GetUser($id: ID!) { user(id: $id) { name } }\`);
563-
* \`\`\`
564-
*
565-
* The query argument is unknown!
566-
* Please regenerate the types.
567-
*/
568-
export function graphql(source: string): unknown;
569-
570-
/**
571-
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
572-
*/
573-
export function graphql(source: "\\n query a {\\n a\\n }\\n"): (typeof documents)["\\n query a {\\n a\\n }\\n"];
574-
575-
export function graphql(source: string) {
576-
return (documents as any)[source] ?? {};
577-
}
578-
579-
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;"
580-
`);
538+
"/* eslint-disable */
539+
import * as types from './graphql';
540+
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
541+
542+
/**
543+
* Map of all GraphQL operations in the project.
544+
*
545+
* This map has several performance disadvantages:
546+
* 1. It is not tree-shakeable, so it will include all operations in the project.
547+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
548+
* 3. It does not support dead code elimination, so it will add unused operations.
549+
*
550+
* Therefore it is highly recommended to use the babel-plugin for production.
551+
*/
552+
const documents = {
553+
"\\n query a {\\n a\\n }\\n": types.ADocument,
554+
};
555+
556+
/**
557+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
558+
*
559+
*
560+
* @example
561+
* \`\`\`ts
562+
* const query = gql(\`query GetUser($id: ID!) { user(id: $id) { name } }\`);
563+
* \`\`\`
564+
*
565+
* The query argument is unknown!
566+
* Please regenerate the types.
567+
*/
568+
export function graphql(source: string): unknown;
569+
570+
/**
571+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
572+
*/
573+
export function graphql(source: "\\n query a {\\n a\\n }\\n"): (typeof documents)["\\n query a {\\n a\\n }\\n"];
574+
575+
export function graphql(source: string) {
576+
return (documents as any)[source] ?? {};
577+
}
578+
579+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;"
580+
`);
581581
const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts');
582582
expect(graphqlFile.content).toMatchInlineSnapshot(`
583583
"/* eslint-disable */
@@ -647,59 +647,59 @@ export * from "./fragment-masking";`);
647647
expect(indexFile.content).toMatchInlineSnapshot(`"export * from "./gql";"`);
648648
const gqlFile = result.find(file => file.filename === 'out1/gql.ts');
649649
expect(gqlFile.content).toMatchInlineSnapshot(`
650-
"/* eslint-disable */
651-
import * as types from './graphql';
652-
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
653-
654-
/**
655-
* Map of all GraphQL operations in the project.
656-
*
657-
* This map has several performance disadvantages:
658-
* 1. It is not tree-shakeable, so it will include all operations in the project.
659-
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
660-
* 3. It does not support dead code elimination, so it will add unused operations.
661-
*
662-
* Therefore it is highly recommended to use the babel-plugin for production.
663-
*/
664-
const documents = {
665-
"\\n query A {\\n a\\n }\\n": types.ADocument,
666-
"\\n query B {\\n b\\n }\\n": types.BDocument,
667-
"\\n fragment C on Query {\\n c\\n }\\n": types.CFragmentDoc,
668-
};
669-
670-
/**
671-
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
672-
*
673-
*
674-
* @example
675-
* \`\`\`ts
676-
* const query = gql(\`query GetUser($id: ID!) { user(id: $id) { name } }\`);
677-
* \`\`\`
678-
*
679-
* The query argument is unknown!
680-
* Please regenerate the types.
681-
*/
682-
export function graphql(source: string): unknown;
683-
684-
/**
685-
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
686-
*/
687-
export function graphql(source: "\\n query A {\\n a\\n }\\n"): (typeof documents)["\\n query A {\\n a\\n }\\n"];
688-
/**
689-
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
690-
*/
691-
export function graphql(source: "\\n query B {\\n b\\n }\\n"): (typeof documents)["\\n query B {\\n b\\n }\\n"];
692-
/**
693-
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
694-
*/
695-
export function graphql(source: "\\n fragment C on Query {\\n c\\n }\\n"): (typeof documents)["\\n fragment C on Query {\\n c\\n }\\n"];
696-
697-
export function graphql(source: string) {
698-
return (documents as any)[source] ?? {};
699-
}
700-
701-
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;"
702-
`);
650+
"/* eslint-disable */
651+
import * as types from './graphql';
652+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
653+
654+
/**
655+
* Map of all GraphQL operations in the project.
656+
*
657+
* This map has several performance disadvantages:
658+
* 1. It is not tree-shakeable, so it will include all operations in the project.
659+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
660+
* 3. It does not support dead code elimination, so it will add unused operations.
661+
*
662+
* Therefore it is highly recommended to use the babel-plugin for production.
663+
*/
664+
const documents = {
665+
"\\n query A {\\n a\\n }\\n": types.ADocument,
666+
"\\n query B {\\n b\\n }\\n": types.BDocument,
667+
"\\n fragment C on Query {\\n c\\n }\\n": types.CFragmentDoc,
668+
};
669+
670+
/**
671+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
672+
*
673+
*
674+
* @example
675+
* \`\`\`ts
676+
* const query = gql(\`query GetUser($id: ID!) { user(id: $id) { name } }\`);
677+
* \`\`\`
678+
*
679+
* The query argument is unknown!
680+
* Please regenerate the types.
681+
*/
682+
export function graphql(source: string): unknown;
683+
684+
/**
685+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
686+
*/
687+
export function graphql(source: "\\n query A {\\n a\\n }\\n"): (typeof documents)["\\n query A {\\n a\\n }\\n"];
688+
/**
689+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
690+
*/
691+
export function graphql(source: "\\n query B {\\n b\\n }\\n"): (typeof documents)["\\n query B {\\n b\\n }\\n"];
692+
/**
693+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
694+
*/
695+
export function graphql(source: "\\n fragment C on Query {\\n c\\n }\\n"): (typeof documents)["\\n fragment C on Query {\\n c\\n }\\n"];
696+
697+
export function graphql(source: string) {
698+
return (documents as any)[source] ?? {};
699+
}
700+
701+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;"
702+
`);
703703
});
704704

705705
it('fragmentMasking: {}', async () => {
@@ -1072,6 +1072,85 @@ export * from "./fragment-masking.js";`);
10721072
});
10731073
});
10741074

1075+
it('embed metadata in executable document node', async () => {
1076+
const result = await executeCodegen({
1077+
schema: [
1078+
/* GraphQL */ `
1079+
type Query {
1080+
a: String
1081+
b: String
1082+
c: String
1083+
}
1084+
`,
1085+
],
1086+
documents: [
1087+
/* GraphQL */ `
1088+
query aaa {
1089+
a
1090+
}
1091+
`,
1092+
/* GraphQL */ `
1093+
query bbb {
1094+
b
1095+
}
1096+
`,
1097+
],
1098+
generates: {
1099+
'out1/': {
1100+
preset,
1101+
plugins: [],
1102+
presetConfig: {
1103+
onDocumentNode(node) {
1104+
return {
1105+
cacheKeys: [node.definitions[0].name.value],
1106+
};
1107+
},
1108+
},
1109+
},
1110+
},
1111+
emitLegacyCommonJSImports: false,
1112+
});
1113+
const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts');
1114+
expect(graphqlFile.content).toMatchInlineSnapshot(`
1115+
"/* eslint-disable */
1116+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
1117+
export type Maybe<T> = T | null;
1118+
export type InputMaybe<T> = Maybe<T>;
1119+
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
1120+
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
1121+
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
1122+
/** All built-in and custom scalars, mapped to their actual values */
1123+
export type Scalars = {
1124+
ID: string;
1125+
String: string;
1126+
Boolean: boolean;
1127+
Int: number;
1128+
Float: number;
1129+
};
1130+
1131+
export type Query = {
1132+
__typename?: 'Query';
1133+
a?: Maybe<Scalars['String']>;
1134+
b?: Maybe<Scalars['String']>;
1135+
c?: Maybe<Scalars['String']>;
1136+
};
1137+
1138+
export type BbbQueryVariables = Exact<{ [key: string]: never; }>;
1139+
1140+
1141+
export type BbbQuery = { __typename?: 'Query', b?: string | null };
1142+
1143+
export type AaaQueryVariables = Exact<{ [key: string]: never; }>;
1144+
1145+
1146+
export type AaaQuery = { __typename?: 'Query', a?: string | null };
1147+
1148+
1149+
export const BbbDocument = {"__meta__":{"cacheKeys":["bbb"]},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"bbb"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode<BbbQuery, BbbQueryVariables>;
1150+
export const AaaDocument = {"__meta__":{"cacheKeys":["aaa"]},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"aaa"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode<AaaQuery, AaaQueryVariables>;"
1151+
`);
1152+
});
1153+
10751154
describe('persisted operations', () => {
10761155
it('apply default settings', async () => {
10771156
const result = await executeCodegen({
@@ -1310,5 +1389,85 @@ export * from "./fragment-masking.js";`);
13101389
export const BDocument = {"__meta__":{"custom_property_name":"c3ea9f3f937d47d72c70055ea55c7cf88a35e608"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode<BQuery, BQueryVariables>;"
13111390
`);
13121391
});
1392+
1393+
it('embed metadata in executable document node', async () => {
1394+
const result = await executeCodegen({
1395+
schema: [
1396+
/* GraphQL */ `
1397+
type Query {
1398+
a: String
1399+
b: String
1400+
c: String
1401+
}
1402+
`,
1403+
],
1404+
documents: [
1405+
/* GraphQL */ `
1406+
query aaa {
1407+
a
1408+
}
1409+
`,
1410+
/* GraphQL */ `
1411+
query bbb {
1412+
b
1413+
}
1414+
`,
1415+
],
1416+
generates: {
1417+
'out1/': {
1418+
preset,
1419+
plugins: [],
1420+
presetConfig: {
1421+
persistedOperations: true,
1422+
onDocumentNode(node) {
1423+
return {
1424+
cacheKeys: [node.definitions[0].name.value],
1425+
};
1426+
},
1427+
},
1428+
},
1429+
},
1430+
emitLegacyCommonJSImports: false,
1431+
});
1432+
const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts');
1433+
expect(graphqlFile.content).toMatchInlineSnapshot(`
1434+
"/* eslint-disable */
1435+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
1436+
export type Maybe<T> = T | null;
1437+
export type InputMaybe<T> = Maybe<T>;
1438+
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
1439+
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
1440+
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
1441+
/** All built-in and custom scalars, mapped to their actual values */
1442+
export type Scalars = {
1443+
ID: string;
1444+
String: string;
1445+
Boolean: boolean;
1446+
Int: number;
1447+
Float: number;
1448+
};
1449+
1450+
export type Query = {
1451+
__typename?: 'Query';
1452+
a?: Maybe<Scalars['String']>;
1453+
b?: Maybe<Scalars['String']>;
1454+
c?: Maybe<Scalars['String']>;
1455+
};
1456+
1457+
export type AaaQueryVariables = Exact<{ [key: string]: never; }>;
1458+
1459+
1460+
export type AaaQuery = { __typename?: 'Query', a?: string | null };
1461+
1462+
export type BbbQueryVariables = Exact<{ [key: string]: never; }>;
1463+
1464+
1465+
export type BbbQuery = { __typename?: 'Query', b?: string | null };
1466+
1467+
1468+
export const AaaDocument = {"__meta__":{"cacheKeys":["aaa"],"hash":"682f60dea844320c05fcb4fb6c4118015902c9a8"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"aaa"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode<AaaQuery, AaaQueryVariables>;
1469+
export const BbbDocument = {"__meta__":{"cacheKeys":["bbb"],"hash":"2a8e0849914b13ebc13b112ba5a502678d757511"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"bbb"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode<BbbQuery, BbbQueryVariables>;"
1470+
`);
1471+
});
13131472
});
13141473
});

0 commit comments

Comments
 (0)