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

brind-apiwalker

v0.2.0

Published

Vérifie une API depuis son contrat OpenAPI : exerce chaque route sur un environnement jetable et engendre un rapport par module.

Readme

brind-apiwalker

Exerce chaque route d'une API depuis son contrat OpenAPI, sur un environnement monté pour l'occasion, et écrit un rapport par module : la route, ce qu'elle fait, le rôle exigé, le payload envoyé, la réponse obtenue.

npx brind-apiwalker                # tous les modules
npx brind-apiwalker care-links lab # ceux-là seulement

Rien à installer : npx récupère le paquet, lit verifier.config.ts à la racine du projet, et travaille.

Ce que ça produit

docs/verification/README.md est le document qui résume tout : le compte par module, puis, module par module, ce que chacun propose — une ligne par route, groupées par sujet, avec ce qu'elle a réellement répondu — et enfin les routes en erreur serveur et celles restées hors de portée.

Un fichier par module à côté porte la pièce à conviction : pour chaque route, l'appel exact et la réponse reçue.

Le code de sortie vaut 1 dès qu'une route répond en 5xx, 0 sinon. Une route hors de portée n'est pas un défaut de l'API : elle ne fait pas échouer la vérification, elle est signalée.

Ce qu'il faut lui dire

Une seule chose est vraiment obligatoire : où joindre l'API. Le reste a un défaut raisonnable.

// verifier.config.ts
import type { Configuration } from 'brind-apiwalker';

const config: Configuration = {
  base: 'http://localhost:3000',
  contrat: '/api/docs-json',
};

export default config;

Cela suffit à exercer les routes ouvertes. Les autres exigent un jeton, donc un contexte.

Le contexte : qui est connecté, et quoi désigner

OpenAPI décrit des formes, jamais des données. GET /patients/{patientId} demande un identifiant qui existe — le contrat ne peut pas l'inventer.

contexte: async (base) => ({
  jetons: { PATIENT: '…', DOCTOR: '…', '*': '…' },
  valeurs: { patientId: 'cmt8…', appointmentId: 'cmt9…' },
  journal: ['patient connecté', 'rendez-vous créé'],
}),

La clé * sert de repli quand aucun rôle ne correspond. journal est repris tel quel dans les rapports : ce qui a été préparé, et ce qui a échoué.

Une route dont un paramètre manque au contexte est déclarée hors de portée plutôt qu'exercée à vide — un 404 sur un identifiant inventé n'apprend rien.

Les rôles

OpenAPI dit qu'un jeton est attendu, jamais lequel. Un projet qui déclare ses rôles par décorateur peut les faire lire :

import { rolesDepuisLesSources } from 'brind-apiwalker/adaptateurs/nestjs';

roles: rolesDepuisLesSources({ racine: 'src/modules', defaut: '*' }),

Sans cela, toutes les routes protégées sont servies avec le jeton de repli.

Les noms de paramètres

/pharmacy/{id} désigne une officine, /users/{id} un compte : le nom seul ne le dit pas. Par défaut la clé se dérive du segment qui précède (/pharmacies/{id}pharmacyId). parametre corrige les exceptions.

L'environnement jetable

Rejouer les mêmes appels sur une base qui garde ses traces donne des réponses différentes d'une fois sur l'autre : un identifiant déjà pris répond 409, un créneau déjà réservé aussi. Le rapport ne vaudrait alors que pour l'état de la base au moment où il a été écrit.

import { baseJetable } from 'brind-apiwalker/adaptateurs/base-jetable';

environnement: baseJetable({
  url: process.env.DATABASE_URL!,   // seul le nom de la base change
  migrer: ['npx', 'prisma', 'migrate', 'deploy'],
  semer: ['npx', 'prisma', 'db', 'seed'],
  batir: ['npx', 'nest', 'build'],
  demarrer: [process.execPath, 'dist/src/main.js'],
  sonde: '/api/docs-json',
  port: 3977,
}),

Base créée, migrée, semée, serveur démarré, routes exercées, tout détruit — y compris si la vérification échoue en route.

Cet adaptateur suppose PostgreSQL et un serveur Node. Un projet bâti autrement fournit son propre Environnement : le noyau n'en demande que demarrer et arreter.

.env n'est pas lu tout seul. Un projet qui y range son DATABASE_URL appelle dotenv.config() en tête de sa configuration.

Ce qui précède l'exercice

avant reçoit un nom de module et rend ce qu'on veut voir en tête du rapport — une couverture unitaire, une analyse statique, un numéro de version :

avant: async (module) => couvertureDuModule(module),

Elles sont prises après que toutes les routes ont été exercées : une analyse un peu longue laisserait sinon le serveur patienter, et rien n'y gagnerait en justesse.

Rendre le résumé lisible

Le document de synthèse groupe les routes par sujet, d'après l'URL — establishments, users. Un projet peut leur donner un titre français, et décrire le parcours que ses routes dessinent : cela ne se déduit d'aucun contrat, seul quelqu'un qui connaît le métier le sait.

const PRESENTATIONS = {
  admin: {
    groupes: { establishments: '🏥 Établissements', users: '👥 Utilisateurs' },
    schema: `
      SUPER_ADMIN → Établissements → Admins établissement → Rôles
    `,
  },
};

resume: (module) => PRESENTATIONS[module],

Le schéma est repris tel quel, dans un bloc préformaté. Un dessin en caractères tient dans un fichier versionné, se lit dans un terminal, et se compare d'une version à l'autre — ce qu'aucune image ne fait.

Un module sans entrée n'est pas moins vérifié : son résumé porte les noms que l'URL lui donne, et pas de schéma.

Portée

Le noyau ne suppose ni framework, ni base de données, ni langage côté serveur : il lit un contrat, exerce des routes, écrit des rapports. Toute API qui publie un OpenAPI 3 est vérifiable — ce qui lui est propre passe par sa configuration.

Les adaptateurs (nestjs, base-jetable) sont des commodités, pas des dépendances : un projet peut n'en utiliser aucun.

Ce que ça ne fait pas

Ce n'est pas une suite de tests : rien n'est comparé à un résultat attendu, il n'y a pas d'assertion. C'est un relevé — ce que l'API répond aujourd'hui, route par route, sur des données connues. Il sert à voir ce qui casse, à documenter le comportement réel, et à faire échouer une intégration continue sur une erreur serveur.

En bibliothèque

import { verifier } from 'brind-apiwalker';

const { bilans, code } = await verifier(config, ['care-links']);

Licence

MIT.