apiwork 0.4.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/lib/apiwork/adapter/serializer/resource/base.rb +15 -0
  3. data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +3 -2
  4. data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +2 -2
  5. data/lib/apiwork/api/base.rb +67 -17
  6. data/lib/apiwork/api/element.rb +33 -2
  7. data/lib/apiwork/api/object.rb +70 -5
  8. data/lib/apiwork/api/router.rb +16 -0
  9. data/lib/apiwork/configuration/validatable.rb +1 -0
  10. data/lib/apiwork/configuration.rb +2 -0
  11. data/lib/apiwork/contract/element.rb +17 -2
  12. data/lib/apiwork/contract/object/coercer.rb +24 -2
  13. data/lib/apiwork/contract/object/deserializer.rb +5 -1
  14. data/lib/apiwork/contract/object/transformer.rb +15 -2
  15. data/lib/apiwork/contract/object/validator.rb +45 -2
  16. data/lib/apiwork/contract/object.rb +77 -7
  17. data/lib/apiwork/element.rb +33 -0
  18. data/lib/apiwork/export/base.rb +1 -4
  19. data/lib/apiwork/export/builder_mapper.rb +184 -0
  20. data/lib/apiwork/export/open_api.rb +9 -2
  21. data/lib/apiwork/export/sorbus.rb +5 -1
  22. data/lib/apiwork/export/sorbus_mapper.rb +3 -7
  23. data/lib/apiwork/export/type_analysis.rb +20 -6
  24. data/lib/apiwork/export/type_script.rb +4 -1
  25. data/lib/apiwork/export/type_script_mapper.rb +25 -2
  26. data/lib/apiwork/export/zod.rb +9 -0
  27. data/lib/apiwork/export/zod_mapper.rb +22 -1
  28. data/lib/apiwork/introspection/dump/action.rb +1 -1
  29. data/lib/apiwork/introspection/dump/param.rb +36 -20
  30. data/lib/apiwork/introspection/dump/type.rb +31 -25
  31. data/lib/apiwork/introspection/param/array.rb +26 -0
  32. data/lib/apiwork/introspection/param/base.rb +16 -18
  33. data/lib/apiwork/introspection/param/binary.rb +36 -0
  34. data/lib/apiwork/introspection/param/boolean.rb +36 -0
  35. data/lib/apiwork/introspection/param/date.rb +36 -0
  36. data/lib/apiwork/introspection/param/date_time.rb +36 -0
  37. data/lib/apiwork/introspection/param/decimal.rb +26 -0
  38. data/lib/apiwork/introspection/param/integer.rb +26 -0
  39. data/lib/apiwork/introspection/param/number.rb +26 -0
  40. data/lib/apiwork/introspection/param/record.rb +71 -0
  41. data/lib/apiwork/introspection/param/string.rb +26 -0
  42. data/lib/apiwork/introspection/param/time.rb +36 -0
  43. data/lib/apiwork/introspection/param/uuid.rb +36 -0
  44. data/lib/apiwork/introspection/param.rb +1 -0
  45. data/lib/apiwork/object.rb +244 -2
  46. data/lib/apiwork/representation/attribute.rb +1 -1
  47. data/lib/apiwork/representation/base.rb +105 -0
  48. data/lib/apiwork/representation/element.rb +15 -5
  49. data/lib/apiwork/version.rb +1 -1
  50. metadata +4 -2
@@ -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 == :array && element.inner
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: of.shape ? build_nested_shape(of.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: build_api_variant_of(variant),
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,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 = resolve_type_reference(options[:type], scope)
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: resolve_variant_of(variant, scope),
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: resolved_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
@@ -48,22 +48,6 @@ module Apiwork
48
48
  @dump[:description]
49
49
  end
50
50
 
51
- # @api public
52
- # The example for this param.
53
- #
54
- # @return [Object, nil]
55
- def example
56
- @dump[:example]
57
- end
58
-
59
- # @api public
60
- # The default for this param.
61
- #
62
- # @return [Object, nil]
63
- def default
64
- @dump[:default]
65
- end
66
-
67
51
  # @api public
68
52
  # The tag for this param.
69
53
  #
@@ -72,6 +56,14 @@ module Apiwork
72
56
  @dump[:tag]
73
57
  end
74
58
 
59
+ # @api public
60
+ # Whether this param is concrete.
61
+ #
62
+ # @return [Boolean]
63
+ def concrete?
64
+ false
65
+ end
66
+
75
67
  # @api public
76
68
  # Whether this param is scalar.
77
69
  #
@@ -96,6 +88,14 @@ module Apiwork
96
88
  false
97
89
  end
98
90
 
91
+ # @api public
92
+ # Whether this param is a record.
93
+ #
94
+ # @return [Boolean]
95
+ def record?
96
+ false
97
+ end
98
+
99
99
  # @api public
100
100
  # Whether this param is a union.
101
101
  #
@@ -262,10 +262,8 @@ module Apiwork
262
262
  # @return [Hash]
263
263
  def to_h
264
264
  {
265
- default: default,
266
265
  deprecated: deprecated?,
267
266
  description: description,
268
- example: example,
269
267
  nullable: nullable?,
270
268
  optional: optional?,
271
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
@@ -20,6 +20,30 @@ module Apiwork
20
20
  # param.enum_reference? # => false
21
21
  # end
22
22
  class Boolean < 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
@@ -20,6 +20,30 @@ module Apiwork
20
20
  # param.enum_reference? # => false
21
21
  # end
22
22
  class Date < 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
@@ -20,6 +20,30 @@ module Apiwork
20
20
  # param.enum_reference? # => false
21
21
  # end
22
22
  class DateTime < 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
@@ -24,6 +24,22 @@ module Apiwork
24
24
  # param.enum_reference? # => false
25
25
  # end
26
26
  class Decimal < Base
27
+ # @api public
28
+ # The default for this param.
29
+ #
30
+ # @return [Object, nil]
31
+ def default
32
+ @dump[:default]
33
+ end
34
+
35
+ # @api public
36
+ # The example for this param.
37
+ #
38
+ # @return [Object, nil]
39
+ def example
40
+ @dump[:example]
41
+ end
42
+
27
43
  # @api public
28
44
  # The minimum for this param.
29
45
  #
@@ -40,6 +56,14 @@ module Apiwork
40
56
  @dump[:max]
41
57
  end
42
58
 
59
+ # @api public
60
+ # Whether this param is concrete.
61
+ #
62
+ # @return [Boolean]
63
+ def concrete?
64
+ true
65
+ end
66
+
43
67
  # @api public
44
68
  # Whether this param is scalar.
45
69
  #
@@ -110,7 +134,9 @@ module Apiwork
110
134
  # @return [Hash]
111
135
  def to_h
112
136
  result = super
137
+ result[:default] = default
113
138
  result[:enum] = enum if enum?
139
+ result[:example] = example
114
140
  result[:max] = max
115
141
  result[:min] = min
116
142
  result
@@ -25,6 +25,22 @@ module Apiwork
25
25
  # param.enum_reference? # => false
26
26
  # end
27
27
  class Integer < Base
28
+ # @api public
29
+ # The default for this param.
30
+ #
31
+ # @return [Object, nil]
32
+ def default
33
+ @dump[:default]
34
+ end
35
+
36
+ # @api public
37
+ # The example for this param.
38
+ #
39
+ # @return [Object, nil]
40
+ def example
41
+ @dump[:example]
42
+ end
43
+
28
44
  # @api public
29
45
  # The minimum for this param.
30
46
  #
@@ -49,6 +65,14 @@ module Apiwork
49
65
  @dump[:format]
50
66
  end
51
67
 
68
+ # @api public
69
+ # Whether this param is concrete.
70
+ #
71
+ # @return [Boolean]
72
+ def concrete?
73
+ true
74
+ end
75
+
52
76
  # @api public
53
77
  # Whether this param is scalar.
54
78
  #
@@ -119,7 +143,9 @@ module Apiwork
119
143
  # @return [Hash]
120
144
  def to_h
121
145
  result = super
146
+ result[:default] = default
122
147
  result[:enum] = enum if enum?
148
+ result[:example] = example
123
149
  result[:format] = format
124
150
  result[:max] = max
125
151
  result[:min] = min
@@ -24,6 +24,22 @@ module Apiwork
24
24
  # param.enum_reference? # => false
25
25
  # end
26
26
  class Number < Base
27
+ # @api public
28
+ # The default for this param.
29
+ #
30
+ # @return [Object, nil]
31
+ def default
32
+ @dump[:default]
33
+ end
34
+
35
+ # @api public
36
+ # The example for this param.
37
+ #
38
+ # @return [Object, nil]
39
+ def example
40
+ @dump[:example]
41
+ end
42
+
27
43
  # @api public
28
44
  # The minimum for this param.
29
45
  #
@@ -40,6 +56,14 @@ module Apiwork
40
56
  @dump[:max]
41
57
  end
42
58
 
59
+ # @api public
60
+ # Whether this param is concrete.
61
+ #
62
+ # @return [Boolean]
63
+ def concrete?
64
+ true
65
+ end
66
+
43
67
  # @api public
44
68
  # Whether this param is scalar.
45
69
  #
@@ -110,7 +134,9 @@ module Apiwork
110
134
  # @return [Hash]
111
135
  def to_h
112
136
  result = super
137
+ result[:default] = default
113
138
  result[:enum] = enum if enum?
139
+ result[:example] = example
114
140
  result[:max] = max
115
141
  result[:min] = min
116
142
  result