treaty 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1fe35b7cf209d578b34ee7d904bdd146db4a3ac61f022a1f5f02c80bfe21875e
|
|
4
|
+
data.tar.gz: 4be4a2f29fbfb30115e696baeaf618eaf59fe5c2fc309a0d1ced3eff61713671
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d256fd30a7553ebfc015c06049c4fc0edceddaa782b3b0bda807364568009465556e72867324bc4a707d61c52da579f5a40f4324922af4349f1a7553023a9443
|
|
7
|
+
data.tar.gz: 4d71a4831e946faf207b9c21947531f3bc6263941f07e3a627c2e504a8c471d6aec597fe167090c0d0d49979b3b4dbf2f8e0620cfe9cd12f492286f60b5a3e7a
|
data/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
> [!WARNING]
|
|
16
|
-
> **Development Status**: Treaty is currently under active development in the 0.x version series. Breaking changes may occur between minor versions (0.x) as we refine the API and add new features. The library will stabilize with the 1.0 release. We recommend pinning to specific patch versions in your Gemfile (e.g., `gem "treaty", "~> 0.
|
|
16
|
+
> **Development Status**: Treaty is currently under active development in the 0.x version series. Breaking changes may occur between minor versions (0.x) as we refine the API and add new features. The library will stabilize with the 1.0 release. We recommend pinning to specific patch versions in your Gemfile (e.g., `gem "treaty", "~> 0.14.0"`) until the 1.0 release.
|
|
17
17
|
|
|
18
18
|
## 📚 Documentation
|
|
19
19
|
|
|
@@ -79,7 +79,7 @@ module Posts
|
|
|
79
79
|
string :title
|
|
80
80
|
string :content
|
|
81
81
|
string :summary
|
|
82
|
-
|
|
82
|
+
time :created_at
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
data/config/locales/en.yml
CHANGED
|
@@ -17,7 +17,9 @@ en:
|
|
|
17
17
|
boolean: "Attribute '%{attribute}' must be a Boolean (true or false), got %{actual}"
|
|
18
18
|
object: "Attribute '%{attribute}' must be a Hash (object), got %{actual}"
|
|
19
19
|
array: "Attribute '%{attribute}' must be an Array, got %{actual}"
|
|
20
|
-
|
|
20
|
+
date: "Attribute '%{attribute}' must be a Date, got %{actual}"
|
|
21
|
+
time: "Attribute '%{attribute}' must be a Time, got %{actual}"
|
|
22
|
+
datetime: "Attribute '%{attribute}' must be a DateTime, got %{actual}"
|
|
21
23
|
|
|
22
24
|
inclusion:
|
|
23
25
|
invalid_schema: "Option 'inclusion' for attribute '%{attribute}' must have a non-empty array of allowed values"
|
|
@@ -50,24 +50,42 @@ module Treaty
|
|
|
50
50
|
# ### From Integer
|
|
51
51
|
# - integer -> string: Converts to string representation
|
|
52
52
|
# - integer -> boolean: 0 = false, non-zero = true
|
|
53
|
-
# - integer ->
|
|
53
|
+
# - integer -> date: Treats as Unix timestamp, converts to date
|
|
54
|
+
# - integer -> time: Treats as Unix timestamp
|
|
55
|
+
# - integer -> datetime: Treats as Unix timestamp, converts to datetime
|
|
54
56
|
#
|
|
55
57
|
# ### From String
|
|
56
58
|
# - string -> integer: Parses integer from string
|
|
57
59
|
# - string -> boolean: Parses truthy/falsy strings (true/false, yes/no, 1/0, on/off)
|
|
60
|
+
# - string -> date: Parses date string
|
|
61
|
+
# - string -> time: Parses time string
|
|
58
62
|
# - string -> datetime: Parses datetime string (ISO8601, RFC3339, etc.)
|
|
59
63
|
#
|
|
60
64
|
# ### From Boolean
|
|
61
65
|
# - boolean -> string: Converts to "true" or "false"
|
|
62
66
|
# - boolean -> integer: true = 1, false = 0
|
|
63
67
|
#
|
|
68
|
+
# ### From Date
|
|
69
|
+
# - date -> string: Converts to ISO8601 format
|
|
70
|
+
# - date -> integer: Converts to Unix timestamp
|
|
71
|
+
# - date -> time: Converts to Time at midnight
|
|
72
|
+
# - date -> datetime: Converts to DateTime at midnight
|
|
73
|
+
#
|
|
74
|
+
# ### From Time
|
|
75
|
+
# - time -> string: Converts to ISO8601 format
|
|
76
|
+
# - time -> integer: Converts to Unix timestamp
|
|
77
|
+
# - time -> date: Converts to Date
|
|
78
|
+
# - time -> datetime: Converts to DateTime
|
|
79
|
+
#
|
|
64
80
|
# ### From DateTime
|
|
65
81
|
# - datetime -> string: Converts to ISO8601 format
|
|
66
82
|
# - datetime -> integer: Converts to Unix timestamp
|
|
83
|
+
# - datetime -> date: Converts to Date
|
|
84
|
+
# - datetime -> time: Converts to Time
|
|
67
85
|
#
|
|
68
86
|
# ## Important Notes
|
|
69
87
|
#
|
|
70
|
-
# - Cast option only works with scalar types (integer, string, boolean, datetime)
|
|
88
|
+
# - Cast option only works with scalar types (integer, string, boolean, date, time, datetime)
|
|
71
89
|
# - Array and Object types are not supported for casting
|
|
72
90
|
# - Casting to the same type is allowed (no-op)
|
|
73
91
|
# - Nil values are not transformed (handled by RequiredValidator)
|
|
@@ -82,9 +100,9 @@ module Treaty
|
|
|
82
100
|
#
|
|
83
101
|
# Schema format: `{ to: :target_type, message: "Custom error" }`
|
|
84
102
|
# Note: Uses `:to` key instead of the default `:is` key.
|
|
85
|
-
class CastModifier < Treaty::Attribute::Option::Base
|
|
103
|
+
class CastModifier < Treaty::Attribute::Option::Base # rubocop:disable Metrics/ClassLength
|
|
86
104
|
# Types that support casting (scalar types only)
|
|
87
|
-
ALLOWED_CAST_TYPES = %i[integer string boolean datetime].freeze
|
|
105
|
+
ALLOWED_CAST_TYPES = %i[integer string boolean date time datetime].freeze
|
|
88
106
|
|
|
89
107
|
# Validates that cast option is correctly configured
|
|
90
108
|
#
|
|
@@ -202,12 +220,16 @@ module Treaty
|
|
|
202
220
|
integer: ->(value:) { value }, # No-op for same type
|
|
203
221
|
string: ->(value:) { value.to_s },
|
|
204
222
|
boolean: ->(value:) { value != 0 },
|
|
205
|
-
|
|
223
|
+
date: ->(value:) { Time.at(value).to_date },
|
|
224
|
+
time: ->(value:) { Time.at(value) },
|
|
225
|
+
datetime: ->(value:) { Time.at(value).to_datetime }
|
|
206
226
|
},
|
|
207
227
|
string: {
|
|
208
228
|
string: ->(value:) { value }, # No-op for same type
|
|
209
229
|
integer: ->(value:) { Integer(value) },
|
|
210
230
|
boolean: ->(value:) { parse_boolean(value) },
|
|
231
|
+
date: ->(value:) { Date.parse(value) },
|
|
232
|
+
time: ->(value:) { Time.parse(value) },
|
|
211
233
|
datetime: ->(value:) { DateTime.parse(value) }
|
|
212
234
|
},
|
|
213
235
|
boolean: {
|
|
@@ -215,10 +237,26 @@ module Treaty
|
|
|
215
237
|
string: ->(value:) { value.to_s },
|
|
216
238
|
integer: ->(value:) { value ? 1 : 0 }
|
|
217
239
|
},
|
|
240
|
+
date: {
|
|
241
|
+
date: ->(value:) { value }, # No-op for same type
|
|
242
|
+
string: ->(value:) { value.iso8601 },
|
|
243
|
+
integer: ->(value:) { value.to_time.to_i },
|
|
244
|
+
time: ->(value:) { value.to_time },
|
|
245
|
+
datetime: ->(value:) { value.to_datetime }
|
|
246
|
+
},
|
|
247
|
+
time: {
|
|
248
|
+
time: ->(value:) { value }, # No-op for same type
|
|
249
|
+
string: ->(value:) { value.iso8601 },
|
|
250
|
+
integer: ->(value:) { value.to_i },
|
|
251
|
+
date: ->(value:) { value.to_date },
|
|
252
|
+
datetime: ->(value:) { value.to_datetime }
|
|
253
|
+
},
|
|
218
254
|
datetime: {
|
|
219
255
|
datetime: ->(value:) { value }, # No-op for same type
|
|
220
256
|
string: ->(value:) { value.iso8601 },
|
|
221
|
-
integer: ->(value:) { value.to_i }
|
|
257
|
+
integer: ->(value:) { value.to_i },
|
|
258
|
+
date: ->(value:) { value.to_date },
|
|
259
|
+
time: ->(value:) { value.to_time }
|
|
222
260
|
}
|
|
223
261
|
}
|
|
224
262
|
end
|
|
@@ -13,7 +13,9 @@ module Treaty
|
|
|
13
13
|
# - `:boolean` - Ruby TrueClass or FalseClass
|
|
14
14
|
# - `:object` - Ruby Hash (for nested objects)
|
|
15
15
|
# - `:array` - Ruby Array (for collections)
|
|
16
|
-
# - `:
|
|
16
|
+
# - `:date` - Ruby Date
|
|
17
|
+
# - `:time` - Ruby Time
|
|
18
|
+
# - `:datetime` - Ruby DateTime
|
|
17
19
|
#
|
|
18
20
|
# ## Usage Examples
|
|
19
21
|
#
|
|
@@ -21,7 +23,9 @@ module Treaty
|
|
|
21
23
|
# integer :age
|
|
22
24
|
# string :name
|
|
23
25
|
# boolean :published
|
|
24
|
-
#
|
|
26
|
+
# date :published_on
|
|
27
|
+
# time :created_at
|
|
28
|
+
# datetime :updated_at
|
|
25
29
|
#
|
|
26
30
|
# Nested structures:
|
|
27
31
|
# object :author do
|
|
@@ -36,14 +40,16 @@ module Treaty
|
|
|
36
40
|
#
|
|
37
41
|
# - Validates only non-nil values (nil handling is done by RequiredValidator)
|
|
38
42
|
# - Type mismatch raises Treaty::Exceptions::Validation
|
|
39
|
-
# -
|
|
43
|
+
# - Date accepts only Date objects (not DateTime or Time)
|
|
44
|
+
# - Time accepts only Time objects (not Date or DateTime)
|
|
45
|
+
# - DateTime accepts only DateTime objects (not Date or Time)
|
|
40
46
|
#
|
|
41
47
|
# ## Note
|
|
42
48
|
#
|
|
43
49
|
# TypeValidator doesn't use option_schema - it validates based on attribute_type.
|
|
44
50
|
# This validator is always active for all attributes.
|
|
45
51
|
class TypeValidator < Treaty::Attribute::Option::Base
|
|
46
|
-
ALLOWED_TYPES = %i[integer string boolean object array datetime].freeze
|
|
52
|
+
ALLOWED_TYPES = %i[integer string boolean object array date time datetime].freeze
|
|
47
53
|
|
|
48
54
|
# Validates that the attribute type is one of the allowed types
|
|
49
55
|
#
|
|
@@ -81,6 +87,10 @@ module Treaty
|
|
|
81
87
|
validate_object!(value)
|
|
82
88
|
when :array
|
|
83
89
|
validate_array!(value)
|
|
90
|
+
when :date
|
|
91
|
+
validate_date!(value)
|
|
92
|
+
when :time
|
|
93
|
+
validate_time!(value)
|
|
84
94
|
when :datetime
|
|
85
95
|
validate_datetime!(value)
|
|
86
96
|
end
|
|
@@ -172,14 +182,33 @@ module Treaty
|
|
|
172
182
|
validate_type!(value, :array) { |v| v.is_a?(Array) }
|
|
173
183
|
end
|
|
174
184
|
|
|
175
|
-
# Validates that value is a DateTime,
|
|
185
|
+
# Validates that value is a Date (but not DateTime, since DateTime < Date)
|
|
176
186
|
#
|
|
177
187
|
# @param value [Object] The value to validate
|
|
178
|
-
# @raise [Treaty::Exceptions::Validation] If value is not a
|
|
188
|
+
# @raise [Treaty::Exceptions::Validation] If value is not a Date
|
|
189
|
+
# @return [void]
|
|
190
|
+
def validate_date!(value)
|
|
191
|
+
validate_type!(value, :date) { |v| v.is_a?(Date) && !v.is_a?(DateTime) }
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Validates that value is a Time or ActiveSupport::TimeWithZone
|
|
195
|
+
#
|
|
196
|
+
# @param value [Object] The value to validate
|
|
197
|
+
# @raise [Treaty::Exceptions::Validation] If value is not a Time
|
|
198
|
+
# @return [void]
|
|
199
|
+
def validate_time!(value)
|
|
200
|
+
validate_type!(value, :time) do |v|
|
|
201
|
+
v.is_a?(Time) || (defined?(ActiveSupport::TimeWithZone) && v.is_a?(ActiveSupport::TimeWithZone))
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Validates that value is a DateTime
|
|
206
|
+
#
|
|
207
|
+
# @param value [Object] The value to validate
|
|
208
|
+
# @raise [Treaty::Exceptions::Validation] If value is not a DateTime
|
|
179
209
|
# @return [void]
|
|
180
210
|
def validate_datetime!(value)
|
|
181
|
-
|
|
182
|
-
validate_type!(value, :datetime) { |v| v.is_a?(DateTime) || v.is_a?(Time) || v.is_a?(Date) }
|
|
211
|
+
validate_type!(value, :datetime) { |v| v.is_a?(DateTime) }
|
|
183
212
|
end
|
|
184
213
|
end
|
|
185
214
|
end
|
data/lib/treaty/version.rb
CHANGED