import fs from 'fs'; import os from 'os'; import path from 'path'; const PACKAGED_DATA_DIRECTORY_NAME = 'MetoYou Server'; type PackagedProcess = NodeJS.Process & { pkg?: unknown }; function uniquePaths(paths: string[]): string[] { return [...new Set(paths.map((candidate) => path.resolve(candidate)))]; } export function isPackagedRuntime(): boolean { return Boolean((process as PackagedProcess).pkg); } export function getRuntimeBaseDir(): string { return isPackagedRuntime() ? path.dirname(process.execPath) : process.cwd(); } export function resolveRuntimePath(...segments: string[]): string { return path.join(getRuntimeBaseDir(), ...segments); } function resolvePackagedDataDirectory(): string { const homeDirectory = os.homedir(); switch (process.platform) { case 'win32': return path.join( process.env.APPDATA || path.join(homeDirectory, 'AppData', 'Roaming'), PACKAGED_DATA_DIRECTORY_NAME ); case 'darwin': return path.join(homeDirectory, 'Library', 'Application Support', PACKAGED_DATA_DIRECTORY_NAME); default: return path.join( process.env.XDG_DATA_HOME || path.join(homeDirectory, '.local', 'share'), PACKAGED_DATA_DIRECTORY_NAME ); } } export function resolvePersistentDataPath(...segments: string[]): string { if (!isPackagedRuntime()) { return resolveRuntimePath(...segments); } return path.join(resolvePackagedDataDirectory(), ...segments); } export function resolveProjectRootPath(...segments: string[]): string { return path.resolve(__dirname, '..', '..', ...segments); } export function findExistingPath(...candidates: string[]): string | null { for (const candidate of uniquePaths(candidates)) { if (fs.existsSync(candidate)) { return candidate; } } return null; } export function resolveEnvFilePath(): string { if (isPackagedRuntime()) { return resolveRuntimePath('.env'); } return findExistingPath( resolveRuntimePath('.env'), resolveProjectRootPath('.env') ) ?? resolveProjectRootPath('.env'); } export function resolveCertificateDirectory(): string { if (isPackagedRuntime()) { return resolveRuntimePath('.certs'); } return findExistingPath( resolveRuntimePath('.certs'), resolveProjectRootPath('.certs') ) ?? resolveRuntimePath('.certs'); }