// driver registry — hardcoded list of known drivers plus lookup helpers. // kept intentionally flat: no DI, no plugin discovery, no lazy imports. both // built-in drivers load unconditionally because their module bodies are cheap // (no I/O, no side effects). import { electronDriver } from './electron' import { playwrightDriver } from './playwright' import type { Driver, DriverId } from './types' export const ALL_DRIVERS: readonly Driver[] = [electronDriver, playwrightDriver] export function getAllDrivers(): readonly Driver[] { return ALL_DRIVERS } export function getDriver(id: DriverId): Driver | null { return ALL_DRIVERS.find((d) => d.id === id) ?? null } // returns the first driver in preference order that reports availability. // used by launch sites that want "pick whatever works" behavior when the // user didn't pass an explicit --driver flag. if `forcedId` is given, that // driver is returned even if unavailable so the caller can surface a // specific error message rather than silently falling back. export function resolveDriver( forcedId: string | null | undefined, preference: readonly DriverId[], ): Driver | null { if (forcedId) { const match = ALL_DRIVERS.find((d) => d.id === forcedId) return match ?? null } for (const id of preference) { const driver = ALL_DRIVERS.find((d) => d.id === id) if (driver && driver.availability().available) return driver } return null } // utility for the `rnx list --drivers` view. returns a rich row per // driver with availability + kind + description, suitable for a table. export interface DriverListRow { id: DriverId name: string kind: Driver['kind'] description: string available: boolean reason: string | null detail: string | null } export function buildDriverListRows(): DriverListRow[] { return ALL_DRIVERS.map((d) => { const probe = d.availability() return { id: d.id, name: d.name, kind: d.kind, description: d.description, available: probe.available, reason: probe.reason, detail: probe.detail ?? null, } }) }