@mcp-abap-adt/adt-clients 5.6.0 → 5.7.1
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/core/functionInclude/delete.d.ts.map +1 -1
- package/dist/core/functionInclude/delete.js +43 -0
- package/dist/core/shared/AdtUtils.d.ts +20 -0
- package/dist/core/shared/AdtUtils.d.ts.map +1 -1
- package/dist/core/shared/AdtUtils.js +26 -0
- package/dist/core/shared/functionGroupIncludesList.d.ts +11 -0
- package/dist/core/shared/functionGroupIncludesList.d.ts.map +1 -0
- package/dist/core/shared/functionGroupIncludesList.js +7 -0
- package/dist/core/shared/functionGroupNodes.d.ts +23 -0
- package/dist/core/shared/functionGroupNodes.d.ts.map +1 -0
- package/dist/core/shared/functionGroupNodes.js +142 -0
- package/dist/core/shared/functionModulesList.d.ts +8 -0
- package/dist/core/shared/functionModulesList.d.ts.map +1 -0
- package/dist/core/shared/functionModulesList.js +7 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/core/functionInclude/delete.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/core/functionInclude/delete.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAgElC,MAAM,WAAW,4BAA4B;IAC3C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAQD;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,aAAa,CAAC,CAyBxB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,aAAa,CAAC,CA8CxB"}
|
|
@@ -5,9 +5,49 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.checkDeletion = checkDeletion;
|
|
7
7
|
exports.deleteFunctionInclude = deleteFunctionInclude;
|
|
8
|
+
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
8
9
|
const contentTypes_1 = require("../../constants/contentTypes");
|
|
9
10
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
10
11
|
const timeouts_1 = require("../../utils/timeouts");
|
|
12
|
+
/**
|
|
13
|
+
* Parse a `del:deletionResult` and throw if the server did not delete.
|
|
14
|
+
*
|
|
15
|
+
* The ADT deletion service answers HTTP 200 even when it refuses to delete:
|
|
16
|
+
* `<del:object del:isDeleted="false"><del:message del:type="E"><del:text>…`.
|
|
17
|
+
* Some function-group includes can only be removed via the Function Builder, so
|
|
18
|
+
* we MUST surface that instead of reporting a phantom success.
|
|
19
|
+
*/
|
|
20
|
+
function assertDeleted(responseData, includeName) {
|
|
21
|
+
const parser = new fast_xml_parser_1.XMLParser({
|
|
22
|
+
ignoreAttributes: false,
|
|
23
|
+
attributeNamePrefix: '@_',
|
|
24
|
+
});
|
|
25
|
+
let deleteObject;
|
|
26
|
+
try {
|
|
27
|
+
const result = parser.parse(String(responseData ?? ''));
|
|
28
|
+
const deletionResult = (result['del:deletionResult'] ??
|
|
29
|
+
result.deletionResult);
|
|
30
|
+
deleteObject = (deletionResult?.['del:object'] ??
|
|
31
|
+
deletionResult?.object);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Malformed/empty body — treat as a failed parse below.
|
|
35
|
+
deleteObject = undefined;
|
|
36
|
+
}
|
|
37
|
+
const isDeleted = deleteObject?.['@_del:isDeleted'] === 'true' ||
|
|
38
|
+
deleteObject?.['@_isDeleted'] === 'true';
|
|
39
|
+
if (isDeleted) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// `del:text` may be a plain string, or an object ({ '#text', atom:link }) when
|
|
43
|
+
// the message carries a longtext link — normalize both to the text.
|
|
44
|
+
const rawText = deleteObject?.['del:message']?.['del:text'] ??
|
|
45
|
+
deleteObject?.message?.text;
|
|
46
|
+
const message = typeof rawText === 'string'
|
|
47
|
+
? rawText
|
|
48
|
+
: rawText?.['#text'];
|
|
49
|
+
throw new Error(`Function include ${includeName} was not deleted${message ? `: ${message}` : ' (server reported isDeleted=false)'}`);
|
|
50
|
+
}
|
|
11
51
|
function objectUri(groupName, includeName) {
|
|
12
52
|
const groupLower = (0, internalUtils_1.encodeSapObjectName)(groupName).toLowerCase();
|
|
13
53
|
const encodedInclude = (0, internalUtils_1.encodeSapObjectName)(includeName.toUpperCase());
|
|
@@ -69,6 +109,9 @@ async function deleteFunctionInclude(connection, params) {
|
|
|
69
109
|
'Content-Type': contentTypes_1.CT_DELETION,
|
|
70
110
|
},
|
|
71
111
|
});
|
|
112
|
+
// The service returns HTTP 200 even when it refuses to delete; verify the
|
|
113
|
+
// result element instead of assuming success.
|
|
114
|
+
assertDeleted(response.data, params.include_name);
|
|
72
115
|
return {
|
|
73
116
|
...response,
|
|
74
117
|
data: {
|
|
@@ -368,6 +368,26 @@ export declare class AdtUtils {
|
|
|
368
368
|
* ```
|
|
369
369
|
*/
|
|
370
370
|
getIncludesList(objectName: string, objectType: 'PROG/P' | 'PROG/I' | 'FUGR' | 'CLAS/OC', timeout?: number): Promise<string[]>;
|
|
371
|
+
/**
|
|
372
|
+
* List the function modules of a function group.
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* const fms = await utils.listFunctionModules('ZMY_FUGR');
|
|
376
|
+
* // Returns: ['Z_MY_FM1', 'Z_MY_FM2']
|
|
377
|
+
*/
|
|
378
|
+
listFunctionModules(functionGroupName: string): Promise<string[]>;
|
|
379
|
+
/**
|
|
380
|
+
* List the includes of a function group (TOP, UXX collector, custom includes).
|
|
381
|
+
*
|
|
382
|
+
* Complements listFunctionModules: includes hold code that is not part of any
|
|
383
|
+
* function module (global data/types in TOP, FORM routines in custom includes),
|
|
384
|
+
* so a complete function-group backup needs them.
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* const includes = await utils.listFunctionGroupIncludes('ZMY_FUGR');
|
|
388
|
+
* // Returns: ['LZMY_FUGRTOP', 'LZMY_FUGRUXX', ...]
|
|
389
|
+
*/
|
|
390
|
+
listFunctionGroupIncludes(functionGroupName: string): Promise<string[]>;
|
|
371
391
|
/**
|
|
372
392
|
* Get package contents as raw XML
|
|
373
393
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtUtils.d.ts","sourceRoot":"","sources":["../../../src/core/shared/AdtUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EACf,OAAO,EACR,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"AdtUtils.d.ts","sourceRoot":"","sources":["../../../src/core/shared/AdtUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,6 +39,8 @@ const allTypes_1 = require("./allTypes");
|
|
|
39
39
|
const discovery_1 = require("./discovery");
|
|
40
40
|
const enhancementImpl_1 = require("./enhancementImpl");
|
|
41
41
|
const enhancements_1 = require("./enhancements");
|
|
42
|
+
const functionGroupIncludesList_1 = require("./functionGroupIncludesList");
|
|
43
|
+
const functionModulesList_1 = require("./functionModulesList");
|
|
42
44
|
const getInactiveObjects_1 = require("./getInactiveObjects");
|
|
43
45
|
const groupActivation_1 = require("./groupActivation");
|
|
44
46
|
const groupDeletion_1 = require("./groupDeletion");
|
|
@@ -479,6 +481,30 @@ class AdtUtils {
|
|
|
479
481
|
async getIncludesList(objectName, objectType, timeout = 30000) {
|
|
480
482
|
return (0, includesList_1.getIncludesList)(this.connection, objectName, objectType, timeout);
|
|
481
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* List the function modules of a function group.
|
|
486
|
+
*
|
|
487
|
+
* @example
|
|
488
|
+
* const fms = await utils.listFunctionModules('ZMY_FUGR');
|
|
489
|
+
* // Returns: ['Z_MY_FM1', 'Z_MY_FM2']
|
|
490
|
+
*/
|
|
491
|
+
async listFunctionModules(functionGroupName) {
|
|
492
|
+
return (0, functionModulesList_1.listFunctionModules)(this.connection, functionGroupName);
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* List the includes of a function group (TOP, UXX collector, custom includes).
|
|
496
|
+
*
|
|
497
|
+
* Complements listFunctionModules: includes hold code that is not part of any
|
|
498
|
+
* function module (global data/types in TOP, FORM routines in custom includes),
|
|
499
|
+
* so a complete function-group backup needs them.
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* const includes = await utils.listFunctionGroupIncludes('ZMY_FUGR');
|
|
503
|
+
* // Returns: ['LZMY_FUGRTOP', 'LZMY_FUGRUXX', ...]
|
|
504
|
+
*/
|
|
505
|
+
async listFunctionGroupIncludes(functionGroupName) {
|
|
506
|
+
return (0, functionGroupIncludesList_1.listFunctionGroupIncludes)(this.connection, functionGroupName);
|
|
507
|
+
}
|
|
482
508
|
/**
|
|
483
509
|
* Get package contents as raw XML
|
|
484
510
|
*
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List the includes of a function group via ADT node structure.
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper over listFunctionGroupChildren for the FUGR/I child type.
|
|
5
|
+
* Includes are the group's TOP include (global data/types), the UXX collector,
|
|
6
|
+
* and any custom includes (FORM routines, helpers) — code that is NOT part of
|
|
7
|
+
* any function module, so a complete FUGR backup needs them.
|
|
8
|
+
*/
|
|
9
|
+
import type { IAbapConnection } from '@mcp-abap-adt/interfaces';
|
|
10
|
+
export declare function listFunctionGroupIncludes(connection: IAbapConnection, functionGroupName: string): Promise<string[]>;
|
|
11
|
+
//# sourceMappingURL=functionGroupIncludesList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionGroupIncludesList.d.ts","sourceRoot":"","sources":["../../../src/core/shared/functionGroupIncludesList.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGhE,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listFunctionGroupIncludes = listFunctionGroupIncludes;
|
|
4
|
+
const functionGroupNodes_1 = require("./functionGroupNodes");
|
|
5
|
+
async function listFunctionGroupIncludes(connection, functionGroupName) {
|
|
6
|
+
return (0, functionGroupNodes_1.listFunctionGroupChildren)(connection, functionGroupName, 'FUGR/I');
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumerate the children of a function group via ADT node structure.
|
|
3
|
+
*
|
|
4
|
+
* The package/include APIs do not surface a function group's children; only a
|
|
5
|
+
* two-step nodestructure drill-down does (root -> child-type node -> names).
|
|
6
|
+
* This is the shared core behind listFunctionModules (FUGR/FF) and
|
|
7
|
+
* listFunctionGroupIncludes (FUGR/I).
|
|
8
|
+
*/
|
|
9
|
+
import type { IAbapConnection } from '@mcp-abap-adt/interfaces';
|
|
10
|
+
/** Function-group child node types reachable via the drill-down. */
|
|
11
|
+
export type FunctionGroupChildType = 'FUGR/FF' | 'FUGR/I';
|
|
12
|
+
/**
|
|
13
|
+
* List the children of a function group that match a given ADT object type.
|
|
14
|
+
*
|
|
15
|
+
* @param connection - ABAP connection
|
|
16
|
+
* @param functionGroupName - Function group name (case-insensitive)
|
|
17
|
+
* @param childType - Child node type to enumerate ('FUGR/FF' modules, 'FUGR/I' includes)
|
|
18
|
+
* @returns Child object names, deduped by uppercased key (first occurrence wins,
|
|
19
|
+
* document order preserved). `[]` for a valid-empty result; throws on a
|
|
20
|
+
* malformed, non-2xx, or wrong-shape response.
|
|
21
|
+
*/
|
|
22
|
+
export declare function listFunctionGroupChildren(connection: IAbapConnection, functionGroupName: string, childType: FunctionGroupChildType): Promise<string[]>;
|
|
23
|
+
//# sourceMappingURL=functionGroupNodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionGroupNodes.d.ts","sourceRoot":"","sources":["../../../src/core/shared/functionGroupNodes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE,oEAAoE;AACpE,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,QAAQ,CAAC;AA+G1D;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,sBAAsB,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CA0EnB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listFunctionGroupChildren = listFunctionGroupChildren;
|
|
4
|
+
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
5
|
+
const nodeStructure_1 = require("./nodeStructure");
|
|
6
|
+
// NODE_ID values are zero-padded ("000007"); value coercion would turn them
|
|
7
|
+
// into numbers and lose the zeros, so it is disabled here.
|
|
8
|
+
const parser = new fast_xml_parser_1.XMLParser({
|
|
9
|
+
ignoreAttributes: false,
|
|
10
|
+
attributeNamePrefix: '',
|
|
11
|
+
parseAttributeValue: false,
|
|
12
|
+
parseTagValue: false,
|
|
13
|
+
trimValues: true,
|
|
14
|
+
});
|
|
15
|
+
// True only for a single element record. Arrays are excluded: the parser
|
|
16
|
+
// represents structurally-invalid duplicate containers (two <DATA/>, two
|
|
17
|
+
// <TREE_CONTENT>, two <OBJECT_TYPES>) as arrays, which must be rejected as a
|
|
18
|
+
// wrong shape, not silently treated as empty. Legitimate repeated entries
|
|
19
|
+
// (multiple SEU_ADT_* nodes) are arrays handled by asArray, not isObject.
|
|
20
|
+
function isObject(v) {
|
|
21
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
22
|
+
}
|
|
23
|
+
// fetchNodeStructure may resolve (not reject) on a non-2xx depending on the
|
|
24
|
+
// connection's validateStatus; guard explicitly so a non-2xx never yields [].
|
|
25
|
+
function assertOk(res, context) {
|
|
26
|
+
const status = res?.status;
|
|
27
|
+
if (typeof status === 'number' && (status < 200 || status >= 300)) {
|
|
28
|
+
throw new Error(`Node structure request failed (${context}): HTTP ${status}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function parseValidated(xml, context) {
|
|
32
|
+
// Layer 1: well-formedness. fast-xml-parser tolerates malformed input, so
|
|
33
|
+
// reject it explicitly before parsing.
|
|
34
|
+
const validation = fast_xml_parser_1.XMLValidator.validate(xml);
|
|
35
|
+
if (validation !== true) {
|
|
36
|
+
throw new Error(`Invalid node structure XML (${context}): ${validation.err?.msg ?? 'malformed'}`);
|
|
37
|
+
}
|
|
38
|
+
return parser.parse(xml);
|
|
39
|
+
}
|
|
40
|
+
function asArray(v) {
|
|
41
|
+
return v === undefined || v === null ? [] : Array.isArray(v) ? v : [v];
|
|
42
|
+
}
|
|
43
|
+
// Read the node list inside a container element (OBJECT_TYPES / TREE_CONTENT).
|
|
44
|
+
// An absent container or an empty one (`<TREE_CONTENT/>` -> "") is valid-empty
|
|
45
|
+
// -> []. Any other scalar (`<TREE_CONTENT>error</TREE_CONTENT>` -> "error") is an
|
|
46
|
+
// unexpected shape and must throw rather than be silently treated as empty.
|
|
47
|
+
//
|
|
48
|
+
// The same applies one level deeper: each inner entry (SEU_ADT_OBJECT_TYPE_INFO /
|
|
49
|
+
// SEU_ADT_REPOSITORY_OBJ_NODE) must be an element. A scalar entry (e.g.
|
|
50
|
+
// `<SEU_ADT_OBJECT_TYPE_INFO>error</...>`) would otherwise be silently skipped
|
|
51
|
+
// (no OBJECT_TYPE -> no match), yielding a wrong [] instead of a throw.
|
|
52
|
+
function extractNodeList(container, innerKey, containerName, context) {
|
|
53
|
+
if (container === undefined || container === null || container === '') {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
if (!isObject(container)) {
|
|
57
|
+
throw new Error(`Unexpected node structure (${context}): ${containerName} is not an element`);
|
|
58
|
+
}
|
|
59
|
+
const list = asArray(container[innerKey]);
|
|
60
|
+
for (const item of list) {
|
|
61
|
+
if (!isObject(item)) {
|
|
62
|
+
throw new Error(`Unexpected node structure (${context}): ${containerName} contains a non-element entry`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return list;
|
|
66
|
+
}
|
|
67
|
+
// Layer 2: expected structure. XMLValidator only proves well-formedness; a
|
|
68
|
+
// valid <html/> error page or bare <asx:abap/> would pass it and be misread as
|
|
69
|
+
// "no children". Assert the asx:abap -> asx:values -> DATA chain of KEYS is
|
|
70
|
+
// present and throw if absent. DATA itself may be empty: an empty <DATA/> is
|
|
71
|
+
// parsed as "" and is a valid-empty payload (e.g. a drill with no TREE_CONTENT)
|
|
72
|
+
// -> normalize to {}. Any other scalar DATA is an unexpected shape -> throw.
|
|
73
|
+
function dataNode(parsed, context) {
|
|
74
|
+
const abap = parsed?.['asx:abap'];
|
|
75
|
+
const values = isObject(abap) ? abap['asx:values'] : undefined;
|
|
76
|
+
if (!isObject(values) || !('DATA' in values)) {
|
|
77
|
+
throw new Error(`Unexpected node structure (${context}): missing asx:abap/asx:values/DATA envelope`);
|
|
78
|
+
}
|
|
79
|
+
const data = values.DATA;
|
|
80
|
+
if (data === '') {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
if (!isObject(data)) {
|
|
84
|
+
throw new Error(`Unexpected node structure (${context}): DATA is not an element`);
|
|
85
|
+
}
|
|
86
|
+
return data;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* List the children of a function group that match a given ADT object type.
|
|
90
|
+
*
|
|
91
|
+
* @param connection - ABAP connection
|
|
92
|
+
* @param functionGroupName - Function group name (case-insensitive)
|
|
93
|
+
* @param childType - Child node type to enumerate ('FUGR/FF' modules, 'FUGR/I' includes)
|
|
94
|
+
* @returns Child object names, deduped by uppercased key (first occurrence wins,
|
|
95
|
+
* document order preserved). `[]` for a valid-empty result; throws on a
|
|
96
|
+
* malformed, non-2xx, or wrong-shape response.
|
|
97
|
+
*/
|
|
98
|
+
async function listFunctionGroupChildren(connection, functionGroupName, childType) {
|
|
99
|
+
if (!functionGroupName) {
|
|
100
|
+
throw new Error('Function group name is required');
|
|
101
|
+
}
|
|
102
|
+
const name = functionGroupName.toUpperCase();
|
|
103
|
+
// Root: find the child-type node id (string, leading zeros preserved).
|
|
104
|
+
const rootRes = await (0, nodeStructure_1.fetchNodeStructure)(connection, 'FUGR/F', name, '000000', true);
|
|
105
|
+
assertOk(rootRes, `root ${name}`);
|
|
106
|
+
const rootData = dataNode(parseValidated(String(rootRes.data), `root ${name}`), `root ${name}`);
|
|
107
|
+
// A genuine FUGR node structure always returns its type catalog. Its complete
|
|
108
|
+
// absence (no key) means we did not get a node structure (e.g. an error
|
|
109
|
+
// envelope) -> throw. An empty `<OBJECT_TYPES/>` is parsed as "" — the key is
|
|
110
|
+
// present, there is simply no matching child -> [] (valid-empty, not an error).
|
|
111
|
+
// So check for KEY presence, not object type.
|
|
112
|
+
if (!('OBJECT_TYPES' in rootData)) {
|
|
113
|
+
throw new Error(`Unexpected node structure (root ${name}): missing OBJECT_TYPES`);
|
|
114
|
+
}
|
|
115
|
+
const types = extractNodeList(rootData.OBJECT_TYPES, 'SEU_ADT_OBJECT_TYPE_INFO', 'OBJECT_TYPES', `root ${name}`);
|
|
116
|
+
const typeInfo = types.find((t) => t?.OBJECT_TYPE === childType);
|
|
117
|
+
const nodeId = typeInfo?.NODE_ID;
|
|
118
|
+
if (typeof nodeId !== 'string' || nodeId === '') {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
// Drill: read the child OBJECT_NAMEs.
|
|
122
|
+
const drillRes = await (0, nodeStructure_1.fetchNodeStructure)(connection, 'FUGR/F', name, nodeId, true);
|
|
123
|
+
assertOk(drillRes, `drill ${name}`);
|
|
124
|
+
const drillData = dataNode(parseValidated(String(drillRes.data), `drill ${name}`), `drill ${name}`);
|
|
125
|
+
const nodes = extractNodeList(drillData.TREE_CONTENT, 'SEU_ADT_REPOSITORY_OBJ_NODE', 'TREE_CONTENT', `drill ${name}`);
|
|
126
|
+
const seen = new Set();
|
|
127
|
+
const result = [];
|
|
128
|
+
for (const node of nodes) {
|
|
129
|
+
if (node?.OBJECT_TYPE !== childType)
|
|
130
|
+
continue;
|
|
131
|
+
const objName = node?.OBJECT_NAME;
|
|
132
|
+
if (typeof objName !== 'string' || objName.trim() === '')
|
|
133
|
+
continue;
|
|
134
|
+
const child = objName.trim();
|
|
135
|
+
const key = child.toUpperCase();
|
|
136
|
+
if (seen.has(key))
|
|
137
|
+
continue;
|
|
138
|
+
seen.add(key);
|
|
139
|
+
result.push(child);
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List the function modules of a function group via ADT node structure.
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper over listFunctionGroupChildren for the FUGR/FF child type.
|
|
5
|
+
*/
|
|
6
|
+
import type { IAbapConnection } from '@mcp-abap-adt/interfaces';
|
|
7
|
+
export declare function listFunctionModules(connection: IAbapConnection, functionGroupName: string): Promise<string[]>;
|
|
8
|
+
//# sourceMappingURL=functionModulesList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionModulesList.d.ts","sourceRoot":"","sources":["../../../src/core/shared/functionModulesList.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGhE,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,eAAe,EAC3B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listFunctionModules = listFunctionModules;
|
|
4
|
+
const functionGroupNodes_1 = require("./functionGroupNodes");
|
|
5
|
+
async function listFunctionModules(connection, functionGroupName) {
|
|
6
|
+
return (0, functionGroupNodes_1.listFunctionGroupChildren)(connection, functionGroupName, 'FUGR/FF');
|
|
7
|
+
}
|