graphlyte 0.1.6 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6daff225ff526c8866c59601de914bbf7cac87c0393d5a3918a16f78c249eaa7
4
- data.tar.gz: 104deccd41d6dc5fd2be8a263f8549e5190f088717737fed61b9ae9da78aca6d
3
+ metadata.gz: 4993b6b7dba33932ac40eff10ac57644a120ee41d23df9408d70ea3c5fe12aec
4
+ data.tar.gz: f7fba13051b20ad335936347753ec3507b113852bcbdd4c5ad62ac3b127496ec
5
5
  SHA512:
6
- metadata.gz: 539c3dfd3b611f79341f32b8eb61db2c76d0c92fd3e2e3d7312dd6d1946ec51463ac7f7f8db09e663a8681e9afc065f5cf0b7a5788d5129ca6e08d5b4870ce28
7
- data.tar.gz: 642ca3c211d11e1b6613a6910ed618685d9a87ae3057438f7f5ab3ccc63dba26041691a4a81309b77e41b682b86ad4aefe6789631fd3b0ddccb11b882d959947
6
+ metadata.gz: 3bab812cb94fd2abeb816180683297c4c95f1486368a5f3029a9917fcf4dcf505d8b6c82777ef4574f550fdc8cd6f0878a92bebcbeb09702b3d832f664e4a0fa
7
+ data.tar.gz: cbbfbbff19e0f789d09b01e8581ded8892601b85710b9c9a84ffcc9e393c1ef69aa27c094deb2a81a23078614982519d6ee0f8047ff63d3f1991fddab764a39f
@@ -16,6 +16,7 @@ module Graphlyte
16
16
  values&.each do |key, value|
17
17
  if value.is_a?(Set)
18
18
  variables.concat extract_variables(value.values)
19
+ elsif value.is_a?(Array)
19
20
  elsif value.symbol?
20
21
  variables << value
21
22
  elsif value.formal?
@@ -41,7 +42,15 @@ module Graphlyte
41
42
 
42
43
  def to_s(inner = false)
43
44
  return "" unless values && !values.empty?
44
- arr = values.map do |k,v|
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|
45
54
  if v.is_a?(Array)
46
55
  "#{k.to_s.to_camel_case}: [#{v.map(&:to_s).join(", ")}]"
47
56
  elsif v.is_a?(Set)
@@ -50,22 +59,26 @@ module Graphlyte
50
59
  "#{k.to_s.to_camel_case}: #{v.to_s}"
51
60
  end
52
61
  end
53
- return arr.join(", ") if inner
54
- "(#{arr.join(", ")})"
55
62
  end
56
63
 
57
- private
58
-
59
64
  def expand_arguments(data)
60
65
  data.inject({}) do |memo, (k, v)|
61
66
  if v.is_a?(Array)
62
67
  memo[k] = v.map do |item|
63
- Value.new(item)
68
+ if item.is_a?(Value)
69
+ item
70
+ else
71
+ Value.new(item)
72
+ end
64
73
  end
65
74
  elsif v.is_a?(Hash)
66
75
  memo[k] = Set.new(v)
67
76
  else
68
- memo[k] = Value.new(v)
77
+ if v.is_a?(Value)
78
+ memo[k] = v
79
+ else
80
+ memo[k] = Value.new(v)
81
+ end
69
82
  end
70
83
  memo
71
84
  end
@@ -17,7 +17,7 @@ module Graphlyte
17
17
  end
18
18
 
19
19
  def method_missing(method, fieldset_or_hargs=nil, hargs={}, &block)
20
- # todo: camel case method
20
+ # todo: camel case method
21
21
 
22
22
  # hack for ruby bug in lower versions
23
23
  if [Fieldset, Fragment].include?(fieldset_or_hargs.class)
@@ -31,6 +31,10 @@ module Graphlyte
31
31
  field
32
32
  end
33
33
 
34
+ def respond_to_missing
35
+ true
36
+ end
37
+
34
38
  # for internal use only
35
39
  def >>
36
40
  @fields
@@ -1,29 +1,45 @@
1
1
  require_relative "./refinements/string_refinement"
2
+ require "json"
2
3
  module Graphlyte
3
4
  class Query < Fieldset
4
5
  using Refinements::StringRefinement
5
6
  attr_reader :name, :type
6
7
 
7
8
  def initialize(query_name=nil, type=:query, **hargs)
8
- @name = query_name
9
+ @name = query_name || "anonymousQuery"
9
10
  @type = type
10
11
  super(**hargs)
11
12
  end
12
13
 
13
14
  def placeholders
14
15
  flatten_variables(builder.>>).map do |value|
15
- ":#{value.value.placeholder} of #{value.value.name}"
16
+ unless value.formal?
17
+ str = ":#{value.value.to_sym.inspect} of unknown"
18
+ else
19
+ str = ":#{value.value.placeholder} of #{value.value.name}"
20
+ end
21
+
22
+ if value.value.default
23
+ str += " with default "
24
+ value.value.default.merge!(str)
25
+ end
26
+ str
16
27
  end.join("\n")
17
28
  end
18
29
 
19
- def to_json(name="anonymousQuery", **hargs)
30
+ def to_json(query_name=name, **hargs)
20
31
  variables = flatten_variables(builder.>>).uniq { |v| v.value }
21
32
  types = merge_variable_types(variables, hargs)
22
33
 
23
- str = "#{type} #{name}"
34
+ str = "#{type} #{query_name}"
24
35
  unless types.empty?
25
36
  type_new = types.map do |type_arr|
26
- "$#{type_arr[0].to_camel_case}: #{type_arr[1]}"
37
+ type_str = "$#{type_arr[0].to_camel_case}: #{type_arr[1]}"
38
+ unless type_arr[2].nil?
39
+ type_str << " = "
40
+ type_arr[2].merge!(type_str)
41
+ end
42
+ type_str
27
43
  end
28
44
  str += "(#{type_new.join(", ")})"
29
45
  end
@@ -49,7 +65,7 @@ module Graphlyte
49
65
  memo << "[#{merge_variable_types(var.value, hargs).first}]"
50
66
  end
51
67
  else
52
- memo << [var.value.placeholder, var.value.name]
68
+ memo << [var.value.placeholder, var.value.name, var.value.default]
53
69
  end
54
70
  memo
55
71
  end
@@ -0,0 +1,521 @@
1
+ require "strscan"
2
+ require_relative "../fieldset"
3
+ require_relative "../query"
4
+ require_relative "../fragment"
5
+ require_relative "../schema_query"
6
+ require_relative "../types"
7
+
8
+ module Graphlyte
9
+ module Schema
10
+ module ParserHelpers
11
+ def parse_fields
12
+ fields = repeat(:parse_field)
13
+ fields
14
+ end
15
+
16
+ def parse_field
17
+ alias_field = expect(:ALIAS)
18
+ if token = expect(:FRAGMENT_REF)
19
+ raise "Can't find fragment #{token[0][1]}" unless fragments_dictionary[token[0][1]]
20
+ fragments_dictionary[token[0][1]]
21
+ elsif field = expect(:FIELD_NAME)
22
+ args = parse_args
23
+ if fieldset = parse_fieldset
24
+ need(:END_FIELD)
25
+ field = Field.new(field[0][1], fieldset, args)
26
+ else
27
+ field = Field.new(field[0][1], Fieldset.empty, args)
28
+ end
29
+
30
+ if alias_field
31
+ field.alias(alias_field[0][1])
32
+ end
33
+
34
+ field
35
+ end
36
+ end
37
+
38
+ def parse_fieldset
39
+ if expect(:START_FIELD)
40
+ fields = parse_fields
41
+ Fieldset.new(builder: Builder.new(fields))
42
+ end
43
+ end
44
+
45
+ def parse_args
46
+ if expect(:START_ARGS)
47
+ args = repeat(:parse_arg).inject(&:merge)
48
+ need(:END_ARGS)
49
+ args
50
+ end
51
+ end
52
+
53
+ def parse_default
54
+ if expect(:START_DEFAULT_VALUE)
55
+ value = parse_value
56
+ need(:END_DEFAULT_VALUE)
57
+ value
58
+ end
59
+ end
60
+
61
+ def parse_arg
62
+ if (token = expect(:ARG_KEY)) && (value = parse_value)
63
+ defaults = parse_default
64
+ key = token[0][1]
65
+ hash = {}
66
+ hash[key] = value
67
+ hash
68
+ elsif (token = expect(:SPECIAL_ARG_KEY)) && (value = parse_value)
69
+ defaults = parse_default
70
+ @special_args ||= {}
71
+ arg = {}
72
+ if [Array, Hash].include?(value.class)
73
+ arg[token[0][1]] = value
74
+ else
75
+ new_val = Schema::Types::Base.new(value, token[0][1], defaults)
76
+ arg[token[0][1]] = new_val
77
+ end
78
+ @special_args.merge!(arg)
79
+ arg
80
+ end
81
+ end
82
+
83
+ def parse_value
84
+ if token = expect(:ARG_NUM_VALUE) || expect(:ARG_STRING_VALUE) || expect(:ARG_BOOL_VALUE) || expect(:ARG_FLOAT_VALUE)
85
+ token[0][1]
86
+ elsif token = expect(:SPECIAL_ARG_REF)
87
+ ref = token[0][1]
88
+ raise "Can't find ref $#{ref}" unless @special_args[ref]
89
+ @special_args[ref]
90
+ elsif token = expect(:SPECIAL_ARG_VAL)
91
+ token[0][1]
92
+ elsif token = expect(:ARG_HASH_START)
93
+ parse_arg_hash
94
+ elsif expect(:ARG_ARRAY_START)
95
+ parse_arg_array
96
+ end
97
+ end
98
+
99
+ def parse_arg_array
100
+ args = repeat(:parse_value)
101
+ need(:ARG_ARRAY_END)
102
+ args
103
+ end
104
+
105
+ def parse_arg_hash
106
+ if (key = expect(:ARG_KEY)) && (value = parse_value)
107
+ hash = {}
108
+ hash[key[0][1]] = value
109
+ hash
110
+ if new_hash = parse_arg_hash
111
+ hash.merge!(new_hash)
112
+ else
113
+ need(:ARG_HASH_END)
114
+ hash
115
+ end
116
+ end
117
+ end
118
+
119
+ def repeat(method)
120
+ results = []
121
+
122
+ while result = send(method)
123
+ results << result
124
+ end
125
+
126
+ results
127
+ end
128
+
129
+ def expect(*expected_tokens)
130
+ upcoming = tokens[position, expected_tokens.size]
131
+ if upcoming.map(&:first) == expected_tokens
132
+ advance(expected_tokens.size)
133
+ upcoming
134
+ end
135
+ end
136
+
137
+ def need(*required_tokens)
138
+ upcoming = tokens[position, required_tokens.size]
139
+ expect(*required_tokens) or raise "Unexpected tokens. Expected #{required_tokens.inspect} but got #{upcoming.inspect}"
140
+ end
141
+
142
+ def advance(offset = 1)
143
+ @position += offset
144
+ end
145
+
146
+ def sort_fragments(sorted = [], fragments)
147
+ return sorted if !fragments || fragments.empty?
148
+ fragment_tokens = fragments.shift
149
+
150
+ current_ref = fragment_tokens.find do |token|
151
+ token[0] == :FRAGMENT_REF
152
+ end
153
+
154
+ if current_ref
155
+ exists = sorted.any? do |frags|
156
+ frags.find do |el|
157
+ el[0] == :START_FRAGMENT && el[1] == current_ref[1]
158
+ end
159
+ end
160
+ if exists
161
+ sorted << fragment_tokens
162
+ sort_fragments(sorted, fragments)
163
+ else
164
+ fragments.push fragment_tokens
165
+ sort_fragments(sorted, fragments)
166
+ end
167
+ else
168
+ sorted << fragment_tokens
169
+ sort_fragments(sorted, fragments)
170
+ end
171
+ end
172
+
173
+ def take_fragments
174
+ aggregate = @tokens.inject({taking: false, idx: 0, fragments: []}) do |memo, token_arr|
175
+ if token_arr[0] == :END_FRAGMENT
176
+ memo[:fragments][memo[:idx]] << token_arr
177
+ memo[:taking] = false
178
+ memo[:idx] += 1
179
+ elsif token_arr[0] === :START_FRAGMENT
180
+ memo[:fragments][memo[:idx]] = [token_arr]
181
+ memo[:taking] = true
182
+ elsif memo[:taking]
183
+ memo[:fragments][memo[:idx]] << token_arr
184
+ end
185
+ memo
186
+ end
187
+ aggregate[:fragments]
188
+ end
189
+ end
190
+
191
+ class FragmentParser
192
+ attr_reader :tokens, :position, :fragments_dictionary
193
+
194
+ include ParserHelpers
195
+
196
+ def initialize(tokens)
197
+ @tokens = tokens.flatten(1)
198
+ @position = 0
199
+ @fragments_dictionary = {}
200
+ end
201
+
202
+ def parse_fragments
203
+ repeat(:parse_fragment)
204
+ fragments_dictionary
205
+ end
206
+
207
+ def parse_fragment
208
+ if token = expect(:START_FRAGMENT)
209
+ parse_args
210
+ builder = Builder.new parse_fields
211
+ fragment = Fragment.new(token[0][1], token[0][2], builder: builder)
212
+ @fragments_dictionary[token[0][1]] = fragment
213
+ need(:END_FRAGMENT)
214
+ end
215
+ end
216
+ end
217
+
218
+ class Parser
219
+ attr_reader :tokens, :position, :fragments_dictionary
220
+
221
+ include ParserHelpers
222
+
223
+ def self.parse(gql)
224
+ obj = new Lexer.new(gql).tokenize
225
+ obj.parse
226
+ end
227
+
228
+ def initialize(tokens)
229
+ @tokens = tokens
230
+ @fragment_tokens = sort_fragments([], take_fragments)
231
+ @fragments_dictionary = {}
232
+ @fragments_dictionary = @fragment_tokens.any? ? FragmentParser.new(@fragment_tokens).parse_fragments : {}
233
+ @position = 0
234
+ end
235
+
236
+ def parse
237
+ if token = expect(:START_QUERY)
238
+ parse_query(token[0][1])
239
+ elsif token = expect(:START_MUTATION)
240
+ parse_mutation(token[0][1])
241
+ else
242
+ raise "INVALID"
243
+ end
244
+ end
245
+
246
+ def parse_query(name)
247
+ parse_args
248
+ builder = Builder.new parse_fields
249
+ query = Query.new(name, :query, builder: builder)
250
+ need(:END_QUERY)
251
+ query
252
+ end
253
+
254
+ def parse_mutation(name)
255
+ builder = Builder.new parse_fields
256
+ mutation = Query.new(name, :mutation, builder: builder)
257
+ need(:END_MUTATION)
258
+ mutation
259
+ end
260
+ end
261
+
262
+ class Lexer
263
+ attr_reader :stack, :scanner
264
+
265
+ def initialize(gql, scanner: StringScanner.new(gql))
266
+ @original_string = gql
267
+ @scanner = scanner
268
+ @tokens = []
269
+ end
270
+
271
+ SPECIAL_ARG_REGEX = /^\s*(?:(?<![\"\{]))([\w\!\[\]]+)(?:(?![\"\}]))/
272
+ SIMPLE_EXPRESSION = /(query|mutation|fragment)\s*\w+\s*on\w*.*\{\s*\n*[.|\w\s]*\}/
273
+ START_MAP = {
274
+ 'query' => :START_QUERY,
275
+ 'mutation' => :START_MUTATION,
276
+ 'fragment' => :START_FRAGMENT
277
+ }
278
+
279
+ def tokenize
280
+ until scanner.eos?
281
+ case state
282
+ when :default
283
+ if scanner.scan /^query (\w+)/
284
+ @tokens << [:START_QUERY, scanner[1]]
285
+ push_state :query
286
+ elsif scanner.scan /^mutation (\w+)/
287
+ @tokens << [:START_MUTATION, scanner[1]]
288
+ push_state :mutation
289
+ elsif scanner.scan /\s*fragment\s*(\w+)\s*on\s*(\w+)/
290
+ @tokens << [:START_FRAGMENT, scanner[1], scanner[2]]
291
+ push_state :fragment
292
+ elsif scanner.scan /\s*{\s*/
293
+ @tokens << [:START_FIELD]
294
+ push_state :field
295
+ elsif scanner.scan /\s*}\s*/
296
+ @tokens << [:END_EXPRESSION_SHOULDNT_GET_THIS]
297
+ else
298
+ advance
299
+ end
300
+ when :fragment
301
+ if scanner.scan /\s*\}\s*/
302
+ @tokens << [:END_FRAGMENT]
303
+ pop_state
304
+ pop_context
305
+ elsif scanner.check /^\s*\{\s*/
306
+ if get_context == :field
307
+ push_state :field
308
+ push_context :field
309
+ else
310
+ scanner.scan /^\s*\{\s*/
311
+ push_context :field
312
+ end
313
+ else
314
+ handle_field
315
+ end
316
+ when :mutation
317
+ if scanner.scan /\}/
318
+ @tokens << [:END_MUTATION]
319
+ pop_state
320
+ pop_context
321
+ elsif scanner.check /^\s*\{\s*$/
322
+ if get_context == :field
323
+ push_state :field
324
+ else
325
+ scanner.scan /^\s*\{\s*$/
326
+ push_context :field
327
+ end
328
+ else
329
+ handle_field
330
+ end
331
+ when :query
332
+ if scanner.scan /\s*\}\s*/
333
+ @tokens << [:END_QUERY]
334
+ pop_state
335
+ pop_context
336
+ elsif scanner.check /^\s*\{\s*/
337
+ if get_context == :field
338
+ push_state :field
339
+ push_context :field
340
+ else
341
+ scanner.scan /^\s*\{\s*/
342
+ push_context :field
343
+ end
344
+ else
345
+ handle_field
346
+ end
347
+ when :field
348
+ if scanner.check /\s*\}\s*/
349
+ if get_context == :field
350
+ scanner.scan /\s*\}\s*/
351
+ @tokens << [:END_FIELD]
352
+ pop_state
353
+ else
354
+ pop_state
355
+ end
356
+ else
357
+ handle_field
358
+ end
359
+ when :hash_arguments
360
+ handle_hash_arguments
361
+ when :array_arguments
362
+ handle_array_arguments
363
+ when :arguments
364
+ if scanner.scan /\s*\)\s*/
365
+ @tokens << [:END_ARGS]
366
+ pop_state
367
+ elsif scanner.scan /\=/
368
+ @tokens << [:START_DEFAULT_VALUE]
369
+ push_state :argument_defaults
370
+ elsif scanner.scan /,/
371
+ #
372
+ else
373
+ handle_shared_arguments
374
+ end
375
+ when :argument_defaults
376
+ if @stack.reverse.take(2).eql?([:argument_defaults, :argument_defaults])
377
+ @tokens << [:END_DEFAULT_VALUE]
378
+ pop_state
379
+ pop_state
380
+ else
381
+ push_state :argument_defaults
382
+ handle_shared_arguments
383
+ end
384
+ when :special_args
385
+ handle_special_args
386
+ end
387
+ end
388
+ @tokens
389
+ end
390
+
391
+ private
392
+
393
+ def handle_field
394
+ if scanner.scan /\s*\{\s*/
395
+ @context = :field
396
+ @tokens << [:START_FIELD]
397
+ push_state :field
398
+ elsif scanner.check /\.{3}(\w+)\s*\}/
399
+ scanner.scan /\.{3}(\w+)/
400
+ @tokens << [:FRAGMENT_REF, scanner[1]]
401
+ pop_context
402
+ # we need to pop state if we are nested in a field, and not in the query context
403
+ pop_state if get_context == :field
404
+ elsif scanner.scan /\.{3}(\w+)/
405
+ @tokens << [:FRAGMENT_REF, scanner[1]]
406
+ elsif scanner.scan /\s*(\w+):\s*/
407
+ @tokens << [:ALIAS, scanner[1]]
408
+ elsif scanner.check /\s*(\w+)\s*\}/
409
+ scanner.scan /\s*(\w+)\s*/
410
+ @tokens << [:FIELD_NAME, scanner[1]]
411
+ pop_context
412
+ # we need to pop state if we are nested in a field, and not in the query context
413
+ pop_state if get_context == :field
414
+ elsif scanner.scan /\s*(\w+)\s*/
415
+ @tokens << [:FIELD_NAME, scanner[1]]
416
+ elsif scanner.scan /^\s*\(/
417
+ @tokens << [:START_ARGS]
418
+ push_state :arguments
419
+ else
420
+ advance
421
+ end
422
+ end
423
+
424
+ def handle_shared_arguments
425
+ if scanner.scan /^(\w+):/
426
+ @tokens << [:ARG_KEY, scanner[1]]
427
+ elsif scanner.scan /^\s*\{\s*?/
428
+ @tokens << [:ARG_HASH_START]
429
+ push_state :hash_arguments
430
+ elsif scanner.scan /\s*\[\s*/
431
+ @tokens << [:ARG_ARRAY_START]
432
+ push_state :array_arguments
433
+ elsif scanner.scan /\s?\"([\w\s]+)\"/
434
+ @tokens << [:ARG_STRING_VALUE, scanner[1]]
435
+ elsif scanner.scan /\s?(\d+\.\d+)/
436
+ @tokens << [:ARG_FLOAT_VALUE, scanner[1].to_f]
437
+ elsif scanner.scan /\s?(\d+)/
438
+ @tokens << [:ARG_NUM_VALUE, scanner[1].to_i]
439
+ elsif scanner.scan /\s?(true|false)\s?/
440
+ bool = scanner[1] == "true"
441
+ @tokens << [:ARG_BOOL_VALUE, bool]
442
+ elsif scanner.scan /\$(\w+):/
443
+ @tokens << [:SPECIAL_ARG_KEY, scanner[1]]
444
+ push_state :special_args
445
+ elsif scanner.scan /\$(\w+)/
446
+ @tokens << [:SPECIAL_ARG_REF, scanner[1]]
447
+ else
448
+ advance
449
+ end
450
+ end
451
+
452
+ def handle_special_args
453
+ if scanner.check SPECIAL_ARG_REGEX
454
+ scanner.scan SPECIAL_ARG_REGEX
455
+ @tokens << [:SPECIAL_ARG_VAL, scanner[1]]
456
+ pop_state
457
+ else
458
+ pop_state
459
+ end
460
+ end
461
+
462
+ def handle_hash_arguments
463
+ if scanner.scan /\}/
464
+ @tokens << [:ARG_HASH_END]
465
+ pop_state
466
+ else
467
+ handle_shared_arguments
468
+ end
469
+ end
470
+
471
+ def handle_array_arguments
472
+ if scanner.scan /\s*\]\s*/
473
+ @tokens << [:ARG_ARRAY_END]
474
+ pop_state
475
+ else
476
+ handle_shared_arguments
477
+ end
478
+ end
479
+
480
+ def env
481
+ @ctx ||= []
482
+ end
483
+
484
+ def get_context
485
+ env.last || :default
486
+ end
487
+
488
+ def push_context(context)
489
+ env << context
490
+ end
491
+
492
+ def pop_context
493
+ env.pop
494
+ end
495
+
496
+ def rewind
497
+ scanner.pos = scanner.pos - 1
498
+ end
499
+
500
+ def advance
501
+ scanner.pos = scanner.pos + 1
502
+ end
503
+
504
+ def stack
505
+ @stack ||= []
506
+ end
507
+
508
+ def state
509
+ stack.last || :default
510
+ end
511
+
512
+ def push_state(state)
513
+ stack << state
514
+ end
515
+
516
+ def pop_state
517
+ stack.pop
518
+ end
519
+ end
520
+ end
521
+ end
@@ -1,12 +1,50 @@
1
1
  module Graphlyte
2
2
  module Schema
3
3
  module Types
4
+ class Defaults
5
+ attr_reader :value
6
+ def initialize(value)
7
+ @value = value
8
+ end
9
+
10
+ def merge!(str)
11
+ parse_value(@value, str)
12
+ end
13
+
14
+ def parse_value(value, str)
15
+ if value.is_a?(Hash)
16
+ str << "{ "
17
+ value.each_with_index do |(k, v), idx|
18
+ str << "#{k}: "
19
+ parse_value(v, str)
20
+ str << ", " if idx < (value.size - 1)
21
+ end
22
+ str << " }"
23
+ elsif value.is_a?(Array)
24
+ str << "["
25
+ value.each_with_index do |item, idx|
26
+ parse_value(item, str)
27
+ str << ", " if idx < (value.size - 1)
28
+ end
29
+ str << "]"
30
+ else
31
+ str << "#{Arguments::Value.new(value).to_s}"
32
+ end
33
+ end
34
+ end
35
+
4
36
  class Base
5
37
  attr_reader :name, :placeholder
6
38
 
7
- def initialize(name, placeholder)
39
+ def initialize(name, placeholder, defaults=nil)
8
40
  @name = name
9
41
  @placeholder = placeholder
42
+ @defaults = defaults
43
+ end
44
+
45
+ def default
46
+ return nil if @defaults.class == NilClass
47
+ Defaults.new(@defaults)
10
48
  end
11
49
  end
12
50
  end
data/lib/graphlyte.rb CHANGED
@@ -4,12 +4,17 @@ require_relative "./graphlyte/query"
4
4
  require_relative "./graphlyte/fragment"
5
5
  require_relative "./graphlyte/schema_query"
6
6
  require_relative "./graphlyte/types"
7
+ require_relative "./graphlyte/schema/parser"
7
8
 
8
9
  module Graphlyte
9
10
  extend SchemaQuery
10
11
 
11
12
  TYPES = Types.new
12
13
 
14
+ def self.parse(gql)
15
+ Graphlyte::Schema::Parser.parse(gql)
16
+ end
17
+
13
18
  def self.query(name = nil, &block)
14
19
  Query.new(name, :query, builder: build(&block))
15
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphlyte
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Gregory
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-06 00:00:00.000000000 Z
11
+ date: 2021-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -53,6 +53,7 @@ files:
53
53
  - lib/graphlyte/fragment.rb
54
54
  - lib/graphlyte/query.rb
55
55
  - lib/graphlyte/refinements/string_refinement.rb
56
+ - lib/graphlyte/schema/parser.rb
56
57
  - lib/graphlyte/schema/types/base.rb
57
58
  - lib/graphlyte/schema_query.rb
58
59
  - lib/graphlyte/types.rb
@@ -60,8 +61,8 @@ homepage: https://rubygems.org/gems/graphlyte
60
61
  licenses:
61
62
  - MIT
62
63
  metadata:
63
- source_code_uri: https://github.com/skinnyjames/graphlyte
64
- post_install_message:
64
+ source_code_uri: https://gitlab.com/seanchristophergregory/graphlyte
65
+ post_install_message:
65
66
  rdoc_options: []
66
67
  require_paths:
67
68
  - lib
@@ -76,8 +77,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
77
  - !ruby/object:Gem::Version
77
78
  version: '0'
78
79
  requirements: []
79
- rubygems_version: 3.2.22
80
- signing_key:
80
+ rubygems_version: 3.2.31
81
+ signing_key:
81
82
  specification_version: 4
82
83
  summary: craft graphql queries with ruby
83
84
  test_files: []