@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.js
CHANGED
|
@@ -43,948 +43,129 @@ __export(index_exports, {
|
|
|
43
43
|
});
|
|
44
44
|
module.exports = __toCommonJS(index_exports);
|
|
45
45
|
|
|
46
|
-
// src/api/
|
|
46
|
+
// src/api/application/database_hosts.ts
|
|
47
47
|
var import_zod = __toESM(require("zod"));
|
|
48
|
-
var
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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/
|
|
58
|
+
// src/api/application/mounts.ts
|
|
101
59
|
var import_zod2 = __toESM(require("zod"));
|
|
102
|
-
var
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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/
|
|
130
|
-
var
|
|
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/
|
|
225
|
-
var
|
|
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/
|
|
288
|
-
var
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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/
|
|
319
|
-
var
|
|
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/
|
|
353
|
-
var
|
|
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/
|
|
411
|
-
var
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
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/
|
|
433
|
-
var
|
|
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
|
|
987
|
-
var languagesSchema =
|
|
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 =
|
|
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 =
|
|
1547
|
-
email:
|
|
1548
|
-
external_id:
|
|
1549
|
-
username:
|
|
1550
|
-
password:
|
|
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/
|
|
1556
|
-
var
|
|
779
|
+
// src/api/client/client.ts
|
|
780
|
+
var import_zod14 = __toESM(require("zod"));
|
|
1557
781
|
|
|
1558
|
-
// src/api/
|
|
1559
|
-
var
|
|
1560
|
-
var
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
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/
|
|
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/
|
|
1587
|
-
var
|
|
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/
|
|
1590
|
-
var
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
});
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
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/
|
|
1649
|
-
var
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
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/
|
|
1123
|
+
// src/api/client/server_settings.ts
|
|
1661
1124
|
var import_zod13 = __toESM(require("zod"));
|
|
1662
|
-
var
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
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/
|
|
1671
|
-
var
|
|
1672
|
-
|
|
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/
|
|
1675
|
-
var
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
constructor(
|
|
1679
|
-
|
|
1680
|
-
this.
|
|
1681
|
-
|
|
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
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
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
|
|
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);
|