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

@infintywab/plugin-sdk

v1.2.0

Published

SDK de développement de plugins pour FasoOrchestra ERP (types AppAPI, classe de base, helpers, contrat de style).

Downloads

32

Readme

@infintywab/plugin-sdk

SDK officiel pour écrire des plugins FasoOrchestra ERP. Fournit le contrat de types complet (AppAPI, Manifest, …), la classe de base ERPPlugin, le helper definePlugin, les constantes (EVENTS, STORE_KEYS, CHANNELS) et le contrat de style (ui, TOKENS).

À l'exécution, le plugin ne charge pas ce code : l'hôte injecte l'AppAPI réelle dans la factory/constructeur. Le SDK n'apporte que des types (effacés au build), une classe de base triviale et des constantes. React reste externe (fourni par l'hôte via window) — voir le contrat de packaging.

Installation

npm i -D @infintywab/plugin-sdk

Build (émet les .d.ts)

npm run build   # → dist/index.js + dist/index.d.ts (+ source maps)

Le package.json expose dist/index.d.ts comme types → autocomplétion complète dans VS Code pour tout projet qui installe le paquet.

Utilisation

import { definePlugin, type AppAPI, ui } from '@infintywab/plugin-sdk'

export const manifest = {
  id: 'my-plugin',
  name: 'Mon plugin',
  version: '1.0.0',
  license: 'MIT',
  permissions: ['tasks:read'],
  dependencies: [],
}

export default definePlugin((app: AppAPI) => ({
  onload() {
    app.registerSidebar([{ label: 'Mon plugin', path: '/mine', icon: 'package', section: 'Modules' }])
    app.registerCommand({ id: 'mine.hello', label: 'Hello', run: () => app.notify(app.t('common.save')) })
    app.navigate('/mine')
    app.log.info('chargé', app.getPermissions())
    const id = setInterval(() => {}, 1000)
    app.addCleanup(() => clearInterval(id))
  },
  onunload() {},
}))

Surface de l'AppAPI

| Domaine | Membres | |---|---| | Identité | pluginId | | UI | registerRoutes, registerSidebar, registerCommand, registerDashboardWidget, registerSettingsSection, navigate | | Notifs | notify, notifications.push/markAllRead | | Réseau | apiGet/Post/Put/Patch/Delete, getQueryClient | | Inter-plugins | events (pipe/on/emit/dispatch), store | | Temps réel | onRealtime(channel, cb) | | i18n | t(key, opts?), getLocale() | | Journalisation | log.debug/info/warn/error | | Permissions | getPermissions(), hasPermission() | | Cycle de vie | addCleanup(fn) | | Contexte | getUser(), getManifest(id) |

Style

Tout plugin repose sur le design system de l'hôte : classes via ui (ui.card, ui.btnPrimary, ui.badgeSuccess, ui.input, ui.metricCard…) et tokens via TOKENS (var(--color-*)). Aucune feuille de style embarquée.


Publication

Le SDK est le contrat entre le shell et tous les plugins. Toute modification de la surface publique (AppAPI, Manifest, constantes) est un événement de version : semver strict, sans exception.

| Changement | Version | |---|---| | Ajout d'une méthode ou d'un champ optionnel | mineure | | Correction sans impact sur la surface | corrective | | Signature modifiée, champ retiré ou rendu obligatoire | majeure |

Publier une version

npm version minor        # met à jour package.json ET crée le tag vX.Y.Z
git push --follow-tags   # déclenche le workflow Release

Le workflow refuse de publier si le tag ne correspond pas à la version du package.json, ou si cette version existe déjà sur le registre. Il vaut mieux échouer à la publication qu'obtenir un paquet dont le numéro ne correspond à aucun commit.

Prérequis, une seule fois

  1. Le scope @infintywab doit exister sur npm et appartenir au compte publiant. Le créer via npm org create infintywab, ou publier sous un autre nom en modifiant le champ name du package.json avant la première publication — un nom publié ne se reprend pas.
  2. Secret NPM_TOKEN dans les paramètres du dépôt (Settings → Secrets and variables → Actions), avec un jeton npm de type Automation — il traverse la double authentification, contrairement à un jeton de publication classique.

--access public est passé explicitement : un paquet scopé est publié en restricted par défaut, ce qui exige un plan payant et le rendrait inaccessible aux consommateurs.

Provenance (optionnel)

Pour attester publiquement le lien entre le paquet et le commit qui l'a produit, ajouter --provenance à l'étape de publication et la permission id-token: write au job. Cela requiert un dépôt public — sur un dépôt privé, la publication échouerait.

Consommateurs

| Dépôt | Usage | |---|---| | InfinityWAB/erp-Orchestra | le shell : kernel, factory et types partagés | | InfinityWAB/branch | module organigramme (frontend/) | | InfinityWAB/xstocks | module stock (frontend/) |

Après une version majeure, prévenir ces dépôts : ils déclarent une plage semver et ne suivront pas automatiquement.

Authentification de la CI — trusted publishing

npm a retiré les jetons Automation classiques de son interface. Les jetons restants (granular access tokens) restent soumis à la double authentification sur les écritures, ce qu'une CI ne peut pas satisfaire — la publication échoue alors en EOTP.

La voie recommandée est le trusted publishing : GitHub émet à chaque exécution un jeton OIDC éphémère, signé, lié au dépôt et au workflow. Aucun secret à stocker ni à faire tourner.

Configuration, une seule fois, sur npmjs.com → page du paquet → Settings → Trusted Publisher → GitHub Actions :

| Champ | Valeur | |---|---| | Organization | InfinityWAB | | Repository | ersdk | | Workflow filename | release.yml | | Allowed actions | npm publish |

Le secret NPM_TOKEN devient alors inutile — supprimez-le, un secret inutilisé reste une surface d'attaque.

Le workflow est déjà prêt : Node 22, npm à jour (≥ 11.5.1) et permission id-token: write.

Amorçage

Le Trusted Publisher se configure dans les réglages du paquet, qui doit donc exister. La toute première version se publie manuellement :

npm login
npm publish --access public --otp=<code>

C'est la seule fois où un code est saisi. Les suivantes passent par la CI.

Si la publication renvoie 404

npm répond 404 au lieu de 403 pour ne pas révéler l'existence d'un scope privé. Causes possibles : l'organisation npm n'existe pas (npm org create infintywab), le jeton ne couvre pas le scope entier — nécessaire pour créer un paquet qui n'existe pas encore —, ou le compte n'est pas membre de l'organisation.