ibrain-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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'