graphql-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []