Browse Source

Switch to async fs.exists

We cannot expose the sync version over the context bridge - the node:fs module
is not available to the preload script under context isolation.
Manav Rathi 1 year ago
parent
commit
f21dc84840

+ 0 - 3
desktop/src/preload.ts

@@ -168,8 +168,6 @@ const writeNodeStream = async (
 
 
 // - Export
 // - Export
 
 
-const exists = (path: string) => existsSync(path);
-
 const checkExistsAndCreateDir = (dirPath: string) =>
 const checkExistsAndCreateDir = (dirPath: string) =>
     fs.mkdir(dirPath, { recursive: true });
     fs.mkdir(dirPath, { recursive: true });
 
 
@@ -442,7 +440,6 @@ contextBridge.exposeInMainWorld("ElectronAPIs", {
     },
     },
 
 
     // - Export
     // - Export
-    exists,
     checkExistsAndCreateDir,
     checkExistsAndCreateDir,
     saveStreamToDisk,
     saveStreamToDisk,
     saveFileToDisk,
     saveFileToDisk,

+ 6 - 6
web/apps/photos/src/components/ExportModal.tsx

@@ -98,8 +98,8 @@ export default function ExportModal(props: Props) {
     // HELPER FUNCTIONS
     // HELPER FUNCTIONS
     // =======================
     // =======================
 
 
-    const verifyExportFolderExists = () => {
-        if (!exportService.exportFolderExists(exportFolder)) {
+    const verifyExportFolderExists = async () => {
+        if (!(await exportService.exportFolderExists(exportFolder))) {
             appContext.setDialogMessage(
             appContext.setDialogMessage(
                 getExportDirectoryDoesNotExistMessage(),
                 getExportDirectoryDoesNotExistMessage(),
             );
             );
@@ -109,7 +109,7 @@ export default function ExportModal(props: Props) {
 
 
     const syncExportRecord = async (exportFolder: string): Promise<void> => {
     const syncExportRecord = async (exportFolder: string): Promise<void> => {
         try {
         try {
-            if (!exportService.exportFolderExists(exportFolder)) {
+            if (!(await exportService.exportFolderExists(exportFolder))) {
                 const pendingExports =
                 const pendingExports =
                     await exportService.getPendingExports(null);
                     await exportService.getPendingExports(null);
                 setPendingExports(pendingExports);
                 setPendingExports(pendingExports);
@@ -145,9 +145,9 @@ export default function ExportModal(props: Props) {
         }
         }
     };
     };
 
 
-    const toggleContinuousExport = () => {
+    const toggleContinuousExport = async () => {
         try {
         try {
-            verifyExportFolderExists();
+            await verifyExportFolderExists();
             const newContinuousExport = !continuousExport;
             const newContinuousExport = !continuousExport;
             if (newContinuousExport) {
             if (newContinuousExport) {
                 exportService.enableContinuousExport();
                 exportService.enableContinuousExport();
@@ -162,7 +162,7 @@ export default function ExportModal(props: Props) {
 
 
     const startExport = async () => {
     const startExport = async () => {
         try {
         try {
-            verifyExportFolderExists();
+            await verifyExportFolderExists();
             await exportService.scheduleExport();
             await exportService.scheduleExport();
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {

+ 5 - 1
web/apps/photos/src/pages/_app.tsx

@@ -241,7 +241,11 @@ export default function App(props: EnteAppProps) {
                 }
                 }
                 await DownloadManager.init(APPS.PHOTOS, { token });
                 await DownloadManager.init(APPS.PHOTOS, { token });
                 const exportSettings = exportService.getExportSettings();
                 const exportSettings = exportService.getExportSettings();
-                if (!exportService.exportFolderExists(exportSettings?.folder)) {
+                if (
+                    !(await exportService.exportFolderExists(
+                        exportSettings?.folder,
+                    ))
+                ) {
                     return;
                     return;
                 }
                 }
                 const exportRecord = await exportService.getExportRecord(
                 const exportRecord = await exportService.getExportRecord(

+ 39 - 34
web/apps/photos/src/services/export/index.ts

@@ -245,7 +245,7 @@ class ExportService {
     };
     };
 
 
     async preExport(exportFolder: string) {
     async preExport(exportFolder: string) {
-        this.verifyExportFolderExists(exportFolder);
+        await this.verifyExportFolderExists(exportFolder);
         const exportRecord = await this.getExportRecord(exportFolder);
         const exportRecord = await this.getExportRecord(exportFolder);
         await this.updateExportStage(ExportStage.MIGRATION);
         await this.updateExportStage(ExportStage.MIGRATION);
         await this.runMigration(
         await this.runMigration(
@@ -259,7 +259,7 @@ class ExportService {
     async postExport() {
     async postExport() {
         try {
         try {
             const exportFolder = this.getExportSettings()?.folder;
             const exportFolder = this.getExportSettings()?.folder;
-            if (!this.exportFolderExists(exportFolder)) {
+            if (!(await this.exportFolderExists(exportFolder))) {
                 this.uiUpdater.setExportStage(ExportStage.INIT);
                 this.uiUpdater.setExportStage(ExportStage.INIT);
                 return;
                 return;
             }
             }
@@ -484,7 +484,7 @@ class ExportService {
                     if (isCanceled.status) {
                     if (isCanceled.status) {
                         throw Error(CustomError.EXPORT_STOPPED);
                         throw Error(CustomError.EXPORT_STOPPED);
                     }
                     }
-                    this.verifyExportFolderExists(exportFolder);
+                    await this.verifyExportFolderExists(exportFolder);
                     const oldCollectionExportName =
                     const oldCollectionExportName =
                         collectionIDExportNameMap.get(collection.id);
                         collectionIDExportNameMap.get(collection.id);
                     const oldCollectionExportPath = getCollectionExportPath(
                     const oldCollectionExportPath = getCollectionExportPath(
@@ -493,7 +493,7 @@ class ExportService {
                     );
                     );
 
 
                     const newCollectionExportName =
                     const newCollectionExportName =
-                        getUniqueCollectionExportName(
+                        await getUniqueCollectionExportName(
                             exportFolder,
                             exportFolder,
                             getCollectionUserFacingName(collection),
                             getCollectionUserFacingName(collection),
                         );
                         );
@@ -574,7 +574,7 @@ class ExportService {
                     if (isCanceled.status) {
                     if (isCanceled.status) {
                         throw Error(CustomError.EXPORT_STOPPED);
                         throw Error(CustomError.EXPORT_STOPPED);
                     }
                     }
-                    this.verifyExportFolderExists(exportFolder);
+                    await this.verifyExportFolderExists(exportFolder);
                     addLogLine(
                     addLogLine(
                         `removing collection with id ${collectionID} from export folder`,
                         `removing collection with id ${collectionID} from export folder`,
                     );
                     );
@@ -662,7 +662,7 @@ class ExportService {
                     throw Error(CustomError.EXPORT_STOPPED);
                     throw Error(CustomError.EXPORT_STOPPED);
                 }
                 }
                 try {
                 try {
-                    this.verifyExportFolderExists(exportDir);
+                    await this.verifyExportFolderExists(exportDir);
                     let collectionExportName = collectionIDFolderNameMap.get(
                     let collectionExportName = collectionIDFolderNameMap.get(
                         file.collectionID,
                         file.collectionID,
                     );
                     );
@@ -743,7 +743,7 @@ class ExportService {
                 exportRecord.fileExportNames,
                 exportRecord.fileExportNames,
             );
             );
             for (const fileUID of removedFileUIDs) {
             for (const fileUID of removedFileUIDs) {
-                this.verifyExportFolderExists(exportDir);
+                await this.verifyExportFolderExists(exportDir);
                 addLogLine(`trashing file with id ${fileUID}`);
                 addLogLine(`trashing file with id ${fileUID}`);
                 if (isCanceled.status) {
                 if (isCanceled.status) {
                     throw Error(CustomError.EXPORT_STOPPED);
                     throw Error(CustomError.EXPORT_STOPPED);
@@ -769,10 +769,10 @@ class ExportService {
                             addLogLine(
                             addLogLine(
                                 `moving image file ${imageExportPath} to trash folder`,
                                 `moving image file ${imageExportPath} to trash folder`,
                             );
                             );
-                            if (this.exists(imageExportPath)) {
+                            if (await this.exists(imageExportPath)) {
                                 await ElectronAPIs.moveFile(
                                 await ElectronAPIs.moveFile(
                                     imageExportPath,
                                     imageExportPath,
-                                    getTrashedFileExportPath(
+                                    await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
                                         imageExportPath,
                                         imageExportPath,
                                     ),
                                     ),
@@ -782,10 +782,12 @@ class ExportService {
                             const imageMetadataFileExportPath =
                             const imageMetadataFileExportPath =
                                 getMetadataFileExportPath(imageExportPath);
                                 getMetadataFileExportPath(imageExportPath);
 
 
-                            if (this.exists(imageMetadataFileExportPath)) {
+                            if (
+                                await this.exists(imageMetadataFileExportPath)
+                            ) {
                                 await ElectronAPIs.moveFile(
                                 await ElectronAPIs.moveFile(
                                     imageMetadataFileExportPath,
                                     imageMetadataFileExportPath,
-                                    getTrashedFileExportPath(
+                                    await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
                                         imageMetadataFileExportPath,
                                         imageMetadataFileExportPath,
                                     ),
                                     ),
@@ -799,10 +801,10 @@ class ExportService {
                             addLogLine(
                             addLogLine(
                                 `moving video file ${videoExportPath} to trash folder`,
                                 `moving video file ${videoExportPath} to trash folder`,
                             );
                             );
-                            if (this.exists(videoExportPath)) {
+                            if (await this.exists(videoExportPath)) {
                                 await ElectronAPIs.moveFile(
                                 await ElectronAPIs.moveFile(
                                     videoExportPath,
                                     videoExportPath,
-                                    getTrashedFileExportPath(
+                                    await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
                                         videoExportPath,
                                         videoExportPath,
                                     ),
                                     ),
@@ -810,10 +812,12 @@ class ExportService {
                             }
                             }
                             const videoMetadataFileExportPath =
                             const videoMetadataFileExportPath =
                                 getMetadataFileExportPath(videoExportPath);
                                 getMetadataFileExportPath(videoExportPath);
-                            if (this.exists(videoMetadataFileExportPath)) {
+                            if (
+                                await this.exists(videoMetadataFileExportPath)
+                            ) {
                                 await ElectronAPIs.moveFile(
                                 await ElectronAPIs.moveFile(
                                     videoMetadataFileExportPath,
                                     videoMetadataFileExportPath,
-                                    getTrashedFileExportPath(
+                                    await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
                                         videoMetadataFileExportPath,
                                         videoMetadataFileExportPath,
                                     ),
                                     ),
@@ -824,14 +828,15 @@ class ExportService {
                                 collectionExportPath,
                                 collectionExportPath,
                                 fileExportName,
                                 fileExportName,
                             );
                             );
-                            const trashedFilePath = getTrashedFileExportPath(
-                                exportDir,
-                                fileExportPath,
-                            );
+                            const trashedFilePath =
+                                await getTrashedFileExportPath(
+                                    exportDir,
+                                    fileExportPath,
+                                );
                             addLogLine(
                             addLogLine(
                                 `moving file ${fileExportPath} to ${trashedFilePath} trash folder`,
                                 `moving file ${fileExportPath} to ${trashedFilePath} trash folder`,
                             );
                             );
-                            if (this.exists(fileExportPath)) {
+                            if (await this.exists(fileExportPath)) {
                                 await ElectronAPIs.moveFile(
                                 await ElectronAPIs.moveFile(
                                     fileExportPath,
                                     fileExportPath,
                                     trashedFilePath,
                                     trashedFilePath,
@@ -839,10 +844,10 @@ class ExportService {
                             }
                             }
                             const metadataFileExportPath =
                             const metadataFileExportPath =
                                 getMetadataFileExportPath(fileExportPath);
                                 getMetadataFileExportPath(fileExportPath);
-                            if (this.exists(metadataFileExportPath)) {
+                            if (await this.exists(metadataFileExportPath)) {
                                 await ElectronAPIs.moveFile(
                                 await ElectronAPIs.moveFile(
                                     metadataFileExportPath,
                                     metadataFileExportPath,
-                                    getTrashedFileExportPath(
+                                    await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
                                         metadataFileExportPath,
                                         metadataFileExportPath,
                                     ),
                                     ),
@@ -995,9 +1000,9 @@ class ExportService {
 
 
     async getExportRecord(folder: string, retry = true): Promise<ExportRecord> {
     async getExportRecord(folder: string, retry = true): Promise<ExportRecord> {
         try {
         try {
-            this.verifyExportFolderExists(folder);
+            await this.verifyExportFolderExists(folder);
             const exportRecordJSONPath = `${folder}/${EXPORT_RECORD_FILE_NAME}`;
             const exportRecordJSONPath = `${folder}/${EXPORT_RECORD_FILE_NAME}`;
-            if (!this.exists(exportRecordJSONPath)) {
+            if (!(await this.exists(exportRecordJSONPath))) {
                 return this.createEmptyExportRecord(exportRecordJSONPath);
                 return this.createEmptyExportRecord(exportRecordJSONPath);
             }
             }
             const recordFile =
             const recordFile =
@@ -1027,9 +1032,9 @@ class ExportService {
         collectionID: number,
         collectionID: number,
         collectionIDNameMap: Map<number, string>,
         collectionIDNameMap: Map<number, string>,
     ) {
     ) {
-        this.verifyExportFolderExists(exportFolder);
+        await this.verifyExportFolderExists(exportFolder);
         const collectionName = collectionIDNameMap.get(collectionID);
         const collectionName = collectionIDNameMap.get(collectionID);
-        const collectionExportName = getUniqueCollectionExportName(
+        const collectionExportName = await getUniqueCollectionExportName(
             exportFolder,
             exportFolder,
             collectionName,
             collectionName,
         );
         );
@@ -1070,7 +1075,7 @@ class ExportService {
                     file,
                     file,
                 );
                 );
             } else {
             } else {
-                const fileExportName = getUniqueFileExportName(
+                const fileExportName = await getUniqueFileExportName(
                     collectionExportPath,
                     collectionExportPath,
                     file.metadata.title,
                     file.metadata.title,
                 );
                 );
@@ -1109,11 +1114,11 @@ class ExportService {
     ) {
     ) {
         const fileBlob = await new Response(fileStream).blob();
         const fileBlob = await new Response(fileStream).blob();
         const livePhoto = await decodeLivePhoto(file, fileBlob);
         const livePhoto = await decodeLivePhoto(file, fileBlob);
-        const imageExportName = getUniqueFileExportName(
+        const imageExportName = await getUniqueFileExportName(
             collectionExportPath,
             collectionExportPath,
             livePhoto.imageNameTitle,
             livePhoto.imageNameTitle,
         );
         );
-        const videoExportName = getUniqueFileExportName(
+        const videoExportName = await getUniqueFileExportName(
             collectionExportPath,
             collectionExportPath,
             livePhoto.videoNameTitle,
             livePhoto.videoNameTitle,
         );
         );
@@ -1177,7 +1182,7 @@ class ExportService {
     };
     };
 
 
     exists = (path: string) => {
     exists = (path: string) => {
-        return ElectronAPIs.exists(path);
+        return ElectronAPIs.fs.exists(path);
     };
     };
 
 
     rename = (oldPath: string, newPath: string) => {
     rename = (oldPath: string, newPath: string) => {
@@ -1188,13 +1193,13 @@ class ExportService {
         return ElectronAPIs.checkExistsAndCreateDir(path);
         return ElectronAPIs.checkExistsAndCreateDir(path);
     };
     };
 
 
-    exportFolderExists = (exportFolder: string) => {
-        return exportFolder && this.exists(exportFolder);
+    exportFolderExists = async (exportFolder: string) => {
+        return exportFolder && (await this.exists(exportFolder));
     };
     };
 
 
-    private verifyExportFolderExists = (exportFolder: string) => {
+    private verifyExportFolderExists = async (exportFolder: string) => {
         try {
         try {
-            if (!this.exportFolderExists(exportFolder)) {
+            if (!(await this.exportFolderExists(exportFolder))) {
                 throw Error(CustomError.EXPORT_FOLDER_DOES_NOT_EXIST);
                 throw Error(CustomError.EXPORT_FOLDER_DOES_NOT_EXIST);
             }
             }
         } catch (e) {
         } catch (e) {

+ 24 - 14
web/apps/photos/src/services/export/migration.ts

@@ -195,7 +195,7 @@ async function migrationV4ToV5(exportDir: string, exportRecord: ExportRecord) {
 }
 }
 
 
 /*
 /*
-    This updates the folder name of already exported folders from the earlier format of 
+    This updates the folder name of already exported folders from the earlier format of
     `collectionID_collectionName` to newer `collectionName(numbered)` format
     `collectionID_collectionName` to newer `collectionName(numbered)` format
 */
 */
 async function migrateCollectionFolders(
 async function migrateCollectionFolders(
@@ -209,12 +209,12 @@ async function migrateCollectionFolders(
             collection.id,
             collection.id,
             collection.name,
             collection.name,
         );
         );
-        const newCollectionExportPath = getUniqueCollectionFolderPath(
+        const newCollectionExportPath = await getUniqueCollectionFolderPath(
             exportDir,
             exportDir,
             collection.name,
             collection.name,
         );
         );
         collectionIDPathMap.set(collection.id, newCollectionExportPath);
         collectionIDPathMap.set(collection.id, newCollectionExportPath);
-        if (!exportService.exists(oldCollectionExportPath)) {
+        if (!(await exportService.exists(oldCollectionExportPath))) {
             continue;
             continue;
         }
         }
         await exportService.rename(
         await exportService.rename(
@@ -230,7 +230,7 @@ async function migrateCollectionFolders(
 }
 }
 
 
 /*
 /*
-    This updates the file name of already exported files from the earlier format of 
+    This updates the file name of already exported files from the earlier format of
     `fileID_fileName` to newer `fileName(numbered)` format
     `fileID_fileName` to newer `fileName(numbered)` format
 */
 */
 async function migrateFiles(
 async function migrateFiles(
@@ -246,7 +246,7 @@ async function migrateFiles(
             collectionIDPathMap.get(file.collectionID),
             collectionIDPathMap.get(file.collectionID),
             file,
             file,
         );
         );
-        const newFileSaveName = getUniqueFileSaveName(
+        const newFileSaveName = await getUniqueFileSaveName(
             collectionIDPathMap.get(file.collectionID),
             collectionIDPathMap.get(file.collectionID),
             file.metadata.title,
             file.metadata.title,
         );
         );
@@ -260,7 +260,7 @@ async function migrateFiles(
             collectionIDPathMap.get(file.collectionID),
             collectionIDPathMap.get(file.collectionID),
             newFileSaveName,
             newFileSaveName,
         );
         );
-        if (!exportService.exists(oldFileSavePath)) {
+        if (!(await exportService.exists(oldFileSavePath))) {
             continue;
             continue;
         }
         }
         await exportService.rename(oldFileSavePath, newFileSavePath);
         await exportService.rename(oldFileSavePath, newFileSavePath);
@@ -306,7 +306,7 @@ async function getCollectionExportNamesFromExportedCollectionPaths(
     return exportedCollectionNames;
     return exportedCollectionNames;
 }
 }
 
 
-/* 
+/*
     Earlier the file were sorted by id,
     Earlier the file were sorted by id,
     which we can use to determine which file got which number suffix
     which we can use to determine which file got which number suffix
     this can be used to determine the filepaths of the those already exported files
     this can be used to determine the filepaths of the those already exported files
@@ -432,17 +432,27 @@ async function removeCollectionExportMissingMetadataFolder(
         return;
         return;
     }
     }
 
 
-    const properlyExportedCollections = Object.entries(
+    const properlyExportedCollectionsAll = Object.entries(
         exportRecord.collectionExportNames,
         exportRecord.collectionExportNames,
-    )
-        // eslint-disable-next-line @typescript-eslint/no-unused-vars
-        .filter(([_, collectionExportName]) =>
-            exportService.exists(
+    );
+    const properlyExportedCollections = [];
+    for (const [
+        collectionID,
+        collectionExportName,
+    ] of properlyExportedCollectionsAll) {
+        if (
+            await exportService.exists(
                 getMetadataFolderExportPath(
                 getMetadataFolderExportPath(
                     getCollectionExportPath(exportDir, collectionExportName),
                     getCollectionExportPath(exportDir, collectionExportName),
                 ),
                 ),
-            ),
-        );
+            )
+        ) {
+            properlyExportedCollections.push([
+                collectionID,
+                collectionExportName,
+            ]);
+        }
+    }
 
 
     const properlyExportedCollectionIDs = properlyExportedCollections.map(
     const properlyExportedCollectionIDs = properlyExportedCollections.map(
         ([collectionID]) => collectionID,
         ([collectionID]) => collectionID,

+ 1 - 1
web/apps/photos/src/services/wasm/ffmpeg.ts

@@ -1,8 +1,8 @@
 import { addLogLine } from "@ente/shared/logging";
 import { addLogLine } from "@ente/shared/logging";
 import { logError } from "@ente/shared/sentry";
 import { logError } from "@ente/shared/sentry";
+import QueueProcessor from "@ente/shared/utils/queueProcessor";
 import { generateTempName } from "@ente/shared/utils/temp";
 import { generateTempName } from "@ente/shared/utils/temp";
 import { createFFmpeg, FFmpeg } from "ffmpeg-wasm";
 import { createFFmpeg, FFmpeg } from "ffmpeg-wasm";
-import QueueProcessor from "@ente/shared/utils/queueProcessor";
 import { getUint8ArrayView } from "services/readerService";
 import { getUint8ArrayView } from "services/readerService";
 import { promiseWithTimeout } from "utils/common";
 import { promiseWithTimeout } from "utils/common";
 
 

+ 1 - 1
web/apps/photos/src/utils/collection/index.ts

@@ -174,7 +174,7 @@ async function createCollectionDownloadFolder(
     downloadDirPath: string,
     downloadDirPath: string,
     collectionName: string,
     collectionName: string,
 ) {
 ) {
-    const collectionDownloadName = getUniqueCollectionExportName(
+    const collectionDownloadName = await getUniqueCollectionExportName(
         downloadDirPath,
         downloadDirPath,
         collectionName,
         collectionName,
     );
     );

+ 11 - 8
web/apps/photos/src/utils/export/index.ts

@@ -197,16 +197,16 @@ export const getGoogleLikeMetadataFile = (
 export const sanitizeName = (name: string) =>
 export const sanitizeName = (name: string) =>
     sanitize(name, { replacement: "_" });
     sanitize(name, { replacement: "_" });
 
 
-export const getUniqueCollectionExportName = (
+export const getUniqueCollectionExportName = async (
     dir: string,
     dir: string,
     collectionName: string,
     collectionName: string,
-): string => {
+): Promise<string> => {
     let collectionExportName = sanitizeName(collectionName);
     let collectionExportName = sanitizeName(collectionName);
     let count = 1;
     let count = 1;
     while (
     while (
-        exportService.exists(
+        (await exportService.exists(
             getCollectionExportPath(dir, collectionExportName),
             getCollectionExportPath(dir, collectionExportName),
-        ) ||
+        )) ||
         collectionExportName === ENTE_TRASH_FOLDER
         collectionExportName === ENTE_TRASH_FOLDER
     ) {
     ) {
         collectionExportName = `${sanitizeName(collectionName)}(${count})`;
         collectionExportName = `${sanitizeName(collectionName)}(${count})`;
@@ -218,14 +218,14 @@ export const getUniqueCollectionExportName = (
 export const getMetadataFolderExportPath = (collectionExportPath: string) =>
 export const getMetadataFolderExportPath = (collectionExportPath: string) =>
     `${collectionExportPath}/${ENTE_METADATA_FOLDER}`;
     `${collectionExportPath}/${ENTE_METADATA_FOLDER}`;
 
 
-export const getUniqueFileExportName = (
+export const getUniqueFileExportName = async (
     collectionExportPath: string,
     collectionExportPath: string,
     filename: string,
     filename: string,
 ) => {
 ) => {
     let fileExportName = sanitizeName(filename);
     let fileExportName = sanitizeName(filename);
     let count = 1;
     let count = 1;
     while (
     while (
-        exportService.exists(
+        await exportService.exists(
             getFileExportPath(collectionExportPath, fileExportName),
             getFileExportPath(collectionExportPath, fileExportName),
         )
         )
     ) {
     ) {
@@ -255,11 +255,14 @@ export const getFileExportPath = (
     fileExportName: string,
     fileExportName: string,
 ) => `${collectionExportPath}/${fileExportName}`;
 ) => `${collectionExportPath}/${fileExportName}`;
 
 
-export const getTrashedFileExportPath = (exportDir: string, path: string) => {
+export const getTrashedFileExportPath = async (
+    exportDir: string,
+    path: string,
+) => {
     const fileRelativePath = path.replace(`${exportDir}/`, "");
     const fileRelativePath = path.replace(`${exportDir}/`, "");
     let trashedFilePath = `${exportDir}/${ENTE_TRASH_FOLDER}/${fileRelativePath}`;
     let trashedFilePath = `${exportDir}/${ENTE_TRASH_FOLDER}/${fileRelativePath}`;
     let count = 1;
     let count = 1;
-    while (exportService.exists(trashedFilePath)) {
+    while (await exportService.exists(trashedFilePath)) {
         const trashedFilePathParts = splitFilenameAndExtension(trashedFilePath);
         const trashedFilePathParts = splitFilenameAndExtension(trashedFilePath);
         if (trashedFilePathParts[1]) {
         if (trashedFilePathParts[1]) {
             trashedFilePath = `${trashedFilePathParts[0]}(${count}).${trashedFilePathParts[1]}`;
             trashedFilePath = `${trashedFilePathParts[0]}(${count}).${trashedFilePathParts[1]}`;

+ 7 - 5
web/apps/photos/src/utils/export/migration.ts

@@ -41,13 +41,13 @@ export const getExportedFiles = (
 export const oldSanitizeName = (name: string) =>
 export const oldSanitizeName = (name: string) =>
     name.replaceAll("/", "_").replaceAll(" ", "_");
     name.replaceAll("/", "_").replaceAll(" ", "_");
 
 
-export const getUniqueCollectionFolderPath = (
+export const getUniqueCollectionFolderPath = async (
     dir: string,
     dir: string,
     collectionName: string,
     collectionName: string,
-): string => {
+): Promise<string> => {
     let collectionFolderPath = `${dir}/${sanitizeName(collectionName)}`;
     let collectionFolderPath = `${dir}/${sanitizeName(collectionName)}`;
     let count = 1;
     let count = 1;
-    while (exportService.exists(collectionFolderPath)) {
+    while (await exportService.exists(collectionFolderPath)) {
         collectionFolderPath = `${dir}/${sanitizeName(
         collectionFolderPath = `${dir}/${sanitizeName(
             collectionName,
             collectionName,
         )}(${count})`;
         )}(${count})`;
@@ -59,14 +59,16 @@ export const getUniqueCollectionFolderPath = (
 export const getMetadataFolderPath = (collectionFolderPath: string) =>
 export const getMetadataFolderPath = (collectionFolderPath: string) =>
     `${collectionFolderPath}/${ENTE_METADATA_FOLDER}`;
     `${collectionFolderPath}/${ENTE_METADATA_FOLDER}`;
 
 
-export const getUniqueFileSaveName = (
+export const getUniqueFileSaveName = async (
     collectionPath: string,
     collectionPath: string,
     filename: string,
     filename: string,
 ) => {
 ) => {
     let fileSaveName = sanitizeName(filename);
     let fileSaveName = sanitizeName(filename);
     let count = 1;
     let count = 1;
     while (
     while (
-        exportService.exists(getFileSavePath(collectionPath, fileSaveName))
+        await exportService.exists(
+            getFileSavePath(collectionPath, fileSaveName),
+        )
     ) {
     ) {
         const filenameParts = splitFilenameAndExtension(sanitizeName(filename));
         const filenameParts = splitFilenameAndExtension(sanitizeName(filename));
         if (filenameParts[1]) {
         if (filenameParts[1]) {

+ 3 - 3
web/apps/photos/src/utils/file/index.ts

@@ -778,7 +778,7 @@ export async function downloadFileDesktop(
     if (file.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
     if (file.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
         const fileBlob = await new Response(updatedFileStream).blob();
         const fileBlob = await new Response(updatedFileStream).blob();
         const livePhoto = await decodeLivePhoto(file, fileBlob);
         const livePhoto = await decodeLivePhoto(file, fileBlob);
-        const imageExportName = getUniqueFileExportName(
+        const imageExportName = await getUniqueFileExportName(
             downloadPath,
             downloadPath,
             livePhoto.imageNameTitle,
             livePhoto.imageNameTitle,
         );
         );
@@ -788,7 +788,7 @@ export async function downloadFileDesktop(
             imageStream,
             imageStream,
         );
         );
         try {
         try {
-            const videoExportName = getUniqueFileExportName(
+            const videoExportName = await getUniqueFileExportName(
                 downloadPath,
                 downloadPath,
                 livePhoto.videoNameTitle,
                 livePhoto.videoNameTitle,
             );
             );
@@ -804,7 +804,7 @@ export async function downloadFileDesktop(
             throw e;
             throw e;
         }
         }
     } else {
     } else {
-        const fileExportName = getUniqueFileExportName(
+        const fileExportName = await getUniqueFileExportName(
             downloadPath,
             downloadPath,
             file.metadata.title,
             file.metadata.title,
         );
         );

+ 0 - 1
web/packages/shared/electron/types.ts

@@ -79,7 +79,6 @@ export interface ElectronAPIsType {
     };
     };
 
 
     /** TODO: AUDIT below this */
     /** TODO: AUDIT below this */
-    exists: (path: string) => boolean;
     checkExistsAndCreateDir: (dirPath: string) => Promise<void>;
     checkExistsAndCreateDir: (dirPath: string) => Promise<void>;
     saveStreamToDisk: (
     saveStreamToDisk: (
         path: string,
         path: string,