返回 AiToEarn
ali-oss.adapter.ts
根目录 / project / aitoearn-backend / libs / assets / src / adapters / ali-oss.adapter.ts
1 import type OSS from 'ali-oss'
2 import type { Readable } from 'node:stream'
3 import type { CopyObjectOptions, StorageGetObjectResult, StorageHeadResult } from '../storage-provider'
4 import { AliOssService } from '@yikart/ali-oss'
5 import { StorageProvider } from '../storage-provider'
6
7 export class AliOssAdapter extends StorageProvider {
8 constructor(
9 private readonly aliOssService: AliOssService,
10 endpoint: string,
11 cdnEndpoint?: string,
12 private readonly callbackUrl?: string,
13 ) {
14 super(endpoint, cdnEndpoint)
15 }
16
17 async putObject(objectPath: string, file: Buffer | Readable, contentType?: string): Promise<{ path: string }> {
18 const options = contentType ? { headers: { 'Content-Type': contentType } } : undefined
19 await this.aliOssService.putObject(objectPath, file as Buffer, options)
20 return { path: objectPath }
21 }
22
23 async headObject(objectPath: string): Promise<StorageHeadResult> {
24 const result = await this.aliOssService.headObject(objectPath)
25 const headers = result.res?.headers as Record<string, string> | undefined
26 return {
27 contentLength: headers?.['content-length'] ? Number(headers['content-length']) : undefined,
28 contentType: headers?.['content-type'],
29 }
30 }
31
32 async putObjectFromUrl(url: string, objectPath: string): Promise<{ path: string, exists?: boolean }> {
33 return this.aliOssService.putObjectFromUrl(url, objectPath)
34 }
35
36 async deleteObject(objectPath: string): Promise<void> {
37 await this.aliOssService.deleteObject(objectPath)
38 }
39
40 private static readonly MIN_TRAFFIC_LIMIT = 819200
41
42 async getUploadSignUrl(objectPath: string, contentType?: string, contentLength?: number, callbackVars?: Record<string, string>): Promise<string> {
43 const callback: OSS.ObjectCallback | undefined = this.callbackUrl
44 ? this.buildCallback(callbackVars)
45 : undefined
46 const trafficLimit = contentLength
47 ? Math.max(contentLength, AliOssAdapter.MIN_TRAFFIC_LIMIT)
48 : undefined
49 return this.aliOssService.getUploadSignUrl(objectPath, contentType, trafficLimit, callback)
50 }
51
52 private buildCallback(callbackVars?: Record<string, string>): OSS.ObjectCallback {
53 const customBody = callbackVars
54 ? `,${this.parseResultBody(callbackVars)}`
55 : ''
56 return {
57 url: this.callbackUrl!,
58 body: `{"object":\${object},"size":\${size},"mimeType":\${mimeType}${customBody}}`,
59 contentType: 'application/json',
60 }
61 }
62
63 private parseResultBody(data: Record<string, string>): string {
64 const str = JSON.stringify(data)
65 return str.slice(1, str.length - 1)
66 }
67
68 async copyObject(objectPath: string, options: CopyObjectOptions): Promise<void> {
69 await this.aliOssService.copyObject(objectPath, options)
70 }
71
72 async getObject(objectPath: string): Promise<StorageGetObjectResult> {
73 const result = await this.aliOssService.getObject(objectPath)
74 const buffer = result.content ? Buffer.from(result.content) : undefined
75 return { buffer }
76 }
77
78 async getReadSignUrl(objectPath: string, expiresIn?: number): Promise<string> {
79 return Promise.resolve(this.aliOssService.getSignUrl(objectPath, expiresIn ? { expires: expiresIn } : undefined))
80 }
81 }
82
82 lines TYPESCRIPT