most-box 0.1.2 → 0.1.3
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 +18 -5
- package/electron/afterPack.cjs +87 -0
- package/electron/main.js +85 -1
- package/electron/updateChecker.js +97 -0
- package/electron/updateChecker.test.js +147 -0
- package/out/404/index.html +2 -2
- package/out/404.html +2 -2
- package/out/__next.__PAGE__.txt +4 -4
- package/out/__next._full.txt +12 -12
- package/out/__next._head.txt +3 -3
- package/out/__next._index.txt +6 -6
- package/out/__next._tree.txt +1 -1
- package/out/_next/static/chunks/04mo7rr..0_1q.js +1 -0
- package/out/_next/static/chunks/06rf3qq5ggs6v.js +1 -0
- package/out/_next/static/chunks/{0aq.rc9woa2nz.js → 0_0oph_z1az14.js} +1 -1
- package/out/_next/static/chunks/0cl7d~7abnk_p.css +1 -0
- package/out/_next/static/chunks/0d306t1wvjpdx.js +1 -0
- package/out/_next/static/chunks/{0etes81d_cihn.js → 0m_5nb6x8qy._.js} +1 -1
- package/out/_next/static/chunks/0n.ayxmsar6e5.js +1 -0
- package/out/_next/static/chunks/0olqjomda37-e.js +1 -0
- package/out/_next/static/chunks/{16xls5tt_68lx.js → 0s~g.l~x049o2.js} +1 -1
- package/out/_next/static/chunks/0voe1.ttrh84k.css +1 -0
- package/out/_next/static/chunks/0x.ky97owcxxs.js +1 -0
- package/out/_next/static/chunks/0ysj5b94vu4ri.js +1 -0
- package/out/_next/static/chunks/{0q0ksgxg98xgd.js → 17cwkb2yn_akx.js} +1 -1
- package/out/_next/static/chunks/184hxsuf-5c84.js +1 -0
- package/out/_not-found/__next._full.txt +11 -11
- package/out/_not-found/__next._head.txt +3 -3
- package/out/_not-found/__next._index.txt +6 -6
- package/out/_not-found/__next._not-found.__PAGE__.txt +4 -4
- package/out/_not-found/__next._not-found.txt +3 -3
- package/out/_not-found/__next._tree.txt +1 -1
- package/out/_not-found/index.html +2 -2
- package/out/_not-found/index.txt +11 -11
- package/out/admin/__next._full.txt +12 -12
- package/out/admin/__next._head.txt +3 -3
- package/out/admin/__next._index.txt +6 -6
- package/out/admin/__next._tree.txt +1 -1
- package/out/admin/__next.admin.__PAGE__.txt +4 -4
- package/out/admin/__next.admin.txt +3 -3
- package/out/admin/index.html +2 -2
- package/out/admin/index.txt +12 -12
- package/out/app/__next._full.txt +12 -12
- package/out/app/__next._head.txt +3 -3
- package/out/app/__next._index.txt +6 -6
- package/out/app/__next._tree.txt +1 -1
- package/out/app/__next.app.__PAGE__.txt +4 -4
- package/out/app/__next.app.txt +3 -3
- package/out/app/index.html +2 -2
- package/out/app/index.txt +12 -12
- package/out/chat/__next._full.txt +12 -12
- package/out/chat/__next._head.txt +3 -3
- package/out/chat/__next._index.txt +6 -6
- package/out/chat/__next._tree.txt +1 -1
- package/out/chat/__next.chat.__PAGE__.txt +4 -4
- package/out/chat/__next.chat.txt +3 -3
- package/out/chat/index.html +2 -2
- package/out/chat/index.txt +12 -12
- package/out/chat/join/__next._full.txt +12 -12
- package/out/chat/join/__next._head.txt +3 -3
- package/out/chat/join/__next._index.txt +6 -6
- package/out/chat/join/__next._tree.txt +1 -1
- package/out/chat/join/__next.chat.join.__PAGE__.txt +4 -4
- package/out/chat/join/__next.chat.join.txt +3 -3
- package/out/chat/join/__next.chat.txt +3 -3
- package/out/chat/join/index.html +2 -2
- package/out/chat/join/index.txt +12 -12
- package/out/download/__next._full.txt +34 -30
- package/out/download/__next._head.txt +3 -3
- package/out/download/__next._index.txt +6 -6
- package/out/download/__next._tree.txt +2 -2
- package/out/download/__next.download.__PAGE__.txt +8 -13
- package/out/download/__next.download.txt +3 -3
- package/out/download/index.html +2 -2
- package/out/download/index.txt +34 -30
- package/out/favicon.ico +0 -0
- package/out/gandengyan/__next._full.txt +25 -0
- package/out/gandengyan/__next._head.txt +5 -0
- package/out/gandengyan/__next._index.txt +9 -0
- package/out/gandengyan/__next._tree.txt +5 -0
- package/out/gandengyan/__next.gandengyan.__PAGE__.txt +10 -0
- package/out/gandengyan/__next.gandengyan.txt +5 -0
- package/out/gandengyan/index.html +15 -0
- package/out/gandengyan/index.txt +25 -0
- package/out/index.html +2 -2
- package/out/index.txt +12 -12
- package/out/note/__next._full.txt +12 -12
- package/out/note/__next._head.txt +3 -3
- package/out/note/__next._index.txt +6 -6
- package/out/note/__next._tree.txt +1 -1
- package/out/note/__next.note.__PAGE__.txt +4 -4
- package/out/note/__next.note.txt +3 -3
- package/out/note/index.html +2 -2
- package/out/note/index.txt +12 -12
- package/out/ping/__next._full.txt +12 -12
- package/out/ping/__next._head.txt +3 -3
- package/out/ping/__next._index.txt +6 -6
- package/out/ping/__next._tree.txt +1 -1
- package/out/ping/__next.ping.__PAGE__.txt +4 -4
- package/out/ping/__next.ping.txt +3 -3
- package/out/ping/index.html +2 -2
- package/out/ping/index.txt +12 -12
- package/out/web3/__next._full.txt +12 -12
- package/out/web3/__next._head.txt +3 -3
- package/out/web3/__next._index.txt +6 -6
- package/out/web3/__next._tree.txt +1 -1
- package/out/web3/__next.web3.__PAGE__.txt +4 -4
- package/out/web3/__next.web3.txt +3 -3
- package/out/web3/ed25519/__next._full.txt +10 -10
- package/out/web3/ed25519/__next._head.txt +3 -3
- package/out/web3/ed25519/__next._index.txt +6 -6
- package/out/web3/ed25519/__next._tree.txt +1 -1
- package/out/web3/ed25519/__next.web3.ed25519.__PAGE__.txt +2 -2
- package/out/web3/ed25519/__next.web3.ed25519.txt +3 -3
- package/out/web3/ed25519/__next.web3.txt +3 -3
- package/out/web3/ed25519/index.html +1 -1
- package/out/web3/ed25519/index.txt +10 -10
- package/out/web3/index.html +2 -2
- package/out/web3/index.txt +12 -12
- package/out/web3/tools/__next._full.txt +10 -10
- package/out/web3/tools/__next._head.txt +3 -3
- package/out/web3/tools/__next._index.txt +6 -6
- package/out/web3/tools/__next._tree.txt +1 -1
- package/out/web3/tools/__next.web3.tools.__PAGE__.txt +2 -2
- package/out/web3/tools/__next.web3.tools.txt +3 -3
- package/out/web3/tools/__next.web3.txt +3 -3
- package/out/web3/tools/index.html +1 -1
- package/out/web3/tools/index.txt +10 -10
- package/package.json +28 -29
- package/public/favicon.ico +0 -0
- package/server/index.js +8 -0
- package/server/src/games/gandengyan.js +675 -0
- package/server/src/http/access.js +4 -0
- package/server/src/http/app.js +7 -0
- package/server/src/utils/api.js +19 -1
- package/out/_next/static/chunks/0.e2avjgna_b2.js +0 -1
- package/out/_next/static/chunks/03h~nhgj0hv3p.css +0 -1
- package/out/_next/static/chunks/0gwian.hp3-92.js +0 -1
- package/out/_next/static/chunks/0l5_.uqb-uqb8.js +0 -1
- package/out/_next/static/chunks/0mex8svsiv-2l.js +0 -1
- package/out/_next/static/chunks/0myq9gs8szydh.js +0 -1
- package/out/_next/static/chunks/0p0sv~fuddvgr.js +0 -1
- /package/out/_next/static/{t7ZIeQpVvjz4a7-5Tt-VK → aPEZ4zaaR5W3WpSZ0dFsa}/_buildManifest.js +0 -0
- /package/out/_next/static/{t7ZIeQpVvjz4a7-5Tt-VK → aPEZ4zaaR5W3WpSZ0dFsa}/_clientMiddlewareManifest.js +0 -0
- /package/out/_next/static/{t7ZIeQpVvjz4a7-5Tt-VK → aPEZ4zaaR5W3WpSZ0dFsa}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -206,19 +206,32 @@ git push origin v0.0.7
|
|
|
206
206
|
触发后自动执行:
|
|
207
207
|
|
|
208
208
|
1. **npm 包发布** — 发布 `most-box` 到 npm registry
|
|
209
|
-
2. **Windows 打包** —
|
|
209
|
+
2. **Windows 打包** — 分别构建 `.exe` 安装包(x64 / arm64)并上传 Release
|
|
210
210
|
3. **macOS 打包** — 构建 `.dmg` 安装包(x64 + arm64)并上传 Release
|
|
211
211
|
4. **Linux 打包** — 构建 `.AppImage` 安装包(x64 + arm64)并上传 Release
|
|
212
|
+
5. **下载镜像** — 将 Release 资产同步到 Cloudflare R2,并生成 `releases/latest.json`
|
|
212
213
|
|
|
213
|
-
|
|
214
|
+
GitHub Release 是可信备用源;下载页优先读取 R2 的 `releases/latest.json` 并使用 R2 下载链接。
|
|
214
215
|
|
|
215
216
|
### 配置 Secrets
|
|
216
217
|
|
|
218
|
+
R2 发布资产使用独立公开桶,默认 bucket 为 `most-box-releases`,默认公开域名为
|
|
219
|
+
`https://download.most.box`。不要复用 `api.most.box` 项目的 `most-box-backup` 备份桶。
|
|
220
|
+
|
|
217
221
|
在仓库 Settings → Secrets and variables → Actions 中添加:
|
|
218
222
|
|
|
219
|
-
| Secret
|
|
220
|
-
|
|
|
221
|
-
| `NPM_TOKEN`
|
|
223
|
+
| Secret | 说明 |
|
|
224
|
+
| ---------------------- | --------------------------------------- |
|
|
225
|
+
| `NPM_TOKEN` | npm 发布令牌(`npm token create` 生成) |
|
|
226
|
+
| `R2_ACCOUNT_ID` | Cloudflare 账户 ID |
|
|
227
|
+
| `R2_ACCESS_KEY_ID` | R2 S3 API Access Key ID |
|
|
228
|
+
| `R2_SECRET_ACCESS_KEY` | R2 S3 API Secret Access Key |
|
|
229
|
+
| `R2_BUCKET` | 可选;默认 `most-box-releases` |
|
|
230
|
+
| `R2_PUBLIC_BASE_URL` | 可选;默认 `https://download.most.box` |
|
|
231
|
+
|
|
232
|
+
下载页默认读取 `https://download.most.box/releases/latest.json`。部署环境可额外配置
|
|
233
|
+
`NEXT_PUBLIC_R2_PUBLIC_BASE_URL` 覆盖公开域名,或直接配置
|
|
234
|
+
`NEXT_PUBLIC_RELEASE_MANIFEST_URL` 指向指定的 `latest.json`。
|
|
222
235
|
|
|
223
236
|
## 社区
|
|
224
237
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const fs = require('node:fs')
|
|
2
|
+
const path = require('node:path')
|
|
3
|
+
|
|
4
|
+
const ARCH_BY_VALUE = new Map([
|
|
5
|
+
[0, 'ia32'],
|
|
6
|
+
[1, 'x64'],
|
|
7
|
+
[2, 'armv7l'],
|
|
8
|
+
[3, 'arm64'],
|
|
9
|
+
[4, 'universal'],
|
|
10
|
+
])
|
|
11
|
+
|
|
12
|
+
function normalizeArch(arch) {
|
|
13
|
+
if (typeof arch === 'string') return arch
|
|
14
|
+
if (typeof arch === 'number') return ARCH_BY_VALUE.get(arch) || String(arch)
|
|
15
|
+
return String(arch || '')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function findPrebuildDirs(root) {
|
|
19
|
+
const matches = []
|
|
20
|
+
const stack = [root]
|
|
21
|
+
|
|
22
|
+
while (stack.length > 0) {
|
|
23
|
+
const dir = stack.pop()
|
|
24
|
+
let entries
|
|
25
|
+
try {
|
|
26
|
+
entries = fs.readdirSync(dir, { withFileTypes: true })
|
|
27
|
+
} catch {
|
|
28
|
+
continue
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (!entry.isDirectory()) continue
|
|
33
|
+
|
|
34
|
+
const fullPath = path.join(dir, entry.name)
|
|
35
|
+
if (entry.name === 'prebuilds') {
|
|
36
|
+
matches.push(fullPath)
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
stack.push(fullPath)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return matches
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function shouldKeepPrebuild(name, target) {
|
|
47
|
+
return (
|
|
48
|
+
name === target ||
|
|
49
|
+
name.startsWith(`${target}-`) ||
|
|
50
|
+
name.startsWith(`${target}+`)
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = async function afterPack(context) {
|
|
55
|
+
const platform = context.electronPlatformName
|
|
56
|
+
const arch = normalizeArch(context.arch)
|
|
57
|
+
const target = `${platform}-${arch}`
|
|
58
|
+
const nodeModulesDir = path.join(
|
|
59
|
+
context.appOutDir,
|
|
60
|
+
'resources',
|
|
61
|
+
'app.asar.unpacked',
|
|
62
|
+
'node_modules'
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if (!platform || !arch || arch === 'universal' || !fs.existsSync(nodeModulesDir)) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let removed = 0
|
|
70
|
+
for (const prebuildDir of findPrebuildDirs(nodeModulesDir)) {
|
|
71
|
+
const entries = fs.readdirSync(prebuildDir, { withFileTypes: true })
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (!entry.isDirectory()) continue
|
|
74
|
+
if (shouldKeepPrebuild(entry.name, target)) continue
|
|
75
|
+
|
|
76
|
+
fs.rmSync(path.join(prebuildDir, entry.name), {
|
|
77
|
+
force: true,
|
|
78
|
+
recursive: true,
|
|
79
|
+
})
|
|
80
|
+
removed += 1
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (removed > 0) {
|
|
85
|
+
console.log(`[MostBox] Pruned ${removed} native prebuild directories for ${target}`)
|
|
86
|
+
}
|
|
87
|
+
}
|
package/electron/main.js
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
app,
|
|
3
|
+
BrowserWindow,
|
|
4
|
+
Menu,
|
|
5
|
+
Tray,
|
|
6
|
+
dialog,
|
|
7
|
+
nativeImage,
|
|
8
|
+
shell,
|
|
9
|
+
} from 'electron'
|
|
2
10
|
import fs from 'node:fs'
|
|
3
11
|
import path from 'node:path'
|
|
4
12
|
import { fileURLToPath } from 'node:url'
|
|
5
13
|
|
|
14
|
+
import {
|
|
15
|
+
formatBytes,
|
|
16
|
+
getAvailableUpdate,
|
|
17
|
+
getCurrentArch,
|
|
18
|
+
getCurrentPlatform,
|
|
19
|
+
getReleaseManifestUrl,
|
|
20
|
+
} from './updateChecker.js'
|
|
21
|
+
|
|
6
22
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
7
23
|
const PORT = 1976
|
|
8
24
|
|
|
@@ -10,6 +26,7 @@ let mainWindow = null
|
|
|
10
26
|
let engine = null
|
|
11
27
|
let tray = null
|
|
12
28
|
let isQuitting = false
|
|
29
|
+
let hasCheckedForUpdates = false
|
|
13
30
|
|
|
14
31
|
function getTrayIconPath() {
|
|
15
32
|
const candidates = [
|
|
@@ -102,12 +119,79 @@ async function startServer() {
|
|
|
102
119
|
engine = await main()
|
|
103
120
|
}
|
|
104
121
|
|
|
122
|
+
async function fetchReleaseManifest(manifestUrl) {
|
|
123
|
+
const controller = new AbortController()
|
|
124
|
+
const timeout = setTimeout(() => controller.abort(), 8000)
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const response = await fetch(manifestUrl, {
|
|
128
|
+
cache: 'no-store',
|
|
129
|
+
signal: controller.signal,
|
|
130
|
+
})
|
|
131
|
+
if (!response.ok) return null
|
|
132
|
+
return await response.json()
|
|
133
|
+
} finally {
|
|
134
|
+
clearTimeout(timeout)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function checkForUpdates() {
|
|
139
|
+
if (hasCheckedForUpdates) return
|
|
140
|
+
hasCheckedForUpdates = true
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
const platform = getCurrentPlatform()
|
|
144
|
+
const arch = getCurrentArch()
|
|
145
|
+
if (!platform || !arch) return
|
|
146
|
+
|
|
147
|
+
const manifest = await fetchReleaseManifest(getReleaseManifestUrl())
|
|
148
|
+
const update = getAvailableUpdate(manifest, {
|
|
149
|
+
currentVersion: app.getVersion(),
|
|
150
|
+
platform,
|
|
151
|
+
arch,
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
if (!update) return
|
|
155
|
+
|
|
156
|
+
const sizeText = formatBytes(update.asset.size)
|
|
157
|
+
const detail = [
|
|
158
|
+
`当前版本:${app.getVersion()}`,
|
|
159
|
+
`最新版本:${update.version}`,
|
|
160
|
+
sizeText ? `安装包大小:${sizeText}` : null,
|
|
161
|
+
'',
|
|
162
|
+
'是否现在打开浏览器下载更新?',
|
|
163
|
+
]
|
|
164
|
+
.filter(line => line !== null)
|
|
165
|
+
.join('\n')
|
|
166
|
+
|
|
167
|
+
const result = await dialog.showMessageBox(mainWindow, {
|
|
168
|
+
type: 'info',
|
|
169
|
+
buttons: ['立即下载', '稍后'],
|
|
170
|
+
defaultId: 0,
|
|
171
|
+
cancelId: 1,
|
|
172
|
+
title: '发现 MostBox 新版本',
|
|
173
|
+
message: `MostBox ${update.version} 已可下载`,
|
|
174
|
+
detail,
|
|
175
|
+
noLink: true,
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
if (result.response === 0) {
|
|
179
|
+
await shell.openExternal(update.downloadUrl)
|
|
180
|
+
}
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.warn('[Electron] Update check skipped:', error)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
105
186
|
app.whenReady().then(async () => {
|
|
106
187
|
try {
|
|
107
188
|
await startServer()
|
|
108
189
|
createWindow()
|
|
109
190
|
createTray()
|
|
110
191
|
Menu.setApplicationMenu(null)
|
|
192
|
+
setTimeout(() => {
|
|
193
|
+
checkForUpdates()
|
|
194
|
+
}, 3000)
|
|
111
195
|
|
|
112
196
|
app.on('activate', () => {
|
|
113
197
|
showMainWindow()
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export const DEFAULT_RELEASE_MANIFEST_URL =
|
|
2
|
+
'https://download.most.box/releases/latest.json'
|
|
3
|
+
|
|
4
|
+
const PLATFORM_BY_PROCESS = {
|
|
5
|
+
darwin: 'macos',
|
|
6
|
+
linux: 'linux',
|
|
7
|
+
win32: 'windows',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getReleaseManifestUrl(env = process.env) {
|
|
11
|
+
return env.MOSTBOX_RELEASE_MANIFEST_URL || DEFAULT_RELEASE_MANIFEST_URL
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getCurrentPlatform(processPlatform = process.platform) {
|
|
15
|
+
return PLATFORM_BY_PROCESS[processPlatform] || null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getCurrentArch(processArch = process.arch) {
|
|
19
|
+
if (processArch === 'x64' || processArch === 'arm64') return processArch
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseVersion(version) {
|
|
24
|
+
if (typeof version !== 'string') return null
|
|
25
|
+
|
|
26
|
+
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/)
|
|
27
|
+
if (!match) return null
|
|
28
|
+
|
|
29
|
+
return match.slice(1).map(part => Number(part))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isNewerVersion(candidateVersion, currentVersion) {
|
|
33
|
+
const candidate = parseVersion(candidateVersion)
|
|
34
|
+
const current = parseVersion(currentVersion)
|
|
35
|
+
|
|
36
|
+
if (!candidate || !current) return false
|
|
37
|
+
|
|
38
|
+
for (let index = 0; index < candidate.length; index += 1) {
|
|
39
|
+
if (candidate[index] > current[index]) return true
|
|
40
|
+
if (candidate[index] < current[index]) return false
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isRecord(value) {
|
|
47
|
+
return typeof value === 'object' && value !== null
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function findUpdateAsset(manifest, platform, arch) {
|
|
51
|
+
if (!isRecord(manifest) || !Array.isArray(manifest.assets)) return null
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
manifest.assets.find(
|
|
55
|
+
asset =>
|
|
56
|
+
isRecord(asset) &&
|
|
57
|
+
asset.platform === platform &&
|
|
58
|
+
asset.arch === arch &&
|
|
59
|
+
asset.kind === 'installer' &&
|
|
60
|
+
typeof asset.githubUrl === 'string' &&
|
|
61
|
+
(typeof asset.r2Url === 'string' || typeof asset.r2Url === 'undefined')
|
|
62
|
+
) || null
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function formatBytes(size) {
|
|
67
|
+
if (!Number.isFinite(size) || size <= 0) return ''
|
|
68
|
+
|
|
69
|
+
const mb = size / 1024 / 1024
|
|
70
|
+
return `${mb.toFixed(mb >= 100 ? 0 : 1)} MB`
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getAvailableUpdate(manifest, options = {}) {
|
|
74
|
+
const currentVersion = options.currentVersion
|
|
75
|
+
const platform = options.platform
|
|
76
|
+
const arch = options.arch
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
!isRecord(manifest) ||
|
|
80
|
+
typeof manifest.version !== 'string' ||
|
|
81
|
+
!isNewerVersion(manifest.version, currentVersion)
|
|
82
|
+
) {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const asset = findUpdateAsset(manifest, platform, arch)
|
|
87
|
+
if (!asset) return null
|
|
88
|
+
|
|
89
|
+
const downloadUrl = asset.r2Url || asset.githubUrl
|
|
90
|
+
if (!downloadUrl) return null
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
version: manifest.version,
|
|
94
|
+
asset,
|
|
95
|
+
downloadUrl,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
findUpdateAsset,
|
|
6
|
+
formatBytes,
|
|
7
|
+
getAvailableUpdate,
|
|
8
|
+
getCurrentArch,
|
|
9
|
+
getCurrentPlatform,
|
|
10
|
+
getReleaseManifestUrl,
|
|
11
|
+
isNewerVersion,
|
|
12
|
+
} from './updateChecker.js'
|
|
13
|
+
|
|
14
|
+
const manifest = {
|
|
15
|
+
version: '0.1.3',
|
|
16
|
+
publishedAt: '2026-06-01T00:00:00.000Z',
|
|
17
|
+
assets: [
|
|
18
|
+
{
|
|
19
|
+
platform: 'windows',
|
|
20
|
+
arch: 'x64',
|
|
21
|
+
kind: 'installer',
|
|
22
|
+
filename: 'MostBox-0.1.3-win-x64-setup.exe',
|
|
23
|
+
size: 112197632,
|
|
24
|
+
sha256: 'hash',
|
|
25
|
+
r2Url:
|
|
26
|
+
'https://download.most.box/releases/v0.1.3/MostBox-0.1.3-win-x64-setup.exe',
|
|
27
|
+
githubUrl:
|
|
28
|
+
'https://github.com/most-people/most/releases/download/v0.1.3/MostBox-0.1.3-win-x64-setup.exe',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
platform: 'windows',
|
|
32
|
+
arch: 'arm64',
|
|
33
|
+
kind: 'installer',
|
|
34
|
+
filename: 'MostBox-0.1.3-win-arm64-setup.exe',
|
|
35
|
+
githubUrl:
|
|
36
|
+
'https://github.com/most-people/most/releases/download/v0.1.3/MostBox-0.1.3-win-arm64-setup.exe',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
platform: 'macos',
|
|
40
|
+
arch: 'arm64',
|
|
41
|
+
kind: 'installer',
|
|
42
|
+
filename: 'MostBox-0.1.3-mac-arm64.dmg',
|
|
43
|
+
githubUrl:
|
|
44
|
+
'https://github.com/most-people/most/releases/download/v0.1.3/MostBox-0.1.3-mac-arm64.dmg',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
describe('desktop update checker', () => {
|
|
50
|
+
it('uses the public R2 manifest by default and allows env override', () => {
|
|
51
|
+
assert.equal(
|
|
52
|
+
getReleaseManifestUrl({}),
|
|
53
|
+
'https://download.most.box/releases/latest.json'
|
|
54
|
+
)
|
|
55
|
+
assert.equal(
|
|
56
|
+
getReleaseManifestUrl({
|
|
57
|
+
MOSTBOX_RELEASE_MANIFEST_URL: 'http://localhost:9999/latest.json',
|
|
58
|
+
}),
|
|
59
|
+
'http://localhost:9999/latest.json'
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('maps process platform and arch to release manifest values', () => {
|
|
64
|
+
assert.equal(getCurrentPlatform('win32'), 'windows')
|
|
65
|
+
assert.equal(getCurrentPlatform('darwin'), 'macos')
|
|
66
|
+
assert.equal(getCurrentPlatform('linux'), 'linux')
|
|
67
|
+
assert.equal(getCurrentPlatform('freebsd'), null)
|
|
68
|
+
|
|
69
|
+
assert.equal(getCurrentArch('x64'), 'x64')
|
|
70
|
+
assert.equal(getCurrentArch('arm64'), 'arm64')
|
|
71
|
+
assert.equal(getCurrentArch('ia32'), null)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('compares stable and prefixed semver strings safely', () => {
|
|
75
|
+
assert.equal(isNewerVersion('0.1.3', '0.1.2'), true)
|
|
76
|
+
assert.equal(isNewerVersion('v0.2.0', '0.1.9'), true)
|
|
77
|
+
assert.equal(isNewerVersion('0.1.2', '0.1.2'), false)
|
|
78
|
+
assert.equal(isNewerVersion('0.1.1', '0.1.2'), false)
|
|
79
|
+
assert.equal(isNewerVersion('0.1.3-beta.1', '0.1.2'), true)
|
|
80
|
+
assert.equal(isNewerVersion('not-a-version', '0.1.2'), false)
|
|
81
|
+
assert.equal(isNewerVersion('0.1.3', 'not-a-version'), false)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('matches the current platform installer asset', () => {
|
|
85
|
+
assert.equal(
|
|
86
|
+
findUpdateAsset(manifest, 'windows', 'x64')?.filename,
|
|
87
|
+
'MostBox-0.1.3-win-x64-setup.exe'
|
|
88
|
+
)
|
|
89
|
+
assert.equal(
|
|
90
|
+
findUpdateAsset(manifest, 'windows', 'arm64')?.filename,
|
|
91
|
+
'MostBox-0.1.3-win-arm64-setup.exe'
|
|
92
|
+
)
|
|
93
|
+
assert.equal(findUpdateAsset(manifest, 'linux', 'x64'), null)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('returns an available update only for newer compatible manifests', () => {
|
|
97
|
+
const update = getAvailableUpdate(manifest, {
|
|
98
|
+
currentVersion: '0.1.2',
|
|
99
|
+
platform: 'windows',
|
|
100
|
+
arch: 'x64',
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
assert.equal(update?.version, '0.1.3')
|
|
104
|
+
assert.equal(update?.downloadUrl, manifest.assets[0].r2Url)
|
|
105
|
+
|
|
106
|
+
assert.equal(
|
|
107
|
+
getAvailableUpdate(manifest, {
|
|
108
|
+
currentVersion: '0.1.3',
|
|
109
|
+
platform: 'windows',
|
|
110
|
+
arch: 'x64',
|
|
111
|
+
}),
|
|
112
|
+
null
|
|
113
|
+
)
|
|
114
|
+
assert.equal(
|
|
115
|
+
getAvailableUpdate(manifest, {
|
|
116
|
+
currentVersion: '0.1.2',
|
|
117
|
+
platform: 'linux',
|
|
118
|
+
arch: 'x64',
|
|
119
|
+
}),
|
|
120
|
+
null
|
|
121
|
+
)
|
|
122
|
+
assert.equal(
|
|
123
|
+
getAvailableUpdate({ version: '0.1.3', assets: [] }, {
|
|
124
|
+
currentVersion: '0.1.2',
|
|
125
|
+
platform: 'windows',
|
|
126
|
+
arch: 'x64',
|
|
127
|
+
}),
|
|
128
|
+
null
|
|
129
|
+
)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('falls back to GitHub when an R2 URL is absent', () => {
|
|
133
|
+
const update = getAvailableUpdate(manifest, {
|
|
134
|
+
currentVersion: '0.1.2',
|
|
135
|
+
platform: 'windows',
|
|
136
|
+
arch: 'arm64',
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
assert.equal(update?.downloadUrl, manifest.assets[1].githubUrl)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('formats installer sizes for update prompts', () => {
|
|
143
|
+
assert.equal(formatBytes(112197632), '107 MB')
|
|
144
|
+
assert.equal(formatBytes(2.5 * 1024 * 1024), '2.5 MB')
|
|
145
|
+
assert.equal(formatBytes(0), '')
|
|
146
|
+
})
|
|
147
|
+
})
|
package/out/404/index.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="zh-CN" data-scroll-behavior="smooth"><head><meta charSet="UTF-8"/><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0adx~d-j05c9d.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/chunks/0xdwau5k2augv.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/03edqrb4zdj~g.js"/><script src="/_next/static/chunks/0pt.5cg1t09qs.js" async=""></script><script src="/_next/static/chunks/0gcsdf57gcm6h.js" async=""></script><script src="/_next/static/chunks/14_inksek_rth.js" async=""></script><script src="/_next/static/chunks/0pqt~8bl3ukh4.js" async=""></script><script src="/_next/static/chunks/turbopack-0xta0kqwzkf28.js" async=""></script><script src="/_next/static/chunks/
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-scroll-behavior="smooth"><head><meta charSet="UTF-8"/><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0adx~d-j05c9d.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/chunks/0xdwau5k2augv.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/03edqrb4zdj~g.js"/><script src="/_next/static/chunks/0pt.5cg1t09qs.js" async=""></script><script src="/_next/static/chunks/0gcsdf57gcm6h.js" async=""></script><script src="/_next/static/chunks/14_inksek_rth.js" async=""></script><script src="/_next/static/chunks/0pqt~8bl3ukh4.js" async=""></script><script src="/_next/static/chunks/turbopack-0xta0kqwzkf28.js" async=""></script><script src="/_next/static/chunks/0_0oph_z1az14.js" async=""></script><script src="/_next/static/chunks/0ysj5b94vu4ri.js" async=""></script><script src="/_next/static/chunks/0t2xr05rlu96l.js" async=""></script><script src="/_next/static/chunks/0m_5nb6x8qy._.js" async=""></script><script src="/_next/static/chunks/0ao1lbi4b.sfa.js" async=""></script><meta name="robots" content="noindex"/><link rel="icon" href="/favicon.ico"/><meta name="theme-color" content="#5e6ad2"/><title>MostBox</title><meta name="description" content="P2P 文件分享,无需注册"/><script>
|
|
2
2
|
(function() {
|
|
3
3
|
var theme = localStorage.getItem('theme');
|
|
4
4
|
if (theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
window.onunhandledrejection = function(event) {
|
|
13
13
|
console.error('[Unhandled Promise Rejection]', event.reason);
|
|
14
14
|
};
|
|
15
|
-
</script><div class="not-found-page"><div class="not-found-card"><div class="not-found-icon"><svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-compass" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"></path></svg></div><h1 class="not-found-title">页面未找到</h1><p class="not-found-desc">你访问的页面似乎已经迷失在 P2P 网络中了</p><div class="not-found-actions"><button class="btn btn-secondary"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg>上一页</button><a class="btn btn-primary" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-house" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"></path><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path></svg>回首页</a></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/03edqrb4zdj~g.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[14232,[\"/_next/static/chunks/
|
|
15
|
+
</script><div class="not-found-page"><div class="not-found-card"><div class="not-found-icon"><svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-compass" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"></path></svg></div><h1 class="not-found-title">页面未找到</h1><p class="not-found-desc">你访问的页面似乎已经迷失在 P2P 网络中了</p><div class="not-found-actions"><button class="btn btn-secondary"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg>上一页</button><a class="btn btn-primary" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-house" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"></path><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path></svg>回首页</a></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/03edqrb4zdj~g.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[14232,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"ErrorBoundary\"]\n3:I[52925,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\"]\n4:I[39756,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\"]\n5:I[37457,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\"]\n6:I[36768,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\",\"/_next/static/chunks/0ao1lbi4b.sfa.js\"],\"default\"]\n7:I[47257,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"ClientPageRoot\"]\na:I[97367,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"OutletBoundary\"]\nb:\"$Sreact.suspense\"\ne:I[97367,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"ViewportBoundary\"]\n10:I[97367,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"MetadataBoundary\"]\n12:I[68027,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/0adx~d-j05c9d.css\",\"style\"]\n:HL[\"/_next/static/chunks/0xdwau5k2augv.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0adx~d-j05c9d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xdwau5k2augv.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0_0oph_z1az14.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/0t2xr05rlu96l.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-3\",{\"src\":\"/_next/static/chunks/0m_5nb6x8qy._.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"zh-CN\",\"suppressHydrationWarning\":true,\"data-scroll-behavior\":\"smooth\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"meta\",null,{\"charSet\":\"UTF-8\"}],[\"$\",\"meta\",null,{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1.0\"}],[\"$\",\"link\",null,{\"rel\":\"icon\",\"href\":\"/favicon.ico\"}],[\"$\",\"meta\",null,{\"name\":\"theme-color\",\"content\":\"#5e6ad2\"}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n (function() {\\n var theme = localStorage.getItem('theme');\\n if (theme === 'dark' || (!theme \u0026\u0026 window.matchMedia('(prefers-color-scheme: dark)').matches)) {\\n document.documentElement.setAttribute('data-theme', 'dark');\\n }\\n })();\\n \"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"children\":[[\"$\",\"$L3\",null,{}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n window.onerror = function(message, source, lineno, colno, error) {\\n console.error('[Global Error]', { message, source, lineno, colno, error });\\n };\\n window.onunhandledrejection = function(event) {\\n console.error('[Unhandled Promise Rejection]', event.reason);\\n };\\n \"}}],[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"$L6\",null,{}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$L7\",null,{\"Component\":\"$6\",\"serverProvidedParams\":{\"searchParams\":{},\"params\":{},\"promises\":[\"$@8\",\"$@9\"]}}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0ao1lbi4b.sfa.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$La\",null,{\"children\":[\"$\",\"$b\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@c\"}]}]]}],{},null,false,null]},null,false,\"$@d\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$Le\",null,{\"children\":\"$Lf\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L10\",null,{\"children\":[\"$\",\"$b\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L11\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$12\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0adx~d-j05c9d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xdwau5k2augv.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"aPEZ4zaaR5W3WpSZ0dFsa\"}\n"])</script><script>self.__next_f.push([1,"13:[]\nd:\"$W13\"\n8:{}\n9:\"$0:f:0:1:1:children:1:children:0:props:children:0:props:serverProvidedParams:params\"\n"])</script><script>self.__next_f.push([1,"f:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"c:null\n11:[[\"$\",\"title\",\"0\",{\"children\":\"MostBox\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"P2P 文件分享,无需注册\"}]]\n"])</script></body></html>
|
package/out/404.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="zh-CN" data-scroll-behavior="smooth"><head><meta charSet="UTF-8"/><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0adx~d-j05c9d.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/chunks/0xdwau5k2augv.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/03edqrb4zdj~g.js"/><script src="/_next/static/chunks/0pt.5cg1t09qs.js" async=""></script><script src="/_next/static/chunks/0gcsdf57gcm6h.js" async=""></script><script src="/_next/static/chunks/14_inksek_rth.js" async=""></script><script src="/_next/static/chunks/0pqt~8bl3ukh4.js" async=""></script><script src="/_next/static/chunks/turbopack-0xta0kqwzkf28.js" async=""></script><script src="/_next/static/chunks/
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-scroll-behavior="smooth"><head><meta charSet="UTF-8"/><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0adx~d-j05c9d.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/chunks/0xdwau5k2augv.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/03edqrb4zdj~g.js"/><script src="/_next/static/chunks/0pt.5cg1t09qs.js" async=""></script><script src="/_next/static/chunks/0gcsdf57gcm6h.js" async=""></script><script src="/_next/static/chunks/14_inksek_rth.js" async=""></script><script src="/_next/static/chunks/0pqt~8bl3ukh4.js" async=""></script><script src="/_next/static/chunks/turbopack-0xta0kqwzkf28.js" async=""></script><script src="/_next/static/chunks/0_0oph_z1az14.js" async=""></script><script src="/_next/static/chunks/0ysj5b94vu4ri.js" async=""></script><script src="/_next/static/chunks/0t2xr05rlu96l.js" async=""></script><script src="/_next/static/chunks/0m_5nb6x8qy._.js" async=""></script><script src="/_next/static/chunks/0ao1lbi4b.sfa.js" async=""></script><meta name="robots" content="noindex"/><link rel="icon" href="/favicon.ico"/><meta name="theme-color" content="#5e6ad2"/><title>MostBox</title><meta name="description" content="P2P 文件分享,无需注册"/><script>
|
|
2
2
|
(function() {
|
|
3
3
|
var theme = localStorage.getItem('theme');
|
|
4
4
|
if (theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
window.onunhandledrejection = function(event) {
|
|
13
13
|
console.error('[Unhandled Promise Rejection]', event.reason);
|
|
14
14
|
};
|
|
15
|
-
</script><div class="not-found-page"><div class="not-found-card"><div class="not-found-icon"><svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-compass" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"></path></svg></div><h1 class="not-found-title">页面未找到</h1><p class="not-found-desc">你访问的页面似乎已经迷失在 P2P 网络中了</p><div class="not-found-actions"><button class="btn btn-secondary"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg>上一页</button><a class="btn btn-primary" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-house" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"></path><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path></svg>回首页</a></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/03edqrb4zdj~g.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[14232,[\"/_next/static/chunks/
|
|
15
|
+
</script><div class="not-found-page"><div class="not-found-card"><div class="not-found-icon"><svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-compass" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"></path></svg></div><h1 class="not-found-title">页面未找到</h1><p class="not-found-desc">你访问的页面似乎已经迷失在 P2P 网络中了</p><div class="not-found-actions"><button class="btn btn-secondary"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg>上一页</button><a class="btn btn-primary" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-house" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"></path><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path></svg>回首页</a></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/03edqrb4zdj~g.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[14232,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"ErrorBoundary\"]\n3:I[52925,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\"]\n4:I[39756,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\"]\n5:I[37457,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\"]\n6:I[36768,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\",\"/_next/static/chunks/0ao1lbi4b.sfa.js\"],\"default\"]\n7:I[47257,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"ClientPageRoot\"]\na:I[97367,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"OutletBoundary\"]\nb:\"$Sreact.suspense\"\ne:I[97367,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"ViewportBoundary\"]\n10:I[97367,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"MetadataBoundary\"]\n12:I[68027,[\"/_next/static/chunks/0_0oph_z1az14.js\",\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"/_next/static/chunks/0t2xr05rlu96l.js\",\"/_next/static/chunks/0m_5nb6x8qy._.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/0adx~d-j05c9d.css\",\"style\"]\n:HL[\"/_next/static/chunks/0xdwau5k2augv.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0adx~d-j05c9d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xdwau5k2augv.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0_0oph_z1az14.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0ysj5b94vu4ri.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/0t2xr05rlu96l.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-3\",{\"src\":\"/_next/static/chunks/0m_5nb6x8qy._.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"zh-CN\",\"suppressHydrationWarning\":true,\"data-scroll-behavior\":\"smooth\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"meta\",null,{\"charSet\":\"UTF-8\"}],[\"$\",\"meta\",null,{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1.0\"}],[\"$\",\"link\",null,{\"rel\":\"icon\",\"href\":\"/favicon.ico\"}],[\"$\",\"meta\",null,{\"name\":\"theme-color\",\"content\":\"#5e6ad2\"}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n (function() {\\n var theme = localStorage.getItem('theme');\\n if (theme === 'dark' || (!theme \u0026\u0026 window.matchMedia('(prefers-color-scheme: dark)').matches)) {\\n document.documentElement.setAttribute('data-theme', 'dark');\\n }\\n })();\\n \"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"children\":[[\"$\",\"$L3\",null,{}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n window.onerror = function(message, source, lineno, colno, error) {\\n console.error('[Global Error]', { message, source, lineno, colno, error });\\n };\\n window.onunhandledrejection = function(event) {\\n console.error('[Unhandled Promise Rejection]', event.reason);\\n };\\n \"}}],[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"$L6\",null,{}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$L7\",null,{\"Component\":\"$6\",\"serverProvidedParams\":{\"searchParams\":{},\"params\":{},\"promises\":[\"$@8\",\"$@9\"]}}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0ao1lbi4b.sfa.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$La\",null,{\"children\":[\"$\",\"$b\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@c\"}]}]]}],{},null,false,null]},null,false,\"$@d\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$Le\",null,{\"children\":\"$Lf\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L10\",null,{\"children\":[\"$\",\"$b\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L11\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$12\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0adx~d-j05c9d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xdwau5k2augv.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"aPEZ4zaaR5W3WpSZ0dFsa\"}\n"])</script><script>self.__next_f.push([1,"13:[]\nd:\"$W13\"\n8:{}\n9:\"$0:f:0:1:1:children:1:children:0:props:children:0:props:serverProvidedParams:params\"\n"])</script><script>self.__next_f.push([1,"f:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"c:null\n11:[[\"$\",\"title\",\"0\",{\"children\":\"MostBox\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"P2P 文件分享,无需注册\"}]]\n"])</script></body></html>
|