Files
TorrentMax/server/utils/magnetParser.ts

69 lines
1.6 KiB
TypeScript

import type { MagnetUrl } from "../../shared/types/magnet";
export function parseMagnet(magnetUrl: string): MagnetUrl {
if (!magnetUrl.startsWith("magnet:?")) {
throw new Error('Invalid magnet URL: Must start with "magnet:?"');
}
const params = new URLSearchParams(magnetUrl.substring(8)); // Remove 'magnet:?' prefix
const xt = params.get("xt");
if (!xt) {
throw new Error("Invalid magnet URL: Missing required xt parameter");
}
// Validate xt format (btih hash)
const btihRegex = /^urn:btih:([a-fA-F0-9]{40}|[A-Z2-7]{32})$/;
if (!btihRegex.test(xt)) {
throw new Error("Invalid magnet URL: Invalid xt parameter format");
}
const magnet: MagnetUrl = {
xt,
};
const dn = params.get("dn");
if (dn) {
magnet.dn = decodeURIComponent(dn);
}
const tr = params.getAll("tr");
if (tr.length > 0) {
magnet.tr = tr.map(decodeURIComponent);
}
const as = params.getAll("as");
if (as.length > 0) {
magnet.as = as.map(decodeURIComponent);
}
const xs = params.getAll("xs");
if (xs.length > 0) {
magnet.xs = xs.map(decodeURIComponent);
}
const kt = params.get("kt");
if (kt) {
magnet.kt = decodeURIComponent(kt);
}
const mt = params.get("mt");
if (mt) {
magnet.mt = decodeURIComponent(mt);
}
return magnet;
}
export function getMagnetUrl(magnet: MagnetUrl): string {
const params = new URLSearchParams();
Object.entries(magnet).forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach((v) => params.append(`${key}`, v));
} else {
params.append(`${key}`, value);
}
});
return `magnet:?${params.toString()}`;
}