@sap/cds-dk 7.5.1 → 7.6.1

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.
Files changed (74) hide show
  1. package/bin/add.js +28 -24
  2. package/bin/bind.js +59 -32
  3. package/bin/build.js +1 -1
  4. package/bin/cds.js +1 -1
  5. package/bin/env.js +1 -6
  6. package/bin/import.js +2 -2
  7. package/bin/init.js +7 -3
  8. package/bin/logout.js +2 -2
  9. package/bin/migrate.js +1 -1
  10. package/bin/version.js +1 -0
  11. package/bin/watch.js +8 -1
  12. package/lib/bind/bindingUtil.js +14 -20
  13. package/lib/bind/cfKeyProvider.js +8 -10
  14. package/lib/bind/index.js +4 -2
  15. package/lib/build/buildTaskFactory.js +31 -20
  16. package/lib/build/constants.js +9 -8
  17. package/lib/build/provider/featureToggleBuildPlugin.js +1 -7
  18. package/lib/build/provider/hana/index.js +44 -9
  19. package/lib/build/provider/internalBuildTaskProvider.js +7 -5
  20. package/lib/build/provider/java/index.js +0 -6
  21. package/lib/build/provider/mtx-sidecar/index.js +5 -0
  22. package/lib/build/provider/nodejs/index.js +32 -47
  23. package/lib/build/util.js +134 -33
  24. package/lib/deploy/to-hana/hana.js +47 -77
  25. package/lib/deploy/to-hana/hdiDeployUtil.js +15 -18
  26. package/lib/deploy/to-hana/mtaUtil.js +1 -1
  27. package/lib/env/schema.js +157 -17
  28. package/lib/env/schemas/cds-rc.js +118 -0
  29. package/lib/import/common.js +18 -23
  30. package/lib/import/odata/metadataconverter/MetadataConverter.js +12 -8
  31. package/lib/import/odata/v4parser.js +67 -12
  32. package/lib/init/constants.js +2 -4
  33. package/lib/init/merge.js +2 -1
  34. package/lib/init/template/application-logging/index.js +1 -2
  35. package/lib/init/template/approuter/files/mta.yaml.hbs +2 -0
  36. package/lib/init/template/approuter/files/package.json +1 -1
  37. package/lib/init/template/approuter/files/values.yaml.hbs +8 -1
  38. package/lib/init/template/hana/files/undeploy.json +3 -2
  39. package/lib/init/template/helm/files/chart/templates/NOTES.txt +2 -0
  40. package/lib/init/template/helm/files/chart/templates/_deployment_helpers.tpl +10 -2
  41. package/lib/init/template/helm/files/content-deployment/Chart.yaml +1 -1
  42. package/lib/init/template/helm/files/content-deployment/templates/_helpers.tpl +6 -5
  43. package/lib/init/template/helm/files/content-deployment/values.yaml +1 -1
  44. package/lib/init/template/helm/files/service-instance/Chart.yaml +1 -1
  45. package/lib/init/template/helm/files/service-instance/templates/_helpers.tpl +6 -5
  46. package/lib/init/template/helm/files/service-instance/values.yaml +1 -1
  47. package/lib/init/template/helm/files/web-application/Chart.yaml +1 -1
  48. package/lib/init/template/helm/files/web-application/templates/_api.tpl +6 -5
  49. package/lib/init/template/helm/files/web-application/values.yaml +1 -1
  50. package/lib/init/template/helm/index.js +1 -12
  51. package/lib/init/template/helm-unified-runtime/index.js +3 -2
  52. package/lib/init/template/html5-repo/files/values.yaml.hbs +9 -0
  53. package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +1 -2
  54. package/lib/init/template/multitenancy/index.js +3 -2
  55. package/lib/init/template/xsuaa/files/package.json.hbs +1 -2
  56. package/lib/lint/Linter.js +2 -2
  57. package/lib/lint/checks.js +0 -51
  58. package/lib/mtx/activate.js +1 -1
  59. package/lib/mtx/auth_manager.js +50 -57
  60. package/lib/mtx/download_legacy.js +1 -1
  61. package/lib/mtx/extend.js +2 -2
  62. package/lib/mtx/pull.js +1 -1
  63. package/lib/mtx/push.js +1 -1
  64. package/lib/mtx/settings_manager.js +90 -44
  65. package/lib/mtx/tenant_action.js +1 -1
  66. package/lib/mtx/util/dependencies.js +1 -1
  67. package/lib/mtx/util/legacy_ext.js +0 -1
  68. package/lib/mtx/util/logging.js +10 -8
  69. package/lib/util/axios.js +6 -19
  70. package/lib/util/cf.js +15 -10
  71. package/npm-shrinkwrap.json +104 -48
  72. package/package.json +1 -10
  73. package/lib/env/schemas/cds-rc.json +0 -101
  74. 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
- Adds one or more features to an existing project - grow as you go.
13
+ Add one or more features to an existing project - grow as you go.
14
14
 
15
- The following features are supported so far:
15
+ The following features can be added:
16
16
 
17
- *hana* - add support for SAP HANA
17
+ *hana* - add support for SAP HANA
18
18
 
19
- *sqlite* - add support for SQLite databases
19
+ *sqlite* - add support for SQLite
20
20
 
21
- *xsuaa* - add support for authentication via XSUAA
21
+ *postgres* - add support for PostgreSQL
22
22
 
23
- *multitenancy* - add support for multitenancy
23
+ *liquibase* - add support for Liquibase
24
24
 
25
- *toggles* - add support for feature toggles
25
+ *xsuaa* - add support for authentication via XSUAA
26
26
 
27
- *extensibility* - add support for extensibility
27
+ *multitenancy* - add support for multitenancy
28
28
 
29
- *approuter* - add support for application routing
29
+ *toggles* - add support for feature toggles
30
30
 
31
- *local-messaging* - add support for local messaging
31
+ *extensibility* - add support for extensibility
32
32
 
33
- *file-based-messaging* - add support for file-based messaging
33
+ *approuter* - add support for application routing
34
34
 
35
- *enterprise-messaging* - add support for SAP Event Mesh
35
+ *local-messaging* - add support for local messaging
36
36
 
37
- *redis-messaging* - add support for Redis messaging
37
+ *file-based-messaging* - add support for file-based messaging
38
38
 
39
- *kibana* - add support for Kibana formatting
39
+ *enterprise-messaging* - add support for SAP Event Mesh
40
40
 
41
- *mta* - add support for MTA-based deployment
41
+ *redis-messaging* - add support for Redis messaging
42
42
 
43
- *cf-manifest* - add support for CF-native deployment
43
+ *kibana* - add support for Kibana formatting
44
44
 
45
- *helm* - add support for Helm-based Kyma deployment
45
+ *mta* - add support for MTA-based deployment
46
46
 
47
- *html5-repo* - add support for the HTML5 repository
47
+ *cf-manifest* - add support for CF-native deployment
48
48
 
49
- *pipeline* - add files for CI/CD pipeline integration
49
+ *helm* - add support for Helm-based Kyma deployment
50
50
 
51
- *tiny-sample* - add minimal sample files
51
+ *html5-repo* - add support for the HTML5 repository
52
52
 
53
- *sample* - add sample files including Fiori UI
53
+ *pipeline* - add files for CI/CD pipeline integration
54
54
 
55
- *data* - add CSV headers for modeled entities
55
+ *tiny-sample* - add minimal sample files
56
56
 
57
- *typer* - add type generation for CDS models
57
+ *sample* - add sample files including Fiori UI
58
58
 
59
- *lint* - add support for CDS Lint
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
- bind to a given Cloud Foundry instance, Kubernetes service binding or Kubernetes secret.
24
+
25
+ Bind to a given Cloud Foundry instance, Kubernetes service binding or Kubernetes secret.
25
26
 
26
27
  *-4 | --for* <profile>
27
- store binding information under <profile> in *.cdsrc-private.json*. Default *hybrid* is used
28
- if '--for' is not specified
28
+
29
+ Profile to store binding information. Defaults to *hybrid*.
29
30
 
30
31
  *-n | --on* cf | k8s
31
- bind to service on Cloud Foundry or Kubernetes, defaults to Cloud Foundry
32
+
33
+ Target platform (Cloud Foundry or Kubernetes) to bind to. Defaults to *cf*.
32
34
 
33
35
  *-k | --kind* <kind>
34
- the kind of service
36
+
37
+ Kind of the service.
35
38
 
36
39
  *-o | --output-file* <path>
37
- save bindings to the given *.cdsrc.json* or *package.json* file. Default is *.cdsrc-private.json*.
38
- If *path* is a directory, then it will save it to the *.cdsrc.json* file in that directory.
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 my-hdi-container
43
- cds bind --to my-hdi-container,my-xsuaa
44
- cds bind uaa --to my-xsuaa:my-xsuaa-key --kind xsuaa --for myprofile
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 my-hdi-container --output-file .
47
- cds bind --to my-hdi-container --output-file package.json
59
+ cds bind --to bookshop-db --output-file .
60
+ cds bind --to bookshop-db --output-file package.json
48
61
 
49
- cds bind --to my-hdi-container --on k8s
50
- cds bind --to my-hdi-container --for my-profile
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
- if (!options.to) {
76
- throw `Use option --to or -2 to specify the target instance, e.g. cds bind --to myInstance:myService`;
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 (args.length > 1) {
80
- throw `Too many arguments: Please specify only one or no service.`;
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
- options.serviceArg = args[0]
84
- options.targets = options.to.split(/,/g);
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
- if (options.targets.length >= 2 && options.serviceArg) {
87
- throw `Service argument cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the service argument.`;
88
- }
112
+ options.serviceArg = args[0]
113
+ options.targets = options.to.split(/,/g);
89
114
 
90
- if (options.targets.length >= 2 && options.kind) {
91
- throw `The option '--kind' cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the '--kind' option.`;
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
- await bind({
95
- ...options,
96
- outputFile: options['output-file']
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
- if (options["resolve-bindings"]) {
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/import.js CHANGED
@@ -87,7 +87,7 @@ async function _import(file, options = {}) {
87
87
  if (!file) return this.help('import');
88
88
  // process options
89
89
  await common.processOptions(options, apiOptions);
90
- const [srcFilePath, destFilePath] = await common.preProcess(file, options, cwd);
90
+ const srcFilePath = await common.preProcess(file, options, cwd);
91
91
 
92
92
  // process - csn generation
93
93
  // if --from option is given, call api directly accordingly
@@ -102,5 +102,5 @@ async function _import(file, options = {}) {
102
102
  options.inputFileKind = apiOptions.odataVersion ? apiOptions.odataVersion : apiOptions.inputFileKind;
103
103
 
104
104
  // postprocess
105
- return await common.postProcess(destFilePath, options, csn, cwd);
105
+ return await common.postProcess(file, options, csn, cwd);
106
106
  }
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 databases
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
- *redis-messaging* - add support for Redis messaging
51
+ *file-based-messaging* - add support for file-based messaging
48
52
 
49
- *kibana* - add support for Kibana formatting
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. Ignores any other
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
@@ -38,7 +38,7 @@ module.exports = Object.assign(migrate, {
38
38
 
39
39
  Do a dry-run only. Only run a verification of the extension migration.
40
40
 
41
- *--skip-verification
41
+ *--skip-verification*
42
42
 
43
43
  Skip verification step. Does not check for potential deployment
44
44
  differences.
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(`(_out\\${sep}|node_modules\\${sep}|@cds-models\\${sep}|@types\\${sep}|app(\\${sep}.+)?\\${sep}((webapp|dist|target)\\${sep}|\\.cds-services\\.json$|tsconfig\\.json$|.*\\.tsbuildinfo$))`)
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'],
@@ -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
- 'xsuaa', // REVISIT: remove with ^8
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.keys(requires)) {
76
- const requireService = requires[kind];
77
- findKindFor(kind, requireService);
78
- findKindFor(kind, { kind });
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 => PreferredKinds.indexOf(kind) >= 0);
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
- let keyObj
97
- try {
98
- keyObj = await this.getKey({ names: key, service_instance_guids: instanceObj.guid });
99
- } catch (error) {
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: keyCredentialsObj.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
- logger.log(`${info('TIP:')} Run with cloud bindings: ${bold(runCmd(options.for, isJavaProject))}`);
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
- // 3. filters the list of build tasks and adapts according to given CLI options
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._applyCliOptionsFilter(tasks)
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
- // 2. add dependencies
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
- const modelPaths = getDefaultModelOptions()
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
- _applyCliOptionsFilter(tasks) {
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 || Array.isArray(task.options.model) && task.options.model.length === 0) {
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
 
@@ -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 if existing into deployment folder - ENABLED by default
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 if existing into deployment folder - ENABLED by default
32
- exports.CONTENT_CDSRC_JSON = "contentCdsrcJson" // copy .cdsrc.json file if existing into deployment folder - ENABLED by default
33
- exports.CONTENT_NODE_MODULES = "contentNodeModules" // copy node_modules folder if existing into deployment folder - DISABLED by default
34
- exports.CONTENT_ENV = "contentEnv" // copy .env file if existing into deployment folder - DISABLED by default
35
- exports.CONTENT_DEFAULT_ENV_JSON = "contentDefaultEnvJson" // copy default-env.json file if existing into deployment folder - DISABLED by default
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" // default name of the mtx sidecar folder
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']