207 lines
6.3 KiB
TypeScript
207 lines
6.3 KiB
TypeScript
/**
|
|
* Application Layer: Entity to DTO Mappers
|
|
*
|
|
* Transforms domain entities to plain objects for crossing architectural boundaries.
|
|
* These mappers handle the Server Component -> Client Component boundary in Next.js 15.
|
|
*/
|
|
|
|
import { Driver } from '../../domain/entities/Driver';
|
|
import { League } from '../../domain/entities/League';
|
|
import { Race } from '../../domain/entities/Race';
|
|
import { Result } from '../../domain/entities/Result';
|
|
import { Standing } from '../../domain/entities/Standing';
|
|
import type { DriverDTO } from '../dto/DriverDTO';
|
|
import type { LeagueDTO } from '../dto/LeagueDTO';
|
|
import type { RaceDTO } from '../dto/RaceDTO';
|
|
import type { ResultDTO } from '../dto/ResultDTO';
|
|
import type { StandingDTO } from '../dto/StandingDTO';
|
|
|
|
export class EntityMappers {
|
|
static toDriverDTO(driver: Driver | null): DriverDTO | null {
|
|
if (!driver) return null;
|
|
return {
|
|
id: driver.id,
|
|
iracingId: driver.iracingId,
|
|
name: driver.name,
|
|
country: driver.country,
|
|
bio: driver.bio ?? '',
|
|
joinedAt: driver.joinedAt.toISOString(),
|
|
};
|
|
}
|
|
|
|
static toLeagueDTO(league: League | null): LeagueDTO | null {
|
|
if (!league) return null;
|
|
|
|
const socialLinks =
|
|
league.socialLinks !== undefined
|
|
? {
|
|
...(league.socialLinks.discordUrl !== undefined
|
|
? { discordUrl: league.socialLinks.discordUrl }
|
|
: {}),
|
|
...(league.socialLinks.youtubeUrl !== undefined
|
|
? { youtubeUrl: league.socialLinks.youtubeUrl }
|
|
: {}),
|
|
...(league.socialLinks.websiteUrl !== undefined
|
|
? { websiteUrl: league.socialLinks.websiteUrl }
|
|
: {}),
|
|
}
|
|
: undefined;
|
|
|
|
return {
|
|
id: league.id,
|
|
name: league.name,
|
|
description: league.description,
|
|
ownerId: league.ownerId,
|
|
settings: league.settings,
|
|
createdAt: league.createdAt.toISOString(),
|
|
...(socialLinks !== undefined ? { socialLinks } : {}),
|
|
};
|
|
}
|
|
|
|
static toLeagueDTOs(leagues: League[]): LeagueDTO[] {
|
|
return leagues.map((league) => {
|
|
const socialLinks =
|
|
league.socialLinks !== undefined
|
|
? {
|
|
...(league.socialLinks.discordUrl !== undefined
|
|
? { discordUrl: league.socialLinks.discordUrl }
|
|
: {}),
|
|
...(league.socialLinks.youtubeUrl !== undefined
|
|
? { youtubeUrl: league.socialLinks.youtubeUrl }
|
|
: {}),
|
|
...(league.socialLinks.websiteUrl !== undefined
|
|
? { websiteUrl: league.socialLinks.websiteUrl }
|
|
: {}),
|
|
}
|
|
: undefined;
|
|
|
|
return {
|
|
id: league.id,
|
|
name: league.name,
|
|
description: league.description,
|
|
ownerId: league.ownerId,
|
|
settings: league.settings,
|
|
createdAt: league.createdAt.toISOString(),
|
|
...(socialLinks !== undefined ? { socialLinks } : {}),
|
|
};
|
|
});
|
|
}
|
|
|
|
static toRaceDTO(race: Race | null): RaceDTO | null {
|
|
if (!race) return null;
|
|
|
|
const sessionTypeMap = {
|
|
practice: 'practice' as const,
|
|
qualifying: 'qualifying' as const,
|
|
q1: 'qualifying' as const,
|
|
q2: 'qualifying' as const,
|
|
q3: 'qualifying' as const,
|
|
sprint: 'race' as const,
|
|
main: 'race' as const,
|
|
timeTrial: 'practice' as const,
|
|
};
|
|
|
|
return {
|
|
id: race.id,
|
|
leagueId: race.leagueId,
|
|
scheduledAt: race.scheduledAt.toISOString(),
|
|
track: race.track,
|
|
trackId: race.trackId ?? '',
|
|
car: race.car,
|
|
carId: race.carId ?? '',
|
|
sessionType: sessionTypeMap[race.sessionType.value],
|
|
status: race.status,
|
|
...(race.strengthOfField !== undefined
|
|
? { strengthOfField: race.strengthOfField }
|
|
: {}),
|
|
...(race.registeredCount !== undefined
|
|
? { registeredCount: race.registeredCount }
|
|
: {}),
|
|
...(race.maxParticipants !== undefined
|
|
? { maxParticipants: race.maxParticipants }
|
|
: {}),
|
|
};
|
|
}
|
|
|
|
static toRaceDTOs(races: Race[]): RaceDTO[] {
|
|
const sessionTypeMap = {
|
|
practice: 'practice' as const,
|
|
qualifying: 'qualifying' as const,
|
|
q1: 'qualifying' as const,
|
|
q2: 'qualifying' as const,
|
|
q3: 'qualifying' as const,
|
|
sprint: 'race' as const,
|
|
main: 'race' as const,
|
|
timeTrial: 'practice' as const,
|
|
};
|
|
|
|
return races.map((race) => ({
|
|
id: race.id,
|
|
leagueId: race.leagueId,
|
|
scheduledAt: race.scheduledAt.toISOString(),
|
|
track: race.track,
|
|
trackId: race.trackId ?? '',
|
|
car: race.car,
|
|
carId: race.carId ?? '',
|
|
sessionType: sessionTypeMap[race.sessionType.value],
|
|
status: race.status,
|
|
...(race.strengthOfField !== undefined
|
|
? { strengthOfField: race.strengthOfField }
|
|
: {}),
|
|
...(race.registeredCount !== undefined
|
|
? { registeredCount: race.registeredCount }
|
|
: {}),
|
|
...(race.maxParticipants !== undefined
|
|
? { maxParticipants: race.maxParticipants }
|
|
: {}),
|
|
}));
|
|
}
|
|
|
|
static toResultDTO(result: Result | null): ResultDTO | null {
|
|
if (!result) return null;
|
|
return {
|
|
id: result.id,
|
|
raceId: result.raceId,
|
|
driverId: result.driverId,
|
|
position: result.position,
|
|
fastestLap: result.fastestLap,
|
|
incidents: result.incidents,
|
|
startPosition: result.startPosition,
|
|
};
|
|
}
|
|
|
|
static toResultDTOs(results: Result[]): ResultDTO[] {
|
|
return results.map(result => ({
|
|
id: result.id,
|
|
raceId: result.raceId,
|
|
driverId: result.driverId,
|
|
position: result.position,
|
|
fastestLap: result.fastestLap,
|
|
incidents: result.incidents,
|
|
startPosition: result.startPosition,
|
|
}));
|
|
}
|
|
|
|
static toStandingDTO(standing: Standing | null): StandingDTO | null {
|
|
if (!standing) return null;
|
|
return {
|
|
leagueId: standing.leagueId,
|
|
driverId: standing.driverId,
|
|
points: standing.points,
|
|
wins: standing.wins,
|
|
position: standing.position,
|
|
racesCompleted: standing.racesCompleted,
|
|
};
|
|
}
|
|
|
|
static toStandingDTOs(standings: Standing[]): StandingDTO[] {
|
|
return standings.map(standing => ({
|
|
leagueId: standing.leagueId,
|
|
driverId: standing.driverId,
|
|
points: standing.points,
|
|
wins: standing.wins,
|
|
position: standing.position,
|
|
racesCompleted: standing.racesCompleted,
|
|
}));
|
|
}
|
|
} |