82 lines
2.2 KiB
TypeScript
82 lines
2.2 KiB
TypeScript
import type {
|
|
FlightReportRequest,
|
|
FlightSearchPlan,
|
|
FlightSearchSourceFinding,
|
|
FlightSearchSourceName,
|
|
FlightSearchSourceViability
|
|
} from "./types.js";
|
|
|
|
export const SOURCE_SILENT_TIMEOUT_MS = 45_000;
|
|
export const SOURCE_TOTAL_TIMEOUT_MS = 180_000;
|
|
export const RUN_TOTAL_TIMEOUT_MS = 900_000;
|
|
export const VPN_CONNECT_TIMEOUT_MS = 30_000;
|
|
export const VPN_DISCONNECT_TIMEOUT_MS = 15_000;
|
|
|
|
const DEFAULT_SOURCE_ORDER: FlightSearchSourceName[] = [
|
|
"kayak",
|
|
"skyscanner",
|
|
"expedia",
|
|
"airline-direct"
|
|
];
|
|
|
|
function findingFor(
|
|
source: FlightSearchSourceName,
|
|
findings: FlightSearchSourceFinding[]
|
|
): FlightSearchSourceFinding | undefined {
|
|
return findings.find((entry) => entry.source === source);
|
|
}
|
|
|
|
function sourceStatus(
|
|
source: FlightSearchSourceName,
|
|
findings: FlightSearchSourceFinding[]
|
|
): FlightSearchSourceViability {
|
|
return findingFor(source, findings)?.status || "viable";
|
|
}
|
|
|
|
export function buildFlightSearchPlan(
|
|
request: FlightReportRequest,
|
|
findings: FlightSearchSourceFinding[] = []
|
|
): FlightSearchPlan {
|
|
const sourceOrder = DEFAULT_SOURCE_ORDER.map((source) => {
|
|
const status = sourceStatus(source, findings);
|
|
const finding = findingFor(source, findings);
|
|
const required = source !== "airline-direct";
|
|
const enabled = status !== "blocked";
|
|
const reason =
|
|
finding?.notes[0] ||
|
|
(source === "airline-direct"
|
|
? "Best-effort airline direct cross-check."
|
|
: "Primary bounded search source.");
|
|
|
|
return {
|
|
source,
|
|
enabled,
|
|
required,
|
|
status,
|
|
silentTimeoutMs: SOURCE_SILENT_TIMEOUT_MS,
|
|
totalTimeoutMs: SOURCE_TOTAL_TIMEOUT_MS,
|
|
reason
|
|
};
|
|
});
|
|
|
|
const degradedReasons = sourceOrder
|
|
.filter((source) => source.status !== "viable")
|
|
.map((source) =>
|
|
source.enabled
|
|
? `${source.source} is degraded for this run: ${source.reason}`
|
|
: `${source.source} is blocked for this run: ${source.reason}`
|
|
);
|
|
|
|
return {
|
|
sourceOrder,
|
|
vpn: {
|
|
enabled: Boolean(request.preferences.marketCountry),
|
|
marketCountry: request.preferences.marketCountry || null,
|
|
connectTimeoutMs: VPN_CONNECT_TIMEOUT_MS,
|
|
disconnectTimeoutMs: VPN_DISCONNECT_TIMEOUT_MS,
|
|
fallbackMode: "default-market"
|
|
},
|
|
degradedReasons
|
|
};
|
|
}
|