wispjs 2.4.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/wisp_api/index.d.ts +6 -0
- package/dist/wisp_api/index.js +8 -0
- package/dist/wisp_socket/filesystem.d.ts +60 -0
- package/dist/wisp_socket/filesystem.js +97 -0
- package/dist/wisp_socket/git.d.ts +57 -0
- package/dist/wisp_socket/git.js +76 -0
- package/dist/wisp_socket/index.d.ts +37 -18
- package/dist/wisp_socket/index.js +117 -158
- package/dist/wisp_socket/pool.d.ts +192 -48
- package/dist/wisp_socket/pool.js +132 -33
- package/dist/wisp_socket/ws_adapter.d.ts +72 -0
- package/dist/wisp_socket/ws_adapter.js +130 -0
- package/package.json +5 -4
- package/.github/workflows/release.yml +0 -77
- package/tsconfig.json +0 -19
- package/wisp.ts +0 -43
- package/wisp_api/apis/allocations.ts +0 -71
- package/wisp_api/apis/audit_log.ts +0 -81
- package/wisp_api/apis/backups.ts +0 -168
- package/wisp_api/apis/databases.ts +0 -80
- package/wisp_api/apis/fastdl.ts +0 -22
- package/wisp_api/apis/filesystem.ts +0 -291
- package/wisp_api/apis/index.ts +0 -135
- package/wisp_api/apis/mods.ts +0 -53
- package/wisp_api/apis/schedules.ts +0 -270
- package/wisp_api/apis/servers.ts +0 -155
- package/wisp_api/apis/startup.ts +0 -65
- package/wisp_api/apis/subusers.ts +0 -159
- package/wisp_api/index.ts +0 -57
- package/wisp_socket/index.ts +0 -495
- package/wisp_socket/pool.ts +0 -369
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import WebSocket from "ws";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
/**
|
|
4
|
+
* A thin adapter that exposes a Socket.IO-like event API over a plain `ws`
|
|
5
|
+
* WebSocket.
|
|
6
|
+
*
|
|
7
|
+
* The new backend speaks a simple JSON envelope rather than the Socket.IO /
|
|
8
|
+
* Engine.IO framing:
|
|
9
|
+
*
|
|
10
|
+
* ```json
|
|
11
|
+
* { "event": "console output", "args": ["...line..."] }
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* `args` is omitted entirely when an event carries no payload
|
|
15
|
+
* (e.g. `{ "event": "auth success" }`).
|
|
16
|
+
*
|
|
17
|
+
* This class translates between that envelope and the `.on/.once/.off/.emit`
|
|
18
|
+
* surface the rest of the codebase already uses, so the calling code barely
|
|
19
|
+
* changes.
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* We *compose* an EventEmitter instead of extending one on purpose: extending
|
|
23
|
+
* it would mean overriding `emit()`, which EventEmitter also calls internally
|
|
24
|
+
* (e.g. the `newListener` event) — so every `.on()` would try to send a frame
|
|
25
|
+
* to the server. Composition keeps "emit to the wire" and "fire local
|
|
26
|
+
* listeners" cleanly separate.
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export class WispWebSocket {
|
|
31
|
+
constructor(url, opts = {}) {
|
|
32
|
+
this.emitter = new EventEmitter();
|
|
33
|
+
this.url = url;
|
|
34
|
+
this.origin = opts.origin;
|
|
35
|
+
// The pool registers a handful of listeners per worker; silence the
|
|
36
|
+
// default 10-listener warning.
|
|
37
|
+
this.emitter.setMaxListeners(0);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Opens the underlying WebSocket and wires up frame translation.
|
|
41
|
+
*/
|
|
42
|
+
connect() {
|
|
43
|
+
const ws = new WebSocket(this.url, this.origin ? { origin: this.origin } : undefined);
|
|
44
|
+
this.ws = ws;
|
|
45
|
+
// Map ws lifecycle onto the Socket.IO-style events the pool listens for
|
|
46
|
+
ws.on("open", () => this.emitter.emit("connect"));
|
|
47
|
+
ws.on("close", (code, reason) => {
|
|
48
|
+
this.emitter.emit("disconnect", reason?.toString() || `code ${code}`);
|
|
49
|
+
});
|
|
50
|
+
ws.on("error", (err) => this.emitter.emit("connect_error", err));
|
|
51
|
+
ws.on("message", (data, isBinary) => {
|
|
52
|
+
if (isBinary)
|
|
53
|
+
return;
|
|
54
|
+
let frame;
|
|
55
|
+
try {
|
|
56
|
+
frame = JSON.parse(data.toString());
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return; // ignore anything that isn't our JSON envelope
|
|
60
|
+
}
|
|
61
|
+
const event = frame.event;
|
|
62
|
+
if (!event)
|
|
63
|
+
return;
|
|
64
|
+
const args = frame.args ?? [];
|
|
65
|
+
// EventEmitter throws if "error" is emitted with no listener; guard it.
|
|
66
|
+
if (event === "error" && this.emitter.listenerCount("error") === 0) {
|
|
67
|
+
console.error("[ws] server error frame:", ...args);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.emitter.emit(event, ...args);
|
|
71
|
+
});
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Sends an event to the server as a `{ event, args }` JSON frame.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* Unlike EventEmitter.emit, this does NOT fire local listeners — it writes
|
|
79
|
+
* to the socket. Incoming frames fire local listeners via the internal
|
|
80
|
+
* emitter.
|
|
81
|
+
*/
|
|
82
|
+
emit(event, ...args) {
|
|
83
|
+
this.outgoingListener?.(event, ...args);
|
|
84
|
+
const frame = JSON.stringify(args.length ? { event, args } : { event });
|
|
85
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
86
|
+
this.ws.send(frame);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.error(`[ws] dropped outgoing "${event}" — socket not open`);
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
on(event, listener) {
|
|
94
|
+
this.emitter.on(event, listener);
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
once(event, listener) {
|
|
98
|
+
this.emitter.once(event, listener);
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Removes a specific listener, or — matching Socket.IO's behaviour — all
|
|
103
|
+
* listeners for an event when no listener is given.
|
|
104
|
+
*/
|
|
105
|
+
off(event, listener) {
|
|
106
|
+
if (listener) {
|
|
107
|
+
this.emitter.off(event, listener);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.emitter.removeAllListeners(event);
|
|
111
|
+
}
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
removeAllListeners(event) {
|
|
115
|
+
this.emitter.removeAllListeners(event);
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Registers a callback invoked for every outgoing emit (parity with
|
|
120
|
+
* Socket.IO's `onAnyOutgoing`, used for logging).
|
|
121
|
+
*/
|
|
122
|
+
onAnyOutgoing(listener) {
|
|
123
|
+
this.outgoingListener = listener;
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
disconnect() {
|
|
127
|
+
this.ws?.close();
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wispjs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A package for interacting with Wisp-based server panels",
|
|
6
6
|
"main": "dist/wisp.js",
|
|
7
7
|
"types": "dist/wisp.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsc",
|
|
10
|
-
"build-docs": "typedoc wisp.ts wisp_api/index.ts wisp_socket/index.ts wisp_api/apis/*"
|
|
10
|
+
"build-docs": "typedoc wisp.ts wisp_api/index.ts wisp_socket/index.ts wisp_socket/git.ts wisp_socket/filesystem.ts wisp_api/apis/*"
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/CFC-Servers/WispJS#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"
|
|
24
|
-
"
|
|
23
|
+
"strip-ansi": "^7.1.0",
|
|
24
|
+
"ws": "^8.21.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^20.5.4",
|
|
28
|
+
"@types/ws": "^8.18.1",
|
|
28
29
|
"typedoc": "^0.25.4",
|
|
29
30
|
"typescript": "^5.3.3"
|
|
30
31
|
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
name: Deploy
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
inputs:
|
|
6
|
-
version_tag:
|
|
7
|
-
description: "Version tag for the package"
|
|
8
|
-
required: true
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
build:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
|
|
16
|
-
- uses: actions/setup-node@v4
|
|
17
|
-
with:
|
|
18
|
-
node-version: 18
|
|
19
|
-
|
|
20
|
-
- name: Update package version
|
|
21
|
-
run: |
|
|
22
|
-
version=${{ inputs.version_tag }}
|
|
23
|
-
npm version $version --no-git-tag-version
|
|
24
|
-
|
|
25
|
-
- name: Install packages
|
|
26
|
-
run: |
|
|
27
|
-
npm ci
|
|
28
|
-
|
|
29
|
-
- name: Build
|
|
30
|
-
run: |
|
|
31
|
-
npm run build
|
|
32
|
-
|
|
33
|
-
- name: Generate Docs
|
|
34
|
-
run: |
|
|
35
|
-
npm run build-docs
|
|
36
|
-
mv docs ../docs_wip
|
|
37
|
-
|
|
38
|
-
- name: Remove Non-distributables
|
|
39
|
-
run: |
|
|
40
|
-
rm .gitignore
|
|
41
|
-
rm tsconfig.json
|
|
42
|
-
rm wisp.ts
|
|
43
|
-
rm -rf wisp_api wisp_socket .github
|
|
44
|
-
|
|
45
|
-
- name: Publish
|
|
46
|
-
uses: JS-DevTools/npm-publish@v3
|
|
47
|
-
with:
|
|
48
|
-
token: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
|
49
|
-
|
|
50
|
-
- name: Configure Git User
|
|
51
|
-
run: |
|
|
52
|
-
git config user.name github-actions
|
|
53
|
-
git config user.email github-actions@github.com
|
|
54
|
-
|
|
55
|
-
- name: Push package version change
|
|
56
|
-
run: |
|
|
57
|
-
git add package.json
|
|
58
|
-
git add package-lock.json
|
|
59
|
-
git commit -m "Update package.json version to: ${{ inputs.version_tag }}" && \
|
|
60
|
-
git push --force-with-lease origin main || \
|
|
61
|
-
echo "Version tag unchanaged"
|
|
62
|
-
|
|
63
|
-
- name: Push new tag
|
|
64
|
-
run: |
|
|
65
|
-
git tag "${{ inputs.version_tag }}"
|
|
66
|
-
git push --tags
|
|
67
|
-
|
|
68
|
-
- name: Publish Docs
|
|
69
|
-
run: |
|
|
70
|
-
# Delete everything except .git
|
|
71
|
-
find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} +
|
|
72
|
-
|
|
73
|
-
# Move the docs back and commit only them
|
|
74
|
-
mv ../docs_wip docs
|
|
75
|
-
git add .
|
|
76
|
-
git commit -m "Update Docs for version: ${{ inputs.version_tag }}"
|
|
77
|
-
git push --force origin HEAD:docs
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
|
|
6
|
-
"outDir": "./dist/",
|
|
7
|
-
"declaration": true,
|
|
8
|
-
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
|
|
12
|
-
"strict": true,
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"moduleResolution": "node"
|
|
15
|
-
},
|
|
16
|
-
"include": ["*.ts"],
|
|
17
|
-
"exclude": ["node_modules"]
|
|
18
|
-
}
|
|
19
|
-
|
package/wisp.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { WispAPI } from "./wisp_api/index.js";
|
|
2
|
-
import { WispSocket } from "./wisp_socket/index.js";
|
|
3
|
-
|
|
4
|
-
export interface WispInterface {
|
|
5
|
-
socket: WispSocket;
|
|
6
|
-
api: WispAPI;
|
|
7
|
-
logger: any;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* The primary Wisp Interface, exposing interactions with both the HTTP and Websockets API
|
|
12
|
-
*
|
|
13
|
-
* @param domain The Domain of the Pterodactyl/Wisp panel (e.g. `my.gamepanel.gg`)
|
|
14
|
-
* @param uuid The UUID of the server to reference in all API requests
|
|
15
|
-
* @param token The panel API token to use for authorization
|
|
16
|
-
* @param ghPAT The Github Personal Access Token used for Cloning/Pulling of private repositories. This may be omitted if you do not need to interact with private repositories
|
|
17
|
-
*
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
export class WispInterface {
|
|
21
|
-
constructor(domain: string, uuid: string, token: string, ghPAT?: string) {
|
|
22
|
-
this.logger = {
|
|
23
|
-
info: (msg: any) => {
|
|
24
|
-
console.log(msg);
|
|
25
|
-
},
|
|
26
|
-
error: (msg: string) => {
|
|
27
|
-
console.error(msg);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
this.api = new WispAPI(domain, uuid, token, this.logger);
|
|
32
|
-
this.socket = new WispSocket(this.logger, this.api, ghPAT);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Manually disconnects from the Websocket connection(s)
|
|
37
|
-
*
|
|
38
|
-
* @public
|
|
39
|
-
*/
|
|
40
|
-
async disconnect() {
|
|
41
|
-
await this.socket.disconnect();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { WispAPICore } from "./index";
|
|
2
|
-
import type { PaginationData } from "./index";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* An Allocation object
|
|
6
|
-
*
|
|
7
|
-
* @internal
|
|
8
|
-
*/
|
|
9
|
-
export interface Allocation {
|
|
10
|
-
object: "allocation";
|
|
11
|
-
attributes: {
|
|
12
|
-
id: number;
|
|
13
|
-
/** Whether or not this Allocation is the primary one for the Server */
|
|
14
|
-
primary: boolean;
|
|
15
|
-
ip: string;
|
|
16
|
-
port: number;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The response object from the GetAllocations call
|
|
22
|
-
*
|
|
23
|
-
* @remarks
|
|
24
|
-
* Used in {@link AllocationsAPI.List}
|
|
25
|
-
*
|
|
26
|
-
* @public
|
|
27
|
-
*/
|
|
28
|
-
export interface GetAllocationsResponse {
|
|
29
|
-
object: "list";
|
|
30
|
-
data: Allocation[];
|
|
31
|
-
meta: {
|
|
32
|
-
pagination: PaginationData;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Handles the listing and updating of a Server's IP/Port Allocations
|
|
38
|
-
*
|
|
39
|
-
* @public
|
|
40
|
-
*/
|
|
41
|
-
export class AllocationsAPI {
|
|
42
|
-
constructor(private core: WispAPICore) {}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Lists all Allocations for the Server
|
|
47
|
-
*
|
|
48
|
-
* @public
|
|
49
|
-
*/
|
|
50
|
-
async List(): Promise<GetAllocationsResponse> {
|
|
51
|
-
const response = await this.core.makeRequest("GET", "allocations");
|
|
52
|
-
const data: GetAllocationsResponse = await response.json()
|
|
53
|
-
|
|
54
|
-
return data;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Sets the new primary Allocation for the server
|
|
60
|
-
*
|
|
61
|
-
* @param id Allocation ID of the new primary allocation
|
|
62
|
-
*
|
|
63
|
-
* @public
|
|
64
|
-
*/
|
|
65
|
-
async Update(id: string): Promise<Allocation> {
|
|
66
|
-
const response = await this.core.makeRequest("PUT", `allocations/${id}`);
|
|
67
|
-
const data: Allocation = await response.json()
|
|
68
|
-
|
|
69
|
-
return data;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { WispAPICore } from "./index";
|
|
2
|
-
import type { PaginationData } from "./index";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Device information
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```json
|
|
9
|
-
* {
|
|
10
|
-
* "city_name": "Seattle",
|
|
11
|
-
* "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0",
|
|
12
|
-
* "country_name": "US",
|
|
13
|
-
* "country_iso_code": "US"
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* @internal
|
|
18
|
-
*/
|
|
19
|
-
export interface Device {
|
|
20
|
-
city_name: string;
|
|
21
|
-
user_agent: string;
|
|
22
|
-
country_name: string;
|
|
23
|
-
country_iso_code: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// TODO: Fully define the audit log type
|
|
27
|
-
/**
|
|
28
|
-
* An Audit Log struct
|
|
29
|
-
*
|
|
30
|
-
* @internal
|
|
31
|
-
*/
|
|
32
|
-
export interface AuditLog {
|
|
33
|
-
object: "audit_log";
|
|
34
|
-
attributes: {
|
|
35
|
-
action: string;
|
|
36
|
-
subaction: string;
|
|
37
|
-
device: Device | undefined;
|
|
38
|
-
metadata: any;
|
|
39
|
-
created_at: string;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* The respones object from the GetAuditLogs call
|
|
45
|
-
*
|
|
46
|
-
* @remarks
|
|
47
|
-
* Used in {@link AuditLogsAPI.List}
|
|
48
|
-
*
|
|
49
|
-
* @public
|
|
50
|
-
*/
|
|
51
|
-
export interface GetAuditLogsResponse {
|
|
52
|
-
object: "list";
|
|
53
|
-
data: AuditLog[];
|
|
54
|
-
meta: {
|
|
55
|
-
pagination: PaginationData;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Interface that handles Listing of all Audit Logs
|
|
62
|
-
*
|
|
63
|
-
* @public
|
|
64
|
-
*/
|
|
65
|
-
export class AuditLogsAPI {
|
|
66
|
-
constructor(private core: WispAPICore) {}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// TODO: Handle pagination
|
|
70
|
-
/**
|
|
71
|
-
* List all Audit Log events for the server
|
|
72
|
-
*
|
|
73
|
-
* @public
|
|
74
|
-
*/
|
|
75
|
-
async List(): Promise<GetAuditLogsResponse> {
|
|
76
|
-
const response = await this.core.makeRequest("GET", "audit-logs");
|
|
77
|
-
const data: GetAuditLogsResponse = await response.json();
|
|
78
|
-
|
|
79
|
-
return data;
|
|
80
|
-
}
|
|
81
|
-
}
|
package/wisp_api/apis/backups.ts
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { WispAPICore } from "./index";
|
|
2
|
-
import type { PaginationData } from "./index";
|
|
3
|
-
import type { DownloadFileResponse } from "./filesystem";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Backup Object
|
|
7
|
-
* @example
|
|
8
|
-
* ```json
|
|
9
|
-
* {
|
|
10
|
-
* "object": "backup",
|
|
11
|
-
* "attributes": {
|
|
12
|
-
* "uuid": "26adeafc-74af-43fd-93a5-9afa0486b21b",
|
|
13
|
-
* "uuid_short": "26adeafc",
|
|
14
|
-
* "name": "test-1",
|
|
15
|
-
* "sha256_hash": "56d2965e9167c785647878a391dfe24460c3aa5e1111b385708094bd8837b487",
|
|
16
|
-
* "bytes": 3266448936,
|
|
17
|
-
* "locked": false,
|
|
18
|
-
* "creating": false,
|
|
19
|
-
* "created_at": "2023-11-28T08:37:39.000000Z"
|
|
20
|
-
* }
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @internal
|
|
25
|
-
*/
|
|
26
|
-
export interface Backup {
|
|
27
|
-
object: "backup";
|
|
28
|
-
attributes: {
|
|
29
|
-
uuid: string;
|
|
30
|
-
uuid_short: string;
|
|
31
|
-
name: string;
|
|
32
|
-
/** The hash of the Backup. May be null if the Backup is still being created. */
|
|
33
|
-
sha256_hash: string | null;
|
|
34
|
-
bytes: number;
|
|
35
|
-
locked: boolean;
|
|
36
|
-
creating: boolean;
|
|
37
|
-
created_at: string;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Response object used in the GetBackups call
|
|
43
|
-
*
|
|
44
|
-
* @remarks
|
|
45
|
-
* Used in {@link BackupsAPI.List}
|
|
46
|
-
*
|
|
47
|
-
* @internal
|
|
48
|
-
*/
|
|
49
|
-
export interface GetBackupsResponse {
|
|
50
|
-
object: "list";
|
|
51
|
-
data: Backup[];
|
|
52
|
-
meta: {
|
|
53
|
-
pagination: PaginationData;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export type BackupErrorCode = "server.backups.creation_would_exceed_limit";
|
|
58
|
-
export interface BackupError {
|
|
59
|
-
code: BackupErrorCode;
|
|
60
|
-
data: any;
|
|
61
|
-
}
|
|
62
|
-
export interface CreateBackupFailure {
|
|
63
|
-
errors: BackupError[] | undefined
|
|
64
|
-
}
|
|
65
|
-
export type CreateBackupResponse = Backup | CreateBackupFailure;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Handles basic server backup tasks, such as creating, restoring, and deleting backups
|
|
69
|
-
*/
|
|
70
|
-
export class BackupsAPI {
|
|
71
|
-
constructor(private core: WispAPICore) {}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Lists all current backups for the server
|
|
75
|
-
*
|
|
76
|
-
* @public
|
|
77
|
-
*/
|
|
78
|
-
async List(): Promise<GetBackupsResponse> {
|
|
79
|
-
const response = await this.core.makeRequest("GET", "backups");
|
|
80
|
-
const data: GetBackupsResponse = await response.json();
|
|
81
|
-
|
|
82
|
-
return data;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Creates a new backup for the server
|
|
87
|
-
*
|
|
88
|
-
* @remarks
|
|
89
|
-
* ⚠️ This can fail to create a Backup even if the function completes successfully
|
|
90
|
-
* For example, if the backup would exceed the size limit (and the limit is not 0), the system wouldn't know it failed until it hit the limit.
|
|
91
|
-
*
|
|
92
|
-
* ⚠️ "It is recomended to stop your server before starting a backup. Backups created while the server is on can contain corupted data."
|
|
93
|
-
*
|
|
94
|
-
* Multiple Backups can exist with the same name.
|
|
95
|
-
*
|
|
96
|
-
* @param name The name of the Backup
|
|
97
|
-
*
|
|
98
|
-
* @throws {@link BackupErrorCode}
|
|
99
|
-
* If the server returns an error code, it will be thrown verbatim here
|
|
100
|
-
*
|
|
101
|
-
* @public
|
|
102
|
-
*/
|
|
103
|
-
async Create(name: string): Promise<CreateBackupResponse> {
|
|
104
|
-
const response = await this.core.makeRequest("POST", "backups", { name: name });
|
|
105
|
-
const data: CreateBackupResponse = await response.json()
|
|
106
|
-
|
|
107
|
-
if ("errors" in data && data.errors) {
|
|
108
|
-
throw new Error(data.errors[0].code);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return data
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Toggles the "Locked" status of the Backup
|
|
116
|
-
*
|
|
117
|
-
* @param id The ID of the Backup
|
|
118
|
-
*
|
|
119
|
-
* @public
|
|
120
|
-
*/
|
|
121
|
-
async ToggleLock(id: string): Promise<Backup> {
|
|
122
|
-
const response = await this.core.makeRequest("POST", `backups/${id}/locked`);
|
|
123
|
-
const data: Backup = await response.json();
|
|
124
|
-
|
|
125
|
-
return data;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Deploys the Backup to the Server
|
|
130
|
-
*
|
|
131
|
-
* @remarks
|
|
132
|
-
* **⚠️ This can be dangerous!**
|
|
133
|
-
* The Backup will overwrite the entire Server, erasing any new data since the Backup's creation
|
|
134
|
-
*
|
|
135
|
-
* @param id The ID of the Backup
|
|
136
|
-
*
|
|
137
|
-
* @public
|
|
138
|
-
*/
|
|
139
|
-
async Deploy(id: string): Promise<Response> {
|
|
140
|
-
return await this.core.makeRequest("POST", `backups/${id}/deploy`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Retrieves a URL from which the Backup can be downloaded
|
|
145
|
-
*
|
|
146
|
-
* @param id The ID of the Backup
|
|
147
|
-
* @returns The download URL
|
|
148
|
-
*
|
|
149
|
-
* @public
|
|
150
|
-
*/
|
|
151
|
-
async GetDownloadURL(id: string): Promise<string> {
|
|
152
|
-
const response = await this.core.makeRequest("GET", `backups/${id}/download`);
|
|
153
|
-
const data: DownloadFileResponse = await response.json();
|
|
154
|
-
|
|
155
|
-
return data.url;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Deletes the Backup
|
|
160
|
-
*
|
|
161
|
-
* @param id The ID of the Backup
|
|
162
|
-
*
|
|
163
|
-
* @public
|
|
164
|
-
*/
|
|
165
|
-
async Delete(id: string): Promise<void> {
|
|
166
|
-
await this.core.makeRequest("DELETE", `backups/${id}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { WispAPICore } from "./index";
|
|
2
|
-
import type { PaginationData } from "./index";
|
|
3
|
-
|
|
4
|
-
export interface DatabaseRelationship {
|
|
5
|
-
object: "database_host";
|
|
6
|
-
attributes: {
|
|
7
|
-
id: number;
|
|
8
|
-
name: string;
|
|
9
|
-
host: string;
|
|
10
|
-
port: number;
|
|
11
|
-
phpmyadmin_url: string | null;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface Database {
|
|
16
|
-
object: "database";
|
|
17
|
-
attributes: {
|
|
18
|
-
id: number;
|
|
19
|
-
name: string;
|
|
20
|
-
remote: string;
|
|
21
|
-
username: string;
|
|
22
|
-
password: string;
|
|
23
|
-
relationships: DatabaseRelationship[];
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export interface GetDatabasesResponse {
|
|
27
|
-
object: "list";
|
|
28
|
-
data: Database[];
|
|
29
|
-
meta: {
|
|
30
|
-
pagination: PaginationData;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Handles Creating, Listing, Updating, and Deleting of Databases for the Server
|
|
36
|
-
*
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
export class DatabasesAPI {
|
|
40
|
-
constructor(private core: WispAPICore) {}
|
|
41
|
-
|
|
42
|
-
// TODO: Handle Pagination
|
|
43
|
-
/**
|
|
44
|
-
* Lists all Databases associated with the Server
|
|
45
|
-
*
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
async List(): Promise<GetDatabasesResponse> {
|
|
49
|
-
const response = await this.core.makeRequest("GET", "databases", { include: "hosts" });
|
|
50
|
-
const data: GetDatabasesResponse = await response.json();
|
|
51
|
-
|
|
52
|
-
return data;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// TODO: verify response
|
|
57
|
-
/**
|
|
58
|
-
* Deletes the Database from the Server
|
|
59
|
-
*
|
|
60
|
-
* @param id The ID of the Backup
|
|
61
|
-
*
|
|
62
|
-
* @public
|
|
63
|
-
*/
|
|
64
|
-
async Delete(id: string): Promise<Response> {
|
|
65
|
-
return await this.core.makeRequest("DELETE", `databases/${id}`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// TODO: Verify response
|
|
70
|
-
/**
|
|
71
|
-
* Rotates the password for the Backup
|
|
72
|
-
*
|
|
73
|
-
* @param id The ID of the Backup
|
|
74
|
-
*
|
|
75
|
-
* @public
|
|
76
|
-
*/
|
|
77
|
-
async RotatePassword(id: string): Promise<Response> {
|
|
78
|
-
return await this.core.makeRequest("POST", `databases/${id}`);
|
|
79
|
-
}
|
|
80
|
-
}
|