import { P as Part, S as S3CallOptions, a as S3ApiOperations, b as S3BaseStorage } from "../../packem_shared/s3-base-storage.d-BmuspwCF.js"; import { F as File, u as MetaStorageOptions, i as BaseStorageOptions, L as LocalMetaStorageOptions, M as MetaStorage, s as HttpError, f as FileQuery, O as OperationOptions, d as FileInit } from "../../packem_shared/storage.d-C9EdfTf1.js"; import { S3ClientConfig, ObjectCannedACL, S3Client } from '@aws-sdk/client-s3'; import { ResponseMetadata } from '@aws-sdk/types'; import { Readable } from 'node:stream'; import 'node:timers'; import 'node:crypto'; import 'node:http'; import 'lru-cache'; declare class S3File extends File { Parts?: Part[]; UploadId?: string; uri?: string; partsUrls?: string[]; partSize?: number; } type S3MetaStorageOptions = MetaStorageOptions & S3ClientConfig & { bucket?: string; keyFile?: string; }; type S3StorageOptions = BaseStorageOptions & S3ClientConfig & { /** * Specifying access rules for uploaded files. */ acl?: ObjectCannedACL; /** * S3 bucket name. * @default 'node-Upload' */ bucket?: string; /** * Force compatible client upload directly to S3 storage */ clientDirectUpload?: boolean; /** * @deprecated Use standard auth providers */ keyFile?: string; /** * Configure metafiles storage * @example * Using local metafiles * ```ts * const storage = new S3Storage({ * bucket: 'upload', * region: 'eu-west-3', * metaStorageConfig: { directory: '/tmp/upload-metafiles' } * }) * ``` * Using a separate bucket for metafiles * ```ts * const storage = new S3Storage({ * bucket: 'upload', * region: 'eu-west-3', * metaStorageConfig: { bucket: 'upload-metafiles' } * }) * ``` */ metaStorageConfig?: LocalMetaStorageOptions | S3MetaStorageOptions; /** * The parts size that the client should use for presigned multipart unloading. * @default '16MB' */ partSize?: number | string; }; /** * SDK V3 * A structure containing information about a service or networking error. */ interface AwsError extends Error { $fault?: "client" | "server"; $metadata: ResponseMetadata; $service?: string; Code?: string; Type?: string; } /** * SDK V2 * A structure containing information about a service or networking error. */ interface AWSErrorV2 extends Error { /** * CloudFront request ID associated with the response. */ cfId: string; /** * A unique short code representing the error that was emitted. */ code: string; /** * Second request ID associated with the response from S3. */ extendedRequestId: string; /** * Set when a networking error occurs to easily identify the endpoint of the request. */ hostname: string; /** * A longer human readable error message. */ message: string; /** * Set when a networking error occurs to easily identify the region of the request. */ region: string; /** * The unique request ID associated with the response. */ requestId: string; /** * Whether the error message is retryable. */ retryable: boolean; /** * Amount of time (in seconds) that the request waited before being resent. */ retryDelay: number; /** * In the case of a request that reached the service, this value contains the response status code. */ statusCode: number; /** * The date time object when the error occurred. */ time: Date; } declare class S3MetaStorage extends MetaStorage { config: S3MetaStorageOptions; private readonly bucket; private readonly client; constructor(config: S3MetaStorageOptions); override get(id: string): Promise; override touch(id: string, file: T): Promise; override delete(id: string): Promise; override save(id: string, file: T): Promise; private accessCheck; } type ReadableStream = globalThis.ReadableStream; /** * Adapter that wraps AWS SDK S3Client to implement S3ApiOperations interface. */ declare class S3ClientAdapter implements S3ApiOperations { private readonly client; constructor(client: S3Client, _bucket: string); createMultipartUpload(params: { ACL?: string; Bucket: string; ContentType?: string; Key: string; Metadata?: Record; }, options?: S3CallOptions): Promise<{ UploadId: string; }>; uploadPart(params: { Body: Readable | ReadableStream | Uint8Array; Bucket: string; ContentLength?: number; ContentMD5?: string; Key: string; PartNumber: number; UploadId: string; }, options?: S3CallOptions): Promise<{ ETag: string; }>; completeMultipartUpload(params: { Bucket: string; Key: string; Parts: { ETag: string; PartNumber: number; }[]; UploadId: string; }, options?: S3CallOptions): Promise<{ ETag?: string; Location: string; }>; abortMultipartUpload(params: { Bucket: string; Key: string; UploadId: string; }, options?: S3CallOptions): Promise; listParts(params: { Bucket: string; Key: string; UploadId: string; }, options?: S3CallOptions): Promise<{ Parts?: Part[]; }>; getObject(params: { Bucket: string; Key: string; Range?: string; }, options?: S3CallOptions): Promise<{ Body?: ReadableStream | Readable; ContentLength?: number; ContentType?: string; ETag?: string; Expires?: Date; LastModified?: Date; Metadata?: Record; }>; headObject(params: { Bucket: string; Key: string; }, options?: S3CallOptions): Promise<{ ContentLength?: number; ContentType?: string; ETag?: string; Expires?: Date; LastModified?: Date; }>; deleteObject(params: { Bucket: string; Key: string; }, options?: S3CallOptions): Promise; copyObject(params: { Bucket: string; CopySource: string; Key: string; StorageClass?: string; }, options?: S3CallOptions): Promise; listObjectsV2(params: { Bucket: string; ContinuationToken?: string; Delimiter?: string; MaxKeys?: number; Prefix?: string; }, options?: S3CallOptions): Promise<{ CommonPrefixes?: { Prefix?: string; }[]; Contents?: { Key?: string; LastModified?: Date; }[]; IsTruncated?: boolean; NextContinuationToken?: string; }>; getPresignedUrl(params: { Bucket: string; expiresIn: number; Key: string; PartNumber: number; UploadId: string; }): Promise; checkBucketAccess(params: { Bucket: string; }): Promise; } /** * Amazon S3 storage implementation. * @example * ```ts * const storage = new S3Storage({ * bucket: , * endpoint: , * region: , * credentials: { * accessKeyId: , * secretAccessKey: * }, * metaStorageConfig: { directory: '/tmp/upload-metafiles' } * }); * ``` * @remarks * ## Error Handling * - S3 API errors are normalized with AWS-specific context * - Errors include S3 error codes and metadata for debugging * - Batch operations handle individual failures gracefully * * ## Retry Behavior * - All S3 API calls are wrapped with configurable retry logic via `retryConfig` option * - Default retryable status codes: 408 (Request Timeout), 429 (Too Many Requests), * 500 (Internal Server Error), 502 (Bad Gateway), 503 (Service Unavailable), 504 (Gateway Timeout) * - Retries server-side faults ($fault === "server") automatically * - Custom `shouldRetry` function can be provided for advanced retry logic * - Default retry configuration: maxRetries: 3, initialDelay: 1000ms, maxDelay: 30000ms, backoffMultiplier: 2 (exponential backoff) * - Retry wrapper handles transient network errors and rate limiting * * ## Multipart Uploads * - Large files are automatically split into multipart uploads * - Maximum 10,000 parts per upload (S3 limitation) * - Part size is configurable (default: 16MB, minimum: 5MB) * - Failed multipart uploads are automatically aborted * * ## Supported Operations * - ✅ create, write, delete, get, getStream, list, update, copy, move * - ✅ Batch operations: deleteBatch, copyBatch, moveBatch (inherited from BaseStorage) * - ✅ exists: Implemented (checks metadata and S3 object) * - ❌ getUrl: Not implemented (presigned URLs available via buildPresigned for clientDirectUpload) * - ❌ getUploadUrl: Not implemented (presigned URLs available via buildPresigned for clientDirectUpload) */ declare class S3Storage extends S3BaseStorage { static override readonly name: string; private s3Api; private rawClient; constructor(config: S3StorageOptions); /** * Normalizes AWS S3 errors with S3-specific context. */ override normalizeError(error: AwsError): HttpError; override update({ id }: FileQuery, metadata: Partial): Promise; override getStream({ id }: FileQuery, options?: OperationOptions & { range?: { end?: number; start: number; }; }): Promise<{ headers?: Record; size?: number; stream: Readable; }>; override get raw(): S3Client; override getReadUrl(key: string, options?: { expiresIn?: number; responseContentDisposition?: string; responseContentType?: string; }): Promise; override getUploadUrl(key: string, options?: { contentLength?: number; contentType?: string; expiresIn?: number; }): Promise; protected getS3Api(): S3ClientAdapter; protected getFileClass(): new (config: FileInit) => S3File; protected getAcl(): string | undefined; protected accessCheck(_maxWaitTime?: number): Promise; } export { type AWSErrorV2, type AwsError, S3File, S3MetaStorage, type S3MetaStorageOptions, S3Storage, type S3StorageOptions };