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

@codebucket/puppet-master

v1.0.7

Published

TypeScript client for the Puppet Master HTML-to-PDF API

Downloads

289

Readme

@codebucket/puppet-master

TypeScript client for the Puppet Master HTML-to-PDF server.

The uploaded server code shows that this client talks to a single POST /pdf endpoint, sends a JSON body shaped like { task: ... }, and downloads the generated PDF as a file stream.

Install

npm install @codebucket/puppet-master

Quick Start

import { PuppetMaster } from "@codebucket/puppet-master";

const client = new PuppetMaster({
  baseUrl: process.env.PUPPET_MASTER_BASE_URL!,
  apiKey: process.env.PUPPET_MASTER_API_KEY!,
});

await client.pdf({
  pdfPath: "./invoice.pdf",
  content: `
    <!doctype html>
    <html>
      <body>
        <h1>Invoice</h1>
        <p>Hello from Puppet Master.</p>
      </body>
    </html>
  `,
  pageOptions: {
    waitUntil: "networkidle0",
  },
  pdfOptions: {
    format: "A4",
    printBackground: true,
  },
});

Public API

import {
  PuppetMaster,
  type PuppetMasterClientOptions,
  type PdfTaskOptions,
  type RemotePdfTaskOptions,
  type PageFunctionCall,
} from "@codebucket/puppet-master";

new PuppetMaster(options)

interface PuppetMasterClientOptions {
  baseUrl: string;
  apiKey: string;
}

await client.pdf(task)

type PageFunctionCall =
  | [methodName: string]
  | [methodName: string, args: unknown[]];

interface RemotePdfTaskOptions {
  launchOptions?: Record<string, unknown>;
  pageOptions?: Record<string, unknown>;
  pdfOptions?: Record<string, unknown>;
  otherPageFunctions?: PageFunctionCall[];
  content: string;
}

interface PdfTaskOptions extends RemotePdfTaskOptions {
  pdfPath: string;
}

What The Server Actually Does

Based on the uploaded server code:

  1. POST /pdf receives { task }.
  2. The worker launches Puppeteer with task.launchOptions.
  3. It creates a page and calls page.setContent(task.content, task.pageOptions).
  4. It generates a PDF with page.pdf({ ...task.pdfOptions, path }).
  5. It optionally runs task.otherPageFunctions.
  6. The server downloads the generated file back to the client.

Important caveat:

  • In the current server implementation, otherPageFunctions runs after page.pdf(). That means those calls do not affect the PDF that was already generated.

Wire Format

The client sends this request body to the server:

{
  "task": {
    "content": "<html>...</html>",
    "launchOptions": {},
    "pageOptions": {},
    "pdfOptions": {},
    "otherPageFunctions": [
      ["waitForNetworkIdle", [{ "idleTime": 500 }]]
    ]
  }
}

Notes:

  • pdfPath is local-only. It is where this client writes the downloaded PDF on the caller's machine.
  • The client always sends the x-api-key header.
  • The uploaded server route currently has API-key validation commented out, but the contract still reserves that header.

otherPageFunctions Format

Use an ordered array of page method calls, not an object.

Examples:

const waitForIdle: PageFunctionCall = ["waitForNetworkIdle", [{ idleTime: 500 }]];
const emulateScreen: PageFunctionCall = ["emulateMediaType", ["screen"]];
const bringToFront: PageFunctionCall = ["bringToFront"];

Agent Guidance

If you are generating code with AI:

  1. Install @codebucket/puppet-master.
  2. Import from the package root.
  3. Create one PuppetMaster client with baseUrl and apiKey.
  4. Call only await client.pdf(...) because this package currently exposes only one public method.
  5. Provide content and pdfPath every time.
  6. Model otherPageFunctions as tuple arrays, not as a map or object.
  7. Do not send pdfPath in hand-written HTTP requests to the server; that field is client-side only.

Minimal Agent Example

import { PuppetMaster, type PageFunctionCall } from "@codebucket/puppet-master";

async function renderPdf(html: string, outputPath: string) {
  const otherPageFunctions: PageFunctionCall[] = [
    ["waitForNetworkIdle", [{ idleTime: 500 }]],
  ];

  const client = new PuppetMaster({
    baseUrl: process.env.PUPPET_MASTER_BASE_URL!,
    apiKey: process.env.PUPPET_MASTER_API_KEY!,
  });

  await client.pdf({
    content: html,
    pdfPath: outputPath,
    otherPageFunctions,
  });
}

Machine-Readable Schema

For tooling and agent integration, see schemas/pdf-task-options.schema.json.