@lytjs/cli 5.0.4 → 6.4.0

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.
Files changed (43) hide show
  1. package/dist/create.cjs +522 -0
  2. package/dist/create.cjs.map +1 -0
  3. package/dist/create.d.mts +2 -0
  4. package/dist/create.d.ts +2 -0
  5. package/dist/create.mjs +520 -0
  6. package/dist/create.mjs.map +1 -0
  7. package/dist/index.cjs +1363 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.mts +188 -0
  10. package/dist/index.d.ts +188 -0
  11. package/dist/index.mjs +1219 -935
  12. package/dist/index.mjs.map +1 -0
  13. package/dist/lyt.cjs +1363 -0
  14. package/dist/lyt.cjs.map +1 -0
  15. package/dist/lyt.d.mts +1 -0
  16. package/dist/lyt.d.ts +1 -0
  17. package/dist/lyt.mjs +1342 -0
  18. package/dist/lyt.mjs.map +1 -0
  19. package/lyt-cli.js +3 -0
  20. package/package.json +34 -31
  21. package/README.md +0 -227
  22. package/dist/bin/cli.cjs +0 -2
  23. package/dist/bin/cli.js +0 -2
  24. package/dist/bin/cli.mjs +0 -1
  25. package/dist/index.js +0 -1058
  26. package/dist/types/bin/cli.d.ts +0 -9
  27. package/dist/types/bin/cli.d.ts.map +0 -1
  28. package/dist/types/build.d.ts +0 -30
  29. package/dist/types/build.d.ts.map +0 -1
  30. package/dist/types/create.d.ts +0 -19
  31. package/dist/types/create.d.ts.map +0 -1
  32. package/dist/types/dev.d.ts +0 -24
  33. package/dist/types/dev.d.ts.map +0 -1
  34. package/dist/types/generate.d.ts +0 -14
  35. package/dist/types/generate.d.ts.map +0 -1
  36. package/dist/types/hmr.d.ts +0 -55
  37. package/dist/types/hmr.d.ts.map +0 -1
  38. package/dist/types/index.d.ts +0 -20
  39. package/dist/types/index.d.ts.map +0 -1
  40. package/dist/types/scaffold.d.ts +0 -67
  41. package/dist/types/scaffold.d.ts.map +0 -1
  42. package/dist/types/utils.d.ts +0 -92
  43. package/dist/types/utils.d.ts.map +0 -1
package/dist/lyt.cjs ADDED
@@ -0,0 +1,1363 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ var fs = require('fs');
5
+ var path = require('path');
6
+ var child_process = require('child_process');
7
+
8
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
10
+ }) : x)(function(x) {
11
+ if (typeof require !== "undefined") return require.apply(this, arguments);
12
+ throw Error('Dynamic require of "' + x + '" is not supported');
13
+ });
14
+
15
+ // src/utils/logger.ts
16
+ var colors = {
17
+ reset: "\x1B[0m",
18
+ bright: "\x1B[1m",
19
+ dim: "\x1B[2m",
20
+ red: "\x1B[31m",
21
+ green: "\x1B[32m",
22
+ yellow: "\x1B[33m",
23
+ blue: "\x1B[34m",
24
+ cyan: "\x1B[36m"
25
+ };
26
+ function colorize(text, color) {
27
+ if (!isColorSupported()) return text;
28
+ return `${colors[color]}${text}${colors.reset}`;
29
+ }
30
+ var logger = {
31
+ info(message) {
32
+ console.log(colorize("\u2139 ", "blue") + message);
33
+ },
34
+ success(message) {
35
+ console.log(colorize("\u2714 ", "green") + message);
36
+ },
37
+ warning(message) {
38
+ console.log(colorize("\u26A0 ", "yellow") + message);
39
+ },
40
+ error(message) {
41
+ console.error(colorize("\u2716 ", "red") + message);
42
+ },
43
+ dim(message) {
44
+ console.log(colorize(message, "dim"));
45
+ },
46
+ bold(message) {
47
+ return colorize(message, "bright");
48
+ }
49
+ };
50
+ function isColorSupported() {
51
+ return process.stdout.isTTY && process.env.NO_COLOR !== "1";
52
+ }
53
+ function ensureDir(dir) {
54
+ if (!fs.existsSync(dir)) {
55
+ fs.mkdirSync(dir, { recursive: true });
56
+ }
57
+ }
58
+ function writeFile(filePath, content) {
59
+ ensureDir(path.dirname(filePath));
60
+ fs.writeFileSync(filePath, content, "utf-8");
61
+ }
62
+ function readFile(filePath) {
63
+ return fs.readFileSync(filePath, "utf-8");
64
+ }
65
+ function exists(path) {
66
+ return fs.existsSync(path);
67
+ }
68
+ function isEmptyDir(dir) {
69
+ if (!fs.existsSync(dir)) return true;
70
+ const files = fs.readdirSync(dir);
71
+ return files.length === 0;
72
+ }
73
+ function detectPackageManager(cwd = process.cwd()) {
74
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
75
+ if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
76
+ if (fs.existsSync(path.join(cwd, "package-lock.json"))) return "npm";
77
+ try {
78
+ child_process.execSync("pnpm --version", { stdio: "ignore" });
79
+ return "pnpm";
80
+ } catch {
81
+ return "npm";
82
+ }
83
+ }
84
+ function getInstallCommand(pm) {
85
+ switch (pm) {
86
+ case "pnpm":
87
+ return "pnpm install";
88
+ case "yarn":
89
+ return "yarn";
90
+ case "npm":
91
+ return "npm install";
92
+ }
93
+ }
94
+ function getRunCommand(pm, script) {
95
+ switch (pm) {
96
+ case "pnpm":
97
+ return `pnpm run ${script}`;
98
+ case "yarn":
99
+ return `yarn ${script}`;
100
+ case "npm":
101
+ return `npm run ${script}`;
102
+ }
103
+ }
104
+ function getAddCommand(pm, dep, dev2 = false) {
105
+ const devFlag = dev2 ? " -D" : "";
106
+ switch (pm) {
107
+ case "pnpm":
108
+ return `pnpm add${devFlag} ${dep}`;
109
+ case "yarn":
110
+ return `yarn add${devFlag} ${dep}`;
111
+ case "npm":
112
+ return `npm install${devFlag} ${dep}`;
113
+ }
114
+ }
115
+ var TEMPLATES = {
116
+ default: "Default template with TypeScript and Vite",
117
+ minimal: "Minimal template without extra dependencies",
118
+ ssr: "SSR-enabled template",
119
+ router: "Template with Router integration",
120
+ store: "Template with Store integration",
121
+ full: "Full-featured template with Router, Store, and UI components"
122
+ };
123
+ async function create(projectName, options = {}) {
124
+ if (!projectName) {
125
+ logger.error("Please provide a project name.");
126
+ logger.info("Usage: lyt create <project-name>");
127
+ process.exit(1);
128
+ }
129
+ const targetDir = path.resolve(process.cwd(), projectName);
130
+ if (exists(targetDir) && !isEmptyDir(targetDir) && !options.force) {
131
+ logger.error(`Directory "${projectName}" already exists and is not empty.`);
132
+ logger.info("Use --force to overwrite.");
133
+ process.exit(1);
134
+ }
135
+ logger.info(`Creating a new LytJS project in ${targetDir}...`);
136
+ ensureDir(targetDir);
137
+ generateProjectFiles(targetDir, projectName, options.template || "default");
138
+ logger.info("Installing dependencies...");
139
+ const pm = detectPackageManager();
140
+ try {
141
+ child_process.execSync(getInstallCommand(pm), { cwd: targetDir, stdio: "inherit" });
142
+ logger.success("Dependencies installed successfully!");
143
+ } catch (_error) {
144
+ logger.warning("Failed to install dependencies automatically.");
145
+ logger.info(`Please run "${getInstallCommand(pm)}" manually.`);
146
+ }
147
+ logger.success(`Project "${projectName}" created successfully!`);
148
+ logger.info("");
149
+ logger.bold("Next steps:");
150
+ logger.info(` cd ${projectName}`);
151
+ logger.info(` ${pm === "npm" ? "npm run" : pm} dev`);
152
+ }
153
+ function generateProjectFiles(targetDir, projectName, template) {
154
+ const isMinimal = template === "minimal";
155
+ const isSsr = template === "ssr";
156
+ const isRouter = template === "router" || template === "full";
157
+ const isStore = template === "store" || template === "full";
158
+ const isFull = template === "full";
159
+ const packageJson = {
160
+ name: projectName,
161
+ version: "0.0.0",
162
+ type: "module",
163
+ scripts: {
164
+ dev: "vite",
165
+ build: "vite build",
166
+ preview: "vite preview"
167
+ },
168
+ dependencies: {
169
+ "@lytjs/core": "^6.0.0"
170
+ },
171
+ devDependencies: {
172
+ "@lytjs/plugin-vite": "^6.0.0",
173
+ "vite": "^5.0.0"
174
+ }
175
+ };
176
+ if (!isMinimal) {
177
+ packageJson.scripts.test = "vitest";
178
+ packageJson.devDependencies.vitest = "^1.0.0";
179
+ }
180
+ if (isSsr) {
181
+ packageJson.dependencies["@lytjs/server"] = "^6.0.0";
182
+ packageJson.scripts["build:client"] = "vite build --ssrManifest";
183
+ packageJson.scripts["build:server"] = "vite build --ssr src/entry-server.ts";
184
+ packageJson.scripts["build"] = "npm run build:client && npm run build:server";
185
+ packageJson.scripts["preview"] = "node server";
186
+ }
187
+ if (isRouter) {
188
+ packageJson.dependencies["@lytjs/router"] = "^1.0.0";
189
+ }
190
+ if (isStore) {
191
+ packageJson.dependencies["@lytjs/store"] = "^1.0.0";
192
+ }
193
+ if (isFull) {
194
+ packageJson.dependencies["@lytjs/ui"] = "^0.4.0";
195
+ }
196
+ writeFile(path.join(targetDir, "package.json"), JSON.stringify(packageJson, null, 2));
197
+ let viteConfig;
198
+ if (isSsr) {
199
+ viteConfig = `import { defineConfig } from 'vite';
200
+ import lytjs from '@lytjs/plugin-vite';
201
+
202
+ export default defineConfig({
203
+ plugins: [lytjs()],
204
+ build: {
205
+ ssrManifest: true,
206
+ },
207
+ });
208
+ `;
209
+ } else {
210
+ viteConfig = `import { defineConfig } from 'vite';
211
+ import lytjs from '@lytjs/plugin-vite';
212
+
213
+ export default defineConfig({
214
+ plugins: [lytjs()],
215
+ });
216
+ `;
217
+ }
218
+ writeFile(path.join(targetDir, "vite.config.ts"), viteConfig);
219
+ const indexHtml = `<!DOCTYPE html>
220
+ <html lang="en">
221
+ <head>
222
+ <meta charset="UTF-8" />
223
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
224
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
225
+ <title>${projectName}</title>
226
+ </head>
227
+ <body>
228
+ <div id="app"></div>
229
+ <script type="module" src="/src/main.ts"></script>
230
+ </body>
231
+ </html>
232
+ `;
233
+ writeFile(path.join(targetDir, "index.html"), indexHtml);
234
+ let mainTs;
235
+ if (isSsr) {
236
+ mainTs = `import { createApp } from '@lytjs/core';
237
+ import App from './App.lyt';
238
+ import { createSSRApp } from '@lytjs/server';
239
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
240
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
241
+
242
+ const app = createSSRApp(App);
243
+ ${isStore ? "app.use(createPinia());" : ""}
244
+ ${isRouter ? `
245
+ const router = createRouter({
246
+ history: createWebHistory(),
247
+ routes: [
248
+ { path: '/', component: () => import('./pages/Home.lyt') },
249
+ { path: '/about', component: () => import('./pages/About.lyt') },
250
+ ],
251
+ });
252
+ app.use(router);
253
+ ` : ""}
254
+ app.mount('#app');
255
+ `;
256
+ } else if (isRouter || isStore) {
257
+ mainTs = `import { createApp } from '@lytjs/core';
258
+ import App from './App.lyt';
259
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
260
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
261
+
262
+ const app = createApp(App);
263
+ ${isStore ? "app.use(createPinia());" : ""}
264
+ ${isRouter ? `
265
+ const router = createRouter({
266
+ history: createWebHistory(),
267
+ routes: [
268
+ { path: '/', component: () => import('./pages/Home.lyt') },
269
+ { path: '/about', component: () => import('./pages/About.lyt') },
270
+ ],
271
+ });
272
+ app.use(router);
273
+ ` : ""}
274
+ app.mount('#app');
275
+ `;
276
+ } else {
277
+ mainTs = `import { createApp } from '@lytjs/core';
278
+ import App from './App.lyt';
279
+
280
+ createApp(App).mount('#app');
281
+ `;
282
+ }
283
+ writeFile(path.join(targetDir, "src/main.ts"), mainTs);
284
+ let appLyt;
285
+ if (isMinimal) {
286
+ appLyt = `<template>
287
+ <div class="app">
288
+ <h1>{{ title }}</h1>
289
+ </div>
290
+ </template>
291
+
292
+ <script setup>
293
+ const title = 'Hello LytJS!';
294
+ </script>
295
+
296
+ <style scoped>
297
+ .app {
298
+ text-align: center;
299
+ }
300
+ </style>
301
+ `;
302
+ } else if (isRouter) {
303
+ appLyt = `<template>
304
+ <div class="app">
305
+ <nav class="nav">
306
+ <router-link to="/">Home</router-link>
307
+ <router-link to="/about">About</router-link>
308
+ </nav>
309
+ <router-view />
310
+ </div>
311
+ </template>
312
+
313
+ <script setup lang="ts">
314
+ import { RouterLink, RouterView } from '@lytjs/router';
315
+ </script>
316
+
317
+ <style scoped>
318
+ .app {
319
+ text-align: center;
320
+ padding: 2rem;
321
+ }
322
+
323
+ .nav {
324
+ margin-bottom: 2rem;
325
+ }
326
+
327
+ .nav a {
328
+ margin: 0 1rem;
329
+ color: #42b883;
330
+ text-decoration: none;
331
+ }
332
+
333
+ .nav a:hover {
334
+ text-decoration: underline;
335
+ }
336
+ </style>
337
+ `;
338
+ } else {
339
+ appLyt = `<template>
340
+ <div class="app">
341
+ <h1>{{ title }}</h1>
342
+ <p>Welcome to your LytJS app!</p>
343
+ </div>
344
+ </template>
345
+
346
+ <script setup>
347
+ const title = 'Hello LytJS!';
348
+ </script>
349
+
350
+ <style scoped>
351
+ .app {
352
+ text-align: center;
353
+ padding: 2rem;
354
+ }
355
+
356
+ h1 {
357
+ color: #42b883;
358
+ }
359
+ </style>
360
+ `;
361
+ }
362
+ writeFile(path.join(targetDir, "src/App.lyt"), appLyt);
363
+ if (isRouter) {
364
+ const homePage = `<template>
365
+ <div class="home">
366
+ <h1>Home</h1>
367
+ ${isStore ? `
368
+ <p>Count: {{ count }}</p>
369
+ <button @click="increment">Increment</button>
370
+ <button @click="decrement">Decrement</button>
371
+ ` : ""}
372
+ <p>Welcome to the Home page!</p>
373
+ </div>
374
+ </template>
375
+
376
+ <script setup lang="ts">
377
+ ${isStore ? `import { useCounterStore } from '../stores/counter';
378
+ const counterStore = useCounterStore();
379
+ const { count, increment, decrement } = counterStore;
380
+ ` : ""}
381
+ </script>
382
+
383
+ <style scoped>
384
+ .home {
385
+ padding: 1rem;
386
+ }
387
+ </style>
388
+ `;
389
+ ensureDir(path.join(targetDir, "src", "pages"));
390
+ writeFile(path.join(targetDir, "src", "pages", "Home.lyt"), homePage);
391
+ const aboutPage = `<template>
392
+ <div class="about">
393
+ <h1>About</h1>
394
+ <p>This is the About page!</p>
395
+ </div>
396
+ </template>
397
+
398
+ <script setup lang="ts">
399
+ </script>
400
+
401
+ <style scoped>
402
+ .about {
403
+ padding: 1rem;
404
+ }
405
+ </style>
406
+ `;
407
+ writeFile(path.join(targetDir, "src", "pages", "About.lyt"), aboutPage);
408
+ }
409
+ if (isStore) {
410
+ const counterStore = `import { defineStore } from '@lytjs/store';
411
+ import { signal, computed } from '@lytjs/reactivity';
412
+
413
+ export const useCounterStore = defineStore('counter', () => {
414
+ // State
415
+ const count = signal(0);
416
+
417
+ // Getters
418
+ const doubleCount = computed(() => count.value * 2);
419
+
420
+ // Actions
421
+ function increment() {
422
+ count.value++;
423
+ }
424
+
425
+ function decrement() {
426
+ count.value--;
427
+ }
428
+
429
+ function reset() {
430
+ count.value = 0;
431
+ }
432
+
433
+ return {
434
+ count,
435
+ doubleCount,
436
+ increment,
437
+ decrement,
438
+ reset,
439
+ };
440
+ });
441
+ `;
442
+ ensureDir(path.join(targetDir, "src", "stores"));
443
+ writeFile(path.join(targetDir, "src", "stores", "counter.ts"), counterStore);
444
+ }
445
+ if (isSsr) {
446
+ const entryServer = `import { createSSRApp } from '@lytjs/core';
447
+ import App from './App.lyt';
448
+
449
+ export async function render(url: string) {
450
+ const app = createSSRApp(App);
451
+ return app;
452
+ }
453
+ `;
454
+ writeFile(path.join(targetDir, "src/entry-server.ts"), entryServer);
455
+ const entryClient = `import { createApp } from '@lytjs/core';
456
+ import App from './App.lyt';
457
+
458
+ const app = createApp(App);
459
+ app.mount('#app');
460
+ `;
461
+ writeFile(path.join(targetDir, "src/entry-client.ts"), entryClient);
462
+ const serverTs = `/**
463
+ * LytJS SSR Server
464
+ *
465
+ * A minimal SSR server for development and production.
466
+ */
467
+
468
+ import fs from 'fs';
469
+ import path from 'path';
470
+ import { fileURLToPath } from 'url';
471
+
472
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
473
+ const isProduction = process.env.NODE_ENV === 'production';
474
+
475
+ async function createServer() {
476
+ let resolve: any;
477
+ let vite: any;
478
+
479
+ if (!isProduction) {
480
+ const { createServer: createViteServer } = await import('vite');
481
+ vite = await createViteServer({
482
+ server: { middlewareMode: true },
483
+ appType: 'custom',
484
+ });
485
+ resolve = (id: string) => vite.resolveUrl(id);
486
+ } else {
487
+ resolve = (id: string) => id;
488
+ }
489
+
490
+ // TODO: Set up express/polka server and SSR rendering
491
+ console.log('LytJS SSR server starting...');
492
+ }
493
+
494
+ createServer();
495
+ `;
496
+ writeFile(path.join(targetDir, "server.ts"), serverTs);
497
+ }
498
+ const tsConfig = {
499
+ compilerOptions: {
500
+ target: "ES2020",
501
+ useDefineForClassFields: true,
502
+ module: "ESNext",
503
+ lib: ["ES2020", "DOM", "DOM.Iterable"],
504
+ skipLibCheck: true,
505
+ moduleResolution: "bundler",
506
+ allowImportingTsExtensions: true,
507
+ resolveJsonModule: true,
508
+ isolatedModules: true,
509
+ noEmit: true,
510
+ strict: true,
511
+ noUnusedLocals: true,
512
+ noUnusedParameters: true,
513
+ noFallthroughCasesInSwitch: true
514
+ },
515
+ include: ["src/**/*.ts", "src/**/*.lyt"],
516
+ references: [{ path: "./tsconfig.node.json" }]
517
+ };
518
+ writeFile(path.join(targetDir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
519
+ const tsConfigNode = {
520
+ compilerOptions: {
521
+ composite: true,
522
+ skipLibCheck: true,
523
+ module: "ESNext",
524
+ moduleResolution: "bundler",
525
+ allowSyntheticDefaultImports: true
526
+ },
527
+ include: ["vite.config.ts"]
528
+ };
529
+ writeFile(path.join(targetDir, "tsconfig.node.json"), JSON.stringify(tsConfigNode, null, 2));
530
+ const gitignore = `# Logs
531
+ logs
532
+ *.log
533
+ npm-debug.log*
534
+ yarn-debug.log*
535
+ yarn-error.log*
536
+ pnpm-debug.log*
537
+ lerna-debug.log*
538
+
539
+ node_modules
540
+ dist
541
+ dist-ssr
542
+ *.local
543
+
544
+ # Editor directories and files
545
+ .vscode/*
546
+ !.vscode/extensions.json
547
+ .idea
548
+ .DS_Store
549
+ *.suo
550
+ *.ntvs*
551
+ *.njsproj
552
+ *.sln
553
+ *.sw?
554
+ `;
555
+ writeFile(path.join(targetDir, ".gitignore"), gitignore);
556
+ }
557
+ function listTemplates() {
558
+ logger.bold("Available templates:");
559
+ for (const [name, description] of Object.entries(TEMPLATES)) {
560
+ logger.info(` ${name.padEnd(10)} - ${description}`);
561
+ }
562
+ }
563
+ async function dev(options = {}) {
564
+ if (!exists(path.join(process.cwd(), "package.json"))) {
565
+ logger.error("No package.json found. Are you in a LytJS project directory?");
566
+ process.exit(1);
567
+ }
568
+ const pm = detectPackageManager();
569
+ const runCmd = getRunCommand(pm, "dev");
570
+ logger.info(`Starting development server with ${pm}...`);
571
+ const devArgs = [];
572
+ if (options.port) devArgs.push("--port", String(options.port));
573
+ if (options.host) devArgs.push("--host", options.host);
574
+ if (options.open) devArgs.push("--open");
575
+ const cmdParts = runCmd.split(" ");
576
+ const cmd = cmdParts[0] ?? "pnpm";
577
+ const cmdArgs = [...cmdParts.slice(1), ...devArgs];
578
+ const child = child_process.spawn(cmd, cmdArgs, {
579
+ stdio: "inherit",
580
+ shell: true
581
+ });
582
+ child.on("error", (error) => {
583
+ logger.error(`Failed to start dev server: ${error.message}`);
584
+ process.exit(1);
585
+ });
586
+ child.on("exit", (code) => {
587
+ process.exit(code || 0);
588
+ });
589
+ }
590
+ async function build(options = {}) {
591
+ if (!exists(path.join(process.cwd(), "package.json"))) {
592
+ logger.error("No package.json found. Are you in a LytJS project directory?");
593
+ process.exit(1);
594
+ }
595
+ const pm = detectPackageManager();
596
+ logger.info("Building for production...");
597
+ const args = ["vite", "build"];
598
+ if (options.outDir) args.push("--outDir", options.outDir);
599
+ if (options.ssr) args.push("--ssr");
600
+ if (options.minify === false) args.push("--minify", "false");
601
+ const child = child_process.spawn(pm === "npm" ? "npx" : pm, args, {
602
+ stdio: "inherit",
603
+ shell: true
604
+ });
605
+ child.on("error", (error) => {
606
+ logger.error(`Build failed: ${error.message}`);
607
+ process.exit(1);
608
+ });
609
+ child.on("exit", (code) => {
610
+ if (code === 0) {
611
+ logger.success("Build completed successfully!");
612
+ } else {
613
+ logger.error(`Build failed with exit code ${code}`);
614
+ }
615
+ process.exit(code || 0);
616
+ });
617
+ }
618
+ async function test(options = {}) {
619
+ if (!exists(path.join(process.cwd(), "package.json"))) {
620
+ logger.error("No package.json found. Are you in a LytJS project directory?");
621
+ process.exit(1);
622
+ }
623
+ const pm = detectPackageManager();
624
+ logger.info("Running tests...");
625
+ const args = ["vitest"];
626
+ if (options.watch === false) args.push("run");
627
+ if (options.coverage) args.push("--coverage");
628
+ if (options.grep) args.push("--grep", options.grep);
629
+ const child = child_process.spawn(pm === "npm" ? "npx" : pm, args, {
630
+ stdio: "inherit",
631
+ shell: true
632
+ });
633
+ child.on("error", (error) => {
634
+ logger.error(`Tests failed: ${error.message}`);
635
+ process.exit(1);
636
+ });
637
+ child.on("exit", (code) => {
638
+ process.exit(code || 0);
639
+ });
640
+ }
641
+ var TEMPLATES2 = {
642
+ component(name, basePath) {
643
+ const filePath = path.join(basePath, `${name}.lyt`);
644
+ return [{
645
+ filePath,
646
+ content: `<template>
647
+ <div class="${name}">
648
+ <slot />
649
+ </div>
650
+ </template>
651
+
652
+ <script setup lang="ts">
653
+ defineProps<{
654
+ /** Component props */
655
+ }>();
656
+
657
+ defineEmits<{
658
+ /** Component events */
659
+ }>();
660
+ </script>
661
+
662
+ <style scoped>
663
+ .${name} {
664
+ /* styles */
665
+ }
666
+ </style>
667
+ `
668
+ }];
669
+ },
670
+ page(name, basePath) {
671
+ const filePath = path.join(basePath, `${name}.lyt`);
672
+ return [{
673
+ filePath,
674
+ content: `<template>
675
+ <div class="page-${name}">
676
+ <h1>${toPascalCase(name)}</h1>
677
+ </div>
678
+ </template>
679
+
680
+ <script setup lang="ts">
681
+ // Page logic here
682
+ </script>
683
+
684
+ <style scoped>
685
+ .page-${name} {
686
+ padding: 1rem;
687
+ }
688
+ </style>
689
+ `
690
+ }];
691
+ },
692
+ store(name, basePath) {
693
+ const filePath = path.join(basePath, `${name}.ts`);
694
+ return [{
695
+ filePath,
696
+ content: `import { defineStore } from '@lytjs/store';
697
+ import { signal, computed } from '@lytjs/reactivity';
698
+
699
+ export const use${toPascalCase(name)}Store = defineStore('${name}', () => {
700
+ // State
701
+ const count = signal(0);
702
+
703
+ // Getters
704
+ const doubleCount = computed(() => count.value * 2);
705
+
706
+ // Actions
707
+ function increment() {
708
+ count.value++;
709
+ }
710
+
711
+ function decrement() {
712
+ count.value--;
713
+ }
714
+
715
+ function reset() {
716
+ count.value = 0;
717
+ }
718
+
719
+ return {
720
+ count,
721
+ doubleCount,
722
+ increment,
723
+ decrement,
724
+ reset,
725
+ };
726
+ });
727
+ `
728
+ }];
729
+ }
730
+ };
731
+ function toPascalCase(str) {
732
+ return str.split(/[-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
733
+ }
734
+ function resolveTargetDir(type) {
735
+ const cwd = process.cwd();
736
+ switch (type) {
737
+ case "component":
738
+ return path.join(cwd, "src", "components");
739
+ case "page":
740
+ return path.join(cwd, "src", "pages");
741
+ case "store":
742
+ return path.join(cwd, "src", "stores");
743
+ }
744
+ }
745
+ async function add(type, name, options = {}) {
746
+ const targetDir = resolveTargetDir(type);
747
+ const fullPath = path.resolve(targetDir);
748
+ if (!exists(path.join(process.cwd(), "package.json"))) {
749
+ logger.error("No package.json found. Are you in a LytJS project directory?");
750
+ process.exit(1);
751
+ }
752
+ const template = TEMPLATES2[type];
753
+ if (!template) {
754
+ logger.error(`Unknown type: ${type}. Supported types: component, page, store`);
755
+ process.exit(1);
756
+ }
757
+ const files = template(name, fullPath);
758
+ for (const file of files) {
759
+ if (exists(file.filePath) && !options.force) {
760
+ logger.warning(`File already exists: ${file.filePath}`);
761
+ logger.info("Use --force to overwrite.");
762
+ continue;
763
+ }
764
+ ensureDir(path.resolve(file.filePath, ".."));
765
+ writeFile(file.filePath, file.content);
766
+ logger.success(`Created ${type}: ${file.filePath}`);
767
+ }
768
+ }
769
+ var PLUGIN_TEMPLATES = {
770
+ default: "Default plugin template with TypeScript",
771
+ minimal: "Minimal plugin without extra dependencies",
772
+ withConfig: "Plugin template with configuration schema"
773
+ };
774
+ function getTemplateContent(template, pluginName) {
775
+ const packageName = `@lytjs/plugin-${pluginName}`;
776
+ const files = {};
777
+ files["package.json"] = JSON.stringify({
778
+ name: packageName,
779
+ version: "0.1.0",
780
+ description: `LytJS plugin: ${pluginName}`,
781
+ main: "dist/index.cjs",
782
+ module: "dist/index.mjs",
783
+ types: "dist/index.d.ts",
784
+ exports: {
785
+ ".": {
786
+ import: "./dist/index.mjs",
787
+ require: "./dist/index.cjs",
788
+ types: "./dist/index.d.ts"
789
+ }
790
+ },
791
+ files: ["dist"],
792
+ scripts: {
793
+ build: "tsup",
794
+ dev: "tsup --watch",
795
+ test: "vitest",
796
+ lint: "eslint src",
797
+ "prepublishOnly": "npm run build"
798
+ },
799
+ keywords: ["lytjs", "plugin"],
800
+ license: "MIT",
801
+ peerDependencies: {
802
+ "@lytjs/core": ">=6.0.0"
803
+ }
804
+ }, null, 2);
805
+ files["tsconfig.json"] = JSON.stringify({
806
+ extends: "@lytjs/core/tsconfig.json",
807
+ compilerOptions: {
808
+ outDir: "./dist",
809
+ rootDir: "./src",
810
+ declaration: true,
811
+ declarationMap: true
812
+ },
813
+ include: ["src"],
814
+ exclude: ["node_modules", "dist", "tests"]
815
+ }, null, 2);
816
+ files["tsup.config.ts"] = `import { defineConfig } from 'tsup';
817
+
818
+ export default defineConfig({
819
+ entry: { index: 'src/index.ts' },
820
+ format: ['esm', 'cjs'],
821
+ dts: true,
822
+ sourcemap: true,
823
+ clean: true,
824
+ splitting: false,
825
+ treeshake: true,
826
+ minify: false,
827
+ external: ['@lytjs/core'],
828
+ });
829
+ `;
830
+ if (template === "withConfig") {
831
+ files["src/index.ts"] = `/**
832
+ * @lytjs/plugin-${pluginName}
833
+ *
834
+ * A LytJS plugin with configuration schema support.
835
+ */
836
+
837
+ import { definePlugin } from '@lytjs/core';
838
+ import type { ConfigSchema } from '@lytjs/core';
839
+
840
+ /**
841
+ * Plugin options schema
842
+ */
843
+ const optionsSchema: ConfigSchema<${pluginName.replace(/-/g, "")}Options> = {
844
+ type: 'object',
845
+ properties: {
846
+ debug: {
847
+ type: 'boolean',
848
+ description: 'Enable debug mode',
849
+ default: false,
850
+ },
851
+ option1: {
852
+ type: 'string',
853
+ description: 'First option',
854
+ default: 'default value',
855
+ },
856
+ },
857
+ additionalProperties: false,
858
+ };
859
+
860
+ ${pluginName.replace(/-/g, "")}Options\`;
861
+
862
+ export interface ${pluginName.replace(/-/g, "")}Options {
863
+ debug?: boolean;
864
+ option1?: string;
865
+ }
866
+
867
+ /**
868
+ * Create the plugin with configuration schema
869
+ */
870
+ export function create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}(options?: ${pluginName.replace(/-/g, "")}Options) {
871
+ return definePlugin({
872
+ name: '${packageName}',
873
+ version: '0.1.0',
874
+ description: 'A LytJS plugin',
875
+ schema: optionsSchema,
876
+ install: (app, opts) => {
877
+ const config = opts || {};
878
+ console.log('[${packageName}] Installing with config:', config);
879
+ },
880
+ });
881
+ }
882
+
883
+ /**
884
+ * Direct plugin export (without schema)
885
+ */
886
+ export default create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}();
887
+ `;
888
+ } else {
889
+ files["src/index.ts"] = `/**
890
+ * @lytjs/plugin-${pluginName}
891
+ *
892
+ * A LytJS plugin.
893
+ */
894
+
895
+ import { definePlugin } from '@lytjs/core';
896
+
897
+ /**
898
+ * Create the plugin
899
+ */
900
+ export function create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}() {
901
+ return definePlugin({
902
+ name: '${packageName}',
903
+ version: '0.1.0',
904
+ description: 'A LytJS plugin',
905
+ install: (app) => {
906
+ console.log('[${packageName}] Plugin installed');
907
+ },
908
+ });
909
+ }
910
+
911
+ /**
912
+ * Direct plugin export
913
+ */
914
+ export default create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}();
915
+ `;
916
+ }
917
+ if (template === "minimal") {
918
+ files["src/types.ts"] = `/**
919
+ * Plugin types
920
+ */
921
+
922
+ export interface PluginOptions {
923
+ // Define your plugin options here
924
+ }
925
+ `;
926
+ }
927
+ files["README.md"] = `# @lytjs/plugin-${pluginName}
928
+
929
+ A LytJS plugin.
930
+
931
+ ## Installation
932
+
933
+ \`\`\`bash
934
+ npm install @lytjs/plugin-${pluginName}
935
+ \`\`\`
936
+
937
+ ## Usage
938
+
939
+ \`\`\`typescript
940
+ import { createApp } from '@lytjs/core';
941
+ import myPlugin from '@lytjs/plugin-${pluginName}';
942
+
943
+ const app = createApp(App);
944
+ app.use(myPlugin);
945
+ \`\`\`
946
+
947
+ ## API
948
+
949
+ ### createPlugin(options?)
950
+
951
+ Create the plugin with options.
952
+
953
+ ## License
954
+
955
+ MIT
956
+ `;
957
+ files[".gitignore"] = `# Logs
958
+ logs
959
+ *.log
960
+ npm-debug.log*
961
+ yarn-debug.log*
962
+ pnpm-debug.log*
963
+
964
+ node_modules
965
+ dist
966
+ *.local
967
+
968
+ # IDE
969
+ .vscode
970
+ .idea
971
+ *.sw?
972
+ `;
973
+ return files;
974
+ }
975
+ async function createPlugin(name, options = {}) {
976
+ const targetDir = path.resolve(process.cwd(), name);
977
+ const template = options.template || "default";
978
+ if (template !== "default" && template !== "minimal" && template !== "withConfig") {
979
+ logger.error(`Unknown template: ${template}`);
980
+ logger.info("Available templates: default, minimal, withConfig");
981
+ process.exit(1);
982
+ }
983
+ if (fs.existsSync(targetDir) && !isEmptyDir2(targetDir) && !options.force) {
984
+ logger.error(`Directory "${name}" already exists and is not empty.`);
985
+ logger.info("Use --force to overwrite.");
986
+ process.exit(1);
987
+ }
988
+ logger.info(`Creating a new LytJS plugin in ${targetDir}...`);
989
+ ensureDir(targetDir);
990
+ const files = getTemplateContent(template, name);
991
+ for (const [filePath, content] of Object.entries(files)) {
992
+ const fullPath = path.join(targetDir, filePath);
993
+ const fileDir = path.resolve(fullPath, "..");
994
+ if (!fs.existsSync(fileDir)) {
995
+ fs.mkdirSync(fileDir, { recursive: true });
996
+ }
997
+ fs.writeFileSync(fullPath, content, "utf-8");
998
+ logger.success(`Created: ${filePath}`);
999
+ }
1000
+ if (!options.skipInstall) {
1001
+ logger.info("Installing dependencies...");
1002
+ try {
1003
+ child_process.execSync("pnpm install", { cwd: targetDir, stdio: "inherit" });
1004
+ logger.success("Dependencies installed!");
1005
+ } catch (_error) {
1006
+ logger.warning("Failed to install dependencies automatically.");
1007
+ logger.info('Please run "pnpm install" manually.');
1008
+ }
1009
+ }
1010
+ logger.success(`Plugin "${name}" created successfully!`);
1011
+ logger.info("");
1012
+ logger.bold("Next steps:");
1013
+ logger.info(` cd ${name}`);
1014
+ logger.info(" pnpm dev # Start development");
1015
+ logger.info(" pnpm build # Build for production");
1016
+ logger.info(" pnpm test # Run tests");
1017
+ }
1018
+ async function buildPlugin(options = {}) {
1019
+ const cwd = process.cwd();
1020
+ const outDir = options.outDir || "dist";
1021
+ const pkgPath = path.join(cwd, "package.json");
1022
+ if (!fs.existsSync(pkgPath)) {
1023
+ logger.error("No package.json found. Are you in a plugin directory?");
1024
+ process.exit(1);
1025
+ }
1026
+ logger.info("Building plugin...");
1027
+ try {
1028
+ const buildCmd = "tsup";
1029
+ const args = ["--entry", "src/index.ts", "--outDir", outDir, "--format", "esm,cjs", "--dts", "--sourcemap"];
1030
+ if (options.minify) {
1031
+ args.push("--minify");
1032
+ }
1033
+ child_process.execSync(`${buildCmd} ${args.join(" ")}`, { cwd, stdio: "inherit" });
1034
+ logger.success("Build completed!");
1035
+ logger.info(`Output: ${path.join(cwd, outDir)}`);
1036
+ } catch (_error) {
1037
+ logger.error("Build failed. Make sure tsup is installed: pnpm add -D tsup");
1038
+ process.exit(1);
1039
+ }
1040
+ }
1041
+ async function validatePlugin(options = {}) {
1042
+ const cwd = process.cwd();
1043
+ logger.info("Validating plugin...");
1044
+ const errors = [];
1045
+ const warnings = [];
1046
+ const pkgPath = path.join(cwd, "package.json");
1047
+ if (!fs.existsSync(pkgPath)) {
1048
+ errors.push("package.json not found");
1049
+ } else {
1050
+ try {
1051
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
1052
+ if (!pkg.name) errors.push("package.json: name is required");
1053
+ if (!pkg.version) errors.push("package.json: version is required");
1054
+ if (!pkg.main) errors.push("package.json: main is required");
1055
+ if (!pkg.module) errors.push("package.json: module is required");
1056
+ if (!pkg.types) errors.push("package.json: types is required");
1057
+ if (!pkg.exports) {
1058
+ warnings.push("package.json: exports field is recommended");
1059
+ }
1060
+ if (!pkg.peerDependencies || !pkg.peerDependencies["@lytjs/core"]) {
1061
+ errors.push("package.json: @lytjs/core peerDependency is required");
1062
+ }
1063
+ if (!pkg.keywords || !pkg.keywords.includes("lytjs")) {
1064
+ warnings.push('package.json: "lytjs" keyword is recommended');
1065
+ }
1066
+ } catch (err) {
1067
+ errors.push(`package.json: Invalid JSON - ${err}`);
1068
+ }
1069
+ }
1070
+ const srcPath = path.join(cwd, "src");
1071
+ if (!fs.existsSync(srcPath)) {
1072
+ errors.push("src directory not found");
1073
+ } else {
1074
+ const indexPath = path.join(srcPath, "index.ts");
1075
+ if (!fs.existsSync(indexPath)) {
1076
+ errors.push("src/index.ts not found");
1077
+ } else {
1078
+ const content = fs.readFileSync(indexPath, "utf-8");
1079
+ if (!content.includes("definePlugin") && !content.includes("EnhancedPlugin")) {
1080
+ warnings.push("src/index.ts: Consider using definePlugin or EnhancedPlugin");
1081
+ }
1082
+ if (!content.includes("export")) {
1083
+ warnings.push("src/index.ts: No exports found");
1084
+ }
1085
+ }
1086
+ }
1087
+ const tsconfigPath = path.join(cwd, "tsconfig.json");
1088
+ if (!fs.existsSync(tsconfigPath)) {
1089
+ warnings.push("tsconfig.json not found (recommended)");
1090
+ }
1091
+ const tsupConfigPath = path.join(cwd, "tsup.config.ts");
1092
+ if (!fs.existsSync(tsupConfigPath)) {
1093
+ warnings.push("tsup.config.ts not found (recommended for builds)");
1094
+ }
1095
+ let hasErrors = errors.length > 0;
1096
+ let hasWarnings = warnings.length > 0;
1097
+ if (hasErrors) {
1098
+ logger.error("Validation failed with errors:");
1099
+ for (const err of errors) {
1100
+ logger.error(` - ${err}`);
1101
+ }
1102
+ }
1103
+ if (hasWarnings && !options.strict) {
1104
+ logger.warning("Warnings:");
1105
+ for (const warn of warnings) {
1106
+ logger.warning(` - ${warn}`);
1107
+ }
1108
+ }
1109
+ if (!hasErrors && !hasWarnings) {
1110
+ logger.success("Plugin validation passed!");
1111
+ } else if (hasWarnings && !hasErrors) {
1112
+ logger.success("Plugin validation passed (with warnings)");
1113
+ if (options.strict) {
1114
+ process.exit(1);
1115
+ }
1116
+ } else {
1117
+ if (options.warningsAsErrors && hasWarnings) {
1118
+ logger.error("Strict mode: treating warnings as errors");
1119
+ }
1120
+ process.exit(1);
1121
+ }
1122
+ }
1123
+ function isEmptyDir2(dir) {
1124
+ if (!fs.existsSync(dir)) return true;
1125
+ const files = __require("fs").readdirSync(dir);
1126
+ return files.length === 0;
1127
+ }
1128
+ function listPluginTemplates() {
1129
+ logger.bold("Available plugin templates:");
1130
+ for (const [name, description] of Object.entries(PLUGIN_TEMPLATES)) {
1131
+ logger.info(` ${name.padEnd(12)} - ${description}`);
1132
+ }
1133
+ }
1134
+
1135
+ // src/commands/run.ts
1136
+ var VERSION = "6.0.0";
1137
+ async function runCli(rawArgs = process.argv.slice(2)) {
1138
+ const { command, args, options } = parseArgs(rawArgs);
1139
+ if (options.help || command === "help") {
1140
+ showHelp();
1141
+ return;
1142
+ }
1143
+ if (options.version || command === "version" || command === "-v" || command === "--version") {
1144
+ console.log(`LytJS CLI v${VERSION}`);
1145
+ return;
1146
+ }
1147
+ switch (command) {
1148
+ case "create":
1149
+ await create(args[0] || "my-lytjs-app", {
1150
+ template: options.template,
1151
+ force: options.force
1152
+ });
1153
+ break;
1154
+ case "templates":
1155
+ listTemplates();
1156
+ break;
1157
+ case "dev":
1158
+ await dev({
1159
+ port: options.port ? parseInt(options.port, 10) : void 0,
1160
+ host: options.host,
1161
+ open: options.open
1162
+ });
1163
+ break;
1164
+ case "build":
1165
+ await build({
1166
+ outDir: options.outDir,
1167
+ ssr: options.ssr,
1168
+ minify: options.minify !== "false"
1169
+ });
1170
+ break;
1171
+ case "test":
1172
+ await test({
1173
+ watch: options.watch !== "false",
1174
+ coverage: options.coverage,
1175
+ grep: options.grep
1176
+ });
1177
+ break;
1178
+ case "add":
1179
+ if (!args[0] || !["component", "page", "store"].includes(args[0])) {
1180
+ logger.error("Usage: lyt add <component|page|store> <name>");
1181
+ logger.info("Example: lyt add component Button");
1182
+ process.exit(1);
1183
+ }
1184
+ await add(args[0], args[1] || "Unnamed", {
1185
+ force: options.force
1186
+ });
1187
+ break;
1188
+ case "plugin":
1189
+ if (!args[0]) {
1190
+ logger.error("Usage: lyt plugin <create|build|validate|templates>");
1191
+ logger.info("Example: lyt plugin create my-plugin");
1192
+ process.exit(1);
1193
+ }
1194
+ const subCommand = args[0];
1195
+ switch (subCommand) {
1196
+ case "create":
1197
+ await createPlugin(args[1] || "my-plugin", {
1198
+ template: options.template,
1199
+ force: options.force,
1200
+ skipInstall: options.skipInstall
1201
+ });
1202
+ break;
1203
+ case "build":
1204
+ await buildPlugin({
1205
+ outDir: options.outDir,
1206
+ minify: options.minify,
1207
+ sourcemap: options.sourcemap
1208
+ });
1209
+ break;
1210
+ case "validate":
1211
+ await validatePlugin({
1212
+ strict: options.strict,
1213
+ warningsAsErrors: options.warningsAsErrors
1214
+ });
1215
+ break;
1216
+ case "templates":
1217
+ listPluginTemplates();
1218
+ break;
1219
+ default:
1220
+ logger.error(`Unknown plugin sub-command: ${subCommand}`);
1221
+ logger.info("Supported sub-commands: create, build, validate, templates");
1222
+ process.exit(1);
1223
+ }
1224
+ break;
1225
+ default:
1226
+ if (command) {
1227
+ logger.error(`Unknown command: ${command}`);
1228
+ logger.info('Run "lyt --help" for usage information.');
1229
+ process.exit(1);
1230
+ } else {
1231
+ showHelp();
1232
+ }
1233
+ }
1234
+ }
1235
+ function parseArgs(args) {
1236
+ let command = args[0] ?? "";
1237
+ const positional = [];
1238
+ const options = {};
1239
+ if (command.startsWith("--") || command.startsWith("-")) {
1240
+ command = "";
1241
+ }
1242
+ const startIndex = command ? 1 : 0;
1243
+ for (let i = startIndex; i < args.length; i++) {
1244
+ const arg = args[i] ?? "";
1245
+ if (arg.startsWith("--")) {
1246
+ const parts = arg.slice(2).split("=");
1247
+ const key = parts[0];
1248
+ const value = parts[1];
1249
+ if (value !== void 0 && key) {
1250
+ options[key] = value;
1251
+ } else if (key && i + 1 < args.length && !(args[i + 1] ?? "").startsWith("-")) {
1252
+ const nextArg = args[++i];
1253
+ if (nextArg) {
1254
+ options[key] = nextArg;
1255
+ }
1256
+ } else if (key) {
1257
+ options[key] = true;
1258
+ }
1259
+ } else if (arg.startsWith("-")) {
1260
+ const key = arg.slice(1);
1261
+ if (key) {
1262
+ options[key] = true;
1263
+ }
1264
+ } else {
1265
+ positional.push(arg);
1266
+ }
1267
+ }
1268
+ return { command, args: positional, options };
1269
+ }
1270
+ function showHelp() {
1271
+ console.log(`
1272
+ ${logger.bold("LytJS CLI")} v${VERSION}
1273
+
1274
+ ${logger.bold("Usage:")}
1275
+ lyt <command> [options]
1276
+
1277
+ ${logger.bold("Commands:")}
1278
+ create <name> Create a new LytJS project
1279
+ templates List available templates
1280
+ dev Start development server
1281
+ build Build for production
1282
+ test Run tests
1283
+ add <type> <name> Generate a component, page, or store
1284
+ plugin <subcmd> Plugin development commands
1285
+ help Show this help message
1286
+
1287
+ ${logger.bold("Options:")}
1288
+ --version, -v Show version number
1289
+ --help Show help
1290
+
1291
+ ${logger.bold("Create Options:")}
1292
+ --template <name> Use a specific template
1293
+ --force Overwrite existing directory
1294
+
1295
+ ${logger.bold("Dev Options:")}
1296
+ --port <number> Specify port (default: 5173)
1297
+ --host <host> Specify host (default: localhost)
1298
+ --open Open browser on start
1299
+
1300
+ ${logger.bold("Build Options:")}
1301
+ --outDir <dir> Output directory (default: dist)
1302
+ --ssr Build for SSR
1303
+ --minify false Disable minification
1304
+
1305
+ ${logger.bold("Test Options:")}
1306
+ --watch false Run tests once (no watch mode)
1307
+ --coverage Generate coverage report
1308
+ --grep <pattern> Filter tests by pattern
1309
+
1310
+ ${logger.bold("Plugin Options:")}
1311
+ --template <name> Use a specific plugin template (default, minimal, withConfig)
1312
+ --force Overwrite existing directory
1313
+ --skipInstall Skip installing dependencies
1314
+ --outDir <dir> Output directory (default: dist)
1315
+ --minify Minify output
1316
+ --sourcemap Generate sourcemaps
1317
+ --strict Strict validation mode
1318
+ --warningsAsErrors Treat warnings as errors
1319
+
1320
+ ${logger.bold("Examples:")}
1321
+ lyt create my-app
1322
+ lyt create my-app --template minimal
1323
+ lyt create my-app --template router
1324
+ lyt create my-app --template full
1325
+ lyt dev --port 3000
1326
+ lyt build --ssr
1327
+ lyt add component Button
1328
+ lyt add page About
1329
+ lyt add store user
1330
+ lyt plugin create my-plugin
1331
+ lyt plugin create my-plugin --template withConfig
1332
+ lyt plugin build
1333
+ lyt plugin validate
1334
+ `);
1335
+ }
1336
+
1337
+ // src/index.ts
1338
+ if (__require.main === module) {
1339
+ runCli().catch(console.error);
1340
+ }
1341
+
1342
+ exports.add = add;
1343
+ exports.build = build;
1344
+ exports.buildPlugin = buildPlugin;
1345
+ exports.create = create;
1346
+ exports.createPlugin = createPlugin;
1347
+ exports.detectPackageManager = detectPackageManager;
1348
+ exports.dev = dev;
1349
+ exports.ensureDir = ensureDir;
1350
+ exports.exists = exists;
1351
+ exports.getAddCommand = getAddCommand;
1352
+ exports.getInstallCommand = getInstallCommand;
1353
+ exports.getRunCommand = getRunCommand;
1354
+ exports.listPluginTemplates = listPluginTemplates;
1355
+ exports.listTemplates = listTemplates;
1356
+ exports.logger = logger;
1357
+ exports.readFile = readFile;
1358
+ exports.runCli = runCli;
1359
+ exports.test = test;
1360
+ exports.validatePlugin = validatePlugin;
1361
+ exports.writeFile = writeFile;
1362
+ //# sourceMappingURL=lyt.cjs.map
1363
+ //# sourceMappingURL=lyt.cjs.map