graphlyte 0.1.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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/graphlyte.rb +174 -0
  3. metadata +72 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a0bffc10187360021075728a9cd92448b728f3a3737e55c8554ac3efce3ad27d
4
+ data.tar.gz: a38f90352c4911513dffc2feff56c5ea0664334241cf583002f264a178990248
5
+ SHA512:
6
+ metadata.gz: 2f64a45e7c4cd9413c414ea7a7c028c6fba32e92036443ae2b123a7ecc7d84e0b4094828913902d642f93953e0b1a50354388e5e622590c1f6c633a4e35612ee
7
+ data.tar.gz: c026a8ad7c93b9ec4b54408b5f4a9ef4736b868e4a5d1b8ad420d78f208ac2a15f30534a0baed49f281f87a9a69cc69ff78bca446b29c624ed886b5872589f96
data/lib/graphlyte.rb ADDED
@@ -0,0 +1,174 @@
1
+ require 'json'
2
+ module Graphlyte
3
+ def self.query(name = nil, &block)
4
+ query = Query.new(name)
5
+ block.call(query) if block
6
+ query
7
+ end
8
+
9
+ def self.fragment(fragment_name, model_name=nil, &block)
10
+ fragment = Fragment.new(fragment_name, model_name)
11
+ block.call(fragment) if block
12
+ fragment
13
+ end
14
+
15
+ def self.fieldset(model_name=nil, &block)
16
+ fieldset = Fieldset.new(model_name)
17
+ block.call(fieldset) if block
18
+ fieldset
19
+ end
20
+
21
+ module Buildable
22
+ def <<(buildable)
23
+ raise "Must pass a Fieldset or Fragment" unless [Fragment, Fieldset].include?(buildable.class)
24
+ @fields.concat(buildable._fields) if buildable.class.eql? Fieldset
25
+ @fields << buildable if buildable.class.eql? Fragment
26
+ end
27
+
28
+ def method_missing(method, optional_fieldset_or_args=nil, hargs={}, &block)
29
+ field = [Fieldset, Fragment].include?(optional_fieldset_or_args.class) ?
30
+ Field.new(method, optional_fieldset_or_args, hargs) :
31
+ Field.new(method, Fieldset.empty, optional_fieldset_or_args)
32
+ block.call(field.value) if block
33
+ @fields << field
34
+ field
35
+ end
36
+ end
37
+
38
+ class Fieldset
39
+ include Buildable
40
+
41
+ def self.empty
42
+ new
43
+ end
44
+
45
+ def initialize(model_name = nil)
46
+ @model_name = model_name
47
+ @fields = []
48
+ end
49
+
50
+ def _model_name
51
+ @model_name
52
+ end
53
+
54
+ def _fields
55
+ @fields
56
+ end
57
+
58
+ def empty?
59
+ @fields.empty?
60
+ end
61
+
62
+ def can_validate?
63
+ !@model_name.nil?
64
+ end
65
+
66
+ def to_s(indent=0)
67
+ @fields.map { |field| field.to_s(indent)}.join("\n")
68
+ end
69
+ end
70
+
71
+ class Query < Fieldset
72
+
73
+ def initialize(query_name=nil)
74
+ @query_name = query_name
75
+ @fields = []
76
+ end
77
+
78
+ def to_json
79
+ { query: to_s }.to_json
80
+ end
81
+
82
+ def to_s(indent=0)
83
+ "{\n#{super(indent + 1)}\n}\n#{format_fragments}\n"
84
+ end
85
+
86
+ def format_fragments
87
+ str = ""
88
+ flatten(@fields).each do |fragment|
89
+ str += "\nfragment #{fragment.name}"
90
+ str += " on #{fragment._model_name}" unless fragment._model_name.nil?
91
+ str += " {\n#{fragment._fields.map {|f| f.to_s(1) }.join("\n")}\n}"
92
+ end
93
+ str
94
+ end
95
+
96
+ def flatten(fields=@fields, new_fields = [])
97
+ fields.each do |field|
98
+ if field.class.eql?(Fragment)
99
+ new_fields << field
100
+ unless field._fields.empty?
101
+ flatten(field._fields, new_fields)
102
+ end
103
+ else
104
+ if field.value.class.eql?(Fragment)
105
+ new_fields << field.value
106
+ flatten(field.value._fields, new_fields) unless field.value._fields.empty?
107
+ else
108
+ flatten(field.value._fields, new_fields) unless field.value._fields.empty?
109
+ end
110
+ end
111
+ end
112
+ new_fields
113
+ end
114
+ end
115
+
116
+ class Fragment < Fieldset
117
+ attr_reader :fragment_name, :name
118
+
119
+ def initialize(fragment_name, model_name=nil)
120
+ @fragment_name = fragment_name
121
+ @name = fragment_name
122
+ super(model_name)
123
+ end
124
+
125
+ def to_s(indent=0)
126
+ actual_indent = ("\s" * indent) * 2
127
+ "#{actual_indent}...#{@fragment_name}#{actual_indent}"
128
+ end
129
+ end
130
+
131
+ class FieldArguments
132
+ def initialize(data)
133
+ @data = data
134
+ end
135
+
136
+ def to_s
137
+ return @data && !@data.empty? ? "(#{@data.map{|k, v| "#{k}: #{v}"}.join(", ")})" : ""
138
+ end
139
+ end
140
+
141
+ class Field
142
+ attr_reader :name, :value, :inputs, :alias
143
+
144
+ def initialize(name, value=nil, hargs)
145
+ @name = name
146
+ @value = value
147
+ @inputs = FieldArguments.new(hargs)
148
+ @alias = nil
149
+ end
150
+
151
+ def atomic?
152
+ value.empty?
153
+ end
154
+
155
+ def alias(name, &block)
156
+ @alias = name
157
+ block.call(value) if block
158
+ end
159
+
160
+ def to_s(indent=0)
161
+ str = ""
162
+ actual_indent = ("\s" * indent) * 2
163
+ if @alias
164
+ str += "#{actual_indent}#{@alias}: #{name}"
165
+ str += inputs.to_s.empty? ? "()" : inputs.to_s
166
+ str += " "
167
+ else
168
+ str += "#{actual_indent}#{name}#{inputs.to_s}"
169
+ end
170
+ str += "{\n#{value.to_s(indent + 1)}#{actual_indent}\n#{actual_indent}}" unless atomic?
171
+ str
172
+ end
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphlyte
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sean Gregory
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: craft graphql queries with ruby
42
+ email: sean.christopher.gregory@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/graphlyte.rb
48
+ homepage: https://rubygems.org/gems/graphlyte
49
+ licenses:
50
+ - MIT
51
+ metadata:
52
+ source_code_uri: https://github.com/skinnyjames/graphlyte
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.2.3
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: craft graphql queries with ruby
72
+ test_files: []