Files
dtf-system/local/static/upload.js
Cauê Faleiros 98c951d374
Some checks failed
Validate, publish and deploy / validate (push) Successful in 2m2s
Validate, publish and deploy / publish-and-deploy (push) Failing after 8s
first commit
2026-09-15 16:42:34 -03:00

31 lines
2.0 KiB
JavaScript

/* Shared direct multipart transport for customer originals/corrections and operator finals. */
window.dtfUpload = async (file, {api, prefix='/uploads', startPath=prefix, progress=()=>{}, scope='guest', resume=true}) => {
const samples=new Blob([file.slice(0,65536),file.slice(Math.max(0,file.size-65536))]);
const hash=Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',await samples.arrayBuffer())),b=>b.toString(16).padStart(2,'0')).join('');
const key='dtf-upload:'+JSON.stringify([scope,file.name,file.size,file.lastModified,hash]);
let id=resume?localStorage.getItem(key):null,state;
if(id){try{state=await api(prefix+'/'+id);}catch(error){if(![404,410].includes(error.status))throw error;id=null;}}
if(!id){state=await api(startPath,{name:file.name,size:file.size});id=state.id;if(resume)localStorage.setItem(key,id);}
async function waitForScan(){
for(let attempt=0;attempt<150;attempt++){
const checked=await api(prefix+'/'+id);
if(checked.scan_state==='clean')return id;
if(['rejected','error'].includes(checked.scan_state))throw new Error(checked.scan_reason||'Arquivo bloqueado pela verificação de segurança.');
progress('Verificando segurança de '+file.name+'…');
await new Promise(resolve=>setTimeout(resolve,1000));
}
throw new Error('Verificação de segurança pendente. Tente novamente para consultar o resultado.');
}
if(state.complete)return waitForScan();
const done=new Set(state.parts||[]),size=state.part_bytes;
for(let offset=0,part=1;offset<file.size;offset+=size,part++){
if(done.has(part))continue;
progress('Enviando '+file.name+' · parte '+part+'/'+Math.ceil(file.size/size));
const signed=await api(prefix+'/'+id+'/parts/'+part,{});
const response=await fetch(signed.url,{method:'PUT',body:file.slice(offset,offset+size)});
if(!response.ok)throw new Error('Upload interrompido. Tente novamente para retomar.');
}
await api(prefix+'/'+id+'/complete',{});
return waitForScan();
};