Files
im0o b276c4a8fe 轻提示铺开到全部页面;内核状态悬停变重启;GEO 支持单文件下载
侧栏动作排撤掉重启图标,内核状态(圆点加版本号)本身变成按钮:悬停
换层显示「重启内核」,不在线时只当状态看。行高压成 1 修掉圆点和等宽
字体不居中的问题。

四个页面的一次性反馈(保存、删除、更新订阅、断开连接、测延迟结论)
全部改走 toast,commit() 改返回成败给「失败不关对话框」用;持续状态
(连接页轮询失败、请求页日志流失败)留在页内,会自动消失的提示装不下
需要一直可见的信息。toast 加 info 类别给中性结论用。

GEO 每行的更新改成单独下载那一个文件:内核只有全量更新的口子,单文件
只能服务端自己下(POST /api/geo/sync),代价是只有形状校验(MaxMind
末尾标记、geodata 首字节,shared/geo.ts 带测试)且内核重启后才换用新
文件;「更新全部」文字按钮保留内核的全量口子,有完整校验和热加载。
上传两行的按钮改「选择或拖放文件」,投放区拖入高亮,恢复策略挪到
恢复行下方。
2026-08-12 02:20:46 +08:00

44 lines
1.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test } from 'bun:test'
import { looksLikeGeodata, looksLikeMmdb } from './geo.ts'
describe('GEO 文件的形状检查', () => {
test('末尾带 MaxMind 标记的通过,纯垃圾不通过', () => {
const marker = new Uint8Array([
0xab,
0xcd,
0xef,
...Array.from('MaxMind.com', (c) => c.charCodeAt(0)),
])
const good = new Uint8Array(4096)
good.set(marker, 4000)
expect(looksLikeMmdb(good)).toBe(true)
expect(looksLikeMmdb(new Uint8Array(4096))).toBe(false)
})
test('标记只认末尾 128KB,太靠前算无效', () => {
const marker = new Uint8Array([
0xab,
0xcd,
0xef,
...Array.from('MaxMind.com', (c) => c.charCodeAt(0)),
])
const bytes = new Uint8Array(300 * 1024)
bytes.set(marker, 100)
expect(looksLikeMmdb(bytes)).toBe(false)
})
test('geodata 认首字节 0x0a,HTML 错误页和小文件被挡下', () => {
const good = new Uint8Array(2048)
good[0] = 0x0a
expect(looksLikeGeodata(good)).toBe(true)
const html = new Uint8Array(2048)
html[0] = '<'.charCodeAt(0)
expect(looksLikeGeodata(html)).toBe(false)
const tiny = new Uint8Array(10)
tiny[0] = 0x0a
expect(looksLikeGeodata(tiny)).toBe(false)
})
})