/**
 * Upload direct téléphone → Nextcloud familial.
 *
 * Ce module est utilisé par l'app mobile (jamais les octets ne passent par le
 * backend central) ET par les tests d'intégration serveur.
 * - < 10 Mo : PUT simple
 * - >= 10 Mo : chunking v2 (MKCOL uploads/ → PUT parts → MOVE .file)
 * - mtime fixé via X-OC-Mtime (survit à la reconstruction de l'index)
 * - idempotence : HEAD sur la destination avant de renvoyer
 *
 * La source des octets est un `UploadData` (voir plus bas) : côté mobile c'est
 * un adaptateur sur `expo-file-system` `File` (streaming depuis le disque,
 * plages lues via FileHandle), côté serveur/tests un Blob normalisé par
 * `blobUploadData`.
 */
/**
 * Source de données d'un upload.
 * Deux implémentations :
 * - `blobUploadData(blob)` — Blob/Uint8Array (tests serveur, Node) ;
 * - côté mobile, un adaptateur sur `expo-file-system` `File` : le PUT simple
 *   streame depuis le disque (`asBody` rend le File directement), le chunking
 *   lit les plages via `FileHandle.readBytes` (10 Mo par part, jamais le
 *   fichier entier en mémoire).
 */
export interface UploadData {
    /** Taille totale en octets. */
    size: number;
    /** Corps à passer à fetch pour le PUT simple — streamé depuis le disque quand possible. */
    asBody(): BodyInit;
    /**
     * Lit une plage [start, end) — utilisée par le chunking. Retourne un
     * BodyInit (Blob côté serveur, Uint8Array côté mobile) : pas de `new Blob`
     * sur le mobile — le polyfill RN rejette les ArrayBufferView
     * (« Creating blobs from 'ArrayBuffer' and 'ArrayBufferView' are not
     * supported »), et le fetch (WinterCG) accepte le Uint8Array tel quel.
     */
    readRange(start: number, end: number): Promise<BodyInit>;
    /** Libère les ressources (FileHandle) — appelé après l'upload, même en erreur. */
    close?(): void;
}
/** Normalise un Blob/Uint8Array en UploadData (serveur, tests, web). */
export declare function blobUploadData(data: Blob | Uint8Array): UploadData;
export interface NextcloudUploadOptions {
    baseUrl: string;
    loginName: string;
    appPassword: string;
    rootFolder: string;
    /** Nom du fichier destination (déjà au format {YYYYMMDD-HHmmss}_{id}.{ext}) */
    fileName: string;
    /** Source des octets : adaptateur UploadData, ou Blob/Uint8Array (normalisé). */
    data: UploadData | Blob | Uint8Array;
    /** Date de capture — envoyée en X-OC-Mtime (timestamp unix) */
    capturedAt: Date;
    timeoutMs?: number;
}
export declare class NextcloudUploadError extends Error {
    readonly httpStatus: number;
    constructor(message: string, httpStatus: number);
}
export declare function fileExistsInNextcloud(opts: Pick<NextcloudUploadOptions, "baseUrl" | "loginName" | "appPassword" | "rootFolder" | "fileName" | "capturedAt" | "timeoutMs">): Promise<boolean>;
export declare function uploadToNextcloud(opts: NextcloudUploadOptions): Promise<void>;
export declare function base64Encode(input: string): string;
/** Identifiant court (8 caractères alphanumériques) pour les noms de fichiers. */
export declare function shortId(length?: number): string;
/**
 * Nom de fichier canonique : {YYYYMMDD-HHmmss}_{shortuuid}.{ext}
 * — la date de capture survit même si l'index est reconstruit de zéro.
 * — le shortuuid sert de clé d'idempotence pour la reprise d'upload.
 */
export declare function buildMediaFileName(capturedAt: Date, extension: string): string;
export declare function davPath(opts: {
    baseUrl: string;
    loginName: string;
    rootFolder: string;
    fileName: string;
    capturedAt: Date;
}): string;
