import { KeyValueStorage } from "./basic"; /** * Key-value store, using local file-system */ export class NodeDirectoryStorage implements KeyValueStorage { readonly directory: string private checked = false constructor(appname: string) { if (typeof require === "undefined") { throw new Error("Storage only available in nodejs"); } const path = require("path"); this.directory = path.join(NodeDirectoryStorage.findUserData(), "tk-storage", appname); } /** * Find the writable user data directory */ static findUserData(): string { const result = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Preferences' : process.env.HOME + "/.local/share"); if (!result) { throw new Error("Cannot locate user data directory"); } return result; } /** * Get the file path for a key */ getPath(key: string): string { const path = require("path"); return path.join(this.directory, key); } async get(key: string): Promise { const fs = require("fs"); return new Promise((resolve, reject) => { fs.readFile(this.getPath(key), { encoding: 'utf8' }, (err: any, data: string) => { resolve(err ? null : data); }); }); } async set(key: string, value: string | null): Promise { const fs = require("fs"); if (!this.checked) { await new Promise((resolve, reject) => { fs.mkdir(this.directory, { recursive: true }, (err: any) => { if (err && err.code !== 'EEXIST') { reject(err); } else { resolve(); } }); }); this.checked = true; } return new Promise((resolve, reject) => { if (value === null) { fs.unlink(this.getPath(key), (err: any) => { if (err) { reject(err); } else { resolve(); } }); } else { fs.writeFile(this.getPath(key), value, { encoding: 'utf8' }, (err: any) => { if (err) { reject(err); } else { resolve(); } }); } }); } }