@mcp-abap-adt/adt-backup 0.1.1 → 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.
Files changed (83) hide show
  1. package/README.md +34 -0
  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.d.ts.map +1 -1
  10. package/dist/lib/backup/backupObject.js +19 -5
  11. package/dist/lib/backup/readMetadataXmlForType.d.ts +1 -1
  12. package/dist/lib/backup/readMetadataXmlForType.d.ts.map +1 -1
  13. package/dist/lib/backup/readMetadataXmlForType.js +113 -92
  14. package/dist/lib/backup/readSourceText.d.ts +1 -1
  15. package/dist/lib/backup/readSourceText.d.ts.map +1 -1
  16. package/dist/lib/backup/readSourceText.js +96 -87
  17. package/dist/lib/cli/createLogger.d.ts.map +1 -1
  18. package/dist/lib/cli/createLogger.js +18 -0
  19. package/dist/lib/cli/parseArgs.d.ts +1 -1
  20. package/dist/lib/cli/parseArgs.d.ts.map +1 -1
  21. package/dist/lib/cli/parseArgs.js +25 -10
  22. package/dist/lib/cli/usage.d.ts.map +1 -1
  23. package/dist/lib/cli/usage.js +92 -87
  24. package/dist/lib/constants/typeOrder.d.ts.map +1 -1
  25. package/dist/lib/constants/typeOrder.js +1 -0
  26. package/dist/lib/dependencies/collectTreeDependencies.d.ts.map +1 -1
  27. package/dist/lib/dependencies/collectTreeDependencies.js +1 -0
  28. package/dist/lib/restore/analyzeDependencies.d.ts +13 -0
  29. package/dist/lib/restore/analyzeDependencies.d.ts.map +1 -0
  30. package/dist/lib/restore/analyzeDependencies.js +187 -0
  31. package/dist/lib/restore/restoreObject.d.ts.map +1 -1
  32. package/dist/lib/restore/restoreObject.js +13 -0
  33. package/dist/lib/restore/restoreObjects.d.ts.map +1 -1
  34. package/dist/lib/restore/restoreObjects.js +49 -10
  35. package/dist/lib/restore/restoreTreeBackup.d.ts +1 -1
  36. package/dist/lib/restore/restoreTreeBackup.d.ts.map +1 -1
  37. package/dist/lib/restore/restoreTreeBackup.js +192 -42
  38. package/dist/lib/restore/restoreTreeNode.d.ts +1 -1
  39. package/dist/lib/restore/restoreTreeNode.d.ts.map +1 -1
  40. package/dist/lib/restore/restoreTreeNode.js +128 -36
  41. package/dist/lib/run.d.ts.map +1 -1
  42. package/dist/lib/run.js +393 -559
  43. package/dist/lib/tree/buildConfigForNode.d.ts.map +1 -1
  44. package/dist/lib/tree/buildConfigForNode.js +19 -0
  45. package/dist/lib/tree/buildPackageBackupTree.d.ts.map +1 -1
  46. package/dist/lib/tree/buildPackageBackupTree.js +9 -3
  47. package/dist/lib/tree/enrichTreeNode.d.ts.map +1 -1
  48. package/dist/lib/tree/enrichTreeNode.js +17 -1
  49. package/dist/lib/tree/isRestoreImplemented.d.ts.map +1 -1
  50. package/dist/lib/tree/isRestoreImplemented.js +2 -0
  51. package/dist/lib/tree/mapAdtTypeToSupported.d.ts.map +1 -1
  52. package/dist/lib/tree/mapAdtTypeToSupported.js +6 -0
  53. package/dist/lib/tree/readPayloadForType.d.ts.map +1 -1
  54. package/dist/lib/tree/readPayloadForType.js +5 -3
  55. package/dist/lib/types.d.ts +22 -2
  56. package/dist/lib/types.d.ts.map +1 -1
  57. package/dist/lib/utils/applyConfigName.d.ts.map +1 -1
  58. package/dist/lib/utils/applyConfigName.js +6 -0
  59. package/dist/lib/utils/normalizeType.d.ts.map +1 -1
  60. package/dist/lib/utils/normalizeType.js +2 -0
  61. package/dist/lib/utils/parseBdefSource.d.ts +9 -0
  62. package/dist/lib/utils/parseBdefSource.d.ts.map +1 -0
  63. package/dist/lib/utils/parseBdefSource.js +18 -0
  64. package/dist/lib/verify/findOtherType.d.ts.map +1 -1
  65. package/dist/lib/verify/findOtherType.js +1 -0
  66. package/dist/lib/verify/formatVerifyResultsText.d.ts +1 -1
  67. package/dist/lib/verify/formatVerifyResultsText.d.ts.map +1 -1
  68. package/dist/lib/verify/formatVerifyResultsText.js +76 -14
  69. package/dist/lib/verify/types.d.ts +3 -0
  70. package/dist/lib/verify/types.d.ts.map +1 -1
  71. package/dist/lib/verify/verifyBackup.d.ts +4 -2
  72. package/dist/lib/verify/verifyBackup.d.ts.map +1 -1
  73. package/dist/lib/verify/verifyBackup.js +67 -32
  74. package/dist/lib/verify/verifyObjectInSystem.d.ts +1 -1
  75. package/dist/lib/verify/verifyObjectInSystem.d.ts.map +1 -1
  76. package/dist/lib/verify/verifyObjectInSystem.js +39 -105
  77. package/dist/lib/xml/index.d.ts +1 -0
  78. package/dist/lib/xml/index.d.ts.map +1 -1
  79. package/dist/lib/xml/index.js +1 -0
  80. package/dist/lib/xml/parseServiceBindingConfig.d.ts +3 -0
  81. package/dist/lib/xml/parseServiceBindingConfig.d.ts.map +1 -0
  82. package/dist/lib/xml/parseServiceBindingConfig.js +70 -0
  83. package/package.json +12 -12
@@ -1,54 +1,89 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.verifyBackup = verifyBackup;
4
+ const logVerbose_1 = require("../cli/logVerbose");
4
5
  const collectBackupNodes_1 = require("./collectBackupNodes");
5
6
  const getExpectedPackage_1 = require("./getExpectedPackage");
6
7
  const verifyObjectInSystem_1 = require("./verifyObjectInSystem");
7
8
  async function verifyBackup(client, backup, options) {
9
+ const mode = options?.mode || 'pre-restore';
10
+ (0, logVerbose_1.logVerbose)(1, `Verifying objects in backup (${mode} mode)...`);
11
+ const entries = await verifyIndividual(client, backup, options);
12
+ return { entries, summary: buildSummary(entries, options) };
13
+ }
14
+ async function verifyIndividual(client, backup, options) {
8
15
  const entries = [];
16
+ const nodes = [];
17
+ const mode = options?.mode || 'pre-restore';
9
18
  if (backup.schemaVersion === 2) {
10
- const tree = backup;
11
- const nodes = [];
12
- (0, collectBackupNodes_1.collectBackupNodes)(tree.root, nodes);
13
- for (const node of nodes) {
14
- if (!node.type) {
15
- continue;
16
- }
19
+ (0, collectBackupNodes_1.collectBackupNodes)(backup.root, nodes);
20
+ }
21
+ else {
22
+ nodes.push(...backup.objects);
23
+ }
24
+ (0, logVerbose_1.logVerbose)(1, `Processing ${nodes.length} objects...`);
25
+ let count = 0;
26
+ for (const node of nodes) {
27
+ if (!node.type)
28
+ continue;
29
+ count++;
30
+ // Always show progress at level 1 or higher (-v, -vv)
31
+ if (count % 10 === 0 || count === nodes.length) {
32
+ (0, logVerbose_1.logVerbose)(1, ` Progress: ${count}/${nodes.length} objects processed...`);
33
+ }
34
+ try {
17
35
  const entry = await (0, verifyObjectInSystem_1.verifyObjectInSystem)(client, {
18
36
  type: node.type,
19
37
  name: node.name,
20
38
  functionGroupName: node.functionGroupName,
21
- }, (0, getExpectedPackage_1.getExpectedPackage)(node.config), undefined, node.codeBase64, node.codeFormat);
39
+ }, (0, getExpectedPackage_1.getExpectedPackage)(node.config), node.source, node.codeBase64, node.codeFormat || (node.source ? 'source' : undefined), mode === 'post-restore' ? 'inactive' : 'active');
40
+ // Detailed object log ONLY for level 2 or higher (-vv)
41
+ const actionLabel = mode === 'pre-restore'
42
+ ? entry.status === 'missing'
43
+ ? 'CREATE'
44
+ : 'UPDATE'
45
+ : entry.status === 'ok'
46
+ ? 'OK '
47
+ : 'FAILED';
48
+ (0, logVerbose_1.logVerbose)(2, ` [${actionLabel}] ${node.type}:${node.name}`);
22
49
  entries.push(entry);
23
50
  }
24
- }
25
- else {
26
- const flat = backup;
27
- for (const obj of flat.objects) {
28
- const entry = await (0, verifyObjectInSystem_1.verifyObjectInSystem)(client, {
29
- type: obj.type,
30
- name: obj.name,
31
- functionGroupName: obj.functionGroupName,
32
- }, (0, getExpectedPackage_1.getExpectedPackage)(obj.config), obj.source, undefined, obj.source ? 'source' : undefined);
33
- entries.push(entry);
51
+ catch (error) {
52
+ (0, logVerbose_1.logVerbose)(1, ` [ERROR ] ${node.type}:${node.name} | ${error.message}`);
53
+ entries.push({
54
+ type: node.type,
55
+ name: node.name,
56
+ status: 'error',
57
+ message: error.message,
58
+ });
34
59
  }
35
60
  }
61
+ return entries;
62
+ }
63
+ function buildSummary(entries, options) {
36
64
  const strict = options?.strict ?? false;
37
- const conflictStatuses = strict
38
- ? ['type-mismatch', 'package-mismatch', 'error', 'source-mismatch']
39
- : ['type-mismatch', 'package-mismatch', 'error'];
40
- const summary = {
65
+ const mode = options?.mode ?? 'pre-restore';
66
+ const conflictStatuses = ['type-mismatch', 'package-mismatch', 'error'];
67
+ if (strict)
68
+ conflictStatuses.push('source-mismatch');
69
+ if (mode === 'post-restore')
70
+ conflictStatuses.push('missing');
71
+ const missingCount = entries.filter((e) => e.status === 'missing').length;
72
+ const okCount = entries.filter((e) => e.status === 'ok').length;
73
+ const pkgMismatchCount = entries.filter((e) => e.status === 'package-mismatch').length;
74
+ const sourceMismatchCount = entries.filter((e) => e.status === 'source-mismatch').length;
75
+ return {
41
76
  total: entries.length,
42
- ok: entries.filter((entry) => entry.status === 'ok').length,
43
- missing: entries.filter((entry) => entry.status === 'missing').length,
44
- typeMismatch: entries.filter((entry) => entry.status === 'type-mismatch')
45
- .length,
46
- packageMismatch: entries.filter((entry) => entry.status === 'package-mismatch').length,
47
- sourceMismatch: entries.filter((entry) => entry.status === 'source-mismatch').length,
48
- unsupported: entries.filter((entry) => entry.status === 'unsupported')
77
+ ok: mode === 'pre-restore' ? okCount + missingCount : okCount,
78
+ missing: missingCount,
79
+ create: missingCount,
80
+ update: okCount + pkgMismatchCount + sourceMismatchCount,
81
+ typeMismatch: entries.filter((e) => e.status === 'type-mismatch').length,
82
+ packageMismatch: pkgMismatchCount,
83
+ sourceMismatch: sourceMismatchCount,
84
+ unsupported: entries.filter((e) => e.status === 'unsupported').length,
85
+ error: entries.filter((e) => e.status === 'error').length,
86
+ conflicts: entries.filter((e) => conflictStatuses.includes(e.status))
49
87
  .length,
50
- error: entries.filter((entry) => entry.status === 'error').length,
51
- conflicts: entries.filter((entry) => conflictStatuses.includes(entry.status)).length,
52
88
  };
53
- return { entries, summary };
54
89
  }
@@ -1,5 +1,5 @@
1
1
  import type { AdtClient } from '@mcp-abap-adt/adt-clients';
2
2
  import type { ObjectSpec } from '../types';
3
3
  import type { VerifyEntry } from './types';
4
- export declare function verifyObjectInSystem(client: AdtClient, spec: ObjectSpec, expectedPackage?: string, expectedSource?: string, expectedSourceBase64?: string, expectedFormat?: 'source' | 'xml' | 'json'): Promise<VerifyEntry>;
4
+ export declare function verifyObjectInSystem(client: AdtClient, spec: ObjectSpec, expectedPackage?: string, expectedSource?: string, expectedSourceBase64?: string, expectedFormat?: 'source' | 'xml' | 'json', version?: 'active' | 'inactive'): Promise<VerifyEntry>;
5
5
  //# sourceMappingURL=verifyObjectInSystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verifyObjectInSystem.d.ts","sourceRoot":"","sources":["../../../src/lib/verify/verifyObjectInSystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAyB3C,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,EAChB,eAAe,CAAC,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM,EACvB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GACzC,OAAO,CAAC,WAAW,CAAC,CA+HtB"}
1
+ {"version":3,"file":"verifyObjectInSystem.d.ts","sourceRoot":"","sources":["../../../src/lib/verify/verifyObjectInSystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,EAChB,eAAe,CAAC,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM,EACvB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,EAC1C,OAAO,GAAE,QAAQ,GAAG,UAAqB,GACxC,OAAO,CAAC,WAAW,CAAC,CA+EtB"}
@@ -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
  }
@@ -8,6 +8,7 @@ export * from './getNodeAttribute';
8
8
  export * from './parseDataElementConfig';
9
9
  export * from './parseDomainConfig';
10
10
  export * from './parsePackageConfig';
11
+ export * from './parseServiceBindingConfig';
11
12
  export * from './toBoolean';
12
13
  export * from './toNumber';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/xml/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/xml/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -24,5 +24,6 @@ __exportStar(require("./getNodeAttribute"), exports);
24
24
  __exportStar(require("./parseDataElementConfig"), exports);
25
25
  __exportStar(require("./parseDomainConfig"), exports);
26
26
  __exportStar(require("./parsePackageConfig"), exports);
27
+ __exportStar(require("./parseServiceBindingConfig"), exports);
27
28
  __exportStar(require("./toBoolean"), exports);
28
29
  __exportStar(require("./toNumber"), exports);
@@ -0,0 +1,3 @@
1
+ import type { IServiceBindingConfig } from '@mcp-abap-adt/adt-clients';
2
+ export declare function parseServiceBindingConfig(xml: string): Partial<IServiceBindingConfig>;
3
+ //# sourceMappingURL=parseServiceBindingConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseServiceBindingConfig.d.ts","sourceRoot":"","sources":["../../../src/lib/xml/parseServiceBindingConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAOvE,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,qBAAqB,CAAC,CAsFhC"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseServiceBindingConfig = parseServiceBindingConfig;
4
+ const xmlParser_1 = require("../constants/xmlParser");
5
+ const findAttribute_1 = require("./findAttribute");
6
+ const findNode_1 = require("./findNode");
7
+ const getNodeAttribute_1 = require("./getNodeAttribute");
8
+ function parseServiceBindingConfig(xml) {
9
+ const parsed = xmlParser_1.xmlParser.parse(xml);
10
+ const root = (0, findNode_1.findNode)(parsed, ['srvb:serviceBinding', 'serviceBinding']) ?? parsed;
11
+ const bindingName = (0, getNodeAttribute_1.getNodeAttribute)(root, 'adtcore:name') ||
12
+ (0, findAttribute_1.findAttribute)(root, 'adtcore:name');
13
+ const description = (0, getNodeAttribute_1.getNodeAttribute)(root, 'adtcore:description') ||
14
+ (0, findAttribute_1.findAttribute)(root, 'adtcore:description');
15
+ const responsible = (0, getNodeAttribute_1.getNodeAttribute)(root, 'adtcore:responsible') ||
16
+ (0, findAttribute_1.findAttribute)(root, 'adtcore:responsible');
17
+ const masterSystem = (0, getNodeAttribute_1.getNodeAttribute)(root, 'adtcore:masterSystem') ||
18
+ (0, findAttribute_1.findAttribute)(root, 'adtcore:masterSystem');
19
+ const masterLanguage = (0, getNodeAttribute_1.getNodeAttribute)(root, 'adtcore:masterLanguage') ||
20
+ (0, findAttribute_1.findAttribute)(root, 'adtcore:masterLanguage') ||
21
+ (0, getNodeAttribute_1.getNodeAttribute)(root, 'adtcore:language') ||
22
+ (0, findAttribute_1.findAttribute)(root, 'adtcore:language');
23
+ const packageRef = (0, findNode_1.findNode)(root, ['adtcore:packageRef', 'packageRef']);
24
+ const packageName = (0, getNodeAttribute_1.getNodeAttribute)(packageRef, 'adtcore:name') ||
25
+ (0, findAttribute_1.findAttribute)(packageRef, 'adtcore:name');
26
+ const services = (0, findNode_1.findNode)(root, ['srvb:services', 'services']);
27
+ const serviceName = (0, getNodeAttribute_1.getNodeAttribute)(services, 'srvb:name') ||
28
+ (0, findAttribute_1.findAttribute)(services, 'srvb:name');
29
+ const content = (0, findNode_1.findNode)(services, ['srvb:content', 'content']);
30
+ const serviceVersion = (0, getNodeAttribute_1.getNodeAttribute)(content, 'srvb:version') ||
31
+ (0, findAttribute_1.findAttribute)(content, 'srvb:version');
32
+ const serviceDefinition = (0, findNode_1.findNode)(content, [
33
+ 'srvb:serviceDefinition',
34
+ 'serviceDefinition',
35
+ ]);
36
+ const serviceDefinitionName = (0, getNodeAttribute_1.getNodeAttribute)(serviceDefinition, 'adtcore:name') ||
37
+ (0, findAttribute_1.findAttribute)(serviceDefinition, 'adtcore:name');
38
+ const binding = (0, findNode_1.findNode)(root, ['srvb:binding', 'binding']);
39
+ const bindingType = (0, getNodeAttribute_1.getNodeAttribute)(binding, 'srvb:type') ||
40
+ (0, findAttribute_1.findAttribute)(binding, 'srvb:type');
41
+ const bindingVersion = (0, getNodeAttribute_1.getNodeAttribute)(binding, 'srvb:version') ||
42
+ (0, findAttribute_1.findAttribute)(binding, 'srvb:version');
43
+ const bindingCategory = (0, getNodeAttribute_1.getNodeAttribute)(binding, 'srvb:category') ||
44
+ (0, findAttribute_1.findAttribute)(binding, 'srvb:category');
45
+ // Keep publication state unchanged by default during restore updates.
46
+ const desiredPublicationState = 'unchanged';
47
+ const normalizedBindingType = bindingType?.toUpperCase();
48
+ const normalizedBindingVersion = bindingVersion?.toUpperCase();
49
+ const serviceType = normalizedBindingType === 'ODATA'
50
+ ? normalizedBindingVersion === 'V2'
51
+ ? 'odatav2'
52
+ : 'odatav4'
53
+ : undefined;
54
+ return {
55
+ bindingName,
56
+ packageName,
57
+ description,
58
+ serviceDefinitionName,
59
+ serviceName,
60
+ serviceVersion,
61
+ bindingType: normalizedBindingType,
62
+ bindingVersion,
63
+ bindingCategory,
64
+ masterLanguage,
65
+ masterSystem,
66
+ responsible,
67
+ desiredPublicationState,
68
+ serviceType,
69
+ };
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/adt-backup",
3
- "version": "0.1.1",
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": "0.3.14",
52
- "@mcp-abap-adt/auth-broker": "^0.2.17",
53
- "@mcp-abap-adt/auth-providers": "^0.2.10",
54
- "@mcp-abap-adt/auth-stores": "^0.2.10",
55
- "@mcp-abap-adt/connection": "^0.2.8",
56
- "fast-xml-parser": "^5.3.3",
57
- "yaml": "^2.3.4"
51
+ "@mcp-abap-adt/adt-clients": "^1.1.1",
52
+ "@mcp-abap-adt/auth-broker": "^1.0.5",
53
+ "@mcp-abap-adt/auth-providers": "^1.0.5",
54
+ "@mcp-abap-adt/auth-stores": "^1.0.2",
55
+ "@mcp-abap-adt/connection": "^1.1.0",
56
+ "fast-xml-parser": "^5.4.1",
57
+ "yaml": "^2.8.2"
58
58
  },
59
59
  "devDependencies": {
60
- "@biomejs/biome": "^2.3.10",
61
- "@types/node": "^24.2.1",
60
+ "@biomejs/biome": "^2.4.4",
61
+ "@types/node": "^25.3.1",
62
62
  "typescript": "^5.9.2"
63
63
  }
64
64
  }