graphql-dsl 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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +23 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +44 -0
  6. data/.ruby-version +1 -0
  7. data/.yardopts +1 -0
  8. data/CODE_OF_CONDUCT.md +84 -0
  9. data/Gemfile +6 -0
  10. data/Gemfile.lock +64 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +899 -0
  13. data/Rakefile +6 -0
  14. data/bin/console +15 -0
  15. data/bin/setup +7 -0
  16. data/graphql-dsl.gemspec +38 -0
  17. data/lib/graphql/dsl/constants.rb +9 -0
  18. data/lib/graphql/dsl/error.rb +32 -0
  19. data/lib/graphql/dsl/formatter/arguments.rb +26 -0
  20. data/lib/graphql/dsl/formatter/directives.rb +52 -0
  21. data/lib/graphql/dsl/formatter/executable_document.rb +22 -0
  22. data/lib/graphql/dsl/formatter/field.rb +49 -0
  23. data/lib/graphql/dsl/formatter/formatter.rb +41 -0
  24. data/lib/graphql/dsl/formatter/fragment_operation.rb +41 -0
  25. data/lib/graphql/dsl/formatter/fragment_spread.rb +25 -0
  26. data/lib/graphql/dsl/formatter/inline_fragment.rb +43 -0
  27. data/lib/graphql/dsl/formatter/operation.rb +60 -0
  28. data/lib/graphql/dsl/formatter/values.rb +146 -0
  29. data/lib/graphql/dsl/formatter/variable_definitions.rb +43 -0
  30. data/lib/graphql/dsl/nodes/containers/directive.rb +46 -0
  31. data/lib/graphql/dsl/nodes/containers/variable_definition.rb +52 -0
  32. data/lib/graphql/dsl/nodes/executable_document.rb +69 -0
  33. data/lib/graphql/dsl/nodes/field.rb +39 -0
  34. data/lib/graphql/dsl/nodes/fragment_operation.rb +36 -0
  35. data/lib/graphql/dsl/nodes/fragment_spread.rb +24 -0
  36. data/lib/graphql/dsl/nodes/inline_fragment.rb +34 -0
  37. data/lib/graphql/dsl/nodes/mixins/selection_set.rb +106 -0
  38. data/lib/graphql/dsl/nodes/node.rb +39 -0
  39. data/lib/graphql/dsl/nodes/operation.rb +61 -0
  40. data/lib/graphql/dsl/version.rb +9 -0
  41. data/lib/graphql/dsl.rb +230 -0
  42. data/lib/graphql-dsl.rb +3 -0
  43. data/lib/graphql_dsl.rb +36 -0
  44. data/tasks/readme/update.rake +143 -0
  45. metadata +173 -0
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module DSL
5
+ ##
6
+ # Create executable GraphQL document
7
+ #
8
+ # @param block [Proc] declare DSL for operations
9
+ #
10
+ # @return [ExecutableDocument] executable GraphQL document
11
+ #
12
+ # @example Create executable document with several queries
13
+ # executable_document = GraphQL::DSL.executable_document {
14
+ # query(:sheep) {
15
+ # animal(type: :sheep) {
16
+ # __fragment :animal
17
+ # }
18
+ # }
19
+ #
20
+ # query(:she_goats) {
21
+ # animal(type: :she_goat) {
22
+ # __fragment :animal
23
+ # }
24
+ # }
25
+ #
26
+ # fragment(:animal, :Animal) {
27
+ # name
28
+ # age
29
+ # }
30
+ # }
31
+ #
32
+ # puts executable_document.to_gql
33
+ # # query sheep
34
+ # # {
35
+ # # animal(type: "sheep")
36
+ # # {
37
+ # # ...animal
38
+ # # }
39
+ # # }
40
+ # #
41
+ # # query she_goats
42
+ # # {
43
+ # # animal(type: "she_goat")
44
+ # # {
45
+ # # ...animal
46
+ # # }
47
+ # # }
48
+ # #
49
+ # # fragment animal on Animal
50
+ # # {
51
+ # # name
52
+ # # age
53
+ # # }
54
+ def executable_document(&block)
55
+ ExecutableDocument.new(&block)
56
+ end
57
+
58
+ module_function :executable_document
59
+
60
+ ##
61
+ # Create GraphQL query operation
62
+ #
63
+ # @param name [String, Symbol, nil] query name
64
+ # @param variable_definitions [Hash] variable definitions
65
+ # @param directives [Array] list of directives
66
+ # @param block [Proc] declare DSL for sub-fields
67
+ #
68
+ # @return [Operation] GraphQL query
69
+ #
70
+ # @example Create query
71
+ # query = GraphQL::DSL.query(:sheep) {
72
+ # animal(type: :sheep) {
73
+ # name
74
+ # age
75
+ # }
76
+ # }
77
+ #
78
+ # puts query.to_gql
79
+ # # query sheep
80
+ # # {
81
+ # # animal(type: "sheep")
82
+ # # {
83
+ # # name
84
+ # # age
85
+ # # }
86
+ # # }
87
+ def query(name = nil, variable_definitions = {}, directives = [], &block)
88
+ Operation.new(:query, name, variable_definitions, directives, &block)
89
+ end
90
+
91
+ module_function :query
92
+
93
+ ##
94
+ # Create GraphQL mutation operation
95
+ #
96
+ # @param name [String, Symbol, nil] mutation name
97
+ # @param variable_definitions [Hash] variable definitions
98
+ # @param directives [Array] list of directives
99
+ # @param block [Proc] declare DSL for sub-fields
100
+ #
101
+ # @return [Operation] GraphQL mutation
102
+ #
103
+ # @example Create mutation
104
+ # mutation = GraphQL::DSL.mutation(:create_sheep) {
105
+ # createSheep(name: 'Milly', age: 5) {
106
+ # id
107
+ # name
108
+ # age
109
+ # }
110
+ # }
111
+ #
112
+ # puts mutation.to_gql
113
+ # # mutation create_sheep
114
+ # # {
115
+ # # createSheep(name: "Milly", age: 5)
116
+ # # {
117
+ # # id
118
+ # # name
119
+ # # age
120
+ # # }
121
+ # # }
122
+ def mutation(name = nil, variable_definitions = {}, directives = [], &block)
123
+ Operation.new(:mutation, name, variable_definitions, directives, &block)
124
+ end
125
+
126
+ module_function :mutation
127
+
128
+ ##
129
+ # Create GraphQL subscription operation
130
+ #
131
+ # @param name [String, Symbol, nil] subscription name
132
+ # @param variable_definitions [Hash] variable definitions
133
+ # @param directives [Array] list of directives
134
+ # @param block [Proc] declare DSL for sub-fields
135
+ #
136
+ # @return [Operation] GraphQL subscription
137
+ #
138
+ # @example Create subscription
139
+ # subscription = GraphQL::DSL.subscription(:sheep_jumps) {
140
+ # animal(type: :sheep) {
141
+ # id
142
+ # name
143
+ # age
144
+ # }
145
+ # }
146
+ #
147
+ # puts subscription.to_gql
148
+ # # subscription sheep_jumps
149
+ # # {
150
+ # # animal(type: "sheep")
151
+ # # {
152
+ # # id
153
+ # # name
154
+ # # age
155
+ # # }
156
+ # # }
157
+ def subscription(name = nil, variable_definitions = {}, directives = [], &block)
158
+ Operation.new(:subscription, name, variable_definitions, directives, &block)
159
+ end
160
+
161
+ module_function :subscription
162
+
163
+ ##
164
+ # Create GraphQL fragment operation
165
+ #
166
+ # @param name [String, Symbol] fragment name
167
+ # @param type [String, Symbol] fragment type or interface
168
+ # @param directives [Array] list of directives
169
+ # @param block [Proc] declare DSL for sub-fields
170
+ #
171
+ # @return [FragmentOperation] GraphQL fragment
172
+ #
173
+ # @example Create fragment
174
+ # fragment = GraphQL::DSL.fragment(:animal, :Animal) {
175
+ # id
176
+ # name
177
+ # age
178
+ # }
179
+ #
180
+ # puts fragment.to_gql
181
+ # # fragment animal on Animal
182
+ # # {
183
+ # # id
184
+ # # name
185
+ # # age
186
+ # # }
187
+ def fragment(name, type, directives = [], &block)
188
+ FragmentOperation.new(name, type, directives, &block)
189
+ end
190
+
191
+ module_function :fragment
192
+
193
+ # @!group Refinement Method Summary
194
+
195
+ ##
196
+ # @!method directive(name, **arguments)
197
+ # @!scope class
198
+ #
199
+ # Create GraphQL directive
200
+ #
201
+ # @param name [String, Symbol] directive name
202
+ # @param arguments [Hash] arguments
203
+ #
204
+ # @return Directive
205
+ refine Kernel do
206
+ def directive(name, **arguments)
207
+ Directive.new(name, **arguments)
208
+ end
209
+ end
210
+
211
+ ##
212
+ # @!method variable(type, default = UNDEFINED, *directives)
213
+ # @!scope class
214
+ #
215
+ # Create GraphQL variable
216
+ #
217
+ # @param type [String, Symbol] variable type
218
+ # @param default [Object, nil] default value
219
+ # @param directives [Array<Directive, Hash, Array>] list of directives
220
+ #
221
+ # @return VariableDefinition
222
+ refine Kernel do
223
+ def variable(type, default = UNDEFINED, *directives)
224
+ VariableDefinition.new(type, default, directives)
225
+ end
226
+ end
227
+
228
+ # @!endgroup
229
+ end
230
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_dsl'
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql/dsl'
4
+ require 'graphql/dsl/constants'
5
+ require 'graphql/dsl/error'
6
+ require 'graphql/dsl/formatter/formatter'
7
+ require 'graphql/dsl/formatter/arguments'
8
+ require 'graphql/dsl/formatter/directives'
9
+ require 'graphql/dsl/formatter/executable_document'
10
+ require 'graphql/dsl/formatter/field'
11
+ require 'graphql/dsl/formatter/fragment_operation'
12
+ require 'graphql/dsl/formatter/fragment_spread'
13
+ require 'graphql/dsl/formatter/inline_fragment'
14
+ require 'graphql/dsl/formatter/operation'
15
+ require 'graphql/dsl/formatter/values'
16
+ require 'graphql/dsl/formatter/variable_definitions'
17
+ require 'graphql/dsl/nodes/containers/directive'
18
+ require 'graphql/dsl/nodes/containers/variable_definition'
19
+ require 'graphql/dsl/nodes/mixins/selection_set'
20
+ require 'graphql/dsl/nodes/node'
21
+ require 'graphql/dsl/nodes/executable_document'
22
+ require 'graphql/dsl/nodes/field'
23
+ require 'graphql/dsl/nodes/fragment_operation'
24
+ require 'graphql/dsl/nodes/fragment_spread'
25
+ require 'graphql/dsl/nodes/inline_fragment'
26
+ require 'graphql/dsl/nodes/operation'
27
+ require 'graphql/dsl/version'
28
+
29
+ ##
30
+ # Base module for GraphQL DSL gem
31
+ module GraphQL
32
+ ##
33
+ # GraphQL DSL entry-point
34
+ module DSL
35
+ end
36
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ReadmeUpdater # rubocop:disable Style/Documentation
4
+ module_function
5
+
6
+ README_FILE = 'README.md'
7
+
8
+ VERSION_REGEXP = /gem 'graphql-dsl', '~> .+'/.freeze
9
+
10
+ RUBY_CODE_BLOCK = /
11
+ (?<ruby_block>
12
+ \p{Blank}*```ruby\n
13
+ (?<ruby_code>
14
+ # lines between ``` separators
15
+ (?:(?!\p{Blank}*```\n)[^\n]*\n)*?
16
+ )
17
+ \p{Blank}*```\n
18
+ )
19
+ /x.freeze
20
+
21
+ GRAPHQL_CODE_BLOCK = /
22
+ (?<graphql_block>
23
+ \p{Blank}*```graphql\n
24
+ (?<graphql_code>
25
+ # lines between ``` separators
26
+ (?:(?!\p{Blank}*```\n)[^\n]*\n)*?
27
+ )
28
+ \p{Blank}*```\n
29
+ )
30
+ /x.freeze
31
+
32
+ NONCOLLAPSABLE_EXAMPLE_REGEXP = /
33
+ (?<before>
34
+ #{RUBY_CODE_BLOCK}
35
+
36
+ \p{Blank}*\n
37
+ )
38
+
39
+ #{GRAPHQL_CODE_BLOCK}
40
+ (?<after>)
41
+ /x.freeze
42
+
43
+ COLLAPSABLE_EXAMPLE = %r{
44
+ (?<before>
45
+ #{RUBY_CODE_BLOCK}
46
+
47
+ \p{Blank}*\n
48
+
49
+ \p{Blank}*<details>\n
50
+ \p{Blank}*<summary>\w+?</summary>\n
51
+
52
+ \p{Blank}*\n
53
+ )
54
+
55
+ #{GRAPHQL_CODE_BLOCK}
56
+
57
+ (?<after>
58
+ \p{Blank}*</details>\n
59
+ )
60
+ }x.freeze
61
+
62
+ EXAMPLES_REGEXPS = [
63
+ NONCOLLAPSABLE_EXAMPLE_REGEXP,
64
+ COLLAPSABLE_EXAMPLE,
65
+ ].freeze
66
+
67
+ # FYI: lambda required to avoid restrictions of Ruby refinements i.e. impossible to call `module_eval`
68
+ # with refinement inside from method but possible from lambda.
69
+ EXECUTE_EXAMPLE_CODE = lambda do |example_code|
70
+ mod = Module.new do
71
+ extend GraphQL::DSL
72
+
73
+ def self.puts(obj)
74
+ "#{obj}\n"
75
+ end
76
+ end
77
+
78
+ mod.module_eval(example_code)
79
+ end
80
+
81
+ def update
82
+ readme = File.read(README_FILE)
83
+ readme = update_version(readme)
84
+ readme = update_examples(readme)
85
+
86
+ File.write(README_FILE, readme)
87
+ end
88
+
89
+ def check
90
+ original_readme = File.read(README_FILE)
91
+ updated_readme = update_version(original_readme)
92
+ updated_readme = update_examples(updated_readme)
93
+
94
+ return unless original_readme != updated_readme
95
+
96
+ abort 'Required update of README.md file. Run `rake readme:update` to update it.'
97
+ end
98
+
99
+ def update_version(readme)
100
+ readme.gsub(VERSION_REGEXP) do
101
+ "gem 'graphql-dsl', '~> #{GraphQL::DSL::VERSION}'"
102
+ end
103
+ end
104
+
105
+ def update_examples(readme)
106
+ EXAMPLES_REGEXPS.reduce(readme) do |str, regexp|
107
+ str.gsub(regexp) do
108
+ before_code = Regexp.last_match(:before)
109
+ after_code = Regexp.last_match(:after)
110
+ ruby_code = Regexp.last_match(:ruby_code)
111
+ graphql_block = Regexp.last_match(:graphql_block)
112
+
113
+ ruby_code_result = EXECUTE_EXAMPLE_CODE.call(ruby_code)
114
+
115
+ format_example(ruby_code_result, before_code, after_code, graphql_block)
116
+ end
117
+ end
118
+ end
119
+
120
+ def format_example(ruby_code_result, before_code, after_code, graphql_block)
121
+ indent = graphql_block[/\A\s*/]
122
+
123
+ [
124
+ before_code,
125
+ "```graphql\n".gsub(/^/, indent),
126
+ ruby_code_result.gsub(/^/, indent),
127
+ "```\n".gsub(/^/, indent),
128
+ after_code,
129
+ ].compact.join
130
+ end
131
+ end
132
+
133
+ namespace :readme do
134
+ desc 'Update README.md file (i.e. examples queries, etc.)'
135
+ task :update do
136
+ ReadmeUpdater.update
137
+ end
138
+
139
+ desc 'Check required changes of README.md file'
140
+ task :check do
141
+ ReadmeUpdater.check
142
+ end
143
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphql-dsl
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Maxim Dobryakov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-10-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.18'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.18'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.9'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.9'
97
+ description: Ruby DSL for GraphQL
98
+ email:
99
+ - maxim.dobryakov@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".github/workflows/main.yml"
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".rubocop.yml"
108
+ - ".ruby-version"
109
+ - ".yardopts"
110
+ - CODE_OF_CONDUCT.md
111
+ - Gemfile
112
+ - Gemfile.lock
113
+ - LICENSE.txt
114
+ - README.md
115
+ - Rakefile
116
+ - bin/console
117
+ - bin/setup
118
+ - graphql-dsl.gemspec
119
+ - lib/graphql-dsl.rb
120
+ - lib/graphql/dsl.rb
121
+ - lib/graphql/dsl/constants.rb
122
+ - lib/graphql/dsl/error.rb
123
+ - lib/graphql/dsl/formatter/arguments.rb
124
+ - lib/graphql/dsl/formatter/directives.rb
125
+ - lib/graphql/dsl/formatter/executable_document.rb
126
+ - lib/graphql/dsl/formatter/field.rb
127
+ - lib/graphql/dsl/formatter/formatter.rb
128
+ - lib/graphql/dsl/formatter/fragment_operation.rb
129
+ - lib/graphql/dsl/formatter/fragment_spread.rb
130
+ - lib/graphql/dsl/formatter/inline_fragment.rb
131
+ - lib/graphql/dsl/formatter/operation.rb
132
+ - lib/graphql/dsl/formatter/values.rb
133
+ - lib/graphql/dsl/formatter/variable_definitions.rb
134
+ - lib/graphql/dsl/nodes/containers/directive.rb
135
+ - lib/graphql/dsl/nodes/containers/variable_definition.rb
136
+ - lib/graphql/dsl/nodes/executable_document.rb
137
+ - lib/graphql/dsl/nodes/field.rb
138
+ - lib/graphql/dsl/nodes/fragment_operation.rb
139
+ - lib/graphql/dsl/nodes/fragment_spread.rb
140
+ - lib/graphql/dsl/nodes/inline_fragment.rb
141
+ - lib/graphql/dsl/nodes/mixins/selection_set.rb
142
+ - lib/graphql/dsl/nodes/node.rb
143
+ - lib/graphql/dsl/nodes/operation.rb
144
+ - lib/graphql/dsl/version.rb
145
+ - lib/graphql_dsl.rb
146
+ - tasks/readme/update.rake
147
+ homepage: https://github.com/maxd/graphql-dsl
148
+ licenses:
149
+ - MIT
150
+ metadata:
151
+ homepage_uri: https://github.com/maxd/graphql-dsl
152
+ source_code_uri: https://github.com/maxd/graphql-dsl
153
+ changelog_uri: https://github.com/maxd/graphql-dsl/releases
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 2.6.0
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubygems_version: 3.2.22
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: GraphQL DSL
173
+ test_files: []