UNPKG

epicleaderboard-ts

Version:

Universal TypeScript SDK for EpicLeaderboard - Works in Node.js and browsers

354 lines (276 loc) 8.65 kB
# EpicLeaderboard SDK [![npm version](https://badge.fury.io/js/epicleaderboard-ts.svg)](https://badge.fury.io/js/epicleaderboard-ts) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Universal TypeScript SDK for EpicLeaderboard - Works seamlessly in both Node.js and browser environments. ## Features - 🌐 **Universal**: Works in Node.js (16+) and modern browsers - 📦 **Zero Dependencies**: Lightweight with no external dependencies - 🔷 **TypeScript**: Full TypeScript support with comprehensive type definitions - 🚀 **Modern**: Uses native `fetch` API (available in Node.js 18+ and all modern browsers) - 📝 **Well Documented**: Comprehensive documentation and examples - ⚡ **Fast**: Minimal overhead and optimized for performance ## Installation ```bash npm install epicleaderboard-ts ``` ## Quick Start ### ES Modules (Recommended) ```typescript import { EpicLeaderboard, Timeframe, IsUsernameAvailableResponse } from 'epicleaderboard-ts'; const client = new EpicLeaderboard(); // Define your game and leaderboard const game = { gameID: 'your-game-id', gameKey: 'your-game-key' }; const leaderboard = { primaryID: 'main-leaderboard', secondaryID: 'level-1' }; // Get leaderboard entries try { const response = await client.getLeaderboardEntries( game, leaderboard, 'player-username', Timeframe.AllTime, true, // around player false // not local ); console.log('Top entries:', response.entries); console.log('Player entry:', response.playerEntry); } catch (error) { console.error('Error fetching leaderboard:', error); } ``` ### CommonJS ```javascript const { EpicLeaderboard, Timeframe } = require('epicleaderboard-ts'); const client = new EpicLeaderboard(); // ... rest is the same ``` ### Browser (via CDN) ```html <script type="module"> import { EpicLeaderboard } from 'https://unpkg.com/epicleaderboard-ts/dist/esm/index.js'; const client = new EpicLeaderboard(); // ... use the SDK </script> ``` ## API Reference ### Constructor ```typescript const client = new EpicLeaderboard(baseURL?: string); ``` - `baseURL` (optional): Custom server URL. Defaults to `https://epicleaderboard.com` ### Methods #### `getLeaderboardEntries()` Fetches leaderboard entries around a specific player. ```typescript async getLeaderboardEntries( game: EpicLeaderboardGame, leaderboard: EpicLeaderboard, username: string, timeframe?: Timeframe, aroundPlayer?: boolean, local?: boolean ): Promise<EpicLeaderboardGetEntriesResponse> ``` **Parameters:** - `game`: Game configuration with `gameID` and `gameKey` - `leaderboard`: Leaderboard configuration with `primaryID` and `secondaryID` - `username`: Player username to center results around - `timeframe`: Time period (default: `Timeframe.AllTime`) - `aroundPlayer`: Whether to center results around the player (default: `true`) - `local`: Whether to fetch local scores only (default: `false`) **Returns:** ```typescript { entries: EpicLeaderboardEntry[]; playerEntry: EpicLeaderboardEntry | null; } ``` #### `submitLeaderboardEntry()` Submits a score to the leaderboard. ```typescript async submitLeaderboardEntry( game: EpicLeaderboardGame, leaderboard: EpicLeaderboard, username: string, score: number, meta?: Record<string, string> ): Promise<TimeframeUpdateResult> ``` **Parameters:** - `game`: Game configuration - `leaderboard`: Leaderboard configuration - `username`: Player username - `score`: Numeric score value - `meta`: Optional additional data to store with the score **Returns:** A bitfield indicating which timeframe leaderboards were updated with this score: ```typescript enum TimeframeUpdateResult { None = 0, // No timeframes were updated AllTime = 1, // All-time leaderboard was updated Year = 2, // Yearly leaderboard was updated Month = 4, // Monthly leaderboard was updated Week = 8, // Weekly leaderboard was updated Day = 16 // Daily leaderboard was updated } ``` #### `isUsernameAvailable()` Checks if a username is available for use. ```typescript async isUsernameAvailable( game: EpicLeaderboardGame, username: string ): Promise<IsUsernameAvailableResponse> ``` **Returns:** One of: - `IsUsernameAvailableResponse.Available` (0) - `IsUsernameAvailableResponse.Invalid` (1) - `IsUsernameAvailableResponse.Profanity` (2) - `IsUsernameAvailableResponse.Taken` (3) ### Types #### `EpicLeaderboardGame` ```typescript interface EpicLeaderboardGame { gameID: string; gameKey: string; } ``` #### `EpicLeaderboard` ```typescript interface EpicLeaderboard { primaryID: string; secondaryID: string; } ``` #### `EpicLeaderboardEntry` ```typescript interface EpicLeaderboardEntry { rank: number; username: string; score: string; country: string; meta: Record<string, string>; } ``` #### `Timeframe` ```typescript enum Timeframe { AllTime = 0, Year = 1, Month = 2, Week = 3, Day = 4 } ``` #### `TimeframeUpdateResult` ```typescript enum TimeframeUpdateResult { None = 0, AllTime = 1, Year = 2, Month = 4, Week = 8, Day = 16 } ``` ## Examples ### Submit a Score with Metadata ```typescript import { EpicLeaderboard, TimeframeUpdateResult } from 'epicleaderboard-ts'; const client = new EpicLeaderboard(); const result = await client.submitLeaderboardEntry( { gameID: 'my-game', gameKey: 'secret-key' }, { primaryID: 'main', secondaryID: 'level-1' }, 'player123', 98500, { level: '1', time: '120.5', difficulty: 'hard' } ); // Check which timeframes were updated if (result & TimeframeUpdateResult.AllTime) { console.log('New all-time high score!'); } if (result & TimeframeUpdateResult.Day) { console.log('New daily high score!'); } ``` ### Check Username Availability ```typescript import { EpicLeaderboard, IsUsernameAvailableResponse } from 'epicleaderboard-ts'; const client = new EpicLeaderboard(); const result = await client.isUsernameAvailable( { gameID: 'my-game', gameKey: 'secret-key' }, 'desired-username' ); switch (result) { case IsUsernameAvailableResponse.Available: console.log('Username is available!'); break; case IsUsernameAvailableResponse.Taken: console.log('Username is already taken'); break; case IsUsernameAvailableResponse.Profanity: console.log('Username contains inappropriate content'); break; case IsUsernameAvailableResponse.Invalid: console.log('Username is invalid'); break; } ``` ### Get Weekly Leaderboard ```typescript import { EpicLeaderboard, Timeframe } from 'epicleaderboard-ts'; const client = new EpicLeaderboard(); const weeklyScores = await client.getLeaderboardEntries( { gameID: 'my-game', gameKey: 'secret-key' }, { primaryID: 'main', secondaryID: 'level-1' }, 'current-player', Timeframe.Week ); console.log('Weekly top scores:', weeklyScores.entries); ``` ## Error Handling The SDK throws `EpicLeaderboardError` for API-related errors: ```typescript import { EpicLeaderboard, EpicLeaderboardError } from 'epicleaderboard-ts'; try { await client.submitLeaderboardEntry(/* ... */); } catch (error) { if (error instanceof EpicLeaderboardError) { console.error('API Error:', error.message); console.error('Status Code:', error.statusCode); } else { console.error('Unknown Error:', error); } } ``` ## Browser Compatibility - **Modern Browsers**: Chrome 63+, Firefox 57+, Safari 12+, Edge 79+ - **Node.js**: 16.0+ (fetch polyfill required for Node.js < 18) ### Fetch Polyfill for Older Environments For Node.js versions < 18 or older browsers, you may need a fetch polyfill: ```bash npm install node-fetch ``` ```typescript // For Node.js < 18 import fetch from 'node-fetch'; globalThis.fetch = fetch as any; ``` ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## License MIT © [EpicLeaderboard](LICENSE) ## Support - 📧 Email: epicleaderboard@gmail.com - 🐛 Issues: [GitHub Issues](https://github.com/jensroth-git/epicleaderboard-ts/issues) - 📖 Documentation: [API Docs](https://epicleaderboard.com/docs)