services refactor
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ import { join } from 'path';
|
|||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule, process.env.GENERATE_OPENAPI ? { logger: false } : undefined);
|
||||||
|
|
||||||
// Swagger/OpenAPI configuration
|
// Swagger/OpenAPI configuration
|
||||||
const config = new DocumentBuilder()
|
const config = new DocumentBuilder()
|
||||||
@@ -35,6 +35,8 @@ async function bootstrap() {
|
|||||||
const outputPath = join(__dirname, '../openapi.json');
|
const outputPath = join(__dirname, '../openapi.json');
|
||||||
writeFileSync(outputPath, JSON.stringify(document, null, 2));
|
writeFileSync(outputPath, JSON.stringify(document, null, 2));
|
||||||
console.log(`✅ OpenAPI spec generated at: ${outputPath}`);
|
console.log(`✅ OpenAPI spec generated at: ${outputPath}`);
|
||||||
|
await app.close();
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
await app.listen(3000);
|
await app.listen(3000);
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface AllLeaguesWithCapacityAndScoringDTO {
|
|
||||||
type: [LeagueSummaryDTO] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => LeagueSummaryDTO)
|
|
||||||
leagues: LeagueSummaryDTO[];
|
|
||||||
totalCount: number;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface AllLeaguesWithCapacityDTO {
|
|
||||||
type: [LeagueWithCapacityDTO] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => LeagueWithCapacityDTO)
|
|
||||||
leagues: LeagueWithCapacityDTO[];
|
|
||||||
totalCount: number;
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface ApplyPenaltyCommandDTO {
|
export interface ApplyPenaltyCommandDTO {
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
stewardId: string;
|
||||||
enum: string;
|
enum: string;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,4 @@
|
|||||||
|
|
||||||
export interface ApproveJoinRequestOutputDTO {
|
export interface ApproveJoinRequestOutputDTO {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { AuthenticatedUserDTO } from './AuthenticatedUserDTO';
|
||||||
|
|
||||||
export interface AuthSessionDTO {
|
export interface AuthSessionDTO {
|
||||||
iracingCustomerId?: string;
|
token: string;
|
||||||
primaryDriverId?: string;
|
user: AuthenticatedUserDTO;
|
||||||
avatarUrl?: string;
|
|
||||||
returnTo?: string;
|
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface AuthenticatedUserDTO {
|
export interface AuthenticatedUserDTO {
|
||||||
iracingCustomerId?: string;
|
userId: string;
|
||||||
primaryDriverId?: string;
|
email: string;
|
||||||
avatarUrl?: string;
|
displayName: string;
|
||||||
returnTo?: string;
|
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,4 @@ export interface CompleteOnboardingInputDTO {
|
|||||||
lastName: string;
|
lastName: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
country: string;
|
country: string;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,4 @@
|
|||||||
|
|
||||||
export interface CompleteOnboardingOutputDTO {
|
export interface CompleteOnboardingOutputDTO {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,4 @@
|
|||||||
export interface CreateLeagueInputDTO {
|
export interface CreateLeagueInputDTO {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
enum: string;
|
|
||||||
ownerId: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,4 @@
|
|||||||
export interface CreateSponsorInputDTO {
|
export interface CreateSponsorInputDTO {
|
||||||
name: string;
|
name: string;
|
||||||
contactEmail: string;
|
contactEmail: string;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface CreateSponsorOutputDTO {
|
|
||||||
sponsor: SponsorDTO;
|
|
||||||
type: SponsorDTO })
|
|
||||||
sponsor: SponsorDTO;
|
|
||||||
}
|
|
||||||
@@ -5,5 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface DashboardDriverSummaryDTO {
|
export interface DashboardDriverSummaryDTO {
|
||||||
nullable: string;
|
id: string;
|
||||||
|
name: string;
|
||||||
|
country: string;
|
||||||
|
avatarUrl: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface DashboardFeedItemSummaryDTO {
|
export interface DashboardFeedItemSummaryDTO {
|
||||||
|
id: string;
|
||||||
enum: string;
|
enum: string;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface DashboardFeedSummaryDTO {
|
export interface DashboardFeedSummaryDTO {
|
||||||
type: [DashboardFeedItemSummaryDTO] })
|
notificationCount: number;
|
||||||
items!: DashboardFeedItemSummaryDTO[];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface DriverDto {
|
export interface DashboardFriendSummaryDTO {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
avatarUrl?: string;
|
country: string;
|
||||||
iracingId?: string;
|
avatarUrl: string;
|
||||||
rating?: number;
|
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,10 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface CreatePaymentInputDTO {
|
export interface DashboardLeagueStandingSummaryDTO {
|
||||||
enum: string;
|
|
||||||
amount: number;
|
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
required: string;
|
leagueName: string;
|
||||||
|
position: number;
|
||||||
|
totalDrivers: number;
|
||||||
|
points: number;
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface DashboardOverviewDTO {
|
|
||||||
nullable: true })
|
|
||||||
currentDriver!: DashboardDriverSummaryDTO null;
|
|
||||||
type: [DashboardRaceSummaryDTO] })
|
|
||||||
myUpcomingRaces!: DashboardRaceSummaryDTO[];
|
|
||||||
}
|
|
||||||
@@ -5,5 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface DashboardRaceSummaryDTO {
|
export interface DashboardRaceSummaryDTO {
|
||||||
enum: string;
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
track: string;
|
||||||
|
car: string;
|
||||||
|
scheduledAt: string;
|
||||||
}
|
}
|
||||||
|
|||||||
15
apps/website/lib/types/generated/DashboardRecentResultDTO.ts
Normal file
15
apps/website/lib/types/generated/DashboardRecentResultDTO.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Auto-generated DTO from OpenAPI spec
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface DashboardRecentResultDTO {
|
||||||
|
raceId: string;
|
||||||
|
raceName: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
finishedAt: string;
|
||||||
|
position: number;
|
||||||
|
incidents: number;
|
||||||
|
}
|
||||||
@@ -15,6 +15,4 @@ export interface DriverLeaderboardItemDTO {
|
|||||||
podiums: number;
|
podiums: number;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
rank: number;
|
rank: number;
|
||||||
avatarUrl?: string;
|
|
||||||
nullable: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface CreatePaymentOutputDTO {
|
export interface DriverRegistrationStatusDTO {
|
||||||
payment: PaymentDTO;
|
isRegistered: boolean;
|
||||||
type: PaymentDTO })
|
raceId: string;
|
||||||
payment: PaymentDTO;
|
driverId: string;
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface DriversLeaderboardDTO {
|
|
||||||
drivers: DriverLeaderboardItemDTO[];
|
|
||||||
totalRaces: number;
|
|
||||||
totalWins: number;
|
|
||||||
activeCount: number;
|
|
||||||
type: [DriverLeaderboardItemDTO] })
|
|
||||||
drivers: DriverLeaderboardItemDTO[];
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface FileProtestCommandDTO {
|
export interface FileProtestCommandDTO {
|
||||||
|
raceId: string;
|
||||||
|
protestingDriverId: string;
|
||||||
|
accusedDriverId: string;
|
||||||
|
incident: Record<string, unknown>;
|
||||||
lap: number;
|
lap: number;
|
||||||
description: string;
|
description: string;
|
||||||
timeInRace: number;
|
timeInRace?: number;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface GetEntitySponsorshipPricingResultDTO {
|
|
||||||
pricing: SponsorshipPricingItemDTO[];
|
|
||||||
type: [SponsorshipPricingItemDTO] })
|
|
||||||
pricing: SponsorshipPricingItemDTO[];
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface GetLeagueAdminConfigOutputDTO {
|
|
||||||
type: () => LeagueConfigFormModelDTO, nullable: true })
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => LeagueConfigFormModelDTO)
|
|
||||||
form: LeagueConfigFormModelDTO null;
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RecordEngagementInputDTO {
|
export interface GetRaceDetailParamsDTODTO {
|
||||||
enum: string;
|
raceId: string;
|
||||||
required: string;
|
driverId: string;
|
||||||
}
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface GetSponsorsOutputDTO {
|
|
||||||
sponsors: SponsorDTO[];
|
|
||||||
type: [SponsorDTO] })
|
|
||||||
sponsors: SponsorDTO[];
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface ImportRaceResultsSummaryDTO {
|
export interface ImportRaceResultsDTO {
|
||||||
errors?: string[];
|
raceId: string;
|
||||||
type: string[];
|
resultsFileContent: string;
|
||||||
}
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueAdminConfigDTO {
|
|
||||||
type: () => LeagueConfigFormModelDTO, nullable: true })
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => LeagueConfigFormModelDTO)
|
|
||||||
form: LeagueConfigFormModelDTO null;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueAdminDTO {
|
|
||||||
type: [LeagueJoinRequestDTO] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => LeagueJoinRequestDTO)
|
|
||||||
joinRequests: LeagueJoinRequestDTO[];
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueAdminProtestsDTO {
|
|
||||||
type: [ProtestDTO] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => ProtestDTO)
|
|
||||||
protests: ProtestDTO[];
|
|
||||||
}
|
|
||||||
@@ -7,5 +7,4 @@
|
|||||||
export interface LeagueConfigFormModelBasicsDTO {
|
export interface LeagueConfigFormModelBasicsDTO {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
enum: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,4 @@
|
|||||||
|
|
||||||
export interface LeagueConfigFormModelDTO {
|
export interface LeagueConfigFormModelDTO {
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
type: LeagueConfigFormModelBasicsDTO })
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => LeagueConfigFormModelBasicsDTO)
|
|
||||||
basics: LeagueConfigFormModelBasicsDTO;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueConfigFormModelStewardingDTO {
|
|
||||||
enum: string;
|
|
||||||
required: string;
|
|
||||||
requireDefense: boolean;
|
|
||||||
defenseTimeLimit: number;
|
|
||||||
voteTimeLimit: number;
|
|
||||||
protestDeadlineHours: number;
|
|
||||||
stewardingClosesHours: number;
|
|
||||||
notifyAccusedOnProtest: boolean;
|
|
||||||
notifyOnVoteRequired: boolean;
|
|
||||||
}
|
|
||||||
@@ -8,11 +8,6 @@ export interface LeagueJoinRequestDTO {
|
|||||||
id: string;
|
id: string;
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
driverId: string;
|
driverId: string;
|
||||||
|
/** Format: date-time */
|
||||||
requestedAt: string;
|
requestedAt: string;
|
||||||
required: string;
|
|
||||||
type: () => DriverDto, required: false })
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DriverDto)
|
|
||||||
driver?: DriverDto;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,4 @@
|
|||||||
|
|
||||||
export interface LeagueMemberDTO {
|
export interface LeagueMemberDTO {
|
||||||
driverId: string;
|
driverId: string;
|
||||||
type: () => DriverDto })
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DriverDto)
|
|
||||||
driver: DriverDto;
|
|
||||||
enum: string;
|
|
||||||
joinedAt: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueMembershipsDTO {
|
|
||||||
type: [LeagueMemberDTO] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => LeagueMemberDTO)
|
|
||||||
members: LeagueMemberDTO[];
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueOwnerSummaryDTO {
|
|
||||||
type: () => DriverDto })
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DriverDto)
|
|
||||||
driver: DriverDto;
|
|
||||||
nullable: string;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueScheduleDTO {
|
|
||||||
type: [RaceDto] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => RaceDto)
|
|
||||||
races: RaceDto[];
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,4 @@ export interface LeagueSeasonSummaryDTO {
|
|||||||
seasonId: string;
|
seasonId: string;
|
||||||
name: string;
|
name: string;
|
||||||
status: string;
|
status: string;
|
||||||
required: string;
|
|
||||||
isPrimary: boolean;
|
|
||||||
isParallelActive: boolean;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,4 @@
|
|||||||
|
|
||||||
export interface LeagueStandingDTO {
|
export interface LeagueStandingDTO {
|
||||||
driverId: string;
|
driverId: string;
|
||||||
type: () => DriverDto })
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DriverDto)
|
|
||||||
driver: DriverDto;
|
|
||||||
points: number;
|
|
||||||
rank: number;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LeagueStandingsDTO {
|
|
||||||
type: [LeagueStandingDTO] })
|
|
||||||
@IsArray()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => LeagueStandingDTO)
|
|
||||||
standings: LeagueStandingDTO[];
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,4 @@
|
|||||||
export interface LeagueSummaryDTO {
|
export interface LeagueSummaryDTO {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
nullable: string;
|
|
||||||
memberCount: number;
|
|
||||||
maxMembers: number;
|
|
||||||
isPublic: boolean;
|
|
||||||
ownerId: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,4 @@
|
|||||||
export interface LeagueWithCapacityDTO {
|
export interface LeagueWithCapacityDTO {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
nullable: string;
|
|
||||||
ownerId: string;
|
|
||||||
type: () => LeagueSettingsDTO })
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => LeagueSettingsDTO)
|
|
||||||
settings: LeagueSettingsDTO;
|
|
||||||
createdAt: string;
|
|
||||||
usedSlots: number;
|
|
||||||
youtubeUrl: string;
|
|
||||||
websiteUrl: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,42 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface MemberPaymentDto {
|
export interface MemberPaymentDto {
|
||||||
payment: MemberPaymentDto;
|
|
||||||
fee: MembershipFeeDto;
|
|
||||||
payments: PaymentDto[];
|
|
||||||
prizes: PrizeDto[];
|
|
||||||
prize: PrizeDto;
|
|
||||||
wallet: WalletDto;
|
|
||||||
transactions: TransactionDto[];
|
|
||||||
transaction: TransactionDto;
|
|
||||||
id: string;
|
id: string;
|
||||||
enum: string;
|
feeId: string;
|
||||||
|
driverId: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
platformFee: number;
|
platformFee: number;
|
||||||
netAmount: number;
|
netAmount: number;
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
|
||||||
required: string;
|
|
||||||
createdAt: string;
|
|
||||||
type: PaymentDto })
|
|
||||||
payment: PaymentDto;
|
|
||||||
paymentId: string;
|
|
||||||
enabled: boolean;
|
|
||||||
updatedAt: string;
|
|
||||||
feeId: string;
|
|
||||||
driverId: string;
|
|
||||||
dueDate: string;
|
|
||||||
seasonId: string;
|
|
||||||
position: number;
|
|
||||||
name: string;
|
|
||||||
awarded: boolean;
|
|
||||||
prizeId: string;
|
|
||||||
success: boolean;
|
|
||||||
balance: number;
|
|
||||||
totalRevenue: number;
|
|
||||||
totalPlatformFees: number;
|
|
||||||
totalWithdrawn: number;
|
|
||||||
currency: string;
|
|
||||||
walletId: string;
|
|
||||||
description: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,42 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface MembershipFeeDto {
|
export interface MembershipFeeDto {
|
||||||
payment: MemberPaymentDto;
|
|
||||||
fee: MembershipFeeDto;
|
|
||||||
payments: PaymentDto[];
|
|
||||||
prizes: PrizeDto[];
|
|
||||||
prize: PrizeDto;
|
|
||||||
wallet: WalletDto;
|
|
||||||
transactions: TransactionDto[];
|
|
||||||
transaction: TransactionDto;
|
|
||||||
id: string;
|
id: string;
|
||||||
enum: string;
|
|
||||||
amount: number;
|
|
||||||
platformFee: number;
|
|
||||||
netAmount: number;
|
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
required: string;
|
|
||||||
createdAt: string;
|
|
||||||
type: PaymentDto })
|
|
||||||
payment: PaymentDto;
|
|
||||||
paymentId: string;
|
|
||||||
enabled: boolean;
|
|
||||||
updatedAt: string;
|
|
||||||
feeId: string;
|
|
||||||
driverId: string;
|
|
||||||
dueDate: string;
|
|
||||||
seasonId: string;
|
|
||||||
position: number;
|
|
||||||
name: string;
|
|
||||||
awarded: boolean;
|
|
||||||
prizeId: string;
|
|
||||||
success: boolean;
|
|
||||||
balance: number;
|
|
||||||
totalRevenue: number;
|
|
||||||
totalPlatformFees: number;
|
|
||||||
totalWithdrawn: number;
|
|
||||||
currency: string;
|
|
||||||
walletId: string;
|
|
||||||
description: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,4 @@
|
|||||||
|
|
||||||
export interface PaymentDTO {
|
export interface PaymentDTO {
|
||||||
id: string;
|
id: string;
|
||||||
enum: string;
|
|
||||||
amount: number;
|
|
||||||
platformFee: number;
|
|
||||||
netAmount: number;
|
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
|
||||||
required: string;
|
|
||||||
createdAt: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,42 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface PrizeDto {
|
export interface PrizeDto {
|
||||||
payment: MemberPaymentDto;
|
|
||||||
fee: MembershipFeeDto;
|
|
||||||
payments: PaymentDto[];
|
|
||||||
prizes: PrizeDto[];
|
|
||||||
prize: PrizeDto;
|
|
||||||
wallet: WalletDto;
|
|
||||||
transactions: TransactionDto[];
|
|
||||||
transaction: TransactionDto;
|
|
||||||
id: string;
|
id: string;
|
||||||
enum: string;
|
|
||||||
amount: number;
|
|
||||||
platformFee: number;
|
|
||||||
netAmount: number;
|
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
required: string;
|
|
||||||
createdAt: string;
|
|
||||||
type: PaymentDto })
|
|
||||||
payment: PaymentDto;
|
|
||||||
paymentId: string;
|
|
||||||
enabled: boolean;
|
|
||||||
updatedAt: string;
|
|
||||||
feeId: string;
|
|
||||||
driverId: string;
|
|
||||||
dueDate: string;
|
|
||||||
seasonId: string;
|
seasonId: string;
|
||||||
position: number;
|
position: number;
|
||||||
name: string;
|
name: string;
|
||||||
awarded: boolean;
|
amount: number;
|
||||||
prizeId: string;
|
|
||||||
success: boolean;
|
|
||||||
balance: number;
|
|
||||||
totalRevenue: number;
|
|
||||||
totalPlatformFees: number;
|
|
||||||
totalWithdrawn: number;
|
|
||||||
currency: string;
|
|
||||||
walletId: string;
|
|
||||||
description: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface ProtestDTO {
|
export interface ProtestDTO {
|
||||||
TODO: protests are filed at race level but also managed on league level
|
|
||||||
|
|
||||||
export class ProtestDTO {
|
|
||||||
@ApiProperty()
|
|
||||||
@IsString()
|
|
||||||
id: string;
|
id: string;
|
||||||
raceId: string;
|
raceId: string;
|
||||||
protestingDriverId: string;
|
protestingDriverId: string;
|
||||||
accusedDriverId: string;
|
accusedDriverId: string;
|
||||||
|
/** Format: date-time */
|
||||||
submittedAt: string;
|
submittedAt: string;
|
||||||
description: string;
|
description: string;
|
||||||
enum: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface QuickPenaltyCommandDTO {
|
export interface QuickPenaltyCommandDTO {
|
||||||
enum: string;
|
raceId: string;
|
||||||
required: string;
|
driverId: string;
|
||||||
|
adminId: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface LeagueSettingsDTO {
|
export interface RaceActionParamsDTO {
|
||||||
nullable: string;
|
raceId: string;
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceDTO {
|
export interface RaceDTO {
|
||||||
leagueName?: string;
|
id: string;
|
||||||
nullable: string;
|
name: string;
|
||||||
|
date: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface RaceDetailDTO {
|
|
||||||
nullable: true })
|
|
||||||
race!: RaceDetailRaceDTO null;
|
|
||||||
type: [RaceDetailEntryDTO] })
|
|
||||||
entryList!: RaceDetailEntryDTO[];
|
|
||||||
required: string;
|
|
||||||
}
|
|
||||||
@@ -5,5 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceDetailEntryDTO {
|
export interface RaceDetailEntryDTO {
|
||||||
nullable: string;
|
id: string;
|
||||||
|
name: string;
|
||||||
|
country: string;
|
||||||
|
avatarUrl: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceDetailLeagueDTO {
|
export interface RaceDetailLeagueDTO {
|
||||||
maxDrivers: number;
|
id: string;
|
||||||
qualifyingFormat: string;
|
name: string;
|
||||||
|
description: string;
|
||||||
|
settings: Record<string, unknown>;
|
||||||
|
maxDrivers?: number;
|
||||||
|
qualifyingFormat?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceDetailRaceDTO {
|
export interface RaceDetailRaceDTO {
|
||||||
nullable: string;
|
id: string;
|
||||||
required: string;
|
leagueId: string;
|
||||||
|
track: string;
|
||||||
|
car: string;
|
||||||
|
scheduledAt: string;
|
||||||
|
sessionType: string;
|
||||||
|
status: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Auto-generated DTO from OpenAPI spec
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface RaceDetailRegistrationDTO {
|
||||||
|
isUserRegistered: boolean;
|
||||||
|
canRegister: boolean;
|
||||||
|
}
|
||||||
@@ -5,5 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceDetailUserResultDTO {
|
export interface RaceDetailUserResultDTO {
|
||||||
nullable: string;
|
position: number;
|
||||||
|
startPosition: number;
|
||||||
|
incidents: number;
|
||||||
|
fastestLap: number;
|
||||||
|
positionChange: number;
|
||||||
|
isPodium: boolean;
|
||||||
|
isClean: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface RacePenaltiesDTO {
|
|
||||||
type: [RacePenaltyDTO] })
|
|
||||||
penalties!: RacePenaltyDTO[];
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RacePenaltyDTO {
|
export interface RacePenaltyDTO {
|
||||||
notes?: string;
|
id: string;
|
||||||
nullable: string;
|
driverId: string;
|
||||||
|
type: string;
|
||||||
|
value: number;
|
||||||
|
reason: string;
|
||||||
|
issuedBy: string;
|
||||||
|
issuedAt: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceProtestDTO {
|
export interface RaceProtestDTO {
|
||||||
|
id: string;
|
||||||
|
protestingDriverId: string;
|
||||||
|
accusedDriverId: string;
|
||||||
|
incident: Record<string, unknown>;
|
||||||
lap: number;
|
lap: number;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface RaceProtestsDTO {
|
|
||||||
type: [RaceProtestDto] })
|
|
||||||
protests!: RaceProtestDto[];
|
|
||||||
}
|
|
||||||
18
apps/website/lib/types/generated/RaceResultDTO.ts
Normal file
18
apps/website/lib/types/generated/RaceResultDTO.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Auto-generated DTO from OpenAPI spec
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface RaceResultDTO {
|
||||||
|
driverId: string;
|
||||||
|
driverName: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
position: number;
|
||||||
|
startPosition: number;
|
||||||
|
incidents: number;
|
||||||
|
fastestLap: number;
|
||||||
|
positionChange: number;
|
||||||
|
isPodium: boolean;
|
||||||
|
isClean: boolean;
|
||||||
|
}
|
||||||
@@ -5,6 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceResultsDetailDTO {
|
export interface RaceResultsDetailDTO {
|
||||||
type: [RaceResultDto] })
|
raceId: string;
|
||||||
results!: RaceResultDto[];
|
track: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface AllRacesPageDTO {
|
export interface RaceStatsDTO {
|
||||||
type: string[];
|
totalRaces: number;
|
||||||
}
|
}
|
||||||
@@ -5,5 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RaceWithSOFDTO {
|
export interface RaceWithSOFDTO {
|
||||||
nullable: string;
|
id: string;
|
||||||
|
track: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface RacesPageDataDTO {
|
|
||||||
type: [RacesPageDataRaceDto] })
|
|
||||||
races!: RacesPageDataRaceDto[];
|
|
||||||
}
|
|
||||||
@@ -5,5 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RacesPageDataRaceDTO {
|
export interface RacesPageDataRaceDTO {
|
||||||
nullable: string;
|
id: string;
|
||||||
|
track: string;
|
||||||
|
car: string;
|
||||||
|
scheduledAt: string;
|
||||||
|
status: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface LeagueConfigFormModelDropPolicyDTO {
|
export interface RecordEngagementOutputDTO {
|
||||||
enum: string;
|
eventId: string;
|
||||||
required: string;
|
engagementWeight: number;
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface RecordPageViewInputDTO {
|
export interface RecordPageViewOutputDTO {
|
||||||
enum: string;
|
pageViewId: string;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
11
apps/website/lib/types/generated/RegisterForRaceParamsDTO.ts
Normal file
11
apps/website/lib/types/generated/RegisterForRaceParamsDTO.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Auto-generated DTO from OpenAPI spec
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface RegisterForRaceParamsDTO {
|
||||||
|
raceId: string;
|
||||||
|
leagueId: string;
|
||||||
|
driverId: string;
|
||||||
|
}
|
||||||
@@ -6,5 +6,4 @@
|
|||||||
|
|
||||||
export interface RejectJoinRequestOutputDTO {
|
export interface RejectJoinRequestOutputDTO {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
required: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface RequestAvatarGenerationOutputDTO {
|
|
||||||
avatarUrls?: string[];
|
|
||||||
type: string;
|
|
||||||
required: string;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Auto-generated DTO from OpenAPI spec
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface RequestProtestDefenseCommandDTO {
|
||||||
|
protestId: string;
|
||||||
|
stewardId: string;
|
||||||
|
}
|
||||||
@@ -8,7 +8,4 @@ export interface SeasonDTO {
|
|||||||
seasonId: string;
|
seasonId: string;
|
||||||
name: string;
|
name: string;
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
required: string;
|
|
||||||
enum: string;
|
|
||||||
isPrimary: boolean;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface SponsorDashboardDTO {
|
export interface SponsorDashboardDTO {
|
||||||
metrics: SponsorDashboardMetricsDTO;
|
|
||||||
sponsoredLeagues: SponsoredLeagueDTO[];
|
|
||||||
investment: SponsorDashboardInvestmentDTO;
|
|
||||||
sponsorId: string;
|
sponsorId: string;
|
||||||
sponsorName: string;
|
sponsorName: string;
|
||||||
type: SponsorDashboardMetricsDTO })
|
|
||||||
metrics: SponsorDashboardMetricsDTO;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface SponsorSponsorshipsDTO {
|
export interface SponsorSponsorshipsDTO {
|
||||||
sponsorships: SponsorshipDetailDTO[];
|
|
||||||
sponsorId: string;
|
sponsorId: string;
|
||||||
sponsorName: string;
|
sponsorName: string;
|
||||||
type: [SponsorshipDetailDTO] })
|
|
||||||
sponsorships: SponsorshipDetailDTO[];
|
|
||||||
summary: string;
|
|
||||||
activeSponsorships: number;
|
|
||||||
totalInvestment: number;
|
|
||||||
totalPlatformFees: number;
|
|
||||||
currency: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,4 @@
|
|||||||
export interface SponsoredLeagueDTO {
|
export interface SponsoredLeagueDTO {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
enum: string;
|
|
||||||
drivers: number;
|
|
||||||
races: number;
|
|
||||||
impressions: number;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,20 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface SponsorshipDetailDTO {
|
export interface SponsorshipDetailDTO {
|
||||||
createdAt: string;
|
|
||||||
id: string;
|
id: string;
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
leagueName: string;
|
leagueName: string;
|
||||||
seasonId: string;
|
seasonId: string;
|
||||||
seasonName: string;
|
seasonName: string;
|
||||||
required: string;
|
|
||||||
enum: string;
|
|
||||||
pricing: string;
|
|
||||||
currency: string;
|
|
||||||
platformFee: string;
|
|
||||||
netAmount: string;
|
|
||||||
metrics: string;
|
|
||||||
races: number;
|
|
||||||
completedRaces: number;
|
|
||||||
impressions: number;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface TeamListItemViewModel {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
tag: string;
|
|
||||||
description: string;
|
|
||||||
memberCount: number;
|
|
||||||
leagues: string;
|
|
||||||
specialization?: string;
|
|
||||||
region?: string;
|
|
||||||
languages?: string;
|
|
||||||
teams: string[];
|
|
||||||
totalCount: number;
|
|
||||||
ownerId: string;
|
|
||||||
createdAt?: string;
|
|
||||||
role: string;
|
|
||||||
joinedAt: string;
|
|
||||||
isActive: boolean;
|
|
||||||
team: string;
|
|
||||||
membership: string;
|
|
||||||
isOwner: boolean;
|
|
||||||
canManage: boolean;
|
|
||||||
success: boolean;
|
|
||||||
}
|
|
||||||
@@ -5,42 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface TransactionDto {
|
export interface TransactionDto {
|
||||||
payment: MemberPaymentDto;
|
|
||||||
fee: MembershipFeeDto;
|
|
||||||
payments: PaymentDto[];
|
|
||||||
prizes: PrizeDto[];
|
|
||||||
prize: PrizeDto;
|
|
||||||
wallet: WalletDto;
|
|
||||||
transactions: TransactionDto[];
|
|
||||||
transaction: TransactionDto;
|
|
||||||
id: string;
|
id: string;
|
||||||
enum: string;
|
|
||||||
amount: number;
|
|
||||||
platformFee: number;
|
|
||||||
netAmount: number;
|
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
|
||||||
required: string;
|
|
||||||
createdAt: string;
|
|
||||||
type: PaymentDto })
|
|
||||||
payment: PaymentDto;
|
|
||||||
paymentId: string;
|
|
||||||
enabled: boolean;
|
|
||||||
updatedAt: string;
|
|
||||||
feeId: string;
|
|
||||||
driverId: string;
|
|
||||||
dueDate: string;
|
|
||||||
seasonId: string;
|
|
||||||
position: number;
|
|
||||||
name: string;
|
|
||||||
awarded: boolean;
|
|
||||||
prizeId: string;
|
|
||||||
success: boolean;
|
|
||||||
balance: number;
|
|
||||||
totalRevenue: number;
|
|
||||||
totalPlatformFees: number;
|
|
||||||
totalWithdrawn: number;
|
|
||||||
currency: string;
|
|
||||||
walletId: string;
|
walletId: string;
|
||||||
description: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,4 @@ export interface UpdateLeagueMemberRoleInputDTO {
|
|||||||
leagueId: string;
|
leagueId: string;
|
||||||
performerDriverId: string;
|
performerDriverId: string;
|
||||||
targetDriverId: string;
|
targetDriverId: string;
|
||||||
enum: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,4 @@
|
|||||||
|
|
||||||
export interface UpdatePaymentStatusInputDTO {
|
export interface UpdatePaymentStatusInputDTO {
|
||||||
paymentId: string;
|
paymentId: string;
|
||||||
enum: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* Auto-generated DTO from OpenAPI spec
|
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface UpdatePaymentStatusOutputDTO {
|
|
||||||
payment: PaymentDTO;
|
|
||||||
type: PaymentDTO })
|
|
||||||
payment: PaymentDTO;
|
|
||||||
}
|
|
||||||
@@ -5,42 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface WalletDto {
|
export interface WalletDto {
|
||||||
payment: MemberPaymentDto;
|
|
||||||
fee: MembershipFeeDto;
|
|
||||||
payments: PaymentDto[];
|
|
||||||
prizes: PrizeDto[];
|
|
||||||
prize: PrizeDto;
|
|
||||||
wallet: WalletDto;
|
|
||||||
transactions: TransactionDto[];
|
|
||||||
transaction: TransactionDto;
|
|
||||||
id: string;
|
id: string;
|
||||||
enum: string;
|
|
||||||
amount: number;
|
|
||||||
platformFee: number;
|
|
||||||
netAmount: number;
|
|
||||||
payerId: string;
|
|
||||||
leagueId: string;
|
leagueId: string;
|
||||||
required: string;
|
|
||||||
createdAt: string;
|
|
||||||
type: PaymentDto })
|
|
||||||
payment: PaymentDto;
|
|
||||||
paymentId: string;
|
|
||||||
enabled: boolean;
|
|
||||||
updatedAt: string;
|
|
||||||
feeId: string;
|
|
||||||
driverId: string;
|
|
||||||
dueDate: string;
|
|
||||||
seasonId: string;
|
|
||||||
position: number;
|
|
||||||
name: string;
|
|
||||||
awarded: boolean;
|
|
||||||
prizeId: string;
|
|
||||||
success: boolean;
|
|
||||||
balance: number;
|
balance: number;
|
||||||
totalRevenue: number;
|
totalRevenue: number;
|
||||||
totalPlatformFees: number;
|
totalPlatformFees: number;
|
||||||
totalWithdrawn: number;
|
totalWithdrawn: number;
|
||||||
|
/** Format: date-time */
|
||||||
|
createdAt: string;
|
||||||
currency: string;
|
currency: string;
|
||||||
walletId: string;
|
|
||||||
description: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface CreateDriverOutputDto {
|
export interface WithdrawFromRaceParamsDTO {
|
||||||
success?: boolean;
|
raceId: string;
|
||||||
driverId?: string;
|
driverId: string;
|
||||||
}
|
}
|
||||||
469
apps/website/lib/types/generated/api.ts
Normal file
469
apps/website/lib/types/generated/api.ts
Normal file
@@ -0,0 +1,469 @@
|
|||||||
|
/**
|
||||||
|
* This file was auto-generated by openapi-typescript.
|
||||||
|
* Do not make direct changes to the file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type paths = Record<string, never>;
|
||||||
|
export type webhooks = Record<string, never>;
|
||||||
|
export interface components {
|
||||||
|
schemas: {
|
||||||
|
SponsorshipPricingItemDTO: {
|
||||||
|
id: string;
|
||||||
|
level: string;
|
||||||
|
price: number;
|
||||||
|
currency: string;
|
||||||
|
};
|
||||||
|
SponsorshipDetailDTO: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
seasonId: string;
|
||||||
|
seasonName: string;
|
||||||
|
};
|
||||||
|
SponsoredLeagueDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
SponsorSponsorshipsDTO: {
|
||||||
|
sponsorId: string;
|
||||||
|
sponsorName: string;
|
||||||
|
};
|
||||||
|
SponsorDashboardMetricsDTO: {
|
||||||
|
impressions: number;
|
||||||
|
impressionsChange: number;
|
||||||
|
uniqueViewers: number;
|
||||||
|
viewersChange: number;
|
||||||
|
races: number;
|
||||||
|
drivers: number;
|
||||||
|
exposure: number;
|
||||||
|
exposureChange: number;
|
||||||
|
};
|
||||||
|
SponsorDashboardInvestmentDTO: {
|
||||||
|
activeSponsorships: number;
|
||||||
|
totalInvestment: number;
|
||||||
|
costPerThousandViews: number;
|
||||||
|
};
|
||||||
|
SponsorDashboardDTO: {
|
||||||
|
sponsorId: string;
|
||||||
|
sponsorName: string;
|
||||||
|
};
|
||||||
|
GetSponsorSponsorshipsQueryParamsDTO: {
|
||||||
|
sponsorId: string;
|
||||||
|
};
|
||||||
|
GetSponsorDashboardQueryParamsDTO: {
|
||||||
|
sponsorId: string;
|
||||||
|
};
|
||||||
|
CreateSponsorInputDTO: {
|
||||||
|
name: string;
|
||||||
|
contactEmail: string;
|
||||||
|
};
|
||||||
|
UpdatePaymentStatusInputDTO: {
|
||||||
|
paymentId: string;
|
||||||
|
};
|
||||||
|
PaymentDto: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
MembershipFeeDto: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
MemberPaymentDto: {
|
||||||
|
id: string;
|
||||||
|
feeId: string;
|
||||||
|
driverId: string;
|
||||||
|
amount: number;
|
||||||
|
platformFee: number;
|
||||||
|
netAmount: number;
|
||||||
|
};
|
||||||
|
PrizeDto: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
seasonId: string;
|
||||||
|
position: number;
|
||||||
|
name: string;
|
||||||
|
amount: number;
|
||||||
|
};
|
||||||
|
WalletDto: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
balance: number;
|
||||||
|
totalRevenue: number;
|
||||||
|
totalPlatformFees: number;
|
||||||
|
totalWithdrawn: number;
|
||||||
|
/** Format: date-time */
|
||||||
|
createdAt: string;
|
||||||
|
currency: string;
|
||||||
|
};
|
||||||
|
TransactionDto: {
|
||||||
|
id: string;
|
||||||
|
walletId: string;
|
||||||
|
};
|
||||||
|
PaymentDTO: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
WithdrawFromRaceParamsDTO: {
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
RequestProtestDefenseCommandDTO: {
|
||||||
|
protestId: string;
|
||||||
|
stewardId: string;
|
||||||
|
};
|
||||||
|
RegisterForRaceParamsDTO: {
|
||||||
|
raceId: string;
|
||||||
|
leagueId: string;
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
RacesPageDataRaceDTO: {
|
||||||
|
id: string;
|
||||||
|
track: string;
|
||||||
|
car: string;
|
||||||
|
scheduledAt: string;
|
||||||
|
status: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
};
|
||||||
|
RaceWithSOFDTO: {
|
||||||
|
id: string;
|
||||||
|
track: string;
|
||||||
|
};
|
||||||
|
RaceStatsDTO: {
|
||||||
|
totalRaces: number;
|
||||||
|
};
|
||||||
|
RaceResultsDetailDTO: {
|
||||||
|
raceId: string;
|
||||||
|
track: string;
|
||||||
|
};
|
||||||
|
RaceResultDTO: {
|
||||||
|
driverId: string;
|
||||||
|
driverName: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
position: number;
|
||||||
|
startPosition: number;
|
||||||
|
incidents: number;
|
||||||
|
fastestLap: number;
|
||||||
|
positionChange: number;
|
||||||
|
isPodium: boolean;
|
||||||
|
isClean: boolean;
|
||||||
|
};
|
||||||
|
RaceProtestDTO: {
|
||||||
|
id: string;
|
||||||
|
protestingDriverId: string;
|
||||||
|
accusedDriverId: string;
|
||||||
|
incident: Record<string, never>;
|
||||||
|
lap: number;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
RacePenaltyDTO: {
|
||||||
|
id: string;
|
||||||
|
driverId: string;
|
||||||
|
type: string;
|
||||||
|
value: number;
|
||||||
|
reason: string;
|
||||||
|
issuedBy: string;
|
||||||
|
issuedAt: string;
|
||||||
|
};
|
||||||
|
RaceDetailUserResultDTO: {
|
||||||
|
position: number;
|
||||||
|
startPosition: number;
|
||||||
|
incidents: number;
|
||||||
|
fastestLap: number;
|
||||||
|
positionChange: number;
|
||||||
|
isPodium: boolean;
|
||||||
|
isClean: boolean;
|
||||||
|
};
|
||||||
|
RaceDetailRegistrationDTO: {
|
||||||
|
isUserRegistered: boolean;
|
||||||
|
canRegister: boolean;
|
||||||
|
};
|
||||||
|
RaceDetailRaceDTO: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
track: string;
|
||||||
|
car: string;
|
||||||
|
scheduledAt: string;
|
||||||
|
sessionType: string;
|
||||||
|
status: string;
|
||||||
|
};
|
||||||
|
RaceDetailLeagueDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
settings: Record<string, never>;
|
||||||
|
maxDrivers?: number;
|
||||||
|
qualifyingFormat?: string;
|
||||||
|
};
|
||||||
|
RaceDetailEntryDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
country: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
};
|
||||||
|
RaceDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
date: string;
|
||||||
|
};
|
||||||
|
RaceActionParamsDTO: {
|
||||||
|
raceId: string;
|
||||||
|
};
|
||||||
|
QuickPenaltyCommandDTO: {
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
adminId: string;
|
||||||
|
};
|
||||||
|
ImportRaceResultsDTO: {
|
||||||
|
raceId: string;
|
||||||
|
resultsFileContent: string;
|
||||||
|
};
|
||||||
|
GetRaceDetailParamsDTODTO: {
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
FileProtestCommandDTO: {
|
||||||
|
raceId: string;
|
||||||
|
protestingDriverId: string;
|
||||||
|
accusedDriverId: string;
|
||||||
|
incident: Record<string, never>;
|
||||||
|
lap: number;
|
||||||
|
description: string;
|
||||||
|
timeInRace?: number;
|
||||||
|
};
|
||||||
|
DashboardRecentResultDTO: {
|
||||||
|
raceId: string;
|
||||||
|
raceName: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
finishedAt: string;
|
||||||
|
position: number;
|
||||||
|
incidents: number;
|
||||||
|
};
|
||||||
|
DashboardRaceSummaryDTO: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
track: string;
|
||||||
|
car: string;
|
||||||
|
scheduledAt: string;
|
||||||
|
};
|
||||||
|
DashboardLeagueStandingSummaryDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
leagueName: string;
|
||||||
|
position: number;
|
||||||
|
totalDrivers: number;
|
||||||
|
points: number;
|
||||||
|
};
|
||||||
|
DashboardFriendSummaryDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
country: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
};
|
||||||
|
DashboardFeedSummaryDTO: {
|
||||||
|
notificationCount: number;
|
||||||
|
};
|
||||||
|
DashboardFeedItemSummaryDTO: {
|
||||||
|
id: string;
|
||||||
|
enum: string;
|
||||||
|
};
|
||||||
|
DashboardDriverSummaryDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
country: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
};
|
||||||
|
ApplyPenaltyCommandDTO: {
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
stewardId: string;
|
||||||
|
enum: string;
|
||||||
|
};
|
||||||
|
RequestAvatarGenerationInputDTO: {
|
||||||
|
userId: string;
|
||||||
|
facePhotoData: string;
|
||||||
|
suitColor: string;
|
||||||
|
};
|
||||||
|
UpdateLeagueMemberRoleOutputDTO: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
UpdateLeagueMemberRoleInputDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
performerDriverId: string;
|
||||||
|
targetDriverId: string;
|
||||||
|
};
|
||||||
|
SeasonDTO: {
|
||||||
|
seasonId: string;
|
||||||
|
name: string;
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
RemoveLeagueMemberOutputDTO: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
RemoveLeagueMemberInputDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
performerDriverId: string;
|
||||||
|
targetDriverId: string;
|
||||||
|
};
|
||||||
|
RejectJoinRequestOutputDTO: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
RejectJoinRequestInputDTO: {
|
||||||
|
requestId: string;
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
ProtestDTO: {
|
||||||
|
id: string;
|
||||||
|
raceId: string;
|
||||||
|
protestingDriverId: string;
|
||||||
|
accusedDriverId: string;
|
||||||
|
/** Format: date-time */
|
||||||
|
submittedAt: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
LeagueWithCapacityDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
LeagueSummaryDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
LeagueStatsDTO: {
|
||||||
|
totalMembers: number;
|
||||||
|
totalRaces: number;
|
||||||
|
averageRating: number;
|
||||||
|
};
|
||||||
|
LeagueStandingDTO: {
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
LeagueSeasonSummaryDTO: {
|
||||||
|
seasonId: string;
|
||||||
|
name: string;
|
||||||
|
status: string;
|
||||||
|
};
|
||||||
|
LeagueMemberDTO: {
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
LeagueJoinRequestDTO: {
|
||||||
|
id: string;
|
||||||
|
leagueId: string;
|
||||||
|
driverId: string;
|
||||||
|
/** Format: date-time */
|
||||||
|
requestedAt: string;
|
||||||
|
};
|
||||||
|
LeagueConfigFormModelTimingsDTO: {
|
||||||
|
raceDayOfWeek: string;
|
||||||
|
raceTimeHour: number;
|
||||||
|
raceTimeMinute: number;
|
||||||
|
};
|
||||||
|
LeagueConfigFormModelStructureDTO: {
|
||||||
|
mode: string;
|
||||||
|
};
|
||||||
|
LeagueConfigFormModelScoringDTO: {
|
||||||
|
type: string;
|
||||||
|
points: number;
|
||||||
|
};
|
||||||
|
LeagueConfigFormModelDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
LeagueConfigFormModelBasicsDTO: {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
LeagueAdminPermissionsDTO: {
|
||||||
|
canRemoveMember: boolean;
|
||||||
|
canUpdateRoles: boolean;
|
||||||
|
};
|
||||||
|
GetLeagueSeasonsQueryDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
GetLeagueProtestsQueryDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
GetLeagueOwnerSummaryQueryDTO: {
|
||||||
|
ownerId: string;
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
GetLeagueJoinRequestsQueryDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
GetLeagueAdminPermissionsInputDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
performerDriverId: string;
|
||||||
|
};
|
||||||
|
GetLeagueAdminConfigQueryDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
CreateLeagueOutputDTO: {
|
||||||
|
leagueId: string;
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
CreateLeagueInputDTO: {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
ApproveJoinRequestOutputDTO: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
ApproveJoinRequestInputDTO: {
|
||||||
|
requestId: string;
|
||||||
|
leagueId: string;
|
||||||
|
};
|
||||||
|
GetDriverRegistrationStatusQueryDTO: {
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
DriverStatsDTO: {
|
||||||
|
totalDrivers: number;
|
||||||
|
};
|
||||||
|
DriverRegistrationStatusDTO: {
|
||||||
|
isRegistered: boolean;
|
||||||
|
raceId: string;
|
||||||
|
driverId: string;
|
||||||
|
};
|
||||||
|
DriverLeaderboardItemDTO: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
rating: number;
|
||||||
|
skillLevel: string;
|
||||||
|
nationality: string;
|
||||||
|
racesCompleted: number;
|
||||||
|
wins: number;
|
||||||
|
podiums: number;
|
||||||
|
isActive: boolean;
|
||||||
|
rank: number;
|
||||||
|
};
|
||||||
|
CompleteOnboardingOutputDTO: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
CompleteOnboardingInputDTO: {
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
displayName: string;
|
||||||
|
country: string;
|
||||||
|
};
|
||||||
|
AuthenticatedUserDTO: {
|
||||||
|
userId: string;
|
||||||
|
email: string;
|
||||||
|
displayName: string;
|
||||||
|
};
|
||||||
|
AuthSessionDTO: {
|
||||||
|
token: string;
|
||||||
|
user: components["schemas"]["AuthenticatedUserDTO"];
|
||||||
|
};
|
||||||
|
RecordPageViewOutputDTO: {
|
||||||
|
pageViewId: string;
|
||||||
|
};
|
||||||
|
RecordEngagementOutputDTO: {
|
||||||
|
eventId: string;
|
||||||
|
engagementWeight: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: never;
|
||||||
|
parameters: never;
|
||||||
|
requestBodies: never;
|
||||||
|
headers: never;
|
||||||
|
pathItems: never;
|
||||||
|
}
|
||||||
|
export type $defs = Record<string, never>;
|
||||||
|
export type operations = Record<string, never>;
|
||||||
99
apps/website/lib/types/generated/index.ts
Normal file
99
apps/website/lib/types/generated/index.ts
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Auto-generated DTO type exports
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Re-export all schema types from the generated OpenAPI types
|
||||||
|
export type { components, paths, operations } from './api';
|
||||||
|
|
||||||
|
// Re-export individual DTO types
|
||||||
|
export type { SponsorshipPricingItemDTO } from './SponsorshipPricingItemDTO';
|
||||||
|
export type { SponsorshipDetailDTO } from './SponsorshipDetailDTO';
|
||||||
|
export type { SponsoredLeagueDTO } from './SponsoredLeagueDTO';
|
||||||
|
export type { SponsorSponsorshipsDTO } from './SponsorSponsorshipsDTO';
|
||||||
|
export type { SponsorDashboardMetricsDTO } from './SponsorDashboardMetricsDTO';
|
||||||
|
export type { SponsorDashboardInvestmentDTO } from './SponsorDashboardInvestmentDTO';
|
||||||
|
export type { SponsorDashboardDTO } from './SponsorDashboardDTO';
|
||||||
|
export type { GetSponsorSponsorshipsQueryParamsDTO } from './GetSponsorSponsorshipsQueryParamsDTO';
|
||||||
|
export type { GetSponsorDashboardQueryParamsDTO } from './GetSponsorDashboardQueryParamsDTO';
|
||||||
|
export type { CreateSponsorInputDTO } from './CreateSponsorInputDTO';
|
||||||
|
export type { UpdatePaymentStatusInputDTO } from './UpdatePaymentStatusInputDTO';
|
||||||
|
export type { PaymentDto } from './PaymentDto';
|
||||||
|
export type { MembershipFeeDto } from './MembershipFeeDto';
|
||||||
|
export type { MemberPaymentDto } from './MemberPaymentDto';
|
||||||
|
export type { PrizeDto } from './PrizeDto';
|
||||||
|
export type { WalletDto } from './WalletDto';
|
||||||
|
export type { TransactionDto } from './TransactionDto';
|
||||||
|
export type { PaymentDTO } from './PaymentDTO';
|
||||||
|
export type { WithdrawFromRaceParamsDTO } from './WithdrawFromRaceParamsDTO';
|
||||||
|
export type { RequestProtestDefenseCommandDTO } from './RequestProtestDefenseCommandDTO';
|
||||||
|
export type { RegisterForRaceParamsDTO } from './RegisterForRaceParamsDTO';
|
||||||
|
export type { RacesPageDataRaceDTO } from './RacesPageDataRaceDTO';
|
||||||
|
export type { RaceWithSOFDTO } from './RaceWithSOFDTO';
|
||||||
|
export type { RaceStatsDTO } from './RaceStatsDTO';
|
||||||
|
export type { RaceResultsDetailDTO } from './RaceResultsDetailDTO';
|
||||||
|
export type { RaceResultDTO } from './RaceResultDTO';
|
||||||
|
export type { RaceProtestDTO } from './RaceProtestDTO';
|
||||||
|
export type { RacePenaltyDTO } from './RacePenaltyDTO';
|
||||||
|
export type { RaceDetailUserResultDTO } from './RaceDetailUserResultDTO';
|
||||||
|
export type { RaceDetailRegistrationDTO } from './RaceDetailRegistrationDTO';
|
||||||
|
export type { RaceDetailRaceDTO } from './RaceDetailRaceDTO';
|
||||||
|
export type { RaceDetailLeagueDTO } from './RaceDetailLeagueDTO';
|
||||||
|
export type { RaceDetailEntryDTO } from './RaceDetailEntryDTO';
|
||||||
|
export type { RaceDTO } from './RaceDTO';
|
||||||
|
export type { RaceActionParamsDTO } from './RaceActionParamsDTO';
|
||||||
|
export type { QuickPenaltyCommandDTO } from './QuickPenaltyCommandDTO';
|
||||||
|
export type { ImportRaceResultsDTO } from './ImportRaceResultsDTO';
|
||||||
|
export type { GetRaceDetailParamsDTODTO } from './GetRaceDetailParamsDTODTO';
|
||||||
|
export type { FileProtestCommandDTO } from './FileProtestCommandDTO';
|
||||||
|
export type { DashboardRecentResultDTO } from './DashboardRecentResultDTO';
|
||||||
|
export type { DashboardRaceSummaryDTO } from './DashboardRaceSummaryDTO';
|
||||||
|
export type { DashboardLeagueStandingSummaryDTO } from './DashboardLeagueStandingSummaryDTO';
|
||||||
|
export type { DashboardFriendSummaryDTO } from './DashboardFriendSummaryDTO';
|
||||||
|
export type { DashboardFeedSummaryDTO } from './DashboardFeedSummaryDTO';
|
||||||
|
export type { DashboardFeedItemSummaryDTO } from './DashboardFeedItemSummaryDTO';
|
||||||
|
export type { DashboardDriverSummaryDTO } from './DashboardDriverSummaryDTO';
|
||||||
|
export type { ApplyPenaltyCommandDTO } from './ApplyPenaltyCommandDTO';
|
||||||
|
export type { RequestAvatarGenerationInputDTO } from './RequestAvatarGenerationInputDTO';
|
||||||
|
export type { UpdateLeagueMemberRoleOutputDTO } from './UpdateLeagueMemberRoleOutputDTO';
|
||||||
|
export type { UpdateLeagueMemberRoleInputDTO } from './UpdateLeagueMemberRoleInputDTO';
|
||||||
|
export type { SeasonDTO } from './SeasonDTO';
|
||||||
|
export type { RemoveLeagueMemberOutputDTO } from './RemoveLeagueMemberOutputDTO';
|
||||||
|
export type { RemoveLeagueMemberInputDTO } from './RemoveLeagueMemberInputDTO';
|
||||||
|
export type { RejectJoinRequestOutputDTO } from './RejectJoinRequestOutputDTO';
|
||||||
|
export type { RejectJoinRequestInputDTO } from './RejectJoinRequestInputDTO';
|
||||||
|
export type { ProtestDTO } from './ProtestDTO';
|
||||||
|
export type { LeagueWithCapacityDTO } from './LeagueWithCapacityDTO';
|
||||||
|
export type { LeagueSummaryDTO } from './LeagueSummaryDTO';
|
||||||
|
export type { LeagueStatsDTO } from './LeagueStatsDTO';
|
||||||
|
export type { LeagueStandingDTO } from './LeagueStandingDTO';
|
||||||
|
export type { LeagueSeasonSummaryDTO } from './LeagueSeasonSummaryDTO';
|
||||||
|
export type { LeagueMemberDTO } from './LeagueMemberDTO';
|
||||||
|
export type { LeagueJoinRequestDTO } from './LeagueJoinRequestDTO';
|
||||||
|
export type { LeagueConfigFormModelTimingsDTO } from './LeagueConfigFormModelTimingsDTO';
|
||||||
|
export type { LeagueConfigFormModelStructureDTO } from './LeagueConfigFormModelStructureDTO';
|
||||||
|
export type { LeagueConfigFormModelScoringDTO } from './LeagueConfigFormModelScoringDTO';
|
||||||
|
export type { LeagueConfigFormModelDTO } from './LeagueConfigFormModelDTO';
|
||||||
|
export type { LeagueConfigFormModelBasicsDTO } from './LeagueConfigFormModelBasicsDTO';
|
||||||
|
export type { LeagueAdminPermissionsDTO } from './LeagueAdminPermissionsDTO';
|
||||||
|
export type { GetLeagueSeasonsQueryDTO } from './GetLeagueSeasonsQueryDTO';
|
||||||
|
export type { GetLeagueProtestsQueryDTO } from './GetLeagueProtestsQueryDTO';
|
||||||
|
export type { GetLeagueOwnerSummaryQueryDTO } from './GetLeagueOwnerSummaryQueryDTO';
|
||||||
|
export type { GetLeagueJoinRequestsQueryDTO } from './GetLeagueJoinRequestsQueryDTO';
|
||||||
|
export type { GetLeagueAdminPermissionsInputDTO } from './GetLeagueAdminPermissionsInputDTO';
|
||||||
|
export type { GetLeagueAdminConfigQueryDTO } from './GetLeagueAdminConfigQueryDTO';
|
||||||
|
export type { CreateLeagueOutputDTO } from './CreateLeagueOutputDTO';
|
||||||
|
export type { CreateLeagueInputDTO } from './CreateLeagueInputDTO';
|
||||||
|
export type { ApproveJoinRequestOutputDTO } from './ApproveJoinRequestOutputDTO';
|
||||||
|
export type { ApproveJoinRequestInputDTO } from './ApproveJoinRequestInputDTO';
|
||||||
|
export type { GetDriverRegistrationStatusQueryDTO } from './GetDriverRegistrationStatusQueryDTO';
|
||||||
|
export type { DriverStatsDTO } from './DriverStatsDTO';
|
||||||
|
export type { DriverRegistrationStatusDTO } from './DriverRegistrationStatusDTO';
|
||||||
|
export type { DriverLeaderboardItemDTO } from './DriverLeaderboardItemDTO';
|
||||||
|
export type { CompleteOnboardingOutputDTO } from './CompleteOnboardingOutputDTO';
|
||||||
|
export type { CompleteOnboardingInputDTO } from './CompleteOnboardingInputDTO';
|
||||||
|
export type { AuthenticatedUserDTO } from './AuthenticatedUserDTO';
|
||||||
|
export type { AuthSessionDTO } from './AuthSessionDTO';
|
||||||
|
export type { RecordPageViewOutputDTO } from './RecordPageViewOutputDTO';
|
||||||
|
export type { RecordEngagementOutputDTO } from './RecordEngagementOutputDTO';
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"docker:prod:logs": "docker-compose -f docker-compose.prod.yml logs -f",
|
"docker:prod:logs": "docker-compose -f docker-compose.prod.yml logs -f",
|
||||||
"docker:prod:clean": "docker-compose -f docker-compose.prod.yml down -v",
|
"docker:prod:clean": "docker-compose -f docker-compose.prod.yml down -v",
|
||||||
"api:build": "npm run build --workspace=@gridpilot/api",
|
"api:build": "npm run build --workspace=@gridpilot/api",
|
||||||
"api:generate-spec": "tsx scripts/generate-openapi-from-dtos.ts",
|
"api:generate-spec": "tsx scripts/generate-openapi-spec.ts",
|
||||||
"api:generate-types": "tsx scripts/generate-api-types.ts",
|
"api:generate-types": "tsx scripts/generate-api-types.ts",
|
||||||
"api:sync-types": "npm run api:generate-spec && npm run api:generate-types",
|
"api:sync-types": "npm run api:generate-spec && npm run api:generate-types",
|
||||||
"test": "vitest run \"$@\"",
|
"test": "vitest run \"$@\"",
|
||||||
|
|||||||
@@ -1,113 +1,238 @@
|
|||||||
#!/usr/bin/env tsx
|
#!/usr/bin/env tsx
|
||||||
|
/**
|
||||||
|
* Generate TypeScript types from OpenAPI spec
|
||||||
|
*
|
||||||
|
* This script uses openapi-typescript to generate proper TypeScript types
|
||||||
|
* from the OpenAPI spec that NestJS/Swagger generates.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* 1. First generate the OpenAPI spec: npm run api:generate-spec
|
||||||
|
* 2. Then generate types: npm run api:generate-types
|
||||||
|
*
|
||||||
|
* Or use: npm run api:sync-types (runs both)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { execSync } from 'child_process';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
async function generateIndividualDTOs() {
|
async function generateTypes() {
|
||||||
const openapiPath = path.join(__dirname, '../apps/api/openapi.json');
|
const openapiPath = path.join(__dirname, '../apps/api/openapi.json');
|
||||||
const outputDir = path.join(__dirname, '../apps/website/lib/types/generated');
|
const outputDir = path.join(__dirname, '../apps/website/lib/types/generated');
|
||||||
|
const outputFile = path.join(outputDir, 'api.ts');
|
||||||
|
|
||||||
console.log('🔄 Generating individual DTO files from OpenAPI spec...');
|
console.log('🔄 Generating TypeScript types from OpenAPI spec...');
|
||||||
|
|
||||||
|
// Check if OpenAPI spec exists
|
||||||
try {
|
try {
|
||||||
// Check if OpenAPI spec exists
|
|
||||||
await fs.access(openapiPath);
|
await fs.access(openapiPath);
|
||||||
} catch {
|
} catch {
|
||||||
console.error(`❌ OpenAPI spec not found at: ${openapiPath}`);
|
console.error(`❌ OpenAPI spec not found at: ${openapiPath}`);
|
||||||
console.error('Run "npm run api:generate-spec" first');
|
console.error('Run "npm run api:generate-spec" first to generate the OpenAPI spec from NestJS');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure output directory exists
|
||||||
|
await fs.mkdir(outputDir, { recursive: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Read the OpenAPI spec
|
// Use openapi-typescript to generate types
|
||||||
const specContent = await fs.readFile(openapiPath, 'utf-8');
|
console.log('📝 Running openapi-typescript...');
|
||||||
const spec = JSON.parse(specContent);
|
execSync(`npx openapi-typescript "${openapiPath}" -o "${outputFile}"`, {
|
||||||
|
stdio: 'inherit',
|
||||||
// Ensure output directory exists
|
cwd: path.join(__dirname, '..')
|
||||||
await fs.mkdir(outputDir, { recursive: true });
|
});
|
||||||
|
|
||||||
// Extract schemas from the spec
|
|
||||||
const schemas = spec.components?.schemas || {};
|
|
||||||
|
|
||||||
console.log(`📝 Found ${Object.keys(schemas).length} schemas to generate`);
|
|
||||||
|
|
||||||
// Generate individual files for each schema
|
|
||||||
for (const [schemaName, schema] of Object.entries(schemas)) {
|
|
||||||
if (typeof schema === 'object' && schema !== null) {
|
|
||||||
const fileName = `${schemaName}.ts`;
|
|
||||||
const filePath = path.join(outputDir, fileName);
|
|
||||||
|
|
||||||
// Convert OpenAPI schema to TypeScript interface
|
|
||||||
const tsInterface = generateTypeScriptInterface(schemaName, schema);
|
|
||||||
|
|
||||||
await fs.writeFile(filePath, tsInterface);
|
|
||||||
console.log(`✅ Generated ${fileName}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`🎉 Generated ${Object.keys(schemas).length} DTO files in ${outputDir}`);
|
|
||||||
|
|
||||||
|
console.log(`✅ TypeScript types generated at: ${outputFile}`);
|
||||||
|
|
||||||
|
// Generate individual DTO files
|
||||||
|
await generateIndividualDtoFiles(openapiPath, outputDir);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Failed to generate DTOs:', error);
|
console.error('❌ Failed to generate types:', error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateTypeScriptInterface(name: string, schema: any): string {
|
async function generateIndividualDtoFiles(openapiPath: string, outputDir: string) {
|
||||||
const properties = schema.properties || {};
|
console.log('📝 Generating individual DTO files...');
|
||||||
const required = schema.required || [];
|
|
||||||
|
const specContent = await fs.readFile(openapiPath, 'utf-8');
|
||||||
|
const spec = JSON.parse(specContent);
|
||||||
|
const schemas = spec.components?.schemas || {};
|
||||||
|
|
||||||
|
const schemaNames = Object.keys(schemas);
|
||||||
|
|
||||||
|
// Generate individual files for each schema
|
||||||
|
for (const schemaName of schemaNames) {
|
||||||
|
const schema = schemas[schemaName];
|
||||||
|
const fileName = `${schemaName}.ts`;
|
||||||
|
const filePath = path.join(outputDir, fileName);
|
||||||
|
|
||||||
|
const fileContent = generateDtoFileContent(schemaName, schema, schemas);
|
||||||
|
await fs.writeFile(filePath, fileContent);
|
||||||
|
console.log(` ✅ Generated ${fileName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate index file that re-exports all DTOs
|
||||||
|
let indexContent = `/**
|
||||||
|
* Auto-generated DTO type exports
|
||||||
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
|
*/
|
||||||
|
|
||||||
let interfaceContent = `/**
|
// Re-export all schema types from the generated OpenAPI types
|
||||||
|
export type { components, paths, operations } from './api';
|
||||||
|
|
||||||
|
// Re-export individual DTO types
|
||||||
|
`;
|
||||||
|
|
||||||
|
for (const schemaName of schemaNames) {
|
||||||
|
indexContent += `export type { ${schemaName} } from './${schemaName}';\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexPath = path.join(outputDir, 'index.ts');
|
||||||
|
await fs.writeFile(indexPath, indexContent);
|
||||||
|
|
||||||
|
console.log(`✅ Generated ${schemaNames.length} individual DTO files and index at: ${outputDir}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateDtoFileContent(schemaName: string, schema: any, allSchemas: Record<string, any>): string {
|
||||||
|
// Collect dependencies (referenced DTOs)
|
||||||
|
const dependencies = new Set<string>();
|
||||||
|
collectDependencies(schema, dependencies, allSchemas);
|
||||||
|
dependencies.delete(schemaName); // Remove self-reference
|
||||||
|
|
||||||
|
let content = `/**
|
||||||
* Auto-generated DTO from OpenAPI spec
|
* Auto-generated DTO from OpenAPI spec
|
||||||
* This file is generated by scripts/generate-api-types.ts
|
* This file is generated by scripts/generate-api-types.ts
|
||||||
* Do not edit manually - regenerate using: npm run api:sync-types
|
* Do not edit manually - regenerate using: npm run api:sync-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface ${name} {\n`;
|
`;
|
||||||
|
|
||||||
for (const [propName, propSchema] of Object.entries(properties)) {
|
// Add imports for dependencies
|
||||||
const isRequired = required.includes(propName);
|
for (const dep of dependencies) {
|
||||||
const optionalMark = isRequired ? '' : '?';
|
content += `import type { ${dep} } from './${dep}';\n`;
|
||||||
const type = openApiTypeToTypeScript(propSchema);
|
}
|
||||||
|
|
||||||
interfaceContent += ` ${propName}${optionalMark}: ${type};\n`;
|
if (dependencies.size > 0) {
|
||||||
|
content += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaceContent += '}\n';
|
// Generate interface
|
||||||
|
content += `export interface ${schemaName} {\n`;
|
||||||
return interfaceContent;
|
|
||||||
|
const properties = schema.properties || {};
|
||||||
|
const required = new Set(schema.required || []);
|
||||||
|
|
||||||
|
for (const [propName, propSchema] of Object.entries(properties)) {
|
||||||
|
const isRequired = required.has(propName);
|
||||||
|
const optionalMark = isRequired ? '' : '?';
|
||||||
|
const typeStr = schemaToTypeString(propSchema as any);
|
||||||
|
|
||||||
|
// Add JSDoc comment for format
|
||||||
|
if ((propSchema as any).format) {
|
||||||
|
content += ` /** Format: ${(propSchema as any).format} */\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
content += ` ${propName}${optionalMark}: ${typeStr};\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
content += '}\n';
|
||||||
|
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
function openApiTypeToTypeScript(schema: any): string {
|
function collectDependencies(schema: any, deps: Set<string>, allSchemas: Record<string, any>): void {
|
||||||
|
if (!schema) return;
|
||||||
|
|
||||||
if (schema.$ref) {
|
if (schema.$ref) {
|
||||||
// Handle references
|
|
||||||
const refName = schema.$ref.split('/').pop();
|
const refName = schema.$ref.split('/').pop();
|
||||||
return refName;
|
if (refName && allSchemas[refName]) {
|
||||||
|
deps.add(refName);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (schema.type === 'array' && schema.items) {
|
||||||
|
collectDependencies(schema.items, deps, allSchemas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.properties) {
|
||||||
|
for (const propSchema of Object.values(schema.properties)) {
|
||||||
|
collectDependencies(propSchema, deps, allSchemas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.oneOf) {
|
||||||
|
for (const subSchema of schema.oneOf) {
|
||||||
|
collectDependencies(subSchema, deps, allSchemas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.anyOf) {
|
||||||
|
for (const subSchema of schema.anyOf) {
|
||||||
|
collectDependencies(subSchema, deps, allSchemas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.allOf) {
|
||||||
|
for (const subSchema of schema.allOf) {
|
||||||
|
collectDependencies(subSchema, deps, allSchemas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function schemaToTypeString(schema: any): string {
|
||||||
|
if (!schema) return 'unknown';
|
||||||
|
|
||||||
|
if (schema.$ref) {
|
||||||
|
return schema.$ref.split('/').pop() || 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
if (schema.type === 'array') {
|
if (schema.type === 'array') {
|
||||||
const itemType = openApiTypeToTypeScript(schema.items);
|
const itemType = schemaToTypeString(schema.items);
|
||||||
return `${itemType}[]`;
|
return `${itemType}[]`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.type === 'object') {
|
if (schema.type === 'object') {
|
||||||
// For complex objects, we'll use a generic Record for now
|
if (schema.properties) {
|
||||||
return 'Record<string, any>';
|
// Inline object type
|
||||||
|
const props = Object.entries(schema.properties)
|
||||||
|
.map(([key, val]) => `${key}: ${schemaToTypeString(val as any)}`)
|
||||||
|
.join('; ');
|
||||||
|
return `{ ${props} }`;
|
||||||
|
}
|
||||||
|
return 'Record<string, unknown>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (schema.oneOf) {
|
||||||
|
return schema.oneOf.map((s: any) => schemaToTypeString(s)).join(' | ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.anyOf) {
|
||||||
|
return schema.anyOf.map((s: any) => schemaToTypeString(s)).join(' | ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.enum) {
|
||||||
|
return schema.enum.map((v: any) => JSON.stringify(v)).join(' | ');
|
||||||
|
}
|
||||||
|
|
||||||
switch (schema.type) {
|
switch (schema.type) {
|
||||||
case 'string':
|
case 'string':
|
||||||
if (schema.format === 'date-time') {
|
|
||||||
return 'string'; // Keep as string for now, could be Date
|
|
||||||
}
|
|
||||||
return 'string';
|
return 'string';
|
||||||
case 'number':
|
case 'number':
|
||||||
case 'integer':
|
case 'integer':
|
||||||
return 'number';
|
return 'number';
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
return 'boolean';
|
return 'boolean';
|
||||||
|
case 'null':
|
||||||
|
return 'null';
|
||||||
default:
|
default:
|
||||||
return 'any';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateIndividualDTOs().catch(console.error);
|
generateTypes().catch(console.error);
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
#!/usr/bin/env tsx
|
|
||||||
import fs from 'fs/promises';
|
|
||||||
import path from 'path';
|
|
||||||
import { glob } from 'glob';
|
|
||||||
|
|
||||||
// Comprehensive OpenAPI spec generator that scans all DTO files
|
|
||||||
async function generateComprehensiveOpenAPISpec() {
|
|
||||||
console.log('🔄 Generating comprehensive OpenAPI spec from all DTO files...');
|
|
||||||
|
|
||||||
const schemas: Record<string, any> = {};
|
|
||||||
|
|
||||||
// Find all DTO files in the API
|
|
||||||
const dtoFiles = await glob('apps/api/src/domain/*/dtos/**/*.ts', {
|
|
||||||
cwd: path.join(__dirname, '..')
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`📁 Found ${dtoFiles.length} DTO files to process`);
|
|
||||||
|
|
||||||
for (const dtoFile of dtoFiles) {
|
|
||||||
const filePath = path.join(__dirname, '..', dtoFile);
|
|
||||||
await processDTOFile(filePath, schemas);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also check for DTOs in other locations
|
|
||||||
const additionalDtoFiles = await glob('apps/api/src/domain/*/*.ts', {
|
|
||||||
cwd: path.join(__dirname, '..')
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const dtoFile of additionalDtoFiles) {
|
|
||||||
if (dtoFile.includes('dto') || dtoFile.includes('DTO')) {
|
|
||||||
const filePath = path.join(__dirname, '..', dtoFile);
|
|
||||||
await processDTOFile(filePath, schemas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const spec = {
|
|
||||||
openapi: '3.0.0',
|
|
||||||
info: {
|
|
||||||
title: 'GridPilot API',
|
|
||||||
description: 'GridPilot API documentation',
|
|
||||||
version: '1.0.0'
|
|
||||||
},
|
|
||||||
paths: {},
|
|
||||||
components: {
|
|
||||||
schemas
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const outputPath = path.join(__dirname, '../apps/api/openapi.json');
|
|
||||||
await fs.writeFile(outputPath, JSON.stringify(spec, null, 2));
|
|
||||||
|
|
||||||
console.log(`✅ Comprehensive OpenAPI spec generated with ${Object.keys(schemas).length} schemas at: ${outputPath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processDTOFile(filePath: string, schemas: Record<string, any>) {
|
|
||||||
try {
|
|
||||||
const content = await fs.readFile(filePath, 'utf-8');
|
|
||||||
|
|
||||||
// Extract all class and interface definitions
|
|
||||||
const classMatches = content.match(/export (?:class|interface) (\w+(?:DTO|Dto))/g);
|
|
||||||
if (!classMatches) {
|
|
||||||
// Debug: check if file has any export statements
|
|
||||||
if (content.includes('export')) {
|
|
||||||
console.log(`📄 ${filePath} has exports but no DTO classes`);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`📄 Processing ${filePath} - found ${classMatches.length} DTO classes`);
|
|
||||||
|
|
||||||
for (const classMatch of classMatches) {
|
|
||||||
const classNameMatch = classMatch.match(/export (?:class|interface) (\w+(?:DTO|Dto))/);
|
|
||||||
if (classNameMatch) {
|
|
||||||
const className = classNameMatch[1];
|
|
||||||
console.log(` 🔍 Extracting schema for ${className}`);
|
|
||||||
const schema = extractSchemaFromClass(content, className);
|
|
||||||
if (schema && Object.keys(schema.properties || {}).length > 0) {
|
|
||||||
schemas[className] = schema;
|
|
||||||
console.log(` ✅ Added schema for ${className} with ${Object.keys(schema.properties).length} properties`);
|
|
||||||
} else {
|
|
||||||
console.log(` ⚠️ No schema generated for ${className}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// File can't be read, continue
|
|
||||||
console.warn(`⚠️ Could not process ${filePath}:`, error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractSchemaFromClass(content: string, className: string): any | null {
|
|
||||||
const properties: Record<string, any> = {};
|
|
||||||
const required: string[] = [];
|
|
||||||
|
|
||||||
// Extract @ApiProperty decorated properties from NestJS DTOs
|
|
||||||
// Pattern: @ApiProperty(...) followed by property declaration
|
|
||||||
const lines = content.split('\n');
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
while (i < lines.length) {
|
|
||||||
const line = lines[i].trim();
|
|
||||||
|
|
||||||
// Look for @ApiProperty decorator
|
|
||||||
if (line.startsWith('@ApiProperty(')) {
|
|
||||||
const decoratorMatch = line.match(/@ApiProperty\(([^)]*)\)/);
|
|
||||||
if (decoratorMatch) {
|
|
||||||
const decoratorContent = decoratorMatch[1];
|
|
||||||
|
|
||||||
// Find the property declaration (could be on next line)
|
|
||||||
let propertyLine = line;
|
|
||||||
if (!line.includes(';')) {
|
|
||||||
i++;
|
|
||||||
if (i < lines.length) {
|
|
||||||
propertyLine = lines[i].trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract property name and type from declaration
|
|
||||||
const propertyMatch = propertyLine.match(/(\w+)\s*\??:\s*([^;]+);/);
|
|
||||||
if (propertyMatch) {
|
|
||||||
const propertyName = propertyMatch[1];
|
|
||||||
const propertyType = propertyMatch[2].trim();
|
|
||||||
|
|
||||||
// Check if property is required
|
|
||||||
const isOptional = propertyName.includes('?') ||
|
|
||||||
decoratorContent.includes('required: false') ||
|
|
||||||
decoratorContent.includes('nullable: true') ||
|
|
||||||
propertyLine.includes('@IsOptional()');
|
|
||||||
|
|
||||||
if (!isOptional) {
|
|
||||||
required.push(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to extract type from decorator first, then fall back to property type
|
|
||||||
let schemaType = extractTypeFromDecorator(decoratorContent);
|
|
||||||
if (!schemaType) {
|
|
||||||
schemaType = mapTypeToSchema(propertyType);
|
|
||||||
}
|
|
||||||
|
|
||||||
properties[propertyName] = schemaType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also extract interface properties (for existing interfaces)
|
|
||||||
const interfacePropertyRegex = /(\w+)\s*\??:\s*([^;]+);/g;
|
|
||||||
let match;
|
|
||||||
while ((match = interfacePropertyRegex.exec(content)) !== null) {
|
|
||||||
const propertyName = match[1];
|
|
||||||
const propertyType = match[2].trim();
|
|
||||||
|
|
||||||
if (!properties[propertyName]) {
|
|
||||||
// Check if property is required
|
|
||||||
if (!propertyName.includes('?')) {
|
|
||||||
required.push(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
properties[propertyName] = mapTypeToSchema(propertyType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(properties).length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const schema: any = {
|
|
||||||
type: 'object',
|
|
||||||
properties
|
|
||||||
};
|
|
||||||
|
|
||||||
if (required.length > 0) {
|
|
||||||
schema.required = required;
|
|
||||||
}
|
|
||||||
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractTypeFromDecorator(decoratorContent: string): any | null {
|
|
||||||
// Extract type information from @ApiProperty decorator
|
|
||||||
// Examples:
|
|
||||||
// @ApiProperty({ type: String })
|
|
||||||
// @ApiProperty({ type: [SomeDTO] })
|
|
||||||
// @ApiProperty({ type: () => SomeDTO })
|
|
||||||
|
|
||||||
if (decoratorContent.includes('type:')) {
|
|
||||||
// Simple type extraction - this is a simplified version
|
|
||||||
// In a real implementation, you'd want proper AST parsing
|
|
||||||
|
|
||||||
if (decoratorContent.includes('[String]') || decoratorContent.includes('[string]')) {
|
|
||||||
return { type: 'array', items: { type: 'string' } };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoratorContent.includes('[Number]') || decoratorContent.includes('[number]')) {
|
|
||||||
return { type: 'array', items: { type: 'number' } };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoratorContent.includes('String') || decoratorContent.includes('string')) {
|
|
||||||
return { type: 'string' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoratorContent.includes('Number') || decoratorContent.includes('number')) {
|
|
||||||
return { type: 'number' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoratorContent.includes('Boolean') || decoratorContent.includes('boolean')) {
|
|
||||||
return { type: 'boolean' };
|
|
||||||
}
|
|
||||||
|
|
||||||
// For complex types with references
|
|
||||||
const refMatch = decoratorContent.match(/type:\s*\[?(\w+DTO)\]?/);
|
|
||||||
if (refMatch) {
|
|
||||||
const refType = refMatch[1];
|
|
||||||
if (decoratorContent.includes('[')) {
|
|
||||||
return { type: 'array', items: { $ref: `#/components/schemas/${refType}` } };
|
|
||||||
} else {
|
|
||||||
return { $ref: `#/components/schemas/${refType}` };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For function types like type: () => SomeDTO
|
|
||||||
const funcMatch = decoratorContent.match(/type:\s*\(\)\s*=>\s*(\w+DTO)/);
|
|
||||||
if (funcMatch) {
|
|
||||||
return { $ref: `#/components/schemas/${funcMatch[1]}` };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapTypeToSchema(type: string): any {
|
|
||||||
// Clean up the type
|
|
||||||
type = type.replace(/[|;]/g, '').trim();
|
|
||||||
|
|
||||||
// Handle array types
|
|
||||||
if (type.endsWith('[]')) {
|
|
||||||
const itemType = type.slice(0, -2);
|
|
||||||
return {
|
|
||||||
type: 'array',
|
|
||||||
items: mapTypeToSchema(itemType)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle union types (simplified)
|
|
||||||
if (type.includes('|')) {
|
|
||||||
const types = type.split('|').map(t => t.trim());
|
|
||||||
if (types.length === 2 && types.includes('null')) {
|
|
||||||
// Nullable type
|
|
||||||
const nonNullType = types.find(t => t !== 'null');
|
|
||||||
return mapTypeToSchema(nonNullType!);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
oneOf: types.map(t => mapTypeToSchema(t))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle basic types
|
|
||||||
switch (type.toLowerCase()) {
|
|
||||||
case 'string':
|
|
||||||
return { type: 'string' };
|
|
||||||
case 'number':
|
|
||||||
case 'bigint':
|
|
||||||
return { type: 'number' };
|
|
||||||
case 'boolean':
|
|
||||||
return { type: 'boolean' };
|
|
||||||
case 'date':
|
|
||||||
return { type: 'string', format: 'date-time' };
|
|
||||||
case 'any':
|
|
||||||
case 'unknown':
|
|
||||||
return {};
|
|
||||||
default:
|
|
||||||
// For complex types, assume they're other DTOs
|
|
||||||
if (type.includes('DTO') || type.includes('Dto')) {
|
|
||||||
return { $ref: `#/components/schemas/${type}` };
|
|
||||||
}
|
|
||||||
// For other types, use string as fallback
|
|
||||||
return { type: 'string' };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generateComprehensiveOpenAPISpec().catch(console.error);
|
|
||||||
@@ -1,39 +1,63 @@
|
|||||||
#!/usr/bin/env tsx
|
#!/usr/bin/env tsx
|
||||||
import fs from 'fs/promises';
|
/**
|
||||||
import path from 'path';
|
* Generate OpenAPI spec from NestJS DTO classes
|
||||||
|
*
|
||||||
|
* This script scans all DTO files and extracts OpenAPI schema definitions
|
||||||
|
* using the @nestjs/swagger metadata.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'reflect-metadata';
|
||||||
|
import * as fs from 'fs/promises';
|
||||||
|
import * as path from 'path';
|
||||||
import { glob } from 'glob';
|
import { glob } from 'glob';
|
||||||
|
|
||||||
// Comprehensive OpenAPI spec generator that scans all DTO files
|
// OpenAPI schema types
|
||||||
async function generateComprehensiveOpenAPISpec() {
|
interface OpenAPISchema {
|
||||||
console.log('🔄 Generating comprehensive OpenAPI spec from all DTO files...');
|
type?: string;
|
||||||
|
format?: string;
|
||||||
|
$ref?: string;
|
||||||
|
items?: OpenAPISchema;
|
||||||
|
properties?: Record<string, OpenAPISchema>;
|
||||||
|
required?: string[];
|
||||||
|
enum?: string[];
|
||||||
|
nullable?: boolean;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const schemas: Record<string, any> = {};
|
interface OpenAPISpec {
|
||||||
|
openapi: string;
|
||||||
|
info: {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
version: string;
|
||||||
|
};
|
||||||
|
paths: Record<string, any>;
|
||||||
|
components: {
|
||||||
|
schemas: Record<string, OpenAPISchema>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Find all DTO files in the API
|
async function generateSpec() {
|
||||||
|
console.log('🔄 Generating OpenAPI spec from DTO files...');
|
||||||
|
|
||||||
|
const schemas: Record<string, OpenAPISchema> = {};
|
||||||
|
|
||||||
|
// Find all DTO files
|
||||||
const dtoFiles = await glob('apps/api/src/domain/*/dtos/**/*.ts', {
|
const dtoFiles = await glob('apps/api/src/domain/*/dtos/**/*.ts', {
|
||||||
cwd: path.join(__dirname, '..')
|
cwd: process.cwd()
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`📁 Found ${dtoFiles.length} DTO files to process`);
|
console.log(`📁 Found ${dtoFiles.length} DTO files to process`);
|
||||||
|
|
||||||
for (const dtoFile of dtoFiles) {
|
for (const dtoFile of dtoFiles) {
|
||||||
const filePath = path.join(__dirname, '..', dtoFile);
|
try {
|
||||||
await processDTOFile(filePath, schemas);
|
await processDTOFile(path.join(process.cwd(), dtoFile), schemas);
|
||||||
}
|
} catch (e: any) {
|
||||||
|
console.warn(`⚠️ Could not process ${dtoFile}: ${e.message}`);
|
||||||
// Also check for DTOs in other locations
|
|
||||||
const additionalDtoFiles = await glob('apps/api/src/domain/*/*.ts', {
|
|
||||||
cwd: path.join(__dirname, '..')
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const dtoFile of additionalDtoFiles) {
|
|
||||||
if (dtoFile.includes('dto') || dtoFile.includes('DTO')) {
|
|
||||||
const filePath = path.join(__dirname, '..', dtoFile);
|
|
||||||
await processDTOFile(filePath, schemas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const spec = {
|
const spec: OpenAPISpec = {
|
||||||
openapi: '3.0.0',
|
openapi: '3.0.0',
|
||||||
info: {
|
info: {
|
||||||
title: 'GridPilot API',
|
title: 'GridPilot API',
|
||||||
@@ -46,218 +70,183 @@ async function generateComprehensiveOpenAPISpec() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const outputPath = path.join(__dirname, '../apps/api/openapi.json');
|
const outputPath = path.join(process.cwd(), 'apps/api/openapi.json');
|
||||||
await fs.writeFile(outputPath, JSON.stringify(spec, null, 2));
|
await fs.writeFile(outputPath, JSON.stringify(spec, null, 2));
|
||||||
|
console.log(`✅ OpenAPI spec generated with ${Object.keys(schemas).length} schemas at: ${outputPath}`);
|
||||||
console.log(`✅ Comprehensive OpenAPI spec generated with ${Object.keys(schemas).length} schemas at: ${outputPath}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processDTOFile(filePath: string, schemas: Record<string, any>) {
|
async function processDTOFile(filePath: string, schemas: Record<string, OpenAPISchema>) {
|
||||||
try {
|
const content = await fs.readFile(filePath, 'utf-8');
|
||||||
const content = await fs.readFile(filePath, 'utf-8');
|
|
||||||
|
|
||||||
// Extract all class and interface definitions
|
// Find class definitions with DTO suffix
|
||||||
const classMatches = content.match(/export (?:class|interface) (\w+(?:DTO|Dto))/g);
|
const classRegex = /export\s+class\s+(\w+(?:DTO|Dto))\s*(?:extends\s+\w+)?\s*\{([^}]*(?:\{[^}]*\}[^}]*)*)\}/gs;
|
||||||
if (!classMatches) {
|
let classMatch;
|
||||||
// Debug: check if file has any export statements
|
|
||||||
if (content.includes('export')) {
|
while ((classMatch = classRegex.exec(content)) !== null) {
|
||||||
console.log(`📄 ${filePath} has exports but no DTO classes`);
|
const className = classMatch[1];
|
||||||
}
|
const classBody = classMatch[2];
|
||||||
return;
|
|
||||||
|
console.log(` 📝 Processing ${className}`);
|
||||||
|
|
||||||
|
const schema = extractSchemaFromClassBody(classBody, content);
|
||||||
|
if (schema && Object.keys(schema.properties || {}).length > 0) {
|
||||||
|
schemas[className] = schema;
|
||||||
|
console.log(` ✅ Added ${className} with ${Object.keys(schema.properties || {}).length} properties`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`📄 Processing ${filePath} - found ${classMatches.length} DTO classes`);
|
|
||||||
|
|
||||||
for (const classMatch of classMatches) {
|
|
||||||
const classNameMatch = classMatch.match(/export (?:class|interface) (\w+(?:DTO|Dto))/);
|
|
||||||
if (classNameMatch) {
|
|
||||||
const className = classNameMatch[1];
|
|
||||||
console.log(` 🔍 Extracting schema for ${className}`);
|
|
||||||
const schema = extractSchemaFromClass(content, className);
|
|
||||||
if (schema && Object.keys(schema.properties || {}).length > 0) {
|
|
||||||
schemas[className] = schema;
|
|
||||||
console.log(` ✅ Added schema for ${className} with ${Object.keys(schema.properties).length} properties`);
|
|
||||||
} else {
|
|
||||||
console.log(` ⚠️ No schema generated for ${className}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// File can't be read, continue
|
|
||||||
console.warn(`⚠️ Could not process ${filePath}:`, error.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractSchemaFromClass(content: string, className: string): any | null {
|
function extractSchemaFromClassBody(classBody: string, fullContent: string): OpenAPISchema {
|
||||||
const properties: Record<string, any> = {};
|
const properties: Record<string, OpenAPISchema> = {};
|
||||||
const required: string[] = [];
|
const required: string[] = [];
|
||||||
|
|
||||||
// Extract @ApiProperty decorated properties from NestJS DTOs
|
// Split by lines and process each property
|
||||||
// Pattern: @ApiProperty(...) followed by property declaration
|
const lines = classBody.split('\n');
|
||||||
const lines = content.split('\n');
|
let currentDecorators: string[] = [];
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
while (i < lines.length) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i].trim();
|
const line = lines[i].trim();
|
||||||
|
|
||||||
// Look for @ApiProperty decorator
|
// Skip empty lines and comments
|
||||||
if (line.startsWith('@ApiProperty(')) {
|
if (!line || line.startsWith('//') || line.startsWith('/*') || line.startsWith('*')) {
|
||||||
const decoratorMatch = line.match(/@ApiProperty\(([^)]*)\)/);
|
continue;
|
||||||
if (decoratorMatch) {
|
|
||||||
const decoratorContent = decoratorMatch[1];
|
|
||||||
|
|
||||||
// Find the property declaration (could be on next line)
|
|
||||||
let propertyLine = line;
|
|
||||||
if (!line.includes(';')) {
|
|
||||||
i++;
|
|
||||||
if (i < lines.length) {
|
|
||||||
propertyLine = lines[i].trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract property name and type from declaration
|
|
||||||
const propertyMatch = propertyLine.match(/(\w+)\s*\??:\s*([^;]+);/);
|
|
||||||
if (propertyMatch) {
|
|
||||||
const propertyName = propertyMatch[1];
|
|
||||||
const propertyType = propertyMatch[2].trim();
|
|
||||||
|
|
||||||
// Check if property is required
|
|
||||||
const isOptional = propertyName.includes('?') ||
|
|
||||||
decoratorContent.includes('required: false') ||
|
|
||||||
decoratorContent.includes('nullable: true') ||
|
|
||||||
propertyLine.includes('@IsOptional()');
|
|
||||||
|
|
||||||
if (!isOptional) {
|
|
||||||
required.push(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to extract type from decorator first, then fall back to property type
|
|
||||||
let schemaType = extractTypeFromDecorator(decoratorContent);
|
|
||||||
if (!schemaType) {
|
|
||||||
schemaType = mapTypeToSchema(propertyType);
|
|
||||||
}
|
|
||||||
|
|
||||||
properties[propertyName] = schemaType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
// Collect decorators
|
||||||
}
|
if (line.startsWith('@')) {
|
||||||
|
currentDecorators.push(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Also extract interface properties (for existing interfaces)
|
// Check if this is a property declaration
|
||||||
const interfacePropertyRegex = /(\w+)\s*\??:\s*([^;]+);/g;
|
const propertyMatch = line.match(/^(\w+)(\?)?[!]?\s*:\s*(.+?)\s*;?\s*$/);
|
||||||
let match;
|
if (propertyMatch) {
|
||||||
while ((match = interfacePropertyRegex.exec(content)) !== null) {
|
const [, propName, optional, propType] = propertyMatch;
|
||||||
const propertyName = match[1];
|
|
||||||
const propertyType = match[2].trim();
|
|
||||||
|
|
||||||
if (!properties[propertyName]) {
|
// Skip if propName is a TypeScript/decorator keyword
|
||||||
// Check if property is required
|
if (['constructor', 'private', 'public', 'protected', 'static', 'readonly'].includes(propName)) {
|
||||||
if (!propertyName.includes('?')) {
|
currentDecorators = [];
|
||||||
required.push(propertyName);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
properties[propertyName] = mapTypeToSchema(propertyType);
|
// Determine if required
|
||||||
|
const hasApiProperty = currentDecorators.some(d => d.includes('@ApiProperty'));
|
||||||
|
const isOptional = !!optional ||
|
||||||
|
currentDecorators.some(d => d.includes('required: false') || d.includes('@IsOptional'));
|
||||||
|
const isNullable = currentDecorators.some(d => d.includes('nullable: true'));
|
||||||
|
|
||||||
|
if (!isOptional && !isNullable) {
|
||||||
|
required.push(propName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract type from @ApiProperty decorator if present
|
||||||
|
let schema = extractTypeFromDecorators(currentDecorators, propType);
|
||||||
|
|
||||||
|
properties[propName] = schema;
|
||||||
|
currentDecorators = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(properties).length === 0) {
|
const result: OpenAPISchema = {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const schema: any = {
|
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties
|
properties
|
||||||
};
|
};
|
||||||
|
|
||||||
if (required.length > 0) {
|
if (required.length > 0) {
|
||||||
schema.required = required;
|
result.required = required;
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractTypeFromDecorator(decoratorContent: string): any | null {
|
function extractTypeFromDecorators(decorators: string[], tsType: string): OpenAPISchema {
|
||||||
// Extract type information from @ApiProperty decorator
|
// Join all decorators to search across them
|
||||||
// Examples:
|
const decoratorStr = decorators.join(' ');
|
||||||
// @ApiProperty({ type: String })
|
|
||||||
// @ApiProperty({ type: [SomeDTO] })
|
|
||||||
// @ApiProperty({ type: () => SomeDTO })
|
|
||||||
|
|
||||||
if (decoratorContent.includes('type:')) {
|
// Check for @ApiProperty type specification
|
||||||
// Simple type extraction - this is a simplified version
|
const apiPropertyMatch = decoratorStr.match(/@ApiProperty\s*\(\s*\{([^}]*)\}\s*\)/s);
|
||||||
// In a real implementation, you'd want proper AST parsing
|
|
||||||
|
if (apiPropertyMatch) {
|
||||||
|
const apiPropertyContent = apiPropertyMatch[1];
|
||||||
|
|
||||||
if (decoratorContent.includes('[String]') || decoratorContent.includes('[string]')) {
|
// Check for array type: type: [SomeDTO]
|
||||||
return { type: 'array', items: { type: 'string' } };
|
const arrayTypeMatch = apiPropertyContent.match(/type:\s*\[\s*(\w+)\s*\]/);
|
||||||
|
if (arrayTypeMatch) {
|
||||||
|
const itemType = arrayTypeMatch[1];
|
||||||
|
return {
|
||||||
|
type: 'array',
|
||||||
|
items: mapTypeToSchema(itemType)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoratorContent.includes('[Number]') || decoratorContent.includes('[number]')) {
|
// Check for function type: type: () => SomeDTO
|
||||||
return { type: 'array', items: { type: 'number' } };
|
const funcTypeMatch = apiPropertyContent.match(/type:\s*\(\)\s*=>\s*(\w+)/);
|
||||||
|
if (funcTypeMatch) {
|
||||||
|
return mapTypeToSchema(funcTypeMatch[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoratorContent.includes('String') || decoratorContent.includes('string')) {
|
// Check for direct type reference: type: SomeDTO
|
||||||
return { type: 'string' };
|
const directTypeMatch = apiPropertyContent.match(/type:\s*(\w+)(?:\s*[,}])/);
|
||||||
|
if (directTypeMatch && !['String', 'Number', 'Boolean', 'string', 'number', 'boolean'].includes(directTypeMatch[1])) {
|
||||||
|
return mapTypeToSchema(directTypeMatch[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoratorContent.includes('Number') || decoratorContent.includes('number')) {
|
// Check for enum
|
||||||
return { type: 'number' };
|
const enumMatch = apiPropertyContent.match(/enum:\s*(\w+)/);
|
||||||
|
if (enumMatch) {
|
||||||
|
return { type: 'string' }; // Simplify enum to string
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoratorContent.includes('Boolean') || decoratorContent.includes('boolean')) {
|
// Check for nullable
|
||||||
return { type: 'boolean' };
|
if (apiPropertyContent.includes('nullable: true')) {
|
||||||
}
|
const baseSchema = mapTypeToSchema(tsType);
|
||||||
|
baseSchema.nullable = true;
|
||||||
// For complex types with references
|
return baseSchema;
|
||||||
const refMatch = decoratorContent.match(/type:\s*\[?(\w+DTO)\]?/);
|
|
||||||
if (refMatch) {
|
|
||||||
const refType = refMatch[1];
|
|
||||||
if (decoratorContent.includes('[')) {
|
|
||||||
return { type: 'array', items: { $ref: `#/components/schemas/${refType}` } };
|
|
||||||
} else {
|
|
||||||
return { $ref: `#/components/schemas/${refType}` };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For function types like type: () => SomeDTO
|
|
||||||
const funcMatch = decoratorContent.match(/type:\s*\(\)\s*=>\s*(\w+DTO)/);
|
|
||||||
if (funcMatch) {
|
|
||||||
return { $ref: `#/components/schemas/${funcMatch[1]}` };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
// Fall back to TypeScript type
|
||||||
|
return mapTypeToSchema(tsType);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapTypeToSchema(type: string): any {
|
function mapTypeToSchema(type: string): OpenAPISchema {
|
||||||
// Clean up the type
|
// Clean up the type
|
||||||
type = type.replace(/[|;]/g, '').trim();
|
type = type.replace(/[;!]/g, '').trim();
|
||||||
|
|
||||||
|
// Handle union with null
|
||||||
|
if (type.includes('| null') || type.includes('null |')) {
|
||||||
|
const baseType = type.replace(/\|\s*null/g, '').replace(/null\s*\|/g, '').trim();
|
||||||
|
const schema = mapTypeToSchema(baseType);
|
||||||
|
schema.nullable = true;
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle array types
|
// Handle array types
|
||||||
if (type.endsWith('[]')) {
|
if (type.endsWith('[]')) {
|
||||||
const itemType = type.slice(0, -2);
|
const itemType = type.slice(0, -2).trim();
|
||||||
return {
|
return {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: mapTypeToSchema(itemType)
|
items: mapTypeToSchema(itemType)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle union types (simplified)
|
// Handle Array<T> syntax
|
||||||
if (type.includes('|')) {
|
const arrayGenericMatch = type.match(/^Array<(.+)>$/);
|
||||||
const types = type.split('|').map(t => t.trim());
|
if (arrayGenericMatch) {
|
||||||
if (types.length === 2 && types.includes('null')) {
|
|
||||||
// Nullable type
|
|
||||||
const nonNullType = types.find(t => t !== 'null');
|
|
||||||
return mapTypeToSchema(nonNullType!);
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
oneOf: types.map(t => mapTypeToSchema(t))
|
type: 'array',
|
||||||
|
items: mapTypeToSchema(arrayGenericMatch[1])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle basic types
|
// Handle object literal types (inline objects)
|
||||||
switch (type.toLowerCase()) {
|
if (type.startsWith('{')) {
|
||||||
|
return { type: 'object' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle primitive types
|
||||||
|
const lowerType = type.toLowerCase();
|
||||||
|
switch (lowerType) {
|
||||||
case 'string':
|
case 'string':
|
||||||
return { type: 'string' };
|
return { type: 'string' };
|
||||||
case 'number':
|
case 'number':
|
||||||
@@ -269,15 +258,17 @@ function mapTypeToSchema(type: string): any {
|
|||||||
return { type: 'string', format: 'date-time' };
|
return { type: 'string', format: 'date-time' };
|
||||||
case 'any':
|
case 'any':
|
||||||
case 'unknown':
|
case 'unknown':
|
||||||
return {};
|
case 'object':
|
||||||
default:
|
return { type: 'object' };
|
||||||
// For complex types, assume they're other DTOs
|
|
||||||
if (type.includes('DTO') || type.includes('Dto')) {
|
|
||||||
return { $ref: `#/components/schemas/${type}` };
|
|
||||||
}
|
|
||||||
// For other types, use string as fallback
|
|
||||||
return { type: 'string' };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle DTO references
|
||||||
|
if (type.endsWith('DTO') || type.endsWith('Dto')) {
|
||||||
|
return { $ref: `#/components/schemas/${type}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to string for unknown types
|
||||||
|
return { type: 'string' };
|
||||||
}
|
}
|
||||||
|
|
||||||
generateComprehensiveOpenAPISpec().catch(console.error);
|
generateSpec().catch(console.error);
|
||||||
Reference in New Issue
Block a user