| 1 |
import { fetchWithTimeout } from '@auto-launch/functions/helpers'; |
| 2 |
import { digest } from '@shared/api/digest'; |
| 3 |
import { uploadMedia } from '@wordpress/media-utils'; |
| 4 |
|
| 5 |
export const uploadMediaFromUrl = async ( |
| 6 |
url, |
| 7 |
{ prefix, caller, timeoutMs = 60000 }, |
| 8 |
) => { |
| 9 |
try { |
| 10 |
const response = await fetchWithTimeout(url); |
| 11 |
// An expired signed url answers 403 with an XML body that would upload fine. |
| 12 |
if (!response.ok) throw new Error(`Fetch failed: ${response.status}`); |
| 13 |
|
| 14 |
const blob = await response.blob(); |
| 15 |
const type = blob.type || 'image/jpeg'; |
| 16 |
const fileExtension = type.replace('image/', ''); |
| 17 |
const name = `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; |
| 18 |
const file = new File([blob], `${name}.${fileExtension}`, { type }); |
| 19 |
|
| 20 |
return await new Promise((resolve) => { |
| 21 |
let settled = false; |
| 22 |
const settle = (fileObj) => { |
| 23 |
if (settled) return; |
| 24 |
settled = true; |
| 25 |
clearTimeout(timeoutId); |
| 26 |
resolve(fileObj); |
| 27 |
}; |
| 28 |
const fail = (error) => { |
| 29 |
digest({ error, details: { source: 'auto-launch', caller, url } }); |
| 30 |
settle(null); |
| 31 |
}; |
| 32 |
// uploadMedia can go quiet without erroring, and the step machinery only |
| 33 |
// retries on errors — an unsettled upload strands the whole launch. |
| 34 |
const timeoutId = setTimeout( |
| 35 |
() => fail(new Error(`Upload timed out after ${timeoutMs}ms`)), |
| 36 |
timeoutMs, |
| 37 |
); |
| 38 |
uploadMedia({ |
| 39 |
filesList: [file], |
| 40 |
// uploadMedia calls onFileChange first with a blob-URL placeholder |
| 41 |
// (no id), then again with the real attachment — wait for the id. |
| 42 |
onFileChange: ([fileObj]) => { |
| 43 |
if (!fileObj?.id) return; |
| 44 |
settle(fileObj); |
| 45 |
}, |
| 46 |
onError: fail, |
| 47 |
}); |
| 48 |
}); |
| 49 |
} catch (err) { |
| 50 |
digest({ |
| 51 |
error: err, |
| 52 |
details: { source: 'auto-launch', caller, url }, |
| 53 |
}); |
| 54 |
return null; |
| 55 |
} |
| 56 |
}; |
| 57 |
|