搭出前端骨架和入站列表
设计基调定为:层次靠底色和一像素描边而不是投影,一屏最多两层容器,间距给足。 tokens.css 顶部写了这三条规则,后面的组件都是它们的推论。 入站列表把两套写法合并成一张表:老式顶层端口字段(mixed-port 这些)和 listeners 数组。 只画 listeners 的话,一台只用 mixed-port 的机器打开会是空板,而那个端口正在跑—— 这等于对用户撒谎。合并逻辑在 shared/inbounds.ts,带 10 个测试。 后端顺带能提供打包后的静态文件了,一个进程就能跑起来。
This commit is contained in:
+11
-2
@@ -11,7 +11,7 @@
|
||||
* 用法:bun run scripts/api-smoke.ts [令牌]
|
||||
* 不给令牌就从配置文件旁边的 .patchbay-token 读。
|
||||
*/
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { copyFile, readFile } from 'node:fs/promises'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { readEnv } from '../server/env.ts'
|
||||
import type { ConfigObject } from '../vendor/config-editor/index.ts'
|
||||
@@ -22,6 +22,10 @@ const token =
|
||||
process.argv[2] ??
|
||||
(await readFile(join(dirname(env.configPath), '.patchbay-token'), 'utf8')).trim()
|
||||
|
||||
// 每次从模板重置。不重置的话第二次运行会写入和上次完全相同的内容,
|
||||
// 而「内容没变就不重载」是刻意的行为,会让「内核已重载」这一项看起来失败。
|
||||
await copyFile('./dev/config.yaml', env.configPath)
|
||||
|
||||
let failures = 0
|
||||
function check(name: string, actual: unknown, expected: unknown) {
|
||||
if (JSON.stringify(actual) === JSON.stringify(expected)) {
|
||||
@@ -56,7 +60,12 @@ check(
|
||||
)
|
||||
check('白名单外的透传被拒', (await call('GET', '/api/kernel/configs/geo')).status, 403)
|
||||
check('不存在的接口', (await call('GET', '/api/nope')).status, 404)
|
||||
check('非 api 路径', (await call('GET', '/index.html')).status, 404)
|
||||
// 静态文件不要令牌:它只是个空壳,所有数据都要带令牌才拿得到。
|
||||
check(
|
||||
'前端页面不需要令牌',
|
||||
(await fetch(`${base}/`)).status,
|
||||
200,
|
||||
)
|
||||
|
||||
// ── 配置读写 ────────────────────────────────────────────
|
||||
const snapshot = await call('GET', '/api/config')
|
||||
|
||||
Reference in New Issue
Block a user