83 lines
2.1 KiB
TypeScript
83 lines
2.1 KiB
TypeScript
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<string | null> {
|
|
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<void> {
|
|
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();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|