kiwivm-cli 0.1.0 → 0.2.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 (52) hide show
  1. package/README.md +62 -36
  2. package/dist/index.d.mts.map +1 -1
  3. package/dist/index.mjs +370 -50
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/src/commands/admin.test.ts +135 -22
  7. package/src/commands/admin.ts +57 -19
  8. package/src/commands/backup.test.ts +26 -23
  9. package/src/commands/backup.ts +13 -15
  10. package/src/commands/help.test.ts +27 -7
  11. package/src/commands/help.ts +61 -26
  12. package/src/commands/info.test.ts +47 -43
  13. package/src/commands/info.ts +11 -13
  14. package/src/commands/iso.test.ts +58 -0
  15. package/src/commands/iso.ts +21 -0
  16. package/src/commands/migrate.test.ts +105 -0
  17. package/src/commands/migrate.ts +38 -0
  18. package/src/commands/network.test.ts +107 -30
  19. package/src/commands/network.ts +56 -18
  20. package/src/commands/power.test.ts +58 -40
  21. package/src/commands/power.ts +27 -16
  22. package/src/commands/shell.test.ts +66 -0
  23. package/src/commands/shell.ts +25 -0
  24. package/src/commands/snapshot.test.ts +141 -71
  25. package/src/commands/snapshot.ts +85 -33
  26. package/src/commands/stats.test.ts +81 -0
  27. package/src/commands/stats.ts +25 -0
  28. package/src/commands/system.test.ts +109 -40
  29. package/src/commands/system.ts +55 -23
  30. package/src/index.test.ts +435 -148
  31. package/src/index.ts +129 -57
  32. package/src/types.ts +57 -1
  33. package/dist/admin-fOud1ZmX.mjs +0 -15
  34. package/dist/admin-fOud1ZmX.mjs.map +0 -1
  35. package/dist/backup-D1UJ4aap.mjs +0 -12
  36. package/dist/backup-D1UJ4aap.mjs.map +0 -1
  37. package/dist/help-Dk-WApoi.mjs +0 -40
  38. package/dist/help-Dk-WApoi.mjs.map +0 -1
  39. package/dist/info-DKExtFYH.mjs +0 -13
  40. package/dist/info-DKExtFYH.mjs.map +0 -1
  41. package/dist/monitoring-BSuv8fj9.mjs +0 -13
  42. package/dist/monitoring-BSuv8fj9.mjs.map +0 -1
  43. package/dist/network-1ycEIJqT.mjs +0 -15
  44. package/dist/network-1ycEIJqT.mjs.map +0 -1
  45. package/dist/power-CDg0Mx1A.mjs +0 -14
  46. package/dist/power-CDg0Mx1A.mjs.map +0 -1
  47. package/dist/snapshot-LO_ufoj5.mjs +0 -23
  48. package/dist/snapshot-LO_ufoj5.mjs.map +0 -1
  49. package/dist/system-Bl-dsqX9.mjs +0 -21
  50. package/dist/system-Bl-dsqX9.mjs.map +0 -1
  51. package/src/commands/monitoring.test.ts +0 -82
  52. package/src/commands/monitoring.ts +0 -20
package/src/index.ts CHANGED
@@ -1,8 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { KiwiVMClient } from "./client.ts";
4
+ import * as admin from "./commands/admin.ts";
5
+ import * as backup from "./commands/backup.ts";
6
+ import * as help from "./commands/help.ts";
7
+ import * as info from "./commands/info.ts";
8
+ import * as iso from "./commands/iso.ts";
9
+ import * as migrate from "./commands/migrate.ts";
10
+ import * as network from "./commands/network.ts";
11
+ import * as power from "./commands/power.ts";
12
+ import * as shell from "./commands/shell.ts";
13
+ import * as snapshot from "./commands/snapshot.ts";
14
+ import * as stats from "./commands/stats.ts";
15
+ import * as system from "./commands/system.ts";
4
16
  import { KiwiVMError } from "./types.ts";
5
17
 
18
+ type Handler = (
19
+ args: string[],
20
+ flags: Record<string, string>,
21
+ client: KiwiVMClient,
22
+ ) => Promise<unknown>;
23
+
24
+ interface SubcommandRoutes {
25
+ default?: Handler;
26
+ [subcommand: string]: Handler | undefined;
27
+ }
28
+
6
29
  function parseFlags(args: string[]): Record<string, string> {
7
30
  const flags: Record<string, string> = {};
8
31
  for (let i = 0; i < args.length; i++) {
@@ -20,9 +43,8 @@ function parseFlags(args: string[]): Record<string, string> {
20
43
  flags[toCamelCase(key)] = next;
21
44
  i++;
22
45
  } else {
23
- // --flag with no value (treat as boolean/empty string)
24
46
  const key = arg.slice(2);
25
- flags[toCamelCase(key)] = "";
47
+ flags[toCamelCase(key)] = "1";
26
48
  }
27
49
  }
28
50
  }
@@ -30,7 +52,6 @@ function parseFlags(args: string[]): Record<string, string> {
30
52
  }
31
53
 
32
54
  function toCamelCase(key: string): string {
33
- // Known mappings: kebab-case flags that need camelCase API param names
34
55
  const known: Record<string, string> = {
35
56
  "backup-token": "backupToken",
36
57
  "new-hostname": "newHostname",
@@ -43,7 +64,6 @@ function toCamelCase(key: string): string {
43
64
  };
44
65
  if (known[key]) return known[key];
45
66
 
46
- // Default: convert --some-flag to someFlag
47
67
  return key.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());
48
68
  }
49
69
 
@@ -70,18 +90,13 @@ async function main() {
70
90
  const args = process.argv.slice(2);
71
91
  const { positional, flags } = getCommandFromArgs(args);
72
92
 
73
- const category = positional[0] ?? "";
74
- const action = positional[1] ?? "";
93
+ const command = positional[0] ?? "";
75
94
 
76
- // Handle help before auth (no credentials needed)
77
- if (category === "" || category === "help") {
78
- const { run } = await import("./commands/help.ts");
79
- const text = await run();
80
- console.log(text as string);
95
+ if (command === "" || command === "help") {
96
+ console.log(await help.run());
81
97
  return;
82
98
  }
83
99
 
84
- // Resolve auth: flags first, then env vars
85
100
  const flagVeid = flags["veid"];
86
101
  const flagApiKey = flags["apiKey"];
87
102
  const resolvedVeid = flagVeid || process.env["KIWIVM_VEID"];
@@ -94,7 +109,6 @@ async function main() {
94
109
  process.exit(1);
95
110
  }
96
111
 
97
- // Strip auth flags before passing to handlers
98
112
  const handlerFlags = { ...flags };
99
113
  delete handlerFlags["veid"];
100
114
  delete handlerFlags["apiKey"];
@@ -107,52 +121,111 @@ async function main() {
107
121
  try {
108
122
  let result: unknown;
109
123
 
110
- switch (category) {
111
- case "power": {
112
- const { run } = await import("./commands/power.ts");
113
- result = await run(action, handlerFlags, client);
114
- break;
115
- }
116
- case "info": {
117
- const { run } = await import("./commands/info.ts");
118
- result = await run(action, handlerFlags, client);
119
- break;
120
- }
121
- case "snapshot": {
122
- const { run } = await import("./commands/snapshot.ts");
123
- result = await run(action, handlerFlags, client);
124
- break;
125
- }
126
- case "backup": {
127
- const { run } = await import("./commands/backup.ts");
128
- result = await run(action, handlerFlags, client);
129
- break;
130
- }
131
- case "system": {
132
- const { run } = await import("./commands/system.ts");
133
- result = await run(action, handlerFlags, client);
134
- break;
135
- }
136
- case "network": {
137
- const { run } = await import("./commands/network.ts");
138
- result = await run(action, handlerFlags, client);
139
- break;
140
- }
141
- case "monitoring": {
142
- const { run } = await import("./commands/monitoring.ts");
143
- result = await run(action, handlerFlags, client);
144
- break;
145
- }
146
- case "admin": {
147
- const { run } = await import("./commands/admin.ts");
148
- result = await run(action, handlerFlags, client);
149
- break;
124
+ const ROUTES: Record<string, Handler | SubcommandRoutes> = {
125
+ start: power.start,
126
+ stop: power.stop,
127
+ restart: power.restart,
128
+ kill: power.kill,
129
+ info: info.info,
130
+ status: info.status,
131
+ hostname: system.hostname,
132
+ password: system.password,
133
+ suspensions: admin.suspensions,
134
+ unsuspend: admin.unsuspend,
135
+ clone: migrate.clone,
136
+
137
+ snapshot: {
138
+ list: snapshot.list,
139
+ create: snapshot.create,
140
+ delete: snapshot.deleteSnapshot,
141
+ restore: snapshot.restore,
142
+ sticky: snapshot.sticky,
143
+ export: snapshot.exportSnapshot,
144
+ import: snapshot.importSnapshot,
145
+ },
146
+ backup: {
147
+ list: backup.list,
148
+ copy: backup.copy,
149
+ },
150
+ os: {
151
+ list: system.osList,
152
+ reinstall: system.osReinstall,
153
+ },
154
+ "ssh-key": {
155
+ default: system.sshKeyShow,
156
+ set: system.sshKeySet,
157
+ },
158
+ rdns: {
159
+ set: network.rdnsSet,
160
+ },
161
+ ipv6: {
162
+ add: network.ipv6Add,
163
+ delete: network.ipv6Delete,
164
+ },
165
+ "private-ip": {
166
+ list: network.privateIpList,
167
+ assign: network.privateIpAssign,
168
+ delete: network.privateIpDelete,
169
+ },
170
+ iso: {
171
+ mount: iso.mount,
172
+ unmount: iso.unmount,
173
+ },
174
+ shell: {
175
+ exec: shell.exec,
176
+ script: shell.script,
177
+ },
178
+ migrate: {
179
+ locations: migrate.locations,
180
+ start: migrate.migrateStart,
181
+ },
182
+ stats: {
183
+ usage: stats.usage,
184
+ audit: stats.audit,
185
+ "rate-limit": stats.rateLimit,
186
+ },
187
+ violations: {
188
+ default: admin.violationsList,
189
+ resolve: admin.violationsResolve,
190
+ },
191
+ notifications: {
192
+ default: admin.notificationsGet,
193
+ set: admin.notificationsSet,
194
+ },
195
+ };
196
+
197
+ const route = ROUTES[command];
198
+
199
+ if (!route) {
200
+ console.error(`Unknown command: ${command}`);
201
+ console.error("Run 'kiwivm-cli help' for usage.");
202
+ process.exit(1);
203
+ }
204
+
205
+ if (typeof route === "function") {
206
+ result = await route(positional.slice(1), handlerFlags, client);
207
+ } else {
208
+ const subcommand = positional[1];
209
+ let handler: Handler | undefined;
210
+
211
+ if (subcommand && subcommand in route) {
212
+ handler = route[subcommand];
213
+ } else if (!subcommand && route.default) {
214
+ handler = route.default;
150
215
  }
151
- default: {
152
- console.error(`Unknown category: ${category}`);
153
- console.error("Run 'kiwivm-cli help' for usage.");
216
+
217
+ if (!handler) {
218
+ const valid = Object.keys(route)
219
+ .filter((k) => k !== "default")
220
+ .join(", ");
221
+ const sc = subcommand || "(none)";
222
+ console.error(
223
+ `Unknown subcommand for ${command}: ${sc}. Valid: ${valid}`,
224
+ );
154
225
  process.exit(1);
155
226
  }
227
+
228
+ result = await handler(positional.slice(2), handlerFlags, client);
156
229
  }
157
230
 
158
231
  console.log(JSON.stringify(result));
@@ -166,7 +239,6 @@ async function main() {
166
239
 
167
240
  export { main };
168
241
 
169
- // Only auto-run when executed directly (not when imported by tests)
170
242
  if (!process.env["VITEST"]) {
171
243
  main();
172
244
  }
package/src/types.ts CHANGED
@@ -16,10 +16,12 @@ export class KiwiVMError extends Error {
16
16
  }
17
17
 
18
18
  export interface ServiceInfo extends KiwiVMResponse {
19
+ vm_type?: "ovz" | "kvm";
19
20
  hostname?: string;
20
21
  node_alias?: string;
21
22
  node_location?: string;
22
23
  location_ipv6_ready?: number;
24
+ monthly_data_multiplier?: number;
23
25
  plan?: string;
24
26
  plan_monthly_data?: number;
25
27
  plan_disk?: number;
@@ -55,7 +57,6 @@ export interface ServiceInfo extends KiwiVMResponse {
55
57
  }
56
58
 
57
59
  export interface LiveServiceInfo extends ServiceInfo {
58
- vm_type?: "ovz" | "kvm";
59
60
  vz_status?: Record<string, unknown>;
60
61
  vz_quota?: Record<string, unknown>;
61
62
  ve_status?: "Starting" | "Running" | "Stopped";
@@ -92,3 +93,58 @@ export interface Backup {
92
93
  md5: string;
93
94
  timestamp: number;
94
95
  }
96
+
97
+ export interface RateLimitStatus extends KiwiVMResponse {
98
+ remaining_points_15min: number;
99
+ remaining_points_24h: number;
100
+ }
101
+
102
+ export interface SuspensionRecord {
103
+ record_id: number;
104
+ flag: string;
105
+ is_soft: number;
106
+ evidence_record_id: number;
107
+ abuse_points: number;
108
+ }
109
+
110
+ export interface SuspensionDetailsResponse extends KiwiVMResponse {
111
+ suspension_count: number;
112
+ total_abuse_points: number;
113
+ max_abuse_points: number;
114
+ suspensions: SuspensionRecord[];
115
+ evidence: Record<string, string>;
116
+ }
117
+
118
+ export interface PolicyViolation {
119
+ record_id: number;
120
+ timestamp: number;
121
+ suspend_at: number;
122
+ flag: string;
123
+ is_soft: number;
124
+ abuse_points: number;
125
+ evidence_data: string;
126
+ }
127
+
128
+ export interface PolicyViolationsResponse extends KiwiVMResponse {
129
+ total_abuse_points: number;
130
+ max_abuse_points: number;
131
+ policy_violations: PolicyViolation[];
132
+ }
133
+
134
+ export interface NotificationPreference {
135
+ id: number;
136
+ name: string;
137
+ description: string;
138
+ value: number;
139
+ }
140
+
141
+ export interface NotificationPreferencesResponse extends KiwiVMResponse {
142
+ email_preferences: NotificationPreference[];
143
+ notificationEmail: string;
144
+ }
145
+
146
+ export interface NotificationSetResponse extends KiwiVMResponse {
147
+ submitted_email_preferences: Record<string, number>;
148
+ updated_email_preferences: Record<string, number>;
149
+ friendly_descriptions: Record<string, string>;
150
+ }
@@ -1,15 +0,0 @@
1
- //#region src/commands/admin.ts
2
- async function run(action, flags, client) {
3
- switch (action) {
4
- case "suspensions": return client.call("getSuspensionDetails");
5
- case "unsuspend": return client.call("unsuspend", { recordId: flags["recordId"] });
6
- case "resolve":
7
- if (flags["recordId"] !== void 0) return client.call("resolvePolicyViolation", { recordId: flags["recordId"] });
8
- return client.call("getPolicyViolations");
9
- default: throw new Error(`Unknown admin action: ${action}. Valid: suspensions, unsuspend, resolve`);
10
- }
11
- }
12
- //#endregion
13
- export { run };
14
-
15
- //# sourceMappingURL=admin-fOud1ZmX.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-fOud1ZmX.mjs","names":[],"sources":["../src/commands/admin.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"suspensions\":\n return client.call(\"getSuspensionDetails\");\n case \"unsuspend\":\n return client.call(\"unsuspend\", { recordId: flags[\"recordId\"] });\n case \"resolve\":\n if (flags[\"recordId\"] !== undefined) {\n return client.call(\"resolvePolicyViolation\", {\n recordId: flags[\"recordId\"],\n });\n }\n return client.call(\"getPolicyViolations\");\n default:\n throw new Error(\n `Unknown admin action: ${action}. Valid: suspensions, unsuspend, resolve`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,cACH,QAAO,OAAO,KAAK,uBAAuB;EAC5C,KAAK,YACH,QAAO,OAAO,KAAK,aAAa,EAAE,UAAU,MAAM,aAAa,CAAC;EAClE,KAAK;AACH,OAAI,MAAM,gBAAgB,KAAA,EACxB,QAAO,OAAO,KAAK,0BAA0B,EAC3C,UAAU,MAAM,aACjB,CAAC;AAEJ,UAAO,OAAO,KAAK,sBAAsB;EAC3C,QACE,OAAM,IAAI,MACR,yBAAyB,OAAO,0CACjC"}
@@ -1,12 +0,0 @@
1
- //#region src/commands/backup.ts
2
- async function run(action, flags, client) {
3
- switch (action) {
4
- case "list": return client.call("backup/list");
5
- case "copy": return client.call("backup/copyToSnapshot", { backupToken: flags["backupToken"] });
6
- default: throw new Error(`Unknown backup action: ${action}. Valid: list, copy`);
7
- }
8
- }
9
- //#endregion
10
- export { run };
11
-
12
- //# sourceMappingURL=backup-D1UJ4aap.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"backup-D1UJ4aap.mjs","names":[],"sources":["../src/commands/backup.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\nimport type { Backup, KiwiVMResponse } from \"../types.ts\";\n\ninterface BackupListResponse extends KiwiVMResponse {\n backups: Backup[];\n}\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"list\":\n return client.call<BackupListResponse>(\"backup/list\");\n case \"copy\":\n return client.call(\"backup/copyToSnapshot\", {\n backupToken: flags[\"backupToken\"],\n });\n default:\n throw new Error(`Unknown backup action: ${action}. Valid: list, copy`);\n }\n}\n"],"mappings":";AAOA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,OACH,QAAO,OAAO,KAAyB,cAAc;EACvD,KAAK,OACH,QAAO,OAAO,KAAK,yBAAyB,EAC1C,aAAa,MAAM,gBACpB,CAAC;EACJ,QACE,OAAM,IAAI,MAAM,0BAA0B,OAAO,qBAAqB"}
@@ -1,40 +0,0 @@
1
- //#region src/commands/help.ts
2
- const HELP = `Usage: kiwivm-cli <category> <action> [--flags...]
3
-
4
- Auth: --veid <VEID> --api-key <KEY> (or KIWIVM_VEID / KIWIVM_API_KEY env vars)
5
-
6
- Categories:
7
-
8
- power start | stop | restart | kill
9
- info (no action) | live
10
- snapshot create | list | delete | restore | sticky | export | import
11
- backup list | copy
12
- system hostname | rdns | password | sshkey | os | reinstall
13
- network ipv6-add | ipv6-delete | private-list | private-assign | private-delete
14
- monitoring usage | audit | rate-limit
15
- admin suspensions | unsuspend | resolve | resolve-violation
16
-
17
- Flags:
18
-
19
- --description Snapshot description (snapshot create)
20
- --snapshot Snapshot file name (snapshot delete/restore/sticky/export)
21
- --sticky 0 or 1 (snapshot sticky)
22
- --source-veid Source VEID (snapshot import)
23
- --source-token Source token (snapshot import)
24
- --backup-token Backup token (backup copy)
25
- --new-hostname New hostname (system hostname)
26
- --ip IP address (system rdns, network ipv6-delete/private-assign/private-delete)
27
- --ptr PTR/rDNS record (system rdns)
28
- --ssh-keys SSH keys (system sshkey update)
29
- --os OS template name (system reinstall)
30
- --record-id Record ID (admin unsuspend/resolve-violation)
31
-
32
- Output: JSON to stdout. Errors to stderr with exit code 1.
33
- `;
34
- async function run() {
35
- return HELP;
36
- }
37
- //#endregion
38
- export { run };
39
-
40
- //# sourceMappingURL=help-Dk-WApoi.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"help-Dk-WApoi.mjs","names":[],"sources":["../src/commands/help.ts"],"sourcesContent":["const HELP = `Usage: kiwivm-cli <category> <action> [--flags...]\n\nAuth: --veid <VEID> --api-key <KEY> (or KIWIVM_VEID / KIWIVM_API_KEY env vars)\n\nCategories:\n\n power start | stop | restart | kill\n info (no action) | live\n snapshot create | list | delete | restore | sticky | export | import\n backup list | copy\n system hostname | rdns | password | sshkey | os | reinstall\n network ipv6-add | ipv6-delete | private-list | private-assign | private-delete\n monitoring usage | audit | rate-limit\n admin suspensions | unsuspend | resolve | resolve-violation\n\nFlags:\n\n --description Snapshot description (snapshot create)\n --snapshot Snapshot file name (snapshot delete/restore/sticky/export)\n --sticky 0 or 1 (snapshot sticky)\n --source-veid Source VEID (snapshot import)\n --source-token Source token (snapshot import)\n --backup-token Backup token (backup copy)\n --new-hostname New hostname (system hostname)\n --ip IP address (system rdns, network ipv6-delete/private-assign/private-delete)\n --ptr PTR/rDNS record (system rdns)\n --ssh-keys SSH keys (system sshkey update)\n --os OS template name (system reinstall)\n --record-id Record ID (admin unsuspend/resolve-violation)\n\nOutput: JSON to stdout. Errors to stderr with exit code 1.\n`;\n\nexport async function run(): Promise<string> {\n return HELP;\n}\n"],"mappings":";AAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCb,eAAsB,MAAuB;AAC3C,QAAO"}
@@ -1,13 +0,0 @@
1
- //#region src/commands/info.ts
2
- async function run(action, _flags, client) {
3
- switch (action) {
4
- case "live": return client.call("getLiveServiceInfo");
5
- case "":
6
- case "info": return client.call("getServiceInfo");
7
- default: throw new Error(`Unknown info action: ${action}. Valid: (no action), live`);
8
- }
9
- }
10
- //#endregion
11
- export { run };
12
-
13
- //# sourceMappingURL=info-DKExtFYH.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"info-DKExtFYH.mjs","names":[],"sources":["../src/commands/info.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\nimport type { LiveServiceInfo, ServiceInfo } from \"../types.ts\";\n\nexport async function run(\n action: string,\n _flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"live\":\n return client.call<LiveServiceInfo>(\"getLiveServiceInfo\");\n case \"\":\n case \"info\":\n return client.call<ServiceInfo>(\"getServiceInfo\");\n default:\n throw new Error(\n `Unknown info action: ${action}. Valid: (no action), live`,\n );\n }\n}\n"],"mappings":";AAGA,eAAsB,IACpB,QACA,QACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,OACH,QAAO,OAAO,KAAsB,qBAAqB;EAC3D,KAAK;EACL,KAAK,OACH,QAAO,OAAO,KAAkB,iBAAiB;EACnD,QACE,OAAM,IAAI,MACR,wBAAwB,OAAO,4BAChC"}
@@ -1,13 +0,0 @@
1
- //#region src/commands/monitoring.ts
2
- async function run(action, _flags, client) {
3
- switch (action) {
4
- case "usage": return client.call("getRawUsageStats");
5
- case "audit": return client.call("getAuditLog");
6
- case "rate-limit": return client.call("getRateLimitStatus");
7
- default: throw new Error(`Unknown monitoring action: ${action}. Valid: usage, audit, rate-limit`);
8
- }
9
- }
10
- //#endregion
11
- export { run };
12
-
13
- //# sourceMappingURL=monitoring-BSuv8fj9.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"monitoring-BSuv8fj9.mjs","names":[],"sources":["../src/commands/monitoring.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n _flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"usage\":\n return client.call(\"getRawUsageStats\");\n case \"audit\":\n return client.call(\"getAuditLog\");\n case \"rate-limit\":\n return client.call(\"getRateLimitStatus\");\n default:\n throw new Error(\n `Unknown monitoring action: ${action}. Valid: usage, audit, rate-limit`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,QACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,QACH,QAAO,OAAO,KAAK,mBAAmB;EACxC,KAAK,QACH,QAAO,OAAO,KAAK,cAAc;EACnC,KAAK,aACH,QAAO,OAAO,KAAK,qBAAqB;EAC1C,QACE,OAAM,IAAI,MACR,8BAA8B,OAAO,mCACtC"}
@@ -1,15 +0,0 @@
1
- //#region src/commands/network.ts
2
- async function run(action, flags, client) {
3
- switch (action) {
4
- case "ipv6-add": return client.call("ipv6/add");
5
- case "ipv6-delete": return client.call("ipv6/delete", { ip: flags["ip"] });
6
- case "private-list": return client.call("privateIp/getAvailableIps");
7
- case "private-assign": return client.call("privateIp/assign", { ip: flags["ip"] });
8
- case "private-delete": return client.call("privateIp/delete", { ip: flags["ip"] });
9
- default: throw new Error(`Unknown network action: ${action}. Valid: ipv6-add, ipv6-delete, private-list, private-assign, private-delete`);
10
- }
11
- }
12
- //#endregion
13
- export { run };
14
-
15
- //# sourceMappingURL=network-1ycEIJqT.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"network-1ycEIJqT.mjs","names":[],"sources":["../src/commands/network.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"ipv6-add\":\n return client.call(\"ipv6/add\");\n case \"ipv6-delete\":\n return client.call(\"ipv6/delete\", { ip: flags[\"ip\"] });\n case \"private-list\":\n return client.call(\"privateIp/getAvailableIps\");\n case \"private-assign\":\n return client.call(\"privateIp/assign\", { ip: flags[\"ip\"] });\n case \"private-delete\":\n return client.call(\"privateIp/delete\", { ip: flags[\"ip\"] });\n default:\n throw new Error(\n `Unknown network action: ${action}. Valid: ipv6-add, ipv6-delete, private-list, private-assign, private-delete`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,WACH,QAAO,OAAO,KAAK,WAAW;EAChC,KAAK,cACH,QAAO,OAAO,KAAK,eAAe,EAAE,IAAI,MAAM,OAAO,CAAC;EACxD,KAAK,eACH,QAAO,OAAO,KAAK,4BAA4B;EACjD,KAAK,iBACH,QAAO,OAAO,KAAK,oBAAoB,EAAE,IAAI,MAAM,OAAO,CAAC;EAC7D,KAAK,iBACH,QAAO,OAAO,KAAK,oBAAoB,EAAE,IAAI,MAAM,OAAO,CAAC;EAC7D,QACE,OAAM,IAAI,MACR,2BAA2B,OAAO,8EACnC"}
@@ -1,14 +0,0 @@
1
- //#region src/commands/power.ts
2
- async function run(action, _flags, client) {
3
- switch (action) {
4
- case "start": return client.call("start");
5
- case "stop": return client.call("stop");
6
- case "restart": return client.call("restart");
7
- case "kill": return client.call("kill");
8
- default: throw new Error(`Unknown power action: ${action}. Valid: start, stop, restart, kill`);
9
- }
10
- }
11
- //#endregion
12
- export { run };
13
-
14
- //# sourceMappingURL=power-CDg0Mx1A.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"power-CDg0Mx1A.mjs","names":[],"sources":["../src/commands/power.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n _flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"start\":\n return client.call(\"start\");\n case \"stop\":\n return client.call(\"stop\");\n case \"restart\":\n return client.call(\"restart\");\n case \"kill\":\n return client.call(\"kill\");\n default:\n throw new Error(\n `Unknown power action: ${action}. Valid: start, stop, restart, kill`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,QACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,QACH,QAAO,OAAO,KAAK,QAAQ;EAC7B,KAAK,OACH,QAAO,OAAO,KAAK,OAAO;EAC5B,KAAK,UACH,QAAO,OAAO,KAAK,UAAU;EAC/B,KAAK,OACH,QAAO,OAAO,KAAK,OAAO;EAC5B,QACE,OAAM,IAAI,MACR,yBAAyB,OAAO,qCACjC"}
@@ -1,23 +0,0 @@
1
- //#region src/commands/snapshot.ts
2
- async function run(action, flags, client) {
3
- switch (action) {
4
- case "create": return client.call("snapshot/create", { description: flags["description"] });
5
- case "list": return client.call("snapshot/list");
6
- case "delete": return client.call("snapshot/delete", { snapshot: flags["snapshot"] });
7
- case "restore": return client.call("snapshot/restore", { snapshot: flags["snapshot"] });
8
- case "sticky": return client.call("snapshot/toggleSticky", {
9
- snapshot: flags["snapshot"],
10
- sticky: flags["sticky"] !== void 0 ? Number(flags["sticky"]) : void 0
11
- });
12
- case "export": return client.call("snapshot/export", { snapshot: flags["snapshot"] });
13
- case "import": return client.call("snapshot/import", {
14
- sourceVeid: flags["sourceVeid"],
15
- sourceToken: flags["sourceToken"]
16
- });
17
- default: throw new Error(`Unknown snapshot action: ${action}. Valid: create, list, delete, restore, sticky, export, import`);
18
- }
19
- }
20
- //#endregion
21
- export { run };
22
-
23
- //# sourceMappingURL=snapshot-LO_ufoj5.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"snapshot-LO_ufoj5.mjs","names":[],"sources":["../src/commands/snapshot.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\nimport type { KiwiVMResponse, Snapshot } from \"../types.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"create\":\n return client.call(\"snapshot/create\", {\n description: flags[\"description\"],\n });\n case \"list\":\n return client.call<KiwiVMResponse & { snapshots: Snapshot[] }>(\n \"snapshot/list\",\n );\n case \"delete\":\n return client.call(\"snapshot/delete\", { snapshot: flags[\"snapshot\"] });\n case \"restore\":\n return client.call(\"snapshot/restore\", { snapshot: flags[\"snapshot\"] });\n case \"sticky\":\n return client.call(\"snapshot/toggleSticky\", {\n snapshot: flags[\"snapshot\"],\n sticky:\n flags[\"sticky\"] !== undefined ? Number(flags[\"sticky\"]) : undefined,\n });\n case \"export\":\n return client.call(\"snapshot/export\", { snapshot: flags[\"snapshot\"] });\n case \"import\":\n return client.call(\"snapshot/import\", {\n sourceVeid: flags[\"sourceVeid\"],\n sourceToken: flags[\"sourceToken\"],\n });\n default:\n throw new Error(\n `Unknown snapshot action: ${action}. Valid: create, list, delete, restore, sticky, export, import`,\n );\n }\n}\n"],"mappings":";AAGA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB,EACpC,aAAa,MAAM,gBACpB,CAAC;EACJ,KAAK,OACH,QAAO,OAAO,KACZ,gBACD;EACH,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB,EAAE,UAAU,MAAM,aAAa,CAAC;EACxE,KAAK,UACH,QAAO,OAAO,KAAK,oBAAoB,EAAE,UAAU,MAAM,aAAa,CAAC;EACzE,KAAK,SACH,QAAO,OAAO,KAAK,yBAAyB;GAC1C,UAAU,MAAM;GAChB,QACE,MAAM,cAAc,KAAA,IAAY,OAAO,MAAM,UAAU,GAAG,KAAA;GAC7D,CAAC;EACJ,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB,EAAE,UAAU,MAAM,aAAa,CAAC;EACxE,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB;GACpC,YAAY,MAAM;GAClB,aAAa,MAAM;GACpB,CAAC;EACJ,QACE,OAAM,IAAI,MACR,4BAA4B,OAAO,gEACpC"}
@@ -1,21 +0,0 @@
1
- //#region src/commands/system.ts
2
- async function run(action, flags, client) {
3
- switch (action) {
4
- case "hostname": return client.call("setHostname", { newHostname: flags["newHostname"] });
5
- case "rdns": return client.call("setPTR", {
6
- ip: flags["ip"],
7
- ptr: flags["ptr"]
8
- });
9
- case "password": return client.call("resetRootPassword");
10
- case "sshkey":
11
- if (flags["sshKeys"] !== void 0) return client.call("updateSshKeys", { sshKeys: flags["sshKeys"] });
12
- return client.call("getSshKeys");
13
- case "os": return client.call("getAvailableOS");
14
- case "reinstall": return client.call("reinstallOS", { os: flags["os"] });
15
- default: throw new Error(`Unknown system action: ${action}. Valid: hostname, rdns, password, sshkey, os, reinstall`);
16
- }
17
- }
18
- //#endregion
19
- export { run };
20
-
21
- //# sourceMappingURL=system-Bl-dsqX9.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"system-Bl-dsqX9.mjs","names":[],"sources":["../src/commands/system.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"hostname\":\n return client.call(\"setHostname\", { newHostname: flags[\"newHostname\"] });\n case \"rdns\":\n return client.call(\"setPTR\", { ip: flags[\"ip\"], ptr: flags[\"ptr\"] });\n case \"password\":\n return client.call(\"resetRootPassword\");\n case \"sshkey\":\n if (flags[\"sshKeys\"] !== undefined) {\n return client.call(\"updateSshKeys\", { sshKeys: flags[\"sshKeys\"] });\n }\n return client.call(\"getSshKeys\");\n case \"os\":\n return client.call(\"getAvailableOS\");\n case \"reinstall\":\n return client.call(\"reinstallOS\", { os: flags[\"os\"] });\n default:\n throw new Error(\n `Unknown system action: ${action}. Valid: hostname, rdns, password, sshkey, os, reinstall`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,WACH,QAAO,OAAO,KAAK,eAAe,EAAE,aAAa,MAAM,gBAAgB,CAAC;EAC1E,KAAK,OACH,QAAO,OAAO,KAAK,UAAU;GAAE,IAAI,MAAM;GAAO,KAAK,MAAM;GAAQ,CAAC;EACtE,KAAK,WACH,QAAO,OAAO,KAAK,oBAAoB;EACzC,KAAK;AACH,OAAI,MAAM,eAAe,KAAA,EACvB,QAAO,OAAO,KAAK,iBAAiB,EAAE,SAAS,MAAM,YAAY,CAAC;AAEpE,UAAO,OAAO,KAAK,aAAa;EAClC,KAAK,KACH,QAAO,OAAO,KAAK,iBAAiB;EACtC,KAAK,YACH,QAAO,OAAO,KAAK,eAAe,EAAE,IAAI,MAAM,OAAO,CAAC;EACxD,QACE,OAAM,IAAI,MACR,0BAA0B,OAAO,0DAClC"}
@@ -1,82 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import type { KiwiVMClient } from "../client.ts";
3
- import { run } from "./monitoring.ts";
4
-
5
- function mockClient() {
6
- const call = vi.fn();
7
- return { client: { call } as unknown as KiwiVMClient, call };
8
- }
9
-
10
- describe("monitoring command", () => {
11
- describe("usage", () => {
12
- it("calls getRawUsageStats", async () => {
13
- const { client, call } = mockClient();
14
- call.mockResolvedValueOnce({
15
- error: 0,
16
- data: [{ month: "2025-01", usage: 100 }],
17
- });
18
-
19
- const result = await run("usage", {}, client);
20
-
21
- expect(client.call).toHaveBeenCalledExactlyOnceWith("getRawUsageStats");
22
- expect(result).toMatchObject({
23
- data: [{ month: "2025-01", usage: 100 }],
24
- });
25
- });
26
- });
27
-
28
- describe("audit", () => {
29
- it("calls getAuditLog", async () => {
30
- const { client, call } = mockClient();
31
- call.mockResolvedValueOnce({
32
- error: 0,
33
- logs: [{ timestamp: 1700000000, action: "restart" }],
34
- });
35
-
36
- const result = await run("audit", {}, client);
37
-
38
- expect(client.call).toHaveBeenCalledExactlyOnceWith("getAuditLog");
39
- expect(result).toMatchObject({
40
- logs: [{ timestamp: 1700000000, action: "restart" }],
41
- });
42
- });
43
- });
44
-
45
- describe("rate-limit", () => {
46
- it("calls getRateLimitStatus", async () => {
47
- const { client, call } = mockClient();
48
- call.mockResolvedValueOnce({
49
- error: 0,
50
- remaining: 950,
51
- limit: 1000,
52
- });
53
-
54
- const result = await run("rate-limit", {}, client);
55
-
56
- expect(client.call).toHaveBeenCalledExactlyOnceWith("getRateLimitStatus");
57
- expect(result).toMatchObject({ remaining: 950, limit: 1000 });
58
- });
59
- });
60
-
61
- it("returns the complete API response", async () => {
62
- const { client, call } = mockClient();
63
- const apiResponse = {
64
- error: 0,
65
- remaining: 500,
66
- limit: 1000,
67
- reset: 1700000000,
68
- };
69
- call.mockResolvedValueOnce(apiResponse);
70
-
71
- const result = await run("rate-limit", {}, client);
72
-
73
- expect(result).toEqual(apiResponse);
74
- });
75
-
76
- it("propagates errors from the client", async () => {
77
- const { client, call } = mockClient();
78
- call.mockRejectedValueOnce(new Error("Rate limited"));
79
-
80
- await expect(run("audit", {}, client)).rejects.toThrow("Rate limited");
81
- });
82
- });