{"id":27916754,"url":"https://github.com/dxfrontier/cds-ts-dispatcher","last_synced_at":"2025-05-06T16:39:43.427Z","repository":{"id":205102466,"uuid":"688492272","full_name":"dxfrontier/cds-ts-dispatcher","owner":"dxfrontier","description":"SAP CAP TypeScript entity handler dispatcher.","archived":false,"fork":false,"pushed_at":"2025-05-06T08:29:32.000Z","size":2255,"stargazers_count":14,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-06T08:47:05.388Z","etag":null,"topics":["cap","cds","cds-ts-dispatcher","cds-ts-repository","nodejs","sap","sap-btp","sap-cap","typescript","ui5"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dxfrontier.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-07T13:07:26.000Z","updated_at":"2025-05-06T08:27:54.000Z","dependencies_parsed_at":"2023-11-10T16:28:06.735Z","dependency_job_id":"1ea5e54d-52ec-4c23-9e93-46c1ea614e90","html_url":"https://github.com/dxfrontier/cds-ts-dispatcher","commit_stats":null,"previous_names":["dxfrontier/cds-ts-dispatcher"],"tags_count":80,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dxfrontier%2Fcds-ts-dispatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dxfrontier%2Fcds-ts-dispatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dxfrontier%2Fcds-ts-dispatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dxfrontier%2Fcds-ts-dispatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dxfrontier","download_url":"https://codeload.github.com/dxfrontier/cds-ts-dispatcher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252721996,"owners_count":21793938,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cap","cds","cds-ts-dispatcher","cds-ts-repository","nodejs","sap","sap-btp","sap-cap","typescript","ui5"],"created_at":"2025-05-06T16:39:41.610Z","updated_at":"2025-05-06T16:39:43.415Z","avatar_url":"https://github.com/dxfrontier.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch2\u003e CDS-TS-Dispatcher \u003c/h2\u003e\n\n![SAP](https://img.shields.io/badge/SAP-0FAAFF?style=for-the-badge\u0026logo=sap\u0026logoColor=white)\n![ts-node](https://img.shields.io/badge/ts--node-3178C6?style=for-the-badge\u0026logo=ts-node\u0026logoColor=white)\n![Node.js](https://img.shields.io/badge/Node%20js-339933?style=for-the-badge\u0026logo=nodedotjs\u0026logoColor=white)\n![Express.js](https://img.shields.io/badge/Express%20js-000000?style=for-the-badge\u0026logo=express\u0026logoColor=white)\n![json](https://img.shields.io/badge/json-5E5C5C?style=for-the-badge\u0026logo=json\u0026logoColor=white)\n![npm](https://img.shields.io/badge/npm-CB3837?style=for-the-badge\u0026logo=npm\u0026logoColor=white)\n\n![NPM Downloads](https://img.shields.io/npm/dy/@dxfrontier/cds-ts-dispatcher?logo=npm)\n![NPM Downloads](https://img.shields.io/npm/dm/%40dxfrontier%2Fcds-ts-dispatcher?logo=npm)\n![NPM Version](https://img.shields.io/npm/v/%40dxfrontier%2Fcds-ts-dispatcher?logo=npm)\n\n![Tests](https://img.shields.io/github/actions/workflow/status/dxfrontier/cds-ts-dispatcher/tests.yml?logo=git\u0026label=test%20(unit%2C%20e2e%2C%20integration))\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/dxfrontier/cds-ts-dispatcher/deployment.yaml?logo=git)\n![GitHub last commit (branch)](https://img.shields.io/github/last-commit/dxfrontier/cds-ts-dispatcher/main?logo=git)\n![GitHub issues](https://img.shields.io/github/issues/dxfrontier/cds-ts-dispatcher?logo=git)\n![GitHub contributors](https://img.shields.io/github/contributors/dxfrontier/cds-ts-dispatcher?logo=git)\n![GitHub Repo stars](https://img.shields.io/github/stars/dxfrontier/cds-ts-dispatcher?style=flat\u0026logo=git)\n\nThe goal of **CDS-TS-Dispatcher** is to significantly reduce the boilerplate code required to implement **Typescript handlers** provided by the SAP CAP framework.\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Prerequisites](#prerequisites)\n- [Installation](#installation)\n  - [`Option 1 :` Install CDS-TS-Dispatcher - `New project`](#option-1--install-cds-ts-dispatcher---new-project)\n  - [`Option 2 :` Install CDS-TS-Dispatcher - `Existing TypeScript project`](#option-2--install-cds-ts-dispatcher---existing-typescript-project)\n  - [`Generate CDS Typed entities`](#generate-cds-typed-entities)\n    - [`Important`](#important)\n  - [`Migration:` from @sap/cds `v7` to `v8`](#migration-from-sapcds-v7-to-v8)\n- [Usage](#usage)\n  - [`Architecture`](#architecture)\n  - [`CDSDispatcher`](#cdsdispatcher)\n  - [`Decorators`](#decorators)\n    - [`Class`](#class)\n      - [@EntityHandler](#entityhandler)\n      - [@ServiceLogic](#servicelogic)\n      - [@Repository](#repository)\n        - [`[Optional]` - CDS-TS-Repository - BaseRepository](#optional---cds-ts-repository---baserepository)\n      - [@UnboundActions](#unboundactions)\n      - [@Use](#use)\n    - [`Field`](#field)\n      - [@Inject](#inject)\n      - [@Inject(`CDS_DISPATCHER.SRV`)](#injectcds_dispatchersrv)\n      - [@Inject(CDS\\_DISPATCHER.OUTBOXED\\_SRV)](#injectcds_dispatcheroutboxed_srv)\n    - [`Parameter`](#parameter)\n      - [@Req](#req)\n      - [@Res](#res)\n      - [@Results / @Result](#results--result)\n      - [@Next](#next)\n      - [@Error](#error)\n      - [@Jwt](#jwt)\n      - [@IsPresent](#ispresent)\n      - [@IsRole](#isrole)\n      - [@IsColumnSupplied](#iscolumnsupplied)\n      - [@GetQuery](#getquery)\n      - [@GetRequest](#getrequest)\n      - [@SingleInstanceSwitch](#singleinstanceswitch)\n      - [@ValidationResults](#validationresults)\n      - [@Locale](#locale)\n      - [@Env](#env)\n      - [@Msg](#msg)\n    - [`Method`-`active entity`](#method-active-entity)\n      - [`Before`](#before)\n        - [@BeforeCreate](#beforecreate)\n        - [@BeforeRead](#beforeread)\n        - [@BeforeUpdate](#beforeupdate)\n        - [@BeforeDelete](#beforedelete)\n        - [@BeforeAll](#beforeall)\n      - [`After`](#after)\n        - [@AfterCreate](#aftercreate)\n        - [@AfterRead](#afterread)\n        - [@AfterReadEachInstance](#afterreadeachinstance)\n        - [@AfterUpdate](#afterupdate)\n        - [@AfterDelete](#afterdelete)\n        - [@AfterAll](#afterall)\n      - [`On`](#on)\n        - [@OnCreate](#oncreate)\n        - [@OnRead](#onread)\n        - [@OnUpdate](#onupdate)\n        - [@OnDelete](#ondelete)\n        - [@OnAction](#onaction)\n        - [@OnFunction](#onfunction)\n        - [@OnEvent](#onevent)\n        - [@OnSubscribe](#onsubscribe)\n        - [@OnError](#onerror)\n        - [@OnBoundAction](#onboundaction)\n        - [@OnBoundFunction](#onboundfunction)\n        - [@OnAll](#onall)\n    - [`Method`-`draft entity`](#method-draft-entity)\n      - [`Before`](#before-1)\n        - [@BeforeNewDraft](#beforenewdraft)\n        - [@BeforeCancelDraft](#beforecanceldraft)\n        - [@BeforeEditDraft](#beforeeditdraft)\n        - [@BeforeSaveDraft](#beforesavedraft)\n      - [`After`](#after-1)\n        - [@AfterNewDraft](#afternewdraft)\n        - [@AfterCancelDraft](#aftercanceldraft)\n        - [@AfterEditDraft](#aftereditdraft)\n        - [@AfterSaveDraft](#aftersavedraft)\n      - [`On`](#on-1)\n        - [@OnNewDraft](#onnewdraft)\n        - [@OnCancelDraft](#oncanceldraft)\n        - [@OnEditDraft](#oneditdraft)\n        - [@OnSaveDraft](#onsavedraft)\n      - [`Other draft decorators`](#other-draft-decorators)\n    - [`Method`-`helpers`](#method-helpers)\n      - [@AfterReadSingleInstance](#afterreadsingleinstance)\n      - [@Prepend](#prepend)\n      - [@Validate](#validate)\n      - [@FieldsFormatter](#fieldsformatter)\n      - [@ExecutionAllowedForRole](#executionallowedforrole)\n      - [@Use](#use-1)\n      - [@CatchAndSetErrorCode](#catchandseterrorcode)\n      - [@CatchAndSetErrorMessage](#catchandseterrormessage)\n- [`Deployment` to BTP using MTA](#deployment-to-btp-using-mta)\n- [`Best practices` \\\u0026 `tips`](#best-practices--tips)\n- [`Samples`](#samples)\n- [Contributing](#contributing)\n- [License](#license)\n- [Authors](#authors)\n\n## Prerequisites\n\nInstall [**@sap/cds-dk**](https://cap.cloud.sap/docs/get-started/), `typescript`, `ts-node` globally:\n\n```bash\nnpm install -g @sap/cds-dk typescript ts-node\n```\n\n## Installation\n\n### `Option 1 :` Install CDS-TS-Dispatcher - `New project`\n\n\u003c!-- #### `Using:` @sap/cds `v8` --\u003e\n\nUse the following steps if you want to create a new **SAP CAP project.**\n\n1. Create new folder :\n\n```bash\nmkdir project\ncd project\n```\n\n2. Initialize the CDS folder structure :\n\n```bash\ncds init\n```\n\n3. Add `TypeScript` and [CDS-Typer](#generate-cds-typed-entities) to your npm package.json:\n\n```bash\ncds add typescript\n```\n\n4. Add `CDS-TS-Dispatcher` to your npm package.json :\n\n```bash\nnpm install @dxfrontier/cds-ts-dispatcher\n```\n\n5. It is recommended to use the following **tsconfig.json** properties:\n\n```json\n{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"allowJs\": true,\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"strictNullChecks\": true,\n    \"strictPropertyInitialization\": false,\n    \"forceConsistentCasingInFileNames\": true,\n    \"allowSyntheticDefaultImports\": true,\n\n    \"strict\": true,\n\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n\n    \"target\": \"ES2021\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n\n    \"outDir\": \"./gen/srv\",\n    \"rootDir\": \".\",\n\n    \"paths\": {\n      \"#cds-models/*\": [\"./@cds-models/*/index.ts\"]\n    }\n  },\n  \"include\": [\"./srv\", \"./@dispatcher\"]\n}\n```\n\n6. Install packages\n\n```bash\nnpm install\n```\n\n7. Run the `CDS-TS` server\n\n```bash\ncds-ts w\n```\n\n\u003e [!IMPORTANT]\n\u003e CDS-TS-Dispatcher uses `@sap/cds`, `@sap/cds-dk` [version 8](https://cap.cloud.sap/docs/releases/jun24)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### `Option 2 :` Install CDS-TS-Dispatcher - `Existing TypeScript project`\n\nUse the following steps if you want to add only the **@dxfrontier/cds-ts-dispatcher to an existing project :**\n\n```bash\nnpm install @dxfrontier/cds-ts-dispatcher\n```\n\nIt is recommended to use the following **tsconfig.json** properties:\n\n```json\n{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"allowJs\": true,\n    \"strictPropertyInitialization\": false,\n    \"forceConsistentCasingInFileNames\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strictNullChecks\": true,\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n\n    \"strict\": true,\n\n    \"lib\": [\"es2022\"],\n\n    \"outDir\": \"./gen/srv\"\n  },\n  \"include\": [\"./srv\"]\n}\n```\n\n\u003e [!WARNING]\n\u003e If below message appears\n\u003e\n\u003e ```bash\n\u003e -----------------------------------------------------------------------\n\u003e WARNING: Package '@sap/cds' was loaded from different installations: [\n\u003e  '***/node_modules/@sap/cds/lib/index.js',\n\u003e  '***/node_modules/@dxfrontier/cds-ts-dispatcher/node_modules/@sap/cds/lib/index.js'\n\u003e ] Rather ensure a single install only to avoid hard-to-resolve errors.\n\u003e -----------------------------------------------------------------------\n\u003e ```\n\u003e\n\u003e Run the following command :\n\u003e\n\u003e ```bash\n\u003e npm install -g @sap/cds-dk@latest\n\u003e ```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### `Generate CDS Typed entities`\n\nExecute the following commands :\n\n```bash\ncds add typer\n```\n\n```bash\nnpm install\n```\n\n\u003e [!TIP]\n\u003e If above option is being used, this means whenever we change a `.CDS` file the changes will reflect in the generated `@cds-models` folder.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\u003c!-- \n#### Option 2\n\nExecute the command :\n\n```bash\nnpx @cap-js/cds-typer \"*\" --outputDirectory ./srv/util/types/entities\n```\n\n- Target folder :`./srv/util/types/entities` - Change to your desired destination folder.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e --\u003e\n\n#### `Important`\n\n\u003e [!IMPORTANT]\n\u003e Import always the `generated entities` from the `service` folders and not from the `index.ts`\n\n![alt text](https://github.com/dxfrontier/markdown-resources/blob/main/common/cds_typer_entities_@cds-models.png?raw=true)\n\n\u003e [!TIP]\n\u003e By default cds-typer will create in your `package.json` a quick path alias like :\n\u003e\n\u003e ```json\n\u003e \"imports\": {\n\u003e   \"#cds-models/*\": \"./@cds-models/*/index.js\"\n\u003e }\n\u003e ```\n\u003e\n\u003e **Use import helper to import entities from `#cds-models` like example :**\n\u003e\n\u003e - **`import { Book } from '#cds-models/CatalogService';`**\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### `Migration:` from @sap/cds `v7` to `v8`\n\nUse the following steps if you want to migrate from `@sap/cds@7` to `@sap/cds@8`:\n\n1. Verify you've installed the `cds@v8` globally by running the following command:\n\n```bash\ncds -v -i\n```\n\n| packages | version                        |\n| ---------------------- | ------------------------------------------------------------------------------ |\n| @cap-js/asyncapi       | 1.0.1                                                                          |\n| @cap-js/cds-typer      | 0.24.0                                                                         |\n| @cap-js/cds-types      | 0.6.4                                                                          |\n| @cap-js/openapi        | 1.0.4                                                                          |\n| @cap-js/sqlite         | 1.7.3                                                                          |\n| `@sap/cds`               | `8.1.0`                                                                          |\n| @sap/cds-compiler      | 5.1.2                                                                          |\n| `@sap/cds-dk (global)`   | `8.0.2`                                                                          |\n| @sap/cds-fiori         | 1.2.7                                                                          |\n| @sap/cds-foss          | 5.0.1                                                                          |\n| @sap/cds-lsp           | 8.0.0                                                                          |\n| @sap/cds-mtxs          | 1.18.2                                                                         |\n| @sap/eslint-plugin-cds | 3.0.4                                                                          |\n| Node.js                | v22.4.1                                                                        |\n\n\u003e [!TIP]\n\u003e If you see a smaller version than `@sap/cds-dk (global)` `8.0.2` run the following command :\n\u003e\n\u003e ```bash\n\u003e npm install -g @sap/cds-dk@latest\n\u003e ```\n\n2. Run the following command inside of your project:\n\n```bash\ncds add typescript\n```\n\n\u003e [!TIP]\n\u003e Command above will add the following packages:\n\u003e\n\u003e - `@types/node`\n\u003e - `@cap-js/cds-types`\n\u003e - `@cap-js/cds-typer`\n\u003e - `typescript`\n\n3. After running command above the `package.json` will look similar to :\n\n```json\n{\n  \"dependencies\": {\n    \"@dxfrontier/cds-ts-dispatcher\": \"^4.0.0\",\n    \"@dxfrontier/cds-ts-repository\": \"^5.1.6\",\n    \"@sap/cds\": \"^8.7.2\"\n  },\n  \"devDependencies\": {\n    \"@cap-js/sqlite\": \"^1.8.0\",\n    \"@cap-js/cds-types\": \"^0.9.0\",\n    \"typescript\": \"^5.5.4\",\n    \"@types/node\": \"^22.1.0\",\n    \"@cap-js/cds-typer\": \"0.33.0\"\n  },\n  \"scripts\": {\n    \"start\": \"cds-serve\",\n    \"watch\": \"cds-ts w\",\n  },\n}\n```\n\n\u003e [!IMPORTANT]\n\u003e You might delete the `node_modules` folder and `package-lock.json` in case `npm run watch` fails working.\n\u003e\n\u003e Re-run the following command :\n\u003e\n\u003e ```bash\n\u003e npm install\n\u003e ```\n\n## Usage\n\n### `Architecture`\n\n**We recommend adhering** to the **Controller-Service-Repository** design pattern using the following folder structure:\n\n1. [EntityHandler](#entityhandler) `(Controller)` - Responsible for managing the REST interface to the business logic implemented in [ServiceLogic](#servicelogic)\n2. [ServiceLogic](#servicelogic) `(Service)` - Contains business logic implementations\n3. [Repository](#repository) `(Repository)` - This component is dedicated to handling entity manipulation operations by leveraging the power of [CDS-QL](https://cap.cloud.sap/docs/node.js/cds-ql).\n\n`Controller-Service-Repository` suggested folder structure\n\n![alt text](https://github.com/dxfrontier/markdown-resources/blob/main/cds-ts-dispatcher/architecture_folder_structure.png?raw=true) \u003c= expanded folders =\u003e ![alt text](https://github.com/dxfrontier/markdown-resources/blob/main/cds-ts-dispatcher/architecture_folder_structure_expanded.png?raw=true)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003e [!TIP]\n\u003e You can have a look over the [CDS-TS-Dispatcher-Samples](https://github.com/dxfrontier/cds-ts-samples) where we use the Controller-Service-Repository pattern and Dispatcher.\n\n### `CDSDispatcher`\n\n**CDSDispatcher**(`entities` : `Constructable[]`)\n\nThe `CDSDispatcher` constructor allows you to create an instance for dispatching and managing entities.\n\n`Parameters`\n\n- `entities (Array)`: An array of **[Entity handler](#entityhandler)(s)** (Constructable) that represent the entities in the CDS.\n\n`Method`\n\n- `initialize`: The `initialize` method of the `CDSDispatcher` class is used to initialize **[Entity handler](#entityhandler)(s)** and all of their dependencies : [Services](#servicelogic), [Repositories](#repository), [UnboundActions](#unboundactions)\n\n`Example`\n\n```typescript\nimport { CDSDispatcher } from '@dxfrontier/cds-ts-dispatcher';\n\nexport = new CDSDispatcher([\n  // Entities\n  BookHandler,\n  ReviewHandler,\n  BookStatsHandler,\n  // Draft\n  BookEventsHandler,\n  // Unbound actions\n  UnboundActionsHandler,\n]).initialize();\n\n// or use\n// module.exports = new CDSDispatcher([ ...\n```\n\n`Visual image`\n\n\u003cimg src=\"https://github.com/dxfrontier/markdown-resources/blob/main/cds-ts-dispatcher/usage_cdsDispatcher.png?raw=true\"\u003e\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### `Decorators`\n\n#### `Class`\n\n##### @EntityHandler\n\nThe `@EntityHandler` decorator is utilized at the `class-level` to annotate a class with:\n\n1. A specific `entity` that will serve as the base entity for all handler decorators within the class.\n2. `'*'` as `all entities` that will serve as the base entity for all handler decorators within the class.\n\n`Overloads`\n\n| Method                               | Parameters                               | Description                                                                                                                                                                                                                                                                                                                                                                            |\n| :----------------------------------- | :--------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 1. EntityHandler(`entity`: CDSTyper) | Must be a `CDS-Typer` generated class    | It ensures that all handlers within the class operate with the specified `entity context`.                                                                                                                                                                                                                                                                                             |\n| 2. EntityHandler(`entity`: `'*'`)    | A wildcard `'*'` indicating all entities | It ensures that all handlers within the class operate with a generic context indicating that registered events will be triggered for all `all entities` (`active entities` and `draft entities`) \u003cbr /\u003e \u003cbr /\u003e Excluded will be [@OnAction()](#onaction), [@OnFunction()](#onfunction), [@OnEvent()](#onevent), [@OnError()](#onerror) as these actions belongs to the Service itself. |\n\n`Parameters`\n\n- `entity (CDSTyperEntity | '*')`: A specialized class generated using the [CDS-Typer](#generate-cds-typed-entities) or generic wild card `'*'` applicable to all entities.\n\n`Example 1` using `CDS-Typer`\n\n```typescript\nimport { EntityHandler } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n}\n```\n\u003e [!TIP]\n\u003e After creation of `BookHandler` class, you can `import it` into the [CDSDispatcher](#cdsdispatcher).\n\u003e\n\u003e ```typescript\n\u003e import { CDSDispatcher } from '@dxfrontier/cds-ts-dispatcher';\n\u003e\n\u003e export = new CDSDispatcher([\n\u003e   // Entities\n\u003e   BookHandler,\n\u003e   // Unbound actions\n\u003e   // ...\n\u003e ]).initialize();\n\u003e ```\n\n`Example 2` using `*` wildcard indicating that events will be triggered for all entities\n\n```typescript\nimport { EntityHandler, CDS_DISPATCHER } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(CDS_DISPATCHER.ALL_ENTITIES) // or use the '*'\nexport class AllEntities {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered on all entities using wildcard '*'\n}\n```\n\u003e [!TIP]\n\u003e After creation of `AllEntities` class, you can `import it` into the [CDSDispatcher](#cdsdispatcher).\n\u003e\n\u003e ```typescript\n\u003e import { CDSDispatcher } from '@dxfrontier/cds-ts-dispatcher';\n\u003e\n\u003e export = new CDSDispatcher([\n\u003e   // Entities\n\u003e   AllEntities,\n\u003e   // Unbound actions\n\u003e   // ...\n\u003e ]).initialize();\n\u003e ```\n\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @ServiceLogic\n\n**@ServiceLogic()**\n\nThe `@ServiceLogic` decorator is utilized at the `class-level` to annotate a `class` as a specialized class containing only business logic.\n\n`Example`\n\n```typescript\nimport { ServiceLogic } from '@dxfrontier/cds-ts-dispatcher';\n\n@ServiceLogic()\nexport class CustomerService {\n  // ...\n  constructor() {}\n  // ...\n}\n```\n\n\u003e [!TIP]\n\u003e When applying `@ServiceLogic()` decorator, the class becomes eligible to be used with [Inject](#inject) decorator for `Dependency injection`.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Repository\n\n**@Repository()**\n\nThe `@Repository` decorator is utilized as a `class-level` annotation that designates a particular `class` as a specialized `Repository`, this class should contain only [CDS-QL](https://cap.cloud.sap/docs/node.js/cds-ql) code.\n\n```typescript\nimport { Repository } from '@dxfrontier/cds-ts-dispatcher';\n\n@Repository()\nexport class CustomerRepository {\n  // ...\n  constructor() {}\n  // ...\n}\n```\n\n\u003e [!TIP]\n\u003e When applying `@Repository()` decorator, the class becomes eligible to be used with [Inject](#inject) decorator for `Dependency injection`.\n\n###### `[Optional]` - CDS-TS-Repository - BaseRepository\n\nThe **[CDS-TS-Repository - BaseRepository](https://github.com/dxfrontier/cds-ts-repository)** was designed to reduce the boilerplate code required to implement data access layer for persistance entities.\n\nIt simplifies the implementation by offering a set of ready-to-use actions for interacting with the database. These actions include:\n\n- `.create()`: Create new records in the database.\n- `.getAll()`: Retrieve all records from the database.\n- `.find()`: Query the database to find specific data.\n- `.delete()`: Remove records from the database.\n- `.exists()`: Check the existence of data in the database.\n- and many more ...\n\n`Example`\n\n```typescript\nimport { Repository } from '@dxfrontier/cds-ts-dispatcher';\nimport { BaseRepository } from '@dxfrontier/cds-ts-repository';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@Repository()\nexport class CustomerRepository extends BaseRepository\u003cMyEntity\u003e {\n  constructor() {\n    super(MyEntity);\n  }\n\n  public async aMethod() {\n    const created = await this.create(...)\n    const createdMany = await this.createMany(...)\n    const updated = await this.update(...)\n    // ...\n  }\n}\n```\n\nTo get started, refer to the official documentation **[CDS-TS-Repository - BaseRepository](https://github.com/dxfrontier/cds-ts-repository)**.\nExplore the capabilities it offers and enhance your data access layer with ease.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @UnboundActions\n\n**@UnboundActions()**\n\nThe `@UnboundActions` decorator is utilized at the `class-level` to annotate a `class` as a specialized class which will be used only for **_Unbound actions._**\n\nThe following decorators can be used inside of `@UnboundActions()` :\n\n- [@OnAction()](#onaction)\n- [@OnFunction()](#onfunction)\n- [@OnEvent()](#onevent)\n- [@OnError()](#onerror)\n- [@OnSubscribe()](#onsubscribe)\n\n`Example`\n\n```typescript\nimport { UnboundActions, OnAction, OnFunction, OnEvent, Req, Next, Error, OnSubscribe } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyAction, MyFunction, MyEvent } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { ActionRequest, ActionReturn, Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\n@UnboundActions()\nexport class UnboundActionsHandler {\n  // ... @Inject dependencies, if needed.\n\n  constructor() {}\n\n  // Unbound action\n  @OnAction(MyAction)\n  private async onActionMethod(\n    @Req() req: ActionRequest\u003ctypeof MyAction\u003e,\n    @Next() next: NextEvent,\n  ): ActionReturn\u003ctypeof MyAction\u003e {\n    // ...\n  }\n\n  // Unbound Function\n  @OnFunction(MyFunction)\n  private async onFunctionMethod(\n    @Req() req: ActionRequest\u003ctypeof MyFunction\u003e,\n    @Next() next: NextEvent,\n  ): ActionReturn\u003ctypeof MyFunction\u003e {\n    // ...\n  }\n\n  // Unbound event\n  @OnEvent(MyEvent)\n  private async onEventMethod(@Req() req: Request\u003cMyEvent\u003e) {\n    // ...\n  }\n\n  // Unbound error\n  @OnError()\n  private onErrorMethod(@Error() err: Error, @Req() req: Request) {\n    // ...\n  }\n\n  // Unbound event\n  @OnSubscribe({ \n    eventName: 'event_name'\n    type: 'SAME_NODE_PROCESS' \n  })\n  private async onSubscribe(@Req() req: Request\u003c{foo: string, bar: number}\u003e): Promise\u003cvoid\u003e {\n    // \n  }\n}\n```\n\n`Imported it` in the [CDSDispatcher](#cdsdispatcher)\n\n```typescript\nimport { CDSDispatcher } from '@dxfrontier/cds-ts-dispatcher';\n\nexport = new CDSDispatcher([ UnboundActionsHandler, ...])\n// or\n// use module.exports = new CDSDispatcher( ... )\n```\n\n\u003e [!NOTE]\n\u003e The reason behind introducing a distinct decorator for `Unbound actions` stems from the fact that these actions are not associated with any specific `Entity` but instead these actions belongs to the Service itself.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Use\n\n**@Use**(`...Middleware[]`)\n\nThe `@Use` decorator simplifies the integration of middlewares into your classes.\n\nWhen `@Use` decorator applied at the `class-level` this decorator inject middlewares into the class and gain access to the `req: Request` and `next: NextMiddleware` middleware across all events `(@AfterRead, @OnRead ...)` within that class.\n\nMiddleware decorators can perform the following tasks:\n\n- Execute any code.\n- Make changes to the request object.\n- End the request-response cycle.\n- Call the next middleware function in the stack.\n- If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.\n\n`Parameters`\n\n- `...Middleware[])`: Middleware classes to be injected.\n\n`Example:` middleware implementation:\n\n```typescript\nimport type { MiddlewareImpl, NextMiddleware, Request } from '@dxfrontier/cds-ts-dispatcher';\n\nexport class MiddlewareClass implements MiddlewareImpl {\n  public async use(req: Request, next: NextMiddleware) {\n    console.log('Middleware use method called.');\n\n    await next(); // call next middleware\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e\n\u003e Inside of the decorator `use` method you can use [@CatchAndSetErrorCode](#catchandseterrorcode) and [@CatchAndSetErrorMessage](#catchandseterrormessage) decorators.\n\n`Example` usage:\n\n```typescript\nimport { EntityHandler, Use, Inject, CDS_DISPATCHER } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\nimport { Middleware1, Middleware2, MiddlewareN } from 'YOUR_MIDDLEWARE_LOCATION';\n\nimport type { Service } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\n@Use(Middleware1, Middleware2, MiddlewareN)\nexport class CustomerHandler {\n  // ...\n  @Inject(CDS_DISPATCHER.SRV) private srv: Service;\n  // ...\n  constructor() {}\n  // ...\n}\n```\n\n\u003e [!TIP]\n\u003e\n\u003e 1. Think of it _(middleware)_ like as a reusable class, enhancing the functionality of all events within the class.\n\u003e 2. Middlewares when applied with `@Use` are executed before the normal events.\n\u003e 3. If you need to apply middleware to a `method` you should use the method specific [@Use](#use-1) decorator .\n\n\u003e [!WARNING]\n\u003e If `req.reject()` is used inside of middleware this will stop the stack of middlewares, this means that next middleware will not be executed.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n#### `Field`\n\n##### @Inject\n\n**@Inject**(`serviceIdentifier: ServiceIdentifierOrFunc\u003cunknown\u003e`)\n\nThe `@Inject` decorator is utilized as a `field-level` decorator and allows you to inject dependencies into your classes.\n\n`Parameters`\n\n- `serviceIdentifier(ServiceIdentifierOrFunc\u003cunknown\u003e)`: A Class representing the service to inject.\n\n`Example`\n\n```typescript\nimport { EntityHandler, Inject, CDS_DISPATCHER } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Service } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(MyEntity)\nexport class CustomerHandler {\n  ...\n  @Inject(CustomerService) private customerService: CustomerService\n  @Inject(CustomerRepository) private customerService: CustomerRepository\n  @Inject(AnyOtherInjectableClass) private repository: AnyOtherInjectableClass\n\n  @Inject(CDS_DISPATCHER.SRV) private srv: Service\n  // ...\n  constructor() {}\n  // ...\n}\n```\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Inject(`CDS_DISPATCHER.SRV`)\n\n**@Inject**(`CDS_DISPATCHER.SRV`) private srv: `Service`\n\nThis specialized `@Inject` can be used as a `constant` in and contains the `CDS.ApplicationService` for further enhancements.\n\nIt can be injected in the following :\n\n- [@EntityHandler()](#entityhandler)\n- [@ServiceLogic()](#servicelogic)\n- [@Repository()](#repository)\n- [@UnboundActions()](#unboundactions)\n\n`Example`\n\n```typescript\nimport { EntityHandler, Inject, CDS_DISPATCHER } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Service } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\n// OR @ServiceLogic()\n// OR @Repository()\n// OR @UnboundActions()\nexport class CustomerHandler {\n  // @Inject dependencies\n  @Inject(CDS_DISPATCHER.SRV) private readonly srv: Service;\n\n  constructor() {}\n  // ...\n}\n```\n\n\u003e [!TIP]\n\u003e The CDS.ApplicationService can be accessed trough `this.srv`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Inject(CDS_DISPATCHER.OUTBOXED_SRV)\n\n**@Inject**(`CDS_DISPATCHER.OUTBOXED_SRV`) private srv: `Service`\n\nThis specialized `@Inject` can be used as a `constant` and contains the `CDS.outboxed` service.\n\nIt can be injected in the following :\n\n- [@EntityHandler()](#entityhandler)\n- [@ServiceLogic()](#servicelogic)\n- [@Repository()](#repository)\n- [@UnboundActions()](#unboundactions)\n\n`Example`\n\n```typescript\nimport { EntityHandler, Inject, CDS_DISPATCHER } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Service } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\n// OR @ServiceLogic()\n// OR @Repository()\n// OR @UnboundActions()\nexport class CustomerHandler {\n  // @Inject dependencies\n  @Inject(CDS_DISPATCHER.OUTBOXED_SRV) private readonly outboxedSrv: Service;\n\n  constructor() {}\n  // ...\n}\n```\n\n\u003e [!TIP]\n\u003e More info about `outboxed` ca be found at [SAP CAP Node.js Outboxed](https://cap.cloud.sap/docs/node.js/outbox)\n\n\u003e [!TIP]\n\u003e The CDS.ApplicationService can be accessed trough `this.outboxedSrv`\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n#### `Parameter`\n\n##### @Req\n\n**@Req()**\n\nThe `@Req` decorator is utilized at the `parameter level` to annotate a parameter with the `Request` object, providing access to request-related information of the current event.\n\n`Return`\n\n- `Request`: An instance of `@sap/cds` - `Request`\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // ... all events like @AfterRead, @BeforeRead ...\n\n  @AfterRead()\n  private async aMethod(@Req() req: Request, @Results() results: MyEntity[]) {\n    // ... req...\n  }\n}\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Res\n\n**@Res()**\n\nThe `@Res` decorator is utilized at the `parameter level` to annotate a parameter with the `Request.http.res - (Response)` object, providing access to response-related information of the current event and it can be used to enhance the `Response`.\n\n`Return`\n\n- `RequestResponse`: An instance of `RequestResponse` providing you response-related information.\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request, RequestResponse } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // ... all events like @AfterRead, @BeforeRead ...\n\n  @AfterRead()\n  private async aMethod(@Req() req: Request, @Res() response: RequestResponse, @Results() results: MyEntity[]) {\n    // Example: we assume we want to add a new header language on the response\n    // We use =\u003e res.setHeader('Accept-Language', 'DE_de');\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Decorator `@Res` can be used in all [After](#after), [Before](#before) and [On](#on) events.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Results / @Result\n\n**@Results()** / **@Result**\n\nThe `@Results` decorator is utilized at the `parameter level` to annotate a parameter with the request `Results`.\n\n`Return`\n\n- `Array / object`: Contains the OData Request `Body`.\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // ... all events like @AfterRead, @BeforeRead ...\n\n  @AfterRead()\n  private async aMethod(@Req() req: Request, @Results() results: MyEntity[]) {\n    // ...\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e When using [@AfterCreate()](#aftercreate), [@AfterUpdate()](#afterupdate) and [@AfterDelete()](#afterdelete) it's recommended to use the `@Result` decorator for single object result and `@Results` for arrays of objects.\n\n```ts\n@AfterCreate()\n@AfterUpdate()\nprivate async aMethod(\n   @Result() result: Book, // \u003c== @Result() decorator used to annotate it's a an object and not an array\n   @Req() req: Request,\n ) {\n   // ...\n }\n\n@AfterRead()\nprivate async aMethod(\n  @Results() result: Book[], // \u003c== @Results() decorator used to annotate as array of objects\n  @Req() req: Request,\n) {\n  // ...\n}\n\n@AfterDelete()\nprivate async aMethod(\n@Result() deleted: boolean, // \u003c== @Result() decorator used to annotate as a boolean\n@Req() req: Request,\n) {\n  // ...\n}\n```\n\n\u003e [!TIP]\n\u003e Decorators `@Results()` and `@Result()` can be applied to all [After](#after) events.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Next\n\n**@Next()**\n\nThe `@Next` decorator is utilized at the `parameter level` to annotate a parameter with the `Next` function, which is used to proceed to the next event in the chain of execution.\n\n`Return`\n\n- `NextEvent`: The next event in chain to be called.\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // ... all events like @AfterRead, @BeforeRead, @OnCreate ...\n\n  @OnCreate()\n  public async onCreate(@Req() req: Request\u003cMyEntity\u003e, @Next() next: NextEvent) {\n    return next();\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Decorator `@Next` can be applied to all [On](#on), [On - draft](#on-1) event decorators.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Error\n\n**@Error()**\n\nThe `@Error` decorator is utilized at the `parameter level` to annotate a parameter with the `Error` and contains information regarding the failed `Request`.\n\n`Return`\n\n- `Error`: An instance of type `Error`.\n\n`Example`\n\n```typescript\nimport { UnboundActions, Req, Error } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@UnboundActions()\nexport class UnboundActionsHandler {\n  // ...\n  constructor() {}\n\n  @OnError()\n  public onError(@Error() err: Error, @Req() req: Request): void {\n    // ...\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Decorator `@Error` can be applied to [@OnError()](#onerror) decorator which resides inside of the [@UnboundActions()](#unboundactions).\n\n##### @Jwt\n\n**@Jwt()**\n\nThe `@Jwt` decorator is utilized at the `parameter level`. It will retrieve the to retrieve `JWT` from the `Request` that is based on the node `req.http.req - IncomingMessage`.\n\nFails if no authorization header is given or has the wrong format.\n\n`Return`\n\n- `string` | `undefined` : The retrieved `JWT token` or undefined if no token was found.\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results, Jwt } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // ... all events like @AfterRead, @BeforeRead ...\n\n  @AfterRead()\n  private async aMethod(@Req() req: Request, @Results() results: MyEntity[], @Jwt() jwt: string | undefined) {\n    // ... req...\n  }\n}\n```\n\n\u003e [!IMPORTANT]\n\u003e Expected format is `Bearer \u003cTOKEN\u003e`.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @IsPresent\n\n**@IsPresent\\\u003cKey extends CRUDQueryKeys\u003e(key: Key, property: PickQueryPropsByKey\\\u003cKey\u003e)**\n\nThe `@IsPresent` decorator is utilized at the `parameter level`. It allows you to verify the existence of a specified Query `property` values.\n\n`Parameters`\n\n- `key (string)`: Specifies the type of query operation. Accepted values are `INSERT`, `SELECT`, `UPDATE`, `UPSERT`, `DELETE`.\n- `property (string)`: Specifies the property based on the `key`.\n\n`Return`\n\n- `boolean`: This decorator returns `true` if `property` `value` is filled, `false` otherwise\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results, IsPresent } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nclass BookHandler {\n  // ...\n  constructor() {}\n\n  @AfterRead()\n  private async aMethod(\n    @Req() req: Request,\n    @Results() results: MyEntity[],\n\n    @IsPresent('SELECT', 'columns') columnsPresent: boolean,\n  ) {\n    if (columnsPresent) {\n      // ...\n    }\n\n    // ...\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Decorator [@IsPresent()](#ispresent) works well with [@GetQuery()](#getquery).\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @IsRole\n\n**@IsRole(...roles: string[])**\n\nThe `@IsRole` decorator is utilized at the `parameter level`. It allows you to verify\nif the `User` has assigned a given role.\n\nIt applies an logical `OR` on the specified roles, meaning it checks if at `least one` of the specified roles is assigned\n\n`Parameters`\n\n- `role (...string[])`: An array of role names to check if are assigned.\n\n`Return`\n\n- `boolean`: This decorator returns `true` if at least one of the specified roles is assigned to the current request user, otherwise `false`.\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results, IsPresent, IsRole } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nclass BookHandler {\n  // ...\n  constructor() {}\n\n  @AfterRead()\n  private async aMethod(\n    @Req() req: Request,\n    @Results() results: MyEntity[],\n\n    @IsRole('role', 'anotherRole') roleAssigned: boolean,\n  ) {\n    if (roleAssigned) {\n      // ...\n    }\n\n    // ...\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e The role names correspond to the values of `@requires` and the `@restrict.grants.to` annotations in your `CDS` models.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @IsColumnSupplied\n\n**@IsColumnSupplied\\\u003cT\\\u003e(field : keyof T)**\n\nThe `@IsColumnSupplied\u003cT\u003e(field : keyof T)` decorator is utilized at the `parameter level`. It allows your to verify the existence of a column in the `SELECT`, `INSERT` or `UPSERT` Query.\n\n`Parameters`\n\n- `field (string)`: A string representing the name of the column to be verified.\n\n`Type Parameters`\n\n- `T`: The entity type (e.g., `MyEntity`) representing the table or collection on which the decorator operates. This allows TypeScript to enforce type safety for the field parameter.\n\n`Return` :\n\n- `boolean`: This decorator returns `true` if `field / column` was found, `false` otherwise\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results, IsPresent } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nclass BookHandler {\n  // ...\n  constructor() {}\n\n  @AfterRead()\n  private async aMethod(\n    @Req() req: Request,\n    @Results() results: MyEntity[],\n\n    @IsColumnSupplied\u003cMyEntity\u003e('price') priceSupplied: boolean,\n  ) {\n    if (priceSupplied) {\n      // ...\n    }\n\n    // ...\n  }\n}\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @GetQuery\n\n**@GetQuery\\\u003cKey extends CRUDQueryKeys\u003e(key: Key, property: PickQueryPropsByKey\\\u003cKey\u003e)**\n\nThe `@GetQuery` decorator is utilized at the `parameter level`. It allows you to retrieve Query `property` values.\n\n`Parameters`\n\n- `key (string)`: Specifies the type of query operation. Accepted values are `INSERT`, `SELECT`, `UPDATE`, `UPSERT`, `DELETE`.\n- `property (string)`: Specifies the property based on the `key`.\n\n`Return`: Varies based on the specified property :\n\n- \u003cdetails\u003e\n\n  \u003csummary\u003eSELECT\u003c/summary\u003e\n\n  - @GetQuery(`'SELECT'`, `'columns'`) columns: `GetQueryType['columns']['forSelect']`\n  - @GetQuery(`'SELECT'`, `'distinct'`) distinct: `GetQueryType['distinct']`\n  - @GetQuery(`'SELECT'`, `'excluding'`) excluding: `GetQueryType['excluding']`\n  - @GetQuery(`'SELECT'`, `'from'`) from: `GetQueryType['from']['forSelect']`\n  - @GetQuery(`'SELECT'`, `'groupBy'`) groupBy: `GetQueryType['groupBy']`\n  - @GetQuery(`'SELECT'`, `'having'`) having: `GetQueryType['having']`\n  - @GetQuery(`'SELECT'`, `'limit'`) limit: `GetQueryType['limit']`\n  - @GetQuery(`'SELECT'`, `'limit.rows'`) limitRows: `GetQueryType['limit']['rows']`\n  - @GetQuery(`'SELECT'`, `'limit.offset'`) limitOffset: `GetQueryType['limit']['offset']`\n  - @GetQuery(`'SELECT'`, `'mixin'`) mixin: `GetQueryType['mixin']`\n  - @GetQuery(`'SELECT'`, `'one'`) one: `GetQueryType['one']`\n  - @GetQuery(`'SELECT'`, `'orderBy'`) orderBy: `GetQueryType['orderBy']`\n  - @GetQuery(`'SELECT'`, `'where'`) where: `GetQueryType['where']`\n\n  \u003c/details\u003e\n\n- \u003cdetails\u003e\n\n  \u003csummary\u003eINSERT\u003c/summary\u003e\n\n  - @GetQuery(`'INSERT'`, `'as'`) as: `GetQueryType['as']`\n  - @GetQuery(`'INSERT'`, `'columns'`) columns: `GetQueryType['columns']['forInsert']`\n  - @GetQuery(`'INSERT'`, `'entries'`) entries: `GetQueryType['entries']`\n  - @GetQuery(`'INSERT'`, `'into'`) into: `GetQueryType['into']`\n  - @GetQuery(`'INSERT'`, `'rows'`) rows: `GetQueryType['rows']`\n  - @GetQuery(`'INSERT'`, `'values'`) values: `GetQueryType['values']`\n\n  \u003c/details\u003e\n\n- \u003cdetails\u003e\n\n    \u003csummary\u003eUPDATE\u003c/summary\u003e\n\n  - @GetQuery(`'UPDATE'`, `'data'`) data: `GetQueryType['data']`\n  - @GetQuery(`'UPDATE'`, `'entity'`) entity: `GetQueryType['entity']`\n  - @GetQuery(`'UPDATE'`, `'where'`) where: `GetQueryType['where']`\n\n  \u003c/details\u003e\n\n- \u003cdetails\u003e\n\n    \u003csummary\u003eUPSERT\u003c/summary\u003e\n\n  - @GetQuery(`'UPSERT'`, `'columns'`) columns: `GetQueryType['columns'][forUpsert]`\n  - @GetQuery(`'UPSERT'`, `'entries'`) entries: `GetQueryType['entries']`\n  - @GetQuery(`'UPSERT'`, `'into'`) into: `GetQueryType['into']`\n  - @GetQuery(`'UPSERT'`, `'rows'`) rows: `GetQueryType['rows']`\n  - @GetQuery(`'UPSERT'`, `'values'`) values: `GetQueryType['values']`\n\n  \u003c/details\u003e\n\n- \u003cdetails\u003e\n\n    \u003csummary\u003eDELETE\u003c/summary\u003e\n\n  - @GetQuery(`'DELETE'`, `'from'`) from: `GetQueryType['from'][forDelete]`\n  - @GetQuery(`'DELETE'`, `'where'`) columns: `GetQueryType['where']`\n\n    \u003c/details\u003e\n\n`Example`\n\n```typescript\nimport { EntityHandler, Req, Results, IsPresent, GetQuery } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request, GetQueryType } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nclass BookHandler {\n  // ...\n  constructor() {}\n\n  @AfterRead()\n  private async aMethod(\n    @Req() req: Request,\n    @Results() results: MyEntity[],\n\n    // Check existence of columns\n    @IsPresent('SELECT', 'columns') columnsPresent: boolean,\n\n    // Get columns\n    @GetQuery('SELECT', 'columns') columns: GetQueryType['columns']['forSelect'],\n\n    @GetQuery('SELECT', 'orderBy') orderBy: GetQueryType['orderBy'],\n    @GetQuery('SELECT', 'groupBy') groupBy: GetQueryType['groupBy'],\n  ) {\n    if (columnsPresent) {\n      // do something with columns values\n      // columns.forEach(...)\n    }\n\n    // ...\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Decorator [@GetQuery()](#getquery) can be used to get the Query property and [@IsPresent()](#ispresent) can check if the Query property is empty or not.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @GetRequest\n\n**@GetRequest(property : keyof Request)**\n\nThe `@GetRequest` decorator is utilized at the `parameter level`. It allows you to retrieve the specified `property` value from the `Request` object.\n\n`Parameters`\n\n- `property (string)`: Specifies the property to retrieve from the `Request` object.\n\n`Return`: Varies based on the specified property :\n\n- **@GetRequest**(`'entity'`) entity: `Request['entity']`,\n- **@GetRequest**(`'event'`) event: `Request['event']`,\n- **@GetRequest**(`'features'`) features: `Request['features']`,\n- **@GetRequest**(`'headers'`) headers: `Request['headers']`,\n- **@GetRequest**(`'http'`) http: `Request['http']`,\n- **@GetRequest**(`'id'`) id: `Request['id']`,\n- **@GetRequest**(`'locale'`) locale: `Request['locale']`,\n- **@GetRequest**(`'method'`) method: `Request['method']`,\n- **@GetRequest**(`'params'`) params: `Request['params']`,\n- **@GetRequest**(`'query'`) query: `Request['query']`,\n- **@GetRequest**(`'subject'`) subject: `Request['subject']`,\n- **@GetRequest**(`'target'`) target: `Request['target']`,\n- **@GetRequest**(`'tenant'`) tenant: `Request['tenant']`,\n- **@GetRequest**(`'timestamp'`) timestamp: `Request['timestamp']`,\n- **@GetRequest**(`'user'`) user: `Request['user']`,\n\n`Example`\n\n```typescript\nimport { EntityHandler, Results, GetRequest } from '@dxfrontier/cds-ts-dispatcher';\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@EntityHandler(MyEntity)\nclass BookHandler {\n  // ...\n  constructor() {}\n\n  @AfterRead()\n  private async aMethod(\n    // @Req() req: Request, we assume we don't need the hole Request object and we need only 'locale' and 'method'\n    @Results() results: MyEntity[],\n\n    @GetRequest('locale') locale: Request['locale'],\n    @GetRequest('method') method: Request['method'],\n  ) {\n    // do something with 'locale' and 'method' ...\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Type `Request` can be import from :\n\u003e\n\u003e ```ts\n\u003e import type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\u003e ```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @SingleInstanceSwitch\n\n**@SingleInstanceSwitch**\n\nThe `@SingleInstanceSwitch()` decorator is applied at the `parameter level`.\n\nIt allows you to manage different behaviors based on whether the request is for a `single entity instance` or `an entity set`, the parameter assigned to the decorator will behave like a **`switch`**.\n\n`Return`\n\n- `true` when the `Request` is `single instance`\n- `false` when the `Request` is `entity set`\n\n`Example 1`\n\nSingle request : \u003chttp://localhost:4004/odata/v4/main/`MyEntity(ID=2f12d711-b09e-4b57-b035-2cbd0a023a09)`\u003e\n\n```typescript\nimport { AfterRead, SingleInstanceCapable } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterRead()\nprivate async singeInstanceMethodAndEntitySet(@Results() results : MyEntity[], @Req() req: Request\u003cMyEntity\u003e, @SingleInstanceSwitch() isSingleInstance: boolean) {\n  if(isSingleInstance) {\n    // This will be executed only when single instance is called : http://localhost:4004/odata/v4/main/MyEntity(ID=2f12d711-b09e-4b57-b035-2cbd0a023a09)\n    return this.customerService.handleSingleInstance(req)\n  }\n\n  // nothing to entity set\n}\n```\n\n`Example 2`\n\nEntity request : \u003chttp://localhost:4004/odata/v4/main/`MyEntity`\u003e\n\n```typescript\nimport { AfterRead, SingleInstanceCapable } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterRead()\nprivate async singeInstanceMethodAndEntitySet(@Results() results : MyEntity[], @Req() req: Request\u003cMyEntity\u003e, @SingleInstanceSwitch() isSingleInstance: boolean) {\n  if(isSingleInstance) {\n    // This will be executed only when single instance is called : http://localhost:4004/odata/v4/main/MyEntity(ID=2f12d711-b09e-4b57-b035-2cbd0a023a09)\n    // ...\n  }\n\n  // ... this will be executed when entity set is called : http://localhost:4004/odata/v4/main/MyEntity\n  results[0] = {\n    name : 'new value'\n  }\n}\n```\n\n\u003e [!TIP]\n\u003e Decorator `@SingleInstanceSwitch` can be used together with the following decorator events:\n\u003e\n\u003e - [@AfterRead()](#afterread)\n\u003e - [@BeforeRead()](#beforeread)\n\u003e - [@OnRead()](#onread)\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @ValidationResults\n\n**@ValidationResults**\n\nThe `@ValidationResults` decorator allows to capture and inject validation results directly into a method parameter, allowing access to `individual validation flags` within the decorated method.\n\nWhen used alongside the [@Validate](#validate) decorator, it enables you to perform conditional logic based on specific validation outcomes.\n\n`Example`\n\n```ts\n@BeforeCreate()\n@Validate\u003cMyEntity\u003e({ action: 'isLowercase', exposeValidatorResult: true }, 'comment')\n@Validate\u003cMyEntity\u003e({ action: 'endsWith', target: 'N', exposeValidatorResult: true }, 'description')\npublic async beforeCreate(\n  @Req() req: Request\u003cMyEntity\u003e,\n  @ValidationResults() validator: ValidatorFlags\u003c'isLowercase' | 'endsWith'\u003e\n) {\n    // Conditional handling based on validation flags\n    if (validator.isLowercase) {\n      // Execute logic when field `comment` is lowercase \n    }\n    else {\n      // Execute logic when field `comment` is not lowercase\n    }\n\n    if (validator.endsWith) {\n      // Execute logic when field `description` is endsWith with letter 'N'\n    }\n    else {\n      // Execute logic when field `description` doesn't endsWith with letter 'N'\n    }\n}\n```\n\n\u003e [!IMPORTANT]\n\u003e For `@ValidationResults` to work, each [@Validate](#validate) decorator must set the `exposeValidatorResult` option to `true`. This ensures that the validation results are available as flags in the method.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Locale\n\n**@Locale**\n\nParameter decorator used to inject locale information into a method parameter.\n\n`Example`\n\n```ts\n@BeforeCreate()\npublic async beforeCreate(\n  @Req() req: Request\u003cMyEntity\u003e,\n  @Locale() locale: string\n) {\n  if (locale === 'en-US') {\n    // handle logic specific to the 'en-US' locale\n  }\n}\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Env\n\n**@Env\\\u003cT\\\u003e(env: PropertyStringPath\\\u003cT\\\u003e)**\n\nThe `@Env` decorator is a parameter decorator used to inject values from the cds.env configuration object directly into a method parameter.\n\n`Parameters`\n\n- `env (string)`: A string path representing a property from `cds.env`. This path follows the format `property string path`, which allows access to deeply nested configuration properties.\n  - E.g. : `'requires.db.credentials.url'` corresponds to **cds.env.requires.db.credentials.url** object.\n\n`Type Parameters`\n\n- `T`: The `CDS environmental variables` type (e.g., `cds env get`) representing the collection on which the decorator operates. This allows TypeScript to enforce type safety.\n\n`Return` :\n\n- The decorator returns the value of the specified `cds.env` property value.\n\n`Example`\n\n```ts\nimport { CDS_ENV } from '#dispatcher';  \n\n@BeforeCreate()\npublic async beforeCreate(\n  @Req() req: Request\u003cMyEntity\u003e,\n  @Env\u003cCDS_ENV\u003e('requires.db.credentials.url') dbUrl: CDS_ENV['requires']['db']['credentials']['url'],\n  // or @Env\u003cCDS_ENV\u003e('requires.db.credentials.url') dbUrl: string\n  // or @Env\u003cCDS_ENV\u003e('requires.db.credentials.url') dbUrl: any\n  // or any other type if you do not want to use the CDS_ENV generated types\n) {\n  if (dbUrl) {\n    // handle custom logic ...\n  }\n}\n```\n\n\u003e [!NOTE]\n\u003e When you install cds-ts-dispatcher `(e.g. npm install @dxfrontier/cds-ts-dispatcher)` or run a general `npm install`, the following will be generated or updated :\n\u003e\n\u003e - New `@dispatcher` folder is generated at the project _**root**_.\n\u003e This folder contains the `CDS ENV TS interfaces`, generated based on the structure of your current `cds.env` project specific configuration (retrieved from `cds env get` cli command).\n\u003e\n\u003e ```text\n\u003e ...\n\u003e @dispatcher\n\u003e ...\n\u003e ```\n\u003e\n\u003e - `package.json` will be updated with a new `import`:\n\u003e\n\u003e ```json\n\u003e  \"imports\": {\n\u003e    \"#dispatcher\": \"./@dispatcher/index.js\"\n\u003e  }\n\u003e ```\n\u003e\n\u003e - `tsconfig.json` will be updated:  \n\u003e\n\u003e ```json\n\u003e  \"include\": [\n\u003e    \"...\",\n\u003e    \"./@dispatcher\"\n\u003e  ]\n\u003e ```\n\u003e\n\u003e - `.gitignore` will be updated::\n\u003e\n\u003e ```text\n\u003e ...\n\u003e @dispatcher\n\u003e ```\n\n\u003e [!NOTE]\n\u003e The `@dispatcher` folder is _**regenerated each time you run npm install.**_\n\n\u003e [!TIP]\n\u003e You can import the generated `CDS env` from the generated `@dispatcher` folder by using :\n\u003e\n\u003e ```ts\n\u003e import { CDS_ENV } from '#dispatcher'; \n\u003e ```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### @Msg\n\n**@Msg()**\n\nThe `@Msg` decorator is a parameter decorator used to inject response [Emitter](#https://cap.cloud.sap/docs/guides/messaging/#typical-emitter-and-receiver-roles) response object directly into a method parameter.\n\n`Parameters`\n\n`Return` :\n\n- The decorator returns an object of type : \n\n```ts\n{\n  event: string,\n  data: any,\n  headers: any,\n  inbound: boolean\n}\n```\n\n`Example`\n\n```ts\nimport { OnSubscribe, Messaging } from '@dxfrontier/cds-ts-dispatcher';  \nimport type { SubscriberType } from '@dxfrontier/cds-ts-dispatcher';  \n\n@OnSubscribe({\n  eventName: 'AnEventName',\n  type: 'MESSAGE_BROKER',\n})\npublic async onSubscribe(@Msg() msg: SubscriberType\u003c{ foo: number; bar: string }\u003e): Promise\u003cvoid\u003e {\n  // ...\n}\n```\n\u003e [!IMPORTANT]\n\u003e To have the `msg` typed you can use TypeScript type `SubscriberType\u003cT\u003e` where T can be a CDS event or any object\n\n\u003e [!TIP]\n\u003e Decorator `@Msg` should be used exclusively on decorator [@OnSubscribe](#onsubscribe).\n\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n#### `Method`-`active entity`\n\n##### `Before`\n\nUse [@BeforeCreate()](#beforecreate), [@BeforeRead()](#beforeread), [@BeforeUpdate()](#beforeupdate), [@BeforeDelete()](#beforedelete) to register handlers to run before `.on` handlers, frequently used for `validating user input.`\n\nThe handlers receive one argument:\n\n- `req` of type `Request`\n\nSee also the official SAP JS **[CDS-Before](https://cap.cloud.sap/docs/node.js/core-services#srv-before-request) event**\n\n\u003e [!TIP]\n\u003e If `@odata.draft.enabled: true` to manage event handlers for draft version you can use\n\u003e\n\u003e - `@BeforeCreateDraft()`\n\u003e - `@BeforeReadDraft()`\n\u003e - `@BeforeUpdateDraft()`\n\u003e - `@BeforeDeleteDraft()`\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeCreate\n\n**@BeforeCreate**()\n\n`Example`\n\n```typescript\nimport { BeforeCreate } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeCreate()\nprivate async beforeCreateMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('CREATE', MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e It is important to note that the decorator `@BeforeCreate()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeRead\n\n**@BeforeRead**()\n\n`Example`\n\n```typescript\nimport { BeforeRead } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeRead()\nprivate async beforeReadMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('READ', MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeRead()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeUpdate\n\n**@BeforeUpdate**()\n\n`Example`\n\n```typescript\nimport { BeforeUpdate } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeUpdate()\nprivate async beforeUpdateMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('UPDATE', MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeUpdate()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeDelete\n\n**@BeforeDelete**()\n\n`Example`\n\n```typescript\nimport { BeforeDelete } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeDelete()\nprivate async beforeDeleteMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('DELETE', MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeDelete()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeAll\n\nThe `@BeforeAll` decorator is triggered whenever **_any CRUD (Create, Read, Update, Delete)_** event occurs, whether the entity is `active` or in `draft` mode.\n\n`ACTIVE ENTITY`\n\nFor active entities, the @BeforeAll decorator will be triggered when at least __one__ of the following events occurs:\n\n- `CREATE` [@BeforeCreate()](#beforecreate), [@AfterCreate()](#aftercreate), [@OnCreate()](#oncreate)\n- `READ` [@BeforeRead()](#beforeread), [@AfterRead()](#afterread), [@OnRead()](#onread)\n- `UPDATE` [@BeforeUpdate()](#beforeupdate), [@AfterUpdate()](#afterupdate), [@OnUpdate()](#onupdate)\n- `DELETE` [@BeforeDelete()](#beforedelete), [@AfterDelete()](#afterdelete), [@OnDelete()](#ondelete)\n- `BOUND ACTIONS` [@OnBoundAction()](#onboundaction)\n- `BOUND FUNCTIONS` [@OnBoundFunction()](#onboundfunction)\n\n`DRAFT`\n\nFor draft entities, the @BeforeAll decorator will be triggered when at least __one__ of the following events occurs:\n\n- `CREATE` [@BeforeNewDraft()](#beforenewdraft), [@AfterNewDraft()](#afternewdraft), [@OnNewDraft()](#onnewdraft)\n- `CANCEL` [@BeforeCancelDraft()](#beforecanceldraft), [@AfterCancelDraft()](#aftercanceldraft), [@OnCancelDraft()](#oncanceldraft)\n- `EDIT` [@BeforeEditDraft()](#beforeeditdraft), [@AfterEditDraft()](#aftereditdraft), [@OnEditDraft()](#oneditdraft)\n- `SAVE` [@BeforeSaveDraft()](#beforesavedraft), [@AfterSaveDraft()](#aftersavedraft), [@OnSaveDraft()](#onsavedraft)\n- :heavy_plus_sign: All active entity [Before](#before), [After](#after), [On](#on) events which have a `Draft` variant.\n\n**@BeforeAll**()\n\n`Example 1`\n\nIn this example, the `@BeforeAll()` decorator of the `beforeAllEvents` method is executed before any CRUD operation `(CREATE, READ, UPDATE, DELETE, BOUND ACTIONS, BOUND FUNCTIONS))` on the `MyEntity` entity. \n\nSince the class is annotated with `@EntityHandler(MyEntity)`, the decorator is scoped to this specific `entity`, meaning it will only be triggered for operations related to `MyEntity`.\n\n```typescript\nimport { BeforeAll, EntityHandler } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n\n  @BeforeAll()\n  private async beforeAllEvents(@Req() req: Request\u003cMyEntity\u003e) {\n    // ...\n  }\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('*', MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n`Example 2`\n\nIn this example, the `@BeforeAll()` decorator is used in a more generic way. Unlike `Example 1`, where it applies only to `MyEntity`, this setup ensures that `beforeAllEvents` is triggered for `all entities`. \n\nThis means the method will execute before any CRUD operation on `any` `entity` handled within the class.\n\n```typescript\nimport { BeforeAll, EntityHandler, CDS_DISPATCHER } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(CDS_DISPATCHER.ALL_ENTITIES)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n\n  @BeforeAll()\n  private async beforeAllEvents(@Req() req: Request\u003cMyEntity\u003e) {\n    // ...\n  }\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('*', '*', async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeAll()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!TIP]\n\u003e If the entity has drafts enabled `@odata.draft.enabled: true`, the `@BeforeAll` decorator will still be triggered for draft events.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### `After`\n\nUse [@AfterCreate()](#aftercreate), [@AfterRead()](#afterread), [@AfterUpdate()](#afterupdate), [@AfterDelete()](#afterdelete) register handlers to run after the `.on` handlers, frequently used to `enrich outbound data.`\n\nThe handlers receive two arguments:\n\n| Parameters     | Decorator                         | Description                                                                |\n| -------------- | --------------------------------- | -------------------------------------------------------------------------- |\n| `results, req` | `@AfterRead`                      | An array of type `MyEntity[]` and the `Request`.                           |\n| `result, req`  | `@AfterUpdate`\u003cbr\u003e `@AfterCreate` | An object of type `MyEntity` and the `Request`.                            |\n| `deleted, req` | `@AfterDelete`                    | A `boolean` indicating whether the instance was deleted and the `Request`. |\n\n\u003e [!TIP]\n\u003e If `@odata.draft.enabled: true` to manage event handlers for draft version you can use :\n\u003e\n\u003e - `@AfterCreateDraft()`\n\u003e - `@AfterReadDraft()`\n\u003e - `@AfterReadDraftSingleInstance()`\n\u003e - `@AfterUpdateDraft()`\n\u003e - `@AfterDeleteDraft()`\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @AfterCreate\n\n**@AfterCreate**()\n\n`Example`\n\n```typescript\nimport { AfterCreate } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterCreate()\nprivate async afterCreateMethod(@Result() result: MyEntity, @Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('CREATE', MyEntity, async (result, req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@AfterCreate()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @AfterRead\n\n**@AfterRead**()\n\n`Example`\n\n```typescript\nimport { AfterRead, Results, Req } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterRead()\nprivate async afterReadMethod(@Results() results: MyEntity[], @Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('READ', MyEntity, async (results, req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@AfterRead()` will be triggered based on the [EntityHandler](#entityhandler) `argument` `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @AfterReadEachInstance\n\n**@AfterReadEachInstance**()\n\nThe `@AfterReadEachInstance` decorator is used to execute custom logic after performing a read operation on `each individual instance`. This behavior is analogous to the JavaScript `Array.prototype.forEach` method.\n\n`Example`\n\n```typescript\nimport { AfterReadEachInstance, Result, Req } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterReadEachInstance()\nprivate async afterEach(@Result() result: MyEntity, @Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('each', MyEntity, async (result, req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@AfterReadEachInstance()` will be triggered based on the [EntityHandler](#entityhandler) `argument` `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @AfterUpdate\n\n**@AfterUpdate**()\n\n`Example`\n\nSingle request : \u003chttp://localhost:4004/odata/v4/main/`MyEntity(ID=2f12d711-b09e-4b57-b035-2cbd0a023a09)`\u003e\n\n```typescript\nimport { AfterUpdate } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterUpdate()\nprivate async afterUpdateMethod(@Result() result: MyEntity, @Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('UPDATE', MyEntity, async (result, req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@AfterUpdate()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @AfterDelete\n\n**@AfterDelete**()\n\n`Example`\n\n```typescript\nimport { AfterDelete} from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@AfterDelete()\nprivate async afterDeleteMethod(@Result() deleted: boolean, @Req() req: Request) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('DELETE', MyEntity, async (deleted, req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@AfterDelete()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @AfterAll\n\nThe `@AfterAll` decorator is triggered whenever **_any CRUD (Create, Read, Update, Delete)_** event occurs, whether the entity is `active` or in `draft` mode.\n\n`ACTIVE ENTITY`\n\nFor active entities, the `@AfterAll` decorator will be triggered when at least __one__ of the following events occurs:\n\n- `CREATE` [@BeforeCreate()](#beforecreate), [@AfterCreate()](#aftercreate), [@OnCreate()](#oncreate)\n- `READ` [@BeforeRead()](#beforeread), [@AfterRead()](#afterread), [@OnRead()](#onread)\n- `UPDATE` [@BeforeUpdate()](#beforeupdate), [@AfterUpdate()](#afterupdate), [@OnUpdate()](#onupdate)\n- `DELETE` [@BeforeDelete()](#beforedelete), [@AfterDelete()](#afterdelete), [@OnDelete()](#ondelete)\n- `BOUND ACTIONS` [@OnBoundAction()](#onboundaction)\n- `BOUND FUNCTIONS` [@OnBoundFunction()](#onboundfunction)\n\n`DRAFT`\n\nFor draft entities, the `@AfterAll` decorator will be triggered when at least __one__ of the following events occurs:\n\n- `CREATE` [@BeforeNewDraft()](#beforenewdraft), [@AfterNewDraft()](#afternewdraft), [@OnNewDraft()](#onnewdraft)\n- `CANCEL` [@BeforeCancelDraft()](#beforecanceldraft), [@AfterCancelDraft()](#aftercanceldraft), [@OnCancelDraft()](#oncanceldraft)\n- `EDIT` [@BeforeEditDraft()](#beforeeditdraft), [@AfterEditDraft()](#aftereditdraft), [@OnEditDraft()](#oneditdraft)\n- `SAVE` [@BeforeSaveDraft()](#beforesavedraft), [@AfterSaveDraft()](#aftersavedraft), [@OnSaveDraft()](#onsavedraft)\n- :heavy_plus_sign: All active entity [Before](#before), [After](#after), [On](#on) events which have a `Draft` variant.\n\n**@AfterAll**()\n\n`Example 1`\n\nIn this example, the `@AfterAll()` decorator of the `afterAll` method is executed after any CRUD operation `(CREATE, READ, UPDATE, DELETE, BOUND ACTIONS, BOUND FUNCTIONS))` on the `MyEntity` entity. \n\nSince the class is annotated with `@EntityHandler(MyEntity)`, the decorator is scoped to this specific `entity`, meaning it will only be triggered for operations related to `MyEntity`.\n\n```typescript\nimport { AfterAll, EntityHandler } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n\n  @AfterAll()\n  private async afterAll(@Result() result: MyEntity | MyEntity[] | boolean, @Req() req: Request) {\n    if(Array.isArray(result)) {\n      // when after `READ` event was triggered\n    }\n    else if(typeof result === 'boolean' ) {\n      // when after `DELETE` event was triggered\n    }\n    else {\n      // when after `CREATE`, `UPDATE` was triggered\n    }\n\n    // ...\n  }\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('*', MyEntity, async (result, req) =\u003e {\n  // ...\n});\n```\n\n`Example 2`\n\nIn this example, the `@AfterAll()` decorator is used in a more generic way. Unlike `Example 1`, where it applies only to `MyEntity`, this setup ensures that `afterAll` is triggered for `all entities`. \n\nThis means the method will execute before any CRUD operation on `any` `entity` handled within the class.\n\n```typescript\nimport { AfterAll, EntityHandler} from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(CDS_DISPATCHER.ALL_ENTITIES)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n\n  @AfterAll()\n  private async afterAll(@Result() result: MyEntity | MyEntity[] | boolean, @Req() req: Request) {\n    if(Array.isArray(result)) {\n      // when after `READ` event was triggered\n    }\n    else if(typeof result === 'boolean' ) {\n      // when after `DELETE` event was triggered\n    }\n    else {\n      // when after `CREATE`, `UPDATE` was triggered\n    }\n\n    // ...\n  }\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('*', '*', async (result, req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@AfterAll()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!TIP]\n\u003e If the entity has drafts enabled `@odata.draft.enabled: true`, the `@AfterAll` decorator will also be triggered for draft events.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n##### `On`\n\nUse [@OnCreate()](#oncreate), [@OnRead()](#onread), [@OnUpdate()](#onupdate), [@OnDelete()](#ondelete), [OnAction()](#onaction), [@OnFunction()](#onfunction), [@OnBoundAction()](#onboundaction), [@OnBoundFunction()](#onboundfunction) handlers to fulfill requests, e.g. by reading/writing data from/to databases handlers.\n\nThe handlers receive two arguments:\n\n- `req` of type `Request`\n- `next` of type `NextEvent`\n\n\u003e [!TIP]\n\u003e If `@odata.draft.enabled: true` to manage event handlers for draft version you can use :\n\u003e\n\u003e - `@OnCreateDraft()`\n\u003e - `@OnReadDraft()`\n\u003e - `@OnUpdateDraft()`\n\u003e - `@OnDeleteDraft()`\n\u003e - `@OnBoundActionDraft()`\n\u003e - `@OnBoundFunctionDraft()`\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnCreate\n\n**@OnCreate**()\n\n`Example`\n\n```typescript\nimport { OnCreate, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnCreate()\nprivate async onCreateMethod(@Req() req: Request\u003cMyEntity\u003e, @Next() next: NextEvent) {\n  // ...\n\n  return next();\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('CREATE', MyEntity, async (req, next) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnCreate()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnRead\n\n**@OnRead**()\n\n`Example`\n\n```typescript\nimport { OnRead, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnRead()\nprivate async onReadMethod(@Req() req: Request\u003cMyEntity\u003e, @Next() next: NextEvent) {\n  // ...\n\n  return next();\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('READ', MyEntity, async (req, next) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnRead()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnUpdate\n\n**@OnUpdate**()\n\n`Example`\n\n```typescript\n\nimport { OnUpdate, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnUpdate()\nprivate async onUpdateMethod(@Req() req: Request\u003cMyEntity\u003e, @Next() next: NextEvent) {\n  // ...\n\n  return next();\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('UPDATE', MyEntity, async (req, next) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnUpdate()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnDelete\n\n**@OnDelete**()\n\n`Example`\n\n```typescript\nimport { OnDelete, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnDelete()\nprivate async onDeleteMethod(@Req() req: Request\u003cMyEntity\u003e, @Next() next: NextEvent) {\n  // ...\n\n  return next();\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('DELETE', MyEntity, async (req, next) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnDelete()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnAction\n\n**@OnAction**(`name` : CdsAction)\n\n`Parameters`\n\n- `name (CdsAction)` : Representing the `CDS action` defined in the `CDS file`\n\n`Example`\n\n```typescript\n\nimport { OnAction, Req, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { ActionRequest, ActionReturn, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { AnAction } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnAction(AnAction)\nprivate async onActionMethod(@Req() req: ActionRequest\u003ctypeof AnAction\u003e, @Next() next: NextEvent): ActionReturn\u003ctypeof AnAction\u003e {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on(AnAction, async (req, next) =\u003e {\n  // ...\n});\n```\n\n\u003e [!NOTE]\n\u003e AnAction was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003e [!IMPORTANT]  \n\u003e Decorator `@OnAction` should be used inside [@UnboundActions()](#unboundactions) class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnFunction\n\n**@OnFunction**(`name` : CdsFunction)\n\n`Parameters`\n\n- `name (CdsFunction)` : Representing the `CDS action` defined in the `CDS file`.\n\n`Example`\n\n```typescript\nimport { OnFunction, Req, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { ActionRequest, ActionReturn, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { AFunction } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnFunction(AFunction)\nprivate async onFunctionMethod(@Req() req: ActionRequest\u003ctypeof AFunction\u003e, @Next() next: NextEvent): ActionReturn\u003ctypeof AFunction\u003e {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on(AFunction, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!NOTE]\n\u003e AFunction was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003e [!IMPORTANT]  \n\u003e Decorator `@OnFunction` should be used inside [@UnboundAction()](#unboundactions) class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnEvent\n\n**@OnEvent**(`name` : CdsEvent)\n\nThe `@OnEvent` decorator facilitates the listening of events when the [Emit](https://cap.cloud.sap/docs/guides/messaging/) and receiver are in the same `NODE JS PROCESS` and `SAME SERVICE`.\n\nThis decorator is particularly useful in conjunction with the [Emit method](https://cap.cloud.sap/docs/guides/messaging/#emitting-events) to handle triggered events.\n\n`Parameters`\n\n- `name (CdsEvent)` : Representing the `CDS event` defined in the `CDS file`.\n\n`Example`\n\n```typescript\nimport { OnEvent, Req, OnSubscribe } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { AEvent } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnEvent(AEvent)\nprivate async onEventMethod(@Req() req: Request\u003cAEvent\u003e) {\n  // ...\n}\n\n// same as\n\n@OnSubscribe({\n  eventName: AEvent,\n  type: 'SAME_NODE_PROCESS',\n})\nprivate async onEventMethod(@Req() req: Request\u003cAEvent\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('AEvent', async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!NOTE] \n\u003e The `AEvent` was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003e [!IMPORTANT]  \n\u003e Decorator `@OnEvent` should be used inside [@UnboundActions](#unboundactions) class.\n\n\u003e [!TIP]\n\u003e An exended version of this event can be found [@OnSubscribe](#onsubscribe).\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnSubscribe\n\n```ts\n@OnSubscribe(options : {\n  eventName: string | object,\n  type : 'SAME_NODE_PROCESS' | 'MESSAGE_BROKER' | 'SAME_NODE_PROCESS_DIFFERENT_SERVICE'\n  externalServiceName: string // applicable only for 'SAME_NODE_PROCESS_DIFFERENT_SERVICE'\n  showReceiverMessage?: boolean\n  consoleStyle?: 'table | 'debug'\n})\n```\n\nUse `@OnSubscribe` decorator enables execution of custom logic when messaging events (`event bus` / `publish subscribe`) are triggered in your SAP CAP application.\n\nThis decorator is particularly useful in conjunction with the [Emit method](https://cap.cloud.sap/docs/guides/messaging/#emitting-events) to handle triggered events.\n\n`Parameters`\n\n- `options`:\n  - `name`: CdsEvent - The name of the event to subscribe to. This can be a `string` or a `CDS event` type imported from your `@cds-models` folder.\n  - `type`: Defines the messaging transport mechanism for SAP CAP applications.\n    - `'SAME_NODE_PROCESS'` - Use when both `emitter` and `receiver` run in the same `CAP server instance` \u0026 `same service`.\n    - `'SAME_NODE_PROCESS_DIFFERENT_SERVICE'` - Use when `emitter` can be found in E.g. `Service A` and `receiver` can reside in E.g. `Service B`, having same `CAP server instance` but `different services`.\n    - `'MESSAGE_BROKER'` - Recommended for production with external message brokers, different CAP Server instances, different services.\n  - `showReceiverMessage?` `[optional]`: **boolean** - When enabled, logs inbound message payloads in the specified `consoleStyle` format.\n  - `externalServiceName`: - The name of the external service to attach the subscribe decorator to. `[Applicable only when type is 'SAME_NODE_PROCESS_DIFFERENT_SERVICE' ]`\n  - `consoleStyle?` `[optional]` - Specifies the log output format for received messages (when `showReceiverMessage` is true).\n    - `'table'`: Displays data using `console.table()`, ideal for structured messages.\n    - `'debug'`: Displays data using  `console.debug()`, ideal for nested or dynamic messages.\n\n`Example 1`\n\nIn this example we emit the event in same `node process` and `same service` and we subscribe to it.\n\n`Emitting and subscribing:`\n\n```ts\nimport { OnSubscribe, Req, OnEvent } from '@dxfrontier/cds-ts-dispatcher';\nimport type { SubscriberType, Request } from '@dxfrontier/cds-ts-dispatcher';\n\n// Emitting the event\n@AfterRead()\nprivate async afterRead(\n  @Req() req: Request,\n  @Results() results: MyEntity[],\n): Promise\u003cvoid\u003e {\n  this.srv.emit('anEventName', { foo: 11, bar: '22' });\n}\n\n// Subscribing to the event\n@OnSubscribe({ \n  eventName: 'anEventName'\n  type: 'SAME_NODE_PROCESS', \n})\nprivate async onSubscribe(@Req() req: Request\u003c{ foo: number, bar: string }\u003e): Promise\u003cvoid\u003e {\n  // \n}\n\n// same as\n\n@OnEvent('anEventName')\nprivate async onEventMethod(@Req() req: Request\u003c{ foo: number, bar: string }\u003e) {\n  // ...\n}\n\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('READ', MyEntity, async (req, res) =\u003e {\n  this.emit('anEventName', { foo: 11, bar: '22' });\n});\n\nthis.on('anEventName', async (msg) =\u003e {\n  // ...\n});\n```\n\n`Example 2`\n\nIn this example we emit the event in same `node process` and `same service` and we subscribe to it, the only difference, is in this case we get the Event from the `@cds-models` folder\n\n`Service Definition (CDS):`\n\n```yml\n// We declare an event into our Service\nservice CatalogService {\n  event SendData : {\n    foo : Integer;\n    bar : String;\n  }\n}\n```\n\n`Emitting and subscribing:`\n\n```ts\nimport { OnSubscribe, Req, AfterRead, Results, OnEvent } from '@dxfrontier/cds-ts-dispatcher';\nimport type { SubscriberType } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { SendData } from '#cds-models/CatalogService'; // \u003c== location of @cds-models can differ.\n\n// Emitting the event\n@AfterRead()\nprivate async afterRead(\n  @Req() req: Request,\n  @Results() results: MyEntity[],\n): Promise\u003cvoid\u003e {\n  this.srv.emit('SendData', { foo: 11, bar: '22' });\n}\n\n// Receiving the event + data\n@OnSubscribe({ \n  eventName: SendData\n  type: 'SAME_NODE_PROCESS' \n})\nprivate async onSubscribe(@Req() req: Request\u003cSendData\u003e): Promise\u003cvoid\u003e {\n  // \n  // req.data.foo ...\n  // req.data.bar ...\n  // req.headers ...\n  // ...\n}\n\n// same as\n\n@OnEvent(SendData)\nprivate async onEventMethod(@Req() req: Request\u003cSendData\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.after('READ', MyEntity, async (req, res) =\u003e {\n  this.emit('SendData', { foo: 11, bar: '22' });\n});\n\nthis.on('SendData', async (msg) =\u003e {\n  // ...\n});\n```\n\n\u003e [!NOTE] \n\u003e The `SendData` was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n`Example 3` \n\n\nIn this example we assume we have `2 node instances` and `2 services` and we use external messaging `Cross-Instance Messaging (Message Broker)`\n\n`Emitter (Service 1 \u0026 node instance 1):`\n\n```ts\nimport { Req, AfterRead, Results } from '@dxfrontier/cds-ts-dispatcher';\nimport cds from '@sap/cds';\n\n@AfterRead()\nprivate async afterRead(\n  @Req() req: Request,\n  @Results() results: MyEntity[],\n): Promise\u003cvoid\u003e {\n\n  const messaging = await cds.connect.to('messaging');\n        messaging.emit('SendData', { foo: 11, bar: '22' });\n\n}\n```\n\n`Equivalent to 'JS'`\n\n```ts\nthis.after('READ', MyEntity, async (req, res) =\u003e {\n  const messaging = await cds.connect.to('messaging');\n        messaging.emit('SendData', { foo: 11, bar: '22' });\n});\n```\n\n`Subscriber (Service 2 \u0026 Node instance 2):`\n\n```ts\n\nimport { SendData } from '#cds-models/CatalogService'; // \u003c== location of @cds-models can differ.\nimport { Messaging, OnSubscribe } from '@dxfrontier/cds-ts-dispatcher';\nimport type { SubscriberType } from '@dxfrontier/cds-ts-dispatcher';\n\n// Receiving the event + data \n@OnSubscribe({\n  eventName: SendData,\n  type: 'MESSAGE_BROKER' \n})\nprivate async onSubscribe(@Msg() msg: SubscriberType\u003cSendData\u003e): Promise\u003cvoid\u003e {\n  // \n  // req.data.foo ...\n  // req.data.bar ...\n  // req.headers ...\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```ts\nconst messaging = await cds.connect.to('messaging');\n      messaging.on(SendData, async (msg) =\u003e {\n        // ...\n      });\n```\n\n\u003e [!IMPORTANT]\n\u003e To have the `msg` parameter typed you can use TypeScript type `SubscriberType\u003cT\u003e` where T can be a CDS event or any object\n\n\u003e [!TIP]\n\u003e When using `messaging (broker)` the decorator [@Msg](#msg) must be applied as the request is anonymous at this level.\n\n`Example 4`\n\nIn this example we emit an event in `Service 1` \u0026 `node process 1`, and we attach from `Service 2` a subscribe to `Service 1` \u0026 `node process 1`, meaning that, when emit `SendData` the service `Service 2` will be notified and the `onSubscribe` method will be triggered which resides attached to `Service 1`.\n\n`Emitter (Service 1 \u0026 node process 1):`\n\n```ts\nimport { Req, AfterRead, Results } from '@dxfrontier/cds-ts-dispatcher';\nimport type { SubscriberType } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { SendData } from '#cds-models/CatalogService'; // \u003c== location of @cds-models can differ.\n\n// Emitting the event\n// This event resides in Service_1\n@AfterRead()\nprivate async afterRead(\n  @Req() req: Request,\n  @Results() results: MyEntity[],\n): Promise\u003cvoid\u003e {\n  this.srv.emit('SendData', { foo: 11, bar: '22' });\n}\n```\n\n`Equivalent to 'JS'`\n\n```ts\n// This event resides in Service_1\nthis.after('READ', MyEntity, async (req, res) =\u003e {\n  this.emit('SendData', { foo: 11, bar: '22' });\n});\n```\n\n`Subscriber (Service 2 \u0026 node process 1):`\n\n```ts\n\nimport { OnSubscribe, Req } from '@dxfrontier/cds-ts-dispatcher';\n\n// Receiving the event + data\n// This event resides in Service_2 but the subscribe will be attached to Service_1\n @OnSubscribe({\n  eventName: 'SendData',\n  type: 'SAME_NODE_PROCESS_DIFFERENT_SERVICE',\n  externalService: 'Service_1'\n})\nprivate async onSubscribe(@Req() req: Request\u003cSendData\u003e): Promise\u003cvoid\u003e {\n  // req.data.foo ...\n  // req.data.bar ...\n  // req.headers ...\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```ts\n// This code resides in Service_2 but it is subscribed to Service_1\nconst Service_1 = cds.connect.to('Service_1');\n      Service_1.on('SendData', (msg) =\u003e {\n        //\n      });\n```\n\n\u003e [!TIP]\n\u003e You can find more info about SAP CAP messaging in the following url [SAP CAP Events and Messaging](https://cap.cloud.sap/docs/guides/messaging/).\n\n\u003e [!IMPORTANT]  \n\u003e Decorator `@OnSubscribe` should be used inside [@UnboundActions](#unboundactions) class, but not mandatory it can reside also in [@EntityHandler](#entityhandler) class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnError\n\n**@OnError**()\n\nUse `@OnError` decorator to register custom error handler.\n\nError handlers are invoked whenever an error occurs during event processing of all potential events and requests, and are used to augment or modify error messages, before they go out to clients.\n\n`Example`\n\n```typescript\nimport { OnError, Error, Req } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\n@OnError()\nprivate onError(@Error() err: Error, @Req() req: Request) { // sync func\n  err.message = 'New message'\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('error', (err, req) =\u003e {\n  err.message = 'New message';\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]  \n\u003e Decorator `@OnError` should be used inside [@UnboundActions](#unboundactions) class.\n\n\u003e [!CAUTION]\n\u003e OnError callback are expected to be a **`sync`** function, i.e., **`not async`**, not returning `Promises`.\n\n\u003e [!TIP]\n\u003e More info can be found at [SAP CAP Error](https://cap.cloud.sap/docs/node.js/core-services#srv-on-error)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnBoundAction\n\n**@OnBoundAction**(`name` : CdsAction)\n\n`Parameters`\n\n- `name (CdsAction)` : Representing the `CDS action` defined in the `CDS file`.\n\n`Example`\n\n```typescript\nimport { OnBoundAction, Req, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { ActionRequest, ActionReturn, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnBoundAction(MyEntity.actions.AnAction)\nprivate async onActionMethod(@Req() req: ActionRequest\u003ctypeof MyEntity.actions.AnAction\u003e, @Next() next: NextEvent): ActionReturn\u003ctypeof MyEntity.actions.AnAction\u003e {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on(MyEntity.actions.AnAction, MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnBoundAction()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnBoundFunction\n\n**@OnBoundFunction**(`name` : CdsFunction)\n\n`Parameters`\n\n- `name (CdsFunction)` : Representing the `CDS action` defined in the `CDS file`.\n\n`Example`\n\n```typescript\nimport { OnBoundFunction, Req, Next } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { ActionRequest, ActionReturn, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@OnBoundFunction(MyEntity.actions.AFunction)\nprivate async onFunctionMethod(@Req() req: ActionRequest\u003ctypeof MyEntity.actions.AFunction\u003e, @Next() next: NextEvent): ActionReturn\u003ctypeof MyEntity.actions.AFunction\u003e {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on(MyEntity.actions.AFunction, MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnBoundFunction()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @OnAll\n\n**@OnAll**()\n\nThe `@OnAll` decorator is triggered whenever **_any CRUD (Create, Read, Update, Delete)_** event occurs, whether the entity is `active` or in `draft` mode.\n\n`ACTIVE ENTITY`\n\nFor active entities, the `@OnAll` decorator will be triggered when at least __one__ of the following events occurs:\n\n- `CREATE` [@BeforeCreate()](#beforecreate), [@AfterCreate()](#aftercreate), [@OnCreate()](#oncreate)\n- `READ` [@BeforeRead()](#beforeread), [@AfterRead()](#afterread), [@OnRead()](#onread)\n- `UPDATE` [@BeforeUpdate()](#beforeupdate), [@AfterUpdate()](#afterupdate), [@OnUpdate()](#onupdate)\n- `DELETE` [@BeforeDelete()](#beforedelete), [@AfterDelete()](#afterdelete), [@OnDelete()](#ondelete)\n- `BOUND ACTIONS` [@OnBoundAction()](#onboundaction)\n- `BOUND FUNCTIONS` [@OnBoundFunction()](#onboundfunction)\n  \n`DRAFT`\n\nFor draft entities, the `@OnAll` decorator will be triggered when at least __one__ of the following events occurs:\n\n- `CREATE` [@BeforeNewDraft()](#beforenewdraft), [@AfterNewDraft()](#afternewdraft), [@OnNewDraft()](#onnewdraft)\n- `CANCEL` [@BeforeCancelDraft()](#beforecanceldraft), [@AfterCancelDraft()](#aftercanceldraft), [@OnCancelDraft()](#oncanceldraft)\n- `EDIT` [@BeforeEditDraft()](#beforeeditdraft), [@AfterEditDraft()](#aftereditdraft), [@OnEditDraft()](#oneditdraft)\n- `SAVE` [@BeforeSaveDraft()](#beforesavedraft), [@AfterSaveDraft()](#aftersavedraft), [@OnSaveDraft()](#onsavedraft)\n- :heavy_plus_sign: All active entity [Before](#before), [After](#after), [On](#on) events which have a `Draft` variant.\n\n\u003e [!NOTE]\n\u003e Exception will be the following decorators [@OnEvent()](#onevent), [@OnError()](#onerror) and `UNBOUND ACTIONS` [@OnAction()](#onaction), `UNBOUND FUNCTIONS` [@OnFunction()](#onfunction) as these are bound to the service itself and not to an entity.\n\n`Example 1`\n\nIn this example, the `@OnAll()` decorator of the `onAll` method is executed after any CRUD operation `(CREATE, READ, UPDATE, DELETE, BOUND ACTIONS, BOUND FUNCTIONS)` on the `MyEntity` entity. \n\nSince the class is annotated with `@EntityHandler(MyEntity)`, the decorator is scoped to this specific `entity`, meaning it will only be triggered for operations related to `MyEntity`.\n\n```typescript\nimport { OnAll, Next, EntityHandler } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(MyEntity)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n\n  @OnAll()\n  private async onAll(@Req() req: Request, @Next() next: NextEvent) {\n    // ...\n    return next();\n  }\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('*', MyEntity, async (req, next) =\u003e {\n  // ...\n});\n```\n`Example 2`\n\nIn this example, the `@OnAll()` decorator is used in a more generic way. Unlike `Example 1`, where it applies only to `MyEntity`, this setup ensures that `afterAll` is triggered for `all entities`. \n\nThis means the method will execute before any CRUD operation on `any` `entity` handled within the class.\n\n\n```typescript\nimport { OnAll, Next, EntityHandler, CDS_DISPATCHER } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request, NextEvent } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@EntityHandler(CDS_DISPATCHER.ALL_ENTITIES)\nexport class BookHandler {\n  // ...\n  constructor() {}\n  // All events like @AfterRead, @BeforeRead, ... will be triggered based on 'MyEntity'\n\n  @OnAll()\n  private async onAll(@Req() req: Request, @Next() next: NextEvent) {\n    // ...\n    return next();\n  }\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.on('*', '*', async (req, next) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@OnAll()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!TIP]\n\u003e If the entity has drafts enabled `@odata.draft.enabled: true`, the `@OnAll` decorator will still be triggered for draft events.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n#### `Method`-`draft entity`\n\n##### `Before`\n\nUse `@BeforeNewDraft(), @BeforeCancelDraft(), @BeforeEditDraft(), @BeforeSaveDraft(), @BeforeCreateDraft(), @BeforeReadDraft(), @BeforeUpdateDraft(), @BeforeDeleteDraft()` to register handlers to run before`.on`handlers, frequently used for `validating user input.`\n\nThe handlers receive one argument:\n\n- `req` of type `Request`\n\n###### @BeforeNewDraft\n\n**@BeforeNewDraft**()\n\nUse this decorator when you want to validate inputs before a new draft is created.\n\n`Example`\n\n```typescript\nimport { BeforeNewDraft, Request } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeNewDraft()\nprivate async beforeCreateDraftMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('NEW', MyEntity.drafts, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeNewDraft()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeCancelDraft\n\n**@BeforeCancelDraft**()\n\nUse this decorator when you want to validate inputs before a draft is discarded.\n\n`Example`\n\n```typescript\nimport { BeforeCancelDraft } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeCancelDraft()\nprivate async beforeCancelDraftMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('CANCEL', MyEntity.drafts, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeCancelDraft()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeEditDraft\n\n**@BeforeEditDraft**()\n\nUse this decorator when you want to validate inputs when a new draft is created from an active instance.\n\n`Example`\n\n```typescript\nimport { BeforeEditDraft } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeEditDraft()\nprivate async beforeEditDraftMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent to 'JS'`\n\n```typescript\nthis.before('EDIT', MyEntity, async (req) =\u003e {\n  // ...\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Decorator `@BeforeEditDraft()` will be triggered based on the [EntityHandler](#entityhandler) `argument` =\u003e `MyEntity`.\n\n\u003e [!NOTE]\n\u003e MyEntity was generated using [CDS-Typer](#generate-cds-typed-entities) and imported in the the class.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#table-of-contents\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n###### @BeforeSaveDraft\n\n**@BeforeSaveDraft**()\n\nUse this decorator when you want to validate inputs when active entity is changed.\n\n`Example`\n\n```typescript\nimport { BeforeSaveDraft } from \"@dxfrontier/cds-ts-dispatcher\";\nimport type { Request } from '@dxfrontier/cds-ts-dispatcher';\n\nimport { MyEntity } from 'YOUR_CDS_TYPER_ENTITIES_LOCATION';\n\n@BeforeSaveDraft()\nprivate async beforeSaveDraftMethod(@Req() req: Request\u003cMyEntity\u003e) {\n  // ...\n}\n```\n\n`Equivalent ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdxfrontier%2Fcds-ts-dispatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdxfrontier%2Fcds-ts-dispatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdxfrontier%2Fcds-ts-dispatcher/lists"}