erlc-api 3.3.1 → 3.3.2
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/README.md +16 -6
- package/README_ES.md +33 -13
- package/package.json +12 -5
- package/pnpm-workspace.yaml +2 -0
- package/src/classes/client.js +13 -2
- package/src/constants.js +4 -1
- package/src/erlc.js +29 -1
- package/src/errors/ErlcError.js +3 -0
- package/src/functions/global/resetGlobalKey.js +12 -8
- package/src/functions/server/getBans.js +11 -41
- package/src/functions/server/getCommandLogs.js +9 -41
- package/src/functions/server/getEmergencyCalls.js +15 -0
- package/src/functions/server/getJoinLogs.js +8 -41
- package/src/functions/server/getKillLogs.js +8 -41
- package/src/functions/server/getModcallLogs.js +8 -41
- package/src/functions/server/getPlayers.js +8 -41
- package/src/functions/server/getQueue.js +8 -41
- package/src/functions/server/getServer.js +50 -68
- package/src/functions/server/getStaff.js +8 -41
- package/src/functions/server/getVehicles.js +8 -41
- package/src/functions/server/requestServer.js +179 -0
- package/src/functions/server/runCommand.js +22 -53
- package/src/types/index.d.ts +91 -5
- package/src/utils/cache.js +63 -0
- package/src/utils/discord.js +99 -0
- package/src/utils/errorHandler.js +22 -1
- package/tests/cache.test.js +46 -0
|
@@ -1,47 +1,14 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { processError } = require("../../utils/errorHandler.js");
|
|
1
|
+
const { requestServer } = require("./requestServer.js");
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* Retrieves current players from a server
|
|
4
|
+
* Retrieves current players from a server.
|
|
6
5
|
* @param {string} serverToken - The server API key
|
|
7
6
|
* @returns {Promise<Array>} Promise that resolves to array of current players
|
|
8
7
|
*/
|
|
9
|
-
module.exports = (serverToken) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const fetch = await import("node-fetch");
|
|
18
|
-
const { config } = await import("../../erlc.js");
|
|
19
|
-
|
|
20
|
-
const headers = {
|
|
21
|
-
"Server-Key": serverToken,
|
|
22
|
-
};
|
|
23
|
-
if (config?.globalToken) {
|
|
24
|
-
headers["Authorization"] = config.globalToken;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const res = await fetch.default(`${BASEURL}/server/players`, {
|
|
28
|
-
headers: headers,
|
|
29
|
-
timeout: 10000, // 10 second timeout
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (!res.ok) {
|
|
33
|
-
const errorData = await res
|
|
34
|
-
.json()
|
|
35
|
-
.catch(() => ({ error: "Unknown API error" }));
|
|
36
|
-
const error = await processError(res, errorData);
|
|
37
|
-
return reject(error);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const data = await res.json();
|
|
41
|
-
resolve(Array.isArray(data) ? data : []);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
const processedError = await processError(error);
|
|
44
|
-
reject(processedError);
|
|
45
|
-
}
|
|
8
|
+
module.exports = (serverToken) =>
|
|
9
|
+
requestServer(serverToken, {
|
|
10
|
+
endpoint: "players",
|
|
11
|
+
includes: ["Players"],
|
|
12
|
+
defaultValue: [],
|
|
13
|
+
transform: (data) => (Array.isArray(data?.Players) ? data.Players : []),
|
|
46
14
|
});
|
|
47
|
-
};
|
|
@@ -1,47 +1,14 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { processError } = require("../../utils/errorHandler.js");
|
|
1
|
+
const { requestServer } = require("./requestServer.js");
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* Retrieves server queue information
|
|
4
|
+
* Retrieves server queue information.
|
|
6
5
|
* @param {string} serverToken - The server API key
|
|
7
6
|
* @returns {Promise<Array>} Promise that resolves to array of queued player IDs
|
|
8
7
|
*/
|
|
9
|
-
module.exports = (serverToken) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const fetch = await import("node-fetch");
|
|
18
|
-
const { config } = await import("../../erlc.js");
|
|
19
|
-
|
|
20
|
-
const headers = {
|
|
21
|
-
"Server-Key": serverToken,
|
|
22
|
-
};
|
|
23
|
-
if (config?.globalToken) {
|
|
24
|
-
headers["Authorization"] = config.globalToken;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const res = await fetch.default(`${BASEURL}/server/queue`, {
|
|
28
|
-
headers: headers,
|
|
29
|
-
timeout: 10000, // 10 second timeout
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (!res.ok) {
|
|
33
|
-
const errorData = await res
|
|
34
|
-
.json()
|
|
35
|
-
.catch(() => ({ error: "Unknown API error" }));
|
|
36
|
-
const error = await processError(res, errorData);
|
|
37
|
-
return reject(error);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const data = await res.json();
|
|
41
|
-
resolve(Array.isArray(data) ? data : []);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
const processedError = await processError(error);
|
|
44
|
-
reject(processedError);
|
|
45
|
-
}
|
|
8
|
+
module.exports = (serverToken) =>
|
|
9
|
+
requestServer(serverToken, {
|
|
10
|
+
endpoint: "queue",
|
|
11
|
+
includes: ["Queue"],
|
|
12
|
+
defaultValue: [],
|
|
13
|
+
transform: (data) => (Array.isArray(data?.Queue) ? data.Queue : []),
|
|
46
14
|
});
|
|
47
|
-
};
|
|
@@ -1,100 +1,82 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const {
|
|
1
|
+
const { Vanity } = require("../../constants.js");
|
|
2
|
+
const { requestServer } = require("./requestServer.js");
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
async function getUsername(fetch, userId) {
|
|
5
|
+
try {
|
|
6
|
+
const response = await fetch(`https://users.roblox.com/v1/users/${userId}`);
|
|
7
|
+
const userData = await response.json();
|
|
8
|
+
|
|
9
|
+
if (!response.ok) {
|
|
10
|
+
console.warn(`Warning: Could not fetch username for ID: ${userId}`);
|
|
11
|
+
return `User:${userId}`;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
return userData.name;
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.warn(`Warning: Error fetching username for ID: ${userId}`, error);
|
|
17
|
+
return `User:${userId}`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
function normalizeIncludes(options = {}) {
|
|
22
|
+
const includeMap = {
|
|
23
|
+
players: "Players",
|
|
24
|
+
staff: "Staff",
|
|
25
|
+
joinLogs: "JoinLogs",
|
|
26
|
+
queue: "Queue",
|
|
27
|
+
killLogs: "KillLogs",
|
|
28
|
+
commandLogs: "CommandLogs",
|
|
29
|
+
modCalls: "ModCalls",
|
|
30
|
+
emergencyCalls: "EmergencyCalls",
|
|
31
|
+
vehicles: "Vehicles",
|
|
32
|
+
};
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
return Object.entries(includeMap)
|
|
35
|
+
.filter(([option]) => options[option])
|
|
36
|
+
.map(([, include]) => include);
|
|
37
|
+
}
|
|
26
38
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
.json()
|
|
30
|
-
.catch(() => ({ error: "Unknown API error" }));
|
|
31
|
-
const error = await processError(res, errorData);
|
|
32
|
-
return reject(error);
|
|
33
|
-
}
|
|
39
|
+
module.exports = (serverToken, options = {}) => {
|
|
40
|
+
const includes = normalizeIncludes(options);
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!response.ok) {
|
|
44
|
-
console.warn(`Warning: Could not fetch username for ID: ${userId}`);
|
|
45
|
-
return `User:${userId}`; // Fallback format
|
|
46
|
-
}
|
|
47
|
-
return userData.name;
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.warn(
|
|
50
|
-
`Warning: Error fetching username for ID: ${userId}`,
|
|
51
|
-
error
|
|
52
|
-
);
|
|
53
|
-
return `User:${userId}`; // Fallback format
|
|
54
|
-
}
|
|
55
|
-
};
|
|
42
|
+
return requestServer(serverToken, {
|
|
43
|
+
endpoint: "server",
|
|
44
|
+
includes,
|
|
45
|
+
transform: async (data) => {
|
|
46
|
+
const fetch =
|
|
47
|
+
typeof globalThis.fetch === "function"
|
|
48
|
+
? globalThis.fetch
|
|
49
|
+
: (await import("node-fetch")).default;
|
|
56
50
|
|
|
57
51
|
try {
|
|
58
|
-
|
|
59
|
-
const ownerUsername = await getUsername(data.OwnerId);
|
|
60
|
-
|
|
61
|
-
// Get co-owner usernames (handle empty array case)
|
|
52
|
+
const ownerUsername = await getUsername(fetch, data.OwnerId);
|
|
62
53
|
const coOwnerUsernames =
|
|
63
54
|
data.CoOwnerIds && data.CoOwnerIds.length > 0
|
|
64
|
-
? await Promise.all(data.CoOwnerIds.map(getUsername))
|
|
55
|
+
? await Promise.all(data.CoOwnerIds.map((id) => getUsername(fetch, id)))
|
|
65
56
|
: [];
|
|
66
57
|
|
|
67
|
-
// Create vanity URL
|
|
68
|
-
const vanityURL = `${Vanity}${data.JoinKey}`;
|
|
69
|
-
|
|
70
|
-
// Add the new properties to the response
|
|
71
58
|
const enhancedData = {
|
|
72
59
|
...data,
|
|
73
60
|
OwnerUsername: ownerUsername,
|
|
74
61
|
CoOwnerUsernames: coOwnerUsernames,
|
|
75
|
-
VanityURL:
|
|
62
|
+
VanityURL: `${Vanity}${data.JoinKey}`,
|
|
76
63
|
};
|
|
77
64
|
|
|
78
|
-
// Remove the original ID properties as they're now converted to usernames
|
|
79
65
|
delete enhancedData.OwnerId;
|
|
80
66
|
delete enhancedData.CoOwnerIds;
|
|
81
67
|
|
|
82
|
-
|
|
68
|
+
return enhancedData;
|
|
83
69
|
} catch (error) {
|
|
84
|
-
// If username fetching fails, still return the original data with IDs
|
|
85
70
|
console.warn(
|
|
86
71
|
"Warning: Could not fetch usernames, returning data with IDs:",
|
|
87
|
-
error
|
|
72
|
+
error,
|
|
88
73
|
);
|
|
89
|
-
|
|
74
|
+
|
|
75
|
+
return {
|
|
90
76
|
...data,
|
|
91
77
|
VanityURL: `${Vanity}${data.JoinKey}`,
|
|
92
78
|
};
|
|
93
|
-
resolve(fallbackData);
|
|
94
79
|
}
|
|
95
|
-
}
|
|
96
|
-
const processedError = await processError(error);
|
|
97
|
-
reject(processedError);
|
|
98
|
-
}
|
|
80
|
+
},
|
|
99
81
|
});
|
|
100
82
|
};
|
|
@@ -1,47 +1,14 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { processError } = require("../../utils/errorHandler.js");
|
|
1
|
+
const { requestServer } = require("./requestServer.js");
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* Retrieves server staff information
|
|
4
|
+
* Retrieves server staff information.
|
|
6
5
|
* @param {string} serverToken - The server API key
|
|
7
6
|
* @returns {Promise<Object>} Promise that resolves to server staff object
|
|
8
7
|
*/
|
|
9
|
-
module.exports = (serverToken) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const fetch = await import("node-fetch");
|
|
18
|
-
const { config } = await import("../../erlc.js");
|
|
19
|
-
|
|
20
|
-
const headers = {
|
|
21
|
-
"Server-Key": serverToken,
|
|
22
|
-
};
|
|
23
|
-
if (config?.globalToken) {
|
|
24
|
-
headers["Authorization"] = config.globalToken;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const res = await fetch.default(`${BASEURL}/server/staff`, {
|
|
28
|
-
headers: headers,
|
|
29
|
-
timeout: 10000, // 10 second timeout
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (!res.ok) {
|
|
33
|
-
const errorData = await res
|
|
34
|
-
.json()
|
|
35
|
-
.catch(() => ({ error: "Unknown API error" }));
|
|
36
|
-
const error = await processError(res, errorData);
|
|
37
|
-
return reject(error);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const data = await res.json();
|
|
41
|
-
resolve(data || { CoOwners: [], Admins: {}, Mods: {} });
|
|
42
|
-
} catch (error) {
|
|
43
|
-
const processedError = await processError(error);
|
|
44
|
-
reject(processedError);
|
|
45
|
-
}
|
|
8
|
+
module.exports = (serverToken) =>
|
|
9
|
+
requestServer(serverToken, {
|
|
10
|
+
endpoint: "staff",
|
|
11
|
+
includes: ["Staff"],
|
|
12
|
+
defaultValue: { Admins: {}, Mods: {}, Helpers: {} },
|
|
13
|
+
transform: (data) => data?.Staff || { Admins: {}, Mods: {}, Helpers: {} },
|
|
46
14
|
});
|
|
47
|
-
};
|
|
@@ -1,47 +1,14 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { processError } = require("../../utils/errorHandler.js");
|
|
1
|
+
const { requestServer } = require("./requestServer.js");
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* Retrieves server vehicles information
|
|
4
|
+
* Retrieves server vehicles information.
|
|
6
5
|
* @param {string} serverToken - The server API key
|
|
7
6
|
* @returns {Promise<Array>} Promise that resolves to array of vehicles
|
|
8
7
|
*/
|
|
9
|
-
module.exports = (serverToken) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const fetch = await import("node-fetch");
|
|
18
|
-
const { config } = await import("../../erlc.js");
|
|
19
|
-
|
|
20
|
-
const headers = {
|
|
21
|
-
"Server-Key": serverToken,
|
|
22
|
-
};
|
|
23
|
-
if (config?.globalToken) {
|
|
24
|
-
headers["Authorization"] = config.globalToken;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const res = await fetch.default(`${BASEURL}/server/vehicles`, {
|
|
28
|
-
headers: headers,
|
|
29
|
-
timeout: 10000, // 10 second timeout
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (!res.ok) {
|
|
33
|
-
const errorData = await res
|
|
34
|
-
.json()
|
|
35
|
-
.catch(() => ({ error: "Unknown API error" }));
|
|
36
|
-
const error = await processError(res, errorData);
|
|
37
|
-
return reject(error);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const data = await res.json();
|
|
41
|
-
resolve(Array.isArray(data) ? data : []);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
const processedError = await processError(error);
|
|
44
|
-
reject(processedError);
|
|
45
|
-
}
|
|
8
|
+
module.exports = (serverToken) =>
|
|
9
|
+
requestServer(serverToken, {
|
|
10
|
+
endpoint: "vehicles",
|
|
11
|
+
includes: ["Vehicles"],
|
|
12
|
+
defaultValue: [],
|
|
13
|
+
transform: (data) => (Array.isArray(data?.Vehicles) ? data.Vehicles : []),
|
|
46
14
|
});
|
|
47
|
-
};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
const { BASEURL, LEGACY_BASEURL } = require("../../constants.js");
|
|
2
|
+
const { processError } = require("../../utils/errorHandler.js");
|
|
3
|
+
const cache = require("../../utils/cache.js");
|
|
4
|
+
|
|
5
|
+
function assertServerToken(serverToken) {
|
|
6
|
+
if (!serverToken || typeof serverToken !== "string") {
|
|
7
|
+
throw new Error("Server token is required and must be a string");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function buildHeaders(serverToken, config, extraHeaders = {}) {
|
|
12
|
+
const headers = {
|
|
13
|
+
"Server-Key": serverToken,
|
|
14
|
+
...extraHeaders,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
if (config?.globalToken) {
|
|
18
|
+
headers["Authorization"] = config.globalToken;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return headers;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function getFetch() {
|
|
25
|
+
const { config } = require("../../erlc.js");
|
|
26
|
+
|
|
27
|
+
if (config?.fetch) {
|
|
28
|
+
return {
|
|
29
|
+
fetch: config.fetch,
|
|
30
|
+
config,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (typeof globalThis.fetch === "function") {
|
|
35
|
+
return {
|
|
36
|
+
fetch: globalThis.fetch,
|
|
37
|
+
config,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const fetch = await import("node-fetch");
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
fetch: fetch.default,
|
|
45
|
+
config,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function readError(res) {
|
|
50
|
+
return res.json().catch(() => ({ error: "Unknown API error" }));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function buildServerUrl(includes = []) {
|
|
54
|
+
const url = new URL(`${BASEURL}/server`);
|
|
55
|
+
|
|
56
|
+
for (const include of includes) {
|
|
57
|
+
url.searchParams.set(include, "true");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return url.toString();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function requestJson(url, options) {
|
|
64
|
+
const res = await options.fetch(url, options.init);
|
|
65
|
+
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
const errorData = await readError(res);
|
|
68
|
+
throw await processError(res, errorData);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return res.json();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function requestServer(serverToken, options = {}) {
|
|
75
|
+
assertServerToken(serverToken);
|
|
76
|
+
|
|
77
|
+
const {
|
|
78
|
+
endpoint = "server",
|
|
79
|
+
includes = [],
|
|
80
|
+
defaultValue = {},
|
|
81
|
+
transform = (data) => data,
|
|
82
|
+
} = options;
|
|
83
|
+
|
|
84
|
+
const { fetch, config } = await getFetch();
|
|
85
|
+
const useCache = !!config?.cache?.enabled;
|
|
86
|
+
const cacheExtras = includes.length ? includes.join(",") : "";
|
|
87
|
+
const key = cache.makeKey(endpoint, serverToken, cacheExtras);
|
|
88
|
+
|
|
89
|
+
if (useCache) {
|
|
90
|
+
const cached = cache.get(key);
|
|
91
|
+
if (cached) {
|
|
92
|
+
return cached;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const data = await requestJson(buildServerUrl(includes), {
|
|
97
|
+
fetch,
|
|
98
|
+
init: {
|
|
99
|
+
headers: buildHeaders(serverToken, config),
|
|
100
|
+
timeout: 10000,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const value = (await transform(data)) ?? defaultValue;
|
|
105
|
+
|
|
106
|
+
if (useCache) {
|
|
107
|
+
const ttlMs = cache.getTTL(endpoint, config);
|
|
108
|
+
cache.set(key, value, ttlMs);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function requestApi(serverToken, path, options = {}) {
|
|
115
|
+
assertServerToken(serverToken);
|
|
116
|
+
|
|
117
|
+
const {
|
|
118
|
+
baseUrl = BASEURL,
|
|
119
|
+
method = "GET",
|
|
120
|
+
endpoint = path,
|
|
121
|
+
body,
|
|
122
|
+
defaultValue = {},
|
|
123
|
+
transform = (data) => data,
|
|
124
|
+
timeout = 10000,
|
|
125
|
+
useCache = true,
|
|
126
|
+
} = options;
|
|
127
|
+
|
|
128
|
+
const { fetch, config } = await getFetch();
|
|
129
|
+
const shouldCache = method === "GET" && useCache && !!config?.cache?.enabled;
|
|
130
|
+
const key = cache.makeKey(endpoint, serverToken);
|
|
131
|
+
|
|
132
|
+
if (shouldCache) {
|
|
133
|
+
const cached = cache.get(key);
|
|
134
|
+
if (cached) {
|
|
135
|
+
return cached;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const headers = buildHeaders(
|
|
140
|
+
serverToken,
|
|
141
|
+
config,
|
|
142
|
+
body ? { "Content-Type": "application/json" } : {},
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const data = await requestJson(`${baseUrl}${path}`, {
|
|
146
|
+
fetch,
|
|
147
|
+
init: {
|
|
148
|
+
method,
|
|
149
|
+
headers,
|
|
150
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
151
|
+
timeout,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const value = (await transform(data)) ?? defaultValue;
|
|
156
|
+
|
|
157
|
+
if (shouldCache) {
|
|
158
|
+
const ttlMs = cache.getTTL(endpoint, config);
|
|
159
|
+
cache.set(key, value, ttlMs);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function requestLegacyServer(serverToken, path, options = {}) {
|
|
166
|
+
return requestApi(serverToken, path, {
|
|
167
|
+
...options,
|
|
168
|
+
baseUrl: LEGACY_BASEURL,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = {
|
|
173
|
+
assertServerToken,
|
|
174
|
+
buildHeaders,
|
|
175
|
+
getFetch,
|
|
176
|
+
requestServer,
|
|
177
|
+
requestApi,
|
|
178
|
+
requestLegacyServer,
|
|
179
|
+
};
|
|
@@ -1,61 +1,30 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { processError } = require("../../utils/errorHandler.js");
|
|
1
|
+
const { assertServerToken, requestApi } = require("./requestServer.js");
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* Executes a command on the server
|
|
4
|
+
* Executes a command on the server.
|
|
6
5
|
* @param {string} serverToken - The server API key
|
|
7
6
|
* @param {string} command - The command to execute
|
|
8
7
|
* @returns {Promise<boolean>} Promise that resolves to true if command was executed successfully
|
|
9
8
|
*/
|
|
10
|
-
module.exports = (serverToken, command) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const requestBody = JSON.stringify({ command: command.trim() });
|
|
30
|
-
|
|
31
|
-
const headers = {
|
|
32
|
-
"Server-Key": serverToken,
|
|
33
|
-
"Content-Type": "application/json",
|
|
34
|
-
};
|
|
35
|
-
if (config?.globalToken) {
|
|
36
|
-
headers["Authorization"] = config.globalToken;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const res = await fetch.default(`${BASEURL}/server/command`, {
|
|
40
|
-
method: "POST",
|
|
41
|
-
headers: headers,
|
|
42
|
-
body: requestBody,
|
|
43
|
-
timeout: 15000, // 15 second timeout for commands
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
if (!res.ok) {
|
|
47
|
-
const errorData = await res
|
|
48
|
-
.json()
|
|
49
|
-
.catch(() => ({ error: "Unknown API error" }));
|
|
50
|
-
const error = await processError(res, errorData);
|
|
51
|
-
return reject(error);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Command executed successfully
|
|
55
|
-
resolve(true);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
const processedError = await processError(error);
|
|
58
|
-
reject(processedError);
|
|
59
|
-
}
|
|
9
|
+
module.exports = async (serverToken, command) => {
|
|
10
|
+
assertServerToken(serverToken);
|
|
11
|
+
|
|
12
|
+
if (!command || typeof command !== "string") {
|
|
13
|
+
throw new Error("Command is required and must be a string");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const trimmedCommand = command.trim();
|
|
17
|
+
if (trimmedCommand.length === 0) {
|
|
18
|
+
throw new Error("Command cannot be empty");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await requestApi(serverToken, "/server/command", {
|
|
22
|
+
method: "POST",
|
|
23
|
+
endpoint: "command",
|
|
24
|
+
body: { command: trimmedCommand },
|
|
25
|
+
timeout: 15000,
|
|
26
|
+
useCache: false,
|
|
60
27
|
});
|
|
28
|
+
|
|
29
|
+
return true;
|
|
61
30
|
};
|