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
profileereleasepodem sernull. Quando um registro retransmitido falha na validação, o cliente o apresenta comonullem vez de falhar a chamada inteira, assim um registro malformado não esvazia uma página de busca. Sempre verifique null antes de lerpkg.profile?.nameoulatest.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
uripode conter um esquemajavascript:. Aplique sua própria lista de permissãohttp/httpsantes de colocar qualquer URL fornecida pelo registro em umhrefousrc.
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
- O registro de plugins — habilitar e usar o registro em um site EmDash
- Empacotamento e publicação — publicar um plugin no registro