Skip to content

Commit 4ee04ea

Browse files
authored
Merge pull request #105 from shelfio/aws-sdk-js-v3
2 parents 7b3fa6e + 68cc8de commit 4ee04ea

File tree

7 files changed

+127
-31
lines changed

7 files changed

+127
-31
lines changed

index-another-concurrent-test.test.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
1-
const {DocumentClient} = require('aws-sdk/clients/dynamodb');
1+
const {DynamoDB} = require('@aws-sdk/client-dynamodb');
2+
const {DynamoDBDocument} = require('@aws-sdk/lib-dynamodb');
23

3-
const ddb = new DocumentClient({
4-
convertEmptyValues: true,
5-
endpoint: 'localhost:8000',
6-
sslEnabled: false,
7-
region: 'local-env'
8-
});
4+
const ddb = DynamoDBDocument.from(
5+
new DynamoDB({
6+
endpoint: 'http://localhost:8000',
7+
tls: false,
8+
region: 'local-env',
9+
credentials: {
10+
accessKeyId: 'fakeMyKeyId',
11+
secretAccessKey: 'fakeSecretAccessKey'
12+
}
13+
}),
14+
{
15+
marshallOptions: {
16+
convertEmptyValues: true
17+
}
18+
}
19+
);
920

1021
it('should insert item into another table concurrently', async () => {
11-
await ddb.put({TableName: 'users', Item: {id: '1', hello: 'world'}}).promise();
22+
await ddb.put({TableName: 'users', Item: {id: '1', hello: 'world'}});
1223

13-
const {Item} = await ddb.get({TableName: 'users', Key: {id: '1'}}).promise();
24+
const {Item} = await ddb.get({TableName: 'users', Key: {id: '1'}});
1425

1526
expect(Item).toEqual({
1627
id: '1',

index.test.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
1-
const {DocumentClient} = require('aws-sdk/clients/dynamodb');
1+
const {DynamoDB} = require('@aws-sdk/client-dynamodb');
2+
const {DynamoDBDocument} = require('@aws-sdk/lib-dynamodb');
23

3-
const ddb = new DocumentClient({
4-
convertEmptyValues: true,
5-
endpoint: 'localhost:8000',
6-
sslEnabled: false,
7-
region: 'local-env'
8-
});
4+
const ddb = DynamoDBDocument.from(
5+
new DynamoDB({
6+
endpoint: 'http://localhost:8000',
7+
tls: false,
8+
region: 'local-env',
9+
credentials: {
10+
accessKeyId: 'fakeMyKeyId',
11+
secretAccessKey: 'fakeSecretAccessKey'
12+
}
13+
}),
14+
{
15+
marshallOptions: {
16+
convertEmptyValues: true
17+
}
18+
}
19+
);
920

1021
it('should insert item into table', async () => {
11-
await ddb.put({TableName: 'files', Item: {id: '1', hello: 'world'}}).promise();
22+
await ddb.put({TableName: 'files', Item: {id: '1', hello: 'world'}});
1223

13-
const {Item} = await ddb.get({TableName: 'files', Key: {id: '1'}}).promise();
24+
const {Item} = await ddb.get({TableName: 'files', Key: {id: '1'}});
1425

1526
expect(Item).toEqual({
1627
id: '1',

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,24 @@
5353
"dynamodb-local": "0.0.31"
5454
},
5555
"devDependencies": {
56+
"@aws-sdk/client-dynamodb": "^3.26.0",
57+
"@aws-sdk/lib-dynamodb": "^3.26.0",
58+
"@aws-sdk/util-dynamodb": "^3.26.0",
5659
"@shelf/eslint-config": "0.19.0",
5760
"@shelf/prettier-config": "0.0.7",
58-
"aws-sdk": "2.631.0",
5961
"eslint": "7.6.0",
6062
"husky": "4.2.5",
6163
"jest": "26.2.2",
6264
"lint-staged": "10.2.11",
6365
"prettier": "2.0.5"
6466
},
6567
"peerDependencies": {
66-
"aws-sdk": "2.x.x"
68+
"@aws-sdk/client-dynamodb": "3.x.x",
69+
"@aws-sdk/lib-dynamodb": "3.x.x",
70+
"@aws-sdk/util-dynamodb": "3.x.x"
6771
},
6872
"engines": {
69-
"node": ">=8"
73+
"node": ">=12"
7074
},
7175
"publishConfig": {
7276
"access": "public"

readme.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ module.exports = async () => {
146146
};
147147
```
148148

149-
### 3. Configure DynamoDB client
149+
### 3.1 Configure DynamoDB client (from aws-sdk v2)
150150

151151
```js
152152
const {DocumentClient} = require('aws-sdk/clients/dynamodb');
@@ -160,6 +160,34 @@ const config = {
160160
const ddb = new DocumentClient(config);
161161
```
162162

163+
### 3.2 Configure DynamoDB client (from aws-sdk v3)
164+
165+
```js
166+
const {DynamoDB} = require('@aws-sdk/client-dynamodb');
167+
const {DynamoDBDocument} = require('@aws-sdk/lib-dynamodb');
168+
169+
const isTest = process.env.JEST_WORKER_ID;
170+
171+
const ddb = DynamoDBDocument.from(
172+
new DynamoDB({
173+
...(isTest && {
174+
endpoint: 'localhost:8000',
175+
sslEnabled: false,
176+
region: 'local-env',
177+
credentials: {
178+
accessKeyId: 'fakeMyKeyId',
179+
secretAccessKey: 'fakeSecretAccessKey'
180+
}
181+
})
182+
}),
183+
{
184+
marshallOptions: {
185+
convertEmptyValues: true
186+
}
187+
}
188+
);
189+
```
190+
163191
### 4. PROFIT! Write tests
164192

165193
```js

setup.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
const {resolve} = require('path');
22
const cwd = require('cwd');
3-
const DynamoDB = require('aws-sdk/clients/dynamodb');
3+
const {DynamoDB} = require('@aws-sdk/client-dynamodb');
44
const DynamoDbLocal = require('dynamodb-local');
55
const debug = require('debug')('jest-dynamodb');
6+
const waitForLocalhost = require('./wait-for-localhost');
67

78
// aws-sdk requires access and secret key to be able to call DDB
89
process.env.AWS_ACCESS_KEY_ID = 'access-key';
@@ -22,17 +23,21 @@ module.exports = async function () {
2223
} = typeof config === 'function' ? await config() : config;
2324

2425
const dynamoDB = new DynamoDB({
25-
endpoint: `localhost:${port}`,
26-
sslEnabled: false,
26+
endpoint: `http://localhost:${port}`,
27+
tls: false,
2728
region: 'local-env',
29+
credentials: {
30+
accessKeyId: 'fakeMyKeyId',
31+
secretAccessKey: 'fakeSecretAccessKey'
32+
},
2833
...clientConfig
2934
});
3035

3136
global.__DYNAMODB_CLIENT__ = dynamoDB;
3237

3338
try {
3439
const {TableNames: tableNames} = await Promise.race([
35-
dynamoDB.listTables().promise(),
40+
dynamoDB.listTables({}),
3641
new Promise(resolve => setTimeout(resolve, 1000))
3742
]);
3843
await deleteTables(dynamoDB, tableNames); // cleanup leftovers
@@ -45,15 +50,19 @@ module.exports = async function () {
4550
}
4651

4752
if (!global.__DYNAMODB__) {
53+
debug('spinning up a local ddb instance');
54+
4855
global.__DYNAMODB__ = await DynamoDbLocal.launch(port, null, options);
56+
57+
await waitForLocalhost({port: DEFAULT_PORT, useGet: true, path: '/'});
4958
}
5059
}
5160

5261
await createTables(dynamoDB, newTables);
5362
};
5463

5564
async function createTables(dynamoDB, tables) {
56-
return Promise.all(tables.map(table => dynamoDB.createTable(table).promise()));
65+
return Promise.all(tables.map(table => dynamoDB.createTable(table)));
5766
}
5867

5968
async function deleteTables(dynamoDB, tableNames) {

teardown.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ module.exports = async function (jestArgs) {
77

88
if (global.__DYNAMODB__) {
99
const watching = jestArgs.watch || jestArgs.watchAll;
10+
1011
if (!watching) {
1112
await DynamoDbLocal.stopChild(global.__DYNAMODB__);
1213
}
1314
} else {
1415
const dynamoDB = global.__DYNAMODB_CLIENT__;
15-
const {TableNames: tableNames} = await dynamoDB.listTables().promise();
16-
await Promise.all(
17-
tableNames.map(tableName => dynamoDB.deleteTable({TableName: tableName}).promise())
18-
);
16+
const {TableNames: tableNames} = await dynamoDB.listTables({});
17+
await Promise.all(tableNames.map(tableName => dynamoDB.deleteTable({TableName: tableName})));
1918
}
2019
};

wait-for-localhost.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
This is copied from https://github.com/sindresorhus/wait-for-localhost/blob/v3.3.0/index.js
3+
With 1 change
4+
We rely on status code 400 instead of 200 to ensure local DDB is up and running
5+
*/
6+
7+
const http = require('http');
8+
9+
const waitForLocalhost = options => {
10+
options = {...options};
11+
12+
return new Promise(resolve => {
13+
const retry = () => setTimeout(main, 200);
14+
15+
const method = options.useGet ? 'GET' : 'HEAD';
16+
17+
const main = () => {
18+
const request = http.request({method, port: options.port, path: options.path}, response => {
19+
if (response.statusCode === 400) {
20+
return resolve();
21+
}
22+
23+
retry();
24+
});
25+
26+
request.on('error', retry);
27+
request.end();
28+
};
29+
30+
main();
31+
});
32+
};
33+
34+
module.exports = waitForLocalhost;

0 commit comments

Comments
 (0)