smithy 2.0.0.pre0 → 2.0.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/smithy-ruby +1 -4
  4. data/lib/smithy/command.rb +68 -0
  5. data/lib/smithy/generators/base.rb +19 -0
  6. data/lib/smithy/generators/client.rb +106 -0
  7. data/lib/smithy/generators/schema.rb +61 -0
  8. data/lib/smithy/generators.rb +29 -0
  9. data/lib/smithy/model/flattener.rb +114 -0
  10. data/lib/smithy/model/operation_parser.rb +42 -0
  11. data/lib/smithy/model/rbs.rb +57 -0
  12. data/lib/smithy/model/service_index.rb +51 -0
  13. data/lib/smithy/model/service_parser.rb +74 -0
  14. data/lib/smithy/model/shape.rb +49 -0
  15. data/lib/smithy/model/structure_parser.rb +43 -0
  16. data/lib/smithy/model/yard.rb +100 -0
  17. data/lib/smithy/model.rb +54 -0
  18. data/lib/smithy/plan.rb +79 -3
  19. data/lib/smithy/templates/client/auth_parameters.erb +29 -0
  20. data/lib/smithy/templates/client/auth_parameters_rbs.erb +14 -0
  21. data/lib/smithy/templates/client/auth_plugin.erb +115 -0
  22. data/lib/smithy/templates/client/auth_resolver.erb +16 -0
  23. data/lib/smithy/templates/client/auth_resolver_rbs.erb +5 -0
  24. data/lib/smithy/templates/client/client.erb +142 -0
  25. data/lib/smithy/templates/client/client_rbs.erb +29 -0
  26. data/lib/smithy/templates/client/customizations.erb +3 -0
  27. data/lib/smithy/templates/client/endpoint_parameters.erb +65 -0
  28. data/lib/smithy/templates/client/endpoint_parameters_rbs.erb +13 -0
  29. data/lib/smithy/templates/client/endpoint_plugin.erb +58 -0
  30. data/lib/smithy/templates/client/endpoint_provider.erb +15 -0
  31. data/lib/smithy/templates/client/endpoint_provider_rbs.erb +5 -0
  32. data/lib/smithy/templates/client/endpoint_provider_spec.erb +70 -0
  33. data/lib/smithy/templates/client/errors.erb +69 -0
  34. data/lib/smithy/templates/client/errors_rbs.erb +17 -0
  35. data/lib/smithy/templates/client/gemspec.erb +17 -0
  36. data/lib/smithy/templates/client/module.erb +22 -0
  37. data/lib/smithy/templates/client/module_rbs.erb +7 -0
  38. data/lib/smithy/templates/client/paginators.erb +33 -0
  39. data/lib/smithy/templates/client/protocol_spec.erb +144 -0
  40. data/lib/smithy/templates/client/rubocop_yml.erb +33 -0
  41. data/lib/smithy/templates/client/schema.erb +76 -0
  42. data/lib/smithy/templates/client/schema_rbs.erb +13 -0
  43. data/lib/smithy/templates/client/spec_helper.erb +10 -0
  44. data/lib/smithy/templates/client/types.erb +64 -0
  45. data/lib/smithy/templates/client/types_rbs.erb +47 -0
  46. data/lib/smithy/templates/client/waiters.erb +42 -0
  47. data/lib/smithy/util/hash_formatter.rb +124 -0
  48. data/lib/smithy/util/underscore.rb +18 -0
  49. data/lib/smithy/util.rb +9 -0
  50. data/lib/smithy/views/client/auth_parameter.rb +29 -0
  51. data/lib/smithy/views/client/auth_parameters.rb +23 -0
  52. data/lib/smithy/views/client/auth_parameters_rbs.rb +23 -0
  53. data/lib/smithy/views/client/auth_plugin.rb +35 -0
  54. data/lib/smithy/views/client/auth_resolver.rb +125 -0
  55. data/lib/smithy/views/client/auth_resolver_rbs.rb +19 -0
  56. data/lib/smithy/views/client/client.rb +208 -0
  57. data/lib/smithy/views/client/client_rbs.rb +231 -0
  58. data/lib/smithy/views/client/customizations.rb +10 -0
  59. data/lib/smithy/views/client/endpoint_parameter.rb +156 -0
  60. data/lib/smithy/views/client/endpoint_parameters.rb +43 -0
  61. data/lib/smithy/views/client/endpoint_parameters_rbs.rb +28 -0
  62. data/lib/smithy/views/client/endpoint_plugin.rb +27 -0
  63. data/lib/smithy/views/client/endpoint_provider.rb +241 -0
  64. data/lib/smithy/views/client/endpoint_provider_rbs.rb +19 -0
  65. data/lib/smithy/views/client/endpoint_provider_spec.rb +137 -0
  66. data/lib/smithy/views/client/errors.rb +88 -0
  67. data/lib/smithy/views/client/errors_rbs.rb +12 -0
  68. data/lib/smithy/views/client/gemspec.rb +36 -0
  69. data/lib/smithy/views/client/module.rb +107 -0
  70. data/lib/smithy/views/client/module_rbs.rb +20 -0
  71. data/lib/smithy/views/client/operation_examples.rb +157 -0
  72. data/lib/smithy/views/client/paginators.rb +108 -0
  73. data/lib/smithy/views/client/plugin.rb +29 -0
  74. data/lib/smithy/views/client/plugin_list.rb +57 -0
  75. data/lib/smithy/views/client/protocol_spec.rb +254 -0
  76. data/lib/smithy/views/client/request_response_example.rb +179 -0
  77. data/lib/smithy/views/client/rubocop_yml.rb +19 -0
  78. data/lib/smithy/views/client/schema.rb +356 -0
  79. data/lib/smithy/views/client/schema_rbs.rb +84 -0
  80. data/lib/smithy/views/client/shape_to_hash.rb +99 -0
  81. data/lib/smithy/views/client/spec_helper.rb +19 -0
  82. data/lib/smithy/views/client/types.rb +293 -0
  83. data/lib/smithy/views/client/types_rbs.rb +67 -0
  84. data/lib/smithy/views/client/waiters.rb +82 -0
  85. data/lib/smithy/views/client.rb +47 -0
  86. data/lib/smithy/views/view.rb +30 -0
  87. data/lib/smithy/views.rb +9 -0
  88. data/lib/smithy/weld.rb +109 -0
  89. data/lib/smithy/welds/auth/anonymous_auth.rb +31 -0
  90. data/lib/smithy/welds/auth/http_api_key_auth.rb +34 -0
  91. data/lib/smithy/welds/auth/http_basic_auth.rb +34 -0
  92. data/lib/smithy/welds/auth/http_bearer_auth.rb +34 -0
  93. data/lib/smithy/welds/auth/http_digest_auth.rb +34 -0
  94. data/lib/smithy/welds/plugins.rb +54 -0
  95. data/lib/smithy/welds/rpc_v2_cbor.rb +20 -0
  96. data/lib/smithy/welds/rubocop.rb +33 -0
  97. data/lib/smithy/welds/transforms/default_endpoint_rules.json +35 -0
  98. data/lib/smithy/welds/transforms/default_endpoint_tests.json +24 -0
  99. data/lib/smithy/welds/transforms/endpoints.rb +68 -0
  100. data/lib/smithy/welds/transforms/synthetic_input_output.rb +60 -0
  101. data/lib/smithy/welds.rb +29 -0
  102. data/lib/smithy.rb +33 -2
  103. metadata +144 -9
@@ -0,0 +1,241 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+
5
+ module Smithy
6
+ module Views
7
+ module Client
8
+ # @api private
9
+ class EndpointProvider < View
10
+ def initialize(plan)
11
+ @plan = plan
12
+ @model = plan.model
13
+ service = @plan.service.values.first
14
+ @endpoint_rules = service['traits']['smithy.rules#endpointRuleSet']
15
+ @parameters = @endpoint_rules['parameters']
16
+ .map { |id, data| EndpointParameter.new(id, data, @plan) }
17
+ @endpoint_function_bindings =
18
+ plan.welds.map(&:endpoint_function_bindings).reduce({}, :merge)
19
+ @assigned_variables = []
20
+ super()
21
+ end
22
+
23
+ attr_reader :parameters
24
+
25
+ def module_name
26
+ @plan.module_name
27
+ end
28
+
29
+ # TODO: simplify this by removing levels and just returning line strings
30
+ def endpoint_rules_code
31
+ res = StringIO.new
32
+ @endpoint_rules['rules'].each do |rule|
33
+ case rule['type']
34
+ when 'endpoint'
35
+ res << endpoint_rule(rule, 3)
36
+ when 'error'
37
+ res << error_rule(rule, 3)
38
+ when 'tree'
39
+ res << tree_rule(rule, 3)
40
+ else
41
+ raise "Unknown rule type: #{rule['type']}"
42
+ end
43
+ end
44
+
45
+ res.string
46
+ end
47
+
48
+ private
49
+
50
+ def indent(str, levels = 3)
51
+ (' ' * levels) + str
52
+ end
53
+
54
+ def endpoint_rule(rule, levels = 3)
55
+ if rule['conditions'] && !rule['conditions'].empty?
56
+ endpoint_rule_with_condition(levels, rule)
57
+ else
58
+ endpoint(rule['endpoint'], levels)
59
+ end
60
+ end
61
+
62
+ def endpoint_rule_with_condition(levels, rule)
63
+ res = StringIO.new
64
+ res << conditions(rule['conditions'], levels)
65
+ res << endpoint(rule['endpoint'], levels + 1)
66
+ res << indent("end\n", levels)
67
+ res.string
68
+ end
69
+
70
+ def endpoint(endpoint, levels)
71
+ res = StringIO.new
72
+ res << "return Smithy::Client::EndpointRules::Endpoint.new(uri: #{str(endpoint['url'])}"
73
+ res << ", headers: #{templated_hash_to_s(endpoint['headers'])}" if endpoint['headers']
74
+ res << ", properties: #{templated_hash_to_s(endpoint['properties'])}" if endpoint['properties']
75
+ res << ")\n"
76
+ indent(res.string, levels)
77
+ end
78
+
79
+ def templated_hash_to_s(hash)
80
+ template_hash_values(hash).to_s.gsub('\#{', '#{') # unescape references
81
+ end
82
+
83
+ def template_hash_values(hash)
84
+ hash.transform_values do |v|
85
+ template_hash_value(v)
86
+ end
87
+ end
88
+
89
+ def template_hash_value(value)
90
+ case value
91
+ when Hash
92
+ template_hash_values(value)
93
+ when Array
94
+ value.map { |v| template_hash_value(v) }
95
+ when String
96
+ template_str(value, wrap: false)
97
+ else
98
+ value
99
+ end
100
+ end
101
+
102
+ def error_rule(rule, levels = 3)
103
+ if rule['conditions'] && !rule['conditions'].empty?
104
+ error_rule_with_condition(levels, rule)
105
+ else
106
+ error(rule['error'], levels)
107
+ end
108
+ end
109
+
110
+ def error_rule_with_condition(levels, rule)
111
+ res = StringIO.new
112
+ res << conditions(rule['conditions'], levels)
113
+ res << error(rule['error'], levels + 1)
114
+ res << indent("end\n", levels)
115
+ res.string
116
+ end
117
+
118
+ def error(error, levels)
119
+ indent("raise ArgumentError, #{str(error)}", levels)
120
+ end
121
+
122
+ def tree_rule(rule, levels = 3)
123
+ if rule['conditions'] && !rule['conditions'].empty?
124
+ tree_rule_with_condition(levels, rule)
125
+ else
126
+ tree_rules(rule['rules'], levels)
127
+ end
128
+ end
129
+
130
+ def tree_rule_with_condition(levels, rule)
131
+ res = StringIO.new
132
+ res << conditions(rule['conditions'], levels)
133
+ res << tree_rules(rule['rules'], levels + 1)
134
+ res << indent("end\n", levels)
135
+ res.string
136
+ end
137
+
138
+ def tree_rules(rules, levels)
139
+ res = StringIO.new
140
+ rules.each do |rule|
141
+ case rule['type']
142
+ when 'endpoint'
143
+ res << endpoint_rule(rule, levels)
144
+ when 'error'
145
+ res << error_rule(rule, levels)
146
+ when 'tree'
147
+ res << tree_rule(rule, levels)
148
+ else
149
+ raise "Unknown rule type: #{rule['type']}"
150
+ end
151
+ end
152
+ res.string
153
+ end
154
+
155
+ def conditions(conditions, level)
156
+ res = StringIO.new
157
+ cnd_str = conditions.map { |c| condition(c) }.join(' && ')
158
+ res << indent("if #{cnd_str}\n", level)
159
+ res.string
160
+ end
161
+
162
+ def condition(condition)
163
+ if condition['assign']
164
+ @assigned_variables << condition['assign']
165
+ "(#{condition['assign'].underscore} = #{function(condition)})"
166
+ else
167
+ function(condition)
168
+ end
169
+ end
170
+
171
+ def str(str)
172
+ if str.is_a?(Hash)
173
+ if str['ref']
174
+ variable(str['ref'])
175
+ elsif str['fn']
176
+ function(str)
177
+ else
178
+ raise "Unknown string type: #{str}"
179
+ end
180
+ else
181
+ template_str(str)
182
+ end
183
+ end
184
+
185
+ def template_str(string, wrap: true)
186
+ string.scan(/\{.+?\}/).each do |capture|
187
+ value = capture[1..-2] # strips curly brackets
188
+ string = string.gsub(capture, "\#{#{template_replace(value)}}")
189
+ end
190
+ string = string.gsub('"', '\"')
191
+ wrap ? "\"#{string}\"" : string
192
+ end
193
+
194
+ def template_replace(value)
195
+ indexes = value.split('#')
196
+ res = variable(indexes.shift)
197
+ res + indexes.map do |index|
198
+ "['#{index}']"
199
+ end.join
200
+ end
201
+
202
+ def function(function)
203
+ args = function['argv'].map { |arg| fn_arg(arg) }.join(', ')
204
+ "#{fn_name(function['fn'])}(#{args})"
205
+ end
206
+
207
+ def fn_arg(arg)
208
+ if arg.is_a?(Hash)
209
+ if arg['ref']
210
+ variable(arg['ref'])
211
+ elsif arg['fn']
212
+ function(arg)
213
+ else
214
+ raise "Unexpected argument type: #{arg}"
215
+ end
216
+ elsif arg.is_a?(String)
217
+ template_str(arg)
218
+ else
219
+ arg
220
+ end
221
+ end
222
+
223
+ def variable(variable)
224
+ if @assigned_variables.include?(variable)
225
+ variable.underscore
226
+ else
227
+ "parameters.#{variable.underscore}"
228
+ end
229
+ end
230
+
231
+ def fn_name(function)
232
+ unless (binding = @endpoint_function_bindings[function])
233
+ raise ArgumentError, "No endpoint function binding registered for #{function}"
234
+ end
235
+
236
+ binding
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class EndpointProviderRbs < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ super()
11
+ end
12
+
13
+ def module_name
14
+ @plan.module_name
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class EndpointProviderSpec < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ @model = plan.model
11
+ service = @plan.service.values.first
12
+ @operations = Model::ServiceIndex.new(@model).operations_for(@plan.service)
13
+ initialize_rules(service)
14
+ initialize_tests(service)
15
+ super()
16
+ end
17
+
18
+ attr_reader :parameters, :test_cases
19
+
20
+ def module_name
21
+ @plan.module_name
22
+ end
23
+
24
+ private
25
+
26
+ def initialize_rules(service)
27
+ @endpoint_rules = service['traits']['smithy.rules#endpointRuleSet']
28
+
29
+ @parameters = @endpoint_rules['parameters']
30
+ .map { |id, data| EndpointParameter.new(id, data, @plan) }
31
+ end
32
+
33
+ def initialize_tests(service)
34
+ @endpoint_tests = service['traits']['smithy.rules#endpointTests'] || {}
35
+ @test_cases = @endpoint_tests['testCases']
36
+ &.map { |data| EndpointTestCase.new(data, @plan, @operations) } || []
37
+ end
38
+
39
+ # @api private
40
+ class EndpointTestCase
41
+ def initialize(data, plan, operations)
42
+ @plan = plan
43
+ @documentation = data['documentation']
44
+ @expect = data['expect']
45
+ @operation_inputs = data.fetch('operationInputs', []).map do |d|
46
+ OperationInputsTest.new(d, plan, operations)
47
+ end
48
+ @params = (data['params'] || {})&.transform_keys do |key|
49
+ key.underscore.to_sym
50
+ end
51
+ end
52
+
53
+ attr_reader :documentation, :expect, :params, :operation_inputs
54
+
55
+ def expect_error?
56
+ !@expect['error'].nil?
57
+ end
58
+ end
59
+
60
+ # @api private
61
+ class OperationInputsTest
62
+ def initialize(data, plan, operations)
63
+ @operation_name = data['operationName'].underscore
64
+ @plan = plan
65
+ @model = plan.model
66
+ @service = @plan.service
67
+
68
+ input = find_input(data, operations)
69
+
70
+ @operation_params = build_operation_params(data, input)
71
+ @client_params = build_client_params(data)
72
+ end
73
+
74
+ attr_reader :operation_name, :operation_params, :client_params
75
+
76
+ private
77
+
78
+ def build_client_params(data)
79
+ client_params = data.fetch('clientParams', {}).map do |k, v|
80
+ Param.new(k.underscore, v)
81
+ end
82
+
83
+ client_params + data.fetch('builtInParams', {}).map do |k, v|
84
+ built_in_to_param(k, v)
85
+ end.flatten
86
+ end
87
+
88
+ def build_operation_params(data, input)
89
+ data.fetch('operationParams', {}).map do |k, v|
90
+ member_shape = Model.shape(@model, input['members'][k]['target'])
91
+ Param.new(k.underscore, ShapeToHash.transform_value(@model, v, member_shape))
92
+ end
93
+ end
94
+
95
+ def find_input(data, operations)
96
+ input_target = operations.find do |k, _v|
97
+ k.split('#').last == data['operationName']
98
+ end.last['input']['target']
99
+ Model.shape(@model, input_target)
100
+ end
101
+
102
+ def built_in_bindings
103
+ @built_in_bindings ||=
104
+ @plan.welds
105
+ .map(&:endpoint_built_in_bindings)
106
+ .reduce({}, :merge)
107
+ end
108
+
109
+ def built_in_to_param(built_in, value)
110
+ built_in_bindings[built_in][:render_test_set]
111
+ .call(@plan, value)
112
+ .map { |k, v| Param.new(k, v) }
113
+ end
114
+ end
115
+
116
+ # @api private
117
+ class Param
118
+ def initialize(param, value, literal: false)
119
+ @param = param
120
+ @value = value
121
+ @literal = literal
122
+ end
123
+
124
+ attr_accessor :param
125
+
126
+ def value
127
+ if @value.is_a?(String) && !@literal
128
+ "'#{@value}'"
129
+ else
130
+ @value
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class Errors < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ @model = plan.model
11
+ super()
12
+ end
13
+
14
+ def module_name
15
+ @plan.module_name
16
+ end
17
+
18
+ def errors
19
+ Model::ServiceIndex
20
+ .new(@model)
21
+ .shapes_for(@plan.service)
22
+ .select { |_key, shape| shape.fetch('traits', {}).any? { |id, _trait| id == 'smithy.api#error' } }
23
+ .map { |id, structure| Error.new(id, structure) }
24
+ end
25
+
26
+ # @api private
27
+ class Error
28
+ def initialize(id, structure)
29
+ @id = id
30
+ @structure = structure
31
+ end
32
+
33
+ def docstrings
34
+ @structure
35
+ .fetch('traits', {})
36
+ .fetch('smithy.api#documentation', "Error class for #{name}.")
37
+ .split("\n")
38
+ end
39
+
40
+ def name
41
+ Model::Shape.name(@id).camelize
42
+ end
43
+
44
+ def retryable?
45
+ @structure
46
+ .dig('traits', 'smithy.api#retryable') != nil
47
+ end
48
+
49
+ def throttling?
50
+ @structure
51
+ .fetch('traits', {})
52
+ .fetch('smithy.api#retryable', {})
53
+ .fetch('throttling', false)
54
+ end
55
+
56
+ def members
57
+ @structure['members'].map { |name, member| Member.new(name, member) }
58
+ end
59
+
60
+ # @api private
61
+ class Member
62
+ def initialize(name, shape)
63
+ @name = name
64
+ @shape = shape
65
+ end
66
+
67
+ attr_reader :shape
68
+
69
+ def message?
70
+ @name == 'message'
71
+ end
72
+
73
+ def docstrings
74
+ @shape
75
+ .fetch('traits', {})
76
+ .fetch('smithy.api#documentation', '')
77
+ .split("\n")
78
+ end
79
+
80
+ def name
81
+ @name.underscore
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class ErrorsRbs < Errors
8
+ attr_reader :model
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class Gemspec < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ super()
11
+ end
12
+
13
+ def gem_name
14
+ @plan.gem_name
15
+ end
16
+
17
+ def gem_version
18
+ @plan.gem_version
19
+ end
20
+
21
+ def dependencies
22
+ dependencies = @plan.welds.map(&:add_dependencies).reduce({}, :merge)
23
+ dependencies = dependencies.except(@plan.welds.map(&:remove_dependencies).reduce([], :+))
24
+ dependencies.merge!(
25
+ if @plan.type == :schema
26
+ { 'smithy-schema' => '~> 1' }
27
+ else
28
+ { 'smithy-client' => '~> 1' }
29
+ end
30
+ )
31
+ dependencies
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class Module < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ _, service = plan.service.first
11
+ @traits = service.fetch('traits', {})
12
+ @model = plan.model
13
+ super()
14
+ end
15
+
16
+ def requires
17
+ requires = @plan.welds.map(&:add_dependencies).reduce({}, :merge)
18
+ requires = requires.except(@plan.welds.map(&:remove_dependencies).reduce([], :+))
19
+ requires = requires.keys
20
+ requires <<
21
+ if @plan.type == :schema
22
+ 'smithy-schema'
23
+ else
24
+ 'smithy-client'
25
+ end
26
+ requires
27
+ end
28
+
29
+ def module_names
30
+ @plan.module_name.split('::')
31
+ end
32
+
33
+ def module_name
34
+ @plan.module_name
35
+ end
36
+
37
+ def docstrings
38
+ lines = []
39
+ lines.concat(title_docstrings)
40
+ lines.concat(documentation_docstrings)
41
+ lines.concat(deprecated_docstrings)
42
+ lines.concat(external_documentation_docstrings)
43
+ lines.concat(since_docstrings)
44
+ lines.concat(unstable_docstrings)
45
+ lines
46
+ end
47
+
48
+ def gem_version
49
+ @plan.gem_version
50
+ end
51
+
52
+ def gem_name
53
+ @plan.gem_name
54
+ end
55
+
56
+ def relative_requires
57
+ return [] unless @plan.destination_root
58
+ # types must come before schemas
59
+ return %i[customizations types schema] if @plan.type == :schema
60
+
61
+ # paginators must come before schemas
62
+ %w[types paginators schema auth_parameters auth_resolver client customizations errors endpoint_parameters
63
+ endpoint_provider waiters]
64
+ end
65
+
66
+ private
67
+
68
+ def title_docstrings
69
+ return [] unless @traits.key?('smithy.api#title')
70
+
71
+ [Model::YARD.title_docstring(@traits['smithy.api#title'])]
72
+ end
73
+
74
+ def documentation_docstrings
75
+ @traits.fetch('smithy.api#documentation', '').split("\n")
76
+ end
77
+
78
+ def deprecated_docstrings
79
+ return [] unless @traits.key?('smithy.api#deprecated')
80
+
81
+ message = @traits['smithy.api#deprecated'].fetch('message', '')
82
+ since = @traits['smithy.api#deprecated'].fetch('since', '')
83
+ Model::YARD.deprecated_docstrings(message, since)
84
+ end
85
+
86
+ def external_documentation_docstrings
87
+ return [] unless @traits.key?('smithy.api#externalDocumentation')
88
+
89
+ hash = @traits.fetch('smithy.api#externalDocumentation', {})
90
+ Model::YARD.external_documentation_docstrings(hash)
91
+ end
92
+
93
+ def since_docstrings
94
+ return [] unless @traits.key?('smithy.api#since')
95
+
96
+ [Model::YARD.since_docstring(@traits['smithy.api#since'])]
97
+ end
98
+
99
+ def unstable_docstrings
100
+ return [] unless @traits.key?('smithy.api#unstable')
101
+
102
+ [Model::YARD.unstable_docstring]
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smithy
4
+ module Views
5
+ module Client
6
+ # @api private
7
+ class ModuleRbs < View
8
+ def initialize(plan)
9
+ @plan = plan
10
+ @model = plan.model
11
+ super()
12
+ end
13
+
14
+ def module_names
15
+ @plan.module_name.split('::')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end