Consultando o registro

Nesta página

Este é um tópico avançado para construir seu próprio software contra o registro de plugins. Se você só quer instalar plugins em um site EmDash, não precisa de nada disso — habilite o registro na sua configuração e use o painel de administração.

O lado de descoberta do registro é uma API pública somente leitura. O pacote @emdash-cms/registry-client o encapsula, para que você possa construir um diretório de plugins, uma página de busca ou um feed de releases fora do EmDash. O cliente funciona em qualquer lugar que fetch esteja disponível — Node, Workers, navegador ou um site Astro.

Instalação

O subcaminho discovery não possui dependências de autenticação ou OAuth. Instale o cliente e fixe-o em uma versão exata:

npm install @emdash-cms/[email protected]

Listar e resolver pacotes

A seguinte página Astro lista todos os plugins em um registro:

---
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>

O link usa pkg.did, que sempre está presente. O handle do publicador é de melhor esforço e pode estar ausente, então não construa URLs a partir dele.

Uma página de detalhes do pacote busca um plugin pelo seu DID e slug, depois busca a release mais recente:

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étodos de descoberta

O cliente expõe um método por consulta ao agregador:

  • searchPackages({ q, capability?, limit?, cursor? }) — busca de texto livre, opcionalmente filtrada a pacotes que declaram uma dada categoria de acesso. Retorna { packages, cursor? }.
  • resolvePackage({ handle, slug }) — resolver um pacote a partir de um handle e slug.
  • getPackage({ did, slug }) — buscar um pacote pelo seu DID e slug.
  • listReleases({ did, package, limit?, cursor? }) — todas as releases de um pacote, versão mais recente primeiro.
  • getLatestRelease({ did, package }) — a versão de release mais alta não retirada.

Tratando registros não confiáveis

O agregador é um índice não confiável que retransmite registros que não escreveu, então o cliente valida cada um na fronteira. Duas regras derivam disso:

  • Os campos profile e release podem ser null. Quando um registro retransmitido falha na validação, o cliente o apresenta como null em vez de falhar a chamada inteira, assim um registro malformado não esvazia uma página de busca. Sempre verifique null antes de ler pkg.profile?.name ou latest.release?.artifacts.package.
  • Valide os esquemas de URL você mesmo antes de renderizar. A validação verifica estrutura, não segurança de URL — um campo uri pode conter um esquema javascript:. Aplique sua própria lista de permissão http/https antes de colocar qualquer URL fornecida pelo registro em um href ou src.

Uma resposta não-2xx lança ClientResponseError (re-exportado do pacote), com .error, .description, .status e .headers.

Filtragem por compatibilidade de host

Uma release pode declarar requisitos de ambiente (uma faixa de versão EmDash ou Astro) em seu bloco requires. O subcaminho @emdash-cms/registry-client/env os avalia, para que um diretório possa marcar releases que não funcionarão em um dado host:

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");

// Passe um resultado de getLatestRelease(). O array retornado é vazio quando
// a release funciona neste host.
export function envMismatches(latest: ValidatedReleaseView) {
  return checkEnvCompatibility(latest.release?.requires, host);
}

O que ler a seguir