//#region src/types.d.ts
interface S3Config {
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
  region?: string;
  requestSizeInBytes?: number;
  requestAbortTimeout?: number;
  logger?: Logger;
  fetch?: typeof fetch;
  minPartSize?: number;
}
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 AWSHeaders {
  [k: `x-amz-${string}`]: 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;
  /** Present when listing with `{ versions: true }` or via `listObjectVersions`. */
  VersionId?: string;
  /** Present when listing versions; true if this is the current version of the key. */
  IsLatest?: boolean;
  /** True when the entry is a delete marker from ListObjectVersions. */
  IsDeleteMarker?: boolean;
}
/**
 * Object identity for delete APIs. Use instead of a bare key string when
 * targeting a specific version on a versioned bucket.
 */
interface DeleteObject {
  key: string;
  versionId?: 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;
} | ListBucketError;
interface ListMultipartUploadSuccess {
  listMultipartUploadsResult: {
    bucket: string;
    key: string;
    uploadId: string;
    size?: number;
    mtime?: Date;
    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;
interface CopyObjectOptions {
  /**
   * Source object version to copy. Appended as `?versionId=` on `x-amz-copy-source`.
   * Useful for restoring an older version (copy version onto the same key).
   */
  versionId?: string;
  /**
   * Specifies whether the metadata is copied from the source object or replaced with metadata provided in the request.
   * Valid values: 'COPY' | 'REPLACE'
   * Default: 'COPY'
   */
  metadataDirective?: 'COPY' | 'REPLACE';
  /**
   * Metadata to be set on the destination object when metadataDirective is 'REPLACE'.
   * Keys can be provided with or without 'x-amz-meta-' prefix.
   */
  metadata?: Record<string, string>;
  contentType?: string;
  /**
   * Storage class for the destination object.
   * Valid values: 'STANDARD' | 'REDUCED_REDUNDANCY' | 'STANDARD_IA' | 'ONEZONE_IA' | 'INTELLIGENT_TIERING' | 'GLACIER' | 'DEEP_ARCHIVE' | 'GLACIER_IR'
   */
  storageClass?: string;
  /**
   * Specifies whether the object tag-set is copied from the source object or replaced with tag-set provided in the request.
   * Valid values: 'COPY' | 'REPLACE'
   */
  taggingDirective?: 'COPY' | 'REPLACE';
  /**
   * If the bucket is configured as a website, redirects requests for this object to another object or URL.
   */
  websiteRedirectLocation?: string;
  /**
   * Server-Side Encryption with Customer-Provided Keys headers for the source object.
   * Should include:
   * - x-amz-copy-source-server-side-encryption-customer-algorithm
   * - x-amz-copy-source-server-side-encryption-customer-key
   * - x-amz-copy-source-server-side-encryption-customer-key-MD5
   */
  sourceSSECHeaders?: Record<string, string | number>;
  destinationSSECHeaders?: SSECHeaders;
  additionalHeaders?: Record<string, string | number>;
}
interface CopyObjectResult {
  etag: string;
  lastModified?: Date;
  /** Version id of the newly created destination object (versioned buckets). */
  versionId?: string;
}
/**
 * Detailed delete outcome for a single target. Returned by `deleteObject` /
 * `deleteObjects` when called with `{ versionInfo: true }`.
 */
interface DeleteObjectResult {
  key: string;
  deleted: boolean;
  /** Version id of the object version permanently deleted (when a `versionId` was targeted). */
  versionId?: string;
  /** True if S3 created a delete marker rather than permanently deleting. */
  deleteMarker?: boolean;
  /** Version id of the delete marker created (versioned bucket, no `versionId` targeted). */
  deleteMarkerVersionId?: string;
}
type BinaryData = ArrayBuffer | Uint8Array;
type MaybeBuffer = typeof globalThis extends {
  Buffer?: infer B;
} ? B extends (new (...a: unknown[]) => unknown) ? InstanceType<B> | BinaryData : BinaryData : BinaryData;
type DataInput = string | MaybeBuffer | ReadableStream | File | Blob;
//#endregion
//#region src/S3.d.ts
/**
 * 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 S3mini({
 *   accessKeyId: 'your-access-key',
 *   secretAccessKey: 'your-secret-key',
 *   endpoint: 'https://your-s3-endpoint.com/bucket-name',
 *   region: 'auto' // 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 {
  #private;
  readonly endpoint: URL;
  readonly region: string;
  readonly bucketName: string;
  readonly requestSizeInBytes: number;
  readonly requestAbortTimeout?: number;
  readonly logger?: Logger;
  readonly _fetch: typeof fetch;
  readonly minPartSize: number;
  private readonly _bun?;
  private signingKeyDate?;
  private signingKey?;
  constructor({ accessKeyId, secretAccessKey, endpoint, region, requestSizeInBytes, requestAbortTimeout, logger, fetch, minPartSize }: S3Config);
  private _sanitize;
  private _log;
  private _asArray;
  private _validateConstructorParams;
  /**
   * Check if credentials are configured (non-empty).
   * @returns true if both accessKeyId and secretAccessKey are non-empty.
   */
  private _hasCredentials;
  /**
   * Re-shape a Bun S3Error as the S3ServiceError the signed path throws, so callers see one error
   * type on every runtime. Bun does not expose the HTTP status, so it is recovered from the error
   * code where the S3 API pins it and left as 0 (unknown) otherwise.
   */
  private _bunError;
  /** True for a Bun S3Error the signed path would have absorbed as a tolerated 404. */
  private _isBunNotFound;
  /** Run a read op via Bun-native S3, returning null when the object or its bucket is absent. */
  private _bunRead;
  private _ensureValidUrl;
  private _validateMethodIsGetOrHead;
  private _checkKey;
  private _checkDelimiter;
  private _checkPrefix;
  private _checkOpts;
  private _filterIfHeaders;
  private _validateUploadPartParams;
  private _sign;
  private _signedRequest;
  /**
   * 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>;
  private _extractBucketName;
  /**
   * 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>;
  /**
   * Sets bucket versioning status (PutBucketVersioning).
   * Required before object versioning APIs (`listObjectVersions`, versioned delete/copy) are useful.
   * @param {'Enabled' | 'Suspended'} status - Versioning status to apply.
   * @returns {Promise<boolean>} True when the service accepts the configuration (HTTP 200).
   * @example
   * await s3.setBucketVersioning('Enabled');
   */
  setBucketVersioning(status: 'Enabled' | 'Suspended'): Promise<boolean>;
  /**
   * Gets bucket versioning status (GetBucketVersioning).
   * @returns {Promise<'Enabled' | 'Suspended' | 'Off'>} Current status. `'Off'` when the config is empty/unset.
   */
  getBucketVersioning(): Promise<'Enabled' | 'Suspended' | 'Off'>;
  /**
   * Lists objects in the bucket with optional filtering and no pagination.
   * This method retrieves all objects matching the criteria (not paginated like listObjectsV2).
   * Pass `{ versions: true }` in opts to list object versions (ListObjectVersions API).
   * @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. Use `{ versions: true }` for version listing.
   * @returns {Promise<IT.ListObject[] | null>} A promise that resolves to an array of objects, or null if the bucket does not exist. An empty bucket resolves to an empty array.
   * @example
   * // List all objects
   * const objects = await s3.listObjects();
   *
   * // List objects with prefix
   * const photos = await s3.listObjects('/', 'photos/', 100);
   *
   * // List object versions (includes VersionId / IsLatest; may include delete markers)
   * const versions = await s3.listObjects('/', 'photos/', undefined, { versions: true });
   */
  listObjects(delimiter?: string, prefix?: string, maxKeys?: number, opts?: Record<string, unknown>): Promise<ListObject[] | null>;
  /**
   * Lists objects in the bucket with optional filtering and pagination using a continuation token.
   * This method retrieves objects matching the criteria (paginated like listObjectsV2).
   * Pass `{ versions: true }` in opts to list object versions (uses key-marker / version-id-marker under the hood;
   * the returned token is opaque and only valid with the same opts).
   * @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. Uses a default value of 100.
   * @param {string} [nextContinuationToken] - The nextContinuationToken to continue previous results. If not provided, starts from the beginning.
   * @param {Record<string, unknown>} [opts={}] - Additional options for the request. Use `{ versions: true }` for version listing.
   * @returns {Promise<{objects: IT.ListObject[] | null; nextContinuationToken?: string } | undefined | null>} A promise that resolves to an array of objects, along with nextContinuationToken if there are more reccords, or null if the bucket does not exist.
   * @example
   * // List all objects
   * const { objects, nextContinuationToken } = await s3.listObjectsPaged();
   *
   * // List 200 objects with prefix
   * const photos = await s3.listObjectsPaged('/', 'photos/', 200, "token...");
   */
  listObjectsPaged(delimiter?: string, prefix?: string, maxKeys?: number, nextContinuationToken?: string, opts?: Record<string, unknown>): Promise<{
    objects: ListObject[] | null;
    nextContinuationToken?: string;
  } | undefined | null>;
  /**
   * Lists all versions (and delete markers) of a specific object key.
   * Auto-paginates until every version is returned (or maxKeys is reached).
   * Entries include `VersionId`, `IsLatest`, and optionally `IsDeleteMarker`.
   *
   * @param {string} key - Exact object key whose versions to list.
   * @param {number} [maxKeys] - Optional cap on how many version entries to return.
   * @returns {Promise<IT.ListObject[] | null>} All versions for the key, or null if the bucket is not found.
   * @example
   * const versions = await s3.listObjectVersions('file.jpg');
   * const latest = versions?.find(v => v.IsLatest);
   * const older = versions?.filter(v => !v.IsLatest && !v.IsDeleteMarker);
   */
  listObjectVersions(key: string, maxKeys?: number): Promise<ListObject[] | null>;
  private _fetchObjectBatch;
  private _isVersionsMode;
  private _encodeVersionListToken;
  private _decodeVersionListToken;
  private _buildListObjectsQuery;
  private _handleListObjectsError;
  private _parseListObjectsResponse;
  private _mapListEntry;
  private _pushListEntries;
  private _pushCommonPrefixes;
  private _extractObjectsFromResponse;
  private _extractContinuationToken;
  private _extractVersionListToken;
  private _bunListAll;
  private _bunFetchPage;
  private _bunMapListResult;
  /**
   * 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; 0 when the object exists but the response carries no content-length header.
   * @throws {Error} If the object does not exist (HTTP 404) or the request otherwise fails; the underlying S3ServiceError is attached as `.cause`.
   */
  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 | IT.MaybeBuffer | ReadableStream | File | Blob} 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.
   * @param {IT.AWSHeaders} [additionalHeaders] - Additional x-amz-* headers specific to this request, if any.
   * @returns {Promise<Response>} 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 | DataInput | ReadableStream | File | Blob, fileType?: string, ssecHeaders?: SSECHeaders, additionalHeaders?: AWSHeaders, contentLength?: number): Promise<Response>;
  /**
   * Put object that automatically chooses single PUT vs multipart.
   * Same signature/shape as putObject so callers don't need to change.
   * @param {string} key - The key/path where the object will be stored.
   * @param {string | IT.MaybeBuffer | ReadableStream | File | Blob} 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.
   * @param {IT.AWSHeaders} [additionalHeaders] - Additional x-amz-* headers specific to this request, if any.
   * @param {number} [contentLength] - Optional known content length of data.
   * @returns {Promise<Response | { ok: boolean; status: number; headers: Map<string, string> }>} 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.putAnyObject('hello.txt', 'Hello, World!', 'text/plain');
   *
   * // Upload binary data
   * const buffer = Buffer.from([0x89, 0x50, 0x4e, 0x47]);
   * await s3.putAnyObject('image.png', buffer, 'image/png');
   */
  putAnyObject(key: string, data: DataInput, fileType?: string, ssecHeaders?: SSECHeaders, additionalHeaders?: AWSHeaders, contentLength?: number): Promise<Response | {
    ok: boolean;
    status: number;
    headers: Map<string, string>;
  }>;
  private _multipartUpload;
  private _uploadKnownSizePartsParallel;
  private _uploadPartsOptimized;
  private _uploadStreamingParts;
  private _uploadPartWithRetry;
  private _safeAbortUpload;
  private _createSuccessResponse;
  /**
   * 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, additionalHeaders?: AWSHeaders): 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 {string | IT.MaybeBuffer | ReadableStream | File | Blob} 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: DataInput, partNumber: number, opts?: Record<string, unknown>, ssecHeaders?: SSECHeaders, additionalHeaders?: AWSHeaders): 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;
  /**
   * Executes the copy operation for local copying (same bucket/endpoint).
   * @private
   */
  private _executeCopyOperation;
  /**
   * Copies an object within the same bucket.
   *
   * @param {string} sourceKey - The key of the source object to copy
   * @param {string} destinationKey - The key where the object will be copied to
   * @param {IT.CopyObjectOptions} [options={}] - Copy operation options
   * @param {string} [options.versionId] - Source object version to copy (for versioned buckets)
   * @param {string} [options.metadataDirective='COPY'] - How to handle metadata ('COPY' | 'REPLACE')
   * @param {Record<string,string>} [options.metadata={}] - New metadata (only used if metadataDirective='REPLACE')
   * @param {string} [options.contentType] - New content type for the destination object
   * @param {string} [options.storageClass] - Storage class for the destination object
   * @param {string} [options.taggingDirective] - How to handle object tags ('COPY' | 'REPLACE')
   * @param {string} [options.websiteRedirectLocation] - Website redirect location for the destination
   * @param {IT.SSECHeaders} [options.sourceSSECHeaders={}] - Encryption headers for reading source (if encrypted)
   * @param {IT.SSECHeaders} [options.destinationSSECHeaders={}] - Encryption headers for destination
   * @param {IT.AWSHeaders} [options.additionalHeaders={}] - Extra x-amz-* headers
   *
   * @returns {Promise<IT.CopyObjectResult>} Copy result with etag, lastModified date, and `versionId` of the new object version (versioned buckets)
   * @throws {TypeError} If sourceKey or destinationKey is invalid
   * @throws {Error} If copy operation fails or S3 returns an error
   *
   * @example
   * // Simple copy
   * const result = await s3.copyObject('report-2024.pdf', 'archive/report-2024.pdf');
   * console.log(`Copied with ETag: ${result.etag}`);
   *
   * @example
   * // Restore an older version onto the same key
   * await s3.copyObject('file.jpg', 'file.jpg', { versionId: 'older-version-id' });
   *
   * @example
   * // Copy with new metadata and content type
   * const result = await s3.copyObject('data.csv', 'processed/data.csv', {
   *   metadataDirective: 'REPLACE',
   *   metadata: {
   *     'processed-date': new Date().toISOString(),
   *     'original-name': 'data.csv'
   *   },
   *   contentType: 'text/csv; charset=utf-8'
   * });
   *
   * @example
   * // Copy encrypted object (Cloudflare R2 SSE-C)
   * const ssecKey = 'n1TKiTaVHlYLMX9n0zHXyooMr026vOiTEFfT+719Hho=';
   * await s3.copyObject('sensitive.json', 'backup/sensitive.json', {
   *   sourceSSECHeaders: {
   *     'x-amz-copy-source-server-side-encryption-customer-algorithm': 'AES256',
   *     'x-amz-copy-source-server-side-encryption-customer-key': ssecKey,
   *     'x-amz-copy-source-server-side-encryption-customer-key-md5': 'gepZmzgR7Be/1+K1Aw+6ow=='
   *   },
   *   destinationSSECHeaders: {
   *     'x-amz-server-side-encryption-customer-algorithm': 'AES256',
   *     'x-amz-server-side-encryption-customer-key': ssecKey,
   *     'x-amz-server-side-encryption-customer-key-md5': 'gepZmzgR7Be/1+K1Aw+6ow=='
   *   }
   * });
   */
  copyObject(sourceKey: string, destinationKey: string, options?: CopyObjectOptions): Promise<CopyObjectResult>;
  private _buildSSECHeaders;
  /**
   * Moves an object within the same bucket (copy + delete atomic-like operation).
   *
   * WARNING: Not truly atomic - if delete fails after successful copy, the object
   * will exist in both locations. Consider your use case carefully.
   *
   * @param {string} sourceKey - The key of the source object to move
   * @param {string} destinationKey - The key where the object will be moved to
   * @param {IT.CopyObjectOptions} [options={}] - Options passed to the copy operation
   *
   * @returns {Promise<IT.CopyObjectResult>} Result from the copy operation
   * @throws {TypeError} If sourceKey or destinationKey is invalid
   * @throws {Error} If copy succeeds but delete fails (includes copy result in error)
   *
   * @example
   * // Simple move
   * await s3.moveObject('temp/upload.tmp', 'files/document.pdf');
   *
   * @example
   * // Move with metadata update
   * await s3.moveObject('unprocessed/image.jpg', 'processed/image.jpg', {
   *   metadataDirective: 'REPLACE',
   *   metadata: {
   *     'status': 'processed',
   *     'processed-at': Date.now().toString()
   *   },
   *   contentType: 'image/jpeg'
   * });
   *
   * @example
   * // Safe move with error handling
   * try {
   *   const result = await s3.moveObject('inbox/file.dat', 'archive/file.dat');
   *   console.log(`Moved successfully: ${result.etag}`);
   * } catch (error) {
   *   // Check if copy succeeded but delete failed
   *   if (error.message.includes('delete source object after successful copy')) {
   *     console.warn('File copied but not deleted from source - manual cleanup needed');
   *   }
   * }
   */
  moveObject(sourceKey: string, destinationKey: string, options?: CopyObjectOptions): Promise<CopyObjectResult>;
  private _buildMetadataHeaders;
  private _parseCopyObjectResponse;
  /**
   * Deletes an object from the bucket.
   * Accepts either a key string or a {@link IT.DeleteObject} with optional `versionId`
   * for permanently removing a specific version on a versioned bucket.
   *
   * By default resolves to a boolean. Pass `{ versionInfo: true }` to receive a
   * {@link IT.DeleteObjectResult} carrying the deleted `versionId`, whether a delete
   * marker was created (`deleteMarker`), and the new marker's `deleteMarkerVersionId`.
   * Requesting version info forces the signed HTTP path (Bun's native delete can't
   * surface those response headers).
   * @param {string | IT.DeleteObject} target - Object key or `{ key, versionId? }`.
   * @param {{ versionInfo?: boolean }} [options] - Pass `{ versionInfo: true }` for a detailed result.
   * @returns Boolean, or {@link IT.DeleteObjectResult} when `versionInfo` is set.
   * @example
   * await s3.deleteObject('file.jpg');
   * await s3.deleteObject({ key: 'file.jpg', versionId: 'abc123' });
   * const info = await s3.deleteObject('file.jpg', { versionInfo: true });
   * if (info.deleteMarker) console.log(info.deleteMarkerVersionId);
   */
  deleteObject(target: string | DeleteObject): Promise<boolean>;
  deleteObject(target: string | DeleteObject, options: {
    versionInfo: true;
  }): Promise<DeleteObjectResult>;
  private _normalizeDeleteTarget;
  private _deleteTargetId;
  private _deleteObjectsProcess;
  private _deleteObjectsProcessInfo;
  private _sendDeleteRequest;
  private _deleteVersionMatches;
  private _markFirstPendingDeleted;
  private _resolveDeleteMatches;
  private _logDeleteErrors;
  /**
   * Deletes multiple objects from the bucket.
   * Each entry may be a key string or a {@link IT.DeleteObject} with optional `versionId`.
   *
   * By default resolves to an array of booleans (one per target, in order). Pass
   * `{ versionInfo: true }` to receive an array of {@link IT.DeleteObjectResult} carrying
   * the deleted `versionId`, whether a delete marker was created, and the new marker's
   * `deleteMarkerVersionId` for each target.
   * @param {Array<string | IT.DeleteObject>} targets - Objects to delete.
   * @param {{ versionInfo?: boolean }} [options] - Pass `{ versionInfo: true }` for detailed per-target results.
   * @returns Booleans, or {@link IT.DeleteObjectResult[]} when `versionInfo` is set.
   * @example
   * await s3.deleteObjects(['a.txt', { key: 'b.txt', versionId: 'v1' }]);
   * const info = await s3.deleteObjects(['a.txt'], { versionInfo: true });
   */
  deleteObjects(targets: Array<string | DeleteObject>): Promise<boolean[]>;
  deleteObjects(targets: Array<string | DeleteObject>, options: {
    versionInfo: true;
  }): Promise<DeleteObjectResult[]>;
  private _sendRequest;
  private _parseErrorXml;
  private _handleErrorResponse;
  private _buildCanonicalQueryString;
  /**
   * Generates a pre-signed URL for direct client access to an S3 object.
   * The URL embeds authentication in query parameters instead of headers,
   * allowing unauthenticated HTTP clients to perform the specified operation.
   *
   * @param {'GET' | 'PUT'} method - HTTP method ('GET' for download, 'PUT' for upload)
   * @param {string} key - The object key/path
   * @param {number} [expiresIn=3600] - URL expiration time in seconds (1–604800)
   * @param {Record<string, string>} [queryParams={}] - Additional query parameters to include in the URL
   * @param {Record<string, string>} [headers={}] - HTTP headers to sign. The consumer of the URL
   *   MUST send these exact headers with matching values. The `host` header is always signed automatically.
   * @returns {Promise<string>} Pre-signed URL string
   * @throws {TypeError} If key is empty or expiresIn is out of range
   * @example
   * // Download URL valid for 1 hour
   * const url = await s3.getPresignedUrl('GET', 'photos/vacation.jpg');
   *
   * // Upload URL valid for 5 minutes with signed Content-Type
   * const url = await s3.getPresignedUrl('PUT', 'uploads/file.bin', 300, {}, {
   *   'Content-Type': 'application/octet-stream',
   * });
   *
   * // Client-side usage (must include signed headers)
   * await fetch(url, { method: 'PUT', body: data, headers: { 'Content-Type': 'application/octet-stream' } });
   */
  getPresignedUrl(method: 'GET' | 'PUT', key: string, expiresIn?: number, queryParams?: Record<string, string>, headers?: Record<string, string>): Promise<string>;
  private _presign;
  private _getSignatureKey;
}
//#endregion
//#region src/utils.d.ts
/**
 * 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>>>;
//#endregion
export { type CompleteMultipartUploadResult, type CopyObjectOptions, type CopyObjectResult, type DeleteObject, type DeleteObjectResult, type ErrorWithCode, type ExistResponseCode, type ListBucketResponse, type ListMultipartUploadResponse, type ListObject, type Logger, type S3Config, S3mini, S3mini as default, type UploadPart, runInBatches, sanitizeETag };