@sap/eslint-plugin-cds 2.2.1 → 2.2.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 +39 -0
- package/lib/api/formatter.js +165 -166
- package/lib/api/index.js +10 -5
- package/lib/impl/constants.js +3 -6
- package/lib/impl/processor.js +3 -3
- package/lib/impl/ruleFactory.js +290 -298
- package/lib/impl/rules/assoc2many-ambiguous-key.js +27 -9
- package/lib/impl/rules/latest-cds-version.js +4 -5
- package/lib/impl/rules/min-node-version.js +0 -1
- package/lib/impl/rules/no-db-keywords.js +25 -15
- package/lib/impl/rules/no-join-on-draft-enabled-entities.js +35 -0
- package/lib/impl/rules/require-2many-oncond.js +1 -1
- package/lib/impl/rules/rule.hbs +15 -8
- package/lib/impl/rules/sql-cast-suggestion.js +4 -2
- package/lib/impl/rules/start-elements-lowercase.js +13 -5
- package/lib/impl/rules/start-entities-uppercase.js +13 -4
- package/lib/impl/utils/helpers.js +27 -48
- package/lib/impl/utils/model.js +524 -481
- package/lib/impl/utils/rules.js +44 -35
- package/lib/impl/utils/validate.js +14 -21
- package/package.json +1 -1
package/lib/impl/utils/rules.js
CHANGED
|
@@ -5,23 +5,14 @@
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const { mkdirp } = require("@sap/cds/lib/utils");
|
|
8
|
-
const { getLastLine } = require("./model");
|
|
8
|
+
const { Cache, getLastLine } = require("./model");
|
|
9
9
|
|
|
10
10
|
const JSONC = require("./jsonc");
|
|
11
|
-
const { categories,
|
|
11
|
+
const { categories, recommended } = require("../constants");
|
|
12
12
|
const REGEX_COMMENT_START = "(/\\*|(.+)?//)(\\s?)+eslint-";
|
|
13
13
|
const REGEX_COMMENTS = `${REGEX_COMMENT_START}(enable|disable)(-next)?(-line)?(.+)?`;
|
|
14
14
|
|
|
15
15
|
module.exports = {
|
|
16
|
-
/**
|
|
17
|
-
* Returns an array of allowed file extensions
|
|
18
|
-
* the plugin can parse of the form "*.ext"
|
|
19
|
-
* @returns {ConfigOverrideFiles} Array of file extensions
|
|
20
|
-
*/
|
|
21
|
-
getFileExtensions: function () {
|
|
22
|
-
return files;
|
|
23
|
-
},
|
|
24
|
-
|
|
25
16
|
/**
|
|
26
17
|
* Turns rules "on" or "off" for given line according to eslint-disable
|
|
27
18
|
* comments:
|
|
@@ -33,16 +24,13 @@ module.exports = {
|
|
|
33
24
|
* @param line current code line to analyze
|
|
34
25
|
* @returns rules dictionary with rules being either 'on' and 'off'
|
|
35
26
|
*/
|
|
36
|
-
getDisabled: function (
|
|
37
|
-
rules,
|
|
38
|
-
listEnvRules,
|
|
39
|
-
listModelRules,
|
|
40
|
-
code,
|
|
41
|
-
sourcecode,
|
|
42
|
-
line
|
|
43
|
-
) {
|
|
27
|
+
getDisabled: function (code, sourcecode, line) {
|
|
44
28
|
const listDisabled = [];
|
|
45
|
-
|
|
29
|
+
let { listEnvRules, listModelRules, listRules } = Cache.get("rulesInfo");
|
|
30
|
+
const rulesDisabled = listRules.reduce(
|
|
31
|
+
(o, key) => ({ ...o, [key]: "on" }),
|
|
32
|
+
{}
|
|
33
|
+
);
|
|
46
34
|
let matches = [];
|
|
47
35
|
if (code) {
|
|
48
36
|
matches = [...code.matchAll(REGEX_COMMENTS)];
|
|
@@ -131,29 +119,20 @@ module.exports = {
|
|
|
131
119
|
},
|
|
132
120
|
|
|
133
121
|
/**
|
|
134
|
-
* Checks whether a
|
|
135
|
-
*
|
|
122
|
+
* Checks whether a lint rule has been disabled by eslint-disable
|
|
123
|
+
* comments at a given location
|
|
136
124
|
* @param entry lint report
|
|
137
125
|
* @param cdscontext cds context object
|
|
138
126
|
* @param rules all availabe rules
|
|
139
127
|
* @returns boolean
|
|
140
128
|
*/
|
|
141
129
|
|
|
142
|
-
|
|
143
|
-
entry,
|
|
144
|
-
cdscontext,
|
|
145
|
-
rules,
|
|
146
|
-
listEnvRules,
|
|
147
|
-
listModelRules
|
|
148
|
-
) {
|
|
130
|
+
isRuleDisabled: function (entry, cdscontext) {
|
|
149
131
|
let isDisabled = false;
|
|
150
132
|
if (entry.loc && entry.loc.start) {
|
|
151
133
|
const line = entry.loc.start.line;
|
|
152
134
|
if (cdscontext) {
|
|
153
135
|
const rulesDisabled = module.exports.getDisabled(
|
|
154
|
-
rules,
|
|
155
|
-
listEnvRules,
|
|
156
|
-
listModelRules,
|
|
157
136
|
cdscontext.code,
|
|
158
137
|
cdscontext.sourcecode,
|
|
159
138
|
line
|
|
@@ -187,7 +166,7 @@ module.exports = {
|
|
|
187
166
|
if (matchQuote) {
|
|
188
167
|
const quote = matchQuote[0].slice(-1);
|
|
189
168
|
const exprStart = `${key}:[\\s]+\\${quote}`;
|
|
190
|
-
const exprEnd = `(\\${quote}
|
|
169
|
+
const exprEnd = `(\\${quote},,?)`;
|
|
191
170
|
const regexKey = new RegExp(`${exprStart}[\\s\\S]*?${exprEnd}`, "gm");
|
|
192
171
|
const matchKey = regexKey.exec(text);
|
|
193
172
|
if (matchKey) {
|
|
@@ -264,17 +243,22 @@ module.exports = {
|
|
|
264
243
|
if (release) {
|
|
265
244
|
version = release;
|
|
266
245
|
}
|
|
246
|
+
|
|
267
247
|
let mdRules = `# @sap/eslint-plugin-cds [${version}]\n\n`;
|
|
268
248
|
if (table) {
|
|
249
|
+
mdRules += `Rules in ESLint are grouped by type to help you understand their purpose. Each rule has emojis denoting:\n\n`;
|
|
250
|
+
mdRules += `✔️ if the plugin's "recommended" configuration enables the rule\n\n`;
|
|
251
|
+
mdRules += `🔧 if problems reported by the rule are automatically fixable (\`--fix\`)\n\n`;
|
|
252
|
+
mdRules += `💡 if problems reported by the rule are manually fixable (editor)\n\n`;
|
|
269
253
|
mdRules += "| | | | | |\n";
|
|
270
254
|
mdRules += "|:-:|:-:|:-:|:-:|:-|\n";
|
|
271
255
|
/* eslint-disable-next-line no-unused-vars */
|
|
272
256
|
Object.entries(ruleDict).forEach(([, rules]) => {
|
|
273
257
|
rules.forEach(function (rule) {
|
|
274
258
|
if (release) {
|
|
275
|
-
mdRules += `| ${rule.recommended} | ${rule.fixable} | ${rule.hasSuggestions} | [${rule.name}](Rules-released.md
|
|
259
|
+
mdRules += `| ${rule.recommended} | ${rule.fixable} | ${rule.hasSuggestions} | [${rule.name}](Rules-released.md#${rule.name}) | ${rule.details}|\n`;
|
|
276
260
|
} else {
|
|
277
|
-
mdRules += `| ${rule.recommended} | ${rule.fixable} | ${rule.hasSuggestions} | [${rule.name}](Rules.md
|
|
261
|
+
mdRules += `| ${rule.recommended} | ${rule.fixable} | ${rule.hasSuggestions} | [${rule.name}](Rules.md#${rule.name}) | ${rule.details}|\n`;
|
|
278
262
|
}
|
|
279
263
|
});
|
|
280
264
|
});
|
|
@@ -538,4 +522,29 @@ module.exports = {
|
|
|
538
522
|
const listRules = listEnvRules.concat(listModelRules);
|
|
539
523
|
return { rules, listRules, listEnvRules, listModelRules };
|
|
540
524
|
},
|
|
525
|
+
|
|
526
|
+
populateRules: function (context, customRulesDir) {
|
|
527
|
+
const configPath = Cache.get("configpath") || "";
|
|
528
|
+
// Allow for custom rules
|
|
529
|
+
if (configPath) {
|
|
530
|
+
let customRulesPath = path.join(
|
|
531
|
+
Cache.get("configpath"),
|
|
532
|
+
customRulesDir,
|
|
533
|
+
"rules"
|
|
534
|
+
);
|
|
535
|
+
let customRulesInfo;
|
|
536
|
+
if (fs.existsSync(customRulesPath)) {
|
|
537
|
+
customRulesInfo = module.exports.getRules(customRulesPath);
|
|
538
|
+
Cache.set("rulesInfo", {
|
|
539
|
+
listEnvRules: context.listEnvRules.concat(
|
|
540
|
+
customRulesInfo.listEnvRules
|
|
541
|
+
),
|
|
542
|
+
listModelRules: context.listModelRules.concat(
|
|
543
|
+
customRulesInfo.listModelRules
|
|
544
|
+
),
|
|
545
|
+
listRules: context.listRules.concat(customRulesInfo.listRules),
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
},
|
|
541
550
|
};
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
module.exports = {
|
|
6
6
|
/**
|
|
7
|
-
* Checks whether the rule name is valid
|
|
8
|
-
*
|
|
9
|
-
* custom rules provided at runtime
|
|
7
|
+
* Checks whether the rule name is valid (i.e. is contained within
|
|
8
|
+
* the plugin's or user's *custom* rules).
|
|
10
9
|
* @param context
|
|
11
10
|
* @param pluginRules
|
|
12
11
|
* @param customRules
|
|
@@ -20,35 +19,29 @@ module.exports = {
|
|
|
20
19
|
},
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
* Checks whether
|
|
24
|
-
*
|
|
25
|
-
* @param cds cds object
|
|
26
|
-
* @param ruleID rule name
|
|
22
|
+
* Checks whether a well-defined cds model exists
|
|
23
|
+
* @param context cds context object
|
|
27
24
|
* @returns
|
|
28
25
|
*/
|
|
29
26
|
isValidModel: function (context) {
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
32
|
-
cds &&
|
|
33
|
-
cds.model &&
|
|
34
|
-
!cds.model.err &&
|
|
35
|
-
!(
|
|
36
|
-
ruleID === "@sap/cds/cds-compile-error" ||
|
|
37
|
-
ruleID === "cds-compile-error"
|
|
38
|
-
)
|
|
39
|
-
) {
|
|
27
|
+
const cds = context.cds;
|
|
28
|
+
if (cds && cds.model && !cds.model.err) {
|
|
40
29
|
return true;
|
|
41
30
|
}
|
|
42
31
|
return false;
|
|
43
32
|
},
|
|
44
33
|
|
|
45
34
|
/**
|
|
46
|
-
* Checks whether
|
|
47
|
-
* @param
|
|
35
|
+
* Checks whether a well-defined cds environment exists
|
|
36
|
+
* @param context cds context object
|
|
48
37
|
* @returns
|
|
49
38
|
*/
|
|
50
|
-
isValidEnv: function (
|
|
51
|
-
if (
|
|
39
|
+
isValidEnv: function (context) {
|
|
40
|
+
if (
|
|
41
|
+
context.options &&
|
|
42
|
+
context.options[0] &&
|
|
43
|
+
context.options[0].environment
|
|
44
|
+
) {
|
|
52
45
|
return true;
|
|
53
46
|
}
|
|
54
47
|
return false;
|
package/package.json
CHANGED