UNPKG

dynamodb-toolbox

Version:

Lightweight and type-safe query builder for DynamoDB and TypeScript.

82 lines (81 loc) 3.97 kB
import { BatchWriteCommand as _BatchWriteCommand } from '@aws-sdk/lib-dynamodb'; import { DynamoDBToolboxError } from '../../../errors/index.js'; import { parseCapacityOption } from '../../../options/capacity.js'; import { parseMetricsOption } from '../../../options/metrics.js'; import { isEmpty } from '../../../utils/isEmpty.js'; import { BatchWriteCommand } from './batchWriteCommand.js'; export const execute = async (..._commands) => { const [headCommandOrOptions = {}, ...tailCommands] = _commands; const commands = tailCommands; let options = {}; if (headCommandOrOptions instanceof BatchWriteCommand) { commands.unshift(headCommandOrOptions); } else { options = headCommandOrOptions; } const firstCommand = commands[0]; if (firstCommand === undefined) { throw new DynamoDBToolboxError('actions.incompleteAction', { message: 'Cannot execute BatchWriteCommands: No BatchWriteCommand supplied' }); } const { maxAttempts = 1, metrics, capacity, documentClient, ...documentClientOptions } = options; const docClient = documentClient !== null && documentClient !== void 0 ? documentClient : firstCommand.table.getDocumentClient(); const { RequestItems: initialRequestItems, ...commandOptions } = getCommandInput(commands, { metrics, capacity }); let attemptCount = 0; let requestItems = initialRequestItems; let unprocessedItems = {}; let consumedCapacity = undefined; let collectionMetrics = undefined; let responseMetadata = {}; do { attemptCount += 1; const { UnprocessedItems: attemptUnprocessedItems = {}, ConsumedCapacity: attemptConsumedCapacity, ItemCollectionMetrics: attemptCollectionMetrics, $metadata: attemptMetadata } = await docClient.send(new _BatchWriteCommand({ RequestItems: requestItems, ...commandOptions }), documentClientOptions); requestItems = attemptUnprocessedItems; unprocessedItems = attemptUnprocessedItems; consumedCapacity = attemptConsumedCapacity; collectionMetrics = attemptCollectionMetrics; responseMetadata = attemptMetadata; } while (attemptCount < maxAttempts && !isEmpty(unprocessedItems)); return { ...(unprocessedItems !== undefined ? { UnprocessedItems: unprocessedItems } : {}), $metadata: {}, // return ConsumedCapacity, ItemCollectionMetrics & $metadata only if one attempt has been tried ...(attemptCount === 1 ? { ...(consumedCapacity !== undefined ? { ConsumedCapacity: consumedCapacity } : {}), ...(collectionMetrics !== undefined ? { ItemCollectionMetrics: collectionMetrics } : {}), ...(responseMetadata !== undefined ? { $metadata: responseMetadata } : {}) } : {}) }; }; export const getCommandInput = (commands, options = {}) => { const requestItems = {}; if (commands.length === 0) { throw new DynamoDBToolboxError('actions.incompleteAction', { message: 'batchWrite arguments incomplete: No BatchWriteCommand supplied' }); } for (const command of commands) { const commandParams = command.params(); for (const tableName of Object.keys(commandParams)) { if (tableName in requestItems) { throw new DynamoDBToolboxError('actions.invalidAction', { message: `Two BatchWriteCommands detected for table: ${tableName}. Please provide only one BatchWriteCommand per table` }); } } Object.assign(requestItems, commandParams); } const { capacity, metrics } = options; return { RequestItems: requestItems, ...(capacity !== undefined ? { ReturnConsumedCapacity: parseCapacityOption(capacity) } : {}), ...(metrics !== undefined ? { ReturnItemCollectionMetrics: parseMetricsOption(metrics) } : {}) }; };