smithy 2.0.0.pre0 → 2.0.0.pre1

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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/smithy-ruby +1 -4
  4. data/lib/smithy/command.rb +68 -0
  5. data/lib/smithy/generators/base.rb +19 -0
  6. data/lib/smithy/generators/client.rb +106 -0
  7. data/lib/smithy/generators/schema.rb +61 -0
  8. data/lib/smithy/generators.rb +29 -0
  9. data/lib/smithy/model/flattener.rb +114 -0
  10. data/lib/smithy/model/operation_parser.rb +42 -0
  11. data/lib/smithy/model/rbs.rb +57 -0
  12. data/lib/smithy/model/service_index.rb +51 -0
  13. data/lib/smithy/model/service_parser.rb +74 -0
  14. data/lib/smithy/model/shape.rb +49 -0
  15. data/lib/smithy/model/structure_parser.rb +43 -0
  16. data/lib/smithy/model/yard.rb +100 -0
  17. data/lib/smithy/model.rb +54 -0
  18. data/lib/smithy/plan.rb +79 -3
  19. data/lib/smithy/templates/client/auth_parameters.erb +29 -0
  20. data/lib/smithy/templates/client/auth_parameters_rbs.erb +14 -0
  21. data/lib/smithy/templates/client/auth_plugin.erb +115 -0
  22. data/lib/smithy/templates/client/auth_resolver.erb +16 -0
  23. data/lib/smithy/templates/client/auth_resolver_rbs.erb +5 -0
  24. data/lib/smithy/templates/client/client.erb +142 -0
  25. data/lib/smithy/templates/client/client_rbs.erb +29 -0
  26. data/lib/smithy/templates/client/customizations.erb +3 -0
  27. data/lib/smithy/templates/client/endpoint_parameters.erb +65 -0
  28. data/lib/smithy/templates/client/endpoint_parameters_rbs.erb +13 -0
  29. data/lib/smithy/templates/client/endpoint_plugin.erb +58 -0
  30. data/lib/smithy/templates/client/endpoint_provider.erb +15 -0
  31. data/lib/smithy/templates/client/endpoint_provider_rbs.erb +5 -0
  32. data/lib/smithy/templates/client/endpoint_provider_spec.erb +70 -0
  33. data/lib/smithy/templates/client/errors.erb +69 -0
  34. data/lib/smithy/templates/client/errors_rbs.erb +17 -0
  35. data/lib/smithy/templates/client/gemspec.erb +17 -0
  36. data/lib/smithy/templates/client/module.erb +22 -0
  37. data/lib/smithy/templates/client/module_rbs.erb +7 -0
  38. data/lib/smithy/templates/client/paginators.erb +33 -0
  39. data/lib/smithy/templates/client/protocol_spec.erb +144 -0
  40. data/lib/smithy/templates/client/rubocop_yml.erb +33 -0
  41. data/lib/smithy/templates/client/schema.erb +76 -0
  42. data/lib/smithy/templates/client/schema_rbs.erb +13 -0
  43. data/lib/smithy/templates/client/spec_helper.erb +10 -0
  44. data/lib/smithy/templates/client/types.erb +64 -0
  45. data/lib/smithy/templates/client/types_rbs.erb +47 -0
  46. data/lib/smithy/templates/client/waiters.erb +42 -0
  47. data/lib/smithy/util/hash_formatter.rb +124 -0
  48. data/lib/smithy/util/underscore.rb +18 -0
  49. data/lib/smithy/util.rb +9 -0
  50. data/lib/smithy/views/client/auth_parameter.rb +29 -0
  51. data/lib/smithy/views/client/auth_parameters.rb +23 -0
  52. data/lib/smithy/views/client/auth_parameters_rbs.rb +23 -0
  53. data/lib/smithy/views/client/auth_plugin.rb +35 -0
  54. data/lib/smithy/views/client/auth_resolver.rb +125 -0
  55. data/lib/smithy/views/client/auth_resolver_rbs.rb +19 -0
  56. data/lib/smithy/views/client/client.rb +208 -0
  57. data/lib/smithy/views/client/client_rbs.rb +231 -0
  58. data/lib/smithy/views/client/customizations.rb +10 -0
  59. data/lib/smithy/views/client/endpoint_parameter.rb +156 -0
  60. data/lib/smithy/views/client/endpoint_parameters.rb +43 -0
  61. data/lib/smithy/views/client/endpoint_parameters_rbs.rb +28 -0
  62. data/lib/smithy/views/client/endpoint_plugin.rb +27 -0
  63. data/lib/smithy/views/client/endpoint_provider.rb +241 -0
  64. data/lib/smithy/views/client/endpoint_provider_rbs.rb +19 -0
  65. data/lib/smithy/views/client/endpoint_provider_spec.rb +137 -0
  66. data/lib/smithy/views/client/errors.rb +88 -0
  67. data/lib/smithy/views/client/errors_rbs.rb +12 -0
  68. data/lib/smithy/views/client/gemspec.rb +36 -0
  69. data/lib/smithy/views/client/module.rb +107 -0
  70. data/lib/smithy/views/client/module_rbs.rb +20 -0
  71. data/lib/smithy/views/client/operation_examples.rb +157 -0
  72. data/lib/smithy/views/client/paginators.rb +108 -0
  73. data/lib/smithy/views/client/plugin.rb +29 -0
  74. data/lib/smithy/views/client/plugin_list.rb +57 -0
  75. data/lib/smithy/views/client/protocol_spec.rb +254 -0
  76. data/lib/smithy/views/client/request_response_example.rb +179 -0
  77. data/lib/smithy/views/client/rubocop_yml.rb +19 -0
  78. data/lib/smithy/views/client/schema.rb +356 -0
  79. data/lib/smithy/views/client/schema_rbs.rb +84 -0
  80. data/lib/smithy/views/client/shape_to_hash.rb +99 -0
  81. data/lib/smithy/views/client/spec_helper.rb +19 -0
  82. data/lib/smithy/views/client/types.rb +293 -0
  83. data/lib/smithy/views/client/types_rbs.rb +67 -0
  84. data/lib/smithy/views/client/waiters.rb +82 -0
  85. data/lib/smithy/views/client.rb +47 -0
  86. data/lib/smithy/views/view.rb +30 -0
  87. data/lib/smithy/views.rb +9 -0
  88. data/lib/smithy/weld.rb +109 -0
  89. data/lib/smithy/welds/auth/anonymous_auth.rb +31 -0
  90. data/lib/smithy/welds/auth/http_api_key_auth.rb +34 -0
  91. data/lib/smithy/welds/auth/http_basic_auth.rb +34 -0
  92. data/lib/smithy/welds/auth/http_bearer_auth.rb +34 -0
  93. data/lib/smithy/welds/auth/http_digest_auth.rb +34 -0
  94. data/lib/smithy/welds/plugins.rb +54 -0
  95. data/lib/smithy/welds/rpc_v2_cbor.rb +20 -0
  96. data/lib/smithy/welds/rubocop.rb +33 -0
  97. data/lib/smithy/welds/transforms/default_endpoint_rules.json +35 -0
  98. data/lib/smithy/welds/transforms/default_endpoint_tests.json +24 -0
  99. data/lib/smithy/welds/transforms/endpoints.rb +68 -0
  100. data/lib/smithy/welds/transforms/synthetic_input_output.rb +60 -0
  101. data/lib/smithy/welds.rb +29 -0
  102. data/lib/smithy.rb +33 -2
  103. metadata +144 -9
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class RequestResponseExample
8
+ # @param [Hash] model Model
9
+ # @param [String] operation_name Operation name
10
+ # @param [Hash<String, Object>] operation Operation shape
11
+ def initialize(model, operation_name, operation)
12
+ @model = model
13
+ @operation_name = operation_name
14
+ @operation = operation
15
+ end
16
+
17
+ def docstrings
18
+ example = <<~EXAMPLE
19
+ @example Request syntax with placeholder values
20
+ params = #{request_params}
21
+ options = {}
22
+ response = client.#{@operation_name}(params, options)
23
+ @example Response structure with placeholder values
24
+ response.to_h #=>
25
+ #{response_hash}
26
+ EXAMPLE
27
+ example.split("\n")
28
+ end
29
+
30
+ private
31
+
32
+ def request_params
33
+ target = @operation['input']['target']
34
+ return '{}' if target == 'smithy.api#Unit'
35
+
36
+ input = Model.shape(@model, target)
37
+ return '{}' unless input['members'].any?
38
+
39
+ structure(input, ' ', Set.new)
40
+ end
41
+
42
+ def response_hash
43
+ target = @operation['output']['target']
44
+ return '{}' if target == 'smithy.api#Unit'
45
+
46
+ output = Model.shape(@model, target)
47
+ return '{}' unless output['members'].any?
48
+
49
+ structure(output, ' ', Set.new)
50
+ end
51
+
52
+ # rubocop:disable Metrics
53
+ def value(target, indent, visited)
54
+ if visited.include?(target)
55
+ shape = Model::Shape.name(target)
56
+ return "{\n#{indent} # recursive #{shape}\n#{indent}}"
57
+ end
58
+
59
+ visited += [target]
60
+ shape = Model.shape(@model, target)
61
+
62
+ case shape['type']
63
+ when 'blob' then blob(shape)
64
+ when 'boolean' then 'false'
65
+ when 'string' then string(target)
66
+ when 'byte' then '97'
67
+ when 'short', 'integer', 'long', 'bigInteger' then '1'
68
+ when 'float', 'double' then '1.0'
69
+ when 'bigDecimal' then 'BigDecimal(1)'
70
+ when 'timestamp' then 'Time.now'
71
+ when 'document' then '""null""'
72
+ when 'enum' then enum(shape)
73
+ when 'intEnum' then enum(shape, string: false)
74
+ when 'list' then list(shape, indent, visited)
75
+ when 'map' then map(shape, indent, visited)
76
+ when 'structure' then structure(shape, indent, visited)
77
+ when 'union' then union(shape, indent, visited)
78
+ else raise "unsupported shape type: #{shape['type'].inspect}"
79
+ end
80
+ end
81
+ # rubocop:enable Metrics
82
+
83
+ def blob(shape)
84
+ if shape && shape['traits']&.include?('smithy.api#streaming')
85
+ 'File.read("source_file")'
86
+ else
87
+ '"data"'
88
+ end
89
+ end
90
+
91
+ def string(target)
92
+ Model::Shape.name(target).inspect
93
+ end
94
+
95
+ def enum(shape, string: true)
96
+ enum_values = shape['members'].map do |_, member_shape|
97
+ value = member_shape['traits']['smithy.api#enumValue']
98
+ string ? "\"#{value}\"" : value
99
+ end
100
+ "#{enum_values.first} # One of: [#{enum_values.join(', ')}]"
101
+ end
102
+
103
+ def structure(structure_shape, indent, visited)
104
+ lines = []
105
+ lines << '{'
106
+ structure_shape['members']&.each_pair do |member_name, member_shape|
107
+ lines << member(member_name, member_shape, indent, visited)
108
+ end
109
+ lines.last.chomp!(',') if lines.last.end_with?(',')
110
+ lines << "#{indent}}"
111
+ lines.join("\n")
112
+ end
113
+
114
+ def union(union_shape, indent, visited)
115
+ lines = []
116
+ lines << '{'
117
+ lines << "#{indent} # One of:"
118
+ union_shape['members']&.each_pair do |member_name, member_shape|
119
+ lines << member(member_name, member_shape, indent, visited)
120
+ end
121
+ lines.last.chomp!(',') if lines.last.end_with?(',')
122
+ lines << "#{indent}}"
123
+ lines.join("\n")
124
+ end
125
+
126
+ def member(member_name, member_shape, indent, visited)
127
+ value = value(member_shape['target'], "#{indent} ", visited)
128
+ entry = "#{indent} #{member_name.underscore}: #{value},"
129
+ apply_comments(member_shape, entry)
130
+ end
131
+
132
+ def list(list_shape, indent, visited)
133
+ member_shape = list_shape['member']
134
+ if complex?(member_shape)
135
+ complex_list(member_shape, indent, visited)
136
+ else
137
+ scalar_list(member_shape, indent, visited)
138
+ end
139
+ end
140
+
141
+ def complex?(member_shape)
142
+ shape = Model.shape(@model, member_shape['target'])
143
+ %w[structure list map].include?(shape['type'])
144
+ end
145
+
146
+ def scalar_list(member_shape, indent, visited)
147
+ "[#{value(member_shape['target'], indent, visited)}]"
148
+ end
149
+
150
+ def complex_list(member_shape, indent, visited)
151
+ "[\n#{indent} #{value(member_shape['target'], "#{indent} ", visited)}\n#{indent}]"
152
+ end
153
+
154
+ def map(map_shape, indent, visited)
155
+ key = string(map_shape['key']['target'])
156
+ value = value(map_shape['value']['target'], "#{indent} ", visited)
157
+ "{\n#{indent} #{key} => #{value}\n#{indent}}"
158
+ end
159
+
160
+ def apply_comments(shape, text)
161
+ lines = text.lines.to_a
162
+ if lines[0].match(/\n$/)
163
+ lines[0] = lines[0].sub(/\n$/, "#{comments(shape)}\n")
164
+ else
165
+ lines[0] += comments(shape)
166
+ end
167
+ lines.join
168
+ end
169
+
170
+ def comments(shape)
171
+ required = shape['traits']&.any? { |k, _| k == 'smithy.api#required' }
172
+ comments = []
173
+ comments << 'required' if required
174
+ comments == [] ? '' : " # #{comments.join(', ')}"
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class RubocopYml < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ super()
11
+ end
12
+
13
+ def gem_name
14
+ @plan.gem_name
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,356 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class Schema < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ @model = plan.model
11
+ @service_id, @service = plan.service.first
12
+ @service_index = Model::ServiceIndex.new(@model)
13
+ super()
14
+ end
15
+
16
+ def module_name
17
+ @plan.module_name
18
+ end
19
+
20
+ def schema_gem?
21
+ @plan.type == :schema
22
+ end
23
+
24
+ def service_shape
25
+ @service_shape ||= ServiceShape.new(@plan.service)
26
+ end
27
+
28
+ def operation_shapes
29
+ @operation_shapes ||=
30
+ @service_index
31
+ .operations_for(@plan.service)
32
+ .map { |k, v| OperationShape.new(@plan.service, k, v) }
33
+ end
34
+
35
+ def shapes
36
+ @shapes ||=
37
+ @service_index
38
+ .shapes_for(@plan.service)
39
+ .map { |k, v| build_shape(k, v) }
40
+ end
41
+
42
+ private
43
+
44
+ def build_shape(id, shape)
45
+ args = [@plan.service, id, shape]
46
+ case shape['type']
47
+ when 'enum' then EnumShape.new(*args)
48
+ when 'intEnum' then IntEnumShape.new(*args)
49
+ when 'structure' then StructureShape.new(*args)
50
+ when 'list' then ListShape.new(*args)
51
+ when 'map' then MapShape.new(*args)
52
+ when 'union' then UnionShape.new(*args)
53
+ else Shape.new(*args)
54
+ end
55
+ end
56
+
57
+ # @api private
58
+ class ServiceShape
59
+ OMITTED_TRAITS = %w[
60
+ smithy.api#documentation
61
+ smithy.api#paginated
62
+ smithy.rules#endpointRuleSet
63
+ smithy.rules#endpointTests
64
+ ].freeze
65
+
66
+ def initialize(service)
67
+ @id, @service = service.first
68
+ @version = @service['version']
69
+ @traits = @service.fetch('traits', {}).except(*OMITTED_TRAITS)
70
+ end
71
+
72
+ attr_reader :id, :version, :traits
73
+
74
+ def name
75
+ Model::Shape.name(@id).camelize
76
+ end
77
+ end
78
+
79
+ # @api private
80
+ class OperationShape
81
+ OMITTED_TRAITS = %w[
82
+ smithy.api#documentation
83
+ smithy.api#examples
84
+ smithy.api#paginated
85
+ smithy.ruby#skipTests
86
+ smithy.test#httpRequestTests
87
+ smithy.test#httpResponseTests
88
+ smithy.waiters#waitable
89
+ ].freeze
90
+
91
+ def initialize(service, id, shape)
92
+ _, @service = service.first
93
+ @id = id
94
+ @input = ShapeRef.new(@service, nil, shape['input'])
95
+ @output = ShapeRef.new(@service, nil, shape['output'])
96
+ @errors = build_errors(@service['errors'] || []).concat(build_errors(shape['errors'] || []))
97
+ @traits = shape.fetch('traits', {})
98
+ end
99
+
100
+ attr_reader :id, :input, :output, :errors
101
+
102
+ def name
103
+ Model::Shape.name(@id)
104
+ end
105
+
106
+ def traits
107
+ @traits.except(*OMITTED_TRAITS)
108
+ end
109
+
110
+ def paginated?
111
+ @traits.key?('smithy.api#paginated')
112
+ end
113
+
114
+ def paginator
115
+ "Paginators::#{Model::Shape.name(@id)}.new"
116
+ end
117
+
118
+ private
119
+
120
+ def build_errors(errors)
121
+ errors.map { |shape_ref| ShapeRef.new(@service, nil, shape_ref) }
122
+ end
123
+ end
124
+
125
+ # @api private
126
+ class Shape
127
+ OMITTED_TRAITS = %w[
128
+ smithy.api#documentation
129
+ ].freeze
130
+
131
+ SHAPE_CLASS_MAP = {
132
+ 'bigDecimal' => 'BigDecimalShape',
133
+ 'bigInteger' => 'IntegerShape',
134
+ 'blob' => 'BlobShape',
135
+ 'boolean' => 'BooleanShape',
136
+ 'byte' => 'IntegerShape',
137
+ 'document' => 'DocumentShape',
138
+ 'double' => 'FloatShape',
139
+ 'enum' => 'EnumShape',
140
+ 'float' => 'FloatShape',
141
+ 'integer' => 'IntegerShape',
142
+ 'intEnum' => 'IntEnumShape',
143
+ 'list' => 'ListShape',
144
+ 'long' => 'IntegerShape',
145
+ 'map' => 'MapShape',
146
+ 'short' => 'IntegerShape',
147
+ 'string' => 'StringShape',
148
+ 'structure' => 'StructureShape',
149
+ 'timestamp' => 'TimestampShape',
150
+ 'union' => 'UnionShape'
151
+ }.freeze
152
+
153
+ def initialize(service, id, shape)
154
+ _, @service = service.first
155
+ @id = id
156
+ @shape = shape
157
+ @type = shape['type']
158
+ @traits = shape.fetch('traits', {}).except(*OMITTED_TRAITS)
159
+ end
160
+
161
+ attr_reader :type, :id
162
+
163
+ def name
164
+ (@service.dig('rename', @id) || Model::Shape.name(@id)).camelize
165
+ end
166
+
167
+ def initializer
168
+ traits_str = ", traits: #{@traits}" unless @traits.empty?
169
+ "Smithy::Schema::Shapes::#{SHAPE_CLASS_MAP[@type]}.new(id: '#{@id}'#{traits_str})"
170
+ end
171
+ end
172
+
173
+ # @api private
174
+ class StructureShape < Shape
175
+ OMITTED_TRAITS = %w[
176
+ smithy.api#documentation
177
+ smithy.api#input
178
+ smithy.api#output
179
+ ].freeze
180
+
181
+ def initialize(service, id, shape)
182
+ super
183
+ @members = build_shape_refs(shape['members'])
184
+ @traits = shape.fetch('traits', {}).except(*OMITTED_TRAITS)
185
+ end
186
+
187
+ attr_reader :members
188
+
189
+ def type_class
190
+ "Types::#{(@service.dig('rename', @id) || Model::Shape.name(@id)).camelize}"
191
+ end
192
+
193
+ def http_payload?
194
+ @members.any?(&:http_payload?)
195
+ end
196
+
197
+ def http_payload
198
+ @members.find(&:http_payload).http_payload
199
+ end
200
+
201
+ private
202
+
203
+ def build_shape_refs(members)
204
+ members.map { |name, shape_ref| ShapeRef.new(@service, name, shape_ref) }
205
+ end
206
+ end
207
+
208
+ # @api private
209
+ class EnumShape < Shape
210
+ def initialize(service, id, shape)
211
+ super
212
+ @members = build_shape_refs(shape['members'])
213
+ end
214
+
215
+ attr_reader :members
216
+
217
+ private
218
+
219
+ def build_shape_refs(members)
220
+ members.map { |name, shape_ref| ShapeRef.new(@service, name, shape_ref) }
221
+ end
222
+ end
223
+
224
+ # @api private
225
+ class IntEnumShape < Shape
226
+ def initialize(service, id, shape)
227
+ super
228
+ @members = build_shape_refs(shape['members'])
229
+ end
230
+
231
+ attr_reader :members
232
+
233
+ private
234
+
235
+ def build_shape_refs(members)
236
+ members.map { |name, shape_ref| ShapeRef.new(@service, name, shape_ref) }
237
+ end
238
+ end
239
+
240
+ # @api private
241
+ class ListShape < Shape
242
+ def initialize(service, id, shape)
243
+ super
244
+ @member = ShapeRef.new(@service, nil, shape['member'])
245
+ end
246
+
247
+ attr_reader :member
248
+ end
249
+
250
+ # @api private
251
+ class MapShape < Shape
252
+ def initialize(service, id, shape)
253
+ super
254
+ @key = ShapeRef.new(@service, nil, shape['key'])
255
+ @value = ShapeRef.new(@service, nil, shape['value'])
256
+ end
257
+
258
+ attr_reader :key, :value
259
+ end
260
+
261
+ # @api private
262
+ class UnionShape < Shape
263
+ def initialize(service, id, shape)
264
+ super
265
+ @members = build_shape_refs(shape['members'])
266
+ end
267
+
268
+ attr_reader :members
269
+
270
+ def type_class
271
+ "Types::#{(@service.dig('rename', @id) || Model::Shape.name(@id)).camelize}"
272
+ end
273
+
274
+ def union_type(shape_ref)
275
+ "#{type_class}::#{shape_ref.name.camelize}"
276
+ end
277
+
278
+ private
279
+
280
+ def build_shape_refs(members)
281
+ members.map { |name, shape_ref| ShapeRef.new(@service, name, shape_ref) }
282
+ end
283
+ end
284
+
285
+ # @api private
286
+ class ShapeRef
287
+ OMITTED_TRAITS = %w[
288
+ smithy.api#documentation
289
+ smithy.api#httpPayload
290
+ ].freeze
291
+
292
+ PRELUDE_SHAPES_MAP = {
293
+ 'smithy.api#BigInteger' => 'Prelude::BigInteger',
294
+ 'smithy.api#BigDecimal' => 'Prelude::BigDecimal',
295
+ 'smithy.api#Blob' => 'Prelude::Blob',
296
+ 'smithy.api#Boolean' => 'Prelude::Boolean',
297
+ 'smithy.api#Byte' => 'Prelude::Byte',
298
+ 'smithy.api#Document' => 'Prelude::Document',
299
+ 'smithy.api#Double' => 'Prelude::Double',
300
+ 'smithy.api#Float' => 'Prelude::Float',
301
+ 'smithy.api#Integer' => 'Prelude::Integer',
302
+ 'smithy.api#Long' => 'Prelude::Long',
303
+ 'smithy.api#PrimitiveBoolean' => 'Prelude::PrimitiveBoolean',
304
+ 'smithy.api#PrimitiveByte' => 'Prelude::PrimitiveByte',
305
+ 'smithy.api#PrimitiveDouble' => 'Prelude::PrimitiveDouble',
306
+ 'smithy.api#PrimitiveFloat' => 'Prelude::PrimitiveFloat',
307
+ 'smithy.api#PrimitiveInteger' => 'Prelude::PrimitiveInteger',
308
+ 'smithy.api#PrimitiveLong' => 'Prelude::PrimitiveLong',
309
+ 'smithy.api#PrimitiveShort' => 'Prelude::PrimitiveShort',
310
+ 'smithy.api#Short' => 'Prelude::Short',
311
+ 'smithy.api#String' => 'Prelude::String',
312
+ 'smithy.api#Timestamp' => 'Prelude::Timestamp',
313
+ 'smithy.api#Unit' => 'Prelude::Unit'
314
+ }.freeze
315
+
316
+ def initialize(service, member_name, shape_ref)
317
+ @service = service
318
+ @name = member_name.underscore if member_name
319
+ @member_name = member_name
320
+ @shape = shape(shape_ref['target'])
321
+ @traits = shape_ref.fetch('traits', {})
322
+ end
323
+
324
+ attr_reader :name
325
+
326
+ def initializer
327
+ options_str = "shape: #{@shape}"
328
+ options_str += ", member_name: '#{@member_name}'" if @member_name
329
+ options_str += ", traits: #{@traits}" unless @traits.empty?
330
+ "Smithy::Schema::Shapes::ShapeRef.new(#{options_str})"
331
+ end
332
+
333
+ def shape(id)
334
+ return "Smithy::Schema::Shapes::#{PRELUDE_SHAPES_MAP[id]}" if PRELUDE_SHAPES_MAP.key?(id)
335
+
336
+ (@service.dig('rename', id) || Model::Shape.name(id)).camelize
337
+ end
338
+
339
+ def traits
340
+ @traits.except(*OMITTED_TRAITS)
341
+ end
342
+
343
+ def http_payload?
344
+ @traits.key?('smithy.api#httpPayload')
345
+ end
346
+
347
+ def http_payload
348
+ return unless http_payload?
349
+
350
+ @name
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class SchemaRbs < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ @service_index = Model::ServiceIndex.new(plan.model)
11
+ super()
12
+ end
13
+
14
+ def module_name
15
+ @plan.module_name
16
+ end
17
+
18
+ def shapes
19
+ @service_index
20
+ .shapes_for(@plan.service)
21
+ .map { |id, shape| Shape.new(@plan.service, id, shape) }
22
+ end
23
+
24
+ def service_shape
25
+ @service_shape ||= ServiceShape.new(@plan.service)
26
+ end
27
+
28
+ # @api private
29
+ class ServiceShape
30
+ def initialize(service)
31
+ @id, = service.first
32
+ end
33
+
34
+ def name
35
+ Model::Shape.name(@id).camelize
36
+ end
37
+
38
+ def shape_class
39
+ 'ServiceShape'
40
+ end
41
+ end
42
+
43
+ # @api private
44
+ class Shape
45
+ SHAPE_TYPES_MAP = {
46
+ 'bigDecimal' => 'BigDecimalShape',
47
+ 'bigInteger' => 'IntegerShape',
48
+ 'blob' => 'BlobShape',
49
+ 'boolean' => 'BooleanShape',
50
+ 'byte' => 'IntegerShape',
51
+ 'document' => 'DocumentShape',
52
+ 'double' => 'FloatShape',
53
+ 'enum' => 'EnumShape',
54
+ 'float' => 'FloatShape',
55
+ 'integer' => 'IntegerShape',
56
+ 'intEnum' => 'IntEnumShape',
57
+ 'list' => 'ListShape',
58
+ 'long' => 'IntegerShape',
59
+ 'map' => 'MapShape',
60
+ 'short' => 'IntegerShape',
61
+ 'string' => 'StringShape',
62
+ 'structure' => 'StructureShape',
63
+ 'timestamp' => 'TimestampShape',
64
+ 'union' => 'UnionShape'
65
+ }.freeze
66
+
67
+ def initialize(service, id, shape)
68
+ _, @service = service.first
69
+ @id = id
70
+ @shape = shape
71
+ end
72
+
73
+ def name
74
+ (@service.dig('rename', @id) || Model::Shape.name(@id)).camelize
75
+ end
76
+
77
+ def shape_class
78
+ SHAPE_TYPES_MAP[@shape['type']]
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end