act_form 0.4.4 → 0.5.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: d93ee18c0209358b5bfdd5f8bab5c31b9065ed223a901de2b5a45db192c7eb7a
4
- data.tar.gz: 6db591154d02ccb5407ee4cb615de83ef1337891cd8dda2f611c7bb6fe4b8522
3
+ metadata.gz: cab0f4f82ad6b6e33c6375695d4a74b54e26e3039583e2b1949ff6690de56832
4
+ data.tar.gz: b6f3dcdabe79a4a0777cae6e38ea4ce4d7c969eae81c3404abc3739f9c7c5026
5
5
  SHA512:
6
- metadata.gz: 5baa5bcdd152bbc018e1d9faa6df224290af67c98064297636e3fedc69b38c626dd0a442076a32ccac199a88915a7a4725ed076c97af8fce7a16f48565b1b78e
7
- data.tar.gz: dccf8fa34e9e10965207b87227ba687926732c27086f59bbe0e5e82bd2d056521ef6399fd7558457a2b3cb9ad8b36cf72dd3489d667ac5ee90dd68634dd7daa9
6
+ metadata.gz: f4746eb8bc9a2483114fce51de1f71d69c68a7cade4c0508cc8506126f73efb6a77703f3f242730ed5027f160dd13cf03b48d986958d9b7b7a0d427fd00da344
7
+ data.tar.gz: 4434f45ef372a6bfaca7e9627aabff63c1054e78d69bc9b694a37fdc255b62715aa50d5ea12e897615b994d0c12e7ce5d4268264ab096d25db5897a0aec8724e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,44 @@
1
+ # 0.5.0
2
+ * [Feature] issue#7 add more attribute type
3
+ * [Feature] issue#3 add `combine` DEPRECATION
4
+
5
+ With the power of `dry-schema`, ActForm now can support all the features of `dry-schema`, like:
6
+
7
+ ```ruby
8
+ class UserForm < ActForm::Base
9
+ params do
10
+ required(:name).filled.desc('Name')
11
+ optional(:age).value(:integer).desc('Age')
12
+ optional(:address).desc('Address')
13
+ optional(:nickname).default('nick').desc('Nick')
14
+ # below will support in the future
15
+ # attribute :desc, default: ->{ 'desc' }
16
+ end
17
+ end
18
+ ```
19
+
20
+ Add we can integrate with `grape` easyly.
21
+
22
+ ```ruby
23
+ module WorkWithGrapeSpec
24
+ class API < Grape::API
25
+ format :json
26
+
27
+ contract UserForm.contract
28
+ get '/foo' do
29
+ 'hello world'
30
+ end
31
+
32
+ contract FooService.contract do
33
+ required(:desc).filled
34
+ end
35
+ get '/bar' do
36
+ 'hello world'
37
+ end
38
+ end
39
+ end
40
+ ```
41
+
1
42
  # 0.4.4
2
43
  * [Fix] fix `setup` run before `required` validation
3
44
 
data/Gemfile CHANGED
@@ -4,5 +4,7 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :development, :test do
7
+ gem 'grape', '>= 1.8.0'
7
8
  gem 'pry'
9
+ gem 'rack-test', '~> 2.1'
8
10
  end
data/README.md CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  ActForm is the gem that provide a simple way to create `form object` or `command object` or `service object`, it only depends on `activemodel >= 5` and provides few api.
4
4
 
5
+ ## About v0.5.0
6
+
7
+ With the power of `dry-schema`, ActForm now can support all the features of `dry-schema`, like:
8
+
9
+ ```ruby
10
+ class UserForm < ActForm::Base
11
+ params do
12
+ required(:name).filled.desc('Name')
13
+ optional(:age).value(:integer).desc('Age')
14
+ optional(:address).desc('Address')
15
+ optional(:nickname).default('nick').desc('Nick')
16
+ # below will support in the future
17
+ # attribute :desc, default: ->{ 'desc' }
18
+ end
19
+ end
20
+ ```
21
+
22
+ Add we can integrate with `grape` easyly.
23
+
24
+ ```ruby
25
+ module WorkWithGrapeSpec
26
+ class API < Grape::API
27
+ format :json
28
+
29
+ contract UserForm.contract
30
+ get '/foo' do
31
+ 'hello world'
32
+ end
33
+
34
+ contract UserForm.contract do
35
+ required(:desc).filled
36
+ end
37
+ get '/bar' do
38
+ 'hello world'
39
+ end
40
+ end
41
+ end
42
+ ```
43
+
5
44
  ## Usage
6
45
 
7
46
  #### API - `attribute`
@@ -191,14 +230,17 @@ Or install it yourself as:
191
230
 
192
231
  $ gem install act_form
193
232
 
194
-
195
233
  ## Development
196
234
 
197
235
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
198
236
 
237
+ ### Unit Tests
238
+
239
+ $ bundle exec rake test
240
+
199
241
  ## Contributing
200
242
 
201
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/act_form. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
243
+ Bug reports and pull requests are welcome on GitHub at https://github.com/simple-and-powerful/act_form. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
202
244
 
203
245
 
204
246
  ## License
data/act_form.gemspec CHANGED
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'act_form/version'
5
4
 
@@ -9,8 +8,8 @@ Gem::Specification.new do |spec|
9
8
  spec.authors = ['zires']
10
9
  spec.email = ['zshuaibin@gmail.com']
11
10
 
12
- spec.summary = %q{A simple way to create form/command/service objects.}
13
- spec.description = %q{The simple way to create form objects or command/service objects with ActiveModel.}
11
+ spec.summary = 'A simple way to create form/command/service objects.'
12
+ spec.description = 'The simple way to create form objects or command/service objects with ActiveModel.'
14
13
  spec.homepage = 'https://github.com/simple-and-powerful/act-form'
15
14
  spec.license = 'MIT'
16
15
 
@@ -27,6 +26,7 @@ Gem::Specification.new do |spec|
27
26
  spec.require_paths = ['lib']
28
27
 
29
28
  spec.add_runtime_dependency 'activemodel', '>= 5.0.0'
29
+ spec.add_runtime_dependency 'dry-schema', '>= 1.13.4'
30
30
 
31
31
  spec.add_development_dependency 'bundler', '~> 2.1'
32
32
  spec.add_development_dependency 'rake', '~> 13.0'
@@ -34,7 +34,9 @@ module ActForm
34
34
  end
35
35
 
36
36
  class_methods do
37
+ # <b>DEPRECATED:</b> Please use <tt>ruby pure module</tt> instead.
37
38
  def combine(*forms)
39
+ warn '[DEPRECATION] `combine` is deprecated and will be removed in future versions. Instead, please use a pure Ruby module approach. For more details, refer to [link to migration guide].' # rubocop:disable Layout/LineLength
38
40
  forms.each do |form_class|
39
41
  raise ArgumentError, "can't combine itself" if form_class == self
40
42
 
@@ -0,0 +1,5 @@
1
+ zh-CN:
2
+ errors:
3
+ messages:
4
+ required: "是一个必填项"
5
+
@@ -8,7 +8,7 @@ module ActForm
8
8
  def merge_attribute_set_from(other)
9
9
  other.attribute_set.each do |attr_name, arr|
10
10
  cast_type, options = arr
11
- attribute attr_name, cast_type, options
11
+ attribute attr_name, cast_type, **options
12
12
  end
13
13
  end
14
14
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'active_model'
4
4
  require 'act_form/attributes'
5
+ require 'act_form/schema'
5
6
  require 'act_form/merge'
6
7
  require 'act_form/combinable'
7
8
 
@@ -11,10 +12,12 @@ module ActForm
11
12
  include ActiveModel::Model
12
13
  include ActiveModel::Validations::Callbacks
13
14
  include Attributes
15
+ include Schema
14
16
  include Merge
15
17
 
16
18
  included do
17
19
  set_callback :validation, :before, :validate_required_attributes
20
+ set_callback :validation, :before, :validate_contract
18
21
  end
19
22
 
20
23
  def initialize(attrs = {})
@@ -71,6 +74,17 @@ module ActForm
71
74
  throw(:abort) unless errors.empty?
72
75
  end
73
76
 
77
+ def validate_contract
78
+ return if self.class._schema.nil?
79
+
80
+ result = self.class._schema.validate(self.attributes)
81
+ return if result.success?
82
+
83
+ result.errors(full: true).each do |err|
84
+ errors.add(err.path.first, :invalid, message: err.text)
85
+ end
86
+ end
87
+
74
88
  class_methods do
75
89
  def inherited(child_class)
76
90
  child_class.include Combinable
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActForm
4
+ module Schema
5
+ class Base # rubocop:disable Style/Documentation
6
+ attr_reader :ins
7
+
8
+ def initialize(*parents, &block)
9
+ parent_arr = parents.map(&:contract)
10
+ @ins = ::Dry::Schema.Params(parent: parent_arr, &block)
11
+ @json = @ins.json_schema(loose: true)
12
+ @defaults = @ins.schema_dsl.defaults
13
+ @descriptions = @ins.schema_dsl.descriptions
14
+ end
15
+
16
+ def each # rubocop:disable Metrics/AbcSize
17
+ @ins.key_map.each do |key|
18
+ name = key.name.to_sym
19
+ opts = {
20
+ required: @json[:required].include?(key.name)
21
+ }
22
+ opts[:default] = @defaults[name] if @defaults.key?(name)
23
+ t = @json[:properties].dig(name, :type)
24
+ t = if t.is_a?(Array)
25
+ :object
26
+ else
27
+ t ? t.to_sym : :object
28
+ end
29
+ opts[:type] = t
30
+ yield name, opts
31
+ end
32
+ end
33
+
34
+ def validate(attrs)
35
+ _attrs = {}.merge!(attrs)
36
+ _attrs.merge!(@defaults)
37
+ @ins.call(_attrs)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActForm
4
+ module Schema
5
+ module Extensions
6
+ # Add defaults and descriptions to schema_dsl
7
+ module DSLExtension
8
+ def defaults
9
+ @_defaults ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
10
+ end
11
+
12
+ def descriptions
13
+ @_descriptions ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
14
+ end
15
+ end
16
+
17
+ # Add default and desc macros
18
+ module MacrosExtension
19
+ def default(value)
20
+ schema_dsl.defaults[name] = value
21
+ self
22
+ end
23
+
24
+ def desc(value)
25
+ schema_dsl.descriptions[name] = value
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActForm
4
+ module Schema # rubocop:disable Style/Documentation
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :_schema, instance_accessor: false
9
+ self._schema = nil
10
+ end
11
+
12
+ module ClassMethods # rubocop:disable Style/Documentation
13
+ def contract
14
+ self._schema.ins
15
+ end
16
+
17
+ def params(*parents, &block)
18
+ self._schema = Base.new(*parents, &block)
19
+ self._schema.each { |k, opts| self.attribute(k, **opts) }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActForm
4
- VERSION = '0.4.4'
4
+ VERSION = '0.5.0'
5
5
  end
data/lib/act_form.rb CHANGED
@@ -4,6 +4,14 @@ require 'act_form/version'
4
4
  require 'act_form/model'
5
5
  require 'act_form/runnable'
6
6
 
7
+ require 'dry/schema'
8
+ Dry::Schema.load_extensions(:json_schema)
9
+
10
+ require 'act_form/schema/base'
11
+ require 'act_form/schema/extensions'
12
+ ::Dry::Schema::DSL.include(::ActForm::Schema::Extensions::DSLExtension)
13
+ ::Dry::Schema::Macros::DSL.include(::ActForm::Schema::Extensions::MacrosExtension)
14
+
7
15
  module ActForm
8
16
  class Base
9
17
  include Model
@@ -17,3 +25,4 @@ module ActForm
17
25
  end
18
26
 
19
27
  I18n.load_path << "#{File.dirname(__FILE__)}/act_form/locale/en.yml"
28
+ I18n.load_path << "#{File.dirname(__FILE__)}/act_form/locale/zh-CN.yml"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: act_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zires
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-02 00:00:00.000000000 Z
11
+ date: 2024-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-schema
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.13.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.13.4
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -73,16 +87,20 @@ files:
73
87
  - lib/act_form/attributes.rb
74
88
  - lib/act_form/combinable.rb
75
89
  - lib/act_form/locale/en.yml
90
+ - lib/act_form/locale/zh-CN.yml
76
91
  - lib/act_form/merge.rb
77
92
  - lib/act_form/model.rb
78
93
  - lib/act_form/runnable.rb
94
+ - lib/act_form/schema.rb
95
+ - lib/act_form/schema/base.rb
96
+ - lib/act_form/schema/extensions.rb
79
97
  - lib/act_form/type.rb
80
98
  - lib/act_form/version.rb
81
99
  homepage: https://github.com/simple-and-powerful/act-form
82
100
  licenses:
83
101
  - MIT
84
102
  metadata: {}
85
- post_install_message:
103
+ post_install_message:
86
104
  rdoc_options: []
87
105
  require_paths:
88
106
  - lib
@@ -97,8 +115,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
115
  - !ruby/object:Gem::Version
98
116
  version: '0'
99
117
  requirements: []
100
- rubygems_version: 3.0.3
101
- signing_key:
118
+ rubygems_version: 3.5.1
119
+ signing_key:
102
120
  specification_version: 4
103
121
  summary: A simple way to create form/command/service objects.
104
122
  test_files: []