@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.7",
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": "345c44f58b91a92723579e072235aa9607827efb"
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 | baseMethod
50
- ${'queryAllPromise'} | ${'query'}
51
- ${'scanAllPromise'} | ${'scan'}
52
- `('$aggregateMethod', ({ aggregateMethod, baseMethod }) => {
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 ${baseMethod}`, async () => {
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(docClient[baseMethod]).toHaveBeenCalledWith(params)
63
+ expect(commandType).toHaveBeenCalledWith(params)
63
64
  })
64
65
 
65
- it(`calls ${baseMethod} repeatedly until LastEvaluatedKey evaluates to false, concatenating all returned items`, async () => {
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[baseMethod]
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 ${baseMethod} results, passes ExclusiveStartKey param`, async () => {
90
+ it(`whilst concatenating ${commandType.name} results, passes ExclusiveStartKey param`, async () => {
83
91
  const expectedKey = Symbol('🔑')
84
92
  const docClient = createDocumentClient()
85
- docClient[baseMethod].mockResolvedValueOnce({ Items: [], LastEvaluatedKey: expectedKey }).mockResolvedValueOnce({ Items: [] })
93
+ docClient.send.mockResolvedValueOnce({ Items: [], LastEvaluatedKey: expectedKey }).mockResolvedValueOnce({ Items: [] })
86
94
  await docClient[aggregateMethod]()
87
- expect(docClient[baseMethod]).toHaveBeenNthCalledWith(
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[baseMethod]).toHaveBeenNthCalledWith(
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 = operationName => {
16
+ const wrapPagedDocumentClientOperation = CommandType => {
17
17
  return async params => {
18
18
  const items = []
19
19
  let lastEvaluatedKey = null
20
20
  do {
21
- const response = await docClient[operationName]({
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('query')
32
- docClient.scanAllPromise = wrapPagedDocumentClientOperation('scan')
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