diff --git a/src/main/filesystem.ts b/src/main/filesystem.ts index c284cd4e..d5d3833a 100644 --- a/src/main/filesystem.ts +++ b/src/main/filesystem.ts @@ -19,6 +19,7 @@ import { import { encrypt } from './utils/safeStorage'; import { LastFMSessionData } from '../@types/last_fm_api'; import { DEFAULT_SONG_PALETTE } from './other/generatePalette'; +import isPathADir from './utils/isPathADir'; export const DEFAULT_ARTWORK_SAVE_LOCATION = path.join(app.getPath('userData'), 'song_covers'); export const DEFAULT_FILE_URL = 'nora://localfiles/'; @@ -569,7 +570,7 @@ function flattenPathArrays(lists: Type) { export const getDirectories = async (srcpath: string) => { try { const dirs = await fs.readdir(srcpath, { withFileTypes: true }); - const filteredDirs = dirs.filter((dir) => dir.isDirectory()); + const filteredDirs = dirs.filter((dir) => isPathADir(dir)); const dirsWithFullPaths = filteredDirs.map((dir) => path.join(srcpath, dir.name)); return dirsWithFullPaths; diff --git a/src/main/utils/copyDir.ts b/src/main/utils/copyDir.ts index 75188fff..fff9a0d9 100644 --- a/src/main/utils/copyDir.ts +++ b/src/main/utils/copyDir.ts @@ -4,6 +4,7 @@ import fs from 'fs/promises'; import log from '../log'; import makeDir from './makeDir'; +import isPathADir from './isPathADir'; async function copyDir(src: string, dest: string) { try { @@ -16,7 +17,7 @@ async function copyDir(src: string, dest: string) { const srcPath = path.join(src, entry.name); const destPath = path.join(dest, entry.name); - if (entry.isDirectory()) await copyDir(srcPath, destPath); + if (isPathADir(entry)) await copyDir(srcPath, destPath); else await fs.copyFile(srcPath, destPath); } } catch (error) { diff --git a/src/main/utils/getDirSize.ts b/src/main/utils/getDirSize.ts index 89ef23d8..a9605ed9 100644 --- a/src/main/utils/getDirSize.ts +++ b/src/main/utils/getDirSize.ts @@ -1,6 +1,7 @@ import fs from 'fs/promises'; import path from 'path'; import { isAnErrorWithCode } from './isAnErrorWithCode'; +import isPathADir from './isPathADir'; const getDirSize = async (dir: string) => { try { @@ -10,7 +11,7 @@ const getDirSize = async (dir: string) => { try { const filepath = path.join(dir, file.name); - if (file.isDirectory()) return getDirSize(filepath); + if (isPathADir(file)) return getDirSize(filepath); if (file.isFile()) { const { size } = await fs.stat(filepath); return size; diff --git a/src/main/utils/isPathADir.ts b/src/main/utils/isPathADir.ts new file mode 100644 index 00000000..2e3074e2 --- /dev/null +++ b/src/main/utils/isPathADir.ts @@ -0,0 +1,35 @@ +import path from 'path'; +import fs, { Dirent } from 'fs'; + +const isPathADir = (pathOrDir: string | Dirent) => { + try { + if (typeof pathOrDir === 'string') { + const stat = fs.statSync(pathOrDir); + + if (stat.isDirectory()) return true; + + if (!stat.isSymbolicLink()) return false; + + const symlinkTarget = fs.readlinkSync(pathOrDir); + + const symlinkStat = fs.statSync(symlinkTarget); + + return symlinkStat.isDirectory(); + } + + if (pathOrDir.isDirectory()) return true; + + if (!pathOrDir.isSymbolicLink()) return false; + + const symlinkPath = path.join(pathOrDir.path, pathOrDir.name); + + const symlinkStat = fs.statSync(symlinkPath); + + return symlinkStat.isDirectory(); + } catch { + return false; + } +}; + +export default isPathADir; +