graphql_rails 0.7.0 → 1.2.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 +4 -4
- data/.hound.yml +1 -0
- data/.rubocop.yml +3 -3
- data/.ruby-version +1 -1
- data/.travis.yml +2 -2
- data/CHANGELOG.md +35 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +181 -71
- data/docs/README.md +40 -8
- data/docs/_sidebar.md +5 -0
- data/docs/components/controller.md +295 -9
- data/docs/components/decorator.md +69 -0
- data/docs/components/model.md +267 -6
- data/docs/components/routes.md +28 -0
- data/docs/getting_started/quick_start.md +10 -3
- data/docs/index.html +1 -1
- data/docs/logging_and_monitoring/logging_and_monitoring.md +35 -0
- data/docs/other_tools/query_runner.md +49 -0
- data/docs/other_tools/schema_dump.md +29 -0
- data/docs/testing/testing.md +3 -1
- data/graphql_rails.gemspec +5 -4
- data/lib/generators/graphql_rails/install_generator.rb +50 -0
- data/lib/generators/graphql_rails/templates/example_users_controller.erb +19 -0
- data/lib/generators/graphql_rails/templates/graphql_application_controller.erb +8 -0
- data/lib/generators/graphql_rails/templates/graphql_controller.erb +20 -0
- data/lib/generators/graphql_rails/templates/graphql_router.erb +19 -0
- data/lib/generators/graphql_rails/templates/graphql_router_spec.erb +21 -0
- data/lib/graphql_rails.rb +6 -0
- data/lib/graphql_rails/attributes/attributable.rb +22 -17
- data/lib/graphql_rails/attributes/attribute.rb +67 -3
- data/lib/graphql_rails/attributes/attribute_name_parser.rb +4 -4
- data/lib/graphql_rails/attributes/input_attribute.rb +33 -15
- data/lib/graphql_rails/attributes/input_type_parser.rb +62 -0
- data/lib/graphql_rails/attributes/type_name_info.rb +38 -0
- data/lib/graphql_rails/attributes/type_parseable.rb +132 -0
- data/lib/graphql_rails/attributes/type_parser.rb +59 -53
- data/lib/graphql_rails/concerns/service.rb +19 -0
- data/lib/graphql_rails/controller.rb +42 -21
- data/lib/graphql_rails/controller/action.rb +12 -67
- data/lib/graphql_rails/controller/action_configuration.rb +70 -28
- data/lib/graphql_rails/controller/build_controller_action_resolver.rb +52 -0
- data/lib/graphql_rails/controller/build_controller_action_resolver/controller_action_resolver.rb +28 -0
- data/lib/graphql_rails/controller/configuration.rb +56 -3
- data/lib/graphql_rails/controller/log_controller_action.rb +71 -0
- data/lib/graphql_rails/controller/request.rb +29 -8
- data/lib/graphql_rails/controller/request/format_errors.rb +58 -0
- data/lib/graphql_rails/decorator.rb +41 -0
- data/lib/graphql_rails/decorator/relation_decorator.rb +75 -0
- data/lib/graphql_rails/errors/custom_execution_error.rb +22 -0
- data/lib/graphql_rails/errors/execution_error.rb +6 -7
- data/lib/graphql_rails/errors/system_error.rb +14 -0
- data/lib/graphql_rails/errors/validation_error.rb +1 -5
- data/lib/graphql_rails/input_configurable.rb +47 -0
- data/lib/graphql_rails/integrations.rb +19 -0
- data/lib/graphql_rails/integrations/lograge.rb +39 -0
- data/lib/graphql_rails/integrations/sentry.rb +34 -0
- data/lib/graphql_rails/model.rb +26 -4
- data/lib/graphql_rails/model/add_fields_to_graphql_type.rb +45 -0
- data/lib/graphql_rails/model/build_connection_type.rb +52 -0
- data/lib/graphql_rails/model/{configuration → build_connection_type}/count_items.rb +5 -5
- data/lib/graphql_rails/model/build_enum_type.rb +39 -10
- data/lib/graphql_rails/model/build_graphql_input_type.rb +8 -4
- data/lib/graphql_rails/model/call_graphql_model_method.rb +72 -0
- data/lib/graphql_rails/model/configurable.rb +6 -2
- data/lib/graphql_rails/model/configuration.rb +30 -16
- data/lib/graphql_rails/model/find_or_build_graphql_type.rb +64 -0
- data/lib/graphql_rails/model/find_or_build_graphql_type_class.rb +46 -0
- data/lib/graphql_rails/model/input.rb +11 -7
- data/lib/graphql_rails/query_runner.rb +68 -0
- data/lib/graphql_rails/railtie.rb +10 -0
- data/lib/graphql_rails/router.rb +40 -13
- data/lib/graphql_rails/router/resource_routes_builder.rb +10 -9
- data/lib/graphql_rails/router/route.rb +21 -6
- data/lib/graphql_rails/router/schema_builder.rb +30 -11
- data/lib/graphql_rails/rspec_controller_helpers.rb +6 -4
- data/lib/graphql_rails/tasks/dump_graphql_schema.rb +57 -0
- data/lib/graphql_rails/tasks/schema.rake +14 -0
- data/lib/graphql_rails/version.rb +1 -1
- metadata +70 -19
- data/lib/graphql_rails/controller/controller_function.rb +0 -50
- data/lib/graphql_rails/controller/format_results.rb +0 -36
- data/lib/graphql_rails/model/build_graphql_type.rb +0 -37
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlRails
|
4
|
+
module Model
|
5
|
+
# Executes model method and adds additional meta data if needed
|
6
|
+
class CallGraphqlModelMethod
|
7
|
+
require 'graphql_rails/concerns/service'
|
8
|
+
|
9
|
+
include ::GraphqlRails::Service
|
10
|
+
|
11
|
+
PAGINATION_KEYS = %i[before after first last].freeze
|
12
|
+
|
13
|
+
def initialize(model:, method_keyword_arguments:, graphql_context:, attribute_config:)
|
14
|
+
@model = model
|
15
|
+
@method_keyword_arguments = method_keyword_arguments
|
16
|
+
@graphql_context = graphql_context
|
17
|
+
@attribute_config = attribute_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
with_graphql_context do
|
22
|
+
run_method
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :model, :attribute_config, :graphql_context, :method_keyword_arguments
|
29
|
+
|
30
|
+
def run_method
|
31
|
+
if custom_keyword_arguments.empty?
|
32
|
+
model.send(method_name)
|
33
|
+
else
|
34
|
+
formatted_arguments = formatted_method_input(custom_keyword_arguments)
|
35
|
+
model.send(method_name, **formatted_arguments)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def formatted_method_input(keyword_arguments)
|
40
|
+
keyword_arguments.transform_values do |input_argument|
|
41
|
+
formatted_method_input_argument(input_argument)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def formatted_method_input_argument(argument)
|
46
|
+
return argument.to_h if argument.is_a?(GraphQL::Schema::InputObject)
|
47
|
+
|
48
|
+
argument
|
49
|
+
end
|
50
|
+
|
51
|
+
def method_name
|
52
|
+
attribute_config.property
|
53
|
+
end
|
54
|
+
|
55
|
+
def paginated?
|
56
|
+
attribute_config.paginated?
|
57
|
+
end
|
58
|
+
|
59
|
+
def custom_keyword_arguments
|
60
|
+
return method_keyword_arguments unless paginated?
|
61
|
+
|
62
|
+
method_keyword_arguments.except(*PAGINATION_KEYS)
|
63
|
+
end
|
64
|
+
|
65
|
+
def with_graphql_context
|
66
|
+
return yield unless model.respond_to?(:with_graphql_context)
|
67
|
+
|
68
|
+
model.with_graphql_context(graphql_context) { yield }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -9,11 +9,15 @@ module GraphqlRails
|
|
9
9
|
@attributes ||= {}
|
10
10
|
end
|
11
11
|
|
12
|
-
def name(
|
13
|
-
@name =
|
12
|
+
def name(graphql_name = nil)
|
13
|
+
@name = graphql_name if graphql_name
|
14
14
|
@name || default_name
|
15
15
|
end
|
16
16
|
|
17
|
+
def type_name
|
18
|
+
@type_name ||= "#{name.camelize}Type#{SecureRandom.hex}"
|
19
|
+
end
|
20
|
+
|
17
21
|
def description(new_description = nil)
|
18
22
|
@description = new_description if new_description
|
19
23
|
@description
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'graphql_rails/attributes'
|
4
|
-
require 'graphql_rails/model/
|
4
|
+
require 'graphql_rails/model/find_or_build_graphql_type'
|
5
5
|
require 'graphql_rails/model/build_enum_type'
|
6
6
|
require 'graphql_rails/model/input'
|
7
7
|
require 'graphql_rails/model/configurable'
|
8
|
-
require 'graphql_rails/model/
|
8
|
+
require 'graphql_rails/model/build_connection_type'
|
9
9
|
|
10
10
|
module GraphqlRails
|
11
11
|
module Model
|
@@ -17,13 +17,28 @@ module GraphqlRails
|
|
17
17
|
@model_class = model_class
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
def initialize_copy(other)
|
21
|
+
super
|
22
|
+
@connection_type = nil
|
23
|
+
@graphql_type = nil
|
24
|
+
@input = other.instance_variable_get(:@input)&.transform_values(&:dup)
|
25
|
+
@attributes = other.instance_variable_get(:@attributes)&.transform_values(&:dup)
|
26
|
+
end
|
27
|
+
|
28
|
+
def attribute(attribute_name, **attribute_options)
|
29
|
+
key = attribute_name.to_s
|
30
|
+
|
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?
|
41
|
+
end
|
27
42
|
end
|
28
43
|
|
29
44
|
def input(input_name = nil)
|
@@ -41,17 +56,16 @@ module GraphqlRails
|
|
41
56
|
end
|
42
57
|
|
43
58
|
def graphql_type
|
44
|
-
@graphql_type ||=
|
45
|
-
name: name,
|
59
|
+
@graphql_type ||= FindOrBuildGraphqlType.call(
|
60
|
+
name: name,
|
61
|
+
description: description,
|
62
|
+
attributes: attributes,
|
63
|
+
type_name: type_name
|
46
64
|
)
|
47
65
|
end
|
48
66
|
|
49
67
|
def connection_type
|
50
|
-
@connection_type ||=
|
51
|
-
graphql_type.define_connection do
|
52
|
-
field :total, types.Int, resolve: CountItems
|
53
|
-
end
|
54
|
-
end
|
68
|
+
@connection_type ||= BuildConnectionType.call(graphql_type)
|
55
69
|
end
|
56
70
|
|
57
71
|
private
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlRails
|
4
|
+
module Model
|
5
|
+
# stores information about model specific config, like attributes and types
|
6
|
+
class FindOrBuildGraphqlType
|
7
|
+
require 'graphql_rails/concerns/service'
|
8
|
+
require 'graphql_rails/model/find_or_build_graphql_type_class'
|
9
|
+
require 'graphql_rails/model/add_fields_to_graphql_type'
|
10
|
+
|
11
|
+
include ::GraphqlRails::Service
|
12
|
+
|
13
|
+
def initialize(name:, description:, attributes:, type_name:)
|
14
|
+
@name = name
|
15
|
+
@description = description
|
16
|
+
@attributes = attributes
|
17
|
+
@type_name = type_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
klass.tap { add_fields_to_graphql_type if new_class? }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :name, :description, :attributes, :type_name
|
27
|
+
|
28
|
+
delegate :klass, :new_class?, to: :type_class_finder
|
29
|
+
|
30
|
+
def type_class_finder
|
31
|
+
@type_class_finder ||= FindOrBuildGraphqlTypeClass.new(
|
32
|
+
name: name,
|
33
|
+
type_name: type_name,
|
34
|
+
description: description
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_fields_to_graphql_type
|
39
|
+
AddFieldsToGraphqlType.call(klass: klass, attributes: attributes.values.select(&:scalar_type?))
|
40
|
+
|
41
|
+
attributes.values.reject(&:scalar_type?).tap do |dynamic_attributes|
|
42
|
+
find_or_build_dynamic_graphql_types(dynamic_attributes) do |name, description, attributes, type_name|
|
43
|
+
self.class.call(
|
44
|
+
name: name, description: description,
|
45
|
+
attributes: attributes, type_name: type_name
|
46
|
+
)
|
47
|
+
end
|
48
|
+
AddFieldsToGraphqlType.call(klass: klass, attributes: dynamic_attributes)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_or_build_dynamic_graphql_types(dynamic_attributes)
|
53
|
+
dynamic_attributes.each do |attribute|
|
54
|
+
yield(
|
55
|
+
attribute.graphql_model.graphql.name,
|
56
|
+
attribute.graphql_model.graphql.description,
|
57
|
+
attribute.graphql_model.graphql.attributes,
|
58
|
+
attribute.graphql_model.graphql.type_name
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlRails
|
4
|
+
module Model
|
5
|
+
# Initializes class to define graphql type and fields.
|
6
|
+
class FindOrBuildGraphqlTypeClass
|
7
|
+
require 'graphql_rails/concerns/service'
|
8
|
+
|
9
|
+
include ::GraphqlRails::Service
|
10
|
+
|
11
|
+
def initialize(name:, type_name:, description: nil)
|
12
|
+
@name = name
|
13
|
+
@type_name = type_name
|
14
|
+
@description = description
|
15
|
+
@new_class = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def klass
|
19
|
+
@klass ||= Object.const_defined?(type_name) && Object.const_get(type_name) || build_graphql_type_klass
|
20
|
+
end
|
21
|
+
|
22
|
+
def new_class?
|
23
|
+
new_class
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_accessor :new_class
|
29
|
+
attr_reader :name, :type_name, :description
|
30
|
+
|
31
|
+
def build_graphql_type_klass
|
32
|
+
graphql_type_name = name
|
33
|
+
graphql_type_description = description
|
34
|
+
|
35
|
+
graphql_type_klass = Class.new(GraphQL::Schema::Object) do
|
36
|
+
graphql_name(graphql_type_name)
|
37
|
+
description(graphql_type_description)
|
38
|
+
end
|
39
|
+
|
40
|
+
self.new_class = true
|
41
|
+
|
42
|
+
Object.const_set(type_name, graphql_type_klass)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -14,6 +14,11 @@ module GraphqlRails
|
|
14
14
|
@input_name_suffix = input_name_suffix
|
15
15
|
end
|
16
16
|
|
17
|
+
def initialize_copy(other)
|
18
|
+
super
|
19
|
+
@attributes = other.instance_variable_get(:@attributes)&.transform_values(&:dup)
|
20
|
+
end
|
21
|
+
|
17
22
|
def graphql_input_type
|
18
23
|
@graphql_input_type ||= BuildGraphqlInputType.call(
|
19
24
|
name: name, description: description, attributes: attributes
|
@@ -21,12 +26,11 @@ module GraphqlRails
|
|
21
26
|
end
|
22
27
|
|
23
28
|
def attribute(attribute_name, type: nil, enum: nil, **attribute_options)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
)
|
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
|
+
)
|
30
34
|
end
|
31
35
|
|
32
36
|
private
|
@@ -35,7 +39,7 @@ module GraphqlRails
|
|
35
39
|
|
36
40
|
def default_name
|
37
41
|
@default_name ||= begin
|
38
|
-
suffix = input_name_suffix ? input_name_suffix.to_s.
|
42
|
+
suffix = input_name_suffix ? input_name_suffix.to_s.camelize : ''
|
39
43
|
"#{model_class.name.split('::').last}#{suffix}Input"
|
40
44
|
end
|
41
45
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlRails
|
4
|
+
# executes GraphQL queries and returns json
|
5
|
+
class QueryRunner
|
6
|
+
require 'graphql_rails/router'
|
7
|
+
require 'graphql_rails/concerns/service'
|
8
|
+
|
9
|
+
include ::GraphqlRails::Service
|
10
|
+
|
11
|
+
def initialize(group: nil, params:, schema: nil, router: nil, **schema_options)
|
12
|
+
@group = group
|
13
|
+
@graphql_schema = schema
|
14
|
+
@params = params
|
15
|
+
@schema_options = schema_options
|
16
|
+
@router = router
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
graphql_schema.execute(
|
21
|
+
params[:query],
|
22
|
+
variables: variables,
|
23
|
+
operation_name: params[:operationName],
|
24
|
+
**schema_options
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :schema_options, :params, :group
|
31
|
+
|
32
|
+
def variables
|
33
|
+
ensure_hash(params[:variables])
|
34
|
+
end
|
35
|
+
|
36
|
+
def graphql_schema
|
37
|
+
@graphql_schema ||= router_schema
|
38
|
+
end
|
39
|
+
|
40
|
+
def router
|
41
|
+
@router ||= ::GraphqlRouter
|
42
|
+
end
|
43
|
+
|
44
|
+
def router_schema
|
45
|
+
router.graphql_schema(group)
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_hash(ambiguous_param)
|
49
|
+
if ambiguous_param.blank?
|
50
|
+
{}
|
51
|
+
elsif ambiguous_param.is_a?(String)
|
52
|
+
ensure_hash(JSON.parse(ambiguous_param))
|
53
|
+
elsif kind_of_hash?(ambiguous_param)
|
54
|
+
ambiguous_param
|
55
|
+
else
|
56
|
+
raise ArgumentError, "Unexpected parameter: #{ambiguous_param.inspect}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def kind_of_hash?(object)
|
61
|
+
return true if object.is_a?(Hash)
|
62
|
+
|
63
|
+
defined?(ActionController) &&
|
64
|
+
defined?(ActionController::Parameters) &&
|
65
|
+
object.is_a?(ActionController::Parameters)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/graphql_rails/router.rb
CHANGED
@@ -11,32 +11,39 @@ module GraphqlRails
|
|
11
11
|
# graphql router that mimics Rails.application.routes
|
12
12
|
class Router
|
13
13
|
RAW_ACTION_NAMES = %i[
|
14
|
-
rescue_from query_analyzer instrument cursor_encoder default_max_page_size
|
14
|
+
use rescue_from query_analyzer instrument cursor_encoder default_max_page_size
|
15
15
|
].freeze
|
16
16
|
|
17
17
|
def self.draw(&block)
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
new.tap do |router|
|
19
|
+
router.instance_eval(&block)
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
23
|
attr_reader :routes, :namespace_name, :raw_graphql_actions
|
24
24
|
|
25
|
-
def initialize(module_name: '')
|
25
|
+
def initialize(module_name: '', group_names: [])
|
26
26
|
@module_name = module_name
|
27
|
+
@group_names = group_names
|
27
28
|
@routes ||= Set.new
|
28
29
|
@raw_graphql_actions ||= []
|
29
30
|
end
|
30
31
|
|
32
|
+
def group(*group_names, &block)
|
33
|
+
scoped_router = router_with(group_names: group_names)
|
34
|
+
scoped_router.instance_eval(&block)
|
35
|
+
routes.merge(scoped_router.routes)
|
36
|
+
end
|
37
|
+
|
31
38
|
def scope(**options, &block)
|
32
39
|
full_module_name = [module_name, options[:module]].reject(&:empty?).join('/')
|
33
|
-
scoped_router =
|
40
|
+
scoped_router = router_with(module_name: full_module_name)
|
34
41
|
scoped_router.instance_eval(&block)
|
35
42
|
routes.merge(scoped_router.routes)
|
36
43
|
end
|
37
44
|
|
38
45
|
def resources(name, **options, &block)
|
39
|
-
builder_options =
|
46
|
+
builder_options = full_route_options(options)
|
40
47
|
routes_builder = ResourceRoutesBuilder.new(name, **builder_options)
|
41
48
|
routes_builder.instance_eval(&block) if block
|
42
49
|
routes.merge(routes_builder.routes)
|
@@ -56,25 +63,45 @@ module GraphqlRails
|
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
59
|
-
def graphql_schema
|
60
|
-
|
66
|
+
def graphql_schema(group = nil)
|
67
|
+
@graphql_schema ||= {}
|
68
|
+
@graphql_schema[group&.to_sym] ||= SchemaBuilder.new(
|
61
69
|
queries: routes.select(&:query?),
|
62
70
|
mutations: routes.select(&:mutation?),
|
63
|
-
raw_actions: raw_graphql_actions
|
71
|
+
raw_actions: raw_graphql_actions,
|
72
|
+
group: group
|
64
73
|
).call
|
65
74
|
end
|
66
75
|
|
76
|
+
def reload_schema
|
77
|
+
@graphql_schema = nil
|
78
|
+
end
|
79
|
+
|
67
80
|
private
|
68
81
|
|
69
|
-
attr_reader :module_name
|
82
|
+
attr_reader :module_name, :group_names
|
83
|
+
|
84
|
+
def router_with(new_router_options = {})
|
85
|
+
default_options = { module_name: module_name, group_names: group_names }
|
86
|
+
full_options = default_options.merge(new_router_options)
|
87
|
+
|
88
|
+
self.class.new(**full_options)
|
89
|
+
end
|
70
90
|
|
71
91
|
def add_raw_action(name, *args, &block)
|
72
92
|
raw_graphql_actions << { name: name, args: args, block: block }
|
73
93
|
end
|
74
94
|
|
75
95
|
def build_route(route_builder, name, **options)
|
76
|
-
|
77
|
-
|
96
|
+
route_builder.new(name, **full_route_options(options))
|
97
|
+
end
|
98
|
+
|
99
|
+
def full_route_options(extra_options)
|
100
|
+
extra_groups = Array(extra_options[:group]) + Array(extra_options[:groups])
|
101
|
+
extra_options = extra_options.except(:group, :groups)
|
102
|
+
groups = (group_names + extra_groups).uniq
|
103
|
+
|
104
|
+
default_route_options.merge(extra_options).merge(groups: groups)
|
78
105
|
end
|
79
106
|
|
80
107
|
def default_route_options
|