Migrazione alla CLI dei plugin

In questa pagina

Questa guida è per gli autori di plugin sandboxed scritti con la forma precedente di definePlugin(). Affronta le modifiche incompatibili in ordine. Nessuna di esse modifica il comportamento dei tuoi hook o route a runtime; modificano come il plugin viene dichiarato, costruito e pubblicato.

Per l’elenco completo delle modifiche in ogni pacchetto, consulta il changelog di EmDash.

Modifiche incompatibili

Rinominato: @emdash-cms/registry-cli ora è @emdash-cms/plugin-cli

Le versioni precedenti fornivano la CLI come @emdash-cms/registry-cli, con un binario emdash-registry.

Il pacchetto ora è @emdash-cms/plugin-cli e il binario è emdash-plugin. Il vecchio pacchetto non viene più pubblicato.

Cosa devo fare?

Sostituisci la dipendenza:

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

Sostituisci emdash-registry con emdash-plugin ovunque lo chiami. Ogni sottocomando mantiene il suo nome (bundle, publish, login, whoami, switch, validate), e vengono aggiunti init, build e dev. Vedi La CLI dei plugin.

Modificato: i plugin sandboxed sono definiti con satisfies SandboxedPlugin

Le versioni precedenti avvolgevano gli hook e le route del plugin in definePlugin() importato da emdash, con i parametri di ogni handler annotati manualmente.

Un plugin sandboxed ora è un’esportazione predefinita semplice annotata con satisfies SandboxedPlugin. Il tipo proviene da emdash/plugin, un punto di ingresso solo di tipi che il bundler rimuove. TypeScript deduce event e ctx di ogni handler dal nome dell’hook o della route, quindi i parametri dell’handler non necessitano di annotazioni.

Cosa devo fare?

Apporta quattro modifiche al file sorgente del plugin. Sostituisci l’importazione:

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

Sostituisci il wrapper definePlugin() con un oggetto semplice e un’annotazione satisfies:

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

Rimuovi le annotazioni dei parametri da ogni handler:

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

Il risultato è un singolo oggetto esportato per impostazione predefinita:

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

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

Per denominare un tipo di evento in una funzione di supporto, importalo da emdash/plugin:

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

L’event di un handler è sempre il tipo canonico per quell’hook. Annotare un handler con un’interfaccia più ristretta non supera più il controllo dei tipi. Convalida qualsiasi campo da cui dipendi a runtime con un controllo typeof o un guard, che è l’approccio corretto per i dati che provengono dall’esterno del sistema di tipi.

Modificato: un plugin è un src/plugin.ts più emdash-plugin.jsonc

Le versioni precedenti dividevano un plugin in due file: src/index.ts restituiva un PluginDescriptor (id, version, capabilities, storage, entrypoint), e src/sandbox-entry.ts conteneva gli hook e le route.

Un plugin ora è un file di runtime, src/plugin.ts (hook e route), e un manifest modificato manualmente, emdash-plugin.jsonc (identità e contratto di fiducia). I campi entrypoint e format sono scomparsi; la build li collega.

Cosa devo fare?

Sposta gli hook e le route in src/plugin.ts utilizzando la forma precedente. Sposta i metadati del descriptor in emdash-plugin.jsonc accanto a package.json. L’id del descriptor diventa lo slug del manifest; capabilities, allowedHosts e storage mantengono la loro forma; version viene letto da package.json, quindi omettilo.

L’esempio seguente mostra l’equivalente manifest di un descriptor che dichiarava una collezione di storage:

{
	"$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"] } }
}

Vedi Il manifest del plugin per tutti i campi, e Fissaggio dell’editore per il campo publisher.

In package.json, punta l’esportazione "./sandbox" al file di runtime costruito:

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

Aggiungi il manifest a files in modo che venga fornito con il pacchetto:

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

Modificato: costruire con emdash-plugin build

Le versioni precedenti costruivano i due file sorgente con uno script tsdown scritto manualmente.

emdash-plugin build legge emdash-plugin.jsonc e src/plugin.ts ed emette gli artefatti dist/. emdash-plugin dev osserva e ricostruisce.

Cosa devo fare?

Sostituisci lo script di build e aggiungi uno script di osservazione:

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

Quindi convalida e costruisci:

emdash-plugin validate
emdash-plugin build

Rimosso: esportazioni di tipi e funzioni di formato standard da emdash

Le versioni precedenti esportavano StandardPluginDefinition, StandardHookHandler, StandardHookEntry, StandardRouteHandler, StandardRouteEntry e la funzione isStandardPluginDefinition da emdash.

Questi vengono rimossi. Erano alias di supporto per la forma precedente di definePlugin.

Cosa devo fare?

Usa SandboxedPlugin da emdash/plugin per lo stesso scopo. L’esportazione predefinita di un plugin sandboxed è già tipizzata dalla sua annotazione satisfies SandboxedPlugin, quindi non c’è alcuna sostituzione per isStandardPluginDefinition; identifica un plugin dalla sua struttura ({ hooks?, routes? }) se necessario.

Rinominato: il tipo di runtime SandboxedPlugin ora è SandboxedPluginInstance

Questo riguarda solo gli autori di un SandboxRunner personalizzato, come @emdash-cms/cloudflare. La maggior parte degli autori di plugin può saltare questa parte.

SandboxedPlugin da emdash ora si riferisce alla forma sorgente orientata all’autore. L’handle di runtime restituito da SandboxRunner.load è SandboxedPluginInstance.

Cosa devo fare?

Se importi SandboxedPlugin da emdash per tipizzare un sandbox runner o contenere handle di plugin di runtime, cambia l’importazione in SandboxedPluginInstance:

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

Informa i tuoi utenti

I siti che installano il tuo plugin devono anche modificare la loro importazione. Indica loro la nuova forma: elimina le parentesi graffe e le ().

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

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

Se il tuo plugin accettava una configurazione tramite la sua factory, quella configurazione si sposta nelle impostazioni del plugin dell’interfaccia di amministrazione. Leggila a runtime tramite ctx.kv o settings. Vedi Impostazioni.

Successivo