export type SystemDatabaseRestoreOutcome={cleanupError?:string} interface Dependencies { allocate:()=>Promise write:(path:string,buffer:Buffer)=>Promise run:(args:string[])=>Promise remove:(path:string)=>Promise invalidate?:()=>void } export function validateSystemDatabaseRestoreArchive(buffer:Buffer):void{ if(buffer.length>512*1024*1024)throw new Error("Файл бэкапа слишком большой") if(buffer.length<5||!buffer.subarray(0,5).equals(Buffer.from("PGDMP")))throw new Error("Файл не похож на резервную копию PostgreSQL (PGDMP)") } export async function executeSystemDatabaseRestore(buffer:Buffer,databaseUrl:string,deps:Dependencies):Promise{ validateSystemDatabaseRestoreArchive(buffer) const file=await deps.allocate() let failed=false,failure:unknown,cleanupError:string|undefined try{ await deps.write(file,buffer) await deps.run(["--single-transaction","--clean","--if-exists","-d",databaseUrl,file]) deps.invalidate?.() }catch(error){failed=true;failure=error} finally{try{await deps.remove(file)}catch{cleanupError="Не удалось удалить временный файл восстановления"}} if(failed){const message=failure instanceof Error?failure.message:"Восстановление PostgreSQL не подтверждено";throw new Error(message+(cleanupError?"; "+cleanupError:""))} return cleanupError?{cleanupError}:{} }