isomorfeus-react 16.9.9 → 16.9.10
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/lib/isomorfeus-react.rb +8 -2
- data/lib/isomorfeus/props/validate_hash_proxy.rb +180 -0
- data/lib/isomorfeus/props/validator.rb +129 -0
- data/lib/lucid_app/mixin.rb +1 -1
- data/lib/lucid_app/native_component_constructor.rb +5 -0
- data/lib/lucid_component/mixin.rb +1 -2
- data/lib/lucid_component/native_component_constructor.rb +2 -21
- data/lib/lucid_material/app/mixin.rb +1 -0
- data/lib/lucid_material/app/native_component_constructor.rb +2 -21
- data/lib/lucid_material/component/mixin.rb +1 -2
- data/lib/lucid_material/component/native_component_constructor.rb +2 -21
- data/lib/lucid_prop_declaration/mixin.rb +89 -0
- data/lib/react/component/api.rb +0 -51
- data/lib/react/component/mixin.rb +1 -2
- data/lib/react/component/native_component_constructor.rb +5 -0
- data/lib/react/pure_component/mixin.rb +1 -2
- data/lib/react/version.rb +1 -1
- metadata +5 -4
- data/lib/lucid_component/api.rb +0 -82
- data/lib/react/component/native_component_validate_prop.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75729fef22a55df3ac3e157a7d7a52db075e43d99e9c46e81aef63824fdabdba
|
4
|
+
data.tar.gz: 26501bbbd44cca1c7e4f5e7d6ea1312b9ddabc7f298d3c8e0367097c10f11906
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fc0991c90a58f4756246b9b26fe85cf0e8d64b24779fce4cac1aaf0846045bcf3bdb2a24896a781aad5af3188dcd754a12be2fb6a1163589cfeabd937f9eab3
|
7
|
+
data.tar.gz: c31e70784c55858c182cce6c194a472ca7476a355046c4d2dba9faf63f92df59b5560b156e6b4eff5c9d6a2ee80aad1862c053ce2048bc237f2e57d8c5dd309a
|
data/lib/isomorfeus-react.rb
CHANGED
@@ -38,6 +38,9 @@ if RUBY_ENGINE == 'opal'
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# props
|
41
|
+
require 'isomorfeus/props/validate_hash_proxy'
|
42
|
+
require 'isomorfeus/props/validator'
|
43
|
+
require 'lucid_prop_declaration/mixin'
|
41
44
|
require 'react/component/props'
|
42
45
|
|
43
46
|
# HTML Elements support
|
@@ -65,7 +68,6 @@ if RUBY_ENGINE == 'opal'
|
|
65
68
|
# require 'react/component/unsafe_api'
|
66
69
|
require 'react/component/initializer'
|
67
70
|
require 'react/component/native_component_constructor'
|
68
|
-
require 'react/component/native_component_validate_prop'
|
69
71
|
require 'react/component/state'
|
70
72
|
require 'react/component/match'
|
71
73
|
require 'react/component/location'
|
@@ -97,7 +99,6 @@ if RUBY_ENGINE == 'opal'
|
|
97
99
|
require 'lucid_component/app_store_proxy'
|
98
100
|
require 'lucid_component/class_store_proxy'
|
99
101
|
require 'lucid_component/instance_store_proxy'
|
100
|
-
require 'lucid_component/api'
|
101
102
|
require 'lucid_component/initializer'
|
102
103
|
require 'lucid_component/native_component_constructor'
|
103
104
|
require 'lucid_component/event_handler'
|
@@ -121,6 +122,11 @@ else
|
|
121
122
|
require 'react/version'
|
122
123
|
require 'isomorfeus/config'
|
123
124
|
|
125
|
+
# props
|
126
|
+
require 'isomorfeus/props/validate_hash_proxy'
|
127
|
+
require 'isomorfeus/props/validator'
|
128
|
+
require 'lucid_prop_declaration/mixin'
|
129
|
+
|
124
130
|
Isomorfeus.env = ENV['RACK_ENV']
|
125
131
|
|
126
132
|
if Isomorfeus.production?
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Props
|
3
|
+
class ValidateHashProxy
|
4
|
+
DEFAULT_HASH = { required: true, validate: {} }
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@validation_hash = DEFAULT_HASH
|
8
|
+
end
|
9
|
+
|
10
|
+
def is
|
11
|
+
self
|
12
|
+
end
|
13
|
+
alias_method :and, :is
|
14
|
+
alias_method :has, :is
|
15
|
+
alias_method :with, :is
|
16
|
+
|
17
|
+
def cast
|
18
|
+
@validation_hash[:cast] = true
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def default(v)
|
23
|
+
@validation_hash[:required] = false
|
24
|
+
@validation_hash[:default] = v
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def ensure(v = nil, &block)
|
29
|
+
if block_given?
|
30
|
+
@validation_hash[:ensure_block] = block
|
31
|
+
else
|
32
|
+
@validation_hash[:ensure] = v
|
33
|
+
end
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def exact_class(t_class)
|
38
|
+
@validation_hash[:class] = t_class
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def greater_than(v)
|
43
|
+
@validation_hash[:validate][:gt] = v
|
44
|
+
self
|
45
|
+
end
|
46
|
+
alias_method :gt, :greater_than
|
47
|
+
|
48
|
+
def is_a(i_class)
|
49
|
+
@validation_hash[:is_a] = i_class
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def keys(*keys)
|
54
|
+
@validation_hash[:validate][:hash_keys] = keys
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def size(l)
|
59
|
+
@validation_hash[:validate][:size] = v
|
60
|
+
self
|
61
|
+
end
|
62
|
+
alias_method :length, :size
|
63
|
+
|
64
|
+
def less_than(v)
|
65
|
+
@validation_hash[:validate][:lt] = v
|
66
|
+
self
|
67
|
+
end
|
68
|
+
alias_method :lt, :less_than
|
69
|
+
|
70
|
+
def matches(regexp)
|
71
|
+
@validation_hash[:validate][:matches] = regexp
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def max(l)
|
76
|
+
@validation_hash[:validate][:max] = l
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
def max_size(l)
|
81
|
+
@validation_hash[:validate][:max_size] = l
|
82
|
+
self
|
83
|
+
end
|
84
|
+
alias_method :max_length, :max_size
|
85
|
+
|
86
|
+
def min(l)
|
87
|
+
@validation_hash[:validate][:min] = l
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def min_size(l)
|
92
|
+
@validation_hash[:validate][:min_size] = l
|
93
|
+
self
|
94
|
+
end
|
95
|
+
alias_method :min_length, :min_size
|
96
|
+
|
97
|
+
def negative
|
98
|
+
@validation_hash[:validate][:direction] = :negative
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
def optional
|
103
|
+
@validation_hash[:required] = false
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def positive
|
108
|
+
@validation_hash[:validate][:direction] = :positive
|
109
|
+
self
|
110
|
+
end
|
111
|
+
|
112
|
+
def required
|
113
|
+
@validation_hash[:required] = true
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
def test(&block)
|
118
|
+
@validation_hash[:validate][:test] = block
|
119
|
+
self
|
120
|
+
end
|
121
|
+
alias_method :condition, :test
|
122
|
+
alias_method :check, :test
|
123
|
+
|
124
|
+
# types
|
125
|
+
|
126
|
+
def Array
|
127
|
+
@validation_hash[:class] = Array
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
def Boolean
|
132
|
+
@validation_hash[:type] = :boolean
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
def Enumerable
|
137
|
+
@validation_hash[:is_a] = Enumerable
|
138
|
+
self
|
139
|
+
end
|
140
|
+
|
141
|
+
def Float
|
142
|
+
@validation_hash[:class] = Float
|
143
|
+
self
|
144
|
+
end
|
145
|
+
|
146
|
+
def Hash
|
147
|
+
@validation_hash[:class] = Hash
|
148
|
+
self
|
149
|
+
end
|
150
|
+
|
151
|
+
def Integer
|
152
|
+
@validation_hash[:class] = Integer
|
153
|
+
self
|
154
|
+
end
|
155
|
+
|
156
|
+
def String
|
157
|
+
@validation_hash[:class] = String
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
# sub types
|
162
|
+
|
163
|
+
def Email
|
164
|
+
@validation_hash[:type] = :string
|
165
|
+
@validation_hash[:validate][:sub_type] = :email
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
def Url
|
170
|
+
@validation_hash[:type] = :string
|
171
|
+
@validation_hash[:validate][:sub_type] = :url
|
172
|
+
self
|
173
|
+
end
|
174
|
+
|
175
|
+
def to_h
|
176
|
+
@validation_hash
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Props
|
3
|
+
class Validator
|
4
|
+
def intialize(source_class, prop, value, options)
|
5
|
+
@c = source_class
|
6
|
+
@p = prop
|
7
|
+
@v = value
|
8
|
+
@o = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate!
|
12
|
+
ensured = ensure!
|
13
|
+
unless ensured
|
14
|
+
cast!
|
15
|
+
type!
|
16
|
+
end
|
17
|
+
run_checks!
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# basic tests
|
24
|
+
|
25
|
+
def cast!
|
26
|
+
if @o.key?(:cast)
|
27
|
+
begin
|
28
|
+
@v = case @o[:class]
|
29
|
+
when Integer then value.to_i
|
30
|
+
when String then value.to_s
|
31
|
+
when Float then value.to_f
|
32
|
+
when Array then value.to_a
|
33
|
+
when Hash then value.to_h
|
34
|
+
end
|
35
|
+
@v = !!@v if @o[:type] == :boolean
|
36
|
+
rescue
|
37
|
+
raise "#{@c}: #{@p} cast failed" unless value.class == @o[:class]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def ensure!
|
43
|
+
if @o.key?(:ensure)
|
44
|
+
@v = @o[:ensure] unless @v
|
45
|
+
true
|
46
|
+
elsif @o.key?(:ensure_block)
|
47
|
+
@v = @o[:ensure_block].call(@v)
|
48
|
+
true
|
49
|
+
else
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def type!
|
55
|
+
if @o.key?(:class)
|
56
|
+
raise "#{@c}: #{@p} class not #{@o[:class]}" unless value.class == @o[:class]
|
57
|
+
elsif @o.key?(:is_a)
|
58
|
+
raise "#{@c}: #{@p} is not a #{@o[:is_a]}" unless value.is_a?(@o[:is_a])
|
59
|
+
elsif @o.key?(:type)
|
60
|
+
case @o[:type]
|
61
|
+
when :boolean
|
62
|
+
raise "#{@c}: #{@p} is not a boolean" unless value.class == TrueClass || value.class == FalseClass
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# all other checks
|
68
|
+
|
69
|
+
def run_checks!
|
70
|
+
@o[:validate].each do |m, l|
|
71
|
+
send('c_' + m, l)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# specific validations
|
76
|
+
def c_gt(v)
|
77
|
+
raise "#{@c}: #{@p} not greater than #{v}!" unless @v > v
|
78
|
+
end
|
79
|
+
|
80
|
+
def c_lt(v)
|
81
|
+
raise "#{@c}: #{@p} not less than #{v}!" unless @v < v
|
82
|
+
end
|
83
|
+
|
84
|
+
def c_keys(v)
|
85
|
+
raise "#{@c}: #{@p} keys dont fit!" unless @v.keys.sort == v.sort
|
86
|
+
end
|
87
|
+
|
88
|
+
def c_size(v)
|
89
|
+
raise "#{@c}: #{@p} length/size is not #{v}" unless @v.size == v
|
90
|
+
end
|
91
|
+
|
92
|
+
def c_matches(v)
|
93
|
+
raise "#{@c}: #{@p} does not match #{v}" unless v.matches?(@v)
|
94
|
+
end
|
95
|
+
|
96
|
+
def c_max(v)
|
97
|
+
raise "#{@c}: #{@p} is larger than #{v}" unless @v <= v
|
98
|
+
end
|
99
|
+
|
100
|
+
def c_min(v)
|
101
|
+
raise "#{@c}: #{@p} is smaller than #{v}" unless @v >= v
|
102
|
+
end
|
103
|
+
|
104
|
+
def c_max_size(v)
|
105
|
+
raise "#{@c}: #{@p} is larger than #{v}" unless @v.size <= v
|
106
|
+
end
|
107
|
+
|
108
|
+
def c_min_size(v)
|
109
|
+
raise "#{@c}: #{@p} is smaller than #{v}" unless @v.size >= v
|
110
|
+
end
|
111
|
+
|
112
|
+
def c_direction(v)
|
113
|
+
raise "#{@c}: #{@p} is positive" if v == :negative && @v >= 0
|
114
|
+
raise "#{@c}: #{@p} is negative" if v == :positive && @v < 0
|
115
|
+
end
|
116
|
+
|
117
|
+
def c_test
|
118
|
+
raise "#{@c}: #{@p} test condition check failed" unless @o[:test].call(@v)
|
119
|
+
end
|
120
|
+
|
121
|
+
def c_sub_type(v)
|
122
|
+
case v
|
123
|
+
when :email
|
124
|
+
when :url
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/lucid_app/mixin.rb
CHANGED
@@ -3,7 +3,7 @@ module LucidApp
|
|
3
3
|
def self.included(base)
|
4
4
|
base.include(::Native::Wrapper)
|
5
5
|
base.extend(::LucidApp::NativeComponentConstructor)
|
6
|
-
base.extend(::
|
6
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
7
7
|
base.extend(::React::Component::ShouldComponentUpdate)
|
8
8
|
base.extend(::React::Component::EventHandler)
|
9
9
|
base.include(::React::Component::Elements)
|
@@ -74,6 +74,11 @@ module LucidApp
|
|
74
74
|
componentWillUnmount() {
|
75
75
|
if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
|
76
76
|
}
|
77
|
+
validateProp(props, propName, componentName) {
|
78
|
+
try { base.$validate_prop(propName, props[propName]) }
|
79
|
+
catch (e) { return new Error(componentName + ": Error: prop validation failed: " + e.message); }
|
80
|
+
return null;
|
81
|
+
}
|
77
82
|
}
|
78
83
|
}
|
79
84
|
end
|
@@ -3,13 +3,12 @@ module LucidComponent
|
|
3
3
|
def self.included(base)
|
4
4
|
base.include(::Native::Wrapper)
|
5
5
|
base.extend(::LucidComponent::NativeComponentConstructor)
|
6
|
-
base.extend(::
|
6
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
7
7
|
base.extend(::LucidComponent::EventHandler)
|
8
8
|
base.include(::React::Component::Elements)
|
9
9
|
base.include(::React::Component::API)
|
10
10
|
base.include(::React::Component::Callbacks)
|
11
11
|
base.include(::LucidComponent::StoreAPI)
|
12
|
-
base.include(::LucidComponent::API)
|
13
12
|
base.include(::LucidComponent::Initializer)
|
14
13
|
base.include(::React::Component::Features)
|
15
14
|
base.include(::React::Component::Resolution)
|
@@ -123,27 +123,8 @@ module LucidComponent
|
|
123
123
|
return false;
|
124
124
|
}
|
125
125
|
validateProp(props, propName, componentName) {
|
126
|
-
|
127
|
-
|
128
|
-
if (!prop_data) { return true; };
|
129
|
-
var value = props[propName];
|
130
|
-
var result;
|
131
|
-
if (typeof prop_data.ruby_class != "undefined") {
|
132
|
-
result = (value.$class() == prop_data.ruby_class);
|
133
|
-
if (!result) {
|
134
|
-
return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
|
135
|
-
}
|
136
|
-
} else if (typeof prop_data.is_a != "undefined") {
|
137
|
-
result = value["$is_a?"](prop_data.is_a);
|
138
|
-
if (!result) {
|
139
|
-
return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
|
140
|
-
}
|
141
|
-
}
|
142
|
-
if (typeof prop_data.required != "undefined") {
|
143
|
-
if (prop_data.required && (typeof props[propName] == "undefined")) {
|
144
|
-
return new Error('Prop ' + propName + ' is required but not given!');
|
145
|
-
}
|
146
|
-
}
|
126
|
+
try { base.$validate_prop(propName, props[propName]) }
|
127
|
+
catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
|
147
128
|
return null;
|
148
129
|
}
|
149
130
|
}
|
@@ -4,6 +4,7 @@ module LucidMaterial
|
|
4
4
|
def self.included(base)
|
5
5
|
base.include(::Native::Wrapper)
|
6
6
|
base.extend(::LucidMaterial::App::NativeComponentConstructor)
|
7
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
7
8
|
base.extend(::React::Component::ShouldComponentUpdate)
|
8
9
|
base.extend(::LucidComponent::EventHandler)
|
9
10
|
base.include(::React::Component::Elements)
|
@@ -77,27 +77,8 @@ module LucidMaterial
|
|
77
77
|
if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
|
78
78
|
}
|
79
79
|
validateProp(props, propName, componentName) {
|
80
|
-
|
81
|
-
|
82
|
-
if (!prop_data) { return true; };
|
83
|
-
var value = props[propName];
|
84
|
-
var result;
|
85
|
-
if (typeof prop_data.ruby_class != "undefined") {
|
86
|
-
result = (value.$class() == prop_data.ruby_class);
|
87
|
-
if (!result) {
|
88
|
-
return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
|
89
|
-
}
|
90
|
-
} else if (typeof prop_data.is_a != "undefined") {
|
91
|
-
result = value["$is_a?"](prop_data.is_a);
|
92
|
-
if (!result) {
|
93
|
-
return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
|
94
|
-
}
|
95
|
-
}
|
96
|
-
if (typeof prop_data.required != "undefined") {
|
97
|
-
if (prop_data.required && (typeof props[propName] == "undefined")) {
|
98
|
-
return new Error('Prop ' + propName + ' is required but not given!');
|
99
|
-
}
|
100
|
-
}
|
80
|
+
try { base.$validate_prop(propName, props[propName]) }
|
81
|
+
catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
|
101
82
|
return null;
|
102
83
|
}
|
103
84
|
}
|
@@ -4,13 +4,12 @@ module LucidMaterial
|
|
4
4
|
def self.included(base)
|
5
5
|
base.include(::Native::Wrapper)
|
6
6
|
base.extend(::LucidMaterial::Component::NativeComponentConstructor)
|
7
|
-
base.extend(::
|
7
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
8
8
|
base.extend(::LucidComponent::EventHandler)
|
9
9
|
base.include(::React::Component::Elements)
|
10
10
|
base.include(::React::Component::API)
|
11
11
|
base.include(::React::Component::Callbacks)
|
12
12
|
base.include(::LucidComponent::StoreAPI)
|
13
|
-
base.include(::LucidComponent::API)
|
14
13
|
base.include(::LucidMaterial::Component::API)
|
15
14
|
base.include(::LucidComponent::Initializer)
|
16
15
|
base.include(::React::Component::Features)
|
@@ -119,27 +119,8 @@ module LucidMaterial
|
|
119
119
|
return false;
|
120
120
|
}
|
121
121
|
validateProp(props, propName, componentName) {
|
122
|
-
|
123
|
-
|
124
|
-
if (!prop_data) { return true; };
|
125
|
-
var value = props[propName];
|
126
|
-
var result;
|
127
|
-
if (typeof prop_data.ruby_class != "undefined") {
|
128
|
-
result = (value.$class() == prop_data.ruby_class);
|
129
|
-
if (!result) {
|
130
|
-
return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
|
131
|
-
}
|
132
|
-
} else if (typeof prop_data.is_a != "undefined") {
|
133
|
-
result = value["$is_a?"](prop_data.is_a);
|
134
|
-
if (!result) {
|
135
|
-
return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
|
136
|
-
}
|
137
|
-
}
|
138
|
-
if (typeof prop_data.required != "undefined") {
|
139
|
-
if (prop_data.required && (typeof props[propName] == "undefined")) {
|
140
|
-
return new Error('Prop ' + propName + ' is required but not given!');
|
141
|
-
}
|
142
|
-
}
|
122
|
+
try { base.$validate_prop(propName, props[propName]) }
|
123
|
+
catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
|
143
124
|
return null;
|
144
125
|
}
|
145
126
|
};
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module LucidPropDeclaration
|
2
|
+
module Mixin
|
3
|
+
if RUBY_ENGINE == 'opal'
|
4
|
+
def self.extended(base)
|
5
|
+
|
6
|
+
def prop(prop_name, validate_hash = { required: true })
|
7
|
+
validate_hash = validate_hash.to_h if validate_hash.class == Isomorfeus::Props::ValidateHashProxy
|
8
|
+
if validate_hash.key?(:default)
|
9
|
+
%x{
|
10
|
+
if (base.lucid_react_component) {
|
11
|
+
let react_prop_name = Opal.React.lower_camelize(prop_name);
|
12
|
+
#{value = validate_hash[:default]}
|
13
|
+
if (!base.lucid_react_component.defaultProps) { base.lucid_react_component.defaultProps = {}; }
|
14
|
+
base.lucid_react_component.defaultProps[react_prop_name] = value;
|
15
|
+
if (!base.lucid_react_component.propTypes) { base.lucid_react_component.propTypes = {}; }
|
16
|
+
base.lucid_react_component.propTypes[react_prop_name] = base.lucid_react_component.prototype.validateProp;
|
17
|
+
} else if (base.react_component) {
|
18
|
+
let react_prop_name = Opal.React.lower_camelize(prop_name);
|
19
|
+
#{value = validate_hash[:default]}
|
20
|
+
if (!base.react_component.defaultProps) { base.react_component.defaultProps = {}; }
|
21
|
+
base.react_component.defaultProps[react_prop_name] = value;
|
22
|
+
if (!base.react_component.propTypes) { base.react_component.propTypes = {}; }
|
23
|
+
base.react_component.propTypes[react_prop_name] = base.react_component.prototype.validateProp;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
end
|
27
|
+
declared_props[prop_name.to_sym] = validate_hash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_function
|
32
|
+
%x{
|
33
|
+
if (typeof base.validate_function === 'undefined') {
|
34
|
+
base.validate_function = function(props_object) {
|
35
|
+
return base.$validate_props(`Opal.Hash.new(props_object)`)
|
36
|
+
}
|
37
|
+
}
|
38
|
+
return base.validate_function;
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate_prop_function(prop)
|
43
|
+
function_name = "validate_#{prop}_function"
|
44
|
+
%x{
|
45
|
+
if (typeof base[function_name] === 'undefined') {
|
46
|
+
base[function_name] = function(value) {
|
47
|
+
return base.$validate_prop(prop, value);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
return base[function_name];
|
51
|
+
}
|
52
|
+
end
|
53
|
+
else
|
54
|
+
def prop(prop_name, validate_hash = { required: true })
|
55
|
+
validate_hash = validate_hash.to_h if validate_hash.class == Isomorfeus::Props::ValidateHashProxy
|
56
|
+
declared_props[prop_name.to_sym] = validate_hash
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def declared_props
|
61
|
+
@declared_props ||= {}
|
62
|
+
end
|
63
|
+
|
64
|
+
def validate
|
65
|
+
Isomorfeus::Props::ValidateHashProxy.new
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_prop(prop, value)
|
69
|
+
return false unless declared_props.key?(prop)
|
70
|
+
validator = Isomorfeus::Props::Validator.new(self, prop, value, declared_props[prop])
|
71
|
+
validator.validate!
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def validate_props(props)
|
76
|
+
declared_props.each_key do |prop|
|
77
|
+
if declared_props[prop].key?(:required) && declared_props[prop][:required] && !props.key?[prop]
|
78
|
+
raise "Required prop #{prop} not given!"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
result = true
|
82
|
+
props.each do |p, v|
|
83
|
+
r = validate_prop(p, v)
|
84
|
+
result = false unless r
|
85
|
+
end
|
86
|
+
result
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/react/component/api.rb
CHANGED
@@ -44,57 +44,6 @@ module React
|
|
44
44
|
@default_state = React::Component::State.new(`native_state`)
|
45
45
|
end
|
46
46
|
|
47
|
-
def prop(name, options = `null`)
|
48
|
-
name = `Opal.React.lower_camelize(name)`
|
49
|
-
if options
|
50
|
-
if options.key?(:default)
|
51
|
-
%x{
|
52
|
-
if (typeof self.react_component.defaultProps == "undefined") {
|
53
|
-
self.react_component.defaultProps = {};
|
54
|
-
}
|
55
|
-
self.react_component.defaultProps[name] = options.$fetch("default");
|
56
|
-
}
|
57
|
-
end
|
58
|
-
if options.key?(:class)
|
59
|
-
%x{
|
60
|
-
Opal.React.set_validate_prop(self, name);
|
61
|
-
self.react_component.propValidations[name].ruby_class = options.$fetch("class");
|
62
|
-
}
|
63
|
-
elsif options.key?(:is_a)
|
64
|
-
%x{
|
65
|
-
Opal.React.set_validate_prop(self, name);
|
66
|
-
self.react_component.propValidations[name].is_a = options.$fetch("is_a");
|
67
|
-
}
|
68
|
-
end
|
69
|
-
if options.key?(:required)
|
70
|
-
%x{
|
71
|
-
Opal.React.set_validate_prop(self, name);
|
72
|
-
self.react_component.propValidations[name].required = options.$fetch("required");
|
73
|
-
}
|
74
|
-
elsif !options.key?(:default)
|
75
|
-
%x{
|
76
|
-
Opal.React.set_validate_prop(self, name);
|
77
|
-
self.react_component.propValidations[name].required = true;
|
78
|
-
}
|
79
|
-
end
|
80
|
-
else
|
81
|
-
%x{
|
82
|
-
Opal.React.set_validate_prop(self, name);
|
83
|
-
self.react_component.propValidations[name].required = true;
|
84
|
-
}
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def default_props
|
89
|
-
return @default_props if @default_props
|
90
|
-
%x{
|
91
|
-
if (typeof self.react_component.defaultProps == "undefined") {
|
92
|
-
self.lucid_react_component.defaultProps = {};
|
93
|
-
}
|
94
|
-
}
|
95
|
-
@default_props = `Opal.React.Component.Props.$new({props: self.react_component.defaultProps})`
|
96
|
-
end
|
97
|
-
|
98
47
|
def render(&block)
|
99
48
|
`base.render_block = block`
|
100
49
|
end
|
@@ -4,13 +4,12 @@ module React
|
|
4
4
|
def self.included(base)
|
5
5
|
base.include(::Native::Wrapper)
|
6
6
|
base.extend(::React::Component::NativeComponentConstructor)
|
7
|
-
base.extend(::
|
7
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
8
8
|
base.extend(::React::Component::ShouldComponentUpdate)
|
9
9
|
base.extend(::React::Component::EventHandler)
|
10
10
|
base.include(::React::Component::Elements)
|
11
11
|
base.include(::React::Component::API)
|
12
12
|
base.include(::React::Component::Callbacks)
|
13
|
-
# base.include(::React::Component::UnsafeAPI)
|
14
13
|
base.include(::React::Component::Initializer)
|
15
14
|
base.include(::React::Component::Features)
|
16
15
|
base.include(::React::Component::Resolution)
|
@@ -80,6 +80,11 @@ module React
|
|
80
80
|
return false;
|
81
81
|
}
|
82
82
|
}
|
83
|
+
validateProp(props, propName, componentName) {
|
84
|
+
try { base.$validate_prop(propName, props[propName]) }
|
85
|
+
catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
|
86
|
+
return null;
|
87
|
+
}
|
83
88
|
}
|
84
89
|
}
|
85
90
|
end
|
@@ -4,12 +4,11 @@ module React
|
|
4
4
|
def self.included(base)
|
5
5
|
base.include(::Native::Wrapper)
|
6
6
|
base.extend(::React::Component::NativeComponentConstructor)
|
7
|
-
base.extend(::
|
7
|
+
base.extend(::LucidPropDeclaration::Mixin)
|
8
8
|
base.extend(::React::Component::EventHandler)
|
9
9
|
base.include(::React::Component::Elements)
|
10
10
|
base.include(::React::Component::API)
|
11
11
|
base.include(::React::Component::Callbacks)
|
12
|
-
# base.include(::React::Component::UnsafeAPI)
|
13
12
|
base.include(::React::Component::Initializer)
|
14
13
|
base.include(::React::Component::Features)
|
15
14
|
base.include(::React::Component::Resolution)
|
data/lib/react/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isomorfeus-react
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 16.9.
|
4
|
+
version: 16.9.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -170,6 +170,8 @@ files:
|
|
170
170
|
- lib/isomorfeus-react.rb
|
171
171
|
- lib/isomorfeus/config.rb
|
172
172
|
- lib/isomorfeus/execution_environment.rb
|
173
|
+
- lib/isomorfeus/props/validate_hash_proxy.rb
|
174
|
+
- lib/isomorfeus/props/validator.rb
|
173
175
|
- lib/isomorfeus/react_view_helper.rb
|
174
176
|
- lib/isomorfeus/top_level_browser.rb
|
175
177
|
- lib/isomorfeus/top_level_ssr.rb
|
@@ -178,7 +180,6 @@ files:
|
|
178
180
|
- lib/lucid_app/context.rb
|
179
181
|
- lib/lucid_app/mixin.rb
|
180
182
|
- lib/lucid_app/native_component_constructor.rb
|
181
|
-
- lib/lucid_component/api.rb
|
182
183
|
- lib/lucid_component/app_store_defaults.rb
|
183
184
|
- lib/lucid_component/app_store_proxy.rb
|
184
185
|
- lib/lucid_component/base.rb
|
@@ -199,6 +200,7 @@ files:
|
|
199
200
|
- lib/lucid_material/component/base.rb
|
200
201
|
- lib/lucid_material/component/mixin.rb
|
201
202
|
- lib/lucid_material/component/native_component_constructor.rb
|
203
|
+
- lib/lucid_prop_declaration/mixin.rb
|
202
204
|
- lib/react.rb
|
203
205
|
- lib/react/active_support_support.rb
|
204
206
|
- lib/react/children.rb
|
@@ -214,7 +216,6 @@ files:
|
|
214
216
|
- lib/react/component/match.rb
|
215
217
|
- lib/react/component/mixin.rb
|
216
218
|
- lib/react/component/native_component_constructor.rb
|
217
|
-
- lib/react/component/native_component_validate_prop.rb
|
218
219
|
- lib/react/component/props.rb
|
219
220
|
- lib/react/component/resolution.rb
|
220
221
|
- lib/react/component/should_component_update.rb
|
data/lib/lucid_component/api.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
module LucidComponent
|
2
|
-
module API
|
3
|
-
def self.included(base)
|
4
|
-
base.instance_exec do
|
5
|
-
def prop(name, options = `null`)
|
6
|
-
name = `Opal.React.lower_camelize(name)`
|
7
|
-
if options
|
8
|
-
if options.key?(:default)
|
9
|
-
%x{
|
10
|
-
if (typeof self.lucid_react_component.defaultProps == "undefined") {
|
11
|
-
self.lucid_react_component.defaultProps = { isomorfeus_store: Opal.Hash.$new() };
|
12
|
-
}
|
13
|
-
self.lucid_react_component.defaultProps[name] = options.$fetch("default");
|
14
|
-
}
|
15
|
-
end
|
16
|
-
if options.key?(:class)
|
17
|
-
%x{
|
18
|
-
if (typeof self.lucid_react_component.propTypes == "undefined") {
|
19
|
-
self.lucid_react_component.propTypes = {};
|
20
|
-
self.lucid_react_component.propValidations = {};
|
21
|
-
self.lucid_react_component.propValidations[name] = {};
|
22
|
-
}
|
23
|
-
self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
|
24
|
-
self.lucid_react_component.propValidations[name].ruby_class = options.$fetch("class");
|
25
|
-
}
|
26
|
-
elsif options.key?(:is_a)
|
27
|
-
%x{
|
28
|
-
if (typeof self.lucid_react_component.propTypes == "undefined") {
|
29
|
-
self.lucid_react_component.propTypes = {};
|
30
|
-
self.lucid_react_component.propValidations = {};
|
31
|
-
self.lucid_react_component.propValidations[name] = {};
|
32
|
-
}
|
33
|
-
self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
|
34
|
-
self.lucid_react_component.propValidations[name].is_a = options.$fetch("is_a");
|
35
|
-
}
|
36
|
-
end
|
37
|
-
if options.key?(:required)
|
38
|
-
%x{
|
39
|
-
if (typeof self.lucid_react_component.propTypes == "undefined") {
|
40
|
-
self.lucid_react_component.propTypes = {};
|
41
|
-
self.lucid_react_component.propValidations = {};
|
42
|
-
self.lucid_react_component.propValidations[name] = {};
|
43
|
-
}
|
44
|
-
self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
|
45
|
-
self.lucid_react_component.propValidations[name].required = options.$fetch("required");
|
46
|
-
}
|
47
|
-
elsif !options.key?(:default)
|
48
|
-
%x{
|
49
|
-
if (typeof self.lucid_react_component.propTypes == "undefined") {
|
50
|
-
self.lucid_react_component.propTypes = {};
|
51
|
-
self.lucid_react_component.propValidations = {};
|
52
|
-
}
|
53
|
-
self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
|
54
|
-
self.lucid_react_component.propValidations[name].required = true;
|
55
|
-
}
|
56
|
-
end
|
57
|
-
else
|
58
|
-
%x{
|
59
|
-
if (typeof self.lucid_react_component.propTypes == "undefined") {
|
60
|
-
self.lucid_react_component.propTypes = {};
|
61
|
-
self.lucid_react_component.propValidations = {};
|
62
|
-
self.lucid_react_component.propValidations[name] = {};
|
63
|
-
}
|
64
|
-
self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
|
65
|
-
self.lucid_react_component.propValidations[name].required = true;
|
66
|
-
}
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def default_props
|
71
|
-
return @default_props if @default_props
|
72
|
-
%x{
|
73
|
-
if (typeof self.lucid_react_component.defaultProps == "undefined") {
|
74
|
-
self.lucid_react_component.defaultProps = { isomorfeus_store: Opal.Hash.$new() };
|
75
|
-
}
|
76
|
-
}
|
77
|
-
@default_props = React::Component::Props.new(`{props: self.lucid_react_component.defaultProps}`)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module React
|
2
|
-
module Component
|
3
|
-
module NativeComponentValidateProp
|
4
|
-
# for should_component_update we apply ruby semantics for comparing props
|
5
|
-
# to do so, we convert the props to ruby hashes and then compare
|
6
|
-
# this makes sure, that for example rubys Nil object gets handled properly
|
7
|
-
def self.extended(base)
|
8
|
-
# language=JS
|
9
|
-
%x{
|
10
|
-
base.react_component.prototype.validateProp = function(props, propName, componentName) {
|
11
|
-
var prop_data = base.react_component.propValidations[propName];
|
12
|
-
if (!prop_data) { return true; };
|
13
|
-
var value = props[propName];
|
14
|
-
var result;
|
15
|
-
if (typeof prop_data.ruby_class != "undefined") {
|
16
|
-
result = (value.$class() == prop_data.ruby_class);
|
17
|
-
if (!result) {
|
18
|
-
return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
|
19
|
-
}
|
20
|
-
} else if (typeof prop_data.is_a != "undefined") {
|
21
|
-
result = value["$is_a?"](prop_data.is_a);
|
22
|
-
if (!result) {
|
23
|
-
return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
|
24
|
-
}
|
25
|
-
}
|
26
|
-
if (typeof prop_data.required != "undefined") {
|
27
|
-
if (prop_data.required && (typeof props[propName] == "undefined")) {
|
28
|
-
return new Error('Prop ' + propName + ' is required but not given!');
|
29
|
-
}
|
30
|
-
}
|
31
|
-
return null;
|
32
|
-
}
|
33
|
-
}
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|