epicleaderboard-ts
Version:
Universal TypeScript SDK for EpicLeaderboard - Works in Node.js and browsers
354 lines (276 loc) • 8.65 kB
Markdown
# EpicLeaderboard SDK
[](https://badge.fury.io/js/epicleaderboard-ts)
[](http://www.typescriptlang.org/)
[](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)