@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
61 lines (54 loc) • 2.64 kB
JavaScript
const path = require('path')
const cds = require('../../../cds')
const { SEVERITY_WARNING, SEVERITY_INFO } = require('../../constants')
class ExtensionCompilation {
constructor(plugin) {
this._plugin = plugin
}
get plugin() { return this._plugin }
isDuplicateDefinitionError(e) {
return e.code === 'ERR_CDS_COMPILATION_FAILURE' && e.messages?.some(m => m.messageId === 'duplicate-definition')
}
async recompileWithoutDuplicates(messages, saasPkgPath) {
// determine directories containing duplicate CDS definitions
const duplicates = messages?.reduce((acc, m) => {
if (m.messageId === 'duplicate-definition' && m.$location?.file) {
const dirname = path.resolve(cds.root, m.$location.file)
if (!dirname.startsWith(saasPkgPath)) {
acc.add(path.dirname(dirname))
}
}
return acc
}, new Set())
function getPkgName(dirname) {
try {
if (dirname && dirname !== cds.root && path.dirname(dirname) !== dirname) {
const pkg = require(path.join(dirname, 'package.json'))
return pkg.name
}
} catch {
return getPkgName(path.dirname(dirname))
}
}
const pkgNames = [...[...duplicates].reduce((acc, dir) => acc.add(getPkgName(dir)), new Set())]
const modelPaths = this.plugin.task.options.model.filter(m => !pkgNames.some(pkg => m === pkg || m.startsWith(pkg + '/')))
this.plugin.task.options.model = modelPaths
this.plugin.pushMessage(`Duplicate CDS model definitions found. Using CDS artifacts from base model instead and recompiling with model options ${JSON.stringify(modelPaths)}.\nMake sure to use compatible versions for the dependencies '${pkgNames.join(', ')}'.`, SEVERITY_WARNING)
// recompile without duplicates
return this.plugin.model()
}
resolveExtensionFiles(model, saasPkgFolder) {
return model['$sources'].filter(file => file.startsWith(cds.root) && !file.startsWith(saasPkgFolder))
}
reclassifyBaseModelMessages(messages, saasPkgPath) {
const severities = cds.env.cdsc?.severities ?? {}
messages.forEach(m => {
if (m.$location?.file && m.severity === SEVERITY_WARNING) {
if (path.resolve(cds.root, m.$location.file).startsWith(saasPkgPath) && !severities[m.messageId]) {
m.severity = SEVERITY_INFO
}
}
})
}
}
module.exports = ExtensionCompilation