@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.
- package/CHANGELOG.md +127 -0
- package/README.md +5 -4
- package/bun.lock +40 -0
- package/dist/api/index.d.mts +778 -787
- package/dist/api/index.d.ts +778 -787
- package/dist/api/index.js +1536 -1534
- package/dist/api/index.mjs +1536 -1534
- package/dist/index.d.mts +270 -188
- package/dist/index.d.ts +270 -188
- package/dist/index.js +1118 -1081
- package/dist/index.mjs +1118 -1081
- package/dist/types.d.ts +251 -260
- package/package.json +3 -1
package/dist/index.mjs
CHANGED
|
@@ -1,945 +1,126 @@
|
|
|
1
|
-
// src/api/
|
|
1
|
+
// src/api/application/database_hosts.ts
|
|
2
2
|
import z from "zod";
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
updateEmail = async (newEmail, password) => {
|
|
13
|
-
newEmail = z.email().parse(newEmail);
|
|
14
|
-
await this.r.put("/account/email", { email: newEmail, password });
|
|
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
|
|
21
|
-
});
|
|
22
|
-
};
|
|
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
|
-
}
|
|
36
|
-
};
|
|
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
|
-
}
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// src/api/client/client.ts
|
|
53
|
-
import z5 from "zod";
|
|
3
|
+
var CreateDBHostSchema = z.object({
|
|
4
|
+
name: z.string().min(1).max(255),
|
|
5
|
+
host: z.string(),
|
|
6
|
+
port: z.number().min(1).max(65535),
|
|
7
|
+
username: z.string().min(1).max(255),
|
|
8
|
+
password: z.string().optional(),
|
|
9
|
+
node_ids: z.array(z.string()).optional(),
|
|
10
|
+
max_databases: z.number().optional()
|
|
11
|
+
});
|
|
54
12
|
|
|
55
|
-
// src/api/
|
|
13
|
+
// src/api/application/mounts.ts
|
|
56
14
|
import z2 from "zod";
|
|
57
|
-
var
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
});
|
|
69
|
-
return data.data.map((d) => d.attributes);
|
|
70
|
-
};
|
|
71
|
-
create = async (database, remote) => {
|
|
72
|
-
const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote });
|
|
73
|
-
return data.attributes;
|
|
74
|
-
};
|
|
75
|
-
rotatePassword = async (database_id) => {
|
|
76
|
-
const { data } = await this.r.post(`/servers/${this.id}/databases/${database_id}/rotate-password`);
|
|
77
|
-
return data.attributes;
|
|
78
|
-
};
|
|
79
|
-
delete = async (database_id) => {
|
|
80
|
-
await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
|
|
81
|
-
};
|
|
82
|
-
};
|
|
15
|
+
var CreateMountSchema = z2.object({
|
|
16
|
+
name: z2.string().min(1).max(255),
|
|
17
|
+
description: z2.string().optional(),
|
|
18
|
+
source: z2.string(),
|
|
19
|
+
target: z2.string(),
|
|
20
|
+
read_only: z2.boolean().optional()
|
|
21
|
+
});
|
|
83
22
|
|
|
84
|
-
// src/api/
|
|
85
|
-
import
|
|
86
|
-
var ServerFiles = class {
|
|
87
|
-
r;
|
|
88
|
-
id;
|
|
89
|
-
constructor(requester, id) {
|
|
90
|
-
this.r = requester;
|
|
91
|
-
this.id = id;
|
|
92
|
-
}
|
|
93
|
-
list = async (path2) => {
|
|
94
|
-
const { data } = await this.r.get(`/servers/${this.id}/files/list`, { params: { directory: path2 } });
|
|
95
|
-
return data.data.map((r) => r.attributes);
|
|
96
|
-
};
|
|
97
|
-
/**
|
|
98
|
-
* Return the contents of a file. To read binary file (non-editable) use {@link download} instead
|
|
99
|
-
*/
|
|
100
|
-
contents = async (path2) => {
|
|
101
|
-
const { data } = await this.r.get(
|
|
102
|
-
`/servers/${this.id}/files/contents`,
|
|
103
|
-
{ params: { file: path2 } }
|
|
104
|
-
);
|
|
105
|
-
return data;
|
|
106
|
-
};
|
|
107
|
-
downloadGetUrl = async (path2) => {
|
|
108
|
-
const { data } = await this.r.get(`/servers/${this.id}/files/download`, { params: { file: path2 } });
|
|
109
|
-
return data.attributes.url;
|
|
110
|
-
};
|
|
111
|
-
download = async (path2) => {
|
|
112
|
-
const url = await this.downloadGetUrl(path2);
|
|
113
|
-
const { data } = await axios.get(url, {
|
|
114
|
-
responseType: "arraybuffer"
|
|
115
|
-
});
|
|
116
|
-
return data;
|
|
117
|
-
};
|
|
118
|
-
rename = async (root = "/", files) => {
|
|
119
|
-
await this.r.put(`/servers/${this.id}/files/rename`, { root, files });
|
|
120
|
-
};
|
|
121
|
-
copy = async (location) => {
|
|
122
|
-
await this.r.post(`/servers/${this.id}/files/copy`, { location });
|
|
123
|
-
};
|
|
124
|
-
write = async (path2, content) => {
|
|
125
|
-
await this.r.post(`/servers/${this.id}/files/write`, content, {
|
|
126
|
-
params: { file: path2 }
|
|
127
|
-
});
|
|
128
|
-
};
|
|
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;
|
|
137
|
-
};
|
|
138
|
-
decompress = async (root = "/", file) => {
|
|
139
|
-
await this.r.post(`/servers/${this.id}/files/decompress`, { root, file });
|
|
140
|
-
};
|
|
141
|
-
delete = async (root = "/", files) => {
|
|
142
|
-
await this.r.post(`/servers/${this.id}/files/delete`, { root, files });
|
|
143
|
-
};
|
|
144
|
-
createFolder = async (root = "/", name) => {
|
|
145
|
-
await this.r.post(`/servers/${this.id}/files/create-folder`, {
|
|
146
|
-
root,
|
|
147
|
-
name
|
|
148
|
-
});
|
|
149
|
-
};
|
|
150
|
-
chmod = async (root = "/", files) => {
|
|
151
|
-
await this.r.post(`/servers/${this.id}/files/chmod`, { root, files });
|
|
152
|
-
};
|
|
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
|
-
});
|
|
161
|
-
};
|
|
162
|
-
uploadGetUrl = async () => {
|
|
163
|
-
const { data } = await this.r.get(`/servers/${this.id}/files/upload`);
|
|
164
|
-
return data.attributes.url;
|
|
165
|
-
};
|
|
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
|
-
);
|
|
176
|
-
};
|
|
177
|
-
};
|
|
23
|
+
// src/api/application/nodes.ts
|
|
24
|
+
import z4 from "zod";
|
|
178
25
|
|
|
179
|
-
// src/api/
|
|
180
|
-
|
|
181
|
-
r;
|
|
182
|
-
id;
|
|
183
|
-
constructor(requester, id) {
|
|
184
|
-
this.r = requester;
|
|
185
|
-
this.id = id;
|
|
186
|
-
}
|
|
187
|
-
list = async () => {
|
|
188
|
-
const { data } = await this.r.get(`/servers/${this.id}/schedules`);
|
|
189
|
-
return data.data.map((d) => d.attributes);
|
|
190
|
-
};
|
|
191
|
-
create = async (params) => {
|
|
192
|
-
const { data } = await this.r.post(`/servers/${this.id}/schedules`, params);
|
|
193
|
-
return data.attributes;
|
|
194
|
-
};
|
|
195
|
-
control = (sched_id) => new ScheduleControl(this.r, this.id, sched_id);
|
|
196
|
-
};
|
|
197
|
-
var ScheduleControl = class {
|
|
198
|
-
r;
|
|
199
|
-
id;
|
|
200
|
-
sched_id;
|
|
201
|
-
constructor(requester, id, sched_id) {
|
|
202
|
-
this.r = requester;
|
|
203
|
-
this.id = id;
|
|
204
|
-
this.sched_id = sched_id;
|
|
205
|
-
}
|
|
206
|
-
info = async () => {
|
|
207
|
-
const { data } = await this.r.get(`/servers/${this.id}/schedules/${this.sched_id}`);
|
|
208
|
-
return data.attributes;
|
|
209
|
-
};
|
|
210
|
-
update = async (params) => {
|
|
211
|
-
const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}`, params);
|
|
212
|
-
return data.attributes;
|
|
213
|
-
};
|
|
214
|
-
delete = async () => {
|
|
215
|
-
await this.r.delete(`/servers/${this.id}/schedules/${this.sched_id}`);
|
|
216
|
-
};
|
|
217
|
-
execute = async () => {
|
|
218
|
-
await this.r.post(
|
|
219
|
-
`/servers/${this.id}/schedules/${this.sched_id}/execute`
|
|
220
|
-
);
|
|
221
|
-
};
|
|
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
|
-
};
|
|
240
|
-
};
|
|
26
|
+
// src/api/application/nodes_allocations.ts
|
|
27
|
+
import z3 from "zod";
|
|
241
28
|
|
|
242
|
-
// src/api/
|
|
243
|
-
var
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
};
|
|
266
|
-
unassign = async (alloc_id) => {
|
|
267
|
-
await this.r.delete(
|
|
268
|
-
`/servers/${this.id}/network/allocations/${alloc_id}`
|
|
269
|
-
);
|
|
270
|
-
};
|
|
271
|
-
};
|
|
29
|
+
// src/api/application/nodes.ts
|
|
30
|
+
var NodeCreateSchema = z4.object({
|
|
31
|
+
name: z4.string().min(1).max(100),
|
|
32
|
+
description: z4.string().optional(),
|
|
33
|
+
public: z4.boolean().optional(),
|
|
34
|
+
fqdn: z4.string().nonempty(),
|
|
35
|
+
scheme: z4.enum(["http", "https"]),
|
|
36
|
+
behind_proxy: z4.boolean().optional(),
|
|
37
|
+
memory: z4.number().min(0),
|
|
38
|
+
memory_overallocate: z4.number().min(-1),
|
|
39
|
+
disk: z4.number().min(0),
|
|
40
|
+
disk_overallocate: z4.number().min(-1),
|
|
41
|
+
cpu: z4.number().min(0),
|
|
42
|
+
cpu_overallocate: z4.number().min(-1),
|
|
43
|
+
daemon_base: z4.string().nonempty().optional(),
|
|
44
|
+
daemon_sftp: z4.number().min(1).max(65535),
|
|
45
|
+
daemon_sftp_alias: z4.string().optional(),
|
|
46
|
+
daemon_listen: z4.number().min(1).max(65535),
|
|
47
|
+
daemon_connect: z4.number().min(1).max(65535),
|
|
48
|
+
maintenance_mode: z4.boolean().optional(),
|
|
49
|
+
upload_size: z4.number().min(1).max(1024),
|
|
50
|
+
tags: z4.array(z4.string()).optional()
|
|
51
|
+
});
|
|
272
52
|
|
|
273
|
-
// src/api/
|
|
274
|
-
|
|
275
|
-
r;
|
|
276
|
-
id;
|
|
277
|
-
constructor(requester, id) {
|
|
278
|
-
this.r = requester;
|
|
279
|
-
this.id = id;
|
|
280
|
-
}
|
|
281
|
-
list = async () => {
|
|
282
|
-
const { data } = await this.r.get(`/servers/${this.id}/users`);
|
|
283
|
-
return data.data.map((d) => d.attributes);
|
|
284
|
-
};
|
|
285
|
-
create = async (email, permissions) => {
|
|
286
|
-
const { data } = await this.r.post(`/servers/${this.id}/users`, { email, permissions });
|
|
287
|
-
return data.attributes;
|
|
288
|
-
};
|
|
289
|
-
info = async (user_uuid) => {
|
|
290
|
-
const { data } = await this.r.get(
|
|
291
|
-
`/servers/${this.id}/users/${user_uuid}`
|
|
292
|
-
);
|
|
293
|
-
return data.attributes;
|
|
294
|
-
};
|
|
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;
|
|
301
|
-
};
|
|
302
|
-
delete = async (user_uuid) => {
|
|
303
|
-
await this.r.delete(`/servers/${this.id}/users/${user_uuid}`);
|
|
304
|
-
};
|
|
305
|
-
};
|
|
53
|
+
// src/api/application/servers.ts
|
|
54
|
+
import z6 from "zod";
|
|
306
55
|
|
|
307
|
-
// src/api/
|
|
308
|
-
import
|
|
309
|
-
import z3 from "zod";
|
|
310
|
-
var ServerBackups = class {
|
|
311
|
-
r;
|
|
312
|
-
id;
|
|
313
|
-
constructor(requester, id) {
|
|
314
|
-
this.r = requester;
|
|
315
|
-
this.id = id;
|
|
316
|
-
}
|
|
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
|
-
});
|
|
329
|
-
return data.attributes;
|
|
330
|
-
};
|
|
331
|
-
info = async (backup_uuid) => {
|
|
332
|
-
const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}`);
|
|
333
|
-
return data.attributes;
|
|
334
|
-
};
|
|
335
|
-
downloadGetUrl = async (backup_uuid) => {
|
|
336
|
-
const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}/download`);
|
|
337
|
-
return data.attributes.url;
|
|
338
|
-
};
|
|
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;
|
|
345
|
-
};
|
|
346
|
-
delete = async (backup_uuid) => {
|
|
347
|
-
await this.r.delete(`/servers/${this.id}/backups/${backup_uuid}`);
|
|
348
|
-
};
|
|
349
|
-
rename = async (backup_uuid, name) => {
|
|
350
|
-
await this.r.put(`/servers/${this.id}/backups/${backup_uuid}/rename`, {
|
|
351
|
-
name
|
|
352
|
-
});
|
|
353
|
-
};
|
|
354
|
-
toggleLock = async (backup_uuid) => {
|
|
355
|
-
await this.r.post(`/servers/${this.id}/backups/${backup_uuid}/lock`);
|
|
356
|
-
};
|
|
357
|
-
restore = async (backup_uuid, truncate) => {
|
|
358
|
-
await this.r.post(
|
|
359
|
-
`/servers/${this.id}/backups/${backup_uuid}/restore`,
|
|
360
|
-
{ truncate }
|
|
361
|
-
);
|
|
362
|
-
};
|
|
363
|
-
};
|
|
56
|
+
// src/api/application/servers_databases.ts
|
|
57
|
+
import z5 from "zod";
|
|
364
58
|
|
|
365
|
-
// src/api/
|
|
366
|
-
var
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
59
|
+
// src/api/application/servers.ts
|
|
60
|
+
var CreateServerSchema = z6.object({
|
|
61
|
+
external_id: z6.string().min(1).max(255).optional(),
|
|
62
|
+
name: z6.string().min(1).max(255),
|
|
63
|
+
description: z6.string().optional(),
|
|
64
|
+
user: z6.number(),
|
|
65
|
+
egg: z6.number(),
|
|
66
|
+
docker_image: z6.string().optional(),
|
|
67
|
+
startup: z6.string().optional(),
|
|
68
|
+
environment: z6.record(z6.string(), z6.string()),
|
|
69
|
+
skip_scripts: z6.boolean().optional(),
|
|
70
|
+
oom_killer: z6.boolean().optional(),
|
|
71
|
+
start_on_completion: z6.boolean().optional(),
|
|
72
|
+
docker_labels: z6.record(z6.string(), z6.string()).optional(),
|
|
73
|
+
limits: z6.object({
|
|
74
|
+
memory: z6.number().min(0),
|
|
75
|
+
swap: z6.number().min(-1),
|
|
76
|
+
disk: z6.number().min(0),
|
|
77
|
+
io: z6.number().min(0),
|
|
78
|
+
threads: z6.string().optional(),
|
|
79
|
+
cpu: z6.number().min(0)
|
|
80
|
+
}),
|
|
81
|
+
feature_limits: z6.object({
|
|
82
|
+
databases: z6.number().min(0),
|
|
83
|
+
allocations: z6.number().min(0),
|
|
84
|
+
backups: z6.number().min(0)
|
|
85
|
+
}),
|
|
86
|
+
allocation: z6.object({
|
|
87
|
+
default: z6.string().nullable(),
|
|
88
|
+
additional: z6.array(z6.string()).optional()
|
|
89
|
+
}).optional(),
|
|
90
|
+
deploy: z6.object({
|
|
91
|
+
tags: z6.array(z6.string()).optional(),
|
|
92
|
+
dedicated_ip: z6.boolean().optional(),
|
|
93
|
+
port_range: z6.array(z6.string()).optional()
|
|
94
|
+
}).optional()
|
|
95
|
+
});
|
|
96
|
+
var UpdateDetailsSchema = CreateServerSchema.pick({
|
|
97
|
+
external_id: true,
|
|
98
|
+
name: true,
|
|
99
|
+
user: true,
|
|
100
|
+
description: true,
|
|
101
|
+
docker_labels: true
|
|
102
|
+
});
|
|
103
|
+
var UpdateBuildSchema = CreateServerSchema.pick({
|
|
104
|
+
oom_killer: true,
|
|
105
|
+
limits: true,
|
|
106
|
+
feature_limits: true
|
|
107
|
+
}).extend({
|
|
108
|
+
allocation: z6.number().optional(),
|
|
109
|
+
add_allocations: z6.array(z6.string()).optional(),
|
|
110
|
+
remove_allocations: z6.array(z6.string()).optional()
|
|
111
|
+
});
|
|
112
|
+
var UpdateStartupSchema = CreateServerSchema.pick({
|
|
113
|
+
startup: true,
|
|
114
|
+
environment: true,
|
|
115
|
+
egg: true
|
|
116
|
+
}).extend({ image: z6.string().optional(), skip_scripts: z6.boolean() });
|
|
386
117
|
|
|
387
|
-
// src/api/
|
|
388
|
-
import
|
|
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
|
-
});
|
|
412
|
-
};
|
|
413
|
-
};
|
|
414
|
-
|
|
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)"
|
|
423
|
-
]);
|
|
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";
|
|
118
|
+
// src/api/application/users.ts
|
|
119
|
+
import z8 from "zod";
|
|
939
120
|
|
|
940
121
|
// src/api/common/types/enums.ts
|
|
941
|
-
import
|
|
942
|
-
var languagesSchema =
|
|
122
|
+
import z7 from "zod";
|
|
123
|
+
var languagesSchema = z7.enum([
|
|
943
124
|
"af",
|
|
944
125
|
"ak",
|
|
945
126
|
"am",
|
|
@@ -1075,7 +256,7 @@ var languagesSchema = z6.enum([
|
|
|
1075
256
|
"zh",
|
|
1076
257
|
"zu"
|
|
1077
258
|
]);
|
|
1078
|
-
var timezonesSchema =
|
|
259
|
+
var timezonesSchema = z7.enum([
|
|
1079
260
|
"Africa/Abidjan",
|
|
1080
261
|
"Africa/Accra",
|
|
1081
262
|
"Africa/Addis_Ababa",
|
|
@@ -1497,172 +678,993 @@ var timezonesSchema = z6.enum([
|
|
|
1497
678
|
"UTC"
|
|
1498
679
|
]);
|
|
1499
680
|
|
|
1500
|
-
// src/api/application/users.ts
|
|
1501
|
-
var CreateSchema =
|
|
1502
|
-
email:
|
|
1503
|
-
external_id:
|
|
1504
|
-
username:
|
|
1505
|
-
password:
|
|
1506
|
-
language: languagesSchema,
|
|
1507
|
-
timezone: timezonesSchema
|
|
1508
|
-
});
|
|
681
|
+
// src/api/application/users.ts
|
|
682
|
+
var CreateSchema = z8.object({
|
|
683
|
+
email: z8.email(),
|
|
684
|
+
external_id: z8.string().max(255).optional(),
|
|
685
|
+
username: z8.string().min(1).max(255),
|
|
686
|
+
password: z8.string().optional(),
|
|
687
|
+
language: languagesSchema,
|
|
688
|
+
timezone: timezonesSchema
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
// src/api/base/request.ts
|
|
692
|
+
import axios from "axios";
|
|
693
|
+
import z9 from "zod";
|
|
694
|
+
|
|
695
|
+
// src/api/base/types.ts
|
|
696
|
+
var PterodactylException = class extends Error {
|
|
697
|
+
data;
|
|
698
|
+
status;
|
|
699
|
+
constructor(message, data, status) {
|
|
700
|
+
super(message);
|
|
701
|
+
this.data = data;
|
|
702
|
+
this.status = status;
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
// src/api/base/request.ts
|
|
707
|
+
var Agent = class {
|
|
708
|
+
base_url;
|
|
709
|
+
token;
|
|
710
|
+
requester;
|
|
711
|
+
constructor(url, token, type, suffix = "/api") {
|
|
712
|
+
this.base_url = z9.url("Invalid URL Schema").transform((url2) => new URL(url2).href).parse(url);
|
|
713
|
+
this.token = z9.string().regex(/^(ptl[ac]|pacc|papp)_.+$/, "Invalid token type").parse(token);
|
|
714
|
+
this.requester = axios.create({
|
|
715
|
+
baseURL: this.base_url.replace(/\/+$/, "") + `${suffix}/${type}`,
|
|
716
|
+
timeout: 3e3,
|
|
717
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
718
|
+
});
|
|
719
|
+
this.requester.interceptors.response.use(void 0, (error) => {
|
|
720
|
+
if (error.response && error.response.status === 400) {
|
|
721
|
+
return Promise.reject(
|
|
722
|
+
new PterodactylException(
|
|
723
|
+
"Invalid request data",
|
|
724
|
+
error.response.data,
|
|
725
|
+
error.response.status
|
|
726
|
+
)
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
return Promise.reject(error);
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
};
|
|
1509
733
|
|
|
1510
|
-
// src/api/
|
|
1511
|
-
import
|
|
734
|
+
// src/api/client/client.ts
|
|
735
|
+
import z14 from "zod";
|
|
1512
736
|
|
|
1513
|
-
// src/api/
|
|
1514
|
-
import
|
|
1515
|
-
var
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
737
|
+
// src/api/client/account.ts
|
|
738
|
+
import z10 from "zod";
|
|
739
|
+
var Account = class {
|
|
740
|
+
r;
|
|
741
|
+
constructor(requester) {
|
|
742
|
+
this.r = requester;
|
|
743
|
+
}
|
|
744
|
+
info = async () => {
|
|
745
|
+
const { data } = await this.r.get("/account");
|
|
746
|
+
return data.attributes;
|
|
747
|
+
};
|
|
748
|
+
updateEmail = async (newEmail, password) => {
|
|
749
|
+
newEmail = z10.email().parse(newEmail);
|
|
750
|
+
await this.r.put("/account/email", { email: newEmail, password });
|
|
751
|
+
};
|
|
752
|
+
updatePassword = async (newPassword) => {
|
|
753
|
+
newPassword = z10.string().min(8).parse(newPassword);
|
|
754
|
+
await this.r.put("/account/password", {
|
|
755
|
+
password: newPassword,
|
|
756
|
+
password_confirmation: newPassword
|
|
757
|
+
});
|
|
758
|
+
};
|
|
759
|
+
apiKeys = {
|
|
760
|
+
list: async () => {
|
|
761
|
+
const { data } = await this.r.get("/account/api-keys");
|
|
762
|
+
return data.data.map((k) => k.attributes);
|
|
763
|
+
},
|
|
764
|
+
create: async (description, allowed_ips) => {
|
|
765
|
+
allowed_ips = z10.array(z10.ipv4()).optional().parse(allowed_ips);
|
|
766
|
+
const { data } = await this.r.post("/account/api-keys", { description, allowed_ips });
|
|
767
|
+
return { ...data.attributes, secret_token: data.meta.secret_token };
|
|
768
|
+
},
|
|
769
|
+
delete: async (identifier) => {
|
|
770
|
+
await this.r.delete(`/account/api-keys/${identifier}`);
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
sshKeys = {
|
|
774
|
+
list: async () => {
|
|
775
|
+
const { data } = await this.r.get("/account/ssh-keys");
|
|
776
|
+
return data.data.map((k) => k.attributes);
|
|
777
|
+
},
|
|
778
|
+
create: async (name, public_key) => {
|
|
779
|
+
const { data } = await this.r.post("/account/ssh-keys", { name, public_key });
|
|
780
|
+
return data.attributes;
|
|
781
|
+
},
|
|
782
|
+
delete: async (fingerprint) => {
|
|
783
|
+
await this.r.delete(`/account/ssh-keys/${fingerprint}`);
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
};
|
|
1537
787
|
|
|
1538
|
-
// src/api/
|
|
788
|
+
// src/api/client/server_activity.ts
|
|
789
|
+
var ServerActivity = class {
|
|
790
|
+
r;
|
|
791
|
+
id;
|
|
792
|
+
constructor(r, id) {
|
|
793
|
+
this.r = r;
|
|
794
|
+
this.id = id;
|
|
795
|
+
}
|
|
796
|
+
list = async (page = 1, per_page = 25) => {
|
|
797
|
+
const { data } = await this.r.get(`/server/${this.id}/activity`, { params: { page, per_page } });
|
|
798
|
+
return data.data.map((log) => log.attributes);
|
|
799
|
+
};
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
// src/api/client/server_allocations.ts
|
|
803
|
+
var ServerAllocations = class {
|
|
804
|
+
r;
|
|
805
|
+
id;
|
|
806
|
+
constructor(requester, id) {
|
|
807
|
+
this.r = requester;
|
|
808
|
+
this.id = id;
|
|
809
|
+
}
|
|
810
|
+
list = async () => {
|
|
811
|
+
const { data } = await this.r.get(`/servers/${this.id}/network/allocations`);
|
|
812
|
+
return data.data.map((r) => r.attributes);
|
|
813
|
+
};
|
|
814
|
+
autoAssign = async () => {
|
|
815
|
+
const { data } = await this.r.post(`/servers/${this.id}/network/allocations`);
|
|
816
|
+
return data.attributes;
|
|
817
|
+
};
|
|
818
|
+
setNotes = async (alloc_id, notes) => {
|
|
819
|
+
const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}`, { notes });
|
|
820
|
+
return data.attributes;
|
|
821
|
+
};
|
|
822
|
+
setPrimary = async (alloc_id) => {
|
|
823
|
+
const { data } = await this.r.post(`/servers/${this.id}/network/allocations/${alloc_id}/primary`);
|
|
824
|
+
return data.attributes;
|
|
825
|
+
};
|
|
826
|
+
unassign = async (alloc_id) => {
|
|
827
|
+
await this.r.delete(
|
|
828
|
+
`/servers/${this.id}/network/allocations/${alloc_id}`
|
|
829
|
+
);
|
|
830
|
+
};
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
// src/api/client/server_backups.ts
|
|
834
|
+
import axios2 from "axios";
|
|
1539
835
|
import z11 from "zod";
|
|
836
|
+
var ServerBackups = class {
|
|
837
|
+
r;
|
|
838
|
+
id;
|
|
839
|
+
constructor(requester, id) {
|
|
840
|
+
this.r = requester;
|
|
841
|
+
this.id = id;
|
|
842
|
+
}
|
|
843
|
+
list = async (page = 1) => {
|
|
844
|
+
z11.number().positive().parse(page);
|
|
845
|
+
const { data } = await this.r.get(`/servers/${this.id}/backups`, { params: { page } });
|
|
846
|
+
return data.data.map((d) => d.attributes);
|
|
847
|
+
};
|
|
848
|
+
create = async (args) => {
|
|
849
|
+
args.name = z11.string().max(255).optional().parse(args.name);
|
|
850
|
+
const { data } = await this.r.post(`/servers/${this.id}/backups`, {
|
|
851
|
+
name: args.name,
|
|
852
|
+
is_locked: args.is_locked,
|
|
853
|
+
ignored_files: args.ignored_files.join("\n")
|
|
854
|
+
});
|
|
855
|
+
return data.attributes;
|
|
856
|
+
};
|
|
857
|
+
info = async (backup_uuid) => {
|
|
858
|
+
const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}`);
|
|
859
|
+
return data.attributes;
|
|
860
|
+
};
|
|
861
|
+
downloadGetUrl = async (backup_uuid) => {
|
|
862
|
+
const { data } = await this.r.get(`/servers/${this.id}/backups/${backup_uuid}/download`);
|
|
863
|
+
return data.attributes.url;
|
|
864
|
+
};
|
|
865
|
+
download = async (backup_uuid) => {
|
|
866
|
+
const url = await this.downloadGetUrl(backup_uuid);
|
|
867
|
+
const { data } = await axios2.get(url, {
|
|
868
|
+
responseType: "arraybuffer"
|
|
869
|
+
});
|
|
870
|
+
return data;
|
|
871
|
+
};
|
|
872
|
+
delete = async (backup_uuid) => {
|
|
873
|
+
await this.r.delete(`/servers/${this.id}/backups/${backup_uuid}`);
|
|
874
|
+
};
|
|
875
|
+
rename = async (backup_uuid, name) => {
|
|
876
|
+
await this.r.put(`/servers/${this.id}/backups/${backup_uuid}/rename`, {
|
|
877
|
+
name
|
|
878
|
+
});
|
|
879
|
+
};
|
|
880
|
+
toggleLock = async (backup_uuid) => {
|
|
881
|
+
await this.r.post(`/servers/${this.id}/backups/${backup_uuid}/lock`);
|
|
882
|
+
};
|
|
883
|
+
restore = async (backup_uuid, truncate) => {
|
|
884
|
+
await this.r.post(
|
|
885
|
+
`/servers/${this.id}/backups/${backup_uuid}/restore`,
|
|
886
|
+
{ truncate }
|
|
887
|
+
);
|
|
888
|
+
};
|
|
889
|
+
};
|
|
1540
890
|
|
|
1541
|
-
// src/api/
|
|
1542
|
-
import
|
|
891
|
+
// src/api/client/server_databases.ts
|
|
892
|
+
import z12 from "zod";
|
|
893
|
+
var ServerDatabases = class {
|
|
894
|
+
r;
|
|
895
|
+
id;
|
|
896
|
+
constructor(requester, id) {
|
|
897
|
+
this.r = requester;
|
|
898
|
+
this.id = id;
|
|
899
|
+
}
|
|
900
|
+
list = async (include, page = 1) => {
|
|
901
|
+
z12.number().positive().parse(page);
|
|
902
|
+
const { data } = await this.r.get(`/servers/${this.id}/databases`, {
|
|
903
|
+
params: { include: include?.join(","), page }
|
|
904
|
+
});
|
|
905
|
+
return data.data.map((d) => d.attributes);
|
|
906
|
+
};
|
|
907
|
+
create = async (database, remote) => {
|
|
908
|
+
const { data } = await this.r.post(`/servers/${this.id}/databases`, { database, remote });
|
|
909
|
+
return data.attributes;
|
|
910
|
+
};
|
|
911
|
+
rotatePassword = async (database_id) => {
|
|
912
|
+
const { data } = await this.r.post(`/servers/${this.id}/databases/${database_id}/rotate-password`);
|
|
913
|
+
return data.attributes;
|
|
914
|
+
};
|
|
915
|
+
delete = async (database_id) => {
|
|
916
|
+
await this.r.delete(`/servers/${this.id}/databases/${database_id}`);
|
|
917
|
+
};
|
|
918
|
+
};
|
|
1543
919
|
|
|
1544
|
-
// src/api/
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
});
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
920
|
+
// src/api/client/server_files.ts
|
|
921
|
+
import axios3 from "axios";
|
|
922
|
+
var ServerFiles = class {
|
|
923
|
+
r;
|
|
924
|
+
id;
|
|
925
|
+
constructor(requester, id) {
|
|
926
|
+
this.r = requester;
|
|
927
|
+
this.id = id;
|
|
928
|
+
}
|
|
929
|
+
list = async (path2) => {
|
|
930
|
+
const { data } = await this.r.get(`/servers/${this.id}/files/list`, { params: { directory: path2 } });
|
|
931
|
+
return data.data.map((r) => r.attributes);
|
|
932
|
+
};
|
|
933
|
+
/**
|
|
934
|
+
* Return the contents of a file. To read binary file (non-editable) use {@link download} instead
|
|
935
|
+
*/
|
|
936
|
+
contents = async (path2) => {
|
|
937
|
+
const { data } = await this.r.get(
|
|
938
|
+
`/servers/${this.id}/files/contents`,
|
|
939
|
+
{ params: { file: path2 } }
|
|
940
|
+
);
|
|
941
|
+
return data;
|
|
942
|
+
};
|
|
943
|
+
downloadGetUrl = async (path2) => {
|
|
944
|
+
const { data } = await this.r.get(`/servers/${this.id}/files/download`, { params: { file: path2 } });
|
|
945
|
+
return data.attributes.url;
|
|
946
|
+
};
|
|
947
|
+
download = async (path2) => {
|
|
948
|
+
const url = await this.downloadGetUrl(path2);
|
|
949
|
+
const { data } = await axios3.get(url, {
|
|
950
|
+
responseType: "arraybuffer"
|
|
951
|
+
});
|
|
952
|
+
return data;
|
|
953
|
+
};
|
|
954
|
+
rename = async (root = "/", files) => {
|
|
955
|
+
await this.r.put(`/servers/${this.id}/files/rename`, { root, files });
|
|
956
|
+
};
|
|
957
|
+
copy = async (location) => {
|
|
958
|
+
await this.r.post(`/servers/${this.id}/files/copy`, { location });
|
|
959
|
+
};
|
|
960
|
+
write = async (path2, content) => {
|
|
961
|
+
await this.r.post(`/servers/${this.id}/files/write`, content, {
|
|
962
|
+
params: { file: path2 }
|
|
963
|
+
});
|
|
964
|
+
};
|
|
965
|
+
compress = async (root = "/", files, archive_name, extension) => {
|
|
966
|
+
const { data } = await this.r.post(`/servers/${this.id}/files/compress`, {
|
|
967
|
+
root,
|
|
968
|
+
files,
|
|
969
|
+
archive_name,
|
|
970
|
+
extension
|
|
971
|
+
});
|
|
972
|
+
return data.attributes;
|
|
973
|
+
};
|
|
974
|
+
decompress = async (root = "/", file) => {
|
|
975
|
+
await this.r.post(`/servers/${this.id}/files/decompress`, { root, file });
|
|
976
|
+
};
|
|
977
|
+
delete = async (root = "/", files) => {
|
|
978
|
+
await this.r.post(`/servers/${this.id}/files/delete`, { root, files });
|
|
979
|
+
};
|
|
980
|
+
createFolder = async (root = "/", name) => {
|
|
981
|
+
await this.r.post(`/servers/${this.id}/files/create-folder`, {
|
|
982
|
+
root,
|
|
983
|
+
name
|
|
984
|
+
});
|
|
985
|
+
};
|
|
986
|
+
chmod = async (root = "/", files) => {
|
|
987
|
+
await this.r.post(`/servers/${this.id}/files/chmod`, { root, files });
|
|
988
|
+
};
|
|
989
|
+
pullFromRemote = async (url, directory, filename, use_header = false, foreground = false) => {
|
|
990
|
+
await this.r.post(`/servers/${this.id}/files/pull`, {
|
|
991
|
+
url,
|
|
992
|
+
directory,
|
|
993
|
+
filename,
|
|
994
|
+
use_header,
|
|
995
|
+
foreground
|
|
996
|
+
});
|
|
997
|
+
};
|
|
998
|
+
uploadGetUrl = async () => {
|
|
999
|
+
const { data } = await this.r.get(`/servers/${this.id}/files/upload`);
|
|
1000
|
+
return data.attributes.url;
|
|
1001
|
+
};
|
|
1002
|
+
upload = async (file, root = "/") => {
|
|
1003
|
+
const url = await this.uploadGetUrl();
|
|
1004
|
+
await axios3.post(
|
|
1005
|
+
url,
|
|
1006
|
+
{ files: file },
|
|
1007
|
+
{
|
|
1008
|
+
headers: { "Content-Type": "multipart/form-data" },
|
|
1009
|
+
params: { directory: root }
|
|
1010
|
+
}
|
|
1011
|
+
);
|
|
1012
|
+
};
|
|
1013
|
+
};
|
|
1602
1014
|
|
|
1603
|
-
// src/api/
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1015
|
+
// src/api/client/server_schedules.ts
|
|
1016
|
+
var ServerSchedules = class {
|
|
1017
|
+
r;
|
|
1018
|
+
id;
|
|
1019
|
+
constructor(requester, id) {
|
|
1020
|
+
this.r = requester;
|
|
1021
|
+
this.id = id;
|
|
1022
|
+
}
|
|
1023
|
+
list = async () => {
|
|
1024
|
+
const { data } = await this.r.get(`/servers/${this.id}/schedules`);
|
|
1025
|
+
return data.data.map((d) => d.attributes);
|
|
1026
|
+
};
|
|
1027
|
+
create = async (params) => {
|
|
1028
|
+
const { data } = await this.r.post(`/servers/${this.id}/schedules`, params);
|
|
1029
|
+
return data.attributes;
|
|
1030
|
+
};
|
|
1031
|
+
control = (sched_id) => new ScheduleControl(this.r, this.id, sched_id);
|
|
1032
|
+
};
|
|
1033
|
+
var ScheduleControl = class {
|
|
1034
|
+
r;
|
|
1035
|
+
id;
|
|
1036
|
+
sched_id;
|
|
1037
|
+
constructor(requester, id, sched_id) {
|
|
1038
|
+
this.r = requester;
|
|
1039
|
+
this.id = id;
|
|
1040
|
+
this.sched_id = sched_id;
|
|
1041
|
+
}
|
|
1042
|
+
info = async () => {
|
|
1043
|
+
const { data } = await this.r.get(`/servers/${this.id}/schedules/${this.sched_id}`);
|
|
1044
|
+
return data.attributes;
|
|
1045
|
+
};
|
|
1046
|
+
update = async (params) => {
|
|
1047
|
+
const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}`, params);
|
|
1048
|
+
return data.attributes;
|
|
1049
|
+
};
|
|
1050
|
+
delete = async () => {
|
|
1051
|
+
await this.r.delete(`/servers/${this.id}/schedules/${this.sched_id}`);
|
|
1052
|
+
};
|
|
1053
|
+
execute = async () => {
|
|
1054
|
+
await this.r.post(
|
|
1055
|
+
`/servers/${this.id}/schedules/${this.sched_id}/execute`
|
|
1056
|
+
);
|
|
1057
|
+
};
|
|
1058
|
+
tasks = {
|
|
1059
|
+
create: async (opts) => {
|
|
1060
|
+
const { data } = await this.r.post(`/servers/${this.id}/schedules/${this.sched_id}/tasks`, opts);
|
|
1061
|
+
return data.attributes;
|
|
1062
|
+
},
|
|
1063
|
+
update: async (task_id, opts) => {
|
|
1064
|
+
const { data } = await this.r.post(
|
|
1065
|
+
`/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`,
|
|
1066
|
+
opts
|
|
1067
|
+
);
|
|
1068
|
+
return data.attributes;
|
|
1069
|
+
},
|
|
1070
|
+
delete: async (task_id) => {
|
|
1071
|
+
await this.r.delete(
|
|
1072
|
+
`/servers/${this.id}/schedules/${this.sched_id}/tasks/${task_id}`
|
|
1073
|
+
);
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
};
|
|
1614
1077
|
|
|
1615
|
-
// src/api/
|
|
1078
|
+
// src/api/client/server_settings.ts
|
|
1616
1079
|
import z13 from "zod";
|
|
1617
|
-
var
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
}
|
|
1080
|
+
var ServerSettings = class {
|
|
1081
|
+
r;
|
|
1082
|
+
id;
|
|
1083
|
+
constructor(requester, id) {
|
|
1084
|
+
this.r = requester;
|
|
1085
|
+
this.id = id;
|
|
1086
|
+
}
|
|
1087
|
+
rename = async (name) => {
|
|
1088
|
+
name = z13.string().max(255).parse(name);
|
|
1089
|
+
await this.r.post(`/servers/${this.id}/settings/rename`, { name });
|
|
1090
|
+
};
|
|
1091
|
+
updateDescription = async (description) => {
|
|
1092
|
+
await this.r.post(`/servers/${this.id}/settings/description`, {
|
|
1093
|
+
description
|
|
1094
|
+
});
|
|
1095
|
+
};
|
|
1096
|
+
reinstall = async () => {
|
|
1097
|
+
await this.r.post(`/servers/${this.id}/settings/reinstall`);
|
|
1098
|
+
};
|
|
1099
|
+
changeDockerImage = async (image) => {
|
|
1100
|
+
await this.r.put(`/servers/${this.id}/settings/docker-image`, {
|
|
1101
|
+
docker_image: image
|
|
1102
|
+
});
|
|
1103
|
+
};
|
|
1104
|
+
};
|
|
1624
1105
|
|
|
1625
|
-
// src/api/
|
|
1626
|
-
|
|
1627
|
-
|
|
1106
|
+
// src/api/client/server_startup.ts
|
|
1107
|
+
var ServerStartup = class {
|
|
1108
|
+
r;
|
|
1109
|
+
id;
|
|
1110
|
+
constructor(requester, id) {
|
|
1111
|
+
this.r = requester;
|
|
1112
|
+
this.id = id;
|
|
1113
|
+
}
|
|
1114
|
+
list = async () => {
|
|
1115
|
+
const { data } = await this.r.get(`/servers/${this.id}/startup`);
|
|
1116
|
+
return {
|
|
1117
|
+
object: "list",
|
|
1118
|
+
meta: data.meta,
|
|
1119
|
+
data: data.data.map((d) => d.attributes)
|
|
1120
|
+
};
|
|
1121
|
+
};
|
|
1122
|
+
set = async (key, value) => {
|
|
1123
|
+
const { data } = await this.r.put(`/servers/${this.id}/startup/variable`, { key, value });
|
|
1124
|
+
return data.attributes;
|
|
1125
|
+
};
|
|
1126
|
+
};
|
|
1628
1127
|
|
|
1629
|
-
// src/api/
|
|
1630
|
-
var
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
constructor(
|
|
1634
|
-
|
|
1635
|
-
this.
|
|
1636
|
-
|
|
1128
|
+
// src/api/client/server_users.ts
|
|
1129
|
+
var ServerUsers = class {
|
|
1130
|
+
r;
|
|
1131
|
+
id;
|
|
1132
|
+
constructor(requester, id) {
|
|
1133
|
+
this.r = requester;
|
|
1134
|
+
this.id = id;
|
|
1135
|
+
}
|
|
1136
|
+
list = async () => {
|
|
1137
|
+
const { data } = await this.r.get(`/servers/${this.id}/users`);
|
|
1138
|
+
return data.data.map((d) => d.attributes);
|
|
1139
|
+
};
|
|
1140
|
+
create = async (email, permissions) => {
|
|
1141
|
+
const { data } = await this.r.post(`/servers/${this.id}/users`, { email, permissions });
|
|
1142
|
+
return data.attributes;
|
|
1143
|
+
};
|
|
1144
|
+
info = async (user_uuid) => {
|
|
1145
|
+
const { data } = await this.r.get(
|
|
1146
|
+
`/servers/${this.id}/users/${user_uuid}`
|
|
1147
|
+
);
|
|
1148
|
+
return data.attributes;
|
|
1149
|
+
};
|
|
1150
|
+
update = async (user_uuid, permissions) => {
|
|
1151
|
+
const { data } = await this.r.put(
|
|
1152
|
+
`/servers/${this.id}/users/${user_uuid}`,
|
|
1153
|
+
{ permissions }
|
|
1154
|
+
);
|
|
1155
|
+
return data.attributes;
|
|
1156
|
+
};
|
|
1157
|
+
delete = async (user_uuid) => {
|
|
1158
|
+
await this.r.delete(`/servers/${this.id}/users/${user_uuid}`);
|
|
1159
|
+
};
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
// src/api/client/server_websocket.ts
|
|
1163
|
+
import { EventEmitter } from "events";
|
|
1164
|
+
import WebSocket from "isomorphic-ws";
|
|
1165
|
+
import stripColor from "strip-color";
|
|
1166
|
+
var isBrowser = typeof window !== "undefined";
|
|
1167
|
+
var RECONNECT_ERRORS = /* @__PURE__ */ new Set([
|
|
1168
|
+
"jwt: exp claim is invalid",
|
|
1169
|
+
"jwt: created too far in past (denylist)"
|
|
1170
|
+
]);
|
|
1171
|
+
var FALLBACK_LOG_MESSAGE = "No logs - is the server online?";
|
|
1172
|
+
var ServerWebsocket = class {
|
|
1173
|
+
r;
|
|
1174
|
+
serverId;
|
|
1175
|
+
socket;
|
|
1176
|
+
currentToken;
|
|
1177
|
+
bus = new EventEmitter();
|
|
1178
|
+
debugLogging = false;
|
|
1179
|
+
stripColors;
|
|
1180
|
+
detachMessageListener;
|
|
1181
|
+
constructor(requester, id, stripColors = false) {
|
|
1182
|
+
this.r = requester;
|
|
1183
|
+
this.serverId = id;
|
|
1184
|
+
this.stripColors = stripColors;
|
|
1185
|
+
}
|
|
1186
|
+
on(event, listener) {
|
|
1187
|
+
const handler = listener;
|
|
1188
|
+
this.bus.on(event, handler);
|
|
1189
|
+
return () => {
|
|
1190
|
+
this.bus.removeListener(event, handler);
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
deregister(event, listener) {
|
|
1194
|
+
const handler = listener;
|
|
1195
|
+
this.bus.removeListener(event, handler);
|
|
1196
|
+
}
|
|
1197
|
+
emit(event, ...args) {
|
|
1198
|
+
if (args.length === 0) {
|
|
1199
|
+
this.bus.emit(event);
|
|
1200
|
+
} else {
|
|
1201
|
+
this.bus.emit(event, args[0]);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
async connect(resumable, debugLogging) {
|
|
1205
|
+
this.debugLogging = debugLogging ?? false;
|
|
1206
|
+
if (this.socket) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
const socketUrl = await this.refreshCredentials();
|
|
1210
|
+
this.socket = isBrowser ? new WebSocket(socketUrl) : new WebSocket(socketUrl, void 0, {
|
|
1211
|
+
origin: new URL(socketUrl).origin
|
|
1212
|
+
});
|
|
1213
|
+
await new Promise((resolve, reject) => {
|
|
1214
|
+
const socket = this.socket;
|
|
1215
|
+
if (!socket) {
|
|
1216
|
+
reject(new Error("Failed to create socket connection"));
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
socket.onopen = async () => {
|
|
1220
|
+
try {
|
|
1221
|
+
await this.authenticate();
|
|
1222
|
+
this.attachMessageListener();
|
|
1223
|
+
socket.onopen = null;
|
|
1224
|
+
socket.onerror = null;
|
|
1225
|
+
resolve();
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
socket.onopen = null;
|
|
1228
|
+
socket.onerror = null;
|
|
1229
|
+
reject(
|
|
1230
|
+
error instanceof Error ? error : new Error("Websocket authentication failed")
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
socket.onerror = (event) => {
|
|
1235
|
+
socket.onopen = null;
|
|
1236
|
+
socket.onerror = null;
|
|
1237
|
+
reject(
|
|
1238
|
+
event instanceof Error ? event : new Error("Websocket connection error")
|
|
1239
|
+
);
|
|
1240
|
+
};
|
|
1241
|
+
});
|
|
1242
|
+
if (resumable) {
|
|
1243
|
+
this.makeResumable(true);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
onSocketDisconnect(handler) {
|
|
1247
|
+
if (!this.socket) {
|
|
1248
|
+
console.error(new Error("No socket connection"));
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
this.socket.onclose = handler;
|
|
1252
|
+
}
|
|
1253
|
+
onSocketError(handler) {
|
|
1254
|
+
if (!this.socket) {
|
|
1255
|
+
console.error(new Error("No socket connection"));
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
this.socket.onerror = handler;
|
|
1259
|
+
}
|
|
1260
|
+
makeResumable(disconnectsToo) {
|
|
1261
|
+
const scheduleReconnect = () => {
|
|
1262
|
+
setTimeout(() => {
|
|
1263
|
+
const previous = this.socket;
|
|
1264
|
+
this.detachMessageListener?.();
|
|
1265
|
+
this.detachMessageListener = void 0;
|
|
1266
|
+
this.socket = void 0;
|
|
1267
|
+
previous?.close();
|
|
1268
|
+
void this.connect(true, this.debugLogging);
|
|
1269
|
+
}, 1e3);
|
|
1270
|
+
};
|
|
1271
|
+
this.onSocketError(() => scheduleReconnect());
|
|
1272
|
+
if (disconnectsToo) {
|
|
1273
|
+
this.onSocketDisconnect(() => scheduleReconnect());
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
attachMessageListener() {
|
|
1277
|
+
if (!this.socket) {
|
|
1278
|
+
throw new Error("No socket connection");
|
|
1279
|
+
}
|
|
1280
|
+
this.detachMessageListener?.();
|
|
1281
|
+
const handler = (event) => {
|
|
1282
|
+
void this.handleIncomingMessage(event);
|
|
1283
|
+
};
|
|
1284
|
+
if (typeof this.socket.addEventListener === "function") {
|
|
1285
|
+
this.socket.addEventListener(
|
|
1286
|
+
"message",
|
|
1287
|
+
handler
|
|
1288
|
+
);
|
|
1289
|
+
this.detachMessageListener = () => {
|
|
1290
|
+
this.socket?.removeEventListener?.(
|
|
1291
|
+
"message",
|
|
1292
|
+
handler
|
|
1293
|
+
);
|
|
1294
|
+
};
|
|
1295
|
+
} else {
|
|
1296
|
+
const fallback = (data) => handler({ data });
|
|
1297
|
+
const socket = this.socket;
|
|
1298
|
+
socket.on?.("message", fallback);
|
|
1299
|
+
this.detachMessageListener = () => {
|
|
1300
|
+
const target = this.socket;
|
|
1301
|
+
if (!target) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
if (typeof target.off === "function") {
|
|
1305
|
+
target.off("message", fallback);
|
|
1306
|
+
} else if (typeof target.removeListener === "function") {
|
|
1307
|
+
target.removeListener("message", fallback);
|
|
1308
|
+
}
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
async handleIncomingMessage(event) {
|
|
1313
|
+
const message = this.parseMessage(event);
|
|
1314
|
+
if (!message) {
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
try {
|
|
1318
|
+
await this.dispatchMessage(message);
|
|
1319
|
+
} catch (error) {
|
|
1320
|
+
if (this.debugLogging) {
|
|
1321
|
+
console.error("Error while handling websocket message", error);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
parseMessage(event) {
|
|
1326
|
+
const payload = this.normalisePayload(event);
|
|
1327
|
+
if (!payload) {
|
|
1328
|
+
return null;
|
|
1329
|
+
}
|
|
1330
|
+
try {
|
|
1331
|
+
return JSON.parse(payload);
|
|
1332
|
+
} catch (error) {
|
|
1333
|
+
if (this.debugLogging) {
|
|
1334
|
+
console.warn("Failed to parse websocket payload", error);
|
|
1335
|
+
}
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
normalisePayload(event) {
|
|
1340
|
+
if (typeof event === "string") {
|
|
1341
|
+
return event;
|
|
1342
|
+
}
|
|
1343
|
+
if (typeof event === "object" && event !== null && "data" in event) {
|
|
1344
|
+
return this.normalisePayload(event.data);
|
|
1345
|
+
}
|
|
1346
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(event)) {
|
|
1347
|
+
return event.toString("utf8");
|
|
1348
|
+
}
|
|
1349
|
+
if (typeof ArrayBuffer !== "undefined" && event instanceof ArrayBuffer) {
|
|
1350
|
+
if (typeof TextDecoder !== "undefined") {
|
|
1351
|
+
return new TextDecoder().decode(new Uint8Array(event));
|
|
1352
|
+
}
|
|
1353
|
+
if (typeof Buffer !== "undefined") {
|
|
1354
|
+
return Buffer.from(event).toString("utf8");
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return null;
|
|
1358
|
+
}
|
|
1359
|
+
async dispatchMessage(message) {
|
|
1360
|
+
switch (message.event) {
|
|
1361
|
+
case "auth success" /* AUTH_SUCCESS */: {
|
|
1362
|
+
if (this.debugLogging) {
|
|
1363
|
+
console.debug("Auth success");
|
|
1364
|
+
}
|
|
1365
|
+
this.emit("auth success" /* AUTH_SUCCESS */);
|
|
1366
|
+
break;
|
|
1367
|
+
}
|
|
1368
|
+
case "status" /* STATUS */: {
|
|
1369
|
+
if (this.debugLogging) {
|
|
1370
|
+
console.debug("Received status event", message.args[0]);
|
|
1371
|
+
}
|
|
1372
|
+
this.emit("status" /* STATUS */, message.args[0]);
|
|
1373
|
+
break;
|
|
1374
|
+
}
|
|
1375
|
+
case "console output" /* CONSOLE_OUTPUT */: {
|
|
1376
|
+
let output = message.args[0];
|
|
1377
|
+
if (this.stripColors) {
|
|
1378
|
+
output = stripColor(output);
|
|
1379
|
+
}
|
|
1380
|
+
if (this.debugLogging) {
|
|
1381
|
+
console.debug("Received console output", output);
|
|
1382
|
+
}
|
|
1383
|
+
this.emit("console output" /* CONSOLE_OUTPUT */, output);
|
|
1384
|
+
break;
|
|
1385
|
+
}
|
|
1386
|
+
case "stats" /* STATS */: {
|
|
1387
|
+
try {
|
|
1388
|
+
const payload = JSON.parse(message.args[0]);
|
|
1389
|
+
this.emit("stats" /* STATS */, payload);
|
|
1390
|
+
} catch (error) {
|
|
1391
|
+
if (this.debugLogging) {
|
|
1392
|
+
console.warn("Failed to parse stats payload", error);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
break;
|
|
1396
|
+
}
|
|
1397
|
+
case "daemon error" /* DAEMON_ERROR */: {
|
|
1398
|
+
this.emit("daemon error" /* DAEMON_ERROR */);
|
|
1399
|
+
break;
|
|
1400
|
+
}
|
|
1401
|
+
case "backup completed" /* BACKUP_COMPLETED */: {
|
|
1402
|
+
try {
|
|
1403
|
+
const payload = JSON.parse(
|
|
1404
|
+
message.args[0]
|
|
1405
|
+
);
|
|
1406
|
+
this.emit("backup completed" /* BACKUP_COMPLETED */, payload);
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
if (this.debugLogging) {
|
|
1409
|
+
console.warn("Failed to parse backup payload", error);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
break;
|
|
1413
|
+
}
|
|
1414
|
+
case "daemon message" /* DAEMON_MESSAGE */: {
|
|
1415
|
+
let output = message.args[0];
|
|
1416
|
+
if (this.stripColors) {
|
|
1417
|
+
output = stripColor(output);
|
|
1418
|
+
}
|
|
1419
|
+
this.emit("daemon message" /* DAEMON_MESSAGE */, output);
|
|
1420
|
+
break;
|
|
1421
|
+
}
|
|
1422
|
+
case "install output" /* INSTALL_OUTPUT */: {
|
|
1423
|
+
let output = message.args[0];
|
|
1424
|
+
if (this.stripColors) {
|
|
1425
|
+
output = stripColor(output);
|
|
1426
|
+
}
|
|
1427
|
+
this.emit("install output" /* INSTALL_OUTPUT */, output);
|
|
1428
|
+
break;
|
|
1429
|
+
}
|
|
1430
|
+
case "backup restore completed" /* BACKUP_RESTORE_COMPLETED */: {
|
|
1431
|
+
this.emit("backup restore completed" /* BACKUP_RESTORE_COMPLETED */);
|
|
1432
|
+
break;
|
|
1433
|
+
}
|
|
1434
|
+
case "install completed" /* INSTALL_COMPLETED */: {
|
|
1435
|
+
this.emit("install completed" /* INSTALL_COMPLETED */);
|
|
1436
|
+
break;
|
|
1437
|
+
}
|
|
1438
|
+
case "install started" /* INSTALL_STARTED */: {
|
|
1439
|
+
this.emit("install started" /* INSTALL_STARTED */);
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
case "transfer logs" /* TRANSFER_LOGS */: {
|
|
1443
|
+
this.emit("transfer logs" /* TRANSFER_LOGS */, message.args[0]);
|
|
1444
|
+
break;
|
|
1445
|
+
}
|
|
1446
|
+
case "transfer status" /* TRANSFER_STATUS */: {
|
|
1447
|
+
this.emit("transfer status" /* TRANSFER_STATUS */, message.args[0]);
|
|
1448
|
+
break;
|
|
1449
|
+
}
|
|
1450
|
+
case "token expiring" /* TOKEN_EXPIRING */: {
|
|
1451
|
+
this.emit("token expiring" /* TOKEN_EXPIRING */);
|
|
1452
|
+
if (this.debugLogging) {
|
|
1453
|
+
console.warn("Token expiring, renewing...");
|
|
1454
|
+
}
|
|
1455
|
+
await this.refreshCredentials();
|
|
1456
|
+
await this.authenticate();
|
|
1457
|
+
break;
|
|
1458
|
+
}
|
|
1459
|
+
case "token expired" /* TOKEN_EXPIRED */: {
|
|
1460
|
+
this.emit("token expired" /* TOKEN_EXPIRED */);
|
|
1461
|
+
throw new Error("Token expired");
|
|
1462
|
+
}
|
|
1463
|
+
case "jwt error" /* JWT_ERROR */: {
|
|
1464
|
+
const reason = message.args[0];
|
|
1465
|
+
if (RECONNECT_ERRORS.has(reason)) {
|
|
1466
|
+
this.emit("token expiring" /* TOKEN_EXPIRING */);
|
|
1467
|
+
if (this.debugLogging) {
|
|
1468
|
+
console.warn("Token expiring (JWT error), renewing...");
|
|
1469
|
+
}
|
|
1470
|
+
await this.refreshCredentials();
|
|
1471
|
+
await this.authenticate();
|
|
1472
|
+
} else {
|
|
1473
|
+
this.emit("jwt error" /* JWT_ERROR */, reason);
|
|
1474
|
+
throw new Error("Token expired");
|
|
1475
|
+
}
|
|
1476
|
+
break;
|
|
1477
|
+
}
|
|
1478
|
+
default: {
|
|
1479
|
+
if (this.debugLogging) {
|
|
1480
|
+
console.warn("Unknown websocket event", message);
|
|
1481
|
+
}
|
|
1482
|
+
break;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1637
1485
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1486
|
+
async refreshCredentials() {
|
|
1487
|
+
const { data } = await this.r.get(
|
|
1488
|
+
`/servers/${this.serverId}/websocket`
|
|
1489
|
+
);
|
|
1490
|
+
this.currentToken = data.data.token;
|
|
1491
|
+
return data.data.socket;
|
|
1492
|
+
}
|
|
1493
|
+
async authenticate() {
|
|
1494
|
+
if (!this.socket) {
|
|
1495
|
+
throw new Error("No socket connection");
|
|
1496
|
+
}
|
|
1497
|
+
if (!this.currentToken) {
|
|
1498
|
+
throw new Error("Missing websocket token");
|
|
1499
|
+
}
|
|
1500
|
+
this.socket.send(
|
|
1501
|
+
JSON.stringify({ event: "auth", args: [this.currentToken] })
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
disconnect() {
|
|
1505
|
+
this.detachMessageListener?.();
|
|
1506
|
+
this.detachMessageListener = void 0;
|
|
1507
|
+
if (this.socket) {
|
|
1508
|
+
this.socket.close();
|
|
1509
|
+
this.socket = void 0;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
requestStats() {
|
|
1513
|
+
this.send("send stats", [null]);
|
|
1514
|
+
}
|
|
1515
|
+
requestLogs() {
|
|
1516
|
+
this.send("send logs", [null]);
|
|
1517
|
+
}
|
|
1518
|
+
send(event, args) {
|
|
1519
|
+
if (!this.socket) {
|
|
1520
|
+
if (this.debugLogging) {
|
|
1521
|
+
console.warn(
|
|
1522
|
+
`Attempted to send "${event}" without an active websocket connection`
|
|
1661
1523
|
);
|
|
1662
1524
|
}
|
|
1663
|
-
return
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
this.socket.send(JSON.stringify({ event, args }));
|
|
1528
|
+
}
|
|
1529
|
+
getStats() {
|
|
1530
|
+
return new Promise((resolve, reject) => {
|
|
1531
|
+
if (!this.socket) {
|
|
1532
|
+
reject(new Error("No socket connection"));
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
let off;
|
|
1536
|
+
const timeout = setTimeout(() => {
|
|
1537
|
+
off?.();
|
|
1538
|
+
reject(new Error("Timed out waiting for stats"));
|
|
1539
|
+
}, 5e3);
|
|
1540
|
+
off = this.on("stats" /* STATS */, (payload) => {
|
|
1541
|
+
clearTimeout(timeout);
|
|
1542
|
+
off?.();
|
|
1543
|
+
resolve(payload);
|
|
1544
|
+
});
|
|
1545
|
+
this.requestStats();
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
getLogs() {
|
|
1549
|
+
return new Promise((resolve, reject) => {
|
|
1550
|
+
if (!this.socket) {
|
|
1551
|
+
reject(new Error("No socket connection"));
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
const lines = [];
|
|
1555
|
+
let off;
|
|
1556
|
+
let initialTimeout;
|
|
1557
|
+
let idleTimeout;
|
|
1558
|
+
const finalize = (payload) => {
|
|
1559
|
+
off?.();
|
|
1560
|
+
if (initialTimeout) {
|
|
1561
|
+
clearTimeout(initialTimeout);
|
|
1562
|
+
}
|
|
1563
|
+
if (idleTimeout) {
|
|
1564
|
+
clearTimeout(idleTimeout);
|
|
1565
|
+
}
|
|
1566
|
+
resolve(payload);
|
|
1567
|
+
};
|
|
1568
|
+
initialTimeout = setTimeout(() => {
|
|
1569
|
+
finalize(lines.length > 0 ? lines : [FALLBACK_LOG_MESSAGE]);
|
|
1570
|
+
}, 5e3);
|
|
1571
|
+
off = this.on("console output" /* CONSOLE_OUTPUT */, (line) => {
|
|
1572
|
+
lines.push(line);
|
|
1573
|
+
if (initialTimeout) {
|
|
1574
|
+
clearTimeout(initialTimeout);
|
|
1575
|
+
initialTimeout = void 0;
|
|
1576
|
+
}
|
|
1577
|
+
if (idleTimeout) {
|
|
1578
|
+
clearTimeout(idleTimeout);
|
|
1579
|
+
}
|
|
1580
|
+
idleTimeout = setTimeout(() => {
|
|
1581
|
+
finalize(lines);
|
|
1582
|
+
}, 1e3);
|
|
1583
|
+
});
|
|
1584
|
+
this.requestLogs();
|
|
1664
1585
|
});
|
|
1665
1586
|
}
|
|
1587
|
+
sendPoweraction(action) {
|
|
1588
|
+
this.send("set state", [action]);
|
|
1589
|
+
}
|
|
1590
|
+
sendCommand(cmd) {
|
|
1591
|
+
this.send("send command", [cmd]);
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
// src/api/client/server.ts
|
|
1596
|
+
var ServerClient = class {
|
|
1597
|
+
r;
|
|
1598
|
+
id;
|
|
1599
|
+
activity;
|
|
1600
|
+
databases;
|
|
1601
|
+
files;
|
|
1602
|
+
schedules;
|
|
1603
|
+
allocations;
|
|
1604
|
+
users;
|
|
1605
|
+
backups;
|
|
1606
|
+
startup;
|
|
1607
|
+
variables;
|
|
1608
|
+
settings;
|
|
1609
|
+
constructor(requester, id) {
|
|
1610
|
+
this.r = requester;
|
|
1611
|
+
this.id = id;
|
|
1612
|
+
this.activity = new ServerActivity(requester, id);
|
|
1613
|
+
this.databases = new ServerDatabases(requester, id);
|
|
1614
|
+
this.files = new ServerFiles(requester, id);
|
|
1615
|
+
this.schedules = new ServerSchedules(requester, id);
|
|
1616
|
+
this.allocations = new ServerAllocations(requester, id);
|
|
1617
|
+
this.users = new ServerUsers(requester, id);
|
|
1618
|
+
this.backups = new ServerBackups(requester, id);
|
|
1619
|
+
this.startup = new ServerStartup(requester, id);
|
|
1620
|
+
this.variables = this.startup;
|
|
1621
|
+
this.settings = new ServerSettings(requester, id);
|
|
1622
|
+
}
|
|
1623
|
+
info = async (include) => {
|
|
1624
|
+
const { data } = await this.r.get(
|
|
1625
|
+
`/servers/${this.id}`,
|
|
1626
|
+
{ params: { include: include?.join(",") } }
|
|
1627
|
+
);
|
|
1628
|
+
return data.attributes;
|
|
1629
|
+
};
|
|
1630
|
+
websocket = (stripColors = false) => {
|
|
1631
|
+
return new ServerWebsocket(this.r, this.id, stripColors);
|
|
1632
|
+
};
|
|
1633
|
+
resources = async () => {
|
|
1634
|
+
const { data } = await this.r.get(
|
|
1635
|
+
`/servers/${this.id}/resources`
|
|
1636
|
+
);
|
|
1637
|
+
return data.attributes;
|
|
1638
|
+
};
|
|
1639
|
+
command = async (command) => {
|
|
1640
|
+
await this.r.post(`/servers/${this.id}/command`, { command });
|
|
1641
|
+
};
|
|
1642
|
+
power = async (signal) => {
|
|
1643
|
+
await this.r.post(`/servers/${this.id}/power`, { signal });
|
|
1644
|
+
};
|
|
1645
|
+
};
|
|
1646
|
+
|
|
1647
|
+
// src/api/client/client.ts
|
|
1648
|
+
var Client = class {
|
|
1649
|
+
account;
|
|
1650
|
+
r;
|
|
1651
|
+
constructor(requester) {
|
|
1652
|
+
this.r = requester;
|
|
1653
|
+
this.account = new Account(requester);
|
|
1654
|
+
}
|
|
1655
|
+
get $r() {
|
|
1656
|
+
return this.r;
|
|
1657
|
+
}
|
|
1658
|
+
listPermissions = async () => {
|
|
1659
|
+
const { data } = await this.r.get("/permissions");
|
|
1660
|
+
return data.attributes.permissions;
|
|
1661
|
+
};
|
|
1662
|
+
listServers = async (type = "accessible", page = 1, per_page = 50, include) => {
|
|
1663
|
+
z14.number().positive().parse(page);
|
|
1664
|
+
const { data } = await this.r.get("/", { params: { type, page, include: include?.join(",") } });
|
|
1665
|
+
return data.data.map((s) => s.attributes);
|
|
1666
|
+
};
|
|
1667
|
+
server = (uuid) => new ServerClient(this.r, uuid);
|
|
1666
1668
|
};
|
|
1667
1669
|
|
|
1668
1670
|
// src/api/index.ts
|
|
@@ -2038,14 +2040,27 @@ var ServerUser = class {
|
|
|
2038
2040
|
// src/humane/Server.ts
|
|
2039
2041
|
var Server = class {
|
|
2040
2042
|
client;
|
|
2043
|
+
/**
|
|
2044
|
+
* Whether the user owns the server
|
|
2045
|
+
*
|
|
2046
|
+
* @remarks
|
|
2047
|
+
* Useful for gatekeeping features from subusers
|
|
2048
|
+
*/
|
|
2041
2049
|
ownsServer;
|
|
2042
2050
|
identifier;
|
|
2051
|
+
/**
|
|
2052
|
+
* ID used by Pelican Application API
|
|
2053
|
+
*/
|
|
2043
2054
|
internalId;
|
|
2044
2055
|
uuid;
|
|
2045
2056
|
$name;
|
|
2046
2057
|
get name() {
|
|
2047
2058
|
return this.$name;
|
|
2048
2059
|
}
|
|
2060
|
+
/**
|
|
2061
|
+
* Node name used by this server
|
|
2062
|
+
* @
|
|
2063
|
+
*/
|
|
2049
2064
|
node;
|
|
2050
2065
|
isNodeUnderMaintenance;
|
|
2051
2066
|
sftp;
|
|
@@ -2179,14 +2194,30 @@ var Client3 = class {
|
|
|
2179
2194
|
constructor(client) {
|
|
2180
2195
|
this.client = client;
|
|
2181
2196
|
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Get raw API client
|
|
2199
|
+
*/
|
|
2182
2200
|
get $client() {
|
|
2183
2201
|
return this.client;
|
|
2184
2202
|
}
|
|
2203
|
+
/**
|
|
2204
|
+
* Get user account
|
|
2205
|
+
*/
|
|
2185
2206
|
getAccount = async () => {
|
|
2186
2207
|
const user = await this.client.account.info();
|
|
2187
2208
|
return new Account2(this.client, user);
|
|
2188
2209
|
};
|
|
2210
|
+
/**
|
|
2211
|
+
* Get subuser (current user) permissions
|
|
2212
|
+
*
|
|
2213
|
+
* Return data is not compatible with subusers API
|
|
2214
|
+
*/
|
|
2189
2215
|
listPermissions = async () => this.client.listPermissions();
|
|
2216
|
+
/**
|
|
2217
|
+
* List servers
|
|
2218
|
+
*
|
|
2219
|
+
* @param opts Filtering options (all optional)
|
|
2220
|
+
*/
|
|
2190
2221
|
listServers = async (opts = { type: "accessible", page: 1, per_page: 50 }) => {
|
|
2191
2222
|
const data = await this.client.listServers(
|
|
2192
2223
|
opts.type,
|
|
@@ -2196,6 +2227,12 @@ var Client3 = class {
|
|
|
2196
2227
|
);
|
|
2197
2228
|
return data.map((d) => new Server(this.client.server(d.uuid), d));
|
|
2198
2229
|
};
|
|
2230
|
+
/**
|
|
2231
|
+
* Get server by UUID
|
|
2232
|
+
*
|
|
2233
|
+
* @param uuid Server UUID
|
|
2234
|
+
* @param include Include additional data
|
|
2235
|
+
*/
|
|
2199
2236
|
getServer = async (uuid, include) => {
|
|
2200
2237
|
const server = await this.client.server(uuid).info(include);
|
|
2201
2238
|
return new Server(this.client.server(uuid), server);
|