@mcp-abap-adt/adt-backup 0.1.2 → 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/README.md +4 -2
- package/dist/bin/adt-backup.js +0 -0
- package/dist/lib/auth/createTokenProvider.d.ts +1 -1
- package/dist/lib/auth/createTokenProvider.d.ts.map +1 -1
- package/dist/lib/auth/createTokenProvider.js +2 -1
- package/dist/lib/auth/getSapConfigFromBroker.d.ts +1 -0
- package/dist/lib/auth/getSapConfigFromBroker.d.ts.map +1 -1
- package/dist/lib/auth/getSapConfigFromBroker.js +94 -95
- package/dist/lib/backup/backupObject.js +5 -5
- package/dist/lib/backup/readMetadataXmlForType.d.ts +1 -1
- package/dist/lib/backup/readMetadataXmlForType.d.ts.map +1 -1
- package/dist/lib/backup/readMetadataXmlForType.js +113 -98
- package/dist/lib/backup/readSourceText.d.ts +1 -1
- package/dist/lib/backup/readSourceText.d.ts.map +1 -1
- package/dist/lib/backup/readSourceText.js +96 -93
- package/dist/lib/cli/createLogger.d.ts.map +1 -1
- package/dist/lib/cli/createLogger.js +18 -0
- package/dist/lib/cli/parseArgs.d.ts +1 -1
- package/dist/lib/cli/parseArgs.d.ts.map +1 -1
- package/dist/lib/cli/parseArgs.js +25 -10
- package/dist/lib/cli/usage.d.ts.map +1 -1
- package/dist/lib/cli/usage.js +92 -88
- package/dist/lib/restore/analyzeDependencies.d.ts +13 -0
- package/dist/lib/restore/analyzeDependencies.d.ts.map +1 -0
- package/dist/lib/restore/analyzeDependencies.js +187 -0
- package/dist/lib/restore/restoreObjects.d.ts.map +1 -1
- package/dist/lib/restore/restoreObjects.js +49 -10
- package/dist/lib/restore/restoreTreeBackup.d.ts +1 -1
- package/dist/lib/restore/restoreTreeBackup.d.ts.map +1 -1
- package/dist/lib/restore/restoreTreeBackup.js +192 -42
- package/dist/lib/restore/restoreTreeNode.d.ts +1 -1
- package/dist/lib/restore/restoreTreeNode.d.ts.map +1 -1
- package/dist/lib/restore/restoreTreeNode.js +116 -37
- package/dist/lib/run.d.ts.map +1 -1
- package/dist/lib/run.js +393 -559
- package/dist/lib/tree/buildConfigForNode.d.ts.map +1 -1
- package/dist/lib/tree/buildConfigForNode.js +11 -0
- package/dist/lib/tree/buildPackageBackupTree.d.ts.map +1 -1
- package/dist/lib/tree/buildPackageBackupTree.js +9 -3
- package/dist/lib/tree/enrichTreeNode.d.ts.map +1 -1
- package/dist/lib/tree/enrichTreeNode.js +17 -1
- package/dist/lib/tree/isRestoreImplemented.d.ts.map +1 -1
- package/dist/lib/tree/isRestoreImplemented.js +1 -0
- package/dist/lib/tree/mapAdtTypeToSupported.d.ts.map +1 -1
- package/dist/lib/tree/mapAdtTypeToSupported.js +3 -0
- package/dist/lib/tree/readPayloadForType.d.ts.map +1 -1
- package/dist/lib/tree/readPayloadForType.js +3 -2
- package/dist/lib/types.d.ts +22 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils/applyConfigName.d.ts.map +1 -1
- package/dist/lib/utils/applyConfigName.js +3 -0
- package/dist/lib/utils/parseBdefSource.d.ts +9 -0
- package/dist/lib/utils/parseBdefSource.d.ts.map +1 -0
- package/dist/lib/utils/parseBdefSource.js +18 -0
- package/dist/lib/verify/formatVerifyResultsText.d.ts +1 -1
- package/dist/lib/verify/formatVerifyResultsText.d.ts.map +1 -1
- package/dist/lib/verify/formatVerifyResultsText.js +76 -14
- package/dist/lib/verify/types.d.ts +3 -0
- package/dist/lib/verify/types.d.ts.map +1 -1
- package/dist/lib/verify/verifyBackup.d.ts +4 -2
- package/dist/lib/verify/verifyBackup.d.ts.map +1 -1
- package/dist/lib/verify/verifyBackup.js +67 -32
- package/dist/lib/verify/verifyObjectInSystem.d.ts +1 -1
- package/dist/lib/verify/verifyObjectInSystem.d.ts.map +1 -1
- package/dist/lib/verify/verifyObjectInSystem.js +39 -105
- package/package.json +6 -6
|
@@ -4,25 +4,8 @@ exports.verifyObjectInSystem = verifyObjectInSystem;
|
|
|
4
4
|
const readMetadataXmlForType_1 = require("../backup/readMetadataXmlForType");
|
|
5
5
|
const readSourceText_1 = require("../backup/readSourceText");
|
|
6
6
|
const decodeBase64_1 = require("../crypto/decodeBase64");
|
|
7
|
-
const verbosity_1 = require("../state/verbosity");
|
|
8
7
|
const extractMetadata_1 = require("../xml/extractMetadata");
|
|
9
|
-
|
|
10
|
-
function getHttpStatus(error) {
|
|
11
|
-
const err = error;
|
|
12
|
-
if (err.response?.status) {
|
|
13
|
-
return err.response.status;
|
|
14
|
-
}
|
|
15
|
-
if (err.status) {
|
|
16
|
-
return err.status;
|
|
17
|
-
}
|
|
18
|
-
// Check if it's a "Request failed with status code 404" style message
|
|
19
|
-
const match = String(err.message || '').match(/status code (\d+)/);
|
|
20
|
-
if (match) {
|
|
21
|
-
return Number.parseInt(match[1], 10);
|
|
22
|
-
}
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
async function verifyObjectInSystem(client, spec, expectedPackage, expectedSource, expectedSourceBase64, expectedFormat) {
|
|
8
|
+
async function verifyObjectInSystem(client, spec, expectedPackage, expectedSource, expectedSourceBase64, expectedFormat, version = 'active') {
|
|
26
9
|
const base = {
|
|
27
10
|
type: spec.type,
|
|
28
11
|
name: spec.name,
|
|
@@ -30,91 +13,42 @@ async function verifyObjectInSystem(client, spec, expectedPackage, expectedSourc
|
|
|
30
13
|
status: 'ok',
|
|
31
14
|
expectedPackage,
|
|
32
15
|
};
|
|
33
|
-
let metadataXml;
|
|
34
16
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
40
|
-
// Check if error message explicitly says "not found"
|
|
41
|
-
// Examples: "Domain 'XYZ' not found", "Function group 'ABC' not found"
|
|
42
|
-
const isNotFoundMessage = /not found/i.test(message) || /does not exist/i.test(message);
|
|
43
|
-
if (status === 404 || status === 410 || isNotFoundMessage) {
|
|
44
|
-
if (verbosity_1.verbosityState.level >= 3) {
|
|
45
|
-
const otherType = await (0, findOtherType_1.findOtherType)(client, spec.type, spec.name);
|
|
46
|
-
if (otherType) {
|
|
47
|
-
return {
|
|
48
|
-
...base,
|
|
49
|
-
status: 'type-mismatch',
|
|
50
|
-
message: `Found object of type ${otherType}`,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
...base,
|
|
56
|
-
status: 'missing',
|
|
57
|
-
message: isNotFoundMessage
|
|
58
|
-
? message
|
|
59
|
-
: 'Object does not exist in the system',
|
|
60
|
-
};
|
|
17
|
+
// 1. Try to get metadata first (works for almost everything)
|
|
18
|
+
const metadataXml = await (0, readMetadataXmlForType_1.readMetadataXmlForType)(client, spec.type, spec.name, spec.functionGroupName);
|
|
19
|
+
if (metadataXml === null) {
|
|
20
|
+
return { ...base, status: 'missing' };
|
|
61
21
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// If this succeeds, the package exists but metadata read failed for some reason
|
|
22
|
+
if (metadataXml !== undefined) {
|
|
23
|
+
const metadata = (0, extractMetadata_1.extractMetadata)(metadataXml);
|
|
24
|
+
if (metadata.packageName) {
|
|
25
|
+
base.actualPackage = metadata.packageName;
|
|
67
26
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
27
|
+
if (expectedPackage &&
|
|
28
|
+
metadata.packageName &&
|
|
29
|
+
metadata.packageName.toUpperCase() !== expectedPackage.toUpperCase()) {
|
|
30
|
+
return {
|
|
31
|
+
...base,
|
|
32
|
+
status: 'package-mismatch',
|
|
33
|
+
message: `Expected package ${expectedPackage}, found ${metadata.packageName}`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// If we don't need source check, we're done
|
|
37
|
+
if (!expectedSource && !expectedSourceBase64) {
|
|
38
|
+
return base;
|
|
73
39
|
}
|
|
74
40
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
if (!metadataXml) {
|
|
82
|
-
return {
|
|
83
|
-
...base,
|
|
84
|
-
status: 'unsupported',
|
|
85
|
-
message: 'Metadata read is not supported for this object type',
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
const metadata = (0, extractMetadata_1.extractMetadata)(metadataXml);
|
|
89
|
-
if (metadata.packageName) {
|
|
90
|
-
base.actualPackage = metadata.packageName;
|
|
91
|
-
}
|
|
92
|
-
if (expectedPackage &&
|
|
93
|
-
metadata.packageName &&
|
|
94
|
-
metadata.packageName.toUpperCase() !== expectedPackage.toUpperCase()) {
|
|
95
|
-
return {
|
|
96
|
-
...base,
|
|
97
|
-
status: 'package-mismatch',
|
|
98
|
-
message: `Expected package ${expectedPackage}, found ${metadata.packageName}`,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
const expectedText = expectedSourceBase64 !== undefined
|
|
102
|
-
? (0, decodeBase64_1.decodeBase64)(expectedSourceBase64)
|
|
103
|
-
: expectedSource;
|
|
104
|
-
if (expectedText !== undefined) {
|
|
105
|
-
if (expectedFormat === 'xml') {
|
|
106
|
-
return base;
|
|
41
|
+
// 2. Secondary check via Source (if required or metadata is unsupported)
|
|
42
|
+
const actualSource = await (0, readSourceText_1.readSourceText)(client, spec, version);
|
|
43
|
+
if (actualSource === null && metadataXml === undefined) {
|
|
44
|
+
// If metadata was unsupported AND source is missing - it's missing
|
|
45
|
+
return { ...base, status: 'missing' };
|
|
107
46
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
...base,
|
|
114
|
-
status: 'error',
|
|
115
|
-
message: 'Source not available for comparison',
|
|
116
|
-
};
|
|
117
|
-
}
|
|
47
|
+
if (actualSource !== undefined) {
|
|
48
|
+
const expectedText = expectedSourceBase64 !== undefined
|
|
49
|
+
? (0, decodeBase64_1.decodeBase64)(expectedSourceBase64)
|
|
50
|
+
: expectedSource;
|
|
51
|
+
if (expectedText !== undefined && expectedFormat !== 'xml') {
|
|
118
52
|
if (expectedText !== actualSource) {
|
|
119
53
|
return {
|
|
120
54
|
...base,
|
|
@@ -123,14 +57,14 @@ async function verifyObjectInSystem(client, spec, expectedPackage, expectedSourc
|
|
|
123
57
|
};
|
|
124
58
|
}
|
|
125
59
|
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
return {
|
|
128
|
-
...base,
|
|
129
|
-
status: 'error',
|
|
130
|
-
message: error instanceof Error ? error.message : String(error),
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
60
|
}
|
|
61
|
+
return base;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return {
|
|
65
|
+
...base,
|
|
66
|
+
status: 'error',
|
|
67
|
+
message: error.message || String(error),
|
|
68
|
+
};
|
|
134
69
|
}
|
|
135
|
-
return base;
|
|
136
70
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/adt-backup",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "ADT backup CLI for SAP ABAP objects (recursive package backups and restores)",
|
|
5
5
|
"main": "dist/bin/adt-backup.js",
|
|
6
6
|
"types": "dist/bin/adt-backup.d.ts",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"lint": "npx biome check --write src",
|
|
39
39
|
"lint:check": "npx biome check src",
|
|
40
40
|
"format": "npx biome format --write src",
|
|
41
|
-
"build": "npm run --silent clean && npx biome check src --diagnostic-level=error && npx tsc -p tsconfig.json",
|
|
42
|
-
"build:fast": "npx tsc -p tsconfig.json",
|
|
41
|
+
"build": "npm run --silent clean && npx biome check src --diagnostic-level=error && npx tsc -p tsconfig.json && chmod +x dist/bin/adt-backup.js",
|
|
42
|
+
"build:fast": "npx tsc -p tsconfig.json && chmod +x dist/bin/adt-backup.js",
|
|
43
43
|
"test:integration": "node scripts/integration-test.mjs",
|
|
44
44
|
"delete:package": "npx ts-node scripts/delete-package.ts",
|
|
45
45
|
"debug:deps": "npx ts-node scripts/debug-where-used-list.ts"
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"node": ">=18.0.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@mcp-abap-adt/adt-clients": "
|
|
51
|
+
"@mcp-abap-adt/adt-clients": "^1.1.1",
|
|
52
52
|
"@mcp-abap-adt/auth-broker": "^1.0.5",
|
|
53
53
|
"@mcp-abap-adt/auth-providers": "^1.0.5",
|
|
54
54
|
"@mcp-abap-adt/auth-stores": "^1.0.2",
|
|
55
55
|
"@mcp-abap-adt/connection": "^1.1.0",
|
|
56
|
-
"fast-xml-parser": "^5.
|
|
56
|
+
"fast-xml-parser": "^5.4.1",
|
|
57
57
|
"yaml": "^2.8.2"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@biomejs/biome": "^2.4.4",
|
|
61
|
-
"@types/node": "^25.3.
|
|
61
|
+
"@types/node": "^25.3.1",
|
|
62
62
|
"typescript": "^5.9.2"
|
|
63
63
|
}
|
|
64
64
|
}
|