typero 0.9.5 → 0.9.9
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/.version +1 -1
- data/lib/adapters/sequel.rb +33 -24
- data/lib/typero/{params.rb → define.rb} +38 -22
- data/lib/typero/schema.rb +77 -19
- data/lib/typero/type/type.rb +10 -4
- data/lib/typero/type/types/currency_type.rb +3 -0
- data/lib/typero/type/types/date_type.rb +8 -3
- data/lib/typero/type/types/datetime_type.rb +8 -2
- data/lib/typero/type/types/float_type.rb +4 -6
- data/lib/typero/type/types/hash_type.rb +2 -2
- data/lib/typero/type/types/image_type.rb +3 -1
- data/lib/typero/type/types/integer_type.rb +1 -1
- data/lib/typero/type/types/model_type.rb +1 -1
- data/lib/typero/type/types/oib_type.rb +1 -1
- data/lib/typero/type/types/point_type.rb +1 -1
- data/lib/typero/type/types/simple_point_type.rb +2 -0
- data/lib/typero/type/types/string_type.rb +2 -2
- data/lib/typero/type/types/text_type.rb +10 -2
- data/lib/typero/type/types/url_type.rb +1 -2
- data/lib/typero/typero.rb +23 -61
- data/lib/typero.rb +1 -1
- metadata +5 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb6ff45894808ab507b69280a5c0789b1a370aadfc8aa9e02a4d246080dd2b7c
|
|
4
|
+
data.tar.gz: 4e7a1e952d836c72e4bcdb042335e61fcf7b123ab9b9a952f05c7d12f6a12ee5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 45688f02580d891eb335d0eea0fbd56a4572f2571da2859c6dbc29253b848334640c6748ccd4fba3428b2a22309c3ad8ec1d21d2a42bc5da623d70785bc673dc
|
|
7
|
+
data.tar.gz: cfd0091edbc1b7f30c6fcd3a8ba4e0cb6965b8389405abadaaac1b6b2fa0040fe0c39123d5d74c19c497446f42a40bc4110d4a95f54462867366edd27ee1a55d
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.9.
|
|
1
|
+
0.9.9
|
data/lib/adapters/sequel.rb
CHANGED
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module Sequel::Plugins::Typero
|
|
4
4
|
module ClassMethods
|
|
5
|
-
def
|
|
6
|
-
|
|
5
|
+
def schema name = nil, &block
|
|
6
|
+
name ||= self
|
|
7
|
+
name = name.to_s.underscore.singularize
|
|
8
|
+
value = Typero.schema name, type: :model, &block
|
|
9
|
+
|
|
10
|
+
if ENV['DB_MIGRATE'] == 'true' && defined?(AutoMigrate)
|
|
11
|
+
AutoMigrate.apply_schema self
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
value
|
|
7
15
|
end
|
|
8
16
|
end
|
|
9
17
|
|
|
@@ -12,31 +20,32 @@ module Sequel::Plugins::Typero
|
|
|
12
20
|
def validate
|
|
13
21
|
super
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
# Typero schema check
|
|
24
|
+
if schema = Typero.schema?(self.class)
|
|
25
|
+
schema.validate(self) do |name, err|
|
|
26
|
+
errors.add(name, err) unless (errors.on(name) || []).include?(err)
|
|
27
|
+
end
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
# this are rules unique to database, so we check them here
|
|
30
|
+
schema.rules.each do |field, rule|
|
|
31
|
+
# check uniqe fields
|
|
32
|
+
if unique = rule.dig(:meta, :unique)
|
|
33
|
+
id = self[:id] || 0
|
|
34
|
+
value = self[field]
|
|
35
|
+
|
|
36
|
+
# we only check if field is changed
|
|
37
|
+
if value.present? && column_changed?(field) && self.class.xwhere("LOWER(%s)=LOWER(?) and #{respond_to?(:ref) ? :ref : :id}::text<>?" % [field], value, id.to_s).first
|
|
38
|
+
error = unique.class == TrueClass ? %[Value "#{value}" for field "#{field}" has been already used, please chose another value.] : unique
|
|
39
|
+
errors.add(field, error) unless (errors.on(field) || []).include?(error)
|
|
40
|
+
end
|
|
32
41
|
end
|
|
33
|
-
end
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
# check protected fields
|
|
44
|
+
if (prot = rule.dig(:meta, :protected)) && self[:id]
|
|
45
|
+
if column_changed?(field)
|
|
46
|
+
error = prot.class == TrueClass ? "value once defined can't be overwritten." : prot
|
|
47
|
+
errors.add(field, error) unless (errors.on(field) || []).include?(error)
|
|
48
|
+
end
|
|
40
49
|
end
|
|
41
50
|
end
|
|
42
51
|
end
|
|
@@ -1,13 +1,33 @@
|
|
|
1
|
-
# Base class for schema validation
|
|
1
|
+
# Base class for schema validation, this loads and defined schema.
|
|
2
|
+
# Accepts set of params and returns hash of parsed rules
|
|
3
|
+
|
|
4
|
+
# module Typero
|
|
5
|
+
# class Loader
|
|
6
|
+
# def timestamps
|
|
7
|
+
# created_at Time
|
|
8
|
+
# created_by_ref
|
|
9
|
+
# end
|
|
10
|
+
# end
|
|
11
|
+
# end
|
|
12
|
+
|
|
13
|
+
# class Task < ApplicationModel
|
|
14
|
+
# schema do
|
|
15
|
+
# name # string type
|
|
16
|
+
# timestamps # metod defined -> call
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
|
|
20
|
+
require 'set'
|
|
21
|
+
require 'json'
|
|
2
22
|
|
|
3
23
|
module Typero
|
|
4
|
-
class
|
|
24
|
+
class Define
|
|
5
25
|
attr_reader :db_rules
|
|
6
26
|
|
|
7
|
-
def initialize &block
|
|
27
|
+
def initialize rules = nil, &block
|
|
8
28
|
@db_rules = []
|
|
9
|
-
@rules = {}
|
|
10
|
-
instance_exec &block
|
|
29
|
+
@rules = rules || {}
|
|
30
|
+
instance_exec &block if block
|
|
11
31
|
end
|
|
12
32
|
|
|
13
33
|
def rules
|
|
@@ -72,13 +92,13 @@ module Typero
|
|
|
72
92
|
opts[:default] = true
|
|
73
93
|
opts[:type] = :boolean
|
|
74
94
|
elsif opts[:type].is_a?(FalseClass) || opts[:type] == :false || opts[:type] == :boolean
|
|
75
|
-
opts[:required] = false
|
|
95
|
+
opts[:required] = false
|
|
76
96
|
opts[:default] = false if opts[:default].nil?
|
|
77
97
|
opts[:type] = :boolean
|
|
78
98
|
end
|
|
79
99
|
|
|
80
100
|
# model / schema
|
|
81
|
-
if opts[:type].
|
|
101
|
+
if opts[:type].is_a?(Typero::Schema)
|
|
82
102
|
opts[:model] = opts.delete(:type)
|
|
83
103
|
end
|
|
84
104
|
opts[:model] = opts.delete(:schema) if opts[:schema]
|
|
@@ -89,23 +109,21 @@ module Typero
|
|
|
89
109
|
opts[:model] = Typero.schema &block
|
|
90
110
|
end
|
|
91
111
|
|
|
92
|
-
opts[:type]
|
|
93
|
-
opts[:type] = opts[:type].to_s.downcase.to_sym
|
|
112
|
+
opts[:type] = opts[:type].to_s.downcase.to_sym
|
|
94
113
|
|
|
95
114
|
opts[:description] = opts.delete(:desc) unless opts[:desc].nil?
|
|
96
115
|
|
|
97
|
-
#
|
|
116
|
+
# check allowed params, all optional should go in meta
|
|
117
|
+
type = Typero::Type.load opts[:type]
|
|
98
118
|
opts.keys.each do |key|
|
|
99
|
-
type = Typero::Type.load opts[:type]
|
|
100
119
|
type.allowed_opt?(key) {|err| raise ArgumentError, err }
|
|
101
120
|
end
|
|
102
121
|
|
|
103
122
|
field = field.to_sym
|
|
104
123
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
Typero::Type.load opts[:type]
|
|
124
|
+
if opts.delete(:index)
|
|
125
|
+
db :add_index, field
|
|
126
|
+
end
|
|
109
127
|
|
|
110
128
|
@rules[field] = opts
|
|
111
129
|
end
|
|
@@ -114,16 +132,14 @@ module Typero
|
|
|
114
132
|
# db :timestamps
|
|
115
133
|
# db :add_index, :code -> t.add_index :code
|
|
116
134
|
def db *args
|
|
117
|
-
@db_rules.push args
|
|
135
|
+
@db_rules.push args.unshift(:db_rule!)
|
|
118
136
|
end
|
|
119
137
|
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
# set :emails, Array[:email]
|
|
124
|
-
# email Array[:emails]
|
|
138
|
+
# if method undefine, call set method
|
|
139
|
+
# age Integer -> set :age, type: :integer
|
|
140
|
+
# email Array[:emails] -> set :emails, Array[:email]
|
|
125
141
|
def method_missing field, *args, &block
|
|
126
142
|
set field, *args, &block
|
|
127
143
|
end
|
|
128
144
|
end
|
|
129
|
-
end
|
|
145
|
+
end
|
data/lib/typero/schema.rb
CHANGED
|
@@ -1,34 +1,90 @@
|
|
|
1
|
+
# Typero.schema :user, type: :model do
|
|
2
|
+
|
|
3
|
+
# Typero.schema :some_name, type: :model, db: DB_LOG do
|
|
4
|
+
# set :name, String, req: true
|
|
5
|
+
# set :email, :email, req: true
|
|
6
|
+
# set :emails, [:email], min: 2
|
|
7
|
+
# end
|
|
8
|
+
#
|
|
9
|
+
# rules = Typero.schema :some_name
|
|
10
|
+
#
|
|
11
|
+
# or
|
|
12
|
+
#
|
|
13
|
+
# rules = Typero.schema do
|
|
14
|
+
# string :name, req: true # generic email string
|
|
15
|
+
# email :email, req: true # string of type email
|
|
16
|
+
# emails [:skills], min: 2 # list of emails in filed named "emails"
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# errors = rules.validate (@object || @hash) {|errors| ... }
|
|
20
|
+
# rules.valid? (@object)
|
|
21
|
+
|
|
1
22
|
module Typero
|
|
2
23
|
class Schema
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
24
|
+
SCHEMA_STORE ||= {}
|
|
25
|
+
|
|
26
|
+
attr_reader :klass
|
|
27
|
+
attr_reader :schema
|
|
28
|
+
attr_reader :opts
|
|
29
|
+
|
|
30
|
+
# accepts dsl block to define schema
|
|
31
|
+
# or define: keyword for internal use (only/except)
|
|
32
|
+
def initialize name, opts = nil, define: nil, &block
|
|
33
|
+
@opts = opts || {}
|
|
34
|
+
|
|
35
|
+
if define
|
|
36
|
+
@schema = define
|
|
37
|
+
elsif block
|
|
38
|
+
@schema = Define.new &block
|
|
39
|
+
|
|
40
|
+
if name
|
|
41
|
+
@klass = name
|
|
42
|
+
SCHEMA_STORE[name] = self
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
raise "Use Typero.schema(:name) to load stored schema"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# returns new schema with only specified keys
|
|
50
|
+
def only *keys
|
|
51
|
+
keys = keys.map(&:to_sym)
|
|
52
|
+
filtered = rules.select { |k, _| keys.include?(k) }
|
|
53
|
+
self.class.new(nil, define: Define.new(filtered))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# returns new schema without specified keys
|
|
57
|
+
def except *keys
|
|
58
|
+
keys = keys.map(&:to_sym)
|
|
59
|
+
filtered = rules.reject { |k, _| keys.include?(k) }
|
|
60
|
+
self.class.new(nil, define: Define.new(filtered))
|
|
7
61
|
end
|
|
8
62
|
|
|
9
63
|
# validates any instance object with hash variable interface
|
|
10
|
-
# it also
|
|
11
|
-
def validate object, options=nil
|
|
12
|
-
@options = options || {}
|
|
64
|
+
# it also coerces values
|
|
65
|
+
def validate object, options = nil
|
|
13
66
|
@object = object
|
|
14
67
|
@errors = {}
|
|
68
|
+
options = options || {}
|
|
15
69
|
|
|
16
70
|
# remove undefined keys if Hash provided
|
|
17
|
-
if
|
|
71
|
+
if options[:strict] && object.is_a?(Hash)
|
|
18
72
|
undefined = object.keys.map(&:to_s) - @schema.rules.keys.map(&:to_s)
|
|
19
73
|
object.delete_if { |k, _| undefined.include?(k.to_s) }
|
|
20
74
|
end
|
|
21
75
|
|
|
22
76
|
@schema.rules.each do |field, opts|
|
|
23
|
-
# force
|
|
77
|
+
# force field as a symbol
|
|
24
78
|
field = field.to_sym
|
|
25
79
|
|
|
26
|
-
|
|
80
|
+
opts.keys.each do |k|
|
|
27
81
|
opts[k] = @object.instance_exec(&opts[k]) if opts[k].is_a?(Proc)
|
|
28
82
|
end
|
|
29
83
|
|
|
30
84
|
# set value to default if value is blank and default given
|
|
31
|
-
|
|
85
|
+
if !opts[:default].nil? && @object[field].to_s.blank?
|
|
86
|
+
@object[field] = opts[:default]
|
|
87
|
+
end
|
|
32
88
|
|
|
33
89
|
if @object.respond_to?(:key?)
|
|
34
90
|
if @object.key?(field)
|
|
@@ -49,7 +105,7 @@ module Typero
|
|
|
49
105
|
|
|
50
106
|
value = value
|
|
51
107
|
.flatten
|
|
52
|
-
.map { |el| el.to_s == '' ? nil :
|
|
108
|
+
.map { |el| el.to_s == '' ? nil : check_field_value(field, el, opts) }
|
|
53
109
|
.compact
|
|
54
110
|
|
|
55
111
|
value = Set.new(value).to_a unless opts[:duplicates]
|
|
@@ -68,7 +124,7 @@ module Typero
|
|
|
68
124
|
add_error field, 'Value "%s" is not allowed' % value, opts
|
|
69
125
|
end
|
|
70
126
|
|
|
71
|
-
value =
|
|
127
|
+
value = check_field_value field, value, opts
|
|
72
128
|
|
|
73
129
|
add_required_error field, value, opts
|
|
74
130
|
end
|
|
@@ -92,14 +148,14 @@ module Typero
|
|
|
92
148
|
# returns field, db_type, db_opts
|
|
93
149
|
def db_schema
|
|
94
150
|
out = @schema.rules.inject([]) do |total, (field, opts)|
|
|
95
|
-
# get db
|
|
151
|
+
# get db field schema
|
|
96
152
|
type, opts = Typero::Type.load(opts[:type]).new(nil, opts).db_field
|
|
97
153
|
|
|
98
|
-
# add array true to field
|
|
154
|
+
# add array true to field if not defined in schema
|
|
99
155
|
schema_opts = @schema.rules[field]
|
|
100
156
|
opts[:array] = true if schema_opts[:array]
|
|
101
157
|
|
|
102
|
-
total << [
|
|
158
|
+
total << [field, type, opts]
|
|
103
159
|
end
|
|
104
160
|
|
|
105
161
|
out += @schema.db_rules
|
|
@@ -107,7 +163,7 @@ module Typero
|
|
|
107
163
|
out
|
|
108
164
|
end
|
|
109
165
|
|
|
110
|
-
# iterate
|
|
166
|
+
# iterate through all the rules via block interface
|
|
111
167
|
# schema.rules do |field, opts|
|
|
112
168
|
# schema.rules(:url) do |field, opts|
|
|
113
169
|
def rules filter = nil, &block
|
|
@@ -146,18 +202,20 @@ module Typero
|
|
|
146
202
|
add_error field, msg, opts
|
|
147
203
|
end
|
|
148
204
|
|
|
149
|
-
def
|
|
205
|
+
def check_field_value field, value, opts
|
|
150
206
|
klass = "Typero::%sType" % safe_type(opts[:type])
|
|
151
207
|
check = klass.constantize.new value, opts
|
|
152
208
|
check.get
|
|
153
209
|
rescue TypeError => e
|
|
154
210
|
if e.message[0] == '{'
|
|
155
|
-
|
|
211
|
+
JSON.parse(e.message).each do |key, msg|
|
|
156
212
|
add_error [field, key].join('.'), msg, opts
|
|
157
213
|
end
|
|
158
214
|
else
|
|
159
215
|
add_error field, e.message, opts
|
|
160
216
|
end
|
|
217
|
+
rescue JSON::ParserError
|
|
218
|
+
add_error field, e.message, opts
|
|
161
219
|
end
|
|
162
220
|
end
|
|
163
221
|
end
|
data/lib/typero/type/type.rb
CHANGED
|
@@ -5,12 +5,12 @@ module Typero
|
|
|
5
5
|
ERRORS = {
|
|
6
6
|
en: {
|
|
7
7
|
# errors shared between various types
|
|
8
|
-
min_length_error: 'min
|
|
9
|
-
max_length_error: 'max
|
|
8
|
+
min_length_error: 'min length is %s, you have %s',
|
|
9
|
+
max_length_error: 'max length is %s, you have %s',
|
|
10
10
|
min_value_error: 'min is %s, got %s',
|
|
11
11
|
max_value_error: 'max is %s, got %s',
|
|
12
12
|
unallowed_characters_error: 'is having unallowed characters',
|
|
13
|
-
not_in_range: 'Value
|
|
13
|
+
not_in_range: 'Value is not in allowed range (%s)'
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -23,6 +23,8 @@ module Typero
|
|
|
23
23
|
:default,
|
|
24
24
|
:description,
|
|
25
25
|
:delimiter,
|
|
26
|
+
:duplicates,
|
|
27
|
+
:index,
|
|
26
28
|
:max_count,
|
|
27
29
|
:meta,
|
|
28
30
|
:min_count,
|
|
@@ -71,12 +73,16 @@ module Typero
|
|
|
71
73
|
|
|
72
74
|
false
|
|
73
75
|
end
|
|
76
|
+
|
|
77
|
+
def db_schema
|
|
78
|
+
new(nil).db_schema
|
|
79
|
+
end
|
|
74
80
|
end
|
|
75
81
|
|
|
76
82
|
###
|
|
77
83
|
|
|
78
84
|
def initialize value, opts={}, &block
|
|
79
|
-
value = value.strip
|
|
85
|
+
value = value.strip if value.is_a?(String)
|
|
80
86
|
|
|
81
87
|
opts.keys.each {|key| self.class.allowed_opt?(key) }
|
|
82
88
|
|
|
@@ -8,6 +8,9 @@ class Typero::CurrencyType < Typero::FloatType
|
|
|
8
8
|
|
|
9
9
|
def set
|
|
10
10
|
value { |data| data.to_f.round(2) }
|
|
11
|
+
|
|
12
|
+
error_for(:min_value_error, opts[:min], value) if opts[:min] && value < opts[:min]
|
|
13
|
+
error_for(:max_value_error, opts[:max], value) if opts[:max] && value > opts[:max]
|
|
11
14
|
end
|
|
12
15
|
|
|
13
16
|
def db_schema
|
|
@@ -2,12 +2,17 @@ class Typero::DateType < Typero::Type
|
|
|
2
2
|
opts :min, 'Smallest date-time allowed'
|
|
3
3
|
opts :max, 'Maximal date-time allowed'
|
|
4
4
|
|
|
5
|
+
error :en, :invalid_date, 'is not a valid date'
|
|
5
6
|
error :en, :min_date, 'Minimal allowed date is %s'
|
|
6
7
|
error :en, :max_date, 'Maximal allowed date is %s'
|
|
7
8
|
|
|
8
9
|
def set
|
|
9
10
|
unless [Date].include?(value.class)
|
|
10
|
-
|
|
11
|
+
begin
|
|
12
|
+
value { |data| DateTime.parse(data.to_s) }
|
|
13
|
+
rescue Date::Error, ArgumentError
|
|
14
|
+
error_for(:invalid_date)
|
|
15
|
+
end
|
|
11
16
|
end
|
|
12
17
|
|
|
13
18
|
value { |data| DateTime.new(data.year, data.month, data.day) }
|
|
@@ -24,12 +29,12 @@ class Typero::DateType < Typero::Type
|
|
|
24
29
|
def check_date_min_max
|
|
25
30
|
if min = opts[:min]
|
|
26
31
|
min = DateTime.parse(min)
|
|
27
|
-
error_for(:min_date, min)
|
|
32
|
+
error_for(:min_date, min) if min > value
|
|
28
33
|
end
|
|
29
34
|
|
|
30
35
|
if max = opts[:max]
|
|
31
36
|
max = DateTime.parse(max)
|
|
32
|
-
error_for(:max_date, max)
|
|
37
|
+
error_for(:max_date, max) if value > max
|
|
33
38
|
end
|
|
34
39
|
|
|
35
40
|
value
|
|
@@ -4,16 +4,22 @@ class Typero::DatetimeType < Typero::DateType
|
|
|
4
4
|
opts :min, 'Smallest date allowed'
|
|
5
5
|
opts :max, 'Maximal date allowed'
|
|
6
6
|
|
|
7
|
+
error :en, :invalid_datetime, 'is not a valid datetime'
|
|
8
|
+
|
|
7
9
|
def set
|
|
8
10
|
unless [Time, DateTime].include?(value.class)
|
|
9
|
-
|
|
11
|
+
begin
|
|
12
|
+
value { |data| DateTime.parse(data.to_s) }
|
|
13
|
+
rescue Date::Error, ArgumentError
|
|
14
|
+
error_for(:invalid_datetime)
|
|
15
|
+
end
|
|
10
16
|
end
|
|
11
17
|
|
|
12
18
|
check_date_min_max
|
|
13
19
|
end
|
|
14
20
|
|
|
15
21
|
def db_schema
|
|
16
|
-
[:
|
|
22
|
+
[:timestamp]
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Typero::FloatType < Typero::Type
|
|
2
2
|
opts :min, 'Minimum value'
|
|
3
|
-
opts :max, '
|
|
3
|
+
opts :max, 'Maximum value'
|
|
4
4
|
opts :round, 'Round to (decimal spaces)'
|
|
5
5
|
|
|
6
6
|
def set
|
|
@@ -11,14 +11,12 @@ class Typero::FloatType < Typero::Type
|
|
|
11
11
|
value.to_f
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
error_for(:
|
|
15
|
-
error_for(:
|
|
14
|
+
error_for(:min_value_error, opts[:min], value) if opts[:min] && value < opts[:min]
|
|
15
|
+
error_for(:max_value_error, opts[:max], value) if opts[:max] && value > opts[:max]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def db_schema
|
|
19
|
-
|
|
20
|
-
opts[:null] = false if opts[:required]
|
|
21
|
-
[:float, opts]
|
|
19
|
+
[:float, {}]
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
|
|
@@ -3,11 +3,11 @@ class Typero::HashType < Typero::Type
|
|
|
3
3
|
|
|
4
4
|
def set
|
|
5
5
|
if value.is_a?(String) && value[0,1] == '{'
|
|
6
|
-
@value = JSON.
|
|
6
|
+
@value = JSON.parse(value)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
@value ||= {}
|
|
10
|
-
@value.delete_if {|_, v| v.empty? }
|
|
10
|
+
@value.delete_if {|_, v| v.respond_to?(:empty?) && v.empty? }
|
|
11
11
|
|
|
12
12
|
error_for(:not_hash_type_error) unless @value.respond_to?(:keys) && @value.respond_to?(:values)
|
|
13
13
|
|
|
@@ -10,7 +10,9 @@ class Typero::ImageType < Typero::Type
|
|
|
10
10
|
error_for(:image_not_starting_error) unless value =~ /^https?:\/\/./
|
|
11
11
|
|
|
12
12
|
if opts[:strict]
|
|
13
|
-
|
|
13
|
+
# strip query string and fragment before checking extension
|
|
14
|
+
path = value.split('?').first.split('#').first
|
|
15
|
+
ext = path.split('.').last.downcase
|
|
14
16
|
error_for(:image_not_image_format) unless FORMATS.include?(ext)
|
|
15
17
|
end
|
|
16
18
|
end
|
|
@@ -14,7 +14,7 @@ class Typero::PointType < Typero::Type
|
|
|
14
14
|
value { 'SRID=4326;POINT(%s)' % point }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
if value && value.include?(',') &&
|
|
17
|
+
if value && value.include?(',') && value !~ /^SRID=4326;POINT\(/
|
|
18
18
|
error_for(:unallowed_characters_error)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
require_relative 'string_type'
|
|
2
2
|
|
|
3
3
|
class Typero::TextType < Typero::StringType
|
|
4
|
-
opts :min, '
|
|
5
|
-
opts :max, '
|
|
4
|
+
opts :min, 'Minimum string length'
|
|
5
|
+
opts :max, 'Maximum string length'
|
|
6
|
+
|
|
7
|
+
def set
|
|
8
|
+
value(&:to_s)
|
|
9
|
+
value(&:downcase) if opts[:downcase]
|
|
10
|
+
|
|
11
|
+
error_for(:min_length_error, opts[:min], value.length) if opts[:min] && value.length < opts[:min]
|
|
12
|
+
error_for(:max_length_error, opts[:max], value.length) if opts[:max] && value.length > opts[:max]
|
|
13
|
+
end
|
|
6
14
|
|
|
7
15
|
def db_schema
|
|
8
16
|
[:text, {}]
|
|
@@ -2,8 +2,7 @@ class Typero::UrlType < Typero::Type
|
|
|
2
2
|
error :en, :url_not_starting_error, 'URL is not starting with http or https'
|
|
3
3
|
|
|
4
4
|
def set
|
|
5
|
-
|
|
6
|
-
error_for(:url_not_starting_error) unless parts[1]
|
|
5
|
+
error_for(:url_not_starting_error) unless value =~ /^https?:\/\//
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
def db_schema
|
data/lib/typero/typero.rb
CHANGED
|
@@ -1,26 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
# set :name, String, req: true
|
|
3
|
-
# set :email, :email, req: true
|
|
4
|
-
# set :skills, [:email], min: 2
|
|
5
|
-
# end
|
|
6
|
-
#
|
|
7
|
-
# or
|
|
8
|
-
#
|
|
9
|
-
# rules = Typero.schema do
|
|
10
|
-
# string :name, req: true
|
|
11
|
-
# email :email, req: true
|
|
12
|
-
# email [:skills], min: 2
|
|
13
|
-
# end
|
|
14
|
-
#
|
|
15
|
-
# errors = rules.validate @object
|
|
16
|
-
# rules.valid?
|
|
17
|
-
# rules.validate(@object) { |errors| ... }
|
|
1
|
+
# module quick access to other types
|
|
18
2
|
|
|
19
3
|
module Typero
|
|
20
4
|
extend self
|
|
21
5
|
|
|
22
6
|
VERSION ||= File.read File.expand_path "../../.version", File.dirname(__FILE__)
|
|
23
|
-
SCHEMAS ||= {}
|
|
24
7
|
|
|
25
8
|
# check and coerce value
|
|
26
9
|
# Typero.type(:label) -> Typero::LabelType
|
|
@@ -55,70 +38,49 @@ module Typero
|
|
|
55
38
|
# get schema
|
|
56
39
|
# Typero.schema(:blog)
|
|
57
40
|
|
|
58
|
-
# get schema
|
|
59
|
-
# Typero.schema(:blog, :with_schema)
|
|
60
|
-
|
|
61
|
-
# get all schema names with type: model
|
|
41
|
+
# get all schema that matches any option
|
|
62
42
|
# Typero.schema(type: :model)
|
|
63
43
|
def schema name = nil, opts = nil, &block
|
|
64
44
|
klass = name.to_s.classify if name && !name.is_a?(Hash)
|
|
65
45
|
|
|
66
46
|
if block_given?
|
|
67
|
-
Typero
|
|
68
|
-
|
|
69
|
-
SCHEMAS[klass] = [schema, opts || {}]
|
|
70
|
-
end
|
|
71
|
-
end
|
|
47
|
+
# Typero.schema type: :model, db: DB_LOG do
|
|
48
|
+
Typero::Schema.new(klass, opts, &block)
|
|
72
49
|
else
|
|
73
|
-
# Schema not given, get schema
|
|
74
50
|
if name.is_a?(Hash)
|
|
75
|
-
#
|
|
51
|
+
# Schema not given, get schema
|
|
52
|
+
# Typero.schema type: :model
|
|
76
53
|
out = []
|
|
77
54
|
|
|
78
|
-
|
|
79
|
-
schema
|
|
80
|
-
|
|
81
|
-
|
|
55
|
+
Schema::SCHEMA_STORE.values.each do |schema|
|
|
56
|
+
if schema.opts[name.keys.first] == name.values.first
|
|
57
|
+
out.push schema.klass
|
|
58
|
+
end
|
|
82
59
|
end
|
|
83
60
|
|
|
84
61
|
out
|
|
85
|
-
elsif klass
|
|
86
|
-
# Typero.schema :user
|
|
87
|
-
schema = SCHEMAS[klass]
|
|
88
|
-
schema ||= class_finder klass, :schema
|
|
89
|
-
|
|
90
|
-
if opts
|
|
91
|
-
schema
|
|
92
|
-
else
|
|
93
|
-
schema.respond_to?(:[]) ? schema[0] : schema
|
|
94
|
-
end
|
|
95
62
|
else
|
|
96
|
-
|
|
63
|
+
# Typero.schema :user
|
|
64
|
+
Typero::Schema::SCHEMA_STORE[klass] || raise('Schema "%s" not found' % klass)
|
|
97
65
|
end
|
|
98
66
|
end
|
|
99
67
|
end
|
|
100
68
|
|
|
69
|
+
# same as schema but returns nil if not found
|
|
70
|
+
def schema? name
|
|
71
|
+
klass = name.to_s.classify if name
|
|
72
|
+
Typero::Schema::SCHEMA_STORE[klass] if klass
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# get array of database fields, ruby Sequel compatibile
|
|
76
|
+
def db_schema name
|
|
77
|
+
Typero.schema(name).db_schema
|
|
78
|
+
end
|
|
79
|
+
|
|
101
80
|
def defined? name
|
|
102
81
|
Typero::Type.load name
|
|
103
82
|
true
|
|
104
83
|
rescue ArgumentError
|
|
105
84
|
false
|
|
106
85
|
end
|
|
107
|
-
|
|
108
|
-
private
|
|
109
|
-
|
|
110
|
-
# class_finder :user, :exporter, :representer
|
|
111
|
-
# find first UserExporter, User::Exporter, User::Representer, UserRepresenter
|
|
112
|
-
def class_finder *args
|
|
113
|
-
name = args.shift.to_s.classify
|
|
114
|
-
|
|
115
|
-
for el in args
|
|
116
|
-
for separator in ['_','/']
|
|
117
|
-
klass = [name, el].join(separator).classify
|
|
118
|
-
return klass.constantize if const_defined? klass
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
nil
|
|
123
|
-
end
|
|
124
86
|
end
|
data/lib/typero.rb
CHANGED
metadata
CHANGED
|
@@ -1,29 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typero
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dino Reic
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
-
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: fast_blank
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
27
12
|
description: Simple and fast ruby type system. Enforce types as Array, Email, Boolean
|
|
28
13
|
for ruby class instances
|
|
29
14
|
email: reic.dino@gmail.com
|
|
@@ -34,7 +19,7 @@ files:
|
|
|
34
19
|
- "./.version"
|
|
35
20
|
- "./lib/adapters/sequel.rb"
|
|
36
21
|
- "./lib/typero.rb"
|
|
37
|
-
- "./lib/typero/
|
|
22
|
+
- "./lib/typero/define.rb"
|
|
38
23
|
- "./lib/typero/schema.rb"
|
|
39
24
|
- "./lib/typero/type/type.rb"
|
|
40
25
|
- "./lib/typero/type/types/boolean_type.rb"
|
|
@@ -62,7 +47,6 @@ homepage: https://github.com/dux/typero
|
|
|
62
47
|
licenses:
|
|
63
48
|
- MIT
|
|
64
49
|
metadata: {}
|
|
65
|
-
post_install_message:
|
|
66
50
|
rdoc_options: []
|
|
67
51
|
require_paths:
|
|
68
52
|
- lib
|
|
@@ -77,8 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
61
|
- !ruby/object:Gem::Version
|
|
78
62
|
version: '0'
|
|
79
63
|
requirements: []
|
|
80
|
-
rubygems_version: 3.
|
|
81
|
-
signing_key:
|
|
64
|
+
rubygems_version: 3.6.9
|
|
82
65
|
specification_version: 4
|
|
83
66
|
summary: Ruby type system
|
|
84
67
|
test_files: []
|