@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.
Files changed (227) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -2
  3. package/dist/agent/server.d.ts +35 -0
  4. package/dist/agent/server.js +408 -0
  5. package/dist/agent/server.js.map +1 -0
  6. package/dist/authoring/abapgit.d.ts +38 -0
  7. package/dist/authoring/abapgit.js +242 -0
  8. package/dist/authoring/abapgit.js.map +1 -0
  9. package/dist/authoring/catalog.d.ts +48 -0
  10. package/dist/authoring/catalog.js +117 -0
  11. package/dist/authoring/catalog.js.map +1 -0
  12. package/dist/authoring/floorplan.d.ts +28 -0
  13. package/dist/authoring/floorplan.js +31 -0
  14. package/dist/authoring/floorplan.js.map +1 -0
  15. package/dist/authoring/generate.d.ts +57 -0
  16. package/dist/authoring/generate.js +630 -0
  17. package/dist/authoring/generate.js.map +1 -0
  18. package/dist/authoring/mcp.d.ts +15 -0
  19. package/dist/authoring/mcp.js +52 -0
  20. package/dist/authoring/mcp.js.map +1 -0
  21. package/dist/authoring/new.d.ts +35 -0
  22. package/dist/authoring/new.js +389 -0
  23. package/dist/authoring/new.js.map +1 -0
  24. package/dist/bdef/ast.d.ts +249 -0
  25. package/dist/bdef/ast.js +3 -0
  26. package/dist/bdef/ast.js.map +1 -0
  27. package/dist/bdef/lexer.d.ts +105 -0
  28. package/dist/bdef/lexer.js +148 -0
  29. package/dist/bdef/lexer.js.map +1 -0
  30. package/dist/bdef/parser.d.ts +22 -0
  31. package/dist/bdef/parser.js +1012 -0
  32. package/dist/bdef/parser.js.map +1 -0
  33. package/dist/build.d.ts +26 -0
  34. package/dist/build.js +62 -0
  35. package/dist/build.js.map +1 -0
  36. package/dist/cds/adapter.d.ts +91 -0
  37. package/dist/cds/adapter.js +381 -0
  38. package/dist/cds/adapter.js.map +1 -0
  39. package/dist/cds/expression-ast.d.ts +65 -0
  40. package/dist/cds/expression-ast.js +330 -0
  41. package/dist/cds/expression-ast.js.map +1 -0
  42. package/dist/cli.d.ts +9 -0
  43. package/dist/cli.js +485 -0
  44. package/dist/cli.js.map +1 -0
  45. package/dist/dcl/parser.d.ts +59 -0
  46. package/dist/dcl/parser.js +338 -0
  47. package/dist/dcl/parser.js.map +1 -0
  48. package/dist/ddic/catalog.d.ts +17 -0
  49. package/dist/ddic/catalog.js +211 -0
  50. package/dist/ddic/catalog.js.map +1 -0
  51. package/dist/ddic/cds-types.d.ts +47 -0
  52. package/dist/ddic/cds-types.js +131 -0
  53. package/dist/ddic/cds-types.js.map +1 -0
  54. package/dist/ddic/table-source.d.ts +70 -0
  55. package/dist/ddic/table-source.js +500 -0
  56. package/dist/ddic/table-source.js.map +1 -0
  57. package/dist/ddic/xml.d.ts +65 -0
  58. package/dist/ddic/xml.js +201 -0
  59. package/dist/ddic/xml.js.map +1 -0
  60. package/dist/dev.d.ts +128 -0
  61. package/dist/dev.js +434 -0
  62. package/dist/dev.js.map +1 -0
  63. package/dist/diagnostics.d.ts +33 -0
  64. package/dist/diagnostics.js +53 -0
  65. package/dist/diagnostics.js.map +1 -0
  66. package/dist/gen/abap/derived-types.d.ts +26 -0
  67. package/dist/gen/abap/derived-types.js +323 -0
  68. package/dist/gen/abap/derived-types.js.map +1 -0
  69. package/dist/gen/abap/eml.d.ts +118 -0
  70. package/dist/gen/abap/eml.js +362 -0
  71. package/dist/gen/abap/eml.js.map +1 -0
  72. package/dist/gen/abap/enums.d.ts +13 -0
  73. package/dist/gen/abap/enums.js +74 -0
  74. package/dist/gen/abap/enums.js.map +1 -0
  75. package/dist/gen/abap/framework-http.d.ts +14 -0
  76. package/dist/gen/abap/framework-http.js +1049 -0
  77. package/dist/gen/abap/framework-http.js.map +1 -0
  78. package/dist/gen/abap/framework-query.d.ts +14 -0
  79. package/dist/gen/abap/framework-query.js +225 -0
  80. package/dist/gen/abap/framework-query.js.map +1 -0
  81. package/dist/gen/abap/framework-utils.d.ts +29 -0
  82. package/dist/gen/abap/framework-utils.js +3707 -0
  83. package/dist/gen/abap/framework-utils.js.map +1 -0
  84. package/dist/gen/abap/framework.d.ts +12 -0
  85. package/dist/gen/abap/framework.js +480 -0
  86. package/dist/gen/abap/framework.js.map +1 -0
  87. package/dist/gen/abap/generate.d.ts +40 -0
  88. package/dist/gen/abap/generate.js +238 -0
  89. package/dist/gen/abap/generate.js.map +1 -0
  90. package/dist/gen/abap/rewrite.d.ts +82 -0
  91. package/dist/gen/abap/rewrite.js +957 -0
  92. package/dist/gen/abap/rewrite.js.map +1 -0
  93. package/dist/gen/abap/shadow.d.ts +25 -0
  94. package/dist/gen/abap/shadow.js +175 -0
  95. package/dist/gen/abap/shadow.js.map +1 -0
  96. package/dist/gen/abap/tokens.d.ts +33 -0
  97. package/dist/gen/abap/tokens.js +87 -0
  98. package/dist/gen/abap/tokens.js.map +1 -0
  99. package/dist/gen/app/index.d.ts +25 -0
  100. package/dist/gen/app/index.js +322 -0
  101. package/dist/gen/app/index.js.map +1 -0
  102. package/dist/gen/csdl.d.ts +11 -0
  103. package/dist/gen/csdl.js +562 -0
  104. package/dist/gen/csdl.js.map +1 -0
  105. package/dist/gen/deploy.d.ts +12 -0
  106. package/dist/gen/deploy.js +53 -0
  107. package/dist/gen/deploy.js.map +1 -0
  108. package/dist/gen/docs/index.d.ts +35 -0
  109. package/dist/gen/docs/index.js +267 -0
  110. package/dist/gen/docs/index.js.map +1 -0
  111. package/dist/gen/docs/markdown.d.ts +23 -0
  112. package/dist/gen/docs/markdown.js +187 -0
  113. package/dist/gen/docs/markdown.js.map +1 -0
  114. package/dist/gen/docs/site.d.ts +17 -0
  115. package/dist/gen/docs/site.js +106 -0
  116. package/dist/gen/docs/site.js.map +1 -0
  117. package/dist/gen/keycloak.d.ts +21 -0
  118. package/dist/gen/keycloak.js +90 -0
  119. package/dist/gen/keycloak.js.map +1 -0
  120. package/dist/gen/launchpad/index.d.ts +48 -0
  121. package/dist/gen/launchpad/index.js +302 -0
  122. package/dist/gen/launchpad/index.js.map +1 -0
  123. package/dist/gen/launchpad/ui.d.ts +14 -0
  124. package/dist/gen/launchpad/ui.js +350 -0
  125. package/dist/gen/launchpad/ui.js.map +1 -0
  126. package/dist/gen/mcp.d.ts +23 -0
  127. package/dist/gen/mcp.js +244 -0
  128. package/dist/gen/mcp.js.map +1 -0
  129. package/dist/gen/sql-expressions.d.ts +12 -0
  130. package/dist/gen/sql-expressions.js +136 -0
  131. package/dist/gen/sql-expressions.js.map +1 -0
  132. package/dist/gen/sql.d.ts +38 -0
  133. package/dist/gen/sql.js +612 -0
  134. package/dist/gen/sql.js.map +1 -0
  135. package/dist/gen/ui/index.d.ts +7 -0
  136. package/dist/gen/ui/index.js +27 -0
  137. package/dist/gen/ui/index.js.map +1 -0
  138. package/dist/gen/ui/layout.d.ts +230 -0
  139. package/dist/gen/ui/layout.js +511 -0
  140. package/dist/gen/ui/layout.js.map +1 -0
  141. package/dist/gen/ui/static.d.ts +55 -0
  142. package/dist/gen/ui/static.js +2901 -0
  143. package/dist/gen/ui/static.js.map +1 -0
  144. package/dist/gen/ui/views.d.ts +10 -0
  145. package/dist/gen/ui/views.js +511 -0
  146. package/dist/gen/ui/views.js.map +1 -0
  147. package/dist/gen/vendor.d.ts +23 -0
  148. package/dist/gen/vendor.js +68 -0
  149. package/dist/gen/vendor.js.map +1 -0
  150. package/dist/gen/xml.d.ts +9 -0
  151. package/dist/gen/xml.js +42 -0
  152. package/dist/gen/xml.js.map +1 -0
  153. package/dist/index.d.ts +20 -0
  154. package/dist/index.js +20 -0
  155. package/dist/index.js.map +1 -0
  156. package/dist/input/project.d.ts +50 -0
  157. package/dist/input/project.js +128 -0
  158. package/dist/input/project.js.map +1 -0
  159. package/dist/ir/access-controls.d.ts +11 -0
  160. package/dist/ir/access-controls.js +148 -0
  161. package/dist/ir/access-controls.js.map +1 -0
  162. package/dist/ir/authorizations.d.ts +25 -0
  163. package/dist/ir/authorizations.js +178 -0
  164. package/dist/ir/authorizations.js.map +1 -0
  165. package/dist/ir/behaviors.d.ts +16 -0
  166. package/dist/ir/behaviors.js +548 -0
  167. package/dist/ir/behaviors.js.map +1 -0
  168. package/dist/ir/builder.d.ts +20 -0
  169. package/dist/ir/builder.js +505 -0
  170. package/dist/ir/builder.js.map +1 -0
  171. package/dist/ir/config.d.ts +25 -0
  172. package/dist/ir/config.js +130 -0
  173. package/dist/ir/config.js.map +1 -0
  174. package/dist/ir/dictionary.d.ts +54 -0
  175. package/dist/ir/dictionary.js +328 -0
  176. package/dist/ir/dictionary.js.map +1 -0
  177. package/dist/ir/entities.d.ts +58 -0
  178. package/dist/ir/entities.js +676 -0
  179. package/dist/ir/entities.js.map +1 -0
  180. package/dist/ir/expressions.d.ts +33 -0
  181. package/dist/ir/expressions.js +327 -0
  182. package/dist/ir/expressions.js.map +1 -0
  183. package/dist/ir/handlers.d.ts +63 -0
  184. package/dist/ir/handlers.js +398 -0
  185. package/dist/ir/handlers.js.map +1 -0
  186. package/dist/ir/number-ranges.d.ts +24 -0
  187. package/dist/ir/number-ranges.js +74 -0
  188. package/dist/ir/number-ranges.js.map +1 -0
  189. package/dist/ir/seed.d.ts +23 -0
  190. package/dist/ir/seed.js +78 -0
  191. package/dist/ir/seed.js.map +1 -0
  192. package/dist/ir/service.d.ts +21 -0
  193. package/dist/ir/service.js +96 -0
  194. package/dist/ir/service.js.map +1 -0
  195. package/dist/launchpad/config.d.ts +47 -0
  196. package/dist/launchpad/config.js +321 -0
  197. package/dist/launchpad/config.js.map +1 -0
  198. package/dist/launchpad/workspace.d.ts +48 -0
  199. package/dist/launchpad/workspace.js +166 -0
  200. package/dist/launchpad/workspace.js.map +1 -0
  201. package/dist/srvd/parser.d.ts +36 -0
  202. package/dist/srvd/parser.js +193 -0
  203. package/dist/srvd/parser.js.map +1 -0
  204. package/dist/standard/data.d.ts +18 -0
  205. package/dist/standard/data.js +534 -0
  206. package/dist/standard/data.js.map +1 -0
  207. package/dist/standard/index.d.ts +36 -0
  208. package/dist/standard/index.js +507 -0
  209. package/dist/standard/index.js.map +1 -0
  210. package/dist/version.d.ts +2 -0
  211. package/dist/version.js +4 -0
  212. package/dist/version.js.map +1 -0
  213. package/docs/AGENTS.md +79 -0
  214. package/docs/ANNOTATIONS.md +76 -0
  215. package/docs/DECISIONS.md +1526 -0
  216. package/docs/DEPLOYMENT.md +113 -0
  217. package/docs/DIAGNOSTICS.md +116 -0
  218. package/docs/FEATURES.md +287 -0
  219. package/docs/GUIDE.md +560 -0
  220. package/docs/KNOWN_GAPS.md +216 -0
  221. package/docs/MCP.md +84 -0
  222. package/docs/PLAN.md +690 -0
  223. package/docs/README.md +148 -0
  224. package/docs/REMOTE_APIS.md +121 -0
  225. package/docs/ROADMAP.md +35 -0
  226. package/docs/UTILITIES.md +95 -0
  227. package/package.json +49 -3
package/docs/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # Open RAP Runtime
2
+
3
+ **Develop, test and deploy your RAP business objects without an SAP system.**
4
+
5
+ You write your RAP BO as in the ABAP Development Tools — tables, CDS views, UI annotations,
6
+ behavior definition, behavior pool in ABAP, service — and Open RAP Runtime turns it into an
7
+ application that runs anywhere: an OData V4 service, the RAP managed runtime with your ABAP code,
8
+ a PostgreSQL database and a List Report / Object Page UI in OpenUI5. The same sources are then
9
+ imported into SAP with abapGit.
10
+
11
+ ![Generated List Report](docs/images/list-report.png)
12
+
13
+ ## What it is for
14
+
15
+ - **Learning and teaching RAP** without a license or a system: the complete cycle BDEF → behavior
16
+ pool → OData → Fiori, locally, in a few seconds.
17
+ - **Prototyping** a BO and showing it to a customer or a business team before opening a system.
18
+ - **Testing** the logic of a BO (determinations, validations, actions, authorizations) in CI.
19
+ - **Shipping a small standalone application** (Docker, SAP BTP Cloud Foundry, an internal server)
20
+ when an SAP system is not justified.
21
+ - **Opening the BO to AI agents**: the service becomes an MCP server whose tools all apply the
22
+ checks of the BO.
23
+
24
+ Everything is open source under permissive licenses: no CAP, no SAPUI5, no proprietary SAP
25
+ library ([LICENSES.md](LICENSES.md)).
26
+
27
+ ## Get started in two minutes
28
+
29
+ **In VS Code**: install the `open-rap-runtime-vscode.vsix` extension (it contains everything), then
30
+ run *RAP: New complete business object…* and *RAP: Start rapt dev* (which asks for the floorplan).
31
+ The browser opens on the development launchpad.
32
+
33
+ **On the command line** (Node.js 22): `npm install -g open-rap-runtime` (or `npx open-rap-runtime`),
34
+ or from a clone `pnpm install && pnpm build`, then `node packages/compiler/dist/cli.js` instead of
35
+ `rapt`:
36
+
37
+ ```sh
38
+ rapt new my-project Travel --prefix ZRT # a complete managed BO, with data
39
+ rapt dev my-project # http://localhost:8080/ — rebuilt on each save
40
+ ```
41
+
42
+ ![Development launchpad](docs/images/dev-launchpad.png)
43
+
44
+ ## What you get
45
+
46
+ | You write (abapGit format) | Open RAP Runtime produces |
47
+ |---|---|
48
+ | Tables (`define table`, as in ADT), CDS table entities | PostgreSQL tables, initial data |
49
+ | CDS views, projections, CDS types (simple, enumerated), DCL | SQL views, OData V4 `$metadata`, per-user access controls |
50
+ | Metadata extensions (`@UI`) | List Report, Worklist, Analytical List Page, Overview Page (Fiori filters, user views, value helps, charts) and Object Page |
51
+ | Behavior definition | RAP managed runtime: draft, locks, ETags, numbering, authorizations, feature control, determinations, validations, actions |
52
+ | Behavior pool (ABAP Cloud) | The same code, transpiled and run: EML, messages, ABAP SQL, released classes (JSON, HTTP, bgPF, e-mail…) |
53
+ | Service definition | OData V4 service at the SAP paths, `$batch`, CSRF, OIDC |
54
+ | `rapt/mcp.json` | MCP server for AI agents |
55
+ | `launchpad.json` | OpenUI5 launchpad: spaces, pages, tiles by role, single sign-on; one per workspace, created and completed when each application is created |
56
+
57
+ ![Object Page in edit mode](docs/images/object-page.png)
58
+
59
+ ## Key features
60
+
61
+ - **Write only ABAP**: `rapt new` (a complete BO), `rapt generate` (a table, a view from its
62
+ table, a projection, a BDEF with its compositions, a behavior pool…), `rapt abapgit` (the XML
63
+ files for the import into SAP).
64
+ - **Development loop** `rapt dev`: embedded database, rebuild on each save, positioned
65
+ diagnostics (`file:line:column`), development launchpad with the built-in documentation.
66
+ - **Modes**: `standard` (strictly as on SAP, activatable on SAP) or `enhanced` (extensions:
67
+ mandatory fields checked automatically, managed BO on a custom entity, CDS enumerated types
68
+ exposed as OData `EnumType`).
69
+ - **Draft** (`with draft`, `with collaborative draft`): drafts, Edit / Activate / Discard,
70
+ exclusive lock, editing status, invited users, as in Fiori Elements.
71
+ - **Table entities and CDS types**: a complete BO on a `define table entity`, simple and
72
+ enumerated types.
73
+ - **Standard views** `I_Currency`, `I_UnitOfMeasure`, `I_Country`, `I_Language`, `I_Region`,
74
+ `I_CalendarDate`, `I_TimeZone`, `I_BusinessUserBasic`, `I_ExchangeRate` with their data, for
75
+ your value helps.
76
+ - **Fiori UI**: List Report, Worklist, Analytical List Page (`$apply`), Overview Page, Form entry;
77
+ filters with conditions (`>100`, `1...5`, `*abc*`, `!(…)`) and the *Search and Select* /
78
+ *Define Conditions* dialog, views saved per user, table settings, value helps, actions,
79
+ editable compositions.
80
+ - **CDS expressions**: calculated elements (`CASE`, `CAST`, arithmetic, SQL functions) computed
81
+ by the database view.
82
+ - **Security**: OIDC (Keycloak, SAP Cloud Identity Services, Entra ID…), Web API bindings with
83
+ OAuth 2.0 (client credentials, PKCE), authorization objects and `AUTHORITY-CHECK`, DCL, roles.
84
+ - **One launchpad per workspace**: each application is added to it when it is created; ship
85
+ either the launchpad with all its applications (`rapt launchpad`) or one application alone
86
+ (`rapt build`).
87
+ - **Deployment**: Docker, `docker compose`, SAP BTP Cloud Foundry (`cf push`), any Node.js
88
+ server.
89
+ - **VS Code extension**: object creation wizard as in ADT, *RAP Objects* view, floorplan choice,
90
+ every command of the CLI, diagnostics in the Problems tab, ABAP, CDS and BDEF highlighting;
91
+ `rapt` in the integrated terminals.
92
+ - **AI coding agents**: `rapt agent`, an MCP server that checks the project, creates objects and
93
+ searches the documentation; registered by the extension for the agent mode of VS Code.
94
+
95
+ ![Filter dialog: Search and Select, Define Conditions](docs/images/filter-dialog.png)
96
+
97
+ ## Documentation
98
+
99
+ | Document | Content |
100
+ |---|---|
101
+ | [Guide](docs/GUIDE.md) | Everything Open RAP Runtime does and how to use it (humans and AI agents) |
102
+ | [Features](docs/FEATURES.md) | RAP coverage, feature by feature |
103
+ | [Annotations](docs/ANNOTATIONS.md) | Each CDS annotation: what the `$metadata` and the UI do with it |
104
+ | [Diagnostics](docs/DIAGNOSTICS.md) | The codes of `rapt check` |
105
+ | [MCP server](docs/MCP.md) | The service for AI agents |
106
+ | [Deployment](docs/DEPLOYMENT.md) | Docker, SAP BTP Cloud Foundry, HTTPS, publishing a version (npm, extension) |
107
+ | [Utility classes](docs/UTILITIES.md), [Remote APIs](docs/REMOTE_APIS.md) | The behavior pool beyond RAP |
108
+ | [Known gaps](KNOWN_GAPS.md), [Roadmap](docs/ROADMAP.md) | What is missing, what is coming |
109
+ | [Decisions](docs/DECISIONS.md), [Plan](PLAN.md) | The technical choices and their reasons |
110
+
111
+ The same documentation opens from the launchpad of `rapt dev` (*Documentation* tile), and on the
112
+ project website.
113
+
114
+ The project website (`site/`, published on GitHub Pages by the `site.yml` workflow) presents
115
+ Open RAP Runtime, contains this documentation and serves the `.vsix` of the latest version.
116
+
117
+ ## Feedback
118
+
119
+ Report a bug or request a feature with the
120
+ [feedback form](https://clementringot.github.io/RAP-Transpiler/feedback.html) (it opens a
121
+ pre-filled issue in the public
122
+ [feedback repository](https://github.com/ClementRingot/open-rap-runtime-feedback)), or in VS Code
123
+ with *RAP: Report a bug or request a feature…*.
124
+
125
+ ## Contributing
126
+
127
+ ```sh
128
+ pnpm install
129
+ pnpm build
130
+ pnpm test # vitest: compiler, runtime, browser (Playwright if present)
131
+ ```
132
+
133
+ ```
134
+ packages/model/ types of the IR (model.json), shared naming conventions
135
+ packages/compiler/ rapt CLI, parsers (BDEF, CDS, SRVD, DCL), IR, generators
136
+ packages/runtime/ runtime of the generated applications (OData V4, RAP managed, launchpad, MCP)
137
+ packages/vscode/ VS Code extension (calls the rapt CLI)
138
+ packages/cli/ npm package open-rap-runtime (the rapt command)
139
+ fixtures/ reference BOs: travel (Travel / Booking), custom-entity, table-entity
140
+ site/ project website
141
+ ```
142
+
143
+ The rules for working on the repository (for humans and agents alike) are in
144
+ [AGENTS.md](AGENTS.md).
145
+
146
+ ## License
147
+
148
+ MIT ([LICENSE](LICENSE)); dependencies under permissive licenses ([LICENSES.md](LICENSES.md)).
@@ -0,0 +1,121 @@
1
+ # Consuming a remote API from the BO (SCM, SCM2, HTTP client)
2
+
3
+ A behavior pool can call a remote API with the usual ABAP Cloud code: the HTTP client
4
+ (`cl_web_http_client_manager`) for a REST API, the OData client proxy of a service consumption
5
+ model for an OData V2 or V4 service. The generated application runs this code as is; only the
6
+ destination is configured differently from SAP (decision D31).
7
+
8
+ ## 1. What to export with abapGit
9
+
10
+ | On SAP | In the abapGit repository | What Open RAP Runtime does with it |
11
+ |---|---|---|
12
+ | Service consumption model 2 (OData V4) | the generated consumption model class (`INHERITING FROM /iwbep/cl_v4_abs_pm_model_prov`) | keeps its types (`tys_…`, `tyt_…`) and constants (`gcs_entity_set`…); the `define` method is removed |
13
+ | Service consumption model (OData V2/V4, first generation) | the generated abstract entities and the service definition of the proxy | the abstract entities type the data; the service definition without a binding is not built (info SRVD007) |
14
+ | REST API | nothing | |
15
+
16
+ The `.srvc` file of the service consumption model itself is not needed: the proxy reads the
17
+ `$metadata` of the remote service on its first call.
18
+
19
+ ## 2. The code of the behavior pool
20
+
21
+ The same as on SAP, for example in an action:
22
+
23
+ ```abap
24
+ METHOD importRemote.
25
+ DATA remote_travels TYPE zscm_rt_travel=>tyt_travel_type.
26
+ DATA travel_ids TYPE RANGE OF zscm_rt_travel=>tys_travel_type-travel_id.
27
+
28
+ READ ENTITIES OF zrt_r_travel IN LOCAL MODE
29
+ ENTITY Travel FIELDS ( TravelID ) WITH CORRESPONDING #( keys )
30
+ RESULT DATA(travels).
31
+ travel_ids = VALUE #( FOR t IN travels ( sign = 'I' option = 'EQ' low = t-TravelID ) ).
32
+
33
+ TRY.
34
+ DATA(destination) = cl_http_destination_provider=>create_by_comm_arrangement(
35
+ comm_scenario = 'ZRT_TRAVEL_REMOTE'
36
+ service_id = 'ZRT_TRAVEL_REMOTE_REST' ).
37
+ DATA(proxy) = /iwbep/cl_cp_factory_remote=>create_v4_remote_proxy(
38
+ is_proxy_model_key = VALUE #( repository_id = 'DEFAULT'
39
+ proxy_model_id = 'ZSCM_RT_TRAVEL'
40
+ proxy_model_version = '0001' )
41
+ io_http_client = cl_web_http_client_manager=>create_by_http_destination( destination )
42
+ iv_relative_service_root = '/sap/opu/odata4/sap/zrt_ui_travel_o4/srvd/sap/zrt_ui_travel/0001/' ).
43
+
44
+ DATA(request) = proxy->create_resource_for_entity_set( zscm_rt_travel=>gcs_entity_set-travel )->create_request_for_read( ).
45
+ DATA(filter_factory) = request->create_filter_factory( ).
46
+ request->set_filter( filter_factory->create_by_range( iv_property_path = 'TRAVEL_ID' it_range = travel_ids ) ).
47
+ request->set_top( 50 ).
48
+ DATA(response) = request->execute( ).
49
+ response->get_business_data( IMPORTING et_business_data = remote_travels ).
50
+
51
+ CATCH /iwbep/cx_cp_remote INTO DATA(remote_error).
52
+ " remote_error->http_status_code, remote_error->get_text( )
53
+ CATCH /iwbep/cx_gateway cx_web_http_client_error cx_http_dest_provider_error INTO DATA(error).
54
+ " error->get_text( )
55
+ ENDTRY.
56
+ ENDMETHOD.
57
+ ```
58
+
59
+ The internal names of the class (`TRAVEL_ID`, `'TRAVEL'`) are matched with the names of the
60
+ service (`TravelID`, `Travel`) ignoring case and `_`. Supported: list read (`create_by_range`,
61
+ `and`/`or`/`not`, `set_select_properties`, `set_orderby`, `set_top`, `set_skip`,
62
+ `request_count`, `request_no_business_data`), read by key (`navigate_with_key`), create, update
63
+ (`PATCH` or `PUT`, `it_provided_property`, `set_if_match`), delete. The CSRF token and the
64
+ session cookies of SAP Gateway are handled by the proxy.
65
+
66
+ A REST API:
67
+
68
+ ```abap
69
+ DATA(client) = cl_web_http_client_manager=>create_by_http_destination(
70
+ cl_http_destination_provider=>create_by_cloud_destination( i_name = 'RATINGS'
71
+ i_authn_mode = if_a4c_cp_service=>service_specific ) ).
72
+ DATA(request) = client->get_http_request( ).
73
+ request->set_uri_path( |/api/ratings/{ travel-TravelID }| ).
74
+ request->set_header_field( i_name = 'Accept' i_value = 'application/json' ).
75
+ DATA(response) = client->execute( if_web_http_client=>get ).
76
+ DATA(status) = response->get_status( ).
77
+ IF status-code = 200.
78
+ DATA(json) = response->get_text( ).
79
+ ENDIF.
80
+ ```
81
+
82
+ ## 3. The destination
83
+
84
+ On SAP, the URL and the credentials come from a communication arrangement or from the
85
+ destination service of BTP. In the generated application, they are environment variables:
86
+
87
+ | Variable | Content |
88
+ |---|---|
89
+ | `DESTINATION_<NAME>_URL` | base URL (mandatory) |
90
+ | `DESTINATION_<NAME>_USER`, `DESTINATION_<NAME>_PASSWORD` | basic authentication |
91
+ | `DESTINATION_<NAME>_TOKEN` | bearer token (`Authorization: Bearer`) |
92
+ | `DESTINATION_<NAME>_HEADERS` | other headers, JSON object: `{"APIKey":"…"}` |
93
+
94
+ `<NAME>` is the name of `create_by_cloud_destination` (`RATINGS`), or for
95
+ `create_by_comm_arrangement`: `<SCENARIO>_<SERVICE_ID>`, otherwise `<SCENARIO>`
96
+ (`ZRT_TRAVEL_REMOTE_ZRT_TRAVEL_REMOTE_REST`, then `ZRT_TRAVEL_REMOTE`), in upper case, the
97
+ characters other than letters and digits replaced by `_`. `rapt build` lists the destinations
98
+ written as literals in the `.env.example` and the README of the application. The credentials stay
99
+ on the server: the ABAP only sees the URL.
100
+
101
+ With docker compose, in the `app` service:
102
+
103
+ ```yaml
104
+ environment:
105
+ DESTINATION_ZRT_TRAVEL_REMOTE_URL: https://my-system.example.com
106
+ DESTINATION_ZRT_TRAVEL_REMOTE_USER: ${REMOTE_USER}
107
+ DESTINATION_ZRT_TRAVEL_REMOTE_PASSWORD: ${REMOTE_PASSWORD}
108
+ ```
109
+
110
+ Behind an outgoing proxy: `HTTPS_PROXY=…` and `NODE_USE_ENV_PROXY=1`.
111
+
112
+ ## 4. Limits
113
+
114
+ See [KNOWN_GAPS.md](../KNOWN_GAPS.md#remote-apis-d31): no `$batch`, `$expand`, deep insert,
115
+ navigation by association nor actions of the remote service in the client proxy; value controls
116
+ not filled; neither user propagation nor OAuth client credentials (a fixed token with `_TOKEN`);
117
+ no communication targets, SOAP nor RFC. As on SAP, a remote call made during the interaction is
118
+ not undone by a rollback of the LUW.
119
+
120
+ Complete tested example: `packages/runtime/test/variants.ts` (`remoteVariant`) and
121
+ `packages/runtime/test/rap-variant-remote.test.ts`.
@@ -0,0 +1,35 @@
1
+ # Roadmap
2
+
3
+ What is planned, with the design elements already known. The available features are in
4
+ [FEATURES.md](FEATURES.md), the accepted gaps in [KNOWN_GAPS.md](../KNOWN_GAPS.md).
5
+
6
+ ## Draft: additions
7
+
8
+ - Determinations and validations during editing (`Prepare`, `on modify` on the draft), state
9
+ messages (`%state_area`), actions of the application on a draft, `SiblingEntity`.
10
+ - Real-time collaborative draft (WebSocket), field locks.
11
+
12
+ ## Floorplans: additions
13
+
14
+ - Analytical List Page: visual filters, several charts, `@Aggregation`.
15
+ - Overview Page described by annotations (`@UI.dataPoint`, `@UI.kpi`) rather than by
16
+ `rapt/config.json`.
17
+
18
+ ## CDS types and table entities: additions
19
+
20
+ - CDS expressions: `CAST` to a CDS type or an enumerated type, `Type.#CONST` constants in the
21
+ views.
22
+ - CDS expressions (continuation of D67): to-one association paths (`_Agency.Name`, left join in
23
+ the view), `BETWEEN`, `$session.user` and `$session.system_language` (PostgreSQL session
24
+ parameters set per request).
25
+
26
+ ## Other leads
27
+
28
+ - Value helps: fixed values of the domains, several qualified value helps per element.
29
+ - Standard views: texts in languages other than English, exchange rates from a configurable
30
+ source.
31
+ - Variants shared between users, order of the columns.
32
+ - Personalization of the launchpad by the user, notifications.
33
+ - MCP: stdio transport, resources (the `$metadata`, the documentation), OAuth authorization of
34
+ the protocol.
35
+ - Late numbering (`adjust_numbers`), RAP events (`RAISE ENTITY EVENT`), change documents.
@@ -0,0 +1,95 @@
1
+ # ABAP Cloud utility classes in the behavior pool
2
+
3
+ A behavior pool can use the released utility classes of ABAP Cloud with the usual code: JSON,
4
+ encodings, numbering, dates, application log, hashing, random numbers, regular expressions,
5
+ RTTS. Open RAP Runtime provides a "clean-room" implementation of them (written from the public
6
+ signatures documented by SAP, no SAP code); the kernel of the application does what ABAP cannot
7
+ do alone (read and write JSON, convert a code page, hash, compress, write to the database,
8
+ describe a data object) (decision D40).
9
+
10
+ Only the objects the project uses are given to the transpiler: a project that uses none of them
11
+ does not change.
12
+
13
+ ## Available classes
14
+
15
+ | Area | Classes | Methods and attributes |
16
+ |---|---|---|
17
+ | JSON | `/ui2/cl_json` | `serialize` (`compress`, `name`, `pretty_name`, `numc_as_string`, `ts_as_iso8601`, `name_mappings`, `format_output`, `hex_as_base64`), `deserialize` (`json`, `jsonx`, `pretty_name`, `name_mappings`), constants `pretty_mode` (`none`, `low_case`, `camel_case`, `extended`, `user`, `user_low_case`) and `c_bool` |
18
+ | JSON (XCO) | `xco_cp_json` | `data->from_string`, `data->from_abap`, `->apply( … )`, `->to_string( )`, `->write_to( REF #( … ) )`, `data->builder( )` (`begin_object`, `end_object`, `begin_array`, `end_array`, `add_member`, `add_string`, `add_number`, `add_boolean`, `add_null`, `get_data`); transformations `camel_case_to_underscore`, `underscore_to_camel_case`, `pascal_case_to_underscore`, `underscore_to_pascal_case`, `boolean_to_abap_bool`, `abap_bool_to_boolean` |
19
+ | Encodings | `cl_web_http_utility` | `encode_base64`, `decode_base64`, `encode_x_base64`, `decode_x_base64`, `encode_utf8`, `decode_utf8`, `escape_url`, `unescape_url`, `escape_html` |
20
+ | | `cl_abap_conv_codepage` | `create_out( codepage )->convert( )`, `create_in( codepage )->convert( )`: UTF-8, UTF-16 (LE, BE), ISO-8859-1, windows-1252, US-ASCII |
21
+ | | `cl_abap_gzip` | `compress_binary`, `decompress_binary`, `compress_text`, `decompress_text` |
22
+ | | `xco_cp=>string`, `xco_cp=>xstring`, `xco_cp_character=>code_page`, `xco_cp_binary=>text_encoding->base64` | `as_xstring`, `as_string`, `value`, `split`, `join`, `append`, `prepend`, `to_upper_case`, `to_lower_case`, `starts_with`, `ends_with` |
23
+ | Text | `cl_abap_char_utilities` | `newline`, `cr_lf`, `horizontal_tab`, `vertical_tab`, `form_feed`, `backspace`, `maxchar`, `charsize`, `byte_order_mark_utf8` |
24
+ | | `cl_abap_string_utilities` | `del_trailing_blanks`, `c2str_preserving_blanks` |
25
+ | Numbering | `cl_numberrange_runtime` | `number_get` (`quantity`, `subobject`, `toyear`; `number`, `returncode`, `returned_quantity`), `number_check`; exceptions `cx_number_ranges`, `cx_nr_object_not_found` |
26
+ | Dates and timestamps | `cl_abap_tstmp` | `add`, `subtractsecs`, `subtract`, `compare`, `move`, `move_to_short`, `normalize`, `tstmp2utclong`, `utclong2tstmp`, `utclong2tstmp_short`, `systemtstmp_syst2utc`, `systemtstmp_utc2syst`, `td_add`, `td_subtract` |
27
+ | | `cl_abap_utclong` | `diff`, `read` |
28
+ | | `xco_cp=>sy`, `xco_cp_time` | `sy->user( )->name`, `sy->language( )->value`, `sy->date( )`, `sy->time( )`, `sy->moment( )`, `sy->unix_timestamp( )`; `xco_cp_time=>date( )`, `time( )`, `moment( )`; `->as( xco_cp_time=>format->abap / iso_8601_basic / iso_8601_extended )->value`, `->add( … )`, `->subtract( … )`, `year`, `month`, `day`, `hour`, `minute`, `second`; `xco_cp_time=>time_zone->user / utc` |
29
+ | Application log | `cl_bali_log`, `cl_bali_header_setter`, `cl_bali_free_text_setter`, `cl_bali_message_setter`, `cl_bali_exception_setter`, `cl_bali_log_db`, `cl_bali_log_filter`, `if_bali_constants` | `create`, `create_with_header`, `set_header`, `add_item`, `get_all_items`, `get_handle`; `save_log`, `load_log`, `load_logs_via_filter`, `load_logs_w_items_via_filter`, `delete_log`; filter by object, subobject, external ID, user, time interval |
30
+ | Hashing | `cl_abap_message_digest`, `cl_abap_hmac` | `calculate_hash_for_char`, `calculate_hash_for_raw`, `calculate_hmac_for_char`, `calculate_hmac_for_raw`, `string_to_xstring`: MD5, SHA1, SHA224, SHA256, SHA384, SHA512 |
31
+ | Random numbers | `cl_abap_random`, `cl_abap_random_int`, `cl_abap_random_int8`, `cl_abap_random_float`, `cl_abap_random_decfloat34` | `cl_abap_random=>seed( )`, `create( seed min max )->get_next( )`; `int`, `intinrange`, `float` |
32
+ | Regular expressions | `cl_abap_regex`, `cl_abap_matcher` | `create_pcre`, `create_posix`, `create_matcher`, `cl_abap_matcher=>create`, `create_pcre`, `matches`, `contains`, `find_next`, `find_all`, `match`, `get_match`, `get_offset`, `get_length`, `get_submatch`, `replace_all`, `replace_found`, `replace_next` |
33
+ | RTTS | `cl_abap_typedescr`, `cl_abap_elemdescr`, `cl_abap_structdescr`, `cl_abap_tabledescr`, `cl_abap_refdescr`, `cl_abap_classdescr` | `describe_by_data`, `describe_by_data_ref`, `describe_by_object_ref`; `type_kind`, `kind`, `length`, `decimals`, `absolute_name`, `components`, `get_components( )`, `get_component_type( )`, `get_table_line_type( )`, constants `typekind_*` and `kind_*` |
34
+ | Background processing | `cl_bgmc_process_factory`, `if_bgmc_op_single`, `if_bgmc_op_single_tx_uncontr`, `cl_abap_tx` | `get_default( )->create( )`, `set_name`, `set_operation`, `set_operation_tx_uncontrolled`, `save_for_execution( )` → monitor (`get_state( )`), `cl_abap_tx=>save( )` / `modify( )` |
35
+ | E-mail | `cl_bcs_mail_message`, `cl_bcs_mail_textpart`, `cl_bcs_mail_binarypart` | `create_instance`, `set_sender`, `set_reply_to`, `add_recipient` (`to`, `cc`, `bcc`), `set_subject`, `set_main`, `add_attachment`, `send` (`et_status`, `ev_mail_status`), `send_async`; `create_text_plain`, `create_text_html` |
36
+ | Types | `string_table`, `xstring_table`, `match_result(_tab)`, `submatch_result(_tab)`, `abap_compdescr_tab`, `abap_component_tab` | |
37
+
38
+ ## Numbering: `rapt/number-ranges.json`
39
+
40
+ The number range objects and intervals are declared next to the sources, like the roles
41
+ (`rapt/authorizations.json`), and are versioned with them:
42
+
43
+ ```json
44
+ {
45
+ "ZRT_TRAVEL": {
46
+ "01": { "from": "1", "to": "99999999" }
47
+ }
48
+ }
49
+ ```
50
+
51
+ An interval can also have `subobject` and `toyear`. The numbers are drawn in the database of the
52
+ application (table `rapt_number_range`); an interval missing from the file starts at 1. Changing
53
+ the bounds keeps the current number. `number` is the last number of the drawn block, as on SAP:
54
+ with `quantity`, the numbers go from `number - returned_quantity + 1` to `number`. `returncode`
55
+ is `2` at the last number of the interval, `3` when the block was reduced; an exhausted interval
56
+ raises `cx_number_ranges`.
57
+
58
+ ## Application log
59
+
60
+ `cl_bali_log_db=>get_instance( )->save_log( )` writes the log into the database of the
61
+ application (tables `rapt_application_log` and `rapt_application_log_item`), with the user and
62
+ the time of the request. Log objects and subobjects do not have to be declared. The tables are
63
+ only created when the code uses the log (or the numbering, for `rapt_number_range`).
64
+
65
+ ## Background processing (bgPF)
66
+
67
+ `save_for_execution( )` records the process in the LUW of the request (table
68
+ `rapt_background_process`, state `NEW`). Once the LUW is committed, the operation runs in a LUW
69
+ of its own, with the same user, after the response to the request; a rolled-back LUW starts
70
+ nothing.
71
+
72
+ - **Controlled operation** (`if_bgmc_op_single`): the EML of the operation (without
73
+ `IN LOCAL MODE`) is saved at its end, as by the RAP framework; ABAP SQL only writes after
74
+ `cl_abap_tx=>save( )`.
75
+ - **Uncontrolled operation** (`if_bgmc_op_single_tx_uncontr`): ABAP SQL writes whenever it wants;
76
+ `COMMIT ENTITIES` (with `RESPONSE OF`) saves the EML, `ROLLBACK ENTITIES` rolls back the LUW.
77
+ - **State**: `SUCCESSFUL` or `ERRONEOUS` (with the text of the exception) in
78
+ `rapt_background_process`, read by `get_state( )` of the monitor.
79
+
80
+ ## E-mail
81
+
82
+ `send( )` composes the mail (HTML or text, text and binary attachments, copies) and keeps it in
83
+ the `rapt_mail` table of the LUW (state `WAITING`, `ev_mail_status` = `W`). Once the LUW is
84
+ committed, it is sent through the SMTP server of `MAIL_SMTP_URL`
85
+ (`smtp://user:password@server:587`, or `smtps://…:465`): state `SENT`, or `ERROR` with the
86
+ reason. Without `MAIL_SMTP_URL`, the mail stays in `rapt_mail` (state `STORED`, complete MIME
87
+ message in `raw_message`): handy with `rapt dev`. `MAIL_FROM` gives the sender when the code does
88
+ not call `set_sender`. A rolled-back LUW sends nothing.
89
+
90
+ ## Differences with SAP
91
+
92
+ See [KNOWN_GAPS.md](../KNOWN_GAPS.md), section "ABAP Cloud utilities". In short: the time zone of
93
+ the user is UTC; numbering and log are written in the LUW of the request (rolled back with it);
94
+ `describe_by_name`, `/ui2/cl_json=>generate` and associative arrays are not supported; regular
95
+ expressions go through those of JavaScript.
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@open-rap/compiler",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Compiles SAP RAP sources (abapGit format) into a standalone Node.js OData V4 application.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://clementringot.github.io/RAP-Transpiler/",
8
+ "keywords": [
9
+ "sap",
10
+ "rap",
11
+ "abap",
12
+ "cds",
13
+ "odata",
14
+ "odata-v4",
15
+ "abapgit",
16
+ "compiler",
17
+ "cli"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "./cli": {
27
+ "types": "./dist/cli.d.ts",
28
+ "default": "./dist/cli.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "framework",
34
+ "docs"
35
+ ],
36
+ "engines": {
37
+ "node": ">=22"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "@abaplint/core": "2.120.98",
44
+ "@abaplint/transpiler": "2.14.24",
45
+ "chevrotain": "13.2.0",
46
+ "fast-xml-parser": "5.12.0",
47
+ "@open-rap/model": "0.1.0"
48
+ },
49
+ "scripts": {
50
+ "build": "tsc -p tsconfig.build.json && node scripts/copy-docs.mjs"
51
+ }
6
52
  }