Interroger le registre

Sur cette page

C’est un sujet avancé pour construire votre propre logiciel contre le registre de plugins. Si vous voulez seulement installer des plugins sur un site EmDash, vous n’avez besoin de rien de ceci — activez le registre dans votre configuration et utilisez le panneau d’administration.

Le côté découverte du registre est une API publique en lecture seule. Le package @emdash-cms/registry-client l’encapsule, pour que vous puissiez construire un répertoire de plugins, une page de recherche ou un flux de releases en dehors d’EmDash. Le client fonctionne partout où fetch est disponible — Node, Workers, le navigateur ou un site Astro.

Installation

Le sous-chemin discovery n’a pas de dépendances d’authentification ou OAuth. Installez le client et fixez-le à une version exacte :

npm install @emdash-cms/[email protected]

Lister et résoudre des packages

La page Astro suivante liste tous les plugins dans un registre :

---
import { DiscoveryClient } from "@emdash-cms/registry-client/discovery";

const discovery = new DiscoveryClient({
  aggregatorUrl: "https://registry.emdashcms.com",
});

const { packages } = await discovery.searchPackages({ q: "", limit: 50 });
---

<ul>
  {
    packages.map((pkg) => (
      <li>
        <a href={`/plugins/${pkg.did}/${pkg.slug}`}>
          {pkg.profile?.name ?? pkg.slug}
        </a>
        {pkg.latestVersion && <span>v{pkg.latestVersion}</span>}
        <p>{pkg.profile?.description}</p>
      </li>
    ))
  }
</ul>

Le lien utilise pkg.did, qui est toujours présent. Le handle du publieur est au mieux et peut être absent, ne construisez donc pas d’URLs à partir de celui-ci.

Une page de détail de package récupère un plugin par son DID et slug, puis récupère la dernière release :

import { DiscoveryClient } from "@emdash-cms/registry-client/discovery";

const discovery = new DiscoveryClient({
  aggregatorUrl: "https://registry.emdashcms.com",
});

export async function getPlugin(did: string, slug: string) {
  const pkg = await discovery.getPackage({ did, slug });
  const latest = await discovery.getLatestRelease({
    did: pkg.did,
    package: pkg.slug,
  });
  return { pkg, latest };
}

Méthodes de découverte

Le client expose une méthode par requête d’agrégateur :

  • searchPackages({ q, capability?, limit?, cursor? }) — recherche en texte libre, optionnellement filtrée aux packages déclarant une catégorie d’accès donnée. Retourne { packages, cursor? }.
  • resolvePackage({ handle, slug }) — résoudre un package à partir d’un handle et d’un slug.
  • getPackage({ did, slug }) — récupérer un package par son DID et slug.
  • listReleases({ did, package, limit?, cursor? }) — toutes les releases d’un package, version la plus récente en premier.
  • getLatestRelease({ did, package }) — la version de release la plus élevée non retirée.

Gestion des enregistrements non fiables

L’agrégateur est un index non fiable qui relaie des enregistrements qu’il n’a pas créés, donc le client valide chacun à la frontière. Deux règles en découlent :

  • Les champs profile et release peuvent être null. Quand un enregistrement relayé échoue à la validation, le client le présente comme null plutôt que de faire échouer tout l’appel, ainsi un enregistrement malformé ne vide pas une page de recherche. Vérifiez toujours null avant de lire pkg.profile?.name ou latest.release?.artifacts.package.
  • Validez les schémas d’URL vous-même avant le rendu. La validation vérifie la structure, pas la sécurité des URL — un champ uri peut porter un schéma javascript:. Appliquez votre propre liste d’autorisation http/https avant de mettre toute URL fournie par le registre dans un href ou src.

Une réponse non-2xx lance ClientResponseError (ré-exporté depuis le package), portant .error, .description, .status et .headers.

Filtrage par compatibilité d’hôte

Une release peut déclarer des exigences d’environnement (une plage de version EmDash ou Astro) dans son bloc requires. Le sous-chemin @emdash-cms/registry-client/env les évalue, pour qu’un répertoire puisse signaler les releases qui ne fonctionneront pas sur un hôte donné :

import { checkEnvCompatibility, hostEnvFromVersions } from "@emdash-cms/registry-client/env";
import type { ValidatedReleaseView } from "@emdash-cms/registry-client/discovery";

const host = hostEnvFromVersions("0.17.0", "5.6.0");

// Passez un résultat de getLatestRelease(). Le tableau retourné est vide quand
// la release fonctionne sur cet hôte.
export function envMismatches(latest: ValidatedReleaseView) {
  return checkEnvCompatibility(latest.release?.requires, host);
}

À lire ensuite