dsh-mobile 0.5.0 → 0.5.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.
- package/CHANGELOG.md +10 -0
- package/CONTRIBUTORS.md +7 -3
- package/README.en.md +31 -30
- package/README.md +35 -33
- package/SECURITY.md +2 -0
- package/THIRD_PARTY_NOTICES.md +4 -4
- package/docs/ATTACH_EXISTING_FRPS.en.md +2 -0
- package/docs/ATTACH_EXISTING_FRPS.md +4 -0
- package/docs/CLOUDFLARE_TUNNEL.en.md +15 -20
- package/docs/CLOUDFLARE_TUNNEL.md +15 -20
- package/docs/DSH_0.1.5_LAN.md +1 -1
- package/docs/README.md +2 -2
- package/docs/SELF_HOSTED_FRP.en.md +7 -10
- package/docs/SELF_HOSTED_FRP.md +7 -10
- package/docs/SELF_HOSTED_ORIGIN.en.md +1 -1
- package/docs/SELF_HOSTED_ORIGIN.md +1 -1
- package/lib/client.js +196 -25
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +2 -0
- package/lib/index.mjs +25 -6
- package/lib/index.mjs.map +1 -1
- package/lib/mobile-layout.js +22 -5
- package/lib/mobile-layout.js.map +1 -1
- package/package.json +5 -5
package/lib/index.d.mts
CHANGED
|
@@ -356,6 +356,8 @@ declare class JsonMobileAccessControlStore implements MobileAccessControlStore {
|
|
|
356
356
|
private readonly file;
|
|
357
357
|
private readonly initiallyEnabled;
|
|
358
358
|
constructor(file: string, initiallyEnabled: boolean);
|
|
359
|
+
/** Avoid writing an absent already-disabled state without changing recovery of existing files. */
|
|
360
|
+
disableIfPresent(): Promise<void>;
|
|
359
361
|
load(): Promise<MobileAccessControlState>;
|
|
360
362
|
save(state: MobileAccessControlState): Promise<void>;
|
|
361
363
|
}
|
package/lib/index.mjs
CHANGED
|
@@ -1078,6 +1078,25 @@ var JsonMobileAccessControlStore = class {
|
|
|
1078
1078
|
this.file = file;
|
|
1079
1079
|
this.initiallyEnabled = initiallyEnabled;
|
|
1080
1080
|
}
|
|
1081
|
+
/** Avoid writing an absent already-disabled state without changing recovery of existing files. */
|
|
1082
|
+
async disableIfPresent() {
|
|
1083
|
+
try {
|
|
1084
|
+
await lstat(this.file);
|
|
1085
|
+
} catch (error) {
|
|
1086
|
+
if (error.code === "ENOENT") {
|
|
1087
|
+
if (this.initiallyEnabled) await this.save({
|
|
1088
|
+
version: 1,
|
|
1089
|
+
enabled: false
|
|
1090
|
+
});
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
throw error;
|
|
1094
|
+
}
|
|
1095
|
+
await this.save({
|
|
1096
|
+
version: 1,
|
|
1097
|
+
enabled: false
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1081
1100
|
async load() {
|
|
1082
1101
|
let stat;
|
|
1083
1102
|
try {
|
|
@@ -9977,7 +9996,7 @@ function buildMobileGuide(state) {
|
|
|
9977
9996
|
const scriptLine = state.hasCustomJs ? "存在(当前生效的自定义脚本)" : "不存在(无自定义脚本)";
|
|
9978
9997
|
const extensionLines = state.extensions.length === 0 ? "(无)" : state.extensions.map((entry) => `- ${entry.id}(${entry.name} v${entry.version})`).join("\n");
|
|
9979
9998
|
const failureLine = state.failedExtensionCount > 0 ? `注意:${state.failedExtensionCount} 个扩展的电脑端 host 激活失败,如改动相关扩展请先检查其 host.mjs 与 extension.json。` : "";
|
|
9980
|
-
return `${`##
|
|
9999
|
+
return `${`## 手机端当前状态(改动前必读,避免覆盖已有定制)
|
|
9981
10000
|
|
|
9982
10001
|
- 定制目录:${state.directory}(所有改动只允许在这里进行)
|
|
9983
10002
|
- mobile.css:${styleLine}
|
|
@@ -10003,6 +10022,8 @@ const MOBILE_CUSTOMIZATION_GUIDE_BODY = `你在为用户定制 DSH Mobile 的手
|
|
|
10003
10022
|
- $DSH_HOME/mobile-access/mobile.js:手机端脚本,用 window.dshMobile.register(({ root }) => { ... }) 把内容挂载到 root,返回清理函数
|
|
10004
10023
|
- 保存后手机端几秒内自动应用,无需重启
|
|
10005
10024
|
|
|
10025
|
+
动手前先读已有的定制文件。若要调整 DSH 自带的输入框、侧栏或设置等现有界面,先确认当前 DSH 版本与手机页面模式(专用移动页面或 ?frontend=stock),只读核对运行页面的 DOM、属性和样式;本机有同版本前端源码时可参考相应组件,没有源码时可查看已安装的客户端产物,不必下载源码。优先使用扩展 API、插槽和稳定的 data-* 标记,不凭猜测依赖构建类名。只读查看不改变前述写入范围。
|
|
10026
|
+
|
|
10006
10027
|
2. 电脑端能力 —— 手机需要读电脑文件、执行命令或访问硬件时,创建扩展:
|
|
10007
10028
|
- 目录:$DSH_HOME/mobile-access/extensions/<id>/,id 用小写字母数字和连字符(如 media-remote)
|
|
10008
10029
|
- extension.json:{"schemaVersion":1,"id":"<id>","name":"显示名","version":"0.1.0","description":"说明"}
|
|
@@ -10019,6 +10040,7 @@ const MOBILE_CUSTOMIZATION_GUIDE_BODY = `你在为用户定制 DSH Mobile 的手
|
|
|
10019
10040
|
|
|
10020
10041
|
完成前请自检:
|
|
10021
10042
|
- 改动涉及 mobile.js 或扩展的 mobile.js / host.mjs 时,先做语法检查再保存(如 node --check <file>),确保没有语法错误
|
|
10043
|
+
- 改动 DSH 现有界面后尽可能在实际手机页面核对效果;无法观察运行页面时,明确告诉用户尚未实测
|
|
10022
10044
|
- 创建或修改扩展后,确认 extension.json 的 schemaVersion 为 1、id 与目录名一致、且 id 只含小写字母数字和连字符
|
|
10023
10045
|
- 扩展的 host.mjs 若在完成前无法激活,先修正而不是留下损坏的扩展
|
|
10024
10046
|
- 完成后检查自己实际写入了哪些文件,向用户简要说明改了什么、手机端会有什么变化`;
|
|
@@ -13705,7 +13727,7 @@ async function apply(ctx, config) {
|
|
|
13705
13727
|
const unregister = ctx.webServer.register(adminRoute);
|
|
13706
13728
|
const disposeMobileCommand = ctx.commands.register({
|
|
13707
13729
|
name: "mobile",
|
|
13708
|
-
description: "
|
|
13730
|
+
description: "定制手机界面或添加电脑能力",
|
|
13709
13731
|
input: { hint: "<要做什么>" },
|
|
13710
13732
|
handler: async ({ agent, rawInput }) => {
|
|
13711
13733
|
const task = rawInput.trim();
|
|
@@ -13751,10 +13773,7 @@ async function apply(ctx, config) {
|
|
|
13751
13773
|
frp: frpStore,
|
|
13752
13774
|
origin: originStore
|
|
13753
13775
|
};
|
|
13754
|
-
await Promise.all(Object.keys(stores).filter((provider) => provider !== remoteProviders.selected).map((provider) => stores[provider].
|
|
13755
|
-
version: 1,
|
|
13756
|
-
enabled: false
|
|
13757
|
-
})));
|
|
13776
|
+
await Promise.all(Object.keys(stores).filter((provider) => provider !== remoteProviders.selected).map((provider) => stores[provider].disableIfPresent()));
|
|
13758
13777
|
for (const provider of REMOTE_PROVIDERS) await remoteControllers[provider].initialize();
|
|
13759
13778
|
const lanDiscovery = lanGateway?.discoveryStatus();
|
|
13760
13779
|
if (lanDiscovery !== void 0 && !lanDiscovery.broadcast) logger.warn("broadcast discovery is unavailable (%s); mDNS is still published, so pair manually or free the UDP port", lanDiscovery.errorCode ?? "unknown_cause");
|