UNPKG

@pothos/plugin-federation

Version:

A Pothos plugin for implementing apollo federation subGraphs

103 lines (90 loc) 2.79 kB
import { FieldBuilder, type InterfaceParam, type MaybePromise, ObjectRef, RootFieldBuilder, type SchemaTypes, } from '@pothos/core'; import type { GraphQLResolveInfo } from 'graphql'; import type { ExternalEntityOptions, Selection, SelectionFromShape, selectionShapeKey, } from './types'; import { addUsedDirectives, keyDirective, mergeDirectives } from './util'; export const providesMap = new WeakMap<{}, string>(); export class ExternalEntityRef< Types extends SchemaTypes, Shape extends object, Key extends Selection<object>, > extends ObjectRef<Types, Shape> { override kind = 'Object' as const; builder: PothosSchemaTypes.SchemaBuilder<Types>; private key?: Key | Key[]; private resolveReference?: ( parent: object, context: Types['Context'], info: GraphQLResolveInfo, ) => MaybePromise<Shape | null | undefined>; constructor( builder: PothosSchemaTypes.SchemaBuilder<Types>, name: string, { key, resolveReference, }: { key?: Key | Key[]; resolveReference?: ( parent: Key[typeof selectionShapeKey], context: Types['Context'], info: GraphQLResolveInfo, ) => MaybePromise<Shape | null | undefined>; }, ) { super(name); this.builder = builder; this.key = key; this.resolveReference = resolveReference; } implement<const Interfaces extends InterfaceParam<Types>[]>({ fields, externalFields, directives, ...options }: ExternalEntityOptions<Types, Shape, Interfaces>) { addUsedDirectives(this.builder, ['extends', 'key']); this.builder.objectType(this as unknown as ObjectRef<Types, unknown>, { ...(options as {} as PothosSchemaTypes.ObjectTypeOptions<Types, Shape>), name: this.name, directives: mergeDirectives(directives as [], [ ...(this.key ? keyDirective(this.key) : []), { name: 'extends', args: {} }, ]) as [], fields: () => ({ ...externalFields?.( new RootFieldBuilder(this.builder, 'ExternalEntity', 'Object') as never, ), ...fields?.(new FieldBuilder(this.builder, 'ExtendedEntity', 'Object') as never), }), extensions: { ...options.extensions, apollo: { ...(options.extensions?.apollo as {}), subgraph: { ...(options.extensions?.apollo as { subgraph: {} })?.subgraph, resolveReference: this.resolveReference, }, }, }, }); return this; } provides<T extends object>(selection: SelectionFromShape<T>) { const ref = Object.create(this) as ExternalEntityRef<Types, Shape & T, Key>; providesMap.set(ref, selection); this.builder.configStore.associateParamWithRef(ref, this); return ref; } }