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

vendure-plugin-capjs

v1.0.2

Published

A Vendure plugin that integrates Cap.js for privacy-focused, lightweight CAPTCHA protection. Provides challenge/redeem endpoints and a guard decorator for protecting GraphQL mutations.

Readme

Capjs Plugin

A Vendure plugin that integrates Cap.js for privacy-focused, lightweight CAPTCHA protection. This plugin provides REST endpoints for challenge creation and redemption, along with a guard decorator for protecting GraphQL mutations.

Features

  • Privacy-focused CAPTCHA: Uses Cap.js proof-of-work challenges instead of tracking-based solutions
  • GraphQL protection: Easily protect any GraphQL mutation with a decorator
  • REST endpoints: /cap/challenge and /cap/redeem endpoints for frontend integration

Installation

npm install vendure-plugin-capjs @cap.js/server

Configuration

Add the plugin to your Vendure config:

import { VendureConfig } from '@vendure/core';
import { CapjsPlugin } from 'vendure-plugin-capjs';

export const config: VendureConfig = {
    // ... other config
    plugins: [
        CapjsPlugin.init({}),
        // ... other plugins
    ],
};

Database Migration

This plugin adds new entities (CapjsChallenges and CapjsToken) to your database. After adding the plugin to your config, you need to generate and run a database migration:

# Generate the migration
npm run migration:generate capjs-plugin

# Run the migration
npm run migration:run

Make sure your Vendure config has migrations enabled:

export const config: VendureConfig = {
    // ... other config
    dbConnectionOptions: {
        // ... other options
        migrations: [/* your migrations */],
        migrationsRun: false, // Set to true to run migrations automatically on startup
    },
};

Usage

REST Endpoints

The plugin exposes two REST endpoints:

Create Challenge

POST /cap/challenge

Returns a new CAPTCHA challenge that the client must solve.

Redeem Challenge

POST /cap/redeem
Content-Type: application/json

{
  "token": "<challenge-token>",
  "solutions": [<solution-numbers>]
}

Validates the solved challenge and returns a token for subsequent API calls.

Protecting GraphQL Mutations

Use the @CapjsValidate() decorator to protect any GraphQL mutation:

import { Mutation, Resolver } from '@nestjs/graphql';
import { CapjsValidate } from 'vendure-plugin-capjs';

@Resolver()
export class MyResolver {
    @Mutation()
    @CapjsValidate()
    async submitForm() {
        // This mutation is protected by CAPTCHA
        // Will throw if x-captcha-token header is missing or invalid
    }
}

Frontend Integration

The client must:

  1. Request a challenge from POST /cap/challenge
  2. Solve the proof-of-work challenge using the @cap.js/widget or @cap.js/vanilla
  3. Submit solutions to POST /cap/redeem to get a validation token
  4. Include the token in the x-captcha-token header for protected GraphQL mutations

Example with the Cap.js widget:

<!-- Load the Cap.js widget script -->
<script src="https://cdn.jsdelivr.net/npm/@cap.js/widget"></script>

<!-- Add the widget to your form -->
<cap-widget id="cap" data-cap-api-endpoint="/cap"></cap-widget>

<script>
    const widget = document.querySelector('#cap');

    widget.addEventListener('solve', function (e) {
        const token = e.detail.token;
        // Include token in your GraphQL request headers
        // headers: { 'x-captcha-token': token }
    });
</script>

For invisible mode (no visible widget):

import Cap from '@cap.js/widget';

const cap = new Cap({
    apiEndpoint: '/cap/',
});

const token = await cap.solve();
// Use token in x-captcha-token header

API Reference

CapjsPlugin

CapjsPlugin.init(options: PluginInitOptions)

Initializes the plugin with the given options.

CapjsValidate Decorator

@CapjsValidate()

Decorator that applies the CapjsGuard to a resolver method. Validates the x-captcha-token header and throws a UserInputError if validation fails.

Error Codes

  • MISSING_CAPTCHA: The x-captcha-token header was not provided
  • INVALID_CAPTCHA: The provided token failed validation

License

MIT