@sap/cds-dk 7.3.1 → 7.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/bin/add.js +2 -0
  2. package/bin/build.js +2 -1
  3. package/bin/cds.js +1 -1
  4. package/bin/compile/index.js +11 -0
  5. package/bin/init.js +1 -1
  6. package/lib/build/provider/edmxBuildPlugin.js +7 -3
  7. package/lib/build/provider/featureToggleBuildPlugin.js +2 -3
  8. package/lib/build/provider/nodejs/index.js +3 -2
  9. package/lib/client/base_command.js +8 -18
  10. package/lib/client/download_legacy.js +0 -3
  11. package/lib/client/params.js +5 -4
  12. package/lib/client/settings_manager.js +22 -21
  13. package/lib/deploy/to-hana/hana.js +53 -35
  14. package/lib/index.js +1 -1
  15. package/lib/init/constants.js +2 -1
  16. package/lib/init/template/enterprise-messaging/files/event-mesh.json.hbs +1 -1
  17. package/lib/init/template/enterprise-messaging/index.js +1 -1
  18. package/lib/init/template/enterprise-messaging-shared/files/event-mesh.json.hbs +1 -1
  19. package/lib/init/template/enterprise-messaging-shared/index.js +19 -5
  20. package/lib/init/template/helm/index.js +1 -1
  21. package/lib/init/template/local-messaging/files/package.json.hbs +15 -0
  22. package/lib/init/template/local-messaging/index.js +25 -0
  23. package/lib/init/template/nodejs/files/.gitignore.hbs +3 -0
  24. package/lib/init/template/notifications/files/package.json.hbs +1 -10
  25. package/lib/init/template/notifications/index.js +7 -16
  26. package/lib/init/template/typer/files/package.json +1 -1
  27. package/lib/init/util/projectReader.js +1 -0
  28. package/npm-shrinkwrap.json +82 -42
  29. package/package.json +1 -1
  30. package/lib/init/template/notifications/files/notificationtypes.json.hbs +0 -16
package/bin/add.js CHANGED
@@ -27,6 +27,8 @@ module.exports = Object.assign(add, {
27
27
 
28
28
  *approuter* - add support for application routing
29
29
 
30
+ *local-messaging* - add support for local messaging
31
+
30
32
  *file-based-messaging* - add support for file-based messaging
31
33
 
32
34
  *enterprise-messaging* - add support for SAP Event Mesh
package/bin/build.js CHANGED
@@ -88,8 +88,9 @@ module.exports = Object.assign(build, {
88
88
 
89
89
  async function build([project], options = {}) {
90
90
  const path = require('path')
91
+
91
92
  const cds = require('../lib/cds')
92
-
93
+
93
94
  // plugins are loaded based on cds.root path
94
95
  cds.root = path.resolve(process.cwd(), project || options.project || '.')
95
96
 
package/bin/cds.js CHANGED
@@ -30,7 +30,7 @@ const cli = { //NOSONAR
30
30
  if (cmd in this.Shortcuts) cmd = process.argv[2] = this.Shortcuts[cmd]
31
31
  if (argv.some(a => this.Shortcuts[a]==='help')) return this.help (cmd)
32
32
 
33
- const cds = require('../lib/cds')
33
+ const cds = require('../lib') // make sure to load cds-dk API for plugins
34
34
  DEBUG?.(`[cds] - @sap/cds ${cds.version} loaded: ${cds.home}`)
35
35
 
36
36
  try {
@@ -53,6 +53,17 @@ module.exports = Object.assign ( compile, {
53
53
 
54
54
  - odata
55
55
  - sql
56
+
57
+ *--dialect* <dialect>
58
+
59
+ Needs option *--to*.
60
+ Specify the dialect in combination with *--to sql*.
61
+ Currently supported:
62
+
63
+ - sqlite
64
+ - h2
65
+ - postgres
66
+ - hana
56
67
 
57
68
  *-s* | *--service* <name> | all
58
69
 
package/bin/init.js CHANGED
@@ -40,7 +40,7 @@ module.exports = Object.assign(init, {
40
40
 
41
41
  *approuter* - add support for application routing
42
42
 
43
- *file-based-messaging* - add support for file-based messaging
43
+ *local-messaging* - add support for local messaging
44
44
 
45
45
  *enterprise-messaging* - add support for SAP Event Mesh
46
46
 
@@ -51,9 +51,13 @@ class EdmxBuildPlugin extends FeatureToggleBuildPlugin {
51
51
  }
52
52
 
53
53
  _isOdataProtocol(srv) {
54
- let protocols = cds.service.protocols.protocol4(srv)
55
- if (typeof protocols === "string") {
56
- protocols = [protocols]
54
+ let protocols = cds.service.protocols4?.(srv)
55
+ if (!protocols) {
56
+ // compatibility with @sap/cds < 7.3.0
57
+ protocols = cds.service.protocols.protocol4(srv)
58
+ if (typeof protocols === "string") {
59
+ protocols = [protocols]
60
+ }
57
61
  }
58
62
  return protocols.some(p => p && p.startsWith('odata'))
59
63
  }
@@ -124,9 +124,8 @@ class FeatureToggleBuildPlugin extends InternalBuildPlugin {
124
124
 
125
125
  _validateFeature(ftCsn, baseCsn) {
126
126
  // features must not have other dependencies than base model dependencies - cross feature dependencies are not supported
127
- // do not pass options.messages in order to avoid duplicate compiler messages
128
- // version 2.13.9 of compileSources does not read the 'requires' definition of parsed CSNs
129
- cds.compiler.compileSources({ [ftCsn.requires[0]]: baseCsn, 'feature.csn': ftCsn }, this.options())
127
+ // assuming only core compiler options are relevant for validation scenario
128
+ cds.compiler.compileSources({ [ftCsn.requires[0]]: baseCsn, 'feature.csn': ftCsn }, { ...super.options(), ...cds.env.cdsc ?? {}})
130
129
  }
131
130
  }
132
131
 
@@ -44,9 +44,10 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
44
44
  await this.collectAllLanguageBundles(dictionary, sources, destSrv, destRoot)
45
45
 
46
46
  if (!this.hasBuildOption(CONTENT_EDMX, false)) {
47
- //REVISIT: inferred model expected by cds.compile.to.edmx()
48
47
  const compileOptions = { [FLAVOR_LOCALIZED_EDMX]: this.hasBuildOption(FLAVOR_LOCALIZED_EDMX, true) }
49
- const baseModel = cds.compiler.compileSources({ 'base.json': dictionary.base }, { messages: this.messages })
48
+ // inferred flavor is required by edmx compiler backend
49
+ // using cds.compile instead of cds.compiler.compileSources ensures that cds.env options are correctly read
50
+ const baseModel = dictionary.base.meta.flavor !== 'inferred' ? await cds.compile(sources.base, super.options(), 'inferred') : dictionary.base
50
51
  await this.compileToEdmx(baseModel, path.join(this.destSrv, 'odata', cds.env.odata.version), compileOptions)
51
52
  }
52
53
 
@@ -38,27 +38,17 @@ module.exports = class BaseCommand {
38
38
  }
39
39
  }
40
40
 
41
- static concatUrls(base, ...paths) {
42
- function trimBeginSlash(str) {
43
- return str.replace(/^\//, '');
44
- }
45
- function trimEndSlash(str) {
46
- return str.replace(/\/$/, '');
47
- }
48
- function trimSlashes(str) {
49
- return trimBeginSlash(trimEndSlash(str));
50
- }
51
- const concatenated = new URL(base);
52
- concatenated.pathname = trimEndSlash(concatenated.pathname) + '/' +
53
- paths.map((p, i) => i < paths.length - 1 ? trimSlashes(p) : trimBeginSlash(p)).join('/');
54
- return concatenated.toString();
41
+ static concatUrls(...parts) {
42
+ return parts
43
+ .map((p, i) => i === 0
44
+ ? p.replace(/\/$/ /*end slash*/, '')
45
+ : i === parts.length - 1
46
+ ? p.replace(/^\// /*begin slash*/, '')
47
+ : p.replace(/^\/|\/$/g /*both*/, ''))
48
+ .join('/');
55
49
  }
56
50
 
57
51
  static getMtxApiUrl(url, action) {
58
52
  return BaseCommand.concatUrls(url, MTX_URL_PATH_PREFIX, action);
59
53
  }
60
-
61
- static getMtxApiUrlSync(url, action) {
62
- return BaseCommand.concatUrls(url, MTX_URL_PATH_PREFIX, action);
63
- }
64
54
  }
@@ -1,6 +1,3 @@
1
- const cds = require ('../cds')
2
- const { tar } = cds.utils;
3
-
4
1
  const fs = require('fs');
5
2
  const { join } = require('path');
6
3
  const axios = require('axios');
@@ -170,7 +170,7 @@ class BasicParams {
170
170
  this.clearOtherTokenStorage = new Param('clearOtherTokenStorage', false, { internal: true });
171
171
 
172
172
  // - persisted
173
- this.appUrl = new Param('appUrl', '', { persist: Persistence.setting });
173
+ this.appUrl = new Param('appUrl', '', { persist: Persistence.setting }); // any trailing slash (/) is removed
174
174
  this.url = this.appUrl.newAlias('url');
175
175
  this.from = this.appUrl.newAlias('from');
176
176
  this.to = this.appUrl.newAlias('to');
@@ -276,6 +276,7 @@ class ParamCollection {
276
276
 
277
277
  /**
278
278
  * Get the name of a main param (as opposed to an alias).
279
+ * Throws an error if the param is not part of this collection.
279
280
  * @param name the param in question
280
281
  */
281
282
  static mainName(name) {
@@ -287,7 +288,7 @@ class ParamCollection {
287
288
  }
288
289
 
289
290
  /**
290
- * Whether this includes the given param.
291
+ * Return whether the given param is included in this collection.
291
292
  * @param name the param in question
292
293
  */
293
294
  has(name) {
@@ -295,7 +296,7 @@ class ParamCollection {
295
296
  }
296
297
 
297
298
  /**
298
- * Return the value of the given param.
299
+ * Return the value of the given param or `undefined` if not part of this collection.
299
300
  * @param name the param in question
300
301
  */
301
302
  get(name) {
@@ -304,7 +305,7 @@ class ParamCollection {
304
305
  }
305
306
 
306
307
  /**
307
- * Return the `Param` object for the given param.
308
+ * Return the `Param` object for the given param or `undefined` if not part of this collection.
308
309
  * @param name the param in question
309
310
  */
310
311
  getParam(name) {
@@ -96,19 +96,17 @@ async function getTokenBaseUrl(params, renewUrl) {
96
96
  if (!params.has('appUrl')) {
97
97
  throw 'Failed to determine token URL: app URL not given';
98
98
  }
99
- const baseUrl = new URL(params.get('appUrl'));
100
- const cleanPathname = pathname => baseUrl.pathname.replace(/\/?$/, pathname);
101
- const getBaseUrl = pathname => {
102
- const url = new URL(baseUrl.toString());
103
- url.pathname = cleanPathname(pathname);
104
- return url;
99
+ const appUrlWith = pathname => {
100
+ const url = new URL(params.get('appUrl'));
101
+ url.pathname = url.pathname.replace(/\/*$/, pathname);
102
+ return url.toString();
105
103
  };
106
104
 
107
105
  let existingPath;
108
106
  const oauthPaths = [OAUTH_PATH_STREAMLINED_MTX];
109
107
  for (const path of oauthPaths) {
110
108
  try {
111
- await axios.head(getBaseUrl(path).toString());
109
+ await axios.head(appUrlWith(path));
112
110
  existingPath = path;
113
111
  break;
114
112
  } catch (error) {
@@ -119,7 +117,7 @@ async function getTokenBaseUrl(params, renewUrl) {
119
117
  }
120
118
  }
121
119
  existingPath = existingPath ?? OAUTH_PATH_OLD_MTX; // REVISIT can this just be included in the array?
122
- return getBaseUrl(existingPath).toString();
120
+ return appUrlWith(existingPath);
123
121
  }
124
122
 
125
123
  function getKeyringAccountName(params) {
@@ -194,7 +192,6 @@ class SettingsManager {
194
192
 
195
193
  const loadedSettings = await this._loadFromFile(projectFolder);
196
194
  DEBUG?.(`Loaded project settings for ${params.get('projectFolder')}: ${loadedSettings.format()}`);
197
- const loadedAppUrl = loadedSettings.get('appUrl');
198
195
 
199
196
  if (params.has('passcode') && loadedSettings.has('username')) {
200
197
  console.log(`Unsetting username${(loadedSettings.has('isEmptyPassword') ? ' and empty-password hint' : '')}`);
@@ -207,14 +204,14 @@ class SettingsManager {
207
204
  if (params.has('username')) {
208
205
  params.set('skipToken', true);
209
206
  }
210
- await this.updateUrls(params, logout, loadedAppUrl);
207
+ await this.updateUrls(params, logout, loadedSettings);
211
208
  await this.setKeytar(params, logout);
212
209
  await this.addAuth(params, logout);
213
210
  DEBUG?.(`Effective project settings: ${params.format()}`);
214
211
  }
215
212
 
216
- static async updateUrls(params, logout, loadedAppUrl) {
217
- async function addAppUrl() {
213
+ static async updateUrls(params, logout, loadedSettings) {
214
+ async function updateAppUrl() {
218
215
  if (!logout && !params.has('appUrl')) {
219
216
  // Get appUrl from CF
220
217
  DEBUG?.('App URL not given');
@@ -240,19 +237,23 @@ class SettingsManager {
240
237
  DEBUG?.(`Added schema to app URL: ${appUrl}`);
241
238
  }
242
239
  params.set('appUrl', appUrl);
240
+ if (params.get('appUrl') !== loadedSettings.get('appUrl')) {
241
+ DEBUG?.(`Updated app URL from '${loadedSettings.get('appUrl')}' (loaded) to '${appUrl}'`);
242
+ }
243
243
  }
244
- async function renewTokenUrl() {
245
- const renewUrl = params.get('appUrl') !== loadedAppUrl;
246
- if (!params.get('tokenUrl') || renewUrl) {
247
- params.set('tokenUrl', await getTokenBaseUrl(params, renewUrl));
244
+ async function updateTokenUrl() {
245
+ const tokenUrl = params.get('tokenUrl');
246
+ const renewUrl = !logout && !params.get('skipToken')
247
+ && (!tokenUrl || tokenUrl.includes('//-/cds') || params.get('appUrl') !== loadedSettings.get('appUrl'));
248
+ if (renewUrl) {
249
+ const tokenUrl = await getTokenBaseUrl(params, renewUrl);
250
+ params.set('tokenUrl', tokenUrl);
251
+ DEBUG?.(`Updated token URL from '${loadedSettings.get('tokenUrl')}' (loaded) to '${tokenUrl}'`);
248
252
  }
249
253
  }
250
254
 
251
- await addAppUrl();
252
-
253
- if (!logout && !params.get('skipToken')) {
254
- await renewTokenUrl();
255
- }
255
+ await updateAppUrl();
256
+ await updateTokenUrl();
256
257
  }
257
258
 
258
259
  static async setKeytar(params, logout = false) {
@@ -45,13 +45,16 @@ class HanaDeployer {
45
45
  // arg object
46
46
  // async deploy(model, serviceName, tunnelAddress, buildTaskOptions, vcapFile, undeployWhitelist, hdiOptions, bindCallback) { // NOSONAR
47
47
  async deploy(options = {}) { // NOSONAR
48
- let { model, serviceName, tunnelAddress, vcapFile, undeployWhitelist, hdiOptions } = options;
48
+ let { model, serviceName, tunnelAddress, vcapFile, undeployWhitelist, hdiOptions, dry } = options;
49
49
 
50
50
  if (model) {
51
51
  throw 'Specifying a model for hana deployment is not supported.';
52
52
  }
53
53
 
54
- console.log(`${bold('Starting deploy to SAP HANA ...')}`);
54
+ if (dry) {
55
+ console.log('-- running in dry mode ---');
56
+ }
57
+
55
58
  if (vcapFile) {
56
59
  console.log(`Using VCAP_SERVICES from file ${vcapFile} (beta feature).`);
57
60
  }
@@ -66,51 +69,66 @@ class HanaDeployer {
66
69
  globalVcapEnv.TARGET_CONTAINER = process.env.TARGET_CONTAINER;
67
70
  }
68
71
 
69
- for (const buildResult of buildResults) {
70
- let vcapEnv = globalVcapEnv;
71
- let serviceKeyName;
72
- const currentModelFolder = buildResult.task.dest;
73
-
74
- if (undeployWhitelist) {
75
- console.log('Writing undeploy.json');
76
- await fs.write(path.join(currentModelFolder, 'undeploy.json'), JSON.stringify(undeployWhitelist, null, 2));
72
+ if (dry) {
73
+ for (const buildResult of buildResults) {
74
+ const model = await cds.load(buildResult.task.src);
75
+ const data = cds.compile.to.hdbtable(model);
76
+ for (const [src, { file }] of data) {
77
+ console.log(`-- ${file}`);
78
+ console.log(src);
79
+ console.log();
80
+ }
77
81
  }
82
+ } else {
83
+ for (const buildResult of buildResults) {
84
+ let vcapEnv = globalVcapEnv;
85
+ let serviceKeyName;
86
+ const currentModelFolder = buildResult.task.dest;
87
+
88
+ if (undeployWhitelist) {
89
+ console.log('Writing undeploy.json');
90
+ await fs.write(path.join(currentModelFolder, 'undeploy.json'), JSON.stringify(undeployWhitelist, null, 2));
91
+ }
78
92
 
79
- const hasVCAPEnv = Object.keys(vcapEnv).length > 0;
80
- if (!serviceName && hasVCAPEnv) {
81
- await fs.mkdir(currentModelFolder, { recursive: true });
82
- } else {
83
- const { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey } =
84
- await this._getOrCreateCFService(projectPath, currentModelFolder, serviceName, tunnelAddress);
85
- serviceKeyName = cfServiceInstanceKeyName;
86
- serviceName = serviceName || cfServiceInstanceName;
93
+ const hasVCAPEnv = Object.keys(vcapEnv).length > 0;
94
+ if (!serviceName && hasVCAPEnv) {
95
+ await fs.mkdir(currentModelFolder, { recursive: true });
96
+ } else {
97
+ const { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey } =
98
+ await this._getOrCreateCFService(projectPath, currentModelFolder, serviceName, tunnelAddress);
99
+ serviceKeyName = cfServiceInstanceKeyName;
100
+ serviceName = serviceName || cfServiceInstanceName;
87
101
 
88
- vcapEnv = this._getVCAPServicesEntry(cfServiceInstanceName, serviceKey);
102
+ vcapEnv = this._getVCAPServicesEntry(cfServiceInstanceName, serviceKey);
89
103
 
90
- if (options.storeCredentials) {
91
- await this._addInstanceToDefaultEnvJson([currentModelFolder, projectPath], cfServiceInstanceName, serviceKey);
104
+ if (options.storeCredentials) {
105
+ await this._addInstanceToDefaultEnvJson([currentModelFolder, projectPath], cfServiceInstanceName, serviceKey);
106
+ }
92
107
  }
93
- }
94
108
 
95
- hdiOptions = hdiOptions || {}
96
- await hdiDeployUtil.deploy(currentModelFolder, vcapEnv, hdiOptions);
109
+ console.log(`${bold('Starting deployment to SAP HANA ...')}`);
110
+
111
+ hdiOptions = hdiOptions || {}
112
+ await hdiDeployUtil.deploy(currentModelFolder, vcapEnv, hdiOptions);
97
113
 
98
- if (!hasVCAPEnv) {
99
- const bindOptions = {
100
- ...options,
101
- to: `${serviceName}:${serviceKeyName}`,
102
- for: options.for,
103
- kind: buildResult.task.for
114
+ if (!hasVCAPEnv) {
115
+ const bindOptions = {
116
+ ...options,
117
+ to: `${serviceName}:${serviceKeyName}`,
118
+ for: options.for,
119
+ kind: buildResult.task.for
120
+ }
121
+ await bind(bindOptions);
104
122
  }
105
- await bind(bindOptions);
106
123
  }
107
- }
108
124
 
109
- if (options.storeCredentials) {
110
- await gitUtil.ensureFileIsGitignored('default-env.json', projectPath);
125
+ if (options.storeCredentials) {
126
+ await gitUtil.ensureFileIsGitignored('default-env.json', projectPath);
127
+ }
128
+
129
+ console.log(`If not already done, use ${info('cds add hana')} to configure the project for SAP HANA.\n`);
111
130
  }
112
131
 
113
- console.log(`If not already done, use ${info('cds add hana')} to configure the project for SAP HANA.\n`);
114
132
  console.log(`Done.`);
115
133
 
116
134
  return { buildResults };
package/lib/index.js CHANGED
@@ -21,7 +21,7 @@ if (cds.compile.to.constructor.name === 'Object') { // not a class as in cds 7
21
21
 
22
22
  cds.schema = cds.schema || {} // backward compatibility
23
23
  cds.extend (cds.schema) .with ( {
24
- overlay4: require('./env/schema')
24
+ get overlay4() { return super.overlay4 = require('./env/schema') }
25
25
  })
26
26
 
27
27
  // set build API, potentially removing the old API facade from sap/cds 7
@@ -27,9 +27,10 @@ module.exports = {
27
27
  POSTGRES: 'postgres',
28
28
  SQLITE: 'sqlite',
29
29
  H2: 'h2',
30
+ LOCAL_MESSAGING: 'local-messaging',
31
+ FILE_BASED_MESSAGING: 'file-based-messaging',
30
32
  ENTERPRISE_MESSAGING: 'enterprise-messaging',
31
33
  ENTERPRISE_MESSAGING_SHARED: 'enterprise-messaging-shared',
32
- FILE_BASED_MESSAGING: 'file-based-messaging',
33
34
  REDIS_MESSAGING: 'redis-messaging',
34
35
  APPROUTER: 'approuter',
35
36
  DESTINATION: 'destination',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "emname": "{{appName}}-emname",
3
3
  "version": "1.1.0",
4
- "namespace": "default/{{appName}}/1",
4
+ "namespace": "default/{{cleanedAppName}}/1",
5
5
  "options": {
6
6
  "management": true,
7
7
  "messagingrest": true,
@@ -23,6 +23,7 @@ module.exports = class EnterpriseMessagingTemplate extends require('../templateB
23
23
  const project = await readProject()
24
24
  const { configFile } = project
25
25
  await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project)
26
+ await mergeJSON('event-mesh.json', join(__dirname, 'files', 'event-mesh.json.hbs'), project)
26
27
  }
27
28
 
28
29
  async runDependentMerging(context = {}) {
@@ -30,7 +31,6 @@ module.exports = class EnterpriseMessagingTemplate extends require('../templateB
30
31
  const { hasXsuaa, hasHelm, hasMta, isNodejs, srvPath, appName } = project
31
32
 
32
33
  if (hasMta) {
33
- await mergeJSON('event-mesh.json', join(__dirname, 'files', 'event-mesh.json.hbs'), project)
34
34
  const srv = (isNodejs ? srvNode4 : srvJava4)(srvPath)
35
35
  await mergeYAML(
36
36
  'mta.yaml',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "emname": "{{appName}}-emname",
3
3
  "version": "1.1.0",
4
- "namespace": "default/{{appName}}/1",
4
+ "namespace": "default/{{cleanedAppName}}/1",
5
5
  "options": {
6
6
  "management": true,
7
7
  "messagingrest": true,
@@ -3,14 +3,14 @@ const cds = require('../../../cds')
3
3
  const { read } = cds.utils
4
4
  const { readProject } = require('../../util/projectReader')
5
5
  const { mergeJSON, mergeYAML } = require('../../util/merge')
6
+ const { parseMd5File, writeMd5File } = require('../../util/md5')
6
7
  const { srvNode4, srvJava4, enterpriseMessaging } = require('../_merging/registry-mta')
7
8
 
8
9
  module.exports = class EnterpriseMessagingSharedTemplate extends require('../templateBase') {
9
10
 
10
11
  async canRun() {
11
- const { hasMta, hasHelm, isJava } = await readProject()
12
- if (isJava) throw `'cds add enterprise-messaging-shared' is not available for Java yet`
13
- if (hasHelm && !hasMta) throw `'cds add enterprise-messaging-shared' is not available for Kyma yet`
12
+ const { isJava } = await readProject()
13
+ if (isJava) throw `'cds add enterprise-messaging-shared' is not available for Java yet`
14
14
  return true
15
15
  }
16
16
 
@@ -26,9 +26,9 @@ module.exports = class EnterpriseMessagingSharedTemplate extends require('../tem
26
26
  await mergeJSON('event-mesh.json', join(__dirname, 'files', 'event-mesh.json.hbs'), project)
27
27
  }
28
28
 
29
- async runDependentMerging() {
29
+ async runDependentMerging(context = {}) {
30
30
  const project = await readProject()
31
- const { hasMta, isNodejs, srvPath } = project
31
+ const { hasMta, hasHelm, isNodejs, srvPath } = project
32
32
 
33
33
  if (hasMta) {
34
34
  const srv = (isNodejs ? srvNode4 : srvJava4)(srvPath)
@@ -45,5 +45,19 @@ module.exports = class EnterpriseMessagingSharedTemplate extends require('../tem
45
45
  }
46
46
  )
47
47
  }
48
+
49
+ if (hasHelm) {
50
+ let isIndependentCommand = false
51
+ if (Object.keys(context).length == 0){
52
+ isIndependentCommand = true
53
+ context.oldTrackingData = context.newTrackingData = await parseMd5File(join('chart', '.cds-add-helm-files.md5'))
54
+ }
55
+ await mergeYAML(join('chart', 'values.yaml'), join(__dirname, 'files', 'values.yaml'))
56
+ const HelmTemplate = require(`../helm`);
57
+ const helmTemplate = new HelmTemplate(context.oldTrackingData, context.newTrackingData);
58
+ isIndependentCommand = isIndependentCommand | await helmTemplate.addSubChart('service-instance');
59
+ await helmTemplate.addDependency('service-instance', 'event-mesh');
60
+ if (isIndependentCommand) await writeMd5File(join('chart', '.cds-add-helm-files.md5'), context.newTrackingData)
61
+ }
48
62
  }
49
63
  }
@@ -14,7 +14,7 @@ module.exports = class HelmTemplate extends require('../templateBase') {
14
14
  }
15
15
 
16
16
  getRelatedFacets() {
17
- return ['hana', 'xsuaa', 'enterprise-messaging', 'destination' , 'multitenancy', 'extensibility', 'approuter', 'connectivity']
17
+ return ['hana', 'xsuaa', 'enterprise-messaging', 'enterprise-messaging-shared', 'destination' , 'multitenancy', 'extensibility', 'approuter', 'connectivity']
18
18
  }
19
19
 
20
20
  static hasFacet() {
@@ -0,0 +1,15 @@
1
+ {
2
+ "cds": {
3
+ "requires": {
4
+ {{#profile}}
5
+ "[{{profile}}]": {
6
+ {{/profile}}
7
+ "messaging": {
8
+ "kind": "local-messaging"
9
+ }
10
+ {{#profile}}
11
+ }
12
+ {{/profile}}
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,25 @@
1
+ const { join } = require('path')
2
+ const cds = require('../../../cds')
3
+ const { read } = cds.utils
4
+ const { readProject } = require('../../util/projectReader')
5
+ const { mergeJSON } = require('../../util/merge')
6
+
7
+ module.exports = class LocalMessagingTemplate extends require('../templateBase') {
8
+
9
+ async canRun() {
10
+ const { isJava } = await readProject()
11
+ if (isJava) throw `'cds add local-messaging' is not available for Java yet`
12
+ return true
13
+ }
14
+
15
+ static hasFacet(env) {
16
+ return env.requires?.messaging?.kind === 'local-messaging'
17
+ }
18
+
19
+ async run() {
20
+ const project = await readProject()
21
+ const { configFile } = project
22
+ project.shortcut = !(await read(configFile)).cds?.requires?.messaging?.kind
23
+ await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project)
24
+ }
25
+ }
@@ -29,3 +29,6 @@ mta_archives/
29
29
  # IDEs
30
30
  # .vscode
31
31
  # .idea
32
+
33
+ # @cap-js/cds-typer
34
+ @cds-models
@@ -1,14 +1,5 @@
1
1
  {
2
2
  "dependencies": {
3
3
  "@cap-js/notifications": "*"
4
- },
5
- "cds":{
6
- "requires":{
7
- "notifications":{
8
- "types" : "notificationtypes.json",
9
- "destination" : "SAP_Notifications",
10
- "prefix": "{{ appName }}"
11
- }
12
- }
13
4
  }
14
- }
5
+ }
@@ -1,6 +1,4 @@
1
1
  const { join } = require('path')
2
- const cds = require('../../../cds')
3
- const { exists } = cds.utils
4
2
  const { readProject } = require('../../util/projectReader')
5
3
  const { mergeJSON, mergeYAML } = require('../../util/merge')
6
4
  const { DESTINATION } = require('../../constants').OPTIONS
@@ -17,7 +15,7 @@ module.exports = class NotificationsTemplate extends require('../templateBase')
17
15
  const project = await readProject()
18
16
  const { isJava } = project
19
17
  if (isJava) {
20
- throw `'cds add notifications' is not available for JAVA yet`
18
+ throw `'cds add notifications' is not available for Java yet`
21
19
  }
22
20
  return true
23
21
  }
@@ -27,26 +25,19 @@ module.exports = class NotificationsTemplate extends require('../templateBase')
27
25
  }
28
26
 
29
27
  async run() {
30
- const project = await readProject();
31
- const { configFile } = project;
32
-
33
- // create notificationtypes if it doesn't exist
34
- if (!exists('notificationtypes.json')) {
35
- await mergeJSON('notificationtypes.json', join(__dirname, 'files', 'notificationtypes.json.hbs'), project);
36
- }
37
-
38
- //update package.json
39
- await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project);
28
+ const project = await readProject()
29
+ const { configFile } = project
30
+ await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), project)
40
31
  }
41
32
 
42
33
  async runDependentMerging() {
43
- const project = await readProject();
44
- const { hasMta } = project;
34
+ const project = await readProject()
35
+ const { hasMta } = project
45
36
 
46
37
  if (hasMta) {
47
38
  await mergeYAML('mta.yaml', join(__dirname, 'files', 'mta.yaml.hbs'), project, {
48
39
  additions: [notificationTypesDeployer]
49
- });
40
+ })
50
41
  }
51
42
  }
52
43
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "devDependencies": {
3
- "@cap-js/cds-typer": "^0"
3
+ "@cap-js/cds-typer": ">=0.1"
4
4
  },
5
5
  "imports": {
6
6
  "#cds-models/*": "./@cds-models/*/index.js"
@@ -83,6 +83,7 @@ module.exports = new class ProjectReader {
83
83
  get appPath() { return env.folders.app ?? 'app' },
84
84
  get appVersion() { return appVersion },
85
85
  get appName() { return appName },
86
+ get cleanedAppName() { return appName.replace('_', '-') }, // Required when _ isn't allowed in the namespace
86
87
  get appId() { return appId },
87
88
  get appDescription() { return appDescription },
88
89
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "7.3.1",
3
+ "version": "7.3.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sap/cds-dk",
9
- "version": "7.3.1",
9
+ "version": "7.3.2",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "dependencies": {
12
12
  "@sap/cds": "^7",
@@ -28,20 +28,6 @@
28
28
  "cds": "bin/cds.js",
29
29
  "cds-ts": "bin/cds-ts.js"
30
30
  },
31
- "devDependencies": {
32
- "@cap-js/sqlite": "^1",
33
- "@types/jest": "^29",
34
- "chai": "^4.3.7",
35
- "chai-as-promised": "^7.1.1",
36
- "chai-subset": "^1.6.0",
37
- "eslint-plugin-cds-dk": "file:.eslint",
38
- "jest": "^29",
39
- "nock": "^13.3.1",
40
- "semver": "^7",
41
- "tar": "^6.2.0",
42
- "ts-node": "^10.9.1",
43
- "typescript": "^5.0.4"
44
- },
45
31
  "optionalDependencies": {
46
32
  "sqlite3": "^5.0.4"
47
33
  }
@@ -67,7 +53,7 @@
67
53
  }
68
54
  },
69
55
  "node_modules/@eslint-community/regexpp": {
70
- "version": "4.9.1",
56
+ "version": "4.10.0",
71
57
  "license": "MIT",
72
58
  "engines": {
73
59
  "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -95,7 +81,7 @@
95
81
  }
96
82
  },
97
83
  "node_modules/@eslint/js": {
98
- "version": "8.51.0",
84
+ "version": "8.52.0",
99
85
  "license": "MIT",
100
86
  "engines": {
101
87
  "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -107,10 +93,10 @@
107
93
  "optional": true
108
94
  },
109
95
  "node_modules/@humanwhocodes/config-array": {
110
- "version": "0.11.11",
96
+ "version": "0.11.13",
111
97
  "license": "Apache-2.0",
112
98
  "dependencies": {
113
- "@humanwhocodes/object-schema": "^1.2.1",
99
+ "@humanwhocodes/object-schema": "^2.0.1",
114
100
  "debug": "^4.1.1",
115
101
  "minimatch": "^3.0.5"
116
102
  },
@@ -130,7 +116,7 @@
130
116
  }
131
117
  },
132
118
  "node_modules/@humanwhocodes/object-schema": {
133
- "version": "1.2.1",
119
+ "version": "2.0.1",
134
120
  "license": "BSD-3-Clause"
135
121
  },
136
122
  "node_modules/@mapbox/node-pre-gyp": {
@@ -225,7 +211,7 @@
225
211
  }
226
212
  },
227
213
  "node_modules/@sap/cds": {
228
- "version": "7.3.0",
214
+ "version": "7.3.1",
229
215
  "license": "SEE LICENSE IN LICENSE",
230
216
  "dependencies": {
231
217
  "@sap/cds-compiler": "^4",
@@ -241,7 +227,7 @@
241
227
  }
242
228
  },
243
229
  "node_modules/@sap/cds-compiler": {
244
- "version": "4.3.0",
230
+ "version": "4.3.2",
245
231
  "license": "SEE LICENSE IN LICENSE",
246
232
  "dependencies": {
247
233
  "antlr4": "4.9.3"
@@ -608,6 +594,10 @@
608
594
  "node": ">= 6"
609
595
  }
610
596
  },
597
+ "node_modules/@ungap/structured-clone": {
598
+ "version": "1.2.0",
599
+ "license": "ISC"
600
+ },
611
601
  "node_modules/abbrev": {
612
602
  "version": "1.1.1",
613
603
  "license": "ISC",
@@ -873,11 +863,12 @@
873
863
  "optional": true
874
864
  },
875
865
  "node_modules/call-bind": {
876
- "version": "1.0.2",
866
+ "version": "1.0.5",
877
867
  "license": "MIT",
878
868
  "dependencies": {
879
- "function-bind": "^1.1.1",
880
- "get-intrinsic": "^1.0.2"
869
+ "function-bind": "^1.1.2",
870
+ "get-intrinsic": "^1.2.1",
871
+ "set-function-length": "^1.1.1"
881
872
  },
882
873
  "funding": {
883
874
  "url": "https://github.com/sponsors/ljharb"
@@ -1020,6 +1011,18 @@
1020
1011
  "version": "0.1.4",
1021
1012
  "license": "MIT"
1022
1013
  },
1014
+ "node_modules/define-data-property": {
1015
+ "version": "1.1.1",
1016
+ "license": "MIT",
1017
+ "dependencies": {
1018
+ "get-intrinsic": "^1.2.1",
1019
+ "gopd": "^1.0.1",
1020
+ "has-property-descriptors": "^1.0.0"
1021
+ },
1022
+ "engines": {
1023
+ "node": ">= 0.4"
1024
+ }
1025
+ },
1023
1026
  "node_modules/delayed-stream": {
1024
1027
  "version": "1.0.0",
1025
1028
  "license": "MIT",
@@ -1128,16 +1131,17 @@
1128
1131
  }
1129
1132
  },
1130
1133
  "node_modules/eslint": {
1131
- "version": "8.51.0",
1134
+ "version": "8.52.0",
1132
1135
  "license": "MIT",
1133
1136
  "dependencies": {
1134
1137
  "@eslint-community/eslint-utils": "^4.2.0",
1135
1138
  "@eslint-community/regexpp": "^4.6.1",
1136
1139
  "@eslint/eslintrc": "^2.1.2",
1137
- "@eslint/js": "8.51.0",
1138
- "@humanwhocodes/config-array": "^0.11.11",
1140
+ "@eslint/js": "8.52.0",
1141
+ "@humanwhocodes/config-array": "^0.11.13",
1139
1142
  "@humanwhocodes/module-importer": "^1.0.1",
1140
1143
  "@nodelib/fs.walk": "^1.2.8",
1144
+ "@ungap/structured-clone": "^1.2.0",
1141
1145
  "ajv": "^6.12.4",
1142
1146
  "chalk": "^4.0.0",
1143
1147
  "cross-spawn": "^7.0.2",
@@ -1500,13 +1504,13 @@
1500
1504
  }
1501
1505
  },
1502
1506
  "node_modules/get-intrinsic": {
1503
- "version": "1.2.1",
1507
+ "version": "1.2.2",
1504
1508
  "license": "MIT",
1505
1509
  "dependencies": {
1506
- "function-bind": "^1.1.1",
1507
- "has": "^1.0.3",
1510
+ "function-bind": "^1.1.2",
1508
1511
  "has-proto": "^1.0.1",
1509
- "has-symbols": "^1.0.3"
1512
+ "has-symbols": "^1.0.3",
1513
+ "hasown": "^2.0.0"
1510
1514
  },
1511
1515
  "funding": {
1512
1516
  "url": "https://github.com/sponsors/ljharb"
@@ -1553,6 +1557,16 @@
1553
1557
  "url": "https://github.com/sponsors/sindresorhus"
1554
1558
  }
1555
1559
  },
1560
+ "node_modules/gopd": {
1561
+ "version": "1.0.1",
1562
+ "license": "MIT",
1563
+ "dependencies": {
1564
+ "get-intrinsic": "^1.1.3"
1565
+ },
1566
+ "funding": {
1567
+ "url": "https://github.com/sponsors/ljharb"
1568
+ }
1569
+ },
1556
1570
  "node_modules/graceful-fs": {
1557
1571
  "version": "4.2.11",
1558
1572
  "license": "ISC",
@@ -1562,13 +1576,6 @@
1562
1576
  "version": "1.4.0",
1563
1577
  "license": "MIT"
1564
1578
  },
1565
- "node_modules/has": {
1566
- "version": "1.0.4",
1567
- "license": "MIT",
1568
- "engines": {
1569
- "node": ">= 0.4.0"
1570
- }
1571
- },
1572
1579
  "node_modules/has-flag": {
1573
1580
  "version": "4.0.0",
1574
1581
  "license": "MIT",
@@ -1576,6 +1583,16 @@
1576
1583
  "node": ">=8"
1577
1584
  }
1578
1585
  },
1586
+ "node_modules/has-property-descriptors": {
1587
+ "version": "1.0.1",
1588
+ "license": "MIT",
1589
+ "dependencies": {
1590
+ "get-intrinsic": "^1.2.2"
1591
+ },
1592
+ "funding": {
1593
+ "url": "https://github.com/sponsors/ljharb"
1594
+ }
1595
+ },
1579
1596
  "node_modules/has-proto": {
1580
1597
  "version": "1.0.1",
1581
1598
  "license": "MIT",
@@ -1601,6 +1618,16 @@
1601
1618
  "license": "ISC",
1602
1619
  "optional": true
1603
1620
  },
1621
+ "node_modules/hasown": {
1622
+ "version": "2.0.0",
1623
+ "license": "MIT",
1624
+ "dependencies": {
1625
+ "function-bind": "^1.1.2"
1626
+ },
1627
+ "engines": {
1628
+ "node": ">= 0.4"
1629
+ }
1630
+ },
1604
1631
  "node_modules/http-cache-semantics": {
1605
1632
  "version": "4.1.1",
1606
1633
  "license": "BSD-2-Clause",
@@ -1818,7 +1845,7 @@
1818
1845
  }
1819
1846
  },
1820
1847
  "node_modules/livereload-js": {
1821
- "version": "4.0.1",
1848
+ "version": "4.0.2",
1822
1849
  "license": "MIT"
1823
1850
  },
1824
1851
  "node_modules/locate-path": {
@@ -2205,7 +2232,7 @@
2205
2232
  }
2206
2233
  },
2207
2234
  "node_modules/object-inspect": {
2208
- "version": "1.13.0",
2235
+ "version": "1.13.1",
2209
2236
  "license": "MIT",
2210
2237
  "funding": {
2211
2238
  "url": "https://github.com/sponsors/ljharb"
@@ -2618,6 +2645,19 @@
2618
2645
  "license": "ISC",
2619
2646
  "optional": true
2620
2647
  },
2648
+ "node_modules/set-function-length": {
2649
+ "version": "1.1.1",
2650
+ "license": "MIT",
2651
+ "dependencies": {
2652
+ "define-data-property": "^1.1.1",
2653
+ "get-intrinsic": "^1.2.1",
2654
+ "gopd": "^1.0.1",
2655
+ "has-property-descriptors": "^1.0.0"
2656
+ },
2657
+ "engines": {
2658
+ "node": ">= 0.4"
2659
+ }
2660
+ },
2621
2661
  "node_modules/setprototypeof": {
2622
2662
  "version": "1.2.0",
2623
2663
  "license": "ISC"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "7.3.1",
3
+ "version": "7.3.2",
4
4
  "description": "Command line client and development toolkit for the SAP Cloud Application Programming Model",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [
@@ -1,16 +0,0 @@
1
- [
2
- {
3
- "NotificationTypeKey": "{{ appName }}-notification",
4
- "NotificationTypeVersion": "1",
5
- "Templates": [
6
- {
7
- "Language": "en",
8
- "TemplatePublic": "Hello world!",
9
- "TemplateSensitive": "Hello SAP!",
10
- "TemplateGrouped": "Hello universe!",
11
- "TemplateLanguage": "mustache",
12
- "Subtitle": "Hello {{ appName }}!"
13
- }
14
- ]
15
- }
16
- ]