groovestack-base 0.1.7 → 0.1.10
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/.rubocop.yml +1 -1
- data/CHANGELOG.md +5 -1
- data/Gemfile +5 -1
- data/config/initializers/graphql.rb +2 -0
- data/groovestack-base.gemspec +1 -1
- data/lib/groovestack/base/graphql/authorization/authorized_field.rb +21 -0
- data/lib/groovestack/base/graphql/authorization/authorized_object.rb +13 -0
- data/lib/groovestack/base/graphql/authorization/visible_field.rb +23 -0
- data/lib/groovestack/base/graphql/base/argument.rb +17 -0
- data/lib/groovestack/base/graphql/base/field.rb +32 -0
- data/lib/groovestack/base/graphql/base/input_object.rb +13 -0
- data/lib/groovestack/base/graphql/base/mutation.rb +25 -0
- data/lib/groovestack/base/graphql/base/object.rb +13 -0
- data/lib/groovestack/base/graphql/base/subscription.rb +15 -0
- data/lib/groovestack/base/graphql/controllers/graphql_controller.rb +57 -0
- data/lib/groovestack/base/graphql/{documentation.rb → documentation/arguments.rb} +0 -7
- data/lib/groovestack/base/graphql/documentation/fields.rb +20 -0
- data/lib/groovestack/base/graphql/mutations/aasm_event_trigger.rb +42 -0
- data/lib/groovestack/base/graphql/mutations/method_trigger.rb +36 -0
- data/lib/groovestack/base/graphql/providers/react_admin.rb +180 -0
- data/lib/groovestack/base/graphql/subscriptions/{event_handler.rb → trigger.rb} +1 -1
- data/lib/groovestack/base/graphql/{tracers/atomic_multiplex_transaction.rb → tracers.rb} +22 -12
- data/lib/groovestack/base/graphql/types/aasm_event_attributes.rb +28 -0
- data/lib/groovestack/base/graphql/types/currency.rb +16 -0
- data/lib/groovestack/base/graphql/types/money.rb +23 -0
- data/lib/groovestack/base/graphql/types/subscription_payload.rb +15 -0
- data/lib/groovestack/base/graphql/types/type_resolver.rb +21 -0
- data/lib/groovestack/base/version.rb +1 -1
- data/lib/groovestack/base.rb +77 -22
- metadata +26 -14
- data/lib/groovestack/base/graphql/base_input_object.rb +0 -11
- data/lib/groovestack/base/graphql/base_mutation.rb +0 -23
- data/lib/groovestack/base/graphql/base_subscription.rb +0 -13
- data/lib/groovestack/base/graphql/helpers.rb +0 -152
- data/lib/groovestack/base/graphql/providers/react_admin/resource.rb +0 -146
- data/lib/groovestack/base/graphql/providers/react_admin/types.rb +0 -17
- data/lib/groovestack/base/graphql/types.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a311efec7ea663cb5f48572a3a47455355153e81f34c7a4335b57a0b6e7bcd1
|
4
|
+
data.tar.gz: e7271df5eccd6fb19e6554b81bff4bffa682e383898fc7792307092aeae262be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 798cfee3f783ab9724cc13833e04b23be4bad6988be974edbbee76e16888746e85a08d758768ff55a901cbc897fc8e9a9494fa8787000d2065737dc50faf3c27
|
7
|
+
data.tar.gz: d713e07a8b1260dd326d8f94d987a20216abf69b5eb44462cf91221a31e68ac09a89cece41c4c980f16f0d9990fccb70f3d14316d483fff0cf325174f76f4f9e
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/groovestack-base.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'Groovestack::Base defines reusable extensions for the CORE Platform.'
|
13
13
|
spec.post_install_message = 'Groovestack::Base installed'
|
14
14
|
|
15
|
-
spec.homepage = 'https://
|
15
|
+
spec.homepage = 'https://talysto.com/tech/groovestack/'
|
16
16
|
spec.required_ruby_version = '>= 3.1.0'
|
17
17
|
|
18
18
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Authorization
|
7
|
+
class AuthorizedField < ::Groovestack::Base::GraphQL::Base::Field
|
8
|
+
def authorized?(obj, args, ctx)
|
9
|
+
authorized_fields = begin
|
10
|
+
obj.authorized_fields_for_serialization(ctx[:current_user])
|
11
|
+
rescue StandardError
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
super && authorized_fields.include?(name.to_sym)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Authorization
|
7
|
+
class AuthorizedObject < ::Groovestack::Base::GraphQL::Base::Object
|
8
|
+
field_class ::Groovestack::Base::GraphQL::Authorization::AuthorizedField
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Authorization
|
7
|
+
class VisibleField < ::Groovestack::Base::GraphQL::Base::Field
|
8
|
+
def visible?(context)
|
9
|
+
return super unless @visibility_permission
|
10
|
+
|
11
|
+
# visibility profile are the visibility levels the
|
12
|
+
# current user is authorized for
|
13
|
+
visibility_profile = context.schema.visibility_profile_for_context(context).map(&:to_sym)
|
14
|
+
|
15
|
+
return super unless visibility_profile
|
16
|
+
|
17
|
+
super && visibility_profile.include?(@visibility_permission.to_sym)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Base
|
7
|
+
class Argument < ::GraphQL::Schema::Argument
|
8
|
+
def initialize(*args, camelize: ::Groovestack::Base.config.graphql.camelize, **kwargs, &block)
|
9
|
+
# Then, call super _without_ any args, where Ruby will take
|
10
|
+
# _all_ the args originally passed to this method and pass it to the super method.
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Base
|
7
|
+
class Field < ::GraphQL::Schema::Field
|
8
|
+
argument_class ::Groovestack::Base::GraphQL::Base::Argument
|
9
|
+
|
10
|
+
attr_accessor :authenticate, :visibility_permission
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/ParameterLists
|
13
|
+
def initialize(
|
14
|
+
*args,
|
15
|
+
authenticate: nil,
|
16
|
+
visibility_permission: nil,
|
17
|
+
null: false,
|
18
|
+
camelize: ::Groovestack::Base.config.graphql.camelize,
|
19
|
+
**kwargs, &block
|
20
|
+
)
|
21
|
+
# Then, call super _without_ any args, where Ruby will take
|
22
|
+
# _all_ the args originally passed to this method and pass it to the super method.
|
23
|
+
@authenticate = authenticate
|
24
|
+
@visibility_permission = visibility_permission
|
25
|
+
super(*args, null: null, camelize: camelize, **kwargs, &block)
|
26
|
+
end
|
27
|
+
# rubocop:enable Metrics/ParameterLists
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Base
|
7
|
+
class Mutation < ::GraphQL::Schema::Mutation
|
8
|
+
argument_class ::Groovestack::Base::GraphQL::Base::Argument
|
9
|
+
|
10
|
+
def resolve(**args)
|
11
|
+
perform(**args)
|
12
|
+
rescue StandardError => e
|
13
|
+
Groovestack::Base.notify_error(self.class, e)
|
14
|
+
|
15
|
+
raise e
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform(**args)
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Base
|
7
|
+
class Subscription < ::GraphQL::Schema::Subscription
|
8
|
+
argument_class ::Groovestack::Base::GraphQL::Base::Argument
|
9
|
+
field_class ::Groovestack::Base::GraphQL::Base::Field
|
10
|
+
object_class ::Groovestack::Base::GraphQL::Base::Object
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Controllers
|
7
|
+
module GraphQLController
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do # rubocop:disable Metrics/BlockLength
|
11
|
+
private
|
12
|
+
|
13
|
+
def operation_name
|
14
|
+
params[:operationName]
|
15
|
+
end
|
16
|
+
|
17
|
+
def query
|
18
|
+
params[:query]
|
19
|
+
end
|
20
|
+
|
21
|
+
def variables
|
22
|
+
prepare_variables(params[:variables])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Handle variables in form data, JSON body, or a blank value
|
26
|
+
def prepare_variables(variables_param)
|
27
|
+
case variables_param
|
28
|
+
when String
|
29
|
+
if variables_param.present?
|
30
|
+
JSON.parse(variables_param) || {}
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
when Hash
|
35
|
+
variables_param
|
36
|
+
when ActionController::Parameters
|
37
|
+
variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables.
|
38
|
+
when nil
|
39
|
+
{}
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Unexpected parameter: #{variables_param}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_error_in_development(err)
|
46
|
+
logger.error err.message
|
47
|
+
logger.error err.backtrace.join('\/n')
|
48
|
+
|
49
|
+
render json: { errors: [{ message: err.message, backtrace: err.backtrace }], data: {} },
|
50
|
+
status: :internal_server_error
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -15,13 +15,6 @@ module Groovestack
|
|
15
15
|
sort_order: 'order with which to sort the results (i.e. ASC, DESC)',
|
16
16
|
filter: 'hash of parameters by which to filter the results (i.e. { ids: [1,2,3] })'
|
17
17
|
})
|
18
|
-
Fields = OpenStruct.new({
|
19
|
-
created_at: 'time of record creation',
|
20
|
-
id: 'a unique record identifier',
|
21
|
-
relation_count: 'total number of records in a given scope',
|
22
|
-
updated_at: 'time of last record update'
|
23
|
-
})
|
24
|
-
|
25
18
|
# rubocop:enable Style/OpenStructUse
|
26
19
|
end
|
27
20
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Groovestack
|
6
|
+
module Base
|
7
|
+
module GraphQL
|
8
|
+
module Documentation
|
9
|
+
# rubocop:disable Style/OpenStructUse
|
10
|
+
Fields = OpenStruct.new({
|
11
|
+
created_at: 'time of record creation',
|
12
|
+
id: 'a unique record identifier',
|
13
|
+
relation_count: 'total number of records in a given scope',
|
14
|
+
updated_at: 'time of last record update'
|
15
|
+
})
|
16
|
+
# rubocop:enable Style/OpenStructUse
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Mutations
|
7
|
+
module AASMEventTrigger
|
8
|
+
def trigger_status_event!(obj:, attrs:, event:, args: nil, authorization_policy: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
9
|
+
# NOTE: args spread requires keys to be symbols, but by default
|
10
|
+
# they are passed as strings. This is why we use `symbolize_keys` here
|
11
|
+
raise ::GraphQL::ExecutionError, 'event not present' if event.blank?
|
12
|
+
|
13
|
+
event = event.gsub('!', '').to_sym
|
14
|
+
|
15
|
+
if attrs.present?
|
16
|
+
raise ::GraphQL::ExecutionError,
|
17
|
+
'Cannot update multiple attributes when firing instance methods'
|
18
|
+
end
|
19
|
+
unless obj.aasm.events.map(&:name).include?(event)
|
20
|
+
raise ::GraphQL::ExecutionError,
|
21
|
+
"#{event.capitalize} unavailable"
|
22
|
+
end
|
23
|
+
unless authorization_policy.nil? || authorization_policy.permitted_aasm_events.include?(event)
|
24
|
+
raise ::GraphQL::ExecutionError,
|
25
|
+
"Unauthorized not allowed to #{event} this #{obj.class}"
|
26
|
+
end
|
27
|
+
|
28
|
+
event = :"#{event}!"
|
29
|
+
|
30
|
+
if args.present? && args.is_a?(Array)
|
31
|
+
obj.send(event.to_s, *args)
|
32
|
+
elsif args.present? && args.is_a?(Hash)
|
33
|
+
obj.send(event.to_s, **args.symbolize_keys!)
|
34
|
+
else
|
35
|
+
obj.send(event.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groovestack
|
4
|
+
module Base
|
5
|
+
module GraphQL
|
6
|
+
module Mutations
|
7
|
+
module MethodTrigger
|
8
|
+
def trigger_instance_method!(obj:, attrs:, instance_method:, args: nil, authorization_policy: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
9
|
+
raise GraphQL::ExecutionError, 'instance_method not present' if instance_method.blank?
|
10
|
+
|
11
|
+
instance_method = instance_method.to_sym
|
12
|
+
|
13
|
+
raise ::GraphQL::ExecutionError, 'instance_method undefined' unless obj.respond_to?(instance_method)
|
14
|
+
|
15
|
+
if attrs.present?
|
16
|
+
raise ::GraphQL::ExecutionError,
|
17
|
+
'Cannot update multiple attributes when triggering instance method'
|
18
|
+
end
|
19
|
+
unless authorization_policy.nil? || authorization_policy.permitted_instance_methods.include?(instance_method) # rubocop:disable Layout/LineLength
|
20
|
+
raise ::GraphQL::ExecutionError,
|
21
|
+
"Unauthorized not allowed to trigger #{instance_method} for this #{obj.class}"
|
22
|
+
end
|
23
|
+
|
24
|
+
if args.present? && args.is_a?(Array)
|
25
|
+
obj.send(instance_method.to_s, *args)
|
26
|
+
elsif args.present? && args.is_a?(Hash)
|
27
|
+
obj.send(instance_method.to_s, **args.symbolize_keys!)
|
28
|
+
else
|
29
|
+
obj.send(instance_method.to_s)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/BlockLength, Metrics/ModuleLength, Metrics/ParameterLists
|
4
|
+
|
5
|
+
module Groovestack
|
6
|
+
module Base
|
7
|
+
module GraphQL
|
8
|
+
module Providers
|
9
|
+
module ReactAdmin
|
10
|
+
module Types
|
11
|
+
class RAListMetadata < ::GraphQL::Schema::Object
|
12
|
+
field :count, Int, null: false, description: Documentation::Fields.relation_count
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Resource
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
class_methods do
|
20
|
+
# TODO: make authorize default to true
|
21
|
+
|
22
|
+
def react_admin_resource(entity,
|
23
|
+
class_name: nil,
|
24
|
+
graphql_path: nil,
|
25
|
+
graphql_type: nil,
|
26
|
+
graphql_filter: nil,
|
27
|
+
authorize: false,
|
28
|
+
visibility_permission: nil,
|
29
|
+
policy: nil,
|
30
|
+
camelize: ::Groovestack::Base.config.graphql.camelize,
|
31
|
+
**args)
|
32
|
+
graphql_namespace = graphql_path&.dup&.concat('::')
|
33
|
+
entity_model_name = entity.to_s.classify
|
34
|
+
entity_class = class_name || entity_model_name
|
35
|
+
entity_type = resolve_entity_type(graphql_type, graphql_namespace, entity_model_name)
|
36
|
+
entity_filter_type = resolve_filter_type(graphql_filter, graphql_namespace, entity_model_name)
|
37
|
+
except = args.delete(:except) || []
|
38
|
+
policy ||= "#{entity_class}Policy"
|
39
|
+
base_scope = resolve_base_scope(entity_class)
|
40
|
+
|
41
|
+
define_resolver_methods(entity, entity_model_name, authorize, policy, base_scope, except)
|
42
|
+
define_graphql_fields(entity, entity_model_name, entity_type, entity_filter_type,
|
43
|
+
visibility_permission, camelize, except)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def resolve_entity_type(graphql_type, graphql_namespace, entity_model_name)
|
49
|
+
type_path = graphql_type || "#{graphql_namespace}#{entity_model_name}::Type"
|
50
|
+
type_path.constantize
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolve_filter_type(graphql_filter, graphql_namespace, entity_model_name)
|
54
|
+
filter_path = graphql_filter || "#{graphql_namespace}#{entity_model_name}::Filter"
|
55
|
+
filter_path.constantize
|
56
|
+
end
|
57
|
+
|
58
|
+
def resolve_base_scope(entity_class)
|
59
|
+
entity_class.constantize.unscoped
|
60
|
+
rescue StandardError
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def define_resolver_methods(entity, entity_model_name, authorize, policy, base_scope, except)
|
65
|
+
unless except.include?(:find)
|
66
|
+
define_find_resolver(entity, entity_model_name, authorize, policy,
|
67
|
+
base_scope)
|
68
|
+
end
|
69
|
+
define_collection_resolver(entity, authorize, policy, base_scope) unless except.include?(:collection)
|
70
|
+
define_meta_resolver(entity, authorize, policy, base_scope) unless except.include?(:collection_meta)
|
71
|
+
end
|
72
|
+
|
73
|
+
def define_find_resolver(_entity, entity_model_name, authorize, policy, base_scope)
|
74
|
+
define_method entity_model_name.to_sym do |id:|
|
75
|
+
scope = resolve_scope(authorize, policy, :ShowScope, base_scope)
|
76
|
+
scope.find id
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def define_collection_resolver(entity, authorize, policy, base_scope)
|
81
|
+
define_method entity do |page: nil, per_page: nil, **attrs|
|
82
|
+
scope = resolve_scope(authorize, policy, :IndexScope, base_scope)
|
83
|
+
scope = send("#{entity}_scope", **attrs, base_scope: scope)
|
84
|
+
apply_pagination(scope, page, per_page)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def define_meta_resolver(entity, authorize, policy, base_scope)
|
89
|
+
define_method :"#{entity}_meta" do |_page: nil, _per_page: nil, **attrs|
|
90
|
+
scope = resolve_scope(authorize, policy, :IndexScope, base_scope)
|
91
|
+
{ count: send("#{entity}_scope", **attrs, base_scope: scope).size }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def define_graphql_fields(entity, entity_model_name, entity_type, entity_filter_type,
|
96
|
+
visibility_permission, camelize, except)
|
97
|
+
unless except.include?(:find)
|
98
|
+
define_find_field(entity, entity_model_name, entity_type,
|
99
|
+
visibility_permission)
|
100
|
+
end
|
101
|
+
unless except.include?(:collection)
|
102
|
+
define_collection_field(entity, entity_type, entity_filter_type, visibility_permission,
|
103
|
+
camelize)
|
104
|
+
end
|
105
|
+
return if except.include?(:collection_meta)
|
106
|
+
|
107
|
+
define_meta_field(entity, entity_filter_type, visibility_permission,
|
108
|
+
camelize)
|
109
|
+
end
|
110
|
+
|
111
|
+
def define_find_field(entity, entity_model_name, entity_type, visibility_permission)
|
112
|
+
field entity_model_name.to_sym, entity_type,
|
113
|
+
null: true,
|
114
|
+
visibility_permission: visibility_permission,
|
115
|
+
resolver_method: entity_model_name.to_sym,
|
116
|
+
description: "Find #{entity}." do
|
117
|
+
argument :id, ::GraphQL::Types::ID, required: true, description: Documentation::Arguments.id
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def define_collection_field(entity, entity_type, entity_filter_type, visibility_permission, camelize)
|
122
|
+
field :"all_#{entity.to_s.underscore}",
|
123
|
+
type: [entity_type],
|
124
|
+
null: false,
|
125
|
+
camelize: camelize,
|
126
|
+
visibility_permission: visibility_permission,
|
127
|
+
resolver_method: entity do
|
128
|
+
argument :page, ::GraphQL::Types::Int, required: false, description: Documentation::Arguments.page
|
129
|
+
argument :per_page, ::GraphQL::Types::Int, required: false,
|
130
|
+
description: Documentation::Arguments.per_page
|
131
|
+
argument :sort_field, ::GraphQL::Types::String, required: false,
|
132
|
+
description: Documentation::Arguments.sort_field
|
133
|
+
argument :sort_order, ::GraphQL::Types::String, required: false,
|
134
|
+
description: Documentation::Arguments.sort_order
|
135
|
+
argument :filter, entity_filter_type, required: false, description: Documentation::Arguments.filter
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def define_meta_field(entity, entity_filter_type, visibility_permission, camelize)
|
140
|
+
field :"_all_#{entity.to_s.underscore}_meta",
|
141
|
+
type: ::Groovestack::Base::GraphQL::Providers::ReactAdmin::Types::RAListMetadata,
|
142
|
+
camelize: camelize,
|
143
|
+
null: true,
|
144
|
+
visibility_permission: visibility_permission,
|
145
|
+
resolver_method: :"#{entity}_meta" do
|
146
|
+
argument :page, ::GraphQL::Types::Int, required: false, description: Documentation::Arguments.page
|
147
|
+
argument :per_page, ::GraphQL::Types::Int, required: false,
|
148
|
+
description: Documentation::Arguments.per_page
|
149
|
+
argument :sort_field, ::GraphQL::Types::String, required: false,
|
150
|
+
description: Documentation::Arguments.sort_field
|
151
|
+
argument :sort_order, ::GraphQL::Types::String, required: false,
|
152
|
+
description: Documentation::Arguments.sort_order
|
153
|
+
argument :filter, entity_filter_type, required: false, description: Documentation::Arguments.filter
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def resolve_scope(authorize, policy, scope_class, base_scope)
|
161
|
+
if authorize
|
162
|
+
policy.constantize.const_get(scope_class).new(context[:current_user], base_scope).resolve
|
163
|
+
else
|
164
|
+
base_scope
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def apply_pagination(scope, page, per_page)
|
169
|
+
return scope unless page.present? && scope.respond_to?(:offset)
|
170
|
+
|
171
|
+
scope.offset(page * per_page).limit(per_page)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# rubocop:enable Metrics/BlockLength, Metrics/ModuleLength, Metrics/ParameterLists
|