presidium 4.0.0 → 4.0.6

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.
@@ -24,6 +24,7 @@ const DynamoDBAttributeValueJSON =
24
24
  require('./internal/DynamoDBAttributeValueJSON')
25
25
  const hashJSON = require('./internal/hashJSON')
26
26
  const sleep = require('./internal/sleep')
27
+ const retryHTTPRequest = require('./internal/retryHTTPRequest')
27
28
  const createExpressionAttributeNames =
28
29
  require('./internal/createExpressionAttributeNames')
29
30
  const createExpressionAttributeValues =
@@ -97,9 +98,9 @@ class DynamoDBGlobalSecondaryIndex {
97
98
  this.key = options.key
98
99
  this.name = DynamoDBIndexname(this.key)
99
100
 
100
- this.accessKeyId = options.accessKeyId ?? ''
101
- this.secretAccessKey = options.secretAccessKey ?? ''
102
- this.region = options.region ?? ''
101
+ this.accessKeyId = options.accessKeyId
102
+ this.secretAccessKey = options.secretAccessKey
103
+ this.region = options.region
103
104
  this.apiVersion = '2012-08-10'
104
105
 
105
106
  this.endpoint = `dynamodb.${this.region}.amazonaws.com`
@@ -227,7 +228,7 @@ class DynamoDBGlobalSecondaryIndex {
227
228
  }
228
229
  })
229
230
 
230
- return this.http[method](url, { headers, body: payload })
231
+ return retryHTTPRequest(this.http, method, url, { headers, body: payload })
231
232
  }
232
233
 
233
234
  /**
package/DynamoDBStream.js CHANGED
@@ -16,6 +16,7 @@ const AwsAuthorization = require('./internal/AwsAuthorization')
16
16
  const AmzDate = require('./internal/AmzDate')
17
17
  const Readable = require('./Readable')
18
18
  const sleep = require('./internal/sleep')
19
+ const retryHTTPRequest = require('./internal/retryHTTPRequest')
19
20
  const dynamoDBStreamGetStreamsIterator =
20
21
  require('./internal/dynamoDBStreamGetStreamsIterator')
21
22
  const dynamoDBStreamGetShardsIterator =
@@ -115,9 +116,9 @@ class DynamoDBStream {
115
116
  this.ListStreamsLimit = options.ListStreamsLimit ?? 100
116
117
  this.JSON = options.JSON ?? false
117
118
 
118
- this.accessKeyId = options.accessKeyId ?? ''
119
- this.secretAccessKey = options.secretAccessKey ?? ''
120
- this.region = options.region ?? ''
119
+ this.accessKeyId = options.accessKeyId
120
+ this.secretAccessKey = options.secretAccessKey
121
+ this.region = options.region
121
122
  this.apiVersion = '2012-08-10'
122
123
 
123
124
  this.endpoint = `dynamodb.${this.region}.amazonaws.com`
@@ -238,7 +239,7 @@ class DynamoDBStream {
238
239
  }
239
240
  })
240
241
 
241
- return this.http[method](url, { headers, body: payload })
242
+ return retryHTTPRequest(this.http, method, url, { headers, body: payload })
242
243
  }
243
244
 
244
245
  /**
@@ -296,7 +297,7 @@ class DynamoDBStream {
296
297
  }
297
298
  })
298
299
 
299
- return this.streamsHttp[method](url, { headers, body: payload })
300
+ return retryHTTPRequest(this.streamsHttp, method, url, { headers, body: payload })
300
301
  }
301
302
 
302
303
  /**
package/DynamoDBTable.js CHANGED
@@ -25,6 +25,7 @@ const AwsError = require('./internal/AwsError')
25
25
  const hashJSON = require('./internal/hashJSON')
26
26
  const sleep = require('./internal/sleep')
27
27
  const join = require('./internal/join')
28
+ const retryHTTPRequest = require('./internal/retryHTTPRequest')
28
29
  const createExpressionAttributeNames =
29
30
  require('./internal/createExpressionAttributeNames')
30
31
  const createExpressionAttributeValues =
@@ -93,9 +94,9 @@ class DynamoDBTable {
93
94
  this.name = options.name
94
95
  this.key = options.key
95
96
 
96
- this.accessKeyId = options.accessKeyId ?? ''
97
- this.secretAccessKey = options.secretAccessKey ?? ''
98
- this.region = options.region ?? ''
97
+ this.accessKeyId = options.accessKeyId
98
+ this.secretAccessKey = options.secretAccessKey
99
+ this.region = options.region
99
100
  this.apiVersion = '2012-08-10'
100
101
 
101
102
  this.endpoint = `dynamodb.${this.region}.amazonaws.com`
@@ -216,7 +217,7 @@ class DynamoDBTable {
216
217
  }
217
218
  })
218
219
 
219
- return this.http[method](url, { headers, body: payload })
220
+ return retryHTTPRequest(this.http, method, url, { headers, body: payload })
220
221
  }
221
222
 
222
223
  /**
package/ECR.js CHANGED
@@ -13,6 +13,7 @@ const AwsAuthorization = require('./internal/AwsAuthorization')
13
13
  const AwsError = require('./internal/AwsError')
14
14
  const userAgent = require('./userAgent')
15
15
  const Readable = require('./Readable')
16
+ const retryHTTPRequest = require('./internal/retryHTTPRequest')
16
17
 
17
18
  /**
18
19
  * @name ECR
@@ -45,9 +46,9 @@ const Readable = require('./Readable')
45
46
  */
46
47
  class ECR {
47
48
  constructor(options) {
48
- this.accessKeyId = options.accessKeyId ?? ''
49
- this.secretAccessKey = options.secretAccessKey ?? ''
50
- this.region = options.region ?? ''
49
+ this.accessKeyId = options.accessKeyId
50
+ this.secretAccessKey = options.secretAccessKey
51
+ this.region = options.region
51
52
  this.apiVersion = '2015-09-21'
52
53
 
53
54
  this.endpoint = `ecr.${this.region}.amazonaws.com`
@@ -112,7 +113,7 @@ class ECR {
112
113
  }
113
114
  })
114
115
 
115
- return this.http[method](url, { headers, body: payload })
116
+ return retryHTTPRequest(this.http, method, url, { headers, body: payload })
116
117
  }
117
118
 
118
119
  /**
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  const https = require('https')
9
+ const EventEmitter = require('events')
9
10
  const os = require('os')
10
11
  const fs = require('fs')
11
12
  const path = require('path')
@@ -15,15 +16,12 @@ const extract = require('extract-zip')
15
16
  const HTTP = require('./HTTP')
16
17
  const XML = require('./XML')
17
18
  const Readable = require('./Readable')
19
+ const getPlatform = require('./internal/getPlatform')
18
20
  const walk = require('./internal/walk')
19
21
  const sleep = require('./internal/sleep')
20
-
21
- async function getChromeVersions() {
22
- const http = new HTTP()
23
- const response = await http.GET('https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json')
24
- const data = await Readable.JSON(response)
25
- return data
26
- }
22
+ const getChromeUrl = require('./internal/getChromeUrl')
23
+ const getAbsoluteFilePath = require('./internal/getAbsoluteFilePath')
24
+ const getChromeBinaryOrExecutableFilePath = require('./internal/getChromeBinaryOrExecutableFilePath')
27
25
 
28
26
  function updateConsoleLog(message, platform) {
29
27
  readline.cursorTo(process.stdout, 0, undefined);
@@ -31,66 +29,16 @@ function updateConsoleLog(message, platform) {
31
29
  process.stdout.write(message);
32
30
  }
33
31
 
34
- function getPlatform() {
35
- let platform = os.platform()
36
- if (platform == 'darwin') {
37
- platform = 'mac'
38
- }
39
- const arch = os.arch()
40
-
41
- if (platform == 'mac') {
42
- platform = `${platform}-${arch}`
43
- }
44
- else if (platform == 'win32') {
45
- platform = `win${arch.slice(1)}`
46
- }
47
- else {
48
- platform = `${platform}${arch.slice(1)}`
49
- }
50
-
51
- return platform
52
- }
53
-
54
- async function getChromeUrl() {
32
+ async function installChrome() {
55
33
  const platform = getPlatform()
34
+ const url = await getChromeUrl.call(this, platform)
56
35
 
57
- let url
58
- if (['stable', 'beta', 'dev', 'canary'].includes(this.chromeVersion)) {
59
- const chromeVersions = await getChromeVersions()
60
- const channel = `${this.chromeVersion[0].toUpperCase()}${this.chromeVersion.slice(1)}`
61
- const chromeVersionNumber = chromeVersions.channels[channel].version
62
- url = `https://storage.googleapis.com/chrome-for-testing-public/${chromeVersionNumber}/${platform}/chrome-${platform}.zip`
63
- } else {
64
- const chromeVersionNumber = this.chromeVersion
65
- url = `https://storage.googleapis.com/chrome-for-testing-public/${chromeVersionNumber}/${platform}/chrome-${platform}.zip`
66
- }
67
-
68
- return url
69
- }
36
+ let filepath = `${this.chromeDir}/${url.replace('https://storage.googleapis.com/chrome-for-testing-public/', '')}`
37
+ filepath = getAbsoluteFilePath(filepath, platform)
70
38
 
71
- async function installChrome() {
72
- const platform = getPlatform()
73
39
  const delimiter = platform.startsWith('win') ? '\\' : '/'
74
- const url = await getChromeUrl.call(this)
75
-
76
- let filepath = `${this.chromeDir}${delimiter}${url.replace('https://storage.googleapis.com/chrome-for-testing-public/', '')}`
77
- if (platform.startsWith('win')) {
78
- filepath = filepath.replace(/\//g, '\\')
79
- if (!filepath.startsWith(`${__dirname[0]}:`)) {
80
- filepath = path.join(process.cwd(), filepath)
81
- }
82
- } else if (!filepath.startsWith('/')) {
83
- filepath = path.join(process.cwd(), filepath)
84
- }
40
+ const parentDir = `${filepath.split(delimiter).slice(0, -1).join(delimiter)}`
85
41
 
86
- let parentDir = `${filepath.split(delimiter).slice(0, -1).join(delimiter)}`
87
- if (platform.startsWith('win')) {
88
- if (!filepath.startsWith(`${__dirname[0]}:`)) {
89
- parentDir = path.join(process.cwd(), parentDir)
90
- }
91
- } else if (!parentDir.startsWith('/')) {
92
- parentDir = path.join(process.cwd(), parentDir)
93
- }
94
42
  await fs.promises.mkdir(parentDir, { recursive: true })
95
43
 
96
44
  const http = new HTTP()
@@ -113,27 +61,26 @@ async function installChrome() {
113
61
  fileStream.write(chunk)
114
62
  })
115
63
 
64
+ response.on('end', () => {
65
+ fileStream.end()
66
+ })
67
+
116
68
  let resolve
117
69
  const promise = new Promise(_resolve => {
118
70
  resolve = _resolve
119
71
  })
120
- response.on('end', () => {
72
+ fileStream.on('finish', () => {
121
73
  resolve()
122
74
  })
123
75
  await promise
124
76
 
125
77
  console.log('Extracting', filepath)
126
- try {
127
- await extract(filepath, { dir: parentDir })
128
- } catch (_error) {
129
- await sleep(1000)
130
- await extract(filepath, { dir: parentDir })
131
- }
78
+ await extract(filepath, { dir: parentDir })
132
79
  }
133
80
 
134
81
  async function getChromeFilepath() {
135
82
  const platform = getPlatform()
136
- const url = await getChromeUrl.call(this)
83
+ const url = await getChromeUrl.call(this, platform)
137
84
  const filepath = `${this.chromeDir}/${url.replace('https://storage.googleapis.com/chrome-for-testing-public/', '')}`
138
85
  const parentDir = `${filepath.split('/').slice(0, -1).join('/')}`
139
86
 
@@ -144,16 +91,13 @@ async function getChromeFilepath() {
144
91
  }
145
92
 
146
93
  for await (const filepath of walk(parentDir)) {
147
- if (platform.startsWith('mac') && filepath.endsWith('Google Chrome for Testing')) {
148
- return filepath
149
- }
150
- if (platform.startsWith('linux') && filepath.endsWith('chrome')) {
151
- return filepath
152
- }
153
- if (platform.startsWith('win') && filepath.endsWith('chrome.exe')) {
154
- return filepath
94
+ const chromeBinaryOrExecutableFilePath =
95
+ getChromeBinaryOrExecutableFilePath(filepath, platform)
96
+ if (chromeBinaryOrExecutableFilePath) {
97
+ return chromeBinaryOrExecutableFilePath
155
98
  }
156
99
  }
100
+ throw new Error('chrome binary or executable not found.')
157
101
  } catch (error) {
158
102
  if (error.code == 'ENOENT') {
159
103
  await installChrome.call(this)
@@ -162,8 +106,6 @@ async function getChromeFilepath() {
162
106
  }
163
107
  throw error
164
108
  }
165
-
166
- throw new Error('unable to find Google Chrome for Testing executable.')
167
109
  }
168
110
 
169
111
  /**
@@ -220,8 +162,9 @@ async function getChromeFilepath() {
220
162
  * sudo apt-get update && sudo apt-get install -y libcairo2 libpango-1.0-0 libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libatspi2.0-0 libcups2 libdrm-dev libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm-dev libasound2-dev
221
163
  * ```
222
164
  */
223
- class GoogleChromeForTesting {
165
+ class GoogleChromeForTesting extends EventEmitter {
224
166
  constructor(options = {}) {
167
+ super()
225
168
  this.chromeVersion = options.chromeVersion ?? 'stable'
226
169
  this.chromeDir = options.chromeDir ?? 'google-chrome-for-testing'
227
170
  this.remoteDebuggingPort = options.remoteDebuggingPort ?? 9222
@@ -295,8 +238,7 @@ class GoogleChromeForTesting {
295
238
  })
296
239
 
297
240
  cmd.on('error', error => {
298
- console.error(error)
299
- process.exit(1)
241
+ this.emit('error', error)
300
242
  })
301
243
 
302
244
  cmd.on('exit', code => {
package/HTTP.js CHANGED
@@ -141,7 +141,7 @@ class HTTP {
141
141
  resolve(response)
142
142
  })
143
143
 
144
- /* TODO remove this an closeConnections from codebase (breaking)
144
+ /* TODO remove this and closeConnections from codebase (breaking)
145
145
  request.on('socket', socket => {
146
146
  this._sockets.add(socket)
147
147
  })
package/S3Bucket.js CHANGED
@@ -14,7 +14,9 @@ const AwsAuthorization = require('./internal/AwsAuthorization')
14
14
  const AmzDate = require('./internal/AmzDate')
15
15
  const AwsError = require('./internal/AwsError')
16
16
  const parseURL = require('./internal/parseURL')
17
+ const retryHTTPRequest = require('./internal/retryHTTPRequest')
17
18
  const createS3DeleteObjectError = require('./internal/createS3DeleteObjectError')
19
+ const createS3DeleteAllObjectsAggregateError = require('./internal/createS3DeleteAllObjectsAggregateError')
18
20
  const XML = require('./XML')
19
21
  const HTMLEntities = require('html-entities')
20
22
  const encodeURIComponentRFC3986 = require('./internal/encodeURIComponentRFC3986')
@@ -89,9 +91,9 @@ class S3Bucket {
89
91
  constructor(options) {
90
92
  this.name = options.name
91
93
 
92
- this.accessKeyId = options.accessKeyId ?? ''
93
- this.secretAccessKey = options.secretAccessKey ?? ''
94
- this.region = options.region ?? ''
94
+ this.accessKeyId = options.accessKeyId
95
+ this.secretAccessKey = options.secretAccessKey
96
+ this.region = options.region
95
97
  this.apiVersion = '2012-08-10'
96
98
 
97
99
  this.host0 = 's3.amazonaws.com'
@@ -255,7 +257,7 @@ class S3Bucket {
255
257
  headers: authorizationHeaders,
256
258
  })
257
259
 
258
- return this.http0[method](url, { headers, body })
260
+ return retryHTTPRequest(this.http0, method, url, { headers, body })
259
261
  }
260
262
 
261
263
  /**
@@ -319,7 +321,7 @@ class S3Bucket {
319
321
  headers: authorizationHeaders,
320
322
  })
321
323
 
322
- return this.http1[method](url, { headers, body })
324
+ return retryHTTPRequest(this.http1, method, url, { headers, body })
323
325
  }
324
326
 
325
327
  // _putBucketEncryption() -> Promise<>
@@ -2242,15 +2244,9 @@ class S3Bucket {
2242
2244
  }
2243
2245
 
2244
2246
  if (response1.Errors.length > 0) {
2245
- const errors = response1.Errors.map(({ Key, VersionId, Code, Message }) => {
2246
- if (VersionId) {
2247
- return new Error(`${Key} (VersionId ${VersionId}): ${Code}: ${Message}`)
2248
- }
2249
- return new Error(`${Key}: ${Code}: ${Message}`)
2250
- })
2247
+ const errors = response1.Errors.map(createS3DeleteObjectError)
2251
2248
  throw new AggregateError(errors)
2252
2249
  }
2253
-
2254
2250
  }
2255
2251
 
2256
2252
  let versions = await this.listObjectVersions({ MaxKeys: BatchSize }).then(get('Versions'))
@@ -2271,7 +2267,6 @@ class S3Bucket {
2271
2267
  const errors = response1.Errors.map(createS3DeleteObjectError)
2272
2268
  throw new AggregateError(errors)
2273
2269
  }
2274
-
2275
2270
  }
2276
2271
 
2277
2272
  let deleteMarkers = await this.listObjectVersions({ MaxKeys: BatchSize }).then(get('DeleteMarkers'))
@@ -2292,7 +2287,6 @@ class S3Bucket {
2292
2287
  const errors = response1.Errors.map(createS3DeleteObjectError)
2293
2288
  throw new AggregateError(errors)
2294
2289
  }
2295
-
2296
2290
  }
2297
2291
 
2298
2292
  return response
package/SecretsManager.js CHANGED
@@ -15,6 +15,8 @@ const userAgent = require('./userAgent')
15
15
  const Readable = require('./Readable')
16
16
  const handleAwsResponse = require('./internal/handleAwsResponse')
17
17
  const retryableErrorNames = require('./internal/retryableErrorNames')
18
+ const retryHTTPRequest = require('./internal/retryHTTPRequest')
19
+ const sleep = require('./internal/sleep')
18
20
 
19
21
  /**
20
22
  * @name SecretsManager
@@ -48,9 +50,9 @@ const retryableErrorNames = require('./internal/retryableErrorNames')
48
50
  */
49
51
  class SecretsManager {
50
52
  constructor(options) {
51
- this.accessKeyId = options.accessKeyId ?? ''
52
- this.secretAccessKey = options.secretAccessKey ?? ''
53
- this.region = options.region ?? ''
53
+ this.accessKeyId = options.accessKeyId
54
+ this.secretAccessKey = options.secretAccessKey
55
+ this.region = options.region
54
56
  this.apiVersion = '2017-10-17'
55
57
 
56
58
  this.endpoint = `secretsmanager.${this.region}.amazonaws.com`
@@ -114,7 +116,54 @@ class SecretsManager {
114
116
  }
115
117
  })
116
118
 
117
- return this.http[method](url, { headers, body: payload })
119
+ return retryHTTPRequest(this.http, method, url, { headers, body: payload })
120
+ }
121
+
122
+ // _createSecret(name string, secretString string) -> Promise<{
123
+ // ARN: string,
124
+ // Name: string,
125
+ // VersionId: string,
126
+ // }>
127
+ async _createSecret(name, secretString) {
128
+ const payload = JSON.stringify({
129
+ ClientRequestToken: crypto.randomUUID(),
130
+ Name: name,
131
+ SecretString: secretString,
132
+ })
133
+
134
+ const response = await this._awsRequest('POST', '/', 'CreateSecret', payload)
135
+
136
+ if (response.ok) {
137
+ const data = await Readable.JSON(response)
138
+ return data
139
+ }
140
+
141
+ throw new AwsError(await Readable.Text(response), response.status)
142
+ }
143
+
144
+ // _createSecret(name string, secretString string) -> Promise<{
145
+ // ARN: string,
146
+ // Name: string,
147
+ // VersionId: string,
148
+ // }>
149
+ async _updateSecret(name, secretString) {
150
+ const secret = await this.getSecret(name)
151
+
152
+ const payload = JSON.stringify({
153
+ ClientRequestToken: crypto.randomUUID(),
154
+ SecretId: secret.ARN,
155
+ SecretString: secretString,
156
+ })
157
+ const updateSecretResponse =
158
+ await this._awsRequest('POST', '/', 'UpdateSecret', payload)
159
+
160
+ return handleAwsResponse.call(
161
+ this,
162
+ updateSecretResponse,
163
+ this.putSecret,
164
+ name,
165
+ secretString
166
+ )
118
167
  }
119
168
 
120
169
  /**
@@ -151,50 +200,19 @@ class SecretsManager {
151
200
  * ```
152
201
  */
153
202
  async putSecret(name, secretString) {
154
- const createSecretPayload = JSON.stringify({
155
- ClientRequestToken: crypto.randomUUID(),
156
- Name: name,
157
- SecretString: secretString,
158
- })
159
- const createSecretResponse =
160
- await this._awsRequest('POST', '/', 'CreateSecret', createSecretPayload)
161
-
162
- if (createSecretResponse.ok) {
163
- const data = await Readable.JSON(createSecretResponse)
203
+ try {
204
+ const data = await this._createSecret(name, secretString)
164
205
  return data
206
+ } catch (error) {
207
+ if (error.name == 'ResourceExistsException') {
208
+ return this._updateSecret(name, secretString)
209
+ } else if (retryableErrorNames.includes(error.name)) {
210
+ await sleep(1000)
211
+ return this.putSecret.call(this, name, secretString)
212
+ } else {
213
+ throw error
214
+ }
165
215
  }
166
-
167
- const createSecretAwsError = new AwsError(
168
- await Readable.Text(createSecretResponse),
169
- createSecretResponse.status
170
- )
171
-
172
- if (createSecretAwsError.name == 'ResourceExistsException') {
173
- // continue
174
- } else if (retryableErrorNames.includes(createSecretAwsError.name)) {
175
- await sleep(1000)
176
- return putSecret.call(this, name, secretString)
177
- } else {
178
- throw createSecretAwsError
179
- }
180
-
181
- const secret = await this.getSecret(name)
182
-
183
- const updateSecretPayload = JSON.stringify({
184
- ClientRequestToken: crypto.randomUUID(),
185
- SecretId: secret.ARN,
186
- SecretString: secretString,
187
- })
188
- const updateSecretResponse =
189
- await this._awsRequest('POST', '/', 'UpdateSecret', updateSecretPayload)
190
-
191
- return handleAwsResponse.call(
192
- this,
193
- updateSecretResponse,
194
- this.putSecret,
195
- name,
196
- secretString
197
- )
198
216
  }
199
217
 
200
218
  /**
@@ -0,0 +1,16 @@
1
+ // createS3DeleteAllObjectsAggregateError(Errors Array<{ Key: string, VersionId: string, Code: string, Message: string }>) -> AggregateError
2
+ function createS3DeleteAllObjectsAggregateError(Errors) {
3
+ const errors = Errors.map(({ Key, VersionId, Code, Message }) => {
4
+ if (VersionId) {
5
+ const error = new Error(`${Key}/${VersionId}: ${Message}`)
6
+ error.name = Code
7
+ return error
8
+ }
9
+ const error = new Error(`${Key}: ${Message}`)
10
+ error.name = Code
11
+ return error
12
+ })
13
+ return new AggregateError(errors)
14
+ }
15
+
16
+ module.exports = createS3DeleteAllObjectsAggregateError
@@ -0,0 +1,50 @@
1
+ const Test = require('thunk-test')
2
+ const createS3DeleteAllObjectsAggregateError = require('./createS3DeleteAllObjectsAggregateError')
3
+
4
+ const test = new Test('createS3DeleteAllObjectsAggregateError', createS3DeleteAllObjectsAggregateError)
5
+
6
+ function createError(name, message) {
7
+ const error = new Error(message)
8
+ error.name = name
9
+ return error
10
+ }
11
+
12
+ test.case([
13
+ {
14
+ Key: 'testkey1',
15
+ Code: 'AccessDenied',
16
+ Message: 'Access Denied',
17
+ },
18
+ {
19
+ Key: 'testkey1',
20
+ Code: 'AllAccessDisabled',
21
+ Message: 'All access to this Amazon S3 resource has been disabled. Contact AWS Support for further assistance.',
22
+ },
23
+ ], new AggregateError([
24
+ createError('AccessDenied', 'testkey1: Access Denied'),
25
+ createError('AllAccessDisabled', 'testkey1: All access to this Amazon S3 resource has been disabled. Contact AWS Support for further assistance.'),
26
+ ]))
27
+
28
+ test.case([
29
+ {
30
+ Key: 'testkey1',
31
+ VersionId: '1',
32
+ Code: 'AccessDenied',
33
+ Message: 'Access Denied',
34
+ },
35
+ {
36
+ Key: 'testkey1',
37
+ VersionId: '1',
38
+ Code: 'AllAccessDisabled',
39
+ Message: 'All access to this Amazon S3 resource has been disabled. Contact AWS Support for further assistance.',
40
+ },
41
+ ], new AggregateError([
42
+ createError('AccessDenied', 'testkey1/1: Access Denied'),
43
+ createError('AllAccessDisabled', 'testkey1/1: All access to this Amazon S3 resource has been disabled. Contact AWS Support for further assistance.'),
44
+ ]))
45
+
46
+ if (process.argv[1] == __filename) {
47
+ test()
48
+ }
49
+
50
+ module.exports = test
@@ -1,5 +1,6 @@
1
1
  const Readable = require('../Readable')
2
2
  const AwsError = require('./AwsError')
3
+ const sleep = require('./sleep')
3
4
 
4
5
  /**
5
6
  * @name dynamoDBStreamListStreams
@@ -0,0 +1,17 @@
1
+ const path = require('path')
2
+
3
+ // getAbsoluteFilePath(filepath string, platform string) -> absoluteFilePath string
4
+ function getAbsoluteFilePath(filepath, platform) {
5
+ if (platform.startsWith('win')) {
6
+ if (/^[A-Z]:/.test(filepath)) {
7
+ filepath = filepath.replace(/\//g, '\\')
8
+ } else {
9
+ filepath = path.join(process.cwd(), filepath).replace(/\//g, '\\')
10
+ }
11
+ } else if (!filepath.startsWith('/')) {
12
+ filepath = path.join(process.cwd(), filepath)
13
+ }
14
+ return filepath
15
+ }
16
+
17
+ module.exports = getAbsoluteFilePath
@@ -0,0 +1,19 @@
1
+ const Test = require('thunk-test')
2
+ const assert = require('assert')
3
+ const getAbsoluteFilePath = require('./getAbsoluteFilePath')
4
+
5
+ const test = new Test('getAbsoluteFilePath', getAbsoluteFilePath)
6
+
7
+ const cwd = process.cwd()
8
+
9
+ test.case('/test', 'linux64', '/test')
10
+ test.case('test', 'linux64', `${cwd}/test`)
11
+ test.case('/test', 'win64', `${cwd.replace(/\//g, '\\')}\\test`)
12
+ test.case('C:\\test', 'win64', 'C:\\test')
13
+ test.case('D:\\test', 'win64', 'D:\\test')
14
+
15
+ if (process.argv[1] == __filename) {
16
+ test()
17
+ }
18
+
19
+ module.exports = test
@@ -0,0 +1,15 @@
1
+ // getChromeBinaryOrExecutableFilePath(filepath string, platform string) -> string
2
+ function getChromeBinaryOrExecutableFilePath(filepath, platform) {
3
+ if (platform.startsWith('mac') && filepath.endsWith('Google Chrome for Testing')) {
4
+ return filepath
5
+ }
6
+ if (platform.startsWith('linux') && filepath.endsWith('chrome')) {
7
+ return filepath
8
+ }
9
+ if (platform.startsWith('win') && filepath.endsWith('chrome.exe')) {
10
+ return filepath
11
+ }
12
+ return undefined
13
+ }
14
+
15
+ module.exports = getChromeBinaryOrExecutableFilePath
@@ -0,0 +1,17 @@
1
+ const Test = require('thunk-test')
2
+ const getChromeBinaryOrExecutableFilePath = require('./getChromeBinaryOrExecutableFilePath.js')
3
+
4
+ const test = new Test('getChromeBinaryOrExecutableFilePath', getChromeBinaryOrExecutableFilePath)
5
+
6
+ test.case('/path/to/Google Chrome for Testing', 'mac-x64', '/path/to/Google Chrome for Testing')
7
+ test.case('/path/to/other', 'mac-x64', undefined)
8
+ test.case('/path/to/chrome', 'linux64', '/path/to/chrome')
9
+ test.case('/path/to/other', 'linux64', undefined)
10
+ test.case('C:\\path\\to\\chrome.exe', 'win64', 'C:\\path\\to\\chrome.exe')
11
+ test.case('C:\\path\\to\\other.exe', 'win64', undefined)
12
+
13
+ if (process.argv[1] == __filename) {
14
+ test()
15
+ }
16
+
17
+ module.exports = test
@@ -0,0 +1,20 @@
1
+ const getChromeVersions = require('./getChromeVersions')
2
+
3
+ // getChromeUrl(platform string) -> chromeUrl string
4
+ async function getChromeUrl(platform) {
5
+
6
+ let url
7
+ if (['stable', 'beta', 'dev', 'canary'].includes(this.chromeVersion)) {
8
+ const chromeVersions = await getChromeVersions()
9
+ const channel = `${this.chromeVersion[0].toUpperCase()}${this.chromeVersion.slice(1)}`
10
+ const chromeVersionNumber = chromeVersions.channels[channel].version
11
+ url = `https://storage.googleapis.com/chrome-for-testing-public/${chromeVersionNumber}/${platform}/chrome-${platform}.zip`
12
+ } else {
13
+ const chromeVersionNumber = this.chromeVersion
14
+ url = `https://storage.googleapis.com/chrome-for-testing-public/${chromeVersionNumber}/${platform}/chrome-${platform}.zip`
15
+ }
16
+
17
+ return url
18
+ }
19
+
20
+ module.exports = getChromeUrl
@@ -0,0 +1,22 @@
1
+ const Test = require('thunk-test')
2
+ const assert = require('assert')
3
+ const getChromeUrl = require('./getChromeUrl')
4
+ const getChromeVersions = require('./getChromeVersions')
5
+
6
+ const test = new Test('getChromeUrl', async function integration() {
7
+ const chromeVersions = await getChromeVersions()
8
+
9
+ const chromeVersionNumber = chromeVersions.channels.Stable.version
10
+ const platform = 'linux64'
11
+ const url = `https://storage.googleapis.com/chrome-for-testing-public/${chromeVersionNumber}/${platform}/chrome-${platform}.zip`
12
+
13
+ assert.equal(await getChromeUrl.call({ chromeVersion: 'stable' }, 'linux64'), url)
14
+ assert.equal(await getChromeUrl.call({ chromeVersion: chromeVersionNumber }, 'linux64'), url)
15
+
16
+ }).case()
17
+
18
+ if (process.argv[1] == __filename) {
19
+ test()
20
+ }
21
+
22
+ module.exports = test
@@ -0,0 +1,19 @@
1
+ const HTTP = require('../HTTP')
2
+ const Readable = require('../Readable')
3
+
4
+ // getChromeVersions() -> Promise<{
5
+ // channels: {
6
+ // Stable: { version: string },
7
+ // Beta: { version: string },
8
+ // Dev: { version: string },
9
+ // Canary: { version: string },
10
+ // },
11
+ // }>
12
+ async function getChromeVersions() {
13
+ const http = new HTTP()
14
+ const response = await http.GET('https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json')
15
+ const data = await Readable.JSON(response)
16
+ return data
17
+ }
18
+
19
+ module.exports = getChromeVersions
@@ -0,0 +1,22 @@
1
+ const os = require('os')
2
+
3
+ // getPlatform() -> platform string
4
+ function getPlatform() {
5
+ let platform = os.platform()
6
+ if (platform == 'darwin') {
7
+ platform = 'mac'
8
+ }
9
+ const arch = os.arch()
10
+
11
+ if (platform == 'mac') {
12
+ platform = `${platform}-${arch}`
13
+ } else if (platform == 'win32') {
14
+ platform = `win${arch.slice(1)}`
15
+ } else {
16
+ platform = `${platform}${arch.slice(1)}`
17
+ }
18
+
19
+ return platform
20
+ }
21
+
22
+ module.exports = getPlatform
@@ -0,0 +1,33 @@
1
+ const Test = require('thunk-test')
2
+ const assert = require('assert')
3
+ const getPlatform = require('./getPlatform')
4
+
5
+ const test = new Test('getPlatform', async function integration() {
6
+ const os = require('os')
7
+
8
+ const osPlatform = os.platform
9
+ const osArch = os.arch
10
+
11
+ os.platform = () => 'darwin'
12
+ os.arch = () => 'x64'
13
+
14
+ assert.equal(getPlatform(), 'mac-x64')
15
+
16
+ os.platform = () => 'win32'
17
+
18
+ assert.equal(getPlatform(), 'win64')
19
+
20
+ os.platform = () => 'linux'
21
+
22
+ assert.equal(getPlatform(), 'linux64')
23
+
24
+ os.platform = osPlatform
25
+ os.arch = osArch
26
+
27
+ }).case()
28
+
29
+ if (process.argv[1] == __filename) {
30
+ test()
31
+ }
32
+
33
+ module.exports = test
@@ -0,0 +1,17 @@
1
+ const sleep = require('./sleep')
2
+
3
+ // retryHTTPRequest(http HTTP, method string, url string, options {
4
+ // headers: Object<string>,
5
+ // body: string,
6
+ // }) -> http.ServerResponse
7
+ async function retryHTTPRequest(http, method, url, options) {
8
+ try {
9
+ const response = await http[method](url, options)
10
+ return response
11
+ } catch {
12
+ await sleep(1000)
13
+ return retryHTTPRequest(http, method, url, options)
14
+ }
15
+ }
16
+
17
+ module.exports = retryHTTPRequest
@@ -0,0 +1,40 @@
1
+ const Test = require('thunk-test')
2
+ const assert = require('assert')
3
+ const retryHTTPRequest = require('./retryHTTPRequest')
4
+
5
+ const test = new Test('retryHTTPRequest', async function integration() {
6
+ const http1 = {
7
+ async GET(url, options) {
8
+ return 'ok'
9
+ }
10
+ }
11
+
12
+ {
13
+ const response = await retryHTTPRequest(http1, 'GET', '/test', {})
14
+ assert.equal(response, 'ok')
15
+ }
16
+
17
+ let retries = 0
18
+ const http2 = {
19
+ async GET(url, options) {
20
+ if (retries === 0) {
21
+ retries += 1
22
+ throw new Error('test')
23
+ }
24
+ return 'ok'
25
+ }
26
+ }
27
+
28
+ {
29
+ const response = await retryHTTPRequest(http2, 'GET', '/test', {})
30
+ assert.equal(response, 'ok')
31
+ assert.strictEqual(retries, 1)
32
+ }
33
+
34
+ }).case()
35
+
36
+ if (process.argv[1] == __filename) {
37
+ test()
38
+ }
39
+
40
+ module.exports = test
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "presidium",
3
- "version": "4.0.0",
3
+ "version": "4.0.6",
4
4
  "description": "A library for creating web services",
5
5
  "author": "Richard Tong",
6
6
  "license": "CFOSS",