-
Notifications
You must be signed in to change notification settings - Fork 2
/
files.ts
137 lines (121 loc) · 3.45 KB
/
files.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import { ReadStream } from 'fs';
import {
BaseReq,
DeleteReq,
encodeIfNotEncoded,
getBySuppliedId,
getPage,
} from '../../client/index';
import { CreateFileRequest, FileList, FileMetadataData } from '../../index';
/** Upload file arguments. */
export interface UploadFileReq extends BaseReq {
/** A {@link CreateFileRequest}. */
readonly createFileReq: CreateFileRequest;
/** File data. */
readonly fileData: Buffer | ReadStream;
}
/**
* Delete all files.
*
* @param args - The {@link DeleteReq}.
*/
export async function deleteAllFiles({
client,
pageSize = 100,
exceptions = new Set(),
}: DeleteReq): Promise<FileMetadataData[]> {
let files: FileMetadataData[] = [];
let cursor: string | undefined;
do {
// eslint-disable-next-line no-await-in-loop
const res = await getPage(() =>
client.files.getFiles({ pageCursor: cursor, pageSize })
);
const ids = res.page.data
.map((d) => d.id)
.filter((id) => !exceptions.has(id));
cursor = res.cursor;
// eslint-disable-next-line no-await-in-loop
await Promise.all(ids.map((id) => client.files.deleteFile({ id })));
files = files.concat(res.page.data);
} while (cursor);
return files;
}
/**
* Create a file resource and upload a file if it doesn't already exist.
*
* @param args - The {@link UploadFileReq}.
*/
export async function uploadFileIfNotExists({
client,
createFileReq,
onMsg = console.log,
verbose,
...rest
}: UploadFileReq): Promise<FileMetadataData> {
const suppliedId = createFileReq.data.attributes.suppliedId;
const existingFile = suppliedId
? await getBySuppliedId<FileMetadataData, FileList>(
() =>
client.files.getFiles({
pageSize: 1,
filterSuppliedId: encodeIfNotEncoded(suppliedId),
}),
suppliedId
)
: undefined;
if (existingFile) {
const fileId = existingFile.id;
if (existingFile.attributes.status === 'complete') {
if (verbose) {
onMsg(
`File with suppliedId '${suppliedId}' already exists, using it, ${fileId}`
);
}
return existingFile;
} else {
if (verbose) {
onMsg(
`Deleting file with suppliedId '${suppliedId}' in status ${existingFile.attributes.status}, ${fileId}`
);
}
await client.files.deleteFile({ id: fileId });
}
}
return uploadFile({ client, createFileReq, onMsg, verbose, ...rest });
}
/**
* Create a file resource and upload a file.
*
* @param args - The {@link UploadFileReq}.
*/
export async function uploadFile({
client,
createFileReq,
fileData,
onMsg = console.log,
verbose,
}: UploadFileReq): Promise<FileMetadataData> {
const fileName = createFileReq.data.attributes.name;
const createRes = await client.files.createFile({
createFileRequest: createFileReq,
});
const fileId = createRes.data.data.id;
if (verbose) onMsg(`Created file '${fileName}', ${fileId}`);
const uploadRes = await client.files.uploadFile({
id: fileId,
body: fileData,
});
if (uploadRes.status !== 204) {
throw new Error(
`Uploading file ${fileId} failed with status code ${uploadRes.status}`
);
}
const getRes = (await client.files.getFile({ id: fileId })).data.data;
const status = getRes.attributes.status;
if (status === 'error') {
throw new Error(`Uploading file ${fileId} failed with status ${status}`);
}
if (verbose) onMsg(`Uploaded file ${fileId}, status ${status}`);
return getRes;
}