dsh-plugin-market
> DSH 插件市场(组合包,重启常驻)— 在设置面板浏览 awesome-dsh-plugin 社区精选列表,支持搜索/分类/排序、GitHub 星标排名、一键安装、已装检测、收藏。
重启 dsh 自动激活,永不丢失。任何人 dsh plugin --profile web add github:joeyefengying/dsh-plugin-market 即可装上。
功能
- 🔍 搜索(按名字 / 描述)
- 🗂 分类筛选(11 类 + 全部)
- ↕️ 排序:精选顺序 / ★ 星标降序 / 名称 A→Z / Z→A
- ★ 收藏(持久化到
~/.dsh/.dsh-market-favorites.json,可「只看收藏」过滤) - ⬇️ 一键安装(Host 执行
dsh plugin --profile web add github:owner/repo) - ✅ 已装检测(读 profile
package.json依赖比对,显示「已安装」徽标)
架构:HTTP 路由通信
组合包插件没有动态插件的 harness.handle/host.call RPC,所以用 HTTP 路由 做 host↔client 通信(与 dsh-side-panel 同一模式):
| 半边 | 职责 | 技术 |
|---|---|---|
Host (lib/index.js) | 注册 HTTP 路由 /dsh-market/api,handler 里跑 node fetch(拉列表/GraphQL 星标)、child_process(执行安装)、fs(读写收藏/已装) | ctx.webServer.register + node:fs/child_process + global fetch |
Client (lib/client.js) | 在 settings.section 注册市场页,用浏览器 fetch 调路由取数据、触发安装 | React + fetch('/dsh-market/api') + slots |
数据源:https://raw.githubusercontent.com/awesome-dsh-plugin/awesome-dsh-plugin/main/README.md
文件
src/index.js # Host 源码(ESM,node 原生 API)
src/client.js # Client 源码(React.createElement + fetch)
lib/index.js # Host 产物(直接复制,无需构建)
lib/client.js # Client 产物(CJS bundle,__ModuleLoader__ 包装,react external)
cordis.patch.yml # 组合激活行: { id: dsh#sh-market, name: dsh-plugin-market }
package.json # dsh.bundle.patch + exports + dsh.clientlib/ 已预编译,安装时无需构建(无 prepare 脚本、无依赖)。
GitHub 星标排名
227+ 仓库超过未认证限额,星标排名需要 token。在 ~/.dsh/.env 加 GITHUB_TOKEN=ghp_你的token 并重启 dsh。未设置时星标排序不可用,其余功能不受影响。
从源码重建 client
client 只有一个 import(react),无需打包器:
node -e '
const fs=require("fs"); let s=fs.readFileSync("src/client.js","utf8");
s=s.replace(/import\s*\{([^}]*?)\}\s*from\s*["\x27]react["\x27]\s*;?/,(m,n)=>"const { "+n.trim().replace(/\bas\b/g,":")+" } = require(\"react\");");
s=s.replace(/export\s*\{\s*apply\s*,\s*inject\s*\}\s*;?\s*$/,"module.exports = { apply, inject };");
fs.writeFileSync("lib/client.js","window.__ModuleLoader__.load({ id: \x27dsh-plugin-market\x27, factory: (require) => { var module = { exports: {} }; var exports = module.exports;\n\"use strict\";\n"+s+"\nreturn module.exports; } });\n");
'Host 是纯 ESM(仅 node: 导入),直接 cp src/index.js lib/index.js。
License
MIT