shale 0.3.1 → 0.4.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 +15 -0
- data/README.md +105 -14
- data/exe/shaleb +79 -31
- data/lib/shale/attribute.rb +6 -0
- data/lib/shale/error.rb +6 -0
- data/lib/shale/mapper.rb +6 -4
- data/lib/shale/schema/json_compiler/boolean.rb +21 -0
- data/lib/shale/schema/json_compiler/date.rb +21 -0
- data/lib/shale/schema/json_compiler/float.rb +21 -0
- data/lib/shale/schema/json_compiler/integer.rb +21 -0
- data/lib/shale/schema/json_compiler/object.rb +85 -0
- data/lib/shale/schema/json_compiler/property.rb +70 -0
- data/lib/shale/schema/json_compiler/string.rb +21 -0
- data/lib/shale/schema/json_compiler/time.rb +21 -0
- data/lib/shale/schema/json_compiler/utils.rb +52 -0
- data/lib/shale/schema/json_compiler/value.rb +13 -0
- data/lib/shale/schema/json_compiler.rb +333 -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 +6 -4
- 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 → 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} +22 -23
- data/lib/shale/schema.rb +28 -5
- data/lib/shale/type/composite.rb +14 -20
- data/lib/shale/version.rb +1 -1
- metadata +36 -24
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'utils'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class JSONCompiler
|
8
|
+
# Class representing Shale's property
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Property
|
12
|
+
# Return property's name
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :property_name
|
18
|
+
|
19
|
+
# Return attribute's name
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :attribute_name
|
25
|
+
|
26
|
+
# Return types's name
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
attr_reader :type
|
32
|
+
|
33
|
+
# Initialize Property object
|
34
|
+
#
|
35
|
+
# @param [String] name
|
36
|
+
# @param [Shale::Schema::JsonCompiler::Type] type
|
37
|
+
# @param [true, false] collection
|
38
|
+
# @param [Object] default
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def initialize(name, type, collection, default)
|
42
|
+
@property_name = name
|
43
|
+
@attribute_name = Utils.snake_case(name)
|
44
|
+
@type = type
|
45
|
+
@collection = collection
|
46
|
+
@default = default
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return whether property is a collection
|
50
|
+
#
|
51
|
+
# @return [true, false]
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
def collection?
|
55
|
+
@collection
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return default value
|
59
|
+
#
|
60
|
+
# @return [nil, Object]
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
def default
|
64
|
+
return if collection?
|
65
|
+
@default.is_a?(::String) ? @default.dump : @default
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale String type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class String
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::String'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale Time type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Time
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Time'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Module with utility functions
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
module Utils
|
10
|
+
# Convert string to Ruby's class naming convention
|
11
|
+
#
|
12
|
+
# @param [String] val
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# Shale::Schema::JSONCompiler.classify('foobar')
|
16
|
+
# # => 'Foobar'
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
def self.classify(str)
|
20
|
+
str = str.to_s.sub(/.*\./, '')
|
21
|
+
|
22
|
+
str = str.sub(/^[a-z\d]*/) { |match| match.capitalize || match }
|
23
|
+
|
24
|
+
str.gsub(%r{(?:_|(/))([a-z\d]*)}i) do
|
25
|
+
word = Regexp.last_match(2)
|
26
|
+
substituted = word.capitalize || word
|
27
|
+
Regexp.last_match(1) ? "::#{substituted}" : substituted
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Convert string to snake case
|
32
|
+
#
|
33
|
+
# @param [String] val
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# Shale::Schema::JSONCompiler.snake_case('FooBar')
|
37
|
+
# # => 'foo_bar'
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def self.snake_case(str)
|
41
|
+
return str.to_s unless /[A-Z-]|::/.match?(str)
|
42
|
+
word = str.to_s.gsub('::', '/')
|
43
|
+
word = word.gsub(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
|
44
|
+
"#{Regexp.last_match(1) || Regexp.last_match(2)}_"
|
45
|
+
end
|
46
|
+
word = word.tr('-', '_')
|
47
|
+
word.downcase
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,333 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
require_relative '../../shale'
|
7
|
+
require_relative 'json_compiler/boolean'
|
8
|
+
require_relative 'json_compiler/date'
|
9
|
+
require_relative 'json_compiler/float'
|
10
|
+
require_relative 'json_compiler/integer'
|
11
|
+
require_relative 'json_compiler/object'
|
12
|
+
require_relative 'json_compiler/property'
|
13
|
+
require_relative 'json_compiler/string'
|
14
|
+
require_relative 'json_compiler/time'
|
15
|
+
require_relative 'json_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.property_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 od objects
|
54
|
+
#
|
55
|
+
# @param [Array<String>] schemas
|
56
|
+
# @param [String, nil] root_name
|
57
|
+
#
|
58
|
+
# @raise [JSONSchemaError] when JSON Schema has errors
|
59
|
+
#
|
60
|
+
# @return [Array<Shale::Schema::JSONCompiler::Object>]
|
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
|
+
# rubocop:disable Style/CombinableLoops
|
85
|
+
@types.each do |type|
|
86
|
+
total_duplicates[type.name] += 1
|
87
|
+
end
|
88
|
+
|
89
|
+
@types.each do |type|
|
90
|
+
duplicates[type.name] += 1
|
91
|
+
|
92
|
+
if total_duplicates[type.name] > 1
|
93
|
+
type.name = format("#{type.name}%d", duplicates[type.name])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
# rubocop:enable Style/CombinableLoops
|
97
|
+
|
98
|
+
@types.reverse
|
99
|
+
end
|
100
|
+
|
101
|
+
# Generate Shale models from JSON Schema
|
102
|
+
#
|
103
|
+
# @param [Array<String>] schemas
|
104
|
+
# @param [String, nil] root_name
|
105
|
+
#
|
106
|
+
# @raise [JSONSchemaError] when JSON Schema has errors
|
107
|
+
#
|
108
|
+
# @return [Hash<String, String>]
|
109
|
+
#
|
110
|
+
# @example
|
111
|
+
# Shale::Schema::JSONCompiler.new.to_models([schema1, schema2])
|
112
|
+
#
|
113
|
+
# @api public
|
114
|
+
def to_models(schemas, root_name: nil)
|
115
|
+
types = as_models(schemas, root_name: root_name)
|
116
|
+
|
117
|
+
types.to_h do |type|
|
118
|
+
[type.file_name, MODEL_TEMPLATE.result(binding)]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# Generate JSON Schema id
|
125
|
+
#
|
126
|
+
# @param [String, nil] base_id
|
127
|
+
# @param [String, nil] id
|
128
|
+
#
|
129
|
+
# @return [String]
|
130
|
+
#
|
131
|
+
# @api private
|
132
|
+
def build_id(base_id, id)
|
133
|
+
return base_id unless id
|
134
|
+
|
135
|
+
base_uri = URI(base_id || '')
|
136
|
+
uri = URI(id)
|
137
|
+
|
138
|
+
if base_uri.relative? && uri.relative?
|
139
|
+
uri.to_s
|
140
|
+
else
|
141
|
+
base_uri.merge(uri).to_s
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Generate JSON pointer
|
146
|
+
#
|
147
|
+
# @param [String, nil] id
|
148
|
+
# @param [Array<String>] fragment
|
149
|
+
#
|
150
|
+
# @return [String]
|
151
|
+
#
|
152
|
+
# @api private
|
153
|
+
def build_pointer(id, fragment)
|
154
|
+
([id, ['#', *fragment].join('/')] - ['#']).join
|
155
|
+
end
|
156
|
+
|
157
|
+
# Resolve JSON Schem ref
|
158
|
+
#
|
159
|
+
# @param [String, nil] base_id
|
160
|
+
# @param [String, nil] ref
|
161
|
+
#
|
162
|
+
# @raise [JSONSchemaError] when ref can't be resolved
|
163
|
+
#
|
164
|
+
# @return [Hash, true, false]
|
165
|
+
#
|
166
|
+
# @api private
|
167
|
+
def resolve_ref(base_id, ref)
|
168
|
+
ref_id, fragment = (ref || '').split('#')
|
169
|
+
id = build_id(base_id, ref_id == '' ? nil : ref_id)
|
170
|
+
key = [id, fragment].compact.join('#')
|
171
|
+
|
172
|
+
entry = @schema_repository[key]
|
173
|
+
|
174
|
+
unless entry
|
175
|
+
raise JSONSchemaError, "can't resolve reference '#{key}'"
|
176
|
+
end
|
177
|
+
|
178
|
+
if entry[:schema].key?('$ref')
|
179
|
+
resolve_ref(id, entry[:schema]['$ref'])
|
180
|
+
else
|
181
|
+
entry
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Get Shale type from JSON Schema type
|
186
|
+
#
|
187
|
+
# @param [Hash, true, false, nil] schema
|
188
|
+
# @param [String] id
|
189
|
+
# @param [String] name
|
190
|
+
#
|
191
|
+
# @return [Shale::Schema::JSONCompiler::Type]
|
192
|
+
#
|
193
|
+
# @api private
|
194
|
+
def infer_type(schema, id, name)
|
195
|
+
return unless schema
|
196
|
+
return Value.new if schema == true
|
197
|
+
|
198
|
+
type = schema['type']
|
199
|
+
format = schema['format']
|
200
|
+
|
201
|
+
if type.is_a?(Array)
|
202
|
+
type -= ['null']
|
203
|
+
|
204
|
+
if type.length > 1
|
205
|
+
return Value.new
|
206
|
+
else
|
207
|
+
type = type[0]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
if type == 'object'
|
212
|
+
Object.new(id, name)
|
213
|
+
elsif type == 'string' && format == 'date'
|
214
|
+
Date.new
|
215
|
+
elsif type == 'string' && format == 'date-time'
|
216
|
+
Time.new
|
217
|
+
elsif type == 'string'
|
218
|
+
String.new
|
219
|
+
elsif type == 'number'
|
220
|
+
Float.new
|
221
|
+
elsif type == 'integer'
|
222
|
+
Integer.new
|
223
|
+
elsif type == 'boolean'
|
224
|
+
Boolean.new
|
225
|
+
else
|
226
|
+
Value.new
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Disassemble JSON schema into separate subschemas
|
231
|
+
#
|
232
|
+
# @param [String] schema
|
233
|
+
# @param [Array<String>] fragment
|
234
|
+
# @param [String] base_id
|
235
|
+
#
|
236
|
+
# @raise [JSONSchemaError] when there are problems with JSON schema
|
237
|
+
#
|
238
|
+
# @api private
|
239
|
+
def disassemble_schema(schema, fragment = [], base_id = '')
|
240
|
+
schema_key = fragment[-1]
|
241
|
+
|
242
|
+
if schema.is_a?(Hash) && schema.key?('$id')
|
243
|
+
id = build_id(base_id, schema['$id'])
|
244
|
+
fragment = []
|
245
|
+
else
|
246
|
+
id = base_id
|
247
|
+
end
|
248
|
+
|
249
|
+
pointer = build_pointer(id, fragment)
|
250
|
+
|
251
|
+
if @schema_repository.key?(pointer)
|
252
|
+
raise JSONSchemaError, "schema with id '#{pointer}' already exists"
|
253
|
+
else
|
254
|
+
@schema_repository[pointer] = {
|
255
|
+
id: pointer,
|
256
|
+
key: schema_key,
|
257
|
+
schema: schema,
|
258
|
+
}
|
259
|
+
end
|
260
|
+
|
261
|
+
return unless schema.is_a?(Hash)
|
262
|
+
|
263
|
+
['properties', '$defs'].each do |definitions|
|
264
|
+
(schema[definitions] || {}).each do |subschema_key, subschema|
|
265
|
+
disassemble_schema(subschema, [*fragment, definitions, subschema_key], id)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# Compile JSON schema into Shale types
|
271
|
+
#
|
272
|
+
# @param [String] schema
|
273
|
+
# @param [true, false] is_root
|
274
|
+
# @param [String] base_id
|
275
|
+
# @param [Array<String>] fragment
|
276
|
+
#
|
277
|
+
# @return [Shale::Schema::JSONCompiler::Property, nil]
|
278
|
+
#
|
279
|
+
# @api private
|
280
|
+
def compile(schema, is_root, base_id = '', fragment = [])
|
281
|
+
entry = {}
|
282
|
+
key = fragment[-1]
|
283
|
+
collection = false
|
284
|
+
default = nil
|
285
|
+
|
286
|
+
if schema.is_a?(Hash) && schema.key?('$id')
|
287
|
+
id = build_id(base_id, schema['$id'])
|
288
|
+
fragment = []
|
289
|
+
else
|
290
|
+
id = base_id
|
291
|
+
end
|
292
|
+
|
293
|
+
if schema.is_a?(Hash) && schema['type'] == 'array'
|
294
|
+
collection = true
|
295
|
+
schema = schema['items']
|
296
|
+
schema ||= true
|
297
|
+
end
|
298
|
+
|
299
|
+
if schema.is_a?(Hash) && schema.key?('$ref')
|
300
|
+
entry = resolve_ref(id, schema['$ref'])
|
301
|
+
schema = entry[:schema]
|
302
|
+
fragment = entry[:id].split('/') - ['#']
|
303
|
+
end
|
304
|
+
|
305
|
+
pointer = entry[:id] || build_pointer(id, fragment)
|
306
|
+
|
307
|
+
if is_root
|
308
|
+
name = @root_name || entry[:key] || key || DEFAULT_ROOT_NAME
|
309
|
+
else
|
310
|
+
name = entry[:key] || key
|
311
|
+
end
|
312
|
+
|
313
|
+
type = @types.find { |e| e.id == pointer }
|
314
|
+
type ||= infer_type(schema, pointer, name)
|
315
|
+
|
316
|
+
if schema.is_a?(Hash) && schema.key?('default')
|
317
|
+
default = schema['default']
|
318
|
+
end
|
319
|
+
|
320
|
+
if type.is_a?(Object) && !@types.include?(type)
|
321
|
+
@types << type
|
322
|
+
|
323
|
+
(schema['properties'] || {}).each do |subschema_key, subschema|
|
324
|
+
property = compile(subschema, false, id, [*fragment, 'properties', subschema_key])
|
325
|
+
type.add_property(property) if property
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
Property.new(key, type, collection, default) if type
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
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
39
|
'$id' => @id,
|
40
|
+
'title' => @title,
|
39
41
|
'description' => @description,
|
40
42
|
}
|
41
43
|
|