import type {BrokerStore} from './store.js'; export type HostValidationFailure = { status: number; message: string; }; export type HostReadyOptions = { /** When set, host must be registered with this cluster model id. */ requiredModel?: string; requiredModelLabel?: string; }; const MISSING_HOST_MESSAGE = "Missing required field 'host'. Open the app in a browser and register a host id."; export function parseHostField(body: {host?: string}): string | HostValidationFailure { if (!body?.host?.trim()) { return {status: 400, message: MISSING_HOST_MESSAGE}; } return body.host.trim(); } export function validateHostRegistered( store: BrokerStore, hostId: string, ): HostValidationFailure | null { if (store.getHost(hostId)) { return null; } return { status: 404, message: `Host '${hostId}' not found. Register it in the browser host page first.`, }; } export function validateHostOnline( store: BrokerStore, hostId: string, ): HostValidationFailure | null { if (store.isHostOnline(hostId)) { return null; } return { status: 503, message: `Host '${hostId}' is offline. Keep the browser host tab open with the model loaded.`, }; } export function validateHostModel( store: BrokerStore, hostId: string, requiredModel: string, requiredModelLabel: string, ): HostValidationFailure | null { const host = store.getHost(hostId); if (host?.model === requiredModel) { return null; } return { status: 400, message: `Host '${hostId}' is registered for '${host?.model ?? 'unknown'}', not ${requiredModelLabel}. Open the host page, select "${requiredModelLabel}", and register again.`, }; } /** Runs registered → online → optional model checks. Returns first failure or null. */ export function validateHostReady( store: BrokerStore, hostId: string, options: HostReadyOptions = {}, ): HostValidationFailure | null { return ( validateHostRegistered(store, hostId) ?? validateHostOnline(store, hostId) ?? (options.requiredModel ? validateHostModel( store, hostId, options.requiredModel, options.requiredModelLabel ?? options.requiredModel, ) : null) ); }