EmDash CLI 提供了用于数据库设置、类型生成、内容创建与编辑、Schema 管理、媒体以及站点导出与导入的命令。
安装
CLI 包含在 emdash 包中。使用以下命令安装:
npm install emdash
使用 npx emdash 运行命令,或将脚本添加到 package.json。该可执行文件也可简写为 em。
使用站点的包脚本(例如 pnpm dev)启动站点。包脚本会启动 Astro;EmDash 集成会生成 emdash-env.d.ts,而运行时会在首次请求时运行待执行的迁移,并在设置完成之前一次性应用内置种子的 Schema 和结构。种子中的示例内容只有在管理员于设置向导中选择时才会应用。
身份验证
连接到运行中的 EmDash 实例的命令按以下顺序解析身份验证:
--token标志 — 在命令行中显式提供的令牌EMDASH_TOKEN环境变量- 已存储的凭据 — 来自
~/.config/emdash/auth.json(由emdash login保存) - 开发绕过 — 如果 URL 是 localhost 且没有可用的令牌,则通过开发绕过端点自动进行身份验证
types、whoami、content、schema、media、search、taxonomy、menu 和 site 命令会连接到运行中的实例。身份验证命令有各自的连接选项。当目标是本地开发服务器时,不需要令牌。
通用标志
连接标志因命令而异。下面的分组命令表示该组中的每个子命令。
| 标志 | 别名 | 适用命令 | 说明与默认值 |
|---|---|---|---|
--url | -u | types, login, logout, whoami, content, schema, media, search, taxonomy, menu, site | 实例 URL;默认为 EMDASH_URL 或 http://localhost:4321 |
--token | -t | types, whoami, content, schema, media, search, taxonomy, menu, site | 来自该标志、EMDASH_TOKEN 或已存储凭据的令牌 |
--header "Name: Value" | -H | types, login, content, schema, media, search, taxonomy, menu, site | 可重复使用的标头,会与 EMDASH_HEADERS 和已存储的标头合并 |
--json | whoami, content, schema, media, search, taxonomy, menu, site | 输出原始 JSON,而不是面向终端的格式化输出 |
输出
当命令将结果写入交互式终端时,会将其格式化以便阅读。上面列出 --json 的命令在设置该标志或输出被管道传输时,会输出原始 JSON。emdash migrate 仅在使用其显式的 --json 选项时才输出 JSON。
命令
emdash init
根据 package.json 中的模板元数据初始化本地 SQLite 数据库。该命令会运行核心迁移,然后应用 emdash.schema 指定的可选 SQL 文件。如需 JSON 种子数据,请单独运行 emdash seed。
npx emdash init [options]
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--database | -d | SQLite 数据库路径 | ./data.db |
--cwd | 项目工作目录 | 当前目录 | |
--force | -f | 在集合已存在时重新应用模板 Schema | false |
不使用 --force 时,已初始化的数据库保持不变。此命令直接打开本地 SQLite 文件;对于由部署管理的 D1、PostgreSQL、libSQL 或 Hyperdrive 迁移,请使用 emdash migrate。
emdash doctor
检查本地 SQLite 数据库的连接、迁移、集合、表和用户问题。如果项目有 Wrangler 配置,该命令还会检查 Cron Trigger 和 EmDash 的 scheduled() 处理程序是否配套配置。
npx emdash doctor [options]
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--database | -d | SQLite 数据库路径 | ./data.db |
--cwd | 项目工作目录 | 当前目录 | |
--json | 输出结构化结果 | false |
该命令会将每项检查报告为通过、警告或失败,并在有检查失败时以非零状态退出。
emdash seed
验证 JSON 种子,或将其应用到本地 SQLite 数据库。该命令优先使用提供的位置参数路径,其次是 .emdash/seed.json,最后是 package.json 中的 emdash.seed 路径。
npx emdash seed [path] [options]
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--database | -d | SQLite 数据库路径 | ./data.db |
--cwd | 项目工作目录 | 当前目录 | |
--validate | 验证种子,但不更改数据库 | false | |
--no-content | 跳过条目、署名和分类法术语 | false | |
--on-conflict | 使用 skip、update 或 error 处理已有记录 | skip | |
--uploads-dir | 用于种子媒体的本地目录 | ./uploads | |
--media-base-url | 为本地种子媒体存储的基础 URL | /_emdash/api/media/file |
应用种子时会先运行核心迁移。当你需要在持续集成中检查文件,而不打开或创建数据库时,请使用 --validate。
emdash migrate
检查或应用由 Astro 构建产出的核心迁移集。
npx emdash migrate [options]
npx emdash migrate --check [options]
npx emdash migrate --status --json [options]
npx emdash migrate --release-lock <id> [options]
默认情况下,该命令会发现项目根目录并读取 .emdash/migrations.json。它会根据项目中已安装的 EmDash 包验证清单,解析适配器的项目本地执行器,并在执行任何 SQL 之前输出不可变的目标。
选项
| 选项 | 说明 |
|---|---|
--check | 不应用任何内容;若存在待执行或未知的迁移记录,则以非零状态退出 |
--status | 在不应用的情况下报告确切状态;报告成功后以零状态退出 |
--json | 以 JSON 输出稳定的迁移报告 |
--manifest <path> | 读取非标准的清单路径 |
--from-config | 显式评估受信任的 Astro 配置,而不是使用清单 |
--config <path> | 与 --from-config 一起使用的 Astro 配置路径 |
--expected-target-fingerprint <sha256> | 非交互式应用或释放锁时必需的保护措施 |
--release-lock <id> | 使用 --status 报告的 id 释放 D1 迁移锁;不能与 --check 或 --status 组合使用 |
--database <path> | 覆盖 SQLite 路径 |
--database-url-env <name> | 覆盖 PostgreSQL 连接变量的名称 |
--d1 <uuid-or-name> | 显式选择 D1 数据库 |
--account-id <id> | 显式选择 Cloudflare 账户 |
--wrangler-config <path> | 从显式指定的 Wrangler 配置中读取 D1 绑定元数据 |
--wrangler-env <name> | 选择环境;需要 --wrangler-config |
交互式的、供人阅读的应用和释放锁操作会要求确认。非交互式的应用或释放锁,以及每一次使用 --json 的应用或释放锁,都需要提供针对该目标输出的确切指纹。没有 down 或 --dry-run;请使用 --check 判断是否需要执行迁移。
退出码
| 退出码 | 含义 |
|---|---|
0 | 成功,包括成功的 --status 报告 |
1 | 验证、配置、目标、迁移或清理错误 |
2 | --check 发现待执行的已知迁移 |
3 | --check 发现未知的已应用记录(优先于待执行迁移) |
4 | 缺少确认、确认被拒绝,或目标指纹不匹配 |
130 | 在执行器有限清理后被中断 |
有关部署顺序、目标凭据和 D1 迁移锁,请参阅管理核心数据库迁移。
emdash types
从运行中的 EmDash 实例的 Schema 生成 TypeScript 类型。
npx emdash types [options]
选项
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--url | -u | EmDash 实例 URL | http://localhost:4321 |
--token | -t | 身份验证令牌 | 来自环境变量或已存储的凭据 |
--header | -H | 自定义请求标头;可重复使用 | 来自环境变量或已存储的凭据 |
--json | 可以接受,但不会改变此命令的文件或进度输出 | — | |
--output | -o | 类型的输出路径 | .emdash/types.ts |
--cwd | 工作目录 | 当前目录 |
示例
# Generate types from local dev server
npx emdash types
# Generate from remote instance
npx emdash types --url https://example.com
# Custom output path
npx emdash types --output src/types/emdash.ts
行为
- 从实例获取 Schema
- 生成 TypeScript 类型定义
- 将类型写入输出文件
- 在旁边写入
schema.json以供参考
emdash login
使用 OAuth 设备流程(OAuth Device Flow)登录 EmDash 实例。
npx emdash login [options]
选项
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--url | -u | EmDash 实例 URL | http://localhost:4321 |
--header | -H | 自定义请求标头;可重复使用 | 来自 EMDASH_HEADERS |
行为
- 从实例发现身份验证端点
- 如果是 localhost 且未配置身份验证,则自动使用开发绕过
- 否则启动 OAuth 设备流程——显示一个代码并打开浏览器。你输入代码后,管理页面会在你批准之前列出 CLI 将获得的权限,以及所请求但你的角色不允许的权限。
- 轮询授权,然后将凭据保存到
~/.config/emdash/auth.json
已保存的凭据会被后续所有针对同一实例的命令自动使用。
emdash logout
登出并移除已存储的凭据。
npx emdash logout [options]
选项
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--url | -u | EmDash 实例 URL | http://localhost:4321 |
emdash whoami
显示当前已通过身份验证的用户。
npx emdash whoami [options]
选项
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--url | -u | EmDash 实例 URL | http://localhost:4321 |
--token | -t | 身份验证令牌 | 来自环境变量/已存储的凭据 |
--json | 以 JSON 输出 |
显示电子邮件、姓名、角色、身份验证方式和实例 URL。
emdash content
管理内容项。所有子命令都通过 EmDashClient 使用远程 API。
content list <collection>
npx emdash content list posts
npx emdash content list posts --status published --limit 10
| 选项 | 说明 |
|---|---|
--status | 按状态筛选 |
--locale | 按语言区域筛选 |
--limit | 最大条目数 |
--cursor | 分页游标 |
content get <collection> <id>
npx emdash content get posts 01ABC123
npx emdash content get posts 01ABC123 --raw
| 选项 | 说明 |
|---|---|
--locale | ID 参数为 slug 时使用的语言区域 |
--raw | 返回原始 Portable Text,而不是 Markdown |
--published | 忽略待发布的草稿,仅返回已发布的数据 |
响应中包含一个 _rev 令牌。将它传给 content update,以确认你在覆盖之前已看过当前状态。
content create <collection>
npx emdash content create posts --data '{"title": "Hello"}'
npx emdash content create posts --file post.json --slug hello-world
cat post.json | npx emdash content create posts --stdin
| 选项 | 说明 |
|---|---|
--data | 包含内容数据的 JSON 字符串 |
--file | 从 JSON 文件读取数据 |
--stdin | 从标准输入读取数据 |
--slug | 内容 slug |
--locale | 内容语言区域 |
--translation-of | 要将此内容链接为其翻译的内容项的 ID |
--draft | 保持为草稿,而不是自动发布 |
通过 --data、--file 或 --stdin 中的恰好一个来提供数据。除非设置了 --draft,否则新条目会被自动发布。
content update <collection> <id>
你必须提供先前 get 返回的 _rev 令牌,以证明你已看过当前状态。这可以防止覆盖你没有看过的更改。以下步骤先读取一个条目,然后用该令牌更新它:
# 1. Read the item, note the _rev
npx emdash content get posts 01ABC123
# 2. Update with the _rev from step 1
npx emdash content update posts 01ABC123 \
--rev MToyMDI2LTAyLTE0... \
--data '{"title": "Updated"}'
| 选项 | 说明 |
|---|---|
--rev | 来自 get 的修订令牌(必填) |
--data | 包含内容数据的 JSON 字符串 |
--file | 从 JSON 文件读取数据 |
--locale | ID 参数为 slug 时使用的语言区域 |
--draft | 将更新保持为草稿,而不是自动发布 |
--override-lock | 即使另一位编辑者已打开该条目,也照常写入 |
如果自你执行 get 之后该条目已发生变化,服务器会返回 409 Conflict——请重新读取后再试。
如果有人在管理后台中打开了该条目,服务器会返回 409,代码为
ENTRY_LOCKED,消息中会指明持有者。请等待对方完成,或
传入 --override-lock。content delete、
content publish、content unpublish 和 content schedule 同样提供该标志。
content delete <collection> <id>
npx emdash content delete posts 01ABC123
软删除该内容项(移入回收站)。
传入 --override-lock 可删除另一位编辑者已打开的条目。
content publish <collection> <id>
npx emdash content publish posts 01ABC123
传入 --override-lock 可发布另一位编辑者已打开的条目。
content unpublish <collection> <id>
npx emdash content unpublish posts 01ABC123
传入 --override-lock 可取消发布另一位编辑者已打开的条目。
content schedule <collection> <id>
npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z
| 选项 | 说明 |
|---|---|
--at | 带有 Z 或显式 UTC 偏移的 ISO 8601 日期时间(必填) |
传入 --override-lock 可为另一位编辑者已打开的条目排期。
content restore <collection> <id>
npx emdash content restore posts 01ABC123
恢复已移入回收站的内容项。
content translations <collection> <id>
列出该条目翻译组中的每个翻译:
npx emdash content translations posts 01ABC123
结果包含每个翻译的 ID、语言区域、slug、状态,以及它是否为所请求的条目。
emdash schema
管理集合和字段。
schema list
npx emdash schema list
列出所有集合。
schema get <collection>
npx emdash schema get posts
显示一个集合及其所有字段。
schema create <collection>
npx emdash schema create articles --label Articles
npx emdash schema create articles --label Articles --label-singular Article --description "Blog articles"
| 选项 | 说明 |
|---|---|
--label | 集合标签(必填) |
--label-singular | 单数形式的标签 |
--description | 集合描述 |
schema delete <collection>
npx emdash schema delete articles
npx emdash schema delete articles --force
| 选项 | 说明 |
|---|---|
--force | 跳过确认 |
除非设置了 --force,否则会提示确认。
schema add-field <collection> <field>
npx emdash schema add-field posts body --type portableText --label "Body Content"
npx emdash schema add-field posts featured --type boolean --required
| 选项 | 说明 |
|---|---|
--type | 字段类型:string、text、url、number、integer、boolean、datetime、select、multiSelect、portableText、image、file、reference、json、slug 或 repeater(必填) |
--label | 字段标签(默认为字段 slug) |
--required | 字段是否为必填 |
schema remove-field <collection> <field>
npx emdash schema remove-field posts featured
emdash media
管理媒体项。
media list
npx emdash media list
npx emdash media list --mime image/png --limit 20
| 选项 | 说明 |
|---|---|
--mime | 按 MIME 类型筛选 |
--limit | 条目数量 |
--cursor | 分页游标 |
media upload <file>
npx emdash media upload ./photo.jpg
npx emdash media upload ./photo.jpg --alt "A sunset" --caption "Taken in Bristol"
| 选项 | 说明 |
|---|---|
--alt | 替代文本 |
--caption | 说明文字 |
media get <id>
npx emdash media get 01MEDIA123
media delete <id>
npx emdash media delete 01MEDIA123
media repair-usage
为一个集合或每个内容集合修复内容媒体使用索引。在导入或直接写入数据库之后,如果使用覆盖情况已过时或不可信,请使用它。
npx emdash media repair-usage --collection posts
npx emdash media repair-usage --all
npx emdash media repair-usage --all --json
| 选项 | 别名 | 说明 |
|---|---|---|
--collection | -c | 修复一个内容集合 |
--all | 修复每个内容集合 |
--collection 和 --all 必须恰好传入其中一个。远程修复需要 Admin 用户,以及带有 admin 范围的身份验证令牌。
修复全部内容是同步运行的,在大型站点上可能很慢或开销很大。如果只需要修复一个集合,请优先使用 --collection。
结构化的 complete、partial 和 stale 修复结果以 0 退出;结构化的 failed 结果以 1 退出。自动化和 cron 任务应使用 --json 并解析 status、failedSourceCount、skippedSourceCount 以及每个集合的摘要,而不是把退出码 0 当作覆盖完整。
emdash search
跨内容的全文搜索。
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5
| 选项 | 别名 | 说明 |
|---|---|---|
--collection | -c | 按集合筛选 |
--locale | 按语言区域筛选 | |
--limit | -l | 最大结果数 |
emdash taxonomy
管理分类法和术语。
taxonomy list
npx emdash taxonomy list
taxonomy terms <name>
npx emdash taxonomy terms categories
npx emdash taxonomy terms tags --limit 50
| 选项 | 别名 | 说明 |
|---|---|---|
--limit | -l | 最大术语数 |
--cursor | 分页游标 |
taxonomy add-term <taxonomy>
npx emdash taxonomy add-term categories --name "Tech" --slug tech
npx emdash taxonomy add-term categories --name "Frontend" --parent 01PARENT123
| 选项 | 说明 |
|---|---|
--name | 术语标签(必填) |
--slug | 术语 slug(默认为名称转换后的 slug) |
--parent | 父术语 ID(用于层级分类法) |
emdash menu
管理导航菜单。
menu list
npx emdash menu list
menu get <name>
npx emdash menu get primary
返回该菜单及其所有菜单项。
emdash site
将整个站点导出为 .emdash 站点包,并将站点包导入到空站点中。站点迁移指南说明了站点包包含什么、目标站点需要什么,以及如何阅读导入计划。
令牌需要 admin 范围(emdash login 的令牌具有该范围),或相应的迁移范围:导出需要 transfer:export,导入需要 transfer:analyze 和 transfer:execute。缺少这些范围的令牌会以 INSUFFICIENT_SCOPE 失败。
进度消息始终输出到 stderr,结果输出到 stdout。使用 --json,或当 stdout 不是终端时,stdout 只包含 JSON 结果。错误以 { "error": { "code": "…", "message": "…" } } 的形式写出。这些代码是服务器的错误代码,另外还有:标志错误时的 INVALID_ARGUMENT、恢复的导入仍需要站点包文件时的 PACKAGE_FILE_REQUIRED,以及 UNKNOWN_ERROR。
这些命令会对网络故障以及 408、429 和 5xx 响应进行带退避的重试。
site export
导出站点并将其写入站点包文件:
npx emdash site export --output site.emdash
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--output | -o | 要写入的站点包文件(必填) | |
--no-comments | 不包含评论和评论回应 | 包含评论 |
该命令会启动一次导出,持续推进直到完成,并逐个文件下载站点包。它会检查下载的清单是否与该导出的站点包摘要匹配,如果不匹配,则在写入任何内容之前以 TRANSFER_PACKAGE_DIGEST_MISMATCH 失败。它会在写入每个文件之前检查其大小和 SHA-256 摘要。站点包会先写入 <output>.partial,完成后重命名为输出路径。
该命令将进度保存在 <output>.partial.json 中,并将下载的文件保存在 <output>.parts/ 目录中。中断后再次运行同一命令即可恢复同一次导出;已下载的文件会被检查并复用,命令会报告复用了多少个。站点包写入完成后,两者都会被删除。如果进度文件是为另一个 URL 或另一种评论设置写入的,或者其导出已失败或已过期,则会被忽略;此时命令会启动一次新的导出。
JSON 结果包含 operationId、output、packageDigest、files、bytes 和 resumed。
site import <file>
分两步导入站点包。先进行分析,然后确认分析输出的计划摘要:
npx emdash site import site.emdash --analyze
npx emdash site import site.emdash --plan sha256:3f1c… --confirm
| 选项 | 说明 |
|---|---|
--analyze | 上传站点包、分析它并输出导入计划 |
--map-principal <from>=<to> | 与 --analyze 一起使用:将站点包中的主体(按 ID 或电子邮件地址)映射到站点用户(按 ID 或电子邮件地址),或映射为 none。可重复使用 |
--use-target-title | 与 --analyze 一起使用:保留此站点的标题,而不是站点包中的标题 |
--use-target-tagline | 与 --analyze 一起使用:保留此站点的标语,而不是站点包中的标语 |
--plan <digest> | 要执行的计划摘要,格式为 sha256:<hex> 或纯十六进制。需要 --confirm |
--confirm | 执行 --plan 给出的计划。需要 --plan |
--yes | 别名为 -y。与 cancel 或 abandon 一起使用:跳过确认提示 |
--analyze 会在本地验证整个站点包文件,然后查找站点上同一站点包已有的导入,或创建一个。它会上传站点尚没有的文件,运行分析,并输出计划:站点包摘要和计划摘要、记录数、大小、标题和标语的选择、每个主体及其映射、“Differences from the source site”下的转换、警告和阻塞项。如果同一站点包之前的导入失败、被取消或放弃,或已过期,命令会发出警告并启动新的导入。
各项决定会随导入一起存储,因此之后不带决定标志再次运行 --analyze 时,会保留这些决定。每次更改决定都会产生新的计划摘要。决定不能与 --plan 组合使用,--plan 也不能与 --analyze 组合使用。
--plan <digest> --confirm 仅在摘要与当前计划匹配时才执行导入,然后持续推进直到完成,并输出回执。如果自你审阅之后计划发生了变化,命令会以 TRANSFER_PLAN_DIGEST_MISMATCH 失败;请重新分析并确认新的摘要。
--analyze 的 JSON 结果包含 operationId、state、packageDigest、planDigest、executable 和完整的 plan。--confirm 的 JSON 结果包含 operationId、state(complete)、receipt 和 receiptDigestValid,后者表示回执的 receiptDigest 是否与其内容匹配。
以下形式通过操作 ID 对某个导入进行操作:
| 命令 | 说明 |
|---|---|
emdash site import status <operation-id> | 输出该导入的状态、阶段、进度、摘要和错误,以及已上传的文件数。JSON 结果为 { operation, files: { declared, verified } }。 |
emdash site import resume <operation-id> [file] | 从当前状态继续该导入:完成上传、完成分析并输出计划,或完成执行并输出回执。仅在导入仍处于上传阶段时才传入站点包文件。 |
emdash site import receipt <operation-id> | 输出已完成导入的回执,格式与 --confirm 相同。 |
emdash site import cancel <operation-id> | 取消该导入。正在运行的导入会在当前批次结束后停止;已写入的内容会保留在站点上。 |
emdash site import abandon <operation-id> | 解除失败或已取消的导入在站点上留下的写入阻止。导入已写入的内容不会被删除,因此再次导入之前,请重置站点或设置一个新站点。 |
cancel 和 abandon 会要求确认。传入 --yes 可跳过提示;使用 --json 或 stdout 不是终端时,也会跳过提示。当 stdin 不是终端且上述两种情况都不适用时,命令会以 INVALID_ARGUMENT 失败。拒绝提示不会更改任何内容,并以退出码 1 退出。两者的 JSON 结果都是 { operationId, state, operation }。
导入命令使用以下退出码:
| 退出码 | 含义 |
|---|---|
0 | 成功。对于 status,表示导入正在进行或已完成 |
1 | 出现错误、提示被拒绝、导入结束但没有回执,或回执的摘要不匹配。对于 status,表示导入已失败、被取消或放弃,或已过期 |
2 | 分析已完成,但计划存在阻塞项 |
emdash export-seed
将数据库 Schema 和内容导出为种子文件。直接对本地 SQLite 文件进行操作。
数据库必须包含已安装的 EmDash 版本所知的每一个迁移。如果命令
报告存在待执行的迁移,请运行 npx emdash migrate,然后再次导出。如果数据库是由更新版本的 EmDash 迁移的,
请先升级已安装的版本再导出。导出
以只读方式打开数据库,且自身从不应用迁移。
npx emdash export-seed [options] > seed.json
选项
| 选项 | 别名 | 说明 | 默认值 |
|---|---|---|---|
--database | -d | 数据库文件路径 | ./data.db |
--cwd | 工作目录 | 当前目录 | |
--with-content | 包含内容(全部或以逗号分隔的集合) | ||
--pretty / --no-pretty | 启用或禁用带缩进的 JSON 输出 | 启用格式化输出 | |
--media-base-url | 站点的公开 URL,用于写出绝对的 $media URL |
输出格式
导出的种子文件包含:
- 设置:站点标题、标语、社交链接
- 集合:所有集合定义及其字段
- 块类型:每个保留的版本以及每种类型的活动版本指针
- 分类法:分类法定义和术语
- 菜单:带菜单项的导航菜单
- 重定向:状态为 301、302、307 或 308 的重定向规则
- 小组件区域:小组件区域和小组件
- 区段:可复用的内容块
- 内容(如有请求):带有
$media引用和$ref:语法(便于移植)的条目
已排期的条目会作为草稿导出,因为种子中没有发布时间的字段。导出会略过 emdash seed 会拒绝的内容,并在 stderr 上给出警告:状态为 410 或 451 的重定向规则、共享同一来源的额外规则(旧数据库中可能出现),以及 slug 中包含小写字母、数字和连字符以外字符的区段。
媒体 URL
emdash seed 会下载每个 $media URL,并将文件上传到目标站点的存储中,因此它需要一个自己能够访问的绝对 http 或 https URL。传入源站点的公开 URL 以写出绝对 URL:
npx emdash export-seed --with-content=all --media-base-url=https://example.com > seed.json
在应用种子期间,站点必须在该 URL 下通过 /_emdash/api/media/file/ 提供其媒体,并且该 URL 不能指向 localhost 或私有网络地址,emdash seed 会拒绝从这些地址下载。如果没有 --media-base-url,$media URL 就是站点相对路径,emdash seed 会跳过它们,使这些字段保持为空,导出时也会在 stderr 上输出警告。
图片和文件字段,以及重复器(repeater)的图片子字段,会作为 $media 引用导出。Portable Text 字段中的图片会保留其已存储的媒体 ID 和 URL,这些在另一个站点上无法解析。
emdash secrets
生成并检查用于加密插件密钥的密钥。
secrets generate
为你的部署生成一个 EMDASH_ENCRYPTION_KEY。该密钥用于
对插件密钥进行静态加密。
npx emdash secrets generate
将新密钥输出到 stdout。你可以通过管道把它送入你的密钥存储,或使用 --write
直接写入本地 .env 文件。Wrangler 和 Cloudflare
Vite 插件会在本地开发中读取该文件。独立的 Node 服务器
不会自动加载 .env;请通过进程管理器加载它,或通过服务器的进程环境
提供该密钥。Node.js 部署指南
展示了本地命令。
npx emdash secrets generate --write .env
没有 --force 时,--write 拒绝覆盖已有条目。要轮换已有加密数据的部署的密钥,请把生成的密钥放在现有值之前,并用逗号分隔各个密钥。EmDash 使用第一个密钥加密新值,并按 kid 使用较旧的条目进行解密。在移除旧密钥之前,请重新保存每个插件密钥。EmDash 目前不会列出已存储设置仍在使用的密钥 ID,因此请保留你重新保存的凭据清单,并在移除旧密钥之前验证每个集成。
secrets fingerprint <key>
输出密钥的 8 个字符的指纹(kid),而不暴露其 值。这在 CI 中很有用,可用于验证部署的是正确的密钥。以下命令输出某个密钥的指纹:
npx emdash secrets fingerprint emdash_enc_v1_...
生成的文件
emdash-env.d.ts
当本地开发服务器启动时,Astro 集成会在项目根目录生成 emdash-env.d.ts。在通过运行中的开发站点更改 Schema 之后,它会刷新该文件。这些声明扩充了 EmDashCollections,因此像 getEmDashCollection("posts") 这样的调用会推断出本地数据库中定义的字段。
该文件是自动生成的,属于本地 Astro 开发工作流。你不需要运行 emdash types 来创建它。
.emdash/types.ts
emdash types 命令会获取运行中实例的 Schema,并写出独立的 TypeScript 接口。当 Schema 位于远程 EmDash 实例上、工具需要自定义路径下的文件,或本地 Astro 开发服务器未运行时,请使用它:
// Generated by EmDash CLI
// Do not edit manually - run `emdash types` to regenerate
import type { PortableTextBlock } from "emdash";
export interface Post {
id: string;
slug: string | null;
status: string;
title: string;
content?: PortableTextBlock[];
createdAt: Date;
updatedAt: Date;
publishedAt: Date | null;
bylines?: ContentBylineCredit[];
terms?: Record<string, TaxonomyTerm[]>;
}
远程输出包含独立的集合接口,不会扩充 EmDashCollections。它只会在你运行 emdash types 时发生变化;emdash-env.d.ts 使用模块扩充,并作为本地开发的一部分刷新。
.emdash/schema.json
该命令还会在所选 TypeScript 输出旁边写出一个名为 schema.json 的原始 Schema 导出。使用默认输出路径时,该文件为 .emdash/schema.json:
{
"version": "a1b2c3d4",
"collections": [
{
"slug": "posts",
"label": "Posts",
"fields": [...]
}
]
}
环境变量
| 变量 | 说明 |
|---|---|
EMDASH_DATABASE_URL | 覆盖数据库 URL |
EMDASH_TOKEN | 远程操作使用的身份验证令牌 |
EMDASH_URL | 使用共享远程客户端的命令的默认 URL |
EMDASH_HEADERS | 以换行符分隔的自定义请求标头,供共享远程客户端和 login 使用 |
EMDASH_ENCRYPTION_KEY | 用于对插件密钥进行静态加密的密钥。由运维人员提供——绝不存储在数据库中。使用 emdash secrets generate 生成。 |
EMDASH_PREVIEW_SECRET | 对预览 HMAC 密钥的可选覆盖。未设置时,EmDash 会生成一个并持久化到 options 表中。 |
EMDASH_IP_SALT | 对评论者 IP 哈希盐值的可选覆盖。未设置时,EmDash 会生成一个并持久化到 options 表中。 |
EMDASH_AUTH_SECRET | 旧版。如果设置,将用作 IP 盐值的来源,以便现有安装在升级后保持稳定的评论者 IP 哈希。新安装不应设置它。 |
包脚本
为方便起见,可将常用命令添加为 package.json 脚本:
{
"scripts": {
"dev": "astro dev",
"types": "emdash types",
"export-seed": "emdash export-seed",
"db:reset": "rm -f data.db"
}
}
通用退出码
大多数命令使用 0 表示成功,1 表示错误。emdash migrate 还使用退出码 2、3、4 和 130 表示其退出码表中列出的特定结果。当导入计划存在阻塞项时,emdash site import 使用 2。
| 退出码 | 说明 |
|---|---|
0 | 成功 |
1 | 错误(配置、网络、数据库) |