Files
cms-website/apps/preview-server/server.d.mts
T
浅念 7194d1bcef feat(preview): 路由驱动的本地预览服务器
Plan 4 Task 7(V2 spec §12.2):apps/preview-server 零依赖 node:http 服务——
只读 succeeded job 的 dist + route-manifest(不查库),exact/ignore 双索引匹配
(query_key 行全串优先),html/asset 文件服务(manifest content_type 优先、
扩展名 MIME 表兜底、未知扩展 octet-stream)、redirect 301+Location、gone 410、
未命中 404 走 dist/404.html 自定义页;全响应 X-Robots-Tag noindex + HTML 响应
基础 CSP;回环绑定白名单(库级即拒);穿越预检先于 URL 解析(裸/编码点段、
反斜杠)+ target_file resolve+realpath 双检在 dist 内;目录请求一律 404(禁
列表);仅 GET/HEAD。sf.ts 增 preview:start(job 定位 + succeeded 校验 + 产物
行读取后即断池;--host 外值拒绝先于 DB 访问)。集成测试 12 例:真实构建产物
全链 + 手构 gone/MIME 探针行 + CLI 拒绝与子进程 happy path 冒烟。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 13:29:30 +08:00

43 lines
1.5 KiB
TypeScript
Raw 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.
// 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
}
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