import { S3Client } from '@aws-sdk/client-s3'; /** * S3 客户端配置。 * 通过自定义 endpoint 即可对接任意 S3 兼容存储: * - AWS S3: endpoint 省略(默认 https://s3.amazonaws.com),forcePathStyle=false * - 腾讯云 COS: https://cos..myqcloud.com,forcePathStyle=false(虚拟主机风格,与原 COS SDK 一致) * - 阿里云 OSS: https://oss-.aliyuncs.com,forcePathStyle=true * - MinIO: http://localhost:9000,forcePathStyle=true * * 生成公开 URL 时,可额外指定 `domain` 域名模板来自定义格式,支持变量替换: * ${Bucket} / ${bucket}(完整桶名,如腾讯云 BucketName-APPID)、 * ${Region} / ${region}(地域)、${BucketName}(桶名去掉 -APPID)、 * ${APPID}(APPID)。例如腾讯云默认:https://${Bucket}.cos.${Region}.myqcloud.com */ export interface S3ClientOptions { accessKeyId: string; secretAccessKey: string; region?: string; /** S3 兼容服务地址(SDK 实际请求地址,不要包含桶名)。 * 支持 ${Region} / ${region} 变量,在创建客户端时替换。 * 如果包含 ${Bucket} 变量,会自动移除(SDK 通过 virtual-hosted / path style 自动拼接 bucket); * 同时原始模板会自动派生为 `domain`(用于生成公开 URL)。 */ endpoint?: string; /** 路径风格(默认 true,适用于 MinIO / 阿里云等)。 * 腾讯云 COS 建议设为 false(虚拟主机风格),以保持与原 COS SDK 的公开 URL 格式一致。 * AWS S3 官方虚拟主机风格也设为 false。 */ forcePathStyle?: boolean; /** 默认存储桶 */ bucket?: string; /** 对外公开 URL 的域名模板,支持以下变量替换: * - ${Bucket} / ${bucket}:完整桶名(如腾讯云 `BucketName-APPID`) * - ${Region} / ${region}:地域 * - ${BucketName}:桶名(去除 `-APPID` 后缀,`-` 之前的部分) * - ${APPID}:APPID(桶名 `-` 之后的部分) * 例如腾讯云默认:`https://${Bucket}.cos.${Region}.myqcloud.com` * 提供后,getObjectUrl 将直接按此模板拼接公开 URL(不再依赖 endpoint 的虚拟主机/路径风格)。 */ domain?: string; } export interface S3PutParams { Bucket: string; Key: string; /** 对象内容(Buffer / 字符串 / 流 等) */ Body?: Buffer | Uint8Array | string | NodeJS.ReadableStream; /** 本地文件路径,提供后自动读取为流上传(与 Body 二选一,FilePath 优先) */ FilePath?: string; ContentType?: string; ContentDisposition?: string; CacheControl?: string; ContentEncoding?: string; ContentLanguage?: string; Expires?: Date; Metadata?: Record; } export interface S3GetParams { Bucket: string; Key: string; } export interface S3UrlParams { Bucket: string; Key: string; /** 是否生成带签名的预签名 URL(默认 false 返回公开 URL) */ Sign?: boolean; /** 预签名 URL 有效期(秒,默认 3600) */ Expires?: number; } /** 客户端连接或配置(任一即可,传配置时自动创建客户端) */ export type S3ClientInput = S3Client | S3ClientOptions; /** 客户端自定义元数据(用于生成公开 URL) */ interface ClientMeta { endpoint?: string; forcePathStyle: boolean; /** 对外公开 URL 的域名模板(支持 ${Bucket} / ${Region} 等变量) */ domain?: string; /** 地域(用于 URL 变量替换) */ region?: string; } /** 获取客户端自定义元数据 */ export declare function getClientMeta(client: S3Client): ClientMeta; /** 替换字符串中的占位符,同时支持 ${Var}(AWS 风格)与 {Var}(腾讯云旧 SDK 风格)两种写法(未匹配保持原样) */ export declare function interpolate(template: string, vars: Record): string; /** 将可读流转换为 Buffer */ export declare function streamToBuffer(stream: NodeJS.ReadableStream): Promise; /** * 创建 S3 客户端。 */ export declare function createClient(option: S3ClientOptions): S3Client; /** * 分片上传文件(适合大文件)。内部使用 @aws-sdk/lib-storage 的 Upload 自动处理分片。 */ export declare function uploadFile(params: S3PutParams, cos?: S3ClientInput): Promise; /** * 简单上传对象(适合小文件)。 * * 注意:当 Body 为 ReadStream 时,AWS SDK v3 会使用流式签名 * (STREAMING-AWS4-HMAC-SHA256-PAYLOAD),自动添加 x-amz-decoded-content-length 头。 * 若流的内容长度未知,该头为 undefined,导致 COS / S3 返回 * `Invalid value "undefined" for header "x-amz-decoded-content-length"`。 * 因此 putObject(小文件场景)会将 ReadStream 自动转为 Buffer 后再上传。 * 大文件请使用 uploadFile(lib-storage 分片上传,原生支持流)。 */ export declare function putObject(params: S3PutParams, cos?: S3ClientInput): Promise; /** * 获取对象。返回 S3 响应,Body 为可读流(NodeJS.ReadableStream), * 可用 streamToBuffer 读取为 Buffer。 */ export declare function getFile(params: S3GetParams, cos?: S3ClientInput): Promise; /** * 获取对象 URL。 * - Sign=true:生成带签名的预签名 GET URL(由 AWS SDK 签名)。 * - Sign=false(默认):根据 endpoint 拼接公开 URL(路径风格 / 虚拟主机风格)。 */ /** * 根据 bucket / region / key 拼接公开访问 URL。 * 若提供 `domain` 模板,直接以其为域名模板拼接(支持 ${Bucket} / ${Region} 等变量替换); * 否则回退到传统的 endpoint + 路径风格 / 虚拟主机风格拼接逻辑。 */ export declare function resolveUrl(bucket: string, region: string, key: string, opts: { domain?: string; endpoint?: string; forcePathStyle: boolean; }): string; export declare function getObjectUrl(params: S3UrlParams, cos?: S3ClientInput): Promise; /** * 检查对象是否存在。 * - 404 / 403 返回 false(文件不存在或无权限)。 * - 其他错误(网络故障、服务端 500 等)向上抛出,避免临时故障被误判为"不存在"。 */ export declare function checkExists(params: S3GetParams, cos?: S3ClientInput): Promise; declare const _default: { createClient: typeof createClient; uploadFile: typeof uploadFile; putObject: typeof putObject; getFile: typeof getFile; getObjectUrl: typeof getObjectUrl; checkExists: typeof checkExists; streamToBuffer: typeof streamToBuffer; getClientMeta: typeof getClientMeta; }; export default _default;