graphql-extras 0.0.0.pre.a203950 → 0.1.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.
- checksums.yaml +4 -4
- data/.travis.yml +7 -0
- data/README.md +2 -37
- data/graphql-extras.gemspec +3 -6
- data/lib/graphql/extras.rb +0 -1
- data/lib/graphql/extras/rspec.rb +16 -46
- data/lib/graphql/extras/types.rb +2 -17
- data/lib/graphql/extras/version.rb +1 -1
- metadata +20 -62
- data/.github/workflows/ci.yml +0 -64
- data/lib/graphql/extras/batch.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af222a7b889067dc013a2977240488cfd959304259703de9fb34d7328ddf98a7
|
4
|
+
data.tar.gz: 2fa4149a0e8eaa432fb7db727360869e606bf48186f0b1acdfb3ab67c11b51de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cda3663a3228dcd49aa4d50760a806f32588c025857e2dffc2860fe8997d079ae4c120dae42ee591cb720fecc88693e62fb9fc115e89fe61ed3664809196ae45
|
7
|
+
data.tar.gz: 86f9c22c8ef9efba9a316070e85217654f27bc7712772d3ba6f262001806e1e56444ea45ce6746586a68c6e2f0f7dfec1b27b6139cfd0bb8f429e952a1c78020
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,11 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
<div align="center">
|
4
|
-
|
5
|
-

|
6
|
-

|
7
|
-
|
8
|
-
</div>
|
1
|
+
# GraphQL::Extras [](https://travis-ci.org/rzane/graphql-extras)
|
9
2
|
|
10
3
|
A collection of utilities for building GraphQL APIs.
|
11
4
|
|
@@ -37,34 +30,6 @@ class GraphqlController < ApplicationController
|
|
37
30
|
end
|
38
31
|
```
|
39
32
|
|
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
33
|
### GraphQL::Extras::Types
|
69
34
|
|
70
35
|
In your base classes, you should include the `GraphQL::Extras::Types`.
|
@@ -124,7 +89,7 @@ Here's an example using CURL:
|
|
124
89
|
|
125
90
|
Take note of the correspondence between the value `"image"` and the additional HTTP parameter called `-F image=@cats.png`.
|
126
91
|
|
127
|
-
See [apollo-
|
92
|
+
See [apollo-absinthe-upload-link](https://github.com/bytewitchcraft/apollo-absinthe-upload-link) for the client-side implementation.
|
128
93
|
|
129
94
|
### RSpec integration
|
130
95
|
|
data/graphql-extras.gemspec
CHANGED
@@ -24,15 +24,12 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
-
spec.add_dependency "activesupport", "
|
28
|
-
spec.add_dependency "graphql", "~> 1.9"
|
29
|
-
spec.add_dependency "graphql-batch", "~> 0.4"
|
27
|
+
spec.add_dependency "activesupport", "~> 5.2"
|
30
28
|
|
31
29
|
spec.add_development_dependency "bundler", "~> 2.0"
|
32
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
33
31
|
spec.add_development_dependency "rspec", "~> 3.0"
|
32
|
+
spec.add_development_dependency "graphql", "~> 1.9"
|
34
33
|
spec.add_development_dependency "rspec-rails", "~> 3.8"
|
35
|
-
spec.add_development_dependency "actionpack", "
|
36
|
-
spec.add_development_dependency "activerecord", ">= 5.2"
|
37
|
-
spec.add_development_dependency "sqlite3", "~> 1.4"
|
34
|
+
spec.add_development_dependency "actionpack", "~> 5.2"
|
38
35
|
end
|
data/lib/graphql/extras.rb
CHANGED
data/lib/graphql/extras/rspec.rb
CHANGED
@@ -6,8 +6,10 @@ module GraphQL
|
|
6
6
|
module Extras
|
7
7
|
module RSpec
|
8
8
|
class Queries
|
9
|
-
def
|
10
|
-
|
9
|
+
def initialize(values)
|
10
|
+
values.each do |key, value|
|
11
|
+
define_singleton_method(key) { value }
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
@@ -48,9 +50,9 @@ module GraphQL
|
|
48
50
|
def deep_transform_values(data, &block)
|
49
51
|
case data
|
50
52
|
when Array
|
51
|
-
data.map { |v|
|
53
|
+
data.map { |v| deep_transform(v, &block) }
|
52
54
|
when Hash
|
53
|
-
data.transform_values { |v|
|
55
|
+
data.transform_values { |v| deep_transform(v, &block) }
|
54
56
|
else
|
55
57
|
yield data
|
56
58
|
end
|
@@ -61,51 +63,19 @@ module GraphQL
|
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
64
|
-
|
65
|
-
|
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
|
66
|
+
def graphql_fixture(filename)
|
67
|
+
root = ::RSpec.configuration.graphql_fixture_path
|
68
|
+
contents = File.read(File.join(root, filename))
|
88
69
|
|
89
|
-
|
70
|
+
parts = contents.split(/^(?=fragment|query|mutation)/)
|
71
|
+
queries, fragments = parts.partition { |query| query !~ /^fragment/ }
|
90
72
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
[fragment, *find_fragments(fragment)]
|
96
|
-
else
|
97
|
-
find_fragments(field)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
73
|
+
result = queries.reduce({}) { |acc, query|
|
74
|
+
name = query.split(/\W+/).at(1).underscore.to_sym
|
75
|
+
acc.merge(name => [*fragments, query].join)
|
76
|
+
}
|
102
77
|
|
103
|
-
|
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
|
78
|
+
Queries.new(result)
|
109
79
|
end
|
110
80
|
|
111
81
|
def use_schema(*args)
|
data/lib/graphql/extras/types.rb
CHANGED
@@ -6,19 +6,10 @@ module GraphQL
|
|
6
6
|
module Extras
|
7
7
|
module Types
|
8
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
9
|
end
|
16
10
|
|
17
11
|
class Date < GraphQL::Schema::Scalar
|
18
|
-
description
|
19
|
-
The `Date` scalar type represents a date. The Date appears in a JSON
|
20
|
-
response as an ISO8601 formatted string.
|
21
|
-
DESC
|
12
|
+
description "An ISO 8601-encoded date"
|
22
13
|
|
23
14
|
def self.coerce_input(value, _context)
|
24
15
|
::Date.iso8601(value)
|
@@ -32,11 +23,7 @@ module GraphQL
|
|
32
23
|
end
|
33
24
|
|
34
25
|
class Decimal < GraphQL::Schema::Scalar
|
35
|
-
description
|
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
|
26
|
+
description "A decimal"
|
40
27
|
|
41
28
|
def self.coerce_input(value, _context)
|
42
29
|
BigDecimal(value.to_s)
|
@@ -50,8 +37,6 @@ module GraphQL
|
|
50
37
|
end
|
51
38
|
|
52
39
|
class Upload < GraphQL::Schema::Scalar
|
53
|
-
description "Represents an uploaded file."
|
54
|
-
|
55
40
|
def self.coerce_input(value, context)
|
56
41
|
return nil if value.nil?
|
57
42
|
|
metadata
CHANGED
@@ -1,57 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-extras
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ray Zane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
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
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
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'
|
19
|
+
version: '5.2'
|
48
20
|
type: :runtime
|
49
21
|
prerelease: false
|
50
22
|
version_requirements: !ruby/object:Gem::Requirement
|
51
23
|
requirements:
|
52
24
|
- - "~>"
|
53
25
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
26
|
+
version: '5.2'
|
55
27
|
- !ruby/object:Gem::Dependency
|
56
28
|
name: bundler
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,61 +67,47 @@ dependencies:
|
|
95
67
|
- !ruby/object:Gem::Version
|
96
68
|
version: '3.0'
|
97
69
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
70
|
+
name: graphql
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
100
72
|
requirements:
|
101
73
|
- - "~>"
|
102
74
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
75
|
+
version: '1.9'
|
104
76
|
type: :development
|
105
77
|
prerelease: false
|
106
78
|
version_requirements: !ruby/object:Gem::Requirement
|
107
79
|
requirements:
|
108
80
|
- - "~>"
|
109
81
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
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'
|
82
|
+
version: '1.9'
|
125
83
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
84
|
+
name: rspec-rails
|
127
85
|
requirement: !ruby/object:Gem::Requirement
|
128
86
|
requirements:
|
129
|
-
- - "
|
87
|
+
- - "~>"
|
130
88
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
89
|
+
version: '3.8'
|
132
90
|
type: :development
|
133
91
|
prerelease: false
|
134
92
|
version_requirements: !ruby/object:Gem::Requirement
|
135
93
|
requirements:
|
136
|
-
- - "
|
94
|
+
- - "~>"
|
137
95
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
96
|
+
version: '3.8'
|
139
97
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
98
|
+
name: actionpack
|
141
99
|
requirement: !ruby/object:Gem::Requirement
|
142
100
|
requirements:
|
143
101
|
- - "~>"
|
144
102
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
103
|
+
version: '5.2'
|
146
104
|
type: :development
|
147
105
|
prerelease: false
|
148
106
|
version_requirements: !ruby/object:Gem::Requirement
|
149
107
|
requirements:
|
150
108
|
- - "~>"
|
151
109
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
110
|
+
version: '5.2'
|
153
111
|
description: A set of modules and types for buildign GraphQL APIs.
|
154
112
|
email:
|
155
113
|
- raymondzane@gmail.com
|
@@ -157,9 +115,9 @@ executables: []
|
|
157
115
|
extensions: []
|
158
116
|
extra_rdoc_files: []
|
159
117
|
files:
|
160
|
-
- ".github/workflows/ci.yml"
|
161
118
|
- ".gitignore"
|
162
119
|
- ".rspec"
|
120
|
+
- ".travis.yml"
|
163
121
|
- Gemfile
|
164
122
|
- README.md
|
165
123
|
- Rakefile
|
@@ -167,7 +125,6 @@ files:
|
|
167
125
|
- bin/setup
|
168
126
|
- graphql-extras.gemspec
|
169
127
|
- lib/graphql/extras.rb
|
170
|
-
- lib/graphql/extras/batch.rb
|
171
128
|
- lib/graphql/extras/controller.rb
|
172
129
|
- lib/graphql/extras/rspec.rb
|
173
130
|
- lib/graphql/extras/types.rb
|
@@ -188,11 +145,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
188
145
|
version: '0'
|
189
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
147
|
requirements:
|
191
|
-
- - "
|
148
|
+
- - ">="
|
192
149
|
- !ruby/object:Gem::Version
|
193
|
-
version:
|
150
|
+
version: '0'
|
194
151
|
requirements: []
|
195
|
-
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.7.6
|
196
154
|
signing_key:
|
197
155
|
specification_version: 4
|
198
156
|
summary: Utiltities for building GraphQL APIs.
|
data/.github/workflows/ci.yml
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
name: CI
|
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
|
26
|
-
|
27
|
-
publish:
|
28
|
-
needs: build
|
29
|
-
runs-on: ubuntu-latest
|
30
|
-
if: ${{ github.ref == 'refs/heads/master' }}
|
31
|
-
steps:
|
32
|
-
- name: Checkout
|
33
|
-
uses: actions/checkout@v2
|
34
|
-
|
35
|
-
- name: Setup Ruby
|
36
|
-
uses: actions/setup-ruby@v1
|
37
|
-
with:
|
38
|
-
ruby-version: 2.6.x
|
39
|
-
registry-url: https://registry.npmjs.org
|
40
|
-
|
41
|
-
- name: Check
|
42
|
-
id: check
|
43
|
-
uses: rzane/is-unpublished@v1
|
44
|
-
|
45
|
-
- name: Publish
|
46
|
-
if: ${{ steps.check.outputs.is-unpublished == 'true' }}
|
47
|
-
run: |
|
48
|
-
mkdir -p $HOME/.gem
|
49
|
-
touch $HOME/.gem/credentials
|
50
|
-
chmod 0600 $HOME/.gem/credentials
|
51
|
-
printf -- "---\n:rubygems_api_key: ${RUBYGEMS_TOKEN}\n" > $HOME/.gem/credentials
|
52
|
-
gem build *.gemspec
|
53
|
-
gem push *.gem
|
54
|
-
env:
|
55
|
-
RUBYGEMS_TOKEN: ${{ secrets.RUBYGEMS_TOKEN }}
|
56
|
-
|
57
|
-
- name: Release
|
58
|
-
if: ${{ steps.check.outputs.is-unpublished == 'true' }}
|
59
|
-
uses: actions/create-release@v1
|
60
|
-
env:
|
61
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
62
|
-
with:
|
63
|
-
tag_name: v${{ steps.check.outputs.version }}
|
64
|
-
release_name: v${{ steps.check.outputs.version }}
|
data/lib/graphql/extras/batch.rb
DELETED
@@ -1,47 +0,0 @@
|
|
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
|