aws-sdk-code-generator 0.4.0.pre → 0.5.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/aws-sdk-code-generator/client_constructor.rb +2 -1
  3. data/lib/aws-sdk-code-generator/code_builder.rb +52 -0
  4. data/lib/aws-sdk-code-generator/eventstream_example.rb +34 -34
  5. data/lib/aws-sdk-code-generator/gem_builder.rb +3 -5
  6. data/lib/aws-sdk-code-generator/plugin_list.rb +2 -1
  7. data/lib/aws-sdk-code-generator/rbs/error_list.rb +38 -0
  8. data/lib/aws-sdk-code-generator/rbs/keyword_argument_builder.rb +159 -0
  9. data/lib/aws-sdk-code-generator/rbs/method_signature.rb +11 -0
  10. data/lib/aws-sdk-code-generator/rbs/resource_action.rb +39 -0
  11. data/lib/aws-sdk-code-generator/rbs/resource_association.rb +50 -0
  12. data/lib/aws-sdk-code-generator/rbs/resource_batch_action.rb +59 -0
  13. data/lib/aws-sdk-code-generator/rbs/resource_client_request.rb +40 -0
  14. data/lib/aws-sdk-code-generator/rbs/waiter.rb +53 -0
  15. data/lib/aws-sdk-code-generator/rbs.rb +40 -0
  16. data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +3 -1
  17. data/lib/aws-sdk-code-generator/resource_client_request.rb +3 -1
  18. data/lib/aws-sdk-code-generator/resource_waiter.rb +6 -5
  19. data/lib/aws-sdk-code-generator/service.rb +21 -0
  20. data/lib/aws-sdk-code-generator/views/async_client_class.rb +5 -1
  21. data/lib/aws-sdk-code-generator/views/client_api_module.rb +29 -4
  22. data/lib/aws-sdk-code-generator/views/client_class.rb +5 -1
  23. data/lib/aws-sdk-code-generator/views/event_streams_module.rb +7 -1
  24. data/lib/aws-sdk-code-generator/views/features/smoke.rb +99 -23
  25. data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +1 -4
  26. data/lib/aws-sdk-code-generator/views/gemspec.rb +13 -3
  27. data/lib/aws-sdk-code-generator/views/rbs/client_class.rb +172 -0
  28. data/lib/aws-sdk-code-generator/views/rbs/errors_module.rb +28 -0
  29. data/lib/aws-sdk-code-generator/views/rbs/resource_class.rb +95 -0
  30. data/lib/aws-sdk-code-generator/views/rbs/root_resource_class.rb +30 -0
  31. data/lib/aws-sdk-code-generator/views/rbs/types_module.rb +257 -0
  32. data/lib/aws-sdk-code-generator/views/rbs/waiters_module.rb +22 -0
  33. data/lib/aws-sdk-code-generator/views/spec/endpoint_provider_spec_class.rb +5 -1
  34. data/lib/aws-sdk-code-generator/views/types_module.rb +8 -9
  35. data/lib/aws-sdk-code-generator.rb +17 -1
  36. data/templates/client_api_module.mustache +7 -0
  37. data/templates/client_class.mustache +0 -45
  38. data/templates/endpoints_module.mustache +1 -0
  39. data/templates/endpoints_plugin.mustache +4 -2
  40. data/templates/features/smoke.mustache +11 -15
  41. data/templates/features/step_definitions.mustache +0 -5
  42. data/templates/gemspec.mustache +5 -2
  43. data/templates/rbs/client_class.mustache +39 -0
  44. data/templates/rbs/errors_module.mustache +17 -0
  45. data/templates/rbs/resource_class.mustache +71 -0
  46. data/templates/rbs/root_resource_class.mustache +26 -0
  47. data/templates/rbs/types_module.mustache +37 -0
  48. data/templates/rbs/waiters_module.mustache +17 -0
  49. data/templates/resource_class.mustache +3 -1
  50. data/templates/spec/endpoint_provider_spec_class.mustache +10 -0
  51. metadata +24 -5
  52. data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +0 -26
  53. data/templates/features/smoke_step_definitions.mustache +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4bb64ca30811529d0c5c4149e3d46b7eabef0d3068672ca06ed6d9fc97369f5
4
- data.tar.gz: c2e56887b3686a58569da5fa643a8cb69bcca35c4b0f24dbdd67e48c3d3675c8
3
+ metadata.gz: 3332820d3c044afc9813a785b511cc25fcce3581477a3f05f860bf49bb225ffe
4
+ data.tar.gz: '09ed058cda2368a87496efc47772d019dfb3f1911732c344c9146af6a51f68fe'
5
5
  SHA512:
6
- metadata.gz: 3a6b20c93b4c58ef3bfac9e2d48551540106fa907deb17b72bb00876c807a2dbf05079b38634534a18a563a6f0b6affd98564a94a16370ba4e3d7efcf34a1034
7
- data.tar.gz: 63b927d59a16241bc32e5ec51d647ae6dcc952c562e9eedccf50451bf62a64065d3833be2b8b0d7ffef6114300068b426bf3a96617c0c97f8bb9932b3ff45605
6
+ metadata.gz: 4de3ecc3f1f0ff599143e79808c395aa82319da3af73f9c9b87c1d6526f438feb4471e52d68e8559a027223d523c21d89250e2e212c83a53a52c41726a8df7e3
7
+ data.tar.gz: 9b6d2456bb9bd9fbff1e7beb50c0f93a8137e1eb249cf931107e0f1dca7dc0f92b57da5d011a199900c03a5cd6d6f53b7fd7387cafead162f7aa892dffaea76f
@@ -8,7 +8,8 @@ module AwsSdkCodeGenerator
8
8
 
9
9
  def initialize(options)
10
10
  plugin_options = documented_plugin_options(options.fetch(:plugins)) +
11
- documented_plugin_options(options.fetch(:codegenerated_plugins))
11
+ documented_plugin_options(options.fetch(:codegenerated_plugins)) +
12
+ documented_plugin_options(options.fetch(:default_plugins, []))
12
13
  documentation = {}
13
14
  plugin_options.each do |option|
14
15
  documentation[option.name] = YardOptionTag.new(
@@ -109,6 +109,58 @@ module AwsSdkCodeGenerator
109
109
  end
110
110
  end
111
111
 
112
+ # @return [Enumerable<String<path>, String<code>>]
113
+ def rbs_files(options = {})
114
+ Enumerator.new do |y|
115
+ prefix = options.fetch(:prefix, '')
116
+ codegenerated_plugins = codegen_plugins(prefix)
117
+ client_class = Views::RBS::ClientClass.new(
118
+ service_name: @service.name,
119
+ codegenerated_plugins: codegenerated_plugins,
120
+ aws_sdk_core_lib_path: @aws_sdk_core_lib_path,
121
+ legacy_endpoints: @service.legacy_endpoints?,
122
+ signature_version: @service.signature_version,
123
+ api: @service.api,
124
+ waiters: @service.waiters,
125
+ protocol: @service.protocol,
126
+ add_plugins: @service.add_plugins,
127
+ remove_plugins: @service.remove_plugins,
128
+ )
129
+ y.yield("#{prefix}/client.rbs", client_class.render)
130
+ y.yield("#{prefix}/errors.rbs", Views::RBS::ErrorsModule.new(
131
+ service: @service
132
+ ).render)
133
+ y.yield("#{prefix}/resource.rbs", Views::RBS::RootResourceClass.new(
134
+ service_name: @service.name,
135
+ client_class: client_class,
136
+ api: @service.api,
137
+ resources: @service.resources,
138
+ paginators: @service.paginators,
139
+ ).render)
140
+ y.yield("#{prefix}/waiters.rbs", Views::RBS::WaitersModule.new(
141
+ service_name: @service.name,
142
+ api: @service.api,
143
+ waiters: @service.waiters,
144
+ ).render)
145
+ y.yield("#{prefix}/types.rbs", Views::RBS::TypesModule.new(
146
+ service: @service
147
+ ).render)
148
+ if @resources
149
+ @resources['resources'].keys.sort.each do |class_name|
150
+ path = "#{prefix}/#{Underscore.underscore(class_name)}.rbs"
151
+ code = Views::RBS::ResourceClass.new(
152
+ service_name: @service.name,
153
+ class_name: class_name,
154
+ resource: @resources['resources'][class_name],
155
+ api: @service.api,
156
+ paginators: @service.paginators,
157
+ ).render
158
+ y.yield(path, code)
159
+ end
160
+ end
161
+ end
162
+ end
163
+
112
164
  private
113
165
 
114
166
  def service_module(prefix, codegenerated_plugins)
@@ -39,52 +39,53 @@ module AwsSdkCodeGenerator
39
39
  <<-EXAMPLE.strip
40
40
  # @example Bi-directional EventStream Operation Example
41
41
  #
42
- # You can signal input events after initial request is
43
- # established, events will be sent to stream
44
- # immediately (once stream connection is established successfully).
42
+ # You can signal input events after the initial request is established. Events
43
+ # will be sent to the stream immediately once the stream connection is
44
+ # established successfully.
45
45
  #
46
- # To signal events, you can call #signal methods from an #{@input_eventstream} object.
47
- # Make sure signal events before calling #wait or #join! at async response.
46
+ # To signal events, you can call the #signal methods from an #{@input_eventstream}
47
+ # object. You must signal events before calling #wait or #join! on the async response.
48
48
  #
49
49
  # input_stream = #{@input_eventstream}.new
50
50
  #
51
- # async_resp = #{@receiver}.#{@method_name}( # params input,
51
+ # async_resp = #{@receiver}.#{@method_name}(
52
+ # # params input
52
53
  # input_event_stream_handler: input_stream) do |out_stream|
53
54
  #
54
- # # register callbacks for events arrival
55
+ # # register callbacks for events
55
56
  #{event_entry(:output, 'out_stream', 2)}
56
57
  #
57
58
  # end
58
- # # => returns Aws::Seahorse::Client::AsyncResponse
59
+ # # => Aws::Seahorse::Client::AsyncResponse
59
60
  #
60
61
  # # signal events
61
62
  #{event_entry(:input, 'input_stream')}
62
63
  #
63
- # # make sure signaling :end_stream in the end
64
+ # # make sure to signal :end_stream at the end
64
65
  # input_stream.signal_end_stream
65
66
  #
66
- # # wait until stream is closed before finalizing sync response
67
+ # # wait until stream is closed before finalizing the sync response
67
68
  # resp = async_resp.wait
68
- # # Or close stream and finalizing sync response immediately
69
+ # # Or close the stream and finalize sync response immediately
69
70
  # # resp = async_resp.join!
70
71
  #
71
- # Inorder to streamingly processing events received, you can also provide an #{@output_eventstream}
72
- # object to register callbacks before initializing request instead of processing from request block
72
+ # You can also provide an #{@output_eventstream} object to register callbacks
73
+ # before initializing the request instead of processing from the request block.
73
74
  #
74
75
  # output_stream = #{@output_eventstream}.new
75
- # # register callbacks for events arrival
76
+ # # register callbacks for output events
76
77
  #{event_entry(:output, 'output_stream')}
77
78
  #{error_event_entry('output_stream')}
78
79
  #
79
- # async_resp = #{@receiver}.#{@method_name} ( #params input,
80
+ # async_resp = #{@receiver}.#{@method_name} (
81
+ # # params input
80
82
  # input_event_stream_handler: input_stream
81
83
  # output_event_stream_handler: output_stream
82
84
  # )
83
85
  #
84
- # resp = async_resp.wait!
86
+ # resp = async_resp.join!
85
87
  #
86
- # Besides above usage patterns for process events when they arrive immediately, you can also
87
- # iterate through events after response complete.
88
+ # You can also iterate through events after the response is complete.
88
89
  #
89
90
  # Events are available at #{@resp_var}.#{@output_eventstream_member} # => Enumerator
90
91
  EXAMPLE
@@ -94,22 +95,22 @@ module AwsSdkCodeGenerator
94
95
  <<-EXAMPLE.strip
95
96
  # @example EventStream Operation Example
96
97
  #
97
- # You can process event once it arrives immediately, or wait until
98
- # full response complete and iterate through eventstream enumerator.
98
+ # You can process the event once it arrives immediately, or wait until the
99
+ # full response is complete and iterate through the eventstream enumerator.
99
100
  #
100
101
  # To interact with event immediately, you need to register ##{@method_name}
101
- # with callbacks, callbacks can be register for specifc events or for all events,
102
- # callback for errors in the event stream is also available for register.
102
+ # with callbacks. Callbacks can be registered for specific events or for all
103
+ # events, including error events.
103
104
  #
104
- # Callbacks can be passed in by `:event_stream_handler` option or within block
105
- # statement attached to ##{@method_name} call directly. Hybrid pattern of both
106
- # is also supported.
105
+ # Callbacks can be passed into the `:event_stream_handler` option or within a
106
+ # block statement attached to the ##{@method_name} call directly. Hybrid
107
+ # pattern of both is also supported.
107
108
  #
108
- # `:event_stream_handler` option takes in either Proc object or
109
+ # `:event_stream_handler` option takes in either a Proc object or
109
110
  # #{@output_eventstream} object.
110
111
  #
111
- # Usage pattern a): callbacks with a block attached to ##{@method_name}
112
- # Example for registering callbacks for all event types and error event
112
+ # Usage pattern a): Callbacks with a block attached to ##{@method_name}
113
+ # Example for registering callbacks for all event types and an error event
113
114
  #
114
115
  # #{@receiver}.#{@method_name}( # params input# ) do |stream|
115
116
  #{error_event_entry('stream', 2)}
@@ -122,9 +123,9 @@ module AwsSdkCodeGenerator
122
123
  #
123
124
  # end
124
125
  #
125
- # Usage pattern b): pass in `:event_stream_handler` for ##{@method_name}
126
+ # Usage pattern b): Pass in `:event_stream_handler` for ##{@method_name}
126
127
  #
127
- # 1) create a #{@output_eventstream} object
128
+ # 1) Create a #{@output_eventstream} object
128
129
  # Example for registering callbacks with specific events
129
130
  #
130
131
  # handler = #{@output_eventstream}.new
@@ -132,7 +133,7 @@ module AwsSdkCodeGenerator
132
133
  #
133
134
  # #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler)
134
135
  #
135
- # 2) use a Ruby Proc object
136
+ # 2) Use a Ruby Proc object
136
137
  # Example for registering callbacks with specific events
137
138
  #
138
139
  # handler = Proc.new do |stream|
@@ -141,7 +142,7 @@ module AwsSdkCodeGenerator
141
142
  #
142
143
  # #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler)
143
144
  #
144
- # Usage pattern c): hybird pattern of a) and b)
145
+ # Usage pattern c): Hybrid pattern of a) and b)
145
146
  #
146
147
  # handler = #{@output_eventstream}.new
147
148
  #{event_entry(:output, 'handler', 2)}
@@ -150,8 +151,7 @@ module AwsSdkCodeGenerator
150
151
  #{error_event_entry('stream', 2)}
151
152
  # end
152
153
  #
153
- # Besides above usage patterns for process events when they arrive immediately, you can also
154
- # iterate through events after response complete.
154
+ # You can also iterate through events after the response complete.
155
155
  #
156
156
  # Events are available at #{@resp_var}.#{@output_eventstream_member} # => Enumerator
157
157
  # For parameter input example, please refer to following request syntax
@@ -25,7 +25,6 @@ module AwsSdkCodeGenerator
25
25
  y.yield('features/step_definitions.rb', features_step_definitions_file)
26
26
  if @service.smoke_tests
27
27
  y.yield('features/smoke.feature', smoke_file)
28
- y.yield('features/smoke_step_definitions.rb', smoke_step_definitions_file)
29
28
  end
30
29
  y.yield('VERSION', version_file)
31
30
  y.yield('LICENSE.txt', license_file)
@@ -37,6 +36,9 @@ module AwsSdkCodeGenerator
37
36
  code.spec_files.each do |path, code|
38
37
  y.yield("spec/#{path}", code)
39
38
  end
39
+ code.rbs_files.each do |path, code|
40
+ y.yield("sig/#{path}", code)
41
+ end
40
42
  end.each(&block)
41
43
  end
42
44
 
@@ -54,10 +56,6 @@ module AwsSdkCodeGenerator
54
56
  Views::Features::Smoke.new(options).render
55
57
  end
56
58
 
57
- def smoke_step_definitions_file
58
- Views::Features::SmokeStepDefinitions.new(options).render
59
- end
60
-
61
59
  def features_step_definitions_file
62
60
  Views::Features::StepDefinitions.new(options).render
63
61
  end
@@ -54,12 +54,14 @@ module AwsSdkCodeGenerator
54
54
  'Aws::Plugins::ResponsePaging' => "#{core_plugins}/response_paging.rb",
55
55
  'Aws::Plugins::StubResponses' => "#{core_plugins}/stub_responses.rb",
56
56
  'Aws::Plugins::IdempotencyToken' => "#{core_plugins}/idempotency_token.rb",
57
+ 'Aws::Plugins::InvocationId' => "#{core_plugins}/invocation_id.rb",
57
58
  'Aws::Plugins::JsonvalueConverter' => "#{core_plugins}/jsonvalue_converter.rb",
58
59
  'Aws::Plugins::ClientMetricsPlugin' => "#{core_plugins}/client_metrics_plugin.rb",
59
60
  'Aws::Plugins::ClientMetricsSendPlugin' => "#{core_plugins}/client_metrics_send_plugin.rb",
60
61
  'Aws::Plugins::TransferEncoding' => "#{core_plugins}/transfer_encoding.rb",
61
62
  'Aws::Plugins::HttpChecksum' => "#{core_plugins}/http_checksum.rb",
62
63
  'Aws::Plugins::ChecksumAlgorithm' => "#{core_plugins}/checksum_algorithm.rb",
64
+ 'Aws::Plugins::RequestCompression' => "#{core_plugins}/request_compression.rb",
63
65
  'Aws::Plugins::DefaultsMode' => "#{core_plugins}/defaults_mode.rb",
64
66
  'Aws::Plugins::RecursionDetection' => "#{core_plugins}/recursion_detection.rb"
65
67
  }
@@ -74,7 +76,6 @@ module AwsSdkCodeGenerator
74
76
  plugins.delete('Aws::Plugins::ClientMetricsPlugin')
75
77
  plugins.delete('Aws::Plugins::ClientMetricsSendPlugin')
76
78
  plugins.delete('Aws::Plugins::TransferEncoding')
77
- plugins['Aws::Plugins::InvocationId'] = "#{core_plugins}/invocation_id.rb"
78
79
  plugins
79
80
  end
80
81
 
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module RBS
5
+ class ErrorList
6
+ include Enumerable
7
+
8
+ def initialize(api:, module_name:)
9
+ @api = api
10
+ @module_name = module_name
11
+ @errors = @api['shapes'].inject([]) do |es, (name, shape)|
12
+ if error_struct?(shape)
13
+ members = shape["members"].map do |member_name, member_body|
14
+ MethodSignature.new(
15
+ method_name: Underscore.underscore(member_name),
16
+ overloads: ["() -> #{Docstring.ucfirst(member_body['type'] ||'::String')}"]
17
+ )
18
+ end
19
+ es << {
20
+ name: name,
21
+ members: members,
22
+ }
23
+ end
24
+ es
25
+ end
26
+ end
27
+
28
+ def error_struct?(shape)
29
+ shape['type'] == 'structure' && !!!shape['event'] &&
30
+ (shape['error'] || shape['exception'])
31
+ end
32
+
33
+ def to_a
34
+ @errors
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module RBS
5
+ # similar to SyntaxExampleHash
6
+ class KeywordArgumentBuilder
7
+ include Helper
8
+
9
+ attr_reader :newline
10
+
11
+ def initialize(api:, shape:, newline:)
12
+ @api = api
13
+ @shape = shape
14
+ @newline = newline
15
+ end
16
+
17
+ def format(indent: '')
18
+ members_str = struct_members(@shape, indent, [], keyword: true)
19
+ result = []
20
+ result << '' if newline
21
+ result << members_str if !members_str.empty?
22
+ result << indent if newline
23
+ result.join(joint)
24
+ end
25
+
26
+ def struct(struct_shape, i, visited)
27
+ members_str = struct_members(struct_shape, i, visited, keyword: false)
28
+ result = ["{"]
29
+ result << members_str if struct_shape['members']&.empty?&.!
30
+ result << "#{i}}"
31
+ result.join(joint)
32
+ end
33
+
34
+ def struct_members(struct_shape, i, visited, keyword:)
35
+ lines = []
36
+ unless struct_shape['members'].nil?
37
+ n = 0
38
+ struct_shape['members'].each do |member_name, member_ref|
39
+ next if member_ref['documented'] === false
40
+ more_indent = newline ? " " : ""
41
+ if @api['shapes'][member_ref['shape']]['eventstream'] === true
42
+ # FIXME: "input_event_stream_hander: EventStreams::#{member_ref['shape']}.new"
43
+ lines << "#{i}#{more_indent}input_event_stream_hander: untyped,"
44
+ else
45
+ lines << "#{i}#{more_indent}#{struct_member(struct_shape, member_name, member_ref, i, visited, keyword: keyword)}"
46
+ end
47
+ end
48
+ end
49
+ if lines.empty?
50
+ ""
51
+ else
52
+ lines.join(joint).chomp(",")
53
+ end
54
+ end
55
+
56
+ def struct_member(struct, member_name, member_ref, i, visited, keyword:)
57
+ required = (struct['required'] || []).include?(member_name)
58
+ if keyword
59
+ "#{required ? '' : '?'}#{underscore(member_name)}: #{ref_value(member_ref, i + more_indent, visited)},"
60
+ else
61
+ "#{underscore(member_name)}: #{ref_value(member_ref, i + more_indent, visited)}#{required ? '' : '?'},"
62
+ end
63
+ end
64
+
65
+ def ref_value(ref, i, visited)
66
+ if visited.include?(ref['shape'])
67
+ return "untyped"
68
+ else
69
+ visited = visited + [ref['shape']]
70
+ end
71
+
72
+ s = shape(ref)
73
+ case s['type']
74
+ when 'structure'
75
+ if ref['shape'] == 'AttributeValue'
76
+ 'untyped'
77
+ else
78
+ struct(s, i, visited)
79
+ end
80
+ when 'blob'
81
+ if ref['streaming']
82
+ "::String | ::StringIO | ::File" # input only
83
+ else
84
+ "::String"
85
+ end
86
+ when 'list' then list(s, i, visited)
87
+ when 'map' then map(s, i, visited)
88
+ when 'boolean' then "bool"
89
+ when 'integer', 'long' then '::Integer'
90
+ when 'float', 'double' then '::Float'
91
+ when 'byte' then '::Integer'
92
+ when 'character' then '::String'
93
+ when 'string' then string(ref)
94
+ when 'timestamp' then '::Time'
95
+ else raise "unsupported shape #{s['type'].inspect}"
96
+ end
97
+ end
98
+
99
+ def list(list_shape, i, visited)
100
+ member_ref = list_shape['member']
101
+ if complex?(member_ref)
102
+ complex_list(member_ref, i, visited)
103
+ else
104
+ scalar_list(member_ref, i, visited)
105
+ end
106
+ end
107
+
108
+ def scalar_list(member_ref, i, visited)
109
+ "Array[#{ref_value(member_ref, i, visited)}]"
110
+ end
111
+
112
+ def complex_list(member_ref, i, visited)
113
+ newline_indent = newline ? "\n#{i}" : ""
114
+ "Array[#{newline_indent}#{more_indent}#{ref_value(member_ref, i + more_indent, visited)},#{newline_indent}]"
115
+ end
116
+
117
+ def complex?(ref)
118
+ s = shape(ref)
119
+ if s['type'] == 'structure'
120
+ !ddb_av?(ref)
121
+ else
122
+ s['type'] == 'list' || s['type'] == 'map'
123
+ end
124
+ end
125
+
126
+ def ddb_av?(ref)
127
+ s = shape(ref)
128
+ case s['type']
129
+ when 'list' then ddb_av?(s['member'])
130
+ when 'structure' then ref['shape'] == 'AttributeValue'
131
+ else false
132
+ end
133
+ end
134
+
135
+ def map(map_shape, i, visited)
136
+ key = string(map_shape['key'])
137
+ value = ref_value(map_shape['value'], i + more_indent, visited)
138
+ "Hash[#{key}, #{value}]"
139
+ end
140
+
141
+ def string(ref)
142
+ string_shape = shape(ref)
143
+ if string_shape['enum']
144
+ "(#{string_shape['enum'].map { |s| "\"#{s}\"" }.join(" | ")})"
145
+ else ref['shape']
146
+ "::String"
147
+ end
148
+ end
149
+
150
+ def more_indent
151
+ newline ? " " : ""
152
+ end
153
+
154
+ def joint
155
+ newline ? "\n" : " "
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module RBS
5
+ class MethodSignature < Struct.new(:method_name, :overloads, keyword_init: true)
6
+ def signature
7
+ "def #{method_name}: #{overloads.join("\n #{" " * method_name.length}| ")}"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module RBS
5
+ class ResourceAction
6
+ class << self
7
+ def build_method_signature_list(resource:, api:)
8
+ (resource["actions"] || []).map do |action_name, action|
9
+ new(action_name: action_name, action: action, api: api).build_method_signature
10
+ end
11
+ end
12
+ end
13
+
14
+ def initialize(action_name:, action:, api:)
15
+ request = action["request"]
16
+ operation = api["operations"][request["operation"]]
17
+ returns = if action["resource"]
18
+ resource = action["resource"]
19
+ AwsSdkCodeGenerator::Api.plural?(resource) ? "#{resource["type"]}::Collection" : resource["type"]
20
+ elsif operation["output"]
21
+ "Types::#{operation["output"]["shape"]}"
22
+ else
23
+ "::Aws::EmptyStructure"
24
+ end
25
+
26
+ @client_request = ResourceClientRequest.new(
27
+ method_name: Underscore.underscore(action_name),
28
+ api: api,
29
+ request: request,
30
+ returns: returns,
31
+ )
32
+ end
33
+
34
+ def build_method_signature
35
+ @client_request.build_method_signature
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module RBS
5
+ class ResourceAssociation
6
+ class << self
7
+ def build_method_signature_list(resource:, api:, paginators:)
8
+ associations = []
9
+ associations += has_associations(resource: resource)
10
+ associations += has_many_associations(resource: resource, api: api, paginators: paginators)
11
+ associations.sort_by(&:method_name)
12
+ end
13
+
14
+ private
15
+
16
+ def has_associations(resource:)
17
+ resource.fetch("has", {}).map do |name, assoc|
18
+ method_name = Underscore.underscore(name)
19
+ arguments = AwsSdkCodeGenerator::ResourceHasAssociation.send(:compute_params, assoc).map { |param|
20
+ "#{param[:type]} #{Underscore.underscore(param[:name])}"
21
+ }.join(', ')
22
+ returns = AwsSdkCodeGenerator::ResourceHasAssociation.send(:return_type, assoc).sub(/, nil$/, "?")
23
+ MethodSignature.new(
24
+ method_name: method_name,
25
+ overloads: ["(#{arguments}) -> #{returns}"]
26
+ )
27
+ end
28
+ end
29
+
30
+ def has_many_associations(resource:, api:, paginators:)
31
+ resource.fetch("hasMany", {}).map do |name, assoc|
32
+ ResourceClientRequest.new(
33
+ method_name: Underscore.underscore(name),
34
+ api: api,
35
+ request: assoc["request"],
36
+ returns: "#{assoc["resource"]["type"]}::Collection",
37
+ skip: AwsSdkCodeGenerator::ResourceHasManyAssociation.send(
38
+ :paging_options,
39
+ {
40
+ assoc: assoc,
41
+ paginators: paginators
42
+ }
43
+ ),
44
+ ).build_method_signature
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module RBS
5
+ class ResourceBatchAction
6
+ class << self
7
+ def build_method_signature_list(resource:, api:)
8
+ resource.fetch("batchActions", {}).map do |name, action|
9
+ new(api: api, name: name, action: action).build_method_signature
10
+ end
11
+ end
12
+ end
13
+
14
+ def initialize(api:, name:, action:)
15
+ @api = api
16
+ @name = name
17
+ @action = action
18
+ @batch_action_documentation = AwsSdkCodeGenerator::ResourceBatchActionDocumentation.new(
19
+ var_name: nil,
20
+ method_name: method_name,
21
+ action: action,
22
+ api: api,
23
+ )
24
+ @skip_params = @batch_action_documentation.send(:skip_params)
25
+ @input_ref = @batch_action_documentation.send(:input_ref)
26
+ @input_shape = AwsSdkCodeGenerator::Api.shape(@input_ref, api)
27
+ end
28
+
29
+ def build_method_signature
30
+ arguments = nil
31
+ include_required = false
32
+
33
+ if @input_shape
34
+ shape = Helper.deep_copy(@input_shape)
35
+ shape.fetch("members").reject! { |member_name, _| @skip_params.include?(member_name) }
36
+ arguments = KeywordArgumentBuilder.new(
37
+ api: @api,
38
+ shape: shape,
39
+ newline: true
40
+ ).format(indent: ' ' * (14 + method_name.length))
41
+ end
42
+
43
+ MethodSignature.new(
44
+ method_name: method_name,
45
+ overloads: [
46
+ "(#{arguments}) -> void",
47
+ "(#{include_required ? "" : "?"}Hash[Symbol, untyped]) -> void",
48
+ ]
49
+ )
50
+ end
51
+
52
+ private
53
+
54
+ def method_name
55
+ AwsSdkCodeGenerator::ResourceBatchAction.send(:build_method_name, @name, @action)
56
+ end
57
+ end
58
+ end
59
+ end