@wenbin_wb/dsh-bridge 2.0.0 → 2.0.2
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/README.md +10 -0
- package/README.zh-CN.md +10 -0
- package/client/client.js +59 -11
- package/client/index.js +62 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,6 +87,16 @@ dsh plugin --profile web add ./dsh-bridge
|
|
|
87
87
|
|
|
88
88
|
After installation, restart DSH and find "Remote Access" in settings.
|
|
89
89
|
|
|
90
|
+
### Upgrade to latest
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
dsh plugin --profile web add @wenbin_wb/dsh-bridge@latest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
> **Note**: `update --latest` may fail to reach the newest major version due to version constraints from already-installed dependencies. Use the `add @latest` command above to force-install the latest version (no need to know the exact version number).
|
|
97
|
+
|
|
98
|
+
After upgrading, restart DSH and **hard-refresh** the browser (Windows: `Ctrl+Shift+R`, macOS: `Cmd+Shift+R`) to clear the cache, then confirm the latest version is shown in settings.
|
|
99
|
+
|
|
90
100
|
---
|
|
91
101
|
|
|
92
102
|
## Usage
|
package/README.zh-CN.md
CHANGED
|
@@ -87,6 +87,16 @@ dsh plugin --profile web add ./dsh-bridge
|
|
|
87
87
|
|
|
88
88
|
安装完成后重启 DSH,在设置页找到「远程访问」即可使用。
|
|
89
89
|
|
|
90
|
+
### 升级到最新版
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
dsh plugin --profile web add @wenbin_wb/dsh-bridge@latest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
> **注意**:`update --latest` 可能因已安装依赖的版本约束而无法升级到最新版。用上面的 `add @latest` 命令即可强制安装最新版(无需知道具体版本号)。
|
|
97
|
+
|
|
98
|
+
升级完成后重启 DSH,并在浏览器**硬刷新**(Windows: `Ctrl+Shift+R`,macOS: `Cmd+Shift+R`)清除缓存,然后确认设置页显示最新版本号。
|
|
99
|
+
|
|
90
100
|
---
|
|
91
101
|
|
|
92
102
|
## 使用
|
package/client/client.js
CHANGED
|
@@ -62,8 +62,10 @@ var BRIDGE_ENDPOINTS = {
|
|
|
62
62
|
|
|
63
63
|
// client/index.js
|
|
64
64
|
var GITHUB_URL = "https://github.com/wenbin-wb/dsh-bridge";
|
|
65
|
+
var RELEASES_URL = "https://github.com/wenbin-wb/dsh-bridge/releases";
|
|
65
66
|
var ISSUES_URL = "https://github.com/wenbin-wb/dsh-bridge/issues/new";
|
|
66
67
|
var TUNNEL_DOCS_URL = "https://github.com/wenbin-wb/dsh-bridge/blob/main/docs/custom-tunnel.md";
|
|
68
|
+
var UPGRADE_COMMAND = "dsh plugin --profile web add @wenbin_wb/dsh-bridge@latest";
|
|
67
69
|
var name = "dsh-bridge";
|
|
68
70
|
var inject = ["slots", "connection"];
|
|
69
71
|
function semverGt(a, b) {
|
|
@@ -95,6 +97,32 @@ var s = {
|
|
|
95
97
|
warn: { background: "var(--dsw-alias-state-warn-bg,#fffbeb)", border: "1px solid var(--dsw-alias-state-warn-border,#fde68a)", borderRadius: 8, padding: "10px 14px", fontSize: 12, color: "var(--dsw-alias-state-warn-primary,#92400e)", lineHeight: 1.6 },
|
|
96
98
|
tip: { background: "var(--dsw-alias-bg-layer-2,#f9fafb)", borderRadius: 8, padding: "10px 14px", fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)", lineHeight: 1.6 }
|
|
97
99
|
};
|
|
100
|
+
function useCopy() {
|
|
101
|
+
const [copied, setCopied] = React.useState(false);
|
|
102
|
+
const copy = React.useCallback((text) => {
|
|
103
|
+
const done = () => {
|
|
104
|
+
setCopied(true);
|
|
105
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
106
|
+
};
|
|
107
|
+
if (navigator.clipboard?.writeText) {
|
|
108
|
+
navigator.clipboard.writeText(text).then(done).catch(() => fallbackCopy());
|
|
109
|
+
} else {
|
|
110
|
+
fallbackCopy();
|
|
111
|
+
}
|
|
112
|
+
function fallbackCopy() {
|
|
113
|
+
const textarea = document.createElement("textarea");
|
|
114
|
+
textarea.value = text;
|
|
115
|
+
textarea.style.position = "fixed";
|
|
116
|
+
textarea.style.opacity = "0";
|
|
117
|
+
document.body.appendChild(textarea);
|
|
118
|
+
textarea.select();
|
|
119
|
+
const success = document.execCommand("copy");
|
|
120
|
+
document.body.removeChild(textarea);
|
|
121
|
+
if (success) done();
|
|
122
|
+
}
|
|
123
|
+
}, []);
|
|
124
|
+
return [copied, copy];
|
|
125
|
+
}
|
|
98
126
|
function StatusTag({ running }) {
|
|
99
127
|
return React.createElement("span", {
|
|
100
128
|
style: {
|
|
@@ -589,6 +617,7 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
589
617
|
function VersionBanner({ rpcCall }) {
|
|
590
618
|
const [info, setInfo] = React.useState(null);
|
|
591
619
|
const [loading, setLoading] = React.useState(false);
|
|
620
|
+
const [copied, copy] = useCopy();
|
|
592
621
|
const check = React.useCallback(async () => {
|
|
593
622
|
setLoading(true);
|
|
594
623
|
try {
|
|
@@ -604,13 +633,19 @@ function VersionBanner({ rpcCall }) {
|
|
|
604
633
|
const hasUpdate = info?.latest && info?.current && !info.error && semverGt(info.latest, info.current);
|
|
605
634
|
const links = React.createElement(
|
|
606
635
|
"div",
|
|
607
|
-
{ style: { display: "flex", gap: 12, alignItems: "center" } },
|
|
636
|
+
{ style: { display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" } },
|
|
608
637
|
React.createElement("a", {
|
|
609
638
|
href: GITHUB_URL,
|
|
610
639
|
target: "_blank",
|
|
611
640
|
rel: "noreferrer",
|
|
612
641
|
style: s.btnLink
|
|
613
642
|
}, "\u2B50 GitHub"),
|
|
643
|
+
React.createElement("a", {
|
|
644
|
+
href: RELEASES_URL,
|
|
645
|
+
target: "_blank",
|
|
646
|
+
rel: "noreferrer",
|
|
647
|
+
style: s.btnLink
|
|
648
|
+
}, "\u{1F4CB} \u66F4\u65B0\u65E5\u5FD7"),
|
|
614
649
|
React.createElement("a", {
|
|
615
650
|
href: ISSUES_URL,
|
|
616
651
|
target: "_blank",
|
|
@@ -639,23 +674,36 @@ function VersionBanner({ rpcCall }) {
|
|
|
639
674
|
React.createElement("span", { style: { fontSize: 20 } }, "\u{1F389}"),
|
|
640
675
|
React.createElement(
|
|
641
676
|
"div",
|
|
642
|
-
{ style: { flex: 1 } },
|
|
677
|
+
{ style: { flex: 1, minWidth: 0 } },
|
|
643
678
|
React.createElement("div", {
|
|
644
679
|
style: {
|
|
645
680
|
fontSize: 13,
|
|
646
681
|
fontWeight: 600,
|
|
647
682
|
color: "var(--dsw-alias-state-info-primary,#1e40af)",
|
|
648
|
-
marginBottom:
|
|
683
|
+
marginBottom: 6
|
|
649
684
|
}
|
|
650
685
|
}, `\u53D1\u73B0\u65B0\u7248\u672C v${info.latest}\uFF08\u5F53\u524D v${info.current}\uFF09`),
|
|
651
|
-
React.createElement(
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
686
|
+
React.createElement(
|
|
687
|
+
"div",
|
|
688
|
+
{
|
|
689
|
+
style: { display: "flex", alignItems: "center", gap: 8 }
|
|
690
|
+
},
|
|
691
|
+
React.createElement("code", {
|
|
692
|
+
style: {
|
|
693
|
+
...s.code,
|
|
694
|
+
fontSize: 11,
|
|
695
|
+
color: "var(--dsw-alias-label-secondary,#6b7280)",
|
|
696
|
+
flex: 1,
|
|
697
|
+
minWidth: 0,
|
|
698
|
+
wordBreak: "break-all"
|
|
699
|
+
}
|
|
700
|
+
}, UPGRADE_COMMAND),
|
|
701
|
+
React.createElement("button", {
|
|
702
|
+
style: { ...s.btnGhost, height: 26, padding: "0 10px", fontSize: 12, flexShrink: 0 },
|
|
703
|
+
onClick: () => copy(UPGRADE_COMMAND),
|
|
704
|
+
title: "\u590D\u5236\u5347\u7EA7\u547D\u4EE4"
|
|
705
|
+
}, copied ? "\u2713 \u5DF2\u590D\u5236" : "\u590D\u5236")
|
|
706
|
+
)
|
|
659
707
|
),
|
|
660
708
|
React.createElement("button", {
|
|
661
709
|
style: {
|
package/client/index.js
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
import { BRIDGE_RPC_CHANNEL, BRIDGE_ENDPOINTS } from '../lib/bridge-rpc-constants.js';
|
|
4
4
|
|
|
5
5
|
const GITHUB_URL = 'https://github.com/wenbin-wb/dsh-bridge';
|
|
6
|
+
const RELEASES_URL = 'https://github.com/wenbin-wb/dsh-bridge/releases';
|
|
6
7
|
const ISSUES_URL = 'https://github.com/wenbin-wb/dsh-bridge/issues/new';
|
|
7
8
|
const TUNNEL_DOCS_URL = 'https://github.com/wenbin-wb/dsh-bridge/blob/main/docs/custom-tunnel.md';
|
|
8
9
|
|
|
10
|
+
// 升级命令:用 add @latest 强制安装最新版(update --latest 受已安装依赖版本约束可能无法升级到最新版)
|
|
11
|
+
const UPGRADE_COMMAND = 'dsh plugin --profile web add @wenbin_wb/dsh-bridge@latest';
|
|
12
|
+
|
|
9
13
|
const name = 'dsh-bridge';
|
|
10
14
|
const inject = ['slots', 'connection'];
|
|
11
15
|
|
|
@@ -43,6 +47,35 @@ const s = {
|
|
|
43
47
|
|
|
44
48
|
// ---- 子组件 ----
|
|
45
49
|
|
|
50
|
+
// 通用复制 hook:返回 [copied, copy],copy(text) 复制文本并短暂显示成功状态
|
|
51
|
+
function useCopy() {
|
|
52
|
+
const [copied, setCopied] = React.useState(false);
|
|
53
|
+
const copy = React.useCallback((text) => {
|
|
54
|
+
const done = () => {
|
|
55
|
+
setCopied(true);
|
|
56
|
+
setTimeout(() => setCopied(false), 2000);
|
|
57
|
+
};
|
|
58
|
+
if (navigator.clipboard?.writeText) {
|
|
59
|
+
navigator.clipboard.writeText(text).then(done).catch(() => fallbackCopy());
|
|
60
|
+
} else {
|
|
61
|
+
fallbackCopy();
|
|
62
|
+
}
|
|
63
|
+
// 降级方案:使用 document.execCommand (HTTP 环境下 Clipboard API 不可用)
|
|
64
|
+
function fallbackCopy() {
|
|
65
|
+
const textarea = document.createElement('textarea');
|
|
66
|
+
textarea.value = text;
|
|
67
|
+
textarea.style.position = 'fixed';
|
|
68
|
+
textarea.style.opacity = '0';
|
|
69
|
+
document.body.appendChild(textarea);
|
|
70
|
+
textarea.select();
|
|
71
|
+
const success = document.execCommand('copy');
|
|
72
|
+
document.body.removeChild(textarea);
|
|
73
|
+
if (success) done();
|
|
74
|
+
}
|
|
75
|
+
}, []);
|
|
76
|
+
return [copied, copy];
|
|
77
|
+
}
|
|
78
|
+
|
|
46
79
|
function StatusTag({ running }) {
|
|
47
80
|
return React.createElement('span', {
|
|
48
81
|
style: {
|
|
@@ -507,8 +540,10 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
507
540
|
}
|
|
508
541
|
|
|
509
542
|
// 版本检查 + GitHub/反馈入口
|
|
510
|
-
function VersionBanner({ rpcCall }) {
|
|
543
|
+
function VersionBanner({ rpcCall }) {
|
|
544
|
+
const [info, setInfo] = React.useState(null);
|
|
511
545
|
const [loading, setLoading] = React.useState(false);
|
|
546
|
+
const [copied, copy] = useCopy();
|
|
512
547
|
|
|
513
548
|
const check = React.useCallback(async () => {
|
|
514
549
|
setLoading(true);
|
|
@@ -525,11 +560,14 @@ function VersionBanner({ rpcCall }) { const [info, setInfo] = React.useState(nu
|
|
|
525
560
|
// 只有 npm 上的版本严格大于当前版本才算有新版本
|
|
526
561
|
const hasUpdate = info?.latest && info?.current && !info.error && semverGt(info.latest, info.current);
|
|
527
562
|
|
|
528
|
-
// 链接按钮组:GitHub + 反馈 Bug
|
|
529
|
-
const links = React.createElement('div', { style: { display: 'flex', gap: 12, alignItems: 'center' } },
|
|
563
|
+
// 链接按钮组:GitHub + 更新日志 + 反馈 Bug
|
|
564
|
+
const links = React.createElement('div', { style: { display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' } },
|
|
530
565
|
React.createElement('a', {
|
|
531
566
|
href: GITHUB_URL, target: '_blank', rel: 'noreferrer', style: s.btnLink,
|
|
532
567
|
}, '⭐ GitHub'),
|
|
568
|
+
React.createElement('a', {
|
|
569
|
+
href: RELEASES_URL, target: '_blank', rel: 'noreferrer', style: s.btnLink,
|
|
570
|
+
}, '📋 更新日志'),
|
|
533
571
|
React.createElement('a', {
|
|
534
572
|
href: ISSUES_URL, target: '_blank', rel: 'noreferrer', style: s.btnLink,
|
|
535
573
|
}, '🐛 反馈 Bug'),
|
|
@@ -549,23 +587,34 @@ function VersionBanner({ rpcCall }) { const [info, setInfo] = React.useState(nu
|
|
|
549
587
|
},
|
|
550
588
|
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 12 } },
|
|
551
589
|
React.createElement('span', { style: { fontSize: 20 } }, '🎉'),
|
|
552
|
-
React.createElement('div', { style: { flex: 1 } },
|
|
590
|
+
React.createElement('div', { style: { flex: 1, minWidth: 0 } },
|
|
553
591
|
React.createElement('div', {
|
|
554
592
|
style: {
|
|
555
593
|
fontSize: 13,
|
|
556
594
|
fontWeight: 600,
|
|
557
595
|
color: 'var(--dsw-alias-state-info-primary,#1e40af)',
|
|
558
|
-
marginBottom:
|
|
596
|
+
marginBottom: 6,
|
|
559
597
|
},
|
|
560
598
|
}, `发现新版本 v${info.latest}(当前 v${info.current})`),
|
|
561
|
-
React.createElement('
|
|
562
|
-
style: {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
599
|
+
React.createElement('div', {
|
|
600
|
+
style: { display: 'flex', alignItems: 'center', gap: 8 },
|
|
601
|
+
},
|
|
602
|
+
React.createElement('code', {
|
|
603
|
+
style: {
|
|
604
|
+
...s.code,
|
|
605
|
+
fontSize: 11,
|
|
606
|
+
color: 'var(--dsw-alias-label-secondary,#6b7280)',
|
|
607
|
+
flex: 1,
|
|
608
|
+
minWidth: 0,
|
|
609
|
+
wordBreak: 'break-all',
|
|
610
|
+
},
|
|
611
|
+
}, UPGRADE_COMMAND),
|
|
612
|
+
React.createElement('button', {
|
|
613
|
+
style: { ...s.btnGhost, height: 26, padding: '0 10px', fontSize: 12, flexShrink: 0 },
|
|
614
|
+
onClick: () => copy(UPGRADE_COMMAND),
|
|
615
|
+
title: '复制升级命令',
|
|
616
|
+
}, copied ? '✓ 已复制' : '复制'),
|
|
617
|
+
),
|
|
569
618
|
),
|
|
570
619
|
React.createElement('button', {
|
|
571
620
|
style: {
|
package/package.json
CHANGED