import { type ShareConfig } from './config.js';
/** DI seam for tests — override the real HTTP DELETE. `body`/`retryAfter` carry
 * the Worker's error response (read only on `!ok`) so a failed delete surfaces
 * WHY, via the bounded {@link extractShareHttpError}. */
export type DeleteFn = (url: string, headers: Record<string, string>) => Promise<{
    ok: boolean;
    status: number;
    body?: string;
    retryAfter?: string;
}>;
/** DI seam for tests — override the real HTTP existence check (HEAD). */
export type CheckFn = (url: string) => Promise<{
    status: number;
}>;
/** DI seam for tests — override the real HTTP GET of the revisions listing route. */
export type RevisionsFetchFn = (url: string) => Promise<{
    status: number;
    contentType: string;
    body: string;
}>;
export interface DeleteEndpoint {
    baseUrl: string;
    token: string;
}
export interface ResolvedShareTarget {
    /** R2 object key for the page, `<user>/<slug>`. */
    key: string;
    /** R2 object key for the sibling OG cover, `<user>/<slug>.png`. */
    coverKey: string;
}
/**
 * Normalize any of the three accepted target forms to the R2 key that publish
 * would have written:
 *   - a full share URL: `https://share.getrush.ai/<user>/<slug>`
 *   - `<user>/<slug>`
 *   - a bare `<slug>` — resolved against the caller's own namespace exactly as
 *     `publishToEndpoint` resolves it at publish time (resolveShareUsername +
 *     buildShareKey), so a bare slug always targets *your* published page.
 *
 * The URL and `<user>/<slug>` forms are taken as already the exact key a prior
 * publish produced (no re-sanitizing) — only the bare-slug form runs through
 * `buildShareKey`, because that's the one case where the slug hasn't already
 * been normalized by a publish.
 */
export declare function resolveDeleteTarget(target: string, opts?: {
    githubUser?: string;
}): Promise<ResolvedShareTarget>;
export interface DeleteObjectResult {
    key: string;
    url: string;
    /** Whether the object resolved (non-404) before the DELETE was issued. */
    existedBefore: boolean;
    /** Whether the Worker's DELETE call itself reported ok. */
    deleted: boolean;
    /** The postcondition: a follow-up check resolved 404 after the DELETE. */
    verified404: boolean;
}
/**
 * Delete one R2 object behind the share Worker and assert the postcondition.
 * `{"ok":true}` from the Worker is not evidence a page came down — R2 delete is
 * idempotent, so a DELETE on a key that was never there also returns `ok:true`.
 * This checks existence before (so callers can tell "deleted" from "was never
 * there") and re-checks after (so callers can tell "deleted" from "still public").
 */
export declare function deleteObject(endpoint: DeleteEndpoint, key: string, opts?: {
    deleter?: DeleteFn;
    checker?: CheckFn;
}): Promise<DeleteObjectResult>;
export interface DeleteShareOptions {
    /** Skip deleting the sibling `<slug>.png` OG cover (default: delete it too). */
    keepCover?: boolean;
    /** Skip deleting the target's retained revisions (`<key>/rev-*`, RUSH-2683
     * revision retention) — default: delete them too. A republished-then-deleted
     * share would otherwise leave its prior world-readable versions live for up
     * to the bucket's lifecycle max-age (see docs/distribution.md). */
    keepRevisions?: boolean;
    /** Treat an already-missing target as a no-op success instead of an error
     * (mirrors SQL's `DROP ... IF EXISTS`). Default: missing target is an error. */
    ifExists?: boolean;
    /** Override the GitHub username used to resolve a bare-slug target. */
    githubUser?: string;
    /** DI seam for tests — override the persisted share endpoint config. */
    config?: ShareConfig;
    /** DI seam for tests — override the keychain-backed write token. Selects BYO. */
    writeToken?: string;
    /** DI seam for tests — override `readSession()`. `null` means signed out. */
    session?: import('../identity/client.js').PhoenixSession | null;
    /** Force the BYO Cloudflare path even when signed in. */
    byo?: boolean;
    /** DI seam for tests — override the real HTTP DELETE. */
    deleter?: DeleteFn;
    /** DI seam for tests — override the real HTTP existence check. */
    checker?: CheckFn;
    /** DI seam for tests — override the real HTTP GET of the revisions listing route. */
    fetchRevisions?: RevisionsFetchFn;
}
export interface DeleteShareResult {
    key: string;
    url: string;
    existedBefore: boolean;
    verified404: boolean;
    /** True when `ifExists` was set and the target was already gone — nothing ran. */
    skipped?: boolean;
    cover?: {
        key: string;
        url: string;
        existedBefore: boolean;
        verified404: boolean;
    };
    /** Retained revisions of this target that were also deleted (omitted when
     * there were none, or `keepRevisions` was passed). */
    revisions?: Array<{
        key: string;
        url: string;
        existedBefore: boolean;
        verified404: boolean;
    }>;
}
/** Delete one share target (page + by default its OG cover) and verify both
 * are gone. Throws on an unverified takedown — never reports success for an
 * object that still resolves. */
export declare function deleteShare(target: string, opts?: DeleteShareOptions): Promise<DeleteShareResult>;
