Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

erlc-api

Exodo0134MIT3.0.0TypeScript support: included

An ER:LC API wrapper for JS/TS

erlc, roblox, prc, erlc-api, liberty-county

readme

🚔 ER:LC API Wrapper

npm version License: MIT

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.

✨ Features

  • 🎯 100% API Coverage - All ER:LC API endpoints supported
  • 🛡️ Robust Error Handling - Comprehensive error catching and meaningful error messages
  • 📝 Full TypeScript Support - Complete type definitions for all methods and responses
  • Optimized Performance - Efficient request handling with timeout management
  • 🔒 Secure - Built-in validation and secure token handling
  • 📚 Well Documented - Extensive documentation and examples
  • 🚀 Easy to Use - Simple, intuitive API design

📦 Installation

npm install erlc-api
bun add erlc-api

🚀 Quick Start

Basic Setup

const erlc = require("erlc-api");

// Initialize the client with your global token
const client = new erlc.Client({
  globalToken: "your-global-token-here", // Get this from ER:LC developers
});

// Register your client
client.config();

TypeScript Setup

import erlc from "erlc-api";

const client = new erlc.Client({
  globalToken: "your-global-token-here",
});

client.config();

📖 API Methods

🖥️ Server Information

Get Server Details

const getServerInfo = async () => {
  try {
    const serverToken = "your-server-api-key"; // From Server Settings
    const server = await erlc.getServer(serverToken);

    console.log(server);
    /*
    Expected Response:
    {
      Name: "Your Server Name",
      OwnerUsername: "ServerOwner",
      CoOwnerUsernames: ["CoOwner1", "CoOwner2"],
      CurrentPlayers: 25,
      MaxPlayers: 40,
      JoinKey: "ABC123",
      AccVerifiedReq: "Disabled", // "Email" | "Phone/ID"
      TeamBalance: true,
      VanityURL: "https://policeroleplay.community/join?code=ABC123"
    }
    */
  } catch (error) {
    console.error("Error fetching server info:", error.message);
  }
};

Get Current Players

const getCurrentPlayers = async () => {
  try {
    const players = await erlc.getPlayers(serverToken);

    console.log(players);
    /*
    Expected Response:
    [
      {
        Player: "PlayerName:123456789",
        Permission: "Server Owner", // "Member" | "Moderator" | "Server Administrator"
        Team: "Police" // "Civilian" | "Fire" | "Sheriff"
      }
    ]
    */
  } catch (error) {
    console.error("Error fetching players:", error.message);
  }
};

Get Server Queue

const getServerQueue = async () => {
  try {
    const queue = await erlc.getQueue(serverToken);
    console.log(`Players in queue: ${queue.length}`);
  } catch (error) {
    console.error("Error fetching queue:", error.message);
  }
};

👥 Staff Management

Get Staff Information

const getStaffInfo = async () => {
  try {
    const staff = await erlc.getStaff(serverToken);

    console.log(staff);
    /*
    Expected Response:
    {
      CoOwners: [123456789, 987654321],
      Admins: { "123456789": "AdminName" },
      Mods: { "987654321": "ModName" }
    }
    */
  } catch (error) {
    console.error("Error fetching staff:", error.message);
  }
};

📊 Server Logs

Get Join/Leave Logs

const getJoinLogs = async () => {
  try {
    const logs = await erlc.getJoinLogs(serverToken);

    logs.forEach((log) => {
      const action = log.Join ? "joined" : "left";
      console.log(
        `${log.Player} ${action} at ${new Date(log.Timestamp * 1000)}`
      );
    });
  } catch (error) {
    console.error("Error fetching join logs:", error.message);
  }
};

Get Kill Logs

const getKillLogs = async () => {
  try {
    const kills = await erlc.getKillLogs(serverToken);

    kills.forEach((kill) => {
      console.log(
        `${kill.Killer} killed ${kill.Killed} at ${new Date(
          kill.Timestamp * 1000
        )}`
      );
    });
  } catch (error) {
    console.error("Error fetching kill logs:", error.message);
  }
};

Get Command Logs

const getCommandLogs = async () => {
  try {
    const commands = await erlc.getCommandLogs(serverToken);

    commands.forEach((cmd) => {
      console.log(`${cmd.Player} executed: ${cmd.Command}`);
    });
  } catch (error) {
    console.error("Error fetching command logs:", error.message);
  }
};

Get Moderator Call Logs

const getModCalls = async () => {
  try {
    const modcalls = await erlc.getModcallLogs(serverToken);

    modcalls.forEach((call) => {
      const status = call.Moderator
        ? `answered by ${call.Moderator}`
        : "unanswered";
      console.log(`${call.Caller} made a modcall - ${status}`);
    });
  } catch (error) {
    console.error("Error fetching modcall logs:", error.message);
  }
};

🚗 Vehicle Management

Get Server Vehicles

const getVehicles = async () => {
  try {
    const vehicles = await erlc.getVehicles(serverToken);

    vehicles.forEach((vehicle) => {
      console.log(
        `${vehicle.Name} owned by ${vehicle.Owner} - Texture: ${
          vehicle.Texture || "Default"
        }`
      );
    });
  } catch (error) {
    console.error("Error fetching vehicles:", error.message);
  }
};

🔨 Server Management

Execute Server Commands

const executeCommand = async () => {
  try {
    const success = await erlc.runCommand(
      serverToken,
      ":h Welcome to our server!"
    );

    if (success) {
      console.log("Command executed successfully!");
    }
  } catch (error) {
    console.error("Error executing command:", error.message);
  }
};

Get Server Bans

const getBannedPlayers = async () => {
  try {
    const bans = await erlc.getBans(serverToken);

    Object.entries(bans).forEach(([playerId, playerName]) => {
      console.log(`${playerName} (${playerId}) is banned`);
    });
  } catch (error) {
    console.error("Error fetching bans:", error.message);
  }
};

🛠️ Advanced Usage

Error Handling Best Practices

const handleApiCall = async () => {
  try {
    const result = await erlc.getServer(serverToken);
    return result;
  } catch (error) {
    // Handle specific error types
    if (error.status === 401) {
      console.error("Authentication failed - check your tokens");
    } else if (error.status === 404) {
      console.error("Server not found - check your server token");
    } else if (error.message.includes("Network error")) {
      console.error("Connection issue - check your internet connection");
    } else if (error.message.includes("timeout")) {
      console.error("Request timed out - try again later");
    } else {
      console.error("Unexpected error:", error.message);
    }

    throw error; // Re-throw if needed
  }
};

Batch Operations

const getServerOverview = async (serverToken) => {
  try {
    // Execute multiple API calls concurrently
    const [serverInfo, players, staff, vehicles] = await Promise.all([
      erlc.getServer(serverToken),
      erlc.getPlayers(serverToken),
      erlc.getStaff(serverToken),
      erlc.getVehicles(serverToken),
    ]);

    return {
      server: serverInfo,
      playerCount: players.length,
      staffCount:
        Object.keys(staff.Admins).length + Object.keys(staff.Mods).length,
      vehicleCount: vehicles.length,
    };
  } catch (error) {
    console.error("Error getting server overview:", error.message);
    throw error;
  }
};

🔑 Authentication

Getting Your Tokens

  1. Global Token: Contact ER:LC developers through their Discord to request increased API limits
  2. Server Token: Found in your server settings within ER:LC

Token Security

// ❌ Don't hardcode tokens
const client = new erlc.Client({
  globalToken: "your-token-here",
});

// ✅ Use environment variables
const client = new erlc.Client({
  globalToken: process.env.ERLC_GLOBAL_TOKEN,
});

📝 TypeScript Support

The package includes comprehensive TypeScript definitions:

import erlc, { ServerStatus, ServerPlayer, JoinLog } from "erlc-api";

const client = new erlc.Client({
  globalToken: process.env.ERLC_GLOBAL_TOKEN!,
});

client.config();

// Fully typed responses
const server: ServerStatus = await erlc.getServer(serverToken);
const players: ServerPlayer[] = await erlc.getPlayers(serverToken);
const joinLogs: JoinLog[] = await erlc.getJoinLogs(serverToken);

⚡ Performance Tips

  1. Use Promise.all() for concurrent requests when fetching multiple endpoints
  2. Implement caching for frequently accessed data that doesn't change often
  3. Handle rate limits by implementing retry logic with exponential backoff
  4. Use timeouts - all methods have built-in 10-15 second timeouts

🐛 Error Types

The wrapper provides detailed error information:

  • Network Errors: Connection issues, DNS resolution failures
  • Authentication Errors: Invalid tokens, insufficient permissions
  • API Errors: Server-side errors with status codes and messages
  • Validation Errors: Invalid input parameters
  • Timeout Errors: Requests that take too long to complete

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

👨‍💻 Credits


Made with ❤️ for the ER:LC community

⭐ Star us on GitHub💬 Join our Discord🐦 Follow on Twitter