groovestack-base 0.1.6 → 0.1.9
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 +2 -2
- 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 +28 -16
- 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
@@ -1,146 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# TODO: refactor according to rubocop suggestions
|
4
|
-
|
5
|
-
module Groovestack
|
6
|
-
module Base
|
7
|
-
module GraphQL
|
8
|
-
module Providers
|
9
|
-
module ReactAdmin
|
10
|
-
module Resource # rubocop:disable Metrics/ModuleLength
|
11
|
-
extend ActiveSupport::Concern
|
12
|
-
|
13
|
-
class_methods do # rubocop:disable Metrics/BlockLength
|
14
|
-
# TODO: make authorize default to true
|
15
|
-
|
16
|
-
# rubocop:disable Metrics/ParameterLists, Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
17
|
-
def react_admin_resource(entity,
|
18
|
-
class_name: nil,
|
19
|
-
graphql_path: nil,
|
20
|
-
graphql_type: nil,
|
21
|
-
graphql_filter: nil,
|
22
|
-
authorize: false,
|
23
|
-
visibility_permission: nil,
|
24
|
-
policy: nil,
|
25
|
-
camelize: ::Groovestack::Base.config.graphql.camelize,
|
26
|
-
**args)
|
27
|
-
# NOTE: class_name is only required if a custom _base_scope is not defined
|
28
|
-
# NOTE graphql_path is only required to override the default graphql path
|
29
|
-
|
30
|
-
graphql_namespace = graphql_path&.dup&.concat('::')
|
31
|
-
entity_model_name = entity.to_s.classify
|
32
|
-
entity_class = class_name || entity_model_name
|
33
|
-
entity_type = (graphql_type || "#{graphql_namespace}#{entity_model_name}::Type").constantize
|
34
|
-
entity_filter_type = (graphql_filter || "#{graphql_namespace}#{entity_model_name}::Filter").constantize
|
35
|
-
except = args.delete(:except) || []
|
36
|
-
policy ||= "#{entity_class}Policy"
|
37
|
-
base_scope = begin
|
38
|
-
entity_class.constantize.unscoped
|
39
|
-
rescue StandardError
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
|
43
|
-
# resolver_method for Record
|
44
|
-
|
45
|
-
unless except.include?(:find)
|
46
|
-
define_method entity_model_name.to_sym do |id:|
|
47
|
-
scope = if authorize
|
48
|
-
policy.constantize::ShowScope.new(context[:current_user],
|
49
|
-
base_scope).resolve
|
50
|
-
else
|
51
|
-
base_scope
|
52
|
-
end
|
53
|
-
scope.find id
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# resolver_method for Collection
|
58
|
-
|
59
|
-
unless except.include?(:collection)
|
60
|
-
define_method entity do |page: nil, per_page: nil, **attrs|
|
61
|
-
scope = if authorize
|
62
|
-
policy.constantize::IndexScope.new(context[:current_user],
|
63
|
-
base_scope).resolve
|
64
|
-
else
|
65
|
-
base_scope
|
66
|
-
end
|
67
|
-
scope = send("#{entity}_scope", **attrs, base_scope: scope)
|
68
|
-
scope = scope.offset(page * per_page).limit(per_page) if page.present? && scope.respond_to?(:offset)
|
69
|
-
scope
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# resolver_method for Collection meta
|
74
|
-
|
75
|
-
unless except.include?(:collection_meta)
|
76
|
-
define_method :"#{entity}_meta" do |page: nil, per_page: nil, **attrs| # rubocop:disable Lint/UnusedBlockArgument
|
77
|
-
scope = if authorize
|
78
|
-
policy.constantize::IndexScope.new(context[:current_user],
|
79
|
-
base_scope).resolve
|
80
|
-
else
|
81
|
-
base_scope
|
82
|
-
end
|
83
|
-
{ count: send("#{entity}_scope", **attrs, base_scope: scope).size }
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Record
|
88
|
-
|
89
|
-
unless except.include?(:find)
|
90
|
-
field entity_model_name.to_sym, entity_type,
|
91
|
-
null: true,
|
92
|
-
visibility_permission: visibility_permission,
|
93
|
-
resolver_method: entity_model_name.to_sym,
|
94
|
-
description: "Find #{entity_class}." do
|
95
|
-
argument :id, ::GraphQL::Types::ID, required: true, description: Documentation::Arguments.id
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Collection
|
100
|
-
|
101
|
-
unless except.include?(:collection)
|
102
|
-
field :"all_#{entity.to_s.underscore}",
|
103
|
-
type: [entity_type],
|
104
|
-
null: false,
|
105
|
-
camelize: camelize,
|
106
|
-
visibility_permission: visibility_permission,
|
107
|
-
resolver_method: entity do
|
108
|
-
argument :page, ::GraphQL::Types::Int, required: false, description: Documentation::Arguments.page
|
109
|
-
argument :per_page, ::GraphQL::Types::Int, required: false,
|
110
|
-
description: Documentation::Arguments.per_page
|
111
|
-
argument :sort_field, ::GraphQL::Types::String, required: false,
|
112
|
-
description: Documentation::Arguments.sort_field
|
113
|
-
argument :sort_order, ::GraphQL::Types::String, required: false,
|
114
|
-
description: Documentation::Arguments.sort_order
|
115
|
-
argument :filter, entity_filter_type, required: false, description: Documentation::Arguments.filter
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
# Collection meta
|
120
|
-
|
121
|
-
return if except.include?(:collection_meta)
|
122
|
-
|
123
|
-
field :"_all_#{entity.to_s.underscore}_meta",
|
124
|
-
type: ::Groovestack::Base::GraphQL::Providers::ReactAdmin::Types::RAListMetadata,
|
125
|
-
camelize: camelize,
|
126
|
-
null: true,
|
127
|
-
visibility_permission: visibility_permission,
|
128
|
-
resolver_method: :"#{entity}_meta" do
|
129
|
-
argument :page, ::GraphQL::Types::Int, required: false, description: Documentation::Arguments.page
|
130
|
-
argument :per_page, ::GraphQL::Types::Int, required: false,
|
131
|
-
description: Documentation::Arguments.per_page
|
132
|
-
argument :sort_field, ::GraphQL::Types::String, required: false,
|
133
|
-
description: Documentation::Arguments.sort_field
|
134
|
-
argument :sort_order, ::GraphQL::Types::String, required: false,
|
135
|
-
description: Documentation::Arguments.sort_order
|
136
|
-
argument :filter, entity_filter_type, required: false, description: Documentation::Arguments.filter
|
137
|
-
end
|
138
|
-
end
|
139
|
-
# rubocop:enable Metrics/ParameterLists, Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Groovestack
|
4
|
-
module Base
|
5
|
-
module GraphQL
|
6
|
-
module Providers
|
7
|
-
module ReactAdmin
|
8
|
-
module Types
|
9
|
-
class RAListMetadata < ::GraphQL::Schema::Object
|
10
|
-
field :count, Int, null: false, description: Documentation::Fields.relation_count
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Groovestack
|
4
|
-
module Base
|
5
|
-
module GraphQL
|
6
|
-
module Types
|
7
|
-
class BaseArgument < ::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
|
-
|
15
|
-
class BaseField < ::GraphQL::Schema::Field
|
16
|
-
argument_class ::Groovestack::Base::GraphQL::Types::BaseArgument
|
17
|
-
|
18
|
-
attr_accessor :authenticate, :visibility_permission
|
19
|
-
|
20
|
-
# rubocop:disable Metrics/ParameterLists
|
21
|
-
def initialize(
|
22
|
-
*args,
|
23
|
-
authenticate: nil,
|
24
|
-
visibility_permission: nil,
|
25
|
-
null: false,
|
26
|
-
camelize: ::Groovestack::Base.config.graphql.camelize,
|
27
|
-
**kwargs, &block
|
28
|
-
)
|
29
|
-
# Then, call super _without_ any args, where Ruby will take
|
30
|
-
# _all_ the args originally passed to this method and pass it to the super method.
|
31
|
-
@authenticate = authenticate
|
32
|
-
@visibility_permission = visibility_permission
|
33
|
-
super(*args, null: null, camelize: camelize, **kwargs, &block)
|
34
|
-
end
|
35
|
-
# rubocop:enable Metrics/ParameterLists
|
36
|
-
end
|
37
|
-
|
38
|
-
class BaseObject < ::GraphQL::Schema::Object
|
39
|
-
field_class ::Groovestack::Base::GraphQL::Types::BaseField
|
40
|
-
end
|
41
|
-
|
42
|
-
class SubscriptionPayload < ::Groovestack::Base::GraphQL::Types::BaseObject
|
43
|
-
field :event, ::GraphQL::Types::JSON, null: false
|
44
|
-
field :subscription, String, null: false
|
45
|
-
field :subscription_args, ::GraphQL::Types::JSON, null: false
|
46
|
-
end
|
47
|
-
|
48
|
-
class Currency < ::Groovestack::Base::GraphQL::Types::BaseObject
|
49
|
-
description 'A currency object'
|
50
|
-
|
51
|
-
field :code, String, null: false, description: 'currency code', method: :iso_code
|
52
|
-
field :symbol, String, null: false, description: 'currency symbol'
|
53
|
-
end
|
54
|
-
|
55
|
-
class Money < ::Groovestack::Base::GraphQL::Types::BaseObject
|
56
|
-
description 'A money object'
|
57
|
-
|
58
|
-
field :amount, String, null: false, description: 'amount in decimal'
|
59
|
-
field :currency, ::Groovestack::Base::GraphQL::Types::Currency, null: false, description: 'currency metadata'
|
60
|
-
field :formatted_amount, String, null: false,
|
61
|
-
description: 'amount in decimal formatted with currency symbol',
|
62
|
-
method: :format
|
63
|
-
|
64
|
-
def amount
|
65
|
-
object.amount.to_s
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# AUTHORIZATION
|
70
|
-
|
71
|
-
class AuthorizedBaseField < BaseField
|
72
|
-
def authorized?(obj, args, ctx)
|
73
|
-
authorized_fields = begin
|
74
|
-
obj.authorized_fields_for_serialization(ctx[:current_user])
|
75
|
-
rescue StandardError
|
76
|
-
[]
|
77
|
-
end
|
78
|
-
|
79
|
-
super && authorized_fields.include?(name.to_sym)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
class AuthorizedBaseObject < BaseObject
|
84
|
-
field_class ::Groovestack::Base::GraphQL::Types::AuthorizedBaseField
|
85
|
-
end
|
86
|
-
|
87
|
-
class VisibleBaseField < BaseField
|
88
|
-
def visible?(context)
|
89
|
-
return super unless @visibility_permission
|
90
|
-
|
91
|
-
# visibility profile are the visibility levels the
|
92
|
-
# current user is authorized for
|
93
|
-
visibility_profile = context.schema.visibility_profile_for_context(context).map(&:to_sym)
|
94
|
-
|
95
|
-
return super unless visibility_profile
|
96
|
-
|
97
|
-
super && visibility_profile.include?(@visibility_permission.to_sym)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|