Skip to content

Commit

Permalink
formatting and expand examples
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed May 20, 2024
1 parent 492c556 commit b4f3c5d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 39 deletions.
21 changes: 11 additions & 10 deletions spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -1220,12 +1220,13 @@ size `60`:
**Variable Use Within Fragments**

Variables can be used within fragments. Operation-defined variables have global
scope within a given operation. Fragment-defined variables have local scope within the
fragment definition in which they are defined. A variable used within a fragment must either
be declared in each top-level operation that transitively consumes that fragment,
or by that same fragment as a fragment variable definition. If a variable
referenced in a fragment is included by an operation where neither the fragment
nor the operation defines that variable, that operation is invalid (see
scope within a given operation. Fragment-defined variables have local scope
within the fragment definition in which they are defined. A variable used within
a fragment must either be declared in each top-level operation that transitively
consumes that fragment, or by that same fragment as a fragment variable
definition. If a variable referenced in a fragment is included by an operation
where neither the fragment nor the operation defines that variable, that
operation is invalid (see
[All Variable Uses Defined](#sec-All-Variable-Uses-Defined)).

## Fragment Variable Definitions
Expand Down Expand Up @@ -1279,10 +1280,10 @@ fragment dynamicProfilePic($size: Int!) on User {
```

The profilePic for `user` will be determined by the variables set by the
operation, while `secondUser` will always have a `profilePic` of size `10`. In this
case, the fragment `variableProfilePic` uses the operation-defined variable,
while `dynamicProfilePic` uses the value passed in via the fragment spread's
`size` argument.
operation, while `secondUser` will always have a `profilePic` of size `10`. In
this case, the fragment `variableProfilePic` uses the operation-defined
variable, while `dynamicProfilePic` uses the value passed in via the fragment
spread's `size` argument.

## Type References

Expand Down
33 changes: 23 additions & 10 deletions spec/Section 5 -- Validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,10 @@ FieldsInSetCanMerge(set):
- Let {spreadsForName} be the set of fragment spreads with a given name in
{visitedSelections}.
- For each {spreadsForName} as {name} and {spreads}:
- Each entry in {spreads} must have identical sets of arguments to each other entry in {spreads}.
- Let {fieldsForName} be the set of field selections with a given response name in
{visitedSelections}.
- Each entry in {spreads} must have identical sets of arguments to each other
entry in {spreads}.
- Let {fieldsForName} be the set of field selections with a given response name
in {visitedSelections}.
- Given each pair of members {fieldA} and {fieldB} in {fieldsForName}:
- {SameResponseShape(fieldA, fieldB)} must be true.
- If the parent types of {fieldA} and {fieldB} are equal or if either is not
Expand Down Expand Up @@ -602,8 +603,9 @@ the fragment spread `...commandFragment(command: SIT)` and
`...commandFragment(command: DOWN)` are part of the visited selections that will
be merged.

If both of these spreads would have `$commandOne` or `$commandTwo` as the argument-value,
it would be allowed as we can be sure that we'd resolve identical fields.
If both of these spreads would have `$commandOne` or `$commandTwo` as the
argument-value, it would be allowed as we can be sure that we'd resolve
identical fields.

### Leaf Field Selections

Expand Down Expand Up @@ -699,8 +701,8 @@ validation rules apply in each case.

**Explanatory Text**

Every argument provided to a field or directive or fragment spread must be
defined in the set of possible arguments of that field, directive or fragment.
Every argument provided to a field or directive must be defined in the set of
possible arguments of that field or directive.

For example the following are valid:

Expand All @@ -712,7 +714,13 @@ fragment argOnRequiredArg on Dog {
fragment argOnOptional on Dog {
isHouseTrained(atOtherHomes: true) @include(if: true)
}
```

The above is also applicable to fragment-definitions and fragment-spreads, each
variable must be defined by the fragment-definition before it can be inserted as
an argument by the fragment-spread.

```graphql example
fragment withFragmentArg($command: DogCommand) on Dog {
doesKnowCommand(dogCommand: $command)
}
Expand All @@ -738,6 +746,10 @@ and this is also invalid as the argument `dogCommand` is not defined on fragment
fragment invalidFragmentArgName on Dog {
...withFragmentArg(dogCommand: SIT)
}

fragment withFragmentArg($command: DogCommand) on Dog {
doesKnowCommand(dogCommand: $command)
}
```

and this is also invalid as `unless` is not defined on `@include`.
Expand Down Expand Up @@ -1620,8 +1632,8 @@ fragment HouseTrainedFragment on Query {
}
```

Likewise, it is valid for a fragment to define a variable with a name that
is also defined on an operation:
Likewise, it is valid for a fragment to define a variable with a name that is
also defined on an operation:

```graphql example
query C($atOtherHomes: Boolean) {
Expand Down Expand Up @@ -1989,7 +2001,8 @@ fragment fragmentArgUnused($atOtherHomes: Boolean) on Dog {
}
```

This document is invalid: fragment `fragmentArgUnused` defines a fragment variable `$atOtherHomes`, but this variable is not used within this fragment.
This document is invalid: fragment `fragmentArgUnused` defines a fragment
variable `$atOtherHomes`, but this variable is not used within this fragment.

### All Variable Usages Are Allowed

Expand Down
47 changes: 28 additions & 19 deletions spec/Section 6 -- Execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,8 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues):
- For each {groupedFieldSet} as {responseKey} and {fields}:
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
is unaffected if an alias is used.
- Let {fragmentVariableValues} be the fragment-variables value of the first entry in {fields}.
- Let {fragmentVariableValues} be the fragment-variables value of the first
entry in {fields}.
- Let {fieldType} be the return type defined for the field {fieldName} of
{objectType}.
- If {fieldType} is defined:
Expand Down Expand Up @@ -493,21 +494,22 @@ The depth-first-search order of the field groups produced by {CollectFields()}
is maintained through execution, ensuring that fields appear in the executed
response in a stable and predictable order.

CollectFields(objectType, selectionSet, variableValues, visitedFragments, localVariableValues):
CollectFields(objectType, selectionSet, variableValues, visitedFragments,
localVariableValues):

- If {visitedFragments} is not provided, initialize it to the empty set.
- Initialize {groupedFields} to an empty ordered map of lists.
- For each {selection} in {selectionSet}:
- If {selection} provides the directive `@skip`, let {skipDirective} be that
directive.
- If {skipDirective}'s {if} argument is {true} or is a variable in
{localVariableValues} or {variableValues} with the value {true}, continue with the next {selection}
in {selectionSet}.
{localVariableValues} or {variableValues} with the value {true}, continue
with the next {selection} in {selectionSet}.
- If {selection} provides the directive `@include`, let {includeDirective} be
that directive.
- If {includeDirective}'s {if} argument is not {true} and is not a variable
in {localVariableValues} or {variableValues} with the value {true}, continue with the next
{selection} in {selectionSet}.
in {localVariableValues} or {variableValues} with the value {true},
continue with the next {selection} in {selectionSet}.
- If {selection} is a {Field}:
- Let {responseKey} be the response key of {selection} (the alias if
defined, otherwise the field name).
Expand All @@ -527,7 +529,8 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments, localV
- If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
with the next {selection} in {selectionSet}.
- Let {localVariableValues} be the result of calling
{getArgumentValuesFromSpread(selection, fragmentDefinition, variableValues, localVariableValues)}.
{getArgumentValuesFromSpread(selection, fragmentDefinition,
variableValues, localVariableValues)}.
- Let {fragmentGroupedFieldSet} be the result of calling
{CollectFields(objectType, fragmentSelectionSet, variableValues,
visitedFragments)}.
Expand Down Expand Up @@ -566,24 +569,27 @@ DoesFragmentTypeApply(objectType, fragmentType):
- If {objectType} is a possible type of {fragmentType}, return {true}
otherwise return {false}.

getArgumentValuesFromSpread(fragmentSpread, fragmentDefinition, variableValues, fragmentArgumentValues):
getArgumentValuesFromSpread(fragmentSpread, fragmentDefinition, variableValues,
fragmentArgumentValues):

- Let {coercedValues} be an empty unordered Map.
- For each {variableDefinition} in {fragmentDefinition}:
- Let {variableName} be the name of {variableDefinition}.
- Let {variableType} be the type of {variableDefinition}.
- Let {defaultValue} be the default value for {variableDefinition}.
- Let {argumentNode} be the node provided in the fragment-spread for {variableName}
- Let {argumentNode} be the node provided in the fragment-spread for
{variableName}
- If {argumentNode} isn't present or is null
- If {defaultValue} exists
- Add an entry to {coercedValues} named {argumentName} with the value
{defaultValue}.
- If {variableType} is non-nullable raise a field-error
- Let {hasValue} be {true} if {fragmentArgumentValues} or {variableValues} provides a value for the name
{variableName}.
- If {variableType} is non-nullable and {hasValue} is {false} raise a field-error
- Add an entry to {coercedValues} named {argumentName} with the value
found in {variableValues} or {fragmentArgumentValues}.
- Let {hasValue} be {true} if {fragmentArgumentValues} or {variableValues}
provides a value for the name {variableName}.
- If {variableType} is non-nullable and {hasValue} is {false} raise a
field-error
- Add an entry to {coercedValues} named {argumentName} with the value found in
{variableValues} or {fragmentArgumentValues}.
- Return {coercedValues}.

Note: The steps in {CollectFields()} evaluating the `@skip` and `@include`
Expand All @@ -597,7 +603,8 @@ coerces any provided argument values, then resolves a value for the field, and
finally completes that value either by recursively executing another selection
set or coercing a scalar value.

ExecuteField(objectType, objectValue, fieldType, fields, variableValues, fragmentVariableValues):
ExecuteField(objectType, objectValue, fieldType, fields, variableValues,
fragmentVariableValues):

- Let {field} be the first entry in {fields}.
- Let {fieldName} be the field name of {field}.
Expand All @@ -617,7 +624,8 @@ the type system to have a specific input type.
At each argument position in an operation may be a literal {Value}, or a
{Variable} to be provided at runtime.

CoerceFieldArgumentValues(objectType, field, variableValues, fragmentVariableValues):
CoerceFieldArgumentValues(objectType, field, variableValues,
fragmentVariableValues):

- Let {argumentValues} be the argument values provided in {field}.
- Let {fieldName} be the name of {field}.
Expand All @@ -626,7 +634,8 @@ CoerceFieldArgumentValues(objectType, field, variableValues, fragmentVariableVal
- Return {CoerceArgumentValues(argumentDefinitions, argumentValues,
variableValues, fragmentVariableValues)}

CoerceArgumentValues(argumentDefinitions, argumentValues, variableValues, fragmentVariableValues):
CoerceArgumentValues(argumentDefinitions, argumentValues, variableValues,
fragmentVariableValues):

- For each {argumentDefinition} in {argumentDefinitions}:
- Let {argumentName} be the name of {argumentDefinition}.
Expand All @@ -638,8 +647,8 @@ CoerceArgumentValues(argumentDefinitions, argumentValues, variableValues, fragme
{argumentName}.
- If {argumentValue} is a {Variable}:
- Let {variableName} be the name of {argumentValue}.
- Let {hasValue} be {true} if {fragmentVariableValues} provides a value for the name
{variableName}.
- Let {hasValue} be {true} if {fragmentVariableValues} provides a value for
the name {variableName}.
- Let {value} be the value provided in {fragmentVariableValues} for the name
{variableName}.
- Let {hasValue} be {true} if {variableValues} provides a value for the name
Expand Down

0 comments on commit b4f3c5d

Please sign in to comment.