diff --git a/es/service/ali/Ali.d.ts b/es/service/ali/Ali.d.ts index 8c3b62d..15e4469 100644 --- a/es/service/ali/Ali.d.ts +++ b/es/service/ali/Ali.d.ts @@ -30,6 +30,27 @@ export declare class ALiYunInstance { bucket: string; name: string; }>; + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + presignMulti(bucket: string, zone: ALiYunZone, key: string, uploadId: string, from: number, to: number, options?: { + expires?: number; + headers?: Record; + timeout?: number; + stsToken?: string; + accessKeyId?: string; + accessKeySecret?: string; + }): Promise<{ + partNumber: number; + uploadUrl: string; + }[]>; /** * 准备分片上传(初始化并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/es/service/ali/Ali.js b/es/service/ali/Ali.js index 3995b51..c8a7294 100644 --- a/es/service/ali/Ali.js +++ b/es/service/ali/Ali.js @@ -207,6 +207,50 @@ export class ALiYunInstance { }); } } + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + async presignMulti(bucket, zone, key, uploadId, from, to, options) { + const client = new OSS({ + region: `oss-${zone}`, + accessKeyId: options?.accessKeyId || this.accessKey, + accessKeySecret: options?.accessKeySecret || this.secretKey, + bucket: bucket, + stsToken: options?.stsToken, + }); + try { + const presignedUrls = []; + const expires = options?.expires || 3600; + for (let i = from; i <= to; i++) { + const uploadUrl = client.signatureUrl(key, { + method: 'PUT', + expires: expires, + subResource: { + uploadId: uploadId, + partNumber: String(i), + }, + "Content-Type": "application/octet-stream", + }); + presignedUrls.push({ + partNumber: i, + uploadUrl: uploadUrl, + }); + } + return presignedUrls; + } + catch (error) { + throw new OakExternalException('aliyun', error.code, error.message, { + status: error.status, + }); + } + } /** * 准备分片上传(初始化并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/es/service/s3/S3.d.ts b/es/service/s3/S3.d.ts index 1add2ca..9447b34 100644 --- a/es/service/s3/S3.d.ts +++ b/es/service/s3/S3.d.ts @@ -36,6 +36,23 @@ export declare class S3Instance { bucket: string; key: string; }>; + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + presignMulti(bucket: string, key: string, uploadId: string, from: number, to: number, options?: { + endpoint?: string; + expiresIn?: number; + }): Promise<{ + partNumber: number; + uploadUrl: string; + }[]>; /** * 准备分片上传(创建分片上传并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/es/service/s3/S3.js b/es/service/s3/S3.js index b98bb33..8ab4c1a 100644 --- a/es/service/s3/S3.js +++ b/es/service/s3/S3.js @@ -143,6 +143,40 @@ export class S3Instance { throw new OakExternalException('s3', err.code, err.message, err, 'oak-external-sdk', {}); } } + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + async presignMulti(bucket, key, uploadId, from, to, options) { + const client = options?.endpoint + ? this.createClient(options.endpoint, this.defaultRegion) + : this.client; + // 2. 为每个分片生成预签名 URL + const parts = []; + const expiresIn = options?.expiresIn || 3600; + for (let i = from; i <= to; i++) { + const uploadCommand = new UploadPartCommand({ + Bucket: bucket, + Key: key, + UploadId: uploadId, + PartNumber: i, + }); + const uploadUrl = await getSignedUrl(client, uploadCommand, { + expiresIn: expiresIn, + }); + parts.push({ + partNumber: i, + uploadUrl: uploadUrl, + }); + } + return parts; + } /** * 准备分片上传(创建分片上传并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/lib/service/ali/Ali.d.ts b/lib/service/ali/Ali.d.ts index 8c3b62d..15e4469 100644 --- a/lib/service/ali/Ali.d.ts +++ b/lib/service/ali/Ali.d.ts @@ -30,6 +30,27 @@ export declare class ALiYunInstance { bucket: string; name: string; }>; + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + presignMulti(bucket: string, zone: ALiYunZone, key: string, uploadId: string, from: number, to: number, options?: { + expires?: number; + headers?: Record; + timeout?: number; + stsToken?: string; + accessKeyId?: string; + accessKeySecret?: string; + }): Promise<{ + partNumber: number; + uploadUrl: string; + }[]>; /** * 准备分片上传(初始化并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/lib/service/ali/Ali.js b/lib/service/ali/Ali.js index 0db4cc3..ffbe450 100644 --- a/lib/service/ali/Ali.js +++ b/lib/service/ali/Ali.js @@ -211,6 +211,50 @@ class ALiYunInstance { }); } } + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + async presignMulti(bucket, zone, key, uploadId, from, to, options) { + const client = new ali_oss_1.default({ + region: `oss-${zone}`, + accessKeyId: options?.accessKeyId || this.accessKey, + accessKeySecret: options?.accessKeySecret || this.secretKey, + bucket: bucket, + stsToken: options?.stsToken, + }); + try { + const presignedUrls = []; + const expires = options?.expires || 3600; + for (let i = from; i <= to; i++) { + const uploadUrl = client.signatureUrl(key, { + method: 'PUT', + expires: expires, + subResource: { + uploadId: uploadId, + partNumber: String(i), + }, + "Content-Type": "application/octet-stream", + }); + presignedUrls.push({ + partNumber: i, + uploadUrl: uploadUrl, + }); + } + return presignedUrls; + } + catch (error) { + throw new Exception_1.OakExternalException('aliyun', error.code, error.message, { + status: error.status, + }); + } + } /** * 准备分片上传(初始化并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/lib/service/s3/S3.d.ts b/lib/service/s3/S3.d.ts index 1add2ca..9447b34 100644 --- a/lib/service/s3/S3.d.ts +++ b/lib/service/s3/S3.d.ts @@ -36,6 +36,23 @@ export declare class S3Instance { bucket: string; key: string; }>; + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + presignMulti(bucket: string, key: string, uploadId: string, from: number, to: number, options?: { + endpoint?: string; + expiresIn?: number; + }): Promise<{ + partNumber: number; + uploadUrl: string; + }[]>; /** * 准备分片上传(创建分片上传并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/lib/service/s3/S3.js b/lib/service/s3/S3.js index 548337d..bb3beb0 100644 --- a/lib/service/s3/S3.js +++ b/lib/service/s3/S3.js @@ -146,6 +146,40 @@ class S3Instance { throw new types_1.OakExternalException('s3', err.code, err.message, err, 'oak-external-sdk', {}); } } + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + async presignMulti(bucket, key, uploadId, from, to, options) { + const client = options?.endpoint + ? this.createClient(options.endpoint, this.defaultRegion) + : this.client; + // 2. 为每个分片生成预签名 URL + const parts = []; + const expiresIn = options?.expiresIn || 3600; + for (let i = from; i <= to; i++) { + const uploadCommand = new client_s3_1.UploadPartCommand({ + Bucket: bucket, + Key: key, + UploadId: uploadId, + PartNumber: i, + }); + const uploadUrl = await (0, s3_request_presigner_1.getSignedUrl)(client, uploadCommand, { + expiresIn: expiresIn, + }); + parts.push({ + partNumber: i, + uploadUrl: uploadUrl, + }); + } + return parts; + } /** * 准备分片上传(创建分片上传并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/src/service/ali/Ali.ts b/src/service/ali/Ali.ts index aecf9ce..a554479 100644 --- a/src/service/ali/Ali.ts +++ b/src/service/ali/Ali.ts @@ -234,6 +234,66 @@ export class ALiYunInstance { } } + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + async presignMulti( + bucket: string, + zone: ALiYunZone, + key: string, + uploadId: string, + from: number, + to: number, + options?: { + expires?: number; // URL 过期时间(秒),默认 3600 + headers?: Record; + timeout?: number; + stsToken?: string; + accessKeyId?: string; + accessKeySecret?: string; + } + ) { + const client = new OSS({ + region: `oss-${zone}`, + accessKeyId: options?.accessKeyId || this.accessKey, + accessKeySecret: options?.accessKeySecret || this.secretKey, + bucket: bucket, + stsToken: options?.stsToken, + }); + try { + const presignedUrls: Array<{ partNumber: number; uploadUrl: string }> = + []; + const expires = options?.expires || 3600; + for (let i = from; i <= to; i++) { + const uploadUrl = client.signatureUrl(key, { + method: 'PUT', + expires: expires, + subResource: { + uploadId: uploadId, + partNumber: String(i), + }, + "Content-Type": "application/octet-stream", + } as any); + + presignedUrls.push({ + partNumber: i, + uploadUrl: uploadUrl, + }); + } + return presignedUrls; + } catch (error: any) { + throw new OakExternalException('aliyun', error.code, error.message, { + status: error.status, + }); + } + } /** * 准备分片上传(初始化并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL diff --git a/src/service/s3/S3.ts b/src/service/s3/S3.ts index 4034618..248af51 100644 --- a/src/service/s3/S3.ts +++ b/src/service/s3/S3.ts @@ -231,6 +231,56 @@ export class S3Instance { } } + /** + * 为分片上传生成预签名 URL + * @param bucket 桶 + * @param key 对象键 + * @param uploadId 上传 ID + * @param from 起始分片号 + * @param to 结束分片号 + * @param options 配置项 + * @returns 分片预签名 URL 列表 + */ + async presignMulti( + bucket: string, + key: string, + uploadId: string, + from: number, + to: number, + options?: { + endpoint?: string; + expiresIn?: number; // URL 过期时间(秒),默认 3600 + } + ) { + const client = options?.endpoint + ? this.createClient(options.endpoint, this.defaultRegion) + : this.client; + + // 2. 为每个分片生成预签名 URL + const parts: Array<{ partNumber: number; uploadUrl: string }> = []; + const expiresIn = options?.expiresIn || 3600; + + for (let i = from; i <= to; i++) { + const uploadCommand = new UploadPartCommand({ + Bucket: bucket, + Key: key, + UploadId: uploadId, + PartNumber: i, + }); + + const uploadUrl = await getSignedUrl(client, uploadCommand, { + expiresIn: expiresIn, + }); + + parts.push({ + partNumber: i, + uploadUrl: uploadUrl, + }); + } + + return parts; + } + /** * 准备分片上传(创建分片上传并生成所有分片的预签名URL) * 用于前端直传场景,返回 uploadId 和每个分片的上传 URL