All notable changes to apollo-compiler
will be documented in this file.
This project adheres to Semantic Versioning.
- Update
ariadne
trait implementations - lrlna, [pull/960][email protected]
release changed their type signature forariadne::Cache
trait, which required an update toapollo-compiler
's implementation ofariadne::Cache<FileId>
.
This release also had a slight change to path formatting, so if you had any snapshots in your tests, you can expect a change from this:
Error: `typeFragment1` contains too much nesting
╭─[overflow.graphql:11:11]
to this (notice the extra white space around the file path):
Error: `typeFragment1` contains too much nesting
╭─[ overflow.graphql:11:11 ]
1.27.0 - 2025-03-04
- Add WebAssembly demo - SimonSapin, pull/954
- Add
root_fields()
andall_fields()
toSelectionSet
- SimonSapin, pull/954
- Avoid reprocessing named fragments - sachindshinde goto-bus-stop and SimonSapin, pull/952
1.26.0 - 2025-01-23
- Provide access to line/col lookup on a
SourceFile
- dylan-apollo, pull/949
1.25.0 - 2025-01-14
While version 1.25.0 has some breaking changes compared to 1.0.0-beta.24 (see below),
with this release apollo-compiler
1.x is leaving "beta" status
and will adhere to semantic versioning going forward:
we will try to avoid breaking changes, and when they do happen it will be in version 2.0.
For stable versions we recommend using a “normal” dependency like apollo_compiler = "1.25.0"
instead of an =
exact dependency like apollo_compiler = "=1.0.0-beta.24"
.
- Reduce scope of execution / introspection APIs - SimonSapin, pull/944
- Move
apollo_compiler::schema::ArgumentByNameError
intoapollo_compiler::ast
- SimonSapin, pull/942 - Remove the
parse_mixed_validate
free function, use theParser
method instead - SimonSapin, pull/945
- Overload
DirectiveList::push
to also accept a plainDirective
, not justNode<Directive>
- SimonSapin, pull/942 - Add
ExtendedType::as_scalar(&self) -> Option<&ScalarType>
and similar - SimonSapin, pull/942
- Validate against reserved names starting with
__
in schemas - SimonSapin, pull/923. - Fix duplicate diagnostic for variable with invalid default value - SimonSapin, pull/925 and pull/929.
- Added or reworded many doc-comments - SimonSapin, pull/942
1.0.0-beta.24 - 2024-09-24
-
Argument value lookup accounts for default value and nullability - SimonSapin, pull/914.
argument_by_name
methods ofDirective
andexecutable::Field
can now return a default value orValue::Null
based on the directive or field definition in the schema. OnDirective
, the method takes a new&Schema
parameter. (executable::Field
on the other hand already contains a reference to its field definition.) Both methods now return aResult
instead of anOption
.The previous behavior and signature is available as
specified_argument_by_name
methods.
- Introspection
deprecationReason
field returns the default string instead ofnull
for argument-less@deprecated
- SimonSapin, pull/914. The directive argument is defined asreason: String = "No longer supported"
.
1.0.0-beta.23 - 2024-09-17
- Validation adds/removes built-in scalar definitions based on usage - SimonSapin, pull/911.
- Fix source spans for object field values - dylan-apollo, pull/912.
1.0.0-beta.22 - 2024-09-09
- Allow adopted orphan schema extensions to define root operations - trevor-scheer, pull/907.
This is only relevant in the non-standard
adopt_orphan_extensions
mode.
1.0.0-beta.21 - 2024-09-03
- Change
Implementers
fields fromHashMap
toIndexMap
- SimonSapin in pull/898 This struct returned bySchema::implementers_map
maps interface types to (object or interface) types that implement that interface. Now the ordering of implementers is deterministic and matches their definition order in the schema. This helps fuzzing, where the same entropy source should generate the same test case.
- Port MaxIntrospectionDepthRule from graphql-js - SimonSapin in pull/904. This limits list nesting in introspection query which can cause very large responses.
- Add convenience APIs on operations - SimonSapin in pull/905
OperationMap::len
andOperationMap::is_empty
, making it more like a collection typeOperation::all_fields
andOperation::root_fields
iterators
1.0.0-beta.20 - 2024-07-30
- Fix variable validation in operation directives - goto-bus-stop in pull/888.
query ($var: Int) @directive(arg: $var)
is now accepted - it used to raise an unused variable error for$var
.
- Make unused variable validation more efficient - goto-bus-stop in pull/887.
1.0.0-beta.19 - 2024-07-19
-
Remove deprecated
Name
reexports - SimonSapin in pull/877.apollo_compiler::Name
should now be imported instead of:apollo_compiler::ast::Name
apollo_compiler::schema::Name
apollo_compiler::executable::Name
These other paths emitted deprecation warnings in 1.0.0-beta.18 and are now removed.
-
Move operations of an
ExecutableDocument
into a new struct - SimonSapin in pull/879.doc.anonymous_operation
→doc.operations.anonymous
doc.named_operations
→doc.operations.named
doc.get_operation()
→doc.operations.get()
doc.get_operation_mut()
→doc.operations.get_mut()
doc.insert_operation()
→doc.operations.insert()
doc.all_operations()
→doc.operations.iter()
This change makesget_mut()
borrow onlydoc.operations
instead of the entire document, making it possible to also mutatedoc.fragments
during that mutable borrow.
-
Move or rename some import paths - SimonSapin in pull/885. Moved from the crate root to the new(ly public)
apollo_compiler::parser
module:Parser
SourceFile
SourceMap
FileId
Moved to the
parser
module and renamed:NodeLocation
→SourceSpan
GraphQLLocation
→LineColumn
-
Return ranges of line/column locations - dylan-apollo in pull/861.
SourceSpan
contains a file ID and a range of UTF-8 offsets within that file. Various APIs can convert offsets to line and column numbers, but often only considered the start offset. They are now changed to consider the range of start and end positions. Added, returningOption<Range<LineColumn>>
:SourceSpan::line_column_range
Diagnostic::line_column_range
Name::line_column_range
Removed:
LineColumn::from_node
Diagnostic::get_line_column
SourceFile::get_line_column
-
Use a fast hasher - o0Ignition0o in pull/881. Configured all hash-based collections used in apollo-compiler to use
ahash
, which is faster than the default standard library hasher.apollo_compiler::collections
provides type aliases for collections configured with the same hasher as collections in various parts of the public API.
- Add a few helper methods - SimonSapin in pull/885:
executable::OperationMap::from_one
schema::SchemaDefinition::iter_root_operations()
schema::ExtendedType::is_leaf
- Fix potential hash collision bug in validation - goto-bus-stop in pull/878
- Fix validation for undefined variables nested in values - goto-bus-stop in pull/885
1.0.0-beta.18 - 2024-06-27
-
Name
representation change - SimonSapin in pull/868. The memory representation of GraphQL names is changed to useArc<str>
or&'static str
internally, and provide corresponding cheap conversions. This may also help enable string interning in a future compiler version.Name
should now be imported from the crate root. The previous paths (apollo_compiler::ast::Name
,apollo_compiler::executable::Name
, andapollo_compiler::schema::Name
) now emit a deprecation warning and will be removed in a later version.NodeStr
has been removed, with its functionality folded intoName
ast::Value::String
now contains a plainString
instead ofNodeStr
.Value
itself is in aNode<_>
that contains the same source span asNodeStr
did.- Descriptions are now represented as
Option<Node<str>>
instead ofOption<NodeStr>
.
-
Feature REMOVED:
Hash
cache inNode<T>
- SimonSapin in pull/872.Node<T>
is a reference-counted smart pointer that provides thread-safe shared ownership for atT
value together with an optional source location. In previous beta version of apollo-compiler 1.0 it contained a cache in itsHash
implementation: the hash of theT
value would be computed once and stored, thenHash for Node<T>
would hash that hash code. That functionality is now removed,Hash for Node<T>
simply forwards toHash for T
. This reduces eachNode
heap allocation by 8 bytes, and reduces code complexity.Now that apollo-compiler does not use Salsa anymore,
Hash
is much less central than it used to be. Many types stored inNode<_>
don’t implementHash
at all (because they contain anIndexMap
which doesn’t either).Programs that relied on this cache will still compile. We still consider this change breaking as they’ll need to build their own cache to maintain performance characteristics.
- Fix validation error message for missing subselections - goto-bus-stop in pull/865 It now reports the correct coordinate for the missing subselection.
1.0.0-beta.17 - 2024-06-05
- Fix validation performance bug - goto-bus-stop in issue/862, pull/863 Adds a cache in fragment spread validation, fixing a situation where validating a query with many fragment spreads against a schema with many interfaces could take multiple seconds to validate.
- Remove ariadne byte/char mapping - goto-bus-stop in pull/855 Generating JSON or CLI reports for apollo-compiler diagnostics used a translation layer between byte offsets and character offsets, which cost some computation and memory proportional to the size of the source text. The latest version of ariadne allows us to remove this translation.
1.0.0-beta.16 - 2024-04-12
This release has no user-facing changes.
- Add GraphQL validation compatibility API for Apollo Router - goto-bus-stop in pull/853 Enables large-scale production deployment of apollo-compiler's validation implementation.
1.0.0-beta.15 - 2024-04-08
- Serialize with initial indentation - SimonSapin, pull/848
This helps use indentation in something that is partly but not entirely GraphQL syntax,
such as the debugging representation of an Apollo Router query plan.
Example:
document.serialize().initial_indent_level(2).to_string()
- Add validation requiring composite types declare fields - tinnou, pull/847 Object types, interfaces, enums, unions, and input objects must all have at least one member. This is now checked in schema validation.
1.0.0-beta.14 - 2024-03-13
- Move
NodeLocation
andFileId
fromapollo_compiler::validation
to the crate root - SimonSapin, pull/838
- Remove Salsa database for 1.2× ~ 2× validation speed - SimonSapin, pull/838
We were not taking advantage of caching it provides.
Additionally, validation uses
Schema
andExecutableDocument
directly rather than converting them to AST.$ cargo bench --bench multi-source supergraph parse_and_validate time: [398.09 µs 399.32 µs 400.82 µs] change: [-19.966% -19.418% -18.864%] (p = 0.00 < 0.05) Performance has improved. simple_query parse_and_validate time: [12.097 µs 12.104 µs 12.113 µs] change: [-52.467% -52.282% -52.109%] (p = 0.00 < 0.05) Performance has improved.
1.0.0-beta.13 - 2024-02-14
This release includes a critical fix to overflow protection in validation.
- New field merging validation implementation - goto-bus-stop, pull/816
- Uses the much more scalable XING algorithm.
- This also fixes some invalid selections that were previously accepted by apollo-compiler.
- Selections in fragment definitions are now only validated in the context of the operations they are used in, reducing duplicate error reports for invalid fragments. This means invalid unused fragments do not produce field merging errors, but they will still raise a different error because fragments being unused is also an error according to the spec.
- Add owned IntoIterator for
DirectiveList
types - SimonSapin, pull/826
- Actually run RecursionGuard in release mode - SimonSapin, pull/827
Due to a
debug_assert!()
oversight, stack overflow protection in validation did not run in release mode. - Accept enum values as input for custom scalars - goto-bus-stop, pull/835 Custom scalars accept any kind of input value. apollo-compiler used to raise a validation error when an enum value was used directly for a custom scalar. However, using an enum value nested inside an object or list was accepted. Now enum values are always accepted where a custom scalar is expected.
- Replace uses of deprecated
IndexMap::remove
- goto-bus-stop, pull/817
1.0.0-beta.12 - 2024-01-15
InputValueDefinition::is_required()
returns false if it has a default value - goto-bus-stop, pull/798- Now
argument.is_required() == true
only if the type is non-null and there is no default value, meaning a value must be provided when it's used.
- Now
- Implement
fmt::Display
forComponentName
- goto-bus-stop, pull/795 - Add
FieldDefinition::argument_by_name
andDirectiveDefinition::argument_by_name
- goto-bus-stop, pull/801- These methods return an argument definition by name, or
None
.
- These methods return an argument definition by name, or
- Add
.lookup
methods to schema coordinates - goto-bus-stop, pull/803coord!(Type).lookup(&schema)
returns the type definition forType
.coord!(Type.field).lookup_field(&schema)
returns the field definition forfield
.coord!(Enum.VALUE).lookup_enum_value(&schema)
returns the enum value definition forVALUE
.coord!(InputType.field).lookup_input_field(&schema)
returns the input field definition forfield
.coord!(Type.field(argument:)).lookup(&schema)
returns the argument definition forargument
.coord!(@directive).lookup(&schema)
returns the directive definition for@directive
.coord!(@directive(argument:)).lookup(&schema)
returns the argument definition forargument
.string.parse::<SchemaCoordinate>()?.lookup(&schema)
returns an enum with all the elements that can be looked up using schema coordinates.
- update ariadne to 0.4.0 - pull/793 Ariadne is the diagnostic printing crate used for validation errors. v0.4.0 improves memory usage.
1.0.0-beta.11 - 2023-12-19
This release includes support for GraphQL schema introspection directly in the compiler. If this is a feature you're interested in, we encourage you to try it out and leave us any feedback in the introspection discussion. More details on this feature in the changelog below.
- Pretty CLI formatting for custom diagnostics - goto-bus-stop, pull/747:
- A
CliReport
builder API for printing with labeled source code to a monospace text stream with optional ANSI color codes. - A
ToCliReport
trait for converting error types to aCliReport
when given a source map. - A
Diagnostic
struct for bundling such an error together with a source map and implementDisplay
/Debug
by printing a CLI report
- A
- Add execution-related and introspection functionality - SimonSapin, pull/758:
- Add data structure in
apollo_compiler::execution
for a GraphQL response, its data, and errors. All (de)serializable withserde
. - Add
coerce_variable_values()
in that same module. - Add
apollo_compiler::execution::SchemaIntrospection
providing full execution for the schema introspection parts of an operation and separating the rest to be executed separately. In order to support all kinds of introspection queries this includes a full execution engine where users provide objects with resolvable fields. At this time this engine is not exposed in the public API. If you’re interested in it let us know about your use case! - Add
ExecutableDocument::insert_operation
convenience method.
- Add data structure in
- Add
NodeStr::from(Name)
- goto-bus-stop, pull/773 - Convenience accessors for
ast::Selection
enum - SimonSapin, pull/777as_field
,as_inline_fragment
, andas_fragment_spread
; all returningOption<&_>
. - Add schema coordinates - goto-bus-stop, pull/757:
Schema coordinates are a compact, human-readable way to uniquely point to an item defined in a schema.
string.parse::<SchemaCoordinate>()
parses a coordinate from a string.- Coordinates have a
Display
impl that writes them out with schema coordinate syntax. - The
coord!()
macro creates a static coordinate at compile time from spec syntax.
- Fix serializing single-line strings with leading whitespace - goto-bus-stop, pull/774 Previously, the leading whitespace would get lost.
1.0.0-beta.10 - 2023-12-04
- Add
Valid::assume_valid_ref
- SimonSapin, pull/768
1.0.0-beta.9 - 2023-12-01
- Add validation convenience APIs - SimonSapin, pull/764:
ast::Document::to_schema_validate
ast::Document::to_executable_validate
DiagnosticList::new
DiagnosticList::merge
1.0.0-beta.8 - 2023-11-30
-
API refactor to make it harder to ignore errors - SimonSapin, pull/752 fixing issue/709:
ast::Document
,Schema
, andExecutableDocument
not longer contain potential errors that users need to check separately.- Instead, various constructors and methods now return a
Result
, with theErr
case containing both both errors and a maybe-incomplete value. - Change
validate
methods ofSchema
andExecutableDocument
to take ownership ofself
. On success they return the schema or document (unmodified) wrapped in aValid<_>
marker type, which is immutable. - Change
ExecutableDocument
to require a&Valid<Schema>
instead of&Schema
, forcing callers to either run validation or opt out explicitly withValid::assume_valid
. - Make
parse_mixed
andto_mixed
validate both the schema and document. Rename them with a_validate
suffix. - Corresponding changes to all of the above in
Parser
method signatures - Remove
ast::Document::check_parse_errors
: parse errors are now encoded in the return value ofparse
. - Remove
ast::Document::to_schema_builder
. UseSchemaBuilder::add_ast
instead. - Move items from the crate top-level to
apollo_compiler::validation
:Diagnostic
DiagnosticList
FileId
NodeLocation
- Move items from the crate top-level to
apollo_compiler::execution
:GraphQLError
GraphQLLocation
- Remove warning-level and advice-level diagnostics. See issue/751.
Highlight of signature changes:
+struct Valid<T>(T); // Implements `Deref` and `AsRef` but not `DerefMut` or `AsMut` + +struct WithErrors<T> { + partial: T, // Errors may cause components to be missing + errors: DiagnosticList, +} -pub fn parse_mixed(…) -> (Schema, ExecutableDocument) +pub fn parse_mixed_validate(…) + -> Result<(Valid<Schema>, Valid<ExecutableDocument>), DiagnosticList> impl ast::Document { - pub fn parse(…) -> Self + pub fn parse(…) -> Result<Self, WithErrors<Self>> - pub fn to_schema(&self) -> Schema + pub fn to_schema(&self) -> Result<Schema, WithErrors<Schema>> - pub fn to_executable(&self) -> ExecutableDocument + pub fn to_executable(&self) -> Result<ExecutableDocument, WithErrors<ExecutableDocument>> - pub fn to_mixed(&self) -> (Schema, ExecutableDocument) + pub fn to_mixed_validate( + &self, + ) -> Result<(Valid<Schema>, Valid<ExecutableDocument>), DiagnosticList> } impl Schema { - pub fn parse(…) -> Self - pub fn validate(&self) -> Result<DiagnosticList, DiagnosticList> + pub fn parse_and_validate(…) -> Result<Valid<Self>, WithErrors<Self>> + pub fn parse(…) -> Result<Self, WithErrors<Self>> + pub fn validate(self) -> Result<Valid<Self>, WithErrors<Self>> } impl SchemaBuilder { - pub fn build(self) -> Schema + pub fn build(self) -> Result<Schema, WithErrors<Schema>> } impl ExecutableDocument { - pub fn parse(schema: &Schema, …) -> Self - pub fn validate(&self, schema: &Schema) -> Result<(), DiagnosticList> + pub fn parse_and_validate(schema: &Valid<Schema>, …) -> Result<Valid<Self>, WithErrors<Self>> + pub fn parse(schema: &Valid<Schema>, …) -> Result<Self, WithErrors<Self>> + pub fn validate(self, schema: &Valid<Schema>) -> Result<Valid<Self>, WithErrors<Self>> }
-
Add
parse_and_validate
constructors forSchema
andExecutableDocument
- SimonSapin, pull/752: when mutating isn’t needed after parsing, this returns an immutableValid<_>
value in one step. -
Implement serde
Serialize
andDeserialize
for some AST types - SimonSapin, pull/760:Node
NodeStr
Name
IntValue
FloatValue
Value
Type
Source locations are not preserved through serialization.
-
Add
ast::Definition::as_*() -> Option<&_>
methods for each variant - SimonSapin, pull/760 -
Serialize (to GraphQL) multi-line strings as block strings - SimonSapin, pull/724: Example before:
"Example\n\nDescription description description" schema { query: MyQuery }
After:
""" Example Description description description """ schema { query: MyQuery }
-
Limit recursion in validation - goto-bus-stop, pull/748 fixing issue/742: Validation now bails out of very long chains of definitions that refer to each other, even if they don't strictly form a cycle. These could previously cause extremely long validation times or stack overflows.
The limit for input objects and directives is set at 32. For fragments, the limit is set at 100. Based on our datasets, real-world documents don't come anywhere close to this.
1.0.0-beta.7 - 2023-11-17
- Helper features for
Name
andType
- SimonSapin, pull/739:- The
name!
macro also accepts an identifier:name!(Query)
andname!("Query")
create equivalentName
values. InvalidNameError
now contain a publicNodeStr
for the input string that is invalid, and implementsDisplay
,Debug
, andError
traits.- Add
TryFrom
conversion toName
fromNodeStr
,&NodeStr
,&str
,String
, and&String
. - Add a
ty!
macro to build a staticast::Type
using GraphQL-like syntax.
- The
-
Add parsing an
ast::Type
from a string - lrlna and goto-bus-stop, pull/718 fixing issue/715Parses GraphQL type syntax:
use apollo_compiler::ast::Type; let ty = Type::parse("[ListItem!]!")?;
-
Fix list and null type validation bugs - goto-bus-stop, pull/746 fixing issue/738 Previous versions of apollo-compiler accepted
null
inside a list even if the list item type was marked as required. Lists were also accepted as inputs to non-list fields. This is now fixed.input Args { string: String ints: [Int!] } type Query { example(args: Args): Int } query { example(args: { # Used to be accepted, now raises an error string: ["1"] # Used to be accepted, now raises an error ints: [1, 2, null, 4] }) }
1.0.0-beta.6 - 2023-11-10
-
Make everything know their own name - SimonSapin, pull/727 fixing issue/708.
In a few places (but not consistently) a
name
field was omitted from some structs used as map values on the basis that it would have been redundant with the map key. This reverts that decision, making it the user’s responsibility when mutating documents to keep names consistent.- Add a
pub name: Name
field toexecutable::Fragment
as well asScalarType
,ObjectType
,InterfaceType
,EnumType
,UnionType
, andInputObjectType
inschema
. - Add a
fn name(&self) -> &Name
method to theschema::ExtendedType
enum - Add a
pub name: Option<Name>
field toexecutable::Operation
- Remove
executable::OperationRef<'_>
(which was equivalent to(Option<&Name>, &Node<Operation>)
), replacing its uses with&Node<Operation>
- Add a
-
Rename
Directives
andDiagnostics
toDirectiveList
andDiagnosticList
- SimonSapin, pull/732 fixing issue/711. The previous names were too similar toDirective
andDiagnostic
(singular). -
Rename
ComponentStr
toComponentName
- SimonSapin, pull/713 and itsnode: NodeStr
field toname: Name
. -
Assorted changed to GraphQL names - SimonSapin, pull/713 fixing issue/710.
- Check validity of
ast::Name
.NodeStr
is a smart string type with infallible conversion from&str
.ast::Name
used to be a type alias forNodeStr
, leaving the possibility of creating one invalid in GraphQL syntax. Validation and serialization would not check this.Name
is now a wrapper type forNodeStr
. Itsnew
constructor checks validity of the given string and returns aResult
. A newname!
macro (see below) creates aName
with compile-time checking. OperationType::default_type_name
returns aName
instead of&str
Type::new_named("x")
is removed. UseType::Named(name!("x"))
instead.ComponentStr
is renamed toComponentName
. It no longer has infallible conversions from&str
orString
. Itsnode
field is renamed toname
; the type of that field is changed fromNodeStr
toName
.NodeStr
no longer has ato_component
method, onlyName
does- Various function or method parameters changed from
impl Into<Name>
toName
, since there is no longer an infallible conversion from&str
- Check validity of
-
Add serialization support for everything - SimonSapin, pull/728.
Schema
,ExecutableDocument
, and all AST types already supported serialization to GraphQL syntax through theDisplay
trait and the.serialize()
method. This is now also the case of all other Rust types representing some element of a GraphQL document:schema::Directives
schema::ExtendedType
schema::ScalarType
schema::ObjectType
schema::InterfaceType
schema::EnumType
schema::UnionType
schema::InputObjectType
executable::Operation
executable::Fragment
executable::SelectionSet
executable::Selection
executable::Field
executable::InlineFragment
executable::FragmentSpread
executable::FieldSet
-
Assorted changed to GraphQL names - SimonSapin, pull/713 fixing issue/710. See also the BREAKING section above.
- Add a
name!("example")
macro, to be imported withuse apollo_compiler::name;
. It creates anast::Name
from a string literal, with a compile-time validity checking. AName
created this way does not own allocated heap memory or a reference counter, so cloning it is extremely cheap. - Add allocation-free
NodeStr::from_static
. This mostly exists to support thename!
macro, but can also be used on its own:let s = apollo_compiler::NodeStr::from_static(&"example"); assert_eq!(s, "example");
- Add a
- Fix crash in validation of self-referential fragments - goto-bus-stop, pull/733 fixing issue/716. Now fragments that cyclically reference themselves inside a nested field also produce a validation error, instead of causing a stack overflow crash.
1.0.0-beta.5 - 2023-11-08
- Diangostic struct is now public by SimonSapin in 11fe454
- Improve lowercase enum value diagnostic by goto-bus-stop in pull/725
- Simplify
SchemaBuilder
internals by SimonSapin in pull/722 - Remove validation dead code by SimonSapin in bd5d107
- Skip schema AST conversion in ExecutableDocument::validate by SimonSapin in pull/726
1.0.0-beta.4 - 2023-10-16
-
JSON Serialisable compiler diagnostics - lrlna and goto-bus-stop, pull/698: This change brings back JSON error format for diagnostics introduced by goto-bus-stop in pull/668 for [email protected]. As a result, diagnostics' line/column numbers are now also accessible as part of the public API.
let json = expect_test::expect![[r#" { "message": "an executable document must not contain an object type definition", "locations": [ { "line": 2, "column": 1 } ] }"#]]; let diagnostics = executable.validate(&schema).unwrap_err(); diagnostics.iter().for_each(|diag| { assert_eq!( diag.get_line_column(), Some(GraphQLLocation { line: 2, column: 1 }) ); json.assert_eq(&serde_json::to_string_pretty(&diag.to_json()).unwrap()); });
- Don’t emit a validation error for relying on argument default - SimonSapin, pull/700 A field argument or directive argument was incorrectly considered required as soon as it had a non-null type, even if it had a default value.
1.0.0-beta.3 - 2023-10-13
- Keep source files in
Arc<Map<…>>
everywhere - SimonSapin, pull/696 Change struct fields fromsources: IndexMap<FileId, Arc<SourceFile>>
(inSchema
) orsource: Option<(FileId, Arc<SourceFile>)>
(inDocument
,ExecutablDocument
,FieldSet
) tosources: SourceMap
, with:Cases other thanpub type SourceMap = Arc<IndexMap<FileId, Arc<SourceFile>>>;
Schema
still only have zero or one source when created by apollo-compiler, but it is now possible to make more sources available to diagnostics, for example when merging documents:Arc::make_mut(&mut doc1.sources).extend(doc2.sources.iter().map(|(k, v)| (*k, v.clone())));
- Add iteration over individual diagnostics - SimonSapin, pull/696:
let schema = Schema::parse(input, "schema.graphql"); if let Err(errors) = schema.validate() { for error in errors.iter() { eprintln!("{error}") } }
- Don’t panic in validation or omit diagnostics when a source location is missing - SimonSapin, pull/697 In apollo-compiler 0.11 every element of the HIR always had a source location because it always came from a parsed input file. In 1.0 source location is always optional. When a node relevant to some diagnostic does not have a source location, the diagnostic should still be emitted but its labels (each printing a bit of source code) may be missing. Essential information should therefore be in the main message, not only in labels.
1.0.0-beta.2 - 2023-10-10
Assorted Schema
API changes - SimonSapin, pull/678
- Type of the
schema_definition
field changed fromOption<SchemaDefinition>
toSchemaDefinition
. Default root operations based on object type names are now stored explicitly inSchemaDefinition
. Serialization relies on a heuristic to decide on implicit schema definition. - Removed
schema_definition_directives
method: no longer having anOption
allows fieldschema.schema_definition.directives
to be accessed directly - Removed
query_root_operation
,mutation_root_operation
, andsubscription_root_operation
methods. Insteadschema.schema_definition.query
etc can be accessed directly.
-
Add
executable::FieldSet
for a selection set with optional outer brackets - lrlna, pull/685 fixing issue/681 This is intended to parse string value of aFieldSet
custom scalar used in some Apollo Federation directives in the context of a specific schema and type. Itsvalidate
method calls a subset of validation rules relevant to selection sets. which is not part of a document.let input = r#" type Query { id: ID organization: Org } type Org { id: ID } "#; let schema = Schema::parse(input, "schema.graphql"); schema.validate().unwrap(); let input = "id organization { id }"; let field_set = FieldSet::parse(&schema, "Query", input, "field_set.graphql"); field_set.validate(&schema).unwrap();
-
Add opt-in configuration for “orphan” extensions to be “adopted” - SimonSapin, pull/678
Type extensions and schema extensions without a corresponding definition are normally ignored except for recording a validation error. In this new mode, an implicit empty definition to extend is generated instead. This behavious is not the default, as it's non-standard. Configure a schema builder to opt in:
let input = "extend type Query { x: Int }"; let schema = apollo_compiler::Schema::builder() .adopt_orphan_extensions() .parse(input, "schema.graphql") .build(); schema.validate()?;
- Allow built-in directives to be redefined - SimonSapin, pull/684 fixing issue/656
- Allow schema extensions to extend a schema definition implied by object types named after default root operations - SimonSapin, pull/678 fixing [issues/682]
1.0.0-beta.1 - 2023-10-05
Compared to 0.11, version 1.0 is a near-complete rewrite of the library
and revamp of the public API.
While in beta, there may still be breaking changes (though not as dramatic)
until 1.0.0 “final”.
If using a beta version, we recommend specifying an exact dependency in Cargo.toml
:
apollo-compiler = "=1.0.0-beta.1"
The API is now centered on Schema
and ExecutableDocument
types.
Users no longer need to create a compiler, add inputs to it, and track them by ID.
Validation is now a method of these types, and returns a Result
to indicate errors.
These types are serializable
(through Display
, .to_string()
, and a .serialize()
config builder),
integrating the functionality of the apollo-encoder crate.
They are also mutable, and can be created programmatically out of thin air.
Node<T>
is a thread-safe reference-counted smart pointer
that provides structural sharing and copy-on-write semantics.
0.11.3 - 2023-10-06
-
expose line/column location and JSON format from diagnostics, by goto-bus-stop in pull/668
You can now use
diagnostic.get_line_column()
to access the line/column number where a validation error occurred.diagnostic.to_json()
returns a GraphQL error structure that's serializable with serde, matching the JSON error format.let diagnostics = compiler.db.validate(); let errors = diagnostics.into_iter().map(ApolloDiagnostic::to_json).collect::<Vec<_>>(); let error_response = serde_json::to_string(&serde_json::json!({ "errors": errors, }))?;
-
improve validation error summaries, by goto-bus-stop in pull/674
Adds more context and a more consistent voice to the "main" message for validation errors. They are now concise, matter-of-fact descriptions of the problem. Information about how to solve the problem is usually already provided by labels and notes on the diagnostic.
- operation
getName
is defined multiple times - interface
NamedEntity
implements itself
The primary use case for this is to make
diagnostic.data.to_string()
return a useful message for text-only error reports, like in JSON responses. The JSON format for diagnostics uses these new messages. - operation
0.11.2 - 2023-09-11
-
Add
validate_standalone_executable
function to validate an executable document without access to a schema, by goto-bus-stop in pull/631, issue/629This runs just those validations that can be done on operations without knowing the types of things.
let compiler = ApolloCompiler::new(); let file_id = compiler.add_executable(r#" { user { ...userData } } "#, "query.graphql"); let diagnostics = compiler.db.validate_standalone_executable(file_id); // Complains about `userData` fragment not existing, but does not complain about `user` being an unknown query.
-
validate input value types, by goto-bus-stop in pull/642
This fixes an oversight in the validation rules implemented by
compiler.db.validate()
. Previously, incorrect types on input values and arguments were not reported:type ObjectType { id: ID! } input InputObject { # accepted in <= 0.11.1, reports "TypeThatDoesNotExist is not in scope" in 0.11.2 property: TypeThatDoesNotExist # accepted in <= 0.11.1, reports "ObjectType is not an input type" in 0.11.2 inputType: ObjectType }
- (TODO: write this)
0.11.1 - 2023-08-24
- disable colours in diagnostics output if the terminal is not interactive, by EverlastingBugstopper in pull/628, issue/499
0.11.0 - 2023-08-18
- add
InterfaceTypeDefinition::implementors(&db)
to list object types and other interfaces that implement an interface, by Geal in pull/616
- fix
SelectionSet::is_introspection
when the same fragment is spread multiple times, by glasser in pull/614, issue/613
- update
apollo-parser
to 0.6.0, by goto-bus-stop in pull/621
0.10.0 - 2023-06-20
SelectionSet::merge
is renamed toSelectionSet::concat
to clarify that it doesn't do field merging, by goto-bus-stop in pull/570hir::InlineFragment::type_condition
now only returnsSome()
if a type condition was explicitly specified, by goto-bus-stop in pull/586
-
add
root_operation_name(OperationType)
helper method onhir::SchemaDefinition
by SimonSapin in pull/579 -
add an
UndefinedDirective
diagnostic type, by goto-bus-stop in pull/587This is used for directives instead of
UndefinedDefinition
.
-
accept objects as values for custom scalars, by goto-bus-stop in pull/585
The GraphQL spec is not entirely clear on this, but this is used in the real world with things like the
_Any
type in Apollo Federation.
- update dependencies, by goto-bus-stop in commit/daf918b
- add a test for validation with
set_type_system_hir()
, by goto-bus-stop in pull/583
0.9.4 - 2023-06-05
-
accept any primitive value type for custom scalar validation, by lrlna in pull/575
If you provide a value to a custom scalar in your GraphQL source text, apollo-compiler now accepts any value type. Previously it was not possible to write values for custom scalars into a query or schema because the value you wrote would never match the custom scalar type.
This now works:
scalar UserID @specifiedBy(url: "https://my-app.net/api-docs/users#id") type Query { username (id: UserID): String }
{ username(id: 575) }
-
add type name to the
UndefinedField
diagnostic data, by goto-bus-stop in pull/577When querying a field that does not exist, the type name that's being queried is stored on the diagnostic, so you can use it when handling the error.
0.9.3 - 2023-05-26
-
fix nullable / non-nullable validations inside lists, by lrlna in pull/567
Providing a variable of type
[Int!]!
to an argument of type[Int]
is now allowed.
- use official ariadne release, by goto-bus-stop in pull/568
0.9.2 - 2023-05-23
-
add
as_$type()
methods tohir::Value
, by goto-bus-stop in pull/564These methods simplify casting the
hir::Value
enum to single Rust types. Added methods:hir::Value::as_i32() -> Option<i32>
hir::Value::as_f64() -> Option<f64>
hir::Value::as_str() -> Option<&str>
hir::Value::as_bool() -> Option<bool>
hir::Value::as_list() -> Option<&Vec<Value>>
hir::Value::as_object() -> Option<&Vec<(Name, Value)>>
hir::Value::as_variable() -> Option<&Variable>
-
non-nullable variables should be accepted for nullable args, by lrlna in pull/565
Fixes several
null
-related issues from 0.9.0. -
add an
UndefinedVariable
diagnostic, by goto-bus-stop in pull/563Previously undefined variables were reported with an
UndefinedDefinition
diagnostic. Splitting it up lets us provide a better error message for missing variables.
0.9.1 - 2023-05-19
- Update the apollo-parser dependency version, by goto-bus-stop in pull/559
0.9.0 - 2023-05-12
This release completes GraphQL validation specification, making the compiler spec-compliant.
You can validate the entire corpus of the compiler, or run individual compiler validation rules. The example below runs the whole corpus, as well specifically runs compiler.db.validate_executable(file_id)
for each of the two defined operations.
let schema = r#"
type Query {
cat: Cat
}
type Cat{
name: String!
nickname: String
purrVolume: Int
doesKnowCommand(catCommand: CatCommand!): Boolean!
}
enum CatCommand {
HOP
}
"#;
let cat_name_op = r#"
query getCatName {
cat {
name
}
}
"#;
let cat_command_op = r#"
query getCatName {
cat {
doesNotKnowCommand
}
}
"#;
let mut compiler = ApolloCompiler::new();
compiler.add_type_system(schema, "schema.graphl");
let cat_name_file = compiler.add_executable(cat_name_op, "cat_name_op.graphql");
let cat_command_file = compiler.add_executable(cat_command_op, "cat_command_op.graphql");
// validate both the operation and the type system
let all_diagnostics = compiler.validate();
assert_eq!(all_diagnostics.len(), 1);
// validate just the executables individual
let cat_name_op_diagnotics = compiler.db.validate_executable(cat_name_file);
assert!(cat_name_op_diagnotics.is_empty());
let cat_command_op_diagnotics = compiler.db.validate_executable(cat_command_file);
// This one has an error, where a field queries is not defined.
assert_eq!(cat_command_op_diagnotics.len(), 1);
for diag in cat_command_op_diagnotics {
println!("{}", diag);
}
-
remove
impl Default
for ApolloCompiler, by [dariuszkuc] in pull/542 -
align HIR extension getters to those of their type definition, by lrlna in pull/540
The following methods were changed:
InputObjectTypeExtension.fields_definition()
->InputObjectTypeDefinition.fields()
ObjectTypeExtension.fields_definition()
->ObjectTypeExtension.fields()
InterfaceTypeExtension.fields_definition()
->InterfaceTypeExtension.fields()
EnumTypeExtension.enum_values_definition()
->EnumTypeExtension.values()
UnionTypeExtension.union_members()
->UnionTypeExtension.members()
- validate values are of correct type, by lrlna in pull/550
- support the built-in
@deprecated
directive on arguments and input values, by goto-bus-stop in pull/518 - validate that variable usage is allowed, by lrlna in pull/537
- validate executable documents do not contain type definitions, by goto-bus-stop in pull/535
- validate union extensions, by goto-bus-stop in pull/534
- validate input object extensions, by goto-bus-stop in pull/533
- validate interface extensions, by goto-bus-stop in pull/532
- validate enum extensions, by goto-bus-stop in pull/528
- validate object type extensions, by goto-bus-stop in pull/524
- validate fragment spread is possible, by goto-bus-stop in pull/511
- fix recursion cycle in
is_introspection
HIR getter, by allancalix and goto-bus-stop in pull/544 and pull/552
0.8.0 - 2023-04-13
There is now an API to set parser's token limits via apollo-compiler
. To
accommodate an additional limit, we changed the API to set several limits
simultaneously.
let op = r#"
query {
a {
a {
a {
a
}
}
}
}
"#;
let mut compiler = ApolloCompiler::new().token_limit(22).recursion_limit(10);
compiler.add_executable(op, "op.graphql");
let errors = compiler.db.syntax_errors();
assert_eq!(errors.len(), 1)
- validate fragment definitions are used, by gocamille in pull/483
- validate fragment type condition exists in the type system and are declared on composite types, by gocamille in pull/483
- validate fragment definitions do not contain cycles, by goto-bus-stop in pull/518
- fix duplicate directive location info, by goto-bus-stop in pull/516
- use
LimitExceeded
diagnostic for limit related errors, by lrlna in pull/520
0.7.2 - 2023-04-03
- validate fragment spread target is defined, by goto-bus-stop in pull/506
- validate circular input objects, by lrlna in pull/505
0.7.1 - 2023-03-28
- validate indirectly self-referential directives by goto-bus-stop in pull/494
- include built-in enum types in
db.type_system()
query by SimonSapin in pull/501 field.field_definition()
works for interface types by zackangelo in pull/502- validate used variables in lists and objects by yanns in pull/497
0.7.0 - 2023-03-28
Important: X breaking changes below, indicated by BREAKING
This release encompasses quite a few validation rules the compiler was missing. Here, we primarily focused on field and directive validation, as well as supporting multi-file diagnostics.
find_operation
query now mimics spec'sgetOperation
functionality and returns the anonymous operation ifNone
is specified for operation name; by lrlna in pull/447- Extensions are applied implicitly in HIR by SimonSapin in pull/481, pull/482, and pull/484
Adding a GraphQL type extension is similar to modifying a type.
This release makes a number of breaking changes to API signatures and behavior
so these modifications are accounted for implicitly.
For example, interface.field(name)
may now return a field
from an extend interface
extension or from the original interface
definition.
We expect that most callers don’t need to tell the difference.
For callers that do, methods with a self_
prefix are added (or renamed)
for accessing components of a definition itself as opposed to added by an extension.
Renamed methods:
SchemaDefinition::root_operation_type_definition
→self_root_operations
ObjectTypeDefinition::fields_definition
→self_fields
InterfaceTypeDefinition::fields_definition
→self_fields
InputObjectTypeDefinition::input_fields_definition
→self_fields
ObjectTypeDefinition::implements_interfaces
→self_implements_interfaces
InterfaceTypeDefinition::implements_interfaces
→self_implements_interfaces
UnionTypeDefinition::union_members
→self_members
EnumTypeDefinition::enum_values_definition
→self_values
TypeDefiniton::directives
→self_directives
SchemaDefiniton::directives
→self_directives
EnumTypeDefiniton::directives
→self_directives
UnionTypeDefiniton::directives
→self_directives
ObjectTypeDefiniton::directives
→self_directives
ScalarTypeDefiniton::directives
→self_directives
InterfaceTypeDefiniton::directives
→self_directives
InputObjectTypeDefiniton::directives
→self_directives
Method names freed by the above are now redefined with new behaviour and signature, and include extensions:
ObjectTypeDefinition::implements_interfaces() -> impl Iterator
InterfaceTypeDefinition::implements_interfaces() -> impl Iterator
TypeDefiniton::directives() -> impl Iterator
SchemaDefiniton::directives() -> impl Iterator
EnumTypeDefiniton::directives() -> impl Iterator
UnionTypeDefiniton::directives() -> impl Iterator
ObjectTypeDefiniton::directives() -> impl Iterator
ScalarTypeDefiniton::directives() -> impl Iterator
InterfaceTypeDefiniton::directives() -> impl Iterator
InputObjectTypeDefiniton::directives() -> impl Iterator
Methods whose behaviour and signature changed, where each method now returns the name of an object type instead of its definition:
SchemaDefinition::query() -> Option<&str>
SchemaDefinition::mutation() -> Option<&str>
SchemaDefinition::subscription() -> Option<&str>
Methods whose behaviour changed to consider extensions, and no signature has changed
TypeDefinition::field(name) -> Option
ObjectTypeDefinition::field(name) -> Option
InterfaceTypeDefinition::field(name) -> Option
New methods which take extensions into consideration:
SchemaDefinition::root_operations() -> impl Iterator
ObjectTypeDefinition::fields() -> impl Iterator
ObjectTypeDefinition::implements_interface(name) -> bool
InterfaceTypeDefinition::fields() -> impl Iterator
InterfaceTypeDefinition::implements_interface(name) -> bool
InputObjectTypeDefinition::self_fields() -> &[_]
InputObjectTypeDefinition::fields() -> impl Iterator
InputObjectTypeDefinition::field(name) -> Option
UnionTypeDefinition::members() -> impl Iterator
UnionTypeDefinition::has_member(name) -> bool
EnumTypeDefinition::values() -> impl Iterator
EnumTypeDefinition::value(name) -> Option
New methods for every type which have a directives
method:
directive_by_name(name) -> Option
directives_by_name(name) -> impl Iterator
- support mutli-file diagnostics by goto-bus-stop in pull/414
- validate directive locations by lrlna in pull/417
- validate undefined directives by lrlna in pull/417
- validate non-repeatable directives in a given location by goto-bus-stop in pull/488
- validate conflicting fields in a selection set (spec: fields can merge) by goto-bus-stop in pull/470
- validate introspection fields in subscriptions by gocamille in [pull/438]
- validate required arguments by goto-bus-stop in pull/452
- validate unique variables by lrlna in pull/455
- validate variables are of input type by lrlna in pull/455
- validate root operation type is of Object Type by lrlna in pull/419
- validate nested fields in selection sets by erikwrede in pull/441
- validate extension existance and kind by goto-bus-stop in pull/458
- validate leaf field selection by yanns in pull/465
- introduce
op.is_introspection
helper method by jregistr in pull/421 - built-in graphql types, including introspection types, are now part of the compiler context by lrlna in pull/489
- fix variables in directive arguments being reported as unused goto-bus-stop in pull/487
op.operation_ty()
does not deref lrlna in pull/434
- tests for operation field type resolution v.s. type extensions by SimonSapin in pull/492
- using [salsa::invoke] macro to annotate trait function location by lrlna in pull/491
- use
Display
forhir::OperationType
andhir::DirectiveLocation
by goto-bus-stop in pull/435 - rework and simplify validation database by lrlna in pull/436
- reset
FileId
between directory tests by goto-bus-stop in pull/437 - remove unncessary into_iter() calls by goto-bus-stop in pull/472
- check test numbers are unique in test output files by goto-bus-stop in pull/471
0.6.0 - 2023-01-18
This release has a few breaking changes as we try to standardise APIs across the compiler. We appreciate your patience with these changes. If you run into trouble, please open an issue.
- Rename
compiler.create_*
methods tocompiler.add_*
, SimonSapin in pull/412 - Rename
schema
totype_system
forcompiler.add_
andcompiler.update_
methods, SimonSapin in pull/413 - Unify
ty
,type_def
andkind
namings in HIR, lrlna in pull/415- in
Type
struct impl:ty()
-->type_def()
- in
TypeDefinition
struct impl:ty()
-->kind()
- in
FragmentDefinition
struct impl:ty()
-->type_def()
- in
RootOperationTypeDefinition
struct:operation_type
field -->operation_ty
- in
FileId
s are unique per process, SimonSapin in [405]- Type alias
compiler.snapshot()
return type toSnapshot
, SimonSapin in [410] - Introduce a type system high-level intermediate representation (HIR) as input to the compiler, SimonSapin in [407]
- Use
#[salsa::transparent]
forfind_*
queries, i.e. not caching query results, lrlna in [403]
- Add compiler benchmarks, lrlna in [404]
- Document
apollo-rs
runs on stable, SimonSapin in [402]
0.5.0 - 2023-01-04
You can now build a compiler from multiple sources. This is especially useful when various parts of a GraphQL document are coming in at different times and need to be analysed as a single context. Or, alternatively, you are looking to lint or validate multiple GraphQL files part of the same context in a given directory or workspace.
The are three different kinds of sources:
document
: for when a source is composed of executable and type system definitions, or you're uncertain of definitions typesschema
: for sources with type system definitions or extensionsexecutable
: for sources with executable definitions/GraphQL queries
You can add a source with create_
and update it with update_
, for example
create_document
and update_document
. Here is an example:
let schema = r#"
type Query {
dog: Dog
}
type Dog {
name: String!
}
"#;
let query = r#"
query getDogName {
dog {
name
}
}
# duplicate name, should show up in diagnostics
query getDogName {
dog {
owner {
name
}
}
}
"#;
let updated_schema = r#"
type Query {
dog: Dog
}
type Dog {
name: String!
owner: Human
}
type Human {
name: String!
}
"#;
let mut compiler = ApolloCompiler::new();
let schema_id = compiler.create_schema(schema, "schema.graphl");
let executable_id = compiler.create_executable(query, "query.graphql");
compiler.update_schema(updated_schema, schema_id);
For more elaborate examples, please refer to multi_source_validation
and
file_watcher
examples in the examples
dir.
We look forward to your feedback on this feature, should you be using it.
Completed in pull/368 in collaboration with goto-bus-stop, SimonSapin and lrlna.
- Remove UUID helpers and related UUID APIs from database by SimonSapin in pull/391
- Merge
DocumentDatabase
trait intoHIRDatabase
by SimonSapin in pull/394 - Replace
hir::Definition
enum withhir::TypeSystemDefinitions
struct by SimonSapin in pull/395 db.type_system_definitions
returns aTypeSystemDefinitions
by SimonSapin in pull/395- Remove
db.db_definitions
,find_definition_by_name
andfind_type_system_definition_by_name
by SimonSapin in pull/395 - Remove queries returning type extensions, instead type definitions in the HIR contain extension information by SimonSapin in pull/387
db.fragments
,db.object_types
,db.scalars
,db.enums
,db.unions
,db.interfaces
,db.input_objects
, anddb.directive_definitions
return name-indexed maps by SimonSapin in pull/387
0.4.1 - 2022-12-13
- add new APIs - SimonSapin, pull/382
db.find_enum_by_name()
to look up anEnumTypeDefinition
.directive.argument_by_name()
to look up the value of an argument to a directive call.scalar_type.is_built_in()
to check if aScalarTypeDefinition
is defined by the GraphQL spec rather than the schema text.enum_value.directives()
to access the directives used on an enum value.hir::Float
is nowCopy
so it can be passed around more easily; usehir_float.get()
to access the underlyingf64
orhir_float.to_i32_checked()
to convert to ani32
.
-
do not panic when creating HIR from a parse tree with syntax errors - goto-bus-stop, pull/381
When using the compiler, nodes with syntax errors in them are ignored. As syntax errors are returned from the parser, you can still tell that something is wrong. The compiler just won't crash the whole program anymore.
0.4.0 - 2022-11-29
-
add parser recursion limit API - SimonSapin, pull/353, issue/296
Calling
ApolloCompiler::with_recursion_limit
instead ofApolloCompiler::new
makes the compiler configure the corresponding parser limit. This limit protects against stack overflow and is enabled either way. Configuring it may be useful for example if you’re also configuring the stack size. -
expose the repeatable attribute on
DirectiveDefinition
- allancalix, pull/367There was previously no way to access the
repeatable
field on theDirectiveDefinition
type. This field is required for validation rules. -
add type extensions - SimonSapin, pull/369
apollo-compiler now partially supports GraphQL
extend
types. Theis_subtype
query takes extensions into account.Some other parts of the compiler, like validation, do not yet support extensions.
-
fix
@include
allowed directive locations - allancalix, pull/366The locations for the
@include
directive wrongly specifiedFragmentDefinition
instead ofFragmentSpread
. It now matches the spec.
- avoid double lookup in
SchemaDefinition::{query,mutation,subscription}
- SimonSapin, pull/364
0.3.0 - 2022-11-02
-
compiler.parse is renamed to compiler.ast - lrlna, pull/290
compiler.ast()
returns theSyntaxTree
produced by the parser and is much clearer method thancompiler.parse()
. -
selection.ty(db) now expects a
db
parameter - lrlna, pull/290As byproduct of separating compiler's query_groups into individual components. Selection's type can now be accessed like so:
let ctx = ApolloCompiler::new(input); let top_product_fields: Vec<String> = top_products .iter() .filter_map(|field| Some(field.ty(&ctx.db)?.name())) .collect();
-
removes db.definitions() API - lrlna, pull/295
db.definitions()
returned a!Send
value that is no longer possible with theParallelDatabase
implementation.To access HIR definitions, use
db.db_definitions()
anddb.type_system_definitions
.
-
add subtype_map and is_subtype queries - lrlna/SimonSapin, pull/333
This allows users to check whether a particular type is a subtype of another type. For example, in a UnionDefinition such as
union SearchResult = Photo | Person
,Person
is a suptype ofSearchResult
. In an InterfaceDefinition such astype Business implements NamedEntity & ValuedEntity { # fields }
,Business
is a subtype ofNamedEntity
. -
pub compiler storage - allow database composition - lrlna, pull/328
This allows for internal query_groups to be exported, and allows users to compose various databases from compiler's existing dbs and their queries.
This is how you'd create a database with storage from apollo-compiler:
use apollo_compiler::{database::{AstStorage, DocumentStorage}}; #[salsa::database(AstStorage, DoumentStorage)] pub struct AnotherDatabase { pub storage: salsa::Storage<AnotherDatabase>, }
You can also see a more detailed linting example in examples dir.
-
validate argument name uniqueness - goto-bus-stop, pull/317
It's an error to declare or provide multiple arguments by the same name, eg:
type Query { things(offset: Int!, offset: Int!): [Thing] # ERR: duplicate argument definition: offset }
query GetThings { things(offset: 10, offset: 20) { id } # ERR: duplicate argument values: offset }
This adds
UniqueArgument
diagnostics and checks for argument duplications in: field definitions, fields, directives, interfaces and directive definitions. -
getter for directives in HIR FragmentSpread - allancalix, pull/315
Allow accessing directives in a given FragmentSpread node in a high-level intermediate representation of the compiler.
-
create validation database - lrlna, pull/303
All validation now happens in its own database, which can be accessed with
ValidationDatabase
andValidationStorage
. -
thread-safe compiler: introduce snapshots - lrlna, pull/295 + pull/332
Implements
ParallelDatabase
forRootDatabase
of the compiler. This allows us to create snapshots that can allow users to query the database from multiple threads. For example:let input = r#" type Query { website: URL, amount: Int } scalar URL @specifiedBy(url: "https://tools.ietf.org/html/rfc3986") "#; let ctx = ApolloCompiler::new(input); let diagnostics = ctx.validate(); for diagnostic in &diagnostics { println!("{}", diagnostic); } assert!(diagnostics.is_empty()); let snapshot = ctx.snapshot(); let snapshot2 = ctx.snapshot(); let thread1 = std::thread::spawn(move || snapshot.find_object_type_by_name("Query".into())); let thread2 = std::thread::spawn(move || snapshot2.scalars()); thread1.join().expect("object_type_by_name panicked"); thread2.join().expect("scalars failed");
-
add description getters to compiler's HIR nodes - aschaeffer, pull/289
Expose getters for descriptions that can be accessed for any definitions that support them. For example:
let input = r#" "Books in a given libary" type Book { id: ID! } "#; let ctx = ApolloCompiler::new(input); let desc = ctx.db.find_object_type_by_name("Book".to_string()).unwrap().description();
-
update parser version - goto-bus-stop, pull/331
-
unused variables return an error diagnostic - lrlna, pull/314
We were previously returning a warning for any unused variables, it is now reported as an error.
-
split up db into several components - lrlna, pull/290
We are splitting up the single
query_group
we had in our db into severalquery_group
s that currently just build upon each other, and eventually could support more complex relationships between one another. The current structure:Inputs
-->DocumentParser
-->Definitions
-->Document
All of these
query_group
s make up theRootDatabase
, i.e.salsa::database
.This also allows external users to build out their own databases with compiler's query groups.
-
support wasm compiler target - allancalix, pull/287, issue/288
apollo-compiler
can now compile to a Wasm target withcargo check --target wasm32-unknown-unknown
.
0.2.0 - 2022-08-16
-
inline_fragment().type_condition() returns Option<&str> - lrlna, pull/282
Instead of returning
Option<&String>
, we now returnOption<&str>
-
Value -> DefaultValue for default_value fields - lrlna, pull/276
default_value getters in Input Value Definitions and Variable Definitions now return
DefaultValue
type. This is a type alias to Value, and makes it consistent with the GraphQL spec.
-
add type information to inline fragments - lrlna, pull/282, issue/280
Inline fragments were missing type correct type information. We now search for applicable type's fields if a type condition exists, otherwise infer information from the current type in scope (as per spec) .Inline fragments
-
fix cycle error in fragment spreads referencing fragments - lrlna, pull/283, issue/281
Because fragment definitions can have fragment spreads, we are running into a self-referential cycle when searching for a fragment definition to get its id. Instead, search for the fragment definition when getting a fragment in a fragment spread in the wrapper API.
-
pub use ApolloDiagnostic - EverlastingBugstopper, pull/268
Exports ApolloDiagnostic to allow users to use it in other contexts.
-
default_value getter in input_value_definition - lrlna, pull/273
A getter for default values in input value definitions.
-
feat(compiler): add db.find_union_by_name() - lrlna, pull/272
Allows to query unions in the database.
-
adds inline_fragments getter to SelectionSet - lrlna, pull/282
Convenience method to get all inline fragments in the current selection set.
0.1.0 - 2022-07-27
Introducing apollo-compiler
!
A query-based compiler for the GraphQL language.
The compiler provides validation and context for GraphQL documents with a comprehensive API.
This is still a work in progress, for outstanding issues, checkout out the apollo-compiler label in our issue tracker.