@sap/cds-dk 7.4.1 → 7.5.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 (180) hide show
  1. package/bin/activate.js +1 -1
  2. package/bin/add.js +6 -4
  3. package/bin/build.js +4 -6
  4. package/bin/cds.js +4 -1
  5. package/bin/deploy/index.js +5 -2
  6. package/bin/eval.js +1 -1
  7. package/bin/extend.js +3 -3
  8. package/bin/login.js +2 -2
  9. package/bin/logout.js +1 -1
  10. package/bin/pull.js +1 -1
  11. package/bin/push.js +2 -2
  12. package/bin/subscribe.js +2 -2
  13. package/bin/unsubscribe.js +2 -2
  14. package/bin/upgrade.js +2 -2
  15. package/bin/version.js +2 -2
  16. package/bin/watch.js +1 -1
  17. package/lib/bind/bindingUtil.js +2 -1
  18. package/lib/bind/cfKeyProvider.js +2 -2
  19. package/lib/bind/userCdsrcJsonStorageProvider.js +1 -1
  20. package/lib/build/buildPlugin.js +6 -12
  21. package/lib/build/buildTaskEngine.js +24 -19
  22. package/lib/build/buildTaskFactory.js +27 -33
  23. package/lib/build/buildTaskProvider.js +1 -1
  24. package/lib/build/buildTaskProviderFactory.js +26 -41
  25. package/lib/build/constants.js +0 -1
  26. package/lib/build/index.js +3 -3
  27. package/lib/build/plugins.js +15 -15
  28. package/lib/build/provider/edmxBuildPlugin.js +6 -7
  29. package/lib/build/provider/fiori/index.js +8 -8
  30. package/lib/build/provider/hana/2migration.js +12 -16
  31. package/lib/build/provider/hana/index.js +5 -7
  32. package/lib/build/provider/hana/template/package.json +1 -1
  33. package/lib/build/provider/internalBuildPlugin.js +0 -8
  34. package/lib/build/provider/internalBuildTaskProvider.js +17 -21
  35. package/lib/build/provider/java/index.js +2 -1
  36. package/lib/build/provider/mtx-extension/index.js +5 -4
  37. package/lib/build/provider/mtx-sidecar/index.js +2 -1
  38. package/lib/build/provider/nodejs/index.js +6 -5
  39. package/lib/compile/openapi/csdl2openapi.js +28 -14
  40. package/lib/compile/openapi/index.js +6 -6
  41. package/lib/deploy/to-hana/hana.js +2 -2
  42. package/lib/env/schema.js +2 -3
  43. package/lib/index.js +68 -28
  44. package/lib/init/add.js +17 -0
  45. package/lib/init/constants.js +5 -3
  46. package/lib/init/index.js +39 -25
  47. package/lib/init/{util/merge.js → merge.js} +32 -20
  48. package/lib/init/{util/mvn.js → mvn.js} +5 -5
  49. package/lib/init/plugin.js +85 -0
  50. package/lib/init/projectReader.js +145 -0
  51. package/lib/init/registries/mta.js +151 -0
  52. package/lib/init/template/{kibana → application-logging}/files/mta.yaml.hbs +3 -3
  53. package/lib/init/template/application-logging/index.js +49 -0
  54. package/lib/init/template/approuter/files/mta.yaml.hbs +11 -11
  55. package/lib/init/template/approuter/files/xs-app.json.hbs +2 -2
  56. package/lib/init/template/approuter/index.js +36 -81
  57. package/lib/init/template/cf-manifest/files/manifest.yml.hbs +3 -3
  58. package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +4 -4
  59. package/lib/init/template/cf-manifest/index.js +4 -4
  60. package/lib/init/template/connectivity/index.js +22 -35
  61. package/lib/init/template/data/index.js +3 -2
  62. package/lib/init/template/destination/files/values.yaml +9 -0
  63. package/lib/init/template/destination/index.js +15 -47
  64. package/lib/init/template/enterprise-messaging/index.js +26 -58
  65. package/lib/init/template/enterprise-messaging-shared/index.js +23 -39
  66. package/lib/init/template/extensibility/index.js +16 -30
  67. package/lib/init/template/file-based-messaging/index.js +7 -8
  68. package/lib/init/template/h2/index.js +4 -4
  69. package/lib/init/template/hana/files/mta.yaml.hbs +8 -8
  70. package/lib/init/template/hana/index.js +29 -115
  71. package/lib/init/template/helm/files/chart/templates/NOTES.txt +12 -0
  72. package/lib/init/template/helm/files/chart/templates/_deployment_helpers.tpl +82 -0
  73. package/lib/init/template/helm/files/chart/templates/_helpers.tpl +28 -0
  74. package/lib/init/template/helm/files/chart/values.root.schema.json +61 -0
  75. package/lib/init/template/helm/files/chart/values.schema.json +366 -0
  76. package/lib/init/template/helm/{subcharts → files}/web-application/Chart.yaml +1 -1
  77. package/lib/init/template/helm/{subcharts → files}/web-application/templates/_api.tpl +1 -1
  78. package/lib/init/template/helm/{subcharts → files}/web-application/values.yaml +1 -1
  79. package/lib/init/template/helm/index.js +84 -85
  80. package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +10 -0
  81. package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +26 -0
  82. package/lib/init/template/helm-unified-runtime/index.js +91 -0
  83. package/lib/init/template/helm-unified-runtime/lib/build.js +0 -0
  84. package/lib/init/template/helm-unified-runtime/package.json +4 -0
  85. package/lib/init/template/html5-repo/files/values.yaml.hbs +28 -0
  86. package/lib/init/template/html5-repo/index.js +23 -97
  87. package/lib/init/template/java/index.js +3 -3
  88. package/lib/init/template/lint/index.js +2 -2
  89. package/lib/init/template/liquibase/index.js +16 -0
  90. package/lib/init/template/local-messaging/index.js +7 -8
  91. package/lib/init/template/mta/index.js +7 -19
  92. package/lib/init/template/mtx/index.js +2 -2
  93. package/lib/init/template/multitenancy/index.js +38 -89
  94. package/lib/init/template/nodejs/index.js +5 -4
  95. package/lib/init/template/notebook/index.js +1 -1
  96. package/lib/init/template/notifications/index.js +16 -19
  97. package/lib/init/template/pipeline/index.js +1 -1
  98. package/lib/init/template/postgres/index.js +25 -31
  99. package/lib/init/template/redis-messaging/index.js +23 -27
  100. package/lib/init/template/sample/index.js +4 -4
  101. package/lib/init/template/samples/index.js +2 -2
  102. package/lib/init/template/sqlite/files/{package.json.hbs → package.json} +0 -2
  103. package/lib/init/template/sqlite/index.js +6 -10
  104. package/lib/init/template/tiny-sample/index.js +6 -6
  105. package/lib/init/template/toggles/index.js +7 -8
  106. package/lib/init/template/typer/index.js +6 -6
  107. package/lib/init/template/xsuaa/files/mta.yaml.hbs +3 -3
  108. package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -3
  109. package/lib/init/template/xsuaa/index.js +27 -52
  110. package/lib/init/{util/template.js → template.js} +1 -1
  111. package/lib/{client → mtx}/activate.js +15 -11
  112. package/lib/{client → mtx}/auth_manager.js +5 -4
  113. package/lib/{client → mtx}/download_legacy.js +6 -4
  114. package/lib/{client → mtx}/extend.js +14 -9
  115. package/lib/{client → mtx}/index.js +1 -1
  116. package/lib/{client → mtx}/params.js +3 -1
  117. package/lib/{client → mtx}/pull.js +6 -4
  118. package/lib/{client → mtx}/push.js +10 -9
  119. package/lib/{client → mtx}/settings_manager.js +8 -6
  120. package/lib/{client → mtx}/tenant_action.js +9 -8
  121. package/lib/{client/helper/cf_helper.js → mtx/util/cf.js} +4 -3
  122. package/lib/{client/helper/dependency_helper.js → mtx/util/dependencies.js} +1 -0
  123. package/lib/mtx/util/errors.js +27 -0
  124. package/lib/mtx/util/legacy_ext.js +16 -0
  125. package/lib/{client/helper/url_helper.js → mtx/util/urls.js} +12 -1
  126. package/lib/util/axios.js +84 -0
  127. package/lib/util/fs.js +5 -1
  128. package/lib/util/write.js +1 -1
  129. package/npm-shrinkwrap.json +363 -157
  130. package/package.json +1 -1
  131. package/lib/client/base_command.js +0 -54
  132. package/lib/init/template/_merging/registry-mta.js +0 -304
  133. package/lib/init/template/helm/Model.d.ts +0 -53
  134. package/lib/init/template/kibana/files/package.json.hbs +0 -17
  135. package/lib/init/template/kibana/index.js +0 -54
  136. package/lib/init/template/templateBase.js +0 -100
  137. package/lib/init/util/md5.js +0 -86
  138. package/lib/init/util/projectReader.js +0 -94
  139. package/lib/util/pruneAxiosErrors.js +0 -39
  140. /package/lib/init/{util/indent.js → indent.js} +0 -0
  141. /package/lib/init/template/helm/{subcharts → files}/content-deployment/Chart.yaml +0 -0
  142. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/_helpers.tpl +0 -0
  143. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/job.yaml +0 -0
  144. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/secret.yaml +0 -0
  145. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/service-account.yaml +0 -0
  146. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/service-binding.yaml +0 -0
  147. /package/lib/init/template/helm/{subcharts → files}/content-deployment/values.schema.json +0 -0
  148. /package/lib/init/template/helm/{subcharts → files}/content-deployment/values.yaml +0 -0
  149. /package/lib/init/template/helm/{subcharts → files}/service-instance/Chart.yaml +0 -0
  150. /package/lib/init/template/helm/{subcharts → files}/service-instance/templates/_helpers.tpl +0 -0
  151. /package/lib/init/template/helm/{subcharts → files}/service-instance/templates/serviceinstance.yaml +0 -0
  152. /package/lib/init/template/helm/{subcharts → files}/service-instance/values.schema.json +0 -0
  153. /package/lib/init/template/helm/{subcharts → files}/service-instance/values.yaml +0 -0
  154. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/NOTES.txt +0 -0
  155. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/_helpers.tpl +0 -0
  156. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/api-rule.yaml +0 -0
  157. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/deployment.yaml +0 -0
  158. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/network-policy.yaml +0 -0
  159. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/pod-disruption-budget.yaml +0 -0
  160. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/rbac.yaml +0 -0
  161. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/secret.yaml +0 -0
  162. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service-account.yaml +0 -0
  163. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service-binding.yaml +0 -0
  164. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service.yaml +0 -0
  165. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/virtual-service.yaml +0 -0
  166. /package/lib/init/template/helm/{subcharts → files}/web-application/values.schema.json +0 -0
  167. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/NOTES.txt +0 -0
  168. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/_deployment_helpers.tpl +0 -0
  169. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/_helpers.tpl +0 -0
  170. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/values.root.schema.json +0 -0
  171. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/values.schema.json +0 -0
  172. /package/lib/init/template/postgres/files/{mta.yaml.hbs → mta.yml.hbs} +0 -0
  173. /package/lib/init/{util/xml.js → xml.js} +0 -0
  174. /package/lib/{client/helper/env_helper.js → mtx/util/env.js} +0 -0
  175. /package/lib/{client/helper/fs_helper.js → mtx/util/fs.js} +0 -0
  176. /package/lib/{client/helper → mtx/util}/logging.js +0 -0
  177. /package/lib/{client/helper → mtx/util}/question.js +0 -0
  178. /package/lib/{client/helper/string_helper.js → mtx/util/strings.js} +0 -0
  179. /package/lib/util/{cfUtil.js → cf.js} +0 -0
  180. /package/lib/util/{gitUtil.js → git.js} +0 -0
@@ -6,6 +6,7 @@ const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FILE_EXT_CDS, CONTENT_LANGUAGE_BUNDLES,
6
6
  OUTPUT_MODE_FILESYSTEM, FLAVOR_LOCALIZED_EDMX, CONTENT_EDMX, CONTENT_LOCALIZED_EDMX } = require('../../constants')
7
7
  const { getI18nDefaultFolder } = require('../../util')
8
8
  const DEFAULT_COMPILE_DEST_FOLDER = path.normalize('src/main/resources/edmx')
9
+ const DEBUG = cds.debug('cli|build')
9
10
 
10
11
  class JavaBuildPlugin extends EdmxBuildPlugin {
11
12
  init() {
@@ -49,7 +50,7 @@ class JavaBuildPlugin extends EdmxBuildPlugin {
49
50
  if (this.isStagingBuild()) {
50
51
  return super.clean()
51
52
  }
52
- this.logger._debug && this.logger.debug(`Deleting build target folder ${this.task.options.compileDest}`)
53
+ DEBUG?.(`Deleting build target folder ${this.task.options.compileDest}`)
53
54
  await fs.promises.rm(this.task.options.compileDest, { force: true, recursive: true })
54
55
  }
55
56
 
@@ -1,11 +1,11 @@
1
1
  const path = require('path')
2
2
  const fs = require('fs')
3
3
  const cds = require('../../../cds')
4
-
5
4
  const InternalBuildPlugin = require('../internalBuildPlugin')
6
5
  const { FOLDER_GEN, EXTENSION_POINT_VALIDATION } = require('../../constants')
7
6
  const ResourcesTarBuilder = require('../mtx/resourcesTarBuilder')
8
7
  const { BuildError, BuildMessage } = require('../../util')
8
+ const DEBUG = cds.debug('cli|build')
9
9
 
10
10
  class MtxExtensionBuildPlugin extends InternalBuildPlugin {
11
11
  init() {
@@ -43,7 +43,8 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
43
43
  await this.collectLanguageBundles(extModel, path.join(destExt, 'i18n'))
44
44
 
45
45
  // perform SQL backend validation to prevent extension deployment problems later on
46
- cds.compile.to.sql(model)
46
+ // REVISIT: disabled - causing stack overflow errors in LinkedCSN for some scenarios
47
+ // cds.compile.to.sql(model)
47
48
 
48
49
  const files = Object.keys(await cds.deploy.resources(model))
49
50
  if (files.length > 0) {
@@ -61,7 +62,7 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
61
62
  try {
62
63
  // throws error in case of linting errors
63
64
  this._lintExtModel(extModel, model)
64
- } catch(error) {
65
+ } catch (error) {
65
66
  // cleanup existing files in case of an error
66
67
  await fs.promises.rm(this.task.dest, { recursive: true })
67
68
  throw error
@@ -108,7 +109,7 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
108
109
  return
109
110
  }
110
111
  const env = cds.env.for('cds', path.join(this.task.src, this._getAppPackageFolder()))
111
- this.logger._debug && this.logger.debug(`Saas extension point restrictions:\n${env.requires?.['cds.xt.ExtensibilityService']}`)
112
+ DEBUG?.(`Saas extension point restrictions:\n${env.requires?.['cds.xt.ExtensibilityService']}`)
112
113
 
113
114
  const messages = linter.lint(extModel, model, env)
114
115
  if (messages.length) {
@@ -6,6 +6,7 @@ const NodejsBuildPlugin = require('../nodejs')
6
6
  const ResourcesTarProvider = require('../mtx/resourcesTarBuilder')
7
7
  const { ERROR } = NodejsBuildPlugin
8
8
  const { relativePaths, BuildError, resolveRequiredSapModels, getI18nDefaultFolder } = require('../../util')
9
+ const DEBUG = cds.debug('cli|build')
9
10
 
10
11
  const DEFAULT_MAIN_FOLDER = "_main"
11
12
 
@@ -114,7 +115,7 @@ class MtxSidecarBuildPlugin extends NodejsBuildPlugin {
114
115
  if (!modelFilePaths || modelFilePaths.length === 0) {
115
116
  throw new BuildError("No CDS models found in MTX sidecar. Make sure up-to-date versions of the required npm modules are installed.")
116
117
  }
117
- this._logger._debug && this._logger.debug(`sidecar model: ${relativePaths(cds.root, modelFilePaths).join(", ")}`)
118
+ DEBUG?.(`sidecar model: ${relativePaths(cds.root, modelFilePaths).join(", ")}`)
118
119
 
119
120
  // check whether all models belonging to the @sap namespace can be resolved
120
121
  const unresolved = resolveRequiredSapModels(modelPaths)
@@ -7,6 +7,7 @@ const { BuildError } = require('../../util')
7
7
  const { OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM, ODATA_VERSION_V2, FOLDER_GEN, CONTENT_EDMX, CONTENT_PACKAGELOCK_JSON,
8
8
  CONTENT_NPMRC, CONTENT_CDSRC_JSON, CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, FLAVOR_LOCALIZED_EDMX } = require('../../constants')
9
9
  const { WARNING } = EdmxBuildPlugin
10
+ const DEBUG = cds.debug('cli|build')
10
11
 
11
12
  class NodejsBuildPlugin extends EdmxBuildPlugin {
12
13
  init() {
@@ -67,7 +68,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
67
68
  if (cds.env.build.target === '.') {
68
69
  // delete the entire 'task.dest' folder otherwise, for details see #constructor
69
70
  // - the value of the folder 'src' has been appended to the origin 'task.dest' dir
70
- this.logger._debug && this.logger.debug(`Deleting build target folder ${this.destSrv}`)
71
+ DEBUG?.(`Deleting build target folder ${this.destSrv}`)
71
72
  await fs.promises.rm(this.isStagingBuild() ? this.task.dest : this.destSrv, { force: true, recursive: true })
72
73
  }
73
74
  }
@@ -186,7 +187,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
186
187
  try {
187
188
  pkgDescriptors = await this._execNpmPack(dest, wsRoot, workspaces)
188
189
  } catch (e) {
189
- this.logger.debug(e)
190
+ DEBUG?.(e)
190
191
  throw new BuildError(`Failed to package npm workspace dependencies\n${e.message}`)
191
192
  }
192
193
  if (pkgDescriptors?.length) {
@@ -229,9 +230,9 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
229
230
  const args = ['pack', '-ws', '--json', `--pack-destination=${dest}`]
230
231
  workspaces.forEach(w => args.push(`-w=${w}`))
231
232
 
232
- this.logger._debug && this.logger.debug(`execute command: npm ${args}`)
233
- const result = await cmd.spawnCommand( 'npm', args, { cwd: wsRoot }, true, !!this.logger._debug)
234
- this.logger._debug && this.logger.debug(result)
233
+ DEBUG?.(`execute command: npm ${args}`)
234
+ const result = await cmd.spawnCommand( 'npm', args, { cwd: wsRoot }, true, !!DEBUG)
235
+ DEBUG?.(result)
235
236
  return JSON.parse(result)
236
237
  }
237
238
  }
@@ -77,8 +77,18 @@ module.exports.csdl2openapi = function (
77
77
  preProcess(csdl, boundOverloads, derivedTypes, alias, namespace, namespaceUrl, voc);
78
78
 
79
79
  const entityContainer = csdl.$EntityContainer ? modelElement(csdl.$EntityContainer) : {};
80
+ if (csdl.$EntityContainer) {
81
+ let serviceName = nameParts(csdl.$EntityContainer).qualifier;
82
+ Object.keys(entityContainer).forEach(element => {
83
+ if (entityContainer[element].$Type) {
84
+ let type = nameParts(entityContainer[element].$Type).name;
85
+ if (csdl[serviceName]?.[type]?.['@cds.autoexpose'] || csdl[serviceName]?.[type]?.['@cds.autoexposed'])
86
+ entityContainer[element]['$cds.autoexpose'] = true;
87
+ }
88
+ });
89
+ }
90
+
80
91
  const keyAsSegment = entityContainer ? entityContainer[voc.Capabilities.KeyAsSegmentSupported] : {};
81
- const deepUpdate = entityContainer ? entityContainer[voc.Capabilities.DeepUpdateSupport] && entityContainer[voc.Capabilities.DeepUpdateSupport].Supported : {};
82
92
 
83
93
  const openapi = {
84
94
  openapi: '3.0.2',
@@ -534,7 +544,7 @@ module.exports.csdl2openapi = function (
534
544
  if (prefixParameters.length > 0) pathItem.parameters = prefixParameters;
535
545
 
536
546
  operationRead(pathItem, element, name, sourceName, targetName, target, level, restrictions, false, nonExpandable);
537
- if (element.$Collection && (element.$ContainsTarget || level < 2 && target)) {
547
+ if (!root['$cds.autoexpose'] && element.$Collection && (element.$ContainsTarget || level < 2 && target)) {
538
548
  operationCreate(pathItem, element, name, sourceName, targetName, target, level, restrictions);
539
549
  }
540
550
  pathItemsForBoundOperations(paths, prefix, prefixParameters, element, sourceName);
@@ -544,9 +554,11 @@ module.exports.csdl2openapi = function (
544
554
  if (level < maxLevels)
545
555
  pathItemsWithKey(paths, prefix, prefixParameters, element, root, sourceName, targetName, target, level, navigationPath, restrictions, nonExpandable);
546
556
  } else {
547
- operationUpdate(pathItem, element, name, sourceName, target, level, restrictions);
548
- if (element.$Nullable) {
549
- operationDelete(pathItem, element, name, sourceName, target, level, restrictions);
557
+ if (!root['$cds.autoexpose']) {
558
+ operationUpdate(pathItem, element, name, sourceName, target, level, restrictions);
559
+ if (element.$Nullable) {
560
+ operationDelete(pathItem, element, name, sourceName, target, level, restrictions);
561
+ }
550
562
  }
551
563
  pathItemsForBoundOperations(paths, prefix, prefixParameters, element, sourceName);
552
564
  pathItemsWithNavigation(paths, prefix, prefixParameters, type, root, sourceName, level, navigationPath);
@@ -616,8 +628,10 @@ module.exports.csdl2openapi = function (
616
628
  paths[path] = pathItem;
617
629
 
618
630
  operationRead(pathItem, element, name, sourceName, targetName, target, level, restrictions, true, nonExpandable);
619
- operationUpdate(pathItem, element, name, sourceName, target, level, restrictions, true);
620
- operationDelete(pathItem, element, name, sourceName, target, level, restrictions, true);
631
+ if (!root['$cds.autoexpose']) {
632
+ operationUpdate(pathItem, element, name, sourceName, target, level, restrictions, true);
633
+ operationDelete(pathItem, element, name, sourceName, target, level, restrictions, true);
634
+ }
621
635
  if (Object.keys(pathItem).filter((i) => i !== "parameters").length === 0)
622
636
  delete paths[path];
623
637
 
@@ -1773,7 +1787,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1773
1787
  title: name,
1774
1788
  enum: members
1775
1789
  };
1776
- const description = type[voc.Core.Description];
1790
+ const description = type[voc.Core.LongDescription];
1777
1791
  if (description) s.description = description;
1778
1792
  schemas[qualifier + '.' + name] = s;
1779
1793
  }
@@ -1789,7 +1803,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1789
1803
  function schemaForTypeDefinition(schemas, qualifier, name, type) {
1790
1804
  const s = getSchema(Object.assign({ $Type: type.$UnderlyingType }, type));
1791
1805
  s.title = name;
1792
- const description = type[voc.Core.Description];
1806
+ const description = type[voc.Core.LongDescription];
1793
1807
  if (description) s.description = description;
1794
1808
  schemas[qualifier + '.' + name] = s;
1795
1809
  }
@@ -1825,10 +1839,10 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1825
1839
  if (property.$Collection && suffix === "" && isCount === true) {
1826
1840
  schemaProperties[`${iName}@${csdl.$Version === '4.0' ? 'odata.' : ''}count`] = ref('count');
1827
1841
  }
1828
- if (property[voc.Core.Permissions] != "Read" && !property[voc.Core.Computed] && property.$ContainsTarget) {
1842
+ if (property[voc.Core.Permissions] != "Read" && !property[voc.Core.Computed] && ( property.$ContainsTarget || property.$OnDelete === 'Cascade') ) {
1829
1843
  if (suffix === SUFFIX.create)
1830
1844
  schemaProperties[iName] = getSchema(property, SUFFIX.create);
1831
- if (suffix === SUFFIX.update && deepUpdate)
1845
+ if (suffix === SUFFIX.update)
1832
1846
  schemaProperties[iName] = getSchema(property, SUFFIX.create);
1833
1847
  }
1834
1848
  } else {
@@ -1858,7 +1872,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1858
1872
  if (suffix === SUFFIX.create && required.length > 0)
1859
1873
  schemas[schemaName].required = [...new Set(required)];
1860
1874
 
1861
- const description = type[voc.Core.Description];
1875
+ const description = type[voc.Core.LongDescription];
1862
1876
  if (description) {
1863
1877
  schemas[schemaName].description = description;
1864
1878
  }
@@ -2248,9 +2262,9 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
2248
2262
  };
2249
2263
  }
2250
2264
 
2251
- if (!forParameter && element[voc.Core.Description]) {
2265
+ if (!forParameter && element[voc.Core.LongDescription]) {
2252
2266
  if (s.$ref) s = { allOf: [s] };
2253
- s.description = element[voc.Core.Description];
2267
+ s.description = element[voc.Core.LongDescription];
2254
2268
  }
2255
2269
 
2256
2270
  return s;
@@ -2,9 +2,13 @@ const csdl2openapi = require('./csdl2openapi')
2
2
  const cds = require('../../cds')
3
3
 
4
4
  module.exports = function processor(csn, options = {}) {
5
+ const edmOptions = Object.assign({
6
+ odataOpenapiHints: true, // hint to compiler
7
+ to: 'openapi' // hint to cds.compile.to.edm (usually set by CLI, but also do this in programmatic usages)
8
+ }, options)
5
9
 
6
10
  // must not be part of function* otherwise thrown errors are swallowed
7
- const csdl = cds.compile.to.edm(csn, options);
11
+ const csdl = cds.compile.to.edm(csn, edmOptions);
8
12
 
9
13
  if (csdl[Symbol.iterator]) { // generator function means multiple services
10
14
  return _iterate(csdl, csn, options)
@@ -12,10 +16,6 @@ module.exports = function processor(csn, options = {}) {
12
16
  const openApiOptions = toOpenApiOptions(csdl, csn, options)
13
17
  return _getOpenApi(csdl, openApiOptions);
14
18
  }
15
-
16
- // const file = csdl.$EntityContainer.replace(/\.[^.]+$/, '');
17
- // yield [openapi, { file }]; // add file to avoid relative path in filename
18
- // return openapi;
19
19
  }
20
20
 
21
21
  function* _iterate(csdl, csn, options) {
@@ -57,6 +57,6 @@ function servicePath(csdl, csn) {
57
57
  if (csdl.$EntityContainer) {
58
58
  const serviceName = csdl.$EntityContainer.replace(/\.[^.]+$/, '')
59
59
  const service = csn.definitions[serviceName]
60
- return cds.service.path4 ? cds.service.path4(service) : cds.serve.path4(service)
60
+ return cds.service.path4?.(service) || cds.serve.path4(service)
61
61
  }
62
62
  }
@@ -10,8 +10,8 @@ const { build } = require('../../build');
10
10
  const buildConstants = require('../../build/constants');
11
11
 
12
12
  const hdiDeployUtil = require('./hdiDeployUtil');
13
- const cfUtil = require('../../util/cfUtil');
14
- const gitUtil = require('../../util/gitUtil');
13
+ const cfUtil = require('../../util/cf');
14
+ const gitUtil = require('../../util/git');
15
15
  const mtaUtil = require('./mtaUtil');
16
16
 
17
17
  const { bold, info } = require('../../util/term');
package/lib/env/schema.js CHANGED
@@ -1,5 +1,4 @@
1
- const { join } = require('path')
2
- const { mergeJSON } = require('../init/util/merge')
1
+ const { merge } = require('../init/merge')
3
2
  const { readJSON } = require('../util/fs')
4
3
 
5
4
  module.exports = async function overlay4(schemaName, cwd = process.cwd()) {
@@ -26,7 +25,7 @@ module.exports = async function overlay4(schemaName, cwd = process.cwd()) {
26
25
 
27
26
  // optional, don't throw if file not found
28
27
  try {
29
- await mergeJSON(result, join(__dirname, 'schemas', schemaName))
28
+ await merge(__dirname, 'schemas', schemaName).into(result)
30
29
  result.description = result.description + ' - overlaid'
31
30
  } catch (err) {
32
31
  if (err.code !== 'ENOENT') throw err
package/lib/index.js CHANGED
@@ -1,33 +1,73 @@
1
+ /** @type { import('./cds') & CdsDk & CdsDkAdd & CdsDkBuild} */
1
2
  const cds = module.exports = require('./cds')
2
- cds.extend (cds.constructor) .with (class {
3
- get import() { return super.import = require('./import/importapi') }
4
- })
5
-
6
- cds.extend (cds.compile.to.constructor) .with (class {
7
- get asyncapi() { return super.asyncapi = require('./compile/asyncapi') }
8
- get openapi() { return super.openapi = require('./compile/openapi') }
9
- get xsuaa(){ return super.xsuaa = require('./compile/to-xsuaa') }
10
- 'edmx-v2'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'v2'}) }
11
- 'edmx-v4'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'v4'}) }
12
- 'edmx-w4'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'w4'}) }
13
- 'edmx-x4'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'x4'}) }
14
- })
15
-
16
- // Compat to cds <=6. Esp. BAS tools need it, see cap/issues#13918
17
- // TODO remove compat w/ cds-dk 8
18
- if (cds.compile.to.constructor.name === 'Object') { // not a class as in cds 7
19
- cds.compile.to.xsuaa = require('./compile/to-xsuaa')
3
+
4
+ class CdsDk {
5
+
6
+ get import() {
7
+ return super.import = require('./import/importapi')
8
+ }
9
+
10
+ get compile() {
11
+ let compile = require(_local('@sap/cds/lib/compile/cds-compile'))
12
+ cds.extend (compile.to.constructor) .with (class {
13
+ get asyncapi() { return super.asyncapi = require('./compile/asyncapi') }
14
+ get openapi() { return super.openapi = require('./compile/openapi') }
15
+ get xsuaa(){ return super.xsuaa = require('./compile/to-xsuaa') }
16
+ 'edmx-v2'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'v2'}) }
17
+ 'edmx-v4'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'v4'}) }
18
+ 'edmx-w4'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'w4'}) }
19
+ 'edmx-x4'(csn,o) { return cds.compile.to.edmx(csn,{...o,flavor:'x4'}) }
20
+ })
21
+ // Compat to cds <=6. Esp. BAS tools need it, see cap/issues#13918
22
+ // TODO remove compat w/ cds-dk 8
23
+ if (compile.to.constructor.name === 'Object') { // not a class as in cds 7
24
+ compile.to.xsuaa = require('./compile/to-xsuaa')
25
+ }
26
+ return super.compile = compile
27
+ }
28
+
29
+ // add overlay4 method to cds.schema to retrieve schema with cds-dk features
30
+ // schema is cds version specific; add cds-dk parts not present in cds, e.g. build
31
+ // failsafe for legacy cds without schema.constructor
32
+ get schema() {
33
+ let schema = require(_local('@sap/cds/lib/env/schemas'))
34
+ cds.extend(schema.constructor) .with (class {
35
+ get overlay4() { return super.overlay4 = require('./env/schema') }
36
+ })
37
+ return super.schema = schema
38
+ }
20
39
  }
21
40
 
22
- // add overlay4 method to cds.schema to retrieve schema with cds-dk features
23
- // schema is cds version specific; add cds-dk parts not present in cds, e.g. build
24
- // failsafe for legacy cds without schema.constructor
25
- cds.extend(cds.schema?.constructor || {}).with(class {
26
- get overlay4() { return super.overlay4 = require('./env/schema') }
27
- })
41
+ cds.extend (cds.constructor) .with (CdsDk)
28
42
 
29
- // set build API, potentially removing the old API facade from sap/cds 7
30
- // delete cds.__proto__?.build //> not required, as its overriden below anyways
31
- cds.extend (cds.constructor) .with (class {
43
+ class CdsDkAdd {
44
+ get add() { return super.add = require('./init/add') }
45
+ }
46
+ class CdsDkBuild {
32
47
  get build() { return super.build = require('./build') }
33
- })
48
+ }
49
+ if (process.argv[2] in { 'add':1, 'init':1 }) {
50
+ cds.extend (cds.constructor) .with (CdsDkAdd)
51
+ } else if (process.argv[2] in { 'build':1, 'deploy':1, 'push':1 }) {
52
+ cds.extend (cds.constructor) .with (CdsDkBuild)
53
+ }
54
+
55
+ const MIN_SUPPORTED_CDS_VERSION = 6
56
+ const [cdsVersion] = cds.version.split('.')
57
+ if (parseInt(cdsVersion) < MIN_SUPPORTED_CDS_VERSION) {
58
+ const [dkVersion] = require('../package.json').version.split('.')
59
+ console.error(`
60
+ This application uses '@sap/cds' version ${cdsVersion}, which is not compatible with the installed '@sap/cds-dk' version ${dkVersion}.
61
+ You can either:
62
+ - update '@sap/cds' to the latest version (recommended)
63
+ - downgrade '@sap/cds-dk' to version ${MIN_SUPPORTED_CDS_VERSION}
64
+ `)
65
+ process.exit(1)
66
+ }
67
+
68
+ function _local (id) {
69
+ return require.resolve (id, {paths:[
70
+ process.cwd(), // project-local module is preferred
71
+ __dirname // otherwise from our own dependencies
72
+ ]})
73
+ }
@@ -0,0 +1,17 @@
1
+ const registered = new Map
2
+
3
+ module.exports = {
4
+ Plugin: require('./plugin'),
5
+ merge: require('./merge').merge, // fluent API
6
+ readProject: require('./projectReader').readProject,
7
+ mvn: {
8
+ add: require('./mvn').add
9
+ },
10
+ registries: {
11
+ mta: require('./registries/mta')
12
+ },
13
+ register: (name, plugin) => {
14
+ registered.set(name, plugin)
15
+ },
16
+ registered
17
+ }
@@ -4,7 +4,7 @@ module.exports = {
4
4
  COMMAND_INIT: 'init',
5
5
  COMMAND_ADD: 'add',
6
6
 
7
- MAVEN_ARCHETYPE_VERSION: '2.4.0',
7
+ MAVEN_ARCHETYPE_VERSION: '2.4.1',
8
8
 
9
9
  OPTIONS: Object.freeze({
10
10
  JAVA: 'java',
@@ -15,6 +15,8 @@ module.exports = {
15
15
  TINY_SAMPLE: 'tiny-sample',
16
16
  SAMPLE: 'sample',
17
17
  PIPELINE: 'pipeline',
18
+ HELM_UNIFIED_RUNTIME: 'helm-unified-runtime',
19
+ HELM: 'helm',
18
20
  MTA: 'mta',
19
21
  CONNECTIVITY: 'connectivity',
20
22
  CF_MANIFEST: 'cf-manifest',
@@ -27,6 +29,7 @@ module.exports = {
27
29
  POSTGRES: 'postgres',
28
30
  SQLITE: 'sqlite',
29
31
  H2: 'h2',
32
+ LIQUIBASE: 'liquibase',
30
33
  LOCAL_MESSAGING: 'local-messaging',
31
34
  FILE_BASED_MESSAGING: 'file-based-messaging',
32
35
  ENTERPRISE_MESSAGING: 'enterprise-messaging',
@@ -35,11 +38,10 @@ module.exports = {
35
38
  APPROUTER: 'approuter',
36
39
  DESTINATION: 'destination',
37
40
  DATA: 'data',
38
- KIBANA: 'kibana',
41
+ APPLICATION_LOGGING: 'application-logging',
39
42
  LINT: 'lint',
40
43
  LINT_GLOBAL: 'lint:global',
41
44
  LINT_DEV: 'lint:dev',
42
- HELM: 'helm',
43
45
  TYPER: 'typer',
44
46
  HTML5_REPO: 'html5-repo',
45
47
  NOTIFICATIONS: 'notifications'
package/lib/init/index.js CHANGED
@@ -5,17 +5,17 @@ const term = require('../util/term');
5
5
  const { OPTIONS, COMMAND_INIT, PROJECT_FILES, REGEX_PROJECT_NAME } = require('./constants')
6
6
  const {
7
7
  NODEJS, JAVA,
8
- HANA, APPROUTER, XSUAA, KIBANA, ENTERPRISE_MESSAGING,
8
+ HANA, APPROUTER, XSUAA, APPLICATION_LOGGING, ENTERPRISE_MESSAGING,
9
9
  MTA, MULTITENANCY, PIPELINE,
10
10
  TINY_SAMPLE, SAMPLE
11
11
  } = OPTIONS
12
12
 
13
- const cds = require('../cds'), { exists, readdir } = cds.utils
13
+ const cds = require('..'), { exists, readdir } = cds.utils
14
14
  const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) ? console.debug : undefined
15
15
 
16
16
  module.exports = class CDSGenerator {
17
17
  constructor() {
18
- this.cwd = process.cwd();
18
+ this.cwd = process.cwd()
19
19
 
20
20
  this.uiConfig = [{
21
21
  title: 'Project Name',
@@ -60,7 +60,7 @@ module.exports = class CDSGenerator {
60
60
  { name: 'SAP HANA Cloud', value: HANA },
61
61
  { name: 'SAP Application Router', value: APPROUTER },
62
62
  { name: 'User Authentication via XSUAA', value: XSUAA },
63
- { name: 'Kibana Logging Dashboard', value: KIBANA },
63
+ { name: 'Application Logging', value: APPLICATION_LOGGING },
64
64
  { name: 'SAP BTP Event Mesh', value: ENTERPRISE_MESSAGING }
65
65
  ],
66
66
  multiple: true,
@@ -133,9 +133,12 @@ module.exports = class CDSGenerator {
133
133
  // keep caller independent from internal names
134
134
  options: {
135
135
  cwd: options.cwd,
136
- add: options.add
136
+ add: new Set(options.add)
137
137
  }
138
138
  }
139
+
140
+ // must be called after above code to ensure cds.cli.options.add is set
141
+ cds.add = require('./add')
139
142
  }
140
143
 
141
144
  this._initialize(projectName);
@@ -176,8 +179,8 @@ module.exports = class CDSGenerator {
176
179
  for (const template of this.templateList) {
177
180
  console.log(`Adding feature '${template.name}'...`);
178
181
  await template.run();
179
- await template.runDependentMerging();
180
- await template.runRelatedMerging();
182
+ await template.combine();
183
+ await template.combineSupported();
181
184
  }
182
185
 
183
186
  if (cds.cli.command === COMMAND_INIT) {
@@ -192,10 +195,10 @@ module.exports = class CDSGenerator {
192
195
  }
193
196
  }
194
197
 
195
- async _createTemplate(filename) {
198
+ async _createTemplate(plugin) {
196
199
  try {
197
- const TemplateClass = require(`./template/${filename}`);
198
- return new TemplateClass(this);
200
+ const Plugin = cds.add.registered.get(plugin) ?? require(`./template/${plugin}`)
201
+ return new Plugin(this)
199
202
  } catch (err) {
200
203
  if (err.code === 'MODULE_NOT_FOUND') {
201
204
  const entries = (await readdir(path.join(__dirname, 'template')))
@@ -205,11 +208,11 @@ module.exports = class CDSGenerator {
205
208
  entry !== 'nodejs' &&
206
209
  entry !== 'java'
207
210
  );
208
- const fuzzySearch = require('../../bin/util/fuzzySearch');
209
- const [bestMatch] = fuzzySearch(filename, entries);
210
- throw `Unknown facet '${term.bold(filename)}'. Did you mean ${term.bold(`cds add ${bestMatch}`)}?\n\nHaven't found the proper facet yet? Here are all supported facets:\n\n ${term.bold(entries.join('\n '))}\n`
211
+ const fuzzySearch = require('../../bin/util/fuzzySearch')
212
+ const [bestMatch] = fuzzySearch(plugin, entries)
213
+ throw `Unknown facet '${term.bold(plugin)}'. Did you mean ${term.bold(`cds add ${bestMatch}`)}?\n\nHaven't found the proper facet yet? Here are all supported facets:\n\n ${term.bold(entries.join('\n '))}\n`
211
214
  }
212
- throw err;
215
+ throw err
213
216
  }
214
217
  }
215
218
 
@@ -217,28 +220,39 @@ module.exports = class CDSGenerator {
217
220
  const templates = new Map
218
221
  const { command, options, argv } = cds.cli
219
222
 
220
- const facets = command === COMMAND_INIT ? options.add : new Set(argv[0].split(','))
223
+ const plugins = command === COMMAND_INIT ? options.add : new Set(argv[0].split(','))
221
224
 
222
- for (let facet of facets) {
225
+ for (let plugin of plugins) {
223
226
  // Compat
224
- if (facet === 'sample-tiny') facet = 'tiny-sample'
225
- if (facet === 'kibana-logging') facet = 'kibana'
226
- if (facet === 'postgresql') facet = 'postgres'
227
+ if (plugin === 'helm' && cds.cli.options['internal-unified-runtime-charts']) {
228
+ plugin = 'helm-unified-runtime'
229
+ cds.cli.options.add.delete('helm')
230
+ cds.cli.options.add.add('helm-unified-runtime')
231
+ }
232
+ if (plugin === 'sample-tiny') plugin = 'tiny-sample'
233
+ if (plugin in { 'kibana-logging':1, 'kibana':1 }) plugin = 'application-logging'
234
+ if (plugin === 'postgresql') plugin = 'postgres'
227
235
 
228
- if (!templates.has(facet)) {
229
- const template = await this._createTemplate(facet)
236
+ if (!templates.has(plugin)) {
237
+ const template = await this._createTemplate(plugin)
230
238
  if (await template.canRun()) {
231
239
  DEBUG?.(`Adding feature '${template.name}'`)
232
- templates.set(facet, template)
233
- const dependencies = await template.getDependencies()
234
- dependencies?.forEach(d => facets.add(d))
240
+ templates.set(plugin, template)
241
+ const dependencies = await template.requires()
242
+ dependencies?.forEach(d => plugins.add(d))
235
243
  }
236
244
  }
237
245
  }
238
246
 
239
247
  const cmds = Object.values(OPTIONS)
240
248
  this.templateList = Array.from(templates.entries())
241
- .sort(([a], [b]) => cmds.indexOf(a) - cmds.indexOf(b))
249
+ .sort(([lhs], [rhs]) => {
250
+ const a = cmds.indexOf(lhs), b = cmds.indexOf(rhs)
251
+ if (a === -1 && b === -1) return 0
252
+ if (a === -1) return 1
253
+ if (b === -1) return -1
254
+ return a - b
255
+ })
242
256
  .map((entry) => entry[1])
243
257
 
244
258
  // check debug to avoid lengthy computation when not in debug mode