UNPKG

@nova-odm/expressions

Version:

Composable expression objects for Amazon DynamoDB

256 lines 9.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.serializeConditionExpression = exports.isConditionExpression = exports.isConditionExpressionSubject = exports.isConditionExpressionPredicate = exports.contains = exports.beginsWith = exports.attributeType = exports.attributeNotExists = exports.attributeExists = exports.inList = exports.between = exports.greaterThanOrEqualTo = exports.greaterThan = exports.lessThanOrEqualTo = exports.lessThan = exports.notEquals = exports.equals = void 0; var tslib_1 = require("tslib"); var AttributePath_1 = require("./AttributePath"); var FunctionExpression_1 = require("./FunctionExpression"); /** * Create an expression predicate asserting that the subject is equal to the * predicate. */ function equals(operand) { return { type: 'Equals', object: operand, }; } exports.equals = equals; function notEquals(operand) { return { type: 'NotEquals', object: operand, }; } exports.notEquals = notEquals; function lessThan(operand) { return { type: 'LessThan', object: operand, }; } exports.lessThan = lessThan; function lessThanOrEqualTo(operand) { return { type: 'LessThanOrEqualTo', object: operand, }; } exports.lessThanOrEqualTo = lessThanOrEqualTo; function greaterThan(operand) { return { type: 'GreaterThan', object: operand, }; } exports.greaterThan = greaterThan; function greaterThanOrEqualTo(operand) { return { type: 'GreaterThanOrEqualTo', object: operand, }; } exports.greaterThanOrEqualTo = greaterThanOrEqualTo; function between(lowerBound, upperBound) { return { type: 'Between', lowerBound: lowerBound, upperBound: upperBound, }; } exports.between = between; function inList() { var operands = []; for (var _i = 0; _i < arguments.length; _i++) { operands[_i] = arguments[_i]; } return { type: 'Membership', values: operands, }; } exports.inList = inList; function attributeExists() { return { type: 'Function', name: 'attribute_exists', }; } exports.attributeExists = attributeExists; function attributeNotExists() { return { type: 'Function', name: 'attribute_not_exists', }; } exports.attributeNotExists = attributeNotExists; function attributeType(expected) { return { type: 'Function', name: 'attribute_type', expected: expected, }; } exports.attributeType = attributeType; function beginsWith(expected) { return { type: 'Function', name: 'begins_with', expected: expected, }; } exports.beginsWith = beginsWith; function contains(expected) { return { type: 'Function', name: 'contains', expected: expected, }; } exports.contains = contains; /** * Evaluate whether the provided value is a condition expression predicate. */ function isConditionExpressionPredicate(arg) { if (arg && typeof arg === 'object') { switch (arg.type) { case 'Equals': case 'NotEquals': case 'LessThan': case 'LessThanOrEqualTo': case 'GreaterThan': case 'GreaterThanOrEqualTo': return arg.object !== undefined; case 'Between': return arg.lowerBound !== undefined && arg.upperBound !== undefined; case 'Membership': return Array.isArray(arg.values); case 'Function': switch (arg.name) { case 'attribute_exists': case 'attribute_not_exists': return true; case 'attribute_type': case 'begins_with': case 'contains': return typeof arg.expected === 'string'; } } } return false; } exports.isConditionExpressionPredicate = isConditionExpressionPredicate; function isConditionExpressionSubject(arg) { return Boolean(arg) && typeof arg === 'object' && (typeof arg.subject === 'string' || AttributePath_1.AttributePath.isAttributePath(arg.subject)); } exports.isConditionExpressionSubject = isConditionExpressionSubject; /** * Evaluates whether the provided value is a condition expression. */ function isConditionExpression(arg) { var e_1, _a; if (FunctionExpression_1.FunctionExpression.isFunctionExpression(arg)) { return true; } if (Boolean(arg) && typeof arg === 'object') { switch (arg.type) { case 'Not': return isConditionExpression(arg.condition); case 'And': case 'Or': if (Array.isArray(arg.conditions)) { try { for (var _b = tslib_1.__values(arg.conditions), _c = _b.next(); !_c.done; _c = _b.next()) { var condition = _c.value; if (!isConditionExpression(condition)) { return false; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return true; } return false; default: return isConditionExpressionSubject(arg) && isConditionExpressionPredicate(arg); } } return false; } exports.isConditionExpression = isConditionExpression; /** * Convert the provided condition expression object to a string, escaping any * values and attributes to expression-safe placeholders whose expansion value * will be managed by the provided ExpressionAttributes object. */ function serializeConditionExpression(condition, attributes) { if (FunctionExpression_1.FunctionExpression.isFunctionExpression(condition)) { return condition.serialize(attributes); } switch (condition.type) { case 'Equals': return serializeBinaryComparison(condition, attributes, '='); case 'NotEquals': return serializeBinaryComparison(condition, attributes, '<>'); case 'LessThan': return serializeBinaryComparison(condition, attributes, '<'); case 'LessThanOrEqualTo': return serializeBinaryComparison(condition, attributes, '<='); case 'GreaterThan': return serializeBinaryComparison(condition, attributes, '>'); case 'GreaterThanOrEqualTo': return serializeBinaryComparison(condition, attributes, '>='); case 'Between': return "".concat(attributes.addName(condition.subject), " BETWEEN ").concat(serializeOperand(condition.lowerBound, attributes), " AND ").concat(serializeOperand(condition.upperBound, attributes)); case 'Membership': return "".concat(attributes.addName(condition.subject), " IN (").concat(condition.values.map(function (val) { return serializeOperand(val, attributes); }) .join(', '), ")"); case 'Function': var subject = AttributePath_1.AttributePath.isAttributePath(condition.subject) ? condition.subject : new AttributePath_1.AttributePath(condition.subject); switch (condition.name) { case 'attribute_exists': case 'attribute_not_exists': return (new FunctionExpression_1.FunctionExpression(condition.name, subject)) .serialize(attributes); case 'attribute_type': case 'begins_with': case 'contains': return (new FunctionExpression_1.FunctionExpression(condition.name, subject, condition.expected)) .serialize(attributes); } case 'Not': return "NOT (".concat(serializeConditionExpression(condition.condition, attributes), ")"); case 'And': case 'Or': if (condition.conditions.length === 1) { return serializeConditionExpression(condition.conditions[0], attributes); } return condition.conditions .map(function (cond) { return "(".concat(serializeConditionExpression(cond, attributes), ")"); }) .join(" ".concat(condition.type.toUpperCase(), " ")); } } exports.serializeConditionExpression = serializeConditionExpression; function serializeBinaryComparison(cond, attributes, comparator) { return "".concat(attributes.addName(cond.subject), " ").concat(comparator, " ").concat(serializeOperand(cond.object, attributes)); } function serializeOperand(operand, attributes) { if (FunctionExpression_1.FunctionExpression.isFunctionExpression(operand)) { return operand.serialize(attributes); } return AttributePath_1.AttributePath.isAttributePath(operand) ? attributes.addName(operand) : attributes.addValue(operand); } //# sourceMappingURL=ConditionExpression.js.map