erlc-api 2.3.4 → 3.1.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/.gitattributes CHANGED
@@ -1,2 +1,2 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
package/README.md CHANGED
@@ -1,110 +1,497 @@
1
- # ER:LC API Wrapper
2
-
3
- A lightweight API Wrapper with 100% coverage of the ER:LC API. Fixed Error and Improvements
4
- 7
5
-
6
- ## Getting Started
7
-
8
- First you need to install the package.
9
-
10
- `npm i erlc-api`
11
-
12
- ### Setting Up
13
-
14
- Setting up is super simple:
15
-
16
- ```js
17
- // index.js
18
- const erlc = require("erlc");
19
- const client = new erlc.Client({
20
- globalToken: "", // You get the global key directly from the ERLC developers. To increase your API request limits
21
- });
22
- client.config(); // Registers your client
23
- ```
24
-
25
- Now you can start using API Methods - here are a few examples:
26
-
27
- ```js
28
- // GetServerInfo.js
29
- const erlc = require("erlc-api"); //JS
30
- import erlc from "erlc-api"; // Module or typeScript
31
-
32
- const getServerFunc = async () => {
33
- const serverId = ""; // The server ApiKey you wish to target. You can get this api key in your (Server Settings)
34
- const server = await erlc.getServer(serverId).catch(console.log); // Gets the server, logs any errors
35
- console.log(server); // Logs the server object
36
-
37
- // Expected Response:
38
- // {
39
- // Name: "Your Sever Name",
40
- // CurrentPlayers: 0,
41
- // MaxPlayers: 40,
42
- // JoinKey: "Your Code Join",
43
- // AccVerifiedReq: "Disabled" | "Email" | "Phone/ID",
44
- // TeamBalance: true or false ,
45
- // OwnerUsername: "Your Name",
46
- // CoOwnerUsernames: [],
47
- // VanityURL: "https://policeroleplay.community/join?code=YourCode",
48
- // },
49
- };
50
-
51
- getServerFunc();
52
- ```
53
-
54
- ```js
55
- // GetPlayers.js
56
- const erlc = require("erlc-api"); //JS
57
- import erlc from "erlc-api"; // Module or typeScript
58
-
59
- const getPlayersFunc = async () => {
60
- const serverId = ""; // The server ApiKey you wish to target. You can get this api key in your (Server Settings)
61
- const server = await erlc.getPlayers(serverId).catch(console.log); // Gets the server, logs any errors
62
- console.log(server); // Logs the server object
63
- // Expected Response:
64
- // [
65
- // {
66
- // "Permission": "Server Owner" Or Member, Moderator,
67
- // "Player": "Player-Username and ID" ,
68
- // "Team": "Civilian" Or Fire, Police, Sherift
69
- // }
70
- // ]
71
- };
72
- getPlayersFunc();
73
- ```
74
-
75
- ```js
76
- //getmodCalls.js
77
- const erlc = require("erlc-api"); //JS
78
- import erlc from "erlc-api"; // Module or typeScript
79
-
80
- const getModCallsFunc = async () => {
81
- const serverId = ""; // The server ApiKey you wish to target. You can get this api key in your (Server Settings)
82
- const server = await erlc.getModcallLogs(serverId).catch(console.log); // Gets the server, logs any errors
83
- console.log(server); // Logs the server object
84
- // Expected Response:
85
- // {
86
- // Caller: ErlcPlayer;
87
- // Moderator?: ErlcPlayer; // If call is unanswered property is undefined
88
- // Timestamp: number;
89
- // }
90
- };
91
- getModCallsFunc()
92
- ```
93
-
94
- ### [Discord Bot](https://discord.com/oauth2/authorize?client_id=1014990793280323624)
95
-
96
- The Discord Bot Back Online 29/05/2024
97
-
98
- ## [Module Examples](https://scarlet-2.gitbook.io/erlc-api/)
99
-
100
- ### [PRC API Docs](https://apidocs.policeroleplay.community/reference/api-reference)
101
-
102
- ## [Liveries]("https://github.com/Exodo0/ERLC-API/tree/main/Custom%20Liveries")
103
-
104
- ### Credits
105
-
106
- Library Re-Development - [Egologics](https://twitter.com/0Adexus0)
107
-
108
- API Development - [Police Roleplay Community](https://twitter.com/PRC_Roblox)
109
-
110
- Apply for more API request limits - [Discord](https://discord.gg/prc)
1
+ # 🚔 ER:LC API Wrapper
2
+
3
+ [![npm version](https://badge.fury.io/js/erlc-api.svg)](https://badge.fury.io/js/erlc-api)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A comprehensive, lightweight, and fully-typed API wrapper for Emergency Response: Liberty County (ER:LC) with 100% API coverage, robust error handling, and TypeScript support.
7
+
8
+ ## Features
9
+
10
+ - 🎯 **100% API Coverage** - All ER:LC API endpoints supported
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
17
+
18
+ ## 📦 Installation
19
+
20
+ ```bash
21
+ npm install erlc-api
22
+ ```
23
+
24
+ ```bash
25
+ bun add erlc-api
26
+ ```
27
+
28
+ ## 🚀 Quick Start
29
+
30
+ ### Basic Setup
31
+
32
+ ```javascript
33
+ const erlc = require("erlc-api");
34
+
35
+ // Initialize the client with your global token
36
+ const client = new erlc.Client({
37
+ globalToken: "your-global-token-here", // Get this from ER:LC developers
38
+ });
39
+
40
+ // Register your client
41
+ client.config();
42
+ ```
43
+
44
+ ### TypeScript Setup
45
+
46
+ ```typescript
47
+ import erlc from "erlc-api";
48
+
49
+ const client = new erlc.Client({
50
+ globalToken: "your-global-token-here",
51
+ });
52
+
53
+ client.config();
54
+ ```
55
+
56
+ ## 📖 API Methods
57
+
58
+ ### 🖥️ Server Information
59
+
60
+ #### Get Server Details
61
+
62
+ ```javascript
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
+ ```
88
+
89
+ #### Get Current Players
90
+
91
+ ```javascript
92
+ const getCurrentPlayers = async () => {
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
+ ```
112
+
113
+ #### Get Server Queue
114
+
115
+ ```javascript
116
+ const getServerQueue = async () => {
117
+ try {
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
127
+
128
+ #### Get Staff Information
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
+ };
148
+ ```
149
+
150
+ ### 📊 Server Logs
151
+
152
+ #### Get Join/Leave Logs
153
+
154
+ ```javascript
155
+ const getJoinLogs = async () => {
156
+ try {
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
+ ```
170
+
171
+ #### Get Kill Logs
172
+
173
+ ```javascript
174
+ const getKillLogs = async () => {
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
+ ```
190
+
191
+ #### Get Command Logs
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
+ };
224
+ ```
225
+
226
+ ### 🚗 Vehicle Management
227
+
228
+ #### Get Server Vehicles
229
+
230
+ ```javascript
231
+ const getVehicles = async () => {
232
+ try {
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
+ ```
247
+
248
+ ### 🔨 Server Management
249
+
250
+ #### Execute Server Commands
251
+
252
+ ```javascript
253
+ const executeCommand = async () => {
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
+ };
267
+ ```
268
+
269
+ #### Get Server Bans
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:
434
+
435
+ - `code`: ERLC error code or HTTP status
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
442
+
443
+ ### Retry Logic Example
444
+
445
+ ```javascript
446
+ async function withRetry(apiCall, maxRetries = 3) {
447
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
448
+ try {
449
+ return await apiCall();
450
+ } catch (error) {
451
+ if (!error.retryable || attempt === maxRetries) {
452
+ throw error;
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
+ }
460
+ }
461
+
462
+ // Usage
463
+ const players = await withRetry(() => erlc.getPlayers(serverToken));
464
+ ```
465
+
466
+ ## 🤝 Contributing
467
+
468
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
469
+
470
+ ## 📄 License
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)
480
+
481
+ ## 👨‍💻 Credits
482
+
483
+ - **Library Development**: [Egologics](https://twitter.com/0Adexus0)
484
+ - **NPM Package**: [ERLC-API](https://www.npmjs.com/package/erlc-api)
485
+ - **API Development**: [Police Roleplay Community](https://twitter.com/PRC_Roblox)
486
+ - **Community Support**: [PRC Discord Community](https://discord.gg/prc)
487
+
488
+ ---
489
+
490
+ <div align="center">
491
+ <p>Made with ❤️ for the ER:LC community</p>
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>
497
+ </div>