@st-gr/abap-adt-skill 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +79 -0
- package/dist/commands/activate.js +58 -0
- package/dist/commands/atc.js +39 -0
- package/dist/commands/classinfo.js +33 -0
- package/dist/commands/completion.js +57 -0
- package/dist/commands/create.js +69 -0
- package/dist/commands/debug.js +217 -0
- package/dist/commands/definition.js +66 -0
- package/dist/commands/delete.js +36 -0
- package/dist/commands/exec.js +112 -0
- package/dist/commands/package.js +24 -0
- package/dist/commands/pretty-print.js +57 -0
- package/dist/commands/quickfix.js +78 -0
- package/dist/commands/read.js +31 -0
- package/dist/commands/rename.js +40 -0
- package/dist/commands/run.js +16 -0
- package/dist/commands/search.js +25 -0
- package/dist/commands/structure.js +39 -0
- package/dist/commands/syntax.js +75 -0
- package/dist/commands/systems.js +514 -0
- package/dist/commands/table.js +65 -0
- package/dist/commands/test.js +100 -0
- package/dist/commands/transport.js +110 -0
- package/dist/commands/users.js +19 -0
- package/dist/commands/whereused.js +30 -0
- package/dist/commands/write.js +131 -0
- package/dist/diag-debug.js +47 -0
- package/dist/diag-raw.js +144 -0
- package/dist/diag-write.js +42 -0
- package/dist/index.js +336 -0
- package/dist/test-write.js +69 -0
- package/dist/util/credentials.js +42 -0
- package/dist/util/error-handler.js +39 -0
- package/dist/util/formatter.js +27 -0
- package/dist/util/landscape.js +121 -0
- package/dist/util/network.js +112 -0
- package/package.json +24 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStatelessClient = getStatelessClient;
|
|
4
|
+
exports.getClient = getClient;
|
|
5
|
+
exports.withStatefulSession = withStatefulSession;
|
|
6
|
+
const abap_adt_api_patched_1 = require("@st-gr/abap-adt-api-patched");
|
|
7
|
+
const network_1 = require("./util/network");
|
|
8
|
+
const systems_1 = require("./commands/systems");
|
|
9
|
+
const credentials_1 = require("./util/credentials");
|
|
10
|
+
let client;
|
|
11
|
+
let statelessClient;
|
|
12
|
+
async function getStatelessClient() {
|
|
13
|
+
if (statelessClient)
|
|
14
|
+
return statelessClient;
|
|
15
|
+
const c = await getClient();
|
|
16
|
+
statelessClient = c.statelessClone;
|
|
17
|
+
return statelessClient;
|
|
18
|
+
}
|
|
19
|
+
async function getClient() {
|
|
20
|
+
var _a;
|
|
21
|
+
if (client)
|
|
22
|
+
return client;
|
|
23
|
+
// Load connection: env vars take precedence, then fall back to ~/.sap/adt-connection.json
|
|
24
|
+
const conn = (0, systems_1.loadConnection)();
|
|
25
|
+
const url = process.env.ADT_URL || (conn === null || conn === void 0 ? void 0 : conn.url) || "";
|
|
26
|
+
const defaultUser = (process.env.USERNAME || process.env.USER || "").toUpperCase();
|
|
27
|
+
const user = process.env.ADT_USER || (conn === null || conn === void 0 ? void 0 : conn.user) || defaultUser;
|
|
28
|
+
let pass = process.env.ADT_PASS || "";
|
|
29
|
+
const sapClient = process.env.ADT_CLIENT || (conn === null || conn === void 0 ? void 0 : conn.client) || "";
|
|
30
|
+
const language = process.env.ADT_LANGUAGE || (conn === null || conn === void 0 ? void 0 : conn.language) || "EN";
|
|
31
|
+
const allowSelfSigned = process.env.ADT_ALLOW_SELF_SIGNED !== undefined
|
|
32
|
+
? process.env.ADT_ALLOW_SELF_SIGNED !== "false"
|
|
33
|
+
: (_a = conn === null || conn === void 0 ? void 0 : conn.allowSelfSigned) !== null && _a !== void 0 ? _a : true;
|
|
34
|
+
// Decrypt stored password if no ADT_PASS env var
|
|
35
|
+
if (!pass && (conn === null || conn === void 0 ? void 0 : conn.encryptedPassword) && (0, credentials_1.isWindows)()) {
|
|
36
|
+
try {
|
|
37
|
+
pass = (0, credentials_1.decryptDPAPI)(conn.encryptedPassword);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error(`Warning: Failed to decrypt stored password: ${err.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!url || !user) {
|
|
44
|
+
console.error(`Error: No connection configured.`);
|
|
45
|
+
console.error(`Run 'abap-adt systems connect <SID> [client]' first, or set ADT_URL + ADT_USER env vars.`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (!pass) {
|
|
49
|
+
const shell = (process.env.SHELL || process.env.ComSpec || "").toLowerCase();
|
|
50
|
+
const isPosh = shell.includes("powershell") || shell.includes("pwsh") || !!process.env.PSModulePath;
|
|
51
|
+
const isCmd = !isPosh && shell.includes("cmd");
|
|
52
|
+
const example = isPosh ? '$env:ADT_PASS = "<your_password>"'
|
|
53
|
+
: isCmd ? 'set ADT_PASS=<your_password>'
|
|
54
|
+
: 'export ADT_PASS="<your_password>"';
|
|
55
|
+
console.error(`Error: No password. Set ADT_PASS or run 'abap-adt systems connect' to store credentials.`);
|
|
56
|
+
console.error(` ${example}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const options = allowSelfSigned ? (0, abap_adt_api_patched_1.createSSLConfig)(true) : {};
|
|
60
|
+
// VPN safety: verify private IP before sending credentials over HTTP
|
|
61
|
+
if (url.startsWith("http://")) {
|
|
62
|
+
const hostname = new URL(url).hostname;
|
|
63
|
+
await (0, network_1.assertPrivateHost)(hostname);
|
|
64
|
+
}
|
|
65
|
+
client = new abap_adt_api_patched_1.ADTClient(url, user, pass, sapClient, language, options);
|
|
66
|
+
await client.login();
|
|
67
|
+
return client;
|
|
68
|
+
}
|
|
69
|
+
async function withStatefulSession(fn) {
|
|
70
|
+
const c = await getClient();
|
|
71
|
+
c.stateful = abap_adt_api_patched_1.session_types.stateful;
|
|
72
|
+
try {
|
|
73
|
+
return await fn(c);
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
c.stateful = abap_adt_api_patched_1.session_types.stateless;
|
|
77
|
+
c.dropSession();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.activateCommand = activateCommand;
|
|
4
|
+
exports.inactiveObjectsCommand = inactiveObjectsCommand;
|
|
5
|
+
const client_1 = require("../client");
|
|
6
|
+
const formatter_1 = require("../util/formatter");
|
|
7
|
+
async function activateCommand(objectName, objectUrl, options) {
|
|
8
|
+
const client = await (0, client_1.getClient)();
|
|
9
|
+
const result = await client.activate(objectName, objectUrl);
|
|
10
|
+
if (options.json) {
|
|
11
|
+
(0, formatter_1.output)(result, true);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (result.success) {
|
|
15
|
+
console.log(`Activation successful: ${objectName}`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.log(`Activation failed: ${objectName}`);
|
|
19
|
+
}
|
|
20
|
+
if (result.messages && result.messages.length > 0) {
|
|
21
|
+
console.log("\nMessages:");
|
|
22
|
+
for (const msg of result.messages) {
|
|
23
|
+
const severity = msg.type || "I";
|
|
24
|
+
const line = msg.line ? `:${msg.line}` : "";
|
|
25
|
+
console.log(` [${severity}]${line} ${msg.shortText}`);
|
|
26
|
+
if (msg.href)
|
|
27
|
+
console.log(` ${msg.href}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (result.inactive && result.inactive.length > 0) {
|
|
31
|
+
console.log("\nRemaining inactive objects:");
|
|
32
|
+
for (const obj of result.inactive) {
|
|
33
|
+
if (obj.object) {
|
|
34
|
+
console.log(` ${obj.object["adtcore:name"]} (${obj.object["adtcore:type"]})`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!result.success)
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
async function inactiveObjectsCommand(options) {
|
|
42
|
+
const client = await (0, client_1.getClient)();
|
|
43
|
+
const objects = await client.inactiveObjects();
|
|
44
|
+
if (options.json) {
|
|
45
|
+
(0, formatter_1.output)(objects, true);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (objects.length === 0) {
|
|
49
|
+
console.log("No inactive objects.");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log("Inactive objects:");
|
|
53
|
+
for (const record of objects) {
|
|
54
|
+
if (record.object) {
|
|
55
|
+
console.log(` ${record.object["adtcore:name"]} (${record.object["adtcore:type"]}) - ${record.object["adtcore:uri"]}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.atcRunCommand = atcRunCommand;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
const formatter_1 = require("../util/formatter");
|
|
6
|
+
async function atcRunCommand(objectUrl, options) {
|
|
7
|
+
const client = await (0, client_1.getClient)();
|
|
8
|
+
const variant = options.variant || "DEFAULT";
|
|
9
|
+
const maxResults = options.max ? parseInt(options.max, 10) : undefined;
|
|
10
|
+
// Create ATC run
|
|
11
|
+
const runResult = await client.createAtcRun(variant, objectUrl, maxResults);
|
|
12
|
+
// Get worklist
|
|
13
|
+
const worklist = await client.atcWorklists(runResult.id);
|
|
14
|
+
if (options.json) {
|
|
15
|
+
(0, formatter_1.output)(worklist, true);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!worklist.objects || worklist.objects.length === 0) {
|
|
19
|
+
console.log("ATC check: No findings.");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log(`ATC Run ID: ${runResult.id}`);
|
|
23
|
+
console.log(`Timestamp: ${worklist.timestamp || ""}`);
|
|
24
|
+
console.log();
|
|
25
|
+
for (const obj of worklist.objects) {
|
|
26
|
+
console.log(`Object: ${obj.name} (${obj.type})`);
|
|
27
|
+
if (obj.findings) {
|
|
28
|
+
for (const finding of obj.findings) {
|
|
29
|
+
const prio = finding.priority || "";
|
|
30
|
+
const check = finding.checkId || "";
|
|
31
|
+
const msg = finding.messageTitle || "";
|
|
32
|
+
const loc = finding.location ? ` at ${finding.location.uri}` : "";
|
|
33
|
+
console.log(` [P${prio}] ${check}: ${msg}${loc}`);
|
|
34
|
+
if (finding.uri)
|
|
35
|
+
console.log(` URI: ${finding.uri}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.classinfoCommand = classinfoCommand;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
async function classinfoCommand(objectUrl, options) {
|
|
6
|
+
const client = await (0, client_1.getStatelessClient)();
|
|
7
|
+
const root = await client.classComponents(objectUrl);
|
|
8
|
+
if (options.json) {
|
|
9
|
+
console.log(JSON.stringify(root, null, 2));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
printComponent(root, 0);
|
|
13
|
+
}
|
|
14
|
+
function printComponent(comp, depth) {
|
|
15
|
+
const indent = " ".repeat(depth);
|
|
16
|
+
const name = comp["adtcore:name"] || "";
|
|
17
|
+
const type = comp["adtcore:type"] || "";
|
|
18
|
+
const desc = comp["adtcore:description"] || "";
|
|
19
|
+
const visibility = comp["abapsource:visibility"] || "";
|
|
20
|
+
const parts = [name];
|
|
21
|
+
if (type)
|
|
22
|
+
parts.push(`(${type})`);
|
|
23
|
+
if (visibility)
|
|
24
|
+
parts.push(`[${visibility}]`);
|
|
25
|
+
if (desc)
|
|
26
|
+
parts.push(`— ${desc}`);
|
|
27
|
+
console.log(`${indent}${parts.join(" ")}`);
|
|
28
|
+
if (comp.components) {
|
|
29
|
+
for (const child of comp.components) {
|
|
30
|
+
printComponent(child, depth + 1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.completionCommand = completionCommand;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const client_1 = require("../client");
|
|
39
|
+
async function completionCommand(sourceUrl, options) {
|
|
40
|
+
const client = await (0, client_1.getStatelessClient)();
|
|
41
|
+
const source = fs.readFileSync(options.sourceFile, "utf-8");
|
|
42
|
+
const line = parseInt(options.line);
|
|
43
|
+
const column = parseInt(options.column);
|
|
44
|
+
const proposals = await client.codeCompletion(sourceUrl, source, line, column);
|
|
45
|
+
if (options.json) {
|
|
46
|
+
console.log(JSON.stringify(proposals, null, 2));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (proposals.length === 0) {
|
|
50
|
+
console.log("No completions available.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
console.log(`${proposals.length} completion(s):\n`);
|
|
54
|
+
for (const p of proposals) {
|
|
55
|
+
console.log(` ${p.IDENTIFIER}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCommand = createCommand;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
const TYPE_ALIASES = {
|
|
6
|
+
"program": "PROG/P",
|
|
7
|
+
"prog": "PROG/P",
|
|
8
|
+
"class": "CLAS/OC",
|
|
9
|
+
"clas": "CLAS/OC",
|
|
10
|
+
"interface": "INTF/OI",
|
|
11
|
+
"intf": "INTF/OI",
|
|
12
|
+
"function-group": "FUGR/F",
|
|
13
|
+
"fugr": "FUGR/F",
|
|
14
|
+
"function-module": "FUGR/FF",
|
|
15
|
+
"include": "PROG/I",
|
|
16
|
+
"table": "TABL/DT",
|
|
17
|
+
"tabl": "TABL/DT",
|
|
18
|
+
"structure": "TABL/DS",
|
|
19
|
+
"cds": "DDLS/DF",
|
|
20
|
+
"ddls": "DDLS/DF",
|
|
21
|
+
"data-element": "DTEL/DE",
|
|
22
|
+
"dtel": "DTEL/DE",
|
|
23
|
+
"domain": "DOMA/DD",
|
|
24
|
+
"doma": "DOMA/DD",
|
|
25
|
+
"package": "DEVC/K",
|
|
26
|
+
"devc": "DEVC/K",
|
|
27
|
+
"message-class": "MSAG/N",
|
|
28
|
+
"msag": "MSAG/N",
|
|
29
|
+
"dcls": "DCLS/DL",
|
|
30
|
+
"ddlx": "DDLX/EX",
|
|
31
|
+
"service-definition": "SRVD/SRV",
|
|
32
|
+
"service-binding": "SRVB/SVB"
|
|
33
|
+
};
|
|
34
|
+
function resolveType(input) {
|
|
35
|
+
const lower = input.toLowerCase();
|
|
36
|
+
if (TYPE_ALIASES[lower])
|
|
37
|
+
return TYPE_ALIASES[lower];
|
|
38
|
+
// Try as raw type ID (e.g. "CLAS/OC")
|
|
39
|
+
if (input.includes("/"))
|
|
40
|
+
return input;
|
|
41
|
+
console.error(`Unknown type: ${input}`);
|
|
42
|
+
console.error(`Available types: ${Object.keys(TYPE_ALIASES).join(", ")}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
async function createCommand(type, name, options) {
|
|
46
|
+
const client = await (0, client_1.getClient)();
|
|
47
|
+
const objtype = resolveType(type);
|
|
48
|
+
let parentName;
|
|
49
|
+
let parentPath;
|
|
50
|
+
if (objtype === "FUGR/FF" || objtype === "FUGR/I") {
|
|
51
|
+
// Function modules/includes: parent is the function group, not the package
|
|
52
|
+
const fugr = options.functionGroup || options.package;
|
|
53
|
+
if (!fugr) {
|
|
54
|
+
console.error("Error: --function-group (or --package with function group name) is required for function modules");
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
parentName = fugr.toUpperCase();
|
|
58
|
+
parentPath = options.parentPath || `/sap/bc/adt/functions/groups/${encodeURIComponent(parentName.toLowerCase())}`;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
parentName = options.package.toUpperCase();
|
|
62
|
+
parentPath = options.parentPath || `/sap/bc/adt/packages/${encodeURIComponent(parentName.toLowerCase())}`;
|
|
63
|
+
}
|
|
64
|
+
await client.createObject(objtype, name.toUpperCase(), parentName, options.description, parentPath, options.responsible || "", options.transport || "");
|
|
65
|
+
console.log(`Created ${objtype} ${name.toUpperCase()} in ${parentName}`);
|
|
66
|
+
if (options.transport) {
|
|
67
|
+
console.log(`Transport: ${options.transport}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.debugListenCommand = debugListenCommand;
|
|
37
|
+
exports.debugAttachCommand = debugAttachCommand;
|
|
38
|
+
exports.debugBreakpointsCommand = debugBreakpointsCommand;
|
|
39
|
+
exports.debugStepCommand = debugStepCommand;
|
|
40
|
+
exports.debugStackCommand = debugStackCommand;
|
|
41
|
+
exports.debugVariablesCommand = debugVariablesCommand;
|
|
42
|
+
exports.debugChildVariablesCommand = debugChildVariablesCommand;
|
|
43
|
+
const crypto = __importStar(require("crypto"));
|
|
44
|
+
const abap_adt_api_patched_1 = require("@st-gr/abap-adt-api-patched");
|
|
45
|
+
const client_1 = require("../client");
|
|
46
|
+
const formatter_1 = require("../util/formatter");
|
|
47
|
+
function generateId() {
|
|
48
|
+
return crypto.randomUUID().toUpperCase();
|
|
49
|
+
}
|
|
50
|
+
// Store debug session IDs in environment for continuity across CLI invocations
|
|
51
|
+
function getTerminalId() {
|
|
52
|
+
return process.env.ADT_TERMINAL_ID || generateId();
|
|
53
|
+
}
|
|
54
|
+
function getIdeId() {
|
|
55
|
+
return process.env.ADT_IDE_ID || generateId();
|
|
56
|
+
}
|
|
57
|
+
async function debugListenCommand(options) {
|
|
58
|
+
const mode = (options.mode || "user");
|
|
59
|
+
const terminalId = getTerminalId();
|
|
60
|
+
const ideId = getIdeId();
|
|
61
|
+
console.error(`Terminal ID: ${terminalId}`);
|
|
62
|
+
console.error(`IDE ID: ${ideId}`);
|
|
63
|
+
console.error(`Mode: ${mode}`);
|
|
64
|
+
console.error("Waiting for debuggee... (set a breakpoint in SAP and run the program)");
|
|
65
|
+
await (0, client_1.withStatefulSession)(async (client) => {
|
|
66
|
+
const user = options.user || client.username;
|
|
67
|
+
const result = await client.debuggerListen(mode, terminalId, ideId, user);
|
|
68
|
+
if (!result) {
|
|
69
|
+
console.log("No debuggee found (timeout or no breakpoint hit).");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if ((0, abap_adt_api_patched_1.isDebugListenerError)(result)) {
|
|
73
|
+
console.error(`Debug listener error: ${result.message.text}`);
|
|
74
|
+
if (result.conflictText) {
|
|
75
|
+
console.error(`Conflict: ${result.conflictText}`);
|
|
76
|
+
}
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
if ((0, abap_adt_api_patched_1.isDebuggee)(result)) {
|
|
80
|
+
if (options.json) {
|
|
81
|
+
(0, formatter_1.output)(result, true);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
console.log(`\nDebuggee found!`);
|
|
85
|
+
console.log(` Debuggee ID: ${result.DEBUGGEE_ID}`);
|
|
86
|
+
console.log(` User: ${result.DEBUGGEE_USER}`);
|
|
87
|
+
console.log(` Program: ${result.PRG_CURR}`);
|
|
88
|
+
console.log(` Include: ${result.INCL_CURR}`);
|
|
89
|
+
console.log(` Line: ${result.LINE_CURR}`);
|
|
90
|
+
console.log(` Terminal ID: ${terminalId}`);
|
|
91
|
+
console.log(` IDE ID: ${ideId}`);
|
|
92
|
+
console.log(`\nTo attach: debug attach ${result.DEBUGGEE_ID} --terminal-id ${terminalId} --ide-id ${ideId}`);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
async function debugAttachCommand(debuggeeId, options) {
|
|
97
|
+
const mode = (options.mode || "user");
|
|
98
|
+
await (0, client_1.withStatefulSession)(async (client) => {
|
|
99
|
+
const user = options.user || client.username;
|
|
100
|
+
const result = await client.debuggerAttach(mode, debuggeeId, user);
|
|
101
|
+
if (options.json) {
|
|
102
|
+
(0, formatter_1.output)(result, true);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
console.log(`Attached to debuggee: ${debuggeeId}`);
|
|
106
|
+
console.log(` Session: ${result.debugSessionId}`);
|
|
107
|
+
console.log(` Stepping possible: ${result.isSteppingPossible}`);
|
|
108
|
+
if (result.reachedBreakpoints && result.reachedBreakpoints.length > 0) {
|
|
109
|
+
console.log(` Reached breakpoints:`);
|
|
110
|
+
for (const bp of result.reachedBreakpoints) {
|
|
111
|
+
console.log(` ${bp.id} (${bp.kind})`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
console.log(`\nAvailable actions:`);
|
|
115
|
+
for (const action of result.actions) {
|
|
116
|
+
if (!action.disabled) {
|
|
117
|
+
console.log(` ${action.name}: ${action.title}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async function debugBreakpointsCommand(uri, options) {
|
|
123
|
+
const mode = (options.mode || "user");
|
|
124
|
+
const terminalId = options.terminalId || getTerminalId();
|
|
125
|
+
const ideId = options.ideId || getIdeId();
|
|
126
|
+
const clientId = options.clientId || generateId();
|
|
127
|
+
const client = await (0, client_1.getClient)();
|
|
128
|
+
const user = options.user || client.username;
|
|
129
|
+
const result = await client.debuggerSetBreakpoints(mode, terminalId, ideId, clientId, [uri], user);
|
|
130
|
+
if (options.json) {
|
|
131
|
+
(0, formatter_1.output)(result, true);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (const bp of result) {
|
|
135
|
+
if ("uri" in bp) {
|
|
136
|
+
console.log(`Breakpoint set: ${bp.id} at ${bp.uri.uri} (${bp.kind})`);
|
|
137
|
+
}
|
|
138
|
+
else if ("errorMessage" in bp) {
|
|
139
|
+
console.error(`Breakpoint error: ${bp.errorMessage}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function debugStepCommand(stepType, options) {
|
|
144
|
+
await (0, client_1.withStatefulSession)(async (client) => {
|
|
145
|
+
const result = options.uri
|
|
146
|
+
? await client.debuggerStep(stepType, options.uri)
|
|
147
|
+
: await client.debuggerStep(stepType);
|
|
148
|
+
if (options.json) {
|
|
149
|
+
(0, formatter_1.output)(result, true);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
console.log(`Step: ${stepType}`);
|
|
153
|
+
console.log(` Session: ${result.debugSessionId}`);
|
|
154
|
+
console.log(` Stepping possible: ${result.isSteppingPossible}`);
|
|
155
|
+
if (result.reachedBreakpoints && result.reachedBreakpoints.length > 0) {
|
|
156
|
+
console.log(` Reached breakpoints:`);
|
|
157
|
+
for (const bp of result.reachedBreakpoints) {
|
|
158
|
+
console.log(` ${bp.id} (${bp.kind})`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
async function debugStackCommand(options) {
|
|
164
|
+
await (0, client_1.withStatefulSession)(async (client) => {
|
|
165
|
+
const result = await client.debuggerStackTrace();
|
|
166
|
+
if (options.json) {
|
|
167
|
+
(0, formatter_1.output)(result, true);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
console.log(`Stack (RFC: ${result.isRfc}, Same system: ${result.isSameSystem}):`);
|
|
171
|
+
for (const entry of result.stack) {
|
|
172
|
+
if ("programName" in entry) {
|
|
173
|
+
const prog = entry.programName;
|
|
174
|
+
const line = entry.line;
|
|
175
|
+
const event = "eventName" in entry ? entry.eventName : "";
|
|
176
|
+
const pos = entry.stackPosition;
|
|
177
|
+
console.log(` [${pos}] ${prog} line ${line} (${event})`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async function debugVariablesCommand(variables, options) {
|
|
183
|
+
await (0, client_1.withStatefulSession)(async (client) => {
|
|
184
|
+
const result = await client.debuggerVariables(variables);
|
|
185
|
+
if (options.json) {
|
|
186
|
+
(0, formatter_1.output)(result, true);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
for (const v of result) {
|
|
190
|
+
const type = v.DECLARED_TYPE_NAME || v.TECHNICAL_TYPE;
|
|
191
|
+
const meta = v.META_TYPE;
|
|
192
|
+
console.log(`${v.NAME} = ${v.VALUE} (${type}, ${meta}, len=${v.LENGTH})`);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
async function debugChildVariablesCommand(parents, options) {
|
|
197
|
+
await (0, client_1.withStatefulSession)(async (client) => {
|
|
198
|
+
const result = await client.debuggerChildVariables(parents);
|
|
199
|
+
if (options.json) {
|
|
200
|
+
(0, formatter_1.output)(result, true);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (result.hierarchies.length > 0) {
|
|
204
|
+
console.log("Hierarchies:");
|
|
205
|
+
for (const h of result.hierarchies) {
|
|
206
|
+
console.log(` ${h.PARENT_ID} -> ${h.CHILD_NAME} (${h.CHILD_ID})`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (result.variables.length > 0) {
|
|
210
|
+
console.log("\nVariables:");
|
|
211
|
+
for (const v of result.variables) {
|
|
212
|
+
const type = v.DECLARED_TYPE_NAME || v.TECHNICAL_TYPE;
|
|
213
|
+
console.log(` ${v.NAME} = ${v.VALUE} (${type}, ${v.META_TYPE})`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.definitionCommand = definitionCommand;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const client_1 = require("../client");
|
|
39
|
+
async function definitionCommand(objectUrl, options) {
|
|
40
|
+
const client = await (0, client_1.getStatelessClient)();
|
|
41
|
+
const line = parseInt(options.line);
|
|
42
|
+
const startCol = parseInt(options.startCol);
|
|
43
|
+
const endCol = parseInt(options.endCol);
|
|
44
|
+
// Source body is needed for the API — read from file or fetch from server
|
|
45
|
+
let source;
|
|
46
|
+
if (options.sourceFile) {
|
|
47
|
+
source = fs.readFileSync(options.sourceFile, "utf-8");
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
source = await client.getObjectSource(objectUrl);
|
|
51
|
+
}
|
|
52
|
+
const result = await client.findDefinition(objectUrl, source, line, startCol, endCol, options.implementation || false, options.mainProgram || "");
|
|
53
|
+
if (options.json) {
|
|
54
|
+
console.log(JSON.stringify(result, null, 2));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!result.url) {
|
|
58
|
+
console.log("No definition found.");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log(`URI: ${result.url}`);
|
|
62
|
+
if (result.line)
|
|
63
|
+
console.log(`Line: ${result.line}`);
|
|
64
|
+
if (result.column)
|
|
65
|
+
console.log(`Column: ${result.column}`);
|
|
66
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteCommand = deleteCommand;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
async function deleteCommand(objectUrl, options) {
|
|
6
|
+
await (0, client_1.withStatefulSession)(async (c) => {
|
|
7
|
+
const lock = await c.lock(objectUrl);
|
|
8
|
+
const lockHandle = lock.LOCK_HANDLE;
|
|
9
|
+
try {
|
|
10
|
+
let transport = options.transport || lock.CORRNR;
|
|
11
|
+
if (!transport) {
|
|
12
|
+
const info = await c.transportInfo(objectUrl);
|
|
13
|
+
if (info.RECORDING && info.RECORDING !== " ") {
|
|
14
|
+
if (info.TRANSPORTS && info.TRANSPORTS.length > 0) {
|
|
15
|
+
transport = info.TRANSPORTS[0].TRKORR;
|
|
16
|
+
console.log(`Using transport: ${transport} (${info.TRANSPORTS[0].AS4TEXT})`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.error("Transport required but none available.");
|
|
20
|
+
await c.unLock(objectUrl, lockHandle);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
await c.deleteObject(objectUrl, lockHandle, transport || undefined);
|
|
26
|
+
console.log(`Deleted: ${objectUrl}`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
try {
|
|
30
|
+
await c.unLock(objectUrl, lockHandle);
|
|
31
|
+
}
|
|
32
|
+
catch ( /* ignore */_a) { /* ignore */ }
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|