platform-paths
Version:
Retrieve paths to common media folders on each platform.
120 lines (119 loc) • 4.99 kB
JavaScript
;
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);
}