@mittwald/cli 1.5.1 → 1.7.0

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 (130) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/app/dependency/list.d.ts +1 -0
  3. package/dist/commands/app/dependency/versions.d.ts +1 -0
  4. package/dist/commands/app/get.js +1 -2
  5. package/dist/commands/app/list-upgrade-candidates.d.ts +1 -0
  6. package/dist/commands/app/list.d.ts +1 -0
  7. package/dist/commands/app/upgrade.d.ts +14 -0
  8. package/dist/commands/app/upgrade.js +35 -22
  9. package/dist/commands/backup/delete.d.ts +1 -0
  10. package/dist/commands/backup/get.js +1 -2
  11. package/dist/commands/backup/list.d.ts +1 -0
  12. package/dist/commands/backup/schedule/list.d.ts +1 -0
  13. package/dist/commands/container/delete.d.ts +1 -0
  14. package/dist/commands/container/exec.d.ts +25 -0
  15. package/dist/commands/container/exec.js +93 -0
  16. package/dist/commands/container/list.d.ts +1 -0
  17. package/dist/commands/container/logs.d.ts +1 -0
  18. package/dist/commands/container/port-forward.d.ts +20 -0
  19. package/dist/commands/container/port-forward.js +68 -0
  20. package/dist/commands/container/run.d.ts +12 -0
  21. package/dist/commands/container/run.js +27 -8
  22. package/dist/commands/container/ssh.d.ts +17 -0
  23. package/dist/commands/container/ssh.js +61 -0
  24. package/dist/commands/conversation/categories.d.ts +1 -0
  25. package/dist/commands/conversation/create.d.ts +1 -0
  26. package/dist/commands/conversation/list.d.ts +1 -0
  27. package/dist/commands/conversation/reply.d.ts +1 -0
  28. package/dist/commands/cronjob/delete.d.ts +1 -0
  29. package/dist/commands/cronjob/execution/get.d.ts +1 -1
  30. package/dist/commands/cronjob/execution/list.d.ts +1 -0
  31. package/dist/commands/cronjob/execution/logs.d.ts +1 -0
  32. package/dist/commands/cronjob/get.js +1 -2
  33. package/dist/commands/cronjob/list.d.ts +1 -0
  34. package/dist/commands/database/list.d.ts +1 -0
  35. package/dist/commands/database/mysql/charsets.d.ts +1 -0
  36. package/dist/commands/database/mysql/delete.d.ts +1 -0
  37. package/dist/commands/database/mysql/get.d.ts +1 -1
  38. package/dist/commands/database/mysql/list.d.ts +1 -0
  39. package/dist/commands/database/mysql/user/delete.d.ts +1 -0
  40. package/dist/commands/database/mysql/user/get.d.ts +1 -1
  41. package/dist/commands/database/mysql/user/list.d.ts +1 -0
  42. package/dist/commands/database/mysql/versions.d.ts +1 -0
  43. package/dist/commands/database/redis/get.d.ts +1 -1
  44. package/dist/commands/database/redis/list.d.ts +1 -0
  45. package/dist/commands/database/redis/versions.d.ts +1 -0
  46. package/dist/commands/domain/dnszone/get.js +1 -2
  47. package/dist/commands/domain/dnszone/list.d.ts +1 -0
  48. package/dist/commands/domain/dnszone/update.js +3 -2
  49. package/dist/commands/domain/get.js +1 -2
  50. package/dist/commands/domain/list.d.ts +1 -0
  51. package/dist/commands/domain/virtualhost/delete.d.ts +1 -0
  52. package/dist/commands/domain/virtualhost/get.js +1 -2
  53. package/dist/commands/domain/virtualhost/list.d.ts +1 -0
  54. package/dist/commands/extension/list-installed.d.ts +1 -0
  55. package/dist/commands/extension/list.d.ts +1 -0
  56. package/dist/commands/mail/address/delete.d.ts +1 -0
  57. package/dist/commands/mail/address/get.d.ts +1 -1
  58. package/dist/commands/mail/address/list.d.ts +1 -0
  59. package/dist/commands/mail/deliverybox/delete.d.ts +1 -0
  60. package/dist/commands/mail/deliverybox/get.d.ts +1 -1
  61. package/dist/commands/mail/deliverybox/list.d.ts +1 -0
  62. package/dist/commands/org/delete.d.ts +1 -0
  63. package/dist/commands/org/get.js +1 -2
  64. package/dist/commands/org/invite/list-own.d.ts +1 -0
  65. package/dist/commands/org/invite/list.d.ts +1 -0
  66. package/dist/commands/org/list.d.ts +1 -0
  67. package/dist/commands/org/membership/list-own.d.ts +1 -0
  68. package/dist/commands/org/membership/list.d.ts +1 -0
  69. package/dist/commands/project/delete.d.ts +1 -0
  70. package/dist/commands/project/filesystem/usage.js +1 -2
  71. package/dist/commands/project/get.js +1 -2
  72. package/dist/commands/project/invite/get.d.ts +1 -1
  73. package/dist/commands/project/invite/list-own.d.ts +1 -0
  74. package/dist/commands/project/invite/list.d.ts +1 -0
  75. package/dist/commands/project/list.d.ts +1 -0
  76. package/dist/commands/project/membership/get-own.d.ts +1 -0
  77. package/dist/commands/project/membership/get.d.ts +1 -1
  78. package/dist/commands/project/membership/list-own.d.ts +1 -0
  79. package/dist/commands/project/membership/list.d.ts +1 -0
  80. package/dist/commands/registry/delete.d.ts +1 -0
  81. package/dist/commands/registry/list.d.ts +1 -0
  82. package/dist/commands/server/get.d.ts +1 -1
  83. package/dist/commands/server/list.d.ts +1 -0
  84. package/dist/commands/sftp-user/delete.d.ts +1 -0
  85. package/dist/commands/sftp-user/list.d.ts +1 -0
  86. package/dist/commands/ssh-user/delete.d.ts +1 -0
  87. package/dist/commands/ssh-user/list.d.ts +1 -0
  88. package/dist/commands/stack/delete.d.ts +1 -0
  89. package/dist/commands/stack/deploy.js +1 -8
  90. package/dist/commands/stack/list.d.ts +1 -0
  91. package/dist/commands/stack/ps.d.ts +1 -0
  92. package/dist/commands/stack/ps.js +1 -1
  93. package/dist/commands/user/api-token/get.d.ts +1 -1
  94. package/dist/commands/user/api-token/list.d.ts +1 -0
  95. package/dist/commands/user/api-token/revoke.d.ts +1 -0
  96. package/dist/commands/user/get.d.ts +1 -1
  97. package/dist/commands/user/session/get.d.ts +1 -1
  98. package/dist/commands/user/session/list.d.ts +1 -0
  99. package/dist/commands/user/ssh-key/delete.d.ts +1 -0
  100. package/dist/commands/user/ssh-key/get.d.ts +1 -1
  101. package/dist/commands/user/ssh-key/list.d.ts +1 -0
  102. package/dist/lib/basecommands/BaseCommand.d.ts +7 -5
  103. package/dist/lib/basecommands/BaseCommand.js +26 -8
  104. package/dist/lib/basecommands/CommandFlags.d.ts +3 -3
  105. package/dist/lib/basecommands/CoreBaseCommand.d.ts +12 -0
  106. package/dist/lib/basecommands/CoreBaseCommand.js +16 -0
  107. package/dist/lib/basecommands/DeleteBaseCommand.d.ts +1 -0
  108. package/dist/lib/basecommands/DeleteBaseCommand.js +1 -0
  109. package/dist/lib/basecommands/ExecRenderBaseCommand.d.ts +3 -0
  110. package/dist/lib/basecommands/ExecRenderBaseCommand.js +3 -0
  111. package/dist/lib/basecommands/ExtendedBaseCommand.d.ts +3 -0
  112. package/dist/lib/basecommands/ExtendedBaseCommand.js +3 -0
  113. package/dist/lib/basecommands/GetBaseCommand.d.ts +1 -1
  114. package/dist/lib/basecommands/GetBaseCommand.js +1 -0
  115. package/dist/lib/basecommands/ListBaseCommand.d.ts +1 -0
  116. package/dist/lib/basecommands/ListBaseCommand.js +1 -0
  117. package/dist/lib/basecommands/UnauthenticatedBaseCommand.d.ts +10 -0
  118. package/dist/lib/basecommands/UnauthenticatedBaseCommand.js +16 -0
  119. package/dist/lib/error/NoTokenFoundError.d.ts +11 -0
  120. package/dist/lib/error/NoTokenFoundError.js +13 -0
  121. package/dist/lib/resources/ssh/container.d.ts +3 -0
  122. package/dist/lib/resources/ssh/container.js +29 -0
  123. package/dist/lib/resources/stack/enrich.d.ts +2 -2
  124. package/dist/lib/resources/stack/enrich.js +1 -31
  125. package/dist/lib/units/PortMapping.d.ts +11 -0
  126. package/dist/lib/units/PortMapping.js +38 -0
  127. package/dist/lib/units/PortMapping.test.d.ts +1 -0
  128. package/dist/lib/units/PortMapping.test.js +28 -0
  129. package/dist/rendering/react/components/ErrorBox.js +4 -0
  130. package/package.json +67 -19
@@ -0,0 +1,38 @@
1
+ import { Args } from "@oclif/core";
2
+ /** Represents a mapping between a local port and a remote port. */
3
+ export default class PortMapping {
4
+ localPort;
5
+ remotePort;
6
+ constructor(localPort, remotePort) {
7
+ this.localPort = localPort;
8
+ this.remotePort = remotePort;
9
+ }
10
+ static validatePort(port) {
11
+ return !isNaN(port) && port > 0 && port <= 65535;
12
+ }
13
+ static arg = Args.custom({
14
+ parse: async (input) => PortMapping.fromString(input),
15
+ });
16
+ /** @param str Port and protocol; example: `8080/tcp` */
17
+ static fromPortAndProtocol(str) {
18
+ const [localPort, protocol] = str.split("/");
19
+ const portNum = parseInt(localPort);
20
+ if (!PortMapping.validatePort(portNum)) {
21
+ throw new Error("Invalid port number. Ports must be between 1 and 65535.");
22
+ }
23
+ if (protocol.toLowerCase() !== "tcp") {
24
+ throw new Error("Only TCP protocol is supported.");
25
+ }
26
+ return new PortMapping(portNum, portNum);
27
+ }
28
+ static fromString(str) {
29
+ const [localPort, remotePort] = str.split(":");
30
+ const localPortNum = parseInt(localPort);
31
+ const remotePortNum = parseInt(remotePort);
32
+ if (!PortMapping.validatePort(localPortNum) ||
33
+ !PortMapping.validatePort(remotePortNum)) {
34
+ throw new Error("Invalid port number. Ports must be between 1 and 65535.");
35
+ }
36
+ return new PortMapping(localPortNum, remotePortNum);
37
+ }
38
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import { describe, expect, it } from "@jest/globals";
2
+ import PortMapping from "./PortMapping.js";
3
+ describe("PortMapping", () => {
4
+ // Test: Successfully create PortMapping instance using fromString
5
+ it("should correctly parse valid port mapping string", () => {
6
+ const result = PortMapping.fromString("8080:9090");
7
+ expect(result.localPort).toBe(8080);
8
+ expect(result.remotePort).toBe(9090);
9
+ });
10
+ // Test: Throws an error for invalid local port
11
+ it("should throw an error for invalid local port", () => {
12
+ expect(() => PortMapping.fromString("100000:8080")).toThrow("Invalid port number. Ports must be between 1 and 65535.");
13
+ });
14
+ // Test: Throws an error for invalid remote port
15
+ it("should throw an error for invalid remote port", () => {
16
+ expect(() => PortMapping.fromString("8080:70000")).toThrow("Invalid port number. Ports must be between 1 and 65535.");
17
+ });
18
+ // Test: Throws an error when input format is incorrect
19
+ it("should throw an error for invalid string format", () => {
20
+ expect(() => PortMapping.fromString("8080-9090")).toThrow("Invalid port number. Ports must be between 1 and 65535.");
21
+ });
22
+ // Test: Successfully assign local and remote ports via constructor
23
+ it("should correctly initialize PortMapping with valid ports", () => {
24
+ const portMapping = new PortMapping(3000, 4000);
25
+ expect(portMapping.localPort).toBe(3000);
26
+ expect(portMapping.remotePort).toBe(4000);
27
+ });
28
+ });
@@ -6,6 +6,7 @@ import GenericError from "./Error/GenericError.js";
6
6
  import APIError from "./Error/APIError.js";
7
7
  import UnexpectedShortIDPassedErrorBox from "./Error/UnexpectedShortIDPassedErrorBox.js";
8
8
  import { MissingArgError, MissingFlagError, } from "../../../lib/context/FlagSetBuilder.js";
9
+ import NoTokenFoundError from "../../../lib/error/NoTokenFoundError.js";
9
10
  /**
10
11
  * Render an error to the terminal.
11
12
  *
@@ -27,6 +28,9 @@ export const ErrorBox = ({ err }) => {
27
28
  err instanceof MissingFlagError) {
28
29
  return (_jsx(GenericError, { err: err, withStack: false, withIssue: false, title: "Input required" }));
29
30
  }
31
+ else if (err instanceof NoTokenFoundError) {
32
+ return (_jsx(GenericError, { err: err, withStack: false, withIssue: false, title: "Login required" }));
33
+ }
30
34
  else if (err instanceof UnexpectedShortIDPassedError) {
31
35
  return _jsx(UnexpectedShortIDPassedErrorBox, { err: err });
32
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/cli",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "description": "Hand-crafted CLI for the mittwald API",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "type": "module",
18
18
  "engines": {
19
- "node": ">=18.0.0"
19
+ "node": ">=20.0.0"
20
20
  },
21
21
  "scripts": {
22
22
  "clean": "(rimraf --glob dist tsconfig.*.tsbuildinfo) | true",
@@ -62,7 +62,7 @@
62
62
  "marked-terminal": "^7.3.0",
63
63
  "open": "^10.0.3",
64
64
  "parse-duration": "^2.0.1",
65
- "pretty-bytes": "^6.1.0",
65
+ "pretty-bytes": "^7.0.0",
66
66
  "react": "^18.2.0",
67
67
  "semver": "^7.5.4",
68
68
  "semver-parser": "^4.1.6",
@@ -73,10 +73,10 @@
73
73
  "uuid": "^11.0.3"
74
74
  },
75
75
  "devDependencies": {
76
- "@jest/globals": "^29.7.0",
76
+ "@jest/globals": "^30.0.4",
77
77
  "@oclif/test": "^4.0.4",
78
78
  "@types/js-yaml": "^4.0.9",
79
- "@types/node": "^22.7.5",
79
+ "@types/node": "^24.0.10",
80
80
  "@types/react": "^18",
81
81
  "@types/semver": "^7.5.0",
82
82
  "@types/shell-escape": "^0.2.3",
@@ -88,11 +88,11 @@
88
88
  "eslint-plugin-json": "^4.0.1",
89
89
  "eslint-plugin-prettier": "^5.5.1",
90
90
  "globals": "^16.0.0",
91
- "jest": "^29.7.0",
91
+ "jest": "^30.0.4",
92
92
  "license-checker-rseidelsohn": "^4.2.6",
93
93
  "nock": "^14.0.0",
94
94
  "oclif": "^4.14.31",
95
- "prettier": "~3.5.3",
95
+ "prettier": "~3.6.2",
96
96
  "prettier-plugin-jsdoc": "^1.3.2",
97
97
  "prettier-plugin-package": "^1.4.0",
98
98
  "prettier-plugin-sort-json": "^4.1.1",
@@ -117,6 +117,9 @@
117
117
  "app": {
118
118
  "description": "Manage apps, and app installations in your projects",
119
119
  "subtopics": {
120
+ "create": {
121
+ "description": "Create new self-managed apps in your projects"
122
+ },
120
123
  "install": {
121
124
  "description": "Install apps in your projects"
122
125
  },
@@ -128,9 +131,6 @@
128
131
  "registry": {
129
132
  "description": "Manage container registries"
130
133
  },
131
- "article": {
132
- "description": "Query available hosting articles"
133
- },
134
134
  "backup": {
135
135
  "description": "Manage backups of your projects",
136
136
  "subtopics": {
@@ -139,12 +139,12 @@
139
139
  }
140
140
  }
141
141
  },
142
+ "container": {
143
+ "description": "Manage containers"
144
+ },
142
145
  "context": {
143
146
  "description": "Save certain environment parameters for later use"
144
147
  },
145
- "contract": {
146
- "description": "Manage your hosting contracts, and order new ones"
147
- },
148
148
  "conversation": {
149
149
  "description": "Manage your support cases"
150
150
  },
@@ -157,16 +157,42 @@
157
157
  }
158
158
  },
159
159
  "cronjob": {
160
- "description": "Manage cronjobs of your projects"
160
+ "description": "Manage cronjobs of your projects",
161
+ "subtopics": {
162
+ "execution": {
163
+ "description": "Manage individual cronjob executions"
164
+ }
165
+ }
161
166
  },
162
167
  "database": {
163
- "description": "Manage databases (like MySQL and Redis) in your projects"
168
+ "description": "Manage databases (like MySQL and Redis) in your projects",
169
+ "subtopics": {
170
+ "mysql": {
171
+ "description": "Manage MySQL databases in your projects",
172
+ "subtopics": {
173
+ "user": {
174
+ "description": "Manage MySQL database users"
175
+ }
176
+ }
177
+ },
178
+ "redis": {
179
+ "description": "Manage Redis databases in your projects"
180
+ }
181
+ }
164
182
  },
165
183
  "ddev": {
166
184
  "description": "Integrate your mittwald projects with DDEV"
167
185
  },
168
186
  "domain": {
169
- "description": "Manage domains, virtual hosts and DNS settings in your projects"
187
+ "description": "Manage domains, virtual hosts and DNS settings in your projects",
188
+ "subtopics": {
189
+ "dnszone": {
190
+ "description": "Manage DNS zones for your domains"
191
+ },
192
+ "virtualhost": {
193
+ "description": "Manage virtual hosts for your domains"
194
+ }
195
+ }
170
196
  },
171
197
  "extension": {
172
198
  "description": "Install and manage extensions in your organisations and projects"
@@ -175,10 +201,26 @@
175
201
  "description": "Manage your client authentication"
176
202
  },
177
203
  "mail": {
178
- "description": "Manage mailboxes and mail addresses in your projects"
204
+ "description": "Manage mailboxes and mail addresses in your projects",
205
+ "subtopics": {
206
+ "address": {
207
+ "description": "Manage mail addresses in your projects"
208
+ },
209
+ "deliverybox": {
210
+ "description": "Manage mail delivery boxes in your projects"
211
+ }
212
+ }
179
213
  },
180
214
  "org": {
181
- "description": "Manage your organizations, and also any kinds of user memberships concerning these organizations."
215
+ "description": "Manage your organizations, and also any kinds of user memberships concerning these organizations.",
216
+ "subtopics": {
217
+ "invite": {
218
+ "description": "Invite users to your organizations and manage their invitations"
219
+ },
220
+ "membership": {
221
+ "description": "Control who gets to work in your organizations, and who doesn't"
222
+ }
223
+ }
182
224
  },
183
225
  "project": {
184
226
  "description": "Manage your projects, and also any kinds of user memberships concerning these projects.",
@@ -209,6 +251,12 @@
209
251
  "user": {
210
252
  "description": "Manage your own user account",
211
253
  "subtopics": {
254
+ "api-token": {
255
+ "description": "Manage your API tokens"
256
+ },
257
+ "session": {
258
+ "description": "Manage your active sessions"
259
+ },
212
260
  "ssh-key": {
213
261
  "description": "Manage your SSH keys"
214
262
  }
@@ -223,7 +271,7 @@
223
271
  ],
224
272
  "update": {
225
273
  "node": {
226
- "version": "18.20.4"
274
+ "version": "20.19.3"
227
275
  },
228
276
  "s3": {
229
277
  "xz": true,