import fs from "node:fs"; import type { IncomingMessage, ServerResponse } from "node:http"; import path from "node:path"; import type { Connect, Plugin, ViteDevServer } from "vite"; export function mp3DownloaderPlugin(): Plugin { return { name: "mp3-downloader", configureServer(server: ViteDevServer) { // Vite dev server middlewares are connect-style: (req, res, next) server.middlewares.use(async (req, res, next) => { const reqUrl = req.url; if (!reqUrl || !reqUrl.startsWith("/uploads/")) return next(); if (!reqUrl.endsWith(".mp3")) return next(); try { await mp3Downloader(req, res, next); } catch (e) { console.error(e, reqUrl); next(); } }); }, }; } async function mp3Downloader( req: Connect.IncomingMessage, res: ServerResponse, next: Connect.NextFunction, ) { const url = new URL(`https://www.howtostudykorean.com/wp-content${req.url}`); const segs = req.url!.slice(1).split("/"); const filename = segs.pop()!; const saveroot = "docs/public"; const saveto = path.join(saveroot, ...segs, filename); if (fs.existsSync(saveto)) { return next(); } fs.mkdirSync(path.join(saveroot, ...segs), { recursive: true }); const r = await fetch(url, { redirect: "follow" }); if (!r.ok) { console.error(r); return next(); } fs.writeFileSync(saveto, Buffer.from(await r.arrayBuffer())); // console.log(fs.statSync(saveto)); console.log("saved to", saveto); res.setHeader("Content-Type", "audio/mpeg"); fs.createReadStream(saveto).pipe(res); }