Files
NetMesh/electron/bridges/terminalBridge/pathValidation.cjs
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

88 lines
3.4 KiB
JavaScript

/* eslint-disable no-undef */
function createPathValidationApi(ctx) {
with (ctx) {
function getDefaultShell() {
return getDefaultLocalShell();
}
/**
* Validate a path - check if it exists and whether it's a file or directory
* @param {object} event - IPC event
* @param {object} payload - Contains { path: string, type?: 'file' | 'directory' | 'any' }
* @returns {{ exists: boolean, isFile: boolean, isDirectory: boolean, isExecutable: boolean }}
*
* `isExecutable` mirrors isExecutableFile(): POSIX requires the file mode
* to have an execute bit; Win32 treats any regular file as executable
* (NTFS lacks POSIX bits — extension/PATHEXT decides at spawn time).
* Existing callers ignore the new field; consumers that need exec
* semantics (e.g. Mosh client path) read it explicitly.
*/
function statIsExecutable(stat) {
if (!stat || !stat.isFile()) return false;
if (process.platform === "win32") return true;
return (stat.mode & 0o111) !== 0;
}
function validatePath(event, payload) {
const targetPath = payload?.path;
const type = payload?.type || 'any';
if (!targetPath) {
return { exists: false, isFile: false, isDirectory: false, isExecutable: false };
}
try {
// Resolve path (handle ~, etc.)
let resolvedPath = expandHomePath(targetPath);
resolvedPath = path.resolve(resolvedPath);
if (fs.existsSync(resolvedPath)) {
const stat = fs.statSync(resolvedPath);
return {
exists: true,
isFile: stat.isFile(),
isDirectory: stat.isDirectory(),
isExecutable: statIsExecutable(stat),
};
}
// If type is 'file' and path doesn't exist, try to resolve via PATH (for executables like cmd.exe, powershell.exe)
if (type === 'file') {
const resolvedExecutable = findExecutable(targetPath);
// findExecutable returns the original name if not found, so check if it actually resolves to a real path
if (resolvedExecutable !== targetPath && fs.existsSync(resolvedExecutable)) {
const stat = fs.statSync(resolvedExecutable);
return {
exists: true,
isFile: stat.isFile(),
isDirectory: stat.isDirectory(),
isExecutable: statIsExecutable(stat),
};
}
// Also try with .exe extension on Windows if not already present
if (process.platform === 'win32' && !targetPath.toLowerCase().endsWith('.exe')) {
const withExe = findExecutable(targetPath + '.exe');
if (withExe !== targetPath + '.exe' && fs.existsSync(withExe)) {
const stat = fs.statSync(withExe);
return {
exists: true,
isFile: stat.isFile(),
isDirectory: stat.isDirectory(),
isExecutable: statIsExecutable(stat),
};
}
}
}
return { exists: false, isFile: false, isDirectory: false, isExecutable: false };
} catch (err) {
console.warn(`[Terminal] Error validating path "${targetPath}":`, err.message);
return { exists: false, isFile: false, isDirectory: false, isExecutable: false };
}
}
return { getDefaultShell, validatePath };
}
}
module.exports = { createPathValidationApi };