refactor(base64): split base64 text and file conversion in two tools + base64 to file
This commit is contained in:
		
							parent
							
								
									a70a0f83a1
								
							
						
					
					
						commit
						e6953d1b67
					
				
							
								
								
									
										20
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										20
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -25,6 +25,7 @@ | ||||
|         "highlight.js": "^11.5.1", | ||||
|         "lodash": "^4.17.21", | ||||
|         "mathjs": "^10.6.0", | ||||
|         "mime-types": "^2.1.35", | ||||
|         "naive-ui": "^2.31.0", | ||||
|         "pinia": "^2.0.11", | ||||
|         "plausible-tracker": "^0.3.5", | ||||
| @ -40,6 +41,7 @@ | ||||
|         "@types/bcryptjs": "^2.4.2", | ||||
|         "@types/crypto-js": "^4.1.1", | ||||
|         "@types/jsdom": "^16.2.14", | ||||
|         "@types/mime-types": "^2.1.1", | ||||
|         "@types/node": "^16.11.25", | ||||
|         "@types/qrcode": "^1.4.2", | ||||
|         "@types/randombytes": "^2.0.0", | ||||
| @ -2248,6 +2250,12 @@ | ||||
|       "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@types/mime-types": { | ||||
|       "version": "2.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.1.tgz", | ||||
|       "integrity": "sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@types/minimist": { | ||||
|       "version": "1.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", | ||||
| @ -7703,7 +7711,6 @@ | ||||
|       "version": "1.52.0", | ||||
|       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", | ||||
|       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">= 0.6" | ||||
|       } | ||||
| @ -7712,7 +7719,6 @@ | ||||
|       "version": "2.1.35", | ||||
|       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", | ||||
|       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "mime-db": "1.52.0" | ||||
|       }, | ||||
| @ -12847,6 +12853,12 @@ | ||||
|       "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/mime-types": { | ||||
|       "version": "2.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.1.tgz", | ||||
|       "integrity": "sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/minimist": { | ||||
|       "version": "1.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", | ||||
| @ -16899,14 +16911,12 @@ | ||||
|     "mime-db": { | ||||
|       "version": "1.52.0", | ||||
|       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", | ||||
|       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" | ||||
|     }, | ||||
|     "mime-types": { | ||||
|       "version": "2.1.35", | ||||
|       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", | ||||
|       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "mime-db": "1.52.0" | ||||
|       } | ||||
|  | ||||
| @ -47,6 +47,7 @@ | ||||
|     "highlight.js": "^11.5.1", | ||||
|     "lodash": "^4.17.21", | ||||
|     "mathjs": "^10.6.0", | ||||
|     "mime-types": "^2.1.35", | ||||
|     "naive-ui": "^2.31.0", | ||||
|     "pinia": "^2.0.11", | ||||
|     "plausible-tracker": "^0.3.5", | ||||
| @ -62,6 +63,7 @@ | ||||
|     "@types/bcryptjs": "^2.4.2", | ||||
|     "@types/crypto-js": "^4.1.1", | ||||
|     "@types/jsdom": "^16.2.14", | ||||
|     "@types/mime-types": "^2.1.1", | ||||
|     "@types/node": "^16.11.25", | ||||
|     "@types/qrcode": "^1.4.2", | ||||
|     "@types/randombytes": "^2.0.0", | ||||
|  | ||||
| @ -1,11 +1,17 @@ | ||||
| import { extension as getExtensionFromMime } from 'mime-types'; | ||||
| import type { Ref } from 'vue'; | ||||
| 
 | ||||
| export function useDownloadFileFromBase64({ source, filename = 'file' }: { source: Ref<string>; filename?: string }) { | ||||
| export function useDownloadFileFromBase64({ source, filename }: { source: Ref<string>; filename?: string }) { | ||||
|   return { | ||||
|     download() { | ||||
|       const base64 = source.value; | ||||
|       const mimeType = base64.match(/data:(.*?);base64/i)?.[1] ?? 'text/plain'; | ||||
|       console.log({ mimeType }); | ||||
|       const cleanFileName = filename ?? `file.${getExtensionFromMime(mimeType)}`; | ||||
| 
 | ||||
|       const a = document.createElement('a'); | ||||
|       a.href = source.value; | ||||
|       a.download = filename; | ||||
|       a.download = cleanFileName; | ||||
|       a.click(); | ||||
|     }, | ||||
|   }; | ||||
|  | ||||
| @ -1,9 +1,8 @@ | ||||
| <template> | ||||
|   <n-card title="Text to base64"> | ||||
|     <n-input v-model:value="textInput" type="textarea" placeholder="Put your string here..." /> | ||||
|     <n-input :value="textBase64" type="textarea" readonly /> | ||||
|   <n-card title="Base64 to file"> | ||||
|     <n-input v-model:value="base64Input" type="textarea" placeholder="Put your base64 file string here..." rows="5" /> | ||||
|     <n-space justify="center"> | ||||
|       <n-button secondary @click="copyTextBase64()"> Copy </n-button> | ||||
|       <n-button secondary @click="download()"> Download file </n-button> | ||||
|     </n-space> | ||||
|   </n-card> | ||||
| 
 | ||||
| @ -17,7 +16,7 @@ | ||||
|       </n-upload-dragger> | ||||
|     </n-upload> | ||||
| 
 | ||||
|     <n-input :value="fileBase64" type="textarea" readonly /> | ||||
|     <n-input :value="fileBase64" type="textarea" readonly placeholder="File in ase64 will be here" /> | ||||
|     <n-space justify="center"> | ||||
|       <n-button secondary @click="copyFileBase64()"> Copy </n-button> | ||||
|     </n-space> | ||||
| @ -26,14 +25,14 @@ | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { useCopy } from '@/composable/copy'; | ||||
| import { useBase64 } from '@vueuse/core'; | ||||
| import { useDownloadFileFromBase64 } from '@/composable/downloadBase64'; | ||||
| import { Upload } from '@vicons/tabler'; | ||||
| import { ref, type Ref } from 'vue'; | ||||
| import { useBase64 } from '@vueuse/core'; | ||||
| import type { UploadFileInfo } from 'naive-ui'; | ||||
| import { ref, type Ref } from 'vue'; | ||||
| 
 | ||||
| const textInput = ref(''); | ||||
| const { base64: textBase64 } = useBase64(textInput); | ||||
| const { copy: copyTextBase64 } = useCopy({ source: textBase64, text: 'Base64 string copied to the clipboard' }); | ||||
| const base64Input = ref(''); | ||||
| const { download } = useDownloadFileFromBase64({ source: base64Input }); | ||||
| 
 | ||||
| const fileList = ref(); | ||||
| const fileInput = ref() as Ref<File>; | ||||
| @ -2,11 +2,11 @@ import { FileDigit } from '@vicons/tabler'; | ||||
| import { defineTool } from '../tool'; | ||||
| 
 | ||||
| export const tool = defineTool({ | ||||
|   name: 'Base64 converter', | ||||
|   name: 'Base64 file converter', | ||||
|   path: '/base64-converter', | ||||
|   description: "Convert string, files or images into a it's base64 representation.", | ||||
|   keywords: ['base64', 'converter', 'upload', 'image', 'file', 'conversion', 'web', 'data', 'format'], | ||||
|   component: () => import('./base64-converter.vue'), | ||||
|   component: () => import('./base64-file-converter.vue'), | ||||
|   icon: FileDigit, | ||||
|   redirectFrom: ['/file-to-base64', '/base64-string-converter'], | ||||
| }); | ||||
| @ -0,0 +1,65 @@ | ||||
| <template> | ||||
|   <n-card title="String to base64"> | ||||
|     <n-form-item label="String to encode"> | ||||
|       <n-input v-model:value="textInput" type="textarea" placeholder="Put your string here..." rows="5" /> | ||||
|     </n-form-item> | ||||
| 
 | ||||
|     <n-form-item label="Base64 of string"> | ||||
|       <n-input | ||||
|         :value="base64Output" | ||||
|         type="textarea" | ||||
|         readonly | ||||
|         placeholder="The base64 encoding of your string will be here" | ||||
|         rows="5" | ||||
|       /> | ||||
|     </n-form-item> | ||||
| 
 | ||||
|     <n-space justify="center"> | ||||
|       <n-button secondary @click="copyTextBase64()"> Copy base64 </n-button> | ||||
|     </n-space> | ||||
|   </n-card> | ||||
| 
 | ||||
|   <n-card title="Base64 to string"> | ||||
|     <n-form-item | ||||
|       label="Base64 string to decode" | ||||
|       :validation-status="b64Validation.status" | ||||
|       :feedback="b64Validation.message" | ||||
|     > | ||||
|       <n-input v-model:value="base64Input" type="textarea" placeholder="Your base64 string..." rows="5" /> | ||||
|     </n-form-item> | ||||
| 
 | ||||
|     <n-form-item label="Decoded string"> | ||||
|       <n-input :value="textOutput" type="textarea" readonly placeholder="The decoded string will be here" rows="5" /> | ||||
|     </n-form-item> | ||||
| 
 | ||||
|     <n-space justify="center"> | ||||
|       <n-button secondary @click="copyText()"> Copy decoded string </n-button> | ||||
|     </n-space> | ||||
|   </n-card> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { useCopy } from '@/composable/copy'; | ||||
| import { useValidation } from '@/composable/validation'; | ||||
| import { computed, ref } from 'vue'; | ||||
| 
 | ||||
| const textInput = ref(''); | ||||
| const base64Output = computed(() => window.btoa(textInput.value)); | ||||
| const { copy: copyTextBase64 } = useCopy({ source: base64Output, text: 'Base64 string copied to the clipboard' }); | ||||
| 
 | ||||
| const base64Input = ref(''); | ||||
| const textOutput = computed(() => { | ||||
|   try { | ||||
|     return window.atob(base64Input.value); | ||||
|   } catch (_) { | ||||
|     return ''; | ||||
|   } | ||||
| }); | ||||
| const { copy: copyText } = useCopy({ source: textOutput, text: 'String copied to the clipboard' }); | ||||
| const b64Validation = useValidation({ | ||||
|   source: base64Input, | ||||
|   rules: [{ message: 'Invalid base64 string', validator: (value) => true || window.atob(value) }], | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped></style> | ||||
							
								
								
									
										12
									
								
								src/tools/base64-string-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/base64-string-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { FileDigit } from '@vicons/tabler'; | ||||
| import { defineTool } from '../tool'; | ||||
| 
 | ||||
| export const tool = defineTool({ | ||||
|   name: 'Base64 string encoder/decoder', | ||||
|   path: '/base64-string-converter', | ||||
|   description: 'Simply encode and decode string into a their base64 representation.', | ||||
|   keywords: ['base64', 'converter', 'conversion', 'web', 'data', 'format', 'atob', 'btoa'], | ||||
|   component: () => import('./base64-string-converter.vue'), | ||||
|   icon: FileDigit, | ||||
|   redirectFrom: ['/file-to-base64', '/base64-converter'], | ||||
| }); | ||||
| @ -1,7 +1,8 @@ | ||||
| import { LockOpen } from '@vicons/tabler'; | ||||
| import type { ToolCategory } from './tool'; | ||||
| 
 | ||||
| import { tool as base64Converter } from './base64-converter'; | ||||
| import { tool as base64FileConverter } from './base64-file-converter'; | ||||
| import { tool as base64StringConverter } from './base64-string-converter'; | ||||
| import { tool as basicAuthGenerator } from './basic-auth-generator'; | ||||
| import { tool as bcrypt } from './bcrypt'; | ||||
| import { tool as bip39 } from './bip39-generator'; | ||||
| @ -43,7 +44,8 @@ export const toolsByCategory: ToolCategory[] = [ | ||||
|       dateTimeConverter, | ||||
|       baseConverter, | ||||
|       romanNumeralConverter, | ||||
|       base64Converter, | ||||
|       base64StringConverter, | ||||
|       base64FileConverter, | ||||
|       colorConverter, | ||||
|       caseConverter, | ||||
|     ], | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user