erlc-api 2.3.3 → 3.0.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.
Files changed (62) hide show
  1. package/.gitattributes +2 -0
  2. package/README.md +381 -87
  3. package/index.js +1 -0
  4. package/package.json +18 -46
  5. package/src/classes/client.js +36 -0
  6. package/src/constants.js +2 -0
  7. package/src/erlc.js +15 -0
  8. package/src/functions/assert.js +5 -0
  9. package/src/functions/server/getBans.js +54 -0
  10. package/src/functions/server/getCommandLogs.js +54 -0
  11. package/src/functions/server/getJoinLogs.js +54 -0
  12. package/src/functions/server/getKillLogs.js +54 -0
  13. package/src/functions/server/getModcallLogs.js +54 -0
  14. package/src/functions/server/getPlayers.js +54 -0
  15. package/src/functions/server/getQueue.js +54 -0
  16. package/src/functions/server/getServer.js +78 -0
  17. package/src/functions/server/getStaff.js +54 -0
  18. package/src/functions/server/getVehicles.js +54 -0
  19. package/src/functions/server/runCommand.js +70 -0
  20. package/src/types/custom.d.ts +5 -0
  21. package/src/types/index.d.ts +98 -0
  22. package/dist/browser/erlc.min.js +0 -1
  23. package/dist/cjs/client.d.ts +0 -25
  24. package/dist/cjs/client.d.ts.map +0 -1
  25. package/dist/cjs/client.js +0 -152
  26. package/dist/cjs/client.js.map +0 -1
  27. package/dist/cjs/errors/index.d.ts +0 -13
  28. package/dist/cjs/errors/index.d.ts.map +0 -1
  29. package/dist/cjs/errors/index.js +0 -32
  30. package/dist/cjs/errors/index.js.map +0 -1
  31. package/dist/cjs/index.d.ts +0 -4
  32. package/dist/cjs/index.d.ts.map +0 -1
  33. package/dist/cjs/index.js +0 -20
  34. package/dist/cjs/index.js.map +0 -1
  35. package/dist/cjs/types/index.d.ts +0 -46
  36. package/dist/cjs/types/index.d.ts.map +0 -1
  37. package/dist/cjs/types/index.js +0 -3
  38. package/dist/cjs/types/index.js.map +0 -1
  39. package/dist/esm/client.d.ts +0 -25
  40. package/dist/esm/client.d.ts.map +0 -1
  41. package/dist/esm/client.js +0 -145
  42. package/dist/esm/client.js.map +0 -1
  43. package/dist/esm/errors/index.d.ts +0 -13
  44. package/dist/esm/errors/index.d.ts.map +0 -1
  45. package/dist/esm/errors/index.js +0 -25
  46. package/dist/esm/errors/index.js.map +0 -1
  47. package/dist/esm/index.d.ts +0 -4
  48. package/dist/esm/index.d.ts.map +0 -1
  49. package/dist/esm/index.js +0 -4
  50. package/dist/esm/index.js.map +0 -1
  51. package/dist/esm/types/index.d.ts +0 -46
  52. package/dist/esm/types/index.d.ts.map +0 -1
  53. package/dist/esm/types/index.js +0 -2
  54. package/dist/esm/types/index.js.map +0 -1
  55. package/dist/types/client.d.ts +0 -25
  56. package/dist/types/client.d.ts.map +0 -1
  57. package/dist/types/errors/index.d.ts +0 -13
  58. package/dist/types/errors/index.d.ts.map +0 -1
  59. package/dist/types/index.d.ts +0 -4
  60. package/dist/types/index.d.ts.map +0 -1
  61. package/dist/types/types/index.d.ts +0 -46
  62. package/dist/types/types/index.d.ts.map +0 -1
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves the list of banned players from a server
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Object>} Promise that resolves to banned players object
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/bans`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(data || {});
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves command logs from a server
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of command logs
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/commandlogs`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves join/leave logs from a server
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of join logs
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/joinlogs`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves kill logs from a server
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of kill logs
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/killlogs`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves moderator call logs from a server
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of modcall logs
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/modcalls`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves current players from a server
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of current players
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/players`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves server queue information
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of queued player IDs
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/queue`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,78 @@
1
+ const { BASEURL, Vanity } = require("../../constants.js");
2
+
3
+ module.exports = (serverToken) => {
4
+ return new Promise(async (resolve, reject) => {
5
+ try {
6
+ const fetch = await import("node-fetch");
7
+ const { config } = await import("../../erlc.js");
8
+
9
+ const res = await fetch.default(`${BASEURL}/server`, {
10
+ headers: {
11
+ "Authorization": config?.globalToken,
12
+ "Server-Key": serverToken,
13
+ },
14
+ });
15
+
16
+ const data = await res.json().catch((err) => {
17
+ return reject(err);
18
+ });
19
+
20
+ if (!res.ok) {
21
+ return reject(data);
22
+ }
23
+
24
+ const getUsername = async (userId) => {
25
+ try {
26
+ const response = await fetch.default(`https://users.roblox.com/v1/users/${userId}`);
27
+ const userData = await response.json();
28
+ if (!response.ok) {
29
+ console.warn(`Warning: Could not fetch username for ID: ${userId}`);
30
+ return `User:${userId}`; // Fallback format
31
+ }
32
+ return userData.name;
33
+ } catch (error) {
34
+ console.warn(`Warning: Error fetching username for ID: ${userId}`, error);
35
+ return `User:${userId}`; // Fallback format
36
+ }
37
+ };
38
+
39
+ try {
40
+ // Get owner username
41
+ const ownerUsername = await getUsername(data.OwnerId);
42
+
43
+ // Get co-owner usernames (handle empty array case)
44
+ const coOwnerUsernames = data.CoOwnerIds && data.CoOwnerIds.length > 0
45
+ ? await Promise.all(data.CoOwnerIds.map(getUsername))
46
+ : [];
47
+
48
+ // Create vanity URL
49
+ const vanityURL = `${Vanity}${data.JoinKey}`;
50
+
51
+ // Add the new properties to the response
52
+ const enhancedData = {
53
+ ...data,
54
+ OwnerUsername: ownerUsername,
55
+ CoOwnerUsernames: coOwnerUsernames,
56
+ VanityURL: vanityURL
57
+ };
58
+
59
+ // Remove the original ID properties as they're now converted to usernames
60
+ delete enhancedData.OwnerId;
61
+ delete enhancedData.CoOwnerIds;
62
+
63
+ resolve(enhancedData);
64
+ } catch (error) {
65
+ // If username fetching fails, still return the original data with IDs
66
+ console.warn('Warning: Could not fetch usernames, returning data with IDs:', error);
67
+ const fallbackData = {
68
+ ...data,
69
+ VanityURL: `${Vanity}${data.JoinKey}`
70
+ };
71
+ resolve(fallbackData);
72
+ }
73
+
74
+ } catch (error) {
75
+ reject(error);
76
+ }
77
+ });
78
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves server staff information
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Object>} Promise that resolves to server staff object
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/staff`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(data || { CoOwners: [], Admins: {}, Mods: {} });
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,54 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Retrieves server vehicles information
5
+ * @param {string} serverToken - The server API key
6
+ * @returns {Promise<Array>} Promise that resolves to array of vehicles
7
+ */
8
+ module.exports = (serverToken) => {
9
+ return new Promise(async (resolve, reject) => {
10
+ // Input validation
11
+ if (!serverToken || typeof serverToken !== 'string') {
12
+ return reject(new Error('Server token is required and must be a string'));
13
+ }
14
+
15
+ try {
16
+ const fetch = await import("node-fetch");
17
+ const { config } = await import("../../erlc.js");
18
+
19
+ // Check if global token is configured
20
+ if (!config?.globalToken) {
21
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
22
+ }
23
+
24
+ const res = await fetch.default(`${BASEURL}/server/vehicles`, {
25
+ headers: {
26
+ "Authorization": config.globalToken,
27
+ "Server-Key": serverToken,
28
+ },
29
+ timeout: 10000, // 10 second timeout
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
34
+ const error = new Error(`API Error: ${res.status} - ${errorData.error || res.statusText}`);
35
+ error.status = res.status;
36
+ error.data = errorData;
37
+ return reject(error);
38
+ }
39
+
40
+ const data = await res.json();
41
+ resolve(Array.isArray(data) ? data : []);
42
+
43
+ } catch (error) {
44
+ // Handle different types of errors
45
+ if (error.code === 'ENOTFOUND') {
46
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
47
+ } else if (error.name === 'AbortError') {
48
+ reject(new Error('Request timeout: API took too long to respond'));
49
+ } else {
50
+ reject(error);
51
+ }
52
+ }
53
+ });
54
+ };
@@ -0,0 +1,70 @@
1
+ const { BASEURL } = require("../../constants.js");
2
+
3
+ /**
4
+ * Executes a command on the server
5
+ * @param {string} serverToken - The server API key
6
+ * @param {string} command - The command to execute
7
+ * @returns {Promise<boolean>} Promise that resolves to true if command was executed successfully
8
+ */
9
+ module.exports = (serverToken, command) => {
10
+ return new Promise(async (resolve, reject) => {
11
+ // Input validation
12
+ if (!serverToken || typeof serverToken !== 'string') {
13
+ return reject(new Error('Server token is required and must be a string'));
14
+ }
15
+
16
+ if (!command || typeof command !== 'string') {
17
+ return reject(new Error('Command is required and must be a string'));
18
+ }
19
+
20
+ if (command.trim().length === 0) {
21
+ return reject(new Error('Command cannot be empty'));
22
+ }
23
+
24
+ try {
25
+ const fetch = await import("node-fetch");
26
+ const { config } = await import("../../erlc.js");
27
+
28
+ // Check if global token is configured
29
+ if (!config?.globalToken) {
30
+ return reject(new Error('Global token not configured. Please initialize the client first.'));
31
+ }
32
+
33
+ const requestBody = JSON.stringify({ command: command.trim() });
34
+
35
+ const res = await fetch.default(`${BASEURL}/server/command`, {
36
+ method: "POST",
37
+ headers: {
38
+ "Authorization": config.globalToken,
39
+ "Server-Key": serverToken,
40
+ "Content-Type": "application/json",
41
+ },
42
+ body: requestBody,
43
+ timeout: 15000, // 15 second timeout for commands
44
+ });
45
+
46
+ if (!res.ok) {
47
+ const errorData = await res.json().catch(() => ({ error: 'Unknown API error' }));
48
+ const error = new Error(`Command execution failed: ${res.status} - ${errorData.error || res.statusText}`);
49
+ error.status = res.status;
50
+ error.data = errorData;
51
+ return reject(error);
52
+ }
53
+
54
+ // Command executed successfully
55
+ resolve(true);
56
+
57
+ } catch (error) {
58
+ // Handle different types of errors
59
+ if (error.code === 'ENOTFOUND') {
60
+ reject(new Error('Network error: Unable to connect to ER:LC API'));
61
+ } else if (error.name === 'AbortError') {
62
+ reject(new Error('Request timeout: Command took too long to execute'));
63
+ } else if (error.message.includes('JSON')) {
64
+ reject(new Error('Invalid command format'));
65
+ } else {
66
+ reject(error);
67
+ }
68
+ }
69
+ });
70
+ };
@@ -0,0 +1,5 @@
1
+ declare module 'NodeModule' {
2
+ interface NodeModule {
3
+ type?: string;
4
+ }
5
+ }