@sap/cds-dk 9.4.3 → 9.6.0
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 +115 -0
- package/bin/compile/index.js +1 -1
- package/bin/env.js +3 -3
- package/bin/export.js +1 -1
- package/bin/help.js +0 -1
- package/bin/import.js +8 -3
- package/bin/repl.js +7 -11
- package/bin/up.js +159 -23
- package/bin/util/containerize.js +79 -25
- package/bin/version.js +4 -4
- package/lib/bind/k8s.js +1 -1
- package/lib/build/plugins/helm/files/templates/_deployment_helpers.tpl +1 -1
- package/lib/build/plugins/helm/index.js +1 -1
- package/lib/build/provider/hana/2migration.js +16 -24
- package/lib/build/provider/hana/index.js +1 -1
- package/lib/build/provider/hana/template/.hdiconfig-all +7 -1
- package/lib/build/provider/hana/template/package.json +1 -1
- package/lib/build/provider/internalBuildPlugin.js +15 -1
- package/lib/build/provider/java/index.js +12 -1
- package/lib/build/provider/mtx-sidecar/index.js +2 -1
- package/lib/build/provider/nodejs/index.js +2 -1
- package/lib/build/util.js +36 -19
- package/lib/compile/to_openapi.js +1 -5
- package/lib/import/common.js +9 -2
- package/lib/import/odata/ParserContext.js +1 -0
- package/lib/import/odata/v4parser.js +57 -25
- package/lib/import/openapi/importOpenAPI.js +6 -1
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +20 -6
- package/lib/init/merge.js +16 -0
- package/lib/init/projectReader.js +34 -8
- package/lib/init/registries/mta.js +2 -2
- package/lib/init/template/ams/index.js +3 -3
- package/lib/init/template/app-frontend/files/app-package.json.hbs +1 -7
- package/lib/init/template/app-frontend/files/ui5.yaml.hbs +21 -1
- package/lib/init/template/app-frontend/index.js +2 -6
- package/lib/init/template/application-logging/index.js +11 -16
- package/lib/init/template/approuter/files/mta.yaml.hbs +0 -2
- package/lib/init/template/approuter/index.js +13 -10
- package/lib/init/template/attachments/index.js +4 -2
- package/lib/init/template/audit-logging/index.js +4 -2
- package/lib/init/template/cloud-logging/index.js +6 -5
- package/lib/init/template/connectivity/index.js +2 -2
- package/lib/init/template/console/files/package.json +5 -0
- package/lib/init/template/console/index.js +25 -0
- package/lib/init/template/containerize/index.js +4 -6
- package/lib/init/template/data/as-json.js +18 -20
- package/lib/init/template/destination/index.js +4 -2
- package/lib/init/template/dynatrace/files/package.json.hbs +2 -2
- package/lib/init/template/dynatrace/index.js +4 -4
- package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +3 -1
- package/lib/init/template/enterprise-messaging/index.js +4 -2
- package/lib/init/template/enterprise-messaging-shared/index.js +4 -2
- package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +16 -1
- package/lib/init/template/github-actions/files/workflows/release.yaml.hbs +2 -2
- package/lib/init/template/github-actions/files/workflows/test.yaml.hbs +20 -0
- package/lib/init/template/github-actions/index.js +7 -10
- package/lib/init/template/hana/files/db/package.json +2 -2
- package/lib/init/template/hana/files/mta.yaml.hbs +0 -4
- package/lib/init/template/hana/index.js +7 -9
- package/lib/init/template/helm/index.js +8 -10
- package/lib/init/template/helm-unified-runtime/index.js +1 -4
- package/lib/init/template/html5-repo/files/app-package.json.hbs +1 -7
- package/lib/init/template/html5-repo/files/ui5.yaml.hbs +21 -1
- package/lib/init/template/html5-repo/index.js +14 -18
- package/lib/init/template/ias/files/values.yaml.hbs +6 -6
- package/lib/init/template/ias/index.js +13 -21
- package/lib/init/template/java/index.js +14 -0
- package/lib/init/template/kafka/index.js +4 -2
- package/lib/init/template/{containerize → kyma}/files/containerize.yaml.hbs +17 -2
- package/lib/init/template/kyma/index.js +129 -5
- package/lib/init/template/malware-scanner/files/mta.yaml.hbs +3 -1
- package/lib/init/template/malware-scanner/files/values.yaml +3 -1
- package/lib/init/template/malware-scanner/index.js +4 -2
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +1 -3
- package/lib/init/template/multitenancy/files/values.yaml.hbs +8 -0
- package/lib/init/template/multitenancy/index.js +15 -7
- package/lib/init/template/nodejs/files/.vscode/extensions.json +0 -3
- package/lib/init/template/nodejs/files/package.json.hbs +1 -1
- package/lib/init/template/pipeline/files/app-package.json.hbs +1 -7
- package/lib/init/template/pipeline/files/ui5.yaml.hbs +21 -1
- package/lib/init/template/pipeline/index.js +1 -2
- package/lib/init/template/portal/files/mta.yaml.hbs +5 -3
- package/lib/init/template/portal/index.js +8 -8
- package/lib/init/template/postgres/index.js +2 -2
- package/lib/init/template/redis/index.js +2 -3
- package/lib/init/template/redis-messaging/index.js +2 -3
- package/lib/init/template/sample/files/_i18n/i18n_de.properties +21 -0
- package/lib/init/template/sample/files/_i18n/i18n_en.properties +21 -0
- package/lib/init/template/sample/files/_i18n/i18n_fr.properties +21 -0
- package/lib/init/template/sample/files/_i18n/messages_de.properties +34 -0
- package/lib/init/template/sample/files/_i18n/messages_en.properties +34 -0
- package/lib/init/template/sample/files/_i18n/messages_fr.properties +34 -0
- package/lib/init/template/sample/files/app/_i18n/i18n.properties +13 -25
- package/lib/init/template/sample/files/app/_i18n/i18n_de.properties +13 -25
- package/lib/init/template/sample/files/app/admin-authors/fiori-service.cds +52 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/i18n/i18n.properties +3 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/i18n/i18n_de.properties +3 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/i18n/i18n_en.properties +3 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/manifest.json +130 -0
- package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +81 -88
- package/lib/init/template/sample/files/app/admin-books/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n.properties +3 -3
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_de.properties +3 -3
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_en.properties +3 -3
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +24 -48
- package/lib/init/template/sample/files/app/appconfig/fioriSandboxConfig.json +56 -5
- package/lib/init/template/sample/files/app/browse/fiori-service.cds +30 -30
- package/lib/init/template/sample/files/app/browse/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n.properties +3 -4
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_de.properties +3 -3
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_en.properties +3 -4
- package/lib/init/template/sample/files/app/browse/webapp/manifest.json +19 -24
- package/lib/init/template/sample/files/app/common.cds +127 -158
- package/lib/init/template/sample/files/app/fiori-apps.html +50 -0
- package/lib/init/template/sample/files/app/genres/fiori-service.cds +33 -0
- package/lib/init/template/sample/files/app/genres/tree-view.cds +42 -0
- package/lib/init/template/sample/files/app/genres/value-help.cds +6 -0
- package/lib/init/template/sample/files/app/genres/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/genres/webapp/i18n/i18n.properties +3 -0
- package/lib/init/template/sample/files/app/genres/webapp/i18n/i18n_de.properties +3 -0
- package/lib/init/template/sample/files/app/genres/webapp/i18n/i18n_en.properties +3 -0
- package/lib/init/template/sample/files/app/genres/webapp/manifest.json +126 -0
- package/lib/init/template/sample/files/app/services.cds +6 -2
- package/lib/init/template/sample/files/db/currencies.cds +13 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +5 -5
- package/lib/init/template/sample/files/db/data/{sap.capire.bookshop-Books_texts.csv → sap.capire.bookshop-Books.texts.csv} +4 -4
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +42 -15
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.texts.csv +43 -0
- package/lib/init/template/sample/files/db/data/sap.common-Currencies.csv +12 -0
- package/lib/init/template/sample/files/db/data/sap.common-Currencies.texts.csv +15 -0
- package/lib/init/template/sample/files/db/hana/index.cds +10 -0
- package/lib/init/template/sample/files/db/schema.cds +35 -22
- package/lib/init/template/sample/files/db/sqlite/index.cds +10 -0
- package/lib/init/template/sample/files/package.json.hbs +14 -1
- package/lib/init/template/sample/files/srv/access-control.cds +3 -0
- package/lib/init/template/sample/files/srv/admin-service.cds +3 -2
- package/lib/init/template/sample/files/srv/cat-service.cds +7 -11
- package/lib/init/template/sample/index.js +40 -18
- package/lib/init/template/sqlite/files/package.json.hbs +13 -0
- package/lib/init/template/sqlite/index.js +1 -1
- package/lib/init/template/telemetry/index.js +1 -3
- package/lib/init/template/typescript/files/package.json +1 -1
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +0 -5
- package/lib/init/template/workzone-standard/index.js +0 -1
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +4 -0
- package/lib/init/template/xsuaa/index.js +7 -6
- package/lib/lint/Linter.js +10 -4
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/mtx/tenant_action.js +12 -4
- package/lib/util/checksum.js +41 -0
- package/lib/util/fs.js +8 -1
- package/lib/util/glob.js +26 -13
- package/lib/util/question.js +60 -7
- package/npm-shrinkwrap.json +141 -118
- package/package.json +2 -2
- package/lib/init/template/app-frontend/files/ui5-deploy.yaml.hbs +0 -25
- package/lib/init/template/github-actions/files/cf-setup/action.yaml +0 -53
- package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +0 -25
- package/lib/init/template/pipeline/files/ui5-deploy.yaml.hbs +0 -25
- package/lib/init/template/sample/files/app/admin-books/webapp/Component.js +0 -8
- package/lib/init/template/sample/files/app/browse/webapp/Component.js +0 -7
- package/lib/init/template/sample/files/app/index.html +0 -32
- package/lib/init/template/sqlite/files/package.json +0 -5
- /package/lib/init/template/{helm → kyma}/files/Chart.yaml.hbs +0 -0
- /package/lib/init/template/{helm → kyma}/files/values.schema.json +0 -0
- /package/lib/init/template/{helm → kyma}/files/values.yaml.hbs +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,17 +6,87 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
8
8
|
|
|
9
|
+
## Version 9.6.0 - 2025-12-16
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `cds add console` adds dependency to the CAP console plugin.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `cds import` no longer generates a first parameter typed as `$self` to bound actions, as this parameter is implicit.
|
|
18
|
+
- `cds add` sets `relativePaths: true` for generated UI5 apps to avoid deployment issues if UI5 data sources start with a "/".
|
|
19
|
+
- `cds up` automatically detects the preferred platform.
|
|
20
|
+
- Added deprecation notices for the following commands in favor of using `cds add kyma`:
|
|
21
|
+
- `cds add containerize`
|
|
22
|
+
- `cds add helm`
|
|
23
|
+
- `cds add helm-unified-runtime`
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- `cds build --ws-pack` now checks folder depth of up to 5.
|
|
28
|
+
- `cds import --config param1=true,param2=0` now writes boolean and number values correctly to `package.json`.
|
|
29
|
+
- `cds add sample` sets the correct UI component in _\_appconfig/fioriSandboxConfig.json_.
|
|
30
|
+
- `cds add xsuaa` correctly adds the authentication binding to the application deployer if executed afterwards.
|
|
31
|
+
- `cds env` prints coloured output by default again.
|
|
32
|
+
- `cds add java` will preserve existing _package.json_ settings.
|
|
33
|
+
- `cds add multitenancy` now correctly adds a `devDependencies` section when missing.
|
|
34
|
+
- `cds add mta` adds fixes an issue where a faulty XSUAA instance was added with `messaging: true` configured.
|
|
35
|
+
- `cds add sqlite --for production` correctly activates SQLite for production, not just development.
|
|
36
|
+
- `cds up -2 k8s` correctly runs `before_all` before the checksum calculation to calculate against the correct artifact.
|
|
37
|
+
|
|
38
|
+
## Version 9.5.0 - 2025-12-01
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- `cds import` now accepts `--into-namespace <string>` to override the namespace entities are imported to, when importing OpenAPI definitions.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- `cds add portal` adds the correct service key configuration to the _mta.yaml_.
|
|
47
|
+
- `cds add sample` creates sample files aligned with recent versions of bookshop and bookstore in https://github.com/capire.
|
|
48
|
+
- `cds add sample` uses a matching ID in generated `manifest.json` and UI5 components.
|
|
49
|
+
- `cds build` uses `hdblogicalschema` and `hdblogicalschemaconfig` plugins in its default `.hdiconfig`.
|
|
50
|
+
- `cds add cloud-logging` adds required dependencies to _pom.xml_ for Java projects.
|
|
51
|
+
- `cds add kyma` is now the only suggested Kyma facet in `cds add help`.
|
|
52
|
+
- `cds add helm-unified-runtime` option is now deprecated; use `cds add kyma --unified-runtime` instead.
|
|
53
|
+
- `cds up --to k8s` now saves the checksum of buildpack images to determine if a rebuild is necessary.
|
|
54
|
+
- `cds up --to k8s` will interactively ask for registry credentials if they don't exist on the remote cluster.
|
|
55
|
+
- `cds build` automatically adds `contentLocalizedEdmx=true` to the java build task configuration if OData V2 is set.
|
|
56
|
+
- `cds add github-actions` has out-of-the-box support for Java projects.
|
|
57
|
+
- `cds add html5-repo` and `cds add app-frontend` do not create a separate _ui5-deploy.yaml_ but use the default _ui5.yaml_.
|
|
58
|
+
- `cds add` plugins allow merging into non-existing files with `cds.add.merge(<object>).into(<yaml-path>)`.
|
|
59
|
+
- `cds build` tasks that produce `csn.json` now emit the `compile.for.runtime` event, in alignment with other runtime CSN producers like `cds serve`. Plugins can use such events to hook into CSN creation.
|
|
60
|
+
- `cds add xsuaa` sets `credential-types: [ "binding-secret", "x509" ]` for XSUAA instances.
|
|
61
|
+
- `cds add hana` does not create an explicit `.hdiconfig` file any more as `cds build` provides defaults.
|
|
62
|
+
- `cds import` generates the on condition for a composition when the corresponding OData navigation property targets a collection, is contained (`$ContainsTarget` in OData EDM) and has a backlink (`$Partner` in OData EDM).
|
|
63
|
+
- `cds import` now considers OData contained navigation properties as compositions instead of associations.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- `cds add ias` will always add a binding to the MTX sidecar or approuter if required.
|
|
68
|
+
- `cds add ias` has improved support for multitenancy scenarios on Kyma.
|
|
69
|
+
- `cds lint` no longer fails with error code 1 and no message when loading the config fails.
|
|
70
|
+
- `cds version` no longer prints an `undefined` value for `@sap/cds-dk`.
|
|
71
|
+
- `cds compile --flavor files` no longer crashes with a `TypeError`.
|
|
72
|
+
- `cds add workzone` does not add superfluous `destinations` configuration to the `srv-api` import.
|
|
73
|
+
|
|
9
74
|
## Version 9.4.3 - 2025-10-29
|
|
10
75
|
|
|
76
|
+
### Added
|
|
77
|
+
|
|
11
78
|
### Changed
|
|
12
79
|
|
|
80
|
+
- `cds add github-actions` will use the `cap-js/cf-setup` action from GitHub marketplace instead of creating a local copy.
|
|
13
81
|
- `cds add containerize` omits the Unix-based `before_all` scripts in `containerize.yaml` in favor of a cross-platform compatible `cds up --to k8s` integration.
|
|
14
82
|
- `cds up --to k8s` now uses built-in containerization, eliminating the hard dependency on the `ctz` library.
|
|
15
83
|
- `cds up --to k8s` will interactively ask for a domain if it can't be determined from the current Kubernetes configuration.
|
|
16
84
|
- `cds build --for hana` no longer requires `.hdbgrants` and `.hdbrevokes` to be specified as a plugin in the `.hdiconfig` file.
|
|
85
|
+
- `cds import` no longer emits usage info when invoked with the dry option.
|
|
17
86
|
|
|
18
87
|
### Fixed
|
|
19
88
|
|
|
89
|
+
- `cds add data` fixes an issue where randomly generated `Decimal` and `Integer` values could exceed their defined precision or scale.
|
|
20
90
|
- `cds add pipeline` does not add UI5 template files in some cases.
|
|
21
91
|
- `cds add ias` does not write to the `mta.yaml` for non-MTA projects.
|
|
22
92
|
- `cds add ias` automatically adds the `authenticationType` to `xs-app.json` if required.
|
|
@@ -40,6 +110,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
|
40
110
|
- `cds add test` creates correct OData URLs with unqualified entity names in service paths.
|
|
41
111
|
- `cds add http` skips contained composition targets.
|
|
42
112
|
- `cds add sample` no longer comes with an error when creating a Book through Fiori.
|
|
113
|
+
- `cds build` now places the `i18n` folder in the generated output root directory instead of nested locations.
|
|
43
114
|
|
|
44
115
|
## Version 9.4.1 - 2025-10-09
|
|
45
116
|
|
|
@@ -331,6 +402,50 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
|
331
402
|
- `cds add multitenancy` requires the `srv-api` instead of the `mtx-api` for Java projects.
|
|
332
403
|
|
|
333
404
|
|
|
405
|
+
## Version 8.9.12 - 2025-12-16
|
|
406
|
+
|
|
407
|
+
### Fixed
|
|
408
|
+
|
|
409
|
+
- `cds import` generates the on condition for a composition when the corresponding OData navigation property targets a collection, is contained (`$ContainsTarget` in OData EDM) and has a backlink (`$Partner` in OData EDM).
|
|
410
|
+
- `cds import` now considers OData contained navigation properties as compositions instead of associations.
|
|
411
|
+
- Support for `hdb` v2.
|
|
412
|
+
|
|
413
|
+
## Version 8.9.11 - 2025-11-21
|
|
414
|
+
|
|
415
|
+
### Fixed
|
|
416
|
+
|
|
417
|
+
- Bump dependencies in shrinkwrap.
|
|
418
|
+
|
|
419
|
+
## Version 8.9.10 - 2025-09-19
|
|
420
|
+
|
|
421
|
+
### Fixed
|
|
422
|
+
|
|
423
|
+
- Updated shrinkwrap to include `@sap/cds-compiler` version 5.9.12.
|
|
424
|
+
|
|
425
|
+
## Version 8.9.9 - 2025-09-16
|
|
426
|
+
|
|
427
|
+
### Fixed
|
|
428
|
+
|
|
429
|
+
- CVE-2025-58754: vulnerability with `axios` versions <1.12.0.
|
|
430
|
+
|
|
431
|
+
## Version 8.9.8 - 2025-07-24
|
|
432
|
+
|
|
433
|
+
### Fixed
|
|
434
|
+
|
|
435
|
+
- CVE-2025-7783: vulnerability with `form-data` versions <4.0.4.
|
|
436
|
+
|
|
437
|
+
## Version 8.9.7 - 2025-07-17
|
|
438
|
+
|
|
439
|
+
### Fixed
|
|
440
|
+
|
|
441
|
+
- Bump dependencies in shrinkwrap.
|
|
442
|
+
|
|
443
|
+
## Version 8.9.6 - 2025-06-05
|
|
444
|
+
|
|
445
|
+
### Fixed
|
|
446
|
+
|
|
447
|
+
- Bump dependencies in shrinkwrap.
|
|
448
|
+
|
|
334
449
|
## Version 8.9.5 - 2025-06-05
|
|
335
450
|
|
|
336
451
|
### Fixed
|
package/bin/compile/index.js
CHANGED
|
@@ -297,7 +297,7 @@ async function compile (models, options={}) {
|
|
|
297
297
|
throw `You must specify a model to compile.\nRun 'cds c -?' to learn more.`
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
let chain = model.then (m => model=m)
|
|
300
|
+
let chain = model.then?. (m => model=m) ?? Promise.resolve(model) // model could be a sync. value
|
|
301
301
|
|
|
302
302
|
// add processors for compiling
|
|
303
303
|
if (options.for) for (let each of options.for.split(',')) {
|
package/bin/env.js
CHANGED
|
@@ -67,12 +67,12 @@ async function env ([cmd, key, value], options={}) {
|
|
|
67
67
|
env['_home_cds-dk'] = path.resolve(__dirname, '..') // to help tools find the DK
|
|
68
68
|
|
|
69
69
|
if (!options.for && options.mocked) await cds.service.bindings
|
|
70
|
+
options.colors = cds.utils.colors.enabled === true
|
|
70
71
|
return fn (env, key, value, options)
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
const { inspect, format } = require('node:util')
|
|
75
|
-
const {colors} = require('../lib/util/term')
|
|
76
76
|
const commands = {
|
|
77
77
|
|
|
78
78
|
json: (env,k,v,o) => commands.get (env,k,v,{...o,json:true}),
|
|
@@ -88,7 +88,7 @@ const commands = {
|
|
|
88
88
|
},
|
|
89
89
|
|
|
90
90
|
get (conf, key, val, options) {
|
|
91
|
-
let fmt = x => inspect (x, {depth:22, colors})
|
|
91
|
+
let fmt = x => inspect (x, { depth:22, colors: true })
|
|
92
92
|
|
|
93
93
|
let obj = (
|
|
94
94
|
!key ? conf
|
|
@@ -97,7 +97,7 @@ const commands = {
|
|
|
97
97
|
: conf.get(key.replace(/^cds\./,''))
|
|
98
98
|
)
|
|
99
99
|
|
|
100
|
-
if (
|
|
100
|
+
if (options.colors === false) {
|
|
101
101
|
fmt = x => typeof x !== 'object' ? x : JSON.stringify(x,0,2)
|
|
102
102
|
}
|
|
103
103
|
if (options.json) {
|
package/bin/export.js
CHANGED
|
@@ -111,7 +111,7 @@ class Export extends Minify {
|
|
|
111
111
|
async export (minified,o) {
|
|
112
112
|
if (this.options.to === '-') return super.print (minified)
|
|
113
113
|
if (this.options.to.endsWith('/*')) this.options.to = this.export_to()
|
|
114
|
-
console.log(`\n${this.name}ing APIs to`, this.options.to, '...\n')
|
|
114
|
+
console.log(`\n${this.name}ing APIs to`, cds.utils.local(this.options.to), '...\n')
|
|
115
115
|
const exports = []; exports.push(...this.export_models (minified))
|
|
116
116
|
if (o.texts) exports.push (...this.export_texts (minified))
|
|
117
117
|
if (o.data) exports.push (this.export_data (minified))
|
package/bin/help.js
CHANGED
|
@@ -12,7 +12,6 @@ module.exports = exports = Object.assign (help, {formatHelp, handleCompletion, h
|
|
|
12
12
|
|
|
13
13
|
*i* | *init* jump-start cds-based projects
|
|
14
14
|
*a* | *add* add a feature to an existing project
|
|
15
|
-
* * | *gen* generate models/data using a descriptive prompt [beta]
|
|
16
15
|
*m* | *import* add models from external sources
|
|
17
16
|
*c* | *compile* compile cds models to different outputs
|
|
18
17
|
*p* | *parse* parses given cds models
|
package/bin/import.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module.exports = Object.assign(_import, {
|
|
2
2
|
_name: 'import',
|
|
3
|
-
options: [ '--services', '--for', '--out', '--as', '--name', '--include-namespaces', '--dependencies', '--from', '--config', '--destination', '--group', '--data-product' ],
|
|
4
|
-
shortcuts: [ '-s',
|
|
3
|
+
options: [ '--services', '--for', '--out', '--as', '--name', '--include-namespaces', '--dependencies', '--from', '--config', '--destination', '--group', '--into-namespace', '--data-product' ],
|
|
4
|
+
shortcuts: [ '-s', '-4', '-o', '-as', '-n', '-ns', '-d',undefined, '-c', undefined, undefined, '-2', '-', '-f'],
|
|
5
5
|
flags: [ '--dry', '--force', '--no-copy', '--no-save', '--keep-namespace', '--data-product', '--edmx', '--rfc', '--odata', '--openapi', '--asyncapi' ],
|
|
6
6
|
help: `
|
|
7
7
|
# SYNOPSIS
|
|
@@ -56,10 +56,15 @@ module.exports = Object.assign(_import, {
|
|
|
56
56
|
Not supported by import types "edmx", "openapi" or "asyncapi".
|
|
57
57
|
|
|
58
58
|
*--data-product*
|
|
59
|
-
Tells cds import to import a data product. The source must be a valid
|
|
59
|
+
Tells cds import to import a data product. The source must be a valid
|
|
60
60
|
data product CSN file, e.g. as found on http://api.sap.com/dataproducts.
|
|
61
61
|
(Not released with general availability yet)
|
|
62
62
|
|
|
63
|
+
*-2 | --into-namespace* <string>
|
|
64
|
+
Specifies a custom namespace to be used for the imported service.
|
|
65
|
+
This will override the namespace that was specified via the the
|
|
66
|
+
@title annotation of the original service.
|
|
67
|
+
|
|
63
68
|
*Below options are valid for OData only*
|
|
64
69
|
|
|
65
70
|
*--keep-namespace*
|
package/bin/repl.js
CHANGED
|
@@ -35,7 +35,7 @@ module.exports = Object.assign (repl, {
|
|
|
35
35
|
*cds eval* to evaluate and execute JavaScript.
|
|
36
36
|
`})
|
|
37
37
|
|
|
38
|
-
async function repl (
|
|
38
|
+
async function repl ([project], options={}) {
|
|
39
39
|
|
|
40
40
|
const GREEN = '\x1b[32m', RESET = '\x1b[0m'
|
|
41
41
|
const cds = require('../lib/cds')
|
|
@@ -46,9 +46,9 @@ async function repl (_, options={}) {
|
|
|
46
46
|
inspect.defaultOptions.depth = 11
|
|
47
47
|
|
|
48
48
|
Object.defineProperty (cds,'repl',{value:true})
|
|
49
|
-
await cds.service.bindings
|
|
49
|
+
await cds.service.bindings // REVISIT: this pre-populates many of the cds facade's lazy properties
|
|
50
50
|
let context={}, repl = { context, displayPrompt(){} }
|
|
51
|
-
if (options.run) await _run (options.run)
|
|
51
|
+
if ((options.run ??= project)) await _run (options.run)
|
|
52
52
|
if (options.use) _export (...options.use.split(','))
|
|
53
53
|
|
|
54
54
|
repl = require('repl').start ({
|
|
@@ -94,14 +94,10 @@ async function repl (_, options={}) {
|
|
|
94
94
|
process.on = (event, listener) => event !== 'uncaughtException' && event !== 'unhandledRejection' && process.addListener(event, listener)
|
|
95
95
|
|
|
96
96
|
async function _run (project) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
} catch (e) {
|
|
102
|
-
if (e.code !== 'MODULE_NOT_FOUND') throw e
|
|
103
|
-
await cds.exec ('--project', project, '--port', '0', '--in-memory?')
|
|
104
|
-
}
|
|
97
|
+
await require('../bin/serve') ([project], { project, port: 0,
|
|
98
|
+
'in-memory?': true,
|
|
99
|
+
'with-mocks': true
|
|
100
|
+
})
|
|
105
101
|
_export ('entities', 'services')
|
|
106
102
|
}
|
|
107
103
|
|
package/bin/up.js
CHANGED
|
@@ -13,7 +13,9 @@ module.exports = Object.assign(up, {
|
|
|
13
13
|
|
|
14
14
|
*-2* | *--to* cf|k8s
|
|
15
15
|
|
|
16
|
-
The platform to deploy to.
|
|
16
|
+
The platform to deploy to.
|
|
17
|
+
|
|
18
|
+
Defaults to *k8s* when Helm charts are present and no *mta.yaml* exists, otherwise *cf*.
|
|
17
19
|
|
|
18
20
|
*-n* | *--namespace* <name>
|
|
19
21
|
|
|
@@ -28,28 +30,78 @@ module.exports = Object.assign(up, {
|
|
|
28
30
|
`})
|
|
29
31
|
|
|
30
32
|
const { execSync } = require('node:child_process')
|
|
33
|
+
const { tmpdir } = require('node:os')
|
|
34
|
+
const crypto = require('node:crypto')
|
|
31
35
|
const cds = require('../lib/cds')
|
|
32
|
-
const { highlight } = require('../lib/util/term')
|
|
33
|
-
const { exists, fs, path, path: { join } } = cds.utils
|
|
36
|
+
const { highlight, warn, dim, info } = require('../lib/util/term')
|
|
37
|
+
const { exists, fs, path, path: { join }, read, write } = cds.utils
|
|
38
|
+
const { ask4 } = require('../lib/util/question')
|
|
34
39
|
const { readProject } = require('../lib/init/projectReader')
|
|
35
40
|
const { mkdirp, copy } = cds.utils
|
|
36
41
|
const { containerize } = require('../bin/util/containerize')
|
|
42
|
+
const { calcDirChecksum } = require('../lib/util/checksum')
|
|
43
|
+
|
|
44
|
+
const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) ? console.debug : undefined
|
|
37
45
|
|
|
38
|
-
const run = cmd => {
|
|
39
|
-
|
|
46
|
+
const run = (cmd, { continueOnFail = false, silent = false } = {}) => {
|
|
47
|
+
const redactedCmd = cmd.replace(/(--docker-password=)(['"]?)[^'"\s]+(['"]?)/, '$1[REDACTED]$3')
|
|
48
|
+
console.log(highlight(redactedCmd))
|
|
40
49
|
try {
|
|
41
50
|
return execSync(cmd, {
|
|
42
|
-
stdio: 'inherit',
|
|
51
|
+
stdio: silent ? 'pipe' : 'inherit',
|
|
43
52
|
env: { ...process.env, FORCE_COLOR: cds.utils.colors.enabled }
|
|
44
53
|
})
|
|
45
54
|
} catch (error) {
|
|
55
|
+
if (continueOnFail) {
|
|
56
|
+
if (!silent)
|
|
57
|
+
console.error(error.message)
|
|
58
|
+
return
|
|
59
|
+
}
|
|
46
60
|
throw error.message
|
|
47
61
|
}
|
|
48
62
|
}
|
|
49
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Get or create checksum file path in temp directory for UI5 apps
|
|
66
|
+
* @param {string} appName - The name of the app
|
|
67
|
+
* @returns {string} - Path to checksum file in temp directory
|
|
68
|
+
*/
|
|
69
|
+
function getChecksumFilePath(appName) {
|
|
70
|
+
const projectHash = crypto.createHash('md5').update(cds.root).digest('hex').substring(0, 8)
|
|
71
|
+
return join(tmpdir(), `cds-ui5-checksum-${projectHash}-${appName}.txt`)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Read stored checksum for an app from temp directory
|
|
76
|
+
* @param {string} appName - The name of the app
|
|
77
|
+
* @returns {string|null} - The stored checksum or null if not found
|
|
78
|
+
*/
|
|
79
|
+
function readStoredChecksum(appName) {
|
|
80
|
+
const checksumFile = getChecksumFilePath(appName)
|
|
81
|
+
if (exists(checksumFile)) {
|
|
82
|
+
try {
|
|
83
|
+
return fs.readFileSync(checksumFile, 'utf-8').trim()
|
|
84
|
+
} catch (e) {
|
|
85
|
+
// Ignore read errors and assume no checksum is stored
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return null
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Write checksum for an app to temp directory
|
|
93
|
+
* @param {string} appName - The name of the app
|
|
94
|
+
* @param {string} checksum - The checksum to store
|
|
95
|
+
*/
|
|
96
|
+
function writeStoredChecksum(appName, checksum) {
|
|
97
|
+
const checksumFile = getChecksumFilePath(appName)
|
|
98
|
+
fs.writeFileSync(checksumFile, checksum, 'utf-8')
|
|
99
|
+
}
|
|
100
|
+
|
|
50
101
|
async function up() {
|
|
51
102
|
const project = readProject()
|
|
52
|
-
const { apps, appName, hasApprouter, hasXsuaa, isMonorepoMicroservice } = project
|
|
103
|
+
const { apps, appName, hasApprouter, hasXsuaa, isMonorepoMicroservice, hasKyma, hasMta, k8s } = project
|
|
104
|
+
const toKyma = cds.cli.options.to === 'k8s' || hasKyma && !hasMta
|
|
53
105
|
|
|
54
106
|
const html5DeployerPath = join(cds.root, cds.env.folders.app, 'html5-deployer', 'resources')
|
|
55
107
|
|
|
@@ -81,19 +133,39 @@ async function up() {
|
|
|
81
133
|
}
|
|
82
134
|
}
|
|
83
135
|
|
|
84
|
-
if (
|
|
85
|
-
if (!exists('chart')) run('cds add
|
|
86
|
-
if (apps.length > 0) {
|
|
87
|
-
await mkdirp(html5DeployerPath)
|
|
88
|
-
}
|
|
136
|
+
if (toKyma) {
|
|
137
|
+
if (!exists('chart') || !exists('containerize.yaml')) run('cds add kyma')
|
|
89
138
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
139
|
+
if (project.hasHtml5Repo) {
|
|
140
|
+
if (apps.length > 0) {
|
|
141
|
+
await mkdirp(html5DeployerPath)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const { app, archiveName } of apps) {
|
|
145
|
+
if (!archiveName) continue
|
|
146
|
+
|
|
147
|
+
const appPath = path.join(cds.root, cds.env.folders.app, app)
|
|
148
|
+
const zipPath = path.join(appPath, `dist/${archiveName}`)
|
|
149
|
+
|
|
150
|
+
// Calculate checksum for the app source folder (excluding node_modules and dist)
|
|
151
|
+
const currentChecksum = await calcDirChecksum(
|
|
152
|
+
appPath,
|
|
153
|
+
(dir) => !dir.includes('node_modules') && !dir.includes('dist')
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
const storedChecksum = readStoredChecksum(app)
|
|
157
|
+
const needsBuild = currentChecksum !== storedChecksum || !exists(zipPath)
|
|
95
158
|
|
|
96
|
-
|
|
159
|
+
if (needsBuild || process.env.SKIP_CHECK == 'true') {
|
|
160
|
+
DEBUG?.(dim(`build required for '${app}' – checksums`, { old: storedChecksum, new: currentChecksum }))
|
|
161
|
+
run(`npm run build --prefix ${appPath}`)
|
|
162
|
+
await copy(zipPath).to(html5DeployerPath, `${app}.zip`)
|
|
163
|
+
writeStoredChecksum(app, currentChecksum)
|
|
164
|
+
} else {
|
|
165
|
+
console.log(info(`Skipping build for UI5 app '${app}' - no changes detected (checksum: ${currentChecksum.substring(0, 8)}...)`))
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
97
169
|
} else {
|
|
98
170
|
if (!exists('mta.yaml')) {
|
|
99
171
|
run('cds add mta')
|
|
@@ -112,18 +184,82 @@ async function up() {
|
|
|
112
184
|
if (!exists(target)) fs.symlinkSync(relative, target, 'junction')
|
|
113
185
|
}
|
|
114
186
|
|
|
115
|
-
if (
|
|
187
|
+
if (toKyma) {
|
|
116
188
|
const ns = cds.cli.options.namespace
|
|
117
|
-
const nsHelm = ns ? `--namespace ${ns}
|
|
189
|
+
const nsHelm = ns ? `--namespace ${ns}` : ''
|
|
118
190
|
const nsKubectl = ns ? `-n ${ns}` : ''
|
|
119
191
|
|
|
120
192
|
run('npm i --package-lock')
|
|
121
193
|
run('cds build --production')
|
|
122
|
-
|
|
123
|
-
|
|
194
|
+
|
|
195
|
+
if (ns) {
|
|
196
|
+
const k8sNamespaceResult = run(`kubectl get namespace ${ns} -o jsonpath="{.metadata.name}"`, { continueOnFail: true, silent: true })
|
|
197
|
+
if (!k8sNamespaceResult) {
|
|
198
|
+
run(`kubectl create namespace ${ns}`)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const isValidDomain = str => /^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(str)
|
|
203
|
+
const { image, imagePullSecret } = k8s.values?.global ?? {}
|
|
204
|
+
let registry = image?.registry
|
|
205
|
+
if (!process.env.CI) {
|
|
206
|
+
if (!registry || !isValidDomain(registry)) {
|
|
207
|
+
const valuesPath = 'chart/values.yaml'
|
|
208
|
+
const [yn] = await ask4([warn(`invalid registry server '${registry}' detected, override in ${valuesPath}? (Y/n)`)])
|
|
209
|
+
if (yn?.toLowerCase() !== 'y' || process.env.CI) {
|
|
210
|
+
throw `registry parameter is invalid, please specify it in ${valuesPath}`
|
|
211
|
+
} else {
|
|
212
|
+
registry = await ask4(['registry server (e.g. index.docker.io): '])
|
|
213
|
+
if (!k8s.values.global.image) k8s.values.global.image = {}
|
|
214
|
+
k8s.values.global.image.registry = registry
|
|
215
|
+
const values = (await read(valuesPath)).replace(/(registry:\s*).*/, `$1${registry}`)
|
|
216
|
+
await write(values).to(valuesPath)
|
|
217
|
+
|
|
218
|
+
const containerize = (await read('containerize.yaml')).replace(/(repository:\s*).*/, `$1${registry}`)
|
|
219
|
+
await write(containerize).to('containerize.yaml')
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (imagePullSecret?.name) {
|
|
223
|
+
const imagePullSecretResult = run(`kubectl get secret ${imagePullSecret.name} ${nsKubectl} -o jsonpath="{.metadata.name}"`, { continueOnFail: true, silent: true })
|
|
224
|
+
if (!imagePullSecretResult) {
|
|
225
|
+
const yn = await ask4([`image pull secret '${imagePullSecret.name}' not found in namespace '${ns || 'default'}' – do you want to create it? (Y/n) `])
|
|
226
|
+
if (yn?.toLowerCase() !== 'y' && yn !== '') {
|
|
227
|
+
throw `image pull secret '${imagePullSecret.name}' is required to pull images from the registry`
|
|
228
|
+
} else {
|
|
229
|
+
const [username, email] = await ask4([
|
|
230
|
+
'registry username: ',
|
|
231
|
+
'registry email: '
|
|
232
|
+
])
|
|
233
|
+
const password = await ask4(['registry password: '], { redacted: true })
|
|
234
|
+
run(`kubectl create secret docker-registry ${imagePullSecret.name} ${nsKubectl} --docker-server=${registry} --docker-username=${username} --docker-password='${password}' --docker-email='${email}'`)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const modules = await containerize()
|
|
241
|
+
const helmArgs = []
|
|
242
|
+
modules?.forEach(m => {
|
|
243
|
+
if (m.path === 'gen/srv') {
|
|
244
|
+
helmArgs.push(`--set srv.annotations.deployment.deployment-checksum=${m.checksum}`)
|
|
245
|
+
}
|
|
246
|
+
if (m.path === 'app/router') {
|
|
247
|
+
helmArgs.push(`--set approuter.annotations.deployment.deployment-checksum=${m.checksum}`)
|
|
248
|
+
}
|
|
249
|
+
if (m.path === 'app/html5-deployer') {
|
|
250
|
+
helmArgs.push(`--set html5-apps-deployer.annotations.job.job-checksum=${m.checksum}`)
|
|
251
|
+
}
|
|
252
|
+
if (m.path === 'gen/db') {
|
|
253
|
+
helmArgs.push(`--set hana-deployer.annotations.job.job-checksum=${m.checksum}`)
|
|
254
|
+
}
|
|
255
|
+
if (m.path === 'gen/mtx/sidecar') {
|
|
256
|
+
helmArgs.push(`--set sidecar.annotations.deployment.deployment-checksum=${m.checksum}`)
|
|
257
|
+
}
|
|
258
|
+
})
|
|
124
259
|
|
|
125
260
|
let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart ${nsHelm} --wait --wait-for-jobs --timeout=10m`
|
|
126
|
-
if (hasXsuaa)
|
|
261
|
+
if (hasXsuaa) helmArgs.push(' --set-file xsuaa.jsonParameters=xs-security.json')
|
|
262
|
+
if (helmArgs.length > 0) helmUpgrade += ` ${helmArgs.join(' ')}`
|
|
127
263
|
run(helmUpgrade)
|
|
128
264
|
run(`kubectl rollout status deployment ${appName}-srv ${nsKubectl} --timeout=8m`)
|
|
129
265
|
if (hasApprouter) run(`kubectl rollout status deployment ${appName}-approuter ${nsKubectl} --timeout=8m`)
|