@sap/cds-dk 7.9.6 → 8.0.3
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 +2136 -0
- package/bin/add.js +18 -52
- package/bin/bind.js +2 -2
- package/bin/build.js +29 -4
- package/bin/cds.js +31 -14
- 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 +13 -14
- 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 +4 -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 +69 -56
- package/lib/build/provider/hana/template/package.json +4 -3
- package/lib/build/provider/internalBuildPlugin.js +32 -97
- package/lib/build/provider/internalBuildTaskProvider.js +12 -48
- 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/provider/nodejs/index.js +4 -3
- 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 +21 -11
- 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 -20
- 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/{redis-messaging → audit-logging}/files/mta.yaml.hbs +4 -4
- 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 +31 -1
- package/lib/init/template/destination/files/package.sidecar.json +7 -0
- package/lib/init/template/destination/index.js +22 -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 +14 -33
- package/lib/init/template/html5-repo/files/package.sidecar.json +7 -0
- 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 +6 -7
- package/lib/init/template/html5-repo/index.js +41 -35
- 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/files/mta.yaml.hbs +25 -0
- package/lib/init/template/redis/files/package.json.hbs +5 -0
- package/lib/init/template/redis/index.js +44 -0
- package/lib/init/template/redis-messaging/files/package.json.hbs +0 -3
- package/lib/init/template/redis-messaging/index.js +8 -18
- 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 +9 -0
- package/lib/init/template/workzone-standard/files/manifest.json.hbs +6 -0
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +59 -0
- package/lib/init/template/workzone-standard/index.js +46 -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 +225 -1083
- 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
|
@@ -1,42 +1,33 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../../cds')
|
|
4
|
-
const
|
|
5
|
-
const { hasOptionValue } = require('../util')
|
|
6
|
-
const { FOLDER_GEN } = require('../constants')
|
|
4
|
+
const Plugin = require('../plugin')
|
|
5
|
+
const { hasOptionValue, getFiles } = require('../util')
|
|
6
|
+
const { FOLDER_GEN, DEFAULT_BUILTIN_PRIORITY_MAX } = require('../constants')
|
|
7
7
|
|
|
8
|
-
class InternalBuildPlugin extends
|
|
8
|
+
class InternalBuildPlugin extends Plugin {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
* ensure
|
|
10
|
+
* By default custom build plugins are executed before internal build plugins
|
|
11
|
+
* to ensure built-in plugin content isn't overwritten by mistake.
|
|
12
12
|
*/
|
|
13
13
|
get priority() {
|
|
14
|
-
return
|
|
14
|
+
return DEFAULT_BUILTIN_PRIORITY_MAX / 2
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
init() {
|
|
17
|
+
init() {
|
|
18
18
|
// REVISIT: no default gen folder for now
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async clean() {
|
|
22
|
+
function _isSubDirectory(parent, child) {
|
|
23
|
+
return !path.relative(parent, child).startsWith('..')
|
|
24
|
+
}
|
|
22
25
|
// build results are deleted by the BuildTaskEngine if the build.target !== '.'
|
|
23
26
|
// make sure that src is not a subfolder of dest
|
|
24
|
-
if (cds.env.build.target === '.' && this.task.src !== this.task.dest && !
|
|
27
|
+
if (cds.env.build.target === '.' && this.task.src !== this.task.dest && !_isSubDirectory(this.task.dest, this.task.src)) {
|
|
25
28
|
await fs.promises.rm(this.task.dest, { force: true, recursive: true })
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Maximum allowed priority for internal build tasks.
|
|
30
|
-
*/
|
|
31
|
-
static get PRIORITY_MAX_VALUE() {
|
|
32
|
-
return 0;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Minimum allowed priority for custom build tasks.
|
|
36
|
-
*/
|
|
37
|
-
static get PRIORITY_MIN_VALUE() {
|
|
38
|
-
return Number.MIN_SAFE_INTEGER;
|
|
39
|
-
}
|
|
40
31
|
|
|
41
32
|
/**
|
|
42
33
|
* Called by the framework after {@link #init()}, used to perform more elaborate preparation.
|
|
@@ -52,16 +43,6 @@ class InternalBuildPlugin extends BuildPlugin {
|
|
|
52
43
|
return false
|
|
53
44
|
}
|
|
54
45
|
|
|
55
|
-
/**
|
|
56
|
-
* Returns whether cds env has a property with the specified value.
|
|
57
|
-
* If the value is omitted the existence of the given property name is checked.
|
|
58
|
-
* @param {string} qualifiedName
|
|
59
|
-
* @param {any=} value
|
|
60
|
-
*/
|
|
61
|
-
hasCdsEnvOption(qualifiedName, value) {
|
|
62
|
-
return hasOptionValue(cds.env.get(qualifiedName), value)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
46
|
/**
|
|
66
47
|
* Determines whether the given build option value has been set for this build task.
|
|
67
48
|
* If the value is omitted, the existence of the given property name is checked.
|
|
@@ -80,14 +61,6 @@ class InternalBuildPlugin extends BuildPlugin {
|
|
|
80
61
|
return super._getBuildOption(qualifiedName)
|
|
81
62
|
}
|
|
82
63
|
|
|
83
|
-
/**
|
|
84
|
-
* Returns a list of CDS model files defining the transitive closure of the CDS model based on the model options
|
|
85
|
-
* defined for this build task.
|
|
86
|
-
*/
|
|
87
|
-
resolveModel() {
|
|
88
|
-
return this._resolveModel()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
64
|
/**
|
|
92
65
|
* Returns whether the build results of this build plugin are created inplace
|
|
93
66
|
* or in a separate staging folder which is not part of the build tasks src folder.
|
|
@@ -97,13 +70,30 @@ class InternalBuildPlugin extends BuildPlugin {
|
|
|
97
70
|
}
|
|
98
71
|
|
|
99
72
|
async copyNativeContent(srcDir, destDir, customFilter) {
|
|
100
|
-
|
|
73
|
+
function commonStagingBuildFilter(src, destDir) {
|
|
74
|
+
if (typeof src !== "string" || typeof destDir !== "string") {
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
if (!fs.statSync(src).isDirectory()) {
|
|
78
|
+
return true //file
|
|
79
|
+
}
|
|
80
|
+
if (src === destDir) {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
const regex = new RegExp(FOLDER_GEN + "\\b")
|
|
84
|
+
if (src === path.resolve(cds.root, cds.env.build.target)) {
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
return !regex.exec(path.basename(src))
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const files = getFiles(srcDir, (src) => {
|
|
101
91
|
// do not copy files that:
|
|
102
92
|
// - from 'cds.env.build.target'
|
|
103
93
|
// - from 'dest'
|
|
104
94
|
// - from some generation folder
|
|
105
|
-
// - do not match filter function
|
|
106
|
-
return
|
|
95
|
+
// - do not match filter function ,
|
|
96
|
+
return commonStagingBuildFilter(src, destDir) && (!customFilter || customFilter.call(this, src))
|
|
107
97
|
})
|
|
108
98
|
return Promise.all(
|
|
109
99
|
files.map((srcFile) => {
|
|
@@ -165,60 +155,5 @@ class InternalBuildPlugin extends BuildPlugin {
|
|
|
165
155
|
}
|
|
166
156
|
return null
|
|
167
157
|
}
|
|
168
|
-
|
|
169
|
-
_isSubDirectory(parent, child) {
|
|
170
|
-
return !path.relative(parent, child).startsWith('..')
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
_commonStagingBuildFilter(src, destDir) {
|
|
174
|
-
if (typeof src !== "string" || typeof destDir !== "string") {
|
|
175
|
-
return false
|
|
176
|
-
}
|
|
177
|
-
if (!fs.statSync(src).isDirectory()) {
|
|
178
|
-
return true //file
|
|
179
|
-
}
|
|
180
|
-
if (src === destDir) {
|
|
181
|
-
return false
|
|
182
|
-
}
|
|
183
|
-
const regex = new RegExp(FOLDER_GEN + "\\b")
|
|
184
|
-
if (src === path.resolve(cds.root, cds.env.build.target)) {
|
|
185
|
-
return false
|
|
186
|
-
}
|
|
187
|
-
return !regex.exec(path.basename(src))
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
static _find(srcDir, filter) {
|
|
191
|
-
const files = []
|
|
192
|
-
this._traverseFileSystem(srcDir, files, filter)
|
|
193
|
-
return files;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
static _traverseFileSystem(srcDir, files, filter) {
|
|
197
|
-
let entries = []
|
|
198
|
-
try {
|
|
199
|
-
entries = fs.readdirSync(srcDir)
|
|
200
|
-
} catch (e) {
|
|
201
|
-
// ignore if not existing
|
|
202
|
-
}
|
|
203
|
-
entries.map(subDirEntry => path.join(srcDir, subDirEntry)).forEach((entry) => {
|
|
204
|
-
this._handleResource(entry, files, filter)
|
|
205
|
-
})
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
static _handleResource(entry, files, filter) {
|
|
209
|
-
if (!filter || filter.call(this, entry)) {
|
|
210
|
-
var stats = this._getResourceStatus(entry)
|
|
211
|
-
if (stats.isDirectory()) {
|
|
212
|
-
this._traverseFileSystem(entry, files, filter)
|
|
213
|
-
} else if (stats.isFile() || stats.isSymbolicLink()) {
|
|
214
|
-
files.push(entry)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// for testing purposes
|
|
220
|
-
static _getResourceStatus(entry) {
|
|
221
|
-
return fs.lstatSync(entry)
|
|
222
|
-
}
|
|
223
158
|
}
|
|
224
159
|
module.exports = InternalBuildPlugin
|
|
@@ -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
|
-
|
|
8
|
-
IGNORE_DEFAULT_MODELS,
|
|
7
|
+
BUILD_TASKS, BUILD_TASK_MTX_SIDECAR, MTX_SIDECAR_FOLDER, BUILD_TASK_MTX_EXTENSION, NODEJS_MODEL_EXCLUDE_LIST,
|
|
8
|
+
IGNORE_DEFAULT_MODELS, OPTION_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
|
-
const ws = hasOptionValue(task.options?.[
|
|
288
|
+
const ws = hasOptionValue(task.options?.[OPTION_WS], true) || cds.cli.options?.[OPTION_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()
|
|
@@ -5,7 +5,8 @@ const cmd = require('../../../util/command');
|
|
|
5
5
|
const EdmxBuildPlugin = require('../edmxBuildPlugin')
|
|
6
6
|
const { BuildError, getWorkspaces } = require('../../util')
|
|
7
7
|
const { OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM, ODATA_VERSION_V2, FOLDER_GEN, CONTENT_EDMX, CONTENT_PACKAGELOCK_JSON,
|
|
8
|
-
CONTENT_NPMRC, CONTENT_CDSRC_JSON, CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, FLAVOR_LOCALIZED_EDMX
|
|
8
|
+
CONTENT_NPMRC, CONTENT_CDSRC_JSON, CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, FLAVOR_LOCALIZED_EDMX,
|
|
9
|
+
OPTION_WS_PACK} = require('../../constants')
|
|
9
10
|
const { WARNING } = EdmxBuildPlugin
|
|
10
11
|
const DEBUG = cds.debug('cli|build')
|
|
11
12
|
|
|
@@ -36,7 +37,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
|
|
|
36
37
|
}
|
|
37
38
|
// by default model contains all features
|
|
38
39
|
const model = await this.model()
|
|
39
|
-
if (!model && !this.context.options[
|
|
40
|
+
if (!model && !this.context.options[OPTION_WS_PACK]) {
|
|
40
41
|
return
|
|
41
42
|
}
|
|
42
43
|
if (model) {
|
|
@@ -55,7 +56,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
|
|
|
55
56
|
if (this.isStagingBuild() && this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM)) {
|
|
56
57
|
const srcSrv = this.task.src === cds.root ? path.resolve(this.task.src, cds.env.folders.srv) : this.task.src
|
|
57
58
|
await this._copyNativeContent(cds.root, srcSrv, destRoot, destSrv)
|
|
58
|
-
if (this.context.options[
|
|
59
|
+
if (this.context.options[OPTION_WS_PACK]) {
|
|
59
60
|
await this._packWorkspaceDependencies(destRoot)
|
|
60
61
|
}
|
|
61
62
|
}
|
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
|
+
}
|