diff --git a/.changeset/blue-turkeys-pay.md b/.changeset/blue-turkeys-pay.md new file mode 100644 index 00000000..c485b75c --- /dev/null +++ b/.changeset/blue-turkeys-pay.md @@ -0,0 +1,5 @@ +--- +"vinxi": patch +--- + +feat: add vinxi serve command (static file server), options --dir, --host, --port, --base diff --git a/packages/vinxi/bin/cli.mjs b/packages/vinxi/bin/cli.mjs index 10c9fcae..89ffc3cd 100755 --- a/packages/vinxi/bin/cli.mjs +++ b/packages/vinxi/bin/cli.mjs @@ -197,7 +197,7 @@ const command = defineCommand({ async run({ args }) { const configFile = args.config; globalThis.MANIFEST = {}; - const { log, c } = await import("../lib/logger.js"); + const { log, c } = await import("../lib/logger.js"); log(c.dim(c.yellow(packageJson.version))); const { loadApp } = await import("../lib/load-app.js"); const app = await loadApp(configFile, args); @@ -330,6 +330,57 @@ const command = defineCommand({ } }, }, + serve: { + meta: { + name: "serve", + version: packageJson.version, + description: "Serve a static directory", + }, + args: { + port: { + type: "number", + description: "Port to listen on (default: 3000)", + }, + host: { + type: "boolean", + description: "Expose to host (default: false)", + }, + dir: { + type: "string", + description: "Directory to serve (default: cwd)", + }, + base: { + type: "string", + description: "Base path", + }, + }, + async run(context) { + const { createApp, fromNodeMiddleware, toNodeListener } = await import( + "h3" + ); + const { listen } = await import("@vinxi/listhen"); + const { isAbsolute, join } = await import("../lib/path.js"); + const { default: serveStatic } = await import("serve-static"); + + const app = createApp(); + app.use( + context.args.base ?? "/", + fromNodeMiddleware( + serveStatic( + context.args.dir + ? isAbsolute(context.args.dir) + ? context.args.dir + : join(process.cwd(), context.args.dir) + : process.cwd(), + ), + ), + ); + + await listen(toNodeListener(app), { + port: context.args.port ?? 3000, + }); + }, + }, }), });