ibrain-core 0.4.6 → 0.4.7

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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/ibrain/base_controller.rb +14 -12
  3. data/app/controllers/ibrain/core/graphql_controller.rb +83 -79
  4. data/app/graphql/ibrain/base_schema.rb +52 -50
  5. data/app/graphql/ibrain/extentions/default_value.rb +11 -7
  6. data/app/graphql/ibrain/extentions/roles.rb +20 -15
  7. data/app/graphql/ibrain/extentions/session_required.rb +14 -10
  8. data/app/graphql/ibrain/lazy/base.rb +6 -2
  9. data/app/graphql/ibrain/loaders/association_loader.rb +55 -51
  10. data/app/graphql/ibrain/mutations/base_mutation.rb +56 -52
  11. data/app/graphql/ibrain/policies/base_policy.rb +47 -43
  12. data/app/graphql/ibrain/policies/graphql_policy.rb +6 -2
  13. data/app/graphql/ibrain/resolvers/base_aggregate.rb +10 -6
  14. data/app/graphql/ibrain/resolvers/base_resolver.rb +12 -8
  15. data/app/graphql/ibrain/types/aggregate_type.rb +8 -4
  16. data/app/graphql/ibrain/types/attribute_type.rb +5 -2
  17. data/app/graphql/ibrain/types/base_api_connection.rb +10 -6
  18. data/app/graphql/ibrain/types/base_api_edge.rb +8 -4
  19. data/app/graphql/ibrain/types/base_api_field.rb +11 -7
  20. data/app/graphql/ibrain/types/base_api_object.rb +10 -6
  21. data/app/graphql/ibrain/types/base_argument.rb +7 -3
  22. data/app/graphql/ibrain/types/base_connection.rb +11 -7
  23. data/app/graphql/ibrain/types/base_edge.rb +7 -3
  24. data/app/graphql/ibrain/types/base_enum.rb +5 -1
  25. data/app/graphql/ibrain/types/base_field.rb +10 -6
  26. data/app/graphql/ibrain/types/base_input_object.rb +10 -6
  27. data/app/graphql/ibrain/types/base_interface.rb +9 -5
  28. data/app/graphql/ibrain/types/base_object.rb +16 -12
  29. data/app/graphql/ibrain/types/base_scalar.rb +5 -1
  30. data/app/graphql/ibrain/types/base_type.rb +10 -4
  31. data/app/graphql/ibrain/types/base_union.rb +7 -3
  32. data/app/graphql/ibrain/types/filter_type.rb +5 -1
  33. data/app/graphql/ibrain/types/node_type.rb +8 -4
  34. data/app/graphql/ibrain/util/field_combiner.rb +9 -5
  35. data/app/graphql/ibrain/util/query_combiner.rb +8 -4
  36. data/app/models/concerns/ibrain/soft_deletable.rb +8 -6
  37. data/app/models/concerns/ibrain/user_api_authentication.rb +16 -14
  38. data/app/models/concerns/ibrain/user_methods.rb +13 -11
  39. data/app/models/ibrain/ability.rb +32 -31
  40. data/app/models/ibrain/aggregate.rb +7 -5
  41. data/app/models/ibrain/application_record.rb +4 -2
  42. data/app/models/ibrain/legacy_user.rb +13 -7
  43. data/app/models/ibrain/role.rb +8 -6
  44. data/app/models/ibrain/role_user.rb +10 -8
  45. data/app/repositories/ibrain/base_repository.rb +11 -9
  46. data/lib/generators/ibrain/core/model_generator.rb +21 -17
  47. data/lib/generators/ibrain/graphql/core.rb +59 -55
  48. data/lib/generators/ibrain/graphql/mutation_generator.rb +66 -58
  49. data/lib/generators/ibrain/graphql/object_generator.rb +70 -58
  50. data/lib/generators/ibrain/graphql/resolver_generator.rb +25 -17
  51. data/lib/generators/ibrain/graphql/resolvers_generator.rb +67 -59
  52. data/lib/generators/ibrain/graphql/templates/aggregate.erb +7 -5
  53. data/lib/generators/ibrain/graphql/templates/input.erb +9 -5
  54. data/lib/generators/ibrain/graphql/templates/mutation.erb +26 -24
  55. data/lib/generators/ibrain/graphql/templates/object.erb +10 -6
  56. data/lib/generators/ibrain/graphql/templates/resolver.erb +11 -9
  57. data/lib/generators/ibrain/graphql/templates/resolvers.erb +10 -8
  58. data/lib/generators/ibrain/graphql/type_generator.rb +88 -84
  59. data/lib/generators/ibrain/install/install_generator.rb +140 -137
  60. data/lib/generators/ibrain/install/templates/graphql/types/mutation_type.rb.tt +15 -13
  61. data/lib/generators/ibrain/install/templates/graphql/types/query_type.rb.tt +13 -11
  62. data/lib/generators/ibrain/install/templates/rubocop.yml.tt +30 -83
  63. data/lib/ibrain/app_configuration.rb +36 -34
  64. data/lib/ibrain/core/class_constantizer.rb +33 -30
  65. data/lib/ibrain/core/controller_helpers/auth.rb +59 -53
  66. data/lib/ibrain/core/controller_helpers/current_host.rb +11 -5
  67. data/lib/ibrain/core/controller_helpers/response.rb +49 -43
  68. data/lib/ibrain/core/controller_helpers/strong_parameters.rb +15 -9
  69. data/lib/ibrain/core/engine.rb +9 -5
  70. data/lib/ibrain/core/environment.rb +9 -5
  71. data/lib/ibrain/core/environment_extension.rb +17 -13
  72. data/lib/ibrain/core/role_configuration.rb +54 -52
  73. data/lib/ibrain/core/validators/email.rb +17 -15
  74. data/lib/ibrain/core/version.rb +2 -2
  75. data/lib/ibrain/core/versioned_value.rb +65 -61
  76. data/lib/ibrain/encryptor.rb +20 -18
  77. data/lib/ibrain/logger.rb +15 -13
  78. data/lib/ibrain/permission_sets/base.rb +26 -22
  79. data/lib/ibrain/permission_sets/super_user.rb +7 -3
  80. data/lib/ibrain/permitted_attributes.rb +20 -18
  81. data/lib/ibrain/preferences/configuration.rb +137 -135
  82. data/lib/ibrain/preferences/preferable.rb +162 -158
  83. data/lib/ibrain/preferences/preferable_class_methods.rb +114 -112
  84. data/lib/ibrain/user_class_handle.rb +24 -22
  85. data/lib/ibrain_core.rb +1 -7
  86. metadata +1 -1
@@ -3,136 +3,138 @@
3
3
  require 'logger'
4
4
  require 'ibrain/encryptor'
5
5
 
6
- module Ibrain::Preferences::PreferableClassMethods
7
- DEFAULT_ADMIN_FORM_PREFERENCE_TYPES = %i(
8
- boolean
9
- decimal
10
- integer
11
- password
12
- string
13
- text
14
- encrypted_string
15
- )
16
-
17
- def defined_preferences
18
- []
19
- end
6
+ module Ibrain::Preferences
7
+ module PreferableClassMethods
8
+ DEFAULT_ADMIN_FORM_PREFERENCE_TYPES = %i(
9
+ boolean
10
+ decimal
11
+ integer
12
+ password
13
+ string
14
+ text
15
+ encrypted_string
16
+ )
17
+
18
+ def defined_preferences
19
+ []
20
+ end
20
21
 
21
- def preference(name, type, options = {})
22
- options.assert_valid_keys(:default, :encryption_key)
22
+ def preference(name, type, options = {})
23
+ options.assert_valid_keys(:default, :encryption_key)
23
24
 
24
- if type == :encrypted_string
25
- preference_encryptor = preference_encryptor(options)
26
- options[:default] = preference_encryptor.encrypt(options[:default])
27
- end
25
+ if type == :encrypted_string
26
+ preference_encryptor = preference_encryptor(options)
27
+ options[:default] = preference_encryptor.encrypt(options[:default])
28
+ end
28
29
 
29
- default = begin
30
- given = options[:default]
31
- if self <= Ibrain::Preferences::Configuration &&
32
- given.is_a?(Proc) &&
33
- given.lambda? &&
34
- given.arity.zero?
35
- Ibrain::Logger.warn <<~MSG
36
- The arity of a proc given as the default for a preference
37
- has changed from 0 to 1 on Ibrain 3.1. The Ibrain
38
- version for the loaded preference defaults is given as the
39
- proc's argument from this point on.
40
-
41
- If you don't need to return a different default value
42
- depending on the loaded Ibrain version, you can change
43
- the proc so that it doesn't have lambda semantics (lambdas
44
- raise when extra arguments are supplied, while raw procs
45
- don't). E.g.:
46
-
47
- preference :foo, :string, default: proc { true }
48
-
49
- If you want to branch on the provided Ibrain version, you can do like the following:
50
-
51
- preference :foo, :string, default: by_version(true, "3.2.0" => false)
52
-
53
- MSG
54
- ->(_default_context) { given.call }
55
- elsif given.is_a?(Proc)
56
- given
57
- else
58
- proc { given }
59
- end
60
- end
30
+ default = begin
31
+ given = options[:default]
32
+ if self <= Ibrain::Preferences::Configuration &&
33
+ given.is_a?(Proc) &&
34
+ given.lambda? &&
35
+ given.arity.zero?
36
+ Ibrain::Logger.warn <<~MSG
37
+ The arity of a proc given as the default for a preference
38
+ has changed from 0 to 1 on Ibrain 3.1. The Ibrain
39
+ version for the loaded preference defaults is given as the
40
+ proc's argument from this point on.
41
+
42
+ If you don't need to return a different default value
43
+ depending on the loaded Ibrain version, you can change
44
+ the proc so that it doesn't have lambda semantics (lambdas
45
+ raise when extra arguments are supplied, while raw procs
46
+ don't). E.g.:
47
+
48
+ preference :foo, :string, default: proc { true }
49
+
50
+ If you want to branch on the provided Ibrain version, you can do like the following:
51
+
52
+ preference :foo, :string, default: by_version(true, "3.2.0" => false)
53
+
54
+ MSG
55
+ ->(_default_context) { given.call }
56
+ elsif given.is_a?(Proc)
57
+ given
58
+ else
59
+ proc { given }
60
+ end
61
+ end
61
62
 
62
- # The defined preferences on a class are all those defined directly on
63
- # that class as well as those defined on ancestors.
64
- # We store these as a class instance variable on each class which has a
65
- # preference. super() collects preferences defined on ancestors.
66
- singleton_preferences = (@defined_singleton_preferences ||= [])
67
- singleton_preferences << name.to_sym
63
+ # The defined preferences on a class are all those defined directly on
64
+ # that class as well as those defined on ancestors.
65
+ # We store these as a class instance variable on each class which has a
66
+ # preference. super() collects preferences defined on ancestors.
67
+ singleton_preferences = (@defined_singleton_preferences ||= [])
68
+ singleton_preferences << name.to_sym
68
69
 
69
- define_singleton_method :defined_preferences do
70
- super() + singleton_preferences
71
- end
70
+ define_singleton_method :defined_preferences do
71
+ super() + singleton_preferences
72
+ end
72
73
 
73
- # cache_key will be nil for new objects, then if we check if there
74
- # is a pending preference before going to default
75
- define_method preference_getter_method(name) do
76
- value = preferences.fetch(name) do
77
- default.call(*context_for_default)
74
+ # cache_key will be nil for new objects, then if we check if there
75
+ # is a pending preference before going to default
76
+ define_method preference_getter_method(name) do
77
+ value = preferences.fetch(name) do
78
+ default.call(*context_for_default)
79
+ end
80
+ value = preference_encryptor.decrypt(value) if preference_encryptor.present?
81
+ value
78
82
  end
79
- value = preference_encryptor.decrypt(value) if preference_encryptor.present?
80
- value
81
- end
82
83
 
83
- define_method preference_setter_method(name) do |value|
84
- value = convert_preference_value(value, type, preference_encryptor)
85
- preferences[name] = value
84
+ define_method preference_setter_method(name) do |value|
85
+ value = convert_preference_value(value, type, preference_encryptor)
86
+ preferences[name] = value
86
87
 
87
- # If this is an activerecord object, we need to inform
88
- # ActiveRecord::Dirty that this value has changed, since this is an
89
- # in-place update to the preferences hash.
90
- preferences_will_change! if respond_to?(:preferences_will_change!)
91
- end
88
+ # If this is an activerecord object, we need to inform
89
+ # ActiveRecord::Dirty that this value has changed, since this is an
90
+ # in-place update to the preferences hash.
91
+ preferences_will_change! if respond_to?(:preferences_will_change!)
92
+ end
92
93
 
93
- define_method preference_default_getter_method(name) do
94
- default.call(*context_for_default)
95
- end
94
+ define_method preference_default_getter_method(name) do
95
+ default.call(*context_for_default)
96
+ end
96
97
 
97
- define_method preference_type_getter_method(name) do
98
- type
98
+ define_method preference_type_getter_method(name) do
99
+ type
100
+ end
99
101
  end
100
- end
101
102
 
102
- def preference_getter_method(name)
103
- "preferred_#{name}".to_sym
104
- end
103
+ def preference_getter_method(name)
104
+ "preferred_#{name}".to_sym
105
+ end
105
106
 
106
- def preference_setter_method(name)
107
- "preferred_#{name}=".to_sym
108
- end
107
+ def preference_setter_method(name)
108
+ "preferred_#{name}=".to_sym
109
+ end
109
110
 
110
- def preference_default_getter_method(name)
111
- "preferred_#{name}_default".to_sym
112
- end
111
+ def preference_default_getter_method(name)
112
+ "preferred_#{name}_default".to_sym
113
+ end
113
114
 
114
- def preference_type_getter_method(name)
115
- "preferred_#{name}_type".to_sym
116
- end
115
+ def preference_type_getter_method(name)
116
+ "preferred_#{name}_type".to_sym
117
+ end
117
118
 
118
- def preference_encryptor(options)
119
- key = options[:encryption_key] ||
120
- ENV['IBRAIN_PREFERENCES_MASTER_KEY'] ||
121
- Rails.application.credentials.secret_key_base
119
+ def preference_encryptor(options)
120
+ key = options[:encryption_key] ||
121
+ ENV['IBRAIN_PREFERENCES_MASTER_KEY'] ||
122
+ Rails.application.credentials.secret_key_base
122
123
 
123
- Ibrain::Encryptor.new(key)
124
- end
124
+ Ibrain::Encryptor.new(key)
125
+ end
125
126
 
126
- # List of preference types allowed as form fields in the Ibrain admin
127
- #
128
- # Overwrite this method in your class that includes +Ibrain::Preferable+
129
- # if you want to provide more fields. If you do so, you also need to provide
130
- # a preference field partial that lives in:
131
- #
132
- # +app/views/Ibrain/admin/shared/preference_fields/+
133
- #
134
- # @return [Array]
135
- def allowed_admin_form_preference_types
136
- DEFAULT_ADMIN_FORM_PREFERENCE_TYPES
127
+ # List of preference types allowed as form fields in the Ibrain admin
128
+ #
129
+ # Overwrite this method in your class that includes +Ibrain::Preferable+
130
+ # if you want to provide more fields. If you do so, you also need to provide
131
+ # a preference field partial that lives in:
132
+ #
133
+ # +app/views/Ibrain/admin/shared/preference_fields/+
134
+ #
135
+ # @return [Array]
136
+ def allowed_admin_form_preference_types
137
+ DEFAULT_ADMIN_FORM_PREFERENCE_TYPES
138
+ end
137
139
  end
138
140
  end
@@ -1,27 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Configuration point for User model implementation.
4
- #
5
- # `Ibrain::UserClassHandle` allows you to configure your own implementation of a
6
- # User class or use an extension like `ibrain-auth`.
7
- #
8
- # @note Placeholder for name of Ibrain.user_class to ensure later evaluation at
9
- # runtime.
10
- #
11
- # Unfortunately, it is possible for classes to get loaded before
12
- # Ibrain.user_class has been set in the initializer. As a result, they end up
13
- # with class_name: "" in their association definitions. For obvious reasons,
14
- # that doesn't work.
15
- #
16
- # For now, Rails does not call to_s on the instance passed in until runtime.
17
- # So this little hack provides a wrapper around Ibrain.user_class so that we
18
- # can basically lazy-evaluate it. Yay! Problem solved forever.
19
- class Ibrain::UserClassHandle
20
- # @return [String] the name of the user class as a string.
21
- # @raise [RuntimeError] if Ibrain.user_class is nil
22
- def to_s
23
- fail "'Ibrain.user_class' has not been set yet." unless Ibrain.user_class
3
+ module Ibrain
4
+ # Configuration point for User model implementation.
5
+ #
6
+ # `Ibrain::UserClassHandle` allows you to configure your own implementation of a
7
+ # User class or use an extension like `ibrain-auth`.
8
+ #
9
+ # @note Placeholder for name of Ibrain.user_class to ensure later evaluation at
10
+ # runtime.
11
+ #
12
+ # Unfortunately, it is possible for classes to get loaded before
13
+ # Ibrain.user_class has been set in the initializer. As a result, they end up
14
+ # with class_name: "" in their association definitions. For obvious reasons,
15
+ # that doesn't work.
16
+ #
17
+ # For now, Rails does not call to_s on the instance passed in until runtime.
18
+ # So this little hack provides a wrapper around Ibrain.user_class so that we
19
+ # can basically lazy-evaluate it. Yay! Problem solved forever.
20
+ class UserClassHandle
21
+ # @return [String] the name of the user class as a string.
22
+ # @raise [RuntimeError] if Ibrain.user_class is nil
23
+ def to_s
24
+ fail "'Ibrain.user_class' has not been set yet." unless Ibrain.user_class
24
25
 
25
- "::#{Ibrain.user_class}"
26
+ "::#{Ibrain.user_class}"
27
+ end
26
28
  end
27
29
  end
data/lib/ibrain_core.rb CHANGED
@@ -1,9 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "zeitwerk"
4
- loader = Zeitwerk::Loader.new
5
- loader.tag = File.basename(__FILE__, ".rb")
6
- loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
7
- loader.enable_reloading
8
- loader.setup
9
- loader.reload
3
+ require 'ibrain/core'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibrain-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tai Nguyen Van