@sap/eslint-plugin-cds 2.7.0 → 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 +31 -1
- package/lib/conf/index.js +35 -13
- package/lib/index.js +18 -3
- package/lib/parser.js +1 -1
- package/lib/rules/auth-valid-restrict-where.js +1 -1
- package/lib/utils/createRule.js +9 -5
- 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/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,37 @@ 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
|
-
## [
|
|
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
|
|
10
40
|
|
|
11
41
|
### Added
|
|
12
42
|
|
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/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/utils/createRule.js
CHANGED
|
@@ -62,12 +62,16 @@ module.exports = (spec) => {
|
|
|
62
62
|
break
|
|
63
63
|
|
|
64
64
|
case 'inferred':
|
|
65
|
-
if (isValidFile && doRootModelChecks) {
|
|
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
|
+
}
|
|
66
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) {
|
|
69
74
|
Cache.set(`rule:${cdscontext.id}:${Cache.get('rootpath')}`, 'done')
|
|
70
|
-
Cache.remove(`report:${context.getFilename()}:${context.id}`)
|
|
71
75
|
}
|
|
72
76
|
createReport(node, cdscontext, meta, create)
|
|
73
77
|
} else {
|
|
@@ -113,7 +117,7 @@ function checkEntryCriteria (meta, cdscontext) {
|
|
|
113
117
|
const showInEditor = cdscontext.options.includes('show')
|
|
114
118
|
const hasProjectRoots = Cache.has(`roots:${Cache.get('rootpath')}`)
|
|
115
119
|
const isValidFile = isConfiguredFileType(cdscontext.getFilename(), 'FILES')
|
|
116
|
-
const doRootModelChecks = isTest || (hasProjectRoots && (isRunningWithCDSLint() || isRunningWithESLint() || showInEditor)
|
|
120
|
+
const doRootModelChecks = isTest || (hasProjectRoots && (isRunningWithCDSLint() || isRunningWithESLint()) || showInEditor)
|
|
117
121
|
// Lint all env rules independent of any parsed file (i.e. 'cds lint' uses the lintText "" API)
|
|
118
122
|
const doEnvironmentChecks =
|
|
119
123
|
isTest || (isRunningWithCDSLint() && cdscontext.getFilename() === '<text>')
|
|
@@ -162,8 +166,8 @@ function createReport (node, cdscontext, meta, create) {
|
|
|
162
166
|
const isValidLocation = (meta.model === 'parsed' && d.$location) ||
|
|
163
167
|
(meta.model === 'inferred' && d.$location?.file)
|
|
164
168
|
Object.entries(handlers)
|
|
165
|
-
.filter(([type,
|
|
166
|
-
.forEach(([
|
|
169
|
+
.filter(([type, _lazy]) => d.is(type) && isValidLocation)
|
|
170
|
+
.forEach(([_lazy, handler]) => {
|
|
167
171
|
try {
|
|
168
172
|
handler(d)
|
|
169
173
|
} catch (err) {
|
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"
|