feat: add support for notification processors

Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
Heikki Hellgren
2023-12-18 09:00:32 +02:00
parent 62141acaee
commit b6c1523444
5 changed files with 85 additions and 17 deletions
@@ -0,0 +1,34 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Notification } from '@backstage/plugin-notifications-common';
/** @public */
export type NotificationProcessor = {
/**
* Decorate notification before sending it
*
* @param notification - The notification to decorate
* @returns The same notification or a modified version of it
*/
decorate?(notification: Notification): Promise<Notification>;
/**
* Send notification using this processor.
*
* @param notification - The notification to send
*/
send?(notification: Notification): Promise<void>;
};
@@ -32,11 +32,13 @@ import {
PluginEndpointDiscovery,
} from '@backstage/backend-common';
import { DatabaseNotificationsStore } from '../database';
import { NotificationProcessor } from './NotificationProcessor';
/** @public */
export type NotificationServiceOptions = {
database: PluginDatabaseManager;
discovery: PluginEndpointDiscovery;
processors?: NotificationProcessor[];
};
/** @public */
@@ -52,21 +54,31 @@ export type NotificationSendOptions = {
/** @public */
export class NotificationService {
private store: NotificationsStore | null = null;
private readonly processors: NotificationProcessor[];
private constructor(
private readonly database: PluginDatabaseManager,
private readonly catalog: CatalogApi,
) {}
processors?: NotificationProcessor[],
) {
this.processors = processors ?? [];
}
static create({
database,
discovery,
processors,
}: NotificationServiceOptions): NotificationService {
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
return new NotificationService(database, catalogClient);
return new NotificationService(database, catalogClient, processors);
}
addProcessor(processor: NotificationProcessor) {
this.processors.push(processor);
return this;
}
async send(options: NotificationSendOptions): Promise<Notification[]> {
@@ -80,27 +92,35 @@ export class NotificationService {
}
const store = await this.getStore();
const baseNotification = {
id: uuid(),
title,
description,
link,
created: new Date(),
icon,
image,
saved: false,
};
for (const user of users) {
const notification = {
id: uuid(),
userRef: user,
title,
description,
link,
created: new Date(),
icon,
image,
saved: false,
};
let notification: Notification = { ...baseNotification, userRef: user };
for (const processor of this.processors) {
notification = processor.decorate
? await processor.decorate(notification)
: notification;
}
await store.saveNotification(notification);
for (const processor of this.processors) {
if (processor.send) {
processor.send(notification);
}
}
notifications.push(notification);
// TODO: Signal service
}
// TODO: Signal service
// TODO: Other senders
return notifications;
}
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export * from './NotificationService';
export * from './NotificationProcessor';