diff --git a/src/utils/url.ts b/src/utils/url.ts index 6d63cc7..59959ed 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -23,15 +23,37 @@ export function extractFileName(url: string): string { return url.substring(url.lastIndexOf('/') + 1); } +function blobToFile(blob: Blob, fileName: string): File { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const b: any = blob; + b.lastModified = Date.now(); + b.name = fileName; + return b as File; +} + export function downloadFile(fileStream: Blob, fileName: string): void { - const file = new File([fileStream], fileName, { type: 'application/octet-stream', lastModified: Date.now() }); + let file: File; + // File constructor is not supported by Edge + // https://developer.mozilla.org/en-US/docs/Web/API/File#Browser_compatibility + if (navigator.msSaveBlob) { + // Detect if Edge + file = blobToFile(new Blob([fileStream], { type: 'application/octet-stream' }), fileName); + } else { + file = new File([fileStream], fileName, { type: 'application/octet-stream', lastModified: Date.now() }); + } + const objectURL = URL.createObjectURL(file); const fileLink = document.createElement('a'); fileLink.href = objectURL; fileLink.download = fileName; + + // Without appending to an HTML Element, download dialog does not show up on Firefox + // https://github.com/verdaccio/ui/issues/119 + document.documentElement.appendChild(fileLink); fileLink.click(); // firefox requires remove the object url setTimeout(() => { URL.revokeObjectURL(objectURL); + document.documentElement.removeChild(fileLink); }, 150); }