@sap-ux/store
Version:
NPM module for storing persistent data
105 lines • 4.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHybridStore = getHybridStore;
const filesystem_1 = require("./filesystem");
const utils_1 = require("../utils");
const secure_store_1 = require("../secure-store");
const decorators_1 = require("../decorators");
const util_1 = require("util");
function getFullyQualifiedServiceName(name) {
return 'fiori/v2/' + name;
}
class HybridStore {
logger;
filesystem;
secureStore;
constructor(logger, options = {}) {
this.logger = logger;
this.filesystem = (0, filesystem_1.getFilesystemStore)(this.logger, options);
this.secureStore = (0, secure_store_1.getSecureStore)(this.logger);
}
async read({ entityName, id }) {
const serialized = await this.filesystem.read({ entityName, id });
if (!serialized) {
this.logger.debug(`hybrid/read - id: [${id}], nothing on the filesystem`);
}
else {
this.logger.debug(`hybrid/read - id: [${id}], filesystem: ${(0, util_1.inspect)(serialized)}`);
}
const sensitiveData = await this.secureStore.retrieve(getFullyQualifiedServiceName(entityName), id);
if (!sensitiveData) {
this.logger.debug(`hybrid/read - id: [${id}], nothing in the secure store`);
}
else {
this.logger.debug(`hybrid/read - id: [${id}]. Found sensitive data in secure store`);
}
if (serialized || sensitiveData) {
// Make sure sensitive props override serialized ones
return { ...serialized, ...sensitiveData };
}
else {
return undefined;
}
}
async getAll({ entityName }) {
return Object.values(await this.readAll({ entityName }));
}
async readAll({ entityName }) {
const result = {};
const entitiesFs = (await this.filesystem.readAll({ entityName })) || {};
const entitiesInSecureStore = (await this.secureStore.getAll(getFullyQualifiedServiceName(entityName))) || {};
for (const key of new Set([...Object.keys(entitiesFs), ...Object.keys(entitiesInSecureStore)])) {
// Make sure sensitive props override serialized ones
const entity = { ...entitiesFs[key], ...entitiesInSecureStore[key] };
result[key] = entity;
}
return result;
}
async write({ entityName, id, entity }) {
const serializableProps = (0, decorators_1.getSerializableProperties)(entity);
const sensitiveProps = (0, decorators_1.getSensitiveDataProperties)(entity);
if (serializableProps.length > 0 && sensitiveProps.length > 0) {
for (let i = 0; i < serializableProps.length; i = i + 1) {
if (sensitiveProps.indexOf(serializableProps[i]) !== -1) {
this.logger.debug(`hybrid/write - [${String(serializableProps[i])}] is also marked as sensitive. Not writing to filesystem`);
serializableProps.splice(i, 1);
}
}
}
const serializable = (0, utils_1.pick)(entity, ...serializableProps);
if (serializable) {
this.logger.debug(`hybrid/write - writing serializable properties: ${(0, util_1.inspect)(serializable)}`);
await this.filesystem.write({ entityName, id, entity: serializable });
}
else {
this.logger.debug(`hybrid/write - no serializable properties found in ${(0, util_1.inspect)(serializable)}`);
}
const sensitiveData = (0, utils_1.pick)(entity, ...sensitiveProps);
if (sensitiveData) {
this.logger.debug(`hybrid/write - writing sensitive properties to secure store. ID: [${id}]`);
await this.secureStore.save(getFullyQualifiedServiceName(entityName), id, sensitiveData);
}
else {
this.logger.debug(`hybrid/write - no sensitive properties found in ${(0, util_1.inspect)(entity)}`);
}
return entity;
}
async del({ entityName, id }) {
const deletedinFs = await this.filesystem.del({ entityName, id });
this.logger.debug(`hybrid/del - delete result for id [${id}] on the filesystem: ${deletedinFs}`);
const deletedInSecureStore = await this.secureStore.delete(getFullyQualifiedServiceName(entityName), id);
this.logger.debug(`hybrid/del - delete result for id [${id}] in the secure store: ${deletedInSecureStore}`);
return deletedinFs || deletedInSecureStore;
}
}
/** A hybrid store
* Stores serializable properties on the filesystem
* The properties need to be decorated with `@serilizable` annotations
*
* Sensitive properties (decorated with `@sensitiveData`) will be stored
* in the system's secure store
*/
function getHybridStore(logger, options) {
return new HybridStore(logger, options);
}
//# sourceMappingURL=hybrid.js.map