@sap/cds-mtxs
Version:
SAP Cloud Application Programming Model - Multitenancy library
77 lines (60 loc) • 2.98 kB
JavaScript
const cds = require('@sap/cds/lib')
const { deduplicateMessages } = require('@sap/cds-compiler')
const NamespaceChecker = require('./namespace')
const AnnotationsChecker = require('./annotations')
const AllowlistChecker = require('./allowlist')
const customLinters = []
const LINTER_OPTIONS = ['element-prefix', 'extension-allowlist', 'namespace-blocklist']
const EXT_SERVICE_NAME = 'cds.xt.ExtensibilityService'
const capire = 'https://cap.cloud.sap/docs/guides/extensibility/customization#restrictions'
module.exports.legacyCheck = (env = cds.env) => {
const LEGACY_OPTIONS = ['entity-whitelist', 'service-whitelist', 'namespace-blacklist']
const compat = env.mtx
const conf = env.requires[EXT_SERVICE_NAME] || {}
if ([...LINTER_OPTIONS, ...LEGACY_OPTIONS].some(option => compat?.[option])) {
cds.error(`Error: Legacy configuration 'mtx' is used. Please update to the new linter options. See ${capire} for details.`)
}
for (let p of LEGACY_OPTIONS) if (compat?.[p] || conf?.[p]) {
cds.error(`Error: Legacy option '${p}' is used. Please update to the new linter options: ${LINTER_OPTIONS.join(', ')}. See ${capire} for details.`)
}
}
module.exports.lint = (extCsn, fullCsn, env = cds.env, cloneExt = false) => {
const conf = env.requires[EXT_SERVICE_NAME] || env.mtx || {}
const linter_options = {}
let x
for (let p of LINTER_OPTIONS) if ((x = conf[p])) {
linter_options[p] = x
}
// reflect corrupts csn -> clone before for runtime use case
const reflectedCsn = cds.reflect(cloneExt ? cds.clone(extCsn) : extCsn)
const reflectedFullCsn = cds.reflect(fullCsn)
const compileBaseDir = cds.root
const messages = [
...new NamespaceChecker().check(reflectedCsn, reflectedFullCsn, compileBaseDir, linter_options),
...new AnnotationsChecker().check(reflectedCsn, reflectedFullCsn, compileBaseDir, linter_options, extCsn),
...new AllowlistChecker().check(reflectedCsn, reflectedFullCsn, compileBaseDir, linter_options)
]
for (const linter of customLinters) {
messages.push(...linter.check(reflectedCsn, reflectedFullCsn, compileBaseDir, linter_options))
}
deduplicateMessages(messages)
return messages
}
module.exports.register = (linter) => {
customLinters.push(linter)
}
module.exports.ERR_CDS_VALIDATION_FAILURE = 'ERR_CDS_VALIDATION_FAILURE'
/**
* Sparsely copies the linter-relevant config from the given env into the given target
*/
module.exports.configCopyFrom = (env, target = {}) => {
if (!env.requires?.[EXT_SERVICE_NAME]) return target
const config = {}
Object.keys(env.requires[EXT_SERVICE_NAME])
.filter(key => LINTER_OPTIONS.includes(key)) // only let some keys pass, to not compromise security
.filter(key => !!env.requires[EXT_SERVICE_NAME][key])
.forEach(key => (config[key] = env.requires[EXT_SERVICE_NAME][key]))
target.requires = target.requires || {}
target.requires[EXT_SERVICE_NAME] = config // overwrite ext.service key, though
return target
}