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

calligrapho

v0.3.0

Published

Contactual testing server mock

Downloads

18

Readme

Calligrapho - Contract testing server mock

Calligrapho is a library and command line tool that helps you emulate an API server.

When it comes to testing, end-to-end tests are the hardest to write and maintain, while also being the most expensive in terms of resources and execution time. However, E2E are the only tests that can fill us with confidence about the application behaviour, as they closely mimic the real behaviour of the application and of its relationships.

A common scenario to test E2E is a provider-consumer relationship. The consumer is an application that receives a message (HTTP request, queued message, etc) while the producer is the application that sends the message and possibly expects an answer. Tests modelling provider-consumer relationships are either incredibly complex (E2E spectrum) or extensively mocked (Unit spectrum). Contract testing is our middle ground. In contract tests we only tests the data contract between a producer and a consumer, and see whether it still holds.

Calligrapho wants to help you write contract tests. At its core, it's a configurable server. You define a calligrapho.config.ts (or calligrapho.config.js) configuration file and Calligrapho will start full Koa application ready to be used. The benefit here is that you can re-use logic from your own producer service, such as validators, authenticators or random values generators.

But the true strenght of Calligrapho is the ability of generating a calligrapho.config.ts file by querying your consumer service (WIP). While in query mode, Calligrapho will accept an array of AxiosRequestConfig objects exported in a calligrapho.query.ts or calligrapho.query.js file. It will then perform HTTP requests and record the responses, generating a full calligrapho configuration file. Since the responses from the consumer service will be real, your tests against Calligrapho will take the best from unit tests and E2E tests:

From unit tests, you will get the easy setup and performance. Your tests against a Koa application that just returns the values you specified will give you responses in the millisecond mark. Additionally, since no real request will be performed, you will not need to worry about setup and teardown.

From E2E tests, you will get the confidence of using a real set of data against a recently up-to-date service that mimics your consumer application. You will also get a real set of data that is related to your original message.

Contract tests with Calligrapho will allow you to run tests that are close in quality and confidence to E2E at the speed and ease of Unit Tests, while developing. And when you run the tests in the pipeline, you can just query with Calligrapho to generate the latest version of your consumer application responses, de facto transforming your contract tests into full E2E tests.

Installation

# Yarn
yarn add --dev calligrapho

# NPM
npm install --dev calligrapho

You are all set!

Usage

Calligrapho Configuration

You can import the CalligraphoConfiguration interface exposes in calligrapho/types. All keys are optional, but a configuration without a routes object will be quite pointless as the Koa application will only answer with a prefigured "Hello World" route.

/**
 * Calligrapho runtime configuration
 */
export interface CalligraphoConfiguration {
  /**
   * Defines the list of routes to be used by Calligrapho.
   * See `CalligraphoRoute` for details
   */
  routes: CalligraphoRoute<unknown>[];

  /** Koa binding port number */
  port: number;

  /** Koa binding host */
  host: string;

  /** HTTP protocol to be used */
  protocol: 'http' | 'https';
}
/**
 * Represents a CalligraphoRoute
 */
export interface CalligraphoRoute<Output, User = number> {
  /**
   * HTTP path excluding the base url.
   * Defaults to /
   */
  path: string;

  /**
   * HTTP Method.
   * Defaults to GET
   */
  method: CalligraphoSupportedMethod;

  /**
   * Authentication function.
   * Returns a User object or null for anonymous users.
   * Defaults to null.
   */
  auth: (context: Context) => Promise<User | null>;

  /**
   * Validator function.
   * Returns a Promise wrapping any object.
   * Any truthy value will automatically fail the request
   * with HTTP 400, returning the truthy value.
   * Defaults to a function resolving null.
   */
  validator: (values: unknown) => Promise<unknown>;

  /**
   * Generator function.
   * Allows you to specify the status code
   * and the http response body you expect
   * from the route.
   *
   * See CalligraphoContext for details.
   *
   * Defaults to a function returning HTTP 200
   */
  generator: (context: CalligraphoContext<User>) => CalligraphoResponse<Output>;

  /**
   * It represents the starting state of your application.
   * Think of it as the database table associated with the route.
   * For a route handling authentication, it may be helpful
   * defining a list of users here.
   *
   * Defaults to a function returning an empty array.
   */
  startingData: () => Output[],
}
/**
 * Represents the context provided
 * to Generators functions.
 */
export type CalligraphoContext<User = number> = {
  /**
   * A map associating routes to their "database table".
   * Use to CRUD in-memory data.
   */
  db: CalligraphoDB;

  /**
   * Authentication function outcome.
   */
  user: User | null;

  /**
   * Koa.Context including
   * request and response objects.
   */
  context: Context;
};

Programmatic use

You can import the Calligrapho class from calligrapho/server and create an instance yourself. This gives you flexibility should you prefer to run Calligrapho directly in your tests suite.

The Calligrapho class exposes a Calligrapho.events object that subclasses EventEmitter, so you can emit and listen to the following events:

  • calligrapho:start: Triggers calligrapho.start()
  • calligrapho:started: Emitted at the end of calligrapho.start()
  • calligrapho:request: Emitted at the beginning of calligrapho.request()
  • calligrapho:response: Emitted at the end of calligrapho.request()
  • calligrapho:close: Triggers calligrapho.close()
  • calligrapho:closed: Emitted at the end of calligrapho.close()

Listening to events can be helpful while embeding Calligrapho in your test suite, as you will be able to wait for events in your setup and teardown functions.

For a few examples of programmatic use of Calligrapho in a test suite, see some of Calligrapho's functional tests.