@sap/cds-dk 7.5.1 → 7.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/bin/add.js +28 -24
- package/bin/bind.js +59 -32
- package/bin/build.js +1 -1
- package/bin/cds.js +1 -1
- package/bin/env.js +1 -6
- package/bin/init.js +7 -3
- package/bin/logout.js +2 -2
- package/bin/migrate.js +1 -1
- package/bin/version.js +1 -0
- package/bin/watch.js +8 -1
- package/lib/bind/bindingUtil.js +14 -20
- package/lib/bind/cfKeyProvider.js +8 -10
- package/lib/bind/index.js +4 -2
- package/lib/build/buildTaskFactory.js +31 -20
- package/lib/build/constants.js +9 -8
- package/lib/build/provider/featureToggleBuildPlugin.js +1 -7
- package/lib/build/provider/hana/index.js +44 -9
- package/lib/build/provider/internalBuildTaskProvider.js +7 -5
- package/lib/build/provider/java/index.js +0 -6
- package/lib/build/provider/mtx-sidecar/index.js +5 -0
- package/lib/build/provider/nodejs/index.js +32 -47
- package/lib/build/util.js +134 -33
- package/lib/deploy/to-hana/hana.js +1 -1
- package/lib/env/schema.js +157 -17
- package/lib/env/schemas/cds-rc.js +118 -0
- package/lib/init/constants.js +1 -1
- package/lib/init/merge.js +2 -1
- package/lib/init/template/application-logging/index.js +1 -2
- package/lib/init/template/approuter/files/mta.yaml.hbs +2 -0
- package/lib/init/template/approuter/files/package.json +1 -1
- package/lib/init/template/approuter/files/values.yaml.hbs +8 -1
- package/lib/init/template/hana/files/undeploy.json +3 -2
- package/lib/init/template/helm/files/chart/templates/NOTES.txt +2 -0
- package/lib/init/template/helm/files/chart/templates/_deployment_helpers.tpl +10 -2
- package/lib/init/template/helm/files/content-deployment/Chart.yaml +1 -1
- package/lib/init/template/helm/files/content-deployment/templates/_helpers.tpl +6 -5
- package/lib/init/template/helm/files/content-deployment/values.yaml +1 -1
- package/lib/init/template/helm/files/service-instance/Chart.yaml +1 -1
- package/lib/init/template/helm/files/service-instance/templates/_helpers.tpl +6 -5
- package/lib/init/template/helm/files/service-instance/values.yaml +1 -1
- package/lib/init/template/helm/files/web-application/Chart.yaml +1 -1
- package/lib/init/template/helm/files/web-application/templates/_api.tpl +6 -5
- package/lib/init/template/helm/files/web-application/values.yaml +1 -1
- package/lib/init/template/helm/index.js +1 -12
- package/lib/init/template/helm-unified-runtime/index.js +3 -2
- package/lib/init/template/html5-repo/files/values.yaml.hbs +9 -0
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +1 -2
- package/lib/init/template/multitenancy/index.js +3 -2
- package/lib/init/template/xsuaa/files/package.json.hbs +1 -2
- package/lib/mtx/activate.js +1 -1
- package/lib/mtx/auth_manager.js +4 -2
- package/lib/mtx/download_legacy.js +1 -1
- package/lib/mtx/extend.js +2 -2
- package/lib/mtx/pull.js +1 -1
- package/lib/mtx/push.js +1 -1
- package/lib/mtx/settings_manager.js +77 -26
- package/lib/mtx/tenant_action.js +1 -1
- package/lib/mtx/util/legacy_ext.js +0 -1
- package/lib/util/axios.js +1 -19
- package/lib/util/cf.js +15 -10
- package/npm-shrinkwrap.json +306 -278
- package/package.json +1 -1
- package/lib/env/schemas/cds-rc.json +0 -101
- package/lib/init/template/helm-unified-runtime/lib/build.js +0 -0
package/bin/add.js
CHANGED
|
@@ -10,53 +10,57 @@ module.exports = Object.assign(add, {
|
|
|
10
10
|
|
|
11
11
|
*cds add* <feature | comma-separated list of features>
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Add one or more features to an existing project - grow as you go.
|
|
14
14
|
|
|
15
|
-
The following features
|
|
15
|
+
The following features can be added:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
*hana* - add support for SAP HANA
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
*sqlite* - add support for SQLite
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
*postgres* - add support for PostgreSQL
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
*liquibase* - add support for Liquibase
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
*xsuaa* - add support for authentication via XSUAA
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
*multitenancy* - add support for multitenancy
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
*toggles* - add support for feature toggles
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
*extensibility* - add support for extensibility
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
*approuter* - add support for application routing
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
*local-messaging* - add support for local messaging
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
*file-based-messaging* - add support for file-based messaging
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
*enterprise-messaging* - add support for SAP Event Mesh
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
*redis-messaging* - add support for Redis messaging
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
*kibana* - add support for Kibana formatting
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
*mta* - add support for MTA-based deployment
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
*cf-manifest* - add support for CF-native deployment
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
*helm* - add support for Helm-based Kyma deployment
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
*html5-repo* - add support for the HTML5 repository
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
*pipeline* - add files for CI/CD pipeline integration
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
*tiny-sample* - add minimal sample files
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
*sample* - add sample files including Fiori UI
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
*data* - add CSV headers for modeled entities
|
|
60
|
+
|
|
61
|
+
*typer* - add type generation for CDS models
|
|
62
|
+
|
|
63
|
+
*lint* - add support for CDS Lint
|
|
60
64
|
|
|
61
65
|
|
|
62
66
|
# OPTIONS
|
package/bin/bind.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module.exports = Object.assign(cds_bind, {
|
|
2
|
-
options: ['--to', '--for', '--on', '--kind', '--output-file'],
|
|
2
|
+
options: ['--to', '--for', '--on', '--kind', '--output-file', '--to-app-services', '--no-create-service-key'],
|
|
3
3
|
flags: ['--exec'],
|
|
4
|
-
shortcuts: ['-2', '-4', '-n', '-k', '-o'],
|
|
4
|
+
shortcuts: ['-2', '-4', '-n', '-k', '-o', '-a'],
|
|
5
5
|
help: `
|
|
6
6
|
# SYNOPSIS
|
|
7
7
|
|
|
@@ -21,33 +21,48 @@ module.exports = Object.assign(cds_bind, {
|
|
|
21
21
|
# OPTIONS
|
|
22
22
|
|
|
23
23
|
*-2 | --to* <instance>[:<key>] | <service-binding> | <secret>
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
Bind to a given Cloud Foundry instance, Kubernetes service binding or Kubernetes secret.
|
|
25
26
|
|
|
26
27
|
*-4 | --for* <profile>
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
Profile to store binding information. Defaults to *hybrid*.
|
|
29
30
|
|
|
30
31
|
*-n | --on* cf | k8s
|
|
31
|
-
|
|
32
|
+
|
|
33
|
+
Target platform (Cloud Foundry or Kubernetes) to bind to. Defaults to *cf*.
|
|
32
34
|
|
|
33
35
|
*-k | --kind* <kind>
|
|
34
|
-
|
|
36
|
+
|
|
37
|
+
Kind of the service.
|
|
35
38
|
|
|
36
39
|
*-o | --output-file* <path>
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
|
|
41
|
+
Output file for added binding information. Use this option if binding configuration should
|
|
42
|
+
be added to *package.json* or *.cdsrc.json*. Defaults to *.cdsrc-private.json*.
|
|
43
|
+
If *path* is a directory, the *.cdsrc.json* file in that directory is used.
|
|
44
|
+
|
|
45
|
+
*-a | --to-app-services <app>* (Beta)
|
|
46
|
+
|
|
47
|
+
Bind to a given application (Cloud Foundry only).
|
|
48
|
+
|
|
49
|
+
*--no-create-service-key*
|
|
50
|
+
|
|
51
|
+
Skip automatic creation of service keys.
|
|
39
52
|
|
|
40
53
|
# EXAMPLE
|
|
41
54
|
|
|
42
|
-
cds bind --to
|
|
43
|
-
cds bind --to
|
|
44
|
-
cds bind
|
|
55
|
+
cds bind --to bookshop-db
|
|
56
|
+
cds bind --to bookshop-db,bookshop-auth
|
|
57
|
+
cds bind auth --to bookshop-auth:bookshop-auth-key --kind xsuaa --for my-profile
|
|
45
58
|
|
|
46
|
-
cds bind --to
|
|
47
|
-
cds bind --to
|
|
59
|
+
cds bind --to bookshop-db --output-file .
|
|
60
|
+
cds bind --to bookshop-db --output-file package.json
|
|
48
61
|
|
|
49
|
-
cds bind --to
|
|
50
|
-
cds bind --to
|
|
62
|
+
cds bind --to bookshop-db --on k8s
|
|
63
|
+
cds bind --to bookshop-db --for my-profile
|
|
64
|
+
|
|
65
|
+
cds bind --to-app-services bookshop-srv
|
|
51
66
|
`
|
|
52
67
|
});
|
|
53
68
|
|
|
@@ -72,29 +87,41 @@ async function cds_bind(args, options) {
|
|
|
72
87
|
throw 'Option --profile is no longer supported. Use --for instead to specify the profile to use when storing connection settings.';
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
|
|
76
|
-
|
|
90
|
+
const { on, 'to-app-services': app, to } = options
|
|
91
|
+
|
|
92
|
+
if (on === 'k8s' && app) {
|
|
93
|
+
throw 'Option --to-app-services is only supported for Cloud Foundry.';
|
|
77
94
|
}
|
|
78
95
|
|
|
79
|
-
if (
|
|
80
|
-
throw `
|
|
96
|
+
if (!to && !app) {
|
|
97
|
+
throw `Use option --to or -2 to specify the target instance, e.g. cds bind --to myInstance:myService`;
|
|
81
98
|
}
|
|
82
99
|
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
const outputFile = options['output-file']
|
|
101
|
+
if (app) {
|
|
102
|
+
const services = await require('../lib/util/cf').getServices(app)
|
|
103
|
+
// Later: optimize logging for parallelization, services.forEach(service => bind({ ...options, to: service.name, outputFile }))
|
|
104
|
+
for (const service of services.filter(s => Object.keys(s.credentials).length > 0)) {
|
|
105
|
+
await bind({ ...options, to: service.name, outputFile })
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
if (args.length > 1) {
|
|
109
|
+
throw `Too many arguments: Please specify only one or no service.`;
|
|
110
|
+
}
|
|
85
111
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
112
|
+
options.serviceArg = args[0]
|
|
113
|
+
options.targets = options.to.split(/,/g);
|
|
89
114
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
115
|
+
if (options.targets.length >= 2 && options.serviceArg) {
|
|
116
|
+
throw `Service argument cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the service argument.`;
|
|
117
|
+
}
|
|
93
118
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
119
|
+
if (options.targets.length >= 2 && options.kind) {
|
|
120
|
+
throw `The option '--kind' cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the '--kind' option.`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
await bind({ ...options, outputFile });
|
|
124
|
+
}
|
|
98
125
|
}
|
|
99
126
|
|
|
100
127
|
async function cds_bind_exec(command) { // eslint-disable-lint
|
package/bin/build.js
CHANGED
|
@@ -80,7 +80,7 @@ module.exports = Object.assign(build, {
|
|
|
80
80
|
a tarball will be created in folder 'gen/srv'. Dependencies in package.json
|
|
81
81
|
will be adapted to point to the correct tarball file URL.
|
|
82
82
|
Contents is packaged based on the rules of the 'npm pack' command.
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
# EXAMPLES
|
|
85
85
|
|
|
86
86
|
*cds* build
|
package/bin/cds.js
CHANGED
|
@@ -45,12 +45,12 @@ const cli = {
|
|
|
45
45
|
}
|
|
46
46
|
const args = this.args(task, argv)
|
|
47
47
|
args[0].push(...appendArgs)
|
|
48
|
-
if (args[1]?.['resolve-bindings']) await _resolveBindings({ silent: cmd === 'env' })
|
|
49
48
|
cds.cli = {
|
|
50
49
|
command: cmd,
|
|
51
50
|
argv: args[0],
|
|
52
51
|
options: args[1],
|
|
53
52
|
}
|
|
53
|
+
if (args[1]?.['resolve-bindings']) await _resolveBindings({ silent: cmd === 'env' })
|
|
54
54
|
return await task.apply(this, args)
|
|
55
55
|
}
|
|
56
56
|
} catch (e) {
|
package/bin/env.js
CHANGED
|
@@ -63,12 +63,7 @@ async function env ([cmd, key, value], options={}) {
|
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
let env = cds.env
|
|
66
|
-
|
|
67
|
-
const BindingManager = require('../lib/bind/bindingManager')
|
|
68
|
-
const bindingManager = new BindingManager({ env, silent: true })
|
|
69
|
-
const bindingEnv = await bindingManager.bindingEnv()
|
|
70
|
-
Object.assign(process.env, bindingEnv)
|
|
71
|
-
}
|
|
66
|
+
// REVISIT: Currently only read in env.test.js
|
|
72
67
|
env['_home_cds-dk'] = path.resolve(__dirname, '..') // to help tools find the DK
|
|
73
68
|
|
|
74
69
|
if (!options.for && options.mocked) await cds.service.bindings
|
package/bin/init.js
CHANGED
|
@@ -28,7 +28,11 @@ module.exports = Object.assign(init, {
|
|
|
28
28
|
|
|
29
29
|
*hana* - add support for SAP HANA
|
|
30
30
|
|
|
31
|
-
*sqlite* - add support for SQLite
|
|
31
|
+
*sqlite* - add support for SQLite
|
|
32
|
+
|
|
33
|
+
*postgres* - add support for PostgreSQL
|
|
34
|
+
|
|
35
|
+
*liquibase* - add support for Liquibase
|
|
32
36
|
|
|
33
37
|
*xsuaa* - add support for authentication via XSUAA
|
|
34
38
|
|
|
@@ -44,9 +48,9 @@ module.exports = Object.assign(init, {
|
|
|
44
48
|
|
|
45
49
|
*enterprise-messaging* - add support for SAP Event Mesh
|
|
46
50
|
|
|
47
|
-
*
|
|
51
|
+
*file-based-messaging* - add support for file-based messaging
|
|
48
52
|
|
|
49
|
-
*
|
|
53
|
+
*redis-messaging* - add support for Redis messaging
|
|
50
54
|
|
|
51
55
|
*mta* - add support for MTA-based deployment
|
|
52
56
|
|
package/bin/logout.js
CHANGED
|
@@ -44,8 +44,8 @@ module.exports = Object.assign(logout, {
|
|
|
44
44
|
*--clear-invalid*
|
|
45
45
|
|
|
46
46
|
Enter special mode to clear all tokens and settings for any project
|
|
47
|
-
folders which no longer exist in the file system.
|
|
48
|
-
command-line arguments.
|
|
47
|
+
folders which no longer exist in the file system. Additionally, removes
|
|
48
|
+
expired tokens. Ignores any other command-line arguments.
|
|
49
49
|
|
|
50
50
|
`;
|
|
51
51
|
}})
|
package/bin/migrate.js
CHANGED
package/bin/version.js
CHANGED
|
@@ -106,6 +106,7 @@ function _markdown (versions) {
|
|
|
106
106
|
console.log ('|', v('@sap/cds-dk (global)'), '|')
|
|
107
107
|
console.log ('|', v('@sap/eslint-plugin-cds'), '|')
|
|
108
108
|
console.log ('|', v('@sap/cds-mtxs'), '|')
|
|
109
|
+
console.log ('|', v('@cap-js/cds-types'), '|')
|
|
109
110
|
function v (component) {
|
|
110
111
|
const version = versions [component] || MISSING
|
|
111
112
|
return (component + ' ').slice(0,22)
|
package/bin/watch.js
CHANGED
|
@@ -64,7 +64,14 @@ const t = module.exports.codes = {
|
|
|
64
64
|
orange: colors ? '\x1b[38;2;255;140;0m' : '' // darker orange, works with bright and dark background
|
|
65
65
|
}
|
|
66
66
|
const extDefaults = 'cds,csn,csv,ts,mjs,cjs,js,json,properties,edmx,xml,env'
|
|
67
|
-
const ignore = RegExp(
|
|
67
|
+
const ignore = RegExp(
|
|
68
|
+
`(node_modules|_out|@types|@cds-models)\\${sep}` +
|
|
69
|
+
`|app(\\${sep}.+)?\\${sep}(` +
|
|
70
|
+
`(webapp|dist|target)\\${sep}|` +
|
|
71
|
+
`tsconfig\\.json$|` +
|
|
72
|
+
`.*\\.tsbuildinfo$` +
|
|
73
|
+
')'
|
|
74
|
+
)
|
|
68
75
|
|
|
69
76
|
async function watch ([cwd], {
|
|
70
77
|
args = ['serve', 'all'],
|
package/lib/bind/bindingUtil.js
CHANGED
|
@@ -14,14 +14,13 @@ const KindToRequiresNameMap = {
|
|
|
14
14
|
'enterprise-messaging': 'messaging',
|
|
15
15
|
'enterprise-messaging-amqp': 'messaging',
|
|
16
16
|
'enterprise-messaging-http': 'messaging',
|
|
17
|
-
'enterprise-messaging-shared': 'messaging'
|
|
17
|
+
'enterprise-messaging-shared': 'messaging',
|
|
18
|
+
'multitenancy': 'multitenancy'
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
const PreferredKinds =
|
|
21
|
-
'hana-cloud',
|
|
22
|
-
|
|
23
|
-
'xsuaa-auth'
|
|
24
|
-
];
|
|
21
|
+
const PreferredKinds = {
|
|
22
|
+
multitenancy:1, 'hana-cloud':1, xsuaa:1, 'xsuaa-auth':1, 'ias-auth':1, 'saas-registry':1
|
|
23
|
+
};
|
|
25
24
|
|
|
26
25
|
const PLATFORM_TYPES = {
|
|
27
26
|
'cf': 'Cloud Foundry',
|
|
@@ -64,29 +63,24 @@ class BindingUtil {
|
|
|
64
63
|
throw new Error(`Please provide a service kind or update @sap/cds version to use the kind detection.`);
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
function findKindFor(kind, service) {
|
|
68
|
-
const vcapService = env._find_credentials_for_required_service(kind, service, vcapServices);
|
|
69
|
-
if (!vcapService) return;
|
|
70
|
-
if (!Object.values(requires).find(require => require !== service && require.kind == kind))
|
|
71
|
-
vcapService.service.kindCandidates.push(kind);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
66
|
const requires = env.requires.kinds || {};
|
|
75
|
-
for (const kind of Object.
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
for (const [kind, service] of Object.entries(requires)) {
|
|
68
|
+
const vcapService = env._find_credentials_for_required_service(kind, service, vcapServices);
|
|
69
|
+
if (!vcapService) continue;
|
|
70
|
+
const isUniqueKind = !Object.values(requires).some(otherService =>
|
|
71
|
+
otherService !== service && otherService.kind === kind
|
|
72
|
+
)
|
|
73
|
+
if (isUniqueKind) vcapService.service.kindCandidates.push(kind);
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
// Check if one "kind" per service was found
|
|
82
77
|
for (const service of services) {
|
|
83
|
-
const preferredKind = service.kindCandidates.find(kind =>
|
|
78
|
+
const preferredKind = service.kindCandidates.find(kind => kind in PreferredKinds);
|
|
84
79
|
if (preferredKind) {
|
|
85
80
|
service.kind = preferredKind;
|
|
86
|
-
} if (service.kindCandidates.length === 1) {
|
|
81
|
+
} else if (service.kindCandidates.length === 1) {
|
|
87
82
|
service.kind = service.kindCandidates[0];
|
|
88
83
|
}
|
|
89
|
-
|
|
90
84
|
delete service.kindCandidates;
|
|
91
85
|
}
|
|
92
86
|
}
|
|
@@ -8,7 +8,7 @@ require('../util/axios').pruneErrors();
|
|
|
8
8
|
const { URL } = require('url');
|
|
9
9
|
const { bold, highlight } = require('../util/term');
|
|
10
10
|
|
|
11
|
-
class CFKeyProvider {
|
|
11
|
+
module.exports = new class CFKeyProvider {
|
|
12
12
|
async getCfSpaceInfo() {
|
|
13
13
|
DEBUG?.('getting space info');
|
|
14
14
|
|
|
@@ -93,17 +93,18 @@ class CFKeyProvider {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
async _resolveManagedService(instanceObj, instance, key, org, space) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
const create = (cds.cli.command === 'bind' || cds.cli.command === 'deploy') && !cds.cli.options['no-create-service-key']
|
|
97
|
+
const silent = (cds.cli.options.json || cds.cli.command === 'env') && !DEBUG
|
|
98
|
+
const credentials = await cfUtil.getOrCreateServiceKey(instanceObj, key, {}, { create, silent });
|
|
99
|
+
|
|
100
|
+
if (!credentials) {
|
|
100
101
|
let message = `No service key ${highlight(key)} found for service instance ${highlight(instance)}.\n\n`;
|
|
101
102
|
message += `Use ${bold(`cf create-service-key ${instanceObj.name} ${key} [-c ...]`)} to create the required service key.`;
|
|
102
103
|
throw message;
|
|
103
104
|
}
|
|
105
|
+
|
|
104
106
|
const planObj = await this.getPlans({ guids: instanceObj.relationships.service_plan.data.guid });
|
|
105
107
|
const offeringObj = await this.getOfferings({ guids: planObj.relationships.service_offering.data.guid });
|
|
106
|
-
const keyCredentialsObj = await BatchRequest.req(this.target, `/v3/service_credential_bindings/${encodeURIComponent(keyObj.guid)}/details`);
|
|
107
108
|
const resolvedBinding = {
|
|
108
109
|
binding: {
|
|
109
110
|
type: "cf",
|
|
@@ -119,7 +120,7 @@ class CFKeyProvider {
|
|
|
119
120
|
},
|
|
120
121
|
resolved: true,
|
|
121
122
|
},
|
|
122
|
-
credentials
|
|
123
|
+
credentials
|
|
123
124
|
};
|
|
124
125
|
|
|
125
126
|
return resolvedBinding;
|
|
@@ -237,7 +238,6 @@ class BatchRequest {
|
|
|
237
238
|
static async req(target, urlPath) {
|
|
238
239
|
const url = new URL(urlPath, target.apiEndpoint);
|
|
239
240
|
DEBUG?.(`_req: ${url.toString()}`);
|
|
240
|
-
|
|
241
241
|
const result = await axios.get(url.toString(), {
|
|
242
242
|
headers: {
|
|
243
243
|
authorization: target.authorization
|
|
@@ -246,5 +246,3 @@ class BatchRequest {
|
|
|
246
246
|
return result.data;
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
|
-
|
|
250
|
-
module.exports = new CFKeyProvider()
|
package/lib/bind/index.js
CHANGED
|
@@ -33,7 +33,7 @@ async function bind(options) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const onText = { 'cf': 'Cloud Foundry', 'k8s': 'Kubernetes' }[on];
|
|
36
|
-
logger.log(`Retrieving data from ${onText}...`);
|
|
36
|
+
if (!options['to-app-services']) logger.log(`Retrieving data from ${onText}...`);
|
|
37
37
|
let resolvedServices
|
|
38
38
|
|
|
39
39
|
const targets = options.to.split(/,/g);
|
|
@@ -94,7 +94,9 @@ async function bind(options) {
|
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
const isJavaProject = await checkIsJavaProject(cds.root);
|
|
97
|
-
|
|
97
|
+
if (!cds.cli.options['to-app-services']) {
|
|
98
|
+
logger.log(`${info('TIP:')} Run with cloud bindings: ${bold(runCmd(options.for, isJavaProject))}`);
|
|
99
|
+
}
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
function runCmd(profile, isJavaProject) {
|
|
@@ -2,8 +2,8 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../cds')
|
|
4
4
|
const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
|
|
5
|
-
const { hasJavaNature, getProperty, flatten, getDefaultModelOptions } = require('./util')
|
|
6
|
-
const { FILE_EXT_CDS, BUILD_TASK_JAVA_CF, BUILD_TASK_JAVA } = require("./constants")
|
|
5
|
+
const { hasJavaNature, getProperty, flatten, getDefaultModelOptions, hasOptionValue } = require('./util')
|
|
6
|
+
const { FILE_EXT_CDS, BUILD_TASK_JAVA_CF, BUILD_TASK_JAVA, CONTENT_WS } = require("./constants")
|
|
7
7
|
const term = require('../util/term')
|
|
8
8
|
const DEBUG = cds.debug('cli|build')
|
|
9
9
|
|
|
@@ -55,27 +55,24 @@ class BuildTaskFactory {
|
|
|
55
55
|
let tasks = BuildTaskFactory._getExistingTasks()
|
|
56
56
|
if (tasks.length === 0) {
|
|
57
57
|
tasks = await this.providerFactory.lookupTasks()
|
|
58
|
+
this._applyCliOptions(tasks)
|
|
58
59
|
} else {
|
|
60
|
+
this._applyCliOptions(tasks)
|
|
59
61
|
// 1. apply default values including task.for and task.use and ensure that for all tasks a provider exists - throwing error otherwise
|
|
60
62
|
await this.providerFactory.applyTaskDefaults(tasks)
|
|
61
63
|
// ensure that dependencies get wired up before filtering
|
|
62
64
|
await this.providerFactory.lookupTasks(tasks, true)
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
//
|
|
67
|
+
// 2. filters the list of build tasks
|
|
66
68
|
// Note: A new task might get created, e.g. 'cds build --for hana' will enforce a hana build even if sqlite has been configured
|
|
67
69
|
let existingTasks = tasks
|
|
68
|
-
tasks = this.
|
|
70
|
+
tasks = await this._filterTasksForCli(tasks)
|
|
69
71
|
if (tasks.length === 0) {
|
|
70
72
|
return tasks
|
|
71
73
|
}
|
|
72
|
-
// a new array is returned to indicate new build tasks have been created
|
|
73
|
-
if (tasks !== existingTasks) {
|
|
74
|
-
// a different task shall be executed
|
|
75
|
-
await this.providerFactory.applyTaskDefaults(tasks)
|
|
76
|
-
}
|
|
77
74
|
|
|
78
|
-
//
|
|
75
|
+
// 3. add dependencies
|
|
79
76
|
existingTasks = [...tasks]
|
|
80
77
|
await this.providerFactory.lookupTasks(tasks, true)
|
|
81
78
|
if (tasks.length > existingTasks.length) {
|
|
@@ -85,7 +82,7 @@ class BuildTaskFactory {
|
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
// obligatory task defaults shared by all tasks
|
|
88
|
-
BuildTaskFactory._applyCommonTaskDefaults(tasks)
|
|
85
|
+
await BuildTaskFactory._applyCommonTaskDefaults(tasks)
|
|
89
86
|
|
|
90
87
|
this._setDefaultBuildTargetFolder(tasks)
|
|
91
88
|
return tasks
|
|
@@ -95,11 +92,26 @@ class BuildTaskFactory {
|
|
|
95
92
|
return Array.isArray(getProperty(cds.env, 'build.tasks')) ? JSON.parse(JSON.stringify(cds.env.build.tasks)) : []
|
|
96
93
|
}
|
|
97
94
|
|
|
98
|
-
static _applyCommonTaskDefaults(tasks) {
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
static async _applyCommonTaskDefaults(tasks) {
|
|
96
|
+
// normalize model options
|
|
97
|
+
tasks.forEach(task => {
|
|
98
|
+
if (task.options?.model && !Array.isArray(task.options.model)) {
|
|
99
|
+
task.options.model = [task.options.model]
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
// there must be at least one task without model options
|
|
103
|
+
if (!tasks.some(task => !task.options?.model?.length > 0)) {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
const modelPaths = await getDefaultModelOptions()
|
|
107
|
+
let wsModelPaths
|
|
108
|
+
// calculate only once
|
|
109
|
+
if (tasks.some(task => hasOptionValue(task.options?.[CONTENT_WS], true))) {
|
|
110
|
+
wsModelPaths = await getDefaultModelOptions(true)
|
|
111
|
+
}
|
|
112
|
+
// set default model options
|
|
101
113
|
tasks.forEach(task => {
|
|
102
|
-
this._setTaskModelOptions(task, modelPaths)
|
|
114
|
+
this._setTaskModelOptions(task, hasOptionValue(task.options?.[CONTENT_WS], true) ? wsModelPaths : modelPaths)
|
|
103
115
|
if (!task.src) {
|
|
104
116
|
throw new Error(`Invalid build task definition - value of property 'src' is missing in [${task.for || task.use}].`)
|
|
105
117
|
}
|
|
@@ -134,7 +146,7 @@ class BuildTaskFactory {
|
|
|
134
146
|
return false
|
|
135
147
|
}
|
|
136
148
|
|
|
137
|
-
|
|
149
|
+
async _filterTasksForCli(tasks) {
|
|
138
150
|
const options = this.options
|
|
139
151
|
// filter tasks using either option for, use, src
|
|
140
152
|
let resultTasks = tasks.filter(task => {
|
|
@@ -149,6 +161,8 @@ class BuildTaskFactory {
|
|
|
149
161
|
task.src = options.src
|
|
150
162
|
}
|
|
151
163
|
resultTasks.push(task)
|
|
164
|
+
this._applyCliOptions(resultTasks)
|
|
165
|
+
await this.providerFactory.applyTaskDefaults(resultTasks)
|
|
152
166
|
}
|
|
153
167
|
} else if (resultTasks.length <= tasks.length) {
|
|
154
168
|
// return the same array as long as it contains a subset of the given tasks
|
|
@@ -156,7 +170,6 @@ class BuildTaskFactory {
|
|
|
156
170
|
resultTasks.forEach(task => tasks.push(task))
|
|
157
171
|
resultTasks = tasks
|
|
158
172
|
}
|
|
159
|
-
this._applyCliOptions(resultTasks)
|
|
160
173
|
return resultTasks
|
|
161
174
|
}
|
|
162
175
|
|
|
@@ -176,14 +189,12 @@ class BuildTaskFactory {
|
|
|
176
189
|
|
|
177
190
|
static _setTaskModelOptions(task, defaultModelPaths) {
|
|
178
191
|
task.options = task.options || {}
|
|
179
|
-
if (!task.options.model
|
|
192
|
+
if (!task.options.model?.length > 0) {
|
|
180
193
|
defaultModelPaths = new Set(defaultModelPaths)
|
|
181
194
|
if (task.src) {
|
|
182
195
|
defaultModelPaths.add(task.src)
|
|
183
196
|
}
|
|
184
197
|
task.options.model = [...defaultModelPaths]
|
|
185
|
-
} else if (!Array.isArray(task.options.model)) {
|
|
186
|
-
task.options.model = [task.options.model]
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
|
package/lib/build/constants.js
CHANGED
|
@@ -26,13 +26,14 @@ exports.FLAVOR_LOCALIZED_EDMX = "flavorLocalizedEdmx" // create locali
|
|
|
26
26
|
exports.CONTENT_EDMX = "contentEdmx" // create EDMX for required languages - ENABLED by default
|
|
27
27
|
exports.CONTENT_LOCALIZED_EDMX = "contentLocalizedEdmx" // create EDMX for required languages - ENABLED for Java by default
|
|
28
28
|
exports.CONTENT_PACKAGE_JSON = "contentPackageJson" // create package.json file if not existing, or modify existing package.json - ENABLED by default
|
|
29
|
-
exports.CONTENT_PACKAGELOCK_JSON = "contentPackageLockJson" // copy package-lock.json file
|
|
30
|
-
exports.CONTENT_HDBTABLEDATA = "contentHdbtabledata" // create .hdbtabledata files for .csv files if not existing - ENABLED by default
|
|
31
|
-
exports.CONTENT_NPMRC = "contentNpmrc" // copy .npmrc file
|
|
32
|
-
exports.CONTENT_CDSRC_JSON = "contentCdsrcJson" // copy .cdsrc.json file
|
|
33
|
-
exports.CONTENT_NODE_MODULES = "contentNodeModules" // copy node_modules folder
|
|
34
|
-
exports.CONTENT_ENV = "contentEnv" // copy .env file
|
|
35
|
-
exports.CONTENT_DEFAULT_ENV_JSON = "contentDefaultEnvJson" // copy default-env.json file
|
|
29
|
+
exports.CONTENT_PACKAGELOCK_JSON = "contentPackageLockJson" // copy package-lock.json file into deployment folder - ENABLED by default
|
|
30
|
+
exports.CONTENT_HDBTABLEDATA = "contentHdbtabledata" // create .hdbtabledata files for .csv files if not already existing - ENABLED by default
|
|
31
|
+
exports.CONTENT_NPMRC = "contentNpmrc" // copy .npmrc file into deployment folder - ENABLED by default
|
|
32
|
+
exports.CONTENT_CDSRC_JSON = "contentCdsrcJson" // copy .cdsrc.json file into deployment folder - ENABLED by default
|
|
33
|
+
exports.CONTENT_NODE_MODULES = "contentNodeModules" // copy node_modules folder into deployment folder - DISABLED by default
|
|
34
|
+
exports.CONTENT_ENV = "contentEnv" // copy .env file into deployment folder - DISABLED by default
|
|
35
|
+
exports.CONTENT_DEFAULT_ENV_JSON = "contentDefaultEnvJson" // copy default-env.json file into deployment folder - DISABLED by default
|
|
36
|
+
exports.CONTENT_WS = "ws" // determine model paths including submodules + CONTENT_SUBMODULES_HANA - DISABLED by default
|
|
36
37
|
|
|
37
38
|
exports.CSV_FILE_TARGET = "csvFileTarget" // target folder when copying CSV files to the deployment target folder ./db/src/gen/*, default is 'data'
|
|
38
39
|
exports.CSV_FILE_DETECTION = "csvFileDetection" // detect CSV files based on CDS model location - ENABLED by default
|
|
@@ -43,7 +44,7 @@ exports.IGNORE_DEFAULT_MODELS = "ignoreDefaultModels" // do not add de
|
|
|
43
44
|
|
|
44
45
|
exports.FOLDER_GEN = "gen"
|
|
45
46
|
exports.FILE_EXT_CDS = ".cds"
|
|
46
|
-
exports.MTX_SIDECAR_FOLDER = "mtx/sidecar"
|
|
47
|
+
exports.MTX_SIDECAR_FOLDER = "mtx/sidecar" // default name of the mtx sidecar folder
|
|
47
48
|
exports.DEFAULT_CSN_FILE_NAME = "csn.json"
|
|
48
49
|
// REVISIT: the models are not required if a custom server.js file is used for MTX bootstrap
|
|
49
50
|
exports.NODEJS_MODEL_EXCLUDE_LIST = ['@sap/cds/srv/mtx', '@sap/cds-mtxs/srv/bootstrap']
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
1
|
const path = require('path')
|
|
3
2
|
const cds = require('../../cds')
|
|
4
3
|
const { DEFAULT_CSN_FILE_NAME, OUTPUT_MODE, OUTPUT_MODE_RESULT } = require('../constants')
|
|
@@ -65,7 +64,7 @@ class FeatureToggleBuildPlugin extends InternalBuildPlugin {
|
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
async _resolveSourcePaths(csn) {
|
|
68
|
-
const regex = new RegExp(
|
|
67
|
+
const regex = new RegExp(this.ftsName + '[/|\\\\](?<ftName>[^/|\\\\]*)')
|
|
69
68
|
let paths = { base: [] }
|
|
70
69
|
|
|
71
70
|
// add ROOT source file paths for the base model
|
|
@@ -77,11 +76,6 @@ class FeatureToggleBuildPlugin extends InternalBuildPlugin {
|
|
|
77
76
|
return acc
|
|
78
77
|
}, [])
|
|
79
78
|
|
|
80
|
-
// keep existing behavior and return paths returned by cds.resolve if features are not supported by this project
|
|
81
|
-
if (!fs.existsSync(path.join(cds.root, this.ftsName))) {
|
|
82
|
-
return paths
|
|
83
|
-
}
|
|
84
|
-
|
|
85
79
|
// add source file paths for the features
|
|
86
80
|
paths.features = csn['$sources'].reduce((acc, file) => {
|
|
87
81
|
const match = file.match(regex)
|