@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.
- 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 +402 -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
|
@@ -5,13 +5,34 @@ const logVerbose_1 = require("../cli/logVerbose");
|
|
|
5
5
|
const decodeBase64_1 = require("../crypto/decodeBase64");
|
|
6
6
|
const asConfig_1 = require("../utils/asConfig");
|
|
7
7
|
const ensureDescription_1 = require("../utils/ensureDescription");
|
|
8
|
+
const parseBdefSource_1 = require("../utils/parseBdefSource");
|
|
9
|
+
const parsePackageConfig_1 = require("../xml/parsePackageConfig");
|
|
8
10
|
const applyTransportRequest_1 = require("./applyTransportRequest");
|
|
9
|
-
async function restoreTreeNode(client, node, mode, activate, transportRequest, softwareComponentOverride, backupPackageNames) {
|
|
11
|
+
async function restoreTreeNode(client, node, mode, activate, transportRequest, softwareComponentOverride, backupPackageNames, superPackageOverride, transportLayerOverride) {
|
|
12
|
+
if (mode === 'skip') {
|
|
13
|
+
(0, logVerbose_1.logVerbose)(2, ` [SKIP] ${node.type}:${node.name}`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
10
16
|
if (!node.type || node.restoreStatus !== 'ok') {
|
|
11
17
|
return;
|
|
12
18
|
}
|
|
13
|
-
|
|
19
|
+
// Use existing config or try to extract from XML if missing
|
|
20
|
+
let nodeConfig = node.config;
|
|
21
|
+
if (!nodeConfig &&
|
|
22
|
+
node.codeBase64 &&
|
|
23
|
+
node.codeFormat === 'xml' &&
|
|
24
|
+
node.type === 'package') {
|
|
25
|
+
try {
|
|
26
|
+
const xml = (0, decodeBase64_1.decodeBase64)(node.codeBase64);
|
|
27
|
+
nodeConfig = (0, parsePackageConfig_1.parsePackageConfig)(xml);
|
|
28
|
+
}
|
|
29
|
+
catch (_e) {
|
|
30
|
+
(0, logVerbose_1.logVerbose)(2, ` Could not parse XML config for package ${node.name}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const config = (0, applyTransportRequest_1.applyTransportRequest)((0, ensureDescription_1.ensureDescription)(nodeConfig || {}, node.name), transportRequest);
|
|
14
34
|
const payload = node.codeBase64 ? (0, decodeBase64_1.decodeBase64)(node.codeBase64) : undefined;
|
|
35
|
+
// Standard options for most objects
|
|
15
36
|
const options = {
|
|
16
37
|
activateOnCreate: activate,
|
|
17
38
|
activateOnUpdate: activate,
|
|
@@ -20,30 +41,48 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
20
41
|
switch (node.type) {
|
|
21
42
|
case 'package': {
|
|
22
43
|
const pkgConfig = (0, asConfig_1.asConfig)(config);
|
|
23
|
-
|
|
24
|
-
|
|
44
|
+
if (!pkgConfig.packageName) {
|
|
45
|
+
pkgConfig.packageName = node.name;
|
|
46
|
+
}
|
|
25
47
|
if (pkgConfig.responsible) {
|
|
26
48
|
delete pkgConfig.responsible;
|
|
27
49
|
}
|
|
28
|
-
// Check if this package's superPackage is within our backup tree
|
|
29
50
|
const superPackageInBackup = pkgConfig.superPackage &&
|
|
30
51
|
backupPackageNames?.has(pkgConfig.superPackage);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// For sub-packages, use CLI override to ensure consistency with parent
|
|
52
|
+
if (!superPackageInBackup && superPackageOverride) {
|
|
53
|
+
pkgConfig.superPackage = superPackageOverride;
|
|
54
|
+
}
|
|
35
55
|
if (softwareComponentOverride) {
|
|
36
56
|
pkgConfig.softwareComponent = softwareComponentOverride;
|
|
37
57
|
}
|
|
38
58
|
else if (!pkgConfig.softwareComponent) {
|
|
39
59
|
pkgConfig.softwareComponent = 'ZLOCAL';
|
|
40
60
|
}
|
|
41
|
-
|
|
61
|
+
// Fix for the transport layer mapping issue in adt-clients
|
|
62
|
+
if (transportLayerOverride) {
|
|
63
|
+
pkgConfig.transportLayer = transportLayerOverride;
|
|
64
|
+
pkgConfig.transport_layer = transportLayerOverride;
|
|
65
|
+
}
|
|
66
|
+
pkgConfig.recordChanges = true;
|
|
42
67
|
if (mode !== 'update') {
|
|
68
|
+
if (!pkgConfig.superPackage && node.type === 'package') {
|
|
69
|
+
throw new Error(`Package ${node.name} cannot be created: superPackage is missing.`);
|
|
70
|
+
}
|
|
71
|
+
(0, logVerbose_1.logVerbose)(3, ` Creating package ${node.name} (Layer: ${pkgConfig.transportLayer}, SoftwareComp: ${pkgConfig.softwareComponent})`);
|
|
43
72
|
await client.getPackage().create(pkgConfig, options);
|
|
73
|
+
// Wait for SAP to commit the package to the database
|
|
74
|
+
// ADT has no event subscription for creation completion
|
|
75
|
+
await delay(2000);
|
|
44
76
|
}
|
|
45
77
|
if (mode !== 'create') {
|
|
46
|
-
|
|
78
|
+
try {
|
|
79
|
+
await client.getPackage().update(pkgConfig, options);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
83
|
+
(0, logVerbose_1.logVerbose)(1, ` [SKIP] Package ${node.name} update skipped`);
|
|
84
|
+
(0, logVerbose_1.logVerbose)(3, ` Reason: ${msg.slice(0, 200)}`);
|
|
85
|
+
}
|
|
47
86
|
}
|
|
48
87
|
return;
|
|
49
88
|
}
|
|
@@ -53,11 +92,10 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
53
92
|
.getDomain()
|
|
54
93
|
.create((0, asConfig_1.asConfig)(config), options);
|
|
55
94
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
95
|
+
// Always update to set datatype/length/decimals (create only registers the name)
|
|
96
|
+
await client
|
|
97
|
+
.getDomain()
|
|
98
|
+
.update((0, asConfig_1.asConfig)(config), options);
|
|
61
99
|
return;
|
|
62
100
|
}
|
|
63
101
|
case 'dataElement': {
|
|
@@ -66,11 +104,10 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
66
104
|
.getDataElement()
|
|
67
105
|
.create((0, asConfig_1.asConfig)(config), options);
|
|
68
106
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
107
|
+
// Always update to set typeKind/typeName/dataType (create only registers the name)
|
|
108
|
+
await client
|
|
109
|
+
.getDataElement()
|
|
110
|
+
.update((0, asConfig_1.asConfig)(config), options);
|
|
74
111
|
return;
|
|
75
112
|
}
|
|
76
113
|
case 'structure': {
|
|
@@ -159,11 +196,10 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
159
196
|
.getFunctionGroup()
|
|
160
197
|
.create((0, asConfig_1.asConfig)(config), options);
|
|
161
198
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
199
|
+
// Always update to set properties (create only registers the name)
|
|
200
|
+
await client
|
|
201
|
+
.getFunctionGroup()
|
|
202
|
+
.update((0, asConfig_1.asConfig)(config), options);
|
|
167
203
|
return;
|
|
168
204
|
}
|
|
169
205
|
case 'functionModule': {
|
|
@@ -200,11 +236,29 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
200
236
|
.getServiceBinding()
|
|
201
237
|
.create((0, asConfig_1.asConfig)(config), options);
|
|
202
238
|
}
|
|
203
|
-
|
|
239
|
+
// Always update to set properties (create only registers the name)
|
|
240
|
+
try {
|
|
204
241
|
await client
|
|
205
242
|
.getServiceBinding()
|
|
206
243
|
.update((0, asConfig_1.asConfig)(config));
|
|
207
244
|
}
|
|
245
|
+
catch (updateError) {
|
|
246
|
+
const msg = updateError instanceof Error
|
|
247
|
+
? updateError.message
|
|
248
|
+
: String(updateError);
|
|
249
|
+
if (mode === 'update' && msg.includes('404')) {
|
|
250
|
+
// Object missing despite verify — fallback to create + update
|
|
251
|
+
await client
|
|
252
|
+
.getServiceBinding()
|
|
253
|
+
.create((0, asConfig_1.asConfig)(config), options);
|
|
254
|
+
await client
|
|
255
|
+
.getServiceBinding()
|
|
256
|
+
.update((0, asConfig_1.asConfig)(config));
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
throw updateError;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
208
262
|
return;
|
|
209
263
|
}
|
|
210
264
|
case 'metadataExtension': {
|
|
@@ -223,9 +277,19 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
223
277
|
}
|
|
224
278
|
case 'behaviorDefinition': {
|
|
225
279
|
if (mode !== 'update') {
|
|
280
|
+
// Fill rootEntity/implementationType from source if missing in config
|
|
281
|
+
let bdefConfig = config;
|
|
282
|
+
if (payload && (!config.rootEntity || !config.implementationType)) {
|
|
283
|
+
const parsed = (0, parseBdefSource_1.parseBdefSource)(payload);
|
|
284
|
+
bdefConfig = {
|
|
285
|
+
...config,
|
|
286
|
+
rootEntity: config.rootEntity || parsed.rootEntity,
|
|
287
|
+
implementationType: config.implementationType || parsed.implementationType,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
226
290
|
await client
|
|
227
291
|
.getBehaviorDefinition()
|
|
228
|
-
.create((0, asConfig_1.asConfig)(
|
|
292
|
+
.create((0, asConfig_1.asConfig)(bdefConfig), options);
|
|
229
293
|
}
|
|
230
294
|
if (payload) {
|
|
231
295
|
await client.getBehaviorDefinition().update((0, asConfig_1.asConfig)({
|
|
@@ -263,28 +327,43 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
|
|
|
263
327
|
}
|
|
264
328
|
return;
|
|
265
329
|
}
|
|
266
|
-
case '
|
|
330
|
+
case 'accessControl': {
|
|
267
331
|
if (mode !== 'update') {
|
|
268
332
|
await client
|
|
269
|
-
.
|
|
333
|
+
.getAccessControl()
|
|
270
334
|
.create((0, asConfig_1.asConfig)(config), options);
|
|
271
335
|
}
|
|
272
|
-
if (
|
|
336
|
+
if (payload) {
|
|
337
|
+
await client.getAccessControl().update((0, asConfig_1.asConfig)({
|
|
338
|
+
...config,
|
|
339
|
+
sourceCode: payload,
|
|
340
|
+
}), options);
|
|
341
|
+
}
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
case 'tableType': {
|
|
345
|
+
if (mode !== 'update') {
|
|
273
346
|
await client
|
|
274
347
|
.getTableType()
|
|
275
|
-
.
|
|
348
|
+
.create((0, asConfig_1.asConfig)(config), options);
|
|
276
349
|
}
|
|
350
|
+
// Always update to set properties (create only registers the name)
|
|
351
|
+
await client
|
|
352
|
+
.getTableType()
|
|
353
|
+
.update((0, asConfig_1.asConfig)(config), options);
|
|
277
354
|
return;
|
|
278
355
|
}
|
|
279
356
|
}
|
|
280
357
|
}
|
|
281
358
|
catch (error) {
|
|
282
|
-
const
|
|
283
|
-
if (
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
: JSON.stringify(err.response.data, null, 2));
|
|
359
|
+
const data = error.response?.data;
|
|
360
|
+
if (data) {
|
|
361
|
+
const errorMsg = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
|
|
362
|
+
console.error(`Error restoring ${node.type}:${node.name}:\n${errorMsg}`);
|
|
287
363
|
}
|
|
288
364
|
throw error;
|
|
289
365
|
}
|
|
290
366
|
}
|
|
367
|
+
function delay(ms) {
|
|
368
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
369
|
+
}
|
package/dist/lib/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/lib/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/lib/run.ts"],"names":[],"mappings":"AAiDA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAgpBzC"}
|