@mcp-abap-adt/adt-clients 3.14.2 → 3.14.4
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/dist/constants/contentTypes.d.ts +1 -1
- package/dist/constants/contentTypes.js +1 -1
- package/dist/core/dataElement/create.d.ts +6 -1
- package/dist/core/dataElement/create.d.ts.map +1 -1
- package/dist/core/dataElement/create.js +8 -102
- package/dist/core/package/update.d.ts.map +1 -1
- package/dist/core/package/update.js +8 -6
- package/dist/executors/class/ClassExecutor.d.ts +9 -0
- package/dist/executors/class/ClassExecutor.d.ts.map +1 -1
- package/dist/executors/class/ClassExecutor.js +72 -37
- package/dist/runtime/traces/profiler.d.ts +4 -1
- package/dist/runtime/traces/profiler.d.ts.map +1 -1
- package/dist/runtime/traces/profiler.js +8 -2
- package/package.json +1 -1
|
@@ -52,7 +52,7 @@ export declare const ACCEPT_TABLE_TYPE = "application/vnd.sap.adt.tabletypes.v2+
|
|
|
52
52
|
export declare const CT_TABLE_TYPE = "application/vnd.sap.adt.tabletype.v1+xml";
|
|
53
53
|
export declare const ACCEPT_DOMAIN = "application/vnd.sap.adt.domains.v2+xml, application/vnd.sap.adt.domains.v1+xml";
|
|
54
54
|
export declare const CT_DOMAIN = "application/vnd.sap.adt.domains.v2+xml";
|
|
55
|
-
export declare const ACCEPT_DATA_ELEMENT = "application/vnd.sap.adt.dataelements.
|
|
55
|
+
export declare const ACCEPT_DATA_ELEMENT = "application/vnd.sap.adt.dataelements.v1+xml, application/vnd.sap.adt.dataelements.v2+xml";
|
|
56
56
|
export declare const CT_DATA_ELEMENT = "application/vnd.sap.adt.dataelements.v2+xml";
|
|
57
57
|
export declare const ACCEPT_STRUCTURE = "application/vnd.sap.adt.structures.v2+xml, application/vnd.sap.adt.structures.v1+xml";
|
|
58
58
|
export declare const CT_STRUCTURE = "application/vnd.sap.adt.structures.v2+xml";
|
|
@@ -84,7 +84,7 @@ exports.CT_TABLE_TYPE = 'application/vnd.sap.adt.tabletype.v1+xml';
|
|
|
84
84
|
exports.ACCEPT_DOMAIN = 'application/vnd.sap.adt.domains.v2+xml, application/vnd.sap.adt.domains.v1+xml';
|
|
85
85
|
exports.CT_DOMAIN = 'application/vnd.sap.adt.domains.v2+xml';
|
|
86
86
|
// Data Elements
|
|
87
|
-
exports.ACCEPT_DATA_ELEMENT = 'application/vnd.sap.adt.dataelements.
|
|
87
|
+
exports.ACCEPT_DATA_ELEMENT = 'application/vnd.sap.adt.dataelements.v1+xml, application/vnd.sap.adt.dataelements.v2+xml';
|
|
88
88
|
exports.CT_DATA_ELEMENT = 'application/vnd.sap.adt.dataelements.v2+xml';
|
|
89
89
|
// Structures
|
|
90
90
|
exports.ACCEPT_STRUCTURE = 'application/vnd.sap.adt.structures.v2+xml, application/vnd.sap.adt.structures.v1+xml';
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DataElement create operations - Low-level functions
|
|
3
3
|
* NOTE: Caller should call connection.setSessionType("stateful") before creating
|
|
4
|
+
*
|
|
5
|
+
* Create sends minimal XML (root element + packageRef only).
|
|
6
|
+
* Type details (typeKind, labels, etc.) are set via update after creation,
|
|
7
|
+
* matching Eclipse ADT behavior.
|
|
4
8
|
*/
|
|
5
9
|
import type { IAdtResponse as AxiosResponse, IAbapConnection } from '@mcp-abap-adt/interfaces';
|
|
6
10
|
import type { ICreateDataElementParams } from './types';
|
|
7
11
|
/**
|
|
8
12
|
* Low-level: Create data element (POST)
|
|
9
|
-
* Does NOT activate - just creates the object
|
|
13
|
+
* Does NOT activate - just creates the object with minimal metadata.
|
|
14
|
+
* Type information and labels should be set via updateDataElement() afterwards.
|
|
10
15
|
*/
|
|
11
16
|
export declare function create(connection: IAbapConnection, args: ICreateDataElementParams): Promise<AxiosResponse>;
|
|
12
17
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/core/dataElement/create.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/core/dataElement/create.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAExD;;;;GAIG;AACH,wBAAsB,MAAM,CAC1B,UAAU,EAAE,eAAe,EAC3B,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,aAAa,CAAC,CA8BxB"}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* DataElement create operations - Low-level functions
|
|
4
4
|
* NOTE: Caller should call connection.setSessionType("stateful") before creating
|
|
5
|
+
*
|
|
6
|
+
* Create sends minimal XML (root element + packageRef only).
|
|
7
|
+
* Type details (typeKind, labels, etc.) are set via update after creation,
|
|
8
|
+
* matching Eclipse ADT behavior.
|
|
5
9
|
*/
|
|
6
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
11
|
exports.create = create;
|
|
@@ -10,118 +14,20 @@ const internalUtils_1 = require("../../utils/internalUtils");
|
|
|
10
14
|
const timeouts_1 = require("../../utils/timeouts");
|
|
11
15
|
/**
|
|
12
16
|
* Low-level: Create data element (POST)
|
|
13
|
-
* Does NOT activate - just creates the object
|
|
17
|
+
* Does NOT activate - just creates the object with minimal metadata.
|
|
18
|
+
* Type information and labels should be set via updateDataElement() afterwards.
|
|
14
19
|
*/
|
|
15
20
|
async function create(connection, args) {
|
|
16
21
|
const url = `/sap/bc/adt/ddic/dataelements${args.transport_request ? `?corrNr=${args.transport_request}` : ''}`;
|
|
17
22
|
const username = args.responsible || '';
|
|
18
23
|
const masterSystem = args.masterSystem || '';
|
|
19
|
-
// Description is limited to 60 characters in SAP ADT
|
|
20
24
|
const description = (0, internalUtils_1.limitDescription)(args.description || args.data_element_name);
|
|
21
|
-
if (!args.type_kind) {
|
|
22
|
-
throw new Error('type_kind is required. Must be one of: domain, predefinedAbapType, refToPredefinedAbapType, refToDictionaryType, refToClifType');
|
|
23
|
-
}
|
|
24
|
-
// Validate required parameters based on type_kind
|
|
25
|
-
// predefinedAbapType and refToPredefinedAbapType require data_type
|
|
26
|
-
// Other types (domain, refToDictionaryType, refToClifType) require type_name
|
|
27
|
-
if (args.type_kind === 'predefinedAbapType' ||
|
|
28
|
-
args.type_kind === 'refToPredefinedAbapType') {
|
|
29
|
-
if (!args.data_type) {
|
|
30
|
-
throw new Error(`data_type is required when type_kind is '${args.type_kind}'. Provide data type (e.g., CHAR, NUMC, INT4).`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
// domain, refToDictionaryType, refToClifType require type_name
|
|
35
|
-
if (args.type_kind === 'domain') {
|
|
36
|
-
// For domain, type_name (domain name) is required, but it will be used as data_type internally
|
|
37
|
-
if (!args.type_name && !args.data_type) {
|
|
38
|
-
throw new Error(`type_name (domain name) is required when type_kind is 'domain'. Provide domain name (e.g., ZOK_AUTH_ID).`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
// refToDictionaryType, refToClifType
|
|
43
|
-
if (!args.type_name) {
|
|
44
|
-
throw new Error(`type_name is required when type_kind is '${args.type_kind}'. Provide ${args.type_kind === 'refToDictionaryType' ? 'data element name' : 'class name'}.`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
const typeKindXml = args.type_kind;
|
|
49
|
-
// Use provided values directly - no automatic determination
|
|
50
|
-
// When typeKind is 'domain', dataType should contain the domain name, and it goes to typeName in XML
|
|
51
|
-
let typeName = '';
|
|
52
|
-
if (typeKindXml === 'domain') {
|
|
53
|
-
// For domain type, typeName is the domain name (type_name), not the underlying data type
|
|
54
|
-
typeName = (args.type_name || args.data_type || '').toUpperCase();
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
// For other types, typeName comes from type_name parameter
|
|
58
|
-
typeName = args.type_name ? args.type_name.toUpperCase() : '';
|
|
59
|
-
}
|
|
60
|
-
const dataType = args.data_type || '';
|
|
61
|
-
const length = args.length || 0;
|
|
62
|
-
const decimals = args.decimals || 0;
|
|
63
|
-
const shortLabel = args.short_label || '';
|
|
64
|
-
const mediumLabel = args.medium_label || '';
|
|
65
|
-
const longLabel = args.long_label || '';
|
|
66
|
-
const headingLabel = args.heading_label || '';
|
|
67
|
-
const searchHelp = args.search_help !== undefined ? args.search_help : '';
|
|
68
|
-
const searchHelpParameter = args.search_help_parameter !== undefined ? args.search_help_parameter : '';
|
|
69
|
-
const setGetParameter = args.set_get_parameter !== undefined ? args.set_get_parameter : '';
|
|
70
|
-
const defaultComponentName = args.default_component_name !== undefined
|
|
71
|
-
? args.default_component_name
|
|
72
|
-
: '';
|
|
73
|
-
const deactivateInputHistory = args.deactivate_input_history !== undefined
|
|
74
|
-
? args.deactivate_input_history
|
|
75
|
-
: false;
|
|
76
|
-
const changeDocument = args.change_document !== undefined ? args.change_document : false;
|
|
77
|
-
const leftToRightDirection = args.left_to_right_direction !== undefined
|
|
78
|
-
? args.left_to_right_direction
|
|
79
|
-
: false;
|
|
80
|
-
const deactivateBIDIFiltering = args.deactivate_bidi_filtering !== undefined
|
|
81
|
-
? args.deactivate_bidi_filtering
|
|
82
|
-
: false;
|
|
83
25
|
const masterSystemAttr = masterSystem
|
|
84
26
|
? ` adtcore:masterSystem="${masterSystem}"`
|
|
85
27
|
: '';
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
xmlns:adtcore="http://www.sap.com/adt/core"
|
|
89
|
-
xmlns:atom="http://www.w3.org/2005/Atom"
|
|
90
|
-
xmlns:dtel="http://www.sap.com/adt/dictionary/dataelements"
|
|
91
|
-
adtcore:description="${description}"
|
|
92
|
-
adtcore:language="EN"
|
|
93
|
-
adtcore:name="${args.data_element_name.toUpperCase()}"
|
|
94
|
-
adtcore:type="DTEL/DE"
|
|
95
|
-
adtcore:masterLanguage="EN"${masterSystemAttr}
|
|
96
|
-
adtcore:responsible="${username}">
|
|
28
|
+
const responsibleAttr = username ? ` adtcore:responsible="${username}"` : '';
|
|
29
|
+
const xmlBody = `<?xml version="1.0" encoding="UTF-8"?><blue:wbobj xmlns:blue="http://www.sap.com/wbobj/dictionary/dtel" xmlns:adtcore="http://www.sap.com/adt/core" adtcore:description="${description}" adtcore:language="EN" adtcore:name="${args.data_element_name.toUpperCase()}" adtcore:type="DTEL/DE" adtcore:masterLanguage="EN"${masterSystemAttr}${responsibleAttr}>
|
|
97
30
|
<adtcore:packageRef adtcore:name="${args.package_name.toUpperCase()}"/>
|
|
98
|
-
<dtel:dataElement>
|
|
99
|
-
<dtel:typeKind>${typeKindXml}</dtel:typeKind>
|
|
100
|
-
${typeName ? `<dtel:typeName>${typeName}</dtel:typeName>` : '<dtel:typeName/>'}
|
|
101
|
-
${dataType ? `<dtel:dataType>${dataType}</dtel:dataType>` : '<dtel:dataType/>'}
|
|
102
|
-
<dtel:dataTypeLength>${String(length).padStart(6, '0')}</dtel:dataTypeLength>
|
|
103
|
-
<dtel:dataTypeDecimals>${String(decimals).padStart(6, '0')}</dtel:dataTypeDecimals>
|
|
104
|
-
<dtel:shortFieldLabel>${shortLabel}</dtel:shortFieldLabel>
|
|
105
|
-
<dtel:shortFieldLength>10</dtel:shortFieldLength>
|
|
106
|
-
<dtel:shortFieldMaxLength>10</dtel:shortFieldMaxLength>
|
|
107
|
-
<dtel:mediumFieldLabel>${mediumLabel}</dtel:mediumFieldLabel>
|
|
108
|
-
<dtel:mediumFieldLength>20</dtel:mediumFieldLength>
|
|
109
|
-
<dtel:mediumFieldMaxLength>20</dtel:mediumFieldMaxLength>
|
|
110
|
-
<dtel:longFieldLabel>${longLabel}</dtel:longFieldLabel>
|
|
111
|
-
<dtel:longFieldLength>40</dtel:longFieldLength>
|
|
112
|
-
<dtel:longFieldMaxLength>40</dtel:longFieldMaxLength>
|
|
113
|
-
<dtel:headingFieldLabel>${headingLabel}</dtel:headingFieldLabel>
|
|
114
|
-
<dtel:headingFieldLength>55</dtel:headingFieldLength>
|
|
115
|
-
<dtel:headingFieldMaxLength>55</dtel:headingFieldMaxLength>
|
|
116
|
-
${searchHelp ? `<dtel:searchHelp>${searchHelp}</dtel:searchHelp>` : '<dtel:searchHelp/>'}
|
|
117
|
-
${searchHelpParameter ? `<dtel:searchHelpParameter>${searchHelpParameter}</dtel:searchHelpParameter>` : '<dtel:searchHelpParameter/>'}
|
|
118
|
-
${setGetParameter ? `<dtel:setGetParameter>${setGetParameter}</dtel:setGetParameter>` : '<dtel:setGetParameter/>'}
|
|
119
|
-
${defaultComponentName ? `<dtel:defaultComponentName>${defaultComponentName}</dtel:defaultComponentName>` : '<dtel:defaultComponentName/>'}
|
|
120
|
-
<dtel:deactivateInputHistory>${deactivateInputHistory}</dtel:deactivateInputHistory>
|
|
121
|
-
<dtel:changeDocument>${changeDocument}</dtel:changeDocument>
|
|
122
|
-
<dtel:leftToRightDirection>${leftToRightDirection}</dtel:leftToRightDirection>
|
|
123
|
-
<dtel:deactivateBIDIFiltering>${deactivateBIDIFiltering}</dtel:deactivateBIDIFiltering>
|
|
124
|
-
</dtel:dataElement>
|
|
125
31
|
</blue:wbobj>`;
|
|
126
32
|
const headers = {
|
|
127
33
|
Accept: contentTypes_1.ACCEPT_DATA_ELEMENT,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/core/package/update.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EACf,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/core/package/update.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EACf,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AA4ElC;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAuCxB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,eAAe,EAC3B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,CAAC,CAkBxB"}
|
|
@@ -19,27 +19,29 @@ const xmlPatch_1 = require("../../utils/xmlPatch");
|
|
|
19
19
|
*/
|
|
20
20
|
function patchPackageXml(currentXml, args) {
|
|
21
21
|
let xml = currentXml;
|
|
22
|
+
// Read-modify-write: empty string means "don't change" — preserve value from GET.
|
|
23
|
+
// Only non-empty values are patched into the XML.
|
|
22
24
|
// Description (always provided for update)
|
|
23
25
|
if (args.description) {
|
|
24
26
|
const description = (0, internalUtils_1.limitDescription)(args.description);
|
|
25
27
|
xml = (0, xmlPatch_1.patchXmlAttribute)(xml, 'adtcore:description', description);
|
|
26
28
|
}
|
|
27
29
|
// Responsible
|
|
28
|
-
xml = (0, xmlPatch_1.patchIf)(xml, args.responsible, (x, val) => (0, xmlPatch_1.patchXmlAttribute)(x, 'adtcore:responsible', val));
|
|
30
|
+
xml = (0, xmlPatch_1.patchIf)(xml, args.responsible || undefined, (x, val) => (0, xmlPatch_1.patchXmlAttribute)(x, 'adtcore:responsible', val));
|
|
29
31
|
// Master system
|
|
30
|
-
xml = (0, xmlPatch_1.patchIf)(xml, args.master_system, (x, val) => (0, xmlPatch_1.patchXmlAttribute)(x, 'adtcore:masterSystem', val));
|
|
32
|
+
xml = (0, xmlPatch_1.patchIf)(xml, args.master_system || undefined, (x, val) => (0, xmlPatch_1.patchXmlAttribute)(x, 'adtcore:masterSystem', val));
|
|
31
33
|
// Package type (pak:packageType attribute on pak:attributes element)
|
|
32
|
-
xml = (0, xmlPatch_1.patchIf)(xml, args.package_type, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:attributes', 'pak:packageType', val));
|
|
34
|
+
xml = (0, xmlPatch_1.patchIf)(xml, args.package_type || undefined, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:attributes', 'pak:packageType', val));
|
|
33
35
|
// Record changes
|
|
34
36
|
if (args.record_changes !== undefined) {
|
|
35
37
|
xml = (0, xmlPatch_1.patchXmlElementAttribute)(xml, 'pak:attributes', 'pak:recordChanges', args.record_changes ? 'true' : 'false');
|
|
36
38
|
}
|
|
37
39
|
// Super package
|
|
38
|
-
xml = (0, xmlPatch_1.patchIf)(xml, args.super_package, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:superPackage', 'adtcore:name', val));
|
|
40
|
+
xml = (0, xmlPatch_1.patchIf)(xml, args.super_package || undefined, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:superPackage', 'adtcore:name', val));
|
|
39
41
|
// Software component
|
|
40
|
-
xml = (0, xmlPatch_1.patchIf)(xml, args.software_component, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:softwareComponent', 'pak:name', val));
|
|
42
|
+
xml = (0, xmlPatch_1.patchIf)(xml, args.software_component || undefined, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:softwareComponent', 'pak:name', val));
|
|
41
43
|
// Transport layer
|
|
42
|
-
xml = (0, xmlPatch_1.patchIf)(xml, args.transport_layer, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:transportLayer', 'pak:name', val));
|
|
44
|
+
xml = (0, xmlPatch_1.patchIf)(xml, args.transport_layer || undefined, (x, val) => (0, xmlPatch_1.patchXmlElementAttribute)(x, 'pak:transportLayer', 'pak:name', val));
|
|
43
45
|
return xml;
|
|
44
46
|
}
|
|
45
47
|
/**
|
|
@@ -9,6 +9,10 @@ export interface IClassExecuteWithProfilerOptions {
|
|
|
9
9
|
export interface IClassExecuteWithProfilingOptions {
|
|
10
10
|
profilerParameters?: IProfilerTraceParameters;
|
|
11
11
|
traceLookupUris?: string[];
|
|
12
|
+
/** Maximum number of polling attempts to find the trace (default: 5) */
|
|
13
|
+
maxTraceAttempts?: number;
|
|
14
|
+
/** Delay in ms between polling attempts (default: 2000) */
|
|
15
|
+
traceRetryDelayMs?: number;
|
|
12
16
|
}
|
|
13
17
|
export interface IClassExecuteWithProfilingResult {
|
|
14
18
|
response: AxiosResponse;
|
|
@@ -25,6 +29,11 @@ export declare class ClassExecutor implements IClassExecutor {
|
|
|
25
29
|
run(target: IClassExecutionTarget): Promise<AxiosResponse>;
|
|
26
30
|
runWithProfiler(target: IClassExecutionTarget, options: IClassExecuteWithProfilerOptions): Promise<AxiosResponse>;
|
|
27
31
|
runWithProfiling(target: IClassExecutionTarget, options?: IClassExecuteWithProfilingOptions): Promise<IClassExecuteWithProfilingResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Single attempt to find trace via trace files (filtered by user),
|
|
34
|
+
* URI lookup, and trace requests fallback.
|
|
35
|
+
*/
|
|
36
|
+
private tryResolveTrace;
|
|
28
37
|
private runWithProfilerId;
|
|
29
38
|
}
|
|
30
39
|
//# sourceMappingURL=ClassExecutor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClassExecutor.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EACf,SAAS,EACT,OAAO,EACR,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAKL,KAAK,wBAAwB,EAG9B,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ClassExecutor.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EACf,SAAS,EACT,OAAO,EACR,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAKL,KAAK,wBAAwB,EAG9B,MAAM,+BAA+B,CAAC;AAKvC,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gCAAgC;IAC/C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iCAAiC;IAChD,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,aAAa,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB,EAAE,aAAa,CAAC;CACtC;AAED,MAAM,WAAW,cACf,SAAQ,SAAS,CACf,qBAAqB,EACrB,aAAa,EACb,gCAAgC,EAChC,iCAAiC,EACjC,gCAAgC,CACjC;CAAG;AAKN,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;gBAEtB,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,OAAO;IAKnD,GAAG,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC;IAO1D,eAAe,CACnB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,aAAa,CAAC;IAUnB,gBAAgB,CACpB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,gCAAgC,CAAC;IAoE5C;;;OAGG;YACW,eAAe;YA2Ef,iBAAiB;CAehC"}
|
|
@@ -4,7 +4,9 @@ exports.ClassExecutor = void 0;
|
|
|
4
4
|
const run_1 = require("../../core/class/run");
|
|
5
5
|
const profiler_1 = require("../../runtime/traces/profiler");
|
|
6
6
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
7
|
+
const systemInfo_1 = require("../../utils/systemInfo");
|
|
7
8
|
const timeouts_1 = require("../../utils/timeouts");
|
|
9
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
10
|
class ClassExecutor {
|
|
9
11
|
connection;
|
|
10
12
|
logger;
|
|
@@ -36,13 +38,69 @@ class ClassExecutor {
|
|
|
36
38
|
if (!profilerId) {
|
|
37
39
|
throw new Error('Failed to extract profilerId from trace parameters response');
|
|
38
40
|
}
|
|
41
|
+
// Resolve current user for trace file lookup
|
|
42
|
+
let userName;
|
|
43
|
+
try {
|
|
44
|
+
const sysInfo = await (0, systemInfo_1.getSystemInformation)(this.connection);
|
|
45
|
+
userName = sysInfo?.userName;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
this.logger?.debug?.('Failed to resolve userName for trace lookup');
|
|
49
|
+
}
|
|
39
50
|
const response = await this.runWithProfilerId(target.className, profilerId);
|
|
51
|
+
const maxAttempts = options.maxTraceAttempts ?? 5;
|
|
52
|
+
const retryDelayMs = options.traceRetryDelayMs ?? 2000;
|
|
40
53
|
const lookupUris = [
|
|
41
54
|
...(options.traceLookupUris ?? []),
|
|
42
55
|
`/sap/bc/adt/oo/classrun/${target.className}`,
|
|
43
56
|
`/sap/bc/adt/oo/classrun/${(0, internalUtils_1.encodeSapObjectName)(target.className).toUpperCase()}`,
|
|
44
57
|
];
|
|
58
|
+
// SAP writes traces asynchronously — poll until the trace file appears
|
|
59
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
60
|
+
this.logger?.debug?.(`Trace lookup attempt ${attempt}/${maxAttempts}`, {
|
|
61
|
+
className: target.className,
|
|
62
|
+
profilerId,
|
|
63
|
+
});
|
|
64
|
+
const result = await this.tryResolveTrace(lookupUris, profilerId, response, userName);
|
|
65
|
+
if (result) {
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
if (attempt < maxAttempts) {
|
|
69
|
+
await delay(retryDelayMs);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this.logger?.warn?.('Failed to resolve trace after all attempts', {
|
|
73
|
+
className: target.className,
|
|
74
|
+
profilerId,
|
|
75
|
+
maxAttempts,
|
|
76
|
+
});
|
|
77
|
+
throw new Error(`Failed to resolve traceId after profiled execution for class ${target.className}`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Single attempt to find trace via trace files (filtered by user),
|
|
81
|
+
* URI lookup, and trace requests fallback.
|
|
82
|
+
*/
|
|
83
|
+
async tryResolveTrace(lookupUris, profilerId, runResponse, userName) {
|
|
45
84
|
let traceRequestsResponse;
|
|
85
|
+
// 1. Primary: list trace files filtered by user
|
|
86
|
+
try {
|
|
87
|
+
const filesResponse = await (0, profiler_1.listTraceFiles)(this.connection, userName ? { user: userName } : undefined);
|
|
88
|
+
const traceId = (0, profiler_1.extractTraceIdFromTraceRequestsResponse)(filesResponse);
|
|
89
|
+
if (traceId) {
|
|
90
|
+
return {
|
|
91
|
+
response: runResponse,
|
|
92
|
+
profilerId,
|
|
93
|
+
traceId,
|
|
94
|
+
traceRequestsResponse: filesResponse,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
this.logger?.debug?.('Trace files list failed', {
|
|
100
|
+
error: error instanceof Error ? error.message : String(error),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// 2. Fallback: lookup by URI
|
|
46
104
|
for (const uri of lookupUris) {
|
|
47
105
|
if (!uri) {
|
|
48
106
|
continue;
|
|
@@ -52,7 +110,7 @@ class ClassExecutor {
|
|
|
52
110
|
const traceId = (0, profiler_1.extractTraceIdFromTraceRequestsResponse)(current);
|
|
53
111
|
if (traceId) {
|
|
54
112
|
return {
|
|
55
|
-
response,
|
|
113
|
+
response: runResponse,
|
|
56
114
|
profilerId,
|
|
57
115
|
traceId,
|
|
58
116
|
traceRequestsResponse: current,
|
|
@@ -62,53 +120,30 @@ class ClassExecutor {
|
|
|
62
120
|
}
|
|
63
121
|
catch (error) {
|
|
64
122
|
this.logger?.debug?.('Trace lookup by URI failed, trying next URI', {
|
|
65
|
-
className: target.className,
|
|
66
123
|
uri,
|
|
67
124
|
error: error instanceof Error ? error.message : String(error),
|
|
68
125
|
});
|
|
69
126
|
}
|
|
70
127
|
}
|
|
71
|
-
|
|
72
|
-
let fallbackTraceId;
|
|
128
|
+
// 3. Fallback: list all trace requests
|
|
73
129
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
130
|
+
const reqResponse = await (0, profiler_1.listTraceRequests)(this.connection);
|
|
131
|
+
const traceId = (0, profiler_1.extractTraceIdFromTraceRequestsResponse)(reqResponse);
|
|
132
|
+
if (traceId) {
|
|
133
|
+
return {
|
|
134
|
+
response: runResponse,
|
|
135
|
+
profilerId,
|
|
136
|
+
traceId,
|
|
137
|
+
traceRequestsResponse: traceRequestsResponse ?? reqResponse,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
77
140
|
}
|
|
78
141
|
catch (error) {
|
|
79
|
-
this.logger?.debug?.('Trace requests list failed
|
|
80
|
-
className: target.className,
|
|
142
|
+
this.logger?.debug?.('Trace requests list failed', {
|
|
81
143
|
error: error instanceof Error ? error.message : String(error),
|
|
82
144
|
});
|
|
83
145
|
}
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const filesResponse = await (0, profiler_1.listTraceFiles)(this.connection);
|
|
87
|
-
fallbackTraceId =
|
|
88
|
-
(0, profiler_1.extractTraceIdFromTraceRequestsResponse)(filesResponse);
|
|
89
|
-
if (fallbackTraceId) {
|
|
90
|
-
fallbackResponse = filesResponse;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
this.logger?.debug?.('Trace files list also failed', {
|
|
95
|
-
className: target.className,
|
|
96
|
-
error: error instanceof Error ? error.message : String(error),
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (!fallbackTraceId) {
|
|
101
|
-
this.logger?.warn?.('Fallback trace response did not contain trace id', {
|
|
102
|
-
className: target.className,
|
|
103
|
-
});
|
|
104
|
-
throw new Error(`Failed to resolve traceId after profiled execution for class ${target.className}`);
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
response,
|
|
108
|
-
profilerId,
|
|
109
|
-
traceId: fallbackTraceId,
|
|
110
|
-
traceRequestsResponse: traceRequestsResponse ?? fallbackResponse,
|
|
111
|
-
};
|
|
146
|
+
return undefined;
|
|
112
147
|
}
|
|
113
148
|
async runWithProfilerId(className, profilerId) {
|
|
114
149
|
const encodedProfilerId = encodeURIComponent(profilerId);
|
|
@@ -73,9 +73,12 @@ export declare function getTraceDbAccesses(connection: IAbapConnection, traceIdO
|
|
|
73
73
|
* List trace files
|
|
74
74
|
*
|
|
75
75
|
* @param connection - ABAP connection
|
|
76
|
+
* @param options - Optional filters (user)
|
|
76
77
|
* @returns Axios response with list of trace files
|
|
77
78
|
*/
|
|
78
|
-
export declare function listTraceFiles(connection: IAbapConnection
|
|
79
|
+
export declare function listTraceFiles(connection: IAbapConnection, options?: {
|
|
80
|
+
user?: string;
|
|
81
|
+
}): Promise<AxiosResponse>;
|
|
79
82
|
/**
|
|
80
83
|
* Get trace parameters
|
|
81
84
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiler.d.ts","sourceRoot":"","sources":["../../../src/runtime/traces/profiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AASlC,MAAM,WAAW,wBAAwB;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,4BAA4B;IAC3C,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,+BAA+B;IAC9C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,+BAA+B;IAC9C,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,iCAAiC,EAAE,IAAI,CAClD,wBAAwB,EACxB,aAAa,CAed,CAAC;AAqCF,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKrE;AASD,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,wBAA6B,GACrC,MAAM,CA+CR;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,eAAe,EAC3B,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,aAAa,CAAC,CAaxB;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,aAAa,GACtB,MAAM,GAAG,SAAS,CAsBpB;AAKD,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,aAAa,GACtB,MAAM,GAAG,SAAS,CA6BpB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,aAAa,CAAC,CAgBxB;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,eAAe,EAC3B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,+BAAoC,GAC5C,OAAO,CAAC,aAAa,CAAC,CA6BxB;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,eAAe,EAC3B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,+BAAoC,GAC5C,OAAO,CAAC,aAAa,CAAC,CAgBxB;AAED
|
|
1
|
+
{"version":3,"file":"profiler.d.ts","sourceRoot":"","sources":["../../../src/runtime/traces/profiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -279,10 +279,16 @@ async function getTraceDbAccesses(connection, traceIdOrUri, options = {}) {
|
|
|
279
279
|
* List trace files
|
|
280
280
|
*
|
|
281
281
|
* @param connection - ABAP connection
|
|
282
|
+
* @param options - Optional filters (user)
|
|
282
283
|
* @returns Axios response with list of trace files
|
|
283
284
|
*/
|
|
284
|
-
async function listTraceFiles(connection) {
|
|
285
|
-
const
|
|
285
|
+
async function listTraceFiles(connection, options) {
|
|
286
|
+
const params = new URLSearchParams();
|
|
287
|
+
if (options?.user) {
|
|
288
|
+
params.set('user', options.user);
|
|
289
|
+
}
|
|
290
|
+
const qs = params.toString();
|
|
291
|
+
const url = `/sap/bc/adt/runtime/traces/abaptraces${qs ? `?${qs}` : ''}`;
|
|
286
292
|
return connection.makeAdtRequest({
|
|
287
293
|
url,
|
|
288
294
|
method: 'GET',
|