From db1ee119ec0bbc52e5fa6b1758415d6cc8c32739 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 20:52:51 +0000 Subject: [PATCH] Write the translator as npx --no-install cap2ui5 abap2js The unscoped npm name cap2ui5 was withdrawn and can be published by anyone. Where the plugin is not installed, a bare `npx cap2ui5 abap2js` downloads and runs whatever npm has under that name. With --no-install, npx runs the project's own @cap2ui5/cds-plugin bin or fails. - Every bare `npx cap2ui5` on the site now reads `npx --no-install cap2ui5`. - The migration page's heading is now "Translate it: `cap2ui5 abap2js`", matching the plugin README. Its anchor and the README anchor it links to changed with it, and the internal links point to the new anchor. - The migration page now installs @abaplint/core before the command and says the command needs @cap2ui5/cds-plugin installed. - AGENTS.md now has this as a rule. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017qE7GHShC7hMeY88tFr3wj --- AGENTS.md | 17 +++++++++++++---- docs/guide/ecosystem.md | 2 +- docs/guide/getting-started.md | 4 ++-- docs/guide/migration-from-abap2ui5.md | 12 +++++++++--- docs/guide/roadmap.md | 10 +++++----- docs/guide/views.md | 4 ++-- docs/guide/vs-abap2ui5.md | 6 +++--- docs/guide/where-it-comes-from.md | 4 ++-- docs/reference/architecture.md | 2 +- 9 files changed, 38 insertions(+), 23 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1f4a93d..4076853 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,8 +68,9 @@ On npm since 2026-09-29: `@cap2ui5/cds-plugin@0.3.1` (Node ≥ 22, peer (on npm since 2026-09-27) **exactly**. Up to 0.2.0 the plugin was the unscoped package `cap2ui5`; it is withdrawn from npm (0.2.0 never reached it), so the site names it only as the old name. What did NOT change name: the -configuration `cds.requires.cap2ui5`, `cds add cap2ui5`, the bin -`npx cap2ui5 abap2js`, the entity `cap2ui5.Drafts` and the logger `cap2ui5`. The runtime package was renamed from +configuration `cds.requires.cap2ui5`, `cds add cap2ui5`, the bin `cap2ui5` +(`npx --no-install cap2ui5 abap2js`), the entity `cap2ui5.Drafts` and the +logger `cap2ui5`. The runtime package was renamed from `@abap2ui5/runtime` before its first publish — the old name never existed on npm, and on the site it appears only in prose that says it is the old name. @@ -97,8 +98,8 @@ Path conventions inside cap2UI5: startup lines naming each app's address), `index.cds` (the `cap2ui5.Drafts` entity), `index.js` (what `import`/`require` of `@cap2ui5/cds-plugin` returns), `index.d.ts` (its TypeScript declarations), `bin/cap2ui5.js` - (`npx cap2ui5 abap2js`) and `lib/` (`abap2js.js`, `add.js`, `config.js`, - `define-app.js`, `define-exit.js`, `draft-store.js`, `hints.js`, + (`npx --no-install cap2ui5 abap2js`) and `lib/` (`abap2js.js`, `add.js`, + `config.js`, `define-app.js`, `define-exit.js`, `draft-store.js`, `hints.js`, `runtime.js`, `view-builder.js`) - `examples/bookshop/` — a CAP project using it, with the test suite. Its apps are in `examples/bookshop/srv/apps/` @@ -138,5 +139,13 @@ against the cap2UI5 repository. the user exit is discovered by a class-repository lookup in ABAP and had to be given a host-side registration (`defineExit`) instead. Boot the runtime and check rather than porting a claim from abap2UI5's documentation. +- Write the translator as `npx --no-install cap2ui5 abap2js`, never a bare + `npx cap2ui5`. The unscoped npm name `cap2ui5` was withdrawn and is + anybody's now; a bare `npx cap2ui5` where the plugin is not installed + downloads and runs whatever npm has under it. `--no-install` runs the + project's own `@cap2ui5/cds-plugin` bin or fails. A page that shows the + command says it needs the plugin installed. Left as they are: `cds add + cap2ui5`, a bare `cap2ui5 abap2js …` in a `package.json` script, and + `npx -p @cap2ui5/cds-plugin cap2ui5 …`. - Run `npm run check` before committing — verify-refs catches stale references, the VitePress build catches dead links. diff --git a/docs/guide/ecosystem.md b/docs/guide/ecosystem.md index f401279..8d99703 100644 --- a/docs/guide/ecosystem.md +++ b/docs/guide/ecosystem.md @@ -9,7 +9,7 @@ owns what saves time when something breaks. |---|---| | [**abap2UI5/abap2UI5**](https://github.com/abap2UI5/abap2UI5) | the framework itself: the ABAP sources and the UI5 shell. Everything cap2UI5 runs comes from here | | [**cap2UI5/cap2UI5**](https://github.com/cap2UI5/cap2UI5) | the plugin. `plugin/` is the npm package `@cap2ui5/cds-plugin`; `examples/bookshop` is a CAP project using it; `runtime/` is a stand-in for `@abap2ui5/node-runtime` that the repository's own tests build from upstream | -| [**cap2UI5/samples**](https://github.com/cap2UI5/samples) | abap2UI5's samples as cap2UI5 apps, each translated from its ABAP original by `npx cap2ui5 abap2js` — the npm package `@cap2ui5/samples` | +| [**cap2UI5/samples**](https://github.com/cap2UI5/samples) | abap2UI5's samples as cap2UI5 apps, each translated from its ABAP original by `npx --no-install cap2ui5 abap2js` — the npm package `@cap2ui5/samples` | | [**cap2UI5/docs**](https://github.com/cap2UI5/docs) | this site | The decisions that led to the current design are in the plugin repository, diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md index 5e0c182..3c47ac0 100644 --- a/docs/guide/getting-started.md +++ b/docs/guide/getting-started.md @@ -81,8 +81,8 @@ npm rm cap2ui5 && npm add @cap2ui5/cds-plugin and its app modules import `@cap2ui5/cds-plugin` instead of `cap2ui5`. Everything else keeps its name: the configuration `cds.requires.cap2ui5`, -`cds add cap2ui5`, `npx cap2ui5 abap2js`, the entity `cap2ui5.Drafts` and the -log `[cap2ui5]`. +`cds add cap2ui5`, `npx --no-install cap2ui5 abap2js`, the entity +`cap2ui5.Drafts` and the log `[cap2ui5]`. ::: ## 2. Your first app diff --git a/docs/guide/migration-from-abap2ui5.md b/docs/guide/migration-from-abap2ui5.md index 84c541f..293679d 100644 --- a/docs/guide/migration-from-abap2ui5.md +++ b/docs/guide/migration-from-abap2ui5.md @@ -128,15 +128,21 @@ in ABAP: `check_on_init()` is this instance's first roundtrip only, and | data access | Open SQL | `cds.ql` — and CAP's remote services | | deployment | abapGit into a system | `npm i` into a CAP project | -## Translate it: `npx cap2ui5 abap2js` +## Translate it: `cap2ui5 abap2js` Because the client and the view builder are abap2UI5's own, an app class translates line for line — and the plugin does it: ```bash -npx cap2ui5 abap2js src/zcl_my_app.clas.abap --out srv/apps +npm add -D @abaplint/core # once: the ABAP parser it reads with +npx --no-install cap2ui5 abap2js src/zcl_my_app.clas.abap --out srv/apps ``` +It needs `@cap2ui5/cds-plugin` installed in the project: `--no-install` makes +npx run the `cap2ui5` of the project's `@cap2ui5/cds-plugin` or fail — never +download one. In a `package.json` script the command is +`cap2ui5 abap2js …`, which runs the installed one as well. + `zcl_my_app.clas.abap` becomes `srv/apps/zcl_my_app.js`, registered as `ZCL_MY_APP`, so `?app_start=` is the same on both sides. A view chain keeps one call per line, `VALUE #( )` one row per line, and comments and texts come @@ -155,7 +161,7 @@ refused: z2ui5_cl_x.clas.abap:41:7 - LOOP AT ... ASSIGNING / REFERENCE INTO writ What it refuses is typically your business logic — Open SQL to `cds.ql`, a field-symbol, a `sy-` field — and that part you are better placed to translate. The options and the details of the translation are in the -plugin's [README](https://github.com/cap2UI5/cap2UI5/tree/main/plugin#an-abap-app-translated-npx-cap2ui5-abap2js). +plugin's [README](https://github.com/cap2UI5/cap2UI5/tree/main/plugin#an-abap-app-translated-cap2ui5-abap2js). How far "line for line" goes is measured, not claimed: the [`@cap2ui5/samples`](https://github.com/cap2UI5/samples) package is 71 of diff --git a/docs/guide/roadmap.md b/docs/guide/roadmap.md index 316e72b..81edb73 100644 --- a/docs/guide/roadmap.md +++ b/docs/guide/roadmap.md @@ -19,8 +19,8 @@ measurements are in [Where cap2UI5 Comes From](./where-it-comes-from). Since then the JavaScript side closed its own gaps. 0.2.0 made the client an app receives abap2UI5's `z2ui5_if_client`, every method under its ABAP name, exported `z2ui5_cl_ui5_view_builder` and shipped TypeScript declarations; -0.3.0 added `npx cap2ui5 abap2js`, which translates an abap2UI5 app class -into a cap2UI5 app line for line, and apps that come from a package — +0.3.0 added `npx --no-install cap2ui5 abap2js`, which translates an abap2UI5 +app class into a cap2UI5 app line for line, and apps that come from a package — [`@cap2ui5/samples`](https://github.com/cap2UI5/samples) is 71 of abap2UI5's samples that way. The details are in the plugin's [CHANGELOG](https://github.com/cap2UI5/cap2UI5/blob/main/plugin/CHANGELOG.md). @@ -49,9 +49,9 @@ unannotated app. ### `abap2js` translates part of ABAP -`npx cap2ui5 abap2js` knows the ABAP an abap2UI5 app is written in and -refuses the rest — a field-symbol, `SELECT`, a `sy-` field — with file, row -and column. What it refuses you translate by hand. Of abap2UI5's 129 +`npx --no-install cap2ui5 abap2js` knows the ABAP an abap2UI5 app is written +in and refuses the rest — a field-symbol, `SELECT`, a `sy-` field — with file, +row and column. What it refuses you translate by hand. Of abap2UI5's 129 samples, it translates 69 today. ### UI5 comes from the CDN, and only from the CDN diff --git a/docs/guide/views.md b/docs/guide/views.md index 9a26697..649b724 100644 --- a/docs/guide/views.md +++ b/docs/guide/views.md @@ -139,7 +139,7 @@ JavaScript name. Template literal or builder is a matter of taste in a new app. The builder is what an app ported from ABAP already has — and what -[`npx cap2ui5 abap2js`](./migration-from-abap2ui5#translate-it-npx-cap2ui5-abap2js) +[`npx --no-install cap2ui5 abap2js`](./migration-from-abap2ui5#translate-it-cap2ui5-abap2js) writes. ## The ABAP view builder @@ -147,7 +147,7 @@ writes. An app can also stay in ABAP: a `z2ui5_if_app` class, transpiled against the runtime the plugin hosts, runs beside the JavaScript apps. That is the route for a class you would rather not translate — the -[translation](./migration-from-abap2ui5#translate-it-npx-cap2ui5-abap2js) is +[translation](./migration-from-abap2ui5#translate-it-cap2ui5-abap2js) is the other one. ### An app in ABAP diff --git a/docs/guide/vs-abap2ui5.md b/docs/guide/vs-abap2ui5.md index 717ce37..5c042bc 100644 --- a/docs/guide/vs-abap2ui5.md +++ b/docs/guide/vs-abap2ui5.md @@ -78,9 +78,9 @@ Line for line. The languages part company in two places: ABAP names its arguments where JavaScript passes one object with the same names, and `_bind( name )` becomes `client._bind("name")` because JavaScript cannot match a value by reference. That is close enough for a machine to do it: -`npx cap2ui5 abap2js` translates an abap2UI5 app class into a cap2UI5 app, -line for line, and refuses what it does not know rather than guess — see -[Migrating from abap2UI5](./migration-from-abap2ui5#translate-it-npx-cap2ui5-abap2js). +`npx --no-install cap2ui5 abap2js` translates an abap2UI5 app class into a +cap2UI5 app, line for line, and refuses what it does not know rather than guess — see +[Migrating from abap2UI5](./migration-from-abap2ui5#translate-it-cap2ui5-abap2js). [`@cap2ui5/samples`](https://github.com/cap2UI5/samples) is 71 of abap2UI5's samples as cap2UI5 apps, 69 of them translated that way. diff --git a/docs/guide/where-it-comes-from.md b/docs/guide/where-it-comes-from.md index 96d2495..a31d00f 100644 --- a/docs/guide/where-it-comes-from.md +++ b/docs/guide/where-it-comes-from.md @@ -101,8 +101,8 @@ identifiers are ABAP's. The plugin keeps them: the client an app's `client->check_on_navigated( )` is `client.check_on_navigated()` — and the view builder is `z2ui5_cl_ui5_view_builder`. Every abap2UI5 sample and document therefore maps onto what you are doing, and an ABAP app ports line -by line; `npx cap2ui5 abap2js` does the porting (see -[Migrating from abap2UI5](./migration-from-abap2ui5#translate-it-npx-cap2ui5-abap2js)). +by line; `npx --no-install cap2ui5 abap2js` does the porting (see +[Migrating from abap2UI5](./migration-from-abap2ui5#translate-it-cap2ui5-abap2js)). ## Next diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index d0d1857..4ae7876 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -24,7 +24,7 @@ project used to be — see [Where cap2UI5 Comes From](../guide/where-it-comes-fr │ ├── view-builder.js records a view builder chain for upstream's class │ ├── draft-store.js the draft store, over a CDS entity │ ├── runtime.js locate and boot the runtime - │ └── abap2js.js npx cap2ui5 abap2js + │ └── abap2js.js npx --no-install cap2ui5 abap2js └── @abap2ui5/node-runtime abap2UI5 itself, one exact release ├── output/ upstream's ABAP, downported + transpiled — │ the GET page embeds the UI5 frontend, from