fenghuo/packages/tus/src/utils/kvstores/FileKvStore.ts

94 lines
2.6 KiB
TypeScript
Raw Normal View History

2025-05-27 16:56:50 +08:00
import fs from 'node:fs/promises'
import path from 'node:path'
import type {KvStore} from './Types'
import type {Upload} from '../models'
/**
* FileKvStore
*
* @description
* @remarks
* - JSON元数据存储在磁盘上
* - 使
*
* @typeparam T Upload类型
*/
export class FileKvStore<T = Upload> implements KvStore<T> {
/** 存储目录路径 */
directory: string
/**
*
*
* @param path
*/
constructor(path: string) {
this.directory = path
}
/**
*
*
* @param key
* @returns undefined
*/
async get(key: string): Promise<T | undefined> {
try {
// 读取对应键的JSON文件
const buffer = await fs.readFile(this.resolve(key), 'utf8')
// 解析JSON并返回
return JSON.parse(buffer as string)
} catch {
// 文件不存在或读取失败时返回undefined
return undefined
}
}
/**
*
* @param key
* @param value
*/
async set(key: string, value: T): Promise<void> {
// 将值转换为JSON并写入文件
await fs.writeFile(this.resolve(key), JSON.stringify(value))
}
/**
*
*
* @param key
*/
async delete(key: string): Promise<void> {
// 删除对应的JSON文件
await fs.rm(this.resolve(key))
}
/**
*
*
* @returns
*/
async list(): Promise<Array<string>> {
// 读取目录中的所有文件
const files = await fs.readdir(this.directory)
// 对文件名进行排序
const sorted = files.sort((a, b) => a.localeCompare(b))
// 提取文件名(不包含扩展名)
const name = (file: string) => path.basename(file, '.json')
// 过滤出有效的tus文件ID
// 仅保留成对出现的文件(文件名相同,一个有.json扩展名
return sorted.filter(
(file, idx) => idx < sorted.length - 1 && name(file) === name(sorted[idx + 1])
)
}
/**
*
*
* @param key
* @returns
* @private
*/
private resolve(key: string): string {
// 将键名转换为完整的JSON文件路径
return path.resolve(this.directory, `${key}.json`)
}
}