From 86fc082d3a202a724795bdfebe9f4f5a1e67f26c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:42:50 +0200 Subject: [PATCH 001/140] chore(deps): update dependency @cap-js/cds-types to v0.10.0 (#1753) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@cap-js/cds-types](https://cap.cloud.sap/) ([source](https://redirect.github.com/cap-js/cds-types)) | [`0.9.0` -> `0.10.0`](https://renovatebot.com/diffs/npm/@cap-js%2fcds-types/0.9.0/0.10.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@cap-js%2fcds-types/0.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@cap-js%2fcds-types/0.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@cap-js%2fcds-types/0.9.0/0.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@cap-js%2fcds-types/0.9.0/0.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
cap-js/cds-types (@​cap-js/cds-types) ### [`v0.10.0`](https://redirect.github.com/cap-js/cds-types/blob/HEAD/CHANGELOG.md#0100---2025-04-01) [Compare Source](https://redirect.github.com/cap-js/cds-types/compare/v0.9.0...v0.10.0) ##### Added - Added support for new builtin type `cds.Map` - Added types for `SELECT.hints()` of `cds.ql` API - Added types for `.bind(Service)` to all queries. - Added types for `i18n` module ##### Changed - `CHANGELOG.md` and `LICENSE` files are no longer part of the npm package. ##### Deprecated ##### Removed ##### Fixed ##### Security
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Steffen Waldmann --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf6e93edf9..5237db9848 100644 --- a/package-lock.json +++ b/package-lock.json @@ -286,14 +286,14 @@ } }, "node_modules/@cap-js/cds-types": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@cap-js/cds-types/-/cds-types-0.9.0.tgz", - "integrity": "sha512-AD4WGAOOSszaleQQqheIo0hHm50zk3NejMlHsuG6cLh4EyK/kozvcx8hkWfAkUT/s11fa8OjyMhztFCy8b5DAA==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@cap-js/cds-types/-/cds-types-0.10.0.tgz", + "integrity": "sha512-E0uVAXmYz8X7O4Pf/ZveECi+qPUl2X/o4BQRlGNstxhvUfrNHmADZR1N3RJvKxO5wOGfaZuJtY+fg7diU9tnAw==", "dev": true, "hasInstallScript": true, - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "peerDependencies": { - "@sap/cds": "^8.0.0", + "@sap/cds": ">=8.0.0", "@types/express": ">=4" } }, From a9260670cd22cf6ded7d723d7026e257ae269044 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:43:10 +0200 Subject: [PATCH 002/140] chore(deps): update dependency @cap-js/cds-typer to v0.34.0 (#1752) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@cap-js/cds-typer](https://cap.cloud.sap/) ([source](https://redirect.github.com/cap-js/cds-typer)) | [`0.33.1` -> `0.34.0`](https://renovatebot.com/diffs/npm/@cap-js%2fcds-typer/0.33.1/0.34.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@cap-js%2fcds-typer/0.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@cap-js%2fcds-typer/0.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@cap-js%2fcds-typer/0.33.1/0.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@cap-js%2fcds-typer/0.33.1/0.34.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
cap-js/cds-typer (@​cap-js/cds-typer) ### [`v0.34.0`](https://redirect.github.com/cap-js/cds-typer/blob/HEAD/CHANGELOG.md#0340---2025-04-01) [Compare Source](https://redirect.github.com/cap-js/cds-typer/compare/v0.33.1...v0.34.0) ##### Added - Improved performance of repeated `cds-typer` runs by introducing an option to cache CDS model between runs. By default, typer will only regenerate the files if the model has changed between runs, using `blake2s256` as algorithm. The used version of cds-typer is included in the hash and will therefore be version-specific. ##### Changed - \[breaking] The config `use_entities_proxy` (allowing for static imports) is now set to `true` as default. You can set it to `false` to revert to the old behaviour. - Running `cds watch` will trigger `cds-typer "*"` before the initial startup ##### Deprecated ##### Removed ##### Fixed ##### Security
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Steffen Waldmann --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5237db9848..65c4715789 100644 --- a/package-lock.json +++ b/package-lock.json @@ -272,9 +272,9 @@ } }, "node_modules/@cap-js/cds-typer": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cap-js/cds-typer/-/cds-typer-0.33.1.tgz", - "integrity": "sha512-g9pyJk1rG41QErfcJvCae+iuAsw+Mvddh0SeepGPsS6QpXmvjfDzF6L61ySubwSo5XPSArwo3Cd6fxH8cffD9w==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/@cap-js/cds-typer/-/cds-typer-0.34.0.tgz", + "integrity": "sha512-ElVS1ZhFU+hRDC6TJWA1jSkqn+e4QHx4MhnSTo5QWBBJmbr4ZtNW3CcbYdOlnIErt9GRlHjaNMipjAFdb0JxTA==", "dev": true, "license": "Apache-2.0", "bin": { From 43b3614ce506ed35014375cc3c67535aca0818b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:43:23 +0200 Subject: [PATCH 003/140] chore(deps): update dependency sass to v1.86.3 (#1747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [sass](https://redirect.github.com/sass/dart-sass) | [`1.86.0` -> `1.86.3`](https://renovatebot.com/diffs/npm/sass/1.86.0/1.86.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/sass/1.86.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/sass/1.86.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/sass/1.86.0/1.86.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sass/1.86.0/1.86.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
sass/dart-sass (sass) ### [`v1.86.3`](https://redirect.github.com/sass/dart-sass/blob/HEAD/CHANGELOG.md#1863) [Compare Source](https://redirect.github.com/sass/dart-sass/compare/1.86.2...1.86.3) - Fix a bug introduced in 1.86.1 where Sass fails to resolve paths starting with a `..` segment. ### [`v1.86.2`](https://redirect.github.com/sass/dart-sass/blob/HEAD/CHANGELOG.md#1862) [Compare Source](https://redirect.github.com/sass/dart-sass/compare/1.86.1...1.86.2) - No user-visible changes. ### [`v1.86.1`](https://redirect.github.com/sass/dart-sass/blob/HEAD/CHANGELOG.md#1861) [Compare Source](https://redirect.github.com/sass/dart-sass/compare/1.86.0...1.86.1) - Improve the performance of `file:` URL case canonicalization on Windows and Mac OS.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65c4715789..10ee017c5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7412,9 +7412,9 @@ "peer": true }, "node_modules/sass": { - "version": "1.86.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.0.tgz", - "integrity": "sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==", + "version": "1.86.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.3.tgz", + "integrity": "sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==", "dev": true, "license": "MIT", "dependencies": { From 913c261149365f5532d516cd2b1d8e206bb30063 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:43:37 +0200 Subject: [PATCH 004/140] chore(deps): update dependency @sap/cds to v8.9.1 (#1745) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@sap/cds](https://cap.cloud.sap/) | [`8.8.3` -> `8.9.1`](https://renovatebot.com/diffs/npm/@sap%2fcds/8.8.3/8.9.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@sap%2fcds/8.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@sap%2fcds/8.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@sap%2fcds/8.8.3/8.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@sap%2fcds/8.8.3/8.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10ee017c5b..23e84e64ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2223,9 +2223,9 @@ ] }, "node_modules/@sap/cds": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.8.3.tgz", - "integrity": "sha512-4OuQ1LTwFQYveMsPivyIfGN7kWIipB8kcG37ddGCrk0lNSv+dNBPpC1nUeOvCbFh0b0lu+shPpuqjQjCyR3pag==", + "version": "8.9.1", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.1.tgz", + "integrity": "sha512-+KoY7Bw1Gc3vwK4X3CFCV+IAQO4QT0HRsaW/qgETeOGqjzbuf6KvUqlkDuPE5msdXwfz/EFDB9Vx9jTyTw581Q==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { @@ -2236,13 +2236,13 @@ "bin": { "cds-deploy": "lib/dbs/cds-deploy.js", "cds-serve": "bin/serve.js", - "cds-test": "bin/test.js", - "chest": "bin/test.js" + "cds-test": "bin/test.js" }, "engines": { "node": ">=18" }, "peerDependencies": { + "@eslint/js": "^9", "express": "^4", "tar": "^7" }, From d3a805bb2bd82e4ee5f7ce7ea17a632d4976b951 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:43:52 +0200 Subject: [PATCH 005/140] chore(deps): update dependency @typescript-eslint/parser to v8.29.0 (#1746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.28.0` -> `8.29.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.28.0/8.29.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.28.0/8.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.28.0/8.29.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.29.0`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8290-2025-03-31) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.28.0...v8.29.0) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23e84e64ef..15bdfd77f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2716,16 +2716,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.28.0.tgz", - "integrity": "sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz", + "integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.28.0", - "@typescript-eslint/types": "8.28.0", - "@typescript-eslint/typescript-estree": "8.28.0", - "@typescript-eslint/visitor-keys": "8.28.0", + "@typescript-eslint/scope-manager": "8.29.0", + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/typescript-estree": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4" }, "engines": { @@ -2741,14 +2741,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.28.0.tgz", - "integrity": "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.0.tgz", + "integrity": "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.28.0", - "@typescript-eslint/visitor-keys": "8.28.0" + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2759,9 +2759,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.28.0.tgz", - "integrity": "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.0.tgz", + "integrity": "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==", "dev": true, "license": "MIT", "engines": { @@ -2773,14 +2773,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.28.0.tgz", - "integrity": "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.0.tgz", + "integrity": "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.28.0", - "@typescript-eslint/visitor-keys": "8.28.0", + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2800,13 +2800,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.28.0.tgz", - "integrity": "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.0.tgz", + "integrity": "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.28.0", + "@typescript-eslint/types": "8.29.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { From de46bab75e562908c9fe3f78cb9cf30b82c21516 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Tue, 8 Apr 2025 09:44:42 +0200 Subject: [PATCH 006/140] Remove `--for production` from facets (#1763) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We'll use the `production` profile as a default when applicable (`cds add hana,xsuaa`) in cds-dk 9 β†’ not required here any more. --- get-started/attic/grow-as-you-go.-md | 6 +++--- guides/deployment/to-cf.md | 6 +++--- guides/deployment/to-kyma.md | 2 +- guides/multitenancy/index.md | 10 +++++----- guides/security/authorization.md | 4 ++-- guides/using-services.md | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/get-started/attic/grow-as-you-go.-md b/get-started/attic/grow-as-you-go.-md index 7e80d92b96..c664f03a03 100644 --- a/get-started/attic/grow-as-you-go.-md +++ b/get-started/attic/grow-as-you-go.-md @@ -15,10 +15,10 @@ As your project evolves, you would gradually add new features, for example as ou While we used SQLite in-memory databases and mocked authentication during development, we would use SAP HANA Cloud and a combination of App Router, IAS and/or XSUAA in production. We can quickly do so as follows: ```sh -cds add hana,approuter,xsuaa --for production +cds add hana,approuter,xsuaa ``` -This adds respective packages and configuration to your project. The content of your project, that is, models or code, doesn't change and doesn't have to be touched. The option `--for production` controls that these service variants are only used when in production profile, that is, when the app is deployed to the cloud. Locally you continue to develop in airplane mode. +This adds respective packages and configuration to your project with the `[production]` profile. The content of your project, that is, models or code, doesn't change and doesn't have to be touched. The profile controls that these service variants are only used when in production, that is, when the app is deployed to the cloud. Locally you continue to develop in airplane mode. @@ -39,7 +39,7 @@ cds add mta If you are creating a SaaS application you also need to add support for tenant subscriptions and tenant upgrades. When a tenant subscribes, new database containers have to be bootstrapped along with other resources, like message channels. CAP provides the so-called MTX services which do that automatically in a sidecar micro service. You can add all required packages and configurations by: ```sh -cds add multitenancy --for production +cds add multitenancy ``` [Learn more about multitenancy.](../guides/multitenancy/){.learn-more} diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index abe553dc91..7254774435 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -147,7 +147,7 @@ While we used SQLite or H2 as a low-cost stand-in during development, we're goin ```sh -cds add hana --for production +cds add hana ``` [Learn more about using SAP HANA for production.](../databases-hana){.learn-more} @@ -157,7 +157,7 @@ cds add hana --for production Configure your app for XSUAA-based authentication: ```sh -cds add xsuaa --for production +cds add xsuaa ``` ::: tip This will also generate an `xs-security.json` file @@ -226,7 +226,7 @@ cds add workzone To enable multitenancy for production, run the following command: ```sh -cds add multitenancy --for production +cds add multitenancy ``` [Learn more about MTX services.](../multitenancy/#behind-the-scenes){.learn-more} diff --git a/guides/deployment/to-kyma.md b/guides/deployment/to-kyma.md index e02c665201..0d1bbc9b89 100644 --- a/guides/deployment/to-kyma.md +++ b/guides/deployment/to-kyma.md @@ -137,7 +137,7 @@ Let's start with a new sample project and prepare it for production using an SA ```sh cds init bookshop --add sample && cd bookshop -cds add hana,xsuaa --for production +cds add hana,xsuaa ``` #### User Interfaces diff --git a/guides/multitenancy/index.md b/guides/multitenancy/index.md index d97fc95c10..a183ac8d28 100644 --- a/guides/multitenancy/index.md +++ b/guides/multitenancy/index.md @@ -53,7 +53,7 @@ cd bookshop Now, you can run this to enable multitenancy for your CAP application: ```sh -cds add multitenancy --for production +cds add multitenancy ```
@@ -715,7 +715,7 @@ In order to get your multitenant application deployed, follow this excerpt from Once: Add SAP HANA Cloud, XSUAA, and [App Router](../deployment/to-cf#add-app-router) configuration. The App Router acts as a single point-of-entry gateway to route requests to. In particular, it ensures user login and authentication in combination with XSUAA. ```sh -cds add hana,xsuaa --for production +cds add hana,xsuaa ``` If you intend to serve UIs you can easily set up the SAP Cloud Portal service: @@ -993,14 +993,14 @@ cds watch --profile dev ## SaaS Dependencies {#saas-dependencies} Some of the xsuaa-based services your application consumes need to be registered as _reuse services_ to work in multitenant environments. This holds true for the usage of both the SaaS Registry service and the Subscription Manager Service (SMS). -CAP Java as well as `@sap/cds-mtxs`, each offer an easy way to integrate these dependencies. They support some services out of the box and also provide a simple API for applications. Most notably, you need such dependencies for the following SAP BTP services: [Audit Log](https://discovery-center.cloud.sap/serviceCatalog/audit-log-service), [Event Mesh](https://discovery-center.cloud.sap/serviceCatalog/event-mesh), [Destination](https://discovery-center.cloud.sap/serviceCatalog/destination), [HTML5 Application Repository](https://discovery-center.cloud.sap/serviceCatalog/html5-application-repository-service), and [Cloud Portal](https://discovery-center.cloud.sap/serviceCatalog/cloud-portal-service). +CAP Java as well as `@sap/cds-mtxs`, each offer an easy way to integrate these dependencies. They support some services out of the box and also provide a simple API for applications. Most notably, you need such dependencies for the following SAP BTP services: [Audit Log](https://discovery-center.cloud.sap/serviceCatalog/audit-log-service), [Event Mesh](https://discovery-center.cloud.sap/serviceCatalog/event-mesh), [Destination](https://discovery-center.cloud.sap/serviceCatalog/destination), [HTML5 Application Repository](https://discovery-center.cloud.sap/serviceCatalog/html5-application-repository-service), and [Cloud Portal](https://discovery-center.cloud.sap/serviceCatalog/cloud-portal-service). For CAP Java, all these services are supported natively and SaaS dependencies are automatically created if such a service instance is bound to the CAP Java application, that is, the `srv` module. :::tip Explicitly activate the Destination service SaaS dependency for Destination service needs to be activated explicitly in the `application.yaml` due to security reasons. SaaS dependencies for some of the other services can be **de**activated by setting the corresponding property to `false` in the `application.yaml`. -Refer to the `cds.multiTenancy.dependencies` section in the [CDS properties](/java/developing-applications/properties#cds-properties). +Refer to the `cds.multiTenancy.dependencies` section in the [CDS properties](/java/developing-applications/properties#cds-properties). ::: For CAP Node.js, all these services are supported natively and can be activated individually by providing configuration in `cds.requires`. In the most common case, you simply activate service dependencies like so: @@ -1049,7 +1049,7 @@ The Boolean values in the _mtx/sidecar/package.json_ activate the default config ### Additional Services -If your CAP Java application uses a service that isn't supported out of the box, you can add a custom dependency by providing a custom handler. Refer to [Define Dependent Services](../../java/multitenancy#define-dependent-services) for details. +If your CAP Java application uses a service that isn't supported out of the box, you can add a custom dependency by providing a custom handler. Refer to [Define Dependent Services](../../java/multitenancy#define-dependent-services) for details. In Node.js, you can use the `subscriptionDependency` setting to provide a dependency configuration similar to the standard configuration shown before. Use your application's or CAP plugin's _package.json_: diff --git a/guides/security/authorization.md b/guides/security/authorization.md index 5381f4e48f..46633bd172 100644 --- a/guides/security/authorization.md +++ b/guides/security/authorization.md @@ -492,7 +492,7 @@ The condition defined in the `where`-clause typically associates domain data wit - `UPDATE` (as reject condition2) - `DELETE` (as reject condition2) - > 1 Node.js supports _static expressions_ that *don't have any reference to the model* such as `where: $user.level = 2` for all events. + > 1 Node.js supports _static expressions_ that *don't have any reference to the model* such as `where: $user.level = 2` for all events. > 2 CAP Java uses a filter condition by default. For instance, a user is allowed to read or edit `Orders` (defined with the `managed` aspect) that they have created: @@ -899,7 +899,7 @@ Information about roles and attributes has to be made available to the UAA platf Derive scopes, attributes, and role templates from the CDS model: ```sh -cds add xsuaa --for production +cds add xsuaa ``` This generates an _xs-security.json_ file: diff --git a/guides/using-services.md b/guides/using-services.md index 37d5d7c5f8..5481826610 100644 --- a/guides/using-services.md +++ b/guides/using-services.md @@ -1394,7 +1394,7 @@ The MTA-based deployment is described in [the deployment guide](deployment/). Yo ```sh -cds add xsuaa,destination,connectivity --for production +cds add xsuaa,destination,connectivity ``` ::: details Learn what this does in the background... From 7475c03b2f443eeef6c00743968bda6359cef5b5 Mon Sep 17 00:00:00 2001 From: Niko Lockenvitz Date: Tue, 8 Apr 2025 11:51:57 +0200 Subject: [PATCH 007/140] Typescript: add global installation of `tsx` earlier (#1761) Following the documentation of setting up TypeScript, I ran into the following issue: ``` $ cds watch cds serve all --with-mocks --in-memory? live reload enabled for browsers ___________________________ Error: detected C:\Users\...\cap-ts\tsconfig.json, but could not run with 'tsx'. Enable Typescript with npm install -D tsx typescript ``` Global installation is mentioned later within cds-tsx but if its also required for `cds watch` it should be mentioned before already. Therefore, my suggestion to add `tsx` to the other packages that should be installed globally. (Also it seems that the auto-generated tsconfig.json - when running `cds add typescript` - is missing `compilerOptions.outDir`; otherwise VSCode complains about `Cannot write file '.../cap-ts/eslint.config.mjs' because it would overwrite input file.` but I guess that's a setup/code issue and not a docs issue) --- node.js/typescript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.js/typescript.md b/node.js/typescript.md index 56a70524cf..9ccdba2410 100644 --- a/node.js/typescript.md +++ b/node.js/typescript.md @@ -17,7 +17,7 @@ Follow these steps to add TypeScript support: 1. Install typescript packages globally: ```sh - npm i -g typescript ts-node + npm i -g typescript ts-node tsx ``` 2. Add a basic _tsconfig.json_ file to your project: From 6852798246da2c515b8f1b63e4b74937e98e812f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:52:56 +0200 Subject: [PATCH 008/140] chore(deps): update eslint (#1760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.29.0` -> `8.29.1`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.29.0/8.29.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.29.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.29.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.29.0/8.29.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.29.0/8.29.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [eslint](https://eslint.org) ([source](https://redirect.github.com/eslint/eslint)) | [`9.23.0` -> `9.24.0`](https://renovatebot.com/diffs/npm/eslint/9.23.0/9.24.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/eslint/9.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint/9.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint/9.23.0/9.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint/9.23.0/9.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.29.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8291-2025-04-07) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.29.0...v8.29.1) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
eslint/eslint (eslint) ### [`v9.24.0`](https://redirect.github.com/eslint/eslint/compare/v9.23.0...d49f5b7333e9a46aabdb0cff267a1d36cdbde598) [Compare Source](https://redirect.github.com/eslint/eslint/compare/v9.23.0...v9.24.0)
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ‘» **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 70 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15bdfd77f6..072f85f7f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1319,9 +1319,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", - "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1429,9 +1429,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", - "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", + "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", "dev": true, "license": "MIT", "engines": { @@ -2716,16 +2716,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz", - "integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==", + "version": "8.29.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz", + "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.29.0", - "@typescript-eslint/types": "8.29.0", - "@typescript-eslint/typescript-estree": "8.29.0", - "@typescript-eslint/visitor-keys": "8.29.0", + "@typescript-eslint/scope-manager": "8.29.1", + "@typescript-eslint/types": "8.29.1", + "@typescript-eslint/typescript-estree": "8.29.1", + "@typescript-eslint/visitor-keys": "8.29.1", "debug": "^4.3.4" }, "engines": { @@ -2741,14 +2741,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.0.tgz", - "integrity": "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==", + "version": "8.29.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz", + "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.0", - "@typescript-eslint/visitor-keys": "8.29.0" + "@typescript-eslint/types": "8.29.1", + "@typescript-eslint/visitor-keys": "8.29.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2759,9 +2759,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.0.tgz", - "integrity": "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==", + "version": "8.29.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz", + "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==", "dev": true, "license": "MIT", "engines": { @@ -2773,14 +2773,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.0.tgz", - "integrity": "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==", + "version": "8.29.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz", + "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.0", - "@typescript-eslint/visitor-keys": "8.29.0", + "@typescript-eslint/types": "8.29.1", + "@typescript-eslint/visitor-keys": "8.29.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2800,13 +2800,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.0.tgz", - "integrity": "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==", + "version": "8.29.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz", + "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/types": "8.29.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -4232,19 +4232,19 @@ } }, "node_modules/eslint": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", - "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", + "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.2", + "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.23.0", + "@eslint/js": "9.24.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", From 317758cd420a388c877a8e5a8d37cdabfe2f8ecc Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Tue, 8 Apr 2025 14:00:03 +0200 Subject: [PATCH 009/140] Remove commented out snippet for monorepo setups in CF guide (#1765) `cds up` will take care of that in cds-dk 9. --- guides/deployment/to-cf.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index 7254774435..b2e1c64141 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -250,16 +250,6 @@ cds up [You need to be logged in to Cloud Foundry.](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/7a37d66c2e7d401db4980db0cd74aa6b.html){.learn-more} - - - ::: details Essentially, this automates the following steps... ```sh @@ -267,6 +257,9 @@ ln -sf ../package-lock.json npm i app/browse npm i app/admin-books +# If project is monrepo +ln -sf ../package-lock.json + # If project is multitenant npm i --package-lock-only mtx/sidecar From 745c16a492a1032f5900509e13447cc5d255cc53 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Mon, 14 Apr 2025 09:55:35 +0200 Subject: [PATCH 010/140] Proper code blocks for `format-cds` --- tools/cds-editors.md | 57 ++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/tools/cds-editors.md b/tools/cds-editors.md index d0be7a2b42..970276b274 100644 --- a/tools/cds-editors.md +++ b/tools/cds-editors.md @@ -446,40 +446,57 @@ Until a further change, reference calculation is reasonably fast. - Changing settings in _CDS_ section will currently perform a complete workspace invalidation, that is, required indexes will lead to recompilations on demand as described above. - Changing certain `cds.env` settings, for example folder configurations, will invalidate the workspace as well. -### CDS Source Formatter -{ #cds-formatter} +### CDS Source Formatter { #cds-formatter} -The CDS code formatter provides a command line interface. Use it as a pre-commit hook or within your CI/CD pipeline, to guarantee a consistent -formatting. +The CDS code formatter provides a command line interface. Use it as a pre-commit hook or within your CI/CD pipeline to ensure consistent formatting. #### Installation -Install the CDS language server globally as a library via `npm i -g @sap/cds-lsp`. -A new shell command `format-cds` is available. +Install the CDS language server globally as a library via + +```sh +npm i -g @sap/cds-lsp +``` + +You can now use the formatter command: + +```sh +format-cds +``` #### Usage -Show help via `format-cds -h`. This explains all commands and formatting options in detail including the default value for -each formatting option. +For detailed usage information run the help command: + +```sh +format-cds -h +``` + +You can create a settings file (_.cdsprettier.json_) with custom formatting options for your project. + +Run this to create an initial version: +```sh +format-cds --init +``` +> Commit the _.cdsprettier.json_ file into your version control system. -It is recommended to generate once for each project a settings file (_.cdsprettier.json_) with all default formatting options available. Execute `format-cds --init` in the project root. An existing file would not be overwritten. To adapt your settings to your preferred style, open the _.cdsprettier.json_ file in VS Code. You get code completion and help for each option. There is also a settings UI in [SAP CDS Language Support](https://marketplace.visualstudio.com/items?itemName=SAPSE.vscode-cds), -reachable via command `CDS: Show Formatting Options Configuration`. This allows to see the effects of each formatting option -on an editable sample source. Commit the _.cdsprettier.json_ file into your version control system. +::: tip Use the visual VS Code settings +Run `CDS: Show Formatting Options Configuration` to jump to the [SAP CDS Language Support](https://marketplace.visualstudio.com/items?itemName=SAPSE.vscode-cds) settings, which shows a preview of selected formatter options. +::: -Use `format-cds` to format all your CDS source files. The effective set of formatting options is calculated in order of precedence: -- Default options -- Options from _.cdsprettier.json_ file -- Command line formatting options +The effective set of formatting options is calculated in order of precedence: +1. Command line options +2. Options from _.cdsprettier.json_ +3. Default options -It is possible to have _.cdsprettier.json_ files in subfolders. In this case the most relevant settings file per CDS source file -is taken. +It is possible to have _.cdsprettier.json_ files in subfolders. In that case, the closest file in the folder hierarchy is used for the respective CDS source. Use `format-cds ...` to restrict the set of CDS source files. -By default, backup files with _.bak_ file extension will be created. -Use `-f` switch to force an overwrite without creating a backup. +By default, backup files with the _.bak_ file extension will be created. Use the `-f` switch to force an overwrite without creating a backup. This is on your own risk. Should there be problems data loss might occur, especially when formatting in a pre-commit hook. -Better add _.bak_ to your _.gitignore_ file and not use `-f`. + +> We recommend adding _.bak_ to your _.gitignore_ file. ### GitHub Integration From 3a80224f2c2994bb296806c486d37767e173463c Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Mon, 14 Apr 2025 09:56:43 +0200 Subject: [PATCH 011/140] Punctuation in synopsis --- tools/apis/cds-import.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/apis/cds-import.md b/tools/apis/cds-import.md index 99b2c62cfc..c51ece4a42 100644 --- a/tools/apis/cds-import.md +++ b/tools/apis/cds-import.md @@ -1,7 +1,7 @@ --- status: released synopsis: > - Programmatically use cds.import + Programmatically use cds.import. --- # CDS Import API From aa1543dfd9f7d3248714eba713f95e5316866bf1 Mon Sep 17 00:00:00 2001 From: Daniel Schlachter Date: Mon, 14 Apr 2025 10:41:58 +0200 Subject: [PATCH 012/140] shared-db (#1717) Co-authored-by: Vladislav Leonkev Co-authored-by: Johannes Vogt Co-authored-by: Vladislav Leonkev <131776471+vl-leon@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Rene Jeglinsky --- .../app-instances.excalidraw.svg | 2 + .../microservices/bookstore.excalidraw.svg | 2 + .../microservices/complex.excalidraw.svg | 2 + .../microservices/late-cut.excalidraw.svg | 2 + .../microservices/modules.excalidraw.svg | 2 + .../microservices/modulith.excalidraw.svg | 2 + .../microservices/monolith.excalidraw.svg | 2 + .../multiple-apps.excalidraw.svg | 2 + .../microservices/multiple-dbs.excalidraw.svg | 2 + .../multiple-deployment-units.excalidraw.svg | 2 + .../true-microservices-full.excalidraw.svg | 2 + .../true-microservices.excalidraw.svg | 2 + guides/deployment/microservices.md | 1099 +++++++++++++++++ menu.md | 2 +- project-words.txt | 2 + 15 files changed, 1126 insertions(+), 1 deletion(-) create mode 100644 guides/deployment/assets/microservices/app-instances.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/bookstore.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/complex.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/late-cut.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/modules.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/modulith.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/monolith.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/multiple-apps.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/multiple-dbs.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/multiple-deployment-units.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/true-microservices-full.excalidraw.svg create mode 100644 guides/deployment/assets/microservices/true-microservices.excalidraw.svg create mode 100644 guides/deployment/microservices.md diff --git a/guides/deployment/assets/microservices/app-instances.excalidraw.svg b/guides/deployment/assets/microservices/app-instances.excalidraw.svg new file mode 100644 index 0000000000..fcbe630a4b --- /dev/null +++ b/guides/deployment/assets/microservices/app-instances.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1b2VLbWlx1MDAxNn3PV1Dc13By5iFVXV1cdTAwMDZcdTAwMDMxYfaA465bKcWSbTWyZCRcdTAwMTkwqfx7b1x1MDAxOWLZlkRscIDctlx1MDAxZlx1MDAxOI6GM62111x1MDAxZY6/v9vY2IxHXHUwMDAzZ/PjxqZz27Y811x1MDAwZa2bzfdJ+7VcdTAwMTNGbuDDJTr+P1xuhmF7fGcvjlx1MDAwN9HHXHUwMDBmXHUwMDFm+lZ46cRcdTAwMDPPajvo2o2Gllx1MDAxN8VD21xyUDvof3Bjp1x1MDAxZv07+Xls9Z1/XHKCvlx1MDAxZIco7WTLsd04XGLv+3I8p+/4cVx1MDAwNG//XHUwMDBm/L+x8X38XHUwMDEzrrh20mOFNcr+8NSrnfLK7m4zUlxcVc340fFNP6dcdTAwMTA67djyu56TXrqFdmlcdTAwMThSXGZzqZWYXFxcdTAwMTjBXHUwMDA1JikyhGNJ0/ZcdTAwMWLXjntwjWOCXGJcdTAwMTX454dM7ug5brdcdTAwMTcnj1x1MDAxM4GkXCLTb73v/eNcdTAwMDaetERxXHUwMDE4XFw6O4FcdTAwMDdzhSH+RYxcIm2aXHUwMDBl8JvVvuyGwdC3J/fEoeVHXHUwMDAzK4RcdTAwMTVJ7+u4nleNR+O3w17AXCJuzvVx8TByOtde9Fx1MDAxNHTa7flOlKx6OrtgYLXdOFlcdTAwMWSC01kkI1x1MDAxY1Ts8Vx1MDAwNv2djimEra0kO+RcdTAwMGY9b9Ls+raTrPumRWZ68+2H3mbujlx1MDAxYyd5XHUwMDAz0ZpLrIxkkyspXHUwMDAyXHIx863HgT9GI8FcdTAwMDJ2VvGpO9yoXGaAisev7Vx1MDAwMCiddLGTQexOgS2dy3BgW/ePXHUwMDEwxSkzhClNWLqWnutfzlx1MDAwZt1cdTAwMGLal2kv49ZcdTAwMWbv8/C7deZen2+rnaHu1COvdPpJxeW7LH5cdTAwMWTPc1x1MDAwN9FcdTAwMWN6teBcdTAwMDBEySjl2lx1MDAxMKzoXGaEhWKIa001ycGwVEhKwriQilx1MDAxMS5cdM1imHIklFx1MDAxNIpqTChcdTAwMTdU8/8rLD+0QSslnUrnbtSM/bDe/EqCRo1cdTAwMDKIXHUwMDFmri9cdTAwMDF5tZ+P+e9pV1x1MDAwZttNXHUwMDFmWn7MU4FiSmFDKMmjgtKqiFxu8IzWwij2hplcdTAwMTBxVVwi1bPj1sGVO1x1MDAxYX1cdTAwMWH9d//r8UWWXHTQR4ZcdTAwMDZcdTAwMTRJo7nCWFx1MDAxM4ONnKWBXHUwMDE2SGhlNGNcbnMqZYZcdTAwMGJcdTAwMTjBLKhSKiFcdTAwMTIm2pgsXHUwMDE5uEHYXGJtpMbAXHUwMDE3wcyaXHUwMDBiz+NC49lcXFx1MDAwMFlgXG7YIPKoIHWhKmiGYUe4+S2qwJbgwqR5XHUwMDEwuNNcdTAwMWVO8kn/2kiRNf5n8vff73Pv3iqGc/LJXHUwMDAwOX1fZlx1MDAxNz0rineCft+NYaKnySAzXG5cdTAwMWRbYbxcctvq+t35a45vXHUwMDE3XFxcdTAwMTk/VVxuw+Cm51hcdTAwMTmQwHPz11x1MDAxZbFcdTAwMWH7J7JR03gw/Fxc2jLfjkv4/HB4uYjVMJQgpTCgXHUwMDAxXHUwMDA0XHUwMDBlXHUwMDFimsLh3moopKhRklx1MDAxOFhMylK2TFlccthzXHJcdTAwMWVcdTAwMDZcdTAwMTFMMmNSeUythkSYXHUwMDAxKlx1MDAxNIdOqMR0LaHPM1x1MDAxYvr5Vlx1MDAwM1x1MDAxM0WxYDijlYnZ4GS+dWI2XHUwMDE4k7DhXCJ97Fx1MDAxZmc1XG7gnHyyQP7DzUa5XHUwMDFk0VFpv9Uo1z+fbZfN0DI+W9jththQKaO0oUIpMlx1MDAxYjlKylx1MDAxMNhcdTAwMTZcYj7AyEq4vPa934LheL7vTTTHKiFBjuHQTM63Tlxmh9JcdTAwMDJkxohcdTAwMTQmr2Q5XHUwMDFloVx1MDAwM+1URPjVWGdXR6rR/FLdOzxsXHJcdTAwMTbOolx1MDAxOHCxuaJSTGdLxllcdTAwMTRDXHUwMDExUULlhqBcdTAwMWEjhiEoYUpcdTAwMTSmUf6Q9IltRT3nZfMnJ4vimVx1MDAxNeKZXHUwMDBiQzjAM6N5if/DaSGgSVx1MDAxMmYp9qRYcjK8dKBT+Iqd23RjpuBZ4nut6/Pzmlx1MDAxZFx1MDAxZNTPavUr/eW0cbM5ue9Hxlx1MDAxZfxWsuSPJkOWmcnc88QwgLxcdTAwMDSvkkFcdTAwMTRcIqY8xnuyqGKySI5cdTAwMTJRXHUwMDA2aYZ4e+aOVDPWZClcIsvpXHUwMDEyyUZcbu4+XHUwMDE4JJ5n5oXItE5YIbFkgoBXsGozXHUwMDBmPtlUSmNcdFx1MDAwN3FcZkCYfrNaL5WmtjDw46p7N9Y6PNO6Z/Vdb1x1MDAxY/3MvKPkud1k9pttXHUwMDE4rlx1MDAxM25OL0Hsti1vckPfte1pcWjDSy2IvMLKXCIqXHUwMDEzhG7X9S2vlj9ua1x1MDAxOFx1MDAwN+dOdD/yOFx1MDAxYzrTa+J8+klcdTAwMDOCqHiEvEfb7bhTs/WJ5VW7d0136IbdxbJMWmcqXHUwMDAyyVpxw1x1MDAxMTjM+WlWXHUwMDAyjDYzxYVcdF1V4lJcdTAwMGIyo5lvmrcvXyM4e77PJrDmWlKZp3HcZFJHP9ksuGSgcPLVfbbfXHUwMDE07WVwmXymXHUwMDEwmb4gI61/QnR3Vm76/Yp7XHUwMDBivyjevcNcdTAwMTX/K6svUVx1MDAxNOSI5PiyXHUwMDFjXHUwMDE5XlRcdTAwMTJcdTAwMDTbgCnjLI/pRFx1MDAxYjRXYnzTRLeDZGtflOnnz/ZmtdRGQyyRR3Ra7MxcdTAwMDItMcWavnpa51x1MDAxMTRcdTAwMWabht2QJ4fl7tWpXHUwMDFiV+zBXHUwMDExv+ougWaKjM4pcXNmkMJcbrM84WJcdTAwMDRcdMxMXHUwMDAy9vtcIndOdpNRNOetvmlYv7x+VZdwO8GtN1x1MDAwMlwig7xqXHUwMDA24YXVXGaKIWJcdTAwMTDTe/D28HuoXHUwMDBlpTWSXHUwMDE35qZ0tNfbq3X3tY2Xwq8gbO40xVx1MDAxOMCaolx1MDAwMr9rXHLfXHUwMDE1wLe2TNQkXGYlnOnMYYxkSlx1MDAwNFx1MDAxN8GXaK4kx287OTa6XHUwMDFldqpX142jnj5cdTAwMTKXp1x1MDAwN6N+7dJf6ohcdTAwMTGhXHUwMDEyQncy51FcYqqyXsNcdTAwMWHBK0RwfVx0XHUwMDA0K4NcdTAwMDVWJLecXGY+Qlx1MDAxMYJcdTAwMTljRIDb8ZZcdTAwMWSIfnA3vIvtK9FcdTAwMTP7LXPDbkejRk6xI5uwksYgKXHWXHUwMDE55lgjWZSrYlx1MDAxMjFhjEqqqkoxnoPcNWSLIFtwLlwi/1xcnKKGYaXyjC4vLkgwLFx1MDAwNEkq369cctlcdTAwMTSBXHUwMDBmXHUwMDE5n3olWkWeynM6UzDIZKniYCrpNJuimlx1MDAxOex8PmpmdKvJRl3iT1x1MDAwN+6BU+/d+lYjvO3dqMuj84WlRVx0irTJZKRcdTAwMThEo9pwkevYg+KiRHTFT2FJcfLbyi5/dcafP5yZXHUwMDE3izOTayGZJrnOvHjklFx1MDAxZVZcXFx1MDAwMqVfsLJSLlmHV1HTJ63tnltcdTAwMWSWy5Vm9/TVKiv5o1lAqFx1MDAwMM/gSnGBqZZaXG7KZlx0IdgjhFx1MDAxMMBcdTAwMTZiXGbG4t5N+/1q9c/gQ3NxPlBcZlFcdTAwMWMn3ORcdTAwMTdVXG7DXHUwMDAzKTSVmvFXd64ySlV2XHUwMDA2XjBK+tqo+268XG7Vem515Vx1MDAxN1oyr2aFM1iNso3aW2eq9G2vXHUwMDE071xi4pxcdTAwMWbXyr3b0cLKplx1MDAxM1x1MDAxZpIyymk26oeoSVx1MDAxYsl1bthEOEFA5vFjY3nLoTOXiKrZqGtN61x0rdvPP1igXHUwMDE504JcdTAwMTf4pcVFXHUwMDE3ML+EXHUwMDFhpehcdTAwMGLqX9w6adOjlr+9U7luea3L3fZu53BcdP3TSjKhp46APUv/8kezgP5pbVx1MDAxMKcgflJTQrUhs5RhXHUwMDFhXHTGaEGqlyNcdTAwMDNcdTAwMWZpuJ7n2zpe+yVd7MVVUFxuISFayy1RMPlIjoxSolxiW3GO7Fx0yM2oYGkweFx1MDAwYsr3XHUwMDBirZlXvplRr0btuodmOGxslUNzXHUwMDE0nlebdVx1MDAxZrBcdTAwMTQurnZUIIqBgtiwTJFGIMbnXHUwMDBmXHUwMDExrNVuVfR1nq92XGbIpLTOPTDEXHUwMDFmSX2D0HHOXHJ/0vdQnqZ2Mtopu63Wxd2x43RcdTAwMGaZIC6NLpZTO57Iy2rULn80i6id0ogl32JcdTAwMTFC5ahcdTAwMWSHWFDpuaM1a7VbXHUwMDA1XTqLq1x1MDAxZGdJQj377dxkQqrYXHUwMDA3NJxcYjB2YrXfznpcdTAwMDJw36rY/UJqXkDsSn1cdTAwMDc7X1o3n3v+3Y4tfH1WOtxeXFzsiEBY5Fx1MDAxY0dcdTAwMDChMvOHyNdCtyrmdlcgdEBMTFx1MDAwNc+jNGOFWU1cdTAwMTh88u1j8pJCd3B61t7e2o9L/OJz42rn02nnrt5aUuhcdTAwMTjneJpcdTAwMWZPXHUwMDE3uvzRLFwidFIjXCI4hG1cdTAwMDRcdTAwMTY4I3RCoTmXca1yq+BKb3GVXHUwMDAzpFxiQzHNPXZWXFw1Jpopzlx1MDAxNZGrrcE9XHUwMDAxtm9V5n4hMquVuXdcdTAwMGamYNNcdTAwMWFcZqoxrOjEMm5eu87NdrEovHvgfFx1MDAwMnRnbFB/vPvxPz3DlkkifQ==XSUAAUIsDeployment UnitAppAppApp \ No newline at end of file diff --git a/guides/deployment/assets/microservices/bookstore.excalidraw.svg b/guides/deployment/assets/microservices/bookstore.excalidraw.svg new file mode 100644 index 0000000000..8f96b5610b --- /dev/null +++ b/guides/deployment/assets/microservices/bookstore.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1dbVfiSlx1MDAxMv5+f8VcdTAwMWP36zXb3dWv91x1MDAxYuqoOL4holxme/Z4XHUwMDE4iJBcdTAwMTFBIai45/73rY5KXHUwMDAy6SBgZtRdOHN0JCF0knrqeaq6uvKfP758WVx1MDAwYkc3/tpfX9b8h0a9XHUwMDEzNPv1+7U/7ft3fn9cdTAwMTD0uriJRX9cdTAwMGZ6w34j2rNcdTAwMWSGN4O//vnP+Fx1MDAxM16jd/30Kb/jX/vdcID7/Vx1MDAwYv/+8uU/0U/cXHUwMDEyNO1ni3C21Vx1MDAxZFx1MDAxZXdOj3nx69fqQHFVNtFHo51eXHUwMDA20/dcdTAwMWJhvdvq+PGmXHUwMDA3fF8p4nHNXHUwMDE5NZpI0EyPt45wK0jmXHUwMDE5yolkYvz+fdBcZtu4TVPhgVx1MDAwMaVcdTAwMTljXHUwMDFhOIx3aPtBq1x1MDAxZNpPXHUwMDFi44FSyjClpdBMjnd5XHUwMDFhyF9fyPidQdjvXfmbvU6vb0f7XHUwMDBmalx1MDAxNG2weKw/6o2rVr837DbH+4T9endwU+/jxYn3u1xmOp1yOIqOjlx1MDAxN1x1MDAxOC/m2tR3nD+Pn029n/Up/NJWu+tcdTAwMGbsXHKg43d7N/VGXHUwMDEw2mtESXxcdTAwMTZ2hDfFZnSv/lx1MDAxZI+pX7/2i/ZmdYedzvjtoNv07S1Yq9OJb+s2n79tYu+B79sjUK25JMrI+HrHZkVcdTAwMTnI6bdcdTAwMGZ73cjGKEiBn9RcIv5gMNhC41xuo+Ne1jtcdTAwMDM/vtp2XHUwMDE0X1x1MDAxM4ZcdTAwMTefzPCmWX/6XGJVnNmxXHUwMDAwVyQ+aCfoXk2PvdNrXFzF31x1MDAxMr37958uWy5cXPvE/167/9buPm42RVeXXG77XHUwMDFic9syJUJ6hEnBOIAkkLhcdTAwMTj2RnElPI7WiFx1MDAwNk2lXHUwMDEyQFTKpnGLR41hVCtB7Mth1Vxcelxmz1x1MDAxOZRYmbPbnJnbnF/udXwj4fmdv1NWXHUwMDBlwkjCXHUwMDA0N24r11lWzlxio5JwI8QyVj5cdTAwMWVgPNSE1YX+Q3xnXHUwMDEyRrt3XFxqbKzvhFx1MDAwNX7+7ex2c/f48rFSW1x1MDAxYu/395/uwz59uNbbJe1cdTAwMWH5fsw25eD7XHKUOmfnMPktL99f7/d79/NcdTAwMWW3VFx1MDAxOPVG51uNLr+s3lx1MDAxNGtcdTAwMWJB58ivzXfc5//NgDxcdTAwMTCEPMlcdTAwMDfy7quXgvzExX9Gu1JcdTAwMWU3klxuXHUwMDAzXFwgrNkk2rX0KOWKXHUwMDEyKjPQbrTHhDFcXCs8IalcdTAwMTOAXHUwMDFlg52tQJ5cdTAwMDFymJ+zXHUwMDAwL62xyHSBXHUwMDE5708mZaF2IIoqyJuyXHUwMDE4XHUwMDE1SqpcdTAwMDXsNzZHa4Z/2W/rXVxywl4/wUCXvW5YXHUwMDBlXHUwMDFln7zQxLvb9eugYy+7mDhOoVx1MDAxM7TsJVhr4JD9/lryMoRcdTAwMDFcbsHxXHUwMDBl10GzmSS7XHUwMDA2XHUwMDFltFx1MDAxZXT9fnFcdTAwMWXW7PWDVtCtd06zx15cdTAwMWaGvVx1MDAxM3/wNPqwP/ST18bffUFcdTAwMDNFvMyA8nopuDvZUJtDfVlcdTAwMTl0XG7HuyrcekxD2e90gptBirtcdTAwMTGNhKJQNJpyXHUwMDBl8aWyXHUwMDE3ToLyJDWcKmqI1Fx1MDAxMNPCXHUwMDBiliXuICk6XHUwMDAyqYBySWOkxFjmXHUwMDFl3nahmCaUccE0/7/Cdsy+jF5cdTAwMTYvXHUwMDFmR9Ww269UL2jv7JQhqFNu/1VcdTAwMTegduYlepZF9OhcdTAwMTVcdTAwMTjeXHUwMDEwRl1y1vDUu2PXoFx1MDAwNYviithcdTAwMTLeyTXMwMOAq1x1MDAwMi2XXHUwMDBla3u3wWi0O/q5c3F4nsaDhVhcblxm0lx1MDAxM4YgXHUwMDFlOFFcZtQktUluPFx1MDAwNFx1MDAwMqVcdTAwMDYovkg6NiOe0pSh+1x1MDAwNMY4odqYNFx1MDAxY/AgxFxibaQmiFx1MDAxOJHA1FxuXHJLoeHszWjA4Fx1MDAwZe+1SoiOXHUwMDA0XHUwMDE4XHUwMDE4z1x1MDAwNFx1MDAwM8dwRKLYoe9ccobx2ze9YFpTx//7XHUwMDEyW1b0x/j///7Tufd6tjnbV8qQ4+Ol7mKnPlxiN3vX10GIJ3psXHUwMDA3mdIsYb1cdTAwMWZu4G1ccrqt6W1+t5mxJfpUwVxu6bZfT1x1MDAxOVx0fm5621xmt7FzJM9ONblcdTAwMTl+K6ybXHUwMDFmh1x1MDAwNXKyP7yay21QKZBcdTAwMDXRXyhJXHUwMDA0Z2SKRFx1MDAwNfW0JNqg44xo1OU2XGZcdTAwMDWNYphcbpCA0thcdTAwMTn+XHUwMDEy0Fx1MDAxNNAzod9GXHUwMDFiWbHo2/yGfrvbQJ7Am51cZnFiv4G3O9NvoC1cdTAwMTjNzMeR17m7jVxmc7avtCF/cr+x1Vx1MDAxOLBRYad2tlX5VtrYMsO66cL88luiczCCSSbwj6lgWmpcdTAwMTTnXHUwMDAynS9FgkKqWcnvj+A43i6/qUZ9aUHgXHUwMDEyXHUwMDFjXHRcdTAwMWKYdlx1MDAxY3irKceI7d1cdTAwMDXHXGY4sMui6F+Yeun2QJ1Vv5e39/drN/PnklFqRNkhheEm4SbhRaOJXHUwMDExXHUwMDAznkC3wohSXFwl0+7j6Vx1MDAxMeJcdTAwMDHRwsBzJpmmXHUwMDExXHUwMDAxnyS51KxcdTAwMGba/u/NLlx1MDAxZL09hcyFTfQr7co66excZjJl6Fx1MDAwMunEXHL/5Vx1MDAxOeRcdTAwMDLfrt2dnJw2XHUwMDA3e5XSaeVWfz8+Wywjq/CHZPlcdTAwMDDHPZpcdTAwMTRwXHUwMDFjXHUwMDE5WVx1MDAwMIJSnDOU4kaj7U9BRr9cdTAwMDJcdTAwMTnJPcvSyNWIPlx1MDAxNPyfOFx1MDAxZvtcdTAwMGWQOV5gXHUwMDEykaGVo1tK51csNli2YJSIKlx1MDAwZWo5bORpvrE1Pic1q+VKofBcdTAwMTGSsa/QznQydmrc+SRiXHUwMDBmNlx1MDAxYeHlaVNcdTAwMWbVO+XWYzVcdTAwMThcdTAwMDb91lxciSdthMeRgkFqSiTVk1xiXHUwMDE21M7nXHUwMDEztFx1MDAwMiRGIWV6Rlx1MDAwNa3K46j/tMBcdTAwMWa2NMBcdTAwMDFhjFI9jSEop5IrTkF8XHUwMDEySP/+KZZSXHUwMDBlkSFcdTAwMTNcdTAwMTjjUVdCXHTFfibOqcR4klximjfOmXX+NGnT71x1MDAxMlx1MDAxOWabqX2lXHI0Pl6KiT9DYHhFdveCPb/SfujWz/pcdTAwMGbte3V1cDK3XHUwMDEy1pR7Rlx1MDAxYkLQJVx1MDAxMKpoXHUwMDFjtkWszjV6XGbAKFx1MDAxYWM7SSCdVMJcdTAwMTjD09FW9qSEY+L/ZUr4XHUwMDFml9Hrk+P/fH5G51pIjOOkXHUwMDEz6ImRTFx1MDAwMV1cdTAwMTjFpSG/UepuXHUwMDE16vu3g2qX1jbaQXm4tVWsto5cdTAwMTeTuqBAxDb0JqnrXHUwMDFlzVx1MDAxY1JXM+1cdTAwMTHCrMiVWidcdTAwMGJSXCJQXGJ4XHJcdTAwMTRCe5pcdTAwMWFElaBcZj2xo84ob6n7v4GJ6vyYYERaJ86NS+WKdFx1MDAwMV1cXHZAjeRcdTAwMTTJIW+Vu6jlplTuln/T6Y3sd32pdIPwI+jdV8hlWu9mnkE+yrdFrk/PXHUwMDA2XHUwMDFiW6CGXHUwMDE3JDw9lZxt8XlzoMCMp5TE+Fx1MDAxZlA1XHUwMDExPpVcdTAwMDM1xEOYXHTBXHUwMDE1QVmQ4MExqJUnuZ6oXGaM0YzbXHUwMDE01XlcdTAwMTdccv5mUMdjXSThXHTD+mBTso3N+2pF0tOgWPTPkrVoa6Ojy7vyI7k9blx1MDAxZFQ2N7t3P69cdTAwMGW+9pfIiH6f3zlcdTAwMThALUqTU2Sxb1x1MDAwMJpZRVx1MDAwYsiYtnx0qfLCWcJYW8mdXHUwMDBmqW2fnsKBXzhpP55cdTAwMWbRO+L7XHUwMDFig4KD1Fx1MDAxY/OHwIlHUK9xo51cdTAwMDCwxbFgTVxcuFx1MDAwMWBcdTAwMTiSXCKYiXLxMVx1MDAwMojHXGLQT85qXHUwMDFmXHUwMDFjXHUwMDAwtflcdTAwMDFANdVcdTAwMDTvomvOXHUwMDEwWGZ6VFxiZYDQ3DNAXHUwMDBiXHUwMDAz4NdEhlx1MDAwZVx1MDAwYrav9Vx1MDAxN+ONP5+6OZ8hXHUwMDEy3GidboZicHG+397f3bvQ15c96M5Lj5yBR2ylLdhcIlx1MDAwMpd30EzirTRcdTAwMTneYUWP7+xcdTAwMWTq83tcdTAwMDdBXHUwMDE1Mlx1MDAwMGeu+ntcdTAwMTCpd2PpLCk1gsjcJ1x1MDAwNnPkx9Luj/WjenW3tXu336zdfT05eFx1MDAxNPOV5Vx1MDAwMWiPK8E1pVx1MDAwZVx1MDAwNKD9eqC1yUZcdTAwMDBCXHUwMDA0UD+6S81RXTJKTO7rSlZcdTAwMThIYuDHXHUwMDAyXGZJXHUwMDA1cC2EdoGAzSirYVRcdTAwMDLRkuVem/pBODJtxfa1XHUwMDFlXHUwMDFi8CdnSYnkV6p1y3fbJ+d3P1x1MDAxZb9cdTAwMGZcdTAwMDfBsZxvXHUwMDAyVKBQMEpxqVx1MDAwMFx1MDAxY1x1MDAxNMk8Qe20NNHM6SCkirJCkmKQqXFXR6r0f2FcdTAwMDZ0OVx1MDAxZpGXXHUwMDBiaCyQQqJ2MYLWriiRmcyCXFyEgZKKJWfA35xY/YjLumJIPGd3vt5FJ1x1MDAxMd+LpdNSXHUwMDFk/zJhj6mkVNhLzKlOZqQmxjudfppcdTAwMWVgPlmn7eNvj1x1MDAxN6MhXHUwMDFm1b7dXHUwMDBmXHUwMDAzMvxqmFxm5p9gIaictS3oXHUwMDE3YFx1MDAxN0pPrWOT2jN24lx1MDAwNFBV4G/jXHUwMDEw1qtVqzlkli/dbmGRkiOlOWUkufg0sdCNk0zZXGa2/Fx1MDAxNOPL37hotVX+QVT/uqBq/nFrv392UFx0TXUhb2HNXHJyqtVzj2ZcdTAwMGXG1aBsylZcdTAwMDNcdTAwMDMujFwik1V6XFxcdTAwMTlPaPTEXGa3uLEjjcdcdTAwMTE7oFDcK9T0n5hxfz9kWlx1MDAwYohpQoldyESdi0BZukovXtyiXHUwMDE5UFREuadcXFx1MDAxN7XfXHUwMDE02/X9u8C/z4Xu3jpcdTAwMGLzXG5cdTAwMDNN02Bq5Pnw4GXws3vky3Cjsrm/d9LyK9s792KBklvJPFv/x1X04pOVXHUwMDA2XFxxj0jEsVx1MDAxMZJcIqRcdTAwMWRcdTAwMDWEK1wizFx1MDAwM9XtN1x1MDAxMyFDV1x1MDAwYlx1MDAwNNWMXHUwMDEz7Dy9TiWeXlx1MDAxMVxuWLJcdTAwMDLxl1x1MDAxM2FcdTAwMTWOTkj7olGT181OUKhUiyUm37t7w+3xRri+V1xytnZape3Bzk31W1ls5SXzmaFU8iTAlydu99Wbg7jRXG6oZ4ixXHUwMDBiSjDwkGpcbuyae9IojIKBZoBcdTAwMWSdXHUwMDA1VcagPsZcdTAwMWa2R9GKuefHeLBcdTAwMDBzS6ZcZvrdjI5DekZcdTAwMWSF4WbSXHUwMDBi5MTc0q78flx1MDAwYnP3+k1cdTAwMWPrRyDuVyhzmrinXHUwMDA3nlx1MDAwZm//PFRcdTAwMGal7vpeYb9cdTAwMGaDVoVcdTAwMWQ2rpqlNIpdK06Z8GyNjeTIuFxiwslcdTAwMTWnglx1MDAwMepvqimNpozAUTDsaYlcdTAwMDZcIlx0R4FcdTAwMDdaKMeKU0rRU1BkfYNBkkR1sOojloHqn28vXHUwMDE4NppjsOReXHUwMDE5QGfkvFx1MDAwNeoyzbRcXCbjNXE2XHUwMDFmdTVptqXaV9pG4+OlXHUwMDE4+TPkwOtFsnW+XmTfqv6oVdlU3++a/TmLSIzyQKJHXHUwMDAwIJrhpZhyXHTMTqGBoLaPi1x1MDAxNumInFx04zGC5Fx1MDAwMSjnhdSOqTL0J1x1MDAxZTCDL9RcdTAwMDaA6mDF81x1MDAxOVx1MDAxZeHqzVx1MDAxZYFRXHUwMDA0oWLGuY5cdTAwMGUvfaZHYIZHa69/gUdAXHUwMDE4mqXqKPNdX55pqfaVttFP7lx1MDAxMWbHOlPxyKRLYFx1MDAwNDxGiVBWunGYztJcdTAwMTnjXHQhOWpcdM2iNVx1MDAxNymfQFx1MDAwNVx1MDAxZVx1MDAwMP1cdTAwMDVcYkC5XHUwMDBmhjlcdTAwMDJ7ajtEYaBgxSpcdTAwMDZcclxcxFxuceVcdTAwMTQmnEInXHUwMDA3p4Amj7cho6VbdqdcdTAwMWGJN1BM9CPKzSksXHUwMDFkXHUwMDE05OpcdTAwMTSyLdW+1tNGmqdXSNzB567B8zSIi1wincYwmpj1XGJG41x1MDAxYThKelR0XHUwMDE0XHUwMDEyLm2tVb/BXaTHKWoyhfyOvzlP28iEO8pcdTAwMWHS7LhnckiEodyyU+bW19raXG5wjFxubFx1MDAxYlx1MDAwZnQtXHUwMDAyY06lddpyXHUwMDE3cYXTXszv/Ojdz5VcdTAwMTDpXHUwMDFmqetNWl2vXHUwMDFmXHUwMDA0hJPzn5WLdrud9pKOhFxiQ2VkXHKCXHUwMDEzPGE81ensJ1iuXHUwMDAxW1ul8dIn5orG1UXKI4B0I58zoGlcdTAwMTeZiG1XLnHCJV4vtqyEMkmcXHUwMDExksh2fUxcdTAwMTOtqFwiy2RDZrs+zrShi3Rgjs3xOa3Q6Pt4yC9RdsGZXHUwMDE1SVTEv+PsvXuY+eRAZqdcXGfKXHUwMDFizoVnojlcdCpR6E1cdTAwMDc8tj2ZXHUwMDE2RFxiLW3FdVxut4DxXHUwMDEyoFRmiH5hILFaLNY2yCraukEmOeGCrzIgXHUwMDE5OO7Oj2MqbHdcdTAwMTaulFx1MDAxM8jZaU3D0fmi9F9mjuJcdTAwMTVcdGOE0kvhOFdcdDOxt0LjZFx1MDAxMknVWONjSr326fVMc/5cdTAwMDWHS+Hid6ipuaWLrYjUUnIhiZRghG1zkVIu2rNSiuApXGKiKSqX5IGCh3ioXHUwMDEzt8hcdTAwMTOGalx1MDAwMqCkpVx1MDAxNTLZXHUwMDEwkeLXXHUwMDFhbpf+U4lfL1x1MDAwMVKXJUOtLVx1MDAxZjxmK6ZcdI9cdTAwMWOdUdlvOVx1MDAwMVx1MDAxMX1hcVC+8Vx1MDAxYlx1MDAwMVx1MDAwNinpL5zeNsOdzy6Um+nOQUYyWFx1MDAxOaWp1jKxfPSpXHUwMDE1mvBsNULUQ1EoV7BqqCds4otI/EeIclx1MDAwNas2TIi6llPUdPyzTEa/Q1ub3vxcdTAwMWVcdTAwMWQwYDGEXHUwMDFiV1BqMpf04X002lxikb8/XHUwMDA3+2yM91x1MDAwZkkn9l5X2uNcdTAwMWFjUFSx6DZcdTAwMDTlr318Pduef81cdTAwMDFT2PhcdTAwMWROfXbN92xfjFx1MDAwMlx1MDAxMENhbeerQaPPVVx1MDAxM6dDPKYkQfmvbHNEQFx1MDAwZXNdoDjeTTHEy1xyXjDCfj3ozz4jZaS2/lx1MDAwZkN8YXSc+rUv1NHMcFxmMpFbhCZUv/l0PjXR3MLljt9cdK7rQbBbOyS7VXLub85XXHUwMDAxwYQnXGLyNNeColx1MDAxMp2kXHUwMDE5ZllcdTAwMWOQ5DVcdTAwMDBPls2NaYbY9XRcbnVcdTAwMDDGlFRR7YhcdTAwMWI+S8D/XHUwMDBlvHIzP68oKpEg0u2S1mYuXHUwMDAzYlxu7y0oyD/VXHUwMDE5VUkt1UXpJd4/slx1MDAxMfRmXHUwMDFibVwiedU/XFy871x1MDAxZWY+8f51v6NO4Eepb453drbPN8qV/Y5jOsOVqKN4aI3wlUh6Qk22fpGMWXmI+lx1MDAxMW1UKFx1MDAxN26BeVx1MDAwNMNcdTAwMDGCQc1Tf9BcdTAwMTVuXHUwMDE3wO3t/LhcdTAwMTVcdTAwMTQvMFHc2Vx1MDAxNjtTXHUwMDBmXHUwMDFhVPxEc75MV+zXcMuSJejL1C11v3xcdTAwMTLoZo40XHUwMDFm9O6ellx1MDAwZWvhYbVdK7VJu7kjR61+PY3erEpjbtmV4N3A8JlD8mF6T51KXHUwMDE5alx1MDAxYy5cdTAwMDSyL0FAO1xujUHblXxcdTAwMTgjWlx1MDAxY6tEXHUwMDEzhURLM/RcdTAwMDO2U4LN+tomT6tcdTAwMTAvXHUwMDBi0n03pFx1MDAxNyg45nZcdTAwMDLeSdBcdTAwMThCZC4tsOtFNF9yne54cFx1MDAwYlVcdTAwMWKfbDSrP4OrXHUwMDEyuyhfYfzTLIR7d99cdTAwMTbs9MuEymnZjXs082lX7dme8dqAXHUwMDE2MFWpbyuAXHUwMDA02Fx1MDAwNqJ2XCLRaObIkTDu2SSgXHUwMDAx+0BL2yXNQYIrxGQhZjA/XHQylFwinClIV+o8oSMzz81cdTAwMTjYKVed97qbhVxyOMWCW/4gRK5cdHGwXHUwMDFmoob3XHUwMDE1Mkq3QHNccj9cdTAwMWZeLG1Vu9fF4Fx1MDAwMX8x8vWRXHUwMDE0u1x1MDAxN1CZm1x1MDAxN7Vt8MtcdEpXsF1cctnU8nVJPIFb0dVcIn+Co3TPdk5cdTAwMDUlteBUSSNFojwk5kWF4tlcdTAwMTDUV1IpZODYXHUwMDEyPjbIezbD9HaQx5xWfFx1MDAxY+2WNtTm9uWmf1x1MDAxNfo/arunncJcdTAwMTLL2cM3s6e27dpNxmpcdTAwMWQw2a3yjUQnL1x1MDAxNM+70YWyXHUwMDFk5HN6pPDobnhZvr07O2jrXHUwMDAzcXW8N7o+vXK0PMpChLJdjezjXHUwMDAwJFx1MDAxMZBseVx1MDAxZCHCbrX5MUq5XHUwMDA2lpCR8Yo0j9nJX6NA20fQMIdSxH2UxsNcdTAwMWI8POe4XHUwMDEz/Vx1MDAxY5DI/cEoeSFiuMAksDJcdTAwMDRlPHU+clxyI4TsTkeM20eE0KXKOX6X7V/3XHUwMDFlh49h81a0xU7N3MPDaHQ2V45cdTAwMDOJ3zNcdTAwMDa4pFx1MDAxNO07WbTwRFx1MDAwNNKjXHUwMDFjf1x1MDAxYZSATKl0KVx1MDAxMiBcdTAwMGbYZ6eQaHtSXHUwMDFmfjp192Gt/G5cdTAwMDEr12hVQJRydTJSXCIzQKKKUlxmkWCpubFcXI08pVx1MDAwMSvFj9xmZGJ0+Si7fWZ6jTP/sUX4fneTXHUwMDFldnbu+ntcdTAwMGIoO+EpKe1jVVx1MDAxNGBsNqXsbDTG0Zs9LdVytVx1MDAxOLHFiVxiZDRcdTAwMDdcIjFmNo7JXHUwMDA2ZZ9ZamHPpK3wSDy0dFx1MDAwNfBlXHUwMDAwfv9mYYdOXHUwMDFhVYtt2enAPcZ22Vx1MDAwZvhcIlx1MDAwNnU+W7LP7XiAXHUwMDBipUaGu+K+Ubx74Oe3Ye1Ql1x1MDAwNyVfNFx1MDAxNkyN5Eed7tHMRZ3GU1x1MDAwMIhcdTAwMTJj+1xmiGmkmVeQZlAxXHUwMDAyYsjQ7DLeXHUwMDE1db5ccllcdTAwMGZcdTAwMGJQJ0TTOFx1MDAxOVx1MDAxMGLpuYVcdTAwMTdcYmmlXHTGwmKZaYRfS531m1x1MDAxYjzrMKPSN+/cyVxmXG59jdOmWdUx8Hy49WqzS47C036hXzrUdfgpW1x1MDAwZmb+viVcYnQvmoW3vUuEoJNcdTAwMGZNsjFcInphRjFcYiTGVbe/ilx1MDAxMd/BXHUwMDA1jFx1MDAxNnBcdTAwMDHEcK6Vcj5cXFx1MDAwNVx1MDAwNVF2jIjUXHUwMDBiv6JcdTAwMWJunkT3ba92QDZcdTAwMGW3Tbt691gsr9dcdTAwMWFb5f25bd/YVY54ioaDUizZxunF9pWyne3Ats0lq/zIh7D9x0VcIkdbpFxyLvKjTGYvdjGCXHUwMDExbnjuj5Ze0vL/eL4+lkLKIVx1MDAxZXKso9dsI6yN7K7Jfzzjxlx1MDAxYYRcdTAwMWbJ77//+Pu/XHUwMDFmXjB9In0=bookstoreXSUAADeployment UnitEventsreviewsorderscreate orderOrderChangedon OrderChangedDestinationsUIsapprouter \ No newline at end of file diff --git a/guides/deployment/assets/microservices/complex.excalidraw.svg b/guides/deployment/assets/microservices/complex.excalidraw.svg new file mode 100644 index 0000000000..ef479520df --- /dev/null +++ b/guides/deployment/assets/microservices/complex.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1d2VLjyLZ976+o4Lw22TlcdTAwMGZcdTAwMWRx44ZcdTAwMDEzXHUwMDFizGBcdTAwMWK4cYIwtsBcdTAwMDJPeFx1MDAwMnOi//3sNGDJUlxuLCOqoK5cdTAwMTXR1VWSh7S01t5rXHUwMDBmmfmfP378WFx1MDAxOYy73srfP1a8x1q16dd71YeVP+35kdfr+502XFyik3/3O8NebfLKxmDQ7f/911+tau/OXHUwMDFidJvVmodGfn9YbfZcdTAwMDfDut9BtU7rL3/gtfr/a/88qLa8/+l2WvVBXHUwMDBmXHUwMDA1X7Lq1f1Bp/f8XV7Ta3ntQVx1MDAxZj79/+DfP378Z/InXFzx6/ZcdTAwMWJ3WHmjPSw2T4t8J58/6yuuTszkrZNcdTAwMTe9/oSeV1x1MDAxYlTbN00vuPRcYuelYUgxzKVWYnphXGZcdTAwMTeYpMhcdTAwMTCOJVxyzj/49UFcdTAwMDOuaY2UXHUwMDE0cFx1MDAwNT9cdTAwMWZ8+oqG5980XHUwMDA29r5cYoJcdTAwMDRcdTAwMTHhdz9/+98/8PRMf9Dr3HnrnSb8Vlx1MDAxOOK/iFGkRoNcdTAwMDFeVWt3N73OsF2fvmbQq7b73WpcdTAwMGbuSPC6a7/ZPFx1MDAxOYwnn1x1MDAwZc9cdTAwMDJu4krkOyovI6eR80nvgi+9abS9vr3rZHq2063W/IG9O1x1MDAwNFx1MDAwN7/CjrC7U588oH9cdTAwMDdj6sGj3bFPqD1sNqen/Xbds/d9pUpmvq1df/m2mVf3Pc9+XHUwMDAy0ZpLrIxk0ytcdTAwMDFcdTAwMDJcclx1MDAxMdGzXHUwMDA3nfZcdTAwMDSNhFCDiTGhh+D3N1x1MDAwMFCDycdeXHUwMDAzKL3gZttB5ENgXHUwMDBifsuwW68+v4UoTpnWxlxiw4I70PTbd9GhNzu1u+BbJmf/+dOF31xcy8Pe+cXDXqP9tF5cdTAwMTdtfZTbX5tcdTAwMWK/mlx1MDAxMaSwwozQWfxyQlx1MDAxMMNcdTAwMWHGqeJcdTAwMDAmnCB7X1xioH6CYFx1MDAxNkcwl4gqxsNvX1wieFx1MDAwNsHUjeDX51x1MDAxYjw89nLmn1x1MDAxOLCZMFx1MDAxMlPBjVx1MDAwM9ha4SRgg1lS0lx1MDAxMMlcdTAwMTfB9XR4wUBDOFx1MDAxYniPwXNcdMF0t3hUW1vdXHUwMDFh5Hhlr3y/vl28fipdrExf98/L31x1MDAxMklcdTAwMDO2XHUwMDE0sEZ5NqRxjyZGmplcdTAwMWbzzFx1MDAxN82RxlJcbqE1U9qQWdJQglxmXHUwMDE3M2R65Vxm48jAIVxy15RPmOOy+kuuuLnC5rf2XGZuraGYXHUwMDEyXHUwMDA3J1x1MDAxNKVJnFCEMEqUxotwXCJL2Fx1MDAwNii06LNcdTAwMTa+21xyPb1Oe3DiP9lcdTAwMTFTPHN2s9rym/Z2i5lPyDX9XHUwMDFi+9NXajBYr7dcdTAwMTL+/Vx1MDAwM1x1MDAxZiTT9Fx1MDAwNS2/Xlx1MDAwZvuHXHUwMDFhfGjVb3u9nXlcdTAwMWNNp+ff+O1q89Q16upw0Dn2+s/jXHUwMDFl9IZe+H5426/4J4iKN1i7euSPjtfU+lBfl/rNXFxxW1xyNp7irPWaTb/bjzg6wKBGIFx1MDAwNDSlXHUwMDFjaItVXHUwMDAwhMk9U1x1MDAwNGnJqHZRVyokJWFcXEjFXGKXJHhrwFxcjlx1MDAwNGg6RTUmlFx1MDAwYqqDJ/7/gcmBy6Lkeuf6aXw2aPdKZ5ekUz6lQOGYdX+X8GprXu9Ik7wj2Fx1MDAwMFxuXHUwMDBmhFx1MDAxMpfsU1omWVx1MDAwMlx1MDAwM/aDXHUwMDBirH+1IXiDXHR9rnLk5OjgYvfeXHUwMDFmj7fHt1uXXHUwMDA3lThcdTAwMTMsuWI0kFx1MDAxMHxgo4BcdTAwMGbEYCNnaaBcdTAwMTkyklx1MDAxYc2YwpxKXHUwMDE541x1MDAwMkZcbjiilGJAJExAyjqkn0HYXGJtpFx1MDAwNl1cdO7QLLnwMS6UP8xcdTAwMDVi5VxusCFcdTAwMTbrWCpIlVx1MDAxOFx1MDAwMVx0MGVCSLyQUvxcdTAwMTSv2O34USFcdTAwMWH87UeArMk/pn//95/OV68mw9lcdTAwMWUxIFx1MDAwN59cdTAwMTd7is1qf7DeabX8XHUwMDAx/NCiXHUwMDFkZEyfXGaqvcFcdTAwMWE8Vr99XHUwMDEzvea161x0VybvyvV6nYeGV42BXHUwMDA03lx1MDAxN732htnYOpTlU427w73cqrk6yOHj/eHdfGZDXHRcdTAwMDRGgTFcZlx1MDAxZVx1MDAwZZvAoj5bXHKJXGLmSlx1MDAxMlx1MDAwMzeTsoAtIathXGLTXHUwMDE4nKdgklx1MDAxOeNIeUDAiJkmTHH4XHUwMDBlKsPwWJqNRcyG/rjVwERRLFx1MDAxOI5cdTAwMTlcYms2eGJ8SVx0ZZJgbYKb9tuZjVx1MDAwNDzbI47kb243Nmp9Os5tXZQ3SntHa1x1MDAxYmZYNW02v/BWXGJzMFx1MDAwZlx1MDAwMFx1MDAwN6FcdTAwMTSZzTNJSlx1MDAxMTVcdTAwMDBcdTAwMTZrZiVcXF6q769gOj6uvonmWFlcdTAwMTY4TIdmiTlXzSTQPPxLv576ptc7ondpqkf3XHUwMDA1VT47P9nc37/oxumQkHIlWFx1MDAxMlx1MDAxNE23SkMh/lQzaaFpuYCjl4zRc7nAobjZN0lcdTAwMWPVq/2G93MzR4dcdTAwMWbPsnJhIVx0QtFcdTAwMDFlSWJnp+JcdTAwMTlcdTAwMWJCwHAtXHUwMDE0SE6HlyrLmuObXHUwMDE3o+Pj03p/t3R0WrrX58XyQ7osq1x1MDAxNlx1MDAxMPtlw1x1MDAxM/doYjyJZ1lBbmJkKNxbaThjXCIkXHUwMDE3n8miXHUwMDEyyVwiObL+XHUwMDE4vDKJZHO+XZb1XHUwMDE3kKWYoqhcdTAwMDZcIs9WMLnLwEucrFxyMaNcdTAwMTBx0swjyrTAXHJw+JKxPDsp5XJfIdP6jn+JZloj484m11pYq1xyrk/r+rDaPLl5OvOHfu9mrlxmk1x1MDAwMblcdTAwMTct/E1qI0IjncRaUG1I4pla45SuXHUwMDEwR8BQ1Vxml780b99QdcF4M6Xt0cfVmmSEcEOwq5LIQ/Y3XHUwMDE26YHC4yZ7Nn+NQC+Oy8nZXHUwMDAwkcFcdTAwMDfEXFzrd1xi7I42ztqtXHUwMDFk/1x1MDAxMf5Hcf5cdO+0L1kpRfNcdTAwMGJHsz0qk85cdTAwMTc4a3hC61x1MDAwYtfIYDprXHUwMDFkXHUwMDAypmuDXCKtNF+a6PWOfbQ/1UFcdTAwMWZ/WM1qqY1cdTAwMDZEu8Qs5YliXHUwMDE2wndcdTAwMDFPTn7luOzAlOtlebi/cXNf9Fx1MDAwNzv1boHf36RAM0VGO1q5ODPxXHUwMDFlmWlZnyCBmcHTbi5HZpNR9Jv4r09C9UlcbtlcdLLeXGKjpKuSXHUwMDAxaEpcZsZcdTAwMDTXmukv4KneXHUwMDAw8L7al9WxrJiHXFxhs7F5erOl6zhcdTAwMTWAXHUwMDA1YVx1MDAxMYk1QbCmKKG2vcRvXHUwMDA2+D1NXHUwMDEzNlx0Q1x0XHUwMDA3JLrsb1xcflx1MDAwNfjFyigw3L88pf5cdTAwMDZ+x6Ph9cn9qFxcaOiCuCvujlund+1UvbSESiNizYiCqrhsWFwiOENcdTAwMDSXUiBYXHUwMDE5XGZgJM5aMjE6XHUwMDE5wVx1MDAwNHNBPqGbVnBKM0pZtTpPw6dB/V40xNaFeWCP43HZUemIp6ykMUhKXHUwMDFjl8NcdTAwMWOCXHUwMDA1qVwi6JtiV1wiJoxtxjBUQdDs7Fx1MDAwNF9i1o3ZhK5cYndcdTAwMDe4ooZhpZzhbWIxQnBcdTAwMDFvM4v1yX5qT2Bpp59FpqrpXYdQXHUwMDEwy1NccjqhtNNskmpmsNGM1MzosslH3eHtXX/XKzVcdTAwMWXb1XLvsfGg7lxux3O7XHUwMDE2hVx1MDAwNdJEzsakk2CVXHUwMDAzXHUwMDAznW5FYMRcdTAwMTidiP6JV1x0QPxpVZd/XU+Ob07Lyvy05FpIXHUwMDA2z8XlSYSOJZanNUJcdTAwMGVcIlxunlxc8Fx1MDAwMz69sLKRq+7f98/a5GKt4Z9cZjc2ds5uiilcbivaYExcdTAwMTWTYewv7qXco5nDSylcdTAwMDI80JQzgplcdTAwMWTPbF2FXHSSQFx1MDAwNobtfFx1MDAwZlx1MDAwM49KR/vbP81R/Vx1MDAxZWw4m59cclx1MDAxNENcdTAwMDTHXHQ3roqK4In9qpxAQGxzOtnqqvSIjXmpjVJcdTAwMTZO6qPllHdcXEfUeYVcdTAwMDedje9cdTAwMTLHebo78Fx1MDAwZve3xvleP39SW8V0/rxcdTAwMTSIQ2RDP1x1MDAxMdeWUlx1MDAxOcS5olK4cq1KSWRIRJJO6Specq3cPFx1MDAxZoGAXsrMXHUwMDE5XHUwMDA2n8/PYMUxU5RjZ2REZWJoJFx1MDAxOMSv4FxmXHUwMDAzdZpccoOJzVx1MDAwNZkwZlx1MDAxN/c5m73B6vnd6HCrtDXK3W9dNLz1tfP5QUwoep4xXHUwMDE1k2BSwiVcdTAwMTVccvuXMuyDsL2YXHUwMDFmtlx1MDAwNCsp7NRcdTAwMThXTUDTRFx1MDAxZEa44OB2XHUwMDE4/olCrLu3W3wqXHUwMDFmn++QvVa5XWrsXFxcdTAwMWVcZmU6IVx1MDAwNmhcbrWufohcdTAwMTTu0cwjxChFhoOgYiBmVVSISaneoMRSjC3KiWpcbk4wcKzYSjJcdTAwMDcnZHKWi1x1MDAxMlx1MDAwZVx1MDAwZlRIlXGWKz1sv6hcdTAwMWF7x498vlx1MDAxYTss7lbu97y7XHUwMDFibdY3VaW7ZiprXHUwMDBlNeZuZqbEIEZZdFx1MDAwNu9zV5pAnCgjnVxyLlxuSa7dZW9cbtdmazbfkbJpWlum5nqleHJ5ID1WPzmRzfJFcfPycJVcdTAwMWSH7P6K75f11v3hfelgW6rty+K+f9vuLtDRXFxLk+BcdTAwMTZKXGKKtUvG0eTONiCp4VpmXHUwMDFlh1x1MDAxMYVZaCbFh1x1MDAxY9bh6Vx1MDAwNW6tnXuXZ6TY2dzDVMq9q3naulxipVx1MDAwNlx0KTg1sVx1MDAwMrk0XHUwMDEyJTV8XHUwMDE4ivBLdSaOfIzobFV9XHT8zIFfn1x1MDAxZvhcdTAwMWFAr1x1MDAxOHW6PEpcdTAwMTJnznNcdTAwMTCBgHr2y3E/PZ1pXHUwMDBmmFx1MDAwM8H2WH1cdTAwMDVv8P7Yw/lcdTAwMGUtYI38QWfcJEfNrj66zl+O6MX6/u287lx1MDAxMH4/XHUwMDEyz6WraL+nbdKONNMsneFcdTAwMTexXHReXG5niJmQVEm3UYg3f09jQ1x0poRQxlx1MDAxN4pccn+SN9yq3JWv+lx1MDAxN0/Htf3e+rDQ1KWrh/qc3lAjTCmPNC2PJ6FcdTAwMWSL9jJPnSFBTIhZUoScIajL2fctoZ859K9TQJ/aTjOCqVx1MDAwYvokPlx1MDAxYmhcbn0lmDGU/nLkf5I/jIPYXHUwMDFlq1x1MDAwMX6/uUdcdTAwMWPk9nrkKVdcdTAwMTXbT/qAXHKOh49jtTpPUlx1MDAwN8ydQTqekH91h4q9scKMJsZIXCL4c6Lf4Vx1MDAxOL9JXHUwMDFmyFuzllx1MDAxNrNccllR/yZcdTAwMDX1XHUwMDE5XHUwMDE3WnDinPhOVGKXqWBaMUHF15HCr8mf/GjyNcHd+mo9I9FcdTAwMDFmk+zpXVb1KeejSlx0V82IXHUwMDFkXHUwMDFkPPFNXHUwMDA3l5OqXHUwMDE2XHUwMDA2Yl5FqKNqXHUwMDAxVEZ2fr+7Xk6JRlRcdTAwMTLlXuZccmRzXFxcdTAwMDd8aVL//FRtI42fJkIrsJ3Oslx1MDAxYiGJk5eIsClcdTAwMWKpZOaVc82IzqjXo01PXHUwMDFl6+eVY72+3ezf+uVcdTAwMDbd2Zq/J1xcXHUwMDEzguzCXGJcdTAwMGWPxLhCRL6s4lx1MDAxOUPwsu62IHD9XHUwMDE0wFx1MDAxNZhTzXR8/aWVSVk0XHUwMDExt0xyLmQ4QfnpdbfjfIXSfO3hZrNYz7dy5yVWZK10dTfJXHUwMDE5zqjR3D2aOSSaplx1MDAwNEGARlx1MDAwNXj4eN1cclxc91x1MDAxYpRY1t1cdTAwMTblxG1cbk5wwjDgO76sguVEvOc8mFZcdTAwMGVmXFxKXHUwMDFkmlx1MDAwMp6RLU9cdTAwMGLbmPT6XHUwMDFhdbd3/Mjn1930w9lo78S/Or3CXHUwMDE1dnnQuT7tqOrcjsxQjsCVRyeCT25cdTAwMTiILW2iXHUwMDE5xWmy0UiEyUSK8UijU0iQXHUwMDA101Ij61kvZdlcZpPv5meymtxR7mwqIeyNXG46tnV3qnjWTFx1MDAwNtktcUbdUFt+Ya+3092vXHUwMDE299dcdTAwMWZcbk1Z0Fx1MDAwNVGbXHUwMDFmzExcIlxumso11Vx026l60dBhqco+iNtmqvIvtcuIMfeid8m7XHUwMDA1SEpAQFx1MDAxOL1cdTAwMTBuXHUwMDE3U2XD0cg/q6z1ypdcdTAwMTdcdTAwMDdblby3e4vLJpUqy5JcdTAwMTTu0cyhyozdLFx1MDAwMFx1MDAwNC99nVx1MDAwN1x1MDAxNaGEeoNcdTAwMTJLVbYoJ1opOEGx5ppqZ2erwslz/ijYclx1MDAwNS47887WtLD9oqrsXHUwMDFkP/JcdTAwMTO6ofztw1xc9zH/yLuNPWnG40vccqzzk7yWXHUwMDFkRVx1MDAxY7uaQjjBXGKDXHUwMDFlX+4g8nlcZm67XHUwMDE5nGZtO4w15Vx0rb8meTlcdTAwMTDwj5iKcP33033d5XatJtjA3Jw0XHUwMDBiR7hSvL1ty910vlx1MDAwZWvNMypcdTAwMWS7RzOHryOEiMmEdUpcdTAwMDTWKtSe/7yDXGJGyk6vdk9cdTAwMTde7iHyY3G2dFL4Oy0gbtTOXHUwMDBlQFx1MDAxNZ+fNVxyXajEeGbB+4y8XVrgxrzdXHUwMDE32UPkXHUwMDFkb/NcdTAwMTP2XHUwMDEwXHUwMDE5XHUwMDE11mmnsNZvlvP1s8JBlzfGXHUwMDFimyn8XHUwMDFkyE0qdbR487rj27JcdTAwMTL0/Fx1MDAxY7OkbTdcdTAwMDVtXHUwMDE5YVJy6ZxBSYhO1KlKXHUwMDEyXHUwMDA2z4EslFD/SVx1MDAxZefg8dy/f3hcXD3uXHUwMDFmXZn+Re+hkdOHKZDLKUCNc1x1MDAxM+9cXGdcXCBD3Y3ry4zDgrC9T1x1MDAwMVvC4a5o9zZu4Sm48YyDrVx1MDAwMpmfOP1qVHo4XFzbrz2Wx/zy6HB8d8Z6ZfzLRJh7NPOIMCwgbqFYXHUwMDEwaaRy1IFwXCIhlvmGRVx1MDAxOdFLwVxiMDTUMKKci1x1MDAwYpvkVbKYvZvGZF7R/7hcdTAwMDL7XHUwMDFh+YZ3nMjn51x1MDAxYvauzjeuPSZcdTAwMWLkrHC/2oRcdTAwMDcw4IX5vVx1MDAxODVcdTAwMWHxmGJ6XmfJIFx1MDAwNrxOaDlf5lx1MDAxYjJgcN/N4DT5XHUwMDA2QZVRhlxiV3LdxJvMp411ymhFmVooslrM1Y3VcWVDXlRcdTAwMDXPnZbG6np4xZ5W07k6u+hkRjON3aOZx9XZVV1cdTAwMDT8oZz5XHUwMDA2YpBJXFxBYplvmJxdkC2D+f1cdTAwMWTHjGvjnnnlyM29skJiXHUwMDEwXCK2hShrb5dcdTAwMTa4MW/3RfJccu94m5+Qb9iSXHUwMDBm+db4eH1nKNd6q9U6Ld71XHUwMDFkK1x1MDAwNCT6O1x0Tsk4lyVmkiDF3a1KlIC8teI0vrpLXHUwMDEwtmFcdTAwMTh6dFnjJYVnKDxMXHUwMDEzxEkuKZXx5vBnXZpcXCOTtpYlVObTRShhoVx1MDAwNOaHvM/tZf6gfjzM6+L2zkH1avOqmJfjXHUwMDE0KFZcdTAwMWHBWKJofc09LJtcdTAwMWSyRe1oftSCXHUwMDAxoKDJaLytYcVmxZJbpzVEzYaEN/L6dEHWLlxmjlx1MDAwYni4dbOTOypsXHUwMDE3jnWf3zd/mSBzj2ZcdTAwMWVBRjXEMKDHZGLuYdnqkDEjXHUwMDFl5meEYkppSp0pZEWT15eXTDOQ2ItFKJ+qxb5G5uFcdTAwMWRcdTAwMTfy+ZlcdTAwMDe8lz+/XHUwMDE23Vq9aM4vb3M75cf8uFx1MDAxMyesY7IvhFCgtJhr/VguXHUwMDE0XHUwMDAyt1x1MDAxZpkgNN25T6DoktBB6YdgXHUwMDA0z5f+XHUwMDE2q5J/0r5Gj/PTXHUwMDE21LCGxyNdfVxmyVu9XHUwMDEzMKRcdTAwMTQkcNZrklx1MDAxYvhP6l8/V3c1jkB7hLFcdTAwMTd8RMx/fofJur5oNXP1wtnJsHreqzxcdTAwMWNcdTAwMWQ/dXLDOKtcdTAwMTOWr+BcZtnCXHUwMDBi1rZCXHUwMDFioGRiXHUwMDA2rTBcdTAwMDWBw7VduJ6FaofLjWmfz6aZw3tRL283N/imeNpvn/O1XG7hu7tPXHUwMDBizOFcdTAwMWS7LUKKnc5cZoTSyi7U6TJcdTAwMTQ02VJcdTAwMThhUzQy+zU6XHUwMDA1XHKvJfAhTVpbv3ystFx1MDAxYZWKf6T7R6PWfvNBzreeXHUwMDA143ZcdTAwMWJmbNOA2Fx1MDAxOEkjXHUwMDFkuODlYJRYYKpcdTAwMDDpXCLu6TCyXHUwMDFkS1bNQiyBwaw6NqnlXHUwMDA2YWO3edZcdTAwMTDTzXTJLLmwXGJcdTAwMTeePsxcdTAwMDVcdTAwMDKGidp1XHUwMDA1XTlcdTAwMGJcdTAwMWSf/Fx1MDAxZUzRsPu7K5G110zNhU/ymslotkdcZsff3IVu7/Pb+pE68mlxKEt3+3Jri/fnslx1MDAxYZxcdTAwMTDEJMNWXHUwMDE5a7hcdTAwMTWBj3y2XHUwMDFhxu5uXHUwMDAyMkNcdTAwMDPKJIl7ULuwNWE2uUlcdTAwMDSz2/Y69j/hXHUwMDEyYbuNuJ1sXHUwMDBm9jm8b8bSbCxgNq4w/rjdXHUwMDAwpk4o68xcdTAwMWGFotWoXHUwMDEzXHUwMDA1JUrgWZvf2HAkXHUwMDAw2lx1MDAxZXEof3PLMbpcdTAwMWGaQeVg42r3Sd7v17o3ud1TMb/4tptyge1cdTAwMTBYMFtfnDVcdTAwMWVGICFcYngoZZRcIiHZtZTfz2d/ie0gXHUwMDFmt1x1MDAxZCBcdTAwMWa5XHUwMDExRDpcdTAwMDW4ilmUV9thXHUwMDA0J1x1MDAwNpxI5rNCM9Tf90xwb/NyvXe92rxsjtj1Vpk6dlx1MDAwZnPpb1x1MDAwNdEmnexr6UoxSaGpe/9RjDSOzFx1MDAxNpjCX3PE1GcsKffbZJiuMHVcdTAwMDPaWeGTXFzY3lx1MDAxNSdy44vPhJeDI4RknmJcIkKF17b5hT4vikB7hLD3zZ1cXGljnbIz0s49+cNu5eL6orS/51hrxEFqLMHhq9hcdTAwMTYsXHUwMDEz96Ywojxp0WRQXHUwMDA3KDqnLpQ4XHUwMDA20Vx1MDAxZM1FL2k9S2uWgtaY2O1XmLMlLVnLKkylXHUwMDAxXHKTdT5cYlwia8VcdTAwMTaq92RKa1x1MDAwN1x1MDAwNO2xXHUwMDFhRt/3IfZcdTAwMWYvY1updrsnXHUwMDAzuOFTzbIy8r2HteS651x1MDAxZi9mwfLAm0idf/7457/Lj1x1MDAwMpAifQ==AppXSUAAUIsDUDUEventsDUDUAppDUAppDU \ No newline at end of file diff --git a/guides/deployment/assets/microservices/late-cut.excalidraw.svg b/guides/deployment/assets/microservices/late-cut.excalidraw.svg new file mode 100644 index 0000000000..f3d5fc9e83 --- /dev/null +++ b/guides/deployment/assets/microservices/late-cut.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1d2XLqyLJ9769w+Ly21TVcdTAwMGZcdTAwMWRx41x1MDAwNp7xjPGAuXHCIYNsZDNcdTAwMTlcdNtwov/9ZmGbQSqBXHUwMDE42rBPw8OObUmIkipXrszKof7z28bGZthpept/bmx6XHUwMDFmJbfql1vu++bv5vib11xu/EZcdTAwMWROkd7fQaPdKvWurIRhM/jzjz9qbuvFXHUwMDBim1W35DlvftB2q0HYLvtccqfUqP3hh14t+F/z75lb8/6n2aiVw5Yz+JEtr+yHjdbnb3lVr+bVw1x1MDAwMO7+f/D3xsZ/ev/CXHUwMDE5v2x+MUtvduvti+rVXHUwMDA1y+7tXHUwMDE1XHUwMDAyyWRe977au+j7XHUwMDExWl4pdOtPVW9w6lx1MDAwM45zRFx1MDAxY8qk4ILw/olcdTAwMGWcoFQ4TCg5OPrul8OKOYO4o1x0l1xuXHUwMDEzjuCD+1dUPP+pXHUwMDEymkswc1x1MDAxMEf9S5DoX/M5hj83UP9IXHUwMDEwtlx1MDAxYS/eTqNcbk9cZlx1MDAwM/1cdTAwMTfWXHUwMDEyl8hgmFx1MDAwZm7p5anVaNfL/WvClltcdTAwMGaablx1MDAwYt7L4LpHv1rNh53e3WFG4FVuRn7j9utcdEjkeNK34EefKnUvMO9+8JSNplvyQ/OOMFx1MDAxYTyFXHUwMDE5YTNb7k3Tv1x1MDAwN2NqwVx1MDAwNGfNPNXb1Wr/sF8ve+btb7p45Nfq5a9fXHUwMDFiuTrwPHNcdTAwMDesXHUwMDE0XHUwMDEzSGpB+2dcdTAwMDZyiFx0ldHDZ416TygxxoowQcngXG4/2Fx1MDAwNblcbnv3fVx1MDAwNNn0XHUwMDA2b9uMYi8qc8NyNyR7L3fv9/l6plPGb7n8Y1x1MDAwZd3u+iei/0Qj8ue2Wo33zf6Zv77+N3hV7WbZ/Vx1MDAxY1x1MDAxMJaMMKlcdTAwMDQmQqr++apff4m+mWqj9DJ4ht7Rv363gSRT85B3V3w/rtS7O2VeV7nMyXZ6kDBcdTAwMDQgoTKCXHUwMDEwhWLYIFx1MDAwNDuMUq7h4ojg98GBMXVcYkZ6+H5rVIyggthRMZDA71x1MDAxOaNfR/6KgVx1MDAwNeZAIMKZtoFcdTAwMDXLXHUwMDE4hvpgXHUwMDAxvUU0x5ouXHUwMDBlLN/iXHUwMDE1elx1MDAxZuEoOj6l8+hcIlfa3jpcYjPs9vjmdefw4rF7XZxcdTAwMGUrXGKDsl5cZlbso4lhZeRhejBcdTAwMTGUOlxcIKBcdTAwMTJMqVRcdTAwMWFH4GKhXHUwMDEy5mj4XGLNQEFcdTAwMTE8zDZ9uJA1Slx1MDAxMlBC03NcdTAwMDeFV6tcdFwi2IZcdTAwMDaEY4dcdTAwMDfUwT/V2SxgWKS8XHUwMDBlxM+IndHozebQ9DXqYd7vmlx1MDAxMVx1MDAxMzRydN+t+VXzvvnIXHUwMDFkMlX/yTz7Zlx0XHUwMDA267U2h58/9MFcdTAwMGXrX1x1MDAxMDaGfqdcdTAwMDR3dP2618qmYZVGy3/y6271yjZkt1x1MDAxZDYuveBz0GGr7Vxyv1xm77BPXHUwMDE2XHUwMDBl4WOwupXz3y635U5bPV5cdTAwMDfVzMWhXGZ3u3GsetWq31xmXCKsJpBykMZYXGJCNUZyINm998XB/kNklPa+cSukI1x1MDAwNKaMXHUwMDBiXHSmXHUwMDFlXHUwMDEwtVx1MDAwNbbM4WBWSqJcdTAwMTAmjFx1MDAxM8X+UTBcdTAwMWUwXHUwMDE1wY/Zx26nXHUwMDEw1lvXhXvcuLlcIoDfmEqfiHZ5kJZcdTAwMTRJXHUwMDEyKYJcdTAwMDIgMCGgni1qQFx1MDAxM1x1MDAxMj3a11x1MDAwMowrsCGHLP0laYExSFximMzgfO6sePTqdzqHneeD+7PbOFx1MDAxMlxmuKIwXHUwMDEwIMyUYqoo1kiLUVx1MDAxOFxi5YBBgOBcckjEiFx1MDAxMDEsIMe4OVJKSlxiQ1hpXHUwMDFkXHUwMDA3XHUwMDAz04A0rrRQXGLwwqleY2E+LNzMjVx1MDAwNfCmqFx1MDAwNDRwXHUwMDFiXHUwMDE00Fx1MDAxOPOQaFB4XFwsXHUwMDFkXHUwMDBi/cPNhlx1MDAxZrU+XHUwMDA3/9tcdTAwMThIVu+P/v///bv16q1kcTafmCBcdTAwMGbuXHUwMDE3m8WqXHUwMDFihDuNWs1cdTAwMGbhQS/MIGPGSei2wm2YVr/+XHUwMDE0PefVy1x0Z3rfylx1MDAxOHey4rkxIYHvRc+N0Vx1MDAxYVx1MDAwN+fi5kqhZvs4s6VcdTAwMWbOMujypP2SSmtI7khcbvzHXHUwMDEwRUiTXHUwMDAxontaQ1wiRzBcbkYtg5dJ6EBYhrSGXHUwMDA2jYOMLFFBtVx1MDAxZdDjQGtcYlx1MDAwN1GFKfxcdTAwMDYobfBm1lx1MDAxNDqf2lDza1xyhCVBnKLYYlx1MDAwYpxUUkSPfqtcclx1MDAwMYaSoEjPtFx1MDAwMvNraI1cdTAwMDRxNp+4IP/iamO3XHUwMDE0kE7moHize32c297VbVfXaWqzWziawXsgoEOkxKOLSuasolx1MDAxY1x1MDAwYkU1XGKNjGuOte29XHUwMDA0xTG/7Y1cdTAwMTVD0oDAZm/IRFx1MDAwN1x1MDAxYyRcdTAwMDRRTvjSXHUwMDE1x1x1MDAxODScbpfCx6uyOner+aduwW/7rad0pjcjXHUwMDBlpVx1MDAwNEyJSPCBaeUojkeCXHUwMDEyXHUwMDAz5lx1MDAxYz7al3nOXHUwMDFjofnInf5cdLI+hVx1MDAxMOfml2GOXHUwMDE0U4JcYtsykpAoSYixomBcdGnC/nuN5iGZNJ+BNP7iTPeCXHUwMDBlj/wj77ryUXdvWlx1MDAxZpV3+XJ6mT5wQoyVXHUwMDFjj5xcdTAwMTDiXHUwMDE4ecC28FwiKEpHfUUkk0IodMEg/9dj7/OLXHUwMDAz/NZcdTAwMGVw23owU1xcXHUwMDAwXHUwMDE5XHSb96uSl4NcdJJSKFx1MDAwNjbeLEDuQ2Gq4Mhuxj15XHJcbnVcXNyu+Pn27m628HSxtOCIfTQxPMSDI5wqRzJFwFx1MDAxYVx1MDAxM0pwQiOIkGNcdTAwMTDBgVxysdZcYnFMjFqxWHxrQFhcdTAwMDBRSFx1MDAwZlxigoThJ6Zt9pmULFx0XHUwMDExYIVLTsnqXHUwMDEw23d8ZNdrVlx1MDAxYlx1MDAxZPNbXHUwMDFi13V/2Hb5+2IlNb9cXFx1MDAxZaaASLhkXHUwMDAyl0TDJYlPsJjQyXt36+21qGuFt1x1MDAxMrnddjuNd5l3UzNcdTAwMWKwmoO0XHUwMDEylKio8YrBhSNcdTAwMWNHjNE+mFx0+MqfnNhjN1v6XGaYxT3+Y/rrszZp7Vx1MDAwMC9OXHUwMDAxcMxcdTAwMTj4zTpObmYoXGbH8lx1MDAwNPpLN1xmXHUwMDEzzfRgJv92xnu6VPKi+1o7e1x1MDAxN8Xc0X5JPZy+7k3FeFxugXCRYVjMznj20aRgPMm0gylcdTAwMDdB15b8Mow5nI1mnn2jRINFXHJyzzGW66yAKTGRXHUwMDEwXHUwMDFisaaUXHTKXHUwMDEwcFx1MDAxZbLZgUBtiXYgaDbOKOZ6XHUwMDE2VCxScGO899BovFx1MDAwNJXGzyRcdTAwMDdMILxcdFx1MDAxNFx1MDAxMyW8+NBcdTAwMTfDdPe6nrm7On4uXHUwMDFmuPkn+Xza2VPuYWqmU5o7QFNWXGYj6YBVSjWyYXjNdFx1MDAwYkT1Q3pQS6FcdTAwMTXTjFrTRFx1MDAxOVx1MDAxYlx1MDAxM9pcdTAwMTRcdTAwMWNLivBcdTAwMGZS3fGNPENcdTAwMGbFs6NcdTAwMDOhi0G2fV0q3pwujerso0lBdVx1MDAxYURcdTAwMWRcdTAwMWNcdTAwMDFJhGQmXHUwMDAzLkp1wpEqus7ZX8/XXHUwMDBlWFx1MDAxZprKz6Q523LHmuySYFGaXHUwMDAyXHUwMDE2WmDB7bDgKjFyh5nUhFx1MDAxMK5cdTAwMTadXHUwMDAyNz/Vtbw333tcdTAwMGZWgekmUEyU6WIjX1xm0eGrq/vXs4+mPr8qXHTv7lBcdTAwMTReX5vpiVx1MDAwZWNcdTAwMDdcdTAwMGKlXHUwMDE5j8UjsFx1MDAwMp7iXFxxbcuGW1x1MDAxM91cdTAwMDJcdTAwMTH9mFx1MDAxZdFcdTAwMDSZPG0xvFx1MDAxYTni0qno4b5L14ucMv6DRFx1MDAxN6it0r5cbs6P7662m/vHuawsy8ulXHUwMDExnX00KYhOMeQwkGOgKUykXHUwMDFlXcRcdTAwMDTn2lx1MDAxMVRcdGldxVx1MDAxNMTBUmtcdTAwMDZcYtNcZrM1z02Diqf0qOCSUq6ItmWocJHIc1IyXHUwMDA18sVcdTAwMTZcdTAwMWRonp/mXHUwMDFhrTJcZnVcdTAwMTVYblx1MDAwMr9EWS468MWQXFyu3tx+bsnM1lNp59jNdlx1MDAwZvab+XJqklx1MDAxM5o6XHUwMDAwYmVcdLpz5FhcclTKhYN5L1x1MDAxM5yNUtdcdTAwMDC4yKhcdTAwMDWm2LqmKVx1MDAxMcKVKYhNI0ooUTZcYmOmXHUwMDEy87RcdTAwMTnMgcnOXFwgr81d5/f7uPue5endY93ttshNU7BcdTAwMWTvoJ6/vlnAfVx1MDAwZmq7tHGQPS69bYelXHUwMDFhP/tcYlx1MDAxZbok3X1/loh17eo6372/dVx1MDAwYlx1MDAwZtLtvt/u+8GhJf80KVxiwWnS0lxmXHUwMDE1XHUwMDBl0URbXHUwMDBieNdcdTAwMTH2WTHsT1x1MDAxM28gopdcdTAwMWRsK0DUXCIx3IAxXHUwMDE1XHUwMDA0XGYkscBi3UnGaVe/XHUwMDFkVlm3xK/Pr1Wre9qs0dP7pWHCPpo0ximSXHUwMDBlyLaxfTDYomy0/pDhZERI4TBjm35HXHUwMDFjVFx1MDAxY1x1MDAxMOtcYrtcclx1MDAxMM9TXHUwMDAxQlx1MDAxM8U5sbGajsPkXHUwMDFiXHUwMDEwijGJNKOLXHUwMDBlsc9vmJ42yu2qt1x1MDAxMpbpXHUwMDA0XHUwMDFliVqmsZEvxjQlzfz+tto7Q1x1MDAxN3c3Lzu551L+dDhcdTAwMWE1KVnMVFx1MDAxY2qJpCVcdTAwMWZcdTAwMTRrR2CJXHUwMDA0Z1x0XGJcdTAwMDZK+7I/XHUwMDEzl2DoYErWpulcYopfpkCxqYRjXHUwMDA0x7tNmKFwmrjmgomJLTA2W1x1MDAwZehsvHa4XHUwMDFmNrogjOwu0Jf15zpcdTAwMGI6hZOlpY7ZR5OC18BOczjDlCDw0E111ig2XGKbgFxyXHRf51pTwSPlvEP+21x1MDAxYVx1MDAxYXZoVNNDw4RwsFx1MDAxNvHWXHUwMDEym6b+J9FpXHUwMDAzO5xhMFaWnuFcdTAwMWbjt7GhdCxGjv7dXHUwMDA0N4FafiyUfnVEL27dm/A60zlcZnJ7zPfunlMznODcofbFXHUwMDE3hpUjKFx1MDAxMVx1MDAxYa1cdTAwMTnua0pcdTAwMTdcdONaelx1MDAxODNcbs6XVsqaJ8aTi1x1MDAxY4RCRLJcdTAwMWZcZimc8qxEtbvrI+FcdTAwMTfx1lx1MDAxYru/yzx6S2M3+2hSsJtcdTAwMTDaUWD2XHRcdTAwMDb8psHaj7BcdTAwMWKdgFx1MDAwYsBcdTAwMTSnXFxbLMc1vU3ERX1cbsuPKFx1MDAwNrOgbOtcdTAwMTlcdTAwMTIlllxmYKqxwqvYQWZcXPj8h9ltXHUwMDAyrfxQ+PxCXHUwMDE2ro9KO1x1MDAxN8eo8Vx1MDAxOPCt02rOJUF6ckPcXHUwMDAx84eo0WywXHUwMDFliLl0kJZcdTAwMWM0q1xck9vGokHcmFwi4VNxYurQtbUtmmDJPVx1MDAwNMH/oEqi2XrAzEZwVyfnt8/yXHUwMDA00YfaR+a2/kKvu9eVpVx1MDAxMZx9NGlcYo5cdTAwMTAj3JxoxImkUYJcdTAwMDPnbjw2mHYko5rLWE3BmuAmYqOZXHUwMDFlXHUwMDFi8IJNzby1tYNUiVx1MDAxNUCYwFc0XoFcdTAwMTLtXHUwMDE4w42JnP8wwU2glp+JnFx1MDAxN/Ot7Ys9yj52RLOyV5X189PhXHUwMDEysUnpYaZcdChcdTAwMTg6kYqEz1650iFMKymTXHUwMDAyXGbrnrlcdTAwMGLE9Gt6TCtqXHUwMDAy4sxcdTAwMWVJJzxcdTAwMTHUWsA8gEex8Ej6XHUwMDFjXHUwMDEx78l0Z1x1MDAxYTexXHUwMDA10d3+U5Pf7zTOqvulSoXjbPXoRl+lXHUwMDA3i1RcdTAwMGVcdTAwMTVcItrm9qttrmkxZdLHkuLTWDtoXGJcYsiScWLKh3pf/06o/Ge1OJlcdTAwMDItLTtapumly7AmoOPiNXKfKEpcZt3B9INcdTAwMTDIXHUwMDE521x1MDAxZc1mNL5cdTAwMWN3XHUwMDBl2dNdcHxcdTAwMWHo8+5+caf4snu2NKPRPppcdTAwMTRGo6koMGxjXHUwMDFhZ1x1MDAxOJ8q1kt3XHUwMDAyhtaddXtHZ8RMkJ5hhDQ0QeNcdTAwMWRcdTAwMDN7I9GJ+ZZcbiMlQN5cdTAwMTZdQfff0Vl3XHUwMDAy+/xAZ917cXKsn1x1MDAxZW5PXvTx1rM8YK+Z4mtcdTAwMWO51lx1MDAxNl9aUIeYNUtlOobaOutyJiRPTEdZt/hK3+KrsvfKaKtcdTAwMTCg0iE/ZydcdTAwMWa5ztVLZ4ZcdTAwMTZfYVqaTOyOXHUwMDA0k0F6rZQtmkCL5MA4XHUwMDA1U1x1MDAxZkylle6ue9hcdTAwMGXYm/SyxWKB3eNs4bixr9txNMRbfGmBXHUwMDFkqTXiMFx1MDAxYc1s3XVFr1x1MDAxMlx1MDAwMzxcdTAwMWY8nLG17q67PCi054aC1Fx1MDAxY2w/ZF1K0fEtXHUwMDE5XHUwMDA27YVAZFx1MDAxNejNmdyuX6JP2D+puW7l1PVPXHUwMDBlXHUwMDFlXHUwMDBlVT23k9mvXHUwMDE2rtj5Vi2N0lx1MDAwMLdcdTAwMDE5SoI+XHUwMDAwXHUwMDBmUvJImZFprlx1MDAwYr4ueCTArVx1MDAxYSNrS+51c92f1lx1MDAxYW9za1xyLIy/L+P+5ObY7vRacFO0TlbHkl731p1Da9yF1feT8utN4fH4fetcbqmz3FtgSVwiTTC8iYOk4oKZzkygQEZcdTAwMTRHr/MuUJOUYDpTsDvWhvdcbuiN9/n1XHUwMDA2wVx1MDAxNJvdbew+OFx1MDAxZVx1MDAxM9SUmFx1MDAxOFx1MDAxNlll03vn5SPXPHlhRzTr57c0z7BCeT+V6c24Q1x1MDAxNZeR5Z/v/rrgdIDwJlx1MDAwNlx1MDAxZLlDXHUwMDEysmm4WXtcdTAwMWFccvL/XHUwMDEzJH9cbpH+mFukXHUwMDE1SFx1MDAxMddsqFx1MDAxNctQLHLMRi2cUERHXG6z/6u4MCaV5jOQx1+c+VrtnaOjw1x1MDAxY7rfOXg72X3vZvfzhYM40pNCLoI6XHUwMDEyXHUwMDFjasrjIVx1MDAxN0JcdTAwMWQjXHUwMDE4TIhcdTAwMDS4r0tcdTAwMDJnxXpniuRcdTAwMWLw/Dhi2lx1MDAxYUdRJLlcdTAwMDJcbjPwXHUwMDE3h1x1MDAxN5b+9ijKs2ggWr9+9ltXt2SviFH+7c37gareXHUwMDE4bi0xTsaGqifnolb7U8ZcdTAwMDBnqTSUwpFcdTAwMTJJY5ZcdTAwMGJcdTAwMWNv5qsmwW3d0Xc2tHXTo00pRM3eXHTWfNX4XCJtv6Gvltxslrs6XGa6wlx1MDAxZH0nMNZcdTAwMGZ39M09VEkn89pccsq7p/7z5VX4svUyRfsnXHKeXTTD7jNcdTAwMDVcdTAwMWQ5VFx1MDAwM1xcKbX3f1onr27MjOhcdTAwMDeE0kNaYqmkXHUwMDFh3k5ruDSDx4zlgZ9HNJNkRlDPxqDVxuM1wWxHn2ReguquXHUwMDE2lUC+Li1cdTAwMGbBPppcdTAwMTRMXHUwMDA3XHUwMDE05XBBpcKSKlx1MDAxMq895OOhsS49nFx1MDAwM1x1MDAxOdPsXHIvKVJaYKtpXHRWSFwi21x1MDAxMbPR1PDWzKvCdqtUfDiBWH6q+FBcdTAwMTSa70F1q45ubytZjm+K++6jJZ6SwG9cdTAwMThcZtJ4XHUwMDA3jFx1MDAxZYopd2DCKI76jmuCW1x1MDAwNIxcdTAwMTM2s7dcdTAwMTJcdTAwMWNcdTAwMDFNqVx1MDAxM1x1MDAxYT9cdJZotFx1MDAxMkSRUEipmWIgs1x1MDAxMVxcu1ZcdTAwMGKPXHUwMDFm7mvH94g3Pm7un/JFUl1cdTAwMWHB2UeTguAwYuCLma1XiOi1MIuUZzA0XHUwMDFlXHUwMDFi6/LDjTmwMc1cdTAwMTb2YMNRoZV9g5bEJVFcdTAwMDWGXHUwMDFmY1x1MDAxNK+eP7dC9YdcdTAwMTOY5YfqXHUwMDBm7zvHXHUwMDE37a77Vnzb7eyTav36se5/pOY3479cdTAwMTFO7dWHYJ+Ktf/2PZ1cdTAwMGKFMJuG3lxiV1JSW1TDdDBJ9N+widZcIkRmMlNno7dcdTAwMDZR753b4+ZRoZRcclx1MDAwZmjpssFeb5ZGb/bRpPHfMHbgzcJIXGJDxFZ8OFx1MDAxNlx1MDAxYevaw405oMHTQ0NrRkwuk43d1Jg9XHUwMDFiuNnRQVwitfRcYnaM3lan+HBcdTAwMDKv/EzxYeWjW6rXsrvutTypvVx1MDAxNc9cdTAwMDTNUcuW0YnOXHUwMDFiNlx1MDAwNYQkuinuZzFcYlx1MDAwNlx1MDAxMGtJcGK4YV1QtUhYXHUwMDBiO6ynqahSXG5cdTAwMTmXwd65niZ301x1MDAxMNxcdTAwMTSbUPGDft51Vd5Vu5yetf2t/dPgrXp03j1fXHUwMDFhXHUwMDEx2keTys9cdTAwMDMzUFx1MDAxM1x1MDAwMeZcdTAwMDeSmFxmecqfXHUwMDE4XHUwMDEyXHUwMDEzMLQuqOpcdTAwMWSdXHUwMDE1MzI9XHUwMDE1clx1MDAwMd64lNY9ycBcdTAwMTJMLqRQRCtE9VxuJYKuUknVXHUwMDA0XHUwMDAy+oGSqo9sWGqeu5fd7v3l2fnHXHUwMDEzp0d5y06CtnxwRFx1MDAxY1wiWW/biGjXes5cdTAwMWOqxjWIMus70YS1QTJbL2F0vWt8MnLVNFx0LkRcdTAwMTFcdTAwMDTgtdKaTI7PUbA+XGLWK7RIs9i0tbhcdTAwMDSaz1Zf+Fx1MDAwNjeIsemvkLjmtlx1MDAwM4/RYuWps507f9JcdTAwMDVdbl8+pFwiZZN3hqjAlm10mVx1MDAxNI4y7k1cIrCJdrjGWnNCv3prxPHN1sBOXHUwMDAytk5cdTAwMGZsglxiklxicXuVczxcdTAwMWU/7J5igdlsXHJcdTAwMDD+Vkp2XHUwMDFjx0rJdDrftOo9hrNcdTAwMTHyyGCj7DsyusWw7/g9PFwiXHUwMDE5eSMoNVx1MDAxYvkyREyDS6RMlGNcdTAwMDSnRDCTlFx1MDAwYlx1MDAxND2mXHUwMDE3gdCCglx1MDAxNGBEwLxGXHUwMDE2XHUwMDFlZuDDRneOWlx1MDAwNcCyyPFlXHUwMDAyNjN/WjlcdTAwMDBHcVx1MDAxYd/Y18ySTLSsOVx1MDAwN7dcdTAwMTNcdLE6WyAutsIqWUDNZ0g0XHUwMDE3ydND0+Z9vq6vZIOx+zv11FKpbVx1MDAxZVx1MDAxZDlcdTAwMThcdTAwMDFcdTAwMDBMZzlcdTAwMDAnpnIwgUbI3GZPNzuMcFx1MDAwMTT56dbGXHUwMDA0Y8RASFx1MDAxYVKW3uzW21x1MDAxN9WrXHUwMDBilt3bK1x1MDAwNJLJvLZccmlcdTAwMGI51GyXXHUwMDBlbCzBslFak9iQeqWdXHUwMDFhke9cclHjsjqNZVx1MDAxMtVXXvWh8Z5qJWF8lvI4fVxilpxcdTAwMDNAMiXOWqvhXoqf+lx1MDAxMFx1MDAxNLGkXHUwMDE0J/Zjx9xcdTAwMDHjxjiqglxihLAl+1x1MDAxNyxGXHUwMDE2XZNfq8NRdbg9tzr8LFx1MDAxYVx1MDAwM6vGZtYwnVxcZqOBXHUwMDA1XHUwMDA1JbPFo8Ymt1x1MDAwYkWW768kXG6o+VxmieaKqUNkckM14zAzVFx1MDAxMoqHiuu/1SFymOaAXHUwMDEyMY86XHUwMDFjn/U8qlx1MDAwZVx1MDAxOZJUaVOLint9nFh8TNT5So5cXJYmXHUwMDFjv1vaOE2IXHUwMDEx5Y5Zyo4vin6qQlx1MDAwMsRKzbop4cBVQ27AYO9cXG3ya4RiPCl9xmw5ylx1MDAxNTGdXHUwMDAwTEVcdTAwMDWnq1x1MDAxNZlYJZW4M79KXHUwMDA08GDQRFaVSHViw0TwXHUwMDBmMOVktlx1MDAwNLSxJqLGQ6ukS9OISWJqPnFcdTAwMDFdMcVIe/1cdTAwMDPMztbgi4NZMjT6byWEXHUwMDFkjYWA87JcdTAwMDdUIcarxtmXklKpqd++3tim22zmQ5CI/ntcdTAwMDBo+OXI6vnnsdBrXHUwMDBl3PTeodNG2duru1x1MDAwZtWodGya9KXt5Fx1MDAxYanfvp7baFx1MDAwMa9cdTAwMDegv3776/9cdTAwMDF7mdJ0In0=AppDeployment UnitbookshopreviewsordersModulesbookshopreviewsordersAppDeployment UnitbookshopreviewsordersApp... \ No newline at end of file diff --git a/guides/deployment/assets/microservices/modules.excalidraw.svg b/guides/deployment/assets/microservices/modules.excalidraw.svg new file mode 100644 index 0000000000..651051525e --- /dev/null +++ b/guides/deployment/assets/microservices/modules.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO2aa1PiSFx1MDAxN8ffz6ew2LdLpu+XqXrqKVx1MDAxNFR0xlFxvMzW1lx1MDAxNIZcYpGQhCSgsOV331x1MDAxM1BcdTAwMTJCUGDxsrX4giq7O8lJzvmfX5/u/uvT1lYhXHUwMDFh+Fbhy1bBujfrjt1cYup3hd/j9r5cdTAwMTWEtudCXHUwMDE3XHUwMDE5/Vx1MDAxZnq9wFx1MDAxY41sRZFcdTAwMWZ++fy5U1x1MDAwZtpW5Dt10zL6dtirO2HUa9ieYXqdz3ZkdcL/x79H9Y71P9/rNKLASFx1MDAxZVK0XHUwMDFhduRcdTAwMDXjZ1mO1bHcKIS7/1x1MDAwMf9vbf01+oVcdTAwMWW7XHUwMDExP9H1W0htn3qtQzvofq2KXHUwMDFm5Ir0R5eOXHUwMDA2Pb1CYJlR3W06VtJ1XHUwMDBm7Vx1MDAxMmtDXG4hXHUwMDEw5oLwSddcdTAwMDC6XHUwMDE4XHUwMDExXHUwMDA2kZpooWTSc2c3olx1MDAxNvRiyVxmjqhGgjBcdTAwMWT/ycmQlmU3W1E8hnJcdTAwMDMjTeV4RHrM2JQvW2jSXHUwMDEyRoHXtnY8XHUwMDA3Xlx1MDAxY+z9XHJriU2SWHtdN9vNwOu5jcmYKKi7oV9cdTAwMGbg8yTjbmzHqUWD0d3BMfBFXHUwMDBimWdcXDy+XHUwMDAyybTPu1xuXHUwMDFl2my5Vlx1MDAxOLtcdTAwMDBPWj2/btpR/KEwSt5cIrbQrzZcdTAwMTJvjVqHvYswuHFcdTAwMWGHePvnz35HtixcdTAwMTSIwmP/n4npXHUwMDAxhEM19qrbc5xJs+02rNhXhfr13pRVbuPRqqnhoWXFtyBcdTAwMDTcykjyyVNBi2m29chzR1x1MDAwMYyx5Fx1MDAwMlx1MDAxMUJ08viwXGYxXHUwMDE4jW56XHUwMDAzcWwlLolNqGTjM1x1MDAxZKNTIVx1MDAxOFn3iZ9SXHUwMDExfHpU7FxmTu/K9+f9ajC8vdtcdLyrm8Jk3MPMd+r5jfrYXHUwMDFliELCIEZcdTAwMTGmNHGnY7vt7FdxPLOdvMKo9eH3PD3lWzOjp6mXXHUwMDE5S0lgQ1xixaXGeWqi+Fx1MDAxOTVpZFxi0Fx1MDAwN4fPj9P9XHUwMDEzKaXutpHOStI5X1xcOpgqhFx1MDAxMME6TzyYkXnioZRrypRYSTvrXGbvJFrjKP1cdTAwMTI/zWuHLc9P+dpzo5o9jM0maKp1t96xndg5fOo2Jcduxu9fMMFiKyikP0JkXHUwMDAzuiZcdTAwMDOi9HNMuGPddq2gulxirbzAbtpu3Tmba3e9XHUwMDE3eadWOLY8XG56VvqzWPtcdTAwMTP0XHUwMDE4hD8j8r66sE/CO3FcdTAwMWOYre6eSe4j17tYXHUwMDFjmlxmXHUwMDFiXGZjTInCXHUwMDE5mXNMXGYsqZrumUCTKENRgih+hCabVTplhuRy6vJcdTAwMGat+IZcdTAwMTfFwfpcdTAwMTEl7+RLPoHTk6PpY8vDTCYggkrFWColpzKBVnMxilx1MDAwNNJEXHUwMDExllxc9+pcdTAwMTit1fYrXHUwMDAz/2r3/uu3K+dg//74e+v89t0wmm/NXCJcdTAwMThl2kBcdTAwMDLmpVpcIlx1MDAxOSsloy9tcE4kZTRvUoqpXHUwMDAxI5SWTMTzzjyQoo2s/pmszMVBqlx1MDAxNVx1MDAwM09QkqtcdTAwMWU+05qoR0pBXHUwMDExonJcdTAwMTX1vCpId+pR3fGaNSvo26aVi1Ms1ovTjt1opFx0lCHqXHUwMDBiKMtcdTAwMTJ13lx1MDAwYqyHq5WjcrR7eX5f02cnpHJ4sV2UR2pcdK5cIkNjilx1MDAxNJ/S7mj6LLhcdTAwMDFTaMGQ2HD1vVx1MDAxM8CcqfRcdTAwMTJcXNVcZjGkXHUwMDE0wemwf6pOU7VnNjFcYlx1MDAwZW6mVCXXvTpWOStcdTAwMWSbQlx1MDAwZkuBssPLs77NdorNd8NqvjWLYJVcdTAwMGKDXHUwMDBiUFx1MDAxN4iAXHUwMDEyRqaxyiQxXHUwMDE0RpzlV6cypqqG8lUqXHUwMDFll7ZcdTAwMWKsrl9VjcWxXG4yYEpcdTAwMGKt8uSTU7VO5MOZhJhcdTAwMTTy43G11OjY7lx1MDAwN6LqXHUwMDBiIMtSNd/89TC15rLh8Vxy/3X8/Ud0cVx1MDAxNrg1NPSDhZmKXHUwMDExVKRCXGKQ79TK0ujbXHUwMDExXHRM5Fx1MDAxOdwmUGVcdTAwMDaKXHUwMDEzwuzqbVx1MDAwMlVpjJe0nsb8O7LAmlapllD37Vx1MDAxMuqGZEyJpihv9YmxXHUwMDE5zSdwRFJcYkV5UpW+Olx1MDAxY381qzvdIFxit89cdTAwMGb2/MtcdTAwMDbpfNOnzlJwVFx1MDAxMnOl0sJYXHUwMDFkjvnWLFx1MDAwMEeMqDZg4lx0hT5VUmhOp3VCyTM6kdjAQEfBOPxA1almZfJvmXO+vS7ai+uCSoVcdTAwMThGambvXCLuXHUwMDEz83c0wJ1ES72SKtZcdTAwMTm4M8wzvU5cdTAwMDesz6PdWy7JvsCXLOqyVq9cdTAwMDdyxbJ/PDRFqXZ6qVx1MDAwNzX2rXx7eDNYXHUwMDE4clx1MDAxYTOY3HKW2V1cdTAwMTnvYnLjadqawziuwa64KnxcdTAwMDRYTuGolIEhI0yG/LdcdTAwMTiXTHRPu06/duztN83isFR1usH2zc7lXG5cdTAwMTPd9lx1MDAxMpuYglx1MDAxMMKFVDNcdTAwMTVhnHfR3DqRI45cYuTq5JVenYT+z93qzbC74+uLM/fwuPurOqT95UgooFx1MDAwMmNp9axOwnxrXHUwMDE2IKFcdTAwMDZBMMWokFRcIoF4dlx1MDAxM1x1MDAxMz0jJlx1MDAwMZdcdTAwMDJcYqmEYlx1MDAwMFxchsSslv5jIHxcdTAwMDXxLLGNqYVcdTAwMDTwodnN/lghev48XHUwMDEy0iFXXCJV5a9cdJjLxvdcZjBcdTAwMDOrb1t34btcdTAwMTPzXHUwMDA1WGWJOWP2epCJz1x1MDAwZWmPnDl7e6VexTo5Oz/Z9q9cdTAwMTZHJsxpXHUwMDExXHUwMDA3raKctVao6rRC+YtBm7XWt9T7P9/CXHUwMDA0XHUwMDFmw1xmXHUwMDE4odwswObuYHJNXHUwMDA0zKfeXHUwMDEyoeLgumyj/avrk9vdMlx1MDAxYVx1MDAwZarEvGq/XHUwMDFiQvOtWVx1MDAwNKFUXHUwMDE5XHUwMDFhYVx09Vx1MDAwMeNQsGRXWrkx8lxizT0ggDnUoZCcwV9cZkudOkqyWWpdm6g6SyzGQNlPXHUwMDE0wiRXPnjuXGaUMVxu0yT2XHUwMDAxIXo6ptFcdTAwMDdaa31cdTAwMDFkWZzOe4H1ULXcZrhYXHUwMDFldItlUsH3/vWe/bW9u8Rqq9KGkmR8cmG2XHUwMDEyfeZo0KZcdTAwMTJdOFx1MDAwZpRcdTAwMGba/dPeQSDLqrq3f1x1MDAwYlx1MDAxOWFn/3aFPOAvnlx1MDAwN6CelHFizjvJINHcXHUwMDEzgZhcYlx1MDAxY1x1MDAxN6Mpb746RkvfaLXqVprdm6NfR4NcdTAwMWaHstJ0/CUxqoFd68FovjVcdTAwMGJgXHUwMDE0Y+AowzFcdDEmUk8vycaV6HwxifhcdTAwMTBcdTAwMWVISCj4wWxTib6CeLpLXHUwMDFjRUeUSFx1MDAxMVx1MDAxZqjNrUTRPPVcdTAwMTDwXHUwMDFkIZKIVcSzzviegahcdTAwMTc0wNR3L0RfgFWWnFmr10PM/aaq6MZR1cZ+pd5sXuHSmbn4mVx1MDAxZlx1MDAxMDhcdTAwMDNizpyMXHUwMDFmXHUwMDE3osRQ8+fKm0L0XHLlXHUwMDFl5Mt9mbO0VEolXHUwMDE1zUMoU3OTXHUwMDAwxnBcclx1MDAxNnq1XHKc1Vx1MDAxMHrQ/75XxKXi3W236bq4+pO41va7ITTfmoVcdTAwMTCKhYFobI3k8VpPplx1MDAxMkUg7Lm7/0hcdTAwMThcdTAwMWNjjSWGJFx1MDAxY2toU4muX1XhXHUwMDEyM1CBuJZ5XHUwMDA0ZXy+eCg4j4r0ca+PgtDvI1x1MDAxOH2gMvRcdTAwMDWOZWE6x/6lmfrpMWCgXHUwMDFj8WtcdTAwMTF85UlWLcR17vasTH67XHUwMDE5/cXhNkpcdTAwMTixRKxRMn749PA3XHUwMDBlLbLDIn0=bookshopCatalogServiceAdminServicecommonreviewsReviewsServiceordersOrdersService \ No newline at end of file diff --git a/guides/deployment/assets/microservices/modulith.excalidraw.svg b/guides/deployment/assets/microservices/modulith.excalidraw.svg new file mode 100644 index 0000000000..65671640b2 --- /dev/null +++ b/guides/deployment/assets/microservices/modulith.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXNtS20pcdTAwMTZ9z1dQnNfQ6fslVVNTJlx1MDAwNmJcdTAwMDJcdTAwMGXgXHUwMDBiXHUwMDBlU6dSwpJtxbJkSzJgUvn3aVx0sGRdwFx1MDAwZT5AZuxcdTAwMDdcdTAwMDItWdrqXmuvfWnl57utre1wNra2P25tWzddw7FN37jeflx1MDAxZo1fWX5ge64+hOO/XHUwMDAzb+p34zNcdTAwMDdhOFx1MDAwZT5++DAy/KFcdTAwMTWOXHUwMDFko2uBKzuYXHUwMDFhTlx1MDAxME5N21x1MDAwM11v9MFcdTAwMGWtUfDv6GfdXHUwMDE4Wf9cdTAwMWF7IzP0QXKTXHUwMDFky7RDz7+7l+VYI8tcclx1MDAwM331/+i/t7Z+xj/1XHUwMDEx24zuWCPtqjs9cZontLa311x0XHUwMDA0XHUwMDE1XHJcdTAwMTV/NT7p4Vx1MDAxMXyrXHUwMDFiXHUwMDFhbt+xkkM3epwrXHUwMDAyXHUwMDA0gZRLweZcdTAwMDdm+lx1MDAwMOFcdTAwMTgoRCHHyfi1bYZcdTAwMDN9jEJcdTAwMDRcdTAwMTBm8OGD5mdcZiy7P1xio68jXHUwMDA2uEDpq97d/eNcdTAwMTacj1x1MDAwNKHvXHKtT56jn1Wb+Fx1MDAxN1JcdTAwMDJ1cWLgpdFcdTAwMWT2fW/qmvNzQt9wg7Hh61x1MDAxOUnO69mO01xiZ/HV9VroSdzO3OP83nKcXHUwMDE5L/uWvml/4FpBNOvJ03ljo2uH0ewgmDxFZOG4ZsZcdTAwMGL0d2KTr5e2XHUwMDE2rZA7dZz5sO2aVjTv21x1MDAwNlq4m2ve323h7MCyoisgKSmHQnEyP5IgUCGeXHUwMDFkrXtujEbFlFwiXGby5Fx07KCq8Vx1MDAxNMZX7WlMWslcXEc27KWwljzKdGxcdTAwMWF3X0GCYqJcdTAwMTCiUsBkKlx1MDAxZNtcdTAwMWRmLXe87jC5Szz6631cdTAwMTF8d07tq7Nd8Wkqe63AqZx8XHUwMDE2YfU2XHUwMDBmX8tx7HGQXHUwMDAxr2RU45BcdTAwMTOMqVRcYlxuvIBgJlxioFJiiVxuIMxcdTAwMDXgXHUwMDFjXHUwMDExyrggiHKE81x1MDAxMMZcdTAwMTQwwZnAXHUwMDEyXCJMXHUwMDE5lvT/XG7K92N6XHUwMDE0o16tdzvrhK7f6nxHXruJNYbvj6+AeHFQXGb5n8mt7pdcdTAwMWLfj/zKMlx1MDAwMUOM9YJgVMRcdTAwMDSRWqFcZlx1MDAxM1x1MDAxMFx1MDAxM1Qyhlx1MDAxNHvDVFxiqKigxmn94nBiz2afZz9cdTAwMGW+18/zVND3yPFcdTAwMDBcdTAwMDOuJFx1MDAxNVx1MDAxMEqkoOKLPJBcZjAplCREQIo5z5FcdTAwMDFcdTAwMDKhSVwihIiYXHUwMDA0kVQqz1x1MDAwNqpcdTAwMDBUTCouoSZcZiNqQ4bnkaH9bDJoWSBC04FcdTAwMTVxgedG51xc0IJAOcaKvDZcdTAwMTfmw2PPTkc40Sf5bStBVvzH/Pe/31x1MDAxN569U1x1MDAwZefok1x1MDAwM3JyvdwqOkZcdTAwMTB+8kYjO9RcdTAwMGZ6XHUwMDEyXHUwMDE5mVPo0PDDXb2sttvPXHUwMDFls1xcs+RI/K2K73vXXHUwMDAzy8iBRH8ve+xcdTAwMTGvcfCVt5tcdTAwMTKOp18qO+qyXoFnR9PhMl5DYVx1MDAwNISAkkCtcFDhhNF3XkNcdTAwMDCBleBI6cnEJGFLymsoRKSOXHUwMDFkXHUwMDExI5wolXjfxGtwXHUwMDAwiUREUH1cdTAwMTPMId5o6PPchny+14BIYMhcYlx1MDAxNEVug8hyt0GIkppVr1x1MDAxZU3+c26jXHUwMDA0z9Enj+Q/3G9Uu1x1MDAwMZ5VXHUwMDBlLtrV1pfT3aqaXHUwMDFhyiVLXHUwMDA33jo5XHUwMDE0Qlx0qTDTiFhMXHUwMDFkOSZAO1x1MDAxN1x1MDAwNCMvy9OA2UTfd6Ov4jmeXHUwMDFmfSNJoYhIUOA5dHRZ6jlcdTAwMTTTkIBaj1/bczxCXHUwMDA33Ksx/7syTifHot351tg/OrpcdTAwMTgvXUZROsamXHUwMDAyc5Yul8RlXHUwMDE0hVx1MDAwMVx1MDAxMkxcdTAwMTQmoVx1MDAxMlx1MDAwMlx1MDAwMiVTRLDSOspcdTAwMWZSPzGNYGC9bFx1MDAwMeXrsngmpXimTCGK9OJcdTAwMTRcdTAwMDBar1kpoLVj0n5PXHUwMDBiwe9cdTAwMDB6bl9iaVxuYKF1k6xMXG6fXHUwMDE1un9xdXbWNIPD1mmzNZHfTtrX2/PzfuVcdTAwMWPCXCJbqFBMx3gpi5/FlmJrcmxZeJg7oiiiMc91XFxJkCQsXHUwMDE1M96xRZSzhVNcdTAwMTCpstZmRFx1MDAxNos6iWhs2FLGlpNcdTAwMTXKjVhcdTAwMDf82iPRXCI/ryW7jFx1MDAxNkKvKFYsVX5Yg5v/XHUwMDFk4CY4jPCnn77TaFUqqVx1MDAxNfTcsGHfxlpcdTAwMDdcdTAwMTdG942R7cTpz8I1Ko7dj1x1MDAxZX67q821/O30XGaEdtdw5ieMbNNMi0NXX9TQqZdfW0ZlPN/u267hNIvtNqahd2ZcdTAwMDV3lof+1ErPifX5gVx1MDAwNVxiYPZcYnePd7thr2nKr4bT6N927Knt95crM0lcdDBcdTAwMTQ6bc6IXHUwMDFjo1x1MDAwMlx1MDAxNJdZYV5cdTAwMTVcdTAwMTOyXHUwMDEygNCmRfBcYmdPn1x1MDAxZrExKKnkmFx1MDAxNyqcKu1cdTAwMWMgSlx1MDAxOdWht0pmY01cXEZKKZHG7Wsle1lgRp9cdTAwMDSSyVx1MDAwNXLC+ickd6fVjjuq2Tf6XHUwMDFmXGb3bmHN/U5aKzRcdTAwMDUpQFx1MDAwNaEsXHUwMDA1ipa1XHUwMDA0JVBcdTAwMTBcdTAwMTNKRFx1MDAwMdORVCDTYnzTTDe9aGlflOpnz1x1MDAwZWYll0rqVKKI6ThVrs8ynUOOdI5NkzPeXnJWV22zzb9cdTAwMWVV+5NcdTAwMTM7rJnjYzrpr1x1MDAwMGdcZpQs6HFTooDIXG7aXHUwMDAzolx0XHUwMDAyXGZcdTAwMTJcdTAwMTWh/a7LXVDeJFx1MDAxOGSC1TeN65dXsMZcblEnioPHgsbFXaZWXG5ggpTEkpO33No7XHUwMDEyR9yY8XN1XTneXHUwMDFm7Df7XHUwMDA30oQrXHUwMDAxmCGS2U9cdTAwMTEjWGJAikOvXHJ+14Df5ipZXHUwMDEzU1x1MDAxOFFcInOuNk4zSrMmXHUwMDA2OdMh2lt2v7Oraa8xuWpcdTAwMWZcdTAwMGbkMVx1MDAxYp5cdTAwMWPORs2hu9JcdTAwMTYjhLlO3HN5XHUwMDAzXHUwMDE2+ahhg9814re1XHUwMDAyfoWCXGZcblTYTkaqPIAgUVxcXHUwMDBmoXjL/nfk3U5vQ3PCXHUwMDA27OBCXZOb2axd0OzI16u4UoBzmI+GKZSAl5WqXGJcdTAwMDeE6TwnaqtcbkFoXHUwMDAxdDeYLcNsycaI4o1xXHUwMDAyq6izUORz8+WrOWSRIDzaXHUwMDE58HZamVx1MDAwZpWqVi1YR53KsXopXHUwMDE45KpUoZcqOi2WqFx1MDAxNozN1qNcdTAwMTasW081alxiP1x1MDAxZtqHVmtw41x1MDAxYW3/ZnAthsdnS2uLYFx1MDAxOEhcdTAwMDVzqapOR6WirDCwR5JcdTAwMDJJRZz8x8KSVEH+sbbLX73484cz83x5ZlLJOJGoMJhnj+zT01x1MDAxYaRcdTAwMTD/rUbh/YFcdTAwMTX7KtWKcTRcdDouuthcdTAwMWTYjWm1Wuv0T5bvq6xZp4qtWUKnNJx1KEVcdTAwMTnUmZDkXGaTRT4w8lxiXHUwMDFmmCaLXHUwMDE2eFxi2V2Y9s+L1f9cdTAwMDZcdTAwMWQ6y9NcdTAwMDFDncNRRFVhS4WWJlx1MDAwN1JcIsmYxK+eXHUwMDFk5ISqao1cdTAwMWRvXHUwMDE23Wur5drhOkTruc2VJ6QkK2alT7BcdTAwMWVhq6vG98tjISa9sHm9ezBcIrVdNVpe2CRcdTAwMDRISIGgXCK5qlWkeZzKwrRcdGNcdTAwMDQoIcmmglx1MDAwMnVDiFx1MDAwMJy58iZcYl3g9rfnby7AUjLI0ptcdTAwMDTS9SxRroFEO3DysrtcdTAwMGJcdTAwMGWnx3uN2+OhNenUZ1NcZlx1MDAwN+7p8e5qu1x1MDAwYrTWizXtLii2Zlx0XHUwMDE1lIJcdTAwMDCiXHUwMDE4i3ZcdTAwMWLp+VcoQ1x1MDAxY/FcYnFcYlx1MDAwNUp/uKJcdTAwMTJTvFBp2yRtT/LlYoWkjSDtmjgvJlx1MDAwNsnvLktVXHUwMDFhJCRcdTAwMWFl8HeIsU7s5tSwMlx1MDAxZb+IXHUwMDAyPpK4PSU4WflbMHk9kjdCk65z1Nk/wyd00MKHNedq0l5e8lx1MDAxNFx1MDAwN4Tg/PZcdTAwMDIq4vI3o7kmznwjXHUwMDFkXHUwMDA197QufyExWYlccnVcdTAwMTeoa6xAXcpcdTAwMTDjWp1wXHUwMDFholx1MDAwZtSVONd7nFx1MDAxN7k1z1x1MDAxMFx1MDAxN/BcdTAwMDUljX2untXq51x1MDAxZF7f+dTrSbPuXdSOX03Siq1ZRtIgXHUwMDA2RGhniVx1MDAwNInfZcxQQzxBjYg70WugUU5Y3J3HXHUwMDFiZpQw43KV7lx1MDAwZlGaXHUwMDE4Slx1MDAxNomaouVcdTAwMWJtJKNcdTAwMTRhmiqJvFx1MDAxNU279LxhMPCKhS310vFLpHZPKEtW2/Kmr0fgfjRcdTAwMGaHk/blXHUwMDBmXHUwMDE14KOrTlx1MDAxZO9cdTAwMTlcdTAwMTdcdTAwMDfLt3GlYvndrXcsRoBhpVduI3D3XHUwMDBiuk5cdTAwMWF3l6exXHUwMDEyOjiVkFx1MDAxNetcdTAwMWIrXHJNOdVJW7SP5uX0rd04VztHs35zXHUwMDE49urd1uS216Rnr6ZvxdYsoW9cbiogdNSHXHUwMDE5olx1MDAxMcRphlx1MDAxOfxcdGYwXHUwMDA2WLSPXFzlNvJsXHUwMDA07klmmCtcYlx1MDAxY9Nw0WFcdTAwMDaHXHUwMDA11FCPVPRl9FJcdTAwMWRcdTAwMTb47Vx0nG9d2dZ1cb/thfXtXHRhyepbzvL1yNuUV29ufkxcdTAwMGbb44PPX8JmZ3B1Y7Dl5Y0yULA3POI3Q5IgyDbatrVuXHUwMDA2W8szOHpxRnCYY2pkSPrt79xbXHUwMDFkXFwwSehcdTAwMGJK21x1MDAxNa1cdTAwMWPd9HfxOVbWl9HJp8bIIbVXk7Zia5ZJ3ThcdTAwMDZUz5xUKt7ltChtWu+eIFx1MDAwNtXMoUQxXHUwMDEx/b8lXHUwMDFiaVuNXHUwMDE4veWJXHUwMDExvdeug1x1MDAwN1rIXGbIy3M3JjBCjLP1vyTxXFxp83xT2/pcdTAwMTaU7Vx0TckqW9bwlYXt3b1f2DbG40ao53X7oWuzXHUwMDFkaeZueTP63b1cdTAwMDOI8G7FzZ5f7379XHUwMDE3wupSYyJ9XSUAAUIsDeployment UnitAppbookshopreviewsorders \ No newline at end of file diff --git a/guides/deployment/assets/microservices/monolith.excalidraw.svg b/guides/deployment/assets/microservices/monolith.excalidraw.svg new file mode 100644 index 0000000000..415c2c6b2e --- /dev/null +++ b/guides/deployment/assets/microservices/monolith.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1aWVPbSlx1MDAxNn7Pr6B8X4PS+5KqqSmDXHUwMDAzMVx1MDAwMWIwNoSpWyldS7Y1yJKRZMDc4r/fI1x1MDAxOSxZXHUwMDBisYGwzKBcdTAwMDcv3ZL6dPf3nbX//rC2VoumY7v2ea1mX/VM17FcdTAwMDLzsvYxbr+wg9DxPehcIsn/0J9cdTAwMDS95M5hXHUwMDE0jcPPnz6NzODMjsau2bONXHUwMDBiJ5yYblx1MDAxOE0sxzd6/uiTXHUwMDEz2aPw3/Hnvjmy/zX2R1ZcdTAwMTRcdTAwMTjpIOu25UR+MFx1MDAxYst27ZHtRSG8/T/wf23t7+RcdTAwMTN6XHUwMDFjK1x1MDAxZbFJu1xyb9Jyj1qs+eXLSSiZbOvk0eSmuylcdTAwMDR2LzK9gWunXVfQLjQ1JEVMKMnnXHUwMDFkU+igglx1MDAxOFx1MDAxYTMkSNp+6VjRXHUwMDEw+lx1MDAxOMJcdTAwMDYmXHUwMDFj3V14fsfQdlx1MDAwNsMoflx1MDAxY3NDSJx962z0z2to3lx1MDAxMkaBf2Zv+i7MXHUwMDE1RPxcdTAwMDNriXskXHUwMDE18C+zdzZcYvyJZ83viVx1MDAwMtNcdTAwMGLHZlx1MDAwMCuS3td3XFy3XHUwMDFkTZO3w17AXCLWcmNcdTAwMWPfSk5y7VVPwaCDoWeH8aqns/PHZs+J4tXBKJ1FLOG4aSVcdTAwMWL0ZypTXHUwMDAwW9uMd8ibuO682fEsO173molcdTAwMTdG86zb0Vx1MDAxNu5cdTAwMGVtO35cdTAwMDNWilx0JLWg855cdTAwMTSBXHUwMDFhi3zrvu8laNRcXGvKkUhn4IRccsBTlLy1XHUwMDBmmLTTtY5l+JLBWjqVydgyZ49gyVxi1Vx1MDAxODMlUbqUruOd5SV3/d5ZOkrSevOxXGa+9ZGN7Fx1MDAxZqeX34be9abFPXVQ391YXHUwMDFhvlxuYIZ4XHUwMDExvYxcdENLXCJ4XHUwMDE5fDFcdTAwMDP4ak1idCb4pUX8wvNEUkbf8VuFX1KO37vtTfeO3rbcXHUwMDE0YE25XHUwMDE2iHCmS2CthKqCtZRcYjZWUP5cdTAwMTBYz8VLXHUwMDA1zcAssq/SfcmgdKd10NtY347q7Phb93zza6t/3Tmtze+7uf31TJwpl6bAmYXJzOhcIpSBOaOYYEql0niRNFxcXHUwMDFhXHUwMDAy6Szm7yhDmaHhXHUwMDEyminCyIJan1OGvFOlgip0eVVPYWk1QVx1MDAwNJdQQlx1MDAxMlRFXHQsQFx0SkCaflxiJ55cdTAwMTK2KVxuY/TFXG5+PM5sn+9Fbec6XHUwMDE2OTOZuHXLXHUwMDFjOW683nzhXHJ111x1MDAxOcRzr/VAWDuoZVx1MDAxNyBywGGa3zByLCtrXHUwMDFlevBS0/HsoLmMnfFcdTAwMDNn4Hime1QmtTmJ/EM7nMlcdTAwMWRcdTAwMDVcdTAwMTM7u1x1MDAxZfbXO1x1MDAwMmCD8HtYu37gXFxcdTAwMWNuyM2J6ndCt976KqPGdZG1tus64zBv5zhcdTAwMDOPS1BCXHUwMDE4sFx1MDAxNsl0R5Ilk9RgSlx1MDAxMYVLrJ1cdTAwMDBSXHUwMDBiTFx1MDAxOVx1MDAxN5JiJnD6aMpcXGZwKbgkXG5hwjhR7P+KyanFXCK43+xfT09cIi/onPzEfveIXHUwMDAwhVx1MDAwYsr9l4SX28tcdTAwMWFHUmVcdTAwMWNBXHUwMDA3XHUwMDEw2Fx1MDAxMFDUZZogs0N5TcAlU5xj/SDr+ExcdTAwMDYsZLKO21x1MDAwN/unO+fOdPp1+t/tn/vHRSrE7MrzgFx1MDAxOEIrJlx1MDAxMVJYIy1cdTAwMTZ5oLjBldRcboxcdTAwMWJiRIhcdTAwMDJcdTAwMTmQIYEkUsqYSVxiK62LbGDaQJorLVx1MDAxNFx1MDAwMsJwqt/J8DgydFx1MDAxZk1cdTAwMDZcYoCoXHUwMDA0OvAyLohC65xcdTAwMGJcdTAwMTD6MEGIpi/NhXnz2Hfyjmj6ay1FVvJn/vvPj6V3r1fDOb5cbkBO31fYRddcZqNNfzRyXCKYaCtcdTAwMTay4KBEZlx1MDAxMG3AtjreIN9ne1ZFT/JUPVxi/MuhbVx1MDAxNkBcdTAwMDLP5fvu0Vx1MDAxYdvfRfdIofHkW31d/7VfR4e7k7NltFx1MDAwNoR6XHUwMDA2XHUwMDA0XHKKXCKwcEhnnKSZ1pCGJFpcbqxhMVx0TdmS0Vx1MDAxYVx1MDAxYVOFwHpyKqjWqfbNXHUwMDA2jIgqTCWDQVxihDXvNvRxakM9XmsgXGYuM6dIlqlcclpcdTAwMTlfYkSpVsCqXHUwMDE3z5v8PrVRgef4Klwi+Y3rjUYvJNP69mm30fl2sNHQXHUwMDEzU3t0acebXHUwMDE4WkpccsEy4YCIxTSTINRcdTAwMDDlglGsZUVcdTAwMTYw7973rPVFNMfjvW+sXHUwMDE4kjFcdEo0XHUwMDA3eJeVmkNzgFx1MDAwNFx1MDAwMnv80prjXHUwMDFlOpB+k1x1MDAwNz+1eXC+J7snP9pbu7un41wiXHUwMDFkKjKuXHUwMDFhfGyWz6wmXHUwMDA1XHUwMDAzTVxmLLksXHJCXHUwMDE1MihSPM4tVVZcZt5I+sgyw6H9vPmj749PtTKuMcOwOSWAzoY4OUBcdTAwMGJcdTAwMDZ6S1x1MDAxMPlcdTAwMTA4z6VbKdNaZ1unXHUwMDE3h4dHVrjTOTjqnKtcdTAwMWat7uWLZVrLpSlwpZhp1ZpcdTAwMDLiXHUwMDA1eJVcdTAwMTQryjNcdTAwMWXjjCuymiuCXHUwMDE5sU1cdTAwMDbLjOliSufNpVpfgCutXHUwMDE1ympcdTAwMDTcfdBHrEzLg1x1MDAxZK7U8sBcbk6Vwk/uXHUwMDFmSlxi1PhcbshNgXibtjxpd+r115Bu/YWRyadbc3I/TcJ1b6NcdTAwMTf1jyz13XTbg+tcdTAwMTNn4lx1MDAwNIPlskxKXHUwMDE1at9JgUQzXHUwMDAz/OXyPCtcdTAwMDZGa1FaXHUwMDE5kbFHzfGCyXzVvH3+XHUwMDEyycHjXTaOXHUwMDE0U4KIMlx1MDAxM8c0ybfO2VxmbonWiJNcdTAwMTf32X5TtFdcdTAwMDBmfGUgmb6gYFvfQnR30DjxRk3nXG6+XGL6co2a3k/aWeH8XHUwMDBiM3CJL8tcZs2qTr+AckBk8WzAnOpYaSN3muZVM93y4619VqpcdTAwMWY+2ptVQmlcdTAwMDWxRFx1MDAxOdNJtTOLXHUwMDA1XHUwMDEyXHUwMDE4gmz24kXSe+C8r7tWV3zfbVxmzltO1LTGe+x8sFx1MDAwMpyJoVXJcS5GtSFR7F+UIJpigyOqY7TPXHUwMDBldJXkNykxcv7qq8b181uw9lxujic49prrksrFLFSrXHUwMDA0MMVaXHUwMDEx9cCTL89cdTAwMDTgXbkrzKk41pf1va3h1tFgW1loJVx1MDAwMHNMc0dcdTAwMDdcdTAwMTNcdTAwMDQrYlS4Xu/4fVx1MDAwMvxcdTAwMWWtXHUwMDEyOHFNMKOq7OBcdTAwMTYpptvv8MuR4OCivWb1O72Y9NvnXHUwMDE33b2h2uNnrZ3p6OjMW+k0LSZcdTAwMDJid5zzKDiRRa/hXHUwMDFkv0+I385cbviV4O8jiUvryVhXO1x1MDAxMJQweFx1MDAxNMnXrH9H/vXkOrLO+ZBvn+pLejWddkuqXHUwMDFkxZSV0NpcdTAwMTBcdTAwMDJcdTAwMTW9YYaUIaqyVVRcdTAwMThcdTAwMTRcdTAwMDIoXHUwMDE511WlpKxcdTAwMDS675itwmzFyYjyM+CS6Li0UKZzi1x1MDAxOaw5ZLGkXCI+XHUwMDFh8HpqmXe5qk4zfIpMlWv3MzAo5KlcIj+TdlpMUi1cYpvPSC1I9zT5qDP0dcfZsTvDK8/sXHUwMDA2V8NLebZ3uLRtkZxcdTAwMThKXHUwMDE3clJcdTAwMTTCUaVcdTAwMTkvdeyxYoZiMinWJIYlPVx1MDAxMfXb6i5/9JPrjTPzeHlmMsVcdTAwMDVVuNSZ5/dcdTAwMWPUXHUwMDAzXHUwMDFipLF4UNbptmPF0kqjbu6ehydcdTAwMWU+3Vx1MDAxODrtSaPRPFx1MDAxObRerLRSLs1cdTAwMTJ2XG7gXGauXHUwMDE041xiXCIhJbJ5u4RcdTAwMGac3sNcdTAwMDdcdTAwMGVkXHUwMDAxXHUwMDAzj1x1MDAxMJ+5ab/fWP1v0OFkeTpcdTAwMTBcdTAwMDQxXHUwMDFjw0yXVlVYZXCgXHUwMDE0VpyrV3iCvWGPXX9cdTAwMWGPtdbxnOgpjNZjyyu/MCV5Y1Y5g5VcctuHW/1QM8fjdlx1MDAwNCtdu8vc1S5cdTAwMWP7cqOaXHUwMDAwXHUwMDFmblx1MDAxNUFMXHUwMDAwO0n43Xy4+Vx1MDAwN3qFK98ifQ==AppXSUAAUIsDeployment Unit \ No newline at end of file diff --git a/guides/deployment/assets/microservices/multiple-apps.excalidraw.svg b/guides/deployment/assets/microservices/multiple-apps.excalidraw.svg new file mode 100644 index 0000000000..dcf4de2f12 --- /dev/null +++ b/guides/deployment/assets/microservices/multiple-apps.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXGlT4spcdTAwMWH+Pr/C8nxcdTAwMWRzel9O1a1bMuA2oqDCqLdOWVx1MDAxOYiQYUmEIOKp+e+3O1xuXHRJh1x0ittcdTAwMWNS5Yx2tk7yPO/zLt39z6eNjc1g4jubf21sOndccrvrNlx1MDAwN/Z487Nuv3VcdTAwMDZD1+urXSj8e+iNXHUwMDA2jfDIdlx1MDAxMPjDv/78s2dcdTAwMGY6TuB37YZj3brDkd1cdTAwMWRcdTAwMDajputZXHKv96dcdTAwMWI4veF/9b9Hds/5j+/1msHAim6y5TTdwFx1MDAxYjzcy+k6PadcdTAwMWZcZtXV/6f+3tj4J/xX7XGb+o77uF7sjyrds1xu2S+Vzoec8FNcdTAwMTmeXHUwMDFhXHUwMDFlNH2EgdNcYux+q+tEu+5UO5PY4lx1MDAxOFx1MDAxMCY4ne2YqFx1MDAxZJghS0JcdTAwMDJcdTAwMTiK2sduM2irfVx1MDAwNEBcdTAwMGJcIlxuplx1MDAxYpxcdTAwMWTRdtxWO9CnQ2oxXHUwMDBl41d9uPtfXHUwMDFiYNYyXGZcdTAwMDZex/niddWzqi7+XHUwMDAxJYdcclx1MDAxNHXwu93otFx1MDAwNt6o35xcdTAwMWRcdTAwMTNcZuz+0LdcdTAwMDfqjUTHXbvd7mkwXHSvrr6FeombiXt8e+w5SrRnnaVu2mr3naF+69HTeb7dcFx1MDAwM/12IIieQvfQ32+GXHUwMDFm6O+oT1x1MDAwM/Vp9/VcdTAwMTfqj7rdWbPbbzr6vW/acO5u/ebj3eaOXHUwMDFlOo6+XHUwMDAyXHUwMDE0gjDAJcOzPVx1MDAxMVx1MDAwMiVcdTAwMTTJ1iOvXHUwMDFmopGo9ylcdTAwMDCPneZcdTAwMGWLXG5PQXjVa4VJJ3rXulx1MDAwZqVcdTAwMTjWokdcdTAwMTn5TfvhXHUwMDE0yFx0wlx1MDAxMkJcdCWL7tp1+51kz7teo1x1MDAxM90lbP352Vx1MDAwNN+tqnt7UuBfRuK6NuxuV/Z4ULxPw9fpdl1/mFx1MDAwMK/gxEJcbu9USiEh4GhcdTAwMGXBlDNcdTAwMGIwZoYw41x1MDAxNmNcdTAwMTBcdTAwMTPKOIaEQZSGMFwilrpcdTAwMDTlSFx1MDAwMIhcYkWC/Kug/NimWlx1MDAxMbzev76fnFx1MDAwN/1B7fxcbnr1M6Qw/Lh/XHTE810z5P+JbvX4udFjy88kXHUwMDEzXHUwMDEwQEh9XHUwMDEwXHUwMDA0TUzggmUxXHUwMDAxqnNcdTAwMDQhmL9nKlxmXHTfhqfVo8uDXHUwMDFidzLZm/zYvTr6lqaCukeKXHUwMDA3yFJcdTAwMTZCXHUwMDAyTlx1MDAwNZRAsnlcdTAwMWVcYmFBXHUwMDA1diAwXHUwMDA3XHUwMDA0MZZcIlx1MDAwM7C4gIhzjlx1MDAxMVK2XUiZZlx1MDAwM5FcdTAwMTaQVKiHXHUwMDA1ijBcdTAwMTTLNVx1MDAxOZ5HhvqzyaBkXHUwMDAxc0VcdTAwMDdq4lx1MDAwMuOZXFwgQnIsXHUwMDAxeHMuzJp9z417OHqLftuIkFx1MDAxNf4x+/3vz8ajt7LhrLdcdTAwMTSQo+ulvmLXXHUwMDFlXHUwMDA2X7xez1xy1INWdCdTXG5cdTAwMWTYg6CgPqvbbyX3Of1mxp7wrO3BwFx1MDAxYrdcdTAwMWQ7XHUwMDA1XHUwMDEydV5y31x1MDAwMquxe8zqZ1x1MDAwMvijr9tb8vvRNjg5XHUwMDFjdfJYXHJJoPLwJGKcXHUwMDBiXHUwMDAwJIpcdTAwMThcdTAwMWRaXHJcdCxcZrhcdTAwMTBMqpeJcMSWmNWQXHUwMDEwXHUwMDBi5TtCilx1MDAxOZYy0sfIaihcdMZcdTAwMDJiToCywFxmoLWGPs9siOdbXHJcdTAwMDA5XHUwMDAyVH1bk9kgINk6NVx1MDAxYlRRhTMhXCJr89tZjVxmOOstXHLkXHUwMDBmbjaKjSGabO9e1ou1r9VCUY5s2ce5/W6s4j9GICOIclx1MDAwZecjR4aYRaREXHUwMDE4KCOrjEvacqyd7zcwXHUwMDFjz3e+oSCAa1x1MDAxMlx1MDAxOFxmh8ApLyQyXHUwMDFjUGAgY1x1MDAxZeP7c73R9T5cdTAwMWRcXEm7elPm9fOL053Dw0s/d1x1MDAxMkVcbmpcdTAwMTGOXHUwMDE4jUeaYVx1MDAxMkVcIlx1MDAwYnKq3ZF0XGIqtMBcbioxp5lZlFx1MDAwZpI9adrDtvO66ZPjvHDGmXAmVEJcdTAwMDLVxzHgmZJU6yyrQoDQdu0pcJ71LupnXGZegXNcdTAwMTd9l1x1MDAxODq3yc7l7cnJWXN4UKue1W7ERaU+3pxcdTAwMWT3M2Vccl6UK+bepLgy9zBcdTAwMGY0kVghnikvXHUwMDAyK4tAY/7iXHUwMDAzV3g2V1x1MDAxOLG0JCthhlx1MDAxOM1cdTAwMWRcdTAwMTEpxporWVxcqSyRakTK2Vf2iJiMPCWZQaXONHKl5KuOKbGKVGPav4R3XHUwMDE44k89/flpbXs79lx1MDAwNb1+cOreh0JcdTAwMDfmWnfsnttcckOfuWtsd92WfvjNhuquM9iMv4HAbdjd2Vx1MDAwMT232YxLQ0Nd1FZh12A/j8Z4XHUwMDAzt+X27e6Zud/2KPBOnOFDz4PByIm/XHUwMDEzZ2/KXHUwMDAyaCG6gLvlQiO4PmuKY7t72ro/d0fuoJUrxSSBXG6bk/JGJLNUXHUwMDE0ac6wQsVmOVdWmFFVJ2YxhXNy+a45u8Cri/q7UspWn+2tXHRcdTAwMDKBIMp3Nlx1MDAxMJnEbG+CyFxiKKedKDv81t7aXHUwMDBihXkpWOotXHUwMDA2yOhcdTAwMDIpVf1cYmFdtXje7+27d+o/XHUwMDA0Svdgv3+Fa0tUXHUwMDAziVx1MDAwNVxyXizJpjlcdTAwMTGWXHUwMDA0XGJcdTAwMTNsXCI6XHUwMDE0ymrM11x1MDAxNt81z5ue/rSvqs0nz/ZjXHUwMDA1XHUwMDEzUqgowuTGomw3Vjm+hGJcdTAwMWGPz99fXFx2JOvNOjs+LLZuKm6w3/TL5Ka1XHUwMDA0nJElhaG4TbC0OOBcdTAwMDCbfE1cZi1cbrDUaH8ob1x1MDAxYvKaXHUwMDE4WVx0T/Vd4/r1q9unS7icyqWXVEVcdTAwMDUmpYLZLickXGapczF784zkXHUwMDAyXHUwMDAwXHUwMDFm8kNmT9g3Od4u77R3zlq7olx0llx1MDAwMjCFODGQXCJEsEBWXCJcdTAwMTJa43eF+D1bJmSiXHUwMDEyQYKFNOBXuVNZ+GXKOOtcdTAwMGb1nuE7uVx1MDAxZF2f3tzWy21Rpp3KwaR31ukvNbhcYlwipsJ2mHApKOJpt2FccuBcdTAwMTVcdTAwMDK4tlx1MDAwNIC5XHUwMDA0XHUwMDE0cGgsJCOQ7UFg5StCieibXHUwMDE3klx1MDAxNyC4592P7oPmXHJt091LOcZ3k0ndUOdIZ6uYlFx1MDAxNmMg7Vx1MDAwZVx1MDAxMyAslpWowszCVEquXHUwMDBiqpxjYoDuXHUwMDFhs1mYzVx1MDAxOFx1MDAxMmFcdTAwMWVcdTAwMTLHkcSAc5PRTce8U8hcblx1MDAwZShCXHUwMDEyvJ/odpqmqu1cdTAwMGZXkaTqOtcxXHUwMDE0pFJUgVx1MDAxN8s4zeen5jqbTEbN9W41qahcdTAwMGXYO3BcdTAwMGacWvuub9dcdTAwMDd37THvlE9yS1x1MDAwYqfIXHUwMDEyMpWRwipcdTAwMWNcdTAwMTWSUKNjXHUwMDBmXHUwMDA1sVx1MDAwNOFhmSbUlWgk1ItVXFz+uFx1MDAwZbdcdTAwMGZOzG/5iUlcdTAwMDRlWECjM09cdTAwMTdcZtCDUnFcdTAwMTNj8aRo9HHHkmWV4rZ9eDM878PLQts9XHUwMDFkXHUwMDE1i/vnrcqblVXMvckhVFxu0MqXXCJcdTAwMTQgwVx1MDAwNKOxXHUwMDE0fMhcYopcdTAwMTcwgiq6QClcdTAwMDGgXHUwMDBmftrLq9XvQYjz/IRAQEVxXHUwMDA0XHUwMDEyaa6oZIZcdTAwMDdcdTAwMDKqc1x1MDAxMH37snlKqoqO3/Um+l5cdTAwMWK1vlx1MDAxYqxCtp5bW/mFmCTlLPNcdFYjbaOaLyG/vXNY7bp5s1fnO559l1vaXHUwMDA0l3o0L0tUT0LXk0qLXGKWXHUwMDEx+FNuYVx1MDAxMe56XGKbXGbDaj7KgILXZ/TF88dcdTAwMTNwqSdcXDBukj7GM2dpIFxiMJOMyldcdTAwMWNRsFcola79XHUwMDFh+XJeqpcnXHUwMDE409JdtVx1MDAxZJO+z+bLPpx81vHHo3tU3Vx1MDAxYnW2Llx1MDAwZjvH3vejnfL8Xab3t3XlXCLvdS+527kjhVx1MDAxZNQsXHUwMDA0peu94y9b/nec77q/lmqktC42rv1ZUm1+ezmkWkhcdTAwMThcdTAwMGUjXHUwMDA0ylxuM6T+mmc3I1x1MDAwYtiNiSXVxiRcdTAwMTGIIGgsrK5Dyyx6Xy5cdTAwMTFaMuUzXHUwMDExbFx1MDAxOOygbSzOzEdcdTAwMTNcdTAwMDEkxJKsNrZcdTAwMTScXHUwMDEznUt4jmBv+/57XHUwMDEw6V/IYlKk53q9XHUwMDFhYf6+V1xuXHUwMDBl+EmrUebHI390elmp9nj+mFNcdLNOk1x1MDAxOeJOwqCeVZBRUVpcdTAwMGLzxtOZ23h+gVx1MDAxNHFcdTAwMTWUXG6TLPPY2ONUfVSxTp31tPLS02TZxzUk6zetRqmxVzjpl8vH58fyzWTO3Js8XHUwMDExqVx1MDAwNFx1MDAxNmKIQ0BDuiRlji3gylrmwtYnkqW5hMxcdTAwMDFcdDBcdTAwMDfIXHUwMDFjl/JUa5T1R1x1MDAwMjO06vHcSueA+qFLQPe96twvVOZcdTAwMTV0ruFcdTAwMGb83bNRwS+yfvlmdMxqndZubp2TXHUwMDFjW4xNS3CpXHUwMDAwXHUwMDE0cZrYs9a5XHUwMDE1UNd5ts4xhiBcdTAwMTPcuEpcdTAwMDDPrkNcdTAwMGKmXHUwMDAyXHUwMDBmddYrhp/HlLQrt6fnVVjdLdk7x+JqWP7yXHUwMDFih5/asOH4+lx1MDAwNM/SZfPby6HLUlx1MDAxN0Co+txcdTAwMTm6TFx1MDAxNnB7rcth61x1MDAxM8l9nV+XOeBCXCJqXHUwMDFjzkd5trtcblx1MDAxNPU5XHUwMDA2dLXD+X6j8PNcdTAwMTei+FxusuxtuZNvvNxcdTAwMWLSinu+9214UWzVXHJcdTAwMGW1YYFcdTAwMDekwktoXHUwMDFljSCFxVByXHUwMDA1nylrubBwJl05S1xy0V+XeGaUbeWnLNTlM1xuhNGTznSk1Vx0ypFe9ZIkirCQXHUwMDEwXHUwMDAx4lx1MDAwMH2TkfZcdTAwMDbohc0z0EVcdTAwMTdIyedHXHUwMDE4aT+xQfHusLGnfr7Sxs7lmI5cXC9cdTAwMGaZpeRcdTAwMTahXHUwMDAygPlcdTAwMTFE01x0NVx1MDAxOCf3zMiM07NMIzJcdTAwMGJrXao18bidn8dcdTAwMTJcdTAwMTLO9dooXHUwMDA2XHUwMDFli0zl5VBKTFRktHJcdTAwMWVcdTAwMGJcdTAwMGWfJLyrnTFjgJ3eQsB9cFx1MDAwZS9cdTAwMGUlXHUwMDEy7v48ifXiKTi1vFhIYlx1MDAwZS2CYcbCY0haJHNiXHUwMDFjUCpcdTAwMGZfYNW8V2byXHUwMDBizYnrmJm8zPJhXHUwMDAySYFcdDRcdTAwMTGcZlx1MDAxMlxcXHUwMDE5XHUwMDA1LqlET0pcdTAwMDQv9KyVXG48aW7rSlx0bkCk3rZcIjCukuWxr/W4smWe4lBcdTAwMThcIjRG+pFVvzS5XGKWiGGd1qeRi6WxZfv6k1k80flcYlx1MDAwYnOmJas7i4OFWHf0XCJcdTAwMGWMak9cdTAwMDdwXHUwMDAwlEtcdTAwMTeNLZ31XHUwMDA2WVNzkFx1MDAwNuYy1ixpiJzud2+cK2WwOLex0NAxaTEokubsYVx1MDAwZYp6zVx1MDAxNErz2DLELIp4xsRAYKGPYeVcdTAwMTbN1n8hM9d9tpmDQFx1MDAwZkSRzDiJXHUwMDFmZ6dcdTAwMTCYQIhcdTAwMTNcYlaeQlg2+fVCnoxcdTAwMDGS4YlcdTAwMGZgfFxyK5fbrCgrR7BcdTAwMWXTSbVIXGKMabzPMyv3XHUwMDEw9j/NxOW2uKorjCEkMGeCXHUwMDEwXHUwMDE1o1x1MDAxOFxmLrXEdGmOt7JxtEGHk1x1MDAxZuCub1x1MDAxN7rVQuuywi6bXHUwMDA2Z864opXiioKGnlx1MDAwNZOKyVx1MDAxONJzRZN7ZiNoucWUXHUwMDFkNFx1MDAxYTnEX2RcdOR37MxFqKhcdTAwMDTfncZhlVx1MDAwN9Vt5yvw6Wj0o1aMg+tIXvlbXzv3O+iU7ZRcbn048JrHT1jXapg/vEOCQiziK/fEpjnhzFx1MDAxNVx1MDAxMSAkXHUwMDAyMVx1MDAxMU+Xr8Ysqq5cYrGiWv3pVdu7aI47R5XihXf4XHJcdTAwMWN1h8P9XFzZXGKuRJxcdTAwMTkn6TFcZlwiNyqFfIkskCxcdTAwMTHG9X2+vL9G/sqRXHUwMDFm5Ec+XHUwMDE0XHUwMDE0KHc5vSasfjMke1KGim8lYfHFgN5cYvkv41x1MDAxMFx1MDAxOCCst60pelfpXHUwMDExvEF2o9e8KJzYO0RWXG4lXHUwMDE0nNdbXplcdTAwMTnqhEZBhIBcblx1MDAwYiCSXFz2Y2pcdTAwMTegXvlxrYjv0S6Mllx1MDAxOerKhHbNpXHtkFhcdTAwMTEhtZy6XHUwMDA0Up3JVj3WdZWS+CVoleDOwc6gMlx1MDAxY5VG1eL+3uS4lE9cdTAwMTKxilxipGlBR0a5JWRcdTAwMTLfM0mEXHUwMDE2ppRk5fYggkDiNfhfXHUwMDEy/Lf5wU9cdTAwMTnTYVx1MDAxNTZcdTAwMDXJKLambTLdj4gyfEL8rpqYxrDetlwi+H5wVVxmxtvS/1Hi1yfji+JV7awy6J5cdTAwMWPkXHUwMDFiPUOzUv5cZsNcdTAwMDWeMuPhJEtcdTAwMDapQo5eZcwgjP9Go7Aqzo/zc55QoFx1MDAxNI+m2a07TDNDQP3RlM3nq65cdTAwMDA8nfPTsTWl2/A20ct6bytcdTAwMDckO7j0SJpPj1jYtH3/NFDvb3Oa0tq8dZ1xIVx1MDAxYvyfXHUwMDFlTYBcdTAwMDa/XHUwMDEzplB/fvr5f3R2blx1MDAxYSJ9XSUAAUIsDeployment UnitAppAppAppEvents \ No newline at end of file diff --git a/guides/deployment/assets/microservices/multiple-dbs.excalidraw.svg b/guides/deployment/assets/microservices/multiple-dbs.excalidraw.svg new file mode 100644 index 0000000000..bb45fc5baa --- /dev/null +++ b/guides/deployment/assets/microservices/multiple-dbs.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXGlT4spcdTAwMWH+Pr/C8nxcdTAwMWQzvS9TdetcdTAwMTZcdTAwMGUuuOKGjrdOWVx1MDAxMVx1MDAwMuRcdTAwMTBcdTAwMTJMgoqn5r/ft1FJyOKAMqOeY6bKge4k3el+nndcdTAwMGZ/f1paWo5HXHUwMDAzZ/nr0rJz27Q9t1x1MDAxNdo3y59N+7VcdTAwMTNGbuBDXHUwMDE3XHUwMDE5f4+CYdhcdTAwMWOf2Y3jQfT1y5e+XHUwMDFk9px44NlNx7p2o6HtRfGw5Vx1MDAwNlYz6H9xY6dcdTAwMWb91/zds/vOf1x1MDAwNkG/XHUwMDE1h1YyyIrTcuMgvFx1MDAxZsvxnL7jx1x1MDAxMdz9f/B9aenv8V/ocVtmxFx1MDAxYW1U/WHdO66z2traWSSZPNLjS8cnPT5C6DRj2+94TtJ1XHUwMDBi7UJTS1LEhJJ80jGCXHUwMDBlKoilMUOCJO03bivuQlx1MDAxZkPYwoSjx1x1MDAwM0/O6Dpup1x1MDAxYpvLMbeExOm73o/+dVx0TVqiOFxmes63wINnhSn+gbXETZJM8NJu9jphMPRbk3Pi0PajgVx1MDAxZMKKJOe1Xc87ikfju8NewFwiLmfGOH2YOcm0l11cdTAwMDWDdrq+XHUwMDEzmVVPni5cdTAwMTjYTTc2q4NR8lx1MDAxNGaGg1prvEF/JnNcbmFra2aH/KHnTZpdv+WYdV+28dRofuthtKmzI8cxd8BKMYGkXHUwMDE2dNKTIFBcdTAwMTOUbd1cdTAwMGL8MVx1MDAxYTXlXGZcdTAwMGJGZTJ8VFx1MDAwNTzF47u2XHUwMDAxk06y1mZcdTAwMGVrKawljzJcdTAwMWO07PtLsGSEakxcdTAwMTXVKlx1MDAxOdVz/V525l7Q7CWjjFt/fC6Cb6XvIOf7+c1217/71uK+OqjsrM5cZl9cdTAwMDUwQzyPXsaEpSVcdTAwMTG8XGK+mFx1MDAwMXy1Jlx1MDAwNp1j/NI8fuF6XCIpLN1cdTAwMDd+S/BLivH7uL3J3tGHllx1MDAxZjlYU65cdTAwMDVcIpzpXHUwMDAyWPPUxmVgjWH2XFxcdTAwMTIq6XNwPZlfMtNcdTAwMTTOYuc22ZhcdTAwMTRMt+pcdTAwMDfN1ZWNuMJOt1x1MDAxYlffNuvtu5Pz5cl5P1x1MDAxZT6VkkZJXHUwMDA1bFRyMaQpnk2ONFNcdTAwMGZzz1x1MDAxN6EszFx1MDAxOcVcdTAwMDRTXG5TwtOs4dJcdTAwMTJIp0H/yFx1MDAxOcosXHKH0ExcdTAwMTFGpuT6hDPkgyslXFyhs8t6QFxuXHUwMDA3kU5wXHUwMDAxJ6guXHUwMDE19ZhIxSlRXFw/h1x1MDAxM4uEbYJCgz4j4Vx1MDAwN4PU9lx1MDAwNX585N6ZKaf0lmldt/uuZ9abT92h4rlcdTAwMWTz7MtNmKxcdTAwMTMup1x1MDAxNyB2wWKanNB3W620fmjCTW3Xd8LaLIomXGLdjuvb3nHRrO1hXHUwMDFjXHUwMDFjOtH9vONw6KTXw9l8JFx1MDAwMLZcYn+CtStcdTAwMDfu9eGq/DZU7ZPIq9Q3ZVxcvcuz1vE8d1x1MDAxMGVcdTAwMTSdxtpigFxmJaRcdTAwMTRcdTAwMTKssiniclx01lx1MDAxNifT+uqRulx1MDAxY1mESM1cdTAwMThVgmmENMtTXHUwMDE3K4swRjilXGZcdTAwMTOBXHUwMDE4Te7/b6ByorNcYm7X2nejs9hcdTAwMGZPzi5w0DgmwOGcdP8p4+XGrOqRlKlHXHUwMDEwXHUwMDAyRFx1MDAxMlx1MDAwNZK6QFx1MDAxNEilykRcdTAwMDHTXFxcdTAwMDBU5GIlwWKtvojJXG4+Otg737pyR6PN0V9cdTAwMWJcdTAwMTd7p3kqXHUwMDE4dmV5oCywaVx1MDAxMUWYXHUwMDBiLOQ0XHJcdTAwMTSzXHUwMDA0ZUxcbsxAWVx1MDAxMZ3jXHUwMDAysmBdtFx1MDAxNESAZ6O40KLAdVx1MDAxMVx1MDAxNpiPXGIp0HNSY4k/qPAyKjReTFx1MDAwNXCAqFx1MDAwNDLkTELDXHUwMDA0kTNcdTAwMWZcdTAwMWaZQJRcdTAwMDKfXHR8oNdmwqR5XHUwMDEwuFkzNPm0lFx1MDAwMGv8ZfL5z8+FZ6+Uo9lcdTAwMWM5XHUwMDFjJ/fLbaJnR/G3oN93Y3jQuplkzjyJ7TBehV11/U62z/FbJT3jqyphXHUwMDE43HRcdTAwMWQ7h1x1MDAxMbgu2/eEzNjYXHUwMDE3jWOFXHUwMDA2w+3Kir7cq6DDnWFvJpkhtCU0XHUwMDA2q1dIJpmYdlx1MDAxNblcdTAwMDJXXHUwMDBmlFx1MDAxZnhcdTAwMTVcbv7hRFwipISGkkb5clx0W2+s31x1MDAwMqHBLFxmYlx1MDAwN2GKNYzDWKJkP6TGc6SGernQQFhcdTAwMTLEKUqUREpqMJJtfZRcdTAwMWFgSElNXHUwMDE1/1x1MDAwN0uNXHUwMDEyOJsjXHUwMDBm5HcuNqrNiIwqXHUwMDFi543qyfbBalVcdTAwMGZt7dOZrW5lXHRCOcFcdTAwMDJWgiaGmOGCwNRCXHUwMDFhKYw5ZzLtsX1Y3lx1MDAwZq2vXCI4Xm55Y8WQpKrQ8FY0J04m4VZcdTAwMDVahHH8lsOtpF3j4YW2XHUwMDBmrnZl4+z70frOzvkgz4aScKtW3JJIXCKKSSZboFx0iFxyLlx1MDAxNS6ItypkUaS4iSuVplx1MDAwYt5J6KhlR13n98aO9l9cdTAwMWVnZVx1MDAxY6xcdTAwMWZcZptTgGeeslSyilAzqbR8llx1MDAxZZzMbq4oa4Wtn19cdTAwMWZcdTAwMWVcdTAwMWW3oq2Tg+OTK/W93riZI8pquMLBU1hcZleKZ5PjSj7KqjW1wOugXHUwMDFjlKiiPCX277lcIsu5XCKMXHUwMDA3qzWnoF3I1Fx1MDAxOe8uzPpcblxcqc+RUyOYmFx1MDAxNCYrXHUwMDEy8lxcPFx1MDAxMWglXHUwMDFhnEqGn5V8eFx1MDAxMrlcdTAwMTJjPFx1MDAwN3JcdTAwMTMgPoQsz45OKpW3XHUwMDEwav2JksmGWjPzXkywdXe1XHUwMDE5t49bat/2jjp3Z+7QXHI7M0WYlFK5xPc4OaKZRUWGlFx1MDAxM0uPWIjqqWsmfJXK4lNcbvNNs/ZcdLsume9CSXvwYntcctgoXHRY2EX6jaVCfFx1MDAxOSpLoiihVL26vfZrXHUwMDFjvTwmzfGIxuTqnFJ9XHUwMDBmXt1B9czv19xb+I+gtTtU8y/oyVx1MDAxY1Uv4OXyLMMptGpWVvNcdTAwMDJSXHUwMDAxZTIsKSdOW5lcdTAwMWGaN03yVmC29req5sNcdTAwMTebsUoorcCJKGI5yavxSTqEXHUwMDE5z5qJt5xcdTAwMGXZ041WQ+zvVDtXdTeutVx1MDAwNrvsqjNcdTAwMDeaiVx1MDAwNVMpqIKhOu+uTTL62OJcdTAwMGby4b6KqyA4QYmVsVPfNKx/f2L/aFx1MDAwZYNcdTAwMTNcZnrNtVx1MDAxNEVJXGacr4GZJDHAdSPcuFx1MDAxMm9cdTAwMTjAO3JH2CNxqm8qu+vd9ePOhmqhuVx1MDAwMFxmXHUwMDBmmKlcdTAwMTdcdTAwMWMjWFx1MDAxMavE5PrA71x1MDAwMvB7PI/DxDVgkaqiai2Cc1I5wS9VjCNcIt4yfkfXw/bR1XVjt6t2ea++NepcdTAwMWb3/LmKaDFcdTAwMTGa5+JinMi82fCB4Fx1MDAwNVwi+GRcdTAwMGVcdTAwMDRLjTiSuDCNTFCpXHUwMDA1XHUwMDAxXVx1MDAwMjHQovxcciO4XHUwMDFm3Fxy7+LWXHUwMDE17/KNc31Db0ejRkGaI1x1MDAxZqxcdTAwMTJaW0KgvDnMkLJEWZyKXG6Lcq0lQppISVlcdTAwMDF0PzBbhtmSgoji0m9JNEVSXHUwMDE2SV1WmopcdTAwMDB5TJRmgr06ZFx1MDAxM1x1MDAwND5Ee05q0VwiYlSe007BIFx1MDAxN6GKg1TAaTo8NTXZbCxqanaLiUT10OaWu+WcdG99u1x1MDAxMd52b2Rv93Bm3VwiwY1XOlx1MDAxN42i4I/CXHUwMDA280LTXHUwMDFlK2YpJsfV72PFUlTltGB2/tFcdTAwMWVcdTAwMWbvnJmnszOTKS6owoXmPC+vzsNIXHUwMDBiXHUwMDBlZtTzzPmHjjnTKtWKvXNcdTAwMTWd+fh8tetcdTAwMWVccqvV2lmnPmdaZXGaqng2M2gqXHUwMDAwNFx1MDAxOFPGllRCmXLXaUZw+lx1MDAwNCM40Fx1MDAwNWuNXHUwMDEwvzfUfr26+mdcdTAwMTDibHZCXHUwMDEwXHUwMDA0flx1MDAxY1x1MDAwM0+2MKPCS1x1MDAxZFx1MDAwNIWp1Jq9QVVVdVx1MDAwNl4wMmMtnfhuvFxitfXS1MpPlElWnZU+wWJU22j7dGuv7nXRTsRcdTAwMGVsvblyV6tszVhbo8bmJZg3Ulx1MDAxMLAxU0V191x1MDAxNe3CXHUwMDAyzGiGNcKIpuRpqrhcdTAwMDZzLVxm5Vx1MDAxOcJYXHUwMDE0XHUwMDE05ZnaXHUwMDFhuIWAXsQoSt3k32CQTuT78mVv6yyoxsejK7pWb5Jzue7YtWeU1nx/caaGISaEZrrwjS9e6oFJwsHbkHTRL7doLPCi1Np+7bT3/Vx1MDAwMlXaw9vTm631xvFd35st4YikJcxcdTAwMWI/ILFcdTAwMDTSKlueyi1OMGg8XHUwMDA2kpXokpp2rECMXHUwMDEywlx1MDAxNWYpVyFd0061YFxuXHUwMDAz0bBMJ70/mPBcdTAwMWMmnL+YXHSKcsk0UoXKkpbW5Fx1MDAwMGBcdFx1MDAwMXnHXHUwMDE3qy2fQYVJ8y+oaS9EszlyOE7ul9vE95DGvNyXXHUwMDE3V3+FXHUwMDA3/d3Nw7X9XWzvXq7uzSQ0jEFLuKaMm1x1MDAxYa3Uqy73QkNaxtFgxChWrYtr2oV5l4zCeiqqSFx1MDAxMkqYqmkn4K1oosG41v/WivZFyVxme1x1MDAwMW+EaYooV8XqM1/n/ig0qERcdTAwMWNcdPy8Sr73ITNKwGyOLIzfucioRLp+vdvQgb9xdmR3wrhcdTAwMTZcdTAwMWNcdTAwMTakKkpsblx0Ulx1MDAwMzZcdTAwMGaARFx1MDAxOZ62NEw9u6bgXHUwMDFim3p1TlPZiFx1MDAwZpN73PpcdTAwMWFC4/LlxeyEMSU5KayOXHUwMDEyqPQ1XHUwMDE4gjih5ldHXt3SeIJcZrLeOo1q24NecF3nbad+XHUwMDFhrK3vzFblhy2mNMmkN1x1MDAxZVx1MDAwYv1Ac5YkPpiwxMNvh+TRr5BcdTAwMDX6XHUwMDE4Lb7a7zdcdTAwMDeTflGlX3P2YFx1MDAxMldcYlx1MDAxM8RkUXQ1bzNPKtZcdTAwMTlcdTAwMTjUNP3TIVx1MDAwYoIsMXr39Vx1MDAxNV1cdTAwMDH4zJGC3ftRbp9cdTAwMWXmtmxcdTAwMGZcdTAwMDZHMaz3RKwtX7vOzWo5XHQ+PUhcdTAwMDNDXHUwMDAyZyxccn98+vF/J3uTviJ9AppXSUAAUIsDeployment Unit \ No newline at end of file diff --git a/guides/deployment/assets/microservices/multiple-deployment-units.excalidraw.svg b/guides/deployment/assets/microservices/multiple-deployment-units.excalidraw.svg new file mode 100644 index 0000000000..523405d521 --- /dev/null +++ b/guides/deployment/assets/microservices/multiple-deployment-units.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXGtT28hcdTAwMTL9nl9BsV+XybxcdTAwMWZbdeuWwYFAgPCycbi1ldJawlawZSPLgL2V/357ZLBkPVx1MDAxY1x1MDAxYlx1MDAxYyC7qGqzoGdr5pzu0z0t/n63trZcdTAwMWWN+t76XHUwMDFma+veXdPp+G7o3K7/bvffeOHA71x1MDAwNXCIxr9cdTAwMGZ6w7BcdTAwMTmf2Y6i/uCP9++7TnjlRf2O0/TQjT9cdTAwMTg6nUE0dP1cdTAwMWVq9rrv/cjrXHUwMDBl/mv/PXS63n/6va5cdTAwMWKFKHnIhuf6US+cPMvreF0viFx1MDAwNnD3/8Hva2t/x//CXHUwMDEx37VPrHQ97H25uP3UXHUwMDBlxluuXGL0cWV/M740PunhXHUwMDE1Qq9cdTAwMTk5QavjJYfuYL8mXHUwMDAyYcGlVmK6f1x1MDAwNPs5l8goKoWkyYFb343acJBwgogxlMBV2G5sekrb81vtyN5AXCKqXHUwMDE4Z6n7Tlx1MDAxZf/HXHUwMDFhnu5cdTAwMTlEYe/K2+p14GXBxt+IUaRJXHUwMDEzXHUwMDBi/3KaV62wN1xm3Ok5UehcdTAwMDSDvlx1MDAxM8KQJOdd+p3OaTSK71x1MDAwZZNcdTAwMDGjuJ55xvm96TSzv+wqeGirXHUwMDFkeFx1MDAwMzvsZLq313eafmTHh+DkLayF/V03nqE/XHUwMDEzm0KY2107RcGw05nu9lx1MDAwM9ezXHUwMDAzv+7QmadcdTAwMDXu/dNcdTAwMWWmN5k7dr/ne2K759lcdTAwMWJcdTAwMTMmjMRUcDM9kiBTy9zew15cdTAwMTCjlHAhhNJUJKPhXHUwMDBmqlx1MDAwMLQovu0lgNVL5sDa9iFcdTAwMGLCNFx1MDAxMGdwXHUwMDE2eXfJxKRgund03Nzc2Ikq/PxT/Xrr49HluHaxPj3v+/1PyfhccvuuM7GHKE6ZIVx1MDAwMFKiklHv+MFVdnA7veZV8lxu71KDliFNsTU50sy8zIQvUiNcIjgjlDCmtCGzrFx1MDAxMVxuSWzSoH/gXGbjyMAmXHLXlMfMyXOGvnGlhCusmCszZ9+TgsHQXHUwMDFhiikp4ITK733ghOZKY4WpflxmJVaJ2lx1MDAwNIRcdTAwMTZ81sH3+6nZ61x1MDAwNdGpP7ZcdTAwMTZTPLN32+n6XHUwMDFkO9xi5lx1MDAwZZWO37Kvvt5cdTAwMDRjvXA9/f6RXHUwMDBmXHUwMDExZ3pC13fddHhowk1cdTAwMWQ/8MLdReJML/RbfuB0zoqsdoZR78RcdTAwMWJM7I7CoZdcdTAwMWVcdTAwMGbv41x1MDAwM/5cdKJiXHUwMDBlaTeO/ZuTTbU11Je1Qady9FFF1XGetF6n4/dcdTAwMDfZOCc4XCJUMko5kFx1MDAxNqtcdTAwMDTb8ZAphrjWVJOCaCeB05IwLqRiMJ0kuTQhLkdCSaGoxoRyQTX/V1x1MDAxMTmJWJRcXO5ejkeNKFxia42vpFc/o8DgnG//Id/VzqLBkZZcdTAwMDVHcFx1MDAwMVx1MDAxNCZcdTAwMDT8dJEj0Fwiu/fBXHUwMDExUFxm2kdQlnrXXHUwMDE38lx1MDAwNHOoMOCqQk6PXHUwMDBmL/au/dHo4+jbztfD8zxcdTAwMTUsu7I8oEhcdTAwMWFwdlx1MDAxOGtisJGzPNBcdTAwMDJcdK2MhtiGOZUyR1x1MDAwNoxcdTAwMTSQRCllmYSJNibPXHUwMDA2blx1MDAxMDZCXHUwMDFiqTFcdTAwMTBGMPNGhqeRof5kMlx1MDAxMK2ZXHUwMDAyOuRQb7mQmuasUKRcdTAwMDRcdTAwMTNQLPL1RMV+z8/q0OSntVx1MDAwNFnxL9Of//y98OyNcjjbLVx1MDAwN+TkfrlZ7DiDaKvX7fpcdTAwMTG86JE1MqdPXCInjDZhWv2glT3mXHUwMDA1bsmR+KpKXHUwMDE49m7bnpNcdTAwMDNcdFxclz02x2vsfJb1M437w0+VXHLz12FcdTAwMDWf7Fx1MDAwZq9cdTAwMTbxXHUwMDFhkOohpbBmoI8wNjRh9MRrKKSoUZJcdTAwMThcdTAwMThMylx1MDAxMrakvIYhTGOInoJJZkxcdTAwMTJcdTAwMWbTXHQjZpowxeEhXHUwMDE00pq3XHUwMDE4+jS3oZ/uNTBRXHUwMDE0XHUwMDBihlWR22Bz8kspXHUwMDAxKIw9Kr/8NdxGXHSe7ZZH8i/uN6rNXHUwMDAxXHUwMDFkVXYu6tXap+PNqlx1MDAxOTomYFx1MDAwYlx1MDAwYm+KjFJcdTAwMDZyZSqUXCKzZSZJXHUwMDE5XHUwMDAy50Kw9bJcdTAwMTJcdTAwMGW/qe/X4Dmerr6J5lhZXHUwMDEyXHUwMDE0eFx1MDAwZc14dm9cIr5cdTAwMDXRXGb+e3HBMYdcdTAwMGX0cleEX41zfH2g6o0vp9v7+1x1MDAxN/08XHUwMDFkSiquXHUwMDA2NDbPVlbt/DJDXHUwMDExUUJcdTAwMTUmoVx1MDAxYSOGtbClpbjiSvI0YL9I9ch1XHUwMDA2be95y0efn15q5Vx1MDAwMkBEYHJcblx1MDAwMM1EeSg0QkpcdTAwMGVcdTAwMDGCPFx1MDAwNtBT+5YqtVb49sXNycmZO9irXHUwMDFkn9Wu9Zej+u1cdTAwMTKlVq2YhPhGVsOWYmtybMmXWo1hgHlcdLqSWZ+Q0oxcdTAwMTO2qHK2SI5sVIbYTNhsUeeXq7W+XHUwMDAwW45cdTAwMTYvtkKCSCl4JF7k51x1MDAxOdeltFCCgVdmauVcblx1MDAxMVx1MDAwNGuqhvuIcmvjtFapvIaC61x1MDAwZsJMtuCasXs1JdeDzWZ0eebqz07ntDVu+EM/bC1WZ9JcdTAwMWHBbOBskOOGI1DMxZVWXHUwMDAyjDaycGlEWU0tyEzQfNW8ff41kuOnizaBNdeSyqIgx02O41x1MDAwZmzmXGYzLPiLXHUwMDE3TH9StpeDpd1SgExukIusv0J2d1xcbVx1MDAwNN1d/1x1MDAwZf5H8Ycx3lxyvrLawnJWXHUwMDAyoUmBluVcYjTPLP9cdTAwMWZozsE1YDrbXHUwMDFiMCU60Vx1MDAwNuHZfoRXzXO3Z6f2WYl+8mQ1q6U2XHUwMDFhcolcIp7TXHUwMDE0jzM8XHUwMDE3kKdjrVKVuSdr2Vx0XHUwMDA0r7fH1ebn820v2jCNr9XjRnj+7WBW2j7A0LHATonZ3+fdd+MgXHUwMDFj11x1MDAxZH13c+I5nZZsVHbbtc3F7vsjkbzalPLQ1N26/LxfbV1cdTAwMWb50a7bP+DXrSU4SJHRuKCLh1x1MDAxOaSwwqwo2jKCXHUwMDA0ZsZSNE4pcUFRllGUkdivmozPXHUwMDFmdE+X0MqQi1x1MDAxOFx1MDAwMelM0VwiXGagqYx1XHUwMDAwNSUguj6Kdc+E3321L52RPDe3lYPt9vZZa0e7eCn8XG5cdTAwMDJJJ8lcdTAwMDFYU1RcIlx1MDAxNt/gu1x1MDAwMvieLZPqXHRDXHRnuqjZjOLyVE8zXCK00Pw143d0M7w8vb6pXHUwMDFmtPWBuDraXHUwMDFidc+ugiXwy2xziVx1MDAxMTN+Nk5ccqnKa503XHUwMDA0r1x1MDAxMMG1JVx1MDAxMKxcZuhcdTAwMTdFXG5XwYkpbVxyo1hat02JWSmCQUhBtqXUalx1MDAxMNztjYfjyL1cdTAwMTZtsXNhbtndaFQvWKPJl9mkMUhKnNfwXHUwMDFjayTLKmxMXCImjFF2NVgpxlx1MDAwYqD7htkyzJb0c1x1MDAxNGJcdTAwMTZQYlx1MDAxOFaqyOvy0nVcdTAwMTSYNYCWkC/uc1x1MDAxM1x1MDAwMN6XqWq7g1VcdTAwMTTXOt5lXG5cdTAwMDW50lrUS1XKZutqM8Zmi2gz1q2mhOY0++PaMNpQ7INu1lx1MDAxYbuN7vW4oGtxXnpcco5CXHUwMDE05NiSXCLNRYm6V1xmXHUwMDAyR9xozE28XHUwMDE1xFx1MDAxNlwi0CT8vFx1MDAxMbWYqO7iRFXxYJticZ82JctUXHUwMDAz4lxi9H1cdTAwMTJcdTAwMDZWXHUwMDEyW2wjXHUwMDBlxjKN2MfHlk+bwfbBx1x1MDAxM9H8sDVyXUpcdTAwMGb3trecxT8xwVx1MDAwNOJILpJMIMxcdTAwMTBmilx1MDAxNLfMU7tcdTAwMDAkJlx1MDAxZqeUrXlcdTAwMTKJ0iA3/66l/yWg7C1cdTAwMGVlQ6RRuuD7kdhcdTAwMTJWWlx1MDAwNiaQIGiY5Fx1MDAxNFx1MDAwN/699SGtOTE6tS72JFx1MDAwNm57X+jW9vC80b5cdTAwMTnpq1pTVIJv11x1MDAwYjNQYYF4/ruTmIFcXCFJREmGwiFAMNt0cE8vLVx1MDAwYii44ujx22W8/eJ0u1xcnG5aWuKIfDudXHUwMDFk3LzuS/Jq224piGSrY9uPOlx1MDAwYj6cXHUwMDFjbu35w72N6MtOVX/4Vj8j1cOlSEHgZYVYXHIpiq1ZIOVRXHUwMDA0wlx1MDAwZZE2Qk6yl1lK2Fx1MDAxNvlSSjBsP32EkZfa8NmE/6dlPv9cZkq0XHUwMDE2p4TUkjFJaGFXXHUwMDAxK62Ualx1MDAwMlx1MDAxN2mhV66lllx1MDAwNW0u66mmylx1MDAxNC/XUfCDKJJNhtJGryZcdTAwMTe6wlx1MDAxZvf8Pa/Wvlx1MDAwYpx6eNe+VVdcdTAwMDcni1x1MDAwYkngnmJcdTAwMDXLXHUwMDFjzDbqq0x0m8YwOCYln1bZXG5cdTAwMWFI30JYXHUwMDExX9uL85VrIdmM8Es3x5WWhinmithv8p6xOa5acfavXHUwMDA3jYBcXGy2/dNhtbrbaFx1MDAxZC1cdTAwMTfCLFx1MDAwNldUtSu2ZoFcdTAwMTCmOcQhyaRcdTAwMDZBjmk+hPFyQrxFsMcywl+cXHUwMDExXHUwMDE0S0M5KWiaWY9cdTAwMGIvZZQwglx1MDAxYVxifPhRKdQqQftKQ9hcdTAwMGZcIsjPXHUwMDBmYfNT0Uy6OKs6uURCXHRSsEzEJZ4jOaVGpX8yXHUwMDAwrvtH9MQl9q6UsWExY5f6kFx1MDAwMUuhiC7siSO8dNFIcJhPmJpHhbZ5VVx1MDAwNUz147ToSpvi8pi028Y9XHUwMDFjk6tz4XTpjrjUXFzd/ymc3Vx1MDAwNdrWYnfUXHUwMDFj2tfdsJ9OxFx1MDAxMp5pkI7ELnWlTms5feuSXHUwMDExZNL3q2A5KMz04ZXZM79ImrJcdTAwMDfMMVx1MDAxNFx1MDAwM7il5lx1MDAwMqQpw1wiZ1x1MDAwZSSok+a5PCyX6fzLuiGv81fvdiFhMr8yNs/NacJcdTAwMTEobdvnkltRVFx1MDAxMoHaK/mrQlx1MDAwMCmebWJK+bms33zVnm5e1/5PcnWDp7s6SoRhhFx1MDAxNX7joml257Q/iXEqgFmPqkPN83SUXHUwMDFilejaXHUwMDE3a/8twGV84Vx1MDAwM1win8PZLeFcXCA8SGKwYJIzI5JcdTAwMGbwXHUwMDEy30LRQyn4cZ5uXHUwMDE5z0uYhKGzn+FwqjRTeVdHXHUwMDExXGJe82ze7t39/Kw7/f5pXHUwMDA0iJu+6PqN791ulucu7+5ccrP+wYup9f3d9/9cdTAwMDOX8yV+In0=AppXSUAAUIsDUDU \ No newline at end of file diff --git a/guides/deployment/assets/microservices/true-microservices-full.excalidraw.svg b/guides/deployment/assets/microservices/true-microservices-full.excalidraw.svg new file mode 100644 index 0000000000..964fb39391 --- /dev/null +++ b/guides/deployment/assets/microservices/true-microservices-full.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1dW1PqytZ9379iled1m933y6766lx1MDAxNHhXRMC7p05ZXGJcdTAwMTGi3FxmQYVT679/s1FcdCRcdTAwMWRWwKylrk1cdTAwMWW8JFx1MDAwMZr0XHUwMDE4PeacPWf3//749m0tXHUwMDE49ty1v7+tuc+1asur+9WntT/N+UfX73vdXHUwMDBlXFxcIuP/+92BX1x1MDAxYt/ZXGaCXv/vv/5qV/17N+i1qjXXefT6g2qrXHUwMDFmXGbqXtepddt/eYHb7v/b/CxW2+7/9brteuA74Yesu3Uv6Povn+W23LbbXHT68O7/gf+/ffvf+CdcXPHq5lx1MDAxM3O1rTu+1yxcdTAwMTXcXHUwMDAzsvl82eqPRm55/NLxTW9fwXdrQbXTaLnhpWc4LzRxXHUwMDE0wpJLhVx0n1xcXHUwMDFhmkuEOopcdTAwMTBcIriYuvLk1YMmXFxlXGI7cFx1MDAxZb1cdTAwMWR4ckfT9Vx1MDAxYc1cdTAwMDBu4cxcdTAwMTGYXHUwMDEy88aRW15cdTAwMWHy9zc0OdNcdTAwMGb87r270W3B14bW/lx1MDAwYmuJayRs6021dt/wu4NOfXJP4Fc7/V7Vh4dcdTAwMTPed+u1WsfBcPzu0C3wPNdcIp9x/vpcdTAwMDVI5HzSq+BDXHUwMDFizY7bN1x1MDAxZFx1MDAxMH6Dbq9a81x1MDAwMvOYMFxuv4VpYW+vPu6r/4Zt8qGX90xndVx1MDAwNq3W5LTXqbumXHUwMDBi1qqXM5/Wqb9+2szdfdc171x1MDAwMJ0hKaJTXHUwMDFkXHUwMDEyYlx1MDAxMVMko6eL3c5cdTAwMTiYVHFGKZY0/Pj+JkArXHUwMDE4v+stwNNccp+1acPWXHUwMDE07MKvMujVqy8vwZJcdTAwMTGqlFBIovBRtrzOfbTlrW7tPvyU8dnvf9qQzFWtxi99dNpcdTAwMTNcdTAwMDPGXFxcdTAwMDPpwjA1kiVijuZaXHUwMDBipKmMIFx1MDAxOS4pXHUwMDE2vfKGZIFcdTAwMWNFXHSimDBtXHUwMDBlXHUwMDFlRzLl2UL3X7fj44vD9jY9bJlcIlgqTqhcdTAwMDW2XFwlolx1MDAxNlx1MDAxYsxijrReXHUwMDA2tq9cdTAwMTdCnM3AKHCfw3FjXG6Fp12/dOBcIrzLj9zKQf/+/LjQKq5N7vv++tdcdTAwMWNOSKqoXHUwMDEw2XDC3ppcdTAwMTgnZr7MXHUwMDBiXHUwMDFkXGJyiORacYmllJRFXHUwMDE4oecwglwiXHUwMDA3XHUwMDAzXHUwMDExXHUwMDE0XHUwMDE2SjNOp4VhQlx0sqKEhVx1MDAxMo30lMCIc6pcdJXaxlx0plx1MDAxMjmBqMbQp0tRXCJL1IYgNOCDb795OtV73U5w7I1Mg1x0mjm7XW17LfO4+cxcdTAwMWLkWl7DfPO1XHUwMDFhtNX116a/fuCBZTS5oe3V69ODf1xy3rTqdVxcfy+NinR9r+F1qq1cdTAwMTNLo6uDoFtx+y/NXHUwMDBl/IE7/TTc3TfoY4fwOZTN6UvBdp9cdTAwMGb3K4Wm389vXHUwMDFjXHL3rrfjlHVbLa/Xj4iYlsRcdTAwMTFcdTAwMTQryuNcIkalwzDCVmtcZktHMMWmX1x1MDAxMzJcdTAwMTWuSazk1yZs2NZcdTAwMWZcdTAwMTN2MlivbTc22M1F5UF29pr7srBHZeXo6W0wX4DXzfS81lx1MDAxYWMsbEKHKY6efSM1QVxmRlkmWSiFXHUwMDE5sZpxovQ0jpfXoqebXHUwMDFjfvLr5VP34vFcdTAwMTI3/OuWpypxYFx1MDAxYq5EUK3AyZBcZlx1MDAxMcriqFZcdTAwMGVDNkiDY4JgqJu5NsE0aFx1MDAxYprRpVx1MDAxNaRcdTAwMTeFtLdcdTAwMDCkXHUwMDE1x4xcdTAwMTBtUyow0ZJArYmkXHUwMDE0keWMtywxPTnd63pR2zD861vYIeN/Jn//90/r3Vx1MDAxNoCaY/1ccpvh62Od06r2g41uu+1cdTAwMDXwxUqmUbEnXHUwMDFmVP0gXHUwMDBmveV1XHUwMDFh0Wtup55wZfyqnO93n5puNdb38LrotTls7+h1/65QkqeqfJlcdTAwMGaCvKye9mopZVxmI8FcdTAwMWSNMI1cYs9cdTAwMGLjtVx1MDAxM+X1SsZ+XHLn79JzniCCwDrlVvNcdTAwMTSImER66DxNwLD9aM7PQba3/bjnXHUwMDFm73fy68fd/PV2zmvQ6lk6XHUwMDFkw1x1MDAwZTikiDNcdTAwMTFDNVx1MDAwMF4kXHUwMDE4Z1x1MDAxYV7FI6+ZUjJM8KxcdTAwMWK2wvWiuL5fQMsoQkpbXCJlpsGYJMFcdTAwMWFLXHUwMDAxuJZLRlwivoCYxTFqjvVcdTAwMTCeX1xczva8i9ZdfXhw2DxqrHvbpZ3z26OLNIFcdTAwMTStmcM1k5E4+JuUXHRNI87aJK4oXHUwMDFkhbVcdTAwMTZcdTAwMTjsejCgeOhb/7Qgys9cbonXq/2mm1x1MDAwMfNcdTAwMTegdGuB4FwiMlx1MDAxY1Ik5l3BNSqiJyeMVmZcdTAwMWNcdTAwMTdcYoV9kFx1MDAxMaM5XCLyXYGUrcfxx4RcdTAwMGZr6WBKy72dQkIslFx1MDAxMnR7SXGUmfZGgybRXHUwMDA2Zlx1MDAxNDhpu8i9vHo6aHZGXHUwMDFidd5R5VxcIZ8+/s/BrlRcdTAwMTG30DxcdTAwMWFGmMOSSMqlM77wNo1cdTAwMTU6Mz8t+P/7zFu1mJ2kYbz9rdPo65nvUe5i6Fx1MDAxN4FcYmc2M1OJ5Cgo2Jlcblx1MDAxMfxcdTAwMGInXHUwMDA29kvlWn59J8ix84Ozh43d0u3o9GqBiVx1MDAwMY1cdTAwMTnWTKBpbixvxNpbk0LPpERcdTAwMGU8O00wR1xufuNcYll0Mlkoc8xcdTAwMDSZ0ExcdTAwMTFGsNWe/SqS9lx1MDAwMWxR6SWNwrPV4ILZJE1OaUBM0zQoIahcdTAwMWFehlx1MDAxNllcIjemableL1x1MDAwYkF77+zAXHUwMDBmNCYqdDOtzkbl1sveYyUvN1x1MDAwNur2tN/KlXZlsDlKXHUwMDE5V5FCOzDqSVx1MDAwZfzDispcdTAwMTDd40dGsIOlnvEzJ+lcdTAwMWHY0ZJRLVx1MDAxMWNcdTAwMTJkLnR/JszF3CFMUMKo0tDfKpTCf1x1MDAwMpFDyVwi+HbvdjS8XGI6/unFNe6enVx1MDAxMGBwbHT/Md930qojSVJHXHUwMDE4XHUwMDAxiCRg2dqmXHUwMDEzpEpcZsLA0My0RjRb0zZbXHUwMDAx6zOZw8fl4tX+gzdcdTAwMWPuXHUwMDBl73aui+dpojBSKEdjoSX4Y2D46yhcdJQjXHUwMDE0V1xcc1xuUjdlQbxRXHUwMDAxOVxmhkhJOVx1MDAwMlx1MDAxZVHw4VicXHUwMDBiXHUwMDE0buJcdTAwMTJTqlx1MDAxMdBcdTAwMDb0Tq7I8D4yXHUwMDFjvZtcZliZXHUwMDExT1pTn6SInZ1wgVxirVxiVzjb1Kf3aGKmkZv1ZDybI47k8FxyY934XHUwMDE1XHUwMDAyOTtH4uxEod7gILeub4o5VClcZu7TjFx1MDAxYlxuY0dcbiHhOVBcdTAwMDHOf2TcgFx1MDAwN4Uw45SCXHUwMDA2XG5cdTAwMTH6XHUwMDE1U8NcdTAwMDY8QoZcdTAwMDCE0P3wXHUwMDBiW8Zcclx1MDAxOHw4uDOEIKkoY9NpXHUwMDFjq3FjqXHj7P3jXHUwMDA2wmAyc3vIV9JkXHUwMDE3k1xuxKFcdTAwMGazjfh+qnEjXHTQ5ohD+YtcdTAwMGZcdTAwMWObtT5cdTAwMTnmdq7ONk9cdTAwMGbK+U09qOpcdTAwMGVdwPBGYFBJbEJFSs46zZxcdTAwMTPHOF1cdTAwMWFGXHUwMDE1xZEtW3plfv/ykaOegcXBXHUwMDEwXGZcdTAwMTBW61vRxLxcdTAwMDcmtVx1MDAwNKHNOLCcrfV9mK9cdTAwMDW3J3V1VG1cdTAwMWQ3Rlx1MDAxN97A81x1MDAxYumsb1x1MDAwNeNcdTAwMDKOTYVAw5zYxOiUdCZkkXJcdTAwMWTPafsnwH1cdTAwMTFcdTAwMWMnzIQsgmOOXHUwMDE0U4JcYls4iek5k55cdTAwMTiDyY3Jb2o6R3FpjilEfnG9K29edNp73jP8XCJoa4T2Otf0NE7xxMIg5sRpXHUwMDBlzoVcdTAwMDPqZM/YY8JcdTAwMDFcdTAwMDVcdTAwMWNcdTAwMGZcdTAwMDEv9T5cdTAwMTZcdTAwMDNcdTAwMTlT7rze8zVcYl/vmi7+tYxcdTAwMGbSMj5xWkVcdKWVptJGeEJjcy2TNFRGpFRIfLjJO1x1MDAwN9ZFfVY/XHUwMDEzR4XNxkPJXHUwMDBi9uq9Q/bQWFx1MDAwMNZkXHUwMDAy0llcdTAwMDGj2pFIzk5cdTAwMWZOJj6ww19z1l6mXHRtISPiRIroPjWuf72QtVx1MDAxN6iNwJRori1RXHUwMDFkc5ElxnoowdqM3Vx1MDAxZq5Xc/BbkFx1MDAwNVFcdTAwMWSKc/2UO9xubp80dlRcdTAwMWQthF9uzatkijgvxZYr+P5cdTAwMTT4LjB9XHUwMDA3j1FcdTAwMTNsPDnb+JtcXKWJjVx1MDAxN8lcdTAwMTnRn1x1MDAxOcDt7mgwXG7qXHUwMDBmvMl3rvRcdTAwMTN9XHUwMDFlXHUwMDBlzyx+dHzmWWjtiGiS5Fx1MDAxOLpIOVwiWoI8XHUwMDAxr3Ao1+A5I01MXHUwMDFkmy3qtlx1MDAwMm1cdTAwMTJoXHUwMDEzwmdW0CpJTGKkNeM3OcufXGLTLVx1MDAxYX+4t1x1MDAxYlwi8HXy9nTvM+dQzbQum6nlrYte7lx1MDAwMfVb+efTRn5YzW/Vt3K5XHUwMDA1pIU6TGBcdTAwMWSx7sdmv1x1MDAwMG15q+WPMVx1MDAxNEvlUCZn8yNDclLkhGtcdTAwMDDAXHUwMDExpsatyDpL1lx1MDAwNXJcdTAwMWXBTCVMaLuBRHiiwiiJNVfZ15kpXHUwMDA19oWaRu07ap6veVx1MDAxNbXwvXt9eLSpXHUwMDBi7c3H8/3d9HmASDv8RSqixWaUgfOJWSRcdTAwMTi1Wlx1MDAwN+CduO2kh61CklwipuNcdTAwMTX/ZvjlyXO4UilcdTAwMDGdqpZcdTAwMTKZ11x1MDAwYlx1MDAwYqb7XHUwMDFkXHKIf76xfjYqilxyViA7lcrDnrvQOlx1MDAwMFlywt6aXHUwMDE0RpckzIFWSG1WYIitXHUwMDAzQDmaw4jVOlx1MDAwMEtTXCIh98dudyGNpbZXWnGcmMAuNSFcdTAwMTIglnX++sKwjVx1MDAxOV6fYyGAXHUwMDFmyMjPX1xioNjbPUOjytFGXHUwMDE3PdSeusWRkMNBelx1MDAxZFPCQYwrreI6JrnDlEgwx6R8y4N/0bFcdTAwMTBWXy6lfV7dyc9ibuqEg8TgqySGQUJZk/Z44lx1MDAxYVx1MDAwMFx1MDAxOFx1MDAwNI6Dd0x+oci1925cdTAwMDflI3d0SLdcdTAwMGWkfr4qeHfCWyyn3Vj+XHUwMDE5LVx1MDAwMGVvTVx1MDAxYZHTxCFcdTAwMDJcdTAwMWNcdTAwMThJuEn9i4icQnPoXCKYIyhYe3H/5svFXHUwMDE3PoIuXHUwMDBi+CySglx1MDAxZEdp3MxbXHUwMDFixzWTeFx1MDAwMZ2CqDky1bklkFx1MDAxYtO5i+PTaf/646TuXHUwMDA3Slx1MDAxM5W6SLuzUTs+YFi266KXK21uu1x1MDAxNzfPV/fNu9RqNy6tNmlcdTAwMTOaxCPbYMLCiDqrg6tcdTAwMDKu97P3XHUwMDA20XeLnVx0WYN3xq3ZdeCxzXPpJOVyOVovp3a507JXUo+9i1Llcr3UXG5cdTAwMDTGuc5iLp02ky/ZqJ29NSnUToPamVx1MDAxYSyqmZScWiq4XHUwMDEy2bKq4Fx1MDAxYZ9dli5cdPWO1khcdTAwMDfhWjLL2oZj035OXHUwMDA1XHUwMDE39CiZZlNGTt2iwI2J3Scp4PqBzPyCXHUwMDAyLvLYedT3XHUwMDA3RXp/UrzZLcpcdTAwMWKC6mnzSFxydTFWXHUwMDAyXGZcdTAwMGaMXHUwMDAwXHUwMDFj8Vx1MDAwMi5jvtqYu8ogTZ1B2rrS7KnlukVORs3RTWXb3aDdxTNIb1x1MDAxMH9/5lx1MDAxZFx1MDAwNb+DzmTQTaWQzontUJOFg+SHXHUwMDBmXHUwMDAzc3hwfcipauVH+mjnuVR62q/06/VUhVx1MDAxOFpcdTAwMDPDwNfSpsyYyFhcdTAwMDGXSbU2i46sXG64Plx1MDAxM1x1MDAxOcS7yaC5IDMl+1OKqFx1MDAxM2esuFRCc579jNXSirgq33pHVupJ/77SO3xcdTAwMWV5lZ27jV5ul9Xopk4zamBcdTAwMDTGK1LjdFx1MDAwM8ThXGKH1Lf6LfZSq7Kq3/pEw4Z897BcdTAwMDE+jllJkFvHXHI5by1cdTAwMDSijb2U7VpcYp9q4PhH1W9cdTAwMWRfb+eOXHUwMDFm/FxyioeDwWX58qp/4PdT2914vMysXHUwMDAyipoy4nj9XHUwMDE22OKMreq3PtHIkZBvucDIXHUwMDAxNiah2Fx1MDAxZXBWyVx1MDAxNeNcblxcM6GWXFxb6Fx1MDAxN1x1MDAxOd/BPj3G17RJePf87uTxcFRr7Vx1MDAxZKaTUWzyXFzGWabxJHiBXHUwMDFjjvFscvGqiiuL0JF+vy8pNSNm9X9cdTAwMWKcmU6eV9RgPWLB6G9qQf/eVVxcpe2tq839m2p3o1x1MDAxOFxcPe/qkt6+8uNET5pWwcJhkmAh42RcdTAwMDcgxdM2J4LHXHUwMDFk8ZJcdJqYRKDgXHUwMDE5jzdcdTAwMTB5veOLeNi/vqDrXHUwMDA25dKSP3GahUMvgVx1MDAxNVx1MDAxN2e5edGczUIwXHUwMDAzn1x1MDAxYumsbWBcckZSVlJWKtefrmXx4qTcXHUwMDFj3G+2j3aGXHUwMDA3d2RcdTAwMDGEg92lXHUwMDA1VbaSXHUwMDE4hlx1MDAxY5yUtbwqislcdTAwMDLZeTuyrXluXHUwMDAyXHUwMDA0w8xu2GKhJHlcdTAwMTOocSFccrgwXHUwMDFm7sfNwfBuYbdUXHUwMDE5XFxcdTAwMWPUXHUwMDBmytJcdTAwMWY8ja52b7dacVxmW+byiPEsXHUwMDA0kswy740sK5quymKygO1WetiC/yxcdTAwMTmCcdS6YrhK9FwiwO9g4FxmXCLxecyuf2xhjDwqn97u31xcXHUwMDA3p+u5W3yznu9cdTAwMDU7XHUwMDE2es6RXHUwMDE4KeVrcUC8MkYm1q6tKmMy4uv2XHUwMDAyMlx1MDAwM8YuR2bFdlx1MDAxYl9cdTAwMTlK9pOI2XuEoI/3k+Yg+aAgds+2T1xuzYN6oXRb3SyLvcun9EhcdTAwMDajRyMlrDVeTDgmWGiXm1VxzLLQXaRcdTAwMTJcdTAwMDA8Vm3WZLaFukX87CRgRczCVMvtuTJxQVx1MDAxNsqkXHUwMDFhVOsj2jm5vmmWPOKL69Fccr7UXHUwMDFmlkllb01cdTAwMWHri0nAPJNYYCU4iVx1MDAxNcfgOYxYXHUwMDE1xyxNid1cdTAwMDUooZBZwFx1MDAxM1mT6YVInv0xfFBoelOIz2J9fY7qmFx1MDAxZlxiyc+vjuGNUu7kuX99VvBaZ4/1u1qF0ss4aS3reFJcdTAwMGXMM3M5MVxyY5g48d0zw1x1MDAwMHYsLzKcvdHG1+LZ78P0+2zJcoNcdTAwMGVcdTAwMTaRMrCa0czuKlNpwYmLXHRwiaGhbKpcdTAwMTMyYq3AdMo++bhQdVx1MDAxNIHmmMJe+Fx1MDAwNjFcdTAwMDX9XG7Bar9YYqzzeJX3RkpcdTAwMTG0X1x1MDAxOGzuWHZwt81KmYg9R1jz+P4tQOpcdTAwMTd1tpM6VlwiXHUwMDE3yi9Czpdaa+xcdTAwMDM4XViA05KCoSOEPVx1MDAxMlx1MDAxMlx1MDAwZutNSM1cdFNUkcznU03Y6+NJvVx1MDAxZYegOULwfXFSS/EoSzLoqjI7wEf0LsfWn1k6oZZcdTAwMGWihNh2Tlx1MDAwM07H91R74zQh1KGJ9Vx0YHdHQvorUn+bJfVhelJLyVx00TS+mq1cdTAwMTl5k4ObaJxCoDPf51NJpKbWXHUwMDFh+ihO21x1MDAxMGiO9Vx0+L44qW9yO9uqfHPO/IO7bm1Yeng4KeNUpNbU0Vx1MDAxNFx0XHUwMDExjyBcdMxMylnyXCLAYnaf09D4Vs5KopPZXFxMz2YwXCK1oshcdTAwMWFAkolcdTAwMDJNwcTCUrLMl/001kLogH9ggsgs8swxxtxcdTAwMTcncfG+dNtez1X0Zat/py6va/6ok34pSYwwdoDEKJrw9bLEhHCYvYZwtb7E+OyybE69XHUwMDExTnLJLVxirzRJ8LZkXHUwMDEwhZJ3hVwiWJgyXHUwMDAyvNRcdTAwMDTHpH1cdTAwMGJcdTAwMDWKvVx1MDAwYvWQ59dXw2Gv2d1s9/J+viNcdTAwMTZcXGBCT+909b6dv62tiVx1MDAxMSZcdTAwMWUoNnuIOFx1MDAwNEZWjjiVXHUwMDE4xVaYwElsWS0vMT67LFtKi4ScODxcdTAwMWONrO6pnGPLSuhcdTAwMWPJs531W1x1MDAwMrchXGY/3fJcdTAwMTLzdeaXLC9RUqq/fc5cdTAwMGKjre7tRaF4duU3bft3J2id4sJRisScypddvKkjo7bpSuwyoW/53WLHpFx1MDAwMrFL2IOFJU7mU1x1MDAwNFx1MDAxY2RiuVx1MDAwMtrlpK6+Wa34qFEu9N3GcLuog9Y+vVxcTOqYwGRcdTAwMTF7eVx1MDAwZV/srUkhdUpQxyy4IyiyKJ2gKpksK61cdTAwMWKfXZYslfRaJ5A0XHS49v2BVfKGLmBcdTAwMWRqjEjGodglkPt5xe5cdTAwMDdCk7XY/fE6XCKsVXu941x1MDAwMJ7qZHhcXHv03Kd8clx1MDAxMsBcdTAwMWav1Ddwd8ej6vc/vv8/XHUwMDA0J/qyIn0=DUEventsAppUIsDUXSUAAAppUIsDUXSUAAXSUAA \ No newline at end of file diff --git a/guides/deployment/assets/microservices/true-microservices.excalidraw.svg b/guides/deployment/assets/microservices/true-microservices.excalidraw.svg new file mode 100644 index 0000000000..eddf3cfa40 --- /dev/null +++ b/guides/deployment/assets/microservices/true-microservices.excalidraw.svg @@ -0,0 +1,2 @@ +eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1da1Pi2lx1MDAxMv0+v2LK8/WY2e/Hqbp1S8C3IIpcInDrlIVcdTAwMTAgXHUwMDEwQiZcdTAwMDRcdTAwMDRPzX+/XHUwMDFkdFxikkRcdTAwMDFh1DNQNZbuXHUwMDFkwk52r+7V3YvMP1++ft3xx66589fXXHUwMDFkc1Sr2lbdq97v/Fx1MDAxOYxcdTAwMGZNr2/1XHUwMDFjmFwik7/7vYFXm1x1MDAxY9nyfbf/17dv3arXMX3XrtZMY2j1XHUwMDA3VbvvXHUwMDBm6lbPqPW63yzf7Pb/XHUwMDFi/MxVu+Z/3F637ntG+CG7Zt3ye97jZ5m22TVcdTAwMWS/XHUwMDBmZ/9cdTAwMWb8/fXrP5OfMGPVg0/MXHUwMDBiebZr7/ZcdTAwMGYqZsZuVvdV/Spdnrx1ctDPS/DMml91mrZcdTAwMTlOjWBcXGhiSEJcdTAwMDUlXG5cdTAwMTM+nVx1MDAxYcNcdTAwMTRcZlx1MDAxYVJiplx1MDAxOJXhzL1V91swi1x1MDAxMbxRSlx1MDAxYUyi4MWmh7RMq9nygzNgZkiqglMzXHUwMDFkvMJjXHUwMDFll/LXVzRcdTAwMWTp+16vY6Z7NlxcOKz3XHUwMDBmrCWukXC1d9Vap+n1XHUwMDA2Tn16jO9Vnb5b9eD2hMc1LNsu+OPJ2WFj4I7uzH3GzdMlkLnxpHfBhzZbjtlcdTAwMGa2XHUwMDAwT0d7brVm+ePJrVxir1wiWKF7XFxcdTAwMGZ3azJqn9xcdTAwMWXeXHUwMDFlO7V2o9+vU25dntvjk52n+b/DpXtgXHUwMDBlx8GuOlx1MDAwM9ueXHUwMDBlW07dXGb2aqdaVM9W5dSfVvXs8L5pXHUwMDA2p9Cwq4JyXHUwMDFjbl1otZgxNT+c6zlcdTAwMTNcdTAwMTPGXFwxxqTSNFxcQD9cdTAwMDNW6E9O21x1MDAwMEs2w01cdFx1MDAxNrE/Y6HhxVxm3Hr18S1YMkKV4lLD507nbcvpzC/d7tU64adMRn/8XHUwMDE5Z/Sa76J84VKOz6+Imde58jhzOFjY6CVWXHUwMDA2x1xiloWVfG70TFx1MDAxMIMjpSXFcFx1MDAwNKyaRSyfK0MquK+CPFx1MDAxYT6NMXy+NfS3XHUwMDE5+mG8of9cdTAwMTN+1NNcdTAwMWXTp5FcdTAwMWbz9s+ZXHUwMDA2r4Z5nP2rmU2bM3/CXHUwMDE5xpqplax/urpwnTPW6JujcPtcdTAwMWVPPTHmlLPfyd0hp1hptLPlzm4zfaBcbjvT435Ebt9GoVx1MDAxNb+aXGK0nl3MI6ooMlx1MDAxOKKUci4xUVx1MDAxYc9cdTAwMDFLvlx1MDAwNizKjCBIXGK4+2RcdTAwMGWaU2SRLbLeiKzi4iGEXHUwMDAwJdBgYlrHYEiI5Fx1MDAxMFx1MDAwMm9cdTAwMTGCY/neXHUwMDExJLTawFrh8vdcXHdmm3uOX7BcdTAwMWUmqEfPRlx1MDAwZqpdy1x1MDAwZfaFPzvDnm01g0vfqcFiTW9n9vp9XHUwMDBi2Nv0gK5Vr89GnVx1MDAxYZy0ajmmd7xI+Op5VtNyqvZV3KqrXHUwMDAzv3dp9lx1MDAxZtfte1x1MDAwM3P2fphHP4GCXHLCX0A5vVx1MDAxOarT8sEh19X2ffGo0rhcdTAwMTat0yjKTdu23P58+CTMoFx1MDAxMP5cdTAwMTBcdTAwMTdcdTAwMTBEpVxu7WByy1x1MDAxNDaAXHUwMDFjXHUwMDAyqXxcdTAwMDJ6XHUwMDA050xcdTAwMThcdTAwMTjgrVx07KmWjMfAXHUwMDFjXHUwMDBiQ3LgjZxcdTAwMTNcdTAwMDG7zpn4TWFcdTAwMGZ3uL37oG4uXHUwMDFit6mTYu7h+Pb0tDhcdTAwMTNE1udcdTAwMTfqi0ZcXJJcdTAwMTRxMYa9XCJcdTAwMWMzOVx1MDAwYowndyExnlx1MDAxZp26XHUwMDBijShcdTAwMThcbpbhXHUwMDExXHUwMDFmj3Gq87GVrjgpVMrnjtK316OrTtqLXHUwMDAyJsDgPFqoXHUwMDEx5EBaSSSR0GJcdTAwMGUtXHUwMDFhsIS4QpqBr2U4glx1MDAxNmRwSrhgmDPFXHUwMDAxLlpF4UKpwYRcdTAwMTBwds5cdTAwMDVikmzRsmG02G9HXHUwMDBi5FjBfsWiXHUwMDA10vIktIA3REBS3z89m1x1MDAwZbs9a57/hr99XHJNb/LH9Pe//4w9ejfZ3oNXxNLD80V20a72/XSv27V8uNB8sMhcYs/xq56fgm21nOb8nOnUXHUwMDEzZibv2vO83n3LrEaMXHUwMDA03jc/94JbuWvU273v+LtLXHUwMDFiXHUwMDE3uGRbOHt4UF/IrUg0uVx1MDAxM1x1MDAwNMH+IUSes22ukaEwglxchqLA0GK9XG54XHUwMDFjJFx1MDAwNaJwXHUwMDFjIaFbminfXHUwMDA0jotcdTAwMDCoKLBApERoqVu3slx1MDAxMbdy82avQmG7MFx1MDAwMfpcdTAwMTXL2CO58DRcdTAwMDRjRiRcdTAwMDQp9m/2KvH2XHUwMDFlvKKW/sndymXnvN3zLos33rjh7D20Sns0U1mY3lODS8omZVvOUJj8XHUwMDA1aFx1MDAxMZhcdTAwMWJMIWB6wP6J5uHslt4/jn5Mz7JwQS3ZtWitKISTuGJcdTAwMDDAKsm1KEhcYplcIvLdi1x1MDAwMS/AZVg6PttcdTAwMWRcdTAwMTL3uplj3pmHlPSvrYWiMFOGhOA71ySZhGBEXGZcdTAwMDKuWKvEglx1MDAxNyTKUovYOpdcdTAwMTRcdTAwMDaij0Xm31x1MDAxNFx1MDAxYWuz/ISC11JUXHUwMDFkIfB1XCI2qlx1MDAxMiFcdTAwMTJNX1CqXHT4t/c2/VxyXHUwMDA11Yj9XHUwMDA2r1x1MDAxOcv95EG0g45OrFx1MDAxM/O6NXKqRW/Uuped7OVcdTAwMTJNJmIohGS0r1xuPkNpNIvsaWtcdHjItKFcbq9cdTAwMTBtXHUwMDFiay390Zi8flx1MDAwZl9QWrz2XHLJp6BcbkcpczDHXHUwMDEya1lcdTAwMDKrgGXOkKaNt48ye9Wz7/2SgyupllVcdTAwMThkMselZv7d2kfxq4mAJqZ9XHUwMDE01MkkeFOgnJxcdTAwMDD/fFx1MDAwZVx1MDAxYU6TQEORgTVwXHUwMDEzLFx1MDAxNDB8Olx1MDAwYreNtY1+K9SUXHUwMDE3R1xyQUJcdTAwMTOGZ6tTM7BBiSRcdTAwMTEjQYFdXHUwMDEy/e4l4NBSn5ovmeuP0DF6JVx1MDAxNs13jGZcdTAwMTe9noZR2z7Z61+dmbqpi93Ty1x1MDAwM+rf+nzhYKg1RDZC59u6P2VGXFwxLZDe6ozeiPiD/bPiQao5KJdaebfV8HRcdTAwMWZcdTAwMWbxXHUwMDE1XHUwMDEw319cdTAwMWPxWDCBXGKabffP6IyETKxjY8zhbYTxlULlS5BXSs+UM99cdTAwMTTNXG6FY8ZcdTAwMWGlym1hvzFIfXfLKKu/L2z1XHUwMDE4YWlgXHUwMDFjSeR+XG6NKCGMgflBcNtcbo3ex9L9eEtfQmdcdTAwMDRcdTAwMGVccoN3QjRWaFx1MDAxN1OJXHJcdTAwMDFcdTAwMTDYP9GrtT1X44rjUaNYObx2XHUwMDBi9nlaZXKX45ubZnc5rrhGdMWvZlx1MDAwMa5cYrdVXHUwMDFikFx1MDAxZWmAXHUwMDBmXHUwMDAwSek5aMnXoLWVXHUwMDFhTUY3i63BXHUwMDEyUVx1MDAwNGlMqI5Xq6rkZijmXHUwMDE0dlx1MDAxOOj/2kssy5p5hDd+XHUwMDEwqdErXHUwMDEx7Fx1MDAxN0iNhmM3Wzh2K6wsL4vFdi83rND2gr1cYlx1MDAwMDoxNFx1MDAwZkrIXHUwMDFhuLycQzpXyNBYwP4/IT1cdTAwMDL0bTNicdxcdTAwMGZPbc/N1irswL5cdTAwMWJcdTAwMWRma5dcdTAwMDdd252JXCJrc1xmwzdXZINcdTAwMWNTSVx1MDAxYcc5dTRcdTAwMTBPvVx1MDAwNVEqcFx1MDAxNu/vLV6AS4vyvGxcdTAwMWTsy8rhQY+kUPfwwdGL9FwiXHUwMDAwK9jQXG7Iolx1MDAwMl5cdTAwMDGJuJzDijaArCNcdTAwMGV5lGJbpdEnwcr927tcdTAwMTewpVx1MDAxNDGi4moy4D1cdTAwMTPRXCJJ4Fx1MDAxN9H6azIrx9at0mj1blx1MDAwNuqmMpVsRp96jYtDWVx1MDAxY1x1MDAxNsxcdTAwMGI7poBcdTAwMTPnV1x1MDAwNJBtISBV4UzPNiV+Ko1cdTAwMDRhkOkqQfVWafRJ3Mro7W6FXHUwMDAwkCmS8ZRdRVRcdTAwMDJTt8KokFx1MDAxYVxi/7vXfTboVn4jqVFnf3DVPKyj/ez3h7a1m1x1MDAxZY28fIwwOpneY0lcdTAwMTFccr5kXHUwMDEyqzWCXHUwMDFjXHUwMDFmU1x1MDAwNsmh3GqNPolvXHUwMDE5v9m3MNgmLLmIZSwz5Zx5aTSSUlxurdYuNVojvWd7Od483H246/OBTpWH+dyRPlgsXGYzaVCIszwqKVxitEaIcC5ZYsVrqzWajG624vXw9qhcbjFcdTAwMDPiXHUwMDAz1bG6XHUwMDAzndhAXHUwMDE1lFx1MDAxMCDs+N/K1f/lUiNeuFx1MDAxN81r/y6XXHUwMDE5V29u+ubDwV3lMOpcdTAwMTWS+0zYYFxiXHUwMDE4XHUwMDA1mm8z0YlAkcFcdTAwMTF8Kzj65Vx1MDAwZeFcdTAwMGWhJWrgmFxuXHUwMDA2QU/GQf9F7T5AX1x1MDAwM89cXCnsTa95qT5SrnRauDOz5+lBgVx1MDAxY5X7ab/suOfv1keKX01cdTAwMDQ9sX0kbGhcdLeOSYViRUcvgGcrPNo0evDi6NFcdTAwMWHySoJYXHUwMDFjZVx1MDAxNCSRMlx1MDAwMs1cdTAwMTRqNeRstHv0MVRHr4SlzauOblx1MDAwNu2TTjt7PbpcdTAwMTiOs+lGeaw9cbNwXFxUjFx1MDAxYlx1MDAxMlx1MDAxMkhcdTAwMWSvOlwi0amt6ujn1i5cdTAwMDH3lLpPj91WpZFy2/S2fVa8z6Zrq8CdLFx1MDAwZXdIgiDbXHUwMDExsaIjmazIXHUwMDA3dDKyojr3JbzroESxnmA2pqVxpXVz5o3OT3Xq5KDafriI+epWkslLbHAsXHUwMDA0ilNcdTAwMWNBrFx1MDAxM5BcdTAwMWUjLbaKo/ezcvp2yVx1MDAxMWFBzYyxWMlcdTAwMTEmiep0SCAxZ4Kt1P9cXI0p7mdoqVwiMntyUGh6dqE7XHUwMDE4XHUwMDFmda6WY4prXHUwMDA0V/xqXHUwMDE2YIpKUciwNNZPgqP5h1x1MDAxYonXoLVVXHUwMDFjTUY3jC22hFRdMFx1MDAxMTi7uO90aZXcXHUwMDE1ZVx1MDAxY2NcdTAwMDHUYO3flF7WzCOc8YMojl5cdGC/QHHUuS1ao4umy4fS9kx+Rlx1MDAwNu6Zs2BLQklpXHUwMDA0iYRIXHUwMDE0XHUwMDFjcYHA+z5cdTAwMDE9gvNtR2Jx2O/dP9By5ip/I3t+umSbNyVW3JvtSKzNL/BFY25iYVZcdEZcdTAwMTgnKEHlm9zu5ECl8KrfXGL7RWHx4aGePzVcdTAwMGJnWpZcbo5dlmORyS2kOVJSXHUwMDE4sFx1MDAxNslcdTAwMTMkR8qAXHQ+OWArOfo0aFx1MDAxMWtoY0gqIHmOXHUwMDA1XHUwMDBiTuxiQLYtwVxi3lx1MDAxYinT4a3eaPWWhuvmMdN5du2YzfuU+1DWjrfQM1x1MDAxNTSBOyEhxUmSXHUwMDFiXHUwMDExoWBcdTAwMDbjrdzo87hcdTAwMTT5dpeCg0fLXG6sYkW/UXHjjOiXa7CI9T+N9Fx1MDAwM7mV30hvRKs1+6wm7Vx1MDAxY3+gZrbczfauLmKeypBA7oVcdTAwMDGMm6hcdTAwMDS5XHUwMDEx5OhUXHTBqdzKjT6Pb0l4KP5cdTAwMTK+hUPGR1x1MDAxOUTlWL5cIl94Vj6VRNLZrODjkXvnkl/U8qxTuT3Pe6P0XHUwMDEwp+l4b6FAjLBcdTAwMDFcdTAwMWUj7lx1MDAxOSZcdTAwMWOmhFx1MDAwNCbHXHUwMDEzXHUwMDBiXlvB0WR0w1x1MDAwNS/9ZttcdTAwMTecXHUwMDA0j3qLrYPxZK1cdTAwMWTE4YCCYflx6mBbxdFcdTAwMTJhNN++XHUwMDE5mde7Pv0+bqbvZH2v3ZnN+15rM1x0XHUwMDBlmb1cdTAwMTAsVnBcdTAwMDT/5v9Dma3g6Fx1MDAxNzmEvXiHXHUwMDEwV1x1MDAwMVx1MDAwN1x1MDAxMkRcdTAwMTlcdTAwMDEvXHUwMDFmg3zJXHUwMDEzK1pBo1x1MDAwM7LU1Vxu4NMrXqqJlC+eXHUwMDE0L8+PjqoqdVnc37uosvGg9G5NpPjVRKBcdTAwMTPTRFxuqmVSgcNNUlx1MDAxYr2AnK3aaNPQSS2h1ePBc/20jH08mMSJhJFAqqZcdTAwMDTWXHUwMDFmJ1x1MDAxN/1YgqNXotJaXHUwMDA1R1+erGOn6rpcdTAwMDVcdTAwMWbu55Q37VxmLfM+lVxmhy9PniGAgzmhWz++/Pg/Of7y+yJ9AppDUAppDUAppDU \ No newline at end of file diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md new file mode 100644 index 0000000000..f94f295feb --- /dev/null +++ b/guides/deployment/microservices.md @@ -0,0 +1,1099 @@ +--- +synopsis: > + A guide on deploying SAP Cloud Application Programming Model (CAP) applications as microservices to the SAP BTP Cloud Foundry environment. +--- + +# Microservices with CAP + +A comprehensive guide on deploying your CAP application as microservices. + +[[toc]] + + +## Create a Solution Monorepo + +Assumed we want to create a composite application consisting of two or more micro services, each living in a separate GitHub repository, for example: + +- https://github.com/capire/bookstore +- https://github.com/capire/reviews +- https://github.com/capire/orders + +With some additional repos, used as dependencies in the same manner, like: + +- https://github.com/capire/common +- https://github.com/capire/bookshop +- https://github.com/capire/data-viewer + +This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[npm workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques... + +1. Create a new monorepo root directory using `npm` workspaces: + + ```sh + mkdir capire + cd capire + echo "{\"name\":\"@capire/samples\",\"workspaces\":[\"*\"]}" > package.json + ``` + +2. Add the previously mentioned projects as `git` submodules: + + ```sh + git init + git submodule add https://github.com/capire/bookstore + git submodule add https://github.com/capire/reviews + git submodule add https://github.com/capire/orders + git submodule add https://github.com/capire/common + git submodule add https://github.com/capire/bookshop + git submodule add https://github.com/capire/data-viewer + git submodule update --init + ``` + + Add a .gitignore + ```txt + node_modules + gen + ``` + > The outcome of this looks and behaves exactly as the monorepo layout in *[cap/samples](https://github.com/sap-samples/cloud-cap-samples)*, so we can exercise the subsequent steps in there... + +3. Test-drive locally as usual + ```sh + npm install + ``` + + ```sh + cds w bookshop + ``` + + ```sh + cds w bookstore + ``` + + +::: details Other project structures + +The project structure used here is as follows: + +```txt +/ +β”œβ”€ bookstore/ +β”œβ”€ orders/ +β”œβ”€ reviews/ +β”œβ”€ ... +└─ package.json +``` + +The individual services (`bookstore`, `reviews`, `orders`) can be + * folders, committed directly to the root project + * git submodules + +Links between the projects are established using npm dependencies. +Since the root project defines workspaces, these dependencies are also found locally without the need for publishing or linking. +When one of the projects is cloned in isolation, it is still possible to fetch dependencies to other modules via the npm registry. + +::: + +## Using a Shared Database + +If you have multiple CAP applications relying on the same domain model or want to split up a monolithic CAP application **on the service level only while still sharing the underlying database layer**, you can deploy your model to a single database and then share it across applications. + +In the following steps, we create an additional project to easily collect the relevant models from these projects, and act as a vehicle to deploy these models to SAP HANA in a controlled way. + +::: details Evaluation + +The advantages are as follows: + - **Query Performance:** Complex queries are executed much faster, for example $expand to an entity on another microservice (compared to calls across services with own data persistencies) + - **Independent Scalability** of application runtimes (compared to a monolithic application) + + Disadvantages: + - Accessing data directly (without an API) means any changes in the data model affect all applications directly + - every change in one of the services either requires + - a redeployment of all microservices involved + - a logic to decide which microservices need redeployment to avoid inconsistencies + - violates 12 factors concept + +::: + +### Add a project for shared database + +1. Add another `cds` project to collect the models from these projects: + + ```sh + cds init shared-db --add hana + cd shared-db + ``` + + ```sh + npm add @capire/bookstore + npm add @capire/reviews + npm add @capire/orders + ``` + + > Note how *npm workspaces* allows us to use the package names of the projects, and nicely creates symlinks in *node_modules* accordingly. + +2. Add a `db/schema.cds` file as a mashup to actually collect the models: + + ```sh + code db/schema.cds + ``` + + ```cds + using from '@capire/bookstore'; + using from '@capire/reviews'; + using from '@capire/orders'; + ``` + + > Note: the `using` directives refer to `index.cds` files existing in the target packages. Your projects may have different entry points. + +::: details Try it out + +With that we're basically done with the setup of the collector project. In sum, it's just another CAP project with some cds models in it, which we can handle as usual. We can test whether it all works as expected, for example, we can test-compile and test-deploy it to sqlite and hana, build it, and deploy it to the cloud as usual: + +```sh +cds db -2 sql +``` +```sh +cds db -2 hana +``` + +```sh +cds deploy -2 sqlite +``` +```sh +cds build --for hana +``` + +> Note: As we can see in the output for `cds deploy` and `cds build`, it also correctly collects and adds all initial data from enclosed `.csv` files. +::: + +::: details Other project structures + +The project structure used here is as follows: + +```txt +/ +β”œβ”€ bookstore/ +β”œβ”€ reviews/ +β”œβ”€ orders/ +└─ shared-db/ + └─ db/ + └─ schema.cds # references schemas of bookstore, reviews, orders + └─ package.json # npm dependencies to bookstore, reviews, orders +β”œβ”€ ... +└─ package.json +``` + +The `shared-db` module is simply another CAP project, with only db content. The dependencies are installed via npm, so it is still possible to install via an npm registry if used outside of the monorepo setup. + +The db model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all npm workspaces. + +::: + +### Deployment as separate mta + +In a setup with multiple deployment units, we can add the `shared-db` project as its own mta deployment: + +```sh +cds add mta +``` + +This adds everything necessary for a full CAP application. +Since we only want the database and database deployment, remove everything else like the srv module and destination and messaging resources: + +```yaml +_schema-version: 3.3.0 +ID: shared-db +version: 1.0.0 +description: "A simple CAP project." +parameters: + enable-parallel-deployments: true +build-parameters: + before-all: + - builder: custom + commands: + - npm ci + - npx cds build --production # [!code --] + - npx cds build --production --for hana # [!code ++] +modules: + - name: shared-db-srv # [!code --] + type: nodejs # [!code --] + path: gen/srv # [!code --] + parameters: # [!code --] + instances: 1 # [!code --] + buildpack: nodejs_buildpack # [!code --] + build-parameters: # [!code --] + builder: npm-ci # [!code --] + provides: # [!code --] + - name: srv-api # [!code --] + properties: # [!code --] + srv-url: ${default-url} # [!code --] + requires: # [!code --] + - name: shared-db-destination # [!code --] + - name: shared-db-messaging # [!code --] + - name: shared-db-db # [!code --] + + - name: shared-db-db-deployer + type: hdb + path: gen/db + parameters: + buildpack: nodejs_buildpack + requires: + - name: shared-db-db + +resources: + - name: shared-db-destination # [!code --] + type: org.cloudfoundry.managed-service # [!code --] + parameters: # [!code --] + service: destination # [!code --] + service-plan: lite # [!code --] + - name: shared-db-messaging # [!code --] + type: org.cloudfoundry.managed-service # [!code --] + parameters: # [!code --] + service: enterprise-messaging # [!code --] + service-plan: default # [!code --] + path: ./event-mesh.json # [!code --] + - name: shared-db-db + type: com.sap.xs.hdi-container + parameters: + service: hana + service-plan: hdi-shared +``` + + + + +#### Binding to shared database + +The only thing left to care about is to ensure all 3+1 projects are bound and connected to the same database at deployment, subscription, and runtime. + +Configure the mta.yaml of the other apps to bind to the existing shared database, for example, in the reviews module: + +```yaml [reviews/mta.yaml] +... +modules: + ... + + - name: reviews-db-deployer # [!code --] + type: hdb # [!code --] + path: gen/db # [!code --] + parameters: # [!code --] + buildpack: nodejs_buildpack # [!code --] + requires: # [!code --] + - name: reviews-db # [!code --] + +resources: + ... + - name: reviews-db + type: com.sap.xs.hdi-container # [!code --] + type: org.cloudfoundry.existing-service # [!code ++] + parameters: + service: hana # [!code --] + service-plan: hdi-shared # [!code --] + service-name: shared-db-db # [!code ++] +``` + + + +#### Subsequent updates + +- TODO... +- Whenever one of the projects has changes affecting the database, that triggers a new deployment of the `shared-db` project +- `git submodules` gives you control of which versions to pull, for example by `git branches` or `git tags` +- Ensure to first deploy `shared-db` before deploying the others + + + +## All-in-one Deployment + +Here we go on with our guide how to deploy all 3+1 projects at once with a common `mta.yaml` + +![component diagram with synchronous and event communication for orders](./assets/microservices/bookstore.excalidraw.svg) + +[cap-samples](https://github.com/SAP-samples/cloud-cap-samples?tab=readme-ov-file#welcome-to-capsamples) already has an all-in-one deployment implemented. Similar steps are necessary to convert projects with multiple CAP applications into a shared database deployment. + +### Deployment Descriptor + +Add initial multitarget application configuration for deployment to Cloud Foundry: + +```shell +cds add mta +``` + +[Learn more about **how to deploy to Cloud Foundry**.](../deployment/to-cf){.learn-more} + +### Database + +Add initial database configuration using the command: + +```shell +cds add hana +``` + +Delete the generated _db_ folder as we don't need it on the root level: + +```shell +rm -r db +``` + +Update the `db-deployer` path to use our `shared-db` project [created previously](#using-a-shared-database): + +::: code-group +```yaml [mta.yaml] + - name: samples-db-deployer + path: gen/db # [!code --] + path: shared-db/gen/db # [!code ++] +``` +::: + +Add build command for generation of the database artifacts: + +::: code-group +```yaml [mta.yaml] +build-parameters: + before-all: + - builder: custom + commands: + - npm ci + - npx cds build --production # [!code --] + - npx cds build ./shared-db --for hana --production # [!code ++] +``` +::: + + +::: info `cds build --ws` +If the CDS models of every npm workspace contained in the monorepo should be considered, then instead of creating this `shared-db` folder, you can also use: +```shell +cds build --for hana --production --ws +``` +The `--ws` aggregates all models in the npm workspaces. + +In this walkthrough, we only include a subset of the CDS models in the deployment. +::: + + +::: details Configure each app for cloud readiness +The preceding steps added configuration only to the workspace root. + +Additionally add database configuration to each module that we want to deploy - bookstore, orders, and reviews: + +```shell +npm i @cap-js/hana --workspace bookstore +npm i @cap-js/hana --workspace orders +npm i @cap-js/hana --workspace reviews +``` +::: + + +### Applications + +Replace the mta module for samples-srv with versions for each CAP service and adjust `name`, `path`, and `provides[0].name` to match the module name. Also change the `npm-ci` builder to the `npm` builder. + +::: code-group +```yaml [mta.yaml] +modules: + - name: bookstore-srv # [!code focus] + type: nodejs + path: bookstore/gen/srv # [!code focus] + parameters: + instances: 1 + buildpack: nodejs_buildpack + build-parameters: + builder: npm # [!code focus] + provides: # [!code focus] + - name: bookstore-api # [!code focus] + properties: + srv-url: ${default-url} + requires: + - name: samples-db + - name: samples-auth + - name: samples-messaging + - name: samples-destination + + - name: orders-srv # [!code focus] + type: nodejs + path: orders/gen/srv # [!code focus] + parameters: + instances: 1 + buildpack: nodejs_buildpack + build-parameters: + builder: npm # [!code focus] + provides: # [!code focus] + - name: orders-api # [!code focus] + properties: + srv-url: ${default-url} + requires: + - name: samples-db + - name: samples-auth + - name: samples-messaging + - name: samples-destination + + - name: reviews-srv # [!code focus] + type: nodejs + path: reviews/gen/srv # [!code focus] + parameters: + instances: 1 + buildpack: nodejs_buildpack + build-parameters: + builder: npm # [!code focus] + provides: # [!code focus] + - name: reviews-api # [!code focus] + properties: + srv-url: ${default-url} + requires: + - name: samples-db + - name: samples-auth + - name: samples-messaging + - name: samples-destination +... +``` +::: + +Add build commands for each module to be deployed: + +::: code-group +```yaml [mta.yaml] +build-parameters: + before-all: + - builder: custom + commands: + - npm ci + - npx cds build ./shared-db --for hana --production + - npx cds build ./orders --for nodejs --production --ws-pack # [!code ++] + - npx cds build ./reviews --for nodejs --production # [!code ++] + - npx cds build ./bookstore --for nodejs --production --ws-pack # [!code ++] +``` +::: + +::: info --ws-pack +Note that we use the *--ws-pack* option for some modules. It's important for node modules referencing other repository-local node modules. +::: + + +### Authentication + +Add [security configuration](../security/authorization#xsuaa-configuration) using the command: + +```shell +cds add xsuaa --for production +``` + +Add the admin role + +::: code-group +```json [xs-security.json] +{ + "scopes": [ + { // [!code ++] + "name": "$XSAPPNAME.admin", // [!code ++] + "description": "admin" // [!code ++] + } // [!code ++] + ], + "role-templates": [ + { // [!code ++] + "name": "admin", // [!code ++] + "scope-references": [ // [!code ++] + "$XSAPPNAME.admin" // [!code ++] + ], // [!code ++] + "description": "cap samples multi-service shared-db" // [!code ++] + } // [!code ++] + ] +} +``` +::: + +::: details Configure each app for cloud readiness +Add npm dependency `@sap/xssec`: + +```shell +npm i @sap/xssec --workspace bookstore +npm i @sap/xssec --workspace orders +npm i @sap/xssec --workspace reviews +``` +::: + +### Messaging + +The messaging service is used to organize asynchronous communication between the CAP services. + +```shell +cds add enterprise-messaging +``` + +Relax the publish filters for the message topics + +::: code-group +```json [event-mesh.json] +{ + ... + "rules": { + "topicRules": { + "publishFilter": [ + "${namespace}/*" // [!code --] + "*" // [!code ++] + ], + "subscribeFilter": [ + "*" + ] + }, + "queueRules": { + "publishFilter": [ + "${namespace}/*" + ], + "subscribeFilter": [ + "${namespace}/*" + ] + } + } +} +``` +::: + +Parameterize the properties `emname` and `namespace`: + +::: code-group +```json [event-mesh.json] + { + "emname": "samples-emname", // [!code --] + "version": "1.1.0", + "namespace": "default/samples/1", // [!code --] + ... + } +``` +::: +::: code-group +```yaml [mta.yaml] +resources: + - name: samples-messaging + type: org.cloudfoundry.managed-service + parameters: + service: enterprise-messaging + service-plan: default + path: ./event-mesh.json + config: # [!code ++] + emname: bookstore-${org}-${space} # [!code ++] + namespace: cap/samples/${space} # [!code ++] +``` +::: + +Add the *processed-after* property, so that the xsuaa instance is created after the messaging: + +::: code-group +```yaml [mta.yaml] +resources: + ... + - name: samples-auth + processed-after: #[!code ++] + - samples-messaging #[!code ++] +``` +::: + +::: details Configure each app for cloud readiness +Enable messaging for the modules that use it: + +::: code-group +```json [bookstore/package.json] +{ + "cds": { + "requires": { + "messaging": true // [!code ++] + } + } +} +``` +```json [orders/package.json] +{ + "cds": { + "requires": { + "messaging": true // [!code ++] + } + } +} +``` + +::: + + +### Destinations + +Add [destination configuration](https://cap.cloud.sap/docs/guides/using-services#using-destinations) for connectivity between the apps: + +```shell +cds add destination +``` + +Add destinations that point to the API endpoints of the orders and reviews applications: + +::: code-group +```yaml [mta.yaml] +modules: +... + - name: destination-content + type: com.sap.application.content + requires: + - name: orders-api + - name: reviews-api + - name: bookstore-api + - name: samples-auth + parameters: + service-key: + name: xsuaa_service-key + - name: samples-destination + parameters: + content-target: true + build-parameters: + no-source: true + parameters: + content: + instance: + existing_destinations_policy: update + destinations: + - Name: orders-dest + URL: ~{orders-api/srv-url} + Authentication: OAuth2ClientCredentials + TokenServiceInstanceName: samples-auth + TokenServiceKeyName: xsuaa_service-key + - Name: reviews-dest + URL: ~{reviews-api/srv-url} + Authentication: OAuth2ClientCredentials + TokenServiceInstanceName: samples-auth + TokenServiceKeyName: xsuaa_service-key +... +``` +::: + +Use the destinations in the bookstore application: + +::: code-group +```yaml [mta.yaml] +modules: + - name: bookstore-srv + ... + properties: # [!code ++] + cds_requires_ReviewsService_credentials: {"destination": "reviews-dest","path": "/reviews"} # [!code ++] + cds_requires_OrdersService_credentials: {"destination": "orders-dest","path": "/odata/v4/orders"} # [!code ++] +``` +::: + +::: details Configure each app for cloud readiness + +Add `@sap-cloud-sdk/http-client` and `@sap-cloud-sdk/resilience` for each module utilizing the destinations: + +```shell +npm i @sap-cloud-sdk/http-client --workspace bookstore +npm i @sap-cloud-sdk/resilience --workspace bookstore +``` +::: + +### Approuter + +Add [approuter configuration](../deployment/to-cf#add-app-router) using the command: + +```shell +cds add approuter +``` + +The approuter serves the UIs and acts as a proxy for requests toward the different apps. + +Since the approuter folder is only necessary for deployment, we move it into a `.deploy` folder. + +```shell +mkdir .deploy +mv app/router .deploy/app-router +``` + +::: code-group +```yaml +modules: + ... + - name: samples + type: approuter.nodejs + path: app/router # [!code --] + path: .deploy/app-router # [!code ++] + ... +``` +::: + +#### Static Content + +The approuter can serve static content. Since our UIs are located in different npm workspaces, we create symbolic links to them as an easy way to deploy them as part of the approuter. + +```shell +mkdir .deploy/app-router/resources +cd .deploy/app-router/resources +ln -s ../../../bookshop/app/vue bookshop +ln -s ../../../orders/app/orders orders +ln -s ../../../reviews/app/vue reviews +cd ../../.. +``` + +::: warning Simplified Setup +This is a simplified setup which deploys the static content as part of the approuter. +See [Deploy to Cloud Foundry](./to-cf#add-ui) for a productive UI setup. +::: + +#### Configuration + +Add destinations for each app url: + +::: code-group +```yaml [mta.yaml] +modules: + ... + - name: samples + type: approuter.nodejs + .... + requires: + - name: service-api # [!code --] + group: destinations # [!code --] + properties: # [!code --] + name: service-api # [!code --] + url: ~{srv-url} # [!code --] + forwardAuthToken: true # [!code --] + - name: orders-api # [!code ++] + group: destinations # [!code ++] + properties: # [!code ++] + name: orders-api # [!code ++] + url: ~{srv-url} # [!code ++] + forwardAuthToken: true # [!code ++] + - name: reviews-api # [!code ++] + group: destinations # [!code ++] + properties: # [!code ++] + name: reviews-api # [!code ++] + url: ~{srv-url} # [!code ++] + forwardAuthToken: true # [!code ++] + - name: bookstore-api # [!code ++] + group: destinations # [!code ++] + properties: # [!code ++] + name: bookstore-api # [!code ++] + url: ~{srv-url} # [!code ++] + forwardAuthToken: true # [!code ++] +``` +::: + +The xs-app.json file describes how to forward incoming request to the API endpoint / OData services and is located in the app/router folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service. + +::: code-group +```json [.deploy/app-router/xs-app.json] +{ + "routes": [ + { // [!code --] + "source": "^/(.*)$", // [!code --] + "target": "$1", // [!code --] + "destination": "srv-api", // [!code --] + "csrfProtection": true // [!code --] + } // [!code --] + { // [!code ++] + "source": "^/admin/(.*)$", // [!code ++] + "target": "/admin/$1", // [!code ++] + "destination": "bookstore-api", // [!code ++] + "csrfProtection": true // [!code ++] + }, // [!code ++] + { // [!code ++] + "source": "^/browse/(.*)$", // [!code ++] + "target": "/browse/$1", // [!code ++] + "destination": "bookstore-api", // [!code ++] + "csrfProtection": true // [!code ++] + }, // [!code ++] + { // [!code ++] + "source": "^/user/(.*)$", // [!code ++] + "target": "/user/$1", // [!code ++] + "destination": "bookstore-api", // [!code ++] + "csrfProtection": true // [!code ++] + }, // [!code ++] + { // [!code ++] + "source": "^/odata/v4/orders/(.*)$", // [!code ++] + "target": "/odata/v4/orders/$1", // [!code ++] + "destination": "orders-api", // [!code ++] + "csrfProtection": true // [!code ++] + }, // [!code ++] + { // [!code ++] + "source": "^/reviews/(.*)$", // [!code ++] + "target": "/reviews/$1", // [!code ++] + "destination": "reviews-api", // [!code ++] + "csrfProtection": true // [!code ++] + } // [!code ++] + ] +} +``` +::: + +Add routes for static content: + +::: code-group +```json [.deploy/app-router/xs-app.json] +{ + "routes": [ + ... + { // [!code ++] + "source": "^/app/(.*)$", // [!code ++] + "target": "$1", // [!code ++] + "localDir": "resources", // [!code ++] + "cacheControl": "no-cache, no-store, must-revalidate" // [!code ++] + } // [!code ++] + ] +} +``` +::: + +The `/app/*` route exposes our UIs, so bookstore is available as `/app/bookstore`, orders as `/app/orders` and reviews as `/app/reviews`. +Due to the `/app` prefix, make sure that static resources are accessed via relative paths inside the UIs. + +Add the `bookshop/index.html` as initial page when visiting the app: + +::: code-group +```json [.deploy/app-router/xs-app.json] +{ + "welcomeFile": "app/bookshop/index.html", // [!code ++] + "routes": { + ... + } +} +``` +::: + +Additionally, the welcomeFile is important for deployed Vue UIs as they obtain CSRF-Tokens via this url. + + +### Deploy + +In order to build, deploy, and undeploy easily, add these `npm` scripts: + +::: code-group +```json [package.json] + "scripts": { + "build": "mbt build -t gen --mtar mta.tar", // [!code ++] + "deploy": "cf deploy gen/mta.tar", // [!code ++] + "undeploy": "cf undeploy capire.samples --delete-services --delete-service-keys" // [!code ++] + } +``` +::: + +Before deploying you need to log in to Cloud Foundry. + +To locally build the apps, run + +```shell +npm run build +``` + +To deploy the built artifacts to Cloud Foundry, run + +```shell +npm run deploy +``` + +Once the app is deployed, you can get the url of the approuter via + +```shell +cf apps # [!code focus] + +name requested state processes routes +bookstore-srv started web:1/1 my-capire-bookstore-srv.cfapps.us10-001.hana.ondemand.com +orders-srv started web:1/1 my-capire-orders-srv.cfapps.us10-001.hana.ondemand.com +reviews-srv started web:1/1 my-capire-reviews-srv.cfapps.us10-001.hana.ondemand.com +samples started web:1/1 my-capire-samples.cfapps.us10-001.hana.ondemand.com # [!code focus] +samples-db-deployer stopped web:0/1 +``` + +You can then navigate to this url and the corresponding apps +```text +/ -> bookshop +/app/bookshop -> bookshop +/app/orders -> orders +/app/reviews -> reviews +``` + + +## Late-Cut Microservices + +Microservices have been attributed with a multitude of benefits like +- granular scalability, +- deployment agility, +- distributed development, and so on. + +While these benefits exist, they are accompanied by complexity and performance losses. True microservices each constitute their own deployment unit with their own database. The benefits attributed to microservices can be broken down into multiple aspects. + +| Aspect | Benefits | Drawbacks | +| ---------- | -------- | --------- | +| App Instances | Scalability, Resilience | Requires Statelessness | +| Modules | Distributed Development, Structure |Β | +| Applications | Independent Scalability, Fault Tolerance | Communication OverheadΒ | +| Deployment Units | Faster Deploy Times, Independent Deployments | Configuration Complexity | +| Databases | Depends | Data Consistency, Fragmentation | + +### Flexibility in Deployments + +Instead of just choosing between a monolith and microservices, these aspects can be combined into an architecture that fits the specific product. + +Since each cut not only has benefits, but also drawbacks, it is important to choose which benefits actually help the overall product and which drawbacks can be accepted. + +![Multiple deployment units - one contains the UIs, one contains shared service instances, one contains a shared db, two each contain an app connected to the shared db, one contains a db and an app, which is also connected to the shared db](./assets/microservices/complex.excalidraw.svg) + +### A Late Cut + +When developing a product it may initially not be apparent where the boundaries are. + +Keeping this in mind, an app can be developed as a modular application with use case specific CAP services. +It can first be deployed as a [monolith / modulith](#monolith-or-microservice). Once the boundaries are clear, it can then be split into multiple applications. + +Generally, the semantic separation and structure can be enforced using modules. The deployment configuration is then an independent step on top. In this way, the same application can be deployed as a monolith, as microservices with shared db, as true microservices, or a combination of these, just via configuration change. + +![Modules which can be arranged in different deploy configurations, e.g. as a monolith (bookshop, reviews, orders), as two apps (bookshop, orders in one, reviews in the other), etc.](./assets/microservices/late-cut.excalidraw.svg) + +### Best Practices + +* Prefer a late cut +* Stay flexible in where to cut +* Prefer staying loosely coupled β†’ e.g. ReviewsService β†’ reviewed events β†’ UPDATE avg ratings +* Leverage db-level integration selectively β†’ Prefer referring to (public) service entities, not (private) db entities + +## Appendix + +### Monolith or Microservice + +A monolith is a single deployment unit with a single application. This is very convenient, because every part of the app is accessible in memory. + +![A monolith](./assets/microservices/monolith.excalidraw.svg) + +A modulith, even though the app is separated into multiple CAP services inside multiple modules, can still be deployed as a single monolithic application. +This combines the benefit of a clear structure and distributed development while keeping a simple deployment. + +![A single app containing the modules bookshop, reviews and orders](./assets/microservices/modulith.excalidraw.svg) + +True microservices each consist of their own deployment unit with their own application and their own database. +Meaning that they are truly independent of each other. And it works well if they actually are independent. + +![A simplified microservices view - three deployment units, each with one app and one database](./assets/microservices/true-microservices.excalidraw.svg) + +The above is a simplified view. In an actual microservice deployment, there are typically shared service instances and wiring needs to be provided so that apps can talk to each other, directly or via events. +If the microservices are not cut well, the communication overhead leads to high performance losses and often the need for data replication or caching. + +![A more complete microservices view - two deployment units with one app, one db and some UIs each, one deployment unit for shared service instances](./assets/microservices/true-microservices-full.excalidraw.svg) + + +### Application Instances + +Having only a single virtual machine or container, the application can only be scaled vertically by increasing the cpu and memory resources. This typically has an upper limit and requires a restart when scaling. + +To improve scalability, we can start multiple instances of the same application. + +Benefits: +- Near unlimited scaling +- No downtimes when scaling +- Better resilience against failures in single app instances + +Requirement: +- The app needs to be stateless, state needs to be persisted + +Multiple app instances can be used both for monoliths and microservices. + +![A single app with multiple application instances](./assets/microservices/app-instances.excalidraw.svg) + +### Modules + +When many developers work on an app, a distribution of work is necessary. Nowadays this distribution is often reached by each team working on one or multiple microservices. +Also, microservices are potentially cut by which team is developing them. + +Instead, developers can work on single modules, which are later deployed and run as a single app... or as multiple apps. But this choice is then independent of who is developing the module. + +Benefits: +- Distributed Development +- Clear Structure + +![Modules: bookshop containing AdminService and CatalogService, reviews containing ReviewsService, orders containing OrdersService, common](./assets/microservices/modules.excalidraw.svg) + +### Multiple Applications + +As described above, [application instances](#application-instances) already have near unlimited scaling, even for a monolith. So why would you want multiple apps? + +Benefits: +- Resource Separation +- Independent Scaling +- Fault Tolerance + +Drawbacks: +- Latency for synchronous calls between dependent apps + +![Three applications connected to the same database, two of the applications communicate](./assets/microservices/multiple-apps.excalidraw.svg) + +#### Resource Separation + +One part of an application may do highly critical background processing, while another handles incoming requests. +The incoming requests take cpu cycles and consume memory, which should rather be used for the background processing. +To make sure that there are always enough resources for specific tasks, they can be split into their own app. + +#### Independent Scaling + +Similar to resource separation, different parts of the app may have different requirements and profiles for scaling. +For some parts, a 100% cpu utilization over an extended period is accepted for efficiency, while request handling apps need spare resources to handle user requests with low latency. + +#### Fault Tolerance + +While app instances already provide some resilience, there are failure classes (e.g. bugs) which affect each app instance. + +Separating functionality into different apps means that when one app experiences issues, the functionality of the other apps is still available. +In the bookstore example, while reviews may be down, orders may still be possible. + +This benefit is null for apps with synchronous dependencies on each other. If A depends on synchronous calls to B, then if B is down, A is down as well. + +### Multiple Deployment Units + +With multiple apps, you can still deploy them together as one unit, for example as part of a multitarget application archive. +Once an application grows bigger, this takes a significant amount of time. +Deployments can then be split up either by type (e.g. deploying UIs separately) or horizontally (e.g. deploying each app via its own deployment unit). + +Benefits: +- Faster individual deploy times +- Independent deployments + +Drawbacks: +- Coordination between deployment units for updates with dependencies +- Configuration wiring to connect systems across deployment units + +![One deployment unit for UIs and one deployment unit for apps, db etc.](./assets/microservices/multiple-deployment-units.excalidraw.svg) + + +With a single deployment unit, when a fix for one part needs to be deployed, the risk of redeploying the rest of the application needs to be considered. +For example, there may already been changes to other parts of the app in the same code line. +A restart / rolling restart may also lead to higher resource consumption due to startup activities and thus slightly degrade the performance during this time. + +Being able to deploy apps or other resources independently reduces the risk when a single part of the system needs to be updated. +The update decision needs less coordination and can be made by the team responsible for this part of the system. + +Coordination is still necessary when deploying changes that affect the whole system, for example when a feature needs implementations in multiple apps. + +### Multiple Databases + +Here we need to differentiate between two scenarios: +- Using multiple types of databases +- Using multiple databases of the same type + +A polyglot persistence can be used when the app has different requirements for the types of data it needs to store. +For example, there may be a large amount of large files that can be stored in a document store, while corresponding administrative data is stored in a relational database. + +Benefits: +- Use suitable technology for different use cases + + +In contrast, using multiple databases of the same type may be suggested for +- Scalability +- Resource Separation +- Tenant Isolation +- Semantic Separation + +Scalability and resource separation need multiple database instances. Tenant isolation and semantic separation could also be achieved through multiple schemas or containers inside the same database instance. + + + +Drawbacks: +- Data consistency across databases +- Collecting data across databases + +![A single application connected to multiple databases](./assets/microservices/multiple-dbs.excalidraw.svg) + +#### Data Federation + +When data is distributed across multiple databases, strategies may be necessary to combine data from multiple sources. + +- Fetching on-demand + - Caching +- HANA synonyms +- Data Replication diff --git a/menu.md b/menu.md index e373bfe69b..f6bfed8e36 100644 --- a/menu.md +++ b/menu.md @@ -91,7 +91,7 @@ ### [Deploy to Cloud Foundry](../guides/deployment/to-cf) ### [Deploy to Kyma/K8s](../guides/deployment/to-kyma) - ### [Deploy to Shared DB](../guides/deployment/shared-db) + ### [Microservices with CAP](../guides/deployment/microservices) ### [Deploy with Confidence](../guides/deployment/dwc) ### [Deploy with CI/CD](../guides/deployment/cicd) ### [Custom Builds](../guides/deployment/custom-builds) diff --git a/project-words.txt b/project-words.txt index bc81821858..997dc781ef 100644 --- a/project-words.txt +++ b/project-words.txt @@ -7,6 +7,8 @@ CRUDQ HCQL IDONTEXIST isdir +modulith +moduliths nolink overlayed Reenskaug From 2fe7fefaf0b24acbf6d3bc70d520f03ef4038821 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Mon, 14 Apr 2025 18:55:30 +0200 Subject: [PATCH 013/140] Remove Beta for `cds debug` (#1769) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shouldn't keep this in Beta forever, especially as breaking changes are very unlikely. --------- Co-authored-by: RenΓ© Jeglinsky --- tools/cds-cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/cds-cli.md b/tools/cds-cli.md index 884bf050c5..e4678ad121 100644 --- a/tools/cds-cli.md +++ b/tools/cds-cli.md @@ -557,14 +557,14 @@ For example, if you work on Node.js things like [building plugins](../guides/dep ::: -## Debugging with `cds debug` {#cds-debug} +## Debugging with `cds debug` {#cds-debug} `cds debug` lets you debug applications running locally or remotely on SAP BTP Cloud Foundry. Local applications will be started in debug mode, while (already running) remote applications are put into debug mode. To debug an application on Cloud Foundry, the following is important: - You're logged in to the space where the application is deployed to. -- You have developer permissions in that space -> [Space Developer role](https://help.sap.com/docs/btp/sap-business-technology-platform/about-roles-in-cloud-foundry-environment). +- You have developer permissions in that space. β†’ [Space Developer role](https://help.sap.com/docs/btp/sap-business-technology-platform/about-roles-in-cloud-foundry-environment) - The app is running and [reachable through SSH](https://docs.cloudfoundry.org/devguide/deploy-apps/ssh-apps.html#check-ssh-permissions). Effectively, run: From 1bba0abe8f12df36bebac51d19c72fe1083b7c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metzing=20M=C3=A1rton?= Date: Mon, 14 Apr 2025 20:31:04 +0200 Subject: [PATCH 014/140] Update code example in outbox.md technical outbox API snippet (#1758) Solves #1757 --- java/outbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/outbox.md b/java/outbox.md index ffdd4f35af..a031f62993 100644 --- a/java/outbox.md +++ b/java/outbox.md @@ -228,7 +228,7 @@ As the `OutboxMessage` instance is serialized and stored in the database, all da must be serializable and deserializable to/from JSON. The following example shows the submission of a custom message to an outbox: ```java -OutboxService outboxService = runtime.getServiceCatalog(OutboxService.class, ""); +OutboxService outboxService = runtime.getServiceCatalog().getService(OutboxService.class, ""); OutboxMessage message = OutboxMessage.create(); message.setParams(Map.of("name", "John", "lastname", "Doe")); From babfec73b3385ca8e7c3725c8e94f12cd22191d5 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Tue, 15 Apr 2025 06:48:59 +0200 Subject: [PATCH 015/140] Remove oauth2-configuration snippet from CF deployment guide (#1764) - Only required with self-hosted approuter - With cds-dk 9 added by default if that's the case (see PR in cds-dk internally) --- guides/deployment/to-cf.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index b2e1c64141..70356c3f3c 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -164,17 +164,6 @@ cds add xsuaa The roles/scopes are derived from authorization-related annotations in your CDS models. Ensure to rerun `cds compile --to xsuaa`, as documented in the [_Authorization_ guide](/guides/security/authorization#xsuaa-configuration) whenever there are changes to these annotations. ::: -::: details For trial and extension landscapes, OAuth configuration is required -Add the following snippet to your _xs-security.json_ and adapt it to the landscape you're deploying to: - -```json -"oauth2-configuration": { - "redirect-uris": ["https://*.cfapps.us10-001.hana.ondemand.com/**"] -} -``` - -::: - [Learn more about SAP Authorization and Trust Management/XSUAA.](https://discovery-center.cloud.sap/serviceCatalog/authorization-and-trust-management-service?region=all){.learn-more} ### 3. MTA-Based Deployment { #add-mta-yaml} From fb6d91621132a0957bce2a186ec0560806ca012e Mon Sep 17 00:00:00 2001 From: Markus Ofterdinger Date: Tue, 15 Apr 2025 13:13:49 +0200 Subject: [PATCH 016/140] Describe limitations of remote services (#1756) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marc Becker Co-authored-by: RenΓ© Jeglinsky --- java/cqn-services/remote-services.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/cqn-services/remote-services.md b/java/cqn-services/remote-services.md index e9fe3e85f7..58e0bffe8f 100644 --- a/java/cqn-services/remote-services.md +++ b/java/cqn-services/remote-services.md @@ -486,3 +486,7 @@ OAuth2DestinationBuilder .property("name", "my-destination") .build(); ``` + +### Limitations + +Streaming of media content is not supported. This means that elements of an entity annotated with `@Core.MediaType` cannot be accessed via Remote OData Services and will cause an error. It is recommended to exclude these elements in your projections on the imported entity. From 5fa9b59b7f6ac5276148ce7f06ac65cc2f536fce Mon Sep 17 00:00:00 2001 From: DJ Adams Date: Wed, 16 Apr 2025 08:35:11 +0100 Subject: [PATCH 017/140] Minor updates for to-cf.md (#1775) Fixed a typo ("monrepo") then also a few other very minor details as I was already editing this file. Great section, btw! --- guides/deployment/to-cf.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index 70356c3f3c..1688ad159f 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -246,7 +246,7 @@ cds up npm i app/browse npm i app/admin-books -# If project is monrepo +# If project is monorepo ln -sf ../package-lock.json # If project is multitenant @@ -290,7 +290,7 @@ You can use this URL to access the approuter as the entry point of your applicat For **multitenant applications**, you have to subscribe a tenant first. The application is accessible via a tenant-specific URL after subscription. ::: tip No index page and SAP Fiori preview in the cloud -The default index page and [SAP Fiori preview](../../advanced/fiori#sap-fiori-preview), that you are used to see from local development, are only available for the development profile and not available in the cloud. For productive applications, you should add a proper SAP Fiori Elements application through on of the [user interface options](#add-ui) outlined before. +The default index page and [SAP Fiori preview](../../advanced/fiori#sap-fiori-preview), that you are used to seeing during local development, are only meant for the development profile and not available in the cloud. For productive applications, you should add a proper SAP Fiori elements application through on of the [user interface options](#add-ui) outlined before. ::: ### Inspect Apps in BTP Cockpit From 1c851bc53f9cafd8564001c1529d8694b3a1a078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jeglinsky?= Date: Thu, 17 Apr 2025 07:28:19 +0200 Subject: [PATCH 018/140] microservice review (#1776) Please have a look at the comments I added. Thanks :) --- guides/deployment/microservices.md | 110 +++++++++++++++-------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md index f94f295feb..fc8a2695d3 100644 --- a/guides/deployment/microservices.md +++ b/guides/deployment/microservices.md @@ -13,7 +13,7 @@ A comprehensive guide on deploying your CAP application as microservices. ## Create a Solution Monorepo Assumed we want to create a composite application consisting of two or more micro services, each living in a separate GitHub repository, for example: - + - https://github.com/capire/bookstore - https://github.com/capire/reviews - https://github.com/capire/orders @@ -24,9 +24,9 @@ With some additional repos, used as dependencies in the same manner, like: - https://github.com/capire/bookshop - https://github.com/capire/data-viewer -This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[npm workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques... +This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[NPM workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques... -1. Create a new monorepo root directory using `npm` workspaces: +1. Create a new monorepo root directory using *NPM workspaces*: ```sh mkdir capire @@ -47,14 +47,14 @@ This guide describes a way to manage development and deployment via *[monorepos] git submodule update --init ``` - Add a .gitignore + Add a _.gitignore_ file with the following content: ```txt node_modules gen ``` > The outcome of this looks and behaves exactly as the monorepo layout in *[cap/samples](https://github.com/sap-samples/cloud-cap-samples)*, so we can exercise the subsequent steps in there... -3. Test-drive locally as usual +3. Test-drive locally: ```sh npm install ``` @@ -67,8 +67,12 @@ This guide describes a way to manage development and deployment via *[monorepos] cds w bookstore ``` + Each microservice can be started independently. If you start each microservice, one after the other in a different terminal, the connection is already established. -::: details Other project structures + [Learn more about Automatic Bindings by `cds watch`](../extensibility/composition#bindings-via-cds-watch){.learn-more} + + +::: details The project structure The project structure used here is as follows: @@ -81,13 +85,13 @@ The project structure used here is as follows: └─ package.json ``` -The individual services (`bookstore`, `reviews`, `orders`) can be +The individual services (`bookstore`, `reviews`, `orders`) can be one of the following: * folders, committed directly to the root project * git submodules -Links between the projects are established using npm dependencies. +Links between the projects are established using NPM dependencies. Since the root project defines workspaces, these dependencies are also found locally without the need for publishing or linking. -When one of the projects is cloned in isolation, it is still possible to fetch dependencies to other modules via the npm registry. +When one of the projects is cloned in isolation, it's still possible to fetch dependencies to other modules via the NPM registry. ::: @@ -97,22 +101,24 @@ If you have multiple CAP applications relying on the same domain model or want t In the following steps, we create an additional project to easily collect the relevant models from these projects, and act as a vehicle to deploy these models to SAP HANA in a controlled way. -::: details Evaluation +::: details Why a shared database? + +A shared database is beneficial if the following are important for you: + + - **Query Performance:** Complex queries are executed much faster, for example `$expand` to an entity on another microservice, compared to calls across services with own data persistencies. + - **Independent Scalability** of application runtimes, compared to a monolithic application. -The advantages are as follows: - - **Query Performance:** Complex queries are executed much faster, for example $expand to an entity on another microservice (compared to calls across services with own data persistencies) - - **Independent Scalability** of application runtimes (compared to a monolithic application) +These are the (not so beneficial) side effects you when using a shared persistence: - Disadvantages: - - Accessing data directly (without an API) means any changes in the data model affect all applications directly - - every change in one of the services either requires - - a redeployment of all microservices involved - - a logic to decide which microservices need redeployment to avoid inconsistencies - - violates 12 factors concept + - Accessing data directly (without an API) means any changes in the data model affect all applications directly. + - Every change in one of the services requires either one of the following: + - Redeployment of all microservices involved. + - Logic to decide which microservices need redeployment to avoid inconsistencies. + - Violates the 12 factors concept. ::: -### Add a project for shared database +### Add a Project For Shared Database 1. Add another `cds` project to collect the models from these projects: @@ -127,7 +133,7 @@ The advantages are as follows: npm add @capire/orders ``` - > Note how *npm workspaces* allows us to use the package names of the projects, and nicely creates symlinks in *node_modules* accordingly. + > Note how *NPM workspaces* allows us to use the package names of the projects, and nicely creates symlinks in *node_modules* accordingly. 2. Add a `db/schema.cds` file as a mashup to actually collect the models: @@ -181,15 +187,15 @@ The project structure used here is as follows: └─ package.json ``` -The `shared-db` module is simply another CAP project, with only db content. The dependencies are installed via npm, so it is still possible to install via an npm registry if used outside of the monorepo setup. +The `shared-db` module is simply another CAP project, with only db content. The dependencies are installed via NPM, so it's still possible to install via an NPM registry if used outside of the monorepo setup. -The db model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all npm workspaces. +The db model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all NPM workspaces. ::: -### Deployment as separate mta +### Deployment as Separate MTA -In a setup with multiple deployment units, we can add the `shared-db` project as its own mta deployment: +In a setup with multiple deployment units, we can add the `shared-db` project as its own MTA deployment: ```sh cds add mta @@ -260,11 +266,11 @@ resources: -#### Binding to shared database +#### Binding to a Shared Database The only thing left to care about is to ensure all 3+1 projects are bound and connected to the same database at deployment, subscription, and runtime. -Configure the mta.yaml of the other apps to bind to the existing shared database, for example, in the reviews module: +Configure the _mta.yaml_ of the other apps to bind to the existing shared database, for example, in the reviews module: ```yaml [reviews/mta.yaml] ... @@ -295,7 +301,7 @@ resources: #### Subsequent updates - TODO... -- Whenever one of the projects has changes affecting the database, that triggers a new deployment of the `shared-db` project +- Whenever one of the projects has changes affecting the database that triggers a new deployment of the `shared-db` project - `git submodules` gives you control of which versions to pull, for example by `git branches` or `git tags` - Ensure to first deploy `shared-db` before deploying the others @@ -303,7 +309,7 @@ resources: ## All-in-one Deployment -Here we go on with our guide how to deploy all 3+1 projects at once with a common `mta.yaml` +This section is about how to deploy all 3+1 projects at once with a common _mta.yaml_. ![component diagram with synchronous and event communication for orders](./assets/microservices/bookstore.excalidraw.svg) @@ -359,18 +365,18 @@ build-parameters: ::: info `cds build --ws` -If the CDS models of every npm workspace contained in the monorepo should be considered, then instead of creating this `shared-db` folder, you can also use: +If the CDS models of every NPM workspace contained in the monorepo should be considered, then instead of creating this `shared-db` folder, you can also use: ```shell cds build --for hana --production --ws ``` -The `--ws` aggregates all models in the npm workspaces. +The `--ws` aggregates all models in the NPM workspaces. In this walkthrough, we only include a subset of the CDS models in the deployment. ::: ::: details Configure each app for cloud readiness -The preceding steps added configuration only to the workspace root. +The preceding steps only added configuration to the workspace root. Additionally add database configuration to each module that we want to deploy - bookstore, orders, and reviews: @@ -384,7 +390,7 @@ npm i @cap-js/hana --workspace reviews ### Applications -Replace the mta module for samples-srv with versions for each CAP service and adjust `name`, `path`, and `provides[0].name` to match the module name. Also change the `npm-ci` builder to the `npm` builder. +Replace the MTA module for `samples-srv` with versions for each CAP service and adjust `name`, `path`, and `provides[0].name` to match the module name. Also change the `npm-ci` builder to the `npm` builder. ::: code-group ```yaml [mta.yaml] @@ -500,7 +506,7 @@ Add the admin role ::: ::: details Configure each app for cloud readiness -Add npm dependency `@sap/xssec`: +Add NPM dependency `@sap/xssec`: ```shell npm i @sap/xssec --workspace bookstore @@ -713,7 +719,7 @@ modules: #### Static Content -The approuter can serve static content. Since our UIs are located in different npm workspaces, we create symbolic links to them as an easy way to deploy them as part of the approuter. +The approuter can serve static content. Since our UIs are located in different NPM workspaces, we create symbolic links to them as an easy way to deploy them as part of the approuter. ```shell mkdir .deploy/app-router/resources @@ -768,7 +774,7 @@ modules: ``` ::: -The xs-app.json file describes how to forward incoming request to the API endpoint / OData services and is located in the app/router folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service. +The _xs-app.json_ file describes how to forward incoming request to the API endpoint / OData services and is located in the app/router folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service. ::: code-group ```json [.deploy/app-router/xs-app.json] @@ -854,7 +860,7 @@ Additionally, the welcomeFile is important for deployed Vue UIs as they obtain C ### Deploy -In order to build, deploy, and undeploy easily, add these `npm` scripts: +To build, deploy, and undeploy easily, add these `npm` scripts: ::: code-group ```json [package.json] @@ -868,13 +874,13 @@ In order to build, deploy, and undeploy easily, add these `npm` scripts: Before deploying you need to log in to Cloud Foundry. -To locally build the apps, run +Build the apps locally: ```shell npm run build ``` -To deploy the built artifacts to Cloud Foundry, run +Deploy the built artifacts to Cloud Foundry: ```shell npm run deploy @@ -923,26 +929,26 @@ While these benefits exist, they are accompanied by complexity and performance l Instead of just choosing between a monolith and microservices, these aspects can be combined into an architecture that fits the specific product. -Since each cut not only has benefits, but also drawbacks, it is important to choose which benefits actually help the overall product and which drawbacks can be accepted. +Since each cut not only has benefits, but also drawbacks, it's important to choose which benefits actually help the overall product and which drawbacks can be accepted. ![Multiple deployment units - one contains the UIs, one contains shared service instances, one contains a shared db, two each contain an app connected to the shared db, one contains a db and an app, which is also connected to the shared db](./assets/microservices/complex.excalidraw.svg) ### A Late Cut -When developing a product it may initially not be apparent where the boundaries are. +When developing a product, it may initially not be apparent where the boundaries are. Keeping this in mind, an app can be developed as a modular application with use case specific CAP services. It can first be deployed as a [monolith / modulith](#monolith-or-microservice). Once the boundaries are clear, it can then be split into multiple applications. Generally, the semantic separation and structure can be enforced using modules. The deployment configuration is then an independent step on top. In this way, the same application can be deployed as a monolith, as microservices with shared db, as true microservices, or a combination of these, just via configuration change. -![Modules which can be arranged in different deploy configurations, e.g. as a monolith (bookshop, reviews, orders), as two apps (bookshop, orders in one, reviews in the other), etc.](./assets/microservices/late-cut.excalidraw.svg) +![Modules which can be arranged in different deploy configurations, for example, as a monolith (bookshop, reviews, orders), as two apps (bookshop, orders in one, reviews in the other), and so on.](./assets/microservices/late-cut.excalidraw.svg) ### Best Practices * Prefer a late cut * Stay flexible in where to cut -* Prefer staying loosely coupled β†’ e.g. ReviewsService β†’ reviewed events β†’ UPDATE avg ratings +* Prefer staying loosely coupled β†’ for example, ReviewsService β†’ reviewed events β†’ UPDATE avg ratings * Leverage db-level integration selectively β†’ Prefer referring to (public) service entities, not (private) db entities ## Appendix @@ -956,14 +962,14 @@ A monolith is a single deployment unit with a single application. This is very c A modulith, even though the app is separated into multiple CAP services inside multiple modules, can still be deployed as a single monolithic application. This combines the benefit of a clear structure and distributed development while keeping a simple deployment. -![A single app containing the modules bookshop, reviews and orders](./assets/microservices/modulith.excalidraw.svg) +![A single app containing the modules bookshop, reviews, and orders](./assets/microservices/modulith.excalidraw.svg) True microservices each consist of their own deployment unit with their own application and their own database. -Meaning that they are truly independent of each other. And it works well if they actually are independent. +Meaning that they're truly independent of each other. And it works well if they are actually independent. ![A simplified microservices view - three deployment units, each with one app and one database](./assets/microservices/true-microservices.excalidraw.svg) -The above is a simplified view. In an actual microservice deployment, there are typically shared service instances and wiring needs to be provided so that apps can talk to each other, directly or via events. +What was mentioned earlier is a simplified view. In an actual microservice deployment, there are typically shared service instances and wiring needs to be provided so that apps can talk to each other, directly or via events. If the microservices are not cut well, the communication overhead leads to high performance losses and often the need for data replication or caching. ![A more complete microservices view - two deployment units with one app, one db and some UIs each, one deployment unit for shared service instances](./assets/microservices/true-microservices-full.excalidraw.svg) @@ -983,7 +989,7 @@ Benefits: Requirement: - The app needs to be stateless, state needs to be persisted -Multiple app instances can be used both for monoliths and microservices. +Multiple app instances can be used for both monoliths and microservices. ![A single app with multiple application instances](./assets/microservices/app-instances.excalidraw.svg) @@ -1027,7 +1033,7 @@ For some parts, a 100% cpu utilization over an extended period is accepted for e #### Fault Tolerance -While app instances already provide some resilience, there are failure classes (e.g. bugs) which affect each app instance. +While app instances already provide some resilience, there are failure classes (for example, bugs) which affect each app instance. Separating functionality into different apps means that when one app experiences issues, the functionality of the other apps is still available. In the bookstore example, while reviews may be down, orders may still be possible. @@ -1038,7 +1044,7 @@ This benefit is null for apps with synchronous dependencies on each other. If A With multiple apps, you can still deploy them together as one unit, for example as part of a multitarget application archive. Once an application grows bigger, this takes a significant amount of time. -Deployments can then be split up either by type (e.g. deploying UIs separately) or horizontally (e.g. deploying each app via its own deployment unit). +Deployments can then be split up either by type (for example, deploying UIs separately) or horizontally (for example, deploying each app via its own deployment unit). Benefits: - Faster individual deploy times @@ -1048,7 +1054,7 @@ Drawbacks: - Coordination between deployment units for updates with dependencies - Configuration wiring to connect systems across deployment units -![One deployment unit for UIs and one deployment unit for apps, db etc.](./assets/microservices/multiple-deployment-units.excalidraw.svg) +![One deployment unit for UIs and one deployment unit for apps, db and so on.](./assets/microservices/multiple-deployment-units.excalidraw.svg) With a single deployment unit, when a fix for one part needs to be deployed, the risk of redeploying the rest of the application needs to be considered. @@ -1067,7 +1073,7 @@ Here we need to differentiate between two scenarios: - Using multiple databases of the same type A polyglot persistence can be used when the app has different requirements for the types of data it needs to store. -For example, there may be a large amount of large files that can be stored in a document store, while corresponding administrative data is stored in a relational database. +For example, there may be a large number of large files that can be stored in a document store, while corresponding administrative data is stored in a relational database. Benefits: - Use suitable technology for different use cases @@ -1093,7 +1099,7 @@ Drawbacks: When data is distributed across multiple databases, strategies may be necessary to combine data from multiple sources. -- Fetching on-demand +- Fetching on demand - Caching - HANA synonyms - Data Replication From d55996ea4aa1d2a3da697ce6344ac496dd247599 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 07:37:43 +0200 Subject: [PATCH 019/140] chore: Update CLI texts (#1767) Updates the output of cds CLI texts to the latest version. Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com> --- tools/assets/help/cds-typer.out.md | 10 +++++++++- tools/assets/help/cds-version-md.out.md | 10 +++++----- tools/assets/help/cds-version.out.md | 10 +++++----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/tools/assets/help/cds-typer.out.md b/tools/assets/help/cds-typer.out.md index 3c1014543e..594fcf474f 100644 --- a/tools/assets/help/cds-typer.out.md +++ b/tools/assets/help/cds-typer.out.md @@ -20,6 +20,13 @@ OPTIONS This value must be set in your project configuration. Passing it as parameter to the cds-typer CLI has no effect. + --cache: <none | blake2s256> + (default: none) + + How to cache typer runs. + none: fully run cds-typer whenever it is called + blake2s256: only run if the blake2s256-hash of the model has changed. Hash is stored in a file between runs. + --help This text. @@ -74,6 +81,7 @@ OPTIONS If set to true, properties in entities are always generated as optional (a?: T). + Setting it to false makes properties non-optional instead (a: T). --targetModuleType --target_module_type: <esm | cjs | auto> @@ -85,7 +93,7 @@ OPTIONS --useEntitiesProxy --use_entities_proxy: <true | false> - (default: false) + (default: true) If set to true the 'cds.entities' exports in the generated 'index.js' files will be wrapped in 'Proxy' objects diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index 5c0fb3d392..1c7f521569 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -5,14 +5,14 @@ | your-project | <Add your repository here> | | ---------------------- | --------------------------------------- | | @cap-js/asyncapi | 1.0.3 | -| @cap-js/cds-types | 0.9.0 | +| @cap-js/cds-types | 0.10.0 | | @cap-js/db-service | 1.19.1 | | @cap-js/openapi | 1.2.1 | | @cap-js/sqlite | 1.10.0 | -| @sap/cds | 8.9.0 | -| @sap/cds-compiler | 5.9.0 | -| @sap/cds-dk (global) | 8.9.0 | -| @sap/cds-fiori | 1.4.0 | +| @sap/cds | 8.9.2 | +| @sap/cds-compiler | 5.9.2 | +| @sap/cds-dk (global) | 8.9.1 | +| @sap/cds-fiori | 1.4.1 | | @sap/cds-foss | 5.0.1 | | @sap/cds-mtxs | 2.7.0 | | @sap/eslint-plugin-cds | 3.2.0 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 6887a503b7..9547cfb612 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -3,14 +3,14 @@ > cds version @cap-js/asyncapi: 1.0.3 -@cap-js/cds-types: 0.9.0 +@cap-js/cds-types: 0.10.0 @cap-js/db-service: 1.19.1 @cap-js/openapi: 1.2.1 @cap-js/sqlite: 1.10.0 -@sap/cds: 8.9.0 -@sap/cds-compiler: 5.9.0 -@sap/cds-dk (global): 8.9.0 -@sap/cds-fiori: 1.4.0 +@sap/cds: 8.9.2 +@sap/cds-compiler: 5.9.2 +@sap/cds-dk (global): 8.9.1 +@sap/cds-fiori: 1.4.1 @sap/cds-foss: 5.0.1 @sap/cds-mtxs: 2.7.0 @sap/eslint-plugin-cds: 3.2.0 From d343af408ea65f043d664f858cd832ea846b23ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 05:35:08 +0000 Subject: [PATCH 020/140] chore(deps): update dependency cspell to v8.19.0 (#1779) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [cspell](https://cspell.org/) ([source](https://redirect.github.com/streetsidesoftware/cspell/tree/HEAD/packages/cspell)) | [`8.18.1` -> `8.19.0`](https://renovatebot.com/diffs/npm/cspell/8.18.1/8.19.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/cspell/8.19.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/cspell/8.19.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/cspell/8.18.1/8.19.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/cspell/8.18.1/8.19.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
streetsidesoftware/cspell (cspell) ### [`v8.19.0`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#8190-2025-04-16) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v8.18.1...v8.19.0) **Note:** Version bump only for package cspell
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 318 +++++++++++++++++++++++----------------------- 1 file changed, 159 insertions(+), 159 deletions(-) diff --git a/package-lock.json b/package-lock.json index 072f85f7f2..f9e5ece501 100644 --- a/package-lock.json +++ b/package-lock.json @@ -298,28 +298,28 @@ } }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.18.1.tgz", - "integrity": "sha512-gxciVVfQqCVXYH0p2Q5D7x7/SgaW3Wv5UjRwO+TCme0P2lVLl/IcfjkujZX+6UQkT7X4QRglXo1QN141UcCRCQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.19.0.tgz", + "integrity": "sha512-ISPiC8YQr+09aGFK6VPxxygp3BOSvU/Axlvl2eCYhH+vS+3NoYWakn+UZJ6DoveIsfFWp9LpbU9/xLea8qbG4g==", "dev": true, "license": "MIT", "dependencies": { "@cspell/dict-ada": "^4.1.0", "@cspell/dict-al": "^1.1.0", - "@cspell/dict-aws": "^4.0.9", + "@cspell/dict-aws": "^4.0.10", "@cspell/dict-bash": "^4.2.0", - "@cspell/dict-companies": "^3.1.14", - "@cspell/dict-cpp": "^6.0.6", + "@cspell/dict-companies": "^3.1.15", + "@cspell/dict-cpp": "^6.0.8", "@cspell/dict-cryptocurrencies": "^5.0.4", "@cspell/dict-csharp": "^4.0.6", "@cspell/dict-css": "^4.0.17", "@cspell/dict-dart": "^2.3.0", - "@cspell/dict-data-science": "^2.0.7", + "@cspell/dict-data-science": "^2.0.8", "@cspell/dict-django": "^4.1.4", - "@cspell/dict-docker": "^1.1.12", + "@cspell/dict-docker": "^1.1.13", "@cspell/dict-dotnet": "^5.0.9", "@cspell/dict-elixir": "^4.0.7", - "@cspell/dict-en_us": "^4.3.35", + "@cspell/dict-en_us": "^4.4.1", "@cspell/dict-en-common-misspellings": "^2.0.10", "@cspell/dict-en-gb": "1.1.33", "@cspell/dict-filetypes": "^3.0.11", @@ -327,9 +327,9 @@ "@cspell/dict-fonts": "^4.0.4", "@cspell/dict-fsharp": "^1.1.0", "@cspell/dict-fullstack": "^3.2.6", - "@cspell/dict-gaming-terms": "^1.1.0", + "@cspell/dict-gaming-terms": "^1.1.1", "@cspell/dict-git": "^3.0.4", - "@cspell/dict-golang": "^6.0.19", + "@cspell/dict-golang": "^6.0.20", "@cspell/dict-google": "^1.0.8", "@cspell/dict-haskell": "^4.0.5", "@cspell/dict-html": "^4.0.11", @@ -342,25 +342,25 @@ "@cspell/dict-lorem-ipsum": "^4.0.4", "@cspell/dict-lua": "^4.0.7", "@cspell/dict-makefile": "^1.0.4", - "@cspell/dict-markdown": "^2.0.9", + "@cspell/dict-markdown": "^2.0.10", "@cspell/dict-monkeyc": "^1.0.10", - "@cspell/dict-node": "^5.0.6", - "@cspell/dict-npm": "^5.1.31", + "@cspell/dict-node": "^5.0.7", + "@cspell/dict-npm": "^5.2.0", "@cspell/dict-php": "^4.0.14", "@cspell/dict-powershell": "^5.0.14", "@cspell/dict-public-licenses": "^2.0.13", - "@cspell/dict-python": "^4.2.16", + "@cspell/dict-python": "^4.2.17", "@cspell/dict-r": "^2.1.0", "@cspell/dict-ruby": "^5.0.8", "@cspell/dict-rust": "^4.0.11", "@cspell/dict-scala": "^5.0.7", "@cspell/dict-shell": "^1.1.0", - "@cspell/dict-software-terms": "^5.0.2", + "@cspell/dict-software-terms": "^5.0.5", "@cspell/dict-sql": "^2.2.0", "@cspell/dict-svelte": "^1.0.6", "@cspell/dict-swift": "^2.0.5", "@cspell/dict-terraform": "^1.1.1", - "@cspell/dict-typescript": "^3.2.0", + "@cspell/dict-typescript": "^3.2.1", "@cspell/dict-vue": "^3.0.4" }, "engines": { @@ -368,22 +368,22 @@ } }, "node_modules/@cspell/cspell-json-reporter": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.18.1.tgz", - "integrity": "sha512-/U3/8bcOL5O35fI9F7nN7Mhic0K01ZRxRV/+5jj7atltBbqgFSxViHCZBX0lDZJM96gUHn+3r6q6/8VEJahpDA==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.19.0.tgz", + "integrity": "sha512-MkpBlQizR9UxwrYhzJgz02yzgrmfyPpb+QctwKNJthscymhjufkBFnBj5cHK5fbmp+/y4jXxaX+Ew6QUFiJsNw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "8.18.1" + "@cspell/cspell-types": "8.19.0" }, "engines": { "node": ">=18" } }, "node_modules/@cspell/cspell-pipe": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.18.1.tgz", - "integrity": "sha512-QHndTQPkR1c02pvvQ7UKFtLjCXgY0OcX8zjTLrCkynmcQxJFjAZAh9cJ7NMOAxab+ciSnkaVf4KWaRSEG17z8Q==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.19.0.tgz", + "integrity": "sha512-OtgF/oQ3n6T/qM+fIWLfhOhW0fLSPnpZGOZi7uKSCJZxnHKVk0h+7zNPlLkcDHrhxZP4Df76S9z7jU5iEC2oYA==", "dev": true, "license": "MIT", "engines": { @@ -391,9 +391,9 @@ } }, "node_modules/@cspell/cspell-resolver": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.18.1.tgz", - "integrity": "sha512-T2sUBv0p9Hnfyg1xT1u3ESKuIWaaIDo0I8idh5DSlTpHgLjdIeAwasmFjEJ28qZv8OKSGawcSQKgJbStfbZASQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.19.0.tgz", + "integrity": "sha512-/iA0ALPgnX9bN6Xwt5hfbmh7oTVoXNDS5k0rBZDGz+w0/zKn6T1XxPUIlkz5T2e4nSKOmmlpcNZGdroA7GdUfA==", "dev": true, "license": "MIT", "dependencies": { @@ -404,9 +404,9 @@ } }, "node_modules/@cspell/cspell-service-bus": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.18.1.tgz", - "integrity": "sha512-PwWl7EyhGIu4wHEhvBJb6xVlqMtFwQk0qLDArBvugL6nA+MX9NfG/w7PTgS7tCkFjVF1ku2sDzDLTDWwEk+MLw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.19.0.tgz", + "integrity": "sha512-L5knViQupeqBMwfP0iQ3+oDQ8s1pzRodcOR/6H2b9cGjuIFPIcsfclzuqVzzMtfptY25WCEpC735pwcfyIRnnQ==", "dev": true, "license": "MIT", "engines": { @@ -414,9 +414,9 @@ } }, "node_modules/@cspell/cspell-types": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.18.1.tgz", - "integrity": "sha512-d/nMG+qnMbI/1JPm+lD0KcKpgtEHMRsHxkdtGyNCDgvHL/JOGaSHc5ERS3IUgBW0Dfya/3z9wPdaMcHEzt7YCQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.19.0.tgz", + "integrity": "sha512-iWOtHogjZdRbX4zBlXRdh3+NB1DqgBD68+U70yL9+r37szMd8D5tRcm3h98yzhfbXW34zWhvfOiXvRi28SH4ng==", "dev": true, "license": "MIT", "engines": { @@ -438,9 +438,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-aws": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.9.tgz", - "integrity": "sha512-bDYdnnJGwSkIZ4gzrauu7qzOs/ZAY/FnU4k11LgdMI8BhwMfsbsy2EI1iS+sD/BI5ZnNT9kU5YR3WADeNOmhRg==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.10.tgz", + "integrity": "sha512-0qW4sI0GX8haELdhfakQNuw7a2pnWXz3VYQA2MpydH2xT2e6EN9DWFpKAi8DfcChm8MgDAogKkoHtIo075iYng==", "dev": true, "license": "MIT" }, @@ -455,16 +455,16 @@ } }, "node_modules/@cspell/dict-companies": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.1.14.tgz", - "integrity": "sha512-iqo1Ce4L7h0l0GFSicm2wCLtfuymwkvgFGhmu9UHyuIcTbdFkDErH+m6lH3Ed+QuskJlpQ9dM7puMIGqUlVERw==", + "version": "3.1.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.1.15.tgz", + "integrity": "sha512-vnGYTJFrqM9HdtgpZFOThFTjlPyJWqPi0eidMKyZxMKTHhP7yg6mD5X9WPEPvfiysmJYMnA6KKYQEBqoKFPU9g==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-cpp": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-6.0.6.tgz", - "integrity": "sha512-HMV1chsExuZt5IL9rYBW7GmhNZDVdQJEd1WtFgOO6jqiNxbpTG3Is3Pkldl7FpusBQQZr4BdjMit5bnPpVRy3A==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-6.0.8.tgz", + "integrity": "sha512-BzurRZilWqaJt32Gif6/yCCPi+FtrchjmnehVEIFzbWyeBd/VOUw77IwrEzehZsu5cRU91yPWuWp5fUsKfDAXA==", "dev": true, "license": "MIT" }, @@ -497,9 +497,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-data-science": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.7.tgz", - "integrity": "sha512-XhAkK+nSW6zmrnWzusmZ1BpYLc62AWYHZc2p17u4nE2Z9XG5DleG55PCZxXQTKz90pmwlhFM9AfpkJsYaBWATA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.8.tgz", + "integrity": "sha512-uyAtT+32PfM29wRBeAkUSbkytqI8bNszNfAz2sGPtZBRmsZTYugKMEO9eDjAIE/pnT9CmbjNuoiXhk+Ss4fCOg==", "dev": true, "license": "MIT" }, @@ -511,9 +511,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-docker": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.12.tgz", - "integrity": "sha512-6d25ZPBnYZaT9D9An/x6g/4mk542R8bR3ipnby3QFCxnfdd6xaWiTcwDPsCgwN2aQZIQ1jX/fil9KmBEqIK/qA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.13.tgz", + "integrity": "sha512-85X+ZC/CPT3ie26DcfeMFkZSNuhS8DlAqPXzAjilHtGE/Nj+QnS3jyBz0spDJOJrjh8wx1+ro2oCK98sbVcztw==", "dev": true, "license": "MIT" }, @@ -532,9 +532,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.3.35", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.35.tgz", - "integrity": "sha512-HF6QNyPHkxeo/SosaZXRQlnKDUTjIzrGKyqfbw/fPPlPYrXefAZZ40ofheb5HnbUicR7xqV/lsc/HQfqYshGIw==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.1.tgz", + "integrity": "sha512-OqIImYIrTAg+lpS+1v/KtjI2kyiw1bD3FqGbuXUxpAc+e+pWluW7rPjsJCxTRlruKQMSCgQeK6N054XnxHdkDQ==", "dev": true, "license": "MIT" }, @@ -588,9 +588,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-gaming-terms": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.1.0.tgz", - "integrity": "sha512-46AnDs9XkgJ2f1Sqol1WgfJ8gOqp60fojpc9Wxch7x+BA63g4JfMV5/M5x0sI0TLlLY8EBSglcr8wQF/7C80AQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.1.1.tgz", + "integrity": "sha512-tb8GFxjTLDQstkJcJ90lDqF4rKKlMUKs5/ewePN9P+PYRSehqDpLI5S5meOfPit8LGszeOrjUdBQ4zXo7NpMyQ==", "dev": true, "license": "MIT" }, @@ -602,9 +602,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-golang": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.19.tgz", - "integrity": "sha512-VS+oinB2/CbgmHE06kMJlj52OVMZM0S2EEXph3oaroNTgTuclSwdFylQmOEjquZi55kW+n3FM9MyWXiitB7Dtg==", + "version": "6.0.20", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.20.tgz", + "integrity": "sha512-b7nd9XXs+apMMzNSWorjirQsbmlwcTC0ViQJU8u+XNose3z0y7oNeEpbTPTVoN1+1sO9aOHuFwfwoOMFCDS14Q==", "dev": true, "license": "MIT" }, @@ -693,16 +693,16 @@ "license": "MIT" }, "node_modules/@cspell/dict-markdown": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.9.tgz", - "integrity": "sha512-j2e6Eg18BlTb1mMP1DkyRFMM/FLS7qiZjltpURzDckB57zDZbUyskOFdl4VX7jItZZEeY0fe22bSPOycgS1Z5A==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.10.tgz", + "integrity": "sha512-vtVa6L/84F9sTjclTYDkWJF/Vx2c5xzxBKkQp+CEFlxOF2SYgm+RSoEvAvg5vj4N5kuqR4350ZlY3zl2eA3MXw==", "dev": true, "license": "MIT", "peerDependencies": { "@cspell/dict-css": "^4.0.17", "@cspell/dict-html": "^4.0.11", "@cspell/dict-html-symbol-entities": "^4.0.3", - "@cspell/dict-typescript": "^3.2.0" + "@cspell/dict-typescript": "^3.2.1" } }, "node_modules/@cspell/dict-monkeyc": { @@ -713,16 +713,16 @@ "license": "MIT" }, "node_modules/@cspell/dict-node": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-5.0.6.tgz", - "integrity": "sha512-CEbhPCpxGvRNByGolSBTrXXW2rJA4bGqZuTx1KKO85mwR6aadeOmUE7xf/8jiCkXSy+qvr9aJeh+jlfXcsrziQ==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-5.0.7.tgz", + "integrity": "sha512-ZaPpBsHGQCqUyFPKLyCNUH2qzolDRm1/901IO8e7btk7bEDF56DN82VD43gPvD4HWz3yLs/WkcLa01KYAJpnOw==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.1.31", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.1.31.tgz", - "integrity": "sha512-Oh9nrhgNV4UD1hlbgO3TFQqQRKziwc7qXKoQiC4oqOYIhMs2WL9Ezozku7FY1e7o5XbCIZX9nRH0ymNx/Rwj6w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.0.tgz", + "integrity": "sha512-kTUdbSE8SuIMKMlASMbI8/SEwv3EmI8eBcwdrtu4PHA+XVx+8JvQCB5fcWK9mn/94Y7LQ1kDIm+yfAZfwopY0A==", "dev": true, "license": "MIT" }, @@ -748,13 +748,13 @@ "license": "MIT" }, "node_modules/@cspell/dict-python": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.16.tgz", - "integrity": "sha512-LkQssFt1hPOWXIQiD8ScTkz/41RL7Ti0V/2ytUzEW82dc0atIEksrBg8MuOjWXktp0Dk5tDwRLgmIvhV3CFFOA==", + "version": "4.2.17", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.17.tgz", + "integrity": "sha512-xqMKfVc8d7yDaOChFdL2uWAN3Mw9qObB/Zr6t5w1OHbi23gWs7V1lI9d0mXAoqSK6N3mosbum4OIq/FleQDnlw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/dict-data-science": "^2.0.7" + "@cspell/dict-data-science": "^2.0.8" } }, "node_modules/@cspell/dict-r": { @@ -793,9 +793,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-software-terms": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.0.2.tgz", - "integrity": "sha512-aCzP+M0WXRLYXTriDMZygUe5s4jKyau/nCA6gBGt4EoHfXn+Ua/+DrW766oXOkkESIlqTBtRgb9gWwQvUdOXSQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.0.5.tgz", + "integrity": "sha512-ZjAOa8FI8/JrxaRqKT3eS7AQXFjU174xxQoKYMkmdwSyNIj7WUCAg10UeLqeMjFVv36zIO0Hm0dD2+Bvn18SLA==", "dev": true, "license": "MIT" }, @@ -828,9 +828,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-typescript": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.0.tgz", - "integrity": "sha512-Pk3zNePLT8qg51l0M4g1ISowYAEGxTuNfZlgkU5SvHa9Cu7x/BWoyYq9Fvc3kAyoisCjRPyvWF4uRYrPitPDFw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.1.tgz", + "integrity": "sha512-jdnKg4rBl75GUBTsUD6nTJl7FGvaIt5wWcWP7TZSC3rV1LfkwvbUiY3PiGpfJlAIdnLYSeFWIpYU9gyVgz206w==", "dev": true, "license": "MIT" }, @@ -842,13 +842,13 @@ "license": "MIT" }, "node_modules/@cspell/dynamic-import": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.18.1.tgz", - "integrity": "sha512-VJHfS/Iv0Rx7wn1pjPmwgsaw6r72N5Cx2gL0slWk8Cogc8YiK7/6jsGnsvxJZVkHntJoiT8PrkIvhNKb3awD3g==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.19.0.tgz", + "integrity": "sha512-VrgcgoSyspbXFalaFZgwQXCZQEUR/iKxyqM0R/gRQOk/cRKUnWOkaV0oRJcHhNXZra48boElWXIOlIDXiGhcJQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.18.1", + "@cspell/url": "8.19.0", "import-meta-resolve": "^4.1.0" }, "engines": { @@ -856,9 +856,9 @@ } }, "node_modules/@cspell/filetypes": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.18.1.tgz", - "integrity": "sha512-vTOb2itP0pjrccvt8wcKiTGyw0pFMTPI85H12T6n8ZhqXTktPgQH2gEf/SU/5tkPNnBKr4GJ+FdU5hJ27HzgXQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.19.0.tgz", + "integrity": "sha512-fsSry1JPksv/LOcFryMPWPmudFekH5SD1UY6WJ2GL8CNryILbbSypEJNriE/hA1UtOTDEBY0bTlsj81GzfW0Ww==", "dev": true, "license": "MIT", "engines": { @@ -866,9 +866,9 @@ } }, "node_modules/@cspell/strong-weak-map": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.18.1.tgz", - "integrity": "sha512-gsgv+5ZQD4aHNHDdfNGoafVYkqRynyYgaodt9Dp/3o0YKYcxGf2jrX8SJ35MfZ61qln0n7P4Djrg+bFV2zNH5w==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.19.0.tgz", + "integrity": "sha512-8T/jf/y5cxkizozFJqKuxB+gYhB3JFdjVZjVGKIK8KLT7ebnO1bkEKe9fbZByZxJQxLVvwIdwWE3EKr5oFNptA==", "dev": true, "license": "MIT", "engines": { @@ -876,9 +876,9 @@ } }, "node_modules/@cspell/url": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.18.1.tgz", - "integrity": "sha512-FRJbLYDC9ucpTOzbF6MohP2u5X3NU5L0RoVuoYCynqm/QOI38XP6WOEaI4H58CAn857bOIKZk0LZRPTGzi6Qlg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.19.0.tgz", + "integrity": "sha512-zleyW54/TUYzlWd+5fJev17pk+jpploJnE/NwactKFmSg3VQi7AbwYWz3/hwLyRDz6cpfLKPKk4aJB6ay5QpSg==", "dev": true, "license": "MIT", "engines": { @@ -3735,25 +3735,25 @@ } }, "node_modules/cspell": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.18.1.tgz", - "integrity": "sha512-RE3LIgN9NAVcYBNX2NQVhLergok8EPymOuCUhu1vBR8cjRmioksn3CJeCoQgD8rPjalM+S9thYkMtOZc5Jjv2A==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.19.0.tgz", + "integrity": "sha512-3I6Cz2JZ9iJ5+/zqm1Wy5ak5LSebv/dsy8LGjQ/MlVeofsH7GLFkN/c/krCJzY/KxmgskkxzHZT4fl78/LFVdg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-json-reporter": "8.18.1", - "@cspell/cspell-pipe": "8.18.1", - "@cspell/cspell-types": "8.18.1", - "@cspell/dynamic-import": "8.18.1", - "@cspell/url": "8.18.1", + "@cspell/cspell-json-reporter": "8.19.0", + "@cspell/cspell-pipe": "8.19.0", + "@cspell/cspell-types": "8.19.0", + "@cspell/dynamic-import": "8.19.0", + "@cspell/url": "8.19.0", "chalk": "^5.4.1", "chalk-template": "^1.1.0", "commander": "^13.1.0", - "cspell-dictionary": "8.18.1", - "cspell-gitignore": "8.18.1", - "cspell-glob": "8.18.1", - "cspell-io": "8.18.1", - "cspell-lib": "8.18.1", + "cspell-dictionary": "8.19.0", + "cspell-gitignore": "8.19.0", + "cspell-glob": "8.19.0", + "cspell-io": "8.19.0", + "cspell-lib": "8.19.0", "fast-json-stable-stringify": "^2.1.0", "file-entry-cache": "^9.1.0", "get-stdin": "^9.0.0", @@ -3772,30 +3772,30 @@ } }, "node_modules/cspell-config-lib": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.18.1.tgz", - "integrity": "sha512-zdJ0uhLROSUrHoibysPw+AkxKPUmiG95hDtiL7s8smewkuaS1hpjqwsDBx981nHYs3xW3qDUfVATrAkSzb0VMw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.19.0.tgz", + "integrity": "sha512-WcLOfdj2ZHXPPL3oAvqBhTQTPt3ZgErzMfR6OWwejO/19UUPe9yfr9oCENfjTTVBvsDhkqz40tawM5Y1Uh3WRQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "8.18.1", + "@cspell/cspell-types": "8.19.0", "comment-json": "^4.2.5", - "yaml": "^2.7.0" + "yaml": "^2.7.1" }, "engines": { "node": ">=18" } }, "node_modules/cspell-dictionary": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.18.1.tgz", - "integrity": "sha512-vKHEPSfkMKMR4S4tk6K2vHC+f3kdJK8Kdh/C0jDh6RRDjDsyAPxshtbremxOgAX6X8GaRUCROoMZ7FhB92+Y9w==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.19.0.tgz", + "integrity": "sha512-kbJf5IiJu5l3jnobSvGx0q0PlkK12q9Z2g3bLSvatw/iEleiZ7xsA7Yy1jf3AL+iB1gHxXqCZMEUulFSfT0JZA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.18.1", - "@cspell/cspell-types": "8.18.1", - "cspell-trie-lib": "8.18.1", + "@cspell/cspell-pipe": "8.19.0", + "@cspell/cspell-types": "8.19.0", + "cspell-trie-lib": "8.19.0", "fast-equals": "^5.2.2" }, "engines": { @@ -3803,15 +3803,15 @@ } }, "node_modules/cspell-gitignore": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.18.1.tgz", - "integrity": "sha512-gp/AdUtW6FqpKY4YyYJ3kz0OsXApwsV1FOUA9Z0VnOYKVZtt2snh4uNlI4Ltq+wh7pDU8mqaPWmX6Xy+HSRDkQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.19.0.tgz", + "integrity": "sha512-iV/cbVlKeIvnyJ6PGYneQgQK+8L62dhoLbyO+9JIOiW0UBqUgEsehImn8gipfSBlgvydbUFwvN3jW4xfjAsl/Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.18.1", - "cspell-glob": "8.18.1", - "cspell-io": "8.18.1" + "@cspell/url": "8.19.0", + "cspell-glob": "8.19.0", + "cspell-io": "8.19.0" }, "bin": { "cspell-gitignore": "bin.mjs" @@ -3821,13 +3821,13 @@ } }, "node_modules/cspell-glob": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.18.1.tgz", - "integrity": "sha512-tlZXvzsN7dByHo69dz/HbJuQDUtrfhdioZ/LHaW7W9diG9NpaghgEfyX4fmsIXjU/2f66LDpYVY6osjtlOgyrg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.19.0.tgz", + "integrity": "sha512-RejVJrORHV8dbbZ0XQvzFAKlnyrFrOTwekgMapb/+FU8/fnoE9id3JZR8NUNRCjs+d4kwDBP3Jh11iSLO+9JlA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.18.1", + "@cspell/url": "8.19.0", "micromatch": "^4.0.8" }, "engines": { @@ -3835,14 +3835,14 @@ } }, "node_modules/cspell-grammar": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.18.1.tgz", - "integrity": "sha512-V6XTN1B++7EzJA0H4g4XbNJtqm6Y3/iXdLeZ6sMRDaNFKXXwTbWRtn8gukDQIytyw09AnCUKeqGSzCVqw26Omg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.19.0.tgz", + "integrity": "sha512-uMMJyiu82cxeLGFtZr6ArtIqwyRn2pZzM+O1VAOD3NMoslyx52Lij0/qrJsfCF0eobhZDU8cNdgNy99OPeMtWg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.18.1", - "@cspell/cspell-types": "8.18.1" + "@cspell/cspell-pipe": "8.19.0", + "@cspell/cspell-types": "8.19.0" }, "bin": { "cspell-grammar": "bin.mjs" @@ -3852,42 +3852,42 @@ } }, "node_modules/cspell-io": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.18.1.tgz", - "integrity": "sha512-mm9SUEF2yShuTXDSjCbsAqYTEb6jrtgcCnlqIzpsZOJOOe+zj/VyzTy2NJvOrdvR59dikdaqB75VGBMfHi804g==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.19.0.tgz", + "integrity": "sha512-F3ciuf2yEH5k1pMdRRI6z6gWyQL/UsTNbHHB5TI0meOduha20CdcgKW3bAPypUbeub6qCoNq5bYUan1LHwfswA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "8.18.1", - "@cspell/url": "8.18.1" + "@cspell/cspell-service-bus": "8.19.0", + "@cspell/url": "8.19.0" }, "engines": { "node": ">=18" } }, "node_modules/cspell-lib": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.18.1.tgz", - "integrity": "sha512-t1j+XB7515yHmrczK6I1N6j0a72vmL/6OxsMJnCucHC6DO0WkOqmHulNRH7LpFacnns0dx15lmrAqPg7gQFcIg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.19.0.tgz", + "integrity": "sha512-TyuSV2onWGwIMx+WxCcLwznYDovAV1cQ2atGhgytfe23JvJo18QEiiNd0u2T3y+WVAJvRal68mhxSdxqXLYL0w==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "8.18.1", - "@cspell/cspell-pipe": "8.18.1", - "@cspell/cspell-resolver": "8.18.1", - "@cspell/cspell-types": "8.18.1", - "@cspell/dynamic-import": "8.18.1", - "@cspell/filetypes": "8.18.1", - "@cspell/strong-weak-map": "8.18.1", - "@cspell/url": "8.18.1", + "@cspell/cspell-bundled-dicts": "8.19.0", + "@cspell/cspell-pipe": "8.19.0", + "@cspell/cspell-resolver": "8.19.0", + "@cspell/cspell-types": "8.19.0", + "@cspell/dynamic-import": "8.19.0", + "@cspell/filetypes": "8.19.0", + "@cspell/strong-weak-map": "8.19.0", + "@cspell/url": "8.19.0", "clear-module": "^4.1.2", "comment-json": "^4.2.5", - "cspell-config-lib": "8.18.1", - "cspell-dictionary": "8.18.1", - "cspell-glob": "8.18.1", - "cspell-grammar": "8.18.1", - "cspell-io": "8.18.1", - "cspell-trie-lib": "8.18.1", + "cspell-config-lib": "8.19.0", + "cspell-dictionary": "8.19.0", + "cspell-glob": "8.19.0", + "cspell-grammar": "8.19.0", + "cspell-io": "8.19.0", + "cspell-trie-lib": "8.19.0", "env-paths": "^3.0.0", "fast-equals": "^5.2.2", "gensequence": "^7.0.0", @@ -3902,14 +3902,14 @@ } }, "node_modules/cspell-trie-lib": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.18.1.tgz", - "integrity": "sha512-UaB36wsyp2eWeMtrbS6Q2t2WFvpedmGXJ879yHn9qKD7ViyUpI4cAbh6v7gWMUu+gjqCulXtke64k1ddmBihPQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.19.0.tgz", + "integrity": "sha512-ZCC8PaHRpB5c6qIIuPLVW2ZxSvc0ulAVD7MKL8fnFKSTw68asDrs7BVwLmNTi3cUkXfGXK9fdL32WtO3YOPMFw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.18.1", - "@cspell/cspell-types": "8.18.1", + "@cspell/cspell-pipe": "8.19.0", + "@cspell/cspell-types": "8.19.0", "gensequence": "^7.0.0" }, "engines": { @@ -8894,9 +8894,9 @@ } }, "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", "dev": true, "license": "ISC", "bin": { From 3facd792194687101fe092ccc8aaa711fac90edc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 05:35:57 +0000 Subject: [PATCH 021/140] chore(deps): update dependency @typescript-eslint/parser to v8.30.1 (#1773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.29.1` -> `8.30.1`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.29.1/8.30.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.30.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.30.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.29.1/8.30.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.29.1/8.30.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.30.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8301-2025-04-14) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.30.0...v8.30.1) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. ### [`v8.30.0`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8300-2025-04-14) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.29.1...v8.30.0) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9e5ece501..4910faa57c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2716,16 +2716,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz", - "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==", + "version": "8.30.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz", + "integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/typescript-estree": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", + "@typescript-eslint/scope-manager": "8.30.1", + "@typescript-eslint/types": "8.30.1", + "@typescript-eslint/typescript-estree": "8.30.1", + "@typescript-eslint/visitor-keys": "8.30.1", "debug": "^4.3.4" }, "engines": { @@ -2741,14 +2741,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz", - "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==", + "version": "8.30.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz", + "integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1" + "@typescript-eslint/types": "8.30.1", + "@typescript-eslint/visitor-keys": "8.30.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2759,9 +2759,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz", - "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==", + "version": "8.30.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz", + "integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==", "dev": true, "license": "MIT", "engines": { @@ -2773,14 +2773,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz", - "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==", + "version": "8.30.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz", + "integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", + "@typescript-eslint/types": "8.30.1", + "@typescript-eslint/visitor-keys": "8.30.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2800,13 +2800,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz", - "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==", + "version": "8.30.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz", + "integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.1", + "@typescript-eslint/types": "8.30.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { From 5b1131609416b77a2bea7b7ceb1deb59a7643585 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 05:36:17 +0000 Subject: [PATCH 022/140] chore(deps): update dependency @sap/cds to v8.9.2 (#1772) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@sap/cds](https://cap.cloud.sap/) | [`8.9.1` -> `8.9.2`](https://renovatebot.com/diffs/npm/@sap%2fcds/8.9.1/8.9.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@sap%2fcds/8.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@sap%2fcds/8.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@sap%2fcds/8.9.1/8.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@sap%2fcds/8.9.1/8.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4910faa57c..ae8efa38e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2223,9 +2223,9 @@ ] }, "node_modules/@sap/cds": { - "version": "8.9.1", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.1.tgz", - "integrity": "sha512-+KoY7Bw1Gc3vwK4X3CFCV+IAQO4QT0HRsaW/qgETeOGqjzbuf6KvUqlkDuPE5msdXwfz/EFDB9Vx9jTyTw581Q==", + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.2.tgz", + "integrity": "sha512-UeyLZp6JvT9mOMEbgMzH+MWzueQQKvzvRNBxa5Ecdp0g2IkPFMmp97xw5bvv0MeKycs1vkJqWkGPZfgI74fiOg==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { From 7719729c2c2ff2013192c69bb22f90e97c29d000 Mon Sep 17 00:00:00 2001 From: Johannes Vogt Date: Thu, 17 Apr 2025 11:53:47 +0200 Subject: [PATCH 023/140] microservice update (#1778) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - create less confusion about the working directory - move section about deployment as separate mta down as it is an alternative to the all-in-one deployment --------- Co-authored-by: RenΓ© Jeglinsky --- guides/deployment/microservices.md | 251 +++++++++++++++-------------- 1 file changed, 128 insertions(+), 123 deletions(-) diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md index fc8a2695d3..eeccfdb83f 100644 --- a/guides/deployment/microservices.md +++ b/guides/deployment/microservices.md @@ -124,28 +124,25 @@ These are the (not so beneficial) side effects you when using a shared persisten ```sh cds init shared-db --add hana - cd shared-db ``` ```sh - npm add @capire/bookstore - npm add @capire/reviews - npm add @capire/orders + npm add --workspace shared-db @capire/bookstore + npm add --workspace shared-db @capire/reviews + npm add --workspace shared-db @capire/orders ``` > Note how *NPM workspaces* allows us to use the package names of the projects, and nicely creates symlinks in *node_modules* accordingly. 2. Add a `db/schema.cds` file as a mashup to actually collect the models: - ```sh - code db/schema.cds - ``` - - ```cds + ::: code-group + ```cds [shared-db/db/schema.cds] using from '@capire/bookstore'; using from '@capire/reviews'; using from '@capire/orders'; ``` + ::: > Note: the `using` directives refer to `index.cds` files existing in the target packages. Your projects may have different entry points. @@ -193,120 +190,6 @@ The db model could also be collected on root level instead of creating a separat ::: -### Deployment as Separate MTA - -In a setup with multiple deployment units, we can add the `shared-db` project as its own MTA deployment: - -```sh -cds add mta -``` - -This adds everything necessary for a full CAP application. -Since we only want the database and database deployment, remove everything else like the srv module and destination and messaging resources: - -```yaml -_schema-version: 3.3.0 -ID: shared-db -version: 1.0.0 -description: "A simple CAP project." -parameters: - enable-parallel-deployments: true -build-parameters: - before-all: - - builder: custom - commands: - - npm ci - - npx cds build --production # [!code --] - - npx cds build --production --for hana # [!code ++] -modules: - - name: shared-db-srv # [!code --] - type: nodejs # [!code --] - path: gen/srv # [!code --] - parameters: # [!code --] - instances: 1 # [!code --] - buildpack: nodejs_buildpack # [!code --] - build-parameters: # [!code --] - builder: npm-ci # [!code --] - provides: # [!code --] - - name: srv-api # [!code --] - properties: # [!code --] - srv-url: ${default-url} # [!code --] - requires: # [!code --] - - name: shared-db-destination # [!code --] - - name: shared-db-messaging # [!code --] - - name: shared-db-db # [!code --] - - - name: shared-db-db-deployer - type: hdb - path: gen/db - parameters: - buildpack: nodejs_buildpack - requires: - - name: shared-db-db - -resources: - - name: shared-db-destination # [!code --] - type: org.cloudfoundry.managed-service # [!code --] - parameters: # [!code --] - service: destination # [!code --] - service-plan: lite # [!code --] - - name: shared-db-messaging # [!code --] - type: org.cloudfoundry.managed-service # [!code --] - parameters: # [!code --] - service: enterprise-messaging # [!code --] - service-plan: default # [!code --] - path: ./event-mesh.json # [!code --] - - name: shared-db-db - type: com.sap.xs.hdi-container - parameters: - service: hana - service-plan: hdi-shared -``` - - - - -#### Binding to a Shared Database - -The only thing left to care about is to ensure all 3+1 projects are bound and connected to the same database at deployment, subscription, and runtime. - -Configure the _mta.yaml_ of the other apps to bind to the existing shared database, for example, in the reviews module: - -```yaml [reviews/mta.yaml] -... -modules: - ... - - - name: reviews-db-deployer # [!code --] - type: hdb # [!code --] - path: gen/db # [!code --] - parameters: # [!code --] - buildpack: nodejs_buildpack # [!code --] - requires: # [!code --] - - name: reviews-db # [!code --] - -resources: - ... - - name: reviews-db - type: com.sap.xs.hdi-container # [!code --] - type: org.cloudfoundry.existing-service # [!code ++] - parameters: - service: hana # [!code --] - service-plan: hdi-shared # [!code --] - service-name: shared-db-db # [!code ++] -``` - - - -#### Subsequent updates - -- TODO... -- Whenever one of the projects has changes affecting the database that triggers a new deployment of the `shared-db` project -- `git submodules` gives you control of which versions to pull, for example by `git branches` or `git tags` -- Ensure to first deploy `shared-db` before deploying the others - - - ## All-in-one Deployment This section is about how to deploy all 3+1 projects at once with a common _mta.yaml_. @@ -908,6 +791,128 @@ You can then navigate to this url and the corresponding apps ``` +## Deployment as separate mta + +This is an alternative to the all-in-one deployment. Assume the applications each already have their own mta.yaml. For example by running `cds add mta` in the `reviews`, `orders` and `bookstore` folder. + +### Database + +We can add the [previously created](#using-a-shared-database) `shared-db` project as its own mta deployment: + +::: code-group +```sh [shared-db/] +cds add mta +``` +::: + +This adds everything necessary for a full CAP application. +Since we only want the database and database deployment, remove everything else like the srv module and destination and messaging resources: + +::: details Diff +```yaml +_schema-version: 3.3.0 +ID: shared-db +version: 1.0.0 +description: "A simple CAP project." +parameters: + enable-parallel-deployments: true +build-parameters: + before-all: + - builder: custom + commands: + - npm ci + - npx cds build --production # [!code --] + - npx cds build --production --for hana # [!code ++] +modules: + - name: shared-db-srv # [!code --] + type: nodejs # [!code --] + path: gen/srv # [!code --] + parameters: # [!code --] + instances: 1 # [!code --] + buildpack: nodejs_buildpack # [!code --] + build-parameters: # [!code --] + builder: npm-ci # [!code --] + provides: # [!code --] + - name: srv-api # [!code --] + properties: # [!code --] + srv-url: ${default-url} # [!code --] + requires: # [!code --] + - name: shared-db-destination # [!code --] + - name: shared-db-messaging # [!code --] + - name: shared-db-db # [!code --] + + - name: shared-db-db-deployer + type: hdb + path: gen/db + parameters: + buildpack: nodejs_buildpack + requires: + - name: shared-db-db + +resources: + - name: shared-db-destination # [!code --] + type: org.cloudfoundry.managed-service # [!code --] + parameters: # [!code --] + service: destination # [!code --] + service-plan: lite # [!code --] + - name: shared-db-messaging # [!code --] + type: org.cloudfoundry.managed-service # [!code --] + parameters: # [!code --] + service: enterprise-messaging # [!code --] + service-plan: default # [!code --] + path: ./event-mesh.json # [!code --] + - name: shared-db-db + type: com.sap.xs.hdi-container + parameters: + service: hana + service-plan: hdi-shared +``` +::: + + + + +#### Binding to shared database + +The only thing left to care about is to ensure all 3+1 projects are bound and connected to the same database at deployment, subscription, and runtime. + +Configure the mta.yaml of the other apps to bind to the existing shared database, for example, in the reviews module: + +```yaml [reviews/mta.yaml] +... +modules: + ... + + - name: reviews-db-deployer # [!code --] + type: hdb # [!code --] + path: gen/db # [!code --] + parameters: # [!code --] + buildpack: nodejs_buildpack # [!code --] + requires: # [!code --] + - name: reviews-db # [!code --] + +resources: + ... + - name: reviews-db + type: com.sap.xs.hdi-container # [!code --] + type: org.cloudfoundry.existing-service # [!code ++] + parameters: + service: hana # [!code --] + service-plan: hdi-shared # [!code --] + service-name: shared-db-db # [!code ++] +``` + + + +#### Subsequent updates + +- TODO... +- Whenever one of the projects has changes affecting the database, that triggers a new deployment of the `shared-db` project +- `git submodules` gives you control of which versions to pull, for example by `git branches` or `git tags` +- Ensure to first deploy `shared-db` before deploying the others + + + ## Late-Cut Microservices Microservices have been attributed with a multitude of benefits like From 20c287cc43a2a76c82bc2802e8ea780ae5f02764 Mon Sep 17 00:00:00 2001 From: Evgeny Andreev Date: Thu, 17 Apr 2025 15:28:52 +0200 Subject: [PATCH 024/140] Describe recursive hierarchies (#1770) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian GΓΆrler Co-authored-by: RenΓ© Jeglinsky --- advanced/odata.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/advanced/odata.md b/advanced/odata.md index 1710576f6d..ce0e1f6d95 100644 --- a/advanced/odata.md +++ b/advanced/odata.md @@ -1139,6 +1139,75 @@ GET SalesOrganizations?$apply= /ancestors(..., ID, filter(contains(Name, 'New York')), keep start) ``` +#### Modeling Recursive Hierarchies + +Recursive hierarchies are parent-child hierarchies, where each entity references its parent and through that defines the hierarchical structure. A common example is a company organization structure or HR reporting, where each employee entity references another employee a as direct report or manager. + +##### Domain Model + +The simplest domain model looks as follows: + +```cds +entity Employee : Hierarchy { + key ID : UUID; + parent : Association to Employee; + fullName : String; +} + +aspect Hierarchy { + virtual LimitedDescendantCount : Integer64; + virtual DistanceFromRoot : Integer64; + virtual DrillState : String; + virtual LimitedRank : Integer64; +} +``` + +The entity `Employee` has the element `ID`, which identifies the hierarchy node. The `parent` association references the same entity, which establishes the parent-child relationship. + +##### Virtual Elements of a Hierarchy + +The `Hierarchy` aspect defines a set of virtual elements, automatically calculated by the backend at runtime, to describe the state of the hierarchy. This information is requested by the UI to correctly render the hierarchy in a *TreeTable* during user interaction. + +##### Service Model + +The following service defines the projection on the domain model. + +```cds +@odata.apply.transformations +service HRService { + entity HREmployee as projection on Employee; +} +``` + +::: warning +The service must be annotated with `@odata.apply.transformations`. This instructs the Java Runtime to push down the whole transformation pipeline to the persistence layer. +::: + +##### OData v4 Annotations for Fiori + +To link the backend and Fiori UI, the projected service entity must be enriched with the following annotations. + +```cds +annotate HRService.HREmployee with @Aggregation.RecursiveHierarchy #EmployeeHierarchy: { + $Type: 'Aggregation.RecursiveHierarchyType', + NodeProperty: ID, + ParentNavigationProperty: parent +}; +``` + +Here the `EmployeeHierarchy` specifies a hierarchy qualifier, `NodeProperty` (identifying the hierarchy node) is linked to `ID` of the entity `HREmployee`, and the `ParentNavigationProperty` is linked to a corresponding `parent` association. + +```cds +annotate HRService.HREmployee with @Hierarchy.RecursiveHierarchy #EmployeeHierarchy: { + $Type: 'Hierarchy.RecursiveHierarchyType', + LimitedDescendantCount: LimitedDescendantCount, + DistanceFromRoot: DistanceFromRoot, + DrillState: DrillState, + LimitedRank: LimitedRank +}; +``` + +Here the same qualifier `EmployeeHierarchy` is referenced to list the names of the [virtual elements of the hierarchy](#virtual-elements-of-a-hierarchy). ### Aggregation Methods From fe23b363f703956feae5e3e2bd2d9280fc0cc879 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 15:38:56 +0200 Subject: [PATCH 025/140] chore(deps): update dependency com.sap.cds:cds4j-api to v3.9.1 (#1781) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.sap.cds:cds4j-api](http://www.sap.com) | `3.9.0` -> `3.9.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.sap.cds:cds4j-api/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.sap.cds:cds4j-api/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.sap.cds:cds4j-api/3.9.0/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.sap.cds:cds4j-api/3.9.0/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index fb557c0481..e94b256b39 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -107,7 +107,7 @@ config.rewrites = rewrites config.themeConfig.capire = { versions: { java_services: '3.9.0', - java_cds4j: '3.9.0' + java_cds4j: '3.9.1' }, gotoLinks: [], maven_host_base: 'https://repo1.maven.org/maven2' From 37c0b169ea5bc4ac309bf98f7d33f4adcd3b237b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 09:02:20 +0200 Subject: [PATCH 026/140] chore(deps): update dependency com.sap.cds:cds-services-api to v3.9.1 (#1783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.sap.cds:cds-services-api](https://cap.cloud.sap/docs/java) | `3.9.0` -> `3.9.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.sap.cds:cds-services-api/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.sap.cds:cds-services-api/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.sap.cds:cds-services-api/3.9.0/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.sap.cds:cds-services-api/3.9.0/3.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index e94b256b39..11bd102ea9 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -106,7 +106,7 @@ config.rewrites = rewrites // Add custom capire info to the theme config config.themeConfig.capire = { versions: { - java_services: '3.9.0', + java_services: '3.9.1', java_cds4j: '3.9.1' }, gotoLinks: [], From b5d8164b580a3b7bb1025c11ef4f0d1586821f2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:44:35 +0200 Subject: [PATCH 027/140] chore(deps): update dependency sass to v1.87.0 (#1786) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [sass](https://redirect.github.com/sass/dart-sass) | [`1.86.3` -> `1.87.0`](https://renovatebot.com/diffs/npm/sass/1.86.3/1.87.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/sass/1.87.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/sass/1.87.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/sass/1.86.3/1.87.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sass/1.86.3/1.87.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
sass/dart-sass (sass) ### [`v1.87.0`](https://redirect.github.com/sass/dart-sass/blob/HEAD/CHANGELOG.md#1870) [Compare Source](https://redirect.github.com/sass/dart-sass/compare/1.86.3...1.87.0) - **Potentially breaking bug fix:** When a plain CSS file with a top-level nesting selector `&` is loaded into a nested Sass context via `meta.load-css()` or `@import`, Sass now emits plain CSS nesting rather than incorrectly combining it with the parent selector using a descendant combinator.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ae8efa38e2..6e706fcf93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7412,9 +7412,9 @@ "peer": true }, "node_modules/sass": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.3.tgz", - "integrity": "sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==", + "version": "1.87.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.87.0.tgz", + "integrity": "sha512-d0NoFH4v6SjEK7BoX810Jsrhj7IQSYHAHLi/iSpgqKc7LaIDshFRlSg5LOymf9FqQhxEHs2W5ZQXlvy0KD45Uw==", "dev": true, "license": "MIT", "dependencies": { From e85ae1de069cfaaa8b453bf07739a60cd63eafa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:44:57 +0200 Subject: [PATCH 028/140] chore(deps): update eslint (#1785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.30.1` -> `8.31.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.30.1/8.31.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.30.1/8.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.30.1/8.31.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [eslint](https://eslint.org) ([source](https://redirect.github.com/eslint/eslint)) | [`9.24.0` -> `9.25.1`](https://renovatebot.com/diffs/npm/eslint/9.24.0/9.25.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/eslint/9.25.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint/9.25.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint/9.24.0/9.25.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint/9.24.0/9.25.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.31.0`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8310-2025-04-21) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.30.1...v8.31.0) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
eslint/eslint (eslint) ### [`v9.25.1`](https://redirect.github.com/eslint/eslint/compare/v9.25.0...3ed4b3652d9fe3dfa4017d22a6ddbd15e3c6cd7a) [Compare Source](https://redirect.github.com/eslint/eslint/compare/v9.25.0...v9.25.1) ### [`v9.25.0`](https://redirect.github.com/eslint/eslint/compare/v9.24.0...e62e26761561e1d78c6466a2d74dbf946012fddc) [Compare Source](https://redirect.github.com/eslint/eslint/compare/v9.24.0...v9.25.0)
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ‘» **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 88 +++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6e706fcf93..99008ca645 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1358,9 +1358,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.0.tgz", - "integrity": "sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", + "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1368,9 +1368,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", - "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1429,9 +1429,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", - "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", + "version": "9.25.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.1.tgz", + "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==", "dev": true, "license": "MIT", "engines": { @@ -1449,13 +1449,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", - "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.12.0", + "@eslint/core": "^0.13.0", "levn": "^0.4.1" }, "engines": { @@ -2716,16 +2716,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz", - "integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.0.tgz", + "integrity": "sha512-67kYYShjBR0jNI5vsf/c3WG4u+zDnCTHTPqVMQguffaWWFs7artgwKmfwdifl+r6XyM5LYLas/dInj2T0SgJyw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", + "@typescript-eslint/scope-manager": "8.31.0", + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/typescript-estree": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0", "debug": "^4.3.4" }, "engines": { @@ -2741,14 +2741,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz", - "integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.0.tgz", + "integrity": "sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1" + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2759,9 +2759,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz", - "integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.0.tgz", + "integrity": "sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==", "dev": true, "license": "MIT", "engines": { @@ -2773,14 +2773,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz", - "integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.0.tgz", + "integrity": "sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2800,13 +2800,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz", - "integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.0.tgz", + "integrity": "sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.30.1", + "@typescript-eslint/types": "8.31.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -4232,20 +4232,20 @@ } }, "node_modules/eslint": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", - "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", + "version": "9.25.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.1.tgz", + "integrity": "sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.0", - "@eslint/core": "^0.12.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.13.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.24.0", - "@eslint/plugin-kit": "^0.2.7", + "@eslint/js": "9.25.1", + "@eslint/plugin-kit": "^0.2.8", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", From 9e9a448da01a7ef8e184bf6b21002cb90eb25f7a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:45:13 +0200 Subject: [PATCH 029/140] chore(deps): update dependency cspell to v8.19.2 (#1784) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [cspell](https://cspell.org/) ([source](https://redirect.github.com/streetsidesoftware/cspell/tree/HEAD/packages/cspell)) | [`8.19.0` -> `8.19.2`](https://renovatebot.com/diffs/npm/cspell/8.19.0/8.19.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/cspell/8.19.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/cspell/8.19.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/cspell/8.19.0/8.19.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/cspell/8.19.0/8.19.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
streetsidesoftware/cspell (cspell) ### [`v8.19.2`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#8192-2025-04-20) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v8.19.1...v8.19.2) **Note:** Version bump only for package cspell ### [`v8.19.1`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#8191-2025-04-18) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v8.19.0...v8.19.1) **Note:** Version bump only for package cspell
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 233 ++++++++++++++++++++++++---------------------- 1 file changed, 123 insertions(+), 110 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99008ca645..c6064e0dbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -298,9 +298,9 @@ } }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.19.0.tgz", - "integrity": "sha512-ISPiC8YQr+09aGFK6VPxxygp3BOSvU/Axlvl2eCYhH+vS+3NoYWakn+UZJ6DoveIsfFWp9LpbU9/xLea8qbG4g==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.19.2.tgz", + "integrity": "sha512-17yxicBRJj/00KlZ9y3fziuY3Y8neK2PA+wzf/NhnyA6AhU60TjLGj2yocKtlg8TYBeQK2kRiKq/2Uy0tv1RKg==", "dev": true, "license": "MIT", "dependencies": { @@ -319,7 +319,7 @@ "@cspell/dict-docker": "^1.1.13", "@cspell/dict-dotnet": "^5.0.9", "@cspell/dict-elixir": "^4.0.7", - "@cspell/dict-en_us": "^4.4.1", + "@cspell/dict-en_us": "^4.4.2", "@cspell/dict-en-common-misspellings": "^2.0.10", "@cspell/dict-en-gb": "1.1.33", "@cspell/dict-filetypes": "^3.0.11", @@ -368,22 +368,22 @@ } }, "node_modules/@cspell/cspell-json-reporter": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.19.0.tgz", - "integrity": "sha512-MkpBlQizR9UxwrYhzJgz02yzgrmfyPpb+QctwKNJthscymhjufkBFnBj5cHK5fbmp+/y4jXxaX+Ew6QUFiJsNw==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.19.2.tgz", + "integrity": "sha512-vW7mybZi5TN0ejB4XY2hpXT0XSDiUduN69Gn+WZtNZYeLV3NWIH/RtzgT7VDGyKUadUeEvbemH3MdW34cCuZjA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "8.19.0" + "@cspell/cspell-types": "8.19.2" }, "engines": { "node": ">=18" } }, "node_modules/@cspell/cspell-pipe": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.19.0.tgz", - "integrity": "sha512-OtgF/oQ3n6T/qM+fIWLfhOhW0fLSPnpZGOZi7uKSCJZxnHKVk0h+7zNPlLkcDHrhxZP4Df76S9z7jU5iEC2oYA==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.19.2.tgz", + "integrity": "sha512-UF9s/bph/ELak6ZDEox9SbvPGU0giZ10jISKkR65MDg3nO7TQxm8TQB4PuNfwrt7Eybm+P10XroeXWfW5BfFmA==", "dev": true, "license": "MIT", "engines": { @@ -391,9 +391,9 @@ } }, "node_modules/@cspell/cspell-resolver": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.19.0.tgz", - "integrity": "sha512-/iA0ALPgnX9bN6Xwt5hfbmh7oTVoXNDS5k0rBZDGz+w0/zKn6T1XxPUIlkz5T2e4nSKOmmlpcNZGdroA7GdUfA==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.19.2.tgz", + "integrity": "sha512-OWm3DWJXbFKpzETmzHXQ6cu7xrOoctU2BuqeRaR2nHHmuHLBEnOeS6OOQeYfWg4vTO5uGnFblWpCBYxFdny08Q==", "dev": true, "license": "MIT", "dependencies": { @@ -404,9 +404,9 @@ } }, "node_modules/@cspell/cspell-service-bus": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.19.0.tgz", - "integrity": "sha512-L5knViQupeqBMwfP0iQ3+oDQ8s1pzRodcOR/6H2b9cGjuIFPIcsfclzuqVzzMtfptY25WCEpC735pwcfyIRnnQ==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.19.2.tgz", + "integrity": "sha512-+krdoByfZGMu7dMue4hMqRTJ/R+Lgzvz0fE9WhVdXhq6TB0EmR/y1b32fQ8XDfZQnOGpg+ZWiVbvAJp1QYmvuQ==", "dev": true, "license": "MIT", "engines": { @@ -414,9 +414,9 @@ } }, "node_modules/@cspell/cspell-types": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.19.0.tgz", - "integrity": "sha512-iWOtHogjZdRbX4zBlXRdh3+NB1DqgBD68+U70yL9+r37szMd8D5tRcm3h98yzhfbXW34zWhvfOiXvRi28SH4ng==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.19.2.tgz", + "integrity": "sha512-nmaxkoRZlHwMkUyNBHMT+vHaSUoCphS1DGAlfdkAt/vft8aisqFuH75hzcI52L4B1T8k/UYjn9BBwV1nQb14Ng==", "dev": true, "license": "MIT", "engines": { @@ -532,9 +532,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.1.tgz", - "integrity": "sha512-OqIImYIrTAg+lpS+1v/KtjI2kyiw1bD3FqGbuXUxpAc+e+pWluW7rPjsJCxTRlruKQMSCgQeK6N054XnxHdkDQ==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.2.tgz", + "integrity": "sha512-mvpv2kWayuOExCnDgvhlYDoW7gbGvGVTyuof9aFGy0+8ALYAJ2AtlvYCqzdTTKvvsYBrxAEEWFkUh75kHnHibg==", "dev": true, "license": "MIT" }, @@ -842,13 +842,13 @@ "license": "MIT" }, "node_modules/@cspell/dynamic-import": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.19.0.tgz", - "integrity": "sha512-VrgcgoSyspbXFalaFZgwQXCZQEUR/iKxyqM0R/gRQOk/cRKUnWOkaV0oRJcHhNXZra48boElWXIOlIDXiGhcJQ==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.19.2.tgz", + "integrity": "sha512-Ylsda+IrXhrIlAyGhCbc62tEk8F4MpO3u8llUQtWKhhvqbcxY+waC0d8S9u95egCACTTZIVDyrcxHX1lGg5+mw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.19.0", + "@cspell/url": "8.19.2", "import-meta-resolve": "^4.1.0" }, "engines": { @@ -856,9 +856,9 @@ } }, "node_modules/@cspell/filetypes": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.19.0.tgz", - "integrity": "sha512-fsSry1JPksv/LOcFryMPWPmudFekH5SD1UY6WJ2GL8CNryILbbSypEJNriE/hA1UtOTDEBY0bTlsj81GzfW0Ww==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.19.2.tgz", + "integrity": "sha512-GqS/N0gTcnaAcBOVdWrehI+w6e+TzLSDj+zjW0DFWAbqnFDUOI9+1XtISINzMV6apOrBg8sMmFuaqif3TqvuZw==", "dev": true, "license": "MIT", "engines": { @@ -866,9 +866,9 @@ } }, "node_modules/@cspell/strong-weak-map": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.19.0.tgz", - "integrity": "sha512-8T/jf/y5cxkizozFJqKuxB+gYhB3JFdjVZjVGKIK8KLT7ebnO1bkEKe9fbZByZxJQxLVvwIdwWE3EKr5oFNptA==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.19.2.tgz", + "integrity": "sha512-W/C6AK+z6sGOfdUsf75S/iLxyJkps8LEI/m9G/+R6RTHF4oyCGzh0JChHdnSjXrb0RpIPQjGOdwJcJOqVn/7/A==", "dev": true, "license": "MIT", "engines": { @@ -876,9 +876,9 @@ } }, "node_modules/@cspell/url": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.19.0.tgz", - "integrity": "sha512-zleyW54/TUYzlWd+5fJev17pk+jpploJnE/NwactKFmSg3VQi7AbwYWz3/hwLyRDz6cpfLKPKk4aJB6ay5QpSg==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.19.2.tgz", + "integrity": "sha512-B6NzFapXtS4DkGHhW8wGNE7u8v6Y3dMzdbvV2VxD6N0ByEiWqvsB2rW55z8e4fUOlGKLtedrBTFPPFIuSPs4Wg==", "dev": true, "license": "MIT", "engines": { @@ -3735,30 +3735,30 @@ } }, "node_modules/cspell": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.19.0.tgz", - "integrity": "sha512-3I6Cz2JZ9iJ5+/zqm1Wy5ak5LSebv/dsy8LGjQ/MlVeofsH7GLFkN/c/krCJzY/KxmgskkxzHZT4fl78/LFVdg==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.19.2.tgz", + "integrity": "sha512-CwH6eARg9nQE5WDSGFac4gde3S8L+1jhgd5rDe4enoGXqW0hBwsDvbIPCaiQTjG4KN+3u2QFxNMsX5lLBJjTmw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-json-reporter": "8.19.0", - "@cspell/cspell-pipe": "8.19.0", - "@cspell/cspell-types": "8.19.0", - "@cspell/dynamic-import": "8.19.0", - "@cspell/url": "8.19.0", + "@cspell/cspell-json-reporter": "8.19.2", + "@cspell/cspell-pipe": "8.19.2", + "@cspell/cspell-types": "8.19.2", + "@cspell/dynamic-import": "8.19.2", + "@cspell/url": "8.19.2", "chalk": "^5.4.1", "chalk-template": "^1.1.0", "commander": "^13.1.0", - "cspell-dictionary": "8.19.0", - "cspell-gitignore": "8.19.0", - "cspell-glob": "8.19.0", - "cspell-io": "8.19.0", - "cspell-lib": "8.19.0", + "cspell-dictionary": "8.19.2", + "cspell-gitignore": "8.19.2", + "cspell-glob": "8.19.2", + "cspell-io": "8.19.2", + "cspell-lib": "8.19.2", "fast-json-stable-stringify": "^2.1.0", "file-entry-cache": "^9.1.0", "get-stdin": "^9.0.0", "semver": "^7.7.1", - "tinyglobby": "^0.2.12" + "tinyglobby": "^0.2.13" }, "bin": { "cspell": "bin.mjs", @@ -3772,13 +3772,13 @@ } }, "node_modules/cspell-config-lib": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.19.0.tgz", - "integrity": "sha512-WcLOfdj2ZHXPPL3oAvqBhTQTPt3ZgErzMfR6OWwejO/19UUPe9yfr9oCENfjTTVBvsDhkqz40tawM5Y1Uh3WRQ==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.19.2.tgz", + "integrity": "sha512-FW7rYL952LSIzTpesmTw856dIV7jhKFvbH/Ug9i74/omC57vsA/caLH8SqYXS+Z2PslihBKKCU8j2aB2qiybMQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "8.19.0", + "@cspell/cspell-types": "8.19.2", "comment-json": "^4.2.5", "yaml": "^2.7.1" }, @@ -3787,15 +3787,15 @@ } }, "node_modules/cspell-dictionary": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.19.0.tgz", - "integrity": "sha512-kbJf5IiJu5l3jnobSvGx0q0PlkK12q9Z2g3bLSvatw/iEleiZ7xsA7Yy1jf3AL+iB1gHxXqCZMEUulFSfT0JZA==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.19.2.tgz", + "integrity": "sha512-YEVM61V0d4TmxB0Dtk3L5I7Rz3WA8Y4vjxO7rPX2piieMwp7T7l4aHb/ZpHx7JqsJSSzp9vjtgVrwVE0gCJpZw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.19.0", - "@cspell/cspell-types": "8.19.0", - "cspell-trie-lib": "8.19.0", + "@cspell/cspell-pipe": "8.19.2", + "@cspell/cspell-types": "8.19.2", + "cspell-trie-lib": "8.19.2", "fast-equals": "^5.2.2" }, "engines": { @@ -3803,15 +3803,15 @@ } }, "node_modules/cspell-gitignore": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.19.0.tgz", - "integrity": "sha512-iV/cbVlKeIvnyJ6PGYneQgQK+8L62dhoLbyO+9JIOiW0UBqUgEsehImn8gipfSBlgvydbUFwvN3jW4xfjAsl/Q==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.19.2.tgz", + "integrity": "sha512-GxWHMow+o5RqVYw9WjIbExiWE1abnF0PqrbVh3gcwCoM/xYTBfGUDBnpD/PQB4uqH1oDolMfu1wp5/J1D97OFw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.19.0", - "cspell-glob": "8.19.0", - "cspell-io": "8.19.0" + "@cspell/url": "8.19.2", + "cspell-glob": "8.19.2", + "cspell-io": "8.19.2" }, "bin": { "cspell-gitignore": "bin.mjs" @@ -3821,28 +3821,41 @@ } }, "node_modules/cspell-glob": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.19.0.tgz", - "integrity": "sha512-RejVJrORHV8dbbZ0XQvzFAKlnyrFrOTwekgMapb/+FU8/fnoE9id3JZR8NUNRCjs+d4kwDBP3Jh11iSLO+9JlA==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.19.2.tgz", + "integrity": "sha512-5/UBFLMh+3vhAyI3ep4Oqrt0rAb1mQHXmmpwk+WDpiS9CoSjoATIvibH5Ln9riwiIt1Bo7lH0BqfEQ3NtcegUg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.19.0", - "micromatch": "^4.0.8" + "@cspell/url": "8.19.2", + "picomatch": "^4.0.2" }, "engines": { "node": ">=18" } }, + "node_modules/cspell-glob/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/cspell-grammar": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.19.0.tgz", - "integrity": "sha512-uMMJyiu82cxeLGFtZr6ArtIqwyRn2pZzM+O1VAOD3NMoslyx52Lij0/qrJsfCF0eobhZDU8cNdgNy99OPeMtWg==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.19.2.tgz", + "integrity": "sha512-jrgMWIivZ9HFLXqdkR5eQ7tmvePYYnFRy4Hs1VGpCr36DqPcrURxtONFJuLCJwKl0xRSlhPIeC8fpIeEwtxUvQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.19.0", - "@cspell/cspell-types": "8.19.0" + "@cspell/cspell-pipe": "8.19.2", + "@cspell/cspell-types": "8.19.2" }, "bin": { "cspell-grammar": "bin.mjs" @@ -3852,42 +3865,42 @@ } }, "node_modules/cspell-io": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.19.0.tgz", - "integrity": "sha512-F3ciuf2yEH5k1pMdRRI6z6gWyQL/UsTNbHHB5TI0meOduha20CdcgKW3bAPypUbeub6qCoNq5bYUan1LHwfswA==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.19.2.tgz", + "integrity": "sha512-qt0QaUCw1/atoA960ev8z2ryT5+vGpXYcp71bzE52PPBACW2vKhwlBfc/4YpCC8pcNQGj6N9hzEX+G6nDTHnUw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "8.19.0", - "@cspell/url": "8.19.0" + "@cspell/cspell-service-bus": "8.19.2", + "@cspell/url": "8.19.2" }, "engines": { "node": ">=18" } }, "node_modules/cspell-lib": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.19.0.tgz", - "integrity": "sha512-TyuSV2onWGwIMx+WxCcLwznYDovAV1cQ2atGhgytfe23JvJo18QEiiNd0u2T3y+WVAJvRal68mhxSdxqXLYL0w==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.19.2.tgz", + "integrity": "sha512-we1IeovendX+vRhdOQpOdwFX7CRxLDMMGcm0Sy6Duo66IKerPYeSJwbTfQi8G8e5ZIU14F0psnjoBaOBcqpLrg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "8.19.0", - "@cspell/cspell-pipe": "8.19.0", - "@cspell/cspell-resolver": "8.19.0", - "@cspell/cspell-types": "8.19.0", - "@cspell/dynamic-import": "8.19.0", - "@cspell/filetypes": "8.19.0", - "@cspell/strong-weak-map": "8.19.0", - "@cspell/url": "8.19.0", + "@cspell/cspell-bundled-dicts": "8.19.2", + "@cspell/cspell-pipe": "8.19.2", + "@cspell/cspell-resolver": "8.19.2", + "@cspell/cspell-types": "8.19.2", + "@cspell/dynamic-import": "8.19.2", + "@cspell/filetypes": "8.19.2", + "@cspell/strong-weak-map": "8.19.2", + "@cspell/url": "8.19.2", "clear-module": "^4.1.2", "comment-json": "^4.2.5", - "cspell-config-lib": "8.19.0", - "cspell-dictionary": "8.19.0", - "cspell-glob": "8.19.0", - "cspell-grammar": "8.19.0", - "cspell-io": "8.19.0", - "cspell-trie-lib": "8.19.0", + "cspell-config-lib": "8.19.2", + "cspell-dictionary": "8.19.2", + "cspell-glob": "8.19.2", + "cspell-grammar": "8.19.2", + "cspell-io": "8.19.2", + "cspell-trie-lib": "8.19.2", "env-paths": "^3.0.0", "fast-equals": "^5.2.2", "gensequence": "^7.0.0", @@ -3902,14 +3915,14 @@ } }, "node_modules/cspell-trie-lib": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.19.0.tgz", - "integrity": "sha512-ZCC8PaHRpB5c6qIIuPLVW2ZxSvc0ulAVD7MKL8fnFKSTw68asDrs7BVwLmNTi3cUkXfGXK9fdL32WtO3YOPMFw==", + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.19.2.tgz", + "integrity": "sha512-/0DuCmBwz1B3yOlxCgib98uVVdIBOp/PNWEA3pmmjPOiWvOb/bBdw5C5o+ghnf93scDZQJF3l8a2sAQmsZkkIw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.19.0", - "@cspell/cspell-types": "8.19.0", + "@cspell/cspell-pipe": "8.19.2", + "@cspell/cspell-types": "8.19.2", "gensequence": "^7.0.0" }, "engines": { @@ -8000,13 +8013,13 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2" }, "engines": { @@ -8017,9 +8030,9 @@ } }, "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", "dev": true, "license": "MIT", "peerDependencies": { From e113301c46684eb2e9389c68eddc9f3b6c37a443 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 22:16:24 +0200 Subject: [PATCH 030/140] chore: Update CLI texts (#1787) Updates the output of cds CLI texts to the latest version. Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com> --- tools/assets/help/cds-version-md.out.md | 8 ++++---- tools/assets/help/cds-version.out.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index 1c7f521569..9aacbcb187 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -6,15 +6,15 @@ | ---------------------- | --------------------------------------- | | @cap-js/asyncapi | 1.0.3 | | @cap-js/cds-types | 0.10.0 | -| @cap-js/db-service | 1.19.1 | +| @cap-js/db-service | 1.20.0 | | @cap-js/openapi | 1.2.1 | -| @cap-js/sqlite | 1.10.0 | +| @cap-js/sqlite | 1.11.0 | | @sap/cds | 8.9.2 | | @sap/cds-compiler | 5.9.2 | -| @sap/cds-dk (global) | 8.9.1 | +| @sap/cds-dk (global) | 8.9.2 | | @sap/cds-fiori | 1.4.1 | | @sap/cds-foss | 5.0.1 | -| @sap/cds-mtxs | 2.7.0 | +| @sap/cds-mtxs | 2.7.1 | | @sap/eslint-plugin-cds | 3.2.0 | | Node.js | v20.19.0 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 9547cfb612..0f8a9dc373 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -4,15 +4,15 @@ @cap-js/asyncapi: 1.0.3 @cap-js/cds-types: 0.10.0 -@cap-js/db-service: 1.19.1 +@cap-js/db-service: 1.20.0 @cap-js/openapi: 1.2.1 -@cap-js/sqlite: 1.10.0 +@cap-js/sqlite: 1.11.0 @sap/cds: 8.9.2 @sap/cds-compiler: 5.9.2 -@sap/cds-dk (global): 8.9.1 +@sap/cds-dk (global): 8.9.2 @sap/cds-fiori: 1.4.1 @sap/cds-foss: 5.0.1 -@sap/cds-mtxs: 2.7.0 +@sap/cds-mtxs: 2.7.1 @sap/eslint-plugin-cds: 3.2.0 Node.js: v20.19.0 your-project: 1.0.0 From 49eae8f28a7f5206225b6c97da32ac23d7252706 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Thu, 24 Apr 2025 22:18:05 +0200 Subject: [PATCH 031/140] Examples for Node server events (#1777) Co-authored-by: Christian Georgi --- node.js/cds-server.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/node.js/cds-server.md b/node.js/cds-server.md index 3941dddfec..1eff4af427 100644 --- a/node.js/cds-server.md +++ b/node.js/cds-server.md @@ -178,19 +178,32 @@ cds.on('bootstrap', app => { Emitted whenever a CDS model got loaded using `cds.load()` +```js twoslash +// @noErrors +const cds = require('@sap/cds') +cds.on('loaded', model => { /* ... */ }) +``` ### connect {.event} Emitted for each service constructed through [`cds.connect`](cds-connect). - +```js twoslash +// @noErrors +const cds = require('@sap/cds') +cds.on('connect', service => { /* ... */ }) +``` ### serving {.event} Emitted for each service constructed by [`cds.serve`](cds-serve). - +```js twoslash +// @noErrors +const cds = require('@sap/cds') +cds.on('serving', service => { /* ... */ }) +``` ### served {.event} @@ -199,7 +212,7 @@ A one-time event, emitted when all services have been bootstrapped and added to ```js twoslash // @noErrors const cds = require('@sap/cds') -cds.on('served', (services)=>{ +cds.on('served', async (services) => { // We can savely access service instances through the provided argument: const { CatalogService, db } = services // ... @@ -213,6 +226,11 @@ This event supports _asynchronous_ event handlers. A one-time event, emitted when the server has been started and is listening to incoming requests. +```js twoslash +// @noErrors +const cds = require('@sap/cds') +cds.on('listening', ({ server, url }) => { /* ... */ }) +``` ### shutdown {.event} @@ -221,6 +239,11 @@ A one-time event, emitted when the server is closed and/or the process finishes. This event supports _asynchronous_ event handlers. +```js twoslash +// @noErrors +const cds = require('@sap/cds') +cds.on('shutdown', async () => { /* ... */ }) +``` From f9925f899df6f7b99f7ac550175b064521b8608b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:01:58 +0200 Subject: [PATCH 032/140] chore: Update CLI texts (#1802) Updates the output of cds CLI texts to the latest version. Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com> --- tools/assets/help/cds-version-md.out.md | 4 ++-- tools/assets/help/cds-version.out.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index 9aacbcb187..a85dfd0428 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -11,10 +11,10 @@ | @cap-js/sqlite | 1.11.0 | | @sap/cds | 8.9.2 | | @sap/cds-compiler | 5.9.2 | -| @sap/cds-dk (global) | 8.9.2 | +| @sap/cds-dk (global) | 8.9.3 | | @sap/cds-fiori | 1.4.1 | | @sap/cds-foss | 5.0.1 | -| @sap/cds-mtxs | 2.7.1 | +| @sap/cds-mtxs | 2.7.2 | | @sap/eslint-plugin-cds | 3.2.0 | | Node.js | v20.19.0 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 0f8a9dc373..bd58d55299 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -9,10 +9,10 @@ @cap-js/sqlite: 1.11.0 @sap/cds: 8.9.2 @sap/cds-compiler: 5.9.2 -@sap/cds-dk (global): 8.9.2 +@sap/cds-dk (global): 8.9.3 @sap/cds-fiori: 1.4.1 @sap/cds-foss: 5.0.1 -@sap/cds-mtxs: 2.7.1 +@sap/cds-mtxs: 2.7.2 @sap/eslint-plugin-cds: 3.2.0 Node.js: v20.19.0 your-project: 1.0.0 From 9d8c9c4dc796ca5549bd4670059bdb2e740cc519 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:02:17 +0200 Subject: [PATCH 033/140] chore(deps): update dependency @typescript-eslint/parser to v8.31.1 (#1799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.31.0` -> `8.31.1`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.31.0/8.31.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.31.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.31.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.31.0/8.31.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.31.0/8.31.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.31.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8311-2025-04-28) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.31.0...v8.31.1) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index c6064e0dbd..4a240a3008 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2716,16 +2716,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.0.tgz", - "integrity": "sha512-67kYYShjBR0jNI5vsf/c3WG4u+zDnCTHTPqVMQguffaWWFs7artgwKmfwdifl+r6XyM5LYLas/dInj2T0SgJyw==", + "version": "8.31.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.1.tgz", + "integrity": "sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.31.0", - "@typescript-eslint/types": "8.31.0", - "@typescript-eslint/typescript-estree": "8.31.0", - "@typescript-eslint/visitor-keys": "8.31.0", + "@typescript-eslint/scope-manager": "8.31.1", + "@typescript-eslint/types": "8.31.1", + "@typescript-eslint/typescript-estree": "8.31.1", + "@typescript-eslint/visitor-keys": "8.31.1", "debug": "^4.3.4" }, "engines": { @@ -2741,14 +2741,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.0.tgz", - "integrity": "sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==", + "version": "8.31.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz", + "integrity": "sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.31.0", - "@typescript-eslint/visitor-keys": "8.31.0" + "@typescript-eslint/types": "8.31.1", + "@typescript-eslint/visitor-keys": "8.31.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2759,9 +2759,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.0.tgz", - "integrity": "sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==", + "version": "8.31.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.1.tgz", + "integrity": "sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ==", "dev": true, "license": "MIT", "engines": { @@ -2773,14 +2773,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.0.tgz", - "integrity": "sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==", + "version": "8.31.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz", + "integrity": "sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.31.0", - "@typescript-eslint/visitor-keys": "8.31.0", + "@typescript-eslint/types": "8.31.1", + "@typescript-eslint/visitor-keys": "8.31.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2800,13 +2800,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.0.tgz", - "integrity": "sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==", + "version": "8.31.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz", + "integrity": "sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/types": "8.31.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { From b1c7be41f981d9478a2548ce9c554065869f08be Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Wed, 30 Apr 2025 13:08:08 +0200 Subject: [PATCH 034/140] Use `cds up` in multitenancy guide (#1803) --- guides/multitenancy/index.md | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/guides/multitenancy/index.md b/guides/multitenancy/index.md index a183ac8d28..1bb34e78a8 100644 --- a/guides/multitenancy/index.md +++ b/guides/multitenancy/index.md @@ -751,33 +751,15 @@ Add the following snippet to your _xs-security.json_ and adapt it to the landsca [Learn more about configured BTP services for SaaS applications.](#behind-the-scenes){.learn-more} -[Freeze the `npm` dependencies](../deployment/to-cf#freeze-dependencies) for server and MTX sidecar. - -```sh -npm update --package-lock-only -npm update --package-lock-only --prefix mtx/sidecar -``` - -In addition, you need install and freeze dependencies for your UI applications: -```sh -npm i --prefix app/browse -npm i --prefix app/admin-books -``` - -**Build and deploy**: ::: code-group ```sh [Cloud Foundry] -mbt build -t gen --mtar mta.tar -cf deploy gen/mta.tar +cds up ``` ```sh [Kyma] -# Omit `--push` flag for testing, otherwise `ctz` -# will push images to the specified repository -ctz containerize.yaml --push -helm upgrade --install bookshop ./chart +cds up --to k8s ``` ::: @@ -1049,10 +1031,11 @@ The Boolean values in the _mtx/sidecar/package.json_ activate the default config ### Additional Services -If your CAP Java application uses a service that isn't supported out of the box, you can add a custom dependency by providing a custom handler. Refer to [Define Dependent Services](../../java/multitenancy#define-dependent-services) for details. +In **CAP Java**, if your application uses a service that isn't supported out of the box, you can define dependencies by providing a custom handler. +[Learn more about defining dependent services](../../java/multitenancy#define-dependent-services){.learn-more} -In Node.js, you can use the `subscriptionDependency` setting to provide a dependency configuration similar to the standard configuration shown before. Use your application's or CAP plugin's _package.json_: +In **CAP Node.js**, you can use a custom `subscriptionDependency` entry in your application's or CAP plugin's _package.json_: ```json [package.json] "cds": { @@ -1068,7 +1051,6 @@ In Node.js, you can use the `subscriptionDependency` setting to provide a depend Alternatively, overriding the [`dependencies`](./mtxs#get-dependencies) handler gives you full flexibility for any custom implementation. -
## Add Custom Handlers From 03a1dc0a91269898dd850e865e2d8f118f30d45a Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Wed, 30 Apr 2025 16:50:56 +0200 Subject: [PATCH 035/140] Fix 404 link in Java testing guide (#1806) For https://github.com/cap-js/docs/issues/1801 --- java/developing-applications/testing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/developing-applications/testing.md b/java/developing-applications/testing.md index 8961ef7702..b3effe384b 100644 --- a/java/developing-applications/testing.md +++ b/java/developing-applications/testing.md @@ -21,7 +21,7 @@ As described in [Modular Architecture](building#starter-bundles#modular_architec Typical areas that require testing are the [services](../cqn-services/#cdsservices) that dispatch events to [event handlers](../event-handlers/), the event handlers themselves that implement the behaviour of the services, and finally the APIs that the application services define and that are exposed to clients through [OData](../cqn-services/application-services#odata-requests). ::: tip -Aside from [JUnit](https://junit.org/junit5/), the [Spring framework](https://docs.spring.io/spring-framework/docs/current/reference/html/index.html) provides much convenience for both unit and integration testing, like dependency injection via [*autowiring*](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-autowire) or the usage of [MockMvc](https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#spring-mvc-test-framework) and [*mocked users*]( https://docs.spring.io/spring-security/reference/servlet/test/method.html#test-method-withmockuser). So whenever possible, it's recommended to use it for writing tests. +Aside from [JUnit](https://junit.org/junit5/), the [Spring framework](https://docs.spring.io/spring-framework/docs/current/reference/html/index.html) provides much convenience for both unit and integration testing, like dependency injection via [*autowiring*](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-autowire) or the usage of [MockMvc](https://docs.spring.io/spring-framework/reference/testing/mockmvc.html) and [*mocked users*](https://docs.spring.io/spring-security/reference/servlet/test/method.html#test-method-withmockuser). So whenever possible, it's recommended to use it for writing tests. ::: ## Sample Tests @@ -222,7 +222,7 @@ For a more extensive version of the previous `CatalogServiceTest` snippets, have Integration tests enable us to verify the behavior of a custom event handler execution doing a roundtrip starting at the protocol adapter layer and going through the whole CAP architecture until it reaches the service and event handler layer and then back again through the protocol adapter. -As the services defined in our `CDS model` are exposed as `OData` endpoints, by using [MockMvc](https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#spring-mvc-test-framework) we can simply invoke a specific `OData` request and assert the response from the addressed service. +As the services defined in our `CDS model` are exposed as `OData` endpoints, by using [MockMvc](https://docs.spring.io/spring-framework/reference/testing/mockmvc.html) we can simply invoke a specific `OData` request and assert the response from the addressed service. The following demonstrates this by invoking a `GET` request to the `OData` endpoint of our `Books` entity, which triggers the execution of the `discountBooks` method of the `CatalogServiceHandler` in our example: @@ -254,4 +254,4 @@ public class CatalogServiceITest { ::: tip Check out the version in our [CAP Java bookshop sample project](https://github.com/SAP-samples/cloud-cap-samples-java/blob/main/srv/src/test/java/my/bookshop/CatalogServiceITest.java) for additional examples of integration testing. -::: \ No newline at end of file +::: From d746ec878839fa25fb7e6a998fe48f74321911e5 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Tue, 6 May 2025 10:55:47 +0200 Subject: [PATCH 036/140] Add `cds add ias` and `cds add ams` to feature list (#1812) --- tools/cds-cli.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cds-cli.md b/tools/cds-cli.md index e4678ad121..d4e986bd99 100644 --- a/tools/cds-cli.md +++ b/tools/cds-cli.md @@ -127,6 +127,8 @@ The facets built into `@sap/cds-dk` provide you with a large set of standard fea | `toggles` | | | | `extensibility` | | | | `xsuaa` | | | +| `ias` | | | +| `ams` | | | | `hana` | | | | `postgres` | 1 | 1 | | `sqlite` | | | From 2d1dd5e03571aa4767420d6677858a252bad0703 Mon Sep 17 00:00:00 2001 From: Patrice Bender Date: Tue, 6 May 2025 11:04:09 +0200 Subject: [PATCH 037/140] feat: standard database functions everywhere (#1750) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cds-compiler and the node database services now are on-par with regard to the supported standard database functions. With this change we move the standard database function section out of the "runtime" part. Once CAP Java closed the gap, we can remove the disclaimer that this is only available for cds-compiler + node database services --------- Co-authored-by: RenΓ© Jeglinsky --- guides/databases.md | 252 ++++++++++++++++++++++++++++++++------------ 1 file changed, 183 insertions(+), 69 deletions(-) diff --git a/guides/databases.md b/guides/databases.md index 5e2979bf34..ab2325c957 100644 --- a/guides/databases.md +++ b/guides/databases.md @@ -22,13 +22,13 @@ impl-variants: true
-### Migrating to New Database Services? {.node} +### Migrating to the `@cap-js/` Database Services? {.node} -With CDS 8, the new database services for SQLite, PostgreSQL, and SAP HANA are now generally available. It's highly recommended to migrate. You can find instructions in the [migration guide](databases-sqlite#migration). Although the guide is written in the context of the new SQLite Service, the same hints apply to PostgreSQL and SAP HANA. +With CDS 8, the [`@cap-js`](https://github.com/cap-js/cds-dbs) database services for SQLite, PostgreSQL, and SAP HANA are generally available. It's highly recommended to migrate. You can find instructions in the [migration guide](databases-sqlite#migration). Although the guide is written in the context of the SQLite Service, the same hints apply to PostgreSQL and SAP HANA. ### Adding Database Packages {.node} -Following are cds-plugin packages for CAP Node.js runtime that support respective databases: +Following are cds-plugin packages for CAP Node.js runtime that support the respective databases: | Database | Package | Remarks | | ------------------------------ | ------------------------------------------------------------ | ---------------------------------- | @@ -37,7 +37,7 @@ Following are cds-plugin packages for CAP Node.js runtime that support respectiv | **[PostgreSQL](databases-postgres)** | [`@cap-js/postgres`](https://www.npmjs.com/package/@cap-js/postgres) | maintained by community + CAP team | -> Follow the links above to find specific information for each. +> Follow the preceding links to find specific information for each. In general, all you need to do is to install one of the database packages, as follows: @@ -345,7 +345,7 @@ Select.from(AUTHOR) ### Standard Operators {.node} -The database services guarantee identical behavior of these operators: +The database services guarantee the identical behavior of these operators: * `==`, `=` β€” with `=` null being translated to `is null` * `!=`, `<>` β€” with `!=` translated to `IS NOT` in SQLite, or to `IS DISTINCT FROM` in standard SQL, or to an equivalent polyfill in SAP HANA @@ -358,67 +358,10 @@ The operator mappings are available for runtime queries only, but not in CDS fil ::: -### Functions Mappings for Runtime Queries {.node} - -A specified set of standard functions is supported in a **database-agnostic**, hence portable way, and translated to database-specific variants or polyfills. -Note that these functions are only supported within runtime queries, but not in CDS files. -This set of functions are by large the same as specified in OData: - -* `concat(x,y,...)` β€” concatenates the given strings or numbers -* `trim(x)` β€” removes leading and trailing whitespaces -* `contains(x,y)` β€” checks whether `y` is contained in `x`, may be fuzzy -* `startswith(x,y)` β€” checks whether `y` starts with `x` -* `endswith(x,y)` β€” checks whether `y` ends with `x` -* `matchespattern(x,y)` β€” checks whether `x` matches regex `y` -* `substring(x,i,n?)` 1 β€” - Extracts a substring from `x` starting at index `i` (0-based) with optional length `n`. - * **`i`**: Positive starts at `i`, negative starts `i` before the end. - * **`n`**: Positive extracts `n` items; omitted extracts to the end; negative is invalid. -* `indexof(x,y)` 1 β€” returns the index of the first occurrence of `y` in `x` -* `length(x)` β€” returns the length of string `x` -* `tolower(x)` β€” returns all-lowercased `x` -* `toupper(x)` β€” returns all-uppercased `x` -* `ceiling(x)` β€” rounds the input numeric parameter up to the nearest numeric value -* `floor(x)` β€” rounds the input numeric parameter down to the nearest numeric value -* `round(x)` β€” rounds the input numeric parameter to the nearest numeric value. - The mid-point between two integers is rounded away from zero, i.e. 0.5 is rounded to 1 and ‑0.5 is rounded to -1. -* `year(x)` `month(x)`, `day(x)`, `hour(x)`, `minute(x)`, `second(x)` β€” - returns parts of a datetime for a given `cds.DateTime` / `cds.Date` / `cds.Time` -* `time(x)`, `date(x)` - returns a string representing the `time` / `date` for a given `cds.DateTime` / `cds.Date` / `cds.Time` -* `fractionalseconds(x)` - returns a a `Decimal` representing the fractions of a second for a given `cds.Timestamp` -* `maxdatetime()` - returns the latest possible point in time: `'9999-12-31T23:59:59.999Z'` -* `mindatetime()` β€” returns the earliest possible point in time: `'0001-01-01T00:00:00.000Z'` -* `totalseconds(x)` β€” returns the duration of the value in total seconds, including fractional seconds. The [OData spec](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_totalseconds) defines the input as EDM.Duration: `P12DT23H59M59.999999999999S` -* `now()` β€” returns the current datetime -* `min(x)` `max(x)` `sum(x)` `average(x)` `count(x)`, `countdistinct(x)` β€” aggregate functions -* `search(xs,y)` β€” checks whether `y` is contained in any of `xs`, may be fuzzy β†’ [see Searching Data](../guides/providing-services#searching-data) -* `session_context(v)` β€” with standard variable names β†’ [see Session Variables](#session-variables) -> 1 These functions work zero-based. E.g., `substring('abcdef', 1, 3)` returns 'bcd' - -> You have to write these functions exactly as given; all-uppercase usages aren't supported. - -In addition to the standard functions, which all `@cap-js` database services support, `@cap-js/sqlite` and `@cap-js/postgres` also support these common SAP HANA functions, to further increase the scope for portable testing: - -* `years_between` β€” Computes the number of years between two specified dates. -* `months_between` β€” Computes the number of months between two specified dates. -* `days_between` β€” Computes the number of days between two specified dates. -* `seconds_between` β€” Computes the number of seconds between two specified dates. -* `nano100_between` β€” Computes the time difference between two dates to the precision of 0.1 microseconds. - -The database service implementation translates these to the best-possible native SQL functions, thus enhancing the extent of **portable** queries. -With open source and the new database service architecture, we also have methods in place to enhance this list by custom implementation. - -> For the SAP HANA functions, both usages are allowed: all-lowercase as given above, as well as all-uppercase. - -::: warning Runtime Only -The function mappings are available for runtime queries only, but not in CDS files. -::: - - ### Session Variables {.node} -The API shown below, which includes the function `session_context()` and specific pseudo variable names, is supported by **all** new database services, that is, *SQLite*, *PostgreSQL* and *SAP HANA*. -This allows you to write respective code once and run it on all these databases: +The API shown after this, which includes the function `session_context()` and specific pseudo variable names, is supported by **all** new database services, that is, *SQLite*, *PostgreSQL* and *SAP HANA*. +This allows you to write the respective code once and run it on all these databases: ```sql SELECT session_context('$user.id') @@ -454,7 +397,7 @@ db.queryForList("SELECT from sqlite_schema where name like ?", name); ### Reading `LargeBinary` / BLOB {.node} -Formerly, `LargeBinary` elements (or BLOBs) were always returned as any other data type. Now, they are skipped from `SELECT *` queries. Yet, you can still enforce reading BLOBs by explicitly selecting them. Then the BLOB properties are returned as readable streams. +Formerly, `LargeBinary` elements (or BLOBs) were always returned as any other data type. Now, they're skipped from `SELECT *` queries. Yet, you can still enforce reading BLOBs by explicitly selecting them. Then the BLOB properties are returned as readable streams. ```js SELECT.from(Books) //> [{ ID, title, ..., image1, image2 }] // [!code --] @@ -481,7 +424,7 @@ You can also do this manually with the CLI command `cds compile --to `. When you've created a CAP Java application with `cds init --java` or with CAP Java's [Maven archetype](../java/developing-applications/building#the-maven-archetype), the Maven build invokes the CDS compiler to generate a `schema.sql` file for your target database. In the `default` profile (development mode), an in-memory database is [initialized by Spring](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-initialization) and the schema is bootstrapped from the `schema.sql` file. -[Learn more about adding an inital database schema.](../java/cqn-services/persistence-services#initial-database-schema){.learn-more} +[Learn more about adding an initial database schema.](../java/cqn-services/persistence-services#initial-database-schema){.learn-more}
@@ -791,7 +734,7 @@ The following rules apply: - If you refer to a column name in the annotation, you need to take care of a potential name mapping yourself, for example, for structured elements. -- Annotation `@sql.prepend` is only supported for entities translating to tables. It can't be used with views nor with elements. +- Annotation `@sql.prepend` is only supported for entities translating to tables. It can't be used with views or with elements. - For SAP HANA tables, there's an implicit `@sql.prepend: 'COLUMN'` that is overwritten by an explicitly provided `@sql.prepend`. * Both `@sql.prepend` and `@sql.append` are disallowed in SaaS extension projects. @@ -823,7 +766,7 @@ ROW TABLE E ( [Learn more about Columnar and Row-Based Data Storage](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-administration-guide/columnar-and-row-based-data-storage){.learn-more} ### Reserved Words -The CDS compiler and CAP runtimes provide smart quoting for reserved words in SQLite and in SAP HANA so that they can still be used in most situations. But in general reserved words cannot be used as identifiers. The list of reserved words varies per database. +The CDS compiler and CAP runtimes provide smart quoting for reserved words in SQLite and in SAP HANA so that they can still be used in most situations. But in general reserved words can't be used as identifiers. The list of reserved words varies per database. Find here a collection of resources on selected databases and their reference documentation: @@ -940,7 +883,178 @@ Instead, they protect the integrity of your data in the database layer against p β†’ Use [`@assert.target`](providing-services#assert-target) for corresponding input validations. ::: +## Standard Database Functions +{ #functions-mappings-for-runtime-queries } + +A specified set of standard functions - inspired by [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions) and [SAP HANA](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/alphabetical-list-of-functions?locale=en-US) - is supported in a **database-agnostic**, hence portable way, and translated to the best-possible native SQL functions or polyfills. + +Those functions are automatically mapped during runtime (Node.js) already today. +To switch on the same mappings for your CDL files, you have to set: + +cds.cdsc.standardDatabaseFunctions = true + +::: tip +this will be the default starting with `@sap/cds-compiler >= 9` and hence is only needed for earlier versions. +::: + + + +### OData standard functions + +The `@sap/cds-compiler` and all CAP Node.js database services come with out of the box support for common OData functions. + +::: warning Case Sensitivity +The OData function mappings are case-sensitive and must be written as in the list below. +::: + +Assuming you have the following entity definition: + +```cds +entity V as select from Books { + startswith(title, 'Raven') as lowerCase, // mapped to native SQL equivalent + startsWith(title, 'Raven') as camelCase, // passed as-is +} +``` + + +Then you compile the SAP HANA artifacts: + +`$ cds compile -2 sql --dialect hana` + + +This is the result: + +```sql +CREATE VIEW V AS SELECT + (CASE WHEN locate(title, 'Raven') = 1 THEN TRUE ELSE FALSE END) AS lowerCase, + -- the below will most likely fail on SAP HANA + startsWith(title, 'Raven') AS camelCase +FROM Books; +``` + +πŸ’‘ If you want to use a DB native function or a UDF (User-Defined Function) instead of the OData function mappings, you can +do that by using a different casing than the OData function names as defined in the list below. +For example, `startsWith` instead of `startswith` will be passed as-is to the database. + +#### String Functions + +- `concat(x, y, ...)` + Concatenates the given strings or numbers. + +- `trim(x)` + Removes leading and trailing whitespaces. + +- `contains(x, y)` + Checks whether `y` is contained in `x` (case-sensitive). + +- `startswith(x, y)` + Checks whether `y` starts with `x` (case-sensitive). + +- `endswith(x, y)` + Checks whether `y` ends with `x` (case-sensitive). + +- `matchespattern(x, y)` + Checks whether `x` matches the regular expression `y`. + +- `indexof(x, y)` 1 + Returns the index of the first occurrence of `y` in `x` (case-sensitive). + +- `substring(x, i, n?)` 1 + Extracts a substring from `x` starting at index `i` (0-based) with an optional length `n`. + + | Parameter | Positive | Negative | Omitted + | --- | --- | --- | -- | + | `i` | starts at index `i` | starts `i` positions before the end | + | `n` | extracts `n` characters | invalid | extracts until the end of the string + +- `length(x)` + Returns the length of the string `x`. + +- `tolower(x)` + Converts all characters in `x` to lowercase. + +- `toupper(x)` + Converts all characters in `x` to uppercase. + +> 1 These functions work zero-based. For example, `substring('abcdef', 1, 3)` returns 'bcd' + +#### Numeric Functions + +- `ceiling(x)` + Rounds the numeric parameter up to the nearest integer. + +- `floor(x)` + Rounds the numeric parameter down to the nearest integer. + +- `round(x)` + Rounds the numeric parameter to the nearest integer. + The midpoint between two integers is rounded away from zero (e.g., `0.5` β†’ `1` and `-0.5` β†’ `-1`). + + ::: warning `round` function with more than one argument + Note that most databases support `round` functions with multiple arguments, + the second parameter being the precision. SAP HANA even has a third argument which is the rounding mode. + If you provide more than one argument, the `round` function may behave differently depending on the database. + ::: + +#### Date and Time Functions + +- `year(x)`, `month(x)`, `day(x)`, `hour(x)`, `minute(x)`, `second(x)` + Extracts and returns specific date / time parts as integer value from a given `cds.DateTime`, `cds.Date`, or `cds.Time`. + +- `time(x)`, `date(x)` + Extracts and returns a time or date from a given `cds.DateTime`, `cds.Date`, or `cds.Time`. + +- `fractionalseconds(x)` + Returns a `Decimal` representing the fractional seconds for a given `cds.Timestamp`. + +- `maxdatetime()` + Returns the latest possible point in time: `'9999-12-31T23:59:59.999Z'`. + +- `mindatetime()` + Returns the earliest possible point in time: `'0001-01-01T00:00:00.000Z'`. + +#### Aggregate Functions + +- `min(x)`, `max(x)`, `sum(x)`, `average(x)`, `count(x)`, `countdistinct(x)` + Standard aggregate functions used to calculate minimum, maximum, sum, average, count, and distinct count of values. + + +### SAP HANA Functions + +In addition to the OData standard functions, the `@sap/cds-compiler` and all CAP Node.js database services come with +out of the box support for some common SAP HANA functions, to further increase the scope for portable testing: + +::: warning Upper- and Lowercase are supported +For the SAP HANA functions, both usages are allowed: all-lowercase as given above, as well as all-uppercase. +::: + +- `years_between` + Computes the number of years between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/years-between-function-datetime?locale=en-US)) +- `months_between` + Computes the number of months between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/months-between-function-datetime?locale=en-US)) +- `days_between` + Computes the number of days between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/days-between-function-datetime?locale=en-US)) +- `seconds_between` + Computes the number of seconds between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/seconds-between-function-datetime?locale=en-US)) +- `nano100_between` + Computes the time difference between two dates to the precision of 0.1 microseconds. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/nano100-between-function-datetime?locale=en-US)) + +### Special Runtime Functions + +In addition to the OData and SAP HANA standard functions, the **CAP runtimes** provides special functions that are only available for runtime queries: + +- `search(x, y)` + Checks whether `y` is contained in any element of `x` (fuzzy matching may apply). + See [Searching Data](../guides/providing-services#searching-data) for more details. + +- `session_context()` + Utilizes standard variable names to maintain session context. + Refer to [Session Variables](#session-variables) for additional information. +- `now()` + Returns the current timestamp. ## Using Native Features { #native-db-functions} @@ -1023,7 +1137,7 @@ In case of conflicts, follow these steps to provide different models for differe ``` 4. For the Spring Boot side it's similar. If you have a local development database and a hybrid profile with a remote SAP HANA database, you only need to run in default (or any other) profile. For the SAP HANA part, the build and deploy part is done separately and the application just needs to be started using `cds bind`. -Once you have 2 non-HANA local databases you need to have 2 distinct database configurations in your Spring Boot configuration (in most cases application.yaml). +Once you have 2 non-HANA local databases, you need to have 2 distinct database configurations in your Spring Boot configuration (in most cases application.yaml). ```yaml spring: From ea38315aa36404cf0b1c575e46e0569958bead16 Mon Sep 17 00:00:00 2001 From: David H Lam Date: Tue, 6 May 2025 15:33:45 +0200 Subject: [PATCH 038/140] Added section about async profiler with cf java (#1771) Added section about how to use the https://github.com/SAP/cf-cli-java-plugin to run profiling with asprof. --------- Co-authored-by: BraunMatthias <59841349+BraunMatthias@users.noreply.github.com> Co-authored-by: Rene Jeglinsky --- java/operating-applications/optimizing.md | 106 ++++++++++++++++++++-- project-words.txt | 1 + 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/java/operating-applications/optimizing.md b/java/operating-applications/optimizing.md index 7485cbd178..93f8c14808 100644 --- a/java/operating-applications/optimizing.md +++ b/java/operating-applications/optimizing.md @@ -17,7 +17,7 @@ uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/ To minimize overhead at runtime, [monitoring](observability#monitoring) information is gathered rather on a global application level and hence might not be sufficient to troubleshoot specific issues. In such a situation, the use of more focused profiling tools can be an option. -Typically, such tools are capable of focusing on a specific aspect of an application (for instance CPU or Memory management), but they come with an additional overhead and should only be enabled when needed. Hence, they need to meet the following requirements: +Typically, such tools can focus on a specific aspect of an application (for instance CPU or Memory management), but they come with an additional overhead and should only be enabled when needed. Hence, they need to meet the following requirements: * Switchable at runtime * Use a communication channel not exposed to unauthorized users @@ -28,20 +28,114 @@ How can dedicated Java tools access the running services in a secure manner? The ![This screenshot is explained in the accompanying text.](./assets/remote-tracing.png){width="600px"} As an authorized operator, you can access the container and start tools [locally](#profiling-local) in a CLI session running with the same user as the target process. Depending on the protocol, the JVM supports on-demand connections, for example, JVM diagnostic tools such as `jcmd`. Alternatively, additional JVM configuration is required as a prerequisite (JMX). -A bunch of tools also support [remote](#profiling-remote) connections in a secure way. Instead of running the tool locally, a remote daemon is started as a proxy in the container, which connects the JVM with a remote profiling tool via an ssh tunnel. ### Local Tools { #profiling-local} Various CLI-based tools for JVMs are delivered with the SDK. Popular examples are [diagnostic tools](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/toc.html) such as `jcmd`, `jinfo`, `jstack`, and `jmap`, which help to fetch basic information about the JVM process regarding all relevant aspects. You can take stack traces, heap dumps, fetch garbage collection events and read Java properties and so on. The SAP JVM comes with additional handy profiling tools: `jvmmon` and `jvmprof`. The latter, for instance, provides a helpful set of traces that allow a deep insight into JVM resource consumption. The collected data is stored within a `prf`-file and can be analyzed offline in the [SAP JVM Profiler frontend](https://wiki.scn.sap.com/wiki/display/ASJAVA/Features+and+Benefits). -### Remote Tools { #profiling-remote} +### Cloud Foundry Command Line Java Plugin -It's even more convenient to interact with the JVM with a frontend client running on a local machine. As already mentioned, a remote daemon as the endpoint of an ssh tunnel is required. Some representative tools are: +The [Java Plugin](https://github.com/SAP/cf-cli-java-plugin) for the [Cloud Foundry cli](https://github.com/cloudfoundry/cli) tool provides convenience utilities to work with Java applications deployed on Cloud Foundry. It helps to create heap dumps, thread dumps and profiling records of deployed and running Java application instances. -- [SAP JVM Profiler](https://wiki.scn.sap.com/wiki/display/ASJAVA/Features+and+Benefits) for SAP JVM with [Memory Analyzer](https://www.eclipse.org/mat/) integration. Find a detailed documentation how to set up a secure remote connection on [Profiling an Application Running on SAP JVM](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/e7097737709842b7bb1c3b9bf3d688b6.html). +Find the installation information in the plugin's [ReadMe](https://github.com/SAP/cf-cli-java-plugin?tab=readme-ov-file#installation). -- [JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html) is a popular Java profiler available for different platforms and IDEs. +#### Creating Heap Dumps + +```sh +cf java heap-dump sample-app-srv +``` + +Produces a `.hprof` file which can be viewed in a Java heap analyzer, such as [Memory Analyzer (MAT)](https://eclipse.dev/mat/). + +#### Creating Thread Dumps + +```sh +cf java thread-dump sample-app-srv > thread-dump.txt +``` + +Produces a thread dump on `stdout` which is here piped into a file for persistence. + +#### Async Profiler + +Using `cf java` to profile Java applications on Cloud Foundry with the [Async Profiler](https://github.com/async-profiler/async-profiler?tab=readme-ov-file#async-profiler) requires the [SAP Java Buildpack](https://help.sap.com/docs/btp/sap-business-technology-platform/sap-jakarta-buildpack?version=Cloud) and SapMachine 17 or 21. + +Make sure [SSH Access](https://github.com/SAP/cf-cli-java-plugin?tab=readme-ov-file#ssh-access) is enabled for the deployed application. Once enabled, you can start profiling easily using `cf java`. + +`cf java` provides the following **async-profiler** related commands: + +- `asprof-start-cpu` + + Start an async-profiler CPU-time profile recording on a running Java application + + +- `asprof-start-wall` + + Start an async-profiler wall-clock profile recording on a running Java application + + +- `asprof-start-alloc` + + Start an async-profiler allocation profile recording on a running Java application + + +- `asprof-start-lock` + + Start an async-profiler lock profile recording on a running Java application + + +- `asprof-stop` + + Stop an async-profiler profile recording on a running Java application + + +- `asprof-status` + + Get the status of async-profiler on a running Java application + + +- `asprof` (*Expert Mode*) + + Run async-profiler commands passed to asprof via --args + + +##### Usage + +The typical usage would be + +1. Start profiling with one of `asprof-start-cpu` , `asprof-start-wall` , `asprof-start-alloc` , `asprof-start-lock`: + ```sh + cf java asprof-start-cpu sample-app-srv + ``` + +2. Produce some load in your Java application. + +3. Optional: Check current async-profiler status: + ```sh + cf java asprof-status sample-app-srv + ``` + +4. Stop profiling: + ```sh + cf java asprof-stop sample-app-srv + ``` + + `asprof-stop` produces a `.jfr` file in your current local working directory. `.jfr` files are *JFR recordings* and can be viewed, for instance, using [multiple options](https://github.com/async-profiler/async-profiler/blob/master/docs/JfrVisualization.md). + +:::tip +Profiling accuracy improves if the following JVM arguments are set: +- **-XX:+UnlockDiagnosticVMOptions** +- **-XX:+DebugNonSafepoints** + +These can be set in a running application as follows: +```sh +cf set-env sample-app-srv JBP_CONFIG_JAVA_OPTS "[java_opts: '-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints']" +``` +Then restage your application: +```sh +cf restage sample-app-srv +``` +::: ### Remote JMX-Based Tools { #profiling-jmx} diff --git a/project-words.txt b/project-words.txt index 997dc781ef..02e8bcc29d 100644 --- a/project-words.txt +++ b/project-words.txt @@ -19,3 +19,4 @@ Undeploying undiscloses unlocalized Woltmann +asprof \ No newline at end of file From 234d6b02e220c31aebc90758226491988ef3ce45 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Tue, 6 May 2025 17:48:22 +0200 Subject: [PATCH 039/140] Fix `npm i` script for MTX sidecar installation --- guides/deployment/to-cf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index 1688ad159f..37186fed72 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -250,7 +250,7 @@ npm i app/admin-books ln -sf ../package-lock.json # If project is multitenant -npm i --package-lock-only mtx/sidecar +npm i --package-lock-only --prefix mtx/sidecar # If package-lock.json doesn't exist npm i --package-lock-only From 55feb3c882559575f228b8fad40319bc5b3d91a7 Mon Sep 17 00:00:00 2001 From: Evgeny Andreev Date: Wed, 7 May 2025 09:47:22 +0200 Subject: [PATCH 040/140] Describe pessimistic lock restrictions (#1796) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky Co-authored-by: Adrian GΓΆrler --- guides/providing-services.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/guides/providing-services.md b/guides/providing-services.md index 4dd24d9581..ae704e3507 100644 --- a/guides/providing-services.md +++ b/guides/providing-services.md @@ -746,12 +746,11 @@ Here's an overview table: [Learn more about using the `Select.lock()` method in the Java runtime.](../java/working-with-cql/query-api#write-lock){.learn-more} -::: warning -Pessimistic locking is not supported by SQLite. H2 supports exclusive locks only. -::: - - +::: warning Restrictions +- Pessimistic locking is supported for domain entities (DB table rows). The locking is not possible for projections and views. +- Pessimistic locking is not supported by SQLite. H2 supports exclusive locks only. +::: ## Input Validation From b7aacca447a60bd48a85edfc3e1bdfe11b2fc551 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 10:42:26 +0200 Subject: [PATCH 041/140] chore(deps): update dependency com.sap.cds:cds4j-api to v3.10.0 (#1815) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.sap.cds:cds4j-api](http://www.sap.com) | `3.9.1` -> `3.10.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.sap.cds:cds4j-api/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.sap.cds:cds4j-api/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.sap.cds:cds4j-api/3.9.1/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.sap.cds:cds4j-api/3.9.1/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index 11bd102ea9..cd0f28294d 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -107,7 +107,7 @@ config.rewrites = rewrites config.themeConfig.capire = { versions: { java_services: '3.9.1', - java_cds4j: '3.9.1' + java_cds4j: '3.10.0' }, gotoLinks: [], maven_host_base: 'https://repo1.maven.org/maven2' From 935b160541f742343e60de3e76b5833dc8504451 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 10:53:56 +0200 Subject: [PATCH 042/140] chore(deps): update eslint (#1808) --- package-lock.json | 577 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 494 insertions(+), 83 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a240a3008..0a62be2aa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1429,9 +1429,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.25.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.1.tgz", - "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==", + "version": "9.26.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", + "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", "dev": true, "license": "MIT", "engines": { @@ -1597,6 +1597,312 @@ "dev": true, "license": "MIT" }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.0.tgz", + "integrity": "sha512-k/1pb70eD638anoi0e8wUGAlbMJXyvdV4p62Ko+EZ7eBe1xMx8Uhak1R5DgfoofsK5IBBnRwsYGTaLZl+6/+RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.3", + "eventsource": "^3.0.2", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.24.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2716,16 +3022,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.31.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.1.tgz", - "integrity": "sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.0.tgz", + "integrity": "sha512-B2MdzyWxCE2+SqiZHAjPphft+/2x2FlO9YBx7eKE1BCb+rqBlQdhtAEhzIEdozHd55DXPmxBdpMygFJjfjjA9A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.31.1", - "@typescript-eslint/types": "8.31.1", - "@typescript-eslint/typescript-estree": "8.31.1", - "@typescript-eslint/visitor-keys": "8.31.1", + "@typescript-eslint/scope-manager": "8.32.0", + "@typescript-eslint/types": "8.32.0", + "@typescript-eslint/typescript-estree": "8.32.0", + "@typescript-eslint/visitor-keys": "8.32.0", "debug": "^4.3.4" }, "engines": { @@ -2741,14 +3047,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.31.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz", - "integrity": "sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.0.tgz", + "integrity": "sha512-jc/4IxGNedXkmG4mx4nJTILb6TMjL66D41vyeaPWvDUmeYQzF3lKtN15WsAeTr65ce4mPxwopPSo1yUUAWw0hQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.31.1", - "@typescript-eslint/visitor-keys": "8.31.1" + "@typescript-eslint/types": "8.32.0", + "@typescript-eslint/visitor-keys": "8.32.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2759,9 +3065,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.31.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.1.tgz", - "integrity": "sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.0.tgz", + "integrity": "sha512-O5Id6tGadAZEMThM6L9HmVf5hQUXNSxLVKeGJYWNhhVseps/0LddMkp7//VDkzwJ69lPL0UmZdcZwggj9akJaA==", "dev": true, "license": "MIT", "engines": { @@ -2773,20 +3079,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.31.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz", - "integrity": "sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.0.tgz", + "integrity": "sha512-pU9VD7anSCOIoBFnhTGfOzlVFQIA1XXiQpH/CezqOBaDppRwTglJzCC6fUQGpfwey4T183NKhF1/mfatYmjRqQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.31.1", - "@typescript-eslint/visitor-keys": "8.31.1", + "@typescript-eslint/types": "8.32.0", + "@typescript-eslint/visitor-keys": "8.32.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2800,13 +3106,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.31.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz", - "integrity": "sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.0.tgz", + "integrity": "sha512-1rYQTCLFFzOI5Nl0c8LUpJT8HxpwVRn9E4CkMsYfuN6ctmQqExjSTzzSk0Tz2apmXy7WU6/6fyaZVVA/thPN+w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.31.1", + "@typescript-eslint/types": "8.32.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -3422,7 +3728,6 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -3433,7 +3738,6 @@ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -3448,7 +3752,6 @@ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "get-intrinsic": "^1.2.6" @@ -3672,7 +3975,6 @@ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -3683,7 +3985,6 @@ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -3719,6 +4020,20 @@ "dev": true, "license": "MIT" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4011,7 +4326,6 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -4072,7 +4386,6 @@ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -4094,8 +4407,7 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -4117,7 +4429,6 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -4154,7 +4465,6 @@ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -4165,7 +4475,6 @@ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -4176,7 +4485,6 @@ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -4228,8 +4536,7 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -4245,9 +4552,9 @@ } }, "node_modules/eslint": { - "version": "9.25.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.1.tgz", - "integrity": "sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==", + "version": "9.26.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", + "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4257,11 +4564,12 @@ "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.13.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.1", + "@eslint/js": "9.26.0", "@eslint/plugin-kit": "^0.2.8", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", + "@modelcontextprotocol/sdk": "^1.8.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -4285,7 +4593,8 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3" + "optionator": "^0.9.3", + "zod": "^3.24.2" }, "bin": { "eslint": "bin/eslint.js" @@ -4549,11 +4858,33 @@ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } }, + "node_modules/eventsource": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz", + "integrity": "sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", + "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -4602,6 +4933,22 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-rate-limit": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", + "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "^4.11 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4868,7 +5215,6 @@ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -4905,7 +5251,6 @@ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4936,7 +5281,6 @@ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-define-property": "^1.0.1", @@ -4962,7 +5306,6 @@ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -5032,7 +5375,6 @@ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5106,7 +5448,6 @@ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5120,7 +5461,6 @@ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5200,7 +5540,6 @@ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5309,8 +5648,7 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/ini": { "version": "4.1.1", @@ -5328,7 +5666,6 @@ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.10" } @@ -5434,6 +5771,13 @@ "node": ">=0.12.0" } }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-what": { "version": "4.1.16", "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", @@ -5825,7 +6169,6 @@ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -6849,13 +7192,22 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -6869,7 +7221,6 @@ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -6877,6 +7228,16 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/oniguruma-to-es": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.10.0.tgz", @@ -6992,7 +7353,6 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -7059,6 +7419,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkce-challenge": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", + "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/postcss": { "version": "8.4.49", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", @@ -7140,7 +7510,6 @@ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -7213,7 +7582,6 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -7354,6 +7722,33 @@ "fsevents": "~2.3.2" } }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/run-con": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", @@ -7413,16 +7808,14 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/sass": { "version": "1.87.0", @@ -7558,8 +7951,7 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -7688,7 +8080,6 @@ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -7709,7 +8100,6 @@ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -7727,7 +8117,6 @@ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -7747,7 +8136,6 @@ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -7832,7 +8220,6 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -8076,7 +8463,6 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.6" } @@ -8093,9 +8479,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", - "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { @@ -8293,7 +8679,6 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -8332,7 +8717,6 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -8873,6 +9257,13 @@ "node": ">=8" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, "node_modules/xdg-basedir": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", @@ -8932,6 +9323,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.24.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", + "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.5", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", + "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", From 09a6499e62eb262516974f67fd1a95b41466e6ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 10:54:36 +0200 Subject: [PATCH 043/140] chore(deps): update dependency @sap/cds to v8.9.3 (#1814) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a62be2aa6..fc2a401ac6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2529,9 +2529,9 @@ ] }, "node_modules/@sap/cds": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.2.tgz", - "integrity": "sha512-UeyLZp6JvT9mOMEbgMzH+MWzueQQKvzvRNBxa5Ecdp0g2IkPFMmp97xw5bvv0MeKycs1vkJqWkGPZfgI74fiOg==", + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.3.tgz", + "integrity": "sha512-ezeT/VgaIQX5gjomgmLcDst4kHWjsZpQWVxn2kJej5py8/MGYCylsQfFUJGChXor1F0jtTtAcIJGrP2a1Jdyqg==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { From 58d7e8b1d7cc8a207dde3936c977d8721181bcd4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 10:55:11 +0200 Subject: [PATCH 044/140] chore: Update CLI texts (#1816) --- tools/assets/help/cds-version-md.out.md | 4 ++-- tools/assets/help/cds-version.out.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index a85dfd0428..77e05a379a 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -9,12 +9,12 @@ | @cap-js/db-service | 1.20.0 | | @cap-js/openapi | 1.2.1 | | @cap-js/sqlite | 1.11.0 | -| @sap/cds | 8.9.2 | +| @sap/cds | 8.9.3 | | @sap/cds-compiler | 5.9.2 | | @sap/cds-dk (global) | 8.9.3 | | @sap/cds-fiori | 1.4.1 | | @sap/cds-foss | 5.0.1 | | @sap/cds-mtxs | 2.7.2 | | @sap/eslint-plugin-cds | 3.2.0 | -| Node.js | v20.19.0 | +| Node.js | v20.19.1 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index bd58d55299..4c67e6eed7 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -7,13 +7,13 @@ @cap-js/db-service: 1.20.0 @cap-js/openapi: 1.2.1 @cap-js/sqlite: 1.11.0 -@sap/cds: 8.9.2 +@sap/cds: 8.9.3 @sap/cds-compiler: 5.9.2 @sap/cds-dk (global): 8.9.3 @sap/cds-fiori: 1.4.1 @sap/cds-foss: 5.0.1 @sap/cds-mtxs: 2.7.2 @sap/eslint-plugin-cds: 3.2.0 -Node.js: v20.19.0 +Node.js: v20.19.1 your-project: 1.0.0 From b73df3dfcd5d87f3b11b3ec2470e67ea61dc5dab Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Wed, 7 May 2025 10:57:02 +0200 Subject: [PATCH 045/140] chore: remove deprecated feature flag `cds.log.kibana_custom_fields` (#1791) --- node.js/cds-log.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/node.js/cds-log.md b/node.js/cds-log.md index 56f7dba784..b87bbcd38a 100644 --- a/node.js/cds-log.md +++ b/node.js/cds-log.md @@ -475,10 +475,6 @@ Without the additional custom field `query` and it's respective value, it would ::: -::: tip -Before `@sap/cds^7.5`, the configuration property was called `kibana_custom_fields`. As Kibana is the dashboard technology and the custom fields are actually a feature of the SAP Application Logging Service, we changed the name to `als_custom_fields`. `kibana_custom_fields` is supported until `@sap/cds^8`. -::: - For SAP Cloud Logging, the JSON formatter uses the following default configuration: ```jsonc From 6937e8b922ab39b0ad51dd3b57fd440a04ebefe1 Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Wed, 7 May 2025 15:13:42 +0200 Subject: [PATCH 046/140] Remove deprecated `dependencies` setting (#1817) --- guides/multitenancy/mtxs.md | 1 - 1 file changed, 1 deletion(-) diff --git a/guides/multitenancy/mtxs.md b/guides/multitenancy/mtxs.md index 1c96b8c0c9..178530494e 100644 --- a/guides/multitenancy/mtxs.md +++ b/guides/multitenancy/mtxs.md @@ -1140,7 +1140,6 @@ The _SaasProvisioningService_ is a faΓ§ade for the _DeploymentService_ to adapt - `workerSize` β€” max number of parallel asynchronous jobs per database - `clusterSize` β€” max number of database clusters, running `workerSize` jobs each - `queueSize` β€” max number of jobs waiting to run in the job queue -- `dependencies` β€” SAP BTP SaaS Provisioning service dependencies #### HTTP Request Options From c8bccafafb98586b6ee2cd6f8a7dbb30d1b80fcd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 15:23:14 +0200 Subject: [PATCH 047/140] chore(deps): update dependency com.sap.cds:cds-services-api to v3.10.0 (#1818) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.sap.cds:cds-services-api](https://cap.cloud.sap/docs/java) | `3.9.1` -> `3.10.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.sap.cds:cds-services-api/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.sap.cds:cds-services-api/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.sap.cds:cds-services-api/3.9.1/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.sap.cds:cds-services-api/3.9.1/3.10.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index cd0f28294d..4beef47aa1 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -106,7 +106,7 @@ config.rewrites = rewrites // Add custom capire info to the theme config config.themeConfig.capire = { versions: { - java_services: '3.9.1', + java_services: '3.10.0', java_cds4j: '3.10.0' }, gotoLinks: [], From baab0ddf44cd62ed3a616a2a1447572302049805 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 9 May 2025 09:19:17 +0200 Subject: [PATCH 048/140] move --- java/operating-applications/optimizing.md | 103 +--------------------- 1 file changed, 1 insertion(+), 102 deletions(-) diff --git a/java/operating-applications/optimizing.md b/java/operating-applications/optimizing.md index 93f8c14808..3ac944744e 100644 --- a/java/operating-applications/optimizing.md +++ b/java/operating-applications/optimizing.md @@ -34,108 +34,7 @@ As an authorized operator, you can access the container and start tools [locally Various CLI-based tools for JVMs are delivered with the SDK. Popular examples are [diagnostic tools](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/toc.html) such as `jcmd`, `jinfo`, `jstack`, and `jmap`, which help to fetch basic information about the JVM process regarding all relevant aspects. You can take stack traces, heap dumps, fetch garbage collection events and read Java properties and so on. The SAP JVM comes with additional handy profiling tools: `jvmmon` and `jvmprof`. The latter, for instance, provides a helpful set of traces that allow a deep insight into JVM resource consumption. The collected data is stored within a `prf`-file and can be analyzed offline in the [SAP JVM Profiler frontend](https://wiki.scn.sap.com/wiki/display/ASJAVA/Features+and+Benefits). -### Cloud Foundry Command Line Java Plugin - -The [Java Plugin](https://github.com/SAP/cf-cli-java-plugin) for the [Cloud Foundry cli](https://github.com/cloudfoundry/cli) tool provides convenience utilities to work with Java applications deployed on Cloud Foundry. It helps to create heap dumps, thread dumps and profiling records of deployed and running Java application instances. - -Find the installation information in the plugin's [ReadMe](https://github.com/SAP/cf-cli-java-plugin?tab=readme-ov-file#installation). - -#### Creating Heap Dumps - -```sh -cf java heap-dump sample-app-srv -``` - -Produces a `.hprof` file which can be viewed in a Java heap analyzer, such as [Memory Analyzer (MAT)](https://eclipse.dev/mat/). - -#### Creating Thread Dumps - -```sh -cf java thread-dump sample-app-srv > thread-dump.txt -``` - -Produces a thread dump on `stdout` which is here piped into a file for persistence. - -#### Async Profiler - -Using `cf java` to profile Java applications on Cloud Foundry with the [Async Profiler](https://github.com/async-profiler/async-profiler?tab=readme-ov-file#async-profiler) requires the [SAP Java Buildpack](https://help.sap.com/docs/btp/sap-business-technology-platform/sap-jakarta-buildpack?version=Cloud) and SapMachine 17 or 21. - -Make sure [SSH Access](https://github.com/SAP/cf-cli-java-plugin?tab=readme-ov-file#ssh-access) is enabled for the deployed application. Once enabled, you can start profiling easily using `cf java`. - -`cf java` provides the following **async-profiler** related commands: - -- `asprof-start-cpu` - - Start an async-profiler CPU-time profile recording on a running Java application - - -- `asprof-start-wall` - - Start an async-profiler wall-clock profile recording on a running Java application - - -- `asprof-start-alloc` - - Start an async-profiler allocation profile recording on a running Java application - - -- `asprof-start-lock` - - Start an async-profiler lock profile recording on a running Java application - - -- `asprof-stop` - - Stop an async-profiler profile recording on a running Java application - - -- `asprof-status` - - Get the status of async-profiler on a running Java application - - -- `asprof` (*Expert Mode*) - - Run async-profiler commands passed to asprof via --args - - -##### Usage - -The typical usage would be - -1. Start profiling with one of `asprof-start-cpu` , `asprof-start-wall` , `asprof-start-alloc` , `asprof-start-lock`: - ```sh - cf java asprof-start-cpu sample-app-srv - ``` - -2. Produce some load in your Java application. - -3. Optional: Check current async-profiler status: - ```sh - cf java asprof-status sample-app-srv - ``` - -4. Stop profiling: - ```sh - cf java asprof-stop sample-app-srv - ``` - - `asprof-stop` produces a `.jfr` file in your current local working directory. `.jfr` files are *JFR recordings* and can be viewed, for instance, using [multiple options](https://github.com/async-profiler/async-profiler/blob/master/docs/JfrVisualization.md). - -:::tip -Profiling accuracy improves if the following JVM arguments are set: -- **-XX:+UnlockDiagnosticVMOptions** -- **-XX:+DebugNonSafepoints** - -These can be set in a running application as follows: -```sh -cf set-env sample-app-srv JBP_CONFIG_JAVA_OPTS "[java_opts: '-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints']" -``` -Then restage your application: -```sh -cf restage sample-app-srv -``` -::: + ### Remote JMX-Based Tools { #profiling-jmx} From 842ede4c44a2b2768c92e97faab0599c506c04a9 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 9 May 2025 10:43:48 +0200 Subject: [PATCH 049/140] add flow --- java/_menu.md | 1 + 1 file changed, 1 insertion(+) diff --git a/java/_menu.md b/java/_menu.md index 115420c777..d69dd1f514 100644 --- a/java/_menu.md +++ b/java/_menu.md @@ -20,6 +20,7 @@ # [Messaging](messaging) # [Audit Logging](auditlog) # [Change Tracking](../../java/change-tracking) +# [State Transitions](../../java/flows) # [Transactional Outbox](outbox) # [Multitenancy](../../java/multitenancy) ## [Multitenancy (Classic)](../../java/multitenancy-classic) From bad1946bbb5776acb7141e96c35ebca43e602180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jeglinsky?= Date: Fri, 9 May 2025 10:48:35 +0200 Subject: [PATCH 050/140] Update best-practices.md (#1823) Closes: https://github.com/cap-js/docs/issues/1820 --- about/best-practices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/about/best-practices.md b/about/best-practices.md index 97d2e01edd..ccbf89b951 100644 --- a/about/best-practices.md +++ b/about/best-practices.md @@ -597,7 +597,7 @@ The *[Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architectur ... and he illustrated that like this: -![Hexagonal architecture basic.gif](https://alistair.cockburn.us/wp-content/uploads/2018/02/Hexagonal-architecture-basic-1.gif) +![Hexagonal architecture basic.gif](https://alistair.cockburn.us/hexFig1.png) In a nutshell, this introduction to the objectives of hexagonal architecture translates to that in our world of cloud-based business applications: From e78617a5b86fbd4fd35bee1755f7525b72317aa5 Mon Sep 17 00:00:00 2001 From: Stefan Henke Date: Fri, 9 May 2025 11:23:09 +0200 Subject: [PATCH 051/140] dynamic field control and assert constraint (#1804) Co-authored-by: Rene Jeglinsky --- guides/providing-services.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/guides/providing-services.md b/guides/providing-services.md index ae704e3507..5589b34b39 100644 --- a/guides/providing-services.md +++ b/guides/providing-services.md @@ -770,6 +770,8 @@ The same applies for fields with the [OData Annotations](../advanced/odata#annot Do not use the `@readonly` annotation on keys in all variants. ::: +
+ ### `@mandatory` Elements marked with `@mandatory` are checked for nonempty input: `null` and (trimmed) empty strings are rejected. @@ -791,7 +793,7 @@ In addition to server-side input validation as introduced above, this adds a cor ``` - +
### `@Common.FieldControl` {#common-fieldcontrol} @@ -961,7 +963,7 @@ entity Foo { } ``` - +
## Custom Logic From 4132e22c0e90763825deb9d6f3b367aa5f52098e Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Fri, 9 May 2025 14:48:05 +0200 Subject: [PATCH 052/140] Details on CSV data recovery using HDI (#1822) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instructions for MT apps were presented so prominently that customers got confused. So separate the single/multi tenant cases and give instructions for each one. --------- Co-authored-by: ecklie <52252271+ecklie@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: RenΓ© Jeglinsky --- get-started/troubleshooting.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/get-started/troubleshooting.md b/get-started/troubleshooting.md index 198ee3bee2..9e4c539091 100644 --- a/get-started/troubleshooting.md +++ b/get-started/troubleshooting.md @@ -397,11 +397,24 @@ On trial, your SAP HANA Cloud instance will be automatically stopped overnight, | _Root Cause_ | SAP HANA still claims exclusive ownership of the data that was once deployed through `hdbtabledata` artifacts, even though the CSV files are now deleted in your project. | _Solution_ | Add an _undeploy.json_ file to the root of your database module (the _db_ folder by default). This file defines the files **and data** to be deleted. See section [HDI Delta Deployment and Undeploy Allow List](https://help.sap.com/docs/HANA_CLOUD_DATABASE/c2b99f19e9264c4d9ae9221b22f6f589/ebb0a1d1d41e4ab0a06ea951717e7d3d.html) for more details. -::: tip -If you want to keep the data from _.csv_ files and data you've already added, see [SAP Note 2922271](https://me.sap.com/notes/2922271) for more details. + +#### How do I keep existing data? +If you want to keep the data from _.csv_ files and data you've already added, apply [SAP Note 2922271](https://me.sap.com/notes/2922271). +Depending on whether you have a single-tenant or multi-tenant application, see the following details for how to set the `path_parameter` and `undeploy` parameters: + +:::details Single-tenant applications {open} + +Use the _db/undeploy.json_ file as given in the SAP note. +The _package.json_ file that is mentioned in the SAP note is located in the _db/_ folder. +- If you don't find a _db/package.json_ file, use _gen/db/package.json_ (created by `cds build`) as a template and copy it to _db/package.json_. +- After the modification, run `cds build --production` and verify your changes have been copied to _gen/db/package.json_. +- Don't modify _gen/db/package.json_ as it is overwritten on every build. + ::: -You can apply this solution also when using the `cds-mtxs` library. You can either set the options via the environment variable [`HDI_DEPLOY_OPTIONS`](https://help.sap.com/docs/SAP_HANA_PLATFORM/4505d0bdaf4948449b7f7379d24d0f0d/a4bbc2dd8a20442387dc7b706e8d3070.html), the CDS configuration or you can add them to the model update request as `hdi` parameter: +:::details Multi-tenant applications + +Instead of configuring the static deployer application in _db/package.json_, use environment variable [`HDI_DEPLOY_OPTIONS`](https://help.sap.com/docs/SAP_HANA_PLATFORM/4505d0bdaf4948449b7f7379d24d0f0d/a4bbc2dd8a20442387dc7b706e8d3070.html), the `cds` configuration in _package.json_, or add the options to the model update request as `hdi` parameter: CDS configuration for [Deployment Service](../guides/multitenancy/mtxs#deployment-config) ```json @@ -439,6 +452,11 @@ Options in [Saas Provisioning Service upgrade API](../guides/multitenancy/mtxs#e } ``` +::: + +After you have successfully deployed these changes to all affected HDI (tenant) containers (in all spaces, accounts etc.), you can remove the configuration again. + + ### How Do I Resolve Deployment Errors? #### Deployment fails β€” _Cyclic dependencies found_ or _Cycle between files_ From 208148aac7c1f1412b5d91d2ddc923d6828d07ff Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Fri, 9 May 2025 16:55:28 +0200 Subject: [PATCH 053/140] Clarifications for CF deployment guide (#1821) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky --- .../assets/deploy-overview.drawio.svg | 98 ------------------- guides/deployment/to-cf.md | 22 +++-- 2 files changed, 14 insertions(+), 106 deletions(-) delete mode 100644 guides/deployment/assets/deploy-overview.drawio.svg diff --git a/guides/deployment/assets/deploy-overview.drawio.svg b/guides/deployment/assets/deploy-overview.drawio.svg deleted file mode 100644 index a1c54de7b0..0000000000 --- a/guides/deployment/assets/deploy-overview.drawio.svg +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - -
-
-
- - - CAP App - - -
-
-
-
- - CAP App - -
-
- - - - - - - - -
-
-
- - App Router - -
-
-
-
- - App Router - -
-
- - - - -
-
-
- - XSUAA - -
-
-
-
- - XSUAA - -
-
- - - - - -
-
-
- - HANA Cloud - -
-
-
-
- - HANA Cloud - -
-
-
- - - - - Text is not SVG - cannot display - - - -
\ No newline at end of file diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index 37186fed72..fdb4904587 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -69,7 +69,7 @@ cd bookshop In addition, you need to prepare the following: -#### 1. SAP BTP with SAP HANA Cloud Database up and Running {#btp-and-hana} +#### 1. SAP BTP with SAP HANA Cloud Database Up and Running {#btp-and-hana} - Access to [SAP BTP, for example a trial](https://developers.sap.com/tutorials/hcp-create-trial-account.html) - An [SAP HANA Cloud database running](https://help.sap.com/docs/hana-cloud/sap-hana-cloud-administration-guide/create-sap-hana-database-instance-using-sap-hana-cloud-central) in your subaccount @@ -126,17 +126,15 @@ npm i @sap/cds #> if necessary ## Prepare for Production {#prepare-for-production} -If you followed CAP's grow-as-you-go approach so far, you've developed your application with an in-memory database and basic/mock authentication. To prepare for production you need to ensure respective production-grade choices are configured: +If you followed CAP's grow-as-you-go approach, you've developed your application with an in-memory database and basic (mocked) authentication. In the cloud, you typically use production-grade services like SAP HANA and authentication providers. -![You need to add SAP HANA Cloud, an App Router and XSUAA.](assets/deploy-overview.drawio.svg){style="margin: 30px auto"} - -We'll use the `cds add ` CLI command for that, which ensures the required services are configured correctly and corresponding package dependencies are added to your _package.json_. +The `cds add ` command ensures required services are configured correctly and their dependencies are added to your _package.json_. ### 1. SAP HANA Database
-While we used SQLite as a low-cost stand-in during development, we're going to use an SAP HANA Cloud database for production: +While we used SQLite as a low-cost stand-in during development, we're using an SAP HANA Cloud database for production:
@@ -210,6 +208,8 @@ For **single-tenant applications**, you can use [SAP Build Work Zone, Standard E cds add workzone ``` +**Important:** This also requires you to set up SAP Build Work Zone, Standard Edition [according to the SAP Learning tutorial](https://developers.sap.com/tutorials/spa-configure-workzone.html). + ### 6. Optional: Multitenancy { #add-multitenancy } To enable multitenancy for production, run the following command: @@ -231,14 +231,20 @@ The previous steps are required _only once_ in a project's lifetime. With that d ## Build and Deploy +Make sure you are logged in to Cloud Foundry and target the space you want to deploy to: +```sh +cf login --sso # to log on with SAP Universal ID +cf target +``` +[Learn more about `cf login`](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/7a37d66c2e7d401db4980db0cd74aa6b.html){.learn-more} + + You can now freeze dependencies, build, and deploy the application: ```sh cds up ``` -[You need to be logged in to Cloud Foundry.](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/7a37d66c2e7d401db4980db0cd74aa6b.html){.learn-more} - ::: details Essentially, this automates the following steps... ```sh From 56e79788af2bc5ca09da579206585c5b3f46bdf1 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Mon, 12 May 2025 13:51:37 +0200 Subject: [PATCH 054/140] chore: use new standard GH token (#1835) --- .github/workflows/PR-SAP.yml | 4 ++-- .github/workflows/lint.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/PR-SAP.yml b/.github/workflows/PR-SAP.yml index a8768e7855..f1145f3e71 100644 --- a/.github/workflows/PR-SAP.yml +++ b/.github/workflows/PR-SAP.yml @@ -18,7 +18,7 @@ jobs: run: | git config --global credential.helper "cache --timeout=3600" echo -e "url=https://user:${GH_TOKEN}@github.com\n" | git credential approve - echo -e "url=https://user:${GH_TOKEN_PARENT}@github.tools.sap\n" | git credential approve + echo -e "url=https://user:${GH_TOKEN_TOOLS}@github.tools.sap\n" | git credential approve git clone --depth 1 --no-single-branch https://github.tools.sap/cap/docs docs cd docs git checkout $GITHUB_HEAD_REF || git checkout main @@ -27,7 +27,7 @@ jobs: git checkout $GITHUB_HEAD_REF env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_TOKEN_PARENT: ${{ secrets.GH_TOKEN_PARENT }} + GH_TOKEN_TOOLS: ${{ secrets.GH_TOKEN_TOOLS }} - name: Use Node.js uses: actions/setup-node@v4 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d8f6960af4..a8aecf0a83 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: run: | git config --global credential.helper "cache --timeout=3600" echo -e "url=https://user:${GH_TOKEN}@github.com\n" | git credential approve - echo -e "url=https://user:${GH_TOKEN_PARENT}@github.tools.sap\n" | git credential approve + echo -e "url=https://user:${GH_TOKEN_TOOLS}@github.tools.sap\n" | git credential approve git clone --depth 1 --no-single-branch https://github.tools.sap/cap/docs docs cd docs git checkout $GITHUB_HEAD_REF || git checkout main @@ -28,7 +28,7 @@ jobs: git checkout $GITHUB_HEAD_REF env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_TOKEN_PARENT: ${{ secrets.GH_TOKEN_PARENT }} + GH_TOKEN_TOOLS: ${{ secrets.GH_TOKEN_TOOLS }} - name: Use Node.js uses: actions/setup-node@v4 with: From a6b81b555c7253c69cb82cc5aff61fd2a60df5c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 13:52:58 +0200 Subject: [PATCH 055/140] chore(deps): update dependency sass to v1.88.0 (#1833) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [sass](https://redirect.github.com/sass/dart-sass) | [`1.87.0` -> `1.88.0`](https://renovatebot.com/diffs/npm/sass/1.87.0/1.88.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/sass/1.88.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/sass/1.88.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/sass/1.87.0/1.88.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sass/1.87.0/1.88.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
sass/dart-sass (sass) ### [`v1.88.0`](https://redirect.github.com/sass/dart-sass/blob/HEAD/CHANGELOG.md#1880) [Compare Source](https://redirect.github.com/sass/dart-sass/compare/1.87.0...1.88.0) - Allow custom properties with empty values (such as `--var:;`). - Fix a bug when calculating source spans for interpolations. ##### Dart and JS APIs - **Potentially breaking bug fix:** Throw an error when passing a function or mixin object from one compilation to another. ##### Dart API - Deprecate passing a relative URL to `compileString()` and related functions.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [x] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fc2a401ac6..d96d253b46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7818,9 +7818,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.87.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.87.0.tgz", - "integrity": "sha512-d0NoFH4v6SjEK7BoX810Jsrhj7IQSYHAHLi/iSpgqKc7LaIDshFRlSg5LOymf9FqQhxEHs2W5ZQXlvy0KD45Uw==", + "version": "1.88.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", + "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", "dev": true, "license": "MIT", "dependencies": { From 8934f853a482e17b7f77ceb960f361320cdab3e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 14:34:14 +0200 Subject: [PATCH 056/140] chore(deps): update dependency cspell to v9 (#1811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [cspell](https://cspell.org/) ([source](https://redirect.github.com/streetsidesoftware/cspell/tree/HEAD/packages/cspell)) | [`^8.0.0` -> `^9.0.0`](https://renovatebot.com/diffs/npm/cspell/8.19.2/9.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/cspell/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/cspell/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/cspell/8.19.2/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/cspell/8.19.2/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
streetsidesoftware/cspell (cspell) ### [`v9.0.1`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#901-2025-05-08) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v9.0.0...v9.0.1) **Note:** Version bump only for package cspell ### [`v9.0.0`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#900-2025-05-05) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v8.19.4...v9.0.0) **Note:** Version bump only for package cspell ### [`v8.19.4`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#8194-2025-05-03) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v8.19.3...v8.19.4) **Note:** Version bump only for package cspell ### [`v8.19.3`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#8193-2025-04-27) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v8.19.2...v8.19.3) **Note:** Version bump only for package cspell
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 330 ++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 159 insertions(+), 173 deletions(-) diff --git a/package-lock.json b/package-lock.json index d96d253b46..8af98414de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@types/express": "^4.17.21", "@typescript-eslint/parser": "^8.0.0", "adm-zip": "^0.5.10", - "cspell": "^8.0.0", + "cspell": "^9.0.0", "eslint": "^9.0.0", "eslint-plugin-vue": "^9.11.0", "fflate": "^0.8.2", @@ -298,9 +298,9 @@ } }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.19.2.tgz", - "integrity": "sha512-17yxicBRJj/00KlZ9y3fziuY3Y8neK2PA+wzf/NhnyA6AhU60TjLGj2yocKtlg8TYBeQK2kRiKq/2Uy0tv1RKg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.0.1.tgz", + "integrity": "sha512-h7gTqg0VF4N8VhOPk66XewuSsT56OP2ujgxtAyYQ4H+NuYd3HMfS0h/I3/y9uBhllwOEamaeAzYhc5JF/qIrsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -308,7 +308,7 @@ "@cspell/dict-al": "^1.1.0", "@cspell/dict-aws": "^4.0.10", "@cspell/dict-bash": "^4.2.0", - "@cspell/dict-companies": "^3.1.15", + "@cspell/dict-companies": "^3.2.1", "@cspell/dict-cpp": "^6.0.8", "@cspell/dict-cryptocurrencies": "^5.0.4", "@cspell/dict-csharp": "^4.0.6", @@ -316,20 +316,20 @@ "@cspell/dict-dart": "^2.3.0", "@cspell/dict-data-science": "^2.0.8", "@cspell/dict-django": "^4.1.4", - "@cspell/dict-docker": "^1.1.13", + "@cspell/dict-docker": "^1.1.14", "@cspell/dict-dotnet": "^5.0.9", "@cspell/dict-elixir": "^4.0.7", - "@cspell/dict-en_us": "^4.4.2", - "@cspell/dict-en-common-misspellings": "^2.0.10", - "@cspell/dict-en-gb": "1.1.33", - "@cspell/dict-filetypes": "^3.0.11", + "@cspell/dict-en_us": "^4.4.8", + "@cspell/dict-en-common-misspellings": "^2.0.11", + "@cspell/dict-en-gb-mit": "^3.0.6", + "@cspell/dict-filetypes": "^3.0.12", "@cspell/dict-flutter": "^1.1.0", "@cspell/dict-fonts": "^4.0.4", "@cspell/dict-fsharp": "^1.1.0", "@cspell/dict-fullstack": "^3.2.6", "@cspell/dict-gaming-terms": "^1.1.1", "@cspell/dict-git": "^3.0.4", - "@cspell/dict-golang": "^6.0.20", + "@cspell/dict-golang": "^6.0.21", "@cspell/dict-google": "^1.0.8", "@cspell/dict-haskell": "^4.0.5", "@cspell/dict-html": "^4.0.11", @@ -345,17 +345,17 @@ "@cspell/dict-markdown": "^2.0.10", "@cspell/dict-monkeyc": "^1.0.10", "@cspell/dict-node": "^5.0.7", - "@cspell/dict-npm": "^5.2.0", + "@cspell/dict-npm": "^5.2.3", "@cspell/dict-php": "^4.0.14", "@cspell/dict-powershell": "^5.0.14", "@cspell/dict-public-licenses": "^2.0.13", - "@cspell/dict-python": "^4.2.17", + "@cspell/dict-python": "^4.2.18", "@cspell/dict-r": "^2.1.0", "@cspell/dict-ruby": "^5.0.8", "@cspell/dict-rust": "^4.0.11", "@cspell/dict-scala": "^5.0.7", "@cspell/dict-shell": "^1.1.0", - "@cspell/dict-software-terms": "^5.0.5", + "@cspell/dict-software-terms": "^5.0.8", "@cspell/dict-sql": "^2.2.0", "@cspell/dict-svelte": "^1.0.6", "@cspell/dict-swift": "^2.0.5", @@ -364,63 +364,63 @@ "@cspell/dict-vue": "^3.0.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/cspell-json-reporter": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.19.2.tgz", - "integrity": "sha512-vW7mybZi5TN0ejB4XY2hpXT0XSDiUduN69Gn+WZtNZYeLV3NWIH/RtzgT7VDGyKUadUeEvbemH3MdW34cCuZjA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.0.1.tgz", + "integrity": "sha512-Rpn7Tuq9t8bZpXZFV43NkhCl0LaPDJZSON4/JFxGbOcH16ryXfrx7oObUTIIyxSxO3fGkzaJZHIwGibRJSsbNQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "8.19.2" + "@cspell/cspell-types": "9.0.1" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/cspell-pipe": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.19.2.tgz", - "integrity": "sha512-UF9s/bph/ELak6ZDEox9SbvPGU0giZ10jISKkR65MDg3nO7TQxm8TQB4PuNfwrt7Eybm+P10XroeXWfW5BfFmA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.0.1.tgz", + "integrity": "sha512-bhFcvF2a8KYKVh/OebCfJ8LFw5GYHyUsUjAbxnznTBrYOFSIclDjwUwT29yVDXwnQkJkB6Px5Y9e2VvtFizVFg==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/cspell-resolver": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.19.2.tgz", - "integrity": "sha512-OWm3DWJXbFKpzETmzHXQ6cu7xrOoctU2BuqeRaR2nHHmuHLBEnOeS6OOQeYfWg4vTO5uGnFblWpCBYxFdny08Q==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.0.1.tgz", + "integrity": "sha512-AhIXAhX1qt7Y3EyiP/5rAk7Ow7DJpAyB44wPbfdF9p1vhnk6oQ7RslnD3G6S9o/vNxZ0DWFPREMWx19J/3c+hw==", "dev": true, "license": "MIT", "dependencies": { "global-directory": "^4.0.1" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/cspell-service-bus": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.19.2.tgz", - "integrity": "sha512-+krdoByfZGMu7dMue4hMqRTJ/R+Lgzvz0fE9WhVdXhq6TB0EmR/y1b32fQ8XDfZQnOGpg+ZWiVbvAJp1QYmvuQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.0.1.tgz", + "integrity": "sha512-DoW6hLkFIO3BXePtUYQEax3FTH9fkwCUbf6qphAEXnr4PjoyPZsgBhR6iCrZd4DyhuFiRvK3Cgpq2o3O0NdODQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/cspell-types": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.19.2.tgz", - "integrity": "sha512-nmaxkoRZlHwMkUyNBHMT+vHaSUoCphS1DGAlfdkAt/vft8aisqFuH75hzcI52L4B1T8k/UYjn9BBwV1nQb14Ng==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.0.1.tgz", + "integrity": "sha512-8FRmvyV1AYEepJB3J7jji1ZYG9yOK0eYr4WuUVPfUJa6N3HyeZjWKhxbVvqedmEI74f5Ls3cQKHY1T2Yvqk/ag==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/dict-ada": { @@ -455,9 +455,9 @@ } }, "node_modules/@cspell/dict-companies": { - "version": "3.1.15", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.1.15.tgz", - "integrity": "sha512-vnGYTJFrqM9HdtgpZFOThFTjlPyJWqPi0eidMKyZxMKTHhP7yg6mD5X9WPEPvfiysmJYMnA6KKYQEBqoKFPU9g==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.1.tgz", + "integrity": "sha512-ryaeJ1KhTTKL4mtinMtKn8wxk6/tqD4vX5tFP+Hg89SiIXmbMk5vZZwVf+eyGUWJOyw5A1CVj9EIWecgoi+jYQ==", "dev": true, "license": "MIT" }, @@ -511,9 +511,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-docker": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.13.tgz", - "integrity": "sha512-85X+ZC/CPT3ie26DcfeMFkZSNuhS8DlAqPXzAjilHtGE/Nj+QnS3jyBz0spDJOJrjh8wx1+ro2oCK98sbVcztw==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.14.tgz", + "integrity": "sha512-p6Qz5mokvcosTpDlgSUREdSbZ10mBL3ndgCdEKMqjCSZJFdfxRdNdjrGER3lQ6LMq5jGr1r7nGXA0gvUJK80nw==", "dev": true, "license": "MIT" }, @@ -532,30 +532,30 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.2.tgz", - "integrity": "sha512-mvpv2kWayuOExCnDgvhlYDoW7gbGvGVTyuof9aFGy0+8ALYAJ2AtlvYCqzdTTKvvsYBrxAEEWFkUh75kHnHibg==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.8.tgz", + "integrity": "sha512-OkNUVuU9Q+Sf827/61YPkk6ya6dSsllzeYniBFqNW9TkoqQXT3vggkgmtCE1aEhSvVctMwxpPYoC8pZgn1TeSA==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-en-common-misspellings": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.10.tgz", - "integrity": "sha512-80mXJLtr0tVEtzowrI7ycVae/ULAYImZUlr0kUTpa8i57AUk7Zy3pYBs44EYIKW7ZC9AHu4Qjjfq4vriAtyTDQ==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.11.tgz", + "integrity": "sha512-xFQjeg0wFHh9sFhshpJ+5BzWR1m9Vu8pD0CGPkwZLK9oii8AD8RXNchabLKy/O5VTLwyqPOi9qpyp1cxm3US4Q==", "dev": true, "license": "CC BY-SA 4.0" }, - "node_modules/@cspell/dict-en-gb": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz", - "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==", + "node_modules/@cspell/dict-en-gb-mit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.0.6.tgz", + "integrity": "sha512-QYDwuXi9Yh+AvU1omhz8sWX+A1SxWI3zeK1HdGfTrICZavhp8xxcQGTa5zxTTFRCcQc483YzUH2Dl+6Zd50tJg==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-filetypes": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.11.tgz", - "integrity": "sha512-bBtCHZLo7MiSRUqx5KEiPdGOmXIlDGY+L7SJEtRWZENpAKE+96rT7hj+TUUYWBbCzheqHr0OXZJFEKDgsG/uZg==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.12.tgz", + "integrity": "sha512-+ds5wgNdlUxuJvhg8A1TjuSpalDFGCh7SkANCWvIplg6QZPXL4j83lqxP7PgjHpx7PsBUS7vw0aiHPjZy9BItw==", "dev": true, "license": "MIT" }, @@ -602,9 +602,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-golang": { - "version": "6.0.20", - "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.20.tgz", - "integrity": "sha512-b7nd9XXs+apMMzNSWorjirQsbmlwcTC0ViQJU8u+XNose3z0y7oNeEpbTPTVoN1+1sO9aOHuFwfwoOMFCDS14Q==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.21.tgz", + "integrity": "sha512-D3wG1MWhFx54ySFJ00CS1MVjR4UiBVsOWGIjJ5Av+HamnguqEshxbF9mvy+BX0KqzdLVzwFkoLBs8QeOID56HA==", "dev": true, "license": "MIT" }, @@ -720,9 +720,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.0.tgz", - "integrity": "sha512-kTUdbSE8SuIMKMlASMbI8/SEwv3EmI8eBcwdrtu4PHA+XVx+8JvQCB5fcWK9mn/94Y7LQ1kDIm+yfAZfwopY0A==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.3.tgz", + "integrity": "sha512-EdGkCpAq66Mhi9Qldgsr+NvPVL4TdtmdlqDe4VBp0P3n6J0B7b0jT1MlVDIiLR+F1eqBfL0qjfHf0ey1CafeNw==", "dev": true, "license": "MIT" }, @@ -748,9 +748,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-python": { - "version": "4.2.17", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.17.tgz", - "integrity": "sha512-xqMKfVc8d7yDaOChFdL2uWAN3Mw9qObB/Zr6t5w1OHbi23gWs7V1lI9d0mXAoqSK6N3mosbum4OIq/FleQDnlw==", + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.18.tgz", + "integrity": "sha512-hYczHVqZBsck7DzO5LumBLJM119a3F17aj8a7lApnPIS7cmEwnPc2eACNscAHDk7qAo2127oI7axUoFMe9/g1g==", "dev": true, "license": "MIT", "dependencies": { @@ -793,9 +793,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-software-terms": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.0.5.tgz", - "integrity": "sha512-ZjAOa8FI8/JrxaRqKT3eS7AQXFjU174xxQoKYMkmdwSyNIj7WUCAg10UeLqeMjFVv36zIO0Hm0dD2+Bvn18SLA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.0.8.tgz", + "integrity": "sha512-VsJesitvaHZpMgNwHHms3yDsZz7LNToC2HuSAnyt1znn37ribiJF1ty0jWhVQO6fv7K4PM1KsKTJIwqBwc446g==", "dev": true, "license": "MIT" }, @@ -842,47 +842,47 @@ "license": "MIT" }, "node_modules/@cspell/dynamic-import": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.19.2.tgz", - "integrity": "sha512-Ylsda+IrXhrIlAyGhCbc62tEk8F4MpO3u8llUQtWKhhvqbcxY+waC0d8S9u95egCACTTZIVDyrcxHX1lGg5+mw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.0.1.tgz", + "integrity": "sha512-BoWzHwkufo90ubMZUN8Jy4HQYYWFW7psVCdG/4RUgfvVnazkPfLxWBbsPQsLrlIP0utaqei7D9FU0K7r7mpl4A==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.19.2", + "@cspell/url": "9.0.1", "import-meta-resolve": "^4.1.0" }, "engines": { - "node": ">=18.0" + "node": ">=20" } }, "node_modules/@cspell/filetypes": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.19.2.tgz", - "integrity": "sha512-GqS/N0gTcnaAcBOVdWrehI+w6e+TzLSDj+zjW0DFWAbqnFDUOI9+1XtISINzMV6apOrBg8sMmFuaqif3TqvuZw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.0.1.tgz", + "integrity": "sha512-swZu3ra2AueyjEz/bPsvwFuHGYhjWZBx1K9FSvZA/yDIX5RVr6orQSuf9zvXNFui6Nyk0tudLnn3y9jT0LHk8A==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/strong-weak-map": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.19.2.tgz", - "integrity": "sha512-W/C6AK+z6sGOfdUsf75S/iLxyJkps8LEI/m9G/+R6RTHF4oyCGzh0JChHdnSjXrb0RpIPQjGOdwJcJOqVn/7/A==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.0.1.tgz", + "integrity": "sha512-u87PWr1xACqs/F3HibZ4Eb0Za/ghWIa6WLvEKV9OaiLfEUQuczbrXPVgHmGr83H0XXWUKy8FvVbWGFmXwiw+gQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@cspell/url": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.19.2.tgz", - "integrity": "sha512-B6NzFapXtS4DkGHhW8wGNE7u8v6Y3dMzdbvV2VxD6N0ByEiWqvsB2rW55z8e4fUOlGKLtedrBTFPPFIuSPs4Wg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.0.1.tgz", + "integrity": "sha512-8xaLrsQ742dmwXwS6tjreps3NpSQe6WEZFPQQT2DprVJXGZnfQR8ob0c+kPhD0hu9A6PwShJsRsfh3DQGKCqAw==", "dev": true, "license": "MIT", "engines": { - "node": ">=18.0" + "node": ">=20" } }, "node_modules/@esbuild/aix-ppc64": { @@ -4050,28 +4050,27 @@ } }, "node_modules/cspell": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.19.2.tgz", - "integrity": "sha512-CwH6eARg9nQE5WDSGFac4gde3S8L+1jhgd5rDe4enoGXqW0hBwsDvbIPCaiQTjG4KN+3u2QFxNMsX5lLBJjTmw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.0.1.tgz", + "integrity": "sha512-AJqsX+3eSTz9GmIuyEZUzCCTbvCPw6+Nv7UYa4PCn7vNV3XEb5LHTp5i9y2i65fNaeNEcQXLrLYoY/JcBFmUSQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-json-reporter": "8.19.2", - "@cspell/cspell-pipe": "8.19.2", - "@cspell/cspell-types": "8.19.2", - "@cspell/dynamic-import": "8.19.2", - "@cspell/url": "8.19.2", + "@cspell/cspell-json-reporter": "9.0.1", + "@cspell/cspell-pipe": "9.0.1", + "@cspell/cspell-types": "9.0.1", + "@cspell/dynamic-import": "9.0.1", + "@cspell/url": "9.0.1", "chalk": "^5.4.1", "chalk-template": "^1.1.0", "commander": "^13.1.0", - "cspell-dictionary": "8.19.2", - "cspell-gitignore": "8.19.2", - "cspell-glob": "8.19.2", - "cspell-io": "8.19.2", - "cspell-lib": "8.19.2", + "cspell-dictionary": "9.0.1", + "cspell-gitignore": "9.0.1", + "cspell-glob": "9.0.1", + "cspell-io": "9.0.1", + "cspell-lib": "9.0.1", "fast-json-stable-stringify": "^2.1.0", "file-entry-cache": "^9.1.0", - "get-stdin": "^9.0.0", "semver": "^7.7.1", "tinyglobby": "^0.2.13" }, @@ -4080,73 +4079,73 @@ "cspell-esm": "bin.mjs" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" } }, "node_modules/cspell-config-lib": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.19.2.tgz", - "integrity": "sha512-FW7rYL952LSIzTpesmTw856dIV7jhKFvbH/Ug9i74/omC57vsA/caLH8SqYXS+Z2PslihBKKCU8j2aB2qiybMQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.0.1.tgz", + "integrity": "sha512-hbeyU6cY4NPKh69L4QpBZgGz00f7rLk10xPlCo6MxEmCqSOTuXXvDEUR51d2ED69G+GyFAeZi5VU9IdJ4jhvzQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "8.19.2", + "@cspell/cspell-types": "9.0.1", "comment-json": "^4.2.5", "yaml": "^2.7.1" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-dictionary": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.19.2.tgz", - "integrity": "sha512-YEVM61V0d4TmxB0Dtk3L5I7Rz3WA8Y4vjxO7rPX2piieMwp7T7l4aHb/ZpHx7JqsJSSzp9vjtgVrwVE0gCJpZw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.0.1.tgz", + "integrity": "sha512-I9gjRpfV4djxN0i2p9OzWIrkjtUaGUyVE9atvRbkHUMeqDUhC2Qt0Mb9tnF8I7qnHeZt+U44vUa9Dg7yrJ+k4Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.19.2", - "@cspell/cspell-types": "8.19.2", - "cspell-trie-lib": "8.19.2", + "@cspell/cspell-pipe": "9.0.1", + "@cspell/cspell-types": "9.0.1", + "cspell-trie-lib": "9.0.1", "fast-equals": "^5.2.2" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-gitignore": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.19.2.tgz", - "integrity": "sha512-GxWHMow+o5RqVYw9WjIbExiWE1abnF0PqrbVh3gcwCoM/xYTBfGUDBnpD/PQB4uqH1oDolMfu1wp5/J1D97OFw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.0.1.tgz", + "integrity": "sha512-xjgOmeGbHEaeF0erRQ2QXwqxWqGDiI4mu+NjCL7ZHPoAM5y8PEO6IbxVNabIB1xC4QAborbtEQ/8ydDWLJcPoQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.19.2", - "cspell-glob": "8.19.2", - "cspell-io": "8.19.2" + "@cspell/url": "9.0.1", + "cspell-glob": "9.0.1", + "cspell-io": "9.0.1" }, "bin": { "cspell-gitignore": "bin.mjs" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-glob": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.19.2.tgz", - "integrity": "sha512-5/UBFLMh+3vhAyI3ep4Oqrt0rAb1mQHXmmpwk+WDpiS9CoSjoATIvibH5Ln9riwiIt1Bo7lH0BqfEQ3NtcegUg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.0.1.tgz", + "integrity": "sha512-dQU/ln6J9Qe31zk1cLJnq/WNAjRrTUig1GG8WA2oK1jHZKY9VbyJLb5DUFnDUx35cI0jdOEnGSCWi8qNjHSc1Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "8.19.2", + "@cspell/url": "9.0.1", "picomatch": "^4.0.2" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-glob/node_modules/picomatch": { @@ -4163,59 +4162,59 @@ } }, "node_modules/cspell-grammar": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.19.2.tgz", - "integrity": "sha512-jrgMWIivZ9HFLXqdkR5eQ7tmvePYYnFRy4Hs1VGpCr36DqPcrURxtONFJuLCJwKl0xRSlhPIeC8fpIeEwtxUvQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.0.1.tgz", + "integrity": "sha512-FZ1z1p3pslfotZT/W/VRZjB4S+z0ETrTbNmQ5pGmhdY0nm7Slmg+8nIJluLEjBneBGTJIOcLjYykwS2vI6jzxw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.19.2", - "@cspell/cspell-types": "8.19.2" + "@cspell/cspell-pipe": "9.0.1", + "@cspell/cspell-types": "9.0.1" }, "bin": { "cspell-grammar": "bin.mjs" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-io": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.19.2.tgz", - "integrity": "sha512-qt0QaUCw1/atoA960ev8z2ryT5+vGpXYcp71bzE52PPBACW2vKhwlBfc/4YpCC8pcNQGj6N9hzEX+G6nDTHnUw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.0.1.tgz", + "integrity": "sha512-L5fZY0glVeQb6nmt1WL1wKzZzoHJUkBQ9BGCrwqSXIrjZrYmBNSKixCjo6o9n2keRUwpNjsvZj1TQDKDV+FsXA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "8.19.2", - "@cspell/url": "8.19.2" + "@cspell/cspell-service-bus": "9.0.1", + "@cspell/url": "9.0.1" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-lib": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.19.2.tgz", - "integrity": "sha512-we1IeovendX+vRhdOQpOdwFX7CRxLDMMGcm0Sy6Duo66IKerPYeSJwbTfQi8G8e5ZIU14F0psnjoBaOBcqpLrg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.0.1.tgz", + "integrity": "sha512-F4vJG6GmAGVAuhgcepO12UtG7yev7Rcfa31MLIyYNTrd5NeORzM+GTHnL970FlEflwYPYjcSTGwkyowQ+ZbmDg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "8.19.2", - "@cspell/cspell-pipe": "8.19.2", - "@cspell/cspell-resolver": "8.19.2", - "@cspell/cspell-types": "8.19.2", - "@cspell/dynamic-import": "8.19.2", - "@cspell/filetypes": "8.19.2", - "@cspell/strong-weak-map": "8.19.2", - "@cspell/url": "8.19.2", + "@cspell/cspell-bundled-dicts": "9.0.1", + "@cspell/cspell-pipe": "9.0.1", + "@cspell/cspell-resolver": "9.0.1", + "@cspell/cspell-types": "9.0.1", + "@cspell/dynamic-import": "9.0.1", + "@cspell/filetypes": "9.0.1", + "@cspell/strong-weak-map": "9.0.1", + "@cspell/url": "9.0.1", "clear-module": "^4.1.2", "comment-json": "^4.2.5", - "cspell-config-lib": "8.19.2", - "cspell-dictionary": "8.19.2", - "cspell-glob": "8.19.2", - "cspell-grammar": "8.19.2", - "cspell-io": "8.19.2", - "cspell-trie-lib": "8.19.2", + "cspell-config-lib": "9.0.1", + "cspell-dictionary": "9.0.1", + "cspell-glob": "9.0.1", + "cspell-grammar": "9.0.1", + "cspell-io": "9.0.1", + "cspell-trie-lib": "9.0.1", "env-paths": "^3.0.0", "fast-equals": "^5.2.2", "gensequence": "^7.0.0", @@ -4226,22 +4225,22 @@ "xdg-basedir": "^5.1.0" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cspell-trie-lib": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.19.2.tgz", - "integrity": "sha512-/0DuCmBwz1B3yOlxCgib98uVVdIBOp/PNWEA3pmmjPOiWvOb/bBdw5C5o+ghnf93scDZQJF3l8a2sAQmsZkkIw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.0.1.tgz", + "integrity": "sha512-gIupiHwLdsQun79biJgiqmXffKUGzFjGLFEeVptI2Zy5Oa3XhRJsHap4PyeleErONkpzxMG1tgpOWzhOqwl65Q==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.19.2", - "@cspell/cspell-types": "8.19.2", + "@cspell/cspell-pipe": "9.0.1", + "@cspell/cspell-types": "9.0.1", "gensequence": "^7.0.0" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/cssesc": { @@ -5314,19 +5313,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", diff --git a/package.json b/package.json index 5080b5f4a1..28d3310f66 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@types/express": "^4.17.21", "@typescript-eslint/parser": "^8.0.0", "adm-zip": "^0.5.10", - "cspell": "^8.0.0", + "cspell": "^9.0.0", "eslint": "^9.0.0", "eslint-plugin-vue": "^9.11.0", "fflate": "^0.8.2", From 04eb8d968f1e5d73218e69d7171f0b395e7dd4e3 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Mon, 12 May 2025 14:52:16 +0200 Subject: [PATCH 057/140] Recommend more modern SQLite viewer --- get-started/troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/get-started/troubleshooting.md b/get-started/troubleshooting.md index 9e4c539091..1d71cd2005 100644 --- a/get-started/troubleshooting.md +++ b/get-started/troubleshooting.md @@ -374,7 +374,7 @@ sqlite> If you want to test further, use _.help_ command to see all available commands in _sqlite3_. -In case you want a visual interface tool to work with SQLite, you can use [SQLTools](https://marketplace.visualstudio.com/items?itemName=mtxr.sqltools). It's available as an extension for VS Code and integrated in SAP Business Application Studio. +In case you want a visual interface tool to work with SQLite, you can use [SQLite Viewer](https://marketplace.visualstudio.com/items?itemName=qwtel.sqlite-viewer). It's available as an extension for VS Code and integrated in SAP Business Application Studio. ## SAP HANA { #hana} From a70c976ff5df0c9e7d97059f5066e2284d6bcec8 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Tue, 13 May 2025 13:17:48 +0200 Subject: [PATCH 058/140] Rename token --- .github/workflows/PR-SAP.yml | 4 ++-- .github/workflows/lint.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/PR-SAP.yml b/.github/workflows/PR-SAP.yml index f1145f3e71..1fc80f96dc 100644 --- a/.github/workflows/PR-SAP.yml +++ b/.github/workflows/PR-SAP.yml @@ -18,7 +18,7 @@ jobs: run: | git config --global credential.helper "cache --timeout=3600" echo -e "url=https://user:${GH_TOKEN}@github.com\n" | git credential approve - echo -e "url=https://user:${GH_TOKEN_TOOLS}@github.tools.sap\n" | git credential approve + echo -e "url=https://user:${GH_TOKEN_TOOLS_DOCS}@github.tools.sap\n" | git credential approve git clone --depth 1 --no-single-branch https://github.tools.sap/cap/docs docs cd docs git checkout $GITHUB_HEAD_REF || git checkout main @@ -27,7 +27,7 @@ jobs: git checkout $GITHUB_HEAD_REF env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_TOKEN_TOOLS: ${{ secrets.GH_TOKEN_TOOLS }} + GH_TOKEN_TOOLS_DOCS: ${{ secrets.GH_TOKEN_TOOLS_DOCS }} - name: Use Node.js uses: actions/setup-node@v4 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a8aecf0a83..1770a1baa9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: run: | git config --global credential.helper "cache --timeout=3600" echo -e "url=https://user:${GH_TOKEN}@github.com\n" | git credential approve - echo -e "url=https://user:${GH_TOKEN_TOOLS}@github.tools.sap\n" | git credential approve + echo -e "url=https://user:${GH_TOKEN_TOOLS_DOCS}@github.tools.sap\n" | git credential approve git clone --depth 1 --no-single-branch https://github.tools.sap/cap/docs docs cd docs git checkout $GITHUB_HEAD_REF || git checkout main @@ -28,7 +28,7 @@ jobs: git checkout $GITHUB_HEAD_REF env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_TOKEN_TOOLS: ${{ secrets.GH_TOKEN_TOOLS }} + GH_TOKEN_TOOLS_DOCS: ${{ secrets.GH_TOKEN_TOOLS_DOCS }} - name: Use Node.js uses: actions/setup-node@v4 with: From 12622513f1f9bf2e566cb37b3160667e851344e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 May 2025 13:37:11 +0200 Subject: [PATCH 059/140] chore(deps): update dependency @typescript-eslint/parser to v8.32.1 (#1838) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.32.0` -> `8.32.1`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.32.0/8.32.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@typescript-eslint%2fparser/8.32.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@typescript-eslint%2fparser/8.32.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@typescript-eslint%2fparser/8.32.0/8.32.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@typescript-eslint%2fparser/8.32.0/8.32.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/parser) ### [`v8.32.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8321-2025-05-12) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.32.0...v8.32.1) This was a version bump only for parser to align it with other projects, there were no code changes. You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8af98414de..fe51f1e980 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3022,16 +3022,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/parser": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.0.tgz", - "integrity": "sha512-B2MdzyWxCE2+SqiZHAjPphft+/2x2FlO9YBx7eKE1BCb+rqBlQdhtAEhzIEdozHd55DXPmxBdpMygFJjfjjA9A==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", + "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.32.0", - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/typescript-estree": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0", + "@typescript-eslint/scope-manager": "8.32.1", + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/typescript-estree": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1", "debug": "^4.3.4" }, "engines": { @@ -3047,14 +3047,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.0.tgz", - "integrity": "sha512-jc/4IxGNedXkmG4mx4nJTILb6TMjL66D41vyeaPWvDUmeYQzF3lKtN15WsAeTr65ce4mPxwopPSo1yUUAWw0hQ==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", + "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0" + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3065,9 +3065,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.0.tgz", - "integrity": "sha512-O5Id6tGadAZEMThM6L9HmVf5hQUXNSxLVKeGJYWNhhVseps/0LddMkp7//VDkzwJ69lPL0UmZdcZwggj9akJaA==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz", + "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", "dev": true, "license": "MIT", "engines": { @@ -3079,14 +3079,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.0.tgz", - "integrity": "sha512-pU9VD7anSCOIoBFnhTGfOzlVFQIA1XXiQpH/CezqOBaDppRwTglJzCC6fUQGpfwey4T183NKhF1/mfatYmjRqQ==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", + "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0", + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3106,13 +3106,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.0.tgz", - "integrity": "sha512-1rYQTCLFFzOI5Nl0c8LUpJT8HxpwVRn9E4CkMsYfuN6ctmQqExjSTzzSk0Tz2apmXy7WU6/6fyaZVVA/thPN+w==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", + "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.32.0", + "@typescript-eslint/types": "8.32.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { From 5d3cbda04ae16ba214a975cee2059caa49d5c385 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Tue, 13 May 2025 17:28:30 +0200 Subject: [PATCH 060/140] fix: update feature details for clarity and accuracy --- index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.md b/index.md index e3f23d0d7e..e14dee3470 100644 --- a/index.md +++ b/index.md @@ -36,7 +36,7 @@ features: details: β€’  Capture intent β‡’ What, not how!
β€’  Minimized boilerplate coding
- β€’  Developers + domain experts
+ β€’  Minimized technical debt
link: about/ linkText: Read the Primer @@ -44,7 +44,7 @@ features: icon: πŸŒ€ details: β€’  Jumpstart with minimal setup
- β€’  Rapid dev at minimized costs
+ β€’  Fast inner loop dev & tests
β€’  Grow as you go...
link: get-started/in-a-nutshell linkText: Get Started in a Nutshell From 9c0ff7c65e5d6019c11cecdd89a70a0f0eeb4c12 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Thu, 15 May 2025 10:07:55 +0200 Subject: [PATCH 061/140] chore: fix typo (#1846) --- java/outbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/outbox.md b/java/outbox.md index a031f62993..b2f16b1e08 100644 --- a/java/outbox.md +++ b/java/outbox.md @@ -160,7 +160,7 @@ To do this, the Maven `resource.filtering` configuration in the `srv/pom.xml` mu To be sure that the deployment version has been set correctly, you can find a log entry at startup that shows the configured version: ```bash -2024-12-19T11:21:33.253+01:00 INFO 3420 --- [main] cds.serviceces.impl.utils.BuildInfo : application.deployment.version: 1.0.0-SNAPSHOT +2024-12-19T11:21:33.253+01:00 INFO 3420 --- [main] cds.services.impl.utils.BuildInfo : application.deployment.version: 1.0.0-SNAPSHOT ``` And finally, if for some reason you don't want to use a version check for a particular outbox collector, you can switch it off via the outbox configuration [cds.outbox.services.MyCustomOutbox.checkVersion: false](../java/developing-applications/properties#cds-outbox-services--checkVersion). From 5f2c6f58783c8cf7ef1bcf7796c0ef1303da421d Mon Sep 17 00:00:00 2001 From: Daniel O'Grady <103028279+daogrady@users.noreply.github.com> Date: Thu, 15 May 2025 10:07:06 +0200 Subject: [PATCH 062/140] Update `cds lint` Page (#1847) Remove outdated output that is no longer printed when adding `cds lint`. --- tools/cds-lint/index.md | 22 ++-------------------- tools/cds-lint/rules/index.md | 2 +- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/tools/cds-lint/index.md b/tools/cds-lint/index.md index 035aaafd45..cdec3e8b24 100644 --- a/tools/cds-lint/index.md +++ b/tools/cds-lint/index.md @@ -34,25 +34,7 @@ The following command automatically installs ESLint, the CDS ESLint plugin, and cds add lint ``` -
-
-Adding feature 'lint'...
-
-Successfully added features to your project.
-
-
-Almost done - you are missing 2 npm dependencies:
-
-(1) ESLint v>=8.0.0
-(2) ESLint plugin for CDS
-
-
-Install dependencies now? [y/n] y
-
-Successfully added features to your project.
-
- -If a _package.json_, _pom.xml_, or _.cdsrc.json_ file is found, you have the choice to install the ESLint dependencies directly. Once confirmed, this will install ESLint and the CDS plugin, as well as add the corresponding configuration for the recommended rules into your project. +You may be asked to install ESLint as additional dependency in case it is not available in your project yet. Just follow the instructions on screen. ### CDS Lint CLI {#usage-lint-cli} @@ -72,7 +54,7 @@ It follows standard ESLint behaviour. If there are no lint errors, there is no o Make sure you have ESLint and our ESLint plugin installed via [`cds add lint`](#cds-add-lint). ::: -To turn on Lint checking in your VS Code Editor simply download the [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) for _Visual Studio Code_. +To turn on lint checking in your VS Code Editor simply download the [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) for _Visual Studio Code_. CDS Lint seamlessly integrates with it. For _SAP Business Application Studio_ this comes preinstalled. Now you can see lint reports also in your editor. You can see all rules [marked as **Editor default** here](./rules/). Any other (project-based) rules are not turned on by diff --git a/tools/cds-lint/rules/index.md b/tools/cds-lint/rules/index.md index d6066f1767..226b7e11e8 100644 --- a/tools/cds-lint/rules/index.md +++ b/tools/cds-lint/rules/index.md @@ -12,7 +12,7 @@ status: released # Rules Reference -Below you can find all rules of the \`@sap/eslint-plugin-cds\` ESLint plugin. +Below you can find all rules of the `@sap/eslint-plugin-cds` ESLint plugin. They are grouped by categories [Model Validation](#model-validation) and [Environment](#environment) to help you understand their purpose. From 3bade5e3b0cbc299ca9853792e2502710166afa0 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Thu, 15 May 2025 13:57:52 +0200 Subject: [PATCH 063/140] chore: increase chunk limit --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index 4beef47aa1..d6ba06afdd 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -70,7 +70,7 @@ const config = defineConfig({ vite: { build: { - chunkSizeWarningLimit: 5000, // chunk for local search index dominates + chunkSizeWarningLimit: 6000, // chunk for local search index dominates }, css: { preprocessorOptions: { From 08ec536078fa456e7b5be020fd5e536fc8e3a707 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Thu, 15 May 2025 13:52:06 +0200 Subject: [PATCH 064/140] Slight update on SAP CI/CD and Piper docs --- guides/deployment/cicd.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/guides/deployment/cicd.md b/guides/deployment/cicd.md index e51fc5d6f8..fd7014a776 100644 --- a/guides/deployment/cicd.md +++ b/guides/deployment/cicd.md @@ -20,25 +20,21 @@ status: released -## SAP CI/CD Service +## SAP Continuous Integration and Delivery -SAP Continuous Integration and Delivery is a service on SAP BTP, which lets you configure and run predefined continuous integration and delivery pipelines. It connects with your Git SCM repository and in its user interface, you can easily monitor the status of your builds and detect errors as soon as possible, which helps you prevent integration problems before completing your development. +[SAP Continuous Integration and Delivery](https://help.sap.com/viewer/SAP-Cloud-Platform-Continuous-Integration-and-Delivery) lets you configure and run predefined continuous integration and delivery pipelines. It connects with your Git SCM repository and in its user interface, you can easily monitor the status of your builds and detect errors as soon as possible, which helps you prevent integration problems before completing your development. SAP Continuous Integration and Delivery has a ready-to-use pipeline for CAP, that is applicable to Node.js, Java and multitarget application (MTA) based projects. It does not require you to host your own Jenkins instance and it provides an easy, UI-guided way to configure your pipelines. Try the tutorial [Get Started with SAP Continuous Integration and Delivery](https://developers.sap.com/tutorials/cicd-start-cap.html) to configure a CI/CD pipeline that builds, tests, and deploys your code changes. -[Learn more about SAP Continuous Integration and Delivery.](https://help.sap.com/viewer/SAP-Cloud-Platform-Continuous-Integration-and-Delivery){.learn-more} - - ## CI/CD Pipelines with SAP Piper -You can set up continuous delivery in your software development project, applicable to both SAP Business Technology Platform (BTP) and SAP on-premise platforms. SAP implements tooling for continuous delivery in project [Piper](https://www.project-piper.io/). +For more flexibility you can set up continuous delivery in your software development project, applicable to both SAP Business Technology Platform (BTP) and SAP on-premise platforms. SAP implements tooling for continuous delivery in project [Piper](https://www.project-piper.io/). Try the tutorial [Create Automated System Tests for SAP Cloud Application Programming Model Projects](https://developers.sap.com/tutorials/cicd-wdi5-cap.html) to create system tests against a CAP-based sample application and automate your tests through a CI/CD pipeline. - -[Learn more about project Piper](https://www.project-piper.io/){.learn-more} +[See a comparison with SAP Continuous Integration and Delivery Service.](https://www.project-piper.io/){.learn-more} ## GitHub Actions From 33b3686455823fb2587c6eb3b85c740748f110e8 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Thu, 15 May 2025 13:56:24 +0200 Subject: [PATCH 065/140] Remove link to custom actions that are disabled --- guides/deployment/cicd.md | 1 - 1 file changed, 1 deletion(-) diff --git a/guides/deployment/cicd.md b/guides/deployment/cicd.md index fd7014a776..58a79842af 100644 --- a/guides/deployment/cicd.md +++ b/guides/deployment/cicd.md @@ -40,4 +40,3 @@ Try the tutorial [Create Automated System Tests for SAP Cloud Application Progra GitHub offers continuous integration workflows using [GitHub Actions](https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration). In our [SFlight sample,](https://github.com/SAP-samples/cap-sflight) we use GitHub Actions in two simple workflows to test our samples on [current Node.js and Java versions](https://github.com/SAP-samples/cap-sflight/tree/main/.github/workflows). -We also defined our [own actions](https://github.com/SAP-samples/cap-sflight/tree/main/.github/actions) and use them in a [custom workflow](https://github.com/SAP-samples/cap-sflight/blob/main/.github/workflows/deploy-btp.yml). From d139d7854c355199cef35a107e7b7f52093672e4 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 16 May 2025 10:58:22 +0200 Subject: [PATCH 066/140] add --- get-started/learning-sources.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/get-started/learning-sources.md b/get-started/learning-sources.md index 65c2fc9e58..243e595c34 100644 --- a/get-started/learning-sources.md +++ b/get-started/learning-sources.md @@ -71,6 +71,12 @@ In here, we collected several interesting sample projects for you. Not all of th display:inline; margin:0 0.2em; padding-bottom:5px; + }main .vp-doc a.github img { + content: url(../assets/logos/github.svg); + height:3em; + display:inline; + margin:0 0.2em; + padding-bottom:5px; } main .vp-doc a:has(> img):hover { opacity: 0.7; @@ -148,7 +154,7 @@ By using BTP services and the SAP Cloud Application Programming Model (CAP), you The repository includes the β€œPoetry Slam Manager” application as a ready-to-run example. It also provides tutorials on how to build the application from scratch using an incremental development approach. Based on this sample application, you find the bill of materials and a sizing example. This addresses the question "Which BTP resources do I need to subscribe to and in what quantities?" and serves as a basis for cost calculation. - + ## Open Source Projects From 4fca02209ca59323592028b7fa99ad70cbe13430 Mon Sep 17 00:00:00 2001 From: ecklie <52252271+ecklie@users.noreply.github.com> Date: Fri, 16 May 2025 11:09:24 +0200 Subject: [PATCH 067/140] Review of migration guide (#1841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Georgi Co-authored-by: RenΓ© Jeglinsky --- guides/multitenancy/old-mtx-migration.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/guides/multitenancy/old-mtx-migration.md b/guides/multitenancy/old-mtx-migration.md index 59d8042927..fdc81580db 100644 --- a/guides/multitenancy/old-mtx-migration.md +++ b/guides/multitenancy/old-mtx-migration.md @@ -20,8 +20,14 @@ Towards new multitenancy capabilities -::: warning -Make sure that you always use the latest version of the CAP modules using `npm outdated`. For Java, also check the versions configured in `pom.xml` files. +::: warning Separate model changes from migration +We strongly recommended to separate any model changes from the migration. If you need to do model changes for the migration, please deploy the application +based on `@sap/cds-mtx` and upgrade all tenants using the [upgrade endpoint](./old-mtx-apis.md#upgrade-base-model-from-filesystem-asynchronous) before you do the migration. +::: +::: warning Deprecated! Update all modules +Make sure that you always use the latest version of the CAP modules using `npm outdated`. For Java, also check the versions configured in `pom.xml` files. Since +`@sap/cds-mtx` is deprecated for quite some time now and will no longer run with, for example, the latest version of `@sap/cds`, updating the versions and adapting your application to it +can only be done together with the migration to `@sap/cds-mtxs`. Please also read all release notes carefully and check it for changes that need to be made to the configuration. ::: ## Functional Differences @@ -75,7 +81,6 @@ Some of the roles have changed with `@sap/cds-mtxs`. ### Temporary Limitations - Diagnose API isn't available. -- Upload of extension only works synchronously. ### Permanent Limitations @@ -371,6 +376,7 @@ In `@sap/cds-mtxs`, you can do the same configuration for the `cds.xt.Deployment }, } ``` +See also [Deployment configuration](./mtxs.md#deployment-config) ##### Extension Restrictions @@ -409,6 +415,13 @@ With `@sap/cds-mtxs`, the same configuration has moved to the `cds.xt.Extensibil } ``` +See also [Extensibility configuration](./mtxs.md#extensibility-config) + +### Verify Application Locally + +As first verification of your configuration changes, you can try to run your application locally in [hybrid mode](../../advanced/hybrid-testing#run-with-service-bindings). To bind all the service +that are bound to your existing application, you can call `cds bind --to-app-services `. Afterwards, you can run `cds run --profile hybrid --resolve-bindings`. + ### Migrate Tenant Content of Existing Applications Depending on the MTX features that your existing application has used, you need to execute some steps to move your data to the persistence used by `@sap/cds-mtxs`. From 757fda61c2a0129edf61da909ec8ab3f96f620c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 17:34:47 +0200 Subject: [PATCH 068/140] chore(deps): update dependency com.sap.cds:cds4j-api to v3.10.1 (#1854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.sap.cds:cds4j-api](http://www.sap.com) | `3.10.0` -> `3.10.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/com.sap.cds:cds4j-api/3.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.sap.cds:cds4j-api/3.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.sap.cds:cds4j-api/3.10.0/3.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.sap.cds:cds4j-api/3.10.0/3.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index d6ba06afdd..0758da0561 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -107,7 +107,7 @@ config.rewrites = rewrites config.themeConfig.capire = { versions: { java_services: '3.10.0', - java_cds4j: '3.10.0' + java_cds4j: '3.10.1' }, gotoLinks: [], maven_host_base: 'https://repo1.maven.org/maven2' From 80b54d72a514964cd58d4d4d22484a4d23155d35 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 17:35:03 +0200 Subject: [PATCH 069/140] chore(deps): update dependency @sap/cds to v8.9.4 (#1853) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@sap/cds](https://cap.cloud.sap/) | [`8.9.3` -> `8.9.4`](https://renovatebot.com/diffs/npm/@sap%2fcds/8.9.3/8.9.4) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@sap%2fcds/8.9.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@sap%2fcds/8.9.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@sap%2fcds/8.9.3/8.9.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@sap%2fcds/8.9.3/8.9.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe51f1e980..2b2aafc3b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2529,13 +2529,13 @@ ] }, "node_modules/@sap/cds": { - "version": "8.9.3", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.3.tgz", - "integrity": "sha512-ezeT/VgaIQX5gjomgmLcDst4kHWjsZpQWVxn2kJej5py8/MGYCylsQfFUJGChXor1F0jtTtAcIJGrP2a1Jdyqg==", + "version": "8.9.4", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.9.4.tgz", + "integrity": "sha512-pgEx855xxtrBkYEtvWOLHqBCvFePbV4ERCpssDn7K4G8WipoXMcOPCkAYq1aP+OVpjz2WMb3p7QSwu4qHwWFKw==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@sap/cds-compiler": ">=5.1", + "@sap/cds-compiler": "^5", "@sap/cds-fiori": "^1", "@sap/cds-foss": "^5.0.0" }, From 657b666f6c805f20ce9783f895363bf135d5b288 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 17:35:15 +0200 Subject: [PATCH 070/140] chore(deps): update dependency sass to v1.89.0 (#1852) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [sass](https://redirect.github.com/sass/dart-sass) | [`1.88.0` -> `1.89.0`](https://renovatebot.com/diffs/npm/sass/1.88.0/1.89.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/sass/1.89.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/sass/1.89.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/sass/1.88.0/1.89.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sass/1.88.0/1.89.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
sass/dart-sass (sass) ### [`v1.89.0`](https://redirect.github.com/sass/dart-sass/blob/HEAD/CHANGELOG.md#1890) [Compare Source](https://redirect.github.com/sass/dart-sass/compare/1.88.0...1.89.0) - Allow the Node package importer to load files even when there are multiple potential resolutions, as long as those resolutions all point to the same file.
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b2aafc3b8..fbbc47d5f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7804,9 +7804,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.88.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", - "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", + "version": "1.89.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz", + "integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==", "dev": true, "license": "MIT", "dependencies": { From 7096c913dd908127d828f8216f1f0abe52932084 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 18:34:22 +0200 Subject: [PATCH 071/140] chore(deps): update dependency com.sap.cds:cds-services-api to v3.10.1 (#1855) --- .vitepress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/config.js b/.vitepress/config.js index 0758da0561..2bff0cd425 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -106,7 +106,7 @@ config.rewrites = rewrites // Add custom capire info to the theme config config.themeConfig.capire = { versions: { - java_services: '3.10.0', + java_services: '3.10.1', java_cds4j: '3.10.1' }, gotoLinks: [], From 9e429b7c92e650ac50fc48f2c3c4e7672c53dff0 Mon Sep 17 00:00:00 2001 From: "Dr. David A. Kunz" Date: Sat, 17 May 2025 11:52:56 +0200 Subject: [PATCH 072/140] cds 9: modified input validations (#1809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [x] rm `@readonly` and `@insertonly` from Access Control Annotations - [x] rm `@Common.FieldControl` from Input Validation - [x] rm `@assert.notNull` from Input Validation - [x] mv `@assert.unique` to Database Constraints - [x] add link to database constraints in Input Validations - [x] document `not null` in Database Constraints - [x] document `not null` (in actions/functions) --------- Co-authored-by: Adrian GΓΆrler Co-authored-by: Daniel Hutzel Co-authored-by: RenΓ© Jeglinsky --- advanced/hana.md | 2 +- cds/annotations.md | 6 -- guides/databases.md | 102 ++++++++++++++++++++++---------- guides/providing-services.md | 110 ++++++++++++----------------------- 4 files changed, 110 insertions(+), 110 deletions(-) diff --git a/advanced/hana.md b/advanced/hana.md index b000cb1172..7d0d9a36d6 100644 --- a/advanced/hana.md +++ b/advanced/hana.md @@ -50,7 +50,7 @@ Steps to match the signature of a database object in a facade entity: * For a view, table function, or calculation view with parameters, check that the parameter names and types match, too. Functions with table-like input parameters are not supported. -> Note: If a field of that entity is defined as `not null` and you want to disable its runtime check, you can add [`@assert.notNull: false`](../guides/providing-services#assert-notnull). This is important if you want to use, for example [SAP HANA history tables](https://help.sap.com/docs/SAP_HANA_PLATFORM/6b94445c94ae495c83a19646e7c3fd56/d0b2c5142a19405fb912f71782cd0a84.html). +> Note: If a field of that entity is defined as `not null` and you want to disable its runtime check, you can add `@assert.notNull: false`. This is important if you want to use, for example [SAP HANA history tables](https://help.sap.com/docs/SAP_HANA_PLATFORM/6b94445c94ae495c83a19646e7c3fd56/d0b2c5142a19405fb912f71782cd0a84.html). As a result, the database name is defined by the name of the entity or its elements, after applying the SQL name mapping. diff --git a/cds/annotations.md b/cds/annotations.md index 25acce2561..5903310a28 100644 --- a/cds/annotations.md +++ b/cds/annotations.md @@ -28,8 +28,6 @@ uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/ | Annotation | Description | |---------------|------------------------------------------------------------------| -| `@readonly` | see [Input Validation](../guides/providing-services#readonly) | -| `@insertonly` | see [Generic Handlers](../guides/providing-services) | | `@restrict` | see [Authorization](../guides/security/authorization#restrict-annotation) | | `@requires` | see [Authorization](../guides/security/authorization#requires) | @@ -40,12 +38,9 @@ uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/ |---------------------|----------------------------------------------------------------------| | `@readonly ` | see [Input Validation](../guides/providing-services#readonly) | | `@mandatory` | see [Input Validation](../guides/providing-services#mandatory) | -| `@assert.unique` | see [Input Validation](../guides/providing-services#assert-unique) | -| `@assert.integrity` | see [Input Validation](../guides/databases#database-constraints) | | `@assert.target` | see [Input Validation](../guides/providing-services#assert-target) | | `@assert.format` | see [Input Validation](../guides/providing-services#assert-format) | | `@assert.range` | see [Input Validation](../guides/providing-services#assert-range) | -| `@assert.notNull` | see [Input Validation](../guides/providing-services#assert-notnull) | @@ -102,4 +97,3 @@ Intrinsically supported OData Annotations: | `@Core.IsMediaType` | see [Media Data](../guides/providing-services#serving-media-data) | | `@Core.IsUrl` | see [Media Data](../guides/providing-services#serving-media-data) | | `@Capabilities...` | see [Fiori](../advanced/fiori) | -| `@Common.FieldControl` | see [Input Validation](../guides/providing-services#common-fieldcontrol) | diff --git a/guides/databases.md b/guides/databases.md index ab2325c957..d16076f53d 100644 --- a/guides/databases.md +++ b/guides/databases.md @@ -784,6 +784,46 @@ Find here a collection of resources on selected databases and their reference do ## Database Constraints +### Not Null + +You can specify that a column's value must not be `NULL` by adding the [`not null` constraint](../cds/cdl#null-values) to the element, for example: + +```cds +entity Books { + key ID: Integer; + title: String not null; +} +``` + + +### Unique + +Annotate an entity with `@assert.unique.`, specifying one or more element combinations to enforce uniqueness checks on all CREATE and UPDATE operations. For example: + +```cds +@assert.unique: { + locale: [ parent, locale ], + timeslice: [ parent, validFrom ], +} +entity LocalizedTemporalData { + key record_ID : UUID; // technical primary key + parent : Association to Data; + locale : String; + validFrom : Date; + validTo : Date; +} +``` +{.indent} + +The value of the annotation is an array of paths referring to elements in the entity. These elements may be of a scalar type, structs, or managed associations. Individual foreign keys or unmanaged associations are not supported. + +If structured elements are specified, the unique constraint will contain all columns stemming from it. If the path points to a managed association, the unique constraint will contain all foreign key columns stemming from it. +::: tip +You don't need to specify `@assert.unique` constraints for the primary key elements of an entity as these are automatically secured by a SQL `PRIMARY KEY` constraint. +::: + +### Foreign Keys + The information about foreign key relations contained in the associations of CDS models can be used to generate foreign key constraints on the database tables. Within CAP, referential consistency is established only at commit. The ["deferred" concept for foreign key constraints](https://www.sqlite.org/foreignkeys.html) in SQL databases allows the constraints to be checked and enforced at the time of the [COMMIT statement within a transaction](https://www.sqlite.org/lang_transaction.html) rather than immediately when the data is modified, providing more flexibility in maintaining data integrity. Enable generation of foreign key constraints on the database with: @@ -906,7 +946,7 @@ TODO: remove the above with cds9 The `@sap/cds-compiler` and all CAP Node.js database services come with out of the box support for common OData functions. ::: warning Case Sensitivity -The OData function mappings are case-sensitive and must be written as in the list below. +The OData function mappings are case-sensitive and must be written as in the list below. ::: Assuming you have the following entity definition: @@ -940,28 +980,28 @@ For example, `startsWith` instead of `startswith` will be passed as-is to the da #### String Functions -- `concat(x, y, ...)` +- `concat(x, y, ...)` Concatenates the given strings or numbers. -- `trim(x)` +- `trim(x)` Removes leading and trailing whitespaces. -- `contains(x, y)` +- `contains(x, y)` Checks whether `y` is contained in `x` (case-sensitive). -- `startswith(x, y)` +- `startswith(x, y)` Checks whether `y` starts with `x` (case-sensitive). -- `endswith(x, y)` +- `endswith(x, y)` Checks whether `y` ends with `x` (case-sensitive). -- `matchespattern(x, y)` +- `matchespattern(x, y)` Checks whether `x` matches the regular expression `y`. -- `indexof(x, y)` 1 +- `indexof(x, y)` 1 Returns the index of the first occurrence of `y` in `x` (case-sensitive). -- `substring(x, i, n?)` 1 +- `substring(x, i, n?)` 1 Extracts a substring from `x` starting at index `i` (0-based) with an optional length `n`. | Parameter | Positive | Negative | Omitted @@ -969,29 +1009,29 @@ For example, `startsWith` instead of `startswith` will be passed as-is to the da | `i` | starts at index `i` | starts `i` positions before the end | | `n` | extracts `n` characters | invalid | extracts until the end of the string -- `length(x)` +- `length(x)` Returns the length of the string `x`. -- `tolower(x)` +- `tolower(x)` Converts all characters in `x` to lowercase. -- `toupper(x)` +- `toupper(x)` Converts all characters in `x` to uppercase. > 1 These functions work zero-based. For example, `substring('abcdef', 1, 3)` returns 'bcd' #### Numeric Functions -- `ceiling(x)` +- `ceiling(x)` Rounds the numeric parameter up to the nearest integer. -- `floor(x)` +- `floor(x)` Rounds the numeric parameter down to the nearest integer. -- `round(x)` - Rounds the numeric parameter to the nearest integer. +- `round(x)` + Rounds the numeric parameter to the nearest integer. The midpoint between two integers is rounded away from zero (e.g., `0.5` β†’ `1` and `-0.5` β†’ `-1`). - + ::: warning `round` function with more than one argument Note that most databases support `round` functions with multiple arguments, the second parameter being the precision. SAP HANA even has a third argument which is the rounding mode. @@ -1000,24 +1040,24 @@ For example, `startsWith` instead of `startswith` will be passed as-is to the da #### Date and Time Functions -- `year(x)`, `month(x)`, `day(x)`, `hour(x)`, `minute(x)`, `second(x)` +- `year(x)`, `month(x)`, `day(x)`, `hour(x)`, `minute(x)`, `second(x)` Extracts and returns specific date / time parts as integer value from a given `cds.DateTime`, `cds.Date`, or `cds.Time`. -- `time(x)`, `date(x)` +- `time(x)`, `date(x)` Extracts and returns a time or date from a given `cds.DateTime`, `cds.Date`, or `cds.Time`. -- `fractionalseconds(x)` +- `fractionalseconds(x)` Returns a `Decimal` representing the fractional seconds for a given `cds.Timestamp`. -- `maxdatetime()` +- `maxdatetime()` Returns the latest possible point in time: `'9999-12-31T23:59:59.999Z'`. -- `mindatetime()` +- `mindatetime()` Returns the earliest possible point in time: `'0001-01-01T00:00:00.000Z'`. #### Aggregate Functions -- `min(x)`, `max(x)`, `sum(x)`, `average(x)`, `count(x)`, `countdistinct(x)` +- `min(x)`, `max(x)`, `sum(x)`, `average(x)`, `count(x)`, `countdistinct(x)` Standard aggregate functions used to calculate minimum, maximum, sum, average, count, and distinct count of values. @@ -1030,30 +1070,30 @@ out of the box support for some common SAP HANA functions, to further increase t For the SAP HANA functions, both usages are allowed: all-lowercase as given above, as well as all-uppercase. ::: -- `years_between` +- `years_between` Computes the number of years between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/years-between-function-datetime?locale=en-US)) -- `months_between` +- `months_between` Computes the number of months between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/months-between-function-datetime?locale=en-US)) -- `days_between` +- `days_between` Computes the number of days between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/days-between-function-datetime?locale=en-US)) -- `seconds_between` +- `seconds_between` Computes the number of seconds between two specified dates. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/seconds-between-function-datetime?locale=en-US)) -- `nano100_between` +- `nano100_between` Computes the time difference between two dates to the precision of 0.1 microseconds. ([link](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/nano100-between-function-datetime?locale=en-US)) ### Special Runtime Functions In addition to the OData and SAP HANA standard functions, the **CAP runtimes** provides special functions that are only available for runtime queries: -- `search(x, y)` +- `search(x, y)` Checks whether `y` is contained in any element of `x` (fuzzy matching may apply). See [Searching Data](../guides/providing-services#searching-data) for more details. -- `session_context()` +- `session_context()` Utilizes standard variable names to maintain session context. Refer to [Session Variables](#session-variables) for additional information. -- `now()` +- `now()` Returns the current timestamp. ## Using Native Features { #native-db-functions} diff --git a/guides/providing-services.md b/guides/providing-services.md index 5589b34b39..ec78291dc1 100644 --- a/guides/providing-services.md +++ b/guides/providing-services.md @@ -736,7 +736,7 @@ The records are locked until the end of the transaction by commit or rollback st Here's an overview table: | State | Select Without Lock | Select With Shared Lock | Select With Exclusive Lock/Update | -| --------------- | ----------------------- | -------------------------- | ------------------------------------- | +| --------------- | ----------------------- | -------------------------- | ------------------------------------- | | not locked | passes | passes | passes | | shared lock | passes | passes | waits | | exclusive lock | passes | waits | waits | @@ -772,6 +772,7 @@ Do not use the `@readonly` annotation on keys in all variants.
+ ### `@mandatory` Elements marked with `@mandatory` are checked for nonempty input: `null` and (trimmed) empty strings are rejected. @@ -795,42 +796,49 @@ In addition to server-side input validation as introduced above, this adds a cor
-### `@Common.FieldControl` -{#common-fieldcontrol} -The input validation for `@Common.FieldControl: #Mandatory` and `@Common.FieldControl: #ReadOnly` is done from the CAP runtimes automatically. -::: warning -Custom validations are required when using static or dynamic numeric values, for example, `@Common.FieldControl: 1` or `@Common.FieldControl: integer_field`. -::: +### `@assert .format` +Allows you to specify a regular expression string (in ECMA 262 format in CAP Node.js and java.util.regex.Pattern format in CAP Java) that all string input must match. +```cds +entity Foo { + bar : String @assert.format: '[a-z]ear'; +} +``` -### `@assert .unique` -Annotate an entity with `@assert.unique.`, specifying one or more element combinations to enforce uniqueness checks on all CREATE and UPDATE operations. For example: +### `@assert .range` + +Allows you to specify `[ min, max ]` ranges for elements with ordinal types — that is, numeric or date/time types. For `enum` elements, `true` can be specified to restrict all input to the defined enum values. ```cds -@assert.unique: { - locale: [ parent, locale ], - timeslice: [ parent, validFrom ], -} -entity LocalizedTemporalData { - key record_ID : UUID; // technical primary key - parent : Association to Data; - locale : String; - validFrom : Date; validTo : Date; +entity Foo { + bar : Integer @assert.range: [ 0, 3 ]; + boo : Decimal @assert.range: [ 2.1, 10.25 ]; + car : DateTime @assert.range: ['2018-10-31', '2019-01-15']; + zoo : String @assert.range enum { high; medium; low; }; } ``` -{.indent} +#### ... with open intervals -This annotation is applicable to entities, which result in tables in SQL databases only. +By default, specified `[min,max]` ranges are interpreted as closed intervals, that means, the performed checks are `min ≀ input ≀ max`. You can also specify open intervals by wrapping the *min* and/or *max* values into parenthesis like that: -The value of the annotation is an array of paths referring to elements in the entity. These elements may be of a scalar type, structs, or managed associations. Individual foreign keys or unmanaged associations are not supported. + +```cds +@assert.range: [(0),100] // 0 < input ≀ 100 +@assert.range: [0,(100)] // 0 ≀ input < 100 +@assert.range: [(0),(100)] // 0 < input < 100 +``` +In addition, you can use an underscore `_` to represent *Infinity* like that: + +```cds +@assert.range: [(0),_] // positive numbers only, _ means +Infinity here +@assert.range: [_,(0)] // negative number only, _ means -Infinity here +``` +> Basically values wrapped in parentheses _`(x)`_ can be read as _excluding `x`_ for *min* or *max*. Note that the underscore `_` doesn't have to be wrapped into parenthesis, as by definition no number can be equal to *Infinity* . -If structured elements are specified, the unique constraint will contain all columns stemming from it. If the path points to a managed association, the unique constraint will contain all foreign key columns stemming from it. -::: tip -You don't need to specify `@assert.unique` constraints for the primary key elements of an entity as these are automatically secured by a SQL `PRIMARY KEY` constraint. -::: +Support for open intervals and infinity is available for CAP Node.js since `@sap/cds` version **8.5** and in CAP Java since version **3.5.0**. @@ -911,59 +919,15 @@ Cross-service checks are not supported. It is expected that the associated entit The `@assert.target` check constraint relies on database locks to ensure accurate results in concurrent scenarios. However, locking is a database-specific feature, and some databases don't permit to lock certain kinds of objects. On SAP HANA, for example, views with joins or unions can't be locked. Do not use `@assert.target` on such artifacts/entities. ::: -### `@assert .format` - -Allows you to specify a regular expression string (in ECMA 262 format in CAP Node.js and java.util.regex.Pattern format in CAP Java) that all string input must match. - -```cds -entity Foo { - bar : String @assert.format: '[a-z]ear'; -} -``` - -### `@assert .range` - -Allows you to specify `[ min, max ]` ranges for elements with ordinal types — that is, numeric or date/time types. For `enum` elements, `true` can be specified to restrict all input to the defined enum values. - -```cds -entity Foo { - bar : Integer @assert.range: [ 0, 3 ]; - boo : Decimal @assert.range: [ 2.1, 10.25 ]; - car : DateTime @assert.range: ['2018-10-31', '2019-01-15']; - zoo : String @assert.range enum { high; medium; low; }; -} -``` -#### ... with open intervals - -By default, specified `[min,max]` ranges are interpreted as closed intervals, that means, the performed checks are `min ≀ input ≀ max`. You can also specify open intervals by wrapping the *min* and/or *max* values into parenthesis like that: - -```cds -@assert.range: [(0),100] // 0 < input ≀ 100 -@assert.range: [0,(100)] // 0 ≀ input < 100 -@assert.range: [(0),(100)] // 0 < input < 100 -``` -In addition, you can use an underscore `_` to represent *Infinity* like that: - -```cds -@assert.range: [(0),_] // positive numbers only, _ means +Infinity here -@assert.range: [_,(0)] // negative number only, _ means -Infinity here -``` -> Basically values wrapped in parentheses _`(x)`_ can be read as _excluding `x`_ for *min* or *max*. Note that the underscore `_` doesn't have to be wrapped into parenthesis, as by definition no number can be equal to *Infinity* . +
-Support for open intervals and infinity is available for CAP Node.js since `@sap/cds` version **8.5** and in CAP Java since version **3.5.0**. -### `@assert .notNull` +### Database Constraints -Annotate a property with `@assert.notNull: false` to have it ignored during the generic not null check, for example if your persistence fills it automatically. +Next to input validation, you can add [database constraints](databases#database-constraints) to prevent invalid data from being persisted. -```cds -entity Foo { - bar : String not null @assert.notNull: false; -} -``` -
## Custom Logic @@ -1089,6 +1053,8 @@ service Sue { action order (x:Integer) returns Integer; //bound to the collection and not a specific instance of Foo action customCreate (in: many $self, x: String) returns Foo; + // All parameters are optional by default, unless marked with `not null`: + action discard (reason: String not null); } } ``` From f86f488dec6b332426ddffa27de3cc19c7044f8a Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Mon, 19 May 2025 10:23:24 +0200 Subject: [PATCH 073/140] Fix `cds build` spacing for learn-more --- guides/deployment/custom-builds.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/guides/deployment/custom-builds.md b/guides/deployment/custom-builds.md index 19b519fe0a..ab138c3399 100644 --- a/guides/deployment/custom-builds.md +++ b/guides/deployment/custom-builds.md @@ -65,11 +65,14 @@ The `for` property defines the executed build task type. Currently supported typ In this scenario the required services are implemented by the Node.js application itself which is the default for Node.js. - `mtx-sidecar`: Creates a deployment layout for Java or Node.js projects using multitenancy, feature toggles, extensibility or a combination of these _with_ sidecar architecture.
Java projects have to use a sidecar architecture. For Node.js this is optional, but allows for better scalability in multitenant scenarios. + [Learn more about **Multitenant Saas Application Deployment**](./to-cf){.learn-more} - `mtx-extension`: Creates a deployment layout (_extension.tgz_ file) for an MTX extension project, which is required for extension activation using `cds push`. Extension point restrictions defined by the SaaS app provider are validated by default. If any restriction is violated the build aborts and the errors are logged.
- The build task is created by default for projects that have `"cds": { "extends": "\" }` configured in their _package.json_.
+ The build task is created by default for projects that have `"cds": { "extends": "\" }` configured in their _package.json_. + [Learn more about **Extending and Customizing SaaS Solutions**](../extensibility/customization){.learn-more} -- Additional types may be supported by build plugin contributions.
+- Additional types may be supported by build plugin contributions. + [Learn more about **Running Build Plugins**](#run-the-plugin){.learn-more} Build tasks can be customized using the following properties: @@ -78,6 +81,7 @@ Build tasks can be customized using the following properties: - `dest`: Optional destination of the modules builds, relative to the enclosing project. The _src_ folder is used by default. - `options`: Sets the options according to the target technology.
- `model`: It has type _string_ or _array of string_. The given list of folders or individual _.cds_ file names is resolved based on the current working dir or the project folder passed to cds build. CDS built-in models (prefix _@sap/cds*_) are added by default to the user-defined list of models. + [Learn more about **Core Data Services (CDS)**](../../cds/){.learn-more} **Note:** From a52007dbabd9a2ee3ffbe8f61c1ebcfbf9f3ccc1 Mon Sep 17 00:00:00 2001 From: Steffen Weinstock <79531202+stewsk@users.noreply.github.com> Date: Mon, 19 May 2025 14:13:24 +0200 Subject: [PATCH 074/140] (cds 9) Std DB functions by default (#1829) --- guides/databases.md | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/guides/databases.md b/guides/databases.md index d16076f53d..b110c785a3 100644 --- a/guides/databases.md +++ b/guides/databases.md @@ -353,10 +353,6 @@ The database services guarantee the identical behavior of these operators: In particular, the translation of `!=` to `IS NOT` in SQLite β€” or to `IS DISTINCT FROM` in standard SQL, or to an equivalent polyfill in SAP HANA β€” greatly improves the portability of your code. -::: warning Runtime Only -The operator mappings are available for runtime queries only, but not in CDS files. -::: - ### Session Variables {.node} @@ -926,20 +922,8 @@ Instead, they protect the integrity of your data in the database layer against p ## Standard Database Functions { #functions-mappings-for-runtime-queries } -A specified set of standard functions - inspired by [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions) and [SAP HANA](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/alphabetical-list-of-functions?locale=en-US) - is supported in a **database-agnostic**, hence portable way, and translated to the best-possible native SQL functions or polyfills. - -Those functions are automatically mapped during runtime (Node.js) already today. -To switch on the same mappings for your CDL files, you have to set: - -cds.cdsc.standardDatabaseFunctions = true - -::: tip -this will be the default starting with `@sap/cds-compiler >= 9` and hence is only needed for earlier versions. -::: +A specified set of standard functions - inspired by [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions) and [SAP HANA](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/alphabetical-list-of-functions?locale=en-US) - is supported in a **database-agnostic**, hence portable way, and translated to the best-possible native SQL functions or polyfills during runtime (currently only Node.js) and for your CDL files. - ### OData standard functions From 3c3e9fb44b1cb7992aeb3e23df55e252dec1d558 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 16:58:05 +0200 Subject: [PATCH 075/140] chore(deps): update dependency markdownlint-cli to v0.45.0 (#1858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [markdownlint-cli](https://redirect.github.com/igorshubovych/markdownlint-cli) | [`0.44.0` -> `0.45.0`](https://renovatebot.com/diffs/npm/markdownlint-cli/0.44.0/0.45.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/markdownlint-cli/0.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/markdownlint-cli/0.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/markdownlint-cli/0.44.0/0.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/markdownlint-cli/0.44.0/0.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
igorshubovych/markdownlint-cli (markdownlint-cli) ### [`v0.45.0`](https://redirect.github.com/igorshubovych/markdownlint-cli/compare/v0.44.0...192ad822316c3a22fb3d3cc8aa6eafa0b8488360) [Compare Source](https://redirect.github.com/igorshubovych/markdownlint-cli/compare/v0.44.0...v0.45.0)
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 233 ++++++++++++++++++++++++++-------------------- 1 file changed, 130 insertions(+), 103 deletions(-) diff --git a/package-lock.json b/package-lock.json index fbbc47d5f5..15b8652b40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2251,17 +2251,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.30.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", @@ -5313,6 +5302,30 @@ "node": ">= 0.4" } }, + "node_modules/glob": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz", + "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5326,6 +5339,22 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global-directory": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", @@ -5784,6 +5813,22 @@ "dev": true, "license": "ISC" }, + "node_modules/jackspeak": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", + "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -5947,6 +5992,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -5994,120 +6049,75 @@ } }, "node_modules/markdownlint": { - "version": "0.37.4", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.37.4.tgz", - "integrity": "sha512-u00joA/syf3VhWh6/ybVFkib5Zpj2e5KB/cfCei8fkSRuums6nyisTWGqjTWIOFoFwuXoTBQQiqlB4qFKp8ncQ==", + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", + "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", "dev": true, "license": "MIT", "dependencies": { - "markdown-it": "14.1.0", - "micromark": "4.0.1", - "micromark-core-commonmark": "2.0.2", - "micromark-extension-directive": "3.0.2", + "micromark": "4.0.2", + "micromark-core-commonmark": "2.0.3", + "micromark-extension-directive": "4.0.0", "micromark-extension-gfm-autolink-literal": "2.1.0", "micromark-extension-gfm-footnote": "2.1.0", - "micromark-extension-gfm-table": "2.1.0", + "micromark-extension-gfm-table": "2.1.1", "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.1" + "micromark-util-types": "2.0.2" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/markdownlint-cli": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.44.0.tgz", - "integrity": "sha512-ZJTAONlvF9NkrIBltCdW15DxN9UTbPiKMEqAh2EU2gwIFlrCMavyCEPPO121cqfYOrLUJWW8/XKWongstmmTeQ==", + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz", + "integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==", "dev": true, "license": "MIT", "dependencies": { "commander": "~13.1.0", - "glob": "~10.4.5", - "ignore": "~7.0.3", + "glob": "~11.0.2", + "ignore": "~7.0.4", "js-yaml": "~4.1.0", "jsonc-parser": "~3.3.1", "jsonpointer": "~5.0.1", - "markdownlint": "~0.37.4", - "minimatch": "~9.0.5", + "markdown-it": "~14.1.0", + "markdownlint": "~0.38.0", + "minimatch": "~10.0.1", "run-con": "~1.3.2", - "smol-toml": "~1.3.1" + "smol-toml": "~1.3.4" }, "bin": { "markdownlint": "markdownlint.js" }, "engines": { - "node": ">=18" - } - }, - "node_modules/markdownlint-cli/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=20" } }, "node_modules/markdownlint-cli/node_modules/ignore": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", - "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", + "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", "dev": true, "license": "MIT", "engines": { "node": ">= 4" } }, - "node_modules/markdownlint-cli/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/markdownlint-cli/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "node_modules/markdownlint-cli/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, - "license": "ISC" - }, - "node_modules/markdownlint-cli/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", + "license": "ISC", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6445,9 +6455,9 @@ } }, "node_modules/micromark": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz", - "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", "dev": true, "funding": [ { @@ -6481,9 +6491,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz", - "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", "dev": true, "funding": [ { @@ -6516,9 +6526,9 @@ } }, "node_modules/micromark-extension-directive": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", - "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", "dev": true, "license": "MIT", "dependencies": { @@ -6574,9 +6584,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", - "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", "dev": true, "license": "MIT", "dependencies": { @@ -6987,9 +6997,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", - "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "dev": true, "funding": [ { @@ -7370,6 +7380,23 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -8150,9 +8177,9 @@ } }, "node_modules/smol-toml": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.1.tgz", - "integrity": "sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.4.tgz", + "integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==", "dev": true, "license": "BSD-3-Clause", "engines": { From 330bc5c4b57b2013d05aeea6c61a3c5d97c76477 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 16:58:17 +0200 Subject: [PATCH 076/140] chore(deps): update dependency @types/express to v4.17.22 (#1857) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@types/express](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/express) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express)) | [`4.17.21` -> `4.17.22`](https://renovatebot.com/diffs/npm/@types%2fexpress/4.17.21/4.17.22) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fexpress/4.17.22?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fexpress/4.17.22?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fexpress/4.17.21/4.17.22?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fexpress/4.17.21/4.17.22?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15b8652b40..4cff4716de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2844,9 +2844,9 @@ "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "version": "4.17.22", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.22.tgz", + "integrity": "sha512-eZUmSnhRX9YRSkplpz0N+k6NljUUn5l3EWZIKZvYzhvMphEuNiyyy1viH/ejgt66JWgALwC/gtSUAeQKtSwW/w==", "dev": true, "license": "MIT", "dependencies": { From 3aef5737962dd611405ed48d8ed069381729ae08 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 16:58:27 +0200 Subject: [PATCH 077/140] chore(deps): update dependency eslint to v9.27.0 (#1856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [eslint](https://eslint.org) ([source](https://redirect.github.com/eslint/eslint)) | [`9.26.0` -> `9.27.0`](https://renovatebot.com/diffs/npm/eslint/9.26.0/9.27.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/eslint/9.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint/9.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint/9.26.0/9.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint/9.26.0/9.27.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
eslint/eslint (eslint) ### [`v9.27.0`](https://redirect.github.com/eslint/eslint/compare/v9.26.0...b9080cf28d88f934941a545a033eb960eceeadbd) [Compare Source](https://redirect.github.com/eslint/eslint/compare/v9.26.0...v9.27.0)
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 542 ++++++---------------------------------------- 1 file changed, 67 insertions(+), 475 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4cff4716de..fb9ae71fae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1368,9 +1368,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1429,13 +1429,16 @@ } }, "node_modules/@eslint/js": { - "version": "9.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", + "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { @@ -1449,13 +1452,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.14.0", "levn": "^0.4.1" }, "engines": { @@ -1597,312 +1600,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.0.tgz", - "integrity": "sha512-k/1pb70eD638anoi0e8wUGAlbMJXyvdV4p62Ko+EZ7eBe1xMx8Uhak1R5DgfoofsK5IBBnRwsYGTaLZl+6/+RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.3", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "dev": true, - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3717,6 +3414,7 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -3727,6 +3425,7 @@ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -3741,6 +3440,7 @@ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "get-intrinsic": "^1.2.6" @@ -3964,6 +3664,7 @@ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -3974,6 +3675,7 @@ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -4009,20 +3711,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4314,6 +4002,7 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -4374,6 +4063,7 @@ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -4395,7 +4085,8 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -4417,6 +4108,7 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -4453,6 +4145,7 @@ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" } @@ -4463,6 +4156,7 @@ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" } @@ -4473,6 +4167,7 @@ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -4524,7 +4219,8 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -4540,9 +4236,9 @@ } }, "node_modules/eslint": { - "version": "9.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", + "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4550,14 +4246,13 @@ "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.26.0", - "@eslint/plugin-kit": "^0.2.8", + "@eslint/js": "9.27.0", + "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -4581,8 +4276,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "zod": "^3.24.2" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -4846,33 +4540,11 @@ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } }, - "node_modules/eventsource": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz", - "integrity": "sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", - "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -4921,22 +4593,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5203,6 +4859,7 @@ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -5239,6 +4896,7 @@ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5269,6 +4927,7 @@ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-define-property": "^1.0.1", @@ -5294,6 +4953,7 @@ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -5390,6 +5050,7 @@ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" }, @@ -5463,6 +5124,7 @@ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" }, @@ -5476,6 +5138,7 @@ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5555,6 +5218,7 @@ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5663,7 +5327,8 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/ini": { "version": "4.1.1", @@ -5681,6 +5346,7 @@ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.10" } @@ -5786,13 +5452,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true, - "license": "MIT" - }, "node_modules/is-what": { "version": "4.1.16", "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", @@ -6165,6 +5824,7 @@ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" } @@ -7188,22 +6848,13 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.4" }, @@ -7217,6 +6868,7 @@ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -7224,16 +6876,6 @@ "node": ">= 0.8" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/oniguruma-to-es": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.10.0.tgz", @@ -7349,6 +6991,7 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -7432,16 +7075,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, "node_modules/postcss": { "version": "8.4.49", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", @@ -7523,6 +7156,7 @@ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -7595,6 +7229,7 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -7735,33 +7370,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/router/node_modules/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - } - }, "node_modules/run-con": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", @@ -7821,14 +7429,16 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/sass": { "version": "1.89.0", @@ -7964,7 +7574,8 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/shebang-command": { "version": "2.0.0", @@ -8093,6 +7704,7 @@ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -8113,6 +7725,7 @@ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -8130,6 +7743,7 @@ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -8149,6 +7763,7 @@ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -8233,6 +7848,7 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -8476,6 +8092,7 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.6" } @@ -8692,6 +8309,7 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -8730,6 +8348,7 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -9270,13 +8889,6 @@ "node": ">=8" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/xdg-basedir": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", @@ -9336,26 +8948,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "dev": true, - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", From 233384c0e6a09fbde9d037ae7a78bc49d9a62b1f Mon Sep 17 00:00:00 2001 From: Steffen Weinstock <79531202+stewsk@users.noreply.github.com> Date: Tue, 20 May 2025 09:13:37 +0200 Subject: [PATCH 078/140] (cds 9) Propagation of doc comments (#1825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doc comments are no longer propagated. --------- Co-authored-by: Andre Meyering Co-authored-by: RenΓ© Jeglinsky --- cds/cdl.md | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/cds/cdl.md b/cds/cdl.md index cee2e5532d..c18c0dda1d 100644 --- a/cds/cdl.md +++ b/cds/cdl.md @@ -302,20 +302,9 @@ entity Employees { ``` The text of a doc comment is stored in CSN in the property `doc`. -When generating OData EDM(X), it appears as value for the annotation `@Core.Description`. - -When generating output for deployment to SAP HANA, the first paragraph of a doc comment is translated to the HANA `COMMENT` feature for tables, table columns, and for views (but not for view columns): - -```sql -CREATE TABLE Employees ( - ID INTEGER, - name NVARCHAR(...) COMMENT 'I am the description for "name"' -) COMMENT 'I am the description for "Employee"' -``` - -::: tip -Propagation of doc comments can be stopped via an empty one: `/** */`. -::: +Doc comments are not propagated. For example, a doc comment defined for an entity +isn't automatically copied to projections of this entity. +When generating OData EDM(X), doc comments are translated to the annotation `@Core.Description`. In CAP Node.js, doc comments need to be switched on when calling the compiler: @@ -331,13 +320,20 @@ cds.compile(..., { docs: true }) ::: -::: tip Doc comments are enabled by default in CAP Java. -In CAP Java, doc comments are automatically enabled by the [CDS Maven Plugin](../java/developing-applications/building#cds-maven-plugin). In generated interfaces they are [converted to corresponding Javadoc comments](../java/assets/cds-maven-plugin-site/generate-mojo.html#documentation). +::: tip Doc comments are automatically enabled in CAP Java. +In CAP Java, doc comments are automatically enabled by the [CDS Maven Plugin](../java/developing-applications/building#cds-maven-plugin). +In generated interfaces they are [converted to corresponding Javadoc comments](../java/assets/cds-maven-plugin-site/generate-mojo.html#documentation). ::: +When generating output for deployment to SAP HANA, the first paragraph of a doc comment is translated +to the HANA `COMMENT` feature for tables, table columns, and for views (but not for view columns): - - +```sql +CREATE TABLE Employees ( + ID INTEGER, + name NVARCHAR(...) COMMENT 'I am the description for "name"' +) COMMENT 'I am the description for "Employee"' +``` ## Entities & Type Definitions From 7cc1fdd25842d9be70fadc5b53d67d701d42027a Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Tue, 20 May 2025 09:36:49 +0200 Subject: [PATCH 079/140] add I-Suite AEM --- plugins/index.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/index.md b/plugins/index.md index d19f5e3989..5c8518b154 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -393,6 +393,15 @@ Available for: [![Node.js logo](../assets/logos/nodejs.svg){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/event-broker#readme) [![Java logo](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/cap-java/cds-feature-event-hub#readme) +## SAP Integration Suite, advanced event mesh +{#advanced-event-mesh} + +[SAP Integration Suite, advanced event mesh](https://www.sap.com/germany/products/technology-platform/integration-suite/advanced-event-mesh.html) allows you to, amongst others, integrate non-SAP systems into your event-driven architecture. + +Available for: + +[![Node.js logo](../assets/logos/nodejs.svg){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/advanced-event-mesh#readme) +[![Java logo](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/cap-java/cds-feature-advanced-event-mesh#readme) ## ABAP RFC From 450d2bbfb7ed0d848704dfb8529b154d92488972 Mon Sep 17 00:00:00 2001 From: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Date: Tue, 20 May 2025 10:12:27 +0200 Subject: [PATCH 080/140] cds9: rm draft compat flag (#1768) --- guides/databases-sqlite.md | 2 +- node.js/fiori.md | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/guides/databases-sqlite.md b/guides/databases-sqlite.md index 185aced81e..b93ea6b89a 100644 --- a/guides/databases-sqlite.md +++ b/guides/databases-sqlite.md @@ -650,7 +650,7 @@ ID;title;author.ID;currency.code // [!code --] As mentioned in [Using Lean Draft](#using-lean-draft), we eliminated all draft handling from new database service implementations, and instead implemented draft in a modular, non-intrusive, and optimized way β€” called *'Lean Draft'*. -When using the new service, the new `cds.fiori.lean_draft` mode is automatically switched on. You may additionally switch on cds.fiori.draft_compat:true in case you run into problems. +When using the new service, the new `cds.fiori.lean_draft` mode is automatically switched on. More detailed documentation for that is coming. diff --git a/node.js/fiori.md b/node.js/fiori.md index 3b1e5eb112..b3b5316fce 100644 --- a/node.js/fiori.md +++ b/node.js/fiori.md @@ -64,10 +64,6 @@ Additionally, you can add your logic to the draft-specific events as follows: - The `EDIT` event is triggered when you start editing an active entity. As a result `MyEntity.drafts` is created. - The `SAVE` event is just a shortcut for `['UPDATE', 'CREATE']` on an active entity. This event is also triggered when you press the `SAVE` button in UI after finishing editing your draft. Note, that composition children of the active entity will also be updated or created. -::: info Compatibility flag -For compatibility to previous variants, set `cds.fiori.draft_compat` to `true`. -::: - ### Draft Locks To prevent inconsistency, the entities with draft are locked for modifications by other users. The lock is released when the draft is saved, canceled or a timeout is hit. The default timeout is 15 minutes. You can configure this timeout by the following application configuration property: From 96255c681b25a8657d576a16f18b5f77bc544715 Mon Sep 17 00:00:00 2001 From: Steffen Weinstock <79531202+stewsk@users.noreply.github.com> Date: Tue, 20 May 2025 10:15:20 +0200 Subject: [PATCH 081/140] (cds9) remove section on "compile to hdbcds" (#1789) Backend hdbcds is deprecated, using it leads to an error. --- node.js/cds-compile.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/node.js/cds-compile.md b/node.js/cds-compile.md index db25936742..b28c6f36d9 100644 --- a/node.js/cds-compile.md +++ b/node.js/cds-compile.md @@ -183,15 +183,6 @@ for (let [edm,{file,suffix}] of all) console.log (file,suffix,edm) ``` - -### .hdbcds() {.method .deprecated} - -Generates `hdbcds` output. - -Current SAP HANA Cloud versions do no longer support `.hdbcds`. The command is supported for backward compatibility with older versions of [SAP HANA Service for SAP BTP](https://help.sap.com/docs/HANA_SERVICE). - -Use [`cds.compile.to.hana`](#hana) instead. - ### .hdbtable() {.method .deprecated} Use [`cds.compile.to.hana`](#hana) instead. From 0c91bf1876a584cc567d5cd50f58ac3f484449cc Mon Sep 17 00:00:00 2001 From: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Date: Tue, 20 May 2025 10:11:48 +0200 Subject: [PATCH 082/140] cds9: remove fallback to default language (#1766) --- guides/i18n.md | 1 - 1 file changed, 1 deletion(-) diff --git a/guides/i18n.md b/guides/i18n.md index 2cb527c157..245e1d417d 100644 --- a/guides/i18n.md +++ b/guides/i18n.md @@ -186,7 +186,6 @@ Upon incoming requests at runtime, the user's preferred language is determined a 1. The value of the `sap-locale` URL parameter, if present. 2. The value of the `sap-language` URL parameter, but only if it's `1Q`, `2Q` or `3Q` as described below. 3. The first entry from the request's `Accept-Language` header. - 4. The `default_language` configured on the app level. 2. Narrow to normalized locales as described below. ::: tip CAP Node.js accepts formats following the available standards of POSIX and RFC 1766, and transforms them into normalized locales. CAP Java only accepts language codes following the standard of RFC 1766 (or [IETF's BCP 47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt)). From d9450d6ddc837169a16ee03a3853e8b796e71796 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 10:19:09 +0200 Subject: [PATCH 083/140] chore(deps): update dependency cspell to v9.0.2 (#1863) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [cspell](https://cspell.org/) ([source](https://redirect.github.com/streetsidesoftware/cspell/tree/HEAD/packages/cspell)) | [`9.0.1` -> `9.0.2`](https://renovatebot.com/diffs/npm/cspell/9.0.1/9.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/cspell/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/cspell/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/cspell/9.0.1/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/cspell/9.0.1/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
streetsidesoftware/cspell (cspell) ### [`v9.0.2`](https://redirect.github.com/streetsidesoftware/cspell/blob/HEAD/packages/cspell/CHANGELOG.md#902-2025-05-20) [Compare Source](https://redirect.github.com/streetsidesoftware/cspell/compare/v9.0.1...v9.0.2) **Note:** Version bump only for package cspell
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Steffen Waldmann --- package-lock.json | 258 ++++++++++++++++++++++++---------------------- 1 file changed, 134 insertions(+), 124 deletions(-) diff --git a/package-lock.json b/package-lock.json index fb9ae71fae..96ecea0f6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -298,9 +298,9 @@ } }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.0.1.tgz", - "integrity": "sha512-h7gTqg0VF4N8VhOPk66XewuSsT56OP2ujgxtAyYQ4H+NuYd3HMfS0h/I3/y9uBhllwOEamaeAzYhc5JF/qIrsQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.0.2.tgz", + "integrity": "sha512-gGFSfVIvYtO95O3Yhcd1o0sOZHjVaCPwYq3MnaNsBBzaMviIZli4FZW9Z+XNKsgo1zRzbl2SdOXJPP0VcyAY0A==", "dev": true, "license": "MIT", "dependencies": { @@ -328,7 +328,7 @@ "@cspell/dict-fsharp": "^1.1.0", "@cspell/dict-fullstack": "^3.2.6", "@cspell/dict-gaming-terms": "^1.1.1", - "@cspell/dict-git": "^3.0.4", + "@cspell/dict-git": "^3.0.5", "@cspell/dict-golang": "^6.0.21", "@cspell/dict-google": "^1.0.8", "@cspell/dict-haskell": "^4.0.5", @@ -355,7 +355,7 @@ "@cspell/dict-rust": "^4.0.11", "@cspell/dict-scala": "^5.0.7", "@cspell/dict-shell": "^1.1.0", - "@cspell/dict-software-terms": "^5.0.8", + "@cspell/dict-software-terms": "^5.0.9", "@cspell/dict-sql": "^2.2.0", "@cspell/dict-svelte": "^1.0.6", "@cspell/dict-swift": "^2.0.5", @@ -368,22 +368,22 @@ } }, "node_modules/@cspell/cspell-json-reporter": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.0.1.tgz", - "integrity": "sha512-Rpn7Tuq9t8bZpXZFV43NkhCl0LaPDJZSON4/JFxGbOcH16ryXfrx7oObUTIIyxSxO3fGkzaJZHIwGibRJSsbNQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.0.2.tgz", + "integrity": "sha512-Hy9hKG53cFhLwiSZuRVAd5YfBb5pPj3V2Val69TW1j4+sy3podewqm4sb3RqoB01LcDkLI/mOeMwHz1xyIjfoA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "9.0.1" + "@cspell/cspell-types": "9.0.2" }, "engines": { "node": ">=20" } }, "node_modules/@cspell/cspell-pipe": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.0.1.tgz", - "integrity": "sha512-bhFcvF2a8KYKVh/OebCfJ8LFw5GYHyUsUjAbxnznTBrYOFSIclDjwUwT29yVDXwnQkJkB6Px5Y9e2VvtFizVFg==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.0.2.tgz", + "integrity": "sha512-M1e+u3dyGCJicSZ16xmoVut4pI8ynfqILYiDAYC9+rbn04wJdnWD46ElIZnRriFXx7fu/UsUEexu3lFaqKVGEg==", "dev": true, "license": "MIT", "engines": { @@ -391,9 +391,9 @@ } }, "node_modules/@cspell/cspell-resolver": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.0.1.tgz", - "integrity": "sha512-AhIXAhX1qt7Y3EyiP/5rAk7Ow7DJpAyB44wPbfdF9p1vhnk6oQ7RslnD3G6S9o/vNxZ0DWFPREMWx19J/3c+hw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.0.2.tgz", + "integrity": "sha512-JkMQb+hcEyZ2ALvEeJvfxoIblRpZlnek50Ew5sLSSZciRuhNvQZS5+Apwt1GXHitTo8/bqXFxABNP36O++YAwA==", "dev": true, "license": "MIT", "dependencies": { @@ -404,9 +404,9 @@ } }, "node_modules/@cspell/cspell-service-bus": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.0.1.tgz", - "integrity": "sha512-DoW6hLkFIO3BXePtUYQEax3FTH9fkwCUbf6qphAEXnr4PjoyPZsgBhR6iCrZd4DyhuFiRvK3Cgpq2o3O0NdODQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.0.2.tgz", + "integrity": "sha512-OjfZ3vnBjmkctC9xs/87/9bx/3kZYUPJkWsZxzfH4rla/HeIUrm9UZlDqCibhWifhPHrDdV9hDW5QEGXkYR2hw==", "dev": true, "license": "MIT", "engines": { @@ -414,9 +414,9 @@ } }, "node_modules/@cspell/cspell-types": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.0.1.tgz", - "integrity": "sha512-8FRmvyV1AYEepJB3J7jji1ZYG9yOK0eYr4WuUVPfUJa6N3HyeZjWKhxbVvqedmEI74f5Ls3cQKHY1T2Yvqk/ag==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.0.2.tgz", + "integrity": "sha512-RioULo34qbUXuCCLi/DCDxdb++Nm1ospNXzVkKZrSvTG4AjkC95ZhfIOp9jbGSWqL2PGdaHVXgG77EyQbAk5xA==", "dev": true, "license": "MIT", "engines": { @@ -532,9 +532,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.8.tgz", - "integrity": "sha512-OkNUVuU9Q+Sf827/61YPkk6ya6dSsllzeYniBFqNW9TkoqQXT3vggkgmtCE1aEhSvVctMwxpPYoC8pZgn1TeSA==", + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.9.tgz", + "integrity": "sha512-5gjqpUwhE+qP9A9wxD1+MGGJ3DNqTgSpiOsS10cGJfV4p/Z194XkDUZrUrJsnJA/3fsCZHAzcNWh8m0bw1v++A==", "dev": true, "license": "MIT" }, @@ -546,9 +546,9 @@ "license": "CC BY-SA 4.0" }, "node_modules/@cspell/dict-en-gb-mit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.0.6.tgz", - "integrity": "sha512-QYDwuXi9Yh+AvU1omhz8sWX+A1SxWI3zeK1HdGfTrICZavhp8xxcQGTa5zxTTFRCcQc483YzUH2Dl+6Zd50tJg==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.0.7.tgz", + "integrity": "sha512-fdZbu4jbkzjjTO0jPBGINwQwzNFGapMnhH9D4mDa4UzGGyQFVRx6n/FFwxnfs7CXbuCV6UFSwjHZEAB8pfWn0A==", "dev": true, "license": "MIT" }, @@ -595,9 +595,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-git": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.4.tgz", - "integrity": "sha512-C44M+m56rYn6QCsLbiKiedyPTMZxlDdEYAsPwwlL5bhMDDzXZ3Ic8OCQIhMbiunhCOJJT+er4URmOmM+sllnjg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.5.tgz", + "integrity": "sha512-I7l86J2nOcpBY0OcwXLTGMbcXbEE7nxZme9DmYKrNgmt35fcLu+WKaiXW7P29V+lIXjJo/wKrEDY+wUEwVuABQ==", "dev": true, "license": "MIT" }, @@ -720,9 +720,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.3.tgz", - "integrity": "sha512-EdGkCpAq66Mhi9Qldgsr+NvPVL4TdtmdlqDe4VBp0P3n6J0B7b0jT1MlVDIiLR+F1eqBfL0qjfHf0ey1CafeNw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.4.tgz", + "integrity": "sha512-/hK5ii9OzSOQkmTjkzJlEYWz+PBnz2hRq5Xu7d4aDURaynO9xMAcK31JJlKNQulBkVbQHxFZLUrzjdzdAr/Opw==", "dev": true, "license": "MIT" }, @@ -793,9 +793,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-software-terms": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.0.8.tgz", - "integrity": "sha512-VsJesitvaHZpMgNwHHms3yDsZz7LNToC2HuSAnyt1znn37ribiJF1ty0jWhVQO6fv7K4PM1KsKTJIwqBwc446g==", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.0.10.tgz", + "integrity": "sha512-2nTcVKTYJKU5GzeviXGPtRRC9d23MtfpD4PM4pLSzl29/5nx5MxOUHkzPuJdyaw9mXIz8Rm9IlGeVAvQoTI8aw==", "dev": true, "license": "MIT" }, @@ -842,13 +842,13 @@ "license": "MIT" }, "node_modules/@cspell/dynamic-import": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.0.1.tgz", - "integrity": "sha512-BoWzHwkufo90ubMZUN8Jy4HQYYWFW7psVCdG/4RUgfvVnazkPfLxWBbsPQsLrlIP0utaqei7D9FU0K7r7mpl4A==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.0.2.tgz", + "integrity": "sha512-KhcoNUj6Ij2P8fbRC7QOn3jzbTZFxoQpFGanGU9f+4DfZBH86PCADyKYH+ZpJPlYgrI+Jh4wKzF5y5YKKNrdrw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.0.1", + "@cspell/url": "9.0.2", "import-meta-resolve": "^4.1.0" }, "engines": { @@ -856,9 +856,9 @@ } }, "node_modules/@cspell/filetypes": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.0.1.tgz", - "integrity": "sha512-swZu3ra2AueyjEz/bPsvwFuHGYhjWZBx1K9FSvZA/yDIX5RVr6orQSuf9zvXNFui6Nyk0tudLnn3y9jT0LHk8A==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.0.2.tgz", + "integrity": "sha512-8KEIgptldoZT3pM+yhYV8nXq5T9Sz0YvZIqwDGEqKJ6j447K+I91QWS7RQDrvHkElMi/2g/h08Efg0RIT+QEaQ==", "dev": true, "license": "MIT", "engines": { @@ -866,9 +866,9 @@ } }, "node_modules/@cspell/strong-weak-map": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.0.1.tgz", - "integrity": "sha512-u87PWr1xACqs/F3HibZ4Eb0Za/ghWIa6WLvEKV9OaiLfEUQuczbrXPVgHmGr83H0XXWUKy8FvVbWGFmXwiw+gQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.0.2.tgz", + "integrity": "sha512-SHTPUcu2e6aYxI5sr1L/9pzz68CArV6WzMvAio//5LbtKI6NtDp/7tARBwLi1G3A3C0289zDHbDKm3wc1lRNhQ==", "dev": true, "license": "MIT", "engines": { @@ -876,9 +876,9 @@ } }, "node_modules/@cspell/url": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.0.1.tgz", - "integrity": "sha512-8xaLrsQ742dmwXwS6tjreps3NpSQe6WEZFPQQT2DprVJXGZnfQR8ob0c+kPhD0hu9A6PwShJsRsfh3DQGKCqAw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.0.2.tgz", + "integrity": "sha512-KwCDL0ejgwVSZB8KTp8FhDe42UOaebTVIMi3O5GcYHi9Cut8B5QU4tbQOFGXP6E4pjimeO9yIkr9Z34kTljj/g==", "dev": true, "license": "MIT", "engines": { @@ -3727,28 +3727,28 @@ } }, "node_modules/cspell": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.0.1.tgz", - "integrity": "sha512-AJqsX+3eSTz9GmIuyEZUzCCTbvCPw6+Nv7UYa4PCn7vNV3XEb5LHTp5i9y2i65fNaeNEcQXLrLYoY/JcBFmUSQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.0.2.tgz", + "integrity": "sha512-VwPNTTivvv/NyovXUMcTYc7BaOgun7k8FhRWaVKxZPEsl/9r9WTLmQ1dNbHRq56LajH2b7wKGQYuRsfov3UWTg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-json-reporter": "9.0.1", - "@cspell/cspell-pipe": "9.0.1", - "@cspell/cspell-types": "9.0.1", - "@cspell/dynamic-import": "9.0.1", - "@cspell/url": "9.0.1", + "@cspell/cspell-json-reporter": "9.0.2", + "@cspell/cspell-pipe": "9.0.2", + "@cspell/cspell-types": "9.0.2", + "@cspell/dynamic-import": "9.0.2", + "@cspell/url": "9.0.2", "chalk": "^5.4.1", "chalk-template": "^1.1.0", - "commander": "^13.1.0", - "cspell-dictionary": "9.0.1", - "cspell-gitignore": "9.0.1", - "cspell-glob": "9.0.1", - "cspell-io": "9.0.1", - "cspell-lib": "9.0.1", + "commander": "^14.0.0", + "cspell-dictionary": "9.0.2", + "cspell-gitignore": "9.0.2", + "cspell-glob": "9.0.2", + "cspell-io": "9.0.2", + "cspell-lib": "9.0.2", "fast-json-stable-stringify": "^2.1.0", "file-entry-cache": "^9.1.0", - "semver": "^7.7.1", + "semver": "^7.7.2", "tinyglobby": "^0.2.13" }, "bin": { @@ -3763,30 +3763,30 @@ } }, "node_modules/cspell-config-lib": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.0.1.tgz", - "integrity": "sha512-hbeyU6cY4NPKh69L4QpBZgGz00f7rLk10xPlCo6MxEmCqSOTuXXvDEUR51d2ED69G+GyFAeZi5VU9IdJ4jhvzQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.0.2.tgz", + "integrity": "sha512-8rCmGUEzlytnNeAazvbBdLeUoN18Cct8k6KLePiUS0GglYomSAvcPWsamSk9jeh947m0cu2dhjZPnKQlp11XBA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "9.0.1", + "@cspell/cspell-types": "9.0.2", "comment-json": "^4.2.5", - "yaml": "^2.7.1" + "yaml": "^2.8.0" }, "engines": { "node": ">=20" } }, "node_modules/cspell-dictionary": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.0.1.tgz", - "integrity": "sha512-I9gjRpfV4djxN0i2p9OzWIrkjtUaGUyVE9atvRbkHUMeqDUhC2Qt0Mb9tnF8I7qnHeZt+U44vUa9Dg7yrJ+k4Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.0.2.tgz", + "integrity": "sha512-u1jLnqu+2IJiGKdUP9LF1/vseOrCh6hUACHZQ8JsCbHC2KU/DL68s4IgS5jDyK5lBcwPOWzQOiTuXQSEardpFQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "9.0.1", - "@cspell/cspell-types": "9.0.1", - "cspell-trie-lib": "9.0.1", + "@cspell/cspell-pipe": "9.0.2", + "@cspell/cspell-types": "9.0.2", + "cspell-trie-lib": "9.0.2", "fast-equals": "^5.2.2" }, "engines": { @@ -3794,15 +3794,15 @@ } }, "node_modules/cspell-gitignore": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.0.1.tgz", - "integrity": "sha512-xjgOmeGbHEaeF0erRQ2QXwqxWqGDiI4mu+NjCL7ZHPoAM5y8PEO6IbxVNabIB1xC4QAborbtEQ/8ydDWLJcPoQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.0.2.tgz", + "integrity": "sha512-2CXpUYa+mf1I0oMH/V0qzT0zP95IqYzaS9BfEB7AcSmjrvuIgmiGLztUNrG5mMMBAlHk7sfI8gAEMMvr/Q7sTQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.0.1", - "cspell-glob": "9.0.1", - "cspell-io": "9.0.1" + "@cspell/url": "9.0.2", + "cspell-glob": "9.0.2", + "cspell-io": "9.0.2" }, "bin": { "cspell-gitignore": "bin.mjs" @@ -3812,13 +3812,13 @@ } }, "node_modules/cspell-glob": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.0.1.tgz", - "integrity": "sha512-dQU/ln6J9Qe31zk1cLJnq/WNAjRrTUig1GG8WA2oK1jHZKY9VbyJLb5DUFnDUx35cI0jdOEnGSCWi8qNjHSc1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.0.2.tgz", + "integrity": "sha512-trTskAU7tw9RpCb+/uPM4zWByZEavHh3SIrjz7Du/ritjZi85O80HItNw5O3ext4zSPfNNLL3kBT7fLLphFHrw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.0.1", + "@cspell/url": "9.0.2", "picomatch": "^4.0.2" }, "engines": { @@ -3839,14 +3839,14 @@ } }, "node_modules/cspell-grammar": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.0.1.tgz", - "integrity": "sha512-FZ1z1p3pslfotZT/W/VRZjB4S+z0ETrTbNmQ5pGmhdY0nm7Slmg+8nIJluLEjBneBGTJIOcLjYykwS2vI6jzxw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.0.2.tgz", + "integrity": "sha512-3hrNZJYEgWSaCvH3rpFq43PX9pxdJt60+pFG3CTZAdpcI97DDsrdH3f7a6h8sNAb+pN59JnV2DtWexsAVL6vjA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "9.0.1", - "@cspell/cspell-types": "9.0.1" + "@cspell/cspell-pipe": "9.0.2", + "@cspell/cspell-types": "9.0.2" }, "bin": { "cspell-grammar": "bin.mjs" @@ -3856,42 +3856,42 @@ } }, "node_modules/cspell-io": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.0.1.tgz", - "integrity": "sha512-L5fZY0glVeQb6nmt1WL1wKzZzoHJUkBQ9BGCrwqSXIrjZrYmBNSKixCjo6o9n2keRUwpNjsvZj1TQDKDV+FsXA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.0.2.tgz", + "integrity": "sha512-TO93FTgQjjp62nAn213885RdyOTsQwdjSHdeYaaNiaTBOBgj2jR8M8bi3+h2imGBlinlYERoVbPF9wghJEK2nw==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "9.0.1", - "@cspell/url": "9.0.1" + "@cspell/cspell-service-bus": "9.0.2", + "@cspell/url": "9.0.2" }, "engines": { "node": ">=20" } }, "node_modules/cspell-lib": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.0.1.tgz", - "integrity": "sha512-F4vJG6GmAGVAuhgcepO12UtG7yev7Rcfa31MLIyYNTrd5NeORzM+GTHnL970FlEflwYPYjcSTGwkyowQ+ZbmDg==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.0.2.tgz", + "integrity": "sha512-uoPQ0f+umOGUQB/q0H+K/gWfd7xJMaPlt5rXMMTeKIPHLDRBE7lBx4mHVCmgevL+oTNSLpIE5FdqRDbr+Q+Awg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "9.0.1", - "@cspell/cspell-pipe": "9.0.1", - "@cspell/cspell-resolver": "9.0.1", - "@cspell/cspell-types": "9.0.1", - "@cspell/dynamic-import": "9.0.1", - "@cspell/filetypes": "9.0.1", - "@cspell/strong-weak-map": "9.0.1", - "@cspell/url": "9.0.1", + "@cspell/cspell-bundled-dicts": "9.0.2", + "@cspell/cspell-pipe": "9.0.2", + "@cspell/cspell-resolver": "9.0.2", + "@cspell/cspell-types": "9.0.2", + "@cspell/dynamic-import": "9.0.2", + "@cspell/filetypes": "9.0.2", + "@cspell/strong-weak-map": "9.0.2", + "@cspell/url": "9.0.2", "clear-module": "^4.1.2", "comment-json": "^4.2.5", - "cspell-config-lib": "9.0.1", - "cspell-dictionary": "9.0.1", - "cspell-glob": "9.0.1", - "cspell-grammar": "9.0.1", - "cspell-io": "9.0.1", - "cspell-trie-lib": "9.0.1", + "cspell-config-lib": "9.0.2", + "cspell-dictionary": "9.0.2", + "cspell-glob": "9.0.2", + "cspell-grammar": "9.0.2", + "cspell-io": "9.0.2", + "cspell-trie-lib": "9.0.2", "env-paths": "^3.0.0", "fast-equals": "^5.2.2", "gensequence": "^7.0.0", @@ -3906,20 +3906,30 @@ } }, "node_modules/cspell-trie-lib": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.0.1.tgz", - "integrity": "sha512-gIupiHwLdsQun79biJgiqmXffKUGzFjGLFEeVptI2Zy5Oa3XhRJsHap4PyeleErONkpzxMG1tgpOWzhOqwl65Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.0.2.tgz", + "integrity": "sha512-inXu6YEoJFLYnxgcXy3quCoGgSWYRye1kM4dj8kbYtNAQgUVD93hPFdmPWObwhVawsS3rQybckG3DSnmxBe9Fg==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "9.0.1", - "@cspell/cspell-types": "9.0.1", + "@cspell/cspell-pipe": "9.0.2", + "@cspell/cspell-types": "9.0.2", "gensequence": "^7.0.0" }, "engines": { "node": ">=20" } }, + "node_modules/cspell/node_modules/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -7484,9 +7494,9 @@ } }, "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", "bin": { @@ -8923,16 +8933,16 @@ } }, "node_modules/yaml": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", - "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yocto-queue": { From 37ea3c31eb0998b232760d163e8b42fc8915640d Mon Sep 17 00:00:00 2001 From: Steffen Waldmann Date: Tue, 20 May 2025 10:56:50 +0200 Subject: [PATCH 084/140] Add tip to prevent outdated lock file issues --- guides/deployment/to-cf.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/guides/deployment/to-cf.md b/guides/deployment/to-cf.md index fdb4904587..bb5e1888a5 100644 --- a/guides/deployment/to-cf.md +++ b/guides/deployment/to-cf.md @@ -238,6 +238,9 @@ cf target ``` [Learn more about `cf login`](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/7a37d66c2e7d401db4980db0cd74aa6b.html){.learn-more} +::: tip Prevent outdated lock file issues +If your project already includes a _package-lock.json_, run `npm update` to make sure it’s in sync with your _package.json_ before proceeding. +::: You can now freeze dependencies, build, and deploy the application: From 25d8eff1bd341930bcf4502c349d74786c9cccb6 Mon Sep 17 00:00:00 2001 From: Steffen Weinstock <79531202+stewsk@users.noreply.github.com> Date: Tue, 20 May 2025 12:18:09 +0200 Subject: [PATCH 085/140] (cds 9) Virtual elements in views (#1826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andre Meyering Co-authored-by: RenΓ© Jeglinsky --- cds/cdl.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cds/cdl.md b/cds/cdl.md index c18c0dda1d..36141c2387 100644 --- a/cds/cdl.md +++ b/cds/cdl.md @@ -804,6 +804,21 @@ By using a cast, annotations and other properties are inherited from the provide
+### Virtual elements in views + +Virtual elements can be defined in views or projections like this: +```cds +entity SomeView as select from Employee { + // ..., + virtual virt1 : String(22), + virtual virt2 // virtual element without type +} +``` +These virtual elements have no relation to the query source `Employee` but are new fields +in the view. Virtual elements in views or projections are handled as described in the +section on [virtual elements in entities](#virtual-elements). + +
### Views with Parameters From c655e91e4942a0b9f9a658e6d1bd565174bf2f86 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Tue, 20 May 2025 13:07:10 +0200 Subject: [PATCH 086/140] chore: remove deprecated `cds.ql` `INSERT.as` method (#1794) `cds.ql` `INSERT.as` is being removed with `@sap/cds^9`. Please use `INSERT.from` to insert sub `SELECTS` instead. --- node.js/cds-ql.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/node.js/cds-ql.md b/node.js/cds-ql.md index 29d60d3610..5667cfc3dd 100644 --- a/node.js/cds-ql.md +++ b/node.js/cds-ql.md @@ -835,9 +835,6 @@ Constructs a _INSERT into SELECT_ statement. ```js INSERT.into('Bar') .from (SELECT.from('Foo')) ``` -### as() {.method} - -The use of _.as()_ method is deprecated. Please use [_.from()_](#from) method instead. ## UPSERT {.class} From 44365f482153ddb44bc161f5763ad4fe2461fdac Mon Sep 17 00:00:00 2001 From: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Date: Tue, 20 May 2025 13:08:41 +0200 Subject: [PATCH 087/140] cds9: remove footnote for data aggregation (#1800) new parser is part of new adapter --- advanced/odata.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/advanced/odata.md b/advanced/odata.md index ce0e1f6d95..abadb6d13c 100644 --- a/advanced/odata.md +++ b/advanced/odata.md @@ -1060,14 +1060,13 @@ If the `groupby` transformation only includes a subset of the entity keys, the r | `aggregate` | aggregate values | | | | `compute` | add computed properties to the result set | | | | `expand` | expand navigation properties | | | -| `concat` | append additional aggregation to the result | (1) | | -| `skip` / `top` | paginate | (1) | | -| `orderby` | sort the input set | (1) | | +| `concat` | append additional aggregation to the result | | | +| `skip` / `top` | paginate | | | +| `orderby` | sort the input set | | | | `topcount`/`bottomcount` | retain highest/lowest _n_ values | | | | `toppercent`/`bottompercent` | retain highest/lowest _p_% values | | | | `topsum`/`bottomsum` | retain _n_ values limited by sum | | | -- (1) Supported with experimental feature `cds.features.odata_new_parser = true` #### `concat` From 24ae3e8e7d8775ef6b1496791f624db44c9b08a4 Mon Sep 17 00:00:00 2001 From: mariayord Date: Tue, 20 May 2025 13:19:29 +0200 Subject: [PATCH 088/140] cds9: use cloud sdk 4 (#1807) Co-authored-by: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> --- guides/using-services.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/guides/using-services.md b/guides/using-services.md index 5481826610..847616b79a 100644 --- a/guides/using-services.md +++ b/guides/using-services.md @@ -92,7 +92,7 @@ If you want to learn about this topic based on the [Incident Management](https:/ ## Install Dependencies { .node } ```sh -npm add @sap-cloud-sdk/http-client@3.x @sap-cloud-sdk/connectivity@3.x @sap-cloud-sdk/resilience@3.x +npm add @sap-cloud-sdk/http-client@4.x @sap-cloud-sdk/connectivity@4.x @sap-cloud-sdk/resilience@4.x ``` ## Get and Import an External Service API { #external-service-api } @@ -986,7 +986,7 @@ Since you don't want to use the destination for local testing, but only for prod } ``` -Additionally, you can provide [destination options](https://sap.github.io/cloud-sdk/api/v3/interfaces/sap-cloud-sdk_connectivity.DestinationFetchOptions.html) inside a `destinationOptions` object: +Additionally, you can provide [destination options](https://sap.github.io/cloud-sdk/api/v4/interfaces/sap-cloud-sdk_connectivity.DestinationFetchOptions.html) inside a `destinationOptions` object: ```jsonc "cds": { @@ -1661,7 +1661,7 @@ This list specifies the properties for application defined destinations. | `queries` | Map of URL parameters | | `forwardAuthToken` | [Forward auth token](#forward-auth-token) | -[Destination Type in SAP Cloud SDK for JavaScript](https://sap.github.io/cloud-sdk/api/v3/interfaces/sap_cloud_sdk_connectivity.Destination.html){.learn-more .node} +[Destination Type in SAP Cloud SDK for JavaScript](https://sap.github.io/cloud-sdk/api/v4/interfaces/sap-cloud-sdk_connectivity.Destination.html){.learn-more .node} [HttpDestination Type in SAP Cloud SDK for Java](https://help.sap.com/doc/82a32040212742019ce79dda40f789b9/1.0/en-US/index.html){.learn-more .java} #### Authentication Types From 95d933020b589c1cf568ba2c5bd18b5c83da976c Mon Sep 17 00:00:00 2001 From: Steffen Weinstock <79531202+stewsk@users.noreply.github.com> Date: Tue, 20 May 2025 13:29:59 +0200 Subject: [PATCH 089/140] (cds 9) No native HANA associations (#1827) Co-authored-by: Andre Meyering Co-authored-by: Rene Jeglinsky --- guides/databases-hana.md | 47 ++++++++++------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/guides/databases-hana.md b/guides/databases-hana.md index e81a4a192f..9a26e6e6fa 100644 --- a/guides/databases-hana.md +++ b/guides/databases-hana.md @@ -659,48 +659,23 @@ All limitations for the SAP HANA Cloud database can be found in the [SAP Help Po ### Native Associations -For SAP HANA, CDS associations are by default reflected in the respective database tables and views -by _Native HANA Associations_ (HANA SQL clause `WITH ASSOCIATIONS`). - -CAP no longer needs these native associations (provided you use the new database -service _@cap-js/hana_ for the CAP Node.js stack). - -Unless you explicitly use them in other native HANA objects, we recommend -switching off the generation of native HANA associations, as they increase deploy times: +In previous CAP releases, CDS associations were by default reflected in SAP HANA +database tables and views by _Native HANA Associations_ (HANA SQL clause `WITH ASSOCIATIONS`). +But the presence of such native associations significantly increases (re-)deploy times: They need to be validated in the HDI deployment, and they can introduce indirect dependencies between other objects, which can trigger other unnecessary revalidations -or even unnecessary drop/create of indexes. By switching them off, all this effort is saved. +or even unnecessary drop/create of indexes. -::: code-group +As CAP doesn't need these native associations, by default no native HANA associations +are created anymore starting with CAP 9. -```json [package.json] -{ - "cds": { - "sql": { - "native_hana_associations": false - } - } -} -``` - -```json [cdsrc.json] -{ - "sql": { - "native_hana_associations": false - } -} -``` - -::: - - -For new projects, `cds add hana` automatically adds this configuration. +In the unlikely case that you need native HANA associations because you explicitly use them +in other native HANA objects or in custom code, you can switch them back on with cds.sql.native_hana_associations = true. ::: warning Initial full table migration -Be aware, that the first deployment after this **configuration change may take longer**. +Be aware that the first deployment after this **configuration change may take longer**. -For each entity with associations, the respective database object will be touched +For each entity with associations, the respective database object is touched (DROP/CREATE for views, full table migration via shadow table and data copy for tables). -This is also the reason why we haven't changed the default so far. -Subsequent deployments will benefit, however. + ::: From c22a702db568ae2c6ad70c61b82db9ed5421a30c Mon Sep 17 00:00:00 2001 From: Steffen Weinstock <79531202+stewsk@users.noreply.github.com> Date: Tue, 20 May 2025 13:43:22 +0200 Subject: [PATCH 090/140] (cds 9) Journal annotation is copied to generated child entities (#1828) Co-authored-by: Andre Meyering Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- guides/databases-hana.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/guides/databases-hana.md b/guides/databases-hana.md index 9a26e6e6fa..e20266956d 100644 --- a/guides/databases-hana.md +++ b/guides/databases-hana.md @@ -508,6 +508,12 @@ Examples: We recommend keeping _.hdbtable_ deployment for entities where you expect low data volume. Every _.hdbmigrationtable_ artifact becomes part of your versioned source code, creating a new migration version on every model change/build cycle. In turn, each such migration can require manual resolution. You can switch large-volume tables to _.hdbmigrationtable_ at any time, keeping in mind that the existing _.hdbtable_ design-time artifact needs to be undeployed. + +When choosing to use _.hdbmigrationtable_ for an entity with +[localized elements](../guides/localized-data#localized-data) or [compositions of aspects](../cds/cdl#managed-compositions), +the generated `.texts` and composition child entities are automatically handled via _.hdbmigrationtable_, too. +If this is not desired, annotate these generated entities with `@cds.persistence.journal: false`. + ::: tip Sticking to _.hdbtable_ for the actual application development phase avoids lots of initial migration versions that would need to be applied to the database schema. ::: From 92de77db43c19132a3ca8161af4a3bac79640a13 Mon Sep 17 00:00:00 2001 From: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Date: Tue, 20 May 2025 13:48:50 +0200 Subject: [PATCH 091/140] fix anchor link for aem (#1864) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @renejeglinsky if the anchor is moved to a new line, it does not apply. --------- Co-authored-by: RenΓ© Jeglinsky --- plugins/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/index.md b/plugins/index.md index 5c8518b154..27d75f12a2 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -393,8 +393,8 @@ Available for: [![Node.js logo](../assets/logos/nodejs.svg){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/event-broker#readme) [![Java logo](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/cap-java/cds-feature-event-hub#readme) -## SAP Integration Suite, advanced event mesh {#advanced-event-mesh} +## SAP Integration Suite, advanced event mesh [SAP Integration Suite, advanced event mesh](https://www.sap.com/germany/products/technology-platform/integration-suite/advanced-event-mesh.html) allows you to, amongst others, integrate non-SAP systems into your event-driven architecture. From aa64c91444651b6503336b37d7997260da3b3a84 Mon Sep 17 00:00:00 2001 From: BraunMatthias <59841349+BraunMatthias@users.noreply.github.com> Date: Tue, 20 May 2025 14:00:50 +0200 Subject: [PATCH 092/140] Java minimum dependency versions major (#1842) Co-authored-by: matthia.braun@sap.com --- java/migration.md | 20 ++++++++++++++------ java/versions.md | 29 +++++++++++------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/java/migration.md b/java/migration.md index 66772f9491..51a9d4dcfd 100644 --- a/java/migration.md +++ b/java/migration.md @@ -309,12 +309,20 @@ Since version 1.27 CAP Java is running with Spring Boot 2.7, which uses Spring S Make sure that all libraries used in your project are either compatible with Spring Boot 3 / Jakarta EE 10 or alternatively offer a new version which you can adopt. -CAP Java 2.0 itself requires updated [dependency versions](./versions#dependencies-version-2) of: -- `@sap/cds-dk` -- `@sap/cds-compiler` -- XSUAA library -- SAP Cloud SDK -- Java Logging (replace `cf-java-logging-support-servlet` with `cf-java-logging-support-servlet-jakarta`) +CAP Java 2.0 itself requires updated minimum dependency versions: + +| Dependency | Minimum Version | Recommended Version | +| --- | --- | --- | +| JDK | 17 | 21 | +| Maven | 3.5.0 | 3.9.8 | +| @sap/cds-dk | 6 | 7 | +| @sap/cds-compiler | 3 | 4 | +| Spring Boot | 3.0 | latest | +| XSUAA | 3.0 | latest | +| SAP Cloud SDK | 4.24 | latest | +| Java Logging | 3.7 | latest | + +Java Logging (replace `cf-java-logging-support-servlet` with `cf-java-logging-support-servlet-jakarta`) ::: warning The Cloud SDK BOM `sdk-bom` manages XSUAA until version 2.x, which isn't compatible with CAP Java 2.x. diff --git a/java/versions.md b/java/versions.md index f3dc700e0a..e3186ef962 100644 --- a/java/versions.md +++ b/java/versions.md @@ -61,40 +61,33 @@ CAP Java uses various dependencies that are also used by the applications themse If the applications decide to manage the versions of these dependencies, it's helpful to know the minimum versions of these dependencies that CAP Java requires. The following table lists these minimum versions for various common dependencies, based on the latest release: - -#### Active Version 3.x { #dependencies-version-3 } +#### Active Version 4.x { #dependencies-version-4 } | Dependency | Minimum Version | Recommended Version | | --- | --- | --- | | JDK | 17 | 21 | -| Maven | 3.6.3 | 3.9.8 | -| @sap/cds-dk | 7 | latest | -| @sap/cds-compiler | 4 | latest | +| Maven | 3.6.3 | 3.9.9 | +| @sap/cds-dk | 8 | latest | +| @sap/cds-compiler | 5 | latest | | Spring Boot | 3.0 | latest | -| XSUAA | 3.0 | latest | +| XSUAA | 3.1 | latest | | SAP Cloud SDK | 5.9 | latest | | Java Logging | 3.7 | latest | +| Node.js | 20 | 22 | -#### Maintenance Version 2.10.x { #dependencies-version-2 } +#### Maintenance Version 3.10.x { #dependencies-version-3 } | Dependency | Minimum Version | Recommended Version | | --- | --- | --- | | JDK | 17 | 21 | -| Maven | 3.5.0 | 3.9.8 | -| @sap/cds-dk | 6 | 7 | -| @sap/cds-compiler | 3 | 4 | +| Maven | 3.6.3 | 3.9.8 | +| @sap/cds-dk | 7 | latest | +| @sap/cds-compiler | 4 | latest | | Spring Boot | 3.0 | latest | | XSUAA | 3.0 | latest | -| SAP Cloud SDK | 4.24 | latest | +| SAP Cloud SDK | 5.9 | latest | | Java Logging | 3.7 | latest | -::: warning -The Cloud SDK BOM `sdk-bom` manages XSUAA until version 2.x, which isn't compatible with CAP Java 2.x. -You have two options: -* Replace `sdk-bom` with `sdk-modules-bom`, which [manages all Cloud SDK dependencies but not the transitive dependencies.](https://sap.github.io/cloud-sdk/docs/java/guides/manage-dependencies#the-sap-cloud-sdk-bill-of-material) -* Or, add [dependency management for XSUAA](https://github.com/SAP/cloud-security-services-integration-library#installation) before Cloud SDK's `sdk-bom`. -::: - ### Consistent Versions From 72302c400472646e3cfff9c53670a68d9aedcef8 Mon Sep 17 00:00:00 2001 From: Marc Becker Date: Tue, 20 May 2025 14:04:58 +0200 Subject: [PATCH 093/140] Remove deprecated APIs from CAP Java Messaging docs (#1843) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should no longer mention deprecated APIs in our CAP Java messaging docs, that are already deprecated since CAP Java 3.0 (almost a year ago!). Those APIs will also be finally removed with the next major release. This documentation change is however already valid, before the upcoming major release. --------- Co-authored-by: RenΓ© Jeglinsky --- java/messaging.md | 143 +++++++++++----------------------------------- java/migration.md | 2 +- 2 files changed, 33 insertions(+), 112 deletions(-) diff --git a/java/messaging.md b/java/messaging.md index 0893f3954b..1f0d73170a 100644 --- a/java/messaging.md +++ b/java/messaging.md @@ -68,11 +68,11 @@ With the availability of a messaging service, you can now use it to send message MessagingService messagingService; // Sending via the technical API of the messaging service -messagingService.emit("My/Destination/Messaging/Topic", "raw message payload"); +messagingService.emit("My/Topic", Map.of("message", "hello world")); // Sending by emitting a context via CAP service API -TopicMessageEventContext context = TopicMessageEventContext.create("My/Destination/Messaging/Topic"); -context.setData("raw message payload"); +TopicMessageEventContext context = TopicMessageEventContext.create("My/Topic"); +context.setDataMap(Map.of("message", "hello world")); messagingService.emit(context); ``` @@ -99,11 +99,11 @@ To receive messages matching a desired topic from a message broker, you just nee Example: ```java -@On(service = "messaging-name", event = "My/Destination/Messaging/Topic") +@On(service = "messaging-name", event = "My/Topic") public void receiveMyTopic(TopicMessageEventContext context) { // get ID and payload of message String msgId = context.getMessageId(); - String payload = context.getData(); + Map payload = context.getDataMap(); // ... } ``` @@ -483,11 +483,11 @@ cds: routes: - service: "em-instance-01" events: - - "My/Destination/Messaging/A" + - "My/Topic/A" - service: "em-instance-02" events: - - "My/Destination/Messaging/B" - - "My/Destination/Messaging/C*" + - "My/Topic/B" + - "My/Topic/C*" ``` ::: @@ -498,11 +498,11 @@ To use such a configuration, you need to use the composite messaging service for @Qualifier(MessagingService.COMPOSITE_NAME) MessagingService messagingService; -messagingService.emit("My/Destination/Messaging/A", "raw message payload to em-instance-01"); -messagingService.emit("My/Destination/Messaging/B", "raw message payload to em-instance-02"); +messagingService.emit("My/Topic/A", Map.of("hello", "instance 01")); +messagingService.emit("My/Topic/B", Map.of("hello", "instance 02")); ``` -As you can see in the configuration, the usage and routing of two messaging services is defined (`em-instance-01`, and `em-instance-02`), each with different topics that should be routed via the service (for example, topic `My/Destination/Messaging/A` will be sent/received via `em-instance-01`, and topic `My/Destination/Messaging/B` will be sent/received via `em-instance-02`). The composite service uses the routing configuration in order to dispatch messages as well as subscriptions to the appropriate messaging service. As shown in the sample code, you can simply use the composite message service and submit messages to topics as desired. The messages will be routed to according messaging services as defined in the configuration automatically. To change the routing of messages you can simply change the configuration, without the need of changing your code. +As you can see in the configuration, the usage and routing of two messaging services is defined (`em-instance-01`, and `em-instance-02`), each with different topics that should be routed via the service (for example, topic `My/Topic/A` will be sent/received via `em-instance-01`, and topic `My/Topic/B` will be sent/received via `em-instance-02`). The composite service uses the routing configuration in order to dispatch messages as well as subscriptions to the appropriate messaging service. As shown in the sample code, you can simply use the composite message service and submit messages to topics as desired. The messages will be routed to according messaging services as defined in the configuration automatically. To change the routing of messages you can simply change the configuration, without the need of changing your code. ::: tip If you emit messages with a topic to the composite messaging service that isn't defined in its routing configuration, then the delivery will fail. Consider careful review of your configuration, when you start sending/receiving messages from/to new topics. @@ -511,12 +511,12 @@ If you emit messages with a topic to the composite messaging service that isn't Example for receiving messages with a given topic via the composite messaging service: ```java -@On(service = MessagingService.COMPOSITE_NAME, event = "My/Destination/Messaging/A") +@On(service = MessagingService.COMPOSITE_NAME, event = "My/Topic/A") public void receiveA(TopicMessageEventContext context) { ... } -@On(service = MessagingService.COMPOSITE_NAME, event = "My/Destination/Messaging/B") +@On(service = MessagingService.COMPOSITE_NAME, event = "My/Topic/B") public void receiveB(TopicMessageEventContext context) { ... } @@ -616,7 +616,7 @@ cds: @On(service = "messaging-name", event = "my-custom-queue") public void receiveMyCustomQueueMessage(TopicMessageEventContext context) { // access the message as usual - String payload = context.getData(); + Map payload = context.getDataMap(); } ``` @@ -638,7 +638,7 @@ cds: @On(service = "messaging-name") public void receiveMyCustomQueueAllMessages(TopicMessageEventContext context) { // access the message as usual - String payload = context.getData(); + Map payload = context.getDataMap(); // ... } ``` @@ -691,8 +691,9 @@ private void handleError(MessagingErrorEventContext ctx) { // how to access the event context of the raised exception: // ctx.getException().getEventContexts().stream().findFirst().ifPresent(e -> { + // TopicMessageEventContext errorContext = e.as(TopicMessageEventContext.class); // String event = e.getEvent()); - // String payload = e.get("data")); + // Map payload = errorContext.getDataMap(); // }); ctx.setResult(true); // acknowledge @@ -700,7 +701,7 @@ private void handleError(MessagingErrorEventContext ctx) { } ``` -In a multi-tenant setup with several microservices, messages of a tenant not yet subscribed to the own microservice would be already received from the message queue. In this case, the message cannot be processed for the tenant because the tenant context is not yet available. By default, the standard error handler still acknowledges the message to prevent it from getting stuck in the message sequence. To change this behavior, the custom error handler from the example above can be extended by checking the exception type of the unknown tenant. +In a multi-tenant setup with several microservices, messages of a tenant not yet subscribed to the own microservice would be already received from the message queue. In this case, the message cannot be processed for the tenant because the tenant context is not yet available. By default, the standard error handler still acknowledges the message to prevent it from getting stuck in the message sequence. To change this behavior, the custom error handler from the example above can be extended by checking the exception type of the unknown tenant. ```java @@ -712,15 +713,15 @@ private void handleError(MessagingErrorEventContext ctx) { errorCode.equals(CdsErrorStatuses.INVALID_DATA_FORMAT.getCodeString())) { // error handling for infrastructure error ctx.setResult(false); // no acknowledgement - + } else if (errorCode.equals(CdsErrorStatuses.TENANT_NOT_EXISTS.getCodeString())) { // error handling for unknown tenant context - + // tenant of the received message String tenant = ctx.getTenant(); // received message - Map headers = ctx.getMessageHeaders(); + Map headers = ctx.getMessageHeaders(); Map message = ctx.getMessageData(); ctx.setResult(true); // acknowledge @@ -729,8 +730,9 @@ private void handleError(MessagingErrorEventContext ctx) { // how to access the event context of the raised exception: // ctx.getException().getEventContexts().stream().findFirst().ifPresent(e -> { + // TopicMessageEventContext errorContext = e.as(TopicMessageEventContext.class); // String event = e.getEvent()); - // String payload = e.get("data")); + // Map payload = errorContext.getDataMap(); // }); ctx.setResult(true); // acknowledge @@ -768,7 +770,7 @@ If you want to consume the message purely locally, and prevent the message from You can register your handler with a higher priority than the default handler like this: ```java -@On(service = "messaging-name", event = "My/Destination/Messaging/Topic") +@On(service = "messaging-name", event = "My/Topic") @HandlerOrder(HandlerOrder.EARLY) public void receiveMyTopic(TopicMessageEventContext context) { // Check if message is outgoing to message broker, or incoming from message broker @@ -808,99 +810,20 @@ When using SAP Event Mesh, the placeholder `$namespace` can be used to dynamical Besides these kinds of topic manipulations, additional topic manipulations might occur, depending on the used message broker or the chosen format of the event message. -### Enhanced Messages Representation - -The configuration property `structured` determines if messages are represented as a plain String (`false`) or always structured as two separate maps, representing data and headers (`true`). Setting this property enables handling of message headers, like `cloudevents` headers, separately from the message itself. This works for all messaging brokers supported by CAP. If using a message broker that supports native headers, for example Kafka, the headers are separated from the business data. On incoming messages the flag determines the internal representation of the message either as a plain string or two maps of message data and message headers. Having header data separated, avoids adding extra information or metadata as part of the business data when sending them to the message broker. Additionally the header data is clearly separated on the consumer side, because they provided by different data and headers maps. - -The default value for the configuration property `structured` is `true`. - -Configuration example: -::: code-group -```yaml [srv/src/main/resources/application.yaml] -cds: - messaging.services: - - name: "messaging-name" - kind: "enterprise-messaging" - structured: true -``` -::: -#### Emitting Events - -The interface `MessagingService` provides a new method for emitting events with a data map and a headers map: - -```java -void emit(String topic, Map data, Map headers); -``` - -This method takes a (`cloudevents`) message, separated into data and headers and sends it to the specified topic of this message broker. It produces the same final message, regardless of the structured flag. Usually data and headers are combined into a final JSON string message following the rule: `{...headers, data: data}`. Brokers that natively support headers, for example Kafka, are able to separate headers from data, when using this method. - -```java -String topic; -MessagingService messagingService; - -messagingService.emit(topic, Map.of("firstname", "John", "lastname", "Doe"), Map.of("timestamp", Instant.now())); -``` - -The semantics of the method `MessagingService.emit(String topic, String message)` has been changed depending on the structured flag: If the service is not configured with the structured flag (default), the message is sent to the specified topic of this message broker as is. If the service is configured with the structured flag, the message string is converted into a map following the rule: `{message: message}`. The map is then interpreted as data map and passed to `MessagingService.emit(String topic, Map dataMap)`. Usually this results in a final message like: `{data: {message: message}}`. - -Example: - -```java -String topic; -MessagingService messagingService; - -messagingService.emit(topic, "hello world"); -``` - -If the service is not configured with the structured flag, the message is sent as is and on the consumer side `TopicMessageEventContext.getData()` returns: - -```txt -hello world -``` - -If the service is configured with the structured flag, the message is converted to a map and on the consumer side `TopicMessageEventContext.getData()` returns: - -```json -{"data": {"message": "hello world"}} -``` +### Messages Representation +{#enhanced-messages-representation} -#### Handling events +Messages are provided as two separate `Map` objects, representing data and headers. This enables handling of message headers, like `cloudevents` headers, separately from the message data itself. If using a message broker that supports native headers, for example Kafka, the headers are separated from the business data in the message broker. For message brokers that don't natively support headers, headers and data are merged into a combined structure by following the rule `{...headers, data: data}`. -The structured flag of the consumer determines how the event payload is provided by the event context. - -If set to `false`, the event payload can be accessed using `getData()` as a string; `getDataMap()` and `getHeadersMap()` return `null`: - -```java -@On(event = "myEvent") -public void handleMyEvent(EventContext context) { - TopicMessageEventContext ctx = context.as(TopicMessageEventContext.class); - String data = ctx.getData(); - - // ... -} -``` - -If set to `true`, the event payload can be accessed using `getDataMap()` and `getHeadersMap()`; `getData()` returns null: - -```java -@On(event = "myEvent") -public void handleMyEvent(EventContext context) { - TopicMessageEventContext ctx = context.as(TopicMessageEventContext.class); - Map data = ctx.getDataMap(); - Map headers = ctx.getHeadersMap(); - - // ... -} -``` +Message data is always structured and when sent to message brokers serialized to JSON. In case a message data is received, that is not a JSON string and can't be parsed as a `Map`, the plain message data is wrapped into a `Map` structure with key `message`. ::: tip -Handling of CDS-defined events is independent of value of the `structured` property. +[Events declared in the CDS model](#cds-declared-events) always result in a structured message data. ::: - ### CloudEvents -CAP is able to produce event messages compatible with the [CloudEvents](https://cloudevents.io/) standard in JSON format. To enable this feature, set the configuration parameter `format` of the messaging service to `cloudevents`, for example, like: +CAP is able to produce event messages compatible with the [CloudEvents](https://cloudevents.io/) standard. To enable this feature, set the configuration parameter `format` of the messaging service to `cloudevents`, for example, like: Excerpt from _application.yaml_: ::: code-group @@ -913,11 +836,11 @@ cds: format: "cloudevents" ``` ::: -With this setting, basic header fields (like `type`, `source`, `id`, `datacontenttype`, `specversion`, `time`) of the JSON-based message format will be populated with sensible data (if they have not been set manually before). The event name will be used as-is (without prefixing or any other modifications) as `type` and set in the according CloudEvents header field. +With this setting, basic header fields (like `type`, `source`, `id`, `datacontenttype`, `specversion`, `time`) will be populated with sensible data (if they have not been set manually before). The event name will be used as-is (without prefixing or any other modifications) as `type` and set in the according CloudEvents header field. When using CloudEvents format with SAP Event Mesh, the following default prefixing of topics will be applied (if not manually declared differently): Default for `publishPrefix` is set to `$namespace/ce/` and default for `subscribePrefix` is set to `+/+/+/ce/`. Make sure that these prefixes are allowed topic prefixes in your SAP Event Mesh service configuration (especially its topic rules section). -When using a CAP service that has [events declared in its CDS model](#cds-declared-events), then the event's payload structure will automatically be embedded in the `data` attribute of a valid JSON-based CloudEvents message. +The message data will automatically be embedded in the `data` attribute of the CloudEvents message. ::: tip Headers of the CloudEvents message can be accessed using the EventContext generated for this event by using its generic `get(String)` API. @@ -935,8 +858,6 @@ private void ratingChanged(ReviewedContext context) { } ``` -When using a CAP messaging service directly to emit the raw message payload as a String, please make sure to emit a valid JSON object representation in this String that has the message payload embedded in the `data` attribute (for example `messagingService.emit("sap.cap.reviews.v1.ReviewService.changed.v1", "{"data":{"subject":"4711","rating":3.6}}");`). Then all missing header fields that are required for a valid CloudEvents message will be extended. If you emit a String that is not a valid JSON, then the message cannot be extended and the String will be emitted as-is as the event message content. - [Learn more about **CloudEvents**.](../guides/messaging/#cloudevents){.learn-more} diff --git a/java/migration.md b/java/migration.md index 51a9d4dcfd..055036d203 100644 --- a/java/migration.md +++ b/java/migration.md @@ -174,7 +174,7 @@ Some property defaults have been adjusted: | `cds.sql.hana.optimizationMode` | `legacy` | `hex` | SQL for SAP HANA is optimized for the HEX engine. | | `cds.odataV4.lazyI18n.enabled` | `null` | `true` | Lazy localization is now enabled by default in multitenant scenarios. | | `cds.auditLog.personalData.`
`throwOnMissingDataSubject` | `false` | `true` | Raise errors for incomplete personal data annotations by default. | -| `cds.messaging.services..structured` | `false` | `true` | [Enhanced message representation](./messaging.md#enhanced-messages-representation) is now enabled by default. | +| `cds.messaging.services..structured` | `false` | `true` | [Structured message representation](./messaging.md#messages-representation) is now enabled by default. | ### Adjusted Property Behavior From 79da8bb1726f63580fb87d50d31af821be749c09 Mon Sep 17 00:00:00 2001 From: Tony Quach Date: Tue, 20 May 2025 19:06:39 +0700 Subject: [PATCH 094/140] docs: update cds-data.md (#1788) Fix typo. Change from CdsService.EVENT_UPDATE to CqnService.EVENT_UPDATE. --- java/cds-data.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/cds-data.md b/java/cds-data.md index e24f4fa9e0..efb1c73434 100644 --- a/java/cds-data.md +++ b/java/cds-data.md @@ -1290,7 +1290,7 @@ For the download scenario, as well, you don't need to implement any custom handl If you want to override the default logic to process the uploaded stream with custom logic (for example, to parse a stream of CSV data), the best place to do that is in a custom `On` handler, as the following examples shows: ```java -@On(event = CdsService.EVENT_UPDATE) +@On(event = CqnService.EVENT_UPDATE) public void processCoverImage(CdsUpdateEventContext context, List books) { books.forEach(book -> { InputStream is = book.getCoverImage(); @@ -1355,7 +1355,7 @@ For uploads, you can either use a custom `Before` or `On` handler to wrap the pr Using a custom `Before` handler makes sense if the stream's final destination is the persistence layer of the CAP Java SDK, which writes the content to the database. Note that the pre-processing logic in this example is implemented in the `read()` methods of the `FilterInputStream` and is only called when the data is streamed, during the `On` phase of the request: ```java -@Before(event = CdsService.EVENT_UPDATE) +@Before(event = CqnService.EVENT_UPDATE) public void preProcessCoverImage(CdsUpdateEventContext context, List books) { books.forEach(book -> { book.setCoverImage(new CoverImagePreProcessor(book.getCoverImage())); @@ -1368,7 +1368,7 @@ The original `InputStream` is replaced by the proxy implementation in the `cover Using a custom `On` handler makes sense if you want to prevent that the default `On` handler is executed and to control the final destination for the stream. You then have the option to pass the streamed data on to some other service for persistence: ```java -@On(event = CdsService.EVENT_UPDATE) +@On(event = CqnService.EVENT_UPDATE) public Result processCoverImage(CdsUpdateEventContext context, List books) { books.forEach(book -> { book.setCoverImage(new CoverImagePreProcessor(book.getCoverImage())); From c244888cf452da0e7a96b524b8fc267a2db220a2 Mon Sep 17 00:00:00 2001 From: Tim Schulze-Hartung <108271660+tim-sh@users.noreply.github.com> Date: Tue, 20 May 2025 14:12:07 +0200 Subject: [PATCH 095/140] Fix Kyma/Kubernetes guide (#1845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Steffen Waldmann Co-authored-by: RenΓ© Jeglinsky --- guides/deployment/to-kyma.md | 53 ++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/guides/deployment/to-kyma.md b/guides/deployment/to-kyma.md index 0d1bbc9b89..c1d01c6965 100644 --- a/guides/deployment/to-kyma.md +++ b/guides/deployment/to-kyma.md @@ -85,9 +85,15 @@ The following diagram illustrates the deployment workflow: + Make sure your SAP HANA Cloud is [mapped to your namespace](https://community.sap.com/t5/technology-blogs-by-sap/consuming-sap-hana-cloud-from-the-kyma-environment/ba-p/13552718#toc-hId-569025164) + Ensure SAP HANA Cloud is accessible from your Kyma cluster by [configuring trusted source IPs](https://help.sap.com/docs/HANA_CLOUD/9ae9104a46f74a6583ce5182e7fb20cb/0610e4440c7643b48d869a6376ccaecd.html) +#### Configure Kubernetes + +Download the Kubernetes configuration from SAP BTP and move it to _$HOME/.kube/config_. + +[Learn more in the SAP BTP Kyma documentation](https://help.sap.com/docs/btp/sap-business-technology-platform/access-kyma-instance-using-kubectl){.learn-more} + #### Get Access to a Container Registry -SAP BTP doesn't provide a container registry, but you can choose from offerings of hosted open source and private container image registries, as well as solutions that can be run on premise or in your own cloud infrastructure. +SAP BTP doesn't provide a container image registry (or container repository), but you can choose from offerings of hosted open source and private container image registries, as well as solutions that can be run on premise or in your own cloud infrastructure. ::: tip Ensure network access @@ -102,26 +108,17 @@ To use a docker image from a private repository, you need to [create an image pu ::: details Use this script to create the docker pull secret... ```sh -echo -n "Your repository: "; read YOUR_REPOSITORY +echo -n "Your docker registry server: "; read YOUR_REGISTRY echo -n "Your user: "; read YOUR_USER echo -n "Your email: "; read YOUR_EMAIL -echo -n "Your API key: "; read -s YOUR_API_KEY +echo -n "Your API token: "; read -s YOUR_API_TOKEN kubectl create secret docker-registry \ - "$YOUR_REPOSITORY" \ + docker-registry \ "--docker-server=$YOUR_REGISTRY" \ "--docker-username=$YOUR_USER" \ - "--docker-password=$YOUR_API_KEY" \ + "--docker-password=$YOUR_API_TOKEN" \ "--docker-email=$YOUR_EMAIL" -``` -The `image` property needs to contain the full tag that was used to push the image to the repository: - -```yaml -spec: - imagePullSecrets: - - name: $YOUR_REPOSITORY - containers: - - name: cap-srv - image: $YOUR_REPOSITORY.docker.io/$YOUR_IMAGE:$YOUR_VERSION +# The 2nd 'docker-registry' above is our default secret name. ``` ::: @@ -135,11 +132,24 @@ It is recommended to use a technical user for this secret that has only read per Let's start with a new sample project and prepare it for production using an SAP HANA database and XSUAA for authentication: +
+ +```sh +cds init bookshop --java --add sample && cd bookshop +cds add hana,xsuaa +``` + +
+
+ ```sh cds init bookshop --add sample && cd bookshop cds add hana,xsuaa ``` +
+ + #### User Interfaces If you need a UI, you can also add SAP Build Work Zone support: @@ -169,6 +179,8 @@ They support the deployment of your CAP service, database, UI content, and the c #### Build and Deploy +**First, ensure the Docker daemon** is running, for example by starting Docker Desktop. + You can now quickly deploy the application like so: ```sh @@ -307,7 +319,7 @@ domain: # Container image registry image: - registry: + registry: ``` ::: @@ -321,14 +333,16 @@ srv: # [Service bindings](#configuration-options-for-service-bindings) bindings: - # [Kubernetes container resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) + # Kubernetes container resources + # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ resources: # Map of additional env variables env: MY_ENV_VAR: 1 - # [Kubernetes Liveness, Readiness and Startup Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + # Kubernetes Liveness, Readiness and Startup Probes + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ health: liveness: path: @@ -336,7 +350,7 @@ srv: path: startupTimeout: - # [Container image](#configuration-options-for-container-images) + # Container image image: ``` ::: @@ -435,7 +449,6 @@ kyma.operator.kyma-project.io/default edited [Learn more about adding modules from the Kyma Dashboard.](https://help.sap.com/docs/btp/sap-business-technology-platform/enable-and-disable-kyma-module?version=Cloud#loio1b548e9ad4744b978b8b595288b0cb5c){.learn-more style="margin-top:10px"} -::: #### Configuration Options for Services From 1a781ee1a120cd662cc1436dccc8b59920c6fdfb Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Tue, 20 May 2025 14:42:58 +0200 Subject: [PATCH 096/140] Improvements on fiori page (#1851) Based on feedback in cap/matters#1265 --- advanced/fiori.md | 90 +++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/advanced/fiori.md b/advanced/fiori.md index 2cc613ace0..ce24e29cd5 100644 --- a/advanced/fiori.md +++ b/advanced/fiori.md @@ -25,63 +25,35 @@ This guide explains how to add one or more SAP Fiori elements apps to a CAP proj For entities exposed via OData V4 there is a _Fiori preview_ link on the index page. It dynamically serves an SAP Fiori Elements list page that allows you to quickly see the effect of annotation changes without having to create a UI application first. -
- ::: details Be aware that this is **not meant for production**. +
+ The preview not meant as a replacement for a proper SAP Fiori Elements (UI5) application. It is only active locally where the [development profile](../node.js/cds-env#profiles) is enabled. -To also enable it in cloud deployments, for test or demo purposes maybe, add the following configuration: - -::: code-group - -```json [package.json] -{ - "cds": { - "features": { - "fiori_preview": true - } - } -} -``` -```json [.cdsrc.json] -{ - "features": { - "fiori_preview": true - } -} -``` - -::: +To also enable it in cloud deployments, for test or demo purposes maybe, set cds.fiori.preview:true.
-::: details Be aware that this is **not meant for production**. - The preview not meant as a replacement for a proper SAP Fiori Elements (UI5) application. It is active by default, but disabled automatically in case the [production profile](../java/developing-applications/configuring#production-profile) is enabled. -To also enable it in cloud deployments, for test or demo purposes maybe, add the following configuration: +To also enable it in cloud deployments, for test or demo purposes maybe, set cds.index-page.enabled:true. + +
-::: code-group -```yaml [srv/src/main/resources/application.yaml] -cds: - index-page: - enabled: true -``` ::: -
## Adding Fiori Apps As showcased in [cap/samples](https://github.com/sap-samples/cloud-cap-samples/tree/main/fiori/app), SAP Fiori apps should be added as sub folders to the `app/` of a CAP project. Each sub folder constitutes an individual SAP Fiori application, with [local annotations](#fiori-annotations), _manifest.json_, etc. So, a typical folder layout would look like this: -| Folder/Sub Folder | Description | +| Folder/Sub Folder | Description | |----------------------------|--------------------------------------| | `app/` | All SAP Fiori apps should go in here | |     `browse/` | SAP Fiori app for end users | @@ -97,9 +69,12 @@ Links to Fiori applications created in the `app/` folder are automatically added ### Using SAP Fiori Tools -The SAP Fiori tools provide advanced support for adding SAP Fiori apps to existing CAP projects as well as a wealth of productivity tools, for example for adding SAP Fiori annotations, or graphical modeling and editing. They can be used locally in [Visual Studio Code (VS Code)](https://marketplace.visualstudio.com/items?itemName=SAPSE.sap-ux-fiori-tools-extension-pack) or in [SAP Business Application Studio](https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/b0110400b44748d7b844bb5977a657fa.html). +The SAP Fiori tools provide advanced support for [adding SAP Fiori apps](https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/db44d45051794d778f1dd50def0fa267.html) to existing CAP projects as well as a wealth of productivity tools, for example for adding SAP Fiori annotations, or graphical modeling and editing. They can be used locally in [Visual Studio Code (VS Code)](https://marketplace.visualstudio.com/items?itemName=SAPSE.sap-ux-fiori-tools-extension-pack) or in [SAP Business Application Studio](https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/b0110400b44748d7b844bb5977a657fa.html). + -[Learn more about **how to install SAP Fiori tools**.](https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/2d8b1cb11f6541e5ab16f05461c64201.html){.learn-more} +### Using [`cds add`](../tools/cds-cli#sample) + +Use `cds add sample` to add Fiori sample code to an existing project, or create a new one with `cds init --add sample`. ### From [cap/samples](https://github.com/sap-samples/cloud-cap-samples) @@ -152,14 +127,14 @@ While CDS in principle allows you to add such annotations everywhere in your mod fiori-service.cds #> annotating ../srv/admin-service.cds ./browse fiori-service.cds #> annotating ../srv/cat-service.cds - index.cds + services.cds #> imports ./admin/fiori-service and ./browse/fiori-service ./srv #> all service definitions should stay clean in here: admin-service.cds cat-service.cds ... ``` -[See this also in **cap/samples/fiori**.](https://github.com/sap-samples/cloud-cap-samples/tree/main/fiori/app){.learn-more} +[See this also in **cap/samples/fiori**.](https://github.com/SAP-samples/cloud-cap-samples/blob/6fa2aaee34e862337c5bc5a413817355ab283437/fiori/app/services.cds){.learn-more} **Reasoning:** This recommendation essentially follows the best practices and guiding principles of [Conceptual Modeling](../guides/domain-modeling#domain-driven-design) and [Separation of Concerns](../guides/domain-modeling#separation-of-concerns). @@ -187,7 +162,7 @@ The CDS OData Language Server provides a list of context-sensitive suggestions b #### Using Code Completion -To trigger code completion, choose ⌘ + ⎡ (macOS) or Ctrl + ⎡ (other platforms). The list of suggested values is displayed. +To trigger code completion, choose CtrlSpace. The list of suggested values is displayed. > Note: You can filter the list of suggested values by typing more characters. @@ -322,7 +297,7 @@ You can navigate to the referenced annotation using the [Peek Definition](#peek- #### Peek Definition { #peek-definition} Peek Definition lets you preview and update the referenced annotation without switching away from the code that you're writing. It's triggered when your cursor is inside the referenced annotation value. -- Using a keyboard: choose βŒ₯ + F12 (macOS) or Alt + F12 (other platforms) +- Using a keyboard: choose βŒ₯F12 (macOS) or AltF12 (other platforms) - Using a mouse: right-click and select **Peek Definition** If an annotation is defined in multiple sources, all these sources are listed. You can select which one you want to view or update. Annotation layering isn't considered. @@ -333,7 +308,7 @@ Go To Definition lets you navigate to the source of the referenced annotation an Place your cursor inside the path referencing the annotation term segment or translatable string value, and trigger Go to Definition: -- Using a keyboard: choose F12 in VS Code, or Ctrl + F12 in SAP Business Application Studio +- Using a keyboard: choose F12 in VS Code, or CtrlF12 in SAP Business Application Studio - Using a mouse: right-click and select **Go To Definition** - Using a keyboard and mouse: ⌘ + mouse click (macOS) or Ctrl + mouse click (other platforms) @@ -353,7 +328,7 @@ The annotation language server provides quick information for annotation terms, To view the quick info for an annotation term, record type, or property used in the annotation file, hover your mouse over it. The accompanying documentation is displayed in a hover window, if provided in the respective OData vocabularies. -To view the quick info for each suggestion in the code completion list, either pressing ⌘ + ⎡ (macOS) or Ctrl + ⎡ (other platforms), or click the *info* icon. The accompanying documentation for the suggestion expands to the side. The expanded documentation stays open and updates as you navigate the list. You can close this by pressing ⌘ + ⎡ / Ctrl + ⎡ again or by clicking on the close icon. +To view the quick info for each suggestion in the code completion list, either pressing CtrlSpace, or click the *info* icon. The accompanying documentation for the suggestion expands to the side. The expanded documentation stays open and updates as you navigate the list. #### Internationalization Support @@ -426,14 +401,15 @@ To enable draft for an entity exposed by a service, simply annotate it with `@od annotate AdminService.Books with @odata.draft.enabled; ``` -[See it live in **cap/samples**.](https://github.com/sap-samples/cloud-cap-samples/tree/main/fiori/app/admin-books/fiori-service.cds#L51){.learn-more} +[See it live in **cap/samples**.](https://github.com/SAP-samples/cloud-cap-samples/blob/6fa2aaee34e862337c5bc5a413817355ab283437/fiori/app/admin-books/fiori-service.cds#L94){.learn-more} ::: warning You can't project from draft-enabled entities, as annotations are propagated. Either _enable_ the draft for the projection and not the original entity or _disable_ the draft on the projection using `@odata.draft.enabled: null`. ::: ### Difference between Compositions and Associations -Be aware that you must not modify associated entities through drafts. Only compositions will get a "Create" button in SAP Fiori elements UIs because they are stored as part of the same draft entity. + +Be aware that you cannot modify _associated_ entities through drafts. Only _compositions_ will get a "Create" button in SAP Fiori elements UIs because they are stored as part of the same draft entity. ### Enabling Draft for [Localized Data](../guides/localized-data) {#draft-for-localized-data} @@ -452,13 +428,14 @@ Adding the annotation `@fiori.draft.enabled` won't work if the corresponding `_t ::: ![An SAP Fiori UI showing how a book is edited in the bookshop sample and that the translations tab is used for non-standard languages.](../assets/draft-for-localized-data.png){style="margin:0"} -[See it live in **cap/samples**.](https://github.com/sap-samples/cloud-cap-samples/tree/main/fiori/app/admin-books/fiori-service.cds#L50){.learn-more} -If you're editing data in multiple languages, the _General_ tab in the example above is reserved for the default language (often "en"). Any change to other languages has to be done in the _Translations_ tab, where a corresponding language can be chosen [from a drop-down menu](https://github.com/SAP-samples/cloud-cap-samples/blob/14ac3efaa13fc025f621b4eed369d03f1ca48341/fiori/app/admin-books/fiori-service.cds#L70) as illustrated above. This also applies if you use the URL parameter `sap-language` on the draft page. +[See it live in **cap/samples**.](https://github.com/SAP-samples/cloud-cap-samples/blob/6fa2aaee34e862337c5bc5a413817355ab283437/fiori/app/admin-books/fiori-service.cds#L93){.learn-more} + +If you're editing data in multiple languages, the _General_ tab in the example above is reserved for the default language (often "en"). Any change to other languages has to be done in the _Translations_ tab, where a corresponding language can be chosen [from a drop-down menu](https://github.com/SAP-samples/cloud-cap-samples/blob/6fa2aaee34e862337c5bc5a413817355ab283437/fiori/app/admin-books/fiori-service.cds#L116) as illustrated above. This also applies if you use the URL parameter `sap-language` on the draft page. ### Validating Drafts -You can add [custom handlers](../guides/providing-services#custom-logic) to add specific validations, as usual. In addition, for a draft, you can register handlers to the `PATCH` events to validate input per field, during the edit session, as follows. +You can add [custom handlers](../guides/providing-services#custom-logic) to add specific validations, as usual. In addition, for a draft, you can register handlers to the respective `UPDATE` events to validate input per field, during the edit session, as follows. ##### ... in Java @@ -626,7 +603,7 @@ We're going to look at three things. 1. Dynamically define the buttons status on the UI -First you need to define an action, like in the [_travel-service.cds_ file](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/srv/travel-service.cds#L11). +First you need to define an action, like in the [_travel-service.cds_ file](https://github.com/SAP-samples/cap-sflight/blob/42ee666e40f9dba1176f8263b512c10d23f07907/srv/travel-service.cds#L11). ```cds entity Travel as projection on my.Travel actions { @@ -637,16 +614,15 @@ entity Travel as projection on my.Travel actions { }; ``` -To define what the action actually is doing, you need to write some custom code. See the [_travel-service.js_](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/srv/travel-service.js#L126) file for example: +To define what the action actually is doing, you need to write some custom code. See the [_travel-service.ts_](https://github.com/SAP-samples/cap-sflight/blob/42ee666e40f9dba1176f8263b512c10d23f07907/srv/travel-service.ts#L86) file for example: ```js -this.on('acceptTravel', req => UPDATE(req._target).with({TravelStatus_code:'A'})) +this.on('acceptTravel', req => UPDATE(req.subject).with({TravelStatus_code:'A'})) ``` -> Note: `req._target` is a workaround that has been [introduced in SFlight](https://github.com/SAP-samples/cap-sflight/blob/685867de9e6a91d61276671e4af7354029c70ac8/srv/workarounds.js#L52). In the future, there might be an official API for it. -Create the buttons, to bring this action onto the UI and make it actionable for the user. There are two buttons: On the overview and in the detail screen. Both are defined in the [_layouts.cds_](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/app/travel_processor/layouts.cds) file. +Create the buttons, to bring this action onto the UI and make it actionable for the user. There are two buttons: On the overview and in the detail screen. Both are defined in the [_layouts.cds_](https://github.com/SAP-samples/cap-sflight/blob/42ee666e40f9dba1176f8263b512c10d23f07907/app/travel_processor/layouts.cds) file. -For the overview of all travels, use the [`@UI.LineItem` annotation](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/app/travel_processor/layouts.cds#L40-L41). +For the overview of all travels, use the [`@UI.LineItem` annotation](https://github.com/SAP-samples/cap-sflight/blob/42ee666e40f9dba1176f8263b512c10d23f07907/app/travel_processor/layouts.cds#L40-L41). ```cds annotate TravelService.Travel with @UI : { @@ -658,7 +634,7 @@ LineItem : [ }; ``` -For the detail screen of a travel, use the [`@UI.Identification` annotation](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/app/travel_processor/layouts.cds#L9-L10). +For the detail screen of a travel, use the [`@UI.Identification` annotation](https://github.com/SAP-samples/cap-sflight/blob/42ee666e40f9dba1176f8263b512c10d23f07907/app/travel_processor/layouts.cds#L9-L10). ```cds annotate TravelService.Travel with @UI : { @@ -670,7 +646,7 @@ annotate TravelService.Travel with @UI : { }; ``` -Now, the buttons are there and connected to the action. The missing piece is to define the availability of the buttons dynamically. Annotate the `Travel` entity in the `TravelService` service accordingly in the [_field-control.cds_](https://github.com/SAP-samples/cap-sflight/blob/8f65dc8b7985bc22584d2a9f94335f110c0450ea/app/travel_processor/field-control.cds#L20-L32) file. +Now, the buttons are there and connected to the action. The missing piece is to define the availability of the buttons dynamically. Annotate the `Travel` entity in the `TravelService` service accordingly in the [_field-control.cds_](https://github.com/SAP-samples/cap-sflight/blob/42ee666e40f9dba1176f8263b512c10d23f07907/app/travel_processor/field-control.cds#L23-L36) file. ```cds annotate TravelService.Travel with actions { @@ -683,7 +659,7 @@ annotate TravelService.Travel with actions { This annotation uses [dynamic expressions](../advanced/odata#dynamic-expressions) to control the buttons for each action. And the status of a travel on the UI is updated, triggered by the `@Common.SideEffects.TargetProperties` annotation. :::info More complex calculation -If you have the need for a more complex calculation, then the interesting parts in SFLIGHT are [virtual fields in _field-control.cds_](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/app/travel_processor/field-control.cds#L10-L16) (also lines 37-44) and [custom code in _travel-service.js_](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/srv/travel-service.js#L13-L22). +If you have the need for a more complex calculation, then the interesting parts in (an older version of) SFLIGHT are [virtual fields in _field-control.cds_](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/app/travel_processor/field-control.cds#L10-L16) (also lines 37-44) and [custom code in _travel-service.js_](https://github.com/SAP-samples/cap-sflight/blob/dfc7827da843ace0ea126f76fc78a6591b325c67/srv/travel-service.js#L13-L22). ::: From 81b0ca647381f850fa27d93e9c0b46fd4a2fc4bd Mon Sep 17 00:00:00 2001 From: Markus Ofterdinger Date: Tue, 20 May 2025 15:52:53 +0200 Subject: [PATCH 097/140] Removed broken links to ../developing-applications/properties#cds-errors-combined (#1865) The property `cds.errors.combined` is marked as deprecated in next Major 4.0 release and with that, it's removed from the property documentation. This causes broken links in Capire which needs to be fixed. See also: https://github.tools.sap/cap/docs/pull/1505 --- java/event-handlers/indicating-errors.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/event-handlers/indicating-errors.md b/java/event-handlers/indicating-errors.md index a0cd1fd6d0..38e2b89b52 100644 --- a/java/event-handlers/indicating-errors.md +++ b/java/event-handlers/indicating-errors.md @@ -45,7 +45,7 @@ The OData adapters turn all exceptions into an OData error response to indicate ## Messages -The [Messages](https://www.javadoc.io/doc/com.sap.cds/cds-services-api/latest/com/sap/cds/services/messages/Messages.html) API allows event handlers to add errors, warnings, info, or success messages to the currently processed request. Adding info, warning or success messages doesn't affect the event processing or the transaction. For error messages by default a `ServiceException` is thrown at the end of the `Before` handler phase. You can change this by setting [`cds.errors.combined`](../developing-applications/properties#cds-errors-combined) to `false`. +The [Messages](https://www.javadoc.io/doc/com.sap.cds/cds-services-api/latest/com/sap/cds/services/messages/Messages.html) API allows event handlers to add errors, warnings, info, or success messages to the currently processed request. Adding info, warning or success messages doesn't affect the event processing or the transaction. For error messages by default a `ServiceException` is thrown at the end of the `Before` handler phase. The `Messages` interface provides a logger-like API to collect these messages. Additional optional details can be added to the [Message](https://www.javadoc.io/doc/com.sap.cds/cds-services-api/latest/com/sap/cds/services/messages/Message.html) using a builder API. You can access the `Messages` API from the Event Context: @@ -82,8 +82,7 @@ messages.throwIfError(); If there are any collected error messages, this method creates a [ServiceException](https://www.javadoc.io/doc/com.sap.cds/cds-services-api/latest/com/sap/cds/services/ServiceException.html) from _one_ of these error messages. The OData adapter turns this exception into an OData error response to indicate the error to the client. The remaining error messages are written into the `details` section of the error response. -If the CDS property [`cds.errors.combined`](../developing-applications/properties#cds-errors-combined) is set to true (default), `Messages.throwIfError()` is automatically called at the end of the `Before` handler phase to abort the event processing in case of errors. It is recommended to use the Messages API for validation errors and rely on the framework calling `Messages.throwIfError()` automatically, instead of throwing a `ServiceException`. - +`Messages.throwIfError()` is automatically called at the end of the `Before` handler phase to abort the event processing in case of errors. It is recommended to use the Messages API for validation errors and rely on the framework calling `Messages.throwIfError()` automatically, instead of throwing a `ServiceException`. ## Formatting and Localization From 39e3eddc073e2dd9e1feb612bfdc7eabe953aa5b Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Tue, 20 May 2025 16:45:35 +0200 Subject: [PATCH 098/140] Allow detection of CI host --- .github/workflows/PR-SAP.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/PR-SAP.yml b/.github/workflows/PR-SAP.yml index 1fc80f96dc..ac83cae599 100644 --- a/.github/workflows/PR-SAP.yml +++ b/.github/workflows/PR-SAP.yml @@ -44,6 +44,7 @@ jobs: working-directory: docs env: NODE_OPTIONS: "--max-old-space-size=6144" + VITE_CAPIRE_CI_HOST: "github.com" - name: Find broken anchor links working-directory: docs run: | From 2e0a97cdd4625b9859b9829528e67e9a5d7b367a Mon Sep 17 00:00:00 2001 From: Johannes Vogt Date: Wed, 21 May 2025 11:19:39 +0530 Subject: [PATCH 099/140] add spring-boot-starter-security note (#1792) Mock users are not initialized if this dependency is not present --- java/security.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/java/security.md b/java/security.md index 5de271c902..d01107116c 100644 --- a/java/security.md +++ b/java/security.md @@ -242,6 +242,13 @@ In the example, the `CustomUserInfoProvider` defines an overlay on the default X ### Mock User Authentication with Spring Boot { #mock-users} By default, CAP Java creates a security configuration, which accepts _mock users_ for test purposes. + +::: details Requirement + +Mock users are only initialized if the `org.springframework.boot:spring-boot-starter-security` dependency is present in the `pom.xml` file of your service. + +::: + #### Preconfigured Mock Users For convenience, the runtime creates default mock users reflecting the [pseudo roles](../guides/security/authorization#pseudo-roles). They are named `authenticated`, `system` and `privileged` and can be used with an empty password. For instance, requests sent during a Spring MVC unit test with annotation `@WithMockUser("authenticated")` will pass authorization checks that require `authenticated-user`. The privileged user will pass any authorization checks. `cds.security.mock.defaultUsers = false` prevents the creation of default mock users at startup. From c198a1f3c910b3dadc176e49426b00c345c14788 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Wed, 21 May 2025 10:04:58 +0200 Subject: [PATCH 100/140] Ensure proper encoding of badge URLs --- java/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/java/index.md b/java/index.md index a9b24dd65a..739495dc3a 100644 --- a/java/index.md +++ b/java/index.md @@ -16,8 +16,8 @@ Reference Documentation { .subtitle} - - + + @@ -27,6 +27,7 @@ const { theme } = useData() const { versions } = theme.value.capire import { data as pages } from './index.data.ts' +const enc = s => s.replace(/-/g,'--')
From 5700c96be73b4f92a1d33d986bcc70f7ab4425db Mon Sep 17 00:00:00 2001 From: Daniel Schlachter Date: Wed, 21 May 2025 12:00:21 +0200 Subject: [PATCH 101/140] Attachment plugin (#1797) The two plugins for node and java have some major differences. In node the Object Store is used, while java stores attachments on HANA db. This has knock-on effects on topics like mtx, encryption etc. --- plugins/index.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/index.md b/plugins/index.md index 27d75f12a2..7b813cac23 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -168,7 +168,7 @@ Available for: ## Attachments -The Attachments plugin provides out-of-the-box handling of attachments stored in, for example, AWS S/3 through [SAP BTP's Object Store service](https://discovery-center.cloud.sap/serviceCatalog/object-store). To use it, simply add a composition of the predefined aspect `Attachments` like so: +The Attachments plugin provides out-of-the-box support for attachment handling. On Node.js, attachments are stored on AWS S/3 through [SAP BTP's Object Store service](https://discovery-center.cloud.sap/serviceCatalog/object-store), whereas Java stores attachments on the SAP HANA database. To use it, simply add a composition of the predefined aspect `Attachments` like so: ```cds using { Attachments } from '@cap-js/attachments'; @@ -189,10 +189,7 @@ Features: - (Automatic) Fiori Annotations for Upload Controls - Streaming and piping to avoid memory overloads - Support for different storage backends - -Outlook: - -- Multitenancy intrinsically handled by the plugin +- Support for Multitenancy Available for: From 7ed0a7837503100a90303e6bab2bc8b58c8a2ab4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 16:26:46 +0200 Subject: [PATCH 102/140] chore: Update CLI texts (#1866) Updates the output of cds CLI texts to the latest version. Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com> --- tools/assets/help/cds-version-md.out.md | 6 +++--- tools/assets/help/cds-version.out.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index 77e05a379a..233a355c64 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -7,11 +7,11 @@ | @cap-js/asyncapi | 1.0.3 | | @cap-js/cds-types | 0.10.0 | | @cap-js/db-service | 1.20.0 | -| @cap-js/openapi | 1.2.1 | +| @cap-js/openapi | 1.2.2 | | @cap-js/sqlite | 1.11.0 | -| @sap/cds | 8.9.3 | +| @sap/cds | 8.9.4 | | @sap/cds-compiler | 5.9.2 | -| @sap/cds-dk (global) | 8.9.3 | +| @sap/cds-dk (global) | 8.9.4 | | @sap/cds-fiori | 1.4.1 | | @sap/cds-foss | 5.0.1 | | @sap/cds-mtxs | 2.7.2 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 4c67e6eed7..6d8efaa2e4 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -5,11 +5,11 @@ @cap-js/asyncapi: 1.0.3 @cap-js/cds-types: 0.10.0 @cap-js/db-service: 1.20.0 -@cap-js/openapi: 1.2.1 +@cap-js/openapi: 1.2.2 @cap-js/sqlite: 1.11.0 -@sap/cds: 8.9.3 +@sap/cds: 8.9.4 @sap/cds-compiler: 5.9.2 -@sap/cds-dk (global): 8.9.3 +@sap/cds-dk (global): 8.9.4 @sap/cds-fiori: 1.4.1 @sap/cds-foss: 5.0.1 @sap/cds-mtxs: 2.7.2 From 704ff03a55da2e7c9b7a546e114d97b501add853 Mon Sep 17 00:00:00 2001 From: Marc Becker Date: Thu, 22 May 2025 11:52:04 +0200 Subject: [PATCH 103/140] Document State Messages in Java Drafts section (#1869) --- java/fiori-drafts.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index 8652fa3e90..45539af590 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -94,6 +94,49 @@ The `DRAFT_CREATE` is an internal event that is not triggered by OData requests For more examples, see the [Bookshop sample application](https://github.com/SAP-samples/cloud-cap-samples-java/tree/master/srv/src/main/java/my/bookshop/handlers/AdminServiceHandler.java). +## Validating Drafts + +CAP Java supports persisting (error) messages for draft-enabled entities and providing _state messages_ to the UI5 OData V4 model. +This enables validations of drafts and giving feedback about errors to users faster in the UI. + +To enable this feature, set the following properties in your `.cdsrc.json`: + +::: code-group +```json [.cdsrc.json] +{ + "cdsc": { + "beta": { + "draftMessages": true + } + } +} +``` +::: + +::: warning Document-based URLs +The state messages feature relies on UI5 to use _document URLs_. CAP sets the annotation `@Common.AddressViaNavigationPath` to instruct UI5 to use _document URLs_. This requires UI5 version >= 1.135.0. +::: + +Setting this property adds additional elements to your draft-enabled entities and `DraftAdministrativeData`, which are required to store and serve state messages. + +If this feature is activated, you can observe the following improvements, without any changes to the application code: + +- Error messages for annotation-based validations (for example, `@mandatory` or `@assert...`) already appear while editing the draft. +- Custom validations can now be bound to the `DRAFT_PATCH` event and can write (error) messages. It's ensured that the invalid value is still persisted, as expected by the draft choreography. +- Messages no longer unexpectedly vanish from the UI after editing another field. +- Messages are automatically loaded when reopening a previously edited draft. + +By default, side-effect annotations are generated in the EDMX that instruct UI5 to fetch state messages after every `PATCH` request. +In case more precise side-effect annotations are required you can disable the default side-effect annotation per entity: + +```cds +annotate MyService.MyEntity with @Common.SideEffects #alwaysFetchMessages: null; +``` + +::: warning Requires Schema Update +Enabling draft messages requires a database schema update, as it adds an additional element to `DraftAdministrativeData`. +::: + ## Activating Drafts When you finish editing drafts by pressing the *Save* button, a draft gets activated. That means, either a single `CREATE` or `UPDATE` event is triggered to create or update the active entity with all of its compositions through a deeply structured document. You can register to these events to validate the activated data. From 5804d87b02cb57ed56db5ed6ce4e739b731296a3 Mon Sep 17 00:00:00 2001 From: Daniel O'Grady <103028279+daogrady@users.noreply.github.com> Date: Thu, 22 May 2025 14:32:18 +0200 Subject: [PATCH 104/140] Doc improvements on 'Custom Builds' (#1837) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Minor Changes - consistent formatting of config values in `monospace font` (rather than _italics_, which is used more for file names) - some changes in wording - make connections within the guide explicit that were implicit before - added file name header to snippets to make it more immediately clear where they are supposed to go - use `` tag where appropriate ## Structural Changes From Manual Testing For CDS9 - πŸ”΄ bad, shows bad practices - 🟑 could be improved, best practices are missing - 🟒 good (not necessarily perfect) _I added a related snippet for convenient searching of the relevant section, followed by my feedback._ ----- > provides options you can use to switch the copy behavior on build task level on or off πŸ”΄ the following example doesn't really make it clear how the behaviour can be changed or what the options shown in the configuration do exactly. βœ… ----- > If custom build tasks are configured, those properties have precedence For example, you want to configure the src folder and add the default models. To achieve this, do not define the model option in your build task. πŸ”΄ How else should we do it then? βœ… ----- > Such a setup is often referred to as a [monorepo] The link then leads to an external blog entry about monorepos. 🟑 This feels a bit weird and out of place. There doesn't seem to be an official guide about mono repos, which is probably the reason why this link was used instead. But maybe we can find something else? βœ… (did not find anything more official) ----- > The for property defines the executed build task type. Currently supported types are: The section then lists various parameters for the `for` parameter. 🟑 I am not entirely sure how to feel about this section. While it currently seems to be up to date, it will inherently become outdated at some point and is basically a clone of what `cds build --help` would list under the appropriate section for `--for`. Could we instead have the output of `cds build --help` here and make that more explicit instead? We do this similarly [for cds-typer](https://cap.cloud.sap/docs/tools/cds-typer#typer-cli). βœ… (postponed: /cds-tools/issues/1541) ----- > It is resolved based on the root folder of your project. 🟑 The following section shows an example of a configuration done in _package.json_. This is one of multiple places where we can see this pattern. We have the `` custom tag to show various ways of including a configuration, aside from _package.json_ nowadays. Could/ should we use this more excessively here? βœ… ----- > for each workspace dependency of your project that has a `*` version identifier πŸ”΄ This needs an example! βœ… ----- > A build plugin is a Node.js module complying to the CDS plugin architecture The following code blocks shows an outdated version of the postgres build plugin. πŸ”΄ I don't think we should duplicate the code at this point. We link to the `main` branch of the repository containing this plugin just above. I don't see how showing a larger code block that will inherently be outdated without added explanation brings any value to the table. (The section after that _does_ go into detail about some of the methods, but not all. So even if we wanted to use this particular plugin as an illustration of the API, it is just not complete and would benefit more from having the actual API doc included at this point.) **Opportunity to include exported type information inside CAPire?!** @chgeo βœ… (we discussed it and came to the conclusion to leave it in. Types can follow at a later point in time.) ----- --------- Co-authored-by: Christian Georgi Co-authored-by: RenΓ© Jeglinsky --- guides/deployment/custom-builds.md | 67 +++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/guides/deployment/custom-builds.md b/guides/deployment/custom-builds.md index ab138c3399..7bbdecd977 100644 --- a/guides/deployment/custom-builds.md +++ b/guides/deployment/custom-builds.md @@ -19,9 +19,9 @@ status: released The CDS model folders and files used by `cds build` are determined as follows: -- Known root folders, by [default](../../get-started/#project-structure) the folders _db/, srv/, app/_, can also be configured by [_folders.db, folders.srv, folders.app_](../../get-started/#project-structure). +- Known root folders, by [default](../../get-started/#project-structure) the folders _db/, srv/, app/_, can also be configured by [`folders.db`, `folders.srv`, `folders.app`](../../get-started/#project-structure). - The _src_ folder configured for the individual build task. -- If [Feature toggles](../extensibility/feature-toggles#enable-feature-toggles) are enabled: subfolders of the folder _fts_. +- If [feature toggles](../extensibility/feature-toggles#enable-feature-toggles) are enabled: subfolders of the folder _fts_. - CDS Model folders and files defined by the [required services](../../node.js/cds-env#services) of your project. This also includes models used by required built-in CDS services, like [persistent outbox](../../node.js/outbox#persistent-outbox) or [MTX related services](../multitenancy/mtxs#mtx-services-reference). Feature toggle folders and required built-in service models will also be added if user defined models have already been configured as [_model_ option](#build-task-properties) in your build tasks. @@ -29,10 +29,30 @@ Feature toggle folders and required built-in service models will also be added i [Learn more about the calculation of the concrete list of CDS models.](../../node.js/cds-compile#cds-resolve){.learn-more} ::: tip If custom build tasks are configured, those properties have precedence -For example, you want to configure the _src_ folder and add the default models. To achieve this, do not define the _model_ option in your build task. That way, the model paths will still be dynamically determined, but the _src_ folder is taken from the build task configuration. So you benefit from the automatic determination of models, for example, when adding a new external services, or when CAP is changing any built-in service configuration values. +For example, you want to configure the _src_ folder and add the default models. To achieve this, do not define the _model_ option in your build task: + +::: code-group + +```jsonc [package.json] +{ + "build": { + "target": "gen", + "tasks": [ + { + "for": "nodejs", + "src": "srv", + "options": { /* no "model" entry here */ } + } + ] + } +} +``` + + + That way, the model paths will still be dynamically determined, but the _src_ folder is taken from the build task configuration. So you benefit from the automatic determination of models, for example, when adding a new external services, or when CAP is changing any built-in service configuration values. ::: -To control which tasks `cds build` executes, you can add them as part of your [project configuration](../../node.js/cds-env#project-settings) in _package.json_ or _.cdsrc.json_. +To control which tasks `cds build` executes, you can add them as part of your [project configuration](../../node.js/cds-env#project-settings) in _package.json_ or _.cdsrc.json_, as outlined [in the following chapter](#build-task-properties). ## Properties @@ -40,7 +60,9 @@ To control which tasks `cds build` executes, you can add them as part of your [p The following build tasks represent the default configuration dynamically determined by `cds build` for a minimal Node.js project when executing `cds build --production` or `cds build --profile production` : -```json +::: code-group + +```json [package.json] { "build": { "target": "gen", @@ -52,6 +74,8 @@ The following build tasks represent the default configuration dynamically determ } ``` +::: + ::: tip The executed build tasks are logged to the command line. You can use them as a blue print – copy & paste them into your CDS configuration and adapt them to your needs. See also the command line help for further details using `cds build --help`. ::: @@ -89,18 +113,14 @@ Alternatively you can execute build tasks and pass the described arguments from ### Build Target Folder {#build-target-folder} -If you want to change the default target folder, use the `target` property in _.cdsrc.json_ or _package.json_. It is resolved based on the root folder of your project. +If you want to change the default target folder, use the cds.build.target=path/to/my/folder property. It is resolved based on the root folder of your project. + -```json -{ - "build": { "target" : "myfolder" } -} -``` #### Node.js Node.js projects use the folder _./gen_ below the project root as build target folder by default.
-Relevant source files from _db_ or _srv_ folders are copied into this folder, which makes it a self-contained folder that is ready for deployment. The default folder names can be changed with the _folders.db_, _folders.srv_, _folders.app_ configuration. Or you can go for individual build task configuration for full flexibility. +Relevant source files from _db_ or _srv_ folders are copied into this folder, which makes it self-contained and ready for deployment. The default folder names can be changed with the cds.folders.db, cds.folders.srv, cds.folders.app configuration. Or you can go for individual build task configuration for full flexibility. Project files like _.cdsrc.json_ or _.npmrc_ located in the _root_ folder or in the _srv_ folder of your project are copied into the application's deployment folder (default _gen/srv_). Files located in the _srv_ folder have precedence over the corresponding files located in the project root directory. As a consequence these files are used when deployed to production. Make sure that the folders do not contain one of these files by mistake. Consider using profiles `development` or `production` in order to distinguish environments. CDS configuration that should be kept locally can be defined in a file _.cdsrc-private.json_. @@ -112,9 +132,11 @@ Relevant source files from _db_ or _srv_ folders are copied into this folder, wh [Learn more about `cds env get`](../../node.js/cds-env#cli){.learn-more} **Note:** -`cds build` provides options you can use to switch on or off the copy behavior on build task level: +`cds build` provides `options` you can use to switch the copy behavior of specific files on or off on build task level: -```json +::: code-group + +```json [package.json] { "build": { "tasks": [ @@ -125,13 +147,26 @@ Relevant source files from _db_ or _srv_ folders are copied into this folder, wh } ``` +::: + #### npm Workspace Support {#build-ws} Use CLI option `--ws-pack` to enable tarball based deployment of [npm workspace](https://docs.npmjs.com/cli/using-npm/workspaces) dependencies. Workspaces are typically used to manage multiple local packages within a singular top-level root package. Such a setup is often referred to as a [monorepo](https://earthly.dev/blog/npm-workspaces-monorepo/). As an effect, your workspace dependencies can be deployed to SAP BTP without them being published to an npm registry before. -Behind the scenes, `cds build --ws-pack` creates a tarball in folder _gen/srv_ for each workspace dependency of your project that has a `*` version identifier. Dependencies in _gen/package.json_ will be adapted to point to the correct tarball file URL. +Behind the scenes, `cds build --ws-pack` creates a tarball in folder _gen/srv_ for each workspace dependency of your project that has a `*` version identifier. Dependencies in _gen/package.json_ will be adapted to point to the correct tarball file URL: + +::: code-group +```jsonc [package.json] +{ + "dependencies": { + "some-package": "^1", // regular package + "some-workspace": "*" // workspace dependency, marked as such via "*" + } +} +``` +::: Packaging of the tarball content is based on the rules of the [`npm pack`](https://docs.npmjs.com/cli/commands/npm-pack) command: @@ -145,7 +180,7 @@ This causes `cds build` to create the build output below the individual source f ## Implement a Build Plugin {#custom-build-plugins} -CDS already offers build plugins to create deployment layouts for the most use cases. However, you find cases where these plugins are not enough and you have to develop your own. This section shows how such a build plugin can be implemented and how it can be used in projects. +CDS already offers build plugins to create deployment layouts for the most use cases. However, you will find cases where these plugins are not enough and you have to develop your own. This section shows how such a build plugin can be implemented and how it can be used in projects. Build plugins are run by `cds build` to generate the required deployment artifacts. Build tasks hold the actual project specific configuration. The task's `for` property value has to match the build plugin ID. From 44ee3475a68c416fee954409e427e58ce232b391 Mon Sep 17 00:00:00 2001 From: Rishi Kunnath <82925475+rishikunnath2747@users.noreply.github.com> Date: Thu, 22 May 2025 18:03:47 +0530 Subject: [PATCH 105/140] Changes for SDM Plugin (#1859) Removed "Permission Management" section --- plugins/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/index.md b/plugins/index.md index 7b813cac23..ea84b18093 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -226,7 +226,6 @@ Features: Outlook: - **Support for Versioned Repository**: Ensure better document control and historical tracking with native support for versioned repositories, enabling you to manage document revisions effectively. -- **Permission Management**: Implement granular permission handling to ensure that only authorized users can access, modify, or manage documents, bolstering security and compliance. - **Native Document Management Features with SAP Document Management Service**: Access a wide array of native document management features provided by the SAP Document Management service, including metadata management, advanced search capabilities, and audit trails. For more information, see [SAP Document Management Service](https://help.sap.com/docs/document-management-service/sap-document-management-service/what-is-document-management-service). Available for: From ec9f1d62ab76a4f481bfcd2d107518b817498ce1 Mon Sep 17 00:00:00 2001 From: Christian Fuchs <32135773+manwithafox@users.noreply.github.com> Date: Thu, 22 May 2025 15:49:39 +0200 Subject: [PATCH 106/140] docs: revised editor docs (#1868) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky --- tools/cds-editors.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/cds-editors.md b/tools/cds-editors.md index 970276b274..5813b59845 100644 --- a/tools/cds-editors.md +++ b/tools/cds-editors.md @@ -346,14 +346,6 @@ Keeps track of the active editor in focus. Only changes there are immediately va The *ActiveEditorOnly* mode is especially useful in situations when navigating through a large model, that is, having multiple files open (even if they are not shown as tabs) and editing a file that the others directly or indirectly depend on. -::: warning Large models can lead to **high CPU and memory load** -If switched to *OpenEditorsAndDirectSources*, all model files on every change, for example typed character, are recompiled. - -If switched to _OpenEditorsOnly_, all open files, for example split tabs, are recompiled. - -The high resource consumption might impact the editor's responsiveness. -::: - ##### Cds > Contributions > [Enablement: Odata](vscode://settings/cds.contributions.enablement.odata) Default: *on* @@ -406,7 +398,7 @@ You want to create a preview of a specific _.cds_ file in your project. You can ##### Visualize CDS file dependencies -Use the command from the context menu on a folder or CDS file. +Use the command from the context menu on a folder or CDS file, or from within the popup when hovering over an _import_ path at the end of a _using_ statement. A selection popup appears to choose one of three modes: @@ -446,7 +438,7 @@ Until a further change, reference calculation is reasonably fast. - Changing settings in _CDS_ section will currently perform a complete workspace invalidation, that is, required indexes will lead to recompilations on demand as described above. - Changing certain `cds.env` settings, for example folder configurations, will invalidate the workspace as well. -### CDS Source Formatter { #cds-formatter} +### CDS Source Formatter { #cds-formatter} The CDS code formatter provides a command line interface. Use it as a pre-commit hook or within your CI/CD pipeline to ensure consistent formatting. From 3347232a4cfe1c6504feb3aa1c4c591ba5cc8e64 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Fri, 23 May 2025 07:39:32 +0200 Subject: [PATCH 107/140] Explain some caveats in change tracking (#1798) Change tracking documentation is extended to attempt to clear two things that cause confusion between stakeholders: - the element-defined identifier should not be used for compositions as it does very little sense for them. - the stakeholders need to ensure that change-tracked entities are updated using deep updates from the root of the document (entity with compositions). Notably, the changes are not linked to their expected parents and this causes confusion. --------- Co-authored-by: Marc Becker Co-authored-by: Rene Jeglinsky --- java/change-tracking.md | 108 +++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 45 deletions(-) diff --git a/java/change-tracking.md b/java/change-tracking.md index d55584ecb5..a55918d0ac 100644 --- a/java/change-tracking.md +++ b/java/change-tracking.md @@ -119,33 +119,36 @@ The level where you annotate your elements with the annotation `@changelog` is v the elements on the _domain_ level, every change made through every projection of the entity is tracked. If you annotate the elements on the _service_ level, only the changes made through that projection are tracked. -In case of the books example above, the changes made through the service entity `Bookshop.Books` are tracked, but the changes +Using the previous books example, the changes made through the service entity `Bookshop.Books` are tracked, but the changes made on the domain entity are omitted. That can be beneficial if you have a service that is used for data replication or mass changes where change tracking can be a very expensive operation, and you do not want to generate changes from such operations. Change tracking also works with the entities that have compositions and tracks the changes made to the items of the compositions. -For example, if you have an entity that represents the order with a composition that represents the items of the order, -you can annotate the elements of both and track the changes made through the order and the items in a deep update. +In the following example you have an entity that represents the order with a composition that represents the items of the order. You can annotate the elements of both and track the changes made through the order and the items in a deep update. ```cds -entity OrderItems { - key ID: UUID; +entity OrderItems : cuid { + parent : Association to Orders; [...] quantity: Integer @changelog; } -entity Orders { - key ID: UUID; +entity Orders : cuid { customerName: String @changelog; [...] - items: Composition of many OrderItems; + items: Composition of many OrderItems on items.parent = $self; } ``` -### Identifiers for Changes +:::tip Remember: Extend `Orders` entity +You must extend the `Orders` with the aspect `changelog.changeTracked` and not the `OrderItems`. With this, all changes in the `Orders`, even deep ones, are associated with the `Orders`. +::: + +### Identifiers for Entities + +You can store some elements of the entity together with the changes in the change log to produce a user-friendly identifier that annotates changes. -You can store some elements of the entity together with the changes in the change log to produce a user-friendly identifier. You define this identifier by annotating the entity with the `@changelog` annotation and including the elements that you want to store together with the changed value: @@ -156,56 +159,74 @@ annotate Bookshop.Book with @changelog: [ ``` This identifier can contain the elements of the entity or values of to-one associations that are reachable via path. -For example, for a book you can store an author name if you have an association from the book to the author. +For example, for a book you can store an author name if you have an association from the book to the author. The best candidates for identifier are the elements that are insert-only or that don't change often. -When you define the identifier for an entity, keep in mind that the projections of the annotated entity -will inherit the annotation `@changelog`. If you change the structure of the projection, -for example, exclude or rename the elements that are used in the identifier, you must annotate the projection again -to provide updated element names in the identifier. +### Identifiers for Compositions -The best candidates for identifier elements are the elements that are insert-only or that don't change often. - -:::warning Stored as-is -The values of the identifier are stored together with the change log as-is. They are not translated and some data types might -not be formatted per user locale or some requirements, for example, different units of measurement or currencies. -You should consider this when you decide what to include in the identifier. -::: +For compositions, no special annotations are required. The identifiers of the target entity are used instead. -### Identifiers for Associated Entities +For example, given the following model: -When your entity has an association to an other entity, you might want to log the changes in their relationship. - -Given the `Orders` entity with an association to a `Customer` instead of the element with customer name: ```cds -entity Orders { - key ID: UUID; +entity Orders : cuid { + OrderNo : String; customer: Association to Customer; [...] + items: Composition of many OrderItems on items.parent = $self; +} + +entity OrderItems : cuid { + parent : Association to Orders; + supplierName: String; + [...] + quantity : Integer; } ``` -If you annotate such an association with `@changelog`, by default, the change log stores the value of the associated entity key. -If you want, you can store some human-readable identifier instead. You define this by annotating the association with an own identifier: +You can annotate your model as follows to define identifiers for both entities. + +```cds +annotate Orders with @changelog: [OrderNo]; + +annotate OrderItems with @changelog: [ + parent.OrderNo, + supplierName, +]; +``` + +Changes for `Orders` and `OrderItems` will have their own respective target or root identifiers filled. + +### Human-readable values for associations + +For associations, the value of the foreign key is stored in the changelog by default. You can change this and store the values of the associated entity instead. +This kind of identifier changes the values stored in the changelog, while [entity identifiers](#identifiers-for-entities) annotate changed values. + +You annotate your entity like this: ```cds annotate Orders { customer @changelog: [ customer.name ] } ``` - -Elements from the `@changelog` annotation value must always be prefixed by the association name. The same caveats as for the identifiers for the entities apply here. - -If you annotate a composition with an identifier, the change log will contain an entry with the identifier's value. Additionally, it will include change log entries for all annotated elements of the composition's target entity. +Elements from the `@changelog` annotation value must always be prefixed by the association name. :::warning Validation required If the target of the association is missing, for example, when an entity is updated with the ID for a customer -that does not exists, the changelog entry will not be created. You need to validate +that does not exist, the changelog entry is not created. You need to validate such cases in the custom code or use annotations, for example, [`@assert.target`](/guides/providing-services#assert-target). ::: -This feature can also be used for to-many compositions, when you don't need to track the deep changes, but still want to track the additions and removals in the composition. +### Caveats of Identifiers + +Consider the following important points that are relevant for all kinds of identifiers and human-readable values: -With association identifiers you also must consider the changes in your entities structure along the projections. In case your target entity is exposed using different projections with removed or renamed elements, you also need to adjust the identifier accordingly in the source entity. +- When you define the identifier for an entity, keep in mind that the projections of the annotated entity +inherit the annotation `@changelog`. If you change the structure of the projection, +for example, exclude or rename the elements that are used in the identifier, you must annotate the projection again +to provide updated element names in the identifier. This is one additional benefit of annotating the top-most projection for change tracking. + +- The values of the identifier are stored together with the change log as-is. They are not translated and some data types might +not be formatted per user locale or some requirements, for example, different units of measurement or currencies. ### Displaying Changes @@ -234,7 +255,7 @@ If you want to have a common UI for all changes, you need to expose the change l your own presentation for it as the changes are exposed only as part of the change-tracked entity. This projection must be read-only and shouldn't be writable via OData requests. -The change log is extended with the texts for your entities from the `@title` annotation and the element. Otherwise, the change log contains only the technical names of the entities and the elements. +The change log is extended with the texts coming from your entities' `@title` annotation and the element. Otherwise, the change log contains only the technical names of the entities and the elements. Titles are translated, if they're annotated as translatable. See [Externalizing Texts Bundles](../guides/i18n#localization-i18n) for more information. ## How Changes are Stored @@ -265,18 +286,15 @@ are considered as modified. Each change detected by the change tracking feature In the case of the deeply structured documents, for example, entities with the compositions, the change tracking feature detects the changes across the complete document and stores them in the change log with the metadata reflecting the structure of the change. -For example, given the order and item model from above, if you change values for the tracked elements with -the deep update, for example, the customer name in the order and the quantity of the item, the change log contains -two entries: one for the order and one for the item. The change log entry for the item will also reflect that -the root of the change is an order. +Take the order and item model used previously in this guide as an example. If you change values for the tracked elements with the deep update, for example, the customer name in the order and the quantity of the item, the change log contains two entries: one for the order and one for the item. The change log entry for the item will also reflect that the root of the change is an order. Both changes will be reachable through the association `changes` of the order entity. -:::warning Prefer deep updates for change tracked entities -If you change the values of the `OrderItems` entity directly via an OData request or a CQL statement, the change log contains only one entry for the item and won't be associated with an order. +:::warning Prefer deep updates for change-tracked entities +If you change the values of the `OrderItems` entity directly via an OData request or a CQL statement, the change log contains only one entry for the item. The change won't be associated with an order and will not be reachable through the `changes` association. While the updates of composition targets directly are possible, the change tracking feature does not attempt to resolve the parent entity by itself, it requires that either OData request or a CQL statement provide the reference to the parent, for example, `Orders`. ::: ## Reacting on Changes -You can write an event handler to observe the change log entries. Keep in mind, that the change log entries +You can write an event handler to observe the change log entries. Keep in mind that the change log entries are created for each statement and this event will not be bound to any kind of transaction or a batch operation. First, update the dependency's scope to `compile` in the `srv/pom.xml` file of your service: From 7d9982c5cf571a5bcb7a49a34346024e3dcc12d3 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Fri, 23 May 2025 08:43:06 +0200 Subject: [PATCH 108/140] feat: Task Queues (#1861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Co-authored-by: RenΓ© Jeglinsky --- cds/cql.md | 2 +- guides/messaging/task-queues.md | 55 +++++++++++++++++++++++++++++++++ menu.md | 1 + 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 guides/messaging/task-queues.md diff --git a/cds/cql.md b/cds/cql.md index a115bd71f5..aaa949c74d 100644 --- a/cds/cql.md +++ b/cds/cql.md @@ -399,7 +399,7 @@ SQL casts and CDL casts. The former produces SQL casts when rendered into SQL, w SELECT cast (foo+1 as Decimal) as bar from Foo; -- standard SQL SELECT from Foo { foo+1 as bar : Decimal }; -- CDL-style ``` -[learn more about CDL type definitions](./cdl#types){.learn-more} +[Learn more about CDL type definitions](./cdl#types){.learn-more} Use SQL casts when you actually want a cast in SQL. CDL casts are useful for expressions such as `foo+1` as the compiler does not deduce types. For the OData backend, by specifying a type, the compiler will also assign the correct EDM type in the generated EDM(X) files. diff --git a/guides/messaging/task-queues.md b/guides/messaging/task-queues.md new file mode 100644 index 0000000000..568bfe9120 --- /dev/null +++ b/guides/messaging/task-queues.md @@ -0,0 +1,55 @@ +--- +synopsis: > + Task Queues allow to schedule the processing of workloads in a resilient fashion. +status: released +--- + +# Task Queues + +The _Outbox Pattern_ is a reliable strategy used in distributed systems to ensure that messages or events are consistently recorded and delivered, even in the face of failures. +This pattern, however, can not only be applied to outbound messages, but to inbound messages and server-internal background tasks as well. +The core principle remains the same: +1. Persist the message (or _task_) in the database -- using the same transaction as the triggering action, if applicable +2. Process it asynchronously afterwards -- incl. retries, if necessary + +Over the next months, CAP will evolve its outbox to generic _Task Queues_ with the following four components: +1. Outbox β†’ for outbound calls to remote services +2. Inbox β†’ for asynchronously handling inbound requests +3. Background tasks β†’ e.g., scheduled periodically +4. Callbacks β†’ implement SAGA patterns + +This guide will grow with the functionality. + + + +## Outbox { #outbox } + +Regarding the _outbox_, please see the following existing documentation: +- [Transactional Outbox](../../java/outbox) in CAP Java +- [Outboxing with `cds.outboxed`](../../node.js/outbox) in CAP Node.js + + + +## Inbox { #inbox } + +Through the _inbox_, inbound messages can be accepted as asynchronous tasks. +That is, the messaging service persists the message to the database, acknowledges it to the message broker, and schedules its processing. + +Simply configure your messaging service for Node.js as cds.requires.messaging.inboxed = true and for CAP Java as cds.messaging.services=[{"name": "messaging-name", "inbox": {"enabled": true}}] + +**Inboxing moves the dead letter queue into your CAP app❗️** + +With the inbox, all messages are acknowledged towards the message broker regardless of whether they can be processed or not. +Hence, failures need to be managed via the dead letter queue built on `cds.outbox.Messages`. + +[Learn more about the dead letter queue in Node.js.](../../node.js/outbox#managing-the-dead-letter-queue){.learn-more} +[Learn more about the dead letter queue in Java.](../../java/outbox#outbox-dead-letter-queue){.learn-more} + +Inboxing is especially beneficial in case the message broker does not allow to trigger redelivery and/ or "fix" the message payload. + + + +## More to Come + +This documentation is not complete yet, or the APIs are not released for general availability. +Stay tuned to upcoming releases for further updates. diff --git a/menu.md b/menu.md index f6bfed8e36..6a7a97b7ff 100644 --- a/menu.md +++ b/menu.md @@ -46,6 +46,7 @@ ### [SAP Event Mesh](guides/messaging/event-mesh) ### [Apache Kafka](../guides/messaging/apache-kafka) ### [Events from S/4](guides/messaging/s4) + ### [Task Queues](guides/messaging/task-queues) ## [Protocols/APIs](advanced/publishing-apis/) From 133b88e91db4cca92abd4797191430fe0e5457f8 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 23 May 2025 09:06:21 +0200 Subject: [PATCH 109/140] fix menu --- java/_menu.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/_menu.md b/java/_menu.md index d69dd1f514..167cf33fb0 100644 --- a/java/_menu.md +++ b/java/_menu.md @@ -16,14 +16,14 @@ ## [Indicating Errors](event-handlers/indicating-errors) ## [Request Contexts](event-handlers/request-contexts) ## [ChangeSet Contexts](event-handlers/changeset-contexts) -# [Fiori Drafts](../../java/fiori-drafts) +# [Fiori Drafts](java/fiori-drafts) # [Messaging](messaging) # [Audit Logging](auditlog) -# [Change Tracking](../../java/change-tracking) +# [Change Tracking](change-tracking) # [State Transitions](../../java/flows) # [Transactional Outbox](outbox) -# [Multitenancy](../../java/multitenancy) - ## [Multitenancy (Classic)](../../java/multitenancy-classic) +# [Multitenancy](java/multitenancy) + ## [Multitenancy (Classic)](java/multitenancy-classic) # [Security](security) ## [IAS and AMS](../../java/ams) # [Spring Boot Integration](spring-boot-integration) @@ -37,5 +37,5 @@ ## [Optimizing](operating-applications/optimizing) ## [Observability](operating-applications/observability) ## [Developer Dashboard](../../java/operating-applications/dashboard) -# [Building Plugins](../../java/building-plugins) +# [Building Plugins](java/building-plugins) # [Migration Guides](migration) \ No newline at end of file From 9b50fe764f3cc72c92ea4904f3bc21c23147b8f8 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 23 May 2025 09:07:19 +0200 Subject: [PATCH 110/140] fix --- java/_menu.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/_menu.md b/java/_menu.md index 167cf33fb0..f556f7bc46 100644 --- a/java/_menu.md +++ b/java/_menu.md @@ -16,14 +16,14 @@ ## [Indicating Errors](event-handlers/indicating-errors) ## [Request Contexts](event-handlers/request-contexts) ## [ChangeSet Contexts](event-handlers/changeset-contexts) -# [Fiori Drafts](java/fiori-drafts) +# [Fiori Drafts](fiori-drafts) # [Messaging](messaging) # [Audit Logging](auditlog) # [Change Tracking](change-tracking) # [State Transitions](../../java/flows) # [Transactional Outbox](outbox) -# [Multitenancy](java/multitenancy) - ## [Multitenancy (Classic)](java/multitenancy-classic) +# [Multitenancy](multitenancy) + ## [Multitenancy (Classic)](multitenancy-classic) # [Security](security) ## [IAS and AMS](../../java/ams) # [Spring Boot Integration](spring-boot-integration) @@ -37,5 +37,5 @@ ## [Optimizing](operating-applications/optimizing) ## [Observability](operating-applications/observability) ## [Developer Dashboard](../../java/operating-applications/dashboard) -# [Building Plugins](java/building-plugins) +# [Building Plugins](building-plugins) # [Migration Guides](migration) \ No newline at end of file From f73e385d4de07a899a085e9bcc205de0fe35b02d Mon Sep 17 00:00:00 2001 From: ecklie <52252271+ecklie@users.noreply.github.com> Date: Fri, 23 May 2025 12:07:21 +0200 Subject: [PATCH 111/140] hint for know mtxs issue with java (#1870) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Are there any other places where the hint would make sense? --------- Co-authored-by: Christian Georgi Co-authored-by: RenΓ© Jeglinsky Co-authored-by: Christian Georgi --- guides/multitenancy/index.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/guides/multitenancy/index.md b/guides/multitenancy/index.md index 1bb34e78a8..fe5e895c63 100644 --- a/guides/multitenancy/index.md +++ b/guides/multitenancy/index.md @@ -274,6 +274,11 @@ After adding multitenancy, Maven build should be used to generate the model rela mvn install ``` +:::warning Error message: 'Invalid MTX sidecar configuration' +If you get the message 'Invalid MTX sidecar configuration', you need to add the dependency to `@sap/cds-mtxs` also to the `package.json` in your project root. +This is a known issue in CDS 9. +::: +
## Test-Drive Locally {#test-locally} From 44c3f2af983a728a9221ff7ea057333933afccbd Mon Sep 17 00:00:00 2001 From: Markus Ofterdinger Date: Fri, 23 May 2025 12:55:06 +0200 Subject: [PATCH 112/140] Removed chapter about exporting default messages. (#1860) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BLI: https://github.wdf.sap.corp/cds-java/home/issues/1915 --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Marc Becker Co-authored-by: Christian Georgi Co-authored-by: Mahati Shankar <93712176+smahati@users.noreply.github.com> Co-authored-by: RenΓ© Jeglinsky --- java/event-handlers/indicating-errors.md | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/java/event-handlers/indicating-errors.md b/java/event-handlers/indicating-errors.md index 38e2b89b52..d9980a3567 100644 --- a/java/event-handlers/indicating-errors.md +++ b/java/event-handlers/indicating-errors.md @@ -128,26 +128,10 @@ CAP Java provides out-of-the-box translation for error messages that originate f The error messages are optimized for UI scenarios and avoid any technical references to entity names or element names. Message targets are used where appropriate to allow the UI to show the error message next to the affected UI element. You can enable these translated error messages by setting [cds.errors.defaultTranslations.enabled: true](../developing-applications/properties#cds-errors-defaultTranslations-enabled). -### Exporting the Default Messages - -As of CAP Java 1.10.0, you can extract the available default messages as a resource bundle file for further processing (for example, translation). Therefore, the delivery artifact [cds-services-utils](https://search.maven.org/artifact/com.sap.cds/cds-services-utils) contains a resource bundle `cds-messages-template.properties` with all available error codes and default messages. Application developers can use this template to customize error messages thrown by the CAP Java SDK in the application. - -1. [Download](https://search.maven.org/artifact/com.sap.cds/cds-services-utils) the artifact or get it from the local Maven repository in `~/.m2/repository/com/sap/cds/cds-services-utils//cds-services-utils-.jar`. -1. Extract the file. - ```sh - jar -f cds-services-utils-.jar -x cds-messages-template.properties - ``` - ::: tip - \ is the version of CAP Java you're using in your project. - ::: - -1. Rename the extracted file `cds-messages-template.properties` appropriately (for example, to `cds-messages.properties`) and move it to the resource directory of your application. -1. In your Spring Boot application, you have to register this additional [resource bundle](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.internationalization) accordingly. - -> Now, you're able to customize the stack error messages in your application. - -With new CAP Java versions, there could be also new or changed error messages in the stack. To identify these changes, export `cds-messages-template.properties` from the new CAP Java version and compare it with the previous version using a diff tool. +### Provide custom error messages +By default, CAP Java provides error messages in several languages. If an error message or translation isn't sufficient for an application, it can be overwritten with a custom error message. Applications can provide the new error message under the respective error code in the application's `messages.properties` resource bundle under `src/main/resources`. +To know which error codes and messages are available by default, you can have a look at the Java enumeration `com.sap.cds.services.utils.CdsErrorStatuses` with your favorite IDE. This enumeration shows all available error codes and messages that are used by the CAP Java runtime. ## Target From 2aa0dd1be880b1ae1a1199d62f533c3baad64620 Mon Sep 17 00:00:00 2001 From: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Date: Fri, 23 May 2025 16:07:27 +0200 Subject: [PATCH 113/140] cds9: changes to req.params (#1873) --- node.js/events.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/node.js/events.md b/node.js/events.md index 294bf50dd8..14141bfcb5 100644 --- a/node.js/events.md +++ b/node.js/events.md @@ -315,8 +315,7 @@ This is a convenience shortcut to [`msg.target.name`](#target). ### . params {.property} -Provides access to parameters in URL paths as an [*iterable*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol) with the contents matching the positional occurrence of parameters in the url path. In the case of compound parameters, the respective entry is the key value pairs as given in the URL. - +Provides access to parameters in URL paths as an [*iterable*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol) with the contents matching the positional occurrence of parameters in the url path. The respective entry is the key value pair matching the entity definition. For example, the parameters in an HTTP request like that: @@ -328,7 +327,7 @@ The provided parameters can be accessed as follows: ```js const [ author, book ] = req.params -// > author === 101 +// > author === { ID: 101 } // > book === { title: 'Eleonora', edition: 2 } ``` From f5408ce0d0288f98a25febaad43aa4fd8ab4a490 Mon Sep 17 00:00:00 2001 From: jeevitha011 <118245189+jeevitha011@users.noreply.github.com> Date: Mon, 26 May 2025 18:17:04 +0530 Subject: [PATCH 114/140] asyncAPI compile guide update (#1840) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky --- advanced/publishing-apis/asyncapi.md | 41 +++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/advanced/publishing-apis/asyncapi.md b/advanced/publishing-apis/asyncapi.md index 68a2360831..5dd28cce7c 100644 --- a/advanced/publishing-apis/asyncapi.md +++ b/advanced/publishing-apis/asyncapi.md @@ -110,6 +110,39 @@ service CatalogService { } ``` +## Extensions { #extensions} + +`@AsyncAPI.Extensions` can be used to provide arbitrary extensions. +If a specific annotation exists for a given extension, it takes precedence over the definition using @AsyncAPI.Extensions. +For example, if both `@AsyncAPI.ShortText` and `@AsyncAPI.Extensions: { ![sap-shortText]: 'baz' }` are provided, the value from `@AsyncAPI.ShortText` will override the one defined in @AsyncAPI.Extensions. + +For example: + +```cds +@AsyncAPI.Extensions : { + ![foo-bar] : 'baz', + ![sap-shortText] : 'Service Base 1' +} + +service CatalogService { + @AsyncAPI.Extensions : { + ![sap-event-source] : '/{region}/sap.app.test' + } + event SampleEntity.Changed.v1 : projection on CatalogService.SampleEntity; +} +``` + +The `@AsyncAPI.Extensions` annotation can be applied at both the service level and the event level. + +Since the AsyncAPI specification requires all extensions to be prefixed with `x-`, the compiler will automatically add this prefix. Therefore, do not include the `x-` prefix when specifying extensions in `@AsyncAPI.Extensions`. + +### Behavior with `--merged` flag + +When the `--merged` CLI flag is used: + +- Extensions defined via `@AsyncAPI.Extensions` on `services` are **ignored**. +- Extensions defined via `@AsyncAPI.Extensions` on `events` remain effective and are applied as expected. + ## Type Mapping { #mapping} CDS Type to AsyncAPI Mapping @@ -120,15 +153,15 @@ CDS Type to AsyncAPI Mapping | `Boolean` | `{ "type": "boolean" }` | | `Integer` | `{ "type": "integer" }` | | `Integer64` | `{ "type": "string", "format": "int64" }` | -| `Decimal`, `{precision, scale}` | `{ "type": "string", "format": "decimal", "formatPrecision": , "formatScale": }` | -| `Decimal`, without scale | `{ "type": "string", "format": "decimal", "formatPrecision": }` | +| `Decimal`, `{precision, scale}` | `{ "type": "string", "format": "decimal", "x-sap-precision": , "x-sap-scale": }` | +| `Decimal`, without scale | `{ "type": "string", "format": "decimal", "x-sap-precision": }` | | `Decimal`, without precision and scale | `{ "type": "string", "format": "decimal" }` | | `Double` | `{ "type": "number" }` | | `Date` | `{ "type": "string", "format": "date" }` | | `Time` | `{ "type": "string", "format": "partial-time" }` | | `DateTime` | `{ "type": "string", "format": "date-time" }` | | `Timestamp` | `{ "type": "string", "format": "date-time" }` | -| `String` | `{ "type": "string", "maxLength": length }` | -| `Binary` | `{ "type": "string", "maxLength": length }` | +| `String`, `{maxLength}` | `{ "type": "string", "maxLength": length }` | +| `Binary`, `{maxLength}` | `{ "type": "string", "maxLength": length }` | | `LargeBinary` | `{ "type": "string" }` | | `LargeString` | `{ "type": "string" }` | From b6175654da1eb1318fe8c753b9f1ba15a68140ca Mon Sep 17 00:00:00 2001 From: Markus Ofterdinger Date: Tue, 27 May 2025 09:54:34 +0200 Subject: [PATCH 115/140] CAP Java: Migration Guide 3 to 4 (#1824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BLI: https://github.wdf.sap.corp/cds-java/home/issues/2111 --------- Co-authored-by: Marc Becker Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: RenΓ© Jeglinsky --- guides/security/authorization.md | 7 -- java/cqn-services/persistence-services.md | 2 +- java/event-handlers/indicating-errors.md | 3 +- java/migration.md | 99 +++++++++++++++++++++++ java/outbox.md | 8 +- java/security.md | 73 ++++++++++++++++- 6 files changed, 174 insertions(+), 18 deletions(-) diff --git a/guides/security/authorization.md b/guides/security/authorization.md index 46633bd172..fc5c35db17 100644 --- a/guides/security/authorization.md +++ b/guides/security/authorization.md @@ -516,13 +516,6 @@ Supported features are: * Value references to constants, [user attributes](#user-attrs), and entity data (elements including [paths](#association-paths)) * [Exists predicate](#exists-predicate) based on subselects. - -
- -CAP Java offers the option to enable rejection conditions for `UPDATE`, `DELETE` and custom events. Enable it using the configuration option cds.security.authorization.instance-based.reject-selected-unauthorized-entity.enabled: true. - -
- ::: info Avoid enumerable keys In case the filter condition is not met in an `UPDATE` or `DELETE` request, the runtime rejects the request (response code 403) even if the user is not even allowed to read the entity. To avoid to disclosure the existence of such entities to unauthorized users, make sure that the key is not efficiently enumerable. ::: diff --git a/java/cqn-services/persistence-services.md b/java/cqn-services/persistence-services.md index 6e8f4ba979..ec2c0250f6 100644 --- a/java/cqn-services/persistence-services.md +++ b/java/cqn-services/persistence-services.md @@ -141,7 +141,7 @@ Advise the CDS Compiler to generate _tables without associations_, as associatio #### SQL Optimization Mode -By default, the SAP HANA adapter in CAP Java generates SQL that is optimized for the new [HEX engine](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-performance-guide-for-developers/query-execution-engine-overview) in SAP HANA Cloud. To generate SQL that is compatible with SAP HANA 2.x ([HANA Service](https://help.sap.com/docs/HANA_SERVICE_CF/6a504812672d48ba865f4f4b268a881e/08c6e596b53843ad97ae68c2d2c237bc.html)) and [SAP HANA Cloud](https://www.sap.com/products/technology-platform/hana.html), set the [CDS property](../developing-applications/properties#cds-properties): +By default, the SAP HANA adapter in CAP Java generates SQL that is optimized for the new [HEX engine](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-performance-guide-for-developers/query-execution-engine-overview) in SAP HANA Cloud. To generate SQL that is compatible with SAP HANA 2.x ([HANA Service](https://help.sap.com/docs/HANA_SERVICE_CF/6a504812672d48ba865f4f4b268a881e/08c6e596b53843ad97ae68c2d2c237bc.html)) and [SAP HANA Cloud](https://www.sap.com/products/technology-platform/hana.html), set the (deprecated) [CDS property](../developing-applications/properties#cds-properties): ```yaml cds.sql.hana.optimizationMode: legacy diff --git a/java/event-handlers/indicating-errors.md b/java/event-handlers/indicating-errors.md index d9980a3567..9d3ed726fc 100644 --- a/java/event-handlers/indicating-errors.md +++ b/java/event-handlers/indicating-errors.md @@ -84,6 +84,7 @@ The OData adapter turns this exception into an OData error response to indicate `Messages.throwIfError()` is automatically called at the end of the `Before` handler phase to abort the event processing in case of errors. It is recommended to use the Messages API for validation errors and rely on the framework calling `Messages.throwIfError()` automatically, instead of throwing a `ServiceException`. + ## Formatting and Localization Texts passed to both `ServiceException` and the `Messages` API can be formatted and localized. @@ -126,7 +127,7 @@ throw new ServiceException(ErrorStatuses.BAD_REQUEST, "my.message.key", paramNum CAP Java provides out-of-the-box translation for error messages that originate from input validation annotations such as `@assert...` or `@mandatory` and security annotations `@requires` and `@restrict`. The error messages are optimized for UI scenarios and avoid any technical references to entity names or element names. Message targets are used where appropriate to allow the UI to show the error message next to the affected UI element. -You can enable these translated error messages by setting [cds.errors.defaultTranslations.enabled: true](../developing-applications/properties#cds-errors-defaultTranslations-enabled). +You can disable these translated error messages by setting [cds.errors.defaultTranslations.enabled: false](../developing-applications/properties#cds-errors-defaultTranslations-enabled). ### Provide custom error messages diff --git a/java/migration.md b/java/migration.md index 055036d203..16431d2d56 100644 --- a/java/migration.md +++ b/java/migration.md @@ -23,6 +23,105 @@ uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/ [[toc]] +## CAP Java 3.10 to CAP Java 4.0 { #three-to-four } + +### New License + +The license of CAP Java 4.0 has changed and it's released under the new [SAP Developer License Agreement for CAP](https://cap.cloud.sap/resources/license/developer-license-3_2_CAP.txt). + +### Minimum Versions + +CAP Java 4.0 increased some minimum required versions: + +| Dependency | Minimum Version | +| --- | --- | +| @sap/cds-dk | ^8 | + +CAP Java 4.0 no longer supports @sap/cds-dk ^7. + +### Removed feature `cds-feature-event-hub` + +The feature `cds-feature-event-hub` has been removed from CAP Java. The successor of this feature is the [CDS Plugin for SAP Cloud Application Event Hub](https://github.com/cap-java/cds-feature-event-hub). This new CAP Java Plugin is published independently of CAP Java and is open source. It however has the same Maven group ID and artifact ID as the previous CAP Java feature and starts versioning with `4.0.0`. + +### Changes in goal `generate` of the `cds-maven-plugin` + +1. Removed already deprecated properties: +- sharedInterfaces +- uniqueEventContexts + +2. Deprecated properties and marked for removal: +- eventContext +- cqnService + +3. Changed default value of properties: +- excludes: "localized.**" -> null + +### Removed unstructured messages from MessagingService { #removed-unstructured } + +The deprecated `cds.messaging.services..structured` property, which allowed to handle messages as (unstructured) plain strings has now been completely removed. +Messaging services always represent data in a structured way by using a `Map`. Headers are represented in a separate `Map`. + +With this change the following deprecated methods have been removed: +- `void MessagingService.emit(String, String)` +- `String TopicMessageEventContext.getData()` + +When publishing a unstructured String-based message, wrap the message into a Map: + +```java +// instead of +messagingService.emit("myTopic", "unstructured message"); +// use +messagingService.emit("myTopic", Map.of("message", "unstructured message")); // [!code focus] +``` + +In case you receive a unstructured String-based message from a message broker, it is also wrapped into a structured message with a `message` property: + +```java +@On(event = "myTopic") +void handleMyTopic(TopicMessageEventContext context) { + // instead of + String message = context.getData(); + // use + String message = (String) context.getDataMap().get("message"); // [!code focus] +} +``` + +This change has no effect on CDS modelled events, as these have always been structured. + +### Adjusted Property Defaults + +Some property defaults have been adjusted: + +| Property | Old Value | New Value | Explanation | +| --- | --- | --- | --- | +| `cds.security.authorization.deep.enabled` | false | true | [Deep Authorization](./security#deep-auth) is now enabled by default. | +| `cds.security.authorization.instanceBased.rejectSelectedUnauthorizedEntity.enabled` | false | true | Requests that violate instance-based authorization conditions now fail with 403, instead of 404. | +| `cds.security.authorization.instanceBased.checkInputData.enabled` | false | true | [Authorization Checks On Input Data](./security#input-data-auth) are now enabled by default. | +| `cds.errors.defaultTranslations.enabled` | false | true | [Translations for Validation Error Messages](./event-handlers/indicating-errors#ootb-translated-messages) are now enabled by default. | + +### Deprecated Properties + +The following properties have been deprecated and might be removed in a future major version: + +- `cds.errors.combined` +- `cds.sql.hana.optimizationMode` +- `cds.outbox.services..storeLastError.enabled` + +The functionality provided by these properties is enabled by default and there is no reason to switch these off. + +### Removed Properties + +The following table gives an overview about the removed properties: + +| Removed Property | Replacement / Explanation | +| --- | --- | +| `cds.messaging.services.`
`.structured` | [Use structured messages.](#removed-unstructured) | +| `cds.security.authorization.`
`emptyAttributeValuesAreRestricted` | [Use conditions with explicit checks for empty attributes.](../guides/security/authorization#user-attrs) | +| `cds.odataV4.serializer.buffered` | OData V4 responses are now always streamed while serialized. | +| `cds.environment.k8s` | Use service bindings from SAP BTP Operator on Kyma. | +| `cds.multiTenancy.subscriptionManager.`
`clientCertificateHeader` | `cds.security.authentication.`
`clientCertificateHeader` | +| `cds.multiTenancy.security.`
`internalUserAccess.enabled` | `cds.security.authentication.`
`internalUserAccess.enabled` | + ## CAP Java 2.10 to CAP Java 3.0 { #two-to-three } ### Minimum Versions diff --git a/java/outbox.md b/java/outbox.md index b2f16b1e08..7a400f9830 100644 --- a/java/outbox.md +++ b/java/outbox.md @@ -70,20 +70,18 @@ cds: services: DefaultOutboxOrdered: maxAttempts: 10 - storeLastError: true # ordered: true DefaultOutboxUnordered: maxAttempts: 10 - storeLastError: true # ordered: false ``` ::: You have the following configuration options: - `maxAttempts` (default `10`): The number of unsuccessful emits until the message is ignored. It still remains in the database table. -- `storeLastError` (default `true`): If this flag is enabled, the last error that occurred, when trying to emit the message - of an entry, is stored. The error is stored in the element `lastError` of the entity `cds.outbox.Messages`. - `ordered` (default `true`): If this flag is enabled, the outbox instance processes the entries in the order they have been submitted to it. Otherwise, the outbox may process entries randomly and in parallel, by leveraging outbox processors running in multiple application instances. This option can't be changed for the default persistent outboxes. +The persistent outbox stores the last error that occurred, when trying to emit the message of an entry. The error is stored in the element `lastError` of the entity `cds.outbox.Messages`. + ### Configuring Custom Outboxes { #custom-outboxes} Custom persistent outboxes can be configured using the `cds.outbox.services` section, for example in the _application.yaml_: @@ -94,10 +92,8 @@ cds: services: MyCustomOutbox: maxAttempts: 5 - storeLastError: false MyOtherCustomOutbox: maxAttempts: 10 - storeLastError: true ``` ::: Afterward you can access the outbox instances from the service catalog: diff --git a/java/security.md b/java/security.md index d01107116c..91c7f41e6d 100644 --- a/java/security.md +++ b/java/security.md @@ -65,9 +65,9 @@ Choose an appropriate XSUAA service plan to fit the requirements. For instance, #### Proof-Of-Possession for IAS { #proof-of-possession} -Proof-Of-Possession is a technique for additional security where a JWT token is **bound** to a particular OAuth client for which the token was issued. On BTP, Proof-Of-Possession is supported by IAS and can be used by a CAP Java application. +Proof-Of-Possession is a technique for additional security where a JWT token is **bound** to a particular OAuth client for which the token was issued. On BTP, Proof-Of-Possession is supported by IAS and can be used by a CAP Java application. -Typically, a caller of a CAP application provides a JWT token issued by IAS to authenticate a request. With Proof-Of-Possession in place, a mutual TLS (mTLS) tunnel is established between the caller and your CAP application in addition to the JWT token. Clients calling your CAP application need to send the certificate provided by their `identity` service instance in addition to the IAS token. +Typically, a caller of a CAP application provides a JWT token issued by IAS to authenticate a request. With Proof-Of-Possession in place, a mutual TLS (mTLS) tunnel is established between the caller and your CAP application in addition to the JWT token. Clients calling your CAP application need to send the certificate provided by their `identity` service instance in addition to the IAS token. On Cloud Foundry, the CAP application needs to be exposed under an additional route which accepts client certificates and forwards them to the application as `X-Forwarded-Client-Cert` header (for example, the `.cert.cfapps.` domain). @@ -361,7 +361,74 @@ More specific access control is provided by the `@restrict` annotation, which al Whereas role-based authorization applies to whole entities only, [Instance-Based Authorization](../guides/security/authorization#instance-based-auth) allows to add more specific conditions that apply on entity instance level and depend on the attributes that are assigned to the request user. A typical use case is to narrow down the set of visible entity instances depending on user properties (for example, `CountryCode` or `Department`). Instance-based authorization is also basis for [domain-driven authorizations](../guides/security/authorization#domain-driven-authorization) built on more complex model constraints. - +#### Deep Authorization { #deep-auth} + +Queries to Application Services are not only authorized by the target entity which has a `@restrict` or `@requires` annotation, but also for all __associated entities__ that are used in the statement. __Compositions__ are neither checked nor extended with additional filters. + +For instance, consider the following model: + +```cds +@(restrict: [{ grant: 'READ', to: 'Manager' }]) +entity Books {...} + +@(restrict: [{ grant: 'READ', to: 'Manager' }]) +entity Orders { + key ID: String; + items: Composition of many { + key book: Association to Books; + quantity: Integer; + } +} +``` + +For the following OData request `GET Orders(ID='1')/items?$expand=book`, authorizations for `Orders` and for `Books` are checked. +If the entity `Books` has a `where` clause for [instance-based authorization](/java/security#instance-based-auth), +it will be added as a filter to the sub-request with the expand. + +Custom CQL statements submitted to the [Application Service](/java/cqn-services/application-services) instances +are also authorized by the same rules including the path expressions and subqueries used in them. + +For example, the following statement checks role-based authorizations for both `Orders` and `Books`, +because the association to `Books` is used in the select list. + +```java +Select.from(Orders_.class, + f -> f.filter(o -> o.ID().eq("1")).items()) + .columns(c -> c.book().title()); +``` + +For modification statements with associated entities used in infix filters or where clauses, +role-based authorizations are checked as well. Associated entities require `READ` authorization, in contrast to the target of the statement itself. + +The following statement requires `UPDATE` authorization on `Orders` and `READ` authorization on `Books` +because an association from `Orders.items` to the book is used in the where condition. + +```java +Update.entity(Orders_.class, f -> f.filter(o -> o.ID().eq("1")).items()) + .data("quantity", 2) + .where(t -> t.book().ID().eq(1)); +``` +:::tip Modification of Statements +Be careful when you modify or extend the statements in custom handlers. +Make sure you keep the filters for authorization. +::: + +Deep authorizations are on by default and can be disabled by setting `cds.security.authorization.deep.enabled: false`. + +#### Authorization Checks On Input Data { #input-data-auth } + +Input data of `CREATE` and `UPDATE` events is also validated with regards to instance-based authorization conditions. +Invalid input that does not meet the condition is rejected with response code `400`. + +Let's assume an entity `Orders` which restricts access to users classified by assigned accounting areas: + +```cds +annotate Orders with @(restrict: [ + { grant: '*', where: 'accountingArea = $user.accountingAreas' } ]); +``` + +A user with accounting areas `[Development, Research]` is not able to send an `UPDATE` request, that changes `accountingArea` from `Research` or `Development` to `CarFleet`, for example. +Note that the `UPDATE` on instances _not matching the request user's accounting areas_ (for example, `CarFleet`) are rejected by standard instance-based authorization checks. #### Current Limitations From ea26065882c2ad20c027e68467277b60571b8e7a Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Tue, 27 May 2025 15:43:01 +0200 Subject: [PATCH 116/140] Fix: wide table rows go over outline Also use color constant for table rows. --- .vitepress/theme/styles.scss | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.vitepress/theme/styles.scss b/.vitepress/theme/styles.scss index 757e9db260..64d5365ab9 100644 --- a/.vitepress/theme/styles.scss +++ b/.vitepress/theme/styles.scss @@ -144,9 +144,7 @@ main { table { tr, th, td { - // &:nth-child(2n) { - background-color: transparent !important; - // } + background-color: var(--vp-c-bg); } td, th { border-color: #bbb; .dark & { border-color: #555 }; @@ -520,11 +518,6 @@ a.learn-more, p.learn-more, .learn-more { .VPBadge { white-space: nowrap; } -/* remove transparency in the odd rows (when it scrolls over outline) */ -tr:nth-child(odd) { - background-color: var(--vp-c-bg); -} - html.java { & .node { display: none; @@ -550,6 +543,10 @@ html.node { table:focus { min-width: fit-content; } + tr { // make wide rows go over outline, not below it + z-index: 1; + position: relative; + } [class*='language-'] pre { overflow: hidden !important; } From 2258d96de1826aaeffbc28d7bd75138f0e698ed2 Mon Sep 17 00:00:00 2001 From: Stefan Henke Date: Wed, 28 May 2025 08:55:52 +0200 Subject: [PATCH 117/140] UCL in Java (#1867) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky --- java/_menu.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/_menu.md b/java/_menu.md index f556f7bc46..04e7b8b858 100644 --- a/java/_menu.md +++ b/java/_menu.md @@ -37,5 +37,7 @@ ## [Optimizing](operating-applications/optimizing) ## [Observability](operating-applications/observability) ## [Developer Dashboard](../../java/operating-applications/dashboard) -# [Building Plugins](building-plugins) +# [Integrating Applications](../../java/integrating-applications/) + ## [Unified Customer Landscape](../../java/integrating-applications/ucl) +# [Building Plugins](../../java/building-plugins) # [Migration Guides](migration) \ No newline at end of file From 87b3dad9d60ce0bda185518c43d6631f826d43f4 Mon Sep 17 00:00:00 2001 From: "Dr. David A. Kunz" Date: Wed, 28 May 2025 09:01:59 +0200 Subject: [PATCH 118/140] cds 9: task queue (#1790) Only for cds 9 --------- Co-authored-by: Christian Georgi Co-authored-by: Rene Jeglinsky Co-authored-by: sjvans <30337871+sjvans@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: D050513 --- guides/deployment/custom-builds.md | 2 +- guides/messaging/task-queues.md | 4 +- node.js/_menu.md | 2 +- node.js/messaging.md | 20 +- node.js/outbox.md | 292 ------------------------ node.js/queue.md | 355 +++++++++++++++++++++++++++++ 6 files changed, 378 insertions(+), 297 deletions(-) delete mode 100644 node.js/outbox.md create mode 100644 node.js/queue.md diff --git a/guides/deployment/custom-builds.md b/guides/deployment/custom-builds.md index 7bbdecd977..0fb76a9dcc 100644 --- a/guides/deployment/custom-builds.md +++ b/guides/deployment/custom-builds.md @@ -22,7 +22,7 @@ The CDS model folders and files used by `cds build` are determined as follows: - Known root folders, by [default](../../get-started/#project-structure) the folders _db/, srv/, app/_, can also be configured by [`folders.db`, `folders.srv`, `folders.app`](../../get-started/#project-structure). - The _src_ folder configured for the individual build task. - If [feature toggles](../extensibility/feature-toggles#enable-feature-toggles) are enabled: subfolders of the folder _fts_. -- CDS Model folders and files defined by the [required services](../../node.js/cds-env#services) of your project. This also includes models used by required built-in CDS services, like [persistent outbox](../../node.js/outbox#persistent-outbox) or [MTX related services](../multitenancy/mtxs#mtx-services-reference). +- CDS Model folders and files defined by the [required services](../../node.js/cds-env#services) of your project. This also includes models used by required built-in CDS services, like [persistent queue](../../node.js/queue#persistent-queue) or [MTX related services](../multitenancy/mtxs#mtx-services-reference). Feature toggle folders and required built-in service models will also be added if user defined models have already been configured as [_model_ option](#build-task-properties) in your build tasks. diff --git a/guides/messaging/task-queues.md b/guides/messaging/task-queues.md index 568bfe9120..49953114bc 100644 --- a/guides/messaging/task-queues.md +++ b/guides/messaging/task-queues.md @@ -26,7 +26,7 @@ This guide will grow with the functionality. Regarding the _outbox_, please see the following existing documentation: - [Transactional Outbox](../../java/outbox) in CAP Java -- [Outboxing with `cds.outboxed`](../../node.js/outbox) in CAP Node.js +- [Outboxing with `cds.queued`](../../node.js/queue) in CAP Node.js @@ -42,7 +42,7 @@ Simply configure your messaging service for Node.js as cds.requires.mess With the inbox, all messages are acknowledged towards the message broker regardless of whether they can be processed or not. Hence, failures need to be managed via the dead letter queue built on `cds.outbox.Messages`. -[Learn more about the dead letter queue in Node.js.](../../node.js/outbox#managing-the-dead-letter-queue){.learn-more} +[Learn more about the dead letter queue in Node.js.](../../node.js/queue#managing-the-dead-letter-queue){.learn-more} [Learn more about the dead letter queue in Java.](../../java/outbox#outbox-dead-letter-queue){.learn-more} Inboxing is especially beneficial in case the message broker does not allow to trigger redelivery and/ or "fix" the message payload. diff --git a/node.js/_menu.md b/node.js/_menu.md index eec9275676..609d8aae34 100644 --- a/node.js/_menu.md +++ b/node.js/_menu.md @@ -57,7 +57,7 @@ # [cds. utils](cds-utils) # [cds. test()](cds-test) # [cds. plugins](cds-plugins) -# [cds. outboxed()](outbox) +# [cds. queued()](queue) # [TypeScript](typescript) # [Fiori Support](fiori) # [Best Practices](best-practices) diff --git a/node.js/messaging.md b/node.js/messaging.md index 5580a8a6e3..8615996f35 100644 --- a/node.js/messaging.md +++ b/node.js/messaging.md @@ -127,7 +127,7 @@ this.after(['CREATE', 'UPDATE', 'DELETE'], 'Reviews', async (_, req) => { ``` ::: tip The messages are sent once the transaction is successful. -Per default, a persistent outbox is used. See [Messaging - Outbox](./outbox) for more information. +Per default, a persistent queue is used. See [Messaging - Queue](./queue) for more information. ::: ## Receiving Events @@ -160,6 +160,24 @@ messaging.on('*', async msg => { /*...*/ }) In general, messages do not contain user information but operate with a technical user. As a consequence, the user of the message processing context (`cds.context.user`) is set to [`cds.User.privileged`](/node.js/authentication#privileged-user) and, hence, any necessary authorization checks must be done in custom handlers. ::: +### Inbox + +You can store received messages in an inbox before they're processed. Under the hood, it uses the [task queue](./queue) for reliable asynchronous processing. +Enable it by setting the `inboxed` option to `true`, for example: + +```js +{ + cds: { + requires: { + messaging: { + kind: 'enterprise-messaging', + inboxed: true + } + } + } +} +``` + ## CloudEvents Protocol [CloudEvents](https://cloudevents.io/) is a commonly used specification for describing event data. diff --git a/node.js/outbox.md b/node.js/outbox.md deleted file mode 100644 index 551370541f..0000000000 --- a/node.js/outbox.md +++ /dev/null @@ -1,292 +0,0 @@ ---- -synopsis: > - Learn details about the outbox feature. -# layout: node-js -status: released ---- - -# Outboxing with `cds.outboxed` - -[[toc]] - - -## Overview - -Often, remote operations should be delayed until the main transaction succeeded. Otherwise, the remote operations are also triggered in case of a rollback. -To enable this, an outbox can be used to defer remote operations until the success of the current transaction. - -Every CAP service can be _outboxed_ that means event dispatching becomes _asynchronous_. - - -## Outboxing a Service - - -### cds.outboxed(srv) {.method} - -Programmatically, you can get the outboxed service as follows: - -```js -const srv = await cds.connect.to('yourService') -const outboxed = cds.outboxed(srv) - -await outboxed.emit('someEvent', { some: 'message' }) // asynchronous -await outboxed.send('someEvent', { some: 'message' }) // synchronous -``` - -::: tip -You still need to `await` these operations. Then the messages are stored in the database, together with the main transaction. -::: - -The `cds.outboxed` function can also be called with optional configuration options. - -```js -const outboxed = cds.outboxed(srv, { kind: 'persistent-outbox' }) -``` - -> The persistent outbox can only be used if it's enabled globally with `cds.requires.outbox = true` because it requires a dedicated database table. - -::: warning One-time configuration -Once you outboxed a service, you cannot override its outbox configuration options again. -::: - - -### cds.unboxed(srv) {.method} - -Use this on an outboxed service to get back the original service: - -```js -const unboxed = cds.unboxed(srv) -``` - -This is useful if your service is outboxed per configuration. - - -### Per Configuration - -You can also configure services to be outboxed by default: - -```json -{ - "requires": { - "yourService": { - "kind": "odata", - "outbox": true - } - } -} -``` - -::: tip Outboxed by default -Some services are outboxed by default, these services include [`cds.MessagingService`](messaging) and `cds.AuditLogService`. -::: - -For transactional safety, you're encouraged to enable the [persistent outbox](#persistent-outbox). - - -## Persistent Outbox (Default) {#persistent-outbox} - -You can enable it globally for all outboxed services with: - -```json -{ - "requires": { - "outbox": true - } -} -``` - -Using the persistent outbox, the to-be-emitted message is stored in a database table first. The same database transaction is used -as for other operations, therefore transactional consistency is guaranteed. - -You can use the following configuration options: - -```json -{ - "requires": { - "outbox": { - "kind": "persistent-outbox", - "maxAttempts": 20, - "chunkSize": 100, - "storeLastError": true, - "parallel": true - } - } -} -``` - -The optional parameters are: - -- `maxAttempts` (default `20`): The number of unsuccessful emits until the message is ignored. It will still remain in the database table. -- `chunkSize` (default `100`): The number of messages which are read from the database table in one go. -- `storeLastError` (default `true`): Specifies if error information of the last failed emit should be stored in the outbox table. -- `parallel` (default `true`): Specifies if messages are sent in parallel (faster but the order isn't guaranteed). - - -Once the transaction succeeds, the messages are read from the database table and emitted. -If an emit was successful, the respective message is deleted from the database table. -If not, there will be retries after (exponentially growing) waiting times. -After a maximum number of attempts, the message is ignored for processing and remains in the database table which -therefore also acts as a dead letter queue. -See [Managing the Dead Letter Queue](#managing-the-dead-letter-queue), to learn about how to handle such messages. - -There is only one active message processor per service, tenant, and app instance. -Hence, there won't be duplicate emits except in the unlikely case of an app crash right after the emit and before the deletion of the message entry. - -::: tip -Some errors during the emit are identified as unrecoverable, for example in [SAP Event Mesh](../guides/messaging/event-mesh) if the used topic is forbidden. -The respective message is then updated and the `attempts` field is set to `maxAttempts` to prevent further processing. -[Programming errors](./best-practices#error-types) crash the server instance and must be fixed. -::: - - -Your database model is automatically extended by the entity `cds.outbox.Messages`: - -```cds -namespace cds.outbox; - -entity Messages { - key ID : UUID; - timestamp : Timestamp; - target : String; - msg : LargeString; - attempts : Integer default 0; - partition : Integer default 0; - lastError : LargeString; - lastAttemptTimestamp : Timestamp @cds.on.update: $now; -} -``` - -In your CDS model, you can refer to the entity `cds.outbox.Messages` using the path `@sap/cds/srv/outbox`, -for example to expose it in a service. - - -#### Known Limitations - -- If the app crashes, another emit for the respective tenant and service is necessary to restart the message processing. -- The service that handles the outboxed event must not use user roles and attributes as they are not stored. However, the user ID is stored to recreate the correct context. -- The service that handles the outboxed event must not perform any database modifications, because a global database transaction is used when dispatching the events. The outbox must only be used for services which communicate with external systems. - - -### Managing the Dead Letter Queue - -You can manage the dead letter queue by implementing a service that exposes a read-only projection on entity `cds.outbox.Messages` as well as bound actions to either revive or delete the respective message. - -::: tip -Please see [Outbox Dead Letter Queue](../java/outbox#outbox-dead-letter-queue) in the CAP Java documentation for additional considerations while we work on a general Outbox guide. -::: - -#### 1. Define the Service - -::: code-group -```cds [srv/outbox-dead-letter-queue-service.cds] -using from '@sap/cds/srv/outbox'; - -@requires: 'internal-user' -service OutboxDeadLetterQueueService { - - @readonly - entity DeadOutboxMessages as projection on cds.outbox.Messages - actions { - action revive(); - action delete(); - }; - -} -``` -::: - -#### 2. Filter for Dead Entries - -As `maxAttempts` is configurable, its value can not be added as a static filter to projection `DeadOutboxMessages`, but must be considered programmatically. - -::: code-group -<<< ./assets/dead-letter-queue-1.js#snippet{5-8} [srv/outbox-dead-letter-queue-service.js] -::: - -#### 3. Implement Bound Actions - -Finally, entries in the dead letter queue can either be _revived_ by resetting the number of attempts (that is, `SET attempts = 0`) or _deleted_. - -::: code-group -<<< ./assets/dead-letter-queue-2.js#snippet{10-12,14-16} [srv/outbox-dead-letter-queue-service.js] -::: - - -## In-Memory Outbox - -You can enable it globally for all outboxed services with: - -```json -{ - "requires": { - "outbox": { - "kind": "in-memory-outbox" - } - } -} -``` -Messages are emitted when the current transaction is successful. Until then, messages are only kept in memory. -This is similar to the following code if done manually: -```js -cds.context.on('succeeded', () => this.emit(msg)) -``` -::: warning No retry mechanism -The message is lost if its emit fails, there is no retry mechanism. -::: - - -## Immediate Emit - -To disable deferred emitting for a particular service, you can set the `outbox` option of your service to `false`: - -```json -{ - "requires": { - "messaging": { - "kind": "enterprise-messaging", - "outbox": false - } - } -} -``` - -## Troubleshooting - -### Delete Entries in the Outbox Table - -To manually delete entries in the table `cds.outbox.Messages`, you can either -expose it in a service, see [Managing the Dead Letter Queue](#managing-the-dead-letter-queue), or programmatically modify it using the `cds.outbox.Messages` -entity: - -```js -const db = await cds.connect.to('db') -const { Messages } = db.entities('cds.outbox') -await DELETE.from(Messages) -``` - -### Outbox Table Not Found - -If the outbox table is not found on the database, this can be caused by insufficient configuration data in _package.json_. - -In case you have overwritten `requires.db.model` there, make sure to add the outbox model path `@sap/cds/srv/outbox`: - -```jsonc -"requires": { - "db": { ... - "model": [..., "@sap/cds/srv/outbox"] - } -} -``` - -The following is only relevant if you're using @sap/cds version < 6.7.0 and you've configured `options.model` in custom build tasks. -Add the model path accordingly: - -```jsonc -"build": { - "tasks": [{ ... - "options": { "model": [..., "@sap/cds/srv/outbox"] } - }] -} -``` - -Note that model configuration isn't required for CAP projects using the [standard project layout](../get-started/#project-structure) that contain the folders `db`, `srv`, and `app`. In this case, you can delete the entire `model` configuration. diff --git a/node.js/queue.md b/node.js/queue.md new file mode 100644 index 0000000000..305ae2c56e --- /dev/null +++ b/node.js/queue.md @@ -0,0 +1,355 @@ +--- +synopsis: > + Learn details about the task queue feature. +status: released +--- + +# Queueing with `cds.queued` + +[[toc]] + + + +## Overview + +The _task queue_ feature allows you to defer event processing. + +A common use case is the outbox pattern, where remote operations are deferred until the main transaction has been successfully committed. +This prevents accidental execution of remote calls in case the transaction is rolled back. + +Every non-database CAP service can be _queued_, meaning that event dispatching becomes _asynchronous_. + +::: tip +The _task queue_ feature can be disabled globally via cds.requires.queue = false. +::: + + +## Queueing a Service + + +### cds. queued (srv) {.method} + +```tsx +function cds.queued ( srv: Service, options? ) => QueuedService +``` + +Programmatically, you can get the queued service as follows: + +```js +const srv = await cds.connect.to('yourService') +const qd_srv = cds.queued(srv) + +await qd_srv.emit('someEvent', { some: 'message' }) // asynchronous +await qd_srv.send('someEvent', { some: 'message' }) // asynchronous +``` + +::: tip `await` needed +You still need to `await` these operations because they're asynchronous. In case of a persistent queue, which is the default, messages are stored in the database, within the current transaction. +::: + +The `cds.queued` function can also be called with optional configuration options. + +```js +const qd_srv = cds.queued(srv, { maxAttempts: 5 }) +``` + +> The persistent queue can only be used if it is not disabled globally via `cds.requires.queue = false`, as it requires a dedicated database table. + +::: warning One-time configuration +Once you queued a service, you cannot override its configuration options again. +::: + +For backwards compatibility, `cds.outboxed(srv)` works as a synonym. + + +### cds. unqueued (srv) {.method} + +```tsx +function cds.unqueued ( srv: QueuedService ) => Service +``` + +Use this on a queued service to get back to the original service: + +```js +const srv = cds.unqueued(qd_srv) +``` + +This is useful if your service is outboxed (that is, queued) per configuration. + +For backwards compatibility, `cds.unboxed(srv)` works as a synonym. + + +### Per Configuration + +Some services are outboxed by default; these include [`cds.MessagingService`](messaging) and `cds.AuditLogService`. +You can configure the outbox behavior by specifying the `outboxed` option in your service configuration. + +```json +{ + "requires": { + "yourService": { + "kind": "odata", + "outboxed": { + "maxAttempts": 5 + } + } + } +} +``` + +For transactional safety, you're encouraged to use the [persistent queue](#persistent-queue), which is enabled by default. + + + +## Persistent Queue (Default) {#persistent-queue} + +The persistent queue is the default configuration. + +Using the persistent queue, the to-be-emitted message is stored in a database table within the current transaction, therefore transactional consistency is guaranteed. + +::: details You can use the following configuration options: + +```json +{ + "requires": { + "queue": { + "kind": "persistent-queue", + "maxAttempts": 20, + "parallel": true, + "chunkSize": 10, + "storeLastError": true, + "legacyLocking": true, + "timeout": "1h" + } + } +} +``` + +The optional parameters are: + +- `maxAttempts` (default `20`): The number of unsuccessful emits until the message is considered unprocessable. The message will remain in the database table! +- `parallel` (default `true`): Specifies if messages are sent in parallel (faster, but the order isn't guaranteed). +- `chunkSize` (default `10`): The number of messages that are read from the database table in one go. Only applies for `parallel !== false`. +- `storeLastError` (default `true`): Specifies whether error information of the last failed emit is stored in the tasks table. +- `legacyLocking` (default `true`): If set to `false`, database locks are only used to set the status of the message to `processing` to prevent long-kept database locks. Although this is the recommended approach, it is incompatible with task runners still on `@sap/cds^8`. +- `timeout` (default `"1h"`): The time after which a message with `status === "processing"` is considered to be abandoned and eligable to be processed again. Only for `legacyLocking === false`. + +::: + +Once the transaction succeeds, the messages are read from the database table and dispatched. +If processing was successful, the respective message is deleted from the database table. +If processing failed, the system retries the message after exponentially increasing delays. +After a maximum number of attempts, the message is ignored for processing and remains in the database, which +therefore also acts as a dead letter queue. +See [Managing the Dead Letter Queue](#managing-the-dead-letter-queue), to learn about how to handle such messages. + +There is only one active message processor per service, tenant, app instance, and message. +This ensures that no duplicate emits happen, except in the highly unlikely case of an app crash right after successful processing but before the message could be deleted. + +::: tip Unrecoverable errors +Some errors during the emit are identified as unrecoverable, for example in [SAP Event Mesh](../guides/messaging/event-mesh) if the used topic is forbidden. +The respective message is then updated and the `attempts` field is set to `maxAttempts` to prevent further processing. +[Programming errors](./best-practices#error-types) crash the server instance and must be fixed. +To mark your own errors as unrecoverable, you can set `unrecoverable = true` on the error object. +::: + + +Your database model is automatically extended by the entity `cds.outbox.Messages`: + +```cds +namespace cds.outbox; + +entity Messages { + key ID : UUID; + timestamp : Timestamp; + target : String; + msg : LargeString; + attempts : Integer default 0; + partition : Integer default 0; + lastError : LargeString; + lastAttemptTimestamp : Timestamp @cds.on.update: $now; + status : String(23); +} +``` + +In your CDS model, you can refer to the entity `cds.outbox.Messages` using the path `@sap/cds/srv/outbox`, for example to expose it in a service (cf. [Managing the Dead Letter Queue](#managing-the-dead-letter-queue)). + + +### Known Limitations + +- If the app crashes, another emit for the respective tenant and service is necessary to restart the message processing. It can be triggered manually using the `flush` method. +- The service that handles the queued event must not rely on user roles and attributes, as they are not stored with the message. In other words, asynchronous task are always processed in a privileged mode. However, the user ID is stored to re-create the correct context. + + +### Managing the Dead Letter Queue + +You can manage the dead letter queue by implementing a service that exposes a read-only projection on entity `cds.outbox.Messages` as well as bound actions to either revive or delete the respective message. + +::: tip +See [Outbox Dead Letter Queue](../java/outbox#outbox-dead-letter-queue) in the CAP Java documentation for additional considerations while we work on a general outbox guide. +::: + +#### 1. Define the Service + +::: code-group +```cds [srv/outbox-dead-letter-queue-service.cds] +using from '@sap/cds/srv/outbox'; + +@requires: 'internal-user' +service OutboxDeadLetterQueueService { + + @readonly + entity DeadOutboxMessages as projection on cds.outbox.Messages + actions { + action revive(); + action delete(); + }; + +} +``` +::: + +#### 2. Filter for Dead Entries + +As `maxAttempts` is configurable, its value cannot be added as a static filter to projection `DeadOutboxMessages`, but must be considered programmatically. + +::: code-group +<<< ./assets/dead-letter-queue-1.js#snippet{5-8} [srv/outbox-dead-letter-queue-service.js] +::: + +#### 3. Implement Bound Actions + +Finally, entries in the dead letter queue can either be _revived_ by resetting the number of attempts (that is, `SET attempts = 0`) or _deleted_. + +::: code-group +<<< ./assets/dead-letter-queue-2.js#snippet{10-12,14-16} [srv/outbox-dead-letter-queue-service.js] +::: + + +### Additional APIs + +You can use the `schedule` method as a shortcut for `cds.queued(srv).send()`, with optional scheduling options `after` and `every`: + +```js +await srv.schedule('someEvent', { some: 'message' }) +await srv.schedule('someEvent', { some: 'message' }).after('1h') // after one hour +await srv.schedule('someEvent', { some: 'message' }).every('1h') // every hour after each processing +``` + + +To manually trigger the message processing, for example if your server is restarted, you can use the `flush` method. + +```js +const srv = await cds.connect.to('yourService') +cds.queued(srv).flush() +``` + +Once a message has been successfully processed, it triggers the `/#succeeded` handlers. + +```js +srv.after('someEvent/#succeeded', (data, req) => { + // `data` is the result of the event processor + console.log('Message successfully processed:', data) +}) +``` + +Similarly, you can use the `/#failed` event to handle failed messages (once the maximum retry count is reached). + +```js +srv.after('someEvent/#failed', (data, req) => { + // `data` is the error from the event processor + console.log('Message could not be processed:', data) +}) +``` + +::: tip Register on specific events +Event handlers have to be registered for these specific events. The `*` wildcard handler is not called for these. +::: + + + +## In-Memory Queue + +You can enable the in-memory queue globally with: + +```json +{ + "requires": { + "queue": { + "kind": "in-memory-queue" + } + } +} +``` + +Messages are emitted only after the current transaction is successfully committed. Until then, messages are only kept in memory. +This is similar to the following code if done manually: + +```js +cds.context.on('succeeded', () => this.emit(msg)) +``` + +::: warning No retry mechanism +The message is lost if the emit fails. There's no retry mechanism. +::: + + + +## Immediate Emit + +To disable deferred emitting for a particular service only, you can set the `outboxed` option of that service to `false`: + +```json +{ + "requires": { + "messaging": { + "kind": "enterprise-messaging", + "outboxed": false + } + } +} +``` + + + +## Troubleshooting + + +### Delete Entries in the Messages Table + +To manually delete entries in the table `cds.outbox.Messages`, you can either +expose it in a service, see [Managing the Dead Letter Queue](#managing-the-dead-letter-queue), or programmatically modify it using the `cds.outbox.Messages` +entity: + +```js +const db = await cds.connect.to('db') +await DELETE.from('cds.outbox.Messages') +``` + + +### Messages Table Not Found + +If the messages table is not found on the database, this can be caused by insufficient configuration data in _package.json_. + +In case you have overwritten `requires.db.model` there, make sure to add the outbox model path `@sap/cds/srv/outbox`: + +```jsonc +"requires": { + "db": { ... + "model": [..., "@sap/cds/srv/outbox"] + } +} +``` + +The following is only relevant if you're using @sap/cds version < 6.7.0 and you've configured `options.model` in custom build tasks. +Add the model path accordingly: + +```jsonc +"build": { + "tasks": [{ ... + "options": { "model": [..., "@sap/cds/srv/outbox"] } + }] +} +``` + +Note that model configuration isn't required for CAP projects using the [standard project layout](../get-started/#project-structure) with `db`, `srv`, and `app` folders. In this case, you can delete the entire `model` configuration. From 0768e93b84b309654bc8ca613f1273f69ffb61a7 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Wed, 28 May 2025 09:08:42 +0200 Subject: [PATCH 119/140] cds.log(): add hint re header masking (#1830) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky --- node.js/cds-log.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node.js/cds-log.md b/node.js/cds-log.md index b87bbcd38a..dfea244261 100644 --- a/node.js/cds-log.md +++ b/node.js/cds-log.md @@ -413,6 +413,11 @@ Some header values shall not appear in logs, for example when pertaining to auth In case your application shares any sensitive data (for example, secrets) via headers, please ensure that you adjust the configuration as necessary. ::: +::: tip +In the log entry, header field names are normalized to lowercase with `_` instead of `-`. +Make sure your matchers work on the original header name, for example, `"/Foo-Bar/"` instead of the normalized `"/foo_bar/"`. +::: + ### Custom Fields { #custom-fields } From a83e9ee0cc042b98f4e6685debc7d70dd95b7507 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Wed, 28 May 2025 09:09:59 +0200 Subject: [PATCH 120/140] feat: ias token validation (#1862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> Co-authored-by: RenΓ© Jeglinsky --- node.js/authentication.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/node.js/authentication.md b/node.js/authentication.md index 8d76c59113..2a1675605e 100644 --- a/node.js/authentication.md +++ b/node.js/authentication.md @@ -369,6 +369,28 @@ npm add @sap/xssec ``` ::: +#### Token Validation + +For tokens issued by SAP Cloud Identity Service, `@sap/xssec` offers two additional validations: (1) token ownership via x5t thumbprint and (2) proof-of-possession. +These validations are enabled by default for requests to the app's `cert` route (`.cert` segment in the domain). + +The default behavior can be overwritten using additional configuration as follows: + +```json +"requires": { + "auth": { + "kind": "ias", + "config": { // passed to @sap/xssec as is + "validation": { + "x5t": { "enabled": false }, + "proofToken": { "enabled": false } + } + } + } +} +``` + +Please see [`@sap/xssec` documentation](https://www.npmjs.com/package/@sap/xssec) for more details. ### Custom Authentication { #custom } From e64c4935ac5b7f11ee73c9e09c3a8fefdffc9819 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 09:26:03 +0200 Subject: [PATCH 121/140] chore: Update CLI texts (#1882) Updates the output of cds CLI texts to the latest version. Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com> --- tools/assets/help/cds-version-md.out.md | 4 ++-- tools/assets/help/cds-version.out.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index 233a355c64..7f707e5ac0 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -6,11 +6,11 @@ | ---------------------- | --------------------------------------- | | @cap-js/asyncapi | 1.0.3 | | @cap-js/cds-types | 0.10.0 | -| @cap-js/db-service | 1.20.0 | +| @cap-js/db-service | 1.20.1 | | @cap-js/openapi | 1.2.2 | | @cap-js/sqlite | 1.11.0 | | @sap/cds | 8.9.4 | -| @sap/cds-compiler | 5.9.2 | +| @sap/cds-compiler | 5.9.4 | | @sap/cds-dk (global) | 8.9.4 | | @sap/cds-fiori | 1.4.1 | | @sap/cds-foss | 5.0.1 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 6d8efaa2e4..627791499e 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -4,11 +4,11 @@ @cap-js/asyncapi: 1.0.3 @cap-js/cds-types: 0.10.0 -@cap-js/db-service: 1.20.0 +@cap-js/db-service: 1.20.1 @cap-js/openapi: 1.2.2 @cap-js/sqlite: 1.11.0 @sap/cds: 8.9.4 -@sap/cds-compiler: 5.9.2 +@sap/cds-compiler: 5.9.4 @sap/cds-dk (global): 8.9.4 @sap/cds-fiori: 1.4.1 @sap/cds-foss: 5.0.1 From 2856e87bb2449c84dee9dc1a91b4a90b91802adb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 08:57:24 +0000 Subject: [PATCH 122/140] chore(deps): update dependency @cap-js/cds-typer to v0.35.0 (#1872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@cap-js/cds-typer](https://cap.cloud.sap/) ([source](https://redirect.github.com/cap-js/cds-typer)) | [`0.34.0` -> `0.35.0`](https://renovatebot.com/diffs/npm/@cap-js%2fcds-typer/0.34.0/0.35.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@cap-js%2fcds-typer/0.35.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@cap-js%2fcds-typer/0.35.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@cap-js%2fcds-typer/0.34.0/0.35.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@cap-js%2fcds-typer/0.34.0/0.35.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
cap-js/cds-typer (@​cap-js/cds-typer) ### [`v0.35.0`](https://redirect.github.com/cap-js/cds-typer/blob/HEAD/CHANGELOG.md#0350---2025-05-23) [Compare Source](https://redirect.github.com/cap-js/cds-typer/compare/v0.34.0...v0.35.0) ##### Added ##### Changed - action parameters annotated with `@mandatory` are no longer nullable - base definitions now properly import the default export of `@sap/cds` ##### Deprecated ##### Removed ##### Fixed - Using `cds.Map` as type will no longer result in the property not being printed at all. ##### Security
--- ### Configuration πŸ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/cap-js/docs). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Christian Georgi --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 96ecea0f6d..0c1ac58f31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -272,9 +272,9 @@ } }, "node_modules/@cap-js/cds-typer": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/@cap-js/cds-typer/-/cds-typer-0.34.0.tgz", - "integrity": "sha512-ElVS1ZhFU+hRDC6TJWA1jSkqn+e4QHx4MhnSTo5QWBBJmbr4ZtNW3CcbYdOlnIErt9GRlHjaNMipjAFdb0JxTA==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@cap-js/cds-typer/-/cds-typer-0.35.0.tgz", + "integrity": "sha512-Atzxt763wEdiSlNLGIil9fU9xFrnJJQ+dQFSbQSiXV/IFJWN5wvZ1IlQjI5KxunDLSzCkITsuBY38dHKzakp6g==", "dev": true, "license": "Apache-2.0", "bin": { From e2e48d3bc974c928037bdf63253608249a19aab2 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Wed, 28 May 2025 13:27:49 +0200 Subject: [PATCH 123/140] SAP Integration Suite, Advanced Event Mesh (#1871) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RenΓ© Jeglinsky --- java/messaging.md | 21 +++++++++++++++++++++ menu.md | 1 + node.js/messaging.md | 10 ++++++++++ plugins/index.md | 6 ++++-- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/java/messaging.md b/java/messaging.md index 1f0d73170a..ff064a2dd0 100644 --- a/java/messaging.md +++ b/java/messaging.md @@ -305,6 +305,27 @@ cds: Support for SAP Cloud Application Event Hub is provided via [plugin](../plugins/#event-hub). +#### Configuring SAP Integration Suite, Advanced Event Mesh Support : +{ #configuring-advanced-event-mesh-support} + +::: code-group +```xml [srv/pom.xml] + + com.sap.cds + cds-feature-advanced-event-mesh + ${version} + +``` +```yaml [srv/src/main/resources/application.yaml] +cds: + messaging.services: + - name: "messaging-name" + kind: "aem" +``` +::: + +[Support for SAP Integration Suite, advanced event mesh is provided via plugin.](../plugins/#advanced-event-mesh){.learn-more} + #### Configuring Redis PubSub Support : { #configuring-redis-pubsub-support-beta} diff --git a/menu.md b/menu.md index 6a7a97b7ff..716409ff24 100644 --- a/menu.md +++ b/menu.md @@ -166,3 +166,4 @@ ## [Open Resource Discovery](plugins/#ord-open-resource-discovery) ## [CAP Operator for K8s](plugins/#cap-operator-plugin) ## [SAP Cloud Appl. Event Hub](plugins/#event-hub) +## [Advanced Event Mesh](plugins/#advanced-event-mesh) diff --git a/node.js/messaging.md b/node.js/messaging.md index 8615996f35..28662bef4b 100644 --- a/node.js/messaging.md +++ b/node.js/messaging.md @@ -428,6 +428,16 @@ Use this if you want to communicate using [SAP Cloud Application Event Hub](http The integration with SAP Cloud Application Event Hub is provided using the plugin [`@cap-js/event-broker`](https://github.com/cap-js/event-broker). Please see the plugin's [setup guide](https://github.com/cap-js/event-broker/blob/main/README.md#setup) for more details. +### SAP Integration Suite, Advanced Event Mesh +{ #advanced-event-mesh } + +`kind`: `advanced-event-mesh` + +Use this if you want to communicate using [SAP Integration Suite, advanced event mesh](https://help.sap.com/docs/event-broker). + +The integration with SAP Integration Suite, advanced event mesh is provided using the plugin [`@cap-js/advanced-event-mesh`](https://github.com/cap-js/advanced-event-mesh). +Please see the plugin's [setup guide](https://github.com/cap-js/advanced-event-mesh/blob/main/README.md#setup) for more details. +
diff --git a/plugins/index.md b/plugins/index.md index ea84b18093..d704af8d72 100644 --- a/plugins/index.md +++ b/plugins/index.md @@ -389,16 +389,18 @@ Available for: [![Node.js logo](../assets/logos/nodejs.svg){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/event-broker#readme) [![Java logo](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/cap-java/cds-feature-event-hub#readme) + +## SAP Integration Suite, Advanced Event Mesh {#advanced-event-mesh} -## SAP Integration Suite, advanced event mesh -[SAP Integration Suite, advanced event mesh](https://www.sap.com/germany/products/technology-platform/integration-suite/advanced-event-mesh.html) allows you to, amongst others, integrate non-SAP systems into your event-driven architecture. +[SAP Integration Suite, advanced event mesh](https://www.sap.com/products/technology-platform/integration-suite/advanced-event-mesh.html) allows you to, amongst others, integrate non-SAP systems into your event-driven architecture. Available for: [![Node.js logo](../assets/logos/nodejs.svg){style="height:2.5em; display:inline; margin:0 0.2em;"}](https://github.com/cap-js/advanced-event-mesh#readme) [![Java logo](../assets/logos/java.svg){style="height:3em; display:inline; margin:0 0.2em;"}](https://github.com/cap-java/cds-feature-advanced-event-mesh#readme) + ## ABAP RFC The `@sap/cds-rfc` plugin allows to import the API of RFC-enabled function modules from From 2a914132279160cf93c64fba8abe4c5747e8eb46 Mon Sep 17 00:00:00 2001 From: BraunMatthias <59841349+BraunMatthias@users.noreply.github.com> Date: Wed, 28 May 2025 13:28:39 +0200 Subject: [PATCH 124/140] Update java security (preparing major release) (#1877) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: matthia.braun@sap.com Co-authored-by: RenΓ© Jeglinsky --- advanced/odata.md | 2 +- java/security.md | 63 +++++++++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/advanced/odata.md b/advanced/odata.md index abadb6d13c..3e033140f5 100644 --- a/advanced/odata.md +++ b/advanced/odata.md @@ -104,7 +104,7 @@ Content-Type: application/json PATCH requests with delta payload are executed using batch delete and [upsert](../java/working-with-cql/query-api#bulk-upsert) statements, and are more efficient than OData [batch requests](https://docs.oasis-open.org/odata/odata/v4.01/csprd02/part1-protocol/odata-v4.01-csprd02-part1-protocol.html#sec_BatchRequests). -Use PATCH on entity collections for uploading mass data using a dedicated service, which is secured using [role-based authorization](../java/security#role-based-auth). Delta updates must be explicitly enabled by annotating the entity with +Use PATCH on entity collections for uploading mass data using a dedicated service, which is secured using [role-based authorization](../guides/security/authorization#requires). Delta updates must be explicitly enabled by annotating the entity with ```cds @Capabilities.UpdateRestrictions.DeltaUpdateSupported diff --git a/java/security.md b/java/security.md index 91c7f41e6d..93bf887709 100644 --- a/java/security.md +++ b/java/security.md @@ -106,11 +106,10 @@ service BooksService @(requires: 'any') { | `/BooksService` | | | `/BooksService/$metadata` | | | `/BooksService/Books` | | -| `/BooksService/Reviews` | 1 | +| `/BooksService/Reviews` | | | `/BooksService/Orders` | | -> 1 Since version 1.25.0 ::: tip For multitenant applications, it's required to authenticate all endpoints as the tenant information is essential for processing the request. ::: @@ -345,26 +344,19 @@ The mock user `Alice` is assigned to the mock tenant `CrazyCars` for which the f CAP Java SDK provides a comprehensive authorization service. By defining authorization rules declaratively via annotations in your CDS model, the runtime enforces authorization of the requests in a generic manner. Two different levels of authorization can be distinguished: -- [Role-based authorization](#role-based-auth) allows to restrict resource access depending on user roles. -- [Instance-based authorization](#instance-based-auth) allows to define user privileges even on entity instance level, that is, a user can be restricted to instances that fulfill a certain condition. +- [Role-based authorization](../guides/security/authorization#requires) allows to restrict resource access depending on user roles. +- [Instance-based authorization](../guides/security/authorization#instance-based-auth) allows to define user privileges even on entity instance level, that is, a user can be restricted to instances that fulfill a certain condition. It's recommended to configure authorization declaratively in the CDS model. If necessary, custom implementations can be built on the [Authorization API](#enforcement-api). A precise description of the general authorization capabilities in CAP can be found in the [Authorization](../guides/security/authorization) guide. -### Role-Based Authorization { #role-based-auth} - -Use CDS annotation `@requires` to specify in the CDS model which role a user requires to access the annotated CDS resources such as services, entities, actions, and functions (see [Restricting Roles with @requires](../guides/security/authorization#requires)). The generic authorization handler of the runtime rejects all requests with response code 403 that don't match the accepted roles. -More specific access control is provided by the `@restrict` annotation, which allows to combine roles with the allowed set of events. For instance, this helps to distinguish between users that may only read an entity from those who are allowed to edit. See section [Control Access with @restrict](../guides/security/authorization#restrict-annotation) to find details about the possibilities. - -### Instance-Based Authorization { #instance-based-auth} - -Whereas role-based authorization applies to whole entities only, [Instance-Based Authorization](../guides/security/authorization#instance-based-auth) allows to add more specific conditions that apply on entity instance level and depend on the attributes that are assigned to the request user. A typical use case is to narrow down the set of visible entity instances depending on user properties (for example, `CountryCode` or `Department`). Instance-based authorization is also basis for [domain-driven authorizations](../guides/security/authorization#domain-driven-authorization) built on more complex model constraints. +In addition to standard authorization, CAP Java provides additional out of the box capabilities to reduce custom code: #### Deep Authorization { #deep-auth} -Queries to Application Services are not only authorized by the target entity which has a `@restrict` or `@requires` annotation, but also for all __associated entities__ that are used in the statement. __Compositions__ are neither checked nor extended with additional filters. - +Queries to Application Services are not only authorized by the target entity which has a `@restrict` or `@requires` annotation, but also for all __associated entities__ that are used in the statement. +__Compositions__ are neither checked nor extended with additional filters. For instance, consider the following model: ```cds @@ -381,15 +373,15 @@ entity Orders { } ``` -For the following OData request `GET Orders(ID='1')/items?$expand=book`, authorizations for `Orders` and for `Books` are checked. -If the entity `Books` has a `where` clause for [instance-based authorization](/java/security#instance-based-auth), +For the following OData request `GET Orders(ID='1')/items?$expand=book`, authorizations for `Orders` and for `Books` are checked. +If the entity `Books` has a `where` clause for [instance-based authorization](/java/security#instance-based-auth), it will be added as a filter to the sub-request with the expand. -Custom CQL statements submitted to the [Application Service](/java/cqn-services/application-services) instances +Custom CQL statements submitted to the [Application Service](/java/cqn-services/application-services) instances are also authorized by the same rules including the path expressions and subqueries used in them. -For example, the following statement checks role-based authorizations for both `Orders` and `Books`, -because the association to `Books` is used in the select list. +For example, the following statement checks role-based authorizations for both `Orders` and `Books`, +because the association to `Books` is used in the select list. ```java Select.from(Orders_.class, @@ -413,7 +405,28 @@ Be careful when you modify or extend the statements in custom handlers. Make sure you keep the filters for authorization. ::: -Deep authorizations are on by default and can be disabled by setting `cds.security.authorization.deep.enabled: false`. +Starting with CAP Java `4.0`, deep authorization is on by default. +It can be disabled by setting cds.security.authorization.deep.enabled: false. + +[Learn more about `@restrict.where` in the instance-based authorization guide.](/guides/security/authorization#instance-based-auth){.learn-more} + +#### Forbidden on Rejected Entity Selection { #reject-403 } + +Entities that have an instance-based authorization condition, that is [`@restrict.where`](/guides/security/authorization#restrict-annotation), +are guarded by the CAP Java runtime by adding a filter condition to the DB query **excluding not matching instances from the result**. +Hence, if the user isn't authorized to query an entity, requests targeting a *single* entity return *404 - Not Found* response and not *403 - Forbidden*. + +To allow the UI to distinguish between *not found* and *forbidden*, CAP Java can detect this situation and rejects`PATCH` and `DELETE` requests to single entities with forbidden accordingly. +The additional authorization check may affect performance. + +::: warning +To avoid to disclosure the existence of such entities to unauthorized users, make sure that the key is not efficiently enumerable or add custom code to overrule the default behaviour otherwise. +::: + +Starting with CAP Java `4.0`, the reject behaviour is on by default. +It can be disabled by setting cds.security.authorization.instance-based.reject-selected-unauthorized-entity.enabled: false. + +[Learn more about `@restrict.where` in the instance-based authorization guide.](/guides/security/authorization#instance-based-auth){.learn-more} #### Authorization Checks On Input Data { #input-data-auth } @@ -430,15 +443,11 @@ annotate Orders with @(restrict: [ A user with accounting areas `[Development, Research]` is not able to send an `UPDATE` request, that changes `accountingArea` from `Research` or `Development` to `CarFleet`, for example. Note that the `UPDATE` on instances _not matching the request user's accounting areas_ (for example, `CarFleet`) are rejected by standard instance-based authorization checks. -#### Current Limitations +Starting with CAP Java `4.0`, deep authorization is on by default. +It can be disabled by setting cds.security.authorization.instanceBased.checkInputData: false. -The CAP Java SDK translates the `where`-condition in the `@restrict` annotation to a predicate, which is appended to the `CQN` statement of the request. This applies only to `READ`,`UPDATE`, and `DELETE` events. In the current version, the following limitations apply: -* For `UPDATE` and `DELETE` events no paths in the `where`-condition are supported. -* Paths in `where`-conditions with `to-many` associations or compositions can only be used with an [`exists` predicate](../guides/security/authorization#exists-predicate). -* `UPDATE` and `DELETE` requests that address instances that aren't covered by the condition (for example, which aren't visible) aren't rejected, but work on the limited set of instances as expected. -As a workaround for the limitations with paths in `where`-conditions, you may consider using the `exists` predicate instead. +[Learn more about `@restrict.where` in the instance-based authorization guide.](/guides/security/authorization#instance-based-auth){.learn-more} -CAP Java SDK supports [User Attribute Values](../guides/security/authorization#user-attrs) that can be referred by `$user.` in the where-clause of the `@restrict`-annotation. Currently, only comparison predicates with user attribute values are supported (`<,<=,=,=>,>`). Note that generally a user attribute represents an *array of strings* and *not* a single value. A given value list `[code1, code2]` for `$user.code` in predicate `$user.code = Code` evaluates to `(code1 = Code) or (code2 = Code)` in the resulting statement. ### Enforcement API & Custom Handlers { #enforcement-api} From 9316e91d85851a02f91b6ae9bd7bcbe27222b6b3 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 28 May 2025 13:29:14 +0200 Subject: [PATCH 125/140] Java Migration Guide: Removed APIs (#1879) --- java/migration.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/migration.md b/java/migration.md index 16431d2d56..21fa59e07e 100644 --- a/java/migration.md +++ b/java/migration.md @@ -122,6 +122,16 @@ The following table gives an overview about the removed properties: | `cds.multiTenancy.subscriptionManager.`
`clientCertificateHeader` | `cds.security.authentication.`
`clientCertificateHeader` | | `cds.multiTenancy.security.`
`internalUserAccess.enabled` | `cds.security.authentication.`
`internalUserAccess.enabled` | +### Removed Java APIs + +- Removed deprecated classes: + - `com.sap.cds.ql.cqn.CqnSearchPredicate`, use `CqnSearchTermPredicate` instead + +- Removed deprecated methods: + - `com.sap.cds.ql.cqn.Modifier.search(String term)`, use `searchTerm(CqnSearchTermPredicate)` instead + - `com.sap.cds.ql.cqn.Modifier.selectListValue(Value value, String alias)`, use `selectListValue(SelectableValue value, String alias)` instead + - `com.sap.cds.ql.SelectableValue.withoutAlias()`, use `as(String alias)` instead + ## CAP Java 2.10 to CAP Java 3.0 { #two-to-three } ### Minimum Versions From 426d90e39edf4d16b0907ca9f2da9f921f4bbc5c Mon Sep 17 00:00:00 2001 From: Evgeny Andreev Date: Mon, 2 Jun 2025 08:22:29 +0200 Subject: [PATCH 126/140] Remove `@odata.apply.transformations` (#1884) Starting from `cds-services` 4.x the annotation `@odata.apply.transformations` is optional --- advanced/odata.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/advanced/odata.md b/advanced/odata.md index 3e033140f5..69960f00af 100644 --- a/advanced/odata.md +++ b/advanced/odata.md @@ -1172,15 +1172,11 @@ The `Hierarchy` aspect defines a set of virtual elements, automatically calculat The following service defines the projection on the domain model. ```cds -@odata.apply.transformations service HRService { entity HREmployee as projection on Employee; } ``` -::: warning -The service must be annotated with `@odata.apply.transformations`. This instructs the Java Runtime to push down the whole transformation pipeline to the persistence layer. -::: ##### OData v4 Annotations for Fiori From b38bbd052d1041cb5d091f00db673ce1bc3ebc6e Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:50:33 +0200 Subject: [PATCH 127/140] Runtime Views: `CTE` mode (#1880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian GΓΆrler --- java/migration.md | 1 + java/working-with-cql/query-execution.md | 64 ++++++++++++++++-------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/java/migration.md b/java/migration.md index 21fa59e07e..1697c152b1 100644 --- a/java/migration.md +++ b/java/migration.md @@ -98,6 +98,7 @@ Some property defaults have been adjusted: | `cds.security.authorization.instanceBased.rejectSelectedUnauthorizedEntity.enabled` | false | true | Requests that violate instance-based authorization conditions now fail with 403, instead of 404. | | `cds.security.authorization.instanceBased.checkInputData.enabled` | false | true | [Authorization Checks On Input Data](./security#input-data-auth) are now enabled by default. | | `cds.errors.defaultTranslations.enabled` | false | true | [Translations for Validation Error Messages](./event-handlers/indicating-errors#ootb-translated-messages) are now enabled by default. | +| `cds.sql.runtimeView.mode` | resolve | cte | [Runtime views](./working-with-cql/query-execution#runtimeviews) are now by default translated into Common Table Expressions | ### Deprecated Properties diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 8f206e1764..af60b19a27 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -400,11 +400,17 @@ The `lock()` method has an optional parameter `timeout` that indicates the maxim The parameter `mode` allows to specify whether an `EXCLUSIVE` or a `SHARED` lock should be set. -## Runtime Views { #runtimeviews} +## Runtime Views { #runtimeviews } -The CDS compiler generates [SQL DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) statements based on your CDS model, which include SQL views for all CDS [views and projections](../../cds/cdl#views-projections). This means adding or changing CDS views requires a deployment of the database schema changes. +The CDS compiler generates [SQL DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) statements from your CDS model, including SQL views for all CDS [views and projections](../../cds/cdl#views-projections). As a result, adding or modifying CDS views typically requires redeploying the database schema. -To avoid schema updates due to adding or updating CDS views, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). In this case the CDS compiler won't generate corresponding static database views. Instead, the CDS views are dynamically resolved by the CAP Java runtime. +To avoid schema redeployments when you add or update CDS views, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This annotation tells the CDS compiler to skip generating database views for these entities. Instead, the CAP Java runtime dynamically resolves such views at runtime. + +::: warning Limitations +Runtime views support only simple [CDS projections](../../cds/cdl#as-projection-on). They do not support complex views that use aggregations, unions, joins, or subqueries in the `FROM` clause. To read [draft-enabled](../fiori-drafts#reading-drafts) entities, set `cds.drafts.persistence` to `split`. [Calculated elements](../../cds/cdl#calculated-elements) are not yet supported in runtime views. +::: + +For example, consider the following CDS model and query: ```cds entity Books { @@ -413,33 +419,47 @@ entity Books { stock : Integer; author : Association to one Authors; } -@cds.persistence.skip // [!code focus] -entity BooksWithLowStock as projection on Books { // [!code focus] - id, title, author.name as author // [!code focus] -} where stock < 10; // [!code focus] +@cds.persistence.skip +entity BooksWithLowStock as projection on Books { + id, title, author.name as author +} where stock < 10; ``` - -At runtime, CAP Java resolves queries against runtime views until an entity is reached that isn't annotated with *@cds.persistence.skip*. For example, the CQL query - ```sql Select BooksWithLowStock where author = 'Kafka' ``` -is executed against SQL databases as - -```SQL -SELECT B.ID, B.TITLE, A.NAME as "author" FROM BOOKS AS B - LEFT OUTER JOIN AUTHORS AS A ON B.AUTHOR_ID = A.ID -WHERE B.STOCK < 10 AND A.NAME = ? -``` +CAP Java provides two modes for resolving runtime views: -::: warning Limitations -Runtime views are supported for simple [CDS projections](../../cds/cdl#as-projection-on). Expands of [filtered associations](../../cds/cdl#publish-associations-with-filter) are only supported since `3.7.0`. Constant values and expressions in runtime views are supported since `3.8.0`. +**`cte` mode**: The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. -Complex views using aggregations or union/join/subqueries in `FROM` are not supported and for reading [draft-enabled](../fiori-drafts#reading-drafts) entities, `cds.drafts.persistence` needs to be set to `split`. +```sql +WITH BOOKSWITHLOWSTOCK_CTE AS ( + SELECT B.ID, + B.TITLE, + A.NAME AS "AUTHOR" + FROM BOOKS B + LEFT OUTER JOIN AUTHOR A ON B.AUTHOR_ID = A.ID + WHERE B.STOCK < 10 +) +SELECT ID, TITLE, AUTHOR AS "author" + FROM BOOKSWITHLOWSTOCK_CTE + WHERE A.NAME = ? +``` + +::: tip +CAP Java 4.x uses `cte` mode by default. In 3.10, enable it with **cds.sql.runtimeView.mode: cte**. ::: -### Using I/O Streams in Queries +**`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against them. + +```sql +SELECT B.ID, B.TITLE, A.NAME AS "author" + FROM BOOKS AS B + LEFT OUTER JOIN AUTHORS AS A ON B.AUTHOR_ID = A.ID + WHERE B.STOCK < 10 AND A.NAME = ? +``` + +## Using I/O Streams in Queries As described in section [Predefined Types](../cds-data#predefined-types) it's possible to stream the data, if the element is annotated with `@Core.MediaType`. The following example demonstrates how to allocate the stream for element `coverImage`, pass it through the API to an underlying database and close the stream. @@ -473,7 +493,7 @@ try (InputStream resource = getResource("IMAGE.PNG")) { // Transaction finished ``` -### Using Native SQL +## Using Native SQL CAP Java doesn't have a dedicated API to execute native SQL Statements. However, when using Spring as application framework you can leverage Spring's features to execute native SQL statements. See [Execute SQL statements with Spring's JdbcTemplate](../cqn-services/persistence-services#jdbctemplate) for more details. From 8ddc1c9cfd0363aaf311e1827fa0de29f2266121 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:51:38 +0200 Subject: [PATCH 128/140] add headings in cds.queued() docs (#1885) --- node.js/queue.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node.js/queue.md b/node.js/queue.md index 305ae2c56e..5db2026446 100644 --- a/node.js/queue.md +++ b/node.js/queue.md @@ -228,6 +228,8 @@ Finally, entries in the dead letter queue can either be _revived_ by resetting t ### Additional APIs +#### Task Scheduling + You can use the `schedule` method as a shortcut for `cds.queued(srv).send()`, with optional scheduling options `after` and `every`: ```js @@ -236,6 +238,7 @@ await srv.schedule('someEvent', { some: 'message' }).after('1h') // after one ho await srv.schedule('someEvent', { some: 'message' }).every('1h') // every hour after each processing ``` +#### Task Processing To manually trigger the message processing, for example if your server is restarted, you can use the `flush` method. @@ -244,6 +247,8 @@ const srv = await cds.connect.to('yourService') cds.queued(srv).flush() ``` +#### Task Callbacks + Once a message has been successfully processed, it triggers the `/#succeeded` handlers. ```js From fa4c3674d5f80c99281a71e186da3e93c2cba424 Mon Sep 17 00:00:00 2001 From: Thomas Bonk <130759028+t-bonk@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:53:01 +0200 Subject: [PATCH 129/140] Internal CdsJsonConverter documentation (#1883) added hook point for the internal CdsJsonConvert docs --- java/cds-data.md | 68 +++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/java/cds-data.md b/java/cds-data.md index efb1c73434..8b6f7538e5 100644 --- a/java/cds-data.md +++ b/java/cds-data.md @@ -21,44 +21,44 @@ uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/ The [predefined CDS types](../cds/types) are mapped to Java types and as follows: -| CDS Type | Java Type | Remark | -|--------------------|------------------------|--------------------------------------------------------------------------| -| `cds.UUID` | `java.lang.String` | | -| `cds.Boolean` | `java.lang.Boolean` | | -| `cds.UInt8` | `java.lang.Short` | | -| `cds.Int16` | `java.lang.Short` | | -| `cds.Int32` | `java.lang.Integer` | | -| `cds.Integer` | `java.lang.Integer` | | -| `cds.Int64` | `java.lang.Long` | | -| `cds.Integer64` | `java.lang.Long` | | -| `cds.Decimal` | `java.math.BigDecimal` | | -| `cds.DecimalFloat` | `java.math.BigDecimal` | deprecated | -| `cds.Double` | `java.lang.Double` | | -| `cds.Date` | `java.time.LocalDate` | date without a time-zone (year-month-day) | -| `cds.Time` | `java.time.LocalTime` | time without a time-zone (hour-minute-second) | -| `cds.DateTime` | `java.time.Instant` | instant on the time-line with _sec_ precision | -| `cds.Timestamp` | `java.time.Instant` | instant on the time-line with _Β΅s_ precision | -| `cds.String` | `java.lang.String` | | -| `cds.LargeString` | `java.lang.String` | `java.io.Reader` (1) if annotated with `@Core.MediaType` | -| `cds.Binary` | `byte[]` | | -| `cds.LargeBinary` | `byte[]` | `java.io.InputStream` (1) if annotated with `@Core.MediaType` | -| `cds.Vector` | `com.sap.cds.CdsVector`| for [vector embeddings](#vector-embeddings) | +| CDS Type | Java Type | Remark | +| ------------------ | ----------------------- | ------------------------------------------------------------------------ | +| `cds.UUID` | `java.lang.String` | | +| `cds.Boolean` | `java.lang.Boolean` | | +| `cds.UInt8` | `java.lang.Short` | | +| `cds.Int16` | `java.lang.Short` | | +| `cds.Int32` | `java.lang.Integer` | | +| `cds.Integer` | `java.lang.Integer` | | +| `cds.Int64` | `java.lang.Long` | | +| `cds.Integer64` | `java.lang.Long` | | +| `cds.Decimal` | `java.math.BigDecimal` | | +| `cds.DecimalFloat` | `java.math.BigDecimal` | deprecated | +| `cds.Double` | `java.lang.Double` | | +| `cds.Date` | `java.time.LocalDate` | date without a time-zone (year-month-day) | +| `cds.Time` | `java.time.LocalTime` | time without a time-zone (hour-minute-second) | +| `cds.DateTime` | `java.time.Instant` | instant on the time-line with _sec_ precision | +| `cds.Timestamp` | `java.time.Instant` | instant on the time-line with _Β΅s_ precision | +| `cds.String` | `java.lang.String` | | +| `cds.LargeString` | `java.lang.String` | `java.io.Reader` (1) if annotated with `@Core.MediaType` | +| `cds.Binary` | `byte[]` | | +| `cds.LargeBinary` | `byte[]` | `java.io.InputStream` (1) if annotated with `@Core.MediaType` | +| `cds.Vector` | `com.sap.cds.CdsVector` | for [vector embeddings](#vector-embeddings) | ### SAP HANA-Specific Data Types To facilitate using legacy CDS models, the following [SAP HANA-specific data types](../advanced/hana#hana-types) are supported: -| CDS Type | Java Type | Remark | -| --- | --- | --- | -| `hana.TINYINT` | `java.lang.Short` | | -| `hana.SMALLINT` | `java.lang.Short` | | -| `hana.SMALLDECIMAL` | `java.math.BigDecimal` | | -| `hana.REAL` | `java.lang.Float` | | -| `hana.CHAR` | `java.lang.String` | | -| `hana.NCHAR` | `java.lang.String` | | -| `hana.VARCHAR` | `java.lang.String` | | -| `hana.CLOB` | `java.lang.String` | `java.io.Reader` (1) if annotated with `@Core.MediaType` | -| `hana.BINARY` | `byte[]` | | +| CDS Type | Java Type | Remark | +| ------------------- | ---------------------- | ------------------------------------------------------------------- | +| `hana.TINYINT` | `java.lang.Short` | | +| `hana.SMALLINT` | `java.lang.Short` | | +| `hana.SMALLDECIMAL` | `java.math.BigDecimal` | | +| `hana.REAL` | `java.lang.Float` | | +| `hana.CHAR` | `java.lang.String` | | +| `hana.NCHAR` | `java.lang.String` | | +| `hana.VARCHAR` | `java.lang.String` | | +| `hana.CLOB` | `java.lang.String` | `java.io.Reader` (1) if annotated with `@Core.MediaType` | +| `hana.BINARY` | `byte[]` | | > (1) Although the API to handle large objects is the same for every database, the streaming feature, however, is supported (and tested) in **SAP HANA**, **PostgreSQL**, and **H2**. See section [Database Support in Java](./cqn-services/persistence-services#database-support) for more details on database support and limitations. @@ -275,6 +275,8 @@ person.toJson(); // { "salutation" : "Mr.", name : { "first" : "Frank" } } Avoid cyclic relationships between CdsData objects when using toJson. ::: +
+ ## Vector Embeddings { #vector-embeddings } From 9224c1ca667cdcc36a25ad2ce9c88a7023eebcb3 Mon Sep 17 00:00:00 2001 From: Vitaly Kozyura <58591662+vkozyura@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:42:31 +0200 Subject: [PATCH 130/140] fix: redirect url (#1889) I followed the steps in the docu - on my side it worked only after changing the url. --- node.js/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.js/authentication.md b/node.js/authentication.md index 2a1675605e..2394829ea9 100644 --- a/node.js/authentication.md +++ b/node.js/authentication.md @@ -483,7 +483,7 @@ If you don't know the API endpoint, have a look at section [Regions and API Endp ```json "oauth2-configuration": { "redirect-uris": [ - "http://localhost:5000/" + "http://localhost:5000/login/callback" ] } ``` From 9fbc0d26a513b282f7d10aecc857264976377e6a Mon Sep 17 00:00:00 2001 From: JenniferStamm Date: Tue, 3 Jun 2025 13:44:42 +0200 Subject: [PATCH 131/140] [Java] copy 'Log CDS Configuration' into observability (#1839) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit copying the section on 'Log CDS Configuration' from March 2025 release note to the page on 'Operating Applications > Observability' for higher visibility. --------- Co-authored-by: RenΓ© Jeglinsky --- java/operating-applications/observability.md | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/java/operating-applications/observability.md b/java/operating-applications/observability.md index 9e7e92c5d2..863d47c9f3 100644 --- a/java/operating-applications/observability.md +++ b/java/operating-applications/observability.md @@ -166,6 +166,34 @@ Most of the loggers are used on DEBUG level by default as they produce quite som Spring comes with its own [standard logger groups](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/html/boot-features-logging.html#boot-features-custom-log-groups). For instance, `web` is useful to track HTTP requests. However, HTTP access logs gathered by the Cloud Foundry platform router are also available in the application log. ::: +#### Log CDS Configuration + +Upon start-up, you can get an overview of the configured CDS properties. Use this feature to: +- list all accepted CDS properties and double-check the running configuration +- check for warnings of usage of deprecated properties +- check for warnings of usage of undocumented properties + +Please note that secrets are masked. + +Turn it on by setting the log level com.sap.cds.properties = DEBUG. + + +::: details Sample output: + +```sh +... DEBUG ... com.sap.cds.properties : 'cds.dataSource.autoConfig.enabled': 'false' (default: 'true') +... DEBUG ... com.sap.cds.properties : 'cds.dataSource.embedded': 'true' (default: 'false') +... WARN ... com.sap.cds.properties : 'cds.security.authorization.emptyAttributeValuesAreRestricted': 'false' (default: 'true', deprecated, not documented) +... DEBUG ... com.sap.cds.properties : 'cds.security.mock.users.admin.name': 'admin' +... DEBUG ... com.sap.cds.properties : 'cds.security.mock.users.admin.password': '***' (sensitive) +... DEBUG ... com.sap.cds.properties : 'cds.security.mock.users.admin.roles[0]': 'admin' +... DEBUG ... com.sap.cds.properties : 'cds.security.mock.users.admin.roles[1]': 'cds.Developer' +... DEBUG ... com.sap.cds.properties : 'cds.security.mock.users.admin.attributes.businessPartner[0]': '10401010' +... DEBUG ... com.sap.cds.properties : 'cds.odataV4.endpoint.path': '/api' (default: '/odata/v4') +... DEBUG ... com.sap.cds.properties : 'cds.errors.defaultTranslations.enabled': 'true' (default: 'false') +``` +::: + ### Logging Service { #logging-service} The SAP BTP platform offers the [SAP Application Logging service for SAP BTP](https://help.sap.com/docs/r/product/APPLICATION_LOGGING) From 9752d8fb5172fc40a816c34fa101553e190ca1e8 Mon Sep 17 00:00:00 2001 From: Johannes Vogt Date: Wed, 4 Jun 2025 07:06:58 +0200 Subject: [PATCH 132/140] Release microservices guide (#1891) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Schlachter Co-authored-by: RenΓ© Jeglinsky --- guides/deployment/microservices.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md index eeccfdb83f..df9cfd6e7f 100644 --- a/guides/deployment/microservices.md +++ b/guides/deployment/microservices.md @@ -1,6 +1,7 @@ --- synopsis: > A guide on deploying SAP Cloud Application Programming Model (CAP) applications as microservices to the SAP BTP Cloud Foundry environment. +status: released --- # Microservices with CAP @@ -10,10 +11,10 @@ A comprehensive guide on deploying your CAP application as microservices. [[toc]] -## Create a Solution Monorepo +## Create a Solution Monorepo Assumed we want to create a composite application consisting of two or more micro services, each living in a separate GitHub repository, for example: - + - https://github.com/capire/bookstore - https://github.com/capire/reviews - https://github.com/capire/orders @@ -906,12 +907,7 @@ resources: #### Subsequent updates -- TODO... -- Whenever one of the projects has changes affecting the database, that triggers a new deployment of the `shared-db` project -- `git submodules` gives you control of which versions to pull, for example by `git branches` or `git tags` -- Ensure to first deploy `shared-db` before deploying the others - - +Whenever one of the projects has changes affecting the database, the database artifacts need to be deployed prior to the application deployment. With a single `mta.yaml`, this is handled in the scope of the mta deployment. When using multiple deployment units, ensure to first deploy the `shared-db` project before deploying the others. ## Late-Cut Microservices From 487e4516ca36848eceeb9ac6efd45a57fd29d34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Wed, 4 Jun 2025 07:34:23 +0200 Subject: [PATCH 133/140] Document CDL Operators vs CAP Java Operators (#1892) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- java/working-with-cql/query-api.md | 56 +++++++++++++++++------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/java/working-with-cql/query-api.md b/java/working-with-cql/query-api.md index e7f61c100e..264a0347e5 100644 --- a/java/working-with-cql/query-api.md +++ b/java/working-with-cql/query-api.md @@ -1474,8 +1474,14 @@ These comparison operators are supported: + + + + - + - + - + - - + @@ -1564,9 +1560,21 @@ GT + + + + + + @@ -1580,9 +1588,7 @@ LT - + @@ -1596,7 +1602,7 @@ LE -
Operator +
+ CAP Java + - Predicate + CDL Description @@ -1488,11 +1494,9 @@ These comparison operators are supported:
EQ= -EQ - - Test if this value equals a given value. NULL values might be treated as unknown resulting in a three-valued logic as in SQL. + Test if this value equals a given value. NULL values might be treated as unknown resulting in a three-valued logic as in SQL. Select.from("bookshop.Books") @@ -1502,11 +1506,9 @@ EQ
NE<> -NE - - Test if this value is NOT equal to a given value. NULL values might be treated as unknown resulting in a three-valued logic as in SQL. + Test if this value is NOT equal to a given value. NULL values might be treated as unknown resulting in a three-valued logic as in SQL. Select.from("bookshop.Books") @@ -1516,11 +1518,9 @@ NE
IS== -IS - - Test if this value equals a given value. NULL values are treated as any other value. + Test if this value equals a given value. NULL values are treated as any other value (Boolean logic). @@ -1532,11 +1532,9 @@ IS
IS NOT!= -IS NOT - - Test if this value is NOT equal to a given value. NULL values are treated as any other value. + Test if this value is NOT equal to a given value. NULL values are treated as any other value (Boolean logic). @@ -1548,9 +1546,7 @@ IS NOT
-GT -GT> Test if this value is greater than a given value.
GE>= -LT + Test if this value is greater than or equal to a given value. + +Select.from("bookshop.Books") + .where(b -> b.get("stock") + .ge(5)); + +
LT< Test if this value is less than a given value.
-LE -LE<= Test if this value is less than or equal to a given value.
+ BETWEEN From e9ca1dc009b572f0da657e8e530d7114823a16c8 Mon Sep 17 00:00:00 2001 From: Markus Ofterdinger Date: Wed, 4 Jun 2025 07:34:57 +0200 Subject: [PATCH 134/140] Update versions.md (#1893) --- java/versions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/versions.md b/java/versions.md index e3186ef962..25073edc17 100644 --- a/java/versions.md +++ b/java/versions.md @@ -80,13 +80,14 @@ The following table lists these minimum versions for various common dependencies | Dependency | Minimum Version | Recommended Version | | --- | --- | --- | | JDK | 17 | 21 | -| Maven | 3.6.3 | 3.9.8 | +| Maven | 3.6.3 | 3.9.9 | | @sap/cds-dk | 7 | latest | | @sap/cds-compiler | 4 | latest | | Spring Boot | 3.0 | latest | | XSUAA | 3.0 | latest | | SAP Cloud SDK | 5.9 | latest | | Java Logging | 3.7 | latest | +| Node.js | 18 | 20 | ### Consistent Versions From 2ba9905d0a7c9ec142064c5c142bcab86165652b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Wed, 4 Jun 2025 07:47:16 +0200 Subject: [PATCH 135/140] Document cds.Map type (#1895) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- java/cds-data.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/cds-data.md b/java/cds-data.md index 8b6f7538e5..a897eea7ae 100644 --- a/java/cds-data.md +++ b/java/cds-data.md @@ -43,6 +43,7 @@ The [predefined CDS types](../cds/types) are mapped to Java types and as follows | `cds.Binary` | `byte[]` | | | `cds.LargeBinary` | `byte[]` | `java.io.InputStream` (1) if annotated with `@Core.MediaType` | | `cds.Vector` | `com.sap.cds.CdsVector` | for [vector embeddings](#vector-embeddings) | +| `cds.Map` | `java.util.Map` | for arbitrary [structured data](#structured-data)(2) | ### SAP HANA-Specific Data Types @@ -62,6 +63,7 @@ To facilitate using legacy CDS models, the following [SAP HANA-specific data typ > (1) Although the API to handle large objects is the same for every database, the streaming feature, however, is supported (and tested) in **SAP HANA**, **PostgreSQL**, and **H2**. See section [Database Support in Java](./cqn-services/persistence-services#database-support) for more details on database support and limitations. +> (2) Serialized as JSON to a CLOB column or JSONB column (on Postgres) ::: warning The framework isn't responsible for closing the stream when writing to the database. You decide when the stream is to be closed. If you forget to close the stream, the open stream can lead to a memory leak. From 55a4724d7eee8444477355e644183b5a57ba9c86 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Wed, 4 Jun 2025 14:06:11 +0200 Subject: [PATCH 136/140] edit --- guides/deployment/microservices.md | 51 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md index df9cfd6e7f..12e87c5c80 100644 --- a/guides/deployment/microservices.md +++ b/guides/deployment/microservices.md @@ -19,13 +19,13 @@ Assumed we want to create a composite application consisting of two or more micr - https://github.com/capire/reviews - https://github.com/capire/orders -With some additional repos, used as dependencies in the same manner, like: +With some additional repositories, used as dependencies in the same manner, like: - https://github.com/capire/common - https://github.com/capire/bookshop - https://github.com/capire/data-viewer -This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[NPM workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques... +This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[NPM workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques. 1. Create a new monorepo root directory using *NPM workspaces*: @@ -98,7 +98,10 @@ When one of the projects is cloned in isolation, it's still possible to fetch de ## Using a Shared Database -If you have multiple CAP applications relying on the same domain model or want to split up a monolithic CAP application **on the service level only while still sharing the underlying database layer**, you can deploy your model to a single database and then share it across applications. +You can deploy your model to a single database and then share it across applications, if you have one of the following scenarios: + +- multiple CAP applications relying on the same domain model +- a monolithic CAP application that you want to split up **on the service level only, while still sharing the underlying database layer** In the following steps, we create an additional project to easily collect the relevant models from these projects, and act as a vehicle to deploy these models to SAP HANA in a controlled way. @@ -185,9 +188,9 @@ The project structure used here is as follows: └─ package.json ``` -The `shared-db` module is simply another CAP project, with only db content. The dependencies are installed via NPM, so it's still possible to install via an NPM registry if used outside of the monorepo setup. +The `shared-db` module is simply another CAP project, with only database content. The dependencies are installed via NPM, so it's still possible to install via an NPM registry if used outside of the monorepo setup. -The db model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all NPM workspaces. +The database model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all NPM workspaces. ::: @@ -658,7 +661,7 @@ modules: ``` ::: -The _xs-app.json_ file describes how to forward incoming request to the API endpoint / OData services and is located in the app/router folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service. +The _xs-app.json_ file describes how to forward incoming request to the API endpoint / OData services and is located in the _.deploy/app-router_ folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service. ::: code-group ```json [.deploy/app-router/xs-app.json] @@ -792,13 +795,13 @@ You can then navigate to this url and the corresponding apps ``` -## Deployment as separate mta +## Deployment as Separate MTA -This is an alternative to the all-in-one deployment. Assume the applications each already have their own mta.yaml. For example by running `cds add mta` in the `reviews`, `orders` and `bookstore` folder. +This is an alternative to the all-in-one deployment. Assume the applications each already have their own _mta.yaml_. For example by running `cds add mta` in the _reviews_, _orders_ and _bookstore_ folder. ### Database -We can add the [previously created](#using-a-shared-database) `shared-db` project as its own mta deployment: +We can add the [previously created](#using-a-shared-database) `shared-db` project as its own MTA deployment: ::: code-group ```sh [shared-db/] @@ -877,7 +880,7 @@ resources: The only thing left to care about is to ensure all 3+1 projects are bound and connected to the same database at deployment, subscription, and runtime. -Configure the mta.yaml of the other apps to bind to the existing shared database, for example, in the reviews module: +Configure the _mta.yaml_ of the other apps to bind to the existing shared database, for example, in the reviews module: ```yaml [reviews/mta.yaml] ... @@ -907,7 +910,7 @@ resources: #### Subsequent updates -Whenever one of the projects has changes affecting the database, the database artifacts need to be deployed prior to the application deployment. With a single `mta.yaml`, this is handled in the scope of the mta deployment. When using multiple deployment units, ensure to first deploy the `shared-db` project before deploying the others. +Whenever one of the projects has changes affecting the database, the database artifacts need to be deployed prior to the application deployment. With a single _mta.yaml_, this is handled in the scope of the MTA deployment. When using multiple deployment units, ensure to first deploy the `shared-db` project before deploying the others. ## Late-Cut Microservices @@ -932,7 +935,7 @@ Instead of just choosing between a monolith and microservices, these aspects can Since each cut not only has benefits, but also drawbacks, it's important to choose which benefits actually help the overall product and which drawbacks can be accepted. -![Multiple deployment units - one contains the UIs, one contains shared service instances, one contains a shared db, two each contain an app connected to the shared db, one contains a db and an app, which is also connected to the shared db](./assets/microservices/complex.excalidraw.svg) +![Multiple deployment units - one contains the UIs, one contains shared service instances, one contains a shared database, two each contain an app connected to the shared database, one contains a database and an app, which is also connected to the shared database](./assets/microservices/complex.excalidraw.svg) ### A Late Cut @@ -941,16 +944,16 @@ When developing a product, it may initially not be apparent where the boundaries Keeping this in mind, an app can be developed as a modular application with use case specific CAP services. It can first be deployed as a [monolith / modulith](#monolith-or-microservice). Once the boundaries are clear, it can then be split into multiple applications. -Generally, the semantic separation and structure can be enforced using modules. The deployment configuration is then an independent step on top. In this way, the same application can be deployed as a monolith, as microservices with shared db, as true microservices, or a combination of these, just via configuration change. +Generally, the semantic separation and structure can be enforced using modules. The deployment configuration is then an independent step on top. In this way, the same application can be deployed as a monolith, as microservices with a shared database, as true microservices, or a combination of these, just via configuration change. ![Modules which can be arranged in different deploy configurations, for example, as a monolith (bookshop, reviews, orders), as two apps (bookshop, orders in one, reviews in the other), and so on.](./assets/microservices/late-cut.excalidraw.svg) -### Best Practices +### Best Practices {.good} * Prefer a late cut * Stay flexible in where to cut -* Prefer staying loosely coupled β†’ for example, ReviewsService β†’ reviewed events β†’ UPDATE avg ratings -* Leverage db-level integration selectively β†’ Prefer referring to (public) service entities, not (private) db entities +* Prefer staying loosely coupled β†’ for example, ReviewsService β†’ reviewed events β†’ UPDATE average ratings +* Leverage database-level integration selectively β†’ Prefer referring to (public) service entities, not (private) database entities ## Appendix @@ -958,27 +961,27 @@ Generally, the semantic separation and structure can be enforced using modules. A monolith is a single deployment unit with a single application. This is very convenient, because every part of the app is accessible in memory. -![A monolith](./assets/microservices/monolith.excalidraw.svg) +![A diagram showing a monolithic application architecture. Three modules labeled bookshop, reviews, and orders are grouped together inside a single large container, representing one deployment unit. The modules are visually separated within the container but are part of the same application. The environment is clean and technical, focusing on modular structure within a unified deployment. The tone is neutral and informative. Text in the image includes bookshop, reviews, and orders.](./assets/microservices/monolith.excalidraw.svg) A modulith, even though the app is separated into multiple CAP services inside multiple modules, can still be deployed as a single monolithic application. This combines the benefit of a clear structure and distributed development while keeping a simple deployment. -![A single app containing the modules bookshop, reviews, and orders](./assets/microservices/modulith.excalidraw.svg) +![A single application visualized as a large container holding three labeled modules: bookshop, reviews, and orders. The modules are grouped together within the container, indicating they are part of the same deployment unit. The environment is clean and technical, focusing on modular structure within a unified application. The tone is neutral and informative. Text in the image includes bookshop, reviews, and orders.](./assets/microservices/modulith.excalidraw.svg) True microservices each consist of their own deployment unit with their own application and their own database. Meaning that they're truly independent of each other. And it works well if they are actually independent. -![A simplified microservices view - three deployment units, each with one app and one database](./assets/microservices/true-microservices.excalidraw.svg) +![Diagram showing a simplified microservices architecture with three separate deployment units. Each unit contains one application labeled App and one database labeled DU. The units are visually separated, emphasizing their independence. The environment is clean and technical, focusing on the modular structure of microservices. The tone is neutral and informative. No additional text is present in the image.](./assets/microservices/true-microservices.excalidraw.svg) What was mentioned earlier is a simplified view. In an actual microservice deployment, there are typically shared service instances and wiring needs to be provided so that apps can talk to each other, directly or via events. If the microservices are not cut well, the communication overhead leads to high performance losses and often the need for data replication or caching. -![A more complete microservices view - two deployment units with one app, one db and some UIs each, one deployment unit for shared service instances](./assets/microservices/true-microservices-full.excalidraw.svg) +![Diagram showing a detailed microservices architecture with three separate deployment units. Each unit contains one application labeled App and one database labeled DU. The units are visually separated, emphasizing their independence. Between the applications, there are two types of communication: a solid line labeled Events connecting the rightmost and center units, and a solid line connecting the center and left units. The environment is clean and technical, focusing on the modular structure and event-driven communication between microservices. The tone is neutral and informative. Text in the image includes DU, App, and Events.](./assets/microservices/true-microservices-full.excalidraw.svg) ### Application Instances -Having only a single virtual machine or container, the application can only be scaled vertically by increasing the cpu and memory resources. This typically has an upper limit and requires a restart when scaling. +Having only a single virtual machine or container, the application can only be scaled vertically by increasing the CPU and memory resources. This typically has an upper limit and requires a restart when scaling. To improve scalability, we can start multiple instances of the same application. @@ -1024,13 +1027,13 @@ Drawbacks: #### Resource Separation One part of an application may do highly critical background processing, while another handles incoming requests. -The incoming requests take cpu cycles and consume memory, which should rather be used for the background processing. +The incoming requests take CPU cycles and consume memory, which should rather be used for the background processing. To make sure that there are always enough resources for specific tasks, they can be split into their own app. #### Independent Scaling Similar to resource separation, different parts of the app may have different requirements and profiles for scaling. -For some parts, a 100% cpu utilization over an extended period is accepted for efficiency, while request handling apps need spare resources to handle user requests with low latency. +For some parts, a 100% CPU utilization over an extended period is accepted for efficiency, while request handling apps need spare resources to handle user requests with low latency. #### Fault Tolerance @@ -1055,7 +1058,7 @@ Drawbacks: - Coordination between deployment units for updates with dependencies - Configuration wiring to connect systems across deployment units -![One deployment unit for UIs and one deployment unit for apps, db and so on.](./assets/microservices/multiple-deployment-units.excalidraw.svg) +![Diagram illustrating multiple deployment units in a microservices architecture. The image shows several distinct containers, each representing a deployment unit. One unit contains UIs, another contains shared service instances, a third contains a shared database, and two separate units each contain an app connected to the shared database. There is also a unit that contains both a database and an app, which is also connected to the shared database. The containers are visually separated, emphasizing modularity and independent deployment. The environment is technical and organized, focusing on the structure and relationships between deployment units. Text in the image includes DU, App, and UIs. The tone is neutral and informative, highlighting architectural flexibility and separation of concerns in microservices deployment.](./assets/microservices/multiple-deployment-units.excalidraw.svg) With a single deployment unit, when a fix for one part needs to be deployed, the risk of redeploying the rest of the application needs to be considered. From 8da86c89f8121e2c7c3ddc24bd0dc6dd8e63e1b9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:13:43 +0200 Subject: [PATCH 137/140] chore: Update CLI texts (#1896) Updates the output of cds CLI texts to the latest version. Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com> --- tools/assets/help/cds-compile.out.md | 2 +- tools/assets/help/cds-debug.out.md | 4 ++++ tools/assets/help/cds-help.out.md | 2 ++ tools/assets/help/cds-init.out.md | 2 +- tools/assets/help/cds-version-md.out.md | 20 +++++++++----------- tools/assets/help/cds-version.out.md | 20 +++++++++----------- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/tools/assets/help/cds-compile.out.md b/tools/assets/help/cds-compile.out.md index 2479f58c0c..8de919a7d4 100644 --- a/tools/assets/help/cds-compile.out.md +++ b/tools/assets/help/cds-compile.out.md @@ -18,7 +18,7 @@ - json, yml - edm, edmx, edmx-v2, edmx-v4, edmx-w4, edmx-x4 - - sql, hdbcds, hdbtable, hana + - sql, hana, hdbtable - cdl - xsuaa - openapi diff --git a/tools/assets/help/cds-debug.out.md b/tools/assets/help/cds-debug.out.md index 1b861de222..17a16a6bbb 100644 --- a/tools/assets/help/cds-debug.out.md +++ b/tools/assets/help/cds-debug.out.md @@ -25,6 +25,10 @@ the debug port (default: '9229' for Node.js, '8000' for Java) + -f | --force + + if necessary, automatically enable ssh for the app and restart it + EXAMPLES cds debug cds debug bookshop-srv --port 8001 diff --git a/tools/assets/help/cds-help.out.md b/tools/assets/help/cds-help.out.md index 215581b595..e3c65240ac 100644 --- a/tools/assets/help/cds-help.out.md +++ b/tools/assets/help/cds-help.out.md @@ -22,6 +22,8 @@ e | env inspect effective configuration b | build prepare for deployment d | deploy deploy to databases or cloud + | up build and deploy your application + | debug debug your application | subscribe subscribe a tenant to a multitenant SaaS app | unsubscribe unsubscribe a tenant from a multitenant SaaS app l | login login to extensible multitenant SaaS app diff --git a/tools/assets/help/cds-init.out.md b/tools/assets/help/cds-init.out.md index 6d9a1db73f..64538bdefd 100644 --- a/tools/assets/help/cds-init.out.md +++ b/tools/assets/help/cds-init.out.md @@ -84,7 +84,7 @@ cds init bookshop --java cds init bookshop --add hana cds init bookshop --add multitenancy,mta - cds init --java --java:mvn groupId=myGroup,artifactId=newId,package=my.company + cds init --java --java:mvn DgroupId=myGroup,DartifactId=newId,Dpackage=my.company SEE ALSO cds add - to augment your projects later on diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md index 7f707e5ac0..5a0c0b19a8 100644 --- a/tools/assets/help/cds-version-md.out.md +++ b/tools/assets/help/cds-version-md.out.md @@ -6,15 +6,13 @@ | ---------------------- | --------------------------------------- | | @cap-js/asyncapi | 1.0.3 | | @cap-js/cds-types | 0.10.0 | -| @cap-js/db-service | 1.20.1 | -| @cap-js/openapi | 1.2.2 | -| @cap-js/sqlite | 1.11.0 | -| @sap/cds | 8.9.4 | -| @sap/cds-compiler | 5.9.4 | -| @sap/cds-dk (global) | 8.9.4 | -| @sap/cds-fiori | 1.4.1 | -| @sap/cds-foss | 5.0.1 | -| @sap/cds-mtxs | 2.7.2 | -| @sap/eslint-plugin-cds | 3.2.0 | -| Node.js | v20.19.1 | +| @cap-js/db-service | 2.0.1 | +| @cap-js/openapi | 1.2.3 | +| @cap-js/sqlite | 2.0.1 | +| @sap/cds | 9.0.2 | +| @sap/cds-compiler | 6.0.10 | +| @sap/cds-dk (global) | 9.0.4 | +| @sap/cds-fiori | 2.0.1 | +| @sap/cds-mtxs | 3.0.1 | +| Node.js | v20.19.2 | diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md index 627791499e..816f6d0f36 100644 --- a/tools/assets/help/cds-version.out.md +++ b/tools/assets/help/cds-version.out.md @@ -4,16 +4,14 @@ @cap-js/asyncapi: 1.0.3 @cap-js/cds-types: 0.10.0 -@cap-js/db-service: 1.20.1 -@cap-js/openapi: 1.2.2 -@cap-js/sqlite: 1.11.0 -@sap/cds: 8.9.4 -@sap/cds-compiler: 5.9.4 -@sap/cds-dk (global): 8.9.4 -@sap/cds-fiori: 1.4.1 -@sap/cds-foss: 5.0.1 -@sap/cds-mtxs: 2.7.2 -@sap/eslint-plugin-cds: 3.2.0 -Node.js: v20.19.1 +@cap-js/db-service: 2.0.1 +@cap-js/openapi: 1.2.3 +@cap-js/sqlite: 2.0.1 +@sap/cds: 9.0.2 +@sap/cds-compiler: 6.0.10 +@sap/cds-dk (global): 9.0.4 +@sap/cds-fiori: 2.0.1 +@sap/cds-mtxs: 3.0.1 +Node.js: v20.19.2 your-project: 1.0.0 From 0f4d43ff5982b29ced22358c194898c131f16e52 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Wed, 4 Jun 2025 18:42:29 +0200 Subject: [PATCH 138/140] fix links (#1898) --- node.js/cds-plugins.md | 2 +- node.js/cds-test.md | 4 ++-- node.js/queue.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/node.js/cds-plugins.md b/node.js/cds-plugins.md index d26ea6f68a..445b456c32 100644 --- a/node.js/cds-plugins.md +++ b/node.js/cds-plugins.md @@ -128,4 +128,4 @@ Currently, the following schema contribution points are supported: #### Usage In a CAP Project -
+ + ### In Kubernetes / Kyma { #in-kubernetes-kyma} CAP supports [servicebinding.io](https://servicebinding.io/) service bindings and SAP BTP service bindings created by the [SAP BTP Service Operator](https://github.com/SAP/sap-btp-service-operator). @@ -608,79 +622,9 @@ The resulting `VCAP_SERVICES` env variable looks like this: ``` -## Hybrid Testing - - -In addition to the [static configuration of required services](#service-bindings), additional information, such as urls, secrets, or passwords are required to actually send requests to remote endpoints. These are dynamically filled into property `credentials` from process environments, as explained in the following. - - -### cds.requires.\.credentials - -All service binding information goes into this property. It's filled from the process environment when starting server processes, managed by deployment environments. Service bindings provide the details about how to reach a required service at runtime, that is, providing requisite credentials, most prominently the target service's `url`. - -For development purposes, you can pass them on the command line or add them to a _.env_ or _default-env.json_ file as follows: - -```properties -# .env file -cds.requires.remote-service.credentials = { "url":"http://...", ... } -``` -::: warning -❗ Never add secrets or passwords to _package.json_ or _.cdsrc.json_! -General rule of thumb: `.credentials` are always filled (and overridden) from process environment on process start. -::: - -One prominent exception of that, which you would frequently add to your _package.json_ is the definition of a database file for persistent sqlite database during development: -```json - "cds": { "requires": { - "db": { - "kind": "sql", - "[development]": { - "kind": "sqlite", - "credentials": { - "url": "db/bookshop.sqlite" - } - } - } - }} -``` - - - - -### Basic Mechanism {#bindings-via-cds-env} - - -The CAP Node.js runtime expects to find the service bindings in `cds.env.requires`. - -1. Configured required services constitute endpoints for service bindings. - - ```json - "cds": { - "requires": { - "ReviewsService": {...}, - } - } - ``` - -2. These are made available to the runtime via `cds.env.requires`. - - ```js - const { ReviewsService } = cds.env.requires - ``` - -3. Service Bindings essentially fill in `credentials` to these entries. - - ```js - const { ReviewsService } = cds.env.requires - ReviewsService.credentials = { - url: "http://localhost:4005/reviews" - } - ``` - -The latter is appropriate in test suites. In productive code, you never provide credentials in a hard-coded way. Instead, use one of the options presented in the following sections. -### Through _.cdsrc-private.json_ File for Local Testing +### Through _.cdsrc-private.json_ File for Hybrid Testing [Learn more about hybrid testing using _.cdsrc-private.json_.](../advanced/hybrid-testing#bind-to-cloud-services)