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

@capibara-dev/sdk

v0.3.0

Published

SDK TypeScript officiel Capibara for Developers — defineApp + constructeurs typés du Kit (générés depuis les schémas de la plateforme), façades typées, harnais de test local (@capibara-dev/sdk/testing), client API publique, aides OAuth (PKCE), vérificatio

Readme

@capibara-dev/sdk

SDK TypeScript officiel Capibara for Developers — zéro dépendance, compatible Node ≥ 18, navigateurs et workers (fetch + WebCrypto).

Documentation complète : https://capibara.fr/dev/docs (versions Markdown brut et llms.txt disponibles pour vos outils IA).

Installation

npm install -D @capibara-dev/sdk

Sans accès au registre npm, le tarball servi par le portail fait la même chose : curl -O https://capibara.fr/dev-sdk/capibara-dev-sdk-0.3.0.tgz && npm install -D ./capibara-dev-sdk-0.3.0.tgz.

Dans la sandbox Capibara, @capibara-dev/sdk est fourni par la plateforme (même API) : le paquet sert au typage, aux tests locaux et au backend externe.

Contenu

  • Types générés depuis les schémas de la plateforme (generated.ts, ne s'édite pas) : un type par composant du Kit (KitStackNode, KitTableNode, KitFieldNode…), les propriétés de chaque constructeur (KitTextProps…), le catalogue des scopes (APP_SCOPES, AppScope), les façades typées (AppApi, APP_FACADE_NAMES, CrmContactsListInput…), les événements (APP_EVENTS), les capabilities, les catégories et les surfaces. Un test anti-dérive dans la CI de Capibara garantit qu'ils correspondent exactement au validateur du portail.
  • defineApp + ui — le contrat du code hébergé : export default defineApp({ pages, widgets, panels, forms, siteBlocks, sitePages, actions, events, schedules, http }) (siteBlocks/sitePages = surfaces du site public : viewer null, visiteur dans visitor), les constructeurs typés ui.<composant>(props, children), ui.doc, ui.ref, ui.each, ui.fallback, et les aides toast(), navigate(), json(), text().
  • @capibara-dev/sdk/testing — le harnais de test local : createTestContext() (KV, collections, fichiers, fetch et façades simulés en mémoire, journal), renderSurface(), runAction(), runEvent(), runSchedule(), runHttp(), et des assertions sur le Kit rendu (findNodes, hasText, kitStrings).
  • Backend externeCapibaraClient (API publique : me(), install(installId) → façades typées, facades()), aides OAuth PKCE, verifyWebhookSignature() et createServerHandler() (vérification de signature + dispatch des webhooks par type d'événement).
  • Types du manifeste add-on.json (AddonManifest, AddonCapability, AddonPermission, AddonPricing…) — la validation autoritaire reste celle du portail.
  • Moteurs gardés (DV-5) — ctx.mail.send (e-mail transactionnel en blocs à des personnes LIÉES à l'organisation, ≤ 5, quota par jour), ctx.notify.user / permission / admins, ctx.calendar.project / remove / clear, ctx.search.index / remove / clear, ctx.approvals.request / get / cancel (décision livrée par l'événement approval.decided). Capabilities mail.send, notify.send, calendar.project, search.index, approvals.request. Le harnais les simule (t.mails, t.notifications, t.calendar, t.searchDocs, t.approvals, t.decideApproval(id, 'APPROVED')).

Exemples

import { defineApp, ui, toast } from '@capibara-dev/sdk';

export default defineApp({
  pages: {
    home: async ({ ctx }) => ui.doc(ui.stack({ gap: 'md' }, [
      ui.pageHeader({ title: `Bonjour ${ctx.viewer?.name ?? 'vous'}` }),
      ui.kpi({ label: 'Compteur', value: (await ctx.kv.get<number>('count')) ?? 0 }),
      ui.button({ label: '+1', action: 'count.add' }),
    ])),
  },
  actions: {
    'count.add': async ({ ctx }) => {
      const n = ((await ctx.kv.get<number>('count')) ?? 0) + 1;
      await ctx.kv.put('count', n);
      return { ...toast(`Compteur : ${n}`, 'success'), refresh: true };
    },
  },
});
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { createTestContext, renderSurface, runAction, hasText } from '@capibara-dev/sdk/testing';
import app from '../src/index';

test('le compteur s\'incrémente', async () => {
  const t = createTestContext({ viewer: { name: 'Léa' } });
  assert.equal(hasText(await renderSurface(app, 'page', 'home', t), 'Bonjour Léa'), true);
  await runAction(app, 'count.add', t);
  assert.equal(t.kv.get('count'), 1);
});
// Moteurs : un e-mail lié, une validation humaine, la décision en retour.
export default defineApp({
  actions: {
    'refund.ask': async ({ ctx, params }) => {
      await ctx.mail.send({
        to: [{ partyId: params.partyId }],
        subject: 'Votre demande de remboursement',
        blocks: [{ type: 'text', text: 'Nous l’examinons et revenons vers vous.' }, { type: 'button', label: 'Suivre', href: '/apps/mon-app/retours' }],
      });
      await ctx.approvals.request({ subject: 'refund', subjectId: params.orderId, title: `Rembourser ${params.amount} € ?`, approver: { resource: 'billing-fr', action: 'write' } });
      return toast('Demande envoyée', 'success');
    },
  },
  events: {
    'approval.decided': async ({ ctx, event }) => {
      if (event.data.decision === 'APPROVED') await ctx.notify.admins({ title: `Remboursement ${event.data.subjectId} approuvé` });
    },
  },
});
import { createServerHandler } from '@capibara-dev/sdk';

// Backend externe : un seul endpoint, la signature est vérifiée sur le corps BRUT.
const webhooks = createServerHandler({
  secret: process.env.CAPIBARA_WEBHOOK_SECRET!,
  handlers: {
    'invoice.paid': async ({ tenantId, data }) => { /* … */ },
  },
});
export default { fetch: (req: Request) => webhooks.fetch(req) };
import { CapibaraClient } from '@capibara-dev/sdk';

const capibara = new CapibaraClient({ token: process.env.CAPIBARA_API_KEY! });
const contacts = await capibara.install(installId).crm.contacts.list({ limit: 20 });

Backend externe (createBackend)

import { createBackend, defineApp, ui, CapibaraClient } from '@capibara-dev/sdk';

const app = defineApp({ pages: { home: () => ui.text({ markdown: 'Rendu depuis mon serveur.' }) } });
const backend = createBackend({
  app,
  secret: process.env.CAPIBARA_BACKEND_SECRET!,                                  // portail › Code › « Backend externe »
  capibara: new CapibaraClient({ token: process.env.CAPIBARA_API_KEY! }),        // ctx.capibara.* via l'API publique
});
export default { fetch: (req: Request) => backend.fetch(req) };                 // ou backend.handle(rawBody, headers)

Le manifeste déclare backend: { url } (sans main) ; Capibara envoie les requêtes du protocole signées (x-capibara-signature: t=…,v1=…, horodatage ≤ 5 min) — createBackend vérifie, dispatche vers defineApp (même sémantique que la sandbox) et renvoie { ok, result, logs }. ctx.kv/data/files/ moteurs sont réservés au code hébergé (refus expliqué).

Versions

  • 0.3.0createBackend (backend externe : signature horodatée t=…,v1=…, dispatch identique au shim, ctx.capibara via CapibaraClient), verifyBackendSignature, createServerHandler({ maxAgeSec }) + WEBHOOK_TIMESTAMP_HEADER, façades billing.documents.payLink / billing.charges.create / billing.charges.get, scopes billing-fr.pos:*, événements sales.document.paid / pos.charge.paid, types de manifeste backend / returnHosts.
  • 0.2.1 — surfaces du site public (siteBlocks, sitePages), visitor dans le contexte et le harnais (createTestContext({ visitor })), types AddonSiteBlockContribution / AddonSitePageContribution, capability ui.site.
  • 0.2.0 — types générés (Kit, scopes, façades, événements), harnais @capibara-dev/sdk/testing, createServerHandler, ui.ref/ui.fallback conformes au Kit.
  • 0.1.0 — types du manifeste recopiés, client API, PKCE, webhooks.