Files
torbox-admin/scripts/start.mjs
T
2026-10-16 09:03:23 -07:00

64 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 统一启动入口:本地运行 Next CLI,Docker 保留 standalone,两者共管 WebDAV 生命周期。
import { execFile, spawn } from "node:child_process";
import { createRequire } from "node:module";
import { getWebdavConfig } from "../src/server/webdav/config.mjs";
const mode = process.argv[2] || "standalone";
if (!["dev", "start", "standalone"].includes(mode))
throw new Error("启动模式必须为 dev、start 或 standalone");
const local = mode !== "standalone";
const load = createRequire(import.meta.url);
if (local) {
process.env.NODE_ENV = mode === "dev" ? "development" : "production";
// 复用当前 Next 安装中的 env loader,与 Next 的 .env* 优先级和变量展开保持一致。
const loadNext = createRequire(load.resolve("next/package.json"));
loadNext("@next/env").loadEnvConfig(process.cwd(), mode === "dev");
process.env.PORT = process.env.PORT?.trim() || "3200";
process.env.WEBDAV_PORT = process.env.WEBDAV_PORT?.trim() || "3201";
}
const config = getWebdavConfig();
if (config.enabled && config.port === Number(process.env.PORT))
throw new Error("WebDAV 与管理页不能使用相同端口");
const children = [];
let stopping = false;
const stop = (code = 0) => {
if (stopping) return;
stopping = true;
process.exitCode = code;
for (const child of children) {
if (child.exitCode !== null || child.signalCode !== null) continue;
// next dev 还会创建服务进程;Windows 必须结束整个子进程树,避免残留监听端口。
if (process.platform === "win32")
execFile("taskkill", ["/PID", String(child.pid), "/T", "/F"], () => {});
else child.kill("SIGTERM");
}
setTimeout(() => {
for (const child of children) child.kill("SIGKILL");
}, 6000).unref();
};
const start = (file, args = [], env = process.env) => {
const child = spawn(process.execPath, [file, ...args], {
stdio: "inherit",
env
});
children.push(child);
child.on("error", () => stop(1));
child.on("exit", (code, signal) => {
if (!stopping) stop(code || (signal ? 1 : 0));
});
};
if (local)
start(load.resolve("next/dist/bin/next"), [mode, "-p", process.env.PORT]);
else start("server.js");
if (config.enabled) {
const env = { ...process.env };
// 本地无密钥的演示模式沿用网页的 mock 密钥,不改变 Next 进程的演示提示。
if (local && !env.TORBOX_API_KEY?.trim() && !env.ACCESS_TOKEN?.trim())
env.ACCESS_TOKEN = "mock";
start("scripts/webdav.mjs", [], env);
}
process.once("SIGINT", () => stop());
process.once("SIGTERM", () => stop());