UNPKG

@gecogvidanto/plugin-nedb

Version:

Nebd local database management plugin for ĞecoĞvidanto

177 lines 5.78 kB
"use strict"; /* * This file is part of @gecogvidanto/plugin-nedb. * Copyright (C) 2020 Stéphane Veyret * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); const crypto = require("crypto"); const BinaryStore_1 = require("./BinaryStore"); /** * Test if the value is a litteral object. * * @param value - The value to test. * @returns True if value is object. */ function isLitteral(value) { if (!value || typeof value !== 'object') { return false; } let proto = value; while (Object.getPrototypeOf((proto = Object.getPrototypeOf(proto))) !== null) { // Loop until last prototype found } return Object.getPrototypeOf(value) === proto; } /** * Create a binary data identifier for the given hash. * * @param hash - The hash. * @returns The binary data identifier. */ function createBinaryData(hash) { return { type: '$$BinaryData$$', hash, }; } /** * Calculate the hash for the given data. * * @param data - The data to calculate hash for. * @returns The hash for the binary data. */ function calculateHash(data) { return crypto.createHash('sha256').update(data).digest('hex'); } /** * This class manages the binary data. Binary data are transformed into an object for identification while * the real data is managed by the binary store. */ class BinaryDataManager { /** * Create a binary data manager. * * @param binaryStore - The binary store. * @param storeName - The name of the store creating this manager. */ constructor(binaryStore, storeName) { this.binaryStore = binaryStore; this.storeName = storeName; this.binaries = []; } /** * Filter which should be input for a database calling method to replace binary data. Real binary data * will be ready to be saved. * * @param input - The input to filter. * @returns The filtered input. */ async inputFilter(input) { let filtered; if (input instanceof Buffer) { const hash = calculateHash(input); filtered = createBinaryData(hash); this.binaries.push({ hash, data: input }); } else if (Array.isArray(input)) { filtered = (await Promise.all(input.map(value => this.inputFilter(value)))); } else if (isLitteral(input)) { filtered = {}; for (const key in input) { filtered[key] = (await this.inputFilter(input[key])); } } else { filtered = input; } return filtered; } /** * Filter all which should be output for a database calling method to replace hash with binary data. Data * will first be searched in filtered input data. * * @param outputs - The output to filter. * @returns The filtered output. */ async outputFilterAll(outputs) { const filtered = []; await Promise.all(outputs.map(async (output) => filtered.push(await this.outputFilter(output)))); return filtered; } /** * Filter which should be output for a database calling method to replace hash with binary data. Data will * first be searched in filtered input data. * * @param output - The output to filter. * @returns The filtered output. */ async outputFilter(output) { let filtered; if (BinaryStore_1.isBinaryData(output)) { filtered = (await this.searchData(output.hash)); } else if (Array.isArray(output)) { filtered = (await Promise.all(output.map(value => this.outputFilter(value)))); } else if (isLitteral(output)) { filtered = {}; for (const key in output) { filtered[key] = (await this.outputFilter(output[key])); } } else { filtered = output; } return filtered; } /** * Save the binary data seen while filtering input. * * @param recordId - The identifier of the current record to associate to binary data. */ async save(recordId) { await Promise.all(this.binaries.map(binary => { this.binaryStore.save(this.storeName, recordId, binary.hash, binary.data); })); } /** * Indicate if a given input has been transformed, meaning if binary data need to be (or already have * been) saved. * * @returns True if data need to be saved. */ get transformed() { return this.binaries.length > 0; } /** * Search the binary data with the given hash. * * @param hash - The hash of the binary data to search for. * @returns The binary data for the hash. */ searchData(hash) { const quickFound = this.binaries.find(binary => hash === binary.hash); if (quickFound) { return Promise.resolve(quickFound.data); } else { return this.binaryStore.read(hash); } } } exports.default = BinaryDataManager; //# sourceMappingURL=BinaryDataManager.js.map