@open-rap/compiler 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -2
- package/dist/agent/server.d.ts +35 -0
- package/dist/agent/server.js +408 -0
- package/dist/agent/server.js.map +1 -0
- package/dist/authoring/abapgit.d.ts +38 -0
- package/dist/authoring/abapgit.js +242 -0
- package/dist/authoring/abapgit.js.map +1 -0
- package/dist/authoring/catalog.d.ts +48 -0
- package/dist/authoring/catalog.js +117 -0
- package/dist/authoring/catalog.js.map +1 -0
- package/dist/authoring/floorplan.d.ts +28 -0
- package/dist/authoring/floorplan.js +31 -0
- package/dist/authoring/floorplan.js.map +1 -0
- package/dist/authoring/generate.d.ts +57 -0
- package/dist/authoring/generate.js +630 -0
- package/dist/authoring/generate.js.map +1 -0
- package/dist/authoring/mcp.d.ts +15 -0
- package/dist/authoring/mcp.js +52 -0
- package/dist/authoring/mcp.js.map +1 -0
- package/dist/authoring/new.d.ts +35 -0
- package/dist/authoring/new.js +389 -0
- package/dist/authoring/new.js.map +1 -0
- package/dist/bdef/ast.d.ts +249 -0
- package/dist/bdef/ast.js +3 -0
- package/dist/bdef/ast.js.map +1 -0
- package/dist/bdef/lexer.d.ts +105 -0
- package/dist/bdef/lexer.js +148 -0
- package/dist/bdef/lexer.js.map +1 -0
- package/dist/bdef/parser.d.ts +22 -0
- package/dist/bdef/parser.js +1012 -0
- package/dist/bdef/parser.js.map +1 -0
- package/dist/build.d.ts +26 -0
- package/dist/build.js +62 -0
- package/dist/build.js.map +1 -0
- package/dist/cds/adapter.d.ts +91 -0
- package/dist/cds/adapter.js +381 -0
- package/dist/cds/adapter.js.map +1 -0
- package/dist/cds/expression-ast.d.ts +65 -0
- package/dist/cds/expression-ast.js +330 -0
- package/dist/cds/expression-ast.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +485 -0
- package/dist/cli.js.map +1 -0
- package/dist/dcl/parser.d.ts +59 -0
- package/dist/dcl/parser.js +338 -0
- package/dist/dcl/parser.js.map +1 -0
- package/dist/ddic/catalog.d.ts +17 -0
- package/dist/ddic/catalog.js +211 -0
- package/dist/ddic/catalog.js.map +1 -0
- package/dist/ddic/cds-types.d.ts +47 -0
- package/dist/ddic/cds-types.js +131 -0
- package/dist/ddic/cds-types.js.map +1 -0
- package/dist/ddic/table-source.d.ts +70 -0
- package/dist/ddic/table-source.js +500 -0
- package/dist/ddic/table-source.js.map +1 -0
- package/dist/ddic/xml.d.ts +65 -0
- package/dist/ddic/xml.js +201 -0
- package/dist/ddic/xml.js.map +1 -0
- package/dist/dev.d.ts +128 -0
- package/dist/dev.js +434 -0
- package/dist/dev.js.map +1 -0
- package/dist/diagnostics.d.ts +33 -0
- package/dist/diagnostics.js +53 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/gen/abap/derived-types.d.ts +26 -0
- package/dist/gen/abap/derived-types.js +323 -0
- package/dist/gen/abap/derived-types.js.map +1 -0
- package/dist/gen/abap/eml.d.ts +118 -0
- package/dist/gen/abap/eml.js +362 -0
- package/dist/gen/abap/eml.js.map +1 -0
- package/dist/gen/abap/enums.d.ts +13 -0
- package/dist/gen/abap/enums.js +74 -0
- package/dist/gen/abap/enums.js.map +1 -0
- package/dist/gen/abap/framework-http.d.ts +14 -0
- package/dist/gen/abap/framework-http.js +1049 -0
- package/dist/gen/abap/framework-http.js.map +1 -0
- package/dist/gen/abap/framework-query.d.ts +14 -0
- package/dist/gen/abap/framework-query.js +225 -0
- package/dist/gen/abap/framework-query.js.map +1 -0
- package/dist/gen/abap/framework-utils.d.ts +29 -0
- package/dist/gen/abap/framework-utils.js +3707 -0
- package/dist/gen/abap/framework-utils.js.map +1 -0
- package/dist/gen/abap/framework.d.ts +12 -0
- package/dist/gen/abap/framework.js +480 -0
- package/dist/gen/abap/framework.js.map +1 -0
- package/dist/gen/abap/generate.d.ts +40 -0
- package/dist/gen/abap/generate.js +238 -0
- package/dist/gen/abap/generate.js.map +1 -0
- package/dist/gen/abap/rewrite.d.ts +82 -0
- package/dist/gen/abap/rewrite.js +957 -0
- package/dist/gen/abap/rewrite.js.map +1 -0
- package/dist/gen/abap/shadow.d.ts +25 -0
- package/dist/gen/abap/shadow.js +175 -0
- package/dist/gen/abap/shadow.js.map +1 -0
- package/dist/gen/abap/tokens.d.ts +33 -0
- package/dist/gen/abap/tokens.js +87 -0
- package/dist/gen/abap/tokens.js.map +1 -0
- package/dist/gen/app/index.d.ts +25 -0
- package/dist/gen/app/index.js +322 -0
- package/dist/gen/app/index.js.map +1 -0
- package/dist/gen/csdl.d.ts +11 -0
- package/dist/gen/csdl.js +562 -0
- package/dist/gen/csdl.js.map +1 -0
- package/dist/gen/deploy.d.ts +12 -0
- package/dist/gen/deploy.js +53 -0
- package/dist/gen/deploy.js.map +1 -0
- package/dist/gen/docs/index.d.ts +35 -0
- package/dist/gen/docs/index.js +267 -0
- package/dist/gen/docs/index.js.map +1 -0
- package/dist/gen/docs/markdown.d.ts +23 -0
- package/dist/gen/docs/markdown.js +187 -0
- package/dist/gen/docs/markdown.js.map +1 -0
- package/dist/gen/docs/site.d.ts +17 -0
- package/dist/gen/docs/site.js +106 -0
- package/dist/gen/docs/site.js.map +1 -0
- package/dist/gen/keycloak.d.ts +21 -0
- package/dist/gen/keycloak.js +90 -0
- package/dist/gen/keycloak.js.map +1 -0
- package/dist/gen/launchpad/index.d.ts +48 -0
- package/dist/gen/launchpad/index.js +302 -0
- package/dist/gen/launchpad/index.js.map +1 -0
- package/dist/gen/launchpad/ui.d.ts +14 -0
- package/dist/gen/launchpad/ui.js +350 -0
- package/dist/gen/launchpad/ui.js.map +1 -0
- package/dist/gen/mcp.d.ts +23 -0
- package/dist/gen/mcp.js +244 -0
- package/dist/gen/mcp.js.map +1 -0
- package/dist/gen/sql-expressions.d.ts +12 -0
- package/dist/gen/sql-expressions.js +136 -0
- package/dist/gen/sql-expressions.js.map +1 -0
- package/dist/gen/sql.d.ts +38 -0
- package/dist/gen/sql.js +612 -0
- package/dist/gen/sql.js.map +1 -0
- package/dist/gen/ui/index.d.ts +7 -0
- package/dist/gen/ui/index.js +27 -0
- package/dist/gen/ui/index.js.map +1 -0
- package/dist/gen/ui/layout.d.ts +230 -0
- package/dist/gen/ui/layout.js +511 -0
- package/dist/gen/ui/layout.js.map +1 -0
- package/dist/gen/ui/static.d.ts +55 -0
- package/dist/gen/ui/static.js +2901 -0
- package/dist/gen/ui/static.js.map +1 -0
- package/dist/gen/ui/views.d.ts +10 -0
- package/dist/gen/ui/views.js +511 -0
- package/dist/gen/ui/views.js.map +1 -0
- package/dist/gen/vendor.d.ts +23 -0
- package/dist/gen/vendor.js +68 -0
- package/dist/gen/vendor.js.map +1 -0
- package/dist/gen/xml.d.ts +9 -0
- package/dist/gen/xml.js +42 -0
- package/dist/gen/xml.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/input/project.d.ts +50 -0
- package/dist/input/project.js +128 -0
- package/dist/input/project.js.map +1 -0
- package/dist/ir/access-controls.d.ts +11 -0
- package/dist/ir/access-controls.js +148 -0
- package/dist/ir/access-controls.js.map +1 -0
- package/dist/ir/authorizations.d.ts +25 -0
- package/dist/ir/authorizations.js +178 -0
- package/dist/ir/authorizations.js.map +1 -0
- package/dist/ir/behaviors.d.ts +16 -0
- package/dist/ir/behaviors.js +548 -0
- package/dist/ir/behaviors.js.map +1 -0
- package/dist/ir/builder.d.ts +20 -0
- package/dist/ir/builder.js +505 -0
- package/dist/ir/builder.js.map +1 -0
- package/dist/ir/config.d.ts +25 -0
- package/dist/ir/config.js +130 -0
- package/dist/ir/config.js.map +1 -0
- package/dist/ir/dictionary.d.ts +54 -0
- package/dist/ir/dictionary.js +328 -0
- package/dist/ir/dictionary.js.map +1 -0
- package/dist/ir/entities.d.ts +58 -0
- package/dist/ir/entities.js +676 -0
- package/dist/ir/entities.js.map +1 -0
- package/dist/ir/expressions.d.ts +33 -0
- package/dist/ir/expressions.js +327 -0
- package/dist/ir/expressions.js.map +1 -0
- package/dist/ir/handlers.d.ts +63 -0
- package/dist/ir/handlers.js +398 -0
- package/dist/ir/handlers.js.map +1 -0
- package/dist/ir/number-ranges.d.ts +24 -0
- package/dist/ir/number-ranges.js +74 -0
- package/dist/ir/number-ranges.js.map +1 -0
- package/dist/ir/seed.d.ts +23 -0
- package/dist/ir/seed.js +78 -0
- package/dist/ir/seed.js.map +1 -0
- package/dist/ir/service.d.ts +21 -0
- package/dist/ir/service.js +96 -0
- package/dist/ir/service.js.map +1 -0
- package/dist/launchpad/config.d.ts +47 -0
- package/dist/launchpad/config.js +321 -0
- package/dist/launchpad/config.js.map +1 -0
- package/dist/launchpad/workspace.d.ts +48 -0
- package/dist/launchpad/workspace.js +166 -0
- package/dist/launchpad/workspace.js.map +1 -0
- package/dist/srvd/parser.d.ts +36 -0
- package/dist/srvd/parser.js +193 -0
- package/dist/srvd/parser.js.map +1 -0
- package/dist/standard/data.d.ts +18 -0
- package/dist/standard/data.js +534 -0
- package/dist/standard/data.js.map +1 -0
- package/dist/standard/index.d.ts +36 -0
- package/dist/standard/index.js +507 -0
- package/dist/standard/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/docs/AGENTS.md +79 -0
- package/docs/ANNOTATIONS.md +76 -0
- package/docs/DECISIONS.md +1526 -0
- package/docs/DEPLOYMENT.md +113 -0
- package/docs/DIAGNOSTICS.md +116 -0
- package/docs/FEATURES.md +287 -0
- package/docs/GUIDE.md +560 -0
- package/docs/KNOWN_GAPS.md +216 -0
- package/docs/MCP.md +84 -0
- package/docs/PLAN.md +690 -0
- package/docs/README.md +148 -0
- package/docs/REMOTE_APIS.md +121 -0
- package/docs/ROADMAP.md +35 -0
- package/docs/UTILITIES.md +95 -0
- package/package.json +49 -3
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Deploying an application or a launchpad
|
|
2
|
+
|
|
3
|
+
An application generated by `rapt build` (or a launchpad by `rapt launchpad`) is a standalone
|
|
4
|
+
folder: Node.js 22, a `package.json`, a `Dockerfile`, a Cloud Foundry `manifest.yml`. It deploys
|
|
5
|
+
anywhere Node.js or a container runs ([D50](DECISIONS.md)).
|
|
6
|
+
|
|
7
|
+
## Two modes: the complete launchpad, or one application alone
|
|
8
|
+
|
|
9
|
+
The workspace has a launchpad (`launchpad.json`, titled "Launchpad") to which each application
|
|
10
|
+
is added when it is created ([D69](DECISIONS.md)). When shipping:
|
|
11
|
+
|
|
12
|
+
| Mode | Command | Result |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **Launchpad (all the applications)** | `rapt launchpad launchpad.json --out out/launchpad` | the launchpad and, in `apps/<id>`, each application built from its sources; `docker compose up` starts everything (one PostgreSQL per application) behind a single origin and a single sign-in |
|
|
15
|
+
| **Application alone (standalone)** | `rapt build my-project --out out/travel` | the application without a launchpad: it does not depend on one (the shell bar only shows behind a launchpad) |
|
|
16
|
+
|
|
17
|
+
In VS Code, *RAP: Build the application…* asks for the mode; *RAP: Build the launchpad…* builds
|
|
18
|
+
the launchpad of the workspace directly.
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
rapt launchpad launchpad.json --out out/launchpad
|
|
22
|
+
cd out/launchpad
|
|
23
|
+
docker compose up --build # http://localhost:8090/: the launchpad, the applications under /apps/<id>/
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## What to set outside `localhost`
|
|
27
|
+
|
|
28
|
+
| Variable | Why |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `PUBLIC_URL` | The address the users see (`https://travel.example.com/`): OIDC redirects. Derived from the route on Cloud Foundry. |
|
|
31
|
+
| `AUTH_MODE=oidc`, `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` | An identity provider: SAP Cloud Identity Services (IAS), Keycloak, Microsoft Entra ID, Auth0… Never expose `AUTH_MODE=none` on a network. |
|
|
32
|
+
| `SESSION_SECRET` | A long random value, the same for the launchpad and its applications. |
|
|
33
|
+
| `DATABASE_URL` (and `DATABASE_CA`) | A PostgreSQL (14 or later) and, if needed, the certificate of its server. Derived from a bound PostgreSQL service on Cloud Foundry. |
|
|
34
|
+
| `OIDC_REQUIRED_ROLE` | Optional: the role without which the application refuses access. |
|
|
35
|
+
|
|
36
|
+
All the variables are in the generated `.env.example`. Secrets never go into `manifest.yml` nor
|
|
37
|
+
into the repository.
|
|
38
|
+
|
|
39
|
+
## Docker (VM, Kubernetes, Azure Container Apps, Google Cloud Run…)
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
rapt build my-project --out out/travel
|
|
43
|
+
cd out/travel
|
|
44
|
+
docker build -t travel .
|
|
45
|
+
docker run -p 8080:8080 --env-file .env travel
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The generated `docker-compose.yml` starts the application with PostgreSQL (and Keycloak with
|
|
49
|
+
`--profile oidc`): useful for a test server.
|
|
50
|
+
|
|
51
|
+
## SAP BTP, Cloud Foundry environment
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
rapt build my-project --out out/travel && cd out/travel
|
|
55
|
+
cf create-service postgresql-db <plan> travel-db # the name manifest.yml expects
|
|
56
|
+
# manifest.yml: fill in OIDC_ISSUER and OIDC_CLIENT_ID (IAS application with OpenID Connect)
|
|
57
|
+
cf push --no-start
|
|
58
|
+
cf set-env travel SESSION_SECRET "$(openssl rand -hex 32)"
|
|
59
|
+
cf set-env travel OIDC_CLIENT_SECRET <secret>
|
|
60
|
+
cf start travel
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The runtime reads `VCAP_APPLICATION` (route → `PUBLIC_URL`) and `VCAP_SERVICES` (bound
|
|
64
|
+
PostgreSQL → `DATABASE_URL`, `DATABASE_CA`). The Node.js buildpack installs the dependencies
|
|
65
|
+
(`vendor/` contains the runtime of Open RAP Runtime). Health check: `/health`.
|
|
66
|
+
|
|
67
|
+
For a launchpad: push each application (folders `apps/<id>` of `rapt launchpad`, or `rapt build`
|
|
68
|
+
of each one), then give their routes to the launchpad
|
|
69
|
+
(`cf set-env launchpad APP_TRAVEL_URL https://travel.cfapps…`); the launchpad and its
|
|
70
|
+
applications share `SESSION_SECRET` and the same OIDC client.
|
|
71
|
+
|
|
72
|
+
## A machine of the network
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
npm install && npm start # listens on 0.0.0.0:8080 (HOST, PORT)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
During development, `rapt dev --host 0.0.0.0` also opens the development server to the network
|
|
79
|
+
(colleagues, phone), still without sign-in: keep it to a trusted network.
|
|
80
|
+
|
|
81
|
+
## HTTPS
|
|
82
|
+
|
|
83
|
+
The application speaks HTTP; TLS terminates in front of it (Cloud Foundry router, Kubernetes
|
|
84
|
+
ingress, nginx or Caddy reverse proxy, managed service of the cloud). `PUBLIC_URL` gives the
|
|
85
|
+
HTTPS address.
|
|
86
|
+
|
|
87
|
+
## Publishing a version of Open RAP Runtime (maintainers)
|
|
88
|
+
|
|
89
|
+
A tag `v1.2.3` runs `release.yml`: the VS Code extension (GitHub release, Marketplace with the
|
|
90
|
+
`VSCE_PAT` secret, Open VSX with `OVSX_PAT`) and the CLI on npm ([D65](DECISIONS.md)):
|
|
91
|
+
`open-rap-runtime` (the `rapt` command), `@open-rap/model`, `@open-rap/compiler` and
|
|
92
|
+
`@open-rap/runtime`, all in version 1.2.3.
|
|
93
|
+
|
|
94
|
+
Once, for npm:
|
|
95
|
+
|
|
96
|
+
1. Create the organization **`open-rap`** on npmjs.com (free for public packages): it
|
|
97
|
+
holds the `@open-rap` scope.
|
|
98
|
+
2. Create a *Granular Access Token* (*Read and write*, packages `open-rap-runtime` and scope
|
|
99
|
+
`@open-rap`, or the whole organization) and save it as the **`NPM_TOKEN`** secret of the
|
|
100
|
+
repository (*Settings → Secrets and variables → Actions*).
|
|
101
|
+
|
|
102
|
+
Without `NPM_TOKEN`, the `npm` job builds and checks the packages (archives of `pnpm pack`
|
|
103
|
+
installed by npm, `rapt check` and `rapt build` of the fixture) but publishes nothing. npm
|
|
104
|
+
provenance (the link between the package and the workflow) is added when the repository is
|
|
105
|
+
public.
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
git tag v0.1.0 && git push origin v0.1.0
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or without a tag: *Actions → Release → Run workflow* with the version (`0.1.0`); the release then
|
|
112
|
+
creates the tag `v0.1.0` on the commit of the run.
|
|
113
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Diagnostic codes
|
|
2
|
+
|
|
3
|
+
`rapt check` prints the diagnostics in the format `file:line:column: severity CODE message`. The
|
|
4
|
+
exit code is 1 as soon as there is an error (or a warning with `--warnings-as-errors`).
|
|
5
|
+
|
|
6
|
+
| Code | Severity | Meaning |
|
|
7
|
+
|---|---|---|
|
|
8
|
+
| PRJ001 | error | No service definition, or several without `--service` |
|
|
9
|
+
| PRJ002 | error | The requested service definition does not exist |
|
|
10
|
+
| SRVD001 | error | Syntax error in a service definition |
|
|
11
|
+
| SRVD002 | warning | Several bindings for the service |
|
|
12
|
+
| SRVD003 | warning | Binding that is not OData V4 |
|
|
13
|
+
| SRVD004 | error | Entity set exposed twice |
|
|
14
|
+
| SRVD005 | error | Exposed entity not found |
|
|
15
|
+
| SRVD006 | info | Association to an entity that is not exposed: navigation omitted |
|
|
16
|
+
| SRVD007 | info | Several service definitions: the one with a binding is built (the others, of a service consumption model for example, are not) |
|
|
17
|
+
| SRVD008 | error | `--binding-type` other than `ui` or `webapi` (D60) |
|
|
18
|
+
| CDS001 | error | Unreadable CDS source |
|
|
19
|
+
| CDS002 | error or warning | Unsupported CDS construct; in a calculated element, the message names the construct (association path, session variable other than `$session.system_date`, `BETWEEN`, aggregate, unsupported SQL function) (D67) |
|
|
20
|
+
| CDS003 | error | Unknown data source or projected entity |
|
|
21
|
+
| CDS004 | error | Unknown element in the source |
|
|
22
|
+
| CDS005 | error | Unknown association or redirection target |
|
|
23
|
+
| CDS006 | warning | Metadata extension for an unknown entity |
|
|
24
|
+
| CDS007 | warning | Metadata extension ignored (`@Metadata.allowExtensions` missing) |
|
|
25
|
+
| CDS008 | warning | Metadata extension on an unknown element |
|
|
26
|
+
| CDS009 | warning | Client field not exposed |
|
|
27
|
+
| CDS010 | error | Unsupported ON condition |
|
|
28
|
+
| CDS011 | error | Entity without a key |
|
|
29
|
+
| CDS012 | warning | Composition or association to parent not redirected in the projection |
|
|
30
|
+
| CDS013 | error | The projection does not expose the fields an association needs |
|
|
31
|
+
| CDS014 | error | Unknown type in an abstract entity |
|
|
32
|
+
| CDS015 | error | Composition without an association to parent in the child |
|
|
33
|
+
| CDS016 | error | Custom entity without `@ObjectModel.query.implementedBy: 'ABAP:<class>'` |
|
|
34
|
+
| CDS017 | error | Query class of a custom entity missing from the sources |
|
|
35
|
+
| CDS018 | warning | Value help (`@Consumption.valueHelpDefinition`) on an unknown entity: value help omitted |
|
|
36
|
+
| CDS019 | error | Table entity name longer than 25 characters (D55) |
|
|
37
|
+
| CDS020 | error | Table entity element: `null` key, key after a non-key element, `abap.string` or `abap.rawstring` without `null` (D55) |
|
|
38
|
+
| CDS021 | error | Element of a CDS enumerated type in an exposed entity: SAP does not expose enumerated types in RAP OData services. In `enhanced` mode, OData enumeration type (D55) |
|
|
39
|
+
| CDS022 | error | Invalid calculated element: type that cannot be derived (`NULL` alone, calculation on a string: add a `CAST`), unknown type in a `CAST`, number of arguments of a function, circular or unknown `$projection` reference, calculated element that is a key or has no alias (D67) |
|
|
40
|
+
| TYPE001 | error | Unreadable CDS type source (`.drty.acds`), or name different from the one of the file (D55) |
|
|
41
|
+
| TYPE002 | error | CDS type based on an unknown type (D55) |
|
|
42
|
+
| TYPE003 | error | Wrong CDS enumerated type: base type (`abap.int1`, `int2`, `int4`, `char(1..8)`, `numc(1..8)`), not exactly one `initial` constant, value outside the base type, duplicate constants or values (D55) |
|
|
43
|
+
| DDIC001 | error | Unknown data element |
|
|
44
|
+
| DDIC002 | error | Unsupported data type |
|
|
45
|
+
| DDIC003 | error | Unsupported included structure |
|
|
46
|
+
| DDIC004 | warning | Table class other than transparent |
|
|
47
|
+
| DDIC005 | info | Table of the project left out of the database (it cannot be built and no entity uses it) |
|
|
48
|
+
| DDIC010 | error | Unreadable table definition |
|
|
49
|
+
| TABL001 | error | Error in the source of a table (`.tabl.astabl`): syntax, unknown type, name different from the one of the file, table without a key |
|
|
50
|
+
| TABL002 | warning | Construct of the source of a table not carried over to the abapGit XML (foreign key) |
|
|
51
|
+
| BDEF001 | error | BDEF syntax error |
|
|
52
|
+
| BDEF002 | error | Out-of-scope feature (unmanaged, late numbering…) |
|
|
53
|
+
| BDEF003 | warning | Construct ignored |
|
|
54
|
+
| BDEF004 | error | Unknown CDS entity |
|
|
55
|
+
| BDEF005 | error | Unknown element |
|
|
56
|
+
| BDEF006 | error | Unknown association |
|
|
57
|
+
| BDEF007 | error | Unknown persistent table |
|
|
58
|
+
| BDEF008 | error | Mapping inconsistent with the CDS view or the table |
|
|
59
|
+
| BDEF009 | error | Element without a matching column |
|
|
60
|
+
| BDEF010 | error | Implementation type missing |
|
|
61
|
+
| BDEF011 | error | Behavior pool required |
|
|
62
|
+
| BDEF012 | error | Statement forbidden in this type of BDEF |
|
|
63
|
+
| BDEF013 | error | Managed BDEF on something other than a view entity |
|
|
64
|
+
| BDEF014 | error | Persistent table missing |
|
|
65
|
+
| BDEF015 | error | Lock definition missing or invalid |
|
|
66
|
+
| BDEF016 | warning | Strict mode without an authorization definition |
|
|
67
|
+
| BDEF017 | error | `numbering : managed` on a field that is not a UUID key |
|
|
68
|
+
| BDEF018 | warning | `create` on a child entity |
|
|
69
|
+
| BDEF019 | error | Create by association on something other than a composition |
|
|
70
|
+
| BDEF020 | warning | Determination without a trigger |
|
|
71
|
+
| BDEF021 | error | Unknown parameter or result entity |
|
|
72
|
+
| BDEF022 | error | Factory action with a result, or function without a result |
|
|
73
|
+
| BDEF023 | error | The projection reuses a feature missing from the base |
|
|
74
|
+
| BDEF024 | error | Composition child without behavior |
|
|
75
|
+
| BDEF025 | error | Child entity without an association to parent |
|
|
76
|
+
| BDEF026 | error | Projection BDEF on something other than a projection of a managed BO |
|
|
77
|
+
| BDEF027 | error or info | Managed BO with unmanaged save on a custom entity: an extension of Open RAP Runtime, not activatable on SAP (D43). Error in `standard` mode, info in `enhanced` mode (D45) |
|
|
78
|
+
| BDEF028 | error | Draft BO (`with draft`) with an entity without a `draft table` (D54) |
|
|
79
|
+
| BDEF029 | error | `with collaborative draft` without `draft action Share` (D59) |
|
|
80
|
+
| ABP001 | error | Behavior pool not found |
|
|
81
|
+
| ABP002 | error | Missing handler method, or missing saver class (with `save_modified`) for additional or unmanaged save |
|
|
82
|
+
| ABP003 | warning | Handler or saver method without a matching BDEF element (including an undeclared precheck, a saver without additional or unmanaged save): it is not called |
|
|
83
|
+
| ABP004 | error | ABAP error (abaplint): syntax of the original sources, complete check of the rewritten sources, at the original line |
|
|
84
|
+
| ABP005 | error | Malformed EML statement or unsupported form (`OPERATIONS`, `RELATING TO`…) |
|
|
85
|
+
| ABP006 | error | Unknown name in the EML or a derived type: BDEF, entity, field, association, action |
|
|
86
|
+
| ABP007 | error | Unsupported construct: ABAP SQL write outside the saver class, `DELETE dbtab FROM @wa`, `WITH`, `SELECT … ENDSELECT` with a field list, `adjust_numbers`, EML on a projection, `GET PERMISSIONS`, out-of-scope derived type or handler |
|
|
87
|
+
| ABP008 | error | Internal error (generated ABAP) or error of the transpiler |
|
|
88
|
+
| ABP009 | error | Result of a `SELECT` abaplint does not type (literal, aggregate other than `COUNT(*)`, `MAX` and `MIN`, expression) in an inline declaration: declare the target |
|
|
89
|
+
| ABP010 | error | `AUTHORITY-CHECK` on a field the authorization object does not have |
|
|
90
|
+
| ABP011 | warning | `AUTHORITY-CHECK` on an authorization object neither in the sources (SUSO) nor in `rapt/authorizations.json`: no role grants it |
|
|
91
|
+
| DCL001 | error | Unreadable access control (DCL), or circular inheritance |
|
|
92
|
+
| DCL002 | warning | Condition of an access control the application does not evaluate: it grants no row |
|
|
93
|
+
| DCL003 | warning | Unknown element, association or entity in an access control, or not exposed by the projection: the condition grants no row |
|
|
94
|
+
| DCL004 | error or warning | `aspect pfcg_auth` on a field the authorization object does not have (error), or on an unknown object (warning) |
|
|
95
|
+
| AUTH001 | error | Unreadable or malformed authorization object or `rapt/authorizations.json` |
|
|
96
|
+
| AUTH002 | warning | Role granting an unknown authorization object (its fields are not checked) |
|
|
97
|
+
| AUTH003 | error | Role giving a value to a field the authorization object does not have |
|
|
98
|
+
| AUTH004 | warning | Role granting an activity (`ACTVT`) the authorization object does not allow |
|
|
99
|
+
| LPD001 | error | Unreadable or malformed `launchpad.json`: groups, titles, id or URL of an application, roles of a tile |
|
|
100
|
+
| LPD002 | error | Tile without a target, with two targets (`app` and `url`), or of an unknown application |
|
|
101
|
+
| LPD003 | error or warning | Application folder not generated by `rapt build` (error); application whose services are not known, neither `build` nor `servicePaths` nor a built `source` (warning) |
|
|
102
|
+
| LPD004 | error | Intent not of the form `SemanticObject-action` |
|
|
103
|
+
| LPD005 | error | Service path under a path of the launchpad (`/ui`, `/apps`, `/auth`…), or served by two applications |
|
|
104
|
+
| LPD006 | error | Counter on an entity set unknown to the service, or on a tile without an application |
|
|
105
|
+
| LPD007 | warning | Role of a tile missing from the `rapt/authorizations.json` of the applications (the IdP must still give it) |
|
|
106
|
+
| LPD008 | error | Malformed space or page in `launchpad.json` (title, pages, sections, roles) (D48) |
|
|
107
|
+
| LPD009 | error | Malformed `source` application (not a path, or with `build`), folder not found, or application that does not build with the launchpad (D69) |
|
|
108
|
+
| SEED001 | error | Unreadable or malformed `rapt/seed.json` (object table → array of rows expected) |
|
|
109
|
+
| SEED002 | error | `rapt/seed.json`: table or field unknown to the application |
|
|
110
|
+
| NR001 | error | Unreadable or malformed `rapt/number-ranges.json`: object longer than 10 characters, interval longer than 2 characters, non-numeric or inverted bounds |
|
|
111
|
+
| CFG001 | error | Unreadable `rapt/config.json`, or unknown mode (`standard` or `enhanced`), in the file or `--mode` (D45) |
|
|
112
|
+
| CFG002 | warning | Unknown setting in `rapt/config.json`, ignored |
|
|
113
|
+
| CFG003 | error | Malformed `ui` of `rapt/config.json`: unknown floorplan, incomplete Overview Page card, entity set missing from the service (D53) |
|
|
114
|
+
| MCP001 | error | Unreadable or malformed `rapt/mcp.json` (D47) |
|
|
115
|
+
| MCP002 | warning | `rapt/mcp.json` describes a tool the service no longer has: run `rapt mcp` again |
|
|
116
|
+
| APP001 | error | Runtime packages not found (`dist/` not built) for the generated application: `--runtime <folder>` or `pnpm build` |
|
package/docs/FEATURES.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Feature coverage: managed RAP BO
|
|
2
|
+
|
|
3
|
+
Target (decision D14): all the features of a managed RAP BO; draft came afterwards (D54).
|
|
4
|
+
This table is updated at each milestone.
|
|
5
|
+
|
|
6
|
+
Legend: ✅ supported and tested · 🟡 partial or not covered by a test (see the note) ·
|
|
7
|
+
⏳ planned (milestone given) · ❌ out of scope (reason given).
|
|
8
|
+
|
|
9
|
+
Since M1, all the constructs of these tables are parsed and represented in the IR, with a
|
|
10
|
+
positioned diagnostic for those that are out of scope; the status gives the behavior of the
|
|
11
|
+
generated application. The tests of M4 use the Travel/Booking fixture and its variants
|
|
12
|
+
(`packages/runtime/test/variants.ts`, `rap-variant*.test.ts` tests) which add what the fixture
|
|
13
|
+
does not use: numbering, global feature control, saver (additional, unmanaged), ABAP SQL,
|
|
14
|
+
dependent ETag, remote APIs.
|
|
15
|
+
|
|
16
|
+
## BDEF: header and entities
|
|
17
|
+
|
|
18
|
+
| Feature | Status | Note |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `managed implementation in class … unique` | ✅ | |
|
|
21
|
+
| `strict`, `strict ( 2 )` | ✅ | Accepted; the strict rules are those of SAP, the tool does not check them all again. |
|
|
22
|
+
| `define root behavior for` / child entity, `alias` | ✅ | |
|
|
23
|
+
| `persistent table`, `mapping for … corresponding` | ✅ | |
|
|
24
|
+
| `lock master`, `lock dependent by` | ✅ | PostgreSQL row lock on the instance of the lock master (`FOR UPDATE NOWAIT`, cause `locked`, 409); one LUW at a time per process (D11). Conflict with another transaction tested on PostgreSQL (`rap-locks.test.ts`), including a lock refused in EML: the LUW goes on. |
|
|
25
|
+
| `etag master` | ✅ | `If-Match` required (428), stale ETag 412, `*` accepted; in a change set, compared with the state read before it (D32). |
|
|
26
|
+
| `etag dependent by` | ✅ | ETag of the master (`@odata.etag`, `Core.OptimisticConcurrency` through the navigation), checked on changes; a change of the dependent entity changes the ETag of the master (D32). Test `rap-variant-etag.test.ts`. |
|
|
27
|
+
| `authorization master ( global )`, `( instance )`, `( global, instance )` | ✅ | Handlers called outside local mode; refusal → 403. |
|
|
28
|
+
| `authorization dependent by` | ✅ | Check of the master (`%update`) for the operations of the dependent entity. |
|
|
29
|
+
| `AUTHORITY-CHECK OBJECT … ID … FIELD …` (`DUMMY`, `sy-subrc` 0/4/12) | ✅ | Authorization objects of abapGit (SUSO), roles of `rapt/authorizations.json` given by the roles of the OIDC token, values from the claims (D34). Tests `rap-authorizations.test.ts`, `keycloak.test.ts`. |
|
|
30
|
+
| Managed `early numbering` (UUID) | ✅ | |
|
|
31
|
+
| External numbering (key given, `mandatory : create`, `readonly : update`) | ✅ | |
|
|
32
|
+
| Unmanaged `early numbering` (`FOR NUMBERING` handler) | ✅ | Direct creation (`rap-variant-features.test.ts`) and creation by association, deep create included (`FOR CREATE Travel\_Booking`, one call for all the parents, `failed`/`reported`; `rap-variant-numbering.test.ts`). |
|
|
33
|
+
| `late numbering` | ❌ | Needs the `adjust_numbers` phase of a saver. |
|
|
34
|
+
| `with additional save`, `with unmanaged save` (header or entity, `with full data`) | ✅ | Saver class `lsc_…`: `save_modified` and `cleanup`; unmanaged: reads and locks through the CDS view (D30). Tests `rap-variant-additional-save`, `rap-variant-unmanaged-save`. |
|
|
35
|
+
| Saver inheriting from `cl_abap_behavior_saver_failed` (`failed` in `save_modified`) | ✅ | Rolls back the LUW, managed write included; message returned to the client. |
|
|
36
|
+
| `with draft`, `draft table`, `total etag`, `draft action Edit / Activate optimized / Discard / Resume`, `draft determine action Prepare` | ✅ | Draft tables, `IsActiveEntity`, exclusive lock, activation by the managed runtime (D54). See the gaps in [KNOWN_GAPS.md](../KNOWN_GAPS.md). |
|
|
37
|
+
| `unmanaged` implementation | ❌ | Out of the target (managed BO). |
|
|
38
|
+
| `with privileged mode` | ✅ | `PRIVILEGED` skips the authorization checks. |
|
|
39
|
+
| `changedocuments`, `event`, `extensible` | ❌ | No equivalent infrastructure. |
|
|
40
|
+
|
|
41
|
+
## Operations
|
|
42
|
+
|
|
43
|
+
| Feature | Status | Note |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `create`, `update`, `delete` | ✅ | OData (POST, PATCH, PUT, DELETE) and EML. |
|
|
46
|
+
| `internal create/update/delete` | ✅ | Available in EML, not exposed in OData (405). |
|
|
47
|
+
| Cascading delete of the compositions | ✅ | |
|
|
48
|
+
| `association _X { create; }` (create by association) | ✅ | OData (navigation, deep insert) and EML. |
|
|
49
|
+
| `( features : instance )` on the operations | ✅ | `__EntityControl`, `__OperationControl`; refused operation → 409. |
|
|
50
|
+
| `( features : global )` | ✅ | `FOR GLOBAL FEATURES` handler; refused operation → 409; exposed like the instance feature control (`__EntityControl`), Delete button disabled in the UI. |
|
|
51
|
+
| `( precheck )` | ✅ | create, update, delete, actions, create by association. |
|
|
52
|
+
|
|
53
|
+
## Fields
|
|
54
|
+
|
|
55
|
+
| Feature | Status | Note |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `readonly` | ✅ | Ignored for an OData consumer (D25); changeable in local mode. |
|
|
58
|
+
| `mandatory` | ✅ | No runtime check, as in RAP (D20). In `enhanced` mode (D45): checked on save, without a validation, one message per field. |
|
|
59
|
+
| `numbering : managed` | ✅ | |
|
|
60
|
+
| `readonly : update`, `mandatory : create` | ✅ | |
|
|
61
|
+
| `features : instance` (dynamic field feature control) | ✅ | `__FieldControl` (`Common.FieldControl`), change of a read-only field refused (400), field not editable in the UI. |
|
|
62
|
+
| `suppress` | ✅ | Property absent from the service. |
|
|
63
|
+
|
|
64
|
+
## Actions and functions
|
|
65
|
+
|
|
66
|
+
| Feature | Status | Note |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| Instance action, `result [1] $self` | ✅ | |
|
|
69
|
+
| Action without a result | ✅ | 204 in OData. |
|
|
70
|
+
| Result `entity …`, cardinalities `[0..*]` | ✅ | Collection of entities of another entity set. |
|
|
71
|
+
| `internal action` | ✅ | Available in EML, not exposed in OData. |
|
|
72
|
+
| `static action` | ✅ | Bound to the collection; result `$self` = the created instance. |
|
|
73
|
+
| `factory action` | ✅ | The result is the instance of `mapped` for the `%cid` of the call. |
|
|
74
|
+
| Action parameter (`parameter` to an abstract entity) | ✅ | |
|
|
75
|
+
| `( features : instance )` on an action | ✅ | `Core.OperationAvailable` through `__OperationControl`. |
|
|
76
|
+
| `( features : global )` on an action | ✅ | Instance action: `Core.OperationAvailable` through `__OperationControl` (one value for all the instances); static action: check at runtime only. |
|
|
77
|
+
| Instance `function` | ✅ | GET; abstract entity result (complex type). |
|
|
78
|
+
| `static function` | ✅ | GET on the collection. |
|
|
79
|
+
| `determine action` | ❌ | Planned after the MVP. |
|
|
80
|
+
|
|
81
|
+
## Determinations and validations
|
|
82
|
+
|
|
83
|
+
| Feature | Status | Note |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `determination … on modify` (triggers `create`, `field`) | ✅ | D21 semantics, in rounds; an internal action run from a determination. |
|
|
86
|
+
| `update`, `delete` triggers | ✅ | `delete`: the determination receives the keys of the deleted instances (still in the database until the save). |
|
|
87
|
+
| `determination … on save` | ✅ | |
|
|
88
|
+
| `validation … on save` | ✅ | Failure → 400 and rollback of the LUW. |
|
|
89
|
+
|
|
90
|
+
## Messages and responses
|
|
91
|
+
|
|
92
|
+
| Feature | Status | Note |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `failed`, `reported`, `mapped` | ✅ | |
|
|
95
|
+
| `new_message_with_text` | ✅ | |
|
|
96
|
+
| `new_message` (T100 message class, MSAG) | ✅ | OData code `CLASS/NNN`. |
|
|
97
|
+
| Exception classes implementing `if_abap_behv_message` | ✅ | Clean-room `cx_root` base (D24); attributes of the message resolved by name. |
|
|
98
|
+
| `%element` → OData `target` | ✅ | Relative to the resource of the request, otherwise absolute `/Set(key)/Property`. |
|
|
99
|
+
| Severities → OData error or `sap-messages` header | ✅ | |
|
|
100
|
+
| `%state_area`, state messages | 🟡 | Without draft, the messages are returned as transition messages. |
|
|
101
|
+
|
|
102
|
+
## EML in the ABP
|
|
103
|
+
|
|
104
|
+
| Feature | Status | Note |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `READ ENTITIES` / `READ ENTITY` (`FIELDS`, `ALL FIELDS`, `FROM`), `RESULT`, `FAILED`, `REPORTED` | ✅ | Lowered by our pass (D2). |
|
|
107
|
+
| `READ … BY \_assoc`, `LINK` | ✅ | |
|
|
108
|
+
| `READ … EXECUTE` (functions) | ✅ | |
|
|
109
|
+
| `MODIFY ENTITIES` `CREATE`, `UPDATE`, `DELETE`, `EXECUTE` (`FIELDS`, `SET FIELDS`, `FROM`, `AUTO FILL CID`) | ✅ | Including the forms abaplint does not parse (`AUTO FILL CID SET FIELDS`). |
|
|
110
|
+
| `MODIFY … CREATE BY \_assoc` | ✅ | |
|
|
111
|
+
| `IN LOCAL MODE`, `PRIVILEGED` | ✅ | Local mode: neither authorization nor feature control, read-only fields changeable. |
|
|
112
|
+
| `COMMIT ENTITIES`, `ROLLBACK ENTITIES` in a handler | ✅ | Forbidden, as in RAP (runtime error). |
|
|
113
|
+
| `GET PERMISSIONS`, `SET LOCKS`, `MODIFY … OPERATIONS`, `RELATING TO`, `AUGMENTING`, `RAISE ENTITY EVENT` | ❌ | Diagnostic ABP005/ABP007. |
|
|
114
|
+
|
|
115
|
+
## ABAP SQL in the ABP
|
|
116
|
+
|
|
117
|
+
| Feature | Status | Note |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `SELECT` on the tables and CDS entities of the project: `SINGLE`, `INTO TABLE`, `APPENDING`, `CORRESPONDING`, `WHERE` (including `IN` on a range, `LIKE`, `BETWEEN`, `EXISTS`), `ORDER BY` (including `PRIMARY KEY`), `UP TO n ROWS`, `GROUP BY`/`HAVING`, aggregates, joins, `FOR ALL ENTRIES` | ✅ | Views in ABAP format of the `rapt_abap` schema, in the transaction of the LUW (D26). Test `rap-variant-sql.test.ts`. |
|
|
120
|
+
| Existence check `SELECT SINGLE @abap_true … INTO @DATA(x)`, `MAX`/`MIN` in an inline declaration | ✅ | Declared by the rewriting pass (abaplint does not type them). |
|
|
121
|
+
| Other literals, aggregates or expressions in an inline declaration | ❌ | Diagnostic ABP009: declare the target. |
|
|
122
|
+
| `SELECT … ENDSELECT` | 🟡 | With `SELECT *` only (ABP007 otherwise). |
|
|
123
|
+
| `OPEN CURSOR`, `FETCH NEXT CURSOR` | 🟡 | Not ABAP Cloud (refused by the check, as on SAP); supported by the runtime. |
|
|
124
|
+
| Types of the CDS entities in the ABP (`DATA ls TYPE zr_travel`) | ✅ | "Shadow" tables (D19, D26). |
|
|
125
|
+
| `MESSAGE … INTO` | ✅ | Texts of the message classes of the project. |
|
|
126
|
+
| `INSERT`, `UPDATE`, `MODIFY`, `DELETE` in the saver (`save_modified`) | ✅ | Exact `MAPPING FROM ENTITY` and `INDICATORS SET STRUCTURE %control` (kernel); classic writes through the `rapt_abap` views and their triggers (D30). |
|
|
127
|
+
| `INSERT`, `UPDATE`, `MODIFY`, `DELETE` in a handler; `WITH` | ❌ | Diagnostic ABP007: the RAP runtime writes the BO, change it with EML. |
|
|
128
|
+
|
|
129
|
+
## Remote APIs in the ABP (D31)
|
|
130
|
+
|
|
131
|
+
| Feature | Status | Note |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| HTTP client: `cl_http_destination_provider` (`create_by_url`, `create_by_comm_arrangement`, `create_by_cloud_destination`), `cl_web_http_client_manager`, `if_web_http_client`, `if_web_http_request`, `if_web_http_response` | ✅ | Path, query, headers, text or binary body, form, basic/bearer, status, headers and body of the response. Test `rap-variant-remote.test.ts`. |
|
|
134
|
+
| Destinations | ✅ | Environment variables `DESTINATION_<NAME>_URL`, `_USER`/`_PASSWORD`, `_TOKEN`, `_HEADERS`; listed in the generated `.env.example`. |
|
|
135
|
+
| OData V4 client proxy (`/iwbep/cl_cp_factory_remote`, `cl_web_odata_client_factory`) with the class of an SCM2 | ✅ | List read (`create_by_range`, `and`/`or`/`not`, `$select`, `$orderby`, `$top`, `$skip`, `$count`), read by key, create, update, delete, ETag, CSRF token. |
|
|
136
|
+
| OData V2 client proxy with the abstract entities of an SCM | ✅ | `d.results`, `__count`, `/Date()/`, `$inlinecount`, `substringof`. |
|
|
137
|
+
| Exceptions `cx_http_dest_provider_error`, `cx_web_http_client_error`, `/iwbep/cx_gateway`, `/iwbep/cx_cp_remote` | ✅ | `get_text( )`, `http_status_code`, `http_error_body`. |
|
|
138
|
+
| `$batch`, `$expand`, deep insert, navigation by association, remote actions and functions, value controls | ❌ | See KNOWN_GAPS.md. |
|
|
139
|
+
| Communication targets, SOAP (`cl_soap_destination_provider`), RFC | ❌ | |
|
|
140
|
+
|
|
141
|
+
## ABAP Cloud utility classes in the ABP (D40)
|
|
142
|
+
|
|
143
|
+
| Feature | Status | Note |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| JSON: `/ui2/cl_json` (`serialize`, `deserialize`), `xco_cp_json` (`from_string`, `from_abap`, `apply`, `write_to`, `builder`) | ✅ | Naming modes, `compress`, `name_mappings`, booleans, dates, ISO timestamps, base64. Guide: [UTILITIES.md](UTILITIES.md). |
|
|
146
|
+
| Encodings: `cl_web_http_utility`, `cl_abap_conv_codepage`, `cl_abap_gzip`, `xco_cp=>string` / `xstring` | ✅ | Base64, UTF-8/16, ISO-8859-1, windows-1252, URL, HTML, gzip. |
|
|
147
|
+
| Text: `cl_abap_char_utilities`, `cl_abap_string_utilities`, types `string_table`, `xstring_table` | ✅ | |
|
|
148
|
+
| Numbering: `cl_numberrange_runtime` | ✅ | Intervals of `rapt/number-ranges.json`, table `rapt_number_range`. |
|
|
149
|
+
| Dates: `cl_abap_tstmp`, `cl_abap_utclong`, `xco_cp=>sy`, `xco_cp_time` | ✅ | UTC time zone. |
|
|
150
|
+
| Application log: `cl_bali_*` | ✅ | Tables `rapt_application_log(_item)`, read by filter. |
|
|
151
|
+
| Hashing: `cl_abap_message_digest`, `cl_abap_hmac` | ✅ | MD5, SHA1, SHA2. |
|
|
152
|
+
| Random numbers: `cl_abap_random*` | ✅ | Deterministic generator by seed (not cryptographic). |
|
|
153
|
+
| Regular expressions: `cl_abap_regex`, `cl_abap_matcher`, types `match_result(_tab)` | ✅ | JavaScript engine. |
|
|
154
|
+
| RTTS: `cl_abap_typedescr` and subclasses | 🟡 | `describe_by_data(_ref)`, `describe_by_object_ref`; not `describe_by_name` nor the creation of types. |
|
|
155
|
+
| Background processing: `cl_bgmc_process_factory`, `if_bgmc_op_single`, `if_bgmc_op_single_tx_uncontr`, `cl_abap_tx` (D41) | ✅ | After the commit of the LUW, in a separate LUW; `COMMIT ENTITIES` in an uncontrolled operation; state in `rapt_background_process`. Test `background.test.ts`. |
|
|
156
|
+
| E-mail: `cl_bcs_mail_message`, `cl_bcs_mail_textpart`, `cl_bcs_mail_binarypart` (D41) | ✅ | Sent after the commit of the LUW through `MAIL_SMTP_URL`, otherwise kept in `rapt_mail`. |
|
|
157
|
+
|
|
158
|
+
## Projection
|
|
159
|
+
|
|
160
|
+
| Feature | Status | Note |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| `projection` BDEF: `use create/update/delete/action/function/association` | ✅ | |
|
|
163
|
+
| `use etag` | ✅ | |
|
|
164
|
+
| Elements renamed or omitted in the projection | ✅ | |
|
|
165
|
+
| `augment`, precheck and actions of the projection itself | ❌ | Planned after the MVP. |
|
|
166
|
+
|
|
167
|
+
## CDS and service
|
|
168
|
+
|
|
169
|
+
| Feature | Status | Note |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| `define root view entity`, `define view entity`, `as projection on`, `provider contract` | ✅ | |
|
|
172
|
+
| `composition`, `association to parent`, `redirected to` | ✅ | |
|
|
173
|
+
| Associations to entities without a BO (read-only entity sets) | ✅ | Entities exposed without behavior: read-only. |
|
|
174
|
+
| Metadata extensions (DDLX) and merge of the annotations | ✅ | |
|
|
175
|
+
| Abstract entities (parameters and results of actions and functions) | ✅ | |
|
|
176
|
+
| Custom entities (`define custom entity`, `@ObjectModel.query.implementedBy`, `if_rap_query_provider`) | ✅ | OData reads through the query class: ranges and SQL string of the filter, sorting, paging, count, navigation, `$expand` (D43). |
|
|
177
|
+
| `managed with unmanaged save` BO on a custom entity | ✅ | `enhanced` mode only (`rapt/config.json`, D45): instances read by the query class, written by `save_modified` to the API (D43). |
|
|
178
|
+
| Standard views `I_Currency`, `I_UnitOfMeasure`, `I_Country`, `I_Language` and their texts | ✅ | Added when a source names them, with their reference data (D44). |
|
|
179
|
+
| Value helps (`@Consumption.valueHelpDefinition`) | ✅ | Entity and text view exposed implicitly as read-only, `Common.ValueList` (D44); `additionalBinding` (filter, result), `useForValidation`, drop-down list (`sizeCategory: #XS`), action parameters (D56). |
|
|
180
|
+
| Table entities (`define [root] table entity`) | ✅ | Table and view entity; implicit persistence of a managed BO; `null`, keys, associations, compositions (D55). |
|
|
181
|
+
| CDS simple types (`define type x : abap.char(40);`) | ✅ | DRTY objects (`.drty.acds`): type and label of the elements (D55). |
|
|
182
|
+
| CDS enumerated types (`define type x : abap.char(1) enum { … }`) | ✅ | Base values in the database; constants usable in the behavior pool. OData exposure: refused in `standard` mode as on SAP (CDS021), `EnumType` in `enhanced` mode (D55). |
|
|
183
|
+
| Standard views `I_Region`, `I_CalendarDate`, `I_TimeZone`, `I_BusinessUserBasic`, `I_ExchangeRate` | ✅ | Generated calendar, users of the IdP recorded on sign-in, exchange rates to maintain (D44). |
|
|
184
|
+
| CDS expressions in the select list (CASE, CAST, calculations, SQL functions, literals, `$projection`) | ✅ | Computed by the PostgreSQL view, type inferred or given by `CAST` (CDS022 otherwise), read-only (`Core.Computed`), projections, drafts (D67). Still CDS002: `$session.user`/`client`/`system_language`, association paths, `BETWEEN`, aggregates, other functions. |
|
|
185
|
+
| DCL access control (`define role … grant select on … where …`) | ✅ | OData reads filtered for the user: `aspect pfcg_auth` (filters `ACTVT = '03'`, tuples), `aspect user`, `?=`, comparisons, `like`, `is [not] null`, `and`/`or`/`not`, paths `_Assoc.Element` (to-one), `inheriting conditions from entity` (D35). Tests `rap-authorizations.test.ts`, `dcl.test.ts`. |
|
|
186
|
+
| Side effects (`side effects { … }`) | ✅ | `Common.SideEffects` in the `$metadata`; the generated UI does not use them yet (the object is reloaded after a save). |
|
|
187
|
+
|
|
188
|
+
## OData V4 service
|
|
189
|
+
|
|
190
|
+
| Feature | Status | Note |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| Service document, `$metadata` (CSDL with annotations) | ✅ | |
|
|
193
|
+
| GET collection, GET entity (short and named key) | ✅ | |
|
|
194
|
+
| Navigation `Entity(…)/_Assoc`, key on the navigation, `/$count` | ✅ | |
|
|
195
|
+
| `$filter`: eq, ne, gt, ge, lt, le, and, or, not, in, parentheses, `null` | ✅ | Parameterized SQL queries. |
|
|
196
|
+
| `$filter`: contains, startswith, endswith, tolower, toupper, trim, length, indexof, substring, concat, year…second, now | ✅ | `%` and `_` are literal characters. |
|
|
197
|
+
| `$filter` on a to-one navigation (`_Travel/Status`) | ✅ | Scalar subquery. |
|
|
198
|
+
| `$filter` with `any`/`all` on a collection | ❌ | 501 response. |
|
|
199
|
+
| `$orderby`, `$top`, `$skip`, `$count` | ✅ | The keys complete the sorting: stable paging. |
|
|
200
|
+
| `$select` | ✅ | Keys and ETag always read. |
|
|
201
|
+
| One-level `$expand`, with nested `$select`, `$orderby`, `$filter`, `$top`, `$skip`, `$count` | ✅ | `$top`/`$skip` per parent (`row_number()`). Nested `$expand`: 501. |
|
|
202
|
+
| Simple `$search` | ✅ | ILIKE on the `@Search.defaultSearchElement` fields, each term required. |
|
|
203
|
+
| `IEEE754Compatible=true` (Decimal and Int64 as strings) | ✅ | Exact JSON numbers otherwise, on read and on write. |
|
|
204
|
+
| ETag (`@odata.etag`, `ETag` header), `If-Match` | ✅ | |
|
|
205
|
+
| POST, PATCH, PUT, DELETE, deep insert, creation through a navigation | ✅ | `Location`, `Prefer: return=minimal`. |
|
|
206
|
+
| Bound and static actions (POST), functions (GET) | ✅ | |
|
|
207
|
+
| Multipart `$batch`: reads and change sets | ✅ | One change set = one LUW, `$<Content-ID>` references, deferred responses (D23). |
|
|
208
|
+
| Instance feature control in the reads | ✅ | `__EntityControl`, `__OperationControl`, `__FieldControl` (D25). |
|
|
209
|
+
| CSRF token (`X-CSRF-Token: Fetch`) | ✅ | Required for cookie sessions (M6). |
|
|
210
|
+
| Errors in OData V4 format (`@Common.numericSeverity`, `details`, `target`) | ✅ | Status according to the cause of the failure (D22). |
|
|
211
|
+
| `sap-*` parameters | ✅ | Ignored. |
|
|
212
|
+
| Authentication: dev mode, Bearer JWT (OIDC, JWKS) | ✅ | Browser sessions (PKCE): M6; *client credentials* tokens (technical user); development OAuth 2.0 server (`/oauth`, client credentials and PKCE) in `rapt dev` (D60). |
|
|
213
|
+
| *OData V4 - Web API* binding | ✅ | Without UI annotations, value helps, side effects, feature control; active instances of a draft BO (D60). |
|
|
214
|
+
| `$apply`: `filter`, `groupby`, `aggregate` (`sum`, `min`, `max`, `average`, `countdistinct`, `$count`) | ✅ | With the DCL of the user; other transformations: 501 (D52). |
|
|
215
|
+
| Enumeration types (`EnumType`): JSON by member name, literals `Ns.Type'M'` | ✅ | `enhanced` mode, CDS enumerated types (D55). |
|
|
216
|
+
| JSON batch, `$value`, single properties | ❌ | Not in the MVP. |
|
|
217
|
+
|
|
218
|
+
## Generated UI (OpenUI5)
|
|
219
|
+
|
|
220
|
+
| Feature | Status | Note |
|
|
221
|
+
|---|---|---|
|
|
222
|
+
| List Report: columns (`UI.lineItem`), sorting (`UI.presentationVariant`), growing | ✅ | `sap.f.DynamicPage`, `sap.m.Table`. |
|
|
223
|
+
| Filter fields (`UI.selectionField`), search (`@Search.searchable`) | ✅ | Conditions as in SAP Fiori (`=`, `!=`, `>`, `>=`, `<`, `<=`, `a...b`, `*x*`, `<empty>`, exclusions `!(…)`), several values per field, NUMC without leading zeros, dates in the format of the language; *Search and Select* / *Define Conditions* dialog as in Fiori elements, operators according to the type and `selectionType` (D68); *Clear*, *Adapt Filters* (columns added as filters), "Filtered By" summary (D51). |
|
|
224
|
+
| User variants (`sap.m.VariantManagement`) | ✅ | Filters, filters and visible columns, sorting; saved per user by the service (`$variants`); default variant, favorites (D51). |
|
|
225
|
+
| Table settings: visible columns, sorting | ✅ | `sap.m.p13n.Popup`; number of rows in the title of the table. |
|
|
226
|
+
| Value help (`@Consumption.valueHelpDefinition`) | ✅ | Entity exposed implicitly, `Common.ValueList`, dialog with the descriptions of the text view, in the Object Page (D44) and in the filter dialog with the conditions (D68). |
|
|
227
|
+
| Refresh of the list after a change on the Object Page, breadcrumbs | ✅ | D51. |
|
|
228
|
+
| Non-draft creation from the List Report | ✅ | Object Page in create mode, `POST` on save. |
|
|
229
|
+
| Delete, table actions (`#FOR_ACTION` in `UI.lineItem`) | ✅ | On the selected row. |
|
|
230
|
+
| Object Page: header (`UI.headerInfo`), sections (`UI.facet`: identification, field groups, tables) | ✅ | `sap.uxap.ObjectPageLayout`. |
|
|
231
|
+
| Edit and save (PATCH in a change set, `If-Match`) | ✅ | Cancel with `resetChanges`. |
|
|
232
|
+
| Tables of the compositions, creation and deletion of children in edit mode | ✅ | New row at the top of the table, creation and deletion sent in the same change set on save. |
|
|
233
|
+
| Header actions (`UI.identification`), parameters (dialog), factory actions | ✅ | Parameter dialog, error message of the action, opening of the instance created by a factory action. |
|
|
234
|
+
| Feature control: actions (`__OperationControl`), Edit/Delete (`__EntityControl`), fields (`__FieldControl`) | ✅ | Instance and global; tested in the browser (`ui-features.test.ts`). |
|
|
235
|
+
| Read-only fields, mandatory fields, fields editable on create only | ✅ | From the field characteristics of the BDEF. |
|
|
236
|
+
| Messages (errors, success) | ✅ | `MessageBox`, `MessageToast`, `MessagePopover`. |
|
|
237
|
+
| Buttons according to the authorizations of the user | ✅ | Create hidden without the global create authorization (`$permissions`); Edit, Delete, actions and creation of children disabled per instance (`__EntityControl`, `__OperationControl`, D36). Test `ui-authorizations.test.ts`. |
|
|
238
|
+
| Worklist, Analytical List Page, Overview Page, Form entry floorplans | ✅ | `ui` of `rapt/config.json`, written by `rapt floorplan` or the VS Code command (D61), which asks for it before generating the application (D66); `@UI.chart` charts in SVG, `@UI.selectionVariant` tabs (D53). |
|
|
239
|
+
| Draft in the UI: creation and editing in a draft, fields saved, Save / Discard, editing status in the list | ✅ | D54; as in Fiori Elements: *Editing Status* filter, draft of the user instead of the active instance, *Locked by X*, `DraftIndicator`, *Keep Draft* / *Discard Draft* (D58). |
|
|
240
|
+
| Collaborative draft (`with collaborative draft`, `draft action Share`) | ✅ | Users of the draft, invitation, joining with Edit, refresh every 5 s (D59). |
|
|
241
|
+
| Values of an enumerated type: labels, choice list in edit mode and in the filter | ✅ | `enhanced` mode (D55). |
|
|
242
|
+
|
|
243
|
+
## Launchpad (D37)
|
|
244
|
+
|
|
245
|
+
| Feature | Status | Note |
|
|
246
|
+
|---|---|---|
|
|
247
|
+
| Groups and tiles (`launchpad.json`): title, subtitle, footer, icon | ✅ | `sap.m.GenericTile`; `rapt launchpad` checks the content (LPD001 to LPD007). |
|
|
248
|
+
| Tiles assigned to roles of the IdP (business catalog of a business role) | ✅ | Filtered by the server; without a role, visible to everyone. |
|
|
249
|
+
| Dynamic tiles: `$count` of an entity set, `$filter` | ✅ | With the access controls of the user (DCL); read on load. |
|
|
250
|
+
| Intent navigation (`/#Object-action`, `/go/Object-action?…`) | ✅ | Parameters passed to the application in the query string. |
|
|
251
|
+
| Shell bar: home, tile search, user, sign-out | ✅ | `sap.f.ShellBar`, also above the applications opened from the launchpad. |
|
|
252
|
+
| A single origin: UI of the applications under `/apps/<id>/`, services at their paths | ✅ | Redirects rewritten; 502 when an application does not answer. |
|
|
253
|
+
| Single sign-on: OIDC session of the launchpad read by the applications | ✅ | Authorizations, DCL, CSRF and required role of each application kept; tested (`launchpad.test.ts`). |
|
|
254
|
+
| External tiles (URL) | ✅ | Opened in a new tab. |
|
|
255
|
+
| Docker: launchpad, applications and their databases, Keycloak (`oidc` profile) | ✅ | Generated `docker-compose.yml`. |
|
|
256
|
+
| Spaces and pages (`spaces` → `pages` → `sections`), assigned to roles | ✅ | Space tabs, list of the pages, last space remembered (D48). |
|
|
257
|
+
| Development launchpad (`rapt dev`): application, documentation, `$metadata`, MCP | ✅ | D49. |
|
|
258
|
+
| One "Launchpad" per workspace, applications added when they are created (`rapt new`, `rapt floorplan`, `rapt launchpad add`) | ✅ | D69; idempotent, `--launchpad`, `--no-launchpad`. |
|
|
259
|
+
| Applications built with the launchpad from their sources (`source`); deployment of the complete launchpad or of one application alone | ✅ | D69; `out/launchpad/apps/<id>`, LPD009. |
|
|
260
|
+
| Personalization by the user, notifications, navigation between applications from an application | ❌ | See KNOWN_GAPS. |
|
|
261
|
+
|
|
262
|
+
## Generated application and operations
|
|
263
|
+
|
|
264
|
+
| Feature | Status | Note |
|
|
265
|
+
|---|---|---|
|
|
266
|
+
| `package.json`, `server.mjs`, bundled runtime (`vendor/`), `npm install` | ✅ | e2e test. |
|
|
267
|
+
| Configuration by environment variables (`.env.example`) | ✅ | |
|
|
268
|
+
| PostgreSQL (`DATABASE_URL`), schema applied on startup | ✅ | e2e test on PostgreSQL 16. |
|
|
269
|
+
| Embedded PGlite (`PGLITE_DIR`) for development | ✅ | e2e test: startup, data kept after a restart (D33). |
|
|
270
|
+
| Multi-stage Dockerfile, `docker-compose.yml` (app + PostgreSQL) | ✅ | Image built and `docker compose up` checked (OData service, actions, UI); `docker` CI job. |
|
|
271
|
+
| Keycloak profile (imported realm: client `rapt-app`, user `alice`) | ✅ | `keycloak.test.ts` against a real Keycloak: sign-in form, PKCE, session, CSRF, sign-out, bearer tokens (JWKS); in CI with the `oidc` profile of the generated docker-compose (D33). |
|
|
272
|
+
| OIDC: bearer tokens (JWKS), browser sessions (code + PKCE), CSRF, sign-out | ✅ | Sign-out with `id_token_hint`: no confirmation page at the provider (D37). |
|
|
273
|
+
| Required role (`OIDC_REQUIRED_ROLE`) | ✅ | Keycloak roles (`realm_access.roles`) or configurable claim. |
|
|
274
|
+
| Optimized UI5 bundle (`ui5 build`) | ❌ | Resources served from the npm sources (D27). |
|
|
275
|
+
| Cloud Foundry (SAP BTP): `manifest.yml`, route and bound PostgreSQL read from `VCAP_*` | ✅ | D50, guide [DEPLOYMENT.md](DEPLOYMENT.md). |
|
|
276
|
+
| MCP server of the service (`rapt mcp`, `/mcp`) | ✅ | One tool per operation, descriptions in `rapt/mcp.json` (D47, guide [MCP.md](MCP.md)). |
|
|
277
|
+
|
|
278
|
+
## Tooling
|
|
279
|
+
|
|
280
|
+
| Feature | Status | Note |
|
|
281
|
+
|---|---|---|
|
|
282
|
+
| VS Code extension: commands of the CLI, Problems, wizard, *RAP Objects* view, floorplans | ✅ | D39, D61. |
|
|
283
|
+
| `rapt` on the PATH of the terminals of VS Code | ✅ | Shims of the extension (D64). |
|
|
284
|
+
| MCP server of rapt for AI coding agents (`rapt agent`), registered in the agent mode of VS Code | ✅ | Check, objects, floorplans, abapGit, documentation (D64). |
|
|
285
|
+
| npm package `open-rap-runtime` (`rapt`, `npx open-rap-runtime`) | ✅ | D65; archives of `pnpm pack` checked on each tag before publication with `NPM_TOKEN`. |
|
|
286
|
+
| Website with the documentation | ✅ | D62, D63. |
|
|
287
|
+
| Feedback form (website, *RAP: Report a bug or request a feature…*) to the public feedback repository | ✅ | D71. |
|