import type { CapturedAtSource } from "@familyalbum/shared";
export interface UploadInput {
    familyId: string;
    /** id de la ligne media (uuid) — le fichier est nommé par cet id. */
    mediaId: string;
    name: string;
    mime: string;
    stream: NodeJS.ReadableStream | Buffer;
    /** Date de capture fournie par le client (priorité 1). */
    capturedAt?: Date;
}
export interface UploadResult {
    /** Chemin relatif au root de stockage (colonne media.path). */
    path: string;
    size: number;
    /** Empreinte sha256 du contenu — sert de etag local (dédup future). */
    etag: string;
    width: number | null;
    height: number | null;
    hasPreview: boolean;
    capturedAt: Date;
    capturedAtSource: CapturedAtSource;
}
export interface RangeRequest {
    start: number;
    end: number;
}
/**
 * Connecteur de stockage local — les octets vivent sur le disque du serveur.
 *
 * Layout (sous DATA_DIR) :
 *   media/<familyId>/<mediaId><ext>        originaux
 *   thumbs/<familyId>/<mediaId>_<size>.jpg miniatures générées (cache)
 */
export declare class LocalStorageConnector {
    private readonly root;
    constructor(opts: {
        dataDir: string;
    });
    /** Chemin absolu d'un fichier média relatif. */
    absolutePath(familyId: string, relativePath: string): string;
    /** Chemin absolu d'un fichier de miniature en cache. */
    private thumbPath;
    /**
     * Écrit le fichier sur disque et calcule les métadonnées (taille, etag,
     * dimensions, date de capture). L'extension est déduite du nom d'origine
     * puis du mime.
     */
    upload(input: UploadInput): Promise<UploadResult>;
    /**
     * Miniature JPEG : cache disque, générée à la demande depuis l'original.
     * Retourne null si le média n'a pas de miniature (vidéo, format non
     * décodable).
     */
    getThumb(familyId: string, mediaId: string, relativePath: string, size: number): Promise<Buffer | null>;
    /** Purge toutes les tailles de miniatures d'un média (après édition). */
    purgeThumbs(familyId: string, mediaId: string): Promise<void>;
    /** Re-calcule size/etag depuis le disque (après édition en place). */
    refreshMetadata(familyId: string, relativePath: string): Promise<{
        size: number;
        etag: string;
    }>;
    /** Supprime l'original + les miniatures en cache. */
    deleteMedia(familyId: string, relativePath: string, mediaId: string): Promise<void>;
    /**
     * Flux de lecture avec support des requêtes Range (vidéo).
     * Retourne le flux + la taille totale.
     */
    openOriginal(familyId: string, relativePath: string, range?: RangeRequest): Promise<{
        stream: import("fs").ReadStream;
        size: number;
        start?: undefined;
        end?: undefined;
    } | {
        stream: null;
        size: number;
        start?: undefined;
        end?: undefined;
    } | {
        stream: import("fs").ReadStream;
        size: number;
        start: number;
        end: number;
    }>;
}
