attribeauty 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ff07e0947450ca0181b92fbed9438ffa4d4e063cd905dcc5148fc47e8640318
4
- data.tar.gz: df35a5f68e745e8ab9decd67c891ca73aa4cd074cdd6695e10ec5313644d4b2c
3
+ metadata.gz: 7c705d3129b34e6dbc91c53163face634eafbc288a2b36b2768faf97a77a7f8a
4
+ data.tar.gz: 1553078b6ae388c7d75c367e9f70b2e1153b59b4999ce7fbe7da7bf078d64725
5
5
  SHA512:
6
- metadata.gz: 4566885478384847bdbe5965fddf3fcf2eb8bccd82782ed0da412cd77c3b89cec6f18965d4777b944313f40350e40a2a00b457af03c088aa4b33f5afc6906c91
7
- data.tar.gz: aca7be5f1af5279ff400ea9f0220146b48b51c74e6d03e8246d13cc300a5794391e8fd3c4f7bcb2197aa0b7f3b3e091fb91a4669f3d5b33089b1fd2ef6b3f387
6
+ metadata.gz: efb29ddb06c0c1391d661efcc43b4b1e122233a7c0a481f0fe5bb96a00fe190e0bd05e87640f8f16872ca32c9bd6aaf7120665a6f931b8d41d60109dc8ac49af
7
+ data.tar.gz: 9c10fb519ec0eaaffd5a31d02c5aea808917fd2ce0b3421ba4e4edf1c4b8dba796ac2fddda907e62e79ba9edf8c8c2355dc37a564346b7377979994ef57ea603
data/.bin/bundle ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "rubygems"
12
+
13
+ m = Module.new do
14
+ module_function
15
+
16
+ def invoked_as_script?
17
+ File.expand_path($0) == File.expand_path(__FILE__)
18
+ end
19
+
20
+ def env_var_version
21
+ ENV["BUNDLER_VERSION"]
22
+ end
23
+
24
+ def cli_arg_version
25
+ return unless invoked_as_script? # don't want to hijack other binstubs
26
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
+ bundler_version = nil
28
+ update_index = nil
29
+ ARGV.each_with_index do |a, i|
30
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
31
+ bundler_version = a
32
+ end
33
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
+ bundler_version = $1
35
+ update_index = i
36
+ end
37
+ bundler_version
38
+ end
39
+
40
+ def gemfile
41
+ gemfile = ENV["BUNDLE_GEMFILE"]
42
+ return gemfile if gemfile && !gemfile.empty?
43
+
44
+ File.expand_path("../Gemfile", __dir__)
45
+ end
46
+
47
+ def lockfile
48
+ lockfile =
49
+ case File.basename(gemfile)
50
+ when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
51
+ else "#{gemfile}.lock"
52
+ end
53
+ File.expand_path(lockfile)
54
+ end
55
+
56
+ def lockfile_version
57
+ return unless File.file?(lockfile)
58
+ lockfile_contents = File.read(lockfile)
59
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
+ Regexp.last_match(1)
61
+ end
62
+
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
+ env_var_version ||
66
+ cli_arg_version ||
67
+ bundler_requirement_for(lockfile_version)
68
+ end
69
+
70
+ def bundler_requirement_for(version)
71
+ return "#{Gem::Requirement.default}.a" unless version
72
+
73
+ bundler_gem_version = Gem::Version.new(version)
74
+
75
+ bundler_gem_version.approximate_recommendation
76
+ end
77
+
78
+ def load_bundler!
79
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
80
+
81
+ activate_bundler
82
+ end
83
+
84
+ def activate_bundler
85
+ gem_error = activation_error_handling do
86
+ gem "bundler", bundler_requirement
87
+ end
88
+ return if gem_error.nil?
89
+ require_error = activation_error_handling do
90
+ require "bundler/version"
91
+ end
92
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
93
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
94
+ exit 42
95
+ end
96
+
97
+ def activation_error_handling
98
+ yield
99
+ nil
100
+ rescue StandardError, LoadError => e
101
+ e
102
+ end
103
+ end
104
+
105
+ m.load_bundler!
106
+
107
+ if m.invoked_as_script?
108
+ load Gem.bin_path("bundler", "bundle")
109
+ end
data/.bin/racc ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'racc' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("racc", "racc")
data/.bin/rake ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("rake", "rake")
data/.bin/rubocop ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("rubocop", "rubocop")
data/.bin/ruby-parse ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'ruby-parse' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("parser", "ruby-parse")
data/.bin/ruby-rewrite ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'ruby-rewrite' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("parser", "ruby-rewrite")
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.6
2
+ TargetRubyVersion: 3.2
3
3
 
4
4
  Style/StringLiterals:
5
5
  Enabled: true
@@ -11,3 +11,21 @@ Style/StringLiteralsInInterpolation:
11
11
 
12
12
  Layout/LineLength:
13
13
  Max: 120
14
+
15
+ Style/Documentation:
16
+ Enabled: false
17
+
18
+ Metrics/MethodLength:
19
+ Max: 30
20
+
21
+ Metrics/AbcSize:
22
+ Enabled: false
23
+
24
+ Metrics/ClassLength:
25
+ Enabled: false
26
+
27
+ Metrics/PerceivedComplexity:
28
+ Enabled: false
29
+
30
+ Metrics/CyclomaticComplexity:
31
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2024-06-21
4
+
5
+ - Experimental params coercion
6
+ - No documentation yet, but tests passing
7
+
3
8
  ## [0.1.0] - 2023-08-09
4
9
 
5
10
  - Initial release
data/Gemfile CHANGED
@@ -5,8 +5,10 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in attribeauty.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
8
+ gem "minitest"
9
+ gem "rake"
10
+ gem "rubocop"
9
11
 
10
- gem "minitest", "~> 5.0"
11
-
12
- gem "rubocop", "~> 1.21"
12
+ group :development, :test do
13
+ gem "zeitwerk"
14
+ end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attribeauty (0.1.0)
4
+ attribeauty (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -34,15 +34,18 @@ GEM
34
34
  parser (>= 3.2.1.0)
35
35
  ruby-progressbar (1.13.0)
36
36
  unicode-display_width (2.4.2)
37
+ zeitwerk (2.6.16)
37
38
 
38
39
  PLATFORMS
39
40
  x86_64-darwin-20
41
+ x86_64-darwin-22
40
42
 
41
43
  DEPENDENCIES
42
44
  attribeauty!
43
- minitest (~> 5.0)
44
- rake (~> 13.0)
45
- rubocop (~> 1.21)
45
+ minitest
46
+ rake
47
+ rubocop
48
+ zeitwerk
46
49
 
47
50
  BUNDLED WITH
48
- 2.4.10
51
+ 2.5.3
data/README.md CHANGED
@@ -62,7 +62,57 @@ instance.wild_animal # => "the_wildest_animals_are_koalas"
62
62
 
63
63
  ```
64
64
 
65
- Note, failing to call `inspect` on the value when casting is likely to raise an error.
65
+ To use rails types add to your config:
66
+ ```
67
+ # config/initializers/attribeauty.rb
68
+
69
+ Rails.application.reloader.to_prepare do
70
+ Attribeauty.configure do |config|
71
+ config.types[:string] = ActiveModel::Type::String
72
+ config.types[:boolean] = ActiveModel::Type::Boolean
73
+ config.types[:date] = ActiveModel::Type::Date
74
+ config.types[:time] = ActiveModel::Type::Time
75
+ config.types[:datetime] = ActiveModel::Type::DateTime
76
+ config.types[:float] = ActiveModel::Type::Float
77
+ config.types[:integer] = ActiveModel::Type::Integer
78
+ end
79
+ end
80
+
81
+ ```
82
+
83
+ ## Params
84
+
85
+ Experimental params sanitizer is now available. This will cast your params, and remove elements you want to exclude if `nil` or `empty`
86
+
87
+ ```
88
+ # app/controllers/my_controller.rb
89
+ class MyController
90
+ def update
91
+ MyRecord.update(update_params)
92
+
93
+ redirect_to index_path
94
+ end
95
+
96
+ private
97
+
98
+ def params_filter
99
+ Attribeauty::Params.with(request.params)
100
+ end
101
+
102
+ def update_params
103
+ params_filter.accept do
104
+ attribute :title, :string, allow_nil: false, required: true
105
+ attribute :email do
106
+ attribute :address, :string, allow_empty: false
107
+ attribute :valid, :boolean, allow_nil: false
108
+ attribute :ip_address, :string, allow_blank: true
109
+ end
110
+ end
111
+ end
112
+ ```
113
+
114
+ See `test/test_params.rb` for what is expected.
115
+
66
116
 
67
117
  ## Development
68
118
 
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module Attribeauty
6
+ class Params
7
+ extend Forwardable
8
+
9
+ def_delegators :to_h, :each_pair, :each, :empty?, :keys
10
+
11
+ def self.with(request_params)
12
+ new(request_params)
13
+ end
14
+
15
+ attr_reader :allow_nil, :prefix, :request_params, :acceptables, :to_h, :errors
16
+
17
+ def initialize(request_params)
18
+ @request_params = request_params.transform_keys(&:to_sym)
19
+ @to_h = {}
20
+ @errors = []
21
+ end
22
+
23
+ def accept(&)
24
+ instance_eval(&)
25
+
26
+ self
27
+ end
28
+
29
+ def to_hash = to_h
30
+
31
+ def [](key)
32
+ to_h[key]
33
+ end
34
+
35
+ # rubocop:disable Naming::BlockForwarding
36
+ def attribute(name, type = nil, **args, &block)
37
+ value = request_params[name]
38
+ return if value.nil? && args[:required].nil?
39
+
40
+ if block_given?
41
+ @to_h[name] =
42
+ if value.is_a?(Array)
43
+ value.map do |val|
44
+ params = self.class.with(val).accept(&block)
45
+ @errors.push(*params.errors)
46
+ params
47
+ end.reject(&:empty?)
48
+ else
49
+ params = self.class.with(value).accept(&block)
50
+ @errors.push(*params.errors)
51
+ params
52
+ end
53
+ else
54
+ validator = Validator.run(name, type, value, **args)
55
+ @to_h[name.to_sym] = validator.value if validator.valid?
56
+ @errors.push(*validator.errors)
57
+ end
58
+ end
59
+ # rubocop:enable Naming::BlockForwarding
60
+
61
+ def inspect
62
+ to_h.inspect
63
+ end
64
+
65
+ def valid?
66
+ errors.empty?
67
+ end
68
+ end
69
+ end
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "types/string"
4
- require_relative "types/integer"
5
- require_relative "types/float"
6
- require_relative "types/boolean"
7
- require_relative "types/time"
8
-
9
3
  module Attribeauty
10
4
  # base cast for types
11
5
  class TypeCaster
@@ -9,7 +9,7 @@ module Attribeauty
9
9
  "0", :"0",
10
10
  "f", :f,
11
11
  "F", :F,
12
- "false", :false,
12
+ "false", false,
13
13
  "FALSE", :FALSE,
14
14
  "off", :off,
15
15
  "OFF", :OFF
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module Attribeauty
6
+ class Validator
7
+ ALLOWS_HASH = {
8
+ allow_nil: :nil?,
9
+ allow_empty: :empty?
10
+ }.freeze
11
+
12
+ def self.run(name, type, original_value, **args)
13
+ new(name, type, original_value, **args).run
14
+ end
15
+
16
+ attr_reader :original_value, :errors, :name, :type, :required, :default, :predicate, :value
17
+
18
+ def initialize(name, type, original_value, **args)
19
+ @name = name
20
+ @type = type
21
+ @original_value = original_value
22
+ @errors = []
23
+ @default = args[:default]
24
+ @required = args[:required] if [true, false].include?(args[:required])
25
+ allows = args.slice(*allows_array)
26
+ return if allows.empty?
27
+
28
+ predicate_array = allows.first
29
+ predicate_array[0] = :"#{ALLOWS_HASH[predicate_array[0]]}"
30
+ @predicate = predicate_array
31
+ end
32
+
33
+ def run
34
+ @original_value = default if original_value.nil? && !default.nil?
35
+ @value = TypeCaster.run(original_value, type)
36
+
37
+ self
38
+ end
39
+
40
+ def valid?
41
+ if required? && original_value.nil?
42
+ errors << "#{name} required"
43
+ return false
44
+ end
45
+ return true if predicate.nil?
46
+
47
+ method, bool = predicate
48
+ return true if bool
49
+
50
+ !value.public_send(method)
51
+ end
52
+
53
+ private
54
+
55
+ def set_args; end
56
+
57
+ def allows_array
58
+ ALLOWS_HASH.keys
59
+ end
60
+
61
+ def required?
62
+ required
63
+ end
64
+ end
65
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Attribeauty
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/attribeauty.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "attribeauty/version"
4
- require_relative "attribeauty/base"
5
- require_relative "attribeauty/type_caster"
6
- require_relative "attribeauty/configuration"
7
3
  require "date"
8
4
  require "time"
9
5
 
@@ -21,3 +17,10 @@ module Attribeauty
21
17
  end
22
18
  end
23
19
  end
20
+
21
+ require "zeitwerk"
22
+
23
+ loader = Zeitwerk::Loader.for_gem
24
+ loader.ignore("#{__dir__}/kamal/sshkit_with_ext.rb")
25
+ loader.setup
26
+ loader.eager_load # We need all commands loaded.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribeauty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toby
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-10 00:00:00.000000000 Z
11
+ date: 2024-06-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: There are so many of these, I just needed this one.
14
14
  email:
@@ -17,6 +17,12 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - ".bin/bundle"
21
+ - ".bin/racc"
22
+ - ".bin/rake"
23
+ - ".bin/rubocop"
24
+ - ".bin/ruby-parse"
25
+ - ".bin/ruby-rewrite"
20
26
  - ".rubocop.yml"
21
27
  - CHANGELOG.md
22
28
  - Gemfile
@@ -27,14 +33,15 @@ files:
27
33
  - lib/attribeauty.rb
28
34
  - lib/attribeauty/base.rb
29
35
  - lib/attribeauty/configuration.rb
36
+ - lib/attribeauty/params.rb
30
37
  - lib/attribeauty/type_caster.rb
31
38
  - lib/attribeauty/types/boolean.rb
32
39
  - lib/attribeauty/types/float.rb
33
40
  - lib/attribeauty/types/integer.rb
34
41
  - lib/attribeauty/types/string.rb
35
42
  - lib/attribeauty/types/time.rb
43
+ - lib/attribeauty/validator.rb
36
44
  - lib/attribeauty/version.rb
37
- - sig/attribeauty.rbs
38
45
  homepage: https://github.com/tobyond/attribeauty
39
46
  licenses:
40
47
  - MIT
@@ -49,14 +56,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
49
56
  requirements:
50
57
  - - ">="
51
58
  - !ruby/object:Gem::Version
52
- version: 2.6.0
59
+ version: 3.2.0
53
60
  required_rubygems_version: !ruby/object:Gem::Requirement
54
61
  requirements:
55
62
  - - ">="
56
63
  - !ruby/object:Gem::Version
57
64
  version: '0'
58
65
  requirements: []
59
- rubygems_version: 3.4.10
66
+ rubygems_version: 3.5.3
60
67
  signing_key:
61
68
  specification_version: 4
62
69
  summary: Attributes simply done
data/sig/attribeauty.rbs DELETED
@@ -1,4 +0,0 @@
1
- module Attribeauty
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end