import { ArgumentRef } from '../refs/arg'; import { InputFieldRef } from '../refs/input-field'; import { InputListRef } from '../refs/input-list'; import type { ArgBuilder, FieldRequiredness, InputOrArgRef, InputShapeFromTypeParam, InputType, InputTypeParam, NormalizeArgs, SchemaTypes, } from '../types'; import { inputTypeFromParam } from '../utils'; export class InputFieldBuilder< Types extends SchemaTypes, Kind extends keyof PothosSchemaTypes.InputFieldOptionsByKind, > { kind: Kind; builder: PothosSchemaTypes.SchemaBuilder; /** * Create a Boolean input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ boolean = this.helper('Boolean'); /** * Create a Float input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ float = this.helper('Float'); /** * Create a ID input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ id = this.helper('ID'); /** * Create a Int input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ int = this.helper('Int'); /** * Create a String input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ string = this.helper('String'); /** * Create a Boolean list input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ booleanList = this.helper(['Boolean']); /** * Create a Float list input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ floatList = this.helper(['Float']); /** * Create a ID list input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ idList = this.helper(['ID']); /** * Create a Int list input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ intList = this.helper(['Int']); /** * Create a String list input field * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ stringList = this.helper(['String']); constructor(builder: PothosSchemaTypes.SchemaBuilder, kind: Kind) { this.builder = builder; this.kind = kind; } listRef = , Required extends boolean = true>( type: T, options?: { required?: Required }, ): InputListRef[]> => new InputListRef[]>( type, options?.required ?? true, ); argBuilder(): ArgBuilder { const builder = this.field.bind(this as never) as InputFieldBuilder['field']; const protoKeys = Object.keys(Object.getPrototypeOf(this) as object).filter( (key) => typeof (this as Record)[key] === 'function' && (Function.prototype as unknown as Record)[key] === undefined, ); for (const key of [...Object.keys(this), ...protoKeys] as (keyof InputFieldBuilder< Types, 'Arg' >)[]) { (builder as unknown as Record)[key] = typeof this[key] === 'function' ? (this[key] as Function).bind(this) : this[key]; } return builder as ArgBuilder; } /** * Create in input field or argument for the current type * @param {PothosSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ field | [InputType], Req extends FieldRequiredness>( options: PothosSchemaTypes.InputFieldOptionsByKind[Kind], ): InputOrArgRef, Kind> { const ref = this.kind === 'Arg' ? new ArgumentRef((name, field, typeConfig) => { const opts = options as PothosSchemaTypes.ArgFieldOptions; return { name, parentField: field, kind: this.kind, graphqlKind: this.kind, parentType: typeConfig.name, type: inputTypeFromParam( opts.type, this.builder.configStore, opts.required ?? this.builder.defaultInputFieldRequiredness, ), pothosOptions: opts, description: opts.description, deprecationReason: opts.deprecationReason, defaultValue: opts.defaultValue, extensions: opts.extensions ?? {}, astNode: opts.astNode, }; }) : new InputFieldRef((name, typeConfig) => { const opts = options as PothosSchemaTypes.InputFieldOptions; return { name, parentField: undefined, kind: this.kind, graphqlKind: this.kind, parentType: typeConfig.name, type: inputTypeFromParam( opts.type, this.builder.configStore, opts.required ?? this.builder.defaultInputFieldRequiredness, ), pothosOptions: opts, description: opts.description, deprecationReason: opts.deprecationReason, defaultValue: opts.defaultValue, extensions: opts.extensions ?? {}, astNode: opts.astNode, }; }); return ref as InputOrArgRef, Kind>; } private helper | [InputType]>(type: Type) { return >( ...args: NormalizeArgs< [options: Omit[Kind], 'type'>] > ) => { const [options = {} as never] = args; return this.field({ ...options, type, } as PothosSchemaTypes.InputFieldOptionsByKind[Kind]); }; } }