@sap/eslint-plugin-cds 2.3.0 → 2.3.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +44 -61
  2. package/lib/api/index.js +11 -13
  3. package/lib/api/lint.d.ts +48 -0
  4. package/lib/constants.js +54 -0
  5. package/lib/index.js +44 -0
  6. package/lib/{impl/parser.js → parser.js} +2 -13
  7. package/lib/processor.js +47 -0
  8. package/lib/{impl/rules → rules}/assoc2many-ambiguous-key.js +50 -53
  9. package/lib/rules/latest-cds-version.js +42 -0
  10. package/lib/rules/min-node-version.js +47 -0
  11. package/lib/rules/no-db-keywords.js +46 -0
  12. package/lib/rules/no-dollar-prefixed-names.js +49 -0
  13. package/lib/{impl/rules → rules}/no-join-on-draft-enabled-entities.js +14 -11
  14. package/lib/rules/require-2many-oncond.js +27 -0
  15. package/lib/rules/sql-cast-suggestion.js +52 -0
  16. package/lib/rules/start-elements-lowercase.js +61 -0
  17. package/lib/rules/start-entities-uppercase.js +55 -0
  18. package/lib/{impl/rules → rules}/valid-csv-header.js +17 -9
  19. package/lib/{impl/utils → utils}/fuzzySearch.js +0 -0
  20. package/lib/utils/helpers.js +47 -0
  21. package/lib/{impl/utils → utils}/jsonc.js +0 -0
  22. package/lib/utils/model.js +387 -0
  23. package/lib/utils/ruleHelpers.js +56 -0
  24. package/lib/utils/ruleTester.js +79 -0
  25. package/lib/utils/rules.js +973 -0
  26. package/lib/{impl/utils → utils}/validate.js +2 -18
  27. package/package.json +2 -2
  28. package/lib/api/formatter.js +0 -182
  29. package/lib/impl/constants.js +0 -30
  30. package/lib/impl/index.js +0 -63
  31. package/lib/impl/processor.js +0 -23
  32. package/lib/impl/ruleFactory.js +0 -341
  33. package/lib/impl/rules/cds-compile-error.js +0 -34
  34. package/lib/impl/rules/latest-cds-version.js +0 -51
  35. package/lib/impl/rules/min-node-version.js +0 -44
  36. package/lib/impl/rules/no-db-keywords.js +0 -38
  37. package/lib/impl/rules/require-2many-oncond.js +0 -31
  38. package/lib/impl/rules/rule.hbs +0 -20
  39. package/lib/impl/rules/sql-cast-suggestion.js +0 -52
  40. package/lib/impl/rules/start-elements-lowercase.js +0 -75
  41. package/lib/impl/rules/start-entities-uppercase.js +0 -65
  42. package/lib/impl/types.d.ts +0 -48
  43. package/lib/impl/utils/helpers.js +0 -68
  44. package/lib/impl/utils/model.js +0 -554
  45. package/lib/impl/utils/rules.js +0 -678
package/CHANGELOG.md CHANGED
@@ -6,60 +6,84 @@ 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.3.4] - 2022-03-31
9
10
 
10
- ## [2.3.0] - 201-12-03
11
+ ### Changed
12
+
13
+ - Only deduplicate model error messages when working within VS Code Editor
14
+ - Hide `no-dollar-prefixed-names` compiler warning message in VS Code Editor (already passed by lsp)
15
+
16
+ ## [2.3.3] - 2022-03-24
17
+
18
+ ### Added
19
+
20
+ - Added new rule `no-dollar-prefixed-names`
21
+ - Lint reports with rules marked with '!' notify of rule compile errors
22
+ - Lint reports of any thrown errors can be exposed by `--debug` (includes stack)
23
+
24
+ ## [2.3.2] - 2022-01-24
25
+
26
+ ### Changed
27
+
28
+ - Rule `require-2many-oncond` now also detect navigations of aaspects for flavor 'parsed'
29
+ - Removed duplicates from rule results of category 'Environment'
11
30
 
12
- ## Added
31
+ ## [2.3.1] - 2021-12-10
32
+
33
+ ### Changed
34
+
35
+ - Removed custom formatter as it is no longer used by `cds lint`.
36
+ - Deduplicate lint results from from rules of category environment.
37
+ - Removed 'unpeploy.json' from files as no lint rule requires it
38
+ - Fixed redundant triggers of model recompilations for non-model files and model files without changes
39
+
40
+ ## [2.3.0] - 2021-12-03
41
+
42
+ ### Added
13
43
 
14
44
  - Added new rule 'valid-csv-header'
15
45
 
16
- ## Changed
46
+ ### Changed
17
47
 
18
48
  - Fixed suggestion messages in editor option (and disabled auto-fix)
19
49
  - Added rule properties 'docs.recommended', 'severity'
20
50
 
21
51
  ## [2.2.2] - 2021-11-08
22
-
23
- ## Added
52
+ ### Added
24
53
 
25
54
  - Added new rule 'no-join-on-draft-enabled-entities'
26
55
 
27
- ## Changed
56
+ ### Changed
28
57
 
29
58
  - Compile 'model' files based on CSN flavor 'inferred'
30
59
  - Compile 'outsider' files based on CSN flavor 'parsed'
31
60
 
32
61
  ## [2.2.1] - 2021-11-01
33
-
34
- ## Changed
62
+ ### Changed
35
63
 
36
64
  - Optimized model loading and fixed bug in loading of 'outsider' files
37
65
 
38
66
  ## [2.2.0] - 2021-10-29
39
-
40
- ## Added
67
+ ### Added
41
68
 
42
69
  - Added typings to javascript for all exposed apis
43
70
 
44
- ## Changed
71
+ ### Changed
45
72
 
46
73
  - Aligned rule creation and tester api with ESLint
47
74
 
48
75
  ## [2.1.2] - 2021-10-05
49
-
50
- ## Changed
76
+ ### Changed
51
77
 
52
78
  - Allow not only *.js but also other file types (i.e. *.ts, etc) to bypass plugin rules
53
79
 
54
80
  ## [2.1.1] - 2021-10-04
55
-
56
- ## Changed
81
+ ### Changed
57
82
 
58
83
  - Added preprocessor to avoid (other plugins) parsing errors on cds files
59
84
 
60
85
  ## [2.1.0] - 2021-09-23
61
-
62
- ## Changed
86
+ ### Changed
63
87
 
64
88
  - Source code is now Javascript only
65
89
  - Rule API simplified to only include report and cds
@@ -67,8 +91,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
67
91
  - Filter out lint messages when run from command line with custom formatter
68
92
 
69
93
  ## [2.0.5] - 2021-07-18
70
-
71
-
72
94
  ### Added
73
95
 
74
96
  - When used from within VS Code ESLint exnteion, do not show environment rules
@@ -77,8 +99,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
77
99
  - Rule 'min-node-version' reverted to use cds.resolve not cds.home
78
100
 
79
101
  ## [2.0.4] - 2021-07-12
80
-
81
-
82
102
  ### Added
83
103
 
84
104
  - Plugin also considers 'outsider' files which are not part of a model
@@ -87,21 +107,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
87
107
  - Custom formatter now prints projectPath for triggered env rule checks
88
108
 
89
109
  ## [2.0.3] - 20210-07-09
90
-
91
110
  ### Changed
92
111
 
93
112
  - Removed `npm-shrinkwrap.json` file from package
94
113
 
95
114
  ## [2.0.2] - 2021-07-07
96
-
97
-
98
115
  ### Changed
99
116
 
100
117
  - Fixed bug that always triggers csn-compile-err on type
101
118
 
102
119
  ## [2.0.1] - 2021-07-06
103
-
104
-
105
120
  ### Added
106
121
 
107
122
  - Re-added model rule 'csn-compile-err' to pass csn compile errors to eslint for readability
@@ -111,8 +126,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
111
126
  - Formatter ignores all lint reports for other file extensions except for those in plugin overrides files
112
127
 
113
128
  ## [2.0.0] - 2021-07-02
114
-
115
-
116
129
  ### Added
117
130
 
118
131
  - New API: split exports into 'impl' (for eslint) and 'api' (for user)
@@ -123,15 +136,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
123
136
  - API: getRuleTester now erquires relative path from ruleTester location to project root
124
137
 
125
138
  ## [1.1.7] - 2021-06-22
126
-
127
-
128
139
  ### Changed
129
140
 
130
141
  - Load/Update model must be in sync with every 'on-type' event
131
142
 
132
143
  ## [1.1.6] - 2021-06-21
133
-
134
-
135
144
  ### Changed
136
145
 
137
146
  - Formatter no longer has explicit dependencies, only reslies on 'stylish' output
@@ -140,26 +149,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
140
149
  - On glob file expressions, gets multiple models in series and reports on all warnings/errors
141
150
 
142
151
  ## [1.1.5] - 2021-05-26
143
-
152
+ ### Changed
144
153
 
145
154
  - Naming convention rules changed to severity 'warning'
146
155
  - Rules of type 'suggestion' must return 'fix' for appliable multipass fixes
147
156
  - Split model generation into load and update to be able to work on all files
148
157
 
149
158
  ## [1.1.4] - 2021-05-20
150
-
151
-
152
159
  ### Changed
153
160
 
154
161
  - Formatter does not show any (env/other) lint messages on model error
155
162
  - Rule lower-camelcase-elements reverted to also check type keys
156
163
  - Rule lower-camelcase-elements is not triggered by element 'ID' (see Bookshop in CAP samples)
157
164
 
158
-
159
165
  ## [1.1.3] - 2021-05-12
160
-
161
-
162
-
163
166
  ### Changed
164
167
 
165
168
  - Changed rule type for naming convention rules to "suggestion"
@@ -167,16 +170,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
167
170
  - Added extra layer to also support ruleTester "environment" checks
168
171
 
169
172
  ## [1.1.2] - 2021-05-05
170
-
171
-
172
173
  ### Changed
173
174
 
174
175
  - Updated all rules to ingest args: (cds, context)
175
176
  - Use context's sourcecode to get correct range indices for fixers
176
177
 
177
178
  ## [1.1.1] - 2021-05-04
178
-
179
-
180
179
  ### Changed
181
180
 
182
181
  - Removed bulky headers from custom formatter
@@ -186,8 +185,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
186
185
  - Fixed formatter to also print any other ESLint messages received
187
186
 
188
187
  ## [1.1.0] - 2021-04-29
189
-
190
-
191
188
  ### Added
192
189
 
193
190
  - Custom cds formatter for separate reporting of env and model checks
@@ -196,25 +193,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
196
193
 
197
194
  - Fixed version of model rule 'sql-cast-suggestion'
198
195
 
199
-
200
196
  ## [1.0.8] - 2021-04-12
201
-
202
-
203
197
  ### Added
204
198
 
205
199
  - Proxy for cds object replaces fragile object clone from before
206
200
  - Added proper typings and ignore where options should remain invisible to the (cds) api
207
201
  - Added docstrings and header to each file to explain ESLint context
208
202
  - Added model rule 'sql-cast-suggestion'
209
-
210
203
  ## [1.0.7] - 2021-04-01
211
-
212
- ### Fixed
204
+ ### Changed
213
205
 
214
206
  - Do not crash if `parserServices.cds` is not available
215
207
 
216
208
  ## [1.0.6] - 2021-04-01
217
-
218
209
  ### Added
219
210
 
220
211
  - peer dependency to `eslint`
@@ -222,7 +213,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
222
213
  - simplified api, cds instead of parserServices
223
214
 
224
215
  ## [1.0.4] - 2021-03-24
225
-
226
216
  ### Changed
227
217
 
228
218
  - Added sync model load from cds to generate fully resolved models
@@ -231,25 +221,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
231
221
  - Removed model rule 'no-entity-moo' and use as sample custom rule in docs
232
222
  - Refactored and added more parserServices
233
223
 
234
-
235
224
  ## [1.0.3] - 2021-01-22
236
-
237
225
  ### Changed
238
226
 
239
227
  - Fixed rule min-node-version to check if cds dependency is installed
240
228
  - Updated README glob statement to double asterisk for check nested dirs
241
229
 
242
-
243
230
  ## [1.0.2] - 2021-01-21
244
-
245
231
  ### Changed
246
232
 
247
233
  - Fixed rules to work in concert and allow for globs
248
234
  - Improved README for better readability
249
235
 
250
-
251
236
  ## [1.0.1] - 2021-01-19
252
-
253
237
  ### Added
254
238
 
255
239
  - Rule `assocs-card-flaw` in category *Model validation*
@@ -258,7 +242,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
258
242
 
259
243
  - Refactoring of ruleFactory and parser code
260
244
 
261
-
262
245
  ## [1.0.0] - 2020-12-07
263
-
246
+ ### Added
264
247
  - Initial release 1.0.0
package/lib/api/index.js CHANGED
@@ -1,24 +1,22 @@
1
+ "use strict";
2
+
1
3
  /**
2
4
  * Our custom ESLint plugin API should:
3
- * - Expose 'createRule', 'defineRule' (experimental) and 'runRuleTester' to
4
- * support the addition of *custom* CDS Lint rules
5
- * - Expose 'getConfigPath', 'getFileExtensions', and 'genDocs' for usage in CDS Lint (@sap/cds-dk)
5
+ * - Expose 'createRule' and 'runRuleTester' to
6
+ * support the addition of *custom* CDS Lint rules at runtime
7
+ * - Expose 'getConfigPath', 'getFileExtensions', and 'genDocs' for usage in
8
+ * 'cds lint' client (@sap/cds-dk)
6
9
  * - Expose 'parserPath' for CDS Lint rule unit tests with ESLint's ruleTester
7
10
  */
8
11
 
9
- const {
10
- createRule,
11
- defineRule,
12
- runRuleTester,
13
- } = require("../impl/ruleFactory");
14
- const { getConfigPath } = require("../impl/utils/model");
15
- const { getFileExtensions } = require("../impl/utils/helpers");
16
- const { genDocs } = require("../impl/utils/rules");
17
- const parserPath = require.resolve("../impl/parser");
12
+ const { runRuleTester } = require("../utils/ruleTester")
13
+ const { getConfigPath } = require("../utils/model");
14
+ const { getFileExtensions } = require("../utils/helpers");
15
+ const { createRule, genDocs } = require("../utils/rules");
16
+ const parserPath = require.resolve("../parser");
18
17
 
19
18
  module.exports = {
20
19
  createRule,
21
- defineRule,
22
20
  runRuleTester,
23
21
  getConfigPath,
24
22
  getFileExtensions,
@@ -0,0 +1,48 @@
1
+
2
+ import { Linter, Rule, RuleTester, SourceCode } from "eslint";
3
+
4
+ export interface CDSRuleContext extends Rule.RuleContext {
5
+ cds: any;
6
+ configPath: string;
7
+ code: string;
8
+ filePath: string;
9
+ options: [];
10
+ id: string;
11
+ sourcecode: SourceCode;
12
+ report: (CDSRuleReport) => void;
13
+ err: Error;
14
+ }
15
+
16
+ export interface CDSRuleSpec {
17
+ meta: CDSRuleMetaData,
18
+ create: (context: CDSRuleContext) => void;
19
+ }
20
+
21
+ export interface CDSRuleMetaData extends Rule.RuleMetaData {
22
+ docs: Rule.RuleMetaData['docs'] & {
23
+ version: string;
24
+ };
25
+ severity?: Linter.RuleLevel;
26
+ }
27
+
28
+ export type CDSRuleReport = Rule.ReportDescriptor & {
29
+ loc?: Rule.ReportDescriptorLocation;
30
+ file?: string;
31
+ };
32
+
33
+ export interface CDSTestCaseError extends RuleTester.TestCaseError {
34
+ message: string | RegExp;
35
+ }
36
+
37
+ export interface CDSRuleTestOpts {
38
+ /** specifies __dirname */
39
+ root: string;
40
+ /** requires your rule .js here */
41
+ rule?: string;
42
+ /** filename ('schema.cds' for model, 'package.json' for env) */
43
+ filename: string;
44
+ /** resolves cds parser path */
45
+ parser?: string;
46
+ /** list of errors from ESLint's [RuleTester](https://eslint.org/docs/developer-guide/nodejs-api#ruletester) */
47
+ errors: CDSTestCaseError[]
48
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * This file is used to store/share any constants for this plugin:
3
+ * - RULE_CATEGORIES: List of plugin's rule categories (used purely as documentation labels)
4
+ * - DEFAULT_RULE_CATEGORY: Default rule category (must be one of plugin's rule categories)
5
+ * - DEFAULT_RULE_SEVERITY: Default rule severity (must be one of those define by ESLint):
6
+ * https://eslint.org/docs/user-guide/configuring/rules#configuring-rules
7
+ * - DEFAULT_RULE_TYPE: Default rule type (must be one of those defined by ESLint):
8
+ * https://eslint.org/docs/developer-guide/working-with-rules#rule-basics
9
+ * - CUSTOM_RULES_DIR: Custom rules directory name in the user's project home
10
+ * (contains rules, docs, tests)
11
+ * - FILES: Files/file extensions which ESLint should lint with this plugin
12
+ * - MODEL_FILES: Files/file extensions which should can be compiled (to CSN)
13
+ * - GLOBALS: Globals which should be exposed to ESLint by this plugin
14
+ */
15
+
16
+ const RULE_CATEGORIES = ["Model Validation", "Environment"];
17
+ const DEFAULT_RULE_CATEGORY = RULE_CATEGORIES[0];
18
+ const DEFAULT_RULE_SEVERITY = "error";
19
+ const DEFAULT_RULE_TYPE = "problem";
20
+
21
+ const PLUGIN_NAME = require("../package.json").name;
22
+ const PLUGIN_PREFIX = "@sap/cds";
23
+ const PROCESSOR_NAME = `${PLUGIN_PREFIX}/cds`
24
+ const CUSTOM_RULES_DIR = ".cdslint";
25
+
26
+ const FILES = ["*.cds", "*.csn", "*.csv"];
27
+ const MODEL_FILES = ["*.cds", "*.csn"];
28
+
29
+ const GLOBALS = {
30
+ SELECT: true,
31
+ INSERT: true,
32
+ UPDATE: true,
33
+ DELETE: true,
34
+ CREATE: true,
35
+ DROP: true,
36
+ CDL: true,
37
+ CQL: true,
38
+ CXL: true,
39
+ cds: true,
40
+ };
41
+
42
+ module.exports = {
43
+ RULE_CATEGORIES,
44
+ DEFAULT_RULE_CATEGORY,
45
+ DEFAULT_RULE_SEVERITY,
46
+ DEFAULT_RULE_TYPE,
47
+ PLUGIN_NAME,
48
+ PLUGIN_PREFIX,
49
+ PROCESSOR_NAME,
50
+ CUSTOM_RULES_DIR,
51
+ FILES,
52
+ MODEL_FILES,
53
+ GLOBALS
54
+ };
package/lib/index.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Custom ESLint plugin:
3
+ * https://eslint.org/docs/developer-guide/working-with-plugins
4
+ * This file exposes our plugins ESLint configuration, which must:
5
+ * - Expose any 'configs' for prescribed rule configuration bundles
6
+ * (i.e. "recommended"). See shareable configs:
7
+ * https://eslint.org/docs/developer-guide/shareable-configs
8
+ * - Expose any 'globals' for use in ESLint
9
+ * - Expose any 'processors' for use in ESLint
10
+ * - Expose any 'rules' for use in ESLint
11
+ */
12
+
13
+ const path = require("path");
14
+ const processor = require("./processor");
15
+
16
+ const { FILES, GLOBALS, PLUGIN_NAME, PROCESSOR_NAME } = require("./constants");
17
+ const { getRules } = require("./utils/rules");
18
+
19
+ const rules = getRules(path.join(__dirname, "rules"));
20
+
21
+ function _getConfig(configName) {
22
+ return {
23
+ globals: GLOBALS,
24
+ plugins: [PLUGIN_NAME],
25
+ overrides: [
26
+ {
27
+ files: FILES,
28
+ processor: PROCESSOR_NAME,
29
+ },
30
+ ],
31
+ rules: rules[configName],
32
+ };
33
+ }
34
+
35
+ module.exports = {
36
+ configs: {
37
+ recommended: _getConfig("recommended"),
38
+ all: _getConfig("all"),
39
+ },
40
+ processors: {
41
+ cds: processor,
42
+ },
43
+ rules: rules.sources,
44
+ };
@@ -9,14 +9,7 @@
9
9
  * (parserOptions). Note, that because we use a 'empty' preprocessor, the
10
10
  * parser is only used by ESLint's ruleTester.
11
11
  */
12
-
13
- const {
14
- getAST,
15
- getCDSProxy,
16
- getLocation,
17
- getRange,
18
- } = require("../impl/utils/model");
19
- const cds = require("@sap/cds");
12
+ const { getAST } = require("./utils/model");
20
13
 
21
14
  module.exports = {
22
15
  parse: function (code, options) {
@@ -24,13 +17,9 @@ module.exports = {
24
17
  },
25
18
 
26
19
  parseForESLint: function (code) {
27
- cds.getLocation = getLocation;
28
- cds.getRange = getRange;
29
20
  return {
30
21
  ast: getAST(code),
31
- services: {
32
- cdsProxy: getCDSProxy(cds),
33
- },
22
+ services: {},
34
23
  scopeManager: null,
35
24
  tokensAndComments: [],
36
25
  visitorKeys: null,
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Custom ESLint processor:
3
+ * https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins
4
+ * This processor is used to avoid parsing errors when this plugin is extended
5
+ * in ESLint alongside other plugins, such as prettier which then also try to
6
+ * read the new file types exposed via globs.
7
+ *
8
+ * Note, that because we cache the file contents and return files contents,
9
+ * the plugin's parser is bypassed so we must retrieve the file contents (see createRule()
10
+ * in utils/rules.js).
11
+ */
12
+
13
+ const { Cache } = require("./utils/model");
14
+ const { isValidFile } = require("./utils/helpers");
15
+
16
+ module.exports = {
17
+ preprocess: function (text, filename) {
18
+ if (isValidFile(filename, 'FILES')) {
19
+ Cache.set(`file:${filename}`, text);
20
+ }
21
+ return [{ text: "", filename }];
22
+ },
23
+ /**
24
+ * Returns message objects as defined by ESLint:
25
+ * https://eslint.org/docs/developer-guide/working-with-custom-formatters#the-message-object
26
+ * @param {*} messages
27
+ * @returns
28
+ */
29
+ postprocess: function (messages) {
30
+ const messagesSanitized = [];
31
+ messages.forEach(fileMessages => {
32
+ const fileMessagesSanitized = [];
33
+ fileMessages.forEach(r => {
34
+ if (r.message.startsWith(`CompilationError:`)) {
35
+ r.message = r.message.replace(`CompilationError: `,
36
+ 'CDS model could not be compiled!\n');
37
+ r.ruleId = `❗${r.ruleId}`;
38
+ r.severity = 2;
39
+ }
40
+ fileMessagesSanitized.push(r);
41
+ })
42
+ messagesSanitized.push(fileMessagesSanitized);
43
+ })
44
+ return [].concat(...messagesSanitized);
45
+ },
46
+ supportsAutofix: true,
47
+ };