import { S3Client } from 'bun';

interface S3Config {
    accessKeyId: string;
    secretAccessKey: string;
    endpoint: string;
    region?: string;
    requestSizeInBytes?: number;
    requestAbortTimeout?: number;
    logger?: Logger;
}
interface SSECHeaders {
    'x-amz-server-side-encryption-customer-algorithm': string;
    'x-amz-server-side-encryption-customer-key': string;
    'x-amz-server-side-encryption-customer-key-md5': string;
}
interface Logger {
    info: (message: string, ...args: unknown[]) => void;
    warn: (message: string, ...args: unknown[]) => void;
    error: (message: string, ...args: unknown[]) => void;
}
interface UploadPart {
    partNumber: number;
    etag: string;
}
interface ListObject {
    Key: string;
    Size: number;
    LastModified: Date;
    ETag: string;
    StorageClass: string;
}
interface CompleteMultipartUploadResult {
    location: string;
    bucket: string;
    key: string;
    etag: string;
    eTag: string;
    ETag: string;
}
interface ListBucketResult {
    keyCount: string;
    contents?: Array<Record<string, unknown>>;
}
interface ListBucketError {
    error: {
        code: string;
        message: string;
    };
}
type ListBucketResponse = {
    listBucketResult: ListBucketResult;
} | {
    error: ListBucketError;
};
interface ListMultipartUploadSuccess {
    listMultipartUploadsResult: {
        bucket: string;
        key: string;
        uploadId: string;
        size?: number;
        mtime?: Date | undefined;
        etag?: string;
        eTag?: string;
        parts: UploadPart[];
        isTruncated: boolean;
        uploads: UploadPart[];
    };
}
interface MultipartUploadError {
    error: {
        code: string;
        message: string;
    };
}
interface ErrorWithCode {
    code?: string;
    cause?: {
        code?: string;
    };
}
type ListMultipartUploadResponse = ListMultipartUploadSuccess | MultipartUploadError;
type HttpMethod = 'POST' | 'GET' | 'HEAD' | 'PUT' | 'DELETE';
type ExistResponseCode = false | true | null;

/**
 * S3 class for interacting with S3-compatible object storage services.
 * This class provides methods for common S3 operations such as uploading, downloading,
 * and deleting objects, as well as multipart uploads.
 *
 * @class
 * @example
 * const s3 = new CoreS3({
 *   accessKeyId: 'your-access-key',
 *   secretAccessKey: 'your-secret-key',
 *   endpoint: 'https://your-s3-endpoint.com',
 *   region: 'us-east-1' // by default is auto
 * });
 *
 * // Upload a file
 * await s3.putObject('example.txt', 'Hello, World!');
 *
 * // Download a file
 * const content = await s3.getObject('example.txt');
 *
 * // Delete a file
 * await s3.deleteObject('example.txt');
 */
declare class S3mini {
    /**
     * Creates an instance of the S3 class.
     *
     * @constructor
     * @param {Object} config - Configuration options for the S3 instance.
     * @param {string} config.accessKeyId - The access key ID for authentication.
     * @param {string} config.secretAccessKey - The secret access key for authentication.
     * @param {string} config.endpoint - The endpoint URL of the S3-compatible service.
     * @param {string} [config.region='auto'] - The region of the S3 service.
     * @param {number} [config.requestSizeInBytes=8388608] - The request size of a single request in bytes (AWS S3 is 8MB).
     * @param {number} [config.requestAbortTimeout=undefined] - The timeout in milliseconds after which a request should be aborted (careful on streamed requests).
     * @param {Object} [config.logger=null] - A logger object with methods like info, warn, error.
     * @throws {TypeError} Will throw an error if required parameters are missing or of incorrect type.
     */
    private accessKeyId;
    private secretAccessKey;
    private endpoint;
    private region;
    private requestSizeInBytes;
    private requestAbortTimeout?;
    private logger?;
    private signingKeyDate?;
    private signingKey?;
    constructor({ accessKeyId, secretAccessKey, endpoint, region, requestSizeInBytes, requestAbortTimeout, logger, }: S3Config);
    private _sanitize;
    private _log;
    private _validateConstructorParams;
    private _ensureValidUrl;
    private _validateMethodIsGetOrHead;
    private _checkKey;
    private _checkDelimiter;
    private _checkPrefix;
    private _checkOpts;
    private _filterIfHeaders;
    private _validateUploadPartParams;
    private _sign;
    private _buildCanonicalHeaders;
    private _buildCanonicalRequest;
    private _buildCredentialScope;
    private _buildStringToSign;
    private _calculateSignature;
    private _buildAuthorizationHeader;
    private _signedRequest;
    /**
     * Gets the current configuration properties of the S3 instance.
     * @returns {IT.S3Config} The current S3 configuration object containing all settings.
     * @example
     * const config = s3.getProps();
     * console.log(config.endpoint); // 'https://s3.amazonaws.com/my-bucket'
     */
    getProps(): S3Config;
    /**
     * Updates the configuration properties of the S3 instance.
     * @param {IT.S3Config} props - The new configuration object.
     * @param {string} props.accessKeyId - The access key ID for authentication.
     * @param {string} props.secretAccessKey - The secret access key for authentication.
     * @param {string} props.endpoint - The endpoint URL of the S3-compatible service.
     * @param {string} [props.region='auto'] - The region of the S3 service.
     * @param {number} [props.requestSizeInBytes=8388608] - The request size of a single request in bytes.
     * @param {number} [props.requestAbortTimeout] - The timeout in milliseconds after which a request should be aborted.
     * @param {IT.Logger} [props.logger] - A logger object with methods like info, warn, error.
     * @throws {TypeError} Will throw an error if required parameters are missing or of incorrect type.
     * @example
     * s3.setProps({
     *   accessKeyId: 'new-access-key',
     *   secretAccessKey: 'new-secret-key',
     *   endpoint: 'https://new-endpoint.com/my-bucket',
     *   region: 'us-west-2' // by default is auto
     * });
     */
    setProps(props: S3Config): void;
    /**
     * Sanitizes an ETag value by removing surrounding quotes and whitespace.
     * Still returns RFC compliant ETag. https://www.rfc-editor.org/rfc/rfc9110#section-8.8.3
     * @param {string} etag - The ETag value to sanitize.
     * @returns {string} The sanitized ETag value.
     * @example
     * const cleanEtag = s3.sanitizeETag('"abc123"'); // Returns: 'abc123'
     */
    sanitizeETag(etag: string): string;
    /**
     * Creates a new bucket.
     * This method sends a request to create a new bucket in the specified in endpoint.
     * @returns A promise that resolves to true if the bucket was created successfully, false otherwise.
     */
    createBucket(): Promise<boolean>;
    /**
     * Checks if a bucket exists.
     * This method sends a request to check if the specified bucket exists in the S3-compatible service.
     * @returns A promise that resolves to true if the bucket exists, false otherwise.
     */
    bucketExists(): Promise<boolean>;
    /**
     * Lists objects in the bucket with optional filtering and no pagination.
     * This method retrieves all objects matching the criteria (not paginated like listObjectsV2).
     * @param {string} [delimiter='/'] - The delimiter to use for grouping objects.
     * @param {string} [prefix=''] - The prefix to filter objects by.
     * @param {number} [maxKeys] - The maximum number of keys to return. If not provided, all keys will be returned.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @returns {Promise<IT.ListObject[] | null>} A promise that resolves to an array of objects or null if the bucket is empty.
     * @example
     * // List all objects
     * const objects = await s3.listObjects();
     *
     * // List objects with prefix
     * const photos = await s3.listObjects('/', 'photos/', 100);
     */
    listObjects(delimiter?: string, prefix?: string, maxKeys?: number, opts?: Record<string, unknown>): Promise<ListObject[] | null | Awaited<ReturnType<S3Client['list']>>["contents"]>;
    /**
     * Lists multipart uploads in the bucket.
     * This method sends a request to list multipart uploads in the specified bucket.
     * @param {string} [delimiter='/'] - The delimiter to use for grouping uploads.
     * @param {string} [prefix=''] - The prefix to filter uploads by.
     * @param {IT.HttpMethod} [method='GET'] - The HTTP method to use for the request (GET or HEAD).
     * @param {Record<string, string | number | boolean | undefined>} [opts={}] - Additional options for the request.
     * @returns A promise that resolves to a list of multipart uploads or an error.
     */
    listMultipartUploads(delimiter?: string, prefix?: string, method?: HttpMethod, opts?: Record<string, string | number | boolean | undefined>): Promise<ListMultipartUploadSuccess | MultipartUploadError>;
    /**
     * Get an object from the S3-compatible service.
     * This method sends a request to retrieve the specified object from the S3-compatible service.
     * @param {string} key - The key of the object to retrieve.
     * @param {Record<string, unknown>} [opts] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns A promise that resolves to the object data (string) or null if not found.
     */
    getObject(key: string, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<string | null>;
    /**
     * Get an object response from the S3-compatible service.
     * This method sends a request to retrieve the specified object and returns the full response.
     * @param {string} key - The key of the object to retrieve.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns A promise that resolves to the Response object or null if not found.
     */
    getObjectResponse(key: string, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<Response | null>;
    /**
     * Get an object as an ArrayBuffer from the S3-compatible service.
     * This method sends a request to retrieve the specified object and returns it as an ArrayBuffer.
     * @param {string} key - The key of the object to retrieve.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns A promise that resolves to the object data as an ArrayBuffer or null if not found.
     */
    getObjectArrayBuffer(key: string, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<ArrayBuffer | null>;
    /**
     * Get an object as JSON from the S3-compatible service.
     * This method sends a request to retrieve the specified object and returns it as JSON.
     * @param {string} key - The key of the object to retrieve.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns A promise that resolves to the object data as JSON or null if not found.
     */
    getObjectJSON<T = unknown>(key: string, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<T | null>;
    /**
     * Get an object with its ETag from the S3-compatible service.
     * This method sends a request to retrieve the specified object and its ETag.
     * @param {string} key - The key of the object to retrieve.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns A promise that resolves to an object containing the ETag and the object data as an ArrayBuffer or null if not found.
     */
    getObjectWithETag(key: string, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<{
        etag: string | null;
        data: ArrayBuffer | null;
    }>;
    /**
     * Get an object as a raw response from the S3-compatible service.
     * This method sends a request to retrieve the specified object and returns the raw response.
     * @param {string} key - The key of the object to retrieve.
     * @param {boolean} [wholeFile=true] - Whether to retrieve the whole file or a range.
     * @param {number} [rangeFrom=0] - The starting byte for the range (if not whole file).
     * @param {number} [rangeTo=this.requestSizeInBytes] - The ending byte for the range (if not whole file).
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns A promise that resolves to the Response object.
     */
    getObjectRaw(key: string, wholeFile?: boolean, rangeFrom?: number, rangeTo?: number, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<Response>;
    /**
     * Get the content length of an object.
     * This method sends a HEAD request to retrieve the content length of the specified object.
     * @param {string} key - The key of the object to retrieve the content length for.
     * @returns A promise that resolves to the content length of the object in bytes, or 0 if not found.
     * @throws {Error} If the content length header is not found in the response.
     */
    getContentLength(key: string, ssecHeaders?: SSECHeaders): Promise<number>;
    /**
     * Checks if an object exists in the S3-compatible service.
     * This method sends a HEAD request to check if the specified object exists.
     * @param {string} key - The key of the object to check.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @returns A promise that resolves to true if the object exists, false if not found, or null if ETag mismatch.
     */
    objectExists(key: string, opts?: Record<string, unknown>): Promise<ExistResponseCode>;
    /**
     * Retrieves the ETag of an object without downloading its content.
     * @param {string} key - The key of the object to retrieve the ETag for.
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns {Promise<string | null>} A promise that resolves to the ETag value or null if the object is not found.
     * @throws {Error} If the ETag header is not found in the response.
     * @example
     * const etag = await s3.getEtag('path/to/file.txt');
     * if (etag) {
     *   console.log(`File ETag: ${etag}`);
     * }
     */
    getEtag(key: string, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<string | null>;
    /**
     * Uploads an object to the S3-compatible service.
     * @param {string} key - The key/path where the object will be stored.
     * @param {string | Buffer} data - The data to upload (string or Buffer).
     * @param {string} [fileType='application/octet-stream'] - The MIME type of the file.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns {Promise<Response | number>} A promise that resolves to the Response object from the upload request.
     * @throws {TypeError} If data is not a string or Buffer.
     * @example
     * // Upload text file
     * await s3.putObject('hello.txt', 'Hello, World!', 'text/plain');
     *
     * // Upload binary data
     * const buffer = Buffer.from([0x89, 0x50, 0x4e, 0x47]);
     * await s3.putObject('image.png', buffer, 'image/png');
     */
    putObject(key: string, data: string | Buffer, fileType?: string, ssecHeaders?: SSECHeaders): Promise<Response | number>;
    /**
     * Initiates a multipart upload and returns the upload ID.
     * @param {string} key - The key/path where the object will be stored.
     * @param {string} [fileType='application/octet-stream'] - The MIME type of the file.
     * @param {IT.SSECHeaders?} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns {Promise<string>} A promise that resolves to the upload ID for the multipart upload.
     * @throws {TypeError} If key is invalid or fileType is not a string.
     * @throws {Error} If the multipart upload fails to initialize.
     * @example
     * const uploadId = await s3.getMultipartUploadId('large-file.zip', 'application/zip');
     * console.log(`Started multipart upload: ${uploadId}`);
     */
    getMultipartUploadId(key: string, fileType?: string, ssecHeaders?: SSECHeaders): Promise<string>;
    /**
     * Uploads a part in a multipart upload.
     * @param {string} key - The key of the object being uploaded.
     * @param {string} uploadId - The upload ID from getMultipartUploadId.
     * @param {Buffer | string} data - The data for this part.
     * @param {number} partNumber - The part number (must be between 1 and 10,000).
     * @param {Record<string, unknown>} [opts={}] - Additional options for the request.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns {Promise<IT.UploadPart>} A promise that resolves to an object containing the partNumber and etag.
     * @throws {TypeError} If any parameter is invalid.
     * @example
     * const part = await s3.uploadPart(
     *   'large-file.zip',
     *   uploadId,
     *   partData,
     *   1
     * );
     * console.log(`Part ${part.partNumber} uploaded with ETag: ${part.etag}`);
     */
    uploadPart(key: string, uploadId: string, data: Buffer | string, partNumber: number, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders): Promise<UploadPart>;
    /**
     * Completes a multipart upload by combining all uploaded parts.
     * @param {string} key - The key of the object being uploaded.
     * @param {string} uploadId - The upload ID from getMultipartUploadId.
     * @param {Array<IT.UploadPart>} parts - Array of uploaded parts with partNumber and etag.
     * @returns {Promise<IT.CompleteMultipartUploadResult>} A promise that resolves to the completion result containing the final ETag.
     * @throws {Error} If the multipart upload fails to complete.
     * @example
     * const result = await s3.completeMultipartUpload(
     *   'large-file.zip',
     *   uploadId,
     *   [
     *     { partNumber: 1, etag: 'abc123' },
     *     { partNumber: 2, etag: 'def456' }
     *   ]
     * );
     * console.log(`Upload completed with ETag: ${result.etag}`);
     */
    completeMultipartUpload(key: string, uploadId: string, parts: Array<UploadPart>): Promise<CompleteMultipartUploadResult>;
    /**
     * Aborts a multipart upload and removes all uploaded parts.
     * @param {string} key - The key of the object being uploaded.
     * @param {string} uploadId - The upload ID to abort.
     * @param {IT.SSECHeaders} [ssecHeaders] - Server-Side Encryption headers, if any.
     * @returns {Promise<object>} A promise that resolves to an object containing the abort status and details.
     * @throws {TypeError} If key or uploadId is invalid.
     * @throws {Error} If the abort operation fails.
     * @example
     * try {
     *   const result = await s3.abortMultipartUpload('large-file.zip', uploadId);
     *   console.log('Upload aborted:', result.status);
     * } catch (error) {
     *   console.error('Failed to abort upload:', error);
     * }
     */
    abortMultipartUpload(key: string, uploadId: string, ssecHeaders?: SSECHeaders): Promise<object>;
    private _buildCompleteMultipartUploadXml;
    /**
     * Deletes an object from the bucket.
     * This method sends a request to delete the specified object from the bucket.
     * @param {string} key - The key of the object to delete.
     * @returns A promise that resolves to true if the object was deleted successfully, false otherwise.
     */
    deleteObject(key: string): Promise<boolean>;
    private _deleteObjectsProcess;
    /**
     * Deletes multiple objects from the bucket.
     * @param {string[]} keys - An array of object keys to delete.
     * @returns A promise that resolves to an array of booleans indicating success for each key in order.
     */
    deleteObjects(keys: string[]): Promise<boolean[]>;
    private _sendRequest;
    private _handleErrorResponse;
    private _buildCanonicalQueryString;
    private _getSignatureKey;
}
/**
 * @deprecated Use `S3mini` instead.
 */
declare const s3mini: typeof S3mini;

/**
 * Creates an S3mini instance optimized for the current runtime.
 * Utilizes native optimizations when possible and falls back to pure js implementations when necessary.
 */
declare function createOptimizedS3mini(config: ConstructorParameters<typeof S3mini>[0]): S3mini;

/**
 * Sanitize ETag value by removing quotes and XML entities
 * @param etag ETag value to sanitize
 * @returns Sanitized ETag
 */
declare const sanitizeETag: (etag: string) => string;
/**
 * Run async-returning tasks in batches with an *optional* minimum
 * spacing (minIntervalMs) between the *start* times of successive batches.
 *
 * @param {Iterable<() => Promise<unknonw>>} tasks       – functions returning Promises
 * @param {number} [batchSize=30]                    – max concurrent requests
 * @param {number} [minIntervalMs=0]                 – ≥0; 0 means “no pacing”
 * @returns {Promise<Array<PromiseSettledResult<T>>>}
 */
declare const runInBatches: <T = unknown>(tasks: Iterable<() => Promise<T>>, batchSize?: number, minIntervalMs?: number) => Promise<Array<PromiseSettledResult<T>>>;

export { S3mini, createOptimizedS3mini, S3mini as default, runInBatches, s3mini, sanitizeETag };
export type { CompleteMultipartUploadResult, ErrorWithCode, ExistResponseCode, ListBucketResponse, ListMultipartUploadResponse, Logger, S3Config, UploadPart };
