UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

93 lines (77 loc) 2.98 kB
const { hasAliasedColumns } = require('../../remote/utils/data') const { revertData } = require('./resolveView') // creates a map with key "remote origin name" and value { as: "projection name"} // if it is an expand, it contains an additional property .expand with classic ref/as syntax // ref/as syntax is kept in order to reuse handleAliasInResult const _createAliasMap = columns => { if (columns) { let aliasMap for (const col of columns) { const processor = {} if (col.as) { processor.as = col.as aliasMap || (aliasMap = new Map()) if (col.ref) { aliasMap.set(col.ref[col.ref.length - 1], processor) } } if (col.expand) { processor.expand = col.expand if (col.expand.some(hasAliasedColumns)) { aliasMap || (aliasMap = new Map()) aliasMap.set(col.ref[col.ref.length - 1], processor) } } } return aliasMap } } // Transforms the result of the remote service according to the provided aliases const handleAliasInResult = (columns, result) => { const postProcessor = _createAliasMap(columns) const resultArray = Array.isArray(result) ? result : [result] if (postProcessor) { for (const row of resultArray) { // we need to use a cache because of cross renamings // e. g. column a is renamed to b and column b is renamed to a const tempCache = new Map() for (const col in row) { const processor = postProcessor.get(col) if (processor && processor.as != null && processor.as !== col) { // if a value for the alias is already present, add it to the cache if (row[processor.as]) { tempCache.set(processor.as, row[processor.as]) } // get the value from cache if present row[processor.as] = tempCache.get(col) || row[col] // if it was not overridden because of a renaming, // delete it from the row if (!tempCache.has(processor.as)) { delete row[col] } } if (processor && processor.expand) { handleAliasInResult(processor.expand, row[processor.as || col]) } } } } } // REVISIT: todo renaming for expanded entities // REVISIT: todo renaming for deep operations const postProcess = (query, result, service, onlySelectAliases = false) => { if (!result) return result //> null and other falsy values must be returned if (query.DELETE) return result if (query.SELECT) { if (query.SELECT.columns?.find(col => col.func === 'count' && col.as === '$count')) { if (result[0] && '$count' in result[0]) return result return [{ $count: result }] } handleAliasInResult(query.SELECT.columns, result) if (onlySelectAliases) return result } const transitions = query._transitions if (transitions) return revertData(result, transitions.at(-1), service) return result } module.exports = postProcess