chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
import { app } from "electron";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import { spawn } from "child_process";
|
||||
import { getAppEnv } from "../system/dependencies";
|
||||
import { APP_DATA_DIR_NAME } from "../constants";
|
||||
import { isWindows } from "../system/shellEnv";
|
||||
|
||||
export interface AppPaths {
|
||||
appData: string; // 应用数据目录
|
||||
nodeModules: string; // 本地 node_modules
|
||||
temp: string; // 临时目录
|
||||
logs: string; // 日志目录
|
||||
workspaces: string; // 工作空间
|
||||
}
|
||||
|
||||
// Get application paths
|
||||
export function getAppPaths(): AppPaths {
|
||||
const appData =
|
||||
app?.getPath("userData") ||
|
||||
path.join(process.env.HOME || "", APP_DATA_DIR_NAME);
|
||||
|
||||
return {
|
||||
appData,
|
||||
nodeModules: path.join(appData, "node_modules"),
|
||||
temp: path.join(appData, "temp"),
|
||||
logs: path.join(appData, "logs"),
|
||||
workspaces: path.join(appData, "workspaces"),
|
||||
};
|
||||
}
|
||||
|
||||
// Ensure directories exist
|
||||
export function ensureAppDirs(): AppPaths {
|
||||
const dirs = getAppPaths();
|
||||
|
||||
for (const [key, dir] of Object.entries(dirs)) {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
return dirs;
|
||||
}
|
||||
|
||||
// Get npm/pnpm executable path (use local if available)
|
||||
export function getPackageManager(): string {
|
||||
// Check for pnpm first, then yarn, then npm
|
||||
const appDirs = getAppPaths();
|
||||
|
||||
// Check local installation
|
||||
const localNpm = path.join(appDirs.nodeModules, ".bin", "npm");
|
||||
const localPnpm = path.join(appDirs.nodeModules, ".bin", "pnpm");
|
||||
const localYarn = path.join(appDirs.nodeModules, ".bin", "yarn");
|
||||
|
||||
if (fs.existsSync(localPnpm)) return localPnpm;
|
||||
if (fs.existsSync(localYarn)) return localYarn;
|
||||
if (fs.existsSync(localNpm)) return localNpm;
|
||||
|
||||
// Fallback to system
|
||||
return isWindows() ? "npm.cmd" : "npm";
|
||||
}
|
||||
|
||||
// Install package locally (not globally)
|
||||
export async function installPackage(
|
||||
packageName: string,
|
||||
options?: {
|
||||
registry?: string;
|
||||
cwd?: string;
|
||||
},
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const dirs = ensureAppDirs();
|
||||
const cwd = options?.cwd || dirs.nodeModules;
|
||||
const registry = options?.registry;
|
||||
|
||||
// Ensure node_modules exists
|
||||
if (!fs.existsSync(cwd)) {
|
||||
fs.mkdirSync(cwd, { recursive: true });
|
||||
}
|
||||
|
||||
// Build command
|
||||
const npmCmd = isWindows() ? "npm.cmd" : "npm";
|
||||
const args = ["install", "--save", "--no-save", packageName];
|
||||
|
||||
if (registry) {
|
||||
args.push(`--registry=${registry}`);
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const proc = spawn(npmCmd, args, {
|
||||
cwd,
|
||||
env: {
|
||||
...process.env,
|
||||
...getAppEnv(),
|
||||
},
|
||||
stdio: "pipe",
|
||||
shell: isWindows(),
|
||||
});
|
||||
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
|
||||
proc.stdout?.on("data", (data) => {
|
||||
stdout += data.toString();
|
||||
});
|
||||
|
||||
proc.stderr?.on("data", (data) => {
|
||||
stderr += data.toString();
|
||||
});
|
||||
|
||||
proc.on("error", (error) => {
|
||||
console.error(`[Install] Error:`, error);
|
||||
resolve({ success: false, error: error.message });
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
resolve({ success: true });
|
||||
} else {
|
||||
console.error(`[Install] Failed: ${stderr}`);
|
||||
resolve({ success: false, error: stderr || "Install failed" });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Uninstall package
|
||||
export async function uninstallPackage(
|
||||
packageName: string,
|
||||
options?: {
|
||||
cwd?: string;
|
||||
},
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const dirs = getAppPaths();
|
||||
const cwd = options?.cwd || dirs.nodeModules;
|
||||
|
||||
const npmCmd = isWindows() ? "npm.cmd" : "npm";
|
||||
const args = ["uninstall", packageName];
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const proc = spawn(npmCmd, args, {
|
||||
cwd,
|
||||
env: { ...process.env, ...getAppEnv() },
|
||||
stdio: "pipe",
|
||||
shell: isWindows(),
|
||||
});
|
||||
|
||||
let stderr = "";
|
||||
|
||||
proc.stderr?.on("data", (data) => {
|
||||
stderr += data.toString();
|
||||
});
|
||||
|
||||
proc.on("error", (error) => {
|
||||
resolve({ success: false, error: error.message });
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
resolve({ success: true });
|
||||
} else {
|
||||
resolve({ success: false, error: stderr });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Check if package is installed locally
|
||||
export function isPackageInstalled(packageName: string): boolean {
|
||||
const dirs = getAppPaths();
|
||||
const packagePath = path.join(dirs.nodeModules, packageName);
|
||||
return fs.existsSync(packagePath);
|
||||
}
|
||||
|
||||
// Get installed packages
|
||||
export function getInstalledPackages(): string[] {
|
||||
const dirs = getAppPaths();
|
||||
const packageJsonPath = path.join(dirs.nodeModules, "package.json");
|
||||
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
||||
return [
|
||||
...Object.keys(packageJson.dependencies || {}),
|
||||
...Object.keys(packageJson.devDependencies || {}),
|
||||
];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up temporary files
|
||||
export function cleanupTemp(): void {
|
||||
const dirs = getAppPaths();
|
||||
|
||||
if (fs.existsSync(dirs.temp)) {
|
||||
fs.rmSync(dirs.temp, { recursive: true, force: true });
|
||||
fs.mkdirSync(dirs.temp, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAppPaths,
|
||||
ensureAppDirs,
|
||||
getPackageManager,
|
||||
installPackage,
|
||||
uninstallPackage,
|
||||
isPackageInstalled,
|
||||
getInstalledPackages,
|
||||
cleanupTemp,
|
||||
};
|
||||
Reference in New Issue
Block a user