catalyst-relay 0.5.9 → 0.5.11
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 +66 -17
- package/dist/index.d.ts +66 -17
- package/dist/index.js +357 -140
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +357 -140
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1226,6 +1226,14 @@ var OBJECT_CONFIG_MAP = {
|
|
|
1226
1226
|
type: "PROG/P",
|
|
1227
1227
|
label: "ABAP Program" /* PROGRAM */,
|
|
1228
1228
|
extension: "asprog"
|
|
1229
|
+
},
|
|
1230
|
+
"asinc": {
|
|
1231
|
+
endpoint: "programs/includes",
|
|
1232
|
+
nameSpace: 'xmlns:include="http://www.sap.com/adt/programs/includes"',
|
|
1233
|
+
rootName: "include:abapInclude",
|
|
1234
|
+
type: "PROG/I",
|
|
1235
|
+
label: "ABAP Include" /* INCLUDE */,
|
|
1236
|
+
extension: "asinc"
|
|
1229
1237
|
}
|
|
1230
1238
|
};
|
|
1231
1239
|
function getConfigByExtension(extension) {
|
|
@@ -1287,6 +1295,80 @@ async function readObject(client, object) {
|
|
|
1287
1295
|
return ok(result);
|
|
1288
1296
|
}
|
|
1289
1297
|
|
|
1298
|
+
// src/core/adt/discovery/whereUsed.ts
|
|
1299
|
+
async function findWhereUsed(client, object) {
|
|
1300
|
+
const config = getConfigByExtension(object.extension);
|
|
1301
|
+
if (!config) {
|
|
1302
|
+
return err(new Error(`Unsupported extension: ${object.extension}`));
|
|
1303
|
+
}
|
|
1304
|
+
const uri = `/sap/bc/adt/${config.endpoint}/${object.name}`;
|
|
1305
|
+
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1306
|
+
<usagereferences:usageReferenceRequest xmlns:usagereferences="http://www.sap.com/adt/ris/usageReferences">
|
|
1307
|
+
<usagereferences:affectedObjects/>
|
|
1308
|
+
</usagereferences:usageReferenceRequest>`;
|
|
1309
|
+
const [response, requestErr] = await client.request({
|
|
1310
|
+
method: "POST",
|
|
1311
|
+
path: "/sap/bc/adt/repository/informationsystem/usageReferences",
|
|
1312
|
+
params: {
|
|
1313
|
+
"uri": uri,
|
|
1314
|
+
"ris_request_type": "usageReferences"
|
|
1315
|
+
},
|
|
1316
|
+
headers: {
|
|
1317
|
+
"Content-Type": "application/vnd.sap.adt.repository.usagereferences.request.v1+xml",
|
|
1318
|
+
"Accept": "application/vnd.sap.adt.repository.usagereferences.result.v1+xml"
|
|
1319
|
+
},
|
|
1320
|
+
body
|
|
1321
|
+
});
|
|
1322
|
+
if (requestErr) {
|
|
1323
|
+
return err(requestErr);
|
|
1324
|
+
}
|
|
1325
|
+
if (!response.ok) {
|
|
1326
|
+
const text2 = await response.text();
|
|
1327
|
+
const errorMsg = extractError(text2);
|
|
1328
|
+
return err(new Error(`Where-used query failed: ${errorMsg}`));
|
|
1329
|
+
}
|
|
1330
|
+
const text = await response.text();
|
|
1331
|
+
const [dependencies, parseErr] = parseWhereUsed(text);
|
|
1332
|
+
if (parseErr) {
|
|
1333
|
+
return err(parseErr);
|
|
1334
|
+
}
|
|
1335
|
+
return ok(dependencies);
|
|
1336
|
+
}
|
|
1337
|
+
function parseWhereUsed(xml) {
|
|
1338
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
1339
|
+
if (parseErr) {
|
|
1340
|
+
return err(parseErr);
|
|
1341
|
+
}
|
|
1342
|
+
const dependencies = [];
|
|
1343
|
+
const referencedObjects = doc.getElementsByTagNameNS(
|
|
1344
|
+
"http://www.sap.com/adt/ris/usageReferences",
|
|
1345
|
+
"referencedObject"
|
|
1346
|
+
);
|
|
1347
|
+
for (let i = 0; i < referencedObjects.length; i++) {
|
|
1348
|
+
const refObj = referencedObjects[i];
|
|
1349
|
+
if (!refObj) continue;
|
|
1350
|
+
const adtObject = refObj.getElementsByTagNameNS(
|
|
1351
|
+
"http://www.sap.com/adt/ris/usageReferences",
|
|
1352
|
+
"adtObject"
|
|
1353
|
+
)[0];
|
|
1354
|
+
if (!adtObject) continue;
|
|
1355
|
+
const name = adtObject.getAttributeNS("http://www.sap.com/adt/core", "name") || adtObject.getAttribute("adtcore:name");
|
|
1356
|
+
const type = adtObject.getAttributeNS("http://www.sap.com/adt/core", "type") || adtObject.getAttribute("adtcore:type");
|
|
1357
|
+
if (!name || !type) continue;
|
|
1358
|
+
const config = getConfigByType(type);
|
|
1359
|
+
if (!config) continue;
|
|
1360
|
+
const packageRef = adtObject.getElementsByTagNameNS("http://www.sap.com/adt/core", "packageRef")[0];
|
|
1361
|
+
const packageName = packageRef ? packageRef.getAttributeNS("http://www.sap.com/adt/core", "name") || packageRef.getAttribute("adtcore:name") : "";
|
|
1362
|
+
dependencies.push({
|
|
1363
|
+
name,
|
|
1364
|
+
extension: config.extension,
|
|
1365
|
+
package: packageName || "",
|
|
1366
|
+
usageType: "reference"
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
return ok(dependencies);
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1290
1372
|
// src/core/adt/craud/lock.ts
|
|
1291
1373
|
async function lockObject(client, object) {
|
|
1292
1374
|
const [config, configErr] = requireConfig(object.extension);
|
|
@@ -1335,6 +1417,135 @@ async function unlockObject(client, object, lockHandle) {
|
|
|
1335
1417
|
return ok(void 0);
|
|
1336
1418
|
}
|
|
1337
1419
|
|
|
1420
|
+
// src/core/adt/craud/delete.ts
|
|
1421
|
+
async function deleteObject(client, object, lockHandle, transport) {
|
|
1422
|
+
const [config, configErr] = requireConfig(object.extension);
|
|
1423
|
+
if (configErr) return err(configErr);
|
|
1424
|
+
const params = {
|
|
1425
|
+
"lockHandle": lockHandle
|
|
1426
|
+
};
|
|
1427
|
+
if (transport) {
|
|
1428
|
+
params["corrNr"] = transport;
|
|
1429
|
+
}
|
|
1430
|
+
const [response, requestErr] = await client.request({
|
|
1431
|
+
method: "DELETE",
|
|
1432
|
+
path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,
|
|
1433
|
+
params,
|
|
1434
|
+
headers: { "Accept": "text/plain" }
|
|
1435
|
+
});
|
|
1436
|
+
const [_, checkErr] = await checkResponse(
|
|
1437
|
+
response,
|
|
1438
|
+
requestErr,
|
|
1439
|
+
`Failed to delete ${config.label} ${object.name}`
|
|
1440
|
+
);
|
|
1441
|
+
if (checkErr) return err(checkErr);
|
|
1442
|
+
return ok(void 0);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// src/core/adt/craud/multiDelete.ts
|
|
1446
|
+
var ExternalReferencesError = class extends Error {
|
|
1447
|
+
constructor(references) {
|
|
1448
|
+
super(`Cannot delete: ${references.length} external reference(s) prevent the operation`);
|
|
1449
|
+
this.references = references;
|
|
1450
|
+
this.name = "ExternalReferencesError";
|
|
1451
|
+
}
|
|
1452
|
+
};
|
|
1453
|
+
function objKey(o) {
|
|
1454
|
+
return `${o.name.toLowerCase()}|${o.extension}`;
|
|
1455
|
+
}
|
|
1456
|
+
async function multiDeleteObjects(client, objects, transport) {
|
|
1457
|
+
if (objects.length === 0) return ok([]);
|
|
1458
|
+
for (const obj of objects) {
|
|
1459
|
+
if (!getConfigByExtension(obj.extension)) {
|
|
1460
|
+
return err(new Error(`Unsupported extension: ${obj.extension}`));
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
const setKeys = /* @__PURE__ */ new Set();
|
|
1464
|
+
const unique = [];
|
|
1465
|
+
for (const obj of objects) {
|
|
1466
|
+
const key = objKey(obj);
|
|
1467
|
+
if (setKeys.has(key)) continue;
|
|
1468
|
+
setKeys.add(key);
|
|
1469
|
+
unique.push(obj);
|
|
1470
|
+
}
|
|
1471
|
+
const whereUsedResults = await Promise.all(
|
|
1472
|
+
unique.map((obj) => findWhereUsed(client, obj))
|
|
1473
|
+
);
|
|
1474
|
+
for (let i = 0; i < whereUsedResults.length; i++) {
|
|
1475
|
+
const [, e] = whereUsedResults[i];
|
|
1476
|
+
if (e) return err(new Error(`where-used failed for ${unique[i].name}: ${e.message}`));
|
|
1477
|
+
}
|
|
1478
|
+
const referencers = /* @__PURE__ */ new Map();
|
|
1479
|
+
const dependents = /* @__PURE__ */ new Map();
|
|
1480
|
+
const externalRefs = [];
|
|
1481
|
+
for (const obj of unique) {
|
|
1482
|
+
referencers.set(objKey(obj), []);
|
|
1483
|
+
dependents.set(objKey(obj), []);
|
|
1484
|
+
}
|
|
1485
|
+
for (let i = 0; i < unique.length; i++) {
|
|
1486
|
+
const obj = unique[i];
|
|
1487
|
+
const oKey = objKey(obj);
|
|
1488
|
+
const [deps] = whereUsedResults[i];
|
|
1489
|
+
for (const dep of deps) {
|
|
1490
|
+
const dKey = objKey(dep);
|
|
1491
|
+
if (dKey === oKey) continue;
|
|
1492
|
+
if (!setKeys.has(dKey)) {
|
|
1493
|
+
externalRefs.push({
|
|
1494
|
+
object: { name: obj.name, extension: obj.extension },
|
|
1495
|
+
referencedBy: dep
|
|
1496
|
+
});
|
|
1497
|
+
continue;
|
|
1498
|
+
}
|
|
1499
|
+
referencers.get(oKey).push(dKey);
|
|
1500
|
+
dependents.get(dKey).push(oKey);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
if (externalRefs.length > 0) {
|
|
1504
|
+
return err(new ExternalReferencesError(externalRefs));
|
|
1505
|
+
}
|
|
1506
|
+
const objByKey = /* @__PURE__ */ new Map();
|
|
1507
|
+
for (const obj of unique) objByKey.set(objKey(obj), obj);
|
|
1508
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
1509
|
+
for (const [k, refs] of referencers.entries()) {
|
|
1510
|
+
inDegree.set(k, refs.length);
|
|
1511
|
+
}
|
|
1512
|
+
const remaining = new Set(setKeys);
|
|
1513
|
+
const results = [];
|
|
1514
|
+
const deleteOne = async (obj) => {
|
|
1515
|
+
const [lockHandle, lockErr] = await lockObject(client, obj);
|
|
1516
|
+
if (lockErr) {
|
|
1517
|
+
return { name: obj.name, extension: obj.extension, status: "error", message: lockErr.message };
|
|
1518
|
+
}
|
|
1519
|
+
const [, deleteErr] = await deleteObject(client, obj, lockHandle, transport);
|
|
1520
|
+
if (deleteErr) {
|
|
1521
|
+
await unlockObject(client, obj, lockHandle);
|
|
1522
|
+
return { name: obj.name, extension: obj.extension, status: "error", message: deleteErr.message };
|
|
1523
|
+
}
|
|
1524
|
+
return { name: obj.name, extension: obj.extension, status: "success" };
|
|
1525
|
+
};
|
|
1526
|
+
while (remaining.size > 0) {
|
|
1527
|
+
const ready = [];
|
|
1528
|
+
for (const key of remaining) {
|
|
1529
|
+
if ((inDegree.get(key) ?? 0) === 0) ready.push(key);
|
|
1530
|
+
}
|
|
1531
|
+
const waveKeys = ready.length > 0 ? ready : [...remaining];
|
|
1532
|
+
const waveObjects = waveKeys.map((k) => objByKey.get(k));
|
|
1533
|
+
const waveResults = await Promise.all(waveObjects.map(deleteOne));
|
|
1534
|
+
for (let i = 0; i < waveResults.length; i++) {
|
|
1535
|
+
const result = waveResults[i];
|
|
1536
|
+
const key = waveKeys[i];
|
|
1537
|
+
results.push(result);
|
|
1538
|
+
remaining.delete(key);
|
|
1539
|
+
if (result.status === "success") {
|
|
1540
|
+
for (const o of dependents.get(key) ?? []) {
|
|
1541
|
+
inDegree.set(o, (inDegree.get(o) ?? 0) - 1);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
return ok(results);
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1338
1549
|
// src/core/adt/craud/create.ts
|
|
1339
1550
|
async function createObject(client, object, packageName, transport, username) {
|
|
1340
1551
|
const [config, configErr] = requireConfig(object.extension);
|
|
@@ -1400,59 +1611,31 @@ async function updateObject(client, object, lockHandle, transport) {
|
|
|
1400
1611
|
return ok(void 0);
|
|
1401
1612
|
}
|
|
1402
1613
|
|
|
1403
|
-
// src/core/adt/craud/delete.ts
|
|
1404
|
-
async function deleteObject(client, object, lockHandle, transport) {
|
|
1405
|
-
const [config, configErr] = requireConfig(object.extension);
|
|
1406
|
-
if (configErr) return err(configErr);
|
|
1407
|
-
const params = {
|
|
1408
|
-
"lockHandle": lockHandle
|
|
1409
|
-
};
|
|
1410
|
-
if (transport) {
|
|
1411
|
-
params["corrNr"] = transport;
|
|
1412
|
-
}
|
|
1413
|
-
const [response, requestErr] = await client.request({
|
|
1414
|
-
method: "DELETE",
|
|
1415
|
-
path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,
|
|
1416
|
-
params,
|
|
1417
|
-
headers: { "Accept": "text/plain" }
|
|
1418
|
-
});
|
|
1419
|
-
const [_, checkErr] = await checkResponse(
|
|
1420
|
-
response,
|
|
1421
|
-
requestErr,
|
|
1422
|
-
`Failed to delete ${config.label} ${object.name}`
|
|
1423
|
-
);
|
|
1424
|
-
if (checkErr) return err(checkErr);
|
|
1425
|
-
return ok(void 0);
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
1614
|
// src/core/adt/craud/activation.ts
|
|
1615
|
+
var MAX_POLL_ATTEMPTS = 30;
|
|
1616
|
+
var RUN_ID_REGEX = /\/activation\/runs\/([^?/]+)/;
|
|
1429
1617
|
async function activateObjects(client, objects) {
|
|
1430
1618
|
if (objects.length === 0) {
|
|
1431
1619
|
return ok([]);
|
|
1432
1620
|
}
|
|
1433
|
-
const extension = objects[0].extension;
|
|
1434
|
-
const config = getConfigByExtension(extension);
|
|
1435
|
-
if (!config) return err(new Error(`Unsupported extension: ${extension}`));
|
|
1436
1621
|
for (const obj of objects) {
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
}
|
|
1622
|
+
const config = getConfigByExtension(obj.extension);
|
|
1623
|
+
if (!config) return err(new Error(`Unsupported extension: ${obj.extension}`));
|
|
1440
1624
|
}
|
|
1441
|
-
const objectRefs = objects.map((obj) =>
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
adtcore:description="*"/>`).join("\n ");
|
|
1625
|
+
const objectRefs = objects.map((obj) => {
|
|
1626
|
+
const config = getConfigByExtension(obj.extension);
|
|
1627
|
+
return `<adtcore:objectReference adtcore:uri="/sap/bc/adt/${config.endpoint}/${obj.name.toLowerCase()}" adtcore:type="${config.type}" adtcore:name="${obj.name}"/>`;
|
|
1628
|
+
}).join("\n ");
|
|
1446
1629
|
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
const [
|
|
1630
|
+
<adtcore:objectReferences xmlns:adtcore="http://www.sap.com/adt/core">
|
|
1631
|
+
${objectRefs}
|
|
1632
|
+
</adtcore:objectReferences>`;
|
|
1633
|
+
const [startRes, startErr] = await client.request({
|
|
1451
1634
|
method: "POST",
|
|
1452
|
-
path: "/sap/bc/adt/activation",
|
|
1635
|
+
path: "/sap/bc/adt/activation/runs",
|
|
1453
1636
|
params: {
|
|
1454
1637
|
"method": "activate",
|
|
1455
|
-
"
|
|
1638
|
+
"preauditRequested": "false"
|
|
1456
1639
|
},
|
|
1457
1640
|
headers: {
|
|
1458
1641
|
"Content-Type": "application/xml",
|
|
@@ -1460,23 +1643,54 @@ async function activateObjects(client, objects) {
|
|
|
1460
1643
|
},
|
|
1461
1644
|
body
|
|
1462
1645
|
});
|
|
1463
|
-
if (
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1646
|
+
if (startErr) return err(startErr);
|
|
1647
|
+
debug(`Activation run start status: ${startRes.status}`);
|
|
1648
|
+
if (!startRes.ok) {
|
|
1649
|
+
const errText = await startRes.text();
|
|
1650
|
+
return err(new Error(`Activation start failed: ${extractError(errText)}`));
|
|
1651
|
+
}
|
|
1652
|
+
const location = startRes.headers.get("location");
|
|
1653
|
+
if (!location) return err(new Error("Activation start response missing Location header"));
|
|
1654
|
+
const runIdMatch = RUN_ID_REGEX.exec(location);
|
|
1655
|
+
if (!runIdMatch || !runIdMatch[1]) {
|
|
1656
|
+
return err(new Error(`Could not extract run ID from Location header: ${location}`));
|
|
1657
|
+
}
|
|
1658
|
+
const runId = runIdMatch[1];
|
|
1659
|
+
debug(`Activation run ID: ${runId}`);
|
|
1660
|
+
let pollAttempt = 0;
|
|
1661
|
+
while (pollAttempt < MAX_POLL_ATTEMPTS) {
|
|
1662
|
+
const [pollRes, pollErr] = await client.request({
|
|
1663
|
+
method: "GET",
|
|
1664
|
+
path: `/sap/bc/adt/activation/runs/${runId}`,
|
|
1665
|
+
params: { "withLongPolling": "true" },
|
|
1666
|
+
headers: { "Accept": "application/xml" }
|
|
1667
|
+
});
|
|
1668
|
+
if (pollErr) return err(pollErr);
|
|
1669
|
+
debug(`Activation poll attempt ${pollAttempt + 1} status: ${pollRes.status}`);
|
|
1670
|
+
if (pollRes.ok) break;
|
|
1671
|
+
pollAttempt++;
|
|
1672
|
+
if (pollAttempt >= MAX_POLL_ATTEMPTS) {
|
|
1673
|
+
const errText = await pollRes.text();
|
|
1674
|
+
return err(new Error(`Activation run ${runId} did not complete: ${extractError(errText)}`));
|
|
1675
|
+
}
|
|
1476
1676
|
}
|
|
1677
|
+
const [resultsRes, resultsErr] = await client.request({
|
|
1678
|
+
method: "GET",
|
|
1679
|
+
path: `/sap/bc/adt/activation/results/${runId}`,
|
|
1680
|
+
headers: { "Accept": "application/xml" }
|
|
1681
|
+
});
|
|
1682
|
+
if (resultsErr) return err(resultsErr);
|
|
1683
|
+
const resultsText = await resultsRes.text();
|
|
1684
|
+
debug(`Activation results status: ${resultsRes.status}`);
|
|
1685
|
+
debug(`Activation results body: ${resultsText.substring(0, 500)}`);
|
|
1686
|
+
if (!resultsRes.ok) {
|
|
1687
|
+
return err(new Error(`Failed to fetch activation results: ${extractError(resultsText)}`));
|
|
1688
|
+
}
|
|
1689
|
+
const [results, parseErr] = extractActivationErrors(objects, resultsText);
|
|
1690
|
+
if (parseErr) return err(parseErr);
|
|
1477
1691
|
return ok(results);
|
|
1478
1692
|
}
|
|
1479
|
-
function extractActivationErrors(objects, xml
|
|
1693
|
+
function extractActivationErrors(objects, xml) {
|
|
1480
1694
|
const [doc, parseErr] = safeParseXml(xml);
|
|
1481
1695
|
if (parseErr) {
|
|
1482
1696
|
return err(parseErr);
|
|
@@ -2075,6 +2289,83 @@ function extractTransports(xml) {
|
|
|
2075
2289
|
return ok(transports);
|
|
2076
2290
|
}
|
|
2077
2291
|
|
|
2292
|
+
// src/core/adt/discovery/inactiveObjects.ts
|
|
2293
|
+
var IOC_NS = "http://www.sap.com/abapxml/inactiveCtsObjects";
|
|
2294
|
+
var ADTCORE_NS = "http://www.sap.com/adt/core";
|
|
2295
|
+
async function getInactiveObjects(client) {
|
|
2296
|
+
const [response, requestErr] = await client.request({
|
|
2297
|
+
method: "GET",
|
|
2298
|
+
path: "/sap/bc/adt/activation/inactiveobjects",
|
|
2299
|
+
headers: {
|
|
2300
|
+
"Accept": "application/vnd.sap.adt.inactivectsobjects.v1+xml, application/xml;q=0.8"
|
|
2301
|
+
}
|
|
2302
|
+
});
|
|
2303
|
+
if (requestErr) return err(requestErr);
|
|
2304
|
+
if (!response.ok) {
|
|
2305
|
+
const text2 = await response.text();
|
|
2306
|
+
const errorMsg = extractError(text2);
|
|
2307
|
+
return err(new Error(`Failed to fetch inactive objects: ${errorMsg}`));
|
|
2308
|
+
}
|
|
2309
|
+
const text = await response.text();
|
|
2310
|
+
return parseInactiveObjects(text);
|
|
2311
|
+
}
|
|
2312
|
+
function parseInactiveObjects(xml) {
|
|
2313
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
2314
|
+
if (parseErr) return err(parseErr);
|
|
2315
|
+
const entries = [];
|
|
2316
|
+
const entryElements = doc.getElementsByTagNameNS(IOC_NS, "entry");
|
|
2317
|
+
for (let i = 0; i < entryElements.length; i++) {
|
|
2318
|
+
const entryEl = entryElements[i];
|
|
2319
|
+
if (!entryEl) continue;
|
|
2320
|
+
const entry = {};
|
|
2321
|
+
const objectEls = entryEl.getElementsByTagNameNS(IOC_NS, "object");
|
|
2322
|
+
if (objectEls.length > 0) {
|
|
2323
|
+
const objectEl = objectEls[0];
|
|
2324
|
+
const objectRef = extractRef(objectEl);
|
|
2325
|
+
if (objectRef) {
|
|
2326
|
+
const user = objectEl.getAttributeNS(IOC_NS, "user") || objectEl.getAttribute("ioc:user") || "";
|
|
2327
|
+
const deletedStr = objectEl.getAttributeNS(IOC_NS, "deleted") || objectEl.getAttribute("ioc:deleted") || "false";
|
|
2328
|
+
entry.object = {
|
|
2329
|
+
user,
|
|
2330
|
+
deleted: deletedStr === "true",
|
|
2331
|
+
ref: objectRef
|
|
2332
|
+
};
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
const transportEls = entryEl.getElementsByTagNameNS(IOC_NS, "transport");
|
|
2336
|
+
if (transportEls.length > 0) {
|
|
2337
|
+
const transportEl = transportEls[0];
|
|
2338
|
+
const transportRef = extractRef(transportEl);
|
|
2339
|
+
if (transportRef) {
|
|
2340
|
+
const user = transportEl.getAttributeNS(IOC_NS, "user") || transportEl.getAttribute("ioc:user") || "";
|
|
2341
|
+
const linkedStr = transportEl.getAttributeNS(IOC_NS, "linked") || transportEl.getAttribute("ioc:linked") || "false";
|
|
2342
|
+
entry.transport = {
|
|
2343
|
+
user,
|
|
2344
|
+
linked: linkedStr === "true",
|
|
2345
|
+
ref: transportRef
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
if (entry.object || entry.transport) {
|
|
2350
|
+
entries.push(entry);
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
return ok(entries);
|
|
2354
|
+
}
|
|
2355
|
+
function extractRef(parent) {
|
|
2356
|
+
const refs = parent.getElementsByTagNameNS(IOC_NS, "ref");
|
|
2357
|
+
if (refs.length === 0) return null;
|
|
2358
|
+
const ref = refs[0];
|
|
2359
|
+
const uri = ref.getAttributeNS(ADTCORE_NS, "uri") || ref.getAttribute("adtcore:uri") || "";
|
|
2360
|
+
const type = ref.getAttributeNS(ADTCORE_NS, "type") || ref.getAttribute("adtcore:type") || "";
|
|
2361
|
+
const name = ref.getAttributeNS(ADTCORE_NS, "name") || ref.getAttribute("adtcore:name") || "";
|
|
2362
|
+
const description = ref.getAttributeNS(ADTCORE_NS, "description") || ref.getAttribute("adtcore:description") || void 0;
|
|
2363
|
+
if (!uri && !name) return null;
|
|
2364
|
+
const result = { uri, type, name };
|
|
2365
|
+
if (description) result.description = description;
|
|
2366
|
+
return result;
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2078
2369
|
// src/core/adt/data_extraction/previewParser.ts
|
|
2079
2370
|
function parseDataPreview(xml, maxRows, isTable) {
|
|
2080
2371
|
const [doc, parseErr] = safeParseXml(xml);
|
|
@@ -2401,80 +2692,6 @@ function parseSearchResults(xml) {
|
|
|
2401
2692
|
return ok(results);
|
|
2402
2693
|
}
|
|
2403
2694
|
|
|
2404
|
-
// src/core/adt/discovery/whereUsed.ts
|
|
2405
|
-
async function findWhereUsed(client, object) {
|
|
2406
|
-
const config = getConfigByExtension(object.extension);
|
|
2407
|
-
if (!config) {
|
|
2408
|
-
return err(new Error(`Unsupported extension: ${object.extension}`));
|
|
2409
|
-
}
|
|
2410
|
-
const uri = `/sap/bc/adt/${config.endpoint}/${object.name}`;
|
|
2411
|
-
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
2412
|
-
<usagereferences:usageReferenceRequest xmlns:usagereferences="http://www.sap.com/adt/ris/usageReferences">
|
|
2413
|
-
<usagereferences:affectedObjects/>
|
|
2414
|
-
</usagereferences:usageReferenceRequest>`;
|
|
2415
|
-
const [response, requestErr] = await client.request({
|
|
2416
|
-
method: "POST",
|
|
2417
|
-
path: "/sap/bc/adt/repository/informationsystem/usageReferences",
|
|
2418
|
-
params: {
|
|
2419
|
-
"uri": uri,
|
|
2420
|
-
"ris_request_type": "usageReferences"
|
|
2421
|
-
},
|
|
2422
|
-
headers: {
|
|
2423
|
-
"Content-Type": "application/vnd.sap.adt.repository.usagereferences.request.v1+xml",
|
|
2424
|
-
"Accept": "application/vnd.sap.adt.repository.usagereferences.result.v1+xml"
|
|
2425
|
-
},
|
|
2426
|
-
body
|
|
2427
|
-
});
|
|
2428
|
-
if (requestErr) {
|
|
2429
|
-
return err(requestErr);
|
|
2430
|
-
}
|
|
2431
|
-
if (!response.ok) {
|
|
2432
|
-
const text2 = await response.text();
|
|
2433
|
-
const errorMsg = extractError(text2);
|
|
2434
|
-
return err(new Error(`Where-used query failed: ${errorMsg}`));
|
|
2435
|
-
}
|
|
2436
|
-
const text = await response.text();
|
|
2437
|
-
const [dependencies, parseErr] = parseWhereUsed(text);
|
|
2438
|
-
if (parseErr) {
|
|
2439
|
-
return err(parseErr);
|
|
2440
|
-
}
|
|
2441
|
-
return ok(dependencies);
|
|
2442
|
-
}
|
|
2443
|
-
function parseWhereUsed(xml) {
|
|
2444
|
-
const [doc, parseErr] = safeParseXml(xml);
|
|
2445
|
-
if (parseErr) {
|
|
2446
|
-
return err(parseErr);
|
|
2447
|
-
}
|
|
2448
|
-
const dependencies = [];
|
|
2449
|
-
const referencedObjects = doc.getElementsByTagNameNS(
|
|
2450
|
-
"http://www.sap.com/adt/ris/usageReferences",
|
|
2451
|
-
"referencedObject"
|
|
2452
|
-
);
|
|
2453
|
-
for (let i = 0; i < referencedObjects.length; i++) {
|
|
2454
|
-
const refObj = referencedObjects[i];
|
|
2455
|
-
if (!refObj) continue;
|
|
2456
|
-
const adtObject = refObj.getElementsByTagNameNS(
|
|
2457
|
-
"http://www.sap.com/adt/ris/usageReferences",
|
|
2458
|
-
"adtObject"
|
|
2459
|
-
)[0];
|
|
2460
|
-
if (!adtObject) continue;
|
|
2461
|
-
const name = adtObject.getAttributeNS("http://www.sap.com/adt/core", "name") || adtObject.getAttribute("adtcore:name");
|
|
2462
|
-
const type = adtObject.getAttributeNS("http://www.sap.com/adt/core", "type") || adtObject.getAttribute("adtcore:type");
|
|
2463
|
-
if (!name || !type) continue;
|
|
2464
|
-
const config = getConfigByType(type);
|
|
2465
|
-
if (!config) continue;
|
|
2466
|
-
const packageRef = adtObject.getElementsByTagNameNS("http://www.sap.com/adt/core", "packageRef")[0];
|
|
2467
|
-
const packageName = packageRef ? packageRef.getAttributeNS("http://www.sap.com/adt/core", "name") || packageRef.getAttribute("adtcore:name") : "";
|
|
2468
|
-
dependencies.push({
|
|
2469
|
-
name,
|
|
2470
|
-
extension: config.extension,
|
|
2471
|
-
package: packageName || "",
|
|
2472
|
-
usageType: "reference"
|
|
2473
|
-
});
|
|
2474
|
-
}
|
|
2475
|
-
return ok(dependencies);
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2478
2695
|
// src/core/adt/transports/createTransport.ts
|
|
2479
2696
|
async function createTransport(client, config) {
|
|
2480
2697
|
const body = dictToAbapXml({
|
|
@@ -2867,16 +3084,7 @@ async function activate(state, requestor, objects) {
|
|
|
2867
3084
|
// src/client/methods/craud/delete.ts
|
|
2868
3085
|
async function deleteObjects(state, requestor, objects, transport) {
|
|
2869
3086
|
if (!state.session) return err(new Error("Not logged in"));
|
|
2870
|
-
|
|
2871
|
-
const [lockHandle, lockErr] = await lockObject(requestor, obj);
|
|
2872
|
-
if (lockErr) return err(lockErr);
|
|
2873
|
-
const [, deleteErr] = await deleteObject(requestor, obj, lockHandle, transport);
|
|
2874
|
-
if (deleteErr) {
|
|
2875
|
-
await unlockObject(requestor, obj, lockHandle);
|
|
2876
|
-
return err(deleteErr);
|
|
2877
|
-
}
|
|
2878
|
-
}
|
|
2879
|
-
return ok(void 0);
|
|
3087
|
+
return multiDeleteObjects(requestor, objects, transport);
|
|
2880
3088
|
}
|
|
2881
3089
|
|
|
2882
3090
|
// src/client/methods/craud/checkSyntax.ts
|
|
@@ -2909,6 +3117,12 @@ async function getTransports2(state, requestor, packageName) {
|
|
|
2909
3117
|
return getTransports(requestor, packageName);
|
|
2910
3118
|
}
|
|
2911
3119
|
|
|
3120
|
+
// src/client/methods/discovery/getInactiveObjects.ts
|
|
3121
|
+
async function getInactiveObjects2(state, requestor) {
|
|
3122
|
+
if (!state.session) return err(new Error("Not logged in"));
|
|
3123
|
+
return getInactiveObjects(requestor);
|
|
3124
|
+
}
|
|
3125
|
+
|
|
2912
3126
|
// src/client/methods/preview/previewData.ts
|
|
2913
3127
|
async function previewData2(state, requestor, query) {
|
|
2914
3128
|
if (!state.session) return err(new Error("Not logged in"));
|
|
@@ -3318,6 +3532,9 @@ var ADTClientImpl = class {
|
|
|
3318
3532
|
async getTransports(packageName) {
|
|
3319
3533
|
return getTransports2(this.state, this.requestor, packageName);
|
|
3320
3534
|
}
|
|
3535
|
+
async getInactiveObjects() {
|
|
3536
|
+
return getInactiveObjects2(this.state, this.requestor);
|
|
3537
|
+
}
|
|
3321
3538
|
// --- Data Preview ---
|
|
3322
3539
|
async previewData(query) {
|
|
3323
3540
|
return previewData2(this.state, this.requestor, query);
|