Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions astrbot/dashboard/routes/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,9 @@ async def get_plugins(self):
if plugin.logo_path:
logo_url = await self.get_plugin_logo_token(plugin.logo_path)
_t = {
"name": plugin.name,
"name": plugin.name.replace(
"_", "-"
), # 统一转换为减号格式,与市场数据保持一致
Comment on lines +1272 to +1274
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Changing the name field from underscores to hyphens in the API response is a breaking change for plugin management. This field acts as the unique identifier for plugins in subsequent API calls such as /api/plugin/uninstall, /api/plugin/on/off, and /api/plugin/update. Since the backend lookup logic (e.g., get_registered_star or _get_plugin_metadata_by_name) performs a direct string comparison against the internal plugin name (which still uses underscores), these operations will fail for any plugin containing an underscore.

Furthermore, this will break plugin pages because _serve_plugin_page_content uses this name to look up metadata. It is recommended to keep the original name as the identifier and add a separate field for marketplace matching, or update all backend lookup logic to be separator-insensitive. Additionally, refactor the lookup logic into a shared helper function and ensure this new functionality is accompanied by unit tests.

References
  1. When implementing similar functionality for different cases (e.g., direct vs. quoted attachments), refactor the logic into a shared helper function to avoid code duplication.
  2. New functionality, such as handling attachments, should be accompanied by corresponding unit tests.

"repo": "" if plugin.repo is None else plugin.repo,
"author": plugin.author,
"desc": plugin.desc,
Expand Down Expand Up @@ -1319,7 +1321,9 @@ async def get_plugin_detail(self):
Response()
.ok(
{
"name": plugin.name,
"name": plugin.name.replace(
"_", "-"
), # 统一转换为减号格式,与市场数据保持一致
"repo": "" if plugin.repo is None else plugin.repo,
"author": plugin.author,
"desc": plugin.desc,
Expand Down Expand Up @@ -1371,7 +1375,9 @@ async def get_plugin_page_components(self, plugin) -> list[dict]:
"page_name": page["name"],
"i18n_key": page["i18n_key"],
"description": "Plugin Page entry",
"plugin_name": plugin.name,
"plugin_name": plugin.name.replace(
"_", "-"
), # 统一转换为减号格式,与市场数据保持一致
}
for page in pages
]
Expand Down
18 changes: 11 additions & 7 deletions dashboard/src/views/extension/useExtensionPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ export const useExtensionPage = () => {
const failRes = await axios.get("/api/plugin/source/get-failed-plugins");
failedPluginsDict.value = failRes.data.data || {};

checkUpdate();
// checkUpdate() is called after pluginMarketData is loaded in onMounted
} catch (err) {
toast(err, "error");
} finally {
Expand Down Expand Up @@ -642,14 +642,19 @@ export const useExtensionPage = () => {
if (plugin.repo) {
onlinePluginsMap.set(plugin.repo.toLowerCase(), plugin);
}
onlinePluginsNameMap.set(plugin.name, plugin);
const normalizedName = normalizeStr(plugin.name);
onlinePluginsNameMap.set(normalizedName, plugin);
});

const data = Array.isArray(extension_data?.data) ? extension_data.data : [];

data.forEach((extension) => {
const repoKey = extension.repo?.toLowerCase();
const onlinePlugin = repoKey ? onlinePluginsMap.get(repoKey) : null;
const onlinePluginByName = onlinePluginsNameMap.get(extension.name);

const normalizedExtensionName = normalizeStr(extension.name);
const onlinePluginByName = onlinePluginsNameMap.get(normalizedExtensionName);
Comment on lines +645 to +656
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The normalizeStr function only performs lowercasing and trimming; it does not handle the _ vs - difference. While the backend now returns hyphenated names in some responses, this makes the frontend matching logic fragile and dependent on inconsistent backend behavior. To ensure robust matching regardless of the backend's internal representation, it is safer to continue normalizing separators (e.g., .replace(/_/g, '-')) during comparison. Consider refactoring this logic into a shared helper function to avoid code duplication.

References
  1. When implementing similar functionality for different cases (e.g., direct vs. quoted attachments), refactor the logic into a shared helper function to avoid code duplication.


const matchedPlugin = onlinePlugin || onlinePluginByName;

if (matchedPlugin) {
Expand Down Expand Up @@ -1234,9 +1239,7 @@ export const useExtensionPage = () => {
const checkAlreadyInstalled = () => {
const data = Array.isArray(extension_data?.data) ? extension_data.data : [];
const installedRepos = new Set(data.map((ext) => ext.repo?.toLowerCase()));
const installedNames = new Set(
data.map((ext) => normalizeStr(ext.name).replace(/_/g, "-")),
); //统一格式,以防下面的匹配不生效
const installedNames = new Set(data.map((ext) => normalizeStr(ext.name)));
const installedByRepo = new Map(
data
.filter((ext) => ext.repo)
Expand Down Expand Up @@ -1266,7 +1269,7 @@ export const useExtensionPage = () => {

plugin.installed =
installedRepos.has(plugin.repo?.toLowerCase()) ||
installedNames.has(normalizeStr(plugin.name).replace(/_/g, "-")); //统一格式,防止匹配失败
installedNames.has(normalizeStr(plugin.name));
}

let installed = [];
Expand Down Expand Up @@ -1477,6 +1480,7 @@ export const useExtensionPage = () => {
selectedMarketInstallPlugin.value = null;
await getExtensions();
checkAlreadyInstalled();
checkUpdate();

viewReadme({
name: resData.data.name,
Expand Down
Loading