Z ZPI 文档 v0.3.8
介绍页

源码

packages/desktop/src/main/file-actions.ts

typescript44 行查看原文
import { stat } from "node:fs/promises";
import { isAbsolute, relative } from "node:path";
import type { FileLocation } from "@zpi-dev/ui/links";
import { localFileCandidate, resolveLocalFilePath, validateFileLocation } from "./local-file-path.ts";

interface FileActionServices {
  openPath(path: string, location?: FileLocation): Promise<string>;
  showItemInFolder(path: string): void;
  writeText(text: string): void;
}

export async function performFileAction(
  cwd: string,
  target: string,
  action: string,
  services: FileActionServices,
  input?: unknown,
): Promise<void> {
  if (
    !target ||
    target.length > 8192 ||
    /[\0\r\n]/.test(target) ||
    !["open", "reveal", "copy-absolute", "copy-relative"].includes(action)
  )
    throw new Error("invalid_input: 文件操作无效");
  const location = validateFileLocation(input);
  const bounded = location?.relative || !isAbsolute(target);
  const path = localFileCandidate(cwd, target, bounded);
  if (action === "copy-absolute" || action === "copy-relative") {
    services.writeText(action === "copy-absolute" ? path : relative(cwd, path) || ".");
    return;
  }
  const actual = await resolveLocalFilePath(cwd, target, bounded);
  const info = await stat(actual);
  const directory = info.isDirectory();
  if (!info.isFile() && !directory) throw new Error("invalid_input: 仅支持打开文件及文件夹");
  if (action === "reveal" && !directory) services.showItemInFolder(path);
  else {
    const failure =
      !directory && location?.line ? await services.openPath(path, location) : await services.openPath(path);
    if (failure) throw new Error(`storage: ${failure}`);
  }
}