alchemy-graphql 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6ce948ae7006c2d16bd83a5ff1e3994cabc55ef13e172022417f81b2f54eaf36
4
+ data.tar.gz: e136bac74fd3617b2d474257cb8331d69a1e496ebb735402199ec8a4943ff8ff
5
+ SHA512:
6
+ metadata.gz: 812891c3d04023fbb842235c373ee45f4cec1e58b0a4369a5fd6f29f1afd00065a5d8c924ac07ba0217bcdfd4fa9422c55d3f901bdf12550928adf625a805840
7
+ data.tar.gz: f9827148143c719971ec244d1082f1a6b705dbbe02dd35daa3693018a8321c7f57e9a0d14032057a38313f14abb91119fb8a0569dead1dc59bfe367487b13e3b
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright 2019 Thomas von Deyen
2
+
3
+ Redistribution and use in source and binary forms, with or without modification,
4
+ are permitted provided that the following conditions are met:
5
+
6
+ Redistributions of source code must retain the above copyright notice, this
7
+ list of conditions and the following disclaimer.
8
+
9
+ Redistributions in binary form must reproduce the above copyright notice, this
10
+ list of conditions and the following disclaimer in the documentation and/or
11
+ other materials provided with the distribution.
12
+
13
+ Neither the name of the copyright holder nor the names of its
14
+ contributors may be used to endorse or promote products derived from
15
+ this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
21
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,338 @@
1
+ [![CircleCI](https://circleci.com/gh/AlchemyCMS/alchemy-graphql/tree/master.svg?style=svg)](https://circleci.com/gh/AlchemyCMS/alchemy-graphql/tree/master)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/d5ccbf59314f813ce195/maintainability)](https://codeclimate.com/github/AlchemyCMS/alchemy-graphql/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/d5ccbf59314f813ce195/test_coverage)](https://codeclimate.com/github/AlchemyCMS/alchemy-graphql/test_coverage)
4
+
5
+ # AlchemyCMS GraphQL API
6
+ Add a GraphQL API to your AlchemyCMS powered site.
7
+
8
+ **WARNING: This is in an early state and changes to the API may be applied without any further announcement!**
9
+
10
+ ## Installation
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'alchemy-graphql', github: 'AlchemyCMS/alchemy-graphql'
15
+ ```
16
+
17
+ And then execute:
18
+ ```bash
19
+ $ bundle
20
+ ```
21
+
22
+ ## Setup
23
+
24
+ There are two ways of setting up the GraphQL API for AlchemyCMS.
25
+
26
+ ### Use the provided GraphQL endpoint
27
+
28
+ This is the easiest way of setting up the AlchemyCMS GraphQL API. Recommended for apps not having a GraphQL API or stand alone Alchemy installations.
29
+
30
+ ```rb
31
+ # config/routes
32
+ Rails.application.routes.draw do
33
+ mount Alchemy::GraphQL::Engine => '/'
34
+ mount Alchemy::Engine => '/'
35
+ ...
36
+ end
37
+ ```
38
+
39
+ _NOTE:_ It is necessary to mount the `Alchemy::GraphQL::Engine` before mounting the `Alchemy::Engine` otherwise Alchemys catch all route will make your GraphQL endpoint unreachable.
40
+
41
+ Your GraphQL endpoint will be available at `/graphql`.
42
+
43
+ _TIP:_ Mounting the engine at a different path (ie `/cms`) will prefix the GraphQL endpoint with that path (ie. `/cms/graphql`)
44
+
45
+ ### Build your own GraphQL endpoint
46
+
47
+ This is the more advanced way of setting up the AlchemyCMS GraphQL API.
48
+ It is recommended for apps already having a GraphQL API or people who want to build their own schema.
49
+
50
+ Include one or all of the [provided fields](https://github.com/AlchemyCMS/alchemy-graphql/tree/master/lib/alchemy/graphql/fields/) in your `GraphQL::Schema::Object` class.
51
+
52
+ ```rb
53
+ # app/graphql/query.rb
54
+ class GraphQL::Query < ::GraphQL::Schema::Object
55
+ field :my_field, String, null: true
56
+ include Alchemy::GraphQL::PageFields
57
+ end
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ We recommend using [GraphiQL](https://github.com/rmosolgo/graphiql-rails) in your app to have an interactive API explorer in your browser.
63
+
64
+ ### Online demo
65
+
66
+ We also provide an online demo for you to play with:
67
+
68
+ https://demo.alchemy-cms.com/graphiql
69
+
70
+ ### Example queries
71
+
72
+ #### Find an Alchemy page by its name
73
+
74
+ ```graphql
75
+ query {
76
+ page: alchemyPage(name: "A page") {
77
+ name
78
+ elements(only: "article") {
79
+ contents(only: "headline") {
80
+ ingredient
81
+ }
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ will return
88
+
89
+ ```json
90
+ {
91
+ "data": {
92
+ "page": {
93
+ "name": "A page",
94
+ "elements": [
95
+ {
96
+ "contents": [
97
+ {
98
+ "ingredient": "My headline"
99
+ }
100
+ ]
101
+ }
102
+ ]
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ It is also possible to find pages by a name match instead of an exact name.
109
+
110
+ ```graphql
111
+ query {
112
+ page: alchemyPage(name: "Contact", exactMatch: false) {
113
+ name
114
+ }
115
+ }
116
+ ```
117
+
118
+ will return
119
+
120
+ ```json
121
+ {
122
+ "data": {
123
+ "page": {
124
+ "name": "Contact us"
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ #### Find an Alchemy page by its urlname
131
+
132
+ ```graphql
133
+ query {
134
+ page: alchemyPage(urlname: "a-page") {
135
+ elements {
136
+ contents {
137
+ ingredient
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ will return
145
+
146
+ ```json
147
+ {
148
+ "data": {
149
+ "page": {
150
+ "elements": [
151
+ {
152
+ "contents": [
153
+ {
154
+ "ingredient": "My headline"
155
+ },
156
+ {
157
+ "ingredient": "<p>My paragraph.</p>"
158
+ }
159
+ ]
160
+ }
161
+ ]
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ It is also possible to find pages by an urlname match instead of an exact urlname.
168
+
169
+ ```graphql
170
+ query {
171
+ page: alchemyPage(urlname: "contact", exactMatch: false) {
172
+ urlname
173
+ }
174
+ }
175
+ ```
176
+
177
+ will return
178
+
179
+ ```json
180
+ {
181
+ "data": {
182
+ "page": {
183
+ "urlname": "contact-us"
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ #### Find an Alchemy page by several attributes
190
+
191
+ You can even combine attributes to narrow down the result.
192
+
193
+ ```graphql
194
+ query {
195
+ page: alchemyPage(
196
+ name: "Foot",
197
+ pageLayout: "footer",
198
+ exactMatch: false
199
+ ) {
200
+ name
201
+ }
202
+ }
203
+ ```
204
+
205
+ will return
206
+
207
+ ```json
208
+ {
209
+ "data": {
210
+ "page": {
211
+ "name": "Footer"
212
+ }
213
+ }
214
+ }
215
+ ```
216
+
217
+ #### Find an Alchemy element by its name
218
+
219
+ ```graphql
220
+ query {
221
+ element: alchemyElement(name: "article") {
222
+ name
223
+ contents(only: "headline") {
224
+ ingredient
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ will return
231
+
232
+ ```json
233
+ {
234
+ "data": {
235
+ "element": {
236
+ "name": "article",
237
+ "contents": [
238
+ {
239
+ "ingredient": "My headline"
240
+ }
241
+ ]
242
+ }
243
+ }
244
+ }
245
+ ```
246
+
247
+ It is also possible to find elements by a name match instead of an exact name.
248
+
249
+ ```graphql
250
+ query {
251
+ element: alchemyElement(name: "head", exactMatch: false) {
252
+ name
253
+ }
254
+ }
255
+ ```
256
+
257
+ will return
258
+
259
+ ```json
260
+ {
261
+ "data": {
262
+ "element": {
263
+ "name": "header"
264
+ }
265
+ }
266
+ }
267
+ ```
268
+
269
+ #### Find Alchemy elements by name
270
+
271
+ ```graphql
272
+ query {
273
+ elements: alchemyElements(only: "article") {
274
+ name
275
+ contents(only: "headline") {
276
+ ingredient
277
+ }
278
+ }
279
+ }
280
+ ```
281
+
282
+ will return
283
+
284
+ ```json
285
+ {
286
+ "data": {
287
+ "elements": [
288
+ {
289
+ "name": "article",
290
+ "contents": [
291
+ {
292
+ "ingredient": "My first headline"
293
+ }
294
+ ]
295
+ },
296
+ {
297
+ "name": "article",
298
+ "contents": [
299
+ {
300
+ "ingredient": "My second headline"
301
+ }
302
+ ]
303
+ }
304
+ ]
305
+ }
306
+ }
307
+ ```
308
+
309
+ It is also possible to exclude elements by name.
310
+
311
+ ```graphql
312
+ query {
313
+ elements: alchemyElements(except: "article") {
314
+ name
315
+ }
316
+ }
317
+ ```
318
+
319
+ will return
320
+
321
+ ```json
322
+ {
323
+ "data": {
324
+ "elements": [
325
+ {
326
+ "name": "header"
327
+ },
328
+ {
329
+ "name": "footer"
330
+ }
331
+ ]
332
+ }
333
+ }
334
+ ```
335
+
336
+ ## License
337
+
338
+ The gem is available as open source under the terms of the [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause).
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Alchemy::GraphQL'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ load 'rails/tasks/statistics.rake'
18
+
19
+ require 'bundler/gem_tasks'
20
+
21
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
22
+ load 'rails/tasks/engine.rake'
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ class GraphqlController < ApplicationController
5
+ include Alchemy::ControllerActions
6
+ include Alchemy::AbilityHelper
7
+
8
+ def execute
9
+ render json: Alchemy::GraphQL::Schema.execute(
10
+ params[:query],
11
+ context: {
12
+ current_user: current_alchemy_user,
13
+ current_ability: current_ability
14
+ },
15
+ operation_name: params[:operationName]
16
+ )
17
+ rescue StandardError => e
18
+ raise e unless Rails.env.development?
19
+
20
+ handle_error_in_development(e)
21
+ end
22
+
23
+ private
24
+
25
+ def handle_error_in_development(e)
26
+ logger.error e.message
27
+ logger.error e.backtrace.join("\n")
28
+
29
+ render json: { error: { message: e.message, backtrace: e.backtrace }, data: {} }, status: 500
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Alchemy::GraphQL::Engine.routes.draw do
4
+ post "/graphql", to: 'graphql#execute'
5
+ end
@@ -0,0 +1 @@
1
+ require 'alchemy/graphql'
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+ require 'alchemy_cms'
5
+
6
+ module Alchemy
7
+ module GraphQL
8
+ autoload :Schema, 'alchemy/graphql/schema'
9
+ autoload :Query, 'alchemy/graphql/query'
10
+ autoload :PageFields, 'alchemy/graphql/fields/page_fields'
11
+ autoload :ElementFields, 'alchemy/graphql/fields/element_fields'
12
+ autoload :PageType, 'alchemy/graphql/types/page_type'
13
+ autoload :ElementType, 'alchemy/graphql/types/element_type'
14
+ autoload :ContentType, 'alchemy/graphql/types/content_type'
15
+ end
16
+ end
17
+
18
+ require_relative 'graphql/engine'
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ class Engine < ::Rails::Engine
6
+ isolate_namespace Alchemy
7
+ engine_name 'alchemy_graphql'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ module ElementFields
6
+ def self.included(query)
7
+ query.field :alchemy_elements, [ElementType], null: true do
8
+ description "Find Alchemy Elements."
9
+ argument :only, ::GraphQL::Types::String, required: false
10
+ argument :except, ::GraphQL::Types::String, required: false
11
+ end
12
+
13
+ query.field :alchemy_element, ElementType, null: true do
14
+ description "Find Alchemy Element by any of its attributes (id, name)."
15
+ argument :id, ::GraphQL::Types::ID, required: false
16
+ argument :name, ::GraphQL::Types::String, required: false
17
+ argument :exact_match, ::GraphQL::Types::Boolean, required: false, default_value: true
18
+ end
19
+ end
20
+
21
+ def alchemy_elements(only: nil, except: nil)
22
+ elements = Alchemy::Element.available
23
+ if only
24
+ elements.where(name: only)
25
+ elsif except
26
+ elements.where.not(name: except)
27
+ else
28
+ elements
29
+ end
30
+ end
31
+
32
+ def alchemy_element(attributes = {})
33
+ exact_match = attributes.delete(:exact_match)
34
+ if exact_match
35
+ Alchemy::Element.find_by(attributes)
36
+ else
37
+ conditions = attributes.flat_map do |attribute, value|
38
+ ["#{attribute} LIKE ?", "%#{sanitize_sql_like(value)}%"]
39
+ end
40
+ Alchemy::Element.where(conditions).first
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ module PageFields
6
+ def self.included(query)
7
+ query.field :alchemy_page, Alchemy::GraphQL::PageType, null: true do
8
+ description "Find Alchemy Page by any of its attributes (id, name, urlname, page_layout)."
9
+ argument :id, ::GraphQL::Types::ID, required: false
10
+ argument :name, ::GraphQL::Types::String, required: false
11
+ argument :urlname, ::GraphQL::Types::String, required: false
12
+ argument :page_layout, ::GraphQL::Types::String, required: false
13
+ argument :exact_match, ::GraphQL::Types::Boolean, required: false, default_value: true
14
+ end
15
+ end
16
+
17
+ include ActiveRecord::Sanitization::ClassMethods
18
+
19
+ def alchemy_page(attributes = {})
20
+ exact_match = attributes.delete(:exact_match)
21
+ if exact_match
22
+ Alchemy::Page.find_by(attributes)
23
+ else
24
+ conditions = attributes.flat_map do |attribute, value|
25
+ ["#{attribute} LIKE ?", "%#{sanitize_sql_like(value)}%"]
26
+ end
27
+ Alchemy::Page.where(conditions).first
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ class Query < ::GraphQL::Schema::Object
6
+ description "Query Alchemy Pages by id, name or url."
7
+
8
+ include PageFields
9
+ include ElementFields
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ class Schema < ::GraphQL::Schema
6
+ query(Alchemy::GraphQL::Query)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ class ContentType < ::GraphQL::Schema::Object
6
+ description "A Alchemy Content"
7
+
8
+ field :id, ID, null: false
9
+ field :element, Alchemy::GraphQL::ElementType, null: false
10
+ field :name, String, null: false
11
+ field :ingredient, String, null: true
12
+
13
+ def ingredient
14
+ object.serialized_ingredient
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ class ElementType < ::GraphQL::Schema::Object
6
+ description "A Alchemy Element"
7
+
8
+ field :id, ID, null: false
9
+ field :page, Alchemy::GraphQL::PageType, null: false
10
+ field :parent_element, self, null: true
11
+ field :name, String, null: false
12
+
13
+ field :contents, [Alchemy::GraphQL::ContentType], null: false do
14
+ description "Filter elements contents by their name. " \
15
+ "Either pass `only` to exclusively load Contents with this name or `except` to exclude these contents."
16
+ argument :only, String, required: false
17
+ argument :except, String, required: false
18
+ end
19
+
20
+ def contents(only: nil, except: nil)
21
+ contents = object.contents
22
+ if only
23
+ contents.where(name: only)
24
+ elsif except
25
+ contents.where.not(name: except)
26
+ else
27
+ contents
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ class PageType < ::GraphQL::Schema::Object
6
+ description "A Alchemy Page"
7
+
8
+ field :id, ID, null: false
9
+ field :name, String, null: false
10
+ field :title, String, null: false
11
+ field :urlname, String, null: false
12
+
13
+ field :elements, [Alchemy::GraphQL::ElementType], null: false do
14
+ description "Filter pages elements by their name. " \
15
+ "Either pass `only` to exclusively load Elements with this name or `except` to exclude these elements."
16
+ argument :only, String, required: false
17
+ argument :except, String, required: false
18
+ end
19
+
20
+ def elements(only: nil, except: nil)
21
+ elements = object.elements.available
22
+ if only
23
+ elements.where(name: only)
24
+ elsif except
25
+ elements.where.not(name: except)
26
+ else
27
+ elements
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module GraphQL
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alchemy-graphql
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Thomas von Deyen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: alchemy_cms
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.0.rc1
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 4.2.0.rc1
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
33
+ - !ruby/object:Gem::Dependency
34
+ name: graphql
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.9'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.9'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.8'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.8'
61
+ - !ruby/object:Gem::Dependency
62
+ name: factory_bot_rails
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '5.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '5.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: simplecov
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.17.1
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.17.1
89
+ description: Description of Alchemy::GraphQL
90
+ email:
91
+ - thomas@vondeyen.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - LICENSE
97
+ - README.md
98
+ - Rakefile
99
+ - app/controllers/alchemy/graphql_controller.rb
100
+ - config/routes.rb
101
+ - lib/alchemy-graphql.rb
102
+ - lib/alchemy/graphql.rb
103
+ - lib/alchemy/graphql/engine.rb
104
+ - lib/alchemy/graphql/fields/element_fields.rb
105
+ - lib/alchemy/graphql/fields/page_fields.rb
106
+ - lib/alchemy/graphql/query.rb
107
+ - lib/alchemy/graphql/schema.rb
108
+ - lib/alchemy/graphql/types/content_type.rb
109
+ - lib/alchemy/graphql/types/element_type.rb
110
+ - lib/alchemy/graphql/types/page_type.rb
111
+ - lib/alchemy/graphql/version.rb
112
+ homepage: https://alchemy-cms.com
113
+ licenses:
114
+ - BSD-3-Clause
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubygems_version: 3.0.3
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Alchemy::GraphQL
135
+ test_files: []