197 lines
10 KiB
TypeScript
197 lines
10 KiB
TypeScript
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<string, unknown> {
|
|
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' && typeof value.date === '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<AllLeaguesWithCapacityDTO> {
|
|
return this.get<AllLeaguesWithCapacityDTO>('/leagues/all-with-capacity');
|
|
}
|
|
|
|
/** Get all leagues with capacity + scoring summary (for leagues page filters) */
|
|
getAllWithCapacityAndScoring(): Promise<AllLeaguesWithCapacityAndScoringDTO> {
|
|
return this.get<AllLeaguesWithCapacityAndScoringDTO>('/leagues/all-with-capacity-and-scoring');
|
|
}
|
|
|
|
/** Get total number of leagues */
|
|
getTotal(): Promise<TotalLeaguesDTO> {
|
|
return this.get<TotalLeaguesDTO>('/leagues/total-leagues');
|
|
}
|
|
|
|
/** Get league standings */
|
|
getStandings(leagueId: string): Promise<LeagueStandingsDTO> {
|
|
return this.get<LeagueStandingsDTO>(`/leagues/${leagueId}/standings`);
|
|
}
|
|
|
|
/** Get league schedule */
|
|
getSchedule(leagueId: string, seasonId?: string): Promise<LeagueScheduleDTO> {
|
|
const qs = seasonId ? `?seasonId=${encodeURIComponent(seasonId)}` : '';
|
|
return this.get<LeagueScheduleDTO>(`/leagues/${leagueId}/schedule${qs}`);
|
|
}
|
|
|
|
/** Get league memberships */
|
|
getMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
|
|
return this.get<LeagueMembershipsDTO>(`/leagues/${leagueId}/memberships`);
|
|
}
|
|
|
|
/** Create a new league */
|
|
create(input: CreateLeagueInputDTO): Promise<CreateLeagueOutputDTO> {
|
|
return this.post<CreateLeagueOutputDTO>('/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<LeagueSeasonSummaryDTO[]> {
|
|
return this.get<LeagueSeasonSummaryDTO[]>(`/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<GetLeagueAdminConfigOutputDTO> {
|
|
return this.get<GetLeagueAdminConfigOutputDTO>(`/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<LeagueSeasonSchedulePublishOutputDTO> {
|
|
return this.post<LeagueSeasonSchedulePublishOutputDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/publish`, {});
|
|
}
|
|
|
|
/** Unpublish a league season schedule (admin/owner only; actor derived from session) */
|
|
unpublishSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
|
return this.post<LeagueSeasonSchedulePublishOutputDTO>(`/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<CreateLeagueScheduleRaceOutputDTO> {
|
|
const { example: _example, ...payload } = input;
|
|
return this.post<CreateLeagueScheduleRaceOutputDTO>(`/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<LeagueScheduleRaceMutationSuccessDTO> {
|
|
const { example: _example, ...payload } = input;
|
|
return this.patch<LeagueScheduleRaceMutationSuccessDTO>(`/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<LeagueScheduleRaceMutationSuccessDTO> {
|
|
return this.delete<LeagueScheduleRaceMutationSuccessDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races/${raceId}`);
|
|
}
|
|
|
|
/** Get races for a league */
|
|
async getRaces(leagueId: string): Promise<{ races: RaceDTO[] }> {
|
|
const response = await this.get<{ races?: unknown }>(`/leagues/${leagueId}/races`);
|
|
return { races: parseRaceDTOArray(response?.races) };
|
|
}
|
|
|
|
/** Admin roster: list current members (admin/owner only; actor derived from session) */
|
|
getAdminRosterMembers(leagueId: string): Promise<LeagueRosterMemberDTO[]> {
|
|
return this.get<LeagueRosterMemberDTO[]>(`/leagues/${leagueId}/admin/roster/members`);
|
|
}
|
|
|
|
/** Admin roster: list pending join requests (admin/owner only; actor derived from session) */
|
|
getAdminRosterJoinRequests(leagueId: string): Promise<LeagueRosterJoinRequestDTO[]> {
|
|
return this.get<LeagueRosterJoinRequestDTO[]>(`/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<ApproveJoinRequestOutputDTO> {
|
|
return this.post<ApproveJoinRequestOutputDTO>(`/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<RejectJoinRequestOutputDTO> {
|
|
return this.post<RejectJoinRequestOutputDTO>(`/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<UpdateLeagueMemberRoleOutputDTO> {
|
|
return this.patch<UpdateLeagueMemberRoleOutputDTO>(`/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<RemoveLeagueMemberOutputDTO> {
|
|
return this.patch<RemoveLeagueMemberOutputDTO>(`/leagues/${leagueId}/admin/roster/members/${targetDriverId}/remove`, {});
|
|
}
|
|
}
|