export interface S3SyncOptions {
    source: string;
    bucket: string;
    prefix?: string;
    delete?: boolean;
    acl?: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read';
    cacheControl?: string;
    contentType?: string;
    metadata?: Record<string, string>;
    exclude?: string[];
    include?: string[];
    dryRun?: boolean;
}
export interface S3CopyOptions {
    source: string;
    bucket: string;
    key: string;
    acl?: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read';
    cacheControl?: string;
    contentType?: string;
    metadata?: Record<string, string>;
}
export interface S3ListOptions {
    bucket: string;
    prefix?: string;
    maxKeys?: number;
}
export interface S3Object {
    Key: string;
    LastModified: string;
    Size: number;
    ETag?: string;
}
/**
 * Options for configuring an {@link S3Client} against AWS S3 or an
 * S3-compatible provider (Backblaze B2, Hetzner Object Storage).
 */
export interface S3ClientOptions {
    /** AWS region used for signing. Defaults to `us-east-1`. */
    region?: string;
    /** Named AWS credential profile. */
    profile?: string;
    /**
     * HTTP(S) endpoint origin or host for S3-compatible providers, e.g.
     * `https://<account>.r2.cloudflarestorage.com` or `fsn1.your-objectstorage.com`.
     */
    endpoint?: string;
    /** Force path-style addressing instead of virtual-hosted. Defaults to virtual-hosted. */
    forcePathStyle?: boolean;
    /**
     * Explicit credentials. When set, these take precedence over profile/env
     * resolution — used by S3-compatible providers whose keys live in
     * provider-specific env vars rather than the AWS chain.
     */
    credentials?: {
        accessKeyId: string;
        secretAccessKey: string;
        sessionToken?: string;
    };
}
/**
 * S3 client using direct API calls
 */
export declare class S3Client {
    private client;
    private region;
    private explicitProfile?;
    private endpoint?;
    private endpointProtocol;
    private forcePathStyle?;
    private explicitCredentials?;
    constructor(region?: string, profile?: string, options?: S3ClientOptions);
    constructor(options?: S3ClientOptions);
    /**
     * Get credentials (used by presigned URL / bucket-policy paths that bypass AWSClient.request).
     * Explicit credentials win; otherwise honors the same explicit-vs-implicit profile
     * semantics as the constructor.
     */
    private getCredentials;
    /** Base S3 endpoint host (no bucket): the provider endpoint or AWS default. */
    private s3BaseHost;
    /**
     * Virtual-hosted-style host for a bucket. In path-style mode the bucket lives
     * in the request path instead, so this returns the bare base host.
     */
    private s3VirtualHost;
    private objectPath;
    private objectUrl;
    /**
     * List all S3 buckets in the account
     */
    listBuckets(): Promise<{
        Buckets: Array<{
            Name: string;
            CreationDate?: string;
        }>;
    }>;
    /**
     * Create an S3 bucket
     */
    createBucket(bucket: string, options?: {
        acl?: string;
    }): Promise<void>;
    /**
     * Delete an S3 bucket (must be empty)
     */
    deleteBucket(bucket: string): Promise<void>;
    /**
     * Empty and delete an S3 bucket
     */
    emptyAndDeleteBucket(bucket: string): Promise<void>;
    /**
     * List all objects in a bucket (handles pagination)
     */
    listAllObjects(options: S3ListOptions): Promise<S3Object[]>;
    /**
     * List objects in S3 bucket
     */
    list(options: S3ListOptions): Promise<S3Object[]>;
    /**
     * Put object to S3 bucket
     */
    putObject(options: {
        bucket: string;
        key: string;
        body: string | Buffer | Uint8Array;
        acl?: string;
        cacheControl?: string;
        contentType?: string;
        metadata?: Record<string, string>;
    }): Promise<void>;
    /**
     * Get object from S3 bucket
     * Returns raw content as string (not parsed as XML)
     */
    getObject(bucket: string, key: string): Promise<string>;
    /**
     * Get object as raw bytes (binary-safe).
     *
     * {@link getObject} decodes the response as UTF-8 text, which corrupts binary
     * payloads (images, archives, mail attachments). This issues a SigV4-signed
     * GET and reads the body via `arrayBuffer()`, preserving every byte. It also
     * returns the `content-type` header so a copy can faithfully reproduce it.
     *
     * Works against any S3-compatible provider (AWS, Backblaze, Hetzner) — it
     * signs against the same virtual-hosted/path-style host the client is
     * configured for.
     */
    getObjectBytes(bucket: string, key: string): Promise<{
        body: Uint8Array;
        contentType?: string;
        contentLength?: number;
    }>;
    /**
     * Copy object within S3 (server-side copy)
     */
    copyObject(options: {
        sourceBucket: string;
        sourceKey: string;
        destinationBucket: string;
        destinationKey: string;
        contentType?: string;
        metadata?: Record<string, string>;
        metadataDirective?: 'COPY' | 'REPLACE';
    }): Promise<void>;
    /**
     * Delete object from S3
     */
    deleteObject(bucket: string, key: string): Promise<void>;
    /**
     * Delete multiple objects from S3
     */
    deleteObjects(bucket: string, keys: string[]): Promise<void>;
    /**
     * Check if bucket exists
     */
    bucketExists(bucket: string): Promise<boolean>;
    /**
     * Copy file to S3
     */
    copy(options: S3CopyOptions): Promise<void>;
    /**
     * Sync local directory to S3 bucket
     * Note: This is a simplified version. For production use, implement proper sync logic
     */
    sync(options: S3SyncOptions): Promise<void>;
    /**
     * Delete object from S3 (alias for deleteObject)
     */
    delete(bucket: string, key: string): Promise<void>;
    /**
     * Delete all objects in a prefix
     */
    deletePrefix(bucket: string, prefix: string): Promise<void>;
    /**
     * Get bucket size
     */
    getBucketSize(bucket: string, prefix?: string): Promise<number>;
    /**
     * List files recursively in a directory
     */
    private listFilesRecursive;
    /**
     * Put bucket policy for an S3 bucket
     * Uses path-style URLs to avoid redirect issues
     */
    putBucketPolicy(bucket: string, policy: object | string): Promise<void>;
    /**
     * Get bucket policy for an S3 bucket
     * Uses path-style URLs to avoid redirect issues
     */
    getBucketPolicy(bucket: string): Promise<object | null>;
    /**
     * Delete bucket policy
     */
    deleteBucketPolicy(bucket: string): Promise<void>;
    /**
     * Head bucket - check if bucket exists and you have access
     */
    headBucket(bucket: string): Promise<{
        exists: boolean;
        region?: string;
    }>;
    /**
     * Head object - get object metadata without downloading
     */
    headObject(bucket: string, key: string): Promise<{
        ContentLength?: number;
        ContentType?: string;
        ETag?: string;
        LastModified?: string;
        Metadata?: Record<string, string>;
    } | null>;
    /**
     * Get object as Buffer
     */
    getObjectBuffer(bucket: string, key: string): Promise<Buffer>;
    /**
     * Get object as JSON
     */
    getObjectJson<T = any>(bucket: string, key: string): Promise<T>;
    /**
     * Put JSON object
     */
    putObjectJson(bucket: string, key: string, data: any, options?: {
        acl?: string;
        cacheControl?: string;
        metadata?: Record<string, string>;
    }): Promise<void>;
    /**
     * Get bucket versioning configuration
     */
    getBucketVersioning(bucket: string): Promise<{
        Status?: 'Enabled' | 'Suspended';
    }>;
    /**
     * Put bucket versioning configuration
     */
    putBucketVersioning(bucket: string, status: 'Enabled' | 'Suspended'): Promise<void>;
    /**
     * Get bucket lifecycle configuration
     */
    getBucketLifecycleConfiguration(bucket: string): Promise<any>;
    /**
     * Put bucket lifecycle configuration
     */
    putBucketLifecycleConfiguration(bucket: string, rules: Array<{
        ID: string;
        Status: 'Enabled' | 'Disabled';
        Filter?: {
            Prefix?: string;
        };
        Expiration?: {
            Days?: number;
            Date?: string;
        };
        Transitions?: Array<{
            Days?: number;
            StorageClass: string;
        }>;
        NoncurrentVersionExpiration?: {
            NoncurrentDays: number;
        };
    }>): Promise<void>;
    /**
     * Delete bucket lifecycle configuration
     */
    deleteBucketLifecycleConfiguration(bucket: string): Promise<void>;
    /**
     * Get bucket CORS configuration
     */
    getBucketCors(bucket: string): Promise<any>;
    /**
     * Put bucket CORS configuration
     */
    putBucketCors(bucket: string, rules: Array<{
        AllowedOrigins: string[];
        AllowedMethods: string[];
        AllowedHeaders?: string[];
        ExposeHeaders?: string[];
        MaxAgeSeconds?: number;
    }>): Promise<void>;
    /**
     * Delete bucket CORS configuration
     */
    deleteBucketCors(bucket: string): Promise<void>;
    /**
     * Get bucket encryption configuration
     */
    getBucketEncryption(bucket: string): Promise<any>;
    /**
     * Put bucket encryption configuration
     */
    putBucketEncryption(bucket: string, sseAlgorithm: 'AES256' | 'aws:kms', kmsKeyId?: string): Promise<void>;
    /**
     * Delete bucket encryption configuration
     */
    deleteBucketEncryption(bucket: string): Promise<void>;
    /**
     * Get bucket tagging
     */
    getBucketTagging(bucket: string): Promise<Array<{
        Key: string;
        Value: string;
    }>>;
    /**
     * Put bucket tagging
     */
    putBucketTagging(bucket: string, tags: Array<{
        Key: string;
        Value: string;
    }>): Promise<void>;
    /**
     * Delete bucket tagging
     */
    deleteBucketTagging(bucket: string): Promise<void>;
    /**
     * Get object tagging
     */
    getObjectTagging(bucket: string, key: string): Promise<Array<{
        Key: string;
        Value: string;
    }>>;
    /**
     * Put object tagging
     */
    putObjectTagging(bucket: string, key: string, tags: Array<{
        Key: string;
        Value: string;
    }>): Promise<void>;
    /**
     * Delete object tagging
     */
    deleteObjectTagging(bucket: string, key: string): Promise<void>;
    /**
     * Get bucket ACL
     */
    getBucketAcl(bucket: string): Promise<any>;
    /**
     * Put bucket ACL (canned ACL)
     */
    putBucketAcl(bucket: string, acl: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read'): Promise<void>;
    /**
     * Get object ACL
     */
    getObjectAcl(bucket: string, key: string): Promise<any>;
    /**
     * Put object ACL (canned ACL)
     */
    putObjectAcl(bucket: string, key: string, acl: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read'): Promise<void>;
    /**
     * Get bucket location
     */
    getBucketLocation(bucket: string): Promise<string>;
    /**
     * Get bucket logging configuration
     */
    getBucketLogging(bucket: string): Promise<any>;
    /**
     * Put bucket logging configuration
     */
    putBucketLogging(bucket: string, targetBucket: string, targetPrefix: string): Promise<void>;
    /**
     * Get bucket notification configuration
     */
    getBucketNotificationConfiguration(bucket: string): Promise<any>;
    /**
     * Put bucket notification configuration
     */
    putBucketNotificationConfiguration(bucket: string, config: {
        LambdaFunctionConfigurations?: Array<{
            Id?: string;
            LambdaFunctionArn: string;
            Events: string[];
            Filter?: {
                Key?: {
                    FilterRules: Array<{
                        Name: string;
                        Value: string;
                    }>;
                };
            };
        }>;
        TopicConfigurations?: Array<{
            Id?: string;
            TopicArn: string;
            Events: string[];
            Filter?: {
                Key?: {
                    FilterRules: Array<{
                        Name: string;
                        Value: string;
                    }>;
                };
            };
        }>;
        QueueConfigurations?: Array<{
            Id?: string;
            QueueArn: string;
            Events: string[];
            Filter?: {
                Key?: {
                    FilterRules: Array<{
                        Name: string;
                        Value: string;
                    }>;
                };
            };
        }>;
    }): Promise<void>;
    /**
     * Get bucket website configuration
     */
    getBucketWebsite(bucket: string): Promise<any>;
    /**
     * Put bucket website configuration
     */
    putBucketWebsite(bucket: string, config: {
        IndexDocument: string;
        ErrorDocument?: string;
        RedirectAllRequestsTo?: {
            HostName: string;
            Protocol?: string;
        };
    }): Promise<void>;
    /**
     * Delete bucket website configuration
     */
    deleteBucketWebsite(bucket: string): Promise<void>;
    /**
     * Get bucket replication configuration
     */
    getBucketReplication(bucket: string): Promise<any>;
    /**
     * Delete bucket replication configuration
     */
    deleteBucketReplication(bucket: string): Promise<void>;
    /**
     * Get public access block configuration
     */
    getPublicAccessBlock(bucket: string): Promise<any>;
    /**
     * Put public access block configuration
     */
    putPublicAccessBlock(bucket: string, config: {
        BlockPublicAcls?: boolean;
        IgnorePublicAcls?: boolean;
        BlockPublicPolicy?: boolean;
        RestrictPublicBuckets?: boolean;
    }): Promise<void>;
    /**
     * Delete public access block configuration
     */
    deletePublicAccessBlock(bucket: string): Promise<void>;
    /**
     * Generate a presigned URL for GET
     */
    generatePresignedGetUrl(bucket: string, key: string, expiresInSeconds?: number): string;
    /**
     * Generate a presigned URL for PUT
     */
    generatePresignedPutUrl(bucket: string, key: string, contentType: string, expiresInSeconds?: number): string;
    /**
     * Initiate multipart upload
     */
    createMultipartUpload(bucket: string, key: string, options?: {
        contentType?: string;
        metadata?: Record<string, string>;
    }): Promise<{
        UploadId: string;
    }>;
    /**
     * Upload a part in multipart upload
     */
    uploadPart(bucket: string, key: string, uploadId: string, partNumber: number, body: Uint8Array | Buffer): Promise<{
        ETag: string;
    }>;
    /**
     * Complete multipart upload
     */
    completeMultipartUpload(bucket: string, key: string, uploadId: string, parts: Array<{
        PartNumber: number;
        ETag: string;
    }>): Promise<void>;
    /**
     * Abort multipart upload
     */
    abortMultipartUpload(bucket: string, key: string, uploadId: string): Promise<void>;
    /**
     * List multipart uploads
     */
    listMultipartUploads(bucket: string): Promise<Array<{
        Key: string;
        UploadId: string;
        Initiated: string;
    }>>;
    /**
     * Restore object from Glacier
     */
    restoreObject(bucket: string, key: string, days: number, tier?: 'Standard' | 'Bulk' | 'Expedited'): Promise<void>;
    /**
     * Select object content (S3 Select)
     */
    selectObjectContent(bucket: string, key: string, expression: string, inputFormat: 'CSV' | 'JSON' | 'Parquet', outputFormat?: 'CSV' | 'JSON'): Promise<string>;
    /**
     * Generate a presigned URL for S3 object access
     * Allows temporary access to private objects without authentication
     */
    getSignedUrl(options: {
        bucket: string;
        key: string;
        expiresIn?: number;
        operation?: 'getObject' | 'putObject';
    }): Promise<string>;
    /**
     * List objects in a bucket with pagination support
     */
    listObjects(options: {
        bucket: string;
        prefix?: string;
        maxKeys?: number;
        continuationToken?: string;
    }): Promise<{
        objects: S3Object[];
        nextContinuationToken?: string;
    }>;
    /**
     * Empty a bucket by deleting all objects (required before bucket deletion)
     */
    emptyBucket(bucket: string): Promise<{
        deletedCount: number;
    }>;
    /**
     * List object versions in a bucket
     */
    listObjectVersions(options: {
        bucket: string;
        prefix?: string;
        keyMarker?: string;
        versionIdMarker?: string;
        maxKeys?: number;
    }): Promise<{
        versions: Array<{
            Key: string;
            VersionId: string;
            IsLatest: boolean;
        }>;
        deleteMarkers: Array<{
            Key: string;
            VersionId: string;
            IsLatest: boolean;
        }>;
        nextKeyMarker?: string;
        nextVersionIdMarker?: string;
    }>;
    /**
     * Delete specific object versions
     */
    deleteObjectVersions(bucket: string, objects: Array<{
        Key: string;
        VersionId?: string;
    }>): Promise<void>;
}
