@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
@@ -0,0 +1,302 @@
1
+ /**
2
+ * `rapt launchpad`: the folder of a launchpad of applications (decision D37). Its server (the
3
+ * runtime, embedded in `vendor/`) serves the OpenUI5 launchpad, opens the sessions the
4
+ * applications read and forwards their requests; docker-compose starts it with the applications
5
+ * built by `rapt build` (one PostgreSQL each) and, in the `oidc` profile, Keycloak.
6
+ */
7
+ import { CFIGNORE, cloudFoundryManifest, deploySection } from "../deploy.js";
8
+ import { existsSync, readFileSync } from "node:fs";
9
+ import path from "node:path";
10
+ import { appUrlVariable } from "@open-rap/model";
11
+ import { generateApplication } from "../../build.js";
12
+ import { Diagnostics } from "../../diagnostics.js";
13
+ import { loadProject } from "../../input/project.js";
14
+ import { resolveLaunchpad } from "../../launchpad/config.js";
15
+ import { keycloakRealm } from "../keycloak.js";
16
+ import { packageDir, vendorPackage } from "../vendor.js";
17
+ import { LAUNCHPAD_COMPONENT, LAUNCHPAD_CONTROLLER, LAUNCHPAD_CSS, LAUNCHPAD_LOGO, LAUNCHPAD_VIEW, launchpadIndexHtml, launchpadManifest } from "./ui.js";
18
+ const SERVER = `#!/usr/bin/env node
19
+ // Generated by Open RAP Runtime: starts the launchpad of the applications.
20
+ // Configuration by environment variables: see README.md and .env.example.
21
+ import { fileURLToPath } from "node:url";
22
+ import { startLaunchpad } from "@open-rap/runtime";
23
+
24
+ const launchpad = await startLaunchpad({ dir: fileURLToPath(new URL(".", import.meta.url)) });
25
+ console.log(\`Launchpad ready at \${launchpad.url}\`);
26
+ for (const signal of ["SIGINT", "SIGTERM"]) {
27
+ process.once(signal, () => {
28
+ launchpad.close().then(() => process.exit(0), () => process.exit(1));
29
+ });
30
+ }
31
+ `;
32
+ const DOCKERFILE = `# syntax=docker/dockerfile:1
33
+ # Generated by Open RAP Runtime.
34
+ FROM node:22-alpine AS dependencies
35
+ WORKDIR /app
36
+ COPY package.json .npmrc ./
37
+ COPY vendor ./vendor
38
+ RUN npm install --omit=dev --omit=optional --no-audit --no-fund
39
+
40
+ FROM node:22-alpine
41
+ ENV NODE_ENV=production PORT=8090
42
+ WORKDIR /app
43
+ COPY --from=dependencies /app/node_modules ./node_modules
44
+ COPY . .
45
+ USER node
46
+ EXPOSE 8090
47
+ HEALTHCHECK --interval=10s --timeout=3s --retries=5 CMD wget -qO- http://127.0.0.1:8090/health || exit 1
48
+ CMD ["node", "server.mjs"]
49
+ `;
50
+ const DOCKERIGNORE = `node_modules
51
+ .env
52
+ `;
53
+ const posix = (p) => p.split(path.sep).join("/");
54
+ /** The applications with a generated folder run in docker-compose, behind the launchpad. */
55
+ function compose(name, model, apps, outDir) {
56
+ const local = apps.filter((a) => a.build !== undefined && outDir !== undefined);
57
+ const lines = [
58
+ "# Generated by Open RAP Runtime.",
59
+ "# docker compose up --build launchpad, applications and PostgreSQL, no login (AUTH_MODE=none)",
60
+ "# AUTH_MODE=oidc docker compose --profile oidc up --build",
61
+ "# with Keycloak (user alice / alice), see README.md",
62
+ "# The applications behind the launchpad share its login: same client, public URL and SESSION_SECRET.",
63
+ "x-login: &login",
64
+ " AUTH_MODE: ${AUTH_MODE:-none}",
65
+ " OIDC_ISSUER: http://localhost:8180/realms/rapt",
66
+ " OIDC_DISCOVERY_URL: http://keycloak:8080/realms/rapt/.well-known/openid-configuration",
67
+ " OIDC_CLIENT_ID: rapt-launchpad",
68
+ " OIDC_CLIENT_SECRET: rapt-launchpad-secret",
69
+ " SESSION_SECRET: ${SESSION_SECRET:-change-me-change-me-change-me-change-me}",
70
+ " PUBLIC_URL: http://localhost:8090/",
71
+ "",
72
+ "services:",
73
+ " launchpad:",
74
+ " build: .",
75
+ ` image: ${name}:latest`,
76
+ " environment:",
77
+ " <<: *login",
78
+ ...model.apps.map((a) => ` ${appUrlVariable(a.id)}: ${local.some((l) => l.id === a.id) ? `http://${a.id}:8080/` : a.url}`),
79
+ " ports:",
80
+ ' - "8090:8090"',
81
+ ];
82
+ if (local.length > 0) {
83
+ lines.push(" depends_on:", ...local.flatMap((a) => [` ${a.id}:`, " condition: service_healthy"]));
84
+ }
85
+ for (const app of local) {
86
+ lines.push("", ` ${app.id}:`, ` build: ${posix(path.relative(outDir, app.build)) || "."}`, " environment:", " <<: *login", ` DATABASE_URL: postgres://app:app@db-${app.id}:5432/app`, " depends_on:", ` db-${app.id}:`, " condition: service_healthy", "", ` db-${app.id}:`, " image: postgres:16-alpine", " environment:", " POSTGRES_DB: app", " POSTGRES_USER: app", " POSTGRES_PASSWORD: app", " healthcheck:", ' test: ["CMD-SHELL", "pg_isready -U app -d app"]', " interval: 5s", " retries: 20", " volumes:", ` - db-${app.id}-data:/var/lib/postgresql/data`);
87
+ }
88
+ lines.push("", " keycloak:", " image: quay.io/keycloak/keycloak:26.0", ' profiles: ["oidc"]', " command: start-dev --import-realm", " environment:", " KC_BOOTSTRAP_ADMIN_USERNAME: admin", " KC_BOOTSTRAP_ADMIN_PASSWORD: admin", " KC_HOSTNAME: http://localhost:8180", ' KC_HOSTNAME_BACKCHANNEL_DYNAMIC: "true"', " volumes:", " - ./keycloak:/opt/keycloak/data/import:ro", " ports:", ' - "8180:8080"');
89
+ if (local.length > 0) {
90
+ lines.push("", "volumes:", ...local.map((a) => ` db-${a.id}-data:`));
91
+ }
92
+ return `${lines.join("\n")}\n`;
93
+ }
94
+ function envExample(model) {
95
+ return `# Configuration of the generated launchpad (all optional).
96
+ PORT=8090
97
+ PUBLIC_URL=http://localhost:8090/
98
+ LOG_LEVEL=info
99
+ # none (development user DEV_USER, its roles DEV_ROLES — default: every tile) or oidc
100
+ AUTH_MODE=none
101
+ DEV_USER=DEVELOPER
102
+ # DEV_ROLES=travel_viewer
103
+ OIDC_ISSUER=http://localhost:8180/realms/rapt
104
+ OIDC_DISCOVERY_URL=
105
+ OIDC_CLIENT_ID=rapt-launchpad
106
+ OIDC_CLIENT_SECRET=rapt-launchpad-secret
107
+ OIDC_REQUIRED_ROLE=
108
+ # the same secret in the applications behind the launchpad: they read its sessions
109
+ SESSION_SECRET=change-me-change-me-change-me-change-me
110
+ # where the launchpad reaches the applications
111
+ ${model.apps.map((a) => `${appUrlVariable(a.id)}=${a.url}`).join("\n")}
112
+ `;
113
+ }
114
+ function readme(name, model) {
115
+ const tiles = model.groups.flatMap((g) => g.tiles.map((t) => ({ group: g.title, tile: t })));
116
+ return `# ${name}
117
+
118
+ Launchpad generated by [Open RAP Runtime](https://clementringot.github.io/RAP-Transpiler): the entry
119
+ point of the applications, as the SAP Fiori launchpad, built with OpenUI5. It shows the tiles
120
+ assigned to the roles of the user, opens the applications at \`/apps/<id>/\` and forwards the
121
+ requests of their UIs to their services: the browser sees a single origin and logs in once.
122
+
123
+ ## Run
124
+
125
+ With Docker (the applications generated next to it are built and started too):
126
+
127
+ \`\`\`sh
128
+ docker compose up --build # http://localhost:8090/ (no login)
129
+ AUTH_MODE=oidc docker compose --profile oidc up --build # Keycloak, user alice / alice
130
+ \`\`\`
131
+
132
+ With Node.js 22, the applications running: \`npm install\` then \`npm start\`
133
+ (\`APP_<ID>_URL\` gives where each application runs).
134
+
135
+ ## The applications behind the launchpad
136
+
137
+ The launchpad opens the session (OIDC, authorization code with PKCE) and the applications read it:
138
+ they need the same \`SESSION_SECRET\`, \`AUTH_MODE=oidc\` with the same issuer, and the client and
139
+ \`PUBLIC_URL\` of the launchpad (a login asked by an application then comes back to it). The claims
140
+ the authorizations of the applications read are kept in the session: ${model.claims.length === 0 ? "none" : model.claims.map((c) => `\`${c}\``).join(", ")}.
141
+
142
+ | Application | Mounted at | Services | Variable |
143
+ |---|---|---|---|
144
+ ${model.apps.map((a) => `| ${a.title} | \`/apps/${a.id}/\` | ${a.servicePaths.map((p) => `\`${p}\``).join("<br>") || "—"} | \`${appUrlVariable(a.id)}\` |`).join("\n")}
145
+
146
+ ## Tiles
147
+
148
+ A tile is shown to the users having one of its roles (every user without roles); \`/go/<intent>\`
149
+ and \`/#<intent>\` open the application of an intent.
150
+
151
+ | Group | Tile | Intent | Roles | Count |
152
+ |---|---|---|---|---|
153
+ ${tiles.map(({ group, tile }) => `| ${group} | ${tile.title} | ${tile.intent === undefined ? "" : `\`${tile.intent}\``} | ${tile.roles.length === 0 ? "every user" : tile.roles.map((r) => `\`${r}\``).join(", ")} | ${tile.count === undefined ? "" : `\`${tile.count}\``} |`).join("\n")}
154
+
155
+ ${deploySection(name, "launchpad")}
156
+ On Cloud Foundry, each application is pushed on its own route; give their routes to the
157
+ launchpad with \`cf set-env ${name} APP_<ID>_URL https://…\`.
158
+
159
+ ## Content
160
+
161
+ | Path | Content |
162
+ |---|---|
163
+ | \`launchpad/config.json\` | the tiles, groups and applications, read by the server |
164
+ | \`ui/\` | OpenUI5 launchpad |
165
+ | \`keycloak/rapt-realm.json\` | realm of the Keycloak of docker-compose (client \`rapt-launchpad\`) |
166
+ | \`vendor/\` | the runtime of Open RAP Runtime (MIT) |
167
+ `;
168
+ }
169
+ /** The files of the OpenUI5 launchpad (`ui/`), served by the launchpad server. */
170
+ export function generateLaunchpadUi(model) {
171
+ return [
172
+ { path: "index.html", content: launchpadIndexHtml(model.title) },
173
+ { path: "manifest.json", content: launchpadManifest(model.title) },
174
+ { path: "Component.js", content: LAUNCHPAD_COMPONENT },
175
+ { path: "view/Launchpad.view.xml", content: LAUNCHPAD_VIEW },
176
+ { path: "controller/Launchpad.controller.js", content: LAUNCHPAD_CONTROLLER },
177
+ { path: "css/style.css", content: LAUNCHPAD_CSS },
178
+ { path: "logo.svg", content: LAUNCHPAD_LOGO },
179
+ ];
180
+ }
181
+ /** Resolves `launchpad.json` and generates the files of the launchpad. */
182
+ export function generateLaunchpad(file, options = {}) {
183
+ const diagnostics = new Diagnostics();
184
+ const resolution = resolveLaunchpad(file, diagnostics, options.built === undefined ? {} : { built: options.built });
185
+ if (resolution === undefined || diagnostics.hasErrors()) {
186
+ return resolution === undefined ? { diagnostics, files: [] } : { diagnostics, model: resolution.model, files: [] };
187
+ }
188
+ const { model, apps } = resolution;
189
+ const runtimeDir = packageDir("@open-rap/runtime", "runtime", options.runtimeDir);
190
+ const modelDir = packageDir("@open-rap/model", "model");
191
+ if (runtimeDir === undefined || modelDir === undefined) {
192
+ diagnostics.error("APP001", "the @open-rap/runtime and @open-rap/model packages (built: dist/) are needed to embed the runtime; give --runtime <dir> or run pnpm build");
193
+ return { diagnostics, model, files: [] };
194
+ }
195
+ const runtime = JSON.parse(readFileSync(path.join(runtimeDir, "package.json"), "utf8"));
196
+ const version = (dependency) => runtime.dependencies?.[dependency] ?? runtime.devDependencies?.[dependency] ?? "*";
197
+ const slug = model.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
198
+ const name = slug === "" ? "rapt-launchpad" : slug.includes("launchpad") ? slug : `${slug}-launchpad`;
199
+ const openui5 = Object.keys(runtime.devDependencies ?? {}).filter((d) => d.startsWith("@openui5/"));
200
+ const pkg = {
201
+ name,
202
+ version: "1.0.0",
203
+ private: true,
204
+ description: `${/launchpad/i.test(model.title) ? model.title : `Launchpad ${model.title}`}, generated by Open RAP Runtime`,
205
+ type: "module",
206
+ engines: { node: ">=22" },
207
+ scripts: { start: "node server.mjs" },
208
+ dependencies: {
209
+ "@open-rap/runtime": "file:vendor/open-rap-runtime",
210
+ "@open-rap/model": "file:vendor/open-rap-model",
211
+ ...Object.fromEntries(openui5.map((d) => [d, version(d)])),
212
+ "less-openui5": version("less-openui5"),
213
+ },
214
+ overrides: { "@open-rap/model": "$@open-rap/model" },
215
+ };
216
+ const realm = keycloakRealm({ clientId: "rapt-launchpad", clientName: "Launchpad generated by Open RAP Runtime", secret: "rapt-launchpad-secret", url: "http://localhost:8090", roles: model.roles, claims: model.claims });
217
+ const files = [
218
+ { path: "package.json", content: `${JSON.stringify(pkg, null, 2)}\n` },
219
+ { path: ".npmrc", content: "install-links=true\n" },
220
+ { path: "server.mjs", content: SERVER },
221
+ { path: "launchpad/config.json", content: `${JSON.stringify(model, null, 2)}\n` },
222
+ ...generateLaunchpadUi(model).map((f) => ({ path: `ui/${f.path}`, content: f.content })),
223
+ { path: "Dockerfile", content: DOCKERFILE },
224
+ // the applications built with it (D69) have their own image and route
225
+ { path: ".dockerignore", content: `${DOCKERIGNORE}${options.built?.size ? "apps\n" : ""}` },
226
+ { path: "manifest.yml", content: cloudFoundryManifest(name, { database: false, memory: "256M" }) },
227
+ { path: ".cfignore", content: `${CFIGNORE}${options.built?.size ? "apps\n" : ""}` },
228
+ { path: "docker-compose.yml", content: compose(name, model, apps, options.outDir === undefined ? undefined : path.resolve(options.outDir)) },
229
+ { path: "keycloak/rapt-realm.json", content: `${JSON.stringify(realm, null, 2)}\n` },
230
+ { path: ".env.example", content: envExample(model) },
231
+ { path: "README.md", content: readme(name, model) },
232
+ ...vendorPackage(modelDir, "open-rap-model", {}),
233
+ ...vendorPackage(runtimeDir, "open-rap-runtime", { "@open-rap/model": "file:../open-rap-model" }),
234
+ ];
235
+ return { diagnostics, model, files };
236
+ }
237
+ const APP_ID = /^[a-z][a-z0-9-]*$/;
238
+ /**
239
+ * `rapt launchpad`: the launchpad and, built from their sources (`source`, D69) into
240
+ * `apps/<id>/`, its applications. A single folder to deploy: docker-compose starts them all.
241
+ */
242
+ export async function buildLaunchpad(file, options) {
243
+ const diagnostics = new Diagnostics();
244
+ const at = { file };
245
+ let entries = [];
246
+ try {
247
+ const source = JSON.parse(readFileSync(file, "utf8"));
248
+ entries = Array.isArray(source?.apps) ? source.apps : [];
249
+ }
250
+ catch {
251
+ // reported by resolveLaunchpad
252
+ }
253
+ const base = path.dirname(path.resolve(file));
254
+ const outDir = path.resolve(options.outDir);
255
+ const built = new Map();
256
+ const files = [];
257
+ const apps = [];
258
+ for (const entry of entries) {
259
+ const id = entry?.["id"];
260
+ const source = entry?.["source"];
261
+ if (typeof id !== "string" || !APP_ID.test(id) || typeof source !== "string" || source.trim() === "" || entry?.["build"] !== undefined || built.has(id)) {
262
+ continue;
263
+ }
264
+ const dir = path.resolve(base, source);
265
+ if (!existsSync(dir)) {
266
+ diagnostics.error("LPD009", `the application ${id}: no folder ${source} (source, relative to launchpad.json)`, at);
267
+ continue;
268
+ }
269
+ const service = entry?.["service"];
270
+ const result = await generateApplication(loadProject(dir), {
271
+ ...(typeof service === "string" ? { service } : {}),
272
+ ...(options.runtimeDir === undefined ? {} : { runtimeDir: options.runtimeDir }),
273
+ });
274
+ for (const d of result.diagnostics.items) {
275
+ if (d.severity !== "info") {
276
+ diagnostics.add(d.severity, d.code, `${id}: ${d.message}`, { file: d.file === undefined ? dir : path.join(dir, ...d.file.split("/")), ...(d.line === undefined ? {} : { line: d.line }), ...(d.column === undefined ? {} : { column: d.column }) });
277
+ }
278
+ }
279
+ if (result.model === undefined || result.files.length === 0) {
280
+ diagnostics.error("LPD009", `the application ${id} does not build (rapt check ${source})`, at);
281
+ continue;
282
+ }
283
+ let title;
284
+ try {
285
+ title = JSON.parse(result.files.find((f) => f.path === "ui/manifest.json")?.content ?? "")["sap.app"]?.title;
286
+ }
287
+ catch {
288
+ // an application without UI (Web API)
289
+ }
290
+ built.set(id, { dir: path.join(outDir, "apps", id), model: result.model, ...(title === undefined ? {} : { title }) });
291
+ files.push(...result.files.map((f) => ({ path: `apps/${id}/${f.path}`, content: f.content })));
292
+ apps.push({ id, source: dir, out: path.join(outDir, "apps", id), files: result.files.length });
293
+ }
294
+ const launchpad = generateLaunchpad(file, { ...options, built });
295
+ diagnostics.addAll(launchpad.diagnostics);
296
+ const model = launchpad.model === undefined ? {} : { model: launchpad.model };
297
+ if (diagnostics.hasErrors() || launchpad.files.length === 0) {
298
+ return { diagnostics, ...model, files: [], apps };
299
+ }
300
+ return { diagnostics, ...model, files: [...launchpad.files, ...files], apps };
301
+ }
302
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/gen/launchpad/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The UI of the launchpad (decision D37), plain OpenUI5 (sap.m, sap.f): the counterpart of the
3
+ * SAP Fiori launchpad, whose shell (sap.ushell) exists in SAPUI5 only. A ShellBar (home, search,
4
+ * user menu with the logout), the groups of tiles of `/launchpad/config` (GenericTile; a
5
+ * NumericContent for the tiles with a count) and the navigation by intent (`#Travel-manage`).
6
+ */
7
+ export declare function launchpadIndexHtml(title: string): string;
8
+ export declare function launchpadManifest(title: string): string;
9
+ export declare const LAUNCHPAD_COMPONENT = "sap.ui.define([\n \"sap/ui/core/UIComponent\",\n \"sap/ui/model/json/JSONModel\"\n], function (UIComponent, JSONModel) {\n \"use strict\";\n\n return UIComponent.extend(\"rapt.launchpad.Component\", {\n metadata: { manifest: \"json\", interfaces: [\"sap.ui.core.IAsyncContentCreation\"] },\n\n init: function () {\n UIComponent.prototype.init.apply(this, arguments);\n this.setModel(new JSONModel({ title: \"\", user: {}, logout: \"\", groups: [], spaces: [], space: \"\", page: \"\", pages: [], counts: {}, loaded: false, error: \"\", emptyText: \"\" }));\n }\n });\n});\n";
10
+ export declare const LAUNCHPAD_VIEW = "<mvc:View controllerName=\"rapt.launchpad.controller.Launchpad\" xmlns:mvc=\"sap.ui.core.mvc\" xmlns=\"sap.m\" xmlns:f=\"sap.f\" xmlns:core=\"sap.ui.core\" displayBlock=\"true\" height=\"100%\">\n <Page id=\"page\" enableScrolling=\"true\" class=\"raptLaunchpad\">\n <customHeader>\n <f:ShellBar id=\"shellBar\" title=\"{/title}\" homeIcon=\"logo.svg\" homeIconTooltip=\"Home\" homeIconPressed=\".onHome\" avatarPressed=\".onAvatarPressed\">\n <f:searchManager>\n <f:SearchManager id=\"search\" placeholder=\"Search for apps\" liveChange=\".onSearch\" search=\".onSearch\"/>\n </f:searchManager>\n <f:profile>\n <Avatar id=\"avatar\" initials=\"{/user/initials}\" tooltip=\"{/user/name}\"/>\n </f:profile>\n </f:ShellBar>\n </customHeader>\n <content>\n <MessageStrip id=\"message\" visible=\"{= ${/error} !== '' }\" text=\"{/error}\" type=\"Error\" showIcon=\"true\" class=\"sapUiSmallMargin\"/>\n <IconTabHeader id=\"spaces\" visible=\"{= ${/spaces}.length > 1 }\" selectedKey=\"{/space}\" select=\".onSpaceSelect\" mode=\"Inline\"\n items=\"{path: '/spaces', templateShareable: false}\">\n <items><IconTabFilter key=\"{id}\" text=\"{title}\"/></items>\n </IconTabHeader>\n <HBox id=\"pageBar\" visible=\"{= ${/pages}.length > 1 }\" alignItems=\"Center\" class=\"raptLaunchpadPages\">\n <Label text=\"Page\" labelFor=\"pages\" class=\"sapUiTinyMarginEnd\"/>\n <Select id=\"pages\" selectedKey=\"{/page}\" change=\".onPageSelect\" items=\"{path: '/pages', templateShareable: false}\">\n <items><core:Item key=\"{id}\" text=\"{title}\"/></items>\n </Select>\n </HBox>\n <VBox id=\"groups\" class=\"raptLaunchpadGroups\"/>\n <Text id=\"empty\" visible=\"{= ${/emptyText} !== '' }\" text=\"{/emptyText}\" class=\"raptLaunchpadEmpty\"/>\n </content>\n </Page>\n</mvc:View>\n";
11
+ export declare const LAUNCHPAD_CONTROLLER = "sap.ui.define([\n \"sap/ui/core/mvc/Controller\",\n \"sap/m/GenericTile\",\n \"sap/m/TileContent\",\n \"sap/m/NumericContent\",\n \"sap/m/ImageContent\",\n \"sap/m/Title\",\n \"sap/m/FlexBox\",\n \"sap/m/VBox\",\n \"sap/m/Text\",\n \"sap/m/Button\",\n \"sap/m/ResponsivePopover\"\n], function (Controller, GenericTile, TileContent, NumericContent, ImageContent, Title, FlexBox, VBox, Text, Button, ResponsivePopover) {\n \"use strict\";\n\n var INTENT = /^([A-Za-z][A-Za-z0-9_]*-[A-Za-z][A-Za-z0-9_]*)(\\?.*)?$/;\n\n /** The menu of the user: its identifier, and the logout of the OIDC sessions. */\n function userMenu(sId, oUser, sLogout) {\n var aItems = [];\n if (oUser.id !== oUser.name) {\n aItems.push(new Text({ text: oUser.id }));\n }\n if (!sLogout) {\n aItems.push(new Text({ text: \"Development user (no login)\" }));\n }\n var oMenu = new ResponsivePopover(sId, { title: oUser.name, placement: \"Bottom\", contentMinWidth: \"12rem\" });\n if (aItems.length > 0) {\n oMenu.addContent(new VBox({ items: aItems }).addStyleClass(\"sapUiSmallMargin\"));\n }\n if (sLogout) {\n oMenu.setBeginButton(new Button(sId + \"-logout\", {\n text: \"Sign Out\",\n icon: \"sap-icon://log\",\n press: function () {\n window.location.assign(sLogout);\n }\n }));\n }\n return oMenu;\n }\n\n return Controller.extend(\"rapt.launchpad.controller.Launchpad\", {\n onInit: function () {\n var that = this;\n this._sQuery = \"\";\n fetch(\"/launchpad/config\", { credentials: \"same-origin\", headers: { accept: \"application/json\" } })\n .then(function (oResponse) {\n if (!oResponse.ok) {\n throw new Error(\"The launchpad answered \" + oResponse.status);\n }\n return oResponse.json();\n })\n .then(function (oConfig) {\n var oModel = that._model();\n oModel.setProperty(\"/title\", oConfig.title);\n oModel.setProperty(\"/user\", oConfig.user);\n oModel.setProperty(\"/logout\", oConfig.logout || \"\");\n oModel.setProperty(\"/groups\", oConfig.groups);\n oModel.setProperty(\"/spaces\", oConfig.spaces || [{ id: \"home\", title: oConfig.title, pages: [{ id: \"home\", title: oConfig.title, groups: oConfig.groups }] }]);\n that._selectSpace(that._rememberedSpace());\n document.title = oConfig.title;\n // #SemanticObject-action: straight to the application of the intent\n if (that._navigateToIntent()) {\n return;\n }\n that._render();\n that._loadCounts();\n oModel.setProperty(\"/loaded\", true);\n })\n .catch(function (oError) {\n that._model().setProperty(\"/error\", oError.message);\n });\n },\n\n _model: function () {\n return this.getOwnerComponent().getModel();\n },\n\n _tiles: function () {\n return this._model().getProperty(\"/groups\").reduce(function (aAll, oGroup) {\n return aAll.concat(oGroup.tiles);\n }, []);\n },\n\n /** The space shown last (local storage), else the first one. */\n _rememberedSpace: function () {\n try {\n return window.localStorage.getItem(\"rapt.launchpad.space\") || \"\";\n } catch (e) {\n return \"\";\n }\n },\n\n _selectSpace: function (sId, sPage) {\n var oModel = this._model();\n var aSpaces = oModel.getProperty(\"/spaces\");\n var oSpace = aSpaces.find(function (s) { return s.id === sId; }) || aSpaces[0];\n if (!oSpace) {\n return;\n }\n oModel.setProperty(\"/space\", oSpace.id);\n oModel.setProperty(\"/pages\", oSpace.pages);\n var oPage = oSpace.pages.find(function (p) { return p.id === sPage; }) || oSpace.pages[0];\n oModel.setProperty(\"/page\", oPage ? oPage.id : \"\");\n try {\n window.localStorage.setItem(\"rapt.launchpad.space\", oSpace.id);\n } catch (e) {\n // the space is not remembered\n }\n },\n\n onSpaceSelect: function (oEvent) {\n this._selectSpace(oEvent.getParameter(\"key\"));\n this._render();\n },\n\n onPageSelect: function (oEvent) {\n this._model().setProperty(\"/page\", oEvent.getParameter(\"selectedItem\").getKey());\n this._render();\n },\n\n /** The sections shown: those of the current page; while searching, every section of every space. */\n _shownGroups: function () {\n var oModel = this._model();\n if (this._sQuery) {\n return oModel.getProperty(\"/groups\");\n }\n var oPage = (oModel.getProperty(\"/pages\") || []).find(function (p) { return p.id === oModel.getProperty(\"/page\"); });\n return oPage ? oPage.groups : oModel.getProperty(\"/groups\");\n },\n\n _navigateToIntent: function () {\n var sHash = window.location.hash.replace(/^#/, \"\");\n try {\n sHash = decodeURIComponent(sHash);\n } catch (e) {\n // kept as written\n }\n var aMatch = INTENT.exec(sHash);\n if (!aMatch || aMatch[1] === \"Shell-home\") {\n return false;\n }\n var oTile = this._tiles().find(function (t) {\n return t.intent === aMatch[1];\n });\n if (!oTile) {\n this._model().setProperty(\"/error\", \"No application of the launchpad for the intent \" + aMatch[1]);\n return false;\n }\n var sQuery = aMatch[2] || \"\";\n window.location.replace(oTile.target + (sQuery && oTile.target.indexOf(\"?\") >= 0 ? \"&\" + sQuery.slice(1) : sQuery));\n return true;\n },\n\n _render: function () {\n var that = this;\n var oBox = this.byId(\"groups\");\n var sQuery = this._sQuery.toLowerCase();\n var iVisible = 0;\n oBox.destroyItems();\n this._shownGroups().forEach(function (oGroup) {\n var aTiles = oGroup.tiles.filter(function (t) {\n return !sQuery || [t.title, t.subtitle, t.info].some(function (s) {\n return !!s && s.toLowerCase().indexOf(sQuery) >= 0;\n });\n });\n if (aTiles.length === 0) {\n return;\n }\n iVisible += aTiles.length;\n var oTiles = new FlexBox({ wrap: \"Wrap\", renderType: \"Bare\" }).addStyleClass(\"raptLaunchpadTiles\");\n aTiles.forEach(function (oTile) {\n oTiles.addItem(that._tile(oTile));\n });\n oBox.addItem(new VBox({ items: [new Title({ text: oGroup.title, level: \"H2\", titleStyle: \"H4\" }).addStyleClass(\"raptLaunchpadGroupTitle\"), oTiles] }).addStyleClass(\"raptLaunchpadGroup\"));\n });\n this._model().setProperty(\"/emptyText\", iVisible > 0 ? \"\" : sQuery ? \"No app matches the search.\" : \"No application is assigned to your roles.\");\n },\n\n _tile: function (oTile) {\n var oContent;\n if (oTile.count) {\n oContent = new NumericContent({ value: \"{/counts/\" + oTile.id + \"}\", icon: oTile.icon, withMargin: false, nullifyValue: false, animateTextChange: false });\n } else if (oTile.icon) {\n oContent = new ImageContent({ src: oTile.icon });\n }\n return new GenericTile(this.createId(\"tile-\" + oTile.id), {\n header: oTile.title,\n subheader: oTile.subtitle,\n press: this._open.bind(this, oTile),\n tileContent: [new TileContent({ footer: oTile.info, content: oContent })]\n }).addStyleClass(\"raptLaunchpadTile\");\n },\n\n /** The dynamic tiles: the $count of an entity set of an application, with the access controls of the user. */\n _loadCounts: function () {\n var oModel = this._model();\n this._tiles().filter(function (t) {\n return !!t.count;\n }).forEach(function (oTile) {\n fetch(oTile.count, { credentials: \"same-origin\", headers: { accept: \"text/plain\" } })\n .then(function (oResponse) {\n return oResponse.ok ? oResponse.text() : \"\";\n })\n .then(function (sCount) {\n oModel.setProperty(\"/counts/\" + oTile.id, sCount.trim());\n })\n .catch(function () {\n oModel.setProperty(\"/counts/\" + oTile.id, \"\");\n });\n });\n },\n\n _open: function (oTile) {\n if (oTile.external) {\n window.open(oTile.target, \"_blank\", \"noopener\");\n } else {\n window.location.assign(oTile.target);\n }\n },\n\n onHome: function () {\n window.location.assign(\"/\");\n },\n\n onSearch: function (oEvent) {\n var sValue = oEvent.getParameter(\"newValue\");\n this._sQuery = (sValue === undefined ? oEvent.getParameter(\"query\") : sValue) || \"\";\n this._render();\n },\n\n onAvatarPressed: function (oEvent) {\n if (!this._oUserMenu) {\n this._oUserMenu = userMenu(this.createId(\"userMenu\"), this._model().getProperty(\"/user\"), this._model().getProperty(\"/logout\"));\n this.getView().addDependent(this._oUserMenu);\n }\n this._oUserMenu.openBy(oEvent.getParameter(\"avatar\"));\n }\n });\n});\n";
12
+ export declare const LAUNCHPAD_CSS = ".raptLaunchpadGroups { padding: 1rem 2rem 0 2rem; }\n.raptLaunchpadPages { padding: 0.75rem 2rem 0 2rem; }\n.raptLaunchpadGroup { margin-bottom: 1.5rem; }\n.raptLaunchpadGroupTitle { margin: 0 0 0.75rem 0; }\n.raptLaunchpadTile { margin: 0 1rem 1rem 0; }\n.raptLaunchpadEmpty { display: block; margin: 2rem; }\n@media (max-width: 599px) {\n .raptLaunchpadGroups { padding: 1rem 1rem 0 1rem; }\n .raptLaunchpadTile { margin: 0 0.5rem 0.5rem 0; }\n}\n";
13
+ /** The mark of the launchpad: four tiles. */
14
+ export declare const LAUNCHPAD_LOGO = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\">\n <rect x=\"3\" y=\"3\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\"/>\n <rect x=\"18\" y=\"3\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\" fill-opacity=\"0.6\"/>\n <rect x=\"3\" y=\"18\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\" fill-opacity=\"0.6\"/>\n <rect x=\"18\" y=\"18\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\"/>\n</svg>\n";