Define AST types for schema
This commit is contained in:
parent
6de85377f7
commit
752f6adde8
32
async-graphql-parser/src/error.rs
Normal file
32
async-graphql-parser/src/error.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use crate::Pos;
|
||||
use pest::error::LineColLocation;
|
||||
use pest::RuleType;
|
||||
use std::fmt;
|
||||
|
||||
/// Parser error
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub struct Error {
|
||||
pub pos: Pos,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: RuleType> From<pest::error::Error<R>> for Error {
|
||||
fn from(err: pest::error::Error<R>) -> Self {
|
||||
Error {
|
||||
pos: {
|
||||
let (line, column) = match err.line_col {
|
||||
LineColLocation::Pos((line, column)) => (line, column),
|
||||
LineColLocation::Span((line, column), _) => (line, column),
|
||||
};
|
||||
Pos { line, column }
|
||||
},
|
||||
message: err.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,11 +3,16 @@ extern crate pest_derive;
|
|||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
mod pos;
|
||||
pub mod query;
|
||||
pub mod schema;
|
||||
|
||||
mod error;
|
||||
mod pos;
|
||||
mod query_parser;
|
||||
mod utils;
|
||||
mod value;
|
||||
|
||||
pub use error::Error;
|
||||
pub use pos::{Pos, Positioned};
|
||||
pub use query_parser::{parse_query, parse_value, Error, ParsedValue, Result};
|
||||
pub use query_parser::{parse_query, parse_value, ParsedValue, Result};
|
||||
pub use value::{UploadValue, Value};
|
||||
|
|
|
@ -29,7 +29,6 @@ nonnull_type = { (list_type | name) ~ "!" }
|
|||
type_ = { nonnull_type | list_type | name }
|
||||
|
||||
// query
|
||||
|
||||
arguments = { "(" ~ pair* ~ ")" }
|
||||
directive = { "@" ~ name ~ arguments? }
|
||||
directives = { directive* }
|
||||
|
|
|
@ -1,102 +1,22 @@
|
|||
use crate::pos::Positioned;
|
||||
use crate::query::*;
|
||||
use crate::utils::{to_static_str, unquote_string, PositionCalculator};
|
||||
use crate::value::Value;
|
||||
use crate::Pos;
|
||||
use arrayvec::ArrayVec;
|
||||
use pest::error::LineColLocation;
|
||||
use crate::{Error, Pos};
|
||||
use pest::iterators::Pair;
|
||||
use pest::Parser;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::iter::Peekable;
|
||||
use std::ops::Deref;
|
||||
use std::str::Chars;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "query.pest"]
|
||||
struct QueryParser;
|
||||
|
||||
/// Parser error
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub struct Error {
|
||||
pub pos: Pos,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<pest::error::Error<Rule>> for Error {
|
||||
fn from(err: pest::error::Error<Rule>) -> Self {
|
||||
Error {
|
||||
pos: {
|
||||
let (line, column) = match err.line_col {
|
||||
LineColLocation::Pos((line, column)) => (line, column),
|
||||
LineColLocation::Span((line, column), _) => (line, column),
|
||||
};
|
||||
Pos { line, column }
|
||||
},
|
||||
message: err.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parser result
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub(crate) struct PositionCalculator<'a> {
|
||||
input: Peekable<Chars<'a>>,
|
||||
pos: usize,
|
||||
line: usize,
|
||||
column: usize,
|
||||
}
|
||||
|
||||
impl<'a> PositionCalculator<'a> {
|
||||
fn new(input: &'a str) -> PositionCalculator<'a> {
|
||||
Self {
|
||||
input: input.chars().peekable(),
|
||||
pos: 0,
|
||||
line: 1,
|
||||
column: 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(&mut self, pair: &Pair<Rule>) -> Pos {
|
||||
let pos = pair.as_span().start();
|
||||
debug_assert!(pos >= self.pos);
|
||||
for _ in 0..pos - self.pos {
|
||||
match self.input.next() {
|
||||
Some('\r') => {
|
||||
if let Some(&'\n') = self.input.peek() {
|
||||
self.input.next();
|
||||
self.line += 1;
|
||||
self.column = 1;
|
||||
} else {
|
||||
self.column += 1;
|
||||
}
|
||||
}
|
||||
Some('\n') => {
|
||||
self.line += 1;
|
||||
self.column = 1;
|
||||
}
|
||||
Some(_) => {
|
||||
self.column += 1;
|
||||
}
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
self.pos = pos;
|
||||
Pos {
|
||||
line: self.line,
|
||||
column: self.column,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a GraphQL query.
|
||||
pub fn parse_query<T: Into<String>>(input: T) -> Result<Document> {
|
||||
let source = input.into();
|
||||
|
@ -134,6 +54,12 @@ pub struct ParsedValue {
|
|||
value: Value,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ParsedValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ParsedValue {
|
||||
type Target = Value;
|
||||
|
||||
|
@ -647,103 +573,6 @@ fn parse_fragment_definition(
|
|||
))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_static_str(s: &str) -> &'static str {
|
||||
unsafe { (s as *const str).as_ref().unwrap() }
|
||||
}
|
||||
|
||||
fn unquote_string(s: &'static str, pos: Pos) -> Result<Cow<'static, str>> {
|
||||
debug_assert!(s.starts_with('"') && s.ends_with('"'));
|
||||
let s = &s[1..s.len() - 1];
|
||||
|
||||
if !s.contains('\\') {
|
||||
return Ok(Cow::Borrowed(to_static_str(s)));
|
||||
}
|
||||
|
||||
let mut chars = s.chars();
|
||||
let mut res = String::with_capacity(s.len());
|
||||
let mut temp_code_point = ArrayVec::<[u8; 4]>::new();
|
||||
|
||||
while let Some(c) = chars.next() {
|
||||
match c {
|
||||
'\\' => {
|
||||
match chars.next().expect("slash cant be at the end") {
|
||||
c @ '"' | c @ '\\' | c @ '/' => res.push(c),
|
||||
'b' => res.push('\u{0010}'),
|
||||
'f' => res.push('\u{000C}'),
|
||||
'n' => res.push('\n'),
|
||||
'r' => res.push('\r'),
|
||||
't' => res.push('\t'),
|
||||
'u' => {
|
||||
temp_code_point.clear();
|
||||
for _ in 0..4 {
|
||||
match chars.next() {
|
||||
Some(inner_c) if inner_c.is_digit(16) => {
|
||||
temp_code_point.push(inner_c as u8)
|
||||
}
|
||||
Some(inner_c) => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!(
|
||||
"{} is not a valid unicode code point",
|
||||
inner_c
|
||||
),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!(
|
||||
"{} must have 4 characters after it",
|
||||
unsafe {
|
||||
std::str::from_utf8_unchecked(
|
||||
temp_code_point.as_slice(),
|
||||
)
|
||||
}
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert our hex string into a u32, then convert that into a char
|
||||
match u32::from_str_radix(
|
||||
unsafe { std::str::from_utf8_unchecked(temp_code_point.as_slice()) },
|
||||
16,
|
||||
)
|
||||
.map(std::char::from_u32)
|
||||
{
|
||||
Ok(Some(unicode_char)) => res.push(unicode_char),
|
||||
_ => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!(
|
||||
"{} is not a valid unicode code point",
|
||||
unsafe {
|
||||
std::str::from_utf8_unchecked(
|
||||
temp_code_point.as_slice(),
|
||||
)
|
||||
}
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
c => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!("bad escaped char {:?}", c),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
c => res.push(c),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Cow::Owned(res))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
31
async-graphql-parser/src/schema.pest
Normal file
31
async-graphql-parser/src/schema.pest
Normal file
|
@ -0,0 +1,31 @@
|
|||
WHITESPACE = _{ " " | "," | "\t" | "\u{feff}" | NEWLINE }
|
||||
COMMENT = _{ "#" ~ (!"\n" ~ ANY)* }
|
||||
|
||||
// value
|
||||
int = @{ "-"? ~ ("0" | (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)) }
|
||||
float = @{ "-"? ~ int ~ "." ~ ASCII_DIGIT+ ~ exp? }
|
||||
exp = @{ ("E" | "e") ~ ("+" | "-")? ~ ASCII_DIGIT+ }
|
||||
|
||||
string = @{ "\"" ~ string_inner ~ "\"" }
|
||||
string_inner = @{ (!("\"" | "\\") ~ ANY)* ~ (escape ~ string_inner)? }
|
||||
escape = @{ "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | unicode) }
|
||||
unicode = @{ "u" ~ ASCII_HEX_DIGIT{4} }
|
||||
|
||||
boolean = { "true" | "false" }
|
||||
null = { "null" }
|
||||
name = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHA | ASCII_DIGIT | "_")* }
|
||||
variable = { "$" ~ name }
|
||||
|
||||
array = { "[" ~ value* ~ "]" }
|
||||
|
||||
pair = { name ~ ":" ~ value }
|
||||
object = { "{" ~ pair* ~ "}" }
|
||||
|
||||
value = { object | array | variable | float | int | string | null | boolean | name }
|
||||
|
||||
// type
|
||||
list_type = { "[" ~ type_ ~ "]" }
|
||||
nonnull_type = { (list_type | name) ~ "!" }
|
||||
type_ = { nonnull_type | list_type | name }
|
||||
|
||||
// type system
|
149
async-graphql-parser/src/schema.rs
Normal file
149
async-graphql-parser/src/schema.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
use crate::pos::Positioned;
|
||||
use crate::ParsedValue;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Type {
|
||||
Named(String),
|
||||
List(Box<Type>),
|
||||
NonNull(Box<Type>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Document {
|
||||
pub definitions: Vec<Positioned<Definition>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Definition {
|
||||
SchemaDefinition(Positioned<SchemaDefinition>),
|
||||
TypeDefinition {
|
||||
extend: bool,
|
||||
description: Positioned<String>,
|
||||
definition: Positioned<TypeDefinition>,
|
||||
},
|
||||
DirectiveDefinition(Positioned<DirectiveDefinition>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SchemaDefinition {
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
pub query: Option<Positioned<String>>,
|
||||
pub mutation: Option<Positioned<String>>,
|
||||
pub subscription: Option<Positioned<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeDefinition {
|
||||
Scalar(Positioned<ScalarType>),
|
||||
Object(Positioned<ObjectType>),
|
||||
Interface(Positioned<InterfaceType>),
|
||||
Union(Positioned<UnionType>),
|
||||
Enum(Positioned<EnumType>),
|
||||
InputObject(Positioned<InputObjectType>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ScalarType {
|
||||
pub name: Positioned<String>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectType {
|
||||
pub name: Positioned<String>,
|
||||
pub implements_interfaces: Vec<Positioned<String>>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
pub fields: Vec<Positioned<Field>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Field {
|
||||
pub description: Option<Positioned<String>>,
|
||||
pub name: Positioned<String>,
|
||||
pub arguments: Vec<Positioned<InputValue>>,
|
||||
pub ty: Positioned<Type>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InputValue {
|
||||
pub description: Option<Positioned<String>>,
|
||||
pub name: Positioned<String>,
|
||||
pub ty: Positioned<Type>,
|
||||
pub default_value: Option<ParsedValue>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceType {
|
||||
pub name: Positioned<String>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
pub fields: Vec<Positioned<Field>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnionType {
|
||||
pub name: Positioned<String>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
pub types: Vec<Positioned<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EnumType {
|
||||
pub name: Positioned<String>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
pub values: Vec<Positioned<EnumValue>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EnumValue {
|
||||
pub description: Option<Positioned<String>>,
|
||||
pub name: Positioned<String>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InputObjectType {
|
||||
pub name: Positioned<String>,
|
||||
pub directives: Vec<Positioned<Directive>>,
|
||||
pub fields: Vec<Positioned<InputValue>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DirectiveLocation {
|
||||
// executable
|
||||
Query,
|
||||
Mutation,
|
||||
Subscription,
|
||||
Field,
|
||||
FragmentDefinition,
|
||||
FragmentSpread,
|
||||
InlineFragment,
|
||||
|
||||
// type_system
|
||||
Schema,
|
||||
Scalar,
|
||||
Object,
|
||||
FieldDefinition,
|
||||
ArgumentDefinition,
|
||||
Interface,
|
||||
Union,
|
||||
Enum,
|
||||
EnumValue,
|
||||
InputObject,
|
||||
InputFieldDefinition,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DirectiveDefinition {
|
||||
pub description: Option<Positioned<String>>,
|
||||
pub name: Positioned<String>,
|
||||
pub arguments: Vec<Positioned<InputValue>>,
|
||||
pub locations: Vec<Positioned<DirectiveLocation>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Directive {
|
||||
pub name: Positioned<String>,
|
||||
pub arguments: Vec<(Positioned<String>, Positioned<ParsedValue>)>,
|
||||
}
|
153
async-graphql-parser/src/utils.rs
Normal file
153
async-graphql-parser/src/utils.rs
Normal file
|
@ -0,0 +1,153 @@
|
|||
use crate::{Error, Pos, Result};
|
||||
use arrayvec::ArrayVec;
|
||||
use pest::iterators::Pair;
|
||||
use pest::RuleType;
|
||||
use std::borrow::Cow;
|
||||
use std::iter::Peekable;
|
||||
use std::str::Chars;
|
||||
|
||||
pub struct PositionCalculator<'a> {
|
||||
input: Peekable<Chars<'a>>,
|
||||
pos: usize,
|
||||
line: usize,
|
||||
column: usize,
|
||||
}
|
||||
|
||||
impl<'a> PositionCalculator<'a> {
|
||||
pub fn new(input: &'a str) -> PositionCalculator<'a> {
|
||||
Self {
|
||||
input: input.chars().peekable(),
|
||||
pos: 0,
|
||||
line: 1,
|
||||
column: 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step<R: RuleType>(&mut self, pair: &Pair<R>) -> Pos {
|
||||
let pos = pair.as_span().start();
|
||||
debug_assert!(pos >= self.pos);
|
||||
for _ in 0..pos - self.pos {
|
||||
match self.input.next() {
|
||||
Some('\r') => {
|
||||
if let Some(&'\n') = self.input.peek() {
|
||||
self.input.next();
|
||||
self.line += 1;
|
||||
self.column = 1;
|
||||
} else {
|
||||
self.column += 1;
|
||||
}
|
||||
}
|
||||
Some('\n') => {
|
||||
self.line += 1;
|
||||
self.column = 1;
|
||||
}
|
||||
Some(_) => {
|
||||
self.column += 1;
|
||||
}
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
self.pos = pos;
|
||||
Pos {
|
||||
line: self.line,
|
||||
column: self.column,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_static_str(s: &str) -> &'static str {
|
||||
unsafe { (s as *const str).as_ref().unwrap() }
|
||||
}
|
||||
|
||||
pub fn unquote_string(s: &'static str, pos: Pos) -> Result<Cow<'static, str>> {
|
||||
debug_assert!(s.starts_with('"') && s.ends_with('"'));
|
||||
let s = &s[1..s.len() - 1];
|
||||
|
||||
if !s.contains('\\') {
|
||||
return Ok(Cow::Borrowed(to_static_str(s)));
|
||||
}
|
||||
|
||||
let mut chars = s.chars();
|
||||
let mut res = String::with_capacity(s.len());
|
||||
let mut temp_code_point = ArrayVec::<[u8; 4]>::new();
|
||||
|
||||
while let Some(c) = chars.next() {
|
||||
match c {
|
||||
'\\' => {
|
||||
match chars.next().expect("slash cant be at the end") {
|
||||
c @ '"' | c @ '\\' | c @ '/' => res.push(c),
|
||||
'b' => res.push('\u{0010}'),
|
||||
'f' => res.push('\u{000C}'),
|
||||
'n' => res.push('\n'),
|
||||
'r' => res.push('\r'),
|
||||
't' => res.push('\t'),
|
||||
'u' => {
|
||||
temp_code_point.clear();
|
||||
for _ in 0..4 {
|
||||
match chars.next() {
|
||||
Some(inner_c) if inner_c.is_digit(16) => {
|
||||
temp_code_point.push(inner_c as u8)
|
||||
}
|
||||
Some(inner_c) => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!(
|
||||
"{} is not a valid unicode code point",
|
||||
inner_c
|
||||
),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!(
|
||||
"{} must have 4 characters after it",
|
||||
unsafe {
|
||||
std::str::from_utf8_unchecked(
|
||||
temp_code_point.as_slice(),
|
||||
)
|
||||
}
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert our hex string into a u32, then convert that into a char
|
||||
match u32::from_str_radix(
|
||||
unsafe { std::str::from_utf8_unchecked(temp_code_point.as_slice()) },
|
||||
16,
|
||||
)
|
||||
.map(std::char::from_u32)
|
||||
{
|
||||
Ok(Some(unicode_char)) => res.push(unicode_char),
|
||||
_ => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!(
|
||||
"{} is not a valid unicode code point",
|
||||
unsafe {
|
||||
std::str::from_utf8_unchecked(
|
||||
temp_code_point.as_slice(),
|
||||
)
|
||||
}
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
c => {
|
||||
return Err(Error {
|
||||
pos,
|
||||
message: format!("bad escaped char {:?}", c),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
c => res.push(c),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Cow::Owned(res))
|
||||
}
|
1
async-graphql-parser/tests/schemas/directive.graphql
Normal file
1
async-graphql-parser/tests/schemas/directive.graphql
Normal file
|
@ -0,0 +1 @@
|
|||
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
Directs the executor to include this field or fragment only when the `if` argument is true.
|
||||
"""
|
||||
directive @include(
|
||||
"""
|
||||
Included when true.
|
||||
"""
|
||||
if: Boolean!
|
||||
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
"""
|
||||
Directs the executor to skip this field or fragment when the `if` argument is true.
|
||||
"""
|
||||
directive @skip(
|
||||
"""
|
||||
Skipped when true.
|
||||
"""
|
||||
if: Boolean!
|
||||
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
|
@ -0,0 +1,13 @@
|
|||
"""
|
||||
Directs the executor to include this field or fragment only when the `if` argument is true.
|
||||
"""
|
||||
directive @include("""
|
||||
Included when true.
|
||||
""" if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
"""
|
||||
Directs the executor to skip this field or fragment when the `if` argument is true.
|
||||
"""
|
||||
directive @skip("""
|
||||
Skipped when true.
|
||||
""" if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
1
async-graphql-parser/tests/schemas/empty_union.graphql
Normal file
1
async-graphql-parser/tests/schemas/empty_union.graphql
Normal file
|
@ -0,0 +1 @@
|
|||
union UndefinedUnion
|
4
async-graphql-parser/tests/schemas/enum.graphql
Normal file
4
async-graphql-parser/tests/schemas/enum.graphql
Normal file
|
@ -0,0 +1,4 @@
|
|||
enum Site {
|
||||
DESKTOP
|
||||
MOBILE
|
||||
}
|
3
async-graphql-parser/tests/schemas/extend_enum.graphql
Normal file
3
async-graphql-parser/tests/schemas/extend_enum.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
extend enum Site {
|
||||
VR
|
||||
}
|
3
async-graphql-parser/tests/schemas/extend_input.graphql
Normal file
3
async-graphql-parser/tests/schemas/extend_input.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
extend input InputType {
|
||||
other: Float = 1.23e4
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
extend input InputType {
|
||||
other: Float = 12300
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
extend interface Bar {
|
||||
two(argument: InputType!): Type
|
||||
}
|
3
async-graphql-parser/tests/schemas/extend_object.graphql
Normal file
3
async-graphql-parser/tests/schemas/extend_object.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
extend type Foo {
|
||||
seven(argument: [String]): Type
|
||||
}
|
1
async-graphql-parser/tests/schemas/extend_scalar.graphql
Normal file
1
async-graphql-parser/tests/schemas/extend_scalar.graphql
Normal file
|
@ -0,0 +1 @@
|
|||
extend scalar CustomScalar @onScalar
|
3
async-graphql-parser/tests/schemas/implements.graphql
Normal file
3
async-graphql-parser/tests/schemas/implements.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
type Type1 implements IOne
|
||||
|
||||
type Type1 implements IOne & ITwo
|
|
@ -0,0 +1,2 @@
|
|||
type Type1 implements & IOne & ITwo
|
||||
type Type2 implements & IOne
|
|
@ -0,0 +1,3 @@
|
|||
type Type1 implements IOne & ITwo
|
||||
|
||||
type Type2 implements IOne
|
4
async-graphql-parser/tests/schemas/input_type.graphql
Normal file
4
async-graphql-parser/tests/schemas/input_type.graphql
Normal file
|
@ -0,0 +1,4 @@
|
|||
input InputType {
|
||||
key: String!
|
||||
answer: Int = 42
|
||||
}
|
3
async-graphql-parser/tests/schemas/interface.graphql
Normal file
3
async-graphql-parser/tests/schemas/interface.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
interface Bar {
|
||||
one: Type
|
||||
}
|
117
async-graphql-parser/tests/schemas/kitchen-sink.graphql
Normal file
117
async-graphql-parser/tests/schemas/kitchen-sink.graphql
Normal file
|
@ -0,0 +1,117 @@
|
|||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
schema {
|
||||
query: QueryType
|
||||
mutation: MutationType
|
||||
}
|
||||
|
||||
"""
|
||||
This is a description
|
||||
of the `Foo` type.
|
||||
"""
|
||||
type Foo implements Bar & Baz {
|
||||
one: Type
|
||||
two(argument: InputType!): Type
|
||||
three(argument: InputType, other: String): Int
|
||||
four(argument: String = "string"): String
|
||||
five(argument: [String] = ["string", "string"]): String
|
||||
six(argument: InputType = {key: "value"}): Type
|
||||
seven(argument: Int = null): Type
|
||||
}
|
||||
|
||||
type AnnotatedObject @onObject(arg: "value") {
|
||||
annotatedField(arg: Type = "default" @onArg): Type @onField
|
||||
}
|
||||
|
||||
type UndefinedType
|
||||
|
||||
extend type Foo {
|
||||
seven(argument: [String]): Type
|
||||
}
|
||||
|
||||
extend type Foo @onType
|
||||
|
||||
interface Bar {
|
||||
one: Type
|
||||
four(argument: String = "string"): String
|
||||
}
|
||||
|
||||
interface AnnotatedInterface @onInterface {
|
||||
annotatedField(arg: Type @onArg): Type @onField
|
||||
}
|
||||
|
||||
interface UndefinedInterface
|
||||
|
||||
extend interface Bar {
|
||||
two(argument: InputType!): Type
|
||||
}
|
||||
|
||||
extend interface Bar @onInterface
|
||||
|
||||
union Feed = Story | Article | Advert
|
||||
|
||||
union AnnotatedUnion @onUnion = A | B
|
||||
|
||||
union AnnotatedUnionTwo @onUnion = | A | B
|
||||
|
||||
union UndefinedUnion
|
||||
|
||||
extend union Feed = Photo | Video
|
||||
|
||||
extend union Feed @onUnion
|
||||
|
||||
scalar CustomScalar
|
||||
|
||||
scalar AnnotatedScalar @onScalar
|
||||
|
||||
extend scalar CustomScalar @onScalar
|
||||
|
||||
enum Site {
|
||||
DESKTOP
|
||||
MOBILE
|
||||
}
|
||||
|
||||
enum AnnotatedEnum @onEnum {
|
||||
ANNOTATED_VALUE @onEnumValue
|
||||
OTHER_VALUE
|
||||
}
|
||||
|
||||
enum UndefinedEnum
|
||||
|
||||
extend enum Site {
|
||||
VR
|
||||
}
|
||||
|
||||
extend enum Site @onEnum
|
||||
|
||||
input InputType {
|
||||
key: String!
|
||||
answer: Int = 42
|
||||
}
|
||||
|
||||
input AnnotatedInput @onInputObject {
|
||||
annotatedField: Type @onField
|
||||
}
|
||||
|
||||
input UndefinedInput
|
||||
|
||||
extend input InputType {
|
||||
other: Float = 1.23e4
|
||||
}
|
||||
|
||||
extend input InputType @onInputObject
|
||||
|
||||
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
directive @include(if: Boolean!)
|
||||
on FIELD
|
||||
| FRAGMENT_SPREAD
|
||||
| INLINE_FRAGMENT
|
||||
|
||||
directive @include2(if: Boolean!) on
|
||||
| FIELD
|
||||
| FRAGMENT_SPREAD
|
||||
| INLINE_FRAGMENT
|
|
@ -0,0 +1,106 @@
|
|||
schema {
|
||||
query: QueryType
|
||||
mutation: MutationType
|
||||
}
|
||||
|
||||
"""
|
||||
This is a description
|
||||
of the `Foo` type.
|
||||
"""
|
||||
type Foo implements Bar & Baz {
|
||||
one: Type
|
||||
two(argument: InputType!): Type
|
||||
three(argument: InputType, other: String): Int
|
||||
four(argument: String = "string"): String
|
||||
five(argument: [String] = ["string", "string"]): String
|
||||
six(argument: InputType = {key: "value"}): Type
|
||||
seven(argument: Int = null): Type
|
||||
}
|
||||
|
||||
type AnnotatedObject @onObject(arg: "value") {
|
||||
annotatedField(arg: Type = "default" @onArg): Type @onField
|
||||
}
|
||||
|
||||
type UndefinedType
|
||||
|
||||
extend type Foo {
|
||||
seven(argument: [String]): Type
|
||||
}
|
||||
|
||||
extend type Foo @onType
|
||||
|
||||
interface Bar {
|
||||
one: Type
|
||||
four(argument: String = "string"): String
|
||||
}
|
||||
|
||||
interface AnnotatedInterface @onInterface {
|
||||
annotatedField(arg: Type @onArg): Type @onField
|
||||
}
|
||||
|
||||
interface UndefinedInterface
|
||||
|
||||
extend interface Bar {
|
||||
two(argument: InputType!): Type
|
||||
}
|
||||
|
||||
extend interface Bar @onInterface
|
||||
|
||||
union Feed = Story | Article | Advert
|
||||
|
||||
union AnnotatedUnion @onUnion = A | B
|
||||
|
||||
union AnnotatedUnionTwo @onUnion = A | B
|
||||
|
||||
union UndefinedUnion
|
||||
|
||||
extend union Feed = Photo | Video
|
||||
|
||||
extend union Feed @onUnion
|
||||
|
||||
scalar CustomScalar
|
||||
|
||||
scalar AnnotatedScalar @onScalar
|
||||
|
||||
extend scalar CustomScalar @onScalar
|
||||
|
||||
enum Site {
|
||||
DESKTOP
|
||||
MOBILE
|
||||
}
|
||||
|
||||
enum AnnotatedEnum @onEnum {
|
||||
ANNOTATED_VALUE @onEnumValue
|
||||
OTHER_VALUE
|
||||
}
|
||||
|
||||
enum UndefinedEnum
|
||||
|
||||
extend enum Site {
|
||||
VR
|
||||
}
|
||||
|
||||
extend enum Site @onEnum
|
||||
|
||||
input InputType {
|
||||
key: String!
|
||||
answer: Int = 42
|
||||
}
|
||||
|
||||
input AnnotatedInput @onInputObject {
|
||||
annotatedField: Type @onField
|
||||
}
|
||||
|
||||
input UndefinedInput
|
||||
|
||||
extend input InputType {
|
||||
other: Float = 12300
|
||||
}
|
||||
|
||||
extend input InputType @onInputObject
|
||||
|
||||
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
directive @include2(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
3
async-graphql-parser/tests/schemas/minimal.graphql
Normal file
3
async-graphql-parser/tests/schemas/minimal.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
schema {
|
||||
query: Query
|
||||
}
|
1
async-graphql-parser/tests/schemas/minimal_type.graphql
Normal file
1
async-graphql-parser/tests/schemas/minimal_type.graphql
Normal file
|
@ -0,0 +1 @@
|
|||
type UndefinedType
|
2
async-graphql-parser/tests/schemas/scalar_type.graphql
Normal file
2
async-graphql-parser/tests/schemas/scalar_type.graphql
Normal file
|
@ -0,0 +1,2 @@
|
|||
"This is the best scalar type"
|
||||
scalar BestType @perfectness(value: 100500)
|
3
async-graphql-parser/tests/schemas/simple_object.graphql
Normal file
3
async-graphql-parser/tests/schemas/simple_object.graphql
Normal file
|
@ -0,0 +1,3 @@
|
|||
type Foo {
|
||||
bar: Type
|
||||
}
|
1
async-graphql-parser/tests/schemas/union.graphql
Normal file
1
async-graphql-parser/tests/schemas/union.graphql
Normal file
|
@ -0,0 +1 @@
|
|||
union Feed = Story | Article | Advert
|
|
@ -0,0 +1 @@
|
|||
extend union Feed = Photo | Video
|
Loading…
Reference in New Issue
Block a user