feat: 画布式 RPA 桌面端 Day1(1016 目录/画布/容器/属性/持久化)

This commit is contained in:
yu committed 2026-10-26 14:38:17 +08:00
commit 32ca0a1af8
34 files changed
+15141

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
import { app } from "electron";
import fs from "node:fs";
import path from "node:path";
import type { Catalog, CatalogComponent } from "../shared/types";
let cached: Catalog | null = null;
function resolveCatalogPath(): string {
const candidates = [
process.env.RPA_CATALOG_PATH,
path.join(process.resourcesPath, "catalog.json"),
path.join(app.getAppPath(), "resources", "catalog.json"),
path.join(__dirname, "../../resources/catalog.json")
].filter(Boolean) as string[];
for (const candidate of candidates) {
if (fs.existsSync(candidate)) return candidate;
}
throw new Error(`catalog.json not found; tried: ${candidates.join(", ")}`);
}
/**
* 已注册执行器的函数名。Day 2 起由 capabilities 注册表汇总;
* Day 1 先标出控制/触发与少量基础组件,保证目录状态可演示。
*/
const EXECUTABLE_FUNCTIONS = new Set<string>([
"Trigger.Manual",
"Trigger.Schedule",
"Trigger.FileArrival",
"logic_control_if_else",
"logic_control_count_for",
"logic_control_array_for_v3",
"logic_control_while",
"logic_control_try_catch",
"logic_control_var",
"logic_control_break_for",
"logic_control_next_for",
"logic_control_stop",
"Basic_Delay_V2",
"Basic_SetVariable",
"Basic_DebugOutput"
]);
export function catalogPath(): string {
return resolveCatalogPath();
}
export function loadCatalog(): Catalog {
if (cached) return cached;
const raw = fs.readFileSync(catalogPath(), "utf8");
const catalog = JSON.parse(raw) as Catalog;
catalog.components = catalog.components.map((component: CatalogComponent) => ({
...component,
implemented: EXECUTABLE_FUNCTIONS.has(component.functionName) || EXECUTABLE_FUNCTIONS.has(component.id)
}));
cached = catalog;
return catalog;
}
export function markImplemented(functionNames: Iterable<string>): void {
for (const name of functionNames) EXECUTABLE_FUNCTIONS.add(name);
cached = null;
}