Skip to content

Commit

Permalink
fix(typescript-operations): properly handle aliased conditionals (#9842)
Browse files Browse the repository at this point in the history
* fix(typescript-operations): properly handle aliased fields with conditional directives

* add changeset
  • Loading branch information
henryqdineen authored Feb 20, 2024
1 parent 8c40cdf commit ed9c205
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .changeset/mighty-doors-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-codegen/visitor-plugin-common': patch
'@graphql-codegen/typescript-operations': patch
---

properly handle aliased conditionals
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { GraphQLInterfaceType, GraphQLNamedType, GraphQLObjectType, GraphQLOutpu
import { AvoidOptionalsConfig, ConvertNameFn, NormalizedScalarsMap } from '../types.js';

export type PrimitiveField = { isConditional: boolean; fieldName: string };
export type PrimitiveAliasedFields = { alias: string; fieldName: string };
export type PrimitiveAliasedFields = { isConditional: boolean; alias: string; fieldName: string };
export type LinkField = { alias: string; name: string; type: string; selectionSet: string };
export type NameAndType = { name: string; type: string };
export type ProcessResult = null | Array<NameAndType | string>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ export class PreResolveTypesProcessor extends BaseSelectionSetProcessor<Selectio
});
}

const name = this.config.formatNamedField(aliasedField.alias, fieldObj.type, undefined, unsetTypes);
const name = this.config.formatNamedField(
aliasedField.alias,
fieldObj.type,
aliasedField.isConditional,
unsetTypes
);
if (unsetTypes) {
return {
type: 'never',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,9 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
const isConditional = hasConditionalDirectives(field) || inlineFragmentConditional;
const isOptional = options.unsetTypes;
linkFields.push({
alias: field.alias ? this._processor.config.formatNamedField(field.alias.value, selectedFieldType) : undefined,
alias: field.alias
? this._processor.config.formatNamedField(field.alias.value, selectedFieldType, isConditional, isOptional)
: undefined,
name: this._processor.config.formatNamedField(field.name.value, selectedFieldType, isConditional, isOptional),
type: realSelectedFieldType.name,
selectionSet: this._processor.config.wrapTypeWithModifiers(
Expand Down Expand Up @@ -679,6 +681,7 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
Array.from(primitiveAliasFields.values()).map(field => ({
alias: field.alias.value,
fieldName: field.name.value,
isConditional: hasConditionalDirectives(field),
})),
options.unsetTypes
),
Expand Down
56 changes: 56 additions & 0 deletions packages/plugins/typescript/operations/tests/ts-documents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6051,6 +6051,62 @@ function test(q: GetEntityBrandDataQuery): void {

expect(content).toMatchSnapshot();
});

it('#8461 - conditional directives are ignored on fields with alias', async () => {
const testSchema = buildSchema(/* GraphQL */ `
type User {
firstName: String!
lastName: Int!
address: Address!
}
type Address {
postalCode: String!
}
type Query {
viewer: User!
}
`);

const query = parse(/* GraphQL */ `
query UserQuery($skipFirstName: Boolean!, $skipAddress: Boolean!) {
viewer {
givenName: firstName @skip(if: $skipFirstName)
lastName
mailingAddress: address @skip(if: $skipAddress) {
postalCode
}
}
}
`);

const config = { preResolveTypes: true };

const { content } = await plugin(testSchema, [{ location: '', document: query }], config, {
outputFile: 'graphql.ts',
});

expect(content).toBeSimilarStringTo(`
export type UserQueryQueryVariables = Exact<{
skipFirstName: Scalars['Boolean']['input'];
skipAddress: Scalars['Boolean']['input'];
}>;
export type UserQueryQuery = {
__typename?: 'Query',
viewer: {
__typename?: 'User',
lastName: number,
givenName?: string,
mailingAddress?: {
__typename?: 'Address',
postalCode: string
}
}
};
`);
});
});

describe('conditional directives handling', () => {
Expand Down

0 comments on commit ed9c205

Please sign in to comment.