Files
botpress--botpress/packages/cli/src/utils/cache-utils.ts
T
2026-07-13 13:34:48 +08:00

85 lines
2.4 KiB
TypeScript

import fs from 'fs'
import pathlib from 'path'
import * as json from './json-utils'
export class FSKeyValueCache<T extends Object> {
private _initialized = false
public constructor(private _filepath: string) {}
public async init(): Promise<void> {
if (this._initialized) {
return
}
const dirname = pathlib.dirname(this._filepath)
if (!fs.existsSync(dirname)) {
await fs.promises.mkdir(dirname, { recursive: true })
}
if (!fs.existsSync(this._filepath)) {
await this._writeJSON(this._filepath, {})
}
this._initialized = true
}
public async sync<K extends keyof T>(
key: K,
value: T[K] | undefined,
prompt: (initial?: T[K]) => Promise<T[K]>
): Promise<T[K]> {
await this.init()
if (value) {
await this.set(key, value)
return value
}
const data = await this.get(key)
const newValue = await prompt(data)
await this.set(key, newValue)
return newValue
}
public async has<K extends keyof T>(key: K): Promise<boolean> {
await this.init()
const data = await this._readJSON(this._filepath)
return data[key] !== undefined
}
public async get<K extends keyof T>(key: K): Promise<T[K] | undefined> {
await this.init()
const data: T = await this._readJSON(this._filepath)
return data[key]
}
public async set<K extends keyof T>(key: K, value: T[K]): Promise<void> {
await this.init()
const data: T = await this._readJSON(this._filepath)
data[key] = value
return this._writeJSON(this._filepath, data)
}
public async rm<K extends keyof T>(key: K): Promise<void> {
await this.init()
const data: T = await this._readJSON(this._filepath)
delete data[key]
return this._writeJSON(this._filepath, data)
}
public async clear(): Promise<void> {
await this.init()
return this._writeJSON(this._filepath, {})
}
private _writeJSON = (filepath: string, data: any) => {
const fileContent = JSON.stringify(data, null, 2)
return fs.promises.writeFile(filepath, fileContent)
}
private _readJSON = async (filepath: string) => {
const fileContent = await fs.promises.readFile(filepath, 'utf8')
const parseResult = json.safeParseJson(fileContent)
if (!parseResult.success) {
throw new Error(`Failed to parse JSON file at ${filepath}: ${parseResult.error.message}`)
}
return parseResult.data as T
}
}