@sap/cds-dk 4.5.4 → 4.6.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.
- package/CHANGELOG.md +61 -0
- package/bin/bind.js +124 -8
- package/bin/cds-ts.js +1 -1
- package/bin/cds.js +1 -0
- package/bin/compile/index.js +2 -1
- package/bin/env.js +50 -9
- package/bin/help.js +1 -0
- package/bin/import.js +34 -14
- package/bin/repl.js +6 -2
- package/bin/watch.js +40 -10
- package/lib/bind/bindingResolver.js +138 -0
- package/lib/bind/cfKeyProvider.js +353 -0
- package/lib/bind/userCdsrcJsonStorageProvider.js +144 -0
- package/lib/client/activate.js +3 -9
- package/lib/client/auth_manager.js +4 -4
- package/lib/client/extend.js +4 -9
- package/lib/client/settings_manager.js +6 -5
- package/lib/import/common.js +10 -1
- package/lib/import/importapi.js +4 -3
- package/lib/import/index.js +37 -7
- 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 +138 -16
- package/lib/import/v4parser.js +212 -172
- package/lib/init/constants.js +1 -1
- package/lib/init/template/data/index.js +11 -1
- package/lib/init/template/hana/index.js +16 -20
- 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 +19 -17
- package/lib/init/template/mta/files/mta.yaml.hbs +0 -7
- package/lib/init/template/mta/projectReader.js +1 -3
- 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 +1 -0
- package/lib/init/template/samples/index.js +1 -1
- package/lib/init/template/templateBase.js +10 -41
- package/lib/init/util/commandUtil.js +5 -0
- package/lib/lint/Linter.js +19 -28
- package/lib/lint/generators.js +5 -4
- package/lib/lint/io.js +76 -51
- package/lib/util/term.js +2 -0
- package/lib/watch/node-watch.js +38 -19
- package/npm-shrinkwrap.json +1053 -1279
- package/package.json +3 -3
- package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/test.js +0 -10
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,66 @@ 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.4 - 2021-11-24
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `cds import` fix for TypeError issue during OData V2 EDMX conversion to CSN.
|
|
14
|
+
- `cds import <file_name>` fix now updates the service name in the `package.json` with only the file name. Earlier, the service name sometimes used to be of the form `A.B`, with `A` being file name and `B` being a part of the schema namespace value in the EDMX file
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `cds init` uses latest `Maven Java archetype` version `1.20.3` for creating Java projects.
|
|
19
|
+
|
|
20
|
+
## Version 4.6.3 - 2021-11-16
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- `cds watch` recovers again from compilation errors and properly prints these
|
|
25
|
+
- `cds import` fix for omitting empty `doc` components.
|
|
26
|
+
- `cds add lint` no longer duplicates initial contents in `package.json`
|
|
27
|
+
- `cds add data` no longer ignores imported services for which credentials are stored in the project
|
|
28
|
+
|
|
29
|
+
## Version 4.6.2 - 2021-11-09
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- `cds add lint` now correctly detects missing local `eslint`
|
|
34
|
+
- `cds add lint` no longer removes parts of `package.json`
|
|
35
|
+
- `cds add lint` no longer creates duplicate configuration entries
|
|
36
|
+
|
|
37
|
+
## Version 4.6.1 - 2021-11-08
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `cds init` uses latest `Maven Java archetype` version `1.20.0` for creating Java projects.
|
|
42
|
+
- `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.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- `cds repl` now finds modules like `hdb` that are installed locally in the app folder
|
|
47
|
+
- `cds repl` now enables the `await` statement also on Windows
|
|
48
|
+
- `cds lint` now limits all file extensions to those allowed by the @sap/eslint-plugin-cds ESLint configuration
|
|
49
|
+
|
|
50
|
+
## Version 4.6.0 - 2021-11-02
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- `cds bind` binds the given service to a hana instance by storing the credentials in `.cdsrc.json` in your user home directory [beta].
|
|
54
|
+
- `cds import` introduced option `--include-namespaces` which imports the custom defined namespaces.
|
|
55
|
+
- `cds import` preserve documentation in CSN file for actions and functions from OData V4 EDMX file.
|
|
56
|
+
- `cds import` now supports reading values of the `as` option from cds.env
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- `cds import` fix for reflecting only supported datatypes in csn for actions and functions for OData V4.
|
|
61
|
+
- `cds import` fix for TypeError issue (#9868) during OData V4 EDMX conversion to CSN.
|
|
62
|
+
- `cds watch` no longer omits starting some services every other time it is restarting the process
|
|
63
|
+
- `cds-ts watch` now honors a local `tsconfig.json` file
|
|
64
|
+
- `cds import` fix for TypeError issue (#9950) during OData V2 EDMX conversion to CSN.
|
|
65
|
+
- `cds import` fix to generate the csn (#9950) during OData V2 EDMX conversion to CSN.
|
|
66
|
+
- `cds import` fix to replace the aliases with original schema namespace value.
|
|
67
|
+
- `cds import` adds `@cds.persistence.skip` back to imported models. Its accidental removal in 4.5.0 caused wrong DB deployments of imported entities.
|
|
68
|
+
|
|
9
69
|
## Version 4.5.4 - 2021-10-07
|
|
10
70
|
|
|
11
71
|
### Fixed
|
|
@@ -64,6 +124,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
|
64
124
|
+ no longer skips over entities marked with `@cds.persistence.skip`, which is true for 'external' entities created by `cds import`.
|
|
65
125
|
- `cds init --add` handles comma list correctly.
|
|
66
126
|
- `cds import` fix for multi-line documentation text in OData V4 EDMX file.
|
|
127
|
+
- `cds import` fix preserves the missing entities in csn for OData V2 EDMX file.
|
|
67
128
|
|
|
68
129
|
|
|
69
130
|
## Version 4.4.2 - 2021-09-03
|
package/bin/bind.js
CHANGED
|
@@ -1,17 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
module.exports = Object.assign(cds_bind, {
|
|
4
|
+
options: ['--to', '--profile', '--kind', '--output-file'],
|
|
5
|
+
flags: [],
|
|
6
|
+
shortcuts: ['-2', '-p', '-k', '-o'],
|
|
7
|
+
help: `
|
|
3
8
|
# SYNOPSIS
|
|
4
9
|
|
|
5
|
-
*cds bind* <service> [<options>]
|
|
10
|
+
*cds bind* <service> [<options>] -- beta feature
|
|
6
11
|
|
|
7
|
-
Binds the given service to
|
|
12
|
+
Binds the given service to a service instance by storing connection information in *.cdsrc-private.json*
|
|
13
|
+
in your project directory. Credentials are not stored in the file but rather retrieved dynamically during *cds watch*.
|
|
14
|
+
Use option *--output-file* to specify a different path or file.
|
|
15
|
+
|
|
16
|
+
Currently *cds bind* only supports Node.js projects.
|
|
8
17
|
|
|
9
18
|
# OPTIONS
|
|
10
19
|
|
|
11
|
-
*-2
|
|
20
|
+
*-2 | --to* <instance>[:<key>]
|
|
21
|
+
bind to a given instance
|
|
22
|
+
|
|
23
|
+
*-p | --profile* <profile>
|
|
24
|
+
add the given profile, defaults to *hybrid*
|
|
25
|
+
|
|
26
|
+
*-k | --kind* <kind>
|
|
27
|
+
the kind of service
|
|
28
|
+
|
|
29
|
+
*-o | --output-file <path>*
|
|
30
|
+
save bindings to the given *.cdsrc.json* or *package.json* file. Default is *.cdsrc-private.json*.
|
|
31
|
+
If *path* is a directory, then it will save it to the *.cdsrc.json* file in that directory.
|
|
32
|
+
|
|
33
|
+
# EXAMPLE
|
|
34
|
+
|
|
35
|
+
cds bind --to my-hdi-container
|
|
36
|
+
cds bind --to my-hdi-container,my-xsuaa
|
|
37
|
+
cds bind uaa --to my-xsuaa:my-xsuaa-key --kind xsuaa --profile myprofile
|
|
38
|
+
|
|
39
|
+
cds bind --to my-hdi-container --output-file ~
|
|
40
|
+
cds bind --to my-hdi-container --output-file package.json
|
|
41
|
+
|
|
42
|
+
`});
|
|
43
|
+
|
|
44
|
+
const { constants, promises: fsp } = require('fs');
|
|
45
|
+
const path = require('path');
|
|
46
|
+
|
|
47
|
+
const cds = require('@sap/cds/lib');
|
|
48
|
+
const LOG = cds.log('bind');
|
|
49
|
+
// required for spinner
|
|
50
|
+
LOG.isDebug = LOG._debug;
|
|
51
|
+
LOG.isTTY = process.stdout.isTTY;
|
|
52
|
+
|
|
53
|
+
const { bold, info } = require('../lib/util/term');
|
|
54
|
+
|
|
55
|
+
const Spinner = require('../lib/init/util/spinner');
|
|
56
|
+
|
|
12
57
|
|
|
13
|
-
|
|
58
|
+
async function cds_bind(args, options) { // eslint-disable-line
|
|
59
|
+
|
|
60
|
+
options.profile = options.profile || 'hybrid';
|
|
61
|
+
|
|
62
|
+
if (await isJavaProject('.')) {
|
|
63
|
+
throw new Error(`Found a 'pom.xml' file in your project root folder indicating a Java project. Currently, 'cds bind' only supports Node.js projects.`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!options.to) {
|
|
67
|
+
throw new Error(`use option --to or -2 to specify the target instance, e.g. cds bind --to myInstance:myService`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (args.length > 1) {
|
|
71
|
+
throw new Error(`Too many arguments: Please specify only one or no service.`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let serviceArg = args[0]
|
|
75
|
+
const targets = options.to.split(/,/g);
|
|
76
|
+
|
|
77
|
+
if (targets.length >= 2 && serviceArg) {
|
|
78
|
+
throw new Error(`Service argument cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the service argument.`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (targets.length >= 2 && options.kind) {
|
|
82
|
+
throw new Error(`The option '--kind' cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the '--kind' option.`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// prepare for different providers
|
|
86
|
+
const keyProvider = require('../lib/bind/cfKeyProvider');
|
|
87
|
+
keyProvider.setLogger(LOG);
|
|
88
|
+
const spinner = new Spinner(LOG);
|
|
89
|
+
const resolvedServices = await spinner.run(`Retrieving data from Cloud Foundry...`, async () => { // NOSONAR
|
|
90
|
+
const resolvedServices = [];
|
|
91
|
+
await Promise.all( targets.map( async target => {
|
|
92
|
+
const [instance, key] = target.split(/:/);
|
|
93
|
+
const resolvedService = await keyProvider.resolve(undefined, { instance, key });
|
|
94
|
+
// if (!options["save-credentials"]) {
|
|
95
|
+
delete resolvedService.credentials;
|
|
96
|
+
resolvedService.binding.resolved = false;
|
|
97
|
+
// }
|
|
98
|
+
resolvedServices.push(resolvedService);
|
|
99
|
+
}));
|
|
100
|
+
return resolvedServices;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!options.kind) {
|
|
104
|
+
keyProvider.determineKinds(resolvedServices);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const resolvedService of resolvedServices) {
|
|
108
|
+
resolvedService.kind = options.kind || resolvedService.kind;
|
|
109
|
+
resolvedService.name = serviceArg || keyProvider.getRequiresNameFromKind(resolvedService.binding.instance, resolvedService.kind);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// prepare for different providers
|
|
113
|
+
const userCdsrcJsonStorageProvider = require('../lib/bind/userCdsrcJsonStorageProvider');
|
|
114
|
+
|
|
115
|
+
await userCdsrcJsonStorageProvider.storeServices(resolvedServices, {
|
|
116
|
+
...options,
|
|
117
|
+
logger: LOG
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
LOG.log();
|
|
121
|
+
LOG.log(`${info("TIP:")} Run with cloud bindings: ${bold(`cds watch --profile ${options.profile}`)}`);
|
|
122
|
+
// LOG.log();
|
|
123
|
+
}
|
|
14
124
|
|
|
15
|
-
function
|
|
16
|
-
|
|
125
|
+
async function isJavaProject(projectPath) {
|
|
126
|
+
const pomXmlPath = path.join(projectPath, 'pom.xml');
|
|
127
|
+
try {
|
|
128
|
+
await fsp.access(pomXmlPath, constants.F_OK);
|
|
129
|
+
return true;
|
|
130
|
+
} catch (err) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
17
133
|
}
|
package/bin/cds-ts.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env ts-node
|
|
1
|
+
#!/usr/bin/env ts-node-cwd
|
|
2
2
|
require('./cds').apply(process.argv)
|
package/bin/cds.js
CHANGED
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/env.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = Object.assign (env, {
|
|
2
|
-
options: ['--for', '--mocked'], flags: [], shortcuts: ['-4'],
|
|
2
|
+
options: ['--for', '--mocked'], flags: ['--process-env', '--resolve-bindings'], shortcuts: ['-4', undefined, '-P', '-b'],
|
|
3
3
|
help: `
|
|
4
4
|
# SYNOPSIS
|
|
5
5
|
|
|
@@ -11,13 +11,29 @@ module.exports = Object.assign (env, {
|
|
|
11
11
|
|
|
12
12
|
# EXPLANATION
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
it in _.properties_ format.
|
|
14
|
+
Lists the effective configuration of the current environment in
|
|
15
|
+
_.properties_ format if no command, *ls*, or *list* is given.
|
|
17
16
|
|
|
18
|
-
The other
|
|
19
|
-
from which the effective configuration has been loaded.
|
|
17
|
+
The other commands either get or set a single property or display
|
|
18
|
+
the sources from which the effective configuration has been loaded.
|
|
20
19
|
|
|
20
|
+
# OPTIONS
|
|
21
|
+
|
|
22
|
+
*-4* | *--for* <path>
|
|
23
|
+
|
|
24
|
+
Load configuration from path instead of the current working directory.
|
|
25
|
+
|
|
26
|
+
*--profile* <profile,...>
|
|
27
|
+
|
|
28
|
+
Load configuration for the specified profile(s).
|
|
29
|
+
|
|
30
|
+
*-P* | *--process-env*
|
|
31
|
+
|
|
32
|
+
Show properties from Node.js _process.env_.
|
|
33
|
+
|
|
34
|
+
*-b* | *--resolve-bindings*
|
|
35
|
+
|
|
36
|
+
Resolve _cds bind_ bindings.
|
|
21
37
|
`})
|
|
22
38
|
|
|
23
39
|
const path = require('path')
|
|
@@ -29,15 +45,20 @@ const info = (s) => process.stdout.isTTY ? term.info (s) : s
|
|
|
29
45
|
async function env ([cmd, key, value], options={}) {
|
|
30
46
|
|
|
31
47
|
const cds = require('@sap/cds/lib')
|
|
32
|
-
const fn = commands[cmd] || (()=>{
|
|
48
|
+
const fn = (options["process-env"] ? processEnvCommands[cmd] : commands[cmd]) || (()=>{
|
|
33
49
|
this.help ('env')
|
|
34
50
|
throw new Error (`Don't understand '${cmd}' here...`)
|
|
35
51
|
})
|
|
36
52
|
|
|
53
|
+
if (options.profile) process.env.CDS_ENV = options.profile
|
|
54
|
+
|
|
37
55
|
const env = options.for ? cds.env.for (options.for) : cds.env
|
|
38
56
|
env['_home_cds-dk'] = path.resolve(__dirname, '..') // to help tools find the DK
|
|
39
57
|
|
|
58
|
+
if (options["resolve-bindings"]) await require('../lib/bind/bindingResolver').applyTo({env, output: "debug"})
|
|
59
|
+
|
|
40
60
|
if (!options.for && options.mocked) await cds.service.bindings
|
|
61
|
+
|
|
41
62
|
fn (env, key, value)
|
|
42
63
|
}
|
|
43
64
|
|
|
@@ -69,19 +90,39 @@ const commands = {
|
|
|
69
90
|
if (!process.stdout.isTTY) return commands.json (conf, key, val)
|
|
70
91
|
// tty: display formatted object
|
|
71
92
|
const obj = (key ? conf.get(key) : conf)
|
|
72
|
-
console.log (inspect (obj, {depth:22,colors:true}))
|
|
93
|
+
console.log (inspect (obj, {depth:22,colors:true}).replace(/\s+use:.*\[Getter\].*/g,''))
|
|
73
94
|
},
|
|
74
95
|
|
|
75
96
|
// eslint-disable-next-line no-unused-vars
|
|
76
97
|
json (conf, key, val) {
|
|
77
98
|
const obj = (key ? conf.get(key) : conf)
|
|
78
|
-
|
|
99
|
+
const str = JSON.stringify(obj, null, 2)
|
|
100
|
+
return console.log (str ? str.replace(/\s+use:.*\[Getter\].*/g,'') : str)
|
|
79
101
|
},
|
|
80
102
|
|
|
81
103
|
set () {
|
|
82
104
|
throw new Error ('cds config set is not yet implemented, sorry')
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const processEnvCommands = {
|
|
109
|
+
get [undefined]() { return processEnvCommands.list },
|
|
110
|
+
get ''() { return processEnvCommands.list },
|
|
111
|
+
get ls() { return process.list },
|
|
112
|
+
|
|
113
|
+
list (_, key) {
|
|
114
|
+
if (key) {
|
|
115
|
+
processEnvCommands.get(undefined, key)
|
|
116
|
+
} else {
|
|
117
|
+
for (const name in process.env) {
|
|
118
|
+
console.log(`${name}=${process.env[name]}`)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
83
121
|
},
|
|
84
122
|
|
|
123
|
+
get (_, key) {
|
|
124
|
+
console.log (process.env[key] || "")
|
|
125
|
+
}
|
|
85
126
|
}
|
|
86
127
|
|
|
87
128
|
/* eslint no-console:0 */
|
package/bin/help.js
CHANGED
|
@@ -10,6 +10,7 @@ module.exports = exports = Object.assign (help, {help:`
|
|
|
10
10
|
|
|
11
11
|
*i* | *init* jump-start cds-based projects
|
|
12
12
|
*a* | *add* add a feature to an existing project
|
|
13
|
+
*y* | *bind* [beta] bind a service to a hana instance
|
|
13
14
|
*m* | *import* add models from external sources
|
|
14
15
|
*c* | *compile* compile cds models to different outputs
|
|
15
16
|
*s* | *serve* run your services in local server
|
package/bin/import.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
module.exports = Object.assign(_import, {
|
|
3
3
|
_name: 'import',
|
|
4
|
-
options: ['--out', '--into', '--as'],
|
|
4
|
+
options: ['--out', '--into', '--as', '--include-namespaces'],
|
|
5
5
|
flags: ['--dry', '--force', '--no-copy', '--no-save', '--keep-namespace'],
|
|
6
|
-
shortcuts: ['-o', '-in', '-as', '-', '-f'],
|
|
6
|
+
shortcuts: ['-o', '-in', '-as', '-ns', '-', '-f'],
|
|
7
7
|
help: `
|
|
8
8
|
# SYNOPSIS
|
|
9
9
|
|
|
@@ -42,7 +42,10 @@ module.exports = Object.assign(_import, {
|
|
|
42
42
|
Converts the input edmx or xml file into one of these supported formats "cds", "csn", "json"
|
|
43
43
|
|
|
44
44
|
*-f | --force*
|
|
45
|
-
Forcefully overwrites the contents in the CDS file and updates the checksum
|
|
45
|
+
Forcefully overwrites the contents in the CDS file and updates the checksum
|
|
46
|
+
|
|
47
|
+
*-ns | --include-namespaces <string_of_namespaces> or* *
|
|
48
|
+
Imports only entities matching to the given list of namespaces.
|
|
46
49
|
|
|
47
50
|
|
|
48
51
|
|
|
@@ -52,6 +55,8 @@ module.exports = Object.assign(_import, {
|
|
|
52
55
|
cds import ~/Downloads/API_BUSINESS_PARTNER.edmx
|
|
53
56
|
cds import - ~/Downloads/API_BUSINESS_PARTNER.edmx
|
|
54
57
|
cds import ~/Downloads/API_BUSINESS_PARTNER.edmx --as cds
|
|
58
|
+
cds import ~/Downloads/API_BUSINESS_PARTNER.edmx --include-namespaces "sap,c4c"
|
|
59
|
+
cds import ~/Downloads/API_BUSINESS_PARTNER.edmx --include-namespaces "*"
|
|
55
60
|
|
|
56
61
|
`})
|
|
57
62
|
const cds = require('@sap/cds/lib')
|
|
@@ -62,12 +67,19 @@ const common = require('../lib/import/common');
|
|
|
62
67
|
const cdsCompiler = require('../lib/compile').compile.to;
|
|
63
68
|
const md5 = require('md5');
|
|
64
69
|
let cwd;
|
|
65
|
-
async function _import(file, { out, dry, into, as,
|
|
70
|
+
async function _import(file, { out, dry, into, as,
|
|
71
|
+
'include-namespaces': include_namespaces,
|
|
66
72
|
'no-save': no_save,
|
|
67
73
|
'no-copy': no_copy,
|
|
68
74
|
'keep-namespace': keep_namespace,
|
|
69
75
|
force
|
|
70
76
|
} = {}) {
|
|
77
|
+
if (!as) {
|
|
78
|
+
if (cds.env.import) as = cds.env.import.as;
|
|
79
|
+
}
|
|
80
|
+
if (!include_namespaces) {
|
|
81
|
+
if(cds.env.import) include_namespaces = cds.env.import.include_namespaces;
|
|
82
|
+
}
|
|
71
83
|
cwd = into || process.cwd();
|
|
72
84
|
if (as && !common.supportedFormats().includes(as))
|
|
73
85
|
throw new Error(messages.INVALID_AS_OPTION);
|
|
@@ -78,6 +90,14 @@ async function _import(file, { out, dry, into, as,
|
|
|
78
90
|
const dst = path.join(external, path.basename(file))
|
|
79
91
|
if (!dry && !no_copy) file = await _copy_to_srv_external(file, dst)
|
|
80
92
|
const src = await edm2csn.getMetadataFromFile(file)
|
|
93
|
+
this.include_all_namespaces = false;
|
|
94
|
+
let namespaces = [];
|
|
95
|
+
if(include_namespaces) {
|
|
96
|
+
if(include_namespaces === "*") this.include_all_namespaces = true;
|
|
97
|
+
else if(typeof include_namespaces === 'string' && !include_namespaces.startsWith('-')) namespaces = include_namespaces.replace(/ /g, "").split(',');
|
|
98
|
+
else throw new Error(messages.INCORRECT_INPUT_NAMESPACES);
|
|
99
|
+
}
|
|
100
|
+
this.namespaces = namespaces;
|
|
81
101
|
let csn = await edm2csn.edmx2csn(src, !keep_namespace && file, this)
|
|
82
102
|
const service = _service_name_from(csn);
|
|
83
103
|
if (out) out = edm2csn.validateAndComputeOutputFilePath(out, as);
|
|
@@ -96,23 +116,23 @@ async function _generateChecksumValidate(dest, output, force) {
|
|
|
96
116
|
return output;
|
|
97
117
|
}
|
|
98
118
|
else {
|
|
99
|
-
let
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
let checksum = md5(
|
|
119
|
+
let existingFileContent = await read(dest, "utf-8");
|
|
120
|
+
existingFileContent = String(existingFileContent);
|
|
121
|
+
if (existingFileContent.indexOf("checksum") === -1){
|
|
122
|
+
let checksum = md5(existingFileContent);
|
|
103
123
|
output = "/* checksum : " + checksum + " */\n" + output;
|
|
104
124
|
return output;
|
|
105
125
|
}
|
|
106
|
-
let fileChecksum =
|
|
107
|
-
|
|
108
|
-
let checksum = md5(
|
|
126
|
+
let fileChecksum = existingFileContent.substring(existingFileContent.indexOf("checksum") + 11, existingFileContent.indexOf(" */"));
|
|
127
|
+
existingFileContent = existingFileContent.substring(existingFileContent.indexOf('*/') + 3);
|
|
128
|
+
let checksum = md5(existingFileContent);
|
|
109
129
|
if (fileChecksum === checksum) {
|
|
110
|
-
output = "/* checksum : " + checksum + " */\n" +
|
|
130
|
+
output = "/* checksum : " + checksum + " */\n" + existingFileContent;
|
|
111
131
|
return output;
|
|
112
132
|
}
|
|
113
133
|
else {
|
|
114
134
|
if (force) {
|
|
115
|
-
output = "/* checksum : " +
|
|
135
|
+
output = "/* checksum : " + md5(output) + " */\n" + output;
|
|
116
136
|
return output;
|
|
117
137
|
}
|
|
118
138
|
else {
|
|
@@ -195,4 +215,4 @@ async function _update_package_json(dest, service, version) {
|
|
|
195
215
|
await write(package_json, JSON.stringify(conf, null, ' '))
|
|
196
216
|
console.log(`[cds] - updated ./package.json`)
|
|
197
217
|
}
|
|
198
|
-
}
|
|
218
|
+
}
|
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
|
|
@@ -67,12 +67,15 @@ async function watch ([cwd], {
|
|
|
67
67
|
.filter(removeArgsIn(watchOnlyOptions)) // remove all watch-only options, as `cds serve` would not accept them
|
|
68
68
|
.filter(a => a !== cwd))
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
let env = Object.assign (process.env, {
|
|
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 ()
|
|
@@ -100,8 +103,12 @@ async function watch ([cwd], {
|
|
|
100
103
|
log (`watching: ${ext}...`)
|
|
101
104
|
if (liveReload) log (`live reload enabled for browsers`)
|
|
102
105
|
|
|
106
|
+
const bindingManager = new require('../lib/bind/bindingResolver').bindingManager({cwd})
|
|
107
|
+
const bindings = await bindingManager.resolve()
|
|
108
|
+
if (bindings) env = {...env, CDS_CONFIG: JSON.stringify(bindings)}
|
|
109
|
+
|
|
103
110
|
const nodemon = require('../lib/watch/node-watch')
|
|
104
|
-
|
|
111
|
+
const watcher = nodemon ({
|
|
105
112
|
watch: ['*','.env','.cdsrc.json'],
|
|
106
113
|
script:__filename, cwd, env, ext, ignore,
|
|
107
114
|
delay: parseInt(process.env.CDS_WATCH_DELAY) || 200,
|
|
@@ -111,12 +118,18 @@ async function watch ([cwd], {
|
|
|
111
118
|
if (liveReload) liveReload.markPending(files)
|
|
112
119
|
if (this.delayed) clearTimeout (this.delayed)
|
|
113
120
|
this.delayed = setTimeout(()=>{
|
|
121
|
+
bindingManager.update({
|
|
122
|
+
onBeforeUpdate: () => watcher.stop(),
|
|
123
|
+
onAfterUpdate: bindings => {
|
|
124
|
+
watcher.setEnv('CDS_CONFIG', bindings && JSON.stringify(bindings))
|
|
125
|
+
watcher.restart()
|
|
126
|
+
}
|
|
127
|
+
})
|
|
114
128
|
log (`${t.bold} _______________________\n`)
|
|
115
129
|
FileHandlers.changed (files,cwd)
|
|
116
130
|
}, 111)
|
|
117
131
|
}).on('quit', ()=>{
|
|
118
132
|
log (`${t.bold+t.green}\n[cds] - my watch has ended.\n`)
|
|
119
|
-
process.exit()
|
|
120
133
|
}).on('message', async (msg) => { switch (msg.code) { // messages from child process
|
|
121
134
|
case 'listening':
|
|
122
135
|
env.PORT = (msg.address && msg.address.port) || msg.port
|
|
@@ -127,6 +140,8 @@ async function watch ([cwd], {
|
|
|
127
140
|
case 'EADDRINUSE': env.PORT = 0; _addr_in_use(msg); break
|
|
128
141
|
default: console.error (msg)
|
|
129
142
|
}})
|
|
143
|
+
|
|
144
|
+
return watcher
|
|
130
145
|
}
|
|
131
146
|
|
|
132
147
|
|
|
@@ -160,6 +175,12 @@ function removeArgsIn (toRemove) {
|
|
|
160
175
|
}
|
|
161
176
|
}
|
|
162
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
|
+
|
|
163
184
|
//
|
|
164
185
|
// Child process impl launched by watch
|
|
165
186
|
//
|
|
@@ -168,15 +189,24 @@ if (!module.parent) (async()=>{ // launched by nodemon
|
|
|
168
189
|
// run through cli in order to use its error handling
|
|
169
190
|
const bootstrap = require('./cds')(...JSON.parse(process.env._args))
|
|
170
191
|
const {cds} = global
|
|
192
|
+
|
|
193
|
+
cds.once('listening', ({server, url}) => {
|
|
194
|
+
process.send ({ code:'listening', port: server.address().port })
|
|
195
|
+
// Need to give bindings an explicit call to purge,
|
|
196
|
+
// as its .exit handler has no chance to execute on Windows.
|
|
197
|
+
process.on ('message', (msg)=> { if (msg && msg.exit) { // see node-watch
|
|
198
|
+
(new cds.service.bindings(url)).purge()
|
|
199
|
+
}})
|
|
200
|
+
})
|
|
201
|
+
|
|
171
202
|
try {
|
|
172
|
-
cds.once('listening', ({server}) => process.send ({ code:'listening', port: server.address().port }))
|
|
173
203
|
await bootstrap
|
|
174
204
|
if (!cds.service.providers.length) return _no_services_found()
|
|
175
205
|
} catch (e) { switch (e.code) {
|
|
176
206
|
case 'NO_SERVICES_FOUND': return _no_services_found(e)
|
|
177
207
|
case 'MODEL_NOT_FOUND': return _no_models_found(e)
|
|
178
208
|
case 'EADDRINUSE': return process.send(e) //> tell cds watch
|
|
179
|
-
default:
|
|
209
|
+
default: { throw e } // cli error handling will catch and format
|
|
180
210
|
}}
|
|
181
211
|
function _no_models_found(e) { console.log (`
|
|
182
212
|
No models found in ${cds.resolve(e.model||'*',false)}.
|