@sap/cds-dk 7.9.5 → 8.0.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.
- package/CHANGELOG.md +2116 -0
- package/bin/add.js +18 -52
- package/bin/bind.js +2 -2
- package/bin/build.js +29 -4
- package/bin/cds.js +23 -11
- package/bin/compile/index.js +7 -6
- package/bin/completion/index.js +70 -46
- package/bin/completion/scripts/cds-bash.sh +4 -1
- package/bin/completion/scripts/cds-fish.fish +13 -0
- package/bin/completion/scripts/cds-ps.ps1 +2 -1
- package/bin/completion/scripts/cds-zsh.sh +2 -1
- package/bin/deploy/index.js +6 -5
- package/bin/deploy/to-sqlite.js +2 -2
- package/bin/extend.js +19 -50
- package/bin/help.js +2 -2
- package/bin/init.js +10 -77
- package/bin/login.js +13 -5
- package/bin/migrate.js +1 -1
- package/bin/pull.js +11 -0
- package/bin/repl.js +3 -0
- package/bin/test.js +5 -0
- package/bin/version.js +7 -7
- package/bin/watch.js +1 -10
- package/lib/bind/KubernetesApiAccessor.js +10 -9
- package/lib/build/buildTaskEngine.js +11 -7
- package/lib/build/buildTaskFactory.js +15 -43
- package/lib/build/buildTaskProviderFactory.js +16 -44
- package/lib/build/constants.js +3 -3
- package/lib/build/index.js +2 -2
- package/lib/build/{buildPlugin.js → plugin.js} +65 -46
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/Chart.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/Chart.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/_helpers.tpl +7 -0
- package/lib/build/plugins/helm/files/subcharts/service-instance/templates/servicebinding.yaml +32 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/serviceinstance.yaml +3 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.schema.json +63 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.yaml +23 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/Chart.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/deployment.yaml +2 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/hpa.yaml +22 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/pod-disruption-budget.yaml +1 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.schema.json +49 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.yaml +8 -2
- package/lib/{init/template/helm/files/chart → build/plugins/helm/files}/templates/_deployment_helpers.tpl +5 -0
- package/lib/build/plugins/helm/files/templates/_helpers.tpl +13 -0
- package/lib/build/plugins/helm/index.js +81 -0
- package/lib/build/plugins.js +12 -15
- package/lib/build/provider/featureToggleBuildPlugin.js +7 -39
- package/lib/build/provider/hana/2migration.js +168 -124
- package/lib/build/provider/hana/index.js +20 -25
- package/lib/build/provider/hana/template/package.json +4 -3
- package/lib/build/provider/internalBuildPlugin.js +32 -97
- package/lib/build/provider/internalBuildTaskProvider.js +10 -46
- package/lib/build/provider/java/index.js +2 -3
- package/lib/build/provider/mtx/index.js +5 -4
- package/lib/build/provider/mtx-extension/index.js +5 -2
- package/lib/build/provider/mtx-sidecar/index.js +2 -2
- package/lib/build/util.js +83 -12
- package/lib/compile/to-mermaid.js +108 -0
- package/lib/compile/to_asyncapi.js +7 -0
- package/lib/compile/to_openapi.js +7 -0
- package/lib/deploy/to-hana/hana.js +37 -34
- package/lib/deploy/to-hana/hdiDeployUtil.js +8 -6
- package/lib/env/schemas/cds-rc.js +1 -1
- package/lib/import/common.js +2 -2
- package/lib/import/odata/metadataconverter/MetadataConverter.js +4 -4
- package/lib/import/odata/v2parser.js +83 -197
- package/lib/import/odata/v4parser.js +1 -38
- package/lib/import/openapi/importOpenAPI.js +164 -42
- package/lib/index.js +10 -12
- package/lib/init/bas.js +91 -0
- package/lib/init/constants.js +16 -10
- package/lib/init/index.js +72 -150
- package/lib/init/merge.js +12 -20
- package/lib/init/mvn.js +103 -150
- package/lib/init/plugin.js +11 -7
- package/lib/init/projectReader.js +53 -19
- package/lib/init/registries/mta.js +51 -6
- package/lib/init/template/application-logging/files/package.json.hbs +7 -0
- package/lib/init/template/application-logging/index.js +13 -1
- package/lib/init/template/approuter/files/containerize.yaml.hbs +10 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +1 -2
- package/lib/init/template/approuter/files/values.yaml.hbs +19 -4
- package/lib/init/template/approuter/files/xs-app.json.hbs +12 -3
- package/lib/init/template/approuter/index.js +29 -25
- package/lib/init/template/attachments/files/mta.yaml.hbs +14 -0
- package/lib/init/template/attachments/files/package.json.hbs +5 -0
- package/lib/init/template/attachments/files/values.yaml +7 -0
- package/lib/init/template/attachments/index.js +53 -0
- package/lib/init/template/audit-logging/files/mta.yaml.hbs +14 -0
- package/lib/init/template/audit-logging/files/package.json.hbs +7 -0
- package/lib/init/template/audit-logging/index.js +66 -0
- package/lib/init/template/cf-manifest/index.js +4 -0
- package/lib/init/template/completion/completionSetup.js +54 -33
- package/lib/init/template/completion/index.js +7 -1
- package/lib/init/template/connectivity/index.js +4 -4
- package/lib/init/template/containerize/files/containerize.yaml.hbs +26 -0
- package/lib/init/template/containerize/index.js +24 -0
- package/lib/init/template/data/index.js +4 -0
- package/lib/init/template/destination/files/mta.yaml.hbs +25 -1
- package/lib/init/template/destination/index.js +12 -2
- package/lib/init/template/enterprise-messaging/index.js +6 -3
- package/lib/init/template/enterprise-messaging-shared/index.js +5 -1
- package/lib/init/template/extensibility/files/package.json.hbs +1 -1
- package/lib/init/template/extensibility/files/xs-security.json.hbs +2 -8
- package/lib/init/template/extensibility/index.js +3 -1
- package/lib/init/template/file-based-messaging/index.js +4 -0
- package/lib/init/template/h2/index.js +4 -0
- package/lib/init/template/hana/files/containerize.yaml.hbs +10 -0
- package/lib/init/template/hana/files/db/package.json +3 -2
- package/lib/init/template/hana/files/package.json.hbs +4 -7
- package/lib/init/template/hana/files/values.yaml.hbs +1 -2
- package/lib/init/template/hana/index.js +15 -7
- package/lib/init/template/helm/files/Chart.yaml.hbs +2 -3
- package/lib/init/template/helm/files/values.schema.json +2173 -0
- package/lib/init/template/helm/files/values.yaml.hbs +11 -6
- package/lib/init/template/helm/index.js +77 -18
- package/lib/init/template/helm-unified-runtime/index.js +19 -56
- package/lib/init/template/html5-repo/files/app-package.json.hbs +11 -7
- package/lib/init/template/html5-repo/files/manifest.json +13 -0
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +41 -8
- package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +21 -0
- package/lib/init/template/html5-repo/files/ui5.yaml.hbs +2 -29
- package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -2
- package/lib/init/template/html5-repo/files/xs-app.json.hbs +21 -8
- package/lib/init/template/html5-repo/index.js +33 -30
- package/lib/init/template/http/index.js +36 -12
- package/lib/init/template/java/index.js +18 -12
- package/lib/init/template/kafka/index.js +4 -0
- package/lib/init/template/lint/index.js +7 -2
- package/lib/init/template/liquibase/index.js +4 -0
- package/lib/init/template/local-messaging/index.js +4 -0
- package/lib/init/template/malware-scanner/files/mta.yaml.hbs +14 -0
- package/lib/init/template/malware-scanner/files/package.json.hbs +17 -0
- package/lib/init/template/malware-scanner/files/values.yaml +7 -0
- package/lib/init/template/malware-scanner/index.js +47 -0
- package/lib/init/template/mta/files/mta.yaml.hbs +3 -3
- package/lib/init/template/mta/files/package.json +1 -1
- package/lib/init/template/mta/index.js +4 -0
- package/lib/init/template/mtx/index.js +4 -0
- package/lib/init/template/multitenancy/files/containerize.yaml.hbs +10 -0
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +0 -1
- package/lib/init/template/multitenancy/files/package.json.hbs +1 -1
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +6 -5
- package/lib/init/template/multitenancy/files/values.yaml.hbs +14 -24
- package/lib/init/template/multitenancy/index.js +50 -28
- package/lib/init/template/nodejs/files/eslint.config.mjs +2 -0
- package/lib/init/template/nodejs/files/package.json.hbs +2 -3
- package/lib/init/template/nodejs/index.js +4 -0
- package/lib/init/template/notifications/files/mta.yaml.hbs +2 -2
- package/lib/init/template/notifications/index.js +4 -0
- package/lib/init/template/pipeline/files/.pipeline/config.yml +1 -1
- package/lib/init/template/pipeline/files/Jenkinsfile +1 -1
- package/lib/init/template/pipeline/index.js +4 -0
- package/lib/init/template/portal/files/mta.yaml.hbs +52 -0
- package/lib/init/template/portal/files/package.json.hbs +11 -0
- package/lib/init/template/portal/files/package.sidecar.json +7 -0
- package/lib/init/template/portal/files/portal-site/CommonDataModel.json.hbs +97 -0
- package/lib/init/template/portal/files/portal-site/i18n/catalog.properties +1 -0
- package/lib/init/template/portal/files/portal-site/i18n/catalog_de.properties +1 -0
- package/lib/init/template/portal/files/portal-site/i18n/group.properties +1 -0
- package/lib/init/template/portal/files/portal-site/i18n/group_de.properties +1 -0
- package/lib/init/template/portal/index.js +84 -0
- package/lib/init/template/postgres/index.js +5 -1
- package/lib/init/template/redis-messaging/index.js +4 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_de.properties +3 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_en.properties +3 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +13 -1
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n.properties +2 -2
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_de.properties +3 -0
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_en.properties +4 -0
- package/lib/init/template/sample/files/app/browse/webapp/manifest.json +3 -3
- package/lib/init/template/sample/files/app/index.html +1 -1
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -5
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -6
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -5
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -16
- package/lib/init/template/sample/files/nodejs/cat-service.js +2 -2
- package/lib/init/template/sample/files/package.json.hbs +3 -0
- package/lib/init/template/sample/index.js +16 -9
- package/lib/init/template/sqlite/index.js +4 -0
- package/lib/init/template/tiny-sample/files/nodejs/db/data/my.bookshop-Books.csv +3 -3
- package/lib/init/template/tiny-sample/files/nodejs/srv/cat-service.cds.hbs +1 -1
- package/lib/init/template/tiny-sample/index.js +4 -0
- package/lib/init/template/toggles/files/package.json.hbs +1 -1
- package/lib/init/template/toggles/index.js +4 -0
- package/lib/init/template/typer/index.js +4 -0
- package/lib/init/template/typescript/files/package.json +12 -0
- package/lib/init/template/typescript/files/tsconfig.json +13 -0
- package/lib/init/template/typescript/index.js +39 -0
- package/lib/init/template/workzone/index.js +5 -0
- package/lib/init/template/workzone-standard/files/manifest.json.hbs +6 -0
- package/lib/init/template/workzone-standard/index.js +30 -0
- package/lib/init/template/xsuaa/files/package.json.hbs +1 -1
- package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -2
- package/lib/init/template/xsuaa/index.js +11 -7
- package/lib/init/validate.js +27 -0
- package/lib/lint/generators.js +1 -1
- package/lib/lint/io.js +25 -7
- package/lib/mtx/auth_manager.js +64 -30
- package/lib/mtx/download_legacy.js +2 -2
- package/lib/mtx/index.js +0 -4
- package/lib/mtx/params.js +32 -38
- package/lib/mtx/pull.js +151 -43
- package/lib/mtx/push.js +3 -3
- package/lib/mtx/settings_manager.js +75 -35
- package/lib/mtx/tenant_action.js +1 -1
- package/lib/mtx/util/cf.js +1 -1
- package/lib/mtx/util/fs.js +26 -1
- package/lib/mtx/util/logging.js +7 -3
- package/lib/util/command.js +0 -2
- package/lib/util/fs.js +2 -3
- package/lib/util/question.js +28 -0
- package/lib/util/term.js +5 -3
- package/npm-shrinkwrap.json +226 -1087
- package/package.json +13 -8
- package/bin/activate.js +0 -77
- package/lib/compile/asyncapi/channels.js +0 -22
- package/lib/compile/asyncapi/components/messageTraits/index.js +0 -89
- package/lib/compile/asyncapi/components/messages/index.js +0 -173
- package/lib/compile/asyncapi/components/schemas/annotations.js +0 -33
- package/lib/compile/asyncapi/components/schemas/array.js +0 -8
- package/lib/compile/asyncapi/components/schemas/cache.js +0 -14
- package/lib/compile/asyncapi/components/schemas/definition.js +0 -187
- package/lib/compile/asyncapi/components/schemas/enum.js +0 -16
- package/lib/compile/asyncapi/components/schemas/examples.js +0 -10
- package/lib/compile/asyncapi/components/schemas/index.js +0 -14
- package/lib/compile/asyncapi/components/schemas/localized.js +0 -29
- package/lib/compile/asyncapi/components/schemas/primitiveElement.js +0 -41
- package/lib/compile/asyncapi/components/schemas/ref.js +0 -45
- package/lib/compile/asyncapi/components/schemas/utils.js +0 -108
- package/lib/compile/asyncapi/index.js +0 -247
- package/lib/compile/asyncapi/message.js +0 -13
- package/lib/compile/asyncapi/utils.js +0 -27
- package/lib/compile/openapi/csdl2openapi.js +0 -2448
- package/lib/compile/openapi/index.js +0 -68
- package/lib/init/template/helm/files/chart/templates/NOTES.txt +0 -14
- package/lib/init/template/helm/files/chart/templates/_helpers.tpl +0 -28
- package/lib/init/template/helm/files/chart/values.root.schema.json +0 -61
- package/lib/init/template/helm/files/chart/values.schema.json +0 -366
- package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +0 -10
- package/lib/init/template/helm-unified-runtime/files/templates/_deployment_helpers.tpl +0 -90
- package/lib/init/template/helm-unified-runtime/files/templates/_helpers.tpl +0 -28
- package/lib/init/template/helm-unified-runtime/files/values.root.schema.json +0 -61
- package/lib/init/template/helm-unified-runtime/files/values.schema.json +0 -366
- package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +0 -26
- package/lib/init/template/helm-unified-runtime/package.json +0 -4
- package/lib/init/template/multitenancy/files/mtxs-configmap-java-approuter.yaml +0 -20
- package/lib/init/template/multitenancy/files/mtxs-configmap-java.yaml +0 -18
- package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs-approuter.yaml +0 -12
- package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs.yaml +0 -12
- package/lib/init/template/multitenancy/files/saas-registry-secret.yaml +0 -9
- package/lib/init/template/nodejs/files/eslint.config.js +0 -13
- package/lib/init/template/notebook/index.js +0 -11
- package/lib/init/template/samples/index.js +0 -9
- package/lib/mtx/activate.js +0 -238
- package/lib/mtx/extend.js +0 -173
- package/lib/util/exec.d.ts +0 -54
- package/lib/util/exec.js +0 -211
- /package/lib/{init/template/approuter/files → build/plugins/helm/files/plugins/approuter}/approuter-configmap.yaml +0 -0
- /package/lib/{init/template/connectivity/files → build/plugins/helm/files/plugins/connectivity}/connectivity-proxy-info.yaml +0 -0
- /package/lib/{init/template/html5-repo/files → build/plugins/helm/files/plugins/html5-repo}/html5-apps-deployer-configmap.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/_helpers.tpl +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/job.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/secret.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-account.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-binding.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.schema.json +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/NOTES.txt +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_api.tpl +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_helpers.tpl +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/api-rule.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/network-policy.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/rbac.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/secret.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-account.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-binding.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/virtual-service.yaml +0 -0
- /package/lib/{init/template/helm-unified-runtime → build/plugins/helm}/files/templates/NOTES.txt +0 -0
- /package/lib/init/template/{nodejs/files → java}/.cdsrc.json +0 -0
- /package/lib/init/template/tiny-sample/files/nodejs/db/{data-model.cds → schema.cds} +0 -0
|
@@ -4,25 +4,14 @@ const cds = require('../../cds')
|
|
|
4
4
|
const { hasJavaNature, getDefaultModelOptions, BuildError, hasOptionValue, normalizePath } = require('../util')
|
|
5
5
|
const BuildTaskProvider = require('../buildTaskProvider')
|
|
6
6
|
const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_TASK_JAVA_CF, BUILD_TASK_NODEJS, BUILD_TASK_NODE_CF, BUILD_TASK_MTX,
|
|
7
|
-
|
|
7
|
+
BUILD_TASKS, BUILD_TASK_MTX_SIDECAR, MTX_SIDECAR_FOLDER, BUILD_TASK_MTX_EXTENSION, NODEJS_MODEL_EXCLUDE_LIST,
|
|
8
8
|
IGNORE_DEFAULT_MODELS, CONTENT_WS } = require("../constants")
|
|
9
9
|
const ResourcesTarBuilder = require('./mtx/resourcesTarBuilder')
|
|
10
10
|
const DEBUG = cds.debug('cli|build')
|
|
11
11
|
|
|
12
12
|
class InternalBuildTaskProvider extends BuildTaskProvider {
|
|
13
|
-
constructor() {
|
|
14
|
-
super()
|
|
15
|
-
// ensure that classic mtx is not used in combination with cds-dk@7
|
|
16
|
-
if (InternalBuildTaskProvider._isClassicMtx()) {
|
|
17
|
-
throw new BuildError(`@sap/cds-mtx is deprecated and not supported by @sap/cds-dk >= 7.
|
|
18
|
-
Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration or install @sap/cds-dk version 6 instead.`)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
13
|
providesTask(key) {
|
|
23
|
-
return BUILD_TASKS.includes(key.for)
|
|
24
|
-
// REVISIT: do not support different build task implementations of the same build task ID defined by 'for'
|
|
25
|
-
// return (BUILD_TASKS.includes(key.for) && !key.use) || (key.use && key.use.startsWith(BUILD_TASK_PREFIX))
|
|
14
|
+
return BUILD_TASKS.includes(key.for)
|
|
26
15
|
}
|
|
27
16
|
|
|
28
17
|
async lookupTasks(tasks, dependencies) {
|
|
@@ -30,10 +19,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
30
19
|
}
|
|
31
20
|
|
|
32
21
|
async applyTaskDefaults(task) {
|
|
33
|
-
const taskFor = InternalBuildTaskProvider._getForValueFromTask(task)
|
|
34
|
-
task.for = task.for || taskFor
|
|
35
|
-
task.use = task.use || `${BUILD_TASK_PREFIX}/${taskFor}`
|
|
36
|
-
|
|
37
22
|
// src folder needs to be initialized first
|
|
38
23
|
InternalBuildTaskProvider._setDefaultSrcFolder(task)
|
|
39
24
|
|
|
@@ -41,7 +26,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
41
26
|
}
|
|
42
27
|
|
|
43
28
|
getPlugin(task) {
|
|
44
|
-
return require(`./${
|
|
29
|
+
return require(`./${task.for}`)
|
|
45
30
|
}
|
|
46
31
|
|
|
47
32
|
async _createTasks(tasks, dependencies) {
|
|
@@ -202,7 +187,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
202
187
|
}
|
|
203
188
|
|
|
204
189
|
// mtxs nodejs app without sidecar
|
|
205
|
-
if (!
|
|
190
|
+
if (!hasJavaNature()) {
|
|
206
191
|
DEBUG?.("MTX Nodejs app without sidecar")
|
|
207
192
|
return {
|
|
208
193
|
for: BUILD_TASK_MTX,
|
|
@@ -218,7 +203,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
218
203
|
return null
|
|
219
204
|
}
|
|
220
205
|
let task = null
|
|
221
|
-
if (
|
|
206
|
+
if (hasJavaNature()) {
|
|
222
207
|
task = this._createJavaTask(src, taskOptions)
|
|
223
208
|
} else {
|
|
224
209
|
task = this._createNodeTask(src, taskOptions)
|
|
@@ -243,6 +228,9 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
243
228
|
|
|
244
229
|
_createNodeTask(src, taskOptions) {
|
|
245
230
|
DEBUG?.("found implementation technology Nodejs")
|
|
231
|
+
if (!fs.existsSync(path.join(cds.root, 'package.json'))) {
|
|
232
|
+
throw new BuildError(`No 'package.json' found in project root folder '${cds.root}'`)
|
|
233
|
+
}
|
|
246
234
|
return {
|
|
247
235
|
src: src,
|
|
248
236
|
for: BUILD_TASK_NODEJS,
|
|
@@ -254,17 +242,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
254
242
|
return !!cds.env.extends
|
|
255
243
|
}
|
|
256
244
|
|
|
257
|
-
static _isClassicMtx() {
|
|
258
|
-
function _hasMtxDependency() {
|
|
259
|
-
try {
|
|
260
|
-
return !!require(path.join(cds.root, 'package.json'))?.dependencies?.['@sap/cds-mtx']
|
|
261
|
-
} catch (e) {
|
|
262
|
-
return false
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return /true/i.test(process.env.OLD_MTX) || _hasMtxDependency()
|
|
266
|
-
}
|
|
267
|
-
|
|
268
245
|
/**
|
|
269
246
|
* Distinguishes whether the Nodejs project is a Streamlined MTX (cds >=6) or an old MTX project.
|
|
270
247
|
*/
|
|
@@ -303,14 +280,14 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
303
280
|
task.src ||= normalizePath(cds.env.folders.srv)
|
|
304
281
|
break
|
|
305
282
|
default:
|
|
306
|
-
throw new Error(`Unknown build task '${task.
|
|
283
|
+
throw new Error(`Unknown build task '${task.for}'`)
|
|
307
284
|
}
|
|
308
285
|
}
|
|
309
286
|
|
|
310
287
|
static async _setDefaultModel(task) {
|
|
311
288
|
const ws = hasOptionValue(task.options?.[CONTENT_WS], true) || cds.cli.options?.ws
|
|
312
289
|
// REVISIT: filter nodejs bootstrap service models for Java - issues/12770#issuecomment-1805719
|
|
313
|
-
const filter =
|
|
290
|
+
const filter = hasJavaNature() ? (m) => !NODEJS_MODEL_EXCLUDE_LIST.includes(m) : null
|
|
314
291
|
let taskModelPaths = task.options?.model
|
|
315
292
|
if (taskModelPaths && !Array.isArray(taskModelPaths)) {
|
|
316
293
|
taskModelPaths = [taskModelPaths]
|
|
@@ -336,19 +313,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
336
313
|
}
|
|
337
314
|
}
|
|
338
315
|
|
|
339
|
-
/**
|
|
340
|
-
* Returns whether this project is a java project or not.
|
|
341
|
-
* @param {string} srv - the folder name of the service module
|
|
342
|
-
*/
|
|
343
|
-
static _hasJavaNature(srv = cds.env.folders.srv) {
|
|
344
|
-
srv = this._getModuleFolder(Array.isArray(srv) ? srv : [srv])
|
|
345
|
-
return hasJavaNature([cds.root, srv && path.join(cds.root, srv)])
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
static _getForValueFromTask(task) {
|
|
349
|
-
return task.for ? task.for : task.use && task.use.substring(BUILD_TASK_PREFIX.length + 1)
|
|
350
|
-
}
|
|
351
|
-
|
|
352
316
|
/**
|
|
353
317
|
* Determines the module folder from the given list that may represent files or folders w or w/o .cds file extension.
|
|
354
318
|
* @param {Array} filesOrFolders
|
|
@@ -24,9 +24,8 @@ class JavaBuildPlugin extends EdmxBuildPlugin {
|
|
|
24
24
|
await this._compileForJava(model, compileDest)
|
|
25
25
|
|
|
26
26
|
if (!this.hasBuildOption(CONTENT_EDMX, false)) {
|
|
27
|
-
// generate edmx files containing all features
|
|
28
|
-
|
|
29
|
-
if (!this.hasBuildOption(CONTENT_LOCALIZED_EDMX, false)) {
|
|
27
|
+
// generate edmx files containing all features - localized edmx for backward compatibility
|
|
28
|
+
if (this.hasBuildOption(CONTENT_LOCALIZED_EDMX, true)) {
|
|
30
29
|
await this.compileToEdmx(model, compileDest, { [FLAVOR_LOCALIZED_EDMX]: true })
|
|
31
30
|
}
|
|
32
31
|
// non-localized edmx
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
const fs = require('fs')
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const cds = require('../../../cds')
|
|
@@ -9,16 +9,17 @@ const { BuildError } = require('../../util')
|
|
|
9
9
|
|
|
10
10
|
class MtxBuildPlugin extends EdmxBuildPlugin {
|
|
11
11
|
get priority() {
|
|
12
|
-
//
|
|
13
|
-
return
|
|
12
|
+
// must run after 'hana' build task
|
|
13
|
+
return super.priority - 10
|
|
14
14
|
}
|
|
15
|
+
|
|
15
16
|
init() {
|
|
16
17
|
super.init()
|
|
17
18
|
|
|
18
19
|
// this build task only supports nodejs mtxs apps without sidecar
|
|
19
20
|
if (cds.env['project-nature'] === 'java') {
|
|
20
21
|
throw new BuildError(`@sap/cds-mtx is deprecated and not supported by @sap/cds-dk >= 7. This also applies to the 'mtx' build task in Java projects.
|
|
21
|
-
Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration
|
|
22
|
+
Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration.`)
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -133,8 +133,11 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
static _getSaasPkgPath() {
|
|
136
|
+
if (!cds.env.extends) {
|
|
137
|
+
throw new BuildError(`Missing configuration 'cds.extends' in package.json`)
|
|
138
|
+
}
|
|
136
139
|
// cds.env.extends holds the SaaS app package name, also if the extends field is defined on root level
|
|
137
|
-
let saasPkgPath = this._getWorkspacePath(cds.env.extends
|
|
140
|
+
let saasPkgPath = this._getWorkspacePath(cds.env.extends)
|
|
138
141
|
if (!saasPkgPath) {
|
|
139
142
|
// older projects might not have a workspace definition
|
|
140
143
|
saasPkgPath = this._getNodeModulesPath(saasPkgPath)
|
|
@@ -156,7 +159,7 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
|
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
static _getNodeModulesPath() {
|
|
159
|
-
const saasPkgPath = path.join(cds.root, 'node_modules', cds.env.extends
|
|
162
|
+
const saasPkgPath = path.join(cds.root, 'node_modules', cds.env.extends)
|
|
160
163
|
if (!fs.existsSync(saasPkgPath)) {
|
|
161
164
|
throw new BuildError(`The SaaS application base model is missing. Did you execute 'cds pull' and 'npm install'?`)
|
|
162
165
|
}
|
|
@@ -12,8 +12,8 @@ const DEFAULT_MAIN_FOLDER = "_main"
|
|
|
12
12
|
|
|
13
13
|
class MtxSidecarBuildPlugin extends NodejsBuildPlugin {
|
|
14
14
|
get priority() {
|
|
15
|
-
//
|
|
16
|
-
return
|
|
15
|
+
// must run after 'hana' build task
|
|
16
|
+
return super.priority - 10
|
|
17
17
|
}
|
|
18
18
|
init() {
|
|
19
19
|
super.init()
|
package/lib/build/util.js
CHANGED
|
@@ -28,18 +28,9 @@ function setProperty(src, segments, value) {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Returns whether this project is a java project or not.
|
|
31
|
-
* @param {Array} dirs - the absolute path names to check.
|
|
32
31
|
*/
|
|
33
|
-
function hasJavaNature(
|
|
34
|
-
return
|
|
35
|
-
if (dir) {
|
|
36
|
-
const file = path.join(dir, 'pom.xml')
|
|
37
|
-
if (fs.existsSync(file)) {
|
|
38
|
-
acc.push(file)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return acc
|
|
42
|
-
}, []).length > 0
|
|
32
|
+
function hasJavaNature() {
|
|
33
|
+
return [cds.env.folders.srv, '.'].some(f => f && fs.existsSync(path.join(cds.root, f, 'pom.xml')))
|
|
43
34
|
}
|
|
44
35
|
|
|
45
36
|
/**
|
|
@@ -176,8 +167,18 @@ async function pathExists(path) {
|
|
|
176
167
|
* @returns the paths are relative to 'cds.root'.
|
|
177
168
|
*/
|
|
178
169
|
async function getWorkspaces(resolve = false, devDependencies = true, wsRoot = cds.root) {
|
|
170
|
+
let pgkJsonWsRoot
|
|
171
|
+
try {
|
|
172
|
+
pgkJsonWsRoot = require(path.join(wsRoot, 'package.json'))
|
|
173
|
+
} catch (e) {
|
|
174
|
+
if (e.code === 'MODULE_NOT_FOUND') {
|
|
175
|
+
DEBUG?.(`No package.json found in project '${wsRoot}', skipping workspace resolution.`)
|
|
176
|
+
return []
|
|
177
|
+
}
|
|
178
|
+
throw e
|
|
179
|
+
}
|
|
180
|
+
|
|
179
181
|
const workspaces = []
|
|
180
|
-
const pgkJsonWsRoot = require(path.join(wsRoot, 'package.json'))
|
|
181
182
|
let pgkJson = pgkJsonWsRoot
|
|
182
183
|
if (wsRoot !== cds.root) {
|
|
183
184
|
pgkJson = require(path.join(cds.root, 'package.json'))
|
|
@@ -201,6 +202,44 @@ async function getWorkspaces(resolve = false, devDependencies = true, wsRoot = c
|
|
|
201
202
|
return workspaces
|
|
202
203
|
}
|
|
203
204
|
|
|
205
|
+
/**
|
|
206
|
+
* This JavaScript function filterFeaturePaths is used to filter and categorize file paths
|
|
207
|
+
* from a given model into two categories: base and features.
|
|
208
|
+
* @param {*} model - represents a data model. It's expected to have a $sources property which is an array of file paths.
|
|
209
|
+
* @param {*} modelPaths - an array of file paths.
|
|
210
|
+
* @returns
|
|
211
|
+
*/
|
|
212
|
+
function filterFeaturePaths(model, modelPaths) {
|
|
213
|
+
const ftsName = path.dirname(cds.env.features.folders || 'fts/*')
|
|
214
|
+
const regex = new RegExp(`[/|\\\\]+${ftsName}[/|\\\\]+(?<ftName>[^/|\\\\]*)`)
|
|
215
|
+
const sources = { base: [] }
|
|
216
|
+
|
|
217
|
+
// add ROOT source file paths for the base model
|
|
218
|
+
sources.base = cds.resolve(modelPaths).reduce((acc, file) => {
|
|
219
|
+
const match = file.match(regex)
|
|
220
|
+
if (!match) {
|
|
221
|
+
acc.push(file)
|
|
222
|
+
}
|
|
223
|
+
return acc
|
|
224
|
+
}, [])
|
|
225
|
+
|
|
226
|
+
// add source file paths for the features
|
|
227
|
+
sources.features = model['$sources'].reduce((acc, file) => {
|
|
228
|
+
const match = file.match(regex)
|
|
229
|
+
if (match) {
|
|
230
|
+
const { ftName } = match.groups
|
|
231
|
+
//feature
|
|
232
|
+
if (!acc[ftName]) {
|
|
233
|
+
acc[ftName] = []
|
|
234
|
+
}
|
|
235
|
+
acc[ftName].push(file)
|
|
236
|
+
}
|
|
237
|
+
return acc
|
|
238
|
+
}, {})
|
|
239
|
+
|
|
240
|
+
return sources
|
|
241
|
+
}
|
|
242
|
+
|
|
204
243
|
/**
|
|
205
244
|
* Read installed npm workspaces using 'npm ls -ws --json'.
|
|
206
245
|
* @returns {Array} list of package paths, or an empty array if either
|
|
@@ -280,6 +319,36 @@ function _filterModelPaths(modelPaths, filter) {
|
|
|
280
319
|
return [...model].filter(m => filter ? filter(m) : true).map(m => normalizePath(m))
|
|
281
320
|
}
|
|
282
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Returns a set of files found in the given directory and its subdirectories.
|
|
324
|
+
* @param {string} srcDir - the directory to search for files
|
|
325
|
+
* @param {Function} filter - the filter function to apply to the found files
|
|
326
|
+
* @param {Array} files - the set of files to add the found files to
|
|
327
|
+
* @returns {Array} files found in the given directory and its subdirectories
|
|
328
|
+
*/
|
|
329
|
+
function getFiles(srcDir, filter, files = []) {
|
|
330
|
+
function handleResource(entry, filter, files) {
|
|
331
|
+
if (!filter || filter.call(this, entry)) {
|
|
332
|
+
const stats = fs.lstatSync(entry)
|
|
333
|
+
if (stats.isDirectory()) {
|
|
334
|
+
getFiles(entry, filter, files)
|
|
335
|
+
} else if (stats.isFile() || stats.isSymbolicLink()) {
|
|
336
|
+
files.push(entry)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
let entries = []
|
|
341
|
+
try {
|
|
342
|
+
entries = fs.readdirSync(srcDir)
|
|
343
|
+
} catch (e) {
|
|
344
|
+
// ignore if not existing
|
|
345
|
+
}
|
|
346
|
+
entries.map(subDirEntry => path.join(srcDir, subDirEntry)).forEach((entry) => {
|
|
347
|
+
handleResource(entry, filter, files)
|
|
348
|
+
})
|
|
349
|
+
return files
|
|
350
|
+
}
|
|
351
|
+
|
|
283
352
|
/**
|
|
284
353
|
* Return gnu-style error string for location `loc`:
|
|
285
354
|
* - 'File:Line:Col' without `loc.end`
|
|
@@ -371,6 +440,8 @@ module.exports = {
|
|
|
371
440
|
normalizePath,
|
|
372
441
|
pathExists,
|
|
373
442
|
getWorkspaces,
|
|
443
|
+
filterFeaturePaths,
|
|
444
|
+
getFiles,
|
|
374
445
|
BuildMessage,
|
|
375
446
|
BuildError
|
|
376
447
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
module.exports = function to_mermaid (model, options={}) {
|
|
4
|
+
options = Object.assign({
|
|
5
|
+
assocnames: false, // include association names
|
|
6
|
+
elements : false, // include all elements { falsy | 'all'|true | 'keys' }
|
|
7
|
+
min : false, // minify the model, i.e. remove unused definitions, available in CLI
|
|
8
|
+
namespaces: true, // group entities by namespace/service
|
|
9
|
+
queries : false, // include relations for queries
|
|
10
|
+
service : undefined // filter service by name, available in CLI
|
|
11
|
+
}, cds.env.mermaid ?? {}, options)
|
|
12
|
+
|
|
13
|
+
const elemOpts = options.elements === 'none' ? false : options.elements
|
|
14
|
+
if (options.min) model = cds.minify(model)
|
|
15
|
+
|
|
16
|
+
model = cds.linked(model)
|
|
17
|
+
const allServices = model.all('service')
|
|
18
|
+
|
|
19
|
+
// filter by one service if its name is given or only one service is present
|
|
20
|
+
const srvFilter = options.service ?? (Object.keys(allServices).length === 1 ? allServices[0].name : undefined)
|
|
21
|
+
if (srvFilter && !model.definitions[srvFilter]) {
|
|
22
|
+
throw new Error(`Service "${srvFilter}" not found among ${model.all('service').map(s => s.name).sort()}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const seenEntities = new Set()
|
|
26
|
+
const namespaces = {}
|
|
27
|
+
const entityFilter = e => !e.name.startsWith('cds.') && !e.name.endsWith('.texts')
|
|
28
|
+
|
|
29
|
+
let diag = ''
|
|
30
|
+
|
|
31
|
+
// if requested, filter by one service
|
|
32
|
+
model.all('service')
|
|
33
|
+
.filter (srv => !srvFilter || srv.name === srvFilter)
|
|
34
|
+
.forEach(srv => {
|
|
35
|
+
namespaces[srv.name] = []
|
|
36
|
+
model.entities(srv)
|
|
37
|
+
.filter (entityFilter)
|
|
38
|
+
.forEach (e => {
|
|
39
|
+
namespaces[srv.name].push(e)
|
|
40
|
+
seenEntities.add(e.name)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// group other namespaces/services
|
|
45
|
+
if (options.namespaces) {
|
|
46
|
+
model.all('entity')
|
|
47
|
+
.filter (e => !seenEntities.has(e.name))
|
|
48
|
+
.filter (entityFilter)
|
|
49
|
+
.forEach (e => {
|
|
50
|
+
const ns = e.name.slice(0,e.name.lastIndexOf('.'))
|
|
51
|
+
if (!srvFilter || ns === srvFilter) {
|
|
52
|
+
namespaces[ns] = namespaces[ns] || []
|
|
53
|
+
namespaces[ns].push(e)
|
|
54
|
+
seenEntities.add(e.name)
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// create namespace groups and classes
|
|
59
|
+
Object.keys(namespaces).forEach(ns => {
|
|
60
|
+
if (!diag.length) diag = `classDiagram\n`
|
|
61
|
+
diag += ` namespace ${ns.replaceAll('.','_')} {\n`
|
|
62
|
+
namespaces[ns].forEach (e => {
|
|
63
|
+
const simpleName = e.name.slice(e.name.lastIndexOf('.')+1)
|
|
64
|
+
diag += ` class \`${e.name}\``
|
|
65
|
+
diag += `["${simpleName}"]` // simple name as label
|
|
66
|
+
if (elemOpts) {
|
|
67
|
+
diag += ` {\n`
|
|
68
|
+
e.elements.forEach (el => {
|
|
69
|
+
if ((elemOpts === 'all' || elemOpts === true) || (el.key && elemOpts == 'keys')) {
|
|
70
|
+
diag += ` +${el._type?.replace('cds.','')} ${el.name}`
|
|
71
|
+
diag += `\n`
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
diag += ` }`
|
|
75
|
+
}
|
|
76
|
+
diag += `\n`
|
|
77
|
+
})
|
|
78
|
+
diag += ` }\n`
|
|
79
|
+
})
|
|
80
|
+
diag += `\n`
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// add associations, either from collected entities or all entities
|
|
84
|
+
const entities = seenEntities.size
|
|
85
|
+
? Array.from(seenEntities).map(name => model.definitions[name])
|
|
86
|
+
: model.all('entity').filter (entityFilter) // if no grouping and no service filter is on
|
|
87
|
+
entities.forEach(e => {
|
|
88
|
+
if (!diag.length) diag = `classDiagram\n`
|
|
89
|
+
e.elements.forEach (el => {
|
|
90
|
+
if (el instanceof cds.Association) {
|
|
91
|
+
if (el.target.endsWith('.texts')) return
|
|
92
|
+
const type = el.type === 'cds.Composition' ? '*-->' : '-->'
|
|
93
|
+
const card = el.cardinality?.max === '*' ? '"*"' : ''
|
|
94
|
+
diag += ` \`${e.name}\` ${type} ${card} \`${el.target}\``
|
|
95
|
+
if (options.assocnames) {
|
|
96
|
+
diag += `: ${el.name}`
|
|
97
|
+
}
|
|
98
|
+
diag += `\n`
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
// add relations for queries
|
|
102
|
+
if (e.query && options.queries) {
|
|
103
|
+
diag += ` \`${e.name}\` ..> \`${e.query.target.name}\`\n`
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
return diag.trim()
|
|
108
|
+
}
|
|
@@ -36,7 +36,7 @@ module.exports = new class HanaDeployer {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async deploy(options = {}) {
|
|
39
|
-
let { model, serviceName, tunnelAddress, vcapFile, undeployWhitelist, hdiOptions = {}, dry, storeCredentials } = options;
|
|
39
|
+
let { model, serviceName: pServiceName, tunnelAddress, vcapFile, undeployWhitelist, hdiOptions = {}, dry, storeCredentials } = options;
|
|
40
40
|
|
|
41
41
|
options.for = options.for || 'hybrid';
|
|
42
42
|
|
|
@@ -51,7 +51,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (vcapFile) {
|
|
54
|
-
console.log(`Using VCAP_SERVICES from file ${vcapFile}
|
|
54
|
+
console.log(`Using VCAP_SERVICES from file ${vcapFile}.`);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const fromFile = vcapFile && exists(vcapFile) ? await read(vcapFile) : {};
|
|
@@ -59,23 +59,22 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
59
59
|
const vcapEnv = { ...fromEnv, ...fromFile };
|
|
60
60
|
|
|
61
61
|
const warnings = [];
|
|
62
|
-
if (
|
|
62
|
+
if (pServiceName && vcapEnv.VCAP_SERVICES?.hana?.[0].name !== pServiceName) {
|
|
63
63
|
if (vcapFile) {
|
|
64
|
-
warnings.push(`The specified service name '${
|
|
64
|
+
warnings.push(`The specified service name '${pServiceName}' was used; the information coming from --vcap-service file was ignored.`);
|
|
65
65
|
} else if (Object.keys(fromEnv).length > 0) {
|
|
66
|
-
warnings.push(`The specified service name '${
|
|
66
|
+
warnings.push(`The specified service name '${pServiceName}' was used; the information coming from environment variable VCAP_SERVICES was ignored.`);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const projectPath = cds.root;
|
|
71
70
|
const buildResults = await this._build();
|
|
72
71
|
|
|
73
72
|
if (process.env.TARGET_CONTAINER) {
|
|
74
73
|
vcapEnv.TARGET_CONTAINER = process.env.TARGET_CONTAINER;
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
for (const { task } of buildResults) {
|
|
77
|
+
if (dry) {
|
|
79
78
|
const model = await cds.load(task.src);
|
|
80
79
|
const data = cds.compile.to.hdbtable(model);
|
|
81
80
|
for (const [src, { file }] of data) {
|
|
@@ -83,23 +82,27 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
83
82
|
console.log(src);
|
|
84
83
|
console.log();
|
|
85
84
|
}
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
for (const { task } of buildResults) {
|
|
85
|
+
} else {
|
|
89
86
|
const dest = task.dest;
|
|
90
87
|
|
|
88
|
+
let serviceName = pServiceName;
|
|
89
|
+
let serviceKeyName;
|
|
90
|
+
if (!serviceName && cds.env.requires.db?.binding?.instance) {
|
|
91
|
+
serviceName = cds.env.requires.db.binding.instance;
|
|
92
|
+
serviceKeyName = cds.env.requires.db.binding.key;
|
|
93
|
+
}
|
|
94
|
+
|
|
91
95
|
if (undeployWhitelist) {
|
|
92
96
|
console.log('Writing undeploy.json');
|
|
93
97
|
await fs.write(path.join(dest, 'undeploy.json'), JSON.stringify(undeployWhitelist, null, 2));
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
const hasVCAPEnv = Object.keys(vcapEnv).length > 0;
|
|
97
|
-
let serviceKeyName
|
|
98
101
|
if (!serviceName && hasVCAPEnv) {
|
|
99
102
|
await fs.mkdir(dest, { recursive: true });
|
|
100
103
|
} else {
|
|
101
104
|
const { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey } =
|
|
102
|
-
await this._getOrCreateCFService(
|
|
105
|
+
await this._getOrCreateCFService(dest, serviceName, serviceKeyName, tunnelAddress);
|
|
103
106
|
|
|
104
107
|
serviceName ??= cfServiceInstanceName;
|
|
105
108
|
serviceKeyName ??= cfServiceInstanceKeyName
|
|
@@ -108,7 +111,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
if (storeCredentials) {
|
|
111
|
-
await this._addInstanceToDefaultEnvJson([dest,
|
|
114
|
+
await this._addInstanceToDefaultEnvJson([dest, cds.root], cfServiceInstanceName, serviceKey);
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
|
|
@@ -129,7 +132,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
if (storeCredentials) {
|
|
132
|
-
await gitUtil.ensureFileIsGitignored('default-env.json',
|
|
135
|
+
await gitUtil.ensureFileIsGitignored('default-env.json', cds.root);
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
console.log(`If not already done, use ${info('cds add hana')} to configure the project for SAP HANA.\n`);
|
|
@@ -146,7 +149,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
146
149
|
}
|
|
147
150
|
|
|
148
151
|
|
|
149
|
-
async _getOrCreateCFService(
|
|
152
|
+
async _getOrCreateCFService(currentModelFolder, serviceName, serviceKeyName, tunnelAddress) {
|
|
150
153
|
const modelName = path.basename(currentModelFolder);
|
|
151
154
|
|
|
152
155
|
// get from param
|
|
@@ -155,7 +158,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
155
158
|
if (serviceName) {
|
|
156
159
|
cfServiceInstanceName = serviceName;
|
|
157
160
|
} else {
|
|
158
|
-
const cfServiceDescriptor = await mtaUtil.getHanaDbModuleDescriptor(
|
|
161
|
+
const cfServiceDescriptor = await mtaUtil.getHanaDbModuleDescriptor(cds.root, modelName);
|
|
159
162
|
cfServiceInstanceName = cfServiceDescriptor.hdiServiceName;
|
|
160
163
|
cfServiceInstanceMta = cfServiceDescriptor.hdiService
|
|
161
164
|
}
|
|
@@ -167,16 +170,16 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
167
170
|
const cfConfig = cfServiceInstanceMta?.parameters?.config;
|
|
168
171
|
const serviceInstance = await this.createHanaService(cfServiceInstanceName, cfConfig);
|
|
169
172
|
|
|
170
|
-
const cfServiceInstanceKeyName = `${cfServiceInstanceName}-key`;
|
|
171
|
-
let
|
|
172
|
-
this.
|
|
173
|
+
const cfServiceInstanceKeyName = serviceKeyName ?? `${cfServiceInstanceName}-key`;
|
|
174
|
+
let credentials = await cfUtil.getOrCreateServiceKey(serviceInstance, cfServiceInstanceKeyName, { permissions: 'development' });
|
|
175
|
+
this._validateCredentials(credentials, cfServiceInstanceKeyName);
|
|
173
176
|
|
|
174
177
|
if (tunnelAddress) {
|
|
175
178
|
console.log(`Using tunnel address ${bold(tunnelAddress)} (beta feature)`);
|
|
176
|
-
|
|
179
|
+
credentials = this._injectTunnelAddress(credentials, tunnelAddress)
|
|
177
180
|
}
|
|
178
181
|
|
|
179
|
-
return { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey, serviceInstance }
|
|
182
|
+
return { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey: credentials, serviceInstance }
|
|
180
183
|
}
|
|
181
184
|
|
|
182
185
|
|
|
@@ -198,18 +201,18 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
|
|
201
|
-
|
|
202
|
-
if (!
|
|
204
|
+
_validateCredentials(credentials, cfServiceInstanceKey) {
|
|
205
|
+
if (!credentials) {
|
|
203
206
|
throw `Could not create service key ${bold(cfServiceInstanceKey)}.`;
|
|
204
207
|
}
|
|
205
208
|
|
|
206
|
-
if (
|
|
209
|
+
if (credentials['sm_url']) {
|
|
207
210
|
throw `Service key credentials are matching to a Service Manager instance of a multitenant environment. Make sure there is no conflict with ${cfServiceInstanceKey}.`;
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
const fields = ['schema', 'user', 'password', 'url'];
|
|
211
214
|
for (const field of fields) {
|
|
212
|
-
if (!
|
|
215
|
+
if (!credentials[field]) {
|
|
213
216
|
throw `Service key is missing mandatory field '${field}'. Make sure you are ${bold('not')} using a managed service.`;
|
|
214
217
|
}
|
|
215
218
|
}
|
|
@@ -266,17 +269,17 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
|
|
|
266
269
|
}
|
|
267
270
|
|
|
268
271
|
|
|
269
|
-
_injectTunnelAddress(
|
|
272
|
+
_injectTunnelAddress(credentials, tunnelAddress) {
|
|
270
273
|
if (!/\w+:\d+/.test(tunnelAddress)) {
|
|
271
274
|
throw `Invalid tunnel address '${tunnelAddress}' - must be in form 'host:port'`;
|
|
272
275
|
}
|
|
273
276
|
const [tunnelHost, tunnelPort] = tunnelAddress.split(':')
|
|
274
|
-
const { host, port } =
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return
|
|
277
|
+
const { host, port } = credentials
|
|
278
|
+
credentials.host = tunnelHost
|
|
279
|
+
credentials.port = tunnelPort
|
|
280
|
+
credentials.url = credentials.url.replace(`${host}:${port}`, tunnelAddress)
|
|
281
|
+
credentials.hostname_in_certificate = host // make cert. verification happy, see xs2/hdideploy.js#527
|
|
282
|
+
credentials.url = credentials.url + (credentials.url.includes('?') ? '&' : '?') + 'hostNameInCertificate=' + host
|
|
283
|
+
return credentials
|
|
281
284
|
}
|
|
282
285
|
}
|