ibrain-core 0.1.0

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 (103) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +75 -0
  4. data/Rakefile +7 -0
  5. data/app/controllers/concerns/ibrain_errors.rb +23 -0
  6. data/app/controllers/concerns/ibrain_handler.rb +42 -0
  7. data/app/controllers/ibrain/base_controller.rb +28 -0
  8. data/app/controllers/ibrain/graphql_controller.rb +55 -0
  9. data/app/graphql/ibrain/base_schema.rb +52 -0
  10. data/app/graphql/ibrain/extentions/default_value.rb +15 -0
  11. data/app/graphql/ibrain/interfaces/base_interface.rb +5 -0
  12. data/app/graphql/ibrain/interfaces/person_interface.rb +15 -0
  13. data/app/graphql/ibrain/interfaces/record_interface.rb +10 -0
  14. data/app/graphql/ibrain/lazy/base.rb +8 -0
  15. data/app/graphql/ibrain/loaders/association_loader.rb +61 -0
  16. data/app/graphql/ibrain/mutations/base_mutation.rb +35 -0
  17. data/app/graphql/ibrain/policies/base_policy.rb +45 -0
  18. data/app/graphql/ibrain/policies/graphql_policy.rb +8 -0
  19. data/app/graphql/ibrain/resolvers/base_aggregate.rb +9 -0
  20. data/app/graphql/ibrain/resolvers/base_resolver.rb +15 -0
  21. data/app/graphql/ibrain/types/aggregate_type.rb +9 -0
  22. data/app/graphql/ibrain/types/base_argument.rb +11 -0
  23. data/app/graphql/ibrain/types/base_connection.rb +16 -0
  24. data/app/graphql/ibrain/types/base_edge.rb +10 -0
  25. data/app/graphql/ibrain/types/base_enum.rb +8 -0
  26. data/app/graphql/ibrain/types/base_field.rb +15 -0
  27. data/app/graphql/ibrain/types/base_input_object.rb +9 -0
  28. data/app/graphql/ibrain/types/base_interface.rb +14 -0
  29. data/app/graphql/ibrain/types/base_node.rb +13 -0
  30. data/app/graphql/ibrain/types/base_object.rb +14 -0
  31. data/app/graphql/ibrain/types/base_query_type.rb +14 -0
  32. data/app/graphql/ibrain/types/base_scalar.rb +8 -0
  33. data/app/graphql/ibrain/types/base_union.rb +10 -0
  34. data/app/graphql/ibrain/types/filter_type.rb +8 -0
  35. data/app/graphql/ibrain/types/node_type.rb +11 -0
  36. data/app/graphql/ibrain/util/field_combiner.rb +13 -0
  37. data/app/graphql/ibrain/util/query_combiner.rb +13 -0
  38. data/app/graphql/mutations/insert_user.rb +18 -0
  39. data/app/models/ibrain/ability.rb +51 -0
  40. data/app/models/ibrain/application_record.rb +7 -0
  41. data/app/models/ibrain/base.rb +47 -0
  42. data/app/models/ibrain/concerns/ransackable_attributes.rb +22 -0
  43. data/app/models/ibrain/concerns/soft_deletable.rb +16 -0
  44. data/app/models/ibrain/concerns/user_api_authentication.rb +23 -0
  45. data/app/models/ibrain/concerns/user_methods.rb +25 -0
  46. data/app/models/ibrain/legacy_user.rb +19 -0
  47. data/app/models/ibrain/role.rb +14 -0
  48. data/app/models/ibrain/role_user.rb +18 -0
  49. data/config/initializers/friendly_id.rb +87 -0
  50. data/config/locales/en.yml +10 -0
  51. data/config/locales/jp.yml +10 -0
  52. data/config/locales/vi.yml +10 -0
  53. data/config/routes.rb +9 -0
  54. data/lib/generators/ibrain/graphql/core.rb +75 -0
  55. data/lib/generators/ibrain/graphql/mutation_generator.rb +58 -0
  56. data/lib/generators/ibrain/graphql/object_generator.rb +80 -0
  57. data/lib/generators/ibrain/graphql/resolver_generator.rb +33 -0
  58. data/lib/generators/ibrain/graphql/resolvers_generator.rb +59 -0
  59. data/lib/generators/ibrain/graphql/templates/aggregate.erb +10 -0
  60. data/lib/generators/ibrain/graphql/templates/mutation.erb +16 -0
  61. data/lib/generators/ibrain/graphql/templates/object.erb +11 -0
  62. data/lib/generators/ibrain/graphql/templates/resolver.erb +15 -0
  63. data/lib/generators/ibrain/graphql/templates/resolvers.erb +13 -0
  64. data/lib/generators/ibrain/graphql/type_generator.rb +101 -0
  65. data/lib/generators/ibrain/install/install_generator.rb +189 -0
  66. data/lib/generators/ibrain/install/templates/config/database.tt +23 -0
  67. data/lib/generators/ibrain/install/templates/config/initializers/cors.tt +25 -0
  68. data/lib/generators/ibrain/install/templates/config/initializers/ibrain.rb.tt +55 -0
  69. data/lib/generators/ibrain/install/templates/config/puma.tt +43 -0
  70. data/lib/generators/ibrain/install/templates/graphql/app_schema.rb.tt +4 -0
  71. data/lib/generators/ibrain/install/templates/graphql/types/mutation_type.rb.tt +10 -0
  72. data/lib/generators/ibrain/install/templates/graphql/types/query_type.rb.tt +13 -0
  73. data/lib/ibrain/app_configuration.rb +66 -0
  74. data/lib/ibrain/config.rb +5 -0
  75. data/lib/ibrain/core/class_constantizer.rb +41 -0
  76. data/lib/ibrain/core/controller_helpers/auth.rb +64 -0
  77. data/lib/ibrain/core/controller_helpers/current_host.rb +17 -0
  78. data/lib/ibrain/core/controller_helpers/response.rb +52 -0
  79. data/lib/ibrain/core/controller_helpers/strong_parameters.rb +21 -0
  80. data/lib/ibrain/core/engine.rb +16 -0
  81. data/lib/ibrain/core/environment.rb +17 -0
  82. data/lib/ibrain/core/environment_extension.rb +27 -0
  83. data/lib/ibrain/core/role_configuration.rb +72 -0
  84. data/lib/ibrain/core/validators/email.rb +23 -0
  85. data/lib/ibrain/core/version.rb +17 -0
  86. data/lib/ibrain/core/versioned_value.rb +73 -0
  87. data/lib/ibrain/core.rb +86 -0
  88. data/lib/ibrain/encryptor.rb +27 -0
  89. data/lib/ibrain/i18n.rb +17 -0
  90. data/lib/ibrain/logger.rb +23 -0
  91. data/lib/ibrain/permission_sets/base.rb +33 -0
  92. data/lib/ibrain/permission_sets/super_user.rb +11 -0
  93. data/lib/ibrain/permission_sets.rb +4 -0
  94. data/lib/ibrain/permitted_attributes.rb +26 -0
  95. data/lib/ibrain/preferences/configuration.rb +170 -0
  96. data/lib/ibrain/preferences/preferable.rb +183 -0
  97. data/lib/ibrain/preferences/preferable_class_methods.rb +140 -0
  98. data/lib/ibrain/user_class_handle.rb +29 -0
  99. data/lib/ibrain_core.rb +3 -0
  100. data/lib/tasks/ibrain/auto_annotate_models.rake +61 -0
  101. data/lib/tasks/ibrain/core_tasks.rake +5 -0
  102. data/lib/tasks/ibrain/ridgepole.rake +37 -0
  103. metadata +293 -0
@@ -0,0 +1,43 @@
1
+ # Puma can serve each request in a thread from an internal thread pool.
2
+ # The `threads` method setting takes two numbers: a minimum and maximum.
3
+ # Any libraries that use thread pools should be configured to match
4
+ # the maximum value specified for Puma. Default is set to 5 threads for minimum
5
+ # and maximum; this matches the default thread size of Active Record.
6
+ #
7
+ max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8
+ min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
9
+ threads min_threads_count, max_threads_count
10
+
11
+ # Specifies the `worker_timeout` threshold that Puma will use to wait before
12
+ # terminating a worker in development environments.
13
+ #
14
+ worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
15
+
16
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
17
+ #
18
+ port ENV.fetch("PORT") { 3000 }
19
+
20
+ # Specifies the `environment` that Puma will run in.
21
+ #
22
+ environment ENV.fetch("RAILS_ENV") { "development" }
23
+
24
+ # Specifies the `pidfile` that Puma will use.
25
+ pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
26
+
27
+ # Specifies the number of `workers` to boot in clustered mode.
28
+ # Workers are forked web server processes. If using threads and workers together
29
+ # the concurrency of the application would be max `threads` * `workers`.
30
+ # Workers do not work on JRuby or Windows (both of which do not support
31
+ # processes).
32
+ #
33
+ # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
34
+
35
+ # Use the `preload_app!` method when specifying a `workers` number.
36
+ # This directive tells Puma to first boot the application and load code
37
+ # before forking the application. This takes advantage of Copy On Write
38
+ # process behavior so workers use less memory.
39
+ #
40
+ # preload_app!
41
+
42
+ # Allow puma to be restarted by `rails restart` command.
43
+ plugin :tmp_restart
@@ -0,0 +1,4 @@
1
+ class AppSchema < Ibrain::BaseSchema
2
+ mutation(Types::MutationType)
3
+ query(Types::QueryType)
4
+ end
@@ -0,0 +1,10 @@
1
+ module Types
2
+ class MutationType < Ibrain::Types::BaseObject
3
+ # TODO: remove me
4
+ field :test_field, String, null: false,
5
+ description: 'An example field added by the generator'
6
+ def test_field
7
+ 'Hello World'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ module Types
2
+ class QueryType < Ibrain::Types::BaseObject
3
+ # Add `node(id: ID!) and `nodes(ids: [ID!]!)`
4
+ include GraphQL::Types::Relay::HasNodeField
5
+ include GraphQL::Types::Relay::HasNodesField
6
+
7
+ # Add root-level fields here.
8
+ # They will be entry points for queries on your schema.
9
+
10
+ # Example with user resolvers
11
+ # field :users, resolver: Resolvers::UsersResolver
12
+ end
13
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the primary location for defining ibrain preferences
4
+ #
5
+ # The expectation is that this is created once and stored in
6
+ # the ibrain environment
7
+ #
8
+ # setters:
9
+ # a.color = :blue
10
+ # a[:color] = :blue
11
+ # a.set :color = :blue
12
+ # a.preferred_color = :blue
13
+ #
14
+ # getters:
15
+ # a.color
16
+ # a[:color]
17
+ # a.get :color
18
+ # a.preferred_color
19
+ #
20
+ require 'ibrain/preferences/configuration'
21
+ require 'ibrain/core/environment'
22
+
23
+ module Ibrain
24
+ class AppConfiguration < Preferences::Configuration
25
+ # Preferences (alphabetized to more easily lookup particular preferences)
26
+
27
+ # @!attribute [rw] guest_token_cookie_options
28
+ # @return [Hash] Add additional guest_token cookie options here (ie. domain or path)
29
+ preference :guest_token_cookie_options, :hash, default: {}
30
+
31
+ # @!attribute [rw] generate_api_key_for_all_roles
32
+ # @return [Boolean] Allow generating api key automatically for user
33
+ # at role_user creation for all roles. (default: +false+)
34
+ preference :generate_api_key_for_all_roles, :boolean, default: false
35
+
36
+ # @!attribute [rw] mails_from
37
+ # @return [String] Email address used as +From:+ field in transactional emails.
38
+ preference :mails_from, :string, default: 'ibrain@example.com'
39
+
40
+ preference :graphql_policy, :string, default: 'Ibrain::Policies::GraphqlPolicy'
41
+
42
+ # Api version for route config
43
+ preference :api_version, :string, default: 'v1'
44
+
45
+ # Graphql Schema name
46
+ preference :graphql_schema, :string, default: 'Ibrain::BaseSchema'
47
+
48
+ # Graphql Encryptor key
49
+ preference :ibrain_encryptor_key, :string, default: nil
50
+
51
+ def static_model_preferences
52
+ @static_model_preferences ||= Ibrain::Preferences::StaticModelPreferences.new
53
+ end
54
+
55
+ def roles
56
+ @roles ||= Ibrain::RoleConfiguration.new.tap do |roles|
57
+ roles.assign_permissions :default, ['Ibrain::PermissionSets::DefaultCustomer']
58
+ roles.assign_permissions :admin, ['Ibrain::PermissionSets::SuperUser']
59
+ end
60
+ end
61
+
62
+ def environment
63
+ @environment ||= Ibrain::Core::Environment.new(self)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ibrain/app_configuration'
4
+
5
+ Ibrain::Config = Ibrain::AppConfiguration.new
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module'
4
+
5
+ module Ibrain
6
+ module Core
7
+ module ClassConstantizer
8
+ class Set
9
+ include Enumerable
10
+
11
+ def initialize
12
+ @collection = ::Set.new
13
+ end
14
+
15
+ def <<(klass)
16
+ @collection << klass.to_s
17
+ end
18
+
19
+ def concat(klasses)
20
+ klasses.each do |klass|
21
+ self << klass
22
+ end
23
+
24
+ self
25
+ end
26
+
27
+ delegate :clear, :empty?, to: :@collection
28
+
29
+ def delete(object)
30
+ @collection.delete(object.to_s)
31
+ end
32
+
33
+ def each
34
+ @collection.each do |klass|
35
+ yield klass.constantize
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ module Core
5
+ module ControllerHelpers
6
+ module Auth
7
+ extend ActiveSupport::Concern
8
+ include Response
9
+
10
+ # @!attribute [rw] fallback_on_unauthorized
11
+ # @!scope class
12
+ # Extension point for overriding behaviour of access denied errors.
13
+ # Default behaviour is to redirect back or to "/unauthorized" with a flash
14
+ # message.
15
+ # @return [Proc] action to take when access denied error is raised.
16
+
17
+ included do
18
+ before_action :set_guest_token
19
+ helper_method :try_ibrain_current_user
20
+
21
+ class_attribute :fallback_on_unauthorized
22
+ self.fallback_on_unauthorized = -> do
23
+ error = ::Struct.new(
24
+ message: I18n.t('ibrain.authorization_failure')
25
+ )
26
+
27
+ render_json_error(error, :unauthorized)
28
+ end
29
+
30
+ rescue_from CanCan::AccessDenied do
31
+ instance_exec(&fallback_on_unauthorized)
32
+ end
33
+ end
34
+
35
+ # Needs to be overriden so that we use Brain's Ability rather than anyone else's.
36
+ def current_ability
37
+ @current_ability ||= Ibrain::Ability.new(try_ibrain_current_user)
38
+ end
39
+
40
+ def set_guest_token
41
+ # if cookies.signed[:guest_token].blank?
42
+ # cookies.permanent.signed[:guest_token] = Ibrain::Config[:guest_token_cookie_options].merge(
43
+ # value: SecureRandom.urlsafe_base64(nil, false),
44
+ # httponly: true
45
+ # )
46
+ # end
47
+ end
48
+
49
+ # proxy method to *possible* ibrain_current_user method
50
+ # Authentication extensions (such as ibrain-auth) are meant to provide ibrain_current_user
51
+ def try_ibrain_current_user
52
+ # This one will be defined by apps looking to hook into Ibrain
53
+ # As per authentication_helpers.rb
54
+ if respond_to?(:ibrain_current_user, true)
55
+ ibrain_current_user
56
+ # This one will be defined by Devise
57
+ elsif respond_to?(:current_ibrain_user, true)
58
+ current_ibrain_user
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ module Core
5
+ module ControllerHelpers
6
+ module CurrentHost
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ before_action do
11
+ ActiveStorage::Current.host = request.base_url
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ module Core
5
+ module ControllerHelpers
6
+ module Response
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ helper_method :render_json_error
11
+ helper_method :render_json_ok
12
+ end
13
+
14
+ protected
15
+
16
+ def render_json_error(error, status)
17
+ e_message = error.try(:record).try(:errors).try(:full_messages).try(:first)
18
+ e_message = error.try(:message) if e_message.blank?
19
+
20
+ backtrace = error.try(:backtrace).try(:join, "\n")
21
+
22
+ Ibrain::Logger.error e_message
23
+ Ibrain::Logger.error backtrace
24
+
25
+ render json: {
26
+ errors: [{
27
+ message: e_message,
28
+ extensions: {
29
+ code: status,
30
+ exception: {
31
+ stacktrace: [
32
+ backtrace
33
+ ]
34
+ }
35
+ }
36
+ }],
37
+ message: e_message,
38
+ data: nil
39
+ }, status: status
40
+ end
41
+
42
+ def render_json_ok(data, message, errors = [])
43
+ render json: {
44
+ errors: errors,
45
+ message: message || I18n.t('ibrain.system.message.ok'),
46
+ data: data.as_json
47
+ }, status: :ok
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ module Core
5
+ module ControllerHelpers
6
+ module StrongParameters
7
+ def permitted_attributes
8
+ Ibrain::PermittedAttributes
9
+ end
10
+
11
+ delegate(*Ibrain::PermittedAttributes::ATTRIBUTES,
12
+ to: :permitted_attributes,
13
+ prefix: :permitted)
14
+
15
+ def permitted_user_attributes
16
+ permitted_attributes.user_attributes
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ibrain/config'
4
+
5
+ module Ibrain
6
+ module Core
7
+ class Engine < ::Rails::Engine
8
+ isolate_namespace Ibrain
9
+ config.generators.api_only = true
10
+
11
+ initializer "ibrain.environment", before: :load_config_initializers do |app|
12
+ app.config.ibrain = Ibrain::Config.environment
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ibrain/core/environment_extension'
4
+
5
+ module Ibrain
6
+ module Core
7
+ class Environment
8
+ include EnvironmentExtension
9
+
10
+ attr_accessor :preferences
11
+
12
+ def initialize(ibrain_config)
13
+ @preferences = ibrain_config
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ibrain/core/class_constantizer'
4
+
5
+ module Ibrain
6
+ module Core
7
+ module EnvironmentExtension
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ def add_class_set(name)
12
+ define_method(name) do
13
+ set = instance_variable_get("@#{name}")
14
+ set ||= send("#{name}=", [])
15
+ set
16
+ end
17
+
18
+ define_method("#{name}=") do |klasses|
19
+ set = ClassConstantizer::Set.new
20
+ set.concat(klasses)
21
+ instance_variable_set("@#{name}", set)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+ require 'ibrain/core/class_constantizer'
5
+
6
+ module Ibrain
7
+ # A class responsible for associating {Ibrain::Role} with a list of permission sets.
8
+ #
9
+ # @see Ibrain::PermissionSets
10
+ #
11
+ # @example Adding order, data, and user display to customer service users.
12
+ # Ibrain::RoleConfiguration.configure do |config|
13
+ # config.assign_permissions :customer_service, [
14
+ # Ibrain::PermissionSets::UserDisplay,
15
+ # ]
16
+ # end
17
+ class RoleConfiguration
18
+ # An internal structure for the association between a role and a
19
+ # set of permissions.
20
+ class Role
21
+ attr_reader :name, :permission_sets
22
+
23
+ def initialize(name, permission_sets)
24
+ @name = name
25
+ @permission_sets = Ibrain::Core::ClassConstantizer::Set.new
26
+ @permission_sets.concat permission_sets
27
+ end
28
+ end
29
+
30
+ attr_accessor :roles
31
+
32
+ # Given a CanCan::Ability, and a user, determine what permissions sets can
33
+ # be activated on the ability, then activate them.
34
+ #
35
+ # This performs can/cannot declarations on the ability, and can modify its
36
+ # internal permissions.
37
+ #
38
+ # @param ability [CanCan::Ability] the ability to invoke declarations on
39
+ # @param user [#roles] the user that holds the roles association.
40
+ def activate_permissions!(ability, user)
41
+ ibrain_roles = ['default'] | user.roles.map(&:name)
42
+ applicable_permissions = Set.new
43
+
44
+ ibrain_roles.each do |role_name|
45
+ applicable_permissions |= roles[role_name].permission_sets
46
+ end
47
+
48
+ applicable_permissions.each do |permission_set|
49
+ permission_set.new(ability).activate!
50
+ end
51
+ end
52
+
53
+ # Not public due to the fact this class is a Singleton
54
+ # @!visibility private
55
+ def initialize
56
+ @roles = Hash.new do |hash, name|
57
+ hash[name] = Role.new(name, Set.new)
58
+ end
59
+ end
60
+
61
+ # Assign permission sets for a {Ibrain::Role} that has the name of role_name
62
+ # @param role_name [Symbol, String] The name of the role to associate permissions with
63
+ # @param permission_sets [Array<Ibrain::PermissionSets::Base>, Set<Ibrain::PermissionSets::Base>]
64
+ # A list of permission sets to activate if the user has the role indicated by role_name
65
+ def assign_permissions(role_name, permission_sets)
66
+ name = role_name.to_s
67
+
68
+ roles[name].permission_sets.concat permission_sets
69
+ roles[name]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ # == An ActiveModel Email Validator
5
+ #
6
+ # === Usage
7
+ #
8
+ # require 'ibrain/core/validators/email'
9
+ #
10
+ # class Person < ApplicationRecord
11
+ # validates :email_address, 'ibrain/email' => true
12
+ # end
13
+ #
14
+ class EmailValidator < ActiveModel::EachValidator
15
+ EMAIL_REGEXP = URI::MailTo::EMAIL_REGEXP
16
+
17
+ def validate_each(record, attribute, value)
18
+ unless EMAIL_REGEXP.match? value
19
+ record.errors.add(attribute, :invalid, **{ value: value }.merge!(options))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ VERSION = "0.1.0"
5
+
6
+ def self.ibrain_version
7
+ VERSION
8
+ end
9
+
10
+ def self.previous_ibrain_minor_version
11
+ '0.1.0'
12
+ end
13
+
14
+ def self.ibrain_gem_version
15
+ Gem::Version.new(ibrain_version)
16
+ end
17
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ibrain
4
+ module Core
5
+ # Wrapper for a value that can be different depending on the Ibrain version
6
+ #
7
+ # Some configuration defaults can be added or changed when a new Ibrain
8
+ # version is released. This class encapsulates getting the correct value for a
9
+ # given Ibrain version.
10
+ #
11
+ # The way it works is you provide an initial value in time, plus the version
12
+ # boundary where it got changed. Then you can fetch the value providing the
13
+ # desired Ibrain version:
14
+ #
15
+ # @example
16
+ # value = VersionedValue.new(true, "3.0.0" => false)
17
+ # value.call("2.7.0") # => true
18
+ # value.call("3.0.0") # => false
19
+ # value.call("3.1.0") # => false
20
+ #
21
+ # Remember that you must provide the exact boundary when a value got changed,
22
+ # which could easily be during a pre-release:
23
+ #
24
+ # @example
25
+ # value = VersionedValue.new(true, "3.0.0" => false)
26
+ # value.call("3.0.0.alpha") # => true
27
+ #
28
+ # value = VersionedValue.new(true, "3.0.0.alpha" => false)
29
+ # value.call("3.0.0.alpha") # => false
30
+ #
31
+ # Multiple boundaries can also be provided:
32
+ #
33
+ # @example
34
+ # value = VersionedValue.new(0, "2.0.0" => 1, "3.0.0" => 2)
35
+ # value.call("1.0.0") # => 0
36
+ # value.call("2.1.0") # => 1
37
+ # value.call("3.0.0") # => 2
38
+ class VersionedValue
39
+ attr_reader :boundaries
40
+
41
+ # @param initial_value [Any]
42
+ # @param boundary [Hash<String, Any>] Map from version number to new value
43
+ def initialize(initial_value, boundaries = {})
44
+ @boundaries = { '0' => initial_value }
45
+ .merge(boundaries)
46
+ .transform_keys { |version| to_gem_version(version) }
47
+ .sort.to_h
48
+ end
49
+
50
+ # @param ibrain_version [String]
51
+ def call(ibrain_version = Ibrain.ibrain_version)
52
+ ibrain_version = to_gem_version(ibrain_version)
53
+ boundaries.fetch(
54
+ boundaries
55
+ .keys
56
+ .reduce do |target, following|
57
+ if target <= ibrain_version && ibrain_version < following
58
+ target
59
+ else
60
+ following
61
+ end
62
+ end
63
+ )
64
+ end
65
+
66
+ private
67
+
68
+ def to_gem_version(string)
69
+ Gem::Version.new(string)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_controller/railtie"
4
+ require "action_mailer/railtie"
5
+ require "active_job/railtie"
6
+ require "active_model/railtie"
7
+ require "active_record/railtie"
8
+ require "active_storage/engine"
9
+ require 'activerecord/session_store'
10
+
11
+ require 'awesome_nested_set'
12
+ require 'cancan'
13
+ require 'friendly_id'
14
+ require 'kaminari/activerecord'
15
+ require 'rack/cors'
16
+ require 'ransack'
17
+
18
+ module Ibrain
19
+ mattr_accessor :user_class
20
+
21
+ def self.user_class
22
+ case @@user_class
23
+ when Class
24
+ raise "Ibrain.user_class MUST be a String or Symbol object, not a Class object."
25
+ when String, Symbol
26
+ @@user_class.to_s.constantize
27
+ end
28
+ end
29
+
30
+ # Load the same version defaults for all available Ibrain components
31
+ #
32
+ # @see Ibrain::Preferences::Configuration#load_defaults
33
+ def self.load_defaults(version)
34
+ Ibrain::Config.load_defaults(version)
35
+ Ibrain::Api::Config.load_defaults(version) if defined?(Ibrain::Api::Config)
36
+ end
37
+
38
+ # Used to configure Ibrain.
39
+ #
40
+ # Example:
41
+ #
42
+ # Ibrain.config do |config|
43
+ # config.track_inventory_levels = false
44
+ # end
45
+ #
46
+ # This method is defined within the core gem on purpose.
47
+ # Some people may only wish to use the Core part of Ibrain.
48
+ def self.config(&_block)
49
+ yield(Ibrain::Config)
50
+ end
51
+
52
+ module Core
53
+ def self.does_ibrain_initializer_exist?(rails_paths, initializer_name)
54
+ rails_paths['config/initializers'].any? do |path|
55
+ File.exist?(Pathname.new(path).join(initializer_name))
56
+ end
57
+ end
58
+
59
+ private_class_method :does_ibrain_initializer_exist?
60
+
61
+ class GatewayError < RuntimeError; end
62
+ end
63
+ end
64
+
65
+ require "ibrain/core/version"
66
+
67
+ require 'ibrain/core/class_constantizer'
68
+ require 'ibrain/core/environment_extension'
69
+ require 'ibrain/core/environment'
70
+
71
+ require "ibrain/core/engine"
72
+
73
+ require 'ibrain/i18n'
74
+ require 'ibrain/permitted_attributes'
75
+ require 'ibrain/permission_sets'
76
+ require 'ibrain/logger'
77
+
78
+ require 'ibrain/core/controller_helpers/response'
79
+ require 'ibrain/core/controller_helpers/current_host'
80
+ require 'ibrain/core/controller_helpers/strong_parameters'
81
+ require 'ibrain/core/controller_helpers/auth'
82
+ require 'ibrain/core/role_configuration'
83
+
84
+ require 'ibrain/core/validators/email'
85
+ require 'ibrain/user_class_handle'
86
+ require 'ibrain/encryptor'