@amirmarmul/waba-common
Version:

172 lines (171 loc) • 4.98 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileStore = void 0;
const promises_1 = __importStar(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const crypto_1 = require("crypto");
class Hash {
static make(text) {
return (0, crypto_1.createHash)('sha256').update(text).digest('hex');
}
}
class File {
static async exists(path) {
try {
await promises_1.default.access(path, promises_1.constants.F_OK);
}
catch (error) {
return false;
}
}
static async mkdir(path) {
try {
await promises_1.default.mkdir(path, { recursive: true });
return true;
}
catch (error) {
return false;
}
}
static async read(path) {
try {
const value = await promises_1.default.readFile(path, 'utf-8');
return value ? JSON.parse(value) : null;
}
catch (error) {
return null;
}
}
static async store(path, data) {
try {
const json = JSON.stringify(data);
await promises_1.default.writeFile(path, json, 'utf-8');
return true;
}
catch (error) {
return false;
}
}
static async delete(path) {
try {
await promises_1.default.unlink(path);
return true;
}
catch (error) {
return false;
}
}
static async rm(path) {
try {
await promises_1.default.rm(path, { recursive: true, force: true });
return true;
}
catch (error) {
return false;
}
}
}
class FileStore {
directory;
constructor(directory) {
this.directory = path_1.default.resolve(directory);
}
async get(key) {
return await this.getPayload(key);
}
async put(key, value, ttl) {
const record = { data: value, expire: ttl * 1000 + Date.now() };
try {
const path = this.path(key);
await this.ensureDirectoryExists(path);
await File.store(path, record);
return true;
}
catch (error) {
return false;
}
}
async forever(key, value) {
const record = { data: value };
try {
const path = this.path(key);
await this.ensureDirectoryExists(path);
await File.store(path, record);
return true;
}
catch (error) {
return false;
}
}
async forget(key) {
try {
const path = this.path(key);
await File.delete(path);
return true;
}
catch (error) {
return false;
}
}
async flush() {
try {
await File.rm(this.directory);
return true;
}
catch (error) {
return false;
}
}
getPrefix() {
return '';
}
async getPayload(key) {
const path = this.path(key);
let now = Date.now();
let record = await File.read(path);
const expiration = record?.expire ?? Infinity;
if (!record || expiration < now) {
await this.forget(key);
return null;
}
return record.data;
}
path(key) {
const hash = Hash.make(key);
const parts = hash.match(/.{2}/g).slice(0, 2);
return path_1.default.join(this.directory, ...parts, hash);
}
async ensureDirectoryExists(path) {
const directory = path_1.default.dirname(path);
if (!await File.exists(directory)) {
await File.mkdir(directory);
}
}
}
exports.FileStore = FileStore;