graphql-preview 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 +7 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/README.md +96 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/graphql-preview.gemspec +30 -0
- data/lib/graphql-preview/extensions/enabled_previews.rb +23 -0
- data/lib/graphql-preview/mask.rb +13 -0
- data/lib/graphql-preview/schema_modification.rb +97 -0
- data/lib/graphql-preview/version.rb +3 -0
- data/lib/graphql-preview.rb +18 -0
- data/script/single_test +6 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fc8eeb565f36949ee6ce15c4609e1c2ee5efd65
|
4
|
+
data.tar.gz: da5d69a6fe681251fab40176c5f6073f18ec3954
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3fb8a0333e507048dfddb56e6a4b3c7798f5ea762a02975f7882c4546e0445e70fc6b753cf0875b16af08c63cadeb640c68164c3f5168724c1d548eeff9375ca
|
7
|
+
data.tar.gz: f84fdaa16c52c932d4731b5e57a55a0e6a57995d19c1edf3c186b07560174b8ef1b0c06cd731c17b88449701dce8ba49318b5dd9b0e9db403114bd9413f30bfb
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# GraphQLPreview
|
2
|
+
|
3
|
+
Easily toggle parts of a GraphQL schema on.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'graphql-preview'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install graphql-preview
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
The basic premise of this gem is to provide an easier interface to toggling parts of a GraphQL schema. You define a single class that contains all the definitions for how your toggler should behave, and this gem will handle the flipping for you.
|
24
|
+
|
25
|
+
The easiest use case to imagine for this gem is to think of something like a public API preview. Perhaps you want to be able to expose certain objects or fields if and only if a client provides a specific `Accept` header. This gem will help you do that!
|
26
|
+
|
27
|
+
### Class definition
|
28
|
+
|
29
|
+
To get started, define a class that inherits from `GraphQLPreview::SchemaModification`. This class can be given various properties, but the two most important are `toggled_by` and `toggled_on`:
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
class TestPreview < GraphQLPreview::SchemaModification
|
33
|
+
# A human-readable name of your preview
|
34
|
+
title "TestPreview"
|
35
|
+
# A description of your preview
|
36
|
+
description "Enable various library items"
|
37
|
+
|
38
|
+
# A symbol that uniquely identifies this preview -- explained below
|
39
|
+
toggled_by :enabled_library
|
40
|
+
|
41
|
+
# A date defining when this preview was announced, with an optional URL announcing it
|
42
|
+
announced_on Date.new(2017, 11, 1), url: "http://example.com"
|
43
|
+
|
44
|
+
# A date defining when this preview was updated, with an optional URL announcing it
|
45
|
+
updated_on Date.new(2017, 11, 2), url: "http://example.com"
|
46
|
+
# You can have more than one of these!
|
47
|
+
updated_on Date.new(2017, 11, 3), url: "http://example.com"
|
48
|
+
|
49
|
+
# The parts of your GraphQL schema you want toggled by this preview
|
50
|
+
toggled_on [
|
51
|
+
Library::Author, # an object
|
52
|
+
Library::ExtraInfo, # an interface,
|
53
|
+
Library::Author.fields["socialSecurityNumber"], # a field
|
54
|
+
Library::Book.fields["author"].arguments["includeMiddleInitial"], # an argument
|
55
|
+
Library::Likeable, # a union,
|
56
|
+
Library::Cover, # an enum
|
57
|
+
Library::Cover.values["DIGITAL"], # an enum value
|
58
|
+
Library::BookOrder, # an input object
|
59
|
+
Library::AddLike, # a mutation
|
60
|
+
]
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
### Toggling the preview on your schema
|
65
|
+
|
66
|
+
This gem introduces a new method to apply on your schema, `enabled_previews`. It takes an array,
|
67
|
+
and you should pass in the list of preview classes you want enabled on your schema. For example:
|
68
|
+
|
69
|
+
``` ruby
|
70
|
+
GraphQL::Schema.define do
|
71
|
+
query(query_type)
|
72
|
+
enabled_previews [
|
73
|
+
TestPreview
|
74
|
+
]
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
### Passing information to `Schema.execute`
|
79
|
+
|
80
|
+
After your preview class is configured, you'll need to make two minor changes to the way the schema is executed.
|
81
|
+
|
82
|
+
First, ensure that your `context` object has a key called `schema_previews`. Within this key, you'll provide an array of symbols that identify which previews you want enabled. For example:
|
83
|
+
|
84
|
+
``` ruby
|
85
|
+
context = { schema_previews: [:enabled_library] }
|
86
|
+
```
|
87
|
+
|
88
|
+
Next, simply pass in the `GraphQLPreview::Mask` class to the `except` kwarg.
|
89
|
+
|
90
|
+
Putting it all together, this looks like:
|
91
|
+
|
92
|
+
``` ruby
|
93
|
+
Schema.execute(query, context: context, except: GraphQLPreview::Mask)
|
94
|
+
```
|
95
|
+
|
96
|
+
It's up to you to decide how to determine the array in `context[:schema_previews]`. It could be based on the `Accept` header, some random `Flipper` percentage, or anything else!
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "graphql/preview"
|
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,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "graphql-preview/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "graphql-preview"
|
8
|
+
spec.version = GraphQLPreview::VERSION
|
9
|
+
spec.authors = ["Garen J. Torikian", "Christian Joudrey"]
|
10
|
+
spec.email = ["gjtorikian@gmail.com", "cmallette@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Provide a system for toggling parts of a GraphQL schema on."
|
13
|
+
spec.homepage = "https://github.com/github/graphql-preview"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "graphql", "~> 1.7"
|
23
|
+
|
24
|
+
spec.add_development_dependency "awesome_print"
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
26
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
27
|
+
spec.add_development_dependency "pry", "~> 0.10.0"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "rubocop-github"
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module GraphQLPreview
|
2
|
+
module Extensions
|
3
|
+
module EnabledPreviews
|
4
|
+
def enabled_previews
|
5
|
+
@enabled_previews
|
6
|
+
end
|
7
|
+
|
8
|
+
def enabled_previews=(previews)
|
9
|
+
unless previews.is_a?(Array)
|
10
|
+
raise ArgumentError, "Expected `enabled_previews` to be an array, but it was `#{previews.class}`"
|
11
|
+
end
|
12
|
+
|
13
|
+
previews.each do |preview|
|
14
|
+
unless preview.ancestors.any? { |ancestor| ancestor == GraphQLPreview::SchemaModification }
|
15
|
+
raise ArgumentError, "One of your `enabled_previews` items does not descend from `GraphQLPreview::SchemaModification`"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
@enabled_previews = previews
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module GraphQLPreview
|
2
|
+
class Mask
|
3
|
+
def self.call(member, context)
|
4
|
+
unless context.key?(:schema_previews)
|
5
|
+
raise ArgumentError, "You are using the `GraphQLPreview::Mask`, but key `:schema_previews` was not provided to the `context`"
|
6
|
+
end
|
7
|
+
return false if Library::Schema.enabled_previews.nil?
|
8
|
+
return false unless member.metadata.key?(:preview_toggled_by)
|
9
|
+
|
10
|
+
!context[:schema_previews].include?(member.metadata[:preview_toggled_by].toggled_by)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module GraphQLPreview
|
2
|
+
class SchemaModification
|
3
|
+
def self.masks
|
4
|
+
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.to_h
|
8
|
+
{
|
9
|
+
title: title,
|
10
|
+
description: description,
|
11
|
+
toggled_by: toggled_by,
|
12
|
+
announcement: announcement,
|
13
|
+
updates: updates,
|
14
|
+
toggled_on: toggled_on
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.title(new_title = nil)
|
19
|
+
if new_title
|
20
|
+
@title = new_title
|
21
|
+
else
|
22
|
+
@title
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.description(new_description = nil)
|
27
|
+
if new_description
|
28
|
+
@description = new_description
|
29
|
+
else
|
30
|
+
@description
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.toggled_by(new_toggled_by = nil)
|
35
|
+
if new_toggled_by
|
36
|
+
@toggled_by = new_toggled_by
|
37
|
+
else
|
38
|
+
@toggled_by
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.announced_on(date, url: nil)
|
43
|
+
@announcement = {
|
44
|
+
date: date,
|
45
|
+
url: url
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.announcement
|
50
|
+
@announcement
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.updated_on(date, url: nil)
|
54
|
+
@updates ||= []
|
55
|
+
|
56
|
+
@updates << {
|
57
|
+
date: date,
|
58
|
+
url: url
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.updates
|
63
|
+
@updates
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.toggled_on(types = nil)
|
67
|
+
if types
|
68
|
+
types.each do |type|
|
69
|
+
unless type.respond_to?(:metadata)
|
70
|
+
raise MethodError, "`#{type}` cannot have its metadata set"
|
71
|
+
end
|
72
|
+
|
73
|
+
if type.metadata.key?(:preview_toggled_by)
|
74
|
+
raise ArgumentError, "Couldn't add `#{self.toggled_by}` to `#{type.name}`: it's already toggled with `#{type.metadata[:preview_toggled_by].toggled_by}`"
|
75
|
+
end
|
76
|
+
|
77
|
+
type.metadata[:preview_toggled_by] = self
|
78
|
+
|
79
|
+
if type.is_a?(GraphQL::InterfaceType)
|
80
|
+
mark_children(type)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@toggled_on = types
|
84
|
+
else
|
85
|
+
@toggled_on
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def self.mark_children(type)
|
92
|
+
type.fields.each_value do |field|
|
93
|
+
field.metadata[:preview_toggled_by] = self
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql-preview/version"
|
3
|
+
require "graphql-preview/schema_modification"
|
4
|
+
require "graphql-preview/mask"
|
5
|
+
require "graphql-preview/extensions/enabled_previews"
|
6
|
+
|
7
|
+
module GraphQLPreview
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module GraphQL
|
12
|
+
Schema.class_eval do
|
13
|
+
include GraphQLPreview::Extensions::EnabledPreviews
|
14
|
+
|
15
|
+
accepts_definitions \
|
16
|
+
enabled_previews: GraphQLPreview::Extensions::EnabledPreviews
|
17
|
+
end
|
18
|
+
end
|
data/script/single_test
ADDED
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphql-preview
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Garen J. Torikian
|
8
|
+
- Christian Joudrey
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2017-12-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: graphql
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.7'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.7'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: awesome_print
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: bundler
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.14'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.14'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: minitest
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '5.0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '5.0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: pry
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.10.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.10.0
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rake
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '10.0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '10.0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rubocop-github
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
description:
|
113
|
+
email:
|
114
|
+
- gjtorikian@gmail.com
|
115
|
+
- cmallette@gmail.com
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".rubocop.yml"
|
122
|
+
- ".travis.yml"
|
123
|
+
- Gemfile
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- bin/console
|
127
|
+
- bin/setup
|
128
|
+
- graphql-preview.gemspec
|
129
|
+
- lib/graphql-preview.rb
|
130
|
+
- lib/graphql-preview/extensions/enabled_previews.rb
|
131
|
+
- lib/graphql-preview/mask.rb
|
132
|
+
- lib/graphql-preview/schema_modification.rb
|
133
|
+
- lib/graphql-preview/version.rb
|
134
|
+
- script/single_test
|
135
|
+
homepage: https://github.com/github/graphql-preview
|
136
|
+
licenses: []
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.6.12
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Provide a system for toggling parts of a GraphQL schema on.
|
158
|
+
test_files: []
|