diff options
Diffstat (limited to 'src/composable/downloadBase64.ts')
-rw-r--r-- | src/composable/downloadBase64.ts | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/src/composable/downloadBase64.ts b/src/composable/downloadBase64.ts index 3904315..37b0428 100644 --- a/src/composable/downloadBase64.ts +++ b/src/composable/downloadBase64.ts @@ -1,32 +1,60 @@ import { extension as getExtensionFromMime } from 'mime-types'; import type { Ref } from 'vue'; +import _ from 'lodash'; -function getFileExtensionFromBase64({ - base64String, +export { getMimeTypeFromBase64, useDownloadFileFromBase64 }; + +const commonMimeTypesSignatures = { + 'JVBERi0': 'application/pdf', + 'R0lGODdh': 'image/gif', + 'R0lGODlh': 'image/gif', + 'iVBORw0KGgo': 'image/png', + '/9j/': 'image/jpg', +}; + +function getMimeTypeFromBase64({ base64String }: { base64String: string }) { + const [,mimeTypeFromBase64] = base64String.match(/data:(.*?);base64/i) ?? []; + + if (mimeTypeFromBase64) { + return { mimeType: mimeTypeFromBase64 }; + } + + const inferredMimeType = _.find(commonMimeTypesSignatures, (_mimeType, signature) => base64String.startsWith(signature)); + + if (inferredMimeType) { + return { mimeType: inferredMimeType }; + } + + return { mimeType: undefined }; +} + +function getFileExtensionFromMimeType({ + mimeType, defaultExtension = 'txt', }: { - base64String: string + mimeType: string | undefined defaultExtension?: string }) { - const hasMimeType = base64String.match(/data:(.*?);base64/i); - - if (hasMimeType) { - return getExtensionFromMime(hasMimeType[1]) || defaultExtension; + if (mimeType) { + return getExtensionFromMime(mimeType) ?? defaultExtension; } return defaultExtension; } -export function useDownloadFileFromBase64({ source, filename }: { source: Ref<string>; filename?: string }) { +function useDownloadFileFromBase64({ source, filename }: { source: Ref<string>; filename?: string }) { return { download() { - const base64String = source.value; - - if (base64String === '') { + if (source.value === '') { throw new Error('Base64 string is empty'); } - const cleanFileName = filename ?? `file.${getFileExtensionFromBase64({ base64String })}`; + const { mimeType } = getMimeTypeFromBase64({ base64String: source.value }); + const base64String = mimeType + ? source.value + : `data:text/plain;base64,${source.value}`; + + const cleanFileName = filename ?? `file.${getFileExtensionFromMimeType({ mimeType })}`; const a = document.createElement('a'); a.href = base64String; |