Skip to content

Commit 1bc46cf

Browse files
committed
Merge branch 'main' into fragment-args-2024-amendments
2 parents 9ef0002 + 468d848 commit 1bc46cf

19 files changed

+1462
-406
lines changed

.github/algorithm-format-check.mjs

Lines changed: 54 additions & 2 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) {
@@ -25,7 +28,7 @@ for (const filename of filenames) {
2528
const matches = line.match(/^([a-z0-9A-Z]+)(\s*)\(([^)]*)\)(\s*):(\s*)$/);
2629
const grammarMatches =
2730
filename === "Section 2 -- Language.md" &&
28-
line.match(/^([A-Za-z0-9]+) :\s+((\S).*)$/);
31+
line.match(/^([A-Za-z0-9]+) ::?\s+((\S).*)$/);
2932
if (matches) {
3033
const [, algorithmName, ns1, _args, ns2, ns3] = matches;
3134
if (ns1 || ns2 || ns3) {
@@ -64,14 +67,50 @@ for (const filename of filenames) {
6467
console.log();
6568
process.exitCode = 1;
6669
}
67-
if (step.match(/^\s*(-|[0-9]\.)\s+[a-z]/)) {
70+
if (step.match(/^\s*(-|[0-9]+\.)\s+[a-z]/)) {
6871
console.log(
6972
`Bad formatting of '${algorithmName}' step (should start with a capital) in '${filename}':`
7073
);
7174
console.dir(step);
7275
console.log();
7376
process.exitCode = 1;
7477
}
78+
const assertMatch = step.match(/^\s*(-|[0-9]+\.)\s*Assert([^:])/);
79+
if (assertMatch) {
80+
console.log(
81+
`Bad formatting of '${algorithmName}' step (Assert should be immediately followed by ':'; found '${assertMatch[2]}') in '${filename}':`
82+
);
83+
console.dir(step);
84+
console.log();
85+
process.exitCode = 1;
86+
}
87+
88+
const stepWithoutValueLiterals = step.replace(
89+
valueLiteralsRegexp,
90+
""
91+
);
92+
if (stepWithoutValueLiterals.match(/\b[A-Z][A-Za-z0-9]+\(/)) {
93+
console.log(
94+
`Bad formatting of '${algorithmName}' step (algorithm call should be wrapped in braces: \`{MyAlgorithm(a, b, c)}\`) in '${filename}':`
95+
);
96+
console.dir(step);
97+
console.log();
98+
process.exitCode = 1;
99+
}
100+
101+
const valueLiterals = step.matchAll(valueLiteralsRegexp, "");
102+
for (const lit of valueLiterals) {
103+
const inner = lit[1];
104+
if (inner.includes("{")) {
105+
console.log(
106+
`Bad formatting of '${algorithmName}' step (algorithm call should not contain braces: \`${lit}\`) in '${filename}':`
107+
);
108+
console.dir(step);
109+
console.log();
110+
process.exitCode = 1;
111+
}
112+
}
113+
75114
const trimmedInnerLine = step.replace(/\s+/g, " ");
76115
if (
77116
trimmedInnerLine.match(
@@ -101,6 +140,10 @@ for (const filename of filenames) {
101140
console.log();
102141
process.exitCode = 1;
103142
}
143+
while (lines[i + 1].trim() !== "") {
144+
// Continuation of definition
145+
i++;
146+
}
104147
if (!lines[i + 2].startsWith("- ")) {
105148
// Not an algorithm; probably more grammar
106149
continue;
@@ -146,6 +189,15 @@ for (const filename of filenames) {
146189
console.log();
147190
process.exitCode = 1;
148191
}
192+
const assertMatch = step.match(/^\s*(-|[0-9]+\.)\s*Assert([^:])/);
193+
if (assertMatch) {
194+
console.log(
195+
`Bad formatting of '${grammarName}' step (Assert should be immediately followed by ':'; found '${assertMatch[2]}') in '${filename}':`
196+
);
197+
console.dir(step);
198+
console.log();
199+
process.exitCode = 1;
200+
}
149201
}
150202
}
151203
}

CONTRIBUTING.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ contributions.
66

77
Contributions that do not change the interpretation of the spec but instead
88
improve legibility, fix editorial errors, clear up ambiguity and improve
9-
examples are encouraged and are often merged by a spec editor with little
10-
process.
9+
examples are encouraged. These "editorial changes" will normally be given the
10+
["✏ Editorial" label](https://github.com/graphql/graphql-spec/issues?q=sort%3Aupdated-desc+is%3Aopen+label%3A%22%E2%9C%8F%EF%B8%8F+Editorial%22)
11+
and are often merged by a spec editor with little process.
1112

1213
However, contributions that _do_ meaningfully change the interpretation of the
1314
spec must follow an RFC (Request For Comments) process led by a _champion_

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![GraphQLConf 2024 Banner: September 10-12, San Francisco. Hosted by the GraphQL Foundation](https://github.com/user-attachments/assets/0203f10b-ae1e-4fe1-9222-6547fa2bbd5d)](https://graphql.org/conf/2024/?utm_source=github&utm_medium=graphql_spec&utm_campaign=readme)
1+
[![GraphQLConf 2025 Banner: September 08-10, Amsterdam. Hosted by the GraphQL Foundation](./assets/graphql.org_conf_2025_.png)](https://graphql.org/conf/2025/?utm_source=github&utm_medium=graphql_js&utm_campaign=readme)
22

33
# GraphQL
44

STYLE_GUIDE.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,25 @@ MyAlgorithm(argOne, argTwo):
8282
- Let {something} be {true}.
8383
- Return {something}.
8484
```
85+
86+
## Definitions
87+
88+
For important terms, use
89+
[Spec Markdown definition paragraphs](https://spec-md.com/#sec-Definition-Paragraph).
90+
91+
Definition paragraphs start with `::` and add the matching italicized term to
92+
the [specification index](https://spec.graphql.org/draft/#index), making it easy
93+
to reference them.
94+
95+
## Tone of voice
96+
97+
The GraphQL specification is a reference document and should use neutral and
98+
descriptive tone of voice.
99+
100+
**Favor the present tense**
101+
102+
The present tense is usually clearer and shorter:
103+
104+
✅ Present: The client then sends a request to the server.
105+
106+
❌ Future: The client will then send a request to the server.

assets/graphql.org_conf_2025_.png

488 KB
Loading

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
"suggest:format": "echo \"\nTo resolve this, run: $(tput bold)npm run format$(tput sgr0)\" && exit 1",
2222
"build": "./build.sh",
2323
"test:build": "spec-md --metadata spec/metadata.json spec/GraphQL.md > /dev/null",
24-
"watch": "nodemon -e json,md --exec \"npm run build\""
24+
"watch": "nodemon -e json,md --exec \"npm run build\"",
25+
"update-appendix-c": "node scripts/update-appendix-c.mjs; prettier --write \"spec/Appendix C -- Built-in Definitions.md\""
2526
},
2627
"devDependencies": {
2728
"cspell": "5.9.1",
2829
"nodemon": "2.0.20",
2930
"prettier": "2.8.2",
30-
"spec-md": "3.1.0"
31+
"spec-md": "3.1.0",
32+
"graphql": "^17.0.0-alpha.8"
3133
},
3234
"prettier": {
3335
"proseWrap": "always",

scripts/update-appendix-c.mjs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { writeFile } from 'node:fs/promises';
2+
import { printIntrospectionSchema, buildSchema, specifiedScalarTypes, printType } from 'graphql';
3+
4+
const FILE = './spec/Appendix C -- Specified Definitions.md';
5+
function printSpecifiedScalars() {
6+
return specifiedScalarTypes
7+
.map((type) => printType(type))
8+
.join('\n\n');
9+
}
10+
11+
const introspectionSchema = printIntrospectionSchema(buildSchema(`type Query { i: Int }`));
12+
const prefix = `
13+
# C. Appendix: Type System Definitions
14+
15+
This appendix lists the specified type system definitions.
16+
17+
The descriptions are non-normative. Implementations are recommended to use them
18+
for consistency but different descriptions are allowed.
19+
20+
The order of types, fields, arguments, values and directives is non-normative.
21+
22+
\`\`\`graphql
23+
`
24+
25+
const suffix = `
26+
\`\`\`
27+
`
28+
await writeFile(FILE, prefix + printSpecifiedScalars() + '\n\n' + introspectionSchema + suffix);

spec/Appendix A -- Notation Conventions.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,5 +214,36 @@ Fibonacci(number):
214214
- Return {Fibonacci(previousNumber)} + {Fibonacci(previousPreviousNumber)}.
215215

216216
Note: Algorithms described in this document are written to be easy to
217-
understand. Implementers are encouraged to include equivalent but optimized
218-
implementations.
217+
understand. Implementers are encouraged to include observably equivalent but
218+
optimized implementations.
219+
220+
## Data Collections
221+
222+
Algorithms within this specification refer to abstract data collection types to
223+
express normative structural, uniqueness, and ordering requirements. Temporary
224+
data collections internal to an algorithm use these types to best describe
225+
expected behavior, but implementers are encouraged to provide observably
226+
equivalent but optimized implementations. Implementations may use any data
227+
structure as long as the expected requirements are met.
228+
229+
**List**
230+
231+
:: A _list_ is an ordered collection of values which may contain duplicates. A
232+
value added to a list is ordered after existing values.
233+
234+
**Set**
235+
236+
:: A _set_ is a collection of values which must not contain duplicates.
237+
238+
:: An _ordered set_ is a set which has a defined order. A value added to an
239+
ordered set, which does not already contain that value, is ordered after
240+
existing values.
241+
242+
**Map**
243+
244+
:: A _map_ is a collection of entries, each of which has a key and value. Each
245+
entry has a unique key, and can be directly referenced by that key.
246+
247+
:: An _ordered map_ is a map which has a defined order. An entry added to an
248+
ordered map, which does not have an entry with that key, is ordered after
249+
existing entries.

spec/Appendix B -- Grammar Summary.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ lines and uniform indentation with {BlockStringValue()}.
133133

134134
## Document Syntax
135135

136+
Description : StringValue
137+
136138
Document : Definition+
137139

138140
Definition :
@@ -149,7 +151,7 @@ ExecutableDefinition :
149151

150152
OperationDefinition :
151153

152-
- OperationType Name? VariablesDefinition? Directives? SelectionSet
154+
- Description? OperationType Name? VariablesDefinition? Directives? SelectionSet
153155
- SelectionSet
154156

155157
OperationType : one of `query` `mutation` `subscription`
@@ -174,7 +176,7 @@ FragmentSpread : ... FragmentName Arguments? Directives?
174176

175177
InlineFragment : ... TypeCondition? Directives? SelectionSet
176178

177-
FragmentDefinition : fragment FragmentName VariablesDefinition? TypeCondition
179+
FragmentDefinition : Description? fragment FragmentName TypeCondition
178180
Directives? SelectionSet
179181

180182
FragmentName : Name but not `on`
@@ -213,7 +215,8 @@ ObjectField[Const] : Name : Value[?Const]
213215

214216
VariablesDefinition : ( VariableDefinition+ )
215217

216-
VariableDefinition : Variable : Type DefaultValue? Directives[Const]?
218+
VariableDefinition : Description? Variable : Type DefaultValue?
219+
Directives[Const]?
217220

218221
Variable : $ Name
219222

@@ -268,8 +271,6 @@ SchemaExtension :
268271

269272
RootOperationTypeDefinition : OperationType : NamedType
270273

271-
Description : StringValue
272-
273274
TypeDefinition :
274275

275276
- ScalarTypeDefinition

0 commit comments

Comments
 (0)