npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@easydev_org/notification-sdk

v1.0.3

Published

TypeScript SDK client for the Unified Email and SMS Notification Service

Readme

@easydev_org/notification-sdk

An elegant, fully-typed TypeScript SDK client for interacting with the Unified Email and SMS Notification Service.

Features

  • Typed Interfaces: Comprehensive TypeScript interfaces for all Email, SMS, and OTP payloads and response formats.
  • Sync & Async Methods: Supporting both async queueing (BullMQ) and synchronous dispatching (waiting for SMTP/SMS provider feedback).
  • Auto-Config: Instantiates automatically using standard environment variables.
  • Idempotency Out of the Box: Auto-generates unique idempotency keys for email requests unless explicitly overridden.
  • Error Mapping: Detailed custom error classes (NotificationHttpError, NotificationValidationError, NotificationTimeoutError) to inspect HTTP statuses and response details.
  • Custom Logging: Connects easily to your favorite logger (Pino, Winston, etc.) or uses the built-in prefix-aware Console Logger.

Installation

Install using your preferred package manager:

# Using pnpm
pnpm add @easydev_org/notification-sdk

# Using npm
npm install @easydev_org/notification-sdk

# Using yarn
yarn add @easydev_org/notification-sdk

Getting Started

1. Configure the Client

You can explicitly configure the client or let it fall back to environment variables.

Option A: Zero-Config (Default Production Setup)

You can initialize the client without any arguments. It will automatically connect to the production URL (https://notifications.easydev.in) using the default API key and tenant ID configurations:

import { NotificationClient } from '@easydev_org/notification-sdk';

const notificationClient = new NotificationClient();

Option B: Environment Variable Overrides

If you define the following environment variables, the SDK will automatically read and apply them:

  • EASYDEV_NOTIFICATION_URL (e.g. https://notifications.staging.url)
  • EASYDEV_NOTIFICATION_API_KEY (your custom secret API key)
  • EASYDEV_NOTIFICATION_TENANT_ID (your custom tenant identifier)
// Uses environment variables automatically
const notificationClient = new NotificationClient();

Option C: Custom Constructor Configuration

You can pass overrides explicitly inside the constructor:

const notificationClient = new NotificationClient({
  baseUrl: 'https://notifications.easydev.in',
  apiKey: 'your-production-secret-api-key',
  tenantId: 'your-tenant-id',
  logger: true, // Enables default ConsoleLogger
  timeout: 10000, // 10 seconds timeout
});

Usage Examples

1. Sending Emails

The SDK client handles branding attributes (like from, fromName, appUrl, and ctaPath) by maps-converting them into the specific request headers expected by the backend service.

Asynchronous Send (Queued via BullMQ)

Dispatches the email to the background queue immediately and resolves.

try {
  const result = await notificationClient.sendEmail({
    to: '[email protected]',
    template: 'welcomeEmailTemplate',
    data: {
      username: 'John Doe',
    },
    // Optional overrides:
    fromName: 'EasyDev Support',
    appUrl: 'https://easydev.in',
    ctaPath: '/dashboard',
  });

  console.log(`Email accepted! Request ID: ${result.requestId}`);
} catch (error) {
  console.error('Failed to send email:', error);
}

Synchronous Send (Waits for SMTP delivery)

Waits for the SMTP transmission to complete before resolving. Recommended for critical transactional flows where you must confirm delivery status (e.g. OTPs).

const result = await notificationClient.sendEmailSync({
  to: '[email protected]',
  template: 'otpEmailTemplate',
  data: {
    name: 'John Doe',
    otp: '847291',
    purpose: 'login verification',
    expiryMinutes: 10,
  },
  // Set explicit idempotency key to prevent double-send in case of retry
  idempotencyKey: 'otp-john-doe-1719889200',
});

console.log(`Email sent successfully! SMTP Message ID: ${result.messageId}`);

2. SMS and OTPs

Sending a Single SMS

const response = await notificationClient.sendSms({
  to: '+919876543210',
  message: 'Your order #ORD-2026-001 has been packed and is ready to ship!',
  messageType: 'TRANSACTIONAL',
});

Generating & Sending an OTP via SMS

Sends a secure OTP generated by the notification service backend.

const response = await notificationClient.sendOtp({
  to: '+919876543210',
  templateCode: 'otp_verification',
  otpLength: 6,
  expiresInMinutes: 5,
});

console.log(`OTP sent. Expires at: ${response.data.expiresAt}`);

Verifying an OTP

const verification = await notificationClient.verifyOtp({
  to: '+919876543210',
  otp: '123456',
});

if (verification.data.valid) {
  console.log('OTP verification successful!');
} else {
  console.warn('Invalid OTP:', verification.data.reason);
}

Bulk SMS Campaigns

const response = await notificationClient.sendBulkSms({
  recipients: [
    { to: '+919876543210', variables: { name: 'John' } },
    { to: '+919876543211', variables: { name: 'Jane' } },
  ],
  templateCode: 'holiday_greetings',
  messageType: 'PROMOTIONAL',
});

3. Log Retrieval and Health Checking

Querying Email Logs

const logsResponse = await notificationClient.getEmailLogs({
  status: 'failed',
  limit: 20,
  sort: { createdAt: -1 },
});

console.log(`Found ${logsResponse.total} failed emails.`);

Checking SMTP connection health

const health = await notificationClient.getEmailHealth();
if (health.success) {
  console.log('SMTP connections are healthy!');
}

Error Handling

The SDK exposes three main categories of errors inheriting from the base NotificationError.

import { 
  NotificationError, 
  NotificationValidationError, 
  NotificationHttpError, 
  NotificationTimeoutError 
} from '@easydev_org/notification-sdk';

try {
  await notificationClient.sendEmail({
    to: 'invalid-email',
    template: 'welcomeEmailTemplate',
  });
} catch (error) {
  if (error instanceof NotificationValidationError) {
    // Thrown BEFORE network request (e.g. missing required properties)
    console.error('Validation error:', error.message);
  } else if (error instanceof NotificationHttpError) {
    // Non-2xx response from the server (e.g. 401 Unauthorized, 400 Bad Request, 500 Server Error)
    console.error(`API Error (HTTP ${error.statusCode}):`, error.responseData);
    console.error(`Error Code:`, error.errorCode); // e.g. 'BadRequestException'
  } else if (error instanceof NotificationTimeoutError) {
    // Request timed out
    console.error(`Request timed out after ${error.timeoutMs}ms`);
  } else if (error instanceof NotificationError) {
    // General network or system error
    console.error('General error:', error.message);
  }
}

Logger Integration

You can easily supply your own logger (e.g. Winston or Pino) by passing an object conforming to the Logger interface.

import { Logger } from '@easydev_org/notification-sdk';
import winston from 'winston';

const myWinstonLogger = winston.createLogger({
  level: 'info',
  transports: [new winston.transports.Console()],
});

// Adapter conforming to the Logger interface
const sdkLoggerAdapter: Logger = {
  info: (msg, ...meta) => myWinstonLogger.info(msg, ...meta),
  warn: (msg, ...meta) => myWinstonLogger.warn(msg, ...meta),
  error: (msg, ...meta) => myWinstonLogger.error(msg, ...meta),
  debug: (msg, ...meta) => myWinstonLogger.debug(msg, ...meta),
};

const client = new NotificationClient({
  apiKey: 'secret',
  logger: sdkLoggerAdapter,
});

Development, Building & Packaging

1. Build the SDK

Compiles the TypeScript source code into ESM and CommonJS formats:

pnpm install
pnpm run build

This cleans the dist/ folder and outputs the compiled bundles containing index.js, index.mjs, and .d.ts typescript mapping files.

2. Pack the SDK (Offline Distribution)

To create a redistributable, compressed package (.tgz file) for use in other projects:

pnpm pack

This generates a file named easydev-notification-sdk-1.0.0.tgz at the package root.

3. Installing in Other Services

Option A: Direct File Installation (in external repositories)

In your other microservices or frontend repositories, install the package directly using the path to the compressed tarball:

# Using pnpm
pnpm add C:/Users/kisho/WorkSpace/Backend/notification-service/packages/notification-sdk/easydev_org-notification-sdk-1.0.0.tgz

# Using npm
npm install C:/Users/kisho/WorkSpace/Backend/notification-service/packages/notification-sdk/easydev_org-notification-sdk-1.0.0.tgz

Option B: Linking Locally (within this Monorepo workspace)

If the target service resides in the same repository workspace, add it as a workspace dependency inside the target's package.json:

"dependencies": {
  "@easydev/notification-sdk": "workspace:*"
}

Then run pnpm install in the root workspace to link the package.