UNPKG

@heliomarpm/kvs

Version:

A simple and robust KeyValues Storage's library

231 lines (230 loc) 8.43 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsonFileHelper = void 0; const node_fs_1 = __importDefault(require("node:fs")); const node_path_1 = __importDefault(require("node:path")); const write_file_atomic_1 = __importDefault(require("write-file-atomic")); const constants_1 = require("./constants"); /** * This module provides a helper class for managing JSON files in a key-value store. * It includes methods for loading, saving, and ensuring the existence of JSON files and directories. * It is designed to work with a customizable directory and file name for storing key-value pairs. * * @module JsonFileHelper * @author Heliomar Marques * @internal * @ignore */ class JsonFileHelper { /** * Creates an instance of JsonFileHelper. * * @param {@link Options} options - The options for the JsonFileHelper. */ constructor(options) { /** * The options for the JsonFileHelper. * @type {@link Options} * @private */ Object.defineProperty(this, "options", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.options = options; } /** * Returns the path to the keyvalues directory. The path * may be customized by the developer by using * `configure()`. * * @returns The path to the keyvalues directory. */ getJsonDirPath() { var _a; const dir = ((_a = this.options.dir) !== null && _a !== void 0 ? _a : node_path_1.default.resolve(constants_1.DEFAULT_DIR_NAME)).trim(); return dir === "" ? "./" : dir; } /** * Returns the path to the keyvalues file. The file name * may be customized by the developer using `configure()`. * * @returns The path to the keyvalues file. */ getJsonFilePath() { const dir = this.getJsonDirPath(); let fileName = this.options.fileName.trim(); fileName = fileName === "" ? constants_1.DEFAULT_FILE_NAME : fileName; return node_path_1.default.join(dir, fileName); } /** * Ensures that the keyvalues file exists. If it does not * exist, then it is created. * * @returns A promise which resolves when the keyvalues file exists. */ ensureJsonFile() { return __awaiter(this, void 0, void 0, function* () { const filePath = this.getJsonFilePath(); try { yield node_fs_1.default.promises.stat(filePath); } catch (error) { const ex = error; if ((ex === null || ex === void 0 ? void 0 : ex.code) === "ENOENT") { yield this.saveKeyValues({}); } else { throw error; } } }); } /** * Ensures that the keyvalues file exists. If it does not * exist, then it is created. * * @returns {void} */ ensureJsonFileSync() { const filePath = this.getJsonFilePath(); try { node_fs_1.default.statSync(filePath); } catch (error) { const ex = error; if ((ex === null || ex === void 0 ? void 0 : ex.code) === "ENOENT") { this.saveKeyValuesSync({}); } else { throw error; } } } /** * Ensures that the KeyValues directory exists. If it does * not exist, then it is created. * * @returns A promise which resolves when the keyvalues dir exists. */ ensureJsonDir() { return __awaiter(this, void 0, void 0, function* () { const dirPath = this.getJsonDirPath(); try { yield node_fs_1.default.promises.stat(dirPath); } catch (error) { const ex = error; if ((ex === null || ex === void 0 ? void 0 : ex.code) === "ENOENT") { yield node_fs_1.default.promises.mkdir(dirPath, { recursive: true }); } else { throw error; } } }); } /** * Ensures that the KeyValues directory exists synchronously. If it does not exist, * then it is created. * * @returns {void} */ ensureJsonDirSync() { const dirPath = this.getJsonDirPath(); try { node_fs_1.default.statSync(dirPath); } catch (error) { const ex = error; if ((ex === null || ex === void 0 ? void 0 : ex.code) === "ENOENT") { node_fs_1.default.mkdirSync(dirPath, { recursive: true }); } else { throw error; } } } /** * Asynchronously loads key-value pairs from a JSON file. First ensures that the file exists, * then reads the file and parses its contents into a JavaScript object. * * @template T - The type of the key-value pairs. * @return {Promise<T>} A promise that resolves with the key-value pairs. */ loadKeyValues() { return __awaiter(this, void 0, void 0, function* () { yield this.ensureJsonFile(); const filePath = this.getJsonFilePath(); const data = yield node_fs_1.default.promises.readFile(filePath, "utf-8"); // fs.promises.readFile com 'utf-8' sempre retorna uma string, então a verificação de array é desnecessária. const jsonData = data || "{}"; return JSON.parse(jsonData); }); } /** * Loads the key-value pairs synchronously from the JSON file. * * @template T - The type of the key-value pairs. * @returns {T} - The loaded key-value pairs. */ loadKeyValuesSync() { this.ensureJsonFileSync(); const filePath = this.getJsonFilePath(); const data = node_fs_1.default.readFileSync(filePath, "utf-8"); return JSON.parse(data.length ? data : "{}"); } /** * Saves the keyvalues to the disk. * * @param {T} obj - The keyvalues object to save. * @return {Promise<void>} A promise that resolves when the keyvalues have been saved. */ saveKeyValues(obj) { return __awaiter(this, void 0, void 0, function* () { const filePath = this.getJsonFilePath(); const numSpaces = this.options.prettify ? this.options.numSpaces : 0; const content = JSON.stringify(obj, null, numSpaces); yield this.ensureJsonDir(); if (this.options.atomicSave) { yield (0, write_file_atomic_1.default)(filePath, content); } else { yield node_fs_1.default.promises.writeFile(filePath, content); } }); } /** * Saves the keyvalues to the disk synchronously. * * @param {T} obj - The keyvalues object to save. * @return {void} This function does not return anything. */ saveKeyValuesSync(obj) { const filePath = this.getJsonFilePath(); const numSpaces = this.options.prettify ? this.options.numSpaces : 0; const data = JSON.stringify(obj, null, numSpaces); this.ensureJsonDirSync(); if (this.options.atomicSave) { write_file_atomic_1.default.sync(filePath, data); } else { node_fs_1.default.writeFileSync(filePath, data); } } } exports.JsonFileHelper = JsonFileHelper;