@teamvelix/velix 5.0.1 → 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,20 +831,68 @@ 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();
839
- if (msg && !msg.includes("Rebuilding...")) {
870
+ if (msg && !msg.includes("Rebuilding...") && !msg.includes("Done in")) {
871
+ logger_default.info(`Tailwind: ${msg}`);
872
+ }
873
+ });
874
+ watcher.stderr.on("data", (data) => {
875
+ const msg = data.toString().trim();
876
+ if (msg && !msg.includes("warn")) {
877
+ logger_default.warn(`Tailwind: ${msg}`);
840
878
  }
841
879
  });
842
880
  watcher.on("error", (err) => {
843
881
  logger_default.error("Tailwind watcher error", err);
844
882
  });
845
- process.on("exit", () => watcher.kill());
883
+ watcher.on("exit", (code) => {
884
+ if (code !== 0 && code !== null) {
885
+ logger_default.error(`Tailwind watcher exited with code ${code}`);
886
+ }
887
+ });
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);
846
896
  }
847
897
  }
848
898
  });
@@ -2017,7 +2067,7 @@ async function createServer(options = {}) {
2017
2067
  await loadPlugins(projectRoot, config);
2018
2068
  await pluginManager.runHook(PluginHooks.CONFIG, config);
2019
2069
  const middlewareFns = await loadMiddleware(projectRoot);
2020
- const appDir = config.resolvedAppDir || path7.join(projectRoot, "app");
2070
+ const appDir = config.resolvedAppDir || path8.join(projectRoot, "app");
2021
2071
  const routes = buildRouteTree(appDir);
2022
2072
  await pluginManager.runHook(PluginHooks.ROUTES_LOADED, routes);
2023
2073
  const startTime = Date.now();
@@ -2059,7 +2109,7 @@ async function createServer(options = {}) {
2059
2109
  await serveVelixInternal(pathname, req, res, projectRoot);
2060
2110
  return;
2061
2111
  }
2062
- const publicDir = config.resolvedPublicDir || path7.join(projectRoot, "public");
2112
+ const publicDir = config.resolvedPublicDir || path8.join(projectRoot, "public");
2063
2113
  if (await serveStaticFile(pathname, publicDir, res, isDev)) {
2064
2114
  if (isDev) logger_default.request(req.method || "GET", pathname, 200, Date.now() - requestStart, { type: "static" });
2065
2115
  return;
@@ -2128,12 +2178,12 @@ async function createServer(options = {}) {
2128
2178
  };
2129
2179
  }
2130
2180
  async function serveStaticFile(pathname, publicDir, res, isDev = false) {
2131
- const filePath = path7.join(publicDir, pathname);
2181
+ const filePath = path8.join(publicDir, pathname);
2132
2182
  if (!filePath.startsWith(publicDir)) return false;
2133
- if (!fs7.existsSync(filePath) || fs7.statSync(filePath).isDirectory()) return false;
2134
- const ext = path7.extname(filePath);
2183
+ if (!fs8.existsSync(filePath) || fs8.statSync(filePath).isDirectory()) return false;
2184
+ const ext = path8.extname(filePath);
2135
2185
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
2136
- const content = fs7.readFileSync(filePath);
2186
+ const content = fs8.readFileSync(filePath);
2137
2187
  res.writeHead(200, {
2138
2188
  "Content-Type": contentType,
2139
2189
  "Content-Length": content.length,
@@ -2213,8 +2263,8 @@ async function handlePageRoute(route, routes, req, res, url, config, isDev, proj
2213
2263
  let LayoutComponent = ({ children }) => React2.createElement(React2.Fragment, null, children);
2214
2264
  let layoutParams = route.params;
2215
2265
  try {
2216
- const layoutPath = path7.join(path7.dirname(route.filePath), "layout.tsx");
2217
- if (fs7.existsSync(layoutPath)) {
2266
+ const layoutPath = path8.join(path8.dirname(route.filePath), "layout.tsx");
2267
+ if (fs8.existsSync(layoutPath)) {
2218
2268
  const layoutMod = await import(`${pathToFileURL3(layoutPath).href}?t=${Date.now()}`);
2219
2269
  if (layoutMod.metadata) {
2220
2270
  metadata = { ...layoutMod.metadata, ...metadata };
@@ -2334,12 +2384,12 @@ async function serveVelixInternal(pathname, req, res, projectRoot) {
2334
2384
  }
2335
2385
  if (pathname === "/__velix/logo.webp") {
2336
2386
  const __filename2 = fileURLToPath2(import.meta.url);
2337
- const __dirname2 = path7.dirname(__filename2);
2338
- const fallbackPath = path7.join(path7.dirname(pathToFileURL3(__dirname2).pathname), "..", "assets", "logo.webp");
2339
- const logoPath = fs7.existsSync(fallbackPath) ? fallbackPath : path7.join(process.cwd(), "node_modules", "velix", "assets", "logo.webp");
2340
- 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)) {
2341
2391
  res.writeHead(200, { "Content-Type": "image/webp", "Cache-Control": "public, max-age=31536000, immutable" });
2342
- res.end(fs7.readFileSync(logoPath));
2392
+ res.end(fs8.readFileSync(logoPath));
2343
2393
  } else {
2344
2394
  res.writeHead(404);
2345
2395
  res.end();
@@ -2350,17 +2400,17 @@ async function serveVelixInternal(pathname, req, res, projectRoot) {
2350
2400
  const componentName = pathname.replace("/__velix/islands/", "").replace(".js", "");
2351
2401
  try {
2352
2402
  const searchDirs = [
2353
- path7.join(projectRoot, "components"),
2354
- path7.join(projectRoot, "app"),
2355
- path7.join(projectRoot, "islands")
2403
+ path8.join(projectRoot, "components"),
2404
+ path8.join(projectRoot, "app"),
2405
+ path8.join(projectRoot, "islands")
2356
2406
  ];
2357
2407
  let componentPath = "";
2358
2408
  for (const dir of searchDirs) {
2359
- if (!fs7.existsSync(dir)) continue;
2360
- const files = fs7.readdirSync(dir, { recursive: true });
2409
+ if (!fs8.existsSync(dir)) continue;
2410
+ const files = fs8.readdirSync(dir, { recursive: true });
2361
2411
  const found = files.find((f) => f.replace(/\\/g, "/").endsWith(`${componentName}.tsx`) || f.replace(/\\/g, "/").endsWith(`${componentName}.jsx`));
2362
2412
  if (found) {
2363
- componentPath = path7.join(dir, found);
2413
+ componentPath = path8.join(dir, found);
2364
2414
  break;
2365
2415
  }
2366
2416
  }