JavaScript API リファレンス
EmDashは、コンテンツのクエリ、メディアの管理、データベースの操作を行うための関数をエクスポートします。
コンテンツクエリ
Section titled “コンテンツクエリ”EmDashのクエリ関数はAstroのライブコンテンツコレクションパターンに従い、エラーを適切に処理するために{ entries, error }または{ entry, error }を返します。
getEmDashCollection()
Section titled “getEmDashCollection()”コレクションからすべてのエントリを取得します。
import { getEmDashCollection } from "emdash";
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) { console.error("Failed to load posts:", error);}| パラメータ | 型 | 説明 |
|---|---|---|
collection | string | コレクションスラッグ |
options | CollectionFilter | オプションのフィルターオプション |
interface CollectionFilter { status?: "draft" | "published" | "archived"; limit?: number; where?: Record<string, string | string[]>; // Filter by field or taxonomy}interface CollectionResult<T> { entries: ContentEntry<T>[]; // Empty array if error or none found error?: Error; // Set if query failed}// Get all published postsconst { entries: posts } = await getEmDashCollection("posts", { status: "published",});
// 最新の5件の投稿を取得const { entries: latest } = await getEmDashCollection("posts", { limit: 5, status: "published",});
// タクソノミーでフィルターconst { entries: newsPosts } = await getEmDashCollection("posts", { status: "published", where: { category: "news" },});
// エラー処理const { entries, error } = await getEmDashCollection("posts");if (error) { return new Response("Server error", { status: 500 });}getEmDashEntry()
Section titled “getEmDashEntry()”スラッグまたはIDで単一のエントリを取得します。
import { getEmDashEntry } from "emdash";
const { entry: post, error } = await getEmDashEntry("posts", "my-post-slug");
if (!post) { return Astro.redirect("/404");}| パラメータ | 型 | 説明 |
|---|---|---|
collection | string | コレクションスラッグ |
slugOrId | string | エントリスラッグまたはID |
プレビューモードは自動的に処理されます — ミドルウェアが_previewトークンを検出し、AsyncLocalStorageを介して下書きコンテンツを提供します。オプションパラメータは必要ありません。
interface EntryResult<T> { entry: ContentEntry<T> | null; // null if not found error?: Error; // Set only for actual errors, not "not found" isPreview: boolean; // true if draft content is being served}// Get by slugconst { entry: post } = await getEmDashEntry("posts", "hello-world");
// IDで取得const { entry: post } = await getEmDashEntry("posts", "01HXK5MZSN0FVXT2Q3KPRT9M7D");
// プレビューは自動的 — 有効な_previewトークンが存在する場合、isPreviewはtrueになりますconst { entry, isPreview, error } = await getEmDashEntry("posts", slug);
// エラーと見つからない場合の処理if (error) { return new Response("Server error", { status: 500 });}if (!entry) { return Astro.redirect("/404");}コンテンツタイプ
Section titled “コンテンツタイプ”ContentEntry
Section titled “ContentEntry”クエリ関数によって返されるエントリ:
interface ContentEntry<T = Record<string, unknown>> { id: string; data: T; edit: EditProxy; // Visual editing annotations}editプロキシはビジュアル編集の注釈を提供します。インライン編集を有効にするには、これを要素にスプレッドします: {...entry.edit.title}。本番環境では、これは出力を生成しません。
dataオブジェクトには、すべてのコンテンツフィールドとシステムフィールドが含まれます:
id- 一意の識別子slug- URLフレンドリーな識別子status- “draft” | “published” | “archived”createdAt- ISOタイムスタンプupdatedAt- ISOタイムスタンプpublishedAt- ISOタイムスタンプまたはnull- コレクションスキーマで定義されたすべてのカスタムフィールド
データベース関数
Section titled “データベース関数”createDatabase()
Section titled “createDatabase()”データベース接続を作成します。
import { createDatabase } from "emdash";
const db = createDatabase({ url: "file:./data.db" });runMigrations()
Section titled “runMigrations()”保留中のデータベースマイグレーションを実行します。
import { createDatabase, runMigrations } from "emdash";
const db = createDatabase({ url: "file:./data.db" });const { applied } = await runMigrations(db);console.log(`Applied ${applied.length} migrations`);getMigrationStatus()
Section titled “getMigrationStatus()”マイグレーションの状態を確認します。
import { createDatabase, getMigrationStatus } from "emdash";
const db = createDatabase({ url: "file:./data.db" });const status = await getMigrationStatus(db);// { applied: ["0001_core", ...], pending: [] }リポジトリを通じた低レベルのデータアクセス。
ContentRepository
Section titled “ContentRepository”import { ContentRepository, createDatabase } from "emdash";
const db = createDatabase({ url: "file:./data.db" });const repo = new ContentRepository(db);
// 複数検索const { items, nextCursor } = await repo.findMany("posts", { limit: 10, where: { status: "published" },});
// IDで検索const post = await repo.findById("posts", "01HXK5MZSN...");
// 作成const newPost = await repo.create({ type: "posts", slug: "new-post", data: { title: "New Post", content: [] }, status: "draft",});
// 更新const updated = await repo.update("posts", "01HXK5MZSN...", { data: { title: "Updated Title" },});
// 削除await repo.delete("posts", "01HXK5MZSN...");MediaRepository
Section titled “MediaRepository”import { MediaRepository, createDatabase } from "emdash";
const db = createDatabase({ url: "file:./data.db" });const repo = new MediaRepository(db);
// メディア一覧const { items } = await repo.findMany({ limit: 20 });
// IDで取得const media = await repo.findById("01HXK5MZSN...");
// 作成(アップロード後)const newMedia = await repo.create({ filename: "photo.jpg", mimeType: "image/jpeg", size: 12345, storageKey: "uploads/photo.jpg",});スキーマレジストリ
Section titled “スキーマレジストリ”プログラムによるスキーマ管理。
import { SchemaRegistry, createDatabase } from "emdash";
const db = createDatabase({ url: "file:./data.db" });const registry = new SchemaRegistry(db);
// コレクション一覧const collections = await registry.listCollections();
// フィールドを含むコレクションを取得const postsSchema = await registry.getCollectionWithFields("posts");
// コレクション作成await registry.createCollection({ slug: "products", label: "Products", labelSingular: "Product", supports: ["drafts", "revisions"],});
// フィールド追加await registry.createField("products", { slug: "price", label: "Price", type: "number", required: true,});プレビューシステム
Section titled “プレビューシステム”generatePreviewToken()
Section titled “generatePreviewToken()”下書きコンテンツ用のプレビュートークンを生成します。
import { generatePreviewToken } from "emdash";
const token = await generatePreviewToken({ contentId: "posts:01HXK5MZSN...", secret: process.env.EMDASH_ADMIN_SECRET, expiresIn: 3600, // 1 hour});verifyPreviewToken()
Section titled “verifyPreviewToken()”プレビュートークンを検証します。
import { verifyPreviewToken } from "emdash";
const result = await verifyPreviewToken({ token, secret: process.env.EMDASH_ADMIN_SECRET,});
if (result.valid) { const { cid, exp, iat } = result.payload; // cidは「collection:id」形式、例: "posts:my-draft-post"}isPreviewRequest()
Section titled “isPreviewRequest()”リクエストにプレビュートークンが含まれているか確認します。
import { isPreviewRequest, getPreviewToken } from "emdash";
if (isPreviewRequest(Astro.request)) { const token = getPreviewToken(Astro.request); // Verify and show preview content}コンテンツコンバーター
Section titled “コンテンツコンバーター”Portable TextとProseMirror形式の間で変換します。
import { prosemirrorToPortableText, portableTextToProsemirror } from "emdash";
// ProseMirror(エディタ)からPortable Text(ストレージ)へconst portableText = prosemirrorToPortableText(prosemirrorDoc);
// Portable TextからProseMirrorへconst prosemirrorDoc = portableTextToProsemirror(portableText);import { getSiteSettings, getSiteSetting } from "emdash";
// すべての設定を取得const settings = await getSiteSettings();
// 単一の設定を取得const title = await getSiteSetting("siteTitle");設定はランタイムAPIからは読み取り専用です。更新するには管理APIを使用してください。
import { getMenu, getMenus } from "emdash";
// すべてのメニューを取得const menus = await getMenus();
// 特定のメニューをアイテムとともに取得const primaryMenu = await getMenu("primary");
if (primaryMenu) { primaryMenu.items.forEach(item => { console.log(item.label, item.url); // ドロップダウン用のネストされた項目 item.children.forEach(child => console.log(" -", child.label)); });}タクソノミー
Section titled “タクソノミー”import { getTaxonomyTerms, getTerm, getEntryTerms, getEntriesByTerm } from "emdash";
// タクソノミーのすべての用語を取得(階層構造の場合はツリー構造)const categories = await getTaxonomyTerms("category");
// 単一のタームを取得const news = await getTerm("category", "news");
// コンテンツエントリに割り当てられたタームを取得const postCategories = await getEntryTerms("posts", "post-123", "category");
// 特定のタームを持つエントリを取得const newsPosts = await getEntriesByTerm("posts", "category", "news");ウィジェットエリア
Section titled “ウィジェットエリア”import { getWidgetArea, getWidgetAreas } from "emdash";
// すべてのウィジェットエリアを取得const areas = await getWidgetAreas();
// ウィジェットを含む特定のウィジェットエリアを取得const sidebar = await getWidgetArea("sidebar");
if (sidebar) { sidebar.widgets.forEach(widget => { console.log(widget.type, widget.title); });}import { getSection, getSections, getSectionCategories } from "emdash";
// すべてのセクションを取得const sections = await getSections();
// セクションをフィルタリングconst heroes = await getSections({ category: "hero" });const themeSections = await getSections({ source: "theme" });const results = await getSections({ search: "newsletter" });
// 単一のセクションを取得const cta = await getSection("newsletter-cta");
// カテゴリを取得const categories = await getSectionCategories();import { search, searchCollection } from "emdash";
// コレクション全体でのグローバル検索const results = await search("hello world", { collections: ["posts", "pages"], status: "published", limit: 20,});
// 結果にはハイライト付きのスニペットが含まれるresults.forEach(result => { console.log(result.title); console.log(result.snippet); // Contains <mark> tags console.log(result.score);});
// コレクション固有の検索const posts = await searchCollection("posts", "typescript", { limit: 10,});エラーハンドリング
Section titled “エラーハンドリング”EmDashは特定の失敗を処理するためのエラークラスをエクスポートします:
import { EmDashDatabaseError, EmDashValidationError, EmDashStorageError, SchemaError,} from "emdash";
try { await repo.create({ ... });} catch (error) { if (error instanceof EmDashValidationError) { console.error("Validation failed:", error.message); } if (error instanceof SchemaError) { console.error("Schema error:", error.code, error.details); }}