dynamodb-toolbox
Version:
Lightweight and type-safe query builder for DynamoDB and TypeScript.
82 lines (81 loc) • 3.97 kB
JavaScript
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) } : {})
};
};