@pelican.ts/sdk 0.4.14 → 0.4.16-next.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.
@@ -1,1096 +1,581 @@
1
- // src/api/client/account.ts
1
+ // src/api/application/database_hosts.ts
2
2
  import z from "zod";
3
- var Account = class {
3
+ var DatabaseHosts = class {
4
4
  r;
5
- constructor(requester) {
6
- this.r = requester;
5
+ constructor(r) {
6
+ this.r = r;
7
7
  }
8
- info = async () => {
9
- const { data } = await this.r.get("/account");
10
- return data.attributes;
8
+ list = async (page = 1) => {
9
+ const { data } = await this.r.get("/database-hosts", { params: { page } });
10
+ return data.data.map((d) => d.attributes);
11
11
  };
12
- updateEmail = async (newEmail, password) => {
13
- newEmail = z.email().parse(newEmail);
14
- await this.r.put("/account/email", { email: newEmail, password });
12
+ info = async (id) => {
13
+ const { data } = await this.r.get(`/database-hosts/${id}`);
14
+ return data.attributes;
15
15
  };
16
- updatePassword = async (newPassword) => {
17
- newPassword = z.string().min(8).parse(newPassword);
18
- await this.r.put("/account/password", {
19
- password: newPassword,
20
- password_confirmation: newPassword
16
+ // TODO: find out why API returns 500
17
+ create = async (opts) => {
18
+ opts = CreateDBHostSchema.parse(opts);
19
+ await this.r.post(
20
+ "/database-hosts",
21
+ opts
22
+ ).catch((e) => {
21
23
  });
22
24
  };
23
- apiKeys = {
24
- list: async () => {
25
- const { data } = await this.r.get("/account/api-keys");
26
- return data.data.map((k) => k.attributes);
27
- },
28
- create: async (description, allowed_ips) => {
29
- allowed_ips = z.array(z.ipv4()).optional().parse(allowed_ips);
30
- const { data } = await this.r.post("/account/api-keys", { description, allowed_ips });
31
- return { ...data.attributes, secret_token: data.meta.secret_token };
32
- },
33
- delete: async (identifier) => {
34
- await this.r.delete(`/account/api-keys/${identifier}`);
35
- }
25
+ update = async (id, opts) => {
26
+ opts = CreateDBHostSchema.parse(opts);
27
+ const { data } = await this.r.patch(`/database-hosts/${id}`, opts);
28
+ return data.attributes;
36
29
  };
37
- sshKeys = {
38
- list: async () => {
39
- const { data } = await this.r.get("/account/ssh-keys");
40
- return data.data.map((k) => k.attributes);
41
- },
42
- create: async (name, public_key) => {
43
- const { data } = await this.r.post("/account/ssh-keys", { name, public_key });
44
- return data.attributes;
45
- },
46
- delete: async (fingerprint) => {
47
- await this.r.delete(`/account/ssh-keys/${fingerprint}`);
48
- }
30
+ delete = async (id) => {
31
+ await this.r.delete(`/database-hosts/${id}`);
49
32
  };
50
33
  };
34
+ var CreateDBHostSchema = z.object({
35
+ name: z.string().min(1).max(255),
36
+ host: z.string(),
37
+ port: z.number().min(1).max(65535),
38
+ username: z.string().min(1).max(255),
39
+ password: z.string().optional(),
40
+ node_ids: z.array(z.string()).optional(),
41
+ max_databases: z.number().optional()
42
+ });
51
43
 
52
- // src/api/client/client.ts
53
- import z5 from "zod";
54
-
55
- // src/api/client/server_databases.ts
56
- import z2 from "zod";
57
- var ServerDatabases = class {
44
+ // src/api/application/eggs.ts
45
+ var Eggs = class {
58
46
  r;
59
- id;
60
- constructor(requester, id) {
61
- this.r = requester;
62
- this.id = id;
47
+ constructor(r) {
48
+ this.r = r;
63
49
  }
64
- list = async (include, page = 1) => {
65
- z2.number().positive().parse(page);
66
- const { data } = await this.r.get(`/servers/${this.id}/databases`, {
67
- params: { include: include?.join(","), page }
68
- });
50
+ list = async () => {
51
+ const { data } = await this.r.get(
52
+ "/eggs"
53
+ );
69
54
  return data.data.map((d) => d.attributes);
70
55
  };
71
- create = async (database, remote) => {
72
- const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote });
56
+ info = async (id) => {
57
+ const { data } = await this.r.get(
58
+ `/eggs/${id}`
59
+ );
73
60
  return data.attributes;
74
61
  };
75
- rotatePassword = async (database_id) => {
76
- const { data } = await this.r.post(`/servers/${this.id}/databases/${database_id}/rotate-password`);
77
- return data.attributes;
62
+ export = async (id, format) => {
63
+ const { data } = await this.r.get(`/eggs/${id}/export`, {
64
+ params: { format },
65
+ transformResponse: (r) => r
66
+ });
67
+ return data;
78
68
  };
79
- delete = async (database_id) => {
80
- await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
69
+ infoExportable = async (id) => {
70
+ const { data } = await this.r.get(`/eggs/${id}/export`, {
71
+ params: { format: "json" }
72
+ });
73
+ return data;
81
74
  };
82
75
  };
83
76
 
84
- // src/api/client/server_files.ts
85
- import axios from "axios";
86
- var ServerFiles = class {
77
+ // src/api/application/mounts.ts
78
+ import z2 from "zod";
79
+ var Mounts = class {
87
80
  r;
88
- id;
89
- constructor(requester, id) {
90
- this.r = requester;
91
- this.id = id;
81
+ constructor(r) {
82
+ this.r = r;
92
83
  }
93
- list = async (path) => {
94
- const { data } = await this.r.get(`/servers/${this.id}/files/list`, { params: { directory: path } });
95
- return data.data.map((r) => r.attributes);
84
+ list = async () => {
85
+ const { data } = await this.r.get("/mounts");
86
+ return data.data.map((d) => d.attributes);
96
87
  };
97
- /**
98
- * Return the contents of a file. To read binary file (non-editable) use {@link download} instead
99
- */
100
- contents = async (path) => {
88
+ info = async (id) => {
101
89
  const { data } = await this.r.get(
102
- `/servers/${this.id}/files/contents`,
103
- { params: { file: path } }
90
+ `/mounts/${id}`
104
91
  );
105
- return data;
106
- };
107
- downloadGetUrl = async (path) => {
108
- const { data } = await this.r.get(`/servers/${this.id}/files/download`, { params: { file: path } });
109
- return data.attributes.url;
92
+ return data.attributes;
110
93
  };
111
- download = async (path) => {
112
- const url = await this.downloadGetUrl(path);
113
- const { data } = await axios.get(url, {
114
- responseType: "arraybuffer"
115
- });
116
- return data;
94
+ create = async (opts) => {
95
+ opts = CreateMountSchema.parse(opts);
96
+ const { data } = await this.r.post(
97
+ "/mounts",
98
+ opts
99
+ );
100
+ return data.attributes;
117
101
  };
118
- rename = async (root = "/", files) => {
119
- await this.r.put(`/servers/${this.id}/files/rename`, { root, files });
102
+ update = async (id, opts) => {
103
+ opts = CreateMountSchema.parse(opts);
104
+ const { data } = await this.r.patch(
105
+ `/mounts/${id}`,
106
+ opts
107
+ );
108
+ return data.attributes;
120
109
  };
121
- copy = async (location) => {
122
- await this.r.post(`/servers/${this.id}/files/copy`, { location });
110
+ delete = async (id) => {
111
+ await this.r.delete(`/mounts/${id}`);
123
112
  };
124
- write = async (path, content) => {
125
- await this.r.post(`/servers/${this.id}/files/write`, content, {
126
- params: { file: path }
127
- });
113
+ listAssignedEggs = async (id) => {
114
+ const { data } = await this.r.get(`/mounts/${id}/eggs`);
115
+ return data.data.map((d) => d.attributes);
128
116
  };
129
- compress = async (root = "/", files, archive_name, extension) => {
130
- const { data } = await this.r.post(`/servers/${this.id}/files/compress`, {
131
- root,
132
- files,
133
- archive_name,
134
- extension
135
- });
136
- return data.attributes;
117
+ assignEggs = async (id, eggs) => {
118
+ await this.r.post(`/mounts/${id}/eggs`, { eggs });
137
119
  };
138
- decompress = async (root = "/", file) => {
139
- await this.r.post(`/servers/${this.id}/files/decompress`, { root, file });
120
+ unassignEgg = async (id, egg_id) => {
121
+ await this.r.delete(`/mounts/${id}/eggs/${egg_id}`);
140
122
  };
141
- delete = async (root = "/", files) => {
142
- await this.r.post(`/servers/${this.id}/files/delete`, { root, files });
123
+ listAssignedNodes = async (id) => {
124
+ const { data } = await this.r.get(`/mounts/${id}/nodes`);
125
+ return data.data.map((d) => d.attributes);
143
126
  };
144
- createFolder = async (root = "/", name) => {
145
- await this.r.post(`/servers/${this.id}/files/create-folder`, {
146
- root,
147
- name
148
- });
127
+ assignNodes = async (id, nodes) => {
128
+ await this.r.post(`/mounts/${id}/nodes`, { nodes });
149
129
  };
150
- chmod = async (root = "/", files) => {
151
- await this.r.post(`/servers/${this.id}/files/chmod`, { root, files });
130
+ unassignNode = async (id, node_id) => {
131
+ await this.r.delete(`/mounts/${id}/nodes/${node_id}`);
152
132
  };
153
- pullFromRemote = async (url, directory, filename, use_header = false, foreground = false) => {
154
- await this.r.post(`/servers/${this.id}/files/pull`, {
155
- url,
156
- directory,
157
- filename,
158
- use_header,
159
- foreground
160
- });
133
+ listAssignedServers = async (id) => {
134
+ const { data } = await this.r.get(`/mounts/${id}/servers`);
135
+ return data.data.map((d) => d.attributes);
161
136
  };
162
- uploadGetUrl = async () => {
163
- const { data } = await this.r.get(`/servers/${this.id}/files/upload`);
164
- return data.attributes.url;
137
+ assignServers = async (id, servers) => {
138
+ await this.r.post(`/mounts/${id}/servers`, { servers });
165
139
  };
166
- upload = async (file, root = "/") => {
167
- const url = await this.uploadGetUrl();
168
- await axios.post(
169
- url,
170
- { files: file },
171
- {
172
- headers: { "Content-Type": "multipart/form-data" },
173
- params: { directory: root }
174
- }
175
- );
140
+ unassignServer = async (id, server_id) => {
141
+ await this.r.delete(`/mounts/${id}/servers/${server_id}`);
176
142
  };
177
143
  };
144
+ var CreateMountSchema = z2.object({
145
+ name: z2.string().min(1).max(255),
146
+ description: z2.string().optional(),
147
+ source: z2.string(),
148
+ target: z2.string(),
149
+ read_only: z2.boolean().optional()
150
+ });
178
151
 
179
- // src/api/client/server_schedules.ts
180
- var ServerSchedules = class {
152
+ // src/api/application/nodes.ts
153
+ import z4 from "zod";
154
+
155
+ // src/api/application/nodes_allocations.ts
156
+ import z3 from "zod";
157
+ var NodesAllocations = class {
181
158
  r;
182
159
  id;
183
160
  constructor(requester, id) {
184
161
  this.r = requester;
185
162
  this.id = id;
186
163
  }
187
- list = async () => {
188
- const { data } = await this.r.get(`/servers/${this.id}/schedules`);
164
+ list = async (include) => {
165
+ const { data } = await this.r.get(`/nodes/${this.id}/allocations`, {
166
+ params: { include: include?.join(",") }
167
+ });
189
168
  return data.data.map((d) => d.attributes);
190
169
  };
191
- create = async (params) => {
192
- const { data } = await this.r.post(`/servers/${this.id}/schedules`, params);
193
- return data.attributes;
170
+ create = async (ip, ports, alias) => {
171
+ z3.ipv4().parse(ip);
172
+ z3.ipv4().or(z3.url().max(255)).optional().parse(alias);
173
+ z3.array(z3.number()).or(z3.string().regex(/\d+-\d+/)).parse(ports);
174
+ await this.r.post(`/nodes/${this.id}/allocations`, { ip, ports, alias });
175
+ };
176
+ delete = async (alloc_id) => {
177
+ await this.r.delete(`/nodes/${this.id}/allocations/${alloc_id}`);
194
178
  };
195
- control = (sched_id) => new ScheduleControl(this.r, this.id, sched_id);
196
179
  };
197
- var ScheduleControl = class {
180
+
181
+ // src/api/application/nodes.ts
182
+ var Nodes = class {
198
183
  r;
199
- id;
200
- sched_id;
201
- constructor(requester, id, sched_id) {
184
+ constructor(requester) {
202
185
  this.r = requester;
203
- this.id = id;
204
- this.sched_id = sched_id;
205
186
  }
206
- info = async () => {
207
- const { data } = await this.r.get(`/servers/${this.id}/schedules/${this.sched_id}`);
187
+ list = async (include, page = 1) => {
188
+ z4.number().positive().parse(page);
189
+ const { data } = await this.r.get("/nodes", { params: { include: include?.join(","), page } });
190
+ return data.data.map((s) => s.attributes);
191
+ };
192
+ listDeployable = async (filters, include, page = 1) => {
193
+ z4.number().positive().parse(page);
194
+ const { data } = await this.r.get("/nodes/deployable", {
195
+ params: {
196
+ include: include?.join(","),
197
+ disk: filters.disk,
198
+ memory: filters.memory,
199
+ cpu: filters.cpu,
200
+ location_ids: filters.location_ids,
201
+ tags: filters.tags,
202
+ page
203
+ }
204
+ });
205
+ return data.data.map((s) => s.attributes);
206
+ };
207
+ info = async (id, include) => {
208
+ z4.number().positive().parse(id);
209
+ const { data } = await this.r.get(
210
+ `/nodes/${id}`,
211
+ { params: { include: include?.join(",") } }
212
+ );
208
213
  return data.attributes;
209
214
  };
210
- update = async (params) => {
211
- const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}`, params);
215
+ create = async (node) => {
216
+ node = NodeCreateSchema.parse(node);
217
+ const { data } = await this.r.post(
218
+ "/nodes",
219
+ node
220
+ );
212
221
  return data.attributes;
213
222
  };
214
- delete = async () => {
215
- await this.r.delete(`/servers/${this.id}/schedules/${this.sched_id}`);
223
+ get_configuration = async (id) => {
224
+ z4.number().positive().parse(id);
225
+ const { data } = await this.r.get(
226
+ `/nodes/${id}/configuration`
227
+ );
228
+ return data;
216
229
  };
217
- execute = async () => {
218
- await this.r.post(
219
- `/servers/${this.id}/schedules/${this.sched_id}/execute`
230
+ update = async (id, node) => {
231
+ z4.number().positive().parse(id);
232
+ node = NodeCreateSchema.parse(node);
233
+ const { data } = await this.r.patch(
234
+ `/nodes/${id}`,
235
+ node
220
236
  );
237
+ return data.attributes;
221
238
  };
222
- tasks = {
223
- create: async (opts) => {
224
- const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}/tasks`, opts);
225
- return data.attributes;
226
- },
227
- update: async (task_id, opts) => {
228
- const { data } = await this.r.post(
229
- `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`,
230
- opts
231
- );
232
- return data.attributes;
233
- },
234
- delete: async (task_id) => {
235
- await this.r.delete(
236
- `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`
237
- );
238
- }
239
+ delete = async (id) => {
240
+ z4.number().positive().parse(id);
241
+ await this.r.delete(`/nodes/${id}`);
239
242
  };
243
+ allocations = (server_id) => new NodesAllocations(this.r, server_id);
240
244
  };
245
+ var NodeCreateSchema = z4.object({
246
+ name: z4.string().min(1).max(100),
247
+ description: z4.string().optional(),
248
+ public: z4.boolean().optional(),
249
+ fqdn: z4.string().nonempty(),
250
+ scheme: z4.enum(["http", "https"]),
251
+ behind_proxy: z4.boolean().optional(),
252
+ memory: z4.number().min(0),
253
+ memory_overallocate: z4.number().min(-1),
254
+ disk: z4.number().min(0),
255
+ disk_overallocate: z4.number().min(-1),
256
+ cpu: z4.number().min(0),
257
+ cpu_overallocate: z4.number().min(-1),
258
+ daemon_base: z4.string().nonempty().optional(),
259
+ daemon_sftp: z4.number().min(1).max(65535),
260
+ daemon_sftp_alias: z4.string().optional(),
261
+ daemon_listen: z4.number().min(1).max(65535),
262
+ daemon_connect: z4.number().min(1).max(65535),
263
+ maintenance_mode: z4.boolean().optional(),
264
+ upload_size: z4.number().min(1).max(1024),
265
+ tags: z4.array(z4.string()).optional()
266
+ });
241
267
 
242
- // src/api/client/server_allocations.ts
243
- var ServerAllocations = class {
268
+ // src/api/application/roles.ts
269
+ var Roles = class {
244
270
  r;
245
- id;
246
- constructor(requester, id) {
247
- this.r = requester;
248
- this.id = id;
271
+ constructor(r) {
272
+ this.r = r;
249
273
  }
250
- list = async () => {
251
- const { data } = await this.r.get(`/servers/${this.id}/network/allocations`);
274
+ list = async (page = 1) => {
275
+ const { data } = await this.r.get(`/roles`, { params: { page } });
252
276
  return data.data.map((r) => r.attributes);
253
277
  };
254
- autoAssign = async () => {
255
- const { data } = await this.r.post(`/servers/${this.id}/network/allocations`);
278
+ info = async (id) => {
279
+ const { data } = await this.r.get(
280
+ `/roles/${id}`
281
+ );
256
282
  return data.attributes;
257
283
  };
258
- setNotes = async (alloc_id, notes) => {
259
- const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}`, { notes });
260
- return data.attributes;
284
+ create = async (opts) => {
285
+ await this.r.post(`/roles`, opts);
261
286
  };
262
- setPrimary = async (alloc_id) => {
263
- const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}/primary`);
264
- return data.attributes;
287
+ update = async (id, opts) => {
288
+ await this.r.patch(`/roles/${id}`, opts);
265
289
  };
266
- unassign = async (alloc_id) => {
267
- await this.r.delete(
268
- `/servers/${this.id}/network/allocations/${alloc_id}`
269
- );
290
+ delete = async (id) => {
291
+ await this.r.delete(`/roles/${id}`);
270
292
  };
271
293
  };
272
294
 
273
- // src/api/client/server_users.ts
274
- var ServerUsers = class {
295
+ // src/api/application/servers.ts
296
+ import z6 from "zod";
297
+
298
+ // src/api/application/servers_databases.ts
299
+ import z5 from "zod";
300
+ var ServersDatabases = class {
275
301
  r;
276
302
  id;
277
- constructor(requester, id) {
278
- this.r = requester;
279
- this.id = id;
303
+ constructor(r, server_id) {
304
+ this.r = r;
305
+ this.id = server_id;
280
306
  }
281
307
  list = async () => {
282
- const { data } = await this.r.get(`/servers/${this.id}/users`);
308
+ const { data } = await this.r.get(`/servers/${this.id}/databases`);
283
309
  return data.data.map((d) => d.attributes);
284
310
  };
285
- create = async (email, permissions) => {
286
- const { data } = await this.r.post(`/servers/${this.id}/users`, { email, permissions });
311
+ create = async (database, remote, host) => {
312
+ database = z5.string().min(1).max(48).parse(database);
313
+ const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote, host });
287
314
  return data.attributes;
288
315
  };
289
- info = async (user_uuid) => {
290
- const { data } = await this.r.get(
291
- `/servers/${this.id}/users/${user_uuid}`
292
- );
316
+ info = async (database_id) => {
317
+ const { data } = await this.r.get(`/servers/${this.id}/databases/${database_id}`);
293
318
  return data.attributes;
294
319
  };
295
- update = async (user_uuid, permissions) => {
296
- const { data } = await this.r.put(
297
- `/servers/${this.id}/users/${user_uuid}`,
298
- { permissions }
299
- );
300
- return data.attributes;
320
+ delete = async (database_id) => {
321
+ await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
301
322
  };
302
- delete = async (user_uuid) => {
303
- await this.r.delete(`/servers/${this.id}/users/${user_uuid}`);
323
+ resetPassword = async (database_id) => {
324
+ await this.r.post(
325
+ `/servers/${this.id}/databases/${database_id}/reset-password`
326
+ );
304
327
  };
305
328
  };
306
329
 
307
- // src/api/client/server_backups.ts
308
- import axios2 from "axios";
309
- import z3 from "zod";
310
- var ServerBackups = class {
330
+ // src/api/application/servers.ts
331
+ var Servers = class {
311
332
  r;
312
333
  id;
313
- constructor(requester, id) {
314
- this.r = requester;
315
- this.id = id;
334
+ databases;
335
+ constructor(r, server_id) {
336
+ this.r = r;
337
+ this.id = server_id;
338
+ this.databases = new ServersDatabases(this.r, this.id);
316
339
  }
317
- list = async (page = 1) => {
318
- z3.number().positive().parse(page);
319
- const { data } = await this.r.get(`/servers/${this.id}/backups`, { params: { page } });
320
- return data.data.map((d) => d.attributes);
321
- };
322
- create = async (args) => {
323
- args.name = z3.string().max(255).optional().parse(args.name);
324
- const { data } = await this.r.post(`/servers/${this.id}/backups`, {
325
- name: args.name,
326
- is_locked: args.is_locked,
327
- ignored_files: args.ignored_files.join("\n")
328
- });
340
+ info = async (include) => {
341
+ const { data } = await this.r.get(`/servers/${this.id}`, { params: { include: include?.join(",") } });
329
342
  return data.attributes;
330
343
  };
331
- info = async (backup_uuid) => {
332
- const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}`);
333
- return data.attributes;
344
+ delete = async (force = false) => {
345
+ await this.r.delete(`/servers/${this.id}${force ? "/force" : ""}`);
334
346
  };
335
- downloadGetUrl = async (backup_uuid) => {
336
- const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}/download`);
337
- return data.attributes.url;
347
+ updateDetails = async (opts) => {
348
+ opts = UpdateDetailsSchema.parse(opts);
349
+ await this.r.patch(`/servers/${this.id}/details`, opts);
338
350
  };
339
- download = async (backup_uuid) => {
340
- const url = await this.downloadGetUrl(backup_uuid);
341
- const { data } = await axios2.get(url, {
342
- responseType: "arraybuffer"
343
- });
344
- return data;
351
+ updateBuild = async (opts) => {
352
+ opts = UpdateBuildSchema.parse(opts);
353
+ await this.r.patch(`/servers/${this.id}/build`, opts);
345
354
  };
346
- delete = async (backup_uuid) => {
347
- await this.r.delete(`/servers/${this.id}/backups/${backup_uuid}`);
355
+ updateStartup = async (opts) => {
356
+ opts = UpdateStartupSchema.parse(opts);
357
+ await this.r.patch(`/servers/${this.id}/startup`, opts);
348
358
  };
349
- rename = async (backup_uuid, name) => {
350
- await this.r.put(`/servers/${this.id}/backups/${backup_uuid}/rename`, {
351
- name
352
- });
359
+ suspend = async () => {
360
+ await this.r.post(`/servers/${this.id}/suspend`);
353
361
  };
354
- toggleLock = async (backup_uuid) => {
355
- await this.r.post(`/servers/${this.id}/backups/${backup_uuid}/lock`);
362
+ unsuspend = async () => {
363
+ await this.r.post(`/servers/${this.id}/unsuspend`);
356
364
  };
357
- restore = async (backup_uuid, truncate) => {
358
- await this.r.post(
359
- `/servers/${this.id}/backups/${backup_uuid}/restore`,
360
- { truncate }
361
- );
365
+ reinstall = async () => {
366
+ await this.r.post(`/servers/${this.id}/reinstall`);
362
367
  };
363
- };
364
-
365
- // src/api/client/server_startup.ts
366
- var ServerStartup = class {
367
- r;
368
- id;
369
- constructor(requester, id) {
370
- this.r = requester;
371
- this.id = id;
372
- }
373
- list = async () => {
374
- const { data } = await this.r.get(`/servers/${this.id}/startup`);
375
- return {
376
- object: "list",
377
- meta: data.meta,
378
- data: data.data.map((d) => d.attributes)
379
- };
368
+ transferStart = async (node_id, allocation_id, allocation_additional) => {
369
+ await this.r.post(`/servers/${this.id}/transfer`, {
370
+ node_id,
371
+ allocation_id,
372
+ allocation_additional
373
+ });
380
374
  };
381
- set = async (key, value) => {
382
- const { data } = await this.r.put(`/servers/${this.id}/startup/variable`, { key, value });
383
- return data.attributes;
384
- };
385
- };
386
-
387
- // src/api/client/server_settings.ts
388
- import z4 from "zod";
389
- var ServerSettings = class {
390
- r;
391
- id;
392
- constructor(requester, id) {
393
- this.r = requester;
394
- this.id = id;
395
- }
396
- rename = async (name) => {
397
- name = z4.string().max(255).parse(name);
398
- await this.r.post(`/servers/${this.id}/settings/rename`, { name });
399
- };
400
- updateDescription = async (description) => {
401
- await this.r.post(`/servers/${this.id}/settings/description`, {
402
- description
403
- });
404
- };
405
- reinstall = async () => {
406
- await this.r.post(`/servers/${this.id}/settings/reinstall`);
407
- };
408
- changeDockerImage = async (image) => {
409
- await this.r.put(`/servers/${this.id}/settings/docker-image`, {
410
- docker_image: image
411
- });
375
+ transferCancel = async () => {
376
+ await this.r.post(`/servers/${this.id}/transfer/cancel`);
412
377
  };
413
378
  };
379
+ var CreateServerSchema = z6.object({
380
+ external_id: z6.string().min(1).max(255).optional(),
381
+ name: z6.string().min(1).max(255),
382
+ description: z6.string().optional(),
383
+ user: z6.number(),
384
+ egg: z6.number(),
385
+ docker_image: z6.string().optional(),
386
+ startup: z6.string().optional(),
387
+ environment: z6.record(z6.string(), z6.string()),
388
+ skip_scripts: z6.boolean().optional(),
389
+ oom_killer: z6.boolean().optional(),
390
+ start_on_completion: z6.boolean().optional(),
391
+ docker_labels: z6.record(z6.string(), z6.string()).optional(),
392
+ limits: z6.object({
393
+ memory: z6.number().min(0),
394
+ swap: z6.number().min(-1),
395
+ disk: z6.number().min(0),
396
+ io: z6.number().min(0),
397
+ threads: z6.string().optional(),
398
+ cpu: z6.number().min(0)
399
+ }),
400
+ feature_limits: z6.object({
401
+ databases: z6.number().min(0),
402
+ allocations: z6.number().min(0),
403
+ backups: z6.number().min(0)
404
+ }),
405
+ allocation: z6.object({
406
+ default: z6.string().nullable(),
407
+ additional: z6.array(z6.string()).optional()
408
+ }).optional(),
409
+ deploy: z6.object({
410
+ tags: z6.array(z6.string()).optional(),
411
+ dedicated_ip: z6.boolean().optional(),
412
+ port_range: z6.array(z6.string()).optional()
413
+ }).optional()
414
+ });
415
+ var UpdateDetailsSchema = CreateServerSchema.pick({
416
+ external_id: true,
417
+ name: true,
418
+ user: true,
419
+ description: true,
420
+ docker_labels: true
421
+ });
422
+ var UpdateBuildSchema = CreateServerSchema.pick({
423
+ oom_killer: true,
424
+ limits: true,
425
+ feature_limits: true
426
+ }).extend({
427
+ allocation: z6.number().optional(),
428
+ add_allocations: z6.array(z6.string()).optional(),
429
+ remove_allocations: z6.array(z6.string()).optional()
430
+ });
431
+ var UpdateStartupSchema = CreateServerSchema.pick({
432
+ startup: true,
433
+ environment: true,
434
+ egg: true
435
+ }).extend({ image: z6.string().optional(), skip_scripts: z6.boolean() });
414
436
 
415
- // src/api/client/server_websocket.ts
416
- import { EventEmitter } from "events";
417
- import WebSocket from "isomorphic-ws";
418
- import stripColor from "strip-color";
419
- var isBrowser = typeof window !== "undefined";
420
- var RECONNECT_ERRORS = /* @__PURE__ */ new Set([
421
- "jwt: exp claim is invalid",
422
- "jwt: created too far in past (denylist)"
437
+ // src/api/application/users.ts
438
+ import z8 from "zod";
439
+
440
+ // src/api/common/types/enums.ts
441
+ import z7 from "zod";
442
+ var languagesSchema = z7.enum([
443
+ "af",
444
+ "ak",
445
+ "am",
446
+ "ar",
447
+ "as",
448
+ "az",
449
+ "be",
450
+ "bg",
451
+ "bm",
452
+ "bn",
453
+ "bo",
454
+ "br",
455
+ "bs",
456
+ "ca",
457
+ "ce",
458
+ "cs",
459
+ "cv",
460
+ "cy",
461
+ "da",
462
+ "de",
463
+ "dz",
464
+ "ee",
465
+ "el",
466
+ "en",
467
+ "eo",
468
+ "es",
469
+ "et",
470
+ "eu",
471
+ "fa",
472
+ "ff",
473
+ "fi",
474
+ "fo",
475
+ "fr",
476
+ "fy",
477
+ "ga",
478
+ "gd",
479
+ "gl",
480
+ "gu",
481
+ "gv",
482
+ "ha",
483
+ "he",
484
+ "hi",
485
+ "hr",
486
+ "hu",
487
+ "hy",
488
+ "ia",
489
+ "id",
490
+ "ig",
491
+ "ii",
492
+ "is",
493
+ "it",
494
+ "ja",
495
+ "jv",
496
+ "ka",
497
+ "ki",
498
+ "kk",
499
+ "kl",
500
+ "km",
501
+ "kn",
502
+ "ko",
503
+ "ks",
504
+ "ku",
505
+ "kw",
506
+ "ky",
507
+ "lb",
508
+ "lg",
509
+ "ln",
510
+ "lo",
511
+ "lt",
512
+ "lu",
513
+ "lv",
514
+ "mg",
515
+ "mi",
516
+ "mk",
517
+ "ml",
518
+ "mn",
519
+ "mr",
520
+ "ms",
521
+ "mt",
522
+ "my",
523
+ "nb",
524
+ "nd",
525
+ "ne",
526
+ "nl",
527
+ "nn",
528
+ "no",
529
+ "om",
530
+ "or",
531
+ "os",
532
+ "pa",
533
+ "pl",
534
+ "ps",
535
+ "pt",
536
+ "qu",
537
+ "rm",
538
+ "rn",
539
+ "ro",
540
+ "ru",
541
+ "rw",
542
+ "sa",
543
+ "sc",
544
+ "sd",
545
+ "se",
546
+ "sg",
547
+ "si",
548
+ "sk",
549
+ "sl",
550
+ "sn",
551
+ "so",
552
+ "sq",
553
+ "sr",
554
+ "su",
555
+ "sv",
556
+ "sw",
557
+ "ta",
558
+ "te",
559
+ "tg",
560
+ "th",
561
+ "ti",
562
+ "tk",
563
+ "to",
564
+ "tr",
565
+ "tt",
566
+ "ug",
567
+ "uk",
568
+ "ur",
569
+ "uz",
570
+ "vi",
571
+ "wo",
572
+ "xh",
573
+ "yi",
574
+ "yo",
575
+ "zh",
576
+ "zu"
423
577
  ]);
424
- var FALLBACK_LOG_MESSAGE = "No logs - is the server online?";
425
- var ServerWebsocket = class {
426
- r;
427
- serverId;
428
- socket;
429
- currentToken;
430
- bus = new EventEmitter();
431
- debugLogging = false;
432
- stripColors;
433
- detachMessageListener;
434
- constructor(requester, id, stripColors = false) {
435
- this.r = requester;
436
- this.serverId = id;
437
- this.stripColors = stripColors;
438
- }
439
- on(event, listener) {
440
- const handler = listener;
441
- this.bus.on(event, handler);
442
- return () => {
443
- this.bus.removeListener(event, handler);
444
- };
445
- }
446
- deregister(event, listener) {
447
- const handler = listener;
448
- this.bus.removeListener(event, handler);
449
- }
450
- emit(event, ...args) {
451
- if (args.length === 0) {
452
- this.bus.emit(event);
453
- } else {
454
- this.bus.emit(event, args[0]);
455
- }
456
- }
457
- async connect(resumable, debugLogging) {
458
- this.debugLogging = debugLogging ?? false;
459
- if (this.socket) {
460
- return;
461
- }
462
- const socketUrl = await this.refreshCredentials();
463
- this.socket = isBrowser ? new WebSocket(socketUrl) : new WebSocket(socketUrl, void 0, {
464
- origin: new URL(socketUrl).origin
465
- });
466
- await new Promise((resolve, reject) => {
467
- const socket = this.socket;
468
- if (!socket) {
469
- reject(new Error("Failed to create socket connection"));
470
- return;
471
- }
472
- socket.onopen = async () => {
473
- try {
474
- await this.authenticate();
475
- this.attachMessageListener();
476
- socket.onopen = null;
477
- socket.onerror = null;
478
- resolve();
479
- } catch (error) {
480
- socket.onopen = null;
481
- socket.onerror = null;
482
- reject(
483
- error instanceof Error ? error : new Error("Websocket authentication failed")
484
- );
485
- }
486
- };
487
- socket.onerror = (event) => {
488
- socket.onopen = null;
489
- socket.onerror = null;
490
- reject(
491
- event instanceof Error ? event : new Error("Websocket connection error")
492
- );
493
- };
494
- });
495
- if (resumable) {
496
- this.makeResumable(true);
497
- }
498
- }
499
- onSocketDisconnect(handler) {
500
- if (!this.socket) {
501
- console.error(new Error("No socket connection"));
502
- return;
503
- }
504
- this.socket.onclose = handler;
505
- }
506
- onSocketError(handler) {
507
- if (!this.socket) {
508
- console.error(new Error("No socket connection"));
509
- return;
510
- }
511
- this.socket.onerror = handler;
512
- }
513
- makeResumable(disconnectsToo) {
514
- const scheduleReconnect = () => {
515
- setTimeout(() => {
516
- const previous = this.socket;
517
- this.detachMessageListener?.();
518
- this.detachMessageListener = void 0;
519
- this.socket = void 0;
520
- previous?.close();
521
- void this.connect(true, this.debugLogging);
522
- }, 1e3);
523
- };
524
- this.onSocketError(() => scheduleReconnect());
525
- if (disconnectsToo) {
526
- this.onSocketDisconnect(() => scheduleReconnect());
527
- }
528
- }
529
- attachMessageListener() {
530
- if (!this.socket) {
531
- throw new Error("No socket connection");
532
- }
533
- this.detachMessageListener?.();
534
- const handler = (event) => {
535
- void this.handleIncomingMessage(event);
536
- };
537
- if (typeof this.socket.addEventListener === "function") {
538
- this.socket.addEventListener(
539
- "message",
540
- handler
541
- );
542
- this.detachMessageListener = () => {
543
- this.socket?.removeEventListener?.(
544
- "message",
545
- handler
546
- );
547
- };
548
- } else {
549
- const fallback = (data) => handler({ data });
550
- const socket = this.socket;
551
- socket.on?.("message", fallback);
552
- this.detachMessageListener = () => {
553
- const target = this.socket;
554
- if (!target) {
555
- return;
556
- }
557
- if (typeof target.off === "function") {
558
- target.off("message", fallback);
559
- } else if (typeof target.removeListener === "function") {
560
- target.removeListener("message", fallback);
561
- }
562
- };
563
- }
564
- }
565
- async handleIncomingMessage(event) {
566
- const message = this.parseMessage(event);
567
- if (!message) {
568
- return;
569
- }
570
- try {
571
- await this.dispatchMessage(message);
572
- } catch (error) {
573
- if (this.debugLogging) {
574
- console.error("Error while handling websocket message", error);
575
- }
576
- }
577
- }
578
- parseMessage(event) {
579
- const payload = this.normalisePayload(event);
580
- if (!payload) {
581
- return null;
582
- }
583
- try {
584
- return JSON.parse(payload);
585
- } catch (error) {
586
- if (this.debugLogging) {
587
- console.warn("Failed to parse websocket payload", error);
588
- }
589
- return null;
590
- }
591
- }
592
- normalisePayload(event) {
593
- if (typeof event === "string") {
594
- return event;
595
- }
596
- if (typeof event === "object" && event !== null && "data" in event) {
597
- return this.normalisePayload(event.data);
598
- }
599
- if (typeof Buffer !== "undefined" && Buffer.isBuffer(event)) {
600
- return event.toString("utf8");
601
- }
602
- if (typeof ArrayBuffer !== "undefined" && event instanceof ArrayBuffer) {
603
- if (typeof TextDecoder !== "undefined") {
604
- return new TextDecoder().decode(new Uint8Array(event));
605
- }
606
- if (typeof Buffer !== "undefined") {
607
- return Buffer.from(event).toString("utf8");
608
- }
609
- }
610
- return null;
611
- }
612
- async dispatchMessage(message) {
613
- switch (message.event) {
614
- case "auth success" /* AUTH_SUCCESS */: {
615
- if (this.debugLogging) {
616
- console.debug("Auth success");
617
- }
618
- this.emit("auth success" /* AUTH_SUCCESS */);
619
- break;
620
- }
621
- case "status" /* STATUS */: {
622
- if (this.debugLogging) {
623
- console.debug("Received status event", message.args[0]);
624
- }
625
- this.emit("status" /* STATUS */, message.args[0]);
626
- break;
627
- }
628
- case "console output" /* CONSOLE_OUTPUT */: {
629
- let output = message.args[0];
630
- if (this.stripColors) {
631
- output = stripColor(output);
632
- }
633
- if (this.debugLogging) {
634
- console.debug("Received console output", output);
635
- }
636
- this.emit("console output" /* CONSOLE_OUTPUT */, output);
637
- break;
638
- }
639
- case "stats" /* STATS */: {
640
- try {
641
- const payload = JSON.parse(message.args[0]);
642
- this.emit("stats" /* STATS */, payload);
643
- } catch (error) {
644
- if (this.debugLogging) {
645
- console.warn("Failed to parse stats payload", error);
646
- }
647
- }
648
- break;
649
- }
650
- case "daemon error" /* DAEMON_ERROR */: {
651
- this.emit("daemon error" /* DAEMON_ERROR */);
652
- break;
653
- }
654
- case "backup completed" /* BACKUP_COMPLETED */: {
655
- try {
656
- const payload = JSON.parse(
657
- message.args[0]
658
- );
659
- this.emit("backup completed" /* BACKUP_COMPLETED */, payload);
660
- } catch (error) {
661
- if (this.debugLogging) {
662
- console.warn("Failed to parse backup payload", error);
663
- }
664
- }
665
- break;
666
- }
667
- case "daemon message" /* DAEMON_MESSAGE */: {
668
- let output = message.args[0];
669
- if (this.stripColors) {
670
- output = stripColor(output);
671
- }
672
- this.emit("daemon message" /* DAEMON_MESSAGE */, output);
673
- break;
674
- }
675
- case "install output" /* INSTALL_OUTPUT */: {
676
- let output = message.args[0];
677
- if (this.stripColors) {
678
- output = stripColor(output);
679
- }
680
- this.emit("install output" /* INSTALL_OUTPUT */, output);
681
- break;
682
- }
683
- case "backup restore completed" /* BACKUP_RESTORE_COMPLETED */: {
684
- this.emit("backup restore completed" /* BACKUP_RESTORE_COMPLETED */);
685
- break;
686
- }
687
- case "install completed" /* INSTALL_COMPLETED */: {
688
- this.emit("install completed" /* INSTALL_COMPLETED */);
689
- break;
690
- }
691
- case "install started" /* INSTALL_STARTED */: {
692
- this.emit("install started" /* INSTALL_STARTED */);
693
- break;
694
- }
695
- case "transfer logs" /* TRANSFER_LOGS */: {
696
- this.emit("transfer logs" /* TRANSFER_LOGS */, message.args[0]);
697
- break;
698
- }
699
- case "transfer status" /* TRANSFER_STATUS */: {
700
- this.emit("transfer status" /* TRANSFER_STATUS */, message.args[0]);
701
- break;
702
- }
703
- case "token expiring" /* TOKEN_EXPIRING */: {
704
- this.emit("token expiring" /* TOKEN_EXPIRING */);
705
- if (this.debugLogging) {
706
- console.warn("Token expiring, renewing...");
707
- }
708
- await this.refreshCredentials();
709
- await this.authenticate();
710
- break;
711
- }
712
- case "token expired" /* TOKEN_EXPIRED */: {
713
- this.emit("token expired" /* TOKEN_EXPIRED */);
714
- throw new Error("Token expired");
715
- }
716
- case "jwt error" /* JWT_ERROR */: {
717
- const reason = message.args[0];
718
- if (RECONNECT_ERRORS.has(reason)) {
719
- this.emit("token expiring" /* TOKEN_EXPIRING */);
720
- if (this.debugLogging) {
721
- console.warn("Token expiring (JWT error), renewing...");
722
- }
723
- await this.refreshCredentials();
724
- await this.authenticate();
725
- } else {
726
- this.emit("jwt error" /* JWT_ERROR */, reason);
727
- throw new Error("Token expired");
728
- }
729
- break;
730
- }
731
- default: {
732
- if (this.debugLogging) {
733
- console.warn("Unknown websocket event", message);
734
- }
735
- break;
736
- }
737
- }
738
- }
739
- async refreshCredentials() {
740
- const { data } = await this.r.get(
741
- `/servers/${this.serverId}/websocket`
742
- );
743
- this.currentToken = data.data.token;
744
- return data.data.socket;
745
- }
746
- async authenticate() {
747
- if (!this.socket) {
748
- throw new Error("No socket connection");
749
- }
750
- if (!this.currentToken) {
751
- throw new Error("Missing websocket token");
752
- }
753
- this.socket.send(
754
- JSON.stringify({ event: "auth", args: [this.currentToken] })
755
- );
756
- }
757
- disconnect() {
758
- this.detachMessageListener?.();
759
- this.detachMessageListener = void 0;
760
- if (this.socket) {
761
- this.socket.close();
762
- this.socket = void 0;
763
- }
764
- }
765
- requestStats() {
766
- this.send("send stats", [null]);
767
- }
768
- requestLogs() {
769
- this.send("send logs", [null]);
770
- }
771
- send(event, args) {
772
- if (!this.socket) {
773
- if (this.debugLogging) {
774
- console.warn(
775
- `Attempted to send "${event}" without an active websocket connection`
776
- );
777
- }
778
- return;
779
- }
780
- this.socket.send(JSON.stringify({ event, args }));
781
- }
782
- getStats() {
783
- return new Promise((resolve, reject) => {
784
- if (!this.socket) {
785
- reject(new Error("No socket connection"));
786
- return;
787
- }
788
- let off;
789
- const timeout = setTimeout(() => {
790
- off?.();
791
- reject(new Error("Timed out waiting for stats"));
792
- }, 5e3);
793
- off = this.on("stats" /* STATS */, (payload) => {
794
- clearTimeout(timeout);
795
- off?.();
796
- resolve(payload);
797
- });
798
- this.requestStats();
799
- });
800
- }
801
- getLogs() {
802
- return new Promise((resolve, reject) => {
803
- if (!this.socket) {
804
- reject(new Error("No socket connection"));
805
- return;
806
- }
807
- const lines = [];
808
- let off;
809
- let initialTimeout;
810
- let idleTimeout;
811
- const finalize = (payload) => {
812
- off?.();
813
- if (initialTimeout) {
814
- clearTimeout(initialTimeout);
815
- }
816
- if (idleTimeout) {
817
- clearTimeout(idleTimeout);
818
- }
819
- resolve(payload);
820
- };
821
- initialTimeout = setTimeout(() => {
822
- finalize(lines.length > 0 ? lines : [FALLBACK_LOG_MESSAGE]);
823
- }, 5e3);
824
- off = this.on("console output" /* CONSOLE_OUTPUT */, (line) => {
825
- lines.push(line);
826
- if (initialTimeout) {
827
- clearTimeout(initialTimeout);
828
- initialTimeout = void 0;
829
- }
830
- if (idleTimeout) {
831
- clearTimeout(idleTimeout);
832
- }
833
- idleTimeout = setTimeout(() => {
834
- finalize(lines);
835
- }, 1e3);
836
- });
837
- this.requestLogs();
838
- });
839
- }
840
- sendPoweraction(action) {
841
- this.send("set state", [action]);
842
- }
843
- sendCommand(cmd) {
844
- this.send("send command", [cmd]);
845
- }
846
- };
847
-
848
- // src/api/client/server_activity.ts
849
- var ServerActivity = class {
850
- r;
851
- id;
852
- constructor(r, id) {
853
- this.r = r;
854
- this.id = id;
855
- }
856
- list = async (page = 1, per_page = 25) => {
857
- const { data } = await this.r.get(`/server/${this.id}/activity`, { params: { page, per_page } });
858
- return data.data.map((log) => log.attributes);
859
- };
860
- };
861
-
862
- // src/api/client/server.ts
863
- var ServerClient = class {
864
- r;
865
- id;
866
- activity;
867
- databases;
868
- files;
869
- schedules;
870
- allocations;
871
- users;
872
- backups;
873
- startup;
874
- variables;
875
- settings;
876
- constructor(requester, id) {
877
- this.r = requester;
878
- this.id = id;
879
- this.activity = new ServerActivity(requester, id);
880
- this.databases = new ServerDatabases(requester, id);
881
- this.files = new ServerFiles(requester, id);
882
- this.schedules = new ServerSchedules(requester, id);
883
- this.allocations = new ServerAllocations(requester, id);
884
- this.users = new ServerUsers(requester, id);
885
- this.backups = new ServerBackups(requester, id);
886
- this.startup = new ServerStartup(requester, id);
887
- this.variables = this.startup;
888
- this.settings = new ServerSettings(requester, id);
889
- }
890
- info = async (include) => {
891
- const { data } = await this.r.get(
892
- `/servers/${this.id}`,
893
- { params: { include: include?.join(",") } }
894
- );
895
- return data.attributes;
896
- };
897
- websocket = (stripColors = false) => {
898
- return new ServerWebsocket(this.r, this.id, stripColors);
899
- };
900
- resources = async () => {
901
- const { data } = await this.r.get(
902
- `/servers/${this.id}/resources`
903
- );
904
- return data.attributes;
905
- };
906
- command = async (command) => {
907
- await this.r.post(`/servers/${this.id}/command`, { command });
908
- };
909
- power = async (signal) => {
910
- await this.r.post(`/servers/${this.id}/power`, { signal });
911
- };
912
- };
913
-
914
- // src/api/client/client.ts
915
- var Client = class {
916
- account;
917
- r;
918
- constructor(requester) {
919
- this.r = requester;
920
- this.account = new Account(requester);
921
- }
922
- get $r() {
923
- return this.r;
924
- }
925
- listPermissions = async () => {
926
- const { data } = await this.r.get("/permissions");
927
- return data.attributes.permissions;
928
- };
929
- listServers = async (type = "accessible", page = 1, per_page = 50, include) => {
930
- z5.number().positive().parse(page);
931
- const { data } = await this.r.get("/", { params: { type, page, include: include?.join(",") } });
932
- return data.data.map((s) => s.attributes);
933
- };
934
- server = (uuid) => new ServerClient(this.r, uuid);
935
- };
936
-
937
- // src/api/application/users.ts
938
- import z7 from "zod";
939
-
940
- // src/utils/transform.ts
941
- var ArrayQueryParams = (p) => {
942
- const params = new URLSearchParams();
943
- const o = {};
944
- for (const [param, value] of Object.entries(p)) {
945
- for (const [key, val] of Object.entries(value)) {
946
- o[`${param}[${key}]`] = val;
947
- }
948
- }
949
- return o;
950
- };
951
- var SortParam = (key, p) => {
952
- return `${p === "desc" ? "-" : ""}${key}`;
953
- };
954
-
955
- // src/api/common/types/enums.ts
956
- import z6 from "zod";
957
- var languagesSchema = z6.enum([
958
- "af",
959
- "ak",
960
- "am",
961
- "ar",
962
- "as",
963
- "az",
964
- "be",
965
- "bg",
966
- "bm",
967
- "bn",
968
- "bo",
969
- "br",
970
- "bs",
971
- "ca",
972
- "ce",
973
- "cs",
974
- "cv",
975
- "cy",
976
- "da",
977
- "de",
978
- "dz",
979
- "ee",
980
- "el",
981
- "en",
982
- "eo",
983
- "es",
984
- "et",
985
- "eu",
986
- "fa",
987
- "ff",
988
- "fi",
989
- "fo",
990
- "fr",
991
- "fy",
992
- "ga",
993
- "gd",
994
- "gl",
995
- "gu",
996
- "gv",
997
- "ha",
998
- "he",
999
- "hi",
1000
- "hr",
1001
- "hu",
1002
- "hy",
1003
- "ia",
1004
- "id",
1005
- "ig",
1006
- "ii",
1007
- "is",
1008
- "it",
1009
- "ja",
1010
- "jv",
1011
- "ka",
1012
- "ki",
1013
- "kk",
1014
- "kl",
1015
- "km",
1016
- "kn",
1017
- "ko",
1018
- "ks",
1019
- "ku",
1020
- "kw",
1021
- "ky",
1022
- "lb",
1023
- "lg",
1024
- "ln",
1025
- "lo",
1026
- "lt",
1027
- "lu",
1028
- "lv",
1029
- "mg",
1030
- "mi",
1031
- "mk",
1032
- "ml",
1033
- "mn",
1034
- "mr",
1035
- "ms",
1036
- "mt",
1037
- "my",
1038
- "nb",
1039
- "nd",
1040
- "ne",
1041
- "nl",
1042
- "nn",
1043
- "no",
1044
- "om",
1045
- "or",
1046
- "os",
1047
- "pa",
1048
- "pl",
1049
- "ps",
1050
- "pt",
1051
- "qu",
1052
- "rm",
1053
- "rn",
1054
- "ro",
1055
- "ru",
1056
- "rw",
1057
- "sa",
1058
- "sc",
1059
- "sd",
1060
- "se",
1061
- "sg",
1062
- "si",
1063
- "sk",
1064
- "sl",
1065
- "sn",
1066
- "so",
1067
- "sq",
1068
- "sr",
1069
- "su",
1070
- "sv",
1071
- "sw",
1072
- "ta",
1073
- "te",
1074
- "tg",
1075
- "th",
1076
- "ti",
1077
- "tk",
1078
- "to",
1079
- "tr",
1080
- "tt",
1081
- "ug",
1082
- "uk",
1083
- "ur",
1084
- "uz",
1085
- "vi",
1086
- "wo",
1087
- "xh",
1088
- "yi",
1089
- "yo",
1090
- "zh",
1091
- "zu"
1092
- ]);
1093
- var timezonesSchema = z6.enum([
578
+ var timezonesSchema = z7.enum([
1094
579
  "Africa/Abidjan",
1095
580
  "Africa/Accra",
1096
581
  "Africa/Addis_Ababa",
@@ -1512,605 +997,1122 @@ var timezonesSchema = z6.enum([
1512
997
  "UTC"
1513
998
  ]);
1514
999
 
1515
- // src/api/application/users.ts
1516
- var Users = class {
1000
+ // src/utils/transform.ts
1001
+ var ArrayQueryParams = (p) => {
1002
+ const params = new URLSearchParams();
1003
+ const o = {};
1004
+ for (const [param, value] of Object.entries(p)) {
1005
+ for (const [key, val] of Object.entries(value)) {
1006
+ o[`${param}[${key}]`] = val;
1007
+ }
1008
+ }
1009
+ return o;
1010
+ };
1011
+ var SortParam = (key, p) => {
1012
+ return `${p === "desc" ? "-" : ""}${key}`;
1013
+ };
1014
+
1015
+ // src/api/application/users.ts
1016
+ var Users = class {
1017
+ r;
1018
+ constructor(requester) {
1019
+ this.r = requester;
1020
+ }
1021
+ list = async (opts, page = 1) => {
1022
+ z8.number().positive().parse(page);
1023
+ const { data } = await this.r.get("/users", {
1024
+ params: {
1025
+ include: opts.include?.join(","),
1026
+ page,
1027
+ ...ArrayQueryParams({ filters: opts.filters || {} }),
1028
+ sort: opts.sort && (opts.sort.id ? SortParam("id", opts.sort.id) : SortParam("uuid", opts.sort.uuid))
1029
+ }
1030
+ });
1031
+ return data.data.map((d) => d.attributes);
1032
+ };
1033
+ info = async (id, { include }) => {
1034
+ z8.number().positive().parse(id);
1035
+ const { data } = await this.r.get(`/users/${id}`, { params: { include: include?.join(",") } });
1036
+ return data.attributes;
1037
+ };
1038
+ infoByExternal = async (external_id, { include }) => {
1039
+ const { data } = await this.r.get(`/users/external/${external_id}`, {
1040
+ params: { include: include?.join(",") }
1041
+ });
1042
+ return data.attributes;
1043
+ };
1044
+ create = async (user) => {
1045
+ user = CreateSchema.parse(user);
1046
+ const { data } = await this.r.post("/users", user);
1047
+ return data.attributes;
1048
+ };
1049
+ update = async (id, user) => {
1050
+ user = CreateSchema.parse(user);
1051
+ const { data } = await this.r.patch(`/users/${id}`, user);
1052
+ return data.attributes;
1053
+ };
1054
+ delete = async (id) => {
1055
+ z8.number().positive().parse(id);
1056
+ await this.r.delete(`/users/${id}`);
1057
+ };
1058
+ addRoles = async (id, roles) => {
1059
+ z8.number().positive().parse(id);
1060
+ await this.r.patch(`/users/${id}/roles/assign`, { roles });
1061
+ };
1062
+ removeRoles = async (id, roles) => {
1063
+ z8.number().positive().parse(id);
1064
+ await this.r.patch(`/users/${id}/roles/remove`, { roles });
1065
+ };
1066
+ apiKeys = {
1067
+ list: async (id) => {
1068
+ const { data } = await this.r.get(`/users/${id}/api-keys`);
1069
+ return data.data.map((k) => k.attributes);
1070
+ },
1071
+ create: async (id, description, allowed_ips) => {
1072
+ allowed_ips = z8.array(z8.ipv4()).optional().parse(allowed_ips);
1073
+ const { data } = await this.r.post(`/users/${id}/api-keys`, { description, allowed_ips });
1074
+ return { ...data.attributes, secret_token: data.meta.secret_token };
1075
+ },
1076
+ delete: async (id, identifier) => {
1077
+ await this.r.delete(`/users/${id}/api-keys/${identifier}`);
1078
+ }
1079
+ };
1080
+ };
1081
+ var CreateSchema = z8.object({
1082
+ email: z8.email(),
1083
+ external_id: z8.string().max(255).optional(),
1084
+ username: z8.string().min(1).max(255),
1085
+ password: z8.string().optional(),
1086
+ language: languagesSchema,
1087
+ timezone: timezonesSchema
1088
+ });
1089
+
1090
+ // src/api/application/client.ts
1091
+ var Client = class {
1092
+ r;
1093
+ users;
1094
+ nodes;
1095
+ databaseHosts;
1096
+ roles;
1097
+ eggs;
1098
+ mounts;
1099
+ constructor(requester) {
1100
+ this.r = requester;
1101
+ this.users = new Users(requester);
1102
+ this.nodes = new Nodes(requester);
1103
+ this.databaseHosts = new DatabaseHosts(requester);
1104
+ this.roles = new Roles(requester);
1105
+ this.eggs = new Eggs(requester);
1106
+ this.mounts = new Mounts(requester);
1107
+ }
1108
+ get $r() {
1109
+ return this.r;
1110
+ }
1111
+ listServers = async (search, page = 1) => {
1112
+ const { data } = await this.r.get("/servers", { params: { search, page } });
1113
+ return data.data.map((s) => s.attributes);
1114
+ };
1115
+ createServer = async (opts) => {
1116
+ opts = CreateServerSchema.parse(opts);
1117
+ const { data } = await this.r.post("/servers", opts);
1118
+ return data.attributes;
1119
+ };
1120
+ getServerByExternalId = async (external_id, include) => {
1121
+ const { data } = await this.r.get(`/servers/external/${external_id}`, {
1122
+ params: { include: include?.join(",") }
1123
+ });
1124
+ return data.attributes;
1125
+ };
1126
+ servers = (server_id) => new Servers(this.r, server_id);
1127
+ };
1128
+
1129
+ // src/api/base/request.ts
1130
+ import axios from "axios";
1131
+ import z9 from "zod";
1132
+
1133
+ // src/api/base/types.ts
1134
+ var PterodactylException = class extends Error {
1135
+ data;
1136
+ status;
1137
+ constructor(message, data, status) {
1138
+ super(message);
1139
+ this.data = data;
1140
+ this.status = status;
1141
+ }
1142
+ };
1143
+
1144
+ // src/api/base/request.ts
1145
+ var Agent = class {
1146
+ base_url;
1147
+ token;
1148
+ requester;
1149
+ constructor(url, token, type, suffix = "/api") {
1150
+ this.base_url = z9.url("Invalid URL Schema").transform((url2) => new URL(url2).href).parse(url);
1151
+ this.token = z9.string().regex(/^(ptl[ac]|pacc|papp)_.+$/, "Invalid token type").parse(token);
1152
+ this.requester = axios.create({
1153
+ baseURL: this.base_url.replace(/\/+$/, "") + `${suffix}/${type}`,
1154
+ timeout: 3e3,
1155
+ headers: { Authorization: `Bearer ${this.token}` }
1156
+ });
1157
+ this.requester.interceptors.response.use(void 0, (error) => {
1158
+ if (error.response && error.response.status === 400) {
1159
+ return Promise.reject(
1160
+ new PterodactylException(
1161
+ "Invalid request data",
1162
+ error.response.data,
1163
+ error.response.status
1164
+ )
1165
+ );
1166
+ }
1167
+ return Promise.reject(error);
1168
+ });
1169
+ }
1170
+ };
1171
+
1172
+ // src/api/client/client.ts
1173
+ import z14 from "zod";
1174
+
1175
+ // src/api/client/account.ts
1176
+ import z10 from "zod";
1177
+ var Account = class {
1178
+ r;
1179
+ constructor(requester) {
1180
+ this.r = requester;
1181
+ }
1182
+ info = async () => {
1183
+ const { data } = await this.r.get("/account");
1184
+ return data.attributes;
1185
+ };
1186
+ updateEmail = async (newEmail, password) => {
1187
+ newEmail = z10.email().parse(newEmail);
1188
+ await this.r.put("/account/email", { email: newEmail, password });
1189
+ };
1190
+ updatePassword = async (newPassword) => {
1191
+ newPassword = z10.string().min(8).parse(newPassword);
1192
+ await this.r.put("/account/password", {
1193
+ password: newPassword,
1194
+ password_confirmation: newPassword
1195
+ });
1196
+ };
1197
+ apiKeys = {
1198
+ list: async () => {
1199
+ const { data } = await this.r.get("/account/api-keys");
1200
+ return data.data.map((k) => k.attributes);
1201
+ },
1202
+ create: async (description, allowed_ips) => {
1203
+ allowed_ips = z10.array(z10.ipv4()).optional().parse(allowed_ips);
1204
+ const { data } = await this.r.post("/account/api-keys", { description, allowed_ips });
1205
+ return { ...data.attributes, secret_token: data.meta.secret_token };
1206
+ },
1207
+ delete: async (identifier) => {
1208
+ await this.r.delete(`/account/api-keys/${identifier}`);
1209
+ }
1210
+ };
1211
+ sshKeys = {
1212
+ list: async () => {
1213
+ const { data } = await this.r.get("/account/ssh-keys");
1214
+ return data.data.map((k) => k.attributes);
1215
+ },
1216
+ create: async (name, public_key) => {
1217
+ const { data } = await this.r.post("/account/ssh-keys", { name, public_key });
1218
+ return data.attributes;
1219
+ },
1220
+ delete: async (fingerprint) => {
1221
+ await this.r.delete(`/account/ssh-keys/${fingerprint}`);
1222
+ }
1223
+ };
1224
+ };
1225
+
1226
+ // src/api/client/server_activity.ts
1227
+ var ServerActivity = class {
1228
+ r;
1229
+ id;
1230
+ constructor(r, id) {
1231
+ this.r = r;
1232
+ this.id = id;
1233
+ }
1234
+ list = async (page = 1, per_page = 25) => {
1235
+ const { data } = await this.r.get(`/server/${this.id}/activity`, { params: { page, per_page } });
1236
+ return data.data.map((log) => log.attributes);
1237
+ };
1238
+ };
1239
+
1240
+ // src/api/client/server_allocations.ts
1241
+ var ServerAllocations = class {
1242
+ r;
1243
+ id;
1244
+ constructor(requester, id) {
1245
+ this.r = requester;
1246
+ this.id = id;
1247
+ }
1248
+ list = async () => {
1249
+ const { data } = await this.r.get(`/servers/${this.id}/network/allocations`);
1250
+ return data.data.map((r) => r.attributes);
1251
+ };
1252
+ autoAssign = async () => {
1253
+ const { data } = await this.r.post(`/servers/${this.id}/network/allocations`);
1254
+ return data.attributes;
1255
+ };
1256
+ setNotes = async (alloc_id, notes) => {
1257
+ const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}`, { notes });
1258
+ return data.attributes;
1259
+ };
1260
+ setPrimary = async (alloc_id) => {
1261
+ const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}/primary`);
1262
+ return data.attributes;
1263
+ };
1264
+ unassign = async (alloc_id) => {
1265
+ await this.r.delete(
1266
+ `/servers/${this.id}/network/allocations/${alloc_id}`
1267
+ );
1268
+ };
1269
+ };
1270
+
1271
+ // src/api/client/server_backups.ts
1272
+ import axios2 from "axios";
1273
+ import z11 from "zod";
1274
+ var ServerBackups = class {
1275
+ r;
1276
+ id;
1277
+ constructor(requester, id) {
1278
+ this.r = requester;
1279
+ this.id = id;
1280
+ }
1281
+ list = async (page = 1) => {
1282
+ z11.number().positive().parse(page);
1283
+ const { data } = await this.r.get(`/servers/${this.id}/backups`, { params: { page } });
1284
+ return data.data.map((d) => d.attributes);
1285
+ };
1286
+ create = async (args) => {
1287
+ args.name = z11.string().max(255).optional().parse(args.name);
1288
+ const { data } = await this.r.post(`/servers/${this.id}/backups`, {
1289
+ name: args.name,
1290
+ is_locked: args.is_locked,
1291
+ ignored_files: args.ignored_files.join("\n")
1292
+ });
1293
+ return data.attributes;
1294
+ };
1295
+ info = async (backup_uuid) => {
1296
+ const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}`);
1297
+ return data.attributes;
1298
+ };
1299
+ downloadGetUrl = async (backup_uuid) => {
1300
+ const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}/download`);
1301
+ return data.attributes.url;
1302
+ };
1303
+ download = async (backup_uuid) => {
1304
+ const url = await this.downloadGetUrl(backup_uuid);
1305
+ const { data } = await axios2.get(url, {
1306
+ responseType: "arraybuffer"
1307
+ });
1308
+ return data;
1309
+ };
1310
+ delete = async (backup_uuid) => {
1311
+ await this.r.delete(`/servers/${this.id}/backups/${backup_uuid}`);
1312
+ };
1313
+ rename = async (backup_uuid, name) => {
1314
+ await this.r.put(`/servers/${this.id}/backups/${backup_uuid}/rename`, {
1315
+ name
1316
+ });
1317
+ };
1318
+ toggleLock = async (backup_uuid) => {
1319
+ await this.r.post(`/servers/${this.id}/backups/${backup_uuid}/lock`);
1320
+ };
1321
+ restore = async (backup_uuid, truncate) => {
1322
+ await this.r.post(
1323
+ `/servers/${this.id}/backups/${backup_uuid}/restore`,
1324
+ { truncate }
1325
+ );
1326
+ };
1327
+ };
1328
+
1329
+ // src/api/client/server_databases.ts
1330
+ import z12 from "zod";
1331
+ var ServerDatabases = class {
1332
+ r;
1333
+ id;
1334
+ constructor(requester, id) {
1335
+ this.r = requester;
1336
+ this.id = id;
1337
+ }
1338
+ list = async (include, page = 1) => {
1339
+ z12.number().positive().parse(page);
1340
+ const { data } = await this.r.get(`/servers/${this.id}/databases`, {
1341
+ params: { include: include?.join(","), page }
1342
+ });
1343
+ return data.data.map((d) => d.attributes);
1344
+ };
1345
+ create = async (database, remote) => {
1346
+ const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote });
1347
+ return data.attributes;
1348
+ };
1349
+ rotatePassword = async (database_id) => {
1350
+ const { data } = await this.r.post(`/servers/${this.id}/databases/${database_id}/rotate-password`);
1351
+ return data.attributes;
1352
+ };
1353
+ delete = async (database_id) => {
1354
+ await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
1355
+ };
1356
+ };
1357
+
1358
+ // src/api/client/server_files.ts
1359
+ import axios3 from "axios";
1360
+ var ServerFiles = class {
1361
+ r;
1362
+ id;
1363
+ constructor(requester, id) {
1364
+ this.r = requester;
1365
+ this.id = id;
1366
+ }
1367
+ list = async (path) => {
1368
+ const { data } = await this.r.get(`/servers/${this.id}/files/list`, { params: { directory: path } });
1369
+ return data.data.map((r) => r.attributes);
1370
+ };
1371
+ /**
1372
+ * Return the contents of a file. To read binary file (non-editable) use {@link download} instead
1373
+ */
1374
+ contents = async (path) => {
1375
+ const { data } = await this.r.get(
1376
+ `/servers/${this.id}/files/contents`,
1377
+ { params: { file: path } }
1378
+ );
1379
+ return data;
1380
+ };
1381
+ downloadGetUrl = async (path) => {
1382
+ const { data } = await this.r.get(`/servers/${this.id}/files/download`, { params: { file: path } });
1383
+ return data.attributes.url;
1384
+ };
1385
+ download = async (path) => {
1386
+ const url = await this.downloadGetUrl(path);
1387
+ const { data } = await axios3.get(url, {
1388
+ responseType: "arraybuffer"
1389
+ });
1390
+ return data;
1391
+ };
1392
+ rename = async (root = "/", files) => {
1393
+ await this.r.put(`/servers/${this.id}/files/rename`, { root, files });
1394
+ };
1395
+ copy = async (location) => {
1396
+ await this.r.post(`/servers/${this.id}/files/copy`, { location });
1397
+ };
1398
+ write = async (path, content) => {
1399
+ await this.r.post(`/servers/${this.id}/files/write`, content, {
1400
+ params: { file: path }
1401
+ });
1402
+ };
1403
+ compress = async (root = "/", files, archive_name, extension) => {
1404
+ const { data } = await this.r.post(`/servers/${this.id}/files/compress`, {
1405
+ root,
1406
+ files,
1407
+ archive_name,
1408
+ extension
1409
+ });
1410
+ return data.attributes;
1411
+ };
1412
+ decompress = async (root = "/", file) => {
1413
+ await this.r.post(`/servers/${this.id}/files/decompress`, { root, file });
1414
+ };
1415
+ delete = async (root = "/", files) => {
1416
+ await this.r.post(`/servers/${this.id}/files/delete`, { root, files });
1417
+ };
1418
+ createFolder = async (root = "/", name) => {
1419
+ await this.r.post(`/servers/${this.id}/files/create-folder`, {
1420
+ root,
1421
+ name
1422
+ });
1423
+ };
1424
+ chmod = async (root = "/", files) => {
1425
+ await this.r.post(`/servers/${this.id}/files/chmod`, { root, files });
1426
+ };
1427
+ pullFromRemote = async (url, directory, filename, use_header = false, foreground = false) => {
1428
+ await this.r.post(`/servers/${this.id}/files/pull`, {
1429
+ url,
1430
+ directory,
1431
+ filename,
1432
+ use_header,
1433
+ foreground
1434
+ });
1435
+ };
1436
+ uploadGetUrl = async () => {
1437
+ const { data } = await this.r.get(`/servers/${this.id}/files/upload`);
1438
+ return data.attributes.url;
1439
+ };
1440
+ upload = async (file, root = "/") => {
1441
+ const url = await this.uploadGetUrl();
1442
+ await axios3.post(
1443
+ url,
1444
+ { files: file },
1445
+ {
1446
+ headers: { "Content-Type": "multipart/form-data" },
1447
+ params: { directory: root }
1448
+ }
1449
+ );
1450
+ };
1451
+ };
1452
+
1453
+ // src/api/client/server_schedules.ts
1454
+ var ServerSchedules = class {
1455
+ r;
1456
+ id;
1457
+ constructor(requester, id) {
1458
+ this.r = requester;
1459
+ this.id = id;
1460
+ }
1461
+ list = async () => {
1462
+ const { data } = await this.r.get(`/servers/${this.id}/schedules`);
1463
+ return data.data.map((d) => d.attributes);
1464
+ };
1465
+ create = async (params) => {
1466
+ const { data } = await this.r.post(`/servers/${this.id}/schedules`, params);
1467
+ return data.attributes;
1468
+ };
1469
+ control = (sched_id) => new ScheduleControl(this.r, this.id, sched_id);
1470
+ };
1471
+ var ScheduleControl = class {
1472
+ r;
1473
+ id;
1474
+ sched_id;
1475
+ constructor(requester, id, sched_id) {
1476
+ this.r = requester;
1477
+ this.id = id;
1478
+ this.sched_id = sched_id;
1479
+ }
1480
+ info = async () => {
1481
+ const { data } = await this.r.get(`/servers/${this.id}/schedules/${this.sched_id}`);
1482
+ return data.attributes;
1483
+ };
1484
+ update = async (params) => {
1485
+ const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}`, params);
1486
+ return data.attributes;
1487
+ };
1488
+ delete = async () => {
1489
+ await this.r.delete(`/servers/${this.id}/schedules/${this.sched_id}`);
1490
+ };
1491
+ execute = async () => {
1492
+ await this.r.post(
1493
+ `/servers/${this.id}/schedules/${this.sched_id}/execute`
1494
+ );
1495
+ };
1496
+ tasks = {
1497
+ create: async (opts) => {
1498
+ const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}/tasks`, opts);
1499
+ return data.attributes;
1500
+ },
1501
+ update: async (task_id, opts) => {
1502
+ const { data } = await this.r.post(
1503
+ `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`,
1504
+ opts
1505
+ );
1506
+ return data.attributes;
1507
+ },
1508
+ delete: async (task_id) => {
1509
+ await this.r.delete(
1510
+ `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`
1511
+ );
1512
+ }
1513
+ };
1514
+ };
1515
+
1516
+ // src/api/client/server_settings.ts
1517
+ import z13 from "zod";
1518
+ var ServerSettings = class {
1517
1519
  r;
1518
- constructor(requester) {
1520
+ id;
1521
+ constructor(requester, id) {
1522
+ this.r = requester;
1523
+ this.id = id;
1524
+ }
1525
+ rename = async (name) => {
1526
+ name = z13.string().max(255).parse(name);
1527
+ await this.r.post(`/servers/${this.id}/settings/rename`, { name });
1528
+ };
1529
+ updateDescription = async (description) => {
1530
+ await this.r.post(`/servers/${this.id}/settings/description`, {
1531
+ description
1532
+ });
1533
+ };
1534
+ reinstall = async () => {
1535
+ await this.r.post(`/servers/${this.id}/settings/reinstall`);
1536
+ };
1537
+ changeDockerImage = async (image) => {
1538
+ await this.r.put(`/servers/${this.id}/settings/docker-image`, {
1539
+ docker_image: image
1540
+ });
1541
+ };
1542
+ };
1543
+
1544
+ // src/api/client/server_startup.ts
1545
+ var ServerStartup = class {
1546
+ r;
1547
+ id;
1548
+ constructor(requester, id) {
1549
+ this.r = requester;
1550
+ this.id = id;
1551
+ }
1552
+ list = async () => {
1553
+ const { data } = await this.r.get(`/servers/${this.id}/startup`);
1554
+ return {
1555
+ object: "list",
1556
+ meta: data.meta,
1557
+ data: data.data.map((d) => d.attributes)
1558
+ };
1559
+ };
1560
+ set = async (key, value) => {
1561
+ const { data } = await this.r.put(`/servers/${this.id}/startup/variable`, { key, value });
1562
+ return data.attributes;
1563
+ };
1564
+ };
1565
+
1566
+ // src/api/client/server_users.ts
1567
+ var ServerUsers = class {
1568
+ r;
1569
+ id;
1570
+ constructor(requester, id) {
1571
+ this.r = requester;
1572
+ this.id = id;
1573
+ }
1574
+ list = async () => {
1575
+ const { data } = await this.r.get(`/servers/${this.id}/users`);
1576
+ return data.data.map((d) => d.attributes);
1577
+ };
1578
+ create = async (email, permissions) => {
1579
+ const { data } = await this.r.post(`/servers/${this.id}/users`, { email, permissions });
1580
+ return data.attributes;
1581
+ };
1582
+ info = async (user_uuid) => {
1583
+ const { data } = await this.r.get(
1584
+ `/servers/${this.id}/users/${user_uuid}`
1585
+ );
1586
+ return data.attributes;
1587
+ };
1588
+ update = async (user_uuid, permissions) => {
1589
+ const { data } = await this.r.put(
1590
+ `/servers/${this.id}/users/${user_uuid}`,
1591
+ { permissions }
1592
+ );
1593
+ return data.attributes;
1594
+ };
1595
+ delete = async (user_uuid) => {
1596
+ await this.r.delete(`/servers/${this.id}/users/${user_uuid}`);
1597
+ };
1598
+ };
1599
+
1600
+ // src/api/client/server_websocket.ts
1601
+ import { EventEmitter } from "events";
1602
+ import WebSocket from "isomorphic-ws";
1603
+ import stripColor from "strip-color";
1604
+ var isBrowser = typeof window !== "undefined";
1605
+ var RECONNECT_ERRORS = /* @__PURE__ */ new Set([
1606
+ "jwt: exp claim is invalid",
1607
+ "jwt: created too far in past (denylist)"
1608
+ ]);
1609
+ var FALLBACK_LOG_MESSAGE = "No logs - is the server online?";
1610
+ var ServerWebsocket = class {
1611
+ r;
1612
+ serverId;
1613
+ socket;
1614
+ currentToken;
1615
+ bus = new EventEmitter();
1616
+ debugLogging = false;
1617
+ stripColors;
1618
+ detachMessageListener;
1619
+ constructor(requester, id, stripColors = false) {
1519
1620
  this.r = requester;
1621
+ this.serverId = id;
1622
+ this.stripColors = stripColors;
1623
+ }
1624
+ on(event, listener) {
1625
+ const handler = listener;
1626
+ this.bus.on(event, handler);
1627
+ return () => {
1628
+ this.bus.removeListener(event, handler);
1629
+ };
1630
+ }
1631
+ deregister(event, listener) {
1632
+ const handler = listener;
1633
+ this.bus.removeListener(event, handler);
1634
+ }
1635
+ emit(event, ...args) {
1636
+ if (args.length === 0) {
1637
+ this.bus.emit(event);
1638
+ } else {
1639
+ this.bus.emit(event, args[0]);
1640
+ }
1641
+ }
1642
+ async connect(resumable, debugLogging) {
1643
+ this.debugLogging = debugLogging ?? false;
1644
+ if (this.socket) {
1645
+ return;
1646
+ }
1647
+ const socketUrl = await this.refreshCredentials();
1648
+ this.socket = isBrowser ? new WebSocket(socketUrl) : new WebSocket(socketUrl, void 0, {
1649
+ origin: new URL(socketUrl).origin
1650
+ });
1651
+ await new Promise((resolve, reject) => {
1652
+ const socket = this.socket;
1653
+ if (!socket) {
1654
+ reject(new Error("Failed to create socket connection"));
1655
+ return;
1656
+ }
1657
+ socket.onopen = async () => {
1658
+ try {
1659
+ await this.authenticate();
1660
+ this.attachMessageListener();
1661
+ socket.onopen = null;
1662
+ socket.onerror = null;
1663
+ resolve();
1664
+ } catch (error) {
1665
+ socket.onopen = null;
1666
+ socket.onerror = null;
1667
+ reject(
1668
+ error instanceof Error ? error : new Error("Websocket authentication failed")
1669
+ );
1670
+ }
1671
+ };
1672
+ socket.onerror = (event) => {
1673
+ socket.onopen = null;
1674
+ socket.onerror = null;
1675
+ reject(
1676
+ event instanceof Error ? event : new Error("Websocket connection error")
1677
+ );
1678
+ };
1679
+ });
1680
+ if (resumable) {
1681
+ this.makeResumable(true);
1682
+ }
1683
+ }
1684
+ onSocketDisconnect(handler) {
1685
+ if (!this.socket) {
1686
+ console.error(new Error("No socket connection"));
1687
+ return;
1688
+ }
1689
+ this.socket.onclose = handler;
1690
+ }
1691
+ onSocketError(handler) {
1692
+ if (!this.socket) {
1693
+ console.error(new Error("No socket connection"));
1694
+ return;
1695
+ }
1696
+ this.socket.onerror = handler;
1697
+ }
1698
+ makeResumable(disconnectsToo) {
1699
+ const scheduleReconnect = () => {
1700
+ setTimeout(() => {
1701
+ const previous = this.socket;
1702
+ this.detachMessageListener?.();
1703
+ this.detachMessageListener = void 0;
1704
+ this.socket = void 0;
1705
+ previous?.close();
1706
+ void this.connect(true, this.debugLogging);
1707
+ }, 1e3);
1708
+ };
1709
+ this.onSocketError(() => scheduleReconnect());
1710
+ if (disconnectsToo) {
1711
+ this.onSocketDisconnect(() => scheduleReconnect());
1712
+ }
1713
+ }
1714
+ attachMessageListener() {
1715
+ if (!this.socket) {
1716
+ throw new Error("No socket connection");
1717
+ }
1718
+ this.detachMessageListener?.();
1719
+ const handler = (event) => {
1720
+ void this.handleIncomingMessage(event);
1721
+ };
1722
+ if (typeof this.socket.addEventListener === "function") {
1723
+ this.socket.addEventListener(
1724
+ "message",
1725
+ handler
1726
+ );
1727
+ this.detachMessageListener = () => {
1728
+ this.socket?.removeEventListener?.(
1729
+ "message",
1730
+ handler
1731
+ );
1732
+ };
1733
+ } else {
1734
+ const fallback = (data) => handler({ data });
1735
+ const socket = this.socket;
1736
+ socket.on?.("message", fallback);
1737
+ this.detachMessageListener = () => {
1738
+ const target = this.socket;
1739
+ if (!target) {
1740
+ return;
1741
+ }
1742
+ if (typeof target.off === "function") {
1743
+ target.off("message", fallback);
1744
+ } else if (typeof target.removeListener === "function") {
1745
+ target.removeListener("message", fallback);
1746
+ }
1747
+ };
1748
+ }
1520
1749
  }
1521
- list = async (opts, page = 1) => {
1522
- z7.number().positive().parse(page);
1523
- const { data } = await this.r.get("/users", {
1524
- params: {
1525
- include: opts.include?.join(","),
1526
- page,
1527
- ...ArrayQueryParams({ filters: opts.filters || {} }),
1528
- sort: opts.sort?.id ? SortParam("id", opts.sort?.id) : SortParam("uuid", opts.sort?.uuid)
1750
+ async handleIncomingMessage(event) {
1751
+ const message = this.parseMessage(event);
1752
+ if (!message) {
1753
+ return;
1754
+ }
1755
+ try {
1756
+ await this.dispatchMessage(message);
1757
+ } catch (error) {
1758
+ if (this.debugLogging) {
1759
+ console.error("Error while handling websocket message", error);
1529
1760
  }
1530
- });
1531
- return data.data.map((d) => d.attributes);
1532
- };
1533
- info = async (id, { include }) => {
1534
- z7.number().positive().parse(id);
1535
- const { data } = await this.r.get(`/users/${id}`, { params: { include: include?.join(",") } });
1536
- return data.attributes;
1537
- };
1538
- infoByExternal = async (external_id, { include }) => {
1539
- const { data } = await this.r.get(`/users/external/${external_id}`, {
1540
- params: { include: include?.join(",") }
1541
- });
1542
- return data.attributes;
1543
- };
1544
- create = async (user) => {
1545
- user = CreateSchema.parse(user);
1546
- const { data } = await this.r.post("/users", user);
1547
- return data.attributes;
1548
- };
1549
- update = async (id, user) => {
1550
- user = CreateSchema.parse(user);
1551
- const { data } = await this.r.patch(`/users/${id}`, user);
1552
- return data.attributes;
1553
- };
1554
- delete = async (id) => {
1555
- z7.number().positive().parse(id);
1556
- await this.r.delete(`/users/${id}`);
1557
- };
1558
- addRoles = async (id, roles) => {
1559
- z7.number().positive().parse(id);
1560
- await this.r.patch(`/users/${id}/roles/assign`, { roles });
1561
- };
1562
- removeRoles = async (id, roles) => {
1563
- z7.number().positive().parse(id);
1564
- await this.r.patch(`/users/${id}/roles/remove`, { roles });
1565
- };
1566
- apiKeys = {
1567
- list: async (id) => {
1568
- const { data } = await this.r.get(`/users/${id}/api-keys`);
1569
- return data.data.map((k) => k.attributes);
1570
- },
1571
- create: async (id, description, allowed_ips) => {
1572
- allowed_ips = z7.array(z7.ipv4()).optional().parse(allowed_ips);
1573
- const { data } = await this.r.post(`/users/${id}/api-keys`, { description, allowed_ips });
1574
- return { ...data.attributes, secret_token: data.meta.secret_token };
1575
- },
1576
- delete: async (id, identifier) => {
1577
- await this.r.delete(`/users/${id}/api-keys/${identifier}`);
1578
1761
  }
1579
- };
1580
- };
1581
- var CreateSchema = z7.object({
1582
- email: z7.email(),
1583
- external_id: z7.string().max(255).optional(),
1584
- username: z7.string().min(1).max(255),
1585
- password: z7.string().optional(),
1586
- language: languagesSchema,
1587
- timezone: timezonesSchema
1588
- });
1589
-
1590
- // src/api/application/nodes_allocations.ts
1591
- import z8 from "zod";
1592
- var NodesAllocations = class {
1593
- r;
1594
- id;
1595
- constructor(requester, id) {
1596
- this.r = requester;
1597
- this.id = id;
1598
1762
  }
1599
- list = async (include) => {
1600
- const { data } = await this.r.get(`/nodes/${this.id}/allocations`, {
1601
- params: { include: include?.join(",") }
1602
- });
1603
- return data.data.map((d) => d.attributes);
1604
- };
1605
- create = async (ip, ports, alias) => {
1606
- z8.ipv4().parse(ip);
1607
- z8.ipv4().or(z8.url().max(255)).optional().parse(alias);
1608
- z8.array(z8.number()).or(z8.string().regex(/\d+-\d+/)).parse(ports);
1609
- await this.r.post(`/nodes/${this.id}/allocations`, { ip, ports, alias });
1610
- };
1611
- delete = async (alloc_id) => {
1612
- await this.r.delete(`/nodes/${this.id}/allocations/${alloc_id}`);
1613
- };
1614
- };
1615
-
1616
- // src/api/application/nodes.ts
1617
- import z9 from "zod";
1618
- var Nodes = class {
1619
- r;
1620
- constructor(requester) {
1621
- this.r = requester;
1763
+ parseMessage(event) {
1764
+ const payload = this.normalisePayload(event);
1765
+ if (!payload) {
1766
+ return null;
1767
+ }
1768
+ try {
1769
+ return JSON.parse(payload);
1770
+ } catch (error) {
1771
+ if (this.debugLogging) {
1772
+ console.warn("Failed to parse websocket payload", error);
1773
+ }
1774
+ return null;
1775
+ }
1622
1776
  }
1623
- list = async (include, page = 1) => {
1624
- z9.number().positive().parse(page);
1625
- const { data } = await this.r.get("/nodes", { params: { include: include?.join(","), page } });
1626
- return data.data.map((s) => s.attributes);
1627
- };
1628
- listDeployable = async (filters, include, page = 1) => {
1629
- z9.number().positive().parse(page);
1630
- const { data } = await this.r.get("/nodes/deployable", {
1631
- params: {
1632
- include: include?.join(","),
1633
- disk: filters.disk,
1634
- memory: filters.memory,
1635
- cpu: filters.cpu,
1636
- location_ids: filters.location_ids,
1637
- tags: filters.tags,
1638
- page
1777
+ normalisePayload(event) {
1778
+ if (typeof event === "string") {
1779
+ return event;
1780
+ }
1781
+ if (typeof event === "object" && event !== null && "data" in event) {
1782
+ return this.normalisePayload(event.data);
1783
+ }
1784
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(event)) {
1785
+ return event.toString("utf8");
1786
+ }
1787
+ if (typeof ArrayBuffer !== "undefined" && event instanceof ArrayBuffer) {
1788
+ if (typeof TextDecoder !== "undefined") {
1789
+ return new TextDecoder().decode(new Uint8Array(event));
1790
+ }
1791
+ if (typeof Buffer !== "undefined") {
1792
+ return Buffer.from(event).toString("utf8");
1793
+ }
1794
+ }
1795
+ return null;
1796
+ }
1797
+ async dispatchMessage(message) {
1798
+ switch (message.event) {
1799
+ case "auth success" /* AUTH_SUCCESS */: {
1800
+ if (this.debugLogging) {
1801
+ console.debug("Auth success");
1802
+ }
1803
+ this.emit("auth success" /* AUTH_SUCCESS */);
1804
+ break;
1805
+ }
1806
+ case "status" /* STATUS */: {
1807
+ if (this.debugLogging) {
1808
+ console.debug("Received status event", message.args[0]);
1809
+ }
1810
+ this.emit("status" /* STATUS */, message.args[0]);
1811
+ break;
1812
+ }
1813
+ case "console output" /* CONSOLE_OUTPUT */: {
1814
+ let output = message.args[0];
1815
+ if (this.stripColors) {
1816
+ output = stripColor(output);
1817
+ }
1818
+ if (this.debugLogging) {
1819
+ console.debug("Received console output", output);
1820
+ }
1821
+ this.emit("console output" /* CONSOLE_OUTPUT */, output);
1822
+ break;
1823
+ }
1824
+ case "stats" /* STATS */: {
1825
+ try {
1826
+ const payload = JSON.parse(message.args[0]);
1827
+ this.emit("stats" /* STATS */, payload);
1828
+ } catch (error) {
1829
+ if (this.debugLogging) {
1830
+ console.warn("Failed to parse stats payload", error);
1831
+ }
1832
+ }
1833
+ break;
1834
+ }
1835
+ case "daemon error" /* DAEMON_ERROR */: {
1836
+ this.emit("daemon error" /* DAEMON_ERROR */);
1837
+ break;
1838
+ }
1839
+ case "backup completed" /* BACKUP_COMPLETED */: {
1840
+ try {
1841
+ const payload = JSON.parse(
1842
+ message.args[0]
1843
+ );
1844
+ this.emit("backup completed" /* BACKUP_COMPLETED */, payload);
1845
+ } catch (error) {
1846
+ if (this.debugLogging) {
1847
+ console.warn("Failed to parse backup payload", error);
1848
+ }
1849
+ }
1850
+ break;
1851
+ }
1852
+ case "daemon message" /* DAEMON_MESSAGE */: {
1853
+ let output = message.args[0];
1854
+ if (this.stripColors) {
1855
+ output = stripColor(output);
1856
+ }
1857
+ this.emit("daemon message" /* DAEMON_MESSAGE */, output);
1858
+ break;
1859
+ }
1860
+ case "install output" /* INSTALL_OUTPUT */: {
1861
+ let output = message.args[0];
1862
+ if (this.stripColors) {
1863
+ output = stripColor(output);
1864
+ }
1865
+ this.emit("install output" /* INSTALL_OUTPUT */, output);
1866
+ break;
1867
+ }
1868
+ case "backup restore completed" /* BACKUP_RESTORE_COMPLETED */: {
1869
+ this.emit("backup restore completed" /* BACKUP_RESTORE_COMPLETED */);
1870
+ break;
1871
+ }
1872
+ case "install completed" /* INSTALL_COMPLETED */: {
1873
+ this.emit("install completed" /* INSTALL_COMPLETED */);
1874
+ break;
1875
+ }
1876
+ case "install started" /* INSTALL_STARTED */: {
1877
+ this.emit("install started" /* INSTALL_STARTED */);
1878
+ break;
1879
+ }
1880
+ case "transfer logs" /* TRANSFER_LOGS */: {
1881
+ this.emit("transfer logs" /* TRANSFER_LOGS */, message.args[0]);
1882
+ break;
1883
+ }
1884
+ case "transfer status" /* TRANSFER_STATUS */: {
1885
+ this.emit("transfer status" /* TRANSFER_STATUS */, message.args[0]);
1886
+ break;
1887
+ }
1888
+ case "token expiring" /* TOKEN_EXPIRING */: {
1889
+ this.emit("token expiring" /* TOKEN_EXPIRING */);
1890
+ if (this.debugLogging) {
1891
+ console.warn("Token expiring, renewing...");
1892
+ }
1893
+ await this.refreshCredentials();
1894
+ await this.authenticate();
1895
+ break;
1896
+ }
1897
+ case "token expired" /* TOKEN_EXPIRED */: {
1898
+ this.emit("token expired" /* TOKEN_EXPIRED */);
1899
+ throw new Error("Token expired");
1900
+ }
1901
+ case "jwt error" /* JWT_ERROR */: {
1902
+ const reason = message.args[0];
1903
+ if (RECONNECT_ERRORS.has(reason)) {
1904
+ this.emit("token expiring" /* TOKEN_EXPIRING */);
1905
+ if (this.debugLogging) {
1906
+ console.warn("Token expiring (JWT error), renewing...");
1907
+ }
1908
+ await this.refreshCredentials();
1909
+ await this.authenticate();
1910
+ } else {
1911
+ this.emit("jwt error" /* JWT_ERROR */, reason);
1912
+ throw new Error("Token expired");
1913
+ }
1914
+ break;
1639
1915
  }
1640
- });
1641
- return data.data.map((s) => s.attributes);
1642
- };
1643
- info = async (id, include) => {
1644
- z9.number().positive().parse(id);
1645
- const { data } = await this.r.get(
1646
- `/nodes/${id}`,
1647
- { params: { include: include?.join(",") } }
1648
- );
1649
- return data.attributes;
1650
- };
1651
- create = async (node) => {
1652
- node = NodeCreateSchema.parse(node);
1653
- const { data } = await this.r.post(
1654
- "/nodes",
1655
- node
1656
- );
1657
- return data.attributes;
1658
- };
1659
- get_configuration = async (id) => {
1660
- z9.number().positive().parse(id);
1916
+ default: {
1917
+ if (this.debugLogging) {
1918
+ console.warn("Unknown websocket event", message);
1919
+ }
1920
+ break;
1921
+ }
1922
+ }
1923
+ }
1924
+ async refreshCredentials() {
1661
1925
  const { data } = await this.r.get(
1662
- `/nodes/${id}/configuration`
1663
- );
1664
- return data;
1665
- };
1666
- update = async (id, node) => {
1667
- z9.number().positive().parse(id);
1668
- node = NodeCreateSchema.parse(node);
1669
- const { data } = await this.r.patch(
1670
- `/nodes/${id}`,
1671
- node
1926
+ `/servers/${this.serverId}/websocket`
1672
1927
  );
1673
- return data.attributes;
1674
- };
1675
- delete = async (id) => {
1676
- z9.number().positive().parse(id);
1677
- await this.r.delete(`/nodes/${id}`);
1678
- };
1679
- allocations = (server_id) => new NodesAllocations(this.r, server_id);
1680
- };
1681
- var NodeCreateSchema = z9.object({
1682
- name: z9.string().min(1).max(100),
1683
- description: z9.string().optional(),
1684
- public: z9.boolean().optional(),
1685
- fqdn: z9.string().nonempty(),
1686
- scheme: z9.enum(["http", "https"]),
1687
- behind_proxy: z9.boolean().optional(),
1688
- memory: z9.number().min(0),
1689
- memory_overallocate: z9.number().min(-1),
1690
- disk: z9.number().min(0),
1691
- disk_overallocate: z9.number().min(-1),
1692
- cpu: z9.number().min(0),
1693
- cpu_overallocate: z9.number().min(-1),
1694
- daemon_base: z9.string().nonempty().optional(),
1695
- daemon_sftp: z9.number().min(1).max(65535),
1696
- daemon_sftp_alias: z9.string().optional(),
1697
- daemon_listen: z9.number().min(1).max(65535),
1698
- daemon_connect: z9.number().min(1).max(65535),
1699
- maintenance_mode: z9.boolean().optional(),
1700
- upload_size: z9.number().min(1).max(1024),
1701
- tags: z9.array(z9.string()).optional()
1702
- });
1703
-
1704
- // src/api/application/servers.ts
1705
- import z11 from "zod";
1706
-
1707
- // src/api/application/servers_databases.ts
1708
- import z10 from "zod";
1709
- var ServersDatabases = class {
1710
- r;
1711
- id;
1712
- constructor(r, server_id) {
1713
- this.r = r;
1714
- this.id = server_id;
1928
+ this.currentToken = data.data.token;
1929
+ return data.data.socket;
1715
1930
  }
1716
- list = async () => {
1717
- const { data } = await this.r.get(`/servers/${this.id}/databases`);
1718
- return data.data.map((d) => d.attributes);
1719
- };
1720
- create = async (database, remote, host) => {
1721
- database = z10.string().min(1).max(48).parse(database);
1722
- const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote, host });
1723
- return data.attributes;
1724
- };
1725
- info = async (database_id) => {
1726
- const { data } = await this.r.get(`/servers/${this.id}/databases/${database_id}`);
1727
- return data.attributes;
1728
- };
1729
- delete = async (database_id) => {
1730
- await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
1731
- };
1732
- resetPassword = async (database_id) => {
1733
- await this.r.post(
1734
- `/servers/${this.id}/databases/${database_id}/reset-password`
1931
+ async authenticate() {
1932
+ if (!this.socket) {
1933
+ throw new Error("No socket connection");
1934
+ }
1935
+ if (!this.currentToken) {
1936
+ throw new Error("Missing websocket token");
1937
+ }
1938
+ this.socket.send(
1939
+ JSON.stringify({ event: "auth", args: [this.currentToken] })
1735
1940
  );
1736
- };
1737
- };
1738
-
1739
- // src/api/application/servers.ts
1740
- var Servers = class {
1741
- r;
1742
- id;
1743
- databases;
1744
- constructor(r, server_id) {
1745
- this.r = r;
1746
- this.id = server_id;
1747
- this.databases = new ServersDatabases(this.r, this.id);
1748
1941
  }
1749
- info = async (include) => {
1750
- const { data } = await this.r.get(`/servers/${this.id}`, { params: { include: include?.join(",") } });
1751
- return data.attributes;
1752
- };
1753
- delete = async (force = false) => {
1754
- await this.r.delete(`/servers/${this.id}${force ? "/force" : ""}`);
1755
- };
1756
- updateDetails = async (opts) => {
1757
- opts = UpdateDetailsSchema.parse(opts);
1758
- await this.r.patch(`/servers/${this.id}/details`, opts);
1759
- };
1760
- updateBuild = async (opts) => {
1761
- opts = UpdateBuildSchema.parse(opts);
1762
- await this.r.patch(`/servers/${this.id}/build`, opts);
1763
- };
1764
- updateStartup = async (opts) => {
1765
- opts = UpdateStartupSchema.parse(opts);
1766
- await this.r.patch(`/servers/${this.id}/startup`, opts);
1767
- };
1768
- suspend = async () => {
1769
- await this.r.post(`/servers/${this.id}/suspend`);
1770
- };
1771
- unsuspend = async () => {
1772
- await this.r.post(`/servers/${this.id}/unsuspend`);
1773
- };
1774
- reinstall = async () => {
1775
- await this.r.post(`/servers/${this.id}/reinstall`);
1776
- };
1777
- transferStart = async (node_id, allocation_id, allocation_additional) => {
1778
- await this.r.post(`/servers/${this.id}/transfer`, {
1779
- node_id,
1780
- allocation_id,
1781
- allocation_additional
1782
- });
1783
- };
1784
- transferCancel = async () => {
1785
- await this.r.post(`/servers/${this.id}/transfer/cancel`);
1786
- };
1787
- };
1788
- var CreateServerSchema = z11.object({
1789
- external_id: z11.string().min(1).max(255).optional(),
1790
- name: z11.string().min(1).max(255),
1791
- description: z11.string().optional(),
1792
- user: z11.number(),
1793
- egg: z11.number(),
1794
- docker_image: z11.string().optional(),
1795
- startup: z11.string().optional(),
1796
- environment: z11.record(z11.string(), z11.string()),
1797
- skip_scripts: z11.boolean().optional(),
1798
- oom_killer: z11.boolean().optional(),
1799
- start_on_completion: z11.boolean().optional(),
1800
- docker_labels: z11.record(z11.string(), z11.string()).optional(),
1801
- limits: z11.object({
1802
- memory: z11.number().min(0),
1803
- swap: z11.number().min(-1),
1804
- disk: z11.number().min(0),
1805
- io: z11.number().min(0),
1806
- threads: z11.string().optional(),
1807
- cpu: z11.number().min(0)
1808
- }),
1809
- feature_limits: z11.object({
1810
- databases: z11.number().min(0),
1811
- allocations: z11.number().min(0),
1812
- backups: z11.number().min(0)
1813
- }),
1814
- allocation: z11.object({
1815
- default: z11.string(),
1816
- additional: z11.array(z11.string()).optional()
1817
- }).optional(),
1818
- deploy: z11.object({
1819
- tags: z11.array(z11.string()).optional(),
1820
- dedicated_ip: z11.boolean().optional(),
1821
- port_range: z11.array(z11.string()).optional()
1822
- }).optional()
1823
- });
1824
- var UpdateDetailsSchema = CreateServerSchema.pick({
1825
- external_id: true,
1826
- name: true,
1827
- user: true,
1828
- description: true,
1829
- docker_labels: true
1830
- });
1831
- var UpdateBuildSchema = CreateServerSchema.pick({
1832
- oom_killer: true,
1833
- limits: true,
1834
- feature_limits: true
1835
- }).extend({
1836
- allocation: z11.number().optional(),
1837
- add_allocations: z11.array(z11.string()).optional(),
1838
- remove_allocations: z11.array(z11.string()).optional()
1839
- });
1840
- var UpdateStartupSchema = CreateServerSchema.pick({
1841
- startup: true,
1842
- environment: true,
1843
- egg: true
1844
- }).extend({ image: z11.string().optional(), skip_scripts: z11.boolean() });
1845
-
1846
- // src/api/application/database_hosts.ts
1847
- import z12 from "zod";
1848
- var DatabaseHosts = class {
1849
- r;
1850
- constructor(r) {
1851
- this.r = r;
1942
+ disconnect() {
1943
+ this.detachMessageListener?.();
1944
+ this.detachMessageListener = void 0;
1945
+ if (this.socket) {
1946
+ this.socket.close();
1947
+ this.socket = void 0;
1948
+ }
1852
1949
  }
1853
- list = async (page = 1) => {
1854
- const { data } = await this.r.get("/database-hosts", { params: { page } });
1855
- return data.data.map((d) => d.attributes);
1856
- };
1857
- info = async (id) => {
1858
- const { data } = await this.r.get(`/database-hosts/${id}`);
1859
- return data.attributes;
1860
- };
1861
- // TODO: find out why API returns 500
1862
- create = async (opts) => {
1863
- opts = CreateDBHostSchema.parse(opts);
1864
- await this.r.post(
1865
- "/database-hosts",
1866
- opts
1867
- ).catch((e) => {
1868
- });
1869
- };
1870
- update = async (id, opts) => {
1871
- opts = CreateDBHostSchema.parse(opts);
1872
- const { data } = await this.r.patch(`/database-hosts/${id}`, opts);
1873
- return data.attributes;
1874
- };
1875
- delete = async (id) => {
1876
- await this.r.delete(`/database-hosts/${id}`);
1877
- };
1878
- };
1879
- var CreateDBHostSchema = z12.object({
1880
- name: z12.string().min(1).max(255),
1881
- host: z12.string(),
1882
- port: z12.number().min(1).max(65535),
1883
- username: z12.string().min(1).max(255),
1884
- password: z12.string().optional(),
1885
- node_ids: z12.array(z12.string()).optional(),
1886
- max_databases: z12.number().optional()
1887
- });
1888
-
1889
- // src/api/application/roles.ts
1890
- var Roles = class {
1891
- r;
1892
- constructor(r) {
1893
- this.r = r;
1950
+ requestStats() {
1951
+ this.send("send stats", [null]);
1894
1952
  }
1895
- list = async (page = 1) => {
1896
- const { data } = await this.r.get(`/roles`, { params: { page } });
1897
- return data.data.map((r) => r.attributes);
1898
- };
1899
- info = async (id) => {
1900
- const { data } = await this.r.get(
1901
- `/roles/${id}`
1902
- );
1903
- return data.attributes;
1904
- };
1905
- create = async (opts) => {
1906
- await this.r.post(`/roles`, opts);
1907
- };
1908
- update = async (id, opts) => {
1909
- await this.r.patch(`/roles/${id}`, opts);
1910
- };
1911
- delete = async (id) => {
1912
- await this.r.delete(`/roles/${id}`);
1913
- };
1914
- };
1915
-
1916
- // src/api/application/eggs.ts
1917
- var Eggs = class {
1918
- r;
1919
- constructor(r) {
1920
- this.r = r;
1953
+ requestLogs() {
1954
+ this.send("send logs", [null]);
1955
+ }
1956
+ send(event, args) {
1957
+ if (!this.socket) {
1958
+ if (this.debugLogging) {
1959
+ console.warn(
1960
+ `Attempted to send "${event}" without an active websocket connection`
1961
+ );
1962
+ }
1963
+ return;
1964
+ }
1965
+ this.socket.send(JSON.stringify({ event, args }));
1921
1966
  }
1922
- list = async () => {
1923
- const { data } = await this.r.get(
1924
- "/eggs"
1925
- );
1926
- return data.data.map((d) => d.attributes);
1927
- };
1928
- info = async (id) => {
1929
- const { data } = await this.r.get(
1930
- `/eggs/${id}`
1931
- );
1932
- return data.attributes;
1933
- };
1934
- export = async (id, format) => {
1935
- const { data } = await this.r.get(`/eggs/${id}/export`, {
1936
- params: { format },
1937
- transformResponse: (r) => r
1967
+ getStats() {
1968
+ return new Promise((resolve, reject) => {
1969
+ if (!this.socket) {
1970
+ reject(new Error("No socket connection"));
1971
+ return;
1972
+ }
1973
+ let off;
1974
+ const timeout = setTimeout(() => {
1975
+ off?.();
1976
+ reject(new Error("Timed out waiting for stats"));
1977
+ }, 5e3);
1978
+ off = this.on("stats" /* STATS */, (payload) => {
1979
+ clearTimeout(timeout);
1980
+ off?.();
1981
+ resolve(payload);
1982
+ });
1983
+ this.requestStats();
1938
1984
  });
1939
- return data;
1940
- };
1941
- infoExportable = async (id) => {
1942
- const { data } = await this.r.get(`/eggs/${id}/export`, {
1943
- params: { format: "json" }
1985
+ }
1986
+ getLogs() {
1987
+ return new Promise((resolve, reject) => {
1988
+ if (!this.socket) {
1989
+ reject(new Error("No socket connection"));
1990
+ return;
1991
+ }
1992
+ const lines = [];
1993
+ let off;
1994
+ let initialTimeout;
1995
+ let idleTimeout;
1996
+ const finalize = (payload) => {
1997
+ off?.();
1998
+ if (initialTimeout) {
1999
+ clearTimeout(initialTimeout);
2000
+ }
2001
+ if (idleTimeout) {
2002
+ clearTimeout(idleTimeout);
2003
+ }
2004
+ resolve(payload);
2005
+ };
2006
+ initialTimeout = setTimeout(() => {
2007
+ finalize(lines.length > 0 ? lines : [FALLBACK_LOG_MESSAGE]);
2008
+ }, 5e3);
2009
+ off = this.on("console output" /* CONSOLE_OUTPUT */, (line) => {
2010
+ lines.push(line);
2011
+ if (initialTimeout) {
2012
+ clearTimeout(initialTimeout);
2013
+ initialTimeout = void 0;
2014
+ }
2015
+ if (idleTimeout) {
2016
+ clearTimeout(idleTimeout);
2017
+ }
2018
+ idleTimeout = setTimeout(() => {
2019
+ finalize(lines);
2020
+ }, 1e3);
2021
+ });
2022
+ this.requestLogs();
1944
2023
  });
1945
- return data;
1946
- };
2024
+ }
2025
+ sendPoweraction(action) {
2026
+ this.send("set state", [action]);
2027
+ }
2028
+ sendCommand(cmd) {
2029
+ this.send("send command", [cmd]);
2030
+ }
1947
2031
  };
1948
2032
 
1949
- // src/api/application/mounts.ts
1950
- import z13 from "zod";
1951
- var Mounts = class {
2033
+ // src/api/client/server.ts
2034
+ var ServerClient = class {
1952
2035
  r;
1953
- constructor(r) {
1954
- this.r = r;
2036
+ id;
2037
+ activity;
2038
+ databases;
2039
+ files;
2040
+ schedules;
2041
+ allocations;
2042
+ users;
2043
+ backups;
2044
+ startup;
2045
+ variables;
2046
+ settings;
2047
+ constructor(requester, id) {
2048
+ this.r = requester;
2049
+ this.id = id;
2050
+ this.activity = new ServerActivity(requester, id);
2051
+ this.databases = new ServerDatabases(requester, id);
2052
+ this.files = new ServerFiles(requester, id);
2053
+ this.schedules = new ServerSchedules(requester, id);
2054
+ this.allocations = new ServerAllocations(requester, id);
2055
+ this.users = new ServerUsers(requester, id);
2056
+ this.backups = new ServerBackups(requester, id);
2057
+ this.startup = new ServerStartup(requester, id);
2058
+ this.variables = this.startup;
2059
+ this.settings = new ServerSettings(requester, id);
1955
2060
  }
1956
- list = async () => {
1957
- const { data } = await this.r.get("/mounts");
1958
- return data.data.map((d) => d.attributes);
1959
- };
1960
- info = async (id) => {
2061
+ info = async (include) => {
1961
2062
  const { data } = await this.r.get(
1962
- `/mounts/${id}`
2063
+ `/servers/${this.id}`,
2064
+ { params: { include: include?.join(",") } }
1963
2065
  );
1964
2066
  return data.attributes;
1965
2067
  };
1966
- create = async (opts) => {
1967
- opts = CreateMountSchema.parse(opts);
1968
- const { data } = await this.r.post(
1969
- "/mounts",
1970
- opts
1971
- );
1972
- return data.attributes;
2068
+ websocket = (stripColors = false) => {
2069
+ return new ServerWebsocket(this.r, this.id, stripColors);
1973
2070
  };
1974
- update = async (id, opts) => {
1975
- opts = CreateMountSchema.parse(opts);
1976
- const { data } = await this.r.patch(
1977
- `/mounts/${id}`,
1978
- opts
2071
+ resources = async () => {
2072
+ const { data } = await this.r.get(
2073
+ `/servers/${this.id}/resources`
1979
2074
  );
1980
2075
  return data.attributes;
1981
2076
  };
1982
- delete = async (id) => {
1983
- await this.r.delete(`/mounts/${id}`);
1984
- };
1985
- listAssignedEggs = async (id) => {
1986
- const { data } = await this.r.get(`/mounts/${id}/eggs`);
1987
- return data.data.map((d) => d.attributes);
1988
- };
1989
- assignEggs = async (id, eggs) => {
1990
- await this.r.post(`/mounts/${id}/eggs`, { eggs });
1991
- };
1992
- unassignEgg = async (id, egg_id) => {
1993
- await this.r.delete(`/mounts/${id}/eggs/${egg_id}`);
1994
- };
1995
- listAssignedNodes = async (id) => {
1996
- const { data } = await this.r.get(`/mounts/${id}/nodes`);
1997
- return data.data.map((d) => d.attributes);
1998
- };
1999
- assignNodes = async (id, nodes) => {
2000
- await this.r.post(`/mounts/${id}/nodes`, { nodes });
2001
- };
2002
- unassignNode = async (id, node_id) => {
2003
- await this.r.delete(`/mounts/${id}/nodes/${node_id}`);
2004
- };
2005
- listAssignedServers = async (id) => {
2006
- const { data } = await this.r.get(`/mounts/${id}/servers`);
2007
- return data.data.map((d) => d.attributes);
2008
- };
2009
- assignServers = async (id, servers) => {
2010
- await this.r.post(`/mounts/${id}/servers`, { servers });
2077
+ command = async (command) => {
2078
+ await this.r.post(`/servers/${this.id}/command`, { command });
2011
2079
  };
2012
- unassignServer = async (id, server_id) => {
2013
- await this.r.delete(`/mounts/${id}/servers/${server_id}`);
2080
+ power = async (signal) => {
2081
+ await this.r.post(`/servers/${this.id}/power`, { signal });
2014
2082
  };
2015
2083
  };
2016
- var CreateMountSchema = z13.object({
2017
- name: z13.string().min(1).max(255),
2018
- description: z13.string().optional(),
2019
- source: z13.string(),
2020
- target: z13.string(),
2021
- read_only: z13.boolean().optional()
2022
- });
2023
2084
 
2024
- // src/api/application/client.ts
2085
+ // src/api/client/client.ts
2025
2086
  var Client2 = class {
2087
+ account;
2026
2088
  r;
2027
- users;
2028
- nodes;
2029
- databaseHosts;
2030
- roles;
2031
- eggs;
2032
- mounts;
2033
2089
  constructor(requester) {
2034
2090
  this.r = requester;
2035
- this.users = new Users(requester);
2036
- this.nodes = new Nodes(requester);
2037
- this.databaseHosts = new DatabaseHosts(requester);
2038
- this.roles = new Roles(requester);
2039
- this.eggs = new Eggs(requester);
2040
- this.mounts = new Mounts(requester);
2091
+ this.account = new Account(requester);
2041
2092
  }
2042
2093
  get $r() {
2043
2094
  return this.r;
2044
2095
  }
2045
- listServers = async (search, page = 1) => {
2046
- const { data } = await this.r.get("/servers", { params: { search, page } });
2047
- return data.data.map((s) => s.attributes);
2048
- };
2049
- createServer = async (opts) => {
2050
- opts = CreateServerSchema.parse(opts);
2051
- const { data } = await this.r.post("/servers", opts);
2052
- return data.attributes;
2096
+ listPermissions = async () => {
2097
+ const { data } = await this.r.get("/permissions");
2098
+ return data.attributes.permissions;
2053
2099
  };
2054
- getServerByExternalId = async (external_id, include) => {
2055
- const { data } = await this.r.get(`/servers/external/${external_id}`, {
2056
- params: { include: include?.join(",") }
2057
- });
2058
- return data.attributes;
2100
+ listServers = async (type = "accessible", page = 1, per_page = 50, include) => {
2101
+ z14.number().positive().parse(page);
2102
+ const { data } = await this.r.get("/", { params: { type, page, include: include?.join(",") } });
2103
+ return data.data.map((s) => s.attributes);
2059
2104
  };
2060
- servers = (server_id) => new Servers(this.r, server_id);
2061
- };
2062
-
2063
- // src/api/base/request.ts
2064
- import z14 from "zod";
2065
- import axios3 from "axios";
2066
-
2067
- // src/api/base/types.ts
2068
- var PterodactylException = class extends Error {
2069
- data;
2070
- status;
2071
- constructor(message, data, status) {
2072
- super(message);
2073
- this.data = data;
2074
- this.status = status;
2075
- }
2076
- };
2077
-
2078
- // src/api/base/request.ts
2079
- var Agent = class {
2080
- base_url;
2081
- token;
2082
- requester;
2083
- constructor(url, token, type, suffix = "/api") {
2084
- this.base_url = z14.url("Invalid URL Schema").transform((url2) => new URL(url2).href).parse(url);
2085
- this.token = z14.string().regex(/^(ptl[ac]|pacc|papp)_.+$/, "Invalid token type").parse(token);
2086
- this.requester = axios3.create({
2087
- baseURL: this.base_url.replace(/\/+$/, "") + `${suffix}/${type}`,
2088
- timeout: 3e3,
2089
- headers: { Authorization: `Bearer ${this.token}` }
2090
- });
2091
- this.requester.interceptors.response.use(void 0, (error) => {
2092
- if (error.response && error.response.status === 400) {
2093
- return Promise.reject(
2094
- new PterodactylException(
2095
- "Invalid request data",
2096
- error.response.data,
2097
- error.response.status
2098
- )
2099
- );
2100
- }
2101
- return Promise.reject(error);
2102
- });
2103
- }
2105
+ server = (uuid) => new ServerClient(this.r, uuid);
2104
2106
  };
2105
2107
 
2106
2108
  // src/api/index.ts
2107
- var PelicanAPIClient = class extends Client {
2109
+ var PelicanAPIClient = class extends Client2 {
2108
2110
  constructor(url, token, suffix = "/api") {
2109
2111
  const ax = new Agent(url, token, "client", suffix);
2110
2112
  super(ax.requester);
2111
2113
  }
2112
2114
  };
2113
- var PelicanAPIApplication = class extends Client2 {
2115
+ var PelicanAPIApplication = class extends Client {
2114
2116
  constructor(url, token, suffix = "/api") {
2115
2117
  const ax = new Agent(url, token, "application", suffix);
2116
2118
  super(ax.requester);