UNPKG

breeze-client

Version:

Breeze data management for JavaScript clients

247 lines (242 loc) 9.62 kB
import * as breeze from 'breeze-client'; /** Appends parameter to url, with appropriate delimiter */ function appendQueryStringParameter(url, parameter) { if (!parameter) return url; let separator = url.endsWith("?") ? "" : url.includes("?") ? "&" : "?"; return url + separator + parameter; } /** Encodes the object into query string parameters */ function encodeParams(obj) { let query = ''; let subValue, innerObj, fullSubName; for (let name in obj) { if (!obj.hasOwnProperty(name)) { continue; } let value = obj[name]; if (value instanceof Array) { for (let i = 0; i < value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += encodeParams(innerObj) + '&'; } } else if (value && value.toISOString) { // a feature of Date-like things query += encodeURIComponent(name) + '=' + encodeURIComponent(value.toISOString()) + '&'; } else if (value instanceof Object) { for (let subName in value) { if (obj.hasOwnProperty(name)) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += encodeParams(innerObj) + '&'; } } } else if (value === null) { query += encodeURIComponent(name) + '=&'; } else if (value !== undefined) { query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } } return query.length ? query.substr(0, query.length - 1) : query; } class UriBuilderODataAdapter { name; constructor() { this.name = "odata"; } static register(config) { config = config || breeze.config; config.registerAdapter("uriBuilder", UriBuilderODataAdapter); return config.initializeAdapterInstance("uriBuilder", "odata", true); } initialize() { } buildUri(entityQuery, metadataStore) { // force entityType validation; let entityType = entityQuery._getFromEntityType(metadataStore, false); if (!entityType) { // anonymous type but still has naming convention info avail entityType = new breeze.EntityType(metadataStore); } let queryOptions = {}; queryOptions["$filter"] = toWhereODataFragment(entityQuery.wherePredicate); queryOptions["$orderby"] = toOrderByODataFragment(entityQuery.orderByClause); if (entityQuery.skipCount) { queryOptions["$skip"] = entityQuery.skipCount; } if (entityQuery.takeCount != null) { queryOptions["$top"] = entityQuery.takeCount; } queryOptions["$expand"] = toExpandODataFragment(entityQuery.expandClause); queryOptions["$select"] = toSelectODataFragment(entityQuery.selectClause); if (entityQuery.inlineCountEnabled) { queryOptions["$inlinecount"] = "allpages"; } const qoText = toQueryOptionsString(queryOptions); return appendQueryStringParameter(entityQuery.resourceName, qoText); // private methods to this func. function toWhereODataFragment(wherePredicate) { if (!wherePredicate) return undefined; // validation occurs inside of the toODataFragment call here. let frag = wherePredicate.visit({ entityType: entityType }, toODataFragmentVisitor); return (frag && frag.length > 0) ? frag : undefined; } function toOrderByODataFragment(orderByClause) { if (!orderByClause) return undefined; orderByClause.validate(entityType); let strings = orderByClause.items.map(function (item) { return entityType.clientPropertyPathToServer(item.propertyPath, "/") + (item.isDesc ? " desc" : ""); }); // should return something like CompanyName,Address/City desc return strings.join(','); } function toSelectODataFragment(selectClause) { if (!selectClause) return undefined; selectClause.validate(entityType); let frag = selectClause.propertyPaths.map(function (pp) { return entityType.clientPropertyPathToServer(pp, "/"); }).join(","); return frag; } function toExpandODataFragment(expandClause) { if (!expandClause) return undefined; // no validate on expand clauses currently. // expandClause.validate(entityType); let frag = expandClause.propertyPaths.map(function (pp) { return entityType.clientPropertyPathToServer(pp, "/"); }).join(","); return frag; } function toQueryOptionsString(queryOptions) { let qoStrings = []; for (let qoName in queryOptions) { let qoValue = queryOptions[qoName]; if (qoValue !== undefined) { if (qoValue instanceof Array) { qoValue.forEach(function (qov) { qoStrings.push(qoName + "=" + encodeURIComponent(qov)); }); } else { qoStrings.push(qoName + "=" + encodeURIComponent(qoValue)); } } } if (qoStrings.length > 0) { return qoStrings.join("&"); } else { return ""; } } } } breeze.Predicate.prototype.toODataFragment = function (context) { return this.visit(context, toODataFragmentVisitor); }; let toODataFragmentVisitor = { passthruPredicate: function () { return this.value; }, unaryPredicate: function (context) { let predVal = this.pred.visit(context); return odataOpFrom(this) + " " + "(" + predVal + ")"; }, binaryPredicate: function (context) { let expr1Val = this.expr1.visit(context); let expr2Val = this.expr2.visit(context); let prefix = context.prefix; if (prefix) { expr1Val = prefix + "/" + expr1Val; } let odataOp = odataOpFrom(this); if (this.op.key === 'in') { let result = expr2Val.map(function (v) { return "(" + expr1Val + " eq " + v + ")"; }).join(" or "); return result; } else if (this.op.isFunction) { if (odataOp === "substringof") { return odataOp + "(" + expr2Val + "," + expr1Val + ") eq true"; } else { return odataOp + "(" + expr1Val + "," + expr2Val + ") eq true"; } } else { return expr1Val + " " + odataOp + " " + expr2Val; } }, andOrPredicate: function (context) { let result = this.preds.map(function (pred) { let predVal = pred.visit(context); return "(" + predVal + ")"; }).join(" " + odataOpFrom(this) + " "); return result; }, anyAllPredicate: function (context) { let exprVal = this.expr.visit(context); if (!this.pred.op) { // added 21-Oct-2016 to fix breeze.js issue #172 return exprVal + "/" + odataOpFrom(this) + "()"; } let prefix = context.prefix; if (prefix) { exprVal = prefix + "/" + exprVal; prefix = "x" + (parseInt(prefix.substring(1)) + 1); } else { prefix = "x1"; } // need to create a new context because of 'prefix' let newContext = breeze.core.extend({}, context); newContext.entityType = this.expr.dataType; newContext.prefix = prefix; let newPredVal = this.pred.visit(newContext); return exprVal + "/" + odataOpFrom(this) + "(" + prefix + ": " + newPredVal + ")"; }, litExpr: function () { if (Array.isArray(this.value)) { return this.value.map(function (v) { return this.dataType.fmtOData(v); }, this); } else { return this.dataType.fmtOData(this.value); } }, propExpr: function (context) { let entityType = context.entityType; // '/' is the OData path delimiter return entityType ? entityType.clientPropertyPathToServer(this.propertyPath, "/") : this.propertyPath; }, fnExpr: function (context) { let exprVals = this.exprs.map(function (expr) { return expr.visit(context); }); return this.fnName + "(" + exprVals.join(",") + ")"; } }; let _operatorMap = { 'contains': 'substringof' }; function odataOpFrom(node) { let op = node.op.key; let odataOp = _operatorMap[op]; return odataOp || op; } breeze.config.registerAdapter("uriBuilder", UriBuilderODataAdapter); /** * Generated bundle index. Do not edit. */ export { UriBuilderODataAdapter }; //# sourceMappingURL=breeze-client-adapter-uri-builder-odata.mjs.map