插件清单

本页内容

每个沙箱插件都在其 package.json 旁边有一个 emdash-plugin.jsonc。它需要手动编辑,包含插件的身份、信任契约(能力、主机、存储)以及注册表显示的配置文件字段。emdash-plugin init 生成脚手架;CLI 在 builddevvalidatebundlepublish 时自动读取 ./emdash-plugin.jsonc

该文件是 JSONC 格式:允许注释和尾随逗号。

以下示例展示了一个图片画廊插件的完整清单:

{
	"$schema": "./node_modules/@emdash-cms/plugin-cli/schemas/emdash-plugin.schema.json",

	"slug": "gallery",
	"publisher": "did:plc:abc123def456",

	"license": "MIT",
	"author": { "name": "Jane Doe", "url": "https://example.com" },
	"security": { "email": "[email protected]" },

	// 可选配置文件
	"name": "Gallery",
	"description": "EmDash 的图片画廊区块。",
	"keywords": ["gallery", "images"],
	"repo": "https://github.com/example/plugin-gallery",

	// 信任契约
	"capabilities": ["content:read"],
	"allowedHosts": [],
	"storage": {}
}

身份

字段必填备注
slug发布者命名空间内的 URL 安全 ID。/^[a-z][a-z0-9_-]*$/,最多 64 个字符。
publisher你的 Atmosphere 账户的 DID 或句柄。参见发布者固定
version无构建元数据的 Semver 2.0。通常省略 — 见下文。

slugpublisher 共同构成包的身份。EmDash 自动从中派生包的完整标识符。

version 放在 package.json

构建会将清单的 versionpackage.json#version 进行核对:

  • 都设置且相同 → 正常。
  • 都设置但不同 → 严重错误。
  • 只设置一个 → 该值优先。
  • 都未设置 → 严重错误。

npm 分发插件的推荐模式是在清单中省略 version,让 package.json 成为唯一的真实来源(你的发布工具已经在那里进行版本提升)。没有 package.json 的仅注册表插件必须在清单中设置 version — 没有其他地方可以放。

配置文件

这些供注册表列表使用。license、作者(authorauthors)和安全联系人(securitysecurityContacts)是必填的;其余是可选的。

字段必填备注
licenseSPDX 表达式("MIT""Apache-2.0""MIT OR Apache-2.0")。首次发布时使用;后续发布中现有配置文件优先。
author / authors两者之一。author: { name, url?, email? } 用于单个作者;authors: [...](≤ 32)用于多个。同时设置两者会报错。
security / securityContacts两者之一。每个联系人至少需要 emailurlsecurityContacts: [...](≤ 8)用于多个。同时设置两者会报错。
name显示名称。默认为 slug。
description保持简短(约 140 个字符)。过长的值可能在列表中被截断。
keywords≤ 5 个条目。
repo源代码仓库的 https:// URL。

除非确实有多个,否则请使用单数形式 author / security — 这是常见情况,脚手架也这样输出。

信任契约

信任契约由 capabilitiesallowedHostsstorage 组成。三者默认都为空,因此不需要额外权限的插件可以完全省略它们。

{
	"capabilities": ["network:request", "content:read"],
	"allowedHosts": ["api.example.com", "*.cdn.example.com"],
	"storage": {
		"events": { "indexes": ["timestamp"] },
		"submissions": { "indexes": ["email"], "uniqueIndexes": ["token"] }
	}
}

能力

已识别的名称:

能力授予
content:read / content:write通过 ctx 读取 / 修改站点内容。
taxonomies:read读取分类法定义和术语(只读)。
media:read / media:write读取 / 写入媒体。
users:read读取用户记录。
email:send通过 ctx 发送邮件。
network:request通过 ctx.http 的出站 HTTP,限制为 allowedHosts
network:request:unrestricted到任何主机的出站 HTTP。代替 network:request 使用。
hooks.email-transport:register注册邮件传输钩子。
hooks.email-events:register注册邮件生命周期钩子。
hooks.page-fragments:register注册 page:fragments 钩子(仅限原生)。

CLI 强制执行的两个交叉字段规则(编辑器的 JSON-Schema 检查不执行 — 运行 emdash-plugin validate):

  • network:request 要求非空的 allowedHosts。如果插件确实需要到达任何主机,请改用 network:request:unrestricted
  • network:request:unrestricted 要求 allowedHosts 为空 — 无限制能力已经授予所有主机,因此列表会产生矛盾。

主机模式是裸主机名(无方案、路径或空格)。前缀 *. 允许子域名:*.cdn.example.com

存储

集合名称 → 索引配置的映射。集合名称遵循相同的 /^[a-z][a-z0-9_]*$/ 规则(运行时使用名称作为 SQL 表后缀)。索引是字段名或复合数组;uniqueIndexes 也可查询 — 不要在 indexes 中重复列出。

"storage": {
	"events": { "indexes": ["timestamp", ["collection", "timestamp"]] }
}

管理界面

可选。沙箱插件通过 Block Kit 渲染管理页面和仪表板小部件;清单仅声明它们出现的位置。如果插件没有管理 UI,请完全省略 admin 键。

"admin": {
	"pages": [{ "path": "/gallery", "label": "画廊", "icon": "image" }],
	"widgets": [{ "id": "recent-uploads", "title": "最近上传", "size": "half" }]
}

声明 admin.pagesadmin.widgets 的插件还必须在 src/plugin.ts 中提供一个渲染 Block Kit 内容的 admin 路由 — schema 无法强制这一点(路由名称是从源代码而非清单中探测的),但运行时会检查。

发布者固定

publisher 固定发布身份,防止你意外使用错误账户发布插件。

在你首次成功发布时,如果清单的 publisher 与活动会话匹配,它将保持原样。如果你用 emdash-plugin init 生成脚手架并留空,CLI 会将活动会话的 DID 写回清单。

以下示例展示了 CLI 写入的行,解析后的句柄作为注释添加以提高可读性:

"publisher": "did:plc:abc123def456", // jane.example.com

后续每次发布时,CLI 将活动会话和固定的 publisher 解析为 DID 并比较。不匹配会立即以 MANIFEST_PUBLISHER_MISMATCH 失败 — 没有覆盖标志。请有意地解决:

  • 错误的会话:emdash-plugin switch <did>,然后重新发布。
  • 真正将插件转让给新发布者:编辑清单中的 publisher

不发布就验证

emdash-plugin validate          # ./emdash-plugin.jsonc
emdash-plugin validate path/    # 特定目录

包含交叉字段规则的离线 schema 检查,使用 tsc 风格的 文件:行:列 诊断。适合预提交钩子或 CI 步骤。重复键和未知键是错误(严格模式捕获 "licens" 等拼写错误)。

CLI 标志始终优先

显式标志(--license--author-name 等)在两者都设置时覆盖清单值 — 适用于 CI 覆盖。--no-manifest 完全跳过清单(如果默认路径存在清单则发出警告,以保持发布者固定安全机制的可见性)。

下一步