这是一个高级主题,用于针对插件注册表构建您自己的软件。如果您只想在 EmDash 站点上安装插件,则不需要这些——在配置中启用注册表并使用管理仪表板即可。
注册表的发现端是一个公开的只读 API。@emdash-cms/registry-client 包对其进行封装,这样您就可以在 EmDash 之外构建插件目录、搜索页面或发布订阅源。客户端可在任何 fetch 可用的地方运行——Node、Workers、浏览器或 Astro 站点。
安装
discovery 子路径没有认证或 OAuth 依赖。安装客户端并固定到确切版本:
npm install @emdash-cms/[email protected]
列出和解析包
以下 Astro 页面列出注册表中的所有插件:
---
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>
链接使用始终存在的 pkg.did。发布者 handle 是尽力而为的,可能不存在,因此不要从中构建 URL。
包详情页通过 DID 和 slug 获取插件,然后获取最新发布:
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 };
}
发现方法
客户端为每个聚合器查询公开一个方法:
searchPackages({ q, capability?, limit?, cursor? })— 自由文本搜索,可选择过滤到声明了给定访问类别的包。返回{ packages, cursor? }。resolvePackage({ handle, slug })— 通过 handle 和 slug 解析包。getPackage({ did, slug })— 通过 DID 和 slug 获取包。listReleases({ did, package, limit?, cursor? })— 包的所有发布,最新版本优先。getLatestRelease({ did, package })— 未撤回的最高发布版本。
处理不可信记录
聚合器是一个不可信的索引,它转发不是自己编写的记录,因此客户端在边界处验证每一条记录。由此产生两条规则:
profile和release字段可以是null。 当转发的记录验证失败时,客户端将其呈现为null而不是让整个调用失败,这样一条格式错误的记录不会清空搜索页面。在读取pkg.profile?.name或latest.release?.artifacts.package之前始终进行空值检查。- 在渲染之前自行验证 URL 方案。 验证检查结构,而不是 URL 安全性——
uri字段可以携带javascript:方案。在将注册表提供的任何 URL 放入href或src之前,应用您自己的http/https许可列表。
非 2xx 响应会抛出 ClientResponseError(从包中重新导出),包含 .error、.description、.status 和 .headers。
按主机兼容性过滤
发布可以在其 requires 块中声明环境要求(EmDash 或 Astro 版本范围)。@emdash-cms/registry-client/env 子路径对其进行评估,这样目录可以标记不会在给定主机上运行的发布:
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");
// 传入 getLatestRelease() 结果。当发布在此主机上运行时,
// 返回的数组为空。
export function envMismatches(latest: ValidatedReleaseView) {
return checkEnvCompatibility(latest.release?.requires, host);
}