@mittwald/cli 1.0.0-alpha.11 → 1.0.0-alpha.14
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 +1136 -579
- package/dist/esm/DeleteBaseCommand.js +1 -1
- package/dist/esm/Helpers.d.ts +1 -0
- package/dist/esm/Helpers.js +7 -1
- package/dist/esm/Translator.d.ts +1 -0
- package/dist/esm/Translator.js +11 -0
- package/dist/esm/commands/app/install/wordpress.js +1 -1
- package/dist/esm/commands/context/set.js +4 -3
- package/dist/esm/commands/database/mysql/charsets.d.ts +14 -3
- package/dist/esm/commands/database/mysql/charsets.js +25 -2
- package/dist/esm/commands/database/mysql/create.d.ts +23 -0
- package/dist/esm/commands/database/mysql/create.js +103 -0
- package/dist/esm/commands/database/mysql/delete.d.ts +14 -0
- package/dist/esm/commands/database/mysql/delete.js +20 -0
- package/dist/esm/commands/database/mysql/dump.d.ts +15 -0
- package/dist/esm/commands/database/mysql/dump.js +70 -0
- package/dist/esm/commands/database/mysql/get.d.ts +14 -2
- package/dist/esm/commands/database/mysql/get.js +14 -5
- package/dist/esm/commands/database/mysql/list.d.ts +11 -3
- package/dist/esm/commands/database/mysql/list.js +23 -13
- package/dist/esm/commands/database/mysql/phpmyadmin.d.ts +8 -0
- package/dist/esm/commands/database/mysql/phpmyadmin.js +25 -0
- package/dist/esm/commands/database/mysql/port-forward.d.ts +14 -0
- package/dist/esm/commands/database/mysql/port-forward.js +44 -0
- package/dist/esm/commands/database/mysql/shell.d.ts +14 -0
- package/dist/esm/commands/database/mysql/shell.js +39 -0
- package/dist/esm/commands/database/mysql/user/get.d.ts +13 -2
- package/dist/esm/commands/database/mysql/user/get.js +18 -5
- package/dist/esm/commands/database/mysql/user/list.d.ts +13 -3
- package/dist/esm/commands/database/mysql/user/list.js +38 -2
- package/dist/esm/commands/database/mysql/versions.d.ts +13 -3
- package/dist/esm/commands/database/mysql/versions.js +19 -2
- package/dist/esm/commands/database/redis/get.d.ts +15 -2
- package/dist/esm/commands/database/redis/get.js +21 -5
- package/dist/esm/commands/database/redis/list.d.ts +13 -3
- package/dist/esm/commands/database/redis/list.js +26 -2
- package/dist/esm/commands/database/redis/shell.d.ts +13 -0
- package/dist/esm/commands/database/redis/shell.js +26 -0
- package/dist/esm/commands/database/redis/versions.d.ts +11 -3
- package/dist/esm/commands/database/redis/versions.js +12 -2
- package/dist/esm/commands/domain/virtualhost/create.js +1 -1
- package/dist/esm/commands/login/reset.js +1 -1
- package/dist/esm/commands/mail/address/create.d.ts +1 -1
- package/dist/esm/commands/mail/address/create.js +1 -1
- package/dist/esm/commands/org/delete.js +2 -3
- package/dist/esm/commands/org/invite/revoke.js +1 -1
- package/dist/esm/commands/org/invite.js +1 -1
- package/dist/esm/commands/org/list.js +4 -0
- package/dist/esm/commands/org/membership/revoke.js +1 -1
- package/dist/esm/commands/project/create.js +1 -1
- package/dist/esm/commands/project/get.js +8 -4
- package/dist/esm/commands/project/list-react.js +1 -1
- package/dist/esm/commands/user/api-token/create.js +1 -1
- package/dist/esm/commands/user/ssh-key/create.js +1 -1
- package/dist/esm/lib/database/common.d.ts +8 -0
- package/dist/esm/lib/database/common.js +17 -0
- package/dist/esm/lib/database/mysql/connect.d.ts +19 -0
- package/dist/esm/lib/database/mysql/connect.js +50 -0
- package/dist/esm/lib/database/mysql/flags.d.ts +10 -0
- package/dist/esm/lib/database/mysql/flags.js +48 -0
- package/dist/esm/lib/database/redis/connect.d.ts +8 -0
- package/dist/esm/lib/database/redis/connect.js +22 -0
- package/dist/esm/lib/database/redis/flags.d.ts +7 -0
- package/dist/esm/lib/database/redis/flags.js +35 -0
- package/dist/esm/lib/org/flags.js +2 -1
- package/dist/esm/rendering/process/components/ProcessConfirmation.d.ts +6 -0
- package/dist/esm/rendering/process/components/ProcessConfirmation.js +12 -0
- package/dist/esm/rendering/process/components/ProcessConfirmationStateSummary.d.ts +5 -0
- package/dist/esm/rendering/process/components/ProcessConfirmationStateSummary.js +18 -0
- package/dist/esm/rendering/process/components/ProcessError.d.ts +4 -0
- package/dist/esm/rendering/process/components/ProcessError.js +10 -0
- package/dist/esm/rendering/process/components/ProcessInput.d.ts +6 -0
- package/dist/esm/rendering/process/components/ProcessInput.js +15 -0
- package/dist/esm/rendering/process/components/ProcessInputStateSummary.d.ts +5 -0
- package/dist/esm/rendering/process/components/ProcessInputStateSummary.js +13 -0
- package/dist/esm/rendering/process/components/ProcessState.d.ts +5 -0
- package/dist/esm/rendering/process/components/ProcessState.js +8 -0
- package/dist/esm/rendering/process/components/ProcessStateIcon.d.ts +5 -0
- package/dist/esm/rendering/process/components/ProcessStateIcon.js +22 -0
- package/dist/esm/rendering/process/components/ProcessStateSummary.d.ts +5 -0
- package/dist/esm/rendering/process/components/ProcessStateSummary.js +27 -0
- package/dist/esm/rendering/process/components/ProcessValidationErrors.d.ts +7 -0
- package/dist/esm/rendering/process/components/ProcessValidationErrors.js +15 -0
- package/dist/esm/rendering/{react → process}/process.d.ts +5 -5
- package/dist/esm/rendering/{react → process}/process_fancy.d.ts +1 -12
- package/dist/esm/rendering/process/process_fancy.js +119 -0
- package/dist/esm/rendering/process/process_flags.d.ts +20 -0
- package/dist/esm/rendering/{react → process}/process_flags.js +13 -0
- package/dist/esm/rendering/{react → process}/process_quiet.d.ts +2 -2
- package/dist/esm/rendering/react/components/ErrorBox.d.ts +11 -0
- package/dist/esm/rendering/react/components/ErrorBox.js +45 -0
- package/dist/esm/rendering/react/components/{ProjectReadiness.js → Project/ProjectReadiness.js} +1 -1
- package/dist/esm/rendering/react/components/Project/ProjectStatus.d.ts +18 -0
- package/dist/esm/rendering/react/error.d.ts +6 -0
- package/dist/esm/rendering/react/error.js +9 -40
- package/package.json +25 -5
- package/dist/esm/commands/database/mysql/user/getMysqlUserPhpMyAdminUrl.d.ts +0 -3
- package/dist/esm/commands/database/mysql/user/getMysqlUserPhpMyAdminUrl.js +0 -7
- package/dist/esm/generated/database/getMysqlDatabase.d.ts +0 -16
- package/dist/esm/generated/database/getMysqlDatabase.js +0 -25
- package/dist/esm/generated/database/getMysqlUser.d.ts +0 -16
- package/dist/esm/generated/database/getMysqlUser.js +0 -25
- package/dist/esm/generated/database/getMysqlUserPhpMyAdminUrl.d.ts +0 -14
- package/dist/esm/generated/database/getMysqlUserPhpMyAdminUrl.js +0 -24
- package/dist/esm/generated/database/getRedisDatabase.d.ts +0 -16
- package/dist/esm/generated/database/getRedisDatabase.js +0 -25
- package/dist/esm/generated/database/listMysqlCharsets.d.ts +0 -13
- package/dist/esm/generated/database/listMysqlCharsets.js +0 -17
- package/dist/esm/generated/database/listMysqlDatabases.d.ts +0 -13
- package/dist/esm/generated/database/listMysqlDatabases.js +0 -24
- package/dist/esm/generated/database/listMysqlUsers.d.ts +0 -13
- package/dist/esm/generated/database/listMysqlUsers.js +0 -24
- package/dist/esm/generated/database/listMysqlVersions.d.ts +0 -13
- package/dist/esm/generated/database/listMysqlVersions.js +0 -17
- package/dist/esm/generated/database/listRedisDatabases.d.ts +0 -13
- package/dist/esm/generated/database/listRedisDatabases.js +0 -24
- package/dist/esm/generated/database/listRedisVersions.d.ts +0 -13
- package/dist/esm/generated/database/listRedisVersions.js +0 -17
- package/dist/esm/rendering/react/components/ProjectStatus.d.ts +0 -7
- package/dist/esm/rendering/react/process_fancy.js +0 -221
- package/dist/esm/rendering/react/process_flags.d.ts +0 -9
- /package/dist/esm/rendering/{react → process}/process.js +0 -0
- /package/dist/esm/rendering/{react → process}/process_quiet.js +0 -0
- /package/dist/esm/rendering/react/components/{ProjectEnabled.d.ts → Project/ProjectEnabled.d.ts} +0 -0
- /package/dist/esm/rendering/react/components/{ProjectEnabled.js → Project/ProjectEnabled.js} +0 -0
- /package/dist/esm/rendering/react/components/{ProjectReadiness.d.ts → Project/ProjectReadiness.d.ts} +0 -0
- /package/dist/esm/rendering/react/components/{ProjectStatus.js → Project/ProjectStatus.js} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as _jsxs, Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Flags, ux } from "@oclif/core";
|
|
3
3
|
import { ExecRenderBaseCommand } from "./rendering/react/ExecRenderBaseCommand.js";
|
|
4
|
-
import { makeProcessRenderer, processFlags, } from "./rendering/
|
|
4
|
+
import { makeProcessRenderer, processFlags, } from "./rendering/process/process_flags.js";
|
|
5
5
|
import { Success } from "./rendering/react/components/Success.js";
|
|
6
6
|
import { Text } from "ink";
|
|
7
7
|
export class DeleteBaseCommand extends ExecRenderBaseCommand {
|
package/dist/esm/Helpers.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export declare function isUuid(id: string): boolean;
|
|
|
3
3
|
export declare function isProjectShortId(id: string): boolean;
|
|
4
4
|
export declare function normalizeProjectIdToUuid(apiClient: MittwaldAPIV2Client, uuidOrShortId: string): Promise<string>;
|
|
5
5
|
export declare function normalizeServerIdToUuid(apiClient: MittwaldAPIV2Client, uuidOrShortId: string): Promise<string>;
|
|
6
|
+
export declare function normalizeCustomerIdToUuid(apiClient: MittwaldAPIV2Client, uuidOrShortId: string): Promise<string>;
|
|
6
7
|
export declare function normalizeConversationIdToUuid(apiClient: MittwaldAPIV2Client, uuidOrShortId: string): Promise<string>;
|
package/dist/esm/Helpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getConversationUuidFromShortId, getProjectUuidFromShortId, getServerUuidFromShortId, } from "./Translator.js";
|
|
1
|
+
import { getConversationUuidFromShortId, getCustomerUuidFromCustomerNumber, getProjectUuidFromShortId, getServerUuidFromShortId, } from "./Translator.js";
|
|
2
2
|
const uuidRegex = RegExp("^[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$");
|
|
3
3
|
const projectShortIdRegex = RegExp("p-[0-9a-zA-Z]{6}");
|
|
4
4
|
export function isUuid(id) {
|
|
@@ -22,6 +22,12 @@ export async function normalizeServerIdToUuid(apiClient, uuidOrShortId) {
|
|
|
22
22
|
}
|
|
23
23
|
return await getServerUuidFromShortId(apiClient, uuidOrShortId);
|
|
24
24
|
}
|
|
25
|
+
export async function normalizeCustomerIdToUuid(apiClient, uuidOrShortId) {
|
|
26
|
+
if (isUuid(uuidOrShortId)) {
|
|
27
|
+
return uuidOrShortId;
|
|
28
|
+
}
|
|
29
|
+
return await getCustomerUuidFromCustomerNumber(apiClient, uuidOrShortId);
|
|
30
|
+
}
|
|
25
31
|
export async function normalizeConversationIdToUuid(apiClient, uuidOrShortId) {
|
|
26
32
|
if (isUuid(uuidOrShortId)) {
|
|
27
33
|
return uuidOrShortId;
|
package/dist/esm/Translator.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MittwaldAPIV2Client } from "@mittwald/api-client";
|
|
2
2
|
export declare function getProjectUuidFromShortId(apiClient: MittwaldAPIV2Client, shortId: string): Promise<string>;
|
|
3
3
|
export declare function getServerUuidFromShortId(apiClient: MittwaldAPIV2Client, shortId: string): Promise<string>;
|
|
4
|
+
export declare function getCustomerUuidFromCustomerNumber(apiClient: MittwaldAPIV2Client, shortId: string): Promise<string>;
|
|
4
5
|
export declare function getConversationUuidFromShortId(apiClient: MittwaldAPIV2Client, shortId: string): Promise<string>;
|
|
5
6
|
export declare function getAppNameFromUuid(apiClient: MittwaldAPIV2Client, uuid: string): Promise<string>;
|
|
6
7
|
export declare function getAppVersionFromUuid(apiClient: MittwaldAPIV2Client, appId: string, appVersionId: string): Promise<string>;
|
package/dist/esm/Translator.js
CHANGED
|
@@ -25,6 +25,17 @@ export async function getServerUuidFromShortId(apiClient, shortId) {
|
|
|
25
25
|
}
|
|
26
26
|
throw new Error("Access Denied.");
|
|
27
27
|
}
|
|
28
|
+
export async function getCustomerUuidFromCustomerNumber(apiClient, shortId) {
|
|
29
|
+
const customers = await apiClient.customer.listCustomers();
|
|
30
|
+
assertStatus(customers, 200);
|
|
31
|
+
const foundCustomer = customers.data.find((item) => {
|
|
32
|
+
return item.customerNumber === shortId;
|
|
33
|
+
});
|
|
34
|
+
if (foundCustomer) {
|
|
35
|
+
return foundCustomer.customerId;
|
|
36
|
+
}
|
|
37
|
+
throw new Error("Access Denied.");
|
|
38
|
+
}
|
|
28
39
|
export async function getConversationUuidFromShortId(apiClient, shortId) {
|
|
29
40
|
const conversations = await apiClient.conversation.listConversations();
|
|
30
41
|
assertStatus(conversations, 200);
|
|
@@ -5,7 +5,7 @@ import { getAppVersionUuidFromAppVersion, getLatestAvailableAppVersionForApp, }
|
|
|
5
5
|
import { assertStatus } from "@mittwald/api-client-commons";
|
|
6
6
|
import { projectFlags, withProjectId } from "../../../lib/project/flags.js";
|
|
7
7
|
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
8
|
-
import { makeProcessRenderer, processFlags, } from "../../../rendering/
|
|
8
|
+
import { makeProcessRenderer, processFlags, } from "../../../rendering/process/process_flags.js";
|
|
9
9
|
import { Value } from "../../../rendering/react/components/Value.js";
|
|
10
10
|
import { Text } from "ink";
|
|
11
11
|
import { Success } from "../../../rendering/react/components/Success.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Flags } from "@oclif/core";
|
|
2
2
|
import { Context } from "../../lib/context.js";
|
|
3
3
|
import { BaseCommand } from "../../BaseCommand.js";
|
|
4
|
-
import { normalizeProjectIdToUuid, normalizeServerIdToUuid, } from "../../Helpers.js";
|
|
4
|
+
import { normalizeCustomerIdToUuid, normalizeProjectIdToUuid, normalizeServerIdToUuid, } from "../../Helpers.js";
|
|
5
5
|
export class Set extends BaseCommand {
|
|
6
6
|
static summary = "Set context values for the current project, org or server";
|
|
7
7
|
static description = "The context allows you to persistently set values for common parameters, like --project-id or --server-id, so you don't have to specify them on every command.";
|
|
@@ -30,8 +30,9 @@ export class Set extends BaseCommand {
|
|
|
30
30
|
this.log(`Set server ID to ${serverId}`);
|
|
31
31
|
}
|
|
32
32
|
if (flags["org-id"]) {
|
|
33
|
-
await
|
|
34
|
-
|
|
33
|
+
const orgId = await normalizeCustomerIdToUuid(this.apiClient, flags["org-id"]);
|
|
34
|
+
await ctx.setOrgId(orgId);
|
|
35
|
+
this.log(`Set organization ID to ${orgId}`);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { Simplify } from "@mittwald/api-client-commons";
|
|
2
|
-
import { MittwaldAPIV2 } from "@mittwald/api-client";
|
|
2
|
+
import { MittwaldAPIV2, MittwaldAPIV2Client } from "@mittwald/api-client";
|
|
3
3
|
import { SuccessfulResponse } from "../../../types.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ListBaseCommand } from "../../../ListBaseCommand.js";
|
|
5
|
+
import { ListColumns } from "../../../Formatter.js";
|
|
5
6
|
type ResponseItem = Simplify<MittwaldAPIV2.Paths.V2MysqlCharsets.Get.Responses.$200.Content.ApplicationJson[number]>;
|
|
6
|
-
export
|
|
7
|
+
export type PathParams = MittwaldAPIV2.Paths.V2MysqlCharsets.Get.Parameters.Path;
|
|
8
|
+
export type Response = Awaited<ReturnType<MittwaldAPIV2Client["database"]["listMysqlCharsets"]>>;
|
|
9
|
+
export declare class Charsets extends ListBaseCommand<typeof Charsets, ResponseItem, Response> {
|
|
10
|
+
static description: string;
|
|
11
|
+
static args: {};
|
|
12
|
+
static flags: {
|
|
13
|
+
[x: string]: import("@oclif/core/lib/interfaces/parser.js").CompletableFlag<any>;
|
|
14
|
+
};
|
|
15
|
+
getData(): Promise<Response>;
|
|
16
|
+
protected mapParams(input: PathParams): Promise<PathParams> | PathParams;
|
|
7
17
|
protected mapData(data: SuccessfulResponse<Response, 200>["data"]): MittwaldAPIV2.Components.Schemas.DatabaseMySqlCharacterSettings[];
|
|
18
|
+
protected getColumns(data: ResponseItem[]): ListColumns<ResponseItem>;
|
|
8
19
|
}
|
|
9
20
|
export {};
|
|
@@ -1,6 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
1
|
+
import { ListBaseCommand } from "../../../ListBaseCommand.js";
|
|
2
|
+
export class Charsets extends ListBaseCommand {
|
|
3
|
+
static description = "List available MySQL character sets and collations, optionally filtered by a MySQLVersion.";
|
|
4
|
+
static args = {};
|
|
5
|
+
static flags = {
|
|
6
|
+
...ListBaseCommand.baseFlags,
|
|
7
|
+
};
|
|
8
|
+
async getData() {
|
|
9
|
+
const pathParams = {};
|
|
10
|
+
return await this.apiClient.database.listMysqlCharsets({
|
|
11
|
+
pathParameters: await this.mapParams(pathParams),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
mapParams(input) {
|
|
15
|
+
return input;
|
|
16
|
+
}
|
|
3
17
|
mapData(data) {
|
|
18
|
+
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
4
19
|
return data;
|
|
5
20
|
}
|
|
21
|
+
getColumns(data) {
|
|
22
|
+
return {
|
|
23
|
+
name: {},
|
|
24
|
+
collations: {
|
|
25
|
+
get: (item) => item.collations.join(", "),
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
6
29
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
type Result = {
|
|
4
|
+
databaseId: string;
|
|
5
|
+
userId: string;
|
|
6
|
+
};
|
|
7
|
+
export declare class Create extends ExecRenderBaseCommand<typeof Create, Result> {
|
|
8
|
+
static summary: string;
|
|
9
|
+
static flags: {
|
|
10
|
+
description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
|
+
version: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
+
collation: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
|
+
"character-set": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
14
|
+
"user-password": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
15
|
+
"user-external": import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
16
|
+
"user-access-level": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
17
|
+
quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
18
|
+
};
|
|
19
|
+
protected exec(): Promise<Result>;
|
|
20
|
+
private getPassword;
|
|
21
|
+
protected render({ databaseId }: Result): ReactNode;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
3
|
+
import { projectFlags, withProjectId } from "../../../lib/project/flags.js";
|
|
4
|
+
import { makeProcessRenderer, processFlags, } from "../../../rendering/process/process_flags.js";
|
|
5
|
+
import { Flags } from "@oclif/core";
|
|
6
|
+
import { Text } from "ink";
|
|
7
|
+
import { assertStatus } from "@mittwald/api-client-commons";
|
|
8
|
+
import { Success } from "../../../rendering/react/components/Success.js";
|
|
9
|
+
import { Value } from "../../../rendering/react/components/Value.js";
|
|
10
|
+
export class Create extends ExecRenderBaseCommand {
|
|
11
|
+
static summary = "Create a new MySQL database";
|
|
12
|
+
static flags = {
|
|
13
|
+
...projectFlags,
|
|
14
|
+
...processFlags,
|
|
15
|
+
description: Flags.string({
|
|
16
|
+
char: "d",
|
|
17
|
+
summary: "a description for the database",
|
|
18
|
+
required: true,
|
|
19
|
+
}),
|
|
20
|
+
version: Flags.string({
|
|
21
|
+
summary: "the MySQL version to use",
|
|
22
|
+
description: 'Use the "database mysql versions" command to list available versions',
|
|
23
|
+
required: true,
|
|
24
|
+
}),
|
|
25
|
+
collation: Flags.string({
|
|
26
|
+
summary: "the collation to use",
|
|
27
|
+
default: "utf8mb4_unicode_ci",
|
|
28
|
+
}),
|
|
29
|
+
"character-set": Flags.string({
|
|
30
|
+
summary: "the character set to use",
|
|
31
|
+
default: "utf8mb4",
|
|
32
|
+
}),
|
|
33
|
+
"user-password": Flags.string({
|
|
34
|
+
summary: "the password to use for the default user (env: MYSQL_PWD)",
|
|
35
|
+
env: "MYSQL_PWD",
|
|
36
|
+
}),
|
|
37
|
+
"user-external": Flags.boolean({
|
|
38
|
+
summary: "enable external access for default user",
|
|
39
|
+
default: false,
|
|
40
|
+
}),
|
|
41
|
+
"user-access-level": Flags.string({
|
|
42
|
+
summary: "the access level preset for the default user",
|
|
43
|
+
options: ["full", "readonly"],
|
|
44
|
+
default: "full",
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
async exec() {
|
|
48
|
+
const p = makeProcessRenderer(this.flags, "Creating a new MySQL database");
|
|
49
|
+
const projectId = await withProjectId(this.apiClient, this.flags, this.args, this.config);
|
|
50
|
+
const { description, version, collation, "character-set": characterSet, "user-external": externalAccess, "user-access-level": accessLevel, } = this.flags;
|
|
51
|
+
const password = await this.getPassword(p);
|
|
52
|
+
const db = await p.runStep("creating MySQL database", async () => {
|
|
53
|
+
const r = await this.apiClient.database.createMysqlDatabase({
|
|
54
|
+
pathParameters: { projectId },
|
|
55
|
+
data: {
|
|
56
|
+
database: {
|
|
57
|
+
projectId,
|
|
58
|
+
description,
|
|
59
|
+
version,
|
|
60
|
+
characterSettings: {
|
|
61
|
+
collation,
|
|
62
|
+
characterSet,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
user: {
|
|
66
|
+
password,
|
|
67
|
+
externalAccess,
|
|
68
|
+
accessLevel: accessLevel,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
assertStatus(r, 201);
|
|
73
|
+
return r.data;
|
|
74
|
+
});
|
|
75
|
+
const database = await p.runStep("fetching database", async () => {
|
|
76
|
+
const r = await this.apiClient.database.getMysqlDatabase({
|
|
77
|
+
pathParameters: { id: db.id },
|
|
78
|
+
});
|
|
79
|
+
assertStatus(r, 200);
|
|
80
|
+
return r.data;
|
|
81
|
+
});
|
|
82
|
+
const user = await p.runStep("fetching user", async () => {
|
|
83
|
+
const r = await this.apiClient.database.getMysqlUser({
|
|
84
|
+
pathParameters: { id: db.userId },
|
|
85
|
+
});
|
|
86
|
+
assertStatus(r, 200);
|
|
87
|
+
return r.data;
|
|
88
|
+
});
|
|
89
|
+
p.complete(_jsxs(Success, { children: ["The database ", _jsx(Value, { children: database.name }), " and the user", " ", _jsx(Value, { children: user.name }), " were successfully created."] }));
|
|
90
|
+
return { databaseId: db.id, userId: db.userId };
|
|
91
|
+
}
|
|
92
|
+
async getPassword(p) {
|
|
93
|
+
if (this.flags["user-password"]) {
|
|
94
|
+
return this.flags["user-password"];
|
|
95
|
+
}
|
|
96
|
+
return await p.addInput(_jsx(Text, { children: "enter password for default user" }), true);
|
|
97
|
+
}
|
|
98
|
+
render({ databaseId }) {
|
|
99
|
+
if (this.flags.quiet) {
|
|
100
|
+
return databaseId;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DeleteBaseCommand } from "../../../DeleteBaseCommand.js";
|
|
2
|
+
export default class Delete extends DeleteBaseCommand<typeof Delete> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static resourceName: string;
|
|
5
|
+
static flags: {
|
|
6
|
+
force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
7
|
+
quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
static args: {
|
|
10
|
+
"database-id": import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
protected deleteResource(): Promise<void>;
|
|
13
|
+
protected mapResourceId(id: string): Promise<string>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { assertStatus } from "@mittwald/api-client-commons";
|
|
2
|
+
import { normalizeProjectIdToUuid } from "../../../Helpers.js";
|
|
3
|
+
import { DeleteBaseCommand } from "../../../DeleteBaseCommand.js";
|
|
4
|
+
import { mysqlArgs, withMySQLId } from "../../../lib/database/mysql/flags.js";
|
|
5
|
+
export default class Delete extends DeleteBaseCommand {
|
|
6
|
+
static description = "Delete a MySQL database";
|
|
7
|
+
static resourceName = "MySQL database";
|
|
8
|
+
static flags = { ...DeleteBaseCommand.baseFlags };
|
|
9
|
+
static args = { ...mysqlArgs };
|
|
10
|
+
async deleteResource() {
|
|
11
|
+
const id = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
|
|
12
|
+
const response = await this.apiClient.database.deleteMysqlDatabase({
|
|
13
|
+
pathParameters: { id },
|
|
14
|
+
});
|
|
15
|
+
assertStatus(response, 200);
|
|
16
|
+
}
|
|
17
|
+
mapResourceId(id) {
|
|
18
|
+
return normalizeProjectIdToUuid(this.apiClient, id);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
export declare class Dump extends ExecRenderBaseCommand<typeof Dump, Record<string, never>> {
|
|
4
|
+
static summary: string;
|
|
5
|
+
static flags: {
|
|
6
|
+
output: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
7
|
+
"mysql-password": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
static args: {
|
|
11
|
+
"database-id": import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
12
|
+
};
|
|
13
|
+
protected exec(): Promise<Record<string, never>>;
|
|
14
|
+
protected render(): ReactNode;
|
|
15
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
3
|
+
import { Flags } from "@oclif/core";
|
|
4
|
+
import { makeProcessRenderer, processFlags, } from "../../../rendering/process/process_flags.js";
|
|
5
|
+
import * as cp from "child_process";
|
|
6
|
+
import { Text } from "ink";
|
|
7
|
+
import { Value } from "../../../rendering/react/components/Value.js";
|
|
8
|
+
import * as fs from "fs";
|
|
9
|
+
import { Success } from "../../../rendering/react/components/Success.js";
|
|
10
|
+
import { mysqlArgs, mysqlConnectionFlags, withMySQLId, } from "../../../lib/database/mysql/flags.js";
|
|
11
|
+
import { getConnectionDetailsWithPassword } from "../../../lib/database/mysql/connect.js";
|
|
12
|
+
export class Dump extends ExecRenderBaseCommand {
|
|
13
|
+
static summary = "Create a dump of a MySQL database";
|
|
14
|
+
static flags = {
|
|
15
|
+
...processFlags,
|
|
16
|
+
...mysqlConnectionFlags,
|
|
17
|
+
output: Flags.string({
|
|
18
|
+
char: "o",
|
|
19
|
+
summary: 'the output file to write the dump to ("-" for stdout)',
|
|
20
|
+
description: 'The output file to write the dump to. You can specify "-" or "/dev/stdout" to write the dump directly to STDOUT; in this case, you might want to use the --quiet/-q flag to supress all other output, so that you can pipe the mysqldump for further processing.',
|
|
21
|
+
required: true,
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
static args = { ...mysqlArgs };
|
|
25
|
+
async exec() {
|
|
26
|
+
const databaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
|
|
27
|
+
const p = makeProcessRenderer(this.flags, "Dumping a MySQL database");
|
|
28
|
+
const { sshUser, sshHost, user, hostname, database, password } = await getConnectionDetailsWithPassword(this.apiClient, databaseId, p, this.flags);
|
|
29
|
+
const sshArgs = [
|
|
30
|
+
"-l",
|
|
31
|
+
sshUser,
|
|
32
|
+
"-T",
|
|
33
|
+
sshHost,
|
|
34
|
+
"mysqldump",
|
|
35
|
+
"-h",
|
|
36
|
+
hostname,
|
|
37
|
+
"-u",
|
|
38
|
+
user,
|
|
39
|
+
"-p" + password,
|
|
40
|
+
database,
|
|
41
|
+
];
|
|
42
|
+
const stream = fs.createWriteStream(this.flags.output);
|
|
43
|
+
await p.runStep(_jsxs(Text, { children: ["starting mysqldump via SSH on ", _jsx(Value, { children: sshHost }), " as", " ", _jsx(Value, { children: sshUser })] }), () => {
|
|
44
|
+
const ssh = cp.spawn("ssh", sshArgs, {
|
|
45
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
46
|
+
});
|
|
47
|
+
let err = "";
|
|
48
|
+
ssh.stdout.pipe(stream);
|
|
49
|
+
ssh.stderr.on("data", (data) => {
|
|
50
|
+
err += data.toString();
|
|
51
|
+
});
|
|
52
|
+
return new Promise((res, rej) => {
|
|
53
|
+
ssh.on("exit", (code) => {
|
|
54
|
+
stream.close();
|
|
55
|
+
if (code === 0) {
|
|
56
|
+
res(undefined);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
rej(new Error(`ssh+mysqldump exited with code ${code}\n${err}`));
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
p.complete(_jsxs(Success, { children: ["Dump of MySQL database ", _jsx(Value, { children: database }), " written to", " ", _jsx(Value, { children: this.flags.output })] }));
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
render() {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { MittwaldAPIV2, MittwaldAPIV2Client } from "@mittwald/api-client";
|
|
2
|
+
import { GetBaseCommand } from "../../../GetBaseCommand.js";
|
|
3
|
+
export type PathParams = MittwaldAPIV2.Paths.V2MysqlDatabasesId.Get.Parameters.Path;
|
|
4
|
+
type APIResponse = Awaited<ReturnType<MittwaldAPIV2Client["database"]["getMysqlDatabase"]>>;
|
|
5
|
+
export declare abstract class Get extends GetBaseCommand<typeof Get, APIResponse> {
|
|
6
|
+
static description: string;
|
|
7
|
+
static flags: {
|
|
8
|
+
[x: string]: import("@oclif/core/lib/interfaces/parser.js").CompletableFlag<any>;
|
|
9
|
+
};
|
|
10
|
+
static args: {
|
|
11
|
+
"database-id": import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
12
|
+
};
|
|
13
|
+
protected getData(): Promise<APIResponse>;
|
|
3
14
|
}
|
|
15
|
+
export {};
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { GetBaseCommand } from "../../../GetBaseCommand.js";
|
|
2
|
+
import { mysqlArgs, withMySQLId } from "../../../lib/database/mysql/flags.js";
|
|
3
|
+
export class Get extends GetBaseCommand {
|
|
4
|
+
static description = "Get a MySQLDatabase.";
|
|
5
|
+
static flags = {
|
|
6
|
+
...GetBaseCommand.baseFlags,
|
|
7
|
+
};
|
|
8
|
+
static args = { ...mysqlArgs };
|
|
9
|
+
async getData() {
|
|
10
|
+
const id = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
|
|
11
|
+
return await this.apiClient.database.getMysqlDatabase({
|
|
12
|
+
pathParameters: { id },
|
|
13
|
+
});
|
|
14
|
+
}
|
|
6
15
|
}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Simplify } from "@mittwald/api-client-commons";
|
|
2
|
-
import { MittwaldAPIV2 } from "@mittwald/api-client";
|
|
2
|
+
import { MittwaldAPIV2, MittwaldAPIV2Client } from "@mittwald/api-client";
|
|
3
3
|
import { SuccessfulResponse } from "../../../types.js";
|
|
4
|
-
import { GeneratedDatabaseListMysqlDatabases, Response } from "../../../generated/database/listMysqlDatabases.js";
|
|
5
4
|
import { ListColumns } from "../../../Formatter.js";
|
|
5
|
+
import { ListBaseCommand } from "../../../ListBaseCommand.js";
|
|
6
6
|
type ResponseItem = Simplify<MittwaldAPIV2.Paths.V2ProjectsProjectIdMysqlDatabases.Get.Responses.$200.Content.ApplicationJson[number]>;
|
|
7
|
-
export
|
|
7
|
+
export type PathParams = MittwaldAPIV2.Paths.V2ProjectsProjectIdMysqlDatabases.Get.Parameters.Path;
|
|
8
|
+
export type Response = Awaited<ReturnType<MittwaldAPIV2Client["database"]["listMysqlDatabases"]>>;
|
|
9
|
+
export declare class List extends ListBaseCommand<typeof List, ResponseItem, Response> {
|
|
10
|
+
static description: string;
|
|
11
|
+
static args: {};
|
|
12
|
+
static flags: {
|
|
13
|
+
[x: string]: import("@oclif/core/lib/interfaces/parser.js").CompletableFlag<any> | import("@oclif/core/lib/interfaces/parser.js").OptionFlag<unknown>;
|
|
14
|
+
};
|
|
15
|
+
getData(): Promise<Response>;
|
|
8
16
|
protected mapData(data: SuccessfulResponse<Response, 200>["data"]): MittwaldAPIV2.Components.Schemas.DatabaseMySqlDatabase[];
|
|
9
17
|
protected getColumns(ignoredData: ResponseItem[]): ListColumns<ResponseItem>;
|
|
10
18
|
}
|
|
@@ -1,25 +1,38 @@
|
|
|
1
|
-
import { GeneratedDatabaseListMysqlDatabases, } from "../../../generated/database/listMysqlDatabases.js";
|
|
2
1
|
import { formatBytes } from "../../../lib/viewhelpers/size.js";
|
|
3
|
-
|
|
2
|
+
import { ListBaseCommand } from "../../../ListBaseCommand.js";
|
|
3
|
+
import { projectFlags, withProjectId } from "../../../lib/project/flags.js";
|
|
4
|
+
export class List extends ListBaseCommand {
|
|
5
|
+
static description = "List MySQLDatabases belonging to a Project.";
|
|
6
|
+
static args = {};
|
|
7
|
+
static flags = {
|
|
8
|
+
...ListBaseCommand.baseFlags,
|
|
9
|
+
...projectFlags,
|
|
10
|
+
};
|
|
11
|
+
async getData() {
|
|
12
|
+
const projectId = await withProjectId(this.apiClient, this.flags, this.args, this.config);
|
|
13
|
+
return await this.apiClient.database.listMysqlDatabases({
|
|
14
|
+
pathParameters: { projectId },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
4
17
|
mapData(data) {
|
|
5
18
|
return data;
|
|
6
19
|
}
|
|
7
20
|
getColumns(ignoredData) {
|
|
8
21
|
const commonColumns = super.getColumns(ignoredData);
|
|
9
22
|
return {
|
|
10
|
-
|
|
23
|
+
id: commonColumns.id,
|
|
11
24
|
name: {
|
|
12
|
-
header: "
|
|
25
|
+
header: "Name",
|
|
13
26
|
minWidth: 12,
|
|
14
27
|
},
|
|
15
28
|
version: {
|
|
16
|
-
header: "
|
|
29
|
+
header: "Version",
|
|
17
30
|
},
|
|
18
31
|
description: {
|
|
19
|
-
header: "
|
|
32
|
+
header: "Description",
|
|
20
33
|
},
|
|
21
34
|
hostname: {
|
|
22
|
-
header: "
|
|
35
|
+
header: "Hostname",
|
|
23
36
|
},
|
|
24
37
|
status: {
|
|
25
38
|
header: "Status",
|
|
@@ -30,12 +43,8 @@ export default class List extends GeneratedDatabaseListMysqlDatabases {
|
|
|
30
43
|
return "ready";
|
|
31
44
|
},
|
|
32
45
|
},
|
|
33
|
-
isShared: {
|
|
34
|
-
header: "isShared",
|
|
35
|
-
extended: true,
|
|
36
|
-
},
|
|
37
46
|
characterSet: {
|
|
38
|
-
header: "
|
|
47
|
+
header: "Character Set",
|
|
39
48
|
get: (row) => row.characterSettings?.characterSet,
|
|
40
49
|
extended: true,
|
|
41
50
|
},
|
|
@@ -45,10 +54,11 @@ export default class List extends GeneratedDatabaseListMysqlDatabases {
|
|
|
45
54
|
extended: true,
|
|
46
55
|
},
|
|
47
56
|
size: {
|
|
48
|
-
header: "
|
|
57
|
+
header: "Size",
|
|
49
58
|
// there is an error in the API mapping
|
|
50
59
|
get: (row) => formatBytes(row.size.low),
|
|
51
60
|
},
|
|
61
|
+
createdAt: commonColumns.createdAt,
|
|
52
62
|
};
|
|
53
63
|
}
|
|
54
64
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../BaseCommand.js";
|
|
2
|
+
export declare class PhpMyAdmin extends BaseCommand {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static args: {
|
|
5
|
+
"database-id": import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
run(): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../BaseCommand.js";
|
|
2
|
+
import { assertStatus } from "@mittwald/api-client-commons";
|
|
3
|
+
import open from "open";
|
|
4
|
+
import { mysqlArgs, withMySQLId } from "../../../lib/database/mysql/flags.js";
|
|
5
|
+
export class PhpMyAdmin extends BaseCommand {
|
|
6
|
+
static summary = "Open phpMyAdmin for a MySQL database.";
|
|
7
|
+
static args = { ...mysqlArgs };
|
|
8
|
+
async run() {
|
|
9
|
+
const { flags, args } = await this.parse(PhpMyAdmin);
|
|
10
|
+
const databaseId = await withMySQLId(this.apiClient, flags, args, this.config);
|
|
11
|
+
const users = await this.apiClient.database.listMysqlUsers({
|
|
12
|
+
pathParameters: { databaseId },
|
|
13
|
+
});
|
|
14
|
+
assertStatus(users, 200);
|
|
15
|
+
const mainUser = users.data.find((u) => u.mainUser);
|
|
16
|
+
if (!mainUser) {
|
|
17
|
+
throw new Error("no main user found.");
|
|
18
|
+
}
|
|
19
|
+
const pma = await this.apiClient.database.getMysqlUserPhpMyAdminUrl({
|
|
20
|
+
pathParameters: { id: mainUser.id },
|
|
21
|
+
});
|
|
22
|
+
assertStatus(pma, 200);
|
|
23
|
+
await open(pma.data.url);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
export declare class PortForward extends ExecRenderBaseCommand<typeof PortForward, Record<string, never>> {
|
|
4
|
+
static summary: string;
|
|
5
|
+
static flags: {
|
|
6
|
+
port: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
7
|
+
quiet: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
static args: {
|
|
10
|
+
"database-id": import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
protected exec(): Promise<Record<string, never>>;
|
|
13
|
+
protected render(): ReactNode;
|
|
14
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ExecRenderBaseCommand } from "../../../rendering/react/ExecRenderBaseCommand.js";
|
|
3
|
+
import { makeProcessRenderer, processFlags, } from "../../../rendering/process/process_flags.js";
|
|
4
|
+
import * as cp from "child_process";
|
|
5
|
+
import { Text } from "ink";
|
|
6
|
+
import { mysqlArgs, withMySQLId } from "../../../lib/database/mysql/flags.js";
|
|
7
|
+
import { getConnectionDetails } from "../../../lib/database/mysql/connect.js";
|
|
8
|
+
import { Value } from "../../../rendering/react/components/Value.js";
|
|
9
|
+
import { Flags } from "@oclif/core";
|
|
10
|
+
export class PortForward extends ExecRenderBaseCommand {
|
|
11
|
+
static summary = "Forward the TCP port of a MySQL database to a local port";
|
|
12
|
+
static flags = {
|
|
13
|
+
...processFlags,
|
|
14
|
+
port: Flags.integer({
|
|
15
|
+
summary: "The local TCP port to forward to",
|
|
16
|
+
default: 3306,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static args = { ...mysqlArgs };
|
|
20
|
+
async exec() {
|
|
21
|
+
const databaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
|
|
22
|
+
const p = makeProcessRenderer(this.flags, "Port-forwarding a MySQL database");
|
|
23
|
+
const { sshUser, sshHost, hostname, database } = await getConnectionDetails(this.apiClient, databaseId, p);
|
|
24
|
+
const { port } = this.flags;
|
|
25
|
+
p.complete(_jsxs(Text, { children: ["Forwarding MySQL database ", _jsx(Value, { children: database }), " to local port", " ", _jsx(Value, { children: port }), ". Use CTRL+C to cancel."] }));
|
|
26
|
+
const sshArgs = [
|
|
27
|
+
"-T",
|
|
28
|
+
"-L",
|
|
29
|
+
`${port}:${hostname}:3306`,
|
|
30
|
+
"-l",
|
|
31
|
+
sshUser,
|
|
32
|
+
sshHost,
|
|
33
|
+
"cat",
|
|
34
|
+
"/dev/zero",
|
|
35
|
+
];
|
|
36
|
+
cp.spawnSync("ssh", sshArgs, {
|
|
37
|
+
stdio: ["ignore", process.stdout, process.stderr],
|
|
38
|
+
});
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
render() {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|