import { a as green, c as url, i as gray, l as yellow, n as bold, o as magenta, r as cyan, s as red } from "./_chunks/_color.mjs"; import { parseArgs } from "node:util"; import { fileURLToPath, pathToFileURL } from "node:url"; import * as nodeHTTP$1 from "node:http"; import { dirname, extname, relative, resolve } from "node:path"; import { fork } from "node:child_process"; import { existsSync } from "node:fs"; //#region src/cli.ts const defaultEntries = [ "server", "index", "src/server", "src/index", "server/index" ]; const defaultExts = [ ".mts", ".ts", ".cts", ".js", ".mjs", ".cjs", ".jsx", ".tsx" ]; const args = process.argv.slice(2); const options = parseArgs$1(args); if (process.send) { setupProcessErrorHandlers(); await serve(); } async function main(mainOpts) { setupProcessErrorHandlers(); if (options._version) { console.log(await version()); process.exit(0); } if (options._help) { console.log(usage(mainOpts)); process.exit(options._help ? 0 : 1); } const isBun = !!process.versions.bun; const isDeno = !!process.versions.deno; const isNode = !isBun && !isDeno; const runtimeArgs = []; if (!options._prod) runtimeArgs.push("--watch"); if (isNode || isDeno) runtimeArgs.push(...[".env", options._prod ? ".env.production" : ".env.local"].filter((f) => existsSync(f)).map((f) => `--env-file=${f}`)); if (isNode) { const [major, minor] = process.versions.node.split("."); if (major === "22" && +minor >= 6) runtimeArgs.push("--experimental-strip-types"); if (options._import) runtimeArgs.push(`--import=${options._import}`); } const child = fork(fileURLToPath(import.meta.url), args, { execArgv: [...process.execArgv, ...runtimeArgs].filter(Boolean) }); child.on("error", (error) => { console.error("Error in child process:", error); process.exit(1); }); child.on("exit", (code) => { if (code !== 0) { console.error(`Child process exited with code ${code}`); process.exit(code); } }); let cleanupCalled = false; const cleanup = (signal, exitCode) => { if (cleanupCalled) return; cleanupCalled = true; try { child.kill(signal || "SIGTERM"); } catch (error) { console.error("Error killing child process:", error); } if (exitCode !== void 0) process.exit(exitCode); }; process.on("exit", () => cleanup("SIGTERM")); process.on("SIGINT", () => cleanup("SIGINT", 130)); process.on("SIGTERM", () => cleanup("SIGTERM", 143)); } async function serve() { try { if (!process.env.NODE_ENV) process.env.NODE_ENV = options._prod ? "production" : "development"; const entry = await loadEntry(options); const { serve: srvxServe } = entry._legacyNode ? await import("srvx/node") : await import("srvx"); const { serveStatic } = await import("srvx/static"); const { log } = await import("srvx/log"); const staticDir = resolve(options._dir, options._static); options._static = existsSync(staticDir) ? staticDir : ""; const server = srvxServe({ error: (error) => { console.error(error); return renderError(error); }, ...entry, middleware: [ log(), options._static ? serveStatic({ dir: options._static }) : void 0, ...entry.middleware || [] ].filter(Boolean) }); globalThis.__srvx__ = server; await server.ready(); await globalThis.__srvx_listen_cb__?.(); printInfo(entry); } catch (error) { console.error(error); process.exit(1); } } async function loadEntry(opts) { try { if (!opts._entry) for (const entry of defaultEntries) { for (const ext of defaultExts) { const entryPath = resolve(opts._dir, `${entry}${ext}`); if (existsSync(entryPath)) { opts._entry = entryPath; break; } } if (opts._entry) break; } if (!opts._entry) { const _error$1 = `No server entry file found.\nPlease specify an entry file or ensure one of the default entries exists (${defaultEntries.join(", ")}).`; return { _error: _error$1, fetch: () => renderError(_error$1, 404, "No Server Entry"), ...opts }; } const entryURL = opts._entry.startsWith("file://") ? opts._entry : pathToFileURL(resolve(opts._entry)).href; const { res: mod, listenHandler } = await interceptListen(() => import(entryURL)); let fetchHandler = mod.fetch || mod.default?.fetch || mod.default?.default?.fetch; let _legacyNode = false; if (!fetchHandler) { const nodeHandler = listenHandler || (typeof mod.default === "function" ? mod.default : void 0); if (nodeHandler) { _legacyNode = true; const { callNodeHandler } = await import("./_chunks/call2.mjs"); fetchHandler = (webReq) => callNodeHandler(nodeHandler, webReq); } } let _error; if (!fetchHandler) { _error = `The entry file "${relative(".", opts._entry)}" does not export a valid fetch handler.`; fetchHandler = () => renderError(_error, 500, "Invalid Entry"); } return { ...mod, ...mod.default, ...opts, _error, _legacyNode, fetch: fetchHandler }; } catch (error) { if (error?.code === "ERR_UNKNOWN_FILE_EXTENSION") { const message = String(error); if (/"\.(m|c)?ts"/g.test(message)) console.error(red(`\nMake sure you're using Node.js v22.18+ or v24+ for TypeScript support (current version: ${process.versions.node})\n\n`)); else if (/"\.(m|c)?tsx"/g.test(message)) console.error(red(`\nYou need a compatible loader for JSX support (Deno, Bun or srvx --register jiti/register)\n\n`)); } if (error instanceof Error) Error.captureStackTrace?.(error, serve); throw error; } } function renderError(error, status = 500, title = "Server Error") { let html = `
Something went wrong while processing your request.
`; else html += `${error instanceof Error ? error.stack || error.message : String(error)}