Migration zur Plugin-CLI

Auf dieser Seite

Dieser Leitfaden richtet sich an Autoren von Sandboxed-Plugins, die gegen die vorherige definePlugin()-Form geschrieben wurden. Arbeiten Sie die Breaking Changes der Reihe nach durch. Keiner von ihnen ändert das Verhalten Ihrer Hooks oder Routen zur Laufzeit; sie ändern, wie das Plugin deklariert, gebaut und veröffentlicht wird.

Die vollständige Liste der Änderungen in jedem Paket finden Sie im EmDash Changelog.

Breaking Changes

Umbenannt: @emdash-cms/registry-cli heißt jetzt @emdash-cms/plugin-cli

Frühere Versionen lieferten die CLI als @emdash-cms/registry-cli mit einem emdash-registry-Binary aus.

Das Paket heißt jetzt @emdash-cms/plugin-cli und das Binary ist emdash-plugin. Das alte Paket wird nicht mehr veröffentlicht.

Was sollte ich tun?

Ersetzen Sie die Abhängigkeit:

pnpm remove @emdash-cms/registry-cli
pnpm add -D @emdash-cms/plugin-cli

Ersetzen Sie emdash-registry überall durch emdash-plugin, wo Sie es aufrufen. Jeder Unterbefehl behält seinen Namen (bundle, publish, login, whoami, switch, validate), und init, build und dev werden hinzugefügt. Siehe Die Plugin-CLI.

Geändert: Sandboxed Plugins werden mit satisfies SandboxedPlugin definiert

Frühere Versionen umschlossen die Hooks und Routen des Plugins in definePlugin(), importiert von emdash, wobei die Parameter jedes Handlers manuell annotiert wurden.

Ein Sandboxed Plugin ist jetzt ein nackter Default-Export, annotiert mit satisfies SandboxedPlugin. Der Typ kommt von emdash/plugin, einem reinen Typ-Entry-Point, den der Bundler entfernt. TypeScript leitet event und ctx jedes Handlers aus dem Hook- oder Routennamen ab, sodass Handler-Parameter keine Annotationen benötigen.

Was sollte ich tun?

Nehmen Sie vier Änderungen an der Quelldatei des Plugins vor. Ersetzen Sie den Import:

import { definePlugin, type ContentHookEvent, type PluginContext } from "emdash";
import type { SandboxedPlugin } from "emdash/plugin";

Ersetzen Sie den definePlugin()-Wrapper durch ein nacktes Objekt und eine satisfies-Annotation:

export default definePlugin({ /* hooks, routes */ });
export default { /* hooks, routes */ } satisfies SandboxedPlugin;

Entfernen Sie die Parameter-Annotationen von jedem Handler:

handler: async (event: ContentHookEvent, ctx: PluginContext) => {
handler: async (event, ctx) => {

Das Ergebnis ist ein einzelnes Default-exportiertes Objekt:

import type { SandboxedPlugin } from "emdash/plugin";

export default {
	hooks: {
		"content:beforeSave": {
			handler: async (event, ctx) => {
				return event.content;
			},
		},
	},
} satisfies SandboxedPlugin;

Um einen Event-Typ in einer Hilfsfunktion zu benennen, importieren Sie ihn von emdash/plugin:

import type { ContentHookEvent, PluginContext } from "emdash/plugin";

Das event eines Handlers ist immer der kanonische Typ für diesen Hook. Die Annotation eines Handlers mit einem engeren Interface wird nicht mehr typgeprüft. Validieren Sie alle Felder, von denen Sie abhängen, zur Laufzeit mit einer typeof-Prüfung oder einem Guard, was der richtige Ansatz für Daten ist, die von außerhalb des Typsystems kommen.

Geändert: Ein Plugin ist ein src/plugin.ts plus emdash-plugin.jsonc

Frühere Versionen teilten ein Plugin in zwei Dateien auf: src/index.ts gab einen PluginDescriptor zurück (id, version, capabilities, storage, entrypoint), und src/sandbox-entry.ts enthielt die Hooks und Routen.

Ein Plugin besteht jetzt aus einer Laufzeitdatei, src/plugin.ts (Hooks und Routen), und einem handbearbeiteten Manifest, emdash-plugin.jsonc (Identität und Vertrauensvertrag). Die Felder entrypoint und format sind verschwunden; der Build verdrahtet sie.

Was sollte ich tun?

Verschieben Sie die Hooks und Routen in src/plugin.ts mit der obigen Form. Verschieben Sie die Metadaten des Descriptors in emdash-plugin.jsonc neben package.json. Die Descriptor-id wird zum Manifest-slug; capabilities, allowedHosts und storage behalten ihre Form; version wird aus package.json gelesen, also lassen Sie es weg.

Das folgende Beispiel zeigt das Manifest-Äquivalent eines Descriptors, der eine Storage-Collection deklariert hat:

{
	"$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": "[email protected]" },

	"capabilities": [],
	"allowedHosts": [],
	"storage": { "events": { "indexes": ["timestamp"] } }
}

Siehe Das Plugin-Manifest für alle Felder und Publisher-Pinning für das publisher-Feld.

Zeigen Sie in package.json den "./sandbox"-Export auf die gebaute Laufzeitdatei:

"./sandbox": "./dist/sandbox-entry.mjs"
"./sandbox": "./dist/plugin.mjs"

Fügen Sie das Manifest zu files hinzu, damit es mit dem Paket ausgeliefert wird:

"files": ["dist"]
"files": ["dist", "emdash-plugin.jsonc"]

Geändert: Bauen mit emdash-plugin build

Frühere Versionen bauten die zwei Quelldateien mit einem handgeschriebenen tsdown-Skript.

emdash-plugin build liest emdash-plugin.jsonc und src/plugin.ts und erzeugt die dist/-Artefakte. emdash-plugin dev überwacht und baut neu.

Was sollte ich tun?

Ersetzen Sie das Build-Skript und fügen Sie ein Watch-Skript hinzu:

"scripts": {
	"build": "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean"
	"build": "emdash-plugin build",
	"dev": "emdash-plugin dev"
}

Dann validieren und bauen:

emdash-plugin validate
emdash-plugin build

Entfernt: Standard-Format-Typen und Funktionsexporte aus emdash

Frühere Versionen exportierten StandardPluginDefinition, StandardHookHandler, StandardHookEntry, StandardRouteHandler, StandardRouteEntry und die Funktion isStandardPluginDefinition aus emdash.

Diese wurden entfernt. Sie waren Hilfs-Aliase für die vorherige definePlugin-Form.

Was sollte ich tun?

Verwenden Sie SandboxedPlugin von emdash/plugin für denselben Zweck. Der Default-Export eines Sandboxed Plugins ist bereits durch seine satisfies SandboxedPlugin-Annotation typisiert, daher gibt es keinen Ersatz für isStandardPluginDefinition; identifizieren Sie ein Plugin bei Bedarf anhand seiner Struktur ({ hooks?, routes? }).

Umbenannt: Der Laufzeit-Typ SandboxedPlugin heißt jetzt SandboxedPluginInstance

Dies betrifft nur Autoren eines benutzerdefinierten SandboxRunner, wie @emdash-cms/cloudflare. Die meisten Plugin-Autoren können dies überspringen.

SandboxedPlugin von emdash bezieht sich jetzt auf die autorenseitige Quellform. Das von SandboxRunner.load zurückgegebene Laufzeit-Handle ist SandboxedPluginInstance.

Was sollte ich tun?

Wenn Sie SandboxedPlugin von emdash importieren, um einen Sandbox-Runner zu typisieren oder Laufzeit-Plugin-Handles zu halten, ändern Sie den Import zu SandboxedPluginInstance:

import type { SandboxedPlugin } from "emdash";
import type { SandboxedPluginInstance } from "emdash";

Informieren Sie Ihre Benutzer

Sites, die Ihr Plugin installieren, müssen auch ihren Import ändern. Weisen Sie sie auf die neue Form hin: Klammern und () weglassen.

import { helloPlugin } from "@my-org/plugin-hello";
import hello from "@my-org/plugin-hello";

export default defineConfig({
	integrations: [
		emdash({
			sandboxed: [helloPlugin()],
			sandboxed: [hello],
		}),
	],
});

Wenn Ihr Plugin Konfiguration über seine Factory akzeptierte, verschiebt sich diese Konfiguration in die Plugin-Einstellungen der Admin-UI. Lesen Sie sie zur Laufzeit über ctx.kv oder Settings. Siehe Einstellungen.

Weiter