EmDash CLI 提供了管理 EmDash CMS 實例的各種命令 — 包括資料庫設定、類型生成、內容 CRUD、結構描述管理、媒體管理等。
安裝
CLI 包含在 emdash 套件中:
npm install emdash
使用 npx emdash 執行命令,或將腳本加入 package.json。為簡潔起見,也可使用 em 作為二進位檔名稱。
驗證
與執行中的 EmDash 實例通訊的命令(除 init、seed、export-seed 和 auth secret 之外的所有命令)會依以下順序解析驗證:
--token旗標 — 命令列上明確指定的權杖EMDASH_TOKEN環境變數- 已儲存的憑證 — 來自
~/.config/emdash/auth.json(由emdash login儲存) - 開發繞過 — 如果 URL 為 localhost 且無可用權杖,則自動透過開發繞過端點進行驗證
大多數命令接受 --url(預設為 http://localhost:4321)和 --token 旗標。當目標為本地開發伺服器時,不需要權杖。
通用旗標
以下旗標可用於所有遠端命令:
| 旗標 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--url | -u | EmDash 實例 URL | http://localhost:4321 |
--token | -t | 驗證權杖 | 從環境變數/已儲存憑證 |
--json | 以 JSON 格式輸出(適合管線) | 從 TTY 自動偵測 |
輸出
當 stdout 為 TTY 時,CLI 會使用 consola 美化列印結果。當透過管線傳輸或設定了 --json 時,會輸出原始 JSON 到 stdout — 適合搭配 jq 或其他工具使用。
命令
emdash init
以核心結構描述和可選的範本資料初始化資料庫。
npx emdash init [options]
選項
| 選項 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--database | -d | 資料庫檔案路徑 | ./data.db |
--cwd | 工作目錄 | 目前目錄 | |
--force | -f | 重新執行結構描述和種子資料 | false |
行為
- 從
package.json讀取emdash設定 - 如有需要,建立資料庫檔案
- 執行核心遷移(建立系統表)
- 如已設定,執行範本
schema.sql - 如已設定,執行範本
seed.sql
emdash dev
啟動開發伺服器,並自動設定資料庫。
npx emdash dev [options]
選項
| 選項 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--database | -d | 資料庫檔案路徑 | ./data.db |
--types | -t | 啟動前從遠端生成類型 | false |
--port | -p | 開發伺服器連接埠 | 4321 |
--cwd | 工作目錄 | 目前目錄 |
範例
# 啟動開發伺服器
npx emdash dev
# 自訂連接埠
npx emdash dev --port 3000
# 啟動前從遠端生成類型
npx emdash dev --types
行為
- 檢查並執行待處理的資料庫遷移
- 如設定了
--types,從遠端實例生成 TypeScript 類型(URL 來自EMDASH_URL環境變數或package.json中的emdash.url) - 啟動 Astro 開發伺服器,並設定
EMDASH_DATABASE_URL
emdash types
從執行中的 EmDash 實例的結構描述生成 TypeScript 類型。
npx emdash types [options]
選項
| 選項 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--url | -u | EmDash 實例 URL | http://localhost:4321 |
--token | -t | 驗證權杖 | 從環境變數/已儲存憑證 |
--output | -o | 類型輸出路徑 | .emdash/types.ts |
--cwd | 工作目錄 | 目前目錄 |
範例
# 從本地開發伺服器生成類型
npx emdash types
# 從遠端實例生成
npx emdash types --url https://my-site.pages.dev
# 自訂輸出路徑
npx emdash types --output src/types/emdash.ts
行為
- 從實例取得結構描述
- 生成 TypeScript 類型定義
- 將類型寫入輸出檔案
- 同時寫入
schema.json以供參考
emdash login
使用 OAuth Device Flow 登入 EmDash 實例。
npx emdash login [options]
選項
| 選項 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--url | -u | EmDash 實例 URL | http://localhost:4321 |
行為
- 從實例探索驗證端點
- 如為 localhost 且未設定驗證,則自動使用開發繞過
- 否則啟動 OAuth Device Flow — 顯示一個代碼並開啟瀏覽器
- 輪詢授權狀態,然後將憑證儲存至
~/.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 | 依狀態篩選 |
--limit | 最大項目數 |
--cursor | 分頁游標 |
content get <collection> <id>
npx emdash content get posts 01ABC123
npx emdash content get posts 01ABC123 --raw
| 選項 | 說明 |
|---|---|
--raw | 回傳原始 Portable Text(跳過 Markdown 轉換) |
回應包含一個 _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 | 從 stdin 讀取資料 |
--slug | 內容 slug |
--status | 初始狀態(draft、published) |
透過 --data、--file 或 --stdin 三者之一提供資料。
content update <collection> <id>
如同檔案編輯器要求您先讀取再寫入 — 您必須提供先前 get 取得的 _rev 權杖,以證明您已查看目前狀態。這可防止意外覆寫您未曾查看的變更。
# 1. 讀取項目,記下 _rev
npx emdash content get posts 01ABC123
# 2. 使用步驟 1 的 _rev 進行更新
npx emdash content update posts 01ABC123 \
--rev MToyMDI2LTAyLTE0... \
--data '{"title": "Updated"}'
| 選項 | 說明 |
|---|---|
--rev | 來自 get 的修訂版本權杖(必填) |
--data | 包含內容資料的 JSON 字串 |
--file | 從 JSON 檔案讀取資料 |
如果項目在您 get 之後已變更,伺服器會回傳 409 Conflict — 請重新讀取後再試。
content delete <collection> <id>
npx emdash content delete posts 01ABC123
軟刪除內容項目(移至垃圾桶)。
content publish <collection> <id>
npx emdash content publish posts 01ABC123
content unpublish <collection> <id>
npx emdash content unpublish posts 01ABC123
content schedule <collection> <id>
npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z
| 選項 | 說明 |
|---|---|
--at | ISO 8601 日期時間(必填) |
content restore <collection> <id>
npx emdash content restore posts 01ABC123
還原已刪除的內容項目。
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、number、integer、boolean、datetime、image、reference、portableText、json(必填) |
--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
emdash search
跨內容全文搜尋。
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5
| 選項 | 別名 | 說明 |
|---|---|---|
--collection | -c | 依集合篩選 |
--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 seed
將種子檔案套用至資料庫。此命令直接操作本地 SQLite 檔案(不需要執行中的伺服器)。
npx emdash seed [path] [options]
參數
| 參數 | 說明 | 預設值 |
|---|---|---|
path | 種子檔案路徑 | .emdash/seed.json |
選項
| 選項 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--database | -d | 資料庫檔案路徑 | ./data.db |
--cwd | 工作目錄 | 目前目錄 | |
--validate | 僅驗證,不套用 | false | |
--no-content | 跳過範例內容 | false | |
--on-conflict | 衝突處理:skip、update、error | skip | |
--uploads-dir | 媒體上傳目錄 | .emdash/uploads | |
--media-base-url | 媒體檔案基礎 URL | /_emdash/api/media/file | |
--base-url | 網站基礎 URL(用於絕對媒體 URL) |
種子檔案解析
命令依以下順序尋找種子檔案:
- 位置參數(如有提供)
.emdash/seed.json(慣例)package.json中emdash.seed欄位的路徑
emdash export-seed
將資料庫結構描述和內容匯出為種子檔案。直接操作本地 SQLite 檔案。
npx emdash export-seed [options] > seed.json
選項
| 選項 | 別名 | 說明 | 預設值 |
|---|---|---|---|
--database | -d | 資料庫檔案路徑 | ./data.db |
--cwd | 工作目錄 | 目前目錄 | |
--with-content | 包含內容(全部或以逗號分隔的集合) | ||
--no-pretty | 停用 JSON 格式化 | false |
輸出格式
匯出的種子檔案包含:
- 設定:網站標題、標語、社群連結
- 集合:所有集合定義及欄位
- 分類法:分類法定義和詞彙
- 選單:導覽選單及項目
- 小工具區域:小工具區域和小工具
- 內容(如有需求):包含
$media參考和$ref:語法的條目,以便移植
emdash auth secret
為您的部署生成安全的驗證密鑰。
npx emdash auth secret
輸出適用於 EMDASH_AUTH_SECRET 的隨機密鑰。
生成的檔案
.emdash/types.ts
由 emdash types 生成的 TypeScript 介面:
// Generated by EmDash CLI
// Do not edit manually - run `emdash types` to regenerate
import type { PortableTextBlock } from "emdash";
export interface Post {
id: string;
title: string;
content: PortableTextBlock[];
publishedAt: Date | null;
}
.emdash/schema.json
供工具使用的原始結構描述匯出:
{
"version": "a1b2c3d4",
"collections": [
{
"slug": "posts",
"label": "Posts",
"fields": [...]
}
]
}
環境變數
| 變數 | 說明 |
|---|---|
EMDASH_DATABASE_URL | 資料庫 URL(由 dev 自動設定) |
EMDASH_TOKEN | 遠端操作的驗證權杖 |
EMDASH_URL | types 和 dev --types 的預設遠端 URL |
EMDASH_AUTH_SECRET | 通行密鑰驗證的密鑰 |
EMDASH_PREVIEW_SECRET | 預覽權杖生成的密鑰 |
套件腳本
{
"scripts": {
"dev": "emdash dev",
"init": "emdash init",
"types": "emdash types",
"seed": "emdash seed",
"export-seed": "emdash export-seed",
"db:reset": "rm -f data.db && emdash init"
}
}
結束碼
| 代碼 | 說明 |
|---|---|
0 | 成功 |
1 | 錯誤(設定、網路、資料庫) |