@voltx/cli 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,213 @@
1
+ // src/dev.ts
2
+ import { spawn } from "child_process";
3
+ import { resolve, join } from "path";
4
+ import { existsSync, writeFileSync, unlinkSync } from "fs";
5
+ import { loadEnv } from "@voltx/core";
6
+ async function runDev(options = {}) {
7
+ const cwd = process.cwd();
8
+ const {
9
+ port,
10
+ entry = findEntryPoint(cwd),
11
+ clearScreen = true
12
+ } = options;
13
+ if (!entry) {
14
+ console.error("[voltx] Could not find entry point. Expected server.ts or src/index.ts");
15
+ process.exit(1);
16
+ }
17
+ const entryPath = resolve(cwd, entry);
18
+ if (!existsSync(entryPath)) {
19
+ console.error(`[voltx] Entry file not found: ${entry}`);
20
+ process.exit(1);
21
+ }
22
+ loadEnv("development", cwd);
23
+ const hasViteConfig = existsSync(resolve(cwd, "vite.config.ts"));
24
+ const hasServerEntry = existsSync(resolve(cwd, "server.ts"));
25
+ const isFullStack = hasViteConfig || hasServerEntry;
26
+ if (isFullStack) {
27
+ await startViteDevServer(cwd, port, entry, options);
28
+ } else {
29
+ await startTsxWatch(cwd, port, entry, options);
30
+ }
31
+ }
32
+ async function startViteDevServer(cwd, port, entry, options) {
33
+ const resolvedPort = port ?? (Number(process.env.PORT) || 3e3);
34
+ printDevBanner(entry, resolvedPort, true);
35
+ const userViteConfig = resolve(cwd, "vite.config.ts");
36
+ const hasUserViteConfig = existsSync(userViteConfig);
37
+ let tempConfigPath = null;
38
+ if (!hasUserViteConfig) {
39
+ tempConfigPath = resolve(cwd, "vite.config.voltx.ts");
40
+ const viteConfigContent = generateViteConfig(entry, resolvedPort);
41
+ writeFileSync(tempConfigPath, viteConfigContent, "utf-8");
42
+ }
43
+ const env = {
44
+ ...process.env,
45
+ NODE_ENV: "development"
46
+ };
47
+ if (port) {
48
+ env.PORT = String(port);
49
+ }
50
+ const viteBin = findBin(cwd, "vite");
51
+ const viteArgs = ["dev"];
52
+ if (tempConfigPath) {
53
+ viteArgs.push("--config", tempConfigPath);
54
+ }
55
+ viteArgs.push("--port", String(resolvedPort));
56
+ let child;
57
+ if (viteBin) {
58
+ child = spawn(viteBin, viteArgs, { cwd, env, stdio: "inherit" });
59
+ } else {
60
+ child = spawn("npx", ["vite", ...viteArgs], { cwd, env, stdio: "inherit" });
61
+ }
62
+ const cleanup = () => {
63
+ if (tempConfigPath && existsSync(tempConfigPath)) {
64
+ try {
65
+ unlinkSync(tempConfigPath);
66
+ } catch {
67
+ }
68
+ }
69
+ };
70
+ const signals = ["SIGINT", "SIGTERM"];
71
+ for (const signal of signals) {
72
+ process.on(signal, () => {
73
+ cleanup();
74
+ child.kill(signal);
75
+ });
76
+ }
77
+ child.on("error", (err) => {
78
+ cleanup();
79
+ if (err.code === "ENOENT") {
80
+ console.error("[voltx] vite not found. Install it with: npm install -D vite @hono/vite-dev-server");
81
+ } else {
82
+ console.error("[voltx] Dev server error:", err.message);
83
+ }
84
+ process.exit(1);
85
+ });
86
+ child.on("exit", (code) => {
87
+ cleanup();
88
+ process.exit(code ?? 0);
89
+ });
90
+ }
91
+ function generateViteConfig(entry, port) {
92
+ return `// Auto-generated by VoltX \u2014 do not commit this file
93
+ import { defineConfig } from "vite";
94
+ import devServer from "@hono/vite-dev-server";
95
+ import react from "@vitejs/plugin-react";
96
+ import tailwindcss from "@tailwindcss/vite";
97
+
98
+ export default defineConfig({
99
+ resolve: {
100
+ alias: {
101
+ "@": "/src",
102
+ },
103
+ },
104
+ server: {
105
+ port: ${port},
106
+ },
107
+ plugins: [
108
+ react(),
109
+ tailwindcss(),
110
+ devServer({
111
+ entry: "${entry}",
112
+ exclude: [
113
+ /.*\\.tsx?($|\\?)/,
114
+ /.*\\.(s?css|less)($|\\?)/,
115
+ /.*\\.(svg|png|jpg|jpeg|gif|webp|ico)($|\\?)/,
116
+ /^\\/@.+$/,
117
+ /^\\/favicon\\.svg$/,
118
+ /^\\/node_modules\\/.*/,
119
+ ],
120
+ injectClientScript: false,
121
+ }),
122
+ ],
123
+ });
124
+ `;
125
+ }
126
+ async function startTsxWatch(cwd, port, entry, options) {
127
+ const resolvedPort = port ?? (Number(process.env.PORT) || 3e3);
128
+ printDevBanner(entry, resolvedPort, false);
129
+ const env = {
130
+ ...process.env,
131
+ NODE_ENV: "development"
132
+ };
133
+ if (port) {
134
+ env.PORT = String(port);
135
+ }
136
+ const tsxArgs = ["watch"];
137
+ if (options.clearScreen ?? true) {
138
+ tsxArgs.push("--clear-screen=false");
139
+ }
140
+ tsxArgs.push("--ignore=node_modules", "--ignore=dist", "--ignore=.turbo");
141
+ tsxArgs.push(entry);
142
+ const tsxBin = findBin(cwd, "tsx");
143
+ let child;
144
+ if (tsxBin) {
145
+ child = spawn(tsxBin, tsxArgs, { cwd, env, stdio: "inherit" });
146
+ } else {
147
+ child = spawn("npx", ["tsx", ...tsxArgs], { cwd, env, stdio: "inherit" });
148
+ }
149
+ const signals = ["SIGINT", "SIGTERM"];
150
+ for (const signal of signals) {
151
+ process.on(signal, () => {
152
+ child.kill(signal);
153
+ });
154
+ }
155
+ child.on("error", (err) => {
156
+ if (err.code === "ENOENT") {
157
+ console.error("[voltx] tsx not found. Install it with: npm install -D tsx");
158
+ } else {
159
+ console.error("[voltx] Dev server error:", err.message);
160
+ }
161
+ process.exit(1);
162
+ });
163
+ child.on("exit", (code) => {
164
+ process.exit(code ?? 0);
165
+ });
166
+ }
167
+ function findEntryPoint(cwd) {
168
+ const candidates = [
169
+ "server.ts",
170
+ "server.js",
171
+ "src/index.ts",
172
+ "src/index.js",
173
+ "src/index.mts",
174
+ "src/main.ts",
175
+ "src/main.js",
176
+ "index.ts",
177
+ "index.js"
178
+ ];
179
+ for (const candidate of candidates) {
180
+ if (existsSync(join(cwd, candidate))) {
181
+ return candidate;
182
+ }
183
+ }
184
+ return null;
185
+ }
186
+ function findBin(cwd, name) {
187
+ const paths = [
188
+ join(cwd, "node_modules", ".bin", name),
189
+ join(cwd, "..", "node_modules", ".bin", name),
190
+ join(cwd, "..", "..", "node_modules", ".bin", name)
191
+ ];
192
+ for (const p of paths) {
193
+ if (existsSync(p)) return p;
194
+ }
195
+ return null;
196
+ }
197
+ function printDevBanner(entry, port, fullStack) {
198
+ console.log("");
199
+ console.log(" \u26A1 VoltX Dev Server");
200
+ console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
201
+ console.log(` Entry: ${entry}`);
202
+ console.log(` Port: ${port}`);
203
+ console.log(` Mode: ${fullStack ? "full-stack (Vite + Hono)" : "API-only (tsx watch)"}`);
204
+ if (fullStack) {
205
+ console.log(` HMR: enabled (frontend + backend)`);
206
+ }
207
+ console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
208
+ console.log("");
209
+ }
210
+
211
+ export {
212
+ runDev
213
+ };
package/dist/cli.js CHANGED
@@ -1270,15 +1270,25 @@ function generateViteConfig(entry, port) {
1270
1270
  return `// Auto-generated by VoltX \u2014 do not commit this file
1271
1271
  import { defineConfig } from "vite";
1272
1272
  import devServer from "@hono/vite-dev-server";
1273
+ import react from "@vitejs/plugin-react";
1274
+ import tailwindcss from "@tailwindcss/vite";
1273
1275
 
1274
1276
  export default defineConfig({
1277
+ resolve: {
1278
+ alias: {
1279
+ "@": "/src",
1280
+ },
1281
+ },
1275
1282
  server: {
1276
1283
  port: ${port},
1277
1284
  },
1278
1285
  plugins: [
1286
+ react(),
1287
+ tailwindcss(),
1279
1288
  devServer({
1280
1289
  entry: "${entry}",
1281
1290
  exclude: [
1291
+ /.*\\.tsx?($|\\?)/,
1282
1292
  /.*\\.(s?css|less)($|\\?)/,
1283
1293
  /.*\\.(svg|png|jpg|jpeg|gif|webp|ico)($|\\?)/,
1284
1294
  /^\\/@.+$/,
@@ -1801,7 +1811,7 @@ var init_index = __esm({
1801
1811
  init_build();
1802
1812
  init_start();
1803
1813
  init_generate();
1804
- CLI_VERSION = "0.3.7";
1814
+ CLI_VERSION = "0.4.1";
1805
1815
  }
1806
1816
  });
1807
1817
 
package/dist/dev.js CHANGED
@@ -116,15 +116,25 @@ function generateViteConfig(entry, port) {
116
116
  return `// Auto-generated by VoltX \u2014 do not commit this file
117
117
  import { defineConfig } from "vite";
118
118
  import devServer from "@hono/vite-dev-server";
119
+ import react from "@vitejs/plugin-react";
120
+ import tailwindcss from "@tailwindcss/vite";
119
121
 
120
122
  export default defineConfig({
123
+ resolve: {
124
+ alias: {
125
+ "@": "/src",
126
+ },
127
+ },
121
128
  server: {
122
129
  port: ${port},
123
130
  },
124
131
  plugins: [
132
+ react(),
133
+ tailwindcss(),
125
134
  devServer({
126
135
  entry: "${entry}",
127
136
  exclude: [
137
+ /.*\\.tsx?($|\\?)/,
128
138
  /.*\\.(s?css|less)($|\\?)/,
129
139
  /.*\\.(svg|png|jpg|jpeg|gif|webp|ico)($|\\?)/,
130
140
  /^\\/@.+$/,
package/dist/dev.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runDev
3
- } from "./chunk-JCDKZPUB.mjs";
3
+ } from "./chunk-WK5XRUE4.mjs";
4
4
  export {
5
5
  runDev
6
6
  };
package/dist/index.d.mts CHANGED
@@ -4,6 +4,6 @@ export { BuildOptions, runBuild } from './build.mjs';
4
4
  export { StartOptions, runStart } from './start.mjs';
5
5
  export { GenerateOptions, GeneratorType, runGenerate } from './generate.mjs';
6
6
 
7
- declare const CLI_VERSION = "0.3.7";
7
+ declare const CLI_VERSION = "0.4.1";
8
8
 
9
9
  export { CLI_VERSION };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,6 @@ export { BuildOptions, runBuild } from './build.js';
4
4
  export { StartOptions, runStart } from './start.js';
5
5
  export { GenerateOptions, GeneratorType, runGenerate } from './generate.js';
6
6
 
7
- declare const CLI_VERSION = "0.3.7";
7
+ declare const CLI_VERSION = "0.4.1";
8
8
 
9
9
  export { CLI_VERSION };
package/dist/index.js CHANGED
@@ -1264,15 +1264,25 @@ function generateViteConfig(entry, port) {
1264
1264
  return `// Auto-generated by VoltX \u2014 do not commit this file
1265
1265
  import { defineConfig } from "vite";
1266
1266
  import devServer from "@hono/vite-dev-server";
1267
+ import react from "@vitejs/plugin-react";
1268
+ import tailwindcss from "@tailwindcss/vite";
1267
1269
 
1268
1270
  export default defineConfig({
1271
+ resolve: {
1272
+ alias: {
1273
+ "@": "/src",
1274
+ },
1275
+ },
1269
1276
  server: {
1270
1277
  port: ${port},
1271
1278
  },
1272
1279
  plugins: [
1280
+ react(),
1281
+ tailwindcss(),
1273
1282
  devServer({
1274
1283
  entry: "${entry}",
1275
1284
  exclude: [
1285
+ /.*\\.tsx?($|\\?)/,
1276
1286
  /.*\\.(s?css|less)($|\\?)/,
1277
1287
  /.*\\.(svg|png|jpg|jpeg|gif|webp|ico)($|\\?)/,
1278
1288
  /^\\/@.+$/,
@@ -1737,7 +1747,7 @@ function toCamelCase(str) {
1737
1747
  }
1738
1748
 
1739
1749
  // src/index.ts
1740
- var CLI_VERSION = "0.3.7";
1750
+ var CLI_VERSION = "0.4.1";
1741
1751
  // Annotate the CommonJS export names for ESM import in node:
1742
1752
  0 && (module.exports = {
1743
1753
  CLI_VERSION,
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-X5JEHOO4.mjs";
7
7
  import {
8
8
  runDev
9
- } from "./chunk-JCDKZPUB.mjs";
9
+ } from "./chunk-WK5XRUE4.mjs";
10
10
  import {
11
11
  runGenerate
12
12
  } from "./chunk-7JVIEGSA.mjs";
@@ -16,7 +16,7 @@ import {
16
16
  import "./chunk-IV352HZA.mjs";
17
17
 
18
18
  // src/index.ts
19
- var CLI_VERSION = "0.3.7";
19
+ var CLI_VERSION = "0.4.1";
20
20
  export {
21
21
  CLI_VERSION,
22
22
  createProject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltx/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "VoltX CLI — dev server, build, start, generate, and scaffolding",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -21,13 +21,13 @@
21
21
  "clean": "rm -rf dist"
22
22
  },
23
23
  "dependencies": {
24
- "@voltx/core": "^0.3.2"
24
+ "@voltx/core": "^0.4.1"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "tsx": ">=4.0.0",
28
28
  "tsup": ">=8.0.0",
29
29
  "vite": ">=5.0.0",
30
- "@hono/vite-dev-server": ">=0.7.0"
30
+ "@hono/vite-dev-server": ">=0.19.0"
31
31
  },
32
32
  "peerDependenciesMeta": {
33
33
  "tsx": {