@qzsy/dsh-bridge 2.18.0 → 3.0.1

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +15 -1094
  2. package/LICENSE +21 -21
  3. package/README.md +73 -476
  4. package/client/build.mjs +1 -3
  5. package/client/client.js +381 -9747
  6. package/client/index.js +242 -6828
  7. package/client/locales.mjs +99 -233
  8. package/cordis.patch.yml +5 -3
  9. package/lib/config.js +93 -0
  10. package/lib/data-dir.js +16 -0
  11. package/lib/dsh-cookie.js +111 -0
  12. package/lib/gate.js +414 -0
  13. package/lib/identity.js +23 -0
  14. package/lib/index.js +303 -3496
  15. package/lib/saas/tunnel-client.mjs +529 -467
  16. package/locale/en.json +3 -3
  17. package/locale/zh.json +3 -3
  18. package/package.json +15 -70
  19. package/README.en.md +0 -488
  20. package/client/host-families.js +0 -442
  21. package/client/mobile-styles.js +0 -1299
  22. package/client/mobile-yield.js +0 -219
  23. package/client/panel-locales.mjs +0 -777
  24. package/client/picker-yield.js +0 -77
  25. package/client/resource-url-compat.js +0 -90
  26. package/client/settings-nav-icon.js +0 -105
  27. package/client/theme-tokens.js +0 -49
  28. package/client/tunnel-guard.js +0 -46
  29. package/client/unlock-manager.js +0 -144
  30. package/lib/auth/dsh-native-cookie.js +0 -148
  31. package/lib/auth/login-template.js +0 -516
  32. package/lib/auth/manager.js +0 -596
  33. package/lib/bridge-rpc-constants.js +0 -66
  34. package/lib/bridge-rpc.js +0 -722
  35. package/lib/cloudflared-manager.mjs +0 -1277
  36. package/lib/cloudflared-network-args.js +0 -99
  37. package/lib/cloudflared-process-scan.js +0 -153
  38. package/lib/compat.js +0 -172
  39. package/lib/connection-compat.js +0 -115
  40. package/lib/feishu/comment.js +0 -50
  41. package/lib/feishu/gateway.js +0 -644
  42. package/lib/feishu/index.js +0 -432
  43. package/lib/feishu/lark-bundled.mjs +0 -131929
  44. package/lib/feishu/markdown.js +0 -148
  45. package/lib/feishu/node.js +0 -1152
  46. package/lib/feishu/slash-commands.js +0 -255
  47. package/lib/platform/account-ops.js +0 -248
  48. package/lib/platform/activity.js +0 -169
  49. package/lib/platform/ask-user.js +0 -293
  50. package/lib/platform/base.js +0 -147
  51. package/lib/platform/changes-digest.js +0 -93
  52. package/lib/platform/commands.js +0 -267
  53. package/lib/platform/config-restore.js +0 -78
  54. package/lib/platform/conversation-bridge.js +0 -1544
  55. package/lib/platform/dsh-storage.js +0 -222
  56. package/lib/platform/index.js +0 -10
  57. package/lib/platform/instances.js +0 -458
  58. package/lib/platform/manager.js +0 -130
  59. package/lib/platform/message-split.js +0 -229
  60. package/lib/platform/session-catalog.js +0 -405
  61. package/lib/platform/session-config.js +0 -52
  62. package/lib/platform/stream-slices.js +0 -21
  63. package/lib/qq/gateway.js +0 -1107
  64. package/lib/qq/index.js +0 -561
  65. package/lib/qq/node.js +0 -1153
  66. package/lib/qq/qqbot-bundled.mjs +0 -8273
  67. package/lib/restart-helper.mjs +0 -133
  68. package/lib/security/log-sanitize.js +0 -50
  69. package/lib/security/path-validator.js +0 -195
  70. package/lib/security/rate-limiter.js +0 -93
  71. package/lib/session-strip.js +0 -100
  72. package/lib/sse-keepalive.js +0 -115
  73. package/lib/telegram/gateway.js +0 -643
  74. package/lib/telegram/index.js +0 -255
  75. package/lib/telegram/node.js +0 -410
  76. package/lib/tunnel-client.mjs +0 -537
  77. package/lib/wechat/gateway.js +0 -1000
  78. package/lib/wechat/index.js +0 -282
  79. package/lib/wechat/media.js +0 -302
  80. package/lib/wechat/node.js +0 -360
  81. package/llms.txt +0 -36
@@ -1,219 +0,0 @@
1
- // dsh-bridge 移动端体验与界面改动层的「让位与开关」机制 (Issue #52)
2
- //
3
- // 背景:
4
- // dsh-bridge 为了在移动端网页访问(纯手机浏览器/局域网扫码)时提供类 App 的移动交互,
5
- // 自建了 body 级导航条(.dsh-mobile-app-header)、输入框折叠按钮以及一套含 !important
6
- // 的移动端全局覆盖样式。
7
- //
8
- // 但在以下环境,这一层自绘会引发严重冲突:
9
- // 1. Android 原生 WebView 壳(如 com.dsharnessmobile.shell),壳层自身已有原生导航栏与手势;
10
- // 2. 页面已安装专门的响应式插件(如 @dsh-android/dsh-client-ui-responsive),争抢同层 DOM;
11
- // 3. 桌面端宿主(如 Tauri 桌面端 / DSH Desktop),无需任何移动端 DOM 侵入。
12
- //
13
- // 本模块提供「多级开关 + 自动特征探测让位」:
14
- // 优先级:URL 参数 > 宿主全局注入配置 (__DSH_BRIDGE_CONFIG__) > 运行时动态配置 > 本地存储 > 自动探测兜底
15
-
16
- /** 特性名称常量 */
17
- export const FEATURES = {
18
- MOBILE_HEADER: 'mobileHeader',
19
- MOBILE_STYLES: 'mobileStyles',
20
- COMPOSER_COLLAPSE: 'composerCollapse',
21
- // 总开关:覆盖全部页面改写动作(含设置钻取/导航图标/iOS 键盘适配等残留项,见 #56)
22
- PAGE_TWEAKS: 'pageTweaks',
23
- };
24
-
25
- // 内存中的动态运行时覆盖配置(可通过 ctx.reflect.get('dsh-bridge').configureFeatures(...) 设置)
26
- let runtimeFeatureOverrides = {};
27
-
28
- /**
29
- * 设置运行时特性覆盖(供 Cordis 反射服务调用)
30
- * @param {Record<string, boolean>} overrides
31
- */
32
- export function setRuntimeFeatureOverrides(overrides) {
33
- if (overrides && typeof overrides === 'object') {
34
- runtimeFeatureOverrides = { ...runtimeFeatureOverrides, ...overrides };
35
- }
36
- }
37
-
38
- /**
39
- * 获取当前运行时特性状态
40
- * @returns {Record<string, boolean>}
41
- */
42
- export function getRuntimeFeatureOverrides() {
43
- return { ...runtimeFeatureOverrides };
44
- }
45
-
46
- /**
47
- * 重置运行时特性覆盖(主要用于测试)
48
- */
49
- export function resetRuntimeFeatureOverrides() {
50
- runtimeFeatureOverrides = {};
51
- }
52
-
53
- /**
54
- * 探测是否处于已具备自适应/原生移动顶栏的环境中
55
- * @returns {boolean}
56
- */
57
- export function detectMobileShellOrResponsivePlugin() {
58
- if (typeof window === 'undefined') return false;
59
-
60
- // 1. 移动端原生/混合壳显式标记
61
- if (window.__DSH_MOBILE_SHELL__ || window.__TAURI__ || window.__DSH_DESKTOP__) {
62
- return true;
63
- }
64
-
65
- // 2. 已加载的移动端自适应插件标记
66
- if (window.__DSH_CLIENT_UI_RESPONSIVE__) {
67
- return true;
68
- }
69
-
70
- // 2b. 第三方移动层显式登记(issue #56 §3.4:不再靠猜全局变量)。
71
- // 宿主按任一约定声明即可:window.__DSH_MOBILE_LAYER__ = '<plugin-id>'
72
- // 或在 <html>/<body> 挂 [data-dsh-mobile-layer] / [data-dsh-mobile-ui]。
73
- if (typeof window.__DSH_MOBILE_LAYER__ === 'string' && window.__DSH_MOBILE_LAYER__) {
74
- return true;
75
- }
76
-
77
- // 3. DOM 标记探测(如 @dsh-android/dsh-client-ui-responsive 挂载的特征属性,
78
- // 以及第三方层按约定挂载的 data-dsh-mobile-layer / data-dsh-mobile-ui)
79
- if (typeof document !== 'undefined') {
80
- if (document.querySelector('[data-dsh-responsive-mobile]') ||
81
- document.querySelector('[data-dsh-mobile-shell]') ||
82
- document.querySelector('[data-dsh-mobile-layer]') ||
83
- document.querySelector('[data-dsh-mobile-ui]')) {
84
- return true;
85
- }
86
- }
87
-
88
- return false;
89
- }
90
-
91
- /**
92
- * 探测页面是否已有主顶栏(避免 body 级双顶栏叠加)
93
- * @returns {boolean}
94
- */
95
- export function detectExistingHeader() {
96
- if (typeof document === 'undefined') return false;
97
- // 如果页面中已经有 #root 下的 header 或 banner 角色元素
98
- return !!document.querySelector('#root header, [role="banner"]:not(.dsh-mobile-app-header)');
99
- }
100
-
101
- /**
102
- * 解析特性开关(返回 true 表示启用,false 表示禁用/让位)
103
- *
104
- * @param {string} featureName 特性名称
105
- * @param {() => boolean} defaultDetector 自动探测兜底函数
106
- * @returns {boolean}
107
- */
108
- export function isFeatureEnabled(featureName, defaultDetector) {
109
- if (typeof window === 'undefined') {
110
- return typeof defaultDetector === 'function' ? defaultDetector() : true;
111
- }
112
-
113
- // 1. URL 应急排障参数(最高优先级,支持 ?dsh_bridge_tweaks=0 或 ?dsh_mobile=off 批量禁用)
114
- try {
115
- if (window.location && window.location.search) {
116
- const params = new URLSearchParams(window.location.search);
117
- // 总开关:禁用所有页面微调
118
- const tweaksVal = params.get('dsh_bridge_tweaks') ?? params.get('dsh_mobile_tweaks');
119
- if (tweaksVal === '0' || tweaksVal === 'false' || tweaksVal === 'off') {
120
- return false;
121
- }
122
- if (tweaksVal === '1' || tweaksVal === 'true' || tweaksVal === 'on') {
123
- return true;
124
- }
125
-
126
- // 单项开关:如 ?dsh_mobile_header=0, ?dsh_mobile_styles=0, ?dsh_composer_collapse=0
127
- const kebabName = featureName.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
128
- const specificVal = params.get(`dsh_${kebabName}`) ?? params.get(`dsh_${featureName}`);
129
- if (specificVal === '0' || specificVal === 'false' || specificVal === 'off') {
130
- return false;
131
- }
132
- if (specificVal === '1' || specificVal === 'true' || specificVal === 'on') {
133
- return true;
134
- }
135
- }
136
- } catch {}
137
-
138
- // 2. 宿主注入的全局配置对象 window.__DSH_BRIDGE_CONFIG__
139
- try {
140
- const hostConfig = window.__DSH_BRIDGE_CONFIG__;
141
- if (hostConfig && typeof hostConfig === 'object') {
142
- if (hostConfig.disablePageTweaks === true || hostConfig.disableMobileTweaks === true ||
143
- hostConfig.mobileUi === false) {
144
- return false;
145
- }
146
- if (hostConfig.mobileUi === true) {
147
- return true;
148
- }
149
- if (typeof hostConfig[featureName] === 'boolean') {
150
- return hostConfig[featureName];
151
- }
152
- }
153
- } catch {}
154
-
155
- // 3. 动态运行时配置(通过反射 API 设置)
156
- if (typeof runtimeFeatureOverrides[featureName] === 'boolean') {
157
- return runtimeFeatureOverrides[featureName];
158
- }
159
-
160
- // 4. 本地持久化偏好 (localStorage)
161
- try {
162
- if (window.localStorage) {
163
- const stored = window.localStorage.getItem(`dsh_bridge:feature:${featureName}`);
164
- if (stored === '0' || stored === 'false') return false;
165
- if (stored === '1' || stored === 'true') return true;
166
- }
167
- } catch {}
168
-
169
- // 5. 自动探测兜底
170
- if (typeof defaultDetector === 'function') {
171
- return defaultDetector();
172
- }
173
-
174
- return true;
175
- }
176
-
177
- /**
178
- * 是否应该让位自绘顶栏 (返回 true 表示让位/不自建顶栏)
179
- * @returns {boolean}
180
- */
181
- export function shouldYieldMobileHeader() {
182
- return !isFeatureEnabled(FEATURES.MOBILE_HEADER, () => {
183
- // 自动判定:如果是移动端壳层/已有自适应插件/页面已有顶栏,则主动让位
184
- return !detectMobileShellOrResponsivePlugin();
185
- });
186
- }
187
-
188
- /**
189
- * 是否应该让位移动端全局样式 (返回 true 表示让位/不注入样式)
190
- * @returns {boolean}
191
- */
192
- export function shouldYieldMobileStyles() {
193
- return !isFeatureEnabled(FEATURES.MOBILE_STYLES, () => {
194
- // 自动判定:如果已被外部响应式插件完全接管,则让位全局样式
195
- return !detectMobileShellOrResponsivePlugin();
196
- });
197
- }
198
-
199
- /**
200
- * 总开关:是否应该让位全部页面改写动作 (返回 true 表示跳过 drilldown/导航图标/
201
- * iOS 键盘适配/折叠按钮/移动体验等所有页面侧改动,见 #56 §2.2)。
202
- * 服务端 mobileUi:false 会经 head 注入的 __DSH_BRIDGE_CONFIG__ 生效,宿主也可在
203
- * 加载阶段直接声明,时机早于 apply()(包级别 opt-in,见 #56 §4)。
204
- * @returns {boolean}
205
- */
206
- export function shouldYieldAllPageTweaks() {
207
- return !isFeatureEnabled(FEATURES.PAGE_TWEAKS, () => true);
208
- }
209
-
210
- /**
211
- * 是否应该让位输入框折叠按钮 (返回 true 表示让位/不挂载折叠按钮)
212
- * @returns {boolean}
213
- */
214
- export function shouldYieldComposerCollapse() {
215
- return !isFeatureEnabled(FEATURES.COMPOSER_COLLAPSE, () => {
216
- // 自动判定:移动端壳层下输入框折叠按钮容易与原生交互冲突,让位
217
- return !detectMobileShellOrResponsivePlugin();
218
- });
219
- }