diff --git a/.github/cli/grab-cli-texts.sh b/.github/cli/grab-cli-texts.sh index 0a8a5546f..bf3af23df 100755 --- a/.github/cli/grab-cli-texts.sh +++ b/.github/cli/grab-cli-texts.sh @@ -10,11 +10,14 @@ pushd `dirname ${proj}` && cds init `basename ${proj}` && pushd `basename ${proj echo echo "Grabbing CLI texts..." -${dir}/grab-cli-texts.js @sap/cds-dk "cds add --help" ${proj} > ${dir}/../../tools/assets/help/cds-add.out.md ${dir}/grab-cli-texts.js @cap-js/cds-typer "cds-typer --help" ${proj} > ${dir}/../../tools/assets/help/cds-typer.out.md ${dir}/grab-cli-texts.js @sap/cds-dk "cds --help" ${proj} > ${dir}/../../tools/assets/help/cds-help.out.md -${dir}/grab-cli-texts.js @sap/cds-dk "cds watch --help" ${proj} > ${dir}/../../tools/assets/help/cds-watch.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds add --help" ${proj} > ${dir}/../../tools/assets/help/cds-add.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds compile --help" ${proj} > ${dir}/../../tools/assets/help/cds-compile.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds env --help" ${proj} > ${dir}/../../tools/assets/help/cds-env.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds init --help" ${proj} > ${dir}/../../tools/assets/help/cds-init.out.md ${dir}/grab-cli-texts.js @sap/cds-dk "cds repl --help" ${proj} > ${dir}/../../tools/assets/help/cds-repl.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds watch --help" ${proj} > ${dir}/../../tools/assets/help/cds-watch.out.md ${dir}/grab-cli-texts.js @sap/cds-dk "cds version" ${proj} > ${dir}/../../tools/assets/help/cds-version.out.md ${dir}/grab-cli-texts.js @sap/cds-dk "cds version --markdown" ${proj} > ${dir}/../../tools/assets/help/cds-version-md.out.md ${dir}/grab-cli-texts.js @sap/cds-dk "cds env requires.db" ${proj} > ${dir}/../../tools/assets/help/cds-env-requires-db.out.md diff --git a/.github/workflows/PR-SAP.yml b/.github/workflows/PR-SAP.yml index e6ef04866..a8768e785 100644 --- a/.github/workflows/PR-SAP.yml +++ b/.github/workflows/PR-SAP.yml @@ -31,7 +31,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 22 cache: 'npm' cache-dependency-path: docs/package-lock.json - run: npm ci diff --git a/.github/workflows/PR.yml b/.github/workflows/PR.yml index fad693786..cedbb4cb1 100644 --- a/.github/workflows/PR.yml +++ b/.github/workflows/PR.yml @@ -17,7 +17,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 22 cache: 'npm' - name: Run CDS snippet checker run: | diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8966978f7..d8f6960af 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -32,7 +32,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 22 cache: 'npm' cache-dependency-path: docs/package-lock.json - run: npm ci diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6a3705289..66ed347cc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,7 +31,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 22 cache: 'npm' - run: npm ci - run: npm test diff --git a/README.md b/README.md index 9d31b4198..1e4c8d6e3 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ We as members, contributors, and leaders pledge to make participation in our com ## Licensing -Copyright 2023-2024 SAP SE or an SAP affiliate company and CAP contributors. Please see our [LICENSE](LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/SAP/cap-js/docs). +Copyright 2023-2025 SAP SE or an SAP affiliate company and CAP contributors. Please see our [LICENSE](LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/SAP/cap-js/docs). diff --git a/cds/cdl.md b/cds/cdl.md index 7eb56429c..611806138 100644 --- a/cds/cdl.md +++ b/cds/cdl.md @@ -815,7 +815,7 @@ In CAP Java, run a select statement against the view with named [parameter value ::: code-group ```js [Node] -SELECT.from({ id: 'UsingView'. args: { bar: { val: true }}}) +SELECT.from({ ref: [{ id: 'UsingView', args: { bar: { val: true }}} ]} ) ``` ```Java [Java] var params = Map.of("bar", true); diff --git a/get-started/in-a-nutshell.md b/get-started/in-a-nutshell.md index f0e06a1af..aed428d5d 100644 --- a/get-started/in-a-nutshell.md +++ b/get-started/in-a-nutshell.md @@ -193,7 +193,7 @@ cds db/schema.cds -2 yml cds db/schema.cds -2 sql ``` -[Learn more about the command line interface by executing `cds help`.](#cli){.learn-more} +[Learn more about the command line interface by executing `cds help`.](../tools/cds-cli#cds-help){.learn-more} diff --git a/guides/data-privacy/audit-logging.md b/guides/data-privacy/audit-logging.md index b44dcdc1f..96ede8fac 100644 --- a/guides/data-privacy/audit-logging.md +++ b/guides/data-privacy/audit-logging.md @@ -42,24 +42,25 @@ npm add @cap-js/audit-logging 1. Sets cds.requires.audit-log: true -2. Which in turn activates the `audit-log` configuration **presets**: +2. Which in turn activates the effective `audit-log` configuration via **presets**: ```jsonc { - "audit-log": { - "handle": [ "READ", "WRITE" ], - "outbox": true - "[development]": { - "impl": "@cap-js/audit-logging/srv/log2console" - }, - "[hybrid]": { - "impl": "@cap-js/audit-logging/srv/log2restv2", - "vcap": { "label": "auditlog" } - }, - "[production]": { - "impl": "@cap-js/audit-logging/srv/log2restv2", - "vcap": { "label": "auditlog" } - } - } + "audit-log": { + "handle": ["READ", "WRITE"], + "outbox": true, + "[development]": { "kind": "audit-log-to-console" }, + "[hybrid]": { "kind": "audit-log-to-restv2" }, + "[production]": { "kind": "audit-log-to-restv2" } + }, + "kinds": { + "audit-log-to-console": { + "impl": "@cap-js/audit-logging/srv/log2console" + }, + "audit-log-to-restv2": { + "impl": "@cap-js/audit-logging/srv/log2restv2", + "vcap": { "label": "auditlog" } + } + } } ``` @@ -182,7 +183,7 @@ There are two options to access audit logs: ### Behind the Scenes... -The generic audit logging implementation does the following: +For all [defined services](../providing-services#service-definitions), the generic audit logging implementation does the following: - Intercept all write operations potentially involving personal data. - Intercept all read operations potentially involving sensitive data. diff --git a/guides/databases.md b/guides/databases.md index 698000bb1..1e374f966 100644 --- a/guides/databases.md +++ b/guides/databases.md @@ -366,7 +366,10 @@ This set of functions are by large the same as specified in OData: * `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 `i` (may be negative) with length `n` (optional; may be negative) +* `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` @@ -375,12 +378,15 @@ This set of functions are by large the same as specified in OData: * `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)`, `fractionalseconds(x)`, `time(x)`, `date(x)` — +* `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` -* `maxdatetime(x)`, `mindatetime(x)` — return the maximum or minimum datetime for a given `cds.DateTime` / `cds.Date` / `cds.Time` -* `totalseconds(x)` — returns the total seconds of a datetime for a given `cds.DateTime` / `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)` `avg(x)` `count(x)`, `countdistinct(x)` — aggregate functions +* `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' diff --git a/guides/deployment/cicd.md b/guides/deployment/cicd.md index c26ac3a5a..e51fc5d6f 100644 --- a/guides/deployment/cicd.md +++ b/guides/deployment/cicd.md @@ -26,7 +26,7 @@ SAP Continuous Integration and Delivery is a service on SAP BTP, which lets you 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 [Configure and Run a Predefined SAP Continuous Integration and Delivery (CI/CD) Pipeline](https://developers.sap.com/tutorials/btp-app-ci-cd-btp.html) to configure a CI/CD pipeline that builds, tests, and deploys your code changes. +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} diff --git a/guides/security/authorization.md b/guides/security/authorization.md index 4e86bb5ff..1d71930ec 100644 --- a/guides/security/authorization.md +++ b/guides/security/authorization.md @@ -129,7 +129,7 @@ Depending on the configured [authentication](#prerequisite-authentication) strat | CAP User Property | XSUAA JWT Property | IAS JWT Property | |---------------------|----------------------------------|-------------------------| | `$user` | `user_name` | `sub` | -| `$user.tenant` | `zid` | `zone_uuid` | +| `$user.tenant` | `zid` | `app_tid` | | `$user.` | `xs.user.attributes.` | All non-meta attributes | ::: tip @@ -489,12 +489,13 @@ A service level entity can't inherit a restriction with a `where` condition that The [restrict annotation](#restrict-annotation) for an entity allows you to enforce authorization checks that statically depend on the event type and user roles. In addition, you can define a `where`-condition that further limits the set of accessible instances. This condition, which acts like a filter, establishes an *instance-based authorization*. -The condition defined in the `where`-clause typically associates domain data with static [user claims](#user-claims). Basically, it *either filters the result set in queries or accepts only write operations on instances that meet the condition*. This means that, the condition applies following standard CDS events only1: +The condition defined in the `where`-clause typically associates domain data with static [user claims](#user-claims). Basically, it *either filters the result set in queries or accepts only write operations on instances that meet the condition*. This means that, the condition applies to following standard CDS events only1: - `READ` (as result filter) -- `UPDATE` (as reject condition) -- `DELETE` (as reject condition) +- `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: @@ -518,6 +519,16 @@ Supported features are: * [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. +::: + ### User Attribute Values { #user-attrs} To refer to attribute values from the user claim, prefix the attribute name with '`$user.`' as outlined in [static user claims](#user-claims). For instance, `$user.country` refers to the attribute with the name `country`. diff --git a/java/cqn-services/remote-services.md b/java/cqn-services/remote-services.md index a2c05b139..9273f6bf6 100644 --- a/java/cqn-services/remote-services.md +++ b/java/cqn-services/remote-services.md @@ -444,8 +444,7 @@ Use the following example if the remote API supports basic authentication: ```java DefaultHttpDestination .builder("https://example.org") - .user("user") - .password("password") + .basicCredentials("user", "password") .name("my-destination").build(); ``` diff --git a/node.js/authentication.md b/node.js/authentication.md index 253b2395c..51213ebc1 100644 --- a/node.js/authentication.md +++ b/node.js/authentication.md @@ -9,16 +9,16 @@ uacp: This page is linked from the Help Portal at https://help.sap.com/products/ # Authentication -{{$frontmatter?.synopsis}} This is done by [authentication middlewares](#strategies) setting the [`req.user` property](#cds-user) which is then used in [authorization enforcement](#enforcement) decisions. +{{$frontmatter?.synopsis}} This is done by [authentication middlewares](#strategies) setting the [`cds.context.user` property](#cds-user) which is then used in [authorization enforcement](#enforcement) decisions. [[toc]] ## cds. User { #cds-user .class } [user]: #cds-user -[`req.user`]: #cds-user +[`cds.context.user`]: #cds-user -Represents the currently logged-in user as filled into [`req.user`](events#user) by authentication middlewares. +Represents the currently logged-in user as filled into [`cds.context.user`](events#user) by authentication middlewares. Simply create instances of `cds.User` or of subclasses thereof in custom middlewares. For example: @@ -26,7 +26,7 @@ For example: const cds = require('@sap/cds') const DummyUser = new class extends cds.User { is:()=>true } module.exports = (req,res,next) => { - req.user = new DummyUser('dummy') + cds.context.user = new DummyUser('dummy') next() } ``` @@ -112,7 +112,7 @@ By default, `cds.User.default` points to `cds.User.Anonymous`. However, you can ## Authorization Enforcement {#enforcement} -Applications can use the `req.user` APIs to do programmatic enforcement. +Applications can use the `cds.context.user` APIs to do programmatic enforcement. For example, the authorization of the following CDS service: ```cds @@ -132,7 +132,7 @@ can be programmatically enforced by means of the API as follows: const cds = require('@sap/cds') cds.serve ('CustomerService') .with (function(){ this.before ('*', req => - req.user.is('authenticated') || req.reject(403) + req.user.is('authenticated') || req.reject(403) ) this.before (['READ', 'CREATE'], 'Orders', req => req.user.is('admin') || req.reject(403) @@ -298,7 +298,7 @@ In contrast to [mocked authentication](#mocked), no default users are automatica This is the default strategy used in production. User identity, as well as assigned roles and user attributes, are provided at runtime, by a bound instance of the ['User Account and Authentication'](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/419ae2ef1ddd49dca9eb65af2d67c6ec.html) service (UAA). This is done in form of a JWT token in the `Authorization` header of incoming HTTP requests. -This authentication strategy also adds [`req.user.tokenInfo`](#user-token-info). +This authentication strategy also adds [`cds.context.user.tokenInfo`](#user-token-info). **Prerequisites:** You need to add [@sap/xssec](https://help.sap.com/docs/HANA_CLOUD_DATABASE/b9902c314aef4afb8f7a29bf8c5b37b3/54513272339246049bf438a03a8095e4.html#loio54513272339246049bf438a03a8095e4__section_atx_2vt_vt) to your project: ```sh @@ -322,7 +322,7 @@ npm add @sap/xssec ### XSUAA-based Authentication { #xsuaa } -Authentication kind `xsuaa` is a logical extension of kind [`jwt`](#jwt) that additionally offers access to SAML attributes through `req.user.attr` (for example, `req.user.attr.familyName`). +Authentication kind `xsuaa` is a logical extension of kind [`jwt`](#jwt) that additionally offers access to SAML attributes through `cds.context.user.attr` (for example, `cds.context.user.attr.familyName`). **Prerequisites:** You need to add [@sap/xssec](https://help.sap.com/docs/HANA_CLOUD_DATABASE/b9902c314aef4afb8f7a29bf8c5b37b3/54513272339246049bf438a03a8095e4.html#loio54513272339246049bf438a03a8095e4__section_atx_2vt_vt) to your project: ```sh @@ -348,7 +348,7 @@ npm add @sap/xssec This is an additional authentication strategy using the [Identity Authentication Service](https://help.sap.com/docs/IDENTITY_AUTHENTICATION) (IAS) that can be used in production. User identity and user attributes are provided at runtime, by a bound instance of the IAS service. This is done in form of a JWT token in the `Authorization` header of incoming HTTP requests. -This authentication strategy also adds [`req.user.tokenInfo`](#user-token-info). +This authentication strategy also adds [`cds.context.user.tokenInfo`](#user-token-info). To allow forwarding to remote services, JWT tokens issued by IAS service don't contain authorization information. In particular, no scopes are included. Closing this gap is up to you as application developer. @@ -384,14 +384,14 @@ You can configure an own implementation by specifying an own `impl` as follows: Essentially, custom authentication middlewares must do two things: -First, they _must_ [fulfill the `req.user` contract](#cds-user) by assigning an instance of `cds.User` or a look-alike to the incoming request at `req.user`. +First, they _must_ [fulfill the `cds.context.user` contract](#cds-user) by assigning an instance of `cds.User` or a look-alike to the continuation of the incoming request at `cds.context.user`. -Second, if running in a multitenant environment, `req.tenant` must be set to a string identifying the tenant that is addressed by the incoming request. +Second, if running in a multitenant environment, `cds.context.tenant` must be set to a string identifying the tenant that is addressed by the incoming request. ```js module.exports = function custom_auth (req, res, next) { // do your custom authentication - req.user = new cds.User({ + cds.context.user = new cds.User({ id: '', roles: ['', ''], attr: { @@ -399,7 +399,7 @@ module.exports = function custom_auth (req, res, next) { : '' } }) - req.tenant = '' + cds.context.tenant = '' } ``` diff --git a/node.js/cds-compile.md b/node.js/cds-compile.md index 5f8df6b80..98bf50c39 100644 --- a/node.js/cds-compile.md +++ b/node.js/cds-compile.md @@ -40,7 +40,6 @@ It supports different variants based on the type of the first argument `model` a Depending on the variants, the method returns a Promise or a sync value. - ### Compiling `.cds` files (async) If the first argument is either a string starting with `"file:"`, or an _array_ of filenames, these files are read and compiled to a single CSN asynchronously: @@ -53,6 +52,9 @@ let csn = await cds.compile ('file:db') > The given filenames are resolved to effective absolute filenames using [`cds.resolve`](#cds-resolve). +> [!TIP] Use cds compile as CLI equivalent +> The [`cds compile` CLI](../tools/cds-cli#cds-compile) is available as entry point to the functions described here. For example, `cds compile --to hana` maps to `cds.compile.to.hana` etc. + ### Single in-memory sources @@ -440,7 +442,7 @@ cds.on('compile.to.edmx', ...) > As we're using Node's standard [EventEmitter](https://nodejs.org/api/events.html#asynchronous-vs-synchronous), > event handlers execute **synchronously** in the order they are registered. -> [!tip] Note that several of these events coud be emitted for the same model, so ensure your handlers are idempodent. +> [!tip] Note that several of these events could be emitted for the same model, so ensure your handlers are idempotent. ### compile.for.runtime {.event} diff --git a/node.js/cds-serve.md b/node.js/cds-serve.md index 351ce9f32..abb234700 100644 --- a/node.js/cds-serve.md +++ b/node.js/cds-serve.md @@ -296,9 +296,9 @@ Be aware that overriding requires constant updates as new middlewares by the fra [Learn more about the middlewares default order.](#cds-middlewares){.learn-more} -#### Customization of `req.user` +#### Customization of `cds.context.user` -You can register middlewares to customize `req.user`. +You can register middlewares to customize `cds.context.user`. It must be done after authentication. If `cds.context.tenant` is manipulated as well, it must also be done before `cds.context.model` is set for the current request. diff --git a/node.js/events.md b/node.js/events.md index 10adc2207..294bf50dd 100644 --- a/node.js/events.md +++ b/node.js/events.md @@ -137,6 +137,11 @@ The current user, an instance of `cds.User` as identified and verified by the au [See reference docs for `cds.User`.](authentication#cds-user){.learn-more .indent} +::: tip +Please note the difference between `req` in a service handler (instance of `cds.EventContext`) and `req` in an express middleware (instance of `http.IncomingMessage`). +Case in point, `req.user` in a service handler is an official API and, if not explicitely set, points to `cds.context.user`. +On the other hand, setting `req.user` in a custom authentication middleware is deprecated. +::: diff --git a/package-lock.json b/package-lock.json index b0de7ec39..174cae6e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1450,9 +1450,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", - "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1511,9 +1511,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", - "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true, "license": "MIT", "engines": { @@ -1531,12 +1531,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", - "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.10.0", "levn": "^0.4.1" }, "engines": { @@ -2293,9 +2294,9 @@ ] }, "node_modules/@sap/cds": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.6.0.tgz", - "integrity": "sha512-MagthrcmAa1l+nAtx/4gMnDv9scfkIwXPFQT7N8+dLU0u1DitLePA5nYk9M62wHZy79mE1tPwxdoLS2NdMzQQw==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.6.1.tgz", + "integrity": "sha512-JYHRrGs6Tgle5Vmj/o3BaQkOBVcroweOrXhhiUVH6twISy+Yi2cWZdTr0EFFEt94FI1dVqvrVnEM67jEjOQImQ==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { @@ -4278,19 +4279,19 @@ } }, "node_modules/eslint": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", - "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.9.0", + "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.17.0", - "@eslint/plugin-kit": "^0.2.3", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", diff --git a/tools/assets/help/cds-compile.out.md b/tools/assets/help/cds-compile.out.md new file mode 100644 index 000000000..2479f58c0 --- /dev/null +++ b/tools/assets/help/cds-compile.out.md @@ -0,0 +1,130 @@ + +
+> cds compile --help
+
+SYNOPSIS
+  cds compile <models> [<options>]
+
+  Compiles the specified models to CSN format, applying processors to unfold
+  and generate target outputs using the <options>.
+  
+
+OPTIONS  
+
+  -2 | --to <target format>
+
+    Compiles the given models to the specified <target format>.
+    Currently supported:
+
+    - json, yml
+    - edm, edmx, edmx-v2, edmx-v4, edmx-w4, edmx-x4
+    - sql, hdbcds, hdbtable, hana
+    - cdl
+    - xsuaa
+    - openapi
+    - asyncapi
+
+  -4 | --for <target>
+
+    Unfolds the compiled CSN for the specified <target> usages,
+    or get a comma-separated list, without generating target formats.
+    Currently supported:
+
+    - odata
+    - sql
+
+  --dialect <dialect>
+
+    Needs option --to.
+    Specify the dialect in combination with --to sql.
+    Currently supported:
+
+    - sqlite
+    - h2
+    - postgres
+    - hana
+
+  -s | --service <name> | all
+
+    Chooses a specific service or all to force output for all services.
+    The service name must be fully qualified, including the namespace, if any.
+
+  -l | --lang <languages> | all
+
+    Localizes the output with given <languages>, a comma-separated list
+    of language/locale codes or all.
+    Localization is carried out before all other processors (-4/u) or backends (-2).
+
+  -o | --dest <folder>
+
+    Writes output to the given folder instead of stdout.
+
+  -f | --flavor sources | files | parsed | xtended | inferred
+
+    Depending on the argument, returns a model with the given level of detail:
+
+      sources:  paths and content of all resolved source files
+      files:    paths of all effectively referenced files
+      parsed:   the definitions and extensions, without applying the
+                extensions or includes, and without imported definitions.
+      xtended:  the definitions with all imports and extensions resolved,
+                but without any derived information
+      inferred: the effective model, including imported definitions, extensions,
+                and derived information.  This is the default flavor.
+
+  --parse
+
+    Shortcut for '--flavor parsed'
+
+  --plain
+
+    Shortcut for '--flavor xtended'
+
+  --docs
+
+    Preserves /**...*/ doc comments in 'doc' properties of CSN outputs,
+    as well as in 'Core.Description' annotations of EDMX outputs.
+
+  --locations
+
+    Preserves $location properties of CSN outputs.
+
+  --log-level debug | info | warn | error
+
+    Chooses which level of compiler messages to log. The default log-level is warn.
+
+  --openapi:url <Server URL for Open API export>
+
+    The server URL used in the generated OpenAPI document. The default is the service
+    base path as declared in the CDS source.
+    Use the ${service-path} variable to have the service path included in the URL.
+
+  --openapi:servers <Stringified JSON Object for Open API export>
+
+    The servers definition used in the generated OpenAPI document. --openapi:url is
+    ignored when this option is specified.
+
+    --odata-version 4.0|4.01
+
+    Adds the OData version's functionality of the input CDS/CSN file to the generated OpenAPI document.
+
+  --openapi:diagram
+
+    Include YUML diagram in the generated OpenAPI document, default: false.
+
+  --openapi:config-file filename
+
+    The passed configuration file will be read to generate the OpenAPI document, incorporating all specified options.
+    Precedence of Options: Inline options specified in the command line will take precedence over those defined in the configuration file.
+
+  --asyncapi:merged
+
+    A single AsyncAPI document is generated using the details of all input services. Information of title
+    and version should be provided as preset.
+
+EXAMPLES
+   cds compile model.cds
+   cds c model.json --to sql
+   cds srv -s all -l all -2 edmx -o out
+   cds compile srv -s sap.sample.TestService -2 asyncapi -o out
+
diff --git a/tools/assets/help/cds-env.out.md b/tools/assets/help/cds-env.out.md new file mode 100644 index 000000000..e3966b940 --- /dev/null +++ b/tools/assets/help/cds-env.out.md @@ -0,0 +1,46 @@ + +
+> cds env --help
+
+SYNOPSIS
+    cds env [<key>] [<options>]
+
+EXPLANATION
+    Displays the effective configuration for the given key, or all of the
+    current environment.
+
+OPTIONS
+    --sources
+
+       Lists the sources from with the current env has been compiled.
+
+    -k | --keys
+
+       Prints (top-level) keys of matching properties only
+
+    -p | --properties
+    -l | --list
+
+       Prints output in .properties format
+
+    -j | --json
+
+       Prints output in JSON format
+
+    -r | --raw
+
+       Prints output with minimum formatting or decoration
+
+    -4 | --for | --profile <profile,...>
+
+       Load configuration for the specified profile(s).
+       The development profile is used by default.
+
+    -P | --process-env
+
+       Show properties from Node.js process.env.
+
+    -b | --resolve-bindings
+
+       Resolve remote service bindings configured via cds bind.
+
diff --git a/tools/assets/help/cds-init.out.md b/tools/assets/help/cds-init.out.md new file mode 100644 index 000000000..78c29e8af --- /dev/null +++ b/tools/assets/help/cds-init.out.md @@ -0,0 +1,90 @@ + +
+> cds init --help
+
+SYNOPSIS
+    cds init [<project>] [<options>]
+
+    Initializes a new project in folder ./<project>, with the current
+    working directory as default.
+
+OPTIONS
+    --java
+
+        Create a CAP Java project.
+
+    --add <feature | comma-separated list of features>
+
+        Add one or more features while creating the project.
+        <feature> can be one of the following:
+
+      completion                   - shell completion for cds commands
+      java                         - creates a Java-based project
+      nodejs                       - creates a Node.js-based project
+      esm                          - ESM-compatible Node.js project
+      tiny-sample                  - add minimal sample files
+      sample                       - add sample files including Fiori UI
+      typer                        - type generation for CDS models
+      typescript                   - add minimum configuration for a bare TypeScript project
+      handler                      - handler stubs for service entities, actions and functions
+      mta                          - Cloud Foundry deployment using mta.yaml
+      cf-manifest                  - Cloud Foundry deployment using manifest files
+      helm                         - Kyma deployment using Helm charts
+      helm-unified-runtime         - Kyma deployment using Unified Runtime Helm charts
+      containerize                 - containerization using ctz CLI
+      multitenancy                 - schema-based multitenancy support
+      toggles                      - allow dynamically toggled features
+      extensibility                - tenant-specific model extensibility
+      side-by-side-extensibility   - logic extensibility via extension points
+      mtx                          - multitenancy + toggles + extensibility
+      xsuaa                        - authentication via XSUAA
+      ias                          - authentication via IAS
+      ams                          - authorization via AMS
+      hana                         - database support for SAP HANA
+      postgres                     - database support for PostgreSQL
+      sqlite                       - database support for SQLite
+      h2                           - database support for H2
+      liquibase                    - database migration using Liquibase
+      redis                        - SAP BTP Redis, Hyperscaler Option
+      attachments                  - SAP BTP Object Store Service
+      malware-scanner              - SAP Malware Scanning Service
+      local-messaging              - messaging via local event bus
+      file-based-messaging         - messaging via file system
+      enterprise-messaging         - messaging via SAP Enterprise Messaging
+      enterprise-messaging-shared  - messaging via shared SAP Enterprise Messaging
+      redis-messaging              - messaging via Redis
+      kafka                        - messaging via Apache Kafka
+      approuter                    - dynamic routing using @sap/approuter
+      connectivity                 - SAP BTP Connectivity Service
+      destination                  - SAP BTP Destination Service
+      html5-repo                   - SAP BTP HTML5 Application Repository
+      portal                       - SAP BTP Portal Service
+      application-logging          - SAP BTP Application Logging Service
+      audit-logging                - SAP BTP Audit Logging Service
+      notifications                - SAP BTP Notification Service
+      workzone-standard            - SAP BTP Work Zone, Standard Edition
+      data                         - add CSV headers for modeled entities
+      http                         - add .http files for modeled services
+      lint                         - configure cds lint
+      pipeline                     - CI/CD pipeline integration
+
+    --java:mvn <Comma separated maven archetype specific parameters>
+
+        Add the given parameters to the archetype call.
+        See https://cap.cloud.sap/docs/java/developing-applications/building#the-maven-archetype
+        for parameters supported by the archetype.
+
+    --force
+
+        Overwrite all files.
+
+EXAMPLES
+    cds init bookshop
+    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
+
+SEE ALSO
+    cds add - to augment your projects later on
+
diff --git a/tools/assets/help/cds-watch.out.md b/tools/assets/help/cds-watch.out.md index 21281a3a9..a19040e0d 100644 --- a/tools/assets/help/cds-watch.out.md +++ b/tools/assets/help/cds-watch.out.md @@ -24,6 +24,14 @@ Specify file extensions to watch for in a comma-separated list. Example: cds w --ext cds,json,js. + --include <paths,...> + + Comma-separated list of additional paths to watch. + + --exclude <paths,...> + + Comma-separated list of additional paths to ignore. + --livereload <port | false> Specify the port for the livereload server. Defaults to '35729'. diff --git a/tools/cds-cli.md b/tools/cds-cli.md index 1bd640cde..b50d8678d 100644 --- a/tools/cds-cli.md +++ b/tools/cds-cli.md @@ -82,7 +82,7 @@ Use `cds help` to see an overview of all commands: Use `cds help ` or `cds ?` to get specific help: - + ## cds init @@ -102,6 +102,9 @@ For example to create a project with a sample bookshop model and configuration f cds init --add sample,hana ``` +::: details See the full help text of `cds init` + +::: ## cds add @@ -362,9 +365,22 @@ Use `cds env` to inspect currently effective config settings: +::: details See the full help text of `cds env` + +::: + ## cds compile +Compiles the specified models to [CSN](../cds/csn) or other formats. + +[See simple examples in the getting started page](../get-started/in-a-nutshell#cli).{.learn-more} + +[For the set of built-in compile 'formats', see the `cds.compile.to` API](../node.js/cds-compile#cds-compile-to).{.learn-more} + + +In addition, the following formats are available: + ### mermaid {.compile} This produces text for a [Mermaid class diagram](https://mermaid.js.org/syntax/classDiagram.html): @@ -428,6 +444,24 @@ To customize the diagram layout, use these settings in the _Cds > Preview_ categ - [Diagram: Namespaces](vscode://settings/cds.preview.diagram.namespaces) - [Diagram: Queries](vscode://settings/cds.preview.diagram.queries) +## cds watch + +Use `cds watch` to watch for changed files, restarting your server. + +::: details See the full help text of `cds watch` + +::: + +### Includes and Excludes + +Additional watched or ignored paths can be specified via CLI options: + +```sh +cds watch --include ../other-app --exclude .idea/ +``` + +Alternatively, you can add these paths through settings cds.watch.include: ["../other-app"] and cds.watch.exclude: [".idea"] to your project configuration. + ## cds repl