設定リファレンス
このページで分かること
astro.config.mjsで指定するEmDashのインテグレーションの設定項目(database、storage、plugins、sandboxRunner、auth、siteUrlなど)- データベース、ストレージ、オブジェクトキャッシュ、認証とサンドボックス、メディアプロバイダー、Astroのキャッシュの各アダプター
src/live.config.tsのローダー、環境変数、package.jsonのemdashの項目、TypeScriptの設定
このページの目次
EmDashの主な設定は astro.config.mjs にあり、src/live.config.ts はコンテンツのローダーを登録します。デプロイ先ごとに異なる値は、環境変数から渡すこともできます。package.json の小さなメタデータのブロックは、テンプレートの表示名と、従来のローカルCLIの手順に使われます。
Astroインテグレーション
astro.config.mjs で、EmDashをAstroのインテグレーションとして設定します。
import { defineConfig } from "astro/config";
import emdash, { local, s3 } from "emdash/astro";
import { sqlite, libsql } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
plugins: [],
}),
],
});
インテグレーションのオプション
database
必須。 データベースアダプターの設定です。次のアダプターから1つを選びます。
// SQLite (Node.js)
database: sqlite({ url: "file:./data.db" });
// PostgreSQL
database: postgres({ connectionString: process.env.DATABASE_URL });
// libSQL
database: libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
});
// Cloudflare D1 (import from @emdash-cms/cloudflare)
database: d1({ binding: "DB" });
詳しくはデータベースの選択肢を参照してください。
migrations
任意。 EmDash内部のデータベースマイグレーションを、実行時にどう扱うかを制御します。このオプションを省略すると { runtime: "auto" } になります。
migrations: {
runtime: "check", // "auto" | "check" | "manual"
dev: "auto", // optional development override
}
auto は保留中のマイグレーションを確認して適用します。check は、実行中のビルドが把握しているマイグレーションが保留中の場合に503を返します。manual は実行時にマイグレーションのクエリを一切発行しません。EMDASH_MIGRATIONS_MODE は、実際に使われる実行時のモードを上書きします。check または manual を使う前に、コアデータベースマイグレーションの管理を参照してください。
storage
任意。 メディアストレージのアダプターの設定です。このオプションを省略すると、EmDashはファイルを ./.emdash/uploads に保存し、/_emdash/api/media/file から配信します。既定のローカルディレクトリーが適さない場合は、アダプターを選びます。
// Local filesystem (development)
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
// R2 binding (Cloudflare Workers)
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev", // optional
});
// S3-compatible (any platform) — all fields from S3_* environment variables
storage: s3()
// Or with explicit values
storage: s3({
endpoint: "https://s3.amazonaws.com",
bucket: "my-bucket",
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
region: "us-east-1", // optional, default: "auto"
publicUrl: "https://cdn.example.com", // optional
});
詳しくはストレージの選択肢を参照してください。
images
任意。 保存したメディアを、Astroの画像最適化と連携させるかどうかを制御します。既定値は true です。
有効にすると、EmDashはAstroの画像エンドポイントをラップし、<Image> と getImage() が、設定したストレージアダプターから元画像のバイト列を直接読み込めるようにします。これは、元のメディアのURLがCloudflare Accessで保護されている場合にも動作します。別の画像サービスがメディアを扱う場合や、すべての画像をEmDashのエンドポイントのラッパーを通さずに描画する場合は、images: false を設定します。
emdash({
images: false,
});
mediaProviders
任意。 メディアライブラリーにメディアサービスを追加します。ストレージを使うローカルのプロバイダーは自動的に使える状態のまま残ります。この配列の記述子(descriptor)1つごとに、編集者がメディアを閲覧またはアップロードできる場所が1つ追加されます。
次の例では、Cloudflare ImagesとCloudflare Streamを追加します。
import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";
emdash({
mediaProviders: [cloudflareImages({}), cloudflareStream({})],
});
プロバイダーの認証情報は実行時に解決されます。上の例の空の設定では、cloudflareImages(config) と cloudflareStream(config) のアダプターの節で説明している、Cloudflareの既定の環境変数を使います。バインディングと描画の設定については、メディアライブラリー:メディアプロバイダーを参照してください。
objectCache
任意。 コンテンツと設定の取得結果をキー・バリューストアにキャッシュし、リクエストのたびにデータベースへクエリを発行せずに読み込みに応答できるようにします。省略すると無効です。次のアダプターから1つを選びます。
// Cloudflare KV (shared across all isolates)
import { kvCache } from "@emdash-cms/cloudflare";
objectCache: kvCache({ binding: "CACHE" });
// In-memory (Node.js / development)
import { memoryCache } from "emdash/astro";
objectCache: memoryCache();
設定方法とオプションについては、オブジェクトキャッシュを参照してください。
middleware.outer
任意。 EmDashのミドルウェア全体の外側に、Astroのミドルウェアのモジュールを登録します。インテグレーションはこのモジュールをAstroの order: "pre" で登録するため、src/middleware.ts で定義したミドルウェアよりも先に実行されます。キャッシュにヒットしたときにランタイムとデータベースの初期化を避ける必要がある、リクエストの入口での判定や、レスポンス全体のキャッシュに使います。EmDashが最終的に出力するHTMLに応じて決まるレスポンスヘッダーにも使えます。
emdash({
middleware: {
outer: "./src/outer-middleware.ts",
},
});
実行順序は次のとおりです。
- 外側のミドルウェアが
await next()まで実行されます。 - EmDashがランタイムとデータベースを初期化し、セットアップ、認証、リクエストコンテキストのミドルウェアを実行します。
- Astroのルートが描画されます。
- EmDashがレスポンスに変更を加えます。これには、ビジュアル編集用のHTMLと、セキュリティ・タイミングのヘッダーが含まれます。
next()が、その最終的なレスポンスを外側のミドルウェアに返します。
next() を呼ぶ前のミドルウェアでは、通常のAstroのリクエストとプラットフォームの実行コンテキストを使えますが、locals.emdash、locals.user、データベース、リクエスト単位のEmDashの状態は使えません。早い段階で Response を返すとEmDashは完全にスキップされるため、そのレスポンスには必要なセキュリティとキャッシュのヘッダーをすべて含める必要があります。next() が値を返したあとは、CSPのnonceの確定、本文全体のキャッシュ、Content-Length の設定を安全に実行できます。ミドルウェアが本文を変更する場合は、既存の Content-Length ヘッダーを削除するか、計算し直してください。
このフックは、NodeとCloudflareのどちらでもAstroのミドルウェアAPIを使います。次の最小限のCloudflare Cache APIの例は、匿名ユーザー向けのHTMLレスポンスだけをキャッシュし、キャッシュにヒットした場合はEmDashの初期化より前に返します。
import { waitUntil } from "cloudflare:workers";
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async ({ request }, next) => {
if (request.method !== "GET" || request.headers.has("cookie")) {
return next();
}
const cacheKey = new Request(request.url, { method: "GET" });
const cached = await caches.default.match(cacheKey);
if (cached) return cached;
const response = await next();
const isHtml = response.headers.get("content-type")?.includes("text/html");
const isPrivate = response.headers.get("cache-control")?.includes("no-store");
if (response.ok && isHtml && !isPrivate) {
waitUntil(caches.default.put(cacheKey, response.clone()));
}
return response;
});
Nodeでは、同じ形のミドルウェアを、RedisなどのNodeで使えるキャッシュと組み合わせて使います。キャッシュキーとキャッシュを使わない条件には、描画されるレスポンスを変えるリクエストの属性をすべて含める必要があります。
playground
任意。 使い捨てのブラウザーで動くEmDashのプレイグラウンドが使うミドルウェアを有効にします。このミドルウェアは、セッションごとに書き込み可能なDurable Objectのデータベースを作成し、設定したシードを適用し、通常のEmDashのミドルウェアが実行される前に、訪問者を匿名の管理者としてサインインさせます。
import { playgroundDatabase } from "@emdash-cms/cloudflare";
emdash({
database: playgroundDatabase({ binding: "PLAYGROUND_DB" }),
playground: {
middlewareEntrypoint: "@emdash-cms/cloudflare/db/playground-middleware",
},
});
このモードには @emdash-cms/cloudflare とDurable Objectのバインディングが必要です。通常のセットアップと認証のミドルウェアを迂回するため、本番のCMSではなく、一時的なデモサイトにだけ使ってください。
plugins
任意。 Astroのサイトと同じプロセスで動くプラグインの配列です。ネイティブ型プラグインはここに指定します。サンドボックス対応のプラグインも、プロセスへの完全なアクセスを許せるほど信頼していて、分離が不要な場合はここで動かせます。
次の例では、ネイティブ型プラグインを登録します。
import seoPlugin from "@emdash-cms/plugin-seo";
plugins: [seoPlugin()];
ネイティブ型プラグインはサーバーとフレームワークのAPIを直接使えるため、パッケージがサンドボックス対応のプラグインのエントリーポイントも提供していない限り、sandboxed に移せません。作り方とデプロイの違いについては、プラグインの形式の選択を参照してください。
sandboxed
任意。 EmDashが定めたプラグインAPIを使い、分離されたランタイムで動く、サンドボックス対応のプラグインの配列です。ネイティブ型プラグインはここに指定しないでください。ネイティブのコードは、サンドボックスが提供しないプロセスやフレームワークへのアクセスに依存している場合があります。
import thirdPartyPlugin from "third-party-emdash-plugin";
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxed: [thirdPartyPlugin()],
sandboxRunner: sandbox(),
});
使用可能なサンドボックスランナーが設定されていない場合、サンドボックス型プラグインはスキップされます。CloudflareとNode.jsのランナーの設定については、プラグインサンドボックスを参照してください。
sandboxRunner
任意。 分離されたプラグインのランタイムを起動するファクトリーの、モジュール指定子です。sandboxed のプラグインと、マーケットプレイスまたはレジストリのプラグインに必要です。
Cloudflare Workersでは、sandbox() アダプターを使います。
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxRunner: sandbox(),
});
Node.jsのデプロイでは、プラグインサンドボックス:Node.jsで説明しているworkerdのランナーモジュールを使います。
sandbox
任意。 設定したサンドボックスランナーでプラグインを分離するかどうかを制御します。sandboxRunner を設定すると、サンドボックスは有効になります。sandbox: false は、問題の原因がプラグインなのか、そのサンドボックスのランタイムなのかを切り分ける場合にだけ設定してください。
emdash({
sandboxRunner: sandbox(),
sandbox: false,
});
false にすると、sandboxed に指定したプラグインとマーケットプレイスからインストールしたプラグインは、分離もリソースの制限もなしに、メインのサーバープロセスで動きます。切り分けが終わったら、サンドボックスを元に戻してください。
registry
任意。 プラグインレジストリのアグリゲーターとポリシーを設定します。値を明示しない場合、sandboxRunner が設定されていて sandbox が false でなければ、EmDashは https://registry.emdashcms.com を使います。
registry: false を設定すると、レジストリでのプラグインの検索と、レジストリからインストールしたプラグインが無効になります。サンドボックスランナーは、sandboxed に指定したプラグインと、従来のMarketplaceのプラグインのために引き続き使えます。
emdash({
sandboxRunner: sandbox(),
registry: false,
});
レジストリサービスのURLは文字列で渡します。サイトでモデレーションの提供元やリリースからの経過期間のポリシーが必要な場合は、オブジェクトを使います。次の例ではオブジェクトの形式を使っています。
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxRunner: sandbox(),
registry: {
aggregatorUrl: "https://registry.emdashcms.com",
acceptLabelers: "did:web:labels.emdashcms.com",
policy: {
minimumReleaseAge: "48h",
minimumReleaseAgeExclude: ["did:plc:yourfirstpartydid"],
},
},
});
| オプション | 型 | 説明 |
|---|---|---|
aggregatorUrl |
string |
レジストリサービスのベースURLです。本番ではHTTPSを使います。 |
acceptLabelers |
string |
任意。リクエストで受け入れるモデレーションサービスの分散型識別子(DID)を、カンマ区切りで指定します。DIDは、Atmosphereアカウントの変わらない識別子です。この設定で、レジストリサービスのポリシーを上書きすることはできません。 |
policy.minimumReleaseAge |
string | number |
この期間より新しいリリースを保留します。期間の文字列("48h"、"7d")または秒数で指定します。 |
policy.minimumReleaseAgeExclude |
string[] |
保留の対象外にする公開者のDID、または <did>/<plugin-slug> の組です。 |
リリースからの経過期間のポリシーがパッケージの最初のリリースを対象外にするのは、保持されているリリースが1つであるとレジストリが報告し、かつレジストリがそのパッケージを継続して観測してきたことを確認できた場合だけです。あとから取り込まれた(backfilled)パッケージ、以前のリリースが削除されたパッケージ、履歴の証拠がないパッケージでは、保留は有効なままです。公開者とパッケージを明示して対象外にした場合は、履歴に関係なく適用されます。
インストールの流れと信頼モデルについては、プラグインレジストリを参照してください。
marketplace
非推奨。 従来のMarketplaceからインストールしたプラグインを更新するために使うベースURLです。管理画面には、Marketplaceの閲覧と新規インストールは表示されません。このオプションを設定している間は、既存のMarketplaceのプラグインの更新とアンインストールを引き続きできます。
emdash({
marketplace: "https://marketplace.emdashcms.com",
sandboxRunner: sandbox(),
});
本番のURLにはHTTPSを使う必要があります。HTTPを使えるのは、開発中の localhost と 127.0.0.1 だけです。このオプションは、すべてのMarketplaceのプラグインを置き換えるかアンインストールするまで残し、その後に削除します。手順全体はMarketplaceからの移行に従ってください。
fonts
任意。 管理画面のUIのフォントの設定です。
既定では、EmDashはAstro Font APIを使ってNoto Sansを読み込みます。フォントはビルド時にGoogleからダウンロードされ、自分のサイトから配信されるため、実行時にCDNへのリクエストは発生しません。基本のフォントは、ラテン文字、キリル文字、ギリシャ文字、デーヴァナーガリー文字、ベトナム語の文字に対応しています。
ほかの文字体系に対応させるには、文字体系の名前を渡します。次の例では、アラビア文字と日本語を追加します。
emdash({
fonts: {
scripts: ["arabic", "japanese"],
},
})
使える文字体系は、arabic、armenian、bengali、chinese-simplified、chinese-traditional、chinese-hongkong、devanagari、ethiopic、farsi、georgian、gujarati、gurmukhi、hebrew、japanese、kannada、khmer、korean、lao、malayalam、myanmar、oriya、sinhala、tamil、telugu、thai、tibetan です。
それぞれの文字体系は、Google Fontsの対応するNoto Sansのバリエーションに対応します(例:"arabic" はNoto Sans Arabicを読み込みます)。すべてのフォントフェイスは1つの font-family 名を共有し、unicode-range を使うため、ブラウザーはページ上の文字に必要なファイルだけをダウンロードします。
フォントの挿入を完全に無効にしてシステムフォントを使うには、false を設定します。
emdash({
fonts: false,
})
管理画面のCSSは、CSS変数 --font-emdash を使います。この変数は、上記のフォントの設定によって自動的に設定されます。
auth
任意。 認証アダプターです。EmDashに組み込まれたログイン方法はパスキーです。auth を設定すると、パスキーが外部のプロバイダーに置き換わります。Cloudflare Accessのアダプター access() は @emdash-cms/cloudflare が提供しています。
import { access } from "@emdash-cms/cloudflare";
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "your-app-audience-tag",
roleMapping: {
Admins: 50,
Editors: 40,
},
}),
});
access() のオプション:
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
teamDomain |
string |
必須 | Cloudflare Accessのチームドメイン |
audience |
string |
— | アプリケーションのAudience(AUD)タグ。Workersでは audienceEnvVar を優先して使います。 |
audienceEnvVar |
string |
"CF_ACCESS_AUDIENCE" |
実行時にAudienceタグを読み込む環境変数 |
autoProvision |
boolean |
true |
初回ログイン時にEmDashのユーザーを作成する |
defaultRole |
number |
30 |
roleMapping に一致しなかったユーザーのロールのレベル(ユーザーのロールを参照) |
syncRoles |
boolean |
false |
ユーザーの作成時だけでなく、ログインのたびに roleMapping を適用し直す |
roleMapping |
object |
— | IdPのグループ名をEmDashのロールのレベルに対応させます。最初に一致したものが使われます |
authProviders
任意。 差し替え可能なログインプロバイダーの配列です(auth と同じくトップレベルに指定します)。次のように、各要素にはプロバイダーのファクトリーを呼び出した結果を指定します。
import { github } from "emdash/auth/providers/github";
import { google } from "emdash/auth/providers/google";
import { atproto } from "@emdash-cms/auth-atproto";
emdash({
authProviders: [github(), google(), atproto()],
});
組み込みのプロバイダー:
github():EMDASH_OAUTH_GITHUB_CLIENT_ID/EMDASH_OAUTH_GITHUB_CLIENT_SECRET(または接頭辞なしの代替の変数)を読み込みます。google():EMDASH_OAUTH_GOOGLE_CLIENT_ID/EMDASH_OAUTH_GOOGLE_CLIENT_SECRETを読み込みます。atproto():Atmosphereアカウントでのログインです(BlueskyとAT Protocolのネットワーク全体)。環境変数は不要です。{ allowedDIDs, allowedHandles, defaultRole }を受け取ります。Atmosphereログインのガイドを参照してください。
サードパーティのパッケージは、同じ AuthProviderDescriptor の形で独自のプロバイダーを登録できます。ログインプロバイダーを参照してください。
mcp
任意。 /_emdash/api/mcp のModel Context Protocol(MCP)のエンドポイントを有効にします。このエンドポイントは既定で有効で、Bearerトークンが必要なため、有効にしても匿名のアクセスは許可されません。
サイトでMCPのエンドポイントを公開してはならない場合は、このオプションを false に設定します。
emdash({
mcp: false,
});
トークンの作成とクライアントの設定については、MCPサーバーリファレンスを参照してください。
siteUrl
任意。 ブラウザーから見たサイトの公開オリジン(スキーム+ホスト+任意でポート。パスは含めない)です。
TLSを終端するリバースプロキシの背後では、Astro.url は公開アドレス(https://cms.example.com)ではなく内部アドレス(http://localhost:4321)を返します。その結果、パスキー、CSRFのオリジン照合、OAuthのリダイレクト、ログイン後のリダイレクト、MCPの検出、スナップショットのエクスポート、サイトマップ、robots.txt、JSON-LDの構造化データが正しく動かなくなります。siteUrl を設定すると、これらをまとめて解決できます。
インテグレーションは、読み込み時にこの値を検証します。値は http: または https: のプロトコルを持つ有効なURLである必要があり、オリジンに正規化されます(パスは取り除かれます)。
次の例では、公開オリジンを設定します。
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
siteUrl: "https://cms.example.com",
});
設定ファイルで siteUrl が設定されていない場合、EmDashは環境変数を EMDASH_SITE_URL、SITE_URL の順に確認します。これは、公開URLを実行時に設定するコンテナーのデプロイで便利です。
Cloudflare Workersでは、環境変数による代替の読み込みは process.env を参照しますが、process.env は互換性フラグ nodejs_compat_populate_process_env を有効にしない限り空です。Workersで設定オプションの代わりに環境変数を使うには、両方を設定します。
// wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat", "nodejs_compat_populate_process_env"],
"vars": { "EMDASH_SITE_URL": "https://cms.example.com" },
}
allowedOrigins
任意。 複数のホスト名で利用できるデプロイについて、パスキーの検証で追加で受け入れるブラウザーのオリジンです。
siteUrl は、正規のオリジンを1つだけ定義します。同じEmDashのデプロイに、登録可能な親ドメインを共有する複数のホスト名(例:https://example.com と https://preview.example.com)でアクセスできる場合、パスキーの検証は、オリジンが siteUrl と完全に一致しないアサーションを拒否します。WebAuthnでは、同じ rpId のもとにあるサブドメインをまたいでパスキーを有効にできるにもかかわらず、拒否されます。
追加で受け入れるオリジンは、astro.config.mjs の allowedOrigins、または環境変数 EMDASH_ALLOWED_ORIGINS のどちらかで宣言します。rpId の元になるのは、引き続き正規の siteUrl です。ここに列挙したオリジンは、検証の時点で受け入れられます。2つの指定元は実行時に統合されるため、変わらないオリジン(バージョン管理され、コードレビューを経たもの)は設定ファイルで宣言し、環境ごとの追加分(例:一時的なPRのプレビュー)は環境変数で加えられます。
次の例では、設定ファイルで追加のオリジンを1つ宣言します。
emdash({
siteUrl: "https://example.com",
allowedOrigins: ["https://preview.example.com"],
})
同じ値を環境変数から渡すこともできます。
EMDASH_SITE_URL=https://example.com
EMDASH_ALLOWED_ORIGINS=https://preview.example.com,https://staging.example.com
検証
ブラウザーが決して受け入れない、意味のない設定を防ぐため、EmDashはこれらの値を検証します。
- 各要素は、解析可能な
http:またはhttps:のURLで、ホスト名の末尾にドットがなく、空のラベルを含まない必要があります。 allowedOriginsが空でない場合、siteUrlが(どちらかの指定元で)設定されている必要があり、siteUrlはIPアドレスのリテラルや、末尾にドットの付いたホスト名であってはなりません。- 各オリジンは、
siteUrlと同じホスト名、またはそのサブドメインである必要があります(WebAuthnでは、rpIdがすべてのオリジンの登録可能なサフィックスである必要があります)。
検証に失敗すると、EmDash config error in EMDASH_ALLOWED_ORIGINS: "https://other-site.com" is not a subdomain of siteUrl "https://example.com". Allowed origins must be the same hostname as siteUrl or a subdomain of it. のような、どの指定元の値かを示すエラーが表示されます。
エラーが表示されるタイミングは、値を宣言した場所によって異なります。
- Astroの起動時:
config.allowedOriginsとconfig.siteUrlの両方がastro.config.mjsにある場合です。コードの入力ミスはビルドの失敗になります。 - 最初のパスキー検証時:どちらかの値が
EMDASH_ALLOWED_ORIGINSまたはEMDASH_SITE_URLから来ている場合です。環境変数の不一致は、最初の検証の試行で500として表面化します。
リバースプロキシの設定
Astroは、公開ホストが許可されている場合にだけ X-Forwarded-* を反映します。ユーザーがアクセスするホスト名(とスキーム)を security.allowedDomains に設定します。astro dev では、Viteがプロキシの Host ヘッダーを受け入れるよう、対応する vite.server.allowedHosts を追加します。
まず allowedDomains(と転送ヘッダー)を正しく設定します。それでも組み立て直されたURLがブラウザーのオリジンとなお異なる場合(前段でTLSが終端され、上流へのリクエストが http:// のままの場合によく起こります)は、siteUrl を使います。
前段でTLSを終端する場合、開発サーバーをループバックにバインドする(astro dev --host 127.0.0.1)だけで足りることがよくあります。プロキシはローカルで接続し、siteUrl は公開HTTPSのオリジンと一致します。
プロキシがクライアントのIPのヘッダーを書き込む場合は、trustedProxyHeaders を設定します。これにより、EmDashのレート制限が、すべてのリクエストを共有の「unknown」キーにまとめるのではなく、実際のクライアントのIPを使えるようになります。
次の設定では、リバースプロキシを使うデプロイ向けに、allowedDomains、vite.server.allowedHosts、siteUrl をまとめて設定します。
import { defineConfig } from "astro/config";
import emdash, { local } from "emdash/astro";
import { sqlite } from "emdash/db";
export default defineConfig({
security: {
allowedDomains: [
{ hostname: "cms.example.com", protocol: "https" },
{ hostname: "cms.example.com", protocol: "http" },
],
},
vite: {
server: {
allowedHosts: ["cms.example.com"],
},
},
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
siteUrl: "https://cms.example.com",
}),
],
});
trustedProxyHeaders
任意。 自分で管理しているリバースプロキシの背後で動かす場合に、クライアントのIPを判定するために信頼するヘッダーです。認証のレート制限(マジックリンク、サインアップ、パスキー、OAuthのデバイスフロー)と、公開のコメントのエンドポイントで使われます。
Cloudflareでは、リクエストに付いている cf オブジェクトが自動的に使われるため、通常はこのオプションを設定する必要はありません。nginx、Caddy、Traefik、Fly、Railwayなどの背後にあるセルフホストのデプロイでは、プロキシが書き込むヘッダーをこのオプションに設定します。これにより、レート制限がすべてのリクエストを「unknown」として扱うのではなく、実際のクライアントのIPごとに集計できるようになります。
次の例では、nginx、Caddy、Traefikが設定する x-real-ip ヘッダーを信頼します。
emdash({
database: sqlite({ url: "file:./data.db" }),
trustedProxyHeaders: ["x-real-ip"],
});
ヘッダーは順番に試されます。*-forwarded-for に一致する値はカンマ区切りのリストとして解析され、最初の要素が使われます。次の例では、Fly.ioのヘッダーを優先し、x-forwarded-for を代わりに使います。
emdash({
trustedProxyHeaders: ["fly-client-ip", "x-forwarded-for"],
});
設定ファイルで指定していない場合、EmDashは環境変数 EMDASH_TRUSTED_PROXY_HEADERS(カンマ区切り)を読み込みます。設定ファイルで明示的に空の配列を指定すると、環境変数より優先されます。
maxUploadSize
任意。 アップロードできるメディアファイルの最大サイズ(バイト単位)です。マルチパートでの直接アップロードと、署名付きURLでのアップロードの両方に適用されます。既定値は 52_428_800(50MB)です。次の例では、上限を100MBに引き上げます。
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
maxUploadSize: 100 * 1024 * 1024, // 100 MB
});
| 値 | 説明 |
|---|---|
number(バイト) |
正の有限な整数である必要があります |
| 省略 | 既定値の50MBになります |
設定した上限を超えるアップロードは、直接アップロードでは 413 Payload Too Large のレスポンスで、署名付きURLでは 400 Validation Error で拒否されます。
admin
任意。 管理画面のEmDashのブランド表示を置き換えます。これらの値は、公開サイトのタイトル、ロゴ、ファビコンを変更しません。
emdash({
admin: {
logo: "/images/agency-logo.webp",
siteName: "Agency CMS",
favicon: "/favicon.ico",
},
});
| オプション | 型 | 説明 |
|---|---|---|
logo |
string |
ログインページとサイドバーに表示するロゴのURLまたはパス |
siteName |
string |
サイドバーとブラウザーのタイトルに表示する名前 |
favicon |
string |
管理画面のページのファビコンのURLまたはパス |
toolbar
任意。 編集ツールバー(公開ページに浮かんで表示される錠剤型の部品)をどのように配信するかを制御します。既定値は "server" です。
| 値 | 動作 |
|---|---|
"server"(既定) |
認証済みの編集者向けに描画するすべてのHTMLレスポンスに、サーバー側でツールバーを挿入します。 |
"client" |
公開HTMLはすべての訪問者で同じになります。小さな起動用スクリプトが、管理画面にログインしたことのあるブラウザーに「Edit」の錠剤型ボタンを表示します。これを選択するとセッションを確認し、クエリパラメーター _edit を付けてページを再読み込みします。このページは常に新しく描画され(キャッシュされることはなく)、完全なツールバーが付きます。 |
false |
ツールバーも起動用スクリプトも描画しません。 |
emdash({
toolbar: "client",
})
公開HTMLを共有キャッシュ(Cloudflare Cache Everything/Workers Cache、Fastly、Varnishなど)から配信している場合は、"client" を使います。サーバー側で挿入する方式では、匿名の訪問者が先にキャッシュを作っていると、公開サイトを閲覧している編集者にも、キャッシュされた匿名向けのもの(ツールバーなし)が返されます。そのため、キャッシュの状態によってツールバーが表示されたり消えたりします。クライアントモードでは、共有できるHTMLにセッション固有のものを何も挿入しないため、キャッシュが完全に効いたまま、ツールバーも確実に表示されます。
"client" モードについての注意:
- ログアウトしている訪問者が共有された
?_editのURLを開くと、正規のURLにリダイレクトされます。そのため、このパラメーターから下書きが漏れたり、ページの内容を含む余分なキャッシュのエントリーが作られたりすることはありません。 - 「ログイン済み」の目印は、管理画面が設定する秘密ではない
localStorageのフラグです。錠剤型ボタンは、編集画面に入る前に実際のセッションを確認します。 - 起動用スクリプトは小さなインラインの
<script>です。サイトが'unsafe-inline'なしの厳格なContent-Security-Policyを送っている場合は、このスクリプトのハッシュを追加してください。サーバー側で挿入するツールバーにも同じことが当てはまります。 - EmDashはセッション固有のものを何も挿入しません。ただし、自分のテンプレートが
Astro.locals.userによって分岐している場合(例:ログイン済みのユーザー向けの「Admin」のナビゲーションリンク)、その違いはHTMLに残るため、キャッシュは引き続き分かれます。
どのモードでも、ツールバーはブラウザー上で×ボタンから閉じられます(ブラウザーごとに、編集者が次に管理画面を開くまで有効です)。プレビューと編集モードのレスポンスは、常に Cache-Control: private, no-store 付きでサーバー側で描画されます。
experimental
任意。 マイナーリリースで動作や通信の形式が変わったり、削除されたりする可能性がある、明示的に有効にする機能です。各フィールドは個別に有効にします。
experimental.registry
非推奨。 トップレベルの registry オプションを使います。トップレベルのオプションを省略している場合、既存の experimental.registry の設定は引き続き動作します。両方がある場合は、トップレベルの値が優先されます。
次の変更では、既存のレジストリのURLをトップレベルに移します。
emdash({
experimental: {
registry: "https://registry.example.com",
},
registry: "https://registry.example.com",
});
データベースアダプター
アダプターは emdash/db からインポートします。
import { sqlite, libsql, postgres } from "emdash/db";
sqlite(config)
Node.jsに組み込まれたデータベースドライバーを使うSQLiteのデータベースです。次の例では、ローカルのファイルに接続します。
| オプション | 型 | 説明 |
|---|---|---|
url |
string |
file: の接頭辞を付けたファイルパス |
sqlite({ url: "file:./data.db" });
libsql(config)
libSQLのデータベースです。次の例では、リモートのlibSQLのデータベースに接続します。
| オプション | 型 | 説明 |
|---|---|---|
url |
string |
データベースのURL |
authToken |
string |
実行時の認証トークン(ローカルのファイルでは任意) |
migrationAuthTokenEnv |
string |
マイグレーション用のトークンの変数名(既定値は TURSO_AUTH_TOKEN) |
libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
});
postgres(config)
コネクションプーリングを備えたPostgreSQLのデータベースです。
| オプション | 型 | 説明 |
|---|---|---|
connectionString |
string |
PostgreSQLの接続URL |
host |
string |
データベースのホスト |
port |
number |
データベースのポート |
database |
string |
データベース名 |
user |
string |
データベースのユーザー |
password |
string |
データベースのパスワード |
ssl |
boolean |
SSLを有効にする |
pool.min |
number |
プールの最小サイズ(既定値:0) |
pool.max |
number |
プールの最大サイズ(既定値:10) |
pool.connectionTimeoutMillis |
number |
接続を待つ最大時間(pgの既定値:0、タイムアウトなし) |
pool.idleTimeoutMillis |
number |
アイドル状態のクライアントの存続時間(pgの既定値:10,000ms) |
migrationConnectionStringEnv |
string |
マイグレーション用の接続文字列の変数名(既定値は DATABASE_URL) |
次の例では、接続文字列で接続します。
postgres({ connectionString: process.env.DATABASE_URL });
d1(config)
Cloudflare D1のデータベースです。@emdash-cms/cloudflare からインポートします。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
binding |
string |
— | wrangler.jsonc のD1のバインディング名 |
session |
string |
"disabled" |
読み取りレプリケーションのモード:"disabled"、"auto"、"primary-first" |
bookmarkCookie |
string |
"__em_d1_bookmark" |
セッションのブックマークに使うCookieの名前 |
coalesce |
boolean |
false |
同じイベントループのターン内で同時に発生した読み取りをまとめて処理します。"disabled" 以外のセッションモードが必要です |
次の例は、基本のバインディングと、読み取りレプリカを有効にしたバインディングです。
// Basic
d1({ binding: "DB" });
// With read replicas
d1({ binding: "DB", session: "auto" });
session が "auto" または "primary-first" の場合、EmDashはD1 Sessions APIを使って、読み取りのクエリを近くのレプリカに振り分けます。認証済みのユーザーには、ブックマークによって、自分が書き込んだ内容を直後に読める一貫性(read-your-writes)が保証されます。詳しくはデータベースの選択肢:読み取りレプリカを参照してください。
hyperdrive(config?)
Cloudflare Hyperdriveのバインディングを通して使うPostgreSQLです。このアダプターは @emdash-cms/cloudflare からインポートします。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
binding |
string |
"HYPERDRIVE" |
クエリキャッシュを無効にした、主となるHyperdriveのバインディング |
cachedBinding |
string |
— | 任意。匿名ユーザーの公開の読み取りに使う、キャッシュを有効にした2つ目のバインディング |
preferUncachedAfterWriteMs |
number |
60_000 |
cachedBinding を設定している場合に、コンテンツの書き込み後、公開の読み取りが主のバインディングを使う期間 |
migrationConnectionStringEnv |
string |
主のバインディングから導出 | emdash migrate が使う、PostgreSQLへの直接のURLを格納した環境変数 |
max |
number |
5 |
1つのWorkerのisolateからHyperdriveへの最大接続数 |
次の例では、認証済みのリクエストと書き込みをキャッシュなしのバインディングに振り分け、匿名ユーザーの公開の読み取りではキャッシュ付きのバインディングを使えるようにします。
hyperdrive({
binding: "HYPERDRIVE",
cachedBinding: "HYPERDRIVE_CACHED",
preferUncachedAfterWriteMs: 60_000,
});
両方のバインディングは、同じデータベースを指している必要があります。pg のバージョン8.16.3以降をインストールし、互換性フラグ nodejs_compat を有効にし、デプロイ時のマイグレーションのためにデータベースへの直接のURLを設定します。Workerとマイグレーションの設定全体については、データベースの選択肢:Hyperdriveを参照してください。
durableObjects(config)
CMSを、SQLiteを使う1つのDurable Objectに保存します。このアダプターは @emdash-cms/cloudflare からインポートします。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
binding |
string |
必須 | EmDashDB クラスのDurable Objectの名前空間のバインディング |
name |
string |
"emdash" |
シングルトンのオブジェクト名。1つのバインディングの背後で複数のデータベースを分ける場合にだけ変更します |
session |
string |
"disabled" |
"auto" は、匿名ユーザーの読み取りをレプリカに、書き込みを主に振り分けます |
bookmarkCookie |
string |
"__em_do_bookmark" |
"auto" モードで、自分が書き込んだ内容を直後に読める一貫性のために使うCookie |
durableObjects({ binding: "DB_DO", session: "auto" });
レプリカへの振り分けには、互換性フラグ experimental と replica_routing に加えて、wrangler.jsonc のDurable Objectのクラスとマイグレーションの記述が必要です。
previewDatabase(config)
プレビューのセッションごとに、分離されたスナップショットのデータベースを1つ、Durable Objectの中に作成します。オプションは必須の binding 名だけです。
previewDatabase({ binding: "PREVIEW_DB" });
このアダプターはプレビューの仕組みのためのもので、本番サイトの主データベース用ではありません。
playgroundDatabase(config)
プレイグラウンドのセッションごとに、シードを適用した書き込み可能なデータベースを1つ、Durable Objectの中に作成します。インテグレーションの playground オプションと組み合わせて使います。
playgroundDatabase({ binding: "PLAYGROUND_DB" });
必須の binding は、プレイグラウンドのDurable Objectの名前空間を示します。このアダプターは、使い捨てのデモサイトにだけ使います。
ストレージアダプター
local と s3 は emdash/astro からインポートします。r2 アダプターは @emdash-cms/cloudflare からインポートします。
import emdash, { local, s3 } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
local(config)
ローカルのファイルシステムのストレージです。次の例では、ローカルのディレクトリーからアップロードしたファイルを配信します。
| オプション | 型 | 説明 |
|---|---|---|
directory |
string |
ディレクトリーのパス |
baseUrl |
string |
ファイルを配信するベースURL |
local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
r2(config)
Cloudflare R2のバインディングです。次の例では、公開URL付きのR2のバインディングを使います。
| オプション | 型 | 説明 |
|---|---|---|
binding |
string |
R2のバインディング名 |
publicUrl |
string |
任意の公開URL |
r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});
s3(config?)
S3互換のストレージです。設定のフィールドはすべて任意です。s3({...}) で省略したフィールドは、Nodeのプロセスの起動時に、対応する S3_* 環境変数から解決されます。明示した値が常に優先されます。
設定ファイルの値と環境変数の値を統合したあと、endpoint と bucket は必須です。認証情報のどちらか一方を設定した場合は、accessKeyId と secretAccessKey の両方が必要です。値が足りない場合は、エラーコード MISSING_S3_CONFIG で起動に失敗します。
前提条件: プロジェクトに @aws-sdk/client-s3 と @aws-sdk/s3-request-presigner をインストールします。EmDashのコアにはAWS SDKは同梱されていません。詳しくはストレージの選択肢:S3互換ストレージを参照してください。
| オプション | 型 | 説明 |
|---|---|---|
endpoint |
string |
S3のエンドポイントのURL(S3_ENDPOINT) |
bucket |
string |
バケット名(S3_BUCKET) |
accessKeyId |
string |
アクセスキー(S3_ACCESS_KEY_ID) |
secretAccessKey |
string |
シークレットキー(S3_SECRET_ACCESS_KEY) |
region |
string |
リージョン。既定値は "auto"(S3_REGION) |
publicUrl |
string |
任意のCDNのURL(S3_PUBLIC_URL) |
次の例は、すべてのフィールドを環境変数から解決する場合、設定ファイルと環境変数を組み合わせる場合、すべてのフィールドを明示する場合です。
// All fields from S3_* environment variables (Node container deployments)
s3()
// Mix: CDN from config, rest from environment
s3({ publicUrl: "https://cdn.example.com" })
// All explicit
s3({
endpoint: "https://xxx.r2.cloudflarestorage.com",
bucket: "media",
accessKeyId: process.env.R2_ACCESS_KEY_ID,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
publicUrl: "https://cdn.example.com",
})
実行時に環境変数から値を解決する機能は、Nodeだけの機能です。Cloudflare Workersでは、シークレットと変数は process.env ではなくfetchハンドラーの env パラメーターを通して渡されるため、S3_* 環境変数は読み込まれません。Workersのデプロイでは、r2(config) アダプターを使うか、s3({...}) に値を明示して渡します。詳しくはストレージの選択肢を参照してください。
オブジェクトキャッシュのアダプター
次のどちらかを objectCache オプションに渡します。
kvCache(config)
すべてのisolateで共有されるCloudflare KVのバックエンドです。@emdash-cms/cloudflare からインポートします。
kvCache({
binding: "CACHE", // KV binding name (required)
defaultTtl: 3600, // entry TTL in seconds (optional, KV minimum 60)
revalidate: 1000, // cross-isolate staleness window in ms (optional)
timeout: 2000, // per-op timeout in ms before a miss (optional, 0 disables)
keyPrefix: "em", // cache key prefix (optional)
})
memoryCache(config?)
Node.jsと開発用の、プロセス内のバックエンドです。emdash/astro からインポートします。
memoryCache({
defaultTtl: 3600, // entry TTL in seconds (optional)
revalidate: 1000, // staleness window in ms (optional)
maxEntries: 1000, // max cached keys before eviction (optional)
keyPrefix: "em", // cache key prefix (optional)
})
設定方法と動作については、オブジェクトキャッシュを参照してください。
認証とサンドボックスのアダプター
これらのアダプターは、インテグレーションの auth と sandboxRunner のオプションに渡す値を返します。
access(config)
組み込みのパスキーによるログインを、Cloudflare Accessの認証に置き換えます。@emdash-cms/cloudflare からインポートし、戻り値を auth に渡します。
import { access } from "@emdash-cms/cloudflare";
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audienceEnvVar: "CF_ACCESS_AUDIENCE",
}),
});
teamDomain は必須です。アダプターは、アプリケーションのAudienceを audience から、または audienceEnvVar で指定した名前の変数から読み込めます。autoProvision、defaultRole、syncRoles、roleMapping も受け取ります。これらの既定値とロールの動作は、auth オプションで説明しています。
sandbox()
プラグインのサンドボックスランナーとして、CloudflareのWorker Loaderを選びます。@emdash-cms/cloudflare からインポートし、戻り値を sandboxRunner に渡します。
import { sandbox } from "@emdash-cms/cloudflare";
emdash({
sandboxRunner: sandbox(),
});
サイトには、Worker Loaderのバインディングと、プラグインのブリッジのエントリーポイントも必要です。これらのデプロイの設定については、プラグインサンドボックス:Cloudflare Workersを参照してください。
メディアプロバイダーのアダプター
メディアプロバイダーの記述子を mediaProviders に渡します。組み込みのCloudflareのプロバイダーは、どちらも @emdash-cms/cloudflare からインポートします。
cloudflareImages(config)
画像アセットの閲覧、アップロード、削除、配信のために、Cloudflare Imagesを追加します。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
accountId |
string |
CF_ACCOUNT_ID から |
CloudflareのアカウントID |
accountIdEnvVar |
string |
"CF_ACCOUNT_ID" |
accountId を省略した場合に使う変数 |
accountHash |
string |
CF_IMAGES_ACCOUNT_HASH から |
配信URLに使うアカウントのハッシュ |
accountHashEnvVar |
string |
"CF_IMAGES_ACCOUNT_HASH" |
accountHash を省略した場合に使う変数 |
apiToken |
string |
CF_IMAGES_TOKEN から |
Cloudflare Imagesの読み取りと編集の権限を持つトークン |
apiTokenEnvVar |
string |
"CF_IMAGES_TOKEN" |
apiToken を省略した場合に使う変数 |
deliveryDomain |
string |
imagedelivery.net |
画像を配信する独自のホスト名 |
defaultVariant |
string |
"public" |
表示に使う画像のバリアント |
mediaProviders: [cloudflareImages({ defaultVariant: "public" })];
cloudflareStream(config)
動画アセットの閲覧、検索、アップロード、削除、再生のために、Cloudflare Streamを追加します。
| オプション | 型 | 既定値 | 説明 |
|---|---|---|---|
accountId |
string |
CF_ACCOUNT_ID から |
CloudflareのアカウントID |
accountIdEnvVar |
string |
"CF_ACCOUNT_ID" |
accountId を省略した場合に使う変数 |
apiToken |
string |
CF_STREAM_TOKEN から |
Cloudflare Streamの読み取りと編集の権限を持つトークン |
apiTokenEnvVar |
string |
"CF_STREAM_TOKEN" |
apiToken を省略した場合に使う変数 |
customerSubdomain |
string |
Cloudflareの既定値 | Streamを配信する独自のホスト名 |
controls |
boolean |
true |
プレーヤーのコントロールを表示する |
autoplay |
boolean |
false |
自動的に再生を開始する |
loop |
boolean |
false |
繰り返し再生する |
muted |
boolean |
false(autoplayの場合は true) |
音声をミュートして再生する |
mediaProviders: [cloudflareStream({ controls: true })];
必要なバインディングと描画用のコンポーネントについては、メディアライブラリー:メディアプロバイダーを参照してください。
Astroのキャッシュアダプター
cloudflareCache(config?)
この従来のアダプターは、Workers Cache APIにレスポンスを保存し、Cloudflare REST APIを通してキャッシュタグでパージするAstroの cache.provider を返します。
import { cloudflareCache } from "@emdash-cms/cloudflare";
export default defineConfig({
cache: {
provider: cloudflareCache(),
},
});
cacheName(既定値 "emdash")と bookmarkCookie(既定値 "__em_d1_bookmark")に加え、タグによるパージのリクエストのために、zoneId または zoneIdEnvVar と、apiToken または apiTokenEnvVar を受け取ります。既定の変数名は CF_ZONE_ID と CF_CACHE_PURGE_TOKEN です。
ライブコレクション
src/live.config.ts でEmDashのローダーを設定します。
import { defineLiveCollection } from "astro:content";
import { emdashLoader } from "emdash/runtime";
export const collections = {
_emdash: defineLiveCollection({
loader: emdashLoader(),
}),
};
ローダーのオプション
emdashLoader() 関数は引数を取りません。
emdashLoader();
環境変数
EmDashは次の環境変数を参照します。
| 変数 | 説明 |
|---|---|
EMDASH_SITE_URL |
ブラウザーから見た公開オリジン(未設定の場合は SITE_URL を使います) |
EMDASH_ALLOWED_ORIGINS |
パスキーの検証で追加で受け入れるオリジンのカンマ区切りのリスト(複数のサブドメインで使うデプロイ向け)。 |
EMDASH_DATABASE_URL |
データベースのURLを上書きします |
EMDASH_ENCRYPTION_KEY |
保存されたプラグインの秘密情報を暗号化するためのキー。運用者が用意します。データベースには決して保存されません。 |
EMDASH_PREVIEW_SECRET |
任意。プレビューのHMACのシークレットを上書きします。未設定の場合は、サイトごとに変わらない値が生成され、データベースに保存されます。 |
EMDASH_IP_SALT |
任意。コメント投稿者のIPのハッシュに使うソルトを上書きします。未設定の場合は、サイトごとに変わらない値が生成され、データベースに保存されます。 |
EMDASH_AUTH_SECRET |
従来の変数。設定されている場合は、IPのソルトの元として使われます。既存のインストールでは、アップグレード後もコメント投稿者のIPのハッシュを変えないために、この変数を残しておく必要があります。 |
EMDASH_TURNSTILE_SECRET_KEY |
Cloudflare Turnstileのシークレットキー(未設定の場合は TURNSTILE_SECRET_KEY を使います)。設定すると、コメントの送信には有効なTurnstileのトークンが必要になります。<CommentForm> の turnstileSiteKey プロパティと組み合わせて使います。 |
EMDASH_URL |
スキーマの同期に使う、リモートのEmDashのURL |
次のコマンドで暗号化キーを生成します。
npx emdash secrets generate
package.jsonの設定
テンプレートとサイトは、package.json の emdash キーの下に、任意のメタデータを宣言できます。
{
"emdash": {
"label": "My Blog Template",
"schema": ".emdash/schema.sql",
"seed": ".emdash/seed.json",
"url": "https://my-site.pages.dev"
}
}
| オプション | 説明 |
|---|---|
label |
表示用のテンプレート名 |
schema |
emdash init が読み込む任意のSQLのスキーマ |
seed |
シードのJSONファイルのパス |
url |
非推奨の emdash dev --types の手順で使うリモートのURL |
TypeScriptの設定
ローカルでの開発中、Astroのインテグレーションはプロジェクトのルートに emdash-env.d.ts を生成し、スキーマの変更後に更新します。このファイルは emdash モジュールを拡張するため、標準の getEmDashCollection() と getEmDashEntry() のインポートは、パスのエイリアスなしでローカルのコレクションのフィールドの型を推論します。
別の emdash types コマンドは、動作中のローカルまたはリモートのインスタンスからスキーマを取得し、既定では .emdash/types.ts に書き出します。アプリケーションのコードがこの単独の出力を直接インポートする場合にだけ、エイリアスを追加します。
{
"compilerOptions": {
"paths": {
"@emdash-cms/types": ["./.emdash/types.ts"]
}
}
}
リモートのスキーマから単独の型を生成するには、次のコマンドを実行します。
npx emdash types