@mcp-abap-adt/adt-clients 34.2.1 → 35.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/README.md CHANGED
@@ -834,20 +834,28 @@ Some ADT endpoints return `406` when the `Accept` header does not match the
834
834
  system's supported media types. The client retries once with a type the `406`
835
835
  names, and remembers it for that endpoint.
836
836
 
837
- **It is on unless you turn it off** — per client, or for the process:
837
+ **It is off unless you turn it on** (since 35.0.0) — per client, or for the
838
+ process. Without a switch a `406` or `415` is the call's answer and nothing is
839
+ sent again:
838
840
 
839
841
  ```typescript
840
842
  import { AdtClient } from '@mcp-abap-adt/adt-clients';
841
843
 
842
844
  const client = new AdtClient(connection, console, {
843
- enableAcceptCorrection: false,
845
+ enableAcceptCorrection: true,
844
846
  });
845
847
  ```
846
848
 
847
849
  ```bash
848
- ADT_ACCEPT_CORRECTION=false npm test
850
+ ADT_ACCEPT_CORRECTION=true npm test
849
851
  ```
850
852
 
853
+ The variable turns it on only when it is exactly `true`. To correct requests
854
+ yourself instead, read a `406` with `extractSupportedAccept(error)` and keep
855
+ the result in the connection's cache with `rememberAccept(connection, request,
856
+ accept)`; `cachedAccept(connection, request)` reads it back, whatever the
857
+ switch says. See [batch](docs/usage/BATCH.md).
858
+
851
859
  **The state is the connection's** since 23.0.0: the remembered types and the
852
860
  switch live on the connection object. They used to be module globals, so a
853
861
  header learned on one system was sent to every other, and one client's switch
@@ -1021,6 +1029,7 @@ See [Architecture Documentation](docs/architecture/ARCHITECTURE.md#type-system-a
1021
1029
  One document per breaking release, each written for a consumer on the contract
1022
1030
  before it:
1023
1031
 
1032
+ - **[34.x → 35.0.0](docs/usage/MIGRATION-35.md)** — accept negotiation is off by default: a `406`/`415` is the call's answer unless you switch it on.
1024
1033
  - **[33.x → 34.0.0](docs/usage/MIGRATION-34.md)** — a batch corrects and resends nothing: a part's `406`/`415` is that call's answer.
1025
1034
  - **[32.x → 33.0.0](docs/usage/MIGRATION-33.md)** — a credential the provider refused before SAP was asked rejects with the connection's refusal as it came; a `401` SAP refused it with comes back carrying that response.
1026
1035
  - **[31.x → 32.0.0](docs/usage/MIGRATION-32.md)** — interfaces-adt 18, three enhancement subtypes, subtype-specific create fields, two new result slots for enhancement hosts, and `metadataUpdated` for enhancement document writes.
package/dist/index.d.ts CHANGED
@@ -26,5 +26,5 @@ export * from './index.executors';
26
26
  export * from './index.readings';
27
27
  export * from './index.runtime';
28
28
  export * from './index.ws';
29
- export { exemptFromAcceptNegotiation, getBaseRequest, } from './utils/acceptNegotiation';
29
+ export { cachedAccept, exemptFromAcceptNegotiation, extractSupportedAccept, getBaseRequest, rememberAccept, } from './utils/acceptNegotiation';
30
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxD,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,2BAA2B,EAC3B,cAAc,GACf,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxD,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,sBAAsB,EACtB,cAAc,EACd,cAAc,GACf,MAAM,2BAA2B,CAAC"}
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
34
34
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
35
35
  };
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.getBaseRequest = exports.exemptFromAcceptNegotiation = exports.CT_INCLUDE = exports.AdtInclude = exports.AdtBatchConnection = void 0;
37
+ exports.rememberAccept = exports.getBaseRequest = exports.extractSupportedAccept = exports.exemptFromAcceptNegotiation = exports.cachedAccept = exports.CT_INCLUDE = exports.AdtInclude = exports.AdtBatchConnection = void 0;
38
38
  var batch_1 = require("./batch");
39
39
  Object.defineProperty(exports, "AdtBatchConnection", { enumerable: true, get: function () { return batch_1.AdtBatchConnection; } });
40
40
  var include_1 = require("./core/include");
@@ -47,5 +47,8 @@ __exportStar(require("./index.readings"), exports);
47
47
  __exportStar(require("./index.runtime"), exports);
48
48
  __exportStar(require("./index.ws"), exports);
49
49
  var acceptNegotiation_1 = require("./utils/acceptNegotiation");
50
+ Object.defineProperty(exports, "cachedAccept", { enumerable: true, get: function () { return acceptNegotiation_1.cachedAccept; } });
50
51
  Object.defineProperty(exports, "exemptFromAcceptNegotiation", { enumerable: true, get: function () { return acceptNegotiation_1.exemptFromAcceptNegotiation; } });
52
+ Object.defineProperty(exports, "extractSupportedAccept", { enumerable: true, get: function () { return acceptNegotiation_1.extractSupportedAccept; } });
51
53
  Object.defineProperty(exports, "getBaseRequest", { enumerable: true, get: function () { return acceptNegotiation_1.getBaseRequest; } });
54
+ Object.defineProperty(exports, "rememberAccept", { enumerable: true, get: function () { return acceptNegotiation_1.rememberAccept; } });
@@ -17,10 +17,28 @@ export interface IAcceptNegotiationOptions {
17
17
  export declare function clearAcceptCache(connection: IAbapConnection): void;
18
18
  /** Switch correction on or off for this connection alone. */
19
19
  export declare function setAcceptCorrectionEnabled(connection: IAbapConnection, enabled?: boolean): void;
20
- /** This connection's switch, or the `ADT_ACCEPT_CORRECTION` default. */
20
+ /**
21
+ * This connection's switch, else the `ADT_ACCEPT_CORRECTION` default. Off
22
+ * unless explicitly on: the environment variable turns it on only when it is
23
+ * exactly `true`; unset, or any other value, leaves it off.
24
+ */
21
25
  export declare function getAcceptCorrectionEnabled(connection: IAbapConnection): boolean;
22
26
  export declare function extractSupportedAccept(error: unknown): string[];
23
27
  export declare function extractSupportedContentType(error: unknown): string[];
28
+ /**
29
+ * The Accept stored for `request`'s method and URL on this connection: what a
30
+ * `406` taught negotiation or `rememberAccept` stored, or `undefined` when
31
+ * there is none. A plain read of the per-connection cache, whatever the
32
+ * correction switch says, so a consumer that corrects requests itself can read
33
+ * it while negotiation is off.
34
+ */
35
+ export declare function cachedAccept(connection: IAbapConnection, request: IAbapRequestOptions): string | undefined;
36
+ /**
37
+ * Store a corrected Accept for `request`'s method and URL on this connection,
38
+ * as the negotiation's own `406` branch does: a later request through the
39
+ * connection's negotiation sends it. A plain write of the per-connection cache.
40
+ */
41
+ export declare function rememberAccept(connection: IAbapConnection, request: IAbapRequestOptions, accept: string): void;
24
42
  /**
25
43
  * The connection's request as it was before an `AdtClient` with correction on
26
44
  * wrapped it: accept negotiation corrects and resends nothing. The
@@ -1 +1 @@
1
- {"version":3,"file":"acceptNegotiation.d.ts","sourceRoot":"","sources":["../../src/utils/acceptNegotiation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAkD9D;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAM7E;AAaD,MAAM,WAAW,yBAAyB;IACxC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,2CAA2C;AAC3C,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAIlE;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,eAAe,EAC3B,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI,CAEN;AAED,wEAAwE;AACxE,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,eAAe,GAC1B,OAAO,CAIT;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAoC/D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAsCpE;AAMD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,GAC1B,eAAe,CAAC,gBAAgB,CAAC,CAInC;AAED,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,GACf,IAAI,CAkBN;AAED,wBAAsB,mCAAmC,CACvD,CAAC,GAAG,OAAO,EACX,CAAC,GAAG,OAAO,EAEX,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,mBAAmB,EAC5B,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAkFjC"}
1
+ {"version":3,"file":"acceptNegotiation.d.ts","sourceRoot":"","sources":["../../src/utils/acceptNegotiation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAkD9D;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAM7E;AAaD,MAAM,WAAW,yBAAyB;IACxC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,2CAA2C;AAC3C,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAIlE;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,eAAe,EAC3B,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,eAAe,GAC1B,OAAO,CAIT;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAoC/D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAsCpE;AAMD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,mBAAmB,GAC3B,MAAM,GAAG,SAAS,CAEpB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,MAAM,GACb,IAAI,CAEN;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,GAC1B,eAAe,CAAC,gBAAgB,CAAC,CAInC;AAED,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,GACf,IAAI,CAkBN;AAED,wBAAsB,mCAAmC,CACvD,CAAC,GAAG,OAAO,EACX,CAAC,GAAG,OAAO,EAEX,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,mBAAmB,EAC5B,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAkFjC"}
@@ -6,6 +6,8 @@ exports.setAcceptCorrectionEnabled = setAcceptCorrectionEnabled;
6
6
  exports.getAcceptCorrectionEnabled = getAcceptCorrectionEnabled;
7
7
  exports.extractSupportedAccept = extractSupportedAccept;
8
8
  exports.extractSupportedContentType = extractSupportedContentType;
9
+ exports.cachedAccept = cachedAccept;
10
+ exports.rememberAccept = rememberAccept;
9
11
  exports.getBaseRequest = getBaseRequest;
10
12
  exports.wrapConnectionAcceptNegotiation = wrapConnectionAcceptNegotiation;
11
13
  exports.makeAdtRequestWithAcceptNegotiation = makeAdtRequestWithAcceptNegotiation;
@@ -59,12 +61,16 @@ function clearAcceptCache(connection) {
59
61
  function setAcceptCorrectionEnabled(connection, enabled) {
60
62
  stateOf(connection).enabled = enabled;
61
63
  }
62
- /** This connection's switch, or the `ADT_ACCEPT_CORRECTION` default. */
64
+ /**
65
+ * This connection's switch, else the `ADT_ACCEPT_CORRECTION` default. Off
66
+ * unless explicitly on: the environment variable turns it on only when it is
67
+ * exactly `true`; unset, or any other value, leaves it off.
68
+ */
63
69
  function getAcceptCorrectionEnabled(connection) {
64
70
  const enabled = stateOf(connection).enabled;
65
71
  if (enabled !== undefined)
66
72
  return enabled;
67
- return process.env.ADT_ACCEPT_CORRECTION !== 'false';
73
+ return process.env.ADT_ACCEPT_CORRECTION === 'true';
68
74
  }
69
75
  function extractSupportedAccept(error) {
70
76
  const types = new Set();
@@ -134,6 +140,24 @@ function extractSupportedContentType(error) {
134
140
  function buildCacheKey(request) {
135
141
  return `${request.method.toUpperCase()} ${request.url}`;
136
142
  }
143
+ /**
144
+ * The Accept stored for `request`'s method and URL on this connection: what a
145
+ * `406` taught negotiation or `rememberAccept` stored, or `undefined` when
146
+ * there is none. A plain read of the per-connection cache, whatever the
147
+ * correction switch says, so a consumer that corrects requests itself can read
148
+ * it while negotiation is off.
149
+ */
150
+ function cachedAccept(connection, request) {
151
+ return stateOf(connection).accept.get(buildCacheKey(request));
152
+ }
153
+ /**
154
+ * Store a corrected Accept for `request`'s method and URL on this connection,
155
+ * as the negotiation's own `406` branch does: a later request through the
156
+ * connection's negotiation sends it. A plain write of the per-connection cache.
157
+ */
158
+ function rememberAccept(connection, request, accept) {
159
+ stateOf(connection).accept.set(buildCacheKey(request), accept);
160
+ }
137
161
  /**
138
162
  * The connection's request as it was before an `AdtClient` with correction on
139
163
  * wrapped it: accept negotiation corrects and resends nothing. The
@@ -73,7 +73,8 @@ Use the real handles and inspect activation messages, including `type="E"`.
73
73
  The transport provides no transaction or rollback; callers own recovery and
74
74
  cleanup after partial failures.
75
75
 
76
- Accept negotiation never corrects or resends an envelope or its parts. A batch
76
+ Accept negotiation never corrects or resends an envelope or its parts. (Since
77
+ 35.0.0 it corrects nothing anywhere unless switched on.) A batch
77
78
  connection is exempt from it: an `AdtClient` built over one does not wrap it,
78
79
  whatever `enableAcceptCorrection` it is given, and a member that negotiates by
79
80
  itself sends through it once. On a connection an `AdtClient` wrapped with
@@ -86,7 +87,27 @@ and is negotiated like any other; mark it with `exemptFromAcceptNegotiation(wrap
86
87
  (exported by the package) and it is exempt too. When the batch connection wraps
87
88
  a forwarder of yours over a connection an `AdtClient` wrapped, forward through
88
89
  `getBaseRequest(thatConnection)` (exported): the envelope then bypasses that
89
- connection's accept negotiation and is sent once. A batch is yours, and so is
90
+ connection's accept negotiation and is sent once. To correct a part that SAP
91
+ answered with `406` yourself, read the acceptable formats from that answer with
92
+ `extractSupportedAccept(error)` (exported): it takes the error the `406` came
93
+ as — any value; one without a response yields an empty list — and returns the
94
+ supported media types as a `string[]`. It reads them from the response headers
95
+ `accept`, `x-sap-adt-supported-accept`, `x-sap-adt-accept`, `supported-accept`
96
+ and `accept-supported` (comma-separated), and from every `type/subtype`
97
+ (with an optional `;parameter`) found in the response body, without
98
+ duplicates. It is the reading accept negotiation applies to a `406` itself.
99
+
100
+ The corrected Accept is remembered where negotiation remembers its own: the
101
+ connection's accept cache, keyed by method and URL. `cachedAccept(connection,
102
+ request)` (exported) returns the Accept stored for that request's method and
103
+ URL on that connection — what a `406` taught negotiation or `rememberAccept`
104
+ stored — or `undefined` when there is none. It is a plain read of the cache and
105
+ ignores the correction switch, so a consumer that corrects requests itself can
106
+ use it while negotiation is off. `rememberAccept(connection, request, accept)` (exported) stores
107
+ `accept` for the request's method and URL on the connection and returns nothing;
108
+ a later request through an `AdtClient` with correction on over the same
109
+ connection sends it (with correction off, only the consumer's own code reads it). Both read and write that cache only, so a correction
110
+ learned on either path serves both. A batch is yours, and so is
90
111
  what SAP answered to each of its parts. The envelope request itself still goes
91
112
  through the connection's own handling — credential renewal, CSRF recovery and
92
113
  session — as every request does: that is about the connection to the endpoint,
@@ -1042,7 +1042,10 @@ judgement moved to the caller, who knows which types they are activating.
1042
1042
 
1043
1043
  ### Accept Negotiation
1044
1044
 
1045
- The client can optionally auto-correct `Accept` headers after a 406 response:
1045
+ The client can optionally auto-correct `Accept` headers after a 406 response
1046
+ (and `Content-Type` after a 415). It is **off** unless switched on, per client
1047
+ as below or with `ADT_ACCEPT_CORRECTION=true`; with no switch a `406`/`415` is
1048
+ the call's answer and nothing is sent again (default flipped in 35.0.0):
1046
1049
 
1047
1050
  ```typescript
1048
1051
  const client = new AdtClient(connection, console, {
@@ -0,0 +1,33 @@
1
+ # Migrating to 35.0.0
2
+
3
+ 35.0.0 changes no type and no dependency range. It changes one default.
4
+
5
+ ## Accept negotiation is off unless switched on
6
+
7
+ Until 34.x, a request SAP answered `406` (its `Accept` not served) or `415`
8
+ (its `Content-Type` not accepted) was corrected from the types SAP named and
9
+ sent once more, unless you turned that off. Now nothing is corrected or sent
10
+ again unless you turn it on: the `406`/`415` is the call's answer, like any
11
+ other status.
12
+
13
+ - `getAcceptCorrectionEnabled(connection)` is `false` without an explicit
14
+ switch.
15
+ - `ADT_ACCEPT_CORRECTION=true` turns it on. Only the exact value `true` does;
16
+ unset, `false` or anything else leaves it off.
17
+ - The `enableAcceptCorrection` option and `setAcceptCorrectionEnabled` are
18
+ unchanged.
19
+
20
+ What to do if you relied on the default:
21
+
22
+ 1. Switch it on: `new AdtClient(connection, logger, { enableAcceptCorrection:
23
+ true })` (the same option on `AdtRuntimeClient`), or set
24
+ `ADT_ACCEPT_CORRECTION=true`; or
25
+ 2. Correct the request yourself. `extractSupportedAccept(error)` returns the
26
+ media types a `406` names; `rememberAccept(connection, request, accept)`
27
+ stores the one you choose in the connection's accept cache;
28
+ `cachedAccept(connection, request)` reads it back. All three are exported
29
+ from the package root; the last two read and write the cache negotiation
30
+ itself uses, so a correction made either way serves both.
31
+
32
+ `cachedAccept` is a plain read of the cache and no longer depends on the switch.
33
+ A batch connection stays exempt from negotiation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/adt-clients",
3
- "version": "34.2.1",
3
+ "version": "35.0.0",
4
4
  "description": "ADT clients for SAP ABAP systems - AdtClient and AdtRuntimeClient",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",