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 +4 -4
- data/.circleci/config.yml +9 -9
- data/README.md +38 -76
- data/gate.gemspec +3 -2
- data/lib/gate.rb +0 -2
- data/lib/gate/rails.rb +31 -29
- data/lib/gate/version.rb +1 -1
- metadata +20 -9
- data/.rubocop.yml +0 -19
- data/lib/gate/command.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a060433f1f524041e43b2018c267f09296f33c9d62f9ca13fd2ca13d171f09d
|
4
|
+
data.tar.gz: e63df883e61a45ea42436cca24e53a750bfda2bea13a74351d55b005d251119a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b891269e835a23d6255fd3fd1fb6a5eceb7f65b933816e48832581fd306d52f6344dac5ff1dfb5da06e2be1e8901d6940d76889937d5174cc68628050bdfcc36
|
7
|
+
data.tar.gz: dcafe4902a3471e0eb0d40d14f74abc28775cddb67bbb6a6658c6f53cb9f9ab35029316f5ec29d1efd98e417a4af231160b7d63c94b2f937fc739b12b8849406
|
data/.circleci/config.yml
CHANGED
@@ -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.
|
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.
|
42
|
+
- test_ruby-2.4:
|
43
43
|
filters:
|
44
44
|
tags:
|
45
45
|
only: /.*/
|
46
|
-
- test_ruby-2.
|
46
|
+
- test_ruby-2.5:
|
47
47
|
filters:
|
48
48
|
tags:
|
49
49
|
only: /.*/
|
50
|
-
- test_ruby-2.
|
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
|
[](http://badge.fury.io/rb/gate)
|
4
4
|
[](https://circleci.com/gh/monterail/gate)
|
5
|
-
[](https://gemnasium.com/monterail/gate)
|
6
5
|
[](https://codeclimate.com/github/monterail/gate)
|
7
6
|
[](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
|
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
|
-
##
|
26
|
+
## Usage
|
30
27
|
|
31
|
-
Define
|
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 :
|
34
|
+
before_action :verify_contract, if: { |c| c.contract_registered? }
|
68
35
|
|
69
|
-
# Define
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
required(:
|
74
|
-
|
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
|
-
|
49
|
+
claimed_params
|
81
50
|
end
|
82
51
|
|
83
|
-
#
|
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
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
74
|
+
class ExampleController < ActionController::Base
|
75
|
+
include Gate::Rails
|
115
76
|
|
116
|
-
|
77
|
+
before_action :verify_contract, if: { |c| c.contract_registered? }
|
117
78
|
|
118
|
-
|
119
|
-
|
120
|
-
|
79
|
+
contract(ExampleFooContract)
|
80
|
+
def foo
|
81
|
+
# you can access Dry::Validation result with:
|
82
|
+
claimed_params
|
83
|
+
end
|
121
84
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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.
|
data/gate.gemspec
CHANGED
@@ -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 = "
|
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
|
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
|
data/lib/gate.rb
CHANGED
data/lib/gate/rails.rb
CHANGED
@@ -2,49 +2,55 @@
|
|
2
2
|
|
3
3
|
module Gate
|
4
4
|
module Rails
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :claimed_params
|
6
6
|
|
7
|
-
|
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
|
20
|
-
@
|
14
|
+
def _contracts
|
15
|
+
@_contracts ||= {}
|
21
16
|
end
|
22
17
|
|
23
|
-
def
|
24
|
-
|
25
|
-
raise
|
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
|
30
|
-
@
|
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
|
-
|
38
|
+
if instance_variable_defined?(:@_contract)
|
39
|
+
_contracts[method_name] = @_contract
|
40
|
+
remove_instance_variable(:@_contract)
|
41
|
+
end
|
35
42
|
|
36
|
-
|
37
|
-
remove_instance_variable(:@_schema)
|
43
|
+
super
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
41
|
-
def
|
42
|
-
result =
|
47
|
+
def verify_contract
|
48
|
+
result = self.class.contract_for(_contract_name).call(request.params)
|
43
49
|
|
44
50
|
if result.success?
|
45
|
-
@
|
51
|
+
@claimed_params = result.to_h
|
46
52
|
else
|
47
|
-
|
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
|
56
|
-
self.class.
|
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
|
65
|
+
def _contract_name
|
64
66
|
action_name.to_sym
|
65
67
|
end
|
66
68
|
end
|
data/lib/gate/version.rb
CHANGED
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.
|
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:
|
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
|
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
|
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
|
-
|
156
|
-
rubygems_version: 2.7.7
|
167
|
+
rubygems_version: 3.0.3
|
157
168
|
signing_key:
|
158
169
|
specification_version: 4
|
159
|
-
summary:
|
170
|
+
summary: Strong params replacement
|
160
171
|
test_files: []
|
data/.rubocop.yml
DELETED
@@ -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
|
data/lib/gate/command.rb
DELETED
@@ -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
|