This directory contains concrete implementations of the core notification interfaces.
infra/
βββ senders/ # Notification channel senders
β βββ email/ # Email providers
β βββ sms/ # SMS providers
β βββ push/ # Push notification providers
βββ repositories/ # Data persistence
β βββ mongoose/ # MongoDB with Mongoose
β βββ in-memory/ # In-memory (testing)
βββ providers/ # Utility providers
βββ id-generator.provider.ts
βββ datetime.provider.ts
βββ template.provider.ts
βββ event-emitter.provider.ts
Works with any SMTP provider (Gmail, SendGrid, AWS SES via SMTP, etc.)
import { NodemailerSender } from "@ciscode/notification-kit/infra";
const emailSender = new NodemailerSender({
host: "smtp.gmail.com",
port: 587,
secure: false,
auth: {
user: "your-email@gmail.com",
pass: "your-app-password",
},
from: "noreply@example.com",
fromName: "My App",
});Peer Dependency: nodemailer
import { TwilioSmsSender } from "@ciscode/notification-kit/infra";
const smsSender = new TwilioSmsSender({
accountSid: "your-account-sid",
authToken: "your-auth-token",
fromNumber: "+1234567890",
});Peer Dependency: twilio
import { AwsSnsSender } from "@ciscode/notification-kit/infra";
const smsSender = new AwsSnsSender({
region: "us-east-1",
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
senderName: "MyApp", // Optional
});Peer Dependency: @aws-sdk/client-sns
import { VonageSmsSender } from "@ciscode/notification-kit/infra";
const smsSender = new VonageSmsSender({
apiKey: "your-api-key",
apiSecret: "your-api-secret",
from: "MyApp",
});Peer Dependency: @vonage/server-sdk
import { FirebasePushSender } from "@ciscode/notification-kit/infra";
const pushSender = new FirebasePushSender({
projectId: "your-project-id",
privateKey: "your-private-key",
clientEmail: "your-client-email",
});Peer Dependency: firebase-admin
import { OneSignalPushSender } from "@ciscode/notification-kit/infra";
const pushSender = new OneSignalPushSender({
appId: "your-app-id",
restApiKey: "your-rest-api-key",
});No additional dependencies (uses fetch API)
import { AwsSnsPushSender } from "@ciscode/notification-kit/infra";
const pushSender = new AwsSnsPushSender({
region: "us-east-1",
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
platformApplicationArn: "arn:aws:sns:...",
});Peer Dependency: @aws-sdk/client-sns
import mongoose from "mongoose";
import { MongooseNotificationRepository } from "@ciscode/notification-kit/infra";
const connection = await mongoose.createConnection("mongodb://localhost:27017/mydb");
const repository = new MongooseNotificationRepository(
connection,
"notifications", // collection name (optional)
);Peer Dependency: mongoose
import { InMemoryNotificationRepository } from "@ciscode/notification-kit/infra";
const repository = new InMemoryNotificationRepository();
// For testing - clear all data
repository.clear();
// For testing - get all notifications
const all = repository.getAll();No dependencies
import { UuidGenerator, ObjectIdGenerator, NanoIdGenerator } from "@ciscode/notification-kit/infra";
// UUID v4
const uuidGen = new UuidGenerator();
uuidGen.generate(); // "a1b2c3d4-..."
// MongoDB ObjectId format
const objectIdGen = new ObjectIdGenerator();
objectIdGen.generate(); // "507f1f77bcf86cd799439011"
// NanoID (requires nanoid package)
const nanoIdGen = new NanoIdGenerator();
nanoIdGen.generate(); // "V1StGXR8_Z5jdHi6B-myT"import { DateTimeProvider } from "@ciscode/notification-kit/infra";
const dateTime = new DateTimeProvider();
dateTime.now(); // "2024-01-15T10:30:00.000Z"
dateTime.isPast("2024-01-01T00:00:00.000Z"); // true
dateTime.isFuture("2025-01-01T00:00:00.000Z"); // trueimport { HandlebarsTemplateEngine } from "@ciscode/notification-kit/infra";
const templateEngine = new HandlebarsTemplateEngine({
templates: {
welcome: {
title: "Welcome {{name}}!",
body: "Hello {{name}}, thanks for joining!",
html: "<h1>Welcome {{name}}!</h1>",
},
},
});
const result = await templateEngine.render("welcome", { name: "John" });
// { title: 'Welcome John!', body: 'Hello John, thanks for joining!', html: '<h1>Welcome John!</h1>' }Peer Dependency: handlebars
import { SimpleTemplateEngine } from "@ciscode/notification-kit/infra";
const templateEngine = new SimpleTemplateEngine({
welcome: {
title: "Welcome {{name}}!",
body: "Hello {{name}}, thanks for joining!",
},
});
const result = await templateEngine.render("welcome", { name: "John" });
// Uses simple {{variable}} replacementNo dependencies
import { InMemoryEventEmitter } from "@ciscode/notification-kit/infra";
const eventEmitter = new InMemoryEventEmitter();
// Listen to specific events
eventEmitter.on("notification.sent", (event) => {
console.log("Notification sent:", event.notification.id);
});
// Listen to all events
eventEmitter.on("*", (event) => {
console.log("Event:", event.type);
});import { ConsoleEventEmitter } from "@ciscode/notification-kit/infra";
const eventEmitter = new ConsoleEventEmitter();
// Logs all events to consoleInstall only the peer dependencies you need:
npm install nodemailer
npm install -D @types/nodemailer# Twilio
npm install twilio
# AWS SNS
npm install @aws-sdk/client-sns
# Vonage
npm install @vonage/server-sdk# Firebase
npm install firebase-admin
# AWS SNS (same as SMS)
npm install @aws-sdk/client-sns# Mongoose
npm install mongoose# Handlebars
npm install handlebars
npm install -D @types/handlebars# NanoID (optional)
npm install nanoidThese implementations will be used when configuring the NotificationKit module:
import { Module } from "@nestjs/common";
import { NotificationKitModule } from "@ciscode/notification-kit";
import {
NodemailerSender,
TwilioSmsSender,
FirebasePushSender,
MongooseNotificationRepository,
UuidGenerator,
DateTimeProvider,
InMemoryEventEmitter,
} from "@ciscode/notification-kit/infra";
@Module({
imports: [
NotificationKitModule.register({
senders: [
new NodemailerSender({
/* config */
}),
new TwilioSmsSender({
/* config */
}),
new FirebasePushSender({
/* config */
}),
],
repository: new MongooseNotificationRepository(/* mongoose connection */),
idGenerator: new UuidGenerator(),
dateTimeProvider: new DateTimeProvider(),
eventEmitter: new InMemoryEventEmitter(),
}),
],
})
export class AppModule {}- All implementations use lazy loading for peer dependencies
- External packages are imported dynamically to avoid build-time dependencies
- TypeScript errors for missing packages are suppressed with
@ts-expect-error - Only install the peer dependencies you actually use