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 🙏

© 2025 – Pkg Stats / Ryan Hefner

caloohpay

v2.1.0

Published

A CLI tool and library to calculate out-of-hours on-call compensation. Works in Node.js and browsers (Next.js, React, etc.)

Downloads

205

Readme

CalOohPay - Calculate Out-of-Hours Pay

TypeScript Node.js PagerDuty npm version License: ISC Buy Me A Coffee

A command-line tool that automates the calculation of out-of-hours (OOH) on-call compensation for engineering teams using PagerDuty schedules.

🚀 What It Does

CalOohPay eliminates the manual work of calculating on-call payments by:

  • Fetching schedule data directly from PagerDuty API
  • Calculating compensation based on weekday vs weekend rates
  • Supporting multiple teams and schedules simultaneously
  • Providing auditable records for payroll processing
  • Handling timezone conversions automatically

The Problem It Solves

In many organizations, engineers get compensated for going on-call outside of working hours. Managers typically spend 5-10 minutes per team each month reconciling on-call rotas for payroll. With multiple teams and distributed locations, this manual process quickly becomes time-consuming and error-prone.

CalOohPay automates this entire process, turning hours of manual work into a single command.

📋 Prerequisites

  • Node.js (v14 or higher)
  • npm or yarn
  • PagerDuty API User Token (How to get one)

🚀 Quick Start

1. Installation

Via npm (Recommended)

npm install -g caloohpay

via npx

No installation required, run directly with npx:

npx caloohpay -r "SCHEDULE_ID"

From Source

git clone https://github.com/lonelydev/caloohpay.git
cd caloohpay
npm install
npm run build
npm link

2. Configuration

Create a .env file in the project root:

# .env
API_TOKEN=your_pagerduty_api_token_here

3. Basic Usage

CLI Usage

# Get help
caloohpay --help

# Calculate payments for a single schedule (previous month)
caloohpay -r "PQRSTUV"

# Calculate for multiple schedules with custom date range
caloohpay -r "PQRSTUV,PSTUVQR" -s "2024-01-01" -u "2024-01-31"

Programmatic Usage

CalOohPay can be used as a library in both Node.js and browser environments.

Node.js (with file system access and PagerDuty API):

import { ConfigLoader, OnCallPaymentsCalculator } from 'caloohpay';

const loader = new ConfigLoader();
const rates = loader.loadRates();
const calculator = new OnCallPaymentsCalculator(rates.weekdayRate, rates.weekendRate);

Browser/Web Applications (Next.js, React, Vue, etc.):

import { OnCallUser, OnCallPeriod, OnCallPaymentsCalculator } from 'caloohpay/core';

// Create on-call periods from your data
const user = new OnCallUser('user-id', 'John Doe', [
  new OnCallPeriod(
    new Date('2024-08-01T18:00:00Z'),
    new Date('2024-08-05T09:00:00Z'),
    'Europe/London'
  )
]);

// Calculate with custom rates
const calculator = new OnCallPaymentsCalculator(60, 90);
const amount = calculator.calculateOnCallPayment(user);
console.log(`Compensation: $${amount}`);

📚 View Full API Documentation →

🌐 Browser Compatibility (New in v2.1.0)

CalOohPay now works in web browsers! The core calculation engine is completely independent of Node.js.

Package Structure

// 🌐 Browser-compatible core (zero Node.js dependencies)
import { OnCallPaymentsCalculator, OnCallUser, OnCallPeriod, DEFAULT_RATES } from 'caloohpay/core';

// 🖥️ Node.js-specific features (ConfigLoader, CsvWriter, PagerDuty API)
import { ConfigLoader, CsvWriter, calOohPay } from 'caloohpay/node';

// 📦 Everything (backward compatible, Node.js only)
import { ConfigLoader, OnCallPaymentsCalculator } from 'caloohpay';

Next.js / React Example

'use client'; // Next.js 13+ App Router

import { useState } from 'react';
import { OnCallPaymentsCalculator, DEFAULT_RATES } from 'caloohpay/core';

export default function CompensationCalculator() {
  const [weekdayRate, setWeekdayRate] = useState(DEFAULT_RATES.weekdayRate);
  const [weekendRate, setWeekendRate] = useState(DEFAULT_RATES.weekendRate);
  
  const calculator = new OnCallPaymentsCalculator(weekdayRate, weekendRate);
  
  // Use calculator.calculateOnCallPayment(user) with your data
  
  return (
    <div>
      <input value={weekdayRate} onChange={(e) => setWeekdayRate(Number(e.target.value))} />
      <input value={weekendRate} onChange={(e) => setWeekendRate(Number(e.target.value))} />
      {/* Your UI here */}
    </div>
  );
}

What works in browsers:

  • ✅ Core calculation engine (OnCallPaymentsCalculator)
  • ✅ Models (OnCallUser, OnCallPeriod)
  • ✅ All constants and types
  • ✅ Date utilities and validation

Node.js only:

  • ❌ ConfigLoader (uses fs module)
  • ❌ CsvWriter (uses fs module)
  • ❌ calOohPay function (uses PagerDuty API)
  • ❌ CLI tools

💰 Compensation Rates

Default Rates

| Period | Rate | |--------|------| | Weekdays (Mon-Thu) | £50 per day | | Weekends (Fri-Sun) | £75 per day |

Customizing Rates

You can customize compensation rates by creating a .caloohpay.json file:

{
  "rates": {
    "weekdayRate": 60,
    "weekendRate": 90,
    "currency": "USD"
  }
}

The tool searches for this file in:

  1. Current working directory (project-specific rates)
  2. Home directory ~/.caloohpay.json (user-wide defaults)
  3. Built-in defaults if no config found

Example config file: .caloohpay.json.example

Development and contributing

Development, testing, contributor workflow and git-hook guidance has moved to CONTRIBUTING.md. Please read that document for detailed setup and contribution instructions, including how to run tests, lint, generate docs, and prepare a pull request.

Note on ESLint configuration: this project uses ESLint v9 with a flat config file located at eslint.config.cjs (instead of legacy .eslintrc.json). If you need to adjust lint rules or add new shareable configs, update eslint.config.cjs and run npm run lint to validate your changes.

🔧 Troubleshooting

Common Issues

"Command not found: caloohpay"

  • Run npm link after building
  • Restart your terminal
  • Check if dist/src/CalOohPay.js exists

"Invalid API Token"

  • Verify your .env file contains the correct token
  • Ensure no extra spaces or quotes around the token
  • Check token permissions in PagerDuty

"No schedule entries found"

  • Verify the schedule ID is correct
  • Check the date range includes on-call periods
  • Ensure you have permissions to view the schedule

📝 Finding Schedule IDs

Schedule IDs can be found in PagerDuty:

  1. Navigate to PeopleOn-Call Schedules
  2. Click on your schedule
  3. The ID is in the URL: https://yourcompany.pagerduty.com/schedules/PQRSTUV

📟 PagerDuty API Setup

To fetch schedule data from PagerDuty, you need an API User Token that provides the same permissions as your user account.

Getting Your API Token

  1. Login to PagerDuty
  2. Navigate to Profile: Hover over your profile icon → My Profile
  3. Access Settings: Go to User Settings
  4. Create Token: Click Create API User Token
  5. Secure Storage: Store the token securely (e.g., 1Password, environment variable)

⚠️ Security Warning: Never commit your API token to version control!

📖 CLI Reference

Quick Reference

caloohpay -r "SCHEDULE_ID" [options]

Common Options:

  • -r, --rota-ids - Schedule ID(s) (required)
  • -s, --since - Start date (YYYY-MM-DD)
  • -u, --until - End date (YYYY-MM-DD)
  • -o, --output-file - Save to CSV file
  • -t, --timeZoneId - Override timezone
  • -k, --key - API token override

Examples:

# Basic usage
caloohpay -r "PQRSTUV"

# Multiple schedules to CSV
caloohpay -r "TEAM_A,TEAM_B" -o "./monthly-report.csv"

# Custom date range
caloohpay -r "PQRSTUV" -s "2024-01-01" -u "2024-01-31"

✅ Current Features

  • PagerDuty Integration: Fetches schedules with automatic timezone detection
  • Multi-Schedule Support: Process multiple schedules simultaneously
  • Configurable Rates: Custom weekday/weekend rates via .caloohpay.json
  • Timezone Support: Accurate OOH calculations for distributed teams
  • CSV Export: Google Sheets compatible payroll files
  • Comprehensive Testing: 328+ unit tests with full coverage

Quick Timezone Example

# Automatic timezone detection (recommended)
caloohpay -r "SCHEDULE_ID"

# Override timezone if needed
caloohpay -r "SCHEDULE_ID" -t "America/New_York"

🚧 Development Roadmap

Recently Completed:

  • ✅ Configurable rates via config file
  • ✅ Full timezone support with automatic detection
  • ✅ CSV export for payroll systems

Coming Soon:

  • Enhanced console output with colors
  • NPM package distribution
  • Automated monthly reporting

📚 Technical References

📄 License

This project is licensed under the ISC License - see the LICENSE file for details.

🤝 Support

If you encounter any issues or have questions:

  1. Check the troubleshooting section
  2. Search existing issues
  3. Create a new issue with detailed information

☕ Sponsor This Project

If CalOohPay has saved you time and made your life easier, consider supporting its development!

Buy Me A Coffee

Your support helps me:

  • 🚀 Continue developing new features
  • 🐛 Fix bugs and improve stability
  • 📚 Maintain documentation
  • 💡 Explore new ideas and integrations

Every coffee counts and is greatly appreciated! ☕


Made with ❤️ for engineering teams who deserve fair compensation for their on-call dedication.