a reactive (signals based) hypermedia web framework (wip)
stormlightlabs.github.io/volt/
hypermedia
frontend
signals
1#!/usr/bin/env node
2/* eslint-disable unicorn/no-process-exit */
3import { buildCommand } from "$commands/build.js";
4import { devCommand } from "$commands/dev.js";
5import { downloadCommand } from "$commands/download.js";
6import { initCommand } from "$commands/init.js";
7import { echo } from "$utils/echo.js";
8import { Command } from "commander";
9
10const program = new Command();
11const isCreateMode = process.argv[1]?.includes("create-voltx");
12
13program.name(isCreateMode ? "create-voltx" : "voltx").description("CLI for creating and managing VoltX.js applications")
14 .version("0.1.0");
15
16program.command("init [project-name]").description("Create a new VoltX.js project").action(
17 async (projectName: string | undefined) => {
18 try {
19 await initCommand(projectName);
20 } catch (error) {
21 echo.err("Error creating project:", error);
22 process.exit(1);
23 }
24 },
25);
26
27program.command("dev").description("Start development server").option(
28 "-p, --port <port>",
29 "Port to run the dev server on",
30 "3000",
31).option("-o, --open", "Open browser automatically", false).action(
32 async (options: { port?: string; open?: boolean }) => {
33 try {
34 const port = options.port ? Number.parseInt(options.port, 10) : 3000;
35 await devCommand({ port, open: options.open });
36 } catch (error) {
37 echo.err("Error starting dev server:", error);
38 process.exit(1);
39 }
40 },
41);
42
43program.command("build").description("Build project for production").option("--out <dir>", "Output directory", "dist")
44 .action(async (options: { out?: string }) => {
45 try {
46 await buildCommand({ outDir: options.out });
47 } catch (error) {
48 echo.err("Error building project:", error);
49 process.exit(1);
50 }
51 });
52
53program.command("download").description("Download VoltX.js assets (JS and CSS)").option(
54 "--version <version>",
55 "VoltX.js version to download",
56 "latest",
57).option("--no-js", "Skip downloading JavaScript file").option("--no-css", "Skip downloading CSS file").option(
58 "-o, --output <dir>",
59 "Output directory",
60 ".",
61).action(async (options: { version?: string; js?: boolean; css?: boolean; output?: string }) => {
62 try {
63 await downloadCommand(options);
64 } catch (error) {
65 echo.err("Error downloading assets:", error);
66 process.exit(1);
67 }
68});
69
70if (isCreateMode && process.argv.length === 2) {
71 initCommand().catch((error) => {
72 echo.err("Error:", error);
73 process.exit(1);
74 });
75} else if (isCreateMode && process.argv.length === 3 && !process.argv[2]?.startsWith("-")) {
76 initCommand(process.argv[2]).catch((error) => {
77 echo.err("Error:", error);
78 process.exit(1);
79 });
80} else {
81 program.parse();
82}