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

steadfast-courier

v1.0.9

Published

TypeScript SDK for Steadfast Courier Limited API with webhook support

Readme

Steadfast Courier SDK

A modern, type-safe TypeScript SDK for the Steadfast Courier Limited API with comprehensive webhook support.

Features

  • Full TypeScript Support - Complete type definitions for all API endpoints
  • Webhook Handling - Built-in webhook handlers for Express, Fastify, and generic frameworks
  • Input Validation - Automatic validation of request parameters
  • Error Handling - Custom error classes with detailed error messages
  • Framework Agnostic - Works with any Node.js framework
  • Tree-shakeable - Optimized for bundle size
  • Well Documented - Comprehensive documentation and examples

Installation

# npm
npm install steadfast-courier

# yarn
yarn add steadfast-courier

# pnpm
pnpm add steadfast-courier

⚠️ TypeScript Configuration Required

If you're using TypeScript and importing from 'steadfast-courier/webhooks', you must update your tsconfig.json:

{
  "compilerOptions": {
    "moduleResolution": "node16" // or "nodenext" or "bundler"
  }
}

Without this, you'll get: Cannot find module 'steadfast-courier/webhooks'

See TypeScript Support section for more details.

Quick Start

Basic Usage

import { SteadfastClient } from 'steadfast-courier';

// Initialize the client
const client = new SteadfastClient({
  apiKey: 'your-api-key',
  secretKey: 'your-secret-key',
});

// Create an order
const order = await client.orders.createOrder({
  invoice: 'INV-12345',
  recipient_name: 'John Doe',
  recipient_phone: '01234567890',
  recipient_address: '123 Main St, Dhaka-1209',
  cod_amount: 1000,
  note: 'Handle with care',
});

console.log(`Order created: ${order.consignment.tracking_code}`);

// Check delivery status
const status = await client.status.getStatusByTrackingCode('15BAEB8A');
console.log(`Status: ${status.delivery_status}`);

// Get current balance
const balance = await client.balance.getBalance();
console.log(`Current balance: ${balance.current_balance} BDT`);

API Reference

Complete API Methods Table

| Service | Method | Description | Parameters | Returns | | ------------------- | -------------------------- | -------------------------------- | ---------------------------- | ----------------------------- | | Orders | createOrder | Create a single order | CreateOrderRequest | CreateOrderResponse | | | createBulkOrders | Create multiple orders (max 500) | BulkOrderItem[] | BulkOrderResponse[] | | Status | getStatusByConsignmentId | Get status by consignment ID | consignmentId: number | DeliveryStatusResponse | | | getStatusByInvoice | Get status by invoice number | invoice: string | DeliveryStatusResponse | | | getStatusByTrackingCode | Get status by tracking code | trackingCode: string | DeliveryStatusResponse | | Balance | getBalance | Get current account balance | - | BalanceResponse | | Returns | createReturnRequest | Create a return request | CreateReturnRequestRequest | CreateReturnRequestResponse | | | getReturnRequest | Get a single return request | id: number | GetReturnRequestResponse | | | getReturnRequests | Get all return requests | - | GetReturnRequestsResponse[] | | Payments | getPayments | Get all payments | - | GetPaymentsResponse | | | getPayment | Get payment with consignments | paymentId: number | GetPaymentResponse | | Police Stations | getPoliceStations | Get all police stations | - | PoliceStation[] |

Webhook Utilities Table

| Utility | Description | Framework | Returns | | -------------------------------------- | ---------------------------------- | --------- | ----------------------------------- | | createSteadfastExpressWebhookHandler | Express.js middleware for webhooks | Express | (req, res, next) => Promise<void> | | createSteadfastFastifyWebhookHandler | Fastify route handler for webhooks | Fastify | (req, reply) => Promise<void> | | createSteadfastGenericWebhookHandler | Generic handler for any framework | Any | (req, res) => Promise<void> | | SteadfastWebhookHandler | Core webhook handler class | Any | Class instance |

Webhook Handler Methods

| Method | Description | Parameters | Returns | | ------------------ | ---------------------------------------- | ---------------------------------------- | -------------------------- | | handle | Process webhook payload | body: unknown, authHeader?: string | Promise<WebhookResponse> | | onDeliveryStatus | Set handler for delivery status webhooks | handler: (payload) => void | void | | onTrackingUpdate | Set handler for tracking update webhooks | handler: (payload) => void | void | | on | Listen to webhook events (EventEmitter) | event: SteadfastWebhookEvent, listener | this |

Error Classes Table

| Error Class | Description | Properties | | ------------------------------ | ----------------------------------------- | --------------------------------------------------------- | | SteadfastError | Base error class for all Steadfast errors | message: string, statusCode?: number, code?: string | | SteadfastApiError | API request/response errors | message: string, statusCode: number, response?: unknown | | SteadfastValidationError | Input validation errors | message: string, field?: string | | SteadfastAuthenticationError | Authentication errors | message: string | | SteadfastWebhookError | Webhook processing errors | message: string |

Type Definitions & Enums

| Category | Name | Description | | ------------------ | ---------------------------------- | --------------------------------------------------------------------------------------------------------- | | Enums | SteadfastWebhookNotificationType | Webhook notification types (DELIVERY_STATUS, TRACKING_UPDATE) | | | SteadfastWebhookEvent | Webhook event names (WEBHOOK, DELIVERY_STATUS, TRACKING_UPDATE, ERROR) | | | SteadfastWebhookDeliveryStatus | Delivery status values for webhooks (PENDING, DELIVERED, PARTIAL_DELIVERED, CANCELLED, UNKNOWN) | | | DeliveryStatus | Delivery status values (PENDING, DELIVERED, CANCELLED, etc.) | | | ReturnStatus | Return request status values (PENDING, APPROVED, COMPLETED, etc.) | | | DeliveryType | Delivery type values (HOME_DELIVERY, POINT_DELIVERY) | | Request Types | CreateOrderRequest | Order creation request payload | | | CreateReturnRequestRequest | Return request creation payload | | Response Types | CreateOrderResponse | Order creation response | | | DeliveryStatusResponse | Delivery status response | | | BalanceResponse | Balance check response | | | WebhookResponse | Webhook processing response | | Webhook Types | DeliveryStatusWebhook | Delivery status webhook payload | | | TrackingUpdateWebhook | Tracking update webhook payload | | | WebhookPayload | Union type for all webhook payloads |

Validation Utilities

| Function | Description | Parameters | Throws | | -------------------------- | ---------------------------------------------------------------- | ----------------------------------- | -------------------------- | | validateInvoice | Validate invoice format (alpha-numeric with hyphens/underscores) | invoice: string | SteadfastValidationError | | validateRecipientName | Validate recipient name (max 100 chars) | name: string | SteadfastValidationError | | validateRecipientAddress | Validate recipient address (max 250 chars) | address: string | SteadfastValidationError | | validatePhoneNumber | Validate phone number (11 digits) | phone: string, fieldName?: string | SteadfastValidationError | | validateCodAmount | Validate COD amount (>= 0) | amount: number | SteadfastValidationError | | validateEmail | Validate email format (optional) | email: string \| undefined | SteadfastValidationError |

Webhook Utility Functions

| Function | Description | Parameters | Returns | | ------------------------- | ------------------------------------------------ | ---------------------------------------------- | ---------------------------------- | | extractBearerToken | Extract Bearer token from Authorization header | authHeader: string \| undefined \| null | string | | verifyBearerToken | Verify Bearer token using timing-safe comparison | receivedToken: string, expectedToken: string | boolean | | parseWebhookPayload | Parse and validate webhook payload | data: unknown | WebhookPayload | | createSuccessResponse | Create webhook success response | - | WebhookSuccessResponse | | createErrorResponse | Create webhook error response | message: string | WebhookErrorResponse | | isDeliveryStatusWebhook | Type guard for delivery status webhooks | payload: WebhookPayload | payload is DeliveryStatusWebhook | | isTrackingUpdateWebhook | Type guard for tracking update webhooks | payload: WebhookPayload | payload is TrackingUpdateWebhook |

API Reference

Orders

Create Single Order

const order = await client.orders.createOrder({
  invoice: 'INV-12345', // Required: Unique invoice ID
  recipient_name: 'John Doe', // Required: Max 100 characters
  recipient_phone: '01234567890', // Required: 11 digits
  recipient_address: '123 Main St, Dhaka-1209', // Required: Max 250 characters
  cod_amount: 1000, // Required: Must be >= 0
  alternative_phone: '01987654321', // Optional: 11 digits
  recipient_email: '[email protected]', // Optional
  note: 'Delivery instructions', // Optional
  item_description: 'Electronics', // Optional
  total_lot: 1, // Optional
  delivery_type: 0, // Optional: 0 = home delivery, 1 = point delivery
});

Create Bulk Orders

const orders = [
  {
    invoice: 'INV-001',
    recipient_name: 'John Doe',
    recipient_phone: '01234567890',
    recipient_address: '123 Main St',
    cod_amount: 1000,
  },
  {
    invoice: 'INV-002',
    recipient_name: 'Jane Smith',
    recipient_phone: '01987654321',
    recipient_address: '456 Oak Ave',
    cod_amount: 2000,
  },
];

const results = await client.orders.createBulkOrders(orders);
// Maximum 500 orders per request

Status

Get Status by Consignment ID

const status = await client.status.getStatusByConsignmentId(1424107);

Get Status by Invoice

const status = await client.status.getStatusByInvoice('INV-12345');

Get Status by Tracking Code

const status = await client.status.getStatusByTrackingCode('15BAEB8A');

Balance

const balance = await client.balance.getBalance();

Returns

Create Return Request

const returnRequest = await client.returns.createReturnRequest({
  consignment_id: 1424107, // Or use invoice or tracking_code
  reason: 'Customer requested return',
});

Get Return Request

const returnRequest = await client.returns.getReturnRequest(1);

Get All Return Requests

const returnRequests = await client.returns.getReturnRequests();

Payments

Get All Payments

const payments = await client.payments.getPayments();

Get Single Payment with Consignments

const payment = await client.payments.getPayment(1);

Police Stations

const policeStations = await client.policeStations.getPoliceStations();

Webhook Integration

The SDK provides comprehensive webhook handling utilities to help you build webhook endpoints quickly.

Express.js Example

Recommended: Use handler instance directly

import express from 'express';
import { SteadfastWebhookHandler } from 'steadfast-courier/webhooks';

const app = express();
app.use(express.json());

// Create handler instance and set up callbacks
const webhookHandler = new SteadfastWebhookHandler({
  apiKey: 'your-api-key',
});

webhookHandler.onDeliveryStatus(async (payload) => {
  console.log('Delivery status updated:', payload);
  // Handle delivery status update
  // e.g., update database, send notification, etc.
});

webhookHandler.onTrackingUpdate(async (payload) => {
  console.log('Tracking updated:', payload);
  // Handle tracking update
});

// Use the handler directly as Express route handler
// Note: We use app.post() instead of app.use() because:
// - Webhooks are POST requests only (not GET, PUT, DELETE, etc.)
// - app.post() handles only POST requests to this specific path
// - app.use() would handle ALL HTTP methods, which is unnecessary and less secure
app.post('/steadfast-webhook', webhookHandler.express());

Why app.post() instead of app.use()?

  • app.post('/path', handler) - Handles only POST requests to that specific path
  • app.use('/path', handler) - Handles ALL HTTP methods (GET, POST, PUT, DELETE, etc.) to that path and sub-paths

For webhooks, you want to:

  • ✅ Only accept POST requests (webhooks are POST-only)
  • ✅ Handle a specific endpoint (not all routes)
  • ✅ Reject other HTTP methods (security best practice)

If you use app.use('/steadfast-webhook', ...), it would also respond to GET, PUT, DELETE requests, which is unnecessary and potentially a security issue.

If you really need app.use() (e.g., for a prefix that handles multiple routes), you can:

// This would handle POST /webhooks/steadfast, POST /webhooks/other, etc.
app.use('/webhooks', (req, res, next) => {
  if (req.method === 'POST' && req.path === '/steadfast') {
    return webhookHandler.express()(req, res, next);
  }
  next();
});

But for a single webhook endpoint, app.post() is the recommended approach.

Alternative: Using adapter function

import express from 'express';
import { createSteadfastExpressWebhookHandler } from 'steadfast-courier/webhooks';

const app = express();
app.use(express.json());

// Simple usage without callbacks
const webhookHandler = createSteadfastExpressWebhookHandler({
  apiKey: 'your-api-key',
});

app.post('/steadfast-webhook', webhookHandler);

Fastify Example

Recommended: Use handler instance directly

import Fastify from 'fastify';
import { SteadfastWebhookHandler } from 'steadfast-courier/webhooks';

const fastify = Fastify();

// Create handler instance and set up callbacks
const webhookHandler = new SteadfastWebhookHandler({
  apiKey: 'your-api-key',
});

webhookHandler.onDeliveryStatus(async (payload) => {
  console.log('Delivery status updated:', payload);
});

// Use the handler directly as Fastify route handler
fastify.post('/steadfast-webhook', webhookHandler.fastify());

Alternative: Using adapter function

import Fastify from 'fastify';
import { createSteadfastFastifyWebhookHandler } from 'steadfast-courier/webhooks';

const fastify = Fastify();

const webhookHandler = createSteadfastFastifyWebhookHandler({
  apiKey: 'your-api-key',
});

fastify.post('/steadfast-webhook', webhookHandler);
```typescript
import Fastify from 'fastify';
import { createSteadfastFastifyWebhookHandler } from 'steadfast-courier/webhooks';

const fastify = Fastify();

const webhookHandler = createSteadfastFastifyWebhookHandler({
  apiKey: 'your-api-key',
});

fastify.post('/webhook', webhookHandler);

Generic Framework Example

Recommended: Use handler instance directly

import { SteadfastWebhookHandler } from 'steadfast-courier/webhooks';

// Create handler instance and set up callbacks
const webhookHandler = new SteadfastWebhookHandler({
  apiKey: 'your-api-key',
});

webhookHandler.onDeliveryStatus(async (payload) => {
  console.log('Delivery status updated:', payload);
});

// Use with any framework
app.post('/steadfast-webhook', async (req, res) => {
  await webhookHandler.generic()(req, res);
});

Alternative: Using adapter function

import { createSteadfastGenericWebhookHandler } from 'steadfast-courier/webhooks';

const handler = createSteadfastGenericWebhookHandler({
  apiKey: 'your-api-key',
});

// Use with any framework
app.post('/steadfast-webhook', async (req, res) => {
  await handler(req, res);
});
```typescript
import { createSteadfastGenericWebhookHandler } from 'steadfast-courier/webhooks';

const handler = createSteadfastGenericWebhookHandler({
  apiKey: 'your-api-key',
});

// Use with any framework
app.post('/webhook', async (req, res) => {
  await handler(req, res);
});

Manual Webhook Handling

import { SteadfastWebhookHandler, SteadfastWebhookEvent } from 'steadfast-courier/webhooks';

const handler = new SteadfastWebhookHandler({
  apiKey: 'your-api-key',
});

// Set up event listeners using SteadfastWebhookEvent enum
handler.on(SteadfastWebhookEvent.WEBHOOK, (payload) => {
  console.log('Received webhook:', payload);
});

handler.on(SteadfastWebhookEvent.DELIVERY_STATUS, (payload) => {
  console.log('Delivery status:', payload);
});

handler.on(SteadfastWebhookEvent.TRACKING_UPDATE, (payload) => {
  console.log('Tracking update:', payload);
});

handler.on(SteadfastWebhookEvent.ERROR, (error) => {
  console.error('Webhook error:', error);
});

// Process webhook
const result = await handler.handle(request.body, request.headers.authorization);

if (result.status === 'success') {
  // Webhook processed successfully
} else {
  // Handle error
  console.error(result.message);
}

Webhook Events

The SteadfastWebhookHandler emits events that you can listen to using the SteadfastWebhookEvent enum:

  • SteadfastWebhookEvent.WEBHOOK - Emitted for any Steadfast webhook payload after successful parsing and authentication
  • SteadfastWebhookEvent.DELIVERY_STATUS - Emitted when a delivery status update webhook is received from Steadfast
  • SteadfastWebhookEvent.TRACKING_UPDATE - Emitted when a tracking update webhook is received from Steadfast
  • SteadfastWebhookEvent.ERROR - Emitted when an error occurs during Steadfast webhook processing
import { SteadfastWebhookHandler, SteadfastWebhookEvent } from 'steadfast-courier/webhooks';

const handler = new SteadfastWebhookHandler({ apiKey: 'your-api-key' });

// Listen to all webhooks
handler.on(SteadfastWebhookEvent.WEBHOOK, (payload) => {
  console.log('Any Steadfast webhook received:', payload);
});

// Listen to specific webhook types
handler.on(SteadfastWebhookEvent.DELIVERY_STATUS, (payload) => {
  // payload is typed as DeliveryStatusWebhook
  console.log('Status:', payload.status);
  console.log('COD Amount:', payload.cod_amount);
});

handler.on(SteadfastWebhookEvent.TRACKING_UPDATE, (payload) => {
  // payload is typed as TrackingUpdateWebhook
  console.log('Tracking message:', payload.tracking_message);
});

// Handle errors
handler.on(SteadfastWebhookEvent.ERROR, (error) => {
  console.error('Steadfast webhook processing error:', error);
});

Webhook Payload Types

The SDK provides TypeScript types for webhook payloads:

import type {
  DeliveryStatusWebhook,
  TrackingUpdateWebhook,
  WebhookPayload,
} from 'steadfast-courier';
import { SteadfastWebhookDeliveryStatus } from 'steadfast-courier';

// Type-safe webhook handling
handler.onDeliveryStatus((payload: DeliveryStatusWebhook) => {
  // payload is fully typed
  console.log(payload.consignment_id);
  console.log(payload.cod_amount);

  // payload.status is typed as SteadfastWebhookDeliveryStatus enum
  console.log(payload.status); // Type: SteadfastWebhookDeliveryStatus

  // Use enum for type-safe comparisons
  if (payload.status === SteadfastWebhookDeliveryStatus.DELIVERED) {
    console.log('Order delivered!');
  } else if (payload.status === SteadfastWebhookDeliveryStatus.CANCELLED) {
    console.log('Order cancelled');
  }

  // Available enum values:
  // - SteadfastWebhookDeliveryStatus.PENDING
  // - SteadfastWebhookDeliveryStatus.DELIVERED
  // - SteadfastWebhookDeliveryStatus.PARTIAL_DELIVERED
  // - SteadfastWebhookDeliveryStatus.CANCELLED
  // - SteadfastWebhookDeliveryStatus.UNKNOWN
});

Error Handling

The SDK provides custom error classes for better error handling:

import {
  SteadfastError,
  SteadfastApiError,
  SteadfastValidationError,
  SteadfastAuthenticationError,
} from 'steadfast-courier';

try {
  await client.orders.createOrder(orderData);
} catch (error) {
  if (error instanceof SteadfastValidationError) {
    console.error('Validation error:', error.message);
    console.error('Field:', error.field);
  } else if (error instanceof SteadfastApiError) {
    console.error('API error:', error.message);
    console.error('Status code:', error.statusCode);
  } else if (error instanceof SteadfastError) {
    console.error('Steadfast error:', error.message);
  }
}

TypeScript Support

The SDK is written in TypeScript and provides full type definitions.

Module Resolution

If you encounter module resolution errors when importing from 'steadfast-courier/webhooks', ensure your tsconfig.json uses one of these moduleResolution settings:

  • "node16" (recommended for Node.js projects)
  • "nodenext" (recommended for modern Node.js projects)
  • "bundler" (recommended for bundler-based projects)

Example tsconfig.json:

{
  "compilerOptions": {
    "moduleResolution": "node16"
    // ... other options
  }
}

Type Definitions

The SDK provides full type definitions:

import type {
  CreateOrderRequest,
  CreateOrderResponse,
  DeliveryStatusResponse,
  WebhookPayload,
} from 'steadfast-courier';

// All types are exported and available
const orderRequest: CreateOrderRequest = {
  // TypeScript will autocomplete and validate
};

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Lint
npm run lint

# Format code
npm run format

# Generate documentation
npm run docs

License

MIT

Support

For API documentation and support, please visit the Steadfast Courier Portal.