import { Alepha, AlephaError, FileLike, KIND, Primitive, Service, Static } from "alepha";
import { FileDetector, FileSystemProvider } from "alepha/system";
import { CryptoProvider } from "alepha/crypto";
import * as fs from "node:fs";
import { S3mini } from "s3mini";
import { R2Bucket } from "@cloudflare/workers-types";
//#region ../../src/bucket/providers/FileStorageProvider.d.ts
declare abstract class FileStorageProvider {
  /**
   * Uploads a file to the storage.
   *
   * @param bucketName - Container name
   * @param file - File to upload
   * @param fileId - Optional file identifier. If not provided, a unique ID will be generated.
   * @return The identifier of the uploaded file.
   */
  abstract upload(bucketName: string, file: FileLike, fileId?: string): Promise<string>;
  /**
   * Downloads a file from the storage.
   *
   * @param bucketName - Container name
   * @param fileId - Identifier of the file to download
   * @return The downloaded file as a FileLike object.
   */
  abstract download(bucketName: string, fileId: string): Promise<FileLike>;
  /**
   * Check if fileId exists in the storage bucket.
   *
   * @param bucketName - Container name
   * @param fileId - Identifier of the file to stream
   * @return True is the file exists, false otherwise.
   */
  abstract exists(bucketName: string, fileId: string): Promise<boolean>;
  /**
   * Delete permanently a file from the storage.
   *
   * @param bucketName - Container name
   * @param fileId - Identifier of the file to delete
   */
  abstract delete(bucketName: string, fileId: string): Promise<void>;
  /**
   * Delete multiple files in one round-trip where the provider supports
   * batch (R2/S3, up to 1000 per call). Memory/Local fall back to a loop.
   *
   * @param bucketName - Container name
   * @param fileIds - Identifiers of the files to delete
   */
  abstract deleteMany(bucketName: string, fileIds: string[]): Promise<void>;
  /**
   * Lists the file identifiers stored in a bucket, like `ls` on a directory.
   *
   * This is a flat, unpaginated listing intended for small buckets. Providers
   * cap the result at their natural page size (~1000 for S3/R2); anything beyond
   * that is silently dropped. It is NOT a search API — use `alepha/api/files`
   * when you need querying or pagination.
   *
   * @param bucketName - Container name
   * @return The identifiers of the files in the bucket (empty if none).
   */
  abstract list(bucketName: string): Promise<string[]>;
}
//#endregion
//#region ../../src/bucket/providers/MemoryFileStorageProvider.d.ts
interface StoredFile {
  buffer: Buffer;
  name: string;
  type: string;
  size: number;
}
declare class MemoryFileStorageProvider implements FileStorageProvider {
  readonly files: Record<string, StoredFile>;
  protected readonly alepha: Alepha;
  protected readonly fileSystem: FileSystemProvider;
  protected readonly fileDetector: FileDetector;
  protected readonly crypto: CryptoProvider;
  upload(bucketName: string, file: FileLike, fileId?: string): Promise<string>;
  download(bucketName: string, fileId: string): Promise<FileLike>;
  exists(bucketName: string, fileId: string): Promise<boolean>;
  delete(bucketName: string, fileId: string): Promise<void>;
  deleteMany(bucketName: string, fileIds: string[]): Promise<void>;
  list(bucketName: string): Promise<string[]>;
  /**
   * In-memory key, tenant-scoped when a tenant is active (`currentTenantAtom`),
   * mirroring the R2/Local/S3 layout: `{tenantId}/{bucket}/{fileId}`.
   */
  protected key(bucket: string, fileId?: string): string;
  protected createId(): string;
}
//#endregion
//#region ../../src/bucket/primitives/$bucket.d.ts
/**
 * Creates a bucket primitive for file storage and management with configurable validation.
 *
 * Provides a comprehensive file storage system that handles uploads, downloads, validation,
 * and management across multiple storage backends with MIME type and size limit controls.
 *
 * **Key Features**
 * - Multi-provider support (filesystem, cloud storage, in-memory)
 * - Automatic MIME type and file size validation
 * - Event integration for file operations monitoring
 * - Flexible per-bucket and per-operation configuration
 * - Smart file type and size detection
 *
 * **Common Use Cases**
 * - User profile pictures and document uploads
 * - Product images and media management
 * - Document storage and retrieval systems
 *
 * @example
 * ```ts
 * class MediaService {
 *   images = $bucket({
 *     name: "user-images",
 *     mimeTypes: ["image/jpeg", "image/png", "image/gif"],
 *     maxSize: 5 // 5MB limit
 *   });
 *
 *   documents = $bucket({
 *     name: "documents",
 *     mimeTypes: ["application/pdf", "text/plain"],
 *     maxSize: 50 // 50MB limit
 *   });
 *
 *   async uploadProfileImage(file: FileLike, userId: string): Promise<string> {
 *     const fileId = await this.images.upload(file);
 *     await this.userService.updateProfileImage(userId, fileId);
 *     return fileId;
 *   }
 *
 *   async downloadDocument(documentId: string): Promise<FileLike> {
 *     return await this.documents.download(documentId);
 *   }
 *
 *   async deleteDocument(documentId: string): Promise<void> {
 *     await this.documents.delete(documentId);
 *   }
 * }
 * ```
 */
declare const $bucket: {
  (options: BucketPrimitiveOptions): BucketPrimitive;
  [KIND]: typeof BucketPrimitive;
};
interface BucketPrimitiveOptions extends BucketFileOptions {
  /**
   * File storage provider configuration for the bucket.
   *
   * Options:
   * - **"memory"**: In-memory storage (default for development, lost on restart)
   * - **Service<FileStorageProvider>**: Custom provider class (e.g., S3FileStorageProvider, AzureBlobProvider)
   * - **undefined**: Uses the default file storage provider from dependency injection
   *
   * **Provider Selection Guidelines**:
   * - **Development**: Use "memory" for fast, simple testing without external dependencies
   * - **Production**: Use cloud providers (S3, Azure Blob, Google Cloud Storage) for scalability
   * - **Local deployment**: Use filesystem providers for on-premise installations
   * - **Hybrid**: Use different providers for different bucket types (temp files vs permanent storage)
   *
   * **Provider Capabilities**:
   * - File persistence and durability guarantees
   * - Scalability and performance characteristics
   * - Geographic distribution and CDN integration
   * - Cost implications for storage and bandwidth
   * - Backup and disaster recovery features
   *
   * @default Uses injected FileStorageProvider
   * @example "memory"
   * @example S3FileStorageProvider
   * @example AzureBlobStorageProvider
   */
  provider?: Service<FileStorageProvider> | "memory";
  /**
   * Unique name identifier for the bucket.
   *
   * This name is used for:
   * - Storage backend organization and partitioning
   * - File path generation and URL construction
   * - Logging, monitoring, and debugging
   * - Access control and permissions management
   * - Backup and replication configuration
   *
   * **Naming Conventions**:
   * - Use lowercase with hyphens for consistency
   * - Include purpose or content type in the name
   * - Avoid spaces and special characters
   * - Consider environment prefixes for deployment isolation
   *
   * If not provided, defaults to the property key where the bucket is declared.
   *
   * @example "user-avatars"
   * @example "product-images"
   * @example "legal-documents"
   * @example "temp-processing-files"
   */
  name?: string;
}
interface BucketFileOptions {
  /**
   * Human-readable description of the bucket's purpose and contents.
   *
   * Used for:
   * - Documentation generation and API references
   * - Developer onboarding and system understanding
   * - Monitoring dashboards and admin interfaces
   * - Compliance and audit documentation
   *
   * **Description Best Practices**:
   * - Explain what types of files this bucket stores
   * - Mention any special handling or processing requirements
   * - Include information about retention policies if applicable
   * - Note any compliance or security considerations
   *
   * @example "User profile pictures and avatar images"
   * @example "Product catalog images with automated thumbnail generation"
   * @example "Legal documents requiring long-term retention"
   * @example "Temporary files for data processing workflows"
   */
  description?: string;
  /**
   * Array of allowed MIME types for files uploaded to this bucket.
   *
   * When specified, only files with these exact MIME types will be accepted.
   * Files with disallowed MIME types will be rejected with an InvalidFileError.
   *
   * **MIME Type Categories**:
   * - Images: "image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"
   * - Documents: "application/pdf", "text/plain", "text/csv"
   * - Office: "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
   * - Archives: "application/zip", "application/x-tar", "application/gzip"
   * - Media: "video/mp4", "audio/mpeg", "audio/wav"
   *
   * **Security Considerations**:
   * - Always validate MIME types for user uploads
   * - Be cautious with executable file types
   * - Consider using allow-lists rather than deny-lists
   * - Remember that MIME types can be spoofed by malicious users
   *
   * If not specified, all MIME types are allowed (not recommended for user uploads).
   *
   * @example ["image/jpeg", "image/png"] // Only JPEG and PNG images
   * @example ["application/pdf", "text/plain"] // Documents only
   * @example ["video/mp4", "video/webm"] // Video files
   */
  mimeTypes?: string[];
  /**
   * Maximum file size allowed in megabytes (MB).
   *
   * Files larger than this limit will be rejected with an InvalidFileError.
   * This helps prevent:
   * - Storage quota exhaustion
   * - Memory issues during file processing
   * - Long upload times and timeouts
   * - Abuse of storage resources
   *
   * **Size Guidelines by File Type**:
   * - Profile images: 1-5 MB
   * - Product photos: 5-10 MB
   * - Documents: 10-50 MB
   * - Video files: 50-500 MB
   * - Data files: 100-1000 MB
   *
   * **Considerations**:
   * - Consider your storage costs and limits
   * - Factor in network upload speeds for users
   * - Account for processing requirements (thumbnails, compression)
   * - Set reasonable limits based on actual use cases
   *
   * @default 10 MB
   *
   * @example 1    // 1MB for small images
   * @example 25   // 25MB for documents
   * @example 100  // 100MB for media files
   */
  maxSize?: number;
}
declare class BucketPrimitive extends Primitive<BucketPrimitiveOptions> {
  readonly provider: FileStorageProvider | MemoryFileStorageProvider;
  protected readonly fileSystem: FileSystemProvider;
  get name(): string;
  /**
   * Uploads a file to the bucket.
   */
  upload(file: FileLike, options?: BucketFileOptions): Promise<string>;
  /**
   * Delete permanently a file from the bucket.
   */
  delete(fileId: string, skipHook?: boolean): Promise<void>;
  /**
   * Delete many files in one round-trip when the underlying provider supports
   * batch (R2/S3 up to 1000 keys per call). Emits one `bucket:file:deleted`
   * event per id unless `skipHook` is set.
   */
  deleteMany(fileIds: string[], skipHook?: boolean): Promise<void>;
  /**
   * Checks if a file exists in the bucket.
   */
  exists(fileId: string): Promise<boolean>;
  /**
   * Lists the file identifiers stored in the bucket, like `ls` on a directory.
   *
   * This is a flat, unpaginated listing meant for small buckets — the result is
   * capped at the provider's natural page size (~1000 for S3/R2) and anything
   * beyond that is silently dropped. It is NOT a search API; reach for
   * `alepha/api/files` when you need querying or pagination.
   */
  list(): Promise<string[]>;
  /**
   * Downloads a file from the bucket.
   */
  download(fileId: string): Promise<FileLike>;
  protected $provider(): FileStorageProvider | MemoryFileStorageProvider;
}
interface BucketFileOptions {
  /**
   * Optional description of the bucket.
   */
  description?: string;
  /**
   * Allowed MIME types.
   */
  mimeTypes?: string[];
  /**
   * Maximum size of the files in the bucket.
   *
   * @default 10
   */
  maxSize?: number;
}
//#endregion
//#region ../../src/bucket/errors/FileNotFoundError.d.ts
declare class FileNotFoundError extends AlephaError {
  readonly status = 404;
}
//#endregion
//#region ../../src/bucket/providers/LocalFileStorageProvider.d.ts
/**
 * Local file storage configuration atom
 */
declare const localFileStorageOptions: import("alepha").Atom<import("zod").ZodObject<{
  storagePath: import("zod").ZodString;
}, import("zod/v4/core").$strip>, "alepha.bucket.local.options">;
type LocalFileStorageProviderOptions = Static<typeof localFileStorageOptions.schema>;
declare module "alepha" {
  interface State {
    [localFileStorageOptions.key]: LocalFileStorageProviderOptions;
  }
}
declare class LocalFileStorageProvider implements FileStorageProvider {
  protected readonly alepha: Alepha;
  protected readonly log: import("alepha/logger").Logger;
  protected readonly fileDetector: FileDetector;
  protected readonly fileSystemProvider: FileSystemProvider;
  protected readonly crypto: CryptoProvider;
  protected readonly options: Readonly<{
    storagePath: string;
  }>;
  protected get storagePath(): string;
  protected readonly onConfigure: import("alepha").HookPrimitive<"configure">;
  protected readonly onStart: import("alepha").HookPrimitive<"start">;
  upload(bucketName: string, file: FileLike, fileId?: string): Promise<string>;
  download(bucketName: string, fileId: string): Promise<FileLike>;
  exists(bucketName: string, fileId: string): Promise<boolean>;
  delete(bucketName: string, fileId: string): Promise<void>;
  deleteMany(bucketName: string, fileIds: string[]): Promise<void>;
  list(bucketName: string): Promise<string[]>;
  protected stat(bucket: string, fileId: string): Promise<fs.Stats>;
  protected createId(mimeType: string): string;
  protected path(bucket: string, fileId?: string): string;
  protected isErrorNoEntry(error: unknown): boolean;
}
//#endregion
//#region ../../src/bucket/providers/R2FileStorageProvider.d.ts
/**
 * Cloudflare R2 storage provider.
 *
 * Uses a single R2 bucket binding for all $bucket primitives.
 * Files are organized as: {APP_NAME}/{bucketName}/{fileId}
 *
 * **Required environment variables:**
 * - `R2_BUCKET_NAME` - The actual R2 bucket name in Cloudflare
 *
 * **Optional (uses core Alepha env):**
 * - `APP_NAME` - Prefix for all files (for multi-app setups sharing one R2 bucket)
 *
 * @example
 * ```bash
 * # .env
 * APP_NAME=myapp        # optional, used as prefix
 * R2_BUCKET_NAME=storage
 * ```
 *
 * @example
 * ```toml
 * # wrangler.toml - automatically generated by alepha build
 * [[r2_buckets]]
 * binding = "R2"
 * bucket_name = "storage"
 * ```
 *
 * @example
 * ```ts
 * // Define buckets with validation rules
 * const avatars = $bucket({
 *   name: "avatars",
 *   maxFileSize: 5 * 1024 * 1024,
 *   allowedMimeTypes: ["image/*"],
 * });
 *
 * const documents = $bucket({
 *   name: "documents",
 *   maxFileSize: 50 * 1024 * 1024,
 *   allowedMimeTypes: ["application/pdf"],
 * });
 *
 * // Files stored at: myapp/avatars/uuid.png, myapp/documents/uuid.pdf
 * ```
 */
declare class R2FileStorageProvider implements FileStorageProvider {
  protected readonly alepha: Alepha;
  protected readonly log: import("alepha/logger").Logger;
  protected readonly crypto: CryptoProvider;
  protected readonly env: {
    R2_BUCKET_NAME: string;
  };
  protected r2?: R2Bucket;
  /**
   * Get the R2 bucket name from environment.
   */
  get bucketName(): string;
  /**
   * Get the optional prefix from APP_NAME environment variable.
   * Used for multi-app setups sharing the same R2 bucket.
   */
  get prefix(): string | undefined;
  protected readonly onStart: import("alepha").HookPrimitive<"start">;
  upload(bucketName: string, file: FileLike, fileId?: string): Promise<string>;
  download(bucketName: string, fileId: string): Promise<FileLike>;
  exists(bucketName: string, fileId: string): Promise<boolean>;
  delete(bucketName: string, fileId: string): Promise<void>;
  deleteMany(bucketName: string, fileIds: string[]): Promise<void>;
  list(bucketName: string): Promise<string[]>;
  /**
   * Build the full R2 key: {prefix}/{tenantId}/{bucketName}/{fileId}
   *
   * When a tenant is active on the current request/job (`currentTenantAtom`),
   * its id is inserted as a directory so a pooled multi-tenant worker keeps
   * each tenant's objects isolated. No tenant → the historical
   * `{prefix}/{bucketName}/{fileId}` layout is unchanged.
   */
  protected key(bucketName: string, fileId: string): string;
  protected getR2(): R2Bucket;
  protected createId(filename: string): string;
}
//#endregion
//#region ../../src/bucket/providers/S3FileStorageProvider.d.ts
declare const envSchema: import("zod").ZodObject<{
  S3_ENDPOINT: import("zod").ZodString;
  S3_REGION: import("zod").ZodOptional<import("zod").ZodString>;
  S3_ACCESS_KEY_ID: import("zod").ZodString;
  S3_SECRET_ACCESS_KEY: import("zod").ZodString;
}, import("zod/v4/core").$strip>;
declare module "alepha" {
  interface Env extends Partial<Static<typeof envSchema>> {}
}
/**
 * S3-compatible file storage provider for Node.js.
 *
 * Backed by `s3mini` (zero-dep, ~20 KB). Works with AWS S3, Cloudflare R2,
 * MinIO, DigitalOcean Spaces, Backblaze B2, and any other S3-compatible service.
 *
 * Uses path-style addressing (`<endpoint>/<bucket>`).
 */
declare class S3FileStorageProvider implements FileStorageProvider {
  protected readonly log: import("alepha/logger").Logger;
  protected readonly env: {
    S3_ENDPOINT: string;
    S3_REGION?: string | undefined;
    S3_ACCESS_KEY_ID: string;
    S3_SECRET_ACCESS_KEY: string;
  };
  protected readonly alepha: Alepha;
  protected readonly fileSystem: FileSystemProvider;
  protected readonly fileDetector: FileDetector;
  protected readonly crypto: CryptoProvider;
  protected readonly clients: Map<string, S3mini>;
  /**
   * Convert bucket name to S3-compatible format.
   * S3 bucket names must be lowercase, 3-63 characters, no underscores.
   */
  convertName(name: string): string;
  protected getClient(bucketName: string): S3mini;
  protected readonly onStart: import("alepha").HookPrimitive<"start">;
  /**
   * Object key, tenant-scoped when a tenant is active (`currentTenantAtom`):
   * `{tenantId}/{fileId}` within the per-bucket S3 bucket. No tenant → `{fileId}`.
   */
  protected key(fileId: string): string;
  protected createId(mimeType: string): string;
  upload(bucketName: string, file: FileLike, fileId?: string): Promise<string>;
  download(bucketName: string, fileId: string): Promise<FileLike>;
  exists(bucketName: string, fileId: string): Promise<boolean>;
  delete(bucketName: string, fileId: string): Promise<void>;
  list(bucketName: string): Promise<string[]>;
  deleteMany(bucketName: string, fileIds: string[]): Promise<void>;
}
//#endregion
//#region ../../src/bucket/index.d.ts
declare module "alepha" {
  interface Hooks {
    /**
     * Triggered when a file is uploaded to a bucket.
     * Can be used to perform actions after a file is uploaded, like creating a database record!
     */
    "bucket:file:uploaded": {
      id: string;
      file: FileLike;
      bucket: BucketPrimitive;
      options: BucketFileOptions;
    };
    /**
     * Triggered when a file is deleted from a bucket.
     */
    "bucket:file:deleted": {
      id: string;
      bucket: BucketPrimitive;
    };
    /**
     * Triggered when a file is downloaded from a bucket.
     */
    "bucket:file:downloaded": {
      id: string;
      file: FileLike;
      bucket: BucketPrimitive;
    };
  }
}
/**
 * Unified file storage abstraction across multiple backends.
 *
 * **Features:**
 * - File storage buckets with constraints
 * - Unified API across all storage backends
 * - MIME type validation
 * - File size limits
 * - Upload/download/delete operations
 * - TTL-based file expiration
 * - Providers: Memory (testing), Local filesystem, AWS S3 / Cloudflare R2 / MinIO, Azure Blob Storage, Vercel Blob
 *
 * @module alepha.bucket
 */
declare const AlephaBucket: import("alepha").Service<import("alepha").Module>;
//#endregion
export { $bucket, AlephaBucket, BucketFileOptions, BucketPrimitive, BucketPrimitiveOptions, FileNotFoundError, FileStorageProvider, LocalFileStorageProvider, LocalFileStorageProviderOptions, MemoryFileStorageProvider, R2FileStorageProvider, S3FileStorageProvider, localFileStorageOptions };
//# sourceMappingURL=index.d.ts.map