UNPKG

platform-paths

Version:

Retrieve paths to common media folders on each platform.

120 lines (119 loc) 4.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isPlatformPathIdentifier = exports.clearCache = exports.platformPaths = exports.getDesktopPath = exports.getVideosPath = exports.getMusicPath = exports.getPicturesPath = exports.getDocumentsPath = exports.getDownloadsPath = exports.getHomePath = exports.getTmpPath = exports.getPlatformPath = void 0; const OS = require("os"); const CP = require("child_process"); const fs_1 = require("fs"); const util_1 = require("util"); const exec = (0, util_1.promisify)(CP.exec); const cachedPaths = new Map(); const getters = { tmp: async () => OS.tmpdir(), home: async () => OS.homedir(), downloads: () => getPath('Downloads', 'Downloads', 'DOWNLOAD', 'Downloads', '/tmp/'), documents: () => getPath('Personal', 'Documents', 'DOCUMENTS', 'Documents'), pictures: () => getPath('My Pictures', 'Pictures', 'PICTURES', 'Pictures'), music: () => getPath('My Music', 'Music', 'MUSIC', 'Music'), videos: () => getPath('My Video', 'Videos', 'VIDEOS', 'Videos'), desktop: () => getPath('Desktop', 'Desktop', 'DESKTOP', 'Desktop'), }; async function getPlatformPath(name, { maxAge = 0 } = {}) { if (!isPlatformPathIdentifier(name)) throw new Error(`Unknown platform path identifier "${name}".`); const cached = cachedPaths.get(name); if (cached && Date.now() - cached.createdAt < maxAge) return cached.value; const value = await getters[name](); cachedPaths.set(name, { value, createdAt: Date.now() }); return value; } exports.getPlatformPath = getPlatformPath; const getTmpPath = (options) => getPlatformPath('tmp', options); exports.getTmpPath = getTmpPath; const getHomePath = (options) => getPlatformPath('home', options); exports.getHomePath = getHomePath; const getDownloadsPath = (options) => getPlatformPath('downloads', options); exports.getDownloadsPath = getDownloadsPath; const getDocumentsPath = (options) => getPlatformPath('documents', options); exports.getDocumentsPath = getDocumentsPath; const getPicturesPath = (options) => getPlatformPath('pictures', options); exports.getPicturesPath = getPicturesPath; const getMusicPath = (options) => getPlatformPath('music', options); exports.getMusicPath = getMusicPath; const getVideosPath = (options) => getPlatformPath('videos', options); exports.getVideosPath = getVideosPath; const getDesktopPath = (options) => getPlatformPath('desktop', options); exports.getDesktopPath = getDesktopPath; exports.platformPaths = { tmp: exports.getTmpPath, home: exports.getHomePath, downloads: exports.getDownloadsPath, documents: exports.getDocumentsPath, pictures: exports.getPicturesPath, music: exports.getMusicPath, videos: exports.getVideosPath, desktop: exports.getDesktopPath, }; function clearCache() { cachedPaths.clear(); } exports.clearCache = clearCache; function isPlatformPathIdentifier(name) { return getters.hasOwnProperty(name); } exports.isPlatformPathIdentifier = isPlatformPathIdentifier; async function getPath(winName, darwinName, xdgName, linuxName, linuxBackup) { switch (OS.platform()) { case 'win32': return getWinRegistryPath(winName); case 'darwin': return `${OS.homedir()}/${darwinName}`; case 'linux': return getLinuxPath(xdgName, linuxName, linuxBackup); } throw new Error(`Unsupported platform.`); } async function getLinuxPath(xdgName, folderName, fallback) { const homeDir = OS.homedir(); try { let path = (await exec(`xdg-user-dir ${xdgName}`, { encoding: 'utf8' })).stdout.trim(); if (path && path !== homeDir) return path; } catch (_a) { } try { const path = `${homeDir}/${folderName}`; if ((await fs_1.promises.stat(path)).isDirectory()) return path; } catch (_b) { } if (fallback) return fallback; throw new Error(`Couldn't resolve Documents directory.`); } async function getWinRegistryPath(name) { const key = name === 'Downloads' ? '{374DE290-123F-4565-9164-39C4925E467B}' : name; const homeDir = OS.homedir(); const { stdout, stderr } = await exec(`reg query "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"`); if (stderr) throw new Error(stderr); let value; for (const line of stdout.split('\r\n').map(line => line.trim())) { if (!line.startsWith(key)) continue; const parts = line.split(/ +REG_EXPAND_SZ +/); if (parts.length === 2) { value = parts[1]; break; } else { throw new Error(`Unexpected registry output:\n${line}`); } } if (!value) { if (name === 'Downloads') return `${homeDir}\\Downloads`; throw new Error(`No registry match for "${name}". stdout:\n\n${stdout}`); } return value.replace('%USERPROFILE%', homeDir); }