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

garde-fou

v0.1.1

Published

Protective wrappers around paid API clients with quotas & duplicate detection

Readme

garde-fou (TypeScript/JavaScript)

npm version License: MIT

garde-fou is a lightweight guard for protecting against accidental over-usage of paid API calls. It provides call counting and duplicate detection to help you avoid unexpected API bills.

Features

  • Call counting - Set maximum number of calls and get warnings or exceptions when exceeded
  • Duplicate detection - Detect and handle repeated identical API calls
  • Flexible violation handling - Choose to warn, raise exceptions, or use custom handlers
  • Configuration support - Load settings from JSON/YAML files or set programmatically
  • Async support - Works with both synchronous and asynchronous functions
  • TypeScript support - Full TypeScript definitions included

Installation

npm install garde-fou
# or
yarn add garde-fou

Quick Start

import { GardeFou } from 'garde-fou';

// Protect any function with call limits
const guard = new GardeFou({ max_calls: 5, on_violation_max_calls: 'warn' });

// Instead of: result = expensiveApiCall("query")
// Use: result = guard.call(expensiveApiCall, "query")
const result = guard.call(yourApiFunction, "your", "arguments");

Usage Examples

Basic Call Limiting

import { GardeFou, QuotaExceededError } from 'garde-fou';

// Create a guard with a 3-call limit
const guard = new GardeFou({ max_calls: 3, on_violation_max_calls: 'raise' });

try {
  for (let i = 0; i < 5; i++) {
    const result = guard.call(apiCall, `query ${i}`);
  }
} catch (error) {
  if (error instanceof QuotaExceededError) {
    console.log('Call limit exceeded!');
  }
}

Duplicate Call Detection

// Warn on duplicate calls
const guard = new GardeFou({ on_violation_duplicate_call: 'warn' });

guard.call(apiCall, 'hello');  // First call - OK
guard.call(apiCall, 'hello');  // Duplicate - Warning logged
guard.call(apiCall, 'world');  // Different call - OK

Async Function Protection

const guard = new GardeFou({ max_calls: 3, on_violation_max_calls: 'raise' });

try {
  const result1 = await guard.callAsync(asyncApiCall, 'query 1');
  const result2 = await guard.callAsync(asyncApiCall, 'query 2');
  const result3 = await guard.callAsync(asyncApiCall, 'query 3');
  const result4 = await guard.callAsync(asyncApiCall, 'query 4'); // Throws
} catch (error) {
  console.log('Async call limit exceeded!');
}

Using Profiles

import { Profile } from 'garde-fou';

// Create a profile with multiple rules
const profile = new Profile({
  max_calls: 10,
  on_violation_max_calls: 'raise',
  on_violation_duplicate_call: 'warn'
});

const guard = new GardeFou({ profile });

Configuration Files

// Load from JSON/YAML file
const profile = new Profile({ config: 'gardefou.config.json' });
const guard = new GardeFou({ profile });

// Or pass config as object
const config = { max_calls: 5, on_violation_max_calls: 'warn' };
const profile2 = new Profile({ config });

Custom Violation Handlers

const customHandler = (profile) => {
  console.log(`Custom violation! Call count: ${profile.call_count}`);
  // Send alert, log to service, etc.
};

const guard = new GardeFou({ 
  max_calls: 5, 
  on_violation_max_calls: customHandler 
});

Configuration Options

  • max_calls: Maximum number of calls allowed (-1 for unlimited)
  • on_violation_max_calls: Handler when call limit exceeded ('warn', 'raise', or function)
  • on_violation_duplicate_call: Handler for duplicate calls ('warn', 'raise', or function)
  • on_violation: Default handler for all violations

API Reference

GardeFou Class

Constructor

new GardeFou(options?: {
  profile?: Profile;
  max_calls?: number;
  on_violation?: ViolationHandler;
  on_violation_max_calls?: ViolationHandler;
  on_violation_duplicate_call?: ViolationHandler;
})

Methods

  • call<T>(fn: T, ...args): ReturnType<T> - Execute a synchronous function with protection
  • callAsync<T>(fn: T, ...args): Promise<ReturnType<T>> - Execute an async function with protection

Profile Class

Constructor

new Profile(options?: {
  config?: string | ProfileConfig;
  max_calls?: number;
  on_violation?: ViolationHandler;
  on_violation_max_calls?: ViolationHandler;
  on_violation_duplicate_call?: ViolationHandler;
})

Types

type ViolationHandler = 'warn' | 'raise' | ((profile: Profile) => void);

interface ProfileConfig {
  max_calls?: number;
  on_violation?: ViolationHandler;
  on_violation_max_calls?: ViolationHandler;
  on_violation_duplicate_call?: ViolationHandler;
}

How It Works

garde-fou works by wrapping your function calls. Instead of calling your API function directly, you call it through the guard:

// Before
const result = openai.chat.completions.create({ messages: [...] });

// After  
const guard = new GardeFou({ max_calls: 10 });
const result = guard.call(openai.chat.completions.create, { messages: [...] });

The guard tracks calls and enforces your configured rules before executing the actual function.

Development

# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

# Run example
npm run build && node examples/example.js

Contributing

This is part of the multi-language garde-fou toolkit. See the main repository for contributing guidelines.

License

MIT