@mittwald/cli 1.0.0-alpha.37 → 1.0.0-alpha.38

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 CHANGED
@@ -2280,7 +2280,7 @@ USAGE
2280
2280
  $ mw database mysql delete DATABASE-ID [-q] [-f]
2281
2281
 
2282
2282
  ARGUMENTS
2283
- DATABASE-ID The ID of the database (when a project context is set, you can also use the name)
2283
+ DATABASE-ID The ID or name of the database
2284
2284
 
2285
2285
  FLAGS
2286
2286
  -f, --force Do not ask for confirmation
@@ -2305,7 +2305,7 @@ USAGE
2305
2305
  $ mw database mysql dump DATABASE-ID -o <value> [-q] [-p <value>] [--ssh-user <value>] [--temporary-user] [--gzip]
2306
2306
 
2307
2307
  ARGUMENTS
2308
- DATABASE-ID The ID of the database (when a project context is set, you can also use the name)
2308
+ DATABASE-ID The ID or name of the database
2309
2309
 
2310
2310
  FLAGS
2311
2311
  -o, --output=<value> (required) the output file to write the dump to ("-" for stdout)
@@ -2365,7 +2365,7 @@ USAGE
2365
2365
  $ mw database mysql get DATABASE-ID [-o json|yaml | | ]
2366
2366
 
2367
2367
  ARGUMENTS
2368
- DATABASE-ID The ID of the database (when a project context is set, you can also use the name)
2368
+ DATABASE-ID The ID or name of the database
2369
2369
 
2370
2370
  FLAGS
2371
2371
  -o, --output=<option> output in a more machine friendly format
@@ -2415,7 +2415,7 @@ USAGE
2415
2415
  $ mw database mysql phpmyadmin DATABASE-ID
2416
2416
 
2417
2417
  ARGUMENTS
2418
- DATABASE-ID The ID of the database (when a project context is set, you can also use the name)
2418
+ DATABASE-ID The ID or name of the database
2419
2419
  ```
2420
2420
 
2421
2421
  ## `mw database mysql port-forward DATABASE-ID`
@@ -2427,7 +2427,7 @@ USAGE
2427
2427
  $ mw database mysql port-forward DATABASE-ID [-q] [--ssh-user <value>] [--port <value>]
2428
2428
 
2429
2429
  ARGUMENTS
2430
- DATABASE-ID The ID of the database (when a project context is set, you can also use the name)
2430
+ DATABASE-ID The ID or name of the database
2431
2431
 
2432
2432
  FLAGS
2433
2433
  -q, --quiet suppress process output and only display a machine-readable summary.
@@ -2457,7 +2457,7 @@ USAGE
2457
2457
  $ mw database mysql shell DATABASE-ID [-q] [-p <value>]
2458
2458
 
2459
2459
  ARGUMENTS
2460
- DATABASE-ID The ID of the database (when a project context is set, you can also use the name)
2460
+ DATABASE-ID The ID or name of the database
2461
2461
 
2462
2462
  FLAGS
2463
2463
  -p, --mysql-password=<value> the password to use for the MySQL user (env: MYSQL_PWD)
@@ -3123,7 +3123,7 @@ DESCRIPTION
3123
3123
  Display help for mw.
3124
3124
  ```
3125
3125
 
3126
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.0.14/src/commands/help.ts)_
3126
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.0.15/src/commands/help.ts)_
3127
3127
 
3128
3128
  ## `mw login reset`
3129
3129
 
@@ -4517,7 +4517,7 @@ EXAMPLES
4517
4517
  $ mw update --available
4518
4518
  ```
4519
4519
 
4520
- _See code: [@oclif/plugin-update](https://github.com/oclif/plugin-update/blob/v4.1.14/src/commands/update.ts)_
4520
+ _See code: [@oclif/plugin-update](https://github.com/oclif/plugin-update/blob/v4.1.16/src/commands/update.ts)_
4521
4521
 
4522
4522
  ## `mw user api-token create`
4523
4523
 
@@ -2,6 +2,8 @@ import { Command } from "@oclif/core";
2
2
  import * as fs from "fs/promises";
3
3
  import * as path from "path";
4
4
  import { MittwaldAPIV2Client } from "@mittwald/api-client";
5
+ import { configureAxiosRetry } from "./lib/api_retry.js";
6
+ import { configureConsistencyHandling } from "./lib/api_consistency.js";
5
7
  export class BaseCommand extends Command {
6
8
  authenticationRequired = true;
7
9
  apiClient = MittwaldAPIV2Client.newUnauthenticated();
@@ -15,6 +17,8 @@ export class BaseCommand extends Command {
15
17
  this.apiClient = MittwaldAPIV2Client.newWithToken(token);
16
18
  this.apiClient.axios.defaults.headers["User-Agent"] =
17
19
  `mittwald-cli/${this.config.version}`;
20
+ configureAxiosRetry(this.apiClient.axios);
21
+ configureConsistencyHandling(this.apiClient.axios);
18
22
  }
19
23
  }
20
24
  getTokenFilename() {
@@ -18,6 +18,7 @@ export declare class Create extends ExecRenderBaseCommand<typeof Create, Result>
18
18
  "project-id": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string>;
19
19
  };
20
20
  protected exec(): Promise<Result>;
21
+ private createMySQLDatabase;
21
22
  private getPassword;
22
23
  protected render({ databaseId }: Result): ReactNode;
23
24
  }
@@ -49,46 +49,48 @@ export class Create extends ExecRenderBaseCommand {
49
49
  const projectId = await this.withProjectId(Create);
50
50
  const { description, version, collation, "character-set": characterSet, "user-external": externalAccess, "user-access-level": accessLevel, } = this.flags;
51
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
- 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;
52
+ const db = await this.createMySQLDatabase(p, projectId, {
53
+ description,
54
+ version,
55
+ characterSettings: {
56
+ collation,
57
+ characterSet,
58
+ },
59
+ }, {
60
+ password,
61
+ externalAccess,
62
+ accessLevel: accessLevel,
74
63
  });
75
64
  const database = await p.runStep("fetching database", async () => {
76
- const r = await this.apiClient.database.getMysqlDatabase({
65
+ const response = await this.apiClient.database.getMysqlDatabase({
77
66
  mysqlDatabaseId: db.id,
78
67
  });
79
- assertStatus(r, 200);
80
- return r.data;
68
+ assertStatus(response, 200);
69
+ return response.data;
81
70
  });
82
71
  const user = await p.runStep("fetching user", async () => {
83
- const r = await this.apiClient.database.getMysqlUser({
72
+ const response = await this.apiClient.database.getMysqlUser({
84
73
  mysqlUserId: db.userId,
85
74
  });
86
- assertStatus(r, 200);
87
- return r.data;
75
+ assertStatus(response, 200);
76
+ return response.data;
88
77
  });
89
- p.complete(_jsxs(Success, { children: ["The database ", _jsx(Value, { children: database.name }), " and the user", " ", _jsx(Value, { children: user.name }), " were successfully created."] }));
78
+ await p.complete(_jsx(DatabaseCreateSuccess, { database: database, user: user }));
90
79
  return { databaseId: db.id, userId: db.userId };
91
80
  }
81
+ async createMySQLDatabase(p, projectId, database, user) {
82
+ return await p.runStep("creating MySQL database", async () => {
83
+ const r = await this.apiClient.database.createMysqlDatabase({
84
+ projectId,
85
+ data: {
86
+ database: { projectId, ...database },
87
+ user,
88
+ },
89
+ });
90
+ assertStatus(r, 201);
91
+ return r.data;
92
+ });
93
+ }
92
94
  async getPassword(p) {
93
95
  if (this.flags["user-password"]) {
94
96
  return this.flags["user-password"];
@@ -101,3 +103,6 @@ export class Create extends ExecRenderBaseCommand {
101
103
  }
102
104
  }
103
105
  }
106
+ function DatabaseCreateSuccess({ database, user, }) {
107
+ return (_jsxs(Success, { children: ["The database ", _jsx(Value, { children: database.name }), " and the user", " ", _jsx(Value, { children: user.name }), " were successfully created."] }));
108
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,100 @@
1
+ import { expect, test } from "@oclif/test";
2
+ describe("database:mysql:create", () => {
3
+ const projectId = "339d6458-839f-4809-a03d-78700069690c";
4
+ const databaseId = "83e0cb85-dcf7-4968-8646-87a63980ae91";
5
+ const userId = "a8c1eb2a-aa4d-4daf-8e21-9d91d56559ca";
6
+ const password = "secret";
7
+ const description = "Test";
8
+ const createFlags = [
9
+ "database mysql create",
10
+ "--project-id",
11
+ projectId,
12
+ "--version",
13
+ "8.0",
14
+ "--description",
15
+ description,
16
+ "--user-password",
17
+ password,
18
+ ];
19
+ test
20
+ .nock("https://api.mittwald.de", (api) => {
21
+ api.get(`/v2/projects/${projectId}`).reply(200, {
22
+ id: projectId,
23
+ });
24
+ api
25
+ .post(`/v2/projects/${projectId}/mysql-databases`, {
26
+ database: {
27
+ projectId,
28
+ description,
29
+ version: "8.0",
30
+ characterSettings: {
31
+ collation: "utf8mb4_unicode_ci",
32
+ characterSet: "utf8mb4",
33
+ },
34
+ },
35
+ user: {
36
+ password,
37
+ externalAccess: false,
38
+ accessLevel: "full",
39
+ },
40
+ })
41
+ .reply(201, { id: databaseId, userId });
42
+ api.get(`/v2/mysql-databases/${databaseId}`).reply(200, {
43
+ id: databaseId,
44
+ name: "mysql_xxxxxx",
45
+ });
46
+ api.get(`/v2/mysql-users/${userId}`).reply(200, {
47
+ id: userId,
48
+ name: "dbu_xxxxxx",
49
+ });
50
+ })
51
+ .env({ MITTWALD_API_TOKEN: "foo" })
52
+ .stdout()
53
+ .command(createFlags)
54
+ .it("creates a database and prints database and user name", (ctx) => {
55
+ // cannot match on exact output, because linebreaks
56
+ expect(ctx.stdout).to.contain("The database mysql_xxxxxx");
57
+ expect(ctx.stdout).to.contain("the user dbu_xxxxxx");
58
+ });
59
+ test
60
+ .nock("https://api.mittwald.de", (api) => {
61
+ api.get(`/v2/projects/${projectId}`).reply(200, {
62
+ id: projectId,
63
+ });
64
+ api
65
+ .post(`/v2/projects/${projectId}/mysql-databases`, {
66
+ database: {
67
+ projectId,
68
+ description: "Test",
69
+ version: "8.0",
70
+ characterSettings: {
71
+ collation: "utf8mb4_unicode_ci",
72
+ characterSet: "utf8mb4",
73
+ },
74
+ },
75
+ user: {
76
+ password: "secret",
77
+ externalAccess: false,
78
+ accessLevel: "full",
79
+ },
80
+ })
81
+ .reply(201, { id: databaseId, userId });
82
+ api.get(`/v2/mysql-databases/${databaseId}`).reply(200, {
83
+ id: databaseId,
84
+ name: "mysql_xxxxxx",
85
+ });
86
+ api.get(`/v2/mysql-users/${userId}`).times(3).reply(403);
87
+ api.get(`/v2/mysql-users/${userId}`).reply(200, {
88
+ id: userId,
89
+ name: "dbu_xxxxxx",
90
+ });
91
+ })
92
+ .env({ MITTWALD_API_TOKEN: "foo" })
93
+ .stdout()
94
+ .command(createFlags)
95
+ .it("retries fetching user until successful", (ctx) => {
96
+ // cannot match on exact output, because linebreaks
97
+ expect(ctx.stdout).to.contain("The database mysql_xxxxxx");
98
+ expect(ctx.stdout).to.contain("the user dbu_xxxxxx");
99
+ });
100
+ });
@@ -8,7 +8,7 @@ export default class Delete extends DeleteBaseCommand {
8
8
  static flags = { ...DeleteBaseCommand.baseFlags };
9
9
  static args = { ...mysqlArgs };
10
10
  async deleteResource() {
11
- const mysqlDatabaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
11
+ const mysqlDatabaseId = await withMySQLId(this.apiClient, this.flags, this.args);
12
12
  const response = await this.apiClient.database.deleteMysqlDatabase({
13
13
  mysqlDatabaseId,
14
14
  });
@@ -43,7 +43,7 @@ export class Dump extends ExecRenderBaseCommand {
43
43
  };
44
44
  static args = { ...mysqlArgs };
45
45
  async exec() {
46
- const databaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
46
+ const databaseId = await withMySQLId(this.apiClient, this.flags, this.args);
47
47
  const p = makeProcessRenderer(this.flags, "Dumping a MySQL database");
48
48
  const connectionDetails = await getConnectionDetailsWithPassword(this.apiClient, databaseId, p, this.flags);
49
49
  if (this.flags["temporary-user"]) {
@@ -7,7 +7,7 @@ export class Get extends GetBaseCommand {
7
7
  };
8
8
  static args = { ...mysqlArgs };
9
9
  async getData() {
10
- const mysqlDatabaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
10
+ const mysqlDatabaseId = await withMySQLId(this.apiClient, this.flags, this.args);
11
11
  return await this.apiClient.database.getMysqlDatabase({
12
12
  mysqlDatabaseId,
13
13
  });
@@ -7,7 +7,7 @@ export class PhpMyAdmin extends BaseCommand {
7
7
  static args = { ...mysqlArgs };
8
8
  async run() {
9
9
  const { flags, args } = await this.parse(PhpMyAdmin);
10
- const databaseId = await withMySQLId(this.apiClient, flags, args, this.config);
10
+ const databaseId = await withMySQLId(this.apiClient, flags, args);
11
11
  const users = await this.apiClient.database.listMysqlUsers({
12
12
  mysqlDatabaseId: databaseId,
13
13
  });
@@ -20,7 +20,7 @@ export class PortForward extends ExecRenderBaseCommand {
20
20
  };
21
21
  static args = { ...mysqlArgs };
22
22
  async exec() {
23
- const databaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
23
+ const databaseId = await withMySQLId(this.apiClient, this.flags, this.args);
24
24
  const p = makeProcessRenderer(this.flags, "Port-forwarding a MySQL database");
25
25
  const { sshUser, sshHost, hostname, database } = await getConnectionDetails(this.apiClient, databaseId, this.flags["ssh-user"], p);
26
26
  const { port } = this.flags;
@@ -13,7 +13,7 @@ export class Shell extends ExecRenderBaseCommand {
13
13
  };
14
14
  static args = { ...mysqlArgs };
15
15
  async exec() {
16
- const databaseId = await withMySQLId(this.apiClient, this.flags, this.args, this.config);
16
+ const databaseId = await withMySQLId(this.apiClient, this.flags, this.args);
17
17
  const p = makeProcessRenderer(this.flags, "Starting a MySQL shell");
18
18
  const { sshUser, sshHost, user, hostname, database, password } = await getConnectionDetailsWithPassword(this.apiClient, databaseId, p, this.flags);
19
19
  p.complete(_jsx(Text, { children: "Starting MySQL shell -- get ready..." }));
@@ -35,7 +35,6 @@ export default class Create extends ExecRenderBaseCommand {
35
35
  data: { description },
36
36
  });
37
37
  assertStatus(result, 201);
38
- const eventId = result.headers["etag"];
39
38
  stepCreating.complete();
40
39
  process.addInfo(_jsxs(Text, { children: ["project ID: ", _jsx(Value, { children: result.data.id })] }));
41
40
  if (flags.wait) {
@@ -43,7 +42,6 @@ export default class Create extends ExecRenderBaseCommand {
43
42
  await waitUntil(async () => {
44
43
  const projectResponse = await this.apiClient.project.getProject({
45
44
  projectId: result.data.id,
46
- headers: { "if-event-reached": eventId },
47
45
  });
48
46
  if (projectResponse.status === 200 &&
49
47
  projectResponse.data.readiness === "ready") {
@@ -0,0 +1,2 @@
1
+ import { AxiosInstance } from "@mittwald/api-client-commons";
2
+ export declare function configureConsistencyHandling(axios: AxiosInstance): void;
@@ -0,0 +1,21 @@
1
+ import debug from "debug";
2
+ const d = debug("mw:api-consistency");
3
+ export function configureConsistencyHandling(axios) {
4
+ let lastEventId = undefined;
5
+ axios.interceptors.request.use((config) => {
6
+ if (lastEventId !== undefined) {
7
+ d("setting if-event-reached to %o", lastEventId);
8
+ config.headers["if-event-reached"] = lastEventId;
9
+ }
10
+ return config;
11
+ });
12
+ axios.interceptors.response.use((response) => {
13
+ const isMutatingRequest = ["post", "put", "delete", "patch"].indexOf(response.config?.method?.toLowerCase() ?? "") >= 0;
14
+ const headers = response.headers;
15
+ if (headers.has("etag") && isMutatingRequest) {
16
+ d("setting last event id to %o after mutating request", headers.get("etag"));
17
+ lastEventId = headers.get("etag");
18
+ }
19
+ return response;
20
+ });
21
+ }
@@ -0,0 +1,2 @@
1
+ import { AxiosInstance } from "@mittwald/api-client-commons";
2
+ export declare function configureAxiosRetry(axios: AxiosInstance): void;
@@ -0,0 +1,29 @@
1
+ import debug from "debug";
2
+ import axiosRetry from "axios-retry";
3
+ const d = debug("mw:api-retry");
4
+ export function configureAxiosRetry(axios) {
5
+ axios.interceptors.request.use((config) => {
6
+ return {
7
+ ...config,
8
+ validateStatus: (status) => status < 300,
9
+ };
10
+ });
11
+ axiosRetry(axios, {
12
+ retries: 10,
13
+ retryDelay: axiosRetry.exponentialDelay,
14
+ onRetry(count, error) {
15
+ d("retrying request after %d attempts; error: %o", count, error.message);
16
+ },
17
+ retryCondition(error) {
18
+ if (error.code === "ERR_FR_TOO_MANY_REDIRECTS") {
19
+ return false;
20
+ }
21
+ if (axiosRetry.isNetworkOrIdempotentRequestError(error)) {
22
+ return true;
23
+ }
24
+ const isSafeRequest = error.config?.method?.toLowerCase() === "get";
25
+ const isAccessDenied = error.response?.status === 403;
26
+ return isSafeRequest && isAccessDenied;
27
+ },
28
+ });
29
+ }
@@ -33,10 +33,10 @@ export class AppInstaller {
33
33
  const projectId = await withProjectId(apiClient, "flag", flags, args, config);
34
34
  await autofillFlags(apiClient, process, this.appSupportedFlags, flags, projectId, this.appName);
35
35
  const appVersion = await normalizeToAppVersionUuid(apiClient, "version" in flags ? flags.version : "latest", process, this.appId);
36
- const [appInstallationId, eventId] = await triggerAppInstallation(apiClient, process, projectId, flags, appVersion);
36
+ const appInstallationId = await triggerAppInstallation(apiClient, process, projectId, flags, appVersion);
37
37
  let successText;
38
38
  if (flags.wait) {
39
- await waitUntilAppIsInstalled(apiClient, process, appInstallationId, eventId);
39
+ await waitUntilAppIsInstalled(apiClient, process, appInstallationId);
40
40
  successText = `Your ${this.appName} installation is now complete. Have fun! 🎉`;
41
41
  }
42
42
  else {
@@ -1,5 +1,5 @@
1
1
  import { MittwaldAPIV2, MittwaldAPIV2Client } from "@mittwald/api-client";
2
2
  import { ProcessRenderer } from "../../rendering/process/process.js";
3
3
  type AppAppVersion = MittwaldAPIV2.Components.Schemas.AppAppVersion;
4
- export declare function triggerAppInstallation(apiClient: MittwaldAPIV2Client, process: ProcessRenderer, projectId: string, flags: Record<string, string>, appVersion: AppAppVersion): Promise<string[]>;
4
+ export declare function triggerAppInstallation(apiClient: MittwaldAPIV2Client, process: ProcessRenderer, projectId: string, flags: Record<string, string>, appVersion: AppAppVersion): Promise<string>;
5
5
  export {};
@@ -1,6 +1,6 @@
1
1
  import { assertStatus } from "@mittwald/api-client-commons";
2
2
  export async function triggerAppInstallation(apiClient, process, projectId, flags, appVersion) {
3
- const [appInstallationId, eventId] = await process.runStep("starting installation", async () => {
3
+ const appInstallationId = await process.runStep("starting installation", async () => {
4
4
  const result = await apiClient.app.requestAppinstallation({
5
5
  projectId,
6
6
  data: {
@@ -14,7 +14,7 @@ export async function triggerAppInstallation(apiClient, process, projectId, flag
14
14
  },
15
15
  });
16
16
  assertStatus(result, 201);
17
- return [result.data.id, result.headers["etag"]];
17
+ return result.data.id;
18
18
  });
19
19
  await process.runStep("waiting for installation to be retrievable", async () => {
20
20
  for (let attempts = 0; attempts < 10; attempts++) {
@@ -31,7 +31,6 @@ export async function triggerAppInstallation(apiClient, process, projectId, flag
31
31
  await process.runStep("setting document root", async () => {
32
32
  const result = await apiClient.app.patchAppinstallation({
33
33
  appInstallationId,
34
- headers: { "if-event-reached": eventId },
35
34
  data: {
36
35
  customDocumentRoot: flags["document-root"],
37
36
  },
@@ -39,5 +38,5 @@ export async function triggerAppInstallation(apiClient, process, projectId, flag
39
38
  assertStatus(result, 204);
40
39
  });
41
40
  }
42
- return [appInstallationId, eventId];
41
+ return appInstallationId;
43
42
  }
@@ -1,3 +1,3 @@
1
1
  import { MittwaldAPIV2Client } from "@mittwald/api-client";
2
2
  import { ProcessRenderer } from "../../rendering/process/process.js";
3
- export declare function waitUntilAppIsInstalled(apiClient: MittwaldAPIV2Client, process: ProcessRenderer, appInstallationId: string, eventId: string): Promise<void>;
3
+ export declare function waitUntilAppIsInstalled(apiClient: MittwaldAPIV2Client, process: ProcessRenderer, appInstallationId: string): Promise<void>;
@@ -1,13 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { waitUntil } from "../wait.js";
3
3
  import { Text } from "ink";
4
- export async function waitUntilAppIsInstalled(apiClient, process, appInstallationId, eventId) {
4
+ export async function waitUntilAppIsInstalled(apiClient, process, appInstallationId) {
5
5
  const stepWaiting = process.addStep(_jsx(Text, { children: "waiting for app installation to be ready" }));
6
6
  await waitUntil(async () => {
7
7
  const installationResponse = await apiClient.app.getAppinstallation({
8
8
  appInstallationId,
9
- // TODO: Remove once @mittwald/api-client supports this
10
- headers: { "if-event-reached": eventId }, // eslint-disable-line
11
9
  });
12
10
  if (installationResponse.status === 200 &&
13
11
  installationResponse.data.appVersion.current ==
@@ -1,4 +1,3 @@
1
- import { Config } from "@oclif/core";
2
1
  import { MittwaldAPIV2Client } from "@mittwald/api-client";
3
2
  import { ArgOutput, FlagOutput } from "@oclif/core/lib/interfaces/parser.js";
4
3
  export declare const mysqlConnectionFlags: {
@@ -7,4 +6,4 @@ export declare const mysqlConnectionFlags: {
7
6
  export declare const mysqlArgs: {
8
7
  "database-id": import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
9
8
  };
10
- export declare function withMySQLId(apiClient: MittwaldAPIV2Client, flags: FlagOutput, args: ArgOutput, cfg: Config): Promise<string>;
9
+ export declare function withMySQLId(apiClient: MittwaldAPIV2Client, flags: FlagOutput, args: ArgOutput): Promise<string>;
@@ -1,6 +1,4 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
- import { isUuid } from "../../../normalize_id.js";
3
- import { withProjectId } from "../../project/flags.js";
4
2
  import { assertStatus } from "@mittwald/api-client-commons";
5
3
  export const mysqlConnectionFlags = {
6
4
  "mysql-password": Flags.string({
@@ -17,7 +15,7 @@ NOTE: This is a security risk, as the password will be visible in the process li
17
15
  };
18
16
  export const mysqlArgs = {
19
17
  "database-id": Args.string({
20
- description: "The ID of the database (when a project context is set, you can also use the name)",
18
+ description: "The ID or name of the database",
21
19
  required: true,
22
20
  }),
23
21
  };
@@ -30,19 +28,11 @@ function getIdCandidate(flags, args) {
30
28
  }
31
29
  throw new Error("No ID given");
32
30
  }
33
- export async function withMySQLId(apiClient, flags, args, cfg) {
34
- const candidate = getIdCandidate(flags, args);
35
- if (isUuid(candidate)) {
36
- return candidate;
37
- }
38
- const projectId = await withProjectId(apiClient, "flag", flags, args, cfg);
39
- const databases = await apiClient.database.listMysqlDatabases({
40
- projectId,
31
+ export async function withMySQLId(apiClient, flags, args) {
32
+ const mysqlDatabaseId = getIdCandidate(flags, args);
33
+ const response = await apiClient.database.getMysqlDatabase({
34
+ mysqlDatabaseId,
41
35
  });
42
- assertStatus(databases, 200);
43
- const database = databases.data.find((db) => db.name === candidate);
44
- if (!database) {
45
- throw new Error(`No database with name "${candidate}" found`);
46
- }
47
- return database.id;
36
+ assertStatus(response, 200);
37
+ return response.data.id;
48
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/cli",
3
- "version": "1.0.0-alpha.37",
3
+ "version": "1.0.0-alpha.38",
4
4
  "description": "Hand-crafted CLI for the mittwald API",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -32,25 +32,24 @@
32
32
  "post:generate": "yarn run -T compile && yarn run -T compile:cjs",
33
33
  "test": "yarn test:format && yarn test:licenses && yarn test:unit",
34
34
  "test:format": "yarn lint && yarn format --check",
35
- "test:unit": "mocha --forbid-only \"src/**/*.test.ts\"",
36
35
  "test:licenses": "yarn license-check --summary --unknown --failOn 'UNLICENSED;UNKNOWN'",
37
- "test:readme": "yarn generate:readme && git diff --exit-code README.md"
36
+ "test:readme": "yarn generate:readme && git diff --exit-code README.md",
37
+ "test:unit": "mocha --forbid-only \"src/**/*.test.ts\""
38
38
  },
39
39
  "files": [
40
40
  ".deps",
41
- "dist/**/*.{js,d.ts}",
42
- "bin"
41
+ "bin",
42
+ "dist/**/*.{js,d.ts}"
43
43
  ],
44
44
  "dependencies": {
45
45
  "@mittwald/api-client": "^4.9.0",
46
- "@mittwald/api-client-commons": "^4.2.2",
47
46
  "@mittwald/react-use-promise": "^2.1.2",
48
47
  "@oclif/core": "^3.18.1",
49
48
  "@oclif/plugin-autocomplete": "^3.0.3",
50
49
  "@oclif/plugin-help": "^6.0.5",
51
50
  "@oclif/plugin-update": "^4.1.3",
52
51
  "@oclif/plugin-warn-if-update-available": "^3.0.2",
53
- "axios": "^1.5.0",
52
+ "axios-retry": "^4.0.0",
54
53
  "chalk": "^5.3.0",
55
54
  "date-fns": "^3.2.0",
56
55
  "humanize-string": "^3.0.0",