@teamvelix/velix 5.0.2 → 5.0.3

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.
@@ -22,8 +22,8 @@ var image_optimizer_exports = {};
22
22
  __export(image_optimizer_exports, {
23
23
  handleImageOptimization: () => handleImageOptimization
24
24
  });
25
- import fs6 from "fs";
26
- import path6 from "path";
25
+ import fs7 from "fs";
26
+ import path7 from "path";
27
27
  async function handleImageOptimization(req, res, projectRoot) {
28
28
  let sharp;
29
29
  try {
@@ -48,14 +48,14 @@ async function handleImageOptimization(req, res, projectRoot) {
48
48
  if (!response.ok) throw new Error(`Failed to fetch ${imageUrl}`);
49
49
  imageBuffer = Buffer.from(await response.arrayBuffer());
50
50
  } else {
51
- const publicDir = path6.join(projectRoot, "public");
52
- const resolvedPath = path6.join(publicDir, imageUrl.startsWith("/") ? imageUrl.slice(1) : imageUrl);
53
- if (!resolvedPath.startsWith(publicDir) || !fs6.existsSync(resolvedPath)) {
51
+ const publicDir = path7.join(projectRoot, "public");
52
+ const resolvedPath = path7.join(publicDir, imageUrl.startsWith("/") ? imageUrl.slice(1) : imageUrl);
53
+ if (!resolvedPath.startsWith(publicDir) || !fs7.existsSync(resolvedPath)) {
54
54
  res.writeHead(404);
55
55
  res.end("Image not found");
56
56
  return;
57
57
  }
58
- imageBuffer = fs6.readFileSync(resolvedPath);
58
+ imageBuffer = fs7.readFileSync(resolvedPath);
59
59
  }
60
60
  if (!sharp) {
61
61
  res.writeHead(200, {
@@ -92,8 +92,8 @@ var init_image_optimizer = __esm({
92
92
  // server/index.ts
93
93
  init_esm_shims();
94
94
  import http from "http";
95
- import fs7 from "fs";
96
- import path7 from "path";
95
+ import fs8 from "fs";
96
+ import path8 from "path";
97
97
  import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL3 } from "url";
98
98
  import React2 from "react";
99
99
  import { renderToString } from "react-dom/server";
@@ -682,6 +682,8 @@ var builtinPlugins = {
682
682
  // plugins/tailwind.ts
683
683
  init_esm_shims();
684
684
  import { spawnSync, spawn } from "child_process";
685
+ import fs6 from "fs";
686
+ import path6 from "path";
685
687
 
686
688
  // logger.ts
687
689
  init_esm_shims();
@@ -733,14 +735,14 @@ var logger = {
733
735
  if (pagesDir) console.log(` ${c.bold}App:${c.reset} ${c.dim}${pagesDir}${c.reset}`);
734
736
  console.log("");
735
737
  },
736
- request(method, path8, status, time, extra = {}) {
738
+ request(method, path9, status, time, extra = {}) {
737
739
  const statusColor = getStatusColor(status);
738
740
  const timeStr = fmtTime(time);
739
741
  let badge = `${c.dim}\u25CB${c.reset}`;
740
742
  if (extra.type === "dynamic" || extra.type === "ssr") badge = `${c.white}\u0192${c.reset}`;
741
743
  else if (extra.type === "api") badge = `${c.cyan}\u03BB${c.reset}`;
742
744
  const statusStr = `${statusColor}${status}${c.reset}`;
743
- console.log(` ${badge} ${c.white}${method}${c.reset} ${path8} ${statusStr} ${c.dim}${timeStr}${c.reset}`);
745
+ console.log(` ${badge} ${c.white}${method}${c.reset} ${path9} ${statusStr} ${c.dim}${timeStr}${c.reset}`);
744
746
  },
745
747
  info(msg) {
746
748
  console.log(` ${c.cyan}\u2139${c.reset} ${msg}`);
@@ -768,10 +770,10 @@ var logger = {
768
770
  plugin(name) {
769
771
  console.log(` ${c.cyan}\u25C6${c.reset} Plugin ${c.dim}${name}${c.reset}`);
770
772
  },
771
- route(path8, type) {
773
+ route(path9, type) {
772
774
  const typeLabel = type === "api" ? "\u03BB" : type === "dynamic" ? "\u0192" : "\u25CB";
773
775
  const color = type === "api" ? c.cyan : type === "dynamic" ? c.white : c.dim;
774
- console.log(` ${color}${typeLabel}${c.reset} ${path8}`);
776
+ console.log(` ${color}${typeLabel}${c.reset} ${path9}`);
775
777
  },
776
778
  divider() {
777
779
  console.log(`${c.dim} \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}`);
@@ -829,10 +831,39 @@ function tailwindPlugin(options = {}) {
829
831
  },
830
832
  [PluginHooks.SERVER_START]: async (server, isDev) => {
831
833
  if (!isDev) return;
834
+ if (!fs6.existsSync(input)) {
835
+ logger_default.warn(`Tailwind input file not found: ${input}`);
836
+ return;
837
+ }
838
+ const outputDir = path6.dirname(output);
839
+ if (!fs6.existsSync(outputDir)) {
840
+ fs6.mkdirSync(outputDir, { recursive: true });
841
+ }
842
+ logger_default.info("Building initial Tailwind CSS...");
843
+ try {
844
+ const buildResult = spawnSync("npx", ["tailwindcss", "-i", input, "-o", output], {
845
+ cwd: process.cwd(),
846
+ stdio: "pipe"
847
+ });
848
+ if (buildResult.error) {
849
+ logger_default.error("Tailwind CSS not installed. Run: npm install -D tailwindcss");
850
+ return;
851
+ }
852
+ if (buildResult.status !== 0) {
853
+ const errorMsg = buildResult.stderr?.toString() || "Unknown error";
854
+ logger_default.error(`Tailwind build failed: ${errorMsg}`);
855
+ return;
856
+ }
857
+ logger_default.success("Tailwind CSS built successfully");
858
+ } catch (err) {
859
+ logger_default.error("Failed to build Tailwind CSS", err);
860
+ return;
861
+ }
832
862
  logger_default.info("Starting Tailwind CSS watcher...");
833
863
  const watcher = spawn("npx", ["tailwindcss", "-i", input, "-o", output, "--watch"], {
834
864
  stdio: "pipe",
835
- cwd: process.cwd()
865
+ cwd: process.cwd(),
866
+ shell: false
836
867
  });
837
868
  watcher.stdout.on("data", (data) => {
838
869
  const msg = data.toString().trim();
@@ -842,7 +873,7 @@ function tailwindPlugin(options = {}) {
842
873
  });
843
874
  watcher.stderr.on("data", (data) => {
844
875
  const msg = data.toString().trim();
845
- if (msg) {
876
+ if (msg && !msg.includes("warn")) {
846
877
  logger_default.warn(`Tailwind: ${msg}`);
847
878
  }
848
879
  });
@@ -854,9 +885,14 @@ function tailwindPlugin(options = {}) {
854
885
  logger_default.error(`Tailwind watcher exited with code ${code}`);
855
886
  }
856
887
  });
857
- process.on("exit", () => watcher.kill());
858
- process.on("SIGINT", () => watcher.kill());
859
- process.on("SIGTERM", () => watcher.kill());
888
+ const cleanup = () => {
889
+ if (watcher && !watcher.killed) {
890
+ watcher.kill();
891
+ }
892
+ };
893
+ process.on("exit", cleanup);
894
+ process.on("SIGINT", cleanup);
895
+ process.on("SIGTERM", cleanup);
860
896
  }
861
897
  }
862
898
  });
@@ -2031,7 +2067,7 @@ async function createServer(options = {}) {
2031
2067
  await loadPlugins(projectRoot, config);
2032
2068
  await pluginManager.runHook(PluginHooks.CONFIG, config);
2033
2069
  const middlewareFns = await loadMiddleware(projectRoot);
2034
- const appDir = config.resolvedAppDir || path7.join(projectRoot, "app");
2070
+ const appDir = config.resolvedAppDir || path8.join(projectRoot, "app");
2035
2071
  const routes = buildRouteTree(appDir);
2036
2072
  await pluginManager.runHook(PluginHooks.ROUTES_LOADED, routes);
2037
2073
  const startTime = Date.now();
@@ -2073,7 +2109,7 @@ async function createServer(options = {}) {
2073
2109
  await serveVelixInternal(pathname, req, res, projectRoot);
2074
2110
  return;
2075
2111
  }
2076
- const publicDir = config.resolvedPublicDir || path7.join(projectRoot, "public");
2112
+ const publicDir = config.resolvedPublicDir || path8.join(projectRoot, "public");
2077
2113
  if (await serveStaticFile(pathname, publicDir, res, isDev)) {
2078
2114
  if (isDev) logger_default.request(req.method || "GET", pathname, 200, Date.now() - requestStart, { type: "static" });
2079
2115
  return;
@@ -2142,12 +2178,12 @@ async function createServer(options = {}) {
2142
2178
  };
2143
2179
  }
2144
2180
  async function serveStaticFile(pathname, publicDir, res, isDev = false) {
2145
- const filePath = path7.join(publicDir, pathname);
2181
+ const filePath = path8.join(publicDir, pathname);
2146
2182
  if (!filePath.startsWith(publicDir)) return false;
2147
- if (!fs7.existsSync(filePath) || fs7.statSync(filePath).isDirectory()) return false;
2148
- const ext = path7.extname(filePath);
2183
+ if (!fs8.existsSync(filePath) || fs8.statSync(filePath).isDirectory()) return false;
2184
+ const ext = path8.extname(filePath);
2149
2185
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
2150
- const content = fs7.readFileSync(filePath);
2186
+ const content = fs8.readFileSync(filePath);
2151
2187
  res.writeHead(200, {
2152
2188
  "Content-Type": contentType,
2153
2189
  "Content-Length": content.length,
@@ -2227,8 +2263,8 @@ async function handlePageRoute(route, routes, req, res, url, config, isDev, proj
2227
2263
  let LayoutComponent = ({ children }) => React2.createElement(React2.Fragment, null, children);
2228
2264
  let layoutParams = route.params;
2229
2265
  try {
2230
- const layoutPath = path7.join(path7.dirname(route.filePath), "layout.tsx");
2231
- if (fs7.existsSync(layoutPath)) {
2266
+ const layoutPath = path8.join(path8.dirname(route.filePath), "layout.tsx");
2267
+ if (fs8.existsSync(layoutPath)) {
2232
2268
  const layoutMod = await import(`${pathToFileURL3(layoutPath).href}?t=${Date.now()}`);
2233
2269
  if (layoutMod.metadata) {
2234
2270
  metadata = { ...layoutMod.metadata, ...metadata };
@@ -2348,12 +2384,12 @@ async function serveVelixInternal(pathname, req, res, projectRoot) {
2348
2384
  }
2349
2385
  if (pathname === "/__velix/logo.webp") {
2350
2386
  const __filename2 = fileURLToPath2(import.meta.url);
2351
- const __dirname2 = path7.dirname(__filename2);
2352
- const fallbackPath = path7.join(path7.dirname(pathToFileURL3(__dirname2).pathname), "..", "assets", "logo.webp");
2353
- const logoPath = fs7.existsSync(fallbackPath) ? fallbackPath : path7.join(process.cwd(), "node_modules", "velix", "assets", "logo.webp");
2354
- if (fs7.existsSync(logoPath)) {
2387
+ const __dirname2 = path8.dirname(__filename2);
2388
+ const fallbackPath = path8.join(path8.dirname(pathToFileURL3(__dirname2).pathname), "..", "assets", "logo.webp");
2389
+ const logoPath = fs8.existsSync(fallbackPath) ? fallbackPath : path8.join(process.cwd(), "node_modules", "velix", "assets", "logo.webp");
2390
+ if (fs8.existsSync(logoPath)) {
2355
2391
  res.writeHead(200, { "Content-Type": "image/webp", "Cache-Control": "public, max-age=31536000, immutable" });
2356
- res.end(fs7.readFileSync(logoPath));
2392
+ res.end(fs8.readFileSync(logoPath));
2357
2393
  } else {
2358
2394
  res.writeHead(404);
2359
2395
  res.end();
@@ -2364,17 +2400,17 @@ async function serveVelixInternal(pathname, req, res, projectRoot) {
2364
2400
  const componentName = pathname.replace("/__velix/islands/", "").replace(".js", "");
2365
2401
  try {
2366
2402
  const searchDirs = [
2367
- path7.join(projectRoot, "components"),
2368
- path7.join(projectRoot, "app"),
2369
- path7.join(projectRoot, "islands")
2403
+ path8.join(projectRoot, "components"),
2404
+ path8.join(projectRoot, "app"),
2405
+ path8.join(projectRoot, "islands")
2370
2406
  ];
2371
2407
  let componentPath = "";
2372
2408
  for (const dir of searchDirs) {
2373
- if (!fs7.existsSync(dir)) continue;
2374
- const files = fs7.readdirSync(dir, { recursive: true });
2409
+ if (!fs8.existsSync(dir)) continue;
2410
+ const files = fs8.readdirSync(dir, { recursive: true });
2375
2411
  const found = files.find((f) => f.replace(/\\/g, "/").endsWith(`${componentName}.tsx`) || f.replace(/\\/g, "/").endsWith(`${componentName}.jsx`));
2376
2412
  if (found) {
2377
- componentPath = path7.join(dir, found);
2413
+ componentPath = path8.join(dir, found);
2378
2414
  break;
2379
2415
  }
2380
2416
  }