f61e050e8c
API functions now build the full localized path matching the Angular
EndpointService pattern (/api/flights/{version}/{locale}/{endpoint}).
The dev proxy forwards /api and /flights to the test backend.
140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
/**
|
|
* Online Board API functions.
|
|
*
|
|
* Pure functions — each takes an `ApiClient` as a parameter (dependency
|
|
* injection). No React hooks, no context, no side effects.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import type { ApiClient } from "@/shared/api/client.js";
|
|
import type {
|
|
IBoardResponse,
|
|
IDaysResponse,
|
|
FlightRequestType,
|
|
} from "./types.js";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Parameter types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export interface SearchFlightsParams {
|
|
/** Flight number search: e.g. "SU100" */
|
|
flightNumber?: string;
|
|
/** Date range start — yyyyMMdd format (used by the API as `dateFrom`) */
|
|
dateFrom: string;
|
|
/** Date range end — yyyyMMdd format (used by the API as `dateTo`) */
|
|
dateTo: string;
|
|
/** Departure airport IATA code */
|
|
departure?: string;
|
|
/** Arrival airport IATA code */
|
|
arrival?: string;
|
|
/** Time range start — HHmm format */
|
|
timeFrom?: string;
|
|
/** Time range end — HHmm format */
|
|
timeTo?: string;
|
|
}
|
|
|
|
export interface FlightDetailsParams {
|
|
/** Carrier code + flight number, e.g. "SU100" */
|
|
flights: string;
|
|
/** Date in yyyy-MM-dd format */
|
|
dates: string;
|
|
}
|
|
|
|
export interface CalendarParams {
|
|
/** Base date — yyyy-MM-dd format */
|
|
date: string;
|
|
/** Search type discriminator */
|
|
searchType: FlightRequestType;
|
|
/** Flight number (for "flight" type), e.g. "SU100" */
|
|
flightNumber?: string;
|
|
/** Departure airport IATA code (for "departure" or "route" type) */
|
|
departure?: string;
|
|
/** Arrival airport IATA code (for "arrival" or "route" type) */
|
|
arrival?: string;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// API functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Search flights on the online board.
|
|
* Maps to: `GET /board?flightNumber=...&dateFrom=...&dateTo=...&...`
|
|
*/
|
|
export async function searchFlights(
|
|
client: ApiClient,
|
|
params: SearchFlightsParams,
|
|
): Promise<IBoardResponse> {
|
|
const query: Record<string, string> = {
|
|
dateFrom: params.dateFrom,
|
|
dateTo: params.dateTo,
|
|
};
|
|
|
|
if (params.flightNumber) query["flightNumber"] = params.flightNumber;
|
|
if (params.departure) query["departure"] = params.departure;
|
|
if (params.arrival) query["arrival"] = params.arrival;
|
|
if (params.timeFrom) query["timeFrom"] = params.timeFrom;
|
|
if (params.timeTo) query["timeTo"] = params.timeTo;
|
|
|
|
return client.get<IBoardResponse>(`flights/v1.1/${client.locale}/board`, query);
|
|
}
|
|
|
|
/**
|
|
* Get flight details.
|
|
* Maps to: `GET /onlineboard/details?flights=SU100&dates=2025-01-15`
|
|
*/
|
|
export async function getFlightDetails(
|
|
client: ApiClient,
|
|
params: FlightDetailsParams,
|
|
): Promise<IBoardResponse> {
|
|
return client.get<IBoardResponse>(`flights/v1.1/${client.locale}/onlineboard/details`, {
|
|
flights: params.flights,
|
|
dates: params.dates,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get available calendar days for a given search context.
|
|
* Maps to: `GET /v1/days/{date}/31/{searchType}/{searchParams}/board/`
|
|
*
|
|
* The API returns `{ days: "2025-01-01,2025-01-02,..." }` — a single
|
|
* comma-separated string. This function splits it into `string[]`.
|
|
*/
|
|
export async function getCalendarDays(
|
|
client: ApiClient,
|
|
params: CalendarParams,
|
|
): Promise<string[]> {
|
|
const searchSegment = buildCalendarSearchSegment(params);
|
|
const path = `flights/v1/${client.locale}/days/${params.date}/31/${searchSegment}/board/`;
|
|
|
|
const response = await client.get<IDaysResponse>(path);
|
|
return parseCalendarDays(response.days);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Internal helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
function buildCalendarSearchSegment(params: CalendarParams): string {
|
|
switch (params.searchType) {
|
|
case "flight":
|
|
return `flight/${params.flightNumber ?? ""}`;
|
|
case "departure":
|
|
return `departure/${params.departure ?? ""}`;
|
|
case "arrival":
|
|
return `arrival/${params.arrival ?? ""}`;
|
|
case "route": {
|
|
const dep = params.departure ?? "";
|
|
const arr = params.arrival ?? "";
|
|
return `route/${dep}-${arr}`;
|
|
}
|
|
}
|
|
}
|
|
|
|
function parseCalendarDays(days: string): string[] {
|
|
if (!days) return [];
|
|
return days.split(",").map((d) => d.trim()).filter(Boolean);
|
|
}
|