Skip to content

Commit 8737dd8

Browse files
authored
Forward customDirectives in client preset to support Apollo unmask directive (#10268)
1 parent 6f1741a commit 8737dd8

File tree

3 files changed

+106
-8
lines changed

3 files changed

+106
-8
lines changed

.changeset/great-dancers-pump.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-codegen/client-preset': minor
3+
---
4+
5+
Forward customDirectives to support Apollo unmask

packages/presets/client/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export const preset: Types.OutputPreset<ClientPresetConfig> = {
136136
skipTypeNameForRoot: options.config.skipTypeNameForRoot,
137137
onlyOperationTypes: options.config.onlyOperationTypes,
138138
onlyEnumTypes: options.config.onlyEnumTypes,
139+
customDirectives: options.config.customDirectives,
139140
};
140141

141142
const visitor = new ClientSideBaseVisitor(options.schemaAst!, [], options.config, options.config);

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

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,98 @@ export * from "./gql";`);
517517
expect(graphqlFile.content).toContain("__typename: 'Query';");
518518
});
519519

520+
it('supports Apollo fragment masking', async () => {
521+
const result = await executeCodegen({
522+
schema: /* GraphQL */ `
523+
type Query {
524+
me: User
525+
}
526+
527+
type User {
528+
id: ID!
529+
name: String!
530+
age: Int!
531+
}
532+
`,
533+
documents: /* GraphQL */ `
534+
query Me {
535+
unmasked: me {
536+
id
537+
...User_Me @unmask
538+
}
539+
masked: me {
540+
id
541+
...User_Me
542+
}
543+
}
544+
545+
fragment User_Me on User {
546+
name
547+
age
548+
}
549+
`,
550+
generates: {
551+
'out1/': {
552+
preset,
553+
presetConfig: { fragmentMasking: false },
554+
config: {
555+
inlineFragmentTypes: 'mask',
556+
customDirectives: { apolloUnmask: true },
557+
},
558+
},
559+
},
560+
});
561+
562+
const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts');
563+
expect(graphqlFile.content).toMatchInlineSnapshot(`
564+
"/* eslint-disable */
565+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
566+
export type Maybe<T> = T | null;
567+
export type InputMaybe<T> = Maybe<T>;
568+
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
569+
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
570+
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
571+
export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };
572+
export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
573+
/** All built-in and custom scalars, mapped to their actual values */
574+
export type Scalars = {
575+
ID: { input: string; output: string; }
576+
String: { input: string; output: string; }
577+
Boolean: { input: boolean; output: boolean; }
578+
Int: { input: number; output: number; }
579+
Float: { input: number; output: number; }
580+
};
581+
582+
export type Query = {
583+
__typename?: 'Query';
584+
me?: Maybe<User>;
585+
};
586+
587+
export type User = {
588+
__typename?: 'User';
589+
age: Scalars['Int']['output'];
590+
id: Scalars['ID']['output'];
591+
name: Scalars['String']['output'];
592+
};
593+
594+
export type MeQueryVariables = Exact<{ [key: string]: never; }>;
595+
596+
597+
export type MeQuery = { __typename?: 'Query', unmasked?: (
598+
{ __typename?: 'User', id: string, name: string, age: number }
599+
& { ' $fragmentRefs'?: { 'User_MeFragment': User_MeFragment } }
600+
) | null, masked?: (
601+
{ __typename?: 'User', id: string }
602+
& { ' $fragmentRefs'?: { 'User_MeFragment': User_MeFragment } }
603+
) | null };
604+
605+
export type User_MeFragment = { __typename?: 'User', name: string, age: number } & { ' $fragmentName'?: 'User_MeFragment' };
606+
607+
export const User_MeFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"User_Me"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"age"}}]}}]} as unknown as DocumentNode<User_MeFragment, unknown>;
608+
export const MeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"unmasked"},"name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"User_Me"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"unmask"}}]}]}},{"kind":"Field","alias":{"kind":"Name","value":"masked"},"name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"User_Me"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"User_Me"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"age"}}]}}]} as unknown as DocumentNode<MeQuery, MeQueryVariables>;"
609+
`);
610+
});
611+
520612
it('prevent duplicate operations', async () => {
521613
const result = await executeCodegen({
522614
schema: [
@@ -2972,29 +3064,29 @@ export * from "./gql.js";`);
29723064
Int: { input: number; output: number; }
29733065
Float: { input: number; output: number; }
29743066
};
2975-
3067+
29763068
export const Color = {
29773069
Blue: 'BLUE',
29783070
Red: 'RED'
29793071
} as const;
2980-
3072+
29813073
export type Color = typeof Color[keyof typeof Color];
29823074
export type Query = {
29833075
__typename?: 'Query';
29843076
thing?: Maybe<Thing>;
29853077
};
2986-
3078+
29873079
export type Thing = {
29883080
__typename?: 'Thing';
29893081
color: Color;
29903082
};
2991-
3083+
29923084
export type FavoriteColorQueryVariables = Exact<{ [key: string]: never; }>;
2993-
2994-
3085+
3086+
29953087
export type FavoriteColorQuery = { __typename?: 'Query', thing?: { __typename?: 'Thing', color: Color } | null };
2996-
2997-
3088+
3089+
29983090
export const FavoriteColorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FavoriteColor"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"thing"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}}]} as unknown as DocumentNode<FavoriteColorQuery, FavoriteColorQueryVariables>;
29993091
`);
30003092
});

0 commit comments

Comments
 (0)