Skip to content

Commit 65df539

Browse files
committed
Merge branch 'main' into benjie/incremental-common
2 parents 140c3da + 1f690d4 commit 65df539

6 files changed

+297
-184
lines changed

.github/algorithm-format-check.mjs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { readFile, readdir } from "node:fs/promises";
22

33
const SPEC_DIR = new URL("../spec", import.meta.url).pathname;
44

5+
/** @see {@link https://spec-md.com/#sec-Value-Literals} */
6+
const valueLiteralsRegexp = /\{((?:[^{}]|(?:\{[^{}]*\}))+)\}/g;
7+
58
process.exitCode = 0;
69
const filenames = await readdir(SPEC_DIR);
710
for (const filename of filenames) {
@@ -72,6 +75,33 @@ for (const filename of filenames) {
7275
console.log();
7376
process.exitCode = 1;
7477
}
78+
79+
const stepWithoutValueLiterals = step.replace(
80+
valueLiteralsRegexp,
81+
""
82+
);
83+
if (stepWithoutValueLiterals.match(/\b[A-Z][A-Za-z0-9]+\(/)) {
84+
console.log(
85+
`Bad formatting of '${algorithmName}' step (algorithm call should be wrapped in braces: \`{MyAlgorithm(a, b, c)}\`) in '${filename}':`
86+
);
87+
console.dir(step);
88+
console.log();
89+
process.exitCode = 1;
90+
}
91+
92+
const valueLiterals = step.matchAll(valueLiteralsRegexp, "");
93+
for (const lit of valueLiterals) {
94+
const inner = lit[1];
95+
if (inner.includes("{")) {
96+
console.log(
97+
`Bad formatting of '${algorithmName}' step (algorithm call should not contain braces: \`${lit}\`) in '${filename}':`
98+
);
99+
console.dir(step);
100+
console.log();
101+
process.exitCode = 1;
102+
}
103+
}
104+
75105
const trimmedInnerLine = step.replace(/\s+/g, " ");
76106
if (
77107
trimmedInnerLine.match(

spec/Section 2 -- Language.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,9 @@ These two operations are semantically identical:
466466

467467
Alias : Name :
468468

469-
:: A _response key_ is the key in the response object which correlates with a
470-
field's result. By default the response key will use the field's name; however,
471-
you can define a different response key by specifying an alias.
469+
:: A _response name_ is the key in the response object which correlates with a
470+
field's result. By default the response name will use the field's name; however,
471+
you can define a different response name by specifying an alias.
472472

473473
In this example, we can fetch two profile pictures of different sizes and ensure
474474
the resulting response object will not have duplicate keys:
@@ -1254,7 +1254,7 @@ Type : Name
12541254

12551255
- Let {name} be the string value of {Name}.
12561256
- Let {type} be the type defined in the Schema named {name}.
1257-
- {type} must not be {null}.
1257+
- {type} must exist.
12581258
- Return {type}.
12591259

12601260
Type : [ Type ]

spec/Section 3 -- Type System.md

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,8 @@ A GraphQL schema may describe that a field represents a list of another type;
329329
the `List` type is provided for this reason, and wraps another type.
330330

331331
Similarly, the `Non-Null` type wraps another type, and denotes that the
332-
resulting value will never be {null} (and that a _field error_ cannot result in
333-
a {null} value).
332+
resulting value will never be {null} (and that an _execution error_ cannot
333+
result in a {null} value).
334334

335335
These two types are referred to as "wrapping types"; non-wrapping types are
336336
referred to as "named types". A wrapping type has an underlying named type,
@@ -351,7 +351,7 @@ IsInputType(type):
351351

352352
- If {type} is a List type or Non-Null type:
353353
- Let {unwrappedType} be the unwrapped type of {type}.
354-
- Return IsInputType({unwrappedType}).
354+
- Return {IsInputType(unwrappedType)}.
355355
- If {type} is a Scalar, Enum, or Input Object type:
356356
- Return {true}.
357357
- Return {false}.
@@ -360,7 +360,7 @@ IsOutputType(type):
360360

361361
- If {type} is a List type or Non-Null type:
362362
- Let {unwrappedType} be the unwrapped type of {type}.
363-
- Return IsOutputType({unwrappedType}).
363+
- Return {IsOutputType(unwrappedType)}.
364364
- If {type} is a Scalar, Object, Interface, Union, or Enum type:
365365
- Return {true}.
366366
- Return {false}.
@@ -461,14 +461,14 @@ more guidance.
461461

462462
A GraphQL service, when preparing a field of a given scalar type, must uphold
463463
the contract the scalar type describes, either by coercing the value or
464-
producing a _field error_ if a value cannot be coerced or if coercion may result
465-
in data loss.
464+
producing an _execution error_ if a value cannot be coerced or if coercion may
465+
result in data loss.
466466

467467
A GraphQL service may decide to allow coercing different internal types to the
468468
expected return type. For example when coercing a field of type {Int} a boolean
469469
{true} value may produce {1} or a string value {"123"} may be parsed as base-10
470470
{123}. However if internal type coercion cannot be reasonably performed without
471-
losing information, then it must raise a _field error_.
471+
losing information, then it must raise an _execution error_.
472472

473473
Since this coercion behavior is not observable to clients of the GraphQL
474474
service, the precise rules of coercion are left to the implementation. The only
@@ -513,15 +513,15 @@ Fields returning the type {Int} expect to encounter 32-bit integer internal
513513
values.
514514

515515
GraphQL services may coerce non-integer internal values to integers when
516-
reasonable without losing information, otherwise they must raise a _field
516+
reasonable without losing information, otherwise they must raise an _execution
517517
error_. Examples of this may include returning `1` for the floating-point number
518518
`1.0`, or returning `123` for the string `"123"`. In scenarios where coercion
519-
may lose data, raising a field error is more appropriate. For example, a
520-
floating-point number `1.2` should raise a field error instead of being
519+
may lose data, raising an execution error is more appropriate. For example, a
520+
floating-point number `1.2` should raise an execution error instead of being
521521
truncated to `1`.
522522

523523
If the integer internal value represents a value less than -2<sup>31</sup> or
524-
greater than or equal to 2<sup>31</sup>, a _field error_ should be raised.
524+
greater than or equal to 2<sup>31</sup>, an _execution error_ should be raised.
525525

526526
**Input Coercion**
527527

@@ -548,12 +548,12 @@ Fields returning the type {Float} expect to encounter double-precision
548548
floating-point internal values.
549549

550550
GraphQL services may coerce non-floating-point internal values to {Float} when
551-
reasonable without losing information, otherwise they must raise a _field
551+
reasonable without losing information, otherwise they must raise an _execution
552552
error_. Examples of this may include returning `1.0` for the integer number `1`,
553553
or `123.0` for the string `"123"`.
554554

555555
Non-finite floating-point internal values ({NaN} and {Infinity}) cannot be
556-
coerced to {Float} and must raise a _field error_.
556+
coerced to {Float} and must raise an _execution error_.
557557

558558
**Input Coercion**
559559

@@ -579,9 +579,9 @@ that representation must be used to serialize this type.
579579
Fields returning the type {String} expect to encounter Unicode string values.
580580

581581
GraphQL services may coerce non-string raw values to {String} when reasonable
582-
without losing information, otherwise they must raise a _field error_. Examples
583-
of this may include returning the string `"true"` for a boolean true value, or
584-
the string `"1"` for the integer `1`.
582+
without losing information, otherwise they must raise an _execution error_.
583+
Examples of this may include returning the string `"true"` for a boolean true
584+
value, or the string `"1"` for the integer `1`.
585585

586586
**Input Coercion**
587587

@@ -600,8 +600,8 @@ representation of the integers `1` and `0`.
600600
Fields returning the type {Boolean} expect to encounter boolean internal values.
601601

602602
GraphQL services may coerce non-boolean raw values to {Boolean} when reasonable
603-
without losing information, otherwise they must raise a _field error_. Examples
604-
of this may include returning `true` for non-zero numbers.
603+
without losing information, otherwise they must raise an _execution error_.
604+
Examples of this may include returning `true` for non-zero numbers.
605605

606606
**Input Coercion**
607607

@@ -623,7 +623,7 @@ large 128-bit random numbers, to base64 encoded values, or string values of a
623623
format like [GUID](https://en.wikipedia.org/wiki/Globally_unique_identifier).
624624

625625
GraphQL services should coerce as appropriate given the ID formats they expect.
626-
When coercion is not possible they must raise a _field error_.
626+
When coercion is not possible they must raise an _execution error_.
627627

628628
**Input Coercion**
629629

@@ -1492,7 +1492,7 @@ enum Direction {
14921492
**Result Coercion**
14931493

14941494
GraphQL services must return one of the defined set of possible values. If a
1495-
reasonable coercion is not possible they must raise a _field error_.
1495+
reasonable coercion is not possible they must raise an _execution error_.
14961496

14971497
**Input Coercion**
14981498

@@ -1548,8 +1548,9 @@ Fields may accept arguments to configure their behavior. These inputs are often
15481548
scalars or enums, but they sometimes need to represent more complex values.
15491549

15501550
A GraphQL Input Object defines a set of input fields; the input fields are
1551-
either scalars, enums, or other input objects. This allows arguments to accept
1552-
arbitrarily complex structs.
1551+
scalars, enums, other input objects, or any wrapping type whose underlying base
1552+
type is one of those three. This allows arguments to accept arbitrarily complex
1553+
structs.
15531554

15541555
In this example, an Input Object called `Point2D` describes `x` and `y` inputs:
15551556

@@ -1654,10 +1655,10 @@ is constructed with the following rules:
16541655

16551656
- If a variable is provided for an input object field, the runtime value of that
16561657
variable must be used. If the runtime value is {null} and the field type is
1657-
non-null, a _field error_ must be raised. If no runtime value is provided, the
1658-
variable definition's default value should be used. If the variable definition
1659-
does not provide a default value, the input object field definition's default
1660-
value should be used.
1658+
non-null, an _execution error_ must be raised. If no runtime value is
1659+
provided, the variable definition's default value should be used. If the
1660+
variable definition does not provide a default value, the input object field
1661+
definition's default value should be used.
16611662

16621663
Following are examples of input coercion for an input object type with a
16631664
`String` field `a` and a required (non-null) `Int!` field `b`:
@@ -1742,19 +1743,19 @@ brackets like this: `pets: [Pet]`. Nesting lists is allowed: `matrix: [[Int]]`.
17421743

17431744
GraphQL services must return an ordered list as the result of a list type. Each
17441745
item in the list must be the result of a result coercion of the item type. If a
1745-
reasonable coercion is not possible it must raise a _field error_. In
1746+
reasonable coercion is not possible it must raise an _execution error_. In
17461747
particular, if a non-list is returned, the coercion should fail, as this
17471748
indicates a mismatch in expectations between the type system and the
17481749
implementation.
17491750

17501751
If a list's item type is nullable, then errors occurring during preparation or
17511752
coercion of an individual item in the list must result in a the value {null} at
1752-
that position in the list along with a _field error_ added to the response. If a
1753-
list's item type is non-null, a field error occurring at an individual item in
1754-
the list must result in a field error for the entire list.
1753+
that position in the list along with an _execution error_ added to the response.
1754+
If a list's item type is non-null, an execution error occurring at an individual
1755+
item in the list must result in an execution error for the entire list.
17551756

1756-
Note: See [Handling Field Errors](#sec-Handling-Field-Errors) for more about
1757-
this behavior.
1757+
Note: See [Handling Execution Errors](#sec-Handling-Execution-Errors) for more
1758+
about this behavior.
17581759

17591760
**Input Coercion**
17601761

@@ -1812,12 +1813,13 @@ always optional and non-null types are always required.
18121813
In all of the above result coercions, {null} was considered a valid value. To
18131814
coerce the result of a Non-Null type, the coercion of the wrapped type should be
18141815
performed. If that result was not {null}, then the result of coercing the
1815-
Non-Null type is that result. If that result was {null}, then a _field error_
1816-
must be raised.
1816+
Non-Null type is that result. If that result was {null}, then an _execution
1817+
error_ must be raised.
18171818

1818-
Note: When a _field error_ is raised on a non-null value, the error propagates
1819-
to the parent field. For more information on this process, see
1820-
[Errors and Non-Null Fields](#sec-Executing-Selection-Sets.Errors-and-Non-Null-Fields)
1819+
Note: When an _execution error_ is raised on a non-null _response position_, the
1820+
error propagates to the parent _response position_. For more information on this
1821+
process, see
1822+
[Errors and Non-Null Types](#sec-Executing-Selection-Sets.Errors-and-Non-Null-Types)
18211823
within the Execution section.
18221824

18231825
**Input Coercion**
@@ -2035,19 +2037,20 @@ directive @invalidExample(arg: String @invalidExample) on ARGUMENT_DEFINITION
20352037
Note: The order in which directives appear may be significant, including
20362038
repeatable directives.
20372039

2038-
**Validation**
2040+
**Type Validation**
20392041

2040-
1. A directive definition must not contain the use of a directive which
2042+
1. A Directive definition must include at least one DirectiveLocation.
2043+
2. A Directive definition must not contain the use of a Directive which
20412044
references itself directly.
2042-
2. A directive definition must not contain the use of a directive which
2045+
3. A Directive definition must not contain the use of a Directive which
20432046
references itself indirectly by referencing a Type or Directive which
2044-
transitively includes a reference to this directive.
2045-
3. The directive must not have a name which begins with the characters {"\_\_"}
2047+
transitively includes a reference to this Directive.
2048+
4. The Directive must not have a name which begins with the characters {"\_\_"}
20462049
(two underscores).
2047-
4. For each argument of the directive:
2050+
5. For each argument of the Directive:
20482051
1. The argument must not have a name which begins with the characters
20492052
{"\_\_"} (two underscores).
2050-
2. The argument must have a unique name within that directive; no two
2053+
2. The argument must have a unique name within that Directive; no two
20512054
arguments may share the same name.
20522055
3. The argument must accept a type where {IsInputType(argumentType)} returns
20532056
{true}.

spec/Section 5 -- Validation.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ fragment directFieldSelectionOnUnion on CatOrDog {
418418

419419
FieldsInSetCanMerge(set):
420420

421-
- Let {fieldsForName} be the set of selections with a given response name in
421+
- Let {fieldsForName} be the set of selections with a given _response name_ in
422422
{set} including visiting fragments and inline fragments.
423423
- Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForName}:
424424
- {SameResponseShape(fieldA, fieldB)} must be true.
@@ -450,7 +450,7 @@ SameResponseShape(fieldA, fieldB):
450450
- Assert: {typeB} is an object, union or interface type.
451451
- Let {mergedSet} be the result of adding the selection set of {fieldA} and the
452452
selection set of {fieldB}.
453-
- Let {fieldsForName} be the set of selections with a given response name in
453+
- Let {fieldsForName} be the set of selections with a given _response name_ in
454454
{mergedSet} including visiting fragments and inline fragments.
455455
- Given each pair of distinct members {subfieldA} and {subfieldB} in
456456
{fieldsForName}:
@@ -462,10 +462,10 @@ type that is either an Object, Interface or Union type.
462462

463463
**Explanatory Text**
464464

465-
If multiple field selections with the same response names are encountered during
466-
execution, the field and arguments to execute and the resulting value should be
467-
unambiguous. Therefore any two field selections which might both be encountered
468-
for the same object are only valid if they are equivalent.
465+
If multiple field selections with the same _response name_ are encountered
466+
during execution, the field and arguments to execute and the resulting value
467+
should be unambiguous. Therefore any two field selections which might both be
468+
encountered for the same object are only valid if they are equivalent.
469469

470470
During execution, the simultaneous execution of fields with the same response
471471
name is accomplished by {CollectSubfields()}.
@@ -1304,15 +1304,26 @@ fragment resourceFragment on Resource {
13041304

13051305
**Formal Specification**
13061306

1307-
- For each input Value {value} in the document:
1307+
- For each literal Input Value {value} in the document:
13081308
- Let {type} be the type expected in the position {value} is found.
1309-
- {value} must be coercible to {type}.
1309+
- {value} must be coercible to {type} (with the assumption that any
1310+
{variableUsage} nested within {value} will represent a runtime value valid
1311+
for usage in its position).
13101312

13111313
**Explanatory Text**
13121314

13131315
Literal values must be compatible with the type expected in the position they
13141316
are found as per the coercion rules defined in the Type System chapter.
13151317

1318+
Note: A {ListValue} or {ObjectValue} may contain nested Input Values, some of
1319+
which may be a variable usage. The
1320+
[All Variable Usages Are Allowed](#sec-All-Variable-Usages-Are-Allowed)
1321+
validation rule ensures that each {variableUsage} is of a type allowed in its
1322+
position. The [Coercing Variable Values](#sec-Coercing-Variable-Values)
1323+
algorithm ensures runtime values for variables coerce correctly. Therefore, for
1324+
the purposes of the "coercible" assertion in this validation rule, we can assume
1325+
the runtime value of each {variableUsage} is valid for usage in its position.
1326+
13161327
The type expected in a position includes the type defined by the argument a
13171328
value is provided for, the type defined by an input object field a value is
13181329
provided for, and the type of a variable definition a default value is provided
@@ -2010,4 +2021,4 @@ query booleanArgQueryWithDefault($booleanArg: Boolean = true) {
20102021
```
20112022

20122023
Note: The value {null} could still be provided to such a variable at runtime. A
2013-
non-null argument must raise a _field error_ if provided a {null} value.
2024+
non-null argument must raise an _execution error_ if provided a {null} value.

0 commit comments

Comments
 (0)