存档
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi.responses import StreamingResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
from kilostar.utils.access import Accessor, TokenData
|
||||
from kilostar.utils.ray_hook import ray_actor_hook
|
||||
from kilostar.utils.settings import get_plugin_dir
|
||||
|
||||
plugin_router = APIRouter(prefix="/api/v1/plugin", tags=["plugin"])
|
||||
|
||||
@@ -106,3 +109,56 @@ async def reload_plugin(
|
||||
pm = ray_actor_hook("global_plugin_manager").global_plugin_manager
|
||||
await pm.reload.remote(name)
|
||||
return {"status": "ok", "name": name}
|
||||
|
||||
|
||||
@plugin_router.get("/{name}/ui-manifest")
|
||||
async def ui_manifest(
|
||||
name: str,
|
||||
token_data: TokenData = Depends(Accessor.get_current_user),
|
||||
):
|
||||
"""返回 Web Component 注入所需的元数据。
|
||||
|
||||
读插件 build 产物 ``<plugin>/frontend/dist/wc-manifest.json``,把 ``js`` / ``css`` 路径
|
||||
转成绝对静态路径(与 ``/plugin-ui/<name>/`` 静态挂载对齐)。dist 不存在 → 404。
|
||||
"""
|
||||
plugin_dir = get_plugin_dir() / name
|
||||
if not plugin_dir.is_dir():
|
||||
raise HTTPException(404, f"plugin {name!r} not found")
|
||||
wc_path = plugin_dir / "frontend" / "dist" / "wc-manifest.json"
|
||||
if not wc_path.is_file():
|
||||
raise HTTPException(404, f"plugin {name!r} has no built UI")
|
||||
try:
|
||||
wc = json.loads(wc_path.read_text(encoding="utf-8"))
|
||||
except Exception as e:
|
||||
raise HTTPException(500, f"invalid wc-manifest.json: {e}")
|
||||
|
||||
js_rel = wc.get("js")
|
||||
if not js_rel or not isinstance(js_rel, str):
|
||||
raise HTTPException(500, "wc-manifest.json missing 'js'")
|
||||
tag = wc.get("tag")
|
||||
if not tag or not isinstance(tag, str):
|
||||
raise HTTPException(500, "wc-manifest.json missing 'tag'")
|
||||
|
||||
base_url = f"/plugin-ui/{name}"
|
||||
css_rel = wc.get("css") or []
|
||||
if isinstance(css_rel, str):
|
||||
css_rel = [css_rel]
|
||||
|
||||
# 顺便把 manifest.json 的展示元数据带回前端,少一次往返
|
||||
display_name = name
|
||||
icon = None
|
||||
try:
|
||||
manifest_data = json.loads((plugin_dir / "manifest.json").read_text(encoding="utf-8"))
|
||||
display_name = manifest_data.get("display_name") or name
|
||||
icon = (manifest_data.get("ui") or {}).get("icon")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {
|
||||
"name": name,
|
||||
"tag": tag,
|
||||
"js": f"{base_url}/{js_rel.lstrip('/')}",
|
||||
"css": [f"{base_url}/{c.lstrip('/')}" for c in css_rel],
|
||||
"display_name": display_name,
|
||||
"icon": icon,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user