aws-sdk-code-generator 0.1.0.pre → 0.2.4.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.
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