// What the mesh delivered to home-assistant's provisions step, and the step's own small memory. // // Per provision it requires, the mesh writes two files beside each other (the manifest's `binds` and // `secrets`): `.json`, the binding — where the provider is (`at`), what it serves (`port`, // `scheme`, …) and the login this module presents (`as`) — and `.secret`, the pair // credential. Nothing here guesses a host, a port or a key. import { mkdir, readFile, rename, writeFile } from "node:fs/promises"; import { join } from "node:path"; import type { Binding, Marks } from "./connections.js"; /** A file the mesh wrote, or undefined when it is not there. */ export async function readIfThere(path: string | undefined): Promise { if (!path) return undefined; return readFile(path, "utf8").catch(() => undefined); } /** A binding file parsed, or undefined when absent or not JSON. */ export async function readBinding(path: string): Promise { const raw = await readIfThere(path); if (raw === undefined) return undefined; try { return JSON.parse(raw) as Binding; } catch { return undefined; } } export function marksIn(dir: string): Marks { return { async get(name) { return (await readIfThere(join(dir, `${name}.digest`)))?.trim() || undefined; }, async set(name, value) { await mkdir(dir, { recursive: true, mode: 0o700 }); const path = join(dir, `${name}.digest`); await writeFile(`${path}.tmp`, `${value}\n`, { mode: 0o600 }); await rename(`${path}.tmp`, path); }, }; }