pailingual-odata
Version:
TypeScript client for OData v4 services
376 lines (375 loc) • 15 kB
JavaScript
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 (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { EdmEntityType } from "./metadata";
import { getFormatter, serializeValue } from "./serialization";
import { expandExpressionBuild, startsWith } from "./utils";
var Query = /** @class */ (function () {
function Query(_apiMetadata, _entityMetadata, _options) {
this._apiMetadata = _apiMetadata;
this._entityMetadata = _entityMetadata;
this._options = _options;
this._segments = [];
this.params = {};
this._method = "get";
}
Query.create = function (apiMetadata, entityMetadata, options) {
return new Query(apiMetadata, entityMetadata, options)._freeze();
};
Query.prototype._clone = function (beforeFreeze) {
var res = new Query(this._apiMetadata, this._entityMetadata, this._options);
res._segments = this._segments.slice();
var cloneArray = function (a) { return a ? a.slice() : null; };
for (var _i = 0, _a = Object.getOwnPropertyNames(this.params); _i < _a.length; _i++) {
var name_1 = _a[_i];
var val = this.params[name_1];
if (val != undefined) {
res.params[name_1] = Array.isArray(val)
? cloneArray(val)
: val;
}
}
res._method = this._method;
res._payload = this._payload;
if (beforeFreeze)
beforeFreeze(res);
return res._freeze();
};
Query.prototype._freeze = function () {
var _this = this;
//freeze segments
this._segments = Object.freeze(this._segments);
//freeze params
Object.getOwnPropertyNames(this.params).forEach(function (n) {
var v = _this.params[n];
if (v !== null && typeof v === "object")
Object.freeze(v);
});
this.params = Object.freeze(this.params);
this._payload = Object.freeze(this._payload);
//freze query
return Object.freeze(this);
};
Query.prototype._action = function (metadata, args) {
return this._clone(function (q) {
q._segments.push(new ActionSegment(metadata));
q._method = "post";
q._entityMetadata = metadata.returnType && metadata.returnType.type;
if (args && args.length > 0) {
var payload = {};
var edmProps = {};
if (metadata.parameters) {
for (var i = 0; i < args.length; i++) {
var param = metadata.parameters[i];
payload[param.name] = args[i];
edmProps[param.name] = param.type;
}
}
q._entityMetadata = new EdmEntityType("", edmProps);
q._payload = payload;
}
});
};
Query.prototype._func = function (metadata, args) {
return this._clone(function (q) {
q._entityMetadata = metadata.returnType && metadata.returnType.type;
q._segments.push(new FuncSegment(metadata, args));
});
};
Query.prototype.byKey = function (keyExpr) {
return this._clone(function (q) {
var pos = q._segments.length;
if (q._segments[pos - 1] instanceof CastSegment)
pos--;
q._segments.splice(pos, 0, new KeySegment(keyExpr));
});
};
Query.prototype.cast = function (fullTypeName) {
return this._clone(function (q) { return q._segments.push(new CastSegment(fullTypeName)); });
};
Query.prototype.navigate = function (property, entityMetadata) {
return this._clone(function (q) {
q._entityMetadata = entityMetadata;
q._segments.push(new NavigationSegment(property));
});
};
Query.prototype.operation = function (metadata, args) {
return metadata.isAction
? this._action(metadata, args)
: this._func(metadata, args);
};
Query.prototype.count = function (o) {
if (o === void 0) { o = { inline: false }; }
return this._clone(function (q) {
if (o.inline)
q.params.count = true;
else
q._segments.push(new CountSegment());
});
};
Query.prototype.delete = function () {
return this._clone(function (q) {
q._method = "delete";
});
};
Query.prototype.expand = function (expand, expr) {
return this._clone(function (q) {
var expandParam = q.params.expand == null
? q.params.expand = []
: q.params.expand;
expandParam.push({ expand: expand, expr: expr });
});
};
Query.prototype.filter = function (expr) {
return this._clone(function (q) {
var filters = (q.params.filter == null)
? q.params.filter = new Array()
: q.params.filter;
filters.push(expr);
});
};
Query.prototype.insert = function (payload) {
return this._clone(function (q) {
q._payload = payload;
q._method = "post";
});
};
Query.prototype.orderBy = function (expressions) {
return this._clone(function (q) {
var _a;
if (expressions) {
if (!q.params.orderBy)
q.params.orderBy = [];
(_a = q.params.orderBy).push.apply(_a, expressions);
}
});
};
Query.prototype.search = function (expr) {
return this._clone(function (q) {
if (!q.params.search)
q.params.search = [];
q.params.search.push(expr);
});
};
Query.prototype.select = function (fields) {
return this._clone(function (q) { return q.params.select = fields; });
};
Query.prototype.skip = function (num) {
return this._clone(function (q) { return q.params.skip = num; });
};
Query.prototype.top = function (num) {
return this._clone(function (q) { return q.params.top = num; });
};
Query.prototype.update = function (payload, put) {
return this._clone(function (q) {
q._payload = payload;
q._method = put ? "put" : "patch";
});
};
Query.prototype.url = function (queryParams, options) {
if (queryParams === void 0) { queryParams = true; }
var apiRoot = (this._apiMetadata && this._apiMetadata.apiRoot) || "";
var params = queryParams ? this.params : undefined;
var opt = Object.assign({}, this._options, options);
var url = apiRoot + this._segments
.map(function (s) { return s.toUrlFragment(opt); })
.join("");
if (params) {
var urlParams = this.buildParams(opt, '&');
if (urlParams)
return url + "?" + urlParams;
}
return url;
};
Query.prototype.buildParams = function (options, separator) {
var _this = this;
if (separator === void 0) { separator = "&"; }
return Object.getOwnPropertyNames(this.params)
.map(function (n) { return _this.params[n] && _this.processParameter(n, _this.params[n], options); })
.filter(function (v) { return v; })
.join(separator);
};
Query.prototype.processParameter = function (name, value, options) {
var _this = this;
switch (name) {
case "select":
return "$select=" + value.join(",");
case "expand":
return "$expand=" + value.map(function (e) { return _this.expandToString(e, options); }).join(",");
case "filter":
return "$filter=" + value.join(" and ");
case "orderBy":
return "$orderby=" + value.join(",");
case "skip":
return "$skip=" + value;
case "top":
return "$top=" + value;
case "count":
return value === true ? "$count=true" : undefined;
case "search":
return "$search=" + value.join(" AND ");
}
};
Query.prototype.expandToString = function (e, options) {
if (e.expr)
return expandExpressionBuild(e.expand, e.expr, this._apiMetadata, this._entityMetadata, options);
return e.expand;
};
Query.prototype.exec = function (options) {
var opt = Object.assign({}, this._options, options);
var url = this.url(true, opt);
return this._fetchData(url, opt);
};
Query.prototype._fetchData = function (url, options) {
var _this = this;
var fetchApi = (options && options.fetch) || fetch;
var inputFormatter = getFormatter(options.format || "application/json");
var body = this._payload ? inputFormatter.serialize(this._payload, this._entityMetadata, options) : null;
return fetchApi(url, {
method: this._method,
body: body,
headers: { "Content-Type": inputFormatter.contentType, "X-Requested-With": "XMLHttpRequest" },
credentials: options.credentials
})
.then(function (response) { return new Promise(function (resolve, reject) {
if (response.body)
response.text().then(function (body) { return resolve({ response: response, body: body }); }, reject);
else
resolve({ response: response });
}); })
.then(function (data) {
var bodyStr = data.body;
var response = data.response;
var contentType = response.headers.get("Content-Type");
if (response.ok) {
if (bodyStr && bodyStr.length > 0) {
if (!contentType) {
if (startsWith(bodyStr, "{"))
contentType = "application/json";
}
else
contentType = contentType.split(";")[0].trim();
var outputFormatter = getFormatter(contentType);
return outputFormatter.deserialize(bodyStr, _this._apiMetadata, options);
}
else
return null;
}
else {
try {
var odError = bodyStr && JSON.parse(bodyStr);
}
catch (_a) { }
var error = (odError && odError.error) || response.statusText;
throw { status: response.status, error: error };
}
});
};
return Query;
}());
export { Query };
var Segment = /** @class */ (function () {
function Segment() {
}
return Segment;
}());
var NavigationSegment = /** @class */ (function (_super) {
__extends(NavigationSegment, _super);
function NavigationSegment(property) {
var _this = _super.call(this) || this;
_this.property = property;
return _this;
}
NavigationSegment.prototype.toUrlFragment = function () {
return "/" + this.property;
};
return NavigationSegment;
}(Segment));
var KeySegment = /** @class */ (function (_super) {
__extends(KeySegment, _super);
function KeySegment(key) {
var _this = _super.call(this) || this;
_this.key = key;
return _this;
}
KeySegment.prototype.toUrlFragment = function () {
return "(" + this.key + ")";
};
return KeySegment;
}(Segment));
var ActionSegment = /** @class */ (function (_super) {
__extends(ActionSegment, _super);
function ActionSegment(_metadata) {
var _this = _super.call(this) || this;
_this._metadata = _metadata;
return _this;
}
ActionSegment.prototype.toUrlFragment = function (options) {
var actionName = this._metadata.bindingTo
&& options.enableUnqualifiedNameCall != true
? this._metadata.getFullName()
: this._metadata.name;
return "/" + actionName;
};
return ActionSegment;
}(Segment));
var FuncSegment = /** @class */ (function (_super) {
__extends(FuncSegment, _super);
function FuncSegment(__metadata, __args) {
var _this = _super.call(this) || this;
_this.__metadata = __metadata;
_this.__args = __args;
return _this;
}
FuncSegment.prototype.toUrlFragment = function (options) {
var _this = this;
var actionName = this.__metadata.bindingTo
&& options.enableUnqualifiedNameCall != true
? this.__metadata.getFullName()
: this.__metadata.name;
var serializedArgs = this.__args.map(function (a, i) {
if (_this.__metadata.parameters) {
var paramMetadata = _this.__metadata.parameters[i];
if (paramMetadata != null) {
var v = serializeValue(a, paramMetadata.type.type, true);
return [paramMetadata.name, v].join("=");
}
}
throw new Error("Parameter '" + i + "', for function '" + actionName + "', not defined in metadata");
});
return "/" + actionName + "(" + serializedArgs.join(",") + ")";
};
return FuncSegment;
}(Segment));
var CountSegment = /** @class */ (function (_super) {
__extends(CountSegment, _super);
function CountSegment() {
return _super !== null && _super.apply(this, arguments) || this;
}
CountSegment.prototype.toUrlFragment = function () {
return "/$count";
};
return CountSegment;
}(Segment));
var CastSegment = /** @class */ (function (_super) {
__extends(CastSegment, _super);
function CastSegment(__fullTypeName) {
var _this = _super.call(this) || this;
_this.__fullTypeName = __fullTypeName;
return _this;
}
CastSegment.prototype.toUrlFragment = function () {
return "/" + this.__fullTypeName;
};
return CastSegment;
}(Segment));