Skip to content

Repository files navigation

builder-cap2UI5-web

build web

Runs the complete cap2UI5 stack inside the browser: the unchanged UI5 frontend plus the whole backend (framework core + samples) bundled into a single JS file. Every roundtrip is answered in-process — no CAP server, no Node.js, just static files on GitHub Pages.

Important

Everything in this project is generated automatically — by AI (Claude) and by a sync pipeline that consumes the upstream abap2UI5 sources. Review and test before relying on it.

The full documentation lives in cap2UI5/docs.

This is the cap2UI5 twin of web-abap2UI5 — the tooling repo over there, which bundles the abaplint-transpiled ABAP sources with @abaplint/runtime and a WASM SQLite and deploys the result to web-abap2UI5-build (live demo). The split is the same one used here: tooling in the source repo, built site in the -build repo. cap2UI5's backend is already plain JavaScript, so this build gets away with much less: no ABAP runtime, no WASM database — the z2ui5-web.js bundle is ~550 KB minified — ~125 KB gzipped, which is what a visitor actually downloads — and the whole site ~1.1 MB, instead of ~12 MB.

Start a specific app exactly like on the CAP server: index.html?app_start=z2ui5_cl_smp_app_000. samples.html lists every bundled sample with its title, deep-linked into the playground and linked to its sources — generated at build time from the same catalogue the in-app overview renders.

How it works

Browser
├── index.html            unchanged UI5 shell (UI5 from CDN)
│   └── z2ui5-web.js      ← loaded BEFORE the UI5 bootstrap
├── Component.js, core/…  unchanged webapp (1:1 from the app repo's app/z2ui5)
│
│   the webapp still calls fetch("/rest/root/z2ui5", {method: "POST", …})
│   like it always does — but z2ui5-web.js has patched globalThis.fetch:
│
└── z2ui5-web.js (bundle)
    ├── fetch interceptor  POST/HEAD to */rest/root/z2ui5 → in-process call,
    │                      everything else → native fetch
    ├── z2ui5_cl_ui5_http_handler + core (core/srv/z2ui5, CAP-free)
    ├── all sample apps + built-ins (static registry, generated at build time)
    └── in-memory draft store (Map — the tab IS the session)

Three substitutions make the backend browser-able, using two additive hooks that live in the cap2UI5 framework:

Node/CAP Browser Hook
app classes resolved by walking srv/ directories + require() static registry generated at build time z2ui5_cl_util.register_app_class()
drafts in the CDS entity z2ui5_t_01 in-memory Map z2ui5_cl_ui5_srv_draft.set_store()
@sap/cds, fs, path, crypto build-time stubs (stubs/) — unreachable at runtime once the hooks above are installed esbuild alias

Build

The build web workflow runs on every push to main, weekly (Sundays 03:00 UTC, safety net) and on demand (workflow_dispatch): it mirrors the upstream repo, builds the site, uploads it as the cap2ui5-web artifact and publishes it to the dedicated build repo cap2UI5/web-cap2UI5-build.

The site is pushed to the main branch of web-cap2UI5-build — one commit per deployment, carrying the upstream sha, the tooling sha and a link to the workflow run. That push triggers the deploy pages workflow in web-cap2UI5-build, which deploys the pushed site to GitHub Pages via GitHub Actions (Settings → Pages → SourceGitHub Actions), so pushing there is the deploy. That repo's history is the audit trail of what was actually deployed: git log lists every deployment, git diff <old>..<new> shows exactly which files changed between two of them. Identical rebuilds (e.g. the weekly cron without upstream changes) add no commit. web-cap2UI5-build is written only by this workflow — don't push to it by hand; this repo (builder-cap2UI5-web) holds only the tooling.

The cross-repo push uses an SSH deploy key: generate a keypair, register the public half on web-cap2UI5-build (Settings → Deploy keys, Allow write access) and store the private half here as the secret BUILT_DEPLOY_KEY (Settings → Secrets and variables → Actions). This mirrors the ACTION_KEY_WEB deploy key that cap2UI5 already uses to push here.

Upstream changes arrive event-driven: after every published app build, the trigger_web workflow in cap2UI5 writes the upstream sha to UPSTREAM_HEAD and pushes it here via a deploy key registered on this repository with write access (private half: secret ACTION_KEY_WEB in cap2UI5) — that push starts this workflow. So the site follows every cap2UI5 change instead of waiting for the weekly cron.

Locally:

npm install
npm run mirror    # snapshot the cap2UI5 app repo → input/cap2UI5/
                  # (MIRROR_SOURCE=/path/to/checkout uses a local copy)
npm run build     # → dist/ (fully static site)
npm run serve     # local test server on http://localhost:8080

Files

mirror.mjs shallow-clone (or copy) the upstream cap2UI5 repo → input/cap2UI5/
entry.mjs browser entry: register classes, plug draft store, patch fetch
gen-registry.mjs scans samples + built-ins → generated/registry.mjs (smoke-requires every candidate, skips broken ones — same policy as the upstream sync pipeline)
build.mjs esbuild bundle + webapp copy + index.html patch + samples.htmldist/
patch-index.mjs the index.html/manifest substitutions as pure, unit-tested functions (+ the shell sanity gate)
samples-page.mjs generates samples.html, the landing page listing every bundled sample
build-info.mjs assembles the deterministic BUILD_INFO.json deployment marker
draft-store.mjs in-memory Map store (FIFO-bounded)
smoke.mjs headless-Chromium smoke suite against a served dist/ (npm run smoke)
live-smoke.mjs same suite against the deployed Pages site (npm run smoke:live); used by the post-deploy verification in build.yml and the daily health workflow
stubs/ build-time stand-ins for @sap/cds, fs, path, crypto
dev-server.mjs dependency-free static server for local testing

input/, generated/ and dist/ are build state (gitignored) — the repo holds only the tooling; the built site itself lives in cap2UI5/web-cap2UI5-build (its main branch, one commit per deployment) and is served from there via GitHub Pages.

Three build details worth knowing:

  • keepNames: true is load-bearing. Draft serialization keys on oApp.constructor.name; without it, minification renames classes and drafts cannot be restored.
  • Samples that Node loads but esbuild's stricter scope analysis rejects (e.g. assignment to a const) are excluded from the registry automatically and reported in the build log — and in BUILD_INFO.json, next to the class count and the OpenUI5 version the bootstrap resolved to.
  • A registry below 50 classes fails the build. The class walk returns an empty list for a directory that is not there, so a samples folder renamed upstream would otherwise deploy a green, sample-less playground.

Limitations

  • Demo/playground artifact. cap2UI5's security benefit — the view is built in the backend — obviously disappears when the backend ships to the client. Use it for live samples, docs, zero-install demos; not as a production topology.
  • Drafts live in the tab. Reload = fresh session (matching the session-scoped draft design). Back-navigation depth is bounded by the store's FIFO limit.
  • Server-only features are off. The Northwind external-service sample needs a CORS-reachable endpoint; anything relying on CAP services, destinations or real persistence won't work.
  • UI5 comes from the CDN (same as the CAP-served app) — the page needs internet access even though the backend doesn't.

About

Running cap2UI5 in Browser [ai-generated]

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages