file-store.js
1.15 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
/**
* 交付文件的内容存储:本地磁盘目录,一个文件一个对象,文件名就是平台生成的 file_id。
* ponytail: 单机磁盘,多实例或换机器会丢;上 stage / 生产前换成对象存储(S3 / OSS)实现同样的 put / get。
*/
import { mkdir, readFile, writeFile } from 'node:fs/promises'
import path from 'node:path'
const FILE_ID = /^f_[0-9a-f-]{36}$/
/**
* @param {{ dir: string }} opts
*/
export function createFileStore({ dir }) {
/** @param {string} file_id */
function pathOf(file_id) {
// file_id 由平台生成;这里再校验一次,保证任何输入都拼不出目录外的路径。
if (!FILE_ID.test(file_id)) throw new Error(`file store: invalid file id: ${file_id}`)
return path.join(dir, file_id)
}
return {
/**
* @param {string} file_id
* @param {Buffer} body
*/
async put(file_id, body) {
await mkdir(dir, { recursive: true })
await writeFile(pathOf(file_id), body, { flag: 'wx' })
},
/**
* @param {string} file_id
* @returns {Promise<Buffer>}
*/
async get(file_id) {
return readFile(pathOf(file_id))
},
}
}