dynamodb-toolbox
Version:
Lightweight and type-safe query builder for DynamoDB and TypeScript.
103 lines (102 loc) • 5.1 kB
JavaScript
import { EntityPathParser } from '../../../entity/actions/parsePaths/index.js';
import { DynamoDBToolboxError } from '../../../errors/index.js';
import { parseConsistentOption } from '../../../options/consistent.js';
import { rejectExtraOptions } from '../../../options/rejectExtraOptions.js';
import { parseTableNameOption } from '../../../options/tableName.js';
import { Deduper } from '../../../schema/actions/utils/deduper.js';
import { $entities, TableAction } from '../../../table/index.js';
import { isEmpty } from '../../../utils/isEmpty.js';
import { $options, $requests } from './constants.js';
export class BatchGetCommand extends TableAction {
constructor(table, entities = [], requests, options = {}) {
super(table, entities);
this[$requests] = requests;
this[$options] = options;
}
requests(...requests) {
const entities = [];
const entityNames = new Set();
for (const request of requests) {
if (entityNames.has(request.entity.entityName)) {
continue;
}
entities.push(request.entity);
entityNames.add(request.entity.entityName);
}
return new BatchGetCommand(this.table, entities, requests, this[$options]);
}
options(nextOptions) {
return new BatchGetCommand(this.table, this[$entities], this[$requests], typeof nextOptions === 'function' ? nextOptions(this[$options]) : nextOptions);
}
params() {
var _a;
const requests = this[$requests];
if (requests === undefined || requests.length === 0) {
throw new DynamoDBToolboxError('actions.incompleteAction', {
message: 'BatchGetCommand incomplete: No BatchGetRequest supplied'
});
}
const { consistent, attributes: _attributes, tableName, ...extraOptions } = (_a = this[$options]) !== null && _a !== void 0 ? _a : {};
rejectExtraOptions(extraOptions);
if (tableName) {
parseTableNameOption(tableName);
}
const attributes = _attributes;
let projectionExpression = undefined;
const expressionAttributeNames = {};
if (attributes !== undefined && attributes.length > 0) {
const transformedPaths = new Deduper({ serializer: value => value });
for (const entity of this[$entities]) {
const entityTransformedPaths = entity
.build(EntityPathParser)
.transform(attributes, { strict: false });
if (entityTransformedPaths.length === 0) {
throw new DynamoDBToolboxError('batchGetCommand.invalidProjectionExpression', {
message: `Unable to match any expression attribute path with entity: ${entity.entityName}`,
payload: { entity: entity.entityName }
});
}
for (const transformedPath of entityTransformedPaths) {
transformedPaths.push(transformedPath);
}
}
const { ExpressionAttributeNames: projectionAttributeNames, ProjectionExpression } = EntityPathParser.express(transformedPaths.values);
Object.assign(expressionAttributeNames, projectionAttributeNames);
projectionExpression = ProjectionExpression;
const { partitionKey, sortKey, entityAttributeSavedAs } = this.table;
const filteredAttributes = new Set(Object.values(expressionAttributeNames));
// table partitionKey and sortKey are required at all times for response re-ordering
if (!filteredAttributes.has(partitionKey.name)) {
projectionExpression += `, #_pk`;
expressionAttributeNames['#_pk'] = partitionKey.name;
}
if (sortKey !== undefined && !filteredAttributes.has(sortKey.name)) {
projectionExpression += `, #_sk`;
expressionAttributeNames['#_sk'] = sortKey.name;
}
// include the entityAttrSavedAs for faster formatting
if (!filteredAttributes.has(entityAttributeSavedAs)) {
projectionExpression += `, #_et`;
expressionAttributeNames['#_et'] = entityAttributeSavedAs;
}
}
const keys = [];
for (const request of requests) {
const key = request.params();
keys.push(key);
}
return {
[tableName !== null && tableName !== void 0 ? tableName : this.table.getName()]: {
Keys: keys,
...(consistent !== undefined ? { ConsistentRead: parseConsistentOption(consistent) } : {}),
...(projectionExpression !== undefined
? { ProjectionExpression: projectionExpression }
: {}),
...(!isEmpty(expressionAttributeNames)
? { ExpressionAttributeNames: expressionAttributeNames }
: {})
}
};
}
}
BatchGetCommand.actionName = 'batchGet';