@@ -3,10 +3,10 @@ import {
33 ArgumentDefinition ,
44 CoreFeature ,
55 DirectiveDefinition ,
6- EnumType ,
6+ EnumType , InputObjectType ,
77 InputType ,
88 isCustomScalarType ,
9- isEnumType ,
9+ isEnumType , isInputObjectType ,
1010 isListType ,
1111 isNonNullType ,
1212 isObjectType ,
@@ -66,7 +66,13 @@ export type FieldSpecification = {
6666 args ?: ResolvedArgumentSpecification [ ] ,
6767}
6868
69- type ResolvedArgumentSpecification = {
69+ export type ResolvedArgumentSpecification = {
70+ name : string ,
71+ type : InputType ,
72+ defaultValue ?: any ,
73+ }
74+
75+ export type InputFieldSpecification = {
7076 name : string ,
7177 type : InputType ,
7278 defaultValue ?: any ,
@@ -251,6 +257,62 @@ export function createObjectTypeSpecification({
251257 }
252258}
253259
260+ export function createInputObjectTypeSpecification ( {
261+ name,
262+ inputFieldsFct,
263+ } : {
264+ name : string ,
265+ inputFieldsFct : ( schema : Schema , feature ?: CoreFeature ) => InputFieldSpecification [ ] ,
266+ } ) : TypeSpecification {
267+ return {
268+ name,
269+ checkOrAdd : ( schema : Schema , feature ?: CoreFeature , asBuiltIn ?: boolean ) => {
270+ const actualName = feature ?. typeNameInSchema ( name ) ?? name ;
271+ const expectedFields = inputFieldsFct ( schema , feature ) ;
272+ const existing = schema . type ( actualName ) ;
273+ if ( existing ) {
274+ let errors = ensureSameTypeKind ( 'InputObjectType' , existing ) ;
275+ if ( errors . length > 0 ) {
276+ return errors ;
277+ }
278+ assert ( isInputObjectType ( existing ) , 'Should be an input object type' ) ;
279+ for ( const { name : field_name , type, defaultValue } of expectedFields ) {
280+ const existingField = existing . field ( field_name ) ;
281+ if ( ! existingField ) {
282+ errors = errors . concat ( ERRORS . TYPE_DEFINITION_INVALID . err (
283+ `Invalid definition of type ${ name } : missing input field ${ field_name } ` ,
284+ { nodes : existing . sourceAST } ,
285+ ) ) ;
286+ continue ;
287+ }
288+ if ( ! sameType ( type , existingField . type ! ) ) {
289+ errors = errors . concat ( ERRORS . TYPE_DEFINITION_INVALID . err (
290+ `Invalid definition for field ${ field_name } of type ${ name } : should have type ${ type } but found type ${ existingField . type } ` ,
291+ { nodes : existingField . sourceAST } ,
292+ ) ) ;
293+ }
294+ if ( defaultValue !== existingField . defaultValue ) {
295+ errors = errors . concat ( ERRORS . TYPE_DEFINITION_INVALID . err (
296+ `Invalid definition for field ${ field_name } of type ${ name } : should have default value ${ defaultValue } but found type ${ existingField . defaultValue } ` ,
297+ { nodes : existingField . sourceAST } ,
298+ ) ) ;
299+ }
300+ }
301+ return errors ;
302+ } else {
303+ const createdType = schema . addType ( new InputObjectType ( actualName , asBuiltIn ) ) ;
304+ for ( const { name, type, defaultValue } of expectedFields ) {
305+ const newField = createdType . addField ( name , type ) ;
306+ if ( defaultValue ) {
307+ newField . defaultValue = defaultValue ;
308+ }
309+ }
310+ return [ ] ;
311+ }
312+ } ,
313+ }
314+ }
315+
254316export function createUnionTypeSpecification ( {
255317 name,
256318 membersFct,
0 commit comments