ts-odata-client
Version:
OData TypeScript Client
233 lines (232 loc) • 12.1 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ODataV4ExpressionVisitor = void 0;
var TypedExpressionVisitor_1 = require("./TypedExpressionVisitor");
var FieldReference_1 = require("./FieldReference");
var Expression_1 = require("./Expression");
var Literal_1 = require("./Literal");
/**
* Converts a version-agnistic @type {Expression} into an object that holds information that adheres to ODataV4 speifications.
*/
var ODataV4ExpressionVisitor = /** @class */ (function (_super) {
__extends(ODataV4ExpressionVisitor, _super);
function ODataV4ExpressionVisitor() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.oDataQuery = {};
return _this;
}
ODataV4ExpressionVisitor.prototype.selectVisitor = function () {
var fields = [];
for (var _i = 0; _i < arguments.length; _i++) {
fields[_i] = arguments[_i];
}
this.oDataQuery.select = fields.filter(function (v) { return typeof v !== "function"; }).map(function (f) { return f.toString(); });
};
ODataV4ExpressionVisitor.prototype.orderByVisitor = function () {
var _a;
var fields = [];
for (var _i = 0; _i < arguments.length; _i++) {
fields[_i] = arguments[_i];
}
if (!this.oDataQuery.orderBy)
this.oDataQuery.orderBy = [];
(_a = this.oDataQuery.orderBy).push.apply(_a, fields.map(function (f) { return ({ field: f.toString() }); }));
};
ODataV4ExpressionVisitor.prototype.orderByDescendingVisitor = function () {
var _a;
var fields = [];
for (var _i = 0; _i < arguments.length; _i++) {
fields[_i] = arguments[_i];
}
if (!this.oDataQuery.orderBy)
this.oDataQuery.orderBy = [];
(_a = this.oDataQuery.orderBy).push.apply(_a, fields.map(function (f) { return ({ field: f.toString(), sort: "desc" }); }));
};
ODataV4ExpressionVisitor.prototype.skipVisitor = function (value) {
this.oDataQuery.skip = value;
};
ODataV4ExpressionVisitor.prototype.topVisitor = function (value) {
this.oDataQuery.top = value;
};
ODataV4ExpressionVisitor.prototype.expandVisitor = function () {
var _a;
var fields = [];
for (var _i = 0; _i < arguments.length; _i++) {
fields[_i] = arguments[_i];
}
if (!this.oDataQuery.expand || this.oDataQuery.expand.some(function (v) { return v === "*"; }))
this.oDataQuery.expand = [];
(_a = this.oDataQuery.expand).push.apply(_a, fields.map(function (f) { return f.toString(); }));
//ensure unique values
this.oDataQuery.expand = Array.from(new Set(this.oDataQuery.expand));
};
ODataV4ExpressionVisitor.prototype.expandAllVisitor = function () {
this.oDataQuery.expand = ["*"];
};
ODataV4ExpressionVisitor.prototype.getWithCountVisitor = function () {
this.oDataQuery.count = true;
};
ODataV4ExpressionVisitor.prototype.getByKeyVisitor = function (key) {
if (key instanceof Expression_1.Expression) {
if (key.operator !== "literal" /* ExpressionOperator.Literal */)
throw new Error("Only literal expressions allowed for ".concat("literal" /* ExpressionOperator.Literal */, " expession types"));
key = key.operands[0];
}
if (!(key instanceof Literal_1.Literal))
key = new Literal_1.Literal(key);
this.oDataQuery.key = this.deriveLiteral(key);
};
ODataV4ExpressionVisitor.prototype.valueVisitor = function () {
this.oDataQuery.value = true;
};
ODataV4ExpressionVisitor.prototype.predicateVisitor = function (predicate) {
if (!predicate.expression)
return;
if (predicate.expression.previous)
throw new Error("Filter Expressions cannot have a value for 'previous', only operands");
var filter = this.translatePredicateExpression(predicate.expression);
if (this.oDataQuery.filter && filter.length > 1) {
filter = __spreadArray(__spreadArray(["("], filter, true), [")"], false);
}
if (!this.oDataQuery.filter)
this.oDataQuery.filter = "";
this.oDataQuery.filter += filter.join(" ");
};
ODataV4ExpressionVisitor.prototype.translatePredicateExpression = function (expression) {
var _this = this;
var translation = [];
for (var _i = 0, _a = expression.operands; _i < _a.length; _i++) {
var operand = _a[_i];
if (operand instanceof Literal_1.Literal) {
translation.push([this.deriveLiteral(operand)]);
}
else if (operand instanceof FieldReference_1.FieldReference) {
translation.push([operand.toString()]);
}
else if (operand instanceof Expression_1.Expression) {
translation.push(this.translatePredicateExpression(operand));
}
else if (operand instanceof Array) {
translation.push([operand.map(function (i) { return _this.deriveLiteral(new Literal_1.Literal(i)); }).join(",")]);
} //assume this is a literal without the type specified
else
translation.push([this.deriveLiteral(new Literal_1.Literal(operand))]);
}
if (translation.length === 1) {
switch (expression.operator) {
case "not" /* ExpressionOperator.Not */:
return ["not " + this.reduceTranslatedExpression(translation[0])];
default:
throw new Error("Operator '".concat(expression.operator, "' is not supported"));
}
}
else if (translation.length === 2) {
var left = translation[0], right = translation[1];
switch (expression.operator) {
case "and" /* ExpressionOperator.And */:
return [this.reduceTranslatedExpression(left), "and", this.reduceTranslatedExpression(right)];
case "or" /* ExpressionOperator.Or */:
return [this.reduceTranslatedExpression(left), "or", this.reduceTranslatedExpression(right)];
case "equals" /* ExpressionOperator.Equals */:
return ["".concat(this.reduceTranslatedExpression(left), " eq ").concat(this.reduceTranslatedExpression(right))];
case "greaterThan" /* ExpressionOperator.GreaterThan */:
return ["".concat(this.reduceTranslatedExpression(left), " gt ").concat(this.reduceTranslatedExpression(right))];
case "greaterThanOrEqualTo" /* ExpressionOperator.GreaterThanOrEqualTo */:
return ["".concat(this.reduceTranslatedExpression(left), " ge ").concat(this.reduceTranslatedExpression(right))];
case "lessThan" /* ExpressionOperator.LessThan */:
return ["".concat(this.reduceTranslatedExpression(left), " lt ").concat(this.reduceTranslatedExpression(right))];
case "lessThanOrEqualTo" /* ExpressionOperator.LessThanOrEqualTo */:
return ["".concat(this.reduceTranslatedExpression(left), " le ").concat(this.reduceTranslatedExpression(right))];
case "notEquals" /* ExpressionOperator.NotEquals */:
return ["".concat(this.reduceTranslatedExpression(left), " ne ").concat(this.reduceTranslatedExpression(right))];
case "contains" /* ExpressionOperator.Contains */:
return ["contains(".concat(this.reduceTranslatedExpression(left), ",").concat(this.reduceTranslatedExpression(right), ")")];
case "startsWith" /* ExpressionOperator.StartsWith */:
return ["startsWith(".concat(this.reduceTranslatedExpression(left), ",").concat(this.reduceTranslatedExpression(right), ")")];
case "endsWith" /* ExpressionOperator.EndsWith */:
return ["endsWith(".concat(this.reduceTranslatedExpression(left), ",").concat(this.reduceTranslatedExpression(right), ")")];
case "in" /* ExpressionOperator.In */:
return ["".concat(this.reduceTranslatedExpression(left), " in (").concat(this.reduceTranslatedExpression(right), ")")];
default:
throw new Error("Operator '".concat(expression.operator, "' is not supported"));
}
}
else if (translation.length === 3) {
var left = translation[0], center = translation[1], right = translation[2];
switch (expression.operator) {
case "any" /* ExpressionOperator.Any */:
return ["".concat(this.reduceTranslatedExpression(left), "/any(").concat(center, ": ").concat(this.reduceTranslatedExpression(right), ")")];
case "all" /* ExpressionOperator.All */:
return ["".concat(this.reduceTranslatedExpression(left), "/all(").concat(center, ": ").concat(this.reduceTranslatedExpression(right), ")")];
default:
throw new Error("Operator '".concat(expression.operator, "' is not supported"));
}
}
throw new Error("Operator '".concat(expression.operator, "' is not supported"));
};
ODataV4ExpressionVisitor.prototype.reduceTranslatedExpression = function (value) {
if (value.length === 0)
return "";
if (value.length === 1)
return "".concat(value[0]);
return "(".concat(value.join(" "), ")");
};
ODataV4ExpressionVisitor.prototype.deriveLiteral = function (literal) {
var value = literal.value;
switch (literal.literalType) {
case "date" /* ODataType.Date */:
return new Date(value).toISOString().substring(0, 10);
case "guid" /* ODataType.Guid */:
return value.toString();
}
switch (typeof value) {
case "string":
return "'".concat(value, "'");
case "number":
case "boolean":
return value.toString();
case "undefined":
return "null";
case "function":
throw new Error("function not supported");
case "symbol":
throw new Error("symbol not supported");
case "object":
//objects handled below
break;
default:
throw new Error("Unhandled primitive type: ".concat(value));
}
if (value === null)
return "null";
if (value instanceof Date)
return value.toISOString();
return value.toString();
};
return ODataV4ExpressionVisitor;
}(TypedExpressionVisitor_1.TypedExpressionVisitor));
exports.ODataV4ExpressionVisitor = ODataV4ExpressionVisitor;