strong_json 1.1.0 → 2.0.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +8 -14
- data/lib/strong_json/type.rb +47 -41
- data/lib/strong_json/types.rb +2 -2
- data/lib/strong_json/version.rb +2 -2
- data/sig/type.rbi +17 -7
- data/spec/enum_spec.rb +8 -8
- data/spec/json_spec.rb +1 -1
- data/spec/object_spec.rb +107 -79
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b06583a5049ceb64b418d9dbfa9d9b024487c116a2b84cda2effc8f20f47dfc
|
4
|
+
data.tar.gz: 3998a14cfa6c87822c9d8da3d510c64cdb3ec8ca49762e104564c2109711ca8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3eea214df1267ca23eb4ca45150c8a967c2f928738a225ccc1b42d2a5dbace87593d1ae8184554e47e40012f3e694b5c8f333a58dcb90fb680e73401b5dd49b6
|
7
|
+
data.tar.gz: 5e974fe31499668b39a8dd953267f2a7ef2ea0b070dcc1c48dfa14b7c1ac33df5a57d7dd20a039bfe1cd16dfa52de0a91c8c8a1bc3445fd48b092b007437d827
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -59,26 +59,20 @@ If an attribute has a value which does not match with given type, the `coerce` m
|
|
59
59
|
|
60
60
|
#### Ignoring unknown attributes
|
61
61
|
|
62
|
-
`
|
63
|
-
You can reject the unknown attributes.
|
62
|
+
You can use `ignore` method to ignore unknown attributes.
|
64
63
|
|
65
64
|
```
|
66
|
-
object(attrs).ignore(
|
67
|
-
object(attrs).ignore
|
65
|
+
object(attrs).ignore() # Ignores all unknown attributes.
|
66
|
+
object(attrs).ignore(:x, :y) # Ignores :x and :y, but rejects other unknown attributes.
|
67
|
+
object(attrs).ignore(except: Set[:x, :y]) # Rejects :x and :y, but ignores other unknown attributes.
|
68
68
|
```
|
69
69
|
|
70
|
-
|
70
|
+
`Object` also provides `reject` method to do the opposite.
|
71
71
|
|
72
72
|
```
|
73
|
-
object(attrs).
|
74
|
-
object(attrs).
|
75
|
-
|
76
|
-
|
77
|
-
`Object` also has `prohibit` method to specify attributes to make the type check failed.
|
78
|
-
|
79
|
-
```
|
80
|
-
object(attrs).prohibit(Set.new([:created_at, :updated_at])) # Make type check failed if :created_at or :updated_at included
|
81
|
-
object(attrs).prohibit!(Set.new([:created_at, :updated_at])) # Destructive version
|
73
|
+
object(attrs).reject() # Rejects all unknown attributes. (default)
|
74
|
+
object(attrs).reject(:x, :y) # Rejects :x and :y, but ignores other unknown attributes.
|
75
|
+
object(attrs).reject(except: Set[:x, :y]) # Ignores :x and :y, but rejects other unknown attributes.
|
82
76
|
```
|
83
77
|
|
84
78
|
### array(type)
|
data/lib/strong_json/type.rb
CHANGED
@@ -192,13 +192,13 @@ class StrongJSON
|
|
192
192
|
include Match
|
193
193
|
include WithAlias
|
194
194
|
|
195
|
-
# @dynamic fields,
|
196
|
-
attr_reader :fields, :
|
195
|
+
# @dynamic fields, on_unknown, exceptions
|
196
|
+
attr_reader :fields, :on_unknown, :exceptions
|
197
197
|
|
198
|
-
def initialize(fields,
|
198
|
+
def initialize(fields, on_unknown:, exceptions:)
|
199
199
|
@fields = fields
|
200
|
-
@
|
201
|
-
@
|
200
|
+
@on_unknown = on_unknown
|
201
|
+
@exceptions = exceptions
|
202
202
|
end
|
203
203
|
|
204
204
|
def coerce(object, path: ErrorPath.root(self))
|
@@ -206,33 +206,31 @@ class StrongJSON
|
|
206
206
|
raise TypeError.new(path: path, value: object)
|
207
207
|
end
|
208
208
|
|
209
|
-
|
210
|
-
|
211
|
-
end
|
209
|
+
object = object.dup
|
210
|
+
unknown_attributes = Set.new(object.keys) - fields.keys
|
212
211
|
|
213
|
-
case
|
214
|
-
when :
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
212
|
+
case on_unknown
|
213
|
+
when :reject
|
214
|
+
unknown_attributes.each do |attr|
|
215
|
+
if exceptions.member?(attr)
|
216
|
+
object.delete(attr)
|
217
|
+
else
|
218
|
+
raise UnexpectedAttributeError.new(path: path, attribute: attr)
|
219
|
+
end
|
219
220
|
end
|
220
|
-
when
|
221
|
-
|
222
|
-
|
223
|
-
|
221
|
+
when :ignore
|
222
|
+
unknown_attributes.each do |attr|
|
223
|
+
if exceptions.member?(attr)
|
224
|
+
raise UnexpectedAttributeError.new(path: path, attribute: attr)
|
225
|
+
else
|
226
|
+
object.delete(attr)
|
227
|
+
end
|
224
228
|
end
|
225
229
|
end
|
226
230
|
|
227
231
|
# @type var result: ::Hash<Symbol, any>
|
228
232
|
result = {}
|
229
233
|
|
230
|
-
object.each do |key, _|
|
231
|
-
unless fields.key?(key)
|
232
|
-
raise UnexpectedAttributeError.new(path: path, attribute: key)
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
234
|
fields.each do |key, type|
|
237
235
|
result[key] = type.coerce(object[key], path: path.dig(key: key, type: type))
|
238
236
|
end
|
@@ -240,29 +238,37 @@ class StrongJSON
|
|
240
238
|
_ = result
|
241
239
|
end
|
242
240
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
241
|
+
# @type method ignore: (*Symbol, ?except: Set<Symbol>?) -> self
|
242
|
+
def ignore(*ignores, except: nil)
|
243
|
+
if ignores.empty? && !except
|
244
|
+
Object.new(fields, on_unknown: :ignore, exceptions: Set[])
|
245
|
+
else
|
246
|
+
if except
|
247
|
+
Object.new(fields, on_unknown: :ignore, exceptions: except)
|
248
|
+
else
|
249
|
+
Object.new(fields, on_unknown: :reject, exceptions: Set.new(ignores))
|
250
|
+
end
|
251
|
+
end
|
254
252
|
end
|
255
253
|
|
256
|
-
|
257
|
-
|
258
|
-
|
254
|
+
# @type method reject: (*Symbol, ?except: Set<Symbol>?) -> self
|
255
|
+
def reject(*rejecteds, except: nil)
|
256
|
+
if rejecteds.empty? && !except
|
257
|
+
Object.new(fields, on_unknown: :reject, exceptions: Set[])
|
258
|
+
else
|
259
|
+
if except
|
260
|
+
Object.new(fields, on_unknown: :reject, exceptions: except)
|
261
|
+
else
|
262
|
+
Object.new(fields, on_unknown: :ignore, exceptions: Set.new(rejecteds))
|
263
|
+
end
|
264
|
+
end
|
259
265
|
end
|
260
266
|
|
261
267
|
def update_fields
|
262
268
|
fields.dup.yield_self do |fields|
|
263
269
|
yield fields
|
264
270
|
|
265
|
-
Object.new(fields,
|
271
|
+
Object.new(fields, on_unknown: on_unknown, exceptions: exceptions)
|
266
272
|
end
|
267
273
|
end
|
268
274
|
|
@@ -278,8 +284,8 @@ class StrongJSON
|
|
278
284
|
if other.is_a?(Object)
|
279
285
|
# @type var other: Object<any>
|
280
286
|
other.fields == fields &&
|
281
|
-
other.
|
282
|
-
other.
|
287
|
+
other.on_unknown == on_unknown &&
|
288
|
+
other.exceptions == exceptions
|
283
289
|
end
|
284
290
|
end
|
285
291
|
|
data/lib/strong_json/types.rb
CHANGED
@@ -3,9 +3,9 @@ class StrongJSON
|
|
3
3
|
# @type method object: (?Hash<Symbol, ty>) -> Type::Object<any>
|
4
4
|
def object(fields = {})
|
5
5
|
if fields.empty?
|
6
|
-
Type::Object.new(fields,
|
6
|
+
Type::Object.new(fields, on_unknown: :ignore, exceptions: Set.new)
|
7
7
|
else
|
8
|
-
Type::Object.new(fields,
|
8
|
+
Type::Object.new(fields, on_unknown: :reject, exceptions: Set.new)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
data/lib/strong_json/version.rb
CHANGED
data/sig/type.rbi
CHANGED
@@ -60,16 +60,26 @@ class StrongJSON::Type::Object<'t>
|
|
60
60
|
include WithAlias
|
61
61
|
|
62
62
|
attr_reader fields: ::Hash<Symbol, _Schema<any>>
|
63
|
-
attr_reader
|
64
|
-
attr_reader
|
63
|
+
attr_reader on_unknown: :ignore | :reject
|
64
|
+
attr_reader exceptions: Set<Symbol>
|
65
65
|
|
66
|
-
def initialize: (::Hash<Symbol, _Schema<'t>>,
|
66
|
+
def initialize: (::Hash<Symbol, _Schema<'t>>, on_unknown: :ignore | :reject, exceptions: Set<Symbol>) -> any
|
67
67
|
def coerce: (any, ?path: ErrorPath) -> 't
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
def
|
69
|
+
# If no argument is given, it ignores all unknown attributes.
|
70
|
+
# If `Symbol`s are given, it ignores the listed attributes, but rejects if other unknown attributes are detected.
|
71
|
+
# If `except:` is specified, it rejects attributes listed in `except` are detected, but ignores other unknown attributes.
|
72
|
+
def ignore: () -> self
|
73
|
+
| (*Symbol) -> self
|
74
|
+
| (?except: Set<Symbol>) -> self
|
75
|
+
|
76
|
+
# If no argument is given, it rejects on any unknown attribute.
|
77
|
+
# If `Symbol`s are given, it rejects the listed attributes are detected, but ignores other unknown attributes.
|
78
|
+
# If `except:` is specified, it ignores given attributes, but rejects if other unknown attributes are detected.
|
79
|
+
def reject: () -> self
|
80
|
+
| (*Symbol) -> self
|
81
|
+
| (?except: Set<Symbol>) -> self
|
82
|
+
|
73
83
|
def update_fields: <'x> { (::Hash<Symbol, _Schema<any>>) -> void } -> Object<'x>
|
74
84
|
end
|
75
85
|
|
data/spec/enum_spec.rb
CHANGED
@@ -29,16 +29,16 @@ describe StrongJSON::Type::Enum do
|
|
29
29
|
id: StrongJSON::Type::Literal.new("id1"),
|
30
30
|
value: StrongJSON::Type::Base.new(:string)
|
31
31
|
},
|
32
|
-
|
33
|
-
|
32
|
+
on_unknown: :raise,
|
33
|
+
exceptions: Set[]
|
34
34
|
),
|
35
35
|
StrongJSON::Type::Object.new(
|
36
36
|
{
|
37
37
|
id: StrongJSON::Type::Base.new(:string),
|
38
38
|
value: StrongJSON::Type::Base.new(:symbol)
|
39
39
|
},
|
40
|
-
|
41
|
-
|
40
|
+
on_unknown: :raise,
|
41
|
+
exceptions: Set[]
|
42
42
|
),
|
43
43
|
StrongJSON::Type::Optional.new(StrongJSON::Type::Literal.new(3)),
|
44
44
|
StrongJSON::Type::Literal.new(false),
|
@@ -73,8 +73,8 @@ describe StrongJSON::Type::Enum do
|
|
73
73
|
regexp: StrongJSON::Type::Base.new(:string),
|
74
74
|
option: StrongJSON::Type::Base.new(:string),
|
75
75
|
},
|
76
|
-
|
77
|
-
|
76
|
+
on_unknown: :raise,
|
77
|
+
exceptions: Set[]
|
78
78
|
)
|
79
79
|
}
|
80
80
|
|
@@ -83,8 +83,8 @@ describe StrongJSON::Type::Enum do
|
|
83
83
|
{
|
84
84
|
literal: StrongJSON::Type::Base.new(:string)
|
85
85
|
},
|
86
|
-
|
87
|
-
|
86
|
+
on_unknown: :raise,
|
87
|
+
exceptions: Set[]
|
88
88
|
)
|
89
89
|
}
|
90
90
|
|
data/spec/json_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require "strong_json"
|
|
3
3
|
describe "StrongJSON.new" do
|
4
4
|
it "tests the structure of a JSON object" do
|
5
5
|
s = StrongJSON.new do
|
6
|
-
let :item, object(name: string, count: numeric, price: numeric).ignore(
|
6
|
+
let :item, object(name: string, count: numeric, price: numeric).ignore(:comment)
|
7
7
|
let :items, array(item)
|
8
8
|
let :checkout,
|
9
9
|
object(items: items,
|
data/spec/object_spec.rb
CHANGED
@@ -8,114 +8,73 @@ describe StrongJSON::Type::Object do
|
|
8
8
|
a: StrongJSON::Type::Base.new(:numeric),
|
9
9
|
b: StrongJSON::Type::Base.new(:string)
|
10
10
|
},
|
11
|
-
|
12
|
-
|
11
|
+
on_unknown: :raise,
|
12
|
+
exceptions: Set.new
|
13
13
|
)
|
14
14
|
|
15
15
|
expect(type.coerce(a: 123, b: "test")).to eq(a: 123, b: "test")
|
16
16
|
end
|
17
17
|
|
18
|
-
it "rejects unspecified fields" do
|
19
|
-
type = StrongJSON::Type::Object.new(
|
20
|
-
{
|
21
|
-
a: StrongJSON::Type::Base.new(:numeric)
|
22
|
-
},
|
23
|
-
ignored_attributes: nil,
|
24
|
-
prohibited_attributes: Set.new
|
25
|
-
)
|
26
|
-
|
27
|
-
expect { type.coerce(a:123, b:true) }.to raise_error(StrongJSON::Type::UnexpectedAttributeError) {|e|
|
28
|
-
expect(e.path.to_s).to eq("$")
|
29
|
-
expect(e.attribute).to eq(:b)
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
18
|
it "rejects objects with missing fields" do
|
34
19
|
type = StrongJSON::Type::Object.new(
|
35
20
|
{
|
36
21
|
a: StrongJSON::Type::Base.new(:numeric)
|
37
22
|
},
|
38
|
-
|
39
|
-
|
23
|
+
on_unknown: :reject,
|
24
|
+
exceptions: Set.new
|
40
25
|
)
|
41
26
|
|
42
|
-
expect{ type.coerce(b: "test") }.to raise_error(StrongJSON::Type::UnexpectedAttributeError) {|e|
|
27
|
+
expect{ type.coerce(a: 123, b: "test") }.to raise_error(StrongJSON::Type::UnexpectedAttributeError) {|e|
|
43
28
|
expect(e.path.to_s).to eq("$")
|
44
29
|
expect(e.attribute).to eq(:b)
|
45
30
|
}
|
46
31
|
end
|
47
32
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
}
|
59
|
-
|
60
|
-
it "ignores field with any value" do
|
61
|
-
expect(type.coerce(a: 123, b: true)).to eq(a: 123)
|
62
|
-
end
|
63
|
-
|
64
|
-
it "accepts if it does not contains the field" do
|
65
|
-
expect(type.coerce(a: 123)).to eq(a: 123)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
context "when ignored_attributes is nil" do
|
70
|
-
let(:type) {
|
71
|
-
StrongJSON::Type::Object.new(
|
72
|
-
{
|
73
|
-
a: StrongJSON::Type::Base.new(:numeric)
|
74
|
-
},
|
75
|
-
ignored_attributes: nil,
|
76
|
-
prohibited_attributes: Set.new
|
77
|
-
)
|
78
|
-
}
|
33
|
+
context "when on_unknown is :ignore" do
|
34
|
+
let(:type) {
|
35
|
+
StrongJSON::Type::Object.new(
|
36
|
+
{
|
37
|
+
a: StrongJSON::Type::Base.new(:numeric)
|
38
|
+
},
|
39
|
+
on_unknown: :ignore,
|
40
|
+
exceptions: Set[:x]
|
41
|
+
)
|
42
|
+
}
|
79
43
|
|
80
|
-
|
81
|
-
|
82
|
-
type.coerce(a: 123, b: true)
|
83
|
-
}.to raise_error(StrongJSON::Type::UnexpectedAttributeError)
|
84
|
-
end
|
44
|
+
it "ignores field with any value" do
|
45
|
+
expect(type.coerce(a: 123, b: true)).to eq(a: 123)
|
85
46
|
end
|
86
47
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
},
|
93
|
-
ignored_attributes: :any,
|
94
|
-
prohibited_attributes: Set.new
|
95
|
-
)
|
48
|
+
it "raises error on attributes listed in exceptions" do
|
49
|
+
expect {
|
50
|
+
type.coerce(a: 123, x: false)
|
51
|
+
}.to raise_error(StrongJSON::Type::UnexpectedAttributeError) {|error|
|
52
|
+
expect(error.attribute).to eq(:x)
|
96
53
|
}
|
97
|
-
|
98
|
-
it "ignores field with any value" do
|
99
|
-
expect(type.coerce(a: 123, b: true)).to eq(a: 123)
|
100
|
-
end
|
101
54
|
end
|
102
55
|
end
|
103
56
|
|
104
|
-
|
57
|
+
context "when on_unknown is :reject" do
|
105
58
|
let(:type) {
|
106
59
|
StrongJSON::Type::Object.new(
|
107
60
|
{
|
108
61
|
a: StrongJSON::Type::Base.new(:numeric)
|
109
62
|
},
|
110
|
-
|
111
|
-
|
63
|
+
on_unknown: :reject,
|
64
|
+
exceptions: Set[:c]
|
112
65
|
)
|
113
66
|
}
|
114
67
|
|
115
|
-
it "raises
|
68
|
+
it "raises with unknown attribute" do
|
116
69
|
expect {
|
117
|
-
type.coerce(a:123, b:true
|
118
|
-
}.to raise_error(StrongJSON::Type::UnexpectedAttributeError)
|
70
|
+
type.coerce(a: 123, b: true)
|
71
|
+
}.to raise_error(StrongJSON::Type::UnexpectedAttributeError) {|error|
|
72
|
+
expect(error.attribute).to eq(:b)
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
it "ignores attributes listed in exceptions" do
|
77
|
+
expect(type.coerce(a: 123, c: false)).to eq(a:123)
|
119
78
|
end
|
120
79
|
end
|
121
80
|
end
|
@@ -126,8 +85,8 @@ describe StrongJSON::Type::Object do
|
|
126
85
|
{
|
127
86
|
a: StrongJSON::Type::Optional.new(StrongJSON::Type::Base.new(:numeric))
|
128
87
|
},
|
129
|
-
|
130
|
-
|
88
|
+
on_unknown: :raise,
|
89
|
+
exceptions: Set[]
|
131
90
|
)
|
132
91
|
}
|
133
92
|
|
@@ -151,8 +110,8 @@ describe StrongJSON::Type::Object do
|
|
151
110
|
a: StrongJSON::Type::Base.new(:numeric),
|
152
111
|
b: StrongJSON::Type::Base.new(:string)
|
153
112
|
},
|
154
|
-
|
155
|
-
|
113
|
+
on_unknown: :raise,
|
114
|
+
exceptions: Set[]
|
156
115
|
)
|
157
116
|
}
|
158
117
|
|
@@ -164,4 +123,73 @@ describe StrongJSON::Type::Object do
|
|
164
123
|
expect(type =~ {}).to be_falsey
|
165
124
|
end
|
166
125
|
end
|
126
|
+
|
127
|
+
describe "#ignore" do
|
128
|
+
let (:type) {
|
129
|
+
StrongJSON::Type::Object.new(
|
130
|
+
{ a: StrongJSON::Type::Base.new(:numeric) },
|
131
|
+
on_unknown: :raise,
|
132
|
+
exceptions: Set[]
|
133
|
+
)
|
134
|
+
}
|
135
|
+
|
136
|
+
context "if no argument is given" do
|
137
|
+
it "ignores all unknown attributes" do
|
138
|
+
updated_type = type.ignore()
|
139
|
+
expect(updated_type.on_unknown).to eq(:ignore)
|
140
|
+
expect(updated_type.exceptions).to eq(Set[])
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
context "if list of Symbol is given" do
|
146
|
+
it "ignores specified attributes but raises unknowns" do
|
147
|
+
updated_type = type.ignore(:x, :y)
|
148
|
+
expect(updated_type.on_unknown).to eq(:reject)
|
149
|
+
expect(updated_type.exceptions).to eq(Set[:x, :y])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "if except keyword is specified" do
|
154
|
+
it "raises unknowns but ignores specified attributes" do
|
155
|
+
updated_type = type.ignore(except: Set[:x, :y])
|
156
|
+
expect(updated_type.on_unknown).to eq(:ignore)
|
157
|
+
expect(updated_type.exceptions).to eq(Set[:x, :y])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#reject" do
|
163
|
+
let (:type) {
|
164
|
+
StrongJSON::Type::Object.new(
|
165
|
+
{ a: StrongJSON::Type::Base.new(:numeric) },
|
166
|
+
on_unknown: :raise,
|
167
|
+
exceptions: Set[]
|
168
|
+
)
|
169
|
+
}
|
170
|
+
|
171
|
+
context "if no argument is given" do
|
172
|
+
it "raises on any unknown attribute" do
|
173
|
+
updated_type = type.reject()
|
174
|
+
expect(updated_type.on_unknown).to eq(:reject)
|
175
|
+
expect(updated_type.exceptions).to eq(Set[])
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "if list of Symbol is given" do
|
180
|
+
it "raises unknowns but ignores specified attributes" do
|
181
|
+
updated_type = type.reject(:x, :y)
|
182
|
+
expect(updated_type.on_unknown).to eq(:ignore)
|
183
|
+
expect(updated_type.exceptions).to eq(Set[:x, :y])
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "if except keyword is specified" do
|
188
|
+
it "ignores specified attributes but raises unknowns" do
|
189
|
+
updated_type = type.reject(except: Set[:x, :y])
|
190
|
+
expect(updated_type.on_unknown).to eq(:reject)
|
191
|
+
expect(updated_type.exceptions).to eq(Set[:x, :y])
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
167
195
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strong_json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|