graphlyte 0.1.4 → 0.1.5

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: ae8c18b5676a04d0c309c37bccf668f6bdc8f61553cfda7e94f17491bbb5c995
4
- data.tar.gz: d46d31fe92d944c0e5c56d94894bf2ca8c4f5bfce33d4815c99969e3269546ac
3
+ metadata.gz: e9b09edacd482f9beb267eed78593bc26f5f0563648399f60fec47d1552052eb
4
+ data.tar.gz: 39756650800195570dc38a7f7990e0b0efc001033045d6865f16b275749d3de5
5
5
  SHA512:
6
- metadata.gz: cb092554a67b5e1805e112b9b2bf09448ed054dbae3b047cd722b84faf9b963dcd46b8bfd71ee5090f966309bfa4f006fbd7e9e7aa08dd81a1234fa400e78674
7
- data.tar.gz: 7044177b3c66375410a1d52eed7e089bf3ba68b5cf49c0702b6cfd5d88314670383eddc1aa501a567cf166ae275fad165e6356fb3506842359a64bc2c172090f
6
+ metadata.gz: e084fd25d75112d2d97a994c63259d436a684e6880a8ea9ef47a56337012f78615bdeb89cb03a39603bdbb5dabd30c07e8b0167f46facae650a990f11dba4377
7
+ data.tar.gz: 88cd8dd425fc74a8707b203683d76b5d168649b979708deffcec92f867c569a4f465ea0c30350ce9caa459c5b9ba667835f9e7ada7e9df4bee85b19bce7dda7b
data/lib/graphlyte.rb CHANGED
@@ -2,8 +2,14 @@ require 'json'
2
2
  require_relative "./graphlyte/fieldset"
3
3
  require_relative "./graphlyte/query"
4
4
  require_relative "./graphlyte/fragment"
5
+ require_relative "./graphlyte/schema_query"
6
+ require_relative "./graphlyte/types"
5
7
 
6
8
  module Graphlyte
9
+ extend SchemaQuery
10
+
11
+ TYPES = Types.new
12
+
7
13
  def self.query(name = nil, &block)
8
14
  Query.new(name, builder: build(&block))
9
15
  end
@@ -1,7 +1,9 @@
1
1
  require_relative "./value"
2
+ require_relative "./../refinements/string_refinement"
2
3
  module Graphlyte
3
4
  module Arguments
4
5
  class Set
6
+ using Refinements::StringRefinement
5
7
 
6
8
  attr_reader :values
7
9
 
@@ -9,16 +11,43 @@ module Graphlyte
9
11
  raise ArgumentError, "input #{data} must be a hash" unless data.nil? || data.is_a?(Hash)
10
12
  @values = expand_arguments(data) unless data.nil?
11
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.symbol?
20
+ variables << value
21
+ elsif value.formal?
22
+ variables << value
23
+ end
24
+ end
25
+ variables
26
+ end
27
+
28
+ def to_h(inner = false)
29
+ return {} unless values && !values.empty?
30
+ values.inject({}) do |memo, (k, v)|
31
+ if v.is_a?(Array)
32
+ memo[k.to_s.to_camel_case] = v.map(&:to_s)
33
+ elsif v.is_a?(Set)
34
+ memo[k.to_s.to_camel_case] = v.to_h
35
+ else
36
+ memo[k.to_s.to_camel_case] = v.to_s
37
+ end
38
+ memo
39
+ end
40
+ end
12
41
 
13
42
  def to_s(inner = false)
14
43
  return "" unless values && !values.empty?
15
44
  arr = values.map do |k,v|
16
45
  if v.is_a?(Array)
17
- "#{k}: [#{v.map(&:to_s).join(", ")}]"
46
+ "#{k.to_s.to_camel_case}: [#{v.map(&:to_s).join(", ")}]"
18
47
  elsif v.is_a?(Set)
19
- "#{k}: { #{v.to_s(true)} }"
48
+ "#{k.to_s.to_camel_case}: { #{v.to_s(true)} }"
20
49
  else
21
- "#{k}: #{v.to_s}"
50
+ "#{k.to_s.to_camel_case}: #{v.to_s}"
22
51
  end
23
52
  end
24
53
  return arr.join(", ") if inner
@@ -1,6 +1,9 @@
1
+ require_relative "./../refinements/string_refinement"
1
2
  module Graphlyte
2
3
  module Arguments
3
4
  class Value
5
+ using Refinements::StringRefinement
6
+
4
7
  attr_reader :value
5
8
 
6
9
  def initialize(value)
@@ -8,10 +11,20 @@ module Graphlyte
8
11
  @value = value
9
12
  end
10
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
+
11
22
  def to_s
23
+ return "$#{value.to_s.to_camel_case}" if value.is_a? Symbol
12
24
  return value if value.is_a? Numeric
13
25
  return "\"#{value}\"" if value.is_a? String
14
26
  return "null" if value.nil?
27
+ return "$#{value.placeholder.to_camel_case}" if value.is_a? Schema::Types::Base
15
28
  value.to_s
16
29
  end
17
30
  end
@@ -3,8 +3,8 @@ require_relative "./fieldset"
3
3
 
4
4
  module Graphlyte
5
5
  class Builder
6
- def initialize
7
- @fields = []
6
+ def initialize(fields = [])
7
+ @fields = fields
8
8
  end
9
9
 
10
10
  def <<(buildable)
@@ -1,11 +1,13 @@
1
1
  require_relative "./arguments/set"
2
-
2
+ require_relative "./refinements/string_refinement"
3
3
  module Graphlyte
4
4
  class Field
5
+ using Refinements::StringRefinement
6
+
5
7
  attr_reader :name, :fieldset, :inputs, :alias
6
8
 
7
9
  def initialize(name, fieldset, hargs, inputs: Arguments::Set.new(hargs))
8
- @name = to_camel_case(name.to_s)
10
+ @name = name.to_s.to_camel_case
9
11
  @fieldset = fieldset
10
12
  @inputs = inputs
11
13
  @alias = nil
@@ -32,16 +34,5 @@ module Graphlyte
32
34
  str += " {\n#{fieldset.to_s(indent + 1)}\n#{actual_indent}}" unless atomic?
33
35
  str
34
36
  end
35
-
36
- def to_camel_case(string)
37
- start_of_string = string.match(/(^_+)/)&.[](0)
38
- end_of_string = string.match(/(_+$)/)&.[](0)
39
-
40
- middle = string.split("_").reject(&:empty?).inject([]) do |memo, str|
41
- memo << (memo.empty? ? str : str.capitalize)
42
- end.join("")
43
-
44
- "#{start_of_string}#{middle}#{end_of_string}"
45
- end
46
37
  end
47
38
  end
@@ -1,6 +1,7 @@
1
+ require_relative "./refinements/string_refinement"
1
2
  module Graphlyte
2
3
  class Query < Fieldset
3
-
4
+ using Refinements::StringRefinement
4
5
  attr_reader :name
5
6
 
6
7
  def initialize(query_name=nil, **hargs)
@@ -8,14 +9,51 @@ module Graphlyte
8
9
  super(**hargs)
9
10
  end
10
11
 
11
- def to_json
12
- { query: to_s }.to_json
12
+ def placeholders
13
+ flatten_variables(builder.>>).map do |value|
14
+ ":#{value.value.placeholder} of #{value.value.name}"
15
+ end.join("\n")
16
+ end
17
+
18
+ def to_json(name="anonymousQuery", **hargs)
19
+ variables = flatten_variables(builder.>>)
20
+ types = merge_variable_types(variables, hargs)
21
+
22
+ str = "query #{name}"
23
+ unless types.empty?
24
+ type_new = types.map do |type_arr|
25
+ "$#{type_arr[0].to_camel_case}: #{type_arr[1]}"
26
+ end
27
+ str += "(#{type_new.join(", ")})"
28
+ end
29
+ { query: "#{str} #{to_s(1)}", variables: Arguments::Set.new(hargs).to_h }.to_json
13
30
  end
14
31
 
15
32
  def to_s(indent=0)
16
33
  "{\n#{super(indent + 1)}\n}#{format_fragments}"
17
34
  end
18
35
 
36
+ def merge_variable_types(variables=[], hargs)
37
+ variables.inject([]) do |memo, var|
38
+ unless var.formal?
39
+ if hargs[var.value].is_a? String
40
+ memo << [var.value.to_camel_case, "String"]
41
+ elsif [TrueClass, FalseClass].include? hargs[var.value].class
42
+ memo << [var.value ,"Boolean"]
43
+ elsif hargs[var.value].is_a? Float
44
+ memo << [var.value, "Float"]
45
+ elsif hargs[var.value].is_a? Integer
46
+ memo << [var.value, "Int"]
47
+ elsif hargs[var.value].is_a? Array
48
+ memo << "[#{merge_variable_types(var.value, hargs).first}]"
49
+ end
50
+ else
51
+ memo << [var.value.placeholder, var.value.name]
52
+ end
53
+ memo
54
+ end
55
+ end
56
+
19
57
  def format_fragments
20
58
  str = "\n"
21
59
  flatten(builder.>>).each do |_, fragment|
@@ -26,6 +64,18 @@ module Graphlyte
26
64
  str
27
65
  end
28
66
 
67
+ def flatten_variables(fields, variables=[])
68
+ fields.each do |field|
69
+ variables.concat field.inputs.extract_variables unless field.class.eql?(Fragment)
70
+ if field.class.eql?(Fragment)
71
+ flatten_variables(field.fields, variables)
72
+ else
73
+ flatten_variables(field.fieldset.fields, variables)
74
+ end
75
+ end
76
+ variables
77
+ end
78
+
29
79
  def flatten(fields, new_fields = {})
30
80
  fields.each do |field|
31
81
  if field.class.eql?(Fragment)
@@ -36,10 +86,8 @@ module Graphlyte
36
86
  else
37
87
  if field.fieldset.class.eql?(Fragment)
38
88
  new_fields[field.fieldset.fragment] = field.fieldset
39
- flatten(field.fieldset.fields, new_fields) unless field.atomic?
40
- else
41
- flatten(field.fieldset.fields, new_fields) unless field.atomic?
42
89
  end
90
+ flatten(field.fieldset.fields, new_fields) unless field.atomic?
43
91
  end
44
92
  end
45
93
  new_fields
@@ -0,0 +1,23 @@
1
+ module Graphlyte
2
+ module Refinements
3
+ module StringRefinement
4
+ refine Symbol do
5
+ def to_camel_case
6
+ to_s.to_camel_case
7
+ end
8
+ end
9
+ refine String do
10
+ def to_camel_case
11
+ start_of_string = match(/(^_+)/)&.[](0)
12
+ end_of_string = match(/(_+$)/)&.[](0)
13
+
14
+ middle = split("_").reject(&:empty?).inject([]) do |memo, str|
15
+ memo << (memo.empty? ? str : str.capitalize)
16
+ end.join("")
17
+
18
+ "#{start_of_string}#{middle}#{end_of_string}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ module Graphlyte
2
+ module Schema
3
+ module Types
4
+ class Base
5
+ attr_reader :name, :placeholder
6
+
7
+ def initialize(name, placeholder)
8
+ @name = name
9
+ @placeholder = placeholder
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,83 @@
1
+
2
+ module Graphlyte
3
+ module SchemaQuery
4
+ def schema_query
5
+ type_ref_fragment = Graphlyte.fragment('TypeRef', '__Type') do
6
+ kind
7
+ name
8
+ of_type {
9
+ kind
10
+ name
11
+ of_type {
12
+ kind
13
+ name
14
+ of_type {
15
+ kind
16
+ name
17
+ of_type {
18
+ kind
19
+ name
20
+ of_type {
21
+ kind
22
+ name
23
+ of_type {
24
+ kind
25
+ name
26
+ of_type {
27
+ kind
28
+ name
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ end
37
+
38
+ input_value_fragment = Graphlyte.fragment('InputValues', '__InputValue') do
39
+ name
40
+ description
41
+ type type_ref_fragment
42
+ default_value
43
+ end
44
+
45
+ full_type_fragment = Graphlyte.fragment('FullType', '__Type') do
46
+ kind
47
+ name
48
+ description
49
+ fields(includeDeprecated: true) do
50
+ name
51
+ description
52
+ args input_value_fragment
53
+ type type_ref_fragment
54
+ is_deprecated
55
+ deprecation_reason
56
+ end
57
+ input_fields input_value_fragment
58
+ interfaces type_ref_fragment
59
+ enum_values(includeDeprecated: true) do
60
+ name
61
+ description
62
+ is_deprecated
63
+ deprecation_reason
64
+ end
65
+ possible_types type_ref_fragment
66
+ end
67
+
68
+ Graphlyte.query do
69
+ __schema do
70
+ query_type { name }
71
+ mutation_type { name }
72
+ subscription_type { name }
73
+ types full_type_fragment
74
+ directives do
75
+ name
76
+ description
77
+ args input_value_fragment
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "schema/types/base"
2
+
3
+ module Graphlyte
4
+ class Types
5
+ def method_missing(method, placeholder)
6
+ Schema::Types::Base.new(method, placeholder)
7
+ end
8
+ end
9
+ 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.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Gregory
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-11 00:00:00.000000000 Z
11
+ date: 2021-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -52,6 +52,10 @@ files:
52
52
  - lib/graphlyte/fieldset.rb
53
53
  - lib/graphlyte/fragment.rb
54
54
  - lib/graphlyte/query.rb
55
+ - lib/graphlyte/refinements/string_refinement.rb
56
+ - lib/graphlyte/schema/types/base.rb
57
+ - lib/graphlyte/schema_query.rb
58
+ - lib/graphlyte/types.rb
55
59
  homepage: https://rubygems.org/gems/graphlyte
56
60
  licenses:
57
61
  - MIT