CLI EmDash
Le CLI EmDash (emdash ou ec) gère les instances EmDash CMS. Les commandes se divisent en deux catégories :
- Commandes locales — fonctionnent directement sur un fichier SQLite, aucun serveur en cours d'exécution requis :
init,dev,seed,export-seed,auth secret - Commandes distantes — communiquent avec une instance EmDash en cours d'exécution via HTTP :
types,login,logout,whoami,content,schema,media,search,taxonomy,menu
Authentification
Les commandes distantes résolvent l'authentification automatiquement :
- Drapeau
--token - Variable d'environnement
EMDASH_TOKEN - Credentials stockés depuis
emdash login - Contournement dev (localhost uniquement — aucun token requis)
Pour les serveurs de développement locaux, exécutez simplement la commande — l'authentification est gérée automatiquement. Pour les instances distantes, exécutez d'abord emdash login --url https://my-site.pages.dev.
En-têtes personnalisés et proxies inverses
Les sites derrière Cloudflare Access ou d'autres proxies inverses ont besoin d'en-têtes d'authentification à chaque requête. Le CLI le supporte via des drapeaux --header et des variables d'environnement.
Jetons de service (recommandé pour CI/Automation)
# En-tête unique
npx emdash login --url https://my-site.pages.dev \
--header "CF-Access-Client-Id: xxx.access" \
--header "CF-Access-Client-Secret: yyy"
# Forme courte
npx emdash login -H "CF-Access-Client-Id: xxx" -H "CF-Access-Client-Secret: yyy"
# Via environnement (séparé par des sauts de ligne)
export EMDASH_HEADERS="CF-Access-Client-Id: xxx
CF-Access-Client-Secret: yyy"
npx emdash login --url https://my-site.pages.dev
Les en-têtes sont persistés dans ~/.config/emdash/auth.json après la connexion, donc les commandes suivantes les héritent automatiquement.
Flux navigateur Cloudflare Access
Si vous n'avez pas de jetons de service et que cloudflared est installé, le CLI fera automatiquement :
- Détecter quand Access bloque la requête
- Essayer d'obtenir un JWT mis en cache via
cloudflared access token - Revenir à
cloudflared access loginpour l'authentification par navigateur
Cela fonctionne pour une utilisation interactive mais n'est pas adapté à CI. Utilisez les jetons de service pour l'automation.
Authentification proxy inverse générique
Le drapeau --header fonctionne avec n'importe quel schéma d'authentification :
# Authentification Basic
npx emdash login --url https://example.com -H "Authorization: Basic dXNlcjpwYXNz"
# En-tête d'authentification personnalisé
npx emdash login --url https://example.com -H "X-API-Key: secret123"
Référence rapide
Configuration de la base de données
Les migrations et l'application de seed se font automatiquement dans le runtime — il n'y a pas d'étape init/seed séparée. Démarrez simplement le serveur de dev (ou déployez) et la première requête exécute les migrations en attente et applique le seed groupé si la base de données est vide.
# Démarrer le serveur de dev (exécute les migrations, applique le seed sur une DB vide, démarre Astro)
npx emdash dev
# Démarrer le serveur de dev et générer les types à partir du serveur distant
npx emdash dev --types
# Exporter une base de données existante en tant que fichier seed
# (le runtime découvre automatiquement .emdash/seed.json au premier démarrage ;
# `mkdir -p` car le répertoire peut ne pas exister encore)
mkdir -p .emdash
npx emdash export-seed > .emdash/seed.json
npx emdash export-seed --with-content > .emdash/seed.json
Génération de types
# Générer les types à partir du serveur de dev local
npx emdash types
# Générer à partir du serveur distant
npx emdash types --url https://my-site.pages.dev
# Chemin de sortie personnalisé
npx emdash types --output src/types/cms.ts
Écrit .emdash/types.ts (interfaces TypeScript) et .emdash/schema.json.
Authentification
# Se connecter (OAuth Device Flow)
npx emdash login --url https://my-site.pages.dev
# Vérifier l'utilisateur actuel
npx emdash whoami
# Se déconnecter
npx emdash logout
# Générer un secret d'authentification pour le déploiement
npx emdash auth secret
CRUD de contenu
Le CLI est conçu pour les agents. La création et la mise à jour se publient automatiquement par défaut, donc les agents obtiennent la cohérence lecture-après-écriture sans gérer les brouillons.
# Lister le contenu
npx emdash content list posts
npx emdash content list posts --status published --limit 10
# Obtenir un élément unique (champs Portable Text convertis en markdown)
# Retourne les données du brouillon s'il existe un brouillon en attente
npx emdash content get posts 01ABC123
npx emdash content get posts 01ABC123 --raw # ignorer la conversion PT->markdown
npx emdash content get posts 01ABC123 --published # ignorer les brouillons en attente
# Créer du contenu (se publie automatiquement par défaut)
npx emdash content create posts --data '{"title": "Hello", "body": "# World"}'
npx emdash content create posts --file post.json --slug hello-world
npx emdash content create posts --draft --data '...' # garder en tant que brouillon
cat post.json | npx emdash content create posts --stdin
# Mettre à jour (nécessite --rev d'un get antérieur, se publie automatiquement par défaut)
npx emdash content update posts 01ABC123 --rev MToyMDI2... --data '{"title": "Updated"}'
npx emdash content update posts 01ABC123 --rev MToyMDI2... --draft --data '...' # garder en tant que brouillon
# Supprimer (suppression logicielle)
npx emdash content delete posts 01ABC123
# Cycle de vie
npx emdash content publish posts 01ABC123
npx emdash content unpublish posts 01ABC123
npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z
npx emdash content restore posts 01ABC123
Gestion du schéma
# Lister les collections
npx emdash schema list
# Obtenir la collection avec les champs
npx emdash schema get posts
# Créer une collection
npx emdash schema create articles --label Articles --description "Blog articles"
# Supprimer une collection
npx emdash schema delete articles --force
# Ajouter un champ
npx emdash schema add-field posts body --type portableText --label "Body Content"
npx emdash schema add-field posts featured --type boolean --required
# Supprimer un champ
npx emdash schema remove-field posts featured
Types de champ : string, text, number, integer, boolean, datetime, select, multiSelect, image, file, reference, portableText, json, slug, url. Voir FIELD_TYPE_TO_COLUMN dans packages/core/src/schema/types.ts pour la liste faisant autorité.
Médias
# Lister les médias
npx emdash media list
npx emdash media list --mime image/png
# Télécharger
npx emdash media upload ./photo.jpg --alt "A sunset" --caption "Bristol, 2026"
# Obtenir / supprimer
npx emdash media get 01MEDIA123
npx emdash media delete 01MEDIA123
Recherche
npx emdash search "hello world"
npx emdash search "hello" --collection posts --limit 5
Taxonomies
npx emdash taxonomy list
npx emdash taxonomy terms categories
npx emdash taxonomy add-term categories --name "Tech" --slug tech
npx emdash taxonomy add-term categories --name "Frontend" --parent 01PARENT123
Menus
npx emdash menu list
npx emdash menu get primary
Brouillons et publication
Le CLI se publie automatiquement lors de create et update par défaut. Cela signifie :
createcrée l'élément et le publie immédiatementupdatemet à jour l'élément et publie si une révision de brouillon a été crééegetretourne les données du brouillon s'il existe un brouillon en attente (par ex. depuis l'interface d'admin)
Utilisez --draft sur create/update pour ignorer la publication automatique. Utilisez --published sur get pour ignorer les brouillons en attente.
Les collections qui supportent les révisions stockent les modifications sous forme de révisions de brouillon. Le CLI gère cela de manière transparente — les agents n'ont pas besoin de savoir si une collection utilise des révisions ou non.
Sortie JSON
Toutes les commandes distantes supportent --json pour une sortie lisible par machine. Elle est activée automatiquement quand stdout est redirigée.
# Redirection vers jq
npx emdash content list posts --json | jq '.items[].slug'
# Utiliser dans des scripts
ID=$(npx emdash content create posts --data '{"title":"Hello"}' --json | jq -r '.id')
Flux d'édition
Pour plus de détails sur le fonctionnement de l'édition de contenu — conversion Portable Text/markdown, jetons _rev, et mode brut — voir EDITING-FLOW.md.