@sap/cds-dk 4.5.4 → 4.6.0
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 +20 -0
- package/bin/bind.js +124 -8
- package/bin/cds-ts.js +1 -1
- package/bin/cds.js +1 -0
- package/bin/env.js +50 -9
- package/bin/help.js +1 -0
- package/bin/import.js +34 -14
- package/bin/watch.js +25 -4
- package/lib/bind/bindingResolver.js +138 -0
- package/lib/bind/cfKeyProvider.js +353 -0
- package/lib/bind/userCdsrcJsonStorageProvider.js +144 -0
- package/lib/client/auth_manager.js +4 -4
- package/lib/client/settings_manager.js +1 -1
- package/lib/import/common.js +10 -1
- package/lib/import/importapi.js +4 -3
- package/lib/import/index.js +34 -5
- package/lib/import/message.js +1 -0
- package/lib/import/utils/MetadataConverter.js +25 -4
- package/lib/import/utils/MetadataConverterFactory.js +1 -2
- package/lib/import/utils/MultiMap.js +26 -0
- package/lib/import/v2parser.js +131 -12
- package/lib/import/v4parser.js +212 -172
- package/lib/init/template/lint/files/.eslint/rules/no-entity-moo.js +36 -52
- package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/rule.test.js +15 -0
- package/lib/init/template/lint/index.js +14 -6
- package/lib/init/template/mta/files/mta.yaml.hbs +0 -7
- package/lib/init/template/mtx/files/xs-security.json.hbs +3 -1
- package/lib/init/template/mtx/package/dependencies.package.json +1 -1
- package/lib/init/template/nodejs/files/.gitignore.hbs +3 -0
- package/lib/init/util/commandUtil.js +5 -0
- package/lib/lint/Linter.js +31 -20
- package/lib/lint/checks.js +5 -1
- package/lib/lint/io.js +59 -35
- package/lib/util/term.js +2 -0
- package/lib/watch/node-watch.js +38 -19
- package/npm-shrinkwrap.json +1782 -1138
- package/package.json +3 -3
- package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/test.js +0 -10
|
@@ -1,56 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
module.exports = cdsLint.createRule(
|
|
4
|
-
// Rule meta data
|
|
5
|
-
{
|
|
1
|
+
module.exports = require("@sap/eslint-plugin-cds/lib/api").createRule({
|
|
2
|
+
meta: {
|
|
6
3
|
docs: {
|
|
7
|
-
description: `Demonstrates how to implement a model validation check.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
description: `Demonstrates how to implement a model validation check.
|
|
5
|
+
|
|
6
|
+
__________________-_______
|
|
7
|
+
< Entity 'Moo' not allowed! >
|
|
8
|
+
--------------------------
|
|
9
|
+
\ ^__^
|
|
10
|
+
\ (oo)\_______
|
|
11
|
+
(__)\ )\/\
|
|
12
|
+
||----w |
|
|
13
|
+
|| ||`,
|
|
14
|
+
version: "1.0.0",
|
|
18
15
|
},
|
|
19
16
|
fixable: "code",
|
|
20
|
-
type: "problem",
|
|
21
|
-
version: "1.0.0",
|
|
22
17
|
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const fix = (fixer) => {
|
|
47
|
-
const rangeEnd = sourcecode.getIndexFromLoc({line: loc.end.line, column: loc.end.column});
|
|
48
|
-
return fixer.insertTextAfterRange([0, rangeEnd], "n");
|
|
49
|
-
};
|
|
50
|
-
report.push({ message: "Entity 'Moo' not allowed!", loc, fix, file: d.$location.file });
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
return report;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
);
|
|
18
|
+
create: function (context) {
|
|
19
|
+
const m = context.cds.model;
|
|
20
|
+
m.forall("entity", (d) => {
|
|
21
|
+
const entityName = d.name.split(".").pop();
|
|
22
|
+
if (entityName === "Moo") {
|
|
23
|
+
const loc = context.cds.getLocation(entityName, d);
|
|
24
|
+
const fix = (fixer) => {
|
|
25
|
+
const rangeEnd = context.sourcecode.getIndexFromLoc({
|
|
26
|
+
line: loc.end.line,
|
|
27
|
+
column: loc.end.column,
|
|
28
|
+
});
|
|
29
|
+
return fixer.insertTextAfterRange([0, rangeEnd], "n");
|
|
30
|
+
};
|
|
31
|
+
context.report({
|
|
32
|
+
message: "Entity 'Moo' not allowed!",
|
|
33
|
+
loc,
|
|
34
|
+
fix,
|
|
35
|
+
file: d.$location.file,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const { runRuleTester } = require("@sap/eslint-plugin-cds/lib/api");
|
|
2
|
+
|
|
3
|
+
runRuleTester({
|
|
4
|
+
root: __dirname,
|
|
5
|
+
filename: "schema.cds",
|
|
6
|
+
errors: [
|
|
7
|
+
{
|
|
8
|
+
message: "Entity 'Moo' not allowed!",
|
|
9
|
+
line: 2,
|
|
10
|
+
column: 8,
|
|
11
|
+
endLine: 2,
|
|
12
|
+
endColumn: 11,
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
});
|
|
@@ -24,6 +24,7 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
24
24
|
this.lintType = "local";
|
|
25
25
|
this.customRuleExample = false;
|
|
26
26
|
this.missingNpmDependencies = { names: [], msgs: [] };
|
|
27
|
+
this.isTest = false;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
async checkEnabled() {
|
|
@@ -45,13 +46,15 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
45
46
|
const globalPath = path.join(cdsdkPath, "../..");
|
|
46
47
|
|
|
47
48
|
// Require ESLint v>=7.0.0
|
|
48
|
-
this.
|
|
49
|
+
if (!this.isTest) {
|
|
50
|
+
this._checkEslint(globalPath);
|
|
51
|
+
}
|
|
49
52
|
|
|
50
53
|
// To enable custom lint rules ('lint' or 'lint:dev')
|
|
51
54
|
if (this.lintType === "local") {
|
|
52
55
|
// Require local ESLint plugin installation and corresponding config
|
|
53
56
|
this._checkEslintPlugin();
|
|
54
|
-
this._addEslintPluginConfig();
|
|
57
|
+
await this._addEslintPluginConfig();
|
|
55
58
|
// Include custom lint sample rule and test ('lint:dev')
|
|
56
59
|
if (this.customRuleExample) {
|
|
57
60
|
// Generate custom lint rules dirs
|
|
@@ -101,15 +104,19 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
101
104
|
this.logger.log("\n");
|
|
102
105
|
}
|
|
103
106
|
});
|
|
104
|
-
|
|
105
107
|
this._promptInstallDependencies(task);
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
}
|
|
111
|
+
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
_checkEslint(globalPath) {
|
|
112
|
-
const
|
|
115
|
+
const eslintInfo = checks.resolveEslint(this.projectPath, globalPath);
|
|
116
|
+
let eslintCmd;
|
|
117
|
+
if (eslintInfo) {
|
|
118
|
+
eslintCmd = eslintInfo.cmd;
|
|
119
|
+
}
|
|
113
120
|
if (!eslintCmd) {
|
|
114
121
|
this.missingNpmDependencies["names"].push("eslint");
|
|
115
122
|
this.missingNpmDependencies["msgs"].push("ESLint v>=7.0.0");
|
|
@@ -144,9 +151,10 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
144
151
|
|
|
145
152
|
async _addEslintPluginConfig() {
|
|
146
153
|
let configPath = getConfigPath(this.projectPath, this.logger);
|
|
147
|
-
if (configPath) {
|
|
148
|
-
|
|
154
|
+
if (!configPath) {
|
|
155
|
+
configPath = path.join(this.projectPath, ".eslintrc");
|
|
149
156
|
}
|
|
157
|
+
await io.sanitizeEslintConfig(configPath, this.customRuleExample, this.logger);
|
|
150
158
|
return;
|
|
151
159
|
}
|
|
152
160
|
|
|
@@ -38,7 +38,6 @@ modules:
|
|
|
38
38
|
{{#cap.isJava}}
|
|
39
39
|
{{#cap.isMultitenant}}
|
|
40
40
|
properties:
|
|
41
|
-
SAP_JWT_TRUST_ACL: [{"clientid":"*","identityzone":"sap-provisioning"}] # Trust between server and SaaS Manager
|
|
42
41
|
SPRING_PROFILES_ACTIVE: cloud
|
|
43
42
|
{{/cap.isMultitenant}}
|
|
44
43
|
{{^cap.isMultitenant}}
|
|
@@ -50,12 +49,6 @@ modules:
|
|
|
50
49
|
commands: [ mvn clean package ]
|
|
51
50
|
build-result: "target/*-exec.[wj]ar"
|
|
52
51
|
{{/cap.isJava}}
|
|
53
|
-
{{#cap.isNodejs}}
|
|
54
|
-
{{#cap.isMultitenant}}
|
|
55
|
-
properties:
|
|
56
|
-
SAP_JWT_TRUST_ACL: [{"clientid":"*","identityzone":"sap-provisioning"}] # Trust between server and SaaS Manager
|
|
57
|
-
{{/cap.isMultitenant}}
|
|
58
|
-
{{/cap.isNodejs}}
|
|
59
52
|
{{#cap.hasRequires}}
|
|
60
53
|
requires:
|
|
61
54
|
{{#cap.isJava}}
|
|
@@ -50,12 +50,17 @@ class CommandUtil {
|
|
|
50
50
|
resolve(stdLogBuffer.getResult());
|
|
51
51
|
} else {
|
|
52
52
|
const errorLog = errLogBuffer.getResult();
|
|
53
|
+
|
|
53
54
|
const error = new Error(`${cmd} ${args.join(' ')} failed with code ${code}, ${errorLog}`)
|
|
54
55
|
// add code ENOENT on Win if command not found
|
|
55
56
|
if (IS_WIN && errorLog.includes(cmd) && /not recognized/i.exec(errorLog)) {
|
|
56
57
|
error.code = 'ENOENT';
|
|
57
58
|
error.path = cmd;
|
|
58
59
|
}
|
|
60
|
+
|
|
61
|
+
error.errLog = errorLog;
|
|
62
|
+
error.stdLog = stdLogBuffer.getResult();
|
|
63
|
+
|
|
59
64
|
reject(error);
|
|
60
65
|
}
|
|
61
66
|
});
|
package/lib/lint/Linter.js
CHANGED
|
@@ -21,6 +21,7 @@ class Linter {
|
|
|
21
21
|
this.eslintCmdOpts = {};
|
|
22
22
|
this.eslintCmdOptsIndex = 0;
|
|
23
23
|
this.eslintCmdFileExpr = "";
|
|
24
|
+
this.formatter = false;
|
|
24
25
|
this.isFile = false;
|
|
25
26
|
this.help = "";
|
|
26
27
|
this.debug = "";
|
|
@@ -44,7 +45,11 @@ class Linter {
|
|
|
44
45
|
* @returns object continaing help, options, flags and shortcuts
|
|
45
46
|
*/
|
|
46
47
|
init(help = "", options = [], flags = [], shortcuts = []) {
|
|
47
|
-
|
|
48
|
+
const eslintInfo = checks.resolveEslint(this.cdsdkPath, this.globalPath);
|
|
49
|
+
if (eslintInfo) {
|
|
50
|
+
this.eslintCmd = eslintInfo.cmd;
|
|
51
|
+
}
|
|
52
|
+
this.addFormatter = eslintInfo.addFormatter;
|
|
48
53
|
if (this.eslintCmd) {
|
|
49
54
|
help = generators.genEslintHelp(this.eslintCmd);
|
|
50
55
|
flags = generators.genEslintFlags(help);
|
|
@@ -75,7 +80,7 @@ class Linter {
|
|
|
75
80
|
this._printHelp();
|
|
76
81
|
} else {
|
|
77
82
|
// Determine if case "local" or "global" and resolve plugin accordingly
|
|
78
|
-
this._getConfigFileAndSetProjectPath(args);
|
|
83
|
+
await this._getConfigFileAndSetProjectPath(args);
|
|
79
84
|
|
|
80
85
|
if (this.lintType === "local") {
|
|
81
86
|
await this._addRulePaths();
|
|
@@ -88,12 +93,12 @@ class Linter {
|
|
|
88
93
|
"rules"
|
|
89
94
|
);
|
|
90
95
|
if (overwriteRules) {
|
|
91
|
-
this._overwriteRuleSeverities();
|
|
96
|
+
await this._overwriteRuleSeverities();
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
// Limit to CDS file extensions
|
|
96
|
-
this._addExtensions();
|
|
101
|
+
this._addExtensions(this.addFormatter);
|
|
97
102
|
// Run ESLint with collected options
|
|
98
103
|
try {
|
|
99
104
|
await this._runEslint();
|
|
@@ -136,23 +141,25 @@ class Linter {
|
|
|
136
141
|
return;
|
|
137
142
|
}
|
|
138
143
|
|
|
139
|
-
_addExtensions() {
|
|
144
|
+
_addExtensions(addFormatter) {
|
|
140
145
|
// Add CDS file extensions to lint
|
|
141
146
|
this.eslintCmdOpts = io.mergeWithUserOpts(
|
|
142
147
|
this.eslintCmdOpts,
|
|
143
148
|
"ext",
|
|
144
149
|
".cds,.csn"
|
|
145
150
|
);
|
|
146
|
-
// Add custom CDS formatter
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.eslintCmdOpts
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
// Add custom CDS formatter (for ESLint v<8)
|
|
152
|
+
if (addFormatter) {
|
|
153
|
+
const formatterPath = this.pluginPath.replace(
|
|
154
|
+
"index.js",
|
|
155
|
+
"../api/formatter.js"
|
|
156
|
+
);
|
|
157
|
+
this.eslintCmdOpts = io.mergeWithUserOpts(
|
|
158
|
+
this.eslintCmdOpts,
|
|
159
|
+
"format",
|
|
160
|
+
path.relative(".", formatterPath)
|
|
161
|
+
);
|
|
162
|
+
}
|
|
156
163
|
// Enable colored output
|
|
157
164
|
if (process.stdout.isTTY) {
|
|
158
165
|
this.eslintCmdOpts = io.mergeWithUserOpts(this.eslintCmdOpts, "color");
|
|
@@ -217,10 +224,14 @@ class Linter {
|
|
|
217
224
|
eslintCmdOpts.unshift(eslintCmdSplit[1]);
|
|
218
225
|
eslintCmdOpts.push(input);
|
|
219
226
|
// Run ESLint with given cmd line options
|
|
227
|
+
// - Show 'eslint' instead of 'node ...eslint.js' cmd
|
|
228
|
+
// - Remove debug flag for printed cmd
|
|
220
229
|
if (this.eslintCmdOpts.debug) {
|
|
230
|
+
eslintCmdOpts.splice(eslintCmdOpts.indexOf('--debug'), 1);
|
|
221
231
|
console.log(
|
|
222
|
-
`Linting:\n ${term.info(
|
|
232
|
+
`Linting:\n ${term.info(`eslint ${eslintCmdOpts.slice(1).join(' ')}`)}\n`
|
|
223
233
|
);
|
|
234
|
+
eslintCmdOpts.push('--debug');
|
|
224
235
|
}
|
|
225
236
|
if (!dryRun) {
|
|
226
237
|
return commandUtil.spawnCommand(this.eslintCmd, eslintCmdOpts, {
|
|
@@ -245,7 +256,7 @@ class Linter {
|
|
|
245
256
|
return;
|
|
246
257
|
}
|
|
247
258
|
|
|
248
|
-
_getConfigFileAndSetProjectPath(args) {
|
|
259
|
+
async _getConfigFileAndSetProjectPath(args) {
|
|
249
260
|
let input;
|
|
250
261
|
// Only resolve the first input argument
|
|
251
262
|
//
|
|
@@ -269,7 +280,7 @@ class Linter {
|
|
|
269
280
|
this.configPath = this.configGlobalPath;
|
|
270
281
|
this.lintType === "global";
|
|
271
282
|
} else {
|
|
272
|
-
this.configContents = io.readEslintConfig(this.configPath);
|
|
283
|
+
this.configContents = await io.readEslintConfig(this.configPath);
|
|
273
284
|
if (this.configContents) {
|
|
274
285
|
if ("extends" in this.configContents) {
|
|
275
286
|
this.extendsPlugin = checks.hasEslintConfigContent(
|
|
@@ -295,8 +306,8 @@ class Linter {
|
|
|
295
306
|
return;
|
|
296
307
|
}
|
|
297
308
|
|
|
298
|
-
_overwriteRuleSeverities() {
|
|
299
|
-
let configContents = io.readEslintConfig(this.configPath) || {};
|
|
309
|
+
async _overwriteRuleSeverities() {
|
|
310
|
+
let configContents = (await io.readEslintConfig(this.configPath)) || {};
|
|
300
311
|
let rules = configContents.rules;
|
|
301
312
|
// Allow recommended plugin rules in cds-dk to be overwritten
|
|
302
313
|
// by user by adding rule to cmd line (because of precedence)
|
package/lib/lint/checks.js
CHANGED
|
@@ -21,6 +21,7 @@ module.exports = {
|
|
|
21
21
|
let cmd;
|
|
22
22
|
let version;
|
|
23
23
|
let errMessage;
|
|
24
|
+
let addFormatter = false;
|
|
24
25
|
try {
|
|
25
26
|
const eslintPath = require.resolve("eslint/package.json", {
|
|
26
27
|
paths: [inputPath, globalPath],
|
|
@@ -28,6 +29,9 @@ module.exports = {
|
|
|
28
29
|
const packageJson = require(eslintPath);
|
|
29
30
|
if (packageJson.version > "7") {
|
|
30
31
|
version = packageJson.version;
|
|
32
|
+
if (version < "8") {
|
|
33
|
+
addFormatter = true;
|
|
34
|
+
}
|
|
31
35
|
} else {
|
|
32
36
|
errMessage =
|
|
33
37
|
`ESLint v>=6.0.0 required!\n\n` +
|
|
@@ -51,7 +55,7 @@ module.exports = {
|
|
|
51
55
|
)}\n`;
|
|
52
56
|
}
|
|
53
57
|
if (cmd && version) {
|
|
54
|
-
return cmd;
|
|
58
|
+
return { cmd, addFormatter };
|
|
55
59
|
}
|
|
56
60
|
if (logger) {
|
|
57
61
|
logger.error(errMessage);
|
package/lib/lint/io.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const os = require("os");
|
|
2
|
-
const
|
|
2
|
+
const fsp = require("fs").promises;
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const yaml = require("@sap/cds-foss")("yaml");
|
|
5
|
+
const term = require("../util/term");
|
|
5
6
|
const FsUtil = require("../init/util/fsUtil");
|
|
6
7
|
const fsUtil = new FsUtil();
|
|
7
8
|
|
|
@@ -13,23 +14,28 @@ module.exports = {
|
|
|
13
14
|
* @param {*} configPath config file path to read from
|
|
14
15
|
* @returns config file contents
|
|
15
16
|
*/
|
|
16
|
-
readEslintConfig(configPath) {
|
|
17
|
+
async readEslintConfig(configPath) {
|
|
17
18
|
let config;
|
|
18
19
|
let configFile = path.basename(configPath);
|
|
20
|
+
let configString = await fsp.readFile(configPath, "utf8");
|
|
19
21
|
switch (configFile) {
|
|
20
22
|
case ".eslintrc.js":
|
|
21
23
|
case ".eslintrc.cjs":
|
|
22
|
-
|
|
24
|
+
try {
|
|
25
|
+
config = JSON.parse(configString.replace(/^module\.exports =/, ""));
|
|
26
|
+
} catch (err) {
|
|
27
|
+
config = {};
|
|
28
|
+
}
|
|
23
29
|
break;
|
|
24
30
|
case ".eslintrc.yaml":
|
|
25
31
|
case ".eslintrc.yml":
|
|
26
|
-
config = yaml.parse(
|
|
32
|
+
config = yaml.parse(await fsp.readFile(configPath, "utf8"));
|
|
27
33
|
break;
|
|
28
34
|
case ".eslintrc.json":
|
|
29
35
|
case ".eslintrc":
|
|
30
36
|
case "package.json":
|
|
31
37
|
try {
|
|
32
|
-
config = JSON.parse(
|
|
38
|
+
config = JSON.parse(await fsp.readFile(configPath, "utf8"));
|
|
33
39
|
if (configFile === "package.json" && "eslintConfig" in config) {
|
|
34
40
|
config = config["eslintConfig"];
|
|
35
41
|
}
|
|
@@ -52,8 +58,11 @@ module.exports = {
|
|
|
52
58
|
* @param {*} configPath ESLint config file
|
|
53
59
|
* @returns {void}
|
|
54
60
|
*/
|
|
55
|
-
async sanitizeEslintConfig(configPath, customRuleExample=false) {
|
|
56
|
-
let configContents =
|
|
61
|
+
async sanitizeEslintConfig(configPath, customRuleExample = false, logger = console) {
|
|
62
|
+
let configContents = {};
|
|
63
|
+
if (await fsUtil.pathExists(configPath)) {
|
|
64
|
+
configContents = (await this.readEslintConfig(configPath)) || {};
|
|
65
|
+
}
|
|
57
66
|
const configType = "recommended";
|
|
58
67
|
const extendsValue = `plugin:@sap/cds/${configType}`;
|
|
59
68
|
if ("extends" in configContents) {
|
|
@@ -79,7 +88,7 @@ module.exports = {
|
|
|
79
88
|
configContents["rules"] = { [ruleName]: ruleValue };
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
|
-
await this.writeEslintConfig(configContents,
|
|
91
|
+
await this.writeEslintConfig(configPath, configContents, logger);
|
|
83
92
|
return;
|
|
84
93
|
},
|
|
85
94
|
|
|
@@ -89,16 +98,37 @@ module.exports = {
|
|
|
89
98
|
* @param {*} configPath config file path to write to
|
|
90
99
|
* @returns {void}
|
|
91
100
|
*/
|
|
92
|
-
async writeEslintConfig(configContents,
|
|
101
|
+
async writeEslintConfig(configPath, configContents, logger=console) {
|
|
102
|
+
const configType = "recommended";
|
|
103
|
+
const extendsValue = `plugin:@sap/cds/${configType}`;
|
|
93
104
|
let contents = {};
|
|
94
105
|
let configFile = path.basename(configPath);
|
|
106
|
+
let configToAdd = {};
|
|
95
107
|
switch (configFile) {
|
|
96
108
|
case ".eslintrc.js":
|
|
97
109
|
case ".eslintrc.cjs":
|
|
98
|
-
|
|
99
|
-
configPath
|
|
100
|
-
|
|
101
|
-
|
|
110
|
+
try {
|
|
111
|
+
configContents = await this.readEslintConfig(configPath);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
configContents = {};
|
|
114
|
+
}
|
|
115
|
+
if (configContents && configContents["extends"]) {
|
|
116
|
+
if (
|
|
117
|
+
!configContents["extends"] === extendsValue ||
|
|
118
|
+
!configContents["extends"].includes(extendsValue)
|
|
119
|
+
) {
|
|
120
|
+
configToAdd["extends"] = extendsValue;
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
configToAdd["extends"] = extendsValue;
|
|
124
|
+
}
|
|
125
|
+
if (configToAdd["extends"]) {
|
|
126
|
+
logger.log(
|
|
127
|
+
`${term.warn(
|
|
128
|
+
`\n\nPlease add the following to your "${configFile}":\n\nmodule.exports = ${JSON.stringify(configToAdd, null, 2)}`
|
|
129
|
+
)}\n`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
102
132
|
break;
|
|
103
133
|
case ".eslintrc.yaml":
|
|
104
134
|
case ".eslintrc.yml":
|
|
@@ -108,25 +138,19 @@ module.exports = {
|
|
|
108
138
|
case ".eslintrc":
|
|
109
139
|
case "package.json":
|
|
110
140
|
if (configFile === "package.json") {
|
|
111
|
-
if (
|
|
112
|
-
contents = JSON.parse(
|
|
141
|
+
if (await fsp.access(configPath)) {
|
|
142
|
+
contents = JSON.parse(await fsp.readFile(configPath, "utf8"));
|
|
113
143
|
} else {
|
|
114
144
|
contents = {};
|
|
115
145
|
}
|
|
116
146
|
if (!("eslintConfig" in configContents)) {
|
|
117
147
|
contents["eslintConfig"] = configContents;
|
|
118
148
|
} else {
|
|
119
|
-
contents["eslintConfig"] = [
|
|
120
|
-
...configContents,
|
|
121
|
-
...contents["eslintConfig"],
|
|
122
|
-
];
|
|
149
|
+
contents["eslintConfig"] = [...configContents, ...contents["eslintConfig"]];
|
|
123
150
|
}
|
|
124
151
|
configContents = contents;
|
|
125
152
|
}
|
|
126
|
-
await fsUtil.writeFile(
|
|
127
|
-
configPath,
|
|
128
|
-
`${JSON.stringify(configContents, null, 2)}`
|
|
129
|
-
);
|
|
153
|
+
await fsUtil.writeFile(configPath, `${JSON.stringify(configContents, null, 2)}`);
|
|
130
154
|
break;
|
|
131
155
|
default:
|
|
132
156
|
break;
|
|
@@ -141,8 +165,12 @@ module.exports = {
|
|
|
141
165
|
*/
|
|
142
166
|
async readVscodeSettings(settingsPath) {
|
|
143
167
|
let settings;
|
|
144
|
-
if (
|
|
145
|
-
|
|
168
|
+
if (fsUtil.pathExists(settingsPath)) {
|
|
169
|
+
try {
|
|
170
|
+
settings = await fsUtil.readJSONC(settingsPath);
|
|
171
|
+
} catch (err) {
|
|
172
|
+
settings = {};
|
|
173
|
+
}
|
|
146
174
|
}
|
|
147
175
|
return settings;
|
|
148
176
|
},
|
|
@@ -186,10 +214,7 @@ module.exports = {
|
|
|
186
214
|
}
|
|
187
215
|
|
|
188
216
|
if (settings["eslint.validate"]) {
|
|
189
|
-
settings["eslint.validate"] = this.mergeArrays(
|
|
190
|
-
settings["eslint.validate"],
|
|
191
|
-
lintFileTypes
|
|
192
|
-
);
|
|
217
|
+
settings["eslint.validate"] = this.mergeArrays(settings["eslint.validate"], lintFileTypes);
|
|
193
218
|
} else {
|
|
194
219
|
settings["eslint.validate"] = lintFileTypes;
|
|
195
220
|
}
|
|
@@ -208,7 +233,7 @@ module.exports = {
|
|
|
208
233
|
}
|
|
209
234
|
}
|
|
210
235
|
|
|
211
|
-
await this.writeVscodeSettings(
|
|
236
|
+
await this.writeVscodeSettings(settingsPath, settings);
|
|
212
237
|
},
|
|
213
238
|
|
|
214
239
|
/**
|
|
@@ -217,7 +242,7 @@ module.exports = {
|
|
|
217
242
|
* @param {*} settingsPath settings file path to write to
|
|
218
243
|
* @returns {void}
|
|
219
244
|
*/
|
|
220
|
-
async writeVscodeSettings(
|
|
245
|
+
async writeVscodeSettings(settingsPath, settings) {
|
|
221
246
|
if (!settings) {
|
|
222
247
|
await fsUtil.mkdirp(path.dirname(settingsPath));
|
|
223
248
|
}
|
|
@@ -236,10 +261,9 @@ module.exports = {
|
|
|
236
261
|
if (propsToAdd) {
|
|
237
262
|
if (Object.keys(userOpts).includes(propKey)) {
|
|
238
263
|
if (!["config", "format"].includes(propKey)) {
|
|
239
|
-
propsToAdd = this.mergeArrays(
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
).join(",");
|
|
264
|
+
propsToAdd = this.mergeArrays(userOpts[propKey].split(","), propsToAdd.split(",")).join(
|
|
265
|
+
","
|
|
266
|
+
);
|
|
243
267
|
}
|
|
244
268
|
}
|
|
245
269
|
userOpts[propKey] = propsToAdd;
|
package/lib/util/term.js
CHANGED
|
@@ -8,6 +8,7 @@ const t = module.exports.codes = {
|
|
|
8
8
|
link: '\x1b[4m', // underline
|
|
9
9
|
red: '\x1b[91m', // Bright Foreground Red
|
|
10
10
|
green: '\x1b[32m', // Foreground Green
|
|
11
|
+
blue: '\x1b[34m', // Foreground Blue
|
|
11
12
|
orange: '\x1b[38;2;255;140;0m' // darker orange, works with bright and dark background
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -24,6 +25,7 @@ module.exports.warn = o => as(t.orange, o)
|
|
|
24
25
|
module.exports.info = o => as(t.green, o)
|
|
25
26
|
module.exports.link = o => as(t.link, o)
|
|
26
27
|
module.exports.bold = o => as(t.bold, o)
|
|
28
|
+
module.exports.highlight = o => as(t.blue,as(t.bold, o))
|
|
27
29
|
|
|
28
30
|
const format = module.exports.format = (o, severity='Error', asInternalError=false, withStack=false) => {
|
|
29
31
|
switch (severity) {
|