@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.
- package/README.md +34 -0
- 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.d.ts.map +1 -1
- package/dist/lib/backup/backupObject.js +19 -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 -92
- 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 -87
- 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 -87
- package/dist/lib/constants/typeOrder.d.ts.map +1 -1
- package/dist/lib/constants/typeOrder.js +1 -0
- package/dist/lib/dependencies/collectTreeDependencies.d.ts.map +1 -1
- package/dist/lib/dependencies/collectTreeDependencies.js +1 -0
- 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/restoreObject.d.ts.map +1 -1
- package/dist/lib/restore/restoreObject.js +13 -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 +128 -36
- 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 +19 -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 +2 -0
- package/dist/lib/tree/mapAdtTypeToSupported.d.ts.map +1 -1
- package/dist/lib/tree/mapAdtTypeToSupported.js +6 -0
- package/dist/lib/tree/readPayloadForType.d.ts.map +1 -1
- package/dist/lib/tree/readPayloadForType.js +5 -3
- 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 +6 -0
- package/dist/lib/utils/normalizeType.d.ts.map +1 -1
- package/dist/lib/utils/normalizeType.js +2 -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/findOtherType.d.ts.map +1 -1
- package/dist/lib/verify/findOtherType.js +1 -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/dist/lib/xml/index.d.ts +1 -0
- package/dist/lib/xml/index.d.ts.map +1 -1
- package/dist/lib/xml/index.js +1 -0
- package/dist/lib/xml/parseServiceBindingConfig.d.ts +3 -0
- package/dist/lib/xml/parseServiceBindingConfig.d.ts.map +1 -0
- package/dist/lib/xml/parseServiceBindingConfig.js +70 -0
- 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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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),
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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:
|
|
43
|
-
missing:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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;
|
|
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
|
-
|
|
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/dist/lib/xml/index.d.ts
CHANGED
|
@@ -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"}
|
package/dist/lib/xml/index.js
CHANGED
|
@@ -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 @@
|
|
|
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.
|
|
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": "
|
|
52
|
-
"@mcp-abap-adt/auth-broker": "^0.
|
|
53
|
-
"@mcp-abap-adt/auth-providers": "^0.
|
|
54
|
-
"@mcp-abap-adt/auth-stores": "^0.2
|
|
55
|
-
"@mcp-abap-adt/connection": "^
|
|
56
|
-
"fast-xml-parser": "^5.
|
|
57
|
-
"yaml": "^2.
|
|
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.
|
|
61
|
-
"@types/node": "^
|
|
60
|
+
"@biomejs/biome": "^2.4.4",
|
|
61
|
+
"@types/node": "^25.3.1",
|
|
62
62
|
"typescript": "^5.9.2"
|
|
63
63
|
}
|
|
64
64
|
}
|