Skip to content

Commit ed9c205

Browse files
authored
fix(typescript-operations): properly handle aliased conditionals (#9842)
* fix(typescript-operations): properly handle aliased fields with conditional directives * add changeset
1 parent 8c40cdf commit ed9c205

File tree

5 files changed

+73
-3
lines changed

5 files changed

+73
-3
lines changed

.changeset/mighty-doors-stare.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@graphql-codegen/visitor-plugin-common': patch
3+
'@graphql-codegen/typescript-operations': patch
4+
---
5+
6+
properly handle aliased conditionals

packages/plugins/other/visitor-plugin-common/src/selection-set-processor/base.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { GraphQLInterfaceType, GraphQLNamedType, GraphQLObjectType, GraphQLOutpu
22
import { AvoidOptionalsConfig, ConvertNameFn, NormalizedScalarsMap } from '../types.js';
33

44
export type PrimitiveField = { isConditional: boolean; fieldName: string };
5-
export type PrimitiveAliasedFields = { alias: string; fieldName: string };
5+
export type PrimitiveAliasedFields = { isConditional: boolean; alias: string; fieldName: string };
66
export type LinkField = { alias: string; name: string; type: string; selectionSet: string };
77
export type NameAndType = { name: string; type: string };
88
export type ProcessResult = null | Array<NameAndType | string>;

packages/plugins/other/visitor-plugin-common/src/selection-set-processor/pre-resolve-types.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ export class PreResolveTypesProcessor extends BaseSelectionSetProcessor<Selectio
101101
});
102102
}
103103

104-
const name = this.config.formatNamedField(aliasedField.alias, fieldObj.type, undefined, unsetTypes);
104+
const name = this.config.formatNamedField(
105+
aliasedField.alias,
106+
fieldObj.type,
107+
aliasedField.isConditional,
108+
unsetTypes
109+
);
105110
if (unsetTypes) {
106111
return {
107112
type: 'never',

packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,9 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
642642
const isConditional = hasConditionalDirectives(field) || inlineFragmentConditional;
643643
const isOptional = options.unsetTypes;
644644
linkFields.push({
645-
alias: field.alias ? this._processor.config.formatNamedField(field.alias.value, selectedFieldType) : undefined,
645+
alias: field.alias
646+
? this._processor.config.formatNamedField(field.alias.value, selectedFieldType, isConditional, isOptional)
647+
: undefined,
646648
name: this._processor.config.formatNamedField(field.name.value, selectedFieldType, isConditional, isOptional),
647649
type: realSelectedFieldType.name,
648650
selectionSet: this._processor.config.wrapTypeWithModifiers(
@@ -679,6 +681,7 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
679681
Array.from(primitiveAliasFields.values()).map(field => ({
680682
alias: field.alias.value,
681683
fieldName: field.name.value,
684+
isConditional: hasConditionalDirectives(field),
682685
})),
683686
options.unsetTypes
684687
),

packages/plugins/typescript/operations/tests/ts-documents.spec.ts

+56
Original file line numberDiff line numberDiff line change
@@ -6051,6 +6051,62 @@ function test(q: GetEntityBrandDataQuery): void {
60516051

60526052
expect(content).toMatchSnapshot();
60536053
});
6054+
6055+
it('#8461 - conditional directives are ignored on fields with alias', async () => {
6056+
const testSchema = buildSchema(/* GraphQL */ `
6057+
type User {
6058+
firstName: String!
6059+
lastName: Int!
6060+
address: Address!
6061+
}
6062+
6063+
type Address {
6064+
postalCode: String!
6065+
}
6066+
6067+
type Query {
6068+
viewer: User!
6069+
}
6070+
`);
6071+
6072+
const query = parse(/* GraphQL */ `
6073+
query UserQuery($skipFirstName: Boolean!, $skipAddress: Boolean!) {
6074+
viewer {
6075+
givenName: firstName @skip(if: $skipFirstName)
6076+
lastName
6077+
mailingAddress: address @skip(if: $skipAddress) {
6078+
postalCode
6079+
}
6080+
}
6081+
}
6082+
`);
6083+
6084+
const config = { preResolveTypes: true };
6085+
6086+
const { content } = await plugin(testSchema, [{ location: '', document: query }], config, {
6087+
outputFile: 'graphql.ts',
6088+
});
6089+
6090+
expect(content).toBeSimilarStringTo(`
6091+
export type UserQueryQueryVariables = Exact<{
6092+
skipFirstName: Scalars['Boolean']['input'];
6093+
skipAddress: Scalars['Boolean']['input'];
6094+
}>;
6095+
6096+
export type UserQueryQuery = {
6097+
__typename?: 'Query',
6098+
viewer: {
6099+
__typename?: 'User',
6100+
lastName: number,
6101+
givenName?: string,
6102+
mailingAddress?: {
6103+
__typename?: 'Address',
6104+
postalCode: string
6105+
}
6106+
}
6107+
};
6108+
`);
6109+
});
60546110
});
60556111

60566112
describe('conditional directives handling', () => {

0 commit comments

Comments
 (0)