optimism 0.3.3 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +78 -74
- data/README.md +4 -0
- data/lib/optimism.rb +39 -36
- data/lib/optimism/version.rb +1 -1
- data/optimism.gemspec +2 -2
- data/reference.md +1 -1
- metadata +5 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8966741ac69e6f62196d1ea78a71a30dda97fa56e6618fb844a829a5d8d93008
|
4
|
+
data.tar.gz: 5f7e64c28e697af5dd3a782549abf6a4872870f7bab9833868ed196a251bc806
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 936c07c2d033fc9d0f932cb31ef073a62a919cc53c635b14b896520d387c4ba8beaa94348e3b67a42786aca948fd0f3760a80530d90f874099db7d177d61bd47
|
7
|
+
data.tar.gz: 8526dc93dd499644f9ebcf63ea3bb3fd24ff672a8ea7579518900800a2738b40cfefb3b96e9de228cb5e97ed718f05c6064871579487c49229e9288309d63a1a
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
optimism (0.3.
|
4
|
+
optimism (0.3.5)
|
5
5
|
cable_ready (>= 4)
|
6
6
|
rack (~> 2.0)
|
7
7
|
rails (>= 6, >= 5.2)
|
@@ -9,75 +9,79 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
actioncable (6.0
|
13
|
-
actionpack (= 6.0
|
12
|
+
actioncable (6.1.0)
|
13
|
+
actionpack (= 6.1.0)
|
14
|
+
activesupport (= 6.1.0)
|
14
15
|
nio4r (~> 2.0)
|
15
16
|
websocket-driver (>= 0.6.1)
|
16
|
-
actionmailbox (6.0
|
17
|
-
actionpack (= 6.0
|
18
|
-
activejob (= 6.0
|
19
|
-
activerecord (= 6.0
|
20
|
-
activestorage (= 6.0
|
21
|
-
activesupport (= 6.0
|
17
|
+
actionmailbox (6.1.0)
|
18
|
+
actionpack (= 6.1.0)
|
19
|
+
activejob (= 6.1.0)
|
20
|
+
activerecord (= 6.1.0)
|
21
|
+
activestorage (= 6.1.0)
|
22
|
+
activesupport (= 6.1.0)
|
22
23
|
mail (>= 2.7.1)
|
23
|
-
actionmailer (6.0
|
24
|
-
actionpack (= 6.0
|
25
|
-
actionview (= 6.0
|
26
|
-
activejob (= 6.0
|
24
|
+
actionmailer (6.1.0)
|
25
|
+
actionpack (= 6.1.0)
|
26
|
+
actionview (= 6.1.0)
|
27
|
+
activejob (= 6.1.0)
|
28
|
+
activesupport (= 6.1.0)
|
27
29
|
mail (~> 2.5, >= 2.5.4)
|
28
30
|
rails-dom-testing (~> 2.0)
|
29
|
-
actionpack (6.0
|
30
|
-
actionview (= 6.0
|
31
|
-
activesupport (= 6.0
|
32
|
-
rack (~> 2.0, >= 2.0.
|
31
|
+
actionpack (6.1.0)
|
32
|
+
actionview (= 6.1.0)
|
33
|
+
activesupport (= 6.1.0)
|
34
|
+
rack (~> 2.0, >= 2.0.9)
|
33
35
|
rack-test (>= 0.6.3)
|
34
36
|
rails-dom-testing (~> 2.0)
|
35
37
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
36
|
-
actiontext (6.0
|
37
|
-
actionpack (= 6.0
|
38
|
-
activerecord (= 6.0
|
39
|
-
activestorage (= 6.0
|
40
|
-
activesupport (= 6.0
|
38
|
+
actiontext (6.1.0)
|
39
|
+
actionpack (= 6.1.0)
|
40
|
+
activerecord (= 6.1.0)
|
41
|
+
activestorage (= 6.1.0)
|
42
|
+
activesupport (= 6.1.0)
|
41
43
|
nokogiri (>= 1.8.5)
|
42
|
-
actionview (6.0
|
43
|
-
activesupport (= 6.0
|
44
|
+
actionview (6.1.0)
|
45
|
+
activesupport (= 6.1.0)
|
44
46
|
builder (~> 3.1)
|
45
47
|
erubi (~> 1.4)
|
46
48
|
rails-dom-testing (~> 2.0)
|
47
49
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
48
|
-
activejob (6.0
|
49
|
-
activesupport (= 6.0
|
50
|
+
activejob (6.1.0)
|
51
|
+
activesupport (= 6.1.0)
|
50
52
|
globalid (>= 0.3.6)
|
51
|
-
activemodel (6.0
|
52
|
-
activesupport (= 6.0
|
53
|
-
activerecord (6.0
|
54
|
-
activemodel (= 6.0
|
55
|
-
activesupport (= 6.0
|
56
|
-
activestorage (6.0
|
57
|
-
actionpack (= 6.0
|
58
|
-
activejob (= 6.0
|
59
|
-
activerecord (= 6.0
|
53
|
+
activemodel (6.1.0)
|
54
|
+
activesupport (= 6.1.0)
|
55
|
+
activerecord (6.1.0)
|
56
|
+
activemodel (= 6.1.0)
|
57
|
+
activesupport (= 6.1.0)
|
58
|
+
activestorage (6.1.0)
|
59
|
+
actionpack (= 6.1.0)
|
60
|
+
activejob (= 6.1.0)
|
61
|
+
activerecord (= 6.1.0)
|
62
|
+
activesupport (= 6.1.0)
|
60
63
|
marcel (~> 0.3.1)
|
61
|
-
|
64
|
+
mimemagic (~> 0.3.2)
|
65
|
+
activesupport (6.1.0)
|
62
66
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
63
|
-
i18n (>=
|
64
|
-
minitest (
|
65
|
-
tzinfo (~>
|
66
|
-
zeitwerk (~> 2.
|
67
|
+
i18n (>= 1.6, < 2)
|
68
|
+
minitest (>= 5.1)
|
69
|
+
tzinfo (~> 2.0)
|
70
|
+
zeitwerk (~> 2.3)
|
67
71
|
ast (2.4.0)
|
68
72
|
builder (3.2.4)
|
69
|
-
cable_ready (4.
|
73
|
+
cable_ready (4.4.5)
|
70
74
|
rails (>= 5.2)
|
71
75
|
coderay (1.1.2)
|
72
|
-
concurrent-ruby (1.1.
|
76
|
+
concurrent-ruby (1.1.7)
|
73
77
|
crass (1.0.6)
|
74
|
-
erubi (1.
|
78
|
+
erubi (1.10.0)
|
75
79
|
globalid (0.4.2)
|
76
80
|
activesupport (>= 4.2.0)
|
77
|
-
i18n (1.8.
|
81
|
+
i18n (1.8.5)
|
78
82
|
concurrent-ruby (~> 1.0)
|
79
83
|
jaro_winkler (1.5.4)
|
80
|
-
loofah (2.
|
84
|
+
loofah (2.8.0)
|
81
85
|
crass (~> 1.0.2)
|
82
86
|
nokogiri (>= 1.5.9)
|
83
87
|
mail (2.7.1)
|
@@ -88,9 +92,9 @@ GEM
|
|
88
92
|
mimemagic (0.3.5)
|
89
93
|
mini_mime (1.0.2)
|
90
94
|
mini_portile2 (2.4.0)
|
91
|
-
minitest (5.14.
|
92
|
-
nio4r (2.5.
|
93
|
-
nokogiri (1.10.
|
95
|
+
minitest (5.14.2)
|
96
|
+
nio4r (2.5.4)
|
97
|
+
nokogiri (1.10.10-x64-mingw32)
|
94
98
|
mini_portile2 (~> 2.4.0)
|
95
99
|
parallel (1.19.1)
|
96
100
|
parser (2.7.0.2)
|
@@ -100,35 +104,35 @@ GEM
|
|
100
104
|
method_source (~> 0.9.0)
|
101
105
|
pry-nav (0.3.0)
|
102
106
|
pry (>= 0.9.10, < 0.13.0)
|
103
|
-
rack (2.2.
|
107
|
+
rack (2.2.3)
|
104
108
|
rack-test (1.1.0)
|
105
109
|
rack (>= 1.0, < 3)
|
106
|
-
rails (6.0
|
107
|
-
actioncable (= 6.0
|
108
|
-
actionmailbox (= 6.0
|
109
|
-
actionmailer (= 6.0
|
110
|
-
actionpack (= 6.0
|
111
|
-
actiontext (= 6.0
|
112
|
-
actionview (= 6.0
|
113
|
-
activejob (= 6.0
|
114
|
-
activemodel (= 6.0
|
115
|
-
activerecord (= 6.0
|
116
|
-
activestorage (= 6.0
|
117
|
-
activesupport (= 6.0
|
118
|
-
bundler (>= 1.
|
119
|
-
railties (= 6.0
|
110
|
+
rails (6.1.0)
|
111
|
+
actioncable (= 6.1.0)
|
112
|
+
actionmailbox (= 6.1.0)
|
113
|
+
actionmailer (= 6.1.0)
|
114
|
+
actionpack (= 6.1.0)
|
115
|
+
actiontext (= 6.1.0)
|
116
|
+
actionview (= 6.1.0)
|
117
|
+
activejob (= 6.1.0)
|
118
|
+
activemodel (= 6.1.0)
|
119
|
+
activerecord (= 6.1.0)
|
120
|
+
activestorage (= 6.1.0)
|
121
|
+
activesupport (= 6.1.0)
|
122
|
+
bundler (>= 1.15.0)
|
123
|
+
railties (= 6.1.0)
|
120
124
|
sprockets-rails (>= 2.0.0)
|
121
125
|
rails-dom-testing (2.0.3)
|
122
126
|
activesupport (>= 4.2.0)
|
123
127
|
nokogiri (>= 1.6)
|
124
128
|
rails-html-sanitizer (1.3.0)
|
125
129
|
loofah (~> 2.3)
|
126
|
-
railties (6.0
|
127
|
-
actionpack (= 6.0
|
128
|
-
activesupport (= 6.0
|
130
|
+
railties (6.1.0)
|
131
|
+
actionpack (= 6.1.0)
|
132
|
+
activesupport (= 6.1.0)
|
129
133
|
method_source
|
130
134
|
rake (>= 0.8.7)
|
131
|
-
thor (
|
135
|
+
thor (~> 1.0)
|
132
136
|
rainbow (3.0.0)
|
133
137
|
rake (13.0.1)
|
134
138
|
rubocop (0.79.0)
|
@@ -141,10 +145,10 @@ GEM
|
|
141
145
|
rubocop-performance (1.5.2)
|
142
146
|
rubocop (>= 0.71.0)
|
143
147
|
ruby-progressbar (1.10.1)
|
144
|
-
sprockets (4.0.
|
148
|
+
sprockets (4.0.2)
|
145
149
|
concurrent-ruby (~> 1.0)
|
146
150
|
rack (> 1, < 3)
|
147
|
-
sprockets-rails (3.2.
|
151
|
+
sprockets-rails (3.2.2)
|
148
152
|
actionpack (>= 4.0)
|
149
153
|
activesupport (>= 4.0)
|
150
154
|
sprockets (>= 3.0.0)
|
@@ -154,17 +158,17 @@ GEM
|
|
154
158
|
standardrb (1.0.0)
|
155
159
|
standard
|
156
160
|
thor (1.0.1)
|
157
|
-
|
158
|
-
|
159
|
-
thread_safe (~> 0.1)
|
161
|
+
tzinfo (2.0.4)
|
162
|
+
concurrent-ruby (~> 1.0)
|
160
163
|
unicode-display_width (1.6.1)
|
161
|
-
websocket-driver (0.7.
|
164
|
+
websocket-driver (0.7.3)
|
162
165
|
websocket-extensions (>= 0.1.0)
|
163
166
|
websocket-extensions (0.1.5)
|
164
|
-
zeitwerk (2.
|
167
|
+
zeitwerk (2.4.2)
|
165
168
|
|
166
169
|
PLATFORMS
|
167
170
|
ruby
|
171
|
+
x64-mingw32
|
168
172
|
|
169
173
|
DEPENDENCIES
|
170
174
|
bundler (~> 2.0)
|
data/README.md
CHANGED
@@ -4,6 +4,10 @@
|
|
4
4
|
|
5
5
|
The missing drop-in solution for realtime remote form validation in Rails.
|
6
6
|
|
7
|
+
{% hint style="success" %}
|
8
|
+
Optimism v0.4.1 now supports Ruby 3.0.0, thanks to [Julian Rubisch](https://twitter.com/julian_rubisch) and Rails 6.1, thanks to [Josh LeBlanc](https://github.com/joshleblanc). 🎉
|
9
|
+
{% endhint %}
|
10
|
+
|
7
11
|
## Why have optimism?
|
8
12
|
|
9
13
|
[Optimism](https://github.com/leastbad/optimism) is an MIT-licensed [Ruby on Rails](https://rubyonrails.org/) gem that makes it easy to give your users instant constructive feedback if they enter invalid data into your application. Instead of dumping a list of errors at the top of your interface, Optimism provides specific instructions directly beside or below individual input elements.
|
data/lib/optimism.rb
CHANGED
@@ -3,22 +3,19 @@ require "optimism/version"
|
|
3
3
|
require "optimism/railtie" if defined?(Rails)
|
4
4
|
|
5
5
|
module Optimism
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
self.form_selector = "#RESOURCE_form"
|
20
|
-
self.submit_selector = "#RESOURCE_submit"
|
21
|
-
end
|
6
|
+
mattr_accessor :channel_proc, :form_class, :error_class, :disable_submit, :suffix, :emit_events, :add_css, :inject_inline, :container_selector, :error_selector, :form_selector, :submit_selector
|
7
|
+
self.channel_proc = ->(context) { "OptimismChannel" }
|
8
|
+
self.form_class = "invalid"
|
9
|
+
self.error_class = "error"
|
10
|
+
self.disable_submit = false
|
11
|
+
self.suffix = ""
|
12
|
+
self.emit_events = false
|
13
|
+
self.add_css = true
|
14
|
+
self.inject_inline = true
|
15
|
+
self.container_selector = "#RESOURCE_ATTRIBUTE_container"
|
16
|
+
self.error_selector = "#RESOURCE_ATTRIBUTE_error"
|
17
|
+
self.form_selector = "#RESOURCE_form"
|
18
|
+
self.submit_selector = "#RESOURCE_submit"
|
22
19
|
|
23
20
|
def self.configure(&block)
|
24
21
|
yield self
|
@@ -26,7 +23,7 @@ module Optimism
|
|
26
23
|
|
27
24
|
def broadcast_errors(model, attributes)
|
28
25
|
return unless model&.errors&.messages
|
29
|
-
resource = model
|
26
|
+
resource = ActiveModel::Naming.param_key(model)
|
30
27
|
form_selector, submit_selector = Optimism.form_selector.sub("RESOURCE", resource), Optimism.submit_selector.sub("RESOURCE", resource)
|
31
28
|
attributes = case attributes
|
32
29
|
when ActionController::Parameters, Hash, ActiveSupport::HashWithIndifferentAccess
|
@@ -41,15 +38,15 @@ module Optimism
|
|
41
38
|
model.valid? if model.errors.empty?
|
42
39
|
process_resource(model, attributes, [resource])
|
43
40
|
if model.errors.any?
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:form:invalid", detail: {resource: resource}) if Optimism.emit_events
|
42
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
|
43
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].set_attribute(selector: submit_selector, name: "disabled") if Optimism.disable_submit
|
47
44
|
else
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:form:valid", detail: {resource: resource}) if Optimism.emit_events
|
46
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].remove_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
|
47
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].remove_attribute(selector: submit_selector, name: "disabled") if Optimism.disable_submit
|
51
48
|
end
|
52
|
-
|
49
|
+
CableReady::Channels.instance.broadcast
|
53
50
|
head :ok if defined?(head)
|
54
51
|
end
|
55
52
|
|
@@ -81,21 +78,31 @@ module Optimism
|
|
81
78
|
container_selector, error_selector = Optimism.container_selector.sub("RESOURCE", resource).sub("ATTRIBUTE", attribute), Optimism.error_selector.sub("RESOURCE", resource).sub("ATTRIBUTE", attribute)
|
82
79
|
if model.errors.any? && model.errors.messages.map(&:first).include?(attribute.to_sym)
|
83
80
|
message = "#{model.errors.full_message(attribute.to_sym, model.errors.messages[attribute.to_sym].first)}#{Optimism.suffix}"
|
84
|
-
|
85
|
-
|
86
|
-
|
81
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:invalid", detail: {resource: resource, attribute: attribute, text: message}) if Optimism.emit_events
|
82
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
|
83
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: message) if Optimism.inject_inline
|
87
84
|
else
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:valid", detail: {resource: resource, attribute: attribute}) if Optimism.emit_events
|
86
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].remove_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
|
87
|
+
CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: "") if Optimism.inject_inline
|
91
88
|
end
|
92
89
|
end
|
93
90
|
end
|
94
91
|
|
95
92
|
module ActionView::Helpers
|
93
|
+
module FormHelper
|
94
|
+
def error_for(object_name, attribute, **options)
|
95
|
+
tag.span **options.merge(id: error_id_for(object_name, attribute))
|
96
|
+
end
|
97
|
+
|
98
|
+
def error_id_for(object_name, attribute)
|
99
|
+
Optimism.error_selector.sub("RESOURCE", object_name.to_s.delete("]").tr("[", "_")).sub("ATTRIBUTE", attribute.to_s)[1..-1]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
96
103
|
class FormBuilder
|
97
104
|
def container_for(attribute, **options, &block)
|
98
|
-
@template.tag.div @template.capture(&block), options.merge
|
105
|
+
@template.tag.div @template.capture(&block), **options.merge(id: container_id_for(attribute)) if block_given?
|
99
106
|
end
|
100
107
|
|
101
108
|
def container_id_for(attribute)
|
@@ -103,11 +110,7 @@ module ActionView::Helpers
|
|
103
110
|
end
|
104
111
|
|
105
112
|
def error_for(attribute, **options)
|
106
|
-
@template.
|
107
|
-
end
|
108
|
-
|
109
|
-
def error_id_for(attribute)
|
110
|
-
Optimism.error_selector.sub("RESOURCE", object_name.to_s.delete("]").tr("[", "_")).sub("ATTRIBUTE", attribute.to_s)[1..-1]
|
113
|
+
@template.error_for(object_name, attribute, **options)
|
111
114
|
end
|
112
115
|
end
|
113
116
|
end
|
data/lib/optimism/version.rb
CHANGED
data/optimism.gemspec
CHANGED
@@ -26,6 +26,6 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency "pry-nav", "~> 0.3.0"
|
27
27
|
spec.add_development_dependency "standardrb", "~> 1.0.0"
|
28
28
|
spec.add_dependency "rack", "~> 2.0"
|
29
|
-
spec.add_dependency "rails", [">= 5.2"
|
30
|
-
spec.add_dependency "cable_ready", ">= 4"
|
29
|
+
spec.add_dependency "rails", [">= 5.2"]
|
30
|
+
spec.add_dependency "cable_ready", ">= 4.4.6"
|
31
31
|
end
|
data/reference.md
CHANGED
@@ -93,7 +93,7 @@ Optimism is configurable via an optional initializer file. As with all initializ
|
|
93
93
|
{% code title="config/initializers/optimism.rb" %}
|
94
94
|
```ruby
|
95
95
|
Optimism.configure do |config|
|
96
|
-
config.
|
96
|
+
config.channel_proc = ->(context) { "OptimismChannel" }
|
97
97
|
config.form_class = "invalid"
|
98
98
|
config.error_class = "error"
|
99
99
|
config.disable_submit = false
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optimism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- leastbad
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,9 +101,6 @@ dependencies:
|
|
101
101
|
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '5.2'
|
104
|
-
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: '6'
|
107
104
|
type: :runtime
|
108
105
|
prerelease: false
|
109
106
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -111,23 +108,20 @@ dependencies:
|
|
111
108
|
- - ">="
|
112
109
|
- !ruby/object:Gem::Version
|
113
110
|
version: '5.2'
|
114
|
-
- - ">="
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: '6'
|
117
111
|
- !ruby/object:Gem::Dependency
|
118
112
|
name: cable_ready
|
119
113
|
requirement: !ruby/object:Gem::Requirement
|
120
114
|
requirements:
|
121
115
|
- - ">="
|
122
116
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
117
|
+
version: 4.4.6
|
124
118
|
type: :runtime
|
125
119
|
prerelease: false
|
126
120
|
version_requirements: !ruby/object:Gem::Requirement
|
127
121
|
requirements:
|
128
122
|
- - ">="
|
129
123
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
124
|
+
version: 4.4.6
|
131
125
|
description: Realtime remote form input validations delivered via websockets
|
132
126
|
email:
|
133
127
|
- hello@leastbad.com
|
@@ -189,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
183
|
- !ruby/object:Gem::Version
|
190
184
|
version: '0'
|
191
185
|
requirements: []
|
192
|
-
rubygems_version: 3.
|
186
|
+
rubygems_version: 3.1.4
|
193
187
|
signing_key:
|
194
188
|
specification_version: 4
|
195
189
|
summary: Drop-in Rails form validations
|