Skip to content

Commit 2fe91bb

Browse files
committed
[resolvers] Refactor to remove NameNode override and simplify federation functions (#10377)
* Remove NameNode override and refactor relevant references * Simplify federation utils by making functions handle nodes * Fix lint issue
1 parent db162e5 commit 2fe91bb

File tree

3 files changed

+31
-59
lines changed

3 files changed

+31
-59
lines changed

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

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
isUnionType,
2121
ListTypeNode,
2222
NamedTypeNode,
23-
NameNode,
2423
NonNullTypeNode,
2524
ObjectTypeDefinitionNode,
2625
ScalarTypeDefinitionNode,
@@ -1495,13 +1494,6 @@ export class BaseResolversVisitor<
14951494
return '';
14961495
}
14971496

1498-
// FIXME: this Name method causes a lot of type inconsistencies
1499-
// because the type of nodes no longer matches the `graphql-js` types
1500-
// So, we should update this and remove any relevant `as any as string` or `as unknown as string`
1501-
Name(node: NameNode): string {
1502-
return node.value;
1503-
}
1504-
15051497
ListType(node: ListTypeNode): string {
15061498
const asString = node.type as any as string;
15071499

@@ -1515,7 +1507,7 @@ export class BaseResolversVisitor<
15151507
}
15161508

15171509
NamedType(node: NamedTypeNode): string {
1518-
const nameStr = node.name as any as string;
1510+
const nameStr = node.name.value;
15191511

15201512
if (this.config.scalars[nameStr]) {
15211513
return this._getScalar(nameStr);
@@ -1563,10 +1555,10 @@ export class BaseResolversVisitor<
15631555
return {
15641556
node: original,
15651557
printContent: (parentNode, avoidResolverOptionals) => {
1566-
const parentName = parentNode.name as unknown as string;
1558+
const parentName = parentNode.name.value;
15671559
const parentType = this.schema.getType(parentName);
15681560
const meta: ReturnType<FieldDefinitionPrintFn>['meta'] = {};
1569-
const typeName = node.name as unknown as string;
1561+
const typeName = node.name.value;
15701562

15711563
const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node: parentNode });
15721564
const shouldGenerateField =
@@ -1634,7 +1626,7 @@ export class BaseResolversVisitor<
16341626

16351627
const directiveMappings =
16361628
node.directives
1637-
?.map(directive => this._directiveResolverMappings[directive.name as any])
1629+
?.map(directive => this._directiveResolverMappings[directive.name.value])
16381630
.filter(Boolean)
16391631
.reverse() ?? [];
16401632

@@ -1681,8 +1673,8 @@ export class BaseResolversVisitor<
16811673
}
16821674

16831675
private getFieldContextType(parentName: string, node: FieldDefinitionNode): string {
1684-
if (this._fieldContextTypeMap[`${parentName}.${node.name}`]) {
1685-
return this._fieldContextTypeMap[`${parentName}.${node.name}`].type;
1676+
if (this._fieldContextTypeMap[`${parentName}.${node.name.value}`]) {
1677+
return this._fieldContextTypeMap[`${parentName}.${node.name.value}`].type;
16861678
}
16871679
return 'ContextType';
16881680
}
@@ -1691,7 +1683,7 @@ export class BaseResolversVisitor<
16911683
let contextType = this.getFieldContextType(parentName, node);
16921684

16931685
for (const directive of node.directives) {
1694-
const name = directive.name as unknown as string;
1686+
const name = directive.name.value;
16951687
const directiveMap = this._directiveContextTypesMap[name];
16961688
if (directiveMap) {
16971689
contextType = `${directiveMap.type}<${contextType}>`;
@@ -1750,7 +1742,7 @@ export class BaseResolversVisitor<
17501742
}
17511743

17521744
ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string | null {
1753-
const typeName = node.name as unknown as string;
1745+
const typeName = node.name.value;
17541746
const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node });
17551747
if (fieldsToGenerate.length === 0) {
17561748
return null;
@@ -1817,7 +1809,7 @@ export class BaseResolversVisitor<
18171809
.withName(name, `<${genericTypes.join(', ')}>`)
18181810
.withBlock(fieldsContent.join('\n'));
18191811

1820-
this._collectedResolvers[node.name as any] = {
1812+
this._collectedResolvers[node.name.value] = {
18211813
typename: name + '<ContextType>',
18221814
baseGeneratedTypename: name,
18231815
};
@@ -1836,11 +1828,11 @@ export class BaseResolversVisitor<
18361828
.map(f => `'${f}'`)
18371829
.join(' | ');
18381830

1839-
this._collectedResolvers[node.name as any] = {
1831+
this._collectedResolvers[node.name.value] = {
18401832
typename: name + '<ContextType>',
18411833
baseGeneratedTypename: name,
18421834
};
1843-
const parentType = this.getParentTypeToUse(node.name as any as string);
1835+
const parentType = this.getParentTypeToUse(node.name.value);
18441836

18451837
return new DeclarationBlock(this._declarationBlockConfig)
18461838
.export()
@@ -1856,15 +1848,15 @@ export class BaseResolversVisitor<
18561848
}
18571849

18581850
ScalarTypeDefinition(node: ScalarTypeDefinitionNode): string {
1859-
const nameAsString = node.name as any as string;
1851+
const nameAsString = node.name.value;
18601852
const baseName = this.getTypeToUse(nameAsString);
18611853

18621854
if (this._federation.skipScalar(nameAsString)) {
18631855
return null;
18641856
}
18651857

18661858
this._hasScalars = true;
1867-
this._collectedResolvers[node.name as any] = {
1859+
this._collectedResolvers[node.name.value] = {
18681860
typename: 'GraphQLScalarType',
18691861
};
18701862

@@ -1882,11 +1874,11 @@ export class BaseResolversVisitor<
18821874
}),
18831875
` extends GraphQLScalarTypeConfig<${baseName}, any>`
18841876
)
1885-
.withBlock(indent(`name: '${node.name}'${this.getPunctuation('interface')}`)).string;
1877+
.withBlock(indent(`name: '${node.name.value}'${this.getPunctuation('interface')}`)).string;
18861878
}
18871879

18881880
DirectiveDefinition(node: DirectiveDefinitionNode, key: string | number, parent: any): string {
1889-
if (this._federation.skipDirective(node.name as any)) {
1881+
if (this._federation.skipDirective(node.name.value)) {
18901882
return null;
18911883
}
18921884

@@ -1896,7 +1888,7 @@ export class BaseResolversVisitor<
18961888
const sourceNode = parent[key] as DirectiveDefinitionNode;
18971889
const hasArguments = sourceNode.arguments && sourceNode.arguments.length > 0;
18981890

1899-
this._collectedDirectiveResolvers[node.name as any] = directiveName + '<any, any, ContextType>';
1891+
this._collectedDirectiveResolvers[node.name.value] = directiveName + '<any, any, ContextType>';
19001892

19011893
const directiveArgsTypeName = this.convertName(node, {
19021894
suffix: 'DirectiveArgs',
@@ -1945,7 +1937,7 @@ export class BaseResolversVisitor<
19451937
}
19461938

19471939
EnumTypeDefinition(node: EnumTypeDefinitionNode): string {
1948-
const rawTypeName = node.name as any;
1940+
const rawTypeName = node.name.value;
19491941

19501942
// If we have enumValues set, and it's point to an external enum - we need to allow internal values resolvers
19511943
// In case we have enumValues set but as explicit values, no need to to do mapping since it's already
@@ -1978,7 +1970,7 @@ export class BaseResolversVisitor<
19781970
suffix: this.config.resolverTypeSuffix,
19791971
});
19801972
const declarationKind = 'type';
1981-
const typeName = node.name as any as string;
1973+
const typeName = node.name.value;
19821974
const implementingTypes = Object.keys(this._parsedSchemaMeta.types.interface[typeName].implementingTypes);
19831975

19841976
this._collectedResolvers[typeName] = {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export class TypeScriptResolversVisitor extends BaseResolversVisitor<
109109

110110
protected buildEnumResolverContentBlock(node: EnumTypeDefinitionNode, mappedEnumType: string): string {
111111
const valuesMap = `{ ${(node.values || [])
112-
.map(v => `${v.name as any as string}${this.config.avoidOptionals.resolvers ? '' : '?'}: any`)
112+
.map(v => `${v.name.value}${this.config.avoidOptionals.resolvers ? '' : '?'}: any`)
113113
.join(', ')} }`;
114114

115115
this._globalDeclarations.add(ENUM_RESOLVERS_SIGNATURE);
@@ -123,7 +123,7 @@ export class TypeScriptResolversVisitor extends BaseResolversVisitor<
123123
): string {
124124
return `{ ${(node.values || [])
125125
.map(v => {
126-
const valueName = v.name as any as string;
126+
const valueName = v.name.value;
127127
const mappedValue = valuesMapping[valueName];
128128
129129
return `${valueName}: ${typeof mappedValue === 'number' ? mappedValue : `'${mappedValue}'`}`;

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

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
GraphQLObjectType,
1010
GraphQLSchema,
1111
InterfaceTypeDefinitionNode,
12-
isInterfaceType,
1312
isObjectType,
1413
ObjectTypeDefinitionNode,
1514
OperationDefinitionNode,
@@ -239,7 +238,8 @@ export function addFederationReferencesToSchema(schema: GraphQLSchema): {
239238

240239
const transformedSchema = mapSchema(schema, {
241240
[MapperKind.INTERFACE_TYPE]: type => {
242-
const federationDetails = checkTypeFederationDetails(type, schema);
241+
const node = astFromInterfaceType(type, schema);
242+
const federationDetails = checkTypeFederationDetails(node, schema);
243243
if (federationDetails && federationDetails.resolvableKeyDirectives.length > 0) {
244244
const typeConfig = type.toConfig();
245245
typeConfig.fields = {
@@ -277,7 +277,8 @@ export function addFederationReferencesToSchema(schema: GraphQLSchema): {
277277
return type;
278278
},
279279
[MapperKind.OBJECT_TYPE]: type => {
280-
const federationDetails = checkTypeFederationDetails(type, schema);
280+
const node = astFromObjectType(type, schema);
281+
const federationDetails = checkTypeFederationDetails(node, schema);
281282
if (federationDetails && federationDetails.resolvableKeyDirectives.length > 0) {
282283
const typeConfig = type.toConfig();
283284

@@ -417,7 +418,7 @@ export class ApolloFederation {
417418
}: {
418419
node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode;
419420
}): readonly FieldDefinitionNode[] {
420-
const nodeName = node.name as unknown as string;
421+
const nodeName = node.name.value;
421422
if (this.fieldsToGenerate[nodeName]) {
422423
return this.fieldsToGenerate[nodeName];
423424
}
@@ -496,7 +497,7 @@ export class ApolloFederation {
496497
}
497498

498499
private hasProvides(node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode, fieldName: string): boolean {
499-
const fields = this.providesMap[node.name as unknown as string];
500+
const fields = this.providesMap[node.name.value];
500501

501502
if (fields?.length) {
502503
return fields.includes(fieldName);
@@ -534,22 +535,16 @@ export class ApolloFederation {
534535
* @param node Type
535536
*/
536537
function checkTypeFederationDetails(
537-
typeOrNode: ObjectTypeDefinitionNode | GraphQLObjectType | InterfaceTypeDefinitionNode | GraphQLInterfaceType,
538+
node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode,
538539
schema: GraphQLSchema
539540
): { resolvableKeyDirectives: readonly DirectiveNode[] } | false {
540-
const node = isObjectType(typeOrNode)
541-
? astFromObjectType(typeOrNode, schema)
542-
: isInterfaceType(typeOrNode)
543-
? astFromInterfaceType(typeOrNode, schema)
544-
: typeOrNode;
545-
546-
const name = node.name.value || (typeOrNode.name as unknown as string);
541+
const name = node.name.value;
547542
const directives = node.directives;
548543

549544
const rootTypeNames = getRootTypeNames(schema);
550545
const isNotRoot = !rootTypeNames.has(name);
551546
const isNotIntrospection = !name.startsWith('__');
552-
const keyDirectives = directives.filter(d => d.name.value === 'key' || (d.name as unknown as string) === 'key');
547+
const keyDirectives = directives.filter(d => d.name.value === 'key');
553548

554549
const check = isNotRoot && isNotIntrospection && keyDirectives.length > 0;
555550

@@ -576,24 +571,9 @@ function checkTypeFederationDetails(
576571
*/
577572
function getDirectivesByName(
578573
name: string,
579-
node: ObjectTypeDefinitionNode | GraphQLObjectType | FieldDefinitionNode | InterfaceTypeDefinitionNode
574+
node: ObjectTypeDefinitionNode | FieldDefinitionNode | InterfaceTypeDefinitionNode
580575
): readonly DirectiveNode[] {
581-
let astNode: ObjectTypeDefinitionNode | FieldDefinitionNode | InterfaceTypeDefinitionNode;
582-
583-
if (isObjectType(node) || isInterfaceType(node)) {
584-
astNode = node.astNode;
585-
} else {
586-
astNode = node;
587-
}
588-
589-
return (
590-
astNode?.directives?.filter(d => {
591-
// A ObjectTypeDefinitionNode's directive looks like `{ kind: 'Directive', name: 'external', arguments: [] }`
592-
// However, other directives looks like `{ kind: 'Directive', name: { kind: 'Name', value: 'external' }, arguments: [] }`
593-
// Therefore, we need to check for both `d.name.value` and d.name
594-
return d.name.value === name || (d.name as unknown as string) === name;
595-
}) || []
596-
);
576+
return node?.directives?.filter(d => d.name.value === name) || [];
597577
}
598578

599579
function extractReferenceSelectionSet(directive: DirectiveNode): ReferenceSelectionSet {

0 commit comments

Comments
 (0)