import type { ApiCoverage, CapabilityUrl, OwnershipModel, ProbeResult, SchemaSnapshot } from "../types.js"; import { type ActionDeclaration, type Route } from "./routes.js"; import { type ApiAuth } from "./session.js"; export interface ApiPhaseOptions { connectionString: string; snapshot: SchemaSnapshot; model: OwnershipModel; cwd: string; baseUrl: string; auth: ApiAuth; mode: "read_only" | "full"; /** * Endpoints named in the config file. Merged with whatever discovery finds, * so a framework Crossline cannot parse is a few lines of config rather than * a dead end. */ declaredRoutes?: Route[]; /** * How to call the server actions the build named — the argument shapes, which * are the one thing `next build` does not record. * * Joined to the ids discovery read out of the build rather than replacing * them: a declaration supplies the call, the build supplies the endpoint, and * a declaration that names nothing in the build is reported and not called. */ declaredActions?: ActionDeclaration[]; /** Skip discovery and use these instead. */ routes?: Route[]; /** How the application came to be running, when Crossline started it. */ appServer?: string | null; /** Ambient environment, for detecting the auth provider off `.env`. */ env?: NodeJS.ProcessEnv; } export interface ApiPhaseResult { probes: ProbeResult[]; routes: Route[]; /** Rows we could not remove afterwards, so the developer can clean up. */ residue: string[]; /** What the API phase actually managed to check. Never omitted. */ coverage: ApiCoverage; /** Endpoints that answer anyone holding the link. Not findings. */ capabilityUrls: CapabilityUrl[]; } /** * Run the API-plane checks. * * Unlike the data plane, this cannot hide inside a transaction: the application * is a separate process with its own connection, so the seeded rows have to be * committed for it to see them. That is the structural reason this plane needs * an ephemeral environment — a preview deployment or a database branch — and * why pointing it at production is not on offer. * * We commit, probe, and then remove exactly the rows we created, reporting * anything we could not clean up rather than leaving it silently behind. That * includes the session row a strategy like Auth.js's needs in order to be * somebody: becoming a user is a write here too, and it is accounted for in the * same list as the seeded data. */ export declare function runApiPhase(opts: ApiPhaseOptions): Promise; /** * Endpoints named in the config file, plus whatever discovery found. * * Declared routes come first so that a developer who writes one down wins the * de-duplication and sees it attributed to their config rather than to a * parser. They are additive rather than a replacement: the usual reason to * write one is that discovery missed it, not that discovery was wrong. */ export declare function mergeRoutes(declared: Route[], discovered: Route[]): Route[];