@sap/eslint-plugin-cds 4.2.3 → 4.2.4
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
CHANGED
|
@@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
8
8
|
|
|
9
|
+
## [4.2.4] - 2026-06-22
|
|
10
|
+
### Fixed
|
|
11
|
+
- `auth-valid-restrict-grant` no longer crashes on JOINs with three or more tables.
|
|
12
|
+
|
|
9
13
|
## [4.2.3] - 2026-05-12
|
|
10
14
|
### Fixed
|
|
11
15
|
- Don't fail if the `tree-sitter` dependency cannot be installed. This might happen in WebContainer environments where native modules cannot be loaded.
|
package/lib/conf/all.js
CHANGED
|
@@ -12,6 +12,7 @@ module.exports = {
|
|
|
12
12
|
'@sap/cds/latest-cds-version': 'error',
|
|
13
13
|
'@sap/cds/no-db-keywords': 'error',
|
|
14
14
|
'@sap/cds/no-dollar-prefixed-names': 'error',
|
|
15
|
+
'@sap/cds/no-escaped-anno-brackets': 'warn',
|
|
15
16
|
'@sap/cds/no-join-on-draft': 'error',
|
|
16
17
|
'@sap/cds/sql-cast-suggestion': 'error',
|
|
17
18
|
'@sap/cds/start-elements-lowercase': 'error',
|
package/lib/conf/recommended.js
CHANGED
|
@@ -10,6 +10,7 @@ module.exports = {
|
|
|
10
10
|
'@sap/cds/auth-valid-restrict-to': 'warn',
|
|
11
11
|
'@sap/cds/auth-valid-restrict-where': 'warn',
|
|
12
12
|
'@sap/cds/no-dollar-prefixed-names': 'warn',
|
|
13
|
+
'@sap/cds/no-escaped-anno-brackets': 'warn',
|
|
13
14
|
'@sap/cds/no-join-on-draft': 'warn',
|
|
14
15
|
'@sap/cds/sql-cast-suggestion': 'warn',
|
|
15
16
|
'@sap/cds/valid-csv-header': 'warn',
|
|
@@ -21,12 +21,19 @@ function extractActions (e, csn) {
|
|
|
21
21
|
const entity = queue.pop()
|
|
22
22
|
actions.push(...getActions(entity))
|
|
23
23
|
if (isJoin(entity)) {
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
const collectRefs = args => {
|
|
25
|
+
for (const arg of args) {
|
|
26
|
+
if (arg.args) {
|
|
27
|
+
collectRefs(arg.args)
|
|
28
|
+
} else if (arg.ref) {
|
|
29
|
+
const ancestor = csn.definitions[arg.ref[0]]
|
|
30
|
+
if (ancestor) {
|
|
31
|
+
queue.push(ancestor)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
}
|
|
36
|
+
collectRefs(entity.query.SELECT.from.args)
|
|
30
37
|
} else if (isProjection(entity)) {
|
|
31
38
|
const ancestor = csn.definitions[projectionTarget(entity)]
|
|
32
39
|
if (ancestor) {
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { RULE_CATEGORIES } = require('../constants')
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
meta: {
|
|
7
|
+
schema: [{/* to avoid deprecation warning for ESLint 9 */}],
|
|
8
|
+
docs: {
|
|
9
|
+
category: RULE_CATEGORIES.model,
|
|
10
|
+
description: 'Escaped annotation syntax ![@...] is unnecessary in modern CAP CDS.',
|
|
11
|
+
recommended: true,
|
|
12
|
+
url: 'https://cap.cloud.sap/docs/tools/cds-lint/rules/no-escaped-anno-brackets',
|
|
13
|
+
},
|
|
14
|
+
type: 'problem',
|
|
15
|
+
fixable: 'code',
|
|
16
|
+
messages: {
|
|
17
|
+
noEscapedAnno: "Escaped annotation '![@{{name}}]' is unnecessary. Use '@{{name}}' instead.",
|
|
18
|
+
},
|
|
19
|
+
model: 'parsed',
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
create(context) {
|
|
23
|
+
return function checkNoEscapedAnnotations() {
|
|
24
|
+
const sourceCode = context.sourceCode
|
|
25
|
+
const code = sourceCode.getText()
|
|
26
|
+
|
|
27
|
+
const regex = /!\[@([^\]]+)\]/g
|
|
28
|
+
let match
|
|
29
|
+
while ((match = regex.exec(code)) !== null) {
|
|
30
|
+
const index = match.index
|
|
31
|
+
if (_isInCommentOrString(code, index)) continue
|
|
32
|
+
|
|
33
|
+
const name = match[1]
|
|
34
|
+
const loc = sourceCode.getLocFromIndex(index)
|
|
35
|
+
const endLoc = sourceCode.getLocFromIndex(index + match[0].length)
|
|
36
|
+
|
|
37
|
+
context.report({
|
|
38
|
+
messageId: 'noEscapedAnno',
|
|
39
|
+
data: { name },
|
|
40
|
+
loc: { start: loc, end: endLoc },
|
|
41
|
+
fix: fixer => fixer.replaceTextRange(
|
|
42
|
+
[index, index + match[0].length],
|
|
43
|
+
'@' + name
|
|
44
|
+
),
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Checks whether the given index in code falls inside a line comment,
|
|
53
|
+
* block comment, or string literal.
|
|
54
|
+
* @param {string} code
|
|
55
|
+
* @param {number} index
|
|
56
|
+
* @returns {boolean}
|
|
57
|
+
*/
|
|
58
|
+
function _isInCommentOrString(code, index) {
|
|
59
|
+
let i = 0
|
|
60
|
+
let inLineComment = false
|
|
61
|
+
let inBlockComment = false
|
|
62
|
+
let inString = false
|
|
63
|
+
let stringChar = ''
|
|
64
|
+
|
|
65
|
+
while (i < index) {
|
|
66
|
+
const ch = code[i]
|
|
67
|
+
if (inLineComment) {
|
|
68
|
+
if (ch === '\n') inLineComment = false
|
|
69
|
+
} else if (inBlockComment) {
|
|
70
|
+
if (ch === '*' && code[i + 1] === '/') {
|
|
71
|
+
inBlockComment = false
|
|
72
|
+
i++
|
|
73
|
+
}
|
|
74
|
+
} else if (inString) {
|
|
75
|
+
if (ch === '\\') { i++ } // skip escaped char
|
|
76
|
+
else if (ch === stringChar) inString = false
|
|
77
|
+
} else {
|
|
78
|
+
if (ch === '/' && code[i + 1] === '/') { inLineComment = true; i++ }
|
|
79
|
+
else if (ch === '/' && code[i + 1] === '*') { inBlockComment = true; i++ }
|
|
80
|
+
else if (ch === "'" || ch === '"') { inString = true; stringChar = ch }
|
|
81
|
+
}
|
|
82
|
+
i++
|
|
83
|
+
}
|
|
84
|
+
return inLineComment || inBlockComment || inString
|
|
85
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/eslint-plugin-cds",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.4",
|
|
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": [
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"README.md"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@eslint/plugin-kit": "^0.7.
|
|
24
|
-
"semver": "^7.
|
|
23
|
+
"@eslint/plugin-kit": "^0.7.2",
|
|
24
|
+
"semver": "^7.8.2"
|
|
25
25
|
},
|
|
26
26
|
"optionalDependencies": {
|
|
27
27
|
"tree-sitter": "^0.21.1",
|
|
@@ -32,6 +32,6 @@
|
|
|
32
32
|
"eslint": "^9 || ^10"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
|
35
|
-
"node": ">=
|
|
35
|
+
"node": ">=22"
|
|
36
36
|
}
|
|
37
37
|
}
|