aws-sdk-code-generator 0.3.0.pre → 0.5.0.pre
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/aws-sdk-code-generator/client_constructor.rb +2 -1
- data/lib/aws-sdk-code-generator/code_builder.rb +52 -0
- data/lib/aws-sdk-code-generator/eventstream_example.rb +34 -34
- data/lib/aws-sdk-code-generator/gem_builder.rb +3 -5
- data/lib/aws-sdk-code-generator/plugin_list.rb +2 -1
- data/lib/aws-sdk-code-generator/rbs/error_list.rb +38 -0
- data/lib/aws-sdk-code-generator/rbs/keyword_argument_builder.rb +159 -0
- data/lib/aws-sdk-code-generator/rbs/method_signature.rb +11 -0
- data/lib/aws-sdk-code-generator/rbs/resource_action.rb +39 -0
- data/lib/aws-sdk-code-generator/rbs/resource_association.rb +50 -0
- data/lib/aws-sdk-code-generator/rbs/resource_batch_action.rb +59 -0
- data/lib/aws-sdk-code-generator/rbs/resource_client_request.rb +40 -0
- data/lib/aws-sdk-code-generator/rbs/waiter.rb +53 -0
- data/lib/aws-sdk-code-generator/rbs.rb +40 -0
- data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +3 -1
- data/lib/aws-sdk-code-generator/resource_client_request.rb +3 -1
- data/lib/aws-sdk-code-generator/resource_waiter.rb +6 -5
- data/lib/aws-sdk-code-generator/service.rb +21 -0
- data/lib/aws-sdk-code-generator/views/async_client_class.rb +5 -1
- data/lib/aws-sdk-code-generator/views/client_api_module.rb +29 -4
- data/lib/aws-sdk-code-generator/views/client_class.rb +5 -1
- data/lib/aws-sdk-code-generator/views/endpoint_provider_class.rb +221 -2
- data/lib/aws-sdk-code-generator/views/event_streams_module.rb +7 -1
- data/lib/aws-sdk-code-generator/views/features/smoke.rb +99 -23
- data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +1 -4
- data/lib/aws-sdk-code-generator/views/gemspec.rb +13 -3
- data/lib/aws-sdk-code-generator/views/rbs/client_class.rb +172 -0
- data/lib/aws-sdk-code-generator/views/rbs/errors_module.rb +28 -0
- data/lib/aws-sdk-code-generator/views/rbs/resource_class.rb +95 -0
- data/lib/aws-sdk-code-generator/views/rbs/root_resource_class.rb +30 -0
- data/lib/aws-sdk-code-generator/views/rbs/types_module.rb +257 -0
- data/lib/aws-sdk-code-generator/views/rbs/waiters_module.rb +22 -0
- data/lib/aws-sdk-code-generator/views/spec/endpoint_provider_spec_class.rb +5 -1
- data/lib/aws-sdk-code-generator/views/types_module.rb +8 -9
- data/lib/aws-sdk-code-generator.rb +17 -1
- data/templates/client_api_module.mustache +7 -0
- data/templates/client_class.mustache +0 -45
- data/templates/endpoint_provider_class.mustache +1 -19
- data/templates/endpoints_module.mustache +1 -0
- data/templates/endpoints_plugin.mustache +4 -2
- data/templates/features/smoke.mustache +11 -15
- data/templates/features/step_definitions.mustache +0 -5
- data/templates/gemspec.mustache +5 -2
- data/templates/rbs/client_class.mustache +39 -0
- data/templates/rbs/errors_module.mustache +17 -0
- data/templates/rbs/resource_class.mustache +71 -0
- data/templates/rbs/root_resource_class.mustache +26 -0
- data/templates/rbs/types_module.mustache +37 -0
- data/templates/rbs/waiters_module.mustache +17 -0
- data/templates/resource_class.mustache +3 -1
- data/templates/spec/endpoint_provider_spec_class.mustache +10 -0
- metadata +24 -5
- data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +0 -26
- data/templates/features/smoke_step_definitions.mustache +0 -31
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class ResourceClientRequest
|
6
|
+
include Helper
|
7
|
+
|
8
|
+
attr_reader :method_name
|
9
|
+
attr_reader :arguments
|
10
|
+
attr_reader :returns
|
11
|
+
attr_reader :include_required
|
12
|
+
|
13
|
+
def initialize(method_name:, api:, request:, returns:, skip: [])
|
14
|
+
@method_name = method_name
|
15
|
+
@returns = returns
|
16
|
+
@include_required = false
|
17
|
+
|
18
|
+
operation = api["operations"][request["operation"]]
|
19
|
+
shape_ref = operation["input"]
|
20
|
+
input_shape = AwsSdkCodeGenerator::Api.shape(shape_ref, api)
|
21
|
+
skip = Set.new(skip + AwsSdkCodeGenerator::ResourceSkipParams.compute(input_shape, request))
|
22
|
+
@arguments = if input_shape
|
23
|
+
shape = deep_copy(input_shape)
|
24
|
+
shape["members"].select! { |member_name, _| !skip.include?(member_name) }
|
25
|
+
KeywordArgumentBuilder.new(api: api, shape: shape, newline: true).format(indent: ' ' * (12 + method_name.length))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_method_signature
|
30
|
+
MethodSignature.new(
|
31
|
+
method_name: method_name,
|
32
|
+
overloads: [
|
33
|
+
"(#{arguments}) -> #{returns}",
|
34
|
+
"(#{@include_required ? "" : "?"}Hash[Symbol, untyped]) -> #{returns}"
|
35
|
+
]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class Waiter < Struct.new(
|
6
|
+
:name,
|
7
|
+
:class_name,
|
8
|
+
:client_overload_keyword_argument,
|
9
|
+
:client_overload_positional_argument,
|
10
|
+
:waiter_overload_keyword_argument,
|
11
|
+
:waiter_overload_positional_argument,
|
12
|
+
keyword_init: true
|
13
|
+
)
|
14
|
+
class << self
|
15
|
+
def build_list(api:, waiters:)
|
16
|
+
operations = api.fetch("operations")
|
17
|
+
waiters =
|
18
|
+
if waiters&.first
|
19
|
+
waiters["waiters"]
|
20
|
+
else
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
waiters.map do |waiter_name, waiter|
|
24
|
+
operation = waiter.fetch("operation")
|
25
|
+
operation_ref = operations[operation]
|
26
|
+
input_shape = operation_ref.dig("input", "shape")
|
27
|
+
include_required = api["shapes"][input_shape]&.[]("required")&.empty?&.!
|
28
|
+
|
29
|
+
name = ":#{Underscore.underscore(waiter_name)}"
|
30
|
+
shapes = api.fetch("shapes")
|
31
|
+
input_shape_ref = shapes[input_shape]
|
32
|
+
params = AwsSdkCodeGenerator::RBS::KeywordArgumentBuilder.new(
|
33
|
+
api: api,
|
34
|
+
shape: input_shape_ref,
|
35
|
+
newline: true,
|
36
|
+
).format(indent: ' ' * 18)
|
37
|
+
returns = operation_ref.dig("output", "shape") ? "Client::_#{operation}ResponseSuccess" : "::Seahorse::Client::_ResponseSuccess[::Aws::EmptyStructure]"
|
38
|
+
prefix = include_required ? "" : "?"
|
39
|
+
|
40
|
+
new.tap do |w|
|
41
|
+
w.name = name
|
42
|
+
w.class_name = waiter_name
|
43
|
+
w.client_overload_keyword_argument = "(#{name} waiter_name, #{params}) -> #{returns}"
|
44
|
+
w.client_overload_positional_argument = "(#{name} waiter_name, #{prefix}Hash[Symbol, untyped] params, ?Hash[Symbol, untyped] options) -> #{returns}"
|
45
|
+
w.waiter_overload_keyword_argument = "(#{params}) -> #{returns}"
|
46
|
+
w.waiter_overload_positional_argument = "(#{prefix}Hash[Symbol, untyped]) -> #{returns}"
|
47
|
+
end
|
48
|
+
end.sort_by(&:name)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class << self
|
6
|
+
def to_type(shape_ref, api)
|
7
|
+
_, shape = Api.resolve(shape_ref, api)
|
8
|
+
case shape['type']
|
9
|
+
when 'blob' then Api.streaming?(shape_ref, api) ? '::IO' : '::String'
|
10
|
+
when 'boolean' then 'bool'
|
11
|
+
when 'byte' then '::Integer'
|
12
|
+
when 'character' then '::String'
|
13
|
+
when 'double' then '::Float'
|
14
|
+
when 'float' then '::Float'
|
15
|
+
when 'integer' then '::Integer'
|
16
|
+
when 'list' then "::Array[#{to_type(shape['member'], api)}]"
|
17
|
+
when 'long' then '::Integer'
|
18
|
+
when 'map' then "::Hash[#{to_type(shape['key'], api)}, #{to_type(shape['value'], api)}]"
|
19
|
+
when 'string'
|
20
|
+
if shape['enum']
|
21
|
+
"(#{shape['enum'].map { |e| "\"#{e}\"" }.join(" | ")})"
|
22
|
+
elsif Api.streaming?(shape_ref, api)
|
23
|
+
'::IO'
|
24
|
+
else
|
25
|
+
'::String'
|
26
|
+
end
|
27
|
+
when 'structure'
|
28
|
+
if shape['document']
|
29
|
+
'untyped'
|
30
|
+
else
|
31
|
+
"Types::#{shape_ref['shape']}"
|
32
|
+
end
|
33
|
+
when 'timestamp' then '::Time'
|
34
|
+
else
|
35
|
+
raise "unhandled type #{shape['type'].inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -15,7 +15,9 @@ module AwsSdkCodeGenerator
|
|
15
15
|
parts << 'batch_enum.each do |batch|'
|
16
16
|
parts << initialize_params
|
17
17
|
parts << apply_params_per_batch
|
18
|
-
parts << "
|
18
|
+
parts << " Aws::Plugins::UserAgent.feature('resource') do"
|
19
|
+
parts << " batch[0].client.#{client_method}(params)"
|
20
|
+
parts << ' end'
|
19
21
|
parts << 'end'
|
20
22
|
parts << 'nil'
|
21
23
|
parts.join("\n").rstrip
|
@@ -15,9 +15,11 @@ module AwsSdkCodeGenerator
|
|
15
15
|
parts = []
|
16
16
|
parts << request_options(params) if merge
|
17
17
|
parts << assignment(options)
|
18
|
-
parts << "
|
18
|
+
parts << "Aws::Plugins::UserAgent.feature('resource') do\n"
|
19
|
+
parts << " @client."
|
19
20
|
parts << operation_name(request)
|
20
21
|
parts << arguments(merge, params, streaming)
|
22
|
+
parts << "\nend"
|
21
23
|
parts.join
|
22
24
|
end
|
23
25
|
|
@@ -52,11 +52,12 @@ module AwsSdkCodeGenerator
|
|
52
52
|
args = ResourceClientRequestParams.new(
|
53
53
|
params: waiter['params']
|
54
54
|
).to_s.strip
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
parts = []
|
56
|
+
parts << 'resp = ' if waiter['path']
|
57
|
+
parts << "Aws::Plugins::UserAgent.feature('resource') do\n"
|
58
|
+
parts << " waiter.wait(params.merge(#{args}))"
|
59
|
+
parts << "\nend"
|
60
|
+
parts.join
|
60
61
|
end
|
61
62
|
|
62
63
|
def constructor_args(resource, waiter)
|
@@ -20,6 +20,7 @@ module AwsSdkCodeGenerator
|
|
20
20
|
# @option options [Hash<gem,version>] :gem_dependencies ({})
|
21
21
|
# @option options [Hash] :add_plugins ({})
|
22
22
|
# @option options [Hash] :remove_plugins ([])
|
23
|
+
# @option options [Boolean] :deprecated (false)
|
23
24
|
def initialize(options)
|
24
25
|
@name = options.fetch(:name)
|
25
26
|
@identifier = name.downcase
|
@@ -57,6 +58,7 @@ module AwsSdkCodeGenerator
|
|
57
58
|
@require_endpoint_discovery = api.fetch('operations', []).any? do |_, o|
|
58
59
|
o['endpointdiscovery'] && o['endpointdiscovery']['required']
|
59
60
|
end
|
61
|
+
@deprecated = options[:deprecated] || false
|
60
62
|
end
|
61
63
|
|
62
64
|
# @return [String] The service name, e.g. "S3"
|
@@ -146,6 +148,25 @@ module AwsSdkCodeGenerator
|
|
146
148
|
# @return [Boolean] true if any operation requires endpoint_discovery
|
147
149
|
attr_reader :require_endpoint_discovery
|
148
150
|
|
151
|
+
# @return [String] the service_id
|
152
|
+
def service_id
|
153
|
+
metadata = @api['metadata']
|
154
|
+
return metadata['serviceId'] if metadata['serviceId']
|
155
|
+
|
156
|
+
name = metadata['serviceAbbreviation'] || metadata['serviceFullName']
|
157
|
+
name = name.gsub(/AWS/, '').gsub(/Amazon/, '')
|
158
|
+
name = name.gsub(/[^a-zA-Z0-9 ]+/, '')
|
159
|
+
name = name.gsub(/^[0-9]+/, '')
|
160
|
+
name = name.strip
|
161
|
+
|
162
|
+
name
|
163
|
+
end
|
164
|
+
|
165
|
+
# @return [Boolean] true if the service is deprecated
|
166
|
+
def deprecated?
|
167
|
+
@deprecated
|
168
|
+
end
|
169
|
+
|
149
170
|
# @api private
|
150
171
|
def inspect
|
151
172
|
"#<#{self.class.name}>"
|
@@ -24,10 +24,14 @@ module AwsSdkCodeGenerator
|
|
24
24
|
@gem_version = options.fetch(:gem_version)
|
25
25
|
@plugins = PluginList.new(options)
|
26
26
|
@codegenerated_plugins = options.fetch(:codegenerated_plugins, [])
|
27
|
+
@default_plugins = Seahorse::Client::AsyncBase.plugins.map do |plugin|
|
28
|
+
PluginList::Plugin.new(class_name: plugin.name, options: plugin.options, path: '')
|
29
|
+
end
|
27
30
|
@client_constructor = ClientConstructor.new(
|
28
31
|
options.merge(
|
29
32
|
plugins: @plugins,
|
30
|
-
codegenerated_plugins: @codegenerated_plugins
|
33
|
+
codegenerated_plugins: @codegenerated_plugins,
|
34
|
+
default_plugins: @default_plugins))
|
31
35
|
@operations = ClientOperationList.new(options).to_a
|
32
36
|
end
|
33
37
|
|
@@ -34,6 +34,8 @@ module AwsSdkCodeGenerator
|
|
34
34
|
'union' => false, # should remain false
|
35
35
|
'document' => true,
|
36
36
|
'jsonvalue' => true,
|
37
|
+
'error' => true, # parsing customized error code in query protocol
|
38
|
+
'locationName' => true, # to recognize xmlName defined on shape
|
37
39
|
# event stream modeling
|
38
40
|
'event' => false,
|
39
41
|
'eventstream' => false,
|
@@ -43,7 +45,7 @@ module AwsSdkCodeGenerator
|
|
43
45
|
'synthetic' => false,
|
44
46
|
'box' => false,
|
45
47
|
'fault' => false,
|
46
|
-
'
|
48
|
+
'exception_event' => false, # internal, exceptions cannot be events
|
47
49
|
'deprecated' => false,
|
48
50
|
'deprecatedMessage' => false,
|
49
51
|
'type' => false,
|
@@ -51,7 +53,6 @@ module AwsSdkCodeGenerator
|
|
51
53
|
'members' => false,
|
52
54
|
'member' => false,
|
53
55
|
'key' => false,
|
54
|
-
'locationName' => false,
|
55
56
|
'value' => false,
|
56
57
|
'required' => false,
|
57
58
|
'enum' => false,
|
@@ -70,9 +71,11 @@ module AwsSdkCodeGenerator
|
|
70
71
|
# keep all
|
71
72
|
'endpointPrefix' => true,
|
72
73
|
'signatureVersion' => true,
|
74
|
+
'auth' => true,
|
73
75
|
'signingName' => true,
|
74
76
|
'serviceFullName' => true,
|
75
77
|
'protocol' => true,
|
78
|
+
'protocols' => true,
|
76
79
|
'targetPrefix' => true,
|
77
80
|
'jsonVersion' => true,
|
78
81
|
'errorPrefix' => true,
|
@@ -98,6 +101,7 @@ module AwsSdkCodeGenerator
|
|
98
101
|
# @return [String|nil]
|
99
102
|
def generated_src_warning
|
100
103
|
return if @service.protocol == 'api-gateway'
|
104
|
+
|
101
105
|
GENERATED_SRC_WARNING
|
102
106
|
end
|
103
107
|
|
@@ -204,12 +208,18 @@ module AwsSdkCodeGenerator
|
|
204
208
|
if operation.key?('httpChecksum')
|
205
209
|
operation['httpChecksum']['requestAlgorithmMember'] = underscore(operation['httpChecksum']['requestAlgorithmMember']) if operation['httpChecksum']['requestAlgorithmMember']
|
206
210
|
operation['httpChecksum']['requestValidationModeMember'] = underscore(operation['httpChecksum']['requestValidationModeMember']) if operation['httpChecksum']['requestValidationModeMember']
|
207
|
-
|
208
211
|
o.http_checksum = operation['httpChecksum'].inject([]) do |a, (k, v)|
|
209
212
|
a << { key: k.inspect, value: v.inspect }
|
210
213
|
a
|
211
214
|
end
|
212
215
|
end
|
216
|
+
|
217
|
+
if operation.key?('requestcompression')
|
218
|
+
o.request_compression = operation['requestcompression'].each_with_object([]) do |(k, v), arr|
|
219
|
+
arr << { key: k.inspect, value: v.inspect }
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
213
223
|
%w(input output).each do |key|
|
214
224
|
if operation[key]
|
215
225
|
o.shape_references << "o.#{key} = #{operation_ref(operation[key])}"
|
@@ -250,6 +260,7 @@ module AwsSdkCodeGenerator
|
|
250
260
|
|
251
261
|
def apig_authorizer
|
252
262
|
return nil unless @service.api.key? 'authorizers'
|
263
|
+
|
253
264
|
@service.api['authorizers'].map do |name, authorizer|
|
254
265
|
Authorizer.new.tap do |a|
|
255
266
|
a.name = name
|
@@ -298,6 +309,9 @@ module AwsSdkCodeGenerator
|
|
298
309
|
args << "name: '#{shape_name}'"
|
299
310
|
shape.each_pair do |key, value|
|
300
311
|
if SHAPE_KEYS[key]
|
312
|
+
# only query protocols have custom error code
|
313
|
+
next if @service.protocol != 'query' && key == 'error'
|
314
|
+
|
301
315
|
args << "#{key}: #{value.inspect}"
|
302
316
|
elsif SHAPE_KEYS[key].nil?
|
303
317
|
raise "unhandled shape key #{key.inspect}"
|
@@ -491,8 +505,16 @@ module AwsSdkCodeGenerator
|
|
491
505
|
options = {}
|
492
506
|
metadata.each_pair do |key, value|
|
493
507
|
next if key == 'resultWrapper'
|
508
|
+
|
494
509
|
if key == 'locationName'
|
495
|
-
options[:location_name] =
|
510
|
+
options[:location_name] =
|
511
|
+
# use the xmlName on shape if defined
|
512
|
+
if (@service.protocol == 'rest-xml') &&
|
513
|
+
(shape_location_name = @service.api['shapes'][shape_name]['locationName'])
|
514
|
+
shape_location_name.inspect
|
515
|
+
else
|
516
|
+
value.inspect
|
517
|
+
end
|
496
518
|
else
|
497
519
|
options[:metadata] ||= {}
|
498
520
|
options[:metadata][key] = value.inspect
|
@@ -551,6 +573,9 @@ module AwsSdkCodeGenerator
|
|
551
573
|
# @return [Hash]
|
552
574
|
attr_accessor :http_checksum
|
553
575
|
|
576
|
+
# @return [Hash]
|
577
|
+
attr_accessor :request_compression
|
578
|
+
|
554
579
|
# @return [Array<String>]
|
555
580
|
attr_accessor :shape_references
|
556
581
|
|
@@ -27,10 +27,14 @@ module AwsSdkCodeGenerator
|
|
27
27
|
@gem_version = options.fetch(:gem_version)
|
28
28
|
@plugins = PluginList.new(options)
|
29
29
|
@codegenerated_plugins = options.fetch(:codegenerated_plugins, [])
|
30
|
+
@default_plugins = Seahorse::Client::Base.plugins.map do |plugin|
|
31
|
+
PluginList::Plugin.new(class_name: plugin.name, options: plugin.options, path: '')
|
32
|
+
end
|
30
33
|
@client_constructor = ClientConstructor.new(
|
31
34
|
options.merge(
|
32
35
|
plugins: @plugins,
|
33
|
-
codegenerated_plugins: @codegenerated_plugins
|
36
|
+
codegenerated_plugins: @codegenerated_plugins,
|
37
|
+
default_plugins: @default_plugins))
|
34
38
|
@operations = ClientOperationList.new(options).to_a
|
35
39
|
@waiters = Waiter.build_list(options[:waiters])
|
36
40
|
@custom = options.fetch(:custom)
|
@@ -26,8 +26,227 @@ module AwsSdkCodeGenerator
|
|
26
26
|
@service.module_name
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
29
|
+
def endpoint_rules_code
|
30
|
+
res = StringIO.new
|
31
|
+
# map parameters first
|
32
|
+
@endpoint_rules["parameters"].each do |k,_v|
|
33
|
+
res << indent("#{underscore(k)} = parameters.#{underscore(k)}\n", 3)
|
34
|
+
end
|
35
|
+
|
36
|
+
# map rules
|
37
|
+
@endpoint_rules["rules"].each do |rule|
|
38
|
+
case rule["type"]
|
39
|
+
when "endpoint"
|
40
|
+
res << endpoint_rule(rule, 3)
|
41
|
+
when "error"
|
42
|
+
res << error_rule(rule, 3)
|
43
|
+
when "tree"
|
44
|
+
res << tree_rule(rule, 3)
|
45
|
+
else
|
46
|
+
raise "Unknown rule type: #{rule['type']}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# if no rules match, raise an error
|
51
|
+
res << indent("raise ArgumentError, 'No endpoint could be resolved'\n", 3)
|
52
|
+
|
53
|
+
res.string
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def endpoint_rule(rule, levels=3)
|
59
|
+
res = StringIO.new
|
60
|
+
if rule['conditions'] && !rule['conditions'].empty?
|
61
|
+
res << conditions(rule['conditions'], levels)
|
62
|
+
res << endpoint(rule['endpoint'], levels+1)
|
63
|
+
res << indent("end\n", levels)
|
64
|
+
else
|
65
|
+
res << endpoint(rule['endpoint'], levels)
|
66
|
+
end
|
67
|
+
res.string
|
68
|
+
end
|
69
|
+
|
70
|
+
def endpoint(endpoint, levels)
|
71
|
+
res = StringIO.new
|
72
|
+
res << "return Aws::Endpoints::Endpoint.new(url: #{str(endpoint['url'])}"
|
73
|
+
if endpoint['headers']
|
74
|
+
res << ", headers: #{templated_hash_to_s(endpoint['headers'])}"
|
75
|
+
end
|
76
|
+
if endpoint['properties']
|
77
|
+
res << ", properties: #{templated_hash_to_s(endpoint['properties'])}"
|
78
|
+
end
|
79
|
+
res << ")\n"
|
80
|
+
indent(res.string, levels)
|
81
|
+
end
|
82
|
+
|
83
|
+
def templated_hash_to_s(hash)
|
84
|
+
template_hash_values(hash).to_s.gsub('\#{', '#{') # unescape references
|
85
|
+
end
|
86
|
+
|
87
|
+
def template_hash_values(hash)
|
88
|
+
hash.inject({}) { |h, (k, v)| h[k] = template_hash_value(v); h }
|
89
|
+
end
|
90
|
+
|
91
|
+
def template_hash_value(value)
|
92
|
+
case value
|
93
|
+
when Hash
|
94
|
+
template_hash_values(value)
|
95
|
+
when Array
|
96
|
+
value.map { |v| template_hash_value(v) }
|
97
|
+
when String
|
98
|
+
template_str(value, false)
|
99
|
+
else
|
100
|
+
value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def error_rule(rule, levels=3)
|
105
|
+
res = StringIO.new
|
106
|
+
if rule['conditions'] && !rule['conditions'].empty?
|
107
|
+
res << conditions(rule['conditions'], levels)
|
108
|
+
res << error(rule['error'], levels+1)
|
109
|
+
res << indent("end\n", levels)
|
110
|
+
else
|
111
|
+
res << error(rule['error'], levels)
|
112
|
+
end
|
113
|
+
res.string
|
114
|
+
end
|
115
|
+
|
116
|
+
def error(error, levels)
|
117
|
+
indent("raise ArgumentError, #{str(error)}\n", levels)
|
118
|
+
end
|
119
|
+
|
120
|
+
def tree_rule(rule, levels=3)
|
121
|
+
res = StringIO.new
|
122
|
+
if rule['conditions'] && !rule['conditions'].empty?
|
123
|
+
res << conditions(rule['conditions'], levels)
|
124
|
+
res << tree_rules(rule['rules'], levels+1)
|
125
|
+
res << indent("end\n", levels)
|
126
|
+
else
|
127
|
+
res << tree_rules(rule['rules'], levels)
|
128
|
+
end
|
129
|
+
res.string
|
130
|
+
end
|
131
|
+
|
132
|
+
def tree_rules(rules, levels)
|
133
|
+
res = StringIO.new
|
134
|
+
rules.each do |rule|
|
135
|
+
case rule["type"]
|
136
|
+
when "endpoint"
|
137
|
+
res << endpoint_rule(rule, levels)
|
138
|
+
when "error"
|
139
|
+
res << error_rule(rule, levels)
|
140
|
+
when "tree"
|
141
|
+
res << tree_rule(rule, levels)
|
142
|
+
else
|
143
|
+
raise "Unknown rule type: #{rule['type']}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
res.string
|
147
|
+
end
|
148
|
+
|
149
|
+
def conditions(conditions, level)
|
150
|
+
res = StringIO.new
|
151
|
+
cnd_str = conditions.map { |c| condition(c) }.join(" && ")
|
152
|
+
res << indent("if #{cnd_str}\n", level)
|
153
|
+
res.string
|
154
|
+
end
|
155
|
+
|
156
|
+
def condition(condition)
|
157
|
+
if condition['assign']
|
158
|
+
"(#{underscore(condition['assign'])} = #{fn(condition)})"
|
159
|
+
else
|
160
|
+
fn(condition)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def str(s)
|
165
|
+
if s.is_a?(Hash)
|
166
|
+
if s['ref']
|
167
|
+
underscore(s['ref'])
|
168
|
+
elsif s['fn']
|
169
|
+
fn(s)
|
170
|
+
else
|
171
|
+
raise "Unknown string type: #{s}"
|
172
|
+
end
|
173
|
+
else
|
174
|
+
template_str(s)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def template_str(string, wrap=true)
|
179
|
+
string.scan(/\{.+?\}/).each do |capture|
|
180
|
+
value = capture[1..-2] # strips curly brackets
|
181
|
+
string = string.gsub(capture, '#{' + template_replace(value) + '}')
|
182
|
+
end
|
183
|
+
string = string.gsub('"', '\"')
|
184
|
+
wrap ? "\"#{string}\"" : string
|
185
|
+
end
|
186
|
+
|
187
|
+
def template_replace(value)
|
188
|
+
indexes = value.split("#")
|
189
|
+
res = underscore(indexes.shift)
|
190
|
+
res += indexes.map do |index|
|
191
|
+
"['#{index}']"
|
192
|
+
end.join("")
|
193
|
+
res
|
194
|
+
end
|
195
|
+
|
196
|
+
def fn(fn)
|
197
|
+
args = fn['argv'].map {|arg| fn_arg(arg)}.join(", ")
|
198
|
+
"#{fn_name(fn['fn'])}(#{args})"
|
199
|
+
end
|
200
|
+
|
201
|
+
def fn_arg(arg)
|
202
|
+
if arg.is_a?(Hash)
|
203
|
+
if arg['ref']
|
204
|
+
underscore(arg['ref'])
|
205
|
+
elsif arg['fn']
|
206
|
+
fn(arg)
|
207
|
+
else
|
208
|
+
raise "Unexpected argument type: #{arg}"
|
209
|
+
end
|
210
|
+
elsif arg.is_a?(String)
|
211
|
+
template_str(arg)
|
212
|
+
else
|
213
|
+
arg
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def fn_name(fn)
|
218
|
+
case fn
|
219
|
+
when 'isSet'
|
220
|
+
"Aws::Endpoints::Matchers.set?"
|
221
|
+
when 'not'
|
222
|
+
"Aws::Endpoints::Matchers.not"
|
223
|
+
when 'getAttr'
|
224
|
+
"Aws::Endpoints::Matchers.attr"
|
225
|
+
when 'substring'
|
226
|
+
"Aws::Endpoints::Matchers.substring"
|
227
|
+
when 'stringEquals'
|
228
|
+
"Aws::Endpoints::Matchers.string_equals?"
|
229
|
+
when 'booleanEquals'
|
230
|
+
"Aws::Endpoints::Matchers.boolean_equals?"
|
231
|
+
when 'uriEncode'
|
232
|
+
"Aws::Endpoints::Matchers.uri_encode"
|
233
|
+
when 'parseURL'
|
234
|
+
"Aws::Endpoints::Matchers.parse_url"
|
235
|
+
when 'isValidHostLabel'
|
236
|
+
"Aws::Endpoints::Matchers.valid_host_label?"
|
237
|
+
when 'aws.partition'
|
238
|
+
"Aws::Endpoints::Matchers.aws_partition"
|
239
|
+
when 'aws.parseArn'
|
240
|
+
"Aws::Endpoints::Matchers.aws_parse_arn"
|
241
|
+
when 'aws.isVirtualHostableS3Bucket'
|
242
|
+
"Aws::Endpoints::Matchers.aws_virtual_hostable_s3_bucket?"
|
243
|
+
else
|
244
|
+
raise "Function not found: #{@fn}"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def indent(s, levels=3)
|
249
|
+
(" " * levels) + s
|
31
250
|
end
|
32
251
|
end
|
33
252
|
end
|
@@ -99,9 +99,15 @@ module AwsSdkCodeGenerator
|
|
99
99
|
).to_s
|
100
100
|
end
|
101
101
|
param_hash_str = Docstring.join_docstrings([option_tags], block_comment: false)
|
102
|
+
param_hash =
|
103
|
+
if param_hash_str.nil?
|
104
|
+
'# This event has no members'
|
105
|
+
else
|
106
|
+
Docstring.indent(param_hash_str, ' ')
|
107
|
+
end
|
102
108
|
m << EventEntry.new(
|
103
109
|
name: underscore(n),
|
104
|
-
param_hash:
|
110
|
+
param_hash: param_hash
|
105
111
|
)
|
106
112
|
m
|
107
113
|
end
|