Merge e64cafd7fe into 318fb6efb9
				
					
				
			This commit is contained in:
		
						commit
						596bc9a7f5
					
				
							
								
								
									
										4
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -142,6 +142,9 @@ declare module '@vue/runtime-core' { | |||||||
|     NLayout: typeof import('naive-ui')['NLayout'] |     NLayout: typeof import('naive-ui')['NLayout'] | ||||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] |     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||||
|     NMenu: typeof import('naive-ui')['NMenu'] |     NMenu: typeof import('naive-ui')['NMenu'] | ||||||
|  |     NP: typeof import('naive-ui')['NP'] | ||||||
|  |     NRadio: typeof import('naive-ui')['NRadio'] | ||||||
|  |     NRadioGroup: typeof import('naive-ui')['NRadioGroup'] | ||||||
|     NScrollbar: typeof import('naive-ui')['NScrollbar'] |     NScrollbar: typeof import('naive-ui')['NScrollbar'] | ||||||
|     NSlider: typeof import('naive-ui')['NSlider'] |     NSlider: typeof import('naive-ui')['NSlider'] | ||||||
|     NSwitch: typeof import('naive-ui')['NSwitch'] |     NSwitch: typeof import('naive-ui')['NSwitch'] | ||||||
| @ -178,6 +181,7 @@ declare module '@vue/runtime-core' { | |||||||
|     TomlToYaml: typeof import('./src/tools/toml-to-yaml/toml-to-yaml.vue')['default'] |     TomlToYaml: typeof import('./src/tools/toml-to-yaml/toml-to-yaml.vue')['default'] | ||||||
|     'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default'] |     'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default'] | ||||||
|     ToolCard: typeof import('./src/components/ToolCard.vue')['default'] |     ToolCard: typeof import('./src/components/ToolCard.vue')['default'] | ||||||
|  |     TorrentToMagnet: typeof import('./src/tools/torrent-to-magnet/torrent-to-magnet.vue')['default'] | ||||||
|     UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default'] |     UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default'] | ||||||
|     UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default'] |     UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default'] | ||||||
|     UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default'] |     UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default'] | ||||||
|  | |||||||
| @ -78,6 +78,7 @@ | |||||||
|     "netmask": "^2.0.2", |     "netmask": "^2.0.2", | ||||||
|     "node-forge": "^1.3.1", |     "node-forge": "^1.3.1", | ||||||
|     "oui-data": "^1.0.10", |     "oui-data": "^1.0.10", | ||||||
|  |     "parse-torrent": "^11.0.17", | ||||||
|     "pdf-signature-reader": "^1.4.2", |     "pdf-signature-reader": "^1.4.2", | ||||||
|     "pinia": "^2.0.34", |     "pinia": "^2.0.34", | ||||||
|     "plausible-tracker": "^0.3.8", |     "plausible-tracker": "^0.3.8", | ||||||
| @ -134,6 +135,7 @@ | |||||||
|     "unplugin-icons": "^0.17.0", |     "unplugin-icons": "^0.17.0", | ||||||
|     "unplugin-vue-components": "^0.25.0", |     "unplugin-vue-components": "^0.25.0", | ||||||
|     "vite": "^4.4.9", |     "vite": "^4.4.9", | ||||||
|  |     "vite-plugin-node-polyfills": "^0.22.0", | ||||||
|     "vite-plugin-pwa": "^0.16.0", |     "vite-plugin-pwa": "^0.16.0", | ||||||
|     "vite-plugin-vue-markdown": "^0.23.5", |     "vite-plugin-vue-markdown": "^0.23.5", | ||||||
|     "vite-svg-loader": "^4.0.0", |     "vite-svg-loader": "^4.0.0", | ||||||
|  | |||||||
							
								
								
									
										733
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										733
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -9,6 +9,7 @@ import { tool as textToUnicode } from './text-to-unicode'; | |||||||
| import { tool as safelinkDecoder } from './safelink-decoder'; | import { tool as safelinkDecoder } from './safelink-decoder'; | ||||||
| import { tool as xmlToJson } from './xml-to-json'; | import { tool as xmlToJson } from './xml-to-json'; | ||||||
| import { tool as jsonToXml } from './json-to-xml'; | import { tool as jsonToXml } from './json-to-xml'; | ||||||
|  | import { tool as torrentToMagnet } from './torrent-to-magnet'; | ||||||
| import { tool as pdfSignatureChecker } from './pdf-signature-checker'; | import { tool as pdfSignatureChecker } from './pdf-signature-checker'; | ||||||
| import { tool as numeronymGenerator } from './numeronym-generator'; | import { tool as numeronymGenerator } from './numeronym-generator'; | ||||||
| import { tool as macAddressGenerator } from './mac-address-generator'; | import { tool as macAddressGenerator } from './mac-address-generator'; | ||||||
| @ -133,6 +134,7 @@ export const toolsByCategory: ToolCategory[] = [ | |||||||
|       httpStatusCodes, |       httpStatusCodes, | ||||||
|       jsonDiff, |       jsonDiff, | ||||||
|       safelinkDecoder, |       safelinkDecoder, | ||||||
|  |       torrentToMagnet, | ||||||
|     ], |     ], | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/tools/torrent-to-magnet/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/torrent-to-magnet/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | import { Bookmarks } from '@vicons/tabler'; | ||||||
|  | import { defineTool } from '../tool'; | ||||||
|  | 
 | ||||||
|  | export const tool = defineTool({ | ||||||
|  |   name: 'Torrent to Magnet', | ||||||
|  |   path: '/torrent-to-magnet', | ||||||
|  |   description: 'Convert a torrent file to a Magnet url', | ||||||
|  |   keywords: ['torrent', 'magnet', 'url', 'link'], | ||||||
|  |   component: () => import('./torrent-to-magnet.vue'), | ||||||
|  |   icon: Bookmarks, | ||||||
|  |   createdAt: new Date('2024-04-20'), | ||||||
|  | }); | ||||||
							
								
								
									
										4
									
								
								src/tools/torrent-to-magnet/parse-torrent.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/tools/torrent-to-magnet/parse-torrent.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | declare module 'parse-torrent'{ | ||||||
|  |     export default function parseTorrent(content: string | ArrayBufferView): Promise<object>; | ||||||
|  |     export function toMagnetURI(parsedTorrent: object): string; | ||||||
|  | } | ||||||
							
								
								
									
										115
									
								
								src/tools/torrent-to-magnet/torrent-to-magnet.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/tools/torrent-to-magnet/torrent-to-magnet.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import type { Ref } from 'vue'; | ||||||
|  | import parseTorrent, { toMagnetURI } from 'parse-torrent'; | ||||||
|  | import { withDefaultOnError } from '@/utils/defaults'; | ||||||
|  | import { useValidation } from '@/composable/validation'; | ||||||
|  | 
 | ||||||
|  | const inputType = ref<'file' | 'content'>('file'); | ||||||
|  | const torrentContent = ref(''); | ||||||
|  | const fileInput = ref() as Ref<File | null>; | ||||||
|  | const torrentInfosRaw = computedAsync(async () => { | ||||||
|  |   const file = fileInput.value; | ||||||
|  |   const content = torrentContent.value; | ||||||
|  |   try { | ||||||
|  |     if (inputType.value === 'file' && file) { | ||||||
|  |       return await parseTorrent(new Uint8Array(await file.arrayBuffer())); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       return await parseTorrent(content); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   catch (e: any) { | ||||||
|  |     return { | ||||||
|  |       error: e.toString(), | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | const torrentInfos = computed(() => withDefaultOnError(() => { | ||||||
|  |   return Object.entries(torrentInfosRaw.value).map(([k, v]) => { | ||||||
|  |     return { | ||||||
|  |       label: k?.toString() || '', | ||||||
|  |       value: JSON.stringify(v), | ||||||
|  |     }; | ||||||
|  |   }); | ||||||
|  | }, [])); | ||||||
|  | const magnetURI = computed(() => withDefaultOnError(() => toMagnetURI(torrentInfosRaw.value), [])); | ||||||
|  | 
 | ||||||
|  | async function onUpload(file: File) { | ||||||
|  |   if (file) { | ||||||
|  |     fileInput.value = file; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | watch(torrentContent, (_, newValue) => { | ||||||
|  |   if (newValue !== '') { | ||||||
|  |     fileInput.value = null; | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const { attrs: validationAttrs } = useValidation({ | ||||||
|  |   source: torrentInfos, | ||||||
|  |   rules: [{ message: 'Invalid torrent content', validator: torrent => torrent?.length > 0 }], | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <n-radio-group v-model:value="inputType" name="radiogroup" mb-2 flex justify-center> | ||||||
|  |       <n-space> | ||||||
|  |         <n-radio | ||||||
|  |           value="file" | ||||||
|  |           label="File" | ||||||
|  |         /> | ||||||
|  |         <n-radio | ||||||
|  |           value="content" | ||||||
|  |           label="Content" | ||||||
|  |         /> | ||||||
|  |       </n-space> | ||||||
|  |     </n-radio-group> | ||||||
|  | 
 | ||||||
|  |     <c-file-upload | ||||||
|  |       v-if="inputType === 'file'" | ||||||
|  |       title="Drag and drop torrent file here, or click to select a file" | ||||||
|  |       @file-upload="onUpload" | ||||||
|  |     /> | ||||||
|  | 
 | ||||||
|  |     <c-input-text | ||||||
|  |       v-if="inputType === 'content'" | ||||||
|  |       v-model:value="torrentContent" | ||||||
|  |       label="Torrent/Magnet Content" | ||||||
|  |       placeholder="Paste your Torrent/Magnet content here" | ||||||
|  |       multiline | ||||||
|  |       mb-2 | ||||||
|  |     /> | ||||||
|  | 
 | ||||||
|  |     <n-divider /> | ||||||
|  | 
 | ||||||
|  |     <input-copyable | ||||||
|  |       label="Magnet URI" | ||||||
|  |       label-position="left" | ||||||
|  |       label-width="100px" | ||||||
|  |       label-align="right" | ||||||
|  |       mb-2 | ||||||
|  |       :value="validationAttrs.validationStatus === 'error' ? '' : magnetURI" | ||||||
|  |       placeholder="Please use a correct torrent" | ||||||
|  |     /> | ||||||
|  | 
 | ||||||
|  |     <input-copyable | ||||||
|  |       v-for="{ label, value } of torrentInfos" | ||||||
|  |       :key="label" | ||||||
|  |       :label="label" | ||||||
|  |       label-position="left" | ||||||
|  |       label-width="100px" | ||||||
|  |       label-align="right" | ||||||
|  |       mb-2 | ||||||
|  |       :value="validationAttrs.validationStatus === 'error' ? '' : value" | ||||||
|  |       placeholder="Please use a correct torrent" | ||||||
|  |     /> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | ::v-deep(.n-upload-trigger) { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -15,6 +15,7 @@ import { VitePWA } from 'vite-plugin-pwa'; | |||||||
| import markdown from 'vite-plugin-vue-markdown'; | import markdown from 'vite-plugin-vue-markdown'; | ||||||
| import svgLoader from 'vite-svg-loader'; | import svgLoader from 'vite-svg-loader'; | ||||||
| import { configDefaults } from 'vitest/config'; | import { configDefaults } from 'vitest/config'; | ||||||
|  | import { nodePolyfills } from 'vite-plugin-node-polyfills' | ||||||
| 
 | 
 | ||||||
| const baseUrl = process.env.BASE_URL ?? '/'; | const baseUrl = process.env.BASE_URL ?? '/'; | ||||||
| 
 | 
 | ||||||
| @ -97,6 +98,7 @@ export default defineConfig({ | |||||||
|       resolvers: [NaiveUiResolver(), IconsResolver({ prefix: 'icon' })], |       resolvers: [NaiveUiResolver(), IconsResolver({ prefix: 'icon' })], | ||||||
|     }), |     }), | ||||||
|     Unocss(), |     Unocss(), | ||||||
|  |     nodePolyfills(), | ||||||
|   ], |   ], | ||||||
|   base: baseUrl, |   base: baseUrl, | ||||||
|   resolve: { |   resolve: { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user