@mittwald/cli 1.10.0 → 1.11.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.
Files changed (106) hide show
  1. package/bin/run.js +4 -1
  2. package/dist/commands/app/create/node.d.ts +1 -3
  3. package/dist/commands/app/create/php-worker.d.ts +1 -3
  4. package/dist/commands/app/create/php.d.ts +1 -3
  5. package/dist/commands/app/create/python.d.ts +1 -3
  6. package/dist/commands/app/create/static.d.ts +1 -3
  7. package/dist/commands/app/dependency/update.js +2 -4
  8. package/dist/commands/app/install/contao.d.ts +1 -3
  9. package/dist/commands/app/install/joomla.d.ts +1 -3
  10. package/dist/commands/app/install/matomo.d.ts +1 -3
  11. package/dist/commands/app/install/nextcloud.d.ts +1 -3
  12. package/dist/commands/app/install/shopware5.d.ts +1 -3
  13. package/dist/commands/app/install/shopware6.d.ts +1 -3
  14. package/dist/commands/app/install/typo3.d.ts +1 -3
  15. package/dist/commands/app/install/wordpress.d.ts +1 -3
  16. package/dist/commands/app/ssh.d.ts +1 -0
  17. package/dist/commands/app/ssh.js +15 -1
  18. package/dist/commands/app/update.js +4 -8
  19. package/dist/commands/app/upgrade.js +9 -9
  20. package/dist/commands/backup/create.js +1 -2
  21. package/dist/commands/backup/download.js +4 -5
  22. package/dist/commands/container/run.d.ts +4 -2
  23. package/dist/commands/container/run.js +7 -6
  24. package/dist/commands/database/mysql/create.js +1 -2
  25. package/dist/commands/database/mysql/dump.js +1 -2
  26. package/dist/commands/database/mysql/import.js +1 -2
  27. package/dist/commands/ddev/init.js +2 -6
  28. package/dist/commands/extension/install.js +1 -3
  29. package/dist/commands/login/reset.js +1 -2
  30. package/dist/commands/mail/address/create.js +1 -4
  31. package/dist/commands/mail/deliverybox/create.js +1 -4
  32. package/dist/commands/project/create.js +4 -6
  33. package/dist/commands/registry/create.js +1 -2
  34. package/dist/commands/registry/update.js +1 -2
  35. package/dist/commands/user/api-token/create.js +1 -1
  36. package/dist/commands/user/ssh-key/create.js +3 -8
  37. package/dist/commands/user/ssh-key/import.js +2 -3
  38. package/dist/lib/basecommands/DeleteBaseCommand.js +4 -4
  39. package/dist/lib/ddev/init_assert.js +1 -6
  40. package/dist/lib/ddev/init_database.js +1 -7
  41. package/dist/lib/ddev/init_projecttype.js +2 -11
  42. package/dist/lib/intellij/config.d.ts +5 -0
  43. package/dist/lib/intellij/config.js +295 -0
  44. package/dist/lib/intellij/config.test.d.ts +1 -0
  45. package/dist/lib/intellij/config.test.js +262 -0
  46. package/dist/lib/intellij/config_xml_types.d.ts +72 -0
  47. package/dist/lib/intellij/config_xml_types.js +2 -0
  48. package/dist/lib/resources/app/Installer.d.ts +6 -2
  49. package/dist/lib/resources/app/Installer.js +13 -6
  50. package/dist/lib/resources/app/flags.js +9 -12
  51. package/dist/lib/resources/app/install.d.ts +2 -1
  52. package/dist/lib/resources/app/install.js +3 -1
  53. package/dist/lib/resources/app/versions.js +1 -4
  54. package/dist/lib/resources/app/wait.js +1 -3
  55. package/dist/lib/resources/mail/commons.js +1 -4
  56. package/dist/lib/resources/ssh/appinstall.d.ts +3 -1
  57. package/dist/lib/resources/ssh/appinstall.js +1 -0
  58. package/dist/lib/resources/stack/enrich.js +9 -2
  59. package/dist/lib/resources/stack/enrich.test.d.ts +1 -0
  60. package/dist/lib/resources/stack/enrich.test.js +167 -0
  61. package/dist/lib/resources/stack/types.d.ts +1 -1
  62. package/dist/rendering/process/components/ProcessStateIcon.js +1 -1
  63. package/dist/rendering/process/process.d.ts +16 -16
  64. package/dist/rendering/process/process_exec.d.ts +1 -2
  65. package/dist/rendering/process/process_fancy.d.ts +9 -9
  66. package/dist/rendering/process/process_flags.js +4 -0
  67. package/dist/rendering/process/process_quiet.d.ts +3 -4
  68. package/dist/rendering/process/process_simple.d.ts +26 -0
  69. package/dist/rendering/process/process_simple.js +143 -0
  70. package/dist/rendering/process/process_simple.test.d.ts +1 -0
  71. package/dist/rendering/process/process_simple.test.js +149 -0
  72. package/dist/rendering/react/components/AppInstallation/AppBackendAccessHints.d.ts +15 -0
  73. package/dist/rendering/react/components/AppInstallation/AppBackendAccessHints.js +13 -0
  74. package/dist/rendering/react/components/AppInstallation/AppDomainConnectionHints.d.ts +12 -0
  75. package/dist/rendering/react/components/AppInstallation/AppDomainConnectionHints.js +21 -0
  76. package/dist/rendering/react/components/AppInstallation/AppManagementCommands.d.ts +12 -0
  77. package/dist/rendering/react/components/AppInstallation/AppManagementCommands.js +17 -0
  78. package/dist/rendering/react/components/AppInstallation/AppUsageHints.d.ts +17 -0
  79. package/dist/rendering/react/components/AppInstallation/AppUsageHints.js +23 -0
  80. package/dist/rendering/react/components/Container/CommandHint.d.ts +14 -0
  81. package/dist/rendering/react/components/Container/CommandHint.js +13 -0
  82. package/dist/rendering/react/components/Container/ContainerManagementCommands.d.ts +22 -0
  83. package/dist/rendering/react/components/Container/ContainerManagementCommands.js +23 -0
  84. package/dist/rendering/react/components/Container/ContainerUsageHints.d.ts +12 -0
  85. package/dist/rendering/react/components/Container/ContainerUsageHints.js +35 -0
  86. package/dist/rendering/react/components/Container/DomainConnectionHints.d.ts +12 -0
  87. package/dist/rendering/react/components/Container/DomainConnectionHints.js +21 -0
  88. package/dist/rendering/react/components/Container/InternalConnectionHints.d.ts +12 -0
  89. package/dist/rendering/react/components/Container/InternalConnectionHints.js +12 -0
  90. package/dist/rendering/react/components/Container/NoPortsUsageHints.d.ts +12 -0
  91. package/dist/rendering/react/components/Container/NoPortsUsageHints.js +12 -0
  92. package/dist/rendering/react/components/Container/PortConnectionHints.d.ts +13 -0
  93. package/dist/rendering/react/components/Container/PortConnectionHints.js +11 -0
  94. package/dist/rendering/react/components/Container/PortForwardingHints.d.ts +12 -0
  95. package/dist/rendering/react/components/Container/PortForwardingHints.js +18 -0
  96. package/dist/rendering/react/components/Container/types.d.ts +4 -0
  97. package/dist/rendering/react/components/Container/types.js +1 -0
  98. package/dist/rendering/react/components/Error/ErrorBox.d.ts +1 -1
  99. package/dist/rendering/react/components/Error/ErrorBox.js +3 -4
  100. package/dist/rendering/react/components/Error/GenericError.js +1 -1
  101. package/dist/rendering/react/components/ErrorBoundary.d.ts +1 -1
  102. package/dist/rendering/react/components/Success.d.ts +0 -1
  103. package/dist/rendering/react/components/Success.js +4 -2
  104. package/dist/rendering/react/styles/useDefaultBoxStyles.d.ts +11 -0
  105. package/dist/rendering/react/styles/useDefaultBoxStyles.js +23 -0
  106. package/package.json +7 -6
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ const infoColor = "blueBright";
5
+ /**
6
+ * AppBackendAccessHints displays backend/admin access information when a
7
+ * backendPathTemplate is available in the app version.
8
+ */
9
+ export const AppBackendAccessHints = ({ backendPathTemplate, appName, appHost, }) => {
10
+ return (_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: infoColor, children: "\uD83D\uDD27 Backend Access:" }), _jsx(Text, { color: "gray", children: appHost
11
+ ? `Your ${appName} backend is available at:`
12
+ : `Once you connect a domain, your ${appName} backend will be available at:` }), _jsx(Text, { color: "gray", children: _jsx(Value, { children: backendPathTemplate.replace("{domain}", appHost ?? "<your-domain>") }) })] }));
13
+ };
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import type { MittwaldAPIV2 } from "@mittwald/api-client";
3
+ type AppInstallation = MittwaldAPIV2.Components.Schemas.AppAppInstallation;
4
+ interface AppDomainConnectionHintsProps {
5
+ appInstallation: AppInstallation;
6
+ }
7
+ /**
8
+ * AppDomainConnectionHints displays instructions for connecting a domain to an
9
+ * app installation via virtualhost creation.
10
+ */
11
+ export declare const AppDomainConnectionHints: FC<AppDomainConnectionHintsProps>;
12
+ export {};
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ import { CommandHint } from "../Container/CommandHint.js";
5
+ const infoColor = "blueBright";
6
+ /**
7
+ * AppDomainConnectionHints displays instructions for connecting a domain to an
8
+ * app installation via virtualhost creation.
9
+ */
10
+ export const AppDomainConnectionHints = ({ appInstallation, }) => {
11
+ return (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: infoColor, children: "\uD83C\uDF10 Connect via Domain:" }), _jsx(CommandHint, { command: [
12
+ "mw",
13
+ "domain",
14
+ "virtualhost",
15
+ "create",
16
+ "--hostname",
17
+ "<your-domain.com>",
18
+ "--path-to-installation",
19
+ `/:${appInstallation.id}`,
20
+ ], description: _jsxs(_Fragment, { children: ["Connect ", _jsx(Value, { children: "<your-domain.com>" }), " to your app installation, making it accessible via HTTPS. This is required for external access to your application."] }) })] }));
21
+ };
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import type { MittwaldAPIV2 } from "@mittwald/api-client";
3
+ type AppInstallation = MittwaldAPIV2.Components.Schemas.AppAppInstallation;
4
+ interface AppManagementCommandsProps {
5
+ appInstallation: AppInstallation;
6
+ }
7
+ /**
8
+ * AppManagementCommands displays management commands for app installations
9
+ * including SSH access, file operations, and maintenance tasks.
10
+ */
11
+ export declare const AppManagementCommands: FC<AppManagementCommandsProps>;
12
+ export {};
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { CommandHint } from "../Container/CommandHint.js";
4
+ const infoColor = "blueBright";
5
+ /**
6
+ * AppManagementCommands displays management commands for app installations
7
+ * including SSH access, file operations, and maintenance tasks.
8
+ */
9
+ export const AppManagementCommands = ({ appInstallation, }) => {
10
+ return (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: infoColor, children: "\uD83D\uDD27 Manage your application:" }), _jsx(CommandHint, { command: ["mw", "app", "ssh", appInstallation.shortId], description: "Open SSH session to your app installation" }), _jsx(CommandHint, { command: ["mw", "app", "download", appInstallation.shortId], description: "Download app files to your local machine" }), _jsx(CommandHint, { command: [
11
+ "mw",
12
+ "app",
13
+ "upload",
14
+ appInstallation.shortId,
15
+ "<local-file>",
16
+ ], description: "Upload files from your local machine to the app" }), _jsx(CommandHint, { command: ["mw", "app", "get", appInstallation.shortId], description: "Show detailed information about your app installation" })] }));
17
+ };
@@ -0,0 +1,17 @@
1
+ import { FC } from "react";
2
+ import type { MittwaldAPIV2 } from "@mittwald/api-client";
3
+ type AppInstallation = MittwaldAPIV2.Components.Schemas.AppAppInstallation;
4
+ type AppVersion = MittwaldAPIV2.Components.Schemas.AppAppVersion;
5
+ interface AppUsageHintsProps {
6
+ appInstallation: AppInstallation;
7
+ appVersion: AppVersion;
8
+ appName: string;
9
+ appHost?: string;
10
+ }
11
+ /**
12
+ * AppUsageHints displays comprehensive usage instructions for app
13
+ * installations, including domain connection setup and backend access
14
+ * information.
15
+ */
16
+ declare const AppUsageHints: FC<AppUsageHintsProps>;
17
+ export default AppUsageHints;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ import useDefaultBoxStyles from "../../styles/useDefaultBoxStyles.js";
5
+ import { AppDomainConnectionHints } from "./AppDomainConnectionHints.js";
6
+ import { AppBackendAccessHints } from "./AppBackendAccessHints.js";
7
+ import { AppManagementCommands } from "./AppManagementCommands.js";
8
+ const infoColor = "blueBright";
9
+ /**
10
+ * AppUsageHints displays comprehensive usage instructions for app
11
+ * installations, including domain connection setup and backend access
12
+ * information.
13
+ */
14
+ const AppUsageHints = ({ appInstallation, appVersion, appName, appHost, }) => {
15
+ const defaultBoxStyles = useDefaultBoxStyles();
16
+ const boxProps = {
17
+ ...defaultBoxStyles,
18
+ borderColor: infoColor,
19
+ marginLeft: 2,
20
+ };
21
+ return (_jsxs(Box, { ...boxProps, flexDirection: "column", children: [_jsx(Text, { bold: true, underline: true, color: infoColor, children: "USAGE HINTS" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Connect to your application using these methods:" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(AppDomainConnectionHints, { appInstallation: appInstallation }), appVersion.backendPathTemplate && (_jsx(AppBackendAccessHints, { appInstallation: appInstallation, backendPathTemplate: appVersion.backendPathTemplate, appName: appName, appHost: appHost })), _jsx(AppManagementCommands, { appInstallation: appInstallation }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: infoColor, children: ["\uD83D\uDCA1 Tip: Use ", _jsx(Value, { children: "mw app list" }), " to see all your app installations and their current status."] }) })] })] }));
22
+ };
23
+ export default AppUsageHints;
@@ -0,0 +1,14 @@
1
+ import { FC, ReactNode } from "react";
2
+ export interface CommandHintProps {
3
+ command: string[];
4
+ description: ReactNode;
5
+ }
6
+ /**
7
+ * CommandHint is a functional React component that renders a command hint
8
+ * display. It presents a styled command and its corresponding description.
9
+ *
10
+ * @param command An array of strings representing the command to be displayed.
11
+ * @param description A textual description of the command.
12
+ * @returns A JSX element displaying the command and description.
13
+ */
14
+ export declare const CommandHint: FC<CommandHintProps>;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ /**
4
+ * CommandHint is a functional React component that renders a command hint
5
+ * display. It presents a styled command and its corresponding description.
6
+ *
7
+ * @param command An array of strings representing the command to be displayed.
8
+ * @param description A textual description of the command.
9
+ * @returns A JSX element displaying the command and description.
10
+ */
11
+ export const CommandHint = ({ command, description }) => {
12
+ return (_jsxs(_Fragment, { children: [_jsx(Box, { children: _jsx(Text, { color: "yellow", children: command.join(" ") }) }), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsx(Text, { wrap: "wrap", children: description }) })] }));
13
+ };
@@ -0,0 +1,22 @@
1
+ import { FC } from "react";
2
+ interface ContainerManagementCommandsProps {
3
+ containerIdentifier: string;
4
+ }
5
+ /**
6
+ * ContainerManagementCommands is a React functional component that provides
7
+ * commands and instructions for interacting with a specific container.
8
+ *
9
+ * This component displays a set of command hints, allowing users to:
10
+ *
11
+ * - Connect to a container via SSH.
12
+ * - View logs generated by the container.
13
+ * - Execute specific commands within the container.
14
+ *
15
+ * The displayed commands are dynamically generated based on the
16
+ * `containerIdentifier` prop, which identifies the container to manage.
17
+ *
18
+ * @property string ContainerIdentifier - The unique identifier of the container
19
+ * to manage. This is included in the commands displayed by the component.
20
+ */
21
+ export declare const ContainerManagementCommands: FC<ContainerManagementCommandsProps>;
22
+ export {};
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { CommandHint } from "./CommandHint.js";
4
+ const infoColor = "blueBright";
5
+ /**
6
+ * ContainerManagementCommands is a React functional component that provides
7
+ * commands and instructions for interacting with a specific container.
8
+ *
9
+ * This component displays a set of command hints, allowing users to:
10
+ *
11
+ * - Connect to a container via SSH.
12
+ * - View logs generated by the container.
13
+ * - Execute specific commands within the container.
14
+ *
15
+ * The displayed commands are dynamically generated based on the
16
+ * `containerIdentifier` prop, which identifies the container to manage.
17
+ *
18
+ * @property string ContainerIdentifier - The unique identifier of the container
19
+ * to manage. This is included in the commands displayed by the component.
20
+ */
21
+ export const ContainerManagementCommands = ({ containerIdentifier }) => {
22
+ return (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, color: infoColor, children: "\uD83D\uDD27 Manage Your Container:" }) }), _jsx(CommandHint, { command: ["mw", "container", "ssh", containerIdentifier], description: "Connect to the container via SSH to run commands interactively" }), _jsx(CommandHint, { command: ["mw", "container", "logs", containerIdentifier], description: "View the container's log output and monitor its activity" }), _jsx(CommandHint, { command: ["mw", "container", "exec", containerIdentifier, "<command>"], description: "Execute a specific command inside the running container" })] }));
23
+ };
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import type { MittwaldAPIV2 } from "@mittwald/api-client";
3
+ type ContainerServiceResponse = MittwaldAPIV2.Components.Schemas.ContainerServiceResponse;
4
+ interface ContainerUsageHintsProps {
5
+ service: ContainerServiceResponse;
6
+ }
7
+ /**
8
+ * ContainerUsageHints displays comprehensive usage instructions for containers,
9
+ * adapting the content based on whether the container exposes ports or not.
10
+ */
11
+ declare const ContainerUsageHints: FC<ContainerUsageHintsProps>;
12
+ export default ContainerUsageHints;
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ import useDefaultBoxStyles from "../../styles/useDefaultBoxStyles.js";
5
+ import { ContainerManagementCommands } from "./ContainerManagementCommands.js";
6
+ import { NoPortsUsageHints } from "./NoPortsUsageHints.js";
7
+ import { PortConnectionHints } from "./PortConnectionHints.js";
8
+ const infoColor = "blueBright";
9
+ const parsePort = (portString) => {
10
+ const [port, protocol] = portString.split("/");
11
+ return { port, protocol };
12
+ };
13
+ /**
14
+ * ContainerUsageHints displays comprehensive usage instructions for containers,
15
+ * adapting the content based on whether the container exposes ports or not.
16
+ */
17
+ const ContainerUsageHints = ({ service }) => {
18
+ const defaultBoxStyles = useDefaultBoxStyles();
19
+ const rawPorts = service.deployedState?.ports || [];
20
+ const ports = rawPorts.map(parsePort);
21
+ const containerId = service.id;
22
+ const containerName = service.serviceName;
23
+ const boxProps = {
24
+ ...defaultBoxStyles,
25
+ borderColor: infoColor,
26
+ marginLeft: 2,
27
+ };
28
+ // Handle containers without exposed ports
29
+ if (ports.length === 0) {
30
+ return (_jsx(NoPortsUsageHints, { boxProps: boxProps, containerName: containerName }));
31
+ }
32
+ // Handle containers with exposed ports
33
+ return (_jsxs(Box, { ...boxProps, flexDirection: "column", children: [_jsx(Text, { bold: true, underline: true, color: infoColor, children: "USAGE HINTS" }), _jsxs(Text, { color: infoColor, children: ["Container ", _jsx(Value, { children: containerName }), " is now running and listening on", " ", ports.length === 1 ? "port" : "ports", ":", " ", ports.map((port, index) => (_jsxs(Value, { children: [port.port, "/", port.protocol, index < ports.length - 1 ? ", " : ""] }, index))), "! \uD83D\uDC33"] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Connect to your container using one of these methods:" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(PortConnectionHints, { ports: ports, containerId: containerId, containerName: containerName }), _jsx(ContainerManagementCommands, { containerIdentifier: containerName }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: infoColor, children: ["\uD83D\uDCA1 Tip: Use ", _jsx(Value, { children: "mw container list" }), " to see all your containers and their current status."] }) })] })] }));
34
+ };
35
+ export default ContainerUsageHints;
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import { ParsedPort } from "./types.js";
3
+ interface DomainConnectionHintsProps {
4
+ ports: ParsedPort[];
5
+ containerId: string;
6
+ }
7
+ /**
8
+ * DomainConnectionHints displays instructions for connecting a domain to
9
+ * container ports via virtualhost creation.
10
+ */
11
+ export declare const DomainConnectionHints: FC<DomainConnectionHintsProps>;
12
+ export {};
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ import { CommandHint } from "./CommandHint.js";
5
+ const infoColor = "blueBright";
6
+ /**
7
+ * DomainConnectionHints displays instructions for connecting a domain to
8
+ * container ports via virtualhost creation.
9
+ */
10
+ export const DomainConnectionHints = ({ ports, containerId, }) => {
11
+ return (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: infoColor, children: "\uD83C\uDF10 Connect via Domain:" }), ports.map((port) => (_jsx(CommandHint, { command: [
12
+ "mw",
13
+ "domain",
14
+ "virtualhost",
15
+ "create",
16
+ "--hostname",
17
+ "<your-domain.com>",
18
+ "--path-to-container",
19
+ `/:${containerId}:${port.port}/${port.protocol}`,
20
+ ], description: _jsxs(_Fragment, { children: ["Connect ", _jsx(Value, { children: "<your-domain.com>" }), " to container port", " ", _jsxs(Value, { children: [port.port, "/", port.protocol] }), ", making it accessible via HTTPS. This works only if the container listens for HTTP connections on this port. Other protocols are not supported."] }) }, `domain-${port.port}`)))] }));
21
+ };
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import { ParsedPort } from "./types.js";
3
+ interface InternalConnectionHintsProps {
4
+ ports: ParsedPort[];
5
+ containerName: string;
6
+ }
7
+ /**
8
+ * InternalConnectionHints displays instructions for connecting to the container
9
+ * from within the hosting environment using the service name as hostname.
10
+ */
11
+ export declare const InternalConnectionHints: FC<InternalConnectionHintsProps>;
12
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Fragment } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { Value } from "../Value.js";
5
+ const infoColor = "blueBright";
6
+ /**
7
+ * InternalConnectionHints displays instructions for connecting to the container
8
+ * from within the hosting environment using the service name as hostname.
9
+ */
10
+ export const InternalConnectionHints = ({ ports, containerName, }) => {
11
+ return (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: infoColor, children: "\uD83C\uDFE0 Connect from within hosting environment:" }), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsxs(Text, { wrap: "wrap", children: ["Access container from other services using", " ", ports.map((port, idx) => (_jsxs(Fragment, { children: [_jsxs(Value, { children: [containerName, ":", port.port] }), idx === ports.length - 1 ? " " : " or "] }, `internal-${idx}`))), "as the hostname and port"] }) })] }));
12
+ };
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import { BoxProps } from "ink";
3
+ interface NoPortsUsageHintsProps {
4
+ containerName: string;
5
+ boxProps: BoxProps;
6
+ }
7
+ /**
8
+ * NoPortsUsageHints displays usage instructions for containers that don't
9
+ * expose any ports. It shows management commands for SSH, logs, and exec.
10
+ */
11
+ export declare const NoPortsUsageHints: FC<NoPortsUsageHintsProps>;
12
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ import { ContainerManagementCommands } from "./ContainerManagementCommands.js";
5
+ const infoColor = "blueBright";
6
+ /**
7
+ * NoPortsUsageHints displays usage instructions for containers that don't
8
+ * expose any ports. It shows management commands for SSH, logs, and exec.
9
+ */
10
+ export const NoPortsUsageHints = ({ containerName, boxProps, }) => {
11
+ return (_jsxs(Box, { ...boxProps, flexDirection: "column", children: [_jsx(Text, { bold: true, underline: true, color: infoColor, children: "USAGE HINTS" }), _jsxs(Text, { color: infoColor, children: ["Container ", _jsx(Value, { children: containerName }), " is now running! \uD83D\uDC33"] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Your container doesn't expose any ports, but you can still interact with it:" }) }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(ContainerManagementCommands, { containerIdentifier: containerName }) })] }));
12
+ };
@@ -0,0 +1,13 @@
1
+ import { FC } from "react";
2
+ import { ParsedPort } from "./types.js";
3
+ interface PortConnectionHintsProps {
4
+ ports: ParsedPort[];
5
+ containerId: string;
6
+ containerName: string;
7
+ }
8
+ /**
9
+ * PortConnectionHints orchestrates the display of internal, domain connection,
10
+ * and port forwarding options for containers with exposed ports.
11
+ */
12
+ export declare const PortConnectionHints: FC<PortConnectionHintsProps>;
13
+ export {};
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { InternalConnectionHints } from "./InternalConnectionHints.js";
3
+ import { DomainConnectionHints } from "./DomainConnectionHints.js";
4
+ import { PortForwardingHints } from "./PortForwardingHints.js";
5
+ /**
6
+ * PortConnectionHints orchestrates the display of internal, domain connection,
7
+ * and port forwarding options for containers with exposed ports.
8
+ */
9
+ export const PortConnectionHints = ({ ports, containerId, containerName, }) => {
10
+ return (_jsxs(_Fragment, { children: [_jsx(InternalConnectionHints, { ports: ports, containerName: containerName }), _jsx(DomainConnectionHints, { ports: ports, containerId: containerId }), _jsx(PortForwardingHints, { ports: ports, containerName: containerName })] }));
11
+ };
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import { ParsedPort } from "./types.js";
3
+ interface PortForwardingHintsProps {
4
+ ports: ParsedPort[];
5
+ containerName: string;
6
+ }
7
+ /**
8
+ * PortForwardingHints displays instructions for forwarding container ports to
9
+ * local ports for development purposes.
10
+ */
11
+ export declare const PortForwardingHints: FC<PortForwardingHintsProps>;
12
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { Value } from "../Value.js";
4
+ import { CommandHint } from "./CommandHint.js";
5
+ const infoColor = "blueBright";
6
+ /**
7
+ * PortForwardingHints displays instructions for forwarding container ports to
8
+ * local ports for development purposes.
9
+ */
10
+ export const PortForwardingHints = ({ ports, containerName, }) => {
11
+ return (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: infoColor, children: "\uD83D\uDD17 Port Forward for Local Development:" }), ports.map((port) => (_jsx(CommandHint, { command: [
12
+ "mw",
13
+ "container",
14
+ "port-forward",
15
+ containerName,
16
+ `<local-port>:${port.port}`,
17
+ ], description: _jsxs(_Fragment, { children: ["Forward container port ", _jsx(Value, { children: port.port }), " to a local port (e.g.,", " ", _jsxs(Value, { children: [port.port, ":", port.port] }), " ", "makes it accessible at ", _jsxs(Value, { children: ["http://localhost:", port.port] }), "). This works for all TCP-based protocols."] }) }, `forward-${port.port}`)))] }));
18
+ };
@@ -0,0 +1,4 @@
1
+ export interface ParsedPort {
2
+ port: string;
3
+ protocol: string;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
1
  import { BoxProps } from "ink";
2
2
  import { PropsWithChildren } from "react";
3
3
  /** A pre-styled box for displaying errors. */
4
- export default function ErrorBox(props: PropsWithChildren<BoxProps>): import("react/jsx-runtime").JSX.Element;
4
+ export default function ErrorBox(props: PropsWithChildren<Omit<BoxProps, "width">>): import("react/jsx-runtime").JSX.Element;
@@ -1,14 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box } from "ink";
3
+ import useDefaultBoxStyles from "../../styles/useDefaultBoxStyles.js";
3
4
  const defaultErrorBoxProps = {
4
- width: 80,
5
5
  flexDirection: "column",
6
6
  borderColor: "red",
7
- borderStyle: "round",
8
- paddingX: 1,
9
7
  rowGap: 1,
10
8
  };
11
9
  /** A pre-styled box for displaying errors. */
12
10
  export default function ErrorBox(props) {
13
- return (_jsx(Box, { ...defaultErrorBoxProps, ...props, children: props.children }));
11
+ const defaultBoxStyles = useDefaultBoxStyles();
12
+ return (_jsx(Box, { ...defaultBoxStyles, ...defaultErrorBoxProps, ...props, children: props.children }));
14
13
  }
@@ -9,5 +9,5 @@ const issueURL = "https://github.com/mittwald/cli/issues/new";
9
9
  * have a specific rendering function.
10
10
  */
11
11
  export default function GenericError({ err, withStack, withIssue = true, title = "Error", }) {
12
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(ErrorBox, { children: [_jsx(ErrorText, { bold: true, underline: true, children: title.toUpperCase() }), _jsx(ErrorText, { children: "An error occurred while executing this command:" }), _jsx(Box, { marginX: 2, children: _jsx(ErrorText, { children: err.toString() }) }), withIssue ? (_jsxs(ErrorText, { children: ["If you believe this to be a bug, please open an issue at ", issueURL, "."] })) : undefined] }), withStack && "stack" in err ? _jsx(ErrorStack, { err: err }) : undefined] }));
12
+ return (_jsxs(Box, { flexDirection: "column", width: Infinity, children: [_jsxs(ErrorBox, { children: [_jsx(ErrorText, { bold: true, underline: true, children: title.toUpperCase() }), _jsx(ErrorText, { children: "An error occurred while executing this command:" }), _jsx(Box, { marginX: 2, children: _jsx(ErrorText, { children: err.toString() }) }), withIssue ? (_jsxs(ErrorText, { children: ["If you believe this to be a bug, please open an issue at ", issueURL, "."] })) : undefined] }), withStack && "stack" in err ? _jsx(ErrorStack, { err: err }) : undefined] }));
13
13
  }
@@ -15,6 +15,6 @@ export default class ErrorBoundary extends Component<PropsWithChildren<ErrorBoun
15
15
  constructor(props: PropsWithChildren<ErrorBoundaryProps>);
16
16
  static getDerivedStateFromError(error: unknown): ErrorBoundaryState;
17
17
  componentDidCatch(error: Error): void;
18
- render(): string | number | boolean | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
18
+ render(): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
19
19
  }
20
20
  export {};
@@ -2,7 +2,6 @@ import { FC, PropsWithChildren } from "react";
2
2
  interface Props {
3
3
  title?: string;
4
4
  color?: string;
5
- width?: number;
6
5
  innerText?: boolean;
7
6
  }
8
7
  export declare const defaultSuccessColor = "#00B785";
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
+ import useDefaultBoxStyles from "../styles/useDefaultBoxStyles.js";
3
4
  export const defaultSuccessColor = "#00B785";
4
5
  export const Success = (props) => {
5
- const { title = "Success", color = defaultSuccessColor, width = 80, innerText = true, } = props;
6
+ const { title = "Success", color = defaultSuccessColor, innerText = true, } = props;
6
7
  const inner = innerText ? (_jsx(Text, { wrap: "wrap", color: color, children: props.children })) : (props.children);
7
- return (_jsxs(Box, { width: width, borderStyle: "round", borderColor: color, flexDirection: "column", paddingX: 2, children: [_jsx(Text, { bold: true, underline: true, color: color, children: title.toUpperCase() }), inner] }));
8
+ const defaultBoxStyles = useDefaultBoxStyles();
9
+ return (_jsxs(Box, { ...defaultBoxStyles, borderColor: color, flexDirection: "column", children: [_jsx(Text, { bold: true, underline: true, color: color, children: title.toUpperCase() }), inner] }));
8
10
  };
@@ -0,0 +1,11 @@
1
+ import { BoxProps } from "ink";
2
+ /**
3
+ * Provides default box styles based on the terminal output environment. If the
4
+ * terminal supports TTY (Text Terminal), default styles such as border style
5
+ * and horizontal padding are applied.
6
+ *
7
+ * @returns The default styles for a box. Returns an object containing styles
8
+ * like `borderStyle` and `paddingX` when the terminal is TTY, otherwise
9
+ * returns an empty object.
10
+ */
11
+ export default function useDefaultBoxStyles(): Partial<BoxProps>;
@@ -0,0 +1,23 @@
1
+ import { useStdout } from "ink";
2
+ /**
3
+ * Provides default box styles based on the terminal output environment. If the
4
+ * terminal supports TTY (Text Terminal), default styles such as border style
5
+ * and horizontal padding are applied.
6
+ *
7
+ * @returns The default styles for a box. Returns an object containing styles
8
+ * like `borderStyle` and `paddingX` when the terminal is TTY, otherwise
9
+ * returns an empty object.
10
+ */
11
+ export default function useDefaultBoxStyles() {
12
+ const { stdout } = useStdout();
13
+ if (stdout.isTTY) {
14
+ return {
15
+ borderStyle: "single",
16
+ paddingX: 2,
17
+ width: 80,
18
+ };
19
+ }
20
+ return {
21
+ width: 99999,
22
+ };
23
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/cli",
3
- "version": "1.10.0",
3
+ "version": "1.11.1",
4
4
  "description": "Hand-crafted CLI for the mittwald API",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -54,8 +54,9 @@
54
54
  "date-fns": "^4.0.0",
55
55
  "docker-names": "^1.2.1",
56
56
  "envfile": "^7.1.0",
57
- "ink": "^5.0.1",
58
- "ink-link": "^4.0.0",
57
+ "fast-xml-parser": "^5.2.5",
58
+ "ink": "^6.2.3",
59
+ "ink-link": "^5.0.0",
59
60
  "ink-text-input": "^6.0.0",
60
61
  "js-yaml": "^4.1.0",
61
62
  "marked": "^15.0.12",
@@ -63,21 +64,21 @@
63
64
  "open": "^10.0.3",
64
65
  "parse-duration": "^2.0.1",
65
66
  "pretty-bytes": "^7.0.0",
66
- "react": "^18.2.0",
67
+ "react": "^19.1.1",
67
68
  "semver": "^7.5.4",
68
69
  "semver-parser": "^4.1.6",
69
70
  "shell-escape": "^0.2.0",
70
71
  "slice-ansi": "^7.1.0",
71
72
  "string-width": "^8.0.0",
72
73
  "tempfile": "^5.0.0",
73
- "uuid": "^11.0.3"
74
+ "uuid": "^13.0.0"
74
75
  },
75
76
  "devDependencies": {
76
77
  "@jest/globals": "^30.0.4",
77
78
  "@oclif/test": "^4.0.4",
78
79
  "@types/js-yaml": "^4.0.9",
79
80
  "@types/node": "^24.0.10",
80
- "@types/react": "^18",
81
+ "@types/react": "^19",
81
82
  "@types/semver": "^7.5.0",
82
83
  "@types/shell-escape": "^0.2.3",
83
84
  "@typescript-eslint/eslint-plugin": "^8.35.0",