catalyst-relay 0.5.2 → 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 +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +224 -82
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +224 -82
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -182,7 +182,7 @@ type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
|
|
|
182
182
|
/**
|
|
183
183
|
* Machine-readable error codes
|
|
184
184
|
*/
|
|
185
|
-
type ErrorCode = 'AUTH_FAILED' | 'SESSION_EXPIRED' | 'SESSION_NOT_FOUND' | 'CSRF_INVALID' | 'OBJECT_LOCKED' | 'OBJECT_NOT_FOUND' | 'TRANSPORT_REQUIRED' | 'ACTIVATION_FAILED' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
185
|
+
type ErrorCode = 'AUTH_FAILED' | 'SESSION_EXPIRED' | 'SESSION_NOT_FOUND' | 'CSRF_INVALID' | 'OBJECT_LOCKED' | 'OBJECT_NOT_FOUND' | 'TRANSPORT_REQUIRED' | 'ACTIVATION_FAILED' | 'CHECK_FAILED' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
186
186
|
|
|
187
187
|
/**
|
|
188
188
|
* Session management type definitions
|
|
@@ -308,6 +308,13 @@ interface ActivationMessage {
|
|
|
308
308
|
column?: number;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
interface CheckResult {
|
|
312
|
+
name: string;
|
|
313
|
+
extension: string;
|
|
314
|
+
status: 'success' | 'warning' | 'error';
|
|
315
|
+
messages: ActivationMessage[];
|
|
316
|
+
}
|
|
317
|
+
|
|
311
318
|
/**
|
|
312
319
|
* Tree types — Public and internal type definitions
|
|
313
320
|
*/
|
|
@@ -341,6 +348,21 @@ interface Package {
|
|
|
341
348
|
name: string;
|
|
342
349
|
description?: string;
|
|
343
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Get list of available packages
|
|
353
|
+
*
|
|
354
|
+
* Uses the ADT search API with DEVC/K object type to search for packages,
|
|
355
|
+
* then enriches results with descriptions from the virtualfolders API.
|
|
356
|
+
*
|
|
357
|
+
* @param client - ADT client
|
|
358
|
+
* @param filter - Package name filter pattern (default: '*' for all packages)
|
|
359
|
+
* Examples: 'Z*' for custom packages, '$TMP' for local, 'ZSNAP*' for specific prefix
|
|
360
|
+
* @returns Array of packages or error
|
|
361
|
+
*/
|
|
362
|
+
interface GetPackagesOptions {
|
|
363
|
+
filter?: string;
|
|
364
|
+
includeDescriptions?: boolean;
|
|
365
|
+
}
|
|
344
366
|
|
|
345
367
|
/**
|
|
346
368
|
* Transports — List transport requests for a package
|
|
@@ -543,8 +565,9 @@ interface ADTClient {
|
|
|
543
565
|
update(object: ObjectContent, transport?: string): AsyncResult<void>;
|
|
544
566
|
upsert(objects: ObjectContent[], packageName: string, transport?: string): AsyncResult<UpsertResult[]>;
|
|
545
567
|
activate(objects: ObjectRef[]): AsyncResult<ActivationResult[]>;
|
|
568
|
+
checkSyntax(objects: ObjectRef[]): AsyncResult<CheckResult[]>;
|
|
546
569
|
delete(objects: ObjectRef[], transport?: string): AsyncResult<void>;
|
|
547
|
-
getPackages(
|
|
570
|
+
getPackages(options?: GetPackagesOptions): AsyncResult<Package[]>;
|
|
548
571
|
getTree(query: TreeQuery): AsyncResult<TreeResponse>;
|
|
549
572
|
getPackageStats(packageName: string): AsyncResult<PackageNode>;
|
|
550
573
|
getPackageStats(packageNames: string[]): AsyncResult<PackageNode[]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -182,7 +182,7 @@ type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
|
|
|
182
182
|
/**
|
|
183
183
|
* Machine-readable error codes
|
|
184
184
|
*/
|
|
185
|
-
type ErrorCode = 'AUTH_FAILED' | 'SESSION_EXPIRED' | 'SESSION_NOT_FOUND' | 'CSRF_INVALID' | 'OBJECT_LOCKED' | 'OBJECT_NOT_FOUND' | 'TRANSPORT_REQUIRED' | 'ACTIVATION_FAILED' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
185
|
+
type ErrorCode = 'AUTH_FAILED' | 'SESSION_EXPIRED' | 'SESSION_NOT_FOUND' | 'CSRF_INVALID' | 'OBJECT_LOCKED' | 'OBJECT_NOT_FOUND' | 'TRANSPORT_REQUIRED' | 'ACTIVATION_FAILED' | 'CHECK_FAILED' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
186
186
|
|
|
187
187
|
/**
|
|
188
188
|
* Session management type definitions
|
|
@@ -308,6 +308,13 @@ interface ActivationMessage {
|
|
|
308
308
|
column?: number;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
interface CheckResult {
|
|
312
|
+
name: string;
|
|
313
|
+
extension: string;
|
|
314
|
+
status: 'success' | 'warning' | 'error';
|
|
315
|
+
messages: ActivationMessage[];
|
|
316
|
+
}
|
|
317
|
+
|
|
311
318
|
/**
|
|
312
319
|
* Tree types — Public and internal type definitions
|
|
313
320
|
*/
|
|
@@ -341,6 +348,21 @@ interface Package {
|
|
|
341
348
|
name: string;
|
|
342
349
|
description?: string;
|
|
343
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Get list of available packages
|
|
353
|
+
*
|
|
354
|
+
* Uses the ADT search API with DEVC/K object type to search for packages,
|
|
355
|
+
* then enriches results with descriptions from the virtualfolders API.
|
|
356
|
+
*
|
|
357
|
+
* @param client - ADT client
|
|
358
|
+
* @param filter - Package name filter pattern (default: '*' for all packages)
|
|
359
|
+
* Examples: 'Z*' for custom packages, '$TMP' for local, 'ZSNAP*' for specific prefix
|
|
360
|
+
* @returns Array of packages or error
|
|
361
|
+
*/
|
|
362
|
+
interface GetPackagesOptions {
|
|
363
|
+
filter?: string;
|
|
364
|
+
includeDescriptions?: boolean;
|
|
365
|
+
}
|
|
344
366
|
|
|
345
367
|
/**
|
|
346
368
|
* Transports — List transport requests for a package
|
|
@@ -543,8 +565,9 @@ interface ADTClient {
|
|
|
543
565
|
update(object: ObjectContent, transport?: string): AsyncResult<void>;
|
|
544
566
|
upsert(objects: ObjectContent[], packageName: string, transport?: string): AsyncResult<UpsertResult[]>;
|
|
545
567
|
activate(objects: ObjectRef[]): AsyncResult<ActivationResult[]>;
|
|
568
|
+
checkSyntax(objects: ObjectRef[]): AsyncResult<CheckResult[]>;
|
|
546
569
|
delete(objects: ObjectRef[], transport?: string): AsyncResult<void>;
|
|
547
|
-
getPackages(
|
|
570
|
+
getPackages(options?: GetPackagesOptions): AsyncResult<Package[]>;
|
|
548
571
|
getTree(query: TreeQuery): AsyncResult<TreeResponse>;
|
|
549
572
|
getPackageStats(packageName: string): AsyncResult<PackageNode>;
|
|
550
573
|
getPackageStats(packageNames: string[]): AsyncResult<PackageNode[]>;
|
package/dist/index.js
CHANGED
|
@@ -1535,8 +1535,201 @@ function extractActivationErrors(objects, xml, _extension) {
|
|
|
1535
1535
|
return ok(results);
|
|
1536
1536
|
}
|
|
1537
1537
|
|
|
1538
|
+
// src/core/adt/craud/syntaxCheck.ts
|
|
1539
|
+
async function checkSyntax(client, objects) {
|
|
1540
|
+
if (objects.length === 0) {
|
|
1541
|
+
return ok([]);
|
|
1542
|
+
}
|
|
1543
|
+
const extension = objects[0].extension;
|
|
1544
|
+
const config = getConfigByExtension(extension);
|
|
1545
|
+
if (!config) return err(new Error(`Unsupported extension: ${extension}`));
|
|
1546
|
+
for (const obj of objects) {
|
|
1547
|
+
if (obj.extension !== extension) {
|
|
1548
|
+
return err(new Error("All objects must have the same extension for batch syntax check"));
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
const sources = /* @__PURE__ */ new Map();
|
|
1552
|
+
for (const obj of objects) {
|
|
1553
|
+
const [result, readErr] = await readObject(client, obj);
|
|
1554
|
+
if (readErr) return err(new Error(`Failed to read ${obj.name}: ${readErr.message}`));
|
|
1555
|
+
sources.set(obj.name.toLowerCase(), result.content);
|
|
1556
|
+
}
|
|
1557
|
+
const objectRefs = objects.map((obj) => {
|
|
1558
|
+
const uri = `/sap/bc/adt/${config.endpoint}/${obj.name.toLowerCase()}`;
|
|
1559
|
+
const sourceUri = `${uri}/source/main`;
|
|
1560
|
+
const content = sources.get(obj.name.toLowerCase()) ?? "";
|
|
1561
|
+
const encoded = Buffer.from(content).toString("base64");
|
|
1562
|
+
return `<chkrun:checkObject adtcore:uri="${uri}" chkrun:version="active">
|
|
1563
|
+
<chkrun:artifacts>
|
|
1564
|
+
<chkrun:artifact chkrun:contentType="text/plain; charset=utf-8" chkrun:uri="${sourceUri}">
|
|
1565
|
+
<chkrun:content>${encoded}</chkrun:content>
|
|
1566
|
+
</chkrun:artifact>
|
|
1567
|
+
</chkrun:artifacts>
|
|
1568
|
+
</chkrun:checkObject>`;
|
|
1569
|
+
}).join("\n ");
|
|
1570
|
+
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1571
|
+
<chkrun:checkObjectList xmlns:chkrun="http://www.sap.com/adt/checkrun"
|
|
1572
|
+
xmlns:adtcore="http://www.sap.com/adt/core">
|
|
1573
|
+
${objectRefs}
|
|
1574
|
+
</chkrun:checkObjectList>`;
|
|
1575
|
+
const [response, requestErr] = await client.request({
|
|
1576
|
+
method: "POST",
|
|
1577
|
+
path: "/sap/bc/adt/checkruns",
|
|
1578
|
+
params: {
|
|
1579
|
+
"reporters": "abapCheckRun"
|
|
1580
|
+
},
|
|
1581
|
+
headers: {
|
|
1582
|
+
"Content-Type": "application/vnd.sap.adt.checkobjects+xml",
|
|
1583
|
+
"Accept": "application/vnd.sap.adt.checkmessages+xml"
|
|
1584
|
+
},
|
|
1585
|
+
body
|
|
1586
|
+
});
|
|
1587
|
+
if (requestErr) {
|
|
1588
|
+
return err(requestErr);
|
|
1589
|
+
}
|
|
1590
|
+
const text = await response.text();
|
|
1591
|
+
debug(`Syntax check response status: ${response.status}`);
|
|
1592
|
+
debug(`Syntax check response: ${text.substring(0, 500)}`);
|
|
1593
|
+
if (!response.ok) {
|
|
1594
|
+
const errorMsg = extractError(text);
|
|
1595
|
+
return err(new Error(`Syntax check failed: ${errorMsg}`));
|
|
1596
|
+
}
|
|
1597
|
+
const [results, parseErr] = extractCheckMessages(objects, text);
|
|
1598
|
+
if (parseErr) {
|
|
1599
|
+
return err(parseErr);
|
|
1600
|
+
}
|
|
1601
|
+
return ok(results);
|
|
1602
|
+
}
|
|
1603
|
+
function extractCheckMessages(objects, xml) {
|
|
1604
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
1605
|
+
if (parseErr) {
|
|
1606
|
+
return err(parseErr);
|
|
1607
|
+
}
|
|
1608
|
+
const messageMap = /* @__PURE__ */ new Map();
|
|
1609
|
+
objects.forEach((obj) => messageMap.set(obj.name.toLowerCase(), []));
|
|
1610
|
+
let msgElements = doc.getElementsByTagName("chkrun:checkMessage");
|
|
1611
|
+
if (msgElements.length === 0) {
|
|
1612
|
+
msgElements = doc.getElementsByTagName("checkMessage");
|
|
1613
|
+
}
|
|
1614
|
+
const startRegex = /#start=(\d+),(\d+)/;
|
|
1615
|
+
for (let i = 0; i < msgElements.length; i++) {
|
|
1616
|
+
const msg = msgElements[i];
|
|
1617
|
+
if (!msg) continue;
|
|
1618
|
+
const type = msg.getAttribute("chkrun:type") ?? msg.getAttribute("type");
|
|
1619
|
+
if (!type) continue;
|
|
1620
|
+
const uri = msg.getAttribute("chkrun:uri") ?? msg.getAttribute("uri") ?? "";
|
|
1621
|
+
let line;
|
|
1622
|
+
let column;
|
|
1623
|
+
const match = startRegex.exec(uri);
|
|
1624
|
+
if (match && match[1] && match[2]) {
|
|
1625
|
+
line = parseInt(match[1], 10);
|
|
1626
|
+
column = parseInt(match[2], 10);
|
|
1627
|
+
}
|
|
1628
|
+
const matchingObj = objects.find(
|
|
1629
|
+
(obj) => uri.toLowerCase().includes(obj.name.toLowerCase())
|
|
1630
|
+
);
|
|
1631
|
+
if (!matchingObj) continue;
|
|
1632
|
+
const text = msg.getAttribute("chkrun:shortText") ?? msg.getAttribute("shortText");
|
|
1633
|
+
if (!text) continue;
|
|
1634
|
+
const message = {
|
|
1635
|
+
severity: type === "E" ? "error" : type === "W" ? "warning" : "info",
|
|
1636
|
+
text,
|
|
1637
|
+
...line !== void 0 && { line },
|
|
1638
|
+
...column !== void 0 && { column }
|
|
1639
|
+
};
|
|
1640
|
+
const messages = messageMap.get(matchingObj.name.toLowerCase()) || [];
|
|
1641
|
+
messages.push(message);
|
|
1642
|
+
messageMap.set(matchingObj.name.toLowerCase(), messages);
|
|
1643
|
+
}
|
|
1644
|
+
const results = objects.map((obj) => {
|
|
1645
|
+
const messages = messageMap.get(obj.name.toLowerCase()) || [];
|
|
1646
|
+
const hasErrors = messages.some((m) => m.severity === "error");
|
|
1647
|
+
return {
|
|
1648
|
+
name: obj.name,
|
|
1649
|
+
extension: obj.extension,
|
|
1650
|
+
status: hasErrors ? "error" : messages.length > 0 ? "warning" : "success",
|
|
1651
|
+
messages
|
|
1652
|
+
};
|
|
1653
|
+
});
|
|
1654
|
+
return ok(results);
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
// src/core/adt/discovery/tree/packageStats.ts
|
|
1658
|
+
function constructPackageStatsBody(packageNames) {
|
|
1659
|
+
const names = packageNames.length === 1 ? [...packageNames, "SRIS_TEST_DATA_VFS_EMPTY"] : packageNames;
|
|
1660
|
+
const values = names.map((name) => ` <vfs:value>${name}</vfs:value>`).join("\n");
|
|
1661
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1662
|
+
<vfs:virtualFoldersRequest xmlns:vfs="http://www.sap.com/adt/ris/virtualFolders" objectSearchPattern="*">
|
|
1663
|
+
<vfs:preselection facet="package">
|
|
1664
|
+
${values}
|
|
1665
|
+
</vfs:preselection>
|
|
1666
|
+
<vfs:facetorder>
|
|
1667
|
+
<vfs:facet>package</vfs:facet>
|
|
1668
|
+
<vfs:facet>group</vfs:facet>
|
|
1669
|
+
<vfs:facet>type</vfs:facet>
|
|
1670
|
+
</vfs:facetorder>
|
|
1671
|
+
</vfs:virtualFoldersRequest>`;
|
|
1672
|
+
}
|
|
1673
|
+
function parsePackageStats(xml) {
|
|
1674
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
1675
|
+
if (parseErr) return [];
|
|
1676
|
+
const packages = [];
|
|
1677
|
+
const virtualFolders = doc.getElementsByTagName("vfs:virtualFolder");
|
|
1678
|
+
for (let i = 0; i < virtualFolders.length; i++) {
|
|
1679
|
+
const vf = virtualFolders[i];
|
|
1680
|
+
if (!vf) continue;
|
|
1681
|
+
const facet = vf.getAttribute("facet")?.toUpperCase();
|
|
1682
|
+
if (facet !== "PACKAGE") continue;
|
|
1683
|
+
const name = vf.getAttribute("name");
|
|
1684
|
+
if (!name) continue;
|
|
1685
|
+
const countAttr = vf.getAttribute("counter");
|
|
1686
|
+
const count = countAttr ? parseInt(countAttr, 10) : 0;
|
|
1687
|
+
const description = vf.getAttribute("text");
|
|
1688
|
+
const pkg = {
|
|
1689
|
+
name,
|
|
1690
|
+
numContents: count
|
|
1691
|
+
};
|
|
1692
|
+
if (description) pkg.description = description;
|
|
1693
|
+
packages.push(pkg);
|
|
1694
|
+
}
|
|
1695
|
+
return packages;
|
|
1696
|
+
}
|
|
1697
|
+
async function getPackageStats(client, packageNames) {
|
|
1698
|
+
const isSingle = typeof packageNames === "string";
|
|
1699
|
+
const names = isSingle ? [packageNames] : packageNames;
|
|
1700
|
+
if (names.length === 0) {
|
|
1701
|
+
return ok([]);
|
|
1702
|
+
}
|
|
1703
|
+
const body = constructPackageStatsBody(names);
|
|
1704
|
+
const [response, requestErr] = await client.request({
|
|
1705
|
+
method: "POST",
|
|
1706
|
+
path: "/sap/bc/adt/repository/informationsystem/virtualfolders/contents",
|
|
1707
|
+
headers: {
|
|
1708
|
+
"Content-Type": "application/vnd.sap.adt.repository.virtualfolders.request.v1+xml",
|
|
1709
|
+
"Accept": "application/vnd.sap.adt.repository.virtualfolders.result.v1+xml"
|
|
1710
|
+
},
|
|
1711
|
+
body
|
|
1712
|
+
});
|
|
1713
|
+
if (requestErr) return err(requestErr);
|
|
1714
|
+
if (!response.ok) {
|
|
1715
|
+
const text = await response.text();
|
|
1716
|
+
const errorMsg = extractError(text);
|
|
1717
|
+
return err(new Error(`Package stats fetch failed: ${errorMsg}`));
|
|
1718
|
+
}
|
|
1719
|
+
const xml = await response.text();
|
|
1720
|
+
const packages = parsePackageStats(xml).filter((pkg) => pkg.name !== "SRIS_TEST_DATA_VFS_EMPTY");
|
|
1721
|
+
if (isSingle) {
|
|
1722
|
+
if (packages.length === 0) {
|
|
1723
|
+
return err(new Error(`Package ${packageNames} not found`));
|
|
1724
|
+
}
|
|
1725
|
+
return ok(packages[0]);
|
|
1726
|
+
}
|
|
1727
|
+
return ok(packages);
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1538
1730
|
// src/core/adt/discovery/packages.ts
|
|
1539
|
-
async function getPackages(client,
|
|
1731
|
+
async function getPackages(client, options = {}) {
|
|
1732
|
+
const { filter = "*", includeDescriptions = false } = options;
|
|
1540
1733
|
const params = new URLSearchParams([
|
|
1541
1734
|
["operation", "quickSearch"],
|
|
1542
1735
|
["query", filter],
|
|
@@ -1560,18 +1753,31 @@ async function getPackages(client, filter = "*") {
|
|
|
1560
1753
|
if (parseErr) {
|
|
1561
1754
|
return err(parseErr);
|
|
1562
1755
|
}
|
|
1563
|
-
const
|
|
1756
|
+
const packageNames = [];
|
|
1564
1757
|
const objectRefs = doc.getElementsByTagNameNS("http://www.sap.com/adt/core", "objectReference");
|
|
1565
1758
|
for (let i = 0; i < objectRefs.length; i++) {
|
|
1566
1759
|
const obj = objectRefs[i];
|
|
1567
1760
|
if (!obj) return err(new Error("Invalid object reference in package search results"));
|
|
1568
1761
|
const name = obj.getAttributeNS("http://www.sap.com/adt/core", "name") || obj.getAttribute("adtcore:name");
|
|
1569
|
-
const description = obj.getAttributeNS("http://www.sap.com/adt/core", "description") || obj.getAttribute("adtcore:description");
|
|
1570
1762
|
if (!name) return err(new Error("Package name missing in object reference"));
|
|
1763
|
+
packageNames.push(name);
|
|
1764
|
+
}
|
|
1765
|
+
if (packageNames.length === 0) return ok([]);
|
|
1766
|
+
if (!includeDescriptions) return ok(packageNames.map((name) => ({ name })));
|
|
1767
|
+
const [stats, statsErr] = await getPackageStats(client, packageNames);
|
|
1768
|
+
if (statsErr) {
|
|
1769
|
+
return ok(packageNames.map((name) => ({ name })));
|
|
1770
|
+
}
|
|
1771
|
+
const descriptionMap = /* @__PURE__ */ new Map();
|
|
1772
|
+
for (const stat2 of stats) {
|
|
1773
|
+
if (stat2.description) descriptionMap.set(stat2.name, stat2.description);
|
|
1774
|
+
}
|
|
1775
|
+
const packages = packageNames.map((name) => {
|
|
1571
1776
|
const pkg = { name };
|
|
1777
|
+
const description = descriptionMap.get(name);
|
|
1572
1778
|
if (description) pkg.description = description;
|
|
1573
|
-
|
|
1574
|
-
}
|
|
1779
|
+
return pkg;
|
|
1780
|
+
});
|
|
1575
1781
|
return ok(packages);
|
|
1576
1782
|
}
|
|
1577
1783
|
|
|
@@ -1811,79 +2017,6 @@ async function getTree(client, query = {}) {
|
|
|
1811
2017
|
return ok(result);
|
|
1812
2018
|
}
|
|
1813
2019
|
|
|
1814
|
-
// src/core/adt/discovery/tree/packageStats.ts
|
|
1815
|
-
function constructPackageStatsBody(packageNames) {
|
|
1816
|
-
const names = packageNames.length === 1 ? [...packageNames, "SRIS_TEST_DATA_VFS_EMPTY"] : packageNames;
|
|
1817
|
-
const values = names.map((name) => ` <vfs:value>${name}</vfs:value>`).join("\n");
|
|
1818
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1819
|
-
<vfs:virtualFoldersRequest xmlns:vfs="http://www.sap.com/adt/ris/virtualFolders" objectSearchPattern="*">
|
|
1820
|
-
<vfs:preselection facet="package">
|
|
1821
|
-
${values}
|
|
1822
|
-
</vfs:preselection>
|
|
1823
|
-
<vfs:facetorder>
|
|
1824
|
-
<vfs:facet>package</vfs:facet>
|
|
1825
|
-
<vfs:facet>group</vfs:facet>
|
|
1826
|
-
<vfs:facet>type</vfs:facet>
|
|
1827
|
-
</vfs:facetorder>
|
|
1828
|
-
</vfs:virtualFoldersRequest>`;
|
|
1829
|
-
}
|
|
1830
|
-
function parsePackageStats(xml) {
|
|
1831
|
-
const [doc, parseErr] = safeParseXml(xml);
|
|
1832
|
-
if (parseErr) return [];
|
|
1833
|
-
const packages = [];
|
|
1834
|
-
const virtualFolders = doc.getElementsByTagName("vfs:virtualFolder");
|
|
1835
|
-
for (let i = 0; i < virtualFolders.length; i++) {
|
|
1836
|
-
const vf = virtualFolders[i];
|
|
1837
|
-
if (!vf) continue;
|
|
1838
|
-
const facet = vf.getAttribute("facet")?.toUpperCase();
|
|
1839
|
-
if (facet !== "PACKAGE") continue;
|
|
1840
|
-
const name = vf.getAttribute("name");
|
|
1841
|
-
if (!name) continue;
|
|
1842
|
-
const countAttr = vf.getAttribute("counter");
|
|
1843
|
-
const count = countAttr ? parseInt(countAttr, 10) : 0;
|
|
1844
|
-
const description = vf.getAttribute("text");
|
|
1845
|
-
const pkg = {
|
|
1846
|
-
name,
|
|
1847
|
-
numContents: count
|
|
1848
|
-
};
|
|
1849
|
-
if (description) pkg.description = description;
|
|
1850
|
-
packages.push(pkg);
|
|
1851
|
-
}
|
|
1852
|
-
return packages;
|
|
1853
|
-
}
|
|
1854
|
-
async function getPackageStats(client, packageNames) {
|
|
1855
|
-
const isSingle = typeof packageNames === "string";
|
|
1856
|
-
const names = isSingle ? [packageNames] : packageNames;
|
|
1857
|
-
if (names.length === 0) {
|
|
1858
|
-
return ok([]);
|
|
1859
|
-
}
|
|
1860
|
-
const body = constructPackageStatsBody(names);
|
|
1861
|
-
const [response, requestErr] = await client.request({
|
|
1862
|
-
method: "POST",
|
|
1863
|
-
path: "/sap/bc/adt/repository/informationsystem/virtualfolders/contents",
|
|
1864
|
-
headers: {
|
|
1865
|
-
"Content-Type": "application/vnd.sap.adt.repository.virtualfolders.request.v1+xml",
|
|
1866
|
-
"Accept": "application/vnd.sap.adt.repository.virtualfolders.result.v1+xml"
|
|
1867
|
-
},
|
|
1868
|
-
body
|
|
1869
|
-
});
|
|
1870
|
-
if (requestErr) return err(requestErr);
|
|
1871
|
-
if (!response.ok) {
|
|
1872
|
-
const text = await response.text();
|
|
1873
|
-
const errorMsg = extractError(text);
|
|
1874
|
-
return err(new Error(`Package stats fetch failed: ${errorMsg}`));
|
|
1875
|
-
}
|
|
1876
|
-
const xml = await response.text();
|
|
1877
|
-
const packages = parsePackageStats(xml).filter((pkg) => pkg.name !== "SRIS_TEST_DATA_VFS_EMPTY");
|
|
1878
|
-
if (isSingle) {
|
|
1879
|
-
if (packages.length === 0) {
|
|
1880
|
-
return err(new Error(`Package ${packageNames} not found`));
|
|
1881
|
-
}
|
|
1882
|
-
return ok(packages[0]);
|
|
1883
|
-
}
|
|
1884
|
-
return ok(packages);
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
2020
|
// src/core/adt/transports/transports.ts
|
|
1888
2021
|
async function getTransports(client, packageName) {
|
|
1889
2022
|
const contentType = "application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData";
|
|
@@ -2539,10 +2672,16 @@ async function deleteObjects(state, requestor, objects, transport) {
|
|
|
2539
2672
|
return ok(void 0);
|
|
2540
2673
|
}
|
|
2541
2674
|
|
|
2675
|
+
// src/client/methods/craud/checkSyntax.ts
|
|
2676
|
+
async function checkSyntax2(state, requestor, objects) {
|
|
2677
|
+
if (!state.session) return err(new Error("Not logged in"));
|
|
2678
|
+
return checkSyntax(requestor, objects);
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2542
2681
|
// src/client/methods/discovery/getPackages.ts
|
|
2543
|
-
async function getPackages2(state, requestor,
|
|
2682
|
+
async function getPackages2(state, requestor, options) {
|
|
2544
2683
|
if (!state.session) return err(new Error("Not logged in"));
|
|
2545
|
-
return getPackages(requestor,
|
|
2684
|
+
return getPackages(requestor, options);
|
|
2546
2685
|
}
|
|
2547
2686
|
|
|
2548
2687
|
// src/client/methods/discovery/getTree.ts
|
|
@@ -2935,12 +3074,15 @@ var ADTClientImpl = class {
|
|
|
2935
3074
|
async activate(objects) {
|
|
2936
3075
|
return activate(this.state, this.requestor, objects);
|
|
2937
3076
|
}
|
|
3077
|
+
async checkSyntax(objects) {
|
|
3078
|
+
return checkSyntax2(this.state, this.requestor, objects);
|
|
3079
|
+
}
|
|
2938
3080
|
async delete(objects, transport) {
|
|
2939
3081
|
return deleteObjects(this.state, this.requestor, objects, transport);
|
|
2940
3082
|
}
|
|
2941
3083
|
// --- Discovery ---
|
|
2942
|
-
async getPackages(
|
|
2943
|
-
return getPackages2(this.state, this.requestor,
|
|
3084
|
+
async getPackages(options) {
|
|
3085
|
+
return getPackages2(this.state, this.requestor, options);
|
|
2944
3086
|
}
|
|
2945
3087
|
async getTree(query) {
|
|
2946
3088
|
return getTree2(this.state, this.requestor, query);
|