UNPKG

isatdatapro-microservices

Version:

A library for creating microservices to access Inmarsat's IsatData Pro satellite IoT system

174 lines (162 loc) 5.01 kB
'use strict'; //const logger = require('../../logging').loggerProxy(__filename); require('dotenv').config(); const dbType = (process.env.DB_TYPE).toLowerCase(); const models = require('../models'); /** * Converts camelCase to snake_case * @private * @param {string} propName The property name in camelCase * @returns {string} snake_case property name */ function camelToSnakeCase_(propName) { let snake_case = propName; ///* Comment out to enable snake_case = propName.replace(/([A-Z])/g, ($1) => { return '_' + $1.toLowerCase(); }); //*/ return snake_case; } /** * Converts snake_case to camelCase * @private * @param {string} propName The property name in snake_case * @returns {string} camelCase property name */ function snakeToCamelCase_(propName) { let camelCase = propName; ///* Comment out to enable camelCase = propName.replace(/([_][a-z])/ig, ($1) => { return $1.toUpperCase().replace('_', ''); }); //*/ return camelCase; } /** * Converts a property and optionally its value to database-compatible * @param {string} modelProp The model property * @param {any} [modelValue] Optional property value * @returns {(string|{dbProp: string, dbValue: any})} the db property name/object */ function propToDb(modelProp, modelValue) { let dbProp = camelToSnakeCase_(modelProp); if (typeof(modelValue) !== 'undefined') { let dbValue = modelValue; if (modelValue instanceof Array || modelValue instanceof Object) { dbValue = JSON.stringify(modelValue); } else if (dbType.includes('mysql') && modelProp.includes('TimeUtc')) { dbValue = isoToMySqlDate(dbValue); } return { dbProp, dbValue }; } return dbProp; } function isoToMySqlDate(date) { if (date) return date.replace('T', ' ').replace('Z', ''); return date; } function mySqlDateToIso(date) { if (date) return date.replace(' ', 'T') + 'Z'; return date; } /** * Converts database-compatible to model property and optionally its value * @param {string} dbProp The property name/key from the database * @param {any} [dbValue] Optional value stored in the database * @returns {(string|{prop: string, value: any})} the model property name/object */ function propFromDb(dbProp, dbValue) { let modelProp = snakeToCamelCase_(dbProp); if (typeof(dbValue) !== 'undefined') { let modelValue = dbValue; if (dbType.includes('mysql') && modelProp.includes('TimeUtc')) { modelValue = mySqlDateToIso(dbValue); } else if (typeof(dbValue) === 'string') { try { modelValue = JSON.parse(dbValue); if (modelProp === 'mailboxId') modelValue = String(modelValue); } catch (err) { if (err.message.includes('JSON')) { //: modelValue = dbValue } else { throw err; } } } return { modelProp, modelValue }; } return modelProp; } /** * Returns an Entity based on Model defined by category from a database read * camelCase tags, JSON objects and Arrays * @private * @param {Object} dbItem The raw item retrieved from the database * @param {boolean} [includeDbId] Adds the primary database key id to the Model * @returns {Object} entity based on Model category * @throws {Error} if no model matching the item.category is found */ function modelFromDb(dbItem, includeDbId) { const category = dbItem.category; let model = null; for (const modelName in models) { if (category === models[modelName].prototype.category) { model = new models[modelName]; break; } } if (!model) throw new Error(`No model found for ${category}`); const modelProperties = Object.getOwnPropertyNames(model); modelProperties.forEach(prop => { const dbProp = propToDb(prop); if (model.hasOwnProperty(prop) && dbItem.hasOwnProperty(dbProp)) { const { modelValue } = propFromDb(dbProp, dbItem[dbProp]); model[prop] = modelValue; } }); if (includeDbId) model.id = dbItem.id; return model; } /** * Returns an database-formatted entry from a Model/Entity * snake_case tags, stringified JSON/Arrays * @private * @param {Object} item The Model-defined Entity * @returns {Object} database-compatible entry */ function modelToDb(item) { const dbItem = {}; const itemProperties = Object.getOwnPropertyNames(item); itemProperties.forEach(prop => { if (item.hasOwnProperty(prop)) { const { dbProp, dbValue } = propToDb(prop, item[prop]); dbItem[dbProp] = dbValue; } }); return dbItem; } /** * Returns a database-compatible filter for queries * @param {Object} filter A filter key/value set * @returns {Object} the database-compatible filter */ function dbFilter(filter) { let newFilter = {}; for (let param in filter) { if (!filter.hasOwnProperty(param)) continue; let dbName = propToDb(param); newFilter[dbName] = filter[param]; } return newFilter; } module.exports = { dbFilter, modelToDb, modelFromDb, propToDb, propFromDb, isoToMySqlDate, };