mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-05 13:57:10 -04:00
feat(base64 file converter): add a filename and extension fields
Add filename and extension (auto filled if data url) to allow downloading with right extension and filename Fix #788
This commit is contained in:
parent
3e27051f8f
commit
435d81281b
2 changed files with 85 additions and 21 deletions
|
@ -1,8 +1,12 @@
|
||||||
import { extension as getExtensionFromMime } from 'mime-types';
|
import { extension as getExtensionFromMimeType, extension as getMimeTypeFromExtension } from 'mime-types';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export { getMimeTypeFromBase64, useDownloadFileFromBase64 };
|
export {
|
||||||
|
getMimeTypeFromBase64,
|
||||||
|
getMimeTypeFromExtension, getExtensionFromMimeType,
|
||||||
|
useDownloadFileFromBase64, useDownloadFileFromBase64Refs,
|
||||||
|
};
|
||||||
|
|
||||||
const commonMimeTypesSignatures = {
|
const commonMimeTypesSignatures = {
|
||||||
'JVBERi0': 'application/pdf',
|
'JVBERi0': 'application/pdf',
|
||||||
|
@ -36,30 +40,55 @@ function getFileExtensionFromMimeType({
|
||||||
defaultExtension?: string
|
defaultExtension?: string
|
||||||
}) {
|
}) {
|
||||||
if (mimeType) {
|
if (mimeType) {
|
||||||
return getExtensionFromMime(mimeType) ?? defaultExtension;
|
return getExtensionFromMimeType(mimeType) ?? defaultExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultExtension;
|
return defaultExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useDownloadFileFromBase64({ source, filename }: { source: Ref<string>; filename?: string }) {
|
function downloadFromBase64({ sourceValue, filename, extension, fileMimeType }:
|
||||||
|
{ sourceValue: string; filename?: string; extension?: string; fileMimeType?: string }) {
|
||||||
|
if (sourceValue === '') {
|
||||||
|
throw new Error('Base64 string is empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultExtension = extension ?? 'txt';
|
||||||
|
const { mimeType } = getMimeTypeFromBase64({ base64String: sourceValue });
|
||||||
|
let base64String = sourceValue;
|
||||||
|
if (!mimeType) {
|
||||||
|
const targetMimeType = fileMimeType ?? getMimeTypeFromExtension(defaultExtension);
|
||||||
|
base64String = `data:${targetMimeType};base64,${sourceValue}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanExtension = extension ?? getFileExtensionFromMimeType(
|
||||||
|
{ mimeType, defaultExtension });
|
||||||
|
let cleanFileName = filename ?? `file.${cleanExtension}`;
|
||||||
|
if (extension && !cleanFileName.endsWith(`.${extension}`)) {
|
||||||
|
cleanFileName = `${cleanFileName}.${cleanExtension}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = base64String;
|
||||||
|
a.download = cleanFileName;
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function useDownloadFileFromBase64(
|
||||||
|
{ source, filename, extension, fileMimeType }:
|
||||||
|
{ source: Ref<string>; filename?: string; extension?: string; fileMimeType?: string }) {
|
||||||
return {
|
return {
|
||||||
download() {
|
download() {
|
||||||
if (source.value === '') {
|
downloadFromBase64({ sourceValue: source.value, filename, extension, fileMimeType });
|
||||||
throw new Error('Base64 string is empty');
|
},
|
||||||
}
|
};
|
||||||
|
}
|
||||||
const { mimeType } = getMimeTypeFromBase64({ base64String: source.value });
|
|
||||||
const base64String = mimeType
|
function useDownloadFileFromBase64Refs(
|
||||||
? source.value
|
{ source, filename, extension }:
|
||||||
: `data:text/plain;base64,${source.value}`;
|
{ source: Ref<string>; filename?: Ref<string>; extension?: Ref<string> }) {
|
||||||
|
return {
|
||||||
const cleanFileName = filename ?? `file.${getFileExtensionFromMimeType({ mimeType })}`;
|
download() {
|
||||||
|
downloadFromBase64({ sourceValue: source.value, filename: filename?.value, extension: extension?.value });
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = base64String;
|
|
||||||
a.download = cleanFileName;
|
|
||||||
a.click();
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,19 @@
|
||||||
import { useBase64 } from '@vueuse/core';
|
import { useBase64 } from '@vueuse/core';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { useCopy } from '@/composable/copy';
|
import { useCopy } from '@/composable/copy';
|
||||||
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
|
import { getExtensionFromMimeType, getMimeTypeFromBase64, useDownloadFileFromBase64Refs } from '@/composable/downloadBase64';
|
||||||
import { useValidation } from '@/composable/validation';
|
import { useValidation } from '@/composable/validation';
|
||||||
import { isValidBase64 } from '@/utils/base64';
|
import { isValidBase64 } from '@/utils/base64';
|
||||||
|
|
||||||
|
const fileName = ref('file');
|
||||||
|
const fileExtension = ref('');
|
||||||
const base64Input = ref('');
|
const base64Input = ref('');
|
||||||
const { download } = useDownloadFileFromBase64({ source: base64Input });
|
const { download } = useDownloadFileFromBase64Refs(
|
||||||
|
{
|
||||||
|
source: base64Input,
|
||||||
|
filename: fileName,
|
||||||
|
extension: fileExtension,
|
||||||
|
});
|
||||||
const base64InputValidation = useValidation({
|
const base64InputValidation = useValidation({
|
||||||
source: base64Input,
|
source: base64Input,
|
||||||
rules: [
|
rules: [
|
||||||
|
@ -18,6 +25,16 @@ const base64InputValidation = useValidation({
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
base64Input,
|
||||||
|
(newValue, _) => {
|
||||||
|
const { mimeType } = getMimeTypeFromBase64({ base64String: newValue });
|
||||||
|
if (mimeType) {
|
||||||
|
fileExtension.value = getExtensionFromMimeType(mimeType) || fileExtension.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
function downloadFile() {
|
function downloadFile() {
|
||||||
if (!base64InputValidation.isValid) {
|
if (!base64InputValidation.isValid) {
|
||||||
return;
|
return;
|
||||||
|
@ -44,6 +61,24 @@ async function onUpload(file: File) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<c-card title="Base64 to file">
|
<c-card title="Base64 to file">
|
||||||
|
<n-grid cols="3" x-gap="12">
|
||||||
|
<n-gi span="2">
|
||||||
|
<c-input-text
|
||||||
|
v-model:value="fileName"
|
||||||
|
label="File Name"
|
||||||
|
placeholder="Download filename"
|
||||||
|
mb-2
|
||||||
|
/>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<c-input-text
|
||||||
|
v-model:value="fileExtension"
|
||||||
|
label="Extension"
|
||||||
|
placeholder="Extension"
|
||||||
|
mb-2
|
||||||
|
/>
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="base64Input"
|
v-model:value="base64Input"
|
||||||
multiline
|
multiline
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue