dpu-cloud-sdk 1.0.0
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/.env.development +1 -0
- package/.env.production +1 -0
- package/dist/DPUClient.d.ts +83 -0
- package/dist/DPUClient.js +1043 -0
- package/dist/ServiceIntegration.d.ts +20 -0
- package/dist/ServiceIntegration.js +506 -0
- package/dist/api/auth.d.ts +3 -0
- package/dist/api/auth.js +10 -0
- package/dist/api/compress.d.ts +4 -0
- package/dist/api/compress.js +16 -0
- package/dist/api/translate.d.ts +8 -0
- package/dist/api/translate.js +38 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/models/RequestModel.d.ts +33 -0
- package/dist/models/RequestModel.js +2 -0
- package/dist/models/ResponseModel.d.ts +99 -0
- package/dist/models/ResponseModel.js +1 -0
- package/dist/utils/Config.d.ts +32 -0
- package/dist/utils/Config.js +44 -0
- package/dist/utils/Constants.d.ts +48 -0
- package/dist/utils/Constants.js +55 -0
- package/dist/utils/Enum.d.ts +27 -0
- package/dist/utils/Enum.js +30 -0
- package/dist/utils/Helper.d.ts +4 -0
- package/dist/utils/Helper.js +47 -0
- package/dist/workerDownloadSingleFile.d.ts +1 -0
- package/dist/workerDownloadSingleFile.js +35 -0
- package/dist/workerUploadChildFile.d.ts +1 -0
- package/dist/workerUploadChildFile.js +82 -0
- package/dist/workerUploadSingleFile.d.ts +1 -0
- package/dist/workerUploadSingleFile.js +93 -0
- package/dpubim-service-1.1.28.tgz +0 -0
- package/package.json +33 -0
- package/src/DPUClient.ts +1505 -0
- package/src/ServiceIntegration.ts +710 -0
- package/src/api/auth.ts +18 -0
- package/src/api/compress.ts +36 -0
- package/src/api/translate.ts +94 -0
- package/src/index.ts +4 -0
- package/src/models/RequestModel.ts +44 -0
- package/src/models/ResponseModel.ts +110 -0
- package/src/utils/Config.ts +59 -0
- package/src/utils/Constants.ts +61 -0
- package/src/utils/Enum.ts +29 -0
- package/src/utils/Helper.ts +57 -0
- package/src/workerDownloadSingleFile.ts +34 -0
- package/src/workerUploadChildFile.ts +85 -0
- package/src/workerUploadSingleFile.ts +123 -0
- package/tsconfig.json +108 -0
- package/webpack.config.js +43 -0
package/src/api/auth.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseReponseModel, Token } from "../models/ResponseModel";
|
|
2
|
+
import { Path, PathAuth } from "../utils/Constants";
|
|
3
|
+
import { Scope } from "../utils/Enum";
|
|
4
|
+
import { baseFetch } from "./translate";
|
|
5
|
+
|
|
6
|
+
export const GetToken = async (clientId: string, clientSecret: string, scopes: Scope[]): Promise<BaseReponseModel<Token>> => {
|
|
7
|
+
const request = {
|
|
8
|
+
clientId,
|
|
9
|
+
clientSecret,
|
|
10
|
+
scopes: [0,1,2,3,4,5,6,7,8,9,10,11,12]
|
|
11
|
+
}
|
|
12
|
+
return baseFetch<Token, typeof request>(
|
|
13
|
+
`${Path.BaseURL}${PathAuth.GetToken}`,
|
|
14
|
+
"POST",
|
|
15
|
+
"",
|
|
16
|
+
request
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CompressFolderRequest, GetStatusCompressionRequest } from "../models/RequestModel";
|
|
2
|
+
import { BaseReponseModel, CompressionResponse, CompressStatus } from "../models/ResponseModel";
|
|
3
|
+
import { Path, PathManagement } from "../utils/Constants";
|
|
4
|
+
import { baseFetch } from "./translate";
|
|
5
|
+
|
|
6
|
+
export const CompressFolder = async (accessToken: string, bucketName: string, rootFolder?: string): Promise<BaseReponseModel<CompressionResponse>> => {
|
|
7
|
+
return baseFetch<CompressionResponse, CompressFolderRequest>(
|
|
8
|
+
`${Path.BaseURL}${PathManagement.CompressFolder}`,
|
|
9
|
+
"POST",
|
|
10
|
+
accessToken,
|
|
11
|
+
{
|
|
12
|
+
bucketName,
|
|
13
|
+
rootFolder
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const GetStatusCompress = async (requestIds: string[], accessToken: string): Promise<BaseReponseModel<CompressStatus>> => {
|
|
19
|
+
return baseFetch<CompressStatus, GetStatusCompressionRequest>(
|
|
20
|
+
`${Path.BaseURL}${PathManagement.GetStatusCompress}`,
|
|
21
|
+
"POST",
|
|
22
|
+
accessToken,
|
|
23
|
+
{
|
|
24
|
+
requestIds
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const CancelDownload = async (requestId: string, accessToken: string): Promise<BaseReponseModel<boolean>> => {
|
|
30
|
+
return baseFetch<boolean, string>(
|
|
31
|
+
`${Path.BaseURL}${PathManagement.CancelDownload}`,
|
|
32
|
+
"DELETE",
|
|
33
|
+
accessToken,
|
|
34
|
+
requestId
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetStatusTranslateRequest,
|
|
3
|
+
TranslateRequest,
|
|
4
|
+
} from "../models/RequestModel";
|
|
5
|
+
import {
|
|
6
|
+
BaseReponseModel,
|
|
7
|
+
TranslateInfo,
|
|
8
|
+
TranslateStatusInfo,
|
|
9
|
+
} from "../models/ResponseModel";
|
|
10
|
+
import { ApiStatus, Path, PathManagement } from "../utils/Constants";
|
|
11
|
+
|
|
12
|
+
export const baseFetch = async <T, T1>(
|
|
13
|
+
url: string,
|
|
14
|
+
method: string,
|
|
15
|
+
accessToken: string,
|
|
16
|
+
request?: T1
|
|
17
|
+
): Promise<BaseReponseModel<T>> => {
|
|
18
|
+
const response = await fetch(url, {
|
|
19
|
+
method: method,
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
Authorization: `Bearer ${accessToken}`,
|
|
23
|
+
'ngrok-skip-browser-warning': true
|
|
24
|
+
} as any,
|
|
25
|
+
body: JSON.stringify(request),
|
|
26
|
+
});
|
|
27
|
+
if (response.ok) return response.json();
|
|
28
|
+
if (response.status === 401)
|
|
29
|
+
return {
|
|
30
|
+
statusCode: ApiStatus.Unauthorized,
|
|
31
|
+
message: "Unauthorized",
|
|
32
|
+
data: null,
|
|
33
|
+
} as BaseReponseModel<T>;
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
reject(response.text);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const TranslateFile = async (
|
|
40
|
+
accessToken: string,
|
|
41
|
+
request: TranslateRequest
|
|
42
|
+
): Promise<BaseReponseModel<TranslateInfo>> => {
|
|
43
|
+
return baseFetch<TranslateInfo, TranslateRequest>(
|
|
44
|
+
`${Path.BaseURL}${PathManagement.TranslateFile}`,
|
|
45
|
+
"POST",
|
|
46
|
+
accessToken,
|
|
47
|
+
request
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const GetStatusTranslate = async (
|
|
52
|
+
accessToken: string,
|
|
53
|
+
request: string[]
|
|
54
|
+
): Promise<BaseReponseModel<TranslateStatusInfo[]>> => {
|
|
55
|
+
return baseFetch<TranslateStatusInfo[], string[]>(
|
|
56
|
+
`${Path.BaseURL}${PathManagement.GetStatusTranslate}`,
|
|
57
|
+
"POST",
|
|
58
|
+
accessToken,
|
|
59
|
+
request
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const GetStatusTranslateFile = async (
|
|
64
|
+
accessToken: string,
|
|
65
|
+
request: GetStatusTranslateRequest[]
|
|
66
|
+
): Promise<BaseReponseModel<TranslateStatusInfo[]>> => {
|
|
67
|
+
return baseFetch<TranslateStatusInfo[], GetStatusTranslateRequest[]>(
|
|
68
|
+
`${Path.BaseURL}${PathManagement.GetStatusTranslateFile}`,
|
|
69
|
+
"POST",
|
|
70
|
+
accessToken,
|
|
71
|
+
request
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const GetEPSGRegionCode = async (
|
|
76
|
+
accessToken: string
|
|
77
|
+
): Promise<BaseReponseModel<string[]>> => {
|
|
78
|
+
return baseFetch<string[], undefined>(
|
|
79
|
+
`${Path.BaseURL}${PathManagement.GetEPSGRegionCode}`,
|
|
80
|
+
"GET",
|
|
81
|
+
accessToken,
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const GetFileTileSet = async (
|
|
86
|
+
accessToken: string,
|
|
87
|
+
translateId: string
|
|
88
|
+
): Promise<BaseReponseModel<string>> => {
|
|
89
|
+
return baseFetch<string, undefined>(
|
|
90
|
+
`${Path.BaseURL}${PathManagement.GetFileTileSet}?translateId=${translateId}`,
|
|
91
|
+
"GET",
|
|
92
|
+
accessToken,
|
|
93
|
+
);
|
|
94
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type FileDownloadInfo = {
|
|
2
|
+
fullName: string;
|
|
3
|
+
contentLength?: number;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
//#region Compress
|
|
7
|
+
export type CompressFolderRequest = {
|
|
8
|
+
bucketName: string;
|
|
9
|
+
rootFolder?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type GetStatusCompressionRequest = {
|
|
13
|
+
requestIds: string[];
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
|
|
17
|
+
//#region Translate
|
|
18
|
+
export interface TranslateRequest {
|
|
19
|
+
modelType: string;
|
|
20
|
+
epsgCode: string;
|
|
21
|
+
translatePos?: number[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface FileTranslateRequest extends TranslateRequest {
|
|
25
|
+
bucketName?: string;
|
|
26
|
+
fileName?: string;
|
|
27
|
+
versionId?: string;
|
|
28
|
+
url?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface URNTranslateRequest extends TranslateRequest {
|
|
32
|
+
urn?: string;
|
|
33
|
+
accessToken: string | null;
|
|
34
|
+
clientId: string | null;
|
|
35
|
+
clientSecret: string | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface GetStatusTranslateRequest {
|
|
39
|
+
bucketName: string;
|
|
40
|
+
fileName: string;
|
|
41
|
+
versionId: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { StatusTranslate } from "../utils/Enum";
|
|
2
|
+
|
|
3
|
+
export type BaseReponseModel<T> = {
|
|
4
|
+
statusCode: number,
|
|
5
|
+
message: string,
|
|
6
|
+
data: T
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface PresignURLResponse {
|
|
10
|
+
url: string;
|
|
11
|
+
headers: { [key: string]: string; };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface MultiPresignURLResponse {
|
|
15
|
+
urls: { [key: string]: string; };
|
|
16
|
+
headers: { [key: string]: string; };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface InitUploadResponse {
|
|
20
|
+
uploadId: string;
|
|
21
|
+
headers: { [key: string]: string; };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type CompressionResponse = {
|
|
25
|
+
bucketName: string;
|
|
26
|
+
rootFolder: string;
|
|
27
|
+
requestId: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CompressStatus {
|
|
31
|
+
compressData: CompressResponse;
|
|
32
|
+
compressInfo: FileCompressInfo;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface FileCompressInfo {
|
|
36
|
+
bucketName: string;
|
|
37
|
+
rootFolder: string;
|
|
38
|
+
requestId: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface CompressResponse {
|
|
42
|
+
status: CompressStatus;
|
|
43
|
+
percent: number;
|
|
44
|
+
fileCompressed: number;
|
|
45
|
+
totalFile: number;
|
|
46
|
+
urlsDownload: string[] | null;
|
|
47
|
+
expireTime: Date | null;
|
|
48
|
+
compressTime: Date;
|
|
49
|
+
message: string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ObjectDetail {
|
|
53
|
+
bucketKey: string;
|
|
54
|
+
lastModified: string;
|
|
55
|
+
versionId: string;
|
|
56
|
+
objectKey: string;
|
|
57
|
+
contentLength: number | null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface CompleteMultipartUploadResponse {
|
|
61
|
+
key: string;
|
|
62
|
+
eTag: string;
|
|
63
|
+
versionId: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface TranslateStatusInfo {
|
|
67
|
+
translateId: string;
|
|
68
|
+
modelType: string;
|
|
69
|
+
translateType: string;
|
|
70
|
+
extensionSaveFile: string;
|
|
71
|
+
ePSGCode: string;
|
|
72
|
+
translatePos: number[] | null;
|
|
73
|
+
translateStatus: TranslateStatus;
|
|
74
|
+
objectTranslateInfo: ObjectTranslateInfo;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface ObjectTranslateInfo {
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface FileTranslateInfo extends ObjectTranslateInfo {
|
|
82
|
+
fileName: string;
|
|
83
|
+
bucketName: string;
|
|
84
|
+
versionId: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface URNTranslateInfo extends ObjectTranslateInfo {
|
|
88
|
+
urn: string;
|
|
89
|
+
clientID: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface TranslateStatus {
|
|
93
|
+
status: StatusTranslate;
|
|
94
|
+
percentTranslateGeometry: number | null;
|
|
95
|
+
percentTranslateMetadata: number | null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface Token{
|
|
99
|
+
accessToken: string;
|
|
100
|
+
expiresIn: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface Dictionary<T> {
|
|
104
|
+
[key: string]: T;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface TranslateInfo {
|
|
108
|
+
listError: Dictionary<string>;
|
|
109
|
+
translateStatusInfo: TranslateStatusInfo[];
|
|
110
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global configuration for DPU Storage
|
|
3
|
+
* This allows external packages to customize the BaseURL for their domains
|
|
4
|
+
*/
|
|
5
|
+
interface IConfig {
|
|
6
|
+
baseURL: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class DPUConfig {
|
|
10
|
+
private static instance: DPUConfig;
|
|
11
|
+
private config: IConfig = {
|
|
12
|
+
baseURL: 'https://translateservicedev.corebim.com', // Default URL
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
private constructor() {}
|
|
16
|
+
|
|
17
|
+
public static getInstance(): DPUConfig {
|
|
18
|
+
if (!DPUConfig.instance) {
|
|
19
|
+
DPUConfig.instance = new DPUConfig();
|
|
20
|
+
}
|
|
21
|
+
return DPUConfig.instance;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Set the base URL for API requests
|
|
26
|
+
* @param baseURL The base URL for all API calls
|
|
27
|
+
*/
|
|
28
|
+
public setBaseURL(baseURL: string): void {
|
|
29
|
+
if (!baseURL || typeof baseURL !== 'string') {
|
|
30
|
+
throw new Error('Invalid baseURL. Must be a non-empty string.');
|
|
31
|
+
}
|
|
32
|
+
this.config.baseURL = baseURL.trim();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get the current base URL
|
|
37
|
+
*/
|
|
38
|
+
public getBaseURL(): string {
|
|
39
|
+
return this.config.baseURL;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Set multiple configuration values at once
|
|
44
|
+
*/
|
|
45
|
+
public setConfig(config: Partial<IConfig>): void {
|
|
46
|
+
if (config.baseURL) {
|
|
47
|
+
this.setBaseURL(config.baseURL);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the entire configuration object
|
|
53
|
+
*/
|
|
54
|
+
public getConfig(): IConfig {
|
|
55
|
+
return { ...this.config };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const dpuConfig = DPUConfig.getInstance();
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { dpuConfig } from './Config';
|
|
2
|
+
|
|
3
|
+
export const Path = {
|
|
4
|
+
get BaseURL() {
|
|
5
|
+
return dpuConfig.getBaseURL();
|
|
6
|
+
},
|
|
7
|
+
InitiateMultipartUpload: '/fileApi/Object/InitiateMultipartUpload',
|
|
8
|
+
GeneratePresignedUrls: '/fileApi/Object/GeneratePresignedUrls',
|
|
9
|
+
GeneratePresignedUrl: '/fileApi/Object/GeneratePresignedUrl',
|
|
10
|
+
GenerateMultiPresignedURL: '/fileApi/Object/GenerateMultiPresignedURL',
|
|
11
|
+
CompleteMultipartUpload: '/fileApi/Object/CompleteMultipartUpload',
|
|
12
|
+
AbortMultipartUpload: '/fileApi/Object/AbortMultipartUpload',
|
|
13
|
+
GetObjectDetail: '/fileApi/Object/GetObjectDetail',
|
|
14
|
+
GetObjects: '/fileApi/Object/GetObjects',
|
|
15
|
+
GetUrlDownload: '/fileApi/Object/GetUrlDownload',
|
|
16
|
+
ApplyPermissionToObjects: '/fileApi/Object/ApplyPermissionToObjects',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const PathManagement = {
|
|
20
|
+
//#region Compress
|
|
21
|
+
CompressFolder: "/manageTranslateApi/Compress/CompressFolder",
|
|
22
|
+
GetStatusCompress: "/manageTranslateApi/Compress/GetStatusCompress",
|
|
23
|
+
CancelDownload: "/manageTranslateApi/Compress/CancelDownload",
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region Translate
|
|
26
|
+
TranslateFile: "/manageTranslateApi/Translate/TranslateFile",
|
|
27
|
+
GetStatusTranslate: "/manageTranslateApi/Translate/GetStatusTranslate",
|
|
28
|
+
GetStatusTranslateFile: "/manageTranslateApi/Translate/GetStatusTranslateFile",
|
|
29
|
+
GetEPSGRegionCode: "/manageTranslateApi/Translate/GetEPSGRegionCode",
|
|
30
|
+
GetFileTileSet: "/manageTranslateApi/Translate/GetFileTileSet",
|
|
31
|
+
//#endregion
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const PathAuth = {
|
|
35
|
+
GetToken: '/authApi/user/GetToken',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const ApiStatus = {
|
|
39
|
+
Success: 200,
|
|
40
|
+
BadRequest: 400,
|
|
41
|
+
Unauthorized: 401,
|
|
42
|
+
Forbidden: 403,
|
|
43
|
+
NotFound: 404,
|
|
44
|
+
InternalServerError: 500
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const ConfigFileRules = {
|
|
48
|
+
ChunkSize: 5 * 1024 * 1024, // 5MB
|
|
49
|
+
MaxChunkCountAllowed: 10000,
|
|
50
|
+
MaxRetryOnUrlExpiry: 2,
|
|
51
|
+
MaxRetry: 3,
|
|
52
|
+
MaxRetryOnTokenExpiry: 2,
|
|
53
|
+
MaxWebWorker: 20,
|
|
54
|
+
LimitFile: 200,
|
|
55
|
+
TaskCurrently: 10,
|
|
56
|
+
MaxFileInChunk: 2000,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const ConfigBase = {
|
|
60
|
+
PageSize: 1000
|
|
61
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export enum StatusWorker {
|
|
2
|
+
Success = "Success",
|
|
3
|
+
Error = "Error"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum StatusTranslate {
|
|
7
|
+
InQueue,
|
|
8
|
+
Translating,
|
|
9
|
+
Translated,
|
|
10
|
+
TranslateError,
|
|
11
|
+
Canceled,
|
|
12
|
+
NotFound
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export enum Scope {
|
|
16
|
+
DataRead,
|
|
17
|
+
DataWrite,
|
|
18
|
+
DataCreate,
|
|
19
|
+
DataSearch,
|
|
20
|
+
BucketCreate,
|
|
21
|
+
BucketRead,
|
|
22
|
+
BucketUpdate,
|
|
23
|
+
BucketDelete,
|
|
24
|
+
CodeAll,
|
|
25
|
+
AccountRead,
|
|
26
|
+
AccountWrite,
|
|
27
|
+
UserProfileRead,
|
|
28
|
+
ViewablesRead
|
|
29
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
|
|
3
|
+
export const validString = (value?: string): boolean => {
|
|
4
|
+
if (value === null || value === undefined || value === "") {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return true;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// large file is not supported (> 2GB)
|
|
12
|
+
// export const readFileDataAsBase64 = async (file: File): Promise<Buffer> => {
|
|
13
|
+
// const chunkSize = 1024 * 1024 * 10; // 10 MB chunks
|
|
14
|
+
// const totalSize = file.size;
|
|
15
|
+
// let bytesRead = 0;
|
|
16
|
+
|
|
17
|
+
// const reader = file.stream().getReader(); // Create a ReadableStream reader
|
|
18
|
+
|
|
19
|
+
// // Create a buffer to store the file data incrementally
|
|
20
|
+
// const arrayBuffer = new Uint8Array(totalSize);
|
|
21
|
+
|
|
22
|
+
// while (true) {
|
|
23
|
+
// const { done, value } = await reader.read(); // Read a chunk
|
|
24
|
+
// if (done) break;
|
|
25
|
+
|
|
26
|
+
// // Copy the chunk into the ArrayBuffer
|
|
27
|
+
// arrayBuffer.set(value, bytesRead);
|
|
28
|
+
// bytesRead += value.byteLength;
|
|
29
|
+
// }
|
|
30
|
+
// return Buffer.from(arrayBuffer);
|
|
31
|
+
// };
|
|
32
|
+
export const readFileDataAsBase64 = (file: File): Promise<Buffer> => {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const reader = new FileReader();
|
|
35
|
+
|
|
36
|
+
reader.onload = (event: any) => {
|
|
37
|
+
const buffer = Buffer.from(event.target.result);
|
|
38
|
+
resolve(buffer);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
reader.onerror = (err: any) => {
|
|
42
|
+
console.error("error when read file", err);
|
|
43
|
+
reject(err);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
reader.readAsArrayBuffer(file);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
export const chunkArray = <T>(array: T[], max: number): T[][] => {
|
|
50
|
+
if (max <= 0) throw new Error("max must be a positive number");
|
|
51
|
+
|
|
52
|
+
const result: T[][] = [];
|
|
53
|
+
for (let i = 0; i < array.length; i += max) {
|
|
54
|
+
result.push(array.slice(i, i + max));
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ServiceIntegration } from "./ServiceIntegration";
|
|
2
|
+
import { StatusWorker } from "./utils/Enum";
|
|
3
|
+
// tạm thời chưa làm phần token
|
|
4
|
+
self.onmessage = async (message) => {
|
|
5
|
+
const { data } = message;
|
|
6
|
+
try {
|
|
7
|
+
const chunk = await downloadSingleFile(data);
|
|
8
|
+
const result = {
|
|
9
|
+
status: StatusWorker.Success,
|
|
10
|
+
chunk: chunk,
|
|
11
|
+
requestId: data.requestId,
|
|
12
|
+
index: data.index,
|
|
13
|
+
};
|
|
14
|
+
self.postMessage(result, [chunk]); // Send the result back to the main thread
|
|
15
|
+
} catch (error) {
|
|
16
|
+
const result = {
|
|
17
|
+
status: StatusWorker.Error,
|
|
18
|
+
requestId: data.requestId,
|
|
19
|
+
};
|
|
20
|
+
self.postMessage(result);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
async function downloadSingleFile(data: any) {
|
|
25
|
+
const { url, start, end } = data;
|
|
26
|
+
try {
|
|
27
|
+
const service = new ServiceIntegration();
|
|
28
|
+
const response = await service.fetchChunkFile(url, start, end);
|
|
29
|
+
return response;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(`Error when download single file: ${error}`);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ApiStatus } from "./utils/Constants";
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import { StatusWorker } from "./utils/Enum";
|
|
4
|
+
|
|
5
|
+
let abortController: AbortController | null = null;
|
|
6
|
+
let workerPortRoot: MessagePort | null = null;
|
|
7
|
+
|
|
8
|
+
self.onmessage = async (message) => {
|
|
9
|
+
const { data } = message;
|
|
10
|
+
if (data.port) {
|
|
11
|
+
workerPortRoot = data.port;
|
|
12
|
+
} else {
|
|
13
|
+
// Handle abort message
|
|
14
|
+
if (data.type === "abort") {
|
|
15
|
+
if (abortController) {
|
|
16
|
+
abortController.abort();
|
|
17
|
+
abortController = null;
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const responseUpload = await uploadChildFile(data);
|
|
24
|
+
const result = {
|
|
25
|
+
status: StatusWorker.Success,
|
|
26
|
+
responseUpload,
|
|
27
|
+
requestId: data.requestId,
|
|
28
|
+
contentLength: data.arrayBuffer.byteLength,
|
|
29
|
+
};
|
|
30
|
+
self.postMessage(result); // Send the result back to the main thread
|
|
31
|
+
if (workerPortRoot) {
|
|
32
|
+
workerPortRoot.postMessage({
|
|
33
|
+
type: "progressUpload",
|
|
34
|
+
progress: {
|
|
35
|
+
dataUploadId: data.dataUploadId,
|
|
36
|
+
percentCompleted: 0,
|
|
37
|
+
fileKey: data.fileName,
|
|
38
|
+
contentLength: data.arrayBuffer.byteLength,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const result = {
|
|
44
|
+
status: StatusWorker.Error,
|
|
45
|
+
requestId: data.requestId,
|
|
46
|
+
error: error instanceof Error ? error.message : String(error),
|
|
47
|
+
};
|
|
48
|
+
self.postMessage(result);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
async function uploadChildFile(data: any) {
|
|
54
|
+
const { currentPresignUrl, arrayBuffer, partNumber } = data;
|
|
55
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
56
|
+
|
|
57
|
+
// Create new AbortController for this request
|
|
58
|
+
abortController = new AbortController();
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(currentPresignUrl.url, {
|
|
62
|
+
method: "PUT",
|
|
63
|
+
headers: currentPresignUrl.headers,
|
|
64
|
+
body: buffer,
|
|
65
|
+
signal: abortController.signal,
|
|
66
|
+
});
|
|
67
|
+
if (response.status === ApiStatus.Success) {
|
|
68
|
+
var eTag = response.headers.get("ETag");
|
|
69
|
+
if (eTag) {
|
|
70
|
+
const result = {
|
|
71
|
+
eTag: eTag.replace(/^"|"$/g, ""),
|
|
72
|
+
partNumber: partNumber,
|
|
73
|
+
};
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
throw new Error(`Error when upload child file: ${response.statusText}`);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
80
|
+
throw new Error("Upload cancelled");
|
|
81
|
+
}
|
|
82
|
+
console.error(`Error when upload child file: ${error}`);
|
|
83
|
+
throw new Error(`Error when upload child file: ${error}`);
|
|
84
|
+
}
|
|
85
|
+
}
|