UNPKG

@sap/odata-v4

Version:

OData V4.0 server library

79 lines (73 loc) 3.51 kB
'use strict'; 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;