@lytjs/cli 5.0.6 → 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 -1058
  23. package/dist/bin/cli.js +0 -2
  24. package/dist/bin/cli.mjs +0 -1058
  25. package/dist/index.js +0 -1058
  26. package/dist/types/bin/cli.d.ts +0 -8
  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
@@ -0,0 +1,522 @@
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
+ // src/utils/logger.ts
9
+ var colors = {
10
+ reset: "\x1B[0m",
11
+ bright: "\x1B[1m",
12
+ dim: "\x1B[2m",
13
+ red: "\x1B[31m",
14
+ green: "\x1B[32m",
15
+ yellow: "\x1B[33m",
16
+ blue: "\x1B[34m",
17
+ cyan: "\x1B[36m"
18
+ };
19
+ function colorize(text, color) {
20
+ if (!isColorSupported()) return text;
21
+ return `${colors[color]}${text}${colors.reset}`;
22
+ }
23
+ var logger = {
24
+ info(message) {
25
+ console.log(colorize("\u2139 ", "blue") + message);
26
+ },
27
+ success(message) {
28
+ console.log(colorize("\u2714 ", "green") + message);
29
+ },
30
+ warning(message) {
31
+ console.log(colorize("\u26A0 ", "yellow") + message);
32
+ },
33
+ error(message) {
34
+ console.error(colorize("\u2716 ", "red") + message);
35
+ },
36
+ dim(message) {
37
+ console.log(colorize(message, "dim"));
38
+ },
39
+ bold(message) {
40
+ return colorize(message, "bright");
41
+ }
42
+ };
43
+ function isColorSupported() {
44
+ return process.stdout.isTTY && process.env.NO_COLOR !== "1";
45
+ }
46
+ function ensureDir(dir) {
47
+ if (!fs.existsSync(dir)) {
48
+ fs.mkdirSync(dir, { recursive: true });
49
+ }
50
+ }
51
+ function writeFile(filePath, content) {
52
+ ensureDir(path.dirname(filePath));
53
+ fs.writeFileSync(filePath, content, "utf-8");
54
+ }
55
+ function exists(path) {
56
+ return fs.existsSync(path);
57
+ }
58
+ function isEmptyDir(dir) {
59
+ if (!fs.existsSync(dir)) return true;
60
+ const files = fs.readdirSync(dir);
61
+ return files.length === 0;
62
+ }
63
+ function detectPackageManager(cwd = process.cwd()) {
64
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
65
+ if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
66
+ if (fs.existsSync(path.join(cwd, "package-lock.json"))) return "npm";
67
+ try {
68
+ child_process.execSync("pnpm --version", { stdio: "ignore" });
69
+ return "pnpm";
70
+ } catch {
71
+ return "npm";
72
+ }
73
+ }
74
+ function getInstallCommand(pm) {
75
+ switch (pm) {
76
+ case "pnpm":
77
+ return "pnpm install";
78
+ case "yarn":
79
+ return "yarn";
80
+ case "npm":
81
+ return "npm install";
82
+ }
83
+ }
84
+ async function create(projectName, options = {}) {
85
+ {
86
+ logger.error("Please provide a project name.");
87
+ logger.info("Usage: lyt create <project-name>");
88
+ process.exit(1);
89
+ }
90
+ const targetDir = path.resolve(process.cwd(), projectName);
91
+ if (exists(targetDir) && !isEmptyDir(targetDir) && !options.force) {
92
+ logger.error(`Directory "${projectName}" already exists and is not empty.`);
93
+ logger.info("Use --force to overwrite.");
94
+ process.exit(1);
95
+ }
96
+ logger.info(`Creating a new LytJS project in ${targetDir}...`);
97
+ ensureDir(targetDir);
98
+ generateProjectFiles(targetDir, projectName, options.template || "default");
99
+ logger.info("Installing dependencies...");
100
+ const pm = detectPackageManager();
101
+ try {
102
+ child_process.execSync(getInstallCommand(pm), { cwd: targetDir, stdio: "inherit" });
103
+ logger.success("Dependencies installed successfully!");
104
+ } catch (_error) {
105
+ logger.warning("Failed to install dependencies automatically.");
106
+ logger.info(`Please run "${getInstallCommand(pm)}" manually.`);
107
+ }
108
+ logger.success(`Project "${projectName}" created successfully!`);
109
+ logger.info("");
110
+ logger.bold("Next steps:");
111
+ logger.info(` cd ${projectName}`);
112
+ logger.info(` ${pm === "npm" ? "npm run" : pm} dev`);
113
+ }
114
+ function generateProjectFiles(targetDir, projectName, template) {
115
+ const isMinimal = template === "minimal";
116
+ const isSsr = template === "ssr";
117
+ const isRouter = template === "router" || template === "full";
118
+ const isStore = template === "store" || template === "full";
119
+ const isFull = template === "full";
120
+ const packageJson = {
121
+ name: projectName,
122
+ version: "0.0.0",
123
+ type: "module",
124
+ scripts: {
125
+ dev: "vite",
126
+ build: "vite build",
127
+ preview: "vite preview"
128
+ },
129
+ dependencies: {
130
+ "@lytjs/core": "^6.0.0"
131
+ },
132
+ devDependencies: {
133
+ "@lytjs/plugin-vite": "^6.0.0",
134
+ "vite": "^5.0.0"
135
+ }
136
+ };
137
+ if (!isMinimal) {
138
+ packageJson.scripts.test = "vitest";
139
+ packageJson.devDependencies.vitest = "^1.0.0";
140
+ }
141
+ if (isSsr) {
142
+ packageJson.dependencies["@lytjs/server"] = "^6.0.0";
143
+ packageJson.scripts["build:client"] = "vite build --ssrManifest";
144
+ packageJson.scripts["build:server"] = "vite build --ssr src/entry-server.ts";
145
+ packageJson.scripts["build"] = "npm run build:client && npm run build:server";
146
+ packageJson.scripts["preview"] = "node server";
147
+ }
148
+ if (isRouter) {
149
+ packageJson.dependencies["@lytjs/router"] = "^1.0.0";
150
+ }
151
+ if (isStore) {
152
+ packageJson.dependencies["@lytjs/store"] = "^1.0.0";
153
+ }
154
+ if (isFull) {
155
+ packageJson.dependencies["@lytjs/ui"] = "^0.4.0";
156
+ }
157
+ writeFile(path.join(targetDir, "package.json"), JSON.stringify(packageJson, null, 2));
158
+ let viteConfig;
159
+ if (isSsr) {
160
+ viteConfig = `import { defineConfig } from 'vite';
161
+ import lytjs from '@lytjs/plugin-vite';
162
+
163
+ export default defineConfig({
164
+ plugins: [lytjs()],
165
+ build: {
166
+ ssrManifest: true,
167
+ },
168
+ });
169
+ `;
170
+ } else {
171
+ viteConfig = `import { defineConfig } from 'vite';
172
+ import lytjs from '@lytjs/plugin-vite';
173
+
174
+ export default defineConfig({
175
+ plugins: [lytjs()],
176
+ });
177
+ `;
178
+ }
179
+ writeFile(path.join(targetDir, "vite.config.ts"), viteConfig);
180
+ const indexHtml = `<!DOCTYPE html>
181
+ <html lang="en">
182
+ <head>
183
+ <meta charset="UTF-8" />
184
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
185
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
186
+ <title>${projectName}</title>
187
+ </head>
188
+ <body>
189
+ <div id="app"></div>
190
+ <script type="module" src="/src/main.ts"></script>
191
+ </body>
192
+ </html>
193
+ `;
194
+ writeFile(path.join(targetDir, "index.html"), indexHtml);
195
+ let mainTs;
196
+ if (isSsr) {
197
+ mainTs = `import { createApp } from '@lytjs/core';
198
+ import App from './App.lyt';
199
+ import { createSSRApp } from '@lytjs/server';
200
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
201
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
202
+
203
+ const app = createSSRApp(App);
204
+ ${isStore ? "app.use(createPinia());" : ""}
205
+ ${isRouter ? `
206
+ const router = createRouter({
207
+ history: createWebHistory(),
208
+ routes: [
209
+ { path: '/', component: () => import('./pages/Home.lyt') },
210
+ { path: '/about', component: () => import('./pages/About.lyt') },
211
+ ],
212
+ });
213
+ app.use(router);
214
+ ` : ""}
215
+ app.mount('#app');
216
+ `;
217
+ } else if (isRouter || isStore) {
218
+ mainTs = `import { createApp } from '@lytjs/core';
219
+ import App from './App.lyt';
220
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
221
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
222
+
223
+ const app = createApp(App);
224
+ ${isStore ? "app.use(createPinia());" : ""}
225
+ ${isRouter ? `
226
+ const router = createRouter({
227
+ history: createWebHistory(),
228
+ routes: [
229
+ { path: '/', component: () => import('./pages/Home.lyt') },
230
+ { path: '/about', component: () => import('./pages/About.lyt') },
231
+ ],
232
+ });
233
+ app.use(router);
234
+ ` : ""}
235
+ app.mount('#app');
236
+ `;
237
+ } else {
238
+ mainTs = `import { createApp } from '@lytjs/core';
239
+ import App from './App.lyt';
240
+
241
+ createApp(App).mount('#app');
242
+ `;
243
+ }
244
+ writeFile(path.join(targetDir, "src/main.ts"), mainTs);
245
+ let appLyt;
246
+ if (isMinimal) {
247
+ appLyt = `<template>
248
+ <div class="app">
249
+ <h1>{{ title }}</h1>
250
+ </div>
251
+ </template>
252
+
253
+ <script setup>
254
+ const title = 'Hello LytJS!';
255
+ </script>
256
+
257
+ <style scoped>
258
+ .app {
259
+ text-align: center;
260
+ }
261
+ </style>
262
+ `;
263
+ } else if (isRouter) {
264
+ appLyt = `<template>
265
+ <div class="app">
266
+ <nav class="nav">
267
+ <router-link to="/">Home</router-link>
268
+ <router-link to="/about">About</router-link>
269
+ </nav>
270
+ <router-view />
271
+ </div>
272
+ </template>
273
+
274
+ <script setup lang="ts">
275
+ import { RouterLink, RouterView } from '@lytjs/router';
276
+ </script>
277
+
278
+ <style scoped>
279
+ .app {
280
+ text-align: center;
281
+ padding: 2rem;
282
+ }
283
+
284
+ .nav {
285
+ margin-bottom: 2rem;
286
+ }
287
+
288
+ .nav a {
289
+ margin: 0 1rem;
290
+ color: #42b883;
291
+ text-decoration: none;
292
+ }
293
+
294
+ .nav a:hover {
295
+ text-decoration: underline;
296
+ }
297
+ </style>
298
+ `;
299
+ } else {
300
+ appLyt = `<template>
301
+ <div class="app">
302
+ <h1>{{ title }}</h1>
303
+ <p>Welcome to your LytJS app!</p>
304
+ </div>
305
+ </template>
306
+
307
+ <script setup>
308
+ const title = 'Hello LytJS!';
309
+ </script>
310
+
311
+ <style scoped>
312
+ .app {
313
+ text-align: center;
314
+ padding: 2rem;
315
+ }
316
+
317
+ h1 {
318
+ color: #42b883;
319
+ }
320
+ </style>
321
+ `;
322
+ }
323
+ writeFile(path.join(targetDir, "src/App.lyt"), appLyt);
324
+ if (isRouter) {
325
+ const homePage = `<template>
326
+ <div class="home">
327
+ <h1>Home</h1>
328
+ ${isStore ? `
329
+ <p>Count: {{ count }}</p>
330
+ <button @click="increment">Increment</button>
331
+ <button @click="decrement">Decrement</button>
332
+ ` : ""}
333
+ <p>Welcome to the Home page!</p>
334
+ </div>
335
+ </template>
336
+
337
+ <script setup lang="ts">
338
+ ${isStore ? `import { useCounterStore } from '../stores/counter';
339
+ const counterStore = useCounterStore();
340
+ const { count, increment, decrement } = counterStore;
341
+ ` : ""}
342
+ </script>
343
+
344
+ <style scoped>
345
+ .home {
346
+ padding: 1rem;
347
+ }
348
+ </style>
349
+ `;
350
+ ensureDir(path.join(targetDir, "src", "pages"));
351
+ writeFile(path.join(targetDir, "src", "pages", "Home.lyt"), homePage);
352
+ const aboutPage = `<template>
353
+ <div class="about">
354
+ <h1>About</h1>
355
+ <p>This is the About page!</p>
356
+ </div>
357
+ </template>
358
+
359
+ <script setup lang="ts">
360
+ </script>
361
+
362
+ <style scoped>
363
+ .about {
364
+ padding: 1rem;
365
+ }
366
+ </style>
367
+ `;
368
+ writeFile(path.join(targetDir, "src", "pages", "About.lyt"), aboutPage);
369
+ }
370
+ if (isStore) {
371
+ const counterStore = `import { defineStore } from '@lytjs/store';
372
+ import { signal, computed } from '@lytjs/reactivity';
373
+
374
+ export const useCounterStore = defineStore('counter', () => {
375
+ // State
376
+ const count = signal(0);
377
+
378
+ // Getters
379
+ const doubleCount = computed(() => count.value * 2);
380
+
381
+ // Actions
382
+ function increment() {
383
+ count.value++;
384
+ }
385
+
386
+ function decrement() {
387
+ count.value--;
388
+ }
389
+
390
+ function reset() {
391
+ count.value = 0;
392
+ }
393
+
394
+ return {
395
+ count,
396
+ doubleCount,
397
+ increment,
398
+ decrement,
399
+ reset,
400
+ };
401
+ });
402
+ `;
403
+ ensureDir(path.join(targetDir, "src", "stores"));
404
+ writeFile(path.join(targetDir, "src", "stores", "counter.ts"), counterStore);
405
+ }
406
+ if (isSsr) {
407
+ const entryServer = `import { createSSRApp } from '@lytjs/core';
408
+ import App from './App.lyt';
409
+
410
+ export async function render(url: string) {
411
+ const app = createSSRApp(App);
412
+ return app;
413
+ }
414
+ `;
415
+ writeFile(path.join(targetDir, "src/entry-server.ts"), entryServer);
416
+ const entryClient = `import { createApp } from '@lytjs/core';
417
+ import App from './App.lyt';
418
+
419
+ const app = createApp(App);
420
+ app.mount('#app');
421
+ `;
422
+ writeFile(path.join(targetDir, "src/entry-client.ts"), entryClient);
423
+ const serverTs = `/**
424
+ * LytJS SSR Server
425
+ *
426
+ * A minimal SSR server for development and production.
427
+ */
428
+
429
+ import fs from 'fs';
430
+ import path from 'path';
431
+ import { fileURLToPath } from 'url';
432
+
433
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
434
+ const isProduction = process.env.NODE_ENV === 'production';
435
+
436
+ async function createServer() {
437
+ let resolve: any;
438
+ let vite: any;
439
+
440
+ if (!isProduction) {
441
+ const { createServer: createViteServer } = await import('vite');
442
+ vite = await createViteServer({
443
+ server: { middlewareMode: true },
444
+ appType: 'custom',
445
+ });
446
+ resolve = (id: string) => vite.resolveUrl(id);
447
+ } else {
448
+ resolve = (id: string) => id;
449
+ }
450
+
451
+ // TODO: Set up express/polka server and SSR rendering
452
+ console.log('LytJS SSR server starting...');
453
+ }
454
+
455
+ createServer();
456
+ `;
457
+ writeFile(path.join(targetDir, "server.ts"), serverTs);
458
+ }
459
+ const tsConfig = {
460
+ compilerOptions: {
461
+ target: "ES2020",
462
+ useDefineForClassFields: true,
463
+ module: "ESNext",
464
+ lib: ["ES2020", "DOM", "DOM.Iterable"],
465
+ skipLibCheck: true,
466
+ moduleResolution: "bundler",
467
+ allowImportingTsExtensions: true,
468
+ resolveJsonModule: true,
469
+ isolatedModules: true,
470
+ noEmit: true,
471
+ strict: true,
472
+ noUnusedLocals: true,
473
+ noUnusedParameters: true,
474
+ noFallthroughCasesInSwitch: true
475
+ },
476
+ include: ["src/**/*.ts", "src/**/*.lyt"],
477
+ references: [{ path: "./tsconfig.node.json" }]
478
+ };
479
+ writeFile(path.join(targetDir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
480
+ const tsConfigNode = {
481
+ compilerOptions: {
482
+ composite: true,
483
+ skipLibCheck: true,
484
+ module: "ESNext",
485
+ moduleResolution: "bundler",
486
+ allowSyntheticDefaultImports: true
487
+ },
488
+ include: ["vite.config.ts"]
489
+ };
490
+ writeFile(path.join(targetDir, "tsconfig.node.json"), JSON.stringify(tsConfigNode, null, 2));
491
+ const gitignore = `# Logs
492
+ logs
493
+ *.log
494
+ npm-debug.log*
495
+ yarn-debug.log*
496
+ yarn-error.log*
497
+ pnpm-debug.log*
498
+ lerna-debug.log*
499
+
500
+ node_modules
501
+ dist
502
+ dist-ssr
503
+ *.local
504
+
505
+ # Editor directories and files
506
+ .vscode/*
507
+ !.vscode/extensions.json
508
+ .idea
509
+ .DS_Store
510
+ *.suo
511
+ *.ntvs*
512
+ *.njsproj
513
+ *.sln
514
+ *.sw?
515
+ `;
516
+ writeFile(path.join(targetDir, ".gitignore"), gitignore);
517
+ }
518
+
519
+ // src/create.ts
520
+ create().catch(console.error);
521
+ //# sourceMappingURL=create.cjs.map
522
+ //# sourceMappingURL=create.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/logger.ts","../src/utils/fs.ts","../src/utils/package.ts","../src/commands/create.ts","../src/create.ts"],"names":["existsSync","mkdirSync","dirname","writeFileSync","readdirSync","join","execSync","resolve"],"mappings":"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","file":"create.cjs","sourcesContent":["/**\r\n * @lytjs/cli - Logger utilities\r\n */\r\n\r\nconst colors = {\r\n reset: '\\x1b[0m',\r\n bright: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n red: '\\x1b[31m',\r\n green: '\\x1b[32m',\r\n yellow: '\\x1b[33m',\r\n blue: '\\x1b[34m',\r\n cyan: '\\x1b[36m',\r\n};\r\n\r\nfunction colorize(text: string, color: keyof typeof colors): string {\r\n if (!isColorSupported()) return text;\r\n return `${colors[color]}${text}${colors.reset}`;\r\n}\r\n\r\nexport const logger = {\r\n info(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize('ℹ ', 'blue') + message);\r\n },\r\n \r\n success(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize('✔ ', 'green') + message);\r\n },\r\n \r\n warning(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize('⚠ ', 'yellow') + message);\r\n },\r\n \r\n error(message: string): void {\r\n console.error(colorize('✖ ', 'red') + message);\r\n },\r\n \r\n dim(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize(message, 'dim'));\r\n },\r\n \r\n bold(message: string): string {\r\n return colorize(message, 'bright');\r\n },\r\n};\r\n\r\n/**\r\n * Check if terminal supports colors\r\n */\r\nexport function isColorSupported(): boolean {\r\n return process.stdout.isTTY && process.env.NO_COLOR !== '1';\r\n}\r\n","/**\r\n * @lytjs/cli - File system utilities\r\n */\r\n\r\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';\r\nimport { join, dirname } from 'path';\r\n\r\n/**\r\n * Ensure directory exists (create if not)\r\n */\r\nexport function ensureDir(dir: string): void {\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n}\r\n\r\n/**\r\n * Write a file with content, creating parent directories if needed\r\n */\r\nexport function writeFile(filePath: string, content: string): void {\r\n ensureDir(dirname(filePath));\r\n writeFileSync(filePath, content, 'utf-8');\r\n}\r\n\r\n/**\r\n * Read a file as string\r\n */\r\nexport function readFile(filePath: string): string {\r\n return readFileSync(filePath, 'utf-8');\r\n}\r\n\r\n/**\r\n * Check if path exists\r\n */\r\nexport function exists(path: string): boolean {\r\n return existsSync(path);\r\n}\r\n\r\n/**\r\n * Copy directory recursively\r\n */\r\nexport function copyDir(src: string, dest: string): void {\r\n ensureDir(dest);\r\n const entries = readdirSync(src, { withFileTypes: true });\r\n \r\n for (const entry of entries) {\r\n const srcPath = join(src, entry.name);\r\n const destPath = join(dest, entry.name);\r\n \r\n if (entry.isDirectory()) {\r\n copyDir(srcPath, destPath);\r\n } else {\r\n writeFile(destPath, readFileSync(srcPath, 'utf-8'));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Check if directory is empty\r\n */\r\nexport function isEmptyDir(dir: string): boolean {\r\n if (!existsSync(dir)) return true;\r\n const files = readdirSync(dir);\r\n return files.length === 0;\r\n}\r\n","/**\r\n * @lytjs/cli - Package manager utilities\r\n */\r\n\r\nimport { execSync } from 'child_process';\r\nimport { existsSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm';\r\n\r\n/**\r\n * Detect which package manager to use\r\n */\r\nexport function detectPackageManager(cwd: string = process.cwd()): PackageManager {\r\n // Check for lock files\r\n if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\r\n if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\r\n if (existsSync(join(cwd, 'package-lock.json'))) return 'npm';\r\n \r\n // Default to pnpm if available\r\n try {\r\n execSync('pnpm --version', { stdio: 'ignore' });\r\n return 'pnpm';\r\n } catch {\r\n // Fall back to npm\r\n return 'npm';\r\n }\r\n}\r\n\r\n/**\r\n * Get install command for package manager\r\n */\r\nexport function getInstallCommand(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'pnpm': return 'pnpm install';\r\n case 'yarn': return 'yarn';\r\n case 'npm': return 'npm install';\r\n }\r\n}\r\n\r\n/**\r\n * Get run command for package manager\r\n */\r\nexport function getRunCommand(pm: PackageManager, script: string): string {\r\n switch (pm) {\r\n case 'pnpm': return `pnpm run ${script}`;\r\n case 'yarn': return `yarn ${script}`;\r\n case 'npm': return `npm run ${script}`;\r\n }\r\n}\r\n\r\n/**\r\n * Get add dependency command\r\n */\r\nexport function getAddCommand(pm: PackageManager, dep: string, dev: boolean = false): string {\r\n const devFlag = dev ? ' -D' : '';\r\n switch (pm) {\r\n case 'pnpm': return `pnpm add${devFlag} ${dep}`;\r\n case 'yarn': return `yarn add${devFlag} ${dep}`;\r\n case 'npm': return `npm install${devFlag} ${dep}`;\r\n }\r\n}\r\n","/**\r\n * @lytjs/cli - create command\r\n *\r\n * Creates a new LytJS project from a template.\r\n */\r\n\r\nimport type { CreateOptions } from '../types';\r\nimport { logger } from '../utils/logger';\r\nimport { ensureDir, writeFile, exists, isEmptyDir } from '../utils/fs';\r\nimport { detectPackageManager, getInstallCommand } from '../utils/package';\r\nimport { join, resolve } from 'path';\r\nimport { execSync } from 'child_process';\r\n\r\nconst TEMPLATES = {\r\n default: 'Default template with TypeScript and Vite',\r\n minimal: 'Minimal template without extra dependencies',\r\n ssr: 'SSR-enabled template',\r\n router: 'Template with Router integration',\r\n store: 'Template with Store integration',\r\n full: 'Full-featured template with Router, Store, and UI components',\r\n};\r\n\r\n/**\r\n * Create a new LytJS project\r\n */\r\nexport async function create(projectName?: string, options: Partial<CreateOptions> = {}): Promise<void> {\n if (!projectName) {\n logger.error('Please provide a project name.');\n logger.info('Usage: lyt create <project-name>');\n process.exit(1);\n }\r\n const targetDir = resolve(process.cwd(), projectName);\r\n \r\n // Check if directory exists and is not empty\r\n if (exists(targetDir) && !isEmptyDir(targetDir) && !options.force) {\r\n logger.error(`Directory \"${projectName}\" already exists and is not empty.`);\r\n logger.info('Use --force to overwrite.');\r\n process.exit(1);\r\n }\r\n \r\n logger.info(`Creating a new LytJS project in ${targetDir}...`);\r\n \r\n // Create directory\r\n ensureDir(targetDir);\r\n \r\n // Generate project files\r\n generateProjectFiles(targetDir, projectName, options.template || 'default');\r\n \r\n // Install dependencies\r\n logger.info('Installing dependencies...');\r\n const pm = detectPackageManager();\r\n try {\r\n execSync(getInstallCommand(pm), { cwd: targetDir, stdio: 'inherit' });\r\n logger.success('Dependencies installed successfully!');\r\n } catch (_error) {\r\n logger.warning('Failed to install dependencies automatically.');\r\n logger.info(`Please run \"${getInstallCommand(pm)}\" manually.`);\r\n }\r\n \r\n // Print next steps\r\n logger.success(`Project \"${projectName}\" created successfully!`);\r\n logger.info('');\r\n logger.bold('Next steps:');\r\n logger.info(` cd ${projectName}`);\r\n logger.info(` ${pm === 'npm' ? 'npm run' : pm} dev`);\r\n}\r\n\r\n/**\r\n * Generate project files\r\n */\r\nfunction generateProjectFiles(targetDir: string, projectName: string, template: string): void {\r\n // Determine template-specific settings\r\n const isMinimal = template === 'minimal';\r\n const isSsr = template === 'ssr';\r\n const isRouter = template === 'router' || template === 'full';\r\n const isStore = template === 'store' || template === 'full';\r\n const isFull = template === 'full';\r\n\r\n // package.json - use explicit type to allow property access\r\n interface PackageJsonTemplate {\r\n name: string;\r\n version: string;\r\n type: string;\r\n scripts: Record<string, string>;\r\n dependencies: Record<string, string>;\r\n devDependencies: Record<string, string>;\r\n }\r\n\r\n const packageJson: PackageJsonTemplate = {\r\n name: projectName,\r\n version: '0.0.0',\r\n type: 'module',\r\n scripts: {\r\n dev: 'vite',\r\n build: 'vite build',\r\n preview: 'vite preview',\r\n },\r\n dependencies: {\r\n '@lytjs/core': '^6.0.0',\r\n },\r\n devDependencies: {\r\n '@lytjs/plugin-vite': '^6.0.0',\r\n 'vite': '^5.0.0',\r\n },\r\n };\r\n\r\n // Minimal template: no vitest, no test script\r\n if (!isMinimal) {\r\n packageJson.scripts.test = 'vitest';\r\n packageJson.devDependencies.vitest = '^1.0.0';\r\n }\r\n\r\n // SSR template: add @lytjs/server dependency\r\n if (isSsr) {\r\n packageJson.dependencies['@lytjs/server'] = '^6.0.0';\r\n packageJson.scripts['build:client'] = 'vite build --ssrManifest';\r\n packageJson.scripts['build:server'] = 'vite build --ssr src/entry-server.ts';\r\n packageJson.scripts['build'] = 'npm run build:client && npm run build:server';\r\n packageJson.scripts['preview'] = 'node server';\r\n }\r\n\r\n // Router template: add @lytjs/router\r\n if (isRouter) {\r\n packageJson.dependencies['@lytjs/router'] = '^1.0.0';\r\n }\r\n\r\n // Store template: add @lytjs/store\r\n if (isStore) {\r\n packageJson.dependencies['@lytjs/store'] = '^1.0.0';\r\n }\r\n\r\n // Full template: add @lytjs/ui\r\n if (isFull) {\r\n packageJson.dependencies['@lytjs/ui'] = '^0.4.0';\r\n }\r\n\r\n writeFile(join(targetDir, 'package.json'), JSON.stringify(packageJson, null, 2));\r\n\r\n // vite.config.ts\r\n let viteConfig: string;\r\n if (isSsr) {\r\n viteConfig = `import { defineConfig } from 'vite';\r\nimport lytjs from '@lytjs/plugin-vite';\r\n\r\nexport default defineConfig({\r\n plugins: [lytjs()],\r\n build: {\r\n ssrManifest: true,\r\n },\r\n});\r\n`;\r\n } else {\r\n viteConfig = `import { defineConfig } from 'vite';\r\nimport lytjs from '@lytjs/plugin-vite';\r\n\r\nexport default defineConfig({\r\n plugins: [lytjs()],\r\n});\r\n`;\r\n }\r\n writeFile(join(targetDir, 'vite.config.ts'), viteConfig);\r\n\r\n // index.html\r\n const indexHtml = `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <title>${projectName}</title>\r\n </head>\r\n <body>\r\n <div id=\"app\"></div>\r\n <script type=\"module\" src=\"/src/main.ts\"></script>\r\n </body>\r\n</html>\r\n`;\r\n writeFile(join(targetDir, 'index.html'), indexHtml);\r\n\r\n // src/main.ts\r\n let mainTs: string;\r\n if (isSsr) {\r\n mainTs = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\nimport { createSSRApp } from '@lytjs/server';\r\n${isRouter ? \"import { createRouter, createWebHistory } from '@lytjs/router';\" : ''}\r\n${isStore ? \"import { createPinia } from '@lytjs/store';\" : ''}\r\n\r\nconst app = createSSRApp(App);\r\n${isStore ? 'app.use(createPinia());' : ''}\r\n${isRouter ? `\r\nconst router = createRouter({\r\n history: createWebHistory(),\r\n routes: [\r\n { path: '/', component: () => import('./pages/Home.lyt') },\r\n { path: '/about', component: () => import('./pages/About.lyt') },\r\n ],\r\n});\r\napp.use(router);\r\n` : ''}\r\napp.mount('#app');\r\n`;\r\n } else if (isRouter || isStore) {\r\n mainTs = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n${isRouter ? \"import { createRouter, createWebHistory } from '@lytjs/router';\" : ''}\r\n${isStore ? \"import { createPinia } from '@lytjs/store';\" : ''}\r\n\r\nconst app = createApp(App);\r\n${isStore ? 'app.use(createPinia());' : ''}\r\n${isRouter ? `\r\nconst router = createRouter({\r\n history: createWebHistory(),\r\n routes: [\r\n { path: '/', component: () => import('./pages/Home.lyt') },\r\n { path: '/about', component: () => import('./pages/About.lyt') },\r\n ],\r\n});\r\napp.use(router);\r\n` : ''}\r\napp.mount('#app');\r\n`;\r\n } else {\r\n mainTs = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n\r\ncreateApp(App).mount('#app');\r\n`;\r\n }\r\n writeFile(join(targetDir, 'src/main.ts'), mainTs);\r\n\r\n // src/App.lyt\r\n let appLyt: string;\r\n if (isMinimal) {\r\n appLyt = `<template>\r\n <div class=\"app\">\r\n <h1>{{ title }}</h1>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nconst title = 'Hello LytJS!';\r\n</script>\r\n\r\n<style scoped>\r\n.app {\r\n text-align: center;\r\n}\r\n</style>\r\n`;\r\n } else if (isRouter) {\r\n appLyt = `<template>\r\n <div class=\"app\">\r\n <nav class=\"nav\">\r\n <router-link to=\"/\">Home</router-link>\r\n <router-link to=\"/about\">About</router-link>\r\n </nav>\r\n <router-view />\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { RouterLink, RouterView } from '@lytjs/router';\r\n</script>\r\n\r\n<style scoped>\r\n.app {\r\n text-align: center;\r\n padding: 2rem;\r\n}\r\n\r\n.nav {\r\n margin-bottom: 2rem;\r\n}\r\n\r\n.nav a {\r\n margin: 0 1rem;\r\n color: #42b883;\r\n text-decoration: none;\r\n}\r\n\r\n.nav a:hover {\r\n text-decoration: underline;\r\n}\r\n</style>\r\n`;\r\n } else {\r\n appLyt = `<template>\r\n <div class=\"app\">\r\n <h1>{{ title }}</h1>\r\n <p>Welcome to your LytJS app!</p>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nconst title = 'Hello LytJS!';\r\n</script>\r\n\r\n<style scoped>\r\n.app {\r\n text-align: center;\r\n padding: 2rem;\r\n}\r\n\r\nh1 {\r\n color: #42b883;\r\n}\r\n</style>\r\n`;\r\n }\r\n writeFile(join(targetDir, 'src/App.lyt'), appLyt);\r\n\r\n // Router template: add pages and store\r\n if (isRouter) {\r\n // Home page\r\n const homePage = `<template>\r\n <div class=\"home\">\r\n <h1>Home</h1>\r\n ${isStore ? `\r\n <p>Count: {{ count }}</p>\r\n <button @click=\"increment\">Increment</button>\r\n <button @click=\"decrement\">Decrement</button>\r\n ` : ''}\r\n <p>Welcome to the Home page!</p>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n${isStore ? `import { useCounterStore } from '../stores/counter';\r\nconst counterStore = useCounterStore();\r\nconst { count, increment, decrement } = counterStore;\r\n` : ''}\r\n</script>\r\n\r\n<style scoped>\r\n.home {\r\n padding: 1rem;\r\n}\r\n</style>\r\n`;\r\n ensureDir(join(targetDir, 'src', 'pages'));\r\n writeFile(join(targetDir, 'src', 'pages', 'Home.lyt'), homePage);\r\n\r\n // About page\r\n const aboutPage = `<template>\r\n <div class=\"about\">\r\n <h1>About</h1>\r\n <p>This is the About page!</p>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n</script>\r\n\r\n<style scoped>\r\n.about {\r\n padding: 1rem;\r\n}\r\n</style>\r\n`;\r\n writeFile(join(targetDir, 'src', 'pages', 'About.lyt'), aboutPage);\r\n }\r\n\r\n // Store template: add example store\r\n if (isStore) {\r\n const counterStore = `import { defineStore } from '@lytjs/store';\r\nimport { signal, computed } from '@lytjs/reactivity';\r\n\r\nexport const useCounterStore = defineStore('counter', () => {\r\n // State\r\n const count = signal(0);\r\n\r\n // Getters\r\n const doubleCount = computed(() => count.value * 2);\r\n\r\n // Actions\r\n function increment() {\r\n count.value++;\r\n }\r\n\r\n function decrement() {\r\n count.value--;\r\n }\r\n\r\n function reset() {\r\n count.value = 0;\r\n }\r\n\r\n return {\r\n count,\r\n doubleCount,\r\n increment,\r\n decrement,\r\n reset,\r\n };\r\n});\r\n`;\r\n ensureDir(join(targetDir, 'src', 'stores'));\r\n writeFile(join(targetDir, 'src', 'stores', 'counter.ts'), counterStore);\r\n }\r\n\r\n // SSR-specific files\r\n if (isSsr) {\r\n // src/entry-server.ts\r\n const entryServer = `import { createSSRApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n\r\nexport async function render(url: string) {\r\n const app = createSSRApp(App);\r\n return app;\r\n}\r\n`;\r\n writeFile(join(targetDir, 'src/entry-server.ts'), entryServer);\r\n\r\n // src/entry-client.ts\r\n const entryClient = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n\r\nconst app = createApp(App);\r\napp.mount('#app');\r\n`;\r\n writeFile(join(targetDir, 'src/entry-client.ts'), entryClient);\r\n\r\n // server.ts\r\n const serverTs = `/**\r\n * LytJS SSR Server\r\n *\r\n * A minimal SSR server for development and production.\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\n\r\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\r\nconst isProduction = process.env.NODE_ENV === 'production';\r\n\r\nasync function createServer() {\r\n let resolve: any;\r\n let vite: any;\r\n\r\n if (!isProduction) {\r\n const { createServer: createViteServer } = await import('vite');\r\n vite = await createViteServer({\r\n server: { middlewareMode: true },\r\n appType: 'custom',\r\n });\r\n resolve = (id: string) => vite.resolveUrl(id);\r\n } else {\r\n resolve = (id: string) => id;\r\n }\r\n\r\n // TODO: Set up express/polka server and SSR rendering\r\n console.log('LytJS SSR server starting...');\r\n}\r\n\r\ncreateServer();\r\n`;\r\n writeFile(join(targetDir, 'server.ts'), serverTs);\r\n }\r\n\r\n // tsconfig.json\r\n const tsConfig = {\r\n compilerOptions: {\r\n target: 'ES2020',\r\n useDefineForClassFields: true,\r\n module: 'ESNext',\r\n lib: ['ES2020', 'DOM', 'DOM.Iterable'],\r\n skipLibCheck: true,\r\n moduleResolution: 'bundler',\r\n allowImportingTsExtensions: true,\r\n resolveJsonModule: true,\r\n isolatedModules: true,\r\n noEmit: true,\r\n strict: true,\r\n noUnusedLocals: true,\r\n noUnusedParameters: true,\r\n noFallthroughCasesInSwitch: true,\r\n },\r\n include: ['src/**/*.ts', 'src/**/*.lyt'],\r\n references: [{ path: './tsconfig.node.json' }],\r\n };\r\n writeFile(join(targetDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));\r\n\r\n // tsconfig.node.json\r\n const tsConfigNode = {\r\n compilerOptions: {\r\n composite: true,\r\n skipLibCheck: true,\r\n module: 'ESNext',\r\n moduleResolution: 'bundler',\r\n allowSyntheticDefaultImports: true,\r\n },\r\n include: ['vite.config.ts'],\r\n };\r\n writeFile(join(targetDir, 'tsconfig.node.json'), JSON.stringify(tsConfigNode, null, 2));\r\n\r\n // .gitignore\r\n const gitignore = `# Logs\r\nlogs\r\n*.log\r\nnpm-debug.log*\r\nyarn-debug.log*\r\nyarn-error.log*\r\npnpm-debug.log*\r\nlerna-debug.log*\r\n\r\nnode_modules\r\ndist\r\ndist-ssr\r\n*.local\r\n\r\n# Editor directories and files\r\n.vscode/*\r\n!.vscode/extensions.json\r\n.idea\r\n.DS_Store\r\n*.suo\r\n*.ntvs*\r\n*.njsproj\r\n*.sln\r\n*.sw?\r\n`;\r\n writeFile(join(targetDir, '.gitignore'), gitignore);\r\n}\r\n\r\n/**\r\n * List available templates\r\n */\r\nexport function listTemplates(): void {\r\n logger.bold('Available templates:');\r\n for (const [name, description] of Object.entries(TEMPLATES)) {\r\n logger.info(` ${name.padEnd(10)} - ${description}`);\r\n }\r\n}\r\n","import { create } from './commands/create';\n\ncreate().catch(console.error);"]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }