@mcp-abap-adt/connection 6.0.1 → 8.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 +157 -1
- package/COPYING +674 -0
- package/LICENSE +165 -21
- package/README.md +22 -1
- package/dist/connection/AbstractAbapConnection.d.ts +58 -25
- package/dist/connection/AbstractAbapConnection.d.ts.map +1 -1
- package/dist/connection/AbstractAbapConnection.js +119 -5
- 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/utils/networkErrors.d.ts +2 -0
- package/dist/utils/networkErrors.d.ts.map +1 -0
- package/dist/utils/networkErrors.js +25 -0
- package/docs/MIGRATION-6.0.md +1 -1
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,159 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [8.0.0] - 2026-09-08
|
|
11
|
+
|
|
12
|
+
**A consumer holding the contract can now do what the connection could always do.**
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **BREAKING: onto `@mcp-abap-adt/interfaces@^39.0.0`**, from `^21.0.0`.
|
|
17
|
+
Seventeen majors, and the whole of it was eight compiler errors in one file.
|
|
18
|
+
|
|
19
|
+
- `makeAdtRequest` returns `IAdtWireResponse<T, D>`, not `IAdtResponse<T, D>`.
|
|
20
|
+
The two parted company when `IAdtResponse` became the result-or-failure
|
|
21
|
+
union a *member* answers, with `E extends IAdtError`; a connection answers
|
|
22
|
+
the raw HTTP shape, which is what `IAdtWireResponse` is. Six occurrences,
|
|
23
|
+
all of them the same rename — no behaviour moved.
|
|
24
|
+
- `isNetworkError` is this package's own again, in `src/utils/networkErrors.ts`.
|
|
25
|
+
`@mcp-abap-adt/interfaces` published it until 29.0.0, when that package
|
|
26
|
+
stopped emitting code: it holds types, interfaces and constants, and a
|
|
27
|
+
predicate is none of those. `NETWORK_ERROR_CODES` is still imported from
|
|
28
|
+
there — the codes are a constant, the judgement is not.
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **`flushGoodbye(timeoutMs?)`** — waits for the goodbye `disconnect()`
|
|
33
|
+
dispatched, within a budget.
|
|
34
|
+
|
|
35
|
+
`disconnect()` sends the logoff and does not await it, deliberately: a goodbye
|
|
36
|
+
carries no request timeout, and a server that never answers must not hold a
|
|
37
|
+
teardown open. That is right for a teardown and wrong for a reconnect —
|
|
38
|
+
`disconnect()` then `connect()` opens the next session while the previous
|
|
39
|
+
one's goodbye is still being assembled, and the server keeps both.
|
|
40
|
+
|
|
41
|
+
Measured on E19 through `@mcp-abap-adt/adt-clients`, whose harness recycled
|
|
42
|
+
the session after each test: a new ABAP session every one to two seconds for a
|
|
43
|
+
whole run, none released, each living to its own thirty-minute idle timeout.
|
|
44
|
+
|
|
45
|
+
The budget bounds the waiting, not the overlap: finishes in time and there is
|
|
46
|
+
none, does not and the caller proceeds while the goodbye stays outstanding.
|
|
47
|
+
|
|
48
|
+
- **The connection declares the atoms it honours**: `ICriticalSection`,
|
|
49
|
+
`IRequestProfiling` and — through 39.0.0's addition to
|
|
50
|
+
`ISessionLifecycleAware` — `flushGoodbye`.
|
|
51
|
+
|
|
52
|
+
All four methods already existed here. What changed is that a consumer can
|
|
53
|
+
reach them: `AbapConnection` is `IAbapConnection`, so until now
|
|
54
|
+
`beginCriticalSection()`, `setProfilingRequest()` and `flushGoodbye()` were
|
|
55
|
+
reachable only by casting to the concrete class, which is the thing the
|
|
56
|
+
contracts package exists to make unnecessary.
|
|
57
|
+
|
|
58
|
+
A test narrows a connection to each atom from the base contract and calls
|
|
59
|
+
through it. Worth saying what that does and does not check: TypeScript is
|
|
60
|
+
structural, so removing an atom from the `implements` list changes nothing —
|
|
61
|
+
the class still has the methods. What the clause buys is the compiler
|
|
62
|
+
checking the class against the contract: removing `beginCriticalSection`
|
|
63
|
+
itself is `TS2420`, which is the failure worth having.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## [7.0.0] - 2026-09-08
|
|
67
|
+
|
|
68
|
+
**Headers that belong to the request stop belonging to the session.**
|
|
69
|
+
|
|
70
|
+
Nothing in the type surface changed: no signature narrowed, `IAbapConnection` is
|
|
71
|
+
untouched, and code built against 6.x compiles unchanged. The major is for the
|
|
72
|
+
wire — every request now looks different in an SAP trace, and on cloud it says
|
|
73
|
+
something about the session it did not say before. A system that reacts badly to
|
|
74
|
+
either should be findable by version rather than by reading a trace.
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- **BREAKING: `sap-adt-request-id` goes out on every request**, not only inside
|
|
79
|
+
the stateful branch, and `X-sap-adt-profiling` comes from a settable default
|
|
80
|
+
rather than a literal.
|
|
81
|
+
|
|
82
|
+
Only `x-sap-adt-sessiontype` ever belonged in that branch. A request id
|
|
83
|
+
identifies the **request**, and asking the server to report its own processing
|
|
84
|
+
time is not a property of the session either. It stayed invisible while every
|
|
85
|
+
write happened inside a lock window — the window was stateful, so the writes
|
|
86
|
+
carried all three — and `@mcp-abap-adt/adt-clients` has since narrowed
|
|
87
|
+
stateful to the `LOCK` and the `UNLOCK`, at which point the writes silently
|
|
88
|
+
lost two headers.
|
|
89
|
+
|
|
90
|
+
Eclipse sends both on everything. From an ADT 3.60.0 trace on E19, a stateless
|
|
91
|
+
source `PUT` carries `sap-adt-request-id` and `X-sap-adt-profiling` and no
|
|
92
|
+
session type at all. Measured on a BTP trial after the narrowing: of 792
|
|
93
|
+
requests in a full run, 99 carried a request id and **693 — 87.5% — carried
|
|
94
|
+
neither**.
|
|
95
|
+
|
|
96
|
+
Both are **defaults, not overrides**: a caller who names either in
|
|
97
|
+
`options.headers` keeps it, matched without case. `adt-clients` passes its own
|
|
98
|
+
id to `getDiscovery({ requestId })` so the id it logs is the id on the wire,
|
|
99
|
+
and a profiler run asks for something other than `server-time`.
|
|
100
|
+
|
|
101
|
+
- **BREAKING (cloud): `x-sap-security-session: use` on every request**, once a
|
|
102
|
+
session exists.
|
|
103
|
+
|
|
104
|
+
ABAP Cloud issues its session as a resource asked for at
|
|
105
|
+
`/sap/bc/adt/core/http/sessions`, and this wire said the header exactly twice
|
|
106
|
+
in a session's life — `create` to open one, `use` on the `DELETE` that ends
|
|
107
|
+
it. Eclipse names it on everything in between. Measured from ADT 3.60.3
|
|
108
|
+
against a BTP trial: a plain `GET …/businessservices/odatav4/ZAC_SRVB01` and a
|
|
109
|
+
`POST …/unpublishjobs`, a read and a write, both stateless, both saying `use`
|
|
110
|
+
beside `saplb: appserver-dgm9s` and `saplb-options: REDISPATCH_ON_SHUTDOWN`.
|
|
111
|
+
|
|
112
|
+
That pair works together on a load-balanced landscape: here is the server, and
|
|
113
|
+
use the session that lives on it. In one full run against the same trial the
|
|
114
|
+
responses named two different application servers — `appserver-dgm9s` 501
|
|
115
|
+
times and `appserver-8q4vl` 290 — so which one answers is not a constant, and
|
|
116
|
+
the session is not on both.
|
|
117
|
+
|
|
118
|
+
**On-prem is deliberately unchanged**: its session arrives with the logon,
|
|
119
|
+
there is no trace of Eclipse sending this there, and adding it would be a
|
|
120
|
+
guess wearing a measurement's clothes.
|
|
121
|
+
|
|
122
|
+
### Added
|
|
123
|
+
|
|
124
|
+
- `setProfilingRequest(what: string | null)` / `getProfilingRequest()` — the
|
|
125
|
+
connection-wide `X-sap-adt-profiling` default, `null` to ask nothing.
|
|
126
|
+
`'server-time'` is what Eclipse asks for and stays the default. Nothing in
|
|
127
|
+
this package reads the answer back, which is an argument for being able to
|
|
128
|
+
turn it off rather than for switching it off: an investigation does read it,
|
|
129
|
+
and one settled this week that the unit is microseconds — a trial's unpublish
|
|
130
|
+
job answered `server-time=132512547` on a request that takes ~133 s.
|
|
131
|
+
|
|
132
|
+
**On the concrete class, not yet on the contract.** `AbapConnection` is
|
|
133
|
+
`IAbapConnection`, so a consumer holding the contract reaches these only by
|
|
134
|
+
casting. `@mcp-abap-adt/interfaces@38.1.0` publishes `IRequestProfiling`
|
|
135
|
+
(and `ICriticalSection`, for the section this package already has) as
|
|
136
|
+
capability atoms for exactly this — but this package is on `^21.0.0`, and
|
|
137
|
+
declaring them means moving seventeen majors, which is its own piece of work
|
|
138
|
+
and not this one. Until then the per-request route is the contract-level one:
|
|
139
|
+
`X-sap-adt-profiling` in `options.headers` is honoured and never overwritten.
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
## [6.1.0] - 2026-09-03
|
|
143
|
+
|
|
144
|
+
### Licence
|
|
145
|
+
|
|
146
|
+
- **This package is now `LGPL-3.0-only`.** It was MIT up to and including 6.0.1, and
|
|
147
|
+
those versions stay MIT — a licence change is not retroactive, and anyone
|
|
148
|
+
already using 6.0.1 under MIT keeps that grant for 6.0.1.
|
|
149
|
+
|
|
150
|
+
The library licence of the GNU family, chosen for what it does *not* ask:
|
|
151
|
+
linking it into your own program — importing it, as every consumer of an npm
|
|
152
|
+
package does — does not put your program under the LGPL. What it asks is that
|
|
153
|
+
changes to this library stay free and that your users can substitute their own
|
|
154
|
+
build of it.
|
|
155
|
+
|
|
156
|
+
Both texts ship in the package: `LICENSE` is the LGPL, `COPYING` is the GPL it
|
|
157
|
+
is written on top of. The LGPL is a set of additional permissions over the GPL,
|
|
158
|
+
so it cannot be read without both.
|
|
159
|
+
|
|
160
|
+
Copyright © 2025–2026 Oleksii Kyslytsia.
|
|
161
|
+
|
|
162
|
+
|
|
10
163
|
## [6.0.1] - 2026-08-25
|
|
11
164
|
|
|
12
165
|
### Removed
|
|
@@ -1360,8 +1513,11 @@ const connection = createAbapConnection(config, logger);
|
|
|
1360
1513
|
- JWT token refresh now properly handles connection errors (401/403 during initial connect)
|
|
1361
1514
|
- Permission errors (403 with "ExceptionResourceNoAccess") no longer trigger JWT refresh loops
|
|
1362
1515
|
- Proper separation: base class handles HTTP/session, concrete classes handle auth-specific errors
|
|
1363
|
-
[Unreleased]: https://github.com/fr0ster/mcp-abap-connection/compare/
|
|
1516
|
+
[Unreleased]: https://github.com/fr0ster/mcp-abap-connection/compare/v8.0.0...HEAD
|
|
1517
|
+
[8.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v7.0.0...v8.0.0
|
|
1518
|
+
[7.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v6.1.0...v7.0.0
|
|
1364
1519
|
[6.0.1]: https://github.com/fr0ster/mcp-abap-connection/compare/v6.0.0...v6.0.1
|
|
1520
|
+
[6.1.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v6.0.1...v6.1.0
|
|
1365
1521
|
[6.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v5.0.0...v6.0.0
|
|
1366
1522
|
[5.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v4.0.0...v5.0.0
|
|
1367
1523
|
[4.0.0]: https://github.com/fr0ster/mcp-abap-connection/compare/v3.0.0...v4.0.0
|