diff --git a/CHANGELOG.md b/CHANGELOG.md index c5a97ec..8a62a78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ for how the document, manifest, and per-plugin versions relate. ## [Unreleased] +### Fixed +- **Route-prefix examples now match the Host.** Every illustrative route prefix said + `/api/plugin//…` (singular) in §7.3, twice in `best-practices.md`, and throughout + `examples/full-plugin` (`routes.py`, `screen.js`, `settings.html`), while the feedBack Host + serves plugin routes under **`/api/plugins/…`** (plural) — and the rest of + `best-practices.md` already used the plural form. All examples and prose now use + `/api/plugins//…`. The normative rule (§7.4: derive every route path from the plugin + `id`) is unchanged — the singular form only ever appeared in examples, never as a + requirement. Closes [#20](https://github.com/got-feedBack/feedBack-plugin-spec/issues/20). + ### Added - **Module `script` entries.** §3 (Anatomy), §4.1/§4.3, new §6.8 (Splitting client code), and `schemas/plugin.schema.json` document the optional **`scriptType`** manifest key: `"module"` loads diff --git a/examples/full-plugin/routes.py b/examples/full-plugin/routes.py index d8e97e0..9a29322 100644 --- a/examples/full-plugin/routes.py +++ b/examples/full-plugin/routes.py @@ -35,11 +35,11 @@ def _read() -> dict: return dict(_DEFAULTS) # Everything below only runs after the plugin has validated its own state. - @app.get(f"/api/plugin/{PLUGIN_ID}/settings") + @app.get(f"/api/plugins/{PLUGIN_ID}/settings") def get_settings() -> JSONResponse: return JSONResponse(_read()) - @app.post(f"/api/plugin/{PLUGIN_ID}/settings") + @app.post(f"/api/plugins/{PLUGIN_ID}/settings") async def set_settings(request: Request) -> JSONResponse: incoming = await request.json() if not isinstance(incoming, dict): diff --git a/examples/full-plugin/screen.js b/examples/full-plugin/screen.js index b084ed9..d0134ab 100644 --- a/examples/full-plugin/screen.js +++ b/examples/full-plugin/screen.js @@ -3,7 +3,7 @@ // The exact runtime API the Host exposes to a plugin screen is Host-provided and // out of scope for spec v0.1.0 (see spec §6.1). This file shows the *shape* of a // screen module: it renders into its own root element and talks only to its own -// namespaced routes (/api/plugin/full-plugin/...). Keep all DOM and CSS scoped to +// namespaced routes (/api/plugins/full-plugin/...). Keep all DOM and CSS scoped to // the plugin's root so nothing leaks into the rest of the app. const PLUGIN_ID = "full-plugin"; @@ -17,7 +17,7 @@ export async function mount(root) { `; try { - const res = await fetch(`/api/plugin/${PLUGIN_ID}/settings`); + const res = await fetch(`/api/plugins/${PLUGIN_ID}/settings`); const settings = await res.json(); root.querySelector('[data-role="color"]').textContent = settings.color; } catch (err) { diff --git a/examples/full-plugin/settings.html b/examples/full-plugin/settings.html index 4bd7ba7..dbb4d96 100644 --- a/examples/full-plugin/settings.html +++ b/examples/full-plugin/settings.html @@ -2,7 +2,7 @@ Settings panel for the full-plugin example. The Host renders this markup in the plugin's settings slot, grouped under settings.category ("graphics"). Scope any styles/scripts to the panel; persist values through the plugin's own routes - (/api/plugin/full-plugin/settings), not by writing files directly from the client. + (/api/plugins/full-plugin/settings), not by writing files directly from the client. -->