dsh-mcp-connector 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -1
- package/README.en.md +5 -4
- package/README.md +5 -4
- package/docs/MARKET-REGISTRATION.md +43 -3
- package/package.json +3 -2
- package/ui/index.html +79 -5
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.7] - 2026-08-22
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- 市场新增“服务商 + 接入方式”组合筛选,可快速查看 OAuth、Key/Token 或免密连接器,并可与全文搜索叠加。
|
|
12
|
+
- 新增 DSH 外部市场注册自动验收:每小时跟踪 PR #2633,合并后继续验证上游 YAML 与 DSH 实际 `plugins.json` 均已生效。
|
|
13
|
+
|
|
14
|
+
### Registry
|
|
15
|
+
|
|
16
|
+
- 独立远程 Registry 已扩展为 4 张第三方卡片、12 个 Server 和 16 个 Prompt;与随包目录合并后共 8 张已发布市场卡片。
|
|
17
|
+
- 新增“盈米·基金投顾”与“QVeris·通用能力网络”;QVeris 默认先做免费发现、参数检查与零成本询价,付费 `call` 需用户明确确认。
|
|
18
|
+
|
|
19
|
+
### Verification
|
|
20
|
+
|
|
21
|
+
- 自动化门禁通过 69 项测试与 43 个 npm 发布文件白名单/敏感内容扫描。
|
|
22
|
+
- QVeris Hosted MCP 无凭据公网探针返回预期的 HTTP 401,确认端点可达且正确要求 Bearer Key;未进行付费 `call`。
|
|
23
|
+
|
|
7
24
|
## [0.2.6] - 2026-08-21
|
|
8
25
|
|
|
9
26
|
### Documentation
|
|
@@ -147,7 +164,8 @@
|
|
|
147
164
|
- 外部 URL 与导入 Header 执行安全校验。
|
|
148
165
|
- iframe 消息校验同源和消息来源。
|
|
149
166
|
|
|
150
|
-
[Unreleased]: https://github.com/duhu2000/dsh-mcp-connector/compare/v0.2.
|
|
167
|
+
[Unreleased]: https://github.com/duhu2000/dsh-mcp-connector/compare/v0.2.7...HEAD
|
|
168
|
+
[0.2.7]: https://github.com/duhu2000/dsh-mcp-connector/compare/v0.2.6...v0.2.7
|
|
151
169
|
[0.2.6]: https://github.com/duhu2000/dsh-mcp-connector/compare/v0.2.5...v0.2.6
|
|
152
170
|
[0.2.5]: https://github.com/duhu2000/dsh-mcp-connector/compare/v0.2.4...v0.2.5
|
|
153
171
|
[0.2.4]: https://github.com/duhu2000/dsh-mcp-connector/compare/v0.2.3...v0.2.4
|
package/README.en.md
CHANGED
|
@@ -15,7 +15,7 @@ Browse and install MCP connectors from different providers in DeepSeek Harness D
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
17
|
- A primary sidebar entry below New Conversation and above workspaces/conversations, with a public footer-slot fallback for incompatible DSH DOM versions.
|
|
18
|
-
- Searchable Marketplace and Installed views
|
|
18
|
+
- Searchable Marketplace and Installed views, provider and connection-method filters, catalog refresh, and active health checks that distinguish Configured, Connected, Reauthorization Required, Partially Unavailable, and Connection Error states.
|
|
19
19
|
- OAuth 2.0 Authorization Code with PKCE, API key/Bearer/unauthenticated URL configuration, and `mcpServers` JSON import.
|
|
20
20
|
- Installation from a credential-free connector descriptor URL.
|
|
21
21
|
- Credential and MCP initialize validation before API-key connectors are saved as installed.
|
|
@@ -26,7 +26,7 @@ Browse and install MCP connectors from different providers in DeepSeek Harness D
|
|
|
26
26
|
- A standalone remote Registry, allowing new marketplace cards to appear after refresh without publishing a new npm version.
|
|
27
27
|
- Explicit, non-destructive migration of authorization from the two earlier Qichacha OAuth plugins.
|
|
28
28
|
|
|
29
|
-
The first four bundled cards are Qichacha connectors.
|
|
29
|
+
The first four bundled cards are Qichacha connectors, followed by PKULaw and Wind. After a remote Registry refresh, Yingmi and QVeris are also available, for eight published marketplace cards in total; the architecture is provider-neutral.
|
|
30
30
|
|
|
31
31
|
## Interface and demo
|
|
32
32
|
|
|
@@ -94,12 +94,13 @@ Set `catalogUrl` to an empty string for an explicitly offline/private setup.
|
|
|
94
94
|
npm run check
|
|
95
95
|
npm run registry:build
|
|
96
96
|
npm run registry:validate
|
|
97
|
+
npm run market:check
|
|
97
98
|
npm run dev:ui
|
|
98
99
|
```
|
|
99
100
|
|
|
100
|
-
`npm run check` performs syntax checks, automated tests, and an npm package allowlist/sensitive-content audit. Tags matching `v*` trigger GitHub Actions; the tag must match `package.json`. npm releases use Trusted Publishing through GitHub OIDC and do not require a long-lived `NPM_TOKEN`.
|
|
101
|
+
`npm run check` performs syntax checks, automated tests, and an npm package allowlist/sensitive-content audit. `npm run market:check` tracks the external DSH marketplace PR and live directory. Tags matching `v*` trigger GitHub Actions; the tag must match `package.json`. npm releases use Trusted Publishing through GitHub OIDC and do not require a long-lived `NPM_TOKEN`.
|
|
101
102
|
|
|
102
|
-
The current public version is [`dsh-mcp-connector@0.2.
|
|
103
|
+
The current public version is [`dsh-mcp-connector@0.2.7`](https://www.npmjs.com/package/dsh-mcp-connector), with [GitHub Release v0.2.7](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.7).
|
|
103
104
|
|
|
104
105
|
See [CHANGELOG.md](CHANGELOG.md) for version history and [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md) for the Desktop release checklist.
|
|
105
106
|
|
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
## 功能
|
|
16
16
|
|
|
17
17
|
- 左侧主导航入口:目标位置为“新会话”下方、“工作区/会话列表”上方;若 DSH DOM 结构不兼容,自动回退到底部公开插槽。
|
|
18
|
-
-
|
|
18
|
+
- 图形化市场:市场/已安装、全文搜索、服务商/接入方式组合筛选、刷新与主动健康检查;区分“已配置”、“已连接”、“需重新授权”、“部分异常”和“连接异常”。
|
|
19
19
|
- 图形化添加:手动 URL/鉴权、`mcpServers` JSON、连接器描述 URL 三种入口,失败时保留表单并给出修复建议。
|
|
20
20
|
- 连接器详情:精选 Prompt 优先展示,点击可带入 DSH 新会话;工具按 Server 分组,支持描述、搜索和独立滚动。
|
|
21
21
|
- Prompt 模板:使用 `{{company}}` 等变量,发送前填写真实查询主体。
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
- 平滑迁移:显式扫描并复制两个旧企查查 OAuth 插件授权;不删除原插件或原凭据。
|
|
29
29
|
- 对话工具:`mcp_connector_catalog`、`connect`、`configure`、`import_json`、`install_from_url`、`status`、`health_check`、`set_enabled`、`disconnect`、`refresh_catalog`、`publish`、`tools_list`。
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
随包目录前 4 张为企查查连接器,另含“北大法宝·法律检索”和“Wind·股票数据”。远程 Registry 刷新后还会加入“盈米·基金投顾”和“QVeris·通用能力网络”,当前共 8 张已发布市场卡片;插件架构不限定厂商。
|
|
32
32
|
|
|
33
33
|
## 界面与演示
|
|
34
34
|
|
|
@@ -90,12 +90,13 @@ Bundle 默认配置位于 `cordis.patch.yml`:
|
|
|
90
90
|
npm run check
|
|
91
91
|
npm run registry:build
|
|
92
92
|
npm run registry:validate
|
|
93
|
+
npm run market:check
|
|
93
94
|
npm run dev:ui
|
|
94
95
|
```
|
|
95
96
|
|
|
96
|
-
`check` 执行语法检查、自动测试和 npm 发布包白名单校验;`dev:ui` 启动不含真实凭据的本地 mock 市场。CI 使用 `--legacy-peer-deps` 安装显式测试依赖,DSH 运行期 peer 仍由 Host 提供。`v*` Tag 会触发 GitHub Actions;Tag 必须与 `package.json` 版本一致。Release 通过 npm Trusted Publishing (GitHub OIDC) 发布,不依赖长期 `NPM_TOKEN`。
|
|
97
|
+
`check` 执行语法检查、自动测试和 npm 发布包白名单校验;`market:check` 检查外部 DSH 市场 PR 与线上目录;`dev:ui` 启动不含真实凭据的本地 mock 市场。CI 使用 `--legacy-peer-deps` 安装显式测试依赖,DSH 运行期 peer 仍由 Host 提供。`v*` Tag 会触发 GitHub Actions;Tag 必须与 `package.json` 版本一致。Release 通过 npm Trusted Publishing (GitHub OIDC) 发布,不依赖长期 `NPM_TOKEN`。
|
|
97
98
|
|
|
98
|
-
当前公开版本为 [`dsh-mcp-connector@0.2.
|
|
99
|
+
当前公开版本为 [`dsh-mcp-connector@0.2.7`](https://www.npmjs.com/package/dsh-mcp-connector),对应 [GitHub Release v0.2.7](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.7)。
|
|
99
100
|
|
|
100
101
|
版本能力与变更记录见 [CHANGELOG.md](CHANGELOG.md)。
|
|
101
102
|
Desktop 发版回归见 [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md)。
|
|
@@ -27,7 +27,18 @@ Bearer/API Key 型连接器可在卡片上点「配置」,一次填写凭据
|
|
|
27
27
|
|
|
28
28
|
插件默认读取 `https://raw.githubusercontent.com/duhu2000/dsh-mcp-connector-registry/main/catalog.json`;远程不可用时自动回退上次缓存或随包内置目录。
|
|
29
29
|
|
|
30
|
-
## 4.
|
|
30
|
+
## 4. DSH 外部插件市场验收
|
|
31
|
+
|
|
32
|
+
`dsh-mcp-connector` 在 `awesome-dsh-plugin` 的注册 PR 为 [#2633](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/2633)。仓库每小时自动执行 `.github/workflows/market-registration.yml`:
|
|
33
|
+
|
|
34
|
+
1. PR 未合并时记录为 `awaiting-merge`,不误报构建失败;
|
|
35
|
+
2. PR 合并后检查上游 `data/plugins/duhu2000__dsh-mcp-connector.yml` 已进入 `main`;
|
|
36
|
+
3. 继续检查 DSH Market 实际使用的 `https://awesome-dsh-plugin.com/plugins.json`;
|
|
37
|
+
4. YAML 与线上目录均生效后状态为 `accepted`,否则在合并后明确报告目录同步未完成。
|
|
38
|
+
|
|
39
|
+
本地可运行 `npm run market:check`查看状态;CI 使用 `--strict-after-merge` 让“已合并但尚未可搜索”成为可见的验收信号。此检查仅需 GitHub Actions 默认的只读 `GITHUB_TOKEN`,不需要新增长期密钥。
|
|
40
|
+
|
|
41
|
+
## 5. OAuth 一键授权要求
|
|
31
42
|
|
|
32
43
|
`auth.mode: "oauth2-pkce"` 不是将现有 Bearer Token 改个名称。厂商服务端必须支持:
|
|
33
44
|
|
|
@@ -67,7 +78,7 @@ Bearer/API Key 型连接器可在卡片上点「配置」,一次填写凭据
|
|
|
67
78
|
}
|
|
68
79
|
```
|
|
69
80
|
|
|
70
|
-
##
|
|
81
|
+
## 6. 北大法宝当前适配结论
|
|
71
82
|
|
|
72
83
|
北大法宝当前公开文档的主路径是在控制台生成 Access Token,然后通过 `Authorization: Bearer ...` 访问多个 MCP Server。因此:
|
|
73
84
|
|
|
@@ -89,7 +100,7 @@ Bearer/API Key 型连接器可在卡片上点「配置」,一次填写凭据
|
|
|
89
100
|
- https://mcp.pkulaw.com/docs?doc=authentication
|
|
90
101
|
- https://mcp.pkulaw.com/docs?doc=mcp-integration
|
|
91
102
|
|
|
92
|
-
##
|
|
103
|
+
## 7. Wind 股票数据当前适配结论
|
|
93
104
|
|
|
94
105
|
万得 AIFin Market 的“万得股票数据服务”详情页公开了标准 MCP 手工配置:
|
|
95
106
|
|
|
@@ -105,3 +116,32 @@ Bearer/API Key 型连接器可在卡片上点「配置」,一次填写凭据
|
|
|
105
116
|
参考:
|
|
106
117
|
|
|
107
118
|
- https://aifinmarket.wind.com.cn/#/market?tab=mcps&detailType=mcp&detailId=wind_stock_data-0
|
|
119
|
+
|
|
120
|
+
## 8. QVeris 通用能力网络适配结论
|
|
121
|
+
|
|
122
|
+
QVeris Hosted MCP 提供单一 Streamable HTTP 端点 `https://mcp.qveris.ai/mcp`,
|
|
123
|
+
通过 `Authorization: Bearer <QVERIS_API_KEY>` 鉴权,与本插件现有的 Bearer
|
|
124
|
+
凭据表单、持久化前 `initialize` 校验和 Streamable HTTP 传输完全兼容。
|
|
125
|
+
|
|
126
|
+
市场卡片只列出 QVeris 对 MCP 暴露的 6 个路由/审计工具:`discover`、
|
|
127
|
+
`inspect`、`probe`、`call`、`usage_history` 和 `credits_ledger`。官方宣传的
|
|
128
|
+
上万项能力是经 `discover` 找到的下游能力,不写成上万个 MCP 工具。
|
|
129
|
+
|
|
130
|
+
由于 `call` 可能消耗 Credits,且查询内容可能由第三方服务商处理,
|
|
131
|
+
该卡片保持 `featured: false`,并执行以下产品约束:
|
|
132
|
+
|
|
133
|
+
- Prompt 默认只执行免费 `discover`/`inspect` 和零成本询价 `probe`;
|
|
134
|
+
- 未经用户明确确认,不执行付费 `call`;
|
|
135
|
+
- 卡片明确提醒用户不要提交未获授权的个人信息、商业秘密或敏感业务数据;
|
|
136
|
+
- 未取得品牌授权前使用市场默认中性图标,不内置第三方商标资产。
|
|
137
|
+
|
|
138
|
+
公共无凭据探针已确认端点可达并正确返回 HTTP 401;完整的
|
|
139
|
+
`tools/list` 和免费发现/询价回归需要用户在 DSH 本机输入自有 API Key。
|
|
140
|
+
|
|
141
|
+
参考:
|
|
142
|
+
|
|
143
|
+
- https://qveris.ai/hosted-mcp
|
|
144
|
+
- https://qveris.ai/docs/mcp-server
|
|
145
|
+
- https://qveris.ai/pricing
|
|
146
|
+
- https://qveris.ai/privacy
|
|
147
|
+
- https://qveris.ai/terms
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mcp-connector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "General-purpose MCP connector, connection manager, plugin extension, and integration marketplace for DeepSeek Harness, initiated and maintained by Qichacha/QCC.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,10 +31,11 @@
|
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
33
|
"test": "node --test",
|
|
34
|
-
"lint": "node --check lib/index.js && node --check lib/web.js && node --check lib/client.js && node --check lib/schema.js && node --check lib/catalog.js && node --check lib/prompts.js && node --check lib/probe.js && node --check lib/mcp-validation.js && node --check lib/migration.js && node --check lib/stores.js && node --check lib/oauth.js && node --check lib/callback-server.js && node --check lib/mcp-provision.js && node --check lib/util.js && node --check lib/constants.js && node --check lib/tools.js && node --check lib/connectors/oauth-connector.js && node --check lib/connectors/manual-connector.js && node --check lib/connectors/json-connector.js && node --check scripts/probe-connector.mjs && node --check scripts/build-registry.mjs && node --check scripts/ui-harness.mjs",
|
|
34
|
+
"lint": "node --check lib/index.js && node --check lib/web.js && node --check lib/client.js && node --check lib/schema.js && node --check lib/catalog.js && node --check lib/prompts.js && node --check lib/probe.js && node --check lib/mcp-validation.js && node --check lib/migration.js && node --check lib/stores.js && node --check lib/oauth.js && node --check lib/callback-server.js && node --check lib/mcp-provision.js && node --check lib/util.js && node --check lib/constants.js && node --check lib/tools.js && node --check lib/connectors/oauth-connector.js && node --check lib/connectors/manual-connector.js && node --check lib/connectors/json-connector.js && node --check scripts/probe-connector.mjs && node --check scripts/build-registry.mjs && node --check scripts/ui-harness.mjs && node --check scripts/check-market-registration.mjs",
|
|
35
35
|
"registry:build": "node scripts/build-registry.mjs",
|
|
36
36
|
"registry:validate": "node scripts/probe-connector.mjs catalog/catalog.json --validate-only",
|
|
37
37
|
"dev:ui": "node scripts/ui-harness.mjs",
|
|
38
|
+
"market:check": "node scripts/check-market-registration.mjs",
|
|
38
39
|
"verify-pack": "node scripts/verify-pack.mjs",
|
|
39
40
|
"check": "npm run lint && npm test && npm run verify-pack",
|
|
40
41
|
"prepublishOnly": "npm run check"
|
package/ui/index.html
CHANGED
|
@@ -104,6 +104,25 @@
|
|
|
104
104
|
.stats { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; }
|
|
105
105
|
.stats .count { font-size: 13px; color: var(--text-2); }
|
|
106
106
|
.stats .count strong { color: var(--text); font-weight: 600; }
|
|
107
|
+
.market-filters {
|
|
108
|
+
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
|
|
109
|
+
margin-bottom: 14px; padding: 10px 12px;
|
|
110
|
+
background: var(--card); border: 1px solid var(--line); border-radius: 10px;
|
|
111
|
+
}
|
|
112
|
+
.market-filters .filter-label { color: var(--muted); font-size: 12px; flex: 0 0 auto; }
|
|
113
|
+
.market-filters select {
|
|
114
|
+
min-width: 150px; height: 34px; border: 1px solid var(--line); border-radius: 8px;
|
|
115
|
+
background: var(--bg); color: var(--text); padding: 0 30px 0 10px; font: inherit; font-size: 12px;
|
|
116
|
+
}
|
|
117
|
+
.market-filters select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); }
|
|
118
|
+
.filter-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
119
|
+
.filter-chip {
|
|
120
|
+
border: 1px solid var(--line); background: var(--bg); color: var(--text-2);
|
|
121
|
+
border-radius: 999px; padding: 5px 10px; cursor: pointer; font: inherit; font-size: 12px;
|
|
122
|
+
}
|
|
123
|
+
.filter-chip:hover { border-color: var(--accent); color: var(--accent); }
|
|
124
|
+
.filter-chip.active { border-color: var(--accent); background: var(--accent-light); color: var(--accent); font-weight: 600; }
|
|
125
|
+
.filter-reset { margin-left: auto; }
|
|
107
126
|
|
|
108
127
|
/* Grid - TraeWork 风格:3 列 */
|
|
109
128
|
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
|
|
@@ -346,6 +365,9 @@
|
|
|
346
365
|
.card { flex-wrap: wrap; }
|
|
347
366
|
.card .actions { width: 100%; justify-content: flex-end; }
|
|
348
367
|
.form-row { grid-template-columns: 1fr; gap: 0; }
|
|
368
|
+
.market-filters { align-items: stretch; }
|
|
369
|
+
.market-filters select { width: 100%; }
|
|
370
|
+
.filter-reset { margin-left: 0; }
|
|
349
371
|
}
|
|
350
372
|
|
|
351
373
|
/* Scrollbar */
|
|
@@ -447,6 +469,8 @@
|
|
|
447
469
|
let view = 'market';
|
|
448
470
|
let marketItems = {};
|
|
449
471
|
let searchQuery = '';
|
|
472
|
+
let marketVendor = '';
|
|
473
|
+
let marketAuth = '';
|
|
450
474
|
const PROMPT_PAGE_SIZE = 4;
|
|
451
475
|
let detailPrompts = [];
|
|
452
476
|
let promptPage = 0;
|
|
@@ -665,6 +689,30 @@
|
|
|
665
689
|
|| (d.tags || []).some(t => t.toLowerCase().includes(q));
|
|
666
690
|
}
|
|
667
691
|
|
|
692
|
+
const AUTH_FILTERS = [
|
|
693
|
+
{ value: '', label: '全部接入' },
|
|
694
|
+
{ value: 'oauth2-pkce', label: 'OAuth' },
|
|
695
|
+
{ value: 'credential', label: 'Key / Token' },
|
|
696
|
+
{ value: 'none', label: '免密' },
|
|
697
|
+
];
|
|
698
|
+
|
|
699
|
+
function matchesMarketFilters(d) {
|
|
700
|
+
if (!matchesSearch(d)) return false;
|
|
701
|
+
if (marketVendor && d.vendor !== marketVendor) return false;
|
|
702
|
+
if (marketAuth === 'credential') return ['bearer', 'api-key'].includes(d.authMode);
|
|
703
|
+
if (marketAuth && d.authMode !== marketAuth) return false;
|
|
704
|
+
return true;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function marketFilterHtml(items) {
|
|
708
|
+
const vendors = [...new Set(items.map((item) => item.vendor).filter(Boolean))]
|
|
709
|
+
.sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
|
710
|
+
const vendorOptions = [`<option value="">全部服务商</option>`, ...vendors.map((vendor) => `<option value="${esc(vendor)}" ${vendor === marketVendor ? 'selected' : ''}>${esc(vendor)}</option>`)].join('');
|
|
711
|
+
const authButtons = AUTH_FILTERS.map((filter) => `<button class="filter-chip ${filter.value === marketAuth ? 'active' : ''}" type="button" data-auth-filter="${esc(filter.value)}" aria-pressed="${filter.value === marketAuth ? 'true' : 'false'}">${esc(filter.label)}</button>`).join('');
|
|
712
|
+
const active = Boolean(marketVendor || marketAuth);
|
|
713
|
+
return `<div class="market-filters" role="group" aria-label="市场筛选"><span class="filter-label">服务商</span><select id="market-vendor-filter" aria-label="按服务商筛选">${vendorOptions}</select><span class="filter-label">接入方式</span><div class="filter-chips" role="group" aria-label="按接入方式筛选">${authButtons}</div><button class="text-btn filter-reset" id="market-filter-reset" type="button" ${active ? '' : 'hidden'}>清除筛选</button></div>`;
|
|
714
|
+
}
|
|
715
|
+
|
|
668
716
|
async function loadMarket({ checkHealth = true } = {}) {
|
|
669
717
|
main.innerHTML = '<div class="empty">加载中…</div>';
|
|
670
718
|
const r = await call('catalog', {});
|
|
@@ -673,10 +721,15 @@
|
|
|
673
721
|
if (!items.length) { main.innerHTML = '<div class="empty">暂无已上架的连接器</div>'; return; }
|
|
674
722
|
marketItems = {};
|
|
675
723
|
items.forEach((d) => { marketItems[d.id] = d; });
|
|
676
|
-
const filtered = items.filter(
|
|
724
|
+
const filtered = items.filter(matchesMarketFilters);
|
|
677
725
|
const count = filtered.length;
|
|
678
726
|
const visible = filtered.slice(0, catalogRenderLimit);
|
|
679
|
-
|
|
727
|
+
const authLabel = AUTH_FILTERS.find((filter) => filter.value === marketAuth)?.label;
|
|
728
|
+
const filterSummary = `${marketVendor ? ` · 服务商「${esc(marketVendor)}」` : ''}${marketAuth ? ` · 接入方式「${esc(authLabel)}」` : ''}`;
|
|
729
|
+
const resultHtml = visible.length > 0
|
|
730
|
+
? `<div class="grid">${visible.map(cardHtml).join('')}</div>${visible.length < count ? `<button class="tools-more" id="catalog-more" type="button">再显示 ${Math.min(60, count - visible.length)} 个(剩余 ${count - visible.length})</button>` : ''}`
|
|
731
|
+
: '<div class="empty">没有匹配当前筛选条件的连接器</div>';
|
|
732
|
+
main.innerHTML = `${marketFilterHtml(items)}<div class="stats"><span class="count">共 <strong>${count}</strong> 个连接器${searchQuery ? ` · 搜索「${esc(searchQuery)}」` : ''}${filterSummary} · 点击卡片查看能力,点击「连接」完成授权</span></div>${resultHtml}`;
|
|
680
733
|
if (checkHealth && !initialHealthCheckStarted && items.some((item) => item.connected?.length > 0)) {
|
|
681
734
|
initialHealthCheckStarted = true;
|
|
682
735
|
call('healthCheck', {}).then(() => {
|
|
@@ -1198,9 +1251,30 @@
|
|
|
1198
1251
|
|
|
1199
1252
|
$('#add-connection').addEventListener('click', () => openAddConnection('json'));
|
|
1200
1253
|
main.addEventListener('click', (event) => {
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1254
|
+
const authFilter = event.target.closest('[data-auth-filter]');
|
|
1255
|
+
if (authFilter) {
|
|
1256
|
+
marketAuth = authFilter.dataset.authFilter || '';
|
|
1257
|
+
catalogRenderLimit = 60;
|
|
1258
|
+
loadMarket({ checkHealth: false });
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
if (event.target.closest('#market-filter-reset')) {
|
|
1262
|
+
marketVendor = '';
|
|
1263
|
+
marketAuth = '';
|
|
1264
|
+
catalogRenderLimit = 60;
|
|
1265
|
+
loadMarket({ checkHealth: false });
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
if (event.target.closest('#catalog-more')) {
|
|
1269
|
+
catalogRenderLimit += 60;
|
|
1270
|
+
loadMarket({ checkHealth: false });
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
main.addEventListener('change', (event) => {
|
|
1274
|
+
if (event.target.id !== 'market-vendor-filter') return;
|
|
1275
|
+
marketVendor = event.target.value;
|
|
1276
|
+
catalogRenderLimit = 60;
|
|
1277
|
+
loadMarket({ checkHealth: false });
|
|
1204
1278
|
});
|
|
1205
1279
|
|
|
1206
1280
|
$('#refresh').addEventListener('click', async () => {
|