@pelican.ts/sdk 0.4.15 → 0.4.16-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -43,948 +43,129 @@ __export(index_exports, {
43
43
  });
44
44
  module.exports = __toCommonJS(index_exports);
45
45
 
46
- // src/api/client/account.ts
46
+ // src/api/application/database_hosts.ts
47
47
  var import_zod = __toESM(require("zod"));
48
- var Account = class {
49
- r;
50
- constructor(requester) {
51
- this.r = requester;
52
- }
53
- info = async () => {
54
- const { data } = await this.r.get("/account");
55
- return data.attributes;
56
- };
57
- updateEmail = async (newEmail, password) => {
58
- newEmail = import_zod.default.email().parse(newEmail);
59
- await this.r.put("/account/email", { email: newEmail, password });
60
- };
61
- updatePassword = async (newPassword) => {
62
- newPassword = import_zod.default.string().min(8).parse(newPassword);
63
- await this.r.put("/account/password", {
64
- password: newPassword,
65
- password_confirmation: newPassword
66
- });
67
- };
68
- apiKeys = {
69
- list: async () => {
70
- const { data } = await this.r.get("/account/api-keys");
71
- return data.data.map((k) => k.attributes);
72
- },
73
- create: async (description, allowed_ips) => {
74
- allowed_ips = import_zod.default.array(import_zod.default.ipv4()).optional().parse(allowed_ips);
75
- const { data } = await this.r.post("/account/api-keys", { description, allowed_ips });
76
- return { ...data.attributes, secret_token: data.meta.secret_token };
77
- },
78
- delete: async (identifier) => {
79
- await this.r.delete(`/account/api-keys/${identifier}`);
80
- }
81
- };
82
- sshKeys = {
83
- list: async () => {
84
- const { data } = await this.r.get("/account/ssh-keys");
85
- return data.data.map((k) => k.attributes);
86
- },
87
- create: async (name, public_key) => {
88
- const { data } = await this.r.post("/account/ssh-keys", { name, public_key });
89
- return data.attributes;
90
- },
91
- delete: async (fingerprint) => {
92
- await this.r.delete(`/account/ssh-keys/${fingerprint}`);
93
- }
94
- };
95
- };
96
-
97
- // src/api/client/client.ts
98
- var import_zod5 = __toESM(require("zod"));
48
+ var CreateDBHostSchema = import_zod.default.object({
49
+ name: import_zod.default.string().min(1).max(255),
50
+ host: import_zod.default.string(),
51
+ port: import_zod.default.number().min(1).max(65535),
52
+ username: import_zod.default.string().min(1).max(255),
53
+ password: import_zod.default.string().optional(),
54
+ node_ids: import_zod.default.array(import_zod.default.string()).optional(),
55
+ max_databases: import_zod.default.number().optional()
56
+ });
99
57
 
100
- // src/api/client/server_databases.ts
58
+ // src/api/application/mounts.ts
101
59
  var import_zod2 = __toESM(require("zod"));
102
- var ServerDatabases = class {
103
- r;
104
- id;
105
- constructor(requester, id) {
106
- this.r = requester;
107
- this.id = id;
108
- }
109
- list = async (include, page = 1) => {
110
- import_zod2.default.number().positive().parse(page);
111
- const { data } = await this.r.get(`/servers/${this.id}/databases`, {
112
- params: { include: include?.join(","), page }
113
- });
114
- return data.data.map((d) => d.attributes);
115
- };
116
- create = async (database, remote) => {
117
- const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote });
118
- return data.attributes;
119
- };
120
- rotatePassword = async (database_id) => {
121
- const { data } = await this.r.post(`/servers/${this.id}/databases/${database_id}/rotate-password`);
122
- return data.attributes;
123
- };
124
- delete = async (database_id) => {
125
- await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
126
- };
127
- };
60
+ var CreateMountSchema = import_zod2.default.object({
61
+ name: import_zod2.default.string().min(1).max(255),
62
+ description: import_zod2.default.string().optional(),
63
+ source: import_zod2.default.string(),
64
+ target: import_zod2.default.string(),
65
+ read_only: import_zod2.default.boolean().optional()
66
+ });
128
67
 
129
- // src/api/client/server_files.ts
130
- var import_axios = __toESM(require("axios"));
131
- var ServerFiles = class {
132
- r;
133
- id;
134
- constructor(requester, id) {
135
- this.r = requester;
136
- this.id = id;
137
- }
138
- list = async (path2) => {
139
- const { data } = await this.r.get(`/servers/${this.id}/files/list`, { params: { directory: path2 } });
140
- return data.data.map((r) => r.attributes);
141
- };
142
- /**
143
- * Return the contents of a file. To read binary file (non-editable) use {@link download} instead
144
- */
145
- contents = async (path2) => {
146
- const { data } = await this.r.get(
147
- `/servers/${this.id}/files/contents`,
148
- { params: { file: path2 } }
149
- );
150
- return data;
151
- };
152
- downloadGetUrl = async (path2) => {
153
- const { data } = await this.r.get(`/servers/${this.id}/files/download`, { params: { file: path2 } });
154
- return data.attributes.url;
155
- };
156
- download = async (path2) => {
157
- const url = await this.downloadGetUrl(path2);
158
- const { data } = await import_axios.default.get(url, {
159
- responseType: "arraybuffer"
160
- });
161
- return data;
162
- };
163
- rename = async (root = "/", files) => {
164
- await this.r.put(`/servers/${this.id}/files/rename`, { root, files });
165
- };
166
- copy = async (location) => {
167
- await this.r.post(`/servers/${this.id}/files/copy`, { location });
168
- };
169
- write = async (path2, content) => {
170
- await this.r.post(`/servers/${this.id}/files/write`, content, {
171
- params: { file: path2 }
172
- });
173
- };
174
- compress = async (root = "/", files, archive_name, extension) => {
175
- const { data } = await this.r.post(`/servers/${this.id}/files/compress`, {
176
- root,
177
- files,
178
- archive_name,
179
- extension
180
- });
181
- return data.attributes;
182
- };
183
- decompress = async (root = "/", file) => {
184
- await this.r.post(`/servers/${this.id}/files/decompress`, { root, file });
185
- };
186
- delete = async (root = "/", files) => {
187
- await this.r.post(`/servers/${this.id}/files/delete`, { root, files });
188
- };
189
- createFolder = async (root = "/", name) => {
190
- await this.r.post(`/servers/${this.id}/files/create-folder`, {
191
- root,
192
- name
193
- });
194
- };
195
- chmod = async (root = "/", files) => {
196
- await this.r.post(`/servers/${this.id}/files/chmod`, { root, files });
197
- };
198
- pullFromRemote = async (url, directory, filename, use_header = false, foreground = false) => {
199
- await this.r.post(`/servers/${this.id}/files/pull`, {
200
- url,
201
- directory,
202
- filename,
203
- use_header,
204
- foreground
205
- });
206
- };
207
- uploadGetUrl = async () => {
208
- const { data } = await this.r.get(`/servers/${this.id}/files/upload`);
209
- return data.attributes.url;
210
- };
211
- upload = async (file, root = "/") => {
212
- const url = await this.uploadGetUrl();
213
- await import_axios.default.post(
214
- url,
215
- { files: file },
216
- {
217
- headers: { "Content-Type": "multipart/form-data" },
218
- params: { directory: root }
219
- }
220
- );
221
- };
222
- };
68
+ // src/api/application/nodes.ts
69
+ var import_zod4 = __toESM(require("zod"));
223
70
 
224
- // src/api/client/server_schedules.ts
225
- var ServerSchedules = class {
226
- r;
227
- id;
228
- constructor(requester, id) {
229
- this.r = requester;
230
- this.id = id;
231
- }
232
- list = async () => {
233
- const { data } = await this.r.get(`/servers/${this.id}/schedules`);
234
- return data.data.map((d) => d.attributes);
235
- };
236
- create = async (params) => {
237
- const { data } = await this.r.post(`/servers/${this.id}/schedules`, params);
238
- return data.attributes;
239
- };
240
- control = (sched_id) => new ScheduleControl(this.r, this.id, sched_id);
241
- };
242
- var ScheduleControl = class {
243
- r;
244
- id;
245
- sched_id;
246
- constructor(requester, id, sched_id) {
247
- this.r = requester;
248
- this.id = id;
249
- this.sched_id = sched_id;
250
- }
251
- info = async () => {
252
- const { data } = await this.r.get(`/servers/${this.id}/schedules/${this.sched_id}`);
253
- return data.attributes;
254
- };
255
- update = async (params) => {
256
- const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}`, params);
257
- return data.attributes;
258
- };
259
- delete = async () => {
260
- await this.r.delete(`/servers/${this.id}/schedules/${this.sched_id}`);
261
- };
262
- execute = async () => {
263
- await this.r.post(
264
- `/servers/${this.id}/schedules/${this.sched_id}/execute`
265
- );
266
- };
267
- tasks = {
268
- create: async (opts) => {
269
- const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}/tasks`, opts);
270
- return data.attributes;
271
- },
272
- update: async (task_id, opts) => {
273
- const { data } = await this.r.post(
274
- `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`,
275
- opts
276
- );
277
- return data.attributes;
278
- },
279
- delete: async (task_id) => {
280
- await this.r.delete(
281
- `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`
282
- );
283
- }
284
- };
285
- };
71
+ // src/api/application/nodes_allocations.ts
72
+ var import_zod3 = __toESM(require("zod"));
286
73
 
287
- // src/api/client/server_allocations.ts
288
- var ServerAllocations = class {
289
- r;
290
- id;
291
- constructor(requester, id) {
292
- this.r = requester;
293
- this.id = id;
294
- }
295
- list = async () => {
296
- const { data } = await this.r.get(`/servers/${this.id}/network/allocations`);
297
- return data.data.map((r) => r.attributes);
298
- };
299
- autoAssign = async () => {
300
- const { data } = await this.r.post(`/servers/${this.id}/network/allocations`);
301
- return data.attributes;
302
- };
303
- setNotes = async (alloc_id, notes) => {
304
- const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}`, { notes });
305
- return data.attributes;
306
- };
307
- setPrimary = async (alloc_id) => {
308
- const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}/primary`);
309
- return data.attributes;
310
- };
311
- unassign = async (alloc_id) => {
312
- await this.r.delete(
313
- `/servers/${this.id}/network/allocations/${alloc_id}`
314
- );
315
- };
316
- };
74
+ // src/api/application/nodes.ts
75
+ var NodeCreateSchema = import_zod4.default.object({
76
+ name: import_zod4.default.string().min(1).max(100),
77
+ description: import_zod4.default.string().optional(),
78
+ public: import_zod4.default.boolean().optional(),
79
+ fqdn: import_zod4.default.string().nonempty(),
80
+ scheme: import_zod4.default.enum(["http", "https"]),
81
+ behind_proxy: import_zod4.default.boolean().optional(),
82
+ memory: import_zod4.default.number().min(0),
83
+ memory_overallocate: import_zod4.default.number().min(-1),
84
+ disk: import_zod4.default.number().min(0),
85
+ disk_overallocate: import_zod4.default.number().min(-1),
86
+ cpu: import_zod4.default.number().min(0),
87
+ cpu_overallocate: import_zod4.default.number().min(-1),
88
+ daemon_base: import_zod4.default.string().nonempty().optional(),
89
+ daemon_sftp: import_zod4.default.number().min(1).max(65535),
90
+ daemon_sftp_alias: import_zod4.default.string().optional(),
91
+ daemon_listen: import_zod4.default.number().min(1).max(65535),
92
+ daemon_connect: import_zod4.default.number().min(1).max(65535),
93
+ maintenance_mode: import_zod4.default.boolean().optional(),
94
+ upload_size: import_zod4.default.number().min(1).max(1024),
95
+ tags: import_zod4.default.array(import_zod4.default.string()).optional()
96
+ });
317
97
 
318
- // src/api/client/server_users.ts
319
- var ServerUsers = class {
320
- r;
321
- id;
322
- constructor(requester, id) {
323
- this.r = requester;
324
- this.id = id;
325
- }
326
- list = async () => {
327
- const { data } = await this.r.get(`/servers/${this.id}/users`);
328
- return data.data.map((d) => d.attributes);
329
- };
330
- create = async (email, permissions) => {
331
- const { data } = await this.r.post(`/servers/${this.id}/users`, { email, permissions });
332
- return data.attributes;
333
- };
334
- info = async (user_uuid) => {
335
- const { data } = await this.r.get(
336
- `/servers/${this.id}/users/${user_uuid}`
337
- );
338
- return data.attributes;
339
- };
340
- update = async (user_uuid, permissions) => {
341
- const { data } = await this.r.put(
342
- `/servers/${this.id}/users/${user_uuid}`,
343
- { permissions }
344
- );
345
- return data.attributes;
346
- };
347
- delete = async (user_uuid) => {
348
- await this.r.delete(`/servers/${this.id}/users/${user_uuid}`);
349
- };
350
- };
98
+ // src/api/application/servers.ts
99
+ var import_zod6 = __toESM(require("zod"));
351
100
 
352
- // src/api/client/server_backups.ts
353
- var import_axios2 = __toESM(require("axios"));
354
- var import_zod3 = __toESM(require("zod"));
355
- var ServerBackups = class {
356
- r;
357
- id;
358
- constructor(requester, id) {
359
- this.r = requester;
360
- this.id = id;
361
- }
362
- list = async (page = 1) => {
363
- import_zod3.default.number().positive().parse(page);
364
- const { data } = await this.r.get(`/servers/${this.id}/backups`, { params: { page } });
365
- return data.data.map((d) => d.attributes);
366
- };
367
- create = async (args) => {
368
- args.name = import_zod3.default.string().max(255).optional().parse(args.name);
369
- const { data } = await this.r.post(`/servers/${this.id}/backups`, {
370
- name: args.name,
371
- is_locked: args.is_locked,
372
- ignored_files: args.ignored_files.join("\n")
373
- });
374
- return data.attributes;
375
- };
376
- info = async (backup_uuid) => {
377
- const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}`);
378
- return data.attributes;
379
- };
380
- downloadGetUrl = async (backup_uuid) => {
381
- const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}/download`);
382
- return data.attributes.url;
383
- };
384
- download = async (backup_uuid) => {
385
- const url = await this.downloadGetUrl(backup_uuid);
386
- const { data } = await import_axios2.default.get(url, {
387
- responseType: "arraybuffer"
388
- });
389
- return data;
390
- };
391
- delete = async (backup_uuid) => {
392
- await this.r.delete(`/servers/${this.id}/backups/${backup_uuid}`);
393
- };
394
- rename = async (backup_uuid, name) => {
395
- await this.r.put(`/servers/${this.id}/backups/${backup_uuid}/rename`, {
396
- name
397
- });
398
- };
399
- toggleLock = async (backup_uuid) => {
400
- await this.r.post(`/servers/${this.id}/backups/${backup_uuid}/lock`);
401
- };
402
- restore = async (backup_uuid, truncate) => {
403
- await this.r.post(
404
- `/servers/${this.id}/backups/${backup_uuid}/restore`,
405
- { truncate }
406
- );
407
- };
408
- };
101
+ // src/api/application/servers_databases.ts
102
+ var import_zod5 = __toESM(require("zod"));
409
103
 
410
- // src/api/client/server_startup.ts
411
- var ServerStartup = class {
412
- r;
413
- id;
414
- constructor(requester, id) {
415
- this.r = requester;
416
- this.id = id;
417
- }
418
- list = async () => {
419
- const { data } = await this.r.get(`/servers/${this.id}/startup`);
420
- return {
421
- object: "list",
422
- meta: data.meta,
423
- data: data.data.map((d) => d.attributes)
424
- };
425
- };
426
- set = async (key, value) => {
427
- const { data } = await this.r.put(`/servers/${this.id}/startup/variable`, { key, value });
428
- return data.attributes;
429
- };
430
- };
104
+ // src/api/application/servers.ts
105
+ var CreateServerSchema = import_zod6.default.object({
106
+ external_id: import_zod6.default.string().min(1).max(255).optional(),
107
+ name: import_zod6.default.string().min(1).max(255),
108
+ description: import_zod6.default.string().optional(),
109
+ user: import_zod6.default.number(),
110
+ egg: import_zod6.default.number(),
111
+ docker_image: import_zod6.default.string().optional(),
112
+ startup: import_zod6.default.string().optional(),
113
+ environment: import_zod6.default.record(import_zod6.default.string(), import_zod6.default.string()),
114
+ skip_scripts: import_zod6.default.boolean().optional(),
115
+ oom_killer: import_zod6.default.boolean().optional(),
116
+ start_on_completion: import_zod6.default.boolean().optional(),
117
+ docker_labels: import_zod6.default.record(import_zod6.default.string(), import_zod6.default.string()).optional(),
118
+ limits: import_zod6.default.object({
119
+ memory: import_zod6.default.number().min(0),
120
+ swap: import_zod6.default.number().min(-1),
121
+ disk: import_zod6.default.number().min(0),
122
+ io: import_zod6.default.number().min(0),
123
+ threads: import_zod6.default.string().optional(),
124
+ cpu: import_zod6.default.number().min(0)
125
+ }),
126
+ feature_limits: import_zod6.default.object({
127
+ databases: import_zod6.default.number().min(0),
128
+ allocations: import_zod6.default.number().min(0),
129
+ backups: import_zod6.default.number().min(0)
130
+ }),
131
+ allocation: import_zod6.default.object({
132
+ default: import_zod6.default.string().nullable(),
133
+ additional: import_zod6.default.array(import_zod6.default.string()).optional()
134
+ }).optional(),
135
+ deploy: import_zod6.default.object({
136
+ tags: import_zod6.default.array(import_zod6.default.string()).optional(),
137
+ dedicated_ip: import_zod6.default.boolean().optional(),
138
+ port_range: import_zod6.default.array(import_zod6.default.string()).optional()
139
+ }).optional()
140
+ });
141
+ var UpdateDetailsSchema = CreateServerSchema.pick({
142
+ external_id: true,
143
+ name: true,
144
+ user: true,
145
+ description: true,
146
+ docker_labels: true
147
+ });
148
+ var UpdateBuildSchema = CreateServerSchema.pick({
149
+ oom_killer: true,
150
+ limits: true,
151
+ feature_limits: true
152
+ }).extend({
153
+ allocation: import_zod6.default.number().optional(),
154
+ add_allocations: import_zod6.default.array(import_zod6.default.string()).optional(),
155
+ remove_allocations: import_zod6.default.array(import_zod6.default.string()).optional()
156
+ });
157
+ var UpdateStartupSchema = CreateServerSchema.pick({
158
+ startup: true,
159
+ environment: true,
160
+ egg: true
161
+ }).extend({ image: import_zod6.default.string().optional(), skip_scripts: import_zod6.default.boolean() });
431
162
 
432
- // src/api/client/server_settings.ts
433
- var import_zod4 = __toESM(require("zod"));
434
- var ServerSettings = class {
435
- r;
436
- id;
437
- constructor(requester, id) {
438
- this.r = requester;
439
- this.id = id;
440
- }
441
- rename = async (name) => {
442
- name = import_zod4.default.string().max(255).parse(name);
443
- await this.r.post(`/servers/${this.id}/settings/rename`, { name });
444
- };
445
- updateDescription = async (description) => {
446
- await this.r.post(`/servers/${this.id}/settings/description`, {
447
- description
448
- });
449
- };
450
- reinstall = async () => {
451
- await this.r.post(`/servers/${this.id}/settings/reinstall`);
452
- };
453
- changeDockerImage = async (image) => {
454
- await this.r.put(`/servers/${this.id}/settings/docker-image`, {
455
- docker_image: image
456
- });
457
- };
458
- };
459
-
460
- // src/api/client/server_websocket.ts
461
- var import_events = require("events");
462
- var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
463
- var import_strip_color = __toESM(require("strip-color"));
464
- var isBrowser = typeof window !== "undefined";
465
- var RECONNECT_ERRORS = /* @__PURE__ */ new Set([
466
- "jwt: exp claim is invalid",
467
- "jwt: created too far in past (denylist)"
468
- ]);
469
- var FALLBACK_LOG_MESSAGE = "No logs - is the server online?";
470
- var ServerWebsocket = class {
471
- r;
472
- serverId;
473
- socket;
474
- currentToken;
475
- bus = new import_events.EventEmitter();
476
- debugLogging = false;
477
- stripColors;
478
- detachMessageListener;
479
- constructor(requester, id, stripColors = false) {
480
- this.r = requester;
481
- this.serverId = id;
482
- this.stripColors = stripColors;
483
- }
484
- on(event, listener) {
485
- const handler = listener;
486
- this.bus.on(event, handler);
487
- return () => {
488
- this.bus.removeListener(event, handler);
489
- };
490
- }
491
- deregister(event, listener) {
492
- const handler = listener;
493
- this.bus.removeListener(event, handler);
494
- }
495
- emit(event, ...args) {
496
- if (args.length === 0) {
497
- this.bus.emit(event);
498
- } else {
499
- this.bus.emit(event, args[0]);
500
- }
501
- }
502
- async connect(resumable, debugLogging) {
503
- this.debugLogging = debugLogging ?? false;
504
- if (this.socket) {
505
- return;
506
- }
507
- const socketUrl = await this.refreshCredentials();
508
- this.socket = isBrowser ? new import_isomorphic_ws.default(socketUrl) : new import_isomorphic_ws.default(socketUrl, void 0, {
509
- origin: new URL(socketUrl).origin
510
- });
511
- await new Promise((resolve, reject) => {
512
- const socket = this.socket;
513
- if (!socket) {
514
- reject(new Error("Failed to create socket connection"));
515
- return;
516
- }
517
- socket.onopen = async () => {
518
- try {
519
- await this.authenticate();
520
- this.attachMessageListener();
521
- socket.onopen = null;
522
- socket.onerror = null;
523
- resolve();
524
- } catch (error) {
525
- socket.onopen = null;
526
- socket.onerror = null;
527
- reject(
528
- error instanceof Error ? error : new Error("Websocket authentication failed")
529
- );
530
- }
531
- };
532
- socket.onerror = (event) => {
533
- socket.onopen = null;
534
- socket.onerror = null;
535
- reject(
536
- event instanceof Error ? event : new Error("Websocket connection error")
537
- );
538
- };
539
- });
540
- if (resumable) {
541
- this.makeResumable(true);
542
- }
543
- }
544
- onSocketDisconnect(handler) {
545
- if (!this.socket) {
546
- console.error(new Error("No socket connection"));
547
- return;
548
- }
549
- this.socket.onclose = handler;
550
- }
551
- onSocketError(handler) {
552
- if (!this.socket) {
553
- console.error(new Error("No socket connection"));
554
- return;
555
- }
556
- this.socket.onerror = handler;
557
- }
558
- makeResumable(disconnectsToo) {
559
- const scheduleReconnect = () => {
560
- setTimeout(() => {
561
- const previous = this.socket;
562
- this.detachMessageListener?.();
563
- this.detachMessageListener = void 0;
564
- this.socket = void 0;
565
- previous?.close();
566
- void this.connect(true, this.debugLogging);
567
- }, 1e3);
568
- };
569
- this.onSocketError(() => scheduleReconnect());
570
- if (disconnectsToo) {
571
- this.onSocketDisconnect(() => scheduleReconnect());
572
- }
573
- }
574
- attachMessageListener() {
575
- if (!this.socket) {
576
- throw new Error("No socket connection");
577
- }
578
- this.detachMessageListener?.();
579
- const handler = (event) => {
580
- void this.handleIncomingMessage(event);
581
- };
582
- if (typeof this.socket.addEventListener === "function") {
583
- this.socket.addEventListener(
584
- "message",
585
- handler
586
- );
587
- this.detachMessageListener = () => {
588
- this.socket?.removeEventListener?.(
589
- "message",
590
- handler
591
- );
592
- };
593
- } else {
594
- const fallback = (data) => handler({ data });
595
- const socket = this.socket;
596
- socket.on?.("message", fallback);
597
- this.detachMessageListener = () => {
598
- const target = this.socket;
599
- if (!target) {
600
- return;
601
- }
602
- if (typeof target.off === "function") {
603
- target.off("message", fallback);
604
- } else if (typeof target.removeListener === "function") {
605
- target.removeListener("message", fallback);
606
- }
607
- };
608
- }
609
- }
610
- async handleIncomingMessage(event) {
611
- const message = this.parseMessage(event);
612
- if (!message) {
613
- return;
614
- }
615
- try {
616
- await this.dispatchMessage(message);
617
- } catch (error) {
618
- if (this.debugLogging) {
619
- console.error("Error while handling websocket message", error);
620
- }
621
- }
622
- }
623
- parseMessage(event) {
624
- const payload = this.normalisePayload(event);
625
- if (!payload) {
626
- return null;
627
- }
628
- try {
629
- return JSON.parse(payload);
630
- } catch (error) {
631
- if (this.debugLogging) {
632
- console.warn("Failed to parse websocket payload", error);
633
- }
634
- return null;
635
- }
636
- }
637
- normalisePayload(event) {
638
- if (typeof event === "string") {
639
- return event;
640
- }
641
- if (typeof event === "object" && event !== null && "data" in event) {
642
- return this.normalisePayload(event.data);
643
- }
644
- if (typeof Buffer !== "undefined" && Buffer.isBuffer(event)) {
645
- return event.toString("utf8");
646
- }
647
- if (typeof ArrayBuffer !== "undefined" && event instanceof ArrayBuffer) {
648
- if (typeof TextDecoder !== "undefined") {
649
- return new TextDecoder().decode(new Uint8Array(event));
650
- }
651
- if (typeof Buffer !== "undefined") {
652
- return Buffer.from(event).toString("utf8");
653
- }
654
- }
655
- return null;
656
- }
657
- async dispatchMessage(message) {
658
- switch (message.event) {
659
- case "auth success" /* AUTH_SUCCESS */: {
660
- if (this.debugLogging) {
661
- console.debug("Auth success");
662
- }
663
- this.emit("auth success" /* AUTH_SUCCESS */);
664
- break;
665
- }
666
- case "status" /* STATUS */: {
667
- if (this.debugLogging) {
668
- console.debug("Received status event", message.args[0]);
669
- }
670
- this.emit("status" /* STATUS */, message.args[0]);
671
- break;
672
- }
673
- case "console output" /* CONSOLE_OUTPUT */: {
674
- let output = message.args[0];
675
- if (this.stripColors) {
676
- output = (0, import_strip_color.default)(output);
677
- }
678
- if (this.debugLogging) {
679
- console.debug("Received console output", output);
680
- }
681
- this.emit("console output" /* CONSOLE_OUTPUT */, output);
682
- break;
683
- }
684
- case "stats" /* STATS */: {
685
- try {
686
- const payload = JSON.parse(message.args[0]);
687
- this.emit("stats" /* STATS */, payload);
688
- } catch (error) {
689
- if (this.debugLogging) {
690
- console.warn("Failed to parse stats payload", error);
691
- }
692
- }
693
- break;
694
- }
695
- case "daemon error" /* DAEMON_ERROR */: {
696
- this.emit("daemon error" /* DAEMON_ERROR */);
697
- break;
698
- }
699
- case "backup completed" /* BACKUP_COMPLETED */: {
700
- try {
701
- const payload = JSON.parse(
702
- message.args[0]
703
- );
704
- this.emit("backup completed" /* BACKUP_COMPLETED */, payload);
705
- } catch (error) {
706
- if (this.debugLogging) {
707
- console.warn("Failed to parse backup payload", error);
708
- }
709
- }
710
- break;
711
- }
712
- case "daemon message" /* DAEMON_MESSAGE */: {
713
- let output = message.args[0];
714
- if (this.stripColors) {
715
- output = (0, import_strip_color.default)(output);
716
- }
717
- this.emit("daemon message" /* DAEMON_MESSAGE */, output);
718
- break;
719
- }
720
- case "install output" /* INSTALL_OUTPUT */: {
721
- let output = message.args[0];
722
- if (this.stripColors) {
723
- output = (0, import_strip_color.default)(output);
724
- }
725
- this.emit("install output" /* INSTALL_OUTPUT */, output);
726
- break;
727
- }
728
- case "backup restore completed" /* BACKUP_RESTORE_COMPLETED */: {
729
- this.emit("backup restore completed" /* BACKUP_RESTORE_COMPLETED */);
730
- break;
731
- }
732
- case "install completed" /* INSTALL_COMPLETED */: {
733
- this.emit("install completed" /* INSTALL_COMPLETED */);
734
- break;
735
- }
736
- case "install started" /* INSTALL_STARTED */: {
737
- this.emit("install started" /* INSTALL_STARTED */);
738
- break;
739
- }
740
- case "transfer logs" /* TRANSFER_LOGS */: {
741
- this.emit("transfer logs" /* TRANSFER_LOGS */, message.args[0]);
742
- break;
743
- }
744
- case "transfer status" /* TRANSFER_STATUS */: {
745
- this.emit("transfer status" /* TRANSFER_STATUS */, message.args[0]);
746
- break;
747
- }
748
- case "token expiring" /* TOKEN_EXPIRING */: {
749
- this.emit("token expiring" /* TOKEN_EXPIRING */);
750
- if (this.debugLogging) {
751
- console.warn("Token expiring, renewing...");
752
- }
753
- await this.refreshCredentials();
754
- await this.authenticate();
755
- break;
756
- }
757
- case "token expired" /* TOKEN_EXPIRED */: {
758
- this.emit("token expired" /* TOKEN_EXPIRED */);
759
- throw new Error("Token expired");
760
- }
761
- case "jwt error" /* JWT_ERROR */: {
762
- const reason = message.args[0];
763
- if (RECONNECT_ERRORS.has(reason)) {
764
- this.emit("token expiring" /* TOKEN_EXPIRING */);
765
- if (this.debugLogging) {
766
- console.warn("Token expiring (JWT error), renewing...");
767
- }
768
- await this.refreshCredentials();
769
- await this.authenticate();
770
- } else {
771
- this.emit("jwt error" /* JWT_ERROR */, reason);
772
- throw new Error("Token expired");
773
- }
774
- break;
775
- }
776
- default: {
777
- if (this.debugLogging) {
778
- console.warn("Unknown websocket event", message);
779
- }
780
- break;
781
- }
782
- }
783
- }
784
- async refreshCredentials() {
785
- const { data } = await this.r.get(
786
- `/servers/${this.serverId}/websocket`
787
- );
788
- this.currentToken = data.data.token;
789
- return data.data.socket;
790
- }
791
- async authenticate() {
792
- if (!this.socket) {
793
- throw new Error("No socket connection");
794
- }
795
- if (!this.currentToken) {
796
- throw new Error("Missing websocket token");
797
- }
798
- this.socket.send(
799
- JSON.stringify({ event: "auth", args: [this.currentToken] })
800
- );
801
- }
802
- disconnect() {
803
- this.detachMessageListener?.();
804
- this.detachMessageListener = void 0;
805
- if (this.socket) {
806
- this.socket.close();
807
- this.socket = void 0;
808
- }
809
- }
810
- requestStats() {
811
- this.send("send stats", [null]);
812
- }
813
- requestLogs() {
814
- this.send("send logs", [null]);
815
- }
816
- send(event, args) {
817
- if (!this.socket) {
818
- if (this.debugLogging) {
819
- console.warn(
820
- `Attempted to send "${event}" without an active websocket connection`
821
- );
822
- }
823
- return;
824
- }
825
- this.socket.send(JSON.stringify({ event, args }));
826
- }
827
- getStats() {
828
- return new Promise((resolve, reject) => {
829
- if (!this.socket) {
830
- reject(new Error("No socket connection"));
831
- return;
832
- }
833
- let off;
834
- const timeout = setTimeout(() => {
835
- off?.();
836
- reject(new Error("Timed out waiting for stats"));
837
- }, 5e3);
838
- off = this.on("stats" /* STATS */, (payload) => {
839
- clearTimeout(timeout);
840
- off?.();
841
- resolve(payload);
842
- });
843
- this.requestStats();
844
- });
845
- }
846
- getLogs() {
847
- return new Promise((resolve, reject) => {
848
- if (!this.socket) {
849
- reject(new Error("No socket connection"));
850
- return;
851
- }
852
- const lines = [];
853
- let off;
854
- let initialTimeout;
855
- let idleTimeout;
856
- const finalize = (payload) => {
857
- off?.();
858
- if (initialTimeout) {
859
- clearTimeout(initialTimeout);
860
- }
861
- if (idleTimeout) {
862
- clearTimeout(idleTimeout);
863
- }
864
- resolve(payload);
865
- };
866
- initialTimeout = setTimeout(() => {
867
- finalize(lines.length > 0 ? lines : [FALLBACK_LOG_MESSAGE]);
868
- }, 5e3);
869
- off = this.on("console output" /* CONSOLE_OUTPUT */, (line) => {
870
- lines.push(line);
871
- if (initialTimeout) {
872
- clearTimeout(initialTimeout);
873
- initialTimeout = void 0;
874
- }
875
- if (idleTimeout) {
876
- clearTimeout(idleTimeout);
877
- }
878
- idleTimeout = setTimeout(() => {
879
- finalize(lines);
880
- }, 1e3);
881
- });
882
- this.requestLogs();
883
- });
884
- }
885
- sendPoweraction(action) {
886
- this.send("set state", [action]);
887
- }
888
- sendCommand(cmd) {
889
- this.send("send command", [cmd]);
890
- }
891
- };
892
-
893
- // src/api/client/server_activity.ts
894
- var ServerActivity = class {
895
- r;
896
- id;
897
- constructor(r, id) {
898
- this.r = r;
899
- this.id = id;
900
- }
901
- list = async (page = 1, per_page = 25) => {
902
- const { data } = await this.r.get(`/server/${this.id}/activity`, { params: { page, per_page } });
903
- return data.data.map((log) => log.attributes);
904
- };
905
- };
906
-
907
- // src/api/client/server.ts
908
- var ServerClient = class {
909
- r;
910
- id;
911
- activity;
912
- databases;
913
- files;
914
- schedules;
915
- allocations;
916
- users;
917
- backups;
918
- startup;
919
- variables;
920
- settings;
921
- constructor(requester, id) {
922
- this.r = requester;
923
- this.id = id;
924
- this.activity = new ServerActivity(requester, id);
925
- this.databases = new ServerDatabases(requester, id);
926
- this.files = new ServerFiles(requester, id);
927
- this.schedules = new ServerSchedules(requester, id);
928
- this.allocations = new ServerAllocations(requester, id);
929
- this.users = new ServerUsers(requester, id);
930
- this.backups = new ServerBackups(requester, id);
931
- this.startup = new ServerStartup(requester, id);
932
- this.variables = this.startup;
933
- this.settings = new ServerSettings(requester, id);
934
- }
935
- info = async (include) => {
936
- const { data } = await this.r.get(
937
- `/servers/${this.id}`,
938
- { params: { include: include?.join(",") } }
939
- );
940
- return data.attributes;
941
- };
942
- websocket = (stripColors = false) => {
943
- return new ServerWebsocket(this.r, this.id, stripColors);
944
- };
945
- resources = async () => {
946
- const { data } = await this.r.get(
947
- `/servers/${this.id}/resources`
948
- );
949
- return data.attributes;
950
- };
951
- command = async (command) => {
952
- await this.r.post(`/servers/${this.id}/command`, { command });
953
- };
954
- power = async (signal) => {
955
- await this.r.post(`/servers/${this.id}/power`, { signal });
956
- };
957
- };
958
-
959
- // src/api/client/client.ts
960
- var Client = class {
961
- account;
962
- r;
963
- constructor(requester) {
964
- this.r = requester;
965
- this.account = new Account(requester);
966
- }
967
- get $r() {
968
- return this.r;
969
- }
970
- listPermissions = async () => {
971
- const { data } = await this.r.get("/permissions");
972
- return data.attributes.permissions;
973
- };
974
- listServers = async (type = "accessible", page = 1, per_page = 50, include) => {
975
- import_zod5.default.number().positive().parse(page);
976
- const { data } = await this.r.get("/", { params: { type, page, include: include?.join(",") } });
977
- return data.data.map((s) => s.attributes);
978
- };
979
- server = (uuid) => new ServerClient(this.r, uuid);
980
- };
981
-
982
- // src/api/application/users.ts
983
- var import_zod7 = __toESM(require("zod"));
163
+ // src/api/application/users.ts
164
+ var import_zod8 = __toESM(require("zod"));
984
165
 
985
166
  // src/api/common/types/enums.ts
986
- var import_zod6 = __toESM(require("zod"));
987
- var languagesSchema = import_zod6.default.enum([
167
+ var import_zod7 = __toESM(require("zod"));
168
+ var languagesSchema = import_zod7.default.enum([
988
169
  "af",
989
170
  "ak",
990
171
  "am",
@@ -1120,7 +301,7 @@ var languagesSchema = import_zod6.default.enum([
1120
301
  "zh",
1121
302
  "zu"
1122
303
  ]);
1123
- var timezonesSchema = import_zod6.default.enum([
304
+ var timezonesSchema = import_zod7.default.enum([
1124
305
  "Africa/Abidjan",
1125
306
  "Africa/Accra",
1126
307
  "Africa/Addis_Ababa",
@@ -1542,172 +723,993 @@ var timezonesSchema = import_zod6.default.enum([
1542
723
  "UTC"
1543
724
  ]);
1544
725
 
1545
- // src/api/application/users.ts
1546
- var CreateSchema = import_zod7.default.object({
1547
- email: import_zod7.default.email(),
1548
- external_id: import_zod7.default.string().max(255).optional(),
1549
- username: import_zod7.default.string().min(1).max(255),
1550
- password: import_zod7.default.string().optional(),
1551
- language: languagesSchema,
1552
- timezone: timezonesSchema
1553
- });
726
+ // src/api/application/users.ts
727
+ var CreateSchema = import_zod8.default.object({
728
+ email: import_zod8.default.email(),
729
+ external_id: import_zod8.default.string().max(255).optional(),
730
+ username: import_zod8.default.string().min(1).max(255),
731
+ password: import_zod8.default.string().optional(),
732
+ language: languagesSchema,
733
+ timezone: timezonesSchema
734
+ });
735
+
736
+ // src/api/base/request.ts
737
+ var import_axios = __toESM(require("axios"));
738
+ var import_zod9 = __toESM(require("zod"));
739
+
740
+ // src/api/base/types.ts
741
+ var PterodactylException = class extends Error {
742
+ data;
743
+ status;
744
+ constructor(message, data, status) {
745
+ super(message);
746
+ this.data = data;
747
+ this.status = status;
748
+ }
749
+ };
750
+
751
+ // src/api/base/request.ts
752
+ var Agent = class {
753
+ base_url;
754
+ token;
755
+ requester;
756
+ constructor(url, token, type, suffix = "/api") {
757
+ this.base_url = import_zod9.default.url("Invalid URL Schema").transform((url2) => new URL(url2).href).parse(url);
758
+ this.token = import_zod9.default.string().regex(/^(ptl[ac]|pacc|papp)_.+$/, "Invalid token type").parse(token);
759
+ this.requester = import_axios.default.create({
760
+ baseURL: this.base_url.replace(/\/+$/, "") + `${suffix}/${type}`,
761
+ timeout: 3e3,
762
+ headers: { Authorization: `Bearer ${this.token}` }
763
+ });
764
+ this.requester.interceptors.response.use(void 0, (error) => {
765
+ if (error.response && error.response.status === 400) {
766
+ return Promise.reject(
767
+ new PterodactylException(
768
+ "Invalid request data",
769
+ error.response.data,
770
+ error.response.status
771
+ )
772
+ );
773
+ }
774
+ return Promise.reject(error);
775
+ });
776
+ }
777
+ };
1554
778
 
1555
- // src/api/application/nodes_allocations.ts
1556
- var import_zod8 = __toESM(require("zod"));
779
+ // src/api/client/client.ts
780
+ var import_zod14 = __toESM(require("zod"));
1557
781
 
1558
- // src/api/application/nodes.ts
1559
- var import_zod9 = __toESM(require("zod"));
1560
- var NodeCreateSchema = import_zod9.default.object({
1561
- name: import_zod9.default.string().min(1).max(100),
1562
- description: import_zod9.default.string().optional(),
1563
- public: import_zod9.default.boolean().optional(),
1564
- fqdn: import_zod9.default.string().nonempty(),
1565
- scheme: import_zod9.default.enum(["http", "https"]),
1566
- behind_proxy: import_zod9.default.boolean().optional(),
1567
- memory: import_zod9.default.number().min(0),
1568
- memory_overallocate: import_zod9.default.number().min(-1),
1569
- disk: import_zod9.default.number().min(0),
1570
- disk_overallocate: import_zod9.default.number().min(-1),
1571
- cpu: import_zod9.default.number().min(0),
1572
- cpu_overallocate: import_zod9.default.number().min(-1),
1573
- daemon_base: import_zod9.default.string().nonempty().optional(),
1574
- daemon_sftp: import_zod9.default.number().min(1).max(65535),
1575
- daemon_sftp_alias: import_zod9.default.string().optional(),
1576
- daemon_listen: import_zod9.default.number().min(1).max(65535),
1577
- daemon_connect: import_zod9.default.number().min(1).max(65535),
1578
- maintenance_mode: import_zod9.default.boolean().optional(),
1579
- upload_size: import_zod9.default.number().min(1).max(1024),
1580
- tags: import_zod9.default.array(import_zod9.default.string()).optional()
1581
- });
782
+ // src/api/client/account.ts
783
+ var import_zod10 = __toESM(require("zod"));
784
+ var Account = class {
785
+ r;
786
+ constructor(requester) {
787
+ this.r = requester;
788
+ }
789
+ info = async () => {
790
+ const { data } = await this.r.get("/account");
791
+ return data.attributes;
792
+ };
793
+ updateEmail = async (newEmail, password) => {
794
+ newEmail = import_zod10.default.email().parse(newEmail);
795
+ await this.r.put("/account/email", { email: newEmail, password });
796
+ };
797
+ updatePassword = async (newPassword) => {
798
+ newPassword = import_zod10.default.string().min(8).parse(newPassword);
799
+ await this.r.put("/account/password", {
800
+ password: newPassword,
801
+ password_confirmation: newPassword
802
+ });
803
+ };
804
+ apiKeys = {
805
+ list: async () => {
806
+ const { data } = await this.r.get("/account/api-keys");
807
+ return data.data.map((k) => k.attributes);
808
+ },
809
+ create: async (description, allowed_ips) => {
810
+ allowed_ips = import_zod10.default.array(import_zod10.default.ipv4()).optional().parse(allowed_ips);
811
+ const { data } = await this.r.post("/account/api-keys", { description, allowed_ips });
812
+ return { ...data.attributes, secret_token: data.meta.secret_token };
813
+ },
814
+ delete: async (identifier) => {
815
+ await this.r.delete(`/account/api-keys/${identifier}`);
816
+ }
817
+ };
818
+ sshKeys = {
819
+ list: async () => {
820
+ const { data } = await this.r.get("/account/ssh-keys");
821
+ return data.data.map((k) => k.attributes);
822
+ },
823
+ create: async (name, public_key) => {
824
+ const { data } = await this.r.post("/account/ssh-keys", { name, public_key });
825
+ return data.attributes;
826
+ },
827
+ delete: async (fingerprint) => {
828
+ await this.r.delete(`/account/ssh-keys/${fingerprint}`);
829
+ }
830
+ };
831
+ };
1582
832
 
1583
- // src/api/application/servers.ts
833
+ // src/api/client/server_activity.ts
834
+ var ServerActivity = class {
835
+ r;
836
+ id;
837
+ constructor(r, id) {
838
+ this.r = r;
839
+ this.id = id;
840
+ }
841
+ list = async (page = 1, per_page = 25) => {
842
+ const { data } = await this.r.get(`/server/${this.id}/activity`, { params: { page, per_page } });
843
+ return data.data.map((log) => log.attributes);
844
+ };
845
+ };
846
+
847
+ // src/api/client/server_allocations.ts
848
+ var ServerAllocations = class {
849
+ r;
850
+ id;
851
+ constructor(requester, id) {
852
+ this.r = requester;
853
+ this.id = id;
854
+ }
855
+ list = async () => {
856
+ const { data } = await this.r.get(`/servers/${this.id}/network/allocations`);
857
+ return data.data.map((r) => r.attributes);
858
+ };
859
+ autoAssign = async () => {
860
+ const { data } = await this.r.post(`/servers/${this.id}/network/allocations`);
861
+ return data.attributes;
862
+ };
863
+ setNotes = async (alloc_id, notes) => {
864
+ const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}`, { notes });
865
+ return data.attributes;
866
+ };
867
+ setPrimary = async (alloc_id) => {
868
+ const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}/primary`);
869
+ return data.attributes;
870
+ };
871
+ unassign = async (alloc_id) => {
872
+ await this.r.delete(
873
+ `/servers/${this.id}/network/allocations/${alloc_id}`
874
+ );
875
+ };
876
+ };
877
+
878
+ // src/api/client/server_backups.ts
879
+ var import_axios2 = __toESM(require("axios"));
1584
880
  var import_zod11 = __toESM(require("zod"));
881
+ var ServerBackups = class {
882
+ r;
883
+ id;
884
+ constructor(requester, id) {
885
+ this.r = requester;
886
+ this.id = id;
887
+ }
888
+ list = async (page = 1) => {
889
+ import_zod11.default.number().positive().parse(page);
890
+ const { data } = await this.r.get(`/servers/${this.id}/backups`, { params: { page } });
891
+ return data.data.map((d) => d.attributes);
892
+ };
893
+ create = async (args) => {
894
+ args.name = import_zod11.default.string().max(255).optional().parse(args.name);
895
+ const { data } = await this.r.post(`/servers/${this.id}/backups`, {
896
+ name: args.name,
897
+ is_locked: args.is_locked,
898
+ ignored_files: args.ignored_files.join("\n")
899
+ });
900
+ return data.attributes;
901
+ };
902
+ info = async (backup_uuid) => {
903
+ const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}`);
904
+ return data.attributes;
905
+ };
906
+ downloadGetUrl = async (backup_uuid) => {
907
+ const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}/download`);
908
+ return data.attributes.url;
909
+ };
910
+ download = async (backup_uuid) => {
911
+ const url = await this.downloadGetUrl(backup_uuid);
912
+ const { data } = await import_axios2.default.get(url, {
913
+ responseType: "arraybuffer"
914
+ });
915
+ return data;
916
+ };
917
+ delete = async (backup_uuid) => {
918
+ await this.r.delete(`/servers/${this.id}/backups/${backup_uuid}`);
919
+ };
920
+ rename = async (backup_uuid, name) => {
921
+ await this.r.put(`/servers/${this.id}/backups/${backup_uuid}/rename`, {
922
+ name
923
+ });
924
+ };
925
+ toggleLock = async (backup_uuid) => {
926
+ await this.r.post(`/servers/${this.id}/backups/${backup_uuid}/lock`);
927
+ };
928
+ restore = async (backup_uuid, truncate) => {
929
+ await this.r.post(
930
+ `/servers/${this.id}/backups/${backup_uuid}/restore`,
931
+ { truncate }
932
+ );
933
+ };
934
+ };
1585
935
 
1586
- // src/api/application/servers_databases.ts
1587
- var import_zod10 = __toESM(require("zod"));
936
+ // src/api/client/server_databases.ts
937
+ var import_zod12 = __toESM(require("zod"));
938
+ var ServerDatabases = class {
939
+ r;
940
+ id;
941
+ constructor(requester, id) {
942
+ this.r = requester;
943
+ this.id = id;
944
+ }
945
+ list = async (include, page = 1) => {
946
+ import_zod12.default.number().positive().parse(page);
947
+ const { data } = await this.r.get(`/servers/${this.id}/databases`, {
948
+ params: { include: include?.join(","), page }
949
+ });
950
+ return data.data.map((d) => d.attributes);
951
+ };
952
+ create = async (database, remote) => {
953
+ const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote });
954
+ return data.attributes;
955
+ };
956
+ rotatePassword = async (database_id) => {
957
+ const { data } = await this.r.post(`/servers/${this.id}/databases/${database_id}/rotate-password`);
958
+ return data.attributes;
959
+ };
960
+ delete = async (database_id) => {
961
+ await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
962
+ };
963
+ };
1588
964
 
1589
- // src/api/application/servers.ts
1590
- var CreateServerSchema = import_zod11.default.object({
1591
- external_id: import_zod11.default.string().min(1).max(255).optional(),
1592
- name: import_zod11.default.string().min(1).max(255),
1593
- description: import_zod11.default.string().optional(),
1594
- user: import_zod11.default.number(),
1595
- egg: import_zod11.default.number(),
1596
- docker_image: import_zod11.default.string().optional(),
1597
- startup: import_zod11.default.string().optional(),
1598
- environment: import_zod11.default.record(import_zod11.default.string(), import_zod11.default.string()),
1599
- skip_scripts: import_zod11.default.boolean().optional(),
1600
- oom_killer: import_zod11.default.boolean().optional(),
1601
- start_on_completion: import_zod11.default.boolean().optional(),
1602
- docker_labels: import_zod11.default.record(import_zod11.default.string(), import_zod11.default.string()).optional(),
1603
- limits: import_zod11.default.object({
1604
- memory: import_zod11.default.number().min(0),
1605
- swap: import_zod11.default.number().min(-1),
1606
- disk: import_zod11.default.number().min(0),
1607
- io: import_zod11.default.number().min(0),
1608
- threads: import_zod11.default.string().optional(),
1609
- cpu: import_zod11.default.number().min(0)
1610
- }),
1611
- feature_limits: import_zod11.default.object({
1612
- databases: import_zod11.default.number().min(0),
1613
- allocations: import_zod11.default.number().min(0),
1614
- backups: import_zod11.default.number().min(0)
1615
- }),
1616
- allocation: import_zod11.default.object({
1617
- default: import_zod11.default.string(),
1618
- additional: import_zod11.default.array(import_zod11.default.string()).optional()
1619
- }).optional(),
1620
- deploy: import_zod11.default.object({
1621
- tags: import_zod11.default.array(import_zod11.default.string()).optional(),
1622
- dedicated_ip: import_zod11.default.boolean().optional(),
1623
- port_range: import_zod11.default.array(import_zod11.default.string()).optional()
1624
- }).optional()
1625
- });
1626
- var UpdateDetailsSchema = CreateServerSchema.pick({
1627
- external_id: true,
1628
- name: true,
1629
- user: true,
1630
- description: true,
1631
- docker_labels: true
1632
- });
1633
- var UpdateBuildSchema = CreateServerSchema.pick({
1634
- oom_killer: true,
1635
- limits: true,
1636
- feature_limits: true
1637
- }).extend({
1638
- allocation: import_zod11.default.number().optional(),
1639
- add_allocations: import_zod11.default.array(import_zod11.default.string()).optional(),
1640
- remove_allocations: import_zod11.default.array(import_zod11.default.string()).optional()
1641
- });
1642
- var UpdateStartupSchema = CreateServerSchema.pick({
1643
- startup: true,
1644
- environment: true,
1645
- egg: true
1646
- }).extend({ image: import_zod11.default.string().optional(), skip_scripts: import_zod11.default.boolean() });
965
+ // src/api/client/server_files.ts
966
+ var import_axios3 = __toESM(require("axios"));
967
+ var ServerFiles = class {
968
+ r;
969
+ id;
970
+ constructor(requester, id) {
971
+ this.r = requester;
972
+ this.id = id;
973
+ }
974
+ list = async (path2) => {
975
+ const { data } = await this.r.get(`/servers/${this.id}/files/list`, { params: { directory: path2 } });
976
+ return data.data.map((r) => r.attributes);
977
+ };
978
+ /**
979
+ * Return the contents of a file. To read binary file (non-editable) use {@link download} instead
980
+ */
981
+ contents = async (path2) => {
982
+ const { data } = await this.r.get(
983
+ `/servers/${this.id}/files/contents`,
984
+ { params: { file: path2 } }
985
+ );
986
+ return data;
987
+ };
988
+ downloadGetUrl = async (path2) => {
989
+ const { data } = await this.r.get(`/servers/${this.id}/files/download`, { params: { file: path2 } });
990
+ return data.attributes.url;
991
+ };
992
+ download = async (path2) => {
993
+ const url = await this.downloadGetUrl(path2);
994
+ const { data } = await import_axios3.default.get(url, {
995
+ responseType: "arraybuffer"
996
+ });
997
+ return data;
998
+ };
999
+ rename = async (root = "/", files) => {
1000
+ await this.r.put(`/servers/${this.id}/files/rename`, { root, files });
1001
+ };
1002
+ copy = async (location) => {
1003
+ await this.r.post(`/servers/${this.id}/files/copy`, { location });
1004
+ };
1005
+ write = async (path2, content) => {
1006
+ await this.r.post(`/servers/${this.id}/files/write`, content, {
1007
+ params: { file: path2 }
1008
+ });
1009
+ };
1010
+ compress = async (root = "/", files, archive_name, extension) => {
1011
+ const { data } = await this.r.post(`/servers/${this.id}/files/compress`, {
1012
+ root,
1013
+ files,
1014
+ archive_name,
1015
+ extension
1016
+ });
1017
+ return data.attributes;
1018
+ };
1019
+ decompress = async (root = "/", file) => {
1020
+ await this.r.post(`/servers/${this.id}/files/decompress`, { root, file });
1021
+ };
1022
+ delete = async (root = "/", files) => {
1023
+ await this.r.post(`/servers/${this.id}/files/delete`, { root, files });
1024
+ };
1025
+ createFolder = async (root = "/", name) => {
1026
+ await this.r.post(`/servers/${this.id}/files/create-folder`, {
1027
+ root,
1028
+ name
1029
+ });
1030
+ };
1031
+ chmod = async (root = "/", files) => {
1032
+ await this.r.post(`/servers/${this.id}/files/chmod`, { root, files });
1033
+ };
1034
+ pullFromRemote = async (url, directory, filename, use_header = false, foreground = false) => {
1035
+ await this.r.post(`/servers/${this.id}/files/pull`, {
1036
+ url,
1037
+ directory,
1038
+ filename,
1039
+ use_header,
1040
+ foreground
1041
+ });
1042
+ };
1043
+ uploadGetUrl = async () => {
1044
+ const { data } = await this.r.get(`/servers/${this.id}/files/upload`);
1045
+ return data.attributes.url;
1046
+ };
1047
+ upload = async (file, root = "/") => {
1048
+ const url = await this.uploadGetUrl();
1049
+ await import_axios3.default.post(
1050
+ url,
1051
+ { files: file },
1052
+ {
1053
+ headers: { "Content-Type": "multipart/form-data" },
1054
+ params: { directory: root }
1055
+ }
1056
+ );
1057
+ };
1058
+ };
1647
1059
 
1648
- // src/api/application/database_hosts.ts
1649
- var import_zod12 = __toESM(require("zod"));
1650
- var CreateDBHostSchema = import_zod12.default.object({
1651
- name: import_zod12.default.string().min(1).max(255),
1652
- host: import_zod12.default.string(),
1653
- port: import_zod12.default.number().min(1).max(65535),
1654
- username: import_zod12.default.string().min(1).max(255),
1655
- password: import_zod12.default.string().optional(),
1656
- node_ids: import_zod12.default.array(import_zod12.default.string()).optional(),
1657
- max_databases: import_zod12.default.number().optional()
1658
- });
1060
+ // src/api/client/server_schedules.ts
1061
+ var ServerSchedules = class {
1062
+ r;
1063
+ id;
1064
+ constructor(requester, id) {
1065
+ this.r = requester;
1066
+ this.id = id;
1067
+ }
1068
+ list = async () => {
1069
+ const { data } = await this.r.get(`/servers/${this.id}/schedules`);
1070
+ return data.data.map((d) => d.attributes);
1071
+ };
1072
+ create = async (params) => {
1073
+ const { data } = await this.r.post(`/servers/${this.id}/schedules`, params);
1074
+ return data.attributes;
1075
+ };
1076
+ control = (sched_id) => new ScheduleControl(this.r, this.id, sched_id);
1077
+ };
1078
+ var ScheduleControl = class {
1079
+ r;
1080
+ id;
1081
+ sched_id;
1082
+ constructor(requester, id, sched_id) {
1083
+ this.r = requester;
1084
+ this.id = id;
1085
+ this.sched_id = sched_id;
1086
+ }
1087
+ info = async () => {
1088
+ const { data } = await this.r.get(`/servers/${this.id}/schedules/${this.sched_id}`);
1089
+ return data.attributes;
1090
+ };
1091
+ update = async (params) => {
1092
+ const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}`, params);
1093
+ return data.attributes;
1094
+ };
1095
+ delete = async () => {
1096
+ await this.r.delete(`/servers/${this.id}/schedules/${this.sched_id}`);
1097
+ };
1098
+ execute = async () => {
1099
+ await this.r.post(
1100
+ `/servers/${this.id}/schedules/${this.sched_id}/execute`
1101
+ );
1102
+ };
1103
+ tasks = {
1104
+ create: async (opts) => {
1105
+ const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}/tasks`, opts);
1106
+ return data.attributes;
1107
+ },
1108
+ update: async (task_id, opts) => {
1109
+ const { data } = await this.r.post(
1110
+ `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`,
1111
+ opts
1112
+ );
1113
+ return data.attributes;
1114
+ },
1115
+ delete: async (task_id) => {
1116
+ await this.r.delete(
1117
+ `/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`
1118
+ );
1119
+ }
1120
+ };
1121
+ };
1659
1122
 
1660
- // src/api/application/mounts.ts
1123
+ // src/api/client/server_settings.ts
1661
1124
  var import_zod13 = __toESM(require("zod"));
1662
- var CreateMountSchema = import_zod13.default.object({
1663
- name: import_zod13.default.string().min(1).max(255),
1664
- description: import_zod13.default.string().optional(),
1665
- source: import_zod13.default.string(),
1666
- target: import_zod13.default.string(),
1667
- read_only: import_zod13.default.boolean().optional()
1668
- });
1125
+ var ServerSettings = class {
1126
+ r;
1127
+ id;
1128
+ constructor(requester, id) {
1129
+ this.r = requester;
1130
+ this.id = id;
1131
+ }
1132
+ rename = async (name) => {
1133
+ name = import_zod13.default.string().max(255).parse(name);
1134
+ await this.r.post(`/servers/${this.id}/settings/rename`, { name });
1135
+ };
1136
+ updateDescription = async (description) => {
1137
+ await this.r.post(`/servers/${this.id}/settings/description`, {
1138
+ description
1139
+ });
1140
+ };
1141
+ reinstall = async () => {
1142
+ await this.r.post(`/servers/${this.id}/settings/reinstall`);
1143
+ };
1144
+ changeDockerImage = async (image) => {
1145
+ await this.r.put(`/servers/${this.id}/settings/docker-image`, {
1146
+ docker_image: image
1147
+ });
1148
+ };
1149
+ };
1669
1150
 
1670
- // src/api/base/request.ts
1671
- var import_zod14 = __toESM(require("zod"));
1672
- var import_axios3 = __toESM(require("axios"));
1151
+ // src/api/client/server_startup.ts
1152
+ var ServerStartup = class {
1153
+ r;
1154
+ id;
1155
+ constructor(requester, id) {
1156
+ this.r = requester;
1157
+ this.id = id;
1158
+ }
1159
+ list = async () => {
1160
+ const { data } = await this.r.get(`/servers/${this.id}/startup`);
1161
+ return {
1162
+ object: "list",
1163
+ meta: data.meta,
1164
+ data: data.data.map((d) => d.attributes)
1165
+ };
1166
+ };
1167
+ set = async (key, value) => {
1168
+ const { data } = await this.r.put(`/servers/${this.id}/startup/variable`, { key, value });
1169
+ return data.attributes;
1170
+ };
1171
+ };
1673
1172
 
1674
- // src/api/base/types.ts
1675
- var PterodactylException = class extends Error {
1676
- data;
1677
- status;
1678
- constructor(message, data, status) {
1679
- super(message);
1680
- this.data = data;
1681
- this.status = status;
1173
+ // src/api/client/server_users.ts
1174
+ var ServerUsers = class {
1175
+ r;
1176
+ id;
1177
+ constructor(requester, id) {
1178
+ this.r = requester;
1179
+ this.id = id;
1180
+ }
1181
+ list = async () => {
1182
+ const { data } = await this.r.get(`/servers/${this.id}/users`);
1183
+ return data.data.map((d) => d.attributes);
1184
+ };
1185
+ create = async (email, permissions) => {
1186
+ const { data } = await this.r.post(`/servers/${this.id}/users`, { email, permissions });
1187
+ return data.attributes;
1188
+ };
1189
+ info = async (user_uuid) => {
1190
+ const { data } = await this.r.get(
1191
+ `/servers/${this.id}/users/${user_uuid}`
1192
+ );
1193
+ return data.attributes;
1194
+ };
1195
+ update = async (user_uuid, permissions) => {
1196
+ const { data } = await this.r.put(
1197
+ `/servers/${this.id}/users/${user_uuid}`,
1198
+ { permissions }
1199
+ );
1200
+ return data.attributes;
1201
+ };
1202
+ delete = async (user_uuid) => {
1203
+ await this.r.delete(`/servers/${this.id}/users/${user_uuid}`);
1204
+ };
1205
+ };
1206
+
1207
+ // src/api/client/server_websocket.ts
1208
+ var import_events = require("events");
1209
+ var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
1210
+ var import_strip_color = __toESM(require("strip-color"));
1211
+ var isBrowser = typeof window !== "undefined";
1212
+ var RECONNECT_ERRORS = /* @__PURE__ */ new Set([
1213
+ "jwt: exp claim is invalid",
1214
+ "jwt: created too far in past (denylist)"
1215
+ ]);
1216
+ var FALLBACK_LOG_MESSAGE = "No logs - is the server online?";
1217
+ var ServerWebsocket = class {
1218
+ r;
1219
+ serverId;
1220
+ socket;
1221
+ currentToken;
1222
+ bus = new import_events.EventEmitter();
1223
+ debugLogging = false;
1224
+ stripColors;
1225
+ detachMessageListener;
1226
+ constructor(requester, id, stripColors = false) {
1227
+ this.r = requester;
1228
+ this.serverId = id;
1229
+ this.stripColors = stripColors;
1230
+ }
1231
+ on(event, listener) {
1232
+ const handler = listener;
1233
+ this.bus.on(event, handler);
1234
+ return () => {
1235
+ this.bus.removeListener(event, handler);
1236
+ };
1237
+ }
1238
+ deregister(event, listener) {
1239
+ const handler = listener;
1240
+ this.bus.removeListener(event, handler);
1241
+ }
1242
+ emit(event, ...args) {
1243
+ if (args.length === 0) {
1244
+ this.bus.emit(event);
1245
+ } else {
1246
+ this.bus.emit(event, args[0]);
1247
+ }
1248
+ }
1249
+ async connect(resumable, debugLogging) {
1250
+ this.debugLogging = debugLogging ?? false;
1251
+ if (this.socket) {
1252
+ return;
1253
+ }
1254
+ const socketUrl = await this.refreshCredentials();
1255
+ this.socket = isBrowser ? new import_isomorphic_ws.default(socketUrl) : new import_isomorphic_ws.default(socketUrl, void 0, {
1256
+ origin: new URL(socketUrl).origin
1257
+ });
1258
+ await new Promise((resolve, reject) => {
1259
+ const socket = this.socket;
1260
+ if (!socket) {
1261
+ reject(new Error("Failed to create socket connection"));
1262
+ return;
1263
+ }
1264
+ socket.onopen = async () => {
1265
+ try {
1266
+ await this.authenticate();
1267
+ this.attachMessageListener();
1268
+ socket.onopen = null;
1269
+ socket.onerror = null;
1270
+ resolve();
1271
+ } catch (error) {
1272
+ socket.onopen = null;
1273
+ socket.onerror = null;
1274
+ reject(
1275
+ error instanceof Error ? error : new Error("Websocket authentication failed")
1276
+ );
1277
+ }
1278
+ };
1279
+ socket.onerror = (event) => {
1280
+ socket.onopen = null;
1281
+ socket.onerror = null;
1282
+ reject(
1283
+ event instanceof Error ? event : new Error("Websocket connection error")
1284
+ );
1285
+ };
1286
+ });
1287
+ if (resumable) {
1288
+ this.makeResumable(true);
1289
+ }
1290
+ }
1291
+ onSocketDisconnect(handler) {
1292
+ if (!this.socket) {
1293
+ console.error(new Error("No socket connection"));
1294
+ return;
1295
+ }
1296
+ this.socket.onclose = handler;
1297
+ }
1298
+ onSocketError(handler) {
1299
+ if (!this.socket) {
1300
+ console.error(new Error("No socket connection"));
1301
+ return;
1302
+ }
1303
+ this.socket.onerror = handler;
1304
+ }
1305
+ makeResumable(disconnectsToo) {
1306
+ const scheduleReconnect = () => {
1307
+ setTimeout(() => {
1308
+ const previous = this.socket;
1309
+ this.detachMessageListener?.();
1310
+ this.detachMessageListener = void 0;
1311
+ this.socket = void 0;
1312
+ previous?.close();
1313
+ void this.connect(true, this.debugLogging);
1314
+ }, 1e3);
1315
+ };
1316
+ this.onSocketError(() => scheduleReconnect());
1317
+ if (disconnectsToo) {
1318
+ this.onSocketDisconnect(() => scheduleReconnect());
1319
+ }
1320
+ }
1321
+ attachMessageListener() {
1322
+ if (!this.socket) {
1323
+ throw new Error("No socket connection");
1324
+ }
1325
+ this.detachMessageListener?.();
1326
+ const handler = (event) => {
1327
+ void this.handleIncomingMessage(event);
1328
+ };
1329
+ if (typeof this.socket.addEventListener === "function") {
1330
+ this.socket.addEventListener(
1331
+ "message",
1332
+ handler
1333
+ );
1334
+ this.detachMessageListener = () => {
1335
+ this.socket?.removeEventListener?.(
1336
+ "message",
1337
+ handler
1338
+ );
1339
+ };
1340
+ } else {
1341
+ const fallback = (data) => handler({ data });
1342
+ const socket = this.socket;
1343
+ socket.on?.("message", fallback);
1344
+ this.detachMessageListener = () => {
1345
+ const target = this.socket;
1346
+ if (!target) {
1347
+ return;
1348
+ }
1349
+ if (typeof target.off === "function") {
1350
+ target.off("message", fallback);
1351
+ } else if (typeof target.removeListener === "function") {
1352
+ target.removeListener("message", fallback);
1353
+ }
1354
+ };
1355
+ }
1356
+ }
1357
+ async handleIncomingMessage(event) {
1358
+ const message = this.parseMessage(event);
1359
+ if (!message) {
1360
+ return;
1361
+ }
1362
+ try {
1363
+ await this.dispatchMessage(message);
1364
+ } catch (error) {
1365
+ if (this.debugLogging) {
1366
+ console.error("Error while handling websocket message", error);
1367
+ }
1368
+ }
1369
+ }
1370
+ parseMessage(event) {
1371
+ const payload = this.normalisePayload(event);
1372
+ if (!payload) {
1373
+ return null;
1374
+ }
1375
+ try {
1376
+ return JSON.parse(payload);
1377
+ } catch (error) {
1378
+ if (this.debugLogging) {
1379
+ console.warn("Failed to parse websocket payload", error);
1380
+ }
1381
+ return null;
1382
+ }
1383
+ }
1384
+ normalisePayload(event) {
1385
+ if (typeof event === "string") {
1386
+ return event;
1387
+ }
1388
+ if (typeof event === "object" && event !== null && "data" in event) {
1389
+ return this.normalisePayload(event.data);
1390
+ }
1391
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(event)) {
1392
+ return event.toString("utf8");
1393
+ }
1394
+ if (typeof ArrayBuffer !== "undefined" && event instanceof ArrayBuffer) {
1395
+ if (typeof TextDecoder !== "undefined") {
1396
+ return new TextDecoder().decode(new Uint8Array(event));
1397
+ }
1398
+ if (typeof Buffer !== "undefined") {
1399
+ return Buffer.from(event).toString("utf8");
1400
+ }
1401
+ }
1402
+ return null;
1403
+ }
1404
+ async dispatchMessage(message) {
1405
+ switch (message.event) {
1406
+ case "auth success" /* AUTH_SUCCESS */: {
1407
+ if (this.debugLogging) {
1408
+ console.debug("Auth success");
1409
+ }
1410
+ this.emit("auth success" /* AUTH_SUCCESS */);
1411
+ break;
1412
+ }
1413
+ case "status" /* STATUS */: {
1414
+ if (this.debugLogging) {
1415
+ console.debug("Received status event", message.args[0]);
1416
+ }
1417
+ this.emit("status" /* STATUS */, message.args[0]);
1418
+ break;
1419
+ }
1420
+ case "console output" /* CONSOLE_OUTPUT */: {
1421
+ let output = message.args[0];
1422
+ if (this.stripColors) {
1423
+ output = (0, import_strip_color.default)(output);
1424
+ }
1425
+ if (this.debugLogging) {
1426
+ console.debug("Received console output", output);
1427
+ }
1428
+ this.emit("console output" /* CONSOLE_OUTPUT */, output);
1429
+ break;
1430
+ }
1431
+ case "stats" /* STATS */: {
1432
+ try {
1433
+ const payload = JSON.parse(message.args[0]);
1434
+ this.emit("stats" /* STATS */, payload);
1435
+ } catch (error) {
1436
+ if (this.debugLogging) {
1437
+ console.warn("Failed to parse stats payload", error);
1438
+ }
1439
+ }
1440
+ break;
1441
+ }
1442
+ case "daemon error" /* DAEMON_ERROR */: {
1443
+ this.emit("daemon error" /* DAEMON_ERROR */);
1444
+ break;
1445
+ }
1446
+ case "backup completed" /* BACKUP_COMPLETED */: {
1447
+ try {
1448
+ const payload = JSON.parse(
1449
+ message.args[0]
1450
+ );
1451
+ this.emit("backup completed" /* BACKUP_COMPLETED */, payload);
1452
+ } catch (error) {
1453
+ if (this.debugLogging) {
1454
+ console.warn("Failed to parse backup payload", error);
1455
+ }
1456
+ }
1457
+ break;
1458
+ }
1459
+ case "daemon message" /* DAEMON_MESSAGE */: {
1460
+ let output = message.args[0];
1461
+ if (this.stripColors) {
1462
+ output = (0, import_strip_color.default)(output);
1463
+ }
1464
+ this.emit("daemon message" /* DAEMON_MESSAGE */, output);
1465
+ break;
1466
+ }
1467
+ case "install output" /* INSTALL_OUTPUT */: {
1468
+ let output = message.args[0];
1469
+ if (this.stripColors) {
1470
+ output = (0, import_strip_color.default)(output);
1471
+ }
1472
+ this.emit("install output" /* INSTALL_OUTPUT */, output);
1473
+ break;
1474
+ }
1475
+ case "backup restore completed" /* BACKUP_RESTORE_COMPLETED */: {
1476
+ this.emit("backup restore completed" /* BACKUP_RESTORE_COMPLETED */);
1477
+ break;
1478
+ }
1479
+ case "install completed" /* INSTALL_COMPLETED */: {
1480
+ this.emit("install completed" /* INSTALL_COMPLETED */);
1481
+ break;
1482
+ }
1483
+ case "install started" /* INSTALL_STARTED */: {
1484
+ this.emit("install started" /* INSTALL_STARTED */);
1485
+ break;
1486
+ }
1487
+ case "transfer logs" /* TRANSFER_LOGS */: {
1488
+ this.emit("transfer logs" /* TRANSFER_LOGS */, message.args[0]);
1489
+ break;
1490
+ }
1491
+ case "transfer status" /* TRANSFER_STATUS */: {
1492
+ this.emit("transfer status" /* TRANSFER_STATUS */, message.args[0]);
1493
+ break;
1494
+ }
1495
+ case "token expiring" /* TOKEN_EXPIRING */: {
1496
+ this.emit("token expiring" /* TOKEN_EXPIRING */);
1497
+ if (this.debugLogging) {
1498
+ console.warn("Token expiring, renewing...");
1499
+ }
1500
+ await this.refreshCredentials();
1501
+ await this.authenticate();
1502
+ break;
1503
+ }
1504
+ case "token expired" /* TOKEN_EXPIRED */: {
1505
+ this.emit("token expired" /* TOKEN_EXPIRED */);
1506
+ throw new Error("Token expired");
1507
+ }
1508
+ case "jwt error" /* JWT_ERROR */: {
1509
+ const reason = message.args[0];
1510
+ if (RECONNECT_ERRORS.has(reason)) {
1511
+ this.emit("token expiring" /* TOKEN_EXPIRING */);
1512
+ if (this.debugLogging) {
1513
+ console.warn("Token expiring (JWT error), renewing...");
1514
+ }
1515
+ await this.refreshCredentials();
1516
+ await this.authenticate();
1517
+ } else {
1518
+ this.emit("jwt error" /* JWT_ERROR */, reason);
1519
+ throw new Error("Token expired");
1520
+ }
1521
+ break;
1522
+ }
1523
+ default: {
1524
+ if (this.debugLogging) {
1525
+ console.warn("Unknown websocket event", message);
1526
+ }
1527
+ break;
1528
+ }
1529
+ }
1682
1530
  }
1683
- };
1684
-
1685
- // src/api/base/request.ts
1686
- var Agent = class {
1687
- base_url;
1688
- token;
1689
- requester;
1690
- constructor(url, token, type, suffix = "/api") {
1691
- this.base_url = import_zod14.default.url("Invalid URL Schema").transform((url2) => new URL(url2).href).parse(url);
1692
- this.token = import_zod14.default.string().regex(/^(ptl[ac]|pacc|papp)_.+$/, "Invalid token type").parse(token);
1693
- this.requester = import_axios3.default.create({
1694
- baseURL: this.base_url.replace(/\/+$/, "") + `${suffix}/${type}`,
1695
- timeout: 3e3,
1696
- headers: { Authorization: `Bearer ${this.token}` }
1697
- });
1698
- this.requester.interceptors.response.use(void 0, (error) => {
1699
- if (error.response && error.response.status === 400) {
1700
- return Promise.reject(
1701
- new PterodactylException(
1702
- "Invalid request data",
1703
- error.response.data,
1704
- error.response.status
1705
- )
1531
+ async refreshCredentials() {
1532
+ const { data } = await this.r.get(
1533
+ `/servers/${this.serverId}/websocket`
1534
+ );
1535
+ this.currentToken = data.data.token;
1536
+ return data.data.socket;
1537
+ }
1538
+ async authenticate() {
1539
+ if (!this.socket) {
1540
+ throw new Error("No socket connection");
1541
+ }
1542
+ if (!this.currentToken) {
1543
+ throw new Error("Missing websocket token");
1544
+ }
1545
+ this.socket.send(
1546
+ JSON.stringify({ event: "auth", args: [this.currentToken] })
1547
+ );
1548
+ }
1549
+ disconnect() {
1550
+ this.detachMessageListener?.();
1551
+ this.detachMessageListener = void 0;
1552
+ if (this.socket) {
1553
+ this.socket.close();
1554
+ this.socket = void 0;
1555
+ }
1556
+ }
1557
+ requestStats() {
1558
+ this.send("send stats", [null]);
1559
+ }
1560
+ requestLogs() {
1561
+ this.send("send logs", [null]);
1562
+ }
1563
+ send(event, args) {
1564
+ if (!this.socket) {
1565
+ if (this.debugLogging) {
1566
+ console.warn(
1567
+ `Attempted to send "${event}" without an active websocket connection`
1706
1568
  );
1707
1569
  }
1708
- return Promise.reject(error);
1570
+ return;
1571
+ }
1572
+ this.socket.send(JSON.stringify({ event, args }));
1573
+ }
1574
+ getStats() {
1575
+ return new Promise((resolve, reject) => {
1576
+ if (!this.socket) {
1577
+ reject(new Error("No socket connection"));
1578
+ return;
1579
+ }
1580
+ let off;
1581
+ const timeout = setTimeout(() => {
1582
+ off?.();
1583
+ reject(new Error("Timed out waiting for stats"));
1584
+ }, 5e3);
1585
+ off = this.on("stats" /* STATS */, (payload) => {
1586
+ clearTimeout(timeout);
1587
+ off?.();
1588
+ resolve(payload);
1589
+ });
1590
+ this.requestStats();
1591
+ });
1592
+ }
1593
+ getLogs() {
1594
+ return new Promise((resolve, reject) => {
1595
+ if (!this.socket) {
1596
+ reject(new Error("No socket connection"));
1597
+ return;
1598
+ }
1599
+ const lines = [];
1600
+ let off;
1601
+ let initialTimeout;
1602
+ let idleTimeout;
1603
+ const finalize = (payload) => {
1604
+ off?.();
1605
+ if (initialTimeout) {
1606
+ clearTimeout(initialTimeout);
1607
+ }
1608
+ if (idleTimeout) {
1609
+ clearTimeout(idleTimeout);
1610
+ }
1611
+ resolve(payload);
1612
+ };
1613
+ initialTimeout = setTimeout(() => {
1614
+ finalize(lines.length > 0 ? lines : [FALLBACK_LOG_MESSAGE]);
1615
+ }, 5e3);
1616
+ off = this.on("console output" /* CONSOLE_OUTPUT */, (line) => {
1617
+ lines.push(line);
1618
+ if (initialTimeout) {
1619
+ clearTimeout(initialTimeout);
1620
+ initialTimeout = void 0;
1621
+ }
1622
+ if (idleTimeout) {
1623
+ clearTimeout(idleTimeout);
1624
+ }
1625
+ idleTimeout = setTimeout(() => {
1626
+ finalize(lines);
1627
+ }, 1e3);
1628
+ });
1629
+ this.requestLogs();
1709
1630
  });
1710
1631
  }
1632
+ sendPoweraction(action) {
1633
+ this.send("set state", [action]);
1634
+ }
1635
+ sendCommand(cmd) {
1636
+ this.send("send command", [cmd]);
1637
+ }
1638
+ };
1639
+
1640
+ // src/api/client/server.ts
1641
+ var ServerClient = class {
1642
+ r;
1643
+ id;
1644
+ activity;
1645
+ databases;
1646
+ files;
1647
+ schedules;
1648
+ allocations;
1649
+ users;
1650
+ backups;
1651
+ startup;
1652
+ variables;
1653
+ settings;
1654
+ constructor(requester, id) {
1655
+ this.r = requester;
1656
+ this.id = id;
1657
+ this.activity = new ServerActivity(requester, id);
1658
+ this.databases = new ServerDatabases(requester, id);
1659
+ this.files = new ServerFiles(requester, id);
1660
+ this.schedules = new ServerSchedules(requester, id);
1661
+ this.allocations = new ServerAllocations(requester, id);
1662
+ this.users = new ServerUsers(requester, id);
1663
+ this.backups = new ServerBackups(requester, id);
1664
+ this.startup = new ServerStartup(requester, id);
1665
+ this.variables = this.startup;
1666
+ this.settings = new ServerSettings(requester, id);
1667
+ }
1668
+ info = async (include) => {
1669
+ const { data } = await this.r.get(
1670
+ `/servers/${this.id}`,
1671
+ { params: { include: include?.join(",") } }
1672
+ );
1673
+ return data.attributes;
1674
+ };
1675
+ websocket = (stripColors = false) => {
1676
+ return new ServerWebsocket(this.r, this.id, stripColors);
1677
+ };
1678
+ resources = async () => {
1679
+ const { data } = await this.r.get(
1680
+ `/servers/${this.id}/resources`
1681
+ );
1682
+ return data.attributes;
1683
+ };
1684
+ command = async (command) => {
1685
+ await this.r.post(`/servers/${this.id}/command`, { command });
1686
+ };
1687
+ power = async (signal) => {
1688
+ await this.r.post(`/servers/${this.id}/power`, { signal });
1689
+ };
1690
+ };
1691
+
1692
+ // src/api/client/client.ts
1693
+ var Client = class {
1694
+ account;
1695
+ r;
1696
+ constructor(requester) {
1697
+ this.r = requester;
1698
+ this.account = new Account(requester);
1699
+ }
1700
+ get $r() {
1701
+ return this.r;
1702
+ }
1703
+ listPermissions = async () => {
1704
+ const { data } = await this.r.get("/permissions");
1705
+ return data.attributes.permissions;
1706
+ };
1707
+ listServers = async (type = "accessible", page = 1, per_page = 50, include) => {
1708
+ import_zod14.default.number().positive().parse(page);
1709
+ const { data } = await this.r.get("/", { params: { type, page, include: include?.join(",") } });
1710
+ return data.data.map((s) => s.attributes);
1711
+ };
1712
+ server = (uuid) => new ServerClient(this.r, uuid);
1711
1713
  };
1712
1714
 
1713
1715
  // src/api/index.ts
@@ -2083,14 +2085,27 @@ var ServerUser = class {
2083
2085
  // src/humane/Server.ts
2084
2086
  var Server = class {
2085
2087
  client;
2088
+ /**
2089
+ * Whether the user owns the server
2090
+ *
2091
+ * @remarks
2092
+ * Useful for gatekeeping features from subusers
2093
+ */
2086
2094
  ownsServer;
2087
2095
  identifier;
2096
+ /**
2097
+ * ID used by Pelican Application API
2098
+ */
2088
2099
  internalId;
2089
2100
  uuid;
2090
2101
  $name;
2091
2102
  get name() {
2092
2103
  return this.$name;
2093
2104
  }
2105
+ /**
2106
+ * Node name used by this server
2107
+ * @
2108
+ */
2094
2109
  node;
2095
2110
  isNodeUnderMaintenance;
2096
2111
  sftp;
@@ -2224,14 +2239,30 @@ var Client3 = class {
2224
2239
  constructor(client) {
2225
2240
  this.client = client;
2226
2241
  }
2242
+ /**
2243
+ * Get raw API client
2244
+ */
2227
2245
  get $client() {
2228
2246
  return this.client;
2229
2247
  }
2248
+ /**
2249
+ * Get user account
2250
+ */
2230
2251
  getAccount = async () => {
2231
2252
  const user = await this.client.account.info();
2232
2253
  return new Account2(this.client, user);
2233
2254
  };
2255
+ /**
2256
+ * Get subuser (current user) permissions
2257
+ *
2258
+ * Return data is not compatible with subusers API
2259
+ */
2234
2260
  listPermissions = async () => this.client.listPermissions();
2261
+ /**
2262
+ * List servers
2263
+ *
2264
+ * @param opts Filtering options (all optional)
2265
+ */
2235
2266
  listServers = async (opts = { type: "accessible", page: 1, per_page: 50 }) => {
2236
2267
  const data = await this.client.listServers(
2237
2268
  opts.type,
@@ -2241,6 +2272,12 @@ var Client3 = class {
2241
2272
  );
2242
2273
  return data.map((d) => new Server(this.client.server(d.uuid), d));
2243
2274
  };
2275
+ /**
2276
+ * Get server by UUID
2277
+ *
2278
+ * @param uuid Server UUID
2279
+ * @param include Include additional data
2280
+ */
2244
2281
  getServer = async (uuid, include) => {
2245
2282
  const server = await this.client.server(uuid).info(include);
2246
2283
  return new Server(this.client.server(uuid), server);