@webdisrupt/persona
Version:
Store local data in a secure data vault.
409 lines • 22.4 kB
JavaScript
"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