UNPKG

@batolye/bdk-core

Version:

Module to provide core utilities for BulusAtolyesi applications and services

175 lines (137 loc) 5.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.populateAttachmentResource = populateAttachmentResource; exports.unpopulateAttachmentResource = unpopulateAttachmentResource; exports.attachToResource = attachToResource; exports.detachFromResource = detachFromResource; exports.removeAttachments = removeAttachments; var _lodash = _interopRequireDefault(require("lodash")); var _hooks = require("./hooks.query"); var _debug = _interopRequireDefault(require("debug")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const debug = (0, _debug.default)("batolye:bdk-core:storage:hooks"); function isAttachmentEqual(file1, file2) { return file1._id === file2._id; } function populateAttachmentResource(hook) { if (hook.type !== "before") { throw new Error(`The 'populateStorageResource' hook should only be used as a 'before' hook.`); } // Avoid populating any target resource when resource parameters are not present return (0, _hooks.populateObject)({ serviceField: "resourcesService", idField: "resource", throwOnNotFound: false })(hook); } function unpopulateAttachmentResource(hook) { if (hook.type !== "after") { throw new Error(`The 'unpopulateAttachmentResource' hook should only be used as a 'after' hook.`); } return (0, _hooks.unpopulateObject)({ serviceField: "resourcesService", idField: "resource" })(hook); } async function attachToResource(hook) { if (hook.type !== "after") { throw new Error(`The 'attachToResource' hook should only be used as a 'after' hook.`); } const data = hook.data; const params = hook.params; const query = params.query; const file = hook.result; const attachmentField = _lodash.default.get(data, "field") || _lodash.default.get(query, "field") || "attachments"; // By default attachments are stored in an array let isArray = _lodash.default.get(data, "isArray") || _lodash.default.get(query, "isArray") || true; // Take care that because file uploads might be submitted by external multipart form data middlewares // all parameters types might be string if (typeof isArray !== "boolean") { isArray = isArray === "true"; } const zone = hook.service.zone; const resourcesService = params.resourcesService; let resource = params.resource; let attachments = _lodash.default.get(resource, attachmentField); let attachment = Object.assign({ _id: file._id }, _lodash.default.omit(file, ["uri"])); // Add zone because attachments might come from different ones on the same target object if (zone) { attachment.zone = typeof zone === "object" ? zone._id : zone; } if (isArray) { // Initialize on first attachment if (!attachments) attachments = []; attachments.push(attachment); } else { attachments = attachment; } await resourcesService.patch(resource._id.toString(), { [attachmentField]: attachments }, { user: params.user, // Forward query so that any update param could be processed as usual on resource // Delete own parameters from query otherwise it will be used to filter items query: _lodash.default.omit(query, ["resource", "resourcesService"]) }); debug("Attached file on resource " + resource._id.toString(), attachment); return hook; } async function detachFromResource(hook) { if (hook.type !== "after") { throw new Error(`The 'detachFromResource' hook should only be used as a 'after' hook.`); } const params = hook.params; const query = params.query; let file = hook.result; const attachmentField = _lodash.default.get(query, "field") || "attachments"; const resourcesService = params.resourcesService; let resource = params.resource; let attachments = _lodash.default.get(resource, attachmentField); let attachment; // List of attachments if (Array.isArray(attachments)) { const attachmentIndex = _lodash.default.findIndex(attachments, attachment => isAttachmentEqual(attachment, file)); if (attachmentIndex >= 0) { // Keep track of it for logging attachment = attachments[attachmentIndex]; _lodash.default.pullAt(attachments, attachmentIndex); } } else { // Single attachment object attachment = attachments; attachments = null; } await resourcesService.patch(resource._id.toString(), { [attachmentField]: attachments }, { user: params.user, // Forward query so that any update param could be processed as usual on resource // Delete own parameters from query otherwise it will be used to filter items query: _lodash.default.omit(query, ["resource", "resourcesService"]) }); debug("Detached file on resource " + resource._id.toString(), attachment); return hook; } function removeAttachments(attachmentField) { return async function (hook) { const zone = hook.service.zone; let storageService = hook.app.core_getService("storage", zone); if (!storageService) return Promise.reject(new Error("No valid zone found to retrieve storage service for initiator service " + hook.service.core_name)); let resource = hook.result; let attachments = _lodash.default.get(resource, attachmentField); // Process with each attachment if (attachments) { debug("Removing attachments for resource " + resource._id.toString(), attachments); if (Array.isArray(attachments)) { let removePromises = []; attachments.forEach(attachment => { removePromises.push(storageService.remove(attachment._id)); // Thumbnail as well removePromises.push(storageService.remove(attachment._id + ".thumbnail")); }); await Promise.all(removePromises); } else { await storageService.remove(attachments._id); // Thumbnail as well await storageService.remove(attachments._id + ".thumbnail"); } } return hook; }; }