@@ -2366,14 +2366,16 @@ ERROR
2366
2366
2367
2367
** Formal Specification**
2368
2368
2369
- - Let {typeNames} be the set of all output type names from all source schemas.
2369
+ - Let {typeNames} be the set of all output type names from all source schemas
2370
+ that are not declared as ` @inaccessible ` in any schema.
2370
2371
- For each {typeName} in {typeNames}
2371
2372
- Let {types} be the set of all types with the {typeName} from all source
2372
- schemas.
2373
- - Let {fieldNames} be the set of all field names from all {types}.
2373
+ schemas that are not declared as ` @internal ` .
2374
+ - Let {fieldNames} be the set of all field names from all {types} that are not
2375
+ declared as ` @inaccessible ` in any schema.
2374
2376
- For each {fieldName} in {fieldNames}
2375
2377
- Let {fields} be the set of all fields with the {fieldName} from all
2376
- {types}.
2378
+ {types} that are not declared as ` @internal ` .
2377
2379
- For each {field} in {fields}
2378
2380
- Let {argumentNames} be the set of all argument names from all {fields}.
2379
2381
- For each {argumentName} in {argumentNames}
@@ -2386,7 +2388,7 @@ ArgumentsAreMergeable(argumentA, argumentB):
2386
2388
2387
2389
- Let {typeA} be the type of {argumentA}
2388
2390
- Let {typeB} be the type of {argumentB}
2389
- - {InputTypesAreMergeable (typeA, typeB)} must be true.
2391
+ - {SameTypeShape (typeA, typeB)} must be true.
2390
2392
2391
2393
** Explanatory Text**
2392
2394
@@ -3882,12 +3884,19 @@ MergeInputTypes(types):
3882
3884
- Set {description } to the description of {type }.
3883
3885
- Let {fieldNames } be the set of all field names in {types }.
3884
3886
- For each {fieldName } in {fieldNames }:
3885
- - Let {fields } be the set of fields with the name {fieldName } in {types }.
3886
- - Let {mergedField } be the result of {MergeInputFields (fields)}.
3887
+ - Let {fieldDefinitions } be the set of fields with the name {fieldName } in
3888
+ {types }.
3889
+ - If length of {fieldDefinitions } is not equal to the length of {types }:
3890
+ - Continue
3891
+ - If any field in {fieldDefinitions } is marked with `@inaccessible `
3892
+ - Continue
3893
+ - Let {mergedField } be the result of {MergeInputField (fieldDefinitions)}.
3887
3894
- If {mergedField } is not {null }:
3888
- - Add {mergedField } to {mergedFields }.
3889
- - Return a new input object type with the name of {typeName }, description of
3890
- {description }, fields of {mergedFields }.
3895
+ - Add {mergedField } to {fields }.
3896
+ - If {fields } is empty :
3897
+ - Return {null }
3898
+ - Return a new input type with the name of {typeName }, description of
3899
+ {description }, and fields of {fields }.
3891
3900
3892
3901
**Explanatory Text **
3893
3902
@@ -3919,10 +3928,18 @@ instance, because one of its underlying definitions was inaccessible - that
3919
3928
field is not included in the final definition . The end result is a single input
3920
3929
type that correctly unifies every compatible field from the various sources .
3921
3930
3931
+ After filtering out inaccessible types , the algorithm takes the **intersection **
3932
+ of the field names across the remaining types - only those fields that appear in
3933
+ **every ** source definition are eligible . For each eligible field , it invokes
3934
+ {MergeInputField (fieldsForName)} to reconcile differences in type , nullability ,
3935
+ default values , etc . The end result is a single input type that correctly
3936
+ unifies every compatible field that appears in all source types .
3937
+
3922
3938
**Examples **
3923
3939
3924
3940
Here , two `OrderInput ` input types from different schemas are merged into a
3925
- single composed `OrderInput ` type .
3941
+ single composed `OrderInput ` type . Notice that only the fields present in _both_
3942
+ schemas are included .
3926
3943
3927
3944
```graphql example
3928
3945
# Schema A
@@ -3943,15 +3960,11 @@ input OrderInput {
3943
3960
3944
3961
input OrderInput {
3945
3962
id : ID !
3946
- description : String
3947
- total : Float
3948
3963
}
3949
3964
```
3950
3965
3951
- In this example , the `OrderInput ` type from two schemas is merged . The `id `
3952
- field is shared across both schemas , while `description ` and `total ` fields are
3953
- contributed by the individual source schemas . The resulting composed type
3954
- includes all fields .
3966
+ Although `description ` appears in Schema A and `total ` appears in Schema B ,
3967
+ neither field is defined in _both_ schemas ; therefore , only `id ` remains .
3955
3968
3956
3969
Another example demonstrates preserving descriptions during merging :
3957
3970
@@ -4168,7 +4181,13 @@ MergeOutputFields(fields):
4168
4181
- Let {argumentNames } be the set of all argument names in {fields }.
4169
4182
- For each {argumentName } in {argumentNames }:
4170
4183
- Let {arguments } be the set of arguments with the name {argumentName } in
4171
- {fields }.
4184
+ {fields }
4185
+ - If length of {arguments } is not equal to the length of {fields }:
4186
+ - Continue .
4187
+ - If any argument in {arguments } is marked with `@inaccessible `:
4188
+ - Continue .
4189
+ - If any argument in {arguments } is marked with `@require `:
4190
+ - Continue .
4172
4191
- Let {mergedArgument } be the result of {MergeArgumentDefinitions (arguments)}.
4173
4192
- If {mergedArgument } is not {null }:
4174
4193
- Add {mergedArgument } to {mergedArguments }.
@@ -4217,17 +4236,14 @@ schema does not break schemas expecting any of those types. For example,
4217
4236
4218
4237
_Merging Arguments_
4219
4238
4220
- Each field can declare arguments . The algorithm collects all all argument names
4221
- across these fields and merges them using {MergeArgumentDefinitions (arguments)},
4222
- ensuring argument definitions remain compatible . If any of the arguments for a
4223
- particular name is `@inaccessible `, then that argument is removed from the final
4224
- set of arguments . Otherwise , any differences in argument type , default value , or
4225
- description are resolved via the merging rules in
4226
- {MergeArgumentDefinitions (arguments)}.
4227
-
4228
- This algorithm preserves as much information as possible from the source fields
4229
- while ensuring they remain mutually compatible . It also systematically excludes
4230
- fields or arguments deemed inaccessible .
4239
+ Each field can declare arguments . The algorithm collects all argument names
4240
+ across these fields and merges them using {MergeArgumentDefinitions (arguments)}.
4241
+ Before merging , any arguments marked with `@inaccessible ` or `@require ` are
4242
+ excluded . If this exclusion causes the number of arguments available for a given
4243
+ name to differ from the total number of fields - or if at least one schema omits
4244
+ the argument - the argument is skipped entirely. Otherwise, any differences in
4245
+ argument type, default value, or description are resolved via the merging rules
4246
+ in {MergeArgumentDefinitions (arguments )}.
4231
4247
4232
4248
**Example **
4233
4249
@@ -4260,6 +4276,67 @@ type Product {
4260
4276
}
4261
4277
```
4262
4278
4279
+ If the argument is missing in one of the schemas , the composed field will not
4280
+ include that argument :
4281
+
4282
+ ```graphql example
4283
+ # Schema A
4284
+ type Product {
4285
+ discountPercentage (percent : Int ): Int
4286
+ }
4287
+
4288
+ # Schema B
4289
+ type Product {
4290
+ discountPercentage : Int
4291
+ }
4292
+
4293
+ # Composed Result
4294
+ type Product {
4295
+ discountPercentage : Int
4296
+ }
4297
+ ```
4298
+
4299
+ In case one argument is marked with `@inaccessible `, the composed field will not
4300
+ include that argument :
4301
+
4302
+ ```graphql example
4303
+ # Schema A
4304
+ type Product {
4305
+ discountPercentage (percent : Int ): Int
4306
+ }
4307
+
4308
+ # Schema B
4309
+ type Product {
4310
+ discountPercentage (percent : Int @inaccessible ): Int
4311
+ }
4312
+
4313
+ # Composed Result
4314
+ type Product {
4315
+ discountPercentage : Int
4316
+ }
4317
+ ```
4318
+
4319
+ In case a schema defines a requirement through the `@require ` directive, the
4320
+ composed field will not include that argument
4321
+
4322
+ ```graphql example
4323
+ # Schema A
4324
+ type Product {
4325
+ discountPercentage (percent : Int ): Int
4326
+ discount : Int
4327
+ }
4328
+
4329
+ # Schema B
4330
+ type Product {
4331
+ discountPercentage (percent : Int @require (field : " discount" )): Int
4332
+ }
4333
+
4334
+ # Composed Result
4335
+ type Product {
4336
+ discountPercentage : Int
4337
+ }
4338
+ ```
4339
+
4263
4340
#### Merge Input Fields
4264
4341
4265
4342
**Formal Specification **
@@ -4275,6 +4352,7 @@ MergeInputFields(fields):
4275
4352
- Let {defaultValue } be the default value of {firstField } or undefined if none
4276
4353
exists .
4277
4354
- For each {field } in {fields }:
4355
+ - Assert : {field } is **not ** marked with `@inaccessible `
4278
4356
- Let {type } be the type of {field}.
4279
4357
- Set {fieldType } to be the result of {MostRestrictiveType (fieldType, type)}.
4280
4358
- If {description } is null :
@@ -4295,8 +4373,9 @@ breakdown of how {MergeInputFields(fields)} operates:
4295
4373
4296
4374
_Inaccessible Fields_
4297
4375
4298
- If any of the fields is marked with `@inaccessible `, we cannot include the field
4299
- in the composed schema , and the merge algorithm returns `null`.
4376
+ Before calling {MergeInputField (fields)}, all fields marked with `@inaccessible `
4377
+ must be filtered out . If any such field appears in the input , it is a
4378
+ precondition violation of this algorithm .
4300
4379
4301
4380
_Combining Descriptions_
4302
4381
@@ -4368,8 +4447,8 @@ MergeArgumentDefinitions(arguments):
4368
4447
- If {mergedArgument } is null
4369
4448
- Return null
4370
4449
- For each {argument } in {arguments }:
4371
- - If {argument } is marked with `@require `
4372
- - Continue
4450
+ - Assert : {argument } is ** not ** marked with `@inaccessible `
4451
+ - Assert : { argument } is ** not ** marked with ` @require `
4373
4452
- Set {mergedArgument } to the result of {MergeArguments (mergedArgument,
4374
4453
argument)}
4375
4454
- Return {mergedArgument }
@@ -4382,26 +4461,27 @@ definition.
4382
4461
4383
4462
_Inaccessible Arguments_
4384
4463
4385
- If any argument in the set is marked with `@inaccessible `, the entire argument
4386
- definition is discarded by returning `null `. An inaccessible argument should not
4387
- appear in the final composed schema .
4464
+ Inaccessible arguments (`@inaccessible`) should be handled and filtered out
4465
+ **before ** calling {MergeArgumentDefinitions (arguments)}. By the time this
4466
+ algorithm is invoked , any arguments marked `@inaccessible ` must already be
4467
+ removed . If such an argument somehow appears here , it is a precondition
4468
+ violation of this algorithm .
4388
4469
4389
4470
_Handling `@require `_
4390
4471
4391
- The `@require ` directive is used to indicate that the argument is required for
4392
- the field to be resolved, yet it specifies it as a dependency that is resolved
4393
- at runtime. Therefore, this argument should not affect the merge process. If
4394
- there are only `@require ` arguments in the set, the merge algorithm returns
4395
- `null`.
4472
+ The `@require ` directive is likewise handled **before ** this algorithm .
4473
+ Arguments marked with `@require ` do not participate in the merge process and
4474
+ must be filtered out of the input . If any `@require ` arguments are included in
4475
+ this function , it is also a precondition violation .
4396
4476
4397
4477
_Merging Arguments_
4398
4478
4399
- All arguments that are not marked with `@require ` are merged using the
4400
- ` MergeArgument` algorithm . This algorithm ensures that the final composed
4401
- argument is compatible with all definitions of that argument, resolving
4402
- differences in type, default value, and description.
4479
+ All remaining arguments (those not marked `@inaccessible` or `@require`) are
4480
+ merged via { MergeArgument (mergedArgument, argument)} . This algorithm ensures
4481
+ that the final composed argument is compatible with all definitions of that
4482
+ argument , resolving differences in type , default value , and description .
4403
4483
4404
- By selectively including or excluding certain arguments (via ` @inaccessible ` or
4484
+ By selectively merging differences where possible , this algorithm ensures that
4405
4485
`@require `), and merging differences where possible , this algorithm ensures that
4406
4486
the resulting composed argument is both valid and compatible with the source
4407
4487
definitions .
0 commit comments