UNPKG

@naria2/node

Version:

Cross-platform wrapper of aria2

126 lines (120 loc) 4.19 kB
'use strict'; const path = require('node:path'); const node_url = require('node:url'); const node_fs = require('node:fs'); const getPort = require('get-port'); var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const path__default = /*#__PURE__*/_interopDefaultCompat(path); const getPort__default = /*#__PURE__*/_interopDefaultCompat(getPort); async function launchWebUI(options) { const serveStatic = interopDefaultCompat(await import('serve-static')); const finalhandler = interopDefaultCompat(await import('finalhandler')); const http = await import('http'); const host = options.host; const port = await getPort__default({ host: options.host, port: options.port }); const clientDir = node_url.fileURLToPath(new URL("../client", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('ui.cjs', document.baseURI).href)))); const serve = serveStatic(clientDir, { index: ["index.html"] }); const handler = await createWebUIHandler(options); const server = http.createServer(async (req, res) => { if (await handler(req, res)) { return; } if (req.url?.startsWith("/connect")) { req.url = req.url.replace("/connect", "/"); } serve(req, res, finalhandler(req, res)); }); server.listen(port, options.host); return { server, host, port, url: `http://${host ?? "0.0.0.0"}:${port}?port=${options.rpc.port}${options.rpc.secret ? `&secret=${options.rpc.secret}` : ""}` }; } async function attachWebUI(_socket, options = {}) { const socket = await _socket; const { server, host, port, url } = await launchWebUI({ host: options.host, port: options.port ?? socket.getOptions().listenPort + 1, rpc: { port: socket.getOptions().listenPort, secret: socket.getOptions().secret } }); socket.onClose(() => { server.close(); }); return { socket, server, host, port, url }; } async function createWebUIHandler(options) { const { createProxyMiddleware } = await import('http-proxy-middleware'); const proxyMiddleware = createProxyMiddleware({ target: `http://127.0.0.1:${options.rpc.port}`, changeOrigin: false, ws: true, logger: void 0 }); return async (req, res) => { if (!req.url) return false; try { const url = new URL(req.url, `http://${req.headers.host}`); if (url.pathname === "/jsonrpc") { await proxyMiddleware(req, res, () => { }); return true; } else if (url.pathname === "/_/open") { return await handleWebUIOpenRequest(url, req, res, options); } return false; } catch (error) { return false; } }; } async function handleWebUIOpenRequest(url, req, res, options) { try { const auth = req.headers.authorization; res.setHeader("Content-Type", "application/json"); if (options.rpc.secret && options.rpc.secret !== auth) { res.statusCode = 400; res.write(JSON.stringify({ status: "ERROR" })); } else { const dir = url.searchParams.get("dir"); if (dir) { const open = interopDefaultCompat(await import('open')); const p = decodeURIComponent(dir); const stat = await node_fs.promises.stat(p); if (stat.isDirectory()) { await open(p).catch(() => { }); res.write(JSON.stringify({ status: "OK", open: p })); } else { const d = path__default.dirname(p); await open(d).catch(() => { }); res.write(JSON.stringify({ status: "OK", open: d })); } } } res.end(); return true; } catch (error) { return false; } } function interopDefaultCompat(mod) { return mod.default ?? mod; } exports.attachWebUI = attachWebUI; exports.createWebUIHandler = createWebUIHandler; exports.handleWebUIOpenRequest = handleWebUIOpenRequest; exports.launchWebUI = launchWebUI;