@sap/cds-dk 4.6.0 → 4.6.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 +21 -0
- package/bin/compile/index.js +2 -1
- package/bin/repl.js +6 -2
- package/bin/watch.js +14 -5
- package/lib/client/settings_manager.js +5 -4
- package/lib/init/constants.js +1 -1
- package/lib/init/template/lint/index.js +11 -17
- package/lib/init/template/nodejs/files/.gitignore.hbs +0 -2
- package/lib/lint/Linter.js +8 -22
- package/lib/lint/checks.js +1 -5
- package/lib/lint/generators.js +5 -4
- package/lib/lint/io.js +4 -2
- package/npm-shrinkwrap.json +404 -1024
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,27 @@ 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
|
+
## Version 4.6.2 - 2021-11-09
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `cds add lint` now correctly detects missing local `eslint`
|
|
14
|
+
- `cds add lint` no longer removes parts of `package.json`
|
|
15
|
+
- `cds add lint` no longer creates duplicate configuration entries
|
|
16
|
+
|
|
17
|
+
## Version 4.6.1 - 2021-11-08
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `cds init` uses latest `Maven Java archetype` version `1.20.0` for creating Java projects.
|
|
22
|
+
- `cds watch` now resolves local node modules like `hdb` even though `@sap/cds` is not installed locally. This is useful during development where `@sap/cds` shall only be installed in a 'central' location, while extra modules shall still be found in the app's dir.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- `cds repl` now finds modules like `hdb` that are installed locally in the app folder
|
|
27
|
+
- `cds repl` now enables the `await` statement also on Windows
|
|
28
|
+
- `cds lint` now limits all file extensions to those allowed by the @sap/eslint-plugin-cds ESLint configuration
|
|
29
|
+
|
|
9
30
|
## Version 4.6.0 - 2021-11-02
|
|
10
31
|
### Added
|
|
11
32
|
|
package/bin/compile/index.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = Object.assign ( compile, {
|
|
|
38
38
|
- json, yml
|
|
39
39
|
- edm, edmx, edmx-v2, edmx-v4, edmx-w4, edmx-x4
|
|
40
40
|
- sql, hdbcds, hdbtable
|
|
41
|
+
- cdl [beta]
|
|
41
42
|
- xsuaa
|
|
42
43
|
- openapi
|
|
43
44
|
|
|
@@ -261,7 +262,7 @@ function compile (models, options={}) {
|
|
|
261
262
|
|
|
262
263
|
function suffix4 (x) { return x && ({
|
|
263
264
|
edmx: '.xml',
|
|
264
|
-
"edmx-v2": '.xml',
|
|
265
|
+
"edmx-v2": '.xml',
|
|
265
266
|
"edmx-v4": '.xml',
|
|
266
267
|
openapi: '.openapi3.json', //'.yml',
|
|
267
268
|
cdl: '.cds',
|
package/bin/repl.js
CHANGED
|
@@ -14,8 +14,12 @@ module.exports = Object.assign (repl, { options: [], help: `
|
|
|
14
14
|
|
|
15
15
|
function repl (_, options={}) {
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// enable `await` statement for Node.js < 16
|
|
18
|
+
if (!process.env['CDS_REPL_SPAWNED'] && process.version.split('.')[0].slice(1) < '16') {
|
|
19
|
+
process.env['CDS_REPL_SPAWNED'] = true
|
|
20
|
+
return require('child_process').spawn('node',['--experimental-repl-await',
|
|
21
|
+
...process.argv.slice(1) ], {stdio:'inherit'}
|
|
22
|
+
)
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
const cds = require('@sap/cds/lib')
|
package/bin/watch.js
CHANGED
|
@@ -43,7 +43,7 @@ module.exports = Object.assign ( watch, {
|
|
|
43
43
|
`})
|
|
44
44
|
|
|
45
45
|
const DEBUG = /\bwatch\b/.test(process.env.DEBUG) && console.debug
|
|
46
|
-
const
|
|
46
|
+
const {delimiter,dirname,relative,resolve,sep} = require ('path')
|
|
47
47
|
const fs = require ('fs')
|
|
48
48
|
const t = module.exports.codes = {
|
|
49
49
|
reset: '\x1b[0m', // Default
|
|
@@ -71,8 +71,11 @@ async function watch ([cwd], {
|
|
|
71
71
|
_args: JSON.stringify(args),
|
|
72
72
|
_options: JSON.stringify(options)
|
|
73
73
|
})
|
|
74
|
+
|
|
75
|
+
// allow running w/o or partial local node_modules, also add cds-dk for its sqlite
|
|
76
|
+
env.NODE_PATH = [...paths(cwd||process.cwd()), ...paths(__dirname)].join(delimiter)
|
|
77
|
+
|
|
74
78
|
if (typeof ext !== 'string') ext = extDefaults
|
|
75
|
-
env.NODE_PATH = path.resolve (__dirname,'../node_modules') // allow global sqlite to be resolved
|
|
76
79
|
|
|
77
80
|
let liveReload //= ...
|
|
78
81
|
let firstTime = true
|
|
@@ -83,7 +86,7 @@ async function watch ([cwd], {
|
|
|
83
86
|
env.CDS_LIVERELOAD_URL = await liveReload.start (options['livereload'])
|
|
84
87
|
.catch(err => { console.log(`Error starting live reload: ${err.message}`); liveReload = null })
|
|
85
88
|
} else {
|
|
86
|
-
ignore = RegExp(`app${
|
|
89
|
+
ignore = RegExp(`app${sep}.*\\.(js|ts)|`+ignore.source) // exclude more frontend stuff
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
const log = (first,...more) => console.log (t.yellow + (first||''), ...more, t.reset)
|
|
@@ -91,8 +94,8 @@ async function watch ([cwd], {
|
|
|
91
94
|
const ocwd = process.env._original_cwd = process.cwd()
|
|
92
95
|
if (fs.existsSync(cwd)) log (`cd ${cwd}`)
|
|
93
96
|
else try {
|
|
94
|
-
const resolved =
|
|
95
|
-
log (`cd ${
|
|
97
|
+
const resolved = dirname (require.resolve(cwd+'/package.json', {paths:[ocwd]}))
|
|
98
|
+
log (`cd ${relative(ocwd,cwd = resolved)}`)
|
|
96
99
|
} catch(_){ throw new Error(`No such folder or package: '${ocwd}' -> '${cwd}'`) }
|
|
97
100
|
}
|
|
98
101
|
log ()
|
|
@@ -172,6 +175,12 @@ function removeArgsIn (toRemove) {
|
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
|
|
178
|
+
// builds paths from dir + its parent node_modules
|
|
179
|
+
function paths (dir) {
|
|
180
|
+
const parts = resolve(dir).split(sep), n = parts.length, nm = sep+'node_modules'
|
|
181
|
+
return parts.map ((_,i,a)=> a.slice(0,n-i).join(sep)+nm).filter(p => fs.existsSync(p))
|
|
182
|
+
}
|
|
183
|
+
|
|
175
184
|
//
|
|
176
185
|
// Child process impl launched by watch
|
|
177
186
|
//
|
|
@@ -138,7 +138,7 @@ class SettingsManager {
|
|
|
138
138
|
if (params.get('clearOtherTokenStorage')) {
|
|
139
139
|
// Delete token from the other storage.
|
|
140
140
|
params.delete('clearOtherTokenStorage');
|
|
141
|
-
await this.deleteToken(params,
|
|
141
|
+
await this.deleteToken(params, true);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
if (params.get('tokenStorage') === 'plain') {
|
|
@@ -303,15 +303,16 @@ class SettingsManager {
|
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
static async deleteToken(params,
|
|
306
|
+
static async deleteToken(params, fromOtherStorage = false) {
|
|
307
307
|
const allParams = params.clone();
|
|
308
308
|
await this.loadAndMergeSettings(allParams, true);
|
|
309
309
|
|
|
310
310
|
const target = `URL ${allParams.get('appUrl')}, subdomain '${allParams.get('subdomain')}'`;
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
let fromStorage = fromOtherStorage && other(params.get('tokenStorage'))
|
|
313
312
|
const deleteBoth = !fromStorage && allParams.get('tokenStorage') && allParams.get('clearOtherTokenStorage');
|
|
314
313
|
|
|
314
|
+
Logger.debug(`Deleting authentication data${fromOtherStorage ? ' from other storage' : ''} for ${target}`);
|
|
315
|
+
|
|
315
316
|
fromStorage = fromStorage || allParams.get('tokenStorage');
|
|
316
317
|
if (!fromStorage) {
|
|
317
318
|
Logger.log(`No authentication data found for ${target}`);
|
package/lib/init/constants.js
CHANGED
|
@@ -42,12 +42,9 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
async run() {
|
|
45
|
-
const cdsdkPath = path.join(__dirname, "../../../..");
|
|
46
|
-
const globalPath = path.join(cdsdkPath, "../..");
|
|
47
|
-
|
|
48
45
|
// Require ESLint v>=7.0.0
|
|
49
46
|
if (!this.isTest) {
|
|
50
|
-
this._checkEslint(
|
|
47
|
+
this._checkEslint();
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
// To enable custom lint rules ('lint' or 'lint:dev')
|
|
@@ -69,15 +66,16 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
69
66
|
// Generate custom lint rules docs
|
|
70
67
|
await generators.genDocs(this.projectPath);
|
|
71
68
|
}
|
|
69
|
+
|
|
70
|
+
// Generate VS Code extension settings
|
|
71
|
+
await io.sanitizeVscodeSettings(
|
|
72
|
+
this.projectPath,
|
|
73
|
+
path.join(this.projectPath, ".vscode/settings.json"),
|
|
74
|
+
this.lintType,
|
|
75
|
+
this.customRuleExample
|
|
76
|
+
);
|
|
72
77
|
}
|
|
73
78
|
|
|
74
|
-
// Generate VS Code extension settings
|
|
75
|
-
await io.sanitizeVscodeSettings(
|
|
76
|
-
this.projectPath,
|
|
77
|
-
path.join(this.projectPath, ".vscode/settings.json"),
|
|
78
|
-
this.lintType,
|
|
79
|
-
this.customRuleExample
|
|
80
|
-
);
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
async finalize() {
|
|
@@ -111,12 +109,8 @@ module.exports = class LintTemplate extends TemplateBase {
|
|
|
111
109
|
|
|
112
110
|
}
|
|
113
111
|
|
|
114
|
-
_checkEslint(
|
|
115
|
-
const
|
|
116
|
-
let eslintCmd;
|
|
117
|
-
if (eslintInfo) {
|
|
118
|
-
eslintCmd = eslintInfo.cmd;
|
|
119
|
-
}
|
|
112
|
+
_checkEslint() {
|
|
113
|
+
const eslintCmd = checks.resolveEslint(this.projectPath, '');
|
|
120
114
|
if (!eslintCmd) {
|
|
121
115
|
this.missingNpmDependencies["names"].push("eslint");
|
|
122
116
|
this.missingNpmDependencies["msgs"].push("ESLint v>=7.0.0");
|
package/lib/lint/Linter.js
CHANGED
|
@@ -14,6 +14,8 @@ const {
|
|
|
14
14
|
} = require("@sap/eslint-plugin-cds/lib/api");
|
|
15
15
|
|
|
16
16
|
const IS_WIN = os.platform() === "win32";
|
|
17
|
+
const ALLOWED_FILE_EXTENSIONS = getFileExtensions();
|
|
18
|
+
|
|
17
19
|
class Linter {
|
|
18
20
|
constructor() {
|
|
19
21
|
this.eslintCmd = "";
|
|
@@ -45,11 +47,7 @@ class Linter {
|
|
|
45
47
|
* @returns object continaing help, options, flags and shortcuts
|
|
46
48
|
*/
|
|
47
49
|
init(help = "", options = [], flags = [], shortcuts = []) {
|
|
48
|
-
|
|
49
|
-
if (eslintInfo) {
|
|
50
|
-
this.eslintCmd = eslintInfo.cmd;
|
|
51
|
-
}
|
|
52
|
-
this.addFormatter = eslintInfo.addFormatter;
|
|
50
|
+
this.eslintCmd = checks.resolveEslint(this.cdsdkPath, this.globalPath);
|
|
53
51
|
if (this.eslintCmd) {
|
|
54
52
|
help = generators.genEslintHelp(this.eslintCmd);
|
|
55
53
|
flags = generators.genEslintFlags(help);
|
|
@@ -98,7 +96,7 @@ class Linter {
|
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
// Limit to CDS file extensions
|
|
101
|
-
this._addExtensions(
|
|
99
|
+
this._addExtensions();
|
|
102
100
|
// Run ESLint with collected options
|
|
103
101
|
try {
|
|
104
102
|
await this._runEslint();
|
|
@@ -141,25 +139,14 @@ class Linter {
|
|
|
141
139
|
return;
|
|
142
140
|
}
|
|
143
141
|
|
|
144
|
-
_addExtensions(
|
|
142
|
+
_addExtensions() {
|
|
145
143
|
// Add CDS file extensions to lint
|
|
144
|
+
const extensions = ALLOWED_FILE_EXTENSIONS.map((ext) => ext.replace('*.', '.'));
|
|
146
145
|
this.eslintCmdOpts = io.mergeWithUserOpts(
|
|
147
146
|
this.eslintCmdOpts,
|
|
148
147
|
"ext",
|
|
149
|
-
|
|
148
|
+
extensions.join(',')
|
|
150
149
|
);
|
|
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
|
-
}
|
|
163
150
|
// Enable colored output
|
|
164
151
|
if (process.stdout.isTTY) {
|
|
165
152
|
this.eslintCmdOpts = io.mergeWithUserOpts(this.eslintCmdOpts, "color");
|
|
@@ -193,7 +180,6 @@ class Linter {
|
|
|
193
180
|
}
|
|
194
181
|
}
|
|
195
182
|
// Only lint file extensions prescribed by plugin
|
|
196
|
-
const fileExtensions = getFileExtensions();
|
|
197
183
|
eslintCmdOpts.push("--ignore-pattern");
|
|
198
184
|
let ignorePattern = "*.*";
|
|
199
185
|
if (IS_WIN) {
|
|
@@ -202,7 +188,7 @@ class Linter {
|
|
|
202
188
|
ignorePattern = `'${ignorePattern}'`;
|
|
203
189
|
}
|
|
204
190
|
eslintCmdOpts.push(ignorePattern);
|
|
205
|
-
|
|
191
|
+
ALLOWED_FILE_EXTENSIONS.forEach((ext) => {
|
|
206
192
|
eslintCmdOpts.push("--ignore-pattern");
|
|
207
193
|
ignorePattern = `!${ext}`;
|
|
208
194
|
if (IS_WIN) {
|
package/lib/lint/checks.js
CHANGED
|
@@ -21,7 +21,6 @@ module.exports = {
|
|
|
21
21
|
let cmd;
|
|
22
22
|
let version;
|
|
23
23
|
let errMessage;
|
|
24
|
-
let addFormatter = false;
|
|
25
24
|
try {
|
|
26
25
|
const eslintPath = require.resolve("eslint/package.json", {
|
|
27
26
|
paths: [inputPath, globalPath],
|
|
@@ -29,9 +28,6 @@ module.exports = {
|
|
|
29
28
|
const packageJson = require(eslintPath);
|
|
30
29
|
if (packageJson.version > "7") {
|
|
31
30
|
version = packageJson.version;
|
|
32
|
-
if (version < "8") {
|
|
33
|
-
addFormatter = true;
|
|
34
|
-
}
|
|
35
31
|
} else {
|
|
36
32
|
errMessage =
|
|
37
33
|
`ESLint v>=6.0.0 required!\n\n` +
|
|
@@ -55,7 +51,7 @@ module.exports = {
|
|
|
55
51
|
)}\n`;
|
|
56
52
|
}
|
|
57
53
|
if (cmd && version) {
|
|
58
|
-
return
|
|
54
|
+
return cmd;
|
|
59
55
|
}
|
|
60
56
|
if (logger) {
|
|
61
57
|
logger.error(errMessage);
|
package/lib/lint/generators.js
CHANGED
|
@@ -3,6 +3,7 @@ const os = require("os");
|
|
|
3
3
|
const cp = require("child_process");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { mkdirp } = require("@sap/cds/lib/utils");
|
|
6
|
+
const term = require("../util/term");
|
|
6
7
|
|
|
7
8
|
const IS_WIN = os.platform() === "win32";
|
|
8
9
|
|
|
@@ -35,12 +36,12 @@ module.exports = {
|
|
|
35
36
|
let cdslintCmd = eslintOpts[0].replace("eslint", "*cds lint*");
|
|
36
37
|
eslintOpts[0] = `
|
|
37
38
|
# SYNOPSIS
|
|
38
|
-
|
|
39
|
+
|
|
39
40
|
${cdslintCmd} [beta]
|
|
40
|
-
|
|
41
|
+
|
|
41
42
|
Runs environment checks and/or checks the specified models
|
|
42
43
|
based on the ESLint framework
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
# OPTIONS`;
|
|
45
46
|
return `${eslintOpts.join("\n ")}\n`;
|
|
46
47
|
},
|
|
@@ -97,7 +98,7 @@ module.exports = {
|
|
|
97
98
|
},
|
|
98
99
|
|
|
99
100
|
/**
|
|
100
|
-
* Generates custom rules documentation for user
|
|
101
|
+
* Generates custom rules documentation for user
|
|
101
102
|
* according to contents of rules files
|
|
102
103
|
* @param {*} projectPath
|
|
103
104
|
*/
|
package/lib/lint/io.js
CHANGED
|
@@ -71,7 +71,9 @@ module.exports = {
|
|
|
71
71
|
configContents["extends"].push(extendsValue);
|
|
72
72
|
}
|
|
73
73
|
} else {
|
|
74
|
-
configContents["extends"]
|
|
74
|
+
if (configContents["extends"] !== extendsValue) {
|
|
75
|
+
configContents["extends"] = [configContents["extends"], extendsValue];
|
|
76
|
+
}
|
|
75
77
|
}
|
|
76
78
|
} else {
|
|
77
79
|
configContents["extends"] = extendsValue;
|
|
@@ -138,7 +140,7 @@ module.exports = {
|
|
|
138
140
|
case ".eslintrc":
|
|
139
141
|
case "package.json":
|
|
140
142
|
if (configFile === "package.json") {
|
|
141
|
-
if (await
|
|
143
|
+
if (await fsUtil.pathExists(configPath)) {
|
|
142
144
|
contents = JSON.parse(await fsp.readFile(configPath, "utf8"));
|
|
143
145
|
} else {
|
|
144
146
|
contents = {};
|