gate 0.10.0 → 1.0.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: 64401d6617c7ebcde128f5e283695475effec0be39a3089ed1a04cc9dd769ec3
4
- data.tar.gz: 4f6192608d2110d1053d2cf1ab0b9afe1973cb65dc60bd556ac37d0d26defce7
3
+ metadata.gz: 3a060433f1f524041e43b2018c267f09296f33c9d62f9ca13fd2ca13d171f09d
4
+ data.tar.gz: e63df883e61a45ea42436cca24e53a750bfda2bea13a74351d55b005d251119a
5
5
  SHA512:
6
- metadata.gz: 76c705ee8b4c09b172b73433487376781683fb1b6619168ad1972557046f2e6f4d831e776ffd91746f4b9b17a2f36a7b6831768453208a61857076602f991b8d
7
- data.tar.gz: 0bf7be2a899cf05f60eeaea97703944ed563f4f7e5dd46565e77858455d65832ed21a11f50dd8b774ca56df8d3db3ae722e9554df47bd3d097349134c68c32a9
6
+ metadata.gz: b891269e835a23d6255fd3fd1fb6a5eceb7f65b933816e48832581fd306d52f6344dac5ff1dfb5da06e2be1e8901d6940d76889937d5174cc68628050bdfcc36
7
+ data.tar.gz: dcafe4902a3471e0eb0d40d14f74abc28775cddb67bbb6a6658c6f53cb9f9ab35029316f5ec29d1efd98e417a4af231160b7d63c94b2f937fc739b12b8849406
@@ -7,10 +7,6 @@ build_steps: &build_steps
7
7
 
8
8
  version: 2
9
9
  jobs:
10
- test_ruby-2.3:
11
- <<: *build_steps
12
- docker:
13
- - image: circleci/ruby:2.3
14
10
  test_ruby-2.4:
15
11
  <<: *build_steps
16
12
  docker:
@@ -19,9 +15,13 @@ jobs:
19
15
  <<: *build_steps
20
16
  docker:
21
17
  - image: circleci/ruby:2.5
18
+ test_ruby-2.6:
19
+ <<: *build_steps
20
+ docker:
21
+ - image: circleci/ruby:2.6
22
22
  release:
23
23
  docker:
24
- - image: circleci/ruby:2.5
24
+ - image: circleci/ruby:2.6
25
25
  steps:
26
26
  - checkout
27
27
  - run:
@@ -39,23 +39,23 @@ workflows:
39
39
  version: 2
40
40
  test_and_release:
41
41
  jobs:
42
- - test_ruby-2.3:
42
+ - test_ruby-2.4:
43
43
  filters:
44
44
  tags:
45
45
  only: /.*/
46
- - test_ruby-2.4:
46
+ - test_ruby-2.5:
47
47
  filters:
48
48
  tags:
49
49
  only: /.*/
50
- - test_ruby-2.5:
50
+ - test_ruby-2.6:
51
51
  filters:
52
52
  tags:
53
53
  only: /.*/
54
54
  - release:
55
55
  requires:
56
- - test_ruby-2.3
57
56
  - test_ruby-2.4
58
57
  - test_ruby-2.5
58
+ - test_ruby-2.6
59
59
  filters:
60
60
  tags:
61
61
  only: /^v.*/
data/README.md CHANGED
@@ -2,13 +2,10 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/gate.svg)](http://badge.fury.io/rb/gate)
4
4
  [![Circle CI](https://circleci.com/gh/monterail/gate.svg?style=shield)](https://circleci.com/gh/monterail/gate)
5
- [![Dependency Status](https://gemnasium.com/monterail/gate.svg)](https://gemnasium.com/monterail/gate)
6
5
  [![Code Climate](https://codeclimate.com/github/monterail/gate/badges/gpa.svg)](https://codeclimate.com/github/monterail/gate)
7
6
  [![Test Coverage](https://codeclimate.com/github/monterail/gate/badges/coverage.svg)](https://codeclimate.com/github/monterail/gate/coverage)
8
7
 
9
- Gate is a small wrapper on [dry-validation](http://dry-rb.org/gems/dry-validation/) that might be used as Command in CQRS pattern or replace [Strong Params](http://api.rubyonrails.org/classes/ActionController/Parameters.html) in [Ruby on Rails](https://rubyonrails.org/) applications.
10
-
11
- `Gate::Command` will raise `InvalidCommand` error for invalid input and provide simple struct with access to coerced input.
8
+ **Gate** is a small wrapper on [dry-validation](http://dry-rb.org/gems/dry-validation/) that integrates it with [Ruby on Rails](https://rubyonrails.org/) and replaces [Strong Params](http://api.rubyonrails.org/classes/ActionController/Parameters.html).
12
9
 
13
10
  ## Installation
14
11
 
@@ -26,61 +23,33 @@ Or install it yourself as:
26
23
 
27
24
  $ gem install gate
28
25
 
29
- ## Command Usage
26
+ ## Usage
30
27
 
31
- Define structure
32
-
33
- ```ruby
34
- class DoSomethingCommand
35
- include Gate::Command
36
-
37
- schema do
38
- required(:id).filled
39
- required(:message).schema do
40
- required(:title).filled
41
- optional(:value).maybe(:decimal?)
42
- end
43
- end
44
- end
45
- ```
46
-
47
- Use it
48
-
49
- ```ruby
50
- begin
51
- cmd = DoSomethingCommand.with(params)
52
- cmd.id
53
- cmd.message
54
- rescue DoSomethingCommand::InvalidCommand => e
55
- e.errors # => hash { key => [errors] }
56
- end
57
- ```
58
-
59
- ## Rails Usage
60
-
61
- Define schemas per action
28
+ Define [contract](https://dry-rb.org/gems/dry-validation) per action with controller DSL...
62
29
 
63
30
  ```ruby
64
31
  class ExampleController < ActionController::Base
65
32
  include Gate::Rails
66
33
 
67
- before_action :validate_params, if: { |c| c.params_schema_registered? }
34
+ before_action :verify_contract, if: { |c| c.contract_registered? }
68
35
 
69
- # Define schema just before action method
70
- def_schema do
71
- required(:id).filled
72
- required(:message).schema do
73
- required(:title).filled
74
- optional(:value).maybe(:decimal?)
36
+ # Define contract just before action method
37
+ contract(handler: :handle_invalid_params) do
38
+ params do
39
+ required(:id).filled
40
+ required(:message).hash do
41
+ required(:title).filled
42
+ optional(:value).maybe(:decimal?)
43
+ end
75
44
  end
76
45
  end
77
46
 
78
47
  def foo
79
48
  # you can access Dry::Validation result with:
80
- validated_params
49
+ claimed_params
81
50
  end
82
51
 
83
- # default handler for invalid params which you can override
52
+ # handler for invalid params
84
53
  def handle_invalid_params(_errors)
85
54
  # errors is Dry::Validation messages hash
86
55
 
@@ -89,50 +58,43 @@ class ExampleController < ActionController::Base
89
58
  end
90
59
  ```
91
60
 
92
- ## Configuration
93
-
94
- Gate gives a possibility to create global, inherited configuration and separated setup in each one schema definition.
95
-
96
- ### Inheriting base setup
97
-
98
- In order to configure the library according to the whole application, create a file under `config/initializers/gate.rb`. There is a possibility of creating a base configuration, defining shared, custom predicates and a lot more useful things. The full list of supported configuration options is consistent with available options in [dry-validation](https://dry-rb.org/gems/dry-validation/) gem.
61
+ ... or as a separate class:
99
62
 
100
63
  ```ruby
101
- Gate::Rails.configure do
102
- configure do |config|
103
- config.messages_file = Rails.root.join("config", "locales" "en.yml")
104
-
105
- predicates(SharedPredicates)
106
-
107
- def foo?(value)
108
- value == "FOO"
64
+ class ExampleFooContract < Dry::Validation::Contract
65
+ params do
66
+ required(:id).filled
67
+ required(:message).hash do
68
+ required(:title).filled
69
+ optional(:value).maybe(:decimal?)
109
70
  end
110
71
  end
111
72
  end
112
- ```
113
73
 
114
- ### Separated setup
74
+ class ExampleController < ActionController::Base
75
+ include Gate::Rails
115
76
 
116
- Sometimes there is a requirement to have a very specific configuration or behaviour in a one schema validation. The easiest way is to do it in a special `configure` block.
77
+ before_action :verify_contract, if: { |c| c.contract_registered? }
117
78
 
118
- ```ruby
119
- class DoSomethingCommand
120
- include Gate::Command
79
+ contract(ExampleFooContract)
80
+ def foo
81
+ # you can access Dry::Validation result with:
82
+ claimed_params
83
+ end
121
84
 
122
- schema do
123
- configure do
124
- config.messages_file = Rails.root.join("config", "locales" "special_en.yml")
125
- predicates(SharedPredicates)
126
- end
127
- required(:id).filled
128
- required(:message).schema do
129
- required(:title).filled
130
- optional(:value).maybe(:decimal?)
131
- end
85
+ # just use default handler
86
+ def handle_invalid_params(_errors)
87
+ # errors is Dry::Validation messages hash
88
+
89
+ head :bad_request
132
90
  end
133
91
  end
134
92
  ```
135
93
 
94
+ ## Configuration
95
+
96
+ *TODO*
97
+
136
98
  ## Development
137
99
 
138
100
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ["Jan Dudulski"]
11
11
  spec.email = ["jan@dudulski.pl"]
12
12
 
13
- spec.summary = "CQRS Command"
13
+ spec.summary = "Strong params replacement"
14
14
  spec.description = "Validate and coerce user input against defined structure."
15
15
  spec.homepage = "https://github.com/monterail/gate"
16
16
  spec.license = "MIT"
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
22
22
 
23
- spec.add_runtime_dependency "dry-validation", "~> 0.12"
23
+ spec.add_runtime_dependency "dry-validation", "~> 1.0"
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.16"
26
26
  spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "pry", "~> 0.11"
29
29
  spec.add_development_dependency "rails", "~> 5.2"
30
30
  spec.add_development_dependency "rake", "~> 12.0"
31
+ spec.add_development_dependency "standardrb", ">= 1.0"
31
32
  end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gate
4
- InvalidCommand = Class.new(StandardError)
5
4
  end
6
5
 
7
6
  require "dry-validation"
8
7
 
9
- require "gate/command"
10
8
  require "gate/rails"
11
9
  require "gate/version"
@@ -2,49 +2,55 @@
2
2
 
3
3
  module Gate
4
4
  module Rails
5
- attr_reader :validated_params
5
+ attr_reader :claimed_params
6
6
 
7
- SchemaNotDefined = Class.new(StandardError)
8
- @base_schema = nil
7
+ ContractNotDefined = Class.new(StandardError)
9
8
 
10
9
  def self.included(base)
11
10
  base.send(:extend, ClassMethods)
12
11
  end
13
12
 
14
- def self.configure(&block)
15
- @base_schema = Class.new(Dry::Validation::Schema, &block)
16
- end
17
-
18
13
  module ClassMethods
19
- def params_schemas
20
- @params_schemas ||= {}
14
+ def _contracts
15
+ @_contracts ||= {}
21
16
  end
22
17
 
23
- def fetch_params_schema(schema_name)
24
- params_schemas.fetch(schema_name) do
25
- raise SchemaNotDefined, "Missing `#{schema_name}` schema"
26
- end
18
+ def contract_for(contract_name)
19
+ _contracts.fetch(contract_name) do
20
+ raise ContractNotDefined, "Missing `#{contract_name}` contract"
21
+ end.fetch(:contract)
22
+ end
23
+
24
+ def handler_for(contract_name)
25
+ _contracts.fetch(contract_name) do
26
+ raise ContractNotDefined, "Missing `#{contract_name}` contract"
27
+ end.fetch(:handler)
27
28
  end
28
29
 
29
- def def_schema(&block)
30
- @_schema = Dry::Validation.Params(Gate::Rails::instance_variable_get(:@base_schema), &block)
30
+ def contract(klass = nil, handler: :handle_invalid_params, &block)
31
+ @_contract = {
32
+ contract: klass ? klass.new : Dry::Validation.Contract(&block),
33
+ handler: handler,
34
+ }
31
35
  end
32
36
 
33
37
  def method_added(method_name)
34
- return unless instance_variable_defined?(:@_schema)
38
+ if instance_variable_defined?(:@_contract)
39
+ _contracts[method_name] = @_contract
40
+ remove_instance_variable(:@_contract)
41
+ end
35
42
 
36
- params_schemas[method_name] = @_schema
37
- remove_instance_variable(:@_schema)
43
+ super
38
44
  end
39
45
  end
40
46
 
41
- def validate_params
42
- result = params_schema.call(request.params)
47
+ def verify_contract
48
+ result = self.class.contract_for(_contract_name).call(request.params)
43
49
 
44
50
  if result.success?
45
- @validated_params = result.output
51
+ @claimed_params = result.to_h
46
52
  else
47
- handle_invalid_params(result.messages)
53
+ send(self.class.handler_for(_contract_name), result.errors.to_h)
48
54
  end
49
55
  end
50
56
 
@@ -52,15 +58,11 @@ module Gate
52
58
  head :bad_request
53
59
  end
54
60
 
55
- def params_schema_registered?
56
- self.class.params_schemas.key?(params_schema_name)
57
- end
58
-
59
- def params_schema
60
- self.class.fetch_params_schema(params_schema_name)
61
+ def contract_registered?
62
+ self.class._contracts.key?(_contract_name)
61
63
  end
62
64
 
63
- def params_schema_name
65
+ def _contract_name
64
66
  action_name.to_sym
65
67
  end
66
68
  end
@@ -1,3 +1,3 @@
1
1
  module Gate
2
- VERSION = "0.10.0"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Dudulski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-10 00:00:00.000000000 Z
11
+ date: 2019-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-validation
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.12'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.12'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '12.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: standardrb
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '1.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '1.0'
111
125
  description: Validate and coerce user input against defined structure.
112
126
  email:
113
127
  - jan@dudulski.pl
@@ -119,7 +133,6 @@ files:
119
133
  - ".circleci/gem_credentials"
120
134
  - ".codeclimate.yml"
121
135
  - ".gitignore"
122
- - ".rubocop.yml"
123
136
  - ".travis.yml"
124
137
  - Gemfile
125
138
  - LICENSE.txt
@@ -129,7 +142,6 @@ files:
129
142
  - bin/setup
130
143
  - gate.gemspec
131
144
  - lib/gate.rb
132
- - lib/gate/command.rb
133
145
  - lib/gate/rails.rb
134
146
  - lib/gate/version.rb
135
147
  homepage: https://github.com/monterail/gate
@@ -152,9 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
164
  - !ruby/object:Gem::Version
153
165
  version: '0'
154
166
  requirements: []
155
- rubyforge_project:
156
- rubygems_version: 2.7.7
167
+ rubygems_version: 3.0.3
157
168
  signing_key:
158
169
  specification_version: 4
159
- summary: CQRS Command
170
+ summary: Strong params replacement
160
171
  test_files: []
@@ -1,19 +0,0 @@
1
- Style/Documentation:
2
- Description: Document classes and non-namespace modules.
3
- Enabled: false
4
- Style/StringLiterals:
5
- Description: Checks if uses of quotes match the configured preference.
6
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
7
- Enabled: true
8
- EnforcedStyle: double_quotes
9
- SupportedStyles:
10
- - single_quotes
11
- - double_quotes
12
- Style/StringLiteralsInInterpolation:
13
- Description: Checks if uses of quotes inside expressions in interpolated strings
14
- match the configured preference.
15
- Enabled: true
16
- EnforcedStyle: single_quotes
17
- SupportedStyles:
18
- - single_quotes
19
- - double_quotes
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "forwardable"
4
-
5
- module Gate
6
- module Command
7
- extend Forwardable
8
-
9
- def_delegator :result, :to_h
10
-
11
- SchemaAlreadyRegistered = Class.new(StandardError)
12
- SchemaNotDefined = Class.new(StandardError)
13
-
14
- attr_reader :result
15
-
16
- class InvalidCommand < StandardError
17
- attr_reader :errors
18
-
19
- def initialize(errors)
20
- @errors = errors
21
- super("Invalid command")
22
- end
23
-
24
- def full_message
25
- errors.values.join(", ")
26
- end
27
- end
28
-
29
- def self.included(base)
30
- base.send(:extend, ClassMethods)
31
- end
32
-
33
- def initialize(data)
34
- @result = data
35
- end
36
-
37
- module ClassMethods
38
- # rubocop:disable Metrics/MethodLength
39
- def schema(&block)
40
- if block_given?
41
- raise SchemaAlreadyRegistered if instance_variable_defined?(:@schema)
42
- @schema = Dry::Validation.Params(&block)
43
- @schema.rules.keys.each do |name|
44
- define_method(name) do
45
- result[name]
46
- end
47
- end
48
- else
49
- raise SchemaNotDefined unless @schema
50
- @schema
51
- end
52
- end
53
- # rubocop:enable Metrics/MethodLength
54
-
55
- def with(input)
56
- result = schema.call(input)
57
- raise InvalidCommand, result.messages(full: true) if result.failure?
58
- new result.output
59
- end
60
- end
61
- end
62
- end