EmDash CLI는 데이터베이스 설정, 타입 생성, 콘텐츠 생성 및 편집, 스키마 관리, 미디어, 사이트 내보내기 및 가져오기, 플러그인 개발을 위한 명령을 제공합니다.
설치
CLI는 emdash 패키지에 포함됩니다. 다음 명령으로 설치하세요.
npm install emdash
npx emdash로 명령을 실행하거나 package.json에 스크립트를 추가하세요. 바이너리는 간결함을 위해 em으로도 사용할 수 있습니다.
패키지 스크립트(예: pnpm dev)로 사이트를 시작하세요. 패키지 스크립트는 Astro를 시작하고, EmDash 통합은 emdash-env.d.ts를 생성합니다. 런타임은 첫 요청에서 보류 중인 마이그레이션을 실행하고, 데이터베이스가 비어 있고 설정이 완료되지 않았을 때 번들된 시드를 적용합니다.
인증
실행 중인 EmDash 인스턴스에 연결하는 명령은 다음 순서로 인증을 결정합니다.
--token플래그 — 명령줄의 명시적 토큰EMDASH_TOKEN환경 변수- 저장된 자격 증명 —
~/.config/emdash/auth.json(emdash login이 저장) - Dev bypass — URL이 localhost이고 토큰이 없으면 dev bypass 엔드포인트를 통해 자동 인증
types, whoami, content, schema, media, search, taxonomy, menu, site 명령은 실행 중인 인스턴스에 연결합니다. 인증 명령은 자체 연결 옵션이 있습니다. 로컬 개발 서버를 대상으로 할 때는 토큰이 필요 없습니다.
공통 플래그
연결 플래그는 명령마다 다릅니다. 아래 그룹화된 명령은 해당 그룹의 모든 하위 명령을 의미합니다.
| Flag | Alias | Available on | Description and default |
|---|---|---|---|
--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]
| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | SQLite 데이터베이스 경로 | ./data.db |
--cwd | 프로젝트 작업 디렉터리 | 현재 디렉터리 | |
--force | -f | 컬렉션이 이미 있을 때 템플릿 스키마 재적용 | false |
--force 없이는 초기화된 데이터베이스가 그대로 유지됩니다. 이 명령은 로컬 SQLite 파일을 직접 엽니다. 배포 관리 D1, PostgreSQL, libSQL 또는 Hyperdrive 마이그레이션에는 emdash migrate를 사용하세요.
emdash doctor
로컬 SQLite 데이터베이스의 연결, 마이그레이션, 컬렉션, 테이블, 사용자 문제를 확인합니다. 프로젝트에 Wrangler 구성이 있으면 Cron Trigger와 EmDash scheduled() 핸들러가 함께 구성되어 있는지도 확인합니다.
npx emdash doctor [options]
| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | SQLite 데이터베이스 경로 | ./data.db |
--cwd | 프로젝트 작업 디렉터리 | 현재 디렉터리 | |
--json | 구조화된 결과 출력 | false |
각 검사를 통과, 경고 또는 실패로 보고하며, 검사가 실패하면 0이 아닌 코드로 종료합니다.
emdash seed
JSON 시드를 로컬 SQLite 데이터베이스에 검증하거나 적용합니다. 명령은 제공된 경우 위치 경로, 그다음 .emdash/seed.json, 그다음 package.json의 emdash.seed 경로를 사용합니다.
npx emdash seed [path] [options]
| Option | Alias | Description | Default |
|---|---|---|---|
--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 |
시드 적용은 먼저 코어 마이그레이션을 실행합니다. 데이터베이스를 열거나 만들지 않고 파일을 확인해야 하는 CI에서는 --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 전에 불변 대상을 출력합니다.
옵션
| Option | Description |
|---|---|
--check | 아무것도 적용하지 않음. 보류 중이거나 알 수 없는 마이그레이션 레코드면 0이 아닌 코드로 종료 |
--status | 적용 없이 정확한 상태 보고. 성공적인 보고 후 0으로 종료 |
--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를 사용하세요.
종료 코드
| Code | Meaning |
|---|---|
0 | 성공. 성공적인 --status 보고 포함 |
1 | 검증, 구성, 대상, 마이그레이션 또는 정리 오류 |
2 | --check가 알려진 보류 마이그레이션을 발견 |
3 | --check가 알 수 없는 적용 레코드를 발견(보류보다 우선) |
4 | 확인 누락, 거부 또는 대상 지문 불일치 |
130 | 제한된 실행기 정리 후 중단 |
배포 순서, 대상 자격 증명, D1 마이그레이션 잠금은 Manage Core Database Migrations를 보세요.
emdash dev (사용 중단)
레거시 명령은 Astro를 시작하기 전에 로컬 SQLite 데이터베이스를 초기화하고 마이그레이션합니다. 이 동작은 사이트가 구성한 데이터베이스 어댑터를 사용하지 않으며 Cloudflare D1 개발과 호환되지 않습니다. 기존 호출은 이제 데이터베이스 작업 전에 사용 중단 경고를 출력합니다.
| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | 로컬 SQLite 데이터베이스 경로 | ./data.db |
--types | -t | Astro 시작 전 원격 타입 가져오기 | false |
--port | -p | Astro 개발 서버 포트 | 4321 |
--cwd | 프로젝트 작업 디렉터리 | 현재 디렉터리 |
emdash types
실행 중인 EmDash 인스턴스의 스키마에서 TypeScript 타입을 생성합니다.
npx emdash types [options]
옵션
| Option | Alias | Description | Default |
|---|---|---|---|
--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://my-site.pages.dev
# Custom output path
npx emdash types --output src/types/emdash.ts
동작
- 인스턴스에서 스키마 가져오기
- TypeScript 타입 정의 생성
- 출력 파일에 타입 쓰기
- 참조용으로 옆에
schema.json쓰기
emdash login
OAuth Device Flow로 EmDash 인스턴스에 로그인합니다.
npx emdash login [options]
옵션
| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash 인스턴스 URL | http://localhost:4321 |
--header | -H | 사용자 지정 요청 헤더. 반복 가능 | EMDASH_HEADERS에서 |
동작
- 인스턴스에서 인증 엔드포인트 발견
- localhost이고 인증이 구성되지 않았으면 자동으로 dev bypass 사용
- 그렇지 않으면 OAuth Device Flow 시작 — 코드를 표시하고 브라우저를 엽니다. 코드를 입력한 후 관리 페이지는 CLI가 받을 권한과 역할이 허용하지 않는 요청된 권한을 승인 전에 나열합니다.
- 권한 부여를 폴링한 다음 자격 증명을
~/.config/emdash/auth.json에 저장
저장된 자격 증명은 같은 인스턴스를 대상으로 하는 이후의 모든 명령에서 자동으로 사용됩니다.
emdash logout
로그아웃하고 저장된 자격 증명을 제거합니다.
npx emdash logout [options]
옵션
| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash 인스턴스 URL | http://localhost:4321 |
emdash whoami
현재 인증된 사용자를 표시합니다.
npx emdash whoami [options]
옵션
| Option | Alias | Description | Default |
|---|---|---|---|
--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
| Option | Description |
|---|---|
--status | 상태로 필터 |
--locale | 로케일로 필터 |
--limit | 최대 항목 수 |
--cursor | 페이지 매김 커서 |
content get <collection> <id>
npx emdash content get posts 01ABC123
npx emdash content get posts 01ABC123 --raw
| Option | Description |
|---|---|
--locale | ID 인수가 슬러그일 때 사용할 로케일 |
--raw | Markdown 대신 원시 Portable Text 반환 |
--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
| Option | Description |
|---|---|
--data | 콘텐츠 데이터가 있는 JSON 문자열 |
--file | JSON 파일에서 데이터 읽기 |
--stdin | stdin에서 데이터 읽기 |
--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"}'
| Option | Description |
|---|---|
--rev | get의 개정 토큰(필수) |
--data | 콘텐츠 데이터가 있는 JSON 문자열 |
--file | JSON 파일에서 데이터 읽기 |
--locale | ID 인수가 슬러그일 때 사용할 로케일 |
--draft | 자동 게시 대신 업데이트를 초안으로 유지 |
--override-lock | 다른 편집자가 항목을 열어 두어도 쓰기 |
get 이후 항목이 변경되면 서버는 409 Conflict를 반환합니다 — 다시 읽고 재시도하세요.
관리자에서 누군가 항목을 열어 두면 서버는 코드
ENTRY_LOCKED와 보유자를 지정하는 메시지가 있는 409를 반환합니다. 끝날 때까지 기다리거나
--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
| Option | Description |
|---|---|
--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, 로케일, 슬러그, 상태, 요청된 항목인지 여부가 포함됩니다.
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"
| Option | Description |
|---|---|
--label | 컬렉션 레이블(필수) |
--label-singular | 단수 레이블 |
--description | 컬렉션 설명 |
schema delete <collection>
npx emdash schema delete articles
npx emdash schema delete articles --force
| Option | Description |
|---|---|
--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
| Option | Description |
|---|---|
--type | 필드 타입: string, text, url, number, integer, boolean, datetime, select, multiSelect, portableText, image, file, reference, json, slug 또는 repeater(필수) |
--label | 필드 레이블(기본값은 필드 슬러그) |
--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
| Option | Description |
|---|---|
--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"
| Option | Description |
|---|---|
--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
| Option | Alias | Description |
|---|---|---|
--collection | -c | 하나의 콘텐츠 컬렉션 복구 |
--all | 모든 콘텐츠 컬렉션 복구 |
--collection 또는 --all 중 정확히 하나를 전달하세요. 원격 복구에는 Admin 사용자와 admin 범위의 인증 토큰이 필요합니다.
전체 콘텐츠 복구는 동기적으로 실행되며 큰 사이트에서는 느리거나 비용이 많이 들 수 있습니다. 한 컬렉션만 복구하면 될 때는 --collection을 선호하세요.
구조화된 complete, partial, stale 결과는 0으로 종료되고, 구조화된 failed 결과는 1로 종료됩니다. 자동화와 cron 작업은 --json을 사용하고 종료 0을 완전한 범위로 취급하지 말고 status, failedSourceCount, skippedSourceCount, 컬렉션별 요약을 파싱하세요.
emdash search
콘텐츠 전체 텍스트 검색입니다.
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5
| Option | Alias | Description |
|---|---|---|
--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
| Option | Alias | Description |
|---|---|---|
--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
| Option | Description |
|---|---|
--name | 용어 레이블(필수) |
--slug | 용어 슬러그(기본값은 슬러그화된 이름) |
--parent | 부모 용어 ID(계층 택소노미용) |
emdash menu
탐색 메뉴를 관리합니다.
menu list
npx emdash menu list
menu get <name>
npx emdash menu get primary
모든 항목과 함께 메뉴를 반환합니다.
emdash site
전체 사이트를 .emdash 사이트 패키지로 내보내고, 빈 사이트에 패키지를 가져옵니다. 사이트 전송 가이드는 패키지 내용, 대상 사이트에 필요한 것, 가져오기 계획 읽는 방법을 설명합니다.
토큰에는 emdash login 토큰이 가진 admin 범위, 또는 해당 전송 범위가 필요합니다. 내보내기는 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
| Option | Alias | Description | Default |
|---|---|---|---|
--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
| Option | Description |
|---|---|
--analyze | 패키지 업로드, 분석, 가져오기 계획 출력 |
--map-principal <from>=<to> | --analyze와 함께: ID 또는 이메일로 패키지 주체를 사이트 사용자(ID 또는 이메일) 또는 none에 매핑. 반복 가능 |
--use-target-title | --analyze와 함께: 패키지 대신 이 사이트의 제목 유지 |
--use-target-tagline | --analyze와 함께: 패키지 대신 이 사이트의 태그라인 유지 |
--plan <digest> | 실행할 계획 다이제스트. sha256:<hex> 또는 순수 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, 영수증의 receiptDigest가 내용과 일치하는지 보고하는 receiptDigestValid가 포함됩니다.
이 형식들은 작업 ID로 가져오기를 조작합니다.
| Command | Description |
|---|---|
emdash site import status <operation-id> | Print the import’s state, stage, progress, digests, and error, and how many files are uploaded. The JSON result is { operation, files: { declared, verified } }. |
emdash site import resume <operation-id> [file] | Continue the import from its current state: finish uploading, finish analysis and print the plan, or finish execution and print the receipt. Pass the package file only while the import is still uploading. |
emdash site import receipt <operation-id> | Print the receipt of a complete import, in the same shape as --confirm. |
emdash site import cancel <operation-id> | Cancel the import. A running import stops after its current batch; what it already wrote stays on the site. |
emdash site import abandon <operation-id> | Lift the write block that a failed or cancelled import leaves on the site. What the import wrote is not deleted, so reset the site or set up a new one before importing again. |
cancel과 abandon은 확인을 요청합니다. 프롬프트를 건너뛰려면 --yes를 전달하세요. --json이거나 stdout이 터미널이 아니면 프롬프트도 건너뜁니다. stdin이 터미널이 아니고 둘 다 해당하지 않으면 명령은 INVALID_ARGUMENT로 실패합니다. 프롬프트를 거부하면 아무것도 바뀌지 않고 코드 1로 종료합니다. 둘의 JSON 결과는 { operationId, state, operation }입니다.
가져오기 명령은 다음 코드로 종료합니다.
| Code | Meaning |
|---|---|
0 | Success. For status, an import that is in progress or complete |
1 | An error, a declined prompt, an import that ended without a receipt, or a receipt whose digest does not match. For status, an import that failed, was cancelled or abandoned, or expired |
2 | Analysis finished, but the plan has blockers |
emdash plugin
EmDash 플러그인을 만들고, 검증하고, 번들하고, 게시합니다. 마켓플레이스 로그인은 CMS 인스턴스 로그인과 별개입니다.
plugin init
샌드박스 또는 네이티브 플러그인 스캐폴드를 만듭니다.
npx emdash plugin init --dir ./my-plugin --name my-plugin --format sandboxed
| Option | Description | Default |
|---|---|---|
--dir | 만들 디렉터리 | 현재 디렉터리 |
--name | 플러그인 패키지 이름 또는 ID | 대화형 프롬프트 |
--format | sandboxed 또는 native | 대화형 프롬프트 |
--native | --format native 단축 | false |
plugin bundle
플러그인을 검증하고 마켓플레이스 tarball을 만듭니다.
npx emdash plugin bundle --dir ./my-plugin --outDir ./artifacts
| Option | Alias | Description | Default |
|---|---|---|---|
--dir | 플러그인 디렉터리 | 현재 디렉터리 | |
--outDir | -o | tarball 출력 디렉터리 | ./dist |
--validateOnly | tarball을 만들지 않고 검증 실행 | false |
plugin validate
tarball을 만들지 않고 plugin bundle과 같은 검증을 실행합니다.
npx emdash plugin validate --dir ./my-plugin
선택적 --dir은 플러그인 디렉터리를 선택하며 기본값은 현재 디렉터리입니다.
plugin publish
번들을 마켓플레이스에 업로드하고 기본적으로 처리 결과를 기다립니다.
npx emdash plugin publish --tarball ./dist/my-plugin-1.0.0.tar.gz
| Option | Description | Default |
|---|---|---|
--tarball | 기존 플러그인 tarball | — |
--dir | --build와 함께 쓰는 플러그인 디렉터리 | 현재 디렉터리 |
--build | 업로드 전 플러그인 빌드 | false |
--registry | 마켓플레이스 기본 URL | https://marketplace.emdashcms.com |
--no-wait | 처리 결과를 기다리지 않고 업로드 후 종료 | false |
--tarball을 제공하거나, 먼저 --dir에서 빌드하려면 --build를 전달하세요.
plugin login
GitHub device flow로 마켓플레이스에 인증합니다. --registry는 다른 마켓플레이스를 선택하며 기본값은 https://marketplace.emdashcms.com입니다.
npx emdash plugin login
plugin logout
저장된 마켓플레이스 자격 증명을 제거합니다. 선택적 --registry는 로그인에 사용한 것과 같은 마켓플레이스를 식별해야 합니다.
npx emdash plugin logout
emdash export-seed
데이터베이스 스키마와 콘텐츠를 시드 파일로 내보냅니다. 로컬 SQLite 파일에서 직접 작동합니다.
데이터베이스는 설치된 EmDash 버전이 아는 모든 마이그레이션을 가지고 있어야 합니다. 명령이
보류 마이그레이션을 보고하면 npx emdash migrate를 실행한 다음 다시 내보내세요. 데이터베이스가
더 새 EmDash 버전으로 마이그레이션된 경우 내보내기 전에 설치된 버전을 업그레이드하세요. 내보내기는
데이터베이스를 읽기 전용으로 열며 스스로 마이그레이션을 적용하지 않습니다.
npx emdash export-seed [options] > seed.json
옵션
| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | 데이터베이스 파일 경로 | ./data.db |
--cwd | 작업 디렉터리 | 현재 디렉터리 | |
--with-content | 콘텐츠 포함(모두 또는 쉼표로 구분된 컬렉션) | ||
--pretty / --no-pretty | 들여쓴 JSON 출력 사용 또는 사용 안 함 | 프리티 출력 사용 | |
--media-base-url | 절대 $media URL을 쓰는 데 사용하는 사이트의 공개 URL |
출력 형식
내보낸 시드 파일에는 다음이 포함됩니다.
- Settings: 사이트 제목, 태그라인, 소셜 링크
- Collections: 필드가 있는 모든 컬렉션 정의
- Block types: 유지된 모든 버전과 각 타입의 활성 버전 포인터
- Taxonomies: 택소노미 정의와 용어
- Menus: 항목이 있는 탐색 메뉴
- Redirects: 상태 301, 302, 307 또는 308의 리디렉션 규칙
- Widget Areas: 위젯 영역과 위젯
- Sections: 재사용 가능한 콘텐츠 블록
- Content(요청 시): 이식성을 위한
$media참조와$ref:구문이 있는 항목
예약된 항목은 초안으로 내보내집니다. 시드에는 게시 시간 필드가 없기 때문입니다. 내보내기는 stderr에 경고와 함께 emdash seed가 거부할 항목을 제외합니다. 상태 410 또는 451 리디렉션 규칙, 같은 소스를 공유하는 추가 규칙(오래된 데이터베이스에서 가능), 슬러그에 소문자·숫자·하이픈 외 문자가 있는 섹션.
미디어 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에 경고를 출력합니다.
이미지와 파일 필드, 리피터의 이미지 하위 필드는 $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
--write는 --force 없이는 기존 항목 덮어쓰기를 거부합니다. 기존 암호화 데이터가 있는 배포를 교체하려면 생성된 키를 기존 값 앞에 두고 쉼표로 구분하세요. EmDash는 첫 번째 키로 새 값을 암호화하고 복호화에는 이전 항목을 kid로 사용합니다. 이전 키를 제거하기 전에 모든 플러그인 시크릿을 다시 저장하세요. EmDash는 현재 저장된 설정이 아직 사용하는 키 ID를 나열하지 않으므로, 다시 저장하는 자격 증명 목록을 유지하고 이전 키를 제거하기 전에 각 통합을 확인하세요.
secrets fingerprint <key>
값을 노출하지 않고 키의 8자 지문(kid)을 출력합니다. 올바른 키가 배포되었는지 확인하는 CI에 유용합니다. 다음 명령은 키의 지문을 출력합니다.
npx emdash secrets fingerprint emdash_enc_v1_...
emdash auth (사용 중단)
auth secret
레거시 EMDASH_AUTH_SECRET 값을 생성합니다.
npx emdash auth secret
기존 설치는 이 변수를 유지하여 안정적인 댓글 작성자 IP 해시를 보존할 수 있습니다. 플러그인 시크릿은 암호화하지 않습니다.
생성된 파일
emdash-env.d.ts
Astro 통합은 로컬 개발 서버가 시작될 때 프로젝트 루트에 emdash-env.d.ts를 생성합니다. 실행 중인 개발 사이트를 통해 이루어진 스키마 변경 후 파일을 새로 고칩니다. 선언은 EmDashCollections를 확장하므로 getEmDashCollection("posts") 같은 호출은 로컬 데이터베이스에 정의된 필드를 추론합니다.
이 파일은 자동이며 로컬 Astro 개발 워크플로에 속합니다. 만들기 위해 emdash types를 실행할 필요는 없습니다.
.emdash/types.ts
emdash types 명령은 실행 중인 인스턴스의 스키마를 가져와 독립 TypeScript 인터페이스를 씁니다. 스키마가 원격 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도 씁니다. 기본 출력 경로에서 파일은 .emdash/schema.json입니다.
{
"version": "a1b2c3d4",
"collections": [
{
"slug": "posts",
"label": "Posts",
"fields": [...]
}
]
}
환경 변수
| Variable | Description |
|---|---|
EMDASH_DATABASE_URL | 데이터베이스 URL 재정의 |
EMDASH_TOKEN | 원격 작업용 인증 토큰 |
EMDASH_URL | 공유 원격 클라이언트를 사용하는 명령의 기본 URL |
EMDASH_HEADERS | 공유 원격 클라이언트와 login용 줄바꿈으로 구분된 사용자 지정 요청 헤더 |
EMDASH_ENCRYPTION_KEY | 저장 시 플러그인 시크릿 암호화 키. 운영자가 제공 — 데이터베이스에 저장되지 않음. emdash secrets generate로 생성. |
EMDASH_PREVIEW_SECRET | 미리보기 HMAC 시크릿의 선택적 재정의. 설정되지 않으면 EmDash가 옵션 테이블에 생성·유지. |
EMDASH_IP_SALT | 댓글 작성자 IP 해시 솔트의 선택적 재정의. 설정되지 않으면 EmDash가 옵션 테이블에 생성·유지. |
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를 사용합니다.
| Code | Description |
|---|---|
0 | 성공 |
1 | 오류(구성, 네트워크, 데이터베이스) |