aws-sdk 2.0.1 → 2.0.5

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 (251) hide show
  1. package/.eslintrc +20 -0
  2. package/.gitignore +10 -0
  3. package/.travis.yml +20 -0
  4. package/.yardopts +20 -0
  5. package/.yardopts_guide +21 -0
  6. package/Gemfile +16 -0
  7. package/Gemfile.lock +34 -0
  8. package/README.md +5 -6
  9. package/Rakefile +14 -0
  10. package/UPGRADING.md +9 -4
  11. package/configuration.sample +5 -0
  12. package/dist/BUNDLE_LICENSE.txt +96 -0
  13. package/dist/aws-sdk.js +9594 -0
  14. package/dist/aws-sdk.min.js +21 -0
  15. package/dist-tools/.eslintrc +10 -0
  16. package/dist-tools/browser-builder.js +142 -0
  17. package/dist-tools/strategies/cache.js +68 -0
  18. package/dist-tools/strategies/default.js +165 -0
  19. package/dist-tools/test/browser-builder.mocha.spec.coffee +182 -0
  20. package/dist-tools/test/helpers.coffee +16 -0
  21. package/doc-src/guide/browser-building.md +93 -0
  22. package/doc-src/guide/browser-configuring-wif.md +287 -0
  23. package/doc-src/guide/browser-configuring.md +218 -0
  24. package/doc-src/guide/browser-examples.md +220 -0
  25. package/doc-src/guide/browser-intro.md +46 -0
  26. package/doc-src/guide/browser-making-requests.md +279 -0
  27. package/doc-src/guide/browser-services.md +75 -0
  28. package/doc-src/guide/index.md +41 -0
  29. package/doc-src/guide/node-configuring.md +272 -0
  30. package/doc-src/guide/node-examples.md +341 -0
  31. package/doc-src/guide/node-intro.md +32 -0
  32. package/doc-src/guide/node-making-requests.md +309 -0
  33. package/doc-src/guide/node-services.md +159 -0
  34. package/doc-src/templates/api-versions/model_documentor.rb +366 -0
  35. package/doc-src/templates/api-versions/plugin.rb +230 -0
  36. package/doc-src/templates/api-versions/templates/default/class/html/setup.rb +9 -0
  37. package/doc-src/templates/api-versions/templates/default/class/html/waiter_details_list.erb +7 -0
  38. package/doc-src/templates/api-versions/templates/default/class/html/waiter_summary.erb +7 -0
  39. package/doc-src/templates/api-versions/templates/default/docstring/html/experimental.erb +4 -0
  40. package/doc-src/templates/api-versions/templates/default/docstring/setup.rb +9 -0
  41. package/doc-src/templates/api-versions/templates/default/fulldoc/html/css/common.css +6 -0
  42. package/doc-src/templates/api-versions/templates/default/fulldoc/html/setup.rb +62 -0
  43. package/doc-src/templates/api-versions/templates/default/layout/html/services.erb +10 -0
  44. package/doc-src/templates/api-versions/templates/default/layout/html/setup.rb +28 -0
  45. package/doc-src/templates/api-versions/templates/default/module/html/box_info.erb +45 -0
  46. package/doc-src/templates/api-versions/templates/default/module/html/children.erb +8 -0
  47. package/doc-src/templates/api-versions/templates/default/tags/setup.rb +3 -0
  48. package/doc-src/templates/api-versions/templates/default/waiter_details/html/method_signature.erb +3 -0
  49. package/doc-src/templates/api-versions/templates/default/waiter_details/html/setup.rb +5 -0
  50. package/doc-src/templates/default/layout/html/footer.erb +31 -0
  51. package/doc-src/templates/default/layout/html/layout.erb +23 -0
  52. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/highlight.github.css +127 -0
  53. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/style.css +1192 -0
  54. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/img/logo.png +0 -0
  55. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/app.js +33 -0
  56. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/highlight.pack.js +27 -0
  57. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/AUTHORS +55 -0
  58. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/LICENSE +25 -0
  59. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/doctools.js +247 -0
  60. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/file.png +0 -0
  61. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/searchtools.js +568 -0
  62. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/underscore.js +23 -0
  63. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search.erb +29 -0
  64. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search_index.erb +1 -0
  65. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/setup.rb +75 -0
  66. package/doc-src/templates/flasky_sphinx_guide/layout/html/layout.erb +93 -0
  67. package/doc-src/templates/flasky_sphinx_guide/layout/html/setup.rb +9 -0
  68. package/doc-src/templates/flasky_sphinx_guide/layout/html/sidebar.erb +45 -0
  69. package/doc-src/templates/flasky_sphinx_guide/onefile/html/layout.erb +51 -0
  70. package/doc-src/templates/flasky_sphinx_guide/onefile/html/setup.rb +1 -0
  71. package/eslint-rules/no-require-in-service.js +10 -0
  72. package/features/autoscaling/autoscaling.feature +21 -0
  73. package/features/autoscaling/step_definitions/autoscaling.js +49 -0
  74. package/features/cloudformation/cloudformation.feature +22 -0
  75. package/features/cloudformation/step_definitions/cloudformation.js +26 -0
  76. package/features/cloudfront/cloudfront.feature +28 -0
  77. package/features/cloudfront/step_definitions/cloudfront-latest.js +54 -0
  78. package/features/cloudfront/step_definitions/cloudfront.js +21 -0
  79. package/features/cloudsearch/cloudsearch.feature +34 -0
  80. package/features/cloudsearch/step_definitions/cloudsearch.js +42 -0
  81. package/features/cloudtrail/cloudtrail.feature +17 -0
  82. package/features/cloudtrail/step_definitions/cloudtrail.js +14 -0
  83. package/features/cloudwatch/cloudwatch.feature +15 -0
  84. package/features/cloudwatch/step_definitions/cloudwatch.js +48 -0
  85. package/features/datapipeline/datapipeline.feature +23 -0
  86. package/features/datapipeline/step_definitions/datapipeline.js +79 -0
  87. package/features/directconnect/directconnect.feature +20 -0
  88. package/features/directconnect/step_definitions/directconnect.js +44 -0
  89. package/features/dynamodb/crc32.feature +18 -0
  90. package/features/dynamodb/step_definitions/dynamodb.js +154 -0
  91. package/features/dynamodb/tables.feature +50 -0
  92. package/features/ec2/ec2.feature +28 -0
  93. package/features/ec2/step_definitions/ec2.js +65 -0
  94. package/features/elasticache/elasticache.feature +20 -0
  95. package/features/elasticache/step_definitions/elasticache.js +34 -0
  96. package/features/elasticbeanstalk/elasticbeanstalk.feature +22 -0
  97. package/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js +38 -0
  98. package/features/elastictranscoder/elastictranscoder.feature +24 -0
  99. package/features/elastictranscoder/step_definitions/elastictranscoder.js +56 -0
  100. package/features/elb/elb.feature +19 -0
  101. package/features/elb/step_definitions/elb.js +37 -0
  102. package/features/emr/emr.feature +16 -0
  103. package/features/emr/step_definitions/emr.js +45 -0
  104. package/features/extra/assertions.js +29 -0
  105. package/features/extra/dummy.feature +0 -0
  106. package/features/extra/fixtures/testfile.txt +1 -0
  107. package/features/extra/helpers.js +113 -0
  108. package/features/extra/hooks.js +107 -0
  109. package/features/extra/world.js +12 -0
  110. package/features/glacier/glacier.feature +47 -0
  111. package/features/glacier/step_definitions/glacier.js +112 -0
  112. package/features/iam/iam.feature +24 -0
  113. package/features/iam/step_definitions/iam.js +66 -0
  114. package/features/importexport/importexport.feature +53 -0
  115. package/features/importexport/step_definitions/importexport.js +42 -0
  116. package/features/kinesis/kinesis.feature +9 -0
  117. package/features/kinesis/step_definitions/kinesis.js +10 -0
  118. package/features/opsworks/opsworks.feature +26 -0
  119. package/features/opsworks/step_definitions/opsworks.js +42 -0
  120. package/features/rds/rds.feature +32 -0
  121. package/features/rds/step_definitions/rds.js +72 -0
  122. package/features/redshift/redshift.feature +20 -0
  123. package/features/redshift/step_definitions/redshift.js +33 -0
  124. package/features/route53/route53.feature +41 -0
  125. package/features/route53/step_definitions/route53.js +97 -0
  126. package/features/s3/buckets.feature +40 -0
  127. package/features/s3/objects.feature +122 -0
  128. package/features/s3/step_definitions/buckets.js +136 -0
  129. package/features/s3/step_definitions/hooks.js +39 -0
  130. package/features/s3/step_definitions/objects.js +204 -0
  131. package/features/s3/step_definitions/proxy.js +44 -0
  132. package/features/ses/ses.feature +20 -0
  133. package/features/ses/step_definitions/ses.js +22 -0
  134. package/features/simpledb/simpledb.feature +29 -0
  135. package/features/simpledb/step_definitions/simpledb.js +46 -0
  136. package/features/sns/sns.feature +15 -0
  137. package/features/sns/step_definitions/sns.js +33 -0
  138. package/features/sqs/messages.feature +21 -0
  139. package/features/sqs/queues.feature +18 -0
  140. package/features/sqs/step_definitions/messages.js +46 -0
  141. package/features/sqs/step_definitions/queues.js +33 -0
  142. package/features/sqs/step_definitions/sqs.js +7 -0
  143. package/features/storagegateway/step_definitions/storagegateway.js +16 -0
  144. package/features/storagegateway/storagegateway.feature +13 -0
  145. package/features/sts/step_definitions/sts.js +35 -0
  146. package/features/sts/sts.feature +29 -0
  147. package/features/support/step_definitions/support.js +35 -0
  148. package/features/support/support.feature +18 -0
  149. package/features/swf/step_definitions/swf.js +38 -0
  150. package/features/swf/swf.feature +15 -0
  151. package/index.js +2 -0
  152. package/lib/core.js +2 -2
  153. package/lib/credentials/shared_ini_file_credentials.js +0 -1
  154. package/lib/event_listeners.js +13 -1
  155. package/lib/http/node.js +19 -30
  156. package/lib/model/resource_waiter.js +0 -4
  157. package/lib/model/shape.js +2 -1
  158. package/lib/protocol/rest_xml.js +1 -1
  159. package/lib/region_config.js +31 -0
  160. package/lib/region_config.json +56 -0
  161. package/lib/request.js +37 -45
  162. package/lib/sequential_executor.js +17 -34
  163. package/lib/service.js +17 -44
  164. package/lib/services/cloudsearchdomain.js +69 -0
  165. package/lib/services/route53.js +0 -12
  166. package/lib/services/s3.js +3 -19
  167. package/lib/signers/v4.js +2 -1
  168. package/lib/util.js +28 -3
  169. package/package.json +3 -3
  170. package/scripts/console +11 -3
  171. package/scripts/coverage +126 -0
  172. package/tasks/apis.rake +122 -0
  173. package/tasks/browser.rake +89 -0
  174. package/tasks/docs.rake +36 -0
  175. package/tasks/lib/cucumber_generator.rb +40 -0
  176. package/tasks/util.rake +33 -0
  177. package/test/browser/js/jasmine-1.3.1.js +2600 -0
  178. package/test/browser/js/jasmine-html.js +681 -0
  179. package/test/browser/runner.html +109 -0
  180. package/test/browser/runner.js +92 -0
  181. package/test/browser/sample/appinfo.sample.js +15 -0
  182. package/test/browser/sample/console.html +429 -0
  183. package/test/browser/sample/css/smoothness/images/animated-overlay.gif +0 -0
  184. package/test/browser/sample/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  185. package/test/browser/sample/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  186. package/test/browser/sample/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  187. package/test/browser/sample/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  188. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  189. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  190. package/test/browser/sample/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  191. package/test/browser/sample/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  192. package/test/browser/sample/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  193. package/test/browser/sample/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  194. package/test/browser/sample/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  195. package/test/browser/sample/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  196. package/test/browser/sample/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  197. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.css +1175 -0
  198. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.min.css +5 -0
  199. package/test/browser/sample/img/loading.gif +0 -0
  200. package/test/browser/sample/js/jquery-1.9.1.js +9597 -0
  201. package/test/browser/sample/js/jquery-ui-1.10.1.custom.js +14903 -0
  202. package/test/browser/sample/js/jquery-ui-1.10.1.custom.min.js +6 -0
  203. package/test/browser/sample/s3upload.html +111 -0
  204. package/test/browser.spec.coffee +207 -0
  205. package/test/config.spec.coffee +202 -0
  206. package/test/credential_provider_chain.spec.coffee +90 -0
  207. package/test/credentials.spec.coffee +452 -0
  208. package/test/endpoint.spec.coffee +80 -0
  209. package/test/event_listeners.spec.coffee +493 -0
  210. package/test/helpers.coffee +150 -0
  211. package/test/http_request.spec.coffee +55 -0
  212. package/test/json/builder.spec.coffee +129 -0
  213. package/test/json/parser.spec.coffee +108 -0
  214. package/test/metadata_service.spec.coffee +54 -0
  215. package/test/model/api.spec.coffee +67 -0
  216. package/test/model/shape.spec.coffee +23 -0
  217. package/test/node_http_client.spec.coffee +40 -0
  218. package/test/param_validator.spec.coffee +456 -0
  219. package/test/protocol/json.spec.coffee +167 -0
  220. package/test/protocol/query.spec.coffee +191 -0
  221. package/test/protocol/rest.spec.coffee +237 -0
  222. package/test/protocol/rest_json.spec.coffee +255 -0
  223. package/test/protocol/rest_xml.spec.coffee +329 -0
  224. package/test/query/query_param_serializer.spec.coffee +327 -0
  225. package/test/region_config.spec.coffee +50 -0
  226. package/test/request.spec.coffee +316 -0
  227. package/test/resource_waiter.spec.coffee +89 -0
  228. package/test/response.spec.coffee +81 -0
  229. package/test/sequential_executor.spec.coffee +118 -0
  230. package/test/service.spec.coffee +230 -0
  231. package/test/services/cloudfront.spec.coffee +44 -0
  232. package/test/services/cloudsearchdomain.spec.coffee +23 -0
  233. package/test/services/dynamodb.spec.coffee +32 -0
  234. package/test/services/ec2.spec.coffee +78 -0
  235. package/test/services/elastictranscoder.spec.coffee +43 -0
  236. package/test/services/glacier.spec.coffee +61 -0
  237. package/test/services/rds.spec.coffee +38 -0
  238. package/test/services/route53.spec.coffee +77 -0
  239. package/test/services/s3.spec.coffee +538 -0
  240. package/test/services/simpledb.spec.coffee +12 -0
  241. package/test/services/sqs.spec.coffee +130 -0
  242. package/test/services/sts.spec.coffee +72 -0
  243. package/test/services/swf.spec.coffee +6 -0
  244. package/test/signers/presign.spec.coffee +36 -0
  245. package/test/signers/s3.spec.coffee +297 -0
  246. package/test/signers/v2.spec.coffee +68 -0
  247. package/test/signers/v4.spec.coffee +135 -0
  248. package/test/util.spec.coffee +510 -0
  249. package/test/xml/builder.spec.coffee +529 -0
  250. package/test/xml/parser.spec.coffee +587 -0
  251. package/lib/services/simpledb.js +0 -15
@@ -0,0 +1,366 @@
1
+ require 'nokogiri'
2
+
3
+ module Documentor
4
+ def documentation(rules)
5
+ docs = rules['documentation'] || ''
6
+ docs = docs.gsub(/<!--.*?-->/m, '')
7
+ docs = docs.gsub(/<examples?>.+?<\/examples?>/m, '')
8
+ docs = docs.gsub(/<\/?note>/m, '')
9
+ docs = docs.gsub(/\{(\S+)\}/, '`{\1}`')
10
+ docs = docs.gsub(/\s+/, ' ').strip
11
+ docs == '' ? nil : docs
12
+ end
13
+
14
+ def method_name(name, downcased = true)
15
+ name = name.sub(/\d{4}_\d{2}_\d{2}$/, '')
16
+ downcased ? name[0].downcase + name[1..-1] : name
17
+ end
18
+ end
19
+
20
+ class ModelDocumentor
21
+ include Documentor
22
+
23
+ attr_reader :lines
24
+
25
+ def initialize(klass, api)
26
+ api_version = api['metadata']['apiVersion']
27
+ @lines = []
28
+ @lines << ''
29
+ @lines << <<-DOCS.strip
30
+ Constructs a service interface object. Each API operation is exposed as a
31
+ function on service.
32
+
33
+ ### Sending a Request Using #{klass}
34
+
35
+ ```javascript
36
+ var #{klass.downcase} = new AWS.#{klass}();
37
+ #{klass.downcase}.#{find_example_operation(api)}(params, function (err, data) {
38
+ if (err) console.log(err, err.stack); // an error occurred
39
+ else console.log(data); // successful response
40
+ });
41
+ ```
42
+
43
+ ### Locking the API Version
44
+
45
+ In order to ensure that the #{klass} object uses this specific API, you can
46
+ construct the object by passing the `apiVersion` option to the constructor:
47
+
48
+ ```javascript
49
+ var #{klass.downcase} = new AWS.#{klass}({apiVersion: '#{api_version}'});
50
+ ```
51
+
52
+ You can also set the API version globally in `AWS.config.apiVersions` using
53
+ the **#{klass.downcase}** service identifier:
54
+
55
+ ```javascript
56
+ AWS.config.apiVersions = {
57
+ #{klass.downcase}: '#{api_version}',
58
+ // other service API versions
59
+ };
60
+
61
+ var #{klass.downcase} = new AWS.#{klass}();
62
+ ```
63
+ DOCS
64
+ end
65
+
66
+ def find_example_operation(api)
67
+ list = api['operations'].keys.grep(/describe|list|get/)
68
+ list = api['operations'].keys if list.size == 0
69
+ method_name(list.first)
70
+ end
71
+ end
72
+
73
+ class MethodDocumentor
74
+
75
+ include Documentor
76
+
77
+ attr_reader :lines
78
+
79
+ def initialize(operation_name, operation, api, klass)
80
+ desc = documentation(operation)
81
+ desc ||= "Calls the #{method_name(operation_name, false)} API operation."
82
+ desc = desc.gsub(/^\s+/, '').strip
83
+
84
+ @lines = [desc, '']
85
+
86
+ ## @param tags
87
+
88
+ @lines << "@param params [Object]"
89
+ @lines += shapes(api, operation['input']).map {|line| " " + line }
90
+
91
+ ## @example tag
92
+
93
+ @lines << "@example Calling the #{method_name(operation_name)} operation"
94
+ @lines << generate_example(api, klass, method_name(operation_name),
95
+ operation['input']).split("\n").map {|line| " " + line }
96
+ @lines << ""
97
+
98
+ ## @callback tag
99
+
100
+ @lines << "@callback callback function(err, data)"
101
+ @lines << " Called when a response from the service is returned. If a"
102
+ @lines << " callback is not supplied, you must call {AWS.Request.send}"
103
+ @lines << " on the returned request object to initiate the request."
104
+ @lines << " @param err [Error] the error object returned from the request."
105
+ @lines << " Set to `null` if the request is successful."
106
+ @lines << " @param data [Object] the de-serialized data returned from"
107
+ @lines << " the request. Set to `null` if a request error occurs."
108
+
109
+ output = shapes(api, operation['output'])
110
+ output = output.map {|line| " " + line }
111
+ if output.size > 0
112
+ @lines << " The `data` object has the following properties:"
113
+ @lines << ""
114
+ @lines += output
115
+ end
116
+
117
+ ## @return tag
118
+
119
+ @lines << "@return [AWS.Request] a handle to the operation request for"
120
+ @lines << " subsequent event callback registration."
121
+
122
+ if operation['documentation_url']
123
+ @lines << "@see #{operation['documentation_url']}"
124
+ @lines << " #{api['serviceAbbreviation']} Documentation for #{operation_name}"
125
+ end
126
+ end
127
+
128
+ def shapes(api, rules)
129
+ rules = api['shapes'][rules['shape']] if rules && rules['shape']
130
+ if rules and rules['members']
131
+ rules['members'].map do |name, member_rules|
132
+ if member_rules['shape']
133
+ member_rules = api['shapes'][member_rules['shape']].merge(member_rules)
134
+ end
135
+ ShapeDocumentor.new(api, member_rules, :name => name).lines
136
+ end.flatten
137
+ else
138
+ []
139
+ end
140
+ end
141
+
142
+ def generate_example(api, klass, name, input)
143
+ ExampleShapeVisitor.new(api).example(klass, name, input)
144
+ end
145
+
146
+ end
147
+
148
+ class ExampleShapeVisitor
149
+ def initialize(api, required_only = false)
150
+ @api = api
151
+ @required_only = required_only
152
+ end
153
+
154
+ def example(klass, name, input)
155
+ lines = []
156
+ params = traverse(input)
157
+ params_var = ""
158
+ if params.strip.length > 0
159
+ lines << "var params = " + params + ";"
160
+ params_var = "params, "
161
+ end
162
+ lines << "#{klass.downcase}.#{name}(#{params_var}function(err, data) {"
163
+ lines << " if (err) console.log(err, err.stack); // an error occurred"
164
+ lines << " else console.log(data); // successful response"
165
+ lines << "});"
166
+ lines.join("\n")
167
+ end
168
+
169
+ def traverse(node, required = false)
170
+ return "" if node.nil?
171
+ node = @api['shapes'][node['shape']].merge(node) if node['shape']
172
+ if (meth = "visit_" + (node['type'] || 'string')) && respond_to?(meth)
173
+ return send(meth, node, required)
174
+ end
175
+ ""
176
+ end
177
+
178
+ def visit_structure(node, required = false)
179
+ required_map = (node['required'] || []).inject({}) {|h,k| h[k] = true; h }
180
+ lines = ["{" + (required ? " // required" : "")]
181
+ node['members'].sort_by {|n, v| [required_map[n] ? -1 : 1, n] }.each_with_index do |(key, value), index|
182
+ next if @required_only && !required_map[key]
183
+ value = @api['shapes'][value['shape']].merge(value) if value['shape']
184
+ lines << " #{key}: " + indent(traverse(value, required_map[key]), false) +
185
+ (index + 1 < node['members'].size ? "," : "") +
186
+ (required_map[key] && !%w(list map structure).include?(value['type']) ?
187
+ " // required" : "")
188
+ end
189
+ lines << "}"
190
+ lines.join("\n")
191
+ end
192
+
193
+ def visit_list(node, required = false)
194
+ lines = ["[" + (required ? " // required" : "")]
195
+ lines << indent(traverse(node['member'])) + ","
196
+ lines << " // ... more items ..."
197
+ lines << "]"
198
+ lines.join("\n")
199
+ end
200
+
201
+ def visit_map(node, required = false)
202
+ lines = ["{" + (required ? " // required" : "")]
203
+ lines << indent("someKey: " + traverse(node['value'])) + ","
204
+ lines << " // anotherKey: ..."
205
+ lines << "}"
206
+ lines.join("\n")
207
+ end
208
+
209
+ def visit_string(node, required = false)
210
+ value = node['enum'] ? node['enum'].join(' | ') : 'STRING_VALUE'
211
+ "'#{value}'"
212
+ end
213
+
214
+ def visit_integer(node, required = false)
215
+ "0"
216
+ end
217
+ alias visit_long visit_integer
218
+
219
+ def visit_float(node, required = false)
220
+ "0.0"
221
+ end
222
+ alias visit_double visit_float
223
+ alias visit_bigdecimal visit_float
224
+
225
+ def visit_boolean(node, required = false)
226
+ "true || false"
227
+ end
228
+
229
+ def visit_base64(node, required = false)
230
+ "new Buffer('...') || 'STRING_VALUE'"
231
+ end
232
+
233
+ def visit_binary(node, required = false)
234
+ value = "new Buffer('...') || 'STRING_VALUE'"
235
+ value += " || streamObject" if node['streaming']
236
+ value
237
+ end
238
+ alias visit_blob visit_binary
239
+
240
+ def visit_timestamp(node, required = false)
241
+ "new Date || 'Wed Dec 31 1969 16:00:00 GMT-0800 (PST)' || 123456789"
242
+ end
243
+
244
+ def indent(text, first_line = true, n = 2)
245
+ text = text.split(/\r?\n/).map {|l| "#{' ' * n}#{l}" }.join("\n")
246
+ text = text.sub(/\A\s+/, '') if !first_line
247
+ text
248
+ end
249
+ end
250
+
251
+ class ShapeDocumentor
252
+ include Documentor
253
+
254
+ attr_reader :name
255
+ attr_reader :rules
256
+ attr_reader :lines
257
+ attr_reader :nested_lines
258
+ attr_reader :prefix
259
+ attr_reader :type
260
+
261
+ def initialize(api, rules, options = {})
262
+ rules = api['shapes'][rules['shape']].merge(rules) if rules['shape']
263
+
264
+ @api = api
265
+ @rules = rules
266
+ @name = options[:name]
267
+ @prefix = options[:prefix] || ''
268
+ @required = !!options[:required]
269
+
270
+ @type =
271
+ case rules['type']
272
+ when 'structure' then 'map'
273
+ when 'list' then 'Array'
274
+ when 'map' then 'map'
275
+ when 'string', nil then 'String'
276
+ when 'integer' then 'Integer'
277
+ when 'long' then 'Integer'
278
+ when 'float' then 'Float'
279
+ when 'double' then 'Float'
280
+ when 'bigdecimal' then 'Float'
281
+ when 'boolean' then 'Boolean'
282
+ when 'base64' then 'Buffer, Typed Array, Blob, String'
283
+ when 'binary' then 'Buffer, Typed Array, Blob, String'
284
+ when 'blob' then 'Buffer, Typed Array, Blob, String'
285
+ when 'timestamp' then 'Date'
286
+ else raise "unhandled type: #{rules['type']}"
287
+ end
288
+
289
+ # TODO : update this format description once we add streaming uploads
290
+ @type += ', ReadableStream' if streaming?
291
+
292
+ @lines = []
293
+ @nested_lines = []
294
+
295
+ if structure?
296
+ required_map = (rules['required'] || []).inject({}) {|h,k| h[k] = true; h }
297
+ rules['members'].each_pair do |name, member_rules|
298
+ @nested_lines += child_shape(member_rules,
299
+ :name => name, :required => required_map[name]).lines
300
+ end
301
+ end
302
+
303
+ if list?
304
+ child = child_shape(rules['member'] || {}, :prefix => prefix)
305
+ @type << "<#{child.type}>"
306
+ @nested_lines += child.nested_lines
307
+ end
308
+
309
+ if map?
310
+
311
+ # sanity check, I don't think this should ever raise, but if it
312
+ # does we will have to document the key shape
313
+ key_child = child_shape(rules['key'] || {}, :prefix => prefix)
314
+ raise "unhandled map key type" if key_child.type != 'String'
315
+
316
+ child = child_shape(rules['value'] || {}, :prefix => prefix)
317
+ @type << "<#{child.type}>"
318
+ @nested_lines += child.nested_lines
319
+
320
+ end
321
+
322
+ @lines = ["#{prefix}* `#{name}` #{description}"]
323
+ @lines += @nested_lines
324
+
325
+ if rules['enum']
326
+ @lines << "#{prefix} Possible values include:"
327
+ @lines += rules['enum'].map{|v| "#{prefix} * `#{v.inspect}`" }
328
+ end
329
+
330
+ end
331
+
332
+ def streaming?
333
+ rules['streaming']
334
+ end
335
+
336
+ def structure?
337
+ rules['type'] == 'structure'
338
+ end
339
+
340
+ def list?
341
+ rules['type'] == 'list'
342
+ end
343
+
344
+ def map?
345
+ rules['type'] == 'map'
346
+ end
347
+
348
+ def description
349
+ text = []
350
+ if @required
351
+ text << "&mdash; **required** &mdash; (`#{@type}`)"
352
+ else
353
+ text << "&mdash; (`#{@type}`)"
354
+ end
355
+ if docs = documentation(rules)
356
+ text << " #{docs}"
357
+ end
358
+ text.join(' ')
359
+ end
360
+
361
+ private
362
+
363
+ def child_shape(rules, options = {})
364
+ ShapeDocumentor.new(@api, rules, { :prefix => prefix + ' ' }.merge(options))
365
+ end
366
+ end
@@ -0,0 +1,230 @@
1
+ require 'json'
2
+ require_relative './model_documentor'
3
+
4
+ $APIS_DIR = File.expand_path(File.dirname(__FILE__) +
5
+ "/../../../vendor/apis/apis")
6
+ $API_FILE_MATCH = /(?:^|\/)([^\/-]+)-(\d+-\d+-\d+)\.full\.json$/
7
+
8
+ YARD::Tags::Library.define_tag 'Service', :service
9
+ YARD::Tags::Library.define_tag 'Waiter Resource States', :waiter
10
+ YARD::Tags::Library.visible_tags << :waiter
11
+ YARD::Templates::Engine.register_template_path(File.dirname(__FILE__) + '/templates')
12
+
13
+ class YARD::CodeObjects::ClassObject
14
+ def title
15
+ path.gsub(/_(\d{4})(\d{2})(\d{2})/, ' (\1-\2-\3)')
16
+ end
17
+
18
+ def name(prefix = false)
19
+ return super unless prefix
20
+ @name.to_s.gsub(/_(\d{4})(\d{2})(\d{2})/, ' (\1-\2-\3)')
21
+ end
22
+ end
23
+
24
+ module YARD::Registry
25
+ class << self
26
+ @@parsed_apis = false
27
+
28
+ def register_aws(object)
29
+ register_without_aws(object)
30
+
31
+ if !@@parsed_apis && object.path == 'AWS'
32
+ @@parsed_apis = true
33
+ ApiDocumentor.new(object).run
34
+ end
35
+ end
36
+ alias register_without_aws register
37
+ alias register register_aws
38
+ end
39
+ end
40
+
41
+ class WaiterObject < YARD::CodeObjects::Base
42
+ attr_accessor :operation
43
+
44
+ def parameters; [] end
45
+ def property_type; 'function' end
46
+ def sep; '$waiter$' end
47
+ def title; name.to_s end
48
+ end
49
+
50
+ class ApiDocumentor
51
+ def initialize(root = :root)
52
+ @root = root
53
+ end
54
+
55
+ def run
56
+ build_map.each do |service, files|
57
+ files.sort.each.with_index do |file, i|
58
+ generate_api(file, !(i == files.length - 1))
59
+ end
60
+ end
61
+ end
62
+
63
+ def build_map
64
+ map = {}
65
+ Dir.entries($APIS_DIR).each do |file|
66
+ if file =~ $API_FILE_MATCH
67
+ (map[$1] ||= []).push(File.join($APIS_DIR, file))
68
+ end
69
+ end
70
+ map
71
+ end
72
+
73
+ def generate_api(file, version_suffix = true)
74
+ _, klass, version = *file.match($API_FILE_MATCH)
75
+ identifier, klass = *class_info_for(klass.downcase)
76
+ name = version_suffix ? klass + '_' + version.gsub('-', '') : klass
77
+
78
+ log.progress("Parsing AWS.#{klass} (#{version})")
79
+ svc = YARD::CodeObjects::ClassObject.new(@root, name)
80
+
81
+ model = load_model(file)
82
+ add_class_documentation(svc, klass, model, version)
83
+ add_methods(svc, klass, model)
84
+ add_waiters(svc, klass, model)
85
+
86
+ svc.docstring.add_tag(YARD::Tags::Tag.new(:service, identifier))
87
+ svc.docstring.add_tag(YARD::Tags::Tag.new(:version, version))
88
+ svc.superclass = 'AWS.Service'
89
+ end
90
+
91
+ def add_class_documentation(service, klass, model, api_version)
92
+ docstring = ModelDocumentor.new(klass, model).lines.join("\n")
93
+ parser = YARD::Docstring.parser
94
+ parser.parse(docstring, service)
95
+ service.docstring = parser.to_docstring
96
+
97
+ # constructor
98
+ ctor = YARDJS::CodeObjects::PropertyObject.new(service, 'constructor')
99
+ ctor.property_type = :function
100
+ ctor.parameters = [['options', '{}']]
101
+ ctor.signature = "constructor(options = {})"
102
+ ctor.docstring = <<-eof
103
+ Constructs a service object. This object has one method for each
104
+ API operation.
105
+
106
+ @example Constructing a #{klass} object
107
+ var #{klass.downcase} = new AWS.#{klass}({apiVersion: '#{api_version}'});
108
+
109
+ @option options [String] endpoint The endpoint URI to send requests
110
+ to. The default endpoint is built from the configured `region`.
111
+ The endpoint should be a string like `'https://{service}.{region}.amazonaws.com'`.
112
+ @option (see AWS.Config.constructor)
113
+ eof
114
+
115
+ # endpoint attribute
116
+ endpoint = YARDJS::CodeObjects::PropertyObject.new(service, 'endpoint')
117
+ endpoint.docstring = <<-eof
118
+ @return [AWS.Endpoint] an Endpoint object representing the endpoint URL
119
+ for service requests.
120
+ eof
121
+
122
+ end
123
+
124
+ def add_methods(service, klass, model)
125
+ model['operations'].each_pair do |name, operation|
126
+ meth = YARDJS::CodeObjects::PropertyObject.new(service, name[0].downcase + name[1..-1])
127
+ docs = MethodDocumentor.new(name, operation, model, klass).lines.join("\n")
128
+ meth.property_type = :function
129
+ meth.parameters = [['params', '{}'], ['callback', nil]]
130
+ meth.signature = "#{name}(params = {}, [callback])"
131
+ meth.dynamic = true
132
+ meth.docstring = docs
133
+ end
134
+ end
135
+
136
+ def add_waiters(service, klass, model)
137
+ return unless waiters = model['waiters']
138
+
139
+ wait_for = YARDJS::CodeObjects::PropertyObject.new(service, 'waitFor')
140
+ wait_for.property_type = :function
141
+ wait_for.parameters = [['state', nil], ['params', '{}'], ['callback', nil]]
142
+ wait_for.signature = "waitFor(state, params = {}, [callback])"
143
+ wait_for.dynamic = true
144
+ wait_for.docstring = <<-eof
145
+ Waits for a given #{service.name} resource. The final callback or
146
+ {AWS.Request~complete 'complete' event} will be fired only when the resource
147
+ is either in its final state or the waiter has timed out and stopped polling
148
+ for the final state.
149
+
150
+ @param state [String] the resource state to wait for. Available states for this
151
+ service are listed in "Waiter Resource States" below.
152
+ @param params [map] a list of parameters for the given state. See each waiter
153
+ resource state for required parameters.
154
+ @callback callback function(err, data)
155
+ Callback containing error and data information. See the respective resource
156
+ state for the expected error or data information.
157
+
158
+ If the waiter times out its requests, it will return a `ResourceNotReady`
159
+ error.
160
+ @return [AWS.Request] a handle to the operation request for subsequent event
161
+ callback registration.
162
+ eof
163
+
164
+ waiters.keys.each do |name|
165
+ next if name =~ /^_/
166
+ config = load_waiter(waiters, name)
167
+ operation_name = config['operation'][0,1].downcase + config['operation'][1..-1]
168
+ name = name[0,1].downcase + name[1..-1]
169
+ obj = WaiterObject.new(service, name)
170
+ obj.operation = YARDJS::CodeObjects::PropertyObject.new(service, operation_name)
171
+ obj.operation.docstring.add_tag YARD::Tags::Tag.new(:waiter, "{#{obj.path}}")
172
+ obj.docstring = <<-eof
173
+ Waits for the `#{name}` state by periodically calling the underlying
174
+ {#{operation_name}} operation every #{config['interval']} seconds
175
+ (at most #{config['maxAttempts']} times).
176
+
177
+ @api experimental
178
+ @callback (see #{obj.operation.path})
179
+ @param (see #{obj.operation.path})
180
+ @return (see #{obj.operation.path})
181
+ @see #{operation_name}
182
+ eof
183
+
184
+ waiter_ex = ExampleShapeVisitor.new(model, true).example(
185
+ service.name.to_s.downcase, 'waitFor', model['operations'][config['operation']]['input'])
186
+ waiter_ex = waiter_ex.sub(/\.waitFor\(/, ".waitFor('#{name}', ")
187
+ waiter_ex = waiter_ex.sub(/\{\s+\}/, "{\n // ... input parameters ...\n}")
188
+ obj.docstring.add_tag YARD::Tags::Tag.new(:example, waiter_ex, nil,
189
+ "Waiting for the #{name} state")
190
+ unless wait_for.docstring.tag(:example)
191
+ wait_for.docstring.add_tag YARD::Tags::Tag.new(:example, waiter_ex, nil,
192
+ "Waiting for the #{name} state")
193
+ end
194
+
195
+ wait_for.docstring.add_tag YARD::Tags::Tag.new(:waiter, "{#{obj.path}}")
196
+ end
197
+ end
198
+
199
+ def load_waiter(waiters, name)
200
+ waiter = waiters[name]
201
+ if waiter['extends']
202
+ waiter = waiter.merge(load_waiter(waiters, waiter['extends']))
203
+ elsif name != '__default__'
204
+ waiter = waiter.merge(load_waiter(waiters, '__default__'))
205
+ end
206
+ waiter
207
+ end
208
+
209
+ def load_model(file)
210
+ json = JSON.parse(File.read(file))
211
+
212
+ waiters_file = file.sub(/\.full\.json$/, '.waiters.json')
213
+ if File.exist? waiters_file
214
+ json = json.merge(JSON.parse(File.read(waiters_file)))
215
+ end
216
+ json
217
+ end
218
+
219
+ def class_info_for(prefix)
220
+ @info ||= JSON.parse(File.read(File.join($APIS_DIR, '../metadata.json')))
221
+ @info.each do |identifier, info|
222
+ iprefix = info['prefix'] || identifier
223
+ if prefix == iprefix
224
+ return [identifier, info['name']]
225
+ end
226
+ end
227
+
228
+ raise "Unknown class name for #{prefix}"
229
+ end
230
+ end
@@ -0,0 +1,9 @@
1
+ def init
2
+ super
3
+ @waiters = object.children.select {|x| x.type == :waiter }
4
+ if @waiters.size > 0
5
+ sections.place(:waiter_summary).before_any(:constant_summary)
6
+ sections.push(:waiter_details_list, [T('waiter_details')])
7
+ end
8
+ end
9
+
@@ -0,0 +1,7 @@
1
+ <div id="waiter_details" class="waiter_details_list method_details_list">
2
+ <h2>Waiter Resource Details</h2>
3
+
4
+ <% @waiters.each_with_index do |waiter, i| %>
5
+ <%= yieldall :object => waiter, :owner => object, :index => i %>
6
+ <% end %>
7
+ </div>
@@ -0,0 +1,7 @@
1
+ <h2>Waiter Resource States</h2>
2
+ <p>This service supports a list of resource states that can be polled using
3
+ the <%= resolve_links "{waitFor}" %> method. The resource states are:</p>
4
+
5
+ <p class="children">
6
+ <%= @waiters.map {|waiter| linkify waiter }.join(", ") %>
7
+ </p>
@@ -0,0 +1,4 @@
1
+ <p class="note experimental private">
2
+ This <%= object.property_type %> is part of an <strong>experimental API</strong>.
3
+ You can use this <%= object.property_type %>, but it may be removed or be changed in the future.
4
+ </p>
@@ -0,0 +1,9 @@
1
+ def init
2
+ super
3
+ sections.place(:experimental).before_any(:private)
4
+ end
5
+
6
+ def experimental
7
+ return unless object.has_tag?(:api) && object.tag(:api).text == 'experimental'
8
+ erb(:experimental)
9
+ end
@@ -0,0 +1,6 @@
1
+ #full_list li.expander { color: #038; }
2
+ .service_list { list-style: none; padding: 0; margin: 0; font-size: 1.1em; clear: both; }
3
+ .service_list li { border-bottom: 1px solid #ccc; padding-bottom: 5px; margin-bottom: 7px; width: 40%; float: left; margin-right: 7px; }
4
+ #listing .service_list li small { font-size: 0.9em; }
5
+ .clear { clear: both; }
6
+ #capabilities-banner { margin-bottom: 12px; font-weight: bold; padding: 12px; }