dynamodb-toolbox
Version:
Lightweight and type-safe query builder for DynamoDB and TypeScript.
79 lines (78 loc) • 3.19 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseQuery = void 0;
const index_js_1 = require("../../../../errors/index.js");
const index_js_2 = require("../../../../schema/actions/parseCondition/index.js");
const schema_js_1 = require("../../../../schema/binary/schema.js");
const schema_js_2 = require("../../../../schema/item/schema.js");
const schema_js_3 = require("../../../../schema/number/schema.js");
const schema_js_4 = require("../../../../schema/string/schema.js");
const pick_js_1 = require("../../../../utils/pick.js");
const queryOperatorSet = new Set([
'eq',
'gt',
'gte',
'lt',
'lte',
'between',
'beginsWith'
]);
const getIndexKeySchema = (key) => {
switch (key.type) {
case 'number':
return new schema_js_3.NumberSchema({ required: 'never', big: true });
case 'string':
return new schema_js_4.StringSchema({ required: 'never' });
case 'binary':
return new schema_js_1.BinarySchema({ required: 'never' });
}
};
const parseQuery = (table, query) => {
const { index, partition, range } = query;
let primaryKeySchema;
if (index !== undefined) {
const indexKeySchema = table.indexes[index];
if (indexKeySchema === undefined) {
const indexes = Object.keys(table.indexes);
const hasIndex = indexes.length > 0;
throw new index_js_1.DynamoDBToolboxError('queryCommand.invalidIndex', {
message: `Unknown index: ${index}. ${hasIndex ? ` Expected one of: ${indexes.join(', ')}.` : ''}`,
payload: { received: index, ...(hasIndex ? { expected: Object.keys(table.indexes) } : {}) }
});
}
primaryKeySchema = indexKeySchema;
}
else {
primaryKeySchema = table;
}
const { partitionKey = table.partitionKey, sortKey } = primaryKeySchema;
if (partition === undefined) {
throw new index_js_1.DynamoDBToolboxError('queryCommand.invalidPartition', {
message: `Missing query partition. Expected: ${partitionKey.type}.`,
path: partitionKey.name,
payload: { partition }
});
}
const indexSchema = new schema_js_2.ItemSchema({
[partitionKey.name]: getIndexKeySchema(partitionKey),
...(sortKey !== undefined && range !== undefined
? { [sortKey.name]: getIndexKeySchema(sortKey) }
: {})
});
let condition = { attr: partitionKey.name, eq: partition };
if (sortKey !== undefined && range !== undefined) {
const sortKeyCondition = {
attr: sortKey.name,
...(0, pick_js_1.pick)(range, ...queryOperatorSet)
};
condition = { and: [condition, sortKeyCondition] };
}
const conditionParser = new index_js_2.ConditionParser(indexSchema);
const { ConditionExpression, ExpressionAttributeNames, ExpressionAttributeValues } = conditionParser.parse(condition, { expressionId: '0' });
return {
KeyConditionExpression: ConditionExpression,
ExpressionAttributeNames,
ExpressionAttributeValues
};
};
exports.parseQuery = parseQuery;