Skip to content

Commit b83b500

Browse files
committed
Fix __resolveReference not getting generated
1 parent d9ff4d7 commit b83b500

File tree

2 files changed

+33
-37
lines changed

2 files changed

+33
-37
lines changed

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

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,7 @@ export interface ParsedResolversConfig extends ParsedConfig {
8383
}
8484

8585
type FieldDefinitionPrintFn = (
86-
parent: {
87-
node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode;
88-
typeName: string;
89-
},
86+
parentName: string,
9087
avoidResolverOptionals: boolean
9188
) => { value: string | null; meta: { federation?: { isResolveReference: boolean } } };
9289
export type FieldDefinitionResult = [{ node: FieldDefinitionNode }, FieldDefinitionPrintFn];
@@ -1530,15 +1527,17 @@ export class BaseResolversVisitor<
15301527

15311528
return [
15321529
{ node },
1533-
(parentNode, avoidResolverOptionals) => {
1534-
const parentName = parentNode.typeName;
1535-
1530+
(parentName, avoidResolverOptionals) => {
15361531
const original: FieldDefinitionNode = parent[key];
15371532
const parentType = this.schema.getType(parentName);
15381533
const meta: ReturnType<FieldDefinitionPrintFn>['meta'] = {};
1534+
const typeName = node.name as unknown as string;
1535+
1536+
const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ type: parentType });
1537+
const shouldGenerateField =
1538+
fieldsToGenerate.some(field => field.name.value === typeName) ||
1539+
this._federation.isResolveReferenceField(node);
15391540

1540-
const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node: parentNode.node });
1541-
const shouldGenerateField = fieldsToGenerate.some(field => field.name === node.name);
15421541
if (!shouldGenerateField) {
15431542
return { value: null, meta };
15441543
}
@@ -1549,7 +1548,7 @@ export class BaseResolversVisitor<
15491548
? this.convertName(
15501549
parentName +
15511550
(this.config.addUnderscoreToArgsType ? '_' : '') +
1552-
this.convertName(node.name, {
1551+
this.convertName(typeName, {
15531552
useTypesPrefix: false,
15541553
useTypesSuffix: false,
15551554
}) +
@@ -1600,7 +1599,7 @@ export class BaseResolversVisitor<
16001599

16011600
if (isSubscriptionType) {
16021601
return {
1603-
mappedTypeKey: `${mappedType}, "${node.name}"`,
1602+
mappedTypeKey: `${mappedType}, "${typeName}"`,
16041603
resolverType: 'SubscriptionResolver',
16051604
};
16061605
}
@@ -1623,7 +1622,7 @@ export class BaseResolversVisitor<
16231622
type: string;
16241623
genericTypes: string[];
16251624
} = {
1626-
name: node.name as any,
1625+
name: typeName,
16271626
modifier: avoidResolverOptionals ? '' : '?',
16281627
type: resolverType,
16291628
genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f),
@@ -1720,7 +1719,10 @@ export class BaseResolversVisitor<
17201719
}
17211720

17221721
ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string | null {
1723-
const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node });
1722+
const typeName = node.name as unknown as string;
1723+
const type = this.schema.getType(typeName);
1724+
1725+
const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ type });
17241726
if (fieldsToGenerate.length === 0) {
17251727
return null;
17261728
}
@@ -1729,7 +1731,6 @@ export class BaseResolversVisitor<
17291731
const name = this.convertName(node, {
17301732
suffix: this.config.resolverTypeSuffix,
17311733
});
1732-
const typeName = node.name as any as string;
17331734
const parentType = this.getParentTypeToUse(typeName);
17341735

17351736
const rootType = ((): false | 'query' | 'mutation' | 'subscription' => {
@@ -1748,7 +1749,7 @@ export class BaseResolversVisitor<
17481749
const fieldsContent = (node.fields as unknown as FieldDefinitionResult[])
17491750
.map(([_, f]) => {
17501751
return f(
1751-
{ node, typeName },
1752+
typeName,
17521753
(rootType === 'query' && this.config.avoidOptionals.query) ||
17531754
(rootType === 'mutation' && this.config.avoidOptionals.mutation) ||
17541755
(rootType === 'subscription' && this.config.avoidOptionals.subscription) ||
@@ -1982,7 +1983,7 @@ export class BaseResolversVisitor<
19821983
// An Interface in Federation may have the additional __resolveReference resolver, if resolvable.
19831984
// So, we filter out the normal fields declared on the Interface and add the __resolveReference resolver.
19841985
const fields = (node.fields as unknown as FieldDefinitionResult[]).map(([_, f]) =>
1985-
f({ node, typeName }, this.config.avoidOptionals.resolvers)
1986+
f(typeName, this.config.avoidOptionals.resolvers)
19861987
);
19871988
for (const field of fields) {
19881989
if (field.meta.federation?.isResolveReference) {

packages/utils/plugins-helpers/src/federation.ts

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { astFromInterfaceType, astFromObjectType, getRootTypeNames, MapperKind, mapSchema } from '@graphql-tools/utils';
2-
import type { FieldDefinitionResult } from '@graphql-codegen/visitor-plugin-common';
32
import {
43
DefinitionNode,
54
DirectiveNode,
@@ -275,27 +274,23 @@ export class ApolloFederation {
275274
* - The field is marked as `@external` and there is no `@provides` path to the field
276275
* - The parent object is marked as `@external` and there is no `@provides` path to the field
277276
*/
278-
findFieldNodesToGenerate({
279-
node,
280-
}: {
281-
node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode;
282-
}): readonly FieldDefinitionNode[] {
283-
if (!this.enabled) {
284-
return node.fields || [];
285-
}
286-
287-
const parentType = this.schema.getType(node.name as any as string);
288-
if (!(isObjectType(parentType) && !isInterfaceType(parentType))) {
277+
findFieldNodesToGenerate({ type }: { type: GraphQLNamedType }): readonly FieldDefinitionNode[] {
278+
if (!(isObjectType(type) && !isInterfaceType(type))) {
289279
return [];
290280
}
291281

292-
const fieldNodes = node.fields as unknown as FieldDefinitionResult[];
282+
const node = type.astNode;
283+
const fieldNodes = node.fields || [];
284+
285+
if (!this.enabled) {
286+
return fieldNodes;
287+
}
293288

294289
// If the object is marked with @external, fields to generate are those with `@provides`
295290
if (this.isExternal(node)) {
296-
const fieldNodesWithProvides = fieldNodes.reduce<FieldDefinitionNode[]>((acc, [fieldDef]) => {
297-
if (this.hasProvides(parentType, fieldDef.node.name as any as string)) {
298-
acc.push(fieldDef.node);
291+
const fieldNodesWithProvides = fieldNodes.reduce<FieldDefinitionNode[]>((acc, fieldNode) => {
292+
if (this.hasProvides(type, fieldNode.name as unknown as string)) {
293+
acc.push(fieldNode);
299294
}
300295
return acc;
301296
}, []);
@@ -305,14 +300,14 @@ export class ApolloFederation {
305300
// If the object is not marked with @external, fields to generate are:
306301
// - the fields without `@external`
307302
// - the `@external` fields with `@provides`
308-
const fieldNodesWithoutExternalOrHasProvides = fieldNodes.reduce<FieldDefinitionNode[]>((acc, [fieldDef]) => {
309-
if (!this.isExternal(fieldDef.node)) {
310-
acc.push(fieldDef.node);
303+
const fieldNodesWithoutExternalOrHasProvides = fieldNodes.reduce<FieldDefinitionNode[]>((acc, fieldNode) => {
304+
if (!this.isExternal(fieldNode)) {
305+
acc.push(fieldNode);
311306
return acc;
312307
}
313308

314-
if (this.isExternal(fieldDef.node) && this.hasProvides(parentType, fieldDef.node.name as any as string)) {
315-
acc.push(fieldDef.node);
309+
if (this.isExternal(fieldNode) && this.hasProvides(type, fieldNode.name as unknown as string)) {
310+
acc.push(fieldNode);
316311
return acc;
317312
}
318313

0 commit comments

Comments
 (0)