@sap/odata-v4
Version:
OData V4.0 server library
79 lines (73 loc) • 3.51 kB
JavaScript
;
const ExpandItem = require('./ExpandItem');
const SelectItem = require('./SelectItem');
const TransformationKind = require('./apply/Transformation').TransformationKind;
const QueryOption = require('./UriInfo').QueryOptions;
const NotImplementedError = require('../errors/NotImplementedError');
/**
* ExpandHelper has utility methods for extracting and combining expand information.
*/
class ExpandHelper {
/**
* Merge expand information from a path into existing expand items.
* @param {?(UriResource[])} pathSegments the path
* @param {ExpandItem[]} items the expand information
* @private
*/
static _mergeExpandPathIntoExpandItems(pathSegments, items) {
if (pathSegments[0].getNavigationProperty()) {
let item = items.find(expItem => expItem.getPathSegments()[0].getNavigationProperty()
=== pathSegments[0].getNavigationProperty());
if (!item) item = new ExpandItem().setPathSegments([pathSegments[0]]);
if (pathSegments[1]) {
if (pathSegments[1].getNavigationProperty()) {
let innerItems = item.getOption(QueryOption.EXPAND) || [];
ExpandHelper._mergeExpandPathIntoExpandItems(pathSegments.slice(1), innerItems);
if (innerItems.length) item.setOption(QueryOption.EXPAND, innerItems);
}
item.setOption(QueryOption.SELECT,
(item.getOption(QueryOption.SELECT) || [])
.concat(new SelectItem().setPathSegments([pathSegments[1]])));
}
if (!items.includes(item)) items.push(item);
}
}
/**
* Extract expand information from the $apply system query option.
* @param {?(Transformation[])} transformations transformations from $apply system query option
* @returns {ExpandItem[]} the extracted expand information
* @private
*/
static _getExpandFromApply(transformations) {
let items = [];
if (!transformations) return items;
for (const transformation of transformations) {
if (transformation.getKind() === TransformationKind.GROUP_BY) {
for (const groupByItem of transformation.getGroupByItems()) {
if (groupByItem.isRollupAll() || groupByItem.getRollup().length) {
throw new NotImplementedError('Construction of expand items for rollup is not supported.');
}
const pathSegments = groupByItem.getPathSegments();
if (!pathSegments.length) continue;
ExpandHelper._mergeExpandPathIntoExpandItems(pathSegments, items);
}
} else if (transformation.getKind() === TransformationKind.AGGREGATE) {
items = [];
}
}
return items;
}
/**
* Extract expand information from the request.
* @param {OdataRequest} request the request
* @returns {ExpandItem[]} the extracted expand information
*/
static getFinalExpand(request) {
const uriInfo = request.getUriInfo();
let expandItems = ExpandHelper._getExpandFromApply(uriInfo.getQueryOption(QueryOption.APPLY));
if (!expandItems.length) expandItems = request.getDeepInsertExpand();
if (!expandItems.length) expandItems = uriInfo.getQueryOption(QueryOption.EXPAND) || [];
return expandItems;
}
}
module.exports = ExpandHelper;