@@ -70,6 +70,29 @@ console.log("Allowed origins:", allowedOrigins);
7070
7171const uploadDir = path . resolve ( __dirname , "../uploads" ) ;
7272
73+ const moveFile = async ( source : string , destination : string ) => {
74+ try {
75+ await fsPromises . rename ( source , destination ) ;
76+ } catch ( error ) {
77+ const err = error as NodeJS . ErrnoException ;
78+ if ( ! err || err . code !== "EXDEV" ) {
79+ throw error ;
80+ }
81+
82+ // Cross-device rename fallback: copy then delete source
83+ await fsPromises
84+ . unlink ( destination )
85+ . catch ( ( unlinkError : NodeJS . ErrnoException ) => {
86+ if ( unlinkError && unlinkError . code !== "ENOENT" ) {
87+ throw unlinkError ;
88+ }
89+ } ) ;
90+
91+ await fsPromises . copyFile ( source , destination ) ;
92+ await fsPromises . unlink ( source ) ;
93+ }
94+ } ;
95+
7396// Initialize upload directory asynchronously
7497const initializeUploadDir = async ( ) => {
7598 try {
@@ -918,7 +941,7 @@ app.post("/import/sqlite/verify", upload.single("db"), async (req, res) => {
918941 await removeFileIfExists ( stagedPath ) ;
919942
920943 if ( ! isValid ) {
921- return res . status ( 400 ) . json ( { error : "Invalid SQLite file " } ) ;
944+ return res . status ( 400 ) . json ( { error : "Invalid database format " } ) ;
922945 }
923946
924947 res . json ( { valid : true , message : "Database file is valid" } ) ;
@@ -945,8 +968,7 @@ app.post("/import/sqlite", upload.single("db"), async (req, res) => {
945968 ) ;
946969
947970 try {
948- // Use async rename instead of blocking renameSync
949- await fsPromises . rename ( originalPath , stagedPath ) ;
971+ await moveFile ( originalPath , stagedPath ) ;
950972 } catch ( error ) {
951973 console . error ( "Failed to stage uploaded database" , error ) ;
952974 await removeFileIfExists ( originalPath ) ;
@@ -975,8 +997,8 @@ app.post("/import/sqlite", upload.single("db"), async (req, res) => {
975997 // Database doesn't exist, skip backup
976998 }
977999
978- // Move staged file to final location
979- await fsPromises . rename ( stagedPath , dbPath ) ;
1000+ // Move staged file to final location, supporting cross-device mounts
1001+ await moveFile ( stagedPath , dbPath ) ;
9801002 } catch ( error ) {
9811003 console . error ( "Failed to replace database" , error ) ;
9821004 await removeFileIfExists ( stagedPath ) ;
0 commit comments