import { BaseApiClient } from '../base/BaseApiClient'; import type { AllLeaguesWithCapacityDTO } from '../../types/generated/AllLeaguesWithCapacityDTO'; import type { TotalLeaguesDTO } from '../../types/generated/TotalLeaguesDTO'; import type { LeagueStandingsDTO } from '../../types/generated/LeagueStandingsDTO'; import type { LeagueScheduleDTO } from '../../types/generated/LeagueScheduleDTO'; import type { LeagueMembershipsDTO } from '../../types/generated/LeagueMembershipsDTO'; import type { CreateLeagueInputDTO } from '../../types/generated/CreateLeagueInputDTO'; import type { CreateLeagueOutputDTO } from '../../types/generated/CreateLeagueOutputDTO'; import type { SponsorshipDetailDTO } from '../../types/generated/SponsorshipDetailDTO'; import type { RaceDTO } from '../../types/generated/RaceDTO'; import type { GetLeagueAdminConfigOutputDTO } from '../../types/generated/GetLeagueAdminConfigOutputDTO'; import type { LeagueScoringPresetDTO } from '../../types/generated/LeagueScoringPresetDTO'; import type { LeagueSeasonSummaryDTO } from '../../types/generated/LeagueSeasonSummaryDTO'; import type { CreateLeagueScheduleRaceInputDTO } from '../../types/generated/CreateLeagueScheduleRaceInputDTO'; import type { CreateLeagueScheduleRaceOutputDTO } from '../../types/generated/CreateLeagueScheduleRaceOutputDTO'; import type { UpdateLeagueScheduleRaceInputDTO } from '../../types/generated/UpdateLeagueScheduleRaceInputDTO'; import type { LeagueScheduleRaceMutationSuccessDTO } from '../../types/generated/LeagueScheduleRaceMutationSuccessDTO'; import type { LeagueSeasonSchedulePublishOutputDTO } from '../../types/generated/LeagueSeasonSchedulePublishOutputDTO'; import type { LeagueRosterMemberDTO } from '../../types/generated/LeagueRosterMemberDTO'; import type { LeagueRosterJoinRequestDTO } from '../../types/generated/LeagueRosterJoinRequestDTO'; import type { ApproveJoinRequestOutputDTO } from '../../types/generated/ApproveJoinRequestOutputDTO'; import type { RejectJoinRequestOutputDTO } from '../../types/generated/RejectJoinRequestOutputDTO'; import type { UpdateLeagueMemberRoleOutputDTO } from '../../types/generated/UpdateLeagueMemberRoleOutputDTO'; import type { RemoveLeagueMemberOutputDTO } from '../../types/generated/RemoveLeagueMemberOutputDTO'; import type { AllLeaguesWithCapacityAndScoringDTO } from '../../types/AllLeaguesWithCapacityAndScoringDTO'; function isRecord(value: unknown): value is Record { return typeof value === 'object' && value !== null; } function isRaceDTO(value: unknown): value is RaceDTO { if (!isRecord(value)) return false; return typeof value.id === 'string' && typeof value.name === 'string'; } function parseRaceDTOArray(value: unknown): RaceDTO[] { if (!Array.isArray(value)) return []; return value.filter(isRaceDTO); } /** * Leagues API Client * * Handles all league-related API operations. */ export class LeaguesApiClient extends BaseApiClient { /** Get all leagues with capacity information */ getAllWithCapacity(): Promise { return this.get('/leagues/all-with-capacity', { retry: false }); } /** Get all leagues with capacity + scoring summary (for leagues page filters) */ getAllWithCapacityAndScoring(): Promise { return this.get('/leagues/all-with-capacity-and-scoring', { retry: false }); } /** Get total number of leagues */ getTotal(): Promise { return this.get('/leagues/total-leagues'); } /** Get league standings */ getStandings(leagueId: string): Promise { return this.get(`/leagues/${leagueId}/standings`); } /** Get league schedule */ getSchedule(leagueId: string, seasonId?: string): Promise { const qs = seasonId ? `?seasonId=${encodeURIComponent(seasonId)}` : ''; return this.get(`/leagues/${leagueId}/schedule${qs}`); } /** Get league memberships */ async getMemberships(leagueId: string): Promise { const response = await this.get(`/leagues/${leagueId}/memberships`); if (Array.isArray(response)) return { members: response }; if (response?.members) return response; return { members: [] }; } /** Create a new league */ create(input: CreateLeagueInputDTO): Promise { return this.post('/leagues', input); } /** Remove a member from league */ removeMember(leagueId: string, performerDriverId: string, targetDriverId: string): Promise<{ success: boolean }> { return this.patch<{ success: boolean }>(`/leagues/${leagueId}/members/${targetDriverId}/remove`, { performerDriverId }); } /** Update a member's role in league */ updateMemberRole(leagueId: string, performerDriverId: string, targetDriverId: string, newRole: string): Promise<{ success: boolean }> { return this.patch<{ success: boolean }>(`/leagues/${leagueId}/members/${targetDriverId}/role`, { performerDriverId, newRole }); } /** Get league seasons */ getSeasons(leagueId: string): Promise { return this.get(`/leagues/${leagueId}/seasons`); } /** Get season sponsorships */ getSeasonSponsorships(seasonId: string): Promise<{ sponsorships: SponsorshipDetailDTO[] }> { return this.get<{ sponsorships: SponsorshipDetailDTO[] }>(`/leagues/seasons/${seasonId}/sponsorships`); } /** Get league config */ getLeagueConfig(leagueId: string): Promise { return this.get(`/leagues/${leagueId}/config`); } /** Get league scoring presets */ getScoringPresets(): Promise<{ presets: LeagueScoringPresetDTO[] }> { return this.get<{ presets: LeagueScoringPresetDTO[] }>(`/leagues/scoring-presets`); } /** Transfer league ownership */ transferOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<{ success: boolean }> { return this.post<{ success: boolean }>(`/leagues/${leagueId}/transfer-ownership`, { currentOwnerId, newOwnerId, }); } /** Publish a league season schedule (admin/owner only; actor derived from session) */ publishSeasonSchedule(leagueId: string, seasonId: string): Promise { return this.post(`/leagues/${leagueId}/seasons/${seasonId}/schedule/publish`, {}); } /** Unpublish a league season schedule (admin/owner only; actor derived from session) */ unpublishSeasonSchedule(leagueId: string, seasonId: string): Promise { return this.post(`/leagues/${leagueId}/seasons/${seasonId}/schedule/unpublish`, {}); } /** Create a schedule race for a league season (admin/owner only; actor derived from session) */ createSeasonScheduleRace( leagueId: string, seasonId: string, input: CreateLeagueScheduleRaceInputDTO, ): Promise { const { example: _, ...payload } = input; return this.post(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races`, payload); } /** Update a schedule race for a league season (admin/owner only; actor derived from session) */ updateSeasonScheduleRace( leagueId: string, seasonId: string, raceId: string, input: UpdateLeagueScheduleRaceInputDTO, ): Promise { const { example: _, ...payload } = input; return this.patch(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races/${raceId}`, payload); } /** Delete a schedule race for a league season (admin/owner only; actor derived from session) */ deleteSeasonScheduleRace( leagueId: string, seasonId: string, raceId: string, ): Promise { return this.delete(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races/${raceId}`); } /** Get races for a league */ async getRaces(leagueId: string): Promise<{ races: RaceDTO[] }> { const response = await this.get(`/leagues/${leagueId}/races`); const races = Array.isArray(response) ? response : (response?.races || []); return { races: parseRaceDTOArray(races) }; } /** Admin roster: list current members (admin/owner only; actor derived from session) */ getAdminRosterMembers(leagueId: string): Promise { return this.get(`/leagues/${leagueId}/admin/roster/members`); } /** Admin roster: list pending join requests (admin/owner only; actor derived from session) */ getAdminRosterJoinRequests(leagueId: string): Promise { return this.get(`/leagues/${leagueId}/admin/roster/join-requests`); } /** Admin roster: approve a join request (admin/owner only; actor derived from session) */ approveRosterJoinRequest(leagueId: string, joinRequestId: string): Promise { return this.post(`/leagues/${leagueId}/admin/roster/join-requests/${joinRequestId}/approve`, {}); } /** Admin roster: reject a join request (admin/owner only; actor derived from session) */ rejectRosterJoinRequest(leagueId: string, joinRequestId: string): Promise { return this.post(`/leagues/${leagueId}/admin/roster/join-requests/${joinRequestId}/reject`, {}); } /** Admin roster: update member role (admin/owner only; actor derived from session) */ updateRosterMemberRole(leagueId: string, targetDriverId: string, newRole: string): Promise { return this.patch(`/leagues/${leagueId}/admin/roster/members/${targetDriverId}/role`, { newRole }); } /** Admin roster: remove member (admin/owner only; actor derived from session) */ removeRosterMember(leagueId: string, targetDriverId: string): Promise { return this.patch(`/leagues/${leagueId}/admin/roster/members/${targetDriverId}/remove`, {}); } }