kv-storage
Version:
💾 Create data storage that uses a simple key-value method for Node, Browser, Deno, Bun, Cloudflare Workers
152 lines (151 loc) • 4.87 kB
JavaScript
import fs from 'node:fs';
export class KVStorageModule {
_storageDir;
constructor({ storageDir }) {
this._storageDir = storageDir;
}
isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
showError(msg = 'Error') {
throw new Error(msg);
}
static async init({ dataDirName = "data", storageName }) {
function isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
function showError(msg = 'Error') {
throw new Error(msg);
}
async function makeDir(dir) {
return new Promise((resolve) => {
fs.stat(dir, (err) => {
if (err) {
fs.mkdir(dir, { recursive: true }, (err, path) => {
if (err) {
throw err;
}
else {
resolve(true);
}
});
}
else {
resolve(true);
}
});
});
}
if (!isAlphanumeric(dataDirName))
showError('dataDirName must be Alphanumeric');
if (!isAlphanumeric(storageName))
showError('storageName must be Alphanumeric');
let _dataDirName = "./" + dataDirName;
let storageDir = _dataDirName + '/' + storageName;
await makeDir(storageDir);
return new KVStorageModule({ storageDir });
}
async put(key, value) {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const keyFilePath = this._storageDir + '/' + key;
fs.writeFile(keyFilePath, value, (err) => {
if (err) {
resolve(false);
}
else {
resolve(true);
}
});
});
}
async get(key) {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const keyFilePath = this._storageDir + '/' + key;
fs.readFile(keyFilePath, (err, data) => {
if (err) {
resolve(false);
}
else {
resolve(data.toString('utf8', 0, data.length));
}
});
});
}
async delete(key) {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const keyFilePath = this._storageDir + '/' + key;
fs.unlink(keyFilePath, (err) => {
if (err) {
fs.stat(keyFilePath, (err) => {
if (err) {
resolve(true);
}
else {
resolve(false);
}
});
}
else {
resolve(true);
}
});
});
}
async has(key) {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const keyFilePath = this._storageDir + '/' + key;
fs.stat(keyFilePath, (err) => {
if (err) {
resolve(false);
}
else {
resolve(true);
}
});
});
}
async list() {
return new Promise((resolve) => {
fs.readdir(this._storageDir, (err, files) => {
if (err) {
resolve(false);
}
else {
let result = {
keys: files,
complete: true
};
resolve(result);
}
});
});
}
async clear() {
return new Promise((resolve) => {
fs.readdir(this._storageDir, (err, files) => {
if (err) {
resolve(false);
}
else {
let success = true;
for (const file of files) {
const keyFilePath = this._storageDir + '/' + file;
fs.unlink(keyFilePath, (err) => {
if (err)
success = false;
});
}
resolve(success);
}
});
});
}
}