ironnotify-js/src/builder.ts

140 lines
3.0 KiB
TypeScript

import type {
SeverityLevel,
NotificationAction,
NotificationPayload,
SendResult,
} from './types';
import type { NotifyClient } from './client';
/**
* Builder for creating notifications with a fluent API.
*/
export class EventBuilder {
private readonly client: NotifyClient;
private readonly eventType: string;
private title: string = '';
private message?: string;
private severity: SeverityLevel = 'info';
private metadata: Record<string, unknown> = {};
private actions: NotificationAction[] = [];
private userId?: string;
private groupKey?: string;
private deduplicationKey?: string;
private expiresAt?: Date;
constructor(client: NotifyClient, eventType: string) {
this.client = client;
this.eventType = eventType;
}
/**
* Set the notification title.
*/
withTitle(title: string): this {
this.title = title;
return this;
}
/**
* Set the notification message.
*/
withMessage(message: string): this {
this.message = message;
return this;
}
/**
* Set the severity level.
*/
withSeverity(severity: SeverityLevel): this {
this.severity = severity;
return this;
}
/**
* Set metadata for the notification.
*/
withMetadata(metadata: Record<string, unknown>): this {
this.metadata = { ...this.metadata, ...metadata };
return this;
}
/**
* Add an action button to the notification.
*/
withAction(action: NotificationAction): this {
this.actions.push(action);
return this;
}
/**
* Set the target user ID.
*/
forUser(userId: string): this {
this.userId = userId;
return this;
}
/**
* Set the group key for grouping related notifications.
*/
withGroupKey(groupKey: string): this {
this.groupKey = groupKey;
return this;
}
/**
* Set the deduplication key to prevent duplicate notifications.
*/
withDeduplicationKey(key: string): this {
this.deduplicationKey = key;
return this;
}
/**
* Set the expiration time for the notification.
*/
expiresIn(ms: number): this {
this.expiresAt = new Date(Date.now() + ms);
return this;
}
/**
* Set the expiration date for the notification.
*/
expiresOn(date: Date): this {
this.expiresAt = date;
return this;
}
/**
* Build the notification payload.
*/
build(): NotificationPayload {
if (!this.title) {
throw new Error('Notification title is required');
}
return {
eventType: this.eventType,
title: this.title,
message: this.message,
severity: this.severity,
metadata: Object.keys(this.metadata).length > 0 ? this.metadata : undefined,
actions: this.actions.length > 0 ? this.actions : undefined,
userId: this.userId,
groupKey: this.groupKey,
deduplicationKey: this.deduplicationKey,
expiresAt: this.expiresAt?.toISOString(),
};
}
/**
* Send the notification.
*/
async send(): Promise<SendResult> {
const payload = this.build();
return this.client.sendPayload(payload);
}
}