@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
package/README.md
CHANGED
|
@@ -36,6 +36,9 @@ Use `--no-activate-on-create` or `--no-activate-on-update` to skip activation fo
|
|
|
36
36
|
# Extract / patch a single object payload
|
|
37
37
|
adt-backup extract --input backup.yaml --object class:ZCL_TEST --out ZCL_TEST.abap
|
|
38
38
|
adt-backup patch --input backup.yaml --object class:ZCL_TEST --file ZCL_TEST.abap
|
|
39
|
+
|
|
40
|
+
# Single object backup (Service Binding)
|
|
41
|
+
adt-backup backup --objects serviceBinding:Z_UI_SERVICE --output srvb_backup.yaml --destination TRIAL
|
|
39
42
|
```
|
|
40
43
|
|
|
41
44
|
## Help
|
|
@@ -59,6 +62,37 @@ Use `-v` for main stages, `-vv` for per-object details, and `-vvv` for ADT/conne
|
|
|
59
62
|
|
|
60
63
|
See `docs/roadmap.yaml` for per-object backup/restore status and the plan for remaining types.
|
|
61
64
|
|
|
65
|
+
## Supported Object Types
|
|
66
|
+
|
|
67
|
+
| Object Type | Backup | Restore | Payload |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| `package` | implemented | implemented | metadata-xml |
|
|
70
|
+
| `domain` | implemented | implemented | metadata-xml |
|
|
71
|
+
| `dataElement` | implemented | implemented | metadata-xml |
|
|
72
|
+
| `structure` | implemented | implemented | source |
|
|
73
|
+
| `table` | implemented | implemented | source |
|
|
74
|
+
| `tableType` | implemented | implemented | metadata-xml |
|
|
75
|
+
| `view` | implemented | implemented | source |
|
|
76
|
+
| `functionGroup` | implemented | implemented | metadata-xml |
|
|
77
|
+
| `functionModule` | implemented | implemented | source |
|
|
78
|
+
| `interface` | implemented | implemented | source |
|
|
79
|
+
| `class` | implemented | implemented | source |
|
|
80
|
+
| `program` | implemented | implemented | source |
|
|
81
|
+
| `serviceDefinition` | implemented | implemented | source |
|
|
82
|
+
| `serviceBinding` | implemented | implemented | metadata-xml |
|
|
83
|
+
| `metadataExtension` | implemented | implemented | source |
|
|
84
|
+
| `behaviorDefinition` | implemented | implemented | source |
|
|
85
|
+
| `behaviorImplementation` | implemented | implemented | source |
|
|
86
|
+
| `enhancement` | implemented | implemented | source |
|
|
87
|
+
| `unitTest` | implemented | implemented | as class |
|
|
88
|
+
| `cdsUnitTest` | implemented | implemented | as class |
|
|
89
|
+
|
|
90
|
+
> **Note**: Unit tests are stored as classes in backups. When restoring, they are created as test classes in the system.
|
|
91
|
+
|
|
92
|
+
## Smoke Checklist
|
|
93
|
+
|
|
94
|
+
When your landscape is ready, use `docs/SMOKE_CHECKLIST.md` for a focused backup/restore/verify checklist.
|
|
95
|
+
|
|
62
96
|
## Changelog
|
|
63
97
|
|
|
64
98
|
See [CHANGELOG.md](./CHANGELOG.md) for a history of changes.
|
package/dist/bin/adt-backup.js
CHANGED
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { IAuthorizationConfig, ITokenProvider } from '@mcp-abap-adt/interfaces';
|
|
2
2
|
import type { createLogger } from '../cli/createLogger';
|
|
3
|
-
export declare function createTokenProvider(authConfig?: IAuthorizationConfig | null, logger?: ReturnType<typeof createLogger>): ITokenProvider;
|
|
3
|
+
export declare function createTokenProvider(authConfig?: IAuthorizationConfig | null, browserAuthPort?: number, logger?: ReturnType<typeof createLogger>): ITokenProvider;
|
|
4
4
|
//# sourceMappingURL=createTokenProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createTokenProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/createTokenProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,wBAAgB,mBAAmB,CACjC,UAAU,CAAC,EAAE,oBAAoB,GAAG,IAAI,EACxC,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACvC,cAAc,
|
|
1
|
+
{"version":3,"file":"createTokenProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/createTokenProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,wBAAgB,mBAAmB,CACjC,UAAU,CAAC,EAAE,oBAAoB,GAAG,IAAI,EACxC,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACvC,cAAc,CAmBhB"}
|
|
@@ -4,7 +4,7 @@ exports.createTokenProvider = createTokenProvider;
|
|
|
4
4
|
const auth_providers_1 = require("@mcp-abap-adt/auth-providers");
|
|
5
5
|
const NoopTokenProvider_1 = require("../auth/NoopTokenProvider");
|
|
6
6
|
const shouldEnableProviderLogger_1 = require("../cli/shouldEnableProviderLogger");
|
|
7
|
-
function createTokenProvider(authConfig, logger) {
|
|
7
|
+
function createTokenProvider(authConfig, browserAuthPort, logger) {
|
|
8
8
|
if (!authConfig ||
|
|
9
9
|
!authConfig.uaaUrl ||
|
|
10
10
|
!authConfig.uaaClientId ||
|
|
@@ -17,6 +17,7 @@ function createTokenProvider(authConfig, logger) {
|
|
|
17
17
|
clientSecret: authConfig.uaaClientSecret,
|
|
18
18
|
refreshToken: authConfig.refreshToken,
|
|
19
19
|
browser: 'system',
|
|
20
|
+
redirectPort: browserAuthPort || 10001,
|
|
20
21
|
logger: (0, shouldEnableProviderLogger_1.shouldEnableProviderLogger)() ? logger : undefined,
|
|
21
22
|
});
|
|
22
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSapConfigFromBroker.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/getSapConfigFromBroker.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"getSapConfigFromBroker.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/getSapConfigFromBroker.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CACzC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CA0HnE"}
|
|
@@ -39,6 +39,7 @@ const os = __importStar(require("node:os"));
|
|
|
39
39
|
const path = __importStar(require("node:path"));
|
|
40
40
|
const auth_broker_1 = require("@mcp-abap-adt/auth-broker");
|
|
41
41
|
const auth_stores_1 = require("@mcp-abap-adt/auth-stores");
|
|
42
|
+
const logVerbose_1 = require("../cli/logVerbose");
|
|
42
43
|
const shouldEnableBrokerLogger_1 = require("../cli/shouldEnableBrokerLogger");
|
|
43
44
|
const shouldEnableStoreLogger_1 = require("../cli/shouldEnableStoreLogger");
|
|
44
45
|
const createTokenProvider_1 = require("./createTokenProvider");
|
|
@@ -46,28 +47,105 @@ async function getSapConfigFromBroker(options) {
|
|
|
46
47
|
const { logger } = options;
|
|
47
48
|
const brokerLogger = (0, shouldEnableBrokerLogger_1.shouldEnableBrokerLogger)() ? logger : undefined;
|
|
48
49
|
const storeLogger = (0, shouldEnableStoreLogger_1.shouldEnableStoreLogger)() ? logger : undefined;
|
|
49
|
-
|
|
50
|
-
if (options.envPath) {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
logger,
|
|
57
|
-
brokerLogger,
|
|
58
|
-
});
|
|
50
|
+
// 1. If --env-path is provided, we load it into process.env first
|
|
51
|
+
if (options.envPath && fs.existsSync(options.envPath)) {
|
|
52
|
+
const content = fs.readFileSync(options.envPath, 'utf8');
|
|
53
|
+
const envVars = parseEnvContent(content);
|
|
54
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
55
|
+
process.env[key] = value;
|
|
56
|
+
}
|
|
59
57
|
}
|
|
58
|
+
const destination = options.destination || 'env';
|
|
60
59
|
const roots = resolveAuthRoots(options.authRoot);
|
|
61
60
|
const { sessionDir, serviceKeyDir } = resolveStoreDirs(roots, destination);
|
|
62
|
-
|
|
61
|
+
// 2. Initialize stores
|
|
62
|
+
const sessionStore = options.envPath
|
|
63
|
+
? new auth_stores_1.EnvFileSessionStore(options.envPath, storeLogger)
|
|
64
|
+
: new auth_stores_1.AbapSessionStore(sessionDir, storeLogger);
|
|
63
65
|
const serviceKeyStore = new auth_stores_1.AbapServiceKeyStore(serviceKeyDir, storeLogger);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
// 3. Get authorization config from store
|
|
67
|
+
const sessionAuthConfig = (await sessionStore.getAuthorizationConfig(destination));
|
|
68
|
+
const serviceKeyAuthConfig = (await serviceKeyStore.getAuthorizationConfig(destination));
|
|
69
|
+
const authConfig = sessionAuthConfig || serviceKeyAuthConfig;
|
|
70
|
+
const broker = new auth_broker_1.AuthBroker({
|
|
66
71
|
sessionStore,
|
|
67
72
|
serviceKeyStore,
|
|
68
|
-
logger,
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
tokenProvider: (0, createTokenProvider_1.createTokenProvider)(authConfig, options.browserAuthPort, logger),
|
|
74
|
+
}, undefined, brokerLogger);
|
|
75
|
+
// 4. Try to get connection.
|
|
76
|
+
let connection = (await broker.getConnectionConfig(destination));
|
|
77
|
+
// Perform authentication if session is missing but auth config is available
|
|
78
|
+
if (!connection && authConfig && destination !== 'env') {
|
|
79
|
+
(0, logVerbose_1.logVerbose)(1, `Initiating authentication for ${destination}...`);
|
|
80
|
+
await broker.getToken(destination);
|
|
81
|
+
connection = (await broker.getConnectionConfig(destination));
|
|
82
|
+
}
|
|
83
|
+
// Fallback to process.env if not found in stores
|
|
84
|
+
if (!connection &&
|
|
85
|
+
(destination === 'env' || destination === 'SAP' || options.envPath)) {
|
|
86
|
+
const url = process.env.SAP_URL || process.env.SAP_SERVICEURL;
|
|
87
|
+
if (url) {
|
|
88
|
+
connection = {
|
|
89
|
+
serviceUrl: url,
|
|
90
|
+
authorizationToken: process.env.SAP_JWT_TOKEN || process.env.SAP_TOKEN,
|
|
91
|
+
username: process.env.SAP_USERNAME || process.env.SAP_USER,
|
|
92
|
+
password: process.env.SAP_PASSWORD || process.env.SAP_PASS,
|
|
93
|
+
authType: (process.env.SAP_AUTH_TYPE ||
|
|
94
|
+
(process.env.SAP_JWT_TOKEN ? 'jwt' : 'basic')),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!connection) {
|
|
99
|
+
throw new Error(`Missing connection config for destination ${destination}. If using service keys, ensure the JSON file exists in ${serviceKeyDir}`);
|
|
100
|
+
}
|
|
101
|
+
// If we have authConfig but no token in session, try to refresh/get it
|
|
102
|
+
if (!connection.authorizationToken &&
|
|
103
|
+
!connection.username &&
|
|
104
|
+
authConfig &&
|
|
105
|
+
destination !== 'env') {
|
|
106
|
+
await broker.getToken(destination);
|
|
107
|
+
connection = (await broker.getConnectionConfig(destination));
|
|
108
|
+
}
|
|
109
|
+
const authType = connection.authType ||
|
|
110
|
+
(connection.authorizationToken
|
|
111
|
+
? 'jwt'
|
|
112
|
+
: connection.username && connection.password
|
|
113
|
+
? 'basic'
|
|
114
|
+
: 'jwt');
|
|
115
|
+
const serviceUrl = connection.serviceUrl;
|
|
116
|
+
if (!serviceUrl) {
|
|
117
|
+
throw new Error(`Missing service URL for destination ${destination}`);
|
|
118
|
+
}
|
|
119
|
+
const config = {
|
|
120
|
+
url: serviceUrl,
|
|
121
|
+
authType: authType,
|
|
122
|
+
};
|
|
123
|
+
if (authType === 'jwt') {
|
|
124
|
+
config.jwtToken = connection.authorizationToken;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
config.username = connection.username;
|
|
128
|
+
config.password = connection.password;
|
|
129
|
+
}
|
|
130
|
+
const tokenRefresher = authType === 'jwt' ? broker.createTokenRefresher(destination) : undefined;
|
|
131
|
+
return { config, tokenRefresher };
|
|
132
|
+
}
|
|
133
|
+
function parseEnvContent(content) {
|
|
134
|
+
const envVars = {};
|
|
135
|
+
for (const line of content.split(/\r?\n/)) {
|
|
136
|
+
const trimmed = line.trim();
|
|
137
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
138
|
+
continue;
|
|
139
|
+
const eqIndex = trimmed.indexOf('=');
|
|
140
|
+
if (eqIndex === -1)
|
|
141
|
+
continue;
|
|
142
|
+
const key = trimmed.substring(0, eqIndex).trim();
|
|
143
|
+
let value = trimmed.substring(eqIndex + 1).trim();
|
|
144
|
+
value = value.replace(/^["']+|["']+$/g, '').trim();
|
|
145
|
+
if (key)
|
|
146
|
+
envVars[key] = value;
|
|
147
|
+
}
|
|
148
|
+
return envVars;
|
|
71
149
|
}
|
|
72
150
|
function resolveAuthRoots(authRoot) {
|
|
73
151
|
if (authRoot) {
|
|
@@ -89,18 +167,6 @@ function resolveAuthRoots(authRoot) {
|
|
|
89
167
|
function resolveStoreDirs(roots, destination) {
|
|
90
168
|
const candidates = roots.map((root) => {
|
|
91
169
|
const normalized = path.resolve(root);
|
|
92
|
-
if (normalized.endsWith(`${path.sep}sessions`)) {
|
|
93
|
-
return {
|
|
94
|
-
sessionDir: normalized,
|
|
95
|
-
serviceKeyDir: path.join(path.dirname(normalized), 'service-keys'),
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
if (normalized.endsWith(`${path.sep}service-keys`)) {
|
|
99
|
-
return {
|
|
100
|
-
sessionDir: path.join(path.dirname(normalized), 'sessions'),
|
|
101
|
-
serviceKeyDir: normalized,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
170
|
return {
|
|
105
171
|
sessionDir: path.join(normalized, 'sessions'),
|
|
106
172
|
serviceKeyDir: path.join(normalized, 'service-keys'),
|
|
@@ -115,70 +181,3 @@ function resolveStoreDirs(roots, destination) {
|
|
|
115
181
|
}
|
|
116
182
|
return candidates[0];
|
|
117
183
|
}
|
|
118
|
-
async function getConfigWithStores(options) {
|
|
119
|
-
const { destination, sessionStore, serviceKeyStore, logger, brokerLogger } = options;
|
|
120
|
-
const sessionAuthConfig = destination === 'env'
|
|
121
|
-
? null
|
|
122
|
-
: await sessionStore.getAuthorizationConfig(destination);
|
|
123
|
-
const serviceKeyAuthConfig = destination === 'env' || !serviceKeyStore?.getAuthorizationConfig
|
|
124
|
-
? null
|
|
125
|
-
: await serviceKeyStore.getAuthorizationConfig(destination);
|
|
126
|
-
const authConfig = sessionAuthConfig || serviceKeyAuthConfig;
|
|
127
|
-
const broker = new auth_broker_1.AuthBroker({
|
|
128
|
-
sessionStore,
|
|
129
|
-
serviceKeyStore,
|
|
130
|
-
tokenProvider: (0, createTokenProvider_1.createTokenProvider)(authConfig, logger),
|
|
131
|
-
}, undefined, brokerLogger);
|
|
132
|
-
const session = await sessionStore.loadSession(destination);
|
|
133
|
-
let connection = await broker.getConnectionConfig(destination);
|
|
134
|
-
if (!connection && authConfig && destination !== 'env') {
|
|
135
|
-
await broker.getToken(destination);
|
|
136
|
-
connection = await broker.getConnectionConfig(destination);
|
|
137
|
-
}
|
|
138
|
-
if (!connection) {
|
|
139
|
-
throw new Error(`Missing connection config for destination ${destination}`);
|
|
140
|
-
}
|
|
141
|
-
if (!connection.authorizationToken &&
|
|
142
|
-
!connection.username &&
|
|
143
|
-
!connection.password &&
|
|
144
|
-
authConfig &&
|
|
145
|
-
destination !== 'env') {
|
|
146
|
-
await broker.getToken(destination);
|
|
147
|
-
connection = await broker.getConnectionConfig(destination);
|
|
148
|
-
if (!connection) {
|
|
149
|
-
throw new Error(`Missing connection config for destination ${destination}`);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
const resolvedAuthType = connection.authorizationToken
|
|
153
|
-
? 'jwt'
|
|
154
|
-
: connection.username && connection.password
|
|
155
|
-
? 'basic'
|
|
156
|
-
: authConfig && destination !== 'env'
|
|
157
|
-
? 'jwt'
|
|
158
|
-
: connection.authType || 'basic';
|
|
159
|
-
const serviceUrl = connection.serviceUrl || session?.serviceUrl;
|
|
160
|
-
if (!serviceUrl) {
|
|
161
|
-
throw new Error(`Missing service URL for destination ${destination}`);
|
|
162
|
-
}
|
|
163
|
-
const config = {
|
|
164
|
-
url: serviceUrl,
|
|
165
|
-
authType: resolvedAuthType,
|
|
166
|
-
};
|
|
167
|
-
if (resolvedAuthType === 'jwt') {
|
|
168
|
-
if (!connection.authorizationToken) {
|
|
169
|
-
throw new Error(`Missing JWT token for destination ${destination}`);
|
|
170
|
-
}
|
|
171
|
-
config.jwtToken = connection.authorizationToken;
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
if (!connection.username || !connection.password) {
|
|
175
|
-
throw new Error(`Missing username/password for destination ${destination}`);
|
|
176
|
-
}
|
|
177
|
-
config.username = connection.username;
|
|
178
|
-
config.password = connection.password;
|
|
179
|
-
}
|
|
180
|
-
const tokenRefresher = resolvedAuthType === 'jwt'
|
|
181
|
-
? broker.createTokenRefresher(destination)
|
|
182
|
-
: undefined;
|
|
183
|
-
return { config, tokenRefresher };
|
|
184
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backupObject.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/backupObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAGV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAgB,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"backupObject.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/backupObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAGV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAgB,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAcvE,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CA6OvB"}
|
|
@@ -9,6 +9,7 @@ const extractMetadata_1 = require("../xml/extractMetadata");
|
|
|
9
9
|
const parseDataElementConfig_1 = require("../xml/parseDataElementConfig");
|
|
10
10
|
const parseDomainConfig_1 = require("../xml/parseDomainConfig");
|
|
11
11
|
const parsePackageConfig_1 = require("../xml/parsePackageConfig");
|
|
12
|
+
const parseServiceBindingConfig_1 = require("../xml/parseServiceBindingConfig");
|
|
12
13
|
const readBasicMetadata_1 = require("./readBasicMetadata");
|
|
13
14
|
const readMetadataXmlForType_1 = require("./readMetadataXmlForType");
|
|
14
15
|
const readSourceText_1 = require("./readSourceText");
|
|
@@ -89,7 +90,20 @@ async function backupObject(client, spec) {
|
|
|
89
90
|
type: spec.type,
|
|
90
91
|
name: spec.name,
|
|
91
92
|
config: (0, applyConfigName_1.applyConfigName)(spec.type, spec.name, undefined, (0, toBackupConfig_1.toBackupConfig)(config)),
|
|
92
|
-
source,
|
|
93
|
+
source: source ?? undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
case 'serviceBinding': {
|
|
97
|
+
const metadataXml = await (0, readMetadataXmlForType_1.readMetadataXmlForType)(client, spec.type, spec.name);
|
|
98
|
+
if (!metadataXml) {
|
|
99
|
+
throw new Error(`Service binding not found: ${spec.name}`);
|
|
100
|
+
}
|
|
101
|
+
const config = (0, parseServiceBindingConfig_1.parseServiceBindingConfig)(metadataXml);
|
|
102
|
+
return {
|
|
103
|
+
id,
|
|
104
|
+
type: spec.type,
|
|
105
|
+
name: spec.name,
|
|
106
|
+
config: (0, applyConfigName_1.applyConfigName)(spec.type, spec.name, undefined, (0, toBackupConfig_1.toBackupConfig)(config)),
|
|
93
107
|
};
|
|
94
108
|
}
|
|
95
109
|
case 'metadataExtension':
|
|
@@ -106,7 +120,7 @@ async function backupObject(client, spec) {
|
|
|
106
120
|
type: spec.type,
|
|
107
121
|
name: spec.name,
|
|
108
122
|
config,
|
|
109
|
-
source,
|
|
123
|
+
source: source ?? undefined,
|
|
110
124
|
};
|
|
111
125
|
}
|
|
112
126
|
case 'behaviorImplementation':
|
|
@@ -126,7 +140,7 @@ async function backupObject(client, spec) {
|
|
|
126
140
|
type: spec.type,
|
|
127
141
|
name: spec.name,
|
|
128
142
|
config,
|
|
129
|
-
source,
|
|
143
|
+
source: source ?? undefined,
|
|
130
144
|
};
|
|
131
145
|
}
|
|
132
146
|
case 'functionModule': {
|
|
@@ -144,7 +158,7 @@ async function backupObject(client, spec) {
|
|
|
144
158
|
name: spec.name,
|
|
145
159
|
functionGroupName: spec.functionGroupName,
|
|
146
160
|
config,
|
|
147
|
-
source,
|
|
161
|
+
source: source ?? undefined,
|
|
148
162
|
};
|
|
149
163
|
}
|
|
150
164
|
default: {
|
|
@@ -159,7 +173,7 @@ async function backupObject(client, spec) {
|
|
|
159
173
|
type: spec.type,
|
|
160
174
|
name: spec.name,
|
|
161
175
|
config,
|
|
162
|
-
source,
|
|
176
|
+
source: source ?? undefined,
|
|
163
177
|
};
|
|
164
178
|
}
|
|
165
179
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { AdtClient } from '@mcp-abap-adt/adt-clients';
|
|
2
2
|
import type { SupportedType } from '../types';
|
|
3
|
-
export declare function readMetadataXmlForType(client: AdtClient, type: SupportedType, name: string,
|
|
3
|
+
export declare function readMetadataXmlForType(client: AdtClient, type: SupportedType, name: string, _functionGroupName?: string): Promise<string | null | undefined>;
|
|
4
4
|
//# sourceMappingURL=readMetadataXmlForType.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readMetadataXmlForType.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readMetadataXmlForType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,
|
|
1
|
+
{"version":3,"file":"readMetadataXmlForType.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readMetadataXmlForType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAsHpC"}
|
|
@@ -2,99 +2,120 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.readMetadataXmlForType = readMetadataXmlForType;
|
|
4
4
|
const responseToText_1 = require("../utils/responseToText");
|
|
5
|
-
async function readMetadataXmlForType(client, type, name,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.getInterface()
|
|
14
|
-
.readMetadata({ interfaceName: name });
|
|
15
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
16
|
-
}
|
|
17
|
-
case 'program': {
|
|
18
|
-
const state = await client
|
|
19
|
-
.getProgram()
|
|
20
|
-
.readMetadata({ programName: name });
|
|
21
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
22
|
-
}
|
|
23
|
-
case 'structure': {
|
|
24
|
-
const state = await client
|
|
25
|
-
.getStructure()
|
|
26
|
-
.readMetadata({ structureName: name });
|
|
27
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
28
|
-
}
|
|
29
|
-
case 'table': {
|
|
30
|
-
const state = await client.getTable().readMetadata({ tableName: name });
|
|
31
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
32
|
-
}
|
|
33
|
-
case 'tableType': {
|
|
34
|
-
const state = await client
|
|
35
|
-
.getTableType()
|
|
36
|
-
.readMetadata({ tableTypeName: name });
|
|
37
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
38
|
-
}
|
|
39
|
-
case 'view': {
|
|
40
|
-
const state = await client.getView().readMetadata({ viewName: name });
|
|
41
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
42
|
-
}
|
|
43
|
-
case 'domain': {
|
|
44
|
-
const state = await client.getDomain().readMetadata({ domainName: name });
|
|
45
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
46
|
-
}
|
|
47
|
-
case 'dataElement': {
|
|
48
|
-
const state = await client
|
|
49
|
-
.getDataElement()
|
|
50
|
-
.readMetadata({ dataElementName: name });
|
|
51
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
52
|
-
}
|
|
53
|
-
case 'functionGroup': {
|
|
54
|
-
const state = await client
|
|
55
|
-
.getFunctionGroup()
|
|
56
|
-
.readMetadata({ functionGroupName: name });
|
|
57
|
-
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
58
|
-
}
|
|
59
|
-
case 'functionModule': {
|
|
60
|
-
if (!functionGroupName) {
|
|
61
|
-
return undefined;
|
|
5
|
+
async function readMetadataXmlForType(client, type, name, _functionGroupName) {
|
|
6
|
+
try {
|
|
7
|
+
switch (type) {
|
|
8
|
+
case 'package': {
|
|
9
|
+
const state = await client
|
|
10
|
+
.getPackage()
|
|
11
|
+
.readMetadata({ packageName: name });
|
|
12
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
62
13
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
.
|
|
94
|
-
|
|
95
|
-
|
|
14
|
+
case 'class': {
|
|
15
|
+
const state = await client.getClass().readMetadata({ className: name });
|
|
16
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
17
|
+
}
|
|
18
|
+
case 'interface': {
|
|
19
|
+
const state = await client
|
|
20
|
+
.getInterface()
|
|
21
|
+
.readMetadata({ interfaceName: name });
|
|
22
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
23
|
+
}
|
|
24
|
+
case 'domain': {
|
|
25
|
+
const state = await client
|
|
26
|
+
.getDomain()
|
|
27
|
+
.readMetadata({ domainName: name });
|
|
28
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
29
|
+
}
|
|
30
|
+
case 'dataElement': {
|
|
31
|
+
const state = await client
|
|
32
|
+
.getDataElement()
|
|
33
|
+
.readMetadata({ dataElementName: name });
|
|
34
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
35
|
+
}
|
|
36
|
+
case 'table': {
|
|
37
|
+
const state = await client.getTable().readMetadata({ tableName: name });
|
|
38
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
39
|
+
}
|
|
40
|
+
case 'tableType': {
|
|
41
|
+
const state = await client
|
|
42
|
+
.getTableType()
|
|
43
|
+
.readMetadata({ tableTypeName: name });
|
|
44
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
45
|
+
}
|
|
46
|
+
case 'structure': {
|
|
47
|
+
const state = await client
|
|
48
|
+
.getStructure()
|
|
49
|
+
.readMetadata({ structureName: name });
|
|
50
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
51
|
+
}
|
|
52
|
+
case 'view': {
|
|
53
|
+
const state = await client.getView().readMetadata({ viewName: name });
|
|
54
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
55
|
+
}
|
|
56
|
+
case 'behaviorDefinition': {
|
|
57
|
+
const state = await client
|
|
58
|
+
.getBehaviorDefinition()
|
|
59
|
+
.readMetadata({ name });
|
|
60
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
61
|
+
}
|
|
62
|
+
case 'behaviorImplementation': {
|
|
63
|
+
const state = await client
|
|
64
|
+
.getBehaviorImplementation()
|
|
65
|
+
.readMetadata({ className: name });
|
|
66
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
67
|
+
}
|
|
68
|
+
case 'serviceDefinition': {
|
|
69
|
+
const state = await client
|
|
70
|
+
.getServiceDefinition()
|
|
71
|
+
.readMetadata({ serviceDefinitionName: name });
|
|
72
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
73
|
+
}
|
|
74
|
+
case 'serviceBinding': {
|
|
75
|
+
const state = await client
|
|
76
|
+
.getServiceBinding()
|
|
77
|
+
.readMetadata({ bindingName: name });
|
|
78
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
79
|
+
}
|
|
80
|
+
case 'metadataExtension': {
|
|
81
|
+
const state = await client
|
|
82
|
+
.getMetadataExtension()
|
|
83
|
+
.readMetadata({ name });
|
|
84
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
85
|
+
}
|
|
86
|
+
case 'functionGroup': {
|
|
87
|
+
const state = await client
|
|
88
|
+
.getFunctionGroup()
|
|
89
|
+
.readMetadata({ functionGroupName: name });
|
|
90
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
91
|
+
}
|
|
92
|
+
case 'enhancement': {
|
|
93
|
+
const state = await client
|
|
94
|
+
.getEnhancement()
|
|
95
|
+
.readMetadata({ enhancementName: name, enhancementType: 'enhoxh' });
|
|
96
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
97
|
+
}
|
|
98
|
+
case 'accessControl': {
|
|
99
|
+
const state = await client
|
|
100
|
+
.getAccessControl()
|
|
101
|
+
.readMetadata({ accessControlName: name });
|
|
102
|
+
return (0, responseToText_1.responseToText)(state.metadataResult);
|
|
103
|
+
}
|
|
104
|
+
default:
|
|
105
|
+
return undefined;
|
|
96
106
|
}
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const status = error.status || error.response?.status;
|
|
110
|
+
const message = error.message || String(error);
|
|
111
|
+
const isNotFound = status === 404 ||
|
|
112
|
+
status === 410 ||
|
|
113
|
+
/not found/i.test(message) ||
|
|
114
|
+
/does not exist/i.test(message) ||
|
|
115
|
+
/ExceptionResourceNotFound/i.test(message);
|
|
116
|
+
if (isNotFound) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
throw error;
|
|
99
120
|
}
|
|
100
121
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { AdtClient } from '@mcp-abap-adt/adt-clients';
|
|
2
2
|
import type { ObjectSpec } from '../types';
|
|
3
|
-
export declare function readSourceText(client: AdtClient, spec: ObjectSpec): Promise<string | undefined>;
|
|
3
|
+
export declare function readSourceText(client: AdtClient, spec: ObjectSpec, version?: 'active' | 'inactive'): Promise<string | null | undefined>;
|
|
4
4
|
//# sourceMappingURL=readSourceText.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readSourceText.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readSourceText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"readSourceText.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readSourceText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,QAAQ,GAAG,UAAqB,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAwGpC"}
|