graphql_rails 1.2.4 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +18 -0
  3. data/.hound.yml +1 -1
  4. data/.rubocop.yml +4 -0
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +21 -0
  7. data/Gemfile +3 -3
  8. data/Gemfile.lock +129 -128
  9. data/docs/README.md +1 -1
  10. data/docs/components/model.md +107 -13
  11. data/docs/components/routes.md +4 -3
  12. data/docs/other_tools/schema_dump.md +8 -8
  13. data/lib/graphql_rails/attributes/attributable.rb +6 -14
  14. data/lib/graphql_rails/attributes/attribute.rb +10 -34
  15. data/lib/graphql_rails/attributes/attribute_configurable.rb +45 -0
  16. data/lib/graphql_rails/attributes/attribute_name_parser.rb +7 -7
  17. data/lib/graphql_rails/attributes/input_attribute.rb +20 -14
  18. data/lib/graphql_rails/attributes/input_type_parser.rb +5 -7
  19. data/lib/graphql_rails/attributes/type_parseable.rb +49 -19
  20. data/lib/graphql_rails/attributes/type_parser.rb +4 -9
  21. data/lib/graphql_rails/concerns/chainable_options.rb +49 -0
  22. data/lib/graphql_rails/controller/build_controller_action_resolver/controller_action_resolver.rb +3 -0
  23. data/lib/graphql_rails/controller/log_controller_action.rb +7 -2
  24. data/lib/graphql_rails/decorator/relation_decorator.rb +2 -2
  25. data/lib/graphql_rails/input_configurable.rb +11 -9
  26. data/lib/graphql_rails/model/build_graphql_input_type.rb +4 -2
  27. data/lib/graphql_rails/model/configurable.rb +30 -8
  28. data/lib/graphql_rails/model/configuration.rb +8 -12
  29. data/lib/graphql_rails/model/find_or_build_graphql_type.rb +16 -19
  30. data/lib/graphql_rails/model/find_or_build_graphql_type_class.rb +2 -1
  31. data/lib/graphql_rails/model/input.rb +10 -26
  32. data/lib/graphql_rails/query_runner.rb +9 -3
  33. data/lib/graphql_rails/router/mutation_route.rb +4 -0
  34. data/lib/graphql_rails/router/query_route.rb +4 -0
  35. data/lib/graphql_rails/router/resource_routes_builder.rb +8 -0
  36. data/lib/graphql_rails/router/route.rb +2 -2
  37. data/lib/graphql_rails/router/schema_builder.rb +12 -3
  38. data/lib/graphql_rails/router/subscription_route.rb +22 -0
  39. data/lib/graphql_rails/router.rb +8 -2
  40. data/lib/graphql_rails/tasks/dump_graphql_schema.rb +18 -27
  41. data/lib/graphql_rails/tasks/dump_graphql_schemas.rb +57 -0
  42. data/lib/graphql_rails/tasks/schema.rake +8 -5
  43. data/lib/graphql_rails/types/argument_type.rb +12 -0
  44. data/lib/graphql_rails/types/field_type.rb +14 -0
  45. data/lib/graphql_rails/types/hidable_by_group.rb +32 -0
  46. data/lib/graphql_rails/types/object_type.rb +12 -0
  47. data/lib/graphql_rails/version.rb +1 -1
  48. metadata +16 -8
  49. data/.travis.yml +0 -5
@@ -2,25 +2,47 @@
2
2
 
3
3
  module GraphqlRails
4
4
  module Model
5
- # contains methods which are shared between various configurations
6
- # expects `default_name` to be defined
5
+ # Contains methods which are shared between various configurations.
6
+ #
7
+ # Expects `default_name` to be defined.
8
+ # Expects `build_attribute(attr_name)` method to be defined.
7
9
  module Configurable
10
+ require 'active_support/concern'
11
+ require 'graphql_rails/concerns/chainable_options'
12
+
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ include GraphqlRails::ChainableOptions
17
+
18
+ chainable_option :description
19
+ end
20
+
21
+ def initialize_copy(other)
22
+ super
23
+ @type_name = nil
24
+ @attributes = other.attributes.transform_values(&:dup)
25
+ end
26
+
8
27
  def attributes
9
28
  @attributes ||= {}
10
29
  end
11
30
 
12
- def name(graphql_name = nil)
13
- @name = graphql_name if graphql_name
14
- @name || default_name
31
+ def name(*args)
32
+ get_or_set_chainable_option(:name, *args) || default_name
15
33
  end
16
34
 
17
35
  def type_name
18
36
  @type_name ||= "#{name.camelize}Type#{SecureRandom.hex}"
19
37
  end
20
38
 
21
- def description(new_description = nil)
22
- @description = new_description if new_description
23
- @description
39
+ def attribute(attribute_name, **attribute_options)
40
+ key = attribute_name.to_s
41
+
42
+ attributes[key] ||= build_attribute(attribute_name).tap do |new_attribute|
43
+ new_attribute.with(**attribute_options) unless attribute_options.empty?
44
+ yield(new_attribute) if block_given?
45
+ end
24
46
  end
25
47
  end
26
48
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'graphql_rails/attributes'
4
4
  require 'graphql_rails/model/find_or_build_graphql_type'
5
- require 'graphql_rails/model/build_enum_type'
6
5
  require 'graphql_rails/model/input'
7
6
  require 'graphql_rails/model/configurable'
8
7
  require 'graphql_rails/model/build_connection_type'
@@ -11,6 +10,7 @@ module GraphqlRails
11
10
  module Model
12
11
  # stores information about model specific config, like attributes and types
13
12
  class Configuration
13
+ include ChainableOptions
14
14
  include Configurable
15
15
 
16
16
  def initialize(model_class)
@@ -22,22 +22,14 @@ module GraphqlRails
22
22
  @connection_type = nil
23
23
  @graphql_type = nil
24
24
  @input = other.instance_variable_get(:@input)&.transform_values(&:dup)
25
- @attributes = other.instance_variable_get(:@attributes)&.transform_values(&:dup)
26
25
  end
27
26
 
28
27
  def attribute(attribute_name, **attribute_options)
29
28
  key = attribute_name.to_s
30
29
 
31
- attributes[key] ||= Attributes::Attribute.new(attribute_name)
32
-
33
- attributes[key].tap do |attribute|
34
- attribute_options.each do |method_name, args|
35
- send_args = [method_name]
36
- send_args << args if attribute.method(method_name).parameters.present?
37
- attribute.public_send(*send_args)
38
- end
39
-
40
- yield(attribute) if block_given?
30
+ attributes[key] ||= build_attribute(attribute_name).tap do |new_attribute|
31
+ new_attribute.with(**attribute_options)
32
+ yield(new_attribute) if block_given?
41
33
  end
42
34
  end
43
35
 
@@ -80,6 +72,10 @@ module GraphqlRails
80
72
 
81
73
  attr_reader :model_class
82
74
 
75
+ def build_attribute(attribute_name)
76
+ Attributes::Attribute.new(attribute_name)
77
+ end
78
+
83
79
  def default_name
84
80
  @default_name ||= model_class.name.split('::').last
85
81
  end
@@ -37,28 +37,25 @@ module GraphqlRails
37
37
  end
38
38
 
39
39
  def add_fields_to_graphql_type
40
- AddFieldsToGraphqlType.call(klass: klass, attributes: attributes.values.select(&:scalar_type?))
40
+ scalar_attributes, dynamic_attributes = attributes.values.partition(&:scalar_type?)
41
41
 
42
- attributes.values.reject(&:scalar_type?).tap do |dynamic_attributes|
43
- find_or_build_dynamic_graphql_types(dynamic_attributes) do |name, description, attributes, type_name|
44
- self.class.call(
45
- name: name, description: description,
46
- attributes: attributes, type_name: type_name
47
- )
48
- end
49
- AddFieldsToGraphqlType.call(klass: klass, attributes: dynamic_attributes)
50
- end
42
+ AddFieldsToGraphqlType.call(klass: klass, attributes: scalar_attributes)
43
+ dynamic_attributes.each { |attribute| find_or_build_dynamic_type(attribute) }
44
+ AddFieldsToGraphqlType.call(klass: klass, attributes: dynamic_attributes)
51
45
  end
52
46
 
53
- def find_or_build_dynamic_graphql_types(dynamic_attributes)
54
- dynamic_attributes.each do |attribute|
55
- yield(
56
- attribute.graphql_model.graphql.name,
57
- attribute.graphql_model.graphql.description,
58
- attribute.graphql_model.graphql.attributes,
59
- attribute.graphql_model.graphql.type_name
60
- )
61
- end
47
+ def find_or_build_dynamic_type(attribute)
48
+ graphql_model = attribute.graphql_model
49
+ find_or_build_graphql_model_type(graphql_model) if graphql_model
50
+ end
51
+
52
+ def find_or_build_graphql_model_type(graphql_model)
53
+ self.class.call(
54
+ name: graphql_model.graphql.name,
55
+ description: graphql_model.graphql.description,
56
+ attributes: graphql_model.graphql.attributes,
57
+ type_name: graphql_model.graphql.type_name
58
+ )
62
59
  end
63
60
  end
64
61
  end
@@ -5,6 +5,7 @@ module GraphqlRails
5
5
  # Initializes class to define graphql type and fields.
6
6
  class FindOrBuildGraphqlTypeClass
7
7
  require 'graphql_rails/concerns/service'
8
+ require 'graphql_rails/types/object_type'
8
9
 
9
10
  include ::GraphqlRails::Service
10
11
 
@@ -32,7 +33,7 @@ module GraphqlRails
32
33
  graphql_type_name = name
33
34
  graphql_type_description = description
34
35
 
35
- graphql_type_klass = Class.new(GraphQL::Schema::Object) do
36
+ graphql_type_klass = Class.new(GraphqlRails::Types::ObjectType) do
36
37
  graphql_name(graphql_type_name)
37
38
  description(graphql_type_description)
38
39
  end
@@ -1,58 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/model/build_graphql_input_type'
4
- require 'graphql_rails/model/configurable'
5
-
6
3
  module GraphqlRails
7
4
  module Model
8
5
  # stores information about model input specific config, like attributes and types
9
6
  class Input
7
+ require 'graphql_rails/concerns/chainable_options'
8
+ require 'graphql_rails/model/configurable'
9
+ require 'graphql_rails/model/build_graphql_input_type'
10
+
10
11
  include Configurable
11
12
 
13
+ chainable_option :enum
14
+
12
15
  def initialize(model_class, input_name_suffix)
13
16
  @model_class = model_class
14
17
  @input_name_suffix = input_name_suffix
15
18
  end
16
19
 
17
- def initialize_copy(other)
18
- super
19
- @attributes = other.instance_variable_get(:@attributes)&.transform_values(&:dup)
20
- end
21
-
22
20
  def graphql_input_type
23
21
  @graphql_input_type ||= BuildGraphqlInputType.call(
24
22
  name: name, description: description, attributes: attributes
25
23
  )
26
24
  end
27
25
 
28
- def attribute(attribute_name, type: nil, enum: nil, **attribute_options)
29
- input_type = attribute_type(attribute_name, type: type, enum: enum, **attribute_options)
30
-
31
- attributes[attribute_name.to_s] = Attributes::InputAttribute.new(
32
- attribute_name, type: input_type, **attribute_options
33
- )
34
- end
35
-
36
26
  private
37
27
 
38
28
  attr_reader :input_name_suffix, :model_class
39
29
 
30
+ def build_attribute(attribute_name)
31
+ Attributes::InputAttribute.new(attribute_name, config: self)
32
+ end
33
+
40
34
  def default_name
41
35
  @default_name ||= begin
42
36
  suffix = input_name_suffix ? input_name_suffix.to_s.camelize : ''
43
37
  "#{model_class.name.split('::').last}#{suffix}Input"
44
38
  end
45
39
  end
46
-
47
- def attribute_type(attribute_name, type:, enum:, description: nil, **_other)
48
- return type unless enum
49
-
50
- BuildEnumType.call(
51
- "#{name}_#{attribute_name}_enum",
52
- allowed_values: enum,
53
- description: description
54
- )
55
- end
56
40
  end
57
41
  end
58
42
  end
@@ -8,12 +8,13 @@ module GraphqlRails
8
8
 
9
9
  include ::GraphqlRails::Service
10
10
 
11
- def initialize(group: nil, params:, schema: nil, router: nil, **schema_options)
11
+ def initialize(params:, context: {}, schema: nil, router: nil, group: nil, **schema_options) # rubocop:disable Metrics/ParameterLists
12
12
  @group = group
13
13
  @graphql_schema = schema
14
14
  @params = params
15
- @schema_options = schema_options
16
15
  @router = router
16
+ @initial_context = context
17
+ @schema_options = schema_options
17
18
  end
18
19
 
19
20
  def call
@@ -21,13 +22,18 @@ module GraphqlRails
21
22
  params[:query],
22
23
  variables: variables,
23
24
  operation_name: params[:operationName],
25
+ context: context,
24
26
  **schema_options
25
27
  )
26
28
  end
27
29
 
28
30
  private
29
31
 
30
- attr_reader :schema_options, :params, :group
32
+ attr_reader :schema_options, :params, :group, :initial_context
33
+
34
+ def context
35
+ initial_context.merge(graphql_group: group)
36
+ end
31
37
 
32
38
  def variables
33
39
  ensure_hash(params[:variables])
@@ -13,6 +13,10 @@ module GraphqlRails
13
13
  def mutation?
14
14
  true
15
15
  end
16
+
17
+ def subscription?
18
+ false
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -13,6 +13,10 @@ module GraphqlRails
13
13
  def mutation?
14
14
  false
15
15
  end
16
+
17
+ def subscription?
18
+ false
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -28,6 +28,10 @@ module GraphqlRails
28
28
  routes << build_mutation(*args, **kwargs)
29
29
  end
30
30
 
31
+ def subscription(*args, **kwargs)
32
+ routes << build_subscription(*args, **kwargs)
33
+ end
34
+
31
35
  private
32
36
 
33
37
  attr_reader :autogenerated_action_names, :name, :options
@@ -62,6 +66,10 @@ module GraphqlRails
62
66
  build_route(QueryRoute, *args, **kwargs)
63
67
  end
64
68
 
69
+ def build_subscription(*args, **kwargs)
70
+ build_route(SubscriptionRoute, *args, **kwargs)
71
+ end
72
+
65
73
  # rubocop:disable Metrics/ParameterLists
66
74
  def build_route(builder, action, prefix: action, suffix: false, on: :member, **custom_options)
67
75
  if suffix == true
@@ -6,7 +6,7 @@ module GraphqlRails
6
6
  class Router
7
7
  # Generic class for any type graphql action. Should not be used directly
8
8
  class Route
9
- attr_reader :name, :module_name, :on, :relative_path
9
+ attr_reader :name, :module_name, :on, :relative_path, :groups
10
10
 
11
11
  def initialize(name, to: '', on:, groups: nil, **options)
12
12
  @name = name.to_s.camelize(:lower)
@@ -43,7 +43,7 @@ module GraphqlRails
43
43
 
44
44
  private
45
45
 
46
- attr_reader :function, :groups
46
+ attr_reader :function
47
47
 
48
48
  def resolver
49
49
  @resolver ||= Controller::BuildControllerActionResolver.call(route: self)
@@ -6,11 +6,12 @@ module GraphqlRails
6
6
  class SchemaBuilder
7
7
  require_relative './plain_cursor_encoder'
8
8
 
9
- attr_reader :queries, :mutations, :raw_actions
9
+ attr_reader :queries, :mutations, :subscriptions, :raw_actions
10
10
 
11
- def initialize(queries:, mutations:, raw_actions:, group: nil)
11
+ def initialize(queries:, mutations:, subscriptions:, raw_actions:, group: nil)
12
12
  @queries = queries
13
13
  @mutations = mutations
14
+ @subscriptions = subscriptions
14
15
  @raw_actions = raw_actions
15
16
  @group = group
16
17
  end
@@ -18,6 +19,7 @@ module GraphqlRails
18
19
  def call
19
20
  query_type = build_group_type('Query', queries)
20
21
  mutation_type = build_group_type('Mutation', mutations)
22
+ subscription_type = build_group_type('Subscription', subscriptions)
21
23
  raw = raw_actions
22
24
 
23
25
  Class.new(GraphQL::Schema) do
@@ -30,6 +32,7 @@ module GraphqlRails
30
32
 
31
33
  query(query_type) if query_type
32
34
  mutation(mutation_type) if mutation_type
35
+ subscription(subscription_type) if subscription_type
33
36
  end
34
37
  end
35
38
 
@@ -39,7 +42,13 @@ module GraphqlRails
39
42
 
40
43
  def build_group_type(type_name, routes)
41
44
  group_name = group
42
- group_routes = routes.select { |route| route.show_in_group?(group_name) }
45
+ group_routes =
46
+ routes
47
+ .select { |route| route.show_in_group?(group_name) }
48
+ .reverse
49
+ .uniq(&:name)
50
+ .reverse
51
+
43
52
  return if group_routes.empty?
44
53
 
45
54
  build_type(type_name, group_routes)
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'route'
4
+
5
+ module GraphqlRails
6
+ class Router
7
+ # stores subscription type graphql action info
8
+ class SubscriptionRoute < Route
9
+ def query?
10
+ false
11
+ end
12
+
13
+ def mutation?
14
+ false
15
+ end
16
+
17
+ def subscription?
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
@@ -5,6 +5,7 @@ require 'active_support/core_ext/string/inflections'
5
5
  require 'graphql_rails/router/schema_builder'
6
6
  require 'graphql_rails/router/mutation_route'
7
7
  require 'graphql_rails/router/query_route'
8
+ require 'graphql_rails/router/subscription_route'
8
9
  require 'graphql_rails/router/resource_routes_builder'
9
10
 
10
11
  module GraphqlRails
@@ -27,6 +28,7 @@ module GraphqlRails
27
28
  @group_names = group_names
28
29
  @routes ||= Set.new
29
30
  @raw_graphql_actions ||= []
31
+ @graphql_schema = {}
30
32
  end
31
33
 
32
34
  def group(*group_names, &block)
@@ -57,6 +59,10 @@ module GraphqlRails
57
59
  routes << build_route(MutationRoute, name, **options)
58
60
  end
59
61
 
62
+ def subscription(name, **options)
63
+ routes << build_route(SubscriptionRoute, name, **options)
64
+ end
65
+
60
66
  RAW_ACTION_NAMES.each do |action_name|
61
67
  define_method(action_name) do |*args, &block|
62
68
  add_raw_action(action_name, *args, &block)
@@ -64,17 +70,17 @@ module GraphqlRails
64
70
  end
65
71
 
66
72
  def graphql_schema(group = nil)
67
- @graphql_schema ||= {}
68
73
  @graphql_schema[group&.to_sym] ||= SchemaBuilder.new(
69
74
  queries: routes.select(&:query?),
70
75
  mutations: routes.select(&:mutation?),
76
+ subscriptions: routes.select(&:subscription?),
71
77
  raw_actions: raw_graphql_actions,
72
78
  group: group
73
79
  ).call
74
80
  end
75
81
 
76
82
  def reload_schema
77
- @graphql_schema = nil
83
+ @graphql_schema.clear
78
84
  end
79
85
 
80
86
  private
@@ -7,51 +7,42 @@ module GraphqlRails
7
7
 
8
8
  class MissingGraphqlRouterError < GraphqlRails::Error; end
9
9
 
10
- attr_reader :name
11
-
12
- def self.call(*args)
13
- new(*args).call
10
+ def self.call(**args)
11
+ new(**args).call
14
12
  end
15
13
 
16
- def initialize(name:)
17
- @name = name
14
+ def initialize(group:, router:, dump_dir: nil)
15
+ @group = group
16
+ @router = router
17
+ @dump_dir = dump_dir
18
18
  end
19
19
 
20
20
  def call
21
- validate
22
- File.write(schema_path, schema.to_definition)
21
+ File.write(schema_path, schema_dump)
23
22
  end
24
23
 
25
24
  private
26
25
 
27
- def validate
28
- return if router
29
-
30
- error_message = \
31
- 'GraphqlRouter is missing. ' \
32
- 'Run `rails g graphql_rails:install` to build it'
33
- raise MissingGraphqlRouterError, error_message
34
- end
26
+ attr_reader :router, :group
35
27
 
36
- def router
37
- @router ||= '::GraphqlRouter'.safe_constantize
28
+ def schema_dump
29
+ context = { graphql_group: group }
30
+ schema.to_definition(context: context)
38
31
  end
39
32
 
40
33
  def schema
41
- @schema ||= ::GraphqlRouter.graphql_schema(name.presence)
34
+ @schema ||= router.graphql_schema(group.presence)
42
35
  end
43
36
 
44
37
  def schema_path
45
- ENV['GRAPHQL_SCHEMA_DUMP_PATH'] || default_schema_path
46
- end
47
-
48
- def default_schema_path
49
- schema_folder_path = Rails.root.join('spec', 'fixtures')
38
+ FileUtils.mkdir_p(dump_dir)
39
+ file_name = group.present? ? "graphql_#{group}_schema.graphql" : 'graphql_schema.graphql'
50
40
 
51
- FileUtils.mkdir_p(schema_folder_path)
52
- file_name = name.present? ? "graphql_#{name}_schema.graphql" : 'graphql_schema.graphql'
41
+ "#{dump_dir}/#{file_name}"
42
+ end
53
43
 
54
- schema_folder_path.join(file_name)
44
+ def dump_dir
45
+ @dump_dir ||= Rails.root.join('spec/fixtures').to_s
55
46
  end
56
47
  end
57
48
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails/tasks/dump_graphql_schema'
4
+
5
+ module GraphqlRails
6
+ # Generates graphql schema dump files
7
+ class DumpGraphqlSchemas
8
+ require 'graphql_rails/errors/error'
9
+
10
+ class MissingGraphqlRouterError < GraphqlRails::Error; end
11
+
12
+ def self.call(**args)
13
+ new(**args).call
14
+ end
15
+
16
+ def initialize(dump_dir:, groups: nil)
17
+ @groups = groups.presence
18
+ @dump_dir = dump_dir
19
+ end
20
+
21
+ def call
22
+ validate
23
+ return dump_default_schema if groups.empty?
24
+
25
+ groups.each { |group| dump_graphql_schema(group) }
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :dump_dir
31
+
32
+ def dump_default_schema
33
+ dump_graphql_schema('')
34
+ end
35
+
36
+ def dump_graphql_schema(group)
37
+ DumpGraphqlSchema.call(group: group, router: router, dump_dir: dump_dir)
38
+ end
39
+
40
+ def validate
41
+ return if router
42
+
43
+ error_message = \
44
+ 'GraphqlRouter is missing. ' \
45
+ 'Run `rails g graphql_rails:install` to build it'
46
+ raise MissingGraphqlRouterError, error_message
47
+ end
48
+
49
+ def router
50
+ @router ||= '::GraphqlRouter'.safe_constantize
51
+ end
52
+
53
+ def groups
54
+ @groups ||= router.routes.flat_map(&:groups).uniq
55
+ end
56
+ end
57
+ end
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/tasks/dump_graphql_schema'
3
+ require 'graphql_rails/tasks/dump_graphql_schemas'
4
4
 
5
5
  namespace :graphql_rails do
6
6
  namespace :schema do
7
7
  desc 'Dump GraphQL schema'
8
- task(:dump, %i[name] => :environment) do |_, args|
9
- default_name = ENV.fetch('SCHEMA_GROUP_NAME', '')
10
- args.with_defaults(name: default_name)
11
- GraphqlRails::DumpGraphqlSchema.call(name: args.name)
8
+ task(dump: :environment) do |_, args|
9
+ groups_from_args = args.extras
10
+ groups_from_env = ENV['SCHEMA_GROUP_NAME'].to_s.split(',').map(&:strip)
11
+ groups = groups_from_args + groups_from_env
12
+ dump_dir = ENV.fetch('GRAPHQL_SCHEMA_DUMP_DIR') { Rails.root.join('spec/fixtures').to_s }
13
+
14
+ GraphqlRails::DumpGraphqlSchemas.call(groups: groups, dump_dir: dump_dir)
12
15
  end
13
16
  end
14
17
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails/types/hidable_by_group'
4
+
5
+ module GraphqlRails
6
+ module Types
7
+ # Base argument type for all GraphqlRails inputs
8
+ class ArgumentType < GraphQL::Schema::Argument
9
+ include GraphqlRails::Types::HidableByGroup
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails/types/argument_type'
4
+ require 'graphql_rails/types/hidable_by_group'
5
+
6
+ module GraphqlRails
7
+ module Types
8
+ # Base field for all GraphqlRails model fields
9
+ class FieldType < GraphQL::Schema::Field
10
+ include GraphqlRails::Types::HidableByGroup
11
+ argument_class(GraphqlRails::Types::ArgumentType)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails/types/argument_type'
4
+
5
+ module GraphqlRails
6
+ module Types
7
+ # Add visibility option based on groups
8
+ module HidableByGroup
9
+ def initialize(*args, groups: [], **kwargs, &block)
10
+ super(*args, **kwargs, &block)
11
+
12
+ @groups = groups.map(&:to_s)
13
+ end
14
+
15
+ def visible?(context)
16
+ super && visible_in_context_group?(context)
17
+ end
18
+
19
+ private
20
+
21
+ def groups
22
+ @groups
23
+ end
24
+
25
+ def visible_in_context_group?(context)
26
+ group = context[:graphql_group] || context['graphql_group']
27
+
28
+ group.nil? || groups.empty? || groups.include?(group.to_s)
29
+ end
30
+ end
31
+ end
32
+ end