import { defaultFieldResolver } from 'graphql'; import type { ArgumentRef } from '../refs/arg'; import { FieldRef } from '../refs/field'; import type { FieldKind, FieldNullability, InputFieldMap, PothosInputFieldConfig, Resolver, SchemaTypes, ShapeFromTypeParam, TypeParam, } from '../types'; import { typeFromParam } from '../utils'; export class BaseFieldUtil { kind: Kind; graphqlKind: PothosSchemaTypes.PothosKindToGraphQLType[Kind]; builder: PothosSchemaTypes.SchemaBuilder; constructor( builder: PothosSchemaTypes.SchemaBuilder, kind: Kind, graphqlKind: PothosSchemaTypes.PothosKindToGraphQLType[Kind], ) { this.builder = builder; this.kind = kind; this.graphqlKind = graphqlKind; } protected createField< Type extends TypeParam, Nullable extends FieldNullability, Args extends InputFieldMap = {}, >( // biome-ignore lint/suspicious/noExplicitAny: this is fine options: PothosSchemaTypes.FieldOptions & { resolve?: Resolver; }, ): FieldRef, Kind> { const ref = new FieldRef, Kind>( this.kind, (name, typeConfig) => { const args: Record> = {}; if (options.args) { for (const [argName, arg] of Object.entries(options.args)) { args[argName] = (arg as ArgumentRef).getConfig( argName, name, typeConfig, ); } } let { resolve } = options as { resolve?: (...argList: unknown[]) => unknown }; if (options.extensions?.pothosExposedField === name) { resolve = defaultFieldResolver as typeof resolve; } const { subscribe } = options as { subscribe?: (...argList: unknown[]) => unknown }; return { kind: this.kind as never, graphqlKind: typeConfig.graphqlKind as 'Interface' | 'Object', parentType: typeConfig.name, name, args, argMappers: [], type: typeFromParam( options.type, this.builder.configStore, options.nullable ?? this.builder.defaultFieldNullability, ), pothosOptions: options as never, extensions: { pothosOriginalResolve: resolve, pothosOriginalSubscribe: subscribe, ...options.extensions, }, description: options.description, deprecationReason: options.deprecationReason, resolve, subscribe, astNode: options.astNode, }; }, ); return ref; } protected exposeField< Type extends TypeParam, Nullable extends FieldNullability, Name extends string & keyof ParentShape, >( name: Name, { extensions, ...options }: PothosSchemaTypes.ObjectFieldOptions, ): FieldRef, Kind> { return this.createField({ ...options, extensions: { pothosExposedField: name, ...extensions, }, resolve: (parent) => (parent as Record)[name as string], }); } }