diff --git a/.gitignore b/.gitignore index 934db85..8251d56 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,7 @@ typings/ .dynamodb/ dist/ + +# Intellij IDEA Configuration +.idea +*.iml diff --git a/src/transform-federation.ts b/src/transform-federation.ts index c0f7d95..7e63f56 100644 --- a/src/transform-federation.ts +++ b/src/transform-federation.ts @@ -58,6 +58,10 @@ export function transformSchemaFederation( const entityTypes = Object.fromEntries( Object.entries(federationConfig) .filter(([, { keyFields }]) => keyFields && keyFields.length) + .filter(([objectName]) => { + const type = schemaWithQueryType.getType(objectName); + return !isInterfaceType(type); + }) .map(([objectName]) => { const type = schemaWithQueryType.getType(objectName); if (!isObjectType(type)) { diff --git a/src/transform-sdl.ts b/src/transform-sdl.ts index 21f595e..8ee1125 100644 --- a/src/transform-sdl.ts +++ b/src/transform-sdl.ts @@ -1,5 +1,5 @@ import { - FieldDefinitionNode, + FieldDefinitionNode, InterfaceTypeDefinitionNode, ObjectTypeDefinitionNode, ObjectTypeExtensionNode, parse, @@ -13,6 +13,7 @@ import { FederationFieldsConfig, FederationObjectConfig, } from './transform-federation'; +import { InterfaceTypeExtensionNode } from 'graphql'; function createDirectiveWithFields(directiveName: string, fields: string) { return createDirectiveNode(directiveName, { @@ -86,10 +87,45 @@ export function addFederationAnnotations( ) : []; + if (extend) { + newDirectives.push(createDirectiveNode('extends')) + } + + return { + ...node, + directives: [...(node.directives || []), ...newDirectives], + kind: (extend ? 'ObjectTypeExtension' : node.kind) + }; + } + }, + leave() { + currentObjectName = undefined; + }, + }, + InterfaceTypeDefinition: { + enter( + node: InterfaceTypeDefinitionNode, + ): InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode | undefined { + currentObjectName = node.name.value; + if (objectTypesTodo.has(currentObjectName)) { + objectTypesTodo.delete(currentObjectName); + + const { keyFields, extend } = federationConfig[currentObjectName]; + + const newDirectives = keyFields + ? keyFields.map((keyField) => + createDirectiveWithFields('key', keyField), + ) + : []; + + if (extend) { + newDirectives.push(createDirectiveNode('extends')) + } + return { ...node, directives: [...(node.directives || []), ...newDirectives], - kind: extend ? 'ObjectTypeExtension' : node.kind, + kind: (extend ? 'InterfaceTypeExtension' : node.kind) }; } },