graphql-rails 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8386088857c27bbcdea43d4891771e8bea89e8f7
4
+ data.tar.gz: 2bedc9fc92d44483612f9253df2dfde7ce2f8973
5
+ SHA512:
6
+ metadata.gz: df543107f1fa308fb2228f7951b70ac28c263f0aea93024d121dfcf093d75e515b146bd71655fc0e6e23beb548924d28c7700284833c3f8725b4c573c8c2eec7
7
+ data.tar.gz: 06057d2317334ed33e8a16e4f7f35e9b6f8209c2f8207ae03c57421a1f28a3b076879f2fd924e74ac76828caf07b6c875b1feae2b8de7efd32d5545cc12f05b2
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 James Reggio <james.reggio@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ module GraphQL
2
+ module Rails
3
+ class SchemaController < ActionController::Base
4
+ include ControllerExtensions
5
+ rescue_from Exception, :with => :internal_error
6
+ rescue_from GraphQL::ParseError, :with => :invalid_query
7
+ rescue_from JSON::ParserError, :with => :invalid_variables
8
+
9
+ def execute
10
+ query_string = params[:query]
11
+ query_variables = to_hash(params[:variables])
12
+ render json: Schema.instance.execute(
13
+ query_string,
14
+ variables: query_variables,
15
+ context: context,
16
+ debug: true
17
+ )
18
+ end
19
+
20
+ private
21
+
22
+ def context
23
+ @context ||= {}
24
+ end
25
+
26
+ def to_hash(param)
27
+ if param.blank?
28
+ {}
29
+ elsif param.is_a?(String)
30
+ JSON.parse(param)
31
+ else
32
+ param
33
+ end
34
+ end
35
+
36
+ def render_error(status, message)
37
+ render json: {
38
+ :errors => [{:message => message}],
39
+ }, :status => status
40
+ end
41
+
42
+ def invalid_request(message)
43
+ render_error 400, message
44
+ end
45
+
46
+ def invalid_query
47
+ invalid_request 'Unable to parse query'
48
+ end
49
+
50
+ def invalid_variables
51
+ invalid_request 'Unable to parse variables'
52
+ end
53
+
54
+ def internal_error
55
+ render_error 500, 'Internal error'
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1 @@
1
+ GraphiQL::Rails.config.csrf = true
data/config/routes.rb ADDED
@@ -0,0 +1,12 @@
1
+ module GraphQL
2
+ module Rails
3
+ Engine.routes.draw do
4
+ if Rails.config.graphiql
5
+ # Empty :graphql_path will cause GraphiQL to use its own URL.
6
+ mount GraphiQL::Rails::Engine => '/', :graphql_path => ''
7
+ end
8
+
9
+ post '/' => 'schema#execute'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails'
2
+ require 'graphql'
3
+ require 'graphql/relay'
4
+ require 'graphiql/rails'
5
+
6
+ require 'graphql/rails/version'
7
+ require 'graphql/rails/dsl'
8
+ require 'graphql/rails/engine'
9
+ require 'graphql/rails/config'
10
+ require 'graphql/rails/config'
11
+ require 'graphql/rails/types'
12
+ require 'graphql/rails/node_identification'
13
+ require 'graphql/rails/controller_extensions'
14
+ require 'graphql/rails/schema'
15
+ require 'graphql/rails/callbacks'
16
+ require 'graphql/rails/operations'
@@ -0,0 +1,49 @@
1
+ module GraphQL
2
+ module Rails
3
+ class Operations
4
+ module Callbacks
5
+ extend ActiveSupport::Concern
6
+ include ActiveSupport::Callbacks
7
+
8
+ included do
9
+ define_callbacks :perform_operation
10
+ end
11
+
12
+ module ClassMethods
13
+ [:before, :after, :around].each do |callback|
14
+ define_method "#{callback}_operation" do |*names, &blk|
15
+ insert_callbacks(names, blk) do |name, options|
16
+ set_callback(:perform_operation, callback, name, options)
17
+ end
18
+ end
19
+ alias_method :"#{callback}_filter", :"#{callback}_operation"
20
+ end
21
+
22
+ private
23
+
24
+ def normalize_callback_options(options)
25
+ normalize_callback_option(options, :only, :if)
26
+ normalize_callback_option(options, :except, :unless)
27
+ end
28
+
29
+ def normalize_callback_option(options, from, to)
30
+ return unless options[from]
31
+ check = -> do
32
+ Array(options[from]).find { |operation| name == operation }
33
+ end
34
+ options[to] = Array(options[to]) + [check]
35
+ end
36
+
37
+ def insert_callbacks(callbacks, block = nil)
38
+ options = callbacks.extract_options!
39
+ normalize_callback_options(options)
40
+ callbacks.push(block) if block
41
+ callbacks.each do |callback|
42
+ yield callback, options
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ module GraphQL
2
+ module Rails
3
+ extend self
4
+
5
+ def configure
6
+ yield config
7
+ end
8
+
9
+ def config
10
+ @config ||= OpenStruct.new({
11
+ # Should the GraphiQL web interface be served?
12
+ :graphiql => ::Rails.env.development?,
13
+
14
+ # Should names be converted to lowerCamelCase per GraphQL convention?
15
+ # For example, should :get_user_tasks become 'getUserTasks'?
16
+ :camel_case => true,
17
+
18
+ # Should object IDs be globally unique?
19
+ # This is necessary to conform to the Relay Global Object ID spec.
20
+ :global_ids => true,
21
+
22
+ # Should the following extensions be loaded?
23
+ :mongoid => defined?(::Mongoid),
24
+ :cancan => defined?(::CanCan),
25
+ })
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ module GraphQL
2
+ module Rails
3
+ module ControllerExtensions
4
+ extend self
5
+
6
+ def add(&block)
7
+ callbacks.push block
8
+ end
9
+
10
+ def included(base)
11
+ callbacks.each do |callback|
12
+ base.class_eval(&callback)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def callbacks
19
+ @callbacks ||= []
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module GraphQL
2
+ module Rails
3
+ class DSL < BasicObject
4
+ def run(&block)
5
+ @self = eval('self', block.binding)
6
+ instance_eval(&block)
7
+ end
8
+
9
+ def method_missing(method, *args, &block)
10
+ begin
11
+ @self.send(method, *args, &block)
12
+ rescue
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,68 @@
1
+ # Inflections must be added before the namespace is isolated, because the
2
+ # namespace's route prefix is calculated and cached at that time.
3
+ ActiveSupport::Inflector.inflections do |inflect|
4
+ inflect.acronym 'GraphQL'
5
+ end
6
+
7
+ module GraphQL
8
+ module Rails
9
+ mattr_accessor :logger
10
+
11
+ class Engine < ::Rails::Engine
12
+ isolate_namespace GraphQL::Rails
13
+
14
+ initializer 'graphql-rails.autoload', :before => :set_autoload_paths do |app|
15
+ # Even though we aren't using symbolic autoloading of operations, they
16
+ # must be included in autoload_paths in order to be unloaded during
17
+ # reload operations.
18
+ @graph_path = app.root.join('app', 'graph')
19
+ app.config.autoload_paths += [
20
+ @graph_path.join('types'),
21
+ @graph_path.join('operations'),
22
+ ]
23
+ end
24
+
25
+ initializer 'graphql-rails.logger', :after => :initialize_logger do |app|
26
+ logger = ::Rails.logger.clone
27
+ logger.class_eval do
28
+ def exception(e)
29
+ begin
30
+ error "#{e.class.name} (#{e.message}):"
31
+ error " #{e.backtrace.join("\n ")}"
32
+ rescue
33
+ end
34
+ end
35
+ end
36
+ Rails.logger = logger
37
+ Rails.logger.debug 'Initialized logger'
38
+ end
39
+
40
+ initializer 'graphql-rails.extensions', :after => :load_config_initializers do |app|
41
+ # These depend upon a loaded Rails app, so we load them dynamically.
42
+ extensions = File.join(File.dirname(__FILE__), 'extensions', '*.rb')
43
+ Dir[extensions].each do |file|
44
+ require file
45
+ end
46
+ end
47
+
48
+ initializer 'graphql-rails.prepare', :before => :add_to_prepare_blocks do
49
+ # The block executes in the context of the reloader, so we have to
50
+ # preserve a reference to the engine instance.
51
+ engine = self
52
+ config.to_prepare_blocks.push -> do
53
+ engine.reload!
54
+ end
55
+ end
56
+
57
+ def reload!
58
+ Types.clear
59
+ Schema.clear
60
+ Rails.logger.debug 'Loading operations'
61
+ Dir[@graph_path.join('operations', '**', '*.rb')].each do |file|
62
+ Rails.logger.debug "Loading file: #{file}"
63
+ require_dependency file
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,50 @@
1
+ module GraphQL
2
+ module Rails
3
+ if Rails.config.cancan
4
+ Rails.logger.debug 'Loading CanCan extensions'
5
+
6
+ Operations.class_eval do
7
+ extend Forwardable
8
+ def_delegators :current_ability, :can?, :cannot?
9
+
10
+ def self.check_authorization(options = {})
11
+ self.after_filter(options.slice(:only, :except)) do |instance|
12
+ next if instance.instance_variable_defined?(:@authorized)
13
+ next if options[:if] && !instance.send(options[:if])
14
+ next if options[:unless] && instance.send(options[:unless])
15
+ raise 'This operation failed to perform an authorization check'
16
+ end
17
+ end
18
+
19
+ def skip_authorization_check(*args)
20
+ self.before_filter(*args) do |instance|
21
+ instance.instance_variable_set(:@authorized, true)
22
+ end
23
+ end
24
+
25
+ def authorize!(*args)
26
+ begin
27
+ @authorized = true
28
+ current_ability.authorize!(*args)
29
+ rescue CanCan::AccessDenied
30
+ raise 'You are not authorized to perform this operation'
31
+ end
32
+ end
33
+
34
+ def current_ability
35
+ @current_ability ||= ::Ability.new(current_user)
36
+ end
37
+
38
+ def current_user
39
+ ctx[:current_user]
40
+ end
41
+ end
42
+
43
+ ControllerExtensions.add do
44
+ before_filter do
45
+ context[:current_user] = current_user
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,96 @@
1
+ module GraphQL
2
+ module Rails
3
+ if Rails.config.mongoid
4
+ Rails.logger.debug 'Loading Mongoid extensions'
5
+
6
+ GraphQL::Relay::BaseConnection.register_connection_implementation(
7
+ ::Mongoid::Relations::Targets::Enumerable,
8
+ GraphQL::Relay::RelationConnection
9
+ )
10
+
11
+ module Mongoid
12
+ extend self
13
+
14
+ NAMESPACE = 'MG'
15
+
16
+ def clear
17
+ @types = nil
18
+ end
19
+
20
+ def resolve(type)
21
+ types[type] || build_type(type)
22
+ end
23
+
24
+ def lookup(type_name, id)
25
+ return if Types.use_namespaces? && !type_name.starts_with?(NAMESPACE)
26
+ types.each_pair do |type, graph_type|
27
+ return type.find(id) if graph_type.name == type_name
28
+ end
29
+ nil
30
+ end
31
+
32
+ private
33
+
34
+ def types
35
+ @types ||= {
36
+ ::Mongoid::Boolean => GraphQL::BOOLEAN_TYPE,
37
+ BSON::ObjectId => GraphQL::STRING_TYPE,
38
+ }
39
+ end
40
+
41
+ def build_type(type)
42
+ return nil unless type.included_modules.include?(::Mongoid::Document)
43
+ Rails.logger.debug "Building Mongoid::Document type: #{type.name}"
44
+
45
+ # TODO: Support parent types/interfaces.
46
+ type_name = to_name(type)
47
+ types[type] = GraphQL::ObjectType.define do
48
+ name type_name
49
+
50
+ if Rails.config.global_ids
51
+ interfaces [NodeIdentification.interface]
52
+ global_id_field :id
53
+ end
54
+
55
+ type.fields.each_value do |field_value|
56
+ field field_value.name do
57
+ type -> { Types.resolve(field_value.type) }
58
+ description field_value.label unless field_value.label.blank?
59
+ end
60
+ end
61
+
62
+ type.relations.each_value do |relationship|
63
+ # TODO: Add polymorphic support.
64
+ if relationship.polymorphic?
65
+ Rails.logger.warn(
66
+ "Skipping polymorphic relationship: #{relationship.name}"
67
+ )
68
+ next
69
+ end
70
+
71
+ if relationship.many?
72
+ connection relationship.name do
73
+ type -> { Types.resolve(relationship.klass).connection_type }
74
+ end
75
+ else
76
+ field relationship.name do
77
+ type -> { Types.resolve(relationship.klass) }
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def to_name(type)
85
+ if Types.use_namespaces?
86
+ NAMESPACE + type.name
87
+ else
88
+ type.name
89
+ end
90
+ end
91
+ end
92
+
93
+ Types.add_extension Mongoid
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,13 @@
1
+ module GraphQL
2
+ module Rails
3
+ NodeIdentification = GraphQL::Relay::GlobalNodeIdentification.define do
4
+ object_from_id -> (id, ctx) do
5
+ Types.lookup(*NodeIdentification.from_global_id(id))
6
+ end
7
+
8
+ type_from_object -> (obj) do
9
+ Types.resolve(obj.class)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,100 @@
1
+ module GraphQL
2
+ module Rails
3
+ class Operations
4
+ extend Forwardable
5
+ include Callbacks
6
+
7
+ def initialize(options = {})
8
+ @options = OpenStruct.new(options)
9
+ self.class.instance_eval do
10
+ def_delegators :@options, *options.keys
11
+ end
12
+ end
13
+
14
+ def self.query(hash, &block)
15
+ hash = extract_pair(hash)
16
+ Rails.logger.debug "Adding query: #{to_name(hash[:name])}"
17
+
18
+ definition = QueryDefinition.new(self)
19
+ definition.run(&block)
20
+ definition.run do
21
+ name hash[:name]
22
+ type hash[:type]
23
+ end
24
+ Schema.add_query definition.field
25
+ end
26
+
27
+ # TODO: Implement mutations and subscriptions.
28
+ # TODO: Implement model functions (only, exclude, rename, etc.)
29
+
30
+ private
31
+
32
+ def self.extract_pair(hash)
33
+ unless hash.length == 1
34
+ raise 'Hash must contain a single :name => Type pair.'
35
+ end
36
+ {name: hash.keys.first, type: hash.values.first}
37
+ end
38
+
39
+ # TODO: Ensure consistent naming convention around everything.
40
+ def self.to_name(symbol)
41
+ if Rails.config.camel_case
42
+ symbol.to_s.camelize(:lower)
43
+ else
44
+ symbol.to_s
45
+ end
46
+ end
47
+
48
+ class QueryDefinition < DSL
49
+ attr_reader :field
50
+
51
+ def initialize(klass)
52
+ @klass = klass
53
+ @field = ::GraphQL::Field.new
54
+ end
55
+
56
+ def name(name)
57
+ @name = name
58
+ @field.name = to_name(name)
59
+ end
60
+
61
+ def type(type)
62
+ @type = type
63
+ @field.type = Types.resolve(type)
64
+ end
65
+
66
+ def description(description)
67
+ @field.description = description
68
+ end
69
+
70
+ def argument(name, type, required = false)
71
+ argument = ::GraphQL::Argument.new
72
+ argument.name = to_name(name)
73
+ argument.type = Types.resolve(type, required == :required)
74
+ @field.arguments[argument.name] = argument
75
+ end
76
+
77
+ def resolve(&block)
78
+ field.resolve = -> (obj, args, ctx) do
79
+ instance = @klass.new({
80
+ op: :query, name: @name, type: @type,
81
+ obj: obj, args: args, ctx: ctx
82
+ })
83
+
84
+ begin
85
+ instance.run_callbacks(:perform_operation) do
86
+ instance.instance_eval(&block)
87
+ end
88
+ rescue => e
89
+ ::GraphQL::ExecutionError.new(e.message)
90
+ rescue ::Exception => e
91
+ Rails.logger.error "Unexpected exception during query: #{@name}"
92
+ Rails.logger.exception e
93
+ ::GraphQL::ExecutionError.new('Internal error')
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,44 @@
1
+ module GraphQL
2
+ module Rails
3
+ module Schema
4
+ extend self
5
+
6
+ def clear
7
+ @schema = nil
8
+ @fields = Hash.new { |hash, key| hash[key] = [] }
9
+ end
10
+
11
+ TYPES = [:query, :mutation, :subscription]
12
+
13
+ TYPES.each do |type|
14
+ define_method "add_#{type.to_s}" do |field|
15
+ @schema = nil # Invalidate cached schema.
16
+ @fields[type].push field
17
+ end
18
+ end
19
+
20
+ def instance
21
+ # TODO: Support max_depth and types.
22
+ # TODO: Sweep available options and expose in config.
23
+ @schema ||= GraphQL::Schema.new begin
24
+ TYPES.reduce({}) do |schema, type|
25
+ fields = @fields[type]
26
+ unless fields.empty?
27
+ schema[type] = GraphQL::ObjectType.define do
28
+ name type.to_s.capitalize
29
+ description "Root #{type.to_s} for this schema"
30
+ fields.each do |value|
31
+ field value.name, field: value
32
+ end
33
+ if Rails.config.global_ids && type == :query
34
+ field :node, field: NodeIdentification.field
35
+ end
36
+ end
37
+ end
38
+ schema
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,92 @@
1
+ module GraphQL
2
+ module Rails
3
+ module Types
4
+ extend self
5
+
6
+ def clear
7
+ @types = nil
8
+ extensions.each do |extension|
9
+ extension.clear
10
+ end
11
+ end
12
+
13
+ # Resolve an arbitrary type to a GraphQL type.
14
+ def resolve(type, required = false)
15
+ if type.nil?
16
+ raise 'Cannot resolve nil type.'
17
+ elsif required
18
+ resolve(type).to_non_null_type
19
+ elsif type.is_a?(GraphQL::BaseType)
20
+ type
21
+ elsif type.is_a?(Array)
22
+ unless type.length == 1
23
+ raise 'Lists must be specified with single-element arrays.'
24
+ end
25
+ resolve(type.first).to_list_type
26
+ elsif types.include?(type)
27
+ resolve(types[type])
28
+ else
29
+ resolve(try_extensions(:resolve, type) || begin
30
+ # TODO: Remove this hack.
31
+ Rails.logger.warn "Unable to resolve type: #{type.name}"
32
+ String
33
+ end)
34
+ end
35
+ end
36
+
37
+ # Lookup an arbitrary object from its GraphQL type name and ID.
38
+ def lookup(type_name, id)
39
+ try_extensions(:lookup, type_name, id)
40
+ end
41
+
42
+ # Should extensions namespace their type names?
43
+ # This is necessary if multiple extensions are loaded, so as to avoid
44
+ # collisions in the shared type namespace.
45
+ def use_namespaces?
46
+ extensions.count > 1
47
+ end
48
+
49
+ # Add an extension to the type system.
50
+ # Generally, each ORM will have its own extension.
51
+ def add_extension(extension)
52
+ extensions.push extension
53
+ end
54
+
55
+ private
56
+
57
+ # Default mapping of built-in scalar types to GraphQL types.
58
+ def types
59
+ @types ||= {
60
+ String => GraphQL::STRING_TYPE,
61
+ Boolean => GraphQL::BOOLEAN_TYPE,
62
+
63
+ Fixnum => GraphQL::INT_TYPE,
64
+ Integer => GraphQL::INT_TYPE,
65
+ Float => GraphQL::FLOAT_TYPE,
66
+
67
+ Date => GraphQL::STRING_TYPE,
68
+ Time => GraphQL::STRING_TYPE,
69
+ DateTime => GraphQL::STRING_TYPE,
70
+
71
+ Array => GraphQL::STRING_TYPE,
72
+ Object => GraphQL::STRING_TYPE,
73
+ Hash => GraphQL::STRING_TYPE,
74
+ }
75
+ end
76
+
77
+ def extensions
78
+ @extensions ||= []
79
+ end
80
+
81
+ # Try a function on each extension, and return the result from
82
+ # the first extension that returns a non-nil value.
83
+ def try_extensions(method, *args, &block)
84
+ extensions.each do |extension|
85
+ result = extension.send(method, *args, &block)
86
+ return result unless result.nil?
87
+ end
88
+ nil
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,5 @@
1
+ module GraphQL
2
+ module Rails
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :graphql_rails do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphql-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Reggio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: graphql
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.13'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: graphql-relay
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: graphiql-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ description: |
70
+ Zero-configuration GraphQL + Relay support for Rails.
71
+
72
+ - Adds a route to process GraphQL operations.
73
+ - Provides a visual editor (GraphiQL) for development.
74
+ - Allows you to specify GraphQL queries and mutations as though they were controller actions.
75
+ - Automatically maps Mongoid models to GraphQL types.
76
+ - Seamlessly integrates with CanCan.
77
+ email:
78
+ - james.reggio@gmail.com
79
+ executables: []
80
+ extensions: []
81
+ extra_rdoc_files: []
82
+ files:
83
+ - app/controllers/graphql/rails/schema_controller.rb
84
+ - config/initializers/graphiql.rb
85
+ - config/routes.rb
86
+ - lib/graphql/rails/callbacks.rb
87
+ - lib/graphql/rails/config.rb
88
+ - lib/graphql/rails/controller_extensions.rb
89
+ - lib/graphql/rails/dsl.rb
90
+ - lib/graphql/rails/engine.rb
91
+ - lib/graphql/rails/extensions/cancan.rb
92
+ - lib/graphql/rails/extensions/mongoid.rb
93
+ - lib/graphql/rails/node_identification.rb
94
+ - lib/graphql/rails/operations.rb
95
+ - lib/graphql/rails/schema.rb
96
+ - lib/graphql/rails/types.rb
97
+ - lib/graphql/rails/version.rb
98
+ - lib/graphql/rails.rb
99
+ - lib/tasks/graphql_rails_tasks.rake
100
+ - LICENSE
101
+ homepage: https://github.com/jamesreggio/graphql-rails
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.0.14.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Zero-configuration GraphQL + Relay support for Rails
125
+ test_files: []