dry-types-json-schema 0.0.2 → 0.0.4
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/.github/workflows/test.yml +12 -0
- data/Gemfile.lock +1 -1
- data/dry-types-json-schema.gemspec +1 -1
- data/lib/dry/types/extensions/json_schema.rb +39 -15
- data/spec/extensions/json_schema_spec.rb +22 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67e63d34a8b81578fef86941bd3f448062ddf6357f5ea66751882f424a52bd28
|
4
|
+
data.tar.gz: 732938510bbdfa5490421cebfff6de06b57108819bdc0f7f7806f03ad4c8131b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0133a959fe532c4f5c75a5084c674a2e83553af6e6abb6580a1809fba8f5dd15c748640c786f4d22cd04a00303582ddc3ef957b707ec00d17281621bf4e6ad7
|
7
|
+
data.tar.gz: 05b90642aa10bce11add57b7591fa466a0102f9c5d62e4fa29b8a2f0a1318908d0a10baf9c36531fadf5584764d740b0beb3a7e21b540be63eb03a4b23f03ba0
|
data/Gemfile.lock
CHANGED
@@ -17,7 +17,7 @@ module Dry
|
|
17
17
|
IDENTITY = ->(v, _) { v }.freeze
|
18
18
|
INSPECT = ->(v, _) { v.inspect }.freeze
|
19
19
|
TO_INTEGER = ->(v, _) { v.to_i }.freeze
|
20
|
-
TO_ARRAY = ->(v, _) { v
|
20
|
+
TO_ARRAY = ->(v, _) { Array(v) }.freeze
|
21
21
|
TO_TYPE = ->(v, _) { CLASS_TO_TYPE.fetch(v.to_s.to_sym) }.freeze
|
22
22
|
|
23
23
|
# Metadata annotations and allowed types overrides for schema generation.
|
@@ -161,21 +161,33 @@ module Dry
|
|
161
161
|
|
162
162
|
definition.transform_values! { |v| v.call(type, ctx) }
|
163
163
|
|
164
|
-
return unless definition.any?
|
164
|
+
return unless definition.any?
|
165
165
|
|
166
166
|
if (extra = EXTRA_PROPS_FOR_TYPE[type.to_s.to_sym])
|
167
167
|
definition = definition.merge(extra)
|
168
168
|
end
|
169
169
|
|
170
|
-
|
171
|
-
|
170
|
+
if ctx.nil?
|
171
|
+
@keys.merge!(definition)
|
172
|
+
else
|
173
|
+
@keys[ctx] ||= {}
|
174
|
+
@keys[ctx].merge!(definition)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def visit_intersection(node, opts = EMPTY_HASH)
|
179
|
+
*types, _ = node
|
180
|
+
|
181
|
+
result = types.map { |type| compile_type(type) }
|
182
|
+
|
183
|
+
@keys[opts[:key]] = deep_merge_items(result)
|
172
184
|
end
|
173
185
|
|
174
186
|
def visit_sum(node, opts = EMPTY_HASH)
|
175
187
|
*types, _ = node
|
176
188
|
|
177
189
|
result = types
|
178
|
-
.map { |type|
|
190
|
+
.map { |type| compile_value(type, opts.merge(sum: true)) }
|
179
191
|
.uniq
|
180
192
|
|
181
193
|
return @keys[opts[:key]] = result.first if result.count == 1
|
@@ -205,14 +217,9 @@ module Dry
|
|
205
217
|
def visit_struct(node, opts = EMPTY_HASH)
|
206
218
|
_, schema = node
|
207
219
|
|
208
|
-
|
209
|
-
target = self.class.new
|
210
|
-
target.visit(schema)
|
220
|
+
return visit(schema, opts) unless opts[:key]
|
211
221
|
|
212
|
-
|
213
|
-
else
|
214
|
-
visit(schema, opts)
|
215
|
-
end
|
222
|
+
@keys[opts[:key]] = compile_type(schema)
|
216
223
|
end
|
217
224
|
|
218
225
|
def visit_array(node, opts = EMPTY_HASH)
|
@@ -253,12 +260,29 @@ module Dry
|
|
253
260
|
|
254
261
|
private
|
255
262
|
|
256
|
-
|
257
|
-
|
258
|
-
|
263
|
+
def deep_merge_items(items)
|
264
|
+
items.reduce({}) do |current, target|
|
265
|
+
current.merge(target) do |_, from, to|
|
266
|
+
case [from.class, to.class]
|
267
|
+
when [::Hash, ::Hash]
|
268
|
+
deep_merge_items([from, to])
|
269
|
+
when [::Array, ::Array]
|
270
|
+
from | to
|
271
|
+
else
|
272
|
+
to
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def compile_type(type, opts = EMPTY_HASH)
|
259
279
|
self.class.new
|
260
280
|
.tap { |target| target.visit(type, opts) }
|
261
281
|
.to_hash
|
282
|
+
end
|
283
|
+
|
284
|
+
def compile_value(type, opts = EMPTY_HASH)
|
285
|
+
compile_type(type, opts)
|
262
286
|
.values
|
263
287
|
.first
|
264
288
|
end
|
@@ -16,6 +16,14 @@ describe Dry::Types::JSONSchema do
|
|
16
16
|
{ type: :string, format: :email, title: title }
|
17
17
|
end
|
18
18
|
end
|
19
|
+
|
20
|
+
it_conforms_definition do
|
21
|
+
let(:type) { Dry::Types["string"].enum(*%w[a b]) }
|
22
|
+
|
23
|
+
let(:definition) do
|
24
|
+
{ type: :string, enum: %w[a b] }
|
25
|
+
end
|
26
|
+
end
|
19
27
|
end
|
20
28
|
|
21
29
|
describe "hash" do
|
@@ -70,6 +78,9 @@ describe Dry::Types::JSONSchema do
|
|
70
78
|
.of(Types::String)
|
71
79
|
.constrained(min_size: 1)
|
72
80
|
|
81
|
+
BasicHash = Types::Hash.schema(name: Types::String)
|
82
|
+
ExtendedHash = Types::Hash.schema(age: Types::Integer) & BasicHash
|
83
|
+
|
73
84
|
attribute :data, Types::String | Types::Hash
|
74
85
|
attribute :string, Types::String.constrained(min_size: 1, max_size: 255)
|
75
86
|
attribute :list, VariableList
|
@@ -81,6 +92,8 @@ describe Dry::Types::JSONSchema do
|
|
81
92
|
attribute? :meta, Types::String.meta(format: :email)
|
82
93
|
attribute? :enum, Types::String.enum(*%w[draft published archived])
|
83
94
|
attribute? :array, ArrayOfStrings
|
95
|
+
attribute? :inter, ExtendedHash
|
96
|
+
|
84
97
|
attribute? :nested do
|
85
98
|
attribute :deep, Types::Integer
|
86
99
|
end
|
@@ -162,6 +175,15 @@ describe Dry::Types::JSONSchema do
|
|
162
175
|
items: { type: :string }
|
163
176
|
},
|
164
177
|
|
178
|
+
inter: {
|
179
|
+
type: :object,
|
180
|
+
properties: {
|
181
|
+
age: { type: :integer },
|
182
|
+
name: { type: :string }
|
183
|
+
},
|
184
|
+
required: %i[age name]
|
185
|
+
},
|
186
|
+
|
165
187
|
nested: {
|
166
188
|
type: :object,
|
167
189
|
properties: {
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-types-json-schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- elcuervo
|
@@ -143,6 +143,7 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
+
- ".github/workflows/test.yml"
|
146
147
|
- ".gitignore"
|
147
148
|
- ".rubocop.yml"
|
148
149
|
- Gemfile
|