apiwork 0.3.1 → 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/lib/apiwork/adapter/serializer/resource/base.rb +15 -0
- data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +4 -3
- data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +13 -9
- data/lib/apiwork/api/base.rb +105 -17
- data/lib/apiwork/api/element.rb +35 -4
- data/lib/apiwork/api/object.rb +72 -7
- data/lib/apiwork/api/router.rb +16 -0
- data/lib/apiwork/configuration/validatable.rb +1 -0
- data/lib/apiwork/configuration.rb +2 -0
- data/lib/apiwork/contract/element.rb +19 -4
- data/lib/apiwork/contract/object/coercer.rb +31 -2
- data/lib/apiwork/contract/object/deserializer.rb +5 -1
- data/lib/apiwork/contract/object/transformer.rb +15 -2
- data/lib/apiwork/contract/object/validator.rb +49 -11
- data/lib/apiwork/contract/object.rb +79 -9
- data/lib/apiwork/element.rb +34 -1
- data/lib/apiwork/export/base.rb +1 -4
- data/lib/apiwork/export/builder_mapper.rb +184 -0
- data/lib/apiwork/export/open_api.rb +9 -2
- data/lib/apiwork/export/sorbus.rb +5 -1
- data/lib/apiwork/export/sorbus_mapper.rb +3 -7
- data/lib/apiwork/export/type_analysis.rb +20 -6
- data/lib/apiwork/export/type_script.rb +4 -1
- data/lib/apiwork/export/type_script_mapper.rb +25 -2
- data/lib/apiwork/export/zod.rb +9 -0
- data/lib/apiwork/export/zod_mapper.rb +22 -1
- data/lib/apiwork/introspection/api.rb +18 -0
- data/lib/apiwork/introspection/dump/action.rb +1 -1
- data/lib/apiwork/introspection/dump/api.rb +2 -0
- data/lib/apiwork/introspection/dump/param.rb +36 -20
- data/lib/apiwork/introspection/dump/resource.rb +7 -4
- data/lib/apiwork/introspection/dump/type.rb +31 -25
- data/lib/apiwork/introspection/param/array.rb +26 -0
- data/lib/apiwork/introspection/param/base.rb +15 -25
- data/lib/apiwork/introspection/param/binary.rb +36 -0
- data/lib/apiwork/introspection/param/boolean.rb +36 -0
- data/lib/apiwork/introspection/param/date.rb +36 -0
- data/lib/apiwork/introspection/param/date_time.rb +36 -0
- data/lib/apiwork/introspection/param/decimal.rb +26 -0
- data/lib/apiwork/introspection/param/integer.rb +26 -0
- data/lib/apiwork/introspection/param/number.rb +26 -0
- data/lib/apiwork/introspection/param/record.rb +71 -0
- data/lib/apiwork/introspection/param/string.rb +26 -0
- data/lib/apiwork/introspection/param/time.rb +36 -0
- data/lib/apiwork/introspection/param/uuid.rb +36 -0
- data/lib/apiwork/introspection/param.rb +1 -0
- data/lib/apiwork/introspection.rb +17 -4
- data/lib/apiwork/object.rb +246 -4
- data/lib/apiwork/representation/attribute.rb +2 -2
- data/lib/apiwork/representation/base.rb +107 -2
- data/lib/apiwork/representation/element.rb +15 -5
- data/lib/apiwork/version.rb +1 -1
- metadata +6 -4
|
@@ -7,8 +7,12 @@ module Apiwork
|
|
|
7
7
|
output :string
|
|
8
8
|
file_extension '.ts'
|
|
9
9
|
|
|
10
|
+
option :builders, default: false, type: :boolean
|
|
11
|
+
|
|
10
12
|
def generate
|
|
11
|
-
SorbusMapper.map(self, surface)
|
|
13
|
+
output = SorbusMapper.map(self, surface)
|
|
14
|
+
output += "\n\n#{BuilderMapper.map(self, surface)}" if options[:builders]
|
|
15
|
+
output
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
private
|
|
@@ -37,10 +37,8 @@ module Apiwork
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def build_contract
|
|
40
|
-
contract = {
|
|
41
|
-
|
|
42
|
-
error: build_error_schema,
|
|
43
|
-
}
|
|
40
|
+
contract = { endpoints: build_endpoint_tree(@export.api.resources) }
|
|
41
|
+
contract[:error] = build_error_schema if @surface.types.key?(:error)
|
|
44
42
|
"export const contract = #{format_object(contract, indent: 0)} as const;"
|
|
45
43
|
end
|
|
46
44
|
|
|
@@ -80,9 +78,7 @@ module Apiwork
|
|
|
80
78
|
end
|
|
81
79
|
|
|
82
80
|
def transform_path(path)
|
|
83
|
-
path.gsub(
|
|
84
|
-
"#{::Regexp.last_match(1)}#{@export.transform_key(::Regexp.last_match(2))}"
|
|
85
|
-
end
|
|
81
|
+
path.to_s.gsub(/:(\w+)/) { ":#{@export.transform_key(::Regexp.last_match(1))}" }
|
|
86
82
|
end
|
|
87
83
|
|
|
88
84
|
def extract_path_params(path)
|
|
@@ -4,9 +4,8 @@ module Apiwork
|
|
|
4
4
|
module Export
|
|
5
5
|
class TypeAnalysis
|
|
6
6
|
PRIMITIVE_TYPES = %i[
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
unknown
|
|
7
|
+
array binary boolean date datetime decimal enum float integer json
|
|
8
|
+
literal number object record string text time union unknown uuid
|
|
10
9
|
].to_set.freeze
|
|
11
10
|
|
|
12
11
|
class << self
|
|
@@ -39,11 +38,22 @@ module Apiwork
|
|
|
39
38
|
|
|
40
39
|
def find_cycle_breaking_types(graph)
|
|
41
40
|
lazy_types = Set.new
|
|
41
|
+
reduced_graph = graph
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
loop do
|
|
44
|
+
previous_size = lazy_types.size
|
|
45
|
+
|
|
46
|
+
find_strongly_connected_components(reduced_graph).each do |component|
|
|
47
|
+
next if component.size == 1 && !reduced_graph[component.first].include?(component.first)
|
|
48
|
+
|
|
49
|
+
lazy_types.add(select_cycle_breaker(component, reduced_graph))
|
|
50
|
+
end
|
|
45
51
|
|
|
46
|
-
lazy_types.
|
|
52
|
+
break if lazy_types.size == previous_size
|
|
53
|
+
|
|
54
|
+
reduced_graph = reduced_graph
|
|
55
|
+
.reject { |node, _| lazy_types.include?(node) }
|
|
56
|
+
.transform_values { |deps| deps - lazy_types.to_a }
|
|
47
57
|
end
|
|
48
58
|
|
|
49
59
|
lazy_types
|
|
@@ -114,6 +124,10 @@ module Apiwork
|
|
|
114
124
|
state[:components] << component
|
|
115
125
|
end
|
|
116
126
|
|
|
127
|
+
def select_cycle_breaker(component, graph)
|
|
128
|
+
component.min_by { |node| [-(graph[node] & component).size, node.to_s] }
|
|
129
|
+
end
|
|
130
|
+
|
|
117
131
|
def collect_references(node, references, filter)
|
|
118
132
|
return unless node.is_a?(Hash)
|
|
119
133
|
|
|
@@ -7,10 +7,13 @@ module Apiwork
|
|
|
7
7
|
output :string
|
|
8
8
|
file_extension '.ts'
|
|
9
9
|
|
|
10
|
+
option :builders, default: false, type: :boolean
|
|
10
11
|
option :version, default: '5', enum: %w[4 5], type: :string
|
|
11
12
|
|
|
12
13
|
def generate
|
|
13
|
-
TypeScriptMapper.map(self, surface)
|
|
14
|
+
output = TypeScriptMapper.map(self, surface)
|
|
15
|
+
output += "\n\n#{BuilderMapper.map(self, surface)}" if options[:builders]
|
|
16
|
+
output
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
private
|
|
@@ -30,7 +30,7 @@ module Apiwork
|
|
|
30
30
|
ts_type = map_field(param)
|
|
31
31
|
optional_marker = param.optional? ? '?' : ''
|
|
32
32
|
|
|
33
|
-
prop_jsdoc = jsdoc(description: param.description, example: param.example)
|
|
33
|
+
prop_jsdoc = jsdoc(description: param.description, example: param.concrete? ? param.example : nil)
|
|
34
34
|
if prop_jsdoc
|
|
35
35
|
indented_jsdoc = prop_jsdoc.lines.map { |line| " #{line.chomp}" }.join("\n")
|
|
36
36
|
"#{indented_jsdoc}\n #{key}#{optional_marker}: #{ts_type};"
|
|
@@ -165,6 +165,8 @@ module Apiwork
|
|
|
165
165
|
map_object_type(param)
|
|
166
166
|
elsif param.array?
|
|
167
167
|
map_array_type(param)
|
|
168
|
+
elsif param.record?
|
|
169
|
+
map_record_type(param)
|
|
168
170
|
elsif param.union?
|
|
169
171
|
map_union_type(param)
|
|
170
172
|
elsif param.literal?
|
|
@@ -207,8 +209,29 @@ module Apiwork
|
|
|
207
209
|
end
|
|
208
210
|
end
|
|
209
211
|
|
|
212
|
+
def map_record_type(param)
|
|
213
|
+
value_type = param.of ? map_param(param.of) : 'unknown'
|
|
214
|
+
"Record<string, #{value_type}>"
|
|
215
|
+
end
|
|
216
|
+
|
|
210
217
|
def map_union_type(param)
|
|
211
|
-
param.variants.map
|
|
218
|
+
variant_types = param.variants.map do |variant|
|
|
219
|
+
if param.discriminator && variant.tag && variant.object?
|
|
220
|
+
discriminator_prop = "#{@export.transform_key(param.discriminator)}: '#{variant.tag}'"
|
|
221
|
+
properties = variant.shape.sort_by { |name, _| name.to_s }.map do |name, field|
|
|
222
|
+
"#{@export.transform_key(name)}: #{map_field(field)}"
|
|
223
|
+
end
|
|
224
|
+
all_properties = [discriminator_prop, *properties].join('; ')
|
|
225
|
+
"{ #{all_properties} }"
|
|
226
|
+
elsif param.discriminator && variant.tag
|
|
227
|
+
base_type = map_param(variant)
|
|
228
|
+
"{ #{@export.transform_key(param.discriminator)}: '#{variant.tag}' } & #{base_type}"
|
|
229
|
+
else
|
|
230
|
+
map_param(variant)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
variant_types.sort.join(' | ')
|
|
212
235
|
end
|
|
213
236
|
|
|
214
237
|
def map_literal_type(param)
|
data/lib/apiwork/export/zod.rb
CHANGED
|
@@ -7,6 +7,7 @@ module Apiwork
|
|
|
7
7
|
output :string
|
|
8
8
|
file_extension '.ts'
|
|
9
9
|
|
|
10
|
+
option :builders, default: false, type: :boolean
|
|
10
11
|
option :version, default: '4', enum: %w[4], type: :string
|
|
11
12
|
|
|
12
13
|
def generate
|
|
@@ -26,6 +27,14 @@ module Apiwork
|
|
|
26
27
|
parts << ''
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
if options[:builders]
|
|
31
|
+
builder_output = BuilderMapper.map(self, surface)
|
|
32
|
+
if builder_output.present?
|
|
33
|
+
parts << builder_output
|
|
34
|
+
parts << ''
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
29
38
|
parts.join("\n")
|
|
30
39
|
end
|
|
31
40
|
|
|
@@ -200,6 +200,8 @@ module Apiwork
|
|
|
200
200
|
map_object_type(param)
|
|
201
201
|
elsif param.array?
|
|
202
202
|
map_array_type(param)
|
|
203
|
+
elsif param.record?
|
|
204
|
+
map_record_type(param)
|
|
203
205
|
elsif param.union?
|
|
204
206
|
map_union_type(param)
|
|
205
207
|
elsif param.literal?
|
|
@@ -248,6 +250,11 @@ module Apiwork
|
|
|
248
250
|
base
|
|
249
251
|
end
|
|
250
252
|
|
|
253
|
+
def map_record_type(param)
|
|
254
|
+
value_schema = param.of ? map_param(param.of) : 'z.unknown()'
|
|
255
|
+
"z.record(z.string(), #{value_schema})"
|
|
256
|
+
end
|
|
257
|
+
|
|
251
258
|
def map_union_type(param)
|
|
252
259
|
if param.discriminator
|
|
253
260
|
map_discriminated_union(param)
|
|
@@ -260,7 +267,21 @@ module Apiwork
|
|
|
260
267
|
def map_discriminated_union(param)
|
|
261
268
|
discriminator_field = @export.transform_key(param.discriminator)
|
|
262
269
|
|
|
263
|
-
variant_schemas = param.variants.map
|
|
270
|
+
variant_schemas = param.variants.map do |variant|
|
|
271
|
+
if variant.tag && variant.object?
|
|
272
|
+
discriminator_prop = "#{discriminator_field}: z.literal('#{variant.tag}')"
|
|
273
|
+
properties = variant.shape.sort_by { |name, _| name.to_s }.map do |name, field|
|
|
274
|
+
"#{@export.transform_key(name)}: #{map_field(field)}"
|
|
275
|
+
end
|
|
276
|
+
all_properties = [discriminator_prop, *properties].join(', ')
|
|
277
|
+
"z.object({ #{all_properties} })"
|
|
278
|
+
elsif variant.tag
|
|
279
|
+
base_schema = map_param(variant)
|
|
280
|
+
"#{base_schema}.extend({ #{discriminator_field}: z.literal('#{variant.tag}') })"
|
|
281
|
+
else
|
|
282
|
+
map_param(variant)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
264
285
|
|
|
265
286
|
"z.discriminatedUnion('#{discriminator_field}', [#{variant_schemas.join(', ')}])"
|
|
266
287
|
end
|
|
@@ -33,6 +33,14 @@ module Apiwork
|
|
|
33
33
|
@dump[:base_path]
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
# @api public
|
|
37
|
+
# The fingerprint for this API.
|
|
38
|
+
#
|
|
39
|
+
# @return [String]
|
|
40
|
+
def fingerprint
|
|
41
|
+
@dump[:fingerprint]
|
|
42
|
+
end
|
|
43
|
+
|
|
36
44
|
# @api public
|
|
37
45
|
# The info for this API.
|
|
38
46
|
#
|
|
@@ -65,6 +73,14 @@ module Apiwork
|
|
|
65
73
|
@enums ||= @dump[:enums].transform_values { |dump| Enum.new(dump) }
|
|
66
74
|
end
|
|
67
75
|
|
|
76
|
+
# @api public
|
|
77
|
+
# The supported locales for this API.
|
|
78
|
+
#
|
|
79
|
+
# @return [Array<Symbol>]
|
|
80
|
+
def locales
|
|
81
|
+
@dump[:locales]
|
|
82
|
+
end
|
|
83
|
+
|
|
68
84
|
# @api public
|
|
69
85
|
# The error codes for this API.
|
|
70
86
|
#
|
|
@@ -80,6 +96,8 @@ module Apiwork
|
|
|
80
96
|
def to_h
|
|
81
97
|
{
|
|
82
98
|
base_path:,
|
|
99
|
+
fingerprint:,
|
|
100
|
+
locales:,
|
|
83
101
|
enums: enums.transform_values(&:to_h),
|
|
84
102
|
error_codes: error_codes.transform_values(&:to_h),
|
|
85
103
|
info: info&.to_h,
|
|
@@ -52,7 +52,7 @@ module Apiwork
|
|
|
52
52
|
|
|
53
53
|
def build_response(response)
|
|
54
54
|
return { body: {}, description: i18n_lookup(:response, :description), no_content: false } unless response
|
|
55
|
-
return { body:
|
|
55
|
+
return { body: nil, description: response.description || i18n_lookup(:response, :description), no_content: true } if response.no_content?
|
|
56
56
|
|
|
57
57
|
description = response.description || i18n_lookup(:response, :description)
|
|
58
58
|
body_shape = response.body
|
|
@@ -18,7 +18,9 @@ module Apiwork
|
|
|
18
18
|
base_path: @api_class.transform_path(@api_class.base_path),
|
|
19
19
|
enums: type_dump_hash[:enums],
|
|
20
20
|
error_codes: build_error_codes(collect_all_error_code_keys(resources)),
|
|
21
|
+
fingerprint: @api_class.fingerprint,
|
|
21
22
|
info: build_info,
|
|
23
|
+
locales: @api_class.locales,
|
|
22
24
|
types: type_dump_hash[:types],
|
|
23
25
|
}
|
|
24
26
|
end
|
|
@@ -162,15 +162,28 @@ module Apiwork
|
|
|
162
162
|
|
|
163
163
|
result = {
|
|
164
164
|
reference:,
|
|
165
|
+
as: nil,
|
|
166
|
+
default: nil,
|
|
167
|
+
deprecated: false,
|
|
168
|
+
description: nil,
|
|
169
|
+
discriminator: nil,
|
|
165
170
|
enum: element.enum,
|
|
171
|
+
example: nil,
|
|
166
172
|
format: element.format,
|
|
167
173
|
max: element.max,
|
|
168
174
|
min: element.min,
|
|
175
|
+
nullable: false,
|
|
176
|
+
of: nil,
|
|
177
|
+
optional: false,
|
|
178
|
+
partial: false,
|
|
169
179
|
shape: resolved_shape,
|
|
180
|
+
tag: nil,
|
|
170
181
|
type: reference ? :reference : type_value,
|
|
182
|
+
value: nil,
|
|
183
|
+
variants: [],
|
|
171
184
|
}
|
|
172
185
|
|
|
173
|
-
result[:of] = build_of_from_element(element.inner) if element.type
|
|
186
|
+
result[:of] = build_of_from_element(element.inner) if [:array, :record].include?(element.type) && element.inner
|
|
174
187
|
|
|
175
188
|
result
|
|
176
189
|
end
|
|
@@ -294,19 +307,39 @@ module Apiwork
|
|
|
294
307
|
of = options[:of]
|
|
295
308
|
return nil unless of
|
|
296
309
|
|
|
310
|
+
union = of.type == :union
|
|
311
|
+
union_shape = union && of.shape.is_a?(Apiwork::API::Union) ? of.shape : nil
|
|
312
|
+
|
|
297
313
|
result = {
|
|
314
|
+
as: nil,
|
|
315
|
+
default: nil,
|
|
316
|
+
deprecated: false,
|
|
317
|
+
description: nil,
|
|
318
|
+
discriminator: union ? of.discriminator : nil,
|
|
298
319
|
enum: of.enum,
|
|
320
|
+
example: nil,
|
|
299
321
|
format: of.format,
|
|
300
322
|
max: of.max,
|
|
301
323
|
min: of.min,
|
|
324
|
+
nullable: false,
|
|
325
|
+
of: nil,
|
|
326
|
+
optional: false,
|
|
327
|
+
partial: false,
|
|
302
328
|
reference: nil,
|
|
303
|
-
shape:
|
|
329
|
+
shape: union ? {} : build_of_shape(of),
|
|
330
|
+
tag: nil,
|
|
304
331
|
type: of.type,
|
|
332
|
+
value: nil,
|
|
333
|
+
variants: union_shape ? union_shape.variants.map { |variant| build_api_variant(variant) } : [],
|
|
305
334
|
}
|
|
306
335
|
result[:of] = build_api_of({ of: of.inner }) if of.type == :array && of.inner
|
|
307
336
|
result
|
|
308
337
|
end
|
|
309
338
|
|
|
339
|
+
def build_of_shape(of)
|
|
340
|
+
of.shape ? build_nested_shape(of.shape) : {}
|
|
341
|
+
end
|
|
342
|
+
|
|
310
343
|
def build_api_variant(variant)
|
|
311
344
|
{
|
|
312
345
|
as: nil,
|
|
@@ -320,7 +353,7 @@ module Apiwork
|
|
|
320
353
|
max: nil,
|
|
321
354
|
min: nil,
|
|
322
355
|
nullable: false,
|
|
323
|
-
of:
|
|
356
|
+
of: build_api_of(variant),
|
|
324
357
|
optional: false,
|
|
325
358
|
partial: variant[:partial] == true,
|
|
326
359
|
reference: nil,
|
|
@@ -332,23 +365,6 @@ module Apiwork
|
|
|
332
365
|
}
|
|
333
366
|
end
|
|
334
367
|
|
|
335
|
-
def build_api_variant_of(variant)
|
|
336
|
-
of = variant[:of]
|
|
337
|
-
return nil unless of
|
|
338
|
-
|
|
339
|
-
result = {
|
|
340
|
-
enum: of.enum,
|
|
341
|
-
format: of.format,
|
|
342
|
-
max: of.max,
|
|
343
|
-
min: of.min,
|
|
344
|
-
reference: nil,
|
|
345
|
-
shape: of.shape ? build_nested_shape(of.shape) : {},
|
|
346
|
-
type: of.type,
|
|
347
|
-
}
|
|
348
|
-
result[:of] = build_api_variant_of({ of: of.inner }) if of.type == :array && of.inner
|
|
349
|
-
result
|
|
350
|
-
end
|
|
351
|
-
|
|
352
368
|
def build_shape(options)
|
|
353
369
|
dumped = options[:shape] ? build_nested_shape(options[:shape]) : nil
|
|
354
370
|
|
|
@@ -4,11 +4,12 @@ module Apiwork
|
|
|
4
4
|
module Introspection
|
|
5
5
|
module Dump
|
|
6
6
|
class Resource
|
|
7
|
-
def initialize(resource, api_class, parent_identifiers: [], parent_param: nil, parent_singular: false)
|
|
7
|
+
def initialize(resource, api_class, parent_identifiers: [], parent_param: nil, parent_path: nil, parent_singular: false)
|
|
8
8
|
@resource = resource
|
|
9
9
|
@api_class = api_class
|
|
10
10
|
@parent_identifiers = parent_identifiers
|
|
11
11
|
@parent_param = parent_param
|
|
12
|
+
@parent_path = parent_path
|
|
12
13
|
@parent_singular = parent_singular
|
|
13
14
|
end
|
|
14
15
|
|
|
@@ -57,10 +58,11 @@ module Apiwork
|
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def build_resource_path(formatted_segment)
|
|
60
|
-
return formatted_segment if @
|
|
61
|
-
return formatted_segment if @parent_singular
|
|
61
|
+
return formatted_segment if @parent_path.nil?
|
|
62
|
+
return "#{@parent_path}/#{formatted_segment}" if @parent_singular
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
param = @parent_param || "#{@parent_identifiers.last.singularize}_id"
|
|
65
|
+
"#{@parent_path}/:#{param}/#{formatted_segment}"
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
def build_nested_resources(resource_path)
|
|
@@ -70,6 +72,7 @@ module Apiwork
|
|
|
70
72
|
|
|
71
73
|
nested_options = {
|
|
72
74
|
parent_identifiers: child_parent_identifiers,
|
|
75
|
+
parent_path: resource_path,
|
|
73
76
|
parent_singular: @resource.singular,
|
|
74
77
|
}
|
|
75
78
|
nested_options[:parent_param] = @resource.param&.to_s || "#{@resource.name.to_s.singularize}_id" unless @resource.singular
|
|
@@ -4,6 +4,11 @@ module Apiwork
|
|
|
4
4
|
module Introspection
|
|
5
5
|
module Dump
|
|
6
6
|
class Type
|
|
7
|
+
PRIMITIVE_TYPES = %i[
|
|
8
|
+
array binary boolean date datetime decimal enum float integer json
|
|
9
|
+
literal number object record string text time union unknown uuid
|
|
10
|
+
].to_set.freeze
|
|
11
|
+
|
|
7
12
|
def initialize(api_class)
|
|
8
13
|
@api_class = api_class
|
|
9
14
|
end
|
|
@@ -99,7 +104,11 @@ module Apiwork
|
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
def build_param(name, options, scope)
|
|
102
|
-
reference =
|
|
107
|
+
reference = if options[:custom_type]
|
|
108
|
+
resolve_type_reference(options[:custom_type], scope)
|
|
109
|
+
elsif options[:type] && !PRIMITIVE_TYPES.include?(options[:type])
|
|
110
|
+
resolve_type_reference(options[:type], scope)
|
|
111
|
+
end
|
|
103
112
|
|
|
104
113
|
{
|
|
105
114
|
reference:,
|
|
@@ -142,7 +151,7 @@ module Apiwork
|
|
|
142
151
|
max: nil,
|
|
143
152
|
min: nil,
|
|
144
153
|
nullable: false,
|
|
145
|
-
of:
|
|
154
|
+
of: resolve_of(variant, scope),
|
|
146
155
|
optional: false,
|
|
147
156
|
partial: variant[:partial] == true,
|
|
148
157
|
shape: build_nested_shape(variant[:shape]),
|
|
@@ -201,23 +210,41 @@ module Apiwork
|
|
|
201
210
|
of = options[:of]
|
|
202
211
|
return nil unless of
|
|
203
212
|
|
|
213
|
+
union = of.type == :union
|
|
214
|
+
union_shape = union && of.shape.is_a?(Apiwork::API::Union) ? of.shape : nil
|
|
204
215
|
type_value = of.type
|
|
205
216
|
scoped_name = resolve_scoped_type_name(type_value, scope)
|
|
206
|
-
resolved_shape = of.shape ? build_nested_shape(of.shape) : {}
|
|
207
217
|
|
|
208
218
|
result = {
|
|
219
|
+
as: nil,
|
|
220
|
+
default: nil,
|
|
221
|
+
deprecated: false,
|
|
222
|
+
description: nil,
|
|
223
|
+
discriminator: union ? of.discriminator : nil,
|
|
209
224
|
enum: of.enum,
|
|
225
|
+
example: nil,
|
|
210
226
|
format: of.format,
|
|
211
227
|
max: of.max,
|
|
212
228
|
min: of.min,
|
|
229
|
+
nullable: false,
|
|
230
|
+
of: nil,
|
|
231
|
+
optional: false,
|
|
232
|
+
partial: false,
|
|
213
233
|
reference: scoped_name,
|
|
214
|
-
shape:
|
|
234
|
+
shape: union ? {} : resolve_of_shape(of),
|
|
235
|
+
tag: nil,
|
|
215
236
|
type: scoped_name ? :reference : type_value,
|
|
237
|
+
value: nil,
|
|
238
|
+
variants: union_shape ? union_shape.variants.map { |variant| build_variant(variant, scope) } : [],
|
|
216
239
|
}
|
|
217
240
|
result[:of] = resolve_of({ of: of.inner }, scope) if of.type == :array && of.inner
|
|
218
241
|
result
|
|
219
242
|
end
|
|
220
243
|
|
|
244
|
+
def resolve_of_shape(of)
|
|
245
|
+
of.shape ? build_nested_shape(of.shape) : {}
|
|
246
|
+
end
|
|
247
|
+
|
|
221
248
|
def resolve_variant_enum(variant, scope)
|
|
222
249
|
return nil unless variant[:enum]
|
|
223
250
|
|
|
@@ -228,27 +255,6 @@ module Apiwork
|
|
|
228
255
|
end
|
|
229
256
|
end
|
|
230
257
|
|
|
231
|
-
def resolve_variant_of(variant, scope)
|
|
232
|
-
of = variant[:of]
|
|
233
|
-
return nil unless of
|
|
234
|
-
|
|
235
|
-
type_value = of.type
|
|
236
|
-
scoped_name = resolve_scoped_type_name(type_value, scope)
|
|
237
|
-
resolved_shape = of.shape ? build_nested_shape(of.shape) : {}
|
|
238
|
-
|
|
239
|
-
result = {
|
|
240
|
-
enum: of.enum,
|
|
241
|
-
format: of.format,
|
|
242
|
-
max: of.max,
|
|
243
|
-
min: of.min,
|
|
244
|
-
reference: scoped_name,
|
|
245
|
-
shape: resolved_shape,
|
|
246
|
-
type: scoped_name ? :reference : type_value,
|
|
247
|
-
}
|
|
248
|
-
result[:of] = resolve_variant_of({ of: of.inner }, scope) if of.type == :array && of.inner
|
|
249
|
-
result
|
|
250
|
-
end
|
|
251
|
-
|
|
252
258
|
def build_enum(qualified_name, enum_definition)
|
|
253
259
|
{
|
|
254
260
|
deprecated: enum_definition.deprecated?,
|
|
@@ -20,6 +20,22 @@ module Apiwork
|
|
|
20
20
|
# param.max # => 10 or nil
|
|
21
21
|
# param.boundable? # => true
|
|
22
22
|
class Array < Base
|
|
23
|
+
# @api public
|
|
24
|
+
# The default for this param.
|
|
25
|
+
#
|
|
26
|
+
# @return [Object, nil]
|
|
27
|
+
def default
|
|
28
|
+
@dump[:default]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @api public
|
|
32
|
+
# The example for this param.
|
|
33
|
+
#
|
|
34
|
+
# @return [Object, nil]
|
|
35
|
+
def example
|
|
36
|
+
@dump[:example]
|
|
37
|
+
end
|
|
38
|
+
|
|
23
39
|
# @api public
|
|
24
40
|
# The of for this param.
|
|
25
41
|
#
|
|
@@ -62,6 +78,14 @@ module Apiwork
|
|
|
62
78
|
true
|
|
63
79
|
end
|
|
64
80
|
|
|
81
|
+
# @api public
|
|
82
|
+
# Whether this param is concrete.
|
|
83
|
+
#
|
|
84
|
+
# @return [Boolean]
|
|
85
|
+
def concrete?
|
|
86
|
+
true
|
|
87
|
+
end
|
|
88
|
+
|
|
65
89
|
# @api public
|
|
66
90
|
# Whether this param is boundable.
|
|
67
91
|
#
|
|
@@ -76,6 +100,8 @@ module Apiwork
|
|
|
76
100
|
# @return [Hash]
|
|
77
101
|
def to_h
|
|
78
102
|
result = super
|
|
103
|
+
result[:default] = default
|
|
104
|
+
result[:example] = example
|
|
79
105
|
result[:max] = max
|
|
80
106
|
result[:min] = min
|
|
81
107
|
result[:of] = of&.to_h
|
|
@@ -49,35 +49,19 @@ module Apiwork
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
# @api public
|
|
52
|
-
# The
|
|
53
|
-
#
|
|
54
|
-
# @return [Object, nil]
|
|
55
|
-
def example
|
|
56
|
-
@dump[:example]
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# @api public
|
|
60
|
-
# The default for this param.
|
|
52
|
+
# The tag for this param.
|
|
61
53
|
#
|
|
62
|
-
# @return [
|
|
63
|
-
def
|
|
64
|
-
@dump[:
|
|
54
|
+
# @return [String, nil]
|
|
55
|
+
def tag
|
|
56
|
+
@dump[:tag]
|
|
65
57
|
end
|
|
66
58
|
|
|
67
59
|
# @api public
|
|
68
|
-
# Whether this param
|
|
60
|
+
# Whether this param is concrete.
|
|
69
61
|
#
|
|
70
62
|
# @return [Boolean]
|
|
71
|
-
def
|
|
72
|
-
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# @api public
|
|
76
|
-
# The tag for this param.
|
|
77
|
-
#
|
|
78
|
-
# @return [String, nil]
|
|
79
|
-
def tag
|
|
80
|
-
@dump[:tag]
|
|
63
|
+
def concrete?
|
|
64
|
+
false
|
|
81
65
|
end
|
|
82
66
|
|
|
83
67
|
# @api public
|
|
@@ -104,6 +88,14 @@ module Apiwork
|
|
|
104
88
|
false
|
|
105
89
|
end
|
|
106
90
|
|
|
91
|
+
# @api public
|
|
92
|
+
# Whether this param is a record.
|
|
93
|
+
#
|
|
94
|
+
# @return [Boolean]
|
|
95
|
+
def record?
|
|
96
|
+
false
|
|
97
|
+
end
|
|
98
|
+
|
|
107
99
|
# @api public
|
|
108
100
|
# Whether this param is a union.
|
|
109
101
|
#
|
|
@@ -270,10 +262,8 @@ module Apiwork
|
|
|
270
262
|
# @return [Hash]
|
|
271
263
|
def to_h
|
|
272
264
|
{
|
|
273
|
-
default: default,
|
|
274
265
|
deprecated: deprecated?,
|
|
275
266
|
description: description,
|
|
276
|
-
example: example,
|
|
277
267
|
nullable: nullable?,
|
|
278
268
|
optional: optional?,
|
|
279
269
|
type: type,
|
|
@@ -20,6 +20,30 @@ module Apiwork
|
|
|
20
20
|
# param.enum_reference? # => false
|
|
21
21
|
# end
|
|
22
22
|
class Binary < Base
|
|
23
|
+
# @api public
|
|
24
|
+
# The default for this param.
|
|
25
|
+
#
|
|
26
|
+
# @return [Object, nil]
|
|
27
|
+
def default
|
|
28
|
+
@dump[:default]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @api public
|
|
32
|
+
# The example for this param.
|
|
33
|
+
#
|
|
34
|
+
# @return [Object, nil]
|
|
35
|
+
def example
|
|
36
|
+
@dump[:example]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @api public
|
|
40
|
+
# Whether this param is concrete.
|
|
41
|
+
#
|
|
42
|
+
# @return [Boolean]
|
|
43
|
+
def concrete?
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
|
|
23
47
|
# @api public
|
|
24
48
|
# Whether this param is scalar.
|
|
25
49
|
#
|
|
@@ -67,6 +91,18 @@ module Apiwork
|
|
|
67
91
|
def formattable?
|
|
68
92
|
false
|
|
69
93
|
end
|
|
94
|
+
|
|
95
|
+
# @api public
|
|
96
|
+
# Converts this param to a hash.
|
|
97
|
+
#
|
|
98
|
+
# @return [Hash]
|
|
99
|
+
def to_h
|
|
100
|
+
result = super
|
|
101
|
+
result[:default] = default
|
|
102
|
+
result[:enum] = enum if enum?
|
|
103
|
+
result[:example] = example
|
|
104
|
+
result
|
|
105
|
+
end
|
|
70
106
|
end
|
|
71
107
|
end
|
|
72
108
|
end
|