@mittwald/cli 1.8.0 → 1.8.1
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.
|
@@ -12,6 +12,7 @@ import { waitUntilAppStateHasNormalized } from "../../lib/resources/app/wait.js"
|
|
|
12
12
|
import { assertStatus } from "@mittwald/api-client-commons";
|
|
13
13
|
import { waitFlags } from "../../lib/wait.js";
|
|
14
14
|
import semver from "semver";
|
|
15
|
+
import { validate as validateUuid } from "uuid";
|
|
15
16
|
export class UpgradeApp extends ExecRenderBaseCommand {
|
|
16
17
|
static description = "Upgrade app installation to target version";
|
|
17
18
|
static args = {
|
|
@@ -39,7 +40,8 @@ export class UpgradeApp extends ExecRenderBaseCommand {
|
|
|
39
40
|
ux.exit(1);
|
|
40
41
|
}
|
|
41
42
|
const currentAppVersion = await getAppVersionFromUuid(this.apiClient, currentApp.id, currentAppInstallation.appVersion.current);
|
|
42
|
-
if (targetAppVersionCandidates.length == 0
|
|
43
|
+
if (targetAppVersionCandidates.length == 0 &&
|
|
44
|
+
!validateUuid(this.flags["target-version"])) {
|
|
43
45
|
process.complete(_jsxs(Text, { children: ["Your ", currentApp.name, " ", currentAppVersion.externalVersion, " is already Up-To-Date. \u2705"] }));
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
@@ -121,6 +123,10 @@ export class UpgradeApp extends ExecRenderBaseCommand {
|
|
|
121
123
|
if (targetAppVersionString == "latest") {
|
|
122
124
|
return await getLatestAvailableTargetAppVersionForAppVersionUpgradeCandidates(this.apiClient, currentApp.id, currentAppVersion.id);
|
|
123
125
|
}
|
|
126
|
+
if (validateUuid(targetAppVersionString) &&
|
|
127
|
+
typeof targetAppVersionString === "string") {
|
|
128
|
+
return await getAppVersionFromUuid(this.apiClient, currentApp.id, targetAppVersionString);
|
|
129
|
+
}
|
|
124
130
|
if (targetAppVersionString) {
|
|
125
131
|
const exactVersionMatch = targetAppVersionCandidates.find((v) => v.externalVersion === targetAppVersionString);
|
|
126
132
|
if (exactVersionMatch) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RenderBaseCommand } from "../../lib/basecommands/RenderBaseCommand.js";
|
|
2
|
+
import React from "react";
|
|
3
|
+
export declare class VersionInfo extends RenderBaseCommand<typeof VersionInfo> {
|
|
4
|
+
static description: string;
|
|
5
|
+
static summary: string;
|
|
6
|
+
static args: {
|
|
7
|
+
app: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
version: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
9
|
+
};
|
|
10
|
+
protected render(): React.ReactNode;
|
|
11
|
+
private getAppVersion;
|
|
12
|
+
private getApp;
|
|
13
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { RenderBaseCommand } from "../../lib/basecommands/RenderBaseCommand.js";
|
|
3
|
+
import { Args } from "@oclif/core";
|
|
4
|
+
import { assertStatus } from "@mittwald/api-client";
|
|
5
|
+
import { usePromise } from "@mittwald/react-use-promise";
|
|
6
|
+
import { Box, Text } from "ink";
|
|
7
|
+
import { SingleResult, SingleResultTable, } from "../../rendering/react/components/SingleResult.js";
|
|
8
|
+
import { Value } from "../../rendering/react/components/Value.js";
|
|
9
|
+
export class VersionInfo extends RenderBaseCommand {
|
|
10
|
+
static description = "show information about specific app versions";
|
|
11
|
+
static summary = "This command shows information about a specific app version. It is useful to get information about the user inputs that are required for the version to be deployed successfully.";
|
|
12
|
+
static args = {
|
|
13
|
+
app: Args.string({
|
|
14
|
+
description: "name of the app",
|
|
15
|
+
required: true,
|
|
16
|
+
}),
|
|
17
|
+
version: Args.string({
|
|
18
|
+
description: "version of the app",
|
|
19
|
+
required: true,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
render() {
|
|
23
|
+
const { app, version } = this.args;
|
|
24
|
+
const appData = usePromise(this.getApp.bind(this), [app]);
|
|
25
|
+
const appVersionData = usePromise(this.getAppVersion.bind(this), [
|
|
26
|
+
appData,
|
|
27
|
+
version,
|
|
28
|
+
]);
|
|
29
|
+
const sections = [
|
|
30
|
+
_jsx(AppVersionDetails, { app: appData, appVersion: appVersionData }, "details"),
|
|
31
|
+
];
|
|
32
|
+
if (appVersionData.userInputs) {
|
|
33
|
+
sections.push(_jsx(UserInputTable, { appVersion: appVersionData }, "inputs"));
|
|
34
|
+
}
|
|
35
|
+
return (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: sections }));
|
|
36
|
+
}
|
|
37
|
+
async getAppVersion(app, versionName) {
|
|
38
|
+
const appVersions = await this.apiClient.app.listAppversions({
|
|
39
|
+
appId: app.id,
|
|
40
|
+
});
|
|
41
|
+
assertStatus(appVersions, 200);
|
|
42
|
+
const version = appVersions.data.find((v) => v.externalVersion === versionName);
|
|
43
|
+
if (!version) {
|
|
44
|
+
throw new Error(`version ${this.args.version} not found`);
|
|
45
|
+
}
|
|
46
|
+
return version;
|
|
47
|
+
}
|
|
48
|
+
async getApp(appName) {
|
|
49
|
+
const appResult = await this.apiClient.app.listApps();
|
|
50
|
+
assertStatus(appResult, 200);
|
|
51
|
+
const app = appResult.data.find((a) => a.name.toLowerCase() === appName.toLowerCase());
|
|
52
|
+
if (!app) {
|
|
53
|
+
throw new Error(`app ${appName} not found`);
|
|
54
|
+
}
|
|
55
|
+
return app;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function UserInputValue({ input }) {
|
|
59
|
+
return (_jsxs(Text, { children: ["type=", _jsx(Value, { children: input.dataType }), input.defaultValue && (_jsxs(_Fragment, { children: [" ", "default=", _jsx(Value, { children: input.defaultValue })] }))] }));
|
|
60
|
+
}
|
|
61
|
+
function UserInputTable({ appVersion }) {
|
|
62
|
+
return (_jsx(SingleResult, { title: "USER INPUTS", rows: Object.fromEntries((appVersion.userInputs ?? []).map((u) => [
|
|
63
|
+
u.name,
|
|
64
|
+
_jsx(UserInputValue, { input: u }),
|
|
65
|
+
])) }, "inputs"));
|
|
66
|
+
}
|
|
67
|
+
function AppVersionDetails({ app, appVersion, }) {
|
|
68
|
+
return (_jsx(SingleResult, { title: "APP VERSION DETAILS", rows: {
|
|
69
|
+
App: (_jsx(SingleResultTable, { rows: {
|
|
70
|
+
UID: _jsx(Value, { children: app.id }),
|
|
71
|
+
Name: _jsx(Value, { children: app.name }),
|
|
72
|
+
} })),
|
|
73
|
+
Version: (_jsx(SingleResultTable, { rows: {
|
|
74
|
+
UID: _jsx(Value, { children: appVersion.id }),
|
|
75
|
+
Version: _jsx(Value, { children: appVersion.externalVersion }),
|
|
76
|
+
} })),
|
|
77
|
+
} }, "details"));
|
|
78
|
+
}
|
|
@@ -45,7 +45,7 @@ export class PortForward extends ExecRenderBaseCommand {
|
|
|
45
45
|
.map((p) => ["-L", `${p.localPort}:localhost:${p.remotePort}`])
|
|
46
46
|
.flat(),
|
|
47
47
|
});
|
|
48
|
-
cp.spawnSync("ssh", [...sshArgs, "
|
|
48
|
+
cp.spawnSync("ssh", [...sshArgs, "sleep", "infinity"], {
|
|
49
49
|
stdio: ["ignore", process.stdout, process.stderr],
|
|
50
50
|
});
|
|
51
51
|
return {};
|
|
@@ -33,7 +33,7 @@ export class PortForward extends ExecRenderBaseCommand {
|
|
|
33
33
|
interactive: false,
|
|
34
34
|
additionalFlags: ["-L", `${port}:${hostname}:3306`],
|
|
35
35
|
});
|
|
36
|
-
cp.spawnSync("ssh", [...sshArgs, "
|
|
36
|
+
cp.spawnSync("ssh", [...sshArgs, "sleep", "infinity"], {
|
|
37
37
|
stdio: ["ignore", process.stdout, process.stderr],
|
|
38
38
|
});
|
|
39
39
|
return {};
|