dry-schema-extensions 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +20 -0
- data/dry-schema-extensions.gemspec +32 -0
- data/lib/dry/schema/extensions/json_schema/schema_compiler.rb +232 -0
- data/lib/dry/schema/extensions/json_schema.rb +29 -0
- data/lib/dry/schema/extensions/open_api/schema_compiler.rb +54 -0
- data/lib/dry/schema/extensions/open_api.rb +29 -0
- data/lib/dry-schema-extensions.rb +11 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f043a132971608919006d6b21f62bb0f057b56511b9bc35c25d3eaa5000d0b19
|
4
|
+
data.tar.gz: b50c68c80aba6e494769c28cfdf10bacd77b5a777426c899cee91006671b6470
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0acd59392bd0db95ad17013191e7610f21823ef9f5748d822ec89eca1e1bdc4a5e2570e2a6c820797a2736aec02b571bf211ef3504da853926b32474fdfc685d
|
7
|
+
data.tar.gz: 75c8127d2c0b38d08bf7da60dd30d339c3df4776ed01fbc3de6f5dfcf16cba88f8b90f305ab1dcd021a8507b270bb072827dc771d87b620ebe5cfb4f71ae31fb
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015-2021 dry-rb team
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# dry-schema-extensions
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/dry-schema-extensions.svg)][gem]
|
4
|
+
[![CI Status](https://github.com/ianks/dry-schema-extensions/workflows/CI/badge.svg)][actions]
|
5
|
+
|
6
|
+
## Extensions Provided
|
7
|
+
|
8
|
+
* [Open API Extension](docsite/source/extensions/open_api.html.md)
|
9
|
+
* [JSON Schema Extension](docsite/source/extensions/json_schema.html.md)
|
10
|
+
|
11
|
+
## Supported Ruby versions
|
12
|
+
|
13
|
+
This library officially supports the following Ruby versions:
|
14
|
+
|
15
|
+
* MRI `>= 2.6.0`
|
16
|
+
* ~~jruby~~ `>= 9.3` (we are waiting for [2.6 support](https://github.com/jruby/jruby/issues/6161))
|
17
|
+
|
18
|
+
## License
|
19
|
+
|
20
|
+
See `LICENSE` file.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# this file is synced from dry-rb/template-gem project
|
4
|
+
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = "dry-schema-extensions"
|
10
|
+
spec.authors = ["Ian Ker-Seymer"]
|
11
|
+
spec.email = ["i.kerseymer@gmail.com"]
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.version = "1.0.0"
|
14
|
+
|
15
|
+
spec.summary = "OpenAPI and JSON Schema extension for dry-schema"
|
16
|
+
spec.description = <<~TEXT
|
17
|
+
Enhances dry-schema with the ability to export convert dry-schemas to OpenAPI definitions.
|
18
|
+
TEXT
|
19
|
+
spec.homepage = "https://dry-rb.org/gems/dry-schema"
|
20
|
+
spec.files = Dir["LICENSE", "README.md", "dry-schema-extensions.gemspec", "lib/**/*"]
|
21
|
+
spec.bindir = "bin"
|
22
|
+
spec.executables = []
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.required_ruby_version = ">= 2.6.0"
|
26
|
+
|
27
|
+
spec.add_runtime_dependency "dry-schema", ">= 1.6.1"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler"
|
30
|
+
spec.add_development_dependency "rake"
|
31
|
+
spec.add_development_dependency "rspec"
|
32
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/constants"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
# @api private
|
8
|
+
module JSONSchema
|
9
|
+
# @api private
|
10
|
+
class SchemaCompiler
|
11
|
+
# An error raised when a predicate cannot be converted
|
12
|
+
UnknownConversionError = Class.new(StandardError)
|
13
|
+
|
14
|
+
IDENTITY = ->(v, _) { v }.freeze
|
15
|
+
TO_INTEGER = ->(v, _) { v.to_i }.freeze
|
16
|
+
|
17
|
+
PREDICATE_TO_TYPE = {
|
18
|
+
array?: {type: "array"},
|
19
|
+
bool?: {type: "boolean"},
|
20
|
+
date?: {type: "string", format: "date"},
|
21
|
+
date_time?: {type: "string", format: "date-time"},
|
22
|
+
decimal?: {type: "number"},
|
23
|
+
float?: {type: "number"},
|
24
|
+
hash?: {type: "object"},
|
25
|
+
int?: {type: "integer"},
|
26
|
+
nil?: {type: "null"},
|
27
|
+
str?: {type: "string"},
|
28
|
+
time?: {type: "string", format: "time"},
|
29
|
+
min_size?: {minLength: TO_INTEGER},
|
30
|
+
max_size?: {maxLength: TO_INTEGER},
|
31
|
+
included_in?: {enum: ->(v, _) { v.to_a }},
|
32
|
+
filled?: EMPTY_HASH,
|
33
|
+
uri?: {format: "uri"},
|
34
|
+
uuid_v1?: {
|
35
|
+
pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$"
|
36
|
+
},
|
37
|
+
uuid_v2?: {
|
38
|
+
pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$"
|
39
|
+
},
|
40
|
+
uuid_v3?: {
|
41
|
+
pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$"
|
42
|
+
},
|
43
|
+
uuid_v4?: {
|
44
|
+
pattern: "^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"
|
45
|
+
},
|
46
|
+
uuid_v5?: {
|
47
|
+
pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$"
|
48
|
+
},
|
49
|
+
gt?: {exclusiveMinimum: IDENTITY},
|
50
|
+
gteq?: {mininum: IDENTITY},
|
51
|
+
lt?: {exclusiveMaximum: IDENTITY},
|
52
|
+
lteq?: {maximum: IDENTITY},
|
53
|
+
odd?: {type: "integer", not: {multipleOf: 2}},
|
54
|
+
even?: {type: "integer", multipleOf: 2}
|
55
|
+
}.freeze
|
56
|
+
|
57
|
+
# @api private
|
58
|
+
attr_reader :keys, :required
|
59
|
+
|
60
|
+
# @api private
|
61
|
+
def initialize(root: false, loose: false)
|
62
|
+
@keys = EMPTY_HASH.dup
|
63
|
+
@required = Set.new
|
64
|
+
@root = root
|
65
|
+
@loose = loose
|
66
|
+
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def to_hash
|
70
|
+
result = {}
|
71
|
+
result[:$schema] = "http://json-schema.org/draft-06/schema#" if root?
|
72
|
+
result.merge!(type: "object", properties: keys, required: required.to_a)
|
73
|
+
result
|
74
|
+
end
|
75
|
+
|
76
|
+
alias_method :to_h, :to_hash
|
77
|
+
|
78
|
+
# @api private
|
79
|
+
def call(ast)
|
80
|
+
visit(ast)
|
81
|
+
end
|
82
|
+
|
83
|
+
# @api private
|
84
|
+
def visit(node, opts = EMPTY_HASH)
|
85
|
+
meth, rest = node
|
86
|
+
public_send(:"visit_#{meth}", rest, opts)
|
87
|
+
end
|
88
|
+
|
89
|
+
# @api private
|
90
|
+
def visit_set(node, opts = EMPTY_HASH)
|
91
|
+
target = (key = opts[:key]) ? self.class.new : self
|
92
|
+
|
93
|
+
node.map { |child| target.visit(child, opts) }
|
94
|
+
|
95
|
+
return unless key
|
96
|
+
|
97
|
+
target_info = opts[:member] ? {items: target.to_h} : target.to_h
|
98
|
+
type = opts[:member] ? "array" : "object"
|
99
|
+
|
100
|
+
keys.update(key => {**keys[key], type: type, **target_info})
|
101
|
+
end
|
102
|
+
|
103
|
+
# @api private
|
104
|
+
def visit_and(node, opts = EMPTY_HASH)
|
105
|
+
left, right = node
|
106
|
+
|
107
|
+
# We need to know the type first to apply filled macro
|
108
|
+
if left[1][0] == :filled?
|
109
|
+
visit(right, opts)
|
110
|
+
visit(left, opts)
|
111
|
+
else
|
112
|
+
visit(left, opts)
|
113
|
+
visit(right, opts)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# @api private
|
118
|
+
def visit_implication(node, opts = EMPTY_HASH)
|
119
|
+
node.each do |el|
|
120
|
+
visit(el, **opts, required: false)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# @api private
|
125
|
+
def visit_each(node, opts = EMPTY_HASH)
|
126
|
+
visit(node, opts.merge(member: true))
|
127
|
+
end
|
128
|
+
|
129
|
+
# @api private
|
130
|
+
def visit_key(node, opts = EMPTY_HASH)
|
131
|
+
name, rest = node
|
132
|
+
|
133
|
+
if opts.fetch(:required, :true)
|
134
|
+
required << name.to_s
|
135
|
+
else
|
136
|
+
opts.delete(:required)
|
137
|
+
end
|
138
|
+
|
139
|
+
visit(rest, opts.merge(key: name))
|
140
|
+
end
|
141
|
+
|
142
|
+
# @api private
|
143
|
+
def visit_not(node, opts = EMPTY_HASH)
|
144
|
+
_name, rest = node
|
145
|
+
|
146
|
+
visit_predicate(rest, opts)
|
147
|
+
end
|
148
|
+
|
149
|
+
# @api private
|
150
|
+
def visit_predicate(node, opts = EMPTY_HASH)
|
151
|
+
name, rest = node
|
152
|
+
|
153
|
+
if name.equal?(:key?)
|
154
|
+
prop_name = rest[0][1]
|
155
|
+
keys[prop_name] = {}
|
156
|
+
else
|
157
|
+
target = keys[opts[:key]]
|
158
|
+
type_opts = fetch_type_opts_for_predicate(name, rest, target)
|
159
|
+
|
160
|
+
if target[:type]&.include?("array")
|
161
|
+
target[:items] ||= {}
|
162
|
+
merge_opts!(target[:items], type_opts)
|
163
|
+
else
|
164
|
+
merge_opts!(target, type_opts)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# @api private
|
170
|
+
def fetch_type_opts_for_predicate(name, rest, target)
|
171
|
+
type_opts = PREDICATE_TO_TYPE.fetch(name) do
|
172
|
+
raise_unknown_conversion_error!(:predicate, name) unless loose?
|
173
|
+
|
174
|
+
EMPTY_HASH
|
175
|
+
end.dup
|
176
|
+
type_opts.transform_values! { |v| v.respond_to?(:call) ? v.call(rest[0][1], target) : v }
|
177
|
+
type_opts.merge!(fetch_filled_options(target[:type], target)) if name == :filled?
|
178
|
+
type_opts
|
179
|
+
end
|
180
|
+
|
181
|
+
# @api private
|
182
|
+
def fetch_filled_options(type, _target)
|
183
|
+
case type
|
184
|
+
when "string"
|
185
|
+
{minLength: 1}
|
186
|
+
when "array"
|
187
|
+
raise_unknown_conversion_error!(:type, :array) unless loose?
|
188
|
+
|
189
|
+
{not: {type: "null"}}
|
190
|
+
else
|
191
|
+
{not: {type: "null"}}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# @api private
|
196
|
+
def merge_opts!(orig_opts, new_opts)
|
197
|
+
new_type = new_opts[:type]
|
198
|
+
orig_type = orig_opts[:type]
|
199
|
+
|
200
|
+
if orig_type && new_type && orig_type != new_type
|
201
|
+
new_opts[:type] = [orig_type, new_type]
|
202
|
+
end
|
203
|
+
|
204
|
+
orig_opts.merge!(new_opts)
|
205
|
+
end
|
206
|
+
|
207
|
+
# @api private
|
208
|
+
def root?
|
209
|
+
@root
|
210
|
+
end
|
211
|
+
|
212
|
+
# @api private
|
213
|
+
def loose?
|
214
|
+
@loose
|
215
|
+
end
|
216
|
+
|
217
|
+
def raise_unknown_conversion_error!(type, name)
|
218
|
+
message = <<~MSG
|
219
|
+
Could not find an equivalent conversion for #{type} #{name.inspect}.
|
220
|
+
|
221
|
+
This means that your generated JSON schema may be missing this validation.
|
222
|
+
|
223
|
+
You can ignore this by generating the schema in "loose" mode, i.e.:
|
224
|
+
my_schema.json_schema(loose: true)
|
225
|
+
MSG
|
226
|
+
|
227
|
+
raise UnknownConversionError, message.chomp
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/extensions/json_schema/schema_compiler"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
# JSONSchema extension
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
module JSONSchema
|
11
|
+
module SchemaMethods
|
12
|
+
# Convert the schema into a JSON schema hash
|
13
|
+
#
|
14
|
+
# @param [Symbol] loose Compile the schema in "loose" mode
|
15
|
+
#
|
16
|
+
# @return [Hash<Symbol=>Hash>]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def json_schema(loose: false)
|
20
|
+
compiler = SchemaCompiler.new(root: true, loose: loose)
|
21
|
+
compiler.call(to_ast)
|
22
|
+
compiler.to_hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Processor.include(JSONSchema::SchemaMethods)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/extensions/json_schema/schema_compiler"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
# @api private
|
8
|
+
module OpenAPI
|
9
|
+
# @api private
|
10
|
+
class SchemaCompiler < JSONSchema::SchemaCompiler
|
11
|
+
UnknownConversionError = Class.new(StandardError)
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
transform_json_schema_hash!(super)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def transform_json_schema_hash!(hash)
|
20
|
+
hash.delete(:$schema)
|
21
|
+
transform_nullables!(hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
def transform_nullables!(hash)
|
25
|
+
deep_transform_values!(hash) do |input|
|
26
|
+
next input unless input.respond_to?(:key?)
|
27
|
+
next input unless input[:type].respond_to?(:each)
|
28
|
+
|
29
|
+
types = input[:type]
|
30
|
+
input[:nullable] = true if types.delete("null")
|
31
|
+
|
32
|
+
if types.length == 1
|
33
|
+
input[:type] = types.first
|
34
|
+
input
|
35
|
+
else
|
36
|
+
raise UnknownConversionError, "cannot map type #{types.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def deep_transform_values!(hash, &block)
|
42
|
+
case hash
|
43
|
+
when Hash
|
44
|
+
hash.transform_values! { |value| deep_transform_values!(yield(value), &block) }
|
45
|
+
when Array
|
46
|
+
hash.map! { |e| deep_transform_values!(e, &block) }
|
47
|
+
else
|
48
|
+
yield(hash)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/extensions/open_api/schema_compiler"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
# JSONSchema extension
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
module OpenAPI
|
11
|
+
module SchemaMethods
|
12
|
+
# Convert the schema into a JSON schema hash
|
13
|
+
#
|
14
|
+
# @param [Symbol] loose Compile the schema in "loose" mode
|
15
|
+
#
|
16
|
+
# @return [Hash<Symbol=>Hash>]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def open_api(loose: false)
|
20
|
+
compiler = SchemaCompiler.new(root: true, loose: loose)
|
21
|
+
compiler.call(to_ast)
|
22
|
+
compiler.to_hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Processor.include(OpenAPI::SchemaMethods)
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dry-schema-extensions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ian Ker-Seymer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-09-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dry-schema
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.6.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.6.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: 'Enhances dry-schema with the ability to export convert dry-schemas to
|
70
|
+
OpenAPI definitions.
|
71
|
+
|
72
|
+
'
|
73
|
+
email:
|
74
|
+
- i.kerseymer@gmail.com
|
75
|
+
executables: []
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- dry-schema-extensions.gemspec
|
82
|
+
- lib/dry-schema-extensions.rb
|
83
|
+
- lib/dry/schema/extensions/json_schema.rb
|
84
|
+
- lib/dry/schema/extensions/json_schema/schema_compiler.rb
|
85
|
+
- lib/dry/schema/extensions/open_api.rb
|
86
|
+
- lib/dry/schema/extensions/open_api/schema_compiler.rb
|
87
|
+
homepage: https://dry-rb.org/gems/dry-schema
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 2.6.0
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubygems_version: 3.1.2
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: OpenAPI and JSON Schema extension for dry-schema
|
110
|
+
test_files: []
|