@mcp-abap-adt/adt-clients 36.0.0 → 36.0.2
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 +11 -3
- package/dist/constants/contentTypes.d.ts +10 -0
- package/dist/constants/contentTypes.d.ts.map +1 -1
- package/dist/constants/contentTypes.js +13 -2
- package/dist/core/enhancement/check.js +18 -18
- package/dist/core/featureToggle/validation.d.ts +7 -0
- package/dist/core/featureToggle/validation.d.ts.map +1 -1
- package/dist/core/featureToggle/validation.js +8 -1
- package/dist/core/transport/AdtRequest.d.ts +39 -1
- package/dist/core/transport/AdtRequest.d.ts.map +1 -1
- package/dist/core/transport/AdtRequest.js +39 -1
- package/dist/core/transport/create.d.ts +6 -1
- package/dist/core/transport/create.d.ts.map +1 -1
- package/dist/core/transport/create.js +10 -2
- package/dist/core/transport/objects.d.ts +3 -1
- package/dist/core/transport/objects.d.ts.map +1 -1
- package/dist/core/transport/objects.js +4 -2
- package/dist/runtime/applicationLog/read.d.ts.map +1 -1
- package/dist/runtime/applicationLog/read.js +3 -2
- package/dist/utils/supportedMediaTypes.d.ts.map +1 -1
- package/dist/utils/supportedMediaTypes.js +27 -36
- package/docs/usage/CLIENT_API_REFERENCE.md +37 -0
- package/docs/usage/MIGRATION-36.md +30 -4
- package/docs/usage/SAP_HEADER_CHECKS.md +101 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -886,6 +886,10 @@ still takes an optional `accept` (`IReadOptions`).
|
|
|
886
886
|
for them. It (and `unicode`) still decides the artifact type inside a
|
|
887
887
|
check-run document and a class's `readMetadata` `Accept`. abapGit's
|
|
888
888
|
`contentTypeVersion` option is removed.
|
|
889
|
+
- An enhancement's `check` takes the `CHECK_RUN` pair below, as every other
|
|
890
|
+
`check` does (since 36.0.2). 35.0.0 sent
|
|
891
|
+
`application/vnd.sap.adt.checkrun.v1+xml` for both, which SAP refuses `415`;
|
|
892
|
+
see [the corrected pairs](docs/usage/MIGRATION-36.md#the-corrected-pairs-measured).
|
|
889
893
|
|
|
890
894
|
The pairs 35.0.0 chose for itself, for the samples below (a modern system):
|
|
891
895
|
|
|
@@ -943,13 +947,17 @@ caches, the `enableAcceptCorrection` option, `setAcceptCorrectionEnabled` /
|
|
|
943
947
|
included.
|
|
944
948
|
|
|
945
949
|
To correct a request yourself, read what SAP named and send it again with the
|
|
946
|
-
pair you choose.
|
|
950
|
+
pair you choose. When SAP checks each header, and what a request has already
|
|
951
|
+
done when it answers `406` or `415` (a `406` on a write may come after the
|
|
952
|
+
work, which may or may not have been rolled back), is in [When SAP checks `Accept` and `Content-Type`](docs/usage/SAP_HEADER_CHECKS.md). Two pure functions over the error are exported:
|
|
947
953
|
|
|
948
954
|
- `extractSupportedAccept(error)` — the list SAP writes into its `406` body,
|
|
949
955
|
`Accepted content types: …` (often empty; measured on an on-premise system).
|
|
950
956
|
It reads no header and no other text.
|
|
951
|
-
- `extractSupportedContentType(error)` — the
|
|
952
|
-
|
|
957
|
+
- `extractSupportedContentType(error)` — the list SAP writes into its `415`
|
|
958
|
+
body, `Supported Media Types: …` (absent from a bare `Unsupported Media
|
|
959
|
+
Type`; measured on an on-premise system). It reads no header — the `415`'s
|
|
960
|
+
own `content-type` is its error document's — and no other text (36.0.1).
|
|
953
961
|
|
|
954
962
|
```typescript
|
|
955
963
|
import { extractSupportedAccept } from '@mcp-abap-adt/adt-clients';
|
|
@@ -111,6 +111,16 @@ export declare const ACCEPT_TRACE_FEED = "application/atom+xml;type=feed";
|
|
|
111
111
|
export declare const ACCEPT_TRACE_CALLTREE = "application/vnd.sap.adt.runtime.traces.abaptraces.aggcalltree+xml, application/xml";
|
|
112
112
|
export declare const CT_TRACE_PARAMETERS = "application/xml";
|
|
113
113
|
export declare const ACCEPT_SYSTEM_INFO = "application/json";
|
|
114
|
+
/**
|
|
115
|
+
* What an application log object's two reads ask for. Until 36.0.1 both sent
|
|
116
|
+
* `application/xml`, which SAP refuses `406` (SADT_RESOURCE 037). Measured on
|
|
117
|
+
* an on-premise system (2026-10-19), on an existing object: the properties
|
|
118
|
+
* answer `200` `application/vnd.sap.adt.blues.v1+xml` to that type, and the
|
|
119
|
+
* source answers `200` `application/json` to that type and `406` to
|
|
120
|
+
* `application/vnd.sap.adt.blues.v1+xml`.
|
|
121
|
+
*/
|
|
122
|
+
export declare const ACCEPT_APPLICATION_LOG_OBJECT = "application/vnd.sap.adt.blues.v1+xml";
|
|
123
|
+
export declare const ACCEPT_APPLICATION_LOG_SOURCE = "application/json";
|
|
114
124
|
export declare const ACCEPT_FEATURE_TOGGLE_METADATA = "application/vnd.sap.adt.blues.v1+xml";
|
|
115
125
|
export declare const CT_FEATURE_TOGGLE_METADATA = "application/vnd.sap.adt.blues.v1+xml";
|
|
116
126
|
export declare const ACCEPT_FEATURE_TOGGLE_STATES = "application/vnd.sap.adt.states.v1+asjson";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contentTypes.d.ts","sourceRoot":"","sources":["../../src/constants/contentTypes.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"contentTypes.d.ts","sourceRoot":"","sources":["../../src/constants/contentTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE;;;;;;GAMG;AAOH,eAAO,MAAM,aAAa,eAAe,CAAC;AAC1C,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,0BAA0B,gCAAgC,CAAC;AACxE,eAAO,MAAM,SAAS,8BAA8B,CAAC;AAGrD,eAAO,MAAM,WAAW,sKAC6I,CAAC;AAGtK,eAAO,MAAM,qBAAqB,8CACW,CAAC;AAC9C,eAAO,MAAM,gBAAgB,6CAA6C,CAAC;AAG3E,eAAO,MAAM,qBAAqB,2DACwB,CAAC;AAC3D,eAAO,MAAM,iBAAiB,0DAC2B,CAAC;AAC1D,eAAO,MAAM,eAAe,qDACwB,CAAC;AACrD,eAAO,MAAM,WAAW,oDAAoD,CAAC;AAG7E,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AACnD,eAAO,MAAM,aAAa,2CAA2C,CAAC;AAGtE,eAAO,MAAM,iBAAiB,+BAA+B,CAAC;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAG/B,CAAC;AACF,eAAO,MAAM,kBAAkB,EAAE,WAGhC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,iGAC6D,CAAC;AAGjG,eAAO,MAAM,gBAAgB,sDACwB,CAAC;AACtD,eAAO,MAAM,qBAAqB,0DACuB,CAAC;AAC1D,eAAO,MAAM,+BAA+B,kDACK,CAAC;AAClD,eAAO,MAAM,sBAAsB,8FAC0D,CAAC;AAC9F,eAAO,MAAM,kBAAkB,gGACgE,CAAC;AAGhG,eAAO,MAAM,gBAAgB,oDACsB,CAAC;AACpD,eAAO,MAAM,uBAAuB,2DACsB,CAAC;AAC3D,eAAO,MAAM,uBAAuB,2DACsB,CAAC;AAC3D,eAAO,MAAM,mBAAmB,wDACuB,CAAC;AAGxD,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAG1D,eAAO,MAAM,qBAAqB,6EAC0C,CAAC;AAG7E,eAAO,MAAM,sBAAsB,oEACgC,CAAC;AACpE,eAAO,MAAM,kBAAkB,qEACqC,CAAC;AAGrE,eAAO,MAAM,wBAAwB,qEAC+B,CAAC;AACrE,eAAO,MAAM,qBAAqB,sEACmC,CAAC;AACtE,eAAO,MAAM,uBAAuB,6EACwC,CAAC;AAC7E,eAAO,MAAM,mBAAmB,4EAC2C,CAAC;AAG5E,eAAO,MAAM,mBAAmB,sEACqC,CAAC;AAOtE,eAAO,MAAM,YAAY,+KACqJ,CAAC;AAC/K,eAAO,MAAM,QAAQ,8CAA8C,CAAC;AAGpE,eAAO,MAAM,gBAAgB,sOACwM,CAAC;AACtO,eAAO,MAAM,YAAY,iDAAiD,CAAC;AAG3E,eAAO,MAAM,cAAc,uGAC2E,CAAC;AACvG,eAAO,MAAM,UAAU,qDAAqD,CAAC;AAG7E,eAAO,MAAM,qBAAqB,qGACkE,CAAC;AACrG,eAAO,MAAM,iBAAiB,oDACqB,CAAC;AAGpD,eAAO,MAAM,sBAAsB,yJACqH,CAAC;AACzJ,eAAO,MAAM,kBAAkB,mDACmB,CAAC;AAGnD,eAAO,MAAM,uBAAuB,wGACmE,CAAC;AACxG,eAAO,MAAM,mBAAmB,uDACsB,CAAC;AAGvD,eAAO,MAAM,YAAY,gFACsD,CAAC;AAChF,eAAO,MAAM,QAAQ,0CAA0C,CAAC;AAGhE,eAAO,MAAM,iBAAiB,+HACgG,CAAC;AAC/H,eAAO,MAAM,aAAa,6CAA6C,CAAC;AAGxE,eAAO,MAAM,aAAa,mFACwD,CAAC;AACnF,eAAO,MAAM,SAAS,2CAA2C,CAAC;AAIlE,eAAO,MAAM,0BAA0B,yCACC,CAAC;AACzC,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAG7E,eAAO,MAAM,mBAAmB,6FAC4D,CAAC;AAC7F,eAAO,MAAM,eAAe,gDAAgD,CAAC;AAG7E,eAAO,MAAM,gBAAgB,yFAC2D,CAAC;AACzF,eAAO,MAAM,YAAY,8CAA8C,CAAC;AAGxE,eAAO,MAAM,WAAW,oFAC2D,CAAC;AACpF,eAAO,MAAM,oBAAoB,0CAA0C,CAAC;AAC5E,eAAO,MAAM,OAAO,0CAA0C,CAAC;AAG/D,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAC7E,eAAO,MAAM,kBAAkB,yCAAyC,CAAC;AAGzE,eAAO,MAAM,uBAAuB,yCAAyC,CAAC;AAC9E,eAAO,MAAM,8BAA8B,wDACY,CAAC;AACxD,eAAO,MAAM,2BAA2B,+EACsC,CAAC;AAE/E,eAAO,MAAM,kCAAkC,qBAAqB,CAAC;AACrE,eAAO,MAAM,8BAA8B,qBAAqB,CAAC;AAGjE,eAAO,MAAM,uBAAuB,oFAC+C,CAAC;AAGpF,eAAO,MAAM,cAAc,qFACyD,CAAC;AACrF,eAAO,MAAM,UAAU,4CAA4C,CAAC;AAGpE,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAG7E,eAAO,MAAM,qBAAqB,6CAA6C,CAAC;AAGhF,eAAO,MAAM,qBAAqB,6CAA6C,CAAC;AAGhF,eAAO,MAAM,iBAAiB,0CAA0C,CAAC;AAGzE,eAAO,MAAM,qBAAqB,gDACa,CAAC;AAChD,eAAO,MAAM,iBAAiB,gDAAgD,CAAC;AAG/E,eAAO,MAAM,yBAAyB;;;;CAI5B,CAAC;AAMX,eAAO,MAAM,4BAA4B,oFAC0C,CAAC;AAGpF,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAClD,eAAO,MAAM,iBAAiB,mCAAmC,CAAC;AAClE,eAAO,MAAM,qBAAqB,uFACoD,CAAC;AACvF,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAGrD,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAGrD;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,yCACF,CAAC;AACzC,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAIhE,eAAO,MAAM,8BAA8B,yCACH,CAAC;AACzC,eAAO,MAAM,0BAA0B,yCACC,CAAC;AACzC,eAAO,MAAM,4BAA4B,6CACG,CAAC;AAC7C,eAAO,MAAM,kCAAkC,0DACU,CAAC;AAC1D,eAAO,MAAM,kCAAkC,8DACc,CAAC;AAC9D,eAAO,MAAM,mCAAmC,gEACe,CAAC;AAChE,eAAO,MAAM,wBAAwB,mDACa,CAAC;AACnD,eAAO,MAAM,4BAA4B,mDAA2B,CAAC;AAGrE,eAAO,MAAM,iCAAiC,+DACgB,CAAC;AAO/D,eAAO,MAAM,uBAAuB,yCAAyC,CAAC;AAG9E,eAAO,MAAM,yBAAyB,+CACQ,CAAC;AAI/C,eAAO,MAAM,wCAAwC,yDACG,CAAC;AACzD,eAAO,MAAM,6CAA6C,0DACD,CAAC;AAS1D,eAAO,MAAM,sBAAsB,eAAe,CAAC;AACnD,eAAO,MAAM,sBAAsB,eAAe,CAAC;AACnD,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AACzD,eAAO,MAAM,qBAAqB,iDACc,CAAC;AACjD,eAAO,MAAM,uBAAuB,6EACwC,CAAC;AAC7E,eAAO,MAAM,sBAAsB,4GACwE,CAAC;AAG5G,eAAO,MAAM,2BAA2B,gDACO,CAAC;AAChD,eAAO,MAAM,0BAA0B,sDACc,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ACCEPT_TABLE_TYPE = exports.CT_TABLE = exports.ACCEPT_TABLE = exports.CT_FUNCTION_INCLUDE = exports.ACCEPT_FUNCTION_INCLUDE = exports.CT_FUNCTION_MODULE = exports.ACCEPT_FUNCTION_MODULE = exports.CT_FUNCTION_GROUP = exports.ACCEPT_FUNCTION_GROUP = exports.CT_PROGRAM = exports.ACCEPT_PROGRAM = exports.CT_INTERFACE = exports.ACCEPT_INTERFACE = exports.CT_CLASS = exports.ACCEPT_CLASS = exports.ACCEPT_DATA_PREVIEW = exports.CT_WHERE_USED_SCOPE = exports.ACCEPT_WHERE_USED_SCOPE = exports.CT_WHERE_USED_REQUEST = exports.ACCEPT_WHERE_USED_RESULT = exports.CT_VIRTUAL_FOLDERS = exports.ACCEPT_VIRTUAL_FOLDERS = exports.ACCEPT_NODE_STRUCTURE = exports.ACCEPT_DISCOVERY = exports.ACCEPT_JUNIT_RESULT = exports.ACCEPT_UNIT_TEST_RESULT = exports.ACCEPT_UNIT_TEST_STATUS = exports.CT_UNIT_TEST_RUN = exports.CT_TRANSPORT_CHECK = exports.ACCEPT_TRANSPORT_CHECK = exports.ACCEPT_TRANSPORT_CONFIGURATIONS = exports.ACCEPT_TRANSPORT_LIST = exports.ACCEPT_TRANSPORT = exports.ACCEPT_PUBLICATION_JOB = exports.ACTIVATION_HEADERS = exports.CHECK_RUN_HEADERS = exports.ACCEPT_VALIDATION = exports.CT_ACTIVATION = exports.ACCEPT_ACTIVATION = exports.CT_DELETION = exports.ACCEPT_DELETION = exports.CT_DELETION_CHECK = exports.ACCEPT_DELETION_CHECK = exports.CT_CHECK_OBJECTS = exports.ACCEPT_CHECK_MESSAGES = exports.ACCEPT_LOCK = exports.CT_SOURCE = exports.ACCEPT_SOURCE_XML_FALLBACK = exports.ACCEPT_SOURCE_UTF8 = exports.ACCEPT_SOURCE = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.ACCEPT_ENHANCEMENT_OPTIONS = exports.ACCEPT_ENHANCEMENT_ELEMENTS = exports.ACCEPT_ATC_CUSTOMIZING = exports.ACCEPT_ATC_WORKLIST_XML = exports.ACCEPT_ATC_RUN_STATUS = exports.ACCEPT_ATC_RUN_RESPONSE = exports.CT_ATC_RUN = void 0;
|
|
4
|
+
exports.ACCEPT_ABAPGIT_EXTERNAL_REPO_INFO_RESPONSE_V2 = exports.CT_ABAPGIT_EXTERNAL_REPO_INFO_REQUEST_V2 = exports.CT_ABAPGIT_REPO_OBJECT_V2 = exports.ACCEPT_ABAPGIT_REPOS_V2 = exports.MESSAGE_CLASS_UPDATE_CONTENT_TYPE = exports.ACCEPT_FEATURE_TOGGLE_SOURCE = exports.CT_FEATURE_TOGGLE_SOURCE = exports.CT_FEATURE_TOGGLE_TOGGLE_PARAMETERS = exports.CT_FEATURE_TOGGLE_CHECK_PARAMETERS = exports.ACCEPT_FEATURE_TOGGLE_CHECK_RESULT = exports.ACCEPT_FEATURE_TOGGLE_STATES = exports.CT_FEATURE_TOGGLE_METADATA = exports.ACCEPT_FEATURE_TOGGLE_METADATA = exports.ACCEPT_APPLICATION_LOG_SOURCE = exports.ACCEPT_APPLICATION_LOG_OBJECT = exports.ACCEPT_SYSTEM_INFO = exports.CT_TRACE_PARAMETERS = exports.ACCEPT_TRACE_CALLTREE = exports.ACCEPT_TRACE_FEED = exports.ACCEPT_TRACE_XML = exports.ACCEPT_VALIDATION_CLASS_NAME = exports.ENHANCEMENT_CONTENT_TYPES = exports.CT_TRANSFORMATION = exports.ACCEPT_TRANSFORMATION = exports.CT_ACCESS_CONTROL = exports.CT_METADATA_EXTENSION = exports.CT_SERVICE_DEFINITION = exports.CT_BEHAVIOR_DEFINITION = exports.CT_PACKAGE = exports.ACCEPT_PACKAGE = exports.ACCEPT_APPEND_STRUCTURE = exports.CT_SCALAR_FUNCTION_IMPL_SOURCE = exports.ACCEPT_SCALAR_FUNCTION_IMPL_SOURCE = exports.ACCEPT_SCALAR_FUNCTION_IMPL = exports.CT_SCALAR_FUNCTION_IMPL_UPDATE = exports.CT_SCALAR_FUNCTION_IMPL = exports.CT_SCALAR_FUNCTION = exports.ACCEPT_SCALAR_FUNCTION = exports.CT_VIEW = exports.ACCEPT_VIEW_METADATA = exports.ACCEPT_VIEW = exports.CT_STRUCTURE = exports.ACCEPT_STRUCTURE = exports.CT_DATA_ELEMENT = exports.ACCEPT_DATA_ELEMENT = exports.CT_AUTHORIZATION_FIELD = exports.ACCEPT_AUTHORIZATION_FIELD = exports.CT_DOMAIN = exports.ACCEPT_DOMAIN = exports.CT_TABLE_TYPE = void 0;
|
|
5
|
+
exports.ACCEPT_ENHANCEMENT_OPTIONS = exports.ACCEPT_ENHANCEMENT_ELEMENTS = exports.ACCEPT_ATC_CUSTOMIZING = exports.ACCEPT_ATC_WORKLIST_XML = exports.ACCEPT_ATC_RUN_STATUS = exports.ACCEPT_ATC_RUN_RESPONSE = exports.CT_ATC_RUN = exports.ACCEPT_ATC_WORKLIST_ID = exports.CT_ATC_WORKLIST_CREATE = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* Centralized ADT content type constants
|
|
8
8
|
*
|
|
@@ -170,6 +170,17 @@ exports.ACCEPT_TRACE_CALLTREE = 'application/vnd.sap.adt.runtime.traces.abaptrac
|
|
|
170
170
|
exports.CT_TRACE_PARAMETERS = 'application/xml';
|
|
171
171
|
// System Information
|
|
172
172
|
exports.ACCEPT_SYSTEM_INFO = 'application/json';
|
|
173
|
+
// Application log objects (APLO)
|
|
174
|
+
/**
|
|
175
|
+
* What an application log object's two reads ask for. Until 36.0.1 both sent
|
|
176
|
+
* `application/xml`, which SAP refuses `406` (SADT_RESOURCE 037). Measured on
|
|
177
|
+
* an on-premise system (2026-10-19), on an existing object: the properties
|
|
178
|
+
* answer `200` `application/vnd.sap.adt.blues.v1+xml` to that type, and the
|
|
179
|
+
* source answers `200` `application/json` to that type and `406` to
|
|
180
|
+
* `application/vnd.sap.adt.blues.v1+xml`.
|
|
181
|
+
*/
|
|
182
|
+
exports.ACCEPT_APPLICATION_LOG_OBJECT = 'application/vnd.sap.adt.blues.v1+xml';
|
|
183
|
+
exports.ACCEPT_APPLICATION_LOG_SOURCE = 'application/json';
|
|
173
184
|
// Feature Toggles (FTG2/FT) — metadata uses the shared blues envelope
|
|
174
185
|
// same as APS IAM; state and domain endpoints use dedicated JSON types.
|
|
175
186
|
exports.ACCEPT_FEATURE_TOGGLE_METADATA = 'application/vnd.sap.adt.blues.v1+xml';
|
|
@@ -18,10 +18,18 @@ async function checkEnhancement(connection, headers, params) {
|
|
|
18
18
|
const { enhancement_name, enhancement_type, version = 'inactive', source_code, } = params;
|
|
19
19
|
const objectUri = (0, types_1.getEnhancementUri)(enhancement_type, enhancement_name);
|
|
20
20
|
const versionParam = version === 'inactive' ? 'workingArea' : 'active';
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
//
|
|
21
|
+
// The document every other handler's check sends (`buildCheckRunXml`), with
|
|
22
|
+
// the reporter in the query. Until 36.0.1 this sent a
|
|
23
|
+
// `chkrun:checkRunRequest` with the reporter inside it, the type of the
|
|
24
|
+
// recorded pair `application/vnd.sap.adt.checkrun.v1+xml`. SAP refuses that
|
|
25
|
+
// pair `415` ("Supported Media Types: application/vnd.sap.adt.checkobjects+xml")
|
|
26
|
+
// and answers `400` "System expected the element
|
|
27
|
+
// '{http://www.sap.com/adt/checkrun}checkObjectList'" to the document under
|
|
28
|
+
// the checkobjects type. With this document and the checkmessages /
|
|
29
|
+
// checkobjects pair it answers `200` (`workingArea` and `active` both
|
|
30
|
+
// processed), with the source too. Measured on an on-premise system,
|
|
31
|
+
// 2026-10-19.
|
|
32
|
+
const checkUrl = `/sap/bc/adt/checkruns?reporters=abapCheckRun`;
|
|
25
33
|
let artifactsXml = '';
|
|
26
34
|
if (source_code && (0, types_1.supportsSourceCode)(enhancement_type)) {
|
|
27
35
|
// Include source code for live validation (base64 encoded)
|
|
@@ -29,23 +37,15 @@ async function checkEnhancement(connection, headers, params) {
|
|
|
29
37
|
artifactsXml = `
|
|
30
38
|
<chkrun:artifacts>
|
|
31
39
|
<chkrun:artifact chkrun:contentType="text/plain; charset=utf-8" chkrun:uri="${objectUri}/source/main">
|
|
32
|
-
|
|
40
|
+
<chkrun:content>${base64Source}</chkrun:content>
|
|
33
41
|
</chkrun:artifact>
|
|
34
|
-
</chkrun:artifacts
|
|
42
|
+
</chkrun:artifacts>
|
|
43
|
+
`;
|
|
35
44
|
}
|
|
36
45
|
const xmlPayload = `<?xml version="1.0" encoding="UTF-8"?>
|
|
37
|
-
<chkrun:
|
|
38
|
-
<chkrun:
|
|
39
|
-
|
|
40
|
-
</chkrun:reporters>
|
|
41
|
-
<chkrun:objectSets>
|
|
42
|
-
<chkrun:objectSet>
|
|
43
|
-
<chkrun:objects>
|
|
44
|
-
<chkrun:object adtcore:uri="${objectUri}" chkrun:version="${versionParam}"/>
|
|
45
|
-
</chkrun:objects>
|
|
46
|
-
</chkrun:objectSet>
|
|
47
|
-
</chkrun:objectSets>${artifactsXml}
|
|
48
|
-
</chkrun:checkRunRequest>`;
|
|
46
|
+
<chkrun:checkObjectList xmlns:chkrun="http://www.sap.com/adt/checkrun" xmlns:adtcore="http://www.sap.com/adt/core">
|
|
47
|
+
<chkrun:checkObject adtcore:uri="${objectUri}" chkrun:version="${versionParam}">${artifactsXml}</chkrun:checkObject>
|
|
48
|
+
</chkrun:checkObjectList>`;
|
|
49
49
|
return connection.makeAdtRequest({
|
|
50
50
|
url: checkUrl,
|
|
51
51
|
method: 'POST',
|
|
@@ -12,6 +12,13 @@ import type { IAbapConnection, IAdtWireResponse } from '@mcp-abap-adt/interfaces
|
|
|
12
12
|
* advertises for this — a GET on it answers 405, a POST with the usual
|
|
13
13
|
* `objname`/`packagename`/`description` query answers 200 with
|
|
14
14
|
* `<CHECK_RESULT>X</CHECK_RESULT>`. Measured 2026-08-31.
|
|
15
|
+
*
|
|
16
|
+
* It answers `application/vnd.sap.as+xml` (the `ACCEPT_VALIDATION` every other
|
|
17
|
+
* name validation sends) and nothing else: the toggle's own
|
|
18
|
+
* `application/vnd.sap.adt.blues.v1+xml`, sent until 36.0.1, is refused `406`
|
|
19
|
+
* "Accepted content types: application/vnd.sap.as+xml". Measured on an
|
|
20
|
+
* on-premise system, 2026-10-19. `validate` is `IAdtValidatable`'s, which takes
|
|
21
|
+
* no `options.headers`, so the type stays here, as in every other validation.
|
|
15
22
|
*/
|
|
16
23
|
export declare function validateFeatureToggleName(connection: IAbapConnection, name: string, packageName?: string, description?: string): Promise<IAdtWireResponse>;
|
|
17
24
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/core/featureToggle/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAIjD
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/core/featureToggle/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAY3B"}
|
|
@@ -16,6 +16,13 @@ const objects_1 = require("../../endpoints/objects");
|
|
|
16
16
|
* advertises for this — a GET on it answers 405, a POST with the usual
|
|
17
17
|
* `objname`/`packagename`/`description` query answers 200 with
|
|
18
18
|
* `<CHECK_RESULT>X</CHECK_RESULT>`. Measured 2026-08-31.
|
|
19
|
+
*
|
|
20
|
+
* It answers `application/vnd.sap.as+xml` (the `ACCEPT_VALIDATION` every other
|
|
21
|
+
* name validation sends) and nothing else: the toggle's own
|
|
22
|
+
* `application/vnd.sap.adt.blues.v1+xml`, sent until 36.0.1, is refused `406`
|
|
23
|
+
* "Accepted content types: application/vnd.sap.as+xml". Measured on an
|
|
24
|
+
* on-premise system, 2026-10-19. `validate` is `IAdtValidatable`'s, which takes
|
|
25
|
+
* no `options.headers`, so the type stays here, as in every other validation.
|
|
19
26
|
*/
|
|
20
27
|
async function validateFeatureToggleName(connection, name, packageName, description) {
|
|
21
28
|
const params = { objname: name.toUpperCase() };
|
|
@@ -27,7 +34,7 @@ async function validateFeatureToggleName(connection, name, packageName, descript
|
|
|
27
34
|
method: 'POST',
|
|
28
35
|
url: objects_1.FEATURE_TOGGLE.validation,
|
|
29
36
|
timeout: 0,
|
|
30
|
-
headers: { Accept: contentTypes_1.
|
|
37
|
+
headers: { Accept: contentTypes_1.ACCEPT_VALIDATION },
|
|
31
38
|
params,
|
|
32
39
|
});
|
|
33
40
|
}
|
|
@@ -50,6 +50,24 @@ export declare class AdtRequest<R extends ITransportResults = typeof transportDo
|
|
|
50
50
|
*
|
|
51
51
|
* The number is the system's to generate, so there is nothing to validate
|
|
52
52
|
* before the POST — which is why this module has no `validate`.
|
|
53
|
+
*
|
|
54
|
+
* **The owner is sent in upper case** (`config.owner`, else the system
|
|
55
|
+
* context's `responsible`). SAP user names are upper case and CTS compares
|
|
56
|
+
* them as given: measured on premise, a lower case name was refused with
|
|
57
|
+
* `SCTS_ADT_MSG 009`, *"User … does not exist in the system (or locked)"*.
|
|
58
|
+
*
|
|
59
|
+
* **One request, and a refusal can still leave one behind.** The POST
|
|
60
|
+
* carries the request and its first task (owned by the owner) in one
|
|
61
|
+
* document; the library makes no second call. Measured on premise: when the
|
|
62
|
+
* task part was refused, SAP still created the request header and kept it —
|
|
63
|
+
* empty, with no task — while the call answered the refusal. The library
|
|
64
|
+
* cannot report a number it was never given, so after a refused create a
|
|
65
|
+
* caller that must leave nothing behind looks among its requests for the
|
|
66
|
+
* empty one with this description, and deletes it. Nothing here deletes it
|
|
67
|
+
* for you.
|
|
68
|
+
*
|
|
69
|
+
* There is no release member: releasing a request stays a person's
|
|
70
|
+
* decision, made in the organizer.
|
|
53
71
|
*/
|
|
54
72
|
create<E extends IAdtError = IAdtError>(config: Omit<ITransportConfig, 'source'> & {
|
|
55
73
|
source?: never;
|
|
@@ -211,6 +229,12 @@ export declare class AdtRequest<R extends ITransportResults = typeof transportDo
|
|
|
211
229
|
*
|
|
212
230
|
* The answer echoes the entries under the source's number, so a `200` is
|
|
213
231
|
* not evidence: re-read both tasks.
|
|
232
|
+
*
|
|
233
|
+
* **Two conditions SAP checks** (measured on premise):
|
|
234
|
+
* - the caller must hold both tasks — otherwise *"… can be changed only by
|
|
235
|
+
* holder …"*;
|
|
236
|
+
* - both requests must have the same target — otherwise *"Object can only
|
|
237
|
+
* be moved to a request with the same target"*.
|
|
214
238
|
*/
|
|
215
239
|
moveObjects<E extends IAdtError = IAdtError>(sourceTask: string, targetNumber: string, objects: readonly (IAbapObjectEntry & {
|
|
216
240
|
position: string;
|
|
@@ -230,6 +254,14 @@ export declare class AdtRequest<R extends ITransportResults = typeof transportDo
|
|
|
230
254
|
* Unclassified task** on an on-premise system, 2026-09-25 — including one
|
|
231
255
|
* created explicitly through {@link createTask}. Classify it through
|
|
232
256
|
* {@link changeTaskType} before adding objects directly.
|
|
257
|
+
*
|
|
258
|
+
* **An entry still held in another task is refused** (*"… is locked in
|
|
259
|
+
* request/task …"*): to move an entry, {@link removeObject} it from the
|
|
260
|
+
* task holding it first, then add it — or use {@link moveObjects}.
|
|
261
|
+
*
|
|
262
|
+
* **A transportable request refuses objects of a package without a
|
|
263
|
+
* transport layer**: *"Only edit objects from package … in local
|
|
264
|
+
* requests"*. Such objects belong in a local request.
|
|
233
265
|
*/
|
|
234
266
|
addObject<E extends IAdtError = IAdtError>(transportNumber: string, object: IAbapObjectEntry, options: {
|
|
235
267
|
headers: IAdtHeaders;
|
|
@@ -248,7 +280,8 @@ export declare class AdtRequest<R extends ITransportResults = typeof transportDo
|
|
|
248
280
|
* exist in the system (or locked)"* — an empty name — and the same call
|
|
249
281
|
* carrying it answered 200 with a task number. This client cannot fill it
|
|
250
282
|
* in: the connection does not say who is authenticated, and asking would
|
|
251
|
-
* cost a second request.
|
|
283
|
+
* cost a second request. It is sent in upper case, as SAP user names are; a
|
|
284
|
+
* lower case name is refused with the same message.
|
|
252
285
|
*/
|
|
253
286
|
createTask<E extends IAdtError = IAdtError>(transportNumber: string, options: {
|
|
254
287
|
headers: IAdtHeaders;
|
|
@@ -302,6 +335,11 @@ export declare class AdtRequest<R extends ITransportResults = typeof transportDo
|
|
|
302
335
|
* are REQUEST types, refused as unknown. Addressed at the TASK — that is
|
|
303
336
|
* where the listing puts the `changetasktype` link.
|
|
304
337
|
*
|
|
338
|
+
* **Only the task's holder can classify it**, even when someone else
|
|
339
|
+
* created the task: a call from anyone else is refused (measured on
|
|
340
|
+
* premise). Create a task for the user who will classify it
|
|
341
|
+
* ({@link createTask}'s `targetUser`), and classify it as that user.
|
|
342
|
+
*
|
|
305
343
|
* As with every user action here, `ok` means the document was understood.
|
|
306
344
|
* Read the request back to see the type.
|
|
307
345
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtRequest.d.ts","sourceRoot":"","sources":["../../../src/core/transport/AdtRequest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,4BAA4B,EAC5B,sBAAsB,EAEvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,eAAe,EACf,2BAA2B,EAC5B,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAiB9D,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAGjB;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EACnD,UAAU,EAAE,CAAC,GACZ,UAAU,IAAI,CAAC,GAAG,2BAA2B,CAK/C;AAED,qBAAa,UAAU,CAAC,CAAC,SAAS,iBAAiB,GAAG,OAAO,kBAAkB,CAC7E,YACE,aAAa,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACzD,oBAAoB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EACjE,qBAAqB,CACnB,OAAO,CAAC,gBAAgB,CAAC,EACzB,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CACjC,EACD,aAAa,CACX,gBAAgB,EAChB,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EACxB,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAC/B,EACD,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAClC,0BAA0B,CACxB,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,EAC9B,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAC5B,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAC5B,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAC1B,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EACxB,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CACjC,EACD,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAClE,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IAYvD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAV/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAa;gBAG7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EAEd,OAAO,GAAE,CAAsC;IAOpE,mDAAmD;IACnD,OAAO,CAAC,MAAM;IAId
|
|
1
|
+
{"version":3,"file":"AdtRequest.d.ts","sourceRoot":"","sources":["../../../src/core/transport/AdtRequest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,4BAA4B,EAC5B,sBAAsB,EAEvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,eAAe,EACf,2BAA2B,EAC5B,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAiB9D,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAGjB;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EACnD,UAAU,EAAE,CAAC,GACZ,UAAU,IAAI,CAAC,GAAG,2BAA2B,CAK/C;AAED,qBAAa,UAAU,CAAC,CAAC,SAAS,iBAAiB,GAAG,OAAO,kBAAkB,CAC7E,YACE,aAAa,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACzD,oBAAoB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EACjE,qBAAqB,CACnB,OAAO,CAAC,gBAAgB,CAAC,EACzB,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CACjC,EACD,aAAa,CACX,gBAAgB,EAChB,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EACxB,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAC/B,EACD,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAClC,0BAA0B,CACxB,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,EAC9B,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAC5B,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAC5B,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAC1B,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EACxB,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CACjC,EACD,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAClE,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IAYvD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAV/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAa;gBAG7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EAEd,OAAO,GAAE,CAAsC;IAOpE,mDAAmD;IACnD,OAAO,CAAC,MAAM;IAId;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,MAAM,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC1C,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,KAAK,CAAA;KAAE,EAC7D,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,GACvD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAqBrD;;;;;;;;OAQG;IACG,YAAY,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAChD,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAChE,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAatD;;;;;;;;;;;;;;;;;OAiBG;IACG,IAAI,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACxC,OAAO,EAAE,sBAAsB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACtD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAUlD;;;;;;;;OAQG;IACG,oBAAoB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACxD,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAYlE;;;;;;;;;;;;;;OAcG;IACG,cAAc,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAClD,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAsB7D;;;;;OAKG;IACH;;;;;;;;;;;;;;;;;;OAkBG;IACG,aAAa,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACjD,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAerD,MAAM,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC1C,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAcrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACG,YAAY,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAChD,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,gBAAgB,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,EAC/C,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAqB3D;;;;;;;;;;;OAWG;IACG,eAAe,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACnD,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAajE;;;;;;;;;;;;;;;;;OAiBG;IACG,WAAW,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC/C,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,SAAS,CAAC,gBAAgB,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,EAC7D,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAsB1D;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC7C,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAmBzD;;;;;;;;;;;;;;;;OAgBG;IACG,UAAU,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC9C,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG;QAClC,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAoBzD;;;;;;;OAOG;IACG,aAAa,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACjD,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAcvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACG,cAAc,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAClD,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAc7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACG,WAAW,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC/C,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAatD"}
|
|
@@ -71,6 +71,24 @@ class AdtRequest {
|
|
|
71
71
|
*
|
|
72
72
|
* The number is the system's to generate, so there is nothing to validate
|
|
73
73
|
* before the POST — which is why this module has no `validate`.
|
|
74
|
+
*
|
|
75
|
+
* **The owner is sent in upper case** (`config.owner`, else the system
|
|
76
|
+
* context's `responsible`). SAP user names are upper case and CTS compares
|
|
77
|
+
* them as given: measured on premise, a lower case name was refused with
|
|
78
|
+
* `SCTS_ADT_MSG 009`, *"User … does not exist in the system (or locked)"*.
|
|
79
|
+
*
|
|
80
|
+
* **One request, and a refusal can still leave one behind.** The POST
|
|
81
|
+
* carries the request and its first task (owned by the owner) in one
|
|
82
|
+
* document; the library makes no second call. Measured on premise: when the
|
|
83
|
+
* task part was refused, SAP still created the request header and kept it —
|
|
84
|
+
* empty, with no task — while the call answered the refusal. The library
|
|
85
|
+
* cannot report a number it was never given, so after a refused create a
|
|
86
|
+
* caller that must leave nothing behind looks among its requests for the
|
|
87
|
+
* empty one with this description, and deletes it. Nothing here deletes it
|
|
88
|
+
* for you.
|
|
89
|
+
*
|
|
90
|
+
* There is no release member: releasing a request stays a person's
|
|
91
|
+
* decision, made in the organizer.
|
|
74
92
|
*/
|
|
75
93
|
async create(config, options) {
|
|
76
94
|
// The caller's deadline, if they set one, on every request below.
|
|
@@ -265,6 +283,12 @@ class AdtRequest {
|
|
|
265
283
|
*
|
|
266
284
|
* The answer echoes the entries under the source's number, so a `200` is
|
|
267
285
|
* not evidence: re-read both tasks.
|
|
286
|
+
*
|
|
287
|
+
* **Two conditions SAP checks** (measured on premise):
|
|
288
|
+
* - the caller must hold both tasks — otherwise *"… can be changed only by
|
|
289
|
+
* holder …"*;
|
|
290
|
+
* - both requests must have the same target — otherwise *"Object can only
|
|
291
|
+
* be moved to a request with the same target"*.
|
|
268
292
|
*/
|
|
269
293
|
async moveObjects(sourceTask, targetNumber, objects, options) {
|
|
270
294
|
const connection = (0, callTimeout_1.withCallTimeout)(this.connection, options?.timeout);
|
|
@@ -284,6 +308,14 @@ class AdtRequest {
|
|
|
284
308
|
* Unclassified task** on an on-premise system, 2026-09-25 — including one
|
|
285
309
|
* created explicitly through {@link createTask}. Classify it through
|
|
286
310
|
* {@link changeTaskType} before adding objects directly.
|
|
311
|
+
*
|
|
312
|
+
* **An entry still held in another task is refused** (*"… is locked in
|
|
313
|
+
* request/task …"*): to move an entry, {@link removeObject} it from the
|
|
314
|
+
* task holding it first, then add it — or use {@link moveObjects}.
|
|
315
|
+
*
|
|
316
|
+
* **A transportable request refuses objects of a package without a
|
|
317
|
+
* transport layer**: *"Only edit objects from package … in local
|
|
318
|
+
* requests"*. Such objects belong in a local request.
|
|
287
319
|
*/
|
|
288
320
|
async addObject(transportNumber, object, options) {
|
|
289
321
|
const connection = (0, callTimeout_1.withCallTimeout)(this.connection, options?.timeout);
|
|
@@ -304,7 +336,8 @@ class AdtRequest {
|
|
|
304
336
|
* exist in the system (or locked)"* — an empty name — and the same call
|
|
305
337
|
* carrying it answered 200 with a task number. This client cannot fill it
|
|
306
338
|
* in: the connection does not say who is authenticated, and asking would
|
|
307
|
-
* cost a second request.
|
|
339
|
+
* cost a second request. It is sent in upper case, as SAP user names are; a
|
|
340
|
+
* lower case name is refused with the same message.
|
|
308
341
|
*/
|
|
309
342
|
async createTask(transportNumber, options) {
|
|
310
343
|
const connection = (0, callTimeout_1.withCallTimeout)(this.connection, options?.timeout);
|
|
@@ -362,6 +395,11 @@ class AdtRequest {
|
|
|
362
395
|
* are REQUEST types, refused as unknown. Addressed at the TASK — that is
|
|
363
396
|
* where the listing puts the `changetasktype` link.
|
|
364
397
|
*
|
|
398
|
+
* **Only the task's holder can classify it**, even when someone else
|
|
399
|
+
* created the task: a call from anyone else is refused (measured on
|
|
400
|
+
* premise). Create a task for the user who will classify it
|
|
401
|
+
* ({@link createTask}'s `targetUser`), and classify it as that user.
|
|
402
|
+
*
|
|
365
403
|
* As with every user action here, `ok` means the document was understood.
|
|
366
404
|
* Read the request back to see the type.
|
|
367
405
|
*/
|
|
@@ -5,7 +5,12 @@ import type { IAdtHeaders } from '@mcp-abap-adt/interfaces-adt';
|
|
|
5
5
|
import type { IAbapConnection, IAdtWireResponse } from '@mcp-abap-adt/interfaces-adt-connection';
|
|
6
6
|
import type { ICreateTransportParams } from './types';
|
|
7
7
|
/**
|
|
8
|
-
* Create ABAP transport request
|
|
8
|
+
* Create ABAP transport request.
|
|
9
|
+
*
|
|
10
|
+
* One POST creates the request and its first task together: the document
|
|
11
|
+
* carries the `tm:request` and, inside it, the `tm:task` with its owner. The
|
|
12
|
+
* library makes no second call, so it has no point at which to notice a half
|
|
13
|
+
* done create — see `AdtRequest.create`.
|
|
9
14
|
*/
|
|
10
15
|
export declare function createTransport(connection: IAbapConnection, headers: IAdtHeaders, params: ICreateTransportParams): Promise<IAdtWireResponse>;
|
|
11
16
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/core/transport/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAGjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/core/transport/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAGjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AA2BtD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAkB3B"}
|
|
@@ -12,7 +12,10 @@ const requestHeaders_1 = require("../../utils/requestHeaders");
|
|
|
12
12
|
function buildCreateTransportXml(args, username) {
|
|
13
13
|
const transportType = args.transport_type === 'customizing' ? 'T' : 'K';
|
|
14
14
|
const description = args.description || 'Transport request created via MCP';
|
|
15
|
-
|
|
15
|
+
// SAP user names are upper case, and CTS compares them as given: a lower
|
|
16
|
+
// case owner was refused, measured on premise, with SCTS_ADT_MSG 009 "User …
|
|
17
|
+
// does not exist in the system (or locked)".
|
|
18
|
+
const owner = (args.owner || username || '').toUpperCase();
|
|
16
19
|
const target = args.target_system?.trim()
|
|
17
20
|
? `/${args.target_system}/`
|
|
18
21
|
: 'LOCAL';
|
|
@@ -24,7 +27,12 @@ function buildCreateTransportXml(args, username) {
|
|
|
24
27
|
</tm:root>`;
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
|
-
* Create ABAP transport request
|
|
30
|
+
* Create ABAP transport request.
|
|
31
|
+
*
|
|
32
|
+
* One POST creates the request and its first task together: the document
|
|
33
|
+
* carries the `tm:request` and, inside it, the `tm:task` with its owner. The
|
|
34
|
+
* library makes no second call, so it has no point at which to notice a half
|
|
35
|
+
* done create — see `AdtRequest.create`.
|
|
28
36
|
*/
|
|
29
37
|
async function createTransport(connection, headers, params) {
|
|
30
38
|
const username = params.owner;
|
|
@@ -101,7 +101,9 @@ export declare function addObjectToTransport(connection: IAbapConnection, header
|
|
|
101
101
|
*
|
|
102
102
|
* Nothing here defaults it: `IAbapConnection` does not expose who is
|
|
103
103
|
* authenticated, and finding out would cost a second request — which is the
|
|
104
|
-
* one thing a member of this library does not do.
|
|
104
|
+
* one thing a member of this library does not do. It is sent in upper case,
|
|
105
|
+
* as SAP user names are: CTS compares the name as given, and a lower case one
|
|
106
|
+
* is refused with the same SCTS_ADT_MSG 009.
|
|
105
107
|
*/
|
|
106
108
|
export declare function createTransportTask(connection: IAbapConnection, headers: IAdtHeaders, transportNumber: string, targetUser: string): Promise<IAdtWireResponse>;
|
|
107
109
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../../src/core/transport/objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAIjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAmDhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,SAAS,CAAC,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,GAC5D,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED
|
|
1
|
+
{"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../../src/core/transport/objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAIjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAmDhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,SAAS,CAAC,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,GAC5D,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CAU3B;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,eAAe,EAC3B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAa3B"}
|
|
@@ -168,7 +168,9 @@ async function addObjectToTransport(connection, headers, transportNumber, object
|
|
|
168
168
|
*
|
|
169
169
|
* Nothing here defaults it: `IAbapConnection` does not expose who is
|
|
170
170
|
* authenticated, and finding out would cost a second request — which is the
|
|
171
|
-
* one thing a member of this library does not do.
|
|
171
|
+
* one thing a member of this library does not do. It is sent in upper case,
|
|
172
|
+
* as SAP user names are: CTS compares the name as given, and a lower case one
|
|
173
|
+
* is refused with the same SCTS_ADT_MSG 009.
|
|
172
174
|
*/
|
|
173
175
|
async function createTransportTask(connection, headers, transportNumber, targetUser) {
|
|
174
176
|
return connection.makeAdtRequest({
|
|
@@ -176,7 +178,7 @@ async function createTransportTask(connection, headers, transportNumber, targetU
|
|
|
176
178
|
method: 'POST',
|
|
177
179
|
timeout: 0,
|
|
178
180
|
data: '<?xml version="1.0" encoding="ASCII"?>\n' +
|
|
179
|
-
`<tm:root xmlns:tm="http://www.sap.com/cts/adt/tm" tm:number="${attribute(transportNumber)}" tm:targetuser="${attribute(targetUser)}" tm:useraction="newtask"/>`,
|
|
181
|
+
`<tm:root xmlns:tm="http://www.sap.com/cts/adt/tm" tm:number="${attribute(transportNumber)}" tm:targetuser="${attribute(targetUser.toUpperCase())}" tm:useraction="newtask"/>`,
|
|
180
182
|
headers: (0, requestHeaders_1.requestHeaders)(headers),
|
|
181
183
|
});
|
|
182
184
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/runtime/applicationLog/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/runtime/applicationLog/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAOjD,YAAY,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAEpF;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,+BAA+B,GACxC,OAAO,CAAC,gBAAgB,CAAC,CAqB3B;AAGD,YAAY,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAEpF;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,+BAA+B,GACxC,OAAO,CAAC,gBAAgB,CAAC,CAmB3B;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CAiB3B"}
|
|
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
11
11
|
exports.getApplicationLogObject = getApplicationLogObject;
|
|
12
12
|
exports.getApplicationLogSource = getApplicationLogSource;
|
|
13
13
|
exports.validateApplicationLogName = validateApplicationLogName;
|
|
14
|
+
const contentTypes_1 = require("../../constants/contentTypes");
|
|
14
15
|
/**
|
|
15
16
|
* Get application log object properties
|
|
16
17
|
*
|
|
@@ -38,7 +39,7 @@ async function getApplicationLogObject(connection, objectName, options) {
|
|
|
38
39
|
timeout: 0,
|
|
39
40
|
params,
|
|
40
41
|
headers: {
|
|
41
|
-
Accept:
|
|
42
|
+
Accept: contentTypes_1.ACCEPT_APPLICATION_LOG_OBJECT,
|
|
42
43
|
'X-sap-adt-relation': 'http://www.sap.com/wbobj/applicationlogobjects/aplotyp/properties',
|
|
43
44
|
},
|
|
44
45
|
});
|
|
@@ -66,7 +67,7 @@ async function getApplicationLogSource(connection, objectName, options) {
|
|
|
66
67
|
timeout: 0,
|
|
67
68
|
params,
|
|
68
69
|
headers: {
|
|
69
|
-
Accept:
|
|
70
|
+
Accept: contentTypes_1.ACCEPT_APPLICATION_LOG_SOURCE,
|
|
70
71
|
'X-sap-adt-relation': 'http://www.sap.com/wbobj/applicationlogobjects/aplotyp/source',
|
|
71
72
|
},
|
|
72
73
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supportedMediaTypes.d.ts","sourceRoot":"","sources":["../../src/utils/supportedMediaTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"supportedMediaTypes.d.ts","sourceRoot":"","sources":["../../src/utils/supportedMediaTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA0DH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAE/D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAKpE"}
|
|
@@ -24,16 +24,31 @@ exports.extractSupportedContentType = extractSupportedContentType;
|
|
|
24
24
|
* URI (`www.sap.com/abapxml`, `types/communicationframework`) on every 406.
|
|
25
25
|
*/
|
|
26
26
|
const ACCEPTED_CONTENT_TYPES = 'Accepted content types:';
|
|
27
|
+
/**
|
|
28
|
+
* The text SAP's 415 puts before the types it accepts as a body.
|
|
29
|
+
*
|
|
30
|
+
* Measured on an on-premise system: SAP answers a 415 with its exception
|
|
31
|
+
* document (`content-type: application/xml`, the document's own type), whose
|
|
32
|
+
* message reads "Unsupported Media Type. Supported Media Types: …" — or a bare
|
|
33
|
+
* "Unsupported Media Type". Only that list is read. Until 36.0.0 the parser
|
|
34
|
+
* also read the response's headers and every `type/subtype` in the body, so it
|
|
35
|
+
* answered `application/xml` and two fragments of the document's namespace URI
|
|
36
|
+
* before the type SAP named.
|
|
37
|
+
*/
|
|
38
|
+
const SUPPORTED_MEDIA_TYPES = 'Supported Media Types:';
|
|
27
39
|
/** Where the list after the marker ends: the element, an attribute or the line. */
|
|
28
40
|
const LIST_ENDS = ['<', '"', '\n'];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const data =
|
|
32
|
-
|
|
41
|
+
/** The body of a refusal as text. */
|
|
42
|
+
function bodyText(error) {
|
|
43
|
+
const data = error?.response?.data;
|
|
44
|
+
return typeof data === 'string' ? data : data ? JSON.stringify(data) : '';
|
|
45
|
+
}
|
|
46
|
+
/** Every type listed after `marker` in `text`, in order, each once. */
|
|
47
|
+
function listedAfter(text, marker) {
|
|
33
48
|
const types = new Set();
|
|
34
|
-
let at = text.indexOf(
|
|
49
|
+
let at = text.indexOf(marker);
|
|
35
50
|
while (at !== -1) {
|
|
36
|
-
const start = at +
|
|
51
|
+
const start = at + marker.length;
|
|
37
52
|
let end = text.length;
|
|
38
53
|
for (const stop of LIST_ENDS) {
|
|
39
54
|
const found = text.indexOf(stop, start);
|
|
@@ -45,40 +60,16 @@ function extractSupportedAccept(error) {
|
|
|
45
60
|
if (type)
|
|
46
61
|
types.add(type);
|
|
47
62
|
}
|
|
48
|
-
at = text.indexOf(
|
|
63
|
+
at = text.indexOf(marker, end);
|
|
49
64
|
}
|
|
50
65
|
return Array.from(types);
|
|
51
66
|
}
|
|
67
|
+
function extractSupportedAccept(error) {
|
|
68
|
+
return listedAfter(bodyText(error), ACCEPTED_CONTENT_TYPES);
|
|
69
|
+
}
|
|
52
70
|
function extractSupportedContentType(error) {
|
|
53
|
-
|
|
54
|
-
if (e?.response?.status !== 415) {
|
|
71
|
+
if (error?.response?.status !== 415) {
|
|
55
72
|
return [];
|
|
56
73
|
}
|
|
57
|
-
|
|
58
|
-
const headers = (e?.response?.headers || {});
|
|
59
|
-
const headerCandidates = [
|
|
60
|
-
headers['content-type'],
|
|
61
|
-
headers['x-sap-adt-supported-content-type'],
|
|
62
|
-
headers['supported-content-type'],
|
|
63
|
-
];
|
|
64
|
-
for (const value of headerCandidates) {
|
|
65
|
-
if (typeof value === 'string') {
|
|
66
|
-
value
|
|
67
|
-
.split(',')
|
|
68
|
-
.map((entry) => entry.trim())
|
|
69
|
-
.filter(Boolean)
|
|
70
|
-
.forEach((entry) => {
|
|
71
|
-
types.add(entry);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
const data = e?.response?.data;
|
|
76
|
-
const text = typeof data === 'string' ? data : data ? JSON.stringify(data) : '';
|
|
77
|
-
if (text) {
|
|
78
|
-
const matches = text.match(/[a-zA-Z0-9.+-]+\/[a-zA-Z0-9.+-]+(?:;[^,\s]+)?/g) || [];
|
|
79
|
-
for (const match of matches) {
|
|
80
|
-
types.add(match);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return Array.from(types).filter(Boolean);
|
|
74
|
+
return listedAfter(bodyText(error), SUPPORTED_MEDIA_TYPES);
|
|
84
75
|
}
|
|
@@ -758,6 +758,38 @@ had:
|
|
|
758
758
|
Unclassified); `Q` is a customizing type and is refused on a workbench
|
|
759
759
|
request, and `K`/`W` are *request* types, refused as unknown.
|
|
760
760
|
|
|
761
|
+
#### What CTS refuses, and why — measured on premise
|
|
762
|
+
|
|
763
|
+
These are SAP's rules, not the library's; each member's doc comment repeats
|
|
764
|
+
the one that applies to it.
|
|
765
|
+
|
|
766
|
+
- **User names go in upper case.** `create()` sends its owner and
|
|
767
|
+
`createTask()` its `targetUser` upper-cased, because CTS compares the name as
|
|
768
|
+
given: a lower case name was refused with `SCTS_ADT_MSG 009`, *"User … does
|
|
769
|
+
not exist in the system (or locked)"*.
|
|
770
|
+
- **A refused `create()` can leave a request behind.** One POST creates the
|
|
771
|
+
request and its first task. When the task part was refused, SAP still kept
|
|
772
|
+
the request header — empty, without a task — and the call answered the
|
|
773
|
+
refusal, with no number to report. A caller that must leave nothing behind
|
|
774
|
+
finds that empty request among its own and deletes it; the library does not.
|
|
775
|
+
- **`moveObjects()`** needs the caller to hold both tasks (*"… can be changed
|
|
776
|
+
only by holder …"*), and both requests must have the same target (*"Object
|
|
777
|
+
can only be moved to a request with the same target"*).
|
|
778
|
+
- **`changeTaskType()`** is the task holder's: someone else is refused, even
|
|
779
|
+
the user who created the task. Create the task for the user who will
|
|
780
|
+
classify it.
|
|
781
|
+
- **`addObject()`** refuses an entry still held in another task (*"… is locked
|
|
782
|
+
in request/task …"*): remove it there first, then add it — or move it. Into a
|
|
783
|
+
transportable request it refuses objects of a package without a transport
|
|
784
|
+
layer (*"Only edit objects from package … in local requests"*); those belong
|
|
785
|
+
in a local request.
|
|
786
|
+
|
|
787
|
+
#### No release
|
|
788
|
+
|
|
789
|
+
There is no member that releases a request or a task, and none is planned:
|
|
790
|
+
releasing ships whatever the request holds, so it stays a person's decision,
|
|
791
|
+
made in the transport organizer.
|
|
792
|
+
|
|
761
793
|
The type goes on a `tm:task` child of the document, not on its root — six
|
|
762
794
|
spellings on the root were each answered `400 "Specified request type or
|
|
763
795
|
task type is unknown"`, with two spaces where the value belongs.
|
|
@@ -1786,6 +1818,11 @@ const logObject = await appLog.getObject('Z_MY_LOG');
|
|
|
1786
1818
|
const logSource = await appLog.getSource('Z_MY_LOG');
|
|
1787
1819
|
```
|
|
1788
1820
|
|
|
1821
|
+
`getObject` asks for `application/vnd.sap.adt.blues.v1+xml` and answers the
|
|
1822
|
+
object's document; `getSource` asks for `application/json` and answers the
|
|
1823
|
+
object's subobjects as JSON. Until 36.0.1 both asked for `application/xml`,
|
|
1824
|
+
which SAP refuses `406`.
|
|
1825
|
+
|
|
1789
1826
|
### ATC check runs
|
|
1790
1827
|
|
|
1791
1828
|
`runtime.getAtc()` makes one request per member. An ATC run is three requests —
|
|
@@ -63,8 +63,10 @@ Pass `undefined` for the positional parameter that was optional:
|
|
|
63
63
|
`activateObjectsGroup(objects, preauditRequested, options)` and
|
|
64
64
|
`deleteObjectsGroup(objects, transportRequest, options)`.
|
|
65
65
|
|
|
66
|
-
To send what 35.0.0 sent, pass the pair from the table below
|
|
67
|
-
|
|
66
|
+
To send what 35.0.0 sent, pass the pair from the table below — except the
|
|
67
|
+
enhancement's `check`, whose pair SAP refuses:
|
|
68
|
+
[the corrected pairs](#the-corrected-pairs-measured) give the one to pass. A
|
|
69
|
+
few things changed on the wire whatever you pass:
|
|
68
70
|
|
|
69
71
|
- **Members that sent one header send both.** `create` of a function group, a
|
|
70
72
|
message class and a message class message, `update` of a feature toggle and
|
|
@@ -140,7 +142,12 @@ nothing else. Until 35.x it also read five headers and every `type/subtype` in
|
|
|
140
142
|
the body, which answered two fragments of the exception's namespace URI
|
|
141
143
|
(`www.sap.com/abapxml`, `types/communicationframework`) for every `406`. A
|
|
142
144
|
consumer that fed it a `406` carrying the types in a header gets `[]` now.
|
|
143
|
-
`extractSupportedContentType` (`415`)
|
|
145
|
+
`extractSupportedContentType` (`415`) was unchanged in 36.0.0; since 36.0.1
|
|
146
|
+
it reads only SAP's list the same way — `Supported Media Types: …` in the
|
|
147
|
+
`415` body (measured on an on-premise system), no header and no other text.
|
|
148
|
+
Until then it answered the `415`'s own `content-type` (`application/xml`, the
|
|
149
|
+
error document's type) and the two namespace fragments before the type SAP
|
|
150
|
+
named.
|
|
144
151
|
|
|
145
152
|
## The completed pairs, measured
|
|
146
153
|
|
|
@@ -164,6 +171,25 @@ the table shows, and SAP accepted it:
|
|
|
164
171
|
The legacy `DELETE`s were sent through `AdtClientLegacy` against that (modern)
|
|
165
172
|
system, which serves the same direct `DELETE`.
|
|
166
173
|
|
|
174
|
+
## The corrected pairs, measured
|
|
175
|
+
|
|
176
|
+
One pair 35.0.0 sent is refused by SAP, whatever the rest of the request: pass
|
|
177
|
+
the pair below instead of the one in [the pairs 35.0.0 sent](#the-pairs-3500-sent).
|
|
178
|
+
Measured on an on-premise system (2026-10-19), on existing objects:
|
|
179
|
+
|
|
180
|
+
| member | Accept | Content-Type | SAP answered |
|
|
181
|
+
|---|---|---|---|
|
|
182
|
+
| enhancement `check` (`POST /sap/bc/adt/checkruns`) | `application/vnd.sap.adt.checkmessages+xml` | `application/vnd.sap.adt.checkobjects+xml` | `200` (since 36.0.2) |
|
|
183
|
+
|
|
184
|
+
The enhancement's `check` sent `application/vnd.sap.adt.checkrun.v1+xml` as
|
|
185
|
+
both headers, and SAP answers `415` "Supported Media Types:
|
|
186
|
+
application/vnd.sap.adt.checkobjects+xml". It is the pair every other
|
|
187
|
+
handler's `check` sends. Its request document changed with it in 36.0.2: the
|
|
188
|
+
`chkrun:checkRunRequest` it sent before is refused `400` under the
|
|
189
|
+
checkobjects type, so it sends the `chkrun:checkObjectList` every other check
|
|
190
|
+
sends, with the reporter in the query (`?reporters=abapCheckRun`). Before
|
|
191
|
+
36.0.2 no pair made it succeed.
|
|
192
|
+
|
|
167
193
|
## The pairs 35.0.0 sent
|
|
168
194
|
|
|
169
195
|
Recorded from 35.0.0 against a stub connection. "legacy" is `AdtClientLegacy`
|
|
@@ -240,7 +266,7 @@ set.
|
|
|
240
266
|
| getDomain() | `delete` | `application/vnd.sap.adt.deletion.response.v1+xml` | `application/vnd.sap.adt.deletion.request.v1+xml` |
|
|
241
267
|
| getDomain() | `updateMetadata` | `application/vnd.sap.adt.domains.v2+xml, application/vnd.sap.adt.domains.v1+xml` | `application/vnd.sap.adt.domains.v2+xml; charset=utf-8` |
|
|
242
268
|
| getEnhancement() | `activate` | `application/xml` | `application/vnd.sap.adt.activation+xml` |
|
|
243
|
-
| getEnhancement() | `check` | `application/vnd.sap.adt.checkrun.v1+xml` | `application/vnd.sap.adt.checkrun.v1+xml` |
|
|
269
|
+
| getEnhancement() | `check` | `application/vnd.sap.adt.checkrun.v1+xml` (refused, [corrected](#the-corrected-pairs-measured)) | `application/vnd.sap.adt.checkrun.v1+xml` (refused, [corrected](#the-corrected-pairs-measured)) |
|
|
244
270
|
| getEnhancement() | `checkDeletion` | `application/vnd.sap.adt.deletion.check.response.v1+xml` | `application/vnd.sap.adt.deletion.check.request.v1+xml` |
|
|
245
271
|
| getEnhancement() | `create` | `application/vnd.sap.adt.enh.enhoxhh.v3+xml` | `application/vnd.sap.adt.enh.enhoxhh.v3+xml` |
|
|
246
272
|
| getEnhancement() | `delete` | `application/vnd.sap.adt.deletion.response.v1+xml` | `application/vnd.sap.adt.deletion.request.v1+xml` |
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# When SAP checks `Accept` and `Content-Type`
|
|
2
|
+
|
|
3
|
+
This page explains what a `406` or a `415` from an ADT endpoint means, where SAP raises it, and what a request may already have done by then. Read it if you pass `options.headers` and correct a refusal yourself. This library sends the pair it is given. It never corrects, retries or remembers one (see the README, "Accept Negotiation (removed in 36.0.0)").
|
|
4
|
+
|
|
5
|
+
## Where these findings come from
|
|
6
|
+
|
|
7
|
+
They come from two sources, both from 2026-10-18 and the same on-premise system:
|
|
8
|
+
|
|
9
|
+
- **SAP's ABAP sources** of the ADT REST framework, read through ADT with GET requests only;
|
|
10
|
+
- **an error corpus** measured on that system.
|
|
11
|
+
|
|
12
|
+
Each statement carries one of three tags:
|
|
13
|
+
|
|
14
|
+
- **Code:** the class and method it was read in;
|
|
15
|
+
- **Measured:** seen on that system;
|
|
16
|
+
- **Inference:** worked out from the code or the measurements, not read or run.
|
|
17
|
+
|
|
18
|
+
"No comparison" claims cover only the implementations that were read. Another release or a cloud system may behave differently.
|
|
19
|
+
|
|
20
|
+
## The short version
|
|
21
|
+
|
|
22
|
+
- **The framework itself checks neither `Accept` nor `Content-Type`.** It does not compare a request against the types a collection lists in discovery. Those types appear only in the discovery document. *Code.*
|
|
23
|
+
- **A resource checks the headers, or doesn't, and it decides when.** It can do so through the checking content handler `CL_ADT_REST_COMP_CNT_HANDLER`, or by calling a check or a negotiation of its own at any point. *Code.*
|
|
24
|
+
- **Through the handler:**
|
|
25
|
+
- `415` is raised when the resource reads its request body;
|
|
26
|
+
- `406` is raised when it writes its response body. *Code.*
|
|
27
|
+
- **Up front, before any change:** the deletion endpoint and the `LOCK` action of the generic object framework check `Accept`. *Code.*
|
|
28
|
+
- **Neither header compared:** activation, class create and the deletes of the generic object framework. *Code.*
|
|
29
|
+
- **A `500` says nothing about the headers.** It can come from:
|
|
30
|
+
- the router, before any resource runs;
|
|
31
|
+
- an ADT exception that carries status `500`;
|
|
32
|
+
- the REST layer's exception handling;
|
|
33
|
+
- a dump, at any point. *Code.*
|
|
34
|
+
|
|
35
|
+
## The order a request goes through
|
|
36
|
+
|
|
37
|
+
1. **Logon: `401`.** The ICF authenticates the user before any ADT code runs.
|
|
38
|
+
- *Inference.*
|
|
39
|
+
- *Measured:* the same GET answers `401` without credentials and `406` with them.
|
|
40
|
+
2. **Authorization: `403`.** `CL_ADT_WB_RES_APP` (`IF_HTTP_EXTENSION~HANDLE_REQUEST`) checks the development authorization and `S_ADT_RES`. *Code.*
|
|
41
|
+
3. **CSRF: `403`.** `CL_REST_HTTP_HANDLER` (`handle_csrf_token`) refuses a request that is not GET, HEAD or OPTIONS and carries no valid token. *Code.*
|
|
42
|
+
4. **Routing: `404` or `500`.** `CL_REST_ROUTER` answers `404` when no route matches. If it cannot create the routed class, the error becomes a `500` (`text/plain`, "Creation of handler class failed"), and no resource code has run. *Code.*
|
|
43
|
+
5. **Method dispatch: `405`.** `CL_ADT_REST_RESOURCE` (`IF_REST_HANDLER~HANDLE`) dispatches GET, POST, PUT and DELETE.
|
|
44
|
+
- When the resource does not implement the method, the default raises `cx_adt_res_meth_not_supported`, which gives `405` with `ExceptionMethodNotSupported`.
|
|
45
|
+
- Any other method gets `400`.
|
|
46
|
+
- No header has been read at this point. *Code.*
|
|
47
|
+
6. **The resource's own work**, where the headers may be checked:
|
|
48
|
+
- **Reading the body.** `IF_ADT_REST_REQUEST~GET_BODY_DATA` calls the resource's content handler. The plain handlers compare nothing. *Code.*
|
|
49
|
+
- The checking handler's `DESERIALIZE` answers `400` `contentTypeMissing` when there is no Content-Type, and `415` `ExceptionUnsupportedMediaType` when the type does not match. *Code.*
|
|
50
|
+
- That this `415` carries the text "Unsupported Media Type. Supported Media Types: …" is *Inference* from the measured text.
|
|
51
|
+
- Resources may also check the Content-Type themselves. For example, the generic object framework's `read_request_body` answers a `415` without that text. *Code*; *Measured*.
|
|
52
|
+
- **Writing the response.** `IF_ADT_REST_RESPONSE~SET_BODY_DATA` calls the content handler. The checking handler's `SERIALIZE` first runs `check_cnt_type_is_supported()`:
|
|
53
|
+
- with no Accept, it answers `400` `acceptHeaderMissing`;
|
|
54
|
+
- when the type does not match, it answers `406` `ExceptionResourceNotAcceptable` ("Accepted content types: …"). *Code.*
|
|
55
|
+
- The list is often empty. *Measured.*
|
|
56
|
+
- **The resource's own checks.** A resource may call that check itself, at any point, or negotiate on its own, for example `CL_BLUE_WB_UTILITY=>NEGOTIATE_CONTENT_TYPE`. Such a check may come before or after the work. *Code.*
|
|
57
|
+
7. **Errors from the work.** An ADT exception becomes an XML exception document with that exception's own status, which may be `400`, `404`, `423` or `500`. Any other exception or runtime error ends as a short dump, which the ICF answers with `500 text/html` ("Application Server Error"). *Code* for the catch clauses; the error page is *Inference*.
|
|
58
|
+
|
|
59
|
+
## What a status says about the headers
|
|
60
|
+
|
|
61
|
+
| Answer | What it says about the headers |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `401` | Nothing. The ICF logon comes before any ADT code. *Inference*; *Measured*: the same GET answers `401` without credentials and `406` with them. |
|
|
64
|
+
| `403` (authorization, CSRF) | Nothing. It comes before any header is read. *Code.* |
|
|
65
|
+
| `404` from the router (no route) | Nothing. It comes before any header is read. *Code.* |
|
|
66
|
+
| `404` from the resource (no such object) | Nothing about the headers. It may come before or after a check. *Inference.* |
|
|
67
|
+
| `405` | Nothing. The method is not implemented; it comes from dispatch, before any header is read. *Code.* |
|
|
68
|
+
| `500` | Nothing. A router failure, an ADT exception with status `500`, or a dump. *Code.* |
|
|
69
|
+
| `415` | The resource refused the Content-Type, through the checking handler or through its own check. *Code.* |
|
|
70
|
+
| `406` | Usually the resource refused the Accept, through the checking handler or through its own check or negotiation. It may come before or after the work. *Code.* A resource can also refuse an unsupported Content-Type with a bare `406` instead of a `415`: no body, no response Content-Type, no SAP exception. `POST /sap/bc/adt/packages/settings`, without Accept, answered a bare `406` with no Content-Type and with a bogus one, and `400` `ExceptionInvalidData` with `application/vnd.sap.adt.packages.settings.v2+xml`. *Measured* (one system). |
|
|
71
|
+
| `400` `acceptHeaderMissing` / `contentTypeMissing` | The resource needs that header and got none. *Code.* |
|
|
72
|
+
| `2xx` with an unusual header | Only that this request succeeded. The resource may compare nothing, or may accept the value through a permissive match. *Inference.* |
|
|
73
|
+
|
|
74
|
+
## Examples seen on that system
|
|
75
|
+
|
|
76
|
+
- **A DELETE of a metadata extension with an unusual Accept deletes the object.**
|
|
77
|
+
- `CL_WB_ADT_PLUGIN_RESOURCE` (`DO_DELETE`) ignores the Accept of a DELETE on purpose: a comment in it says so, because a DELETE has no body either way. It then commits. *Code.*
|
|
78
|
+
- That metadata extensions are served by this resource is *Inference*.
|
|
79
|
+
- The deletion itself is *Measured*.
|
|
80
|
+
- **A class create with an unusual Accept creates the class.** `CL_OO_ADT_RES_CLASS` (`CREATE`) reads the body through a plain handler, commits, and writes no response body. *Code*; *Measured*.
|
|
81
|
+
- **The generic object framework saves first and checks Accept afterwards.** `CL_WB_ADT_PLUGIN_RESOURCE` (`DO_CREATE_CHILD`) works in this order:
|
|
82
|
+
1. it reads the body (a `415` here);
|
|
83
|
+
2. it records the transport entry;
|
|
84
|
+
3. it saves;
|
|
85
|
+
4. it negotiates the response type (a `406`), and only when it fills a response body.
|
|
86
|
+
|
|
87
|
+
A `406` there runs `ROLLBACK WORK`. *Code.*
|
|
88
|
+
- *Measured:* a domain create with an unusual Accept answered `406`, and a read afterwards answered `404`. The domain did not exist.
|
|
89
|
+
- *Inference:* the rollback undid the save. This is not established for every object type, nor for the transport entry.
|
|
90
|
+
- **Activation answers `2xx` whatever the headers say.** `CL_SEU_ADT_RES_ACTIVATION` reads and writes through plain handlers. *Code*; *Measured*.
|
|
91
|
+
- **The deletion endpoint answers `406` before it deletes anything.** `CL_ADT_DELETION_RESOURCE` (`POST`) checks the Accept before it reads the body. *Code*; *Measured*.
|
|
92
|
+
|
|
93
|
+
## What follows for a consumer
|
|
94
|
+
|
|
95
|
+
These are deductions from the findings above. *Inference*, unless tagged otherwise.
|
|
96
|
+
|
|
97
|
+
- **To learn the acceptable types, a request has to reach the resource's check.** A request on an object that does not exist often ends with `404` first. Many `GET`s, though, answer `406` even on a name that does not exist. *Measured.*
|
|
98
|
+
- **A `415` from the checking handler means the body was refused before it was deserialized.** That does not prove nothing happened earlier in the resource.
|
|
99
|
+
- **A `406` on a write does not say whether the write left a lasting change.** The work may have run before the check, and it may then have been rolled back, as the domain create above suggests, or not. Read the object's state before sending a write again after a `406`.
|
|
100
|
+
- **An unusual header that gets a `2xx` proves neither that the header is right nor that the resource ignores it.**
|
|
101
|
+
- **`extractSupportedAccept(error)` and `extractSupportedContentType(error)`** read the two lists described above, and nothing else.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/adt-clients",
|
|
3
|
-
"version": "36.0.
|
|
3
|
+
"version": "36.0.2",
|
|
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",
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
"test:long-polling-read": "npx ts-node scripts/test-long-polling-read.ts",
|
|
99
99
|
"package:contents": "npx ts-node scripts/show-package-contents.ts",
|
|
100
100
|
"discovery:markdown": "npx ts-node tools/discovery-to-markdown.ts",
|
|
101
|
+
"header:discovery": "npx ts-node tools/header-probe/errorCorpus.ts",
|
|
101
102
|
"adt:entities": "node tools/adt-object-entities.js",
|
|
102
103
|
"shared:setup": "npx jest --testPathIgnorePatterns node_modules --testPathPatterns admin/shared-deps/setup",
|
|
103
104
|
"shared:teardown": "npx jest --testPathIgnorePatterns node_modules --testPathPatterns admin/shared-deps/teardown",
|