kangaru 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/kangaru/application.rb +2 -12
  5. data/lib/kangaru/concern.rb +31 -0
  6. data/lib/kangaru/concerns/attributable.rb +33 -0
  7. data/lib/kangaru/concerns/configurable.rb +13 -15
  8. data/lib/kangaru/concerns/validatable.rb +23 -33
  9. data/lib/kangaru/configurator.rb +2 -2
  10. data/lib/kangaru/database.rb +1 -1
  11. data/lib/kangaru/initialiser.rb +1 -1
  12. data/lib/kangaru/{injected_methods.rb → interface.rb} +16 -4
  13. data/lib/kangaru/model.rb +1 -1
  14. data/lib/kangaru/patches/inflections.rb +4 -2
  15. data/lib/kangaru/request.rb +2 -2
  16. data/lib/kangaru/validation/attribute_validator.rb +8 -12
  17. data/lib/kangaru/validation/error.rb +3 -11
  18. data/lib/kangaru/validation/model_validator.rb +27 -0
  19. data/lib/kangaru/validator.rb +20 -0
  20. data/lib/kangaru/validators/required_validator.rb +3 -1
  21. data/lib/kangaru/validators.rb +29 -0
  22. data/lib/kangaru/version.rb +1 -1
  23. data/lib/kangaru.rb +2 -1
  24. data/sig/kangaru/application.rbs +1 -3
  25. data/sig/kangaru/concern.rbs +13 -0
  26. data/sig/kangaru/concerns/attributable.rbs +25 -0
  27. data/sig/kangaru/concerns/configurable.rbs +8 -10
  28. data/sig/kangaru/concerns/validatable.rbs +14 -16
  29. data/sig/kangaru/configurator.rbs +4 -4
  30. data/sig/kangaru/database.rbs +2 -2
  31. data/sig/kangaru/initialiser.rbs +0 -4
  32. data/sig/kangaru/interface.rbs +21 -0
  33. data/sig/kangaru/model.rbs +2 -2
  34. data/sig/kangaru/patches/inflections.rbs +1 -1
  35. data/sig/kangaru/request.rbs +1 -1
  36. data/sig/kangaru/validation/attribute_validator.rbs +5 -7
  37. data/sig/kangaru/validation/error.rbs +2 -6
  38. data/sig/kangaru/validation/model_validator.rbs +19 -0
  39. data/sig/kangaru/validator.rbs +14 -0
  40. data/sig/kangaru/validators/required_validator.rbs +2 -0
  41. data/sig/kangaru/validators.rbs +11 -0
  42. data/sig/kangaru.rbs +0 -5
  43. metadata +14 -10
  44. data/lib/kangaru/concerns/attributes_concern.rb +0 -35
  45. data/lib/kangaru/concerns/concern.rb +0 -33
  46. data/lib/kangaru/validators/validator.rb +0 -22
  47. data/sig/kangaru/concerns/attributes_concern.rbs +0 -27
  48. data/sig/kangaru/concerns/concern.rbs +0 -15
  49. data/sig/kangaru/injected_methods.rbs +0 -19
  50. data/sig/kangaru/validators/validator.rbs +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db7c4419e9f9d9661c4d12498fcb5450cde2f209958f0bb7249a39dec4a93b54
4
- data.tar.gz: 43b3237bf249c4c4a3ef59eddbd4328a7b03a0084d9c69296557bab93d0b1492
3
+ metadata.gz: 9007bb0fb5d483fe6fb13697b94ec895958b93c5db157e82e4e7178e04278137
4
+ data.tar.gz: ff23e3595c129e04ae6391269570060929ecc73409d3e024eef14374c7d5957e
5
5
  SHA512:
6
- metadata.gz: c2c5dff9c5ecd0a4401261203f6c89d5837b7824dae3e88d8dd1ad7683f7ae9b65200892d81f4d20d181acca253c5b4dab9b48c24dae32c069dd3ddcea8fd5d9
7
- data.tar.gz: 6b1c7bbef5ef7a08437b5bd33b7fcfa8d2106bd29b52f8df7e56a228caff297fd22df609b96d8a6828390d6bc503bf4105fab52064efb1b4e146866e81a30162
6
+ metadata.gz: c3eb823da88e761346f49eff461333b79fe63768eb5093be6b6842e911eb9a4feab588755c7bceed9fc16d74118cc25cadf715b7f7dea829b47441c48843b86a
7
+ data.tar.gz: b1e203b218b378f571568e2730cd199ff8bc785929ec7eb1d8f42de3b34ce1f486fff4323607d95593bf7e2ae000db0b26a0eb0d6cd8d198464e122073b581b9
data/.rubocop.yml CHANGED
@@ -65,6 +65,7 @@ RSpec/ExpectChange:
65
65
  RSpec/FilePath:
66
66
  Exclude:
67
67
  - spec/kangaru/components/**/*.rb
68
+ - spec/kangaru/concerns/**/*.rb
68
69
  RSpec/LetSetup:
69
70
  Enabled: false
70
71
  RSpec/MultipleMemoizedHelpers:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kangaru (0.2.0)
4
+ kangaru (0.2.2)
5
5
  colorize (~> 1.1)
6
6
  erb (~> 4.0)
7
7
  sequel (~> 5.72)
@@ -24,11 +24,8 @@ module Kangaru
24
24
  @router ||= Router.new(namespace:)
25
25
  end
26
26
 
27
- # If called with no env, the config will be applied regardless of current
28
- # env. If multiple configure calls matching the current env are made, the
29
- # most recent calls will overwrite older changes.
30
- def configure(env = nil, &block)
31
- block.call(config) if current_env?(env)
27
+ def configure(&block)
28
+ block.call(config)
32
29
  end
33
30
 
34
31
  def configured?
@@ -62,13 +59,6 @@ module Kangaru
62
59
 
63
60
  private
64
61
 
65
- # Returns true if nil as this is represents all envs.
66
- def current_env?(env)
67
- return true if env.nil?
68
-
69
- Kangaru.env?(env)
70
- end
71
-
72
62
  def autoloader
73
63
  @autoloader ||= Zeitwerk::Loader.new.tap do |loader|
74
64
  loader.inflector = Zeitwerk::GemInflector.new(paths.source.to_s)
@@ -0,0 +1,31 @@
1
+ module Kangaru
2
+ module Concern
3
+ def append_features(base)
4
+ super
5
+ evaluate_concern_blocks!(base)
6
+ end
7
+
8
+ def class_methods(&)
9
+ if const_defined?(:ClassMethods)
10
+ const_get(:ClassMethods)
11
+ else
12
+ const_set(:ClassMethods, Module.new)
13
+ end.module_eval(&)
14
+ end
15
+
16
+ def included(base = nil, &block)
17
+ super base if base
18
+ return if block.nil?
19
+
20
+ @included = block
21
+ end
22
+
23
+ private
24
+
25
+ def evaluate_concern_blocks!(base)
26
+ base.extend(const_get(:ClassMethods)) if const_defined?(:ClassMethods)
27
+
28
+ base.class_eval(&@included) if instance_variable_defined?(:@included)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ module Kangaru
2
+ module Attributable
3
+ extend Concern
4
+
5
+ class_methods do
6
+ def attributes
7
+ instance_methods.grep(/\w=$/).map do |attribute|
8
+ attribute.to_s.delete_suffix("=").to_sym
9
+ end
10
+ end
11
+
12
+ def set_default(**attributes)
13
+ defaults.merge!(**attributes)
14
+ end
15
+
16
+ def defaults
17
+ @defaults ||= {}
18
+ end
19
+ end
20
+
21
+ def initialize(**attributes)
22
+ attributes = self.class.defaults.merge(**attributes)
23
+
24
+ merge!(**attributes)
25
+ end
26
+
27
+ def merge!(**attributes)
28
+ attributes.slice(*self.class.attributes).each do |attr, value|
29
+ instance_variable_set(:"@#{attr}", value)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,23 +1,21 @@
1
1
  module Kangaru
2
- module Concerns
3
- module Configurable
4
- extend Concern
2
+ module Configurable
3
+ extend Concern
5
4
 
6
- using Patches::Inflections
5
+ using Patches::Inflections
7
6
 
8
- class_methods do
9
- def configurator_key
10
- (name || raise("class name not set"))
11
- .gsub(/^.*::/, "")
12
- .to_snakecase
13
- .to_sym
14
- end
7
+ class_methods do
8
+ def configurator_key
9
+ (name || raise("class name not set"))
10
+ .gsub(/^.*::/, "")
11
+ .to_snakecase
12
+ .to_sym
15
13
  end
14
+ end
16
15
 
17
- def config
18
- Kangaru.application!.config[self.class.configurator_key] ||
19
- raise("inferred configurator not set by application")
20
- end
16
+ def config
17
+ Kangaru.application!.config[self.class.configurator_key] ||
18
+ raise("inferred configurator not set by application")
21
19
  end
22
20
  end
23
21
  end
@@ -1,46 +1,36 @@
1
1
  module Kangaru
2
- module Concerns
3
- module Validatable
4
- extend Concern
5
-
6
- class_methods do
7
- def validation_rules
8
- @validation_rules ||= {}
9
- end
10
-
11
- def validates(attribute, **validations)
12
- validation_rules[attribute] ||= {}
13
- validation_rules[attribute].merge!(**validations)
14
- end
15
- end
2
+ module Validatable
3
+ extend Concern
16
4
 
17
- def errors
18
- @errors ||= []
5
+ class_methods do
6
+ def validation_rules
7
+ @validation_rules ||= {}
19
8
  end
20
9
 
21
- def validate
22
- self.class.validation_rules.each do |attribute, validations|
23
- validator = validator_for(attribute)
10
+ def validates(attribute, **validations)
11
+ validation_rules[attribute] ||= {}
12
+ validation_rules[attribute].merge!(**validations)
13
+ end
14
+ end
24
15
 
25
- validations.each do |validator_name, params|
26
- params = {} if params == true
16
+ def errors
17
+ @errors ||= []
18
+ end
27
19
 
28
- validator.validate(validator_name, **params)
29
- end
30
- end
31
- end
20
+ def validate
21
+ model_validator.validate!(**self.class.validation_rules)
22
+ end
32
23
 
33
- def valid?
34
- validate
24
+ def valid?
25
+ validate
35
26
 
36
- errors.empty?
37
- end
27
+ errors.empty?
28
+ end
38
29
 
39
- private
30
+ private
40
31
 
41
- def validator_for(attribute)
42
- Validation::AttributeValidator.new(model: self, attribute:)
43
- end
32
+ def model_validator
33
+ @model_validator ||= Validation::ModelValidator.new(model: self)
44
34
  end
45
35
  end
46
36
  end
@@ -1,7 +1,7 @@
1
1
  module Kangaru
2
2
  class Configurator
3
- include Concerns::AttributesConcern
4
- include Concerns::Validatable
3
+ include Attributable
4
+ include Validatable
5
5
 
6
6
  using Patches::Inflections
7
7
 
@@ -2,7 +2,7 @@ module Kangaru
2
2
  class Database
3
3
  extend Forwardable
4
4
 
5
- include Concerns::AttributesConcern
5
+ include Attributable
6
6
 
7
7
  PLUGINS = %i[
8
8
  enum
@@ -6,7 +6,7 @@ module Kangaru
6
6
  Kangaru.application = Application.new(source:, namespace:)
7
7
  Kangaru.eager_load(Initialisers)
8
8
 
9
- namespace.extend InjectedMethods
9
+ namespace.extend Interface
10
10
  end
11
11
  end
12
12
  end
@@ -1,5 +1,5 @@
1
1
  module Kangaru
2
- module InjectedMethods
2
+ module Interface
3
3
  def run!(*argv)
4
4
  Kangaru.application!.run!(*argv)
5
5
  end
@@ -8,11 +8,15 @@ module Kangaru
8
8
  Kangaru.application!.config
9
9
  end
10
10
 
11
- def configure(env = nil, &)
12
- Kangaru.application!.configure(env, &)
11
+ def configure(env: nil, &)
12
+ return unless env_applies?(env)
13
+
14
+ Kangaru.application!.configure(&)
13
15
  end
14
16
 
15
- def import_config_from!(path)
17
+ def config_path(path, env: nil)
18
+ return unless env_applies?(env)
19
+
16
20
  Kangaru.application!.config_path = path
17
21
  end
18
22
 
@@ -23,5 +27,13 @@ module Kangaru
23
27
  def database
24
28
  Kangaru.application!.database
25
29
  end
30
+
31
+ private
32
+
33
+ def env_applies?(env)
34
+ return true if env.nil?
35
+
36
+ Kangaru.env?(env)
37
+ end
26
38
  end
27
39
  end
data/lib/kangaru/model.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Kangaru
2
2
  Model = Class.new(Sequel::Model) do
3
- include Concerns::Validatable
3
+ include Validatable
4
4
  end
5
5
 
6
6
  Model.def_Model(self)
@@ -2,8 +2,10 @@ module Kangaru
2
2
  module Patches
3
3
  module Inflections
4
4
  refine String do
5
- def to_class_name
6
- Inflectors::ClassInflector.inflect(self)
5
+ def to_class_name(suffix: nil)
6
+ class_name = Inflectors::ClassInflector.inflect(self)
7
+
8
+ [class_name, suffix.to_s.capitalize].compact.join
7
9
  end
8
10
 
9
11
  def to_constant_name
@@ -2,7 +2,7 @@ module Kangaru
2
2
  class Request
3
3
  using Patches::Inflections
4
4
 
5
- include Concerns::Configurable
5
+ include Configurable
6
6
 
7
7
  DEFAULT_CONTROLLER = "DefaultController".freeze
8
8
 
@@ -18,7 +18,7 @@ module Kangaru
18
18
  def controller
19
19
  return default_controller if path_parser.controller.nil?
20
20
 
21
- path_parser.controller&.to_class_name&.concat(Controller::SUFFIX) || raise
21
+ path_parser.controller&.to_class_name(suffix: Controller::SUFFIX) || raise
22
22
  end
23
23
 
24
24
  def action
@@ -10,22 +10,18 @@ module Kangaru
10
10
  @attribute = attribute
11
11
  end
12
12
 
13
- def validate(validator, **params)
14
- load_validator(validator:, params:).validate
15
- end
16
-
17
- private
13
+ def validate!(**validations)
14
+ validations.each do |validator, params|
15
+ params = {} if params == true
18
16
 
19
- def validator_name(validator)
20
- "#{validator.to_s.to_class_name}Validator"
17
+ load_validator(validator:, **params).validate
18
+ end
21
19
  end
22
20
 
23
- def load_validator(validator:, params:)
24
- name = validator_name(validator)
25
-
26
- raise "#{name} is not defined" unless Validators.const_defined?(name)
21
+ private
27
22
 
28
- Validators.const_get(name).new(model:, attribute:, params:)
23
+ def load_validator(validator:, **params)
24
+ Validators.get(validator).new(model:, attribute:, **params)
29
25
  end
30
26
  end
31
27
  end
@@ -3,15 +3,11 @@ module Kangaru
3
3
  class Error
4
4
  using Patches::Inflections
5
5
 
6
- MESSAGES = {
7
- blank: "can't be blank"
8
- }.freeze
6
+ attr_reader :attribute, :message
9
7
 
10
- attr_reader :attribute, :type
11
-
12
- def initialize(attribute:, type:)
8
+ def initialize(attribute:, message:)
13
9
  @attribute = attribute
14
- @type = type
10
+ @message = message
15
11
  end
16
12
 
17
13
  def full_message
@@ -23,10 +19,6 @@ module Kangaru
23
19
  def human_attribute
24
20
  attribute.to_s.to_humanised
25
21
  end
26
-
27
- def message
28
- MESSAGES[type] || raise("invalid message type")
29
- end
30
22
  end
31
23
  end
32
24
  end
@@ -0,0 +1,27 @@
1
+ module Kangaru
2
+ module Validation
3
+ class ModelValidator
4
+ attr_reader :model
5
+
6
+ def initialize(model:)
7
+ @model = model
8
+ end
9
+
10
+ def validate!(**rules)
11
+ rules.each do |attribute, validations|
12
+ validate_attribute!(attribute, validations)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def validate_attribute!(attribute, validations)
19
+ load_attribute_validator(attribute).validate!(**validations)
20
+ end
21
+
22
+ def load_attribute_validator(attribute)
23
+ AttributeValidator.new(model:, attribute:)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Kangaru
2
+ class Validator
3
+ attr_reader :model, :attribute, :params, :value
4
+
5
+ def initialize(model:, attribute:, **params)
6
+ @model = model
7
+ @attribute = attribute
8
+ @params = params
9
+ @value = model.public_send(attribute)
10
+ end
11
+
12
+ def validate
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def add_error!(message)
17
+ model.errors << Validation::Error.new(attribute:, message:)
18
+ end
19
+ end
20
+ end
@@ -1,10 +1,12 @@
1
1
  module Kangaru
2
2
  module Validators
3
3
  class RequiredValidator < Validator
4
+ MESSAGE = "can't be blank".freeze
5
+
4
6
  def validate
5
7
  return unless value_missing?
6
8
 
7
- add_error!(:blank)
9
+ add_error!(MESSAGE)
8
10
  end
9
11
 
10
12
  private
@@ -0,0 +1,29 @@
1
+ module Kangaru
2
+ module Validators
3
+ using Patches::Inflections
4
+
5
+ def self.get(name)
6
+ class_name = name.to_s.to_class_name(suffix: :validator)
7
+
8
+ from_kangaru(class_name) || from_application(class_name) ||
9
+ raise("#{class_name} is not defined")
10
+ end
11
+
12
+ def self.from_kangaru(class_name)
13
+ return unless const_defined?(class_name)
14
+
15
+ const_get(class_name)
16
+ end
17
+
18
+ def self.from_application(class_name)
19
+ namespace = Kangaru.application&.const_get(:Validators)
20
+
21
+ return unless namespace&.const_defined?(class_name)
22
+
23
+ namespace.const_get(class_name)
24
+ end
25
+
26
+ private_class_method :from_kangaru
27
+ private_class_method :from_application
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module Kangaru
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.2.2".freeze
3
3
  end
data/lib/kangaru.rb CHANGED
@@ -11,7 +11,8 @@ require "yaml"
11
11
 
12
12
  module Kangaru
13
13
  COLLAPSED_DIRS = [
14
- "#{__dir__}/kangaru/components"
14
+ "#{__dir__}/kangaru/components",
15
+ "#{__dir__}/kangaru/concerns"
15
16
  ].freeze
16
17
 
17
18
  DEFAULT_ENV = :runtime
@@ -16,7 +16,7 @@ module Kangaru
16
16
 
17
17
  def initialize: (source: String, namespace: Module) -> void
18
18
 
19
- def configure: (?Symbol?) { (Config) -> void } -> void
19
+ def configure: { (Config) -> void } -> void
20
20
 
21
21
  def configured?: -> bool
22
22
 
@@ -34,8 +34,6 @@ module Kangaru
34
34
 
35
35
  @configured: bool
36
36
 
37
- def current_env?: (Symbol?) -> bool
38
-
39
37
  attr_reader autoloader: Zeitwerk::Loader
40
38
 
41
39
  def validate_config!: -> void
@@ -0,0 +1,13 @@
1
+ module Kangaru
2
+ module Concern : Module
3
+ @included: untyped
4
+
5
+ def append_features: (untyped) -> void
6
+
7
+ def class_methods: { [self: singleton(Class)] -> void } -> void
8
+
9
+ def included: (?untyped?) ?{ -> void } -> void
10
+
11
+ def evaluate_concern_blocks!: (untyped) -> void
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ module Kangaru
2
+ module Attributable
3
+ extend Concern
4
+
5
+ module ClassMethods
6
+ def attributes: -> Array[Symbol]
7
+
8
+ def defaults: -> Hash[Symbol, untyped]
9
+
10
+ def set_default: (**untyped) -> void
11
+
12
+ @defaults: Hash[Symbol, untyped]
13
+ end
14
+
15
+ extend ClassMethods
16
+
17
+ attr_reader defaults: Hash[Symbol, untyped]
18
+
19
+ def instance_methods: -> Array[Symbol]
20
+
21
+ def initialize: (**untyped) -> void
22
+
23
+ def merge!: (**untyped) -> void
24
+ end
25
+ end
@@ -1,15 +1,13 @@
1
1
  module Kangaru
2
- module Concerns
3
- module Configurable
4
- extend Concern
5
- extend ClassMethods
2
+ module Configurable
3
+ extend Concern
4
+ extend ClassMethods
6
5
 
7
- module ClassMethods
8
- def configurator_key: -> Symbol
9
- end
10
-
11
- def name: -> String
12
- def config: -> untyped
6
+ module ClassMethods
7
+ def configurator_key: -> Symbol
13
8
  end
9
+
10
+ def name: -> String
11
+ def config: -> untyped
14
12
  end
15
13
  end
@@ -1,28 +1,26 @@
1
1
  module Kangaru
2
- module Concerns
3
- module Validatable
4
- type validations = Hash[Symbol, Hash[Symbol, untyped]]
2
+ module Validatable
3
+ type validations = Hash[Symbol, Hash[Symbol, untyped]]
5
4
 
6
- extend Concern
7
- extend ClassMethods
5
+ extend Concern
6
+ extend ClassMethods
8
7
 
9
- attr_reader validation_rules: validations
8
+ attr_reader validation_rules: validations
10
9
 
11
- module ClassMethods
12
- attr_reader validation_rules: validations
10
+ module ClassMethods
11
+ attr_reader validation_rules: validations
13
12
 
14
- def validates: (Symbol, **untyped) -> void
15
- end
13
+ def validates: (Symbol, **untyped) -> void
14
+ end
16
15
 
17
- attr_reader errors: Array[Validation::Error]
16
+ attr_reader errors: Array[Validation::Error]
18
17
 
19
- def validate: -> void
18
+ def validate: -> void
20
19
 
21
- def valid?: -> bool
20
+ def valid?: -> bool
22
21
 
23
- private
22
+ private
24
23
 
25
- def validator_for: (Symbol) -> Validation::AttributeValidator
26
- end
24
+ attr_reader model_validator: Validation::ModelValidator
27
25
  end
28
26
  end
@@ -1,10 +1,10 @@
1
1
  module Kangaru
2
2
  class Configurator
3
- include Concerns::AttributesConcern
4
- extend Concerns::AttributesConcern::ClassMethods
3
+ include Attributable
4
+ extend Attributable::ClassMethods
5
5
 
6
- include Concerns::Validatable
7
- extend Concerns::Validatable::ClassMethods
6
+ include Validatable
7
+ extend Validatable::ClassMethods
8
8
 
9
9
  def self.key: -> Symbol
10
10
 
@@ -2,8 +2,8 @@ module Kangaru
2
2
  class Database
3
3
  extend Forwardable
4
4
 
5
- include Concerns::AttributesConcern
6
- extend Concerns::AttributesConcern::ClassMethods
5
+ include Attributable
6
+ extend Attributable::ClassMethods
7
7
 
8
8
  PLUGINS: Array[Symbol]
9
9
 
@@ -1,9 +1,5 @@
1
1
  module Kangaru
2
2
  module Initialiser
3
- module InjectedMethods
4
- include Kangaru::_ApplicationMethods
5
- end
6
-
7
3
  def self.extended: (Module) -> void
8
4
  end
9
5
  end
@@ -0,0 +1,21 @@
1
+ module Kangaru
2
+ module Interface
3
+ type env = Symbol?
4
+
5
+ def run!: (*String) -> void
6
+
7
+ def config: -> Config
8
+
9
+ def configure: (?env: env) { (Config) -> void } -> void
10
+
11
+ def apply_config!: -> void
12
+
13
+ def config_path: (String, ?env: env) -> void
14
+
15
+ def database: -> Database?
16
+
17
+ private
18
+
19
+ def env_applies?: (Symbol?) -> bool
20
+ end
21
+ end
@@ -8,8 +8,8 @@ module Kangaru
8
8
  end
9
9
 
10
10
  class Model < Sequel::Model
11
- include Concerns::Validatable
12
- extend Concerns::Validatable::ClassMethods
11
+ include Validatable
12
+ extend Validatable::ClassMethods
13
13
 
14
14
  def self.enum: (Symbol, **Integer) -> void
15
15
  end
@@ -2,7 +2,7 @@ module Kangaru
2
2
  module Patches
3
3
  module Inflections : String
4
4
  class ::String
5
- def to_class_name: -> String
5
+ def to_class_name: (?suffix: String? | Symbol?) -> String
6
6
 
7
7
  def to_constant_name: -> String
8
8
 
@@ -1,6 +1,6 @@
1
1
  module Kangaru
2
2
  class Request
3
- include Concerns::Configurable
3
+ include Configurable
4
4
 
5
5
  DEFAULT_CONTROLLER: String
6
6
 
@@ -1,21 +1,19 @@
1
1
  module Kangaru
2
2
  module Validation
3
3
  class AttributeValidator
4
+ type validations = Hash[Symbol, rule]
5
+ type rule = bool | Hash[Symbol, untyped]
6
+
4
7
  attr_reader model: untyped
5
8
  attr_reader attribute: Symbol
6
9
 
7
10
  def initialize: (model: untyped, attribute: Symbol) -> void
8
11
 
9
- def validate: (Symbol, **untyped) -> void
12
+ def validate!: (**untyped) -> void
10
13
 
11
14
  private
12
15
 
13
- def validator_name: (Symbol) -> String
14
-
15
- def load_validator: (
16
- validator: Symbol,
17
- params: Hash[Symbol, untyped]
18
- ) -> Validators::Validator
16
+ def load_validator: (validator: Symbol, **untyped) -> Validator
19
17
  end
20
18
  end
21
19
  end
@@ -1,20 +1,16 @@
1
1
  module Kangaru
2
2
  module Validation
3
3
  class Error
4
- MESSAGES: Hash[Symbol, String]
5
-
6
4
  attr_reader attribute: Symbol
7
- attr_reader type: Symbol
5
+ attr_reader message: String
8
6
 
9
- def initialize: (attribute: Symbol, type: Symbol) -> void
7
+ def initialize: (attribute: Symbol, message: String) -> void
10
8
 
11
9
  def full_message: -> String
12
10
 
13
11
  private
14
12
 
15
13
  def human_attribute: -> String
16
-
17
- def message: -> String
18
14
  end
19
15
  end
20
16
  end
@@ -0,0 +1,19 @@
1
+ module Kangaru
2
+ module Validation
3
+ class ModelValidator
4
+ type rules = Hash[Symbol, AttributeValidator::validations]
5
+
6
+ attr_reader model: untyped
7
+
8
+ def initialize: (model: untyped) -> void
9
+
10
+ def validate!: (**rules) -> void
11
+
12
+ private
13
+
14
+ def validate_attribute!: (Symbol, AttributeValidator::validations) -> void
15
+
16
+ def load_attribute_validator: (Symbol) -> AttributeValidator
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module Kangaru
2
+ class Validator
3
+ attr_reader model: untyped
4
+ attr_reader attribute: Symbol
5
+ attr_reader params: Hash[Symbol, untyped]
6
+ attr_reader value: untyped
7
+
8
+ def initialize: (model: untyped, attribute: Symbol, **untyped) -> void
9
+
10
+ def validate: -> void
11
+
12
+ def add_error!: (String) -> void
13
+ end
14
+ end
@@ -1,6 +1,8 @@
1
1
  module Kangaru
2
2
  module Validators
3
3
  class RequiredValidator < Validator
4
+ MESSAGE: String
5
+
4
6
  private
5
7
 
6
8
  def value_missing?: -> bool
@@ -0,0 +1,11 @@
1
+ module Kangaru
2
+ module Validators
3
+ def self.get: (String | Symbol) -> singleton(Validator)
4
+
5
+ private
6
+
7
+ def self.from_kangaru: (String | Symbol) -> singleton(Validator)?
8
+
9
+ def self.from_application: (String | Symbol) -> singleton(Validator)?
10
+ end
11
+ end
data/sig/kangaru.rbs CHANGED
@@ -21,9 +21,4 @@ module Kangaru
21
21
 
22
22
  def test?: -> bool
23
23
  end
24
-
25
- # Included in target applications that extend Kangaru::Initialiser.
26
- interface _ApplicationMethods
27
- include InjectedMethods::_InjectedMethods
28
- end
29
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kangaru
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Welham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-12 00:00:00.000000000 Z
11
+ date: 2023-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -102,8 +102,8 @@ files:
102
102
  - lib/kangaru/application.rb
103
103
  - lib/kangaru/argument_parser.rb
104
104
  - lib/kangaru/components/component.rb
105
- - lib/kangaru/concerns/attributes_concern.rb
106
- - lib/kangaru/concerns/concern.rb
105
+ - lib/kangaru/concern.rb
106
+ - lib/kangaru/concerns/attributable.rb
107
107
  - lib/kangaru/concerns/configurable.rb
108
108
  - lib/kangaru/concerns/validatable.rb
109
109
  - lib/kangaru/config.rb
@@ -127,7 +127,7 @@ files:
127
127
  - lib/kangaru/initialisers/rspec.rb
128
128
  - lib/kangaru/initialisers/rspec/kangaru_helper.rb
129
129
  - lib/kangaru/initialisers/rspec/request_helper.rb
130
- - lib/kangaru/injected_methods.rb
130
+ - lib/kangaru/interface.rb
131
131
  - lib/kangaru/model.rb
132
132
  - lib/kangaru/patches/constantise.rb
133
133
  - lib/kangaru/patches/inflections.rb
@@ -141,8 +141,10 @@ files:
141
141
  - lib/kangaru/router.rb
142
142
  - lib/kangaru/validation/attribute_validator.rb
143
143
  - lib/kangaru/validation/error.rb
144
+ - lib/kangaru/validation/model_validator.rb
145
+ - lib/kangaru/validator.rb
146
+ - lib/kangaru/validators.rb
144
147
  - lib/kangaru/validators/required_validator.rb
145
- - lib/kangaru/validators/validator.rb
146
148
  - lib/kangaru/version.rb
147
149
  - rbs_collection.lock.yaml
148
150
  - rbs_collection.yaml
@@ -151,8 +153,8 @@ files:
151
153
  - sig/kangaru/application.rbs
152
154
  - sig/kangaru/argument_parser.rbs
153
155
  - sig/kangaru/components/component.rbs
154
- - sig/kangaru/concerns/attributes_concern.rbs
155
- - sig/kangaru/concerns/concern.rbs
156
+ - sig/kangaru/concern.rbs
157
+ - sig/kangaru/concerns/attributable.rbs
156
158
  - sig/kangaru/concerns/configurable.rbs
157
159
  - sig/kangaru/concerns/validatable.rbs
158
160
  - sig/kangaru/config.rbs
@@ -174,7 +176,7 @@ files:
174
176
  - sig/kangaru/inflectors/tokeniser.rbs
175
177
  - sig/kangaru/initialiser.rbs
176
178
  - sig/kangaru/initialisers/rspec.rbs
177
- - sig/kangaru/injected_methods.rbs
179
+ - sig/kangaru/interface.rbs
178
180
  - sig/kangaru/model.rbs
179
181
  - sig/kangaru/patches/constantise.rbs
180
182
  - sig/kangaru/patches/inflections.rbs
@@ -188,8 +190,10 @@ files:
188
190
  - sig/kangaru/router.rbs
189
191
  - sig/kangaru/validation/attribute_validator.rbs
190
192
  - sig/kangaru/validation/error.rbs
193
+ - sig/kangaru/validation/model_validator.rbs
194
+ - sig/kangaru/validator.rbs
195
+ - sig/kangaru/validators.rbs
191
196
  - sig/kangaru/validators/required_validator.rbs
192
- - sig/kangaru/validators/validator.rbs
193
197
  homepage: https://github.com/apexatoll/kangaru
194
198
  licenses:
195
199
  - MIT
@@ -1,35 +0,0 @@
1
- module Kangaru
2
- module Concerns
3
- module AttributesConcern
4
- extend Concern
5
-
6
- class_methods do
7
- def attributes
8
- instance_methods.grep(/\w=$/).map do |attribute|
9
- attribute.to_s.delete_suffix("=").to_sym
10
- end
11
- end
12
-
13
- def set_default(**attributes)
14
- defaults.merge!(**attributes)
15
- end
16
-
17
- def defaults
18
- @defaults ||= {}
19
- end
20
- end
21
-
22
- def initialize(**attributes)
23
- attributes = self.class.defaults.merge(**attributes)
24
-
25
- merge!(**attributes)
26
- end
27
-
28
- def merge!(**attributes)
29
- attributes.slice(*self.class.attributes).each do |attr, value|
30
- instance_variable_set(:"@#{attr}", value)
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,33 +0,0 @@
1
- module Kangaru
2
- module Concerns
3
- module Concern
4
- def append_features(base)
5
- super
6
- evaluate_concern_blocks!(base)
7
- end
8
-
9
- def class_methods(&)
10
- if const_defined?(:ClassMethods)
11
- const_get(:ClassMethods)
12
- else
13
- const_set(:ClassMethods, Module.new)
14
- end.module_eval(&)
15
- end
16
-
17
- def included(base = nil, &block)
18
- super base if base
19
- return if block.nil?
20
-
21
- @included = block
22
- end
23
-
24
- private
25
-
26
- def evaluate_concern_blocks!(base)
27
- base.extend(const_get(:ClassMethods)) if const_defined?(:ClassMethods)
28
-
29
- base.class_eval(&@included) if instance_variable_defined?(:@included)
30
- end
31
- end
32
- end
33
- end
@@ -1,22 +0,0 @@
1
- module Kangaru
2
- module Validators
3
- class Validator
4
- attr_reader :model, :attribute, :params, :value
5
-
6
- def initialize(model:, attribute:, params:)
7
- @model = model
8
- @attribute = attribute
9
- @params = params
10
- @value = model.public_send(attribute)
11
- end
12
-
13
- def validate
14
- raise NotImplementedError
15
- end
16
-
17
- def add_error!(type)
18
- model.errors << Validation::Error.new(attribute:, type:)
19
- end
20
- end
21
- end
22
- end
@@ -1,27 +0,0 @@
1
- module Kangaru
2
- module Concerns
3
- module AttributesConcern
4
- extend Concern
5
-
6
- module ClassMethods
7
- def attributes: -> Array[Symbol]
8
-
9
- def defaults: -> Hash[Symbol, untyped]
10
-
11
- def set_default: (**untyped) -> void
12
-
13
- @defaults: Hash[Symbol, untyped]
14
- end
15
-
16
- extend ClassMethods
17
-
18
- attr_reader defaults: Hash[Symbol, untyped]
19
-
20
- def instance_methods: -> Array[Symbol]
21
-
22
- def initialize: (**untyped) -> void
23
-
24
- def merge!: (**untyped) -> void
25
- end
26
- end
27
- end
@@ -1,15 +0,0 @@
1
- module Kangaru
2
- module Concerns
3
- module Concern : Module
4
- @included: untyped
5
-
6
- def append_features: (untyped) -> void
7
-
8
- def class_methods: { [self: singleton(Class)] -> void } -> void
9
-
10
- def included: (?untyped?) ?{ -> void } -> void
11
-
12
- def evaluate_concern_blocks!: (untyped) -> void
13
- end
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- module Kangaru
2
- module InjectedMethods
3
- interface _InjectedMethods
4
- def run!: (*String) -> void
5
-
6
- def config: -> Config
7
-
8
- def configure: (?Symbol?) { (Config) -> void } -> void
9
-
10
- def apply_config!: -> void
11
-
12
- def import_config_from!: (String) -> void
13
-
14
- def database: -> Database?
15
- end
16
-
17
- include _InjectedMethods
18
- end
19
- end
@@ -1,20 +0,0 @@
1
- module Kangaru
2
- module Validators
3
- class Validator
4
- attr_reader model: untyped
5
- attr_reader attribute: Symbol
6
- attr_reader params: Hash[Symbol, untyped]
7
- attr_reader value: untyped
8
-
9
- def initialize: (
10
- model: untyped,
11
- attribute: Symbol,
12
- params: Hash[Symbol, untyped]
13
- ) -> void
14
-
15
- def validate: -> void
16
-
17
- def add_error!: (Symbol) -> void
18
- end
19
- end
20
- end