@mcp-abap-adt/connection 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +209 -1
- package/COPYING +674 -0
- package/LICENSE +165 -21
- package/README.md +22 -1
- package/bin/sap-abap-auth.js +101 -13
- package/dist/connection/AbstractAbapConnection.d.ts +24 -22
- package/dist/connection/AbstractAbapConnection.d.ts.map +1 -1
- package/dist/connection/AbstractAbapConnection.js +65 -3
- package/dist/connection/CloudHttpTransport.d.ts +19 -0
- package/dist/connection/CloudHttpTransport.d.ts.map +1 -1
- package/dist/connection/CloudHttpTransport.js +21 -0
- package/dist/connection/HttpTransport.d.ts +9 -0
- package/dist/connection/HttpTransport.d.ts.map +1 -1
- package/dist/connection/HttpTransport.js +12 -0
- package/dist/connection/RfcTransport.d.ts.map +1 -1
- package/dist/connection/RfcTransport.js +14 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,216 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [7.0.0] - 2026-09-08
|
|
11
|
+
|
|
12
|
+
**Headers that belong to the request stop belonging to the session.**
|
|
13
|
+
|
|
14
|
+
Nothing in the type surface changed: no signature narrowed, `IAbapConnection` is
|
|
15
|
+
untouched, and code built against 6.x compiles unchanged. The major is for the
|
|
16
|
+
wire — every request now looks different in an SAP trace, and on cloud it says
|
|
17
|
+
something about the session it did not say before. A system that reacts badly to
|
|
18
|
+
either should be findable by version rather than by reading a trace.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- **BREAKING: `sap-adt-request-id` goes out on every request**, not only inside
|
|
23
|
+
the stateful branch, and `X-sap-adt-profiling` comes from a settable default
|
|
24
|
+
rather than a literal.
|
|
25
|
+
|
|
26
|
+
Only `x-sap-adt-sessiontype` ever belonged in that branch. A request id
|
|
27
|
+
identifies the **request**, and asking the server to report its own processing
|
|
28
|
+
time is not a property of the session either. It stayed invisible while every
|
|
29
|
+
write happened inside a lock window — the window was stateful, so the writes
|
|
30
|
+
carried all three — and `@mcp-abap-adt/adt-clients` has since narrowed
|
|
31
|
+
stateful to the `LOCK` and the `UNLOCK`, at which point the writes silently
|
|
32
|
+
lost two headers.
|
|
33
|
+
|
|
34
|
+
Eclipse sends both on everything. From an ADT 3.60.0 trace on E19, a stateless
|
|
35
|
+
source `PUT` carries `sap-adt-request-id` and `X-sap-adt-profiling` and no
|
|
36
|
+
session type at all. Measured on a BTP trial after the narrowing: of 792
|
|
37
|
+
requests in a full run, 99 carried a request id and **693 — 87.5% — carried
|
|
38
|
+
neither**.
|
|
39
|
+
|
|
40
|
+
Both are **defaults, not overrides**: a caller who names either in
|
|
41
|
+
`options.headers` keeps it, matched without case. `adt-clients` passes its own
|
|
42
|
+
id to `getDiscovery({ requestId })` so the id it logs is the id on the wire,
|
|
43
|
+
and a profiler run asks for something other than `server-time`.
|
|
44
|
+
|
|
45
|
+
- **BREAKING (cloud): `x-sap-security-session: use` on every request**, once a
|
|
46
|
+
session exists.
|
|
47
|
+
|
|
48
|
+
ABAP Cloud issues its session as a resource asked for at
|
|
49
|
+
`/sap/bc/adt/core/http/sessions`, and this wire said the header exactly twice
|
|
50
|
+
in a session's life — `create` to open one, `use` on the `DELETE` that ends
|
|
51
|
+
it. Eclipse names it on everything in between. Measured from ADT 3.60.3
|
|
52
|
+
against a BTP trial: a plain `GET …/businessservices/odatav4/ZAC_SRVB01` and a
|
|
53
|
+
`POST …/unpublishjobs`, a read and a write, both stateless, both saying `use`
|
|
54
|
+
beside `saplb: appserver-dgm9s` and `saplb-options: REDISPATCH_ON_SHUTDOWN`.
|
|
55
|
+
|
|
56
|
+
That pair works together on a load-balanced landscape: here is the server, and
|
|
57
|
+
use the session that lives on it. In one full run against the same trial the
|
|
58
|
+
responses named two different application servers — `appserver-dgm9s` 501
|
|
59
|
+
times and `appserver-8q4vl` 290 — so which one answers is not a constant, and
|
|
60
|
+
the session is not on both.
|
|
61
|
+
|
|
62
|
+
**On-prem is deliberately unchanged**: its session arrives with the logon,
|
|
63
|
+
there is no trace of Eclipse sending this there, and adding it would be a
|
|
64
|
+
guess wearing a measurement's clothes.
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- `setProfilingRequest(what: string | null)` / `getProfilingRequest()` — the
|
|
69
|
+
connection-wide `X-sap-adt-profiling` default, `null` to ask nothing.
|
|
70
|
+
`'server-time'` is what Eclipse asks for and stays the default. Nothing in
|
|
71
|
+
this package reads the answer back, which is an argument for being able to
|
|
72
|
+
turn it off rather than for switching it off: an investigation does read it,
|
|
73
|
+
and one settled this week that the unit is microseconds — a trial's unpublish
|
|
74
|
+
job answered `server-time=132512547` on a request that takes ~133 s.
|
|
75
|
+
|
|
76
|
+
**On the concrete class, not yet on the contract.** `AbapConnection` is
|
|
77
|
+
`IAbapConnection`, so a consumer holding the contract reaches these only by
|
|
78
|
+
casting. `@mcp-abap-adt/interfaces@38.1.0` publishes `IRequestProfiling`
|
|
79
|
+
(and `ICriticalSection`, for the section this package already has) as
|
|
80
|
+
capability atoms for exactly this — but this package is on `^21.0.0`, and
|
|
81
|
+
declaring them means moving seventeen majors, which is its own piece of work
|
|
82
|
+
and not this one. Until then the per-request route is the contract-level one:
|
|
83
|
+
`X-sap-adt-profiling` in `options.headers` is honoured and never overwritten.
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
## [6.1.0] - 2026-09-03
|
|
87
|
+
|
|
88
|
+
### Licence
|
|
89
|
+
|
|
90
|
+
- **This package is now `LGPL-3.0-only`.** It was MIT up to and including 6.0.1, and
|
|
91
|
+
those versions stay MIT — a licence change is not retroactive, and anyone
|
|
92
|
+
already using 6.0.1 under MIT keeps that grant for 6.0.1.
|
|
93
|
+
|
|
94
|
+
The library licence of the GNU family, chosen for what it does *not* ask:
|
|
95
|
+
linking it into your own program — importing it, as every consumer of an npm
|
|
96
|
+
package does — does not put your program under the LGPL. What it asks is that
|
|
97
|
+
changes to this library stay free and that your users can substitute their own
|
|
98
|
+
build of it.
|
|
99
|
+
|
|
100
|
+
Both texts ship in the package: `LICENSE` is the LGPL, `COPYING` is the GPL it
|
|
101
|
+
is written on top of. The LGPL is a set of additional permissions over the GPL,
|
|
102
|
+
so it cannot be read without both.
|
|
103
|
+
|
|
104
|
+
Copyright © 2025–2026 Oleksii Kyslytsia.
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## [6.0.1] - 2026-08-25
|
|
108
|
+
|
|
109
|
+
### Removed
|
|
110
|
+
|
|
111
|
+
- **`express` is no longer a dependency.** It was a runtime dependency for one
|
|
112
|
+
thing: the localhost server in `bin/sap-abap-auth.js` that catches the OAuth2
|
|
113
|
+
redirect. The library never touched it, and that file already imported
|
|
114
|
+
`node:http`. Rewritten on `node:http`, which sheds 5.6MB of `node_modules` and
|
|
115
|
+
the transitive tree the Dependabot bumps kept arriving for — `qs`,
|
|
116
|
+
`body-parser` and `follow-redirects` were all express's.
|
|
117
|
+
|
|
118
|
+
Two things express was doing implicitly are now stated: a request is the
|
|
119
|
+
redirect only when it is a `GET` for `/callback`, so a browser fetching
|
|
120
|
+
`/favicon.ico` no longer reaches the handler waiting for an authorization
|
|
121
|
+
code; and the success page declares `text/html`, which `res.send()` used to
|
|
122
|
+
infer. Exercised as a server: `200` with the page, `400` without a code, `404`
|
|
123
|
+
for anything else including a `POST`.
|
|
124
|
+
|
|
125
|
+
Runtime dependencies are now `@mcp-abap-adt/interfaces`, `axios`, `commander`
|
|
126
|
+
and `open`. The end-to-end flow was measured against the BTP trial — see
|
|
127
|
+
*Verified* below.
|
|
128
|
+
|
|
129
|
+
### Changed
|
|
130
|
+
|
|
131
|
+
- **The browser wait is the caller's to set.** `bin/sap-abap-auth.js` waited a
|
|
132
|
+
fixed five minutes for the redirect, and a real BTP login does not fit in it —
|
|
133
|
+
the identity provider, a password manager and whatever second factor the
|
|
134
|
+
tenant asks for all happen before the redirect is issued. Measured twice, and
|
|
135
|
+
both times the window closed first; the browser then had nowhere to redirect
|
|
136
|
+
to, which reads as the authentication having failed rather than as a timeout.
|
|
137
|
+
|
|
138
|
+
`--timeout <minutes>`, or `SAP_AUTH_TIMEOUT_MS` for a script that would rather
|
|
139
|
+
not pass an argument, with the flag winning when both are given. Anything that
|
|
140
|
+
is not a positive number is refused by name rather than silently becoming a
|
|
141
|
+
default. **The default is now fifteen minutes**, which covered the login this
|
|
142
|
+
was measured against with room to spare and still bounds an abandoned run.
|
|
143
|
+
|
|
144
|
+
### Verified
|
|
145
|
+
|
|
146
|
+
- **The whole chain, end to end**: `bin/sap-abap-auth.js auth` → browser
|
|
147
|
+
authorization against the tenant's UAA → redirect to `localhost:3001/callback`
|
|
148
|
+
→ code exchanged for a token → `.env` written with `SAP_JWT_TOKEN`,
|
|
149
|
+
`SAP_REFRESH_TOKEN` and the UAA fields.
|
|
150
|
+
|
|
151
|
+
- Each seam the express removal touched, measured on the real handler rather
|
|
152
|
+
than a stand-in: `GET /favicon.ico` answers `404` and does not reach the
|
|
153
|
+
handler waiting for a code — routing express used to do; `GET /callback` with
|
|
154
|
+
no code answers `400`; the success page comes back
|
|
155
|
+
`200 text/html; charset=utf-8`, the Content-Type `res.send()` used to infer
|
|
156
|
+
and `node:http` will not.
|
|
157
|
+
|
|
158
|
+
- **The issued token then drove this library** against the trial:
|
|
159
|
+
`AdtCloudConnector` with `CloudHttpTransport` connected, took a session
|
|
160
|
+
(`SAP_SESSIONID_TRL_100`), answered a `GET /sap/bc/adt/discovery` with `200`
|
|
161
|
+
and 444826 bytes of XML, and `disconnect()` left `isConnected()` false.
|
|
162
|
+
|
|
163
|
+
### Fixed
|
|
164
|
+
|
|
165
|
+
- **The live RFC suite skips a wire the machine did not install.** It asked for
|
|
166
|
+
four environment variables and nothing else, so a checkout with an env file
|
|
167
|
+
and no SAP NW RFC SDK ran the suite anyway and went eleven tests red, all on
|
|
168
|
+
`@mcp-abap-adt/sap-rfc-lite is not available`. The dependency is `optional` —
|
|
169
|
+
`npm ci` leaves it out WITHOUT failing, which is what optional means — so
|
|
170
|
+
nothing warns and the next run is red for a reason unrelated to the change
|
|
171
|
+
under test.
|
|
172
|
+
|
|
173
|
+
Nothing here is configured at build time the way a C package is: the installed
|
|
174
|
+
optional dependency IS the choice of wire, made at install and readable only
|
|
175
|
+
at runtime. `canRun()` now reads it with `require.resolve`, asking whether the
|
|
176
|
+
wire could be taken rather than loading a native addon to find out. Measured
|
|
177
|
+
in both states: SDK hidden — 11 skipped, 2 passed, green; SDK present — 13
|
|
178
|
+
passed.
|
|
179
|
+
|
|
180
|
+
- `RfcTransport` says why it ignores `request.timeout`. No behaviour change: the
|
|
181
|
+
file contained no occurrence of the word, and that silence read as an
|
|
182
|
+
oversight. It is deliberate — the SDK exposes no cancel, its per-call
|
|
183
|
+
`timeout` is parsed into a commented-out branch, and an abandoned call still
|
|
184
|
+
holds the conversation, so the next one would queue behind a call nobody is
|
|
185
|
+
waiting for. A deadline that reports failure while the wire stays busy is
|
|
186
|
+
worse than none, because the error reads as "safe to retry" when it is not.
|
|
187
|
+
The server bounds the call at `rdisp/max_wprun_time`.
|
|
188
|
+
|
|
10
189
|
## [6.0.0] - 2026-08-24
|
|
11
190
|
|
|
12
191
|
The wire owns what is the wire's, and the factory and per-credential classes are
|
|
13
192
|
gone. See [Migration to 6.0](./docs/MIGRATION-6.0.md).
|
|
14
193
|
|
|
194
|
+
### Added — tooling
|
|
195
|
+
|
|
196
|
+
- **CI.** Until this release the only workflow ran on a tag, and `Release` went
|
|
197
|
+
from build straight to `npm pack` — so nothing ran the gate before a merge,
|
|
198
|
+
and the artifact a tag published had been tested nowhere but on a laptop.
|
|
199
|
+
`ci.yml` runs `lint:check`, `build`, `jest --no-cache`, `check:docs` and
|
|
200
|
+
`check:pack` on push and pull request, across ubuntu and windows on Node 18
|
|
201
|
+
and 20. Windows is in the matrix because npm is `npm.cmd` there and Node will
|
|
202
|
+
not execute a `.cmd` without a shell. `release.yml` runs the same three checks
|
|
203
|
+
between build and pack, so a tag is not a route around them.
|
|
204
|
+
|
|
205
|
+
- **`check:pack`** — inspects `npm pack --dry-run --json` and refuses a tarball
|
|
206
|
+
carrying a test file, a `.tsbuildinfo`, a `.ts` source, an env file or an
|
|
207
|
+
npmrc. Both defects it was written for had already shipped once:
|
|
208
|
+
`dist/__tests__/` and 120KB of compiler bookkeeping, neither visible from
|
|
209
|
+
`files`, because it is the compiler that decides what `dist` holds.
|
|
210
|
+
|
|
211
|
+
- **`typecheck:scripts`** — `scripts/*.ts` were checked by nothing, which is how
|
|
212
|
+
three live verification scripts came to sit on a constructor signature two
|
|
213
|
+
releases old.
|
|
214
|
+
|
|
215
|
+
### Changed — packaging
|
|
216
|
+
|
|
217
|
+
- 111 files / 182KB → 95 / 147KB. Test helpers and the compiler's incremental
|
|
218
|
+
state no longer ship.
|
|
219
|
+
|
|
15
220
|
### Added
|
|
16
221
|
|
|
17
222
|
- **The transport axis is complete and public.** `IAdtTransport` now covers
|
|
@@ -1252,7 +1457,10 @@ const connection = createAbapConnection(config, logger);
|
|
|
1252
1457
|
- JWT token refresh now properly handles connection errors (401/403 during initial connect)
|
|
1253
1458
|
- Permission errors (403 with "ExceptionResourceNoAccess") no longer trigger JWT refresh loops
|
|
1254
1459
|
- Proper separation: base class handles HTTP/session, concrete classes handle auth-specific errors
|
|
1255
|
-
[Unreleased]: https://github.com/fr0ster/mcp-abap-connection/compare/
|
|
1460
|
+
[Unreleased]: https://github.com/fr0ster/mcp-abap-connection/compare/v7.0.0...HEAD
|
|
1461
|
+
[7.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v6.1.0...v7.0.0
|
|
1462
|
+
[6.0.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v6.0.0...v6.0.1
|
|
1463
|
+
[6.1.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v6.0.1...v6.1.0
|
|
1256
1464
|
[6.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v5.0.0...v6.0.0
|
|
1257
1465
|
[5.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v4.0.0...v5.0.0
|
|
1258
1466
|
[4.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v3.0.0...v4.0.0
|