erlc-api 3.2.0 → 3.3.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/README.md +81 -432
- package/package.json +1 -1
- package/src/classes/client.js +6 -6
- package/src/functions/global/resetGlobalKey.js +4 -4
- package/src/functions/server/getBans.js +6 -12
- package/src/functions/server/getCommandLogs.js +6 -12
- package/src/functions/server/getJoinLogs.js +6 -12
- package/src/functions/server/getKillLogs.js +6 -12
- package/src/functions/server/getModcallLogs.js +6 -12
- package/src/functions/server/getPlayers.js +6 -12
- package/src/functions/server/getQueue.js +6 -12
- package/src/functions/server/getServer.js +6 -11
- package/src/functions/server/getStaff.js +6 -12
- package/src/functions/server/getVehicles.js +6 -12
- package/src/functions/server/runCommand.js +9 -15
- package/src/types/index.d.ts +1 -1
package/README.md
CHANGED
|
@@ -1,497 +1,146 @@
|
|
|
1
1
|
# 🚔 ER:LC API Wrapper
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/erlc-api)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.npmjs.com/package/erlc-api)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Una librería ligera, completa y **totalmente tipada** para interactuar con la API de *Emergency Response: Liberty County* (ER:LC). Diseñada para ofrecer la mejor experiencia de desarrollo tanto en JavaScript como en TypeScript.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
---
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
- 🛡️ **Robust Error Handling** - Comprehensive error catching and meaningful error messages
|
|
12
|
-
- 📝 **Full TypeScript Support** - Complete type definitions for all methods and responses
|
|
13
|
-
- ⚡ **Optimized Performance** - Efficient request handling with timeout management
|
|
14
|
-
- 🔒 **Secure** - Built-in validation and secure token handling
|
|
15
|
-
- 📚 **Well Documented** - Extensive documentation and examples
|
|
16
|
-
- 🚀 **Easy to Use** - Simple, intuitive API design
|
|
11
|
+
## ✨ Características
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
- 🎯 **Cobertura Total**: Soporte para el 100% de los endpoints de la API v1.
|
|
14
|
+
- 🛡️ **Tipado TypeScript**: Definiciones de tipos incluidas nativamente.
|
|
15
|
+
- ⚡ **Ligero y Rápido**: Sin dependencias pesadas innecesarias.
|
|
16
|
+
- 🔒 **Seguro**: Validación de tokens y manejo de errores robusto.
|
|
17
|
+
- 🆕 **Actualizado**: Soporte para `GlobalToken` opcional (v3.2.0+).
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
npm install erlc-api
|
|
22
|
-
```
|
|
19
|
+
## 📦 Instalación
|
|
23
20
|
|
|
24
21
|
```bash
|
|
22
|
+
npm install erlc-api
|
|
23
|
+
# o
|
|
25
24
|
bun add erlc-api
|
|
26
25
|
```
|
|
27
26
|
|
|
28
|
-
## 🚀
|
|
27
|
+
## 🚀 Inicio Rápido
|
|
29
28
|
|
|
30
|
-
###
|
|
29
|
+
### Inicialización
|
|
31
30
|
|
|
31
|
+
Puedes usar la librería con o sin un `Global Token` (requerido solo para aplicaciones a gran escala).
|
|
32
|
+
|
|
33
|
+
**JavaScript**
|
|
32
34
|
```javascript
|
|
33
35
|
const erlc = require("erlc-api");
|
|
34
36
|
|
|
35
|
-
//
|
|
36
|
-
const client = new erlc.Client(
|
|
37
|
-
globalToken: "your-global-token-here", // Get this from ER:LC developers
|
|
38
|
-
});
|
|
37
|
+
// Inicialización simple (Recomendada para la mayoría)
|
|
38
|
+
const client = new erlc.Client();
|
|
39
39
|
|
|
40
|
-
//
|
|
41
|
-
client.
|
|
40
|
+
// O con Global Token (Para Large Apps)
|
|
41
|
+
// const client = new erlc.Client({ globalToken: "..." });
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
**TypeScript**
|
|
46
45
|
```typescript
|
|
47
|
-
import
|
|
46
|
+
import { Client, getServer } from "erlc-api";
|
|
48
47
|
|
|
49
|
-
const client = new
|
|
50
|
-
globalToken: "your-global-token-here",
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
client.config();
|
|
48
|
+
const client = new Client();
|
|
54
49
|
```
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### 🖥️ Server Information
|
|
51
|
+
---
|
|
59
52
|
|
|
60
|
-
|
|
53
|
+
## 📖 Ejemplos de Uso
|
|
61
54
|
|
|
62
|
-
|
|
63
|
-
const getServerInfo = async () => {
|
|
64
|
-
try {
|
|
65
|
-
const serverToken = "your-server-api-key"; // From Server Settings
|
|
66
|
-
const server = await erlc.getServer(serverToken);
|
|
67
|
-
|
|
68
|
-
console.log(server);
|
|
69
|
-
/*
|
|
70
|
-
Expected Response:
|
|
71
|
-
{
|
|
72
|
-
Name: "Your Server Name",
|
|
73
|
-
OwnerUsername: "ServerOwner",
|
|
74
|
-
CoOwnerUsernames: ["CoOwner1", "CoOwner2"],
|
|
75
|
-
CurrentPlayers: 25,
|
|
76
|
-
MaxPlayers: 40,
|
|
77
|
-
JoinKey: "ABC123",
|
|
78
|
-
AccVerifiedReq: "Disabled", // "Email" | "Phone/ID"
|
|
79
|
-
TeamBalance: true,
|
|
80
|
-
VanityURL: "https://policeroleplay.community/join?code=ABC123"
|
|
81
|
-
}
|
|
82
|
-
*/
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error("Error fetching server info:", error.message);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
```
|
|
55
|
+
Asegúrate de tener tu `Server Key` a mano (obtenla en los ajustes de tu servidor privado en ER:LC).
|
|
88
56
|
|
|
89
|
-
|
|
57
|
+
### 🖥️ Información del Servidor
|
|
90
58
|
|
|
91
59
|
```javascript
|
|
92
|
-
const
|
|
93
|
-
try {
|
|
94
|
-
const players = await erlc.getPlayers(serverToken);
|
|
95
|
-
|
|
96
|
-
console.log(players);
|
|
97
|
-
/*
|
|
98
|
-
Expected Response:
|
|
99
|
-
[
|
|
100
|
-
{
|
|
101
|
-
Player: "PlayerName:123456789",
|
|
102
|
-
Permission: "Server Owner", // "Member" | "Moderator" | "Server Administrator"
|
|
103
|
-
Team: "Police" // "Civilian" | "Fire" | "Sheriff"
|
|
104
|
-
}
|
|
105
|
-
]
|
|
106
|
-
*/
|
|
107
|
-
} catch (error) {
|
|
108
|
-
console.error("Error fetching players:", error.message);
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
```
|
|
60
|
+
const serverToken = "tu-server-key-aqui";
|
|
112
61
|
|
|
113
|
-
|
|
62
|
+
// Obtener estado del servidor
|
|
63
|
+
const server = await erlc.getServer(serverToken);
|
|
64
|
+
console.log(`Servidor: ${server.Name} | Jugadores: ${server.CurrentPlayers}/${server.MaxPlayers}`);
|
|
114
65
|
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
const queue = await erlc.getQueue(serverToken);
|
|
119
|
-
console.log(`Players in queue: ${queue.length}`);
|
|
120
|
-
} catch (error) {
|
|
121
|
-
console.error("Error fetching queue:", error.message);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### 👥 Staff Management
|
|
66
|
+
// Obtener jugadores conectados
|
|
67
|
+
const players = await erlc.getPlayers(serverToken);
|
|
68
|
+
console.table(players); // Muestra nombre, ID, permisos y equipo
|
|
127
69
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```javascript
|
|
131
|
-
const getStaffInfo = async () => {
|
|
132
|
-
try {
|
|
133
|
-
const staff = await erlc.getStaff(serverToken);
|
|
134
|
-
|
|
135
|
-
console.log(staff);
|
|
136
|
-
/*
|
|
137
|
-
Expected Response:
|
|
138
|
-
{
|
|
139
|
-
CoOwners: [123456789, 987654321],
|
|
140
|
-
Admins: { "123456789": "AdminName" },
|
|
141
|
-
Mods: { "987654321": "ModName" }
|
|
142
|
-
}
|
|
143
|
-
*/
|
|
144
|
-
} catch (error) {
|
|
145
|
-
console.error("Error fetching staff:", error.message);
|
|
146
|
-
}
|
|
147
|
-
};
|
|
70
|
+
// Obtener vehículos en el mapa
|
|
71
|
+
const vehicles = await erlc.getVehicles(serverToken);
|
|
148
72
|
```
|
|
149
73
|
|
|
150
|
-
###
|
|
74
|
+
### 📜 Registros (Logs)
|
|
151
75
|
|
|
152
|
-
|
|
76
|
+
Accede a los historiales de actividad de tu servidor:
|
|
153
77
|
|
|
154
78
|
```javascript
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const logs = await erlc.getJoinLogs(serverToken);
|
|
158
|
-
|
|
159
|
-
logs.forEach((log) => {
|
|
160
|
-
const action = log.Join ? "joined" : "left";
|
|
161
|
-
console.log(
|
|
162
|
-
`${log.Player} ${action} at ${new Date(log.Timestamp * 1000)}`
|
|
163
|
-
);
|
|
164
|
-
});
|
|
165
|
-
} catch (error) {
|
|
166
|
-
console.error("Error fetching join logs:", error.message);
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
```
|
|
79
|
+
// Logs de Entradas/Salidas
|
|
80
|
+
const joinLogs = await erlc.getJoinLogs(serverToken);
|
|
170
81
|
|
|
171
|
-
|
|
82
|
+
// Logs de Muertes (Killfeed)
|
|
83
|
+
const killLogs = await erlc.getKillLogs(serverToken);
|
|
172
84
|
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
try {
|
|
176
|
-
const kills = await erlc.getKillLogs(serverToken);
|
|
177
|
-
|
|
178
|
-
kills.forEach((kill) => {
|
|
179
|
-
console.log(
|
|
180
|
-
`${kill.Killer} killed ${kill.Killed} at ${new Date(
|
|
181
|
-
kill.Timestamp * 1000
|
|
182
|
-
)}`
|
|
183
|
-
);
|
|
184
|
-
});
|
|
185
|
-
} catch (error) {
|
|
186
|
-
console.error("Error fetching kill logs:", error.message);
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
```
|
|
85
|
+
// Logs de Comandos ejecutados
|
|
86
|
+
const commandLogs = await erlc.getCommandLogs(serverToken);
|
|
190
87
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
```javascript
|
|
194
|
-
const getCommandLogs = async () => {
|
|
195
|
-
try {
|
|
196
|
-
const commands = await erlc.getCommandLogs(serverToken);
|
|
197
|
-
|
|
198
|
-
commands.forEach((cmd) => {
|
|
199
|
-
console.log(`${cmd.Player} executed: ${cmd.Command}`);
|
|
200
|
-
});
|
|
201
|
-
} catch (error) {
|
|
202
|
-
console.error("Error fetching command logs:", error.message);
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
#### Get Moderator Call Logs
|
|
208
|
-
|
|
209
|
-
```javascript
|
|
210
|
-
const getModCalls = async () => {
|
|
211
|
-
try {
|
|
212
|
-
const modcalls = await erlc.getModcallLogs(serverToken);
|
|
213
|
-
|
|
214
|
-
modcalls.forEach((call) => {
|
|
215
|
-
const status = call.Moderator
|
|
216
|
-
? `answered by ${call.Moderator}`
|
|
217
|
-
: "unanswered";
|
|
218
|
-
console.log(`${call.Caller} made a modcall - ${status}`);
|
|
219
|
-
});
|
|
220
|
-
} catch (error) {
|
|
221
|
-
console.error("Error fetching modcall logs:", error.message);
|
|
222
|
-
}
|
|
223
|
-
};
|
|
88
|
+
// Logs de Llamadas a Moderadores
|
|
89
|
+
const modCalls = await erlc.getModcallLogs(serverToken);
|
|
224
90
|
```
|
|
225
91
|
|
|
226
|
-
###
|
|
227
|
-
|
|
228
|
-
#### Get Server Vehicles
|
|
92
|
+
### 🛠️ Gestión y Administración
|
|
229
93
|
|
|
230
94
|
```javascript
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const vehicles = await erlc.getVehicles(serverToken);
|
|
234
|
-
|
|
235
|
-
vehicles.forEach((vehicle) => {
|
|
236
|
-
console.log(
|
|
237
|
-
`${vehicle.Name} owned by ${vehicle.Owner} - Texture: ${
|
|
238
|
-
vehicle.Texture || "Default"
|
|
239
|
-
}`
|
|
240
|
-
);
|
|
241
|
-
});
|
|
242
|
-
} catch (error) {
|
|
243
|
-
console.error("Error fetching vehicles:", error.message);
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
```
|
|
95
|
+
// Ver lista de Baneos
|
|
96
|
+
const bans = await erlc.getBans(serverToken);
|
|
247
97
|
|
|
248
|
-
|
|
98
|
+
// Obtener Staff del servidor
|
|
99
|
+
const staff = await erlc.getStaff(serverToken);
|
|
249
100
|
|
|
250
|
-
|
|
101
|
+
// Ejecutar comando remoto (Ej: Anuncio)
|
|
102
|
+
await erlc.runCommand(serverToken, ":h ¡Hola desde la API!");
|
|
251
103
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
try {
|
|
255
|
-
const success = await erlc.runCommand(
|
|
256
|
-
serverToken,
|
|
257
|
-
":h Welcome to our server!"
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
if (success) {
|
|
261
|
-
console.log("Command executed successfully!");
|
|
262
|
-
}
|
|
263
|
-
} catch (error) {
|
|
264
|
-
console.error("Error executing command:", error.message);
|
|
265
|
-
}
|
|
266
|
-
};
|
|
104
|
+
// Resetear Global Key (Solo si tienes una configurada)
|
|
105
|
+
// await erlc.resetGlobalKey();
|
|
267
106
|
```
|
|
268
107
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
```javascript
|
|
272
|
-
const getBannedPlayers = async () => {
|
|
273
|
-
try {
|
|
274
|
-
const bans = await erlc.getBans(serverToken);
|
|
275
|
-
|
|
276
|
-
Object.entries(bans).forEach(([playerId, playerName]) => {
|
|
277
|
-
console.log(`${playerName} (${playerId}) is banned`);
|
|
278
|
-
});
|
|
279
|
-
} catch (error) {
|
|
280
|
-
console.error("Error fetching bans:", error.message);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
## 🛠️ Advanced Usage
|
|
286
|
-
|
|
287
|
-
### Error Handling Best Practices
|
|
288
|
-
|
|
289
|
-
```javascript
|
|
290
|
-
const handleApiCall = async () => {
|
|
291
|
-
try {
|
|
292
|
-
const result = await erlc.getServer(serverToken);
|
|
293
|
-
return result;
|
|
294
|
-
} catch (error) {
|
|
295
|
-
// The error is now an ErlcError with detailed information
|
|
296
|
-
console.error(`Error ${error.code}: ${error.message}`);
|
|
297
|
-
console.error(`Category: ${error.category}, Severity: ${error.severity}`);
|
|
298
|
-
|
|
299
|
-
// Handle specific ERLC error codes
|
|
300
|
-
switch (error.code) {
|
|
301
|
-
case 2002:
|
|
302
|
-
console.error(
|
|
303
|
-
"Invalid server key - get a new one from server settings"
|
|
304
|
-
);
|
|
305
|
-
break;
|
|
306
|
-
case 4001:
|
|
307
|
-
console.error("Rate limited - reduce request frequency");
|
|
308
|
-
break;
|
|
309
|
-
case 3002:
|
|
310
|
-
console.error("Server offline - wait for players to join");
|
|
311
|
-
break;
|
|
312
|
-
case 9999:
|
|
313
|
-
console.error("Server module outdated - restart server");
|
|
314
|
-
break;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Show suggested actions
|
|
318
|
-
if (error.suggestions) {
|
|
319
|
-
console.error("Suggested actions:");
|
|
320
|
-
error.suggestions.forEach((action) => console.error(`- ${action}`));
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Check if error is retryable
|
|
324
|
-
if (error.retryable) {
|
|
325
|
-
console.error("This error might be resolved by retrying");
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
throw error; // Re-throw if needed
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Batch Operations
|
|
334
|
-
|
|
335
|
-
```javascript
|
|
336
|
-
const getServerOverview = async (serverToken) => {
|
|
337
|
-
try {
|
|
338
|
-
// Execute multiple API calls concurrently
|
|
339
|
-
const [serverInfo, players, staff, vehicles] = await Promise.all([
|
|
340
|
-
erlc.getServer(serverToken),
|
|
341
|
-
erlc.getPlayers(serverToken),
|
|
342
|
-
erlc.getStaff(serverToken),
|
|
343
|
-
erlc.getVehicles(serverToken),
|
|
344
|
-
]);
|
|
345
|
-
|
|
346
|
-
return {
|
|
347
|
-
server: serverInfo,
|
|
348
|
-
playerCount: players.length,
|
|
349
|
-
staffCount:
|
|
350
|
-
Object.keys(staff.Admins).length + Object.keys(staff.Mods).length,
|
|
351
|
-
vehicleCount: vehicles.length,
|
|
352
|
-
};
|
|
353
|
-
} catch (error) {
|
|
354
|
-
console.error("Error getting server overview:", error.message);
|
|
355
|
-
throw error;
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
## 🔑 Authentication
|
|
361
|
-
|
|
362
|
-
### Getting Your Tokens
|
|
363
|
-
|
|
364
|
-
1. **Global Token**: Contact ER:LC developers through their [Discord](https://discord.gg/prc) to request increased API limits
|
|
365
|
-
2. **Server Token**: Found in your server settings within ER:LC
|
|
366
|
-
|
|
367
|
-
### Token Security
|
|
368
|
-
|
|
369
|
-
```javascript
|
|
370
|
-
// ❌ Don't hardcode tokens
|
|
371
|
-
const client = new erlc.Client({
|
|
372
|
-
globalToken: "your-token-here",
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
// ✅ Use environment variables
|
|
376
|
-
const client = new erlc.Client({
|
|
377
|
-
globalToken: process.env.ERLC_GLOBAL_TOKEN,
|
|
378
|
-
});
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
## 📝 TypeScript Support
|
|
382
|
-
|
|
383
|
-
The package includes comprehensive TypeScript definitions:
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
import erlc, { ServerStatus, ServerPlayer, JoinLog } from "erlc-api";
|
|
387
|
-
|
|
388
|
-
const client = new erlc.Client({
|
|
389
|
-
globalToken: process.env.ERLC_GLOBAL_TOKEN!,
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
client.config();
|
|
393
|
-
|
|
394
|
-
// Fully typed responses
|
|
395
|
-
const server: ServerStatus = await erlc.getServer(serverToken);
|
|
396
|
-
const players: ServerPlayer[] = await erlc.getPlayers(serverToken);
|
|
397
|
-
const joinLogs: JoinLog[] = await erlc.getJoinLogs(serverToken);
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
## ⚡ Performance Tips
|
|
401
|
-
|
|
402
|
-
1. **Use Promise.all()** for concurrent requests when fetching multiple endpoints
|
|
403
|
-
2. **Implement caching** for frequently accessed data that doesn't change often
|
|
404
|
-
3. **Handle rate limits** by implementing retry logic with exponential backoff
|
|
405
|
-
4. **Use timeouts** - all methods have built-in 10-15 second timeouts
|
|
406
|
-
|
|
407
|
-
## 🐛 Error Types
|
|
408
|
-
|
|
409
|
-
The wrapper provides comprehensive error handling with specific ERLC error codes:
|
|
410
|
-
|
|
411
|
-
### ERLC Error Codes
|
|
412
|
-
|
|
413
|
-
| Code | Category | Description |
|
|
414
|
-
| ---- | -------------------- | -------------------------------------- |
|
|
415
|
-
| 0 | System Error | Unknown error occurred |
|
|
416
|
-
| 1001 | Communication Error | Error communicating with Roblox server |
|
|
417
|
-
| 1002 | System Error | Internal system error |
|
|
418
|
-
| 2000 | Authentication Error | Missing server key |
|
|
419
|
-
| 2001 | Authentication Error | Invalid server key format |
|
|
420
|
-
| 2002 | Authentication Error | Invalid or expired server key |
|
|
421
|
-
| 2003 | Authentication Error | Invalid global API key |
|
|
422
|
-
| 2004 | Authentication Error | Server key banned |
|
|
423
|
-
| 3001 | Request Error | Invalid command provided |
|
|
424
|
-
| 3002 | Request Error | Server offline (no players) |
|
|
425
|
-
| 4001 | Rate Limit Error | Rate limited |
|
|
426
|
-
| 4002 | Permission Error | Restricted command |
|
|
427
|
-
| 4003 | Content Error | Prohibited message |
|
|
428
|
-
| 9998 | Access Error | Restricted resource |
|
|
429
|
-
| 9999 | Version Error | Outdated server module |
|
|
430
|
-
|
|
431
|
-
### Error Properties
|
|
432
|
-
|
|
433
|
-
All errors are instances of `ErlcError` with these properties:
|
|
108
|
+
---
|
|
434
109
|
|
|
435
|
-
|
|
436
|
-
- `message`: Human-readable error message
|
|
437
|
-
- `category`: Error category (e.g., "AUTHENTICATION_ERROR")
|
|
438
|
-
- `severity`: Error severity ("LOW", "MEDIUM", "HIGH", "CRITICAL")
|
|
439
|
-
- `suggestions`: Array of suggested actions to resolve the error
|
|
440
|
-
- `retryable`: Boolean indicating if the error might be resolved by retrying
|
|
441
|
-
- `timestamp`: ISO timestamp when the error occurred
|
|
110
|
+
## 🚨 Manejo de Errores
|
|
442
111
|
|
|
443
|
-
|
|
112
|
+
La librería lanza errores descriptivos (`ErlcError`) que facilitan la depuración.
|
|
444
113
|
|
|
445
114
|
```javascript
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// Wait before retrying with exponential backoff
|
|
456
|
-
const delay = 1000 * Math.pow(2, attempt - 1);
|
|
457
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
458
|
-
}
|
|
459
|
-
}
|
|
115
|
+
try {
|
|
116
|
+
await erlc.getServer(serverToken);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error(`Error ${error.code}: ${error.message}`);
|
|
119
|
+
|
|
120
|
+
if (error.code === 4001) console.log("⏳ Rate limit alcanzado, espera un momento.");
|
|
121
|
+
if (error.code === 2002) console.log("🔑 La Server Key es inválida o expiró.");
|
|
460
122
|
}
|
|
461
|
-
|
|
462
|
-
// Usage
|
|
463
|
-
const players = await withRetry(() => erlc.getPlayers(serverToken));
|
|
464
123
|
```
|
|
465
124
|
|
|
466
|
-
|
|
125
|
+
### Códigos Comunes
|
|
467
126
|
|
|
468
|
-
|
|
127
|
+
| Código | Significado | Solución |
|
|
128
|
+
|:---:|---|---|
|
|
129
|
+
| **2002** | Key Inválida | Verifica tu `Server-Key` en el juego. |
|
|
130
|
+
| **3002** | Servidor Offline | El servidor no tiene jugadores o está apagado. |
|
|
131
|
+
| **4001** | Rate Limit | Estás enviando muchas peticiones muy rápido. |
|
|
132
|
+
| **403** | No Autorizado | Verifica tus permisos o tokens. |
|
|
469
133
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
473
|
-
|
|
474
|
-
## 🔗 Links
|
|
475
|
-
|
|
476
|
-
- **Discord Bot**: [Invite to your server](https://discord.com/oauth2/authorize?client_id=1014990793280323624)
|
|
477
|
-
- **API Documentation**: [PRC API Docs](https://apidocs.policeroleplay.community/reference/api-reference)
|
|
478
|
-
- **Discord Support**: [Join PRC Discord](https://discord.gg/prc)
|
|
479
|
-
- **Custom Liveries**: [Browse Collection](https://github.com/Exodo0/ERLC-API/tree/main/Custom%20Liveries)
|
|
134
|
+
---
|
|
480
135
|
|
|
481
|
-
##
|
|
136
|
+
## 🔗 Enlaces Útiles
|
|
482
137
|
|
|
483
|
-
-
|
|
484
|
-
-
|
|
485
|
-
-
|
|
486
|
-
- **Community Support**: [PRC Discord Community](https://discord.gg/prc)
|
|
138
|
+
- [Documentación Oficial de PRC](https://apidocs.policeroleplay.community/)
|
|
139
|
+
- [Discord de Soporte PRC](https://discord.gg/prc)
|
|
140
|
+
- [NPM Package](https://www.npmjs.com/package/erlc-api)
|
|
487
141
|
|
|
488
142
|
---
|
|
489
143
|
|
|
490
144
|
<div align="center">
|
|
491
|
-
<
|
|
492
|
-
<p>
|
|
493
|
-
<a href="https://github.com/Exodo0/ERLC-API">⭐ Star us on GitHub</a> •
|
|
494
|
-
<a href="https://discord.gg/prc">💬 Join our Discord</a> •
|
|
495
|
-
<a href="https://twitter.com/0Adexus0">🐦 Follow on Twitter</a>
|
|
496
|
-
</p>
|
|
145
|
+
<sub>Hecho con ❤️ para la comunidad de ER:LC</sub>
|
|
497
146
|
</div>
|
package/package.json
CHANGED
package/src/classes/client.js
CHANGED
|
@@ -17,12 +17,12 @@ class Client {
|
|
|
17
17
|
* @constructor
|
|
18
18
|
* @param {ClientConfig} options - Client Options
|
|
19
19
|
*/
|
|
20
|
-
constructor(options) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
if (options && typeof options === "object") {
|
|
22
|
+
this.options = { ...options };
|
|
23
|
+
} else {
|
|
24
|
+
this.options = {};
|
|
25
|
+
}
|
|
26
26
|
this.config();
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -15,8 +15,8 @@ module.exports = () => {
|
|
|
15
15
|
if (!config?.globalToken) {
|
|
16
16
|
const error = await processError(
|
|
17
17
|
new Error(
|
|
18
|
-
"Global token not configured. Please initialize the client first."
|
|
19
|
-
)
|
|
18
|
+
"Global token not configured. Please initialize the client first."
|
|
19
|
+
)
|
|
20
20
|
);
|
|
21
21
|
return reject(error);
|
|
22
22
|
}
|
|
@@ -44,13 +44,13 @@ module.exports = () => {
|
|
|
44
44
|
// However, looking at other endpoints, they return data directly.
|
|
45
45
|
// Let's assume it returns a JSON with the key, or we can inspect the response content type.
|
|
46
46
|
// But for now, let's try to parse as JSON.
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
const data = await res.json();
|
|
49
49
|
// If data has a specific field for the key, we should return that.
|
|
50
50
|
// If the documentation doesn't specify, I'll return the whole data object or try to find the key.
|
|
51
51
|
// Based on "This will send a new key", it might be { "apiKey": "..." } or just the string if it's text/plain.
|
|
52
52
|
// Given other endpoints return JSON, this likely returns JSON.
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
resolve(data);
|
|
55
55
|
} catch (error) {
|
|
56
56
|
const processedError = await processError(error);
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/bans`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/commandlogs`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/joinlogs`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/killlogs`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/modcalls`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/players`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/queue`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -12,20 +12,15 @@ module.exports = (serverToken) => {
|
|
|
12
12
|
const fetch = await import("node-fetch");
|
|
13
13
|
const { config } = await import("../../erlc.js");
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
21
|
-
);
|
|
15
|
+
const headers = {
|
|
16
|
+
"Server-Key": serverToken,
|
|
17
|
+
};
|
|
18
|
+
if (config?.globalToken) {
|
|
19
|
+
headers["Authorization"] = config.globalToken;
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
const res = await fetch.default(`${BASEURL}/server`, {
|
|
25
|
-
headers:
|
|
26
|
-
Authorization: config?.globalToken,
|
|
27
|
-
"Server-Key": serverToken,
|
|
28
|
-
},
|
|
23
|
+
headers: headers,
|
|
29
24
|
timeout: 10000, // 10 second timeout
|
|
30
25
|
});
|
|
31
26
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/staff`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -17,21 +17,15 @@ module.exports = (serverToken) => {
|
|
|
17
17
|
const fetch = await import("node-fetch");
|
|
18
18
|
const { config } = await import("../../erlc.js");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
return reject(error);
|
|
20
|
+
const headers = {
|
|
21
|
+
"Server-Key": serverToken,
|
|
22
|
+
};
|
|
23
|
+
if (config?.globalToken) {
|
|
24
|
+
headers["Authorization"] = config.globalToken;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const res = await fetch.default(`${BASEURL}/server/vehicles`, {
|
|
31
|
-
headers:
|
|
32
|
-
Authorization: config.globalToken,
|
|
33
|
-
"Server-Key": serverToken,
|
|
34
|
-
},
|
|
28
|
+
headers: headers,
|
|
35
29
|
timeout: 10000, // 10 second timeout
|
|
36
30
|
});
|
|
37
31
|
|
|
@@ -26,25 +26,19 @@ module.exports = (serverToken, command) => {
|
|
|
26
26
|
const fetch = await import("node-fetch");
|
|
27
27
|
const { config } = await import("../../erlc.js");
|
|
28
28
|
|
|
29
|
-
// Check if global token is configured
|
|
30
|
-
if (!config?.globalToken) {
|
|
31
|
-
const error = await processError(
|
|
32
|
-
new Error(
|
|
33
|
-
"Global token not configured. Please initialize the client first."
|
|
34
|
-
)
|
|
35
|
-
);
|
|
36
|
-
return reject(error);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
29
|
const requestBody = JSON.stringify({ command: command.trim() });
|
|
40
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
|
+
|
|
41
39
|
const res = await fetch.default(`${BASEURL}/server/command`, {
|
|
42
40
|
method: "POST",
|
|
43
|
-
headers:
|
|
44
|
-
Authorization: config.globalToken,
|
|
45
|
-
"Server-Key": serverToken,
|
|
46
|
-
"Content-Type": "application/json",
|
|
47
|
-
},
|
|
41
|
+
headers: headers,
|
|
48
42
|
body: requestBody,
|
|
49
43
|
timeout: 15000, // 15 second timeout for commands
|
|
50
44
|
});
|
package/src/types/index.d.ts
CHANGED