aws-sdk-code-generator 0.1.0.pre → 0.2.4.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +5 -5
  2. data/lib/aws-sdk-code-generator/api.rb +150 -0
  3. data/lib/aws-sdk-code-generator/apply_docs.rb +15 -2
  4. data/lib/aws-sdk-code-generator/client_constructor.rb +39 -0
  5. data/lib/aws-sdk-code-generator/client_operation_documentation.rb +282 -0
  6. data/lib/aws-sdk-code-generator/client_operation_list.rb +148 -0
  7. data/lib/aws-sdk-code-generator/client_response_structure_example.rb +115 -0
  8. data/lib/aws-sdk-code-generator/code_builder.rb +146 -133
  9. data/lib/aws-sdk-code-generator/crosslink.rb +42 -0
  10. data/lib/aws-sdk-code-generator/docstring.rb +199 -0
  11. data/lib/aws-sdk-code-generator/error_list.rb +77 -0
  12. data/lib/aws-sdk-code-generator/errors.rb +2 -0
  13. data/lib/aws-sdk-code-generator/eventstream_example.rb +220 -0
  14. data/lib/aws-sdk-code-generator/gem_builder.rb +42 -25
  15. data/lib/aws-sdk-code-generator/hash_formatter.rb +5 -2
  16. data/lib/aws-sdk-code-generator/helper.rb +86 -119
  17. data/lib/aws-sdk-code-generator/plugin_list.rb +147 -0
  18. data/lib/aws-sdk-code-generator/resource_action.rb +69 -0
  19. data/lib/aws-sdk-code-generator/resource_action_code.rb +57 -0
  20. data/lib/aws-sdk-code-generator/resource_association.rb +37 -0
  21. data/lib/aws-sdk-code-generator/resource_attribute.rb +76 -0
  22. data/lib/aws-sdk-code-generator/resource_batch_action.rb +56 -0
  23. data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +136 -0
  24. data/lib/aws-sdk-code-generator/resource_batch_action_documentation.rb +108 -0
  25. data/lib/aws-sdk-code-generator/resource_batch_builder.rb +212 -0
  26. data/lib/aws-sdk-code-generator/resource_builder.rb +48 -0
  27. data/lib/aws-sdk-code-generator/resource_client_request.rb +62 -0
  28. data/lib/aws-sdk-code-generator/resource_client_request_documentation.rb +81 -0
  29. data/lib/aws-sdk-code-generator/resource_client_request_params.rb +86 -0
  30. data/lib/aws-sdk-code-generator/resource_data_method.rb +60 -0
  31. data/lib/aws-sdk-code-generator/resource_has_association.rb +117 -0
  32. data/lib/aws-sdk-code-generator/resource_has_many_association.rb +52 -0
  33. data/lib/aws-sdk-code-generator/resource_has_many_association_code.rb +76 -0
  34. data/lib/aws-sdk-code-generator/resource_identifier.rb +44 -0
  35. data/lib/aws-sdk-code-generator/resource_identifiers_method.rb +29 -0
  36. data/lib/aws-sdk-code-generator/resource_load_method.rb +68 -0
  37. data/lib/aws-sdk-code-generator/resource_method.rb +22 -0
  38. data/lib/aws-sdk-code-generator/resource_skip_params.rb +36 -0
  39. data/lib/aws-sdk-code-generator/resource_value_source.rb +68 -0
  40. data/lib/aws-sdk-code-generator/resource_waiter.rb +80 -0
  41. data/lib/aws-sdk-code-generator/service.rb +30 -7
  42. data/lib/aws-sdk-code-generator/shared_example.rb +131 -0
  43. data/lib/aws-sdk-code-generator/syntax_example.rb +60 -0
  44. data/lib/aws-sdk-code-generator/syntax_example_hash.rb +174 -0
  45. data/lib/aws-sdk-code-generator/underscore.rb +10 -5
  46. data/lib/aws-sdk-code-generator/view.rb +33 -0
  47. data/lib/aws-sdk-code-generator/views/apig_endpoint_class.rb +25 -0
  48. data/lib/aws-sdk-code-generator/views/apig_readme.rb +32 -0
  49. data/lib/aws-sdk-code-generator/views/async_client_class.rb +68 -0
  50. data/lib/aws-sdk-code-generator/views/authorizer_class.rb +17 -0
  51. data/lib/aws-sdk-code-generator/views/client_api_module.rb +602 -0
  52. data/lib/aws-sdk-code-generator/views/client_class.rb +93 -0
  53. data/lib/aws-sdk-code-generator/views/docstring.rb +27 -0
  54. data/lib/aws-sdk-code-generator/views/errors_module.rb +32 -0
  55. data/lib/aws-sdk-code-generator/views/event_streams_module.rb +149 -0
  56. data/lib/aws-sdk-code-generator/views/features/env.rb +9 -0
  57. data/lib/aws-sdk-code-generator/views/features/smoke.rb +52 -0
  58. data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +26 -0
  59. data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +6 -2
  60. data/lib/aws-sdk-code-generator/views/gemspec.rb +39 -5
  61. data/lib/aws-sdk-code-generator/views/resource_class.rb +122 -0
  62. data/lib/aws-sdk-code-generator/views/root_resource_class.rb +58 -0
  63. data/lib/aws-sdk-code-generator/views/service_module.rb +38 -14
  64. data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +9 -0
  65. data/lib/aws-sdk-code-generator/views/types_module.rb +329 -0
  66. data/lib/aws-sdk-code-generator/views/version.rb +2 -0
  67. data/lib/aws-sdk-code-generator/views/waiters_module.rb +37 -0
  68. data/lib/aws-sdk-code-generator/views.rb +2 -0
  69. data/lib/aws-sdk-code-generator/waiter.rb +95 -0
  70. data/lib/aws-sdk-code-generator/yard_option_tag.rb +43 -0
  71. data/lib/aws-sdk-code-generator.rb +68 -75
  72. data/templates/apig_endpoint_class.mustache +16 -0
  73. data/templates/apig_readme.mustache +62 -0
  74. data/templates/async_client_class.mustache +125 -0
  75. data/templates/authorizer_class.mustache +37 -0
  76. data/templates/client_api_module.mustache +106 -0
  77. data/templates/client_class.mustache +295 -0
  78. data/templates/code.mustache +4 -0
  79. data/templates/documentation.mustache +4 -0
  80. data/templates/errors_module.mustache +70 -0
  81. data/templates/event_streams_module.mustache +76 -0
  82. data/templates/features/env.mustache +15 -0
  83. data/templates/features/smoke.mustache +22 -0
  84. data/templates/features/smoke_step_definitions.mustache +31 -0
  85. data/templates/features/step_definitions.mustache +13 -0
  86. data/templates/gemspec.mustache +31 -0
  87. data/templates/license.txt +202 -0
  88. data/templates/method.mustache +7 -0
  89. data/templates/resource_class.mustache +304 -0
  90. data/templates/root_resource_class.mustache +51 -0
  91. data/templates/service_module.mustache +58 -0
  92. data/templates/spec/spec_helper.mustache +15 -0
  93. data/templates/types_module.mustache +53 -0
  94. data/templates/version.mustache +1 -0
  95. data/templates/waiters_module.mustache +112 -0
  96. metadata +115 -70
  97. data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +0 -23
  98. data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +0 -43
  99. data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +0 -11
  100. data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +0 -11
  101. data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +0 -15
  102. data/lib/aws-sdk-code-generator/dsl/block_param.rb +0 -11
  103. data/lib/aws-sdk-code-generator/dsl/class.rb +0 -27
  104. data/lib/aws-sdk-code-generator/dsl/code_literal.rb +0 -66
  105. data/lib/aws-sdk-code-generator/dsl/code_object.rb +0 -33
  106. data/lib/aws-sdk-code-generator/dsl/docstring.rb +0 -36
  107. data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +0 -15
  108. data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +0 -12
  109. data/lib/aws-sdk-code-generator/dsl/formatter.rb +0 -25
  110. data/lib/aws-sdk-code-generator/dsl/include_statement.rb +0 -17
  111. data/lib/aws-sdk-code-generator/dsl/main.rb +0 -105
  112. data/lib/aws-sdk-code-generator/dsl/method.rb +0 -108
  113. data/lib/aws-sdk-code-generator/dsl/module.rb +0 -167
  114. data/lib/aws-sdk-code-generator/dsl/option_tag.rb +0 -36
  115. data/lib/aws-sdk-code-generator/dsl/param.rb +0 -43
  116. data/lib/aws-sdk-code-generator/dsl/param_list.rb +0 -38
  117. data/lib/aws-sdk-code-generator/dsl/return_tag.rb +0 -19
  118. data/lib/aws-sdk-code-generator/dsl/tag_default.rb +0 -20
  119. data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +0 -27
  120. data/lib/aws-sdk-code-generator/dsl/tag_type.rb +0 -18
  121. data/lib/aws-sdk-code-generator/generators/client_api_module.rb +0 -334
  122. data/lib/aws-sdk-code-generator/generators/client_class.rb +0 -389
  123. data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +0 -166
  124. data/lib/aws-sdk-code-generator/generators/errors_module.rb +0 -25
  125. data/lib/aws-sdk-code-generator/generators/resource/action.rb +0 -88
  126. data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +0 -211
  127. data/lib/aws-sdk-code-generator/generators/resource/builder.rb +0 -50
  128. data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +0 -15
  129. data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +0 -49
  130. data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +0 -97
  131. data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +0 -88
  132. data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +0 -180
  133. data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +0 -24
  134. data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +0 -18
  135. data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +0 -49
  136. data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +0 -29
  137. data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +0 -32
  138. data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +0 -101
  139. data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +0 -108
  140. data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +0 -26
  141. data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +0 -28
  142. data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +0 -67
  143. data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +0 -65
  144. data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +0 -68
  145. data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +0 -61
  146. data/lib/aws-sdk-code-generator/generators/resource_class.rb +0 -325
  147. data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +0 -83
  148. data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +0 -42
  149. data/lib/aws-sdk-code-generator/generators/service_documentation.rb +0 -64
  150. data/lib/aws-sdk-code-generator/generators/shared_example.rb +0 -132
  151. data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +0 -95
  152. data/lib/aws-sdk-code-generator/generators/syntax_example.rb +0 -169
  153. data/lib/aws-sdk-code-generator/generators/types_module.rb +0 -52
  154. data/lib/aws-sdk-code-generator/generators/waiter_class.rb +0 -62
  155. data/lib/aws-sdk-code-generator/generators/waiters_module.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cd7b6eb0cfae166558e734fdb8e7c9236f7f14d6
4
- data.tar.gz: 8cad3f3e2213a13d558259216831b08e1e4d5323
2
+ SHA256:
3
+ metadata.gz: 0cd62265104fa228849cca4ee26d749025e7ba94a0ff446885abc045a17a91cf
4
+ data.tar.gz: 537442139442f772fecb3e829a9a584a07bf6795757c01b90032f78c5b4fde99
5
5
  SHA512:
6
- metadata.gz: c970544cd6c87e3794260f4dda931f717c9e7ef9dfb43693b35c0d22f0a3b1ec850b3ff281b7e9e825591905a2a45b19168337521c8039c2e648db3e66b1d525
7
- data.tar.gz: 6a927656fc80f7df13cc27c03f1675a81fb3f000bcec4b6fb3ba6d672ad1e37a74296ccaff8b37137e3ce4912780bf1a1818f4b7c03e13ca3b8781f9a7375ade
6
+ metadata.gz: 7dd69754c3ad489c192c4db3986fc79376dbd34316f5d6d79694e5807824d36de9333762d49727a4e92525bbea4b0190803474641282499e116afd7955d6a162
7
+ data.tar.gz: a44c6a9fd0a8778bbe4d00c73dcc07584b1beac9c278671f006c349c7e7f0a36d6e8fa18084ebd61984769496abde3faf9037b85d09e40ce7c86d9f823030923
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module Api
5
+ class << self
6
+
7
+ # @param [Hash, String] shape_or_shape_ref
8
+ # @param [Hash, String] api
9
+ # @return [String, nil]
10
+ def docstring(shape_or_shape_ref, api)
11
+ ref, shape = resolve(shape_or_shape_ref, api)
12
+ # APIG models, downcase shape name in origin or "__" prefix in origin
13
+ # code-gen shape name might have been changed (upcased_first/lstrip_prefix/both),
14
+ # when shape cannot be located with current shape name, try to resolve shape with
15
+ # (downcase_fist/apig_prefix/both) original names
16
+ if shape.nil?
17
+ ref, shape = resolve(AwsSdkCodeGenerator::Helper.downcase_first(shape_or_shape_ref), api)
18
+ if shape.nil?
19
+ ref, shape = resolve(AwsSdkCodeGenerator::Helper.apig_prefix(shape_or_shape_ref), api)
20
+ if shape.nil?
21
+ ref, shape = resolve(AwsSdkCodeGenerator::Helper.apig_prefix(downcase_first(shape_or_shape_ref)), api)
22
+ end
23
+ end
24
+ end
25
+ ref['documentation'] || shape['documentation']
26
+ end
27
+
28
+ # @param [Hash, String] shape_or_shape_ref
29
+ # @param [Hash, String] api
30
+ # @return [Hash<ShapeRef>, Hash<Shape>]
31
+ def resolve(shape_or_shape_ref, api)
32
+ if String === shape_or_shape_ref
33
+ [{}, api['shapes'][shape_or_shape_ref]]
34
+ elsif shape_or_shape_ref['type']
35
+ [{}, shape_or_shape_ref]
36
+ else
37
+ [shape_or_shape_ref, api['shapes'][shape_or_shape_ref['shape']]]
38
+ end
39
+ end
40
+
41
+ # @param [String, Hash] shape_name_or_ref
42
+ # @return [Hash]
43
+ def shape(shape_name_or_ref, api)
44
+ case shape_name_or_ref
45
+ when Hash then api.fetch('shapes').fetch(shape_name_or_ref.fetch('shape'))
46
+ when String then api.fetch('shapes').fetch(shape_name_or_ref)
47
+ end
48
+ end
49
+
50
+ def ruby_input_type(shape_ref, api, operation = nil, options = {})
51
+ nested = options.fetch(:nested, false)
52
+ _, shape = resolve(shape_ref, api)
53
+ case shape['type']
54
+ when 'byte' then 'Integer<byte>'
55
+ when 'blob'
56
+ if streaming_input?(shape, operation)
57
+ 'String, IO'
58
+ else
59
+ 'String, StringIO, File'
60
+ end
61
+ when 'boolean' then 'Boolean'
62
+ when 'character' then 'String<character>'
63
+ when 'double' then 'Float'
64
+ when 'float' then 'Float'
65
+ when 'integer' then 'Integer'
66
+ when 'list'
67
+ if nested
68
+ "Array"
69
+ else
70
+ "Array<#{ruby_input_type(shape['member'], api, operation, nested: true)}>"
71
+ end
72
+ when 'long' then 'Integer'
73
+ when 'map'
74
+ if nested
75
+ "Hash"
76
+ else
77
+ "Hash<String,#{ruby_input_type(shape['value'], api, operation, nested: true)}>"
78
+ end
79
+ when 'string' then 'String'
80
+ when 'structure'
81
+ if shape['document']
82
+ 'Hash,Array,String,Numeric,Boolean'
83
+ else
84
+ "Types::#{shape_ref['shape']}"
85
+ end
86
+ when 'timestamp' then 'Time,DateTime,Date,Integer,String'
87
+ else
88
+ raise "unhandled type #{shape.type}.inspect"
89
+ end
90
+ end
91
+
92
+ def ruby_type(shape_ref, api)
93
+ _, shape = resolve(shape_ref, api)
94
+ case shape['type']
95
+ when 'blob' then streaming?(shape_ref, api) ? 'IO' : 'String'
96
+ when 'boolean' then 'Boolean'
97
+ when 'byte' then 'Integer<byte>'
98
+ when 'character' then 'String<character>'
99
+ when 'double' then 'Float'
100
+ when 'float' then 'Float'
101
+ when 'integer' then 'Integer'
102
+ when 'list' then "Array<#{ruby_type(shape['member'], api)}>"
103
+ when 'long' then 'Integer'
104
+ when 'map' then "Hash<String,#{ruby_type(shape['value'], api)}>"
105
+ when 'string' then streaming?(shape_ref, api) ? 'IO' : 'String'
106
+ when 'structure'
107
+ if shape['document']
108
+ 'Hash,Array,String,Numeric,Boolean'
109
+ else
110
+ "Types::#{shape_ref['shape']}"
111
+ end
112
+ when 'timestamp' then 'Time'
113
+ else
114
+ raise "unhandled type #{shape['type'].inspect}"
115
+ end
116
+ end
117
+
118
+ # @return [Boolean]
119
+ def streaming?(shape_or_shape_ref, api)
120
+ ref, shape = resolve(shape_or_shape_ref, api)
121
+ ref['streaming'] || shape['streaming'] ||
122
+ ref['eventstream'] || shape['eventstream']
123
+ end
124
+
125
+ # @return [Boolean]
126
+ def eventstream?(shape_or_shape_ref, api)
127
+ ref, shape = resolve(shape_or_shape_ref, api)
128
+ ref['eventstream'] || shape['eventstream']
129
+ end
130
+
131
+ # @return [Boolean]
132
+ def streaming_input?(shape, operation)
133
+ shape['streaming'] && operation &&
134
+ operation['authtype'] == "v4-unsigned-body"
135
+ end
136
+
137
+ def plural?(resource)
138
+ plural = false
139
+ (resource['identifiers'] || []).each do |i|
140
+ if i['path'] && i['path'].include?('[]')
141
+ plural = true
142
+ break
143
+ end
144
+ end
145
+ plural = true if resource['data'] && resource['data'].include?('[]')
146
+ plural
147
+ end
148
+ end
149
+ end
150
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsSdkCodeGenerator
2
4
  class ApplyDocs
3
5
 
@@ -17,17 +19,28 @@ module AwsSdkCodeGenerator
17
19
  def apply_docs(docs)
18
20
  @api['documentation'] = docs['service']
19
21
  docs['operations'].each do |name, docstring|
22
+ next unless @api['operations'][name]
20
23
  @api['operations'][name]['documentation'] = docstring
21
24
  end
22
25
  docs['shapes'].each do |shape_name, shape_docs|
26
+ next unless @api['shapes'][shape_name]
23
27
  @api['shapes'][shape_name]['documentation'] = shape_docs['base']
24
28
  shape_docs['refs'].each do |ref, ref_docs|
25
29
  ref_shape, ref_member = ref.split('$')
30
+ next unless @api['shapes'][ref_shape]
26
31
  case @api['shapes'][ref_shape]['type']
27
32
  when 'structure'
28
- @api['shapes'][ref_shape]['members'][ref_member]['documentation'] = ref_docs
33
+ shape = @api['shapes'][ref_shape]
34
+ if shape && shape['members']
35
+ member = shape['members'][ref_member]
36
+ member['documentation'] = ref_docs if member
37
+ end
29
38
  when 'list', 'map'
30
- @api['shapes'][ref_shape][ref_member]['documentation'] = ref_docs
39
+ shape = @api['shapes'][ref_shape]
40
+ if shape
41
+ member = shape[ref_member]
42
+ member['documentation'] = ref_docs if member
43
+ end
31
44
  end
32
45
  end
33
46
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ class ClientConstructor
5
+
6
+ # @option options [required, PluginList] :plugins
7
+ def initialize(options)
8
+ plugin_options = documented_plugin_options(options.fetch(:plugins))
9
+ documentation = {}
10
+ plugin_options.each do |option|
11
+ documentation[option.name] = YardOptionTag.new(
12
+ name: option.name,
13
+ required: option.required,
14
+ ruby_type: option.doc_type,
15
+ default_value: option.doc_default(options),
16
+ docstring: option.docstring,
17
+ indent: " "
18
+ ).to_s
19
+ end
20
+ @documentation = Docstring.join_docstrings(documentation.values, block_comment: false)
21
+ end
22
+
23
+ # @return [String]
24
+ attr_reader :documentation
25
+
26
+ private
27
+
28
+ def documented_plugin_options(plugins)
29
+ i = 0
30
+ plugins.map(&:options).flatten.select(&:documented?).sort_by do |opt|
31
+ # Stable sort, first required options, then sort by name, then if
32
+ # two plugins of the same name, use an incrementer.
33
+ # options.fetch(:plugins) will be ordered.
34
+ [opt.required ? 'a' : 'b', opt.name, i += 1] #, opt.override ? 'b' : 'a']
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,282 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ class ClientOperationDocumentation
5
+
6
+ # get all of the enumerable methods that may conflict with members
7
+ # count has special handling in UnsafeEnumerableMethods
8
+ ENUMERABLE_METHODS = Class.new.new.extend(Enumerable).methods - [:count]
9
+
10
+ # @option options [required, String] :method_name
11
+ # @option options [required, Hash] :operation
12
+ # @option options [required, Hash] :api
13
+ # @option options [Array<Hash>] :examples
14
+ def initialize(options)
15
+ @name = options.fetch(:name)
16
+ @method_name = options.fetch(:method_name)
17
+ @operation = options.fetch(:operation)
18
+ @api = options.fetch(:api)
19
+ @client_examples = options.fetch(:client_examples, [])
20
+ @examples = options.fetch(:examples)
21
+ @module_name = options.fetch(:module_name)
22
+ @async_client = options[:async_client] || false
23
+ @pager = options[:pager]
24
+ @waiters = options[:waiters]
25
+ end
26
+
27
+ # @return [String]
28
+ attr_reader :method_name
29
+
30
+ # @return [String]
31
+ attr_reader :module_name
32
+
33
+ # @return [Hash]
34
+ attr_reader :operation
35
+
36
+ # @return [Hash]
37
+ attr_reader :api
38
+
39
+ # @return [Array<Hash>]
40
+ attr_reader :examples
41
+
42
+ # @return [Array<Hash>]
43
+ attr_reader :client_examples
44
+
45
+ # @return [Hash]
46
+ attr_reader :pager
47
+
48
+ # @return [String]
49
+ def to_str
50
+ Docstring.join_docstrings([
51
+ docstring(operation),
52
+ response_target_tag(operation, api),
53
+ option_tags(operation, api),
54
+ return_tag(operation, api),
55
+ pagination(pager, operation, api),
56
+ generated_examples(operation, api),
57
+ eventstream_examples(module_name, method_name, operation, api),
58
+ shared_examples(examples, operation, api),
59
+ given_examples(client_examples),
60
+ @async_client ? async_request_syntax_example(method_name, operation, api)
61
+ : request_syntax_example(method_name, operation, api),
62
+ response_structure_example(operation, api),
63
+ waiters_tag(@waiters),
64
+ see_also_tag(@name, api),
65
+ ], block_comment: false)
66
+ end
67
+ alias to_s to_str
68
+
69
+ private
70
+
71
+ def docstring(operation)
72
+ Docstring.block_comment(
73
+ Docstring.html_to_markdown(operation['documentation'])
74
+ )
75
+ end
76
+
77
+ def response_target_tag(operation, api)
78
+ if output = Api.shape(operation['output'], api)
79
+ if output['payload'] && output['members'][output['payload']]['streaming']
80
+ YardOptionTag.new(
81
+ name: 'response_target',
82
+ ruby_type: 'String, IO',
83
+ option_hash_name: 'params',
84
+ required: false,
85
+ docstring: 'Where to write response data, file path, or IO object.'
86
+ ).to_s
87
+ end
88
+ end
89
+ end
90
+
91
+ def option_tags(operation, api)
92
+ if operation['input']
93
+ shape = Api.shape(operation['input'], api)
94
+ return if shape['members'].nil?
95
+ shape['members'].map do |member_name, member_ref|
96
+ next if member_ref['documented'] === false
97
+ # input eventstream is not provided by params
98
+ member_shape = Api.shape(member_ref['shape'], api)
99
+ next if member_shape['eventstream'] === true
100
+ docstring = Api.docstring(member_ref, api)
101
+ if member_ref['idempotencyToken']
102
+ docstring = docstring.to_s + "<p><b>A suitable default value is auto-generated.** You should normally not need to pass this option.</b></p>"
103
+ end
104
+ if member_ref['jsonvalue']
105
+ docstring = docstring.to_s + "<p><b>SDK automatically handles json encoding and base64 encoding for you when the required value (Hash, Array, etc.) is provided according to the description.</b></p>"
106
+ end
107
+ if member_shape['document']
108
+ docstring = docstring.to_s + "<p>Document type used to carry open content (Hash,Array,String,Numeric,Boolean). A document type value is serialized using the same format as its surroundings and requires no additional encoding or escaping.</p>"
109
+ end
110
+ if member_ref['union']
111
+ docstring = docstring.to_s + "<p>This is a union type and you must set exactly one of the members.</p>"
112
+ end
113
+ YardOptionTag.new(
114
+ name: Underscore.underscore(member_name),
115
+ ruby_type: Api.ruby_input_type(member_ref, api, operation),
116
+ required: shape.fetch('required', []).include?(member_name),
117
+ docstring: Docstring.html_to_markdown(docstring),
118
+ option_hash_name: 'params',
119
+ ).to_s
120
+ end
121
+ else
122
+ []
123
+ end
124
+ end
125
+
126
+ def return_tag(operation, api)
127
+ output = Api.shape(operation['output'], api)
128
+ if output && output['members'] && output['members'].size > 0
129
+ shape_name = operation.fetch('output').fetch('shape')
130
+ type = "Types::#{shape_name}"
131
+ _, shape = Api.resolve(shape_name, api)
132
+ # add rest body streaming if qualified
133
+ unless shape['payload'].nil?
134
+ _, member_shape = Api.resolve(shape['payload'], api)
135
+ unless member_shape.nil?
136
+ member_shape['streaming'] = member_shape['type'] == 'blob' ||
137
+ member_shape['type'] == 'string'
138
+ end
139
+ end
140
+ methods = shape['members'].map do |member_name, member_ref|
141
+ member_type = Docstring.escape_html(Api.ruby_type(member_ref, api))
142
+ method_name = Underscore.underscore(member_name)
143
+ if ENUMERABLE_METHODS.include?(method_name.to_sym)
144
+ "# * {#{type}##{method_name} #data.#{method_name}} => #{member_type} (This method conflicts with a method on Response, call it through the data member)"
145
+ else
146
+ "# * {#{type}##{method_name} ##{method_name}} => #{member_type}"
147
+ end
148
+ end
149
+ "# @return [#{type}] Returns a {Seahorse::Client::Response response} object which responds to the following methods:\n#\n" + methods.join("\n")
150
+ else
151
+ "# @return [Struct] Returns an empty {Seahorse::Client::Response response}."
152
+ end
153
+ end
154
+
155
+ def pagination(pager, operation, api)
156
+ return unless pager
157
+
158
+ input = Array(pager['input_token'])
159
+ output = Array(pager['output_token'])
160
+ tokens = {}
161
+ input.each.with_index do |key, n|
162
+ tokens[Underscore.underscore_jmespath(output[n])] = Underscore.underscore_jmespath(key)
163
+ end
164
+
165
+ return if tokens.empty?
166
+
167
+ "# The returned {Seahorse::Client::Response response}" \
168
+ " is a pageable response and is Enumerable. For details on usage see" \
169
+ " {Aws::PageableResponse PageableResponse}."
170
+ end
171
+
172
+ def shared_examples(examples, operation, api)
173
+ return if examples.nil? || examples['examples'].nil? || examples['examples'][@name].nil?
174
+ begin # skip broken/nil examples
175
+ example_block = []
176
+ examples['examples'][@name].each do |example|
177
+ comments = example['comments']
178
+ input = SharedExample.new(
179
+ example['input'],
180
+ method_name,
181
+ operation,
182
+ api,
183
+ (comments.nil? ? '' : comments['input'])).to_str_input
184
+ parts = []
185
+ parts << "#\n"
186
+ parts << "# @example Example: #{example['title']}\n#\n"
187
+ if example['description'] && example['description'].length > 0
188
+ parts << "#{Helper.wrap_string(example['description'], 120, "# # ")}\n#\n"
189
+ end
190
+ parts += input.lines.map { |line| "# " + line }
191
+ if example['output']
192
+ output = SharedExample.new(
193
+ example['output'],
194
+ method_name,
195
+ operation,
196
+ api,
197
+ (comments.nil? ? '' : comments['output'])).to_str_output
198
+ parts << "\n#\n# resp.to_h outputs the following:\n"
199
+ parts += output.lines.map { |line| "# " + line }
200
+ end
201
+ example_block << parts.join
202
+ end
203
+ example_block.join("\n")
204
+ rescue
205
+ puts "Invalid example for operation: #{@name}"
206
+ nil
207
+ end
208
+ end
209
+
210
+ def generated_examples(operation, api)
211
+ nil
212
+ end
213
+
214
+ def eventstream_examples(module_name, method_name, operation, api)
215
+ return unless !!Helper.eventstream_output?(operation, api)
216
+ EventStreamExample.new(
217
+ api: api,
218
+ operation: operation,
219
+ method_name: method_name,
220
+ module_name: module_name,
221
+ receiver: 'client',
222
+ resp_var: 'resp'
223
+ ).format
224
+ end
225
+
226
+ def given_examples(client_examples)
227
+ client_examples.map do |example|
228
+ name = example[:name]
229
+ code = example[:code]
230
+ "# @example #{name}\n" + Docstring.block_comment(code, gap: ' ')
231
+ end
232
+ end
233
+
234
+ def request_syntax_example(method_name, operation, api)
235
+ SyntaxExample.new(
236
+ api: api,
237
+ shape: Api.shape(operation['input'], api),
238
+ method_name: method_name,
239
+ receiver: 'client',
240
+ resp_var: 'resp',
241
+ ).format
242
+ end
243
+
244
+ def async_request_syntax_example(method_name, operation, api)
245
+ SyntaxExample.new(
246
+ api: api,
247
+ shape: Api.shape(operation['input'], api),
248
+ method_name: method_name,
249
+ receiver: 'async_client',
250
+ resp_var: 'async_resp',
251
+ async: true
252
+ ).format
253
+ end
254
+
255
+ def response_structure_example(operation, api)
256
+ output = Api.shape(operation['output'], api) if operation['output']
257
+ if output && output['members'] && output['members'].size > 0
258
+ Docstring.block_comment(ClientResponseStructureExample.new(
259
+ shape_ref: operation['output'],
260
+ api: api
261
+ ).to_s)
262
+ end
263
+ end
264
+
265
+ def waiters_tag(waiters)
266
+ return unless waiters && waiters.size > 0
267
+
268
+ waiters_doc = waiters.map do |w|
269
+ "# * #{w.name}"
270
+ end
271
+ "#\n# The following waiters are defined for this operation (see {Client#wait_until} for detailed usage):\n#\n" + waiters_doc.join("\n")
272
+ end
273
+
274
+ def see_also_tag(operation, api)
275
+ uid = api['metadata']['uid']
276
+ if api['metadata']['protocol'] != 'api-gateway' && Crosslink.taggable?(uid)
277
+ "# " + Crosslink.tag_string(uid, operation)
278
+ end
279
+ end
280
+
281
+ end
282
+ end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ class ClientOperationList
5
+
6
+ include Enumerable
7
+
8
+ def initialize(options)
9
+ api = options.fetch(:api)
10
+ examples = options.fetch(:examples, {})
11
+ module_name = options.fetch(:module_name)
12
+ protocol_settings = options.fetch(:protocol_settings, {})
13
+ client_examples = options.fetch(:client_examples, {})
14
+ paginators = options.fetch(:paginators, {})
15
+ operation_waiters = Waiter.build_operations_map(options[:waiters])
16
+
17
+ @operations = api['operations'].inject([]) do |ops, (name, operation)|
18
+ method_name = Underscore.underscore(name)
19
+ waiters = operation_waiters[method_name]
20
+
21
+ async_client = options[:async_client] || false
22
+ es_output = AwsSdkCodeGenerator::Helper.eventstream_output?(operation, api)
23
+ es_input = AwsSdkCodeGenerator::Helper.eventstream_input?(operation, api)
24
+ if es_input || es_output
25
+ # eventstreaming operations
26
+ if protocol_settings['h2'] == 'eventstream'
27
+ # h2 supported, only generate for async client
28
+ if async_client
29
+ if es_input == es_output
30
+ # input & output eventstream sharing
31
+ # same eventstream shape
32
+ # see EventStreamModule
33
+ es_input = "Input" + es_input
34
+ es_output = "Output" + es_output
35
+ end
36
+ ops << Operation.new(
37
+ name: method_name,
38
+ documentation: ClientOperationDocumentation.new(
39
+ name: name,
40
+ module_name: module_name,
41
+ method_name: method_name,
42
+ operation: operation,
43
+ api: api,
44
+ examples: examples,
45
+ client_examples: client_examples[method_name] || [],
46
+ async_client: true
47
+ ).to_s,
48
+ streaming: AwsSdkCodeGenerator::Helper.operation_streaming?(operation, api),
49
+ eventstream_output: es_output,
50
+ eventstream_input: es_input
51
+ )
52
+ end
53
+ elsif !es_input && es_output && !async_client
54
+ # http1.1 only support eventstream at output
55
+ ops << Operation.new(
56
+ name: method_name,
57
+ documentation: ClientOperationDocumentation.new(
58
+ name: name,
59
+ module_name: module_name,
60
+ method_name: method_name,
61
+ operation: operation,
62
+ api: api,
63
+ examples: examples,
64
+ client_examples: client_examples[method_name] || [],
65
+ async_client: false
66
+ ).to_s,
67
+ streaming: AwsSdkCodeGenerator::Helper.operation_streaming?(operation, api),
68
+ eventstream_output: es_output,
69
+ eventstream_input: false
70
+ )
71
+ end
72
+ elsif !async_client
73
+ # non streaming operations
74
+ # generate at sync client only
75
+ ops << Operation.new(
76
+ name: method_name,
77
+ documentation: ClientOperationDocumentation.new(
78
+ name: name,
79
+ module_name: module_name,
80
+ method_name: method_name,
81
+ operation: operation,
82
+ api: api,
83
+ examples: examples,
84
+ client_examples: client_examples[method_name] || [],
85
+ async_client: false,
86
+ pager: paginators && paginators['pagination'][name],
87
+ waiters: waiters
88
+ ).to_s,
89
+ streaming: AwsSdkCodeGenerator::Helper.operation_streaming?(operation, api),
90
+ eventstream_output: false,
91
+ eventstream_input: false
92
+ )
93
+ end
94
+
95
+ ops
96
+ end
97
+ end
98
+
99
+ # @return [Enumerable<Operation>]
100
+ def each(&block)
101
+ @operations.each(&block)
102
+ end
103
+
104
+ class Operation
105
+
106
+ def initialize(options)
107
+ @name = options.fetch(:name)
108
+ @documentation = options.fetch(:documentation)
109
+ @streaming = options.fetch(:streaming)
110
+ @eventstream_output = !!options.fetch(:eventstream_output)
111
+ @eventstream_input = !!options.fetch(:eventstream_input)
112
+ @output_eventstream_member = @eventstream_output ?
113
+ options.fetch(:eventstream_output) : nil
114
+ @input_eventstream_member = @eventstream_input ?
115
+ options.fetch(:eventstream_input) : nil
116
+ @bidirectional = @eventstream_output && @eventstream_input
117
+ end
118
+
119
+ # @return [String]
120
+ attr_reader :name
121
+
122
+ # @return [String, nil]
123
+ attr_reader :documentation
124
+
125
+ # @return [Boolean]
126
+ attr_reader :eventstream_input
127
+
128
+ # @return [Boolean]
129
+ attr_reader :eventstream_output
130
+
131
+ # @return [String]
132
+ attr_reader :input_eventstream_member
133
+
134
+ # @return [String]
135
+ attr_reader :output_eventstream_member
136
+
137
+ # @return [Boolean]
138
+ attr_reader :bidirectional
139
+
140
+ def block_option
141
+ if @streaming
142
+ ", &block"
143
+ end
144
+ end
145
+
146
+ end
147
+ end
148
+ end