UNPKG

@unchainedshop/core-events

Version:

Event history and tracking module for the Unchained Engine

117 lines (116 loc) 4.39 kB
import { mongodb, generateDbFilterById, buildSortOptions, generateDbObjectId, } from '@unchainedshop/mongodb'; import { getRegisteredEvents } from '@unchainedshop/events'; import { SortDirection } from '@unchainedshop/utils'; import { EventsCollection } from "../db/EventsCollection.js"; import { configureEventHistoryAdapter } from "./configureEventHistoryAdapter.js"; import { createLogger } from '@unchainedshop/logger'; const logger = createLogger('unchained:core-events'); export const buildFindSelector = ({ types, queryString, created }) => { const selector = {}; if (types && Array.isArray(types)) selector.type = { $in: types }; if (queryString) { selector.$text = { $search: queryString }; } if (created) { selector.created = created?.end ? { $gte: created.start || new Date(0), $lte: created.end } : { $gte: created.start || new Date(0) }; } return selector; }; export const configureEventsModule = async ({ db }) => { const Events = await EventsCollection(db); const create = async (doc) => { const result = await Events.insertOne({ _id: generateDbObjectId(), created: new Date(), ...doc, }); return result.insertedId; }; await configureEventHistoryAdapter(create); return { create, findEvent: async ({ eventId, ...rest }, options) => { const selector = eventId ? generateDbFilterById(eventId) : rest; return Events.findOne(selector, options); }, findEvents: async ({ limit, offset, sort, ...query }) => { const defaultSort = [{ key: 'created', value: SortDirection.DESC }]; return Events.find(buildFindSelector(query), { skip: offset, limit, sort: buildSortOptions(sort || defaultSort), }).toArray(); }, type: (event) => { if (getRegisteredEvents().includes(event.type)) { return event.type; } return 'UNKNOWN'; }, count: async (query) => { const count = await Events.countDocuments(buildFindSelector(query)); return count; }, getReport: async ({ dateRange, types, } = {}) => { const match = {}; if (dateRange?.start || dateRange?.end) { const conditions = []; if (dateRange.start) { const fromDate = new Date(dateRange.start); conditions.push({ created: { $gte: fromDate } }); } if (dateRange.end) { const toDate = new Date(dateRange.end); conditions.push({ created: { $lte: toDate } }); } if (conditions.length) { match.$or = conditions; } } if (types?.length) { match.type = { $in: types }; } const pipeline = [ Object.keys(match).length ? { $match: match } : null, { $group: { _id: { type: '$type', day: { $dateToString: { format: '%Y-%m-%d', date: '$created' }, }, }, count: { $sum: 1 }, }, }, { $group: { _id: '$_id.type', detail: { $push: { date: '$_id.day', count: '$count', }, }, emitCount: { $sum: '$count' }, }, }, { $project: { _id: 0, type: '$_id', emitCount: 1, detail: 1, }, }, { $sort: { type: 1 } }, ].filter(Boolean); const report = await Events.aggregate(pipeline).toArray(); logger.info(report); return report ?? []; }, }; };