From fe61bace16d9afaf7b641145da6a86c18c65e218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=AE=E7=94=9F=EF=BC=88=E5=AD=90=E8=99=9A=EF=BC=89?= <2234839456@qq.com> Date: Sat, 15 Aug 2026 07:38:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=80=E6=9C=89=20T?= =?UTF-8?q?ypeScript=20=E7=B1=BB=E5=9E=8B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 fonteditor-core 模块声明(添加 FontEditor 命名空间、FontType 类型、SubsetOptions 接口) - 修复 llrt.ts 中 mkdir 和 rm 方法的返回类型问题 - 修复 tcp_server.ts 中 chunk 类型问题(添加 Buffer 类型检查和转换) - 修复 font_detail.ts 中缺失的 ORIGIN 导入 - 修复 subset.ts 中 subsetQueueTimeoutSeconds 的导入 - 为 Font 类添加 optimize() 和 write() 方法声明 --- backend/app.ts | 4 +-- backend/font_util/cff-subset.ts | 2 +- backend/interface.ts | 12 +++++++-- backend/routes/font_detail.ts | 3 ++- backend/routes/subset.ts | 6 ++--- backend/server/llrt.ts | 12 ++++++--- backend/server/node.ts | 11 ++++++--- backend/server/tcp_server.ts | 7 +++--- vendor/fonteditor-core/lib/ttf/font.d.ts | 31 ++++++++++++++++++++++++ 9 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 vendor/fonteditor-core/lib/ttf/font.d.ts diff --git a/backend/app.ts b/backend/app.ts index 959c77d..25ac93d 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -76,7 +76,7 @@ const staticFileMiddleware: cMiddleware = async function (req, _res, next) { } const fileContent = await readFile(resolvedPath); const extname = resolvedPath.split(".").pop() ?? ""; - newRes = new Response(fileContent, { + newRes = new Response(fileContent as unknown as BodyInit, { status: 200, headers: { "Content-Type": mimeTypes[extname] || "application/octet-stream", @@ -109,7 +109,7 @@ const staticFileMiddleware: cMiddleware = async function (req, _res, next) { }); } else { const fallbackContent = await readFile(path_join(ROOT_DIR, "index.html")); - newRes = new Response(fallbackContent, { + newRes = new Response(fallbackContent as unknown as BodyInit, { status: 200, headers: { "Content-Type": "text/html; charset=utf-8", diff --git a/backend/font_util/cff-subset.ts b/backend/font_util/cff-subset.ts index 3f8f19f..6d5fbdb 100644 --- a/backend/font_util/cff-subset.ts +++ b/backend/font_util/cff-subset.ts @@ -183,7 +183,7 @@ function encodeDictInt(v: number): number[] { /** Type 2 charstring 操作码(Adobe Type 2 Charstring Format)。 */ const T2_CALLSUBR = 10; -const T2_RETURN = 11; +// const T2_RETURN = 11; // 未使用,保留注释 const T2_ENDCHAR = 14; const T2_HSTEM = 1; const T2_VSTEM = 3; diff --git a/backend/interface.ts b/backend/interface.ts index c0bd98b..e19270b 100644 --- a/backend/interface.ts +++ b/backend/interface.ts @@ -1,5 +1,6 @@ export let stat: (path: string) => Promise<{ isFile: () => boolean; + isDirectory: () => boolean; size: number; /** 最后修改时间戳(毫秒),用于文件变更检测 */ mtimeMs: number; @@ -18,6 +19,8 @@ export let mkdir: (path: string) => Promise; export let unlink: (path: string) => Promise; +export let rm: (path: string) => Promise; + /** LLRT 专用:保存 rm 函数引用,避免闭包问题 */ let llrtRm: ((path: string) => Promise) | undefined; @@ -28,8 +31,7 @@ export const implInterface = (options: { readdir: typeof readdir; mkdir: typeof mkdir; unlink?: typeof unlink; - /** LLRT 没有 unlink,提供 rm 作为替代 */ - rm?: (path: string) => Promise; + rm?: typeof rm; }) => { stat = options.stat; readFile = options.readFile; @@ -46,6 +48,12 @@ export const implInterface = (options: { await llrtRm(path); } }; + /** 同时暴露 rm 方法 */ + rm = async (path) => { + if (options.rm) { + await options.rm(path); + } + }; }; export function path_join(...paths: string[]) { diff --git a/backend/routes/font_detail.ts b/backend/routes/font_detail.ts index fb79a36..a10e212 100644 --- a/backend/routes/font_detail.ts +++ b/backend/routes/font_detail.ts @@ -11,7 +11,7 @@ import { readFile, stat } from "../interface"; import { path_join } from "../interface"; import { fontDirs } from "../config"; -import { FONT_NAME, FONT_SLUG, type PlaceholderValues } from "../../src/placeholders"; +import { FONT_NAME, FONT_SLUG, ORIGIN, type PlaceholderValues } from "../../src/placeholders"; const ROOT_DIR = "dist"; @@ -69,6 +69,7 @@ export async function handleFontDetail(pathname: string): Promise = { ttf: "font/ttf", woff2: "font/woff2" }; return { req, - res: new Response(newFont, { + res: new Response(newFont as unknown as BodyInit, { status: 200, headers: { "Content-Type": contentTypes[outType] || "font/ttf", diff --git a/backend/server/llrt.ts b/backend/server/llrt.ts index 2c18982..85015ce 100644 --- a/backend/server/llrt.ts +++ b/backend/server/llrt.ts @@ -17,11 +17,15 @@ implInterface({ return Promise.all( names.map(async (name) => { const s = await fs.stat(`${path}/${name}`); - return { name, isFile: () => s.isFile() }; + return { name, isFile: () => s.isFile(), isDirectory: () => s.isDirectory() }; }) ); }, - mkdir: (path) => fs.mkdir(path, { recursive: true }), - /** LLRT 没有 unlink,用箭头函数包装 rm 避免 this 问题 */ - rm: (path: string) => fs.rm(path), + mkdir: async (path) => { + await fs.mkdir(path, { recursive: true }); + }, + /** LLRT 没有 unlink,用 rm 代替,忽略返回值 */ + rm: async (path: string) => { + await fs.rm(path); + }, }); diff --git a/backend/server/node.ts b/backend/server/node.ts index edb2b57..88431aa 100644 --- a/backend/server/node.ts +++ b/backend/server/node.ts @@ -1,10 +1,10 @@ import { implInterface } from "../interface"; -import { stat as fsStat, readFile, writeFile, readdir as fsReaddir, mkdir, unlink } from "fs/promises"; +import { stat as fsStat, readFile, writeFile, readdir as fsReaddir, mkdir, unlink, rm } from "fs/promises"; implInterface({ async stat(path) { const r = await fsStat(path); - return r; + return { ...r, isDirectory: () => r.isDirectory() }; }, readFile(path) { return readFile(path); @@ -21,11 +21,11 @@ implInterface({ */ async readdir(path) { const names = await fsReaddir(path); - const results: { isFile: () => boolean; name: string }[] = []; + const results: { isFile: () => boolean; isDirectory: () => boolean; name: string }[] = []; for (const name of names) { try { const s = await fsStat(path + "/" + name); - results.push({ name, isFile: () => s.isFile() }); + results.push({ name, isFile: () => s.isFile(), isDirectory: () => s.isDirectory() }); } catch { /** stat 失败(符号链接断裂等)跳过 */ } @@ -38,4 +38,7 @@ implInterface({ unlink(path) { return unlink(path); }, + rm(path) { + return rm(path); + }, }); diff --git a/backend/server/tcp_server.ts b/backend/server/tcp_server.ts index 0142e5b..a85dee7 100644 --- a/backend/server/tcp_server.ts +++ b/backend/server/tcp_server.ts @@ -11,7 +11,7 @@ export function createTcpServer( const server = createServer((socket) => { const readable = new ReadableStream({ start(controller) { - socket.on("data", (chunk) => { + socket.on("data", (chunk: Buffer) => { controller.enqueue(new Uint8Array(chunk)); }); socket.on("error", (err) => { @@ -29,8 +29,9 @@ export function createTcpServer( // 创建 WritableStream const writable = new WritableStream({ write(chunk) { - return new Promise((resolve, reject) => { - socket.write(chunk, (err) => { + return new Promise((resolve, reject) => { + const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); + socket.write(buffer, (err) => { if (err) reject(err); else resolve(); }); diff --git a/vendor/fonteditor-core/lib/ttf/font.d.ts b/vendor/fonteditor-core/lib/ttf/font.d.ts new file mode 100644 index 0000000..fbf222d --- /dev/null +++ b/vendor/fonteditor-core/lib/ttf/font.d.ts @@ -0,0 +1,31 @@ +/** + * fonteditor-core 类型声明 + */ + +export namespace FontEditor { + export type FontType = "ttf" | "otf" | "woff" | "woff2" | "eot" | "svg"; + + export interface SubsetOptions { + type?: string; + subset?: number[]; + kerning?: boolean; + extraSubsetGids?: number[]; + presetCmap?: Record; + } +} + +export interface FontEditor { + /** 字体编辑器接口 */ +} + +export function createFontEditor(data: ArrayBuffer): FontEditor; + +export class Font { + static create(buffer: ArrayBuffer | Buffer | string | Document, options?: FontEditor.SubsetOptions): Font; + + get(): any; + set(data: any): Font; + export(options?: { type?: string }): ArrayBuffer; + optimize(options?: any): Font; + write(options?: any): ArrayBuffer; +} \ No newline at end of file