@or-sdk/files 3.8.2 → 3.9.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/CHANGELOG.md +9 -0
- package/dist/cjs/Files.js +223 -114
- package/dist/cjs/Files.js.map +1 -1
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/system-files.js +3 -0
- package/dist/cjs/types/system-files.js.map +1 -0
- package/dist/cjs/types/ttl.js +3 -0
- package/dist/cjs/types/ttl.js.map +1 -0
- package/dist/cjs/types/upload-files.js +3 -0
- package/dist/cjs/types/upload-files.js.map +1 -0
- package/dist/esm/Files.js +158 -84
- package/dist/esm/Files.js.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/system-files.js +2 -0
- package/dist/esm/types/system-files.js.map +1 -0
- package/dist/esm/types/ttl.js +2 -0
- package/dist/esm/types/ttl.js.map +1 -0
- package/dist/esm/types/upload-files.js +2 -0
- package/dist/esm/types/upload-files.js.map +1 -0
- package/dist/types/Files.d.ts +164 -6
- package/dist/types/Files.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types/system-files.d.ts +9 -0
- package/dist/types/types/system-files.d.ts.map +1 -0
- package/dist/types/types/ttl.d.ts +7 -0
- package/dist/types/types/ttl.d.ts.map +1 -0
- package/dist/types/types/upload-files.d.ts +130 -0
- package/dist/types/types/upload-files.d.ts.map +1 -0
- package/dist/types/types.d.ts +51 -72
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/Files.ts +317 -166
- package/src/index.ts +1 -1
- package/src/types/system-files.ts +29 -0
- package/src/types/ttl.ts +6 -0
- package/src/types/upload-files.ts +170 -0
- package/src/types.ts +50 -88
- package/tsconfig.types.json +3 -2
package/src/Files.ts
CHANGED
|
@@ -5,32 +5,38 @@ import { Memoize } from 'typescript-memoize';
|
|
|
5
5
|
|
|
6
6
|
import { SERVICE_KEY } from './constants';
|
|
7
7
|
import type {
|
|
8
|
+
ExtendedFileModel,
|
|
8
9
|
FileItem,
|
|
9
10
|
FileItemSelect,
|
|
11
|
+
FileModel,
|
|
10
12
|
FilesConfig,
|
|
11
|
-
GetItemsQuery,
|
|
13
|
+
GetItemsQuery,
|
|
14
|
+
GetSystemFileUploadUrlParams,
|
|
15
|
+
GetUploadUrlDataPayload,
|
|
16
|
+
RequestOptions,
|
|
12
17
|
SearchQuery,
|
|
18
|
+
Timestamp,
|
|
19
|
+
UploadFileOptions,
|
|
13
20
|
UploadFileProps,
|
|
21
|
+
UploadFilePropsLegacy,
|
|
14
22
|
UploadSystemFileParams,
|
|
15
|
-
|
|
23
|
+
UploadSystemFileParamsLegacy,
|
|
16
24
|
UploadToSignedUrlParameters,
|
|
17
25
|
UploadUrlProps,
|
|
26
|
+
UploadUrlPropsLegacy,
|
|
18
27
|
UploadUrlResponse,
|
|
19
28
|
} from './types';
|
|
20
29
|
import { isNode } from './utils';
|
|
21
30
|
|
|
22
31
|
export class Files extends Base {
|
|
23
|
-
/**
|
|
24
|
-
* @deprecated serviceUrl Use filesApiUrl instead
|
|
25
|
-
*/
|
|
26
32
|
constructor(params: FilesConfig) {
|
|
27
|
-
const { token,
|
|
33
|
+
const { token, accountId, discoveryUrl, filesApiUrl, serviceUrl } = params;
|
|
28
34
|
|
|
29
35
|
super({
|
|
30
36
|
token,
|
|
31
37
|
accountId,
|
|
32
38
|
discoveryUrl,
|
|
33
|
-
serviceUrl: filesApiUrl
|
|
39
|
+
serviceUrl: filesApiUrl ?? serviceUrl,
|
|
34
40
|
serviceKey: SERVICE_KEY,
|
|
35
41
|
});
|
|
36
42
|
}
|
|
@@ -40,7 +46,7 @@ export class Files extends Base {
|
|
|
40
46
|
* @param isPublic does this file public or private
|
|
41
47
|
* @param prefix the file path, example: /data/images/second.png
|
|
42
48
|
* @param attributes select specific props from FileItem. Example: 'key, isBoolean, size'
|
|
43
|
-
* @
|
|
49
|
+
* @returns object with: file, headData and url for downloading
|
|
44
50
|
*/
|
|
45
51
|
async getFile(prefix: string, isPublic: boolean, attributes?: string): Promise<FileItem> {
|
|
46
52
|
return await this.callApiV2({
|
|
@@ -57,7 +63,7 @@ export class Files extends Base {
|
|
|
57
63
|
/**
|
|
58
64
|
* Get one folder full data
|
|
59
65
|
* @param key the file path, example: /data/images/second.png
|
|
60
|
-
* @
|
|
66
|
+
* @returns Folder record
|
|
61
67
|
*/
|
|
62
68
|
async getFolder(key: string): Promise<FileItem> {
|
|
63
69
|
return await this.callApiV2({
|
|
@@ -72,7 +78,7 @@ export class Files extends Base {
|
|
|
72
78
|
/**
|
|
73
79
|
* Get folder size
|
|
74
80
|
* @param key the name of folder
|
|
75
|
-
* @
|
|
81
|
+
* @returns total folder size in bytes
|
|
76
82
|
*/
|
|
77
83
|
async getFolderSize(key: string): Promise<number> {
|
|
78
84
|
const { size } = await this.callApiV2<{ size: number; }>({
|
|
@@ -88,7 +94,7 @@ export class Files extends Base {
|
|
|
88
94
|
* Get list of public/private FileItems from api
|
|
89
95
|
* @param treePrefix the folder path where GET FileItems, for Root use ''
|
|
90
96
|
* @param isPublic does this file public or private, undefined for both types
|
|
91
|
-
* @
|
|
97
|
+
* @returns list of FileItem records
|
|
92
98
|
*/
|
|
93
99
|
async getItemsList(treePrefix: string, isPublic?: boolean): Promise<FileItem[]>;
|
|
94
100
|
/**
|
|
@@ -96,7 +102,7 @@ export class Files extends Base {
|
|
|
96
102
|
* @param treePrefix the folder path where GET FileItems, for Root use ''
|
|
97
103
|
* @param isPublic does this file public or private, undefined for both types
|
|
98
104
|
* @param attributes select specific props from FileItem. Example: 'key, isBoolean, size'
|
|
99
|
-
* @
|
|
105
|
+
* @returns list of FileItemSelect
|
|
100
106
|
*/
|
|
101
107
|
async getItemsList(treePrefix: string, isPublic?: boolean, attributes?: string): Promise<FileItemSelect[]>;
|
|
102
108
|
|
|
@@ -135,7 +141,7 @@ export class Files extends Base {
|
|
|
135
141
|
* Se list of public/private FileItems from api with specific prefix
|
|
136
142
|
* @param term the folder/file path where search will be done
|
|
137
143
|
* @param isPublic does this file public or private, undefined for both types
|
|
138
|
-
* @
|
|
144
|
+
* @returns list of FileItems
|
|
139
145
|
*/
|
|
140
146
|
async search(term: string, isPublic?: boolean): Promise<FileItem[]> {
|
|
141
147
|
const queryParams: SearchQuery = {
|
|
@@ -293,7 +299,7 @@ export class Files extends Base {
|
|
|
293
299
|
* @param isPublic does this file public or private
|
|
294
300
|
* @param expireMs how long PRIVATE file link will be accessible in milliseconds
|
|
295
301
|
* @param checkFileExist check that file exists in database
|
|
296
|
-
* @
|
|
302
|
+
* @returns file url
|
|
297
303
|
*/
|
|
298
304
|
async getDownloadUrl(key: string, isPublic: boolean, expireMs = 86400000, checkFileExist?: boolean): Promise<string> {
|
|
299
305
|
return await this.callApiV2({
|
|
@@ -310,201 +316,202 @@ export class Files extends Base {
|
|
|
310
316
|
|
|
311
317
|
/**
|
|
312
318
|
* Get a link for uploading specific file, JUST FOR INNER USE
|
|
313
|
-
* @
|
|
314
|
-
* @param isPublic does this file public or private
|
|
315
|
-
* @param ttl timestamp of file expiration
|
|
316
|
-
* @return uploading Url with different header Fields
|
|
319
|
+
* @returns URL for uploading a file with additional header Fields
|
|
317
320
|
*/
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
isPublic:
|
|
321
|
-
|
|
322
|
-
|
|
321
|
+
public async getUploadUrlV2(
|
|
322
|
+
/** Details of the file to be uploaded */
|
|
323
|
+
{ fileName, prefix, contentType, isPublic = false, expiresAt, ...data }: UploadUrlProps,
|
|
324
|
+
|
|
325
|
+
/** Additional request options */
|
|
326
|
+
options?: RequestOptions,
|
|
323
327
|
): Promise<UploadUrlResponse> {
|
|
324
|
-
const
|
|
325
|
-
|
|
328
|
+
const fileKey = `${prefix ?? ''}${fileName}`;
|
|
329
|
+
const reqData: GetUploadUrlDataPayload = {
|
|
330
|
+
...data,
|
|
331
|
+
key: fileKey,
|
|
332
|
+
contentType: contentType ?? this.defaultContentType,
|
|
333
|
+
};
|
|
334
|
+
const signal = options?.signal;
|
|
326
335
|
|
|
327
|
-
|
|
336
|
+
const expiresDate = this.normalizeDate(expiresAt);
|
|
337
|
+
if (expiresDate != undefined) {
|
|
338
|
+
reqData.ttl = expiresDate.toISOString();
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return await this.callApiV2<UploadUrlResponse>({
|
|
328
342
|
method: 'post',
|
|
329
343
|
route: 'files/upload-params',
|
|
330
344
|
params: {
|
|
331
345
|
isPublic,
|
|
332
346
|
setDefaultCache: true,
|
|
333
347
|
},
|
|
334
|
-
signal
|
|
348
|
+
signal,
|
|
335
349
|
data: reqData,
|
|
336
350
|
});
|
|
337
351
|
}
|
|
338
352
|
|
|
339
353
|
/**
|
|
340
|
-
* Upload file to
|
|
341
|
-
*
|
|
342
|
-
* @
|
|
343
|
-
* @param fileModel file itself or Buffer
|
|
344
|
-
* @param prefix represent the file parent folder
|
|
345
|
-
* @param isPublic file privacy state
|
|
346
|
-
* @param progress callback with progress event
|
|
347
|
-
* @param rewriteMode if file already exist, should we rewrite it
|
|
348
|
-
* @param ttl timestamp when file should be deleted
|
|
349
|
-
* @param maxFileSize max file size
|
|
350
|
-
* @param abortSignal signal to cancel file upload
|
|
351
|
-
* @param waitTillFileAddedInDb true if you want to make sure file added to DB,
|
|
352
|
-
* for example for instant removing it. Please, use it carefully.
|
|
354
|
+
* Upload the file to File service
|
|
355
|
+
*
|
|
356
|
+
* @returns URL of the uploaded file into Files
|
|
353
357
|
*/
|
|
354
|
-
async
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
358
|
+
public async uploadFileV2(
|
|
359
|
+
{
|
|
360
|
+
fileName,
|
|
361
|
+
prefix,
|
|
362
|
+
fileContent,
|
|
363
|
+
contentType,
|
|
364
|
+
expiresAt,
|
|
365
|
+
isPublic = false,
|
|
366
|
+
rewriteMode,
|
|
367
|
+
maxFileSize,
|
|
368
|
+
knownLength,
|
|
369
|
+
cacheControl = 'no-cache',
|
|
370
|
+
waitTillFileAddedInDb,
|
|
371
|
+
onUploadProgress,
|
|
372
|
+
}: UploadFileProps,
|
|
373
|
+
{
|
|
374
|
+
signal,
|
|
375
|
+
waitForDatabaseUpdateTimeout = 60_000,
|
|
376
|
+
waitForDatabaseUpdatePollInterval = 2_000,
|
|
377
|
+
}: UploadFileOptions = {},
|
|
378
|
+
): Promise<string> {
|
|
379
|
+
const fileKey = `${prefix ?? ''}${fileName}`;
|
|
370
380
|
|
|
371
|
-
const signedUrl = await this.
|
|
381
|
+
const signedUrl = await this.getUploadUrlV2(
|
|
372
382
|
{
|
|
383
|
+
fileName,
|
|
384
|
+
prefix,
|
|
373
385
|
contentType,
|
|
374
|
-
key: fileKey,
|
|
375
386
|
cacheControl,
|
|
376
|
-
rewriteMode
|
|
377
|
-
maxFileSize
|
|
387
|
+
rewriteMode,
|
|
388
|
+
maxFileSize,
|
|
389
|
+
expiresAt,
|
|
390
|
+
isPublic,
|
|
378
391
|
},
|
|
379
|
-
|
|
380
|
-
ttl,
|
|
381
|
-
abortSignal,
|
|
392
|
+
{ signal },
|
|
382
393
|
);
|
|
383
394
|
|
|
384
|
-
await this.uploadToSignedUrl(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
395
|
+
await this.uploadToSignedUrl(
|
|
396
|
+
{
|
|
397
|
+
signedUrl,
|
|
398
|
+
fileContent: this.normalizeFileModel(fileContent),
|
|
399
|
+
fileName,
|
|
400
|
+
cacheControl,
|
|
401
|
+
contentType,
|
|
402
|
+
knownLength,
|
|
403
|
+
onUploadProgress,
|
|
404
|
+
},
|
|
405
|
+
{ signal },
|
|
406
|
+
);
|
|
394
407
|
|
|
395
408
|
if (waitTillFileAddedInDb) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
await new Promise((res, rej) => {
|
|
401
|
-
// it may take some time to copy file on S3, so we check it each "STEP" time
|
|
409
|
+
await new Promise<void>((res, rej) => {
|
|
410
|
+
// it may take some time for database to recognize new file upload, so we check it periodically
|
|
411
|
+
const start = Date.now();
|
|
402
412
|
const interval = setInterval(() => {
|
|
403
413
|
this.getFile(fileKey, isPublic)
|
|
414
|
+
.catch(() => { })
|
|
404
415
|
.then(() => {
|
|
405
|
-
if (
|
|
416
|
+
if (start + waitForDatabaseUpdateTimeout >= Date.now()) rej('Timeout reached');
|
|
406
417
|
clearInterval(interval);
|
|
407
|
-
res(
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
}, STEP);
|
|
418
|
+
res();
|
|
419
|
+
});
|
|
420
|
+
}, waitForDatabaseUpdatePollInterval);
|
|
411
421
|
});
|
|
412
422
|
}
|
|
413
423
|
|
|
414
424
|
return signedUrl.downloadUrl;
|
|
415
425
|
}
|
|
416
426
|
|
|
417
|
-
//
|
|
418
|
-
// ---System files logic---
|
|
419
|
-
//
|
|
427
|
+
// --------------------------
|
|
428
|
+
// --- System files logic ---
|
|
429
|
+
// --------------------------
|
|
420
430
|
|
|
421
431
|
/**
|
|
422
432
|
* Upload system file to S3 bucket, will not affect total size for user storage
|
|
423
|
-
* @param prefix prefix inside the system folder
|
|
424
|
-
* @param file file for uploading
|
|
425
|
-
* @param cacheControl cache settings
|
|
426
|
-
* @param abortSignal signal to cancel uploading
|
|
427
|
-
* @deprecated use `uploadSystemFileV2` instead
|
|
428
433
|
*/
|
|
429
|
-
async
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
+
public async uploadSystemFileV3(
|
|
435
|
+
{
|
|
436
|
+
fileName,
|
|
437
|
+
prefix,
|
|
438
|
+
fileContent,
|
|
439
|
+
contentType,
|
|
440
|
+
cacheControl = 'max-age=3600',
|
|
441
|
+
expiresAt,
|
|
442
|
+
knownLength,
|
|
443
|
+
onUploadProgress,
|
|
444
|
+
}: UploadSystemFileParams,
|
|
445
|
+
options?: RequestOptions,
|
|
434
446
|
): Promise<string> {
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
447
|
+
const signal = options?.signal;
|
|
448
|
+
|
|
449
|
+
const signedUrl = await this.getSystemFileUploadUrl(
|
|
450
|
+
{
|
|
451
|
+
fileName,
|
|
439
452
|
prefix,
|
|
440
453
|
cacheControl,
|
|
441
|
-
|
|
454
|
+
expiresAt,
|
|
442
455
|
},
|
|
443
|
-
signal
|
|
444
|
-
|
|
456
|
+
{ signal },
|
|
457
|
+
);
|
|
445
458
|
|
|
446
|
-
await this.uploadToSignedUrl(
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
459
|
+
await this.uploadToSignedUrl(
|
|
460
|
+
{
|
|
461
|
+
signedUrl,
|
|
462
|
+
fileContent: this.normalizeFileModel(fileContent),
|
|
463
|
+
fileName,
|
|
464
|
+
cacheControl,
|
|
465
|
+
contentType,
|
|
466
|
+
knownLength,
|
|
467
|
+
onUploadProgress,
|
|
468
|
+
},
|
|
469
|
+
{ signal },
|
|
470
|
+
);
|
|
454
471
|
|
|
455
472
|
return signedUrl.downloadUrl;
|
|
456
473
|
}
|
|
457
474
|
|
|
458
|
-
/**
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
* @param ttl timestamp when file should be deleted
|
|
465
|
-
* @param contentType content type of file
|
|
466
|
-
* @param fileName name of file
|
|
467
|
-
*/
|
|
475
|
+
/** Get signed URL params for uploading of system file */
|
|
476
|
+
protected async getSystemFileUploadUrl(
|
|
477
|
+
params: GetSystemFileUploadUrlParams,
|
|
478
|
+
options?: RequestOptions,
|
|
479
|
+
): Promise<UploadUrlResponse> {
|
|
480
|
+
const { fileName, prefix, cacheControl, expiresAt } = params;
|
|
468
481
|
|
|
469
|
-
|
|
470
|
-
prefix,
|
|
471
|
-
file,
|
|
472
|
-
cacheControl = 'max-age=3600',
|
|
473
|
-
ttl,
|
|
474
|
-
fileName,
|
|
475
|
-
contentType,
|
|
476
|
-
knownLength,
|
|
477
|
-
abortSignal,
|
|
478
|
-
}: UploadSystemFileParams): Promise<string> {
|
|
479
|
-
const signedUrl: UploadSystemUrlResponse = await this.callApiV2({
|
|
482
|
+
return await this.callApiV2<UploadUrlResponse>({
|
|
480
483
|
method: 'post',
|
|
481
484
|
route: 'system-file',
|
|
482
485
|
data: {
|
|
483
|
-
prefix,
|
|
484
|
-
cacheControl,
|
|
485
486
|
key: fileName,
|
|
486
|
-
|
|
487
|
+
prefix: prefix ?? '',
|
|
488
|
+
cacheControl,
|
|
489
|
+
ttl: this.normalizeDate(expiresAt)?.getTime(),
|
|
487
490
|
},
|
|
488
|
-
signal:
|
|
491
|
+
signal: options?.signal,
|
|
489
492
|
});
|
|
493
|
+
}
|
|
490
494
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Delete system file
|
|
497
|
+
* @param path file path
|
|
498
|
+
*/
|
|
499
|
+
public async deleteSystemFile(path: string): Promise<void> {
|
|
500
|
+
await this.callApiV2({
|
|
501
|
+
method: 'delete',
|
|
502
|
+
route: 'system-file',
|
|
503
|
+
params: { key: path },
|
|
499
504
|
});
|
|
500
|
-
|
|
501
|
-
return signedUrl.downloadUrl;
|
|
502
505
|
}
|
|
503
506
|
|
|
507
|
+
// -----------------------
|
|
508
|
+
// --- Files TTL logic ---
|
|
509
|
+
// -----------------------
|
|
510
|
+
|
|
504
511
|
/**
|
|
505
512
|
* Set ttl for a specific file or folder
|
|
506
513
|
* @param key file or folder path
|
|
507
|
-
* @param isPublic false for folders, true or false for files
|
|
514
|
+
* @param isPublic `false` for folders, `true` or `false` for files
|
|
508
515
|
* @param ttl number which represents milliseconds
|
|
509
516
|
*/
|
|
510
517
|
async addTtl(key: string, isPublic: boolean, ttl: number): Promise<void> {
|
|
@@ -553,29 +560,17 @@ export class Files extends Base {
|
|
|
553
560
|
});
|
|
554
561
|
}
|
|
555
562
|
|
|
556
|
-
/**
|
|
557
|
-
* Delete system file
|
|
558
|
-
* @param path file path
|
|
559
|
-
*/
|
|
560
|
-
async deleteSystemFile(path: string): Promise<void> {
|
|
561
|
-
await this.callApiV2({
|
|
562
|
-
method: 'delete',
|
|
563
|
-
route: 'system-file',
|
|
564
|
-
params: { key: path },
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
|
|
568
563
|
private async uploadToSignedUrl({
|
|
569
564
|
signedUrl,
|
|
570
|
-
file,
|
|
571
565
|
fileName,
|
|
566
|
+
fileContent,
|
|
572
567
|
cacheControl,
|
|
573
568
|
contentType,
|
|
574
569
|
knownLength,
|
|
575
|
-
signal,
|
|
576
570
|
onUploadProgress,
|
|
577
|
-
}: UploadToSignedUrlParameters) {
|
|
571
|
+
}: UploadToSignedUrlParameters, options?: RequestOptions) {
|
|
578
572
|
const { url, fields } = signedUrl;
|
|
573
|
+
const signal = options?.signal;
|
|
579
574
|
|
|
580
575
|
const FormDataLib = await this.formDataFactory();
|
|
581
576
|
const formData = new FormDataLib();
|
|
@@ -590,16 +585,16 @@ export class Files extends Base {
|
|
|
590
585
|
if (contentType) formData.append('content-type', contentType);
|
|
591
586
|
|
|
592
587
|
if (isNode) {
|
|
593
|
-
(formData as FormDataNode).append('File',
|
|
588
|
+
(formData as FormDataNode).append('File', fileContent, {
|
|
594
589
|
filename: fileName,
|
|
595
590
|
contentType,
|
|
596
591
|
knownLength,
|
|
597
592
|
});
|
|
598
593
|
} else {
|
|
599
|
-
if (!(
|
|
594
|
+
if (!(fileContent instanceof File || fileContent instanceof Blob)) {
|
|
600
595
|
throw new Error('In browser file can only be an instance of File or Blob');
|
|
601
596
|
}
|
|
602
|
-
(formData as FormData).append('File',
|
|
597
|
+
(formData as FormData).append('File', fileContent, fileName);
|
|
603
598
|
}
|
|
604
599
|
|
|
605
600
|
return await axios.post(url, formData, {
|
|
@@ -628,4 +623,160 @@ export class Files extends Base {
|
|
|
628
623
|
? formData.getHeaders()
|
|
629
624
|
: {};
|
|
630
625
|
}
|
|
626
|
+
|
|
627
|
+
private normalizeFileModel(fileContent: ExtendedFileModel): FileModel {
|
|
628
|
+
if (typeof fileContent === 'string') {
|
|
629
|
+
const bytes = new TextEncoder().encode(fileContent);
|
|
630
|
+
return isNode ? Buffer.from(bytes) : new Blob([bytes]);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
return fileContent;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Get Date instance from input that represents date
|
|
638
|
+
*
|
|
639
|
+
* @param input input to normalize
|
|
640
|
+
* @param errorMessage error message to throw if input is invalid date
|
|
641
|
+
* @returns Date instance represented by input
|
|
642
|
+
* @throws If input is invalid date
|
|
643
|
+
*/
|
|
644
|
+
private normalizeDate(input: Timestamp | undefined, errorMessage?: string): Date | undefined {
|
|
645
|
+
if (input == undefined) return undefined;
|
|
646
|
+
|
|
647
|
+
const date = input instanceof Date ? input : new Date(input);
|
|
648
|
+
|
|
649
|
+
if (isNaN(date.getTime())) throw new Error(errorMessage ?? 'Invalid date input');
|
|
650
|
+
|
|
651
|
+
return date;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
private get defaultContentType() {
|
|
655
|
+
return 'binary/octet-stream';
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// --------------------------
|
|
659
|
+
// --- Deprecated methods ---
|
|
660
|
+
// --------------------------
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Upload the file to File service
|
|
664
|
+
*
|
|
665
|
+
* @returns URL of the uploaded file into Files
|
|
666
|
+
* @deprecated Use {@link uploadFileV2} instead
|
|
667
|
+
*/
|
|
668
|
+
public async uploadFile(
|
|
669
|
+
{
|
|
670
|
+
name,
|
|
671
|
+
prefix,
|
|
672
|
+
fileModel,
|
|
673
|
+
type,
|
|
674
|
+
isPublic = false,
|
|
675
|
+
rewriteMode,
|
|
676
|
+
maxFileSize,
|
|
677
|
+
knownLength,
|
|
678
|
+
cacheControl = 'no-cache',
|
|
679
|
+
ttl,
|
|
680
|
+
waitTillFileAddedInDb,
|
|
681
|
+
abortSignal,
|
|
682
|
+
progress,
|
|
683
|
+
}: UploadFilePropsLegacy,
|
|
684
|
+
signal?: AbortSignal,
|
|
685
|
+
): Promise<string> {
|
|
686
|
+
return await this.uploadFileV2(
|
|
687
|
+
{
|
|
688
|
+
fileName: name,
|
|
689
|
+
prefix,
|
|
690
|
+
fileContent: fileModel,
|
|
691
|
+
contentType: type,
|
|
692
|
+
isPublic,
|
|
693
|
+
cacheControl,
|
|
694
|
+
rewriteMode,
|
|
695
|
+
maxFileSize,
|
|
696
|
+
knownLength,
|
|
697
|
+
expiresAt: ttl,
|
|
698
|
+
waitTillFileAddedInDb,
|
|
699
|
+
onUploadProgress: progress,
|
|
700
|
+
},
|
|
701
|
+
{ signal: signal ?? abortSignal },
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Get a link for uploading specific file, JUST FOR INNER USE
|
|
707
|
+
* @returns uploading Url with different header Fields
|
|
708
|
+
* @deprecated Use {@link getUploadUrlV2} instead
|
|
709
|
+
*/
|
|
710
|
+
public async getUploadUrl(
|
|
711
|
+
/** Details of the file to be uploaded */
|
|
712
|
+
params: UploadUrlPropsLegacy,
|
|
713
|
+
isPublic?: boolean,
|
|
714
|
+
ttl?: number,
|
|
715
|
+
abortSignal?: AbortSignal,
|
|
716
|
+
): Promise<UploadUrlResponse> {
|
|
717
|
+
const { key, ...data } = params;
|
|
718
|
+
return await this.getUploadUrlV2(
|
|
719
|
+
{
|
|
720
|
+
...data,
|
|
721
|
+
fileName: key,
|
|
722
|
+
isPublic,
|
|
723
|
+
expiresAt: ttl,
|
|
724
|
+
},
|
|
725
|
+
{ signal: abortSignal },
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Upload system file to S3 bucket, will not affect total size for user storage
|
|
731
|
+
* @param prefix prefix inside the system folder
|
|
732
|
+
* @param file file for uploading
|
|
733
|
+
* @param cacheControl cache settings
|
|
734
|
+
* @param abortSignal signal to cancel uploading
|
|
735
|
+
* @deprecated use {@link uploadSystemFileV3} instead
|
|
736
|
+
*/
|
|
737
|
+
public async uploadSystemFile(
|
|
738
|
+
prefix: string,
|
|
739
|
+
file: File,
|
|
740
|
+
cacheControl = 'max-age=3600',
|
|
741
|
+
abortSignal?: AbortSignal,
|
|
742
|
+
): Promise<string> {
|
|
743
|
+
return await this.uploadSystemFileV3(
|
|
744
|
+
{
|
|
745
|
+
fileName: file.name,
|
|
746
|
+
prefix,
|
|
747
|
+
fileContent: file,
|
|
748
|
+
contentType: file.type,
|
|
749
|
+
cacheControl,
|
|
750
|
+
},
|
|
751
|
+
{ signal: abortSignal },
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Upload system file to S3 bucket, will not affect total size for user storage
|
|
757
|
+
* @deprecated Use {@link uploadSystemFileV3} instead
|
|
758
|
+
*/
|
|
759
|
+
public async uploadSystemFileV2({
|
|
760
|
+
fileName,
|
|
761
|
+
prefix,
|
|
762
|
+
file,
|
|
763
|
+
contentType,
|
|
764
|
+
cacheControl = 'max-age=3600',
|
|
765
|
+
ttl,
|
|
766
|
+
knownLength,
|
|
767
|
+
abortSignal,
|
|
768
|
+
}: UploadSystemFileParamsLegacy): Promise<string> {
|
|
769
|
+
return await this.uploadSystemFileV3(
|
|
770
|
+
{
|
|
771
|
+
fileName,
|
|
772
|
+
prefix,
|
|
773
|
+
fileContent: file,
|
|
774
|
+
contentType,
|
|
775
|
+
cacheControl,
|
|
776
|
+
expiresAt: ttl,
|
|
777
|
+
knownLength,
|
|
778
|
+
},
|
|
779
|
+
{ signal: abortSignal },
|
|
780
|
+
);
|
|
781
|
+
}
|
|
631
782
|
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ExtendedFileModel, UploadFileProps } from '../types';
|
|
2
|
+
|
|
3
|
+
export type UploadSystemFileParams = Pick<
|
|
4
|
+
UploadFileProps,
|
|
5
|
+
| 'fileName'
|
|
6
|
+
| 'prefix'
|
|
7
|
+
| 'contentType'
|
|
8
|
+
| 'cacheControl'
|
|
9
|
+
| 'expiresAt'
|
|
10
|
+
| 'fileContent'
|
|
11
|
+
| 'onUploadProgress'
|
|
12
|
+
| 'knownLength'
|
|
13
|
+
>
|
|
14
|
+
|
|
15
|
+
export type GetSystemFileUploadUrlParams = Pick<
|
|
16
|
+
UploadSystemFileParams,
|
|
17
|
+
'fileName' | 'prefix' | 'cacheControl' | 'expiresAt'
|
|
18
|
+
>
|
|
19
|
+
|
|
20
|
+
// ----- deprecated -----
|
|
21
|
+
|
|
22
|
+
export type UploadSystemFileParamsLegacy = Pick<
|
|
23
|
+
UploadSystemFileParams,
|
|
24
|
+
'fileName' | 'prefix' | 'contentType' | 'cacheControl' | 'knownLength'
|
|
25
|
+
> & {
|
|
26
|
+
file: ExtendedFileModel;
|
|
27
|
+
ttl?: number;
|
|
28
|
+
abortSignal?: AbortSignal;
|
|
29
|
+
}
|
package/src/types/ttl.ts
ADDED