UNPKG

@natlibfi/melinda-ui-commons

Version:
212 lines (162 loc) 6.52 kB
/* eslint-disable no-unused-vars */ /* eslint-disable max-statements */ //****************************************************************************// // // // SERVER NOTIFICATIONS FOR MELINDA UI APPLICATIONS // // - collection 'notes' in Mongo DB // // // //****************************************************************************// import httpStatus from 'http-status'; import {MongoClient, ObjectId} from 'mongodb'; import sanitize from 'mongo-sanitize'; import {createLogger} from '@natlibfi/melinda-backend-commons'; import {Error as ApiError} from '@natlibfi/melinda-commons'; import {construct, hasUndefinedProperty, isObject} from './notificationUtils.js'; export default async function (MONGO_URI, dbName = 'melinda-ui') { const logger = createLogger(); // Connect to mongo (MONGO) const client = await MongoClient.connect(MONGO_URI); const db = client.db(dbName); const collection = 'notes'; // Default projection for a note item // The returned note item object: // - has property '_id' removed // - has property 'id' added // - all other properties are returned without modifications // * url is an optional property and is therefore not always present in returned objects const noteItemProjection = { projection: { _id: 0, id: {$toString: '$_id'}, blocksInteraction: 1, componentStyle: 1, context: 1, endDate: 1, isDismissible: 1, messageStyle: 1, messageText: 1, url: 1 } }; return {addNoteItem, getNoteItem, getNoteItems, getNoteItemsForApp, removeNoteItem, removeNoteItemsByMessageStyle}; //----------------------------------------------------------------------------- // ADD SERVER NOTIFICATIONS //----------------------------------------------------------------------------- /** * Add note item to collection * @param {Object} noteItem contains note item data: * { * blocksInteraction: false, * componentStyle: "banner", * context: ["artikkelit", "muuntaja"], * endDate: new Date("2024-12-30T12:30:15.002"), * isDismissible: true, * messageStyle: "info", * messageText: "Test server notification message", * url: "https://www.kansalliskirjasto.fi/" //optional property * } * @returns {void} */ async function addNoteItem(noteItem) { logger.info(`MongoNotes: Adding one note item ${JSON.stringify(noteItem)}`); if (!isObject(noteItem)) { logger.debug('MongoNotes: NoteItem parameter is not object'); throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, 'NoteItem data is not valid'); } const newNoteItem = construct(noteItem); if (hasUndefinedProperty(newNoteItem)) { logger.debug('MongoNotes: NoteItem data did not pass validation'); throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, 'NoteItem data is not valid'); } // '_id' property is automatically generated by mongo node driver // and added to noteItem before insert to collection. // type of '_id' is ObjectId. const result = await db.collection(collection).insertOne(newNoteItem); if (result.acknowledged) { logger.info(`New ${noteItem.componentStyle} note item added with ${noteItem.messageStyle} message: ${noteItem.messageText}`); const {_id: _, ...rest} = newNoteItem; return {id: result.insertedId.toString(), ...rest}; } throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, `MongoNotes could not add note ${noteItem}`); } //----------------------------------------------------------------------------- // GET SERVER NOTIFICATIONS //----------------------------------------------------------------------------- /** * Get note item with id * @param {String} noteId object's id * @returns Boolean */ async function getNoteItem(noteId) { logger.info(`MongoNotes: Getting one note item`); const cleanId = sanitize(noteId); const query = {_id: new ObjectId(cleanId)}; const result = await db.collection(collection).findOne(query, noteItemProjection); return result; } /** * Get note items with matching context.app * @param {String} app apps name * @returns Array of note objects */ async function getNoteItemsForApp(app) { logger.info(`MongoNotes: Getting all note items for app`); const cleanAppName = sanitize(app); const query = { 'context': { $in: [cleanAppName, 'all'] } }; const result = await db.collection(collection).find(query, noteItemProjection).toArray(); return result; } /** * Get note items * @returns Array of note objects */ async function getNoteItems() { logger.info(`MongoNotes: Getting all note items`); const query = {}; const result = await db.collection(collection).find(query, noteItemProjection).toArray(); return result; } //----------------------------------------------------------------------------- // REMOVE SERVER NOTIFICATIONS //----------------------------------------------------------------------------- /** * Remove note * @param {String} noteId object's id * @returns Boolean */ async function removeNoteItem(noteId) { logger.info(`MongoNotes: Removing one note item with id ${noteId}`); const cleanId = sanitize(noteId); const filter = {_id: new ObjectId(cleanId)}; const result = await db.collection(collection).deleteOne(filter); if (result.deletedCount > 0) { return true; } if (result.deletedCount === 0) { return false; } throw new ApiError(httpStatus.NOT_FOUND, `MongoNotes could not remove note with id ${noteId}`); } /** * Remove notes by message style * @param {String} messageStyle * @returns Boolean */ async function removeNoteItemsByMessageStyle(messageStyle) { logger.info(`MongoNotes: Removing all notes with message style ${messageStyle}`); const cleanMessageStyle = sanitize(messageStyle); const filter = {messageStyle: cleanMessageStyle}; const result = await db.collection(collection).deleteMany(filter); if (result.deletedCount > 0) { return true; } if (result.deletedCount === 0) { return false; } throw new ApiError(httpStatus.NOT_FOUND, `MongoNotes could not remove notes`); } }