@mcp-abap-adt/adt-backup 0.1.2 → 1.1.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.
Files changed (66) hide show
  1. package/README.md +4 -2
  2. package/dist/bin/adt-backup.js +0 -0
  3. package/dist/lib/auth/createTokenProvider.d.ts +1 -1
  4. package/dist/lib/auth/createTokenProvider.d.ts.map +1 -1
  5. package/dist/lib/auth/createTokenProvider.js +2 -1
  6. package/dist/lib/auth/getSapConfigFromBroker.d.ts +1 -0
  7. package/dist/lib/auth/getSapConfigFromBroker.d.ts.map +1 -1
  8. package/dist/lib/auth/getSapConfigFromBroker.js +94 -95
  9. package/dist/lib/backup/backupObject.js +5 -5
  10. package/dist/lib/backup/readMetadataXmlForType.d.ts +1 -1
  11. package/dist/lib/backup/readMetadataXmlForType.d.ts.map +1 -1
  12. package/dist/lib/backup/readMetadataXmlForType.js +113 -98
  13. package/dist/lib/backup/readSourceText.d.ts +1 -1
  14. package/dist/lib/backup/readSourceText.d.ts.map +1 -1
  15. package/dist/lib/backup/readSourceText.js +96 -93
  16. package/dist/lib/cli/createLogger.d.ts.map +1 -1
  17. package/dist/lib/cli/createLogger.js +18 -0
  18. package/dist/lib/cli/parseArgs.d.ts +1 -1
  19. package/dist/lib/cli/parseArgs.d.ts.map +1 -1
  20. package/dist/lib/cli/parseArgs.js +25 -10
  21. package/dist/lib/cli/usage.d.ts.map +1 -1
  22. package/dist/lib/cli/usage.js +92 -88
  23. package/dist/lib/restore/analyzeDependencies.d.ts +13 -0
  24. package/dist/lib/restore/analyzeDependencies.d.ts.map +1 -0
  25. package/dist/lib/restore/analyzeDependencies.js +187 -0
  26. package/dist/lib/restore/restoreObjects.d.ts.map +1 -1
  27. package/dist/lib/restore/restoreObjects.js +49 -10
  28. package/dist/lib/restore/restoreTreeBackup.d.ts +1 -1
  29. package/dist/lib/restore/restoreTreeBackup.d.ts.map +1 -1
  30. package/dist/lib/restore/restoreTreeBackup.js +192 -42
  31. package/dist/lib/restore/restoreTreeNode.d.ts +1 -1
  32. package/dist/lib/restore/restoreTreeNode.d.ts.map +1 -1
  33. package/dist/lib/restore/restoreTreeNode.js +116 -37
  34. package/dist/lib/run.d.ts.map +1 -1
  35. package/dist/lib/run.js +402 -559
  36. package/dist/lib/tree/buildConfigForNode.d.ts.map +1 -1
  37. package/dist/lib/tree/buildConfigForNode.js +11 -0
  38. package/dist/lib/tree/buildPackageBackupTree.d.ts.map +1 -1
  39. package/dist/lib/tree/buildPackageBackupTree.js +9 -3
  40. package/dist/lib/tree/enrichTreeNode.d.ts.map +1 -1
  41. package/dist/lib/tree/enrichTreeNode.js +17 -1
  42. package/dist/lib/tree/isRestoreImplemented.d.ts.map +1 -1
  43. package/dist/lib/tree/isRestoreImplemented.js +1 -0
  44. package/dist/lib/tree/mapAdtTypeToSupported.d.ts.map +1 -1
  45. package/dist/lib/tree/mapAdtTypeToSupported.js +3 -0
  46. package/dist/lib/tree/readPayloadForType.d.ts.map +1 -1
  47. package/dist/lib/tree/readPayloadForType.js +3 -2
  48. package/dist/lib/types.d.ts +22 -2
  49. package/dist/lib/types.d.ts.map +1 -1
  50. package/dist/lib/utils/applyConfigName.d.ts.map +1 -1
  51. package/dist/lib/utils/applyConfigName.js +3 -0
  52. package/dist/lib/utils/parseBdefSource.d.ts +9 -0
  53. package/dist/lib/utils/parseBdefSource.d.ts.map +1 -0
  54. package/dist/lib/utils/parseBdefSource.js +18 -0
  55. package/dist/lib/verify/formatVerifyResultsText.d.ts +1 -1
  56. package/dist/lib/verify/formatVerifyResultsText.d.ts.map +1 -1
  57. package/dist/lib/verify/formatVerifyResultsText.js +76 -14
  58. package/dist/lib/verify/types.d.ts +3 -0
  59. package/dist/lib/verify/types.d.ts.map +1 -1
  60. package/dist/lib/verify/verifyBackup.d.ts +4 -2
  61. package/dist/lib/verify/verifyBackup.d.ts.map +1 -1
  62. package/dist/lib/verify/verifyBackup.js +67 -32
  63. package/dist/lib/verify/verifyObjectInSystem.d.ts +1 -1
  64. package/dist/lib/verify/verifyObjectInSystem.d.ts.map +1 -1
  65. package/dist/lib/verify/verifyObjectInSystem.js +39 -105
  66. 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
- const findOtherType_1 = require("./findOtherType");
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
- metadataXml = await (0, readMetadataXmlForType_1.readMetadataXmlForType)(client, spec.type, spec.name, spec.functionGroupName);
36
- }
37
- catch (error) {
38
- const status = getHttpStatus(error);
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
- // If it's a package, and we failed to read metadata, let's try a simpler check
63
- if (spec.type === 'package') {
64
- try {
65
- await client.getUtils().getPackageContents(spec.name);
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
- catch (innerError) {
69
- const innerStatus = getHttpStatus(innerError);
70
- if (innerStatus === 404) {
71
- return { ...base, status: 'missing', message: 'Package not found' };
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
- return {
76
- ...base,
77
- status: 'error',
78
- message: error instanceof Error ? error.message : String(error),
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
- else {
109
- try {
110
- const actualSource = await (0, readSourceText_1.readSourceText)(client, spec);
111
- if (actualSource === undefined) {
112
- return {
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.1.2",
3
+ "version": "1.1.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": "0.3.22",
51
+ "@mcp-abap-adt/adt-clients": "^2.2.0",
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.3.7",
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.0",
61
+ "@types/node": "^25.3.1",
62
62
  "typescript": "^5.9.2"
63
63
  }
64
64
  }