import { assertValidName } from 'graphql' import { GetGen, InterfaceFieldsFor, FieldResolver, ModificationType, AbstractTypeResolver, } from '../typegenTypeHelpers' import { AbstractTypes, NexusTypes, NonNullConfig, RootTypingDef, withNexusSymbol } from './_types' import { OutputDefinitionBlock, OutputDefinitionBuilder } from './definitionBlocks' import { ArgsRecord } from './args' import { messages } from '../messages' export type Implemented = GetGen<'interfaceNames'> | NexusInterfaceTypeDef export interface FieldModification { type?: ModificationType /** * The description to annotate the GraphQL SDL */ description?: string | null /** * The resolve method we should be resolving the field with */ resolve?: FieldResolver /** * You are allowed to add non-required args when modifying a field */ args?: ArgsRecord } export interface FieldModificationDef extends FieldModification { field: FieldName } export type NexusInterfaceTypeConfig = { name: TypeName // Really wanted to keep this here, but alas, it looks like there's some // issues around inferring the generic. // https://github.com/Microsoft/TypeScript/pull/29478 // https://github.com/Microsoft/TypeScript/issues/10195 // // resolveType: AbstractTypeResolver; definition(t: InterfaceDefinitionBlock): void /** * Configures the nullability for the type, check the * documentation's "Getting Started" section to learn * more about GraphQL Nexus's assumptions and configuration * on nullability. */ nonNullDefaults?: NonNullConfig /** * The description to annotate the GraphQL SDL */ description?: string | null /** * Root type information for this type */ rootTyping?: RootTypingDef } & AbstractTypes.MaybeTypeDefConfigFieldResolveType export interface InterfaceDefinitionBuilder extends OutputDefinitionBuilder { // TODO(tim): Remove before 1.0 setLegacyResolveType(fn: AbstractTypeResolver): void addInterfaces(toAdd: Implemented[]): void addModification(toAdd: FieldModificationDef): void } export class InterfaceDefinitionBlock extends OutputDefinitionBlock { constructor(protected typeBuilder: InterfaceDefinitionBuilder) { super(typeBuilder) } /** * @param interfaceName */ implements(...interfaceName: Array) { this.typeBuilder.addInterfaces(interfaceName) } /** * Modifies a field added via an interface */ modify, string>>( field: FieldName, modifications: FieldModification ) { this.typeBuilder.addModification({ ...modifications, field }) } /* istanbul ignore next */ protected resolveType(fn: AbstractTypeResolver) { console.error(new Error(messages.removedResolveType(this.typeBuilder.typeName))) this.typeBuilder.setLegacyResolveType(fn) } } export class NexusInterfaceTypeDef { constructor(readonly name: TypeName, protected config: NexusInterfaceTypeConfig) { assertValidName(name) } get value() { return this.config } } withNexusSymbol(NexusInterfaceTypeDef, NexusTypes.Interface) /** * Defines a GraphQLInterfaceType * @param config */ export function interfaceType(config: NexusInterfaceTypeConfig) { return new NexusInterfaceTypeDef(config.name, config) }