@defra-fish/connectors-lib 1.63.0-rc.7 → 1.63.0-rc.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/connectors-lib",
|
|
3
|
-
"version": "1.63.0-rc.
|
|
3
|
+
"version": "1.63.0-rc.9",
|
|
4
4
|
"description": "Shared connectors",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"node-fetch": "^2.7.0",
|
|
47
47
|
"redlock": "^4.2.0"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "fc11192e1947a9a254138b543c8718ad892f0a15"
|
|
50
50
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createDocumentClient } from '../documentclient-decorator'
|
|
2
2
|
import { DynamoDB } from '@aws-sdk/client-dynamodb'
|
|
3
|
-
import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb'
|
|
3
|
+
import { DynamoDBDocument, QueryCommand, ScanCommand } from '@aws-sdk/lib-dynamodb'
|
|
4
4
|
|
|
5
5
|
jest.mock('@aws-sdk/client-dynamodb')
|
|
6
6
|
jest.mock('@aws-sdk/lib-dynamodb')
|
|
@@ -9,6 +9,7 @@ describe('document client decorations', () => {
|
|
|
9
9
|
beforeAll(() => {
|
|
10
10
|
jest.spyOn(global, 'setTimeout').mockImplementation(cb => cb())
|
|
11
11
|
DynamoDBDocument.from.mockReturnValue({
|
|
12
|
+
send: jest.fn().mockResolvedValue({ Items: [], lastEvaluatedKey: false }),
|
|
12
13
|
query: jest.fn().mockResolvedValue({ Items: [], lastEvaluatedKey: false }),
|
|
13
14
|
scan: jest.fn().mockResolvedValue({ Items: [], lastEvaluatedKey: false }),
|
|
14
15
|
batchWrite: jest.fn().mockResolvedValue({ UnprocessedItems: {} })
|
|
@@ -46,23 +47,30 @@ describe('document client decorations', () => {
|
|
|
46
47
|
})
|
|
47
48
|
|
|
48
49
|
describe.each`
|
|
49
|
-
aggregateMethod |
|
|
50
|
-
${'queryAllPromise'} | ${
|
|
51
|
-
${'scanAllPromise'} | ${
|
|
52
|
-
`('$aggregateMethod', ({ aggregateMethod,
|
|
50
|
+
aggregateMethod | commandType
|
|
51
|
+
${'queryAllPromise'} | ${QueryCommand}
|
|
52
|
+
${'scanAllPromise'} | ${ScanCommand}
|
|
53
|
+
`('$aggregateMethod', ({ aggregateMethod, commandType }) => {
|
|
53
54
|
it('is added to document client', () => {
|
|
54
55
|
const docClient = createDocumentClient()
|
|
55
56
|
expect(docClient[aggregateMethod]).toBeDefined()
|
|
56
57
|
})
|
|
57
58
|
|
|
58
|
-
it(`passes arguments provided for ${aggregateMethod} to ${
|
|
59
|
+
it(`passes arguments provided for ${aggregateMethod} to ${commandType.name}`, async () => {
|
|
59
60
|
const params = { TableName: 'TEST', KeyConditionExpression: 'id = :id', ExpressionAttributeValues: { ':id': 1 } }
|
|
60
61
|
const docClient = createDocumentClient()
|
|
61
62
|
await docClient[aggregateMethod](params)
|
|
62
|
-
expect(
|
|
63
|
+
expect(commandType).toHaveBeenCalledWith(params)
|
|
63
64
|
})
|
|
64
65
|
|
|
65
|
-
it(`
|
|
66
|
+
it(`passes created command ${commandType.name} to docClient.send`, async () => {
|
|
67
|
+
const docClient = createDocumentClient()
|
|
68
|
+
await docClient[aggregateMethod]()
|
|
69
|
+
const [command] = commandType.mock.instances
|
|
70
|
+
expect(docClient.send).toHaveBeenCalledWith(command)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('calls send repeatedly until LastEvaluatedKey evaluates to false, concatenating all returned items', async () => {
|
|
66
74
|
const expectedItems = [
|
|
67
75
|
{ id: 1, data: Symbol('data1') },
|
|
68
76
|
{ id: 2, data: Symbol('data2') },
|
|
@@ -71,7 +79,7 @@ describe('document client decorations', () => {
|
|
|
71
79
|
{ id: 5, data: Symbol('data5') }
|
|
72
80
|
]
|
|
73
81
|
const docClient = createDocumentClient()
|
|
74
|
-
docClient
|
|
82
|
+
docClient.send
|
|
75
83
|
.mockResolvedValueOnce({ Items: expectedItems.slice(0, 2), LastEvaluatedKey: true })
|
|
76
84
|
.mockResolvedValueOnce({ Items: expectedItems.slice(2, 4), LastEvaluatedKey: true })
|
|
77
85
|
.mockResolvedValueOnce({ Items: expectedItems.slice(4), LastEvaluatedKey: false })
|
|
@@ -79,13 +87,12 @@ describe('document client decorations', () => {
|
|
|
79
87
|
expect(actualItems).toEqual(expectedItems)
|
|
80
88
|
})
|
|
81
89
|
|
|
82
|
-
it(`whilst concatenating ${
|
|
90
|
+
it(`whilst concatenating ${commandType.name} results, passes ExclusiveStartKey param`, async () => {
|
|
83
91
|
const expectedKey = Symbol('🔑')
|
|
84
92
|
const docClient = createDocumentClient()
|
|
85
|
-
docClient
|
|
93
|
+
docClient.send.mockResolvedValueOnce({ Items: [], LastEvaluatedKey: expectedKey }).mockResolvedValueOnce({ Items: [] })
|
|
86
94
|
await docClient[aggregateMethod]()
|
|
87
|
-
expect(
|
|
88
|
-
2,
|
|
95
|
+
expect(commandType).toHaveBeenLastCalledWith(
|
|
89
96
|
expect.objectContaining({
|
|
90
97
|
ExclusiveStartKey: expectedKey
|
|
91
98
|
})
|
|
@@ -95,7 +102,7 @@ describe('document client decorations', () => {
|
|
|
95
102
|
it("omits ExclusiveStartKey if previous LastEvaluatedKey isn't available", async () => {
|
|
96
103
|
const docClient = createDocumentClient()
|
|
97
104
|
await docClient[aggregateMethod]()
|
|
98
|
-
expect(docClient
|
|
105
|
+
expect(docClient.send).toHaveBeenNthCalledWith(
|
|
99
106
|
1,
|
|
100
107
|
expect.not.objectContaining({
|
|
101
108
|
ExclusiveStartKey: expect.anything()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import db from 'debug'
|
|
2
2
|
import { DynamoDB } from '@aws-sdk/client-dynamodb'
|
|
3
|
-
import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb'
|
|
3
|
+
import { DynamoDBDocument, QueryCommand, ScanCommand } from '@aws-sdk/lib-dynamodb'
|
|
4
4
|
const debug = db('connectors:aws')
|
|
5
5
|
|
|
6
6
|
export const createDocumentClient = options => {
|
|
@@ -13,23 +13,24 @@ export const createDocumentClient = options => {
|
|
|
13
13
|
})
|
|
14
14
|
|
|
15
15
|
// Support for large query/scan operations which return results in pages
|
|
16
|
-
const wrapPagedDocumentClientOperation =
|
|
16
|
+
const wrapPagedDocumentClientOperation = CommandType => {
|
|
17
17
|
return async params => {
|
|
18
18
|
const items = []
|
|
19
19
|
let lastEvaluatedKey = null
|
|
20
20
|
do {
|
|
21
|
-
const
|
|
21
|
+
const command = new CommandType({
|
|
22
22
|
...params,
|
|
23
23
|
...(lastEvaluatedKey && { ExclusiveStartKey: lastEvaluatedKey })
|
|
24
24
|
})
|
|
25
|
+
const response = await docClient.send(command)
|
|
25
26
|
lastEvaluatedKey = response.LastEvaluatedKey
|
|
26
27
|
response.Items && items.push(...response.Items)
|
|
27
28
|
} while (lastEvaluatedKey)
|
|
28
29
|
return items
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
docClient.queryAllPromise = wrapPagedDocumentClientOperation(
|
|
32
|
-
docClient.scanAllPromise = wrapPagedDocumentClientOperation(
|
|
32
|
+
docClient.queryAllPromise = wrapPagedDocumentClientOperation(QueryCommand)
|
|
33
|
+
docClient.scanAllPromise = wrapPagedDocumentClientOperation(ScanCommand)
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Handles batch writes which may return UnprocessedItems. If UnprocessedItems are returned then they will be retried with exponential backoff
|