shale 0.3.0 → 0.5.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 +31 -0
- data/README.md +200 -21
- data/exe/shaleb +108 -36
- data/lib/shale/adapter/nokogiri/document.rb +87 -0
- data/lib/shale/adapter/nokogiri/node.rb +100 -0
- data/lib/shale/adapter/nokogiri.rb +11 -151
- data/lib/shale/adapter/ox/document.rb +80 -0
- data/lib/shale/adapter/ox/node.rb +88 -0
- data/lib/shale/adapter/ox.rb +9 -134
- data/lib/shale/adapter/rexml/document.rb +88 -0
- data/lib/shale/adapter/rexml/node.rb +99 -0
- data/lib/shale/adapter/rexml.rb +9 -150
- data/lib/shale/attribute.rb +6 -0
- data/lib/shale/error.rb +39 -0
- data/lib/shale/mapper.rb +8 -6
- data/lib/shale/schema/compiler/boolean.rb +21 -0
- data/lib/shale/schema/compiler/complex.rb +88 -0
- data/lib/shale/schema/compiler/date.rb +21 -0
- data/lib/shale/schema/compiler/float.rb +21 -0
- data/lib/shale/schema/compiler/integer.rb +21 -0
- data/lib/shale/schema/compiler/property.rb +70 -0
- data/lib/shale/schema/compiler/string.rb +21 -0
- data/lib/shale/schema/compiler/time.rb +21 -0
- data/lib/shale/schema/compiler/value.rb +21 -0
- data/lib/shale/schema/compiler/xml_complex.rb +50 -0
- data/lib/shale/schema/compiler/xml_property.rb +73 -0
- data/lib/shale/schema/json_compiler.rb +331 -0
- data/lib/shale/schema/{json → json_generator}/base.rb +2 -2
- data/lib/shale/schema/{json → json_generator}/boolean.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/collection.rb +2 -2
- data/lib/shale/schema/{json → json_generator}/date.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/float.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/integer.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/object.rb +5 -2
- data/lib/shale/schema/{json → json_generator}/ref.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/schema.rb +7 -5
- data/lib/shale/schema/{json → json_generator}/string.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/time.rb +1 -1
- data/lib/shale/schema/json_generator/value.rb +23 -0
- data/lib/shale/schema/{json.rb → json_generator.rb} +36 -36
- data/lib/shale/schema/xml_compiler.rb +919 -0
- data/lib/shale/schema/{xml → xml_generator}/attribute.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/complex_type.rb +5 -2
- data/lib/shale/schema/{xml → xml_generator}/element.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/import.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/ref_attribute.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/ref_element.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/schema.rb +5 -5
- data/lib/shale/schema/{xml → xml_generator}/typed_attribute.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/typed_element.rb +1 -1
- data/lib/shale/schema/{xml.rb → xml_generator.rb} +25 -26
- data/lib/shale/schema.rb +44 -5
- data/lib/shale/type/{composite.rb → complex.rb} +34 -22
- data/lib/shale/utils.rb +42 -7
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +8 -19
- data/shale.gemspec +1 -1
- metadata +47 -27
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'complex'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
module Compiler
|
8
|
+
# Class representing Shale's XML complex type
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class XMLComplex < Complex
|
12
|
+
# Accessor for root attribute
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_accessor :root
|
18
|
+
|
19
|
+
# Return namespace prefix
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :prefix
|
25
|
+
|
26
|
+
# Return namespace URI
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
attr_reader :namespace
|
32
|
+
|
33
|
+
# Initialize object
|
34
|
+
#
|
35
|
+
# @param [String] id
|
36
|
+
# @param [String] name
|
37
|
+
# @param [String] prefix
|
38
|
+
# @param [String] namespace
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def initialize(id, name, prefix, namespace)
|
42
|
+
super(id, name)
|
43
|
+
@root = name
|
44
|
+
@prefix = prefix
|
45
|
+
@namespace = namespace
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'property'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
module Compiler
|
8
|
+
# Class representing Shale's property
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class XMLProperty < Property
|
12
|
+
# Return namespace URI
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :namespace
|
18
|
+
|
19
|
+
# Return namespace prefix
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :prefix
|
25
|
+
|
26
|
+
# Initialize object
|
27
|
+
#
|
28
|
+
# @param [String] name
|
29
|
+
# @param [Shale::Schema::Compiler::Type] type
|
30
|
+
# @param [true, false] collection
|
31
|
+
# @param [Object] default
|
32
|
+
# @param [String] prefix
|
33
|
+
# @param [String] namespace
|
34
|
+
# @param [Symbol] category
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
def initialize(name:, type:, collection:, default:, prefix:, namespace:, category:)
|
38
|
+
super(name, type, collection, default)
|
39
|
+
@prefix = prefix
|
40
|
+
@namespace = namespace
|
41
|
+
@category = category
|
42
|
+
end
|
43
|
+
|
44
|
+
# Check if property's category is content
|
45
|
+
#
|
46
|
+
# @return [true, false]
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
def content?
|
50
|
+
@category == :content
|
51
|
+
end
|
52
|
+
|
53
|
+
# Check if property's category is attribute
|
54
|
+
#
|
55
|
+
# @return [true, false]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def attribute?
|
59
|
+
@category == :attribute
|
60
|
+
end
|
61
|
+
|
62
|
+
# Check if property's category is element
|
63
|
+
#
|
64
|
+
# @return [true, false]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
def element?
|
68
|
+
@category == :element
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
require_relative '../../shale'
|
7
|
+
require_relative 'compiler/boolean'
|
8
|
+
require_relative 'compiler/complex'
|
9
|
+
require_relative 'compiler/date'
|
10
|
+
require_relative 'compiler/float'
|
11
|
+
require_relative 'compiler/integer'
|
12
|
+
require_relative 'compiler/property'
|
13
|
+
require_relative 'compiler/string'
|
14
|
+
require_relative 'compiler/time'
|
15
|
+
require_relative 'compiler/value'
|
16
|
+
|
17
|
+
module Shale
|
18
|
+
module Schema
|
19
|
+
# Class for compiling JSON schema into Ruby data model
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
class JSONCompiler
|
23
|
+
# Default root type name
|
24
|
+
# @api private
|
25
|
+
DEFAULT_ROOT_NAME = 'root'
|
26
|
+
|
27
|
+
# Shale model template
|
28
|
+
# @api private
|
29
|
+
MODEL_TEMPLATE = ERB.new(<<~TEMPLATE, trim_mode: '-')
|
30
|
+
require 'shale'
|
31
|
+
<%- unless type.references.empty? -%>
|
32
|
+
|
33
|
+
<%- type.references.each do |property| -%>
|
34
|
+
require_relative '<%= property.type.file_name %>'
|
35
|
+
<%- end -%>
|
36
|
+
<%- end -%>
|
37
|
+
|
38
|
+
class <%= type.name %> < Shale::Mapper
|
39
|
+
<%- type.properties.each do |property| -%>
|
40
|
+
attribute :<%= property.attribute_name %>, <%= property.type.name -%>
|
41
|
+
<%- if property.collection? %>, collection: true<% end -%>
|
42
|
+
<%- unless property.default.nil? %>, default: -> { <%= property.default %> }<% end %>
|
43
|
+
<%- end -%>
|
44
|
+
|
45
|
+
json do
|
46
|
+
<%- type.properties.each do |property| -%>
|
47
|
+
map '<%= property.mapping_name %>', to: :<%= property.attribute_name %>
|
48
|
+
<%- end -%>
|
49
|
+
end
|
50
|
+
end
|
51
|
+
TEMPLATE
|
52
|
+
|
53
|
+
# Generate Shale models from JSON Schema and return them as a Ruby Array of objects
|
54
|
+
#
|
55
|
+
# @param [Array<String>] schemas
|
56
|
+
# @param [String, nil] root_name
|
57
|
+
#
|
58
|
+
# @raise [SchemaError] when JSON Schema has errors
|
59
|
+
#
|
60
|
+
# @return [Array<Shale::Schema::Compiler::Complex>]
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# Shale::Schema::JSONCompiler.new.as_models([schema1, schema2])
|
64
|
+
#
|
65
|
+
# @api public
|
66
|
+
def as_models(schemas, root_name: nil)
|
67
|
+
schemas = schemas.map do |schema|
|
68
|
+
Shale.json_adapter.load(schema)
|
69
|
+
end
|
70
|
+
|
71
|
+
@root_name = root_name
|
72
|
+
@schema_repository = {}
|
73
|
+
@types = []
|
74
|
+
|
75
|
+
schemas.each do |schema|
|
76
|
+
disassemble_schema(schema)
|
77
|
+
end
|
78
|
+
|
79
|
+
compile(schemas[0], true)
|
80
|
+
|
81
|
+
total_duplicates = Hash.new(0)
|
82
|
+
duplicates = Hash.new(0)
|
83
|
+
|
84
|
+
@types.each do |type|
|
85
|
+
total_duplicates[type.name] += 1
|
86
|
+
end
|
87
|
+
|
88
|
+
@types.each do |type|
|
89
|
+
duplicates[type.name] += 1
|
90
|
+
|
91
|
+
if total_duplicates[type.name] > 1
|
92
|
+
type.name = format("#{type.name}%d", duplicates[type.name])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
@types.reverse
|
97
|
+
end
|
98
|
+
|
99
|
+
# Generate Shale models from JSON Schema
|
100
|
+
#
|
101
|
+
# @param [Array<String>] schemas
|
102
|
+
# @param [String, nil] root_name
|
103
|
+
#
|
104
|
+
# @raise [SchemaError] when JSON Schema has errors
|
105
|
+
#
|
106
|
+
# @return [Hash<String, String>]
|
107
|
+
#
|
108
|
+
# @example
|
109
|
+
# Shale::Schema::JSONCompiler.new.to_models([schema1, schema2])
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
def to_models(schemas, root_name: nil)
|
113
|
+
types = as_models(schemas, root_name: root_name)
|
114
|
+
|
115
|
+
types.to_h do |type|
|
116
|
+
[type.file_name, MODEL_TEMPLATE.result(binding)]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# Generate JSON Schema id
|
123
|
+
#
|
124
|
+
# @param [String, nil] base_id
|
125
|
+
# @param [String, nil] id
|
126
|
+
#
|
127
|
+
# @return [String]
|
128
|
+
#
|
129
|
+
# @api private
|
130
|
+
def build_id(base_id, id)
|
131
|
+
return base_id unless id
|
132
|
+
|
133
|
+
base_uri = URI(base_id || '')
|
134
|
+
uri = URI(id)
|
135
|
+
|
136
|
+
if base_uri.relative? && uri.relative?
|
137
|
+
uri.to_s
|
138
|
+
else
|
139
|
+
base_uri.merge(uri).to_s
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Generate JSON pointer
|
144
|
+
#
|
145
|
+
# @param [String, nil] id
|
146
|
+
# @param [Array<String>] fragment
|
147
|
+
#
|
148
|
+
# @return [String]
|
149
|
+
#
|
150
|
+
# @api private
|
151
|
+
def build_pointer(id, fragment)
|
152
|
+
([id, ['#', *fragment].join('/')] - ['#']).join
|
153
|
+
end
|
154
|
+
|
155
|
+
# Resolve JSON Schem ref
|
156
|
+
#
|
157
|
+
# @param [String, nil] base_id
|
158
|
+
# @param [String, nil] ref
|
159
|
+
#
|
160
|
+
# @raise [SchemaError] when ref can't be resolved
|
161
|
+
#
|
162
|
+
# @return [Hash, true, false]
|
163
|
+
#
|
164
|
+
# @api private
|
165
|
+
def resolve_ref(base_id, ref)
|
166
|
+
ref_id, fragment = (ref || '').split('#')
|
167
|
+
id = build_id(base_id, ref_id == '' ? nil : ref_id)
|
168
|
+
key = [id, fragment].compact.join('#')
|
169
|
+
|
170
|
+
entry = @schema_repository[key]
|
171
|
+
|
172
|
+
unless entry
|
173
|
+
raise SchemaError, "can't resolve reference '#{key}'"
|
174
|
+
end
|
175
|
+
|
176
|
+
if entry[:schema].key?('$ref')
|
177
|
+
resolve_ref(id, entry[:schema]['$ref'])
|
178
|
+
else
|
179
|
+
entry
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Get Shale type from JSON Schema type
|
184
|
+
#
|
185
|
+
# @param [Hash, true, false, nil] schema
|
186
|
+
# @param [String] id
|
187
|
+
# @param [String] name
|
188
|
+
#
|
189
|
+
# @return [Shale::Schema::Compiler::Type]
|
190
|
+
#
|
191
|
+
# @api private
|
192
|
+
def infer_type(schema, id, name)
|
193
|
+
return unless schema
|
194
|
+
return Compiler::Value.new if schema == true
|
195
|
+
|
196
|
+
type = schema['type']
|
197
|
+
format = schema['format']
|
198
|
+
|
199
|
+
if type.is_a?(Array)
|
200
|
+
type -= ['null']
|
201
|
+
|
202
|
+
if type.length > 1
|
203
|
+
return Compiler::Value.new
|
204
|
+
else
|
205
|
+
type = type[0]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
if type == 'object'
|
210
|
+
Compiler::Complex.new(id, name)
|
211
|
+
elsif type == 'string' && format == 'date'
|
212
|
+
Compiler::Date.new
|
213
|
+
elsif type == 'string' && format == 'date-time'
|
214
|
+
Compiler::Time.new
|
215
|
+
elsif type == 'string'
|
216
|
+
Compiler::String.new
|
217
|
+
elsif type == 'number'
|
218
|
+
Compiler::Float.new
|
219
|
+
elsif type == 'integer'
|
220
|
+
Compiler::Integer.new
|
221
|
+
elsif type == 'boolean'
|
222
|
+
Compiler::Boolean.new
|
223
|
+
else
|
224
|
+
Compiler::Value.new
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Disassemble JSON schema into separate subschemas
|
229
|
+
#
|
230
|
+
# @param [String] schema
|
231
|
+
# @param [Array<String>] fragment
|
232
|
+
# @param [String] base_id
|
233
|
+
#
|
234
|
+
# @raise [SchemaError] when there are problems with JSON schema
|
235
|
+
#
|
236
|
+
# @api private
|
237
|
+
def disassemble_schema(schema, fragment = [], base_id = '')
|
238
|
+
schema_key = fragment[-1]
|
239
|
+
|
240
|
+
if schema.is_a?(Hash) && schema.key?('$id')
|
241
|
+
id = build_id(base_id, schema['$id'])
|
242
|
+
fragment = []
|
243
|
+
else
|
244
|
+
id = base_id
|
245
|
+
end
|
246
|
+
|
247
|
+
pointer = build_pointer(id, fragment)
|
248
|
+
|
249
|
+
if @schema_repository.key?(pointer)
|
250
|
+
raise SchemaError, "schema with id '#{pointer}' already exists"
|
251
|
+
else
|
252
|
+
@schema_repository[pointer] = {
|
253
|
+
id: pointer,
|
254
|
+
key: schema_key,
|
255
|
+
schema: schema,
|
256
|
+
}
|
257
|
+
end
|
258
|
+
|
259
|
+
return unless schema.is_a?(Hash)
|
260
|
+
|
261
|
+
['properties', '$defs'].each do |definitions|
|
262
|
+
(schema[definitions] || {}).each do |subschema_key, subschema|
|
263
|
+
disassemble_schema(subschema, [*fragment, definitions, subschema_key], id)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# Compile JSON schema into Shale types
|
269
|
+
#
|
270
|
+
# @param [String] schema
|
271
|
+
# @param [true, false] is_root
|
272
|
+
# @param [String] base_id
|
273
|
+
# @param [Array<String>] fragment
|
274
|
+
#
|
275
|
+
# @return [Shale::Schema::Compiler::Property, nil]
|
276
|
+
#
|
277
|
+
# @api private
|
278
|
+
def compile(schema, is_root, base_id = '', fragment = [])
|
279
|
+
entry = {}
|
280
|
+
key = fragment[-1]
|
281
|
+
collection = false
|
282
|
+
default = nil
|
283
|
+
|
284
|
+
if schema.is_a?(Hash) && schema.key?('$id')
|
285
|
+
id = build_id(base_id, schema['$id'])
|
286
|
+
fragment = []
|
287
|
+
else
|
288
|
+
id = base_id
|
289
|
+
end
|
290
|
+
|
291
|
+
if schema.is_a?(Hash) && schema['type'] == 'array'
|
292
|
+
collection = true
|
293
|
+
schema = schema['items']
|
294
|
+
schema ||= true
|
295
|
+
end
|
296
|
+
|
297
|
+
if schema.is_a?(Hash) && schema.key?('$ref')
|
298
|
+
entry = resolve_ref(id, schema['$ref'])
|
299
|
+
schema = entry[:schema]
|
300
|
+
fragment = entry[:id].split('/') - ['#']
|
301
|
+
end
|
302
|
+
|
303
|
+
pointer = entry[:id] || build_pointer(id, fragment)
|
304
|
+
|
305
|
+
if is_root
|
306
|
+
name = @root_name || entry[:key] || key || DEFAULT_ROOT_NAME
|
307
|
+
else
|
308
|
+
name = entry[:key] || key
|
309
|
+
end
|
310
|
+
|
311
|
+
type = @types.find { |e| e.id == pointer }
|
312
|
+
type ||= infer_type(schema, pointer, name)
|
313
|
+
|
314
|
+
if schema.is_a?(Hash) && schema.key?('default')
|
315
|
+
default = schema['default']
|
316
|
+
end
|
317
|
+
|
318
|
+
if type.is_a?(Compiler::Complex) && !@types.include?(type)
|
319
|
+
@types << type
|
320
|
+
|
321
|
+
(schema['properties'] || {}).each do |subschema_key, subschema|
|
322
|
+
property = compile(subschema, false, id, [*fragment, 'properties', subschema_key])
|
323
|
+
type.add_property(property) if property
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
Compiler::Property.new(key, type, collection, default) if type
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Shale
|
4
4
|
module Schema
|
5
|
-
class
|
5
|
+
class JSONGenerator
|
6
6
|
# Base class for JSON Schema types
|
7
7
|
#
|
8
8
|
# @api private
|
@@ -30,7 +30,7 @@ module Shale
|
|
30
30
|
# @api private
|
31
31
|
def as_json
|
32
32
|
type = as_type
|
33
|
-
type['type'] = [type['type'], 'null'] if type['type'] && @nullable
|
33
|
+
type['type'] = [*type['type'], 'null'] if type['type'] && @nullable
|
34
34
|
type['default'] = @default unless @default.nil?
|
35
35
|
|
36
36
|
type
|
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
module Shale
|
4
4
|
module Schema
|
5
|
-
class
|
5
|
+
class JSONGenerator
|
6
6
|
# Class representing array type in JSON Schema
|
7
7
|
#
|
8
8
|
# @api private
|
9
9
|
class Collection
|
10
10
|
# Initialize Collection object
|
11
11
|
#
|
12
|
-
# @param [Shale::Schema::
|
12
|
+
# @param [Shale::Schema::JSONGenerator::Base] type
|
13
13
|
#
|
14
14
|
# @api private
|
15
15
|
def initialize(type)
|
@@ -4,7 +4,7 @@ require_relative 'base'
|
|
4
4
|
|
5
5
|
module Shale
|
6
6
|
module Schema
|
7
|
-
class
|
7
|
+
class JSONGenerator
|
8
8
|
# Class representing JSON Schema object type
|
9
9
|
#
|
10
10
|
# @api private
|
@@ -12,7 +12,10 @@ module Shale
|
|
12
12
|
# Initialize object
|
13
13
|
#
|
14
14
|
# @param [String] name
|
15
|
-
# @param [
|
15
|
+
# @param [
|
16
|
+
# Array<Shale::Schema::JSONGenerator::Base,
|
17
|
+
# Shale::Schema::JSONGenerator::Collection>
|
18
|
+
# ] properties
|
16
19
|
#
|
17
20
|
# @api private
|
18
21
|
def initialize(name, properties)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Shale
|
4
4
|
module Schema
|
5
|
-
class
|
5
|
+
class JSONGenerator
|
6
6
|
# Class representing JSON schema
|
7
7
|
#
|
8
8
|
# @api private
|
@@ -13,14 +13,15 @@ module Shale
|
|
13
13
|
|
14
14
|
# Initialize Schema object
|
15
15
|
#
|
16
|
-
# @param [Array<Shale::Schema::
|
16
|
+
# @param [Array<Shale::Schema::JSONGenerator::Base>] types
|
17
17
|
# @param [String, nil] id
|
18
18
|
# @param [String, nil] description
|
19
19
|
#
|
20
20
|
# @api private
|
21
|
-
def initialize(types, id: nil, description: nil)
|
21
|
+
def initialize(types, id: nil, title: nil, description: nil)
|
22
22
|
@types = types
|
23
23
|
@id = id
|
24
|
+
@title = title
|
24
25
|
@description = description
|
25
26
|
end
|
26
27
|
|
@@ -29,13 +30,14 @@ module Shale
|
|
29
30
|
# @return [Hash]
|
30
31
|
#
|
31
32
|
# @example
|
32
|
-
# Shale::Schema::
|
33
|
+
# Shale::Schema::JSONGenerator::Schema.new(types).as_json
|
33
34
|
#
|
34
35
|
# @api private
|
35
36
|
def as_json
|
36
37
|
schema = {
|
37
38
|
'$schema' => DIALECT,
|
38
|
-
'id' => @id,
|
39
|
+
'$id' => @id,
|
40
|
+
'title' => @title,
|
39
41
|
'description' => @description,
|
40
42
|
}
|
41
43
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class JSONGenerator
|
8
|
+
# Class representing JSON Schema any type
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Value < Base
|
12
|
+
# Return JSON Schema fragment as Ruby Hash
|
13
|
+
#
|
14
|
+
# @return [Hash]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
def as_type
|
18
|
+
{ 'type' => %w[boolean integer number object string] }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|