Skip to content

Commit 016484a

Browse files
committed
Generate FederationReferenceTypes once
1 parent abd8276 commit 016484a

File tree

4 files changed

+180
-211
lines changed

4 files changed

+180
-211
lines changed

packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -818,12 +818,9 @@ export class BaseResolversVisitor<
818818
shouldInclude: namedType => !isEnumType(namedType),
819819
onNotMappedObjectType: ({ typeName, initialType }) => {
820820
let result = initialType;
821-
const federationReferenceTypes = this._federation.printReferenceSelectionSets({
822-
typeName,
823-
baseFederationType: `${this.convertName('FederationTypes')}['${typeName}']`,
824-
});
825-
if (federationReferenceTypes) {
826-
result += ` | ${federationReferenceTypes}`;
821+
const referenceSelectionSetsString = this._federation.getMeta()[typeName]?.referenceSelectionSetsString;
822+
if (referenceSelectionSetsString) {
823+
result += ` | ${this.convertName('FederationReferenceTypes')}['${typeName}']`;
827824
}
828825
return result;
829826
},
@@ -1306,6 +1303,33 @@ export class BaseResolversVisitor<
13061303
).string;
13071304
}
13081305

1306+
public buildFederationReferenceTypes(): string {
1307+
const federationMeta = this._federation.getMeta();
1308+
1309+
if (Object.keys(federationMeta).length === 0) {
1310+
return '';
1311+
}
1312+
1313+
const declarationKind = 'type';
1314+
return new DeclarationBlock(this._declarationBlockConfig)
1315+
.export()
1316+
.asKind(declarationKind)
1317+
.withName(this.convertName('FederationReferenceTypes'))
1318+
.withComment('Mapping of federation reference types')
1319+
.withBlock(
1320+
Object.entries(federationMeta)
1321+
.map(([typeName, { referenceSelectionSetsString }]) => {
1322+
if (!referenceSelectionSetsString) {
1323+
return undefined;
1324+
}
1325+
1326+
return indent(`${typeName}: ${referenceSelectionSetsString}${this.getPunctuation(declarationKind)}`);
1327+
})
1328+
.filter(v => v)
1329+
.join('\n')
1330+
).string;
1331+
}
1332+
13091333
public get schema(): GraphQLSchema {
13101334
return this._schema;
13111335
}
@@ -1586,13 +1610,6 @@ export class BaseResolversVisitor<
15861610
}
15871611
}
15881612

1589-
const parentTypeSignature = this._federation.transformFieldParentType({
1590-
fieldNode: original,
1591-
parentType,
1592-
parentTypeSignature: this.getParentTypeForSignature(node),
1593-
federationTypeSignature: 'FederationType',
1594-
});
1595-
15961613
const { mappedTypeKey, resolverType } = ((): { mappedTypeKey: string; resolverType: string } => {
15971614
const baseType = getBaseTypeNode(original.type);
15981615
const realType = baseType.name.value;
@@ -1637,16 +1654,18 @@ export class BaseResolversVisitor<
16371654
name: typeName,
16381655
modifier: avoidResolverOptionals ? '' : '?',
16391656
type: resolverType,
1640-
genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f),
1657+
genericTypes: [mappedTypeKey, this.getParentTypeForSignature(node), contextType, argsType].filter(f => f),
16411658
};
16421659

16431660
if (this._federation.isResolveReferenceField(node)) {
16441661
if (!this._federation.getMeta()[parentType.name].hasResolveReference) {
16451662
return { value: '', meta };
16461663
}
1664+
const resultType = `${mappedTypeKey} | FederationReferenceType`;
1665+
const referenceType = 'FederationReferenceType';
1666+
16471667
signature.type = 'ReferenceResolver';
1648-
signature.genericTypes = [mappedTypeKey, parentTypeSignature, contextType];
1649-
meta.federation = { isResolveReference: true };
1668+
signature.genericTypes = [resultType, referenceType, contextType];
16501669
}
16511670

16521671
return {
@@ -1788,7 +1807,7 @@ export class BaseResolversVisitor<
17881807
];
17891808
this._federation.addFederationTypeGenericIfApplicable({
17901809
genericTypes,
1791-
federationTypesType: this.convertName('FederationTypes'),
1810+
federationTypesType: this.convertName('FederationReferenceTypes'),
17921811
typeName,
17931812
});
17941813

packages/plugins/typescript/resolvers/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs
250250
`;
251251

252252
const federationTypes = visitor.buildFederationTypes();
253+
const federationReferenceTypes = visitor.buildFederationReferenceTypes();
253254
const resolversTypeMapping = visitor.buildResolversTypes();
254255
const resolversParentTypeMapping = visitor.buildResolversParentTypes();
255256
const resolversUnionTypesMapping = visitor.buildResolversUnionTypes();
@@ -294,6 +295,7 @@ export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs
294295
content: [
295296
header,
296297
federationTypes,
298+
federationReferenceTypes,
297299
resolversUnionTypesMapping,
298300
resolversInterfaceTypesMapping,
299301
resolversTypeMapping,

packages/plugins/typescript/resolvers/tests/ts-resolvers.federation.spec.ts

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,20 @@ describe('TypeScript Resolvers Plugin + Apollo Federation', () => {
300300
expect(content).toBeSimilarStringTo(`
301301
export type ResolversParentTypes = {
302302
Query: {};
303-
Account: Account |
304-
( { __typename: 'Account' }
305-
& GraphQLRecursivePick<FederationTypes['Account'], {"id":true}> );
303+
Account: Account | FederationReferenceTypes['Account'];
306304
ID: Scalars['ID']['output'];
307305
String: Scalars['String']['output'];
308-
User: User |
306+
User: User | FederationReferenceTypes['User'];
307+
Boolean: Scalars['Boolean']['output'];
308+
};
309+
`);
310+
311+
expect(content).toBeSimilarStringTo(`
312+
export type FederationReferenceTypes = {
313+
Account:
314+
( { __typename: 'Account' }
315+
& GraphQLRecursivePick<FederationTypes['Account'], {"id":true}> );
316+
User:
309317
( { __typename: 'User' }
310318
& GraphQLRecursivePick<FederationTypes['User'], {"id":true}>
311319
& ( {}
@@ -323,31 +331,13 @@ describe('TypeScript Resolvers Plugin + Apollo Federation', () => {
323331
| GraphQLRecursivePick<FederationTypes['User'], {"c":true}>
324332
| GraphQLRecursivePick<FederationTypes['User'], {"c":true,"d":true}>
325333
| GraphQLRecursivePick<FederationTypes['User'], {"d":true}> ) );
326-
Boolean: Scalars['Boolean']['output'];
327334
};
328335
`);
329336

330337
// User should have it
331338
expect(content).toBeSimilarStringTo(`
332-
export type UserResolvers<ContextType = any, ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User'], FederationType extends FederationTypes['User'] = FederationTypes['User']> = {
333-
__resolveReference?: ReferenceResolver<Maybe<ResolversTypes['User']>,
334-
( { __typename: 'User' }
335-
& GraphQLRecursivePick<FederationType, {"id":true}>
336-
& ( {}
337-
| GraphQLRecursivePick<FederationType, {"a":true}>
338-
| GraphQLRecursivePick<FederationType, {"a":true,"b":true}>
339-
| GraphQLRecursivePick<FederationType, {"a":true,"c":true}>
340-
| GraphQLRecursivePick<FederationType, {"a":true,"d":true}>
341-
| GraphQLRecursivePick<FederationType, {"a":true,"b":true,"c":true}>
342-
| GraphQLRecursivePick<FederationType, {"a":true,"b":true,"d":true}>
343-
| GraphQLRecursivePick<FederationType, {"a":true,"b":true,"c":true,"d":true}>
344-
| GraphQLRecursivePick<FederationType, {"b":true}>
345-
| GraphQLRecursivePick<FederationType, {"b":true,"c":true}>
346-
| GraphQLRecursivePick<FederationType, {"b":true,"d":true}>
347-
| GraphQLRecursivePick<FederationType, {"b":true,"c":true,"d":true}>
348-
| GraphQLRecursivePick<FederationType, {"c":true}>
349-
| GraphQLRecursivePick<FederationType, {"c":true,"d":true}>
350-
| GraphQLRecursivePick<FederationType, {"d":true}> ) ), ContextType>;
339+
export type UserResolvers<ContextType = any, ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User'], FederationReferenceType extends FederationReferenceTypes['User'] = FederationReferenceTypes['User']> = {
340+
__resolveReference?: ReferenceResolver<Maybe<ResolversTypes['User']> | FederationReferenceType, FederationReferenceType, ContextType>;
351341
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
352342
aRequires?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
353343
bRequires?: Resolver<ResolversTypes['String'], ParentType, ContextType>;

0 commit comments

Comments
 (0)