UNPKG

@eventcatalog/notifier

Version:

CLI tool to detect EventCatalog changes and send notifications

166 lines 7.77 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConsumerRemovedEvent = void 0; const Event_1 = require("./Event"); const sdk_1 = __importDefault(require("@eventcatalog/sdk")); const git_1 = require("../utils/git"); class ConsumerRemovedEvent extends Event_1.Event { constructor({ catalogPath, changedFiles, commitRange, options, }) { super({ catalogPath, changedFiles, commitRange, options }); this.eventId = 'consumer-removed'; } async process() { const { getServiceByPath, getOwnersForResource, getEvent, isService, toService } = (0, sdk_1.default)(this.catalogPath); const changedServices = []; // Get any service that has been changed for (const file of this.changedFiles) { const isChangedFileAService = await isService(file); if (isChangedFileAService) { const service = await getServiceByPath(file); if (service) { changedServices.push({ ...service, absolutePath: file, }); } } } const notifications = []; // Process each service for (const service of changedServices) { // Handle both .. and ... git range syntax const [beforeRange, afterRange] = this.parseCommitRange(this.commitRange); const fileBefore = (0, git_1.getFileAtCommit)(this.catalogPath, service.absolutePath, beforeRange); const fileAfter = (0, git_1.getFileAtCommit)(this.catalogPath, service.absolutePath, afterRange); const serviceBefore = await toService(fileBefore); const serviceAfter = await toService(fileAfter); // If we have two versions of the service, then we can compare the consumers if (serviceBefore && serviceAfter) { const removedReceives = this.findRemovedReceives(serviceBefore.receives || [], serviceAfter.receives || []); // Get the owners of any event change for (const receive of removedReceives) { const ownersForMessage = await getOwnersForResource(receive.id); const resource = await getEvent(receive.id); const ownersForConsumer = await getOwnersForResource(serviceAfter.id); notifications.push({ id: this.eventId, version: '1.0.0', resource: { id: resource.id, name: resource.name, version: resource.version, // TODO: Get type of resource, SDK function, getResourceType(resource)? type: 'event', owners: ownersForMessage, }, consumer: { id: serviceAfter.id, name: serviceAfter.name, version: serviceAfter.version, type: 'service', owners: ownersForConsumer, }, metadata: { timestamp: new Date().toISOString(), catalog_path: this.catalogPath, }, }); } } } return notifications; } static getSlackMessage(config, notification, lifecycle, actionUrl) { const eventOwners = notification.resource.owners .map((owner) => { const id = owner.id || owner; return `<${config.eventcatalog_url}/docs/teams/${id}|${id}>`; }) .join(', '); const consumerOwners = notification.consumer.owners .map((owner) => { const id = owner.id || owner; return `<https://eventcatalog.dev/docs/teams/${id}|${id}>`; }) .join(', '); const timestamp = new Date(notification.metadata.timestamp).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit', }); const isDraft = lifecycle === 'draft'; const text = isDraft ? `🔄 EventCatalog - 🗑️ Request to Remove Event Consumer` : `🗑️ EventCatalog - ✉️ Event Consumer Removed`; const pretext = isDraft ? `A request has been made to remove an event consumer in your architecture` : `A service has stopped consuming an event in your architecture`; return { text, attachments: [ { color: 'warning', pretext, fields: [ { title: '📡 Event No Longer Consumed', value: `<${config.eventcatalog_url}/docs/events/${notification.resource.id}/${notification.resource.version}|*${notification.resource.name}*> (v${notification.resource.version})`, short: true, }, { title: '⚙️ Service That Removed Consumption', value: `<${config.eventcatalog_url}/docs/services/${notification.consumer.id}/${notification.consumer.version}|*${notification.consumer.name}*> (v${notification.consumer.version})`, short: true, }, { title: '👥 Event Owners (Need to Know)', value: eventOwners || 'No owners assigned', short: true, }, { title: '👥 Service Team', value: consumerOwners || 'No owners assigned', short: true, }, { title: '📅 When', value: timestamp, short: true, }, { title: '💼 Impact', value: `The *${notification.consumer.name}* service is no longer dependent on the *${notification.resource.name}* event. This may affect downstream processing.`, short: false, }, ], footer: 'EventCatalog Notifier • eventcatalog.dev', ts: Math.floor(Date.now() / 1000), }, ], }; } parseCommitRange(commitRange) { // Handle both .. (two-dot) and ... (three-dot) git range syntax if (commitRange.includes('...')) { // Three-dot syntax: A...B const parts = commitRange.split('...'); return [parts[0], parts[1]]; } else { // Two-dot syntax: A..B const parts = commitRange.split('..'); return [parts[0], parts[1]]; } } findRemovedReceives(beforeReceives, afterReceives) { const afterIds = new Set(afterReceives.map((r) => r.id)); return beforeReceives.filter((r) => !afterIds.has(r.id)); } } exports.ConsumerRemovedEvent = ConsumerRemovedEvent; //# sourceMappingURL=ConsumerRemovedEvent.js.map