From a46b8d99c797283d773ec14163c62be9c84d4c2b Mon Sep 17 00:00:00 2001 From: Charly POLY <1252066+charlypoly@users.noreply.github.com> Date: Tue, 18 Oct 2022 16:22:19 +0200 Subject: [PATCH] fix(typescript): Fragment masking ` $fragmentName` and ` $fragmentRefs` are optional (#8498) --- .changeset/dry-pianos-grab.md | 7 ++++++ .../gql/fragment-masking.ts | 4 ++-- .../gql/graphql.ts | 8 +++---- .../gql/fragment-masking.ts | 4 ++-- .../gql-tag-operations-masking/gql/graphql.ts | 12 +++++----- .../graphql/fragment-masking.ts | 4 ++-- .../gql-tag-operations/graphql/graphql.ts | 4 ++-- .../src/selection-set-to-object.ts | 8 ++++--- .../operations/tests/ts-documents.spec.ts | 24 +++++++++---------- .../client/src/fragment-masking-plugin.ts | 4 ++-- .../client/tests/client-preset.spec.ts | 6 ++--- .../src/fragment-masking-plugin.ts | 4 ++-- .../tests/gql-tag-operations.spec.ts | 12 +++++----- 13 files changed, 55 insertions(+), 46 deletions(-) create mode 100644 .changeset/dry-pianos-grab.md diff --git a/.changeset/dry-pianos-grab.md b/.changeset/dry-pianos-grab.md new file mode 100644 index 00000000000..f9a659fe234 --- /dev/null +++ b/.changeset/dry-pianos-grab.md @@ -0,0 +1,7 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +'@graphql-codegen/client-preset': minor +'@graphql-codegen/gql-tag-operations-preset': minor +--- + +Fragment masking ` $fragmentName` and ` $fragmentRefs` are optionals diff --git a/dev-test/gql-tag-operations-masking-star-wars/gql/fragment-masking.ts b/dev-test/gql-tag-operations-masking-star-wars/gql/fragment-masking.ts index a939c1d1cc2..0c3d1311f04 100644 --- a/dev-test/gql-tag-operations-masking-star-wars/gql/fragment-masking.ts +++ b/dev-test/gql-tag-operations-masking-star-wars/gql/fragment-masking.ts @@ -4,9 +4,9 @@ export type FragmentType> = TDocume infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never; diff --git a/dev-test/gql-tag-operations-masking-star-wars/gql/graphql.ts b/dev-test/gql-tag-operations-masking-star-wars/gql/graphql.ts index bd97e97cc66..f4c21499d32 100644 --- a/dev-test/gql-tag-operations-masking-star-wars/gql/graphql.ts +++ b/dev-test/gql-tag-operations-masking-star-wars/gql/graphql.ts @@ -247,17 +247,17 @@ export type HeroDetailsWithFragmentQueryVariables = Exact<{ export type HeroDetailsWithFragmentQuery = { __typename?: 'Query'; hero?: - | ({ __typename?: 'Droid' } & { ' $fragmentRefs': { HeroDetails_Droid_Fragment: HeroDetails_Droid_Fragment } }) - | ({ __typename?: 'Human' } & { ' $fragmentRefs': { HeroDetails_Human_Fragment: HeroDetails_Human_Fragment } }) + | ({ __typename?: 'Droid' } & { ' $fragmentRefs'?: { HeroDetails_Droid_Fragment: HeroDetails_Droid_Fragment } }) + | ({ __typename?: 'Human' } & { ' $fragmentRefs'?: { HeroDetails_Human_Fragment: HeroDetails_Human_Fragment } }) | null; }; type HeroDetails_Droid_Fragment = { __typename: 'Droid'; primaryFunction?: string | null; name: string } & { - ' $fragmentName': 'HeroDetails_Droid_Fragment'; + ' $fragmentName'?: 'HeroDetails_Droid_Fragment'; }; type HeroDetails_Human_Fragment = { __typename: 'Human'; height?: number | null; name: string } & { - ' $fragmentName': 'HeroDetails_Human_Fragment'; + ' $fragmentName'?: 'HeroDetails_Human_Fragment'; }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; diff --git a/dev-test/gql-tag-operations-masking/gql/fragment-masking.ts b/dev-test/gql-tag-operations-masking/gql/fragment-masking.ts index a939c1d1cc2..0c3d1311f04 100644 --- a/dev-test/gql-tag-operations-masking/gql/fragment-masking.ts +++ b/dev-test/gql-tag-operations-masking/gql/fragment-masking.ts @@ -4,9 +4,9 @@ export type FragmentType> = TDocume infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never; diff --git a/dev-test/gql-tag-operations-masking/gql/graphql.ts b/dev-test/gql-tag-operations-masking/gql/graphql.ts index c3a626ac9e3..05bd6350120 100644 --- a/dev-test/gql-tag-operations-masking/gql/graphql.ts +++ b/dev-test/gql-tag-operations-masking/gql/graphql.ts @@ -106,26 +106,26 @@ export type User = { }; export type TweetFragmentFragment = ({ __typename?: 'Tweet'; id: string; body: string } & { - ' $fragmentRefs': { TweetAuthorFragmentFragment: TweetAuthorFragmentFragment }; -}) & { ' $fragmentName': 'TweetFragmentFragment' }; + ' $fragmentRefs'?: { TweetAuthorFragmentFragment: TweetAuthorFragmentFragment }; +}) & { ' $fragmentName'?: 'TweetFragmentFragment' }; export type TweetAuthorFragmentFragment = { __typename?: 'Tweet'; id: string; author: { __typename?: 'User'; id: string; username?: string | null }; -} & { ' $fragmentName': 'TweetAuthorFragmentFragment' }; +} & { ' $fragmentName'?: 'TweetAuthorFragmentFragment' }; export type TweetsFragmentFragment = { __typename?: 'Query'; Tweets?: Array< - { __typename?: 'Tweet'; id: string } & { ' $fragmentRefs': { TweetFragmentFragment: TweetFragmentFragment } } + { __typename?: 'Tweet'; id: string } & { ' $fragmentRefs'?: { TweetFragmentFragment: TweetFragmentFragment } } > | null; -} & { ' $fragmentName': 'TweetsFragmentFragment' }; +} & { ' $fragmentName'?: 'TweetsFragmentFragment' }; export type TweetAppQueryQueryVariables = Exact<{ [key: string]: never }>; export type TweetAppQueryQuery = { __typename?: 'Query' } & { - ' $fragmentRefs': { TweetsFragmentFragment: TweetsFragmentFragment }; + ' $fragmentRefs'?: { TweetsFragmentFragment: TweetsFragmentFragment }; }; export const TweetAuthorFragmentFragmentDoc = { diff --git a/dev-test/gql-tag-operations/graphql/fragment-masking.ts b/dev-test/gql-tag-operations/graphql/fragment-masking.ts index a939c1d1cc2..0c3d1311f04 100644 --- a/dev-test/gql-tag-operations/graphql/fragment-masking.ts +++ b/dev-test/gql-tag-operations/graphql/fragment-masking.ts @@ -4,9 +4,9 @@ export type FragmentType> = TDocume infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never; diff --git a/dev-test/gql-tag-operations/graphql/graphql.ts b/dev-test/gql-tag-operations/graphql/graphql.ts index aff65bfbfaf..b4c3541c433 100644 --- a/dev-test/gql-tag-operations/graphql/graphql.ts +++ b/dev-test/gql-tag-operations/graphql/graphql.ts @@ -110,14 +110,14 @@ export type FooQueryVariables = Exact<{ [key: string]: never }>; export type FooQuery = { __typename?: 'Query'; Tweets?: Array<{ __typename?: 'Tweet'; id: string } | null> | null }; export type LelFragment = { __typename?: 'Tweet'; id: string; body?: string | null } & { - ' $fragmentName': 'LelFragment'; + ' $fragmentName'?: 'LelFragment'; }; export type BarQueryVariables = Exact<{ [key: string]: never }>; export type BarQuery = { __typename?: 'Query'; - Tweets?: Array<({ __typename?: 'Tweet' } & { ' $fragmentRefs': { LelFragment: LelFragment } }) | null> | null; + Tweets?: Array<({ __typename?: 'Tweet' } & { ' $fragmentRefs'?: { LelFragment: LelFragment } }) | null> | null; }; export const LelFragmentDoc = { diff --git a/packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts b/packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts index 88dc48f89b8..74e3d588080 100644 --- a/packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts +++ b/packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts @@ -586,7 +586,7 @@ export class SelectionSetToObject `'${name}': ${name}`).join(`;`)} } }`); + fields.push(`{ ' $fragmentRefs'?: { ${fragmentsSpreadUsages.map(name => `'${name}': ${name}`).join(`;`)} } }`); } } @@ -683,7 +683,7 @@ export class SelectionSetToObject { export type TestQuery = { __typename?: 'Query', notifications: Array<( { __typename?: 'TextNotification' } - & { ' $fragmentRefs': { 'N_TextNotification_Fragment': N_TextNotification_Fragment } } + & { ' $fragmentRefs'?: { 'N_TextNotification_Fragment': N_TextNotification_Fragment } } ) | ( { __typename?: 'ImageNotification' } - & { ' $fragmentRefs': { 'N_ImageNotification_Fragment': N_ImageNotification_Fragment } } + & { ' $fragmentRefs'?: { 'N_ImageNotification_Fragment': N_ImageNotification_Fragment } } )> }; - type N_TextNotification_Fragment = { __typename?: 'TextNotification', id: string } & { ' $fragmentName': 'N_TextNotification_Fragment' }; + type N_TextNotification_Fragment = { __typename?: 'TextNotification', id: string } & { ' $fragmentName'?: 'N_TextNotification_Fragment' }; - type N_ImageNotification_Fragment = { __typename?: 'ImageNotification', id: string } & { ' $fragmentName': 'N_ImageNotification_Fragment' }; + type N_ImageNotification_Fragment = { __typename?: 'ImageNotification', id: string } & { ' $fragmentName'?: 'N_ImageNotification_Fragment' }; export type NFragment = N_TextNotification_Fragment | N_ImageNotification_Fragment; `); @@ -5862,20 +5862,20 @@ function test(q: GetEntityBrandDataQuery): void { export type GetPeopleQuery = { __typename?: 'Query', people: ( { __typename?: 'Character' } - & { ' $fragmentRefs': { 'PeopleInfo_Character_Fragment': PeopleInfo_Character_Fragment } } + & { ' $fragmentRefs'?: { 'PeopleInfo_Character_Fragment': PeopleInfo_Character_Fragment } } ) | ( { __typename?: 'Jedi' } - & { ' $fragmentRefs': { 'PeopleInfo_Jedi_Fragment': PeopleInfo_Jedi_Fragment } } + & { ' $fragmentRefs'?: { 'PeopleInfo_Jedi_Fragment': PeopleInfo_Jedi_Fragment } } ) | ( { __typename?: 'Droid' } - & { ' $fragmentRefs': { 'PeopleInfo_Droid_Fragment': PeopleInfo_Droid_Fragment } } + & { ' $fragmentRefs'?: { 'PeopleInfo_Droid_Fragment': PeopleInfo_Droid_Fragment } } ) }; - type PeopleInfo_Character_Fragment = { __typename?: 'Character', name?: string | null } & { ' $fragmentName': 'PeopleInfo_Character_Fragment' }; + type PeopleInfo_Character_Fragment = { __typename?: 'Character', name?: string | null } & { ' $fragmentName'?: 'PeopleInfo_Character_Fragment' }; - type PeopleInfo_Jedi_Fragment = { __typename?: 'Jedi', side?: string | null } & { ' $fragmentName': 'PeopleInfo_Jedi_Fragment' }; + type PeopleInfo_Jedi_Fragment = { __typename?: 'Jedi', side?: string | null } & { ' $fragmentName'?: 'PeopleInfo_Jedi_Fragment' }; - type PeopleInfo_Droid_Fragment = { __typename?: 'Droid', model?: string | null } & { ' $fragmentName': 'PeopleInfo_Droid_Fragment' }; + type PeopleInfo_Droid_Fragment = { __typename?: 'Droid', model?: string | null } & { ' $fragmentName'?: 'PeopleInfo_Droid_Fragment' }; export type PeopleInfoFragment = PeopleInfo_Character_Fragment | PeopleInfo_Jedi_Fragment | PeopleInfo_Droid_Fragment; " @@ -6434,10 +6434,10 @@ function test(q: GetEntityBrandDataQuery): void { export type Unnamed_1_Query = { __typename?: 'Query', me?: ( { __typename?: 'User' } - & { ' $fragmentRefs': { 'UserFragmentFragment': UserFragmentFragment } } + & { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } ) | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName': 'UserFragmentFragment' }; + export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; `); }); }); diff --git a/packages/presets/client/src/fragment-masking-plugin.ts b/packages/presets/client/src/fragment-masking-plugin.ts index 59be8117e61..71f8962337c 100644 --- a/packages/presets/client/src/fragment-masking-plugin.ts +++ b/packages/presets/client/src/fragment-masking-plugin.ts @@ -5,9 +5,9 @@ export type FragmentType> = TDocume infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never;`; diff --git a/packages/presets/client/tests/client-preset.spec.ts b/packages/presets/client/tests/client-preset.spec.ts index 5064d714cb1..b6fdbefd7f1 100644 --- a/packages/presets/client/tests/client-preset.spec.ts +++ b/packages/presets/client/tests/client-preset.spec.ts @@ -245,7 +245,7 @@ export * from "./fragment-masking"`); export type BQuery = { __typename?: 'Query', b?: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName': 'CFragment' }; + export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; 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; @@ -454,9 +454,9 @@ export * from "./fragment-masking"`); infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never; diff --git a/packages/presets/gql-tag-operations/src/fragment-masking-plugin.ts b/packages/presets/gql-tag-operations/src/fragment-masking-plugin.ts index 59be8117e61..71f8962337c 100644 --- a/packages/presets/gql-tag-operations/src/fragment-masking-plugin.ts +++ b/packages/presets/gql-tag-operations/src/fragment-masking-plugin.ts @@ -5,9 +5,9 @@ export type FragmentType> = TDocume infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never;`; diff --git a/packages/presets/gql-tag-operations/tests/gql-tag-operations.spec.ts b/packages/presets/gql-tag-operations/tests/gql-tag-operations.spec.ts index 01db9223dff..40cfc01267d 100644 --- a/packages/presets/gql-tag-operations/tests/gql-tag-operations.spec.ts +++ b/packages/presets/gql-tag-operations/tests/gql-tag-operations.spec.ts @@ -379,9 +379,9 @@ describe('gql-tag-operations-preset', () => { infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never; @@ -477,9 +477,9 @@ describe('gql-tag-operations-preset', () => { infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never; @@ -665,9 +665,9 @@ describe('gql-tag-operations-preset', () => { infer TType, any > - ? TType extends { ' $fragmentName': infer TKey } + ? TType extends { ' $fragmentName'?: infer TKey } ? TKey extends string - ? { ' $fragmentRefs': { [key in TKey]: TType } } + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never : never : never;