formeze 4.3.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +28 -0
- data/README.md +34 -18
- data/formeze.gemspec +4 -4
- data/lib/formeze/{condition.rb → block.rb} +1 -1
- data/lib/formeze/errors.rb +20 -5
- data/lib/formeze/field.rb +32 -14
- data/lib/formeze/form_data.rb +42 -12
- data/lib/formeze/validation.rb +2 -4
- data/lib/formeze.rb +36 -44
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd2160c23942cd4a127e7f84993aceb1a416a687060fb4f907181d295d5b26d5
|
4
|
+
data.tar.gz: 7406001697348315beeeb47c7400756e4bf8fb8acb60b8d872004f8de2966382
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83a0278250e4a4d9a1e7adae850e34cc4d44bdfa0e71638cf15ec7042abce347889495a4c6466d189ca30a9eb7b35e23472db91237f85f11841ef83fee2e01f8
|
7
|
+
data.tar.gz: b4218dd2e97436668378a40863a652ef1e7f7e329c0fa903e44197846b935ba8af21c7d2e34f804e483c9fda385deb39529b8a2049f69e4130b2238ef1ef9c2b
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
# 5.0.0
|
2
|
+
|
3
|
+
* Added a `fill` field option to specify how to fill a field. For example:
|
4
|
+
|
5
|
+
class ExampleForm < Formeze::Form
|
6
|
+
field :year, required: false, fill: ->{ _1.date&.year }
|
7
|
+
end
|
8
|
+
|
9
|
+
* Added functionality for defining field specific error messages via i18n.
|
10
|
+
|
11
|
+
Add translations to your locale files like this:
|
12
|
+
|
13
|
+
ExampleForm:
|
14
|
+
errors:
|
15
|
+
comments:
|
16
|
+
required: 'are required'
|
17
|
+
|
18
|
+
* Removed support for older rubies. **Required ruby version is now 3.0.0**
|
19
|
+
|
20
|
+
* Changed from cgi to rack for parsing form data, adding support for parsing
|
21
|
+
requests with different methods e.g. PUT and PATCH instead of just POST.
|
22
|
+
|
23
|
+
Whilst this should largely be backwards compatible there are some differences,
|
24
|
+
for example uploaded files will be instances of `Rack::Multipart::UploadedFile`
|
25
|
+
instead of `StringIO` instances as they were before.
|
26
|
+
|
27
|
+
* Changed the default blank value to `nil`
|
28
|
+
|
1
29
|
# 4.3.0
|
2
30
|
|
3
31
|
* Added dependency on cgi gem
|
data/README.md
CHANGED
@@ -3,19 +3,19 @@
|
|
3
3
|
![Gem Version](https://badge.fury.io/rb/formeze.svg)
|
4
4
|
![Test Status](https://github.com/readysteady/formeze/actions/workflows/test.yml/badge.svg)
|
5
5
|
|
6
|
-
Ruby gem for validating form data.
|
6
|
+
Ruby gem for parsing and validating form data.
|
7
7
|
|
8
8
|
|
9
9
|
## Motivation
|
10
10
|
|
11
|
-
Most web
|
11
|
+
Most web applications built for end users will need to process form data.
|
12
12
|
Registration forms, profile forms, checkout forms, contact forms, and forms
|
13
13
|
for adding/editing application specific data.
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
With formeze you can define form objects that explicitly define what your
|
16
|
+
application expects as input. This is more secure, and leads to much better
|
17
|
+
separation of responsibilities, and also allows for implementing different
|
18
|
+
validation rules in different contexts.
|
19
19
|
|
20
20
|
|
21
21
|
## Install
|
@@ -53,7 +53,8 @@ else
|
|
53
53
|
end
|
54
54
|
```
|
55
55
|
|
56
|
-
Formeze will automatically ignore the Rails "
|
56
|
+
Formeze will automatically ignore the Rails "authenticity_token", "commit",
|
57
|
+
and "utf8" parameters.
|
57
58
|
|
58
59
|
If you prefer not to inherit from the `Formeze::Form` class then you can
|
59
60
|
instead call the `Formeze.setup` method on your classes like this:
|
@@ -89,9 +90,9 @@ messages specific to a single field.
|
|
89
90
|
|
90
91
|
## Field options
|
91
92
|
|
92
|
-
By default fields cannot be blank, they are limited
|
93
|
-
and they cannot contain newlines. These restrictions can be
|
94
|
-
by setting various field options.
|
93
|
+
By default fields are required (i.e. they cannot be blank), they are limited
|
94
|
+
to 64 characters, and they cannot contain newlines. These restrictions can be
|
95
|
+
overridden by setting various field options.
|
95
96
|
|
96
97
|
Defining a field without any options works well for a simple text input.
|
97
98
|
If the default length limit is too big or too small you can override it
|
@@ -101,11 +102,14 @@ by setting the `maxlength` option. For example:
|
|
101
102
|
field :title, maxlength: 200
|
102
103
|
```
|
103
104
|
|
104
|
-
Similarly there is a `minlength` option for
|
105
|
-
|
105
|
+
Similarly there is a `minlength` option for defining a minimum length:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
field :password, minlength: 8
|
109
|
+
```
|
106
110
|
|
107
111
|
Fields are required by default. Specify the `required` option if the field
|
108
|
-
is
|
112
|
+
is optional. For example:
|
109
113
|
|
110
114
|
```ruby
|
111
115
|
field :title, required: false
|
@@ -308,11 +312,11 @@ would include the value of the `formeze.errors.does_not_match` I18n key.
|
|
308
312
|
|
309
313
|
## I18n integration
|
310
314
|
|
311
|
-
Formeze integrates with [
|
315
|
+
Formeze integrates with the [i18n gem](https://rubygems.org/gems/i18n)
|
312
316
|
so that you can define custom error messages and field labels within your
|
313
317
|
locales (useful both for localization, and when working with designers).
|
314
|
-
|
315
|
-
|
318
|
+
|
319
|
+
Here is an example of how you would change the "required" error message:
|
316
320
|
|
317
321
|
```yaml
|
318
322
|
# config/locales/en.yml
|
@@ -322,8 +326,20 @@ en:
|
|
322
326
|
required: "cannot be blank"
|
323
327
|
```
|
324
328
|
|
325
|
-
|
326
|
-
|
329
|
+
Error messages defined in this way apply globally to all Formeze forms.
|
330
|
+
|
331
|
+
You can also change error messages on a per field basis, for example:
|
332
|
+
|
333
|
+
```yaml
|
334
|
+
# config/locales/en.yml
|
335
|
+
en:
|
336
|
+
ExampleForm:
|
337
|
+
errors:
|
338
|
+
comments:
|
339
|
+
required: 'are required'
|
340
|
+
```
|
341
|
+
|
342
|
+
Here is an example of how to define a custom label for "first_name" fields:
|
327
343
|
|
328
344
|
```yaml
|
329
345
|
# config/locales/en.yml
|
data/formeze.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'formeze'
|
3
|
-
s.version = '
|
3
|
+
s.version = '5.0.0'
|
4
4
|
s.license = 'LGPL-3.0'
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = ['Tim Craft']
|
7
7
|
s.email = ['mail@timcraft.com']
|
8
8
|
s.homepage = 'https://github.com/readysteady/formeze'
|
9
|
-
s.description = 'Ruby gem for validating form data'
|
9
|
+
s.description = 'Ruby gem for parsing and validating form data'
|
10
10
|
s.summary = 'See description'
|
11
11
|
s.files = Dir.glob('lib/**/*.rb') + %w(CHANGES.md LICENSE.txt README.md formeze.gemspec)
|
12
|
-
s.required_ruby_version = '>=
|
12
|
+
s.required_ruby_version = '>= 3.0.0'
|
13
13
|
s.require_path = 'lib'
|
14
14
|
s.metadata = {
|
15
15
|
'homepage' => 'https://github.com/readysteady/formeze',
|
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
|
|
17
17
|
'bug_tracker_uri' => 'https://github.com/readysteady/formeze/issues',
|
18
18
|
'changelog_uri' => 'https://github.com/readysteady/formeze/blob/main/CHANGES.md'
|
19
19
|
}
|
20
|
-
s.add_dependency '
|
20
|
+
s.add_dependency 'rack', '~> 3'
|
21
21
|
end
|
data/lib/formeze/errors.rb
CHANGED
@@ -1,11 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Formeze::Errors
|
2
4
|
SCOPE = [:formeze, :errors].freeze
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
DEFAULT = {
|
7
|
+
bad_value: 'is invalid',
|
8
|
+
not_accepted: 'is not an accepted file type',
|
9
|
+
not_multiline: 'cannot contain newlines',
|
10
|
+
no_match: 'is invalid',
|
11
|
+
required: 'is required',
|
12
|
+
too_large: 'is too large',
|
13
|
+
too_long: 'is too long',
|
14
|
+
too_short: 'is too short',
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.translate(error, scope:)
|
18
|
+
default = DEFAULT[error] || 'is invalid'
|
19
|
+
|
20
|
+
return default unless defined?(I18n)
|
21
|
+
|
22
|
+
message = I18n.translate(error, scope: scope, default: nil)
|
8
23
|
|
9
|
-
default
|
24
|
+
message || I18n.translate(error, scope: SCOPE, default: default)
|
10
25
|
end
|
11
26
|
end
|
data/lib/formeze/field.rb
CHANGED
@@ -16,7 +16,7 @@ class Formeze::Field
|
|
16
16
|
if String === value
|
17
17
|
value = validate(value, form)
|
18
18
|
else
|
19
|
-
form.add_error(self, :not_accepted
|
19
|
+
form.add_error(self, :not_accepted) unless acceptable_file?(value)
|
20
20
|
|
21
21
|
size += value.size
|
22
22
|
end
|
@@ -26,26 +26,26 @@ class Formeze::Field
|
|
26
26
|
form.send(:"#{name}=", value)
|
27
27
|
end
|
28
28
|
|
29
|
-
form.add_error(self, :too_large
|
29
|
+
form.add_error(self, :too_large) if maxsize? && size > maxsize
|
30
30
|
end
|
31
31
|
|
32
32
|
def validate(value, form)
|
33
33
|
value = Formeze.scrub(value, @options[:scrub])
|
34
34
|
|
35
35
|
if blank?(value)
|
36
|
-
form.add_error(self, :required
|
36
|
+
form.add_error(self, :required) if required?
|
37
37
|
|
38
|
-
value = blank_value
|
38
|
+
value = blank_value
|
39
39
|
else
|
40
|
-
form.add_error(self, :not_multiline
|
40
|
+
form.add_error(self, :not_multiline) if !multiline? && value.lines.count > 1
|
41
41
|
|
42
|
-
form.add_error(self, :too_long
|
42
|
+
form.add_error(self, :too_long) if too_long?(value)
|
43
43
|
|
44
|
-
form.add_error(self, :too_short
|
44
|
+
form.add_error(self, :too_short) if too_short?(value)
|
45
45
|
|
46
|
-
form.add_error(self, :no_match
|
46
|
+
form.add_error(self, :no_match) if no_match?(value)
|
47
47
|
|
48
|
-
form.add_error(self, :bad_value
|
48
|
+
form.add_error(self, :bad_value) if values? && !values.include?(value)
|
49
49
|
end
|
50
50
|
|
51
51
|
value
|
@@ -95,6 +95,10 @@ class Formeze::Field
|
|
95
95
|
@options.fetch(:maxsize)
|
96
96
|
end
|
97
97
|
|
98
|
+
def accept?
|
99
|
+
@options.key?(:accept)
|
100
|
+
end
|
101
|
+
|
98
102
|
def accept
|
99
103
|
@accept ||= @options.fetch(:accept).split(',').flat_map { |type| MIME::Types[type] }
|
100
104
|
end
|
@@ -111,12 +115,8 @@ class Formeze::Field
|
|
111
115
|
@options.key?(:pattern) && value !~ @options[:pattern]
|
112
116
|
end
|
113
117
|
|
114
|
-
def blank_value?
|
115
|
-
@options.key?(:blank)
|
116
|
-
end
|
117
|
-
|
118
118
|
def blank_value
|
119
|
-
@options
|
119
|
+
@options[:blank]
|
120
120
|
end
|
121
121
|
|
122
122
|
def values?
|
@@ -142,4 +142,22 @@ class Formeze::Field
|
|
142
142
|
def defined_unless
|
143
143
|
@options.fetch(:defined_unless)
|
144
144
|
end
|
145
|
+
|
146
|
+
def undefined?(form)
|
147
|
+
if defined_if?
|
148
|
+
!Formeze::Block.evaluate(form, defined_if)
|
149
|
+
elsif defined_unless?
|
150
|
+
Formeze::Block.evaluate(form, defined_unless)
|
151
|
+
else
|
152
|
+
false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def fill_proc?
|
157
|
+
@options.key?(:fill)
|
158
|
+
end
|
159
|
+
|
160
|
+
def fill_proc
|
161
|
+
@options[:fill]
|
162
|
+
end
|
145
163
|
end
|
data/lib/formeze/form_data.rb
CHANGED
@@ -1,23 +1,53 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rack'
|
2
3
|
|
3
4
|
module Formeze::FormData
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def self.parse(input)
|
6
|
+
if input.is_a?(String)
|
7
|
+
query_parser.parse_query(input)
|
8
|
+
elsif input.respond_to?(:env)
|
9
|
+
body = input.body
|
10
|
+
body.rewind if body.respond_to?(:rewind)
|
11
|
+
case input.media_type
|
12
|
+
when 'multipart/form-data'
|
13
|
+
Rack::Multipart.parse_multipart(input.env, Params)
|
14
|
+
when 'application/x-www-form-urlencoded'
|
15
|
+
query_parser.parse_query(body.read)
|
16
|
+
else
|
17
|
+
raise ArgumentError, "can't parse #{input.media_type.inspect} form data"
|
18
|
+
end
|
19
|
+
else
|
20
|
+
raise ArgumentError, "can't parse #{input.class} form data"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Params
|
25
|
+
def self.make_params
|
26
|
+
ParamsHash.new { |h, k| h[k] = Array.new }
|
7
27
|
end
|
8
28
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
29
|
+
def self.normalize_params(params, key, value)
|
30
|
+
if value.is_a?(Hash)
|
31
|
+
value = Rack::Multipart::UploadedFile.new(io: value[:tempfile], filename: value[:filename], content_type: value[:type])
|
12
32
|
end
|
33
|
+
|
34
|
+
params[key] << value
|
13
35
|
end
|
14
36
|
end
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
38
|
+
class ParamsHash < ::Hash
|
39
|
+
alias_method :to_params_hash, :to_h
|
40
|
+
end
|
41
|
+
|
42
|
+
class QueryParser < Rack::QueryParser
|
43
|
+
def make_params
|
44
|
+
Hash.new { |h, k| h[k] = Array.new }
|
21
45
|
end
|
22
46
|
end
|
47
|
+
|
48
|
+
def self.query_parser
|
49
|
+
@query_parser ||= QueryParser.new(nil, 0)
|
50
|
+
end
|
51
|
+
|
52
|
+
private_class_method :query_parser
|
23
53
|
end
|
data/lib/formeze/validation.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
class Formeze::Validation
|
4
2
|
include Formeze::Presence
|
5
3
|
|
@@ -14,7 +12,7 @@ class Formeze::Validation
|
|
14
12
|
end
|
15
13
|
|
16
14
|
def validates?(form)
|
17
|
-
@precondition ? Formeze::
|
15
|
+
@precondition ? Formeze::Block.evaluate(form, @precondition) : true
|
18
16
|
end
|
19
17
|
|
20
18
|
def field_value?(form)
|
@@ -33,7 +31,7 @@ class Formeze::Validation
|
|
33
31
|
form.instance_eval(&@block)
|
34
32
|
end
|
35
33
|
|
36
|
-
form.add_error(@field, @error
|
34
|
+
form.add_error(@field, @error) unless return_value
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
data/lib/formeze.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Formeze
|
4
|
-
autoload :
|
4
|
+
autoload :Block, 'formeze/block'
|
5
5
|
autoload :Errors, 'formeze/errors'
|
6
6
|
autoload :Field, 'formeze/field'
|
7
7
|
autoload :Form, 'formeze/form'
|
@@ -36,16 +36,24 @@ module Formeze
|
|
36
36
|
|
37
37
|
class ValueError < StandardError; end
|
38
38
|
|
39
|
-
class ValidationError < StandardError
|
39
|
+
class ValidationError < StandardError
|
40
|
+
def initialize(field, message)
|
41
|
+
@field = field
|
40
42
|
|
41
|
-
|
43
|
+
super("#{field.label} #{message}")
|
44
|
+
end
|
42
45
|
|
43
|
-
|
46
|
+
def field_name
|
47
|
+
@field.name
|
48
|
+
end
|
49
|
+
end
|
44
50
|
|
45
51
|
module InstanceMethods
|
46
52
|
def fill(object)
|
47
53
|
self.class.fields.each_value do |field|
|
48
|
-
if
|
54
|
+
if field.fill_proc?
|
55
|
+
send(:"#{field.name}=", Formeze::Block.evaluate(object, field.fill_proc))
|
56
|
+
elsif Hash === object && object.key?(field.name)
|
49
57
|
send(:"#{field.name}=", object[field.name])
|
50
58
|
elsif object.respond_to?(field.name)
|
51
59
|
send(:"#{field.name}=", object.send(field.name))
|
@@ -59,27 +67,31 @@ module Formeze
|
|
59
67
|
form_data = FormData.parse(input)
|
60
68
|
|
61
69
|
self.class.fields.each_value do |field|
|
62
|
-
next
|
70
|
+
next if field.undefined?(self)
|
63
71
|
|
64
72
|
unless form_data.key?(field.key)
|
65
73
|
next if field.multiple? || !field.key_required?
|
66
74
|
|
67
|
-
raise KeyError, "missing form key: #{field.key}"
|
75
|
+
raise KeyError, "missing form key: #{field.key}" unless field.accept?
|
68
76
|
end
|
69
77
|
|
70
78
|
values = form_data.delete(field.key)
|
71
79
|
|
72
|
-
if values.
|
73
|
-
|
74
|
-
|
80
|
+
if values.is_a?(Array)
|
81
|
+
if values.length > 1
|
82
|
+
raise ValueError, "multiple values for #{field.key} field" unless field.multiple?
|
83
|
+
end
|
75
84
|
|
76
|
-
|
85
|
+
field.validate_all(values, self)
|
86
|
+
else
|
87
|
+
field.validate(values, self)
|
88
|
+
end
|
77
89
|
end
|
78
90
|
|
79
91
|
if defined?(Rails)
|
80
|
-
|
81
|
-
|
82
|
-
|
92
|
+
form_data.delete('authenticity_token')
|
93
|
+
form_data.delete('commit')
|
94
|
+
form_data.delete('utf8')
|
83
95
|
end
|
84
96
|
|
85
97
|
unless form_data.empty?
|
@@ -93,14 +105,10 @@ module Formeze
|
|
93
105
|
return self
|
94
106
|
end
|
95
107
|
|
96
|
-
def add_error(field,
|
97
|
-
message = Formeze::Errors.translate(
|
98
|
-
|
99
|
-
error = ValidationError.new("#{field.label} #{message}")
|
108
|
+
def add_error(field, error)
|
109
|
+
message = Formeze::Errors.translate(error, scope: "#{self.class.name}.errors.#{field.name}")
|
100
110
|
|
101
|
-
errors <<
|
102
|
-
|
103
|
-
field_errors[field.name] << error
|
111
|
+
errors << ValidationError.new(field, message)
|
104
112
|
end
|
105
113
|
|
106
114
|
def valid?
|
@@ -116,11 +124,11 @@ module Formeze
|
|
116
124
|
end
|
117
125
|
|
118
126
|
def errors_on?(field_name)
|
119
|
-
|
127
|
+
errors.any? { |error| error.field_name == field_name }
|
120
128
|
end
|
121
129
|
|
122
130
|
def errors_on(field_name)
|
123
|
-
|
131
|
+
errors.select { |error| error.field_name == field_name }
|
124
132
|
end
|
125
133
|
|
126
134
|
def to_h
|
@@ -130,22 +138,6 @@ module Formeze
|
|
130
138
|
end
|
131
139
|
|
132
140
|
alias_method :to_hash, :to_h
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def field_defined?(field)
|
137
|
-
if field.defined_if?
|
138
|
-
Formeze::Condition.evaluate(self, field.defined_if)
|
139
|
-
elsif field.defined_unless?
|
140
|
-
!Formeze::Condition.evaluate(self, field.defined_unless)
|
141
|
-
else
|
142
|
-
true
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def field_errors
|
147
|
-
@field_errors ||= Hash.new { |h, k| h[k] = [] }
|
148
|
-
end
|
149
141
|
end
|
150
142
|
|
151
143
|
def self.label(field_name)
|
@@ -154,11 +146,11 @@ module Formeze
|
|
154
146
|
|
155
147
|
def self.scrub_methods
|
156
148
|
@scrub_methods ||= {
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
161
|
-
:
|
149
|
+
strip: :strip.to_proc,
|
150
|
+
upcase: :upcase.to_proc,
|
151
|
+
downcase: :downcase.to_proc,
|
152
|
+
squeeze: proc { |string| string.squeeze(' ') },
|
153
|
+
squeeze_lines: proc { |string| string.gsub(/(\r?\n)(\r?\n)(\r?\n)+/, '\\1\\2') }
|
162
154
|
}
|
163
155
|
end
|
164
156
|
|
metadata
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formeze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Craft
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3'
|
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: '
|
27
|
-
description: Ruby gem for validating form data
|
26
|
+
version: '3'
|
27
|
+
description: Ruby gem for parsing and validating form data
|
28
28
|
email:
|
29
29
|
- mail@timcraft.com
|
30
30
|
executables: []
|
@@ -36,7 +36,7 @@ files:
|
|
36
36
|
- README.md
|
37
37
|
- formeze.gemspec
|
38
38
|
- lib/formeze.rb
|
39
|
-
- lib/formeze/
|
39
|
+
- lib/formeze/block.rb
|
40
40
|
- lib/formeze/errors.rb
|
41
41
|
- lib/formeze/field.rb
|
42
42
|
- lib/formeze/form.rb
|
@@ -60,14 +60,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
60
|
requirements:
|
61
61
|
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: 3.0.0
|
64
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
requirements: []
|
70
|
-
rubygems_version: 3.5.
|
70
|
+
rubygems_version: 3.5.11
|
71
71
|
signing_key:
|
72
72
|
specification_version: 4
|
73
73
|
summary: See description
|