Skip to content

Commit 50abfaf

Browse files
authored
An adopted schema extension disables implicit root operations + Prep releases (#909)
`adopt_orphan_extensions` is a non-standard mode so we don’t have a spec to precisely define its behavior, but I think this behavior is more consistent. See new tests for examples. Also prepare releases for: * [email protected] * [email protected] * [email protected] (only needed to update the pinned compiler dependency)
1 parent f3cb052 commit 50abfaf

File tree

11 files changed

+114
-49
lines changed

11 files changed

+114
-49
lines changed

crates/apollo-compiler/CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,17 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1717
## Maintenance
1818
## Documentation-->
1919

20-
# [1.0.0-beta.21](https://crates.io/crates/apollo-compiler/1.0.0-beta.21) - 2024-08-03
20+
# [1.0.0-beta.22](https://crates.io/crates/apollo-compiler/1.0.0-beta.21) - 2024-09-09
21+
22+
## Fixes
23+
- **Allow adopted orphan schema extensions to define root operations - [trevor-scheer], [pull/907].**
24+
This is only relevant in the non-standard `adopt_orphan_extensions` mode.
25+
26+
[trevor-scheer]: https://github.com/trevor-scheer
27+
[pull/907]: https://github.com/apollographql/apollo-rs/pull/907
28+
29+
30+
# [1.0.0-beta.21](https://crates.io/crates/apollo-compiler/1.0.0-beta.21) - 2024-09-03
2131

2232
## BREAKING
2333

crates/apollo-compiler/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "apollo-compiler"
3-
version = "1.0.0-beta.21" # When bumping, also update README.md
3+
version = "1.0.0-beta.22" # When bumping, also update README.md
44
authors = ["Irina Shestak <[email protected]>"]
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/apollographql/apollo-rs"

crates/apollo-compiler/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Or add this to your `Cargo.toml` for a manual installation:
4040
# Just an example, change to the necessary package version.
4141
# Using an exact dependency is recommended for beta versions
4242
[dependencies]
43-
apollo-compiler = "=1.0.0-beta.21"
43+
apollo-compiler = "=1.0.0-beta.22"
4444
```
4545

4646
## Rust versions

crates/apollo-compiler/src/schema/from_ast.rs

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -273,53 +273,35 @@ impl SchemaBuilder {
273273
SchemaDefinitionStatus::NoneSoFar { orphan_extensions } => {
274274
// This a macro rather than a closure to generate separate `static`s
275275
let schema_def = schema.schema_definition.make_mut();
276-
let mut has_implicit_root_operation = false;
277-
'root_operation_loop: for (operation_type, root_operation) in [
278-
(OperationType::Query, &mut schema_def.query),
279-
(OperationType::Mutation, &mut schema_def.mutation),
280-
(OperationType::Subscription, &mut schema_def.subscription),
281-
] {
282-
let name = operation_type.default_type_name();
283-
// If `adopt_orphan_extensions` is enabled, we should scan
284-
// each orphan schema extension for root operations. If we
285-
// see one, we should skip adding that particular implicit
286-
// root operation since the extensions will be applied
287-
// further down.
288-
if adopt_orphan_extensions {
289-
for ext in &orphan_extensions {
290-
for node in &ext.root_operations {
291-
let current_operation_type = node.as_ref().0;
292-
if current_operation_type == operation_type {
293-
continue 'root_operation_loop;
294-
}
295-
}
296-
}
297-
}
298-
299-
if schema.types.get(&name).is_some_and(|def| def.is_object()) {
300-
*root_operation = Some(name.into());
301-
has_implicit_root_operation = true
302-
}
303-
}
304-
305-
let apply_schema_extensions =
306-
// https://github.com/apollographql/apollo-rs/issues/682
307-
// If we have no explict `schema` definition but do have object type(s)
308-
// with a default type name for root operations,
309-
// an implicit schema definition is generated with those root operations.
310-
// That implict definition can be extended:
311-
has_implicit_root_operation ||
276+
if adopt_orphan_extensions {
312277
// https://github.com/apollographql/apollo-rs/pull/678
313278
// In this opt-in mode we unconditionally assume
314279
// an implicit schema definition to extend
315-
adopt_orphan_extensions;
316-
if apply_schema_extensions {
317280
for ext in &orphan_extensions {
318281
schema_def.extend_ast(&mut errors, ext)
319282
}
283+
if schema_def.query.is_none()
284+
&& schema_def.mutation.is_none()
285+
&& schema_def.subscription.is_none()
286+
{
287+
add_implicit_root_types(schema_def, &schema.types);
288+
}
320289
} else {
321-
for ext in &orphan_extensions {
322-
errors.push(ext.location(), BuildError::OrphanSchemaExtension)
290+
let has_implicit_root_operation =
291+
add_implicit_root_types(schema_def, &schema.types);
292+
if has_implicit_root_operation {
293+
// https://github.com/apollographql/apollo-rs/issues/682
294+
// If we have no explict `schema` definition but do have object type(s)
295+
// with a default type name for root operations,
296+
// an implicit schema definition is generated with those root operations.
297+
// That implict definition can be extended:
298+
for ext in &orphan_extensions {
299+
schema_def.extend_ast(&mut errors, ext)
300+
}
301+
} else {
302+
for ext in &orphan_extensions {
303+
errors.push(ext.location(), BuildError::OrphanSchemaExtension)
304+
}
323305
}
324306
}
325307
}
@@ -343,6 +325,25 @@ impl SchemaBuilder {
343325
}
344326
}
345327

328+
fn add_implicit_root_types(
329+
schema_def: &mut SchemaDefinition,
330+
types: &IndexMap<Name, ExtendedType>,
331+
) -> bool {
332+
let mut has_implicit_root_operation = false;
333+
for (operation_type, root_operation) in [
334+
(OperationType::Query, &mut schema_def.query),
335+
(OperationType::Mutation, &mut schema_def.mutation),
336+
(OperationType::Subscription, &mut schema_def.subscription),
337+
] {
338+
let name = operation_type.default_type_name();
339+
if types.get(&name).is_some_and(|def| def.is_object()) {
340+
*root_operation = Some(name.into());
341+
has_implicit_root_operation = true
342+
}
343+
}
344+
has_implicit_root_operation
345+
}
346+
346347
fn adopt_type_extensions(
347348
errors: &mut DiagnosticList,
348349
type_name: &Name,

crates/apollo-compiler/tests/extensions.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,43 @@ fn test_invalid_orphan_extensions_schema_def_with_duplicate_root_operation() {
9292
assert!(err.contains("duplicate definitions for the `query` root operation type"));
9393
}
9494

95+
#[test]
96+
fn test_orphan_schema_extension_with_root_type_disables_implicit_root_types() {
97+
let input = r#"
98+
extend schema { query: Query }
99+
type Query { viruses: [Virus] }
100+
type Virus { mutations: [Mutation] }
101+
type Mutation { something: String }
102+
"#;
103+
104+
let schema = Schema::builder()
105+
.adopt_orphan_extensions()
106+
.parse(input, "schema.graphql")
107+
.build()
108+
.unwrap();
109+
110+
assert!(schema.schema_definition.mutation.is_none());
111+
schema.validate().unwrap();
112+
}
113+
114+
#[test]
115+
fn test_orphan_schema_extension_without_root_type_enables_implicit_root_types() {
116+
let input = r#"
117+
directive @something on SCHEMA
118+
extend schema @something
119+
type Query { field: Int }
120+
"#;
121+
122+
let schema = Schema::builder()
123+
.adopt_orphan_extensions()
124+
.parse(input, "schema.graphql")
125+
.build()
126+
.unwrap();
127+
128+
assert!(schema.schema_definition.query.is_some());
129+
schema.validate().unwrap();
130+
}
131+
95132
#[test]
96133
fn test_orphan_extensions_kind_mismatch() {
97134
let input = r#"

crates/apollo-parser/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1616
## Maintenance
1717
1818
## Documentation -->
19+
20+
# [0.8.2](https://crates.io/crates/apollo-parser/0.8.2) - 2024-09-09
21+
22+
## Fixes
23+
- **Allow object type definition syntax without fields - [trevor-scheer], [pull/901].**
24+
It is syntactically valid for an object type to have no fields
25+
when the `{}` curly braces are omitted.
26+
During validation, this is also valid as long as an extension for the type
27+
also exists which does include field definitions.
28+
29+
[trevor-scheer]: https://github.com/trevor-scheer
30+
[pull/901]: https://github.com/apollographql/apollo-rs/pull/901
31+
1932
# [0.8.1](https://crates.io/crates/apollo-parser/0.8.1) - 2024-08-20
2033

2134
## Features

crates/apollo-parser/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "apollo-parser"
3-
version = "0.8.1" # When bumping, also update README.md
3+
version = "0.8.2" # When bumping, also update README.md
44
authors = ["Irina Shestak <[email protected]>"]
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/apollographql/apollo-rs"

crates/apollo-parser/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Or add this to your `Cargo.toml` for a manual installation:
3535
```toml
3636
# Just an example, change to the necessary package version.
3737
[dependencies]
38-
apollo-parser = "0.8.1"
38+
apollo-parser = "0.8.2"
3939
```
4040

4141
## Rust versions

crates/apollo-smith/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1818
## Maintenance
1919
2020
## Documentation -->
21-
# [0.11.0](https://crates.io/crates/apollo-smith/0.10.0) - 2024-09-03
21+
# [0.12.0](https://crates.io/crates/apollo-smith/0.12.0) - 2024-09-09
22+
23+
- **Update apollo-compiler dependency to `=1.0.0-beta.22`**
24+
25+
# [0.11.0](https://crates.io/crates/apollo-smith/0.11.0) - 2024-09-03
2226

2327
- **Update apollo-compiler dependency to `=1.0.0-beta.21`**
2428

crates/apollo-smith/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "apollo-smith"
3-
version = "0.11.0" # When bumping, also update README.md
3+
version = "0.12.0" # When bumping, also update README.md
44
edition = "2021"
55
authors = ["Benjamin Coenen <[email protected]>"]
66
license = "MIT OR Apache-2.0"
@@ -22,7 +22,7 @@ categories = [
2222
]
2323

2424
[dependencies]
25-
apollo-compiler = { path = "../apollo-compiler", version = "=1.0.0-beta.21" }
25+
apollo-compiler = { path = "../apollo-compiler", version = "=1.0.0-beta.22" }
2626
apollo-parser = { path = "../apollo-parser", version = "0.8.0" }
2727
arbitrary = { version = "1.3.0", features = ["derive"] }
2828
indexmap = "2.0.0"

0 commit comments

Comments
 (0)