UNPKG

@batolye/bdk-core

Version:

Module to provide core utilities for BulusAtolyesi applications and services

230 lines (178 loc) 8.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processTime = processTime; exports.unprocessTime = unprocessTime; exports.processPerspectives = processPerspectives; exports.preventUpdatePerspectives = preventUpdatePerspectives; exports.serialize = serialize; exports.processObjectIDs = processObjectIDs; exports.convertObjectIDs = convertObjectIDs; exports.toDates = toDates; exports.convertDates = convertDates; exports.populatePreviousObject = populatePreviousObject; exports.setAsDeleted = setAsDeleted; exports.setExpireAfter = setExpireAfter; var _lodash = _interopRequireDefault(require("lodash")); var _moment = _interopRequireDefault(require("moment")); var _mongoDb = require("../utils/mongoDb"); var _marshall = require("../utils/marshall"); var _feathersHooksCommon = require("feathers-hooks-common"); var _debug = _interopRequireDefault(require("debug")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const debug = (0, _debug.default)("batolye:bdk-core:model:hooks"); // Need to convert from server side types (moment dates) to basic JS types when "writing" to DB adapters function processTime(hook) { let items = (0, _feathersHooksCommon.getItems)(hook); const isArray = Array.isArray(items); items = isArray ? items : [items]; items.forEach(item => { (0, _marshall.marshallTime)(item, "time"); }); (0, _feathersHooksCommon.replaceItems)(hook, isArray ? items : items[0]); } // Need to convert back to server side types (moment dates) from basic JS types when "reading" from DB adapters function unprocessTime(hook) { let items = (0, _feathersHooksCommon.getItems)(hook); const isArray = Array.isArray(items); items = isArray ? items : [items]; items.forEach(item => { (0, _marshall.unmarshallTime)(item, "time"); }); (0, _feathersHooksCommon.replaceItems)(hook, isArray ? items : items[0]); } function processPerspectives(hook) { let params = hook.params; let query = params.query; let service = hook.service; // Test if some perspectives are defined on the model if (!service.core_options || !service.core_options.perspectives) return; // Iterate through known perspectives of the model service.core_options.perspectives.forEach(perspective => { // Only discard if not explicitely asked by $select let filterPerspective = true; if (!_lodash.default.isNil(query) && !_lodash.default.isNil(query.$select)) { // Transform to array to unify processing // https://docs.feathersjs.com/api/databases/querying.html#select let selectedFields = typeof query.$select === "string" ? [query.$select] : query.$select; if (Array.isArray(selectedFields)) { selectedFields.forEach(field => { // Take care that we might only ask for a subset of perspective fields like ['perspective.fieldName'] // user -> perspectives: ["profile","google","github"] // organisation -> parspectives: ["billing"] if (field === perspective || field.startsWith(perspective + ".")) { filterPerspective = false; } }); } } if (filterPerspective) { // https://feathers-plus.github.io/v1/feathers-hooks-common/#discard (0, _feathersHooksCommon.discard)(perspective)(hook); } }); } // When perspectives are present we disallow update in order to avoid erase them. // Indeed when requesting an object they are not retrieved by default function preventUpdatePerspectives(hook) { let service = hook.service; // Test if some perspectives are defined on the model if (!service.core_options || !service.core_options.perspectives) return; (0, _feathersHooksCommon.disallow)()(hook); } // The hook serialize allows to copy/move some properties within the objects holded by the hook // It applies an array of rules defined by: // - source: the path to the property to be copied // - target: the path where to copy the property // - delete: a flag to define whether the hook has to delete the source property function serialize(rules, options = {}) { return function (hook) { // Retrieve the items from the hook let items = (0, _feathersHooksCommon.getItems)(hook); const isArray = Array.isArray(items); items = isArray ? items : [items]; // Apply the rules for each item items.forEach(item => { rules.forEach(rule => { const source = _lodash.default.get(item, rule.source); // https://lodash.com/docs/#isNil if (!_lodash.default.isNil(source)) { _lodash.default.set(item, rule.target, source); if (rule.delete) { // https://lodash.com/docs/#unset _lodash.default.unset(item, rule.source); } } else if (options.throwOnNotFound || rule.throwOnNotFound) { throw new Error("Cannot find valid input value for property " + rule.target); } }); }); // Replace the items within the hook (0, _feathersHooksCommon.replaceItems)(hook, isArray ? items : items[0]); }; } // The hook objectify allows to transform the value bound to an '_id' like key as a string // into a Mongo ObjectId on client queries function processObjectIDs(hook) { if (hook.params.query) (0, _mongoDb.objectifyIDs)(hook.params.query); if (hook.data) (0, _mongoDb.objectifyIDs)(hook.data); return hook; } // The hook convert allows to transform a set of input properties as a string // into a Mongo ObjectId on client queries function convertObjectIDs(properties) { return function (hook) { if (hook.params.query) (0, _mongoDb.toObjectIDs)(hook.params.query, properties); if (hook.data) (0, _mongoDb.toObjectIDs)(hook.data, properties); return hook; }; } // Utility function used to convert from string to Dates a fixed set of properties on a given object function toDates(object, properties, asMoment) { properties.forEach(property => { let date = _lodash.default.get(object, property); if (date) { // We use moment to validate the date date = _moment.default.utc(date); if (date.isValid()) { if (!asMoment) { date = date.toDate(); } _lodash.default.set(object, property, date); } } }); } // The hook allows to transform a set of input properties as a string // into a Date/Moment object on client queries function convertDates(properties, asMoment) { return function (hook) { if (hook.params.query) toDates(hook.params.query, properties, asMoment); if (hook.data) toDates(hook.data, properties, asMoment); return hook; }; } async function populatePreviousObject(hook) { if (hook.type !== "before") { throw new Error(`The 'populatePreviousObject' hook should only be used as a 'before' hook.`); } let item = (0, _feathersHooksCommon.getItems)(hook); let id = item._id || hook.id; // Retrieve previous version of the item and make it available to next hooks if (id) { try { hook.params.previousItem = await hook.service.get(id.toString()); } catch (error) {} debug("Populated previous object", hook.params.previousItem); } return hook; } function setAsDeleted(hook) { // Retrieve the items from the hook let items = (0, _feathersHooksCommon.getItems)(hook); const isArray = Array.isArray(items); items = isArray ? items : [items]; // Apply the rules for each item items.forEach(item => _lodash.default.set(item, "deleted", true)); // Replace the items within the hook (0, _feathersHooksCommon.replaceItems)(hook, isArray ? items : items[0]); return hook; } function setExpireAfter(delayInSeconds) { return function (hook) { if (hook.type !== "before") { throw new Error(`The 'setExpireAfter' hook should only be used as a 'before' hook.`); } // Retrieve the items from the hook let items = (0, _feathersHooksCommon.getItems)(hook); const isArray = Array.isArray(items); items = isArray ? items : [items]; // Apply the rules for each item let date = new Date(Date.now() + 1000 * delayInSeconds); items.forEach(item => _lodash.default.set(item, "expireAt", date)); // Replace the items within the hook (0, _feathersHooksCommon.replaceItems)(hook, isArray ? items : items[0]); return hook; }; }