-
Notifications
You must be signed in to change notification settings - Fork 52
/
utils.ts
56 lines (47 loc) · 1.78 KB
/
utils.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
import { readFile } from 'node:fs/promises'
import path from 'node:path'
import { fdir } from 'fdir'
const METADATA_PREFIX = '$'
const METADATA_SUFFIX = '.json'
/** Given output directory, find all file paths to upload excluding metadata files */
export async function getKeysToUpload(blobsDir: string): Promise<string[]> {
const files = await new fdir()
.withRelativePaths() // we want the relative path from the blobsDir
.filter((fpath) => !path.basename(fpath).startsWith(METADATA_PREFIX))
.crawl(blobsDir)
.withPromise()
// normalize the path separators to all use the forward slash
return files.map((f) => f.split(path.sep).join('/'))
}
/** Read a file and its metadata file from the blobs directory */
export async function getFileWithMetadata(
blobsDir: string,
key: string,
): Promise<{ data: Buffer; metadata: Record<string, string> }> {
const contentPath = path.join(blobsDir, key)
const dirname = path.dirname(key)
const basename = path.basename(key)
const metadataPath = path.join(blobsDir, dirname, `${METADATA_PREFIX}${basename}${METADATA_SUFFIX}`)
const [data, metadata] = await Promise.all([readFile(contentPath), readMetadata(metadataPath)]).catch((err) => {
throw new Error(`Failed while reading '${key}' and its metadata: ${err.message}`)
})
return { data, metadata }
}
async function readMetadata(metadataPath: string): Promise<Record<string, string>> {
let metadataFile
try {
metadataFile = await readFile(metadataPath, { encoding: 'utf8' })
} catch (err) {
if (err.code === 'ENOENT') {
// no metadata file found, that's ok
return {}
}
throw err
}
try {
return JSON.parse(metadataFile)
} catch {
// Normalize the error message
throw new Error(`Error parsing metadata file '${metadataPath}'`)
}
}