-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathfiles.ts
More file actions
72 lines (69 loc) · 2.21 KB
/
Copy pathfiles.ts
File metadata and controls
72 lines (69 loc) · 2.21 KB
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
import type { DGSupabaseClient } from "./client";
const ASSETS_BUCKET_NAME = "assets";
export const addFile = async ({
client,
spaceId,
sourceLocalId,
fname,
mimetype,
created,
lastModified,
content,
}: {
client: DGSupabaseClient;
spaceId: number;
sourceLocalId: string;
fname: string;
mimetype: string;
created: Date;
lastModified: Date;
content: ArrayBuffer;
}): Promise<void> => {
// This assumes the content fits in memory.
const uint8Array = new Uint8Array(content);
const hashBuffer = await crypto.subtle.digest("SHA-256", uint8Array);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashvalue = hashArray
.map((h) => h.toString(16).padStart(2, "0"))
.join("");
const lookForDup = await client.rpc("file_exists", { hashvalue });
if (lookForDup.error) throw lookForDup.error;
const exists = lookForDup.data;
if (!exists) {
// we should use upsert here for sync issues, but we get obscure rls errors.
const uploadResult = await client.storage
.from(ASSETS_BUCKET_NAME)
.upload(hashvalue, content, { contentType: mimetype });
if (
uploadResult.error &&
// eslint-disable-next-line @typescript-eslint/no-explicit-any
String((uploadResult.error as Record<string, any>).statusCode) !== "409"
)
throw uploadResult.error;
}
// not doing an upsert because it does not update on conflict
const frefResult = await client.from("FileReference").insert({
space_id: spaceId,
source_local_id: sourceLocalId,
last_modified: lastModified.toISOString(),
filepath: fname,
filehash: hashvalue,
created: created.toISOString(),
});
if (frefResult.error) {
if (frefResult.error.code === "23505") {
// 23505 is duplicate key, which means the file is already there, not an error
const updateResult = await client
.from("FileReference")
.update({
last_modified: lastModified.toISOString(),
filehash: hashvalue,
created: created.toISOString(),
})
.eq("source_local_id", sourceLocalId)
.eq("space_id", spaceId)
.eq("filepath", fname);
if (updateResult.error) throw updateResult.error;
} else throw frefResult.error;
}
};