import { type DrizzleExecutor } from "../drizzle.js"; import { type Readable, type Writable } from "node:stream"; import type { ServerConfig } from "../config/type.js"; import type { StoredFile } from "../file/types.js"; import type { User } from "../user/types.js"; import { type MediaProcessor } from "./media.js"; import { type ByteRange, type FileStorageProvider, type MediaVariant, type ResumableUpload } from "./provider.js"; import { type FileQuotaPolicy, type QuotaScope } from "./quota.js"; import { type MalwareScanner } from "./scanner.js"; export interface AvatarCrop { readonly x: number; readonly y: number; readonly width: number; readonly height: number; } export interface FileStorageFileSystem { mkdir(path: string): Promise; readHeader(path: string, maximumBytes: number): Promise; imageSource(path: string): Promise; rename(from: string, to: string): Promise; rm(path: string): Promise; writeFile(path: string, contents: Buffer): Promise; createReadStream(path: string, range?: { start: number; end: number; }): Readable; createWriteStream(path: string): Writable; } export declare class InvalidUploadError extends Error { constructor(message: string, options?: ErrorOptions); } export declare class UploadRejectedError extends Error { readonly reason: "malware" | "scanner_unavailable"; constructor(reason: "malware" | "scanner_unavailable"); } export declare class FileQuotaExceededError extends InvalidUploadError { readonly scope: QuotaScope; readonly limit: number; constructor(scope: QuotaScope, limit: number); } export interface FileStorageOptions { provider?: FileStorageProvider; quota?: FileQuotaPolicy; scanner?: MalwareScanner; mediaProcessor?: MediaProcessor; } export declare class FileStorage { private readonly config; private readonly executor; private readonly provider; private readonly quota; private readonly scanner; private readonly mediaProcessor; constructor(config: ServerConfig, executor: DrizzleExecutor, optionsOrFileSystem?: FileStorageOptions | FileStorageFileSystem); /** Validates an orientation-normalized square crop and persists only its normalized avatar. */ saveAvatarUpload(user: User, input: Buffer, crop: AvatarCrop, isPublic: boolean): Promise; saveAttachmentUpload(user: User, input: Readable, upload: { filename?: string; contentType?: string; }): Promise; createResumableUpload(user: User, input: { filename?: string; contentType?: string; size: number; }): Promise; resumableUploadState(userId: string, uploadId: string): Promise; appendResumableUpload(userId: string, uploadId: string, expectedOffset: number, input: Readable): Promise; completeResumableUpload(user: User, uploadId: string): Promise; cancelResumableUpload(userId: string, uploadId: string): Promise; open(file: Pick, range?: ByteRange): Readable; variant(file: StoredFile, variant: MediaVariant): Promise<{ size: number; contentType: "image/webp"; stream: Readable; } | undefined>; variantSizes(file: StoredFile): Promise>>; /** Local-only compatibility helper; consumers should prefer open(). */ pathFor(file: StoredFile): string; /** Call only after the durable file record and references have been removed. */ deleteStoredFile(file: StoredFile): Promise; /** * Maintenance is intentionally caller-driven so deployments can run it * under a distributed lease. It cleans abandoned uploads/quarantine and, * when given the authoritative file records, unreferenced local objects. */ runMaintenance(input: { now?: Date; referencedFiles?: Iterable; orphanGraceMs?: number; }): Promise<{ expiredUploadIds: string[]; deletedQuarantineObjects: number; deletedOrphanStorageNames: string[]; }>; private saveStagedAttachment; private prepareQuota; private assertSafe; private commitFile; createReadStream(file: StoredFile, range?: { start: number; end: number; }): Readable; } //# sourceMappingURL=storage.d.ts.map