シードファイル

このページ

シードファイルは、EmDash サイトの初期スキーマと任意のサンプルデータを記述します。現在のテンプレートはこれを seed/seed.json に置き、package.json#emdash.seed で指します。

EmDash はビルド時にシードを埋め込みます。初回セットアップと明示的なシードコマンド向けであり、デプロイのたびに実行されるマイグレーションではありません。

ファイルの検出

Astro 統合は次の順でシードを探します。

  1. .emdash/seed.json
  2. package.json#emdash.seed のパス
  3. seed/seed.json
  4. ユーザーシードがない場合の組み込みデフォルトシード

次のパッケージフィールドがテンプレートの慣例パスを選びます。

{
  "emdash": {
    "seed": "seed/seed.json"
  }
}

ルート形状

次の例にはすべてのルートプロパティが含まれています。

{
  "$schema": "https://emdashcms.com/seed.schema.json",
  "version": "1",
  "defaultLocale": "en",
  "meta": {
    "name": "Publication",
    "description": "A publication seed",
    "author": "Example Studio"
  },
  "settings": {},
  "blockTypes": [],
  "collections": [],
  "relations": [],
  "taxonomies": [],
  "bylines": [],
  "content": {},
  "menus": [],
  "redirects": [],
  "widgetAreas": [],
  "sections": []
}
プロパティ必須用途
$schemaいいえエディタ用のスキーマ URL
versionはいシード形式。受け付ける値は "1" のみ
defaultLocaleいいえlocale を省略したロケール付きの行に使うロケール。デフォルトはランタイム設定、次に en
metaいいえセットアップ中に表示される説明用の名前、説明、作成者
settingsいいえサイト設定の一部
blockTypesいいえblocks フィールドが使うバージョン付き定義
collectionsいいえコレクションとフィールドの定義
taxonomiesいいえタクソノミー定義と任意の用語
bylinesいいえ任意の表示クレジット用プロフィール
contentいいえコレクションスラッグごとにまとめたサンプルエントリ
menusいいえメニューとネストされた項目
redirectsいいえローカルのリダイレクトルール
widgetAreasいいえウィジェットエリアとウィジェット
sectionsいいえ再利用可能な Portable Text のセクション

defaultLocale は、先頭と末尾に空白がない空でない文字列である必要があります。

設定

settings はサイト設定の一部を表すオブジェクトです。一般的なプロパティは title、tagline、logo、favicon、url、postsPerPage、dateFormat、timezone、social、seo です。

セットアップウィザードでは、管理者がシードされたタイトルとタグラインを置き換えられます。デフォルトの onConflict: "skip" では、シードを再適用してもそれらの値は保持され、提供された設定のうちまだ不足しているものが補われます。

{
  "version": "1",
  "settings": {
    "title": "Field Notes",
    "tagline": "Reports from the team",
    "postsPerPage": 12,
    "dateFormat": "MMMM d, yyyy",
    "timezone": "Europe/London"
  }
}

ブロックタイプ

blockTypes は、blocks コレクションフィールドが使うバージョン付きの形状を定義します。EmDash はこれらの定義をコレクションより先に適用するため、フィールドは validation.allowedTypes でそれらを指名できます。

次のシードは、保存済みコンテンツとリビジョンのためにバージョン 1 を保持しつつ、新しいブロックではバージョン 2 を有効にします。

{
  "version": "1",
  "blockTypes": [
    {
      "slug": "hero",
      "label": "Hero",
      "category": "Layout",
      "currentVersion": 2,
      "versions": [
        {
          "version": 1,
          "fields": [
            { "slug": "heading", "label": "Heading", "type": "string", "required": true }
          ]
        },
        {
          "version": 2,
          "fields": [
            { "slug": "title", "label": "Title", "type": "string", "required": true },
            { "slug": "image", "label": "Image", "type": "image" }
          ]
        }
      ]
    }
  ],
  "collections": [
    {
      "slug": "pages",
      "label": "Pages",
      "fields": [
        {
          "slug": "layout",
          "label": "Layout",
          "type": "blocks",
          "validation": { "allowedTypes": ["hero"], "maxItems": 20 }
        }
      ]
    }
  ]
}

バージョン番号は 1 から始まる連続した正の整数です。currentVersion は宣言済みのバージョンのいずれかを指名する必要があります。シードをエクスポートして再適用しても、バージョン番号と有効バージョンへのポインタはそのまま保持されます。EmDash が番号を振り直すことはありません。

onConflict: "update" では、新しい定義に互換性がある場合にのみ、シードは保存済みのバージョンを修正できます。互換性のない定義で既存の番号を再利用すると、BLOCK_TYPE_VERSION_CONFLICT で失敗します。破壊的な定義には新しいバージョン番号を追加してください。

保存されたブロック値には _type、_version、_key が含まれます。シードコンテンツが保持されたバージョンを対象にする場合は、これらのプロパティを指定してください。新しく書き込まれるブロックがこれらを省略した場合、ランタイムが有効なバージョンとキーを割り当てます。

コレクション

コレクションには slug、label、fields が必要です。

{
  "version": "1",
  "collections": [
    {
      "slug": "posts",
      "label": "Posts",
      "labelSingular": "Post",
      "description": "Published articles",
      "supports": ["drafts", "revisions", "scheduling", "search", "seo"],
      "urlPattern": "/posts/{slug}",
      "routable": true,
      "commentsEnabled": true,
      "editLocking": true,
      "titleField": "title",
      "dateField": "event_date",
      "admin": {
        "listColumns": ["event_date"]
      },
      "fields": [
        { "slug": "title", "label": "Title", "type": "string", "required": true },
        { "slug": "event_date", "label": "Event date", "type": "datetime", "indexed": true },
        { "slug": "content", "label": "Content", "type": "portableText" }
      ]
    }
  ]
}

コレクションプロパティ

プロパティ型動作
slugstring必須のデータベース/API 名。小文字で始まり、小文字・数字・アンダースコアを含む
labelstring必須の複数形 UI ラベル
labelSingularstring任意の単数形 UI ラベル
descriptionstring任意の管理画面の説明
iconstringサイドバーの項目に使う Phosphor アイコン名。例: calendar-blank
admin.listColumnsstring[]コンテンツリストに表示する、宣言済みフィールドスラッグ最大 4 つ
admin.quickCreatebooleanダッシュボードにこのコレクションの「新規エントリ」クイックアクションを表示するか。デフォルト true
supportsstring[]drafts、revisions、preview、scheduling、search、seo のいずれか
urlPatternstring/posts/{slug} のような公開パターン。パスセグメントごとにプレースホルダーは最大 1 つ
routableboolean公開エントリにスラッグが必要か。デフォルト true
hiddenboolean生成されたサイドバーリンク、コマンドパレットのリンク、ダッシュボードのクイックアクションを隠す。コレクションは URL と API では到達可能のまま
sortOrdernumber管理サイドバーでの明示的な位置。並べ替えられたコレクションが先に、昇順で来る
groupstring管理サイドバーのフォルダ。同じグループのコレクションは折りたたみ可能なエントリを共有する
commentsEnabledbooleanコレクションのコメントを有効にする
editLockingboolean編集ロックを有効にする。デフォルト true
titleFieldstringコンテンツリストのタイトルに使うフィールド
dateFieldstringコンテンツリストの日付に使う datetime フィールド
fieldsSeedField[]必須のフィールド定義

sortOrder はコレクションに属し、サイドバー順を制御します。SeedField に sortOrder プロパティはありません。フィールドはその配列順で作成されます。

フィールドプロパティ

プロパティ型用途
slugstringコレクションスラッグと同じパターンの必須フィールド名
labelstring必須の UI ラベル
typeFieldType必須の保存フィールドタイプ
requiredboolean必須の空の値を拒否する
uniqueboolean一意性制約を追加する
searchablebooleanコレクション検索にフィールドを含める
indexedbooleanサポートされるスカラー型のクエリインデックスを追加する
translatablebooleanロケールごとに値を保存。デフォルト true。false は翻訳間で 1 つの値を共有
defaultValue任意フィールド省略時の初期値
validationオブジェクト生成されたコンテンツスキーマが使う検証ルール
widgetstring管理フィールドウィジェットの上書き
optionsオブジェクトウィジェット固有のオプション

サポートされるフィールドタイプは次のとおりです。

  • string、text、url、slug
  • number、integer、boolean
  • datetime
  • select、multiSelect
  • portableText、json、repeater
  • blocks
  • image、file、reference

reference フィールドはコレクションテーブルには何も保存しません。そのリンクは結び付いたリレーションにあります。 リレーションを参照してください。

indexed: true を設定できるのは string、url、number、integer、boolean、datetime、select、reference、slug のみです。reference フィールドでは、フィールドがリレーションを持たない間だけフラグが適用されます。結び付いたフィールドにはインデックスする列がないためです。

フィールド検証

生成されたコレクションスキーマは、フィールドタイプがサポートするところで次のルールを認識します。

ルール使用先
min、max数値フィールド
minLength、maxLength、pattern文字列形フィールド
optionsselect と multiSelect
subFields、minItems、maxItemsrepeater
allowedTypes、minItems、maxItemsblocks
allowedMimeTypesメディアフィールド

blocks フィールドの retiredTypes はサーバーが管理します。allowedTypes からスラッグを取り除くとそのタイプは廃止扱いとなり、保存済みの既存ブロックは有効なまま残り、新しいブロックでは使えなくなります。

validateSeed() は、validation や options のすべてのルールを深く型チェックするわけではありません。そのため、無効なルールがシード検証を通過し、後でコレクションスキーマの構築時やコンテンツの書き込み時に失敗することがあります。

リレーション

リレーションは 2 つのコレクションを結び付け、それらのエントリ間のリンクを所有します。reference フィールドはリレーションの 1 つに結び付き、一方の端からそのリンクを参照します。次のシードは、投稿 1 件につき著者 1 人を許可する、posts と authors の間のリレーションを宣言しています。

{
	"relations": [
		{
			"slug": "post_authors",
			"parentCollection": "posts",
			"childCollection": "authors",
			"parentLabel": "Posts",
			"parentLabelSingular": "Post",
			"childLabel": "Authors",
			"childLabelSingular": "Author",
			"maxChildrenPerParent": 1
		}
	]
}
プロパティ型必須説明
slugstringはいreference フィールドがリレーションを指す際の一意な名前
parentCollectionstringはい親側のコレクション
childCollectionstringはい子側のコレクション
parentLabelstringはい子から見た、親の役割の名前
parentLabelSingularstringいいえparentLabel の単数形
childLabelstringはい親から見た、子の役割の名前
childLabelSingularstringいいえchildLabel の単数形
maxChildrenPerParentnumber | nullいいえ1 つの親がリンクできる子の数(null:無制限)
maxParentsPerChildnumber | nullいいえ1 つの子がリンクできる親の数(null:無制限)

collections 内の reference フィールドは、結び付けるリレーションを指名します。

{
	"slug": "author",
	"label": "Author",
	"type": "reference",
	"validation": { "relation": "post_authors" }
}

フィールドは代わりに targetCollection を指名し、そのためのリレーションを作成させることもできます。これは一方のコレクションだけが見るリンクへの最短経路です。両方のコレクションが見る必要があるとき、またはラベルと上限を設定するときは relations でリレーションを宣言してください。 reference は両方の形と、それぞれが受け付ける検証キーを文書化しています。

リレーションの 2 つのコレクションは、存在した後は固定されます。異なるコレクションを指名するシードは、保持しているリンクが、もはやリレーションの端ではないコレクションを指してしまわないよう、失敗します。ラベルと上限は、シードが onConflict: "update" で適用されるときに更新されます。

タクソノミー

タクソノミー定義は対象コレクションを識別します。用語はサンプルデータで、includeContent が true のときだけ適用されます。

{
  "version": "1",
  "taxonomies": [
    {
      "name": "category",
      "label": "Categories",
      "labelSingular": "Category",
      "hierarchical": true,
      "collections": ["posts"],
      "terms": [
        { "slug": "engineering", "label": "Engineering" },
        { "slug": "platform", "label": "Platform", "parent": "engineering" }
      ]
    }
  ]
}

タクソノミーはシードローカルの id、locale、translationOf を持てます。用語もそれらのプロパティを持てます。translationOf は別のシードローカル ID を指します。用語は、翻訳元の用語の後に並べる必要があります。同じ name のタクソノミーエントリは任意の順で現れ得ます。タクソノミーの構造を宣言するエントリが翻訳より先に適用されるためです。

hierarchical と collections はタクソノミーのすべてのロケールで共有されるため、同じ name のエントリを translationOf が指すタクソノミーエントリはそれらを省略できます。適用エンジンは同じ name のエントリを通じて translationOf をたどり、最後のものから取ります。検証は、翻訳が取る値と異なる値を宣言したとき、またはタクソノミーについてそれらを宣言する 2 つのエントリが一致しないときに警告します。既存のタクソノミーは、translationOf のないエントリが置き換えるまで値を保ちます。これは onConflict: "update" で起き、競合動作で述べる未変更の組み込み category または tag 定義をエントリのロケールが持つ場合、またはその組み込み定義がタクソノミーの唯一のものである場合はどのモードでも起きます。エクスポートは、翻訳が指すエントリにのみそれらを書き込みます。

用語の parent は同じロケール内の親用語のスラッグです。非階層タクソノミーの親は警告を出し、無視されます。translationOf があり parent がない用語は、翻訳元の用語の親を取ります。

バイライン

ルートの bylines は表示クレジットを定義します。サンプルデータであり、includeContent: true が必要です。

{
  "version": "1",
  "bylines": [
    {
      "id": "byline-editor",
      "slug": "alex-editor",
      "displayName": "Alex Editor",
      "isGuest": true
    }
  ]
}

id はシードローカルで、コンテンツのクレジットが使います。任意のプロパティは bio、websiteUrl、isGuest、avatar です。

バイラインのアバターは、設定済みのストレージにすでに存在するファイルを指します。

{
  "id": "byline-editor",
  "slug": "alex-editor",
  "displayName": "Alex Editor",
  "avatar": {
    "storageKey": "avatars/alex.jpg",
    "filename": "alex.jpg",
    "mimeType": "image/jpeg",
    "alt": "Alex Editor",
    "width": 400,
    "height": 400
  }
}

バイラインのアバターのシードでは、ストレージキーに対するメディア行を作成または再利用します。ファイルのアップロードやダウンロードは行いません。

コンテンツ

content はエントリをコレクションスラッグごとにまとめます。各エントリにはシードローカルの id と data オブジェクトが必要です。ルーティング可能なコレクションには、空でない slug も必要です。

{
  "version": "1",
  "content": {
    "posts": [
      {
        "id": "post-welcome",
        "slug": "welcome",
        "status": "published",
        "data": {
          "title": "Welcome",
          "content": []
        },
        "taxonomies": {
          "category": ["engineering"]
        },
        "bylines": [
          { "byline": "byline-editor", "roleLabel": "Editor" }
        ]
      }
    ]
  }
}
プロパティ必須動作
idはいシードローカルの参照 ID
slugルーティング可能なコレクションでは必須公開スラッグと競合キー
statusいいえpublished または draft。デフォルト published
dataはいコレクションのフィールドスラッグをキーとする値
taxonomiesいいえタクソノミー名から用語スラッグの配列へのマップ
bylinesいいえルートのバイライン ID を参照する、順序付きのクレジット
localeいいえBCP 47 ロケール。defaultLocale を通じてデフォルトが決まる
translationOfいいえ同じコレクション内のシードローカルなコンテンツ ID

ルーティング可能なエントリでは、シードローカルの id はデータベース上の ID ではありません。EmDash はデータベース ID を作成し、後の参照のためにそのマッピングを記録します。routable: false のコレクションにあるスラッグなしのエントリでは、EmDash はシードの id を保存 ID として使うため、再適用しても冪等性が保たれます。

読み取り時、entry.id は Astro のルート識別子で、通常はスラッグです。保存されたデータベース ID は entry.data.id です。

コンテンツ参照

data 内で $ref: 文字列を使うと、シードローカルのコンテンツ ID を作成済みのデータベース ID に置き換えられます。

{
  "id": "event-opening",
  "slug": "opening-night",
  "data": {
    "title": "Opening night",
    "venue": "$ref:venue-main-hall"
  }
}

参照先は、適用エンジンの ID マップに存在するよう、十分早い位置に現れる必要があります。解決されない $ref: の値は元のリテラル文字列のまま残り、validateSeed() はそれを拒否しません。

reference フィールドでは、リレーションの親側からリンクを宣言してください。両端は 1 つのリンク集合を参照するため、子コレクション側のフィールドは、親がすでに持っているリンクを重複して記述することになります。

メディア参照

コンテンツデータで $media を使うと、URL をダウンロードし、渡されたストレージアダプターでアップロードし、メディア行を作成して、そのオブジェクトをメディアフィールド値に置き換えます。

{
  "featured_image": {
    "$media": {
      "url": "https://example.com/images/launch.jpg",
      "filename": "launch.jpg",
      "alt": "A product launch on stage",
      "caption": "Launch event"
    }
  }
}

Portable Text の image ブロックや gallery の画像では、asset 内の $media はメディア参照(_type: "reference"、_ref、url、provider)になり、画像自身の alt、width、height が不足している場合は、メディアの代替テキストと寸法で補われます。

1 回の適用呼び出しの中では、同じ URL への繰り返しの参照は解決済みのメディア値を再利用します。シードのメディア参照はローカルの file プロパティを受け付けません。mediaBasePath は公開の SeedApplyOptions 型に残っていますが、現在の適用エンジンは読み取りません。

ストレージアダプターが渡されない場合、$media 参照はスキップされ null に解決されます。skipMediaDownload: true では外部メディア値になり、ストレージアダプターは不要です。

メニュー

メニューは構造データであり、includeContent が false でも適用されます。

{
  "version": "1",
  "menus": [
    {
      "name": "primary",
      "label": "Primary navigation",
      "items": [
        {
          "type": "page",
          "label": "About",
          "ref": "page-about",
          "collection": "pages"
        },
        {
          "type": "custom",
          "label": "Contact",
          "url": "/contact",
          "target": "_self"
        }
      ]
    }
  ]
}

使用できる項目タイプは custom、page、post、taxonomy、collection です。custom には url が、page と post には ref が必要です。項目には id、translationOf、label、collection、titleAttr、cssClasses、locale、target、ネストされた children を含められます。

page と post では、ref はシードのコンテンツ ID を指名します。対象がない場合は検証警告となり、解決済みのコンテンツ参照を持たないメニュー項目になります。既存のメニュー項目は、そのメニューが適用されるたびに onConflict に関係なく削除されて再作成されます。

リダイレクト

リダイレクトにはローカルのソースパスと宛先パスが必要です。

{
  "version": "1",
  "redirects": [
    {
      "source": "/old-path",
      "destination": "/new-path",
      "type": 308,
      "enabled": true,
      "groupName": "WordPress migration"
    }
  ]
}

どちらのパスも 1 つの / で始まる必要があります。プロトコル相対 URL、パストラバーサルのセグメント、改行は拒否されます。使用できるステータスコードは 301、302、307、308 です。

ウィジェットエリア

ウィジェットエリアには content、menu、component のウィジェットを含められます。

{
  "version": "1",
  "widgetAreas": [
    {
      "name": "sidebar",
      "label": "Sidebar",
      "widgets": [
        {
          "type": "menu",
          "title": "Explore",
          "menuName": "primary"
        },
        {
          "type": "component",
          "title": "Recent posts",
          "componentId": "core:recent-posts",
          "props": { "count": 5 }
        }
      ]
    }
  ]
}

content ウィジェットは content に Portable Text を保存します。menu ウィジェットには menuName が必要です。component ウィジェットには componentId が必要で、props を渡せます。SeedWidget に settings プロパティはありません。

エリア内の既存のウィジェットは、そのエリアが適用されるたびに onConflict に関係なく削除されて再作成されます。

Sections

セクションには再利用可能な Portable Text コンテンツが入ります。

{
  "version": "1",
  "sections": [
    {
      "slug": "newsletter-signup",
      "title": "Newsletter signup",
      "description": "Signup call to action",
      "keywords": ["newsletter", "email"],
      "source": "theme",
      "content": []
    }
  ]
}

セクションのスラッグには、小文字、数字、ハイフンを使えます。source は theme、user、import のいずれかで、シードではデフォルトで theme になります。テーマのセクションは管理画面から削除できません。セクションは構造データであり、includeContent が false でも適用されます。

ローカライゼーション

defaultLocale は、タクソノミー、用語、メニュー、メニュー項目、コンテンツで不足しているロケールを補います。アクティブなランタイムの i18n 設定がある場合は、そちらが優先されます。

ローカライズされたタクソノミー、用語、メニュー、メニュー項目、コンテンツは、シードローカルの id と translationOf フィールドを使います。適用エンジンが翻訳グループを解決できるよう、翻訳より前に元の項目を置いてください。翻訳されたコンテンツエントリは locale を設定する必要があり、その translationOf は同じコレクション内の別のエントリを指名する必要があります。

プログラムからのシード適用

applySeed() と validateSeed() は emdash/seed からエクスポートされます。次のヘルパーは、適用の前に検証を行います。

import {
  applySeed,
  validateSeed,
  type SeedApplyOptions,
  type SeedFile,
} from "emdash/seed";

type SeedDatabase = Parameters<typeof applySeed>[0];

export async function applyProjectSeed(
  db: SeedDatabase,
  seed: SeedFile,
  options: SeedApplyOptions,
) {
  const validation = validateSeed(seed);
  if (!validation.valid) {
    throw new Error(validation.errors.join("\n"));
  }

  return applySeed(db, seed, options);
}

SeedApplyOptions

オプションデフォルト現在の動作
includeContentfalseコンテンツエントリ、バイライン、タクソノミーの用語を含める
onConflict"skip"サポートされるエンティティの競合に対する "skip"、"update"、"error"
storageなし$media URL のダウンロードに必要なストレージアダプター
skipMediaDownloadfalse$media URL を外部メディア値のまま保持する
mediaBasePathなし公開型には存在するが、現在の適用エンジンでは使われない

プログラムからの適用では、includeContent のデフォルトは false です。セットアップウィザードは、管理者によるサンプルコンテンツの選択を渡します。emdash seed CLI は、--no-content を指定しない限り、デフォルトでコンテンツを含めます。

競合動作

onConflict は、シード全体に対するトランザクションのポリシーではありません。

  • コレクション、フィールド、バイライン、コンテンツ、リダイレクト、セクションは、スキップ、更新、エラーの動作をサポートします。
  • タクソノミー定義と用語は、該当する競合モードに従います。例外は、新しいデータベースがすべて最初から持っている組み込みの category と tag 定義です。サイトが編集するまでは、これらを宣言するシードはどのモードでもそれらを置き換えます。
  • 設定はキーごとに競合を処理します。skip は不足している設定を作成し、既存の値を保持します。update は提供されたすべての設定を上書きします。ただし seo と social では、提供されたフィールドのみが上書きされます。error は最初に存在する設定で停止します。シードの順序でそれより前に作成された設定は、適用されたままになります。
  • 既存のメニューはメニュー行を保持しますが、すべての項目を置き換えます。
  • 既存のウィジェットエリアはエリア行を保持しますが、すべてのウィジェットを置き換えます。
  • コンテンツの競合は、コレクション、スラッグ、ロケールで照合されます。ルーティング不可のコレクションにあるスラッグなしのエントリは、そのシード ID で照合されます。

onConflict: "update" では、コンテンツデータが置き換えられ、そのバイラインとタクソノミーの割り当てがシードに合わせて調整されます。既存のサイトに使う前に、コピーで update モードを試してください。

applySeed() は、コレクション、フィールド、タクソノミー、バイライン、メニュー、リダイレクト、ウィジェットエリア、セクション、設定、コンテンツ、メディアのカウンターを返します。

検証動作

validateSeed() は { valid, errors, warnings } を返します。applySeed() はこれを呼び出し、エラーがある場合は Invalid seed file をスローします。

検証は、適用エンジンが必要とする次のような構造ルールをチェックします。

  • バージョンと、空でない defaultLocale。
  • コレクション、フィールド、タクソノミー、用語、メニュー、ウィジェットエリア、セクション、バイライン、コンテンツのコンテナ形状。
  • 必須の名前、ラベル、ID、スラッグ、サポートされるフィールドまたはウィジェットのタイプ。
  • 該当するスコープ内での識別子の重複。
  • インデックス可能なフィールドタイプと admin.listColumns の参照。
  • タクソノミーの親、コンテンツの翻訳、コンテンツのバイライン参照、メニュー項目の要件。
  • 安全なローカルのリダイレクトパスとステータスコード。

一部の条件はエラーではなく警告です。たとえば、コレクションのないタクソノミー、フラットなタクソノミーの親、シードに存在しないメニューのコンテンツ参照などです。

検証は、すべての data 値がコレクションのフィールドに適合することを保証しません。また、サイト設定、フィールドの validation、フィールドの options、任意の Portable Text ブロック、component ウィジェットの props、コンテンツデータ内の $ref: の参照先、リモートの $media の可用性も深くは検証しません。有効なシードでも、スキーマ作成、コンテンツ検証、ネットワークダウンロード、ストレージアップロードの途中で失敗することがあります。

エディタ支援には $schema URL を使い、適用する前に実行可能な検証を実行してください。

npx emdash seed seed/seed.json --validate

CLI コマンド

競合動作を明示して、シードをローカルの SQLite データベースに適用します。

npx emdash seed seed/seed.json --database ./data.db --on-conflict skip

現在のローカルモデルとすべてのコンテンツを、テンプレートのパスにエクスポートし直します。

npx emdash export-seed --database ./data.db --with-content=all > seed/seed.json

export-seed はローカルの SQLite ファイルに対して直接動作します。デプロイ済みの D1 データベースの場合は、先にローカルファイルへエクスポートしてください。結果をコミットする前に、エクスポートされた設定、コンテンツ、メディア参照を確認してください。エクスポートしたメディアを別のサイトでインポートできるようにするには、--media-base-url を渡してください。メディアの URLを参照してください。

次のステップ