bridge-update-server 1.0.0 → 1.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.
@@ -20,20 +20,30 @@ if (args.includes('--help') || args.includes('-h')) {
20
20
  '用法: bridge-updater [options]',
21
21
  '',
22
22
  '选项:',
23
- ' --port <number> HTTP 端口 (默认: 51145)',
24
- ' --mdns-host <string> mDNS 广播的 host 覆盖值',
25
- ' --mdns-port <number> mDNS 广播的 port 覆盖值',
26
- ' --mdns-path <string> API 路径前缀 (默认: "")',
27
- ' --help, -h 显示帮助信息',
23
+ ' --port <number> HTTP 端口 (默认: 51145)',
24
+ ' --svr-proto <string> 服务对外的协议 (如 https)',
25
+ ' --svr-host <string> 服务对外的域名或IP',
26
+ ' --svr-port <number> 服务对外的端口',
27
+ ' --svr-path <string> 服务对外的路径前缀',
28
+ ' --help, -h 显示帮助信息',
28
29
  ''
29
30
  ].join('\n'));
30
31
  process.exit(0);
31
32
  }
32
33
 
33
34
  const port = parseInt(getArg('--port', '51145'), 10);
34
- const mdnsHost = getArg('--mdns-host', '') || '';
35
- const mdnsPort = parseInt(getArg('--mdns-port', '0'), 10) || 0;
36
- const mdnsPath = (getArg('--mdns-path', '') || '').replace(/^\/+/, '').replace(/\/+$/, '');
37
- const normalizedPath = mdnsPath ? '/' + mdnsPath : '';
35
+ const svrProto = getArg('--svr-proto', '') || '';
36
+ const svrHost = getArg('--svr-host', '') || '';
37
+ const svrPort = parseInt(getArg('--svr-port', '0'), 10) || 0;
38
+ const svrPath = (getArg('--svr-path', '') || '').replace(/^\/+/, '').replace(/\/+$/, '');
39
+ const normalizedSvrPath = svrPath ? '/' + svrPath : '';
38
40
 
39
- startServer({port, mdnsHost, mdnsPort, mdnsPath: normalizedPath});
41
+ startServer({
42
+ port,
43
+ svrOptions: {
44
+ proto: svrProto,
45
+ host: svrHost,
46
+ port: svrPort,
47
+ path: normalizedSvrPath
48
+ }
49
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bridge-update-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Bridge App Update Server",
5
5
  "type": "module",
6
6
  "bin": {
package/public/index.html CHANGED
@@ -98,7 +98,7 @@
98
98
  <span class="status" id="status-text">正在获取版本信息…</span>
99
99
  </div>
100
100
  <div id="buttons" style="display: none;">
101
- <a id="btn-cache" class="btn btn-cache">本地下载</a>
101
+ <a id="btn-cache" class="btn btn-cache" target="_blank" rel="noopener">本地下载</a>
102
102
  <a id="btn-github" class="btn btn-github" target="_blank" rel="noopener">GitHub 下载</a>
103
103
  </div>
104
104
  <div id="sha256"></div>
@@ -124,7 +124,7 @@
124
124
  const btnGithub = document.getElementById('btn-github');
125
125
 
126
126
  if (downUrl.local) {
127
- btnCache.href = base + 'download';
127
+ btnCache.href = downUrl.local;
128
128
  } else {
129
129
  btnCache.removeAttribute('href');
130
130
  btnCache.classList.add('btn-disabled');
package/src/cache.js CHANGED
@@ -17,11 +17,6 @@ export function getCachedApkPath() {
17
17
  return existsSync(filePath) ? filePath : null;
18
18
  }
19
19
 
20
- // 是否已有APK缓存
21
- export function hasCachedApk() {
22
- return getCachedApkPath() !== null;
23
- }
24
-
25
20
  // 获取APK文件流
26
21
  export function getCachedApkStream() {
27
22
  const filePath = getCachedApkPath();
@@ -51,17 +46,6 @@ function computeSha256(filePath) {
51
46
  });
52
47
  }
53
48
 
54
- // 验证本地缓存文件的SHA256是否匹配
55
- export async function verifyCachedApk() {
56
- const info = getVersionInfo();
57
- const filePath = getCachedApkPath();
58
- if (!filePath || !info?.sha256) {
59
- return false;
60
- }
61
- const actual = await computeSha256(filePath);
62
- return actual === info.sha256;
63
- }
64
-
65
49
  async function downloadFromUrl(url, destPath) {
66
50
  const res = await fetch(url, {
67
51
  headers: {'User-Agent': 'bridge-update-server'}
@@ -151,7 +135,9 @@ export async function triggerRebuild(discoverPeers) {
151
135
  // 确保APK缓存可用。返回true表示已就绪,false表示正在同步中
152
136
  export async function syncApk(discoverPeers) {
153
137
  const info = getVersionInfo();
154
- if (!info || downloading) return false;
138
+ if (!info || downloading) {
139
+ return false;
140
+ }
155
141
 
156
142
  const filePath = getCachedApkPath();
157
143
  if (!filePath) {
package/src/mdns.js CHANGED
@@ -11,19 +11,19 @@ let publishedService = null;
11
11
  const instanceId = randomUUID();
12
12
 
13
13
  // 启动mDNS广播
14
- export async function startMdns(port, mdnsHost, mdnsPort, mdnsPath) {
14
+ export async function startMdns(port, svrOptions = {}) {
15
15
  bonjourInstance = new Bonjour();
16
16
  ciaoResponder = ciao.getResponder();
17
17
 
18
18
  const txt = {instance: instanceId};
19
- if (mdnsPath) {
20
- txt.path = mdnsPath;
19
+ if (svrOptions.path) {
20
+ txt.path = svrOptions.path;
21
21
  }
22
- if (mdnsHost) {
23
- txt.host = mdnsHost;
22
+ if (svrOptions.host) {
23
+ txt.host = svrOptions.host;
24
24
  }
25
- if (mdnsPort) {
26
- txt.port = String(mdnsPort);
25
+ if (svrOptions.port) {
26
+ txt.port = String(svrOptions.port);
27
27
  }
28
28
 
29
29
  publishedService = ciaoResponder.createService({
package/src/router.js CHANGED
@@ -2,17 +2,22 @@ import {fileURLToPath} from 'node:url';
2
2
  import {dirname, join} from 'node:path';
3
3
  import express, {Router} from 'express';
4
4
  import {getVersionInfo} from './github.js';
5
- import {getCachedApkSize, getCachedApkStream, hasCachedApk, syncApk} from './cache.js';
5
+ import {getCachedApkSize, getCachedApkStream, syncApk} from './cache.js';
6
6
 
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
 
9
9
  // 创建REST API路由
10
- export function createRouter(mdnsPath, discoverPeers) {
10
+ export function createRouter(discoverPeers, svrOptions = {}, serverPort = 0) {
11
11
  const router = Router();
12
12
 
13
13
  // 静态文件
14
14
  router.use(express.static(join(__dirname, '../public')));
15
15
 
16
+ // 连通性探测
17
+ router.get('/hello', (req, res) => {
18
+ res.send('hello');
19
+ });
20
+
16
21
  // 获取最新版本信息
17
22
  router.get('/version', (req, res) => {
18
23
  const info = getVersionInfo();
@@ -23,12 +28,28 @@ export function createRouter(mdnsPath, discoverPeers) {
23
28
  });
24
29
  }
25
30
 
26
- let localUrl = null;
27
- if (hasCachedApk()) {
28
- const proto = req.get('X-Forwarded-Proto') || req.protocol || 'http';
29
- const host = req.get('X-Forwarded-Host') || req.get('Host');
30
- localUrl = `${proto}://${host}${mdnsPath}/download`;
31
- }
31
+ const proto = svrOptions.proto
32
+ || req.get('X-Forwarded-Proto')
33
+ || req.protocol
34
+ || 'http';
35
+
36
+ const fwdHost = req.get('X-Forwarded-Host') || '';
37
+ const fwdHostName = fwdHost.split(':')[0];
38
+ const fwdHostPort = fwdHost.split(':')[1] || '';
39
+ const host = svrOptions.host || fwdHostName || req.hostname;
40
+
41
+ const rawPort = svrOptions.port
42
+ || parseInt(req.get('X-Forwarded-Port') || fwdHostPort || '0', 10)
43
+ || serverPort;
44
+ const isDefaultPort = (proto === 'https' && rawPort === 443)
45
+ || (proto === 'http' && rawPort === 80);
46
+ const portStr = (!rawPort || isDefaultPort) ? '' : ':' + rawPort;
47
+
48
+ const path = svrOptions.path
49
+ || req.get('X-Forwarded-Prefix')
50
+ || '';
51
+
52
+ const localUrl = proto + '://' + host + portStr + path + '/download';
32
53
 
33
54
  res.json({
34
55
  state: true,
@@ -42,6 +63,7 @@ export function createRouter(mdnsPath, discoverPeers) {
42
63
  sha256: info.sha256
43
64
  }
44
65
  });
66
+ console.log('[Version]', '返回版本信息', 'localUrl=', localUrl, 'githubUrl=', info.apkUrl);
45
67
  });
46
68
 
47
69
  // 下载APK
package/src/server.js CHANGED
@@ -6,18 +6,14 @@ import {syncApk} from './cache.js';
6
6
  import {discoverPeers, startMdns} from './mdns.js';
7
7
 
8
8
  export async function startServer(options) {
9
- const {port, mdnsHost, mdnsPort, mdnsPath} = options;
9
+ const {port, svrOptions} = options;
10
10
 
11
11
  const app = express();
12
12
  const server = createServer(app);
13
13
 
14
14
  // 挂载路由
15
- const router = createRouter(mdnsPath, discoverPeers);
16
- if (mdnsPath) {
17
- app.use(mdnsPath, router);
18
- } else {
19
- app.use(router);
20
- }
15
+ const router = createRouter(discoverPeers, svrOptions, port);
16
+ app.use(router);
21
17
 
22
18
  // 每次轮询成功后同步APK
23
19
  onPollComplete(() => syncApk(discoverPeers));
@@ -31,7 +27,7 @@ export async function startServer(options) {
31
27
  });
32
28
 
33
29
  // 启动mDNS广播
34
- await startMdns(port, mdnsHost, mdnsPort, mdnsPath);
30
+ await startMdns(port, svrOptions);
35
31
 
36
32
  return server;
37
33
  }