Skip to content

Latest commit

Β 

History

History
374 lines (274 loc) Β· 7.96 KB

File metadata and controls

374 lines (274 loc) Β· 7.96 KB

Infrastructure Layer

This directory contains concrete implementations of the core notification interfaces.

πŸ“ Structure

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

πŸ”Œ Email Senders

Nodemailer (SMTP)

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

πŸ“± SMS Senders

Twilio

import { TwilioSmsSender } from "@ciscode/notification-kit/infra";

const smsSender = new TwilioSmsSender({
  accountSid: "your-account-sid",
  authToken: "your-auth-token",
  fromNumber: "+1234567890",
});

Peer Dependency: twilio

AWS SNS

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

Vonage (Nexmo)

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

πŸ”” Push Notification Senders

Firebase Cloud Messaging

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

OneSignal

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)

AWS SNS (Push)

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

πŸ’Ύ Repositories

MongoDB with Mongoose

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

In-Memory (Testing)

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

πŸ› οΈ Utility Providers

ID Generator

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"

DateTime Provider

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"); // true

Template Engine

Handlebars

import { 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

Simple Template Engine

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}} replacement

No dependencies

Event Emitter

In-Memory Event Emitter

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);
});

Console Event Emitter

import { ConsoleEventEmitter } from "@ciscode/notification-kit/infra";

const eventEmitter = new ConsoleEventEmitter();
// Logs all events to console

πŸ“¦ Installation

Install only the peer dependencies you need:

Email (Nodemailer)

npm install nodemailer
npm install -D @types/nodemailer

SMS

# Twilio
npm install twilio

# AWS SNS
npm install @aws-sdk/client-sns

# Vonage
npm install @vonage/server-sdk

Push Notifications

# Firebase
npm install firebase-admin

# AWS SNS (same as SMS)
npm install @aws-sdk/client-sns

Repository

# Mongoose
npm install mongoose

Template Engine

# Handlebars
npm install handlebars
npm install -D @types/handlebars

ID Generator

# NanoID (optional)
npm install nanoid

🎯 Usage with NestJS Module

These 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 {}

πŸ”’ Architecture Notes

  • 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