graphql-preview 0.0.8 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/graphql-preview.gemspec +1 -1
- data/lib/graphql-preview.rb +18 -7
- data/lib/graphql-preview/extensions/enabled_previews.rb +2 -20
- data/lib/graphql-preview/instrumenter.rb +37 -0
- data/lib/graphql-preview/schema_modification.rb +6 -2
- data/lib/graphql-preview/version.rb +1 -1
- metadata +5 -5
- data/lib/graphql-preview/member_from_path.rb +0 -135
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1be4eeeab76bb2658d11526964813f5aa5235b30
|
4
|
+
data.tar.gz: 695ec9a606222425d366e4cb3360930500f79a89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf0f46b715be0f0634def0fed28a51063d9a4991da8f28847e8f33bc129737283232b9f073d4f544fc343fad83593936723e32afd69a38f7f31f59650188d324
|
7
|
+
data.tar.gz: 65d9959b521f07f18391aed52021d155182d103ece6eb07c7a54d396d3ac4aca149ec12f0c3bc241fbfc07a92c63059dfc5c6e916bc1ed63090dab356aea8f5d
|
data/graphql-preview.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_dependency "graphql", "~> 1.
|
23
|
+
spec.add_dependency "graphql", "~> 1.8.0.pre6"
|
24
24
|
|
25
25
|
spec.add_development_dependency "awesome_print"
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.14"
|
data/lib/graphql-preview.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require "graphql"
|
2
|
+
require "graphql-preview/instrumenter"
|
2
3
|
require "graphql-preview/version"
|
3
4
|
require "graphql-preview/schema_modification"
|
4
5
|
require "graphql-preview/mask"
|
5
|
-
require "graphql-preview/member_from_path"
|
6
6
|
require "graphql-preview/extensions/enabled_previews"
|
7
7
|
|
8
8
|
module GraphQLPreview
|
@@ -16,16 +16,27 @@ module GraphQLPreview
|
|
16
16
|
|
17
17
|
context[:schema_previews].include?(member.metadata[:preview_toggled_by].toggled_by)
|
18
18
|
end
|
19
|
+
|
20
|
+
def self.use(schema_def, enabled_previews: [])
|
21
|
+
unless enabled_previews.is_a?(Array)
|
22
|
+
raise ArgumentError, "Expected `enabled_previews` to be an array, but it was `#{enabled_previews.class}`"
|
23
|
+
end
|
24
|
+
|
25
|
+
enabled_previews.each do |preview|
|
26
|
+
unless preview < GraphQLPreview::SchemaModification
|
27
|
+
raise ArgumentError, "Preview #{preview} must inherit from `GraphQLPreview::SchemaModification`"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
schema = schema_def.target
|
32
|
+
schema_def.instrument(:field, Instrumenter.new(enabled_previews))
|
33
|
+
enabled_previews.each { |preview| preview.apply_to_schema(schema) }
|
34
|
+
schema.metadata[:enabled_previews] = enabled_previews
|
35
|
+
end
|
19
36
|
end
|
20
37
|
|
21
38
|
module GraphQL
|
22
39
|
Schema.class_eval do
|
23
|
-
# To support `graphql-ruby`'s `.define` based API
|
24
|
-
include GraphQLPreview::Extensions::EnabledPreviews
|
25
|
-
|
26
|
-
accepts_definitions \
|
27
|
-
enabled_previews: -> (schema, previews = nil) { schema.enabled_previews(previews) }
|
28
|
-
|
29
40
|
# To support `graphql-ruby`'s class-based API
|
30
41
|
extend GraphQLPreview::Extensions::EnabledPreviews
|
31
42
|
end
|
@@ -1,26 +1,8 @@
|
|
1
1
|
module GraphQLPreview
|
2
2
|
module Extensions
|
3
3
|
module EnabledPreviews
|
4
|
-
def enabled_previews
|
5
|
-
|
6
|
-
|
7
|
-
unless previews.is_a?(Array)
|
8
|
-
raise ArgumentError, "Expected `enabled_previews` to be an array, but it was `#{previews.class}`"
|
9
|
-
end
|
10
|
-
|
11
|
-
previews.each do |preview|
|
12
|
-
unless preview < GraphQLPreview::SchemaModification
|
13
|
-
raise ArgumentError, "Preview #{preview} must inherit from `GraphQLPreview::SchemaModification`"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
previews.each { |preview| preview.apply_to_schema(self) }
|
18
|
-
|
19
|
-
@enabled_previews = previews
|
20
|
-
end
|
21
|
-
|
22
|
-
def enabled_previews=(previews)
|
23
|
-
enabled_previews(previews)
|
4
|
+
def enabled_previews
|
5
|
+
metadata[:enabled_previews]
|
24
6
|
end
|
25
7
|
end
|
26
8
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module GraphQLPreview
|
2
|
+
# Modify each field & argument in the schema so that
|
3
|
+
# its metadata contains the preview, if there is one.
|
4
|
+
class Instrumenter
|
5
|
+
def initialize(enabled_previews)
|
6
|
+
@enabled_previews = enabled_previews
|
7
|
+
end
|
8
|
+
|
9
|
+
def instrument(type, field)
|
10
|
+
# Maybe get an isolated copy that we can modify
|
11
|
+
field_dup = nil
|
12
|
+
|
13
|
+
if (preview = enabled_previews.find { |prev| prev.toggled_on.include?("#{type.name}.#{field.name}")})
|
14
|
+
field_dup = field.dup
|
15
|
+
assign_preview(field_dup, preview)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return the modified copy if we made one,
|
19
|
+
# otherwise return the original
|
20
|
+
field_dup || field
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :enabled_previews
|
26
|
+
|
27
|
+
def assign_preview(obj, preview)
|
28
|
+
if obj.metadata[:preview_toggled_by]
|
29
|
+
raise ArgumentError, "Couldn't add `#{preview}` to `#{obj.name}`: it's already toggled with `#{obj.metadata[:preview_toggled_by].toggled_by}`"
|
30
|
+
end
|
31
|
+
obj.metadata[:preview_toggled_by] = preview
|
32
|
+
if obj.respond_to?(:mutation) && (mut = obj.mutation)
|
33
|
+
mut.metadata[:preview_toggled_by] = preview
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -84,10 +84,14 @@ module GraphQLPreview
|
|
84
84
|
private
|
85
85
|
|
86
86
|
def self.set_preview_toggled_by_on_members(schema, value)
|
87
|
-
|
88
|
-
members = @member_paths.map { |path| member_from_path.find(path) }
|
87
|
+
members = @member_paths.map { |path| schema.find(path) }
|
89
88
|
|
90
89
|
members.each do |member|
|
90
|
+
if member.is_a?(GraphQL::Field)
|
91
|
+
# Let fields pass; we'll apply it during instrumentation
|
92
|
+
next
|
93
|
+
end
|
94
|
+
|
91
95
|
unless member.respond_to?(:metadata)
|
92
96
|
raise NoMethodError, "`#{member}` cannot have its metadata set"
|
93
97
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-preview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garen J. Torikian
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: graphql
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 1.8.0.pre6
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 1.8.0.pre6
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: awesome_print
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,8 +129,8 @@ files:
|
|
129
129
|
- graphql-preview.gemspec
|
130
130
|
- lib/graphql-preview.rb
|
131
131
|
- lib/graphql-preview/extensions/enabled_previews.rb
|
132
|
+
- lib/graphql-preview/instrumenter.rb
|
132
133
|
- lib/graphql-preview/mask.rb
|
133
|
-
- lib/graphql-preview/member_from_path.rb
|
134
134
|
- lib/graphql-preview/schema_modification.rb
|
135
135
|
- lib/graphql-preview/version.rb
|
136
136
|
- script/single_test
|
@@ -1,135 +0,0 @@
|
|
1
|
-
module GraphQLPreview
|
2
|
-
class MemberFromPath
|
3
|
-
class MemberNotFoundError < ArgumentError; end
|
4
|
-
|
5
|
-
def initialize(schema)
|
6
|
-
@schema = schema
|
7
|
-
end
|
8
|
-
|
9
|
-
def find(path)
|
10
|
-
path = path.split(".")
|
11
|
-
type_or_directive = path.shift
|
12
|
-
|
13
|
-
if type_or_directive.start_with?("@")
|
14
|
-
directive = schema.directives[type_or_directive[1..-1]]
|
15
|
-
|
16
|
-
if directive.nil?
|
17
|
-
raise MemberNotFoundError, "Could not find directive `#{type_or_directive}` in schema."
|
18
|
-
end
|
19
|
-
|
20
|
-
return directive if path.empty?
|
21
|
-
|
22
|
-
find_in_directive(directive, path: path)
|
23
|
-
else
|
24
|
-
type = schema.types[type_or_directive]
|
25
|
-
|
26
|
-
if type.nil?
|
27
|
-
raise MemberNotFoundError, "Could not find type `#{type_or_directive}` in schema."
|
28
|
-
end
|
29
|
-
|
30
|
-
return type if path.empty?
|
31
|
-
|
32
|
-
find_in_type(type, path: path)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
attr_reader :schema
|
39
|
-
|
40
|
-
def find_in_directive(directive, path:)
|
41
|
-
argument_name = path.shift
|
42
|
-
argument = directive.arguments[argument_name]
|
43
|
-
|
44
|
-
if argument.nil?
|
45
|
-
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on directive #{directive}."
|
46
|
-
end
|
47
|
-
|
48
|
-
argument
|
49
|
-
end
|
50
|
-
|
51
|
-
def find_in_type(type, path:)
|
52
|
-
case type
|
53
|
-
when GraphQL::ObjectType
|
54
|
-
find_in_fields_type(type, kind: "object", path: path)
|
55
|
-
when GraphQL::InterfaceType
|
56
|
-
find_in_fields_type(type, kind: "interface", path: path)
|
57
|
-
when GraphQL::InputObjectType
|
58
|
-
find_in_input_object(type, path: path)
|
59
|
-
when GraphQL::UnionType
|
60
|
-
# Error out if path that was provided is too long
|
61
|
-
# i.e UnionType.PossibleType.aField
|
62
|
-
# Use PossibleType.aField instead.
|
63
|
-
if invalid = path.first
|
64
|
-
raise MemberNotFoundError, "Cannot select union possible type `#{invalid}`. Select the type directly instead."
|
65
|
-
end
|
66
|
-
when GraphQL::EnumType
|
67
|
-
find_in_enum_type(type, path: path)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def find_in_fields_type(type, kind:, path:)
|
72
|
-
field_name = path.shift
|
73
|
-
instrumented_field = schema.get_field(type, field_name)
|
74
|
-
|
75
|
-
if instrumented_field.nil?
|
76
|
-
raise MemberNotFoundError, "Could not find field `#{field_name}` on #{kind} type `#{type}`."
|
77
|
-
end
|
78
|
-
|
79
|
-
return instrumented_field if path.empty?
|
80
|
-
|
81
|
-
find_in_field(instrumented_field, path: path)
|
82
|
-
end
|
83
|
-
|
84
|
-
def find_in_field(field, path:)
|
85
|
-
argument_name = path.shift
|
86
|
-
argument = field.arguments[argument_name]
|
87
|
-
|
88
|
-
if argument.nil?
|
89
|
-
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
|
90
|
-
end
|
91
|
-
|
92
|
-
# Error out if path that was provided is too long
|
93
|
-
# i.e Type.field.argument.somethingBad
|
94
|
-
if invalid = path.first
|
95
|
-
raise MemberNotFoundError, "Cannot select member `#{invalid}` on a field."
|
96
|
-
end
|
97
|
-
|
98
|
-
argument
|
99
|
-
end
|
100
|
-
|
101
|
-
def find_in_input_object(input_object, path:)
|
102
|
-
field_name = path.shift
|
103
|
-
input_field = input_object.input_fields[field_name]
|
104
|
-
|
105
|
-
if input_field.nil?
|
106
|
-
raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object}`."
|
107
|
-
end
|
108
|
-
|
109
|
-
# Error out if path that was provided is too long
|
110
|
-
# i.e InputType.inputField.bad
|
111
|
-
if invalid = path.first
|
112
|
-
raise MemberNotFoundError, "Cannot select member `#{invalid}` on an input field."
|
113
|
-
end
|
114
|
-
|
115
|
-
input_field
|
116
|
-
end
|
117
|
-
|
118
|
-
def find_in_enum_type(enum_type, path:)
|
119
|
-
value_name = path.shift
|
120
|
-
enum_value = enum_type.values[value_name]
|
121
|
-
|
122
|
-
if enum_value.nil?
|
123
|
-
raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type}`."
|
124
|
-
end
|
125
|
-
|
126
|
-
# Error out if path that was provided is too long
|
127
|
-
# i.e Enum.VALUE.wat
|
128
|
-
if invalid = path.first
|
129
|
-
raise MemberNotFoundError, "Cannot select member `#{invalid}` on an enum value."
|
130
|
-
end
|
131
|
-
|
132
|
-
enum_value
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|