@evjs/cli 0.0.28 → 0.0.29

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.
package/dist/cli.js CHANGED
@@ -2,12 +2,33 @@
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { configure, getConsoleSink, getLogger } from "@logtape/logtape";
5
+ import { configure, getConsoleSink, getLogger, } from "@logtape/logtape";
6
6
  import { Command } from "commander";
7
7
  import { build, dev } from "./index.js";
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
  await configure({
10
- sinks: { console: getConsoleSink() },
10
+ sinks: {
11
+ console: getConsoleSink({
12
+ formatter: (record) => {
13
+ const time = new Date(record.timestamp).toLocaleTimeString("en-US", {
14
+ hour12: false,
15
+ });
16
+ const levelColor = record.level === "info"
17
+ ? "\x1b[36m"
18
+ : record.level === "warning"
19
+ ? "\x1b[33m"
20
+ : record.level === "error" || record.level === "fatal"
21
+ ? "\x1b[31m"
22
+ : "\x1b[32m";
23
+ const reset = "\x1b[0m";
24
+ const cat = record.category[1]
25
+ ? `\x1b[90m[${record.category[1]}]\x1b[0m `
26
+ : "";
27
+ const msg = record.message.map(String).join("");
28
+ return `${levelColor}${time}${reset} ${cat}${msg}\n`;
29
+ },
30
+ }),
31
+ },
11
32
  loggers: [
12
33
  { category: ["logtape", "meta"], lowestLevel: "warning" },
13
34
  { category: ["evjs"], sinks: ["console"], lowestLevel: "info" },
package/dist/index.js CHANGED
@@ -99,10 +99,21 @@ export async function dev(userConfig, options) {
99
99
  // Run buildStart hooks
100
100
  await runBuildStartHooks(hooks);
101
101
  const bundler = await getBundlerAdapter(config);
102
+ // Validate HTML files exist
103
+ if (config.pages) {
104
+ for (const [name, page] of Object.entries(config.pages)) {
105
+ if (!fs.existsSync(path.resolve(cwd, page.html))) {
106
+ throw new Error(`[evjs] MPA page "${name}" html template not found: ${page.html}`);
107
+ }
108
+ }
109
+ }
110
+ else if (!fs.existsSync(path.resolve(cwd, config.html))) {
111
+ throw new Error(`[evjs] HTML template not found: ${config.html}`);
112
+ }
102
113
  // Track the running API server process for lifecycle management.
103
114
  let apiProcess = null;
104
115
  let isFirstBuild = true;
105
- const handleServerBundleReady = () => {
116
+ const handleServerBundleReady = async () => {
106
117
  if (!config.serverEnabled)
107
118
  return;
108
119
  const manifestPath = path.resolve(cwd, "dist/server/manifest.json");
@@ -133,8 +144,16 @@ export async function dev(userConfig, options) {
133
144
  // Kill previous process before restarting (handles both first start and restarts)
134
145
  if (apiProcess) {
135
146
  logger.info `Restarting API server...`;
136
- apiProcess.kill();
147
+ const oldProcess = apiProcess;
137
148
  apiProcess = null;
149
+ oldProcess.kill();
150
+ try {
151
+ await Promise.race([
152
+ oldProcess.catch(() => { }),
153
+ new Promise((resolve) => setTimeout(resolve, 3000)),
154
+ ]);
155
+ }
156
+ catch (e) { }
138
157
  }
139
158
  const serverPort = config?.server?.dev?.port ?? CONFIG_DEFAULTS.serverPort;
140
159
  const runtimeConfig = config?.server?.runtime ?? "node";
@@ -148,7 +167,7 @@ export async function dev(userConfig, options) {
148
167
  }
149
168
  fs.writeFileSync(bootstrapPath, [
150
169
  `const bundle = require(${JSON.stringify(serverBundlePath)});`,
151
- `const app = bundle.app || bundle.createApp({ endpoint: ${JSON.stringify(config.server.endpoint)} });`,
170
+ `const app = bundle.app || bundle.createApp({ functions: { endpoint: ${JSON.stringify(config.server.endpoint)} } });`,
152
171
  `const { serve } = require("@evjs/server/node");`,
153
172
  `serve(app, { port: ${serverPort}, https: ${JSON.stringify(config.server.dev.https)} });`,
154
173
  ].join("\n"));
@@ -197,6 +216,17 @@ export async function build(userConfig, options) {
197
216
  // Run buildStart hooks
198
217
  await runBuildStartHooks(hooks);
199
218
  const bundler = await getBundlerAdapter(config);
219
+ // Validate HTML files exist
220
+ if (config.pages) {
221
+ for (const [name, page] of Object.entries(config.pages)) {
222
+ if (!fs.existsSync(path.resolve(cwd, page.html))) {
223
+ throw new Error(`[evjs] MPA page "${name}" html template not found: ${page.html}`);
224
+ }
225
+ }
226
+ }
227
+ else if (!fs.existsSync(path.resolve(cwd, config.html))) {
228
+ throw new Error(`[evjs] HTML template not found: ${config.html}`);
229
+ }
200
230
  await bundler.build(config, cwd, hooks);
201
231
  // Run buildEnd hooks with manifests
202
232
  const buildResult = readBuildResult(cwd, config.serverEnabled, false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evjs/cli",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "CLI and configuration layer for the evjs framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",