UNPKG

@sap/eslint-plugin-cds

Version:

ESLint plugin including recommended SAP Cloud Application Programming model and environment rules

78 lines (69 loc) 2.06 kB
'use strict' const cds = requireMtx() const { dirname } = require('node:path') const rule = module.exports = { meta: { docs: { description: 'Extensions must not violate restrictions set by the extended SaaS app.', category: 'Model Validation', recommended: true, url: 'https://cap.cloud.sap/docs/tools/cds-lint/rules/extension-restrictions', }, hasSuggestions: false, type: 'problem', model: 'parsed' }, mtxApi: () => { if (!cds) return // no mtxs lib installed if (!cds.xt?.linter) return // too old mtxs return cds.xt.linter }, create (context) { if (!rule.mtxApi()) return // no mtxs lib installed return () => { const extModel = context.getModel() if (!extModel) return const base = baseModel(context) if (!base) return const file = context.getFilename() const findings = rule.mtxApi().lint(extModel, base.model, base.env) for (const finding of findings) { context.report({ message: finding.message, node: context.getNode(finding.element), file }) } } } } /** * @param {CDSRuleContext} context */ function baseModel (context) { let dir = context.getFilename() do { dir = dirname(dir) const projEnv = cds.env.for('cds', dir) if (!projEnv.extends) continue const files = cds.resolve(projEnv.extends, { root: dir }) // resolve local base model if (files?.length) { const model = cds.load(files, { sync: true }) // env of SaaS app is needed for extension rules const env = cds.env.for('cds', dirname(files[0])) return { env, model } } } while (dir && dir !== cds.root && dir.length > 1) } /** @returns { import('@sap/cds/apis/cds') } */ function requireMtx () { const cds = require('@sap/cds') try { // eslint-disable-next-line const pkg = require.resolve('@sap/cds-mtxs', { paths: [cds.root, __dirname] }) return require(pkg) } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') throw e } }