attribeauty 0.2.0 → 0.3.0

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