@sap/eslint-plugin-cds 2.6.0 → 2.6.1
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 +9 -0
- package/lib/conf/all.js +16 -16
- package/lib/conf/recommended.js +1 -1
- package/lib/constants.js +1 -0
- package/lib/index.js +7 -0
- package/lib/rules/auth-valid-restrict-grant.js +3 -1
- package/lib/rules/auth-valid-restrict-to.js +11 -8
- package/lib/rules/no-db-keywords.js +5 -2
- package/lib/utils/createRule.js +8 -2
- package/lib/utils/findFuzzy.js +8 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,15 @@ 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
|
+
## [2.6.1] - 2023-01-26
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Fixed rule name in ESLint config:all to `@sap/cds/start-elements-lowercase`.
|
|
14
|
+
- Allow expensive rules to be reported when running from ESLint Cli.
|
|
15
|
+
- In _auth-valid-restrict-grant_, only suggest closely related user roles.
|
|
16
|
+
- In _auth-valid-restrict-to_, only suggest `*` if other entries apart from `*` exist.
|
|
17
|
+
|
|
9
18
|
## [2.6.0] - 2022-09-29
|
|
10
19
|
|
|
11
20
|
### Changed
|
package/lib/conf/all.js
CHANGED
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
'@sap/cds/assoc2many-ambiguous-key': 2,
|
|
5
5
|
'@sap/cds/auth-no-empty-restrictions': 2,
|
|
6
|
-
'@sap/cds/auth-use-requires':
|
|
7
|
-
'@sap/cds/auth-valid-restrict-grant':
|
|
8
|
-
'@sap/cds/auth-valid-restrict-keys':
|
|
9
|
-
'@sap/cds/auth-valid-restrict-to':
|
|
10
|
-
'@sap/cds/auth-valid-restrict-where':
|
|
11
|
-
'@sap/cds/latest-cds-version':
|
|
12
|
-
'@sap/cds/min-node-version':
|
|
13
|
-
'@sap/cds/no-db-keywords':
|
|
14
|
-
'@sap/cds/no-dollar-prefixed-names':
|
|
15
|
-
'@sap/cds/no-join-on-draft':
|
|
16
|
-
'@sap/cds/require-2many-oncond':
|
|
17
|
-
'@sap/cds/sql-cast-suggestion':
|
|
18
|
-
'@sap/cds/start-elements-
|
|
19
|
-
'@sap/cds/start-entities-uppercase':
|
|
20
|
-
'@sap/cds/valid-csv-header':
|
|
21
|
-
'@sap/cds/extension-restrictions':
|
|
6
|
+
'@sap/cds/auth-use-requires': 2,
|
|
7
|
+
'@sap/cds/auth-valid-restrict-grant': 2,
|
|
8
|
+
'@sap/cds/auth-valid-restrict-keys': 2,
|
|
9
|
+
'@sap/cds/auth-valid-restrict-to': 2,
|
|
10
|
+
'@sap/cds/auth-valid-restrict-where': 2,
|
|
11
|
+
'@sap/cds/latest-cds-version': 2,
|
|
12
|
+
'@sap/cds/min-node-version': 2,
|
|
13
|
+
'@sap/cds/no-db-keywords': 2,
|
|
14
|
+
'@sap/cds/no-dollar-prefixed-names': 2,
|
|
15
|
+
'@sap/cds/no-join-on-draft': 2,
|
|
16
|
+
'@sap/cds/require-2many-oncond': 2,
|
|
17
|
+
'@sap/cds/sql-cast-suggestion': 2,
|
|
18
|
+
'@sap/cds/start-elements-lowercase': 2,
|
|
19
|
+
'@sap/cds/start-entities-uppercase': 2,
|
|
20
|
+
'@sap/cds/valid-csv-header': 2,
|
|
21
|
+
'@sap/cds/extension-restrictions': 2
|
|
22
22
|
}
|
package/lib/conf/recommended.js
CHANGED
|
@@ -9,7 +9,7 @@ module.exports = {
|
|
|
9
9
|
'@sap/cds/auth-valid-restrict-to': 1,
|
|
10
10
|
'@sap/cds/auth-valid-restrict-where': 1,
|
|
11
11
|
'@sap/cds/min-node-version': 2,
|
|
12
|
-
'@sap/cds/no-db-keywords':
|
|
12
|
+
'@sap/cds/no-db-keywords': 1,
|
|
13
13
|
'@sap/cds/no-dollar-prefixed-names': 1,
|
|
14
14
|
'@sap/cds/no-join-on-draft': 1,
|
|
15
15
|
'@sap/cds/require-2many-oncond': 2,
|
package/lib/constants.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
// index.js
|
|
2
|
+
/**
|
|
3
|
+
* ## Plugin structure
|
|
4
|
+
* This is the main entry point of our [custom ESLint plugin](https://eslint.org/docs/developer-guide/working-with-plugins),
|
|
5
|
+
* which exposes sets of [rules]() along with their [severity configurations]() to the [ESLint Cli]() or [API]().
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
1
8
|
/**
|
|
2
9
|
* Custom ESLint plugin:
|
|
3
10
|
* https://eslint.org/docs/developer-guide/working-with-plugins
|
|
@@ -78,6 +78,7 @@ module.exports = {
|
|
|
78
78
|
})
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
+
// If values do not contain 'READ, WRITE, *', 'WRITE' only is enough
|
|
81
82
|
const allValuesIncluded = grantValue.every((v) => valuesForWrite.includes(v))
|
|
82
83
|
if (allValuesIncluded) {
|
|
83
84
|
context.report({
|
|
@@ -87,7 +88,8 @@ module.exports = {
|
|
|
87
88
|
file
|
|
88
89
|
})
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
+
// If values contain '*', '*' only is enough
|
|
92
|
+
if (grantValue.length > 1 && grantValue.includes('*')) {
|
|
91
93
|
context.report({
|
|
92
94
|
messageId: 'InvalidItem',
|
|
93
95
|
data: { invalid: `[${grantValue}]`, candidates: ['["*"]'] },
|
|
@@ -101,7 +101,8 @@ module.exports = {
|
|
|
101
101
|
file
|
|
102
102
|
})
|
|
103
103
|
} else {
|
|
104
|
-
|
|
104
|
+
// If values contain 'any', 'any' only is enough
|
|
105
|
+
if (toValue.length > 1 && toValue.includes('any')) {
|
|
105
106
|
context.report({
|
|
106
107
|
messageId: 'InvalidItem',
|
|
107
108
|
data: { invalid: `[${toValue}]`, candidates: ['["any"]'] },
|
|
@@ -111,13 +112,15 @@ module.exports = {
|
|
|
111
112
|
}
|
|
112
113
|
toValue.forEach((value) => {
|
|
113
114
|
if (!ROLES.includes(value)) {
|
|
114
|
-
const candidates = findFuzzy(value, ROLES.sort())
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
const candidates = findFuzzy(value, ROLES.sort(), undefined, false, 2)
|
|
116
|
+
if (candidates.length > 0) {
|
|
117
|
+
context.report({
|
|
118
|
+
messageId: 'InvalidItem',
|
|
119
|
+
data: { invalid: value, candidates },
|
|
120
|
+
node,
|
|
121
|
+
file
|
|
122
|
+
})
|
|
123
|
+
}
|
|
121
124
|
}
|
|
122
125
|
})
|
|
123
126
|
}
|
|
@@ -7,7 +7,8 @@ module.exports = {
|
|
|
7
7
|
description: 'Avoid using reserved SQL keywords.',
|
|
8
8
|
recommended: true
|
|
9
9
|
},
|
|
10
|
-
type: 'problem'
|
|
10
|
+
type: 'problem',
|
|
11
|
+
model: 'inferred'
|
|
11
12
|
},
|
|
12
13
|
create (context) {
|
|
13
14
|
const { db = { kind: 'sql' } } = cds.env.requires
|
|
@@ -23,9 +24,11 @@ module.exports = {
|
|
|
23
24
|
// Do not blame in case of external services
|
|
24
25
|
const srv = d._service || (d.parent && d.parent._service)
|
|
25
26
|
if (srv && srv['@cds.external']) return
|
|
27
|
+
if (d.kind === 'entity' && d['@cds.persistence.skip'] === true) return
|
|
26
28
|
context.report({
|
|
27
29
|
message: `'${d.name}' is a reserved keyword in ${db.kind.toUpperCase()}`,
|
|
28
|
-
node: context.getNode(d)
|
|
30
|
+
node: context.getNode(d),
|
|
31
|
+
file: d.$location.file
|
|
29
32
|
})
|
|
30
33
|
}
|
|
31
34
|
}
|
package/lib/utils/createRule.js
CHANGED
|
@@ -91,11 +91,15 @@ function isRunningWithCDSLint () {
|
|
|
91
91
|
return process.argv[0].endsWith('node') && process.argv[1].endsWith('cds') && process.argv[2] === 'lint'
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
function isRunningWithESLint () {
|
|
95
|
+
return process.argv[0].endsWith('node') && process.argv[1].endsWith('eslint')
|
|
96
|
+
}
|
|
97
|
+
|
|
94
98
|
function checkEntryCriteria (meta, cdscontext) {
|
|
95
99
|
const isTest = Cache.has('test')
|
|
96
100
|
const hasProjectRoots = Cache.has(`roots:${Cache.get('rootpath')}`)
|
|
97
101
|
const isValidFile = isConfiguredFileType(cdscontext.getFilename(), 'FILES')
|
|
98
|
-
const doRootModelChecks = isTest || (hasProjectRoots && (isRunningWithCDSLint() || cdscontext.options.includes('show')))
|
|
102
|
+
const doRootModelChecks = isTest || (hasProjectRoots && (isRunningWithCDSLint() || isRunningWithESLint() || cdscontext.options.includes('show')))
|
|
99
103
|
// Also lint empty folders (i.e. lintText "" API)
|
|
100
104
|
const doEnvironmentChecks =
|
|
101
105
|
isTest || (hasProjectRoots && isRunningWithCDSLint() && cdscontext.getSourceCode().lines[0] === '')
|
|
@@ -221,7 +225,9 @@ function isRuleDisabled (line, cdscontext) {
|
|
|
221
225
|
|
|
222
226
|
function cacheReport (r, file, context, meta) {
|
|
223
227
|
delete r.file
|
|
224
|
-
r.node.range
|
|
228
|
+
if (r.node && r.node.range) {
|
|
229
|
+
r.node.range = []
|
|
230
|
+
}
|
|
225
231
|
if (r.messageId) {
|
|
226
232
|
r.message = meta.messages[r.messageId]
|
|
227
233
|
delete r.message
|
package/lib/utils/findFuzzy.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
const cache = {}
|
|
11
11
|
|
|
12
|
-
module.exports = (input, list, log, keepCase = false) => {
|
|
12
|
+
module.exports = (input, list, log, keepCase = false, threshold = Number.MAX_SAFE_INTEGER) => {
|
|
13
13
|
let minDistWords = []
|
|
14
14
|
|
|
15
15
|
if (input.length > 50 || list.length > 50) {
|
|
@@ -38,12 +38,16 @@ module.exports = (input, list, log, keepCase = false) => {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
if (levDist === minDist) {
|
|
41
|
-
|
|
41
|
+
if (!threshold || (threshold && levDist < threshold)) {
|
|
42
|
+
minDistWords.push(word)
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
if (levDist < minDist) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
if (!threshold || (threshold && levDist < threshold)) {
|
|
48
|
+
minDist = levDist
|
|
49
|
+
minDistWords = [word]
|
|
50
|
+
}
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
|
package/package.json
CHANGED