graphql 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/{types/input_value.rb → argument.rb} +4 -1
  3. data/lib/graph_ql/{scalars/boolean_type.rb → boolean_type.rb} +0 -0
  4. data/lib/graph_ql/definition_helpers.rb +10 -0
  5. data/lib/graph_ql/definition_helpers/argument_definer.rb +5 -2
  6. data/lib/graph_ql/definition_helpers/definable.rb +1 -1
  7. data/lib/graph_ql/definition_helpers/field_definer.rb +4 -1
  8. data/lib/graph_ql/definition_helpers/non_null_with_bang.rb +3 -1
  9. data/lib/graph_ql/definition_helpers/string_named_hash.rb +7 -1
  10. data/lib/graph_ql/definition_helpers/type_definer.rb +13 -1
  11. data/lib/graph_ql/directive.rb +14 -6
  12. data/lib/graph_ql/{directives → directive}/include_directive.rb +1 -1
  13. data/lib/graph_ql/{directives → directive}/skip_directive.rb +1 -1
  14. data/lib/graph_ql/enum_type.rb +66 -0
  15. data/lib/graph_ql/field.rb +49 -13
  16. data/lib/graph_ql/{scalars/float_type.rb → float_type.rb} +0 -0
  17. data/lib/graph_ql/{scalars/id_type.rb → id_type.rb} +0 -0
  18. data/lib/graph_ql/input_object_type.rb +33 -0
  19. data/lib/graph_ql/{scalars/int_type.rb → int_type.rb} +0 -0
  20. data/lib/graph_ql/interface_type.rb +33 -0
  21. data/lib/graph_ql/introspection/field_type.rb +1 -0
  22. data/lib/graph_ql/introspection/fields_field.rb +1 -0
  23. data/lib/graph_ql/introspection/input_value_type.rb +1 -1
  24. data/lib/graph_ql/introspection/introspection_query.rb +77 -0
  25. data/lib/graph_ql/introspection/schema_field.rb +13 -0
  26. data/lib/graph_ql/introspection/type_by_name_field.rb +14 -0
  27. data/lib/graph_ql/introspection/type_kind_enum.rb +1 -1
  28. data/lib/graph_ql/{types/list_type.rb → list_type.rb} +3 -0
  29. data/lib/graph_ql/{parser/nodes.rb → nodes.rb} +8 -1
  30. data/lib/graph_ql/{types/non_null_type.rb → non_null_type.rb} +3 -0
  31. data/lib/graph_ql/object_type.rb +92 -0
  32. data/lib/graph_ql/parser.rb +107 -6
  33. data/lib/graph_ql/query.rb +8 -0
  34. data/lib/graph_ql/query/arguments.rb +13 -4
  35. data/lib/graph_ql/{directives → query}/directive_chain.rb +2 -2
  36. data/lib/graph_ql/query/field_resolution_strategy.rb +2 -2
  37. data/lib/graph_ql/query/operation_resolver.rb +3 -3
  38. data/lib/graph_ql/query/selection_resolver.rb +1 -1
  39. data/lib/graph_ql/scalar_type.rb +9 -0
  40. data/lib/graph_ql/schema.rb +26 -17
  41. data/lib/graph_ql/schema/type_reducer.rb +7 -0
  42. data/lib/graph_ql/static_validation/arguments_validator.rb +1 -0
  43. data/lib/graph_ql/static_validation/message.rb +4 -1
  44. data/lib/graph_ql/static_validation/rules/fields_are_defined_on_type.rb +1 -0
  45. data/lib/graph_ql/static_validation/rules/fields_have_appropriate_selections.rb +1 -0
  46. data/lib/graph_ql/static_validation/type_stack.rb +24 -4
  47. data/lib/graph_ql/static_validation/validator.rb +27 -0
  48. data/lib/graph_ql/{scalars/string_type.rb → string_type.rb} +0 -0
  49. data/lib/graph_ql/transform.rb +87 -0
  50. data/lib/graph_ql/type_kinds.rb +9 -0
  51. data/lib/graph_ql/{types/union.rb → union_type.rb} +8 -4
  52. data/lib/graph_ql/version.rb +1 -1
  53. data/lib/graph_ql/{parser/visitor.rb → visitor.rb} +29 -4
  54. data/lib/graphql.rb +28 -11
  55. data/readme.md +11 -1
  56. data/spec/graph_ql/{types/enum_spec.rb → enum_type_spec.rb} +1 -1
  57. data/spec/graph_ql/{fields/field_spec.rb → field_spec.rb} +0 -0
  58. data/spec/graph_ql/{scalars/id_type_spec.rb → id_type_spec.rb} +0 -0
  59. data/spec/graph_ql/{types/input_object_type_spec.rb → input_object_type_spec.rb} +0 -0
  60. data/spec/graph_ql/{types/interface_spec.rb → interface_type_spec.rb} +1 -1
  61. data/spec/graph_ql/introspection/introspection_query_spec.rb +10 -0
  62. data/spec/graph_ql/introspection/schema_type_spec.rb +0 -4
  63. data/spec/graph_ql/introspection/type_type_spec.rb +1 -5
  64. data/spec/graph_ql/{types/object_type_spec.rb → object_type_spec.rb} +0 -0
  65. data/spec/graph_ql/{parser/parser_spec.rb → parser_spec.rb} +0 -0
  66. data/spec/graph_ql/query/operation_resolver_spec.rb +1 -1
  67. data/spec/graph_ql/query_spec.rb +6 -2
  68. data/spec/graph_ql/schema/type_validator_spec.rb +1 -1
  69. data/spec/graph_ql/{parser/transform_spec.rb → transform_spec.rb} +0 -0
  70. data/spec/graph_ql/{types/union_spec.rb → union_type_spec.rb} +2 -2
  71. data/spec/graph_ql/{parser/visitor_spec.rb → visitor_spec.rb} +0 -0
  72. data/spec/support/{dummy_app.rb → dairy_app.rb} +8 -8
  73. data/spec/support/{dummy_data.rb → dairy_data.rb} +0 -0
  74. data/spec/support/star_wars_data.rb +71 -0
  75. data/spec/support/star_wars_schema.rb +87 -0
  76. metadata +59 -50
  77. data/lib/graph_ql/definition_helpers/forwardable.rb +0 -10
  78. data/lib/graph_ql/parser/parser.rb +0 -108
  79. data/lib/graph_ql/parser/transform.rb +0 -87
  80. data/lib/graph_ql/scalars/scalar_type.rb +0 -5
  81. data/lib/graph_ql/types/enum.rb +0 -32
  82. data/lib/graph_ql/types/input_object_type.rb +0 -14
  83. data/lib/graph_ql/types/interface.rb +0 -14
  84. data/lib/graph_ql/types/object_type.rb +0 -66
@@ -13,6 +13,13 @@ class GraphQL::Schema::TypeReducer
13
13
  end
14
14
  end
15
15
 
16
+ # Reduce all of `types` and return the combined result
17
+ def self.find_all(types)
18
+ types.reduce({}) do |memo, type|
19
+ self.new(type, memo).result
20
+ end
21
+ end
22
+
16
23
  private
17
24
 
18
25
  def find_types(type, type_hash)
@@ -5,6 +5,7 @@ class GraphQL::StaticValidation::ArgumentsValidator
5
5
  def validate(context)
6
6
  visitor = context.visitor
7
7
  visitor[GraphQL::Nodes::Field] << -> (node, parent) {
8
+ return if context.skip_field?(node.name)
8
9
  field_defn = context.field_definition
9
10
  validate_node(node, field_defn, context)
10
11
  }
@@ -8,12 +8,15 @@ class GraphQL::StaticValidation::Message
8
8
  GraphQL::StaticValidation::Message.new(message, line: node.line, col: node.col)
9
9
  end
10
10
  end
11
- attr_reader :message, :line, :co
11
+ attr_reader :message, :line, :col
12
+
12
13
  def initialize(message, line: nil, col: nil)
13
14
  @message = message
14
15
  @line = line
15
16
  @col = col
16
17
  end
18
+
19
+ # A hash representation of this Message
17
20
  def to_h
18
21
  {
19
22
  "message" => message,
@@ -6,6 +6,7 @@ class GraphQL::StaticValidation::FieldsAreDefinedOnType
6
6
  def validate(context)
7
7
  visitor = context.visitor
8
8
  visitor[GraphQL::Nodes::Field] << -> (node, parent) {
9
+ return if context.skip_field?(node.name)
9
10
  parent_type = context.object_types[-2]
10
11
  parent_type = parent_type.kind.unwrap(parent_type)
11
12
  validate_field(context.errors, node, parent_type, parent)
@@ -5,6 +5,7 @@ class GraphQL::StaticValidation::FieldsHaveAppropriateSelections
5
5
 
6
6
  def validate(context)
7
7
  context.visitor[GraphQL::Nodes::Field] << -> (node, parent) {
8
+ return if context.skip_field?(node.name)
8
9
  field_defn = context.field_definition
9
10
  validate_field_selections(node, field_defn, context.errors)
10
11
  }
@@ -7,7 +7,25 @@ class GraphQL::StaticValidation::TypeStack
7
7
  GraphQL::Nodes::FragmentDefinition,
8
8
  ]
9
9
 
10
- attr_reader :schema, :object_types, :field_definitions, :directive_definitions
10
+ # @return [GraphQL::Schema] the schema whose types are present in this document
11
+ attr_reader :schema
12
+
13
+ # When it enters an object (starting with query or mutation root), it's pushed on this stack.
14
+ # When it exits, it's popped off.
15
+ # @return [Array<GraphQL::ObjectType, GraphQL::Union, GraphQL::Interface>]
16
+ attr_reader :object_types
17
+
18
+ # When it enters a field, it's pushed on this stack (useful for nested fields, args).
19
+ # When it exits, it's popped off.
20
+ # @return [Array<GraphQL::Field>] fields which have been entered
21
+ attr_reader :field_definitions
22
+
23
+ # Directives are pushed on, then popped off while traversing the tree
24
+ # @return [Array<GraphQL::Node::Directive>] directives which have been entered
25
+ attr_reader :directive_definitions
26
+
27
+ # @param schema [GraphQL::Schema] the schema whose types to use when climbing this document
28
+ # @param visitor [GraphQL::Visitor] a visitor to follow & watch the types
11
29
  def initialize(schema, visitor)
12
30
  @schema = schema
13
31
  @object_types = []
@@ -61,7 +79,7 @@ class GraphQL::StaticValidation::TypeStack
61
79
  parent_type = stack.object_types.last
62
80
  parent_type = parent_type.kind.unwrap(parent_type)
63
81
  if parent_type.kind.fields?
64
- field_class = parent_type.fields[node.name]
82
+ field_class = stack.schema.get_field(parent_type, node.name)
65
83
  stack.field_definitions.push(field_class)
66
84
  if !field_class.nil?
67
85
  next_object_type = field_class.type
@@ -92,8 +110,10 @@ class GraphQL::StaticValidation::TypeStack
92
110
  end
93
111
  end
94
112
 
113
+ # A no-op strategy (don't handle this node)
95
114
  class NullStrategy
96
- def push(stack, node); end
97
- def pop(stack, node); end
115
+ def self.new; self; end
116
+ def self.push(stack, node); end
117
+ def self.pop(stack, node); end
98
118
  end
99
119
  end
@@ -1,12 +1,23 @@
1
1
  # Initialized with a {GraphQL::Schema}, then it can validate {GraphQL::Nodes::Documents}s based on that schema.
2
2
  #
3
3
  # By default, it's used by {GraphQL::Query}
4
+ #
5
+ # @example Validate a query
6
+ # validator = GraphQL::StaticValidation::Validator.new(schema: MySchema)
7
+ # document = GraphQL.parse(query_string)
8
+ # errors = validator.validate(document)
9
+ #
4
10
  class GraphQL::StaticValidation::Validator
11
+ # @param schema [GraphQL::Schema]
12
+ # @param rule [Array<#validate(context)>] a list of rules to use when validating
5
13
  def initialize(schema:, rules: GraphQL::StaticValidation::ALL_RULES)
6
14
  @schema = schema
7
15
  @rules = rules
8
16
  end
9
17
 
18
+ # Validate `document` against the schema. Returns an array of message hashes.
19
+ # @param document [GraphQL::Nodes::Document]
20
+ # @return [Array<Hash>]
10
21
  def validate(document)
11
22
  context = Context.new(@schema, document)
12
23
  @rules.each do |rules|
@@ -16,6 +27,16 @@ class GraphQL::StaticValidation::Validator
16
27
  context.errors.map(&:to_h)
17
28
  end
18
29
 
30
+ # The validation context gets passed to each validator.
31
+ #
32
+ # It exposes a {GraphQL::Visitor} where validators may add hooks. ({Visitor#visit} is called in {Validator#validate})
33
+ #
34
+ # It provides access to the schema & fragments which validators may read from.
35
+ #
36
+ # It holds a list of errors which each validator may add to.
37
+ #
38
+ # It also provides limited access to the {TypeStack} instance,
39
+ # which tracks state as you climb in and out of different fields.
19
40
  class Context
20
41
  attr_reader :schema, :document, :errors, :visitor, :fragments
21
42
  def initialize(schema, document)
@@ -40,5 +61,11 @@ class GraphQL::StaticValidation::Validator
40
61
  def directive_definition
41
62
  @type_stack.directive_definitions.last
42
63
  end
64
+
65
+ # Don't try to validate dynamic fields
66
+ # since they aren't defined by the type system
67
+ def skip_field?(field_name)
68
+ GraphQL::Schema::DYNAMIC_FIELDS.include?(field_name)
69
+ end
43
70
  end
44
71
  end
@@ -0,0 +1,87 @@
1
+ module GraphQL
2
+ # {Transform} is a [parslet](http://kschiess.github.io/parslet/) transform for for turning the AST into objects in {GraphQL::Nodes} objects.
3
+ class Transform < Parslet::Transform
4
+ def self.optional_sequence(name)
5
+ rule(name => simple(:val)) { [] }
6
+ rule(name => sequence(:val)) { val }
7
+ end
8
+
9
+ # Document
10
+ rule(document_parts: sequence(:p)) { Nodes::Document.new(parts: p, line: p.first.line, col: p.first.col)}
11
+
12
+ # Fragment Definition
13
+ rule(
14
+ fragment_keyword: simple(:kw),
15
+ fragment_name: simple(:name),
16
+ type_condition: simple(:type),
17
+ directives: sequence(:directives),
18
+ selections: sequence(:selections)
19
+ ) { Nodes::FragmentDefinition.new(name: name.to_s, type: type.to_s, directives: directives, selections: selections, position_source: kw)}
20
+
21
+ rule(
22
+ fragment_spread_keyword: simple(:kw),
23
+ fragment_spread_name: simple(:n),
24
+ directives: sequence(:d)
25
+ ) { Nodes::FragmentSpread.new(name: n.to_s, directives: d, position_source: kw)}
26
+
27
+ rule(
28
+ fragment_spread_keyword: simple(:kw),
29
+ inline_fragment_type: simple(:n),
30
+ directives: sequence(:d),
31
+ selections: sequence(:s),
32
+ ) { Nodes::InlineFragment.new(type: n.to_s, directives: d, selections: s, position_source: kw)}
33
+
34
+ # Operation Definition
35
+ rule(
36
+ operation_type: simple(:ot),
37
+ name: simple(:n),
38
+ variables: sequence(:v),
39
+ directives: sequence(:d),
40
+ selections: sequence(:s),
41
+ ) { Nodes::OperationDefinition.new(operation_type: ot.to_s, name: n.to_s, variables: v, directives: d, selections: s, position_source: ot) }
42
+ optional_sequence(:optional_variables)
43
+ rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: simple(:v)) { Nodes::Variable.new(name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
44
+ rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: sequence(:v)) { Nodes::Variable.new(name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
45
+ rule(variable_default_value: simple(:v) ) { v }
46
+ rule(variable_default_value: sequence(:v) ) { v }
47
+ # Query short-hand
48
+ rule(unnamed_selections: sequence(:s)) { Nodes::OperationDefinition.new(selections: s, operation_type: "query", name: nil, variables: [], directives: [], line: s.first.line, col: s.first.col)}
49
+
50
+ # Field
51
+ rule(
52
+ alias: simple(:a),
53
+ field_name: simple(:name),
54
+ field_arguments: sequence(:args),
55
+ directives: sequence(:dir),
56
+ selections: sequence(:sel)
57
+ ) { Nodes::Field.new(alias: a && a.to_s, name: name.to_s, arguments: args, directives: dir, selections: sel, position_source: [a, name].find { |part| !part.nil? }) }
58
+
59
+ rule(alias_name: simple(:a)) { a }
60
+ optional_sequence(:optional_field_arguments)
61
+ rule(field_argument_name: simple(:n), field_argument_value: simple(:v)) { Nodes::Argument.new(name: n.to_s, value: v, position_source: n)}
62
+ optional_sequence(:optional_selections)
63
+ optional_sequence(:optional_directives)
64
+
65
+ # Directive
66
+ rule(directive_name: simple(:name), directive_arguments: sequence(:args)) { Nodes::Directive.new(name: name.to_s, arguments: args, position_source: name ) }
67
+ rule(directive_argument_name: simple(:n), directive_argument_value: simple(:v)) { Nodes::Argument.new(name: n.to_s, value: v, position_source: n)}
68
+ optional_sequence(:optional_directive_arguments)
69
+
70
+ # Type Defs
71
+ rule(type_name: simple(:n)) { Nodes::TypeName.new(name: n.to_s, position_source: n) }
72
+ rule(list_type: simple(:t)) { Nodes::ListType.new(of_type: t, line: t.line, col: t.col)}
73
+ rule(non_null_type: simple(:t)) { Nodes::NonNullType.new(of_type: t, line: t.line, col: t.col)}
74
+
75
+ # Values
76
+ rule(array: sequence(:v)) { v }
77
+ rule(boolean: simple(:v)) { v == "true" ? true : false }
78
+ rule(input_object: sequence(:v)) { Nodes::InputObject.new(pairs: v, line: v.first.line, col: v.first.col) }
79
+ rule(input_object_name: simple(:n), input_object_value: simple(:v)) { Nodes::Argument.new(name: n.to_s, value: v, position_source: n)}
80
+ rule(int: simple(:v)) { v.to_i }
81
+ rule(float: simple(:v)) { v.to_f }
82
+ rule(string: simple(:v)) { v.to_s }
83
+ rule(variable: simple(:v)) { Nodes::VariableIdentifier.new(name: v.to_s, position_source: v) }
84
+ rule(enum: simple(:v)) { Nodes::Enum.new(name: v.to_s, position_source: v)}
85
+ end
86
+ TRANSFORM = GraphQL::Transform.new
87
+ end
@@ -1,4 +1,6 @@
1
+ # Type kinds are the basic categories which a type may belong to (`Object`, `Scalar`, `Union`...)
1
2
  module GraphQL::TypeKinds
3
+ # These objects are singletons, eg `GraphQL::TypeKinds::UNION`, `GraphQL::TypeKinds::SCALAR`.
2
4
  class TypeKind
3
5
  attr_reader :name
4
6
  def initialize(name, resolves: false, fields: false, wraps: false, input: false)
@@ -10,13 +12,19 @@ module GraphQL::TypeKinds
10
12
  @composite = fields? || resolves?
11
13
  end
12
14
 
15
+ # Does this TypeKind have multiple possible implementors?
13
16
  def resolves?; @resolves; end
17
+ # Does this TypeKind have queryable fields?
14
18
  def fields?; @fields; end
19
+ # Does this TypeKind modify another type?
15
20
  def wraps?; @wraps; end
21
+ # Is this TypeKind a valid query input?
16
22
  def input?; @input; end
17
23
  def to_s; @name; end
24
+ # Is this TypeKind composed of many values?
18
25
  def composite?; @composite; end
19
26
 
27
+ # Get the implementing type for `value` from `type` (no-op for TypeKinds which don't `resolves?`)
20
28
  def resolve(type, value)
21
29
  if resolves?
22
30
  type.resolve_type(value)
@@ -25,6 +33,7 @@ module GraphQL::TypeKinds
25
33
  end
26
34
  end
27
35
 
36
+ # Get the modified type for `type` (no-op for TypeKinds which don't `wraps?`)
28
37
  def unwrap(type)
29
38
  if wraps?
30
39
  wrapped_type = type.of_type
@@ -1,5 +1,10 @@
1
- class GraphQL::Union
2
- include GraphQL::NonNullWithBang
1
+ # A collection of {ObjectType}s
2
+ #
3
+ # @example a union of types
4
+ # PetUnion = GraphQL::UnionType.new("Pet", "House pets", [DogType, CatType])
5
+ #
6
+ class GraphQL::UnionType
7
+ include GraphQL::DefinitionHelpers::NonNullWithBang
3
8
  attr_reader :name, :description, :possible_types
4
9
  def initialize(name, desc, types)
5
10
  @name = name
@@ -11,8 +16,7 @@ class GraphQL::Union
11
16
  GraphQL::TypeKinds::UNION
12
17
  end
13
18
 
14
- # Find a type in this union for a given object.
15
- # Reimplement if needed
19
+ # @see {InterfaceType#resolve_type}
16
20
  def resolve_type(object)
17
21
  type_name = object.class.name
18
22
  possible_types.find {|t| t.name == type_name}
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,28 +1,44 @@
1
1
  # Depth-first traversal through the tree, calling hooks at each stop.
2
2
  #
3
- # @example: Create a visitor, add hooks, then search a document
3
+ # @example Create a visitor, add hooks, then search a document
4
4
  # total_field_count = 0
5
5
  # visitor = GraphQL::Visitor.new
6
+ # # Whenever you find a field, increment the field count:
6
7
  # visitor[GraphQL::Nodes::Field] << -> (node) { total_field_count += 1 }
8
+ # # When we finish, print the field count:
7
9
  # visitor[GraphQL::Nodes::Document].leave << -> (node) { p total_field_count }
8
10
  # visitor.visit(document)
9
11
  # # => 6
10
12
  #
11
13
  class GraphQL::Visitor
14
+ # If any hook returns this value, the {Visitor} stops visiting this
15
+ # node right away
12
16
  SKIP = :_skip
13
17
 
14
- attr_reader :enter, :leave
18
+ # @return [Array<Proc>] Hooks to call when entering _any_ node
19
+ attr_reader :enter
20
+ # @return [Array<Proc>] Hooks to call when leaving _any_ node
21
+ attr_reader :leave
22
+
15
23
  def initialize
16
24
  @visitors = {}
17
25
  @enter = []
18
26
  @leave = []
19
27
  end
20
28
 
29
+ # Get a {NodeVisitor} for `node_class`
30
+ # @param node_class [Class] The node class that you want to listen to
31
+ # @return [NodeVisitor]
32
+ #
33
+ # @example Run a hook whenever you enter a new Field
34
+ # visitor[GraphQL::Nodes::Field] << -> (node, parent) { p "Here's a field" }
21
35
  def [](node_class)
22
36
  @visitors[node_class] ||= NodeVisitor.new
23
37
  end
24
38
 
25
- # Apply built-up vistors to `document`
39
+ # Visit `root` and all children, applying hooks as you go
40
+ # @param root [GraphQL::Nodes::AbstractNode] some node to start parsing on
41
+ # @return [void]
26
42
  def visit(root, parent=nil)
27
43
  begin_visit(root, parent) &&
28
44
  root.children.reduce(true) { |memo, child| memo && visit(child, root) }
@@ -49,13 +65,22 @@ class GraphQL::Visitor
49
65
  hooks.reduce(true) { |memo, proc| memo && (proc.call(node, parent) != SKIP) }
50
66
  end
51
67
 
68
+ # Collect `enter` and `leave` hooks for classes in {GraphQL::Nodes}
69
+ #
70
+ # Access {NodeVisitor}s via {GraphQL::Visitor#[]}
52
71
  class NodeVisitor
53
- attr_reader :enter, :leave
72
+ # @return [Array<Proc>] Hooks to call when entering a node of this type
73
+ attr_reader :enter
74
+ # @return [Array<Proc>] Hooks to call when leaving a node of this type
75
+ attr_reader :leave
76
+
54
77
  def initialize
55
78
  @enter = []
56
79
  @leave = []
57
80
  end
58
81
 
82
+ # Shorthand to add a hook to the {#enter} array
83
+ # @param hook [Proc] A hook to add
59
84
  def <<(hook)
60
85
  enter << hook
61
86
  end
data/lib/graphql.rb CHANGED
@@ -3,6 +3,10 @@ require "parslet"
3
3
  require "singleton"
4
4
 
5
5
  module GraphQL
6
+ # Turn a query string into an AST
7
+ # @param string [String] a GraphQL query string
8
+ # @param as [Symbol] If you want to use this to parse some _piece_ of a document, pass the rule name (from {GraphQL::Parser::Parser})
9
+ # @return [GraphQL::Nodes::Document]
6
10
  def self.parse(string, as: nil)
7
11
  parser = as ? GraphQL::PARSER.send(as) : GraphQL::PARSER
8
12
  tree = parser.parse(string)
@@ -12,26 +16,33 @@ module GraphQL
12
16
  raise [line, col, string].join(", ")
13
17
  end
14
18
 
19
+ # Types & Fields that support GraphQL introspection queries
15
20
  module Introspection; end
16
21
  end
17
22
 
18
- def require_dir(dir)
19
- Dir.glob(File.expand_path("../graph_ql/#{dir}/*.rb", __FILE__)).each do |file|
20
- require file
21
- end
22
- end
23
23
  # Order matters for these:
24
24
 
25
- require_dir('definition_helpers')
26
- require 'graph_ql/types/object_type'
27
- require_dir('types')
25
+ require 'graph_ql/definition_helpers'
26
+ require 'graph_ql/object_type'
27
+
28
+ require 'graph_ql/enum_type'
29
+ require 'graph_ql/input_object_type'
30
+ require 'graph_ql/interface_type'
31
+ require 'graph_ql/list_type'
32
+ require 'graph_ql/non_null_type'
33
+ require 'graph_ql/union_type'
28
34
 
35
+ require 'graph_ql/argument'
29
36
  require 'graph_ql/field'
30
37
  require 'graph_ql/type_kinds'
31
38
  require 'graph_ql/introspection/typename_field'
32
39
 
33
- require 'graph_ql/scalars/scalar_type'
34
- require_dir('scalars')
40
+ require 'graph_ql/scalar_type'
41
+ require 'graph_ql/boolean_type'
42
+ require 'graph_ql/float_type'
43
+ require 'graph_ql/id_type'
44
+ require 'graph_ql/int_type'
45
+ require 'graph_ql/string_type'
35
46
 
36
47
  require 'graph_ql/introspection/input_value_type'
37
48
  require 'graph_ql/introspection/enum_value_type'
@@ -45,13 +56,19 @@ require 'graph_ql/introspection/enum_values_field'
45
56
  require 'graph_ql/introspection/interfaces_field'
46
57
 
47
58
  require 'graph_ql/introspection/type_type'
59
+ require 'graph_ql/introspection/arguments_field'
48
60
  require 'graph_ql/introspection/field_type'
49
61
 
50
- require 'graph_ql/introspection/arguments_field'
51
62
  require 'graph_ql/introspection/directive_type'
52
63
  require 'graph_ql/introspection/schema_type'
64
+ require 'graph_ql/introspection/schema_field'
65
+ require 'graph_ql/introspection/type_by_name_field'
66
+ require 'graph_ql/introspection/introspection_query'
53
67
 
68
+ require 'graph_ql/nodes'
54
69
  require 'graph_ql/parser'
70
+ require 'graph_ql/transform'
71
+ require 'graph_ql/visitor'
55
72
  require 'graph_ql/directive'
56
73
  require 'graph_ql/schema'
57
74