5f78dde9ee
复审四项: - serveFile 改 createReadStream 直 pipe(Content-Length 取自先行 stat)—— 64MB 文件 RSS 平坦(冒烟实测 -53MB 增长,此前整读驻留);HEAD 只发头 零读盘;流错误掐断连接不崩进程;头纪律抽 applyHeaders 唯一出口。 - createPreviewServer 增 quiet 选项(缺省 verbose);sf.ts preview:start 与 server.mjs 直跑入口各加 --quiet;CLI 透传经子进程冒烟验证。 - redirect 迁移页内嵌 location 时 HTML 转义(</&/"——Location 头原样)。 - parseCliArgs 末尾缺值 flag 显式报错(不再静默 undefined 漏成默认值)。 测试 12→13(新增 quiet 开关用例;用例 12 增 --quiet stdout 断言): 根套件 380 + 主题 26 = 406 全绿;typecheck/lint 干净。 Co-Authored-By: Claude Code <noreply@anthropic.com>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
// server.mjs 的 TS 声明面(NodeNext 自动拾取):实现刻意保持纯 JS(零依赖、不进 TS
|
||
// 构建链),类型契约在此钉死。行类型是 RouteManifestRoute 的结构超集容忍面——
|
||
// @sf/contracts 的 RouteManifest 可直接传入(字段窄化兼容)。
|
||
import type { AddressInfo } from 'node:net'
|
||
import type { Server } from 'node:http'
|
||
|
||
export interface PreviewRouteRow {
|
||
exact_key: string
|
||
query_policy: string
|
||
query_key?: string | null
|
||
kind: string
|
||
target_file?: string
|
||
status: number
|
||
location?: string
|
||
content_type?: string
|
||
indexable: boolean
|
||
}
|
||
|
||
export interface PreviewManifestLike {
|
||
routes: PreviewRouteRow[]
|
||
}
|
||
|
||
export interface PreviewServerOptions {
|
||
/** 构建产物目录(<artifactsRoot>/jobs/<jobId>/dist) */
|
||
distDir: string
|
||
/** §12.1 route-manifest(已解析对象——预览只读不加载路径) */
|
||
routeManifest: PreviewManifestLike
|
||
/** 绑定地址;仅 127.0.0.1 / localhost(缺省 127.0.0.1)——外值构造即拒 */
|
||
host?: string
|
||
/** 监听端口(缺省 4173;0 = 随机可用端口) */
|
||
port?: number
|
||
/** 静默逐请求访问日志(缺省 false——逐请求一行 stdout) */
|
||
quiet?: boolean
|
||
}
|
||
|
||
export interface PreviewServerHandle {
|
||
server: Server
|
||
/** 开始监听;resolve 值 = server.address()(port=0 时含实际端口) */
|
||
start(): Promise<AddressInfo>
|
||
/** 关停(destroy 连接后 close——防 keep-alive 套接字吊住) */
|
||
stop(): Promise<void>
|
||
}
|
||
|
||
export declare function createPreviewServer(options: PreviewServerOptions): PreviewServerHandle
|