/** * Picking up the OAuth client JSON the console just downloaded. * * Google names the file `client_secret_.apps.googleusercontent.com.json`, * so matching on filename is fragile and matching on an exact name is simply * wrong. The browser tool owns the profile the download landed in, so the flow * already knows the directory, what it needs is to identify the right file by * **content shape**: a JSON object with an `installed` key carrying both * `client_id` and `client_secret`. * * When collection fails the flow asks for a path rather than stalling. A * question the user can answer in five seconds is always better than a silent * wait, which is the failure mode this whole integration exists to eliminate. */ /** Directory listing and file reading, injected so this is testable. */ export interface DownloadScanPort { listFiles(directory: string): readonly string[]; readText(path: string): string | null; /** Modification time in epoch milliseconds; used only to prefer the newest match. */ modifiedAtMs(path: string): number | null; } export interface CollectedClientFile { readonly path: string; readonly contents: string; } export type CollectClientFileResult = { readonly ok: true; readonly file: CollectedClientFile; } | { readonly ok: false; readonly problem: string; readonly fix: string; }; /** * Does this text look like a Desktop-app OAuth client JSON? * * Checks structure, not name. A `web` client is deliberately not accepted, * it cannot complete the loopback flow, and silently picking one up would * produce a baffling failure several steps later. */ export declare function looksLikeDesktopClientJson(text: string): boolean; /** * Find the most recently modified Desktop-client JSON in a download directory. * * `since` lets the caller ignore files that predate this walkthrough, so a * stale client JSON downloaded months ago is never picked up in place of the * one just created. */ export declare function collectDownloadedClientFile(scan: DownloadScanPort, directory: string, options?: { readonly since?: number; }): CollectClientFileResult; //# sourceMappingURL=client-download.d.ts.map