@@ -3,10 +3,10 @@ import {
3
3
ArgumentDefinition ,
4
4
CoreFeature ,
5
5
DirectiveDefinition ,
6
- EnumType ,
6
+ EnumType , InputObjectType ,
7
7
InputType ,
8
8
isCustomScalarType ,
9
- isEnumType ,
9
+ isEnumType , isInputObjectType ,
10
10
isListType ,
11
11
isNonNullType ,
12
12
isObjectType ,
@@ -66,7 +66,13 @@ export type FieldSpecification = {
66
66
args ?: ResolvedArgumentSpecification [ ] ,
67
67
}
68
68
69
- type ResolvedArgumentSpecification = {
69
+ export type ResolvedArgumentSpecification = {
70
+ name : string ,
71
+ type : InputType ,
72
+ defaultValue ?: any ,
73
+ }
74
+
75
+ export type InputFieldSpecification = {
70
76
name : string ,
71
77
type : InputType ,
72
78
defaultValue ?: any ,
@@ -251,6 +257,62 @@ export function createObjectTypeSpecification({
251
257
}
252
258
}
253
259
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
+
254
316
export function createUnionTypeSpecification ( {
255
317
name,
256
318
membersFct,
0 commit comments