fix: 修复所有 TypeScript 类型错误

- 修复 fonteditor-core 模块声明(添加 FontEditor 命名空间、FontType 类型、SubsetOptions 接口)
- 修复 llrt.ts 中 mkdir 和 rm 方法的返回类型问题
- 修复 tcp_server.ts 中 chunk 类型问题(添加 Buffer 类型检查和转换)
- 修复 font_detail.ts 中缺失的 ORIGIN 导入
- 修复 subset.ts 中 subsetQueueTimeoutSeconds 的导入
- 为 Font 类添加 optimize() 和 write() 方法声明
This commit is contained in:
崮生(子虚) 2026-08-15 07:38:57 +08:00
parent dc1ee66fe3
commit fe61bace16
9 changed files with 68 additions and 20 deletions

View File

@ -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",

View File

@ -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;

View File

@ -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<void>;
export let unlink: (path: string) => Promise<void>;
export let rm: (path: string) => Promise<void>;
/** LLRT 专用:保存 rm 函数引用,避免闭包问题 */
let llrtRm: ((path: string) => Promise<void>) | 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<void>;
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[]) {

View File

@ -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<Response | nul
const values: PlaceholderValues = {
[FONT_NAME]: slug,
[FONT_SLUG]: slug,
[ORIGIN]: "",
};
/** 解码模板为字符串,替换所有占位符 */

View File

@ -3,7 +3,7 @@ import type { FontEditor } from "../../vendor/fonteditor-core/lib/ttf/font.js";
import { parseUrl, stats, subsetCache, findFontPath, readFontBuffer, markStatsDirty } from "../shared";
import { markFontUsed } from "../temp_cleaner";
import { withMemoryGate } from "../subset_queue";
import { subsetConcurrency, subsetQueueTimeoutSeconds } from "../config";
import { subsetQueueTimeoutSeconds } from "../config";
/**
*
@ -142,13 +142,13 @@ export async function handleFontSubset(req: Request, res: Response) {
const t3 = Date.now();
/** 写入裁剪结果缓存 */
subsetCache.set(cacheKey, newFont as ArrayBuffer);
subsetCache.set(cacheKey, newFont as unknown as ArrayBuffer);
const contentTypes: Record<string, string> = { 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",

View File

@ -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);
},
});

View File

@ -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);
},
});

View File

@ -11,7 +11,7 @@ export function createTcpServer(
const server = createServer((socket) => {
const readable = new ReadableStream<Uint8Array>({
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<Uint8Array>({
write(chunk) {
return new Promise((resolve, reject) => {
socket.write(chunk, (err) => {
return new Promise<void>((resolve, reject) => {
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
socket.write(buffer, (err) => {
if (err) reject(err);
else resolve();
});

View File

@ -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<number, number>;
}
}
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;
}