@zenithbuild/core 0.3.3 → 0.4.2

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/zen-build.js CHANGED
@@ -92,8 +92,8 @@ var require_picocolors = __commonJS((exports, module) => {
92
92
  import process2 from "process";
93
93
 
94
94
  // cli/commands/dev.ts
95
- import path4 from "path";
96
- import fs4 from "fs";
95
+ import path5 from "path";
96
+ import fs5 from "fs";
97
97
  var {serve } = globalThis.Bun;
98
98
 
99
99
  // cli/utils/project.ts
@@ -141,34 +141,161 @@ function requireProject(cwd = process.cwd()) {
141
141
  }
142
142
 
143
143
  // cli/utils/logger.ts
144
- var colors = {
145
- reset: "\x1B[0m",
146
- bright: "\x1B[1m",
147
- dim: "\x1B[2m",
148
- red: "\x1B[31m",
149
- green: "\x1B[32m",
150
- yellow: "\x1B[33m",
151
- blue: "\x1B[34m",
152
- cyan: "\x1B[36m"
153
- };
144
+ var import_picocolors = __toESM(require_picocolors(), 1);
154
145
  function log(message) {
155
- console.log(`${colors.cyan}[zenith]${colors.reset} ${message}`);
146
+ console.log(`${import_picocolors.default.cyan("[zenith]")} ${message}`);
156
147
  }
157
148
  function success(message) {
158
- console.log(`${colors.green}\u2713${colors.reset} ${message}`);
149
+ console.log(`${import_picocolors.default.green("\u2713")} ${message}`);
159
150
  }
160
151
  function warn(message) {
161
- console.log(`${colors.yellow}\u26A0${colors.reset} ${message}`);
152
+ console.log(`${import_picocolors.default.yellow("\u26A0")} ${message}`);
162
153
  }
163
154
  function error(message) {
164
- console.error(`${colors.red}\u2717${colors.reset} ${message}`);
155
+ console.error(`${import_picocolors.default.red("\u2717")} ${message}`);
165
156
  }
166
157
  function info(message) {
167
- console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
158
+ console.log(`${import_picocolors.default.blue("\u2139")} ${message}`);
168
159
  }
169
160
  function header(title) {
170
161
  console.log(`
171
- ${colors.bright}${colors.cyan}${title}${colors.reset}
162
+ ${import_picocolors.default.bold(import_picocolors.default.cyan(title))}
163
+ `);
164
+ }
165
+ function hmr(type, path2) {
166
+ console.log(`${import_picocolors.default.magenta("[HMR]")} ${import_picocolors.default.bold(type)} updated: ${import_picocolors.default.dim(path2)}`);
167
+ }
168
+ function route(method, path2, status, totalMs, compileMs, renderMs) {
169
+ const statusColor = status < 400 ? import_picocolors.default.green : import_picocolors.default.red;
170
+ const timeColor = totalMs > 1000 ? import_picocolors.default.yellow : import_picocolors.default.gray;
171
+ console.log(`${import_picocolors.default.bold(method)} ${import_picocolors.default.cyan(path2.padEnd(15))} ` + `${statusColor(status)} ${import_picocolors.default.dim("in")} ${timeColor(`${totalMs}ms`)} ` + `${import_picocolors.default.dim(`(compile: ${compileMs}ms, render: ${renderMs}ms)`)}`);
172
+ }
173
+
174
+ // cli/utils/branding.ts
175
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
176
+ var colors = {
177
+ primary: import_picocolors2.default.blue,
178
+ secondary: import_picocolors2.default.cyan,
179
+ success: import_picocolors2.default.green,
180
+ warning: import_picocolors2.default.yellow,
181
+ error: import_picocolors2.default.red,
182
+ muted: import_picocolors2.default.gray,
183
+ bold: import_picocolors2.default.bold,
184
+ dim: import_picocolors2.default.dim
185
+ };
186
+ var LOGO = `
187
+ ${import_picocolors2.default.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
188
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.cyan("\u2551")}
189
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2588\u2557 \u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2557 \u2588\u2588\u2557"))} ${import_picocolors2.default.cyan("\u2551")}
190
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.bold(import_picocolors2.default.blue("\u255A\u2550\u2550\u2588\u2588\u2588\u2554\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2551 \u2588\u2588\u2551"))} ${import_picocolors2.default.cyan("\u2551")}
191
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.bold(import_picocolors2.default.blue(" \u2588\u2588\u2588\u2554\u255D "))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2557 "))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.blue(" \u2588\u2588\u2551 "))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551"))} ${import_picocolors2.default.cyan("\u2551")}
192
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.bold(import_picocolors2.default.blue(" \u2588\u2588\u2588\u2554\u255D "))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2554\u2550\u2550\u255D "))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.blue(" \u2588\u2588\u2551 "))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551"))} ${import_picocolors2.default.cyan("\u2551")}
193
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2551"))}${import_picocolors2.default.bold(import_picocolors2.default.blue(" \u2588\u2588\u2551 "))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u2588\u2588\u2551 \u2588\u2588\u2551"))} ${import_picocolors2.default.cyan("\u2551")}
194
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.bold(import_picocolors2.default.blue("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.blue("\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u255A\u2550\u255D"))}${import_picocolors2.default.bold(import_picocolors2.default.blue(" \u255A\u2550\u255D "))}${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u255A\u2550\u255D \u255A\u2550\u255D"))} ${import_picocolors2.default.cyan("\u2551")}
195
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.cyan("\u2551")}
196
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.dim("The Modern Reactive Web Framework")} ${import_picocolors2.default.cyan("\u2551")}
197
+ ${import_picocolors2.default.cyan("\u2551")} ${import_picocolors2.default.cyan("\u2551")}
198
+ ${import_picocolors2.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")}
199
+ `;
200
+ var LOGO_COMPACT = `
201
+ ${import_picocolors2.default.bold(import_picocolors2.default.blue("\u26A1"))} ${import_picocolors2.default.bold(import_picocolors2.default.cyan("ZENITH"))} ${import_picocolors2.default.dim("- Modern Reactive Framework")}
202
+ `;
203
+ var spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
204
+
205
+ class Spinner {
206
+ interval = null;
207
+ frameIndex = 0;
208
+ message;
209
+ constructor(message) {
210
+ this.message = message;
211
+ }
212
+ start() {
213
+ this.interval = setInterval(() => {
214
+ process.stdout.write(`\r${import_picocolors2.default.cyan(spinnerFrames[this.frameIndex])} ${this.message}`);
215
+ this.frameIndex = (this.frameIndex + 1) % spinnerFrames.length;
216
+ }, 80);
217
+ }
218
+ stop(finalMessage) {
219
+ if (this.interval) {
220
+ clearInterval(this.interval);
221
+ this.interval = null;
222
+ }
223
+ process.stdout.write("\r" + " ".repeat(this.message.length + 5) + "\r");
224
+ if (finalMessage) {
225
+ console.log(finalMessage);
226
+ }
227
+ }
228
+ succeed(message) {
229
+ this.stop(`${import_picocolors2.default.green("\u2713")} ${message}`);
230
+ }
231
+ fail(message) {
232
+ this.stop(`${import_picocolors2.default.red("\u2717")} ${message}`);
233
+ }
234
+ }
235
+ function showLogo() {
236
+ console.log(LOGO);
237
+ }
238
+ function header2(text) {
239
+ console.log(`
240
+ ${import_picocolors2.default.bold(import_picocolors2.default.cyan("\u25B8"))} ${import_picocolors2.default.bold(text)}
241
+ `);
242
+ }
243
+ function error2(text) {
244
+ console.log(`${import_picocolors2.default.red("\u2717")} ${text}`);
245
+ }
246
+ function warn2(text) {
247
+ console.log(`${import_picocolors2.default.yellow("\u26A0")} ${text}`);
248
+ }
249
+ function info2(text) {
250
+ console.log(`${import_picocolors2.default.blue("\u2139")} ${text}`);
251
+ }
252
+ function highlight(text) {
253
+ return import_picocolors2.default.cyan(text);
254
+ }
255
+ function dim(text) {
256
+ return import_picocolors2.default.dim(text);
257
+ }
258
+ function bold(text) {
259
+ return import_picocolors2.default.bold(text);
260
+ }
261
+ async function showIntro() {
262
+ console.clear();
263
+ showLogo();
264
+ await sleep(300);
265
+ }
266
+ function sleep(ms) {
267
+ return new Promise((resolve) => setTimeout(resolve, ms));
268
+ }
269
+ function showNextSteps(projectName) {
270
+ console.log(`
271
+ ${import_picocolors2.default.cyan("\u250C\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")}
272
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("\u2502")}
273
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.green("\u2728")} ${import_picocolors2.default.bold("Your Zenith app is ready!")} ${import_picocolors2.default.cyan("\u2502")}
274
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("\u2502")}
275
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.dim("Next steps:")} ${import_picocolors2.default.cyan("\u2502")}
276
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("\u2502")}
277
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("$")} ${import_picocolors2.default.bold(`cd ${projectName}`)}${" ".repeat(Math.max(0, 40 - projectName.length))}${import_picocolors2.default.cyan("\u2502")}
278
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("$")} ${import_picocolors2.default.bold("bun run dev")} ${import_picocolors2.default.cyan("\u2502")}
279
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("\u2502")}
280
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.dim("Then open")} ${import_picocolors2.default.underline(import_picocolors2.default.blue("http://localhost:3000"))} ${import_picocolors2.default.cyan("\u2502")}
281
+ ${import_picocolors2.default.cyan("\u2502")} ${import_picocolors2.default.cyan("\u2502")}
282
+ ${import_picocolors2.default.cyan("\u2514\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518")}
283
+ `);
284
+ }
285
+ function showServerPanel(options) {
286
+ console.clear();
287
+ console.log(LOGO_COMPACT);
288
+ console.log(`${import_picocolors2.default.cyan("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}`);
289
+ console.log(` ${import_picocolors2.default.magenta("\uD83D\uDFE3 Zenith Dev Server")}`);
290
+ console.log(`${import_picocolors2.default.cyan("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}`);
291
+ console.log(` ${import_picocolors2.default.bold("Project:")} ${import_picocolors2.default.dim(options.project)}`);
292
+ console.log(` ${import_picocolors2.default.bold("Pages:")} ${import_picocolors2.default.dim(options.pages)}`);
293
+ console.log(` ${import_picocolors2.default.bold("Mode:")} ${import_picocolors2.default.cyan(options.mode)} ${import_picocolors2.default.dim(`(${options.hmr ? "HMR enabled" : "HMR disabled"})`)}`);
294
+ console.log(`${import_picocolors2.default.cyan("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}`);
295
+ console.log(` ${import_picocolors2.default.bold("Server:")} ${import_picocolors2.default.cyan(import_picocolors2.default.underline(options.url))} ${import_picocolors2.default.dim("(clickable)")}`);
296
+ console.log(` ${import_picocolors2.default.bold("Hot Reload:")} ${options.hmr ? import_picocolors2.default.green("Enabled \u2705") : import_picocolors2.default.red("Disabled \u2717")}`);
297
+ console.log(`${import_picocolors2.default.cyan("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}`);
298
+ console.log(` ${import_picocolors2.default.dim("Press Ctrl+C to stop")}
172
299
  `);
173
300
  }
174
301
 
@@ -1486,9 +1613,9 @@ class Tokenizer {
1486
1613
  this._err(ERR.absenceOfDigitsInNumericCharacterReference, this.entityStartPos - this.preprocessor.pos + consumed);
1487
1614
  },
1488
1615
  validateNumericCharacterReference: (code) => {
1489
- const error2 = getErrorForNumericCharacterReference(code);
1490
- if (error2)
1491
- this._err(error2, 1);
1616
+ const error3 = getErrorForNumericCharacterReference(code);
1617
+ if (error3)
1618
+ this._err(error3, 1);
1492
1619
  }
1493
1620
  } : undefined);
1494
1621
  }
@@ -8047,8 +8174,8 @@ function parseTemplate(html, filePath) {
8047
8174
  nodes,
8048
8175
  expressions
8049
8176
  };
8050
- } catch (error2) {
8051
- throw new CompilerError(`Template parsing failed: ${error2.message}`, filePath, 1, 1);
8177
+ } catch (error3) {
8178
+ throw new CompilerError(`Template parsing failed: ${error3.message}`, filePath, 1, 1);
8052
8179
  }
8053
8180
  }
8054
8181
 
@@ -9139,6 +9266,7 @@ function transformStateDeclarations(script) {
9139
9266
  transformed = transformed.replace(/export\s+let\s+props(?:\s*:\s*([^;]+))?\s*;?[ \t]*/g, "");
9140
9267
  transformed = transformed.replace(/(?:type|interface)\s+Props\s*=?\s*\{[^}]*(?:\{[^}]*\}[^}]*)*\}[ \t]*;?/gs, "");
9141
9268
  transformed = transformed.replace(/import\s+{[^}]+}\s+from\s+['"]zenith\/runtime['"]\s*;?[ \t]*/g, "");
9269
+ transformed = transformed.replace(/import\s*{\s*([^}]+)\s*}\s*from\s*['"]zenith:content['"]\s*;?/g, (_, imports) => `const { ${imports.trim()} } = window.__zenith;`);
9142
9270
  return transformed.trim();
9143
9271
  }
9144
9272
 
@@ -9406,9 +9534,9 @@ function validateSingleExpression(expr, filePath) {
9406
9534
  if (!hasJSX) {
9407
9535
  try {
9408
9536
  new Function("state", "loaderData", "props", "stores", `return ${code}`);
9409
- } catch (error2) {
9537
+ } catch (error3) {
9410
9538
  errors.push(new CompilerError(`Invalid expression syntax: ${code}
9411
- ${error2.message}`, filePath, location.line, location.column));
9539
+ ${error3.message}`, filePath, location.line, location.column));
9412
9540
  }
9413
9541
  }
9414
9542
  if (code.includes("eval(") || code.includes("Function(") || code.includes("with (")) {
@@ -9446,9 +9574,9 @@ function finalizeOutput(ir, compiled) {
9446
9574
  const errors = [];
9447
9575
  try {
9448
9576
  validateExpressionsOrThrow(ir.template.expressions, ir.filePath);
9449
- } catch (error2) {
9450
- if (error2 instanceof Error) {
9451
- errors.push(error2.message);
9577
+ } catch (error3) {
9578
+ if (error3 instanceof Error) {
9579
+ errors.push(error3.message);
9452
9580
  return {
9453
9581
  html: "",
9454
9582
  js: "",
@@ -9472,8 +9600,8 @@ function finalizeOutput(ir, compiled) {
9472
9600
  let runtimeCode;
9473
9601
  try {
9474
9602
  runtimeCode = transformIR(ir);
9475
- } catch (error2) {
9476
- errors.push(`Runtime generation failed: ${error2.message}`);
9603
+ } catch (error3) {
9604
+ errors.push(`Runtime generation failed: ${error3.message}`);
9477
9605
  return {
9478
9606
  html: "",
9479
9607
  js: "",
@@ -9548,9 +9676,9 @@ function compileZenSource(source, filePath) {
9548
9676
  try {
9549
9677
  const finalized = finalizeOutputOrThrow(ir, compiled);
9550
9678
  return { ir, compiled, finalized };
9551
- } catch (error2) {
9679
+ } catch (error3) {
9552
9680
  throw new Error(`Failed to finalize output for ${filePath}:
9553
- ${error2.message}`);
9681
+ ${error3.message}`);
9554
9682
  }
9555
9683
  }
9556
9684
 
@@ -10143,6 +10271,88 @@ function generateBundleJS() {
10143
10271
  triggerMount();
10144
10272
  }
10145
10273
 
10274
+ // ============================================
10275
+ // zenith:content - Content Engine
10276
+ // ============================================
10277
+
10278
+ const schemaRegistry = new Map();
10279
+ const builtInEnhancers = {
10280
+ readTime: (item) => {
10281
+ const wordsPerMinute = 200;
10282
+ const text = item.content || '';
10283
+ const wordCount = text.split(/\\s+/).length;
10284
+ const minutes = Math.ceil(wordCount / wordsPerMinute);
10285
+ return Object.assign({}, item, { readTime: minutes + ' min' });
10286
+ },
10287
+ wordCount: (item) => {
10288
+ const text = item.content || '';
10289
+ const wordCount = text.split(/\\s+/).length;
10290
+ return Object.assign({}, item, { wordCount: wordCount });
10291
+ }
10292
+ };
10293
+
10294
+ async function applyEnhancers(item, enhancers) {
10295
+ let enrichedItem = Object.assign({}, item);
10296
+ for (const enhancer of enhancers) {
10297
+ if (typeof enhancer === 'string') {
10298
+ const fn = builtInEnhancers[enhancer];
10299
+ if (fn) enrichedItem = await fn(enrichedItem);
10300
+ } else if (typeof enhancer === 'function') {
10301
+ enrichedItem = await enhancer(enrichedItem);
10302
+ }
10303
+ }
10304
+ return enrichedItem;
10305
+ }
10306
+
10307
+ class ZenCollection {
10308
+ constructor(items) {
10309
+ this.items = [...items];
10310
+ this.filters = [];
10311
+ this.sortField = null;
10312
+ this.sortOrder = 'desc';
10313
+ this.limitCount = null;
10314
+ this.selectedFields = null;
10315
+ this.enhancers = [];
10316
+ }
10317
+ where(fn) { this.filters.push(fn); return this; }
10318
+ sortBy(field, order = 'desc') { this.sortField = field; this.sortOrder = order; return this; }
10319
+ limit(n) { this.limitCount = n; return this; }
10320
+ fields(f) { this.selectedFields = f; return this; }
10321
+ enhanceWith(e) { this.enhancers.push(e); return this; }
10322
+ async get() {
10323
+ let results = [...this.items];
10324
+ for (const filter of this.filters) results = results.filter(filter);
10325
+ if (this.sortField) {
10326
+ results.sort((a, b) => {
10327
+ const valA = a[this.sortField];
10328
+ const valB = b[this.sortField];
10329
+ if (valA < valB) return this.sortOrder === 'asc' ? -1 : 1;
10330
+ if (valA > valB) return this.sortOrder === 'asc' ? 1 : -1;
10331
+ return 0;
10332
+ });
10333
+ }
10334
+ if (this.limitCount !== null) results = results.slice(0, this.limitCount);
10335
+ if (this.enhancers.length > 0) {
10336
+ results = await Promise.all(results.map(item => applyEnhancers(item, this.enhancers)));
10337
+ }
10338
+ if (this.selectedFields) {
10339
+ results = results.map(item => {
10340
+ const newItem = {};
10341
+ this.selectedFields.forEach(f => { newItem[f] = item[f]; });
10342
+ return newItem;
10343
+ });
10344
+ }
10345
+ return results;
10346
+ }
10347
+ }
10348
+
10349
+ function defineSchema(name, schema) { schemaRegistry.set(name, schema); }
10350
+
10351
+ function zenCollection(collectionName) {
10352
+ const data = (global.__ZENITH_CONTENT__ && global.__ZENITH_CONTENT__[collectionName]) || [];
10353
+ return new ZenCollection(data);
10354
+ }
10355
+
10146
10356
  // ============================================
10147
10357
  // Export to window.__zenith
10148
10358
  // ============================================
@@ -10156,6 +10366,9 @@ function generateBundleJS() {
10156
10366
  ref: zenRef,
10157
10367
  batch: zenBatch,
10158
10368
  untrack: zenUntrack,
10369
+ // zenith:content
10370
+ defineSchema: defineSchema,
10371
+ zenCollection: zenCollection,
10159
10372
  // Lifecycle
10160
10373
  onMount: zenOnMount,
10161
10374
  onUnmount: zenOnUnmount,
@@ -10191,20 +10404,161 @@ function generateBundleJS() {
10191
10404
  global.onMount = zenOnMount;
10192
10405
  global.onUnmount = zenOnUnmount;
10193
10406
 
10407
+ // ============================================
10408
+ // HMR Client (Development Only)
10409
+ // ============================================
10410
+
10411
+ if (typeof window !== 'undefined' && (location.hostname === 'localhost' || location.hostname === '127.0.0.1')) {
10412
+ let socket;
10413
+ function connectHMR() {
10414
+ const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
10415
+ socket = new WebSocket(protocol + '//' + location.host + '/hmr');
10416
+
10417
+ socket.onmessage = function(event) {
10418
+ try {
10419
+ const data = JSON.parse(event.data);
10420
+ if (data.type === 'reload') {
10421
+ console.log('[Zenith] HMR: Reloading page...');
10422
+ location.reload();
10423
+ } else if (data.type === 'style-update') {
10424
+ console.log('[Zenith] HMR: Updating style ' + data.url);
10425
+ const links = document.querySelectorAll('link[rel="stylesheet"]');
10426
+ for (let i = 0; i < links.length; i++) {
10427
+ const link = links[i];
10428
+ const url = new URL(link.href);
10429
+ if (url.pathname === data.url) {
10430
+ link.href = data.url + '?t=' + Date.now();
10431
+ break;
10432
+ }
10433
+ }
10434
+ }
10435
+ } catch (e) {
10436
+ console.error('[Zenith] HMR Error:', e);
10437
+ }
10438
+ };
10439
+
10440
+ socket.onclose = function() {
10441
+ console.log('[Zenith] HMR: Connection closed. Retrying in 2s...');
10442
+ setTimeout(connectHMR, 2000);
10443
+ };
10444
+ }
10445
+
10446
+ // Connect unless explicitly disabled
10447
+ if (!window.__ZENITH_NO_HMR__) {
10448
+ connectHMR();
10449
+ }
10450
+ }
10451
+
10194
10452
  })(typeof window !== 'undefined' ? window : this);
10195
10453
  `;
10196
10454
  }
10197
10455
 
10456
+ // cli/utils/content.ts
10457
+ import fs4 from "fs";
10458
+ import path4 from "path";
10459
+ function loadContent(contentDir) {
10460
+ if (!fs4.existsSync(contentDir)) {
10461
+ return {};
10462
+ }
10463
+ const collections = {};
10464
+ const files = getAllFiles(contentDir);
10465
+ for (const filePath of files) {
10466
+ const ext = path4.extname(filePath).toLowerCase();
10467
+ const relativePath = path4.relative(contentDir, filePath);
10468
+ const collection = relativePath.split(path4.sep)[0];
10469
+ if (!collection)
10470
+ continue;
10471
+ const slug = relativePath.replace(/\.(md|mdx|json)$/, "").replace(/\\/g, "/");
10472
+ const id = slug;
10473
+ const rawContent = fs4.readFileSync(filePath, "utf-8");
10474
+ if (!collections[collection]) {
10475
+ collections[collection] = [];
10476
+ }
10477
+ if (ext === ".json") {
10478
+ try {
10479
+ const data = JSON.parse(rawContent);
10480
+ collections[collection].push({
10481
+ id,
10482
+ slug,
10483
+ collection,
10484
+ content: "",
10485
+ ...data
10486
+ });
10487
+ } catch (e) {
10488
+ console.error(`Error parsing JSON file ${filePath}:`, e);
10489
+ }
10490
+ } else if (ext === ".md" || ext === ".mdx") {
10491
+ const { metadata, content } = parseMarkdown(rawContent);
10492
+ collections[collection].push({
10493
+ id,
10494
+ slug,
10495
+ collection,
10496
+ content,
10497
+ ...metadata
10498
+ });
10499
+ }
10500
+ }
10501
+ return collections;
10502
+ }
10503
+ function getAllFiles(dir, fileList = []) {
10504
+ const files = fs4.readdirSync(dir);
10505
+ files.forEach((file) => {
10506
+ const name = path4.join(dir, file);
10507
+ if (fs4.statSync(name).isDirectory()) {
10508
+ getAllFiles(name, fileList);
10509
+ } else {
10510
+ fileList.push(name);
10511
+ }
10512
+ });
10513
+ return fileList;
10514
+ }
10515
+ function parseMarkdown(content) {
10516
+ const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
10517
+ const match = content.match(frontmatterRegex);
10518
+ if (!match) {
10519
+ return { metadata: {}, content: content.trim() };
10520
+ }
10521
+ const [, yamlStr, body] = match;
10522
+ const metadata = {};
10523
+ if (yamlStr) {
10524
+ yamlStr.split(`
10525
+ `).forEach((line) => {
10526
+ const [key, ...values] = line.split(":");
10527
+ if (key && values.length > 0) {
10528
+ const value = values.join(":").trim();
10529
+ if (value === "true")
10530
+ metadata[key.trim()] = true;
10531
+ else if (value === "false")
10532
+ metadata[key.trim()] = false;
10533
+ else if (!isNaN(Number(value)))
10534
+ metadata[key.trim()] = Number(value);
10535
+ else if (value.startsWith("[") && value.endsWith("]")) {
10536
+ metadata[key.trim()] = value.slice(1, -1).split(",").map((v) => v.trim().replace(/^['"]|['"]$/g, ""));
10537
+ } else
10538
+ metadata[key.trim()] = value.replace(/^['"]|['"]$/g, "");
10539
+ }
10540
+ });
10541
+ }
10542
+ return { metadata, content: (body || "").trim() };
10543
+ }
10544
+
10198
10545
  // cli/commands/dev.ts
10199
10546
  var pageCache = new Map;
10200
10547
  async function dev(options = {}) {
10201
10548
  const project = requireProject();
10202
10549
  const port = options.port || parseInt(process.env.PORT || "3000", 10);
10203
- const appDir = project.root;
10204
10550
  const pagesDir = project.pagesDir;
10205
- header("Zenith Dev Server");
10206
- log(`Project: ${project.root}`);
10207
- log(`Pages: ${project.pagesDir}`);
10551
+ const rootDir = project.root;
10552
+ const contentDir = path5.join(rootDir, "content");
10553
+ let contentData = loadContent(contentDir);
10554
+ const clients = new Set;
10555
+ showServerPanel({
10556
+ project: project.root,
10557
+ pages: project.pagesDir,
10558
+ url: `http://localhost:${port}`,
10559
+ hmr: true,
10560
+ mode: "In-memory compilation"
10561
+ });
10208
10562
  const STATIC_EXTENSIONS = new Set([
10209
10563
  ".js",
10210
10564
  ".css",
@@ -10222,23 +10576,18 @@ async function dev(options = {}) {
10222
10576
  ".json",
10223
10577
  ".map"
10224
10578
  ]);
10225
- function generateRuntimeJS() {
10226
- return generateBundleJS();
10227
- }
10228
10579
  function compilePageInMemory(pagePath) {
10229
10580
  try {
10230
- const layoutsDir = path4.join(pagesDir, "../layouts");
10581
+ const layoutsDir = path5.join(pagesDir, "../layouts");
10231
10582
  const layouts = discoverLayouts(layoutsDir);
10232
- const source = fs4.readFileSync(pagePath, "utf-8");
10583
+ const source = fs5.readFileSync(pagePath, "utf-8");
10233
10584
  let processedSource = source;
10234
10585
  let layoutToUse = layouts.get("DefaultLayout");
10235
- if (layoutToUse) {
10586
+ if (layoutToUse)
10236
10587
  processedSource = processLayout(source, layoutToUse);
10237
- }
10238
10588
  const result = compileZenSource(processedSource, pagePath);
10239
- if (!result.finalized) {
10240
- throw new Error("Compilation failed: No finalized output");
10241
- }
10589
+ if (!result.finalized)
10590
+ throw new Error("Compilation failed");
10242
10591
  const routeDef = generateRouteDefinition(pagePath, pagesDir);
10243
10592
  return {
10244
10593
  html: result.finalized.html,
@@ -10247,100 +10596,138 @@ async function dev(options = {}) {
10247
10596
  route: routeDef.path,
10248
10597
  lastModified: Date.now()
10249
10598
  };
10250
- } catch (error2) {
10251
- error(`Compilation error for ${pagePath}: ${error2.message}`);
10599
+ } catch (error3) {
10600
+ error(`Compilation error: ${error3.message}`);
10252
10601
  return null;
10253
10602
  }
10254
10603
  }
10255
- function generateDevHTML(page) {
10256
- const runtimeTag = `<script src="/runtime.js"></script>`;
10257
- const scriptTag = `<script>
10258
- ${page.script}
10259
- </script>`;
10260
- const allScripts = `${runtimeTag}
10261
- ${scriptTag}`;
10262
- if (page.html.includes("</body>")) {
10263
- return page.html.replace("</body>", `${allScripts}
10264
- </body>`);
10604
+ const watcher = fs5.watch(path5.join(pagesDir, ".."), { recursive: true }, (event, filename) => {
10605
+ if (!filename)
10606
+ return;
10607
+ if (filename.endsWith(".zen")) {
10608
+ hmr("Page", filename);
10609
+ for (const client of clients) {
10610
+ client.send(JSON.stringify({ type: "reload" }));
10611
+ }
10612
+ } else if (filename.endsWith(".css")) {
10613
+ hmr("CSS", filename);
10614
+ for (const client of clients) {
10615
+ client.send(JSON.stringify({
10616
+ type: "style-update",
10617
+ url: filename.includes("global.css") ? "/styles/global.css" : `/${filename}`
10618
+ }));
10619
+ }
10620
+ } else if (filename.startsWith("content")) {
10621
+ hmr("Content", filename);
10622
+ contentData = loadContent(contentDir);
10623
+ for (const client of clients) {
10624
+ client.send(JSON.stringify({ type: "reload" }));
10625
+ }
10265
10626
  }
10266
- return `${page.html}
10267
- ${allScripts}`;
10268
- }
10269
- function findPageForRoute(route) {
10270
- const exactPath = path4.join(pagesDir, route === "/" ? "index.zen" : `${route.slice(1)}.zen`);
10271
- if (fs4.existsSync(exactPath))
10272
- return exactPath;
10273
- const indexPath = path4.join(pagesDir, route === "/" ? "index.zen" : `${route.slice(1)}/index.zen`);
10274
- if (fs4.existsSync(indexPath))
10275
- return indexPath;
10276
- return null;
10277
- }
10278
- const cachedRuntimeJS = generateRuntimeJS();
10627
+ });
10279
10628
  const server = serve({
10280
10629
  port,
10281
- async fetch(req) {
10630
+ fetch(req, server2) {
10631
+ const startTime = performance.now();
10282
10632
  const url = new URL(req.url);
10283
10633
  const pathname = url.pathname;
10284
- const ext = path4.extname(pathname).toLowerCase();
10285
- if (pathname === "/runtime.js" || pathname === "/assets/bundle.js") {
10286
- return new Response(cachedRuntimeJS, {
10287
- headers: {
10288
- "Content-Type": "application/javascript; charset=utf-8",
10289
- "Cache-Control": "no-cache"
10290
- }
10291
- });
10634
+ const ext = path5.extname(pathname).toLowerCase();
10635
+ if (pathname === "/hmr") {
10636
+ const upgraded = server2.upgrade(req);
10637
+ if (upgraded)
10638
+ return;
10292
10639
  }
10293
- if (pathname === "/assets/styles.css" || pathname === "/styles/global.css" || pathname === "/app/styles/global.css") {
10294
- const globalCssPath = path4.join(pagesDir, "../styles/global.css");
10295
- if (fs4.existsSync(globalCssPath)) {
10296
- const css = fs4.readFileSync(globalCssPath, "utf-8");
10297
- return new Response(css, {
10298
- headers: { "Content-Type": "text/css; charset=utf-8" }
10299
- });
10640
+ if (pathname === "/runtime.js") {
10641
+ const response = new Response(generateBundleJS(), {
10642
+ headers: { "Content-Type": "application/javascript; charset=utf-8" }
10643
+ });
10644
+ route("GET", pathname, 200, Math.round(performance.now() - startTime), 0, Math.round(performance.now() - startTime));
10645
+ return response;
10646
+ }
10647
+ if (pathname === "/styles/global.css") {
10648
+ const globalCssPath = path5.join(pagesDir, "../styles/global.css");
10649
+ if (fs5.existsSync(globalCssPath)) {
10650
+ const css = fs5.readFileSync(globalCssPath, "utf-8");
10651
+ const response = new Response(css, { headers: { "Content-Type": "text/css" } });
10652
+ route("GET", pathname, 200, Math.round(performance.now() - startTime), 0, Math.round(performance.now() - startTime));
10653
+ return response;
10300
10654
  }
10301
10655
  }
10302
10656
  if (STATIC_EXTENSIONS.has(ext)) {
10303
- const publicPath = path4.join(pagesDir, "../public", pathname);
10304
- const distPath = path4.join(pagesDir, "../dist", pathname);
10305
- const appRelativePath = path4.join(pagesDir, "..", pathname);
10306
- for (const filePath of [publicPath, distPath, appRelativePath]) {
10307
- const file = Bun.file(filePath);
10308
- if (await file.exists()) {
10309
- return new Response(file);
10310
- }
10657
+ const publicPath = path5.join(pagesDir, "../public", pathname);
10658
+ if (fs5.existsSync(publicPath)) {
10659
+ const response = new Response(Bun.file(publicPath));
10660
+ route("GET", pathname, 200, Math.round(performance.now() - startTime), 0, Math.round(performance.now() - startTime));
10661
+ return response;
10311
10662
  }
10312
- return new Response("Not found", { status: 404 });
10313
10663
  }
10314
- const pagePath = findPageForRoute(pathname);
10664
+ const pagePath = findPageForRoute(pathname, pagesDir);
10315
10665
  if (pagePath) {
10666
+ const compileStart = performance.now();
10316
10667
  let cached = pageCache.get(pagePath);
10317
- const stat = fs4.statSync(pagePath);
10668
+ const stat = fs5.statSync(pagePath);
10318
10669
  if (!cached || stat.mtimeMs > cached.lastModified) {
10319
- const compiled = compilePageInMemory(pagePath);
10320
- if (compiled) {
10321
- pageCache.set(pagePath, compiled);
10322
- cached = compiled;
10323
- }
10670
+ cached = compilePageInMemory(pagePath) || undefined;
10671
+ if (cached)
10672
+ pageCache.set(pagePath, cached);
10324
10673
  }
10674
+ const compileEnd = performance.now();
10325
10675
  if (cached) {
10326
- const html = generateDevHTML(cached);
10327
- return new Response(html, {
10328
- headers: { "Content-Type": "text/html; charset=utf-8" }
10329
- });
10676
+ const renderStart = performance.now();
10677
+ const html = generateDevHTML(cached, contentData);
10678
+ const renderEnd = performance.now();
10679
+ const totalTime = Math.round(performance.now() - startTime);
10680
+ const compileTime = Math.round(compileEnd - compileStart);
10681
+ const renderTime = Math.round(renderEnd - renderStart);
10682
+ route("GET", pathname, 200, totalTime, compileTime, renderTime);
10683
+ return new Response(html, { headers: { "Content-Type": "text/html" } });
10330
10684
  }
10331
10685
  }
10686
+ route("GET", pathname, 404, Math.round(performance.now() - startTime), 0, 0);
10332
10687
  return new Response("Not Found", { status: 404 });
10688
+ },
10689
+ websocket: {
10690
+ open(ws) {
10691
+ clients.add(ws);
10692
+ },
10693
+ close(ws) {
10694
+ clients.delete(ws);
10695
+ },
10696
+ message() {}
10333
10697
  }
10334
10698
  });
10335
- success(`Server running at http://localhost:${server.port}`);
10336
- info("\u2022 In-memory compilation active");
10337
- info("\u2022 Auto-recompile on file changes");
10338
- info("Press Ctrl+C to stop");
10699
+ process.on("SIGINT", () => {
10700
+ watcher.close();
10701
+ server.stop();
10702
+ process.exit(0);
10703
+ });
10339
10704
  await new Promise(() => {});
10340
10705
  }
10706
+ function findPageForRoute(route2, pagesDir) {
10707
+ const exactPath = path5.join(pagesDir, route2 === "/" ? "index.zen" : `${route2.slice(1)}.zen`);
10708
+ if (fs5.existsSync(exactPath))
10709
+ return exactPath;
10710
+ const indexPath = path5.join(pagesDir, route2 === "/" ? "index.zen" : `${route2.slice(1)}/index.zen`);
10711
+ if (fs5.existsSync(indexPath))
10712
+ return indexPath;
10713
+ return null;
10714
+ }
10715
+ function generateDevHTML(page, contentData = {}) {
10716
+ const runtimeTag = `<script src="/runtime.js"></script>`;
10717
+ const contentTag = `<script>window.__ZENITH_CONTENT__ = ${JSON.stringify(contentData)};</script>`;
10718
+ const scriptTag = `<script>
10719
+ ${page.script}
10720
+ </script>`;
10721
+ const allScripts = `${runtimeTag}
10722
+ ${contentTag}
10723
+ ${scriptTag}`;
10724
+ return page.html.includes("</body>") ? page.html.replace("</body>", `${allScripts}
10725
+ </body>`) : `${page.html}
10726
+ ${allScripts}`;
10727
+ }
10341
10728
 
10342
10729
  // cli/commands/preview.ts
10343
- import path5 from "path";
10730
+ import path6 from "path";
10344
10731
  var {serve: serve2 } = globalThis.Bun;
10345
10732
  async function preview(options = {}) {
10346
10733
  const project = requireProject();
@@ -10370,16 +10757,16 @@ async function preview(options = {}) {
10370
10757
  async fetch(req) {
10371
10758
  const url = new URL(req.url);
10372
10759
  const pathname = url.pathname;
10373
- const ext = path5.extname(pathname).toLowerCase();
10760
+ const ext = path6.extname(pathname).toLowerCase();
10374
10761
  if (STATIC_EXTENSIONS.has(ext)) {
10375
- const filePath = path5.join(distDir, pathname);
10762
+ const filePath = path6.join(distDir, pathname);
10376
10763
  const file = Bun.file(filePath);
10377
10764
  if (await file.exists()) {
10378
10765
  return new Response(file);
10379
10766
  }
10380
10767
  return new Response("Not found", { status: 404 });
10381
10768
  }
10382
- const indexPath = path5.join(distDir, "index.html");
10769
+ const indexPath = path6.join(distDir, "index.html");
10383
10770
  const indexFile = Bun.file(indexPath);
10384
10771
  if (await indexFile.exists()) {
10385
10772
  return new Response(indexFile, {
@@ -10395,8 +10782,8 @@ async function preview(options = {}) {
10395
10782
  }
10396
10783
 
10397
10784
  // compiler/ssg-build.ts
10398
- import fs5 from "fs";
10399
- import path6 from "path";
10785
+ import fs6 from "fs";
10786
+ import path7 from "path";
10400
10787
 
10401
10788
  // compiler/build-analyzer.ts
10402
10789
  function analyzePageSource(source) {
@@ -10458,9 +10845,9 @@ function getBuildOutputType(analysis) {
10458
10845
 
10459
10846
  // compiler/ssg-build.ts
10460
10847
  function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
10461
- const source = fs5.readFileSync(pagePath, "utf-8");
10848
+ const source = fs6.readFileSync(pagePath, "utf-8");
10462
10849
  const analysis = analyzePageSource(source);
10463
- const layoutsDir = path6.join(baseDir, "layouts");
10850
+ const layoutsDir = path7.join(baseDir, "layouts");
10464
10851
  const layouts = discoverLayouts(layoutsDir);
10465
10852
  let processedSource = source;
10466
10853
  const layoutToUse = layouts.get("DefaultLayout");
@@ -10489,7 +10876,7 @@ function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
10489
10876
  outputDir
10490
10877
  };
10491
10878
  }
10492
- function generatePageHTML(page, globalStyles) {
10879
+ function generatePageHTML(page, globalStyles, contentData) {
10493
10880
  const { html, styles, analysis, routePath, pageScript } = page;
10494
10881
  const pageStyles = styles.join(`
10495
10882
  `);
@@ -10498,6 +10885,7 @@ function generatePageHTML(page, globalStyles) {
10498
10885
  let scriptTags = "";
10499
10886
  if (analysis.needsHydration) {
10500
10887
  scriptTags = `
10888
+ <script>window.__ZEN_CONTENT__ = ${JSON.stringify(contentData)};</script>
10501
10889
  <script src="/assets/bundle.js"></script>`;
10502
10890
  if (pageScript) {
10503
10891
  const pageJsName = routePath === "/" ? "page_index.js" : `page_${routePath.replace(/^\//, "").replace(/\//g, "_")}.js`;
@@ -10560,16 +10948,18 @@ ${page.pageScript}
10560
10948
  `;
10561
10949
  }
10562
10950
  function buildSSG(options) {
10563
- const { pagesDir, outDir, baseDir = path6.dirname(pagesDir) } = options;
10951
+ const { pagesDir, outDir, baseDir = path7.dirname(pagesDir) } = options;
10952
+ const contentDir = path7.join(baseDir, "content");
10953
+ const contentData = loadContent(contentDir);
10564
10954
  console.log("\uD83D\uDD28 Zenith SSG Build");
10565
10955
  console.log(` Pages: ${pagesDir}`);
10566
10956
  console.log(` Output: ${outDir}`);
10567
10957
  console.log("");
10568
- if (fs5.existsSync(outDir)) {
10569
- fs5.rmSync(outDir, { recursive: true, force: true });
10958
+ if (fs6.existsSync(outDir)) {
10959
+ fs6.rmSync(outDir, { recursive: true, force: true });
10570
10960
  }
10571
- fs5.mkdirSync(outDir, { recursive: true });
10572
- fs5.mkdirSync(path6.join(outDir, "assets"), { recursive: true });
10961
+ fs6.mkdirSync(outDir, { recursive: true });
10962
+ fs6.mkdirSync(path7.join(outDir, "assets"), { recursive: true });
10573
10963
  const pageFiles = discoverPages(pagesDir);
10574
10964
  if (pageFiles.length === 0) {
10575
10965
  console.warn("\u26A0\uFE0F No pages found in", pagesDir);
@@ -10579,7 +10969,7 @@ function buildSSG(options) {
10579
10969
  const compiledPages = [];
10580
10970
  let hasHydratedPages = false;
10581
10971
  for (const pageFile of pageFiles) {
10582
- const relativePath = path6.relative(pagesDir, pageFile);
10972
+ const relativePath = path7.relative(pagesDir, pageFile);
10583
10973
  console.log(` Compiling: ${relativePath}`);
10584
10974
  try {
10585
10975
  const compiled = compilePage(pageFile, pagesDir, baseDir);
@@ -10590,61 +10980,61 @@ function buildSSG(options) {
10590
10980
  const outputType = getBuildOutputType(compiled.analysis);
10591
10981
  const summary = getAnalysisSummary(compiled.analysis);
10592
10982
  console.log(` \u2192 ${outputType.toUpperCase()} [${summary}]`);
10593
- } catch (error2) {
10594
- console.error(` \u274C Error: ${error2.message}`);
10595
- throw error2;
10983
+ } catch (error3) {
10984
+ console.error(` \u274C Error: ${error3.message}`);
10985
+ throw error3;
10596
10986
  }
10597
10987
  }
10598
10988
  console.log("");
10599
10989
  let globalStyles = "";
10600
- const globalCssPath = path6.join(baseDir, "styles", "global.css");
10601
- if (fs5.existsSync(globalCssPath)) {
10602
- globalStyles = fs5.readFileSync(globalCssPath, "utf-8");
10990
+ const globalCssPath = path7.join(baseDir, "styles", "global.css");
10991
+ if (fs6.existsSync(globalCssPath)) {
10992
+ globalStyles = fs6.readFileSync(globalCssPath, "utf-8");
10603
10993
  console.log("\uD83D\uDCE6 Loaded global.css");
10604
10994
  }
10605
10995
  if (hasHydratedPages) {
10606
10996
  const bundleJS = generateBundleJS();
10607
- fs5.writeFileSync(path6.join(outDir, "assets", "bundle.js"), bundleJS);
10997
+ fs6.writeFileSync(path7.join(outDir, "assets", "bundle.js"), bundleJS);
10608
10998
  console.log("\uD83D\uDCE6 Generated assets/bundle.js");
10609
10999
  }
10610
11000
  if (globalStyles) {
10611
- fs5.writeFileSync(path6.join(outDir, "assets", "styles.css"), globalStyles);
11001
+ fs6.writeFileSync(path7.join(outDir, "assets", "styles.css"), globalStyles);
10612
11002
  console.log("\uD83D\uDCE6 Generated assets/styles.css");
10613
11003
  }
10614
11004
  for (const page of compiledPages) {
10615
- const pageOutDir = path6.join(outDir, page.outputDir);
10616
- fs5.mkdirSync(pageOutDir, { recursive: true });
10617
- const html = generatePageHTML(page, globalStyles);
10618
- fs5.writeFileSync(path6.join(pageOutDir, "index.html"), html);
11005
+ const pageOutDir = path7.join(outDir, page.outputDir);
11006
+ fs6.mkdirSync(pageOutDir, { recursive: true });
11007
+ const html = generatePageHTML(page, globalStyles, contentData);
11008
+ fs6.writeFileSync(path7.join(pageOutDir, "index.html"), html);
10619
11009
  if (page.pageScript) {
10620
11010
  const pageJsName = page.routePath === "/" ? "page_index.js" : `page_${page.routePath.replace(/^\//, "").replace(/\//g, "_")}.js`;
10621
11011
  const pageJS = generatePageJS(page);
10622
- fs5.writeFileSync(path6.join(outDir, "assets", pageJsName), pageJS);
11012
+ fs6.writeFileSync(path7.join(outDir, "assets", pageJsName), pageJS);
10623
11013
  }
10624
11014
  console.log(`\u2705 ${page.outputDir}/index.html`);
10625
11015
  }
10626
- const faviconPath = path6.join(baseDir, "favicon.ico");
10627
- if (fs5.existsSync(faviconPath)) {
10628
- fs5.copyFileSync(faviconPath, path6.join(outDir, "favicon.ico"));
11016
+ const faviconPath = path7.join(baseDir, "favicon.ico");
11017
+ if (fs6.existsSync(faviconPath)) {
11018
+ fs6.copyFileSync(faviconPath, path7.join(outDir, "favicon.ico"));
10629
11019
  console.log("\uD83D\uDCE6 Copied favicon.ico");
10630
11020
  }
10631
11021
  const custom404Candidates = ["404.zen", "+404.zen", "not-found.zen"];
10632
11022
  let has404 = false;
10633
11023
  for (const candidate of custom404Candidates) {
10634
- const custom404Path = path6.join(pagesDir, candidate);
10635
- if (fs5.existsSync(custom404Path)) {
11024
+ const custom404Path = path7.join(pagesDir, candidate);
11025
+ if (fs6.existsSync(custom404Path)) {
10636
11026
  try {
10637
11027
  const compiled = compilePage(custom404Path, pagesDir, baseDir);
10638
- const html = generatePageHTML(compiled, globalStyles);
10639
- fs5.writeFileSync(path6.join(outDir, "404.html"), html);
11028
+ const html = generatePageHTML(compiled, globalStyles, contentData);
11029
+ fs6.writeFileSync(path7.join(outDir, "404.html"), html);
10640
11030
  console.log("\uD83D\uDCE6 Generated 404.html (custom)");
10641
11031
  has404 = true;
10642
11032
  if (compiled.pageScript) {
10643
11033
  const pageJS = generatePageJS(compiled);
10644
- fs5.writeFileSync(path6.join(outDir, "assets", "page_404.js"), pageJS);
11034
+ fs6.writeFileSync(path7.join(outDir, "assets", "page_404.js"), pageJS);
10645
11035
  }
10646
- } catch (error2) {
10647
- console.warn(` \u26A0\uFE0F Could not compile ${candidate}: ${error2.message}`);
11036
+ } catch (error3) {
11037
+ console.warn(` \u26A0\uFE0F Could not compile ${candidate}: ${error3.message}`);
10648
11038
  }
10649
11039
  break;
10650
11040
  }
@@ -10675,7 +11065,7 @@ function buildSSG(options) {
10675
11065
  </div>
10676
11066
  </body>
10677
11067
  </html>`;
10678
- fs5.writeFileSync(path6.join(outDir, "404.html"), default404HTML);
11068
+ fs6.writeFileSync(path7.join(outDir, "404.html"), default404HTML);
10679
11069
  console.log("\uD83D\uDCE6 Generated 404.html (default)");
10680
11070
  }
10681
11071
  console.log("");
@@ -10713,30 +11103,30 @@ async function build(options = {}) {
10713
11103
  }
10714
11104
 
10715
11105
  // cli/utils/plugin-manager.ts
10716
- import fs6 from "fs";
10717
- import path7 from "path";
11106
+ import fs7 from "fs";
11107
+ import path8 from "path";
10718
11108
  var PLUGINS_FILE = "zenith.plugins.json";
10719
11109
  function getPluginsPath() {
10720
11110
  const root = findProjectRoot();
10721
11111
  if (!root) {
10722
11112
  throw new Error("Not in a Zenith project");
10723
11113
  }
10724
- return path7.join(root, PLUGINS_FILE);
11114
+ return path8.join(root, PLUGINS_FILE);
10725
11115
  }
10726
11116
  function readPlugins() {
10727
11117
  const pluginsPath = getPluginsPath();
10728
- if (!fs6.existsSync(pluginsPath)) {
11118
+ if (!fs7.existsSync(pluginsPath)) {
10729
11119
  return { plugins: [] };
10730
11120
  }
10731
11121
  try {
10732
- return JSON.parse(fs6.readFileSync(pluginsPath, "utf-8"));
11122
+ return JSON.parse(fs7.readFileSync(pluginsPath, "utf-8"));
10733
11123
  } catch {
10734
11124
  return { plugins: [] };
10735
11125
  }
10736
11126
  }
10737
11127
  function writePlugins(data) {
10738
11128
  const pluginsPath = getPluginsPath();
10739
- fs6.writeFileSync(pluginsPath, JSON.stringify(data, null, 2));
11129
+ fs7.writeFileSync(pluginsPath, JSON.stringify(data, null, 2));
10740
11130
  }
10741
11131
  function addPlugin(name, options) {
10742
11132
  const data = readPlugins();
@@ -10810,124 +11200,10 @@ async function remove(pluginName) {
10810
11200
  }
10811
11201
 
10812
11202
  // cli/commands/create.ts
10813
- import fs7 from "fs";
10814
- import path8 from "path";
11203
+ import fs8 from "fs";
11204
+ import path9 from "path";
10815
11205
  import { execSync } from "child_process";
10816
11206
  import readline from "readline";
10817
-
10818
- // cli/utils/branding.ts
10819
- var import_picocolors = __toESM(require_picocolors(), 1);
10820
- var colors2 = {
10821
- primary: import_picocolors.default.blue,
10822
- secondary: import_picocolors.default.cyan,
10823
- success: import_picocolors.default.green,
10824
- warning: import_picocolors.default.yellow,
10825
- error: import_picocolors.default.red,
10826
- muted: import_picocolors.default.gray,
10827
- bold: import_picocolors.default.bold,
10828
- dim: import_picocolors.default.dim
10829
- };
10830
- var LOGO = `
10831
- ${import_picocolors.default.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
10832
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.cyan("\u2551")}
10833
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2588\u2557 \u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2557 \u2588\u2588\u2557"))} ${import_picocolors.default.cyan("\u2551")}
10834
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.bold(import_picocolors.default.blue("\u255A\u2550\u2550\u2588\u2588\u2588\u2554\u255D"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D"))}${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.blue("\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2551 \u2588\u2588\u2551"))} ${import_picocolors.default.cyan("\u2551")}
10835
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.bold(import_picocolors.default.blue(" \u2588\u2588\u2588\u2554\u255D "))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2557 "))}${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.blue(" \u2588\u2588\u2551 "))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551"))} ${import_picocolors.default.cyan("\u2551")}
10836
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.bold(import_picocolors.default.blue(" \u2588\u2588\u2588\u2554\u255D "))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2554\u2550\u2550\u255D "))}${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.blue(" \u2588\u2588\u2551 "))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551"))} ${import_picocolors.default.cyan("\u2551")}
10837
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}${import_picocolors.default.bold(import_picocolors.default.blue("\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2551"))}${import_picocolors.default.bold(import_picocolors.default.blue(" \u2588\u2588\u2551 "))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u2588\u2588\u2551 \u2588\u2588\u2551"))} ${import_picocolors.default.cyan("\u2551")}
10838
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.bold(import_picocolors.default.blue("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"))}${import_picocolors.default.bold(import_picocolors.default.blue("\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D"))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u255A\u2550\u255D"))}${import_picocolors.default.bold(import_picocolors.default.blue(" \u255A\u2550\u255D "))}${import_picocolors.default.bold(import_picocolors.default.cyan("\u255A\u2550\u255D \u255A\u2550\u255D"))} ${import_picocolors.default.cyan("\u2551")}
10839
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.cyan("\u2551")}
10840
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.dim("The Modern Reactive Web Framework")} ${import_picocolors.default.cyan("\u2551")}
10841
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.cyan("\u2551")}
10842
- ${import_picocolors.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")}
10843
- `;
10844
- var LOGO_COMPACT = `
10845
- ${import_picocolors.default.bold(import_picocolors.default.blue("\u26A1"))} ${import_picocolors.default.bold(import_picocolors.default.cyan("ZENITH"))} ${import_picocolors.default.dim("- Modern Reactive Framework")}
10846
- `;
10847
- var spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
10848
-
10849
- class Spinner {
10850
- interval = null;
10851
- frameIndex = 0;
10852
- message;
10853
- constructor(message) {
10854
- this.message = message;
10855
- }
10856
- start() {
10857
- this.interval = setInterval(() => {
10858
- process.stdout.write(`\r${import_picocolors.default.cyan(spinnerFrames[this.frameIndex])} ${this.message}`);
10859
- this.frameIndex = (this.frameIndex + 1) % spinnerFrames.length;
10860
- }, 80);
10861
- }
10862
- stop(finalMessage) {
10863
- if (this.interval) {
10864
- clearInterval(this.interval);
10865
- this.interval = null;
10866
- }
10867
- process.stdout.write("\r" + " ".repeat(this.message.length + 5) + "\r");
10868
- if (finalMessage) {
10869
- console.log(finalMessage);
10870
- }
10871
- }
10872
- succeed(message) {
10873
- this.stop(`${import_picocolors.default.green("\u2713")} ${message}`);
10874
- }
10875
- fail(message) {
10876
- this.stop(`${import_picocolors.default.red("\u2717")} ${message}`);
10877
- }
10878
- }
10879
- function showLogo() {
10880
- console.log(LOGO);
10881
- }
10882
- function header2(text) {
10883
- console.log(`
10884
- ${import_picocolors.default.bold(import_picocolors.default.cyan("\u25B8"))} ${import_picocolors.default.bold(text)}
10885
- `);
10886
- }
10887
- function error2(text) {
10888
- console.log(`${import_picocolors.default.red("\u2717")} ${text}`);
10889
- }
10890
- function warn2(text) {
10891
- console.log(`${import_picocolors.default.yellow("\u26A0")} ${text}`);
10892
- }
10893
- function info2(text) {
10894
- console.log(`${import_picocolors.default.blue("\u2139")} ${text}`);
10895
- }
10896
- function highlight(text) {
10897
- return import_picocolors.default.cyan(text);
10898
- }
10899
- function dim(text) {
10900
- return import_picocolors.default.dim(text);
10901
- }
10902
- function bold(text) {
10903
- return import_picocolors.default.bold(text);
10904
- }
10905
- async function showIntro() {
10906
- console.clear();
10907
- showLogo();
10908
- await sleep(300);
10909
- }
10910
- function sleep(ms) {
10911
- return new Promise((resolve) => setTimeout(resolve, ms));
10912
- }
10913
- function showNextSteps(projectName) {
10914
- console.log(`
10915
- ${import_picocolors.default.cyan("\u250C\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")}
10916
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10917
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.green("\u2728")} ${import_picocolors.default.bold("Your Zenith app is ready!")} ${import_picocolors.default.cyan("\u2502")}
10918
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10919
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.dim("Next steps:")} ${import_picocolors.default.cyan("\u2502")}
10920
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10921
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("$")} ${import_picocolors.default.bold(`cd ${projectName}`)}${" ".repeat(Math.max(0, 40 - projectName.length))}${import_picocolors.default.cyan("\u2502")}
10922
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("$")} ${import_picocolors.default.bold("bun run dev")} ${import_picocolors.default.cyan("\u2502")}
10923
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10924
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.dim("Then open")} ${import_picocolors.default.underline(import_picocolors.default.blue("http://localhost:3000"))} ${import_picocolors.default.cyan("\u2502")}
10925
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10926
- ${import_picocolors.default.cyan("\u2514\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518")}
10927
- `);
10928
- }
10929
-
10930
- // cli/commands/create.ts
10931
11207
  async function prompt(question, defaultValue) {
10932
11208
  const rl = readline.createInterface({
10933
11209
  input: process.stdin,
@@ -10964,7 +11240,7 @@ async function create(appName) {
10964
11240
  configSpinner.succeed("Configurations generated");
10965
11241
  const installSpinner = new Spinner("Installing dependencies...");
10966
11242
  installSpinner.start();
10967
- const targetDir = path8.resolve(process.cwd(), options.name);
11243
+ const targetDir = path9.resolve(process.cwd(), options.name);
10968
11244
  process.chdir(targetDir);
10969
11245
  try {
10970
11246
  execSync("bun install", { stdio: "pipe" });
@@ -10995,8 +11271,8 @@ async function gatherOptions(providedName) {
10995
11271
  process.exit(1);
10996
11272
  }
10997
11273
  }
10998
- const targetDir = path8.resolve(process.cwd(), name);
10999
- if (fs7.existsSync(targetDir)) {
11274
+ const targetDir = path9.resolve(process.cwd(), name);
11275
+ if (fs8.existsSync(targetDir)) {
11000
11276
  error2(`Directory "${name}" already exists`);
11001
11277
  process.exit(1);
11002
11278
  }
@@ -11017,14 +11293,14 @@ async function gatherOptions(providedName) {
11017
11293
  };
11018
11294
  }
11019
11295
  async function createProject(options) {
11020
- const targetDir = path8.resolve(process.cwd(), options.name);
11296
+ const targetDir = path9.resolve(process.cwd(), options.name);
11021
11297
  const baseDir = options.directory;
11022
- const appDir = path8.join(targetDir, baseDir);
11023
- fs7.mkdirSync(targetDir, { recursive: true });
11024
- fs7.mkdirSync(path8.join(appDir, "pages"), { recursive: true });
11025
- fs7.mkdirSync(path8.join(appDir, "layouts"), { recursive: true });
11026
- fs7.mkdirSync(path8.join(appDir, "components"), { recursive: true });
11027
- fs7.mkdirSync(path8.join(appDir, "styles"), { recursive: true });
11298
+ const appDir = path9.join(targetDir, baseDir);
11299
+ fs8.mkdirSync(targetDir, { recursive: true });
11300
+ fs8.mkdirSync(path9.join(appDir, "pages"), { recursive: true });
11301
+ fs8.mkdirSync(path9.join(appDir, "layouts"), { recursive: true });
11302
+ fs8.mkdirSync(path9.join(appDir, "components"), { recursive: true });
11303
+ fs8.mkdirSync(path9.join(appDir, "styles"), { recursive: true });
11028
11304
  const pkg = {
11029
11305
  name: options.name,
11030
11306
  version: "0.1.0",
@@ -11054,14 +11330,14 @@ async function createProject(options) {
11054
11330
  devDeps["prettier"] = "^3.0.0";
11055
11331
  pkg.scripts = { ...pkg.scripts, format: "prettier --write ." };
11056
11332
  }
11057
- fs7.writeFileSync(path8.join(targetDir, "package.json"), JSON.stringify(pkg, null, 4));
11058
- fs7.writeFileSync(path8.join(targetDir, baseDir, "pages", "index.zen"), generateIndexPage());
11059
- fs7.writeFileSync(path8.join(targetDir, baseDir, "layouts", "DefaultLayout.zen"), generateDefaultLayout());
11060
- fs7.writeFileSync(path8.join(appDir, "styles", "global.css"), generateGlobalCSS());
11061
- fs7.writeFileSync(path8.join(targetDir, ".gitignore"), generateGitignore());
11333
+ fs8.writeFileSync(path9.join(targetDir, "package.json"), JSON.stringify(pkg, null, 4));
11334
+ fs8.writeFileSync(path9.join(targetDir, baseDir, "pages", "index.zen"), generateIndexPage());
11335
+ fs8.writeFileSync(path9.join(targetDir, baseDir, "layouts", "DefaultLayout.zen"), generateDefaultLayout());
11336
+ fs8.writeFileSync(path9.join(appDir, "styles", "global.css"), generateGlobalCSS());
11337
+ fs8.writeFileSync(path9.join(targetDir, ".gitignore"), generateGitignore());
11062
11338
  }
11063
11339
  async function generateConfigs(options) {
11064
- const targetDir = path8.resolve(process.cwd(), options.name);
11340
+ const targetDir = path9.resolve(process.cwd(), options.name);
11065
11341
  const tsconfig = {
11066
11342
  compilerOptions: {
11067
11343
  target: "ESNext",
@@ -11085,7 +11361,7 @@ async function generateConfigs(options) {
11085
11361
  "@/*": [`./${options.directory}/*`]
11086
11362
  };
11087
11363
  }
11088
- fs7.writeFileSync(path8.join(targetDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 4));
11364
+ fs8.writeFileSync(path9.join(targetDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 4));
11089
11365
  if (options.eslint) {
11090
11366
  const eslintConfig = {
11091
11367
  root: true,
@@ -11106,7 +11382,7 @@ async function generateConfigs(options) {
11106
11382
  },
11107
11383
  ignorePatterns: ["dist", "node_modules"]
11108
11384
  };
11109
- fs7.writeFileSync(path8.join(targetDir, ".eslintrc.json"), JSON.stringify(eslintConfig, null, 4));
11385
+ fs8.writeFileSync(path9.join(targetDir, ".eslintrc.json"), JSON.stringify(eslintConfig, null, 4));
11110
11386
  }
11111
11387
  if (options.prettier) {
11112
11388
  const prettierConfig = {
@@ -11116,8 +11392,8 @@ async function generateConfigs(options) {
11116
11392
  trailingComma: "es5",
11117
11393
  printWidth: 100
11118
11394
  };
11119
- fs7.writeFileSync(path8.join(targetDir, ".prettierrc"), JSON.stringify(prettierConfig, null, 4));
11120
- fs7.writeFileSync(path8.join(targetDir, ".prettierignore"), `dist
11395
+ fs8.writeFileSync(path9.join(targetDir, ".prettierrc"), JSON.stringify(prettierConfig, null, 4));
11396
+ fs8.writeFileSync(path9.join(targetDir, ".prettierignore"), `dist
11121
11397
  node_modules
11122
11398
  bun.lock
11123
11399
  `);