Compare commits

...

4 Commits

Author SHA1 Message Date
c423f5e624 Improve Accessibility 2025-10-31 14:31:29 +03:30
25a968ba53 Cleanup API functions 2025-10-31 14:07:36 +03:30
8938d893ad Minor improvement 2025-10-31 13:55:22 +03:30
906eb10eb2 Added torrent file upload support 2025-10-31 13:53:07 +03:30
11 changed files with 453 additions and 111 deletions

View File

@@ -0,0 +1,13 @@
<template>
<div class="hero">
<div class="hero-content text-center">
<div class="max-w-md">
<h1 class="text-5xl font-bold drop-shadow-xl">TorrentMax</h1>
<p class="py-6">
Paste a magnet link below and TorrentMax will enrich it with
additional trackers
</p>
</div>
</div>
</div>
</template>

View File

@@ -60,6 +60,7 @@ function handleSubmit() {
<!-- Right circular button --> <!-- Right circular button -->
<button <button
class="ml-3 w-10 h-10 flex items-center justify-center rounded-full bg-primary text-accent hover:scale-110 transition-transform duration-300 shadow-md" class="ml-3 w-10 h-10 flex items-center justify-center rounded-full bg-primary text-accent hover:scale-110 transition-transform duration-300 shadow-md"
aria-label="Submit magnet link"
@click="handleSubmit" @click="handleSubmit"
> >
<svg <svg

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
const emit = defineEmits(["submit"]);
function handleFileChange(e: Event) {
const target = e.target as HTMLInputElement;
// TODO: add file size verification
if (target.files?.length) {
emit("submit", target.files[0]);
}
}
</script>
<template>
<div class="flex justify-center">
<fieldset class="fieldset w-full max-w-2/3">
<legend class="fieldset-legend">Pick a file</legend>
<input
id="torrent-file"
type="file"
class="file-input file-input-bordered w-full border-primary bg-base-100 file-input-md"
accept=".torrent,application/x-bittorrent"
@change="handleFileChange"
/>
<label class="label">Max size 1MB</label>
</fieldset>
</div>
</template>

View File

@@ -0,0 +1,21 @@
<script setup lang="ts">
const props = defineProps<{ message: string }>()
</script>
<template>
<div role="alert" class="alert alert-error mt-3">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 shrink-0 stroke-current"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<span>Error! {{ props.message }}</span>
</div>
</template>

72
app/lib/api.ts Normal file
View File

@@ -0,0 +1,72 @@
interface MaxedMagnetResponse {
totalTrackers: number;
name?: string;
id: string;
maxedMagnet: string;
error?: string;
}
export async function getMaxedMagnetUrl(
magnet: string
): Promise<MaxedMagnetResponse> {
try {
const response = await fetch("/api/magnet", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ magnet }),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
return {
totalTrackers: 0,
id: "",
maxedMagnet: "",
error: errorData.message || `HTTP error! status: ${response.status}`,
} as MaxedMagnetResponse;
}
return await response.json();
} catch (err) {
return {
totalTrackers: 0,
id: "",
maxedMagnet: "",
error: err instanceof Error ? err.message : "An unknown error occurred",
} as MaxedMagnetResponse;
}
}
export async function getMaxedMagnetFromTorrent(
file: File
): Promise<MaxedMagnetResponse> {
try {
const form = new FormData();
form.append("file", file);
const response = await fetch("/api/torrent", {
method: "POST",
body: form,
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
return {
totalTrackers: 0,
id: "",
maxedMagnet: "",
error: errorData.message || `HTTP error! status: ${response.status}`,
} as MaxedMagnetResponse;
}
return await response.json();
} catch (err) {
return {
totalTrackers: 0,
id: "",
maxedMagnet: "",
error: err instanceof Error ? err.message : "An unknown error occurred",
} as MaxedMagnetResponse;
}
}

View File

@@ -1,46 +1,46 @@
<script setup lang="ts"> <script setup lang="ts">
import MagnetCard from "~/components/MagnetCard.vue"; import MagnetCard from "~/components/MagnetCard.vue";
import { ref } from "vue"; import { ref } from "vue";
import IndexHero from "~/components/IndexHero.vue";
import { getMaxedMagnetFromTorrent, getMaxedMagnetUrl } from "~/lib/api";
interface MaxedMagnetResponse { interface MaxedMagnetResponse {
totalTrackers: number; totalTrackers: number;
name?: string; name?: string;
id: string; id: string;
maxedMagnet: string; maxedMagnet: string;
error?: string;
} }
const maxedMagnet = ref<MaxedMagnetResponse | null>(null); const maxedMagnet = ref<MaxedMagnetResponse | null>(null);
const error = ref<string | null>(null); const error = ref<string | null>(null);
const loading = ref(false); const loading = ref(false);
async function getMaxedMagnetUrl(magnet: string) { async function handleMagnetSubmit(magnet: string) {
error.value = null; // Clear any previous error loading.value = true;
loading.value = true; // Set loading to true error.value = null;
maxedMagnet.value = null;
try { const result = await getMaxedMagnetUrl(magnet);
const response = await fetch("/api/magnet", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ magnet }),
});
if (!response.ok) { loading.value = false;
const errorData = await response.json().catch(() => ({}));
error.value =
errorData.message || `HTTP error! status: ${response.status}`;
console.error("API error:", error.value);
return;
}
maxedMagnet.value = await response.json(); if (result.error) {
} catch (err) { error.value = result.error;
error.value = } else {
err instanceof Error ? err.message : "An unknown error occurred"; maxedMagnet.value = result;
console.error("Network error:", err); }
} finally { }
loading.value = false; // Reset loading state
async function handleTorrentUpload(file: File) {
loading.value = true;
const result = await getMaxedMagnetFromTorrent(file);
loading.value = false;
if (result.error) {
error.value = result.error;
} else {
maxedMagnet.value = result;
} }
} }
</script> </script>
@@ -48,56 +48,40 @@ async function getMaxedMagnetUrl(magnet: string) {
<template> <template>
<div class="flex flex-col min-h-screen bg-base-300"> <div class="flex flex-col min-h-screen bg-base-300">
<div class="grow flex items-start justify-center pt-40 px-4"> <div class="grow flex items-start justify-center pt-40 px-4">
<div class="w-full max-w-2xl space-y-6"> <div class="w-full max-w-2xl">
<div class="hero"> <IndexHero />
<div class="hero-content text-center"> <div v-if="!maxedMagnet && !loading" class="space-y-6">
<div class="max-w-md"> <SearchBar @submit="handleMagnetSubmit" />
<h1 class="text-5xl font-bold drop-shadow-xl">TorrentMax</h1> <div class="divider divider-neutral">OR</div>
<p class="py-6"> <TorrentUpload @submit="handleTorrentUpload" />
Paste a magnet link below and TorrentMax will enrich it with
additional trackers
</p>
</div>
</div>
</div> </div>
<SearchBar @submit="getMaxedMagnetUrl" />
<!-- Loading indicator -->
<div <div
v-motion-fade
v-if="loading" v-if="loading"
v-motion-fade
class="flex justify-center items-center p-8" class="flex justify-center items-center p-8"
> >
<span class="loading loading-infinity loading-lg"></span> <span class="loading loading-infinity loading-xl" />
</div> </div>
<!-- Error message display --> <!-- Error message display -->
<div v-if="error && !loading" class="max-w-2xl mx-auto p-4"> <AlertError v-if="error && !loading" :message="error" />
<div class="alert alert-error">
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<span>{{ error }}</span>
</div>
</div>
<MagnetCard <MagnetCard
v-if="maxedMagnet && !loading && !error"
v-motion-fade v-motion-fade
v-if="maxedMagnet && !loading"
:name="maxedMagnet.name || 'Unknown Torrent'" :name="maxedMagnet.name || 'Unknown Torrent'"
:total-trackers="maxedMagnet.totalTrackers" :total-trackers="maxedMagnet.totalTrackers"
:magnet-url="maxedMagnet.maxedMagnet" :magnet-url="maxedMagnet.maxedMagnet"
/> />
<div v-if="maxedMagnet" class="flex justify-center pt-5">
<button
class="btn btn-primary text-accent"
@click="maxedMagnet = null"
>
Max Another Torrent
</button>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -13,11 +13,13 @@
"@formkit/auto-animate": "^0.9.0", "@formkit/auto-animate": "^0.9.0",
"@nuxt/eslint": "1.10.0", "@nuxt/eslint": "1.10.0",
"@tailwindcss/vite": "^4.1.16", "@tailwindcss/vite": "^4.1.16",
"@types/parse-torrent": "^5.8.8",
"@vercel/analytics": "^1.5.0", "@vercel/analytics": "^1.5.0",
"@vueuse/motion": "^3.0.3", "@vueuse/motion": "^3.0.3",
"daisyui": "^5.3.10", "daisyui": "^5.3.10",
"eslint": "^9.38.0", "eslint": "^9.38.0",
"nuxt": "^4.2.0", "nuxt": "^4.2.0",
"parse-torrent": "^11.0.19",
"tailwindcss": "^4.1.16", "tailwindcss": "^4.1.16",
"vue": "^3.5.22", "vue": "^3.5.22",
"vue-router": "^4.6.3" "vue-router": "^4.6.3"

264
pnpm-lock.yaml generated
View File

@@ -13,10 +13,13 @@ importers:
version: 0.9.0 version: 0.9.0
'@nuxt/eslint': '@nuxt/eslint':
specifier: 1.10.0 specifier: 1.10.0
version: 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.5.1)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) version: 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.5.1)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: ^4.1.16 specifier: ^4.1.16
version: 4.1.16(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) version: 4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
'@types/parse-torrent':
specifier: ^5.8.8
version: 5.8.8
'@vercel/analytics': '@vercel/analytics':
specifier: ^1.5.0 specifier: ^1.5.0
version: 1.5.0(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) version: 1.5.0(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))
@@ -31,7 +34,10 @@ importers:
version: 9.38.0(jiti@2.6.1) version: 9.38.0(jiti@2.6.1)
nuxt: nuxt:
specifier: ^4.2.0 specifier: ^4.2.0
version: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1) version: 4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
parse-torrent:
specifier: ^11.0.19
version: 11.0.19
tailwindcss: tailwindcss:
specifier: ^4.1.16 specifier: ^4.1.16
version: 4.1.16 version: 4.1.16
@@ -1282,6 +1288,10 @@ packages:
peerDependencies: peerDependencies:
vite: ^5.2.0 || ^6 || ^7 vite: ^5.2.0 || ^6 || ^7
'@thaunknown/thirty-two@1.0.5':
resolution: {integrity: sha512-Q53KyCXweV1CS62EfqtPDqfpksn5keQ59PGqzzkK+g8Vif1jB4inoBCcs/BUSdsqddhE3G+2Fn+4RX3S6RqT0A==}
engines: {node: '>=0.2.6'}
'@tybys/wasm-util@0.10.1': '@tybys/wasm-util@0.10.1':
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
@@ -1291,10 +1301,22 @@ packages:
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/magnet-uri@5.1.5':
resolution: {integrity: sha512-SbBjlb1KGe38VfjRR+mwqztJd/4skhdKkRbIzPDhTy7IAeEAPZWIVSEkZw00Qr4ZZOGR3/ATJ20WWPBfrKHGdA==}
'@types/node@24.9.2':
resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==}
'@types/parse-path@7.1.0': '@types/parse-path@7.1.0':
resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==}
deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed.
'@types/parse-torrent-file@4.0.6':
resolution: {integrity: sha512-SxqVth0Iv0WuEkqWS5MaY4S4Tlyi+QHkElQREvsUPw2xHcPgKyQ2dkJRRv5vAxmLzH+tnMdOj1Nws/wsenbzUw==}
'@types/parse-torrent@5.8.8':
resolution: {integrity: sha512-CInK3z3BxMXUeO/UiUeSfpQ0CkjOAWZUCUigVn3ZkppeLZTm32/TepolcxzgYuk6q3z91gdWsmOW2S6fYx326w==}
'@types/resolve@1.20.2': '@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
@@ -1717,6 +1739,10 @@ packages:
bare-abort-controller: bare-abort-controller:
optional: true optional: true
base64-arraybuffer@1.0.2:
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
engines: {node: '>= 0.6.0'}
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -1724,6 +1750,14 @@ packages:
resolution: {integrity: sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==} resolution: {integrity: sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==}
hasBin: true hasBin: true
bencode@4.0.0:
resolution: {integrity: sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==}
engines: {node: '>=12.20.0'}
bep53-range@2.0.0:
resolution: {integrity: sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA==}
engines: {node: '>=12.20.0'}
bindings@1.5.0: bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
@@ -1916,6 +1950,9 @@ packages:
resolution: {integrity: sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==} resolution: {integrity: sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==}
engines: {node: '>=18.0'} engines: {node: '>=18.0'}
cross-fetch-ponyfill@1.0.3:
resolution: {integrity: sha512-uOBkDhUAGAbx/FEzNKkOfx3w57H8xReBBXoZvUnOKTI0FW0Xvrj3GrYv2iZXUqlffC1LMGfQzhmBM/ke+6eTDA==}
cross-spawn@7.0.6: cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@@ -1977,6 +2014,10 @@ packages:
daisyui@5.3.10: daisyui@5.3.10:
resolution: {integrity: sha512-vmjyPmm0hvFhA95KB6uiGmWakziB2pBv6CUcs5Ka/3iMBMn9S+C3SZYx9G9l2JrgTZ1EFn61F/HrPcwaUm2kLQ==} resolution: {integrity: sha512-vmjyPmm0hvFhA95KB6uiGmWakziB2pBv6CUcs5Ka/3iMBMn9S+C3SZYx9G9l2JrgTZ1EFn61F/HrPcwaUm2kLQ==}
data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
db0@0.3.4: db0@0.3.4:
resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==}
peerDependencies: peerDependencies:
@@ -2343,6 +2384,10 @@ packages:
picomatch: picomatch:
optional: true optional: true
fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
figures@6.1.0: figures@6.1.0:
resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
engines: {node: '>=18'} engines: {node: '>=18'}
@@ -2385,6 +2430,10 @@ packages:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'} engines: {node: '>=14'}
formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
fraction.js@4.3.7: fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
@@ -2418,6 +2467,10 @@ packages:
get-port-please@3.2.0: get-port-please@3.2.0:
resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==}
get-stdin@9.0.0:
resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==}
engines: {node: '>=12'}
get-stream@8.0.1: get-stream@8.0.1:
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
engines: {node: '>=16'} engines: {node: '>=16'}
@@ -2883,6 +2936,10 @@ packages:
magicast@0.5.1: magicast@0.5.1:
resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==}
magnet-uri@7.0.7:
resolution: {integrity: sha512-z/+dB2NQsXaDuxVBjoPLpZT8ePaacUmoontoFheRBl++nALHYs4qV9MmhTur9e4SaMbkCR/uPX43UMzEOoeyaw==}
engines: {node: '>=12.20.0'}
mdn-data@2.0.28: mdn-data@2.0.28:
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
@@ -2998,6 +3055,11 @@ packages:
node-addon-api@7.1.1: node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
deprecated: Use your platform's native DOMException instead
node-fetch-native@1.6.7: node-fetch-native@1.6.7:
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
@@ -3010,6 +3072,10 @@ packages:
encoding: encoding:
optional: true optional: true
node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
node-forge@1.3.1: node-forge@1.3.1:
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
engines: {node: '>= 6.13.0'} engines: {node: '>= 6.13.0'}
@@ -3155,6 +3221,11 @@ packages:
parse-statements@1.0.11: parse-statements@1.0.11:
resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==}
parse-torrent@11.0.19:
resolution: {integrity: sha512-T0lEkDdFVQsy0YxHIKjzDHSgt/yl57f3INs5jl7OZqAm77XDF0FgRgrv3LCKgSqsTOrMwYaF0t2761WKdvhgig==}
engines: {node: '>=12.20.0'}
hasBin: true
parse-url@9.2.0: parse-url@9.2.0:
resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==}
engines: {node: '>=14.13.0'} engines: {node: '>=14.13.0'}
@@ -3846,6 +3917,9 @@ packages:
ufo@1.6.1: ufo@1.6.1:
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
uint8-util@2.2.5:
resolution: {integrity: sha512-/QxVQD7CttWpVUKVPz9znO+3Dd4BdTSnFQ7pv/4drVhC9m4BaL2LFHTkJn6EsYoxT79VDq/2Gg8L0H22PrzyMw==}
ultrahtml@1.6.0: ultrahtml@1.6.0:
resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
@@ -3855,6 +3929,9 @@ packages:
unctx@2.4.1: unctx@2.4.1:
resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==}
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
undici@7.16.0: undici@7.16.0:
resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==}
engines: {node: '>=20.18.1'} engines: {node: '>=20.18.1'}
@@ -4125,6 +4202,10 @@ packages:
typescript: typescript:
optional: true optional: true
web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
webidl-conversions@3.0.1: webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
@@ -4762,19 +4843,19 @@ snapshots:
'@nuxt/devalue@2.0.2': {} '@nuxt/devalue@2.0.2': {}
'@nuxt/devtools-kit@2.7.0(magicast@0.3.5)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': '@nuxt/devtools-kit@2.7.0(magicast@0.3.5)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
dependencies: dependencies:
'@nuxt/kit': 3.20.0(magicast@0.3.5) '@nuxt/kit': 3.20.0(magicast@0.3.5)
execa: 8.0.1 execa: 8.0.1
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- magicast - magicast
'@nuxt/devtools-kit@3.0.0(magicast@0.5.1)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': '@nuxt/devtools-kit@3.0.0(magicast@0.5.1)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
dependencies: dependencies:
'@nuxt/kit': 4.2.0(magicast@0.5.1) '@nuxt/kit': 4.2.0(magicast@0.5.1)
execa: 8.0.1 execa: 8.0.1
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- magicast - magicast
@@ -4789,12 +4870,12 @@ snapshots:
prompts: 2.4.2 prompts: 2.4.2
semver: 7.7.3 semver: 7.7.3
'@nuxt/devtools@2.7.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': '@nuxt/devtools@2.7.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))':
dependencies: dependencies:
'@nuxt/devtools-kit': 2.7.0(magicast@0.3.5)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/devtools-kit': 2.7.0(magicast@0.3.5)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
'@nuxt/devtools-wizard': 2.7.0 '@nuxt/devtools-wizard': 2.7.0
'@nuxt/kit': 3.20.0(magicast@0.3.5) '@nuxt/kit': 3.20.0(magicast@0.3.5)
'@vue/devtools-core': 7.7.7(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@vue/devtools-core': 7.7.7(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
'@vue/devtools-kit': 7.7.7 '@vue/devtools-kit': 7.7.7
birpc: 2.6.1 birpc: 2.6.1
consola: 3.4.2 consola: 3.4.2
@@ -4819,9 +4900,9 @@ snapshots:
sirv: 3.0.2 sirv: 3.0.2
structured-clone-es: 1.0.0 structured-clone-es: 1.0.0
tinyglobby: 0.2.15 tinyglobby: 0.2.15
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vite-plugin-inspect: 11.3.3(@nuxt/kit@3.20.0(magicast@0.3.5))(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) vite-plugin-inspect: 11.3.3(@nuxt/kit@3.20.0(magicast@0.3.5))(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
vite-plugin-vue-tracer: 1.0.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) vite-plugin-vue-tracer: 1.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
which: 5.0.0 which: 5.0.0
ws: 8.18.3 ws: 8.18.3
transitivePeerDependencies: transitivePeerDependencies:
@@ -4870,10 +4951,10 @@ snapshots:
- supports-color - supports-color
- typescript - typescript
'@nuxt/eslint@1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.5.1)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': '@nuxt/eslint@1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.5.1)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
dependencies: dependencies:
'@eslint/config-inspector': 1.3.0(eslint@9.38.0(jiti@2.6.1)) '@eslint/config-inspector': 1.3.0(eslint@9.38.0(jiti@2.6.1))
'@nuxt/devtools-kit': 3.0.0(magicast@0.5.1)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/devtools-kit': 3.0.0(magicast@0.5.1)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
'@nuxt/eslint-config': 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) '@nuxt/eslint-config': 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)
'@nuxt/eslint-plugin': 1.10.0(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) '@nuxt/eslint-plugin': 1.10.0(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)
'@nuxt/kit': 4.2.0(magicast@0.5.1) '@nuxt/kit': 4.2.0(magicast@0.5.1)
@@ -4975,7 +5056,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- magicast - magicast
'@nuxt/nitro-server@4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)': '@nuxt/nitro-server@4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)':
dependencies: dependencies:
'@nuxt/devalue': 2.0.2 '@nuxt/devalue': 2.0.2
'@nuxt/kit': 4.2.0(magicast@0.5.1) '@nuxt/kit': 4.2.0(magicast@0.5.1)
@@ -4993,7 +5074,7 @@ snapshots:
klona: 2.0.6 klona: 2.0.6
mocked-exports: 0.1.1 mocked-exports: 0.1.1
nitropack: 2.12.9 nitropack: 2.12.9
nuxt: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1) nuxt: 4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
pathe: 2.0.3 pathe: 2.0.3
pkg-types: 2.3.0 pkg-types: 2.3.0
radix3: 1.1.2 radix3: 1.1.2
@@ -5064,12 +5145,12 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- magicast - magicast
'@nuxt/vite-builder@4.2.0(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)': '@nuxt/vite-builder@4.2.0(@types/node@24.9.2)(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)':
dependencies: dependencies:
'@nuxt/kit': 4.2.0(magicast@0.5.1) '@nuxt/kit': 4.2.0(magicast@0.5.1)
'@rollup/plugin-replace': 6.0.3(rollup@4.52.5) '@rollup/plugin-replace': 6.0.3(rollup@4.52.5)
'@vitejs/plugin-vue': 6.0.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@vitejs/plugin-vue': 6.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
'@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
autoprefixer: 10.4.21(postcss@8.5.6) autoprefixer: 10.4.21(postcss@8.5.6)
consola: 3.4.2 consola: 3.4.2
cssnano: 7.1.2(postcss@8.5.6) cssnano: 7.1.2(postcss@8.5.6)
@@ -5084,7 +5165,7 @@ snapshots:
magic-string: 0.30.21 magic-string: 0.30.21
mlly: 1.8.0 mlly: 1.8.0
mocked-exports: 0.1.1 mocked-exports: 0.1.1
nuxt: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1) nuxt: 4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
pathe: 2.0.3 pathe: 2.0.3
pkg-types: 2.3.0 pkg-types: 2.3.0
postcss: 8.5.6 postcss: 8.5.6
@@ -5093,9 +5174,9 @@ snapshots:
std-env: 3.10.0 std-env: 3.10.0
ufo: 1.6.1 ufo: 1.6.1
unenv: 2.0.0-rc.24 unenv: 2.0.0-rc.24
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vite-node: 3.2.4(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite-node: 3.2.4(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vite-plugin-checker: 0.11.0(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) vite-plugin-checker: 0.11.0(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
vue: 3.5.22(typescript@5.9.3) vue: 3.5.22(typescript@5.9.3)
vue-bundle-renderer: 2.2.0 vue-bundle-renderer: 2.2.0
transitivePeerDependencies: transitivePeerDependencies:
@@ -5562,12 +5643,16 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.16 '@tailwindcss/oxide-win32-arm64-msvc': 4.1.16
'@tailwindcss/oxide-win32-x64-msvc': 4.1.16 '@tailwindcss/oxide-win32-x64-msvc': 4.1.16
'@tailwindcss/vite@4.1.16(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': '@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
dependencies: dependencies:
'@tailwindcss/node': 4.1.16 '@tailwindcss/node': 4.1.16
'@tailwindcss/oxide': 4.1.16 '@tailwindcss/oxide': 4.1.16
tailwindcss: 4.1.16 tailwindcss: 4.1.16
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
'@thaunknown/thirty-two@1.0.5':
dependencies:
uint8-util: 2.2.5
'@tybys/wasm-util@0.10.1': '@tybys/wasm-util@0.10.1':
dependencies: dependencies:
@@ -5578,10 +5663,28 @@ snapshots:
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
'@types/magnet-uri@5.1.5':
dependencies:
'@types/node': 24.9.2
'@types/node@24.9.2':
dependencies:
undici-types: 7.16.0
'@types/parse-path@7.1.0': '@types/parse-path@7.1.0':
dependencies: dependencies:
parse-path: 7.1.0 parse-path: 7.1.0
'@types/parse-torrent-file@4.0.6':
dependencies:
'@types/node': 24.9.2
'@types/parse-torrent@5.8.8':
dependencies:
'@types/magnet-uri': 5.1.5
'@types/node': 24.9.2
'@types/parse-torrent-file': 4.0.6
'@types/resolve@1.20.2': {} '@types/resolve@1.20.2': {}
'@types/web-bluetooth@0.0.21': {} '@types/web-bluetooth@0.0.21': {}
@@ -5768,22 +5871,22 @@ snapshots:
- rollup - rollup
- supports-color - supports-color
'@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': '@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))':
dependencies: dependencies:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
'@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5)
'@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5)
'@rolldown/pluginutils': 1.0.0-beta.45 '@rolldown/pluginutils': 1.0.0-beta.45
'@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5) '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5)
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vue: 3.5.22(typescript@5.9.3) vue: 3.5.22(typescript@5.9.3)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@vitejs/plugin-vue@6.0.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': '@vitejs/plugin-vue@6.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))':
dependencies: dependencies:
'@rolldown/pluginutils': 1.0.0-beta.29 '@rolldown/pluginutils': 1.0.0-beta.29
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vue: 3.5.22(typescript@5.9.3) vue: 3.5.22(typescript@5.9.3)
'@volar/language-core@2.4.23': '@volar/language-core@2.4.23':
@@ -5863,14 +5966,14 @@ snapshots:
'@vue/devtools-api@6.6.4': {} '@vue/devtools-api@6.6.4': {}
'@vue/devtools-core@7.7.7(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': '@vue/devtools-core@7.7.7(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))':
dependencies: dependencies:
'@vue/devtools-kit': 7.7.7 '@vue/devtools-kit': 7.7.7
'@vue/devtools-shared': 7.7.7 '@vue/devtools-shared': 7.7.7
mitt: 3.0.1 mitt: 3.0.1
nanoid: 5.1.6 nanoid: 5.1.6
pathe: 2.0.3 pathe: 2.0.3
vite-hot-client: 2.1.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) vite-hot-client: 2.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
vue: 3.5.22(typescript@5.9.3) vue: 3.5.22(typescript@5.9.3)
transitivePeerDependencies: transitivePeerDependencies:
- vite - vite
@@ -6053,10 +6156,18 @@ snapshots:
bare-events@2.8.1: {} bare-events@2.8.1: {}
base64-arraybuffer@1.0.2: {}
base64-js@1.5.1: {} base64-js@1.5.1: {}
baseline-browser-mapping@2.8.21: {} baseline-browser-mapping@2.8.21: {}
bencode@4.0.0:
dependencies:
uint8-util: 2.2.5
bep53-range@2.0.0: {}
bindings@1.5.0: bindings@1.5.0:
dependencies: dependencies:
file-uri-to-path: 1.0.0 file-uri-to-path: 1.0.0
@@ -6258,6 +6369,11 @@ snapshots:
croner@9.1.0: {} croner@9.1.0: {}
cross-fetch-ponyfill@1.0.3:
dependencies:
abort-controller: 3.0.0
node-fetch: 3.3.2
cross-spawn@7.0.6: cross-spawn@7.0.6:
dependencies: dependencies:
path-key: 3.1.1 path-key: 3.1.1
@@ -6346,6 +6462,8 @@ snapshots:
daisyui@5.3.10: {} daisyui@5.3.10: {}
data-uri-to-buffer@4.0.1: {}
db0@0.3.4: {} db0@0.3.4: {}
debug@4.4.3: debug@4.4.3:
@@ -6739,6 +6857,11 @@ snapshots:
optionalDependencies: optionalDependencies:
picomatch: 4.0.3 picomatch: 4.0.3
fetch-blob@3.2.0:
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.3
figures@6.1.0: figures@6.1.0:
dependencies: dependencies:
is-unicode-supported: 2.1.0 is-unicode-supported: 2.1.0
@@ -6783,6 +6906,10 @@ snapshots:
cross-spawn: 7.0.6 cross-spawn: 7.0.6
signal-exit: 4.1.0 signal-exit: 4.1.0
formdata-polyfill@4.0.10:
dependencies:
fetch-blob: 3.2.0
fraction.js@4.3.7: {} fraction.js@4.3.7: {}
framesync@6.1.2: framesync@6.1.2:
@@ -6804,6 +6931,8 @@ snapshots:
get-port-please@3.2.0: {} get-port-please@3.2.0: {}
get-stdin@9.0.0: {}
get-stream@8.0.1: {} get-stream@8.0.1: {}
get-stream@9.0.1: get-stream@9.0.1:
@@ -7243,6 +7372,12 @@ snapshots:
'@babel/types': 7.28.5 '@babel/types': 7.28.5
source-map-js: 1.2.1 source-map-js: 1.2.1
magnet-uri@7.0.7:
dependencies:
'@thaunknown/thirty-two': 1.0.5
bep53-range: 2.0.0
uint8-util: 2.2.5
mdn-data@2.0.28: {} mdn-data@2.0.28: {}
mdn-data@2.12.2: {} mdn-data@2.12.2: {}
@@ -7421,12 +7556,20 @@ snapshots:
node-addon-api@7.1.1: {} node-addon-api@7.1.1: {}
node-domexception@1.0.0: {}
node-fetch-native@1.6.7: {} node-fetch-native@1.6.7: {}
node-fetch@2.7.0: node-fetch@2.7.0:
dependencies: dependencies:
whatwg-url: 5.0.0 whatwg-url: 5.0.0
node-fetch@3.3.2:
dependencies:
data-uri-to-buffer: 4.0.1
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
node-forge@1.3.1: {} node-forge@1.3.1: {}
node-gyp-build@4.8.4: {} node-gyp-build@4.8.4: {}
@@ -7456,16 +7599,16 @@ snapshots:
dependencies: dependencies:
boolbase: 1.0.0 boolbase: 1.0.0
nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1): nuxt@4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1):
dependencies: dependencies:
'@dxup/nuxt': 0.2.0(magicast@0.5.1) '@dxup/nuxt': 0.2.0(magicast@0.5.1)
'@nuxt/cli': 3.29.3(magicast@0.5.1) '@nuxt/cli': 3.29.3(magicast@0.5.1)
'@nuxt/devtools': 2.7.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/devtools': 2.7.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
'@nuxt/kit': 4.2.0(magicast@0.5.1) '@nuxt/kit': 4.2.0(magicast@0.5.1)
'@nuxt/nitro-server': 4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3) '@nuxt/nitro-server': 4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)
'@nuxt/schema': 4.2.0 '@nuxt/schema': 4.2.0
'@nuxt/telemetry': 2.6.6(magicast@0.5.1) '@nuxt/telemetry': 2.6.6(magicast@0.5.1)
'@nuxt/vite-builder': 4.2.0(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1) '@nuxt/vite-builder': 4.2.0(@types/node@24.9.2)(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.1)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)
'@unhead/vue': 2.0.19(vue@3.5.22(typescript@5.9.3)) '@unhead/vue': 2.0.19(vue@3.5.22(typescript@5.9.3))
'@vue/shared': 3.5.22 '@vue/shared': 3.5.22
c12: 3.3.1(magicast@0.5.1) c12: 3.3.1(magicast@0.5.1)
@@ -7517,6 +7660,7 @@ snapshots:
vue-router: 4.6.3(vue@3.5.22(typescript@5.9.3)) vue-router: 4.6.3(vue@3.5.22(typescript@5.9.3))
optionalDependencies: optionalDependencies:
'@parcel/watcher': 2.5.1 '@parcel/watcher': 2.5.1
'@types/node': 24.9.2
transitivePeerDependencies: transitivePeerDependencies:
- '@azure/app-configuration' - '@azure/app-configuration'
- '@azure/cosmos' - '@azure/cosmos'
@@ -7722,6 +7866,15 @@ snapshots:
parse-statements@1.0.11: {} parse-statements@1.0.11: {}
parse-torrent@11.0.19:
dependencies:
bencode: 4.0.0
cross-fetch-ponyfill: 1.0.3
get-stdin: 9.0.0
magnet-uri: 7.0.7
queue-microtask: 1.2.3
uint8-util: 2.2.5
parse-url@9.2.0: parse-url@9.2.0:
dependencies: dependencies:
'@types/parse-path': 7.1.0 '@types/parse-path': 7.1.0
@@ -8384,6 +8537,10 @@ snapshots:
ufo@1.6.1: {} ufo@1.6.1: {}
uint8-util@2.2.5:
dependencies:
base64-arraybuffer: 1.0.2
ultrahtml@1.6.0: {} ultrahtml@1.6.0: {}
uncrypto@0.1.3: {} uncrypto@0.1.3: {}
@@ -8395,6 +8552,8 @@ snapshots:
magic-string: 0.30.21 magic-string: 0.30.21
unplugin: 2.3.10 unplugin: 2.3.10
undici-types@7.16.0: {}
undici@7.16.0: {} undici@7.16.0: {}
unenv@2.0.0-rc.24: unenv@2.0.0-rc.24:
@@ -8544,23 +8703,23 @@ snapshots:
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
vite-dev-rpc@1.1.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): vite-dev-rpc@1.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)):
dependencies: dependencies:
birpc: 2.6.1 birpc: 2.6.1
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vite-hot-client: 2.1.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) vite-hot-client: 2.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
vite-hot-client@2.1.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): vite-hot-client@2.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)):
dependencies: dependencies:
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vite-node@3.2.4(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): vite-node@3.2.4(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.4.3 debug: 4.4.3
es-module-lexer: 1.7.0 es-module-lexer: 1.7.0
pathe: 2.0.3 pathe: 2.0.3
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- jiti - jiti
@@ -8575,7 +8734,7 @@ snapshots:
- tsx - tsx
- yaml - yaml
vite-plugin-checker@0.11.0(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): vite-plugin-checker@0.11.0(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)):
dependencies: dependencies:
'@babel/code-frame': 7.27.1 '@babel/code-frame': 7.27.1
chokidar: 4.0.3 chokidar: 4.0.3
@@ -8584,14 +8743,14 @@ snapshots:
picomatch: 4.0.3 picomatch: 4.0.3
tiny-invariant: 1.3.3 tiny-invariant: 1.3.3
tinyglobby: 0.2.15 tinyglobby: 0.2.15
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vscode-uri: 3.1.0 vscode-uri: 3.1.0
optionalDependencies: optionalDependencies:
eslint: 9.38.0(jiti@2.6.1) eslint: 9.38.0(jiti@2.6.1)
optionator: 0.9.4 optionator: 0.9.4
typescript: 5.9.3 typescript: 5.9.3
vite-plugin-inspect@11.3.3(@nuxt/kit@3.20.0(magicast@0.3.5))(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)): vite-plugin-inspect@11.3.3(@nuxt/kit@3.20.0(magicast@0.3.5))(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)):
dependencies: dependencies:
ansis: 4.2.0 ansis: 4.2.0
debug: 4.4.3 debug: 4.4.3
@@ -8601,24 +8760,24 @@ snapshots:
perfect-debounce: 2.0.0 perfect-debounce: 2.0.0
sirv: 3.0.2 sirv: 3.0.2
unplugin-utils: 0.3.1 unplugin-utils: 0.3.1
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vite-dev-rpc: 1.1.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) vite-dev-rpc: 1.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
optionalDependencies: optionalDependencies:
'@nuxt/kit': 3.20.0(magicast@0.3.5) '@nuxt/kit': 3.20.0(magicast@0.3.5)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
vite-plugin-vue-tracer@1.0.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): vite-plugin-vue-tracer@1.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)):
dependencies: dependencies:
estree-walker: 3.0.3 estree-walker: 3.0.3
exsolve: 1.0.7 exsolve: 1.0.7
magic-string: 0.30.21 magic-string: 0.30.21
pathe: 2.0.3 pathe: 2.0.3
source-map-js: 1.2.1 source-map-js: 1.2.1
vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
vue: 3.5.22(typescript@5.9.3) vue: 3.5.22(typescript@5.9.3)
vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
dependencies: dependencies:
esbuild: 0.25.11 esbuild: 0.25.11
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
@@ -8627,6 +8786,7 @@ snapshots:
rollup: 4.52.5 rollup: 4.52.5
tinyglobby: 0.2.15 tinyglobby: 0.2.15
optionalDependencies: optionalDependencies:
'@types/node': 24.9.2
fsevents: 2.3.3 fsevents: 2.3.3
jiti: 2.6.1 jiti: 2.6.1
lightningcss: 1.30.2 lightningcss: 1.30.2
@@ -8668,6 +8828,8 @@ snapshots:
optionalDependencies: optionalDependencies:
typescript: 5.9.3 typescript: 5.9.3
web-streams-polyfill@3.3.3: {}
webidl-conversions@3.0.1: {} webidl-conversions@3.0.1: {}
webpack-virtual-modules@0.6.2: {} webpack-virtual-modules@0.6.2: {}

View File

@@ -23,7 +23,7 @@ export default defineEventHandler(async (event) => {
id: maxedMagnet.xt.slice(9), id: maxedMagnet.xt.slice(9),
maxedMagnet: getMagnetUrl(maxedMagnet), maxedMagnet: getMagnetUrl(maxedMagnet),
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) { } catch (error: any) {
throw createError({ throw createError({
statusCode: 400, statusCode: 400,

43
server/api/torrent.ts Normal file
View File

@@ -0,0 +1,43 @@
export default defineEventHandler(async (event) => {
const form = await readMultipartFormData(event);
if (!form || form.length === 0) {
throw createError({ statusCode: 400, statusMessage: "No file uploaded" });
}
// Find the torrent file part (e.g., name="file")
const filePart = form.find((p) => p.name === "file");
if (!filePart || !filePart.data) {
throw createError({
statusCode: 400,
statusMessage: "Missing torrent file",
});
}
// Basic validation
if (!filePart.filename?.toLowerCase().endsWith(".torrent")) {
throw createError({
statusCode: 400,
statusMessage: "File must be a .torrent",
});
}
// Size validation
if (filePart.data.length > 1e6) {
throw createError({
statusCode: 400,
statusMessage: "File size must be less than 1MB",
});
}
const bytes = filePart.data;
const parsed = await parseTorrentFileToMagnetUrl(bytes);
const maxedMagnet = addTrackers(parsed, await getTrackers());
return {
totalTrackers: maxedMagnet.tr?.length,
name: maxedMagnet.dn,
id: maxedMagnet.xt.slice(9),
maxedMagnet: getMagnetUrl(maxedMagnet),
};
});

View File

@@ -0,0 +1,18 @@
import parseTorrent from "parse-torrent";
import type { MagnetUrl } from "../../shared/types/magnet";
export async function parseTorrentFileToMagnetUrl(
file: Buffer
): Promise<MagnetUrl> {
const parsed = await parseTorrent(file);
const magnet: MagnetUrl = {
xt: `urn:btih:${parsed.infoHash}`,
dn: Array.isArray(parsed.name) ? parsed.name.join(" ") : parsed.name,
tr: parsed.announce || [],
xs: parsed.urlList || [],
// as, kt, mt are rarely present in .torrent files, but you can add if needed
};
return magnet;
}