このガイドは、以前の definePlugin() 形式で書かれた サンドボックス プラグインの作者向けです。破壊的変更を順番に進めてください。いずれもフックやルートのランタイム動作は変えず、プラグインの宣言・ビルド・公開の方法を変えます。
各パッケージの変更の完全な一覧は、リリースページ の該当エントリを参照してください。
破壊的変更
改名: @emdash-cms/registry-cli は @emdash-cms/plugin-cli になりました
以前のリリースは CLI を @emdash-cms/registry-cli として配布し、バイナリは emdash-registry でした。
パッケージは現在 @emdash-cms/plugin-cli で、バイナリは emdash-plugin です。旧パッケージはもう公開されません。
何をすべきか?
依存関係を置き換えます。
pnpm remove @emdash-cms/registry-cli
pnpm add -D @emdash-cms/plugin-cli
呼び出すすべての場所で emdash-registry を emdash-plugin に置き換えます。各サブコマンドは名前を維持し(bundle、publish、login、whoami、switch、validate)、init、build、dev が追加されます。The plugin CLI を参照してください。
改名: capability 名は resource-first の表記を使用
以前のマニフェストは read:content や network:fetch などの capability 名を使っていました。オーサリングマニフェストは現在の名前のみを受け入れますが、ランタイムは互換ウィンドウ中、既に公開されたバンドル内のレガシー名を引き続き正規化します。
何をすべきか?
マニフェスト内のすべてのレガシー名を置き換えます。
| 以前の名前 | 現在の名前 |
|---|---|
network:fetch | network:request |
network:fetch:any | network:request:unrestricted |
read:content | content:read |
write:content | content:write |
read:media | media:read |
write:media | media:write |
read:users | users:read |
email:provide | hooks.email-transport:register |
email:intercept | hooks.email-events:register |
page:inject | hooks.page-fragments:register |
空でない allowedHosts リスト付きで network:request を使います。オペレーターがランタイムで宛先を選ぶ場合にのみ、空リスト付きで network:request:unrestricted を使います。Capabilities and security が現在の権限とネットワーク規則を説明します。
変更: サンドボックスプラグインは明示的な SandboxedPlugin アノテーションを使用
以前のリリースは、emdash からインポートした definePlugin() でプラグインのフックとルートをラップし、各ハンドラーのパラメーターを手で注釈していました。
サンドボックスプラグインは定義を SandboxedPlugin 型の定数に代入し、その定数を default としてエクスポートします。型は import type で emdash/plugin からインポートします。バンドラーはそのインポートを消去します。同じサブパスは軽量ランタイムヘルパー pluginRoute() と pluginResponse() もエクスポートします。TypeScript はフックまたはルート名から各ハンドラーの event と ctx を推論するため、ハンドラーパラメーターに注釈は不要です。明示的なアノテーションは、分離されたパッケージマネージャーレイアウト下でも生成宣言を移植可能に保ちます。
何をすべきか?
プラグインのソースファイルに 4 つの変更を加えます。インポートを置き換えます。
import { definePlugin, type ContentHookEvent, type PluginContext } from "emdash";
import type { SandboxedPlugin } from "emdash/plugin";
definePlugin() ラッパーを明示的に型付けされた定数に置き換えます。
export default definePlugin({ /* hooks, routes */ });
const plugin: SandboxedPlugin = { /* hooks, routes */ };
export default plugin;
すべてのハンドラーからパラメーター注釈を削除します。
handler: async (event: ContentHookEvent, ctx: PluginContext) => {
handler: async (event, ctx) => {
結果は 1 つの default エクスポートオブジェクトです。
import type { SandboxedPlugin } from "emdash/plugin";
const plugin: SandboxedPlugin = {
hooks: {
"content:beforeSave": {
handler: async (event, ctx) => {
return event.content;
},
},
},
};
export default plugin;
ヘルパー関数でイベント型に名前を付けるには、emdash/plugin からインポートします。
import type { ContentHookEvent, PluginContext } from "emdash/plugin";
ハンドラーの event は常にそのフックの正規型です。より狭いインターフェイスでハンドラーに注釈を付けると、もはや型チェックを通りません。依存するフィールドは、型システム外から来るデータに対する正しい方法である typeof チェックまたはガードでランタイム検証してください。
変更: プラグインは 1 つの src/plugin.ts と emdash-plugin.jsonc
以前のリリースはプラグインを 2 ファイルに分割していました。src/index.ts が PluginDescriptor(id、version、capabilities、storage、entrypoint)を返し、src/sandbox-entry.ts がフックとルートを保持していました。
プラグインは今、1 つのランタイムファイル src/plugin.ts(フックとルート)と、手編集のマニフェスト emdash-plugin.jsonc(識別と信頼契約)です。entrypoint と format フィールドはなくなり、ビルドがそれらを配線します。
何をすべきか?
上記の形でフックとルートを src/plugin.ts に移します。ディスクリプタのメタデータを package.json の隣の emdash-plugin.jsonc に移します。ディスクリプタの id はマニフェストの slug になり、capabilities、allowedHosts、storage は形を維持し、version は package.json から読まれるため省略します。
次の例は、1 つのストレージコレクションを宣言したディスクリプタのマニフェスト相当です。
{
"$schema": "./node_modules/@emdash-cms/plugin-cli/schemas/emdash-plugin.schema.json",
"slug": "plugin-hello",
"publisher": "did:plc:abc123def456",
"license": "MIT",
"author": { "name": "Jane Doe", "url": "https://example.com" },
"security": { "email": "security@example.com" },
"capabilities": [],
"allowedHosts": [],
"storage": { "events": { "indexes": ["timestamp"] } }
}
各フィールドは The plugin manifest、publisher フィールドは Publisher pinning を参照してください。
package.json では、"./sandbox" エクスポートをビルド済みランタイムファイルに向けます。
"./sandbox": "./dist/sandbox-entry.mjs"
"./sandbox": "./dist/plugin.mjs"
マニフェストを files に追加し、パッケージと一緒に配布されるようにします。
"files": ["dist"]
"files": ["dist", "emdash-plugin.jsonc"]
変更: emdash-plugin build でビルド
以前のリリースは、手書きの tsdown スクリプトで 2 つのソースファイルをビルドしていました。
emdash-plugin build は emdash-plugin.jsonc と src/plugin.ts を読み、dist/ 成果物を出力します。emdash-plugin dev は監視して再ビルドします。
何をすべきか?
ビルドスクリプトを置き換え、ウォッチスクリプトを追加します。
"scripts": {
"build": "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean"
"build": "emdash-plugin build",
"dev": "emdash-plugin dev"
}
その後、検証してビルドします。
emdash-plugin validate
emdash-plugin build
削除: emdash からの標準形式の型と関数のエクスポート
以前のリリースは、StandardPluginDefinition、StandardHookHandler、StandardHookEntry、StandardRouteHandler、StandardRouteEntry、および関数 isStandardPluginDefinition を emdash からエクスポートしていました。
これらは削除されました。以前の definePlugin 形式のヘルパーエイリアスでした。
何をすべきか?
同じ目的には emdash/plugin の SandboxedPlugin を使います。サンドボックスプラグインのエクスポート定義はすでに SandboxedPlugin アノテーションで型付けされているため、isStandardPluginDefinition の代替はありません。必要なら構造({ hooks?, routes? })でプラグインを識別してください。
改名: サンドボックスランナーのハンドルは SandboxedPluginInstance を使用
これは @emdash-cms/cloudflare などのカスタム SandboxRunner の作者にのみ影響します。ほとんどのプラグイン作者はスキップできます。
作者向けの SandboxedPlugin 型は、emdash/plugin オーサリングエントリポイントから利用できます。SandboxRunner.load が返すランタイムハンドルは、emdash から SandboxedPluginInstance としてエクスポートされます。
何をすべきか?
サンドボックスランナーを型付けしたりランタイムプラグインハンドルを保持したりするために emdash から SandboxedPlugin をインポートしている場合は、インポートを SandboxedPluginInstance に変更します。
import type { SandboxedPlugin } from "emdash";
import type { SandboxedPluginInstance } from "emdash";
ユーザーに伝える
プラグインをインストールするサイトもインポートを変更する必要があります。新しい形を案内してください。波括弧と () を外します。
import { helloPlugin } from "@my-org/plugin-hello";
import hello from "@my-org/plugin-hello";
export default defineConfig({
integrations: [
emdash({
sandboxed: [helloPlugin()],
sandboxed: [hello],
}),
],
});
プラグインがファクトリ経由で設定を受け取っていた場合は、その設定を管理設定ページに移し、ctx.settings から読みます。サンドボックスプラグインのディスクリプタはプレーンオブジェクトであり、コンストラクタオプションを受け取れません。Settings を参照してください。
移行したプラグインの検証
プラグインのテストを実行し、オーサリングマニフェストを検証し、完全なビルドとバンドルチェックを実行します。
pnpm test
pnpm exec emdash-plugin validate
pnpm exec emdash-plugin build
pnpm exec emdash-plugin bundle --validate-only
その後、ローカルパッケージを開発サイトにインストールし、移行した各フックとルートを行使します。ビルドは名前と形を確認できますが、ルートが意図したデータを返すことや、フックがコンテンツを正しく保持することは確認できません。