simplemdg-dev-cli 1.5.1 → 2.4.4
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 +65 -243
- package/USER_GUIDE.md +55 -249
- package/dist/commands/cds.command.js +69 -60
- package/dist/commands/cds.command.js.map +1 -1
- package/dist/commands/cf-db.command.d.ts +2 -0
- package/dist/commands/cf-db.command.js +606 -0
- package/dist/commands/cf-db.command.js.map +1 -0
- package/dist/commands/cf.command.js +1625 -198
- package/dist/commands/cf.command.js.map +1 -1
- package/dist/commands/gitlab.command.d.ts +2 -0
- package/dist/commands/gitlab.command.js +351 -0
- package/dist/commands/gitlab.command.js.map +1 -0
- package/dist/commands/npmrc.command.js +50 -44
- package/dist/commands/npmrc.command.js.map +1 -1
- package/dist/core/cache.d.ts +1 -1
- package/dist/core/cache.js +58 -31
- package/dist/core/cache.js.map +1 -1
- package/dist/core/cds.js +32 -22
- package/dist/core/cds.js.map +1 -1
- package/dist/core/cf-env-parser.d.ts +1 -1
- package/dist/core/cf-env-parser.js +4 -1
- package/dist/core/cf-env-parser.js.map +1 -1
- package/dist/core/cf.d.ts +1 -1
- package/dist/core/cf.js +46 -31
- package/dist/core/cf.js.map +1 -1
- package/dist/core/db/db-btp.d.ts +48 -0
- package/dist/core/db/db-btp.js +162 -0
- package/dist/core/db/db-btp.js.map +1 -0
- package/dist/core/db/db-cache.d.ts +35 -0
- package/dist/core/db/db-cache.js +164 -0
- package/dist/core/db/db-cache.js.map +1 -0
- package/dist/core/db/db-connection.d.ts +22 -0
- package/dist/core/db/db-connection.js +73 -0
- package/dist/core/db/db-connection.js.map +1 -0
- package/dist/core/db/db-crypto.d.ts +3 -0
- package/dist/core/db/db-crypto.js +54 -0
- package/dist/core/db/db-crypto.js.map +1 -0
- package/dist/core/db/db-hana-adapter.d.ts +32 -0
- package/dist/core/db/db-hana-adapter.js +243 -0
- package/dist/core/db/db-hana-adapter.js.map +1 -0
- package/dist/core/db/db-metadata.d.ts +25 -0
- package/dist/core/db/db-metadata.js +150 -0
- package/dist/core/db/db-metadata.js.map +1 -0
- package/dist/core/db/db-postgres-adapter.d.ts +30 -0
- package/dist/core/db/db-postgres-adapter.js +245 -0
- package/dist/core/db/db-postgres-adapter.js.map +1 -0
- package/dist/core/db/db-query-files.d.ts +20 -0
- package/dist/core/db/db-query-files.js +106 -0
- package/dist/core/db/db-query-files.js.map +1 -0
- package/dist/core/db/db-query-history.d.ts +5 -0
- package/dist/core/db/db-query-history.js +49 -0
- package/dist/core/db/db-query-history.js.map +1 -0
- package/dist/core/db/db-row.d.ts +22 -0
- package/dist/core/db/db-row.js +70 -0
- package/dist/core/db/db-row.js.map +1 -0
- package/dist/core/db/db-studio-html.d.ts +4 -0
- package/dist/core/db/db-studio-html.js +437 -0
- package/dist/core/db/db-studio-html.js.map +1 -0
- package/dist/core/db/db-studio-server.d.ts +11 -0
- package/dist/core/db/db-studio-server.js +465 -0
- package/dist/core/db/db-studio-server.js.map +1 -0
- package/dist/core/db/db-types.d.ts +174 -0
- package/dist/core/db/db-types.js +3 -0
- package/dist/core/db/db-types.js.map +1 -0
- package/dist/core/db/db-vcap-parser.d.ts +7 -0
- package/dist/core/db/db-vcap-parser.js +137 -0
- package/dist/core/db/db-vcap-parser.js.map +1 -0
- package/dist/core/doctor.d.ts +1 -1
- package/dist/core/doctor.js +14 -8
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/guide.js +31 -26
- package/dist/core/guide.js.map +1 -1
- package/dist/core/install.d.ts +1 -1
- package/dist/core/install.js +17 -11
- package/dist/core/install.js.map +1 -1
- package/dist/core/navigator.d.ts +17 -0
- package/dist/core/navigator.js +140 -0
- package/dist/core/navigator.js.map +1 -0
- package/dist/core/npmrc.js +29 -16
- package/dist/core/npmrc.js.map +1 -1
- package/dist/core/process.js +11 -6
- package/dist/core/process.js.map +1 -1
- package/dist/core/prompts.js +16 -8
- package/dist/core/prompts.js.map +1 -1
- package/dist/core/repository.d.ts +1 -1
- package/dist/core/repository.js +16 -9
- package/dist/core/repository.js.map +1 -1
- package/dist/core/scanner.d.ts +1 -1
- package/dist/core/scanner.js +13 -7
- package/dist/core/scanner.js.map +1 -1
- package/dist/core/tooling.d.ts +28 -0
- package/dist/core/tooling.js +168 -0
- package/dist/core/tooling.js.map +1 -0
- package/dist/core/types.js +2 -1
- package/dist/core/version-conflict.d.ts +2 -2
- package/dist/core/version-conflict.js +11 -6
- package/dist/core/version-conflict.js.map +1 -1
- package/dist/index.js +65 -48
- package/dist/index.js.map +1 -1
- package/dist/types-local.js +2 -1
- package/package.json +12 -6
- package/src/commands/cds.command.ts +529 -0
- package/src/commands/cf-db.command.ts +636 -0
- package/src/commands/cf.command.ts +3345 -0
- package/src/commands/gitlab.command.ts +373 -0
- package/src/commands/npmrc.command.ts +581 -0
- package/src/core/cache.ts +332 -0
- package/src/core/cds.ts +278 -0
- package/src/core/cf-env-parser.ts +131 -0
- package/src/core/cf.ts +271 -0
- package/src/core/db/db-btp.ts +207 -0
- package/src/core/db/db-cache.ts +215 -0
- package/src/core/db/db-connection.ts +79 -0
- package/src/core/db/db-crypto.ts +53 -0
- package/src/core/db/db-hana-adapter.ts +294 -0
- package/src/core/db/db-metadata.ts +174 -0
- package/src/core/db/db-postgres-adapter.ts +275 -0
- package/src/core/db/db-query-files.ts +130 -0
- package/src/core/db/db-query-history.ts +53 -0
- package/src/core/db/db-row.ts +93 -0
- package/src/core/db/db-studio-html.ts +439 -0
- package/src/core/db/db-studio-server.ts +559 -0
- package/src/core/db/db-types.ts +195 -0
- package/src/core/db/db-vcap-parser.ts +182 -0
- package/src/core/doctor.ts +70 -0
- package/src/core/guide.ts +261 -0
- package/src/core/install.ts +91 -0
- package/src/core/navigator.ts +164 -0
- package/src/core/npmrc.ts +171 -0
- package/src/core/process.ts +75 -0
- package/src/core/prompts.ts +225 -0
- package/src/core/repository.ts +36 -0
- package/src/core/scanner.ts +41 -0
- package/src/core/tooling.ts +207 -0
- package/src/core/types.ts +152 -0
- package/src/core/version-conflict.ts +46 -0
- package/src/index.ts +460 -0
- package/src/types/external.d.ts +3 -0
- package/src/types-local.ts +11 -0
- package/tsconfig.json +17 -0
package/dist/core/cf.js
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCloudFoundryTargetKey = buildCloudFoundryTargetKey;
|
|
4
|
+
exports.readCloudFoundryTarget = readCloudFoundryTarget;
|
|
5
|
+
exports.setCloudFoundryApiEndpoint = setCloudFoundryApiEndpoint;
|
|
6
|
+
exports.authenticateCloudFoundry = authenticateCloudFoundry;
|
|
7
|
+
exports.targetCloudFoundryOrg = targetCloudFoundryOrg;
|
|
8
|
+
exports.targetCloudFoundrySpace = targetCloudFoundrySpace;
|
|
9
|
+
exports.listCloudFoundryOrganizations = listCloudFoundryOrganizations;
|
|
10
|
+
exports.listCloudFoundrySpaces = listCloudFoundrySpaces;
|
|
11
|
+
exports.inferCloudFoundryRegionFromApiEndpoint = inferCloudFoundryRegionFromApiEndpoint;
|
|
12
|
+
exports.scanCloudFoundryOrganizationsAcrossRegions = scanCloudFoundryOrganizationsAcrossRegions;
|
|
13
|
+
exports.loginCloudFoundry = loginCloudFoundry;
|
|
14
|
+
exports.listCloudFoundryApps = listCloudFoundryApps;
|
|
15
|
+
exports.parseCloudFoundryApps = parseCloudFoundryApps;
|
|
16
|
+
const process_1 = require("./process");
|
|
17
|
+
function buildCloudFoundryTargetKey(target) {
|
|
3
18
|
return [
|
|
4
19
|
target.apiEndpoint ?? "unknown-api",
|
|
5
20
|
target.org ?? "unknown-org",
|
|
6
21
|
target.space ?? "unknown-space",
|
|
7
22
|
].join("|");
|
|
8
23
|
}
|
|
9
|
-
|
|
10
|
-
const result = await runCommand("cf", ["target"]);
|
|
24
|
+
async function readCloudFoundryTarget() {
|
|
25
|
+
const result = await (0, process_1.runCommand)("cf", ["target"]);
|
|
11
26
|
if (result.exitCode !== 0) {
|
|
12
27
|
return {};
|
|
13
28
|
}
|
|
@@ -27,47 +42,47 @@ export async function readCloudFoundryTarget() {
|
|
|
27
42
|
}
|
|
28
43
|
return target;
|
|
29
44
|
}
|
|
30
|
-
|
|
31
|
-
const result = await runCommand("cf", ["api", apiEndpoint]);
|
|
45
|
+
async function setCloudFoundryApiEndpoint(apiEndpoint) {
|
|
46
|
+
const result = await (0, process_1.runCommand)("cf", ["api", apiEndpoint]);
|
|
32
47
|
if (result.stdout)
|
|
33
48
|
console.log(result.stdout);
|
|
34
49
|
if (result.stderr)
|
|
35
50
|
console.error(result.stderr);
|
|
36
51
|
return result.exitCode;
|
|
37
52
|
}
|
|
38
|
-
|
|
39
|
-
const result = await runCommand("cf", ["auth", options.username, options.password]);
|
|
53
|
+
async function authenticateCloudFoundry(options) {
|
|
54
|
+
const result = await (0, process_1.runCommand)("cf", ["auth", options.username, options.password]);
|
|
40
55
|
if (result.stdout)
|
|
41
56
|
console.log(result.stdout);
|
|
42
57
|
if (result.stderr)
|
|
43
58
|
console.error(result.stderr);
|
|
44
59
|
return result.exitCode;
|
|
45
60
|
}
|
|
46
|
-
|
|
47
|
-
const result = await runCommand("cf", ["target", "-o", org]);
|
|
61
|
+
async function targetCloudFoundryOrg(org) {
|
|
62
|
+
const result = await (0, process_1.runCommand)("cf", ["target", "-o", org]);
|
|
48
63
|
if (result.stdout)
|
|
49
64
|
console.log(result.stdout);
|
|
50
65
|
if (result.stderr)
|
|
51
66
|
console.error(result.stderr);
|
|
52
67
|
return result.exitCode;
|
|
53
68
|
}
|
|
54
|
-
|
|
55
|
-
const result = await runCommand("cf", ["target", "-s", space]);
|
|
69
|
+
async function targetCloudFoundrySpace(space) {
|
|
70
|
+
const result = await (0, process_1.runCommand)("cf", ["target", "-s", space]);
|
|
56
71
|
if (result.stdout)
|
|
57
72
|
console.log(result.stdout);
|
|
58
73
|
if (result.stderr)
|
|
59
74
|
console.error(result.stderr);
|
|
60
75
|
return result.exitCode;
|
|
61
76
|
}
|
|
62
|
-
|
|
63
|
-
const result = await runCommand("cf", ["orgs"]);
|
|
77
|
+
async function listCloudFoundryOrganizations() {
|
|
78
|
+
const result = await (0, process_1.runCommand)("cf", ["orgs"]);
|
|
64
79
|
if (result.exitCode !== 0) {
|
|
65
80
|
throw new Error(result.stderr || result.stdout || "cf orgs failed");
|
|
66
81
|
}
|
|
67
82
|
return parseCloudFoundryNameList(result.stdout, "name");
|
|
68
83
|
}
|
|
69
|
-
|
|
70
|
-
const result = await runCommand("cf", ["spaces"]);
|
|
84
|
+
async function listCloudFoundrySpaces() {
|
|
85
|
+
const result = await (0, process_1.runCommand)("cf", ["spaces"]);
|
|
71
86
|
if (result.exitCode !== 0) {
|
|
72
87
|
throw new Error(result.stderr || result.stdout || "cf spaces failed");
|
|
73
88
|
}
|
|
@@ -85,20 +100,20 @@ function parseCloudFoundryNameList(output, headerName) {
|
|
|
85
100
|
.filter((line) => !/^OK$/i.test(line))
|
|
86
101
|
.filter(Boolean);
|
|
87
102
|
}
|
|
88
|
-
|
|
103
|
+
function inferCloudFoundryRegionFromApiEndpoint(apiEndpoint) {
|
|
89
104
|
const match = apiEndpoint.match(/api\.cf\.([^.]+)\./i);
|
|
90
105
|
return match?.[1] ?? apiEndpoint.replace(/^https?:\/\//, "");
|
|
91
106
|
}
|
|
92
|
-
|
|
107
|
+
async function scanCloudFoundryOrganizationsAcrossRegions(apiEndpoints, credentials = []) {
|
|
93
108
|
const originalTarget = await readCloudFoundryTarget();
|
|
94
109
|
const orgEntries = [];
|
|
95
110
|
const uniqueApiEndpoints = [...new Set(apiEndpoints.map((apiEndpoint) => apiEndpoint.trim()).filter(Boolean))];
|
|
96
111
|
for (const apiEndpoint of uniqueApiEndpoints) {
|
|
97
|
-
const apiResult = await runCommand("cf", ["api", apiEndpoint]);
|
|
112
|
+
const apiResult = await (0, process_1.runCommand)("cf", ["api", apiEndpoint]);
|
|
98
113
|
if (apiResult.exitCode !== 0) {
|
|
99
114
|
continue;
|
|
100
115
|
}
|
|
101
|
-
let orgResult = await runCommand("cf", ["orgs"]);
|
|
116
|
+
let orgResult = await (0, process_1.runCommand)("cf", ["orgs"]);
|
|
102
117
|
if (orgResult.exitCode !== 0) {
|
|
103
118
|
const endpointCredentials = [
|
|
104
119
|
...credentials.filter((item) => item.apiEndpoint === apiEndpoint && item.password?.trim()),
|
|
@@ -111,11 +126,11 @@ export async function scanCloudFoundryOrganizationsAcrossRegions(apiEndpoints, c
|
|
|
111
126
|
continue;
|
|
112
127
|
}
|
|
113
128
|
triedUsers.add(credentialKey);
|
|
114
|
-
const authResult = await runCommand("cf", ["auth", credential.username, credential.password]);
|
|
129
|
+
const authResult = await (0, process_1.runCommand)("cf", ["auth", credential.username, credential.password]);
|
|
115
130
|
if (authResult.exitCode !== 0) {
|
|
116
131
|
continue;
|
|
117
132
|
}
|
|
118
|
-
orgResult = await runCommand("cf", ["orgs"]);
|
|
133
|
+
orgResult = await (0, process_1.runCommand)("cf", ["orgs"]);
|
|
119
134
|
if (orgResult.exitCode === 0) {
|
|
120
135
|
break;
|
|
121
136
|
}
|
|
@@ -128,9 +143,9 @@ export async function scanCloudFoundryOrganizationsAcrossRegions(apiEndpoints, c
|
|
|
128
143
|
const region = inferCloudFoundryRegionFromApiEndpoint(apiEndpoint);
|
|
129
144
|
for (const org of organizations) {
|
|
130
145
|
let spaces = [];
|
|
131
|
-
const orgTargetResult = await runCommand("cf", ["target", "-o", org]);
|
|
146
|
+
const orgTargetResult = await (0, process_1.runCommand)("cf", ["target", "-o", org]);
|
|
132
147
|
if (orgTargetResult.exitCode === 0) {
|
|
133
|
-
const spacesResult = await runCommand("cf", ["spaces"]);
|
|
148
|
+
const spacesResult = await (0, process_1.runCommand)("cf", ["spaces"]);
|
|
134
149
|
spaces = spacesResult.exitCode === 0 ? parseCloudFoundryNameList(spacesResult.stdout, "name") : [];
|
|
135
150
|
}
|
|
136
151
|
orgEntries.push({
|
|
@@ -144,12 +159,12 @@ export async function scanCloudFoundryOrganizationsAcrossRegions(apiEndpoints, c
|
|
|
144
159
|
}
|
|
145
160
|
}
|
|
146
161
|
if (originalTarget.apiEndpoint) {
|
|
147
|
-
await runCommand("cf", ["api", originalTarget.apiEndpoint]);
|
|
162
|
+
await (0, process_1.runCommand)("cf", ["api", originalTarget.apiEndpoint]);
|
|
148
163
|
if (originalTarget.org) {
|
|
149
|
-
await runCommand("cf", ["target", "-o", originalTarget.org]);
|
|
164
|
+
await (0, process_1.runCommand)("cf", ["target", "-o", originalTarget.org]);
|
|
150
165
|
}
|
|
151
166
|
if (originalTarget.space) {
|
|
152
|
-
await runCommand("cf", ["target", "-s", originalTarget.space]);
|
|
167
|
+
await (0, process_1.runCommand)("cf", ["target", "-s", originalTarget.space]);
|
|
153
168
|
}
|
|
154
169
|
}
|
|
155
170
|
return orgEntries.sort((left, right) => {
|
|
@@ -157,7 +172,7 @@ export async function scanCloudFoundryOrganizationsAcrossRegions(apiEndpoints, c
|
|
|
157
172
|
return byOrg !== 0 ? byOrg : left.region.localeCompare(right.region);
|
|
158
173
|
});
|
|
159
174
|
}
|
|
160
|
-
|
|
175
|
+
async function loginCloudFoundry(options) {
|
|
161
176
|
const apiExitCode = await setCloudFoundryApiEndpoint(options.apiEndpoint);
|
|
162
177
|
if (apiExitCode !== 0) {
|
|
163
178
|
return apiExitCode;
|
|
@@ -178,14 +193,14 @@ export async function loginCloudFoundry(options) {
|
|
|
178
193
|
}
|
|
179
194
|
return targetCloudFoundrySpace(options.space.trim());
|
|
180
195
|
}
|
|
181
|
-
|
|
182
|
-
const result = await runCommand("cf", ["apps"]);
|
|
196
|
+
async function listCloudFoundryApps() {
|
|
197
|
+
const result = await (0, process_1.runCommand)("cf", ["apps"]);
|
|
183
198
|
if (result.exitCode !== 0) {
|
|
184
199
|
throw new Error(result.stderr || result.stdout || "cf apps failed");
|
|
185
200
|
}
|
|
186
201
|
return parseCloudFoundryApps(result.stdout);
|
|
187
202
|
}
|
|
188
|
-
|
|
203
|
+
function parseCloudFoundryApps(output) {
|
|
189
204
|
const lines = output.split(/\r?\n/).map((line) => line.trimEnd()).filter(Boolean);
|
|
190
205
|
const nameHeaderIndex = lines.findIndex((line) => /^name\s+/i.test(line.trim()));
|
|
191
206
|
if (nameHeaderIndex === -1) {
|
package/dist/core/cf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cf.js","sourceRoot":"","sources":["../../src/core/cf.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cf.js","sourceRoot":"","sources":["../../src/core/cf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { TConnectionDraft } from "./db-cache";
|
|
2
|
+
import type { TDatabaseConnectionProfile, TDatabaseServiceCandidate, TDatabaseType } from "./db-types";
|
|
3
|
+
import type { TCloudFoundryApp, TCloudFoundryTarget } from "../types";
|
|
4
|
+
export type TCloudFoundrySessionState = {
|
|
5
|
+
loggedIn: boolean;
|
|
6
|
+
target: TCloudFoundryTarget;
|
|
7
|
+
message?: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Confirm there is a usable CF session. When the CF CLI reports no session, try
|
|
11
|
+
* to silently re-login using a cached profile that stored its password.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ensureCloudFoundrySession(): Promise<TCloudFoundrySessionState>;
|
|
14
|
+
export declare function getCloudFoundryTargetSummary(): Promise<TCloudFoundryTarget & {
|
|
15
|
+
region?: string;
|
|
16
|
+
}>;
|
|
17
|
+
export declare function listCloudFoundryAppsWithCache(options?: {
|
|
18
|
+
refresh?: boolean;
|
|
19
|
+
}): Promise<TCloudFoundryApp[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Read and parse VCAP_SERVICES from `cf env <app>`. Never logs the raw output
|
|
22
|
+
* because it contains credentials.
|
|
23
|
+
*/
|
|
24
|
+
export declare function readAppVcapServices(appName: string): Promise<unknown>;
|
|
25
|
+
export declare function detectAppDatabaseServices(appName: string): Promise<TDatabaseServiceCandidate[]>;
|
|
26
|
+
export declare function buildDraftFromCandidate(candidate: TDatabaseServiceCandidate, context: {
|
|
27
|
+
region?: string;
|
|
28
|
+
org?: string;
|
|
29
|
+
space?: string;
|
|
30
|
+
app?: string;
|
|
31
|
+
}): TConnectionDraft;
|
|
32
|
+
/**
|
|
33
|
+
* Import a single detected database service from a BTP app into the encrypted
|
|
34
|
+
* connection cache.
|
|
35
|
+
*/
|
|
36
|
+
export declare function importConnectionFromApp(options: {
|
|
37
|
+
app: string;
|
|
38
|
+
serviceName?: string;
|
|
39
|
+
type?: TDatabaseType;
|
|
40
|
+
context?: {
|
|
41
|
+
region?: string;
|
|
42
|
+
org?: string;
|
|
43
|
+
space?: string;
|
|
44
|
+
};
|
|
45
|
+
}): Promise<{
|
|
46
|
+
profile: TDatabaseConnectionProfile;
|
|
47
|
+
candidates: TDatabaseServiceCandidate[];
|
|
48
|
+
}>;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureCloudFoundrySession = ensureCloudFoundrySession;
|
|
4
|
+
exports.getCloudFoundryTargetSummary = getCloudFoundryTargetSummary;
|
|
5
|
+
exports.listCloudFoundryAppsWithCache = listCloudFoundryAppsWithCache;
|
|
6
|
+
exports.readAppVcapServices = readAppVcapServices;
|
|
7
|
+
exports.detectAppDatabaseServices = detectAppDatabaseServices;
|
|
8
|
+
exports.buildDraftFromCandidate = buildDraftFromCandidate;
|
|
9
|
+
exports.importConnectionFromApp = importConnectionFromApp;
|
|
10
|
+
const cache_1 = require("../cache");
|
|
11
|
+
const cf_1 = require("../cf");
|
|
12
|
+
const process_1 = require("../process");
|
|
13
|
+
const cf_env_parser_1 = require("../cf-env-parser");
|
|
14
|
+
const db_vcap_parser_1 = require("./db-vcap-parser");
|
|
15
|
+
const db_cache_1 = require("./db-cache");
|
|
16
|
+
async function isCloudFoundryCliAvailable() {
|
|
17
|
+
const result = await (0, process_1.runCommand)("cf", ["--version"]).catch(() => undefined);
|
|
18
|
+
return Boolean(result && result.exitCode === 0);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Confirm there is a usable CF session. When the CF CLI reports no session, try
|
|
22
|
+
* to silently re-login using a cached profile that stored its password.
|
|
23
|
+
*/
|
|
24
|
+
async function ensureCloudFoundrySession() {
|
|
25
|
+
if (!(await isCloudFoundryCliAvailable())) {
|
|
26
|
+
return {
|
|
27
|
+
loggedIn: false,
|
|
28
|
+
target: {},
|
|
29
|
+
message: "Cloud Foundry CLI 'cf' is not installed or not on PATH. Install it, then run: smdg cf login",
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const orgsCheck = await (0, process_1.runCommand)("cf", ["orgs"]);
|
|
33
|
+
if (orgsCheck.exitCode === 0) {
|
|
34
|
+
return { loggedIn: true, target: await (0, cf_1.readCloudFoundryTarget)() };
|
|
35
|
+
}
|
|
36
|
+
const cache = await (0, cache_1.readCache)();
|
|
37
|
+
const target = await (0, cf_1.readCloudFoundryTarget)();
|
|
38
|
+
const profilesWithPassword = cache.cloudFoundry.loginProfiles.filter((profile) => profile.password?.trim());
|
|
39
|
+
if (profilesWithPassword.length === 0) {
|
|
40
|
+
return {
|
|
41
|
+
loggedIn: false,
|
|
42
|
+
target,
|
|
43
|
+
message: "Not logged in to Cloud Foundry and no cached password was found. Run: smdg cf login",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const preferredProfiles = target.apiEndpoint
|
|
47
|
+
? [
|
|
48
|
+
...profilesWithPassword.filter((profile) => profile.apiEndpoint === target.apiEndpoint),
|
|
49
|
+
...profilesWithPassword.filter((profile) => profile.apiEndpoint !== target.apiEndpoint),
|
|
50
|
+
]
|
|
51
|
+
: profilesWithPassword;
|
|
52
|
+
for (const profile of preferredProfiles) {
|
|
53
|
+
const apiExitCode = await (0, cf_1.setCloudFoundryApiEndpoint)(profile.apiEndpoint);
|
|
54
|
+
if (apiExitCode !== 0)
|
|
55
|
+
continue;
|
|
56
|
+
const authExitCode = await (0, cf_1.authenticateCloudFoundry)({ username: profile.username, password: profile.password });
|
|
57
|
+
if (authExitCode !== 0)
|
|
58
|
+
continue;
|
|
59
|
+
await (0, cf_1.targetCloudFoundryOrg)(profile.org).catch(() => undefined);
|
|
60
|
+
if (profile.space) {
|
|
61
|
+
await (0, cf_1.targetCloudFoundrySpace)(profile.space).catch(() => undefined);
|
|
62
|
+
}
|
|
63
|
+
const recheck = await (0, process_1.runCommand)("cf", ["orgs"]);
|
|
64
|
+
if (recheck.exitCode === 0) {
|
|
65
|
+
return { loggedIn: true, target: await (0, cf_1.readCloudFoundryTarget)() };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
loggedIn: false,
|
|
70
|
+
target,
|
|
71
|
+
message: "Automatic Cloud Foundry re-login failed. Run: smdg cf login",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function getCloudFoundryTargetSummary() {
|
|
75
|
+
const target = await (0, cf_1.readCloudFoundryTarget)();
|
|
76
|
+
return {
|
|
77
|
+
...target,
|
|
78
|
+
region: target.apiEndpoint ? (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(target.apiEndpoint) : undefined,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async function listCloudFoundryAppsWithCache(options) {
|
|
82
|
+
const target = await (0, cf_1.readCloudFoundryTarget)();
|
|
83
|
+
const targetKey = (0, cf_1.buildCloudFoundryTargetKey)(target);
|
|
84
|
+
if (!options?.refresh) {
|
|
85
|
+
const cache = await (0, cache_1.readCache)();
|
|
86
|
+
const cachedEntry = cache.cloudFoundry.appListsByTarget[targetKey];
|
|
87
|
+
if (cachedEntry?.apps.length) {
|
|
88
|
+
return cachedEntry.apps;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const apps = await (0, cf_1.listCloudFoundryApps)();
|
|
92
|
+
await (0, cache_1.rememberCloudFoundryApps)(targetKey, apps).catch(() => undefined);
|
|
93
|
+
return apps;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Read and parse VCAP_SERVICES from `cf env <app>`. Never logs the raw output
|
|
97
|
+
* because it contains credentials.
|
|
98
|
+
*/
|
|
99
|
+
async function readAppVcapServices(appName) {
|
|
100
|
+
const result = await (0, process_1.runCommand)("cf", ["env", appName]);
|
|
101
|
+
if (result.exitCode !== 0) {
|
|
102
|
+
throw new Error(result.stderr || result.stdout || `cf env ${appName} failed`);
|
|
103
|
+
}
|
|
104
|
+
const parsed = (0, cf_env_parser_1.parseCloudFoundryEnvironment)(result.stdout);
|
|
105
|
+
if (parsed.VCAP_SERVICES === undefined) {
|
|
106
|
+
throw new Error(`VCAP_SERVICES was not found in cf env ${appName}`);
|
|
107
|
+
}
|
|
108
|
+
return parsed.VCAP_SERVICES;
|
|
109
|
+
}
|
|
110
|
+
async function detectAppDatabaseServices(appName) {
|
|
111
|
+
const vcapServices = await readAppVcapServices(appName);
|
|
112
|
+
const candidates = (0, db_vcap_parser_1.detectDatabaseServiceCandidates)(vcapServices);
|
|
113
|
+
if (candidates.length === 0) {
|
|
114
|
+
throw new Error(`No HANA or PostgreSQL service was detected in cf env ${appName}`);
|
|
115
|
+
}
|
|
116
|
+
return candidates;
|
|
117
|
+
}
|
|
118
|
+
function buildDraftFromCandidate(candidate, context) {
|
|
119
|
+
const databaseTypeLabel = { hana: "HANA", postgresql: "PostgreSQL" };
|
|
120
|
+
const namePieces = [context.app ?? "btp-app", candidate.serviceName, databaseTypeLabel[candidate.type]].filter(Boolean);
|
|
121
|
+
return {
|
|
122
|
+
name: namePieces.join(" / "),
|
|
123
|
+
type: candidate.type,
|
|
124
|
+
region: context.region,
|
|
125
|
+
org: context.org,
|
|
126
|
+
space: context.space,
|
|
127
|
+
app: context.app,
|
|
128
|
+
serviceName: candidate.serviceName,
|
|
129
|
+
servicePlan: candidate.servicePlan,
|
|
130
|
+
host: candidate.host,
|
|
131
|
+
port: candidate.port,
|
|
132
|
+
database: candidate.database,
|
|
133
|
+
schema: candidate.schema,
|
|
134
|
+
username: candidate.username,
|
|
135
|
+
password: candidate.password,
|
|
136
|
+
ssl: candidate.ssl,
|
|
137
|
+
sslValidateCertificate: candidate.sslValidateCertificate,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Import a single detected database service from a BTP app into the encrypted
|
|
142
|
+
* connection cache.
|
|
143
|
+
*/
|
|
144
|
+
async function importConnectionFromApp(options) {
|
|
145
|
+
const candidates = await detectAppDatabaseServices(options.app);
|
|
146
|
+
const target = await (0, cf_1.readCloudFoundryTarget)();
|
|
147
|
+
const chosen = options.serviceName
|
|
148
|
+
? candidates.find((candidate) => candidate.serviceName === options.serviceName && (!options.type || candidate.type === options.type))
|
|
149
|
+
: candidates[0];
|
|
150
|
+
if (!chosen) {
|
|
151
|
+
throw new Error(`Service '${options.serviceName ?? ""}' was not found among detected database services for ${options.app}`);
|
|
152
|
+
}
|
|
153
|
+
const draft = buildDraftFromCandidate(chosen, {
|
|
154
|
+
region: options.context?.region ?? (target.apiEndpoint ? (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(target.apiEndpoint) : undefined),
|
|
155
|
+
org: options.context?.org ?? target.org,
|
|
156
|
+
space: options.context?.space ?? target.space,
|
|
157
|
+
app: options.app,
|
|
158
|
+
});
|
|
159
|
+
const profile = await (0, db_cache_1.upsertConnectionFromDraft)(draft);
|
|
160
|
+
return { profile, candidates };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=db-btp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-btp.js","sourceRoot":"","sources":["../../../src/core/db/db-btp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { TDatabaseConnectionProfile, TDatabaseType, TPublicDatabaseConnection, TResolvedDatabaseConnection } from "./db-types";
|
|
2
|
+
/**
|
|
3
|
+
* Draft used when creating or updating a connection. The password is provided
|
|
4
|
+
* in plain text and encrypted before it ever touches disk.
|
|
5
|
+
*/
|
|
6
|
+
export type TConnectionDraft = {
|
|
7
|
+
id?: string;
|
|
8
|
+
name: string;
|
|
9
|
+
type: TDatabaseType;
|
|
10
|
+
region?: string;
|
|
11
|
+
org?: string;
|
|
12
|
+
space?: string;
|
|
13
|
+
app?: string;
|
|
14
|
+
serviceName?: string;
|
|
15
|
+
servicePlan?: string;
|
|
16
|
+
host: string;
|
|
17
|
+
port: number;
|
|
18
|
+
database?: string;
|
|
19
|
+
schema?: string;
|
|
20
|
+
username: string;
|
|
21
|
+
password: string;
|
|
22
|
+
ssl?: boolean;
|
|
23
|
+
sslValidateCertificate?: boolean;
|
|
24
|
+
tags?: string[];
|
|
25
|
+
};
|
|
26
|
+
export declare function listConnectionProfiles(): Promise<TDatabaseConnectionProfile[]>;
|
|
27
|
+
export declare function listPublicConnections(): Promise<TPublicDatabaseConnection[]>;
|
|
28
|
+
export declare function findConnectionProfile(id: string): Promise<TDatabaseConnectionProfile | undefined>;
|
|
29
|
+
export declare function getResolvedConnection(id: string): Promise<TResolvedDatabaseConnection>;
|
|
30
|
+
export declare function upsertConnectionFromDraft(draft: TConnectionDraft): Promise<TDatabaseConnectionProfile>;
|
|
31
|
+
export declare function removeConnection(id: string): Promise<boolean>;
|
|
32
|
+
export declare function renameConnection(id: string, name: string): Promise<TDatabaseConnectionProfile>;
|
|
33
|
+
export declare function duplicateConnection(id: string): Promise<TDatabaseConnectionProfile>;
|
|
34
|
+
export declare function touchConnectionUsage(id: string): Promise<void>;
|
|
35
|
+
export declare function getConnectionsFilePath(): string;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.listConnectionProfiles = listConnectionProfiles;
|
|
7
|
+
exports.listPublicConnections = listPublicConnections;
|
|
8
|
+
exports.findConnectionProfile = findConnectionProfile;
|
|
9
|
+
exports.getResolvedConnection = getResolvedConnection;
|
|
10
|
+
exports.upsertConnectionFromDraft = upsertConnectionFromDraft;
|
|
11
|
+
exports.removeConnection = removeConnection;
|
|
12
|
+
exports.renameConnection = renameConnection;
|
|
13
|
+
exports.duplicateConnection = duplicateConnection;
|
|
14
|
+
exports.touchConnectionUsage = touchConnectionUsage;
|
|
15
|
+
exports.getConnectionsFilePath = getConnectionsFilePath;
|
|
16
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
17
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
18
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
19
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
20
|
+
const db_crypto_1 = require("./db-crypto");
|
|
21
|
+
const CACHE_DIRECTORY = node_path_1.default.join(node_os_1.default.homedir(), ".simplemdg");
|
|
22
|
+
const CONNECTIONS_FILE_PATH = node_path_1.default.join(CACHE_DIRECTORY, "db-connections.json");
|
|
23
|
+
async function readCacheFile() {
|
|
24
|
+
if (!(await fs_extra_1.default.pathExists(CONNECTIONS_FILE_PATH))) {
|
|
25
|
+
return { connections: [] };
|
|
26
|
+
}
|
|
27
|
+
const parsed = await fs_extra_1.default
|
|
28
|
+
.readJson(CONNECTIONS_FILE_PATH)
|
|
29
|
+
.catch(() => ({ connections: [] }));
|
|
30
|
+
return { connections: Array.isArray(parsed.connections) ? parsed.connections : [] };
|
|
31
|
+
}
|
|
32
|
+
async function writeCacheFile(cache) {
|
|
33
|
+
await fs_extra_1.default.ensureDir(CACHE_DIRECTORY);
|
|
34
|
+
// Defensive: ensure every password is encrypted before persisting.
|
|
35
|
+
const secured = {
|
|
36
|
+
connections: cache.connections.map((connection) => ({
|
|
37
|
+
...connection,
|
|
38
|
+
encryptedPassword: (0, db_crypto_1.encryptSecret)(connection.encryptedPassword),
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
await fs_extra_1.default.writeJson(CONNECTIONS_FILE_PATH, secured, { spaces: 2 });
|
|
42
|
+
}
|
|
43
|
+
function toPublicConnection(profile) {
|
|
44
|
+
const { encryptedPassword: _ignored, ...rest } = profile;
|
|
45
|
+
void _ignored;
|
|
46
|
+
return rest;
|
|
47
|
+
}
|
|
48
|
+
async function listConnectionProfiles() {
|
|
49
|
+
const cache = await readCacheFile();
|
|
50
|
+
return cache.connections;
|
|
51
|
+
}
|
|
52
|
+
async function listPublicConnections() {
|
|
53
|
+
const cache = await readCacheFile();
|
|
54
|
+
return cache.connections
|
|
55
|
+
.map(toPublicConnection)
|
|
56
|
+
.sort((left, right) => (right.lastUsedAt ?? right.updatedAt).localeCompare(left.lastUsedAt ?? left.updatedAt));
|
|
57
|
+
}
|
|
58
|
+
async function findConnectionProfile(id) {
|
|
59
|
+
const cache = await readCacheFile();
|
|
60
|
+
return cache.connections.find((connection) => connection.id === id);
|
|
61
|
+
}
|
|
62
|
+
async function getResolvedConnection(id) {
|
|
63
|
+
const profile = await findConnectionProfile(id);
|
|
64
|
+
if (!profile) {
|
|
65
|
+
throw new Error(`Connection not found: ${id}`);
|
|
66
|
+
}
|
|
67
|
+
const { encryptedPassword, ...rest } = profile;
|
|
68
|
+
return { ...rest, password: (0, db_crypto_1.decryptSecret)(encryptedPassword) };
|
|
69
|
+
}
|
|
70
|
+
async function upsertConnectionFromDraft(draft) {
|
|
71
|
+
const cache = await readCacheFile();
|
|
72
|
+
const now = new Date().toISOString();
|
|
73
|
+
const existingIndex = draft.id
|
|
74
|
+
? cache.connections.findIndex((connection) => connection.id === draft.id)
|
|
75
|
+
: cache.connections.findIndex((connection) => connection.app === draft.app &&
|
|
76
|
+
connection.serviceName === draft.serviceName &&
|
|
77
|
+
connection.type === draft.type &&
|
|
78
|
+
Boolean(draft.app) &&
|
|
79
|
+
Boolean(draft.serviceName));
|
|
80
|
+
const existing = existingIndex >= 0 ? cache.connections[existingIndex] : undefined;
|
|
81
|
+
const profile = {
|
|
82
|
+
id: existing?.id ?? draft.id ?? node_crypto_1.default.randomUUID(),
|
|
83
|
+
name: draft.name,
|
|
84
|
+
type: draft.type,
|
|
85
|
+
region: draft.region,
|
|
86
|
+
org: draft.org,
|
|
87
|
+
space: draft.space,
|
|
88
|
+
app: draft.app,
|
|
89
|
+
serviceName: draft.serviceName,
|
|
90
|
+
servicePlan: draft.servicePlan,
|
|
91
|
+
host: draft.host,
|
|
92
|
+
port: draft.port,
|
|
93
|
+
database: draft.database,
|
|
94
|
+
schema: draft.schema,
|
|
95
|
+
username: draft.username,
|
|
96
|
+
encryptedPassword: (0, db_crypto_1.encryptSecret)(draft.password),
|
|
97
|
+
ssl: draft.ssl,
|
|
98
|
+
sslValidateCertificate: draft.sslValidateCertificate,
|
|
99
|
+
tags: draft.tags,
|
|
100
|
+
createdAt: existing?.createdAt ?? now,
|
|
101
|
+
updatedAt: now,
|
|
102
|
+
lastUsedAt: existing?.lastUsedAt,
|
|
103
|
+
};
|
|
104
|
+
if (existingIndex >= 0) {
|
|
105
|
+
cache.connections[existingIndex] = profile;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
cache.connections.unshift(profile);
|
|
109
|
+
}
|
|
110
|
+
await writeCacheFile(cache);
|
|
111
|
+
return profile;
|
|
112
|
+
}
|
|
113
|
+
async function removeConnection(id) {
|
|
114
|
+
const cache = await readCacheFile();
|
|
115
|
+
const nextConnections = cache.connections.filter((connection) => connection.id !== id);
|
|
116
|
+
if (nextConnections.length === cache.connections.length) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
await writeCacheFile({ connections: nextConnections });
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
async function renameConnection(id, name) {
|
|
123
|
+
const cache = await readCacheFile();
|
|
124
|
+
const profile = cache.connections.find((connection) => connection.id === id);
|
|
125
|
+
if (!profile) {
|
|
126
|
+
throw new Error(`Connection not found: ${id}`);
|
|
127
|
+
}
|
|
128
|
+
profile.name = name;
|
|
129
|
+
profile.updatedAt = new Date().toISOString();
|
|
130
|
+
await writeCacheFile(cache);
|
|
131
|
+
return profile;
|
|
132
|
+
}
|
|
133
|
+
async function duplicateConnection(id) {
|
|
134
|
+
const cache = await readCacheFile();
|
|
135
|
+
const source = cache.connections.find((connection) => connection.id === id);
|
|
136
|
+
if (!source) {
|
|
137
|
+
throw new Error(`Connection not found: ${id}`);
|
|
138
|
+
}
|
|
139
|
+
const now = new Date().toISOString();
|
|
140
|
+
const copy = {
|
|
141
|
+
...source,
|
|
142
|
+
id: node_crypto_1.default.randomUUID(),
|
|
143
|
+
name: `${source.name} (copy)`,
|
|
144
|
+
createdAt: now,
|
|
145
|
+
updatedAt: now,
|
|
146
|
+
lastUsedAt: undefined,
|
|
147
|
+
};
|
|
148
|
+
cache.connections.unshift(copy);
|
|
149
|
+
await writeCacheFile(cache);
|
|
150
|
+
return copy;
|
|
151
|
+
}
|
|
152
|
+
async function touchConnectionUsage(id) {
|
|
153
|
+
const cache = await readCacheFile();
|
|
154
|
+
const profile = cache.connections.find((connection) => connection.id === id);
|
|
155
|
+
if (!profile) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
profile.lastUsedAt = new Date().toISOString();
|
|
159
|
+
await writeCacheFile(cache);
|
|
160
|
+
}
|
|
161
|
+
function getConnectionsFilePath() {
|
|
162
|
+
return CONNECTIONS_FILE_PATH;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=db-cache.js.map
|