UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

65 lines (51 loc) 2.1 kB
const $collected = Symbol.for('collected') module.exports = function cds_compile_for_assert(csn) { function _asserts4element(element, name, base) { let xpr = element?.['@assert']?.xpr if (!xpr) return const inherited = base.elements[name]?.['@assert']?.xpr if (inherited) { // dedupe by splitting into "when ... then ..." blocks and filtering out own blocks already in @assert of projection target const _inherited = _extract_cases(inherited).map(c => JSON.stringify(c)) const own = _extract_cases(xpr).filter(c => !_inherited.includes(JSON.stringify(c))) if (own.length) xpr = ['case', ...inherited.slice(1, -1), ...own.reduce((acc, cur) => (acc.push(...cur), acc), []), 'end'] } return xpr } function _asserts4entity(entity) { if (entity[$collected]) return // buttom up collection of asserts -> process base entity first projection: if (entity.projection || entity.query) { // during compile for java, model is never linked -> no prototype chain let base = (entity.projection || entity.query.SELECT)?.from?.ref?.[0] if (!base) throw new Error(`Unable to determine base entity of ${entity.name}`) base = csn.definitions[base] // REVISIT: when compiling extensions, base may not be in the model -> OK to abort? if (!base) break projection _asserts4entity(base) for (const each in entity.elements) { const element = entity.elements[each] if (element['@assert']) { element['@assert']._xpr = element['@assert'].xpr element['@assert'].xpr = _asserts4element(element, each, base) } } } entity[$collected] = true } for (const each in csn.definitions) { const entity = csn.definitions[each] if (entity.kind !== 'entity') continue if (!entity.projection && !entity.query) continue _asserts4entity(entity) } } function _extract_cases(xpr) { const cases = [] for (const each of xpr.slice(1, -1)) { if (each === 'when') cases.push([]) cases.at(-1).push(each) } return cases }