presidium 0.16.16 → 0.16.18

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.
package/.eslintrc.js CHANGED
@@ -210,7 +210,7 @@ module.exports = {
210
210
  'no-sequences': 'off',
211
211
  'no-shadow': 'off',
212
212
  'no-spaced-func': 'error',
213
- 'no-sync': 'error',
213
+ 'no-sync': 'off',
214
214
  'no-tabs': 'error',
215
215
  'no-template-curly-in-string': 'error',
216
216
  'no-ternary': 'off',
@@ -0,0 +1,61 @@
1
+ require('rubico/global')
2
+ const fs = require('fs')
3
+ const nodePath = require('path')
4
+ const pathResolve = require('./internal/pathResolve')
5
+
6
+ /**
7
+ * @name AwsCredentials
8
+ *
9
+ * @synopsis
10
+ * ```coffeescript [specscript]
11
+ * AwsCredentials(options {
12
+ * profile?: string,
13
+ * credentialsFileDir?: string,
14
+ * }) -> awsCreds {
15
+ * accessKeyId: string,
16
+ * secretAccessKey: string,
17
+ * }
18
+ *
19
+ * AwsCredentials(profile string) -> awsCreds {
20
+ * accessKeyId: string,
21
+ * secretAccessKey: string,
22
+ * }
23
+ * ```
24
+ */
25
+
26
+ const AwsCredentials = async function (options = {}) {
27
+ const profile = (
28
+ typeof options == 'string' ? options : options.profile
29
+ ) ?? 'default'
30
+
31
+ let credentialsFileDir =
32
+ options.credentialsFileDir ?? pathResolve(process.cwd())
33
+ let lines = ''
34
+ while (credentialsFileDir != '/') {
35
+ const credentialsFilePath =
36
+ pathResolve(credentialsFileDir, '.aws/credentials')
37
+ if (fs.existsSync(credentialsFilePath)) {
38
+ lines = await (
39
+ fs.promises.readFile(credentialsFilePath)
40
+ .then(buffer => `${buffer}`.split('\n'))
41
+ )
42
+ break
43
+ }
44
+ credentialsFileDir = pathResolve(credentialsFileDir, '..')
45
+ }
46
+
47
+ const startingLineNumber = lines.findIndex(line => line == `[${profile}]`)
48
+
49
+ const accessKeyId = lines.find(
50
+ (line, index) => index > startingLineNumber
51
+ && line.startsWith('aws_access_key_id')
52
+ ).split(' = ')[1]
53
+ const secretAccessKey = lines.find(
54
+ (line, index) => index > startingLineNumber
55
+ && line.startsWith('aws_secret_access_key')
56
+ ).split(' = ')[1]
57
+
58
+ return { accessKeyId, secretAccessKey }
59
+ }
60
+
61
+ module.exports = AwsCredentials
@@ -0,0 +1,45 @@
1
+ const Test = require('thunk-test')
2
+ const assert = require('assert')
3
+ const fs = require('fs')
4
+ const AwsCredentials = require('./AwsCredentials')
5
+
6
+ const test = new Test('AwsCredentials', async function () {
7
+ try {
8
+ await fs.promises.mkdir(`${__dirname}/../.aws`)
9
+ } catch {
10
+ await fs.promises.rm(`${__dirname}/../.aws`, { recursive: true })
11
+ await fs.promises.mkdir(`${__dirname}/../.aws`)
12
+ }
13
+
14
+ await fs.promises.writeFile(`${__dirname}/../.aws/credentials`, `
15
+ [default]
16
+ aws_access_key_id = AAA
17
+ aws_secret_access_key = FFF
18
+ `.trim())
19
+
20
+ {
21
+ const awsCreds = await AwsCredentials('default')
22
+ assert.equal(awsCreds.accessKeyId, 'AAA')
23
+ assert.equal(awsCreds.secretAccessKey, 'FFF')
24
+ }
25
+
26
+ {
27
+ const awsCreds = await AwsCredentials({ profile: 'default' })
28
+ assert.equal(awsCreds.accessKeyId, 'AAA')
29
+ assert.equal(awsCreds.secretAccessKey, 'FFF')
30
+ }
31
+
32
+ {
33
+ const awsCreds = await AwsCredentials()
34
+ assert.equal(awsCreds.accessKeyId, 'AAA')
35
+ assert.equal(awsCreds.secretAccessKey, 'FFF')
36
+ }
37
+
38
+ await fs.promises.rm(`${__dirname}/../.aws`, { recursive: true })
39
+ }).case()
40
+
41
+ if (process.argv[1] == __filename) {
42
+ test()
43
+ }
44
+
45
+ module.exports = test
@@ -38,6 +38,7 @@ const test = Test('DynamoStream', DynamoStream)
38
38
  table: 'my-table',
39
39
  endpoint: 'http://localhost:8000',
40
40
  shardIteratorType: 'TRIM_HORIZON',
41
+ shardUpdatePeriod: 1000,
41
42
  }, async function (myStream) {
42
43
  await myStream.ready
43
44
 
@@ -83,7 +84,7 @@ const test = Test('DynamoStream', DynamoStream)
83
84
  endpoint: 'http://localhost:8000',
84
85
  getRecordsLimit: 1,
85
86
  getRecordsInterval: 1000,
86
- shardUpdatePeriod: 5000,
87
+ shardUpdatePeriod: 1000,
87
88
  shardIteratorType: 'TRIM_HORIZON',
88
89
  }, async function (myStream) {
89
90
  await myStream.ready
@@ -129,6 +130,7 @@ const test = Test('DynamoStream', DynamoStream)
129
130
  table: 'my-table',
130
131
  endpoint: 'http://localhost:8000',
131
132
  getRecordsLimit: 1,
133
+ shardUpdatePeriod: 1000,
132
134
  shardIteratorType: 'TRIM_HORIZON',
133
135
  }, async function (myStream) {
134
136
  await myStream.ready
@@ -183,6 +185,7 @@ const test = Test('DynamoStream', DynamoStream)
183
185
  listStreamsLimit: 1,
184
186
  shardIteratorType: 'TRIM_HORIZON',
185
187
  debug: true,
188
+ shardUpdatePeriod: 1000,
186
189
  }, async function (myStream) {
187
190
  await myStream.ready
188
191
 
@@ -223,6 +226,82 @@ const test = Test('DynamoStream', DynamoStream)
223
226
  myStream.close()
224
227
  })
225
228
 
229
+ .case({
230
+ table: 'my-table',
231
+ endpoint: 'http://localhost:8000',
232
+ listStreamsLimit: 1,
233
+ shardIteratorType: 'TRIM_HORIZON',
234
+ debug: true,
235
+ shardUpdatePeriod: 1000,
236
+ }, async function (myStream) {
237
+ await myStream.ready
238
+
239
+ const originalClient = myStream.client
240
+ const alternatingErrorClient = {
241
+ listStreams(options) {
242
+ return originalClient.listStreams(options)
243
+ },
244
+ describeStream(options) {
245
+ return originalClient.describeStream(options)
246
+ },
247
+ getShardIterator(options) {
248
+ return originalClient.getShardIterator(options)
249
+ },
250
+ getRecordsCount: 0,
251
+ getRecords(options) {
252
+ return {
253
+ async promise() {
254
+ if (alternatingErrorClient.getRecordsCount % 2 == 0) {
255
+ const error = new Error('stub error')
256
+ error.retryable = true
257
+ alternatingErrorClient.getRecordsCount += 1
258
+ throw error
259
+ }
260
+ alternatingErrorClient.getRecordsCount += 1
261
+ return originalClient.getRecords(options).promise()
262
+ },
263
+ }
264
+ },
265
+ }
266
+ myStream.client = alternatingErrorClient
267
+
268
+ const table = this.table
269
+ await table.putItem({
270
+ id: '1',
271
+ status: 'waitlist',
272
+ createTime: 1000,
273
+ name: 'George',
274
+ })
275
+ await table.putItem({
276
+ id: '2',
277
+ status: 'waitlist',
278
+ createTime: 1001,
279
+ name: 'geo',
280
+ })
281
+ await table.putItem({
282
+ id: '3',
283
+ status: 'waitlist',
284
+ createTime: 1002,
285
+ name: 'john',
286
+ })
287
+ await table.putItem({
288
+ id: '4',
289
+ status: 'approved',
290
+ createTime: 1003,
291
+ name: 'sally',
292
+ })
293
+ await table.putItem({
294
+ id: '5',
295
+ status: 'approved',
296
+ createTime: 1004,
297
+ name: 'sally',
298
+ })
299
+
300
+ const first5 = await asyncIterableTake(5)(myStream)
301
+ assert.strictEqual(first5.length, 5)
302
+ myStream.close()
303
+ })
304
+
226
305
  .case({
227
306
  table: 'my-table',
228
307
  endpoint: 'http://localhost:8000',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "presidium",
3
- "version": "0.16.16",
3
+ "version": "0.16.18",
4
4
  "description": "A library for creating web services",
5
5
  "author": "Richard Tong",
6
6
  "license": "MIT",
package/teardown.js ADDED
@@ -0,0 +1,39 @@
1
+ const DynamoTable = require('./DynamoTable')
2
+ const DynamoStream = require('./DynamoStream')
3
+ const ElasticsearchIndex = require('./ElasticsearchIndex')
4
+ const S3Bucket = require('./S3Bucket')
5
+ const KinesisStream = require('./KinesisStream')
6
+
7
+ /**
8
+ * @name teardown
9
+ *
10
+ * @synopsis
11
+ * ```coffeescript [specscript]
12
+ * teardown(
13
+ * dependency DynamoTable|DynamoStream
14
+ * |ElasticsearchIndex|S3Bucket
15
+ * |KinesisStream
16
+ * ) -> Promise<>
17
+ * ```
18
+ */
19
+ const teardown = async function (dependency) {
20
+ if (dependency.constructor == DynamoTable) {
21
+ await dependency.delete()
22
+ }
23
+ else if (dependency.constructor == DynamoStream) {
24
+ dependency.close()
25
+ }
26
+ else if (dependency.constructor == ElasticsearchIndex) {
27
+ await dependency.delete()
28
+ }
29
+ else if (dependency.constructor == S3Bucket) {
30
+ await dependency.deleteAllObjects()
31
+ await dependency.delete()
32
+ }
33
+ else if (dependency.constructor == KinesisStream) {
34
+ dependency.close()
35
+ await dependency.delete()
36
+ }
37
+ }
38
+
39
+ module.exports = teardown
@@ -0,0 +1,62 @@
1
+ const Test = require('thunk-test')
2
+ const DynamoTable = require('presidium/DynamoTable')
3
+ const DynamoStream = require('presidium/DynamoStream')
4
+ const ElasticsearchIndex = require('presidium/ElasticsearchIndex')
5
+ const S3Bucket = require('presidium/S3Bucket')
6
+ const KinesisStream = require('presidium/KinesisStream')
7
+ const teardown = require('./teardown')
8
+
9
+ const test = new Test('teardown', async function () {
10
+ const myDynamoTable = new DynamoTable({
11
+ name: 'my_dynamo_table',
12
+ key: [{ a: 'string' }],
13
+ endpoint: 'http://localhost:8000',
14
+ region: 'dynamodblocal',
15
+ })
16
+ await myDynamoTable.ready
17
+
18
+ const myDynamoStream = new DynamoStream({
19
+ table: 'my_dynamo_table',
20
+ endpoint: 'http://localhost:8000',
21
+ region: 'dynamodblocal',
22
+ })
23
+ await myDynamoStream.ready
24
+
25
+ const myElasticsearchIndex = new ElasticsearchIndex({
26
+ node: 'http://localhost:9200/',
27
+ index: 'local_post',
28
+ mappings: {
29
+ a: { type: 'keyword' },
30
+ b: { type: 'keyword' },
31
+ },
32
+ })
33
+ await myElasticsearchIndex.ready
34
+
35
+ const myS3Bucket = new S3Bucket({
36
+ name: 'my-s3-bucket',
37
+ endpoint: 'http://localhost:9000',
38
+ region: 'us-west-1',
39
+ accessKeyId: 'minioadmin',
40
+ secretAccessKey: 'minioadmin',
41
+ })
42
+ await myS3Bucket.ready
43
+
44
+ const myKinesisStream = new KinesisStream({
45
+ name: 'my_kinesis_stream',
46
+ endpoint: 'http://localhost:4567',
47
+ shardIteratorType: 'TRIM_HORIZON',
48
+ })
49
+ await myKinesisStream.ready
50
+
51
+ await teardown(myDynamoTable)
52
+ await teardown(myDynamoStream)
53
+ await teardown(myElasticsearchIndex)
54
+ await teardown(myS3Bucket)
55
+ await teardown(myKinesisStream)
56
+ }).case()
57
+
58
+ if (process.argv[1] == __filename) {
59
+ test()
60
+ }
61
+
62
+ module.exports = teardown