文件
hyb-oa/server/src/services/events.js
T

105 行
2.2 KiB
JavaScript

const { EventEmitter } = require("node:events");
function uniqueStrings(values) {
return Array.from(
new Set(
(Array.isArray(values) ? values : [])
.map((value) => (typeof value === "string" ? value.trim() : ""))
.filter(Boolean),
),
);
}
function createAppEventBus() {
const emitter = new EventEmitter();
emitter.setMaxListeners(500);
let sequence = 0;
return {
publish(event) {
const payload = {
id: `${Date.now()}-${++sequence}`,
createdAt: new Date().toISOString(),
...event,
audienceEmployeeIds: uniqueStrings(event?.audienceEmployeeIds),
};
emitter.emit("event", payload);
return payload;
},
subscribe(handler) {
emitter.on("event", handler);
return () => emitter.off("event", handler);
},
};
}
function buildInvoiceUpdatedEvent({
invoiceId,
status,
updatedAt = null,
audienceEmployeeIds = [],
}) {
return {
type: "invoice.updated",
invoiceId,
status,
updatedAt: updatedAt ?? new Date().toISOString(),
audienceEmployeeIds: uniqueStrings(audienceEmployeeIds),
};
}
function publishInvoiceUpdated(fastify, event) {
if (!fastify?.appEvents || typeof fastify.appEvents.publish !== "function") {
return null;
}
return fastify.appEvents.publish(buildInvoiceUpdatedEvent(event));
}
function canReceiveEvent(employee, event, options = {}) {
if (!employee) {
return false;
}
if (event?.type === "invoice.updated" && options.canManageInvoice) {
return true;
}
const audience = uniqueStrings(event?.audienceEmployeeIds);
if (!audience.length) {
return false;
}
return audience.includes(employee.id);
}
function toClientEvent(event) {
if (!event) {
return null;
}
if (event.type === "invoice.updated") {
return {
id: event.id,
type: event.type,
invoiceId: event.invoiceId,
status: event.status ?? null,
updatedAt: event.updatedAt ?? event.createdAt ?? null,
createdAt: event.createdAt ?? null,
};
}
return {
id: event.id,
type: event.type,
createdAt: event.createdAt ?? null,
};
}
module.exports = {
buildInvoiceUpdatedEvent,
canReceiveEvent,
createAppEventBus,
publishInvoiceUpdated,
toClientEvent,
};