mirror of
https://github.com/simonw/datasette.git
synced 2026-07-09 09:04:42 +02:00
Convert /-/plugins.json from top-level array to object
/-/plugins.json now returns {"ok": true, "plugins": [...]} instead of a
bare JSON array, so the response can grow additional keys without a
breaking change. The `datasette plugins` CLI command still outputs a
plain array.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
parent
089e96a437
commit
b74a8e5b12
7 changed files with 39 additions and 18 deletions
|
|
@ -2551,7 +2551,10 @@ class Datasette:
|
|||
)
|
||||
add_route(
|
||||
JsonDataView.as_view(
|
||||
self, "plugins.json", self._plugins, needs_request=True
|
||||
self,
|
||||
"plugins.json",
|
||||
lambda request: {"plugins": self._plugins(request)},
|
||||
needs_request=True,
|
||||
),
|
||||
r"/-/plugins(\.(?P<format>json))?$",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -78,15 +78,18 @@ Shows a list of currently installed plugins and their versions. `Plugins example
|
|||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{
|
||||
"name": "datasette_cluster_map",
|
||||
"static": true,
|
||||
"templates": false,
|
||||
"version": "0.10",
|
||||
"hooks": ["extra_css_urls", "extra_js_urls", "extra_body_script"]
|
||||
}
|
||||
]
|
||||
{
|
||||
"ok": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "datasette_cluster_map",
|
||||
"static": true,
|
||||
"templates": false,
|
||||
"version": "0.10",
|
||||
"hooks": ["extra_css_urls", "extra_js_urls", "extra_body_script"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Add ``?all=1`` to include details of the default plugins baked into Datasette.
|
||||
|
||||
|
|
|
|||
|
|
@ -228,8 +228,8 @@ app.py:2552-2557, `Datasette._plugins` (app.py:2247-2266). Permission
|
|||
|
||||
- **Parameters:** `?all=1` — include Datasette's built-in default plugins
|
||||
(filtered out by default).
|
||||
- **Response:** a JSON **array**, sorted by name, of
|
||||
`{"name", "static", "templates", "version", "hooks"}`.
|
||||
- **Response:** `{"ok": true, "plugins": [...]}` — each plugin is
|
||||
`{"name", "static", "templates", "version", "hooks"}`, sorted by name.
|
||||
|
||||
### GET /-/settings(.json)
|
||||
|
||||
|
|
|
|||
|
|
@ -541,13 +541,13 @@ async def test_plugins_json(ds_client):
|
|||
response = await ds_client.get("/-/plugins.json")
|
||||
# Filter out TrackEventPlugin
|
||||
actual_plugins = sorted(
|
||||
[p for p in response.json() if p["name"] != "TrackEventPlugin"],
|
||||
[p for p in response.json()["plugins"] if p["name"] != "TrackEventPlugin"],
|
||||
key=lambda p: p["name"],
|
||||
)
|
||||
assert EXPECTED_PLUGINS == actual_plugins
|
||||
# Try with ?all=1
|
||||
response = await ds_client.get("/-/plugins.json?all=1")
|
||||
names = {p["name"] for p in response.json()}
|
||||
names = {p["name"] for p in response.json()["plugins"]}
|
||||
assert names.issuperset(p["name"] for p in EXPECTED_PLUGINS)
|
||||
assert names.issuperset(DEFAULT_PLUGINS)
|
||||
|
||||
|
|
|
|||
|
|
@ -109,9 +109,10 @@ def test_settings(config_dir_client):
|
|||
def test_plugins(config_dir_client):
|
||||
response = config_dir_client.get("/-/plugins.json")
|
||||
assert 200 == response.status
|
||||
assert "hooray.py" in {p["name"] for p in response.json}
|
||||
assert "non_py_file.txt" not in {p["name"] for p in response.json}
|
||||
assert "mypy_cache" not in {p["name"] for p in response.json}
|
||||
plugins = response.json["plugins"]
|
||||
assert "hooray.py" in {p["name"] for p in plugins}
|
||||
assert "non_py_file.txt" not in {p["name"] for p in plugins}
|
||||
assert "mypy_cache" not in {p["name"] for p in plugins}
|
||||
|
||||
|
||||
def test_templates_and_plugin(config_dir_client):
|
||||
|
|
|
|||
|
|
@ -1482,7 +1482,7 @@ async def test_plugin_is_installed():
|
|||
datasette.pm.register(DummyPlugin(), name="DummyPlugin")
|
||||
response = await datasette.client.get("/-/plugins.json")
|
||||
assert response.status_code == 200
|
||||
installed_plugins = {p["name"] for p in response.json()}
|
||||
installed_plugins = {p["name"] for p in response.json()["plugins"]}
|
||||
assert "DummyPlugin" in installed_plugins
|
||||
|
||||
finally:
|
||||
|
|
|
|||
|
|
@ -76,3 +76,17 @@ async def test_permissions_post_success_has_ok_true(ds_envelope):
|
|||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["ok"] is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_plugins_json_is_object(ds_client):
|
||||
response = await ds_client.get("/-/plugins.json")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert set(data.keys()) == {"ok", "plugins"}
|
||||
assert data["ok"] is True
|
||||
assert isinstance(data["plugins"], list)
|
||||
# ?all=1 should include Datasette's default plugins in the same shape
|
||||
response_all = await ds_client.get("/-/plugins.json?all=1")
|
||||
all_plugins = response_all.json()["plugins"]
|
||||
assert len(all_plugins) > len(data["plugins"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue