feat: 实现动态 DOCX 模板与样式映射

This commit is contained in:
SkyJourney
2026-07-30 14:10:43 +08:00
parent fe5d67fb6d
commit fa159d916f
41 changed files with 3610 additions and 7 deletions
@@ -0,0 +1,48 @@
import { describe, expect, it } from "vitest";
import { zipSync } from "fflate";
import {
readReferenceDocxPackage,
requiredReferenceDocxParts
} from "../src/index.js";
function createReferencePackage(
overrides: Record<string, Uint8Array> = {}
) {
const entries = Object.fromEntries(
requiredReferenceDocxParts.map((name) => [
name,
new TextEncoder().encode(`<part name="${name}"/>`)
])
);
return zipSync({ ...entries, ...overrides });
}
describe("reference.docx 包", () => {
it("预检中央目录并返回稳定指纹", () => {
const content = createReferencePackage();
const first = readReferenceDocxPackage(content);
const second = readReferenceDocxPackage(content);
expect(first.entries.size).toBe(requiredReferenceDocxParts.length);
expect(first.entries.has("word/styles.xml")).toBe(true);
expect(first.fingerprint).toMatch(/^[0-9a-f]{64}$/u);
expect(second.fingerprint).toBe(first.fingerprint);
});
it("拒绝路径穿越和缺少必要部件", () => {
expect(() =>
readReferenceDocxPackage(
createReferencePackage({
"../outside.xml": new Uint8Array([1])
})
)
).toThrow("不安全路径");
const incomplete = zipSync({
"[Content_Types].xml": new Uint8Array([1])
});
expect(() => readReferenceDocxPackage(incomplete)).toThrow(
"缺少必要部件"
);
});
});