@cloudbase/storage 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +48 -404
- package/dist/cjs/storage.d.ts +49 -0
- package/dist/cjs/storage.js +701 -0
- package/dist/cjs/supabase/errors.d.ts +20 -0
- package/dist/cjs/supabase/errors.js +65 -0
- package/dist/cjs/supabase/index.d.ts +145 -0
- package/dist/cjs/supabase/index.js +706 -0
- package/dist/cjs/supabase/types.d.ts +64 -0
- package/dist/cjs/supabase/types.js +3 -0
- package/dist/esm/index.js +47 -403
- package/dist/esm/storage.d.ts +49 -0
- package/dist/esm/storage.js +698 -0
- package/dist/esm/supabase/errors.d.ts +20 -0
- package/dist/esm/supabase/errors.js +61 -0
- package/dist/esm/supabase/index.d.ts +145 -0
- package/dist/esm/supabase/index.js +703 -0
- package/dist/esm/supabase/types.d.ts +64 -0
- package/dist/esm/supabase/types.js +2 -0
- package/package.json +4 -4
- package/src/index.ts +58 -330
- package/src/storage.ts +683 -0
- package/src/supabase/errors.ts +43 -0
- package/src/supabase/index.ts +746 -0
- package/src/supabase/types.ts +132 -0
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
export type FileBody = ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | NodeJS.ReadableStream | ReadableStream<Uint8Array> | URLSearchParams | string;
|
|
4
|
+
export type BucketType = 'STANDARD' | 'ANALYTICS';
|
|
5
|
+
export interface Bucket {
|
|
6
|
+
id: string;
|
|
7
|
+
type?: BucketType;
|
|
8
|
+
name: string;
|
|
9
|
+
owner: string;
|
|
10
|
+
file_size_limit?: number;
|
|
11
|
+
allowed_mime_types?: string[];
|
|
12
|
+
created_at: string;
|
|
13
|
+
updated_at: string;
|
|
14
|
+
public: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface FileObject {
|
|
17
|
+
name: string;
|
|
18
|
+
bucket_id: string;
|
|
19
|
+
owner: string;
|
|
20
|
+
id: string;
|
|
21
|
+
updated_at: string;
|
|
22
|
+
created_at: string;
|
|
23
|
+
last_accessed_at: string;
|
|
24
|
+
metadata: Record<string, any>;
|
|
25
|
+
buckets: Bucket;
|
|
26
|
+
}
|
|
27
|
+
export interface FileObjectV2 {
|
|
28
|
+
id: string;
|
|
29
|
+
version: string;
|
|
30
|
+
name: string;
|
|
31
|
+
bucket_id: string;
|
|
32
|
+
updated_at: string;
|
|
33
|
+
created_at: string;
|
|
34
|
+
last_accessed_at: string;
|
|
35
|
+
size?: number;
|
|
36
|
+
cache_control?: string;
|
|
37
|
+
content_type?: string;
|
|
38
|
+
etag?: string;
|
|
39
|
+
last_modified?: string;
|
|
40
|
+
metadata?: Record<string, any>;
|
|
41
|
+
}
|
|
42
|
+
export interface FileOptions {
|
|
43
|
+
cacheControl?: string;
|
|
44
|
+
contentType?: string;
|
|
45
|
+
upsert?: boolean;
|
|
46
|
+
duplex?: string;
|
|
47
|
+
metadata?: Record<string, any>;
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
export interface DestinationOptions {
|
|
51
|
+
destinationBucket?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface TransformOptions {
|
|
54
|
+
width?: number;
|
|
55
|
+
height?: number;
|
|
56
|
+
resize?: 'cover' | 'contain' | 'fill';
|
|
57
|
+
quality?: number;
|
|
58
|
+
format?: 'origin';
|
|
59
|
+
}
|
|
60
|
+
type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}` ? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}` : S;
|
|
61
|
+
export type Camelize<T> = {
|
|
62
|
+
[K in keyof T as CamelCase<Extract<K, string>>]: T[K];
|
|
63
|
+
};
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3VwYWJhc2UvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIEZpbGVCb2R5ID1cbiAgfCBBcnJheUJ1ZmZlclxuICB8IEFycmF5QnVmZmVyVmlld1xuICB8IEJsb2JcbiAgfCBCdWZmZXJcbiAgfCBGaWxlXG4gIHwgRm9ybURhdGFcbiAgfCBOb2RlSlMuUmVhZGFibGVTdHJlYW1cbiAgfCBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PlxuICB8IFVSTFNlYXJjaFBhcmFtc1xuICB8IHN0cmluZ1xuXG4vKipcbiAqIFR5cGUgb2Ygc3RvcmFnZSBidWNrZXRcbiAqIC0gU1RBTkRBUkQ6IFJlZ3VsYXIgZmlsZSBzdG9yYWdlIGJ1Y2tldHNcbiAqIC0gQU5BTFlUSUNTOiBJY2ViZXJnIHRhYmxlLWJhc2VkIGJ1Y2tldHMgZm9yIGFuYWx5dGljYWwgd29ya2xvYWRzXG4gKi9cbmV4cG9ydCB0eXBlIEJ1Y2tldFR5cGUgPSAnU1RBTkRBUkQnIHwgJ0FOQUxZVElDUydcblxuZXhwb3J0IGludGVyZmFjZSBCdWNrZXQge1xuICBpZDogc3RyaW5nXG4gIHR5cGU/OiBCdWNrZXRUeXBlXG4gIG5hbWU6IHN0cmluZ1xuICBvd25lcjogc3RyaW5nXG4gIGZpbGVfc2l6ZV9saW1pdD86IG51bWJlclxuICBhbGxvd2VkX21pbWVfdHlwZXM/OiBzdHJpbmdbXVxuICBjcmVhdGVkX2F0OiBzdHJpbmdcbiAgdXBkYXRlZF9hdDogc3RyaW5nXG4gIHB1YmxpYzogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVPYmplY3Qge1xuICBuYW1lOiBzdHJpbmdcbiAgYnVja2V0X2lkOiBzdHJpbmdcbiAgb3duZXI6IHN0cmluZ1xuICBpZDogc3RyaW5nXG4gIHVwZGF0ZWRfYXQ6IHN0cmluZ1xuICBjcmVhdGVkX2F0OiBzdHJpbmdcbiAgLyoqIEBkZXByZWNhdGVkICovXG4gIGxhc3RfYWNjZXNzZWRfYXQ6IHN0cmluZ1xuICBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgYW55PlxuICBidWNrZXRzOiBCdWNrZXRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlT2JqZWN0VjIge1xuICBpZDogc3RyaW5nXG4gIHZlcnNpb246IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAgYnVja2V0X2lkOiBzdHJpbmdcbiAgdXBkYXRlZF9hdDogc3RyaW5nXG4gIGNyZWF0ZWRfYXQ6IHN0cmluZ1xuICAvKiogQGRlcHJlY2F0ZWQgKi9cbiAgbGFzdF9hY2Nlc3NlZF9hdDogc3RyaW5nXG4gIHNpemU/OiBudW1iZXJcbiAgY2FjaGVfY29udHJvbD86IHN0cmluZ1xuICBjb250ZW50X3R5cGU/OiBzdHJpbmdcbiAgZXRhZz86IHN0cmluZ1xuICBsYXN0X21vZGlmaWVkPzogc3RyaW5nXG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgYW55PlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2Ygc2Vjb25kcyB0aGUgYXNzZXQgaXMgY2FjaGVkIGluIHRoZSBicm93c2VyIGFuZCBpbiB0aGUgU3VwYWJhc2UgQ0ROLiBUaGlzIGlzIHNldCBpbiB0aGUgYENhY2hlLUNvbnRyb2w6IG1heC1hZ2U9PHNlY29uZHM+YCBoZWFkZXIuIERlZmF1bHRzIHRvIDM2MDAgc2Vjb25kcy5cbiAgICovXG4gIGNhY2hlQ29udHJvbD86IHN0cmluZ1xuICAvKipcbiAgICogdGhlIGBDb250ZW50LVR5cGVgIGhlYWRlciB2YWx1ZS4gU2hvdWxkIGJlIHNwZWNpZmllZCBpZiB1c2luZyBhIGBmaWxlQm9keWAgdGhhdCBpcyBuZWl0aGVyIGBCbG9iYCBub3IgYEZpbGVgIG5vciBgRm9ybURhdGFgLCBvdGhlcndpc2Ugd2lsbCBkZWZhdWx0IHRvIGB0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLThgLlxuICAgKi9cbiAgY29udGVudFR5cGU/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFdoZW4gdXBzZXJ0IGlzIHNldCB0byB0cnVlLCB0aGUgZmlsZSBpcyBvdmVyd3JpdHRlbiBpZiBpdCBleGlzdHMuIFdoZW4gc2V0IHRvIGZhbHNlLCBhbiBlcnJvciBpcyB0aHJvd24gaWYgdGhlIG9iamVjdCBhbHJlYWR5IGV4aXN0cy4gRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICovXG4gIHVwc2VydD86IGJvb2xlYW5cbiAgLyoqXG4gICAqIFRoZSBkdXBsZXggb3B0aW9uIGlzIGEgc3RyaW5nIHBhcmFtZXRlciB0aGF0IGVuYWJsZXMgb3IgZGlzYWJsZXMgZHVwbGV4IHN0cmVhbWluZywgYWxsb3dpbmcgZm9yIGJvdGggcmVhZGluZyBhbmQgd3JpdGluZyBkYXRhIGluIHRoZSBzYW1lIHN0cmVhbS4gSXQgY2FuIGJlIHBhc3NlZCBhcyBhbiBvcHRpb24gdG8gdGhlIGZldGNoKCkgbWV0aG9kLlxuICAgKi9cbiAgZHVwbGV4Pzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBtZXRhZGF0YSBvcHRpb24gaXMgYW4gb2JqZWN0IHRoYXQgYWxsb3dzIHlvdSB0byBzdG9yZSBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaWxlLiBUaGlzIGluZm9ybWF0aW9uIGNhbiBiZSB1c2VkIHRvIGZpbHRlciBhbmQgc2VhcmNoIGZvciBmaWxlcy4gVGhlIG1ldGFkYXRhIG9iamVjdCBjYW4gY29udGFpbiBhbnkga2V5LXZhbHVlIHBhaXJzIHlvdSB3YW50IHRvIHN0b3JlLlxuICAgKi9cbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsbHkgYWRkIGV4dHJhIGhlYWRlcnNcbiAgICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVzdGluYXRpb25PcHRpb25zIHtcbiAgZGVzdGluYXRpb25CdWNrZXQ/OiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2Zvcm1PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSB3aWR0aCBvZiB0aGUgaW1hZ2UgaW4gcGl4ZWxzLlxuICAgKi9cbiAgd2lkdGg/OiBudW1iZXJcbiAgLyoqXG4gICAqIFRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGluIHBpeGVscy5cbiAgICovXG4gIGhlaWdodD86IG51bWJlclxuICAvKipcbiAgICogVGhlIHJlc2l6ZSBtb2RlIGNhbiBiZSBjb3ZlciwgY29udGFpbiBvciBmaWxsLiBEZWZhdWx0cyB0byBjb3Zlci5cbiAgICogQ292ZXIgcmVzaXplcyB0aGUgaW1hZ2UgdG8gbWFpbnRhaW4gaXQncyBhc3BlY3QgcmF0aW8gd2hpbGUgZmlsbGluZyB0aGUgZW50aXJlIHdpZHRoIGFuZCBoZWlnaHQuXG4gICAqIENvbnRhaW4gcmVzaXplcyB0aGUgaW1hZ2UgdG8gbWFpbnRhaW4gaXQncyBhc3BlY3QgcmF0aW8gd2hpbGUgZml0dGluZyB0aGUgZW50aXJlIGltYWdlIHdpdGhpbiB0aGUgd2lkdGggYW5kIGhlaWdodC5cbiAgICogRmlsbCByZXNpemVzIHRoZSBpbWFnZSB0byBmaWxsIHRoZSBlbnRpcmUgd2lkdGggYW5kIGhlaWdodC4gSWYgdGhlIG9iamVjdCdzIGFzcGVjdCByYXRpbyBkb2VzIG5vdCBtYXRjaCB0aGUgd2lkdGggYW5kIGhlaWdodCwgdGhlIGltYWdlIHdpbGwgYmUgc3RyZXRjaGVkIHRvIGZpdC5cbiAgICovXG4gIHJlc2l6ZT86ICdjb3ZlcicgfCAnY29udGFpbicgfCAnZmlsbCdcbiAgLyoqXG4gICAqIFNldCB0aGUgcXVhbGl0eSBvZiB0aGUgcmV0dXJuZWQgaW1hZ2UuXG4gICAqIEEgbnVtYmVyIGZyb20gMjAgdG8gMTAwLCB3aXRoIDEwMCBiZWluZyB0aGUgaGlnaGVzdCBxdWFsaXR5LlxuICAgKiBEZWZhdWx0cyB0byA4MFxuICAgKi9cbiAgcXVhbGl0eT86IG51bWJlclxuICAvKipcbiAgICogU3BlY2lmeSB0aGUgZm9ybWF0IG9mIHRoZSBpbWFnZSByZXF1ZXN0ZWQuXG4gICAqXG4gICAqIFdoZW4gdXNpbmcgJ29yaWdpbicgd2UgZm9yY2UgdGhlIGZvcm1hdCB0byBiZSB0aGUgc2FtZSBhcyB0aGUgb3JpZ2luYWwgaW1hZ2UuXG4gICAqIFdoZW4gdGhpcyBvcHRpb24gaXMgbm90IHBhc3NlZCBpbiwgaW1hZ2VzIGFyZSBvcHRpbWl6ZWQgdG8gbW9kZXJuIGltYWdlIGZvcm1hdHMgbGlrZSBXZWJwLlxuICAgKi9cbiAgZm9ybWF0PzogJ29yaWdpbidcbn1cblxudHlwZSBDYW1lbENhc2U8UyBleHRlbmRzIHN0cmluZz4gPSBTIGV4dGVuZHMgYCR7aW5mZXIgUDF9XyR7aW5mZXIgUDJ9JHtpbmZlciBQM31gXG4gID8gYCR7TG93ZXJjYXNlPFAxPn0ke1VwcGVyY2FzZTxQMj59JHtDYW1lbENhc2U8UDM+fWBcbiAgOiBTXG5cbmV4cG9ydCB0eXBlIENhbWVsaXplPFQ+ID0ge1xuICBbSyBpbiBrZXlvZiBUIGFzIENhbWVsQ2FzZTxFeHRyYWN0PEssIHN0cmluZz4+XTogVFtLXVxufVxuIl19
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/storage",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "cloudbase js sdk storage module",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"author": "",
|
|
28
28
|
"license": "Apache-2.0",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@cloudbase/types": "3.0.
|
|
31
|
-
"@cloudbase/utilities": "3.0.
|
|
30
|
+
"@cloudbase/types": "3.0.1",
|
|
31
|
+
"@cloudbase/utilities": "3.0.1"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "a29767afc9a2b16cd632074c7c751abcf81746ed"
|
|
34
34
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,358 +1,86 @@
|
|
|
1
|
-
import { constants, utils, helpers } from '@cloudbase/utilities'
|
|
2
1
|
import { ICloudbase } from '@cloudbase/types'
|
|
3
2
|
import { ICloudbaseComponent } from '@cloudbase/types/component'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
ICloudbaseFileInfo,
|
|
7
|
-
ICloudbaseUploadFileParams,
|
|
8
|
-
ICloudbaseUploadFileResult,
|
|
9
|
-
ICloudbaseGetUploadMetadataParams,
|
|
10
|
-
ICloudbaseDeleteFileParams,
|
|
11
|
-
ICloudbaseDeleteFileResult,
|
|
12
|
-
ICloudbaseGetTempFileURLResult,
|
|
13
|
-
ICloudbaseGetTempFileURLParams,
|
|
14
|
-
ICloudbaseDownloadFileResult,
|
|
15
|
-
ICloudbaseDownloadFileParams,
|
|
16
|
-
} from '@cloudbase/types/storage'
|
|
3
|
+
import { CloudbaseStorage, COMPONENT_NAME, ICloudbaseContext } from './storage'
|
|
4
|
+
import { SupabaseFileAPILikeStorage } from './supabase'
|
|
17
5
|
|
|
18
6
|
declare const cloudbase: ICloudbase
|
|
19
7
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
const storage = new CloudbaseStorage()
|
|
9
|
+
const component: ICloudbaseComponent = {
|
|
10
|
+
name: COMPONENT_NAME,
|
|
11
|
+
entity: {
|
|
12
|
+
uploadFile: storage.uploadFile,
|
|
13
|
+
deleteFile: storage.deleteFile,
|
|
14
|
+
getTempFileURL: storage.getTempFileURL,
|
|
15
|
+
downloadFile: storage.downloadFile,
|
|
16
|
+
getUploadMetadata: storage.getUploadMetadata,
|
|
17
|
+
copyFile: storage.copyFile,
|
|
18
|
+
getFileInfo: storage.getFileInfo,
|
|
19
|
+
isGateWay: storage.isGateWay,
|
|
20
|
+
},
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class CloudbaseStorage {
|
|
32
|
-
@catchErrorsDecorator({
|
|
33
|
-
customInfo: {
|
|
34
|
-
className: 'Cloudbase',
|
|
35
|
-
methodName: 'uploadFile',
|
|
36
|
-
},
|
|
37
|
-
title: '上传文件失败',
|
|
38
|
-
messages: [
|
|
39
|
-
'请确认以下各项:',
|
|
40
|
-
' 1 - 调用 uploadFile() 的语法或参数是否正确',
|
|
41
|
-
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
|
|
42
|
-
' 3 - 云存储安全规则是否限制了当前登录状态访问',
|
|
43
|
-
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`,
|
|
44
|
-
],
|
|
45
|
-
})
|
|
46
|
-
public async uploadFile(
|
|
47
|
-
params: ICloudbaseUploadFileParams,
|
|
48
|
-
callback?: Function
|
|
49
|
-
): Promise<ICloudbaseUploadFileResult> {
|
|
50
|
-
const { cloudPath, filePath, onUploadProgress, method = 'put', headers = {} } = params
|
|
51
|
-
if (!isString(cloudPath) || !filePath) {
|
|
52
|
-
throw new Error(JSON.stringify({
|
|
53
|
-
code: ERRORS.INVALID_PARAMS,
|
|
54
|
-
msg: `[${COMPONENT_NAME}.uploadFile] invalid params`,
|
|
55
|
-
}))
|
|
56
|
-
}
|
|
57
|
-
const uploadMethod = { put: EUploadMethod.put, post: EUploadMethod.post }[method.toLocaleLowerCase()] || EUploadMethod.put
|
|
58
|
-
|
|
59
|
-
const action = 'storage.getUploadMetadata'
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
const { request } = this
|
|
62
|
-
const metaDataParam = {
|
|
63
|
-
path: cloudPath,
|
|
64
|
-
method: uploadMethod,
|
|
65
|
-
}
|
|
66
|
-
if (uploadMethod === EUploadMethod.put) {
|
|
67
|
-
/* eslint-disable-next-line */
|
|
68
|
-
metaDataParam["headers"] = headers
|
|
69
|
-
}
|
|
70
|
-
const metaData: ICloudbaseFileMetaDataRes = await request.send(action, metaDataParam)
|
|
71
|
-
|
|
72
|
-
const {
|
|
73
|
-
data: { url, authorization, token, fileId, cosFileId, download_url: downloadUrl },
|
|
74
|
-
requestId,
|
|
75
|
-
} = metaData
|
|
76
|
-
|
|
77
|
-
const commonParams = {
|
|
78
|
-
url,
|
|
79
|
-
file: filePath,
|
|
80
|
-
name: cloudPath,
|
|
81
|
-
onUploadProgress,
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const putParams = {
|
|
85
|
-
...commonParams,
|
|
86
|
-
method: EUploadMethod.put,
|
|
87
|
-
headers: {
|
|
88
|
-
...headers,
|
|
89
|
-
authorization,
|
|
90
|
-
'x-cos-meta-fileid': cosFileId,
|
|
91
|
-
'x-cos-security-token': token,
|
|
92
|
-
},
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const postParams = {
|
|
96
|
-
...commonParams,
|
|
97
|
-
method: EUploadMethod.post,
|
|
98
|
-
data: {
|
|
99
|
-
key: cloudPath,
|
|
100
|
-
signature: authorization,
|
|
101
|
-
'x-cos-meta-fileid': cosFileId,
|
|
102
|
-
success_action_status: '201',
|
|
103
|
-
'x-cos-security-token': token,
|
|
104
|
-
},
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const uploadConfig = {
|
|
108
|
-
[EUploadMethod.put]: {
|
|
109
|
-
params: putParams,
|
|
110
|
-
isSuccess: (code: number) => code >= 200 && code < 300,
|
|
111
|
-
},
|
|
112
|
-
[EUploadMethod.post]: {
|
|
113
|
-
params: postParams,
|
|
114
|
-
isSuccess: (code: number) => code === 201,
|
|
115
|
-
},
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const res = await request.upload(uploadConfig[uploadMethod].params)
|
|
119
|
-
|
|
120
|
-
if (uploadConfig[uploadMethod].isSuccess(res.statusCode)) {
|
|
121
|
-
return execCallback(callback, null, {
|
|
122
|
-
fileID: fileId,
|
|
123
|
-
download_url: downloadUrl,
|
|
124
|
-
requestId,
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
return execCallback(callback, new Error(`[${getSdkName()}][${ERRORS.OPERATION_FAIL}][${COMPONENT_NAME}]:${res.data}`))
|
|
128
|
-
}
|
|
129
|
-
@catchErrorsDecorator({
|
|
130
|
-
customInfo: {
|
|
131
|
-
className: 'Cloudbase',
|
|
132
|
-
methodName: 'getUploadMetadata',
|
|
133
|
-
},
|
|
134
|
-
title: '获取上传元信息失败',
|
|
135
|
-
messages: [
|
|
136
|
-
'请确认以下各项:',
|
|
137
|
-
' 1 - 调用 getUploadMetadata() 的语法或参数是否正确',
|
|
138
|
-
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
|
|
139
|
-
' 3 - 云存储安全规则是否限制了当前登录状态访问',
|
|
140
|
-
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`,
|
|
141
|
-
],
|
|
142
|
-
})
|
|
143
|
-
public async getUploadMetadata(
|
|
144
|
-
params: ICloudbaseGetUploadMetadataParams,
|
|
145
|
-
callback?: Function
|
|
146
|
-
): Promise<any> {
|
|
147
|
-
const { cloudPath } = params
|
|
148
|
-
if (!isString(cloudPath)) {
|
|
149
|
-
throw new Error(JSON.stringify({
|
|
150
|
-
code: ERRORS.INVALID_PARAMS,
|
|
151
|
-
msg: `[${COMPONENT_NAME}.getUploadMetadata] invalid cloudPath`,
|
|
152
|
-
}))
|
|
153
|
-
}
|
|
154
|
-
// @ts-ignore
|
|
155
|
-
const { request } = this
|
|
156
|
-
const action = 'storage.getUploadMetadata'
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
const metaData = await request.send(action, {
|
|
160
|
-
path: cloudPath,
|
|
161
|
-
})
|
|
162
|
-
return execCallback(callback, null, metaData)
|
|
163
|
-
} catch (err) {
|
|
164
|
-
return execCallback(callback, err)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
@catchErrorsDecorator({
|
|
168
|
-
customInfo: {
|
|
169
|
-
className: 'Cloudbase',
|
|
170
|
-
methodName: 'deleteFile',
|
|
171
|
-
},
|
|
172
|
-
title: '删除文件失败',
|
|
173
|
-
messages: [
|
|
174
|
-
'请确认以下各项:',
|
|
175
|
-
' 1 - 调用 deleteFile() 的语法或参数是否正确',
|
|
176
|
-
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
|
|
177
|
-
' 3 - 云存储安全规则是否限制了当前登录状态访问',
|
|
178
|
-
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`,
|
|
179
|
-
],
|
|
180
|
-
})
|
|
181
|
-
public async deleteFile(
|
|
182
|
-
params: ICloudbaseDeleteFileParams,
|
|
183
|
-
callback?: Function
|
|
184
|
-
): Promise<ICloudbaseDeleteFileResult> {
|
|
185
|
-
const { fileList } = params
|
|
186
|
-
|
|
187
|
-
if (!fileList || !isArray(fileList) || fileList.length === 0) {
|
|
188
|
-
throw new Error(JSON.stringify({
|
|
189
|
-
code: ERRORS.INVALID_PARAMS,
|
|
190
|
-
msg: `[${COMPONENT_NAME}.deleteFile] fileList must not be empty`,
|
|
191
|
-
}))
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
for (const fileId of fileList) {
|
|
195
|
-
if (!fileId || !isString(fileId)) {
|
|
196
|
-
throw new Error(JSON.stringify({
|
|
197
|
-
code: ERRORS.INVALID_PARAMS,
|
|
198
|
-
msg: `[${COMPONENT_NAME}.deleteFile] fileID must be string`,
|
|
199
|
-
}))
|
|
200
|
-
}
|
|
201
|
-
}
|
|
23
|
+
const supabaseComponent: ICloudbaseComponent = {
|
|
24
|
+
name: `${COMPONENT_NAME}/supabase`,
|
|
25
|
+
IIFE: true,
|
|
26
|
+
entity() {
|
|
27
|
+
// 在 IIFE 中,this 是 Cloudbase 类(构造函数),不是实例
|
|
28
|
+
// 所以我们需要使用 getter 来延迟获取实例的 config 和 request
|
|
202
29
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const { request } = this
|
|
206
|
-
const res = await request.send(action, {
|
|
207
|
-
fileid_list: fileList,
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
if (res.code) {
|
|
211
|
-
return execCallback(callback, null, res)
|
|
212
|
-
}
|
|
213
|
-
const data = {
|
|
214
|
-
fileList: res.data.delete_list,
|
|
215
|
-
requestId: res.requestId,
|
|
216
|
-
}
|
|
217
|
-
return execCallback(callback, null, data)
|
|
218
|
-
}
|
|
219
|
-
@catchErrorsDecorator({
|
|
220
|
-
customInfo: {
|
|
221
|
-
className: 'Cloudbase',
|
|
222
|
-
methodName: 'getTempFileURL',
|
|
223
|
-
},
|
|
224
|
-
title: '获取文件下载链接',
|
|
225
|
-
messages: [
|
|
226
|
-
'请确认以下各项:',
|
|
227
|
-
' 1 - 调用 getTempFileURL() 的语法或参数是否正确',
|
|
228
|
-
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
|
|
229
|
-
' 3 - 云存储安全规则是否限制了当前登录状态访问',
|
|
230
|
-
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`,
|
|
231
|
-
],
|
|
232
|
-
})
|
|
233
|
-
public async getTempFileURL(
|
|
234
|
-
params: ICloudbaseGetTempFileURLParams,
|
|
235
|
-
callback?: Function
|
|
236
|
-
): Promise<ICloudbaseGetTempFileURLResult> {
|
|
237
|
-
const { fileList } = params
|
|
30
|
+
// 使用 WeakMap 缓存每个实例的 storage 对象
|
|
31
|
+
const storageCache = new WeakMap<any, SupabaseFileAPILikeStorage>()
|
|
238
32
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}))
|
|
244
|
-
}
|
|
33
|
+
// 定义 storage 属性的 getter,每个实例只创建一次
|
|
34
|
+
Object.defineProperty(this.prototype, 'storage', {
|
|
35
|
+
get() {
|
|
36
|
+
// 这里的 this 是 cloudbase 实例
|
|
245
37
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (!Object.prototype.hasOwnProperty.call(file, 'fileID')
|
|
250
|
-
|| !Object.prototype.hasOwnProperty.call(file, 'maxAge')) {
|
|
251
|
-
throw new Error(JSON.stringify({
|
|
252
|
-
code: ERRORS.INVALID_PARAMS,
|
|
253
|
-
msg: `[${COMPONENT_NAME}.getTempFileURL] file info must include fileID and maxAge`,
|
|
254
|
-
}))
|
|
38
|
+
// 如果已经创建过,直接返回缓存的实例
|
|
39
|
+
if (storageCache.has(this)) {
|
|
40
|
+
return storageCache.get(this)
|
|
255
41
|
}
|
|
256
42
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
43
|
+
// 创建动态 context,从当前实例获取 config 和 request
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
45
|
+
const instance = this
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
47
|
+
const context = new Proxy<ICloudbaseContext>({} as ICloudbaseContext, {
|
|
48
|
+
get: (_target, prop) => {
|
|
49
|
+
if (prop === 'config') {
|
|
50
|
+
return instance.config
|
|
51
|
+
}
|
|
52
|
+
if (prop === 'request') {
|
|
53
|
+
return instance.request
|
|
54
|
+
}
|
|
55
|
+
return undefined
|
|
56
|
+
},
|
|
260
57
|
})
|
|
261
|
-
} else if (isString(file)) {
|
|
262
|
-
convertedFileList.push({
|
|
263
|
-
fileid: file,
|
|
264
|
-
})
|
|
265
|
-
} else {
|
|
266
|
-
throw new Error(JSON.stringify({
|
|
267
|
-
code: ERRORS.INVALID_PARAMS,
|
|
268
|
-
msg: `[${COMPONENT_NAME}.getTempFileURL] invalid fileList`,
|
|
269
|
-
}))
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const action = 'storage.batchGetDownloadUrl'
|
|
274
|
-
// @ts-ignore
|
|
275
|
-
const { request } = this
|
|
276
|
-
|
|
277
|
-
const res = await request.send(action, { file_list: convertedFileList })
|
|
278
58
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
})
|
|
287
|
-
}
|
|
288
|
-
@catchErrorsDecorator({
|
|
289
|
-
customInfo: {
|
|
290
|
-
className: 'Cloudbase',
|
|
291
|
-
methodName: 'downloadFile',
|
|
292
|
-
},
|
|
293
|
-
title: '下载文件失败',
|
|
294
|
-
messages: [
|
|
295
|
-
'请确认以下各项:',
|
|
296
|
-
' 1 - 调用 downloadFile() 的语法或参数是否正确',
|
|
297
|
-
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
|
|
298
|
-
' 3 - 云存储安全规则是否限制了当前登录状态访问',
|
|
299
|
-
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`,
|
|
300
|
-
],
|
|
301
|
-
})
|
|
302
|
-
public async downloadFile(
|
|
303
|
-
params: ICloudbaseDownloadFileParams,
|
|
304
|
-
callback?: Function
|
|
305
|
-
): Promise<ICloudbaseDownloadFileResult> {
|
|
306
|
-
const { fileID } = params
|
|
307
|
-
if (!isString(fileID)) {
|
|
308
|
-
throw new Error(JSON.stringify({
|
|
309
|
-
code: ERRORS.INVALID_PARAMS,
|
|
310
|
-
msg: `[${COMPONENT_NAME}.getTempFileURL] fileID must be string`,
|
|
311
|
-
}))
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
const tmpUrlRes = await this.getTempFileURL.call(this, {
|
|
315
|
-
fileList: [{
|
|
316
|
-
fileID,
|
|
317
|
-
maxAge: 600,
|
|
318
|
-
}],
|
|
59
|
+
// 创建新的 storage 实例并缓存
|
|
60
|
+
const storage = new SupabaseFileAPILikeStorage(context)
|
|
61
|
+
storageCache.set(this, storage)
|
|
62
|
+
return storage
|
|
63
|
+
},
|
|
64
|
+
configurable: true,
|
|
65
|
+
enumerable: true,
|
|
319
66
|
})
|
|
320
|
-
|
|
321
|
-
const res = tmpUrlRes.fileList[0]
|
|
322
|
-
|
|
323
|
-
if (res.code !== 'SUCCESS') {
|
|
324
|
-
return execCallback(callback, res)
|
|
325
|
-
}
|
|
326
|
-
// @ts-ignore
|
|
327
|
-
const { request } = this
|
|
328
|
-
|
|
329
|
-
const tmpUrl = encodeURI(res.download_url)
|
|
330
|
-
|
|
331
|
-
const result = await request.download({ url: tmpUrl })
|
|
332
|
-
return execCallback(callback, null, result)
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const cloudbaseStorage = new CloudbaseStorage()
|
|
337
|
-
const component: ICloudbaseComponent = {
|
|
338
|
-
name: COMPONENT_NAME,
|
|
339
|
-
entity: {
|
|
340
|
-
uploadFile: cloudbaseStorage.uploadFile,
|
|
341
|
-
deleteFile: cloudbaseStorage.deleteFile,
|
|
342
|
-
getTempFileURL: cloudbaseStorage.getTempFileURL,
|
|
343
|
-
downloadFile: cloudbaseStorage.downloadFile,
|
|
344
|
-
getUploadMetadata: cloudbaseStorage.getUploadMetadata,
|
|
345
67
|
},
|
|
346
68
|
}
|
|
347
69
|
|
|
348
70
|
try {
|
|
349
71
|
cloudbase.registerComponent(component)
|
|
350
|
-
|
|
72
|
+
cloudbase.registerComponent(supabaseComponent)
|
|
73
|
+
} catch (e) {}
|
|
351
74
|
|
|
352
75
|
export function registerStorage(app: Pick<ICloudbase, 'registerComponent'>) {
|
|
353
76
|
try {
|
|
354
77
|
app.registerComponent(component)
|
|
78
|
+
app.registerComponent(supabaseComponent)
|
|
355
79
|
} catch (e) {
|
|
356
80
|
console.warn(e)
|
|
357
81
|
}
|
|
358
82
|
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
(window as any).registerStorage = registerStorage
|
|
86
|
+
} catch (e) {}
|