/** * HTTP server for `qfg serve`. Boots a single `@quonfig/node` Quonfig client * with `{datadir, dataDirAutoReload}` so file changes flow into a shared * snapshot (mirror of the SDK's `ConfigStore`). All requests evaluate against * that snapshot — see plan project/plans/qfg-serve.md §5 ("Integration with * auto-reload work"). * * Bound by default to 127.0.0.1. Auth and CORS are configured per plan §4. */ import type { ConfigResponse } from '@quonfig/node'; export interface Logger { log: (msg: string) => void; warn: (msg: string) => void; } export interface ServeOptions { allowNonLoopback: boolean; corsOrigins: string[]; datadir: string; environment: string; /** * Test-only escape hatch — startServer treats this string as the bind host * for the loopback / non-loopback policy check, while still actually * binding to `host`. Lets unit tests assert the WARN path without binding * 0.0.0.0 in CI (which some networks forbid). NOT a public option. */ forceNonLoopbackForTest?: string; frontendSdkKey?: string; host: string; logger: Logger; port: number; verbose: boolean; watch: boolean; /** Override the SDK's 200ms default debounce; lets tests check the watch path quickly. */ watchDebounceMs?: number; } export interface ServeHandle { /** Stop watching, close all sockets, await SDK close. Idempotent. */ close(): Promise; host: string; port: number; } export declare function startServer(opts: ServeOptions): Promise; /** * G8 (qfg-38sf.6): compute meta.version as sha256 of the canonicalized * configs array. Canonical form is `JSON.stringify(configs, sortedKeys)` so * two snapshots with identical config content produce the same hash regardless * of object-key order. The hash replaces the prior `datadir:#` * shape, which leaked operator filesystem layout and changed on every reload * even when the data was unchanged. * * Exported for unit tests that want to assert determinism / stability. */ export declare function computeVersion(configs: ConfigResponse[]): string;