graphlyte 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/graphlyte/data.rb +68 -0
- data/lib/graphlyte/document.rb +131 -0
- data/lib/graphlyte/dsl.rb +86 -0
- data/lib/graphlyte/editor.rb +288 -0
- data/lib/graphlyte/editors/annotate_types.rb +75 -0
- data/lib/graphlyte/editors/canonicalize.rb +26 -0
- data/lib/graphlyte/editors/collect_variable_references.rb +36 -0
- data/lib/graphlyte/editors/infer_signature.rb +36 -0
- data/lib/graphlyte/editors/inline_fragments.rb +37 -0
- data/lib/graphlyte/editors/remove_unneeded_spreads.rb +64 -0
- data/lib/graphlyte/editors/select_operation.rb +116 -0
- data/lib/graphlyte/editors/with_variables.rb +106 -0
- data/lib/graphlyte/errors.rb +33 -0
- data/lib/graphlyte/lexer.rb +392 -0
- data/lib/graphlyte/lexing/location.rb +43 -0
- data/lib/graphlyte/lexing/token.rb +31 -0
- data/lib/graphlyte/parser.rb +269 -0
- data/lib/graphlyte/parsing/backtracking_parser.rb +160 -0
- data/lib/graphlyte/refinements/string_refinement.rb +14 -8
- data/lib/graphlyte/refinements/syntax_refinements.rb +62 -0
- data/lib/graphlyte/schema.rb +165 -0
- data/lib/graphlyte/schema_query.rb +82 -65
- data/lib/graphlyte/selection_builder.rb +189 -0
- data/lib/graphlyte/selector.rb +75 -0
- data/lib/graphlyte/serializer.rb +223 -0
- data/lib/graphlyte/syntax.rb +369 -0
- data/lib/graphlyte.rb +24 -42
- metadata +88 -18
- data/lib/graphlyte/arguments/set.rb +0 -88
- data/lib/graphlyte/arguments/value.rb +0 -32
- data/lib/graphlyte/builder.rb +0 -53
- data/lib/graphlyte/directive.rb +0 -21
- data/lib/graphlyte/field.rb +0 -65
- data/lib/graphlyte/fieldset.rb +0 -36
- data/lib/graphlyte/fragment.rb +0 -17
- data/lib/graphlyte/inline_fragment.rb +0 -29
- data/lib/graphlyte/query.rb +0 -148
- data/lib/graphlyte/schema/parser.rb +0 -674
- data/lib/graphlyte/schema/types/base.rb +0 -54
- data/lib/graphlyte/types.rb +0 -9
@@ -0,0 +1,369 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './errors'
|
4
|
+
require_relative './data'
|
5
|
+
require_relative './refinements/syntax_refinements'
|
6
|
+
|
7
|
+
module Graphlyte
|
8
|
+
module Syntax
|
9
|
+
# An operation represents a top-level executable definition of
|
10
|
+
# a query, mutation or a subscription.
|
11
|
+
# See: https://spec.graphql.org/October2021/#sec-Language.Operations
|
12
|
+
class Operation < Graphlyte::Data
|
13
|
+
attr_reader :type
|
14
|
+
attr_accessor :name, :variables, :directives, :selection
|
15
|
+
|
16
|
+
def initialize(type: nil, **args)
|
17
|
+
super(**args)
|
18
|
+
self.type = type if type
|
19
|
+
end
|
20
|
+
|
21
|
+
def executable?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid?
|
26
|
+
!selection.empty? && valid_type?
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_type?
|
30
|
+
%i[query mutation subscription].include?(type)
|
31
|
+
end
|
32
|
+
|
33
|
+
def type=(value)
|
34
|
+
@type = value
|
35
|
+
return if valid_type?
|
36
|
+
|
37
|
+
raise IllegalValue,
|
38
|
+
"Illegal value: #{value.inspect}. Expected query, mutation or subscription"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# An argument to a Field
|
43
|
+
# See: https://spec.graphql.org/October2021/#sec-Language.Arguments
|
44
|
+
class Argument < Graphlyte::Data
|
45
|
+
attr_accessor :name, :value
|
46
|
+
|
47
|
+
def initialize(name = nil, value = nil, **kwargs)
|
48
|
+
super(**kwargs)
|
49
|
+
@name = name if name
|
50
|
+
@value = value if value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Directive = Struct.new(:name, :arguments)
|
55
|
+
|
56
|
+
# Clases that have fragment names may include this module
|
57
|
+
module HasFragmentName
|
58
|
+
def self.included(mod)
|
59
|
+
mod.attr_reader :name
|
60
|
+
end
|
61
|
+
|
62
|
+
def name=(value)
|
63
|
+
raise IllegalValue, 'Not a legal fragment name' if value == 'on'
|
64
|
+
|
65
|
+
@name = value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# A discrete piece of information in the Graph
|
70
|
+
# See: https://spec.graphql.org/October2021/#sec-Language.Fields
|
71
|
+
class Field < Graphlyte::Data
|
72
|
+
attr_accessor :as, :name, :arguments, :directives, :selection
|
73
|
+
# type is special: it is not part of the serialized Query, but
|
74
|
+
# inferred from the schema. See: editors/annotate_types.rb
|
75
|
+
attr_accessor :type
|
76
|
+
|
77
|
+
def initialize(**kwargs)
|
78
|
+
super
|
79
|
+
@arguments ||= []
|
80
|
+
@directives ||= []
|
81
|
+
@selection ||= []
|
82
|
+
end
|
83
|
+
|
84
|
+
def simple?
|
85
|
+
as.nil? && arguments.empty? && directives.empty? && selection.empty?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# A reference to the use of a Fragment
|
90
|
+
# See: https://spec.graphql.org/October2021/#FragmentSpread
|
91
|
+
class FragmentSpread < Graphlyte::Data
|
92
|
+
include HasFragmentName
|
93
|
+
|
94
|
+
attr_accessor :directives
|
95
|
+
|
96
|
+
def simple?
|
97
|
+
false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
InlineFragment = Struct.new(:type_name, :directives, :selection) do
|
102
|
+
def simple?
|
103
|
+
false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# A definition of a re-usable chunk of an operation
|
108
|
+
# See: https://spec.graphql.org/October2021/#sec-Language.Fragments
|
109
|
+
class Fragment < Graphlyte::Data
|
110
|
+
include HasFragmentName
|
111
|
+
|
112
|
+
attr_accessor :type_name, :directives, :selection
|
113
|
+
|
114
|
+
def initialize(**kwargs)
|
115
|
+
super
|
116
|
+
@refers_to = []
|
117
|
+
end
|
118
|
+
|
119
|
+
def inline
|
120
|
+
InlineFragment.new(type_name, directives, selection)
|
121
|
+
end
|
122
|
+
|
123
|
+
def refers_to(fragment)
|
124
|
+
@refers_to << fragment
|
125
|
+
end
|
126
|
+
|
127
|
+
def required_fragments
|
128
|
+
[self] + @refers_to
|
129
|
+
end
|
130
|
+
|
131
|
+
def executable?
|
132
|
+
true
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
Literal = Struct.new(:value, :type, :to_s) # rubocop:disable Lint/StructNewOverride
|
137
|
+
NULL = Literal.new(nil, :NULL, 'null').freeze
|
138
|
+
TRUE = Literal.new(true, :BOOL, 'true').freeze
|
139
|
+
FALSE = Literal.new(false, :BOOL, 'false').freeze
|
140
|
+
|
141
|
+
VariableDefinition = Struct.new(:variable, :type, :default_value, :directives, keyword_init: true)
|
142
|
+
|
143
|
+
# A use of a variable in an operation or fragment
|
144
|
+
# See: https://spec.graphql.org/October2021/#Variable
|
145
|
+
class VariableReference < Graphlyte::Data
|
146
|
+
attr_accessor :variable, :inferred_type
|
147
|
+
|
148
|
+
def initialize(variable = nil, inferred_type = nil, **kwargs)
|
149
|
+
super(**kwargs)
|
150
|
+
@variable ||= variable
|
151
|
+
@inferred_type ||= inferred_type
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_definition
|
155
|
+
VariableDefinition.new(variable: variable, type: inferred_type)
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def state
|
161
|
+
@variable
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# A reference to a type, possibly containing other types.
|
166
|
+
# See: https://spec.graphql.org/October2021/#sec-Type-References
|
167
|
+
class Type < Graphlyte::Data
|
168
|
+
attr_accessor :inner, :is_list, :non_null, :non_null_list
|
169
|
+
|
170
|
+
def initialize(name = nil, **kwargs)
|
171
|
+
super(**kwargs)
|
172
|
+
@inner ||= name
|
173
|
+
@is_list ||= false
|
174
|
+
@non_null ||= false
|
175
|
+
@non_null_list ||= false
|
176
|
+
end
|
177
|
+
|
178
|
+
# Used during value->type inference
|
179
|
+
# always non-null, because we have a value.
|
180
|
+
def self.list_of(inner)
|
181
|
+
t = new(inner)
|
182
|
+
t.is_list = true
|
183
|
+
t.non_null = true
|
184
|
+
t
|
185
|
+
end
|
186
|
+
|
187
|
+
def to_s
|
188
|
+
str = inner.to_s
|
189
|
+
str = "#{str}!" if non_null
|
190
|
+
str = "[#{str}]" if is_list
|
191
|
+
str += '!' if non_null_list
|
192
|
+
|
193
|
+
str
|
194
|
+
end
|
195
|
+
|
196
|
+
def unpack
|
197
|
+
return inner if inner.is_a?(String)
|
198
|
+
|
199
|
+
inner.unpack
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.from_type_ref(type_ref)
|
203
|
+
raise ArgumentError, 'type_ref cannot be nil' if type_ref.nil?
|
204
|
+
|
205
|
+
inner = from_type_ref(type_ref.of_type) if type_ref.of_type
|
206
|
+
|
207
|
+
case type_ref.kind
|
208
|
+
when :NON_NULL
|
209
|
+
non_null(inner)
|
210
|
+
when :LIST
|
211
|
+
list_type(inner)
|
212
|
+
when :SCALAR, :OBJECT, :ENUM
|
213
|
+
raise ArgumentError, "#{type_ref.kind} cannot have inner type" if inner
|
214
|
+
|
215
|
+
new(inner: type_ref.name)
|
216
|
+
else
|
217
|
+
raise ArgumentError, "Unexpected kind: #{type_ref.kind.inspect}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.list_type(inner)
|
222
|
+
raise ArgumentError, 'List types must have inner type' unless inner
|
223
|
+
|
224
|
+
new(is_list: true, inner: inner)
|
225
|
+
end
|
226
|
+
|
227
|
+
def self.non_null(inner)
|
228
|
+
raise ArgumentError, 'Non null types must have inner type' unless inner
|
229
|
+
|
230
|
+
type = new(non_null: true, inner: inner)
|
231
|
+
|
232
|
+
if inner.respond_to?(:is_list) && inner.is_list
|
233
|
+
type.is_list = true
|
234
|
+
type.inner = inner.inner
|
235
|
+
end
|
236
|
+
|
237
|
+
type
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# A CONST input value
|
242
|
+
# See: https://spec.graphql.org/October2021/#sec-Input-Values
|
243
|
+
class Value < Graphlyte::Data
|
244
|
+
using Refinements::SyntaxRefinements
|
245
|
+
|
246
|
+
attr_accessor :value, :type
|
247
|
+
|
248
|
+
def initialize(value = nil, type = nil, **kwargs)
|
249
|
+
super(**kwargs)
|
250
|
+
@value = value if value
|
251
|
+
@type = type if type
|
252
|
+
@type ||= value&.type
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.from_name(name)
|
256
|
+
case name
|
257
|
+
when 'true'
|
258
|
+
true.to_input_value
|
259
|
+
when 'false'
|
260
|
+
false.to_input_value
|
261
|
+
when 'null'
|
262
|
+
nil.to_input_value
|
263
|
+
else
|
264
|
+
name.to_sym.to_input_value
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def inspect
|
269
|
+
"#<#{self.class.name} @type=#{type} @value=#{value.inspect}>"
|
270
|
+
end
|
271
|
+
alias to_s inspect
|
272
|
+
|
273
|
+
def eql?(other)
|
274
|
+
return true if super
|
275
|
+
return true if numeric_eql?(other)
|
276
|
+
|
277
|
+
false
|
278
|
+
end
|
279
|
+
|
280
|
+
def numeric_eql?(other)
|
281
|
+
return false unless number?
|
282
|
+
return false unless other&.number?
|
283
|
+
|
284
|
+
if floating? || other.floating?
|
285
|
+
(value.to_f - other.value.to_f) < Float::EPSILON
|
286
|
+
else
|
287
|
+
value.to_i == other.value.to_i
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def floating?
|
292
|
+
return false unless number?
|
293
|
+
return true if value.is_a?(Float)
|
294
|
+
return true if value.is_a?(NumericLiteral) && value.floating?
|
295
|
+
|
296
|
+
false
|
297
|
+
end
|
298
|
+
|
299
|
+
def number?
|
300
|
+
type == :NUMBER
|
301
|
+
end
|
302
|
+
|
303
|
+
def self.from_ruby(object)
|
304
|
+
object.to_input_value
|
305
|
+
rescue NoMethodError
|
306
|
+
raise IllegalValue, object
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# A representation of a GraphQL literal, preserving the text components
|
311
|
+
#
|
312
|
+
# Note: NumericLiterals are immutable.
|
313
|
+
class NumericLiteral < Graphlyte::Data
|
314
|
+
attr_reader :integer_part, :fractional_part, :exponent_part, :negated
|
315
|
+
|
316
|
+
def initialize(**kwargs)
|
317
|
+
super
|
318
|
+
@negated ||= false
|
319
|
+
|
320
|
+
raise ArgumentError, 'integer_part is required' unless @integer_part
|
321
|
+
|
322
|
+
freeze
|
323
|
+
end
|
324
|
+
|
325
|
+
def floating?
|
326
|
+
!!@fractional_part || !!@exponent_part
|
327
|
+
end
|
328
|
+
|
329
|
+
def to_s
|
330
|
+
s = "#{negated ? '-' : ''}#{integer_part}"
|
331
|
+
return s unless floating?
|
332
|
+
|
333
|
+
s << ".#{fractional_part}" if fractional_part
|
334
|
+
s << "e#{exponent_part.first}#{exponent_part.last}" if @exponent_part
|
335
|
+
|
336
|
+
s
|
337
|
+
end
|
338
|
+
|
339
|
+
def to_i
|
340
|
+
unnegate(negated, integer_part.to_i)
|
341
|
+
end
|
342
|
+
|
343
|
+
def to_f
|
344
|
+
n = to_i.to_f
|
345
|
+
n += fractional_value if fractional_part
|
346
|
+
n *= exponent_value if exponent_part
|
347
|
+
|
348
|
+
n
|
349
|
+
end
|
350
|
+
|
351
|
+
private
|
352
|
+
|
353
|
+
attr_writer :integer_part, :fractional_part, :exponent_part, :negated
|
354
|
+
|
355
|
+
def exponent_value
|
356
|
+
10**unnegate(exponent_part.first, exponent_part.last.to_i)
|
357
|
+
end
|
358
|
+
|
359
|
+
def fractional_value
|
360
|
+
fp = unnegate(negated, fractional_part.to_i.to_f)
|
361
|
+
fp / (10**fractional_part.length)
|
362
|
+
end
|
363
|
+
|
364
|
+
def unnegate(negated, value)
|
365
|
+
value * (negated ? -1 : 1)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
data/lib/graphlyte.rb
CHANGED
@@ -1,54 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
1
4
|
require 'json'
|
2
|
-
require_relative "./graphlyte/fieldset"
|
3
|
-
require_relative "./graphlyte/query"
|
4
|
-
require_relative "./graphlyte/fragment"
|
5
|
-
require_relative 'graphlyte/inline_fragment'
|
6
|
-
require_relative "./graphlyte/schema_query"
|
7
|
-
require_relative "./graphlyte/types"
|
8
|
-
require_relative "./graphlyte/schema/parser"
|
9
5
|
|
6
|
+
require_relative './graphlyte/syntax'
|
7
|
+
require_relative './graphlyte/schema'
|
8
|
+
require_relative './graphlyte/lexer'
|
9
|
+
require_relative './graphlyte/parser'
|
10
|
+
require_relative './graphlyte/editor'
|
11
|
+
require_relative './graphlyte/serializer'
|
12
|
+
require_relative './graphlyte/selector'
|
13
|
+
require_relative './graphlyte/selection_builder'
|
14
|
+
require_relative './graphlyte/dsl'
|
15
|
+
require_relative './graphlyte/schema_query'
|
16
|
+
|
17
|
+
# A GraphQL parsing, introspection, construction and manipulation library
|
10
18
|
module Graphlyte
|
11
19
|
extend SchemaQuery
|
20
|
+
extend SingleForwardable
|
12
21
|
|
13
|
-
|
14
|
-
|
15
|
-
def self.parse(gql)
|
16
|
-
Graphlyte::Schema::Parser.parse(gql)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.query(name = nil, &block)
|
20
|
-
Query.new(name, :query, builder: build(&block))
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.mutation(name = nil, &block)
|
24
|
-
Query.new(name, :mutation, builder: build(&block))
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.custom(name, type, &block)
|
28
|
-
Query.new(name, type.to_sym, builder: build(&block))
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.inline_fragment(model_name, &block)
|
32
|
-
InlineFragment.new(model_name, builder: build(&block))
|
33
|
-
end
|
22
|
+
NO_SCHEMA_DSL = Graphlyte::DSL.new
|
34
23
|
|
35
|
-
|
36
|
-
InlineFragment.from_directive(directive, **hargs, builder: build(&block) )
|
37
|
-
end
|
24
|
+
def_delegators 'Graphlyte::NO_SCHEMA_DSL', :query, :mutation, :var, :fragment
|
38
25
|
|
39
|
-
def self.
|
40
|
-
|
41
|
-
|
26
|
+
def self.parse(gql)
|
27
|
+
ts = Graphlyte::Lexer.lex(gql)
|
28
|
+
parser = Graphlyte::Parser.new(tokens: ts)
|
42
29
|
|
43
|
-
|
44
|
-
Fieldset.new(model_name, builder: build(&block))
|
30
|
+
parser.query
|
45
31
|
end
|
46
32
|
|
47
|
-
|
48
|
-
|
49
|
-
def self.build(&block)
|
50
|
-
builder = Builder.new
|
51
|
-
builder.>.instance_eval(&block)
|
52
|
-
builder
|
33
|
+
def self.dsl(schema)
|
34
|
+
DSL.new(schema)
|
53
35
|
end
|
54
36
|
end
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphlyte
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Gregory
|
8
|
+
- Alex Kalderimis
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2022-
|
12
|
+
date: 2022-07-19 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: pry-byebug
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
18
|
- - ">="
|
@@ -38,32 +39,101 @@ dependencies:
|
|
38
39
|
- - ">="
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: simplecov
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: simplecov-cobertura
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: super_diff
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
41
98
|
description: craft graphql queries with ruby
|
42
|
-
email:
|
99
|
+
email: alex.kalderimis@gmail.com
|
43
100
|
executables: []
|
44
101
|
extensions: []
|
45
102
|
extra_rdoc_files: []
|
46
103
|
files:
|
47
104
|
- lib/graphlyte.rb
|
48
|
-
- lib/graphlyte/
|
49
|
-
- lib/graphlyte/
|
50
|
-
- lib/graphlyte/
|
51
|
-
- lib/graphlyte/
|
52
|
-
- lib/graphlyte/
|
53
|
-
- lib/graphlyte/
|
54
|
-
- lib/graphlyte/
|
55
|
-
- lib/graphlyte/
|
56
|
-
- lib/graphlyte/
|
105
|
+
- lib/graphlyte/data.rb
|
106
|
+
- lib/graphlyte/document.rb
|
107
|
+
- lib/graphlyte/dsl.rb
|
108
|
+
- lib/graphlyte/editor.rb
|
109
|
+
- lib/graphlyte/editors/annotate_types.rb
|
110
|
+
- lib/graphlyte/editors/canonicalize.rb
|
111
|
+
- lib/graphlyte/editors/collect_variable_references.rb
|
112
|
+
- lib/graphlyte/editors/infer_signature.rb
|
113
|
+
- lib/graphlyte/editors/inline_fragments.rb
|
114
|
+
- lib/graphlyte/editors/remove_unneeded_spreads.rb
|
115
|
+
- lib/graphlyte/editors/select_operation.rb
|
116
|
+
- lib/graphlyte/editors/with_variables.rb
|
117
|
+
- lib/graphlyte/errors.rb
|
118
|
+
- lib/graphlyte/lexer.rb
|
119
|
+
- lib/graphlyte/lexing/location.rb
|
120
|
+
- lib/graphlyte/lexing/token.rb
|
121
|
+
- lib/graphlyte/parser.rb
|
122
|
+
- lib/graphlyte/parsing/backtracking_parser.rb
|
57
123
|
- lib/graphlyte/refinements/string_refinement.rb
|
58
|
-
- lib/graphlyte/
|
59
|
-
- lib/graphlyte/schema
|
124
|
+
- lib/graphlyte/refinements/syntax_refinements.rb
|
125
|
+
- lib/graphlyte/schema.rb
|
60
126
|
- lib/graphlyte/schema_query.rb
|
61
|
-
- lib/graphlyte/
|
127
|
+
- lib/graphlyte/selection_builder.rb
|
128
|
+
- lib/graphlyte/selector.rb
|
129
|
+
- lib/graphlyte/serializer.rb
|
130
|
+
- lib/graphlyte/syntax.rb
|
62
131
|
homepage: https://rubygems.org/gems/graphlyte
|
63
132
|
licenses:
|
64
133
|
- MIT
|
65
134
|
metadata:
|
66
|
-
source_code_uri: https://gitlab.com/
|
135
|
+
source_code_uri: https://gitlab.com/skinnyjames/graphlyte
|
136
|
+
rubygems_mfa_required: 'true'
|
67
137
|
post_install_message:
|
68
138
|
rdoc_options: []
|
69
139
|
require_paths:
|
@@ -72,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
142
|
requirements:
|
73
143
|
- - ">="
|
74
144
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
145
|
+
version: 2.7.0
|
76
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
147
|
requirements:
|
78
148
|
- - ">="
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require_relative "./value"
|
2
|
-
require_relative "./../refinements/string_refinement"
|
3
|
-
module Graphlyte
|
4
|
-
module Arguments
|
5
|
-
class Set
|
6
|
-
using Refinements::StringRefinement
|
7
|
-
|
8
|
-
attr_reader :values
|
9
|
-
|
10
|
-
def initialize(data)
|
11
|
-
raise ArgumentError, "input #{data} must be a hash" unless data.nil? || data.is_a?(Hash)
|
12
|
-
@values = expand_arguments(data) unless data.nil?
|
13
|
-
end
|
14
|
-
|
15
|
-
def extract_variables(values=@values, variables=[])
|
16
|
-
values&.each do |key, value|
|
17
|
-
if value.is_a?(Set)
|
18
|
-
variables.concat extract_variables(value.values)
|
19
|
-
elsif value.is_a?(Array)
|
20
|
-
elsif value.symbol?
|
21
|
-
variables << value
|
22
|
-
elsif value.formal?
|
23
|
-
variables << value
|
24
|
-
end
|
25
|
-
end
|
26
|
-
variables
|
27
|
-
end
|
28
|
-
|
29
|
-
def to_h(raw = false)
|
30
|
-
return {} unless values && !values.empty?
|
31
|
-
values.inject({}) do |memo, (k, v)|
|
32
|
-
if v.is_a?(Array)
|
33
|
-
memo[k.to_s.to_camel_case] = v.map { |value| value.to_s(raw) }
|
34
|
-
elsif v.is_a?(Set)
|
35
|
-
memo[k.to_s.to_camel_case] = v.to_h
|
36
|
-
else
|
37
|
-
memo[k.to_s.to_camel_case] = v.to_s(raw)
|
38
|
-
end
|
39
|
-
memo
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def to_s(inner = false)
|
44
|
-
return "" unless values && !values.empty?
|
45
|
-
arr = stringify_arguments
|
46
|
-
return arr.join(", ") if inner
|
47
|
-
"(#{arr.join(", ")})"
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def stringify_arguments
|
53
|
-
values.map do |k,v|
|
54
|
-
if v.is_a?(Array)
|
55
|
-
"#{k.to_s.to_camel_case}: [#{v.map(&:to_s).join(", ")}]"
|
56
|
-
elsif v.is_a?(Set)
|
57
|
-
"#{k.to_s.to_camel_case}: { #{v.to_s(true)} }"
|
58
|
-
else
|
59
|
-
"#{k.to_s.to_camel_case}: #{v.to_s}"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def expand_arguments(data)
|
65
|
-
data.inject({}) do |memo, (k, v)|
|
66
|
-
if v.is_a?(Array)
|
67
|
-
memo[k] = v.map do |item|
|
68
|
-
if item.is_a?(Value)
|
69
|
-
item
|
70
|
-
else
|
71
|
-
Value.new(item)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
elsif v.is_a?(Hash)
|
75
|
-
memo[k] = Set.new(v)
|
76
|
-
else
|
77
|
-
if v.is_a?(Value)
|
78
|
-
memo[k] = v
|
79
|
-
else
|
80
|
-
memo[k] = Value.new(v)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
memo
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require_relative "./../refinements/string_refinement"
|
2
|
-
module Graphlyte
|
3
|
-
module Arguments
|
4
|
-
class Value
|
5
|
-
using Refinements::StringRefinement
|
6
|
-
|
7
|
-
attr_reader :value
|
8
|
-
|
9
|
-
def initialize(value)
|
10
|
-
raise ArgumentError, "Hash not allowed in this context" if value.is_a? Hash
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
def symbol?
|
15
|
-
value.is_a? Symbol
|
16
|
-
end
|
17
|
-
|
18
|
-
def formal?
|
19
|
-
value.is_a? Schema::Types::Base
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s(raw = false)
|
23
|
-
return "$#{value.to_s.to_camel_case}" if value.is_a? Symbol
|
24
|
-
return value if value.is_a? Numeric
|
25
|
-
return "\"#{value}\"" if value.is_a?(String) && !raw
|
26
|
-
return "null" if value.nil?
|
27
|
-
return "$#{value.placeholder.to_camel_case}" if value.is_a? Schema::Types::Base
|
28
|
-
value.to_s
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|