graphql-preview 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc975ff4b49ae763232e7658f510a8bac187efa2
4
- data.tar.gz: 779d52ef6311effa305f09154353f3996e0859d8
3
+ metadata.gz: 4dead6d1a5f54b189170b3d4da9cb77d4f31a9d3
4
+ data.tar.gz: 400454ff941ed04a48bf3ada71a45527c2f3764a
5
5
  SHA512:
6
- metadata.gz: 887ee46c24ca8613d3dc8af6b0b6ebc5212072dcf5d97b7a02babbb90ef28f4fe61fad47a7a83a6d71f5d93ca341f57444bc0ccbdc6df583ab8161eff968d3c9
7
- data.tar.gz: 44ac0b9b7ee55894cb044363bec954e326264bc8ce13bdca8998ed7899938b8af7830c234bb17d7d5d962044eb430a502b857ede3bab46114b8d53bd85a99f5c
6
+ metadata.gz: f18cea3be7ff3f17632e4a3cc302473025974f0cc72759f9d8971878076f901539ff116573b7b59d289e9d59899fbd5628f7b18f1d27e75e0c0a94eee2b9eb64
7
+ data.tar.gz: 6e6f0b25d10af928191be4e1ea08c01fe9f078db98121aa247d4552a3038585fa2fa6125085dcacb8ed8e46a900c76ff40ada8b58f0bbb58a4fceba577b464ad
data/README.md CHANGED
@@ -48,15 +48,15 @@ class TestPreview < GraphQLPreview::SchemaModification
48
48
 
49
49
  # The parts of your GraphQL schema you want toggled by this preview
50
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
51
+ "Author", # an object
52
+ "ExtraInfo", # an interface,
53
+ "Author.socialSecurityNumber", # a field
54
+ "Book.author.includeMiddleInitial", # an argument
55
+ "Likeable", # a union,
56
+ "Cover", # an enum
57
+ "Cover.DIGITAL", # an enum value
58
+ "BookOrder", # an input object
59
+ "Mutation.addLike", # a mutation
60
60
  ]
61
61
  end
62
62
  ```
@@ -66,6 +66,17 @@ end
66
66
  This gem introduces a new method to apply on your schema, `enabled_previews`. It takes an array,
67
67
  and you should pass in the list of preview classes you want enabled on your schema. For example:
68
68
 
69
+ ``` ruby
70
+ class Schema < GraphQL::Schema
71
+ query(query_type)
72
+ enabled_previews [
73
+ TestPreview
74
+ ]
75
+ end
76
+ ```
77
+
78
+ If you are using `graphql-ruby`'s `.define` DSL a similar API is provided:
79
+
69
80
  ``` ruby
70
81
  GraphQL::Schema.define do
71
82
  query(query_type)
@@ -2,10 +2,20 @@ require "graphql"
2
2
  require "graphql-preview/version"
3
3
  require "graphql-preview/schema_modification"
4
4
  require "graphql-preview/mask"
5
+ require "graphql-preview/member_from_path"
5
6
  require "graphql-preview/extensions/enabled_previews"
6
7
 
7
8
  module GraphQLPreview
9
+ def self.visible?(member, context:)
10
+ return true unless member.respond_to?(:metadata)
11
+ return true unless member.metadata[:preview_toggled_by]
8
12
 
13
+ unless context.key?(:schema_previews)
14
+ raise ArgumentError, "[GraphQLPreview] `:schema_previews` was not provided to the `context`"
15
+ end
16
+
17
+ context[:schema_previews].include?(member.metadata[:preview_toggled_by].toggled_by)
18
+ end
9
19
  end
10
20
 
11
21
  module GraphQL
@@ -9,11 +9,13 @@ module GraphQLPreview
9
9
  end
10
10
 
11
11
  previews.each do |preview|
12
- unless preview.ancestors.any? { |ancestor| ancestor == GraphQLPreview::SchemaModification }
13
- raise ArgumentError, "One of your `enabled_previews` items does not descend from `GraphQLPreview::SchemaModification`"
12
+ unless preview < GraphQLPreview::SchemaModification
13
+ raise ArgumentError, "Preview #{preview} must inherit from `GraphQLPreview::SchemaModification`"
14
14
  end
15
15
  end
16
16
 
17
+ previews.each { |preview| preview.apply_to_schema(self) }
18
+
17
19
  @enabled_previews = previews
18
20
  end
19
21
 
@@ -1,13 +1,7 @@
1
1
  module GraphQLPreview
2
2
  class Mask
3
3
  def self.call(member, context)
4
- return false unless member.respond_to?(:metadata)
5
- return false unless member.metadata.key?(:preview_toggled_by)
6
- unless context.key?(:schema_previews)
7
- raise ArgumentError, "You are using the `GraphQLPreview::Mask`, but key `:schema_previews` was not provided to the `context`"
8
- end
9
-
10
- !context[:schema_previews].include?(member.metadata[:preview_toggled_by].toggled_by)
4
+ !GraphQLPreview.visible?(member, context: context)
11
5
  end
12
6
  end
13
7
  end
@@ -0,0 +1,135 @@
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
+ field = type.fields[field_name]
74
+
75
+ if field.nil?
76
+ raise MemberNotFoundError, "Could not find field `#{field_name}` on #{kind} type `#{type}`."
77
+ end
78
+
79
+ return field if path.empty?
80
+
81
+ find_in_field(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
@@ -59,34 +59,55 @@ module GraphQLPreview
59
59
  @updates
60
60
  end
61
61
 
62
- def self.toggled_on(types = nil)
63
- if types
64
- types.each do |type|
65
- unless type.respond_to?(:metadata)
66
- raise MethodError, "`#{type}` cannot have its metadata set"
67
- end
68
-
69
- if type.metadata.key?(:preview_toggled_by)
70
- raise ArgumentError, "Couldn't add `#{self.toggled_by}` to `#{type.name}`: it's already toggled with `#{type.metadata[:preview_toggled_by].toggled_by}`"
71
- end
72
-
73
- type.metadata[:preview_toggled_by] = self
74
-
75
- if type.is_a?(GraphQL::InterfaceType)
76
- mark_children(type)
62
+ def self.toggled_on(member_paths = nil)
63
+ if member_paths
64
+ member_paths.each do |path|
65
+ unless path.is_a?(String)
66
+ raise ArgumentError, "Provide string paths to `toggled_on`. For example, to toggle on a field called `name` on a type `Author`, use `\"Author.name\"``"
77
67
  end
78
68
  end
79
- @toggled_on = types
69
+
70
+ @member_paths = member_paths
80
71
  else
81
- @toggled_on
72
+ @member_paths
82
73
  end
83
74
  end
84
75
 
76
+ def self.unset(schema)
77
+ set_preview_toggled_by_on_members(schema, nil)
78
+ end
79
+
80
+ def self.apply_to_schema(schema)
81
+ set_preview_toggled_by_on_members(schema, self)
82
+ end
83
+
85
84
  private
86
85
 
87
- def self.mark_children(type)
88
- type.fields.each_value do |field|
89
- field.metadata[:preview_toggled_by] = self
86
+ def self.set_preview_toggled_by_on_members(schema, value)
87
+ member_from_path = GraphQLPreview::MemberFromPath.new(schema)
88
+ members = @member_paths.map { |path| member_from_path.find(path) }
89
+
90
+ members.each do |member|
91
+ unless member.respond_to?(:metadata)
92
+ raise NoMethodError, "`#{member}` cannot have its metadata set"
93
+ end
94
+
95
+ # unless we're unsetting the preview, don't allow adding a new value
96
+ if value && member.metadata[:preview_toggled_by]
97
+ raise ArgumentError, "Couldn't add `#{self.toggled_by}` to `#{member.name}`: it's already toggled with `#{member.metadata[:preview_toggled_by].toggled_by}`"
98
+ end
99
+
100
+ member.metadata[:preview_toggled_by] = value
101
+
102
+ if member.is_a?(GraphQL::InterfaceType)
103
+ member.fields.each_value do |field|
104
+ field.metadata[:preview_toggled_by] = value
105
+ end
106
+ end
107
+
108
+ if member.respond_to?(:mutation) && member.mutation
109
+ member.mutation.metadata[:preview_toggled_by] = value
110
+ end
90
111
  end
91
112
  end
92
113
  end
@@ -1,3 +1,3 @@
1
1
  module GraphQLPreview
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  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.6
4
+ version: 0.0.7
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-01-10 00:00:00.000000000 Z
12
+ date: 2018-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: graphql
@@ -130,6 +130,7 @@ files:
130
130
  - lib/graphql-preview.rb
131
131
  - lib/graphql-preview/extensions/enabled_previews.rb
132
132
  - lib/graphql-preview/mask.rb
133
+ - lib/graphql-preview/member_from_path.rb
133
134
  - lib/graphql-preview/schema_modification.rb
134
135
  - lib/graphql-preview/version.rb
135
136
  - script/single_test