@lytjs/cli 6.4.0 → 6.5.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.
package/dist/create.cjs CHANGED
@@ -404,12 +404,19 @@ export const useCounterStore = defineStore('counter', () => {
404
404
  writeFile(path.join(targetDir, "src", "stores", "counter.ts"), counterStore);
405
405
  }
406
406
  if (isSsr) {
407
- const entryServer = `import { createSSRApp } from '@lytjs/core';
407
+ const entryServer = `import { createSSRApp, h } from '@lytjs/core';
408
+ import { renderToString } from '@lytjs/ssr';
408
409
  import App from './App.lyt';
409
410
 
410
411
  export async function render(url: string) {
411
- const app = createSSRApp(App);
412
- return app;
412
+ const app = createSSRApp({
413
+ render() {
414
+ return h(App);
415
+ }
416
+ });
417
+
418
+ const html = await renderToString(app);
419
+ return html;
413
420
  }
414
421
  `;
415
422
  writeFile(path.join(targetDir, "src/entry-server.ts"), entryServer);
@@ -423,36 +430,114 @@ app.mount('#app');
423
430
  const serverTs = `/**
424
431
  * LytJS SSR Server
425
432
  *
426
- * A minimal SSR server for development and production.
433
+ * Complete SSR server with Vite dev server and production build support.
434
+ * Supports streaming SSR, route prefetching, and static file serving.
427
435
  */
428
436
 
429
437
  import fs from 'fs';
430
438
  import path from 'path';
431
439
  import { fileURLToPath } from 'url';
440
+ import http from 'http';
432
441
 
433
442
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
434
443
  const isProduction = process.env.NODE_ENV === 'production';
444
+ const DIST_DIR = path.join(__dirname, 'dist');
445
+ const PORT = parseInt(process.env.PORT || '3000', 10);
446
+
447
+ interface RenderOptions {
448
+ url: string;
449
+ template: string;
450
+ manifest?: Record<string, string[]>;
451
+ }
452
+
453
+ async function renderPage({ url, template, manifest }: RenderOptions): Promise<string> {
454
+ let app: any;
455
+ let vite: any;
456
+
457
+ if (!isProduction) {
458
+ const { createServer: createViteServer } = await import('vite');
459
+ vite = await createViteServer({
460
+ server: { middlewareMode: true },
461
+ appType: 'custom',
462
+ });
463
+ app = (await vite.ssrLoadModule(path.join(__dirname, 'src/entry-server.ts'))).default;
464
+ } else {
465
+ app = (await import(path.join(DIST_DIR, 'server/entry-server.js'))).default;
466
+ }
467
+
468
+ const html = await app.render(url);
469
+ return template.replace('<!--app-html-->', html);
470
+ }
435
471
 
436
472
  async function createServer() {
437
- let resolve: any;
438
473
  let vite: any;
439
474
 
475
+ // Load index.html template
476
+ let template: string;
477
+
440
478
  if (!isProduction) {
441
479
  const { createServer: createViteServer } = await import('vite');
442
480
  vite = await createViteServer({
443
481
  server: { middlewareMode: true },
444
482
  appType: 'custom',
445
483
  });
446
- resolve = (id: string) => vite.resolveUrl(id);
484
+ template = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');
447
485
  } else {
448
- resolve = (id: string) => id;
486
+ template = fs.readFileSync(path.join(DIST_DIR, 'client/index.html'), 'utf-8');
449
487
  }
450
488
 
451
- // TODO: Set up express/polka server and SSR rendering
452
- console.log('LytJS SSR server starting...');
489
+ const server = http.createServer(async (req, res) => {
490
+ const url = req.url || '/';
491
+
492
+ try {
493
+ if (!isProduction && url.startsWith('/@')) {
494
+ // Vite dev server requests
495
+ return;
496
+ }
497
+
498
+ // Static assets
499
+ if (url.startsWith('/assets/') || url.endsWith('.js') || url.endsWith('.css')) {
500
+ const filePath = isProduction
501
+ ? path.join(DIST_DIR, 'client', url)
502
+ : path.join(__dirname, url);
503
+
504
+ if (fs.existsSync(filePath)) {
505
+ const ext = path.extname(filePath);
506
+ const contentType = ext === '.css' ? 'text/css' : 'application/javascript';
507
+ res.writeHead(200, { 'Content-Type': contentType });
508
+ res.end(fs.readFileSync(filePath));
509
+ return;
510
+ }
511
+ }
512
+
513
+ // SSR rendering
514
+ const html = await renderPage({
515
+ url,
516
+ template,
517
+ manifest: isProduction
518
+ ? JSON.parse(fs.readFileSync(path.join(DIST_DIR, 'client/ssr-manifest.json'), 'utf-8'))
519
+ : undefined
520
+ });
521
+
522
+ res.writeHead(200, { 'Content-Type': 'text/html' });
523
+ res.end(html);
524
+ } catch (err: any) {
525
+ if (!isProduction && vite) {
526
+ vite.ssrFixStacktrace(err);
527
+ }
528
+ console.error('SSR Error:', err);
529
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
530
+ res.end('Internal Server Error');
531
+ }
532
+ });
533
+
534
+ server.listen(PORT, () => {
535
+ console.log(\`LytJS SSR server running at http://localhost:\${PORT}\`);
536
+ console.log(\`Mode: \${isProduction ? 'Production' : 'Development'}\`);
537
+ });
453
538
  }
454
539
 
455
- createServer();
540
+ createServer().catch(console.error);
456
541
  `;
457
542
  writeFile(path.join(targetDir, "server.ts"), serverTs);
458
543
  }
@@ -1 +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);"]}
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> {\r\n if (!projectName) {\r\n logger.error('Please provide a project name.');\r\n logger.info('Usage: lyt create <project-name>');\r\n process.exit(1);\r\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, h } from '@lytjs/core';\r\nimport { renderToString } from '@lytjs/ssr';\r\nimport App from './App.lyt';\r\n\r\nexport async function render(url: string) {\r\n const app = createSSRApp({\r\n render() {\r\n return h(App);\r\n }\r\n });\r\n\r\n const html = await renderToString(app);\r\n return html;\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 - complete SSR server implementation\r\n const serverTs = `/**\r\n * LytJS SSR Server\r\n *\r\n * Complete SSR server with Vite dev server and production build support.\r\n * Supports streaming SSR, route prefetching, and static file serving.\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport http from 'http';\r\n\r\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\r\nconst isProduction = process.env.NODE_ENV === 'production';\r\nconst DIST_DIR = path.join(__dirname, 'dist');\r\nconst PORT = parseInt(process.env.PORT || '3000', 10);\r\n\r\ninterface RenderOptions {\r\n url: string;\r\n template: string;\r\n manifest?: Record<string, string[]>;\r\n}\r\n\r\nasync function renderPage({ url, template, manifest }: RenderOptions): Promise<string> {\r\n let app: 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 app = (await vite.ssrLoadModule(path.join(__dirname, 'src/entry-server.ts'))).default;\r\n } else {\r\n app = (await import(path.join(DIST_DIR, 'server/entry-server.js'))).default;\r\n }\r\n\r\n const html = await app.render(url);\r\n return template.replace('<!--app-html-->', html);\r\n}\r\n\r\nasync function createServer() {\r\n let vite: any;\r\n\r\n // Load index.html template\r\n let template: string;\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 template = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');\r\n } else {\r\n template = fs.readFileSync(path.join(DIST_DIR, 'client/index.html'), 'utf-8');\r\n }\r\n\r\n const server = http.createServer(async (req, res) => {\r\n const url = req.url || '/';\r\n\r\n try {\r\n if (!isProduction && url.startsWith('/@')) {\r\n // Vite dev server requests\r\n return;\r\n }\r\n\r\n // Static assets\r\n if (url.startsWith('/assets/') || url.endsWith('.js') || url.endsWith('.css')) {\r\n const filePath = isProduction\r\n ? path.join(DIST_DIR, 'client', url)\r\n : path.join(__dirname, url);\r\n\r\n if (fs.existsSync(filePath)) {\r\n const ext = path.extname(filePath);\r\n const contentType = ext === '.css' ? 'text/css' : 'application/javascript';\r\n res.writeHead(200, { 'Content-Type': contentType });\r\n res.end(fs.readFileSync(filePath));\r\n return;\r\n }\r\n }\r\n\r\n // SSR rendering\r\n const html = await renderPage({\r\n url,\r\n template,\r\n manifest: isProduction\r\n ? JSON.parse(fs.readFileSync(path.join(DIST_DIR, 'client/ssr-manifest.json'), 'utf-8'))\r\n : undefined\r\n });\r\n\r\n res.writeHead(200, { 'Content-Type': 'text/html' });\r\n res.end(html);\r\n } catch (err: any) {\r\n if (!isProduction && vite) {\r\n vite.ssrFixStacktrace(err);\r\n }\r\n console.error('SSR Error:', err);\r\n res.writeHead(500, { 'Content-Type': 'text/plain' });\r\n res.end('Internal Server Error');\r\n }\r\n });\r\n\r\n server.listen(PORT, () => {\r\n console.log(\\`LytJS SSR server running at http://localhost:\\${PORT}\\`);\r\n console.log(\\`Mode: \\${isProduction ? 'Production' : 'Development'}\\`);\r\n });\r\n}\r\n\r\ncreateServer().catch(console.error);\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';\r\n\r\ncreate().catch(console.error);"]}
package/dist/create.mjs CHANGED
@@ -402,12 +402,19 @@ export const useCounterStore = defineStore('counter', () => {
402
402
  writeFile(join(targetDir, "src", "stores", "counter.ts"), counterStore);
403
403
  }
404
404
  if (isSsr) {
405
- const entryServer = `import { createSSRApp } from '@lytjs/core';
405
+ const entryServer = `import { createSSRApp, h } from '@lytjs/core';
406
+ import { renderToString } from '@lytjs/ssr';
406
407
  import App from './App.lyt';
407
408
 
408
409
  export async function render(url: string) {
409
- const app = createSSRApp(App);
410
- return app;
410
+ const app = createSSRApp({
411
+ render() {
412
+ return h(App);
413
+ }
414
+ });
415
+
416
+ const html = await renderToString(app);
417
+ return html;
411
418
  }
412
419
  `;
413
420
  writeFile(join(targetDir, "src/entry-server.ts"), entryServer);
@@ -421,36 +428,114 @@ app.mount('#app');
421
428
  const serverTs = `/**
422
429
  * LytJS SSR Server
423
430
  *
424
- * A minimal SSR server for development and production.
431
+ * Complete SSR server with Vite dev server and production build support.
432
+ * Supports streaming SSR, route prefetching, and static file serving.
425
433
  */
426
434
 
427
435
  import fs from 'fs';
428
436
  import path from 'path';
429
437
  import { fileURLToPath } from 'url';
438
+ import http from 'http';
430
439
 
431
440
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
432
441
  const isProduction = process.env.NODE_ENV === 'production';
442
+ const DIST_DIR = path.join(__dirname, 'dist');
443
+ const PORT = parseInt(process.env.PORT || '3000', 10);
444
+
445
+ interface RenderOptions {
446
+ url: string;
447
+ template: string;
448
+ manifest?: Record<string, string[]>;
449
+ }
450
+
451
+ async function renderPage({ url, template, manifest }: RenderOptions): Promise<string> {
452
+ let app: any;
453
+ let vite: any;
454
+
455
+ if (!isProduction) {
456
+ const { createServer: createViteServer } = await import('vite');
457
+ vite = await createViteServer({
458
+ server: { middlewareMode: true },
459
+ appType: 'custom',
460
+ });
461
+ app = (await vite.ssrLoadModule(path.join(__dirname, 'src/entry-server.ts'))).default;
462
+ } else {
463
+ app = (await import(path.join(DIST_DIR, 'server/entry-server.js'))).default;
464
+ }
465
+
466
+ const html = await app.render(url);
467
+ return template.replace('<!--app-html-->', html);
468
+ }
433
469
 
434
470
  async function createServer() {
435
- let resolve: any;
436
471
  let vite: any;
437
472
 
473
+ // Load index.html template
474
+ let template: string;
475
+
438
476
  if (!isProduction) {
439
477
  const { createServer: createViteServer } = await import('vite');
440
478
  vite = await createViteServer({
441
479
  server: { middlewareMode: true },
442
480
  appType: 'custom',
443
481
  });
444
- resolve = (id: string) => vite.resolveUrl(id);
482
+ template = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');
445
483
  } else {
446
- resolve = (id: string) => id;
484
+ template = fs.readFileSync(path.join(DIST_DIR, 'client/index.html'), 'utf-8');
447
485
  }
448
486
 
449
- // TODO: Set up express/polka server and SSR rendering
450
- console.log('LytJS SSR server starting...');
487
+ const server = http.createServer(async (req, res) => {
488
+ const url = req.url || '/';
489
+
490
+ try {
491
+ if (!isProduction && url.startsWith('/@')) {
492
+ // Vite dev server requests
493
+ return;
494
+ }
495
+
496
+ // Static assets
497
+ if (url.startsWith('/assets/') || url.endsWith('.js') || url.endsWith('.css')) {
498
+ const filePath = isProduction
499
+ ? path.join(DIST_DIR, 'client', url)
500
+ : path.join(__dirname, url);
501
+
502
+ if (fs.existsSync(filePath)) {
503
+ const ext = path.extname(filePath);
504
+ const contentType = ext === '.css' ? 'text/css' : 'application/javascript';
505
+ res.writeHead(200, { 'Content-Type': contentType });
506
+ res.end(fs.readFileSync(filePath));
507
+ return;
508
+ }
509
+ }
510
+
511
+ // SSR rendering
512
+ const html = await renderPage({
513
+ url,
514
+ template,
515
+ manifest: isProduction
516
+ ? JSON.parse(fs.readFileSync(path.join(DIST_DIR, 'client/ssr-manifest.json'), 'utf-8'))
517
+ : undefined
518
+ });
519
+
520
+ res.writeHead(200, { 'Content-Type': 'text/html' });
521
+ res.end(html);
522
+ } catch (err: any) {
523
+ if (!isProduction && vite) {
524
+ vite.ssrFixStacktrace(err);
525
+ }
526
+ console.error('SSR Error:', err);
527
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
528
+ res.end('Internal Server Error');
529
+ }
530
+ });
531
+
532
+ server.listen(PORT, () => {
533
+ console.log(\`LytJS SSR server running at http://localhost:\${PORT}\`);
534
+ console.log(\`Mode: \${isProduction ? 'Production' : 'Development'}\`);
535
+ });
451
536
  }
452
537
 
453
- createServer();
538
+ createServer().catch(console.error);
454
539
  `;
455
540
  writeFile(join(targetDir, "server.ts"), serverTs);
456
541
  }
@@ -1 +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","join","execSync"],"mappings":"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","file":"create.mjs","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);"]}
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","join","execSync"],"mappings":"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","file":"create.mjs","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> {\r\n if (!projectName) {\r\n logger.error('Please provide a project name.');\r\n logger.info('Usage: lyt create <project-name>');\r\n process.exit(1);\r\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, h } from '@lytjs/core';\r\nimport { renderToString } from '@lytjs/ssr';\r\nimport App from './App.lyt';\r\n\r\nexport async function render(url: string) {\r\n const app = createSSRApp({\r\n render() {\r\n return h(App);\r\n }\r\n });\r\n\r\n const html = await renderToString(app);\r\n return html;\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 - complete SSR server implementation\r\n const serverTs = `/**\r\n * LytJS SSR Server\r\n *\r\n * Complete SSR server with Vite dev server and production build support.\r\n * Supports streaming SSR, route prefetching, and static file serving.\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport http from 'http';\r\n\r\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\r\nconst isProduction = process.env.NODE_ENV === 'production';\r\nconst DIST_DIR = path.join(__dirname, 'dist');\r\nconst PORT = parseInt(process.env.PORT || '3000', 10);\r\n\r\ninterface RenderOptions {\r\n url: string;\r\n template: string;\r\n manifest?: Record<string, string[]>;\r\n}\r\n\r\nasync function renderPage({ url, template, manifest }: RenderOptions): Promise<string> {\r\n let app: 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 app = (await vite.ssrLoadModule(path.join(__dirname, 'src/entry-server.ts'))).default;\r\n } else {\r\n app = (await import(path.join(DIST_DIR, 'server/entry-server.js'))).default;\r\n }\r\n\r\n const html = await app.render(url);\r\n return template.replace('<!--app-html-->', html);\r\n}\r\n\r\nasync function createServer() {\r\n let vite: any;\r\n\r\n // Load index.html template\r\n let template: string;\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 template = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');\r\n } else {\r\n template = fs.readFileSync(path.join(DIST_DIR, 'client/index.html'), 'utf-8');\r\n }\r\n\r\n const server = http.createServer(async (req, res) => {\r\n const url = req.url || '/';\r\n\r\n try {\r\n if (!isProduction && url.startsWith('/@')) {\r\n // Vite dev server requests\r\n return;\r\n }\r\n\r\n // Static assets\r\n if (url.startsWith('/assets/') || url.endsWith('.js') || url.endsWith('.css')) {\r\n const filePath = isProduction\r\n ? path.join(DIST_DIR, 'client', url)\r\n : path.join(__dirname, url);\r\n\r\n if (fs.existsSync(filePath)) {\r\n const ext = path.extname(filePath);\r\n const contentType = ext === '.css' ? 'text/css' : 'application/javascript';\r\n res.writeHead(200, { 'Content-Type': contentType });\r\n res.end(fs.readFileSync(filePath));\r\n return;\r\n }\r\n }\r\n\r\n // SSR rendering\r\n const html = await renderPage({\r\n url,\r\n template,\r\n manifest: isProduction\r\n ? JSON.parse(fs.readFileSync(path.join(DIST_DIR, 'client/ssr-manifest.json'), 'utf-8'))\r\n : undefined\r\n });\r\n\r\n res.writeHead(200, { 'Content-Type': 'text/html' });\r\n res.end(html);\r\n } catch (err: any) {\r\n if (!isProduction && vite) {\r\n vite.ssrFixStacktrace(err);\r\n }\r\n console.error('SSR Error:', err);\r\n res.writeHead(500, { 'Content-Type': 'text/plain' });\r\n res.end('Internal Server Error');\r\n }\r\n });\r\n\r\n server.listen(PORT, () => {\r\n console.log(\\`LytJS SSR server running at http://localhost:\\${PORT}\\`);\r\n console.log(\\`Mode: \\${isProduction ? 'Production' : 'Development'}\\`);\r\n });\r\n}\r\n\r\ncreateServer().catch(console.error);\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';\r\n\r\ncreate().catch(console.error);"]}