import { DynamoDB } from "aws-sdk" import { PartitionAndSortKey } from "../keys" import { Table } from "../Table" import { TaggedModel } from "../types" import { UnprocessedKeyCollector } from "../UnprocessedKeyCollector" import { BaseParams } from "./BaseParams" export interface BatchGetItemsParams> extends BaseParams { table: Table client: DynamoDB.DocumentClient keys: T[] consistentRead?: boolean } export interface BatchGetItemsResult> { items: DynamoDB.DocumentClient.AttributeMap[] unprocessedKeys: T[] } /** Performs a "raw" batchGet operation in Dynamo */ export async function batchGetItems>( params: BatchGetItemsParams ): Promise> { const { table, client, consistentRead } = params const { tableName } = table const results = await client .batchGet({ RequestItems: { [tableName]: { ConsistentRead: consistentRead, Keys: mapToKeysAndRemoveDuplicate(params.keys, table) } } }) .promise() const unprocessedKeys = new UnprocessedKeyCollector(table, params.keys) if (results.UnprocessedKeys && results.UnprocessedKeys[tableName]) { results.UnprocessedKeys[tableName].Keys.forEach((key) => unprocessedKeys.add(key)) } if (results.Responses && results.Responses[tableName]) { return { items: results.Responses[tableName], unprocessedKeys: unprocessedKeys.getUnprocessedKeys() } } else { return { items: [], unprocessedKeys: [] } } } function mapToKeysAndRemoveDuplicate>( keys: T[], table: Table ): Array> { const dynamoKeyMap: Record = {} const uniqueKeys: Array> = [] const { partitionKeyName, sortKeyName } = table keys.forEach(({ partitionKey, sortKey }) => { if (!dynamoKeyMap[`${partitionKey}-${sortKey}`]) { dynamoKeyMap[`${partitionKey}-${sortKey}`] = true uniqueKeys.push({ [partitionKeyName]: partitionKey, [sortKeyName]: sortKey }) } }) return uniqueKeys }