@nerdware/ddb-single-table
Version:
A schema-based DynamoDB modeling tool, high-level API, and type-generator built to supercharge single-table designs!⚡
85 lines (84 loc) • 4.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertWhereQueryToSdkQueryArgs = void 0;
const ts_type_safety_utils_1 = require("@nerdware/ts-type-safety-utils");
const index_js_1 = require("../../utils/index.js");
const getNormalizedComparisonMeta_js_1 = require("./getNormalizedComparisonMeta.js");
const whereQueryOperatorToExpression_js_1 = require("./whereQueryOperatorToExpression.js");
/**
* This function converts `WhereQuery` objects into the following `QueryCommand` arguments:
*
* - `KeyConditionExpression`
* - `ExpressionAttributeNames`
* - `ExpressionAttributeValues`
*/
const convertWhereQueryToSdkQueryArgs = ({ where, }) => {
// Ensure `where` is a plain Record-like object
if (!(0, ts_type_safety_utils_1.isPlainObject)(where)) {
throw new index_js_1.InvalidExpressionError({
expressionName: "KeyConditionExpression",
invalidValue: where,
invalidValueDescription: `"where" value`,
problem: "Expected an object with enumerable properties, but received",
});
}
// Ensure there are not more than 2 keys in the where object
const whereQueryKeys = Object.keys(where);
if (whereQueryKeys.length > 2) {
throw new index_js_1.InvalidExpressionError({
expressionName: "KeyConditionExpression",
invalidValue: where,
invalidValueDescription: "WhereQuery object",
problem: `KeyConditionExpressions can only include hash and sort keys, but the WhereQuery object contains more than two keys`,
});
}
// Process whereQuery to derive the KCE, EAN, and EAV:
let KeyConditionExpression = "";
const ExpressionAttributeNames = {};
const ExpressionAttributeValues = {};
for (let i = 0; i < whereQueryKeys.length; i++) {
const attrName = whereQueryKeys[i];
const whereQueryComparison = where[attrName]; // Non-null assertion since we know the key exists
// Get the operator and comparand to use in the expression
const { operator, comparand } = (0, getNormalizedComparisonMeta_js_1.getNormalizedComparisonMeta)(attrName, whereQueryComparison);
// Update ExpressionAttributeNames
const eanToken = `#${attrName}`;
ExpressionAttributeNames[eanToken] = attrName;
// Update ExpressionAttributeValues, and get the KCE clause
let kceClause;
if (operator === "between") {
// For "between", the comparand is an array, so we need to add 2 KV-pairs to EAV
const [lowerBoundComparand, upperBoundComparand] = comparand;
const lowerBoundEavToken = `:${attrName}LowerBound`;
const upperBoundEavToken = `:${attrName}UpperBound`;
ExpressionAttributeValues[lowerBoundEavToken] = lowerBoundComparand;
ExpressionAttributeValues[upperBoundEavToken] = upperBoundComparand;
kceClause = whereQueryOperatorToExpression_js_1.WHERE_QUERY_OPERATOR_TO_EXPRESSION[operator](eanToken, [
lowerBoundEavToken,
upperBoundEavToken,
]);
}
else {
const eavToken = `:${attrName}`;
ExpressionAttributeValues[eavToken] = comparand;
kceClause = whereQueryOperatorToExpression_js_1.WHERE_QUERY_OPERATOR_TO_EXPRESSION[operator](eanToken, [eavToken]);
}
// Update the KeyConditionExpression
KeyConditionExpression += KeyConditionExpression.length === 0 ? kceClause : ` AND ${kceClause}`;
}
// If neither are equality clauses, throw an error (KCE requires at least 1 equality clause)
if (!/\s=\s/.test(KeyConditionExpression)) {
throw new index_js_1.InvalidExpressionError({
expressionName: "KeyConditionExpression",
invalidValue: where,
invalidValueDescription: "WhereQuery object",
problem: `KeyConditionExpressions must include an equality check on a table/index hash key`,
});
}
return {
KeyConditionExpression,
ExpressionAttributeNames,
ExpressionAttributeValues,
};
};
exports.convertWhereQueryToSdkQueryArgs = convertWhereQueryToSdkQueryArgs;