- engine/(registry/types/runtime/expression)物理迁入包, 解耦shared/types(域类型归包, 宿主type-only re-export) - 31个纯Node能力+27个测试迁入包; 宿主留守Electron/浏览器/AI依赖能力, index.ts经@rpa/core/capabilities拉起 - 新增createEngine()/defaultEngine: excel缓存/Excel句柄/db连接/FTP客户端/OCR实例/拟真设置挂引擎实例 - remaining-core子流程依赖改为host-bridge注入, 包内不再import宿主flows - 宿主main/index.ts启动时注入子流程源; electron-vite/vitest/tsconfig配@rpa/core源码别名 - 验证: typecheck绿, 快照909个id diff为零, 332测试过(2个桌面冒烟因会话无交互SetForegroundWindow被拒, 环境阻塞)
55 lines
3.0 KiB
TypeScript
55 lines
3.0 KiB
TypeScript
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { PDFDocument, StandardFonts } from "pdf-lib";
|
|
import { PNG } from "pngjs";
|
|
import { getHandler } from "../engine/registry";
|
|
import type { CatalogComponent, FlowNode } from "../types";
|
|
import type { RunContext } from "../engine/types";
|
|
import "./pdf";
|
|
|
|
const directories: string[] = [];
|
|
const context = {} as RunContext;
|
|
const component = {} as CatalogComponent;
|
|
const node = (id: string): FlowNode => ({ id, componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} });
|
|
async function run(id: string, args: Record<string, unknown>) {
|
|
const handler = getHandler(id);
|
|
expect(handler, id).toBeTruthy();
|
|
return handler!(context, node(id), args, component);
|
|
}
|
|
afterEach(async () => Promise.all(directories.splice(0).map((directory) => rm(directory, { recursive: true, force: true }))));
|
|
|
|
describe("PDF high-level capabilities", () => {
|
|
it("creates a pdf fixture", async () => {
|
|
const directory = await mkdtempSafe();
|
|
const pdf = await PDFDocument.create();
|
|
const page = pdf.addPage([220, 120]);
|
|
const font = await pdf.embedFont(StandardFonts.Helvetica);
|
|
const png = new PNG({ width: 8, height: 8 });
|
|
png.data.fill(255); png.data[0] = 20; png.data[1] = 90; png.data[2] = 200; png.data[3] = 255;
|
|
page.drawImage(await pdf.embedPng(PNG.sync.write(png)), { x: 140, y: 70, width: 40, height: 40 });
|
|
for (const [value, x, y] of [["Name", 24, 90], ["Age", 120, 90], ["Alice", 24, 72], ["30", 120, 72]] as Array<[string, number, number]>) page.drawText(value, { x, y, size: 9, font });
|
|
await writeFile(path.join(directory, "source.pdf"), await pdf.save());
|
|
const filePath = path.join(directory, "source.pdf");
|
|
expect((await readFile(path.join(directory, "source.pdf"))).byteLength).toBeGreaterThan(0);
|
|
const images = await run("PDF_GetPdfImg", { fileInPath: filePath, pdfRange: "all", pdfNum: "1", imgSavePath: directory, imageType: "png" }) as string[];
|
|
expect(images.length).toBeGreaterThan(0);
|
|
expect((await readFile(images[0])).subarray(0, 4)).toEqual(Buffer.from([0x89, 0x50, 0x4e, 0x47]));
|
|
|
|
await expect(run("PDF_GetPdfTable", { fileInPath: filePath, pdfRange: "all", pdfNum: "1" })).resolves.toEqual([["Name", "Age"], ["Alice", "30"]]);
|
|
|
|
const encryptedPath = path.join(directory, "encrypted.pdf");
|
|
await writeFile(encryptedPath, await readFile(filePath));
|
|
await expect(run("PDF_PdfEncryption", { fileInPath: encryptedPath, passWord: "secret" })).resolves.toBe(encryptedPath);
|
|
const pdfjs = await import("pdfjs-dist/legacy/build/pdf.mjs");
|
|
const opened = await pdfjs.getDocument({ data: new Uint8Array(await readFile(encryptedPath)), password: "secret" }).promise;
|
|
expect(opened.numPages).toBe(1);
|
|
}, 60000);
|
|
});
|
|
async function mkdtempSafe(): Promise<string> {
|
|
const directory = await (await import("node:fs/promises")).mkdtemp(path.join(os.tmpdir(), "rpa-pdf-high-"));
|
|
directories.push(directory);
|
|
return directory;
|
|
}
|