@zenithbuild/core 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -107,7 +107,7 @@ function findProjectRoot(startDir = process.cwd()) {
107
107
  try {
108
108
  const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
109
109
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
110
- const hasZenith = Object.keys(deps).some((d) => d.startsWith("@zenith/"));
110
+ const hasZenith = Object.keys(deps).some((d) => d.startsWith("@zenith/") || d.startsWith("@zenithbuild/"));
111
111
  if (hasZenith) {
112
112
  return current;
113
113
  }
@@ -121,10 +121,14 @@ function getProject(cwd = process.cwd()) {
121
121
  const root = findProjectRoot(cwd);
122
122
  if (!root)
123
123
  return null;
124
+ let appDir = path.join(root, "app");
125
+ if (!fs.existsSync(appDir)) {
126
+ appDir = path.join(root, "src");
127
+ }
124
128
  return {
125
129
  root,
126
- pagesDir: path.join(root, "app/pages"),
127
- distDir: path.join(root, "app/dist"),
130
+ pagesDir: path.join(appDir, "pages"),
131
+ distDir: path.join(appDir, "dist"),
128
132
  hasZenithDeps: true
129
133
  };
130
134
  }
@@ -137,34 +141,161 @@ function requireProject(cwd = process.cwd()) {
137
141
  }
138
142
 
139
143
  // cli/utils/logger.ts
140
- var colors = {
141
- reset: "\x1B[0m",
142
- bright: "\x1B[1m",
143
- dim: "\x1B[2m",
144
- red: "\x1B[31m",
145
- green: "\x1B[32m",
146
- yellow: "\x1B[33m",
147
- blue: "\x1B[34m",
148
- cyan: "\x1B[36m"
149
- };
144
+ var import_picocolors = __toESM(require_picocolors(), 1);
150
145
  function log(message) {
151
- console.log(`${colors.cyan}[zenith]${colors.reset} ${message}`);
146
+ console.log(`${import_picocolors.default.cyan("[zenith]")} ${message}`);
152
147
  }
153
148
  function success(message) {
154
- console.log(`${colors.green}\u2713${colors.reset} ${message}`);
149
+ console.log(`${import_picocolors.default.green("\u2713")} ${message}`);
155
150
  }
156
151
  function warn(message) {
157
- console.log(`${colors.yellow}\u26A0${colors.reset} ${message}`);
152
+ console.log(`${import_picocolors.default.yellow("\u26A0")} ${message}`);
158
153
  }
159
154
  function error(message) {
160
- console.error(`${colors.red}\u2717${colors.reset} ${message}`);
155
+ console.error(`${import_picocolors.default.red("\u2717")} ${message}`);
161
156
  }
162
157
  function info(message) {
163
- console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
158
+ console.log(`${import_picocolors.default.blue("\u2139")} ${message}`);
164
159
  }
165
160
  function header(title) {
166
161
  console.log(`
167
- ${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")}
168
299
  `);
169
300
  }
170
301
 
@@ -1482,9 +1613,9 @@ class Tokenizer {
1482
1613
  this._err(ERR.absenceOfDigitsInNumericCharacterReference, this.entityStartPos - this.preprocessor.pos + consumed);
1483
1614
  },
1484
1615
  validateNumericCharacterReference: (code) => {
1485
- const error2 = getErrorForNumericCharacterReference(code);
1486
- if (error2)
1487
- this._err(error2, 1);
1616
+ const error3 = getErrorForNumericCharacterReference(code);
1617
+ if (error3)
1618
+ this._err(error3, 1);
1488
1619
  }
1489
1620
  } : undefined);
1490
1621
  }
@@ -8043,8 +8174,8 @@ function parseTemplate(html, filePath) {
8043
8174
  nodes,
8044
8175
  expressions
8045
8176
  };
8046
- } catch (error2) {
8047
- 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);
8048
8179
  }
8049
8180
  }
8050
8181
 
@@ -9135,6 +9266,7 @@ function transformStateDeclarations(script) {
9135
9266
  transformed = transformed.replace(/export\s+let\s+props(?:\s*:\s*([^;]+))?\s*;?[ \t]*/g, "");
9136
9267
  transformed = transformed.replace(/(?:type|interface)\s+Props\s*=?\s*\{[^}]*(?:\{[^}]*\}[^}]*)*\}[ \t]*;?/gs, "");
9137
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;`);
9138
9270
  return transformed.trim();
9139
9271
  }
9140
9272
 
@@ -9402,9 +9534,9 @@ function validateSingleExpression(expr, filePath) {
9402
9534
  if (!hasJSX) {
9403
9535
  try {
9404
9536
  new Function("state", "loaderData", "props", "stores", `return ${code}`);
9405
- } catch (error2) {
9537
+ } catch (error3) {
9406
9538
  errors.push(new CompilerError(`Invalid expression syntax: ${code}
9407
- ${error2.message}`, filePath, location.line, location.column));
9539
+ ${error3.message}`, filePath, location.line, location.column));
9408
9540
  }
9409
9541
  }
9410
9542
  if (code.includes("eval(") || code.includes("Function(") || code.includes("with (")) {
@@ -9442,9 +9574,9 @@ function finalizeOutput(ir, compiled) {
9442
9574
  const errors = [];
9443
9575
  try {
9444
9576
  validateExpressionsOrThrow(ir.template.expressions, ir.filePath);
9445
- } catch (error2) {
9446
- if (error2 instanceof Error) {
9447
- errors.push(error2.message);
9577
+ } catch (error3) {
9578
+ if (error3 instanceof Error) {
9579
+ errors.push(error3.message);
9448
9580
  return {
9449
9581
  html: "",
9450
9582
  js: "",
@@ -9468,8 +9600,8 @@ function finalizeOutput(ir, compiled) {
9468
9600
  let runtimeCode;
9469
9601
  try {
9470
9602
  runtimeCode = transformIR(ir);
9471
- } catch (error2) {
9472
- errors.push(`Runtime generation failed: ${error2.message}`);
9603
+ } catch (error3) {
9604
+ errors.push(`Runtime generation failed: ${error3.message}`);
9473
9605
  return {
9474
9606
  html: "",
9475
9607
  js: "",
@@ -9544,9 +9676,9 @@ function compileZenSource(source, filePath) {
9544
9676
  try {
9545
9677
  const finalized = finalizeOutputOrThrow(ir, compiled);
9546
9678
  return { ir, compiled, finalized };
9547
- } catch (error2) {
9679
+ } catch (error3) {
9548
9680
  throw new Error(`Failed to finalize output for ${filePath}:
9549
- ${error2.message}`);
9681
+ ${error3.message}`);
9550
9682
  }
9551
9683
  }
9552
9684
 
@@ -10139,6 +10271,88 @@ function generateBundleJS() {
10139
10271
  triggerMount();
10140
10272
  }
10141
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
+
10142
10356
  // ============================================
10143
10357
  // Export to window.__zenith
10144
10358
  // ============================================
@@ -10152,6 +10366,9 @@ function generateBundleJS() {
10152
10366
  ref: zenRef,
10153
10367
  batch: zenBatch,
10154
10368
  untrack: zenUntrack,
10369
+ // zenith:content
10370
+ defineSchema: defineSchema,
10371
+ zenCollection: zenCollection,
10155
10372
  // Lifecycle
10156
10373
  onMount: zenOnMount,
10157
10374
  onUnmount: zenOnUnmount,
@@ -10187,20 +10404,161 @@ function generateBundleJS() {
10187
10404
  global.onMount = zenOnMount;
10188
10405
  global.onUnmount = zenOnUnmount;
10189
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
+
10190
10452
  })(typeof window !== 'undefined' ? window : this);
10191
10453
  `;
10192
10454
  }
10193
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
+
10194
10545
  // cli/commands/dev.ts
10195
10546
  var pageCache = new Map;
10196
10547
  async function dev(options = {}) {
10197
10548
  const project = requireProject();
10198
10549
  const port = options.port || parseInt(process.env.PORT || "3000", 10);
10199
- const appDir = project.root;
10200
10550
  const pagesDir = project.pagesDir;
10201
- header("Zenith Dev Server");
10202
- log(`Project: ${project.root}`);
10203
- 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
+ });
10204
10562
  const STATIC_EXTENSIONS = new Set([
10205
10563
  ".js",
10206
10564
  ".css",
@@ -10218,23 +10576,18 @@ async function dev(options = {}) {
10218
10576
  ".json",
10219
10577
  ".map"
10220
10578
  ]);
10221
- function generateRuntimeJS() {
10222
- return generateBundleJS();
10223
- }
10224
10579
  function compilePageInMemory(pagePath) {
10225
10580
  try {
10226
- const layoutsDir = path4.join(pagesDir, "../layouts");
10581
+ const layoutsDir = path5.join(pagesDir, "../layouts");
10227
10582
  const layouts = discoverLayouts(layoutsDir);
10228
- const source = fs4.readFileSync(pagePath, "utf-8");
10583
+ const source = fs5.readFileSync(pagePath, "utf-8");
10229
10584
  let processedSource = source;
10230
10585
  let layoutToUse = layouts.get("DefaultLayout");
10231
- if (layoutToUse) {
10586
+ if (layoutToUse)
10232
10587
  processedSource = processLayout(source, layoutToUse);
10233
- }
10234
10588
  const result = compileZenSource(processedSource, pagePath);
10235
- if (!result.finalized) {
10236
- throw new Error("Compilation failed: No finalized output");
10237
- }
10589
+ if (!result.finalized)
10590
+ throw new Error("Compilation failed");
10238
10591
  const routeDef = generateRouteDefinition(pagePath, pagesDir);
10239
10592
  return {
10240
10593
  html: result.finalized.html,
@@ -10243,100 +10596,138 @@ async function dev(options = {}) {
10243
10596
  route: routeDef.path,
10244
10597
  lastModified: Date.now()
10245
10598
  };
10246
- } catch (error2) {
10247
- error(`Compilation error for ${pagePath}: ${error2.message}`);
10599
+ } catch (error3) {
10600
+ error(`Compilation error: ${error3.message}`);
10248
10601
  return null;
10249
10602
  }
10250
10603
  }
10251
- function generateDevHTML(page) {
10252
- const runtimeTag = `<script src="/runtime.js"></script>`;
10253
- const scriptTag = `<script>
10254
- ${page.script}
10255
- </script>`;
10256
- const allScripts = `${runtimeTag}
10257
- ${scriptTag}`;
10258
- if (page.html.includes("</body>")) {
10259
- return page.html.replace("</body>", `${allScripts}
10260
- </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
+ }
10261
10626
  }
10262
- return `${page.html}
10263
- ${allScripts}`;
10264
- }
10265
- function findPageForRoute(route) {
10266
- const exactPath = path4.join(pagesDir, route === "/" ? "index.zen" : `${route.slice(1)}.zen`);
10267
- if (fs4.existsSync(exactPath))
10268
- return exactPath;
10269
- const indexPath = path4.join(pagesDir, route === "/" ? "index.zen" : `${route.slice(1)}/index.zen`);
10270
- if (fs4.existsSync(indexPath))
10271
- return indexPath;
10272
- return null;
10273
- }
10274
- const cachedRuntimeJS = generateRuntimeJS();
10627
+ });
10275
10628
  const server = serve({
10276
10629
  port,
10277
- async fetch(req) {
10630
+ fetch(req, server2) {
10631
+ const startTime = performance.now();
10278
10632
  const url = new URL(req.url);
10279
10633
  const pathname = url.pathname;
10280
- const ext = path4.extname(pathname).toLowerCase();
10281
- if (pathname === "/runtime.js" || pathname === "/assets/bundle.js") {
10282
- return new Response(cachedRuntimeJS, {
10283
- headers: {
10284
- "Content-Type": "application/javascript; charset=utf-8",
10285
- "Cache-Control": "no-cache"
10286
- }
10287
- });
10634
+ const ext = path5.extname(pathname).toLowerCase();
10635
+ if (pathname === "/hmr") {
10636
+ const upgraded = server2.upgrade(req);
10637
+ if (upgraded)
10638
+ return;
10288
10639
  }
10289
- if (pathname === "/assets/styles.css" || pathname === "/styles/global.css" || pathname === "/app/styles/global.css") {
10290
- const globalCssPath = path4.join(pagesDir, "../styles/global.css");
10291
- if (fs4.existsSync(globalCssPath)) {
10292
- const css = fs4.readFileSync(globalCssPath, "utf-8");
10293
- return new Response(css, {
10294
- headers: { "Content-Type": "text/css; charset=utf-8" }
10295
- });
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;
10296
10654
  }
10297
10655
  }
10298
10656
  if (STATIC_EXTENSIONS.has(ext)) {
10299
- const publicPath = path4.join(pagesDir, "../public", pathname);
10300
- const distPath = path4.join(pagesDir, "../dist", pathname);
10301
- const appRelativePath = path4.join(pagesDir, "..", pathname);
10302
- for (const filePath of [publicPath, distPath, appRelativePath]) {
10303
- const file = Bun.file(filePath);
10304
- if (await file.exists()) {
10305
- return new Response(file);
10306
- }
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;
10307
10662
  }
10308
- return new Response("Not found", { status: 404 });
10309
10663
  }
10310
- const pagePath = findPageForRoute(pathname);
10664
+ const pagePath = findPageForRoute(pathname, pagesDir);
10311
10665
  if (pagePath) {
10666
+ const compileStart = performance.now();
10312
10667
  let cached = pageCache.get(pagePath);
10313
- const stat = fs4.statSync(pagePath);
10668
+ const stat = fs5.statSync(pagePath);
10314
10669
  if (!cached || stat.mtimeMs > cached.lastModified) {
10315
- const compiled = compilePageInMemory(pagePath);
10316
- if (compiled) {
10317
- pageCache.set(pagePath, compiled);
10318
- cached = compiled;
10319
- }
10670
+ cached = compilePageInMemory(pagePath) || undefined;
10671
+ if (cached)
10672
+ pageCache.set(pagePath, cached);
10320
10673
  }
10674
+ const compileEnd = performance.now();
10321
10675
  if (cached) {
10322
- const html = generateDevHTML(cached);
10323
- return new Response(html, {
10324
- headers: { "Content-Type": "text/html; charset=utf-8" }
10325
- });
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" } });
10326
10684
  }
10327
10685
  }
10686
+ route("GET", pathname, 404, Math.round(performance.now() - startTime), 0, 0);
10328
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() {}
10329
10697
  }
10330
10698
  });
10331
- success(`Server running at http://localhost:${server.port}`);
10332
- info("\u2022 In-memory compilation active");
10333
- info("\u2022 Auto-recompile on file changes");
10334
- info("Press Ctrl+C to stop");
10699
+ process.on("SIGINT", () => {
10700
+ watcher.close();
10701
+ server.stop();
10702
+ process.exit(0);
10703
+ });
10335
10704
  await new Promise(() => {});
10336
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
+ }
10337
10728
 
10338
10729
  // cli/commands/preview.ts
10339
- import path5 from "path";
10730
+ import path6 from "path";
10340
10731
  var {serve: serve2 } = globalThis.Bun;
10341
10732
  async function preview(options = {}) {
10342
10733
  const project = requireProject();
@@ -10366,16 +10757,16 @@ async function preview(options = {}) {
10366
10757
  async fetch(req) {
10367
10758
  const url = new URL(req.url);
10368
10759
  const pathname = url.pathname;
10369
- const ext = path5.extname(pathname).toLowerCase();
10760
+ const ext = path6.extname(pathname).toLowerCase();
10370
10761
  if (STATIC_EXTENSIONS.has(ext)) {
10371
- const filePath = path5.join(distDir, pathname);
10762
+ const filePath = path6.join(distDir, pathname);
10372
10763
  const file = Bun.file(filePath);
10373
10764
  if (await file.exists()) {
10374
10765
  return new Response(file);
10375
10766
  }
10376
10767
  return new Response("Not found", { status: 404 });
10377
10768
  }
10378
- const indexPath = path5.join(distDir, "index.html");
10769
+ const indexPath = path6.join(distDir, "index.html");
10379
10770
  const indexFile = Bun.file(indexPath);
10380
10771
  if (await indexFile.exists()) {
10381
10772
  return new Response(indexFile, {
@@ -10391,8 +10782,8 @@ async function preview(options = {}) {
10391
10782
  }
10392
10783
 
10393
10784
  // compiler/ssg-build.ts
10394
- import fs5 from "fs";
10395
- import path6 from "path";
10785
+ import fs6 from "fs";
10786
+ import path7 from "path";
10396
10787
 
10397
10788
  // compiler/build-analyzer.ts
10398
10789
  function analyzePageSource(source) {
@@ -10454,9 +10845,9 @@ function getBuildOutputType(analysis) {
10454
10845
 
10455
10846
  // compiler/ssg-build.ts
10456
10847
  function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
10457
- const source = fs5.readFileSync(pagePath, "utf-8");
10848
+ const source = fs6.readFileSync(pagePath, "utf-8");
10458
10849
  const analysis = analyzePageSource(source);
10459
- const layoutsDir = path6.join(baseDir, "layouts");
10850
+ const layoutsDir = path7.join(baseDir, "layouts");
10460
10851
  const layouts = discoverLayouts(layoutsDir);
10461
10852
  let processedSource = source;
10462
10853
  const layoutToUse = layouts.get("DefaultLayout");
@@ -10485,7 +10876,7 @@ function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
10485
10876
  outputDir
10486
10877
  };
10487
10878
  }
10488
- function generatePageHTML(page, globalStyles) {
10879
+ function generatePageHTML(page, globalStyles, contentData) {
10489
10880
  const { html, styles, analysis, routePath, pageScript } = page;
10490
10881
  const pageStyles = styles.join(`
10491
10882
  `);
@@ -10494,6 +10885,7 @@ function generatePageHTML(page, globalStyles) {
10494
10885
  let scriptTags = "";
10495
10886
  if (analysis.needsHydration) {
10496
10887
  scriptTags = `
10888
+ <script>window.__ZEN_CONTENT__ = ${JSON.stringify(contentData)};</script>
10497
10889
  <script src="/assets/bundle.js"></script>`;
10498
10890
  if (pageScript) {
10499
10891
  const pageJsName = routePath === "/" ? "page_index.js" : `page_${routePath.replace(/^\//, "").replace(/\//g, "_")}.js`;
@@ -10556,16 +10948,18 @@ ${page.pageScript}
10556
10948
  `;
10557
10949
  }
10558
10950
  function buildSSG(options) {
10559
- 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);
10560
10954
  console.log("\uD83D\uDD28 Zenith SSG Build");
10561
10955
  console.log(` Pages: ${pagesDir}`);
10562
10956
  console.log(` Output: ${outDir}`);
10563
10957
  console.log("");
10564
- if (fs5.existsSync(outDir)) {
10565
- fs5.rmSync(outDir, { recursive: true, force: true });
10958
+ if (fs6.existsSync(outDir)) {
10959
+ fs6.rmSync(outDir, { recursive: true, force: true });
10566
10960
  }
10567
- fs5.mkdirSync(outDir, { recursive: true });
10568
- fs5.mkdirSync(path6.join(outDir, "assets"), { recursive: true });
10961
+ fs6.mkdirSync(outDir, { recursive: true });
10962
+ fs6.mkdirSync(path7.join(outDir, "assets"), { recursive: true });
10569
10963
  const pageFiles = discoverPages(pagesDir);
10570
10964
  if (pageFiles.length === 0) {
10571
10965
  console.warn("\u26A0\uFE0F No pages found in", pagesDir);
@@ -10575,7 +10969,7 @@ function buildSSG(options) {
10575
10969
  const compiledPages = [];
10576
10970
  let hasHydratedPages = false;
10577
10971
  for (const pageFile of pageFiles) {
10578
- const relativePath = path6.relative(pagesDir, pageFile);
10972
+ const relativePath = path7.relative(pagesDir, pageFile);
10579
10973
  console.log(` Compiling: ${relativePath}`);
10580
10974
  try {
10581
10975
  const compiled = compilePage(pageFile, pagesDir, baseDir);
@@ -10586,61 +10980,61 @@ function buildSSG(options) {
10586
10980
  const outputType = getBuildOutputType(compiled.analysis);
10587
10981
  const summary = getAnalysisSummary(compiled.analysis);
10588
10982
  console.log(` \u2192 ${outputType.toUpperCase()} [${summary}]`);
10589
- } catch (error2) {
10590
- console.error(` \u274C Error: ${error2.message}`);
10591
- throw error2;
10983
+ } catch (error3) {
10984
+ console.error(` \u274C Error: ${error3.message}`);
10985
+ throw error3;
10592
10986
  }
10593
10987
  }
10594
10988
  console.log("");
10595
10989
  let globalStyles = "";
10596
- const globalCssPath = path6.join(baseDir, "styles", "global.css");
10597
- if (fs5.existsSync(globalCssPath)) {
10598
- 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");
10599
10993
  console.log("\uD83D\uDCE6 Loaded global.css");
10600
10994
  }
10601
10995
  if (hasHydratedPages) {
10602
10996
  const bundleJS = generateBundleJS();
10603
- fs5.writeFileSync(path6.join(outDir, "assets", "bundle.js"), bundleJS);
10997
+ fs6.writeFileSync(path7.join(outDir, "assets", "bundle.js"), bundleJS);
10604
10998
  console.log("\uD83D\uDCE6 Generated assets/bundle.js");
10605
10999
  }
10606
11000
  if (globalStyles) {
10607
- fs5.writeFileSync(path6.join(outDir, "assets", "styles.css"), globalStyles);
11001
+ fs6.writeFileSync(path7.join(outDir, "assets", "styles.css"), globalStyles);
10608
11002
  console.log("\uD83D\uDCE6 Generated assets/styles.css");
10609
11003
  }
10610
11004
  for (const page of compiledPages) {
10611
- const pageOutDir = path6.join(outDir, page.outputDir);
10612
- fs5.mkdirSync(pageOutDir, { recursive: true });
10613
- const html = generatePageHTML(page, globalStyles);
10614
- 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);
10615
11009
  if (page.pageScript) {
10616
11010
  const pageJsName = page.routePath === "/" ? "page_index.js" : `page_${page.routePath.replace(/^\//, "").replace(/\//g, "_")}.js`;
10617
11011
  const pageJS = generatePageJS(page);
10618
- fs5.writeFileSync(path6.join(outDir, "assets", pageJsName), pageJS);
11012
+ fs6.writeFileSync(path7.join(outDir, "assets", pageJsName), pageJS);
10619
11013
  }
10620
11014
  console.log(`\u2705 ${page.outputDir}/index.html`);
10621
11015
  }
10622
- const faviconPath = path6.join(baseDir, "favicon.ico");
10623
- if (fs5.existsSync(faviconPath)) {
10624
- 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"));
10625
11019
  console.log("\uD83D\uDCE6 Copied favicon.ico");
10626
11020
  }
10627
11021
  const custom404Candidates = ["404.zen", "+404.zen", "not-found.zen"];
10628
11022
  let has404 = false;
10629
11023
  for (const candidate of custom404Candidates) {
10630
- const custom404Path = path6.join(pagesDir, candidate);
10631
- if (fs5.existsSync(custom404Path)) {
11024
+ const custom404Path = path7.join(pagesDir, candidate);
11025
+ if (fs6.existsSync(custom404Path)) {
10632
11026
  try {
10633
11027
  const compiled = compilePage(custom404Path, pagesDir, baseDir);
10634
- const html = generatePageHTML(compiled, globalStyles);
10635
- fs5.writeFileSync(path6.join(outDir, "404.html"), html);
11028
+ const html = generatePageHTML(compiled, globalStyles, contentData);
11029
+ fs6.writeFileSync(path7.join(outDir, "404.html"), html);
10636
11030
  console.log("\uD83D\uDCE6 Generated 404.html (custom)");
10637
11031
  has404 = true;
10638
11032
  if (compiled.pageScript) {
10639
11033
  const pageJS = generatePageJS(compiled);
10640
- fs5.writeFileSync(path6.join(outDir, "assets", "page_404.js"), pageJS);
11034
+ fs6.writeFileSync(path7.join(outDir, "assets", "page_404.js"), pageJS);
10641
11035
  }
10642
- } catch (error2) {
10643
- console.warn(` \u26A0\uFE0F Could not compile ${candidate}: ${error2.message}`);
11036
+ } catch (error3) {
11037
+ console.warn(` \u26A0\uFE0F Could not compile ${candidate}: ${error3.message}`);
10644
11038
  }
10645
11039
  break;
10646
11040
  }
@@ -10671,7 +11065,7 @@ function buildSSG(options) {
10671
11065
  </div>
10672
11066
  </body>
10673
11067
  </html>`;
10674
- fs5.writeFileSync(path6.join(outDir, "404.html"), default404HTML);
11068
+ fs6.writeFileSync(path7.join(outDir, "404.html"), default404HTML);
10675
11069
  console.log("\uD83D\uDCE6 Generated 404.html (default)");
10676
11070
  }
10677
11071
  console.log("");
@@ -10709,30 +11103,30 @@ async function build(options = {}) {
10709
11103
  }
10710
11104
 
10711
11105
  // cli/utils/plugin-manager.ts
10712
- import fs6 from "fs";
10713
- import path7 from "path";
11106
+ import fs7 from "fs";
11107
+ import path8 from "path";
10714
11108
  var PLUGINS_FILE = "zenith.plugins.json";
10715
11109
  function getPluginsPath() {
10716
11110
  const root = findProjectRoot();
10717
11111
  if (!root) {
10718
11112
  throw new Error("Not in a Zenith project");
10719
11113
  }
10720
- return path7.join(root, PLUGINS_FILE);
11114
+ return path8.join(root, PLUGINS_FILE);
10721
11115
  }
10722
11116
  function readPlugins() {
10723
11117
  const pluginsPath = getPluginsPath();
10724
- if (!fs6.existsSync(pluginsPath)) {
11118
+ if (!fs7.existsSync(pluginsPath)) {
10725
11119
  return { plugins: [] };
10726
11120
  }
10727
11121
  try {
10728
- return JSON.parse(fs6.readFileSync(pluginsPath, "utf-8"));
11122
+ return JSON.parse(fs7.readFileSync(pluginsPath, "utf-8"));
10729
11123
  } catch {
10730
11124
  return { plugins: [] };
10731
11125
  }
10732
11126
  }
10733
11127
  function writePlugins(data) {
10734
11128
  const pluginsPath = getPluginsPath();
10735
- fs6.writeFileSync(pluginsPath, JSON.stringify(data, null, 2));
11129
+ fs7.writeFileSync(pluginsPath, JSON.stringify(data, null, 2));
10736
11130
  }
10737
11131
  function addPlugin(name, options) {
10738
11132
  const data = readPlugins();
@@ -10806,124 +11200,10 @@ async function remove(pluginName) {
10806
11200
  }
10807
11201
 
10808
11202
  // cli/commands/create.ts
10809
- import fs7 from "fs";
10810
- import path8 from "path";
11203
+ import fs8 from "fs";
11204
+ import path9 from "path";
10811
11205
  import { execSync } from "child_process";
10812
11206
  import readline from "readline";
10813
-
10814
- // cli/utils/branding.ts
10815
- var import_picocolors = __toESM(require_picocolors(), 1);
10816
- var colors2 = {
10817
- primary: import_picocolors.default.blue,
10818
- secondary: import_picocolors.default.cyan,
10819
- success: import_picocolors.default.green,
10820
- warning: import_picocolors.default.yellow,
10821
- error: import_picocolors.default.red,
10822
- muted: import_picocolors.default.gray,
10823
- bold: import_picocolors.default.bold,
10824
- dim: import_picocolors.default.dim
10825
- };
10826
- var LOGO = `
10827
- ${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")}
10828
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.cyan("\u2551")}
10829
- ${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")}
10830
- ${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")}
10831
- ${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")}
10832
- ${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")}
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\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")}
10834
- ${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")}
10835
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.cyan("\u2551")}
10836
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.dim("The Modern Reactive Web Framework")} ${import_picocolors.default.cyan("\u2551")}
10837
- ${import_picocolors.default.cyan("\u2551")} ${import_picocolors.default.cyan("\u2551")}
10838
- ${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")}
10839
- `;
10840
- var LOGO_COMPACT = `
10841
- ${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")}
10842
- `;
10843
- var spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
10844
-
10845
- class Spinner {
10846
- interval = null;
10847
- frameIndex = 0;
10848
- message;
10849
- constructor(message) {
10850
- this.message = message;
10851
- }
10852
- start() {
10853
- this.interval = setInterval(() => {
10854
- process.stdout.write(`\r${import_picocolors.default.cyan(spinnerFrames[this.frameIndex])} ${this.message}`);
10855
- this.frameIndex = (this.frameIndex + 1) % spinnerFrames.length;
10856
- }, 80);
10857
- }
10858
- stop(finalMessage) {
10859
- if (this.interval) {
10860
- clearInterval(this.interval);
10861
- this.interval = null;
10862
- }
10863
- process.stdout.write("\r" + " ".repeat(this.message.length + 5) + "\r");
10864
- if (finalMessage) {
10865
- console.log(finalMessage);
10866
- }
10867
- }
10868
- succeed(message) {
10869
- this.stop(`${import_picocolors.default.green("\u2713")} ${message}`);
10870
- }
10871
- fail(message) {
10872
- this.stop(`${import_picocolors.default.red("\u2717")} ${message}`);
10873
- }
10874
- }
10875
- function showLogo() {
10876
- console.log(LOGO);
10877
- }
10878
- function header2(text) {
10879
- console.log(`
10880
- ${import_picocolors.default.bold(import_picocolors.default.cyan("\u25B8"))} ${import_picocolors.default.bold(text)}
10881
- `);
10882
- }
10883
- function error2(text) {
10884
- console.log(`${import_picocolors.default.red("\u2717")} ${text}`);
10885
- }
10886
- function warn2(text) {
10887
- console.log(`${import_picocolors.default.yellow("\u26A0")} ${text}`);
10888
- }
10889
- function info2(text) {
10890
- console.log(`${import_picocolors.default.blue("\u2139")} ${text}`);
10891
- }
10892
- function highlight(text) {
10893
- return import_picocolors.default.cyan(text);
10894
- }
10895
- function dim(text) {
10896
- return import_picocolors.default.dim(text);
10897
- }
10898
- function bold(text) {
10899
- return import_picocolors.default.bold(text);
10900
- }
10901
- async function showIntro() {
10902
- console.clear();
10903
- showLogo();
10904
- await sleep(300);
10905
- }
10906
- function sleep(ms) {
10907
- return new Promise((resolve) => setTimeout(resolve, ms));
10908
- }
10909
- function showNextSteps(projectName) {
10910
- console.log(`
10911
- ${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")}
10912
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10913
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.green("\u2728")} ${import_picocolors.default.bold("Your Zenith app is ready!")} ${import_picocolors.default.cyan("\u2502")}
10914
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10915
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.dim("Next steps:")} ${import_picocolors.default.cyan("\u2502")}
10916
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10917
- ${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")}
10918
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("$")} ${import_picocolors.default.bold("bun run dev")} ${import_picocolors.default.cyan("\u2502")}
10919
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10920
- ${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")}
10921
- ${import_picocolors.default.cyan("\u2502")} ${import_picocolors.default.cyan("\u2502")}
10922
- ${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")}
10923
- `);
10924
- }
10925
-
10926
- // cli/commands/create.ts
10927
11207
  async function prompt(question, defaultValue) {
10928
11208
  const rl = readline.createInterface({
10929
11209
  input: process.stdin,
@@ -10960,7 +11240,7 @@ async function create(appName) {
10960
11240
  configSpinner.succeed("Configurations generated");
10961
11241
  const installSpinner = new Spinner("Installing dependencies...");
10962
11242
  installSpinner.start();
10963
- const targetDir = path8.resolve(process.cwd(), options.name);
11243
+ const targetDir = path9.resolve(process.cwd(), options.name);
10964
11244
  process.chdir(targetDir);
10965
11245
  try {
10966
11246
  execSync("bun install", { stdio: "pipe" });
@@ -10991,8 +11271,8 @@ async function gatherOptions(providedName) {
10991
11271
  process.exit(1);
10992
11272
  }
10993
11273
  }
10994
- const targetDir = path8.resolve(process.cwd(), name);
10995
- if (fs7.existsSync(targetDir)) {
11274
+ const targetDir = path9.resolve(process.cwd(), name);
11275
+ if (fs8.existsSync(targetDir)) {
10996
11276
  error2(`Directory "${name}" already exists`);
10997
11277
  process.exit(1);
10998
11278
  }
@@ -11013,14 +11293,14 @@ async function gatherOptions(providedName) {
11013
11293
  };
11014
11294
  }
11015
11295
  async function createProject(options) {
11016
- const targetDir = path8.resolve(process.cwd(), options.name);
11296
+ const targetDir = path9.resolve(process.cwd(), options.name);
11017
11297
  const baseDir = options.directory;
11018
- const appDir = path8.join(targetDir, baseDir);
11019
- fs7.mkdirSync(targetDir, { recursive: true });
11020
- fs7.mkdirSync(path8.join(appDir, "pages"), { recursive: true });
11021
- fs7.mkdirSync(path8.join(appDir, "layouts"), { recursive: true });
11022
- fs7.mkdirSync(path8.join(appDir, "components"), { recursive: true });
11023
- 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 });
11024
11304
  const pkg = {
11025
11305
  name: options.name,
11026
11306
  version: "0.1.0",
@@ -11050,14 +11330,14 @@ async function createProject(options) {
11050
11330
  devDeps["prettier"] = "^3.0.0";
11051
11331
  pkg.scripts = { ...pkg.scripts, format: "prettier --write ." };
11052
11332
  }
11053
- fs7.writeFileSync(path8.join(targetDir, "package.json"), JSON.stringify(pkg, null, 4));
11054
- fs7.writeFileSync(path8.join(targetDir, baseDir, "pages", "index.zen"), generateIndexPage());
11055
- fs7.writeFileSync(path8.join(targetDir, baseDir, "layouts", "DefaultLayout.zen"), generateDefaultLayout());
11056
- fs7.writeFileSync(path8.join(appDir, "styles", "global.css"), generateGlobalCSS());
11057
- 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());
11058
11338
  }
11059
11339
  async function generateConfigs(options) {
11060
- const targetDir = path8.resolve(process.cwd(), options.name);
11340
+ const targetDir = path9.resolve(process.cwd(), options.name);
11061
11341
  const tsconfig = {
11062
11342
  compilerOptions: {
11063
11343
  target: "ESNext",
@@ -11081,7 +11361,7 @@ async function generateConfigs(options) {
11081
11361
  "@/*": [`./${options.directory}/*`]
11082
11362
  };
11083
11363
  }
11084
- 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));
11085
11365
  if (options.eslint) {
11086
11366
  const eslintConfig = {
11087
11367
  root: true,
@@ -11102,7 +11382,7 @@ async function generateConfigs(options) {
11102
11382
  },
11103
11383
  ignorePatterns: ["dist", "node_modules"]
11104
11384
  };
11105
- 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));
11106
11386
  }
11107
11387
  if (options.prettier) {
11108
11388
  const prettierConfig = {
@@ -11112,8 +11392,8 @@ async function generateConfigs(options) {
11112
11392
  trailingComma: "es5",
11113
11393
  printWidth: 100
11114
11394
  };
11115
- fs7.writeFileSync(path8.join(targetDir, ".prettierrc"), JSON.stringify(prettierConfig, null, 4));
11116
- 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
11117
11397
  node_modules
11118
11398
  bun.lock
11119
11399
  `);