import type { Env, Store } from "./store-interface.js"; import type { ShortlinksTransportOverrides } from "./client-types.js"; /** The hosted-API HTTP transport. */ export { CloudShortlinksStore as ApiStore } from "./cloud-store.js"; export type { Store } from "./store-interface.js"; /** * The on-box SQLite store — TYPE ONLY here. A value import would drag * `bun:sqlite` back into every bundle that touches this seam; the class is * loaded through the gated dynamic import in {@link resolveStore}. */ export type { LocalStore } from "./local-store.js"; /** * Environment opt-in for the on-box SQLite store, canonical name first. The * legacy `SHORTLINKS_LOCAL` spelling stays accepted (it is documented and in * the wild). This is the ONLY door to local storage: without a hosted * credential AND without this flag the CLI fails closed instead of serving * local data, and `--db ` alone is refused. */ export declare const LOCAL_OPT_IN_ENV_KEYS: readonly ["HASNA_SHORTLINKS_LOCAL", "SHORTLINKS_LOCAL"]; /** The canonical local opt-in env key, named in errors and notices. */ export declare const LOCAL_OPT_IN_ENV_KEY: "HASNA_SHORTLINKS_LOCAL"; /** * True when the environment explicitly opts into the on-box SQLite store via * `HASNA_SHORTLINKS_LOCAL` / `SHORTLINKS_LOCAL`. Any value except an empty * string / 0 / false / no / off opts in. A fully configured hosted API still * wins over this flag — opt-in never silently shadows an explicit hosted * configuration. */ export declare function isLocalOptIn(env: Env): boolean; /** Actionable fail-closed message: names the credential chain and the local opt-in. */ export declare function missingBackendMessage(): string; /** * Refusal for `--db ` / `options.dbPath` without the environment opt-in. * `--db` used to select the on-box store by itself — a second, undocumented * door into local storage. It now only NAMES THE FILE for a run that already * opted in, so one line naming the opt-in is the whole fix an operator needs. */ export declare function dbPathWithoutOptInMessage(dbPath: string): string; /** Reset the once-per-process local-backend notice. Test seam only. */ export declare function __resetShortlinksLocalNotice(): void; /** Options shared by client resolution and public redirect-server helpers. */ export interface ExplicitLocalStoreOptions { /** Optional database path; the explicit local opt-in is still required. */ dbPath?: string; /** Where the one-line local-backend notice goes. Defaults to `process.stderr`. */ notice?: (line: string) => void; } /** * Open the on-box store only after the caller has explicitly selected it. * * Public server helpers use this seam when no store is injected. It deliberately * does not inspect hosted credentials: hosted callers resolve their transport * through {@link resolveStore} and inject that resolved store. This prevents a * library helper from silently choosing either a fleet authority or SQLite. */ export declare function openExplicitLocalStore(env?: Env, options?: ExplicitLocalStoreOptions): Promise; export interface ResolveStoreOptions { /** * Explicit local SQLite path (CLI `--db`). It CHOOSES THE FILE for a run * that already opted into local storage; it is NOT itself an opt-in (a * `dbPath` without `HASNA_SHORTLINKS_LOCAL` is refused), and it is ignored * when the hosted API is selected. */ dbPath?: string; /** Transport overrides for the hosted-API client (test injection: fetchImpl, ...). */ cloudOverrides?: ShortlinksTransportOverrides; /** Where the one-line local-backend notice goes. Defaults to `process.stderr`. */ notice?: (line: string) => void; } /** * Resolve the active {@link Store} for the current environment. * * - The hosted-API {@link ApiStore} wins when the @hasna/contracts client * resolver finds a shortlinks credential (Keychain, disk credential file, or * `HASNA_SHORTLINKS_API_KEY`); a partially configured hosted client throws. * - Otherwise the on-box `LocalStore` is used ONLY when the environment * explicitly opted in (`HASNA_SHORTLINKS_LOCAL=1`, alias `SHORTLINKS_LOCAL=1`); * `dbPath` (`--db`) names the file for such a run but never opens one by * itself — a `dbPath` without the opt-in is REFUSED. * - Otherwise resolution FAILS CLOSED: it throws an error naming the credential * chain instead of silently serving the local SQLite dataset. * * Async because the local store — and with it `bun:sqlite` — is behind a gated * dynamic import; the hosted and fail-closed paths never touch it. */ export declare function resolveStore(env?: Env, options?: ResolveStoreOptions): Promise; /** * Run `fn` with a resolved {@link Store}, always closing it afterward. The * canonical helper for one-shot CLI/MCP operations. Fails closed (throws * naming the credential chain) when no backend is configured and the local * backend was not explicitly opted into. */ export declare function withStore(fn: (store: Store) => T | Promise, env?: Env, options?: ResolveStoreOptions): Promise;