catalyst-relay 0.5.1 → 0.5.3
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/index.d.mts +40 -3
- package/dist/index.d.ts +40 -3
- package/dist/index.js +270 -83
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +268 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -839,6 +839,12 @@ function extractCsrfToken(headers) {
|
|
|
839
839
|
|
|
840
840
|
// src/core/utils/logging.ts
|
|
841
841
|
var isActive = false;
|
|
842
|
+
function activateLogging() {
|
|
843
|
+
isActive = true;
|
|
844
|
+
}
|
|
845
|
+
function deactivateLogging() {
|
|
846
|
+
isActive = false;
|
|
847
|
+
}
|
|
842
848
|
function debug(message) {
|
|
843
849
|
if (isActive) {
|
|
844
850
|
console.log(`[DEBUG] ${message}`);
|
|
@@ -1061,16 +1067,22 @@ function exportSessionState(ctx, ssoCerts) {
|
|
|
1061
1067
|
// src/client/methods/session/importSessionState.ts
|
|
1062
1068
|
var DEFAULT_REFRESH_INTERVAL2 = 30 * 60 * 1e3;
|
|
1063
1069
|
async function importSessionState(ctx, state, setSsoCerts) {
|
|
1070
|
+
debug(`importSessionState: starting import`);
|
|
1064
1071
|
if (state.session.expiresAt <= Date.now()) {
|
|
1072
|
+
debug(`importSessionState: session expired`);
|
|
1065
1073
|
return err(new Error("Session has expired"));
|
|
1066
1074
|
}
|
|
1075
|
+
debug(`importSessionState: session expiry OK (expires at ${state.session.expiresAt})`);
|
|
1067
1076
|
ctx.state.session = state.session;
|
|
1068
1077
|
ctx.state.csrfToken = state.csrfToken;
|
|
1078
|
+
debug(`importSessionState: restored session and CSRF token`);
|
|
1069
1079
|
ctx.state.cookies.clear();
|
|
1070
1080
|
for (const cookie of state.cookies) {
|
|
1071
1081
|
ctx.state.cookies.set(cookie.name, cookie.value);
|
|
1072
1082
|
}
|
|
1083
|
+
debug(`importSessionState: restored ${state.cookies.length} cookies`);
|
|
1073
1084
|
if (state.authType === "sso" && state.ssoCertPaths) {
|
|
1085
|
+
debug(`importSessionState: loading SSO certs from ${state.ssoCertPaths.fullChainPath}`);
|
|
1074
1086
|
try {
|
|
1075
1087
|
const fs = await import("fs/promises");
|
|
1076
1088
|
const [fullChain, key] = await Promise.all([
|
|
@@ -1078,32 +1090,52 @@ async function importSessionState(ctx, state, setSsoCerts) {
|
|
|
1078
1090
|
fs.readFile(state.ssoCertPaths.keyPath, "utf-8")
|
|
1079
1091
|
]);
|
|
1080
1092
|
setSsoCerts({ cert: fullChain, key });
|
|
1093
|
+
debug(`importSessionState: SSO certs loaded successfully`);
|
|
1081
1094
|
} catch (certErr) {
|
|
1095
|
+
debug(`importSessionState: SSO cert load failed: ${certErr}`);
|
|
1082
1096
|
return err(new Error(`Failed to load SSO certificates: ${certErr instanceof Error ? certErr.message : String(certErr)}`));
|
|
1083
1097
|
}
|
|
1084
1098
|
}
|
|
1099
|
+
debug(`importSessionState: fetching fresh CSRF token...`);
|
|
1085
1100
|
const [response, reqErr] = await ctx.request({
|
|
1086
1101
|
method: "GET",
|
|
1087
|
-
path: "/sap/bc/adt/compatibility/graph"
|
|
1102
|
+
path: "/sap/bc/adt/compatibility/graph",
|
|
1103
|
+
headers: {
|
|
1104
|
+
[CSRF_TOKEN_HEADER]: FETCH_CSRF_TOKEN
|
|
1105
|
+
}
|
|
1088
1106
|
});
|
|
1107
|
+
debug(`importSessionState: CSRF fetch completed`);
|
|
1089
1108
|
if (reqErr) {
|
|
1109
|
+
debug(`importSessionState: CSRF fetch error: ${reqErr.message}`);
|
|
1090
1110
|
ctx.state.session = null;
|
|
1091
1111
|
ctx.state.csrfToken = null;
|
|
1092
1112
|
ctx.state.cookies.clear();
|
|
1093
1113
|
return err(new Error(`Session validation failed: ${reqErr.message}`));
|
|
1094
1114
|
}
|
|
1095
1115
|
if (!response.ok) {
|
|
1116
|
+
debug(`importSessionState: CSRF fetch failed with status ${response.status}`);
|
|
1096
1117
|
ctx.state.session = null;
|
|
1097
1118
|
ctx.state.csrfToken = null;
|
|
1098
1119
|
ctx.state.cookies.clear();
|
|
1099
1120
|
return err(new Error(`Session validation failed with status ${response.status}`));
|
|
1100
1121
|
}
|
|
1122
|
+
const newToken = extractCsrfToken(response.headers);
|
|
1123
|
+
if (!newToken) {
|
|
1124
|
+
debug(`importSessionState: no CSRF token in response headers`);
|
|
1125
|
+
ctx.state.session = null;
|
|
1126
|
+
ctx.state.csrfToken = null;
|
|
1127
|
+
ctx.state.cookies.clear();
|
|
1128
|
+
return err(new Error("Session validation failed: no CSRF token returned"));
|
|
1129
|
+
}
|
|
1130
|
+
ctx.state.csrfToken = newToken;
|
|
1131
|
+
debug(`importSessionState: new CSRF token obtained: ${newToken.substring(0, 20)}...`);
|
|
1101
1132
|
const autoRefresh = ctx.state.config.autoRefresh ?? { enabled: true };
|
|
1102
1133
|
if (autoRefresh.enabled) {
|
|
1103
1134
|
const interval = autoRefresh.intervalMs ?? DEFAULT_REFRESH_INTERVAL2;
|
|
1104
1135
|
ctx.startAutoRefresh(interval);
|
|
1105
1136
|
debug(`Auto-refresh started with ${interval}ms interval (after import)`);
|
|
1106
1137
|
}
|
|
1138
|
+
debug(`importSessionState: import complete`);
|
|
1107
1139
|
return ok(true);
|
|
1108
1140
|
}
|
|
1109
1141
|
|
|
@@ -1145,6 +1177,14 @@ var OBJECT_CONFIG_MAP = {
|
|
|
1145
1177
|
dpEndpoint: "ddic",
|
|
1146
1178
|
dpParam: "ddicEntityName"
|
|
1147
1179
|
},
|
|
1180
|
+
"astablds": {
|
|
1181
|
+
endpoint: "ddic/structures",
|
|
1182
|
+
nameSpace: 'xmlns:blue="http://www.sap.com/wbobj/blue"',
|
|
1183
|
+
rootName: "blue:blueSource",
|
|
1184
|
+
type: "STRU/D",
|
|
1185
|
+
label: "Structure" /* STRUCTURE */,
|
|
1186
|
+
extension: "astablds"
|
|
1187
|
+
},
|
|
1148
1188
|
"asprog": {
|
|
1149
1189
|
endpoint: "programs/programs",
|
|
1150
1190
|
nameSpace: 'xmlns:program="http://www.sap.com/adt/programs/programs"',
|
|
@@ -1461,8 +1501,201 @@ function extractActivationErrors(objects, xml, _extension) {
|
|
|
1461
1501
|
return ok(results);
|
|
1462
1502
|
}
|
|
1463
1503
|
|
|
1504
|
+
// src/core/adt/craud/syntaxCheck.ts
|
|
1505
|
+
async function checkSyntax(client, objects) {
|
|
1506
|
+
if (objects.length === 0) {
|
|
1507
|
+
return ok([]);
|
|
1508
|
+
}
|
|
1509
|
+
const extension = objects[0].extension;
|
|
1510
|
+
const config = getConfigByExtension(extension);
|
|
1511
|
+
if (!config) return err(new Error(`Unsupported extension: ${extension}`));
|
|
1512
|
+
for (const obj of objects) {
|
|
1513
|
+
if (obj.extension !== extension) {
|
|
1514
|
+
return err(new Error("All objects must have the same extension for batch syntax check"));
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
const sources = /* @__PURE__ */ new Map();
|
|
1518
|
+
for (const obj of objects) {
|
|
1519
|
+
const [result, readErr] = await readObject(client, obj);
|
|
1520
|
+
if (readErr) return err(new Error(`Failed to read ${obj.name}: ${readErr.message}`));
|
|
1521
|
+
sources.set(obj.name.toLowerCase(), result.content);
|
|
1522
|
+
}
|
|
1523
|
+
const objectRefs = objects.map((obj) => {
|
|
1524
|
+
const uri = `/sap/bc/adt/${config.endpoint}/${obj.name.toLowerCase()}`;
|
|
1525
|
+
const sourceUri = `${uri}/source/main`;
|
|
1526
|
+
const content = sources.get(obj.name.toLowerCase()) ?? "";
|
|
1527
|
+
const encoded = Buffer.from(content).toString("base64");
|
|
1528
|
+
return `<chkrun:checkObject adtcore:uri="${uri}" chkrun:version="active">
|
|
1529
|
+
<chkrun:artifacts>
|
|
1530
|
+
<chkrun:artifact chkrun:contentType="text/plain; charset=utf-8" chkrun:uri="${sourceUri}">
|
|
1531
|
+
<chkrun:content>${encoded}</chkrun:content>
|
|
1532
|
+
</chkrun:artifact>
|
|
1533
|
+
</chkrun:artifacts>
|
|
1534
|
+
</chkrun:checkObject>`;
|
|
1535
|
+
}).join("\n ");
|
|
1536
|
+
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1537
|
+
<chkrun:checkObjectList xmlns:chkrun="http://www.sap.com/adt/checkrun"
|
|
1538
|
+
xmlns:adtcore="http://www.sap.com/adt/core">
|
|
1539
|
+
${objectRefs}
|
|
1540
|
+
</chkrun:checkObjectList>`;
|
|
1541
|
+
const [response, requestErr] = await client.request({
|
|
1542
|
+
method: "POST",
|
|
1543
|
+
path: "/sap/bc/adt/checkruns",
|
|
1544
|
+
params: {
|
|
1545
|
+
"reporters": "abapCheckRun"
|
|
1546
|
+
},
|
|
1547
|
+
headers: {
|
|
1548
|
+
"Content-Type": "application/vnd.sap.adt.checkobjects+xml",
|
|
1549
|
+
"Accept": "application/vnd.sap.adt.checkmessages+xml"
|
|
1550
|
+
},
|
|
1551
|
+
body
|
|
1552
|
+
});
|
|
1553
|
+
if (requestErr) {
|
|
1554
|
+
return err(requestErr);
|
|
1555
|
+
}
|
|
1556
|
+
const text = await response.text();
|
|
1557
|
+
debug(`Syntax check response status: ${response.status}`);
|
|
1558
|
+
debug(`Syntax check response: ${text.substring(0, 500)}`);
|
|
1559
|
+
if (!response.ok) {
|
|
1560
|
+
const errorMsg = extractError(text);
|
|
1561
|
+
return err(new Error(`Syntax check failed: ${errorMsg}`));
|
|
1562
|
+
}
|
|
1563
|
+
const [results, parseErr] = extractCheckMessages(objects, text);
|
|
1564
|
+
if (parseErr) {
|
|
1565
|
+
return err(parseErr);
|
|
1566
|
+
}
|
|
1567
|
+
return ok(results);
|
|
1568
|
+
}
|
|
1569
|
+
function extractCheckMessages(objects, xml) {
|
|
1570
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
1571
|
+
if (parseErr) {
|
|
1572
|
+
return err(parseErr);
|
|
1573
|
+
}
|
|
1574
|
+
const messageMap = /* @__PURE__ */ new Map();
|
|
1575
|
+
objects.forEach((obj) => messageMap.set(obj.name.toLowerCase(), []));
|
|
1576
|
+
let msgElements = doc.getElementsByTagName("chkrun:checkMessage");
|
|
1577
|
+
if (msgElements.length === 0) {
|
|
1578
|
+
msgElements = doc.getElementsByTagName("checkMessage");
|
|
1579
|
+
}
|
|
1580
|
+
const startRegex = /#start=(\d+),(\d+)/;
|
|
1581
|
+
for (let i = 0; i < msgElements.length; i++) {
|
|
1582
|
+
const msg = msgElements[i];
|
|
1583
|
+
if (!msg) continue;
|
|
1584
|
+
const type = msg.getAttribute("chkrun:type") ?? msg.getAttribute("type");
|
|
1585
|
+
if (!type) continue;
|
|
1586
|
+
const uri = msg.getAttribute("chkrun:uri") ?? msg.getAttribute("uri") ?? "";
|
|
1587
|
+
let line;
|
|
1588
|
+
let column;
|
|
1589
|
+
const match = startRegex.exec(uri);
|
|
1590
|
+
if (match && match[1] && match[2]) {
|
|
1591
|
+
line = parseInt(match[1], 10);
|
|
1592
|
+
column = parseInt(match[2], 10);
|
|
1593
|
+
}
|
|
1594
|
+
const matchingObj = objects.find(
|
|
1595
|
+
(obj) => uri.toLowerCase().includes(obj.name.toLowerCase())
|
|
1596
|
+
);
|
|
1597
|
+
if (!matchingObj) continue;
|
|
1598
|
+
const text = msg.getAttribute("chkrun:shortText") ?? msg.getAttribute("shortText");
|
|
1599
|
+
if (!text) continue;
|
|
1600
|
+
const message = {
|
|
1601
|
+
severity: type === "E" ? "error" : type === "W" ? "warning" : "info",
|
|
1602
|
+
text,
|
|
1603
|
+
...line !== void 0 && { line },
|
|
1604
|
+
...column !== void 0 && { column }
|
|
1605
|
+
};
|
|
1606
|
+
const messages = messageMap.get(matchingObj.name.toLowerCase()) || [];
|
|
1607
|
+
messages.push(message);
|
|
1608
|
+
messageMap.set(matchingObj.name.toLowerCase(), messages);
|
|
1609
|
+
}
|
|
1610
|
+
const results = objects.map((obj) => {
|
|
1611
|
+
const messages = messageMap.get(obj.name.toLowerCase()) || [];
|
|
1612
|
+
const hasErrors = messages.some((m) => m.severity === "error");
|
|
1613
|
+
return {
|
|
1614
|
+
name: obj.name,
|
|
1615
|
+
extension: obj.extension,
|
|
1616
|
+
status: hasErrors ? "error" : messages.length > 0 ? "warning" : "success",
|
|
1617
|
+
messages
|
|
1618
|
+
};
|
|
1619
|
+
});
|
|
1620
|
+
return ok(results);
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
// src/core/adt/discovery/tree/packageStats.ts
|
|
1624
|
+
function constructPackageStatsBody(packageNames) {
|
|
1625
|
+
const names = packageNames.length === 1 ? [...packageNames, "SRIS_TEST_DATA_VFS_EMPTY"] : packageNames;
|
|
1626
|
+
const values = names.map((name) => ` <vfs:value>${name}</vfs:value>`).join("\n");
|
|
1627
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1628
|
+
<vfs:virtualFoldersRequest xmlns:vfs="http://www.sap.com/adt/ris/virtualFolders" objectSearchPattern="*">
|
|
1629
|
+
<vfs:preselection facet="package">
|
|
1630
|
+
${values}
|
|
1631
|
+
</vfs:preselection>
|
|
1632
|
+
<vfs:facetorder>
|
|
1633
|
+
<vfs:facet>package</vfs:facet>
|
|
1634
|
+
<vfs:facet>group</vfs:facet>
|
|
1635
|
+
<vfs:facet>type</vfs:facet>
|
|
1636
|
+
</vfs:facetorder>
|
|
1637
|
+
</vfs:virtualFoldersRequest>`;
|
|
1638
|
+
}
|
|
1639
|
+
function parsePackageStats(xml) {
|
|
1640
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
1641
|
+
if (parseErr) return [];
|
|
1642
|
+
const packages = [];
|
|
1643
|
+
const virtualFolders = doc.getElementsByTagName("vfs:virtualFolder");
|
|
1644
|
+
for (let i = 0; i < virtualFolders.length; i++) {
|
|
1645
|
+
const vf = virtualFolders[i];
|
|
1646
|
+
if (!vf) continue;
|
|
1647
|
+
const facet = vf.getAttribute("facet")?.toUpperCase();
|
|
1648
|
+
if (facet !== "PACKAGE") continue;
|
|
1649
|
+
const name = vf.getAttribute("name");
|
|
1650
|
+
if (!name) continue;
|
|
1651
|
+
const countAttr = vf.getAttribute("counter");
|
|
1652
|
+
const count = countAttr ? parseInt(countAttr, 10) : 0;
|
|
1653
|
+
const description = vf.getAttribute("text");
|
|
1654
|
+
const pkg = {
|
|
1655
|
+
name,
|
|
1656
|
+
numContents: count
|
|
1657
|
+
};
|
|
1658
|
+
if (description) pkg.description = description;
|
|
1659
|
+
packages.push(pkg);
|
|
1660
|
+
}
|
|
1661
|
+
return packages;
|
|
1662
|
+
}
|
|
1663
|
+
async function getPackageStats(client, packageNames) {
|
|
1664
|
+
const isSingle = typeof packageNames === "string";
|
|
1665
|
+
const names = isSingle ? [packageNames] : packageNames;
|
|
1666
|
+
if (names.length === 0) {
|
|
1667
|
+
return ok([]);
|
|
1668
|
+
}
|
|
1669
|
+
const body = constructPackageStatsBody(names);
|
|
1670
|
+
const [response, requestErr] = await client.request({
|
|
1671
|
+
method: "POST",
|
|
1672
|
+
path: "/sap/bc/adt/repository/informationsystem/virtualfolders/contents",
|
|
1673
|
+
headers: {
|
|
1674
|
+
"Content-Type": "application/vnd.sap.adt.repository.virtualfolders.request.v1+xml",
|
|
1675
|
+
"Accept": "application/vnd.sap.adt.repository.virtualfolders.result.v1+xml"
|
|
1676
|
+
},
|
|
1677
|
+
body
|
|
1678
|
+
});
|
|
1679
|
+
if (requestErr) return err(requestErr);
|
|
1680
|
+
if (!response.ok) {
|
|
1681
|
+
const text = await response.text();
|
|
1682
|
+
const errorMsg = extractError(text);
|
|
1683
|
+
return err(new Error(`Package stats fetch failed: ${errorMsg}`));
|
|
1684
|
+
}
|
|
1685
|
+
const xml = await response.text();
|
|
1686
|
+
const packages = parsePackageStats(xml).filter((pkg) => pkg.name !== "SRIS_TEST_DATA_VFS_EMPTY");
|
|
1687
|
+
if (isSingle) {
|
|
1688
|
+
if (packages.length === 0) {
|
|
1689
|
+
return err(new Error(`Package ${packageNames} not found`));
|
|
1690
|
+
}
|
|
1691
|
+
return ok(packages[0]);
|
|
1692
|
+
}
|
|
1693
|
+
return ok(packages);
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1464
1696
|
// src/core/adt/discovery/packages.ts
|
|
1465
|
-
async function getPackages(client,
|
|
1697
|
+
async function getPackages(client, options = {}) {
|
|
1698
|
+
const { filter = "*", includeDescriptions = false } = options;
|
|
1466
1699
|
const params = new URLSearchParams([
|
|
1467
1700
|
["operation", "quickSearch"],
|
|
1468
1701
|
["query", filter],
|
|
@@ -1486,18 +1719,31 @@ async function getPackages(client, filter = "*") {
|
|
|
1486
1719
|
if (parseErr) {
|
|
1487
1720
|
return err(parseErr);
|
|
1488
1721
|
}
|
|
1489
|
-
const
|
|
1722
|
+
const packageNames = [];
|
|
1490
1723
|
const objectRefs = doc.getElementsByTagNameNS("http://www.sap.com/adt/core", "objectReference");
|
|
1491
1724
|
for (let i = 0; i < objectRefs.length; i++) {
|
|
1492
1725
|
const obj = objectRefs[i];
|
|
1493
1726
|
if (!obj) return err(new Error("Invalid object reference in package search results"));
|
|
1494
1727
|
const name = obj.getAttributeNS("http://www.sap.com/adt/core", "name") || obj.getAttribute("adtcore:name");
|
|
1495
|
-
const description = obj.getAttributeNS("http://www.sap.com/adt/core", "description") || obj.getAttribute("adtcore:description");
|
|
1496
1728
|
if (!name) return err(new Error("Package name missing in object reference"));
|
|
1729
|
+
packageNames.push(name);
|
|
1730
|
+
}
|
|
1731
|
+
if (packageNames.length === 0) return ok([]);
|
|
1732
|
+
if (!includeDescriptions) return ok(packageNames.map((name) => ({ name })));
|
|
1733
|
+
const [stats, statsErr] = await getPackageStats(client, packageNames);
|
|
1734
|
+
if (statsErr) {
|
|
1735
|
+
return ok(packageNames.map((name) => ({ name })));
|
|
1736
|
+
}
|
|
1737
|
+
const descriptionMap = /* @__PURE__ */ new Map();
|
|
1738
|
+
for (const stat2 of stats) {
|
|
1739
|
+
if (stat2.description) descriptionMap.set(stat2.name, stat2.description);
|
|
1740
|
+
}
|
|
1741
|
+
const packages = packageNames.map((name) => {
|
|
1497
1742
|
const pkg = { name };
|
|
1743
|
+
const description = descriptionMap.get(name);
|
|
1498
1744
|
if (description) pkg.description = description;
|
|
1499
|
-
|
|
1500
|
-
}
|
|
1745
|
+
return pkg;
|
|
1746
|
+
});
|
|
1501
1747
|
return ok(packages);
|
|
1502
1748
|
}
|
|
1503
1749
|
|
|
@@ -1737,79 +1983,6 @@ async function getTree(client, query = {}) {
|
|
|
1737
1983
|
return ok(result);
|
|
1738
1984
|
}
|
|
1739
1985
|
|
|
1740
|
-
// src/core/adt/discovery/tree/packageStats.ts
|
|
1741
|
-
function constructPackageStatsBody(packageNames) {
|
|
1742
|
-
const names = packageNames.length === 1 ? [...packageNames, "SRIS_TEST_DATA_VFS_EMPTY"] : packageNames;
|
|
1743
|
-
const values = names.map((name) => ` <vfs:value>${name}</vfs:value>`).join("\n");
|
|
1744
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1745
|
-
<vfs:virtualFoldersRequest xmlns:vfs="http://www.sap.com/adt/ris/virtualFolders" objectSearchPattern="*">
|
|
1746
|
-
<vfs:preselection facet="package">
|
|
1747
|
-
${values}
|
|
1748
|
-
</vfs:preselection>
|
|
1749
|
-
<vfs:facetorder>
|
|
1750
|
-
<vfs:facet>package</vfs:facet>
|
|
1751
|
-
<vfs:facet>group</vfs:facet>
|
|
1752
|
-
<vfs:facet>type</vfs:facet>
|
|
1753
|
-
</vfs:facetorder>
|
|
1754
|
-
</vfs:virtualFoldersRequest>`;
|
|
1755
|
-
}
|
|
1756
|
-
function parsePackageStats(xml) {
|
|
1757
|
-
const [doc, parseErr] = safeParseXml(xml);
|
|
1758
|
-
if (parseErr) return [];
|
|
1759
|
-
const packages = [];
|
|
1760
|
-
const virtualFolders = doc.getElementsByTagName("vfs:virtualFolder");
|
|
1761
|
-
for (let i = 0; i < virtualFolders.length; i++) {
|
|
1762
|
-
const vf = virtualFolders[i];
|
|
1763
|
-
if (!vf) continue;
|
|
1764
|
-
const facet = vf.getAttribute("facet")?.toUpperCase();
|
|
1765
|
-
if (facet !== "PACKAGE") continue;
|
|
1766
|
-
const name = vf.getAttribute("name");
|
|
1767
|
-
if (!name) continue;
|
|
1768
|
-
const countAttr = vf.getAttribute("counter");
|
|
1769
|
-
const count = countAttr ? parseInt(countAttr, 10) : 0;
|
|
1770
|
-
const description = vf.getAttribute("text");
|
|
1771
|
-
const pkg = {
|
|
1772
|
-
name,
|
|
1773
|
-
numContents: count
|
|
1774
|
-
};
|
|
1775
|
-
if (description) pkg.description = description;
|
|
1776
|
-
packages.push(pkg);
|
|
1777
|
-
}
|
|
1778
|
-
return packages;
|
|
1779
|
-
}
|
|
1780
|
-
async function getPackageStats(client, packageNames) {
|
|
1781
|
-
const isSingle = typeof packageNames === "string";
|
|
1782
|
-
const names = isSingle ? [packageNames] : packageNames;
|
|
1783
|
-
if (names.length === 0) {
|
|
1784
|
-
return ok([]);
|
|
1785
|
-
}
|
|
1786
|
-
const body = constructPackageStatsBody(names);
|
|
1787
|
-
const [response, requestErr] = await client.request({
|
|
1788
|
-
method: "POST",
|
|
1789
|
-
path: "/sap/bc/adt/repository/informationsystem/virtualfolders/contents",
|
|
1790
|
-
headers: {
|
|
1791
|
-
"Content-Type": "application/vnd.sap.adt.repository.virtualfolders.request.v1+xml",
|
|
1792
|
-
"Accept": "application/vnd.sap.adt.repository.virtualfolders.result.v1+xml"
|
|
1793
|
-
},
|
|
1794
|
-
body
|
|
1795
|
-
});
|
|
1796
|
-
if (requestErr) return err(requestErr);
|
|
1797
|
-
if (!response.ok) {
|
|
1798
|
-
const text = await response.text();
|
|
1799
|
-
const errorMsg = extractError(text);
|
|
1800
|
-
return err(new Error(`Package stats fetch failed: ${errorMsg}`));
|
|
1801
|
-
}
|
|
1802
|
-
const xml = await response.text();
|
|
1803
|
-
const packages = parsePackageStats(xml).filter((pkg) => pkg.name !== "SRIS_TEST_DATA_VFS_EMPTY");
|
|
1804
|
-
if (isSingle) {
|
|
1805
|
-
if (packages.length === 0) {
|
|
1806
|
-
return err(new Error(`Package ${packageNames} not found`));
|
|
1807
|
-
}
|
|
1808
|
-
return ok(packages[0]);
|
|
1809
|
-
}
|
|
1810
|
-
return ok(packages);
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
1986
|
// src/core/adt/transports/transports.ts
|
|
1814
1987
|
async function getTransports(client, packageName) {
|
|
1815
1988
|
const contentType = "application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData";
|
|
@@ -2465,10 +2638,16 @@ async function deleteObjects(state, requestor, objects, transport) {
|
|
|
2465
2638
|
return ok(void 0);
|
|
2466
2639
|
}
|
|
2467
2640
|
|
|
2641
|
+
// src/client/methods/craud/checkSyntax.ts
|
|
2642
|
+
async function checkSyntax2(state, requestor, objects) {
|
|
2643
|
+
if (!state.session) return err(new Error("Not logged in"));
|
|
2644
|
+
return checkSyntax(requestor, objects);
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2468
2647
|
// src/client/methods/discovery/getPackages.ts
|
|
2469
|
-
async function getPackages2(state, requestor,
|
|
2648
|
+
async function getPackages2(state, requestor, options) {
|
|
2470
2649
|
if (!state.session) return err(new Error("Not logged in"));
|
|
2471
|
-
return getPackages(requestor,
|
|
2650
|
+
return getPackages(requestor, options);
|
|
2472
2651
|
}
|
|
2473
2652
|
|
|
2474
2653
|
// src/client/methods/discovery/getTree.ts
|
|
@@ -2573,6 +2752,7 @@ function createAutoRefresh(getSession, refreshSession3) {
|
|
|
2573
2752
|
debug(`Auto-refresh failed: ${refreshErr.message}`);
|
|
2574
2753
|
}
|
|
2575
2754
|
}, intervalMs);
|
|
2755
|
+
timer.unref();
|
|
2576
2756
|
},
|
|
2577
2757
|
stop() {
|
|
2578
2758
|
if (timer) {
|
|
@@ -2860,12 +3040,15 @@ var ADTClientImpl = class {
|
|
|
2860
3040
|
async activate(objects) {
|
|
2861
3041
|
return activate(this.state, this.requestor, objects);
|
|
2862
3042
|
}
|
|
3043
|
+
async checkSyntax(objects) {
|
|
3044
|
+
return checkSyntax2(this.state, this.requestor, objects);
|
|
3045
|
+
}
|
|
2863
3046
|
async delete(objects, transport) {
|
|
2864
3047
|
return deleteObjects(this.state, this.requestor, objects, transport);
|
|
2865
3048
|
}
|
|
2866
3049
|
// --- Discovery ---
|
|
2867
|
-
async getPackages(
|
|
2868
|
-
return getPackages2(this.state, this.requestor,
|
|
3050
|
+
async getPackages(options) {
|
|
3051
|
+
return getPackages2(this.state, this.requestor, options);
|
|
2869
3052
|
}
|
|
2870
3053
|
async getTree(query) {
|
|
2871
3054
|
return getTree2(this.state, this.requestor, query);
|
|
@@ -2917,8 +3100,10 @@ function createClient(config) {
|
|
|
2917
3100
|
return ok(new ADTClientImpl(config));
|
|
2918
3101
|
}
|
|
2919
3102
|
export {
|
|
3103
|
+
activateLogging,
|
|
2920
3104
|
buildSQLQuery,
|
|
2921
3105
|
createClient,
|
|
3106
|
+
deactivateLogging,
|
|
2922
3107
|
err,
|
|
2923
3108
|
ok
|
|
2924
3109
|
};
|