UNPKG

@webdisrupt/persona

Version:

Store local data in a secure data vault.

409 lines 22.4 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); 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 __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; exports.__esModule = true; exports.StorageBlockDirectory = void 0; var generic_1 = require("../helpers/generic"); var config_1 = require("../config"); var response_1 = require("../helpers/response"); var storage_block_core_1 = require("../core/storage-block-core"); var recursive = require("recursive-readdir"); var fs = require("fs"); var StorageBlockDirectory = /** @class */ (function (_super) { __extends(StorageBlockDirectory, _super); /** * Constructor - Used to assign personaOptions. * @param options */ function StorageBlockDirectory(options) { if (options === void 0) { options = null; } var _this = _super.call(this, options) || this; _this.progressTracker = []; return _this; } /** * Save the entire file structure inside a directory to a storage block. Does not save empty directories * @param directoryPath - Directory you would like to save * @param storageBlockName */ StorageBlockDirectory.prototype.save = function (directoryPath, storageBlockName, clearDirectory) { var _a; if (clearDirectory === void 0) { clearDirectory = false; } return __awaiter(this, void 0, void 0, function () { var previousVersion, newVersion, fileDirectory, directoryContent, percentageTotal, percentagePart, index, name_1, content, _b, response; var _this = this; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.load(storageBlockName)]; case 1: previousVersion = ((_a = (_c.sent()).data) === null || _a === void 0 ? void 0 : _a.version) || 0; newVersion = (previousVersion + 1); this.setProgress(storageBlockName); return [4 /*yield*/, recursive(directoryPath)]; case 2: fileDirectory = _c.sent(); directoryContent = []; percentageTotal = 0; percentagePart = (100 / fileDirectory.length); index = 0; _c.label = 3; case 3: if (!(index < fileDirectory.length)) return [3 /*break*/, 8]; _c.label = 4; case 4: _c.trys.push([4, 6, , 7]); name_1 = fileDirectory[index].substr(fileDirectory[index].lastIndexOf("\\")); return [4 /*yield*/, generic_1.generic.fileLoad(fileDirectory[index]).then(function (contents) { percentageTotal += percentagePart; _this.setProgress(storageBlockName, Math.round(percentageTotal)); return contents; })]; case 5: content = _c.sent(); directoryContent.push({ path: fileDirectory[index].replace(name_1, ''), name: name_1.substr(("\\").length), content: content.toString() }); return [3 /*break*/, 7]; case 6: _b = _c.sent(); percentageTotal += percentagePart; this.setProgress(storageBlockName, Math.round(percentageTotal)); return [3 /*break*/, 7]; case 7: index++; return [3 /*break*/, 3]; case 8: this.setProgress(storageBlockName, 100); return [4 /*yield*/, _super.prototype.save.call(this, storageBlockName, { type: "dir", version: newVersion, path: directoryPath, files: directoryContent })]; case 9: response = _c.sent(); if (!response.status) return [3 /*break*/, 11]; return [4 /*yield*/, this.setVersion(storageBlockName, newVersion, 'both')]; case 10: _c.sent(); _c.label = 11; case 11: if (!clearDirectory) return [3 /*break*/, 13]; return [4 /*yield*/, this.removeDirectory(storageBlockName)]; case 12: _c.sent(); _c.label = 13; case 13: return [2 /*return*/, response]; } }); }); }; /** * Create a new directory baed on a storage block * @param storageBlockName - Unique Storage block * @param newLocation - (optional) Used for moving files to a new location. */ StorageBlockDirectory.prototype.load = function (storageBlockName, newLocation) { if (newLocation === void 0) { newLocation = null; } return __awaiter(this, void 0, void 0, function () { var fileVersion, systemTrackedFileVersion, fileDirectory, files, thisPath, percentageTotal_1, percentagePart_1, index, _a; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 15, , 16]); this.setProgress(storageBlockName); return [4 /*yield*/, this.getVersion(storageBlockName, 'file')]; case 1: fileVersion = _b.sent(); return [4 /*yield*/, this.getVersion(storageBlockName, 'cache')]; case 2: systemTrackedFileVersion = _b.sent(); if (!(systemTrackedFileVersion > fileVersion)) return [3 /*break*/, 13]; return [4 /*yield*/, _super.prototype.load.call(this, storageBlockName)]; case 3: fileDirectory = _b.sent(); fileDirectory.data = JSON.parse(fileDirectory.data); files = fileDirectory.data.files; thisPath = newLocation !== null ? newLocation : fileDirectory.data.path; if (!fileDirectory.status) return [3 /*break*/, 11]; if (!(Number(fileDirectory.data.version) > fileVersion)) return [3 /*break*/, 9]; percentageTotal_1 = 0; percentagePart_1 = (100 / files.length); index = 0; _b.label = 4; case 4: if (!(index < files.length)) return [3 /*break*/, 7]; return [4 /*yield*/, generic_1.generic.fileUpdate(files[index].path.replace(fileDirectory.data.path, thisPath), files[index].name, files[index].content).then(function () { percentageTotal_1 += percentagePart_1; _this.setProgress(storageBlockName, Math.round(percentageTotal_1)); })]; case 5: _b.sent(); _b.label = 6; case 6: index++; return [3 /*break*/, 4]; case 7: this.setProgress(storageBlockName, 100); return [4 /*yield*/, this.setVersion(storageBlockName, Number(fileDirectory.data.version), 'both')]; case 8: _b.sent(); return [2 /*return*/, response_1.response.success("Directory ".concat(thisPath, " successfully loaded from storage block."))]; case 9: this.setProgress(storageBlockName, 100); return [2 /*return*/, response_1.response.failed("Loaded version is greater, so we will not load the stored ".concat(storageBlockName, "."))]; case 10: return [3 /*break*/, 12]; case 11: return [2 /*return*/, response_1.response.failed("Data storage block called ".concat(storageBlockName, " was found."))]; case 12: return [3 /*break*/, 14]; case 13: this.setProgress(storageBlockName, 100); return [2 /*return*/, response_1.response.failed("Loaded version is greater, so we will not load the stored ".concat(storageBlockName, "."))]; case 14: return [3 /*break*/, 16]; case 15: _a = _b.sent(); return [2 /*return*/, response_1.response.failed("Data storage block ".concat(storageBlockName, " failed to load."))]; case 16: return [2 /*return*/]; } }); }); }; /** * Sets the directory loading progress based on storage block name. * @param storageBlockName - Unique Storage block */ StorageBlockDirectory.prototype.setProgress = function (storageBlockName, progress) { if (progress === void 0) { progress = 0; } var currentIndex = this.progressTracker.findIndex(function (elem) { return (elem === null || elem === void 0 ? void 0 : elem.name) === storageBlockName; }); if (currentIndex === -1) { this.progressTracker.push({ name: storageBlockName, progress: progress }); } else { this.progressTracker[currentIndex].progress = progress; } }; /** * Gets current loading progress based on the provided storage block name. * @param storageBlockName - Unique Storage block * @returns percentage out of 100 that the directory has been loaded */ StorageBlockDirectory.prototype.getProgress = function (storageBlockName) { try { var currentIndex = this.progressTracker.findIndex(function (elem) { return (elem === null || elem === void 0 ? void 0 : elem.name) === storageBlockName; }); return currentIndex === -1 ? 0 : Math.round(Number(this.progressTracker[currentIndex].progress)); } catch (_a) { return 0; } }; /** * Get storage block path based on storage block id * @param storageBlockName * @returns */ StorageBlockDirectory.prototype.getDirectoryPath = function (storageBlockName) { return __awaiter(this, void 0, void 0, function () { var _a, _b, _c, _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: _g.trys.push([0, 2, , 3]); _b = (_a = response_1.response).success; _c = ["The ".concat(storageBlockName, " path was return successfully.")]; _e = (_d = JSON).parse; return [4 /*yield*/, _super.prototype.load.call(this, storageBlockName)]; case 1: return [2 /*return*/, _b.apply(_a, _c.concat([_e.apply(_d, [(_g.sent()).data]).path]))]; case 2: _f = _g.sent(); return [2 /*return*/, response_1.response.failed("The ".concat(storageBlockName, " storage block doesn't exist."))]; case 3: return [2 /*return*/]; } }); }); }; /** * Storage Block Directory - Get version from the pstore.version file inside the directory * @param storageBlockName - Storage block that * @param source - Which location are you checking [file, cache] * @return New version */ StorageBlockDirectory.prototype.getVersion = function (storageBlockName, source) { if (source === void 0) { source = 'file'; } return __awaiter(this, void 0, void 0, function () { var thisPath, _a, _b, version; return __generator(this, function (_c) { switch (_c.label) { case 0: if (!(source === 'file')) return [3 /*break*/, 6]; return [4 /*yield*/, this.getDirectoryPath(storageBlockName)]; case 1: thisPath = (_c.sent()).data; return [4 /*yield*/, fs.existsSync(thisPath + "\\" + config_1.defaults.versionName)]; case 2: if (!(_c.sent())) return [3 /*break*/, 4]; _b = Number; return [4 /*yield*/, generic_1.generic.fileLoad(thisPath + "\\" + config_1.defaults.versionName)]; case 3: _a = _b.apply(void 0, [_c.sent()]); return [3 /*break*/, 5]; case 4: _a = 0; _c.label = 5; case 5: return [2 /*return*/, _a]; case 6: if (!(source === 'cache')) return [3 /*break*/, 8]; return [4 /*yield*/, _super.prototype.getCache.call(this, "".concat(storageBlockName, ":storageDirectoryVersion"))]; case 7: version = _c.sent(); return [2 /*return*/, version ? Number(version.value) : 0]; case 8: return [2 /*return*/]; } }); }); }; /** * Storage Block not having * @param storageBlockName - Storage block that * @param version - Set a new version, if empty increment by 1 * @param source - Which location are you checking [file, cache, both] * @return New version */ StorageBlockDirectory.prototype.setVersion = function (storageBlockName, version, source) { if (version === void 0) { version = null; } if (source === void 0) { source = 'file'; } return __awaiter(this, void 0, void 0, function () { var thisPath, previousVersion, _a, _b, newVersion; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.getDirectoryPath(storageBlockName)]; case 1: thisPath = (_c.sent()).data; previousVersion = 0; _c.label = 2; case 2: _c.trys.push([2, 4, , 5]); _a = Number; return [4 /*yield*/, generic_1.generic.fileLoad(thisPath + "\\" + config_1.defaults.versionName)]; case 3: previousVersion = _a.apply(void 0, [_c.sent()]); return [3 /*break*/, 5]; case 4: _b = _c.sent(); return [3 /*break*/, 5]; case 5: newVersion = version === null ? (previousVersion + 1).toString() : version.toString(); if (!(source === 'file' || source === 'both')) return [3 /*break*/, 7]; return [4 /*yield*/, generic_1.generic.fileUpdate(thisPath, config_1.defaults.versionName, newVersion)]; case 6: _c.sent(); _c.label = 7; case 7: if (!(source === 'cache' || source === 'both')) return [3 /*break*/, 9]; return [4 /*yield*/, _super.prototype.setCache.call(this, "".concat(storageBlockName, ":storageDirectoryVersion"), newVersion)]; case 8: _c.sent(); _c.label = 9; case 9: return [2 /*return*/, Number(newVersion)]; } }); }); }; /** * Removes a directory and all files inside that directory based on storage block name. * @param storageBlockName - Name of the storage block */ StorageBlockDirectory.prototype.removeDirectory = function (storageBlockName) { return __awaiter(this, void 0, void 0, function () { var _a, _b, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: _d.trys.push([0, 2, , 3]); _b = (_a = fs).rmSync; return [4 /*yield*/, this.getDirectoryPath(storageBlockName)]; case 1: _b.apply(_a, [(_d.sent()).data, { recursive: true }]); return [2 /*return*/, response_1.response.success("The storage block directory was deleted successfully.")]; case 2: _c = _d.sent(); return [2 /*return*/, response_1.response.failed("The storage block directory failed to be deleted.")]; case 3: return [2 /*return*/]; } }); }); }; /** * Checks if a directory exists based on the provided storage block name. * @param storageBlockName - Name of the storage block */ StorageBlockDirectory.prototype.checkDirectory = function (storageBlockName) { return __awaiter(this, void 0, void 0, function () { var _a, _b, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: _d.trys.push([0, 2, , 3]); _b = (_a = fs).existsSync; return [4 /*yield*/, this.getDirectoryPath(storageBlockName)]; case 1: if (_b.apply(_a, [(_d.sent()).data])) { return [2 /*return*/, response_1.response.success("The storage block folder exists.")]; } else { return [2 /*return*/, response_1.response.failed("The storage block folder does not exist.")]; } return [3 /*break*/, 3]; case 2: _c = _d.sent(); return [2 /*return*/, response_1.response.failed("Failed to load corrupted storage block or you don't have the right access permissions")]; case 3: return [2 /*return*/]; } }); }); }; return StorageBlockDirectory; }(storage_block_core_1.BaseStorageBlock)); exports.StorageBlockDirectory = StorageBlockDirectory; //# sourceMappingURL=storage-block-directory.js.map