graphql-extras 0.0.0.pre.2dcd696

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
+ SHA256:
3
+ metadata.gz: 6288183977267b694bbb2b74e36674b2df79736879d60e9b5d5abb5ce4c487d4
4
+ data.tar.gz: ae68c8cc32d0fe6407c9f21ff2a9b4ee3957d06cabfa25921f14423af3e99be3
5
+ SHA512:
6
+ metadata.gz: 467b82f5a0c596ab3828157da1b3728d01a6c8332ece4a20f617c31457e33ed4298b4ffa76aa9f47ed6e537ec12af651a2d859bdc57be4e6a60edb33e16f4a09
7
+ data.tar.gz: a219844d1c1ef0a1c519fd699d18b74ef7f015776fedf1788ff2a2257c67050f07c2dd23fb2acf25705af2e71fa65cb983e7969b9db260dd681b2ad7e029eb9a
@@ -0,0 +1,25 @@
1
+ name: Build
2
+ on: [push]
3
+ jobs:
4
+ build:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - name: Checkout
8
+ uses: actions/checkout@v2
9
+
10
+ - name: Setup Ruby
11
+ uses: actions/setup-ruby@v1
12
+ with:
13
+ ruby-version: 2.6.x
14
+
15
+ - name: Install packages
16
+ run: sudo apt-get install libsqlite3-dev
17
+
18
+ - name: Install bundler
19
+ run: gem install bundler
20
+
21
+ - name: Install dependencies
22
+ run: bundle install
23
+
24
+ - name: Test
25
+ run: bundle exec rspec
@@ -0,0 +1,41 @@
1
+ name: Publish
2
+ on:
3
+ release:
4
+ types: [published]
5
+ jobs:
6
+ publish:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - name: Checkout
10
+ uses: actions/checkout@v2
11
+
12
+ - name: Setup Ruby
13
+ uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6.x
16
+
17
+ - name: Install packages
18
+ run: sudo apt-get install libsqlite3-dev
19
+
20
+ - name: Install bundler
21
+ run: gem install bundler
22
+
23
+ - name: Install dependencies
24
+ run: bundle install
25
+
26
+ - name: Test
27
+ run: bundle exec rspec
28
+
29
+ - name: Set version
30
+ run: perl -pi -e "s/0\.0\.0/${GITHUB_REF:11}/" lib/graphql/extras/version.rb
31
+
32
+ - name: Publish
33
+ run: |
34
+ mkdir -p $HOME/.gem
35
+ touch $HOME/.gem/credentials
36
+ chmod 0600 $HOME/.gem/credentials
37
+ printf -- "---\n:rubygems_api_key: ${RUBYGEMS_TOKEN}\n" > $HOME/.gem/credentials
38
+ gem build *.gemspec
39
+ gem push *.gem
40
+ env:
41
+ RUBYGEMS_TOKEN: ${{ secrets.RUBYGEMS_TOKEN }}
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ Gemfile.lock
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in graphql-extras.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,174 @@
1
+ <h1 align="center">GraphQL::Extras</h1>
2
+
3
+ <div align="center">
4
+
5
+ ![Build](https://github.com/rzane/graphql-extras/workflows/CI/badge.svg)
6
+ ![Version](https://img.shields.io/gem/v/graphql-extras)
7
+
8
+ </div>
9
+
10
+ A collection of utilities for building GraphQL APIs.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'graphql-extras'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ ## Usage
25
+
26
+ ### GraphQL::Extras::Controller
27
+
28
+ The [`graphql` gem](https://github.com/rmosolgo/graphql-ruby) will generate a controller for you with a bunch of boilerplate. This module will encapsulate that boilerplate:
29
+
30
+ ```ruby
31
+ class GraphqlController < ApplicationController
32
+ include GraphQL::Extras::Controller
33
+
34
+ def execute
35
+ graphql(schema: MySchema, context: { current_user: current_user })
36
+ end
37
+ end
38
+ ```
39
+
40
+ ### GraphQL::Extras::Batch::AssociationLoader
41
+
42
+ This is a subclass of [`GraphQL::Batch::Loader`](https://github.com/Shopify/graphql-batch) that performs eager loading of Active Record associations.
43
+
44
+ ```ruby
45
+ loader = GraphQL::Extras::Batch::AssociationLoader.for(:blog)
46
+ loader.load(Post.first)
47
+ loader.load_many(Post.all)
48
+ ```
49
+
50
+ ### GraphQL::Extras::Batch::Resolvers
51
+
52
+ This includes a set of convenience methods for query batching.
53
+
54
+ ```ruby
55
+ class Post < GraphQL::Schema::Object
56
+ include GraphQL::Extras::Batch::Resolver
57
+
58
+ field :blog, BlogType, resolve: association(:blog), null: false
59
+ field :comments, [CommentType], resolve: association(:comments, preload: { comments: :user }), null: false
60
+ field :blog_title, String, null: false
61
+
62
+ def blog_title
63
+ association(object, :blog).then(&:title)
64
+ end
65
+ end
66
+ ```
67
+
68
+ ### GraphQL::Extras::Types
69
+
70
+ In your base classes, you should include the `GraphQL::Extras::Types`.
71
+
72
+ ```ruby
73
+ class BaseObject < GraphQL::Schema::Object
74
+ include GraphQL::Extras::Types
75
+ end
76
+
77
+ class BaseInputObject < GraphQL::Schema::InputObject
78
+ include GraphQL::Extras::Types
79
+ end
80
+ ```
81
+
82
+ #### Date
83
+
84
+ This scalar takes a `Date` and transmits it as a string, using ISO 8601 format.
85
+
86
+ ```ruby
87
+ field :birthday, Date, required: true
88
+ ```
89
+
90
+ #### DateTime
91
+
92
+ This scalar takes a `DateTime` and transmits it as a string, using ISO 8601 format.
93
+
94
+ ```ruby
95
+ field :created_at, DateTime, required: true
96
+ ```
97
+
98
+ *Note: This is just an alias for the `ISO8601DateTime` type that is included in the `graphql` gem.*
99
+
100
+ #### Decimal
101
+
102
+ This scalar takes a `BigDecimal` and transmits it as a string.
103
+
104
+ ```ruby
105
+ field :weight, BigDecimal, required: true
106
+ ```
107
+
108
+ #### Upload
109
+
110
+ This scalar is used for accepting file uploads.
111
+
112
+ ```ruby
113
+ field :image, Upload, required: true
114
+ ```
115
+
116
+ It achieves this by passing in all file upload parameters through context. This will work out of the box if you're using `GraphQL::Extras::Controller`.
117
+
118
+ Here's an example using CURL:
119
+
120
+ $ curl -X POST \
121
+ -F query='mutation { uploadFile(image: "image") }' \
122
+ -F image=@cats.png \
123
+ localhost:3000/graphql
124
+
125
+ Take note of the correspondence between the value `"image"` and the additional HTTP parameter called `-F image=@cats.png`.
126
+
127
+ See [apollo-link-upload](https://github.com/rzane/apollo-link-upload) for the client-side implementation.
128
+
129
+ ### RSpec integration
130
+
131
+ Add the following to your `rails_helper.rb` (or `spec_helper.rb`).
132
+
133
+ ```ruby
134
+ require "graphql/extras/rspec"
135
+ ```
136
+
137
+ Now, you can run tests like so:
138
+
139
+ ```ruby
140
+ RSpec.describe "hello" do
141
+ let(:context) { { name: "Ray" } }
142
+ let(:schema) { use_schema(Schema, context: context) }
143
+ let(:queries) { graphql_fixture("hello.graphql") }
144
+
145
+ it "allows easily executing queries" do
146
+ result = schema.execute(queries.hello)
147
+
148
+ expect(result).to be_successful_query
149
+ expect(result['data']['hello']).to eq("world")
150
+ end
151
+ end
152
+ ```
153
+
154
+ The `graphql_fixture` method assumes that your queries live in `spec/fixtures/graphql`. You can change this assumption with the following configuration:
155
+
156
+ ```ruby
157
+ RSpec.configure do |config|
158
+ config.graphql_fixture_path = '/path/to/queries'
159
+ end
160
+ ```
161
+
162
+ ## Development
163
+
164
+ To install dependencies:
165
+
166
+ $ bundle install
167
+
168
+ To run the test suite:
169
+
170
+ $ bundle exec rspec
171
+
172
+ ## Contributing
173
+
174
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rzane/graphql-extras.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "graphql/extras"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,38 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "graphql/extras/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "graphql-extras"
7
+ spec.version = GraphQL::Extras::VERSION
8
+ spec.authors = ["Ray Zane"]
9
+ spec.email = ["raymondzane@gmail.com"]
10
+
11
+ spec.summary = %q{Utiltities for building GraphQL APIs.}
12
+ spec.description = %q{A set of modules and types for buildign GraphQL APIs.}
13
+ spec.homepage = "https://github.com/promptworks/graphql-extras"
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+ spec.metadata["source_code_uri"] = "https://github.com/promptworks/graphql-extras"
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_dependency "activesupport", ">= 5.2"
28
+ spec.add_dependency "graphql", "~> 1.9"
29
+ spec.add_dependency "graphql-batch", "~> 0.4"
30
+
31
+ spec.add_development_dependency "bundler", "~> 2.0"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency "rspec-rails", "~> 3.8"
35
+ spec.add_development_dependency "actionpack", ">= 5.2"
36
+ spec.add_development_dependency "activerecord", ">= 5.2"
37
+ spec.add_development_dependency "sqlite3", "~> 1.4"
38
+ end
@@ -0,0 +1,9 @@
1
+ require "graphql/extras/version"
2
+ require "graphql/extras/types"
3
+ require "graphql/extras/controller"
4
+ require "graphql/extras/batch"
5
+
6
+ module GraphQL
7
+ module Extras
8
+ end
9
+ end
@@ -0,0 +1,47 @@
1
+ require "graphql/batch"
2
+
3
+ module GraphQL
4
+ module Extras
5
+ module Batch
6
+ class AssociationLoader < GraphQL::Batch::Loader
7
+ def initialize(name, preload: name)
8
+ @name = name
9
+ @preload = preload
10
+ end
11
+
12
+ def cache_key(record)
13
+ record.object_id
14
+ end
15
+
16
+ def perform(records)
17
+ preloader = ActiveRecord::Associations::Preloader.new
18
+ preloader.preload(records, @preload)
19
+
20
+ records.each do |record|
21
+ fulfill(record, record.public_send(@name))
22
+ end
23
+ end
24
+ end
25
+
26
+ module Resolvers
27
+ def self.included(base)
28
+ base.extend ClassMethods
29
+ end
30
+
31
+ module ClassMethods
32
+ def association(name)
33
+ lambda do |record, _args, _ctx|
34
+ loader = AssociationLoader.for(name)
35
+ loader.load(record)
36
+ end
37
+ end
38
+ end
39
+
40
+ def association(record, name)
41
+ loader = AssociationLoader.for(name)
42
+ loader.load(record)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ module GraphQL
2
+ module Extras
3
+ module Controller
4
+ def graphql(schema:, context: {}, debug: Rails.env.development?)
5
+ query = params[:query]
6
+ operation = params[:operationName]
7
+ variables = cast_graphql_params(params[:variables])
8
+
9
+ uploads = params.to_unsafe_h.select do |_, value|
10
+ value.is_a?(ActionDispatch::Http::UploadedFile)
11
+ end
12
+
13
+ result = schema.execute(
14
+ query,
15
+ operation_name: operation,
16
+ variables: variables,
17
+ context: context.merge(uploads: uploads)
18
+ )
19
+
20
+ render(status: 200, json: result)
21
+ rescue => error
22
+ raise error unless debug
23
+
24
+ logger.error(error.message)
25
+ logger.error(error.backtrace.join("\n"))
26
+
27
+ render(
28
+ status: 500,
29
+ json: {
30
+ data: {},
31
+ error: {
32
+ message: error.message,
33
+ backtrace: error.backtrace
34
+ }
35
+ }
36
+ )
37
+ end
38
+
39
+ private def cast_graphql_params(param)
40
+ case param
41
+ when String
42
+ return {} if param.blank?
43
+ cast_graphql_params(JSON.parse(param))
44
+ when Hash, ActionController::Parameters
45
+ param
46
+ when nil
47
+ {}
48
+ else
49
+ raise ArgumentError, "Unexpected parameter: #{param}"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,133 @@
1
+ require "yaml"
2
+ require "active_support/inflector"
3
+ require "active_support/core_ext/hash"
4
+
5
+ module GraphQL
6
+ module Extras
7
+ module RSpec
8
+ class Queries
9
+ def add(key, value)
10
+ define_singleton_method(key) { value }
11
+ end
12
+ end
13
+
14
+ class Schema
15
+ def initialize(schema, context: {})
16
+ @schema = schema
17
+ @context = context
18
+ end
19
+
20
+ def execute(query, variables = {})
21
+ variables = deep_camelize_keys(variables)
22
+ variables, uploads = extract_uploads(variables)
23
+ context = @context.merge(uploads: uploads)
24
+
25
+ result = @schema.execute(query, variables: variables, context: context)
26
+ result.to_h
27
+ end
28
+
29
+ private
30
+
31
+ def extract_uploads(variables)
32
+ uploads = {}
33
+ variables = deep_transform_values(variables) { |value|
34
+ if upload?(value)
35
+ SecureRandom.hex.tap { |key| uploads.merge!(key => value) }
36
+ else
37
+ value
38
+ end
39
+ }
40
+
41
+ [variables, uploads]
42
+ end
43
+
44
+ def deep_camelize_keys(variables)
45
+ variables.deep_transform_keys { |key| key.to_s.camelize(:lower) }
46
+ end
47
+
48
+ def deep_transform_values(data, &block)
49
+ case data
50
+ when Array
51
+ data.map { |v| deep_transform_values(v, &block) }
52
+ when Hash
53
+ data.transform_values { |v| deep_transform_values(v, &block) }
54
+ else
55
+ yield data
56
+ end
57
+ end
58
+
59
+ def upload?(value)
60
+ value.respond_to?(:tempfile) && value.respond_to?(:original_filename)
61
+ end
62
+ end
63
+
64
+ class Parser
65
+ include ::GraphQL::Language
66
+
67
+ def initialize(document)
68
+ @operations = document.definitions
69
+ .grep(Nodes::OperationDefinition)
70
+
71
+ @fragments = document.definitions
72
+ .grep(Nodes::FragmentDefinition)
73
+ .reduce({}) { |acc, f| acc.merge(f.name => f) }
74
+ end
75
+
76
+ def parse
77
+ queries = Queries.new
78
+ printer = Printer.new
79
+
80
+ @operations.each do |op|
81
+ nodes = [op, *find_fragments(op)]
82
+ nodes = nodes.map { |node| printer.print(node) }
83
+ queries.add op.name.underscore, nodes.join
84
+ end
85
+
86
+ queries
87
+ end
88
+
89
+ private
90
+
91
+ def find_fragments(node)
92
+ node.selections.flat_map do |field|
93
+ if field.is_a? Nodes::FragmentSpread
94
+ fragment = @fragments.fetch(field.name)
95
+ [fragment, *find_fragments(fragment)]
96
+ else
97
+ find_fragments(field)
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ def graphql_fixture(filename)
104
+ root = ::RSpec.configuration.graphql_fixture_path
105
+ file = File.join(root, filename)
106
+ document = ::GraphQL.parse_file(file)
107
+ parser = Parser.new(document)
108
+ parser.parse
109
+ end
110
+
111
+ def use_schema(*args)
112
+ Schema.new(*args)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ RSpec::Matchers.define :be_successful_query do
119
+ match do |result|
120
+ result['errors'].nil?
121
+ end
122
+
123
+ failure_message do |result|
124
+ errors = result['errors'].map(&:deep_stringify_keys)
125
+ message = "expected query to be successful, but encountered errors:\n"
126
+ message + errors.to_yaml.lines.drop(1).join.indent(2)
127
+ end
128
+ end
129
+
130
+ RSpec.configure do |config|
131
+ config.add_setting :graphql_fixture_path, default: "spec/fixtures/graphql"
132
+ config.include GraphQL::Extras::RSpec, type: :graphql
133
+ end
@@ -0,0 +1,69 @@
1
+ require "date"
2
+ require "bigdecimal"
3
+ require "graphql"
4
+
5
+ module GraphQL
6
+ module Extras
7
+ module Types
8
+ class DateTime < GraphQL::Types::ISO8601DateTime
9
+ description <<~DESC
10
+ The `DateTime` scalar type represents a date and time in the UTC
11
+ timezone. The DateTime appears in a JSON response as an ISO8601 formatted
12
+ string, including UTC timezone ("Z"). The parsed date and time string will
13
+ be converted to UTC and any UTC offset other than 0 will be rejected.
14
+ DESC
15
+ end
16
+
17
+ class Date < GraphQL::Schema::Scalar
18
+ description <<~DESC
19
+ The `Date` scalar type represents a date. The Date appears in a JSON
20
+ response as an ISO8601 formatted string.
21
+ DESC
22
+
23
+ def self.coerce_input(value, _context)
24
+ ::Date.iso8601(value)
25
+ rescue ArgumentError
26
+ nil
27
+ end
28
+
29
+ def self.coerce_result(value, _context)
30
+ value.iso8601
31
+ end
32
+ end
33
+
34
+ class Decimal < GraphQL::Schema::Scalar
35
+ description <<~DESC
36
+ The `Decimal` scalar type represents signed double-precision fractional
37
+ values parsed by the `Decimal` library. The Decimal appears in a JSON
38
+ response as a string to preserve precision.
39
+ DESC
40
+
41
+ def self.coerce_input(value, _context)
42
+ BigDecimal(value.to_s)
43
+ rescue ArgumentError
44
+ nil
45
+ end
46
+
47
+ def self.coerce_result(value, _context)
48
+ value.to_s("F")
49
+ end
50
+ end
51
+
52
+ class Upload < GraphQL::Schema::Scalar
53
+ description "Represents an uploaded file."
54
+
55
+ def self.coerce_input(value, context)
56
+ return nil if value.nil?
57
+
58
+ uploads = context.fetch(:uploads) {
59
+ raise "Expected context to include a hash of uploads."
60
+ }
61
+
62
+ uploads.fetch(value) do
63
+ raise GraphQL::CoercionError, "No upload named `#{value}` provided."
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,5 @@
1
+ module GraphQL
2
+ module Extras
3
+ VERSION = "0.0.0.pre.2dcd696"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphql-extras
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.pre.2dcd696
5
+ platform: ruby
6
+ authors:
7
+ - Ray Zane
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-05-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: graphql
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: graphql-batch
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.8'
111
+ - !ruby/object:Gem::Dependency
112
+ name: actionpack
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '5.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '5.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activerecord
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '5.2'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '5.2'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.4'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.4'
153
+ description: A set of modules and types for buildign GraphQL APIs.
154
+ email:
155
+ - raymondzane@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".github/workflows/build.yml"
161
+ - ".github/workflows/publish.yml"
162
+ - ".gitignore"
163
+ - ".rspec"
164
+ - Gemfile
165
+ - README.md
166
+ - Rakefile
167
+ - bin/console
168
+ - bin/setup
169
+ - graphql-extras.gemspec
170
+ - lib/graphql/extras.rb
171
+ - lib/graphql/extras/batch.rb
172
+ - lib/graphql/extras/controller.rb
173
+ - lib/graphql/extras/rspec.rb
174
+ - lib/graphql/extras/types.rb
175
+ - lib/graphql/extras/version.rb
176
+ homepage: https://github.com/promptworks/graphql-extras
177
+ licenses: []
178
+ metadata:
179
+ homepage_uri: https://github.com/promptworks/graphql-extras
180
+ source_code_uri: https://github.com/promptworks/graphql-extras
181
+ post_install_message:
182
+ rdoc_options: []
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ required_rubygems_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">"
193
+ - !ruby/object:Gem::Version
194
+ version: 1.3.1
195
+ requirements: []
196
+ rubygems_version: 3.0.3
197
+ signing_key:
198
+ specification_version: 4
199
+ summary: Utiltities for building GraphQL APIs.
200
+ test_files: []