import { InputType, SchemaTypes } from '../types'; import { inputTypeFromParam } from '../utils'; import { ArgBuilder, FieldRequiredness, InputFieldRef, InputShapeFromTypeParam, NormalizeArgs, } from '..'; export default class InputFieldBuilder< Types extends SchemaTypes, Kind extends keyof GiraphQLSchemaTypes.InputFieldOptionsByKind, > { builder: GiraphQLSchemaTypes.SchemaBuilder; kind: Kind; typename: string; /** * Create a Boolean input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ boolean = this.helper('Boolean'); /** * Create a Float input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ float = this.helper('Float'); /** * Create a ID input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ id = this.helper('ID'); /** * Create a Int input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ int = this.helper('Int'); /** * Create a String input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ string = this.helper('String'); /** * Create a Boolean list input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ booleanList = this.helper(['Boolean']); /** * Create a Float list input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ floatList = this.helper(['Float']); /** * Create a ID list input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ idList = this.helper(['ID']); /** * Create a Int list input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ intList = this.helper(['Int']); /** * Create a String list input field * @param {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ stringList = this.helper(['String']); constructor(builder: GiraphQLSchemaTypes.SchemaBuilder, kind: Kind, typename: string) { this.builder = builder; this.kind = kind; this.typename = typename; } 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, ); ([...Object.keys(this), ...protoKeys] as (keyof InputFieldBuilder)[]).forEach( (key) => { (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 {GiraphQLSchemaTypes.InputFieldOptions} [options={}] - Options for this field */ field | [InputType], Req extends FieldRequiredness>( options: GiraphQLSchemaTypes.InputFieldOptionsByKind[Kind], ) { const ref: InputFieldRef, Kind> = new InputFieldRef( this.kind, this.typename, ); this.builder.configStore.addFieldRef(ref, options.type, {}, (name, parentField) => ({ name, parentField, kind: this.kind, graphqlKind: this.kind, parentType: this.typename, type: inputTypeFromParam( options.type, this.builder.configStore, options.required ?? this.builder.defaultInputFieldRequiredness, ), giraphqlOptions: options as unknown as GiraphQLSchemaTypes.InputFieldOptionsByKind[Kind], description: options.description, deprecationReason: options.deprecationReason, defaultValue: options.defaultValue, extensions: options.extensions, })); return ref; } private helper | [InputType]>(type: Type) { return >( ...args: NormalizeArgs< [ options?: Omit< GiraphQLSchemaTypes.InputFieldOptionsByKind[Kind], 'type' >, ] > ) => { const [options = {} as never] = args; return this.field({ ...options, type, } as GiraphQLSchemaTypes.InputFieldOptionsByKind[Kind]); }; } }