bracket-api-client
v1.0.5
Published
Type-safe API client for Bracket tournament management system
Maintainers
Readme
@bracket/api-client
Type-safe API client for the Bracket tournament management system, powered by Eden Treaty.
Features
- Full Type Safety: End-to-end type safety from backend to frontend
- Auto-Generated Types: Types are automatically generated from your Elysia backend
- Eden Treaty Integration: Leverages Elysia's official client for seamless integration
- Authentication Support: Built-in API key authentication helper
- Zero Configuration: Works out of the box with sensible defaults
Installation
npm install @bracket/api-client @elysiajs/eden
# or
yarn add @bracket/api-client @elysiajs/eden
# or
bun add @bracket/api-client @elysiajs/eden
# or
pnpm add @bracket/api-client @elysiajs/edenNote: @elysiajs/eden is a peer dependency and must be installed alongside this package.
Usage
Basic Usage
import { createApiClient } from "@bracket/api-client";
// Create the client
const api = createApiClient("http://localhost:3000");
// Make type-safe API calls
const { data, error } = await api.tournaments.post({
name: "My Tournament",
pointsConfig: {
win: 3,
draw: 1,
loss: 0,
forfeitWin: 3,
forfeitLoss: 0
},
tiebreakerConfig: {
rules: [
{ order: 1, type: "points" },
{ order: 2, type: "score_difference" }
]
}
});
if (error) {
console.error("Error:", error);
} else {
console.log("Tournament created:", data);
}With API Key Authentication
import { createAuthenticatedApiClient } from "@bracket/api-client";
// Create authenticated client
const api = createAuthenticatedApiClient(
"http://localhost:3000",
"your-api-key-here"
);
// All requests will include the X-API-KEY header
const { data, error } = await api.tournaments.get();Advanced Configuration
import { createApiClient } from "@bracket/api-client";
// Custom fetch implementation
const api = createApiClient("http://localhost:3000", {
fetcher: customFetch,
$fetch: {
// Default fetch options
headers: {
"Custom-Header": "value"
}
}
});API Reference
createApiClient(baseUrl, options?)
Creates a type-safe Eden Treaty client for the Bracket API.
Parameters:
baseUrl(string): The base URL of the API server (e.g., "http://localhost:3000")options(optional):fetcher: Custom fetch implementation$fetch: Default RequestInit options to pass to all fetch calls
Returns: Fully typed API client
createAuthenticatedApiClient(baseUrl, apiKey, options?)
Creates a type-safe Eden Treaty client with API key authentication.
Parameters:
baseUrl(string): The base URL of the API serverapiKey(string): The API key for authenticationoptions(optional):fetcher: Custom fetch implementation$fetch: Default RequestInit options
Returns: Fully typed API client with authentication
Type Safety
All API calls are fully typed based on your backend Elysia application:
// TypeScript knows the exact shape of request and response
const { data, error } = await api.tournaments[":id"].get({
$params: { id: "tournament-123" }
});
// data is typed as Tournament | null
// error is typed based on possible error responses
if (data) {
// TypeScript knows all properties of Tournament
console.log(data.name);
console.log(data.pointsConfig);
}Exported Types and Schemas
This package re-exports all relevant types from the backend, including:
API Types:
App- The main Elysia app type for type inference
Prisma Entity Types:
Tournament,Event,Stage,Round,Node,ParticipantSlot,MatchStageType,NodeType,MatchStatus
Schema Types: (TypeScript types, not validators)
- All input/output schema types from the backend
- Tournament, Event, Stage, Round, Node, and Match schemas
- Points config, tiebreaker config, and more
import type {
App,
Tournament,
CreateTournamentInput,
PointsConfig,
TiebreakerConfig
} from "bracket-api-client";
// Use types in your client code
const tournamentData: CreateTournamentInput = {
name: "My Tournament",
pointsConfig: { win: 3, draw: 1, loss: 0, forfeitWin: 3, forfeitLoss: 0 },
tiebreakerConfig: {
rules: [{ order: 1, type: "points" }]
}
};Error Handling
Eden Treaty returns responses in the format { data, error }:
const { data, error } = await api.tournaments.post(tournamentData);
if (error) {
// Handle error
console.error("Status:", error.status);
console.error("Message:", error.value);
} else {
// Handle success
console.log("Created:", data);
}Example: Complete CRUD Operations
import { createAuthenticatedApiClient } from "@bracket/api-client";
const api = createAuthenticatedApiClient(
"http://localhost:3000",
process.env.API_KEY
);
// Create a tournament
const { data: tournament } = await api.tournaments.post({
name: "World Championship 2024",
pointsConfig: { win: 3, draw: 1, loss: 0, forfeitWin: 3, forfeitLoss: 0 },
tiebreakerConfig: {
rules: [
{ order: 1, type: "points" },
{ order: 2, type: "score_difference" }
]
}
});
// Get tournament by ID
const { data: fetchedTournament } = await api.tournaments[":id"].get({
$params: { id: tournament.id }
});
// Update tournament
const { data: updated } = await api.tournaments[":id"].patch({
$params: { id: tournament.id },
name: "Updated Championship 2024"
});
// Delete tournament
await api.tournaments[":id"].delete({
$params: { id: tournament.id }
});Development
Building
bun run buildDevelopment Mode (Watch)
bun run devPublishing
This package is designed to be published to npm. Before publishing:
- Update the version in
package.json - Build the package:
bun run build - Publish:
npm publish --access public
The prepublishOnly script will automatically build the package before publishing.
Package Structure
@bracket/api-client/
├── src/
│ └── index.ts # Main entry point
├── dist/ # Built files (generated)
│ ├── index.js # CommonJS bundle
│ ├── index.mjs # ESM bundle
│ ├── index.d.ts # TypeScript definitions
│ └── index.d.mts # ESM TypeScript definitions
├── package.json
├── tsconfig.json
└── README.mdRequirements
- Node.js >= 16
@elysiajs/eden>= 1.0.0 (peer dependency)
License
MIT
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Support
For issues and questions:
- Open an issue on GitHub
- Check the Elysia Documentation
- Check the Eden Treaty Documentation
