@sap/cds
Version:
SAP Cloud Application Programming Model - CDS for Node.js
923 lines (698 loc) • 63.2 kB
Markdown
# Change Log
- All notable changes to this project are documented in this file.
- The format is based on [Keep a Changelog](https://keepachangelog.com/).
- This project adheres to [Semantic Versioning](https://semver.org/).
## Version 9.6.3 - 2026-01-14
### Fixed
- `queue`: Exactly-once guarantee only with `legacyLocking: false`
## Version 9.6.2 - 2026-01-08
### Fixed
- Consider `@mandatory.message` for the error message, when a mandatory action / function parameter is not provided
- Respond with error code `400` when receiving requests that use `any()` / `all()` filters on an association to one
- Error message of unknown property check will no longer include `undefined` to identify structs without a name
- `enterprise-messaging`: Type error in check for unofficial XSUAA fallback
- Status Transition Flows: Exclusions for multiple projections
## Version 9.6.1 - 2025-12-18
### Fixed
- Status check in case of non-existing subject
- Gracefully handle bad value when calculating `@Core.OperationAvailable` from `@from`
## Version 9.6.0 - 2025-12-16
### Added
- New config entry `cds.folders.apps = 'app/*'` to fetch and load all .cds files from subfolders of `./app` automatically. This eliminates the need for an `./app/index.cds` file with respective `using` directives. Can be disabled by setting `cds.folders.apps` to `false`.
- Support for direct CRUD on draft-enabled entities (beta)
+ Enable via `cds.fiori.direct_crud` (replacing `cds.features.new_draft_via_action`)
+ In such requests, `IsActiveEntity` is defaulted to `true`
- Columns `task` and `appid` to `cds.outbox.Messages`
- `cds.env` getter for `appid`
### Changed
- Improved Event Queue Processing
+ For db-only message processors, the guarantee is now "exactly once" instead of "at least once".
+ Use default target `queue` unless specified (formerly it was the name of the service). In effect, all services with the default queue config are processed together.
- Cleaned-up Model Reflection APIs
+ `cds.entities` and `model.entities` provide access to all entities, not just the ones matching the first sources' namespace
+ Function usage `cds.entities()` without passing a namespace no longer offers unqualified access to the entities of the first sources' namespace
+ `srv.entities` returns `LinkedDefinitions` for that service
+ Undocumented function usages `srv.entities()`, `srv.types()`, `srv.events()`, and `srv.actions()` are officially deprecated and will be removed with `cds^10`.
+ For `srv.entities()`, use `cds.entities()` instead. The others have no replacement. Simply use `srv.types`, `srv.events`, and `srv.actions`.
+ All `.entities` variants only provide `.texts` entities if `cds.features.compat_texts_entities = true` (default until `cds^10`). Use `.texts` property of the respective entity instead (i.e., `CatalogService.Books.texts` instead of `CatalogService['Books.texts']`).
### Fixed
- Actions rejected with `415` for requests with empty body
- `cds.parse.expr` with template literals using "param" as parameter name
- Kafka messaging won't listen for messages without registered on handlers
- Single quote escaping in remote OData requests
- Lambda prefix within function calls in remote OData requests
- Hierarchy requests with `$top` in combination with `$filter`
- Response format of `ASSERT_DATA_TYPE` errors with draft messages
- Deletion of `@assert` draft messages on SAVE
- Check for `process.env.VCAP_SERVICES_FILE_PATH` in logging aspects enterprise messaging tasks
- Remove control data from deserialized task
- Hierarchy draft requests with $filter
## Version 9.5.2 - 2025-12-09
### Fixed
- Usage of associations in `@assert`
- Usage of `@assert` on child entities
- Mocking of remote services using `srv.post('<url>')`
## Version 9.5.1 - 2025-12-01
### Fixed
- Draft child creation in case `cds.features.new_draft_via_action` is enabled
- Draft messages of declarative constraints
- Persisted draft messages in case of on-commit errors
- Async UCL tenant mapping for UCL SPII v2
- Quoting in `cds.compile.to.yaml`
## Version 9.5.0 - 2025-11-26
### Added
- Support for Declarative Constraints (`@assert`; beta)
- Status Transition Flows (`@flow`; beta):
+ Aspect `sap.common.FlowHistory` automatically appended to entities with a `@to: $flow.previous`
+ Deactivate via `cds.features.history_for_flows=false`
+ Experimental: Via `cds.features.history_for_flows='all'`, all entities with a flow definition get appended
+ Note: FlowHistory is not maintained within drafts
+ Support for `@flow.status: <element name>` on entity level
+ UI annotation generation adds action to UI automatically (Object Page and List Report) but hidden in draft mode
+ Experimental support for CRUD flows:
+ Pseudo bound actions `CREATE` and `UPDATE` events can be flow-annotated
+ Note: The `CREATE` event cannot have a `@from` condition
+ Pseudo bound actions for drafts `NEW`, `EDIT`, `PATCH`, `DISCARD`, and `SAVE` can be flow-annotated
+ Note: Flow annotations inside drafts (`@from`, `@to`) are processed as in standard flow transitions, with the following exceptions:
+ The `NEW` event cannot have a `@from` condition
+ The `DISCARD` event cannot have a `@to` condition
- Support for pseudo protocols
- Support for Async UCL tenant mapping notification flow
- `flush` on a queued service returns a Promise that resolves when immediate work (i.e., not scheduled for future) is processed
- Support for `@Common.DraftRoot.NewAction` annotation with feature flag `cds.features.new_draft_via_action`
+ Generic collection bound action `draftNew` will be added to draft enabled entities
+ The action specified in the annotation will be rewritten into a draft `NEW` event
+ Active instances of draft enabled entities can be created directly via `POST`
- Limited support for `$compute` query option: computed properties are only supported in `$select` at the root level, not in expanded entries or other query options. Only numeric operands and operators `add`, `sub`, `-`, `mul` and `div` are supported
- `ias-auth`: configurable name for XSUAA fallback's `cds.requires` entry
- `enterprise-messaging`: Support for scenario `ias-auth` with XSUAA fallback
- Service configuration through `VCAP_SERVICES` can now be supplied with `VCAP_SERVICES_FILE_PATH`. Note that this is an experimental CF feature.
### Changed
- Internal service `UCLService` moved into non-extensible namespace `cds.core`
- Status Transition Flows (`@flow`; beta):
+ UI annotation generation is on by default. Switch off via `cds.features.annotate_for_flows=false`.
+ Feature flag `cds.features.compile_for_flows` renamed to `cds.features.annotate_for_flows`
- `DELETE` requests during draft edit, that do not use containment will cause persisted draft messages to be cleared
### Fixed
- Correctly format values in a where clause send to an external OData service, when the expression order is: value, operator, reference
- cds.ql: tolerate extra spaces after in; parse RHS arrays of values as list
- CRUD-style API: `cds.read()` et al. used without `await` do not throw if there is no database connected
- Unnecessary compilation of model for edmx generation in multitenancy cases
- Using `req.notify`, `req.warn` and `req.info` in custom draft handlers by collecting validation errors in a dedicated collection
- `cds.auth` factory: passed options take precedence
- `cds deploy --dry` no longer produces broken SQL for DB functions like `days_between`.
- Read-after-write for create events during draft choreography will no longer include messages targeting siblings
- `before` and `after` handlers now really run in parallel. If that causes trouble, you can restore the previous behavior with `cds.features.async_handler_compat=true` until `@sap/cds@10`.
- Escaping of JSON escape sequences during localization
- Persisted draft messages in case of on-commit errors
## Version 9.4.5 - 2025-11-07
### Fixed
- Custom error message for `@assert.range`
- For hierarchy requests with `$filter`, properly remove inner `where` clause
- Calling a parameterless function with parameter
- Aligned error handling for path navigation and `$expand`
- Input validation immediately rejects for `@mandatory`
## Version 9.4.4 - 2025-10-23
### Fixed
- Input validation of action parameters in action calls on draft state of draft enabled entities
- Input validation on `NEW` event of draft choreography
- Ignore outbox model on Windows
- `enterprise-messaging-shared`: preserve error listener during reconnect
## Version 9.4.3 - 2025-10-10
### Fixed
- Don't continue validation user input if data type is wrong
- UI annotation generation for status transition flows for Java
- Increased minimium version of `@sap/cds-compiler` to 6.3.x
- Undefined error message for early access checks
## Version 9.4.2 - 2025-10-08
### Fixed
- `DISCARD` as a synonym for `CANCEL`
- `cds.load()` called twice
## Version 9.4.1 - 2025-10-06
### Fixed
- Default `kind` for unknown required service to `hcql`
- Consider and allow aliases from nesting during OData query validation
## Version 9.4.0 - 2025-09-30
### Added
- Status Transition Flows (`@flow`; alpha):
+ Resolve enum references in `@from`/`@to` values
+ Support for `@to: $flow.previous` (transition to the previous status in a flow)
+ Use `cds.env.features.flows_history_stack=true` to switch from history (default) to stack-based behavior
+ Requires adding aspect `sap.common.FlowHistory` to the respective entity
- `i18n` translations for `@assert` messages
- `SELECT ... .stream ()` returns the data from the database as a raw stream
- `cds.validate` treats `@insertonly` elements as immutable
- Vietnamese translations for texts from `@sap/cds/common`
- `ias`/`jwt`/`xsuaa`-auth: Add token payload (as `token_payload`) to warning log in case of an invalid token
+ Note: Some invalid tokens are (for performance reasons) not fully validated and, hence, the payload may not be trusted!
### Changed
- `SAVE` handlers for drafts are triggered when a draft is activated
+ Opt-out until cds^10 with `cds.features.compat_save_drafts=true`
- Improved default error messages for input validation.
- Renamed error key for validation errors of `@mandatory` from `ASSERT_NOT_NULL` to `ASSERT_MANDATORY`
+ For i18n message lookup, an automatic fallback is implemented.
+ Opt-out until cds^10 with `cds.features.compat_assert_not_null=true`
- Errors are collected for `_initial` (internal!) and `before` phase
### Fixed
- Duplicate reconnects in AMQP
- `ASSERT_FORMAT` errors return correct regexp in message
- Crash by draft validation with (custom) error w/o target
- Fixed issue where `' $'` in payloads of batch requests would be prefixed with `'/'`
- Broken link `cds.auth`
- Persist original error message in draft validation messages
- Escaping of `\t` and `\f` in edmx during localization
## Version 9.3.1 - 2025-09-03
### Fixed
- In messaging services, propagated headers (e.g. `x-correlation-id`) will not be automatically propagated for `format: 'cloudevents'`
- Avoid deprecation warning for `cds.context.user.tokenInfo`
- Consider `@Capabilities.ExpandRestrictions.NonExpandableProperties` annotation and ignore fields referenced by the annotation, when rewriting asterisk expand into columns
## Version 9.3.0 - 2025-08-29
### Added
- New method `collect()` has been added to `LinkedCSN`, which can be used like that:
```js
const federated_entities = cds.linked(csn).collect (d => d.is_entity && d['@federated'])
```
- Remote services can now be configured without `kind`, for example:
```json
{ "cds": { "requires": { "SomeService": true }}}
```
- Automatic protocol selection is applied if a required service is configured as above
and the remote services is served via multiple protocols. For example, if the above
service would be declared like that, the best protocol would be chosen automatically
(`hcql` in this case):
```cds
@hcql @rest @odata service SomeService {...}
```
- Method `cds.connect.to()` now allows to connect to remote services with just an http url.
For example use that from `cds repl` like that:
```js
srv = await cds.connect.to ('http://localhost:4004/hcql/books')
await srv.read `ID, title, author.name from Books`
```
- Property `cds.User.authInfo` as generic container for authentication-related information
+ For `@sap/xssec`-based authentication strategies, `cds.context.user.authInfo` is an instance of `@sap/xssec`'s `SecurityContext`
- Support for status transition flows (`@flow`; alpha):
+ Generic handlers for validating entry (`@from`) and exit (`@to`) states
+ Automatic addition of necessary annotations for Fiori UIs (`@Common.SideEffects` and `@Core.OperationAvailable`) during compile to EDMX with feature flag `cds.features.compile_for_flows = true`
- Experimental support for consuming remote HCQL services (`cds.requires.<remote>.kind = 'hcql'`)
- Infrastructure for implementing the tenant mapping notification of Unified Customer Landscape's (UCL) Service Provider Integration Interface (SPII) API
+ Bootstrap the `UCLService` via `cds.requires.ucl = true` and implement the assign and unassign operations like so:
```js
// custom server.js
cds.on('served', async () => {
const ucl = await cds.connect.to('ucl')
ucl.on('assign', async function(req) { ... })
ucl.on('unassign', async function(req) { ... })
})
```
+ Currently, only the synchronous interaction pattern is supported!
- The targets of `@Common.Text` are added to the default search targets
- Patch Level Validations are enabled by default. Opt-out with `cds.fiori.draft_messages=false`
- Enable custom aggregations for currency codes and units of measure
### Changed
- `UCLService` only pushes the application template to UCL if `cds.requires.ucl.applicationTemplate` is present
- `cds.User.tokenInfo` is deprecated. Use `cds.context.user.authInfo.token` instead.
- Undocumented compat `cds.context.http.req.authInfo` is deprecated. Use `cds.context.user.authInfo` instead.
- Delete all persisted draft messages, when the first request targeting a draft child without containment is handled.
- cds build now trims leading or trailing whitespace characters for all values in CSV files deployed to SAP HANA.
### Fixed
- Errors when reading complementary drafts
- Apply configurations in case `cds.env` was loaded before `cds.log` is initialized.
- `req.diff` resolves correctly deleted nested composition by deep update
- `cds-deploy` did not terminate correctly even though deployment was successful
- Requests to an unimplemented unbound action/ function are rejected
- Custom app-service implementations configured through `cds.requires.app-service.impl` is now correctly resolved (again)
- Validation of UUID format for navigation by key
### Removed
- Internal property `cds.services._pending` was removed => use `cds.services` instead.
- Internal property `srv._is_dark` was removed => use `!srv.endpoints?.length` instead.
- Internal method `cds.env.requires._resolved` was removed => use `cds.requires` instead.
## Version 9.2.1 - 2025-08-15
### Fixed
- Check whether token validation was configured
- `UPDATE(Foo).with`foo=${'bar'}` erroneously constructed the equivalent of `UPDATE(Foo).with`foo=bar` instead of `UPDATE(Foo).with`foo='bar'`
- Errors in emits for file-based messaging are thrown
- Queue: Ensure `method`, `path`, `entity` and `params` are correctly taken over when creating tasks
- Reject navigations in `$expand` without parsing the navigation path
## Version 9.2.0 - 2025-07-29
### Added
- `srv.schedule` allows to specify the time in a more readable way, e.g. `srv.schedule(...).after('1min')`
- Support for `jwt`/`xsuaa`-auth on XSA
- Enable `@sap/xssec`'s caching mechanisms (requires `@sap/xssec^4.8`)
+ The signature cache can be configured via `cds.requires.auth.config`, which is passed to `@sap/xssec`'s authentication services
+ The token decode cache can be configured programmatically via `require('@sap/xssec').Token.enableDecodeCache(config?)` and deactivated via `require('@sap/xssec').Token.decodeCache = false`
- `cds.requires` correctly resolve service credentials on Kyma when its merged env configuration is only `true` and the service is found via its property name.
- `ias`-auth: Support for fallback XSUAA-based authentication meant to ease migration to IAS
+ The fallback is automatically enabled if XSUAA credentials are available. To enable the credentials look-up, simply add `cds.requires.xsuaa = true` to your env.
+ In case you need a custom config for the fallback (passed through to `@sap/xssec` as is!), configure it via `cds.requires.xsuaa = { config: { ... } }`
- Better error message if `cds.xt.Extensions` table is missing in extensibility scenarios.
### Changed
- Upgrade to Peggy 5 version
- Enabled conversion of `not exists where not` to OData `all`, integrating the inverse of the policy applied by the OData parser.
- Numeric values in `.csv` files are now returned as numbers instead of strings, e.g. `1` instead of `'1'`;
when pre-padded with zeros, e.g., `0123`, they are returned as strings, e.g. `'0123'` instead of `123`.
### Fixed
- Runtime error in transaction handling in messaging services when used with outbox
- Always use `cds.context` middleware for `enterprise-messaging` endpoints
- Crash during Location header generation caused by custom response not matching the entity definition.
- Support for logging of correct error locations with `cds watch` and `cds run`.
- Double-unescaping of values in double quotes during OData URL parsing
- Throw explicit error if the result of a media data query is not an instance of `Readable`, rather than responding with `No Content`
- When loading `.csv` files quoted strings containing the separator (comma or semicolon) where erroneously
parsed as two separate values instead of one.
## Version 9.1.0 - 2025-06-30
### Added
- CDS config schema validations for `cds.requires.auth.tenants`, `cds.cdsc`, `cds.query`, `cds.log`, `cds.server`
- Queue option `targetPrefix` to prefix `target` value of `cds.outbox.Messages` entries for microservice isolation
- Basic support for CRUD for hierarchy entities
### Changed
- Reduced the amount of SELECT nesting the OData adapter does for `$apply` queries.
- Better error messages for unresolved parent associations in hierarchy requests.
- Enabled updated behavior of `draftActivate` to move updates to fields of draft enabled entities with type `cds.LargeBinary` from draft to active table on the database level, with feature flag `cds.env.fiori.move_media_data_in_db`.
### Fixed
- Copies of `cds.context` with `locale`
- Support for relative paths in `@odata.bind`
- `cds build` on Windows OS - fixed cli tar usage for resources.tgz
- Actions and functions with scalar return types use same `@odata.context` calculation as other return types, fixing e.g. `cds.odata.contextAbsoluteUrl` not being respected
- Improve content-type and content-length handling in OData adapter
- Parsing incorrect function parameters
- `cds deploy --dry` no longer tries to load a DB adapter, so that it works w/o one installed.
- Fix `@mandatory` for actions and functions
## Version 9.0.4 - 2025-06-18
### Fixed
- In some cases, the app crashed if an element was named like a reserved CSN key.
- Locale detection does not enforce `<http-req>.query` to be present. Some protocol adapters do not set it.
- `between` operator for remote OData requests
- `cds serve/watch` and `cds.test()` no longer try to connect to an SQLite database if none is configured.
- `cds.connect.to` for required queueable services if no persistence is configured
- Persistent queue is not enabled if no persistence is configured
## Version 9.0.3 - 2025-06-04
### Fixed
- Handling of bad timestamps in URL ($filter and temporals)
- View metadata for requests with $apply
- Server crash for some URLs
## Version 9.0.2 - 2025-05-28
### Changed
- REVERT: For drafts, read-only fields must be set in `CREATE` handlers (calculated values set in `NEW` handlers are cleansed). If children are added in draft `CREATE` handlers, the field `DraftAdministrativeData_DraftUUID` must be set.
### Fixed
- `cds.load()` ignores the outbox model if it's the only model source, helping `watch` to suppress it as well.
## Version 9.0.1 - 2025-05-26
### Changed
- Lean draft handler is registered in a service only if a draft-enabled service entity exists
- Add back in server version on CAP server launch info log record
### Fixed
- `cqn2odata`: value formatting in OData v4 lambda expressions
- Processing in `filed-based-messaging` must be async
- `Location` response header for REST protocol
- `cds.log` is unwired from `cds.env` now, which allows to use `cds.log` in plugins, without risk of loading `cds.env` too early.
- Elements from `mixin` are now being considered by `minify`
- Lean draft: Insert.entries on draft enabled entity
- Remote call of action/function always forwards passed headers
- `cds serve` no longer fails with an duplicate install error if the shell's working directory differs in case (like `C:` vs `c:` on Windows).
- Erroneously skipped input validation for local service calls
## Version 9.0.0 - 2025-05-07
### Added
- CAP-native task queues (beta; replacing generic outbox -- see section Changed for additional details)
+ Events and requests to a "queued service" are written to the database in the current transaction (with default kind `persistent-queue`) and processed as asynchronous tasks
+ Programmatically queue or unqueue any service via `cds.queued(srv)`/ `cds.unqueued(srv)`
+ Statically queue instances of `cds.MessagingService` or `AuditLogService` via config `cds.requires.<srv>.queued = true`
+ Disable the persistent task queue via `cds.requires.queue = false`
+ Tasks are processed in dedicated transactions (except on SQLite, where there are no concurrent transactions)
+ Tasks are retried until processed succesfully or the max. retry count is reached, i.e., adding resiliency to the respective service
+ Tasks that cause unrecoverable or programming errors will remain in the database table but will not be retried
+ Experimental task scheduling API `<srv>.schedule()` as variant of `<srv>.send()` with fluent API options `.after(<ms>)` and `.every(<ms>)`
+ Experimental task callback API `<srv>.after('<event>/#succeeded', (results, req))`/ `<srv>.after('<event>/#failed', (error, req))`
+ Experimental task trigger API `<srv>.flush()`
+ Experimental application-level task status management to avoid long-lasting database locks
+ Enable via `cds.requires.queue.legacyLocking = false`
+ Caution: Application-level task status management only works if all active app deployments are on cds^9!
- Inbox: Inbound messages can be accepted as asynchronous tasks via config `cds.requires.messaging.inboxed = true`
- Not null validiations for actions and functions
- `cds.auth`: Provide custom configuration to `@sap/xssec`-based authentication via `cds.requires.auth.config`
- IAS: Token validation for requests to the app's "cert url" (with `.cert` segment in the domain)
- Support refs with longer path expressions like `ref: ['root', 'child', 'subchild', 'ID']` when resolving queries to the target entity
- `PATCH` as synonym for `UPDATE` during event handler registration
- `UPSERT` semantics for `PUT` requests can be deactivated via flag `cds.runtime.put_as_upsert=false`
### Changed
- Evolution of the generic outbox to CAP-native task queues:
+ `cds.queued()`/ `cds.unqueued()` replace `cds.outboxed()`/ `cds.unboxed()` (temporary compat in place)
+ Global configuration `cds.requires.queue` replaces `cds.requires.outbox` (temporary compat in place)
+ New default `cds.requires.queue = true`. This change requires a database deployment (for table `cds.outbox.Messages`) if `cds.requires.outbox` was not manually set to `true` before.
+ Default `chunkSize` reduced from `100` to `10`. If parallel processing is disabled (`parallel = false`), the `chunkSize` config is ignored and the effective `chunkSize` is `1`.
- Support for `@sap/cds-mtxs` version 1 is dropped
- Service level restrictions for application service calls are enforced by default
+ Opt out with `cds.features.service_level_restrictions=false` until next major version
- `req.diff` uses a deep expand to fetch data for deep update comparison. Previously, it read each composition layer sequentially.
- `cds.test` now requires module `@cap-js/cds-test` to be installed. Test dependencies like `axios`, `chai`, `chai-as-promised`, and `chai-subset` can be usually removed in favor of `@cap-js/cds-test`.
- `cds.context.locale` is only set if initiated from an HTTP client specifying a locale
- Only new major version 4 of SAP Cloud SDK is supported from now on . Please make sure to upgrade. Detailed changes are documented in the [migration guide](https://github.com/SAP/cloud-sdk-js/blob/main/V4-Upgrade-Guide.md).
- `cds-serve` now fails if `@sap/cds` would be loaded from different installation paths to prevent inconsistent server state. Such situations are always a setup issue, often caused by plugins that require diverging versions. Disable with `cds.server.exit_on_multi_install: false`.
- For drafts, read-only fields must be set in `CREATE` handlers (calculated values set in `NEW` handlers are cleansed). If children are added in draft `CREATE` handlers, the field `DraftAdministrativeData_DraftUUID` must be set.
- `hdbtabledata` files created by `cds compile/build` now instruct SAP HANA to decode base64 values in CSV files for `LargeBinary` elements. This aligns the behavior with SQLite and H2, avoiding manual base64 decoding. It can be disabled with `cds.hana.table_data.column_mapping.LargeBinary=false`.
- `PATCH` requests no longer create the target resource if it doesn't exist (`UPSERT` semantics)
+ Re-enable via flag `cds.runtime.patch_as_upsert=true`
- `PUT` requests no longer set unprovided properties to their default values (`REPLACE` semantics)
+ Re-enable via flag `cds.runtime.put_as_replace=true`
+ If enabled, the defaulting is now done in the protocol adapter
- `req.params` is an array of objects (instead of plain values for single-keyed entities with key `ID`)
+ Opt out with `cds.features.consistent_params=false` until next major version
### Fixed
- Webhook creation in `enterprise-messaging` is more resilient in case of multiple instances
- `cdsjsonschema` protocol in lower case for cds json schema
- In `CREATE` handlers for drafts, the original path is preserved
- `@sap/cds-mtxs` is now loaded before other plugins so that they can register handlers for mtx services.
- The default index page respects now `cds.odata.containment`
- Remove incorrect `Type` suffix from `@odata.context` for views with parameters
- Support where clauses in refs
### Removed
- Legacy OData adapter which was enabled with compat `cds.features.odata_new_adapter=false`
- Legacy Database services which were enabled with `@sap/cds-hana` or `sqlite3`
- `@cds.default.order` and `@odata.default.order` for implicit sorting
- `cds.auth`: Support for `@sap/xssec^3` (incl. compatibility mode of `@sap/xssec^4`)
- Undocumented compat flag `cds.features.odata_v2_result_conversion`
- Undocumented util `cds.utils.pool`
- Undocumented method `INSERT.as`. Use `INSERT.from` instead to insert sub `SELECT` queries.
- Undocumented method `req._queryOptions` of `cds.Request` belonging to the new OData adapter
- Undocumented method `_reset` of the `cds.ql` API
- Undocumented property `cmd` of the `cds.ql` `Query` class. Please use method `kind` instead.
- Undocumented method `protocol4` of the `Protocol` class. Please use property `def.protocols` instead.
- Undocumented methods `impl` and `with` of the `ApplicationService` class. Please use `prepend` instead.
- Undocumented compat flag `cds.features.rest_error_handler`
- Deprecated compat flags `cds.features.compat_restrict_bound` and `cds.env.features.compat_restrict_where`
- Deprecated compat flag `cds.features.stream_compat`
- Deprecated feature flag `cds.log.kibana_custom_fields`. Please use `cds.log.als_custom_fields` instead`.
- Deprecated compat flag `cds.features.keys_in_data_compat`
- Deprecated element-level annotation `@Search.defaultSearchElement`. Please use annotation `@cds.search` instead.
- Deprecated stripping of unnecessary topic prefix `topic:` in messaging
- Deprecated messaging `Outbox` class. Please use config or `cds.outboxed(srv)` to outbox your service.
## Version 8.9.7 - 2025-11-07
### Fixed
- Reject navigations in `$expand` without parsing the navigation path
- Aligned error handling for path navigation and `$expand`
## Version 8.9.6 - 2025-07-29
### Fixed
- Batch insert using `INSERT.entries()` on draft enabled entities
## Version 8.9.5 - 2025-07-25
### Fixed
- `req.diff` in case of draft entities using associations to joins/unions
- Locale detection does not enforce `<http-req>.query` to be present. Some protocol adapters do not set it.
- View metadata for requests with $apply
- Handling of bad timestamps in URL ($filter and temporals)
## Version 8.9.4 - 2025-05-16
### Fixed
- No longer require `@sap/cds-compiler` versions 6.x as these are not supported with CAP Java 3.
- Regression in view resolving with mixins
- View resolving for external service entities aborted too early
- `cds.Map` validation in action/function parameters
## Version 8.9.3 - 2025-05-06
### Fixed
- OData: `$value` access of primitive properties returned by custom handler
- UCL: Add missing declaration of variable `$input` in mutation for creating an application template
- Purge of `servers` from `.cds-services.json` file
- Loading of relative service implementations in plugins
- `cds.compile.to.edmx` in case the model was manipulated in a plugin
## Version 8.9.2 - 2025-04-14
### Fixed
- `forUpdate` will not consider `wait` if `ignoreLocked` is set
- Do not crash in case of custom `DraftAdministrativeData` table
## Version 8.9.1 - 2025-04-03
### Fixed
- `cds.env` merging for `null` values
- Best-effort mechanisms for lambda support on OData V2 remote services (usage of functions in lambda expressions)
- Use extended model in `enterprise-messaging` inbound handlers
- Compat flag `cds.features.draft_compat` for handler registration in draft scenarios
## Version 8.9.0 - 2025-03-31
### Added
- Support for parallel multi-instance processing of outbox entries
- Remote services: ensure request correlation by guaranteeing outgoing header `x-correlation-id`
- Support for `@odata.bind` to reference foreign keys
- Support for plugins in ESM format
- Dependency to `@eslint/js` so that `eslint` works w/o the application having to install it.
- IAS: In the `client_credentials` flow, the array of `ias_apis` (if present) is added to the technical user's roles
- Opt-in feature `cds.features.consistent_params` for `req.params` always being an array of objects
+ That is, no more plain values for single-keyed entities with key `ID`
+ Will become the default in `@sap/cds^9`
### Changed
- Invalid draft requests now have status code 400
- Allow ESM loading of handler files (`.js`, `.ts`) in all situations, incl. test runs with Jest's `--experimental-vm-modules` option.
- Application and remote services now throw the error `Target <yourTarget> cannot be resolved for service <yourService>` when the query cannot be resolved to the service entity. Setting the feature flag `cds.env.features.restrict_service_scope` to false disables this.
- Accept 2xx status codes set in custom operation handlers
- Implicit orderby elements are marked as such and are no longer considered for requests to remote services
### Fixed
- Lean draft: Proper navigation to the service entity of draft-administrative data
- Unprocessed foreign keys from expressions of semi join conditions in `UPDATE.data`
- Kafka: Each topic will have a dedicated consumer-group id (configurable with `consumerGroup`)
- Foreign-key calculation based on navigation path
- `cds.env` shortcuts like `cds.requires.db === 'hana'` are normalized to `cds.requires.db.kind === 'hana'` when combined from multiple sources
- Error handling for invalid access of an entity that does not have a key, by key, through REST
- `cds.validate` crashed with unknown target
- `cds.parse.expr` parsed SAP HANA native functions like `current_utctimestamp` erroneously as `ref`
- `null` values in logger if `custom_fields` are configured
- User-provided instances of SAP Cloud Logging should have either tag `cloud-logging` or `Cloud Logging`
- The `@odata.context` for entities and views with parameters should refer to the EntityType with `/Set` at the end e.g. `../$metadata#ViewWithParamType(1)/Set`
## Version 8.8.3 - 2025-03-20
### Fixed
- Event Mesh: Reconnect in case of error in AMQP connection
## Version 8.8.2 - 2025-03-13
### Fixed
- Consuming REST actions returning anonymous structures
- `i18n.labels/messages` were occasionally missing
## Version 8.8.1 - 2025-03-07
### Fixed
- Requests violating `cds.odata.max_batch_header_size` are terminated with `431 Request Header Fields Too Large` instead of `400 - Bad Request`
- `cds.parse.<x>` writing directly to `stdout`
- Instance-based authorization for programmatic action invocations
- Implicit function parameter calls with Array or Object values
- OData: Throw an error by `POST` with payload that contains array of entity representation
- `cds.validate` filters out annotations according to OData V4 spec
- Crash for requests with invalid time data format
- Add missing 'and' between conditions in object notation of QL
- Multiline payloads in `$batch` sub requests
- Instance-based authorization for modeling like `$user.<property> is null`
- Respect `cds.odata.contextAbsoluteUrl` in new OData adapter
- `cds.odata.context_with_columns` also applies to singletons
## Version 8.8.0 - 2025-03-03
### Added
- `cds.ql` method `SELECT.hints()` which passes hints to the database query optimizer that can influence the execution plan
- Schema updates for MTX configuration
- Deprecate `cds.requires.db.database` in JSON schema
- Service level restrictions for application service calls can be enforced with `cds.features.service_level_restrictions=true`
+ With `@sap/cds^9`, this becomes the new default.
- Support implicit function parameters calls with @prefix
- `cds.test` now uses package `@cap-js/cds-test` if installed, otherwise prints a hint to install it. With cds 9, this package will be required.
- Operation response streaming
+ OData: Operations returning `cds.LargeBinary` annotated with `@Core.MediaType` may send stream responses.
+ REST: Operations may send stream responses.
+ Annotations `@Core.MediaType`, `@Core.ContentDisposition.Filename` and `@Core.ContentDisposition.Type` on operation return types will be considered.
### Changed
- The default index page now shows links to CDS functions with their parameter names but no default values anymore.
### Fixed
- Order by virtual fields in draft-related requests
- Erroneous cleansing when draft activation is invoked programmatically
- Skip validation for mandatory fields in update scenarios for entities in draft activation
- Simplified default configuration: `cds.requires.messaging = true`
- `cds.connect` called with options erroneously filled in `cds.services`
- Mocked users won't have a tenant in single-tenant mode
- Allow usage of latest versions of `chai` and `chai-as-promised` on Node >= 23 with the built-in test runner and `mocha`. The `jest` runner is not able though to load these ESM modules.
- Reject navigations in expand
- Activation of drafts for entities using `@cds.api.ignore`
- Prevent uncaught type error during validation of composition entries
## Version 8.7.2 - 2025-02-14
### Fixed
- Strip `Z` suffix of values of `cds.Timestamp` with OData type `Edm.DateTime`
- Skip validation for mandatory fields in update scenarios for entities in draft activation
- `cds.compile.to.yaml` escapes strings including colons if necessary
## Version 8.7.1 - 2025-02-04
### Fixed
- Loading of CAP Plugins implemented in Typescript
- `Location` header if read after write returns empty result due to missing read authentication
- Enable accessing `req.params` when handling requests on parameterized views
- `cds.connect.to(class {...})` did not call the `init` function
- Generic Paging/Sorting was run twice for non-draft requests
- Service implementation loaded from `node_modules`
## Version 8.7.0 - 2025-01-28
### Added
- Allow usage of tar library (https://www.npmjs.com/package/tar) as a workaround to solve remaining issues by extension build on Windows. The tar library should be installed by app developers.
- `cds.ql` supports limit with an optional offset, e.g. `limit(10, 5)`
- Basic support for new built-in type `cds.Map`
- Normalization of DateTime and Timestamp payloads in new OData adapter
### Changed
- Cleanse immutable values in draft modifications
- Do not use compatibility mode of @sap/xssec 4, can be reverted with `cds.env.features.xssec_compat = true`
- `cds.Float` is now correctly deprecated in `cds.builtin.types`.
- Input provided via protocol adapter for elements annotated with `@cds.api.ignore` are rejected. Previously, they were ignored.
### Fixed
- Narrowed down peer dependency version of `express` to `^4`
- OData, REST: Responses are only written in case that the response object is not already closed, which allows responding to requests directly in custom handlers.
+ Note: Responses sent directly are not transactionally safe! Further, subsequent errors can no longer be communicated to the client!
+ Note: Only respond directly in non-`$batch` requests!
## Version 8.6.2 - 2025-01-27
### Fixed
- Crash during requests to actions with parameter `array of <type>`
- Instance based restriction using `is null`
- Filtering of grouped result on default aggregate
- Multipart batch response for failed changesets
- Handling of invalid parentheses in OData property access
- Resolve view: Mixins are not in elements of projection target
- Input provided via protocol adapter for elements annotated with `@cds.api.ignore` can be rejected with `cds.features.reject_ignored: true`.
## Version 8.6.1 - 2025-01-10
### Fixed
- find draft root in authorization checks when entity has recursive compositions
- `default-env.json` was not loaded anymore when in production mode.
- i18n texts like `1` or `true` were returned as numbers, or booleans instead of strings
- CSN files produced by `cds build` now again contain information to resolve handler files. That was broken in case of reflected/linked models set by e.g. plugins.
- `average` aggregation used with draft enabled entities
## Version 8.6.0 - 2024-12-17
### Added
- `SELECT.from` now supports full-query tagged template literals, e.g.: ``` SELECT.from`Books where ID=${201}` ```
- `cds.ql` enhanced by functions to facilitate construction of CQN objects.
- `cds.ql` became a function to turn CQN objects, CQL strings, or tagged template literals into instances of the respective `cds.ql` class.
- New `cds` events to allow multitenant plugins: `compile.for.runtime`, `compile.to.dbx`, `compile.to.edmx`.
- `cds.env` now supports `.cdsrc.js` and `.cdsrc.yaml` files, also in plugins.
- `cds.env` now supports profile-specific `.env` files, e.g. `.hybrid.env` or `.attic.env`.
- Experimental OData parsing for hierarchy requests (`descendants`, `ancestors`, `TopLevels`)
- The new OData adapter now supports `cds.odata.containment`. Contained entities can only be accessed via their parents and do not show up as EntitySets in $metadata and the service document.
### Changed
- `CDL`, `CQL`, and `CXL` globals are deprecated => use respective functions from `cds.ql` instead.
- `CREATE`, and `DROP` globals are deprecated => use respective functions from `cds.ql` instead.
- Zulu time zone information is stripped from `cds.DateTime` properties when querying Odata V2 remote services
- Processing of `@restrict.where` was aligned with CAP Java:
+ Instance-based authorization on app service calls does not consider custom `WHERE` clauses of `UPDATE`/`DELETE` queries
+ Until `@sap/cds^9`, this change can be deactivated via `cds.env.features.compat_restrict_where = true`
+ Simple static clauses (e.g., `$user.level > 5`) are no longer evaluated by the server but added to the respective SQL regardless. As a result, requests may receive a response of `2xx` with an empty body instead of a `403`.
+ Until `@sap/cds^9`, this change can be deactivated via `cds.env.features.compat_static_auth = true`
+ Read restrictions on the entity are no longer taken into consideration when evaluating restrictions on bound actions/ functions
+ Until `@sap/cds^9`, this change can be deactivated via `cds.env.features.compat_restrict_bound = true`
### Fixed
- ETag calculation if column was provided as Javascript Date
- Forwarding of `/$count` queries while mocking the external service
- Resolving of implicit function parameters (e.g `GET .../test.foo?x='bar'`)
- Arrayed elements are not part of response unless explicitly selected with `$select`
- In case of nonexistent user attributes (`$user.X`), only the subclause gets substituted with `false`
- `@odata.context` in new OData adapter:
+ Fixed crash for requests to actions/functions when `cds.env.odata.context_with_columns` is enabled
+ Aggregation functions with `$apply` are now returned when `cds.env.odata.context_with_columns` is enabled
+ `@odata.context` is now the first property in the response values of `concat` requests
+ Binary key values are now properly encoded and formatted
+ Fixed keys appearing as `(undefined)` for updates via navigation to-one
+ Fixed key value pairs being returned as `undefined=undefined` for property access of aspects
+ Backlinks no longer appear as keys for property access of aspects
+ Non-anonymous structured types are now prefixed with the service name
+ Structured types no longer end with `/$entity`
## Version 8.5.1 - 2024-12-06
### Fixed
- `cds deploy --dry --model-only` no longer tries to load a SQLite database
- Requests with HTTP methods other than `POST` to the `/$batch` endpoint are now rejected when using the new OData adapter
## Version 8.5.0 - 2024-11-25
### Added
- New `cds.i18n` module used consistently for both, UI labels and runtime messages.
- Enhanced `cds.validate` to support open intervals for: `@assert.range:[(0),(Infinity)]` -> `0 < x < ∞`
- `package.json` validation and suggestions for messaging services.
- `cds.log()`: Detect binding to SAP Cloud Logging via user provided service. The user provided service must have tag `cloud-logging`.
- Support for function parameters via query component (example: `GET /foo?bar=baz` instead of `GET /foo(bar='baz')`)
- Experimental support for programmatic draft actions `srv.new(MyEntity, data)`, `srv.cancel(MyEntity.drafts, keys)`, `srv.edit(MyEntity, data)` and `srv.save(MyEntity.drafts, keys)`
### Changed
- `cds-deploy` script has a non-zero exit code on deployment failure
- Properties of type `cds.Binary` in URLs as well as request payload are converted to `Buffer`s.
Properties of type `cds.LargeBinary` in request payload are converted to `Readable`s.
Previously, both were provided as Base64-encoded strings.
This change can be deactivated via `cds.env.features.base64_binaries = true`, which is set by default for profile `attic`.
### Fixed
- `cds.validate` should not delete readonly keys from `req.data`
- `cds.validate` should not reject imported associations
- Readonly fields must not be set when creating draft entities
- Validation of mandatory properties caused streams to be rejected for new OData adapter
- `cds.log` with null parameters and JSON format
- `cds.compile.to.sql` proper replacement for sqlite session variables in java projects
- `cds.compile.to.serviceinfo` ignores only the `endpoints` property for unknown protocols
- `Preference-Applied` header is returned in OData adapter if requested
- No location header is returned on OData update requests if `minimal` preference is set
- Handling of invalid requests for views with parameters
## Version 8.4.2 - 2024-11-13
### Fixed
- `cds.compile.to.edmx` if using the new builtin type `cds.Map`
## Version 8.4.1 - 2024-11-07
### Fixed
- Validate request method for operations
- Correctly generate CQN for lambda expressions in new OData adapter
- `req.diff()` on old database with property transitions
## Version 8.4.0 - 2024-10-29
### Added
- Set the maximum allowed size of HTTP headers in bytes for `$batch` subrequests via flag `cds.env.odata.max_batch_header_size` (default: 64 KiB)
- New OData flag `cds.env.odata.context_with_columns` that adds selected and expanded columns to `@odata.context`. Default is `false`
- New experimental option `--workers` to `cds watch/run/serve` that allows running a `cds.server` cluster
(process env variable `WORKERS` or `CDS_WORKERS` can be used alternatively)
### Changed
- Internal API `srv.endpoints` now always is an array of endpoint objects, an empty one if the service is not served to any protocol.
- Property `.cmd` of `cds.ql.Query` (and subclasses thereof) is deprecated → use `.kind` instead
- For remote service calls to OData v2 services, less conversions are performed on the returned data
### Fixed
- Commands like `cds deploy` now fail with a clear error message if called with an invalid value for `cds.features.assert_integrity` (like `true`)
- Authentication validation errors (e.g., expired token, wrong audience) are logged as warning
- Requests using `$apply` will always apply implicit sorting on best effort mechanism
- Properly handle empty content-type in new OData adapter
- Error/crash with `cds.features.odata_new_parser` for requests containing `$expand=*` and `$select`, which selects individual columns and star, e.g. `$select=ID,*`
- Referencing new entities in `$batch` with new OData adapter did not work properly when using non integer content IDs in multipart/mixed
- `cds.compile.to.serviceinfo` to ignore unknown protocols
- New OData adapter and `cds.spawn` did not crash on programming errors (for example TypeError)
## Version 8.3.1 - 2024-10-08
### Fixed
- Erroneous caching in `cds.validate`
- Precedence of request headers for `cds.context.id`
- For `quoted` names, overwrite `@cds.persistence.name` for drafts and localized views properly
- Do not use hana error code as http status code
## Version 8.3.0 - 2024-09-30
### Added
- `cds.deploy` can now also write its DDL statements to a separate log
- Symlinks are followed in `cds test`
### Changed
- Unknown protocols in `@protocol` annotations formerly prevented server starts; they are merely ignored now with a warning in the logs.
- Deprecated configuration flag `cds.env.features.keys_in_data_compat` because of incompatibility with data validation in new OData adapter.
- `@cds.api.ignore` doesn't suppress an association, the annotation is propagated to the (generated) foreign keys.
- Where clauses of restrictions for bound actions and functions defined by `@restrict` are now enforced and no longer ignored.
- `@cap-js/telemetry` is now loaded before other plugins to allow better instrumentation.
### Fixed
- When modifying active children of of draft-enabled entities directly (`bypass_draft`), the error message was misleading.
- Cleaning up drafts calls `CANCEL` handlers
- Allow to call `CANCEL` on draft entities programmatically
- Encoding of `@odata.nextLink` path
- Computed fields are ignored in projections
- Consider `id` in a `ref` step for mapping of service elements to their name on the db.
- Feature toggles with new OData adapter.
- Target entity was incorrectly calculated for some actions in new OData adapter.
- `req.diff()` does not manipulate existing queries anymore.
- New OData adapter: normalize on commit error in `/$batch`
### Removed
- Alpha support for SAP Event Broker-based messaging (kind `event-broker`). Use CDS plugin `@cap-js/event-broker` instead.
## Version 8.2.3 - 2024-09-20
### Changed
- All annotations in input data are skipped and removed from the input by `cds.validate()` - as we did in legacy OData adapter
### Fixed
- Unmanaged associations are excluded from `@mandatory` checks
- Properly reject direct requests to `DraftAdministrativeData`
- Virtual elements annotated with `@Core.MediaType`
- OData Requests targeting a specific instance and custom handler returns empty array
- `cds-serve` and `cds-deploy` now set `cds.cli` information
## Version 8.2.2 - 2024-09-13
### Fixed
- Erroneous caching in `cds.validate`
- Properly check `$filter` element types across navigations
## Version 8.2.1 - 2024-09-04
### Fixed
- Date validation of legacy OData protocol adapter
- Content-Length headers in multipart batch request body
- Streaming requests with virtual properties
- Bring back support for `x-correlationid`
- Validation of inlined elements
- multipart `$batch` parsing with _--_ as part of payload
## Version 8.2.0 - 2024-08-30
### Added
- Allow `cds.connect.to (SomeService)` where `SomeService` is a class
- Lean draft: support CDS orderBy in `list status: all`
- Support where not in as object in `cds.ql` expressions like: `where({ID:{not:{in:[...]}}})`
- Unbound CDS functions now show up in the server's index page along with an exemplary call signature
- `cds.log`'s JSON formatter:
+ Field `w3c_traceparent` is filled based on request header `traceparent` (cf. W3C Trace Context) for improved correlation
+ Custom fields `cds.env.log.cls_custom_fields` are filled if bound to an instance of SAP Cloud Logging
+ Default `cds.env.log.als_custom_fields` enhanced by `{ reason: 3 }` (project config takes precedence)
- Support for `cds.hana` types like `cds.ha