@sap/eslint-plugin-cds 2.6.7 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/lib/conf/all.js +0 -1
- package/lib/conf/index.js +35 -13
- package/lib/conf/recommended.js +0 -1
- package/lib/index.js +18 -3
- package/lib/parser.js +1 -1
- package/lib/rules/auth-valid-restrict-where.js +1 -1
- package/lib/rules/index.js +0 -1
- package/lib/rules/latest-cds-version.js +6 -4
- package/lib/rules/no-db-keywords.js +3 -5
- package/lib/utils/createRule.js +19 -10
- package/lib/utils/genDocs.js +2 -2
- package/lib/utils/getConfigPath.js +16 -9
- package/lib/utils/runRuleTester.js +15 -8
- package/package.json +2 -8
- package/lib/rules/min-node-version.js +0 -48
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,51 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
8
8
|
|
|
9
|
+
## [3.0.2] - 2024-04-29
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Internal parser call now handles `ESLint` version 8 and 9
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- requires `ESLint` version 8 or above
|
|
18
|
+
|
|
19
|
+
## [3.0.1] - 2024-04-25
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Add namespace `@sap/cds` to plugin configuration
|
|
24
|
+
|
|
25
|
+
## [3.0.0] - 2024-04-23
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Support ESLint flat configurations (`eslint@v9`) and make them available as *recommended*, *all*.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- Plugin configurations (*recommended*, *all*) for `eslint@<v9` are now available with the `-legacy` suffix.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- In _latest-cds-version_, get output from `npm outdated` on exit code 1.
|
|
38
|
+
|
|
39
|
+
## [2.7.0] - 2024-04-12
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- Add `getRootPath()` method to `context` object to get the project rootPath.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Rule option "show" now allows inferred rules to rerun/recompile instead of just running once (as is the CLI behavior).
|
|
48
|
+
- Removed `min-node-version` rule, as it is now covered by the cds CLI.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- In _no-db-keywords_, use `getRootPath()` instead of dirname, as wrong paths lead to missing db entries, disabling the rule.
|
|
53
|
+
|
|
9
54
|
## [2.6.7] - 2024-03-11
|
|
10
55
|
|
|
11
56
|
### Fixed
|
package/lib/conf/all.js
CHANGED
|
@@ -10,7 +10,6 @@ module.exports = {
|
|
|
10
10
|
'@sap/cds/auth-valid-restrict-to': 2,
|
|
11
11
|
'@sap/cds/auth-valid-restrict-where': 2,
|
|
12
12
|
'@sap/cds/latest-cds-version': 2,
|
|
13
|
-
'@sap/cds/min-node-version': 2,
|
|
14
13
|
'@sap/cds/no-db-keywords': 2,
|
|
15
14
|
'@sap/cds/no-dollar-prefixed-names': 2,
|
|
16
15
|
'@sap/cds/no-join-on-draft': 2,
|
package/lib/conf/index.js
CHANGED
|
@@ -1,22 +1,44 @@
|
|
|
1
|
+
const path = require('path')
|
|
1
2
|
const { FILES, GLOBALS, PLUGIN_NAME } = require('../constants')
|
|
2
3
|
const { parserPath } = require('../api')
|
|
3
4
|
|
|
4
|
-
function _createConfig (
|
|
5
|
+
function _createConfig (plugin, configName, legacy = false) {
|
|
6
|
+
const config = require(path.join(__dirname, configName))
|
|
7
|
+
if (legacy) {
|
|
8
|
+
return {
|
|
9
|
+
root: true,
|
|
10
|
+
globals: GLOBALS,
|
|
11
|
+
plugins: [PLUGIN_NAME],
|
|
12
|
+
overrides: [
|
|
13
|
+
{
|
|
14
|
+
files: FILES,
|
|
15
|
+
parser: parserPath
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
rules: config
|
|
19
|
+
}
|
|
20
|
+
}
|
|
5
21
|
return {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
],
|
|
22
|
+
languageOptions: {
|
|
23
|
+
globals: GLOBALS,
|
|
24
|
+
parser: require(parserPath)
|
|
25
|
+
},
|
|
26
|
+
plugins: {
|
|
27
|
+
'@sap/cds': plugin
|
|
28
|
+
},
|
|
29
|
+
files: FILES.map(file => file.replace('*.', '**/*.')),
|
|
15
30
|
rules: config
|
|
16
31
|
}
|
|
17
32
|
}
|
|
18
33
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
// Export both eslintrc and flat configs to ensure backwards compatibility (<eslint@v9):
|
|
35
|
+
// https://eslint.org/docs/latest/extend/plugin-migration-flat-config#backwards-compatibility
|
|
36
|
+
module.exports = function (plugin) {
|
|
37
|
+
return {
|
|
38
|
+
all: _createConfig(plugin, 'all'),
|
|
39
|
+
recommended: _createConfig(plugin, 'recommended'),
|
|
40
|
+
// Legacy configs (for backwards compatibility)
|
|
41
|
+
'all-legacy': _createConfig(plugin, 'all', true),
|
|
42
|
+
'recommended-legacy': _createConfig(plugin, 'recommended', true)
|
|
43
|
+
}
|
|
22
44
|
}
|
package/lib/conf/recommended.js
CHANGED
|
@@ -9,7 +9,6 @@ module.exports = {
|
|
|
9
9
|
'@sap/cds/auth-valid-restrict-keys': 1,
|
|
10
10
|
'@sap/cds/auth-valid-restrict-to': 1,
|
|
11
11
|
'@sap/cds/auth-valid-restrict-where': 1,
|
|
12
|
-
'@sap/cds/min-node-version': 2,
|
|
13
12
|
'@sap/cds/no-db-keywords': 1,
|
|
14
13
|
'@sap/cds/no-dollar-prefixed-names': 1,
|
|
15
14
|
'@sap/cds/no-join-on-draft': 1,
|
package/lib/index.js
CHANGED
|
@@ -15,15 +15,30 @@
|
|
|
15
15
|
* - Expose any 'rules' for use in ESLint
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
const path = require('node:path')
|
|
19
|
+
|
|
18
20
|
const api = require('./api')
|
|
21
|
+
const getConfigs = require('./conf')
|
|
19
22
|
const rules = Object.assign(
|
|
20
23
|
{},
|
|
21
24
|
...Object.entries(require('./rules')).map(([k, v]) => ({ [k]: v() }))
|
|
22
25
|
)
|
|
23
|
-
const configs = require('./conf')
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
const packageJson = require(path.join(__dirname, '../package.json'))
|
|
28
|
+
|
|
29
|
+
const plugin = {
|
|
30
|
+
meta: {
|
|
31
|
+
name: packageJson.name,
|
|
32
|
+
version: packageJson.version
|
|
33
|
+
},
|
|
34
|
+
configs: {},
|
|
27
35
|
rules,
|
|
28
36
|
...api
|
|
29
37
|
}
|
|
38
|
+
|
|
39
|
+
// Assign configs here so we can reference `plugin`
|
|
40
|
+
Object.assign(plugin.configs, getConfigs(plugin))
|
|
41
|
+
|
|
42
|
+
// Use commonJS entry point to ensure backwards compatibility (<eslint@v9):
|
|
43
|
+
// https://eslint.org/docs/latest/extend/plugin-migration-flat-config#backwards-compatibility
|
|
44
|
+
module.exports = plugin
|
package/lib/parser.js
CHANGED
package/lib/rules/index.js
CHANGED
|
@@ -11,7 +11,6 @@ const rules = {
|
|
|
11
11
|
'auth-valid-restrict-to': () => createRule(require('./auth-valid-restrict-to')),
|
|
12
12
|
'auth-valid-restrict-where': () => createRule(require('./auth-valid-restrict-where')),
|
|
13
13
|
'latest-cds-version': () => createRule(require('./latest-cds-version')),
|
|
14
|
-
'min-node-version': () => createRule(require('./min-node-version')),
|
|
15
14
|
'no-db-keywords': () => createRule(require('./no-db-keywords')),
|
|
16
15
|
'no-dollar-prefixed-names': () => createRule(require('./no-dollar-prefixed-names')),
|
|
17
16
|
'no-join-on-draft': () => createRule(require('./no-join-on-draft')),
|
|
@@ -22,12 +22,14 @@ module.exports = {
|
|
|
22
22
|
let cdsVersions
|
|
23
23
|
let e = context.getEnvironment()
|
|
24
24
|
if (!e) {
|
|
25
|
-
|
|
26
|
-
.execSync('npm outdated @sap/cds --json', {
|
|
25
|
+
try {
|
|
26
|
+
cp.execSync('npm outdated @sap/cds --json', {
|
|
27
27
|
cwd: process.cwd(),
|
|
28
28
|
stdio: 'pipe'
|
|
29
|
-
})
|
|
30
|
-
|
|
29
|
+
}).toString()
|
|
30
|
+
} catch (err) {
|
|
31
|
+
e = JSON.parse(err.stdout.toString())
|
|
32
|
+
}
|
|
31
33
|
}
|
|
32
34
|
if (e && e['@sap/cds']) {
|
|
33
35
|
cdsVersions = e['@sap/cds']
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const { dirname } = require('path')
|
|
2
|
-
|
|
3
1
|
const cds = require('@sap/cds')
|
|
4
2
|
|
|
5
3
|
module.exports = {
|
|
@@ -13,9 +11,9 @@ module.exports = {
|
|
|
13
11
|
model: 'inferred'
|
|
14
12
|
},
|
|
15
13
|
create (context) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const { requires } = cds.env.for('cds',
|
|
14
|
+
const rootPath = context.getRootPath()
|
|
15
|
+
if (!rootPath) return
|
|
16
|
+
const { requires } = cds.env.for('cds', rootPath)
|
|
19
17
|
if (requires.db?.kind !== 'sqlite') return
|
|
20
18
|
|
|
21
19
|
return {
|
package/lib/utils/createRule.js
CHANGED
|
@@ -49,7 +49,7 @@ module.exports = (spec) => {
|
|
|
49
49
|
}
|
|
50
50
|
const cdscontext = extendContext(node, context, meta)
|
|
51
51
|
Cache.set('context', cdscontext)
|
|
52
|
-
const { isTest, isValidFile, doEnvironmentChecks, doRootModelChecks } = checkEntryCriteria(meta, cdscontext)
|
|
52
|
+
const { isTest, isValidFile, doEnvironmentChecks, doRootModelChecks, showInEditor } = checkEntryCriteria(meta, cdscontext)
|
|
53
53
|
switch (meta.model) {
|
|
54
54
|
case 'none':
|
|
55
55
|
if (doEnvironmentChecks) {
|
|
@@ -62,10 +62,17 @@ module.exports = (spec) => {
|
|
|
62
62
|
break
|
|
63
63
|
|
|
64
64
|
case 'inferred':
|
|
65
|
-
if (isValidFile && doRootModelChecks) {
|
|
66
|
-
if (
|
|
65
|
+
if (isValidFile && (doRootModelChecks)) {
|
|
66
|
+
if (showInEditor) {
|
|
67
|
+
Cache.remove(`model:${Cache.get('rootpath')}`)
|
|
68
|
+
Cache.remove(`rule:${cdscontext.id}:${Cache.get('rootpath')}`)
|
|
69
|
+
Cache.remove(`report:${context.getFilename()}:${context.id}`)
|
|
70
|
+
}
|
|
71
|
+
if (isTest || showInEditor || Cache.has(`rule:${cdscontext.id}:${Cache.get('rootpath')}`)) {
|
|
67
72
|
LOG && LOG(` Model: "${meta.model}" Rule: ${context.id}`)
|
|
68
|
-
|
|
73
|
+
if (!showInEditor) {
|
|
74
|
+
Cache.set(`rule:${cdscontext.id}:${Cache.get('rootpath')}`, 'done')
|
|
75
|
+
}
|
|
69
76
|
createReport(node, cdscontext, meta, create)
|
|
70
77
|
} else {
|
|
71
78
|
if (Cache.has(`report:${context.getFilename()}:${context.id}`)) {
|
|
@@ -107,13 +114,14 @@ function isRunningWithESLint () {
|
|
|
107
114
|
|
|
108
115
|
function checkEntryCriteria (meta, cdscontext) {
|
|
109
116
|
const isTest = Cache.has('test')
|
|
117
|
+
const showInEditor = cdscontext.options.includes('show')
|
|
110
118
|
const hasProjectRoots = Cache.has(`roots:${Cache.get('rootpath')}`)
|
|
111
119
|
const isValidFile = isConfiguredFileType(cdscontext.getFilename(), 'FILES')
|
|
112
|
-
const doRootModelChecks = isTest || (hasProjectRoots && (isRunningWithCDSLint() || isRunningWithESLint() ||
|
|
113
|
-
//
|
|
120
|
+
const doRootModelChecks = isTest || (hasProjectRoots && (isRunningWithCDSLint() || isRunningWithESLint()) || showInEditor)
|
|
121
|
+
// Lint all env rules independent of any parsed file (i.e. 'cds lint' uses the lintText "" API)
|
|
114
122
|
const doEnvironmentChecks =
|
|
115
|
-
isTest || (
|
|
116
|
-
return { isTest, isValidFile, doRootModelChecks, doEnvironmentChecks }
|
|
123
|
+
isTest || (isRunningWithCDSLint() && cdscontext.getFilename() === '<text>')
|
|
124
|
+
return { isTest, isValidFile, doRootModelChecks, doEnvironmentChecks, showInEditor }
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
function setMetaDefaults (meta) {
|
|
@@ -158,8 +166,8 @@ function createReport (node, cdscontext, meta, create) {
|
|
|
158
166
|
const isValidLocation = (meta.model === 'parsed' && d.$location) ||
|
|
159
167
|
(meta.model === 'inferred' && d.$location?.file)
|
|
160
168
|
Object.entries(handlers)
|
|
161
|
-
.filter(([type,
|
|
162
|
-
.forEach(([
|
|
169
|
+
.filter(([type, _lazy]) => d.is(type) && isValidLocation)
|
|
170
|
+
.forEach(([_lazy, handler]) => {
|
|
163
171
|
try {
|
|
164
172
|
handler(d)
|
|
165
173
|
} catch (err) {
|
|
@@ -230,6 +238,7 @@ function extendContext (node, context, meta) {
|
|
|
230
238
|
}
|
|
231
239
|
cdscontext.getLocation = parserServices.getLocation
|
|
232
240
|
cdscontext.getNode = Object.keys(parserServices).length > 0 ? parserServices.getNode : () => node
|
|
241
|
+
cdscontext.getRootPath = () => Cache.get('rootpath')
|
|
233
242
|
return cdscontext
|
|
234
243
|
}
|
|
235
244
|
|
package/lib/utils/genDocs.js
CHANGED
|
@@ -166,7 +166,7 @@ function getPackageVersion (registry) {
|
|
|
166
166
|
stdio: 'pipe'
|
|
167
167
|
})
|
|
168
168
|
.toString()
|
|
169
|
-
} catch (
|
|
169
|
+
} catch (_err) {
|
|
170
170
|
LOG?.(`Failed to connect to ${registry} - check your connection and try again.`)
|
|
171
171
|
exit(0)
|
|
172
172
|
}
|
|
@@ -231,7 +231,7 @@ function getRules (docsPath, rulePath, testPath, versionRequired = '0.0.0', rele
|
|
|
231
231
|
}
|
|
232
232
|
try {
|
|
233
233
|
mdRule = getRuleExamples(rule, ruleTestPath, testPath, rulesEntry)
|
|
234
|
-
} catch (
|
|
234
|
+
} catch (_err) {
|
|
235
235
|
// Just continue
|
|
236
236
|
}
|
|
237
237
|
mdRuleContents = ''
|
|
@@ -9,16 +9,23 @@
|
|
|
9
9
|
const fs = require('fs')
|
|
10
10
|
const path = require('path')
|
|
11
11
|
|
|
12
|
-
module.exports = (currentDir = '.') => {
|
|
13
|
-
|
|
14
|
-
'.
|
|
15
|
-
'.
|
|
16
|
-
'.
|
|
17
|
-
'.eslintrc.yml',
|
|
18
|
-
'.eslintrc.json',
|
|
19
|
-
'.eslintrc',
|
|
20
|
-
'package.json'
|
|
12
|
+
module.exports = (currentDir = '.', legacy=false) => {
|
|
13
|
+
let configFiles = [
|
|
14
|
+
'eslint.config.js',
|
|
15
|
+
'eslint.config.cjs',
|
|
16
|
+
'eslint.config.mjs'
|
|
21
17
|
]
|
|
18
|
+
if (legacy) {
|
|
19
|
+
configFiles = [
|
|
20
|
+
'.eslintrc.js',
|
|
21
|
+
'.eslintrc.cjs',
|
|
22
|
+
'.eslintrc.yaml',
|
|
23
|
+
'.eslintrc.yml',
|
|
24
|
+
'.eslintrc.json',
|
|
25
|
+
'.eslintrc',
|
|
26
|
+
'package.json',
|
|
27
|
+
]
|
|
28
|
+
}
|
|
22
29
|
let configDir = path.resolve(currentDir)
|
|
23
30
|
while (configDir !== path.resolve(configDir, '..')) {
|
|
24
31
|
for (const configFile of configFiles) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
|
|
4
|
-
const { RuleTester } = require('eslint')
|
|
4
|
+
const { Linter, RuleTester } = require('eslint')
|
|
5
5
|
const Cache = require('./Cache')
|
|
6
6
|
const createRule = require('./createRule')
|
|
7
7
|
const isConfiguredFileType = require('./isConfiguredFileType')
|
|
@@ -17,13 +17,13 @@ const { compileModelFromDict } = require('../parser')
|
|
|
17
17
|
* @returns RuleTester results
|
|
18
18
|
*/
|
|
19
19
|
module.exports = (options) => {
|
|
20
|
-
let
|
|
20
|
+
let parserPath
|
|
21
21
|
let rule = {}
|
|
22
22
|
Cache.set('rules', require(path.join(__dirname, '../rules')))
|
|
23
23
|
const rulename = path.basename(options.root)
|
|
24
24
|
if (options.root.startsWith(path.resolve(__dirname, '../..'))) {
|
|
25
25
|
// For plugin's internal tests, resolve parser from here
|
|
26
|
-
|
|
26
|
+
parserPath = require.resolve('../parser')
|
|
27
27
|
const pluginPath = path.join(path.dirname(options.root), '../..')
|
|
28
28
|
rule = createRule(require(`../rules/${path.basename(options.root)}`))
|
|
29
29
|
Cache.set('pluginpath', pluginPath)
|
|
@@ -32,15 +32,22 @@ module.exports = (options) => {
|
|
|
32
32
|
const resolvedPlugin = require.resolve('@sap/eslint-plugin-cds', {
|
|
33
33
|
paths: [options.root]
|
|
34
34
|
})
|
|
35
|
-
|
|
35
|
+
parserPath = path.join(path.dirname(resolvedPlugin), 'parser')
|
|
36
36
|
rule = require(path.join(options.root, `../../rules/${path.basename(options.root)}`))
|
|
37
37
|
const pluginPath = path.join(path.dirname(options.root), '../../..')
|
|
38
38
|
Cache.set('pluginpath', pluginPath)
|
|
39
39
|
}
|
|
40
40
|
let tester = new RuleTester({})
|
|
41
|
-
if (
|
|
42
|
-
|
|
41
|
+
if (parserPath) {
|
|
42
|
+
let options
|
|
43
|
+
if (Number(Linter.version.split('.')[0]) >= 9) {
|
|
44
|
+
options = { languageOptions: { parser: require(parserPath) } }
|
|
45
|
+
} else {
|
|
46
|
+
options = { parser: parserPath }
|
|
47
|
+
}
|
|
48
|
+
tester = new RuleTester(options)
|
|
43
49
|
}
|
|
50
|
+
|
|
44
51
|
const testerCases = {};
|
|
45
52
|
['valid', 'invalid'].forEach((type) => {
|
|
46
53
|
const filePath = path.join(options.root, `${type}/${options.filename}`)
|
|
@@ -79,7 +86,7 @@ module.exports = (options) => {
|
|
|
79
86
|
/**
|
|
80
87
|
* Creates a model for ESLint unit tests
|
|
81
88
|
*/
|
|
82
|
-
function _initModelRuleTester
|
|
89
|
+
function _initModelRuleTester(filePath, flavor) {
|
|
83
90
|
Cache.set('test', true)
|
|
84
91
|
const rootPath = path.dirname(filePath)
|
|
85
92
|
Cache.set('rootpath', rootPath)
|
|
@@ -101,7 +108,7 @@ function _initModelRuleTester (filePath, flavor) {
|
|
|
101
108
|
* @param files
|
|
102
109
|
* @returns dictFiles
|
|
103
110
|
*/
|
|
104
|
-
function _getDictFiles
|
|
111
|
+
function _getDictFiles(input, files) {
|
|
105
112
|
let dictFiles = {}
|
|
106
113
|
if (Cache.has(`dictfiles:${input}`)) {
|
|
107
114
|
dictFiles = Cache.get(`dictfiles:${input}`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/eslint-plugin-cds",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "ESLint plugin including recommended SAP Cloud Application Programming model and environment rules",
|
|
5
5
|
"homepage": "https://cap.cloud.sap/",
|
|
6
6
|
"keywords": [
|
|
@@ -23,14 +23,8 @@
|
|
|
23
23
|
"@sap/cds": ">=5.6.0",
|
|
24
24
|
"semver": "^7.3.4"
|
|
25
25
|
},
|
|
26
|
-
"eslintConfig": {
|
|
27
|
-
"extends": [
|
|
28
|
-
"eslint:recommended",
|
|
29
|
-
"standard"
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
26
|
"peerDependencies": {
|
|
33
|
-
"eslint": ">=
|
|
27
|
+
"eslint": ">=8"
|
|
34
28
|
},
|
|
35
29
|
"engines": {
|
|
36
30
|
"node": ">=18"
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const semver = require('semver')
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
meta: {
|
|
6
|
-
schema: [{/* to avoid deprecation warning for ESLint 9 */}],
|
|
7
|
-
docs: {
|
|
8
|
-
description: 'Checks whether the minimum Node.js version required by `@sap/cds` is achieved.'
|
|
9
|
-
},
|
|
10
|
-
severity: 'off',
|
|
11
|
-
type: 'problem',
|
|
12
|
-
model: 'none'
|
|
13
|
-
},
|
|
14
|
-
create: function (context) {
|
|
15
|
-
return checkMinNodeVersion
|
|
16
|
-
|
|
17
|
-
function checkMinNodeVersion () {
|
|
18
|
-
const e = context.getEnvironment()
|
|
19
|
-
let nodeVersion, nodeVersionCDS
|
|
20
|
-
if (!e) {
|
|
21
|
-
// Get current and required node versions
|
|
22
|
-
try {
|
|
23
|
-
const CDSPath = require.resolve('@sap/cds/package.json', {
|
|
24
|
-
paths: [path.dirname('.')]
|
|
25
|
-
})
|
|
26
|
-
const jsonCDS = require(CDSPath)
|
|
27
|
-
nodeVersion = process.version
|
|
28
|
-
nodeVersionCDS = jsonCDS.engines.node
|
|
29
|
-
} catch (err) {
|
|
30
|
-
// Do not throw
|
|
31
|
-
}
|
|
32
|
-
} else {
|
|
33
|
-
nodeVersion = e.nodeVersion
|
|
34
|
-
nodeVersionCDS = e.nodeVersionCDS
|
|
35
|
-
}
|
|
36
|
-
if (
|
|
37
|
-
nodeVersion &&
|
|
38
|
-
nodeVersionCDS &&
|
|
39
|
-
!semver.satisfies(nodeVersion, nodeVersionCDS, { loose: true })
|
|
40
|
-
) {
|
|
41
|
-
context.report({
|
|
42
|
-
message: `CDS minimum node version of ${nodeVersionCDS} required, found ${nodeVersion}!`,
|
|
43
|
-
node: context.getNode()
|
|
44
|
-
})
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|