@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 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': 1,
7
- '@sap/cds/auth-valid-restrict-grant': 1,
8
- '@sap/cds/auth-valid-restrict-keys': 1,
9
- '@sap/cds/auth-valid-restrict-to': 'warn',
10
- '@sap/cds/auth-valid-restrict-where': 'warn',
11
- '@sap/cds/latest-cds-version': 'warn',
12
- '@sap/cds/min-node-version': 'error',
13
- '@sap/cds/no-db-keywords': 'error',
14
- '@sap/cds/no-dollar-prefixed-names': 'warn',
15
- '@sap/cds/no-join-on-draft': 'warn',
16
- '@sap/cds/require-2many-oncond': 'error',
17
- '@sap/cds/sql-cast-suggestion': 'warn',
18
- '@sap/cds/start-elements-uppercase': 'warn',
19
- '@sap/cds/start-entities-uppercase': 'warn',
20
- '@sap/cds/valid-csv-header': 'error',
21
- '@sap/cds/extension-restrictions': 'error'
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
  }
@@ -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': 2,
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
@@ -31,6 +31,7 @@ const MODEL_FILES = ['*.cds', '*.csn']
31
31
  const GLOBALS = {
32
32
  SELECT: true,
33
33
  INSERT: true,
34
+ UPSERT: true,
34
35
  UPDATE: true,
35
36
  DELETE: true,
36
37
  CREATE: true,
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
- if (grantValue.includes('*')) {
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
- if (toValue.includes('any')) {
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
- context.report({
116
- messageId: 'InvalidItem',
117
- data: { invalid: value, candidates },
118
- node,
119
- file
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
  }
@@ -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
@@ -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
- minDistWords.push(word)
41
+ if (!threshold || (threshold && levDist < threshold)) {
42
+ minDistWords.push(word)
43
+ }
42
44
  }
43
45
 
44
46
  if (levDist < minDist) {
45
- minDist = levDist
46
- minDistWords = [word]
47
+ if (!threshold || (threshold && levDist < threshold)) {
48
+ minDist = levDist
49
+ minDistWords = [word]
50
+ }
47
51
  }
48
52
  }
49
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/eslint-plugin-cds",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
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": [