@lytjs/cli 5.0.4 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/create.cjs +522 -0
  2. package/dist/create.cjs.map +1 -0
  3. package/dist/create.d.mts +2 -0
  4. package/dist/create.d.ts +2 -0
  5. package/dist/create.mjs +520 -0
  6. package/dist/create.mjs.map +1 -0
  7. package/dist/index.cjs +1363 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.mts +188 -0
  10. package/dist/index.d.ts +188 -0
  11. package/dist/index.mjs +1219 -935
  12. package/dist/index.mjs.map +1 -0
  13. package/dist/lyt.cjs +1363 -0
  14. package/dist/lyt.cjs.map +1 -0
  15. package/dist/lyt.d.mts +1 -0
  16. package/dist/lyt.d.ts +1 -0
  17. package/dist/lyt.mjs +1342 -0
  18. package/dist/lyt.mjs.map +1 -0
  19. package/lyt-cli.js +3 -0
  20. package/package.json +34 -31
  21. package/README.md +0 -227
  22. package/dist/bin/cli.cjs +0 -2
  23. package/dist/bin/cli.js +0 -2
  24. package/dist/bin/cli.mjs +0 -1
  25. package/dist/index.js +0 -1058
  26. package/dist/types/bin/cli.d.ts +0 -9
  27. package/dist/types/bin/cli.d.ts.map +0 -1
  28. package/dist/types/build.d.ts +0 -30
  29. package/dist/types/build.d.ts.map +0 -1
  30. package/dist/types/create.d.ts +0 -19
  31. package/dist/types/create.d.ts.map +0 -1
  32. package/dist/types/dev.d.ts +0 -24
  33. package/dist/types/dev.d.ts.map +0 -1
  34. package/dist/types/generate.d.ts +0 -14
  35. package/dist/types/generate.d.ts.map +0 -1
  36. package/dist/types/hmr.d.ts +0 -55
  37. package/dist/types/hmr.d.ts.map +0 -1
  38. package/dist/types/index.d.ts +0 -20
  39. package/dist/types/index.d.ts.map +0 -1
  40. package/dist/types/scaffold.d.ts +0 -67
  41. package/dist/types/scaffold.d.ts.map +0 -1
  42. package/dist/types/utils.d.ts +0 -92
  43. package/dist/types/utils.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,1058 +1,1342 @@
1
1
  #!/usr/bin/env node
2
- import*as ie from"fs";import*as ae from"path";import*as v from"fs";import*as U from"path";var ce="\x1B[0m",pe={black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m",bgBlack:"\x1B[40m",bgRed:"\x1B[41m",bgGreen:"\x1B[42m",bgYellow:"\x1B[43m",bgBlue:"\x1B[44m",bgMagenta:"\x1B[45m",bgCyan:"\x1B[46m",bgWhite:"\x1B[47m",bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",underline:"\x1B[4m",strikethrough:"\x1B[9m"};function o(e,t){let n=pe[t];return n?`${n}${e}${ce}`:e}function q(e){let t=e.slice(2),n={command:"",args:[],options:{},raw:t},r=0;for(;r<t.length;){let s=t[r];if(s==="--help"||s==="-h")n.options.help=!0,r++;else if(s==="--version"||s==="-v")n.options.version=!0,r++;else if(s.startsWith("--")){let a=s.indexOf("=");if(a!==-1){let p=s.slice(2,a),d=s.slice(a+1);n.options[p]=d}else{let p=s.slice(2),d=t[r+1];d&&!d.startsWith("-")?(n.options[p]=d,r++):n.options[p]=!0}r++}else if(s.startsWith("-")&&s.length>1){let a=s.slice(1),p=t[r+1];p&&!p.startsWith("-")?(n.options[a]=p,r++):n.options[a]=!0,r++}else n.command?(n.args.push(s),r++):(n.command=s,r++)}return n}function $(e){v.existsSync(e)||v.mkdirSync(e,{recursive:!0})}function I(e){return v.existsSync(e)}function S(e){return v.readFileSync(e,"utf-8")}function w(e,t){let n=U.dirname(e);$(n),typeof t=="string"?v.writeFileSync(e,t,"utf-8"):v.writeFileSync(e,t)}var i={info(e){console.log(`${o("[INFO]","blue")} ${e}`)},warn(e){console.log(`${o("[WARN]","yellow")} ${e}`)},error(e){console.error(`${o("[ERROR]","red")} ${e}`)},success(e){console.log(`${o("[SUCCESS]","green")} ${e}`)}};import*as H from"path";function de(){return`<!DOCTYPE html>
3
- <html lang="zh-CN">
4
- <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Lyt App</title>
8
- <link rel="stylesheet" href="/src/style.css" />
9
- </head>
10
- <body>
11
- <div id="app"></div>
12
- <script type="module" src="/src/main.ts"></script>
13
- </body>
14
- </html>
15
- `}function ue(){return`import { createApp } from '@lytjs/lytjs';
16
- import App from './App';
17
-
18
- // \u521B\u5EFA\u5E94\u7528\u5B9E\u4F8B
19
- const app = createApp(App);
20
-
21
- // \u5C06\u5E94\u7528\u6302\u8F7D\u5230 #app \u5143\u7D20
22
- app.mount('#app');
23
- `}function me(){return`import { defineComponent, ref, computed } from '@lytjs/lytjs';
24
-
25
- // \u5B9A\u4E49\u6839\u7EC4\u4EF6
26
- const App = defineComponent({
27
- name: 'App',
28
-
29
- // \u7EC4\u4EF6\u6A21\u677F
30
- template: \`
31
- <div class="app">
32
- <header class="app-header">
33
- <div class="logo">
34
- <span class="logo-text">Lyt</span>
35
- </div>
36
- </header>
37
-
38
- <main class="app-main">
39
- <div class="welcome-section">
40
- <h1>\u6B22\u8FCE\u4F7F\u7528 Lyt.js!</h1>
41
- <p>\u8F7B\u5199\u8F7B\u8DD1\uFF0C\u6240\u89C1\u5373\u4EE3\u7801</p>
42
-
43
- <div class="counter-section">
44
- <h2>\u8BA1\u6570\u5668\u793A\u4F8B</h2>
45
- <p class="count-display">
46
- \u5F53\u524D\u8BA1\u6570: <strong>{{ count }}</strong>
47
- </p>
48
- <p class="double-display">
49
- \u53CC\u500D: <strong>{{ double }}</strong>
50
- </p>
51
-
52
- <div class="button-group">
53
- <button class="btn btn-primary" on-click="increment">+1</button>
54
- <button class="btn btn-secondary" on-click="decrement">-1</button>
55
- <button class="btn btn-success" on-click="reset">\u91CD\u7F6E</button>
56
- </div>
57
- </div>
58
-
59
- <div class="features-section">
60
- <h2>\u6838\u5FC3\u529F\u80FD</h2>
61
- <ul>
62
- <li v-for="feature in features" :key="feature">
63
- {{ feature }}
64
- </li>
65
- </ul>
66
- </div>
67
- </div>
68
- </main>
69
-
70
- <footer class="app-footer">
71
- <p>
72
- \u7528 \u2764\uFE0F \u6253\u9020
73
- </p>
74
- </footer>
75
- </div>
76
- \`,
77
-
78
- // \u54CD\u5E94\u5F0F\u6570\u636E
79
- setup() {
80
- const count = ref(0);
81
- const double = computed(() => count.value * 2);
82
-
83
- const features = [
84
- '\u54CD\u5E94\u5F0F\u7CFB\u7EDF\uFF08Proxy + Signal\uFF09',
85
- '\u865A\u62DF DOM + Patch Flag \u4F18\u5316',
86
- '\u7EC4\u4EF6\u7CFB\u7EDF\uFF08Options + Composition API\uFF09',
87
- '\u5185\u7F6E\u8DEF\u7531',
88
- '\u72B6\u6001\u7BA1\u7406',
89
- 'CLI \u5DE5\u5177\u94FE',
90
- '\u6D4F\u89C8\u5668 DevTools',
91
- '28+ UI \u7EC4\u4EF6',
92
- ];
93
-
94
- const increment = () => {
95
- count.value++;
96
- };
97
-
98
- const decrement = () => {
99
- count.value--;
100
- };
101
-
102
- const reset = () => {
103
- count.value = 0;
104
- };
105
-
106
- return {
107
- count,
108
- double,
109
- features,
110
- increment,
111
- decrement,
112
- reset,
113
- };
114
- },
2
+ import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'fs';
3
+ import { join, resolve, dirname } from 'path';
4
+ import { execSync, spawn } from 'child_process';
5
+
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
115
11
  });
116
12
 
117
- export default App;
118
- `}function ge(){return`/* Lyt.js \u5E94\u7528\u6837\u5F0F */
119
-
120
- :root {
121
- --primary-color: #42b883;
122
- --primary-hover: #35a06f;
123
- --secondary-color: #747b88;
124
- --success-color: #10b981;
125
- --danger-color: #ef4444;
126
- --text-color: #333;
127
- --bg-color: #f9fafb;
128
- --card-bg: #ffffff;
129
- --border-color: #e5e7eb;
13
+ // src/utils/logger.ts
14
+ var colors = {
15
+ reset: "\x1B[0m",
16
+ bright: "\x1B[1m",
17
+ dim: "\x1B[2m",
18
+ red: "\x1B[31m",
19
+ green: "\x1B[32m",
20
+ yellow: "\x1B[33m",
21
+ blue: "\x1B[34m",
22
+ cyan: "\x1B[36m"
23
+ };
24
+ function colorize(text, color) {
25
+ if (!isColorSupported()) return text;
26
+ return `${colors[color]}${text}${colors.reset}`;
130
27
  }
131
-
132
- * {
133
- margin: 0;
134
- padding: 0;
135
- box-sizing: border-box;
136
- }
137
-
138
- body {
139
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
140
- color: var(--text-color);
141
- background-color: var(--bg-color);
142
- line-height: 1.6;
143
- }
144
-
145
- .app {
146
- min-height: 100vh;
147
- display: flex;
148
- flex-direction: column;
28
+ var logger = {
29
+ info(message) {
30
+ console.log(colorize("\u2139 ", "blue") + message);
31
+ },
32
+ success(message) {
33
+ console.log(colorize("\u2714 ", "green") + message);
34
+ },
35
+ warning(message) {
36
+ console.log(colorize("\u26A0 ", "yellow") + message);
37
+ },
38
+ error(message) {
39
+ console.error(colorize("\u2716 ", "red") + message);
40
+ },
41
+ dim(message) {
42
+ console.log(colorize(message, "dim"));
43
+ },
44
+ bold(message) {
45
+ return colorize(message, "bright");
46
+ }
47
+ };
48
+ function isColorSupported() {
49
+ return process.stdout.isTTY && process.env.NO_COLOR !== "1";
149
50
  }
150
-
151
- .app-header {
152
- background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));
153
- padding: 1.5rem 2rem;
154
- color: white;
155
- box-shadow: 0 2px 10px rgba(66, 184, 131, 0.2);
51
+ function ensureDir(dir) {
52
+ if (!existsSync(dir)) {
53
+ mkdirSync(dir, { recursive: true });
54
+ }
156
55
  }
157
-
158
- .logo {
159
- font-size: 1.8rem;
160
- font-weight: 700;
56
+ function writeFile(filePath, content) {
57
+ ensureDir(dirname(filePath));
58
+ writeFileSync(filePath, content, "utf-8");
161
59
  }
162
-
163
- .logo-text {
164
- letter-spacing: 2px;
60
+ function readFile(filePath) {
61
+ return readFileSync(filePath, "utf-8");
165
62
  }
166
-
167
- .app-main {
168
- flex: 1;
169
- padding: 3rem 2rem;
170
- max-width: 900px;
171
- margin: 0 auto;
172
- width: 100%;
63
+ function exists(path) {
64
+ return existsSync(path);
173
65
  }
174
-
175
- .welcome-section {
176
- text-align: center;
66
+ function isEmptyDir(dir) {
67
+ if (!existsSync(dir)) return true;
68
+ const files = readdirSync(dir);
69
+ return files.length === 0;
177
70
  }
178
-
179
- .welcome-section h1 {
180
- font-size: 2.5rem;
181
- margin-bottom: 0.5rem;
182
- color: var(--primary-color);
71
+ function detectPackageManager(cwd = process.cwd()) {
72
+ if (existsSync(join(cwd, "pnpm-lock.yaml"))) return "pnpm";
73
+ if (existsSync(join(cwd, "yarn.lock"))) return "yarn";
74
+ if (existsSync(join(cwd, "package-lock.json"))) return "npm";
75
+ try {
76
+ execSync("pnpm --version", { stdio: "ignore" });
77
+ return "pnpm";
78
+ } catch {
79
+ return "npm";
80
+ }
183
81
  }
184
-
185
- .welcome-section p {
186
- font-size: 1.2rem;
187
- color: var(--secondary-color);
188
- margin-bottom: 2rem;
82
+ function getInstallCommand(pm) {
83
+ switch (pm) {
84
+ case "pnpm":
85
+ return "pnpm install";
86
+ case "yarn":
87
+ return "yarn";
88
+ case "npm":
89
+ return "npm install";
90
+ }
189
91
  }
190
-
191
- .counter-section {
192
- background: var(--card-bg);
193
- border-radius: 12px;
194
- padding: 2rem;
195
- margin: 2rem 0;
196
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
197
- border: 1px solid var(--border-color);
92
+ function getRunCommand(pm, script) {
93
+ switch (pm) {
94
+ case "pnpm":
95
+ return `pnpm run ${script}`;
96
+ case "yarn":
97
+ return `yarn ${script}`;
98
+ case "npm":
99
+ return `npm run ${script}`;
100
+ }
198
101
  }
199
-
200
- .counter-section h2 {
201
- margin-bottom: 1rem;
202
- color: var(--text-color);
102
+ function getAddCommand(pm, dep, dev2 = false) {
103
+ const devFlag = dev2 ? " -D" : "";
104
+ switch (pm) {
105
+ case "pnpm":
106
+ return `pnpm add${devFlag} ${dep}`;
107
+ case "yarn":
108
+ return `yarn add${devFlag} ${dep}`;
109
+ case "npm":
110
+ return `npm install${devFlag} ${dep}`;
111
+ }
203
112
  }
204
-
205
- .count-display,
206
- .double-display {
207
- font-size: 1.25rem;
208
- margin: 0.75rem 0;
113
+ var TEMPLATES = {
114
+ default: "Default template with TypeScript and Vite",
115
+ minimal: "Minimal template without extra dependencies",
116
+ ssr: "SSR-enabled template",
117
+ router: "Template with Router integration",
118
+ store: "Template with Store integration",
119
+ full: "Full-featured template with Router, Store, and UI components"
120
+ };
121
+ async function create(projectName, options = {}) {
122
+ if (!projectName) {
123
+ logger.error("Please provide a project name.");
124
+ logger.info("Usage: lyt create <project-name>");
125
+ process.exit(1);
126
+ }
127
+ const targetDir = resolve(process.cwd(), projectName);
128
+ if (exists(targetDir) && !isEmptyDir(targetDir) && !options.force) {
129
+ logger.error(`Directory "${projectName}" already exists and is not empty.`);
130
+ logger.info("Use --force to overwrite.");
131
+ process.exit(1);
132
+ }
133
+ logger.info(`Creating a new LytJS project in ${targetDir}...`);
134
+ ensureDir(targetDir);
135
+ generateProjectFiles(targetDir, projectName, options.template || "default");
136
+ logger.info("Installing dependencies...");
137
+ const pm = detectPackageManager();
138
+ try {
139
+ execSync(getInstallCommand(pm), { cwd: targetDir, stdio: "inherit" });
140
+ logger.success("Dependencies installed successfully!");
141
+ } catch (_error) {
142
+ logger.warning("Failed to install dependencies automatically.");
143
+ logger.info(`Please run "${getInstallCommand(pm)}" manually.`);
144
+ }
145
+ logger.success(`Project "${projectName}" created successfully!`);
146
+ logger.info("");
147
+ logger.bold("Next steps:");
148
+ logger.info(` cd ${projectName}`);
149
+ logger.info(` ${pm === "npm" ? "npm run" : pm} dev`);
209
150
  }
151
+ function generateProjectFiles(targetDir, projectName, template) {
152
+ const isMinimal = template === "minimal";
153
+ const isSsr = template === "ssr";
154
+ const isRouter = template === "router" || template === "full";
155
+ const isStore = template === "store" || template === "full";
156
+ const isFull = template === "full";
157
+ const packageJson = {
158
+ name: projectName,
159
+ version: "0.0.0",
160
+ type: "module",
161
+ scripts: {
162
+ dev: "vite",
163
+ build: "vite build",
164
+ preview: "vite preview"
165
+ },
166
+ dependencies: {
167
+ "@lytjs/core": "^6.0.0"
168
+ },
169
+ devDependencies: {
170
+ "@lytjs/plugin-vite": "^6.0.0",
171
+ "vite": "^5.0.0"
172
+ }
173
+ };
174
+ if (!isMinimal) {
175
+ packageJson.scripts.test = "vitest";
176
+ packageJson.devDependencies.vitest = "^1.0.0";
177
+ }
178
+ if (isSsr) {
179
+ packageJson.dependencies["@lytjs/server"] = "^6.0.0";
180
+ packageJson.scripts["build:client"] = "vite build --ssrManifest";
181
+ packageJson.scripts["build:server"] = "vite build --ssr src/entry-server.ts";
182
+ packageJson.scripts["build"] = "npm run build:client && npm run build:server";
183
+ packageJson.scripts["preview"] = "node server";
184
+ }
185
+ if (isRouter) {
186
+ packageJson.dependencies["@lytjs/router"] = "^1.0.0";
187
+ }
188
+ if (isStore) {
189
+ packageJson.dependencies["@lytjs/store"] = "^1.0.0";
190
+ }
191
+ if (isFull) {
192
+ packageJson.dependencies["@lytjs/ui"] = "^0.4.0";
193
+ }
194
+ writeFile(join(targetDir, "package.json"), JSON.stringify(packageJson, null, 2));
195
+ let viteConfig;
196
+ if (isSsr) {
197
+ viteConfig = `import { defineConfig } from 'vite';
198
+ import lytjs from '@lytjs/plugin-vite';
199
+
200
+ export default defineConfig({
201
+ plugins: [lytjs()],
202
+ build: {
203
+ ssrManifest: true,
204
+ },
205
+ });
206
+ `;
207
+ } else {
208
+ viteConfig = `import { defineConfig } from 'vite';
209
+ import lytjs from '@lytjs/plugin-vite';
210
210
 
211
- .button-group {
212
- display: flex;
213
- justify-content: center;
214
- gap: 1rem;
215
- margin-top: 1.5rem;
216
- flex-wrap: wrap;
217
- }
211
+ export default defineConfig({
212
+ plugins: [lytjs()],
213
+ });
214
+ `;
215
+ }
216
+ writeFile(join(targetDir, "vite.config.ts"), viteConfig);
217
+ const indexHtml = `<!DOCTYPE html>
218
+ <html lang="en">
219
+ <head>
220
+ <meta charset="UTF-8" />
221
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
222
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
223
+ <title>${projectName}</title>
224
+ </head>
225
+ <body>
226
+ <div id="app"></div>
227
+ <script type="module" src="/src/main.ts"></script>
228
+ </body>
229
+ </html>
230
+ `;
231
+ writeFile(join(targetDir, "index.html"), indexHtml);
232
+ let mainTs;
233
+ if (isSsr) {
234
+ mainTs = `import { createApp } from '@lytjs/core';
235
+ import App from './App.lyt';
236
+ import { createSSRApp } from '@lytjs/server';
237
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
238
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
239
+
240
+ const app = createSSRApp(App);
241
+ ${isStore ? "app.use(createPinia());" : ""}
242
+ ${isRouter ? `
243
+ const router = createRouter({
244
+ history: createWebHistory(),
245
+ routes: [
246
+ { path: '/', component: () => import('./pages/Home.lyt') },
247
+ { path: '/about', component: () => import('./pages/About.lyt') },
248
+ ],
249
+ });
250
+ app.use(router);
251
+ ` : ""}
252
+ app.mount('#app');
253
+ `;
254
+ } else if (isRouter || isStore) {
255
+ mainTs = `import { createApp } from '@lytjs/core';
256
+ import App from './App.lyt';
257
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
258
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
218
259
 
219
- .btn {
220
- padding: 0.75rem 1.5rem;
221
- border: none;
222
- border-radius: 8px;
223
- font-size: 1rem;
224
- font-weight: 500;
225
- cursor: pointer;
226
- transition: all 0.2s ease;
227
- color: white;
228
- }
260
+ const app = createApp(App);
261
+ ${isStore ? "app.use(createPinia());" : ""}
262
+ ${isRouter ? `
263
+ const router = createRouter({
264
+ history: createWebHistory(),
265
+ routes: [
266
+ { path: '/', component: () => import('./pages/Home.lyt') },
267
+ { path: '/about', component: () => import('./pages/About.lyt') },
268
+ ],
269
+ });
270
+ app.use(router);
271
+ ` : ""}
272
+ app.mount('#app');
273
+ `;
274
+ } else {
275
+ mainTs = `import { createApp } from '@lytjs/core';
276
+ import App from './App.lyt';
229
277
 
230
- .btn:hover {
231
- transform: translateY(-2px);
232
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
233
- }
278
+ createApp(App).mount('#app');
279
+ `;
280
+ }
281
+ writeFile(join(targetDir, "src/main.ts"), mainTs);
282
+ let appLyt;
283
+ if (isMinimal) {
284
+ appLyt = `<template>
285
+ <div class="app">
286
+ <h1>{{ title }}</h1>
287
+ </div>
288
+ </template>
234
289
 
235
- .btn:active {
236
- transform: translateY(0);
237
- }
290
+ <script setup>
291
+ const title = 'Hello LytJS!';
292
+ </script>
238
293
 
239
- .btn-primary {
240
- background: var(--primary-color);
294
+ <style scoped>
295
+ .app {
296
+ text-align: center;
241
297
  }
298
+ </style>
299
+ `;
300
+ } else if (isRouter) {
301
+ appLyt = `<template>
302
+ <div class="app">
303
+ <nav class="nav">
304
+ <router-link to="/">Home</router-link>
305
+ <router-link to="/about">About</router-link>
306
+ </nav>
307
+ <router-view />
308
+ </div>
309
+ </template>
242
310
 
243
- .btn-primary:hover {
244
- background: var(--primary-hover);
245
- }
311
+ <script setup lang="ts">
312
+ import { RouterLink, RouterView } from '@lytjs/router';
313
+ </script>
246
314
 
247
- .btn-secondary {
248
- background: var(--secondary-color);
315
+ <style scoped>
316
+ .app {
317
+ text-align: center;
318
+ padding: 2rem;
249
319
  }
250
320
 
251
- .btn-secondary:hover {
252
- background: #5d6470;
321
+ .nav {
322
+ margin-bottom: 2rem;
253
323
  }
254
324
 
255
- .btn-success {
256
- background: var(--success-color);
325
+ .nav a {
326
+ margin: 0 1rem;
327
+ color: #42b883;
328
+ text-decoration: none;
257
329
  }
258
330
 
259
- .btn-success:hover {
260
- background: #059669;
331
+ .nav a:hover {
332
+ text-decoration: underline;
261
333
  }
334
+ </style>
335
+ `;
336
+ } else {
337
+ appLyt = `<template>
338
+ <div class="app">
339
+ <h1>{{ title }}</h1>
340
+ <p>Welcome to your LytJS app!</p>
341
+ </div>
342
+ </template>
262
343
 
263
- .features-section {
264
- margin-top: 2rem;
265
- text-align: left;
266
- }
344
+ <script setup>
345
+ const title = 'Hello LytJS!';
346
+ </script>
267
347
 
268
- .features-section h2 {
348
+ <style scoped>
349
+ .app {
269
350
  text-align: center;
270
- margin-bottom: 1.5rem;
271
- color: var(--text-color);
272
- }
273
-
274
- .features-section ul {
275
- list-style: none;
276
- padding: 0;
277
- max-width: 600px;
278
- margin: 0 auto;
279
- }
280
-
281
- .features-section li {
282
- padding: 0.75rem 1rem;
283
- margin: 0.5rem 0;
284
- background: var(--card-bg);
285
- border-radius: 8px;
286
- border-left: 4px solid var(--primary-color);
287
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
351
+ padding: 2rem;
288
352
  }
289
353
 
290
- .app-footer {
291
- padding: 1.5rem 2rem;
292
- text-align: center;
293
- color: var(--secondary-color);
294
- border-top: 1px solid var(--border-color);
295
- background: var(--card-bg);
354
+ h1 {
355
+ color: #42b883;
296
356
  }
297
-
298
- @media (max-width: 640px) {
299
- .welcome-section h1 {
300
- font-size: 2rem;
301
- }
302
-
303
- .app-main {
304
- padding: 2rem 1rem;
357
+ </style>
358
+ `;
305
359
  }
306
- }
307
- `}function fe(e){return JSON.stringify({name:e,version:"0.1.0",type:"module",private:!0,scripts:{dev:"lytx dev",build:"lytx build",preview:"lytx preview"},dependencies:{"@lytjs/lytjs":"latest"},devDependencies:{"@lytjs/cli":"latest"}},null,2)+`
308
- `}function he(){return JSON.stringify({compilerOptions:{target:"ES2020",module:"ESNext",moduleResolution:"bundler",strict:!0,jsx:"preserve",resolveJsonModule:!0,isolatedModules:!0,esModuleInterop:!0,lib:["ES2020","DOM","DOM.Iterable"],skipLibCheck:!0,noEmit:!0,paths:{"@/*":["./src/*"]}},include:["src/**/*.ts","src/**/*.tsx"],exclude:["node_modules","dist"]},null,2)+`
309
- `}function ye(){return`# Dependencies
310
- node_modules/
311
- .pnp
312
- .pnp.js
313
-
314
- # Build outputs
315
- dist/
316
- build/
317
- *.log
318
- npm-debug.log*
319
-
320
- # IDE
321
- .vscode/
322
- .idea/
323
- *.swp
324
- *.swo
325
-
326
- # OS
327
- .DS_Store
328
- Thumbs.db
329
-
330
- # Environment
331
- .env.local
332
- .env.*.local
333
-
334
- # Cache
335
- *.cache
336
- .cache/
337
- `}function be(e){return`# ${e}
338
-
339
- \u8FD9\u662F\u4E00\u4E2A\u4F7F\u7528 [Lyt.js](https://gitee.com/lytjs/lytjs) \u6846\u67B6\u521B\u5EFA\u7684\u9879\u76EE\u3002
340
-
341
- ## \u7279\u6027
342
-
343
- - \u26A1 **\u96F6\u4F9D\u8D56** - \u7EAF\u539F\u751F\u5B9E\u73B0\uFF0C\u4E0D\u4F9D\u8D56\u4EFB\u4F55\u7B2C\u4E09\u65B9\u5E93
344
- - \u{1F680} **\u8D85\u8F7B\u91CF** - \u6838\u5FC3\u4EC5 34.56KB\uFF0C\u6781\u901F\u52A0\u8F7D
345
- - \u{1F3A8} **Vue 3 \u517C\u5BB9** - API \u9AD8\u5EA6\u517C\u5BB9\uFF0C\u8FC1\u79FB\u6210\u672C\u4F4E
346
- - \u{1F527} **\u5F00\u7BB1\u5373\u7528** - \u5185\u7F6E\u8DEF\u7531\u3001\u72B6\u6001\u7BA1\u7406\u3001\u7EC4\u4EF6\u5E93
347
-
348
- ## \u5FEB\u901F\u5F00\u59CB
349
-
350
- ### \u5B89\u88C5\u4F9D\u8D56
351
-
352
- \`\`\`bash
353
- npm install
354
- \`\`\`
355
-
356
- ### \u542F\u52A8\u5F00\u53D1\u670D\u52A1\u5668
357
-
358
- \`\`\`bash
359
- npm run dev
360
- \`\`\`
361
-
362
- ### \u6784\u5EFA\u751F\u4EA7\u7248\u672C
363
-
364
- \`\`\`bash
365
- npm run build
366
- \`\`\`
367
-
368
- ## \u9879\u76EE\u7ED3\u6784
369
-
370
- \`\`\`
371
- ${e}/
372
- \u251C\u2500\u2500 index.html # HTML \u5165\u53E3
373
- \u251C\u2500\u2500 package.json # \u9879\u76EE\u914D\u7F6E
374
- \u251C\u2500\u2500 tsconfig.json # TypeScript \u914D\u7F6E
375
- \u251C\u2500\u2500 src/
376
- \u2502 \u251C\u2500\u2500 main.ts # \u5E94\u7528\u5165\u53E3
377
- \u2502 \u251C\u2500\u2500 App.ts # \u6839\u7EC4\u4EF6
378
- \u2502 \u2514\u2500\u2500 style.css # \u5168\u5C40\u6837\u5F0F
379
- \u2514\u2500\u2500 README.md # \u9879\u76EE\u6587\u6863
380
- \`\`\`
381
-
382
- ## \u5B66\u4E60\u8D44\u6E90
383
-
384
- - \u{1F4D6} [Lyt.js \u5B98\u65B9\u6587\u6863](https://gitee.com/lytjs/lytjs)
385
- - \u{1F4A1} [\u5FEB\u901F\u5F00\u59CB\u6307\u5357](https://gitee.com/lytjs/lytjs)
386
- - \u{1F527} [API \u53C2\u8003](https://gitee.com/lytjs/lytjs)
387
-
388
- ## \u793E\u533A\u652F\u6301
389
-
390
- - \u{1F310} Gitee: [https://gitee.com/lytjs/lytjs](https://gitee.com/lytjs/lytjs)
391
- - \u{1F4AC} Issues: [https://gitee.com/lytjs/lytjs/issues](https://gitee.com/lytjs/lytjs/issues)
360
+ writeFile(join(targetDir, "src/App.lyt"), appLyt);
361
+ if (isRouter) {
362
+ const homePage = `<template>
363
+ <div class="home">
364
+ <h1>Home</h1>
365
+ ${isStore ? `
366
+ <p>Count: {{ count }}</p>
367
+ <button @click="increment">Increment</button>
368
+ <button @click="decrement">Decrement</button>
369
+ ` : ""}
370
+ <p>Welcome to the Home page!</p>
371
+ </div>
372
+ </template>
392
373
 
393
- ## License
374
+ <script setup lang="ts">
375
+ ${isStore ? `import { useCounterStore } from '../stores/counter';
376
+ const counterStore = useCounterStore();
377
+ const { count, increment, decrement } = counterStore;
378
+ ` : ""}
379
+ </script>
394
380
 
395
- MIT
396
- `}async function Z(e,t={}){let n=t.template||"spa",r=H.resolve(process.cwd(),e);i.info(`\u6B63\u5728\u521B\u5EFA Lyt \u9879\u76EE: ${o(e,"brightCyan")}`),i.info(`\u4F7F\u7528\u6A21\u677F: ${o(n,"brightCyan")}`),I(r)&&(i.error(`\u76EE\u5F55 "${e}" \u5DF2\u5B58\u5728\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u540D\u79F0\u6216\u5220\u9664\u5DF2\u6709\u76EE\u5F55`),process.exit(1)),$(r);let s=[{filePath:"index.html",content:de()},{filePath:"src/main.ts",content:ue()},{filePath:"src/App.ts",content:me()},{filePath:"src/style.css",content:ge()},{filePath:"package.json",content:fe(e)},{filePath:"tsconfig.json",content:he()},{filePath:".gitignore",content:ye()},{filePath:"README.md",content:be(e)}];for(let a of s){let p=H.join(r,a.filePath);w(p,a.content),i.success(` \u521B\u5EFA ${a.filePath}`)}console.log(""),i.success(`\u9879\u76EE ${o(e,"brightCyan")} \u521B\u5EFA\u6210\u529F\uFF01`),console.log(""),console.log(" \u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u542F\u52A8\u9879\u76EE\uFF1A"),console.log(""),console.log(` ${o("cd","brightGreen")} ${e}`),console.log(` ${o("npm install","brightGreen")}`),console.log(` ${o("npm run dev","brightGreen")}`),console.log("")}import*as F from"fs";import*as h from"path";var G={spa:{description:"\u57FA\u7840 SPA \u5355\u9875\u5E94\u7528\uFF08\u8BA1\u6570\u5668\u793A\u4F8B\uFF09",type:"builtin"},ssr:{description:"SSR \u670D\u52A1\u7AEF\u6E32\u67D3\u5E94\u7528",type:"builtin"},ssg:{description:"SSG \u9759\u6001\u7AD9\u70B9\u751F\u6210",type:"builtin"},"todo-app":{description:"Todo \u5F85\u529E\u4E8B\u9879\u5E94\u7528\uFF08\u54CD\u5E94\u5F0F + LocalStorage \u6301\u4E45\u5316\uFF09",type:"example"},"admin-dashboard":{description:"Admin Dashboard \u4F01\u4E1A\u7EA7\u540E\u53F0\u7BA1\u7406\u7CFB\u7EDF\uFF0810 \u4E2A\u9875\u9762\uFF09",type:"example"}};function N(){let e={};for(let[t,n]of Object.entries(G))e[t]=n.description;return e}function z(e){return e in G}function xe(e){let t={name:e.name,version:"0.1.0",private:!0,type:"module",scripts:{dev:"lytx dev",build:"lytx build",preview:"lytx preview"},dependencies:{"@lytjs/lytjs":"latest"}};return e.ts&&(t.devDependencies={"@lytjs/cli":"latest",typescript:"^5.0.1"}),e.eslint&&(t.devDependencies=t.devDependencies||{},t.devDependencies.eslint="^8.0.0",t.scripts=t.scripts||{},t.scripts.lint="eslint src --ext .ts,.js"),e.router&&(t.dependencies["@lytjs/router"]="latest"),e.store&&(t.dependencies["@lytjs/store"]="latest"),JSON.stringify(t,null,2)+`
397
- `}function ve(e){let t={compilerOptions:{target:"ES2020",module:"ESNext",moduleResolution:"bundler",strict:!0,jsx:"preserve",resolveJsonModule:!0,isolatedModules:!0,esModuleInterop:!0,lib:["ES2020","DOM","DOM.Iterable"],skipLibCheck:!0,noEmit:!0,paths:{"@/*":["./src/*"]}},include:["src/**/*.ts","src/**/*.tsx"],exclude:["node_modules","dist"]};return e.template==="ssr"&&(t.compilerOptions.types=["node"]),JSON.stringify(t,null,2)+`
398
- `}function $e(e){let t=e.ts?".ts":".js";return`<!DOCTYPE html>
399
- <html lang="zh-CN">
400
- <head>
401
- <meta charset="UTF-8" />
402
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
403
- <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
404
- <title>${e.name}</title>
405
- </head>
406
- <body>
407
- <div id="app"></div>
408
- <script type="module" src="/src/main${t}"></script>
409
- </body>
410
- </html>
411
- `}function we(e){let t=["// Lytx \u914D\u7F6E\u6587\u4EF6","import { defineConfig } from '@lytjs/lytjs'","","export default defineConfig({"," // \u6784\u5EFA\u6A21\u5F0F",` mode: '${e.template}',`];return e.router&&(t.push(" // \u8DEF\u7531\u914D\u7F6E"),t.push(" router: {"),t.push(" historyMode: true,"),t.push(" },")),e.store&&(t.push(" // \u72B6\u6001\u7BA1\u7406\u914D\u7F6E"),t.push(" store: {"),t.push(" strict: true,"),t.push(" },")),t.push("})"),t.push(""),t.join(`
412
- `)}function Se(e){let t=e.ts?".ts":".js",n=["import { createApp } from '@lytjs/lytjs'","import App from './App.lyt'","import './styles/main.css'"];return e.router&&n.push("import { router } from './router'"),e.store&&n.push("import { store } from './store'"),n.push(""),n.push("// \u521B\u5EFA\u5E94\u7528\u5B9E\u4F8B"),n.push("const app = createApp(App)"),e.router&&n.push("app.use(router)"),e.store&&n.push("app.use(store)"),n.push(""),n.push("// \u5C06\u5E94\u7528\u6302\u8F7D\u5230 #app \u5143\u7D20"),n.push("app.mount('#app')"),n.join(`
413
- `)+`
414
- `}function je(){return`<template>
415
- <div class="app">
416
- <Header />
417
- <main>
418
- <h1>Hello Lyt!</h1>
419
- <p>\u6B22\u8FCE\u4F7F\u7528 Lyt \u6846\u67B6</p>
420
- </main>
381
+ <style scoped>
382
+ .home {
383
+ padding: 1rem;
384
+ }
385
+ </style>
386
+ `;
387
+ ensureDir(join(targetDir, "src", "pages"));
388
+ writeFile(join(targetDir, "src", "pages", "Home.lyt"), homePage);
389
+ const aboutPage = `<template>
390
+ <div class="about">
391
+ <h1>About</h1>
392
+ <p>This is the About page!</p>
421
393
  </div>
422
394
  </template>
423
395
 
424
- <script lang="ts">
425
- import { defineComponent } from '@lytjs/lytjs'
426
- import Header from './components/Header'
427
-
428
- export default defineComponent({
429
- name: 'App',
430
- components: {
431
- Header,
432
- },
433
- })
396
+ <script setup lang="ts">
434
397
  </script>
435
398
 
436
399
  <style scoped>
437
- .app {
438
- text-align: center;
439
- padding: 20px;
400
+ .about {
401
+ padding: 1rem;
440
402
  }
441
403
  </style>
442
- `}function Ce(){return`import { defineComponent } from '@lytjs/lytjs'
443
-
444
- export default defineComponent({
445
- name: 'HomePage',
446
-
447
- template: \`
448
- <div class="page-home">
449
- <h1>\u9996\u9875</h1>
450
- <p>\u8FD9\u662F\u9996\u9875\u5185\u5BB9</p>
451
- </div>
452
- \`,
453
- })
454
- `}function Pe(){return`import { defineComponent } from '@lytjs/lytjs'
455
-
456
- export default defineComponent({
457
- name: 'AboutPage',
458
-
459
- template: \`
460
- <div class="page-about">
461
- <h1>\u5173\u4E8E</h1>
462
- <p>\u8FD9\u662F\u5173\u4E8E\u9875\u9762</p>
463
- </div>
464
- \`,
465
- })
466
- `}function ke(){return`import { defineComponent } from '@lytjs/lytjs'
467
-
468
- export default defineComponent({
469
- name: 'Header',
470
-
471
- template: \`
472
- <header class="header">
473
- <nav>
474
- <a href="/">\u9996\u9875</a>
475
- <a href="/about">\u5173\u4E8E</a>
476
- </nav>
477
- </header>
478
- \`,
479
- })
480
- `}function Ae(){return`import { createRouter, createWebHistory } from '@lytjs/router'
481
- import HomePage from '../pages/index'
482
- import AboutPage from '../pages/about'
483
-
484
- export const router = createRouter({
485
- history: createWebHistory(),
486
- routes: [
487
- {
488
- path: '/',
489
- component: HomePage,
490
- },
491
- {
492
- path: '/about',
493
- component: AboutPage,
494
- },
495
- ],
496
- })
497
- `}function Re(){return`import { createStore } from '@lytjs/store'
404
+ `;
405
+ writeFile(join(targetDir, "src", "pages", "About.lyt"), aboutPage);
406
+ }
407
+ if (isStore) {
408
+ const counterStore = `import { defineStore } from '@lytjs/store';
409
+ import { signal, computed } from '@lytjs/reactivity';
498
410
 
499
- export const store = createStore({
500
- state: {
501
- count: 0,
502
- message: 'Hello Lyt!',
503
- },
411
+ export const useCounterStore = defineStore('counter', () => {
412
+ // State
413
+ const count = signal(0);
504
414
 
505
- mutations: {
506
- increment(state: any) {
507
- state.count++
508
- },
415
+ // Getters
416
+ const doubleCount = computed(() => count.value * 2);
509
417
 
510
- setMessage(state: any, message: string) {
511
- state.message = message
512
- },
513
- },
418
+ // Actions
419
+ function increment() {
420
+ count.value++;
421
+ }
514
422
 
515
- actions: {
516
- async fetchMessage({ commit }: any) {
517
- commit('setMessage', 'Fetched from API')
518
- },
519
- },
423
+ function decrement() {
424
+ count.value--;
425
+ }
520
426
 
521
- getters: {
522
- doubleCount: (state: any) => state.count * 2,
523
- },
524
- })
525
- `}function Te(){return`/* \u5168\u5C40\u6837\u5F0F */
427
+ function reset() {
428
+ count.value = 0;
429
+ }
526
430
 
527
- * {
528
- margin: 0;
529
- padding: 0;
530
- box-sizing: border-box;
531
- }
431
+ return {
432
+ count,
433
+ doubleCount,
434
+ increment,
435
+ decrement,
436
+ reset,
437
+ };
438
+ });
439
+ `;
440
+ ensureDir(join(targetDir, "src", "stores"));
441
+ writeFile(join(targetDir, "src", "stores", "counter.ts"), counterStore);
442
+ }
443
+ if (isSsr) {
444
+ const entryServer = `import { createSSRApp } from '@lytjs/core';
445
+ import App from './App.lyt';
532
446
 
533
- body {
534
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
535
- 'Helvetica Neue', Arial, sans-serif;
536
- -webkit-font-smoothing: antialiased;
537
- -moz-osx-font-smoothing: grayscale;
538
- color: #2c3e50;
447
+ export async function render(url: string) {
448
+ const app = createSSRApp(App);
449
+ return app;
539
450
  }
451
+ `;
452
+ writeFile(join(targetDir, "src/entry-server.ts"), entryServer);
453
+ const entryClient = `import { createApp } from '@lytjs/core';
454
+ import App from './App.lyt';
540
455
 
541
- a {
542
- color: #42b883;
543
- text-decoration: none;
544
- }
456
+ const app = createApp(App);
457
+ app.mount('#app');
458
+ `;
459
+ writeFile(join(targetDir, "src/entry-client.ts"), entryClient);
460
+ const serverTs = `/**
461
+ * LytJS SSR Server
462
+ *
463
+ * A minimal SSR server for development and production.
464
+ */
545
465
 
546
- a:hover {
547
- text-decoration: underline;
548
- }
549
- `}function Me(){return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
550
- <rect width="32" height="32" rx="6" fill="#42b883"/>
551
- <text x="16" y="22" text-anchor="middle" fill="white" font-size="18" font-weight="bold">L</text>
552
- </svg>
553
- `}function Ee(){return JSON.stringify({root:!0,env:{browser:!0,es2021:!0,node:!0},extends:["eslint:recommended"],parserOptions:{ecmaVersion:"latest",sourceType:"module"},rules:{"no-unused-vars":"warn","no-console":"warn"}},null,2)+`
554
- `}function X(e,t){if(!F.existsSync(e))throw new Error(`\u6A21\u677F\u76EE\u5F55\u4E0D\u5B58\u5728: ${e}`);let n=F.readdirSync(e,{withFileTypes:!0});for(let r of n){let s=h.join(e,r.name),a=h.join(t,r.name);if(!(r.name===".DS_Store"||r.name==="node_modules"))if(r.isDirectory())X(s,a);else{$(h.dirname(a));let p=S(s);w(a,p),i.success(` \u521B\u5EFA ${h.relative(t,a)}`)}}}async function Ie(e){let{name:t,template:n}=e,r=h.resolve(process.cwd(),t);if(i.info(`\u6B63\u5728\u521B\u5EFA Lyt \u9879\u76EE: ${o(t,"brightCyan")}`),i.info(`\u4F7F\u7528\u6A21\u677F: ${o(n,"brightCyan")} (${G[n].description})`),I(r))throw i.error(`\u76EE\u5F55 "${t}" \u5DF2\u5B58\u5728\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u540D\u79F0\u6216\u5220\u9664\u5DF2\u6709\u76EE\u5F55`),new Error(`Directory "${t}" already exists`);$(r);let s=h.resolve(__dirname,".."),a=h.join(s,"templates",n);X(a,r);let p=h.join(r,"package.json");if(F.existsSync(p)){let d=S(p),u=JSON.parse(d);u.name=t,w(p,JSON.stringify(u,null,2)+`
555
- `),i.success(` \u66F4\u65B0 package.json (name: ${t})`)}console.log(""),i.success(`\u9879\u76EE ${o(t,"brightCyan")} \u521B\u5EFA\u6210\u529F\uFF01`),console.log(""),console.log(" \u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u542F\u52A8\u9879\u76EE\uFF1A"),console.log(""),console.log(` ${o("cd","brightGreen")} ${t}`),console.log(` ${o("npm install","brightGreen")}`),console.log(` ${o("npm run dev","brightGreen")}`),console.log("")}async function W(e){var c;if(((c=G[e.template])==null?void 0:c.type)==="example")return Ie(e);let{name:t,template:n,ts:r,router:s,store:a,eslint:p}=e,d=h.resolve(process.cwd(),t);if(i.info(`\u6B63\u5728\u521B\u5EFA Lyt \u9879\u76EE: ${o(t,"brightCyan")}`),i.info(`\u4F7F\u7528\u6A21\u677F: ${o(n,"brightCyan")}`),I(d))throw i.error(`\u76EE\u5F55 "${t}" \u5DF2\u5B58\u5728\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u540D\u79F0\u6216\u5220\u9664\u5DF2\u6709\u76EE\u5F55`),new Error(`Directory "${t}" already exists`);$(d);let u=[{filePath:"package.json",content:xe(e)},{filePath:"index.html",content:$e(e)},{filePath:"lytx.config.ts",content:we(e)},{filePath:"src/main.ts",content:Se(e)},{filePath:"src/App.lyt",content:je()},{filePath:"src/pages/index.ts",content:Ce()},{filePath:"src/pages/about.ts",content:Pe()},{filePath:"src/components/Header.ts",content:ke()},{filePath:"src/styles/main.css",content:Te()},{filePath:"public/favicon.svg",content:Me()}];r&&u.push({filePath:"tsconfig.json",content:ve(e)}),s&&u.push({filePath:"src/router/index.ts",content:Ae()}),a&&u.push({filePath:"src/store/index.ts",content:Re()}),p&&u.push({filePath:".eslintrc.json",content:Ee()});for(let m of u){let l=h.join(d,m.filePath);w(l,m.content),i.success(` \u521B\u5EFA ${m.filePath}`)}console.log(""),i.success(`\u9879\u76EE ${o(t,"brightCyan")} \u521B\u5EFA\u6210\u529F\uFF01`),console.log(""),console.log(" \u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u542F\u52A8\u9879\u76EE\uFF1A"),console.log(""),console.log(` ${o("cd","brightGreen")} ${t}`),console.log(` ${o("npm install","brightGreen")}`),console.log(` ${o("npm run dev","brightGreen")}`),console.log("")}import*as te from"http";import*as A from"fs";import*as x from"path";import*as Q from"http";import*as T from"fs";import*as j from"path";import*as ee from"crypto";var L=class{constructor(){this.clients=[]}handleUpgrade(t,n,r){let s=t.headers["sec-websocket-key"];if(!s){n.destroy();return}let a=ee.createHash("sha1").update(s+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");n.write(`HTTP/1.1 101 Switching Protocols\r
556
- Upgrade: websocket\r
557
- Connection: Upgrade\r
558
- Sec-WebSocket-Accept: ${a}\r
559
- \r
560
- `);let p={socket:n,isAlive:!0};n.on("close",()=>{this.clients=this.clients.filter(d=>d!==p)}),n.on("error",()=>{this.clients=this.clients.filter(d=>d!==p)}),this.clients.push(p)}broadcast(t){let n=[];for(let r of this.clients)try{if(!r.isAlive){n.push(r);continue}let s=Buffer.from(t,"utf-8"),a=this.createFrame(129,s);r.socket.write(a)}catch(s){n.push(r)}for(let r of n){this.clients=this.clients.filter(s=>s!==r);try{r.socket.destroy()}catch(s){}}}createFrame(t,n){let r=n.length,s;r<126?s=2:r<65536?s=4:s=10;let a=Buffer.alloc(s+r);return a[0]=t,r<126?a[1]=r:r<65536?(a[1]=126,a.writeUInt16BE(r,2)):(a[1]=127,a.writeUInt32BE(0,2),a.writeUInt32BE(r,6)),n.copy(a,s),a}getClientCount(){return this.clients.length}closeAll(){for(let t of this.clients)try{t.socket.destroy()}catch(n){}this.clients=[]}};function Fe(e){let t=new L,n=[],r=[],s=null,a=!1;function p(u){let c=j.extname(u).toLowerCase();if(c===".css")return"css";let m=j.basename(u);return m.startsWith("lytx.config")||m==="tsconfig.json"||m==="package.json"?"reload":c===".ts"||c===".tsx"||c===".lyt"||c===".js"||c===".jsx"?"update":"reload"}function d(u){try{let c=T.readdirSync(u,{withFileTypes:!0});for(let m of c){let l=j.join(u,m.name);if(m.isDirectory()){if(m.name==="node_modules"||m.name===".git"||m.name==="dist")continue;d(l)}else if(m.isFile()){let f=j.extname(m.name).toLowerCase();if(new Set([".ts",".tsx",".js",".jsx",".css",".html",".json",".lyt"]).has(f))try{let P=T.watch(l,{persistent:!1},K=>{if(K==="change"){let E=j.relative(e,l);for(let k of n)try{k(E)}catch(O){}let R=p(l),C={type:R,path:`/${E}`};if(R==="css")try{C.content=T.readFileSync(l,"utf-8")}catch(k){}t.broadcast(JSON.stringify(C))}});r.push(P)}catch(P){}}}}catch(c){}}return{start(u){a||(a=!0,s=Q.createServer((c,m)=>{m.writeHead(426,{"Content-Type":"text/plain"}),m.end("Upgrade Required")}),s.on("upgrade",(c,m,l)=>{t.handleUpgrade(c,m,l)}),s.listen(u,()=>{}),d(e))},stop(){a=!1;for(let u of r)try{u.close()}catch(c){}if(r.length=0,t.closeAll(),s){try{s.close()}catch(u){}s=null}},onFileChange(u){n.push(u)},notifyClient(u){t.broadcast(JSON.stringify(u))}}}function _(e){let t=new L;return e.on("upgrade",(n,r,s)=>{t.handleUpgrade(n,r,s)}),{broadcast(n){t.broadcast(n)},getClientCount(){return t.getClientCount()}}}function J(){return`(function() {
561
- 'use strict';
562
-
563
- var ws = null;
564
- var reconnectTimer = null;
565
- var reconnectAttempts = 0;
566
- var maxReconnectAttempts = 10;
567
-
568
- function connect() {
569
- var protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
570
- var wsUrl = protocol + '//' + location.host + '/__hmr__';
571
- ws = new WebSocket(wsUrl);
572
-
573
- ws.onopen = function() {
574
- reconnectAttempts = 0;
575
- console.log('[HMR] Connected');
576
- };
577
-
578
- ws.onmessage = function(event) {
579
- try {
580
- var update = JSON.parse(event.data);
581
-
582
- if (update.type === 'css') {
583
- handleCSSUpdate(update);
584
- } else if (update.type === 'update') {
585
- handleModuleUpdate(update);
586
- } else if (update.type === 'reload') {
587
- handleFullReload(update);
588
- }
589
- } catch (e) {
590
- console.error('[HMR] Failed to parse update:', e);
591
- }
592
- };
466
+ import fs from 'fs';
467
+ import path from 'path';
468
+ import { fileURLToPath } from 'url';
593
469
 
594
- ws.onclose = function() {
595
- console.log('[HMR] Disconnected');
596
- scheduleReconnect();
597
- };
470
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
471
+ const isProduction = process.env.NODE_ENV === 'production';
598
472
 
599
- ws.onerror = function() {
600
- ws.close();
601
- };
602
- }
473
+ async function createServer() {
474
+ let resolve: any;
475
+ let vite: any;
603
476
 
604
- function scheduleReconnect() {
605
- if (reconnectAttempts >= maxReconnectAttempts) {
606
- console.log('[HMR] Max reconnect attempts reached');
607
- return;
608
- }
609
- reconnectAttempts++;
610
- var delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
611
- console.log('[HMR] Reconnecting in ' + delay + 'ms (attempt ' + reconnectAttempts + ')');
612
- reconnectTimer = setTimeout(connect, delay);
477
+ if (!isProduction) {
478
+ const { createServer: createViteServer } = await import('vite');
479
+ vite = await createViteServer({
480
+ server: { middlewareMode: true },
481
+ appType: 'custom',
482
+ });
483
+ resolve = (id: string) => vite.resolveUrl(id);
484
+ } else {
485
+ resolve = (id: string) => id;
613
486
  }
614
487
 
615
- function handleCSSUpdate(update) {
616
- console.log('[HMR] CSS update:', update.path);
617
- // \u67E5\u627E\u6240\u6709 link[rel="stylesheet"] \u5E76\u91CD\u65B0\u52A0\u8F7D
618
- var links = document.querySelectorAll('link[rel="stylesheet"]');
619
- links.forEach(function(link) {
620
- var href = link.getAttribute('href');
621
- if (href && href.indexOf(update.path) !== -1) {
622
- var newLink = document.createElement('link');
623
- newLink.rel = 'stylesheet';
624
- newLink.href = href + (href.indexOf('?') !== -1 ? '&' : '?') + 't=' + Date.now();
625
- link.parentNode.replaceChild(newLink, link);
626
- }
627
- });
488
+ // TODO: Set up express/polka server and SSR rendering
489
+ console.log('LytJS SSR server starting...');
490
+ }
628
491
 
629
- // \u5982\u679C\u6709\u5185\u8054 CSS \u5185\u5BB9\uFF0C\u76F4\u63A5\u6CE8\u5165
630
- if (update.content) {
631
- var style = document.createElement('style');
632
- style.textContent = update.content;
633
- document.head.appendChild(style);
634
- }
492
+ createServer();
493
+ `;
494
+ writeFile(join(targetDir, "server.ts"), serverTs);
635
495
  }
636
-
637
- function handleModuleUpdate(update) {
638
- console.log('[HMR] Module update:', update.path);
639
- // \u5C1D\u8BD5\u70ED\u66F4\u65B0\u6A21\u5757
640
- if (typeof module !== 'undefined' && module.hot) {
641
- module.hot.accept(update.path, function() {
642
- console.log('[HMR] Module accepted:', update.path);
643
- });
496
+ const tsConfig = {
497
+ compilerOptions: {
498
+ target: "ES2020",
499
+ useDefineForClassFields: true,
500
+ module: "ESNext",
501
+ lib: ["ES2020", "DOM", "DOM.Iterable"],
502
+ skipLibCheck: true,
503
+ moduleResolution: "bundler",
504
+ allowImportingTsExtensions: true,
505
+ resolveJsonModule: true,
506
+ isolatedModules: true,
507
+ noEmit: true,
508
+ strict: true,
509
+ noUnusedLocals: true,
510
+ noUnusedParameters: true,
511
+ noFallthroughCasesInSwitch: true
512
+ },
513
+ include: ["src/**/*.ts", "src/**/*.lyt"],
514
+ references: [{ path: "./tsconfig.node.json" }]
515
+ };
516
+ writeFile(join(targetDir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
517
+ const tsConfigNode = {
518
+ compilerOptions: {
519
+ composite: true,
520
+ skipLibCheck: true,
521
+ module: "ESNext",
522
+ moduleResolution: "bundler",
523
+ allowSyntheticDefaultImports: true
524
+ },
525
+ include: ["vite.config.ts"]
526
+ };
527
+ writeFile(join(targetDir, "tsconfig.node.json"), JSON.stringify(tsConfigNode, null, 2));
528
+ const gitignore = `# Logs
529
+ logs
530
+ *.log
531
+ npm-debug.log*
532
+ yarn-debug.log*
533
+ yarn-error.log*
534
+ pnpm-debug.log*
535
+ lerna-debug.log*
536
+
537
+ node_modules
538
+ dist
539
+ dist-ssr
540
+ *.local
541
+
542
+ # Editor directories and files
543
+ .vscode/*
544
+ !.vscode/extensions.json
545
+ .idea
546
+ .DS_Store
547
+ *.suo
548
+ *.ntvs*
549
+ *.njsproj
550
+ *.sln
551
+ *.sw?
552
+ `;
553
+ writeFile(join(targetDir, ".gitignore"), gitignore);
554
+ }
555
+ function listTemplates() {
556
+ logger.bold("Available templates:");
557
+ for (const [name, description] of Object.entries(TEMPLATES)) {
558
+ logger.info(` ${name.padEnd(10)} - ${description}`);
559
+ }
560
+ }
561
+ async function dev(options = {}) {
562
+ if (!exists(join(process.cwd(), "package.json"))) {
563
+ logger.error("No package.json found. Are you in a LytJS project directory?");
564
+ process.exit(1);
565
+ }
566
+ const pm = detectPackageManager();
567
+ const runCmd = getRunCommand(pm, "dev");
568
+ logger.info(`Starting development server with ${pm}...`);
569
+ const devArgs = [];
570
+ if (options.port) devArgs.push("--port", String(options.port));
571
+ if (options.host) devArgs.push("--host", options.host);
572
+ if (options.open) devArgs.push("--open");
573
+ const cmdParts = runCmd.split(" ");
574
+ const cmd = cmdParts[0] ?? "pnpm";
575
+ const cmdArgs = [...cmdParts.slice(1), ...devArgs];
576
+ const child = spawn(cmd, cmdArgs, {
577
+ stdio: "inherit",
578
+ shell: true
579
+ });
580
+ child.on("error", (error) => {
581
+ logger.error(`Failed to start dev server: ${error.message}`);
582
+ process.exit(1);
583
+ });
584
+ child.on("exit", (code) => {
585
+ process.exit(code || 0);
586
+ });
587
+ }
588
+ async function build(options = {}) {
589
+ if (!exists(join(process.cwd(), "package.json"))) {
590
+ logger.error("No package.json found. Are you in a LytJS project directory?");
591
+ process.exit(1);
592
+ }
593
+ const pm = detectPackageManager();
594
+ logger.info("Building for production...");
595
+ const args = ["vite", "build"];
596
+ if (options.outDir) args.push("--outDir", options.outDir);
597
+ if (options.ssr) args.push("--ssr");
598
+ if (options.minify === false) args.push("--minify", "false");
599
+ const child = spawn(pm === "npm" ? "npx" : pm, args, {
600
+ stdio: "inherit",
601
+ shell: true
602
+ });
603
+ child.on("error", (error) => {
604
+ logger.error(`Build failed: ${error.message}`);
605
+ process.exit(1);
606
+ });
607
+ child.on("exit", (code) => {
608
+ if (code === 0) {
609
+ logger.success("Build completed successfully!");
644
610
  } else {
645
- // \u56DE\u9000\u5230\u5168\u91CF\u5237\u65B0
646
- console.log('[HMR] Full reload (module.hot not available)');
647
- location.reload();
611
+ logger.error(`Build failed with exit code ${code}`);
648
612
  }
613
+ process.exit(code || 0);
614
+ });
615
+ }
616
+ async function test(options = {}) {
617
+ if (!exists(join(process.cwd(), "package.json"))) {
618
+ logger.error("No package.json found. Are you in a LytJS project directory?");
619
+ process.exit(1);
649
620
  }
650
-
651
- function handleFullReload(update) {
652
- console.log('[HMR] Full reload:', update.path);
653
- location.reload();
654
- }
655
-
656
- // \u542F\u52A8\u8FDE\u63A5
657
- connect();
658
- })();`}var D=null;async function Oe(){if(!D)try{D=await import("esbuild")}catch(e){i.error("\u7F3A\u5C11\u4F9D\u8D56: esbuild"),i.error(""),i.error(" Lyt CLI \u7684\u5F00\u53D1\u670D\u52A1\u5668\u9700\u8981 esbuild \u6765\u5B9E\u65F6\u7F16\u8BD1 TypeScript\u3002"),i.error(""),i.error(" \u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B89\u88C5:"),i.error(` ${o("npm install esbuild --save-dev","brightGreen")}`),i.error(""),i.error(" \u5982\u679C\u60A8\u4F7F\u7528 pnpm:"),i.error(` ${o("pnpm add esbuild -D","brightGreen")}`),i.error(""),process.exit(1)}return D}function He(e,t){try{return D.transformSync(e,{loader:"ts",target:"es2018",format:"esm",sourcemap:"inline"}).code}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[Lyt CLI] \u7F16\u8BD1\u9519\u8BEF ${t||""}:`,r),e}}function Ge(e,t){var u;let n=((u=e.url)==null?void 0:u.split("?")[0])||"/";if(n==="/"&&(n="/index.html"),n.startsWith("/node_modules/")||n.startsWith("/@")){let c;if(n.startsWith("/@")&&!n.startsWith("/node_modules/")?c=x.join(t,"node_modules",n.slice(1)):c=x.join(t,n.slice(1)),n.match(/^\/(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/)&&!n.includes(".")){let m=x.join(c,"package.json");if(A.existsSync(m))try{let l=JSON.parse(S(m)),f=l.module||l.main||"index.js";l.exports&&(typeof l.exports=="string"?f=l.exports:typeof l.exports=="object"&&l.exports["."]&&(typeof l.exports["."]=="string"?f=l.exports["."]:l.exports["."].import?f=l.exports["."].import:l.exports["."].default?f=l.exports["."].default:Object.values(l.exports["."])[0]&&(f=Object.values(l.exports["."])[0]))),f.startsWith("./")&&(f=f.slice(2)),c=x.join(c,f)}catch(l){}}if(A.existsSync(c)&&A.statSync(c).isFile()){let m=x.extname(c).toLowerCase(),f={".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".json":"application/json; charset=utf-8"}[m]||"application/octet-stream",b=S(c);return{statusCode:200,headers:{"Content-Type":f},body:b}}}let r=x.join(t,n);if(!r.startsWith(t))return{statusCode:403,headers:{"Content-Type":"text/plain; charset=utf-8"},body:"403 Forbidden"};if(!A.existsSync(r)||!A.statSync(r).isFile())return{statusCode:404,headers:{"Content-Type":"text/plain; charset=utf-8"},body:"404 Not Found"};let s=x.extname(r).toLowerCase(),p={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".ts":"application/typescript; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".txt":"text/plain; charset=utf-8"}[s]||"application/octet-stream",d=S(r);return(s===".ts"||s===".tsx")&&(d=He(d,n)),s===".html"&&(d=d.replace("</head>",`<script>${J()}</script>
659
- </head>`)),{statusCode:200,headers:{"Content-Type":p},body:d}}async function V(e={}){let t=e.port||3e3,n=x.resolve(e.root||process.cwd()),r=e.hmr!==!1;await Oe();let s=te.createServer((d,u)=>{let c=Ge(d,n);u.writeHead(c.statusCode,c.headers),u.end(c.body)}),a=r?_(s):null;s.listen(t,()=>{console.log(""),console.log(o(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","brightCyan")),console.log(o(" \u2551","brightCyan")+o(" Lyt \u5F00\u53D1\u670D\u52A1\u5668\u5DF2\u542F\u52A8 ","brightWhite")+o("\u2551","brightCyan")),console.log(o(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","brightCyan")),console.log(""),console.log(` ${o("\u279C","brightGreen")} \u672C\u5730\u8BBF\u95EE: ${o(`http://localhost:${t}`,"brightBlue")}`),console.log(` ${o("\u279C","brightGreen")} \u7F51\u7EDC\u8BBF\u95EE: ${o(`http://127.0.0.1:${t}`,"brightBlue")}`),console.log(` ${o("\u279C","brightGreen")} \u9879\u76EE\u76EE\u5F55: ${o(n,"brightBlue")}`),console.log(` ${o("\u279C","brightGreen")} \u70ED\u66F4\u65B0: ${o(r?"\u5DF2\u5F00\u542F":"\u5DF2\u5173\u95ED",r?"brightGreen":"brightRed")}`),console.log(""),console.log(` ${o("\u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668","dim")}`),console.log("")}),s.on("error",d=>{d.code==="EADDRINUSE"?(i.error(`\u7AEF\u53E3 ${t} \u5DF2\u88AB\u5360\u7528\uFF0C\u8BF7\u4F7F\u7528 --port \u6307\u5B9A\u5176\u4ED6\u7AEF\u53E3`),process.exit(1)):(i.error(`\u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25: ${d.message}`),process.exit(1))});let p=()=>{i.info("\u6B63\u5728\u5173\u95ED\u5F00\u53D1\u670D\u52A1\u5668..."),s.close(()=>{i.success("\u670D\u52A1\u5668\u5DF2\u5173\u95ED"),process.exit(0)}),setTimeout(()=>{i.warn("\u670D\u52A1\u5668\u5173\u95ED\u8D85\u65F6\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)},5e3)};process.on("SIGINT",p),process.on("SIGTERM",p)}import*as y from"fs";import*as g from"path";var B=null;async function Le(){if(!B)try{B=await import("esbuild")}catch(e){i.error("\u7F3A\u5C11\u4F9D\u8D56: esbuild"),i.error(""),i.error(" Lyt CLI \u7684\u6784\u5EFA\u529F\u80FD\u9700\u8981 esbuild\u3002"),i.error(""),i.error(" \u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B89\u88C5:"),i.error(` ${o("npm install esbuild --save-dev","brightGreen")}`),i.error(""),i.error(" \u5982\u679C\u60A8\u4F7F\u7528 pnpm:"),i.error(` ${o("pnpm add esbuild -D","brightGreen")}`),i.error(""),process.exit(1)}return B}async function oe(e={}){let t=Date.now(),n=g.resolve(e.root||process.cwd()),r=g.resolve(n,e.outDir||"dist"),s=e.entry||"index.html",a=e.minify||!1;await Le(),i.info("\u5F00\u59CB\u6784\u5EFA\u9879\u76EE..."),i.info(` \u6839\u76EE\u5F55: ${o(n,"brightCyan")}`),i.info(` \u8F93\u51FA\u76EE\u5F55: ${o(r,"brightCyan")}`),i.info(` \u538B\u7F29: ${o(a?"\u5F00\u542F":"\u5173\u95ED",a?"brightGreen":"brightYellow")}`);let p=g.join(n,s);y.existsSync(p)||(i.error(`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728: ${p}`),process.exit(1));let d=S(p),u=/<script\s+type="module"\s+src="([^"]+)"\s*><\/script>/g,c,m=[];for(;(c=u.exec(d))!==null;)m.push(c[1]);m.length===0&&i.warn("\u672A\u5728\u5165\u53E3 HTML \u4E2D\u627E\u5230\u6A21\u5757\u811A\u672C\u5F15\u7528");let l={inputFiles:0,outputFiles:0,totalSize:0,buildTime:0};$(r),$(g.join(r,"assets"));for(let b of m){let P=g.join(n,b);if(!y.existsSync(P)){i.warn(`\u811A\u672C\u6587\u4EF6\u4E0D\u5B58\u5728: ${b}`);continue}i.info(`\u6B63\u5728\u6253\u5305: ${o(b,"brightYellow")}`);let E=`${g.basename(b,g.extname(b))}.bundle.js`,R=g.join(r,"assets",E);try{await B.build({entryPoints:[P],bundle:!0,minify:a,target:"es2018",format:"esm",outfile:R,sourcemap:!0,external:O=>O.startsWith("@lytjs/"),drop:a?["console"]:[],metafile:!0});let C=y.readFileSync(R,"utf-8");l.totalSize+=Buffer.byteLength(C,"utf-8"),l.outputFiles++;let k=R+".map";if(y.existsSync(k)){let O=y.readFileSync(k,"utf-8");l.totalSize+=Buffer.byteLength(O,"utf-8"),l.outputFiles++}d=d.replace(`<script type="module" src="${b}"></script>`,`<script src="/assets/${E}"></script>`),l.inputFiles++}catch(C){let k=C instanceof Error?C.message:String(C);i.error(`\u6253\u5305\u5931\u8D25 ${b}: ${k}`),process.exit(1)}}De(n,r,l);let f=g.join(r,"index.html");w(f,d),l.outputFiles++,l.totalSize+=Buffer.byteLength(d,"utf-8"),l.buildTime=Date.now()-t,console.log(""),i.success("\u6784\u5EFA\u5B8C\u6210\uFF01"),console.log(""),console.log(` ${o("\u8F93\u5165\u6587\u4EF6:","brightWhite")} ${l.inputFiles} \u4E2A`),console.log(` ${o("\u8F93\u51FA\u6587\u4EF6:","brightWhite")} ${l.outputFiles} \u4E2A`),console.log(` ${o("\u603B\u5927\u5C0F:","brightWhite")} ${Be(l.totalSize)}`),console.log(` ${o("\u6784\u5EFA\u8017\u65F6:","brightWhite")} ${l.buildTime}ms`),console.log(` ${o("\u8F93\u51FA\u76EE\u5F55:","brightWhite")} ${o(r,"brightCyan")}`),console.log("")}function De(e,t,n){let r=g.join(e,"src");if(!y.existsSync(r))return;function s(a,p){let d=y.readdirSync(a,{withFileTypes:!0});for(let u of d){let c=g.join(a,u.name);if(u.isDirectory()){if(u.name==="node_modules")continue;s(c,p)}else if(u.isFile()){let m=g.extname(u.name);if([".ts",".tsx",".js",".jsx"].includes(m))continue;let l=g.relative(p,c),f=g.join(t,l);if(/\.(png|jpe?g|gif|svg|ico|woff2?|ttf|eot|mp[34]|webm|avi|pdf|zip|gz)$/i.test(c)){let P=y.readFileSync(c);w(f,P)}else w(f,y.readFileSync(c).toString("utf-8"));n.outputFiles++,n.totalSize+=y.statSync(c).size}}}s(r,r)}function Be(e){if(e===0)return"0 B";let t=["B","KB","MB","GB"],n=1024,r=Math.floor(Math.log(e)/Math.log(n));return`${(e/Math.pow(n,r)).toFixed(2)} ${t[r]}`}import*as M from"fs";import*as ne from"path";var Y=`
660
- ${o("lytx generate","brightCyan")} - \u751F\u6210\u4EE3\u7801\uFF08\u7EC4\u4EF6\u3001Store\u3001\u9875\u9762\u3001API\uFF09
661
-
662
- ${o("\u7528\u6CD5:","brightGreen")}
663
- lytx generate <type> <name> [options]
664
-
665
- ${o("\u53C2\u6570:","brightGreen")}
666
- ${o("<type>","brightYellow")} \u751F\u6210\u7C7B\u578B (component, store, page, api)
667
- ${o("<name>","brightYellow")} \u540D\u79F0
668
-
669
- ${o("\u9009\u9879:","brightGreen")}
670
- ${o("--ai","brightYellow")} \u4F7F\u7528 AI \u751F\u6210\uFF08\u9700\u8981\u914D\u7F6E API Key\uFF09
671
- ${o("--no-ai","brightYellow")} \u4E0D\u4F7F\u7528 AI\uFF08\u6A21\u677F\u751F\u6210\uFF09
672
- ${o("-t, --type <type>","brightYellow")} \u7EC4\u4EF6\u7C7B\u578B (button, input, form, card, list, table, modal, dropdown, tabs, navigation, custom)
673
- ${o("-o, --output <path>","brightYellow")}\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84
674
- ${o("--no-style","brightYellow")} \u4E0D\u6DFB\u52A0\u6837\u5F0F
675
- ${o("--api-key <key>","brightYellow")} AI API Key
676
- ${o("--model <model>","brightYellow")} AI \u6A21\u578B\u540D\u79F0
677
- ${o("--provider <name>","brightYellow")} AI \u63D0\u4F9B\u5546 (openai, anthropic, custom)
678
- ${o("--base-url <url>","brightYellow")} AI API \u57FA\u7840 URL
679
-
680
- ${o("\u793A\u4F8B:","brightGreen")}
681
- ${o("$","dim")} lytx generate component MyButton
682
- ${o("$","dim")} lytx generate component MyButton --type button
683
- ${o("$","dim")} lytx generate component MyButton --type button --ai
684
- ${o("$","dim")} lytx generate store counter
685
- ${o("$","dim")} lytx generate page Home
686
- ${o("$","dim")} lytx generate api users
687
- `;function Ye(e){let t={type:"component",name:"",useAI:!1,style:!0};for(let n=0;n<e.length;n++){let r=e[n];r==="--ai"?t.useAI=!0:r==="--no-ai"?t.useAI=!1:r==="-t"||r==="--type"?t.componentType=e[++n]:r==="-o"||r==="--output"?t.outputPath=e[++n]:r==="--no-style"?t.style=!1:r==="--api-key"?t.apiKey=e[++n]:r==="--model"?t.model=e[++n]:r==="--provider"?t.provider=e[++n]:r==="--base-url"?t.baseUrl=e[++n]:r==="-d"||r==="--description"?t.description=e[++n]:!t.type&&["component","store","page","api"].includes(r)?t.type=r:!t.name&&!r.startsWith("-")&&(t.name=r)}return t}function Ue(e,t){let n=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),r=t.componentType||"functional",s={functional:`<!-- ${e} \u7EC4\u4EF6 -->
688
- <template>
689
- <div class="${n}">
690
- <slot></slot>
621
+ const pm = detectPackageManager();
622
+ logger.info("Running tests...");
623
+ const args = ["vitest"];
624
+ if (options.watch === false) args.push("run");
625
+ if (options.coverage) args.push("--coverage");
626
+ if (options.grep) args.push("--grep", options.grep);
627
+ const child = spawn(pm === "npm" ? "npx" : pm, args, {
628
+ stdio: "inherit",
629
+ shell: true
630
+ });
631
+ child.on("error", (error) => {
632
+ logger.error(`Tests failed: ${error.message}`);
633
+ process.exit(1);
634
+ });
635
+ child.on("exit", (code) => {
636
+ process.exit(code || 0);
637
+ });
638
+ }
639
+ var TEMPLATES2 = {
640
+ component(name, basePath) {
641
+ const filePath = join(basePath, `${name}.lyt`);
642
+ return [{
643
+ filePath,
644
+ content: `<template>
645
+ <div class="${name}">
646
+ <slot />
691
647
  </div>
692
648
  </template>
693
649
 
694
- <script setup>
695
- // \u7EC4\u4EF6\u903B\u8F91
650
+ <script setup lang="ts">
651
+ defineProps<{
652
+ /** Component props */
653
+ }>();
654
+
655
+ defineEmits<{
656
+ /** Component events */
657
+ }>();
696
658
  </script>
697
659
 
698
660
  <style scoped>
699
- .${n} {
700
- /* \u6837\u5F0F */
661
+ .${name} {
662
+ /* styles */
701
663
  }
702
664
  </style>
703
- `,button:`<!-- ${e} \u6309\u94AE\u7EC4\u4EF6 -->
704
- <template>
705
- <button class="${n}" :disabled="disabled" @click="handleClick">
706
- <slot></slot>
707
- </button>
665
+ `
666
+ }];
667
+ },
668
+ page(name, basePath) {
669
+ const filePath = join(basePath, `${name}.lyt`);
670
+ return [{
671
+ filePath,
672
+ content: `<template>
673
+ <div class="page-${name}">
674
+ <h1>${toPascalCase(name)}</h1>
675
+ </div>
708
676
  </template>
709
677
 
710
- <script setup>
711
- import { defineProps, defineEmits } from '@lytjs/core';
678
+ <script setup lang="ts">
679
+ // Page logic here
680
+ </script>
712
681
 
713
- const props = defineProps({
714
- disabled: {
715
- type: Boolean,
716
- default: false
682
+ <style scoped>
683
+ .page-${name} {
684
+ padding: 1rem;
685
+ }
686
+ </style>
687
+ `
688
+ }];
689
+ },
690
+ store(name, basePath) {
691
+ const filePath = join(basePath, `${name}.ts`);
692
+ return [{
693
+ filePath,
694
+ content: `import { defineStore } from '@lytjs/store';
695
+ import { signal, computed } from '@lytjs/reactivity';
696
+
697
+ export const use${toPascalCase(name)}Store = defineStore('${name}', () => {
698
+ // State
699
+ const count = signal(0);
700
+
701
+ // Getters
702
+ const doubleCount = computed(() => count.value * 2);
703
+
704
+ // Actions
705
+ function increment() {
706
+ count.value++;
717
707
  }
718
- });
719
708
 
720
- const emit = defineEmits(['click']);
709
+ function decrement() {
710
+ count.value--;
711
+ }
721
712
 
722
- function handleClick(event) {
723
- emit('click', event);
724
- }
725
- </script>
713
+ function reset() {
714
+ count.value = 0;
715
+ }
726
716
 
727
- <style scoped>
728
- .${n} {
729
- padding: 8px 16px;
730
- border: none;
731
- border-radius: 4px;
732
- background: #3b82f6;
733
- color: white;
734
- cursor: pointer;
735
- font-size: 14px;
717
+ return {
718
+ count,
719
+ doubleCount,
720
+ increment,
721
+ decrement,
722
+ reset,
723
+ };
724
+ });
725
+ `
726
+ }];
727
+ }
728
+ };
729
+ function toPascalCase(str) {
730
+ return str.split(/[-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
736
731
  }
737
-
738
- .${n}:hover:not(:disabled) {
739
- background: #2563eb;
732
+ function resolveTargetDir(type) {
733
+ const cwd = process.cwd();
734
+ switch (type) {
735
+ case "component":
736
+ return join(cwd, "src", "components");
737
+ case "page":
738
+ return join(cwd, "src", "pages");
739
+ case "store":
740
+ return join(cwd, "src", "stores");
741
+ }
740
742
  }
741
-
742
- .${n}:disabled {
743
- background: #9ca3af;
744
- cursor: not-allowed;
743
+ async function add(type, name, options = {}) {
744
+ const targetDir = resolveTargetDir(type);
745
+ const fullPath = resolve(targetDir);
746
+ if (!exists(join(process.cwd(), "package.json"))) {
747
+ logger.error("No package.json found. Are you in a LytJS project directory?");
748
+ process.exit(1);
749
+ }
750
+ const template = TEMPLATES2[type];
751
+ if (!template) {
752
+ logger.error(`Unknown type: ${type}. Supported types: component, page, store`);
753
+ process.exit(1);
754
+ }
755
+ const files = template(name, fullPath);
756
+ for (const file of files) {
757
+ if (exists(file.filePath) && !options.force) {
758
+ logger.warning(`File already exists: ${file.filePath}`);
759
+ logger.info("Use --force to overwrite.");
760
+ continue;
761
+ }
762
+ ensureDir(resolve(file.filePath, ".."));
763
+ writeFile(file.filePath, file.content);
764
+ logger.success(`Created ${type}: ${file.filePath}`);
765
+ }
745
766
  }
746
- </style>
747
- `,input:`<!-- ${e} \u8F93\u5165\u6846\u7EC4\u4EF6 -->
748
- <template>
749
- <div class="${n}">
750
- <input
751
- :value="modelValue"
752
- :type="type"
753
- :placeholder="placeholder"
754
- :disabled="disabled"
755
- @input="handleInput"
756
- @change="handleChange"
757
- />
758
- </div>
759
- </template>
767
+ var PLUGIN_TEMPLATES = {
768
+ default: "Default plugin template with TypeScript",
769
+ minimal: "Minimal plugin without extra dependencies",
770
+ withConfig: "Plugin template with configuration schema"
771
+ };
772
+ function getTemplateContent(template, pluginName) {
773
+ const packageName = `@lytjs/plugin-${pluginName}`;
774
+ const files = {};
775
+ files["package.json"] = JSON.stringify({
776
+ name: packageName,
777
+ version: "0.1.0",
778
+ description: `LytJS plugin: ${pluginName}`,
779
+ main: "dist/index.cjs",
780
+ module: "dist/index.mjs",
781
+ types: "dist/index.d.ts",
782
+ exports: {
783
+ ".": {
784
+ import: "./dist/index.mjs",
785
+ require: "./dist/index.cjs",
786
+ types: "./dist/index.d.ts"
787
+ }
788
+ },
789
+ files: ["dist"],
790
+ scripts: {
791
+ build: "tsup",
792
+ dev: "tsup --watch",
793
+ test: "vitest",
794
+ lint: "eslint src",
795
+ "prepublishOnly": "npm run build"
796
+ },
797
+ keywords: ["lytjs", "plugin"],
798
+ license: "MIT",
799
+ peerDependencies: {
800
+ "@lytjs/core": ">=6.0.0"
801
+ }
802
+ }, null, 2);
803
+ files["tsconfig.json"] = JSON.stringify({
804
+ extends: "@lytjs/core/tsconfig.json",
805
+ compilerOptions: {
806
+ outDir: "./dist",
807
+ rootDir: "./src",
808
+ declaration: true,
809
+ declarationMap: true
810
+ },
811
+ include: ["src"],
812
+ exclude: ["node_modules", "dist", "tests"]
813
+ }, null, 2);
814
+ files["tsup.config.ts"] = `import { defineConfig } from 'tsup';
815
+
816
+ export default defineConfig({
817
+ entry: { index: 'src/index.ts' },
818
+ format: ['esm', 'cjs'],
819
+ dts: true,
820
+ sourcemap: true,
821
+ clean: true,
822
+ splitting: false,
823
+ treeshake: true,
824
+ minify: false,
825
+ external: ['@lytjs/core'],
826
+ });
827
+ `;
828
+ if (template === "withConfig") {
829
+ files["src/index.ts"] = `/**
830
+ * @lytjs/plugin-${pluginName}
831
+ *
832
+ * A LytJS plugin with configuration schema support.
833
+ */
760
834
 
761
- <script setup>
762
- import { defineProps, defineEmits } from '@lytjs/core';
835
+ import { definePlugin } from '@lytjs/core';
836
+ import type { ConfigSchema } from '@lytjs/core';
763
837
 
764
- const props = defineProps({
765
- modelValue: {
766
- type: [String, Number],
767
- default: ''
768
- },
769
- type: {
770
- type: String,
771
- default: 'text'
772
- },
773
- placeholder: {
774
- type: String,
775
- default: ''
838
+ /**
839
+ * Plugin options schema
840
+ */
841
+ const optionsSchema: ConfigSchema<${pluginName.replace(/-/g, "")}Options> = {
842
+ type: 'object',
843
+ properties: {
844
+ debug: {
845
+ type: 'boolean',
846
+ description: 'Enable debug mode',
847
+ default: false,
848
+ },
849
+ option1: {
850
+ type: 'string',
851
+ description: 'First option',
852
+ default: 'default value',
853
+ },
776
854
  },
777
- disabled: {
778
- type: Boolean,
779
- default: false
780
- }
781
- });
855
+ additionalProperties: false,
856
+ };
782
857
 
783
- const emit = defineEmits(['update:modelValue', 'change']);
858
+ ${pluginName.replace(/-/g, "")}Options\`;
784
859
 
785
- function handleInput(event) {
786
- emit('update:modelValue', event.target.value);
860
+ export interface ${pluginName.replace(/-/g, "")}Options {
861
+ debug?: boolean;
862
+ option1?: string;
787
863
  }
788
864
 
789
- function handleChange(event) {
790
- emit('change', event.target.value);
865
+ /**
866
+ * Create the plugin with configuration schema
867
+ */
868
+ export function create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}(options?: ${pluginName.replace(/-/g, "")}Options) {
869
+ return definePlugin({
870
+ name: '${packageName}',
871
+ version: '0.1.0',
872
+ description: 'A LytJS plugin',
873
+ schema: optionsSchema,
874
+ install: (app, opts) => {
875
+ const config = opts || {};
876
+ console.log('[${packageName}] Installing with config:', config);
877
+ },
878
+ });
791
879
  }
792
- </script>
793
880
 
794
- <style scoped>
795
- .${n} input {
796
- padding: 8px 12px;
797
- border: 1px solid #d1d5db;
798
- border-radius: 4px;
799
- font-size: 14px;
800
- outline: none;
801
- }
881
+ /**
882
+ * Direct plugin export (without schema)
883
+ */
884
+ export default create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}();
885
+ `;
886
+ } else {
887
+ files["src/index.ts"] = `/**
888
+ * @lytjs/plugin-${pluginName}
889
+ *
890
+ * A LytJS plugin.
891
+ */
802
892
 
803
- .${n} input:focus {
804
- border-color: #3b82f6;
805
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
893
+ import { definePlugin } from '@lytjs/core';
894
+
895
+ /**
896
+ * Create the plugin
897
+ */
898
+ export function create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}() {
899
+ return definePlugin({
900
+ name: '${packageName}',
901
+ version: '0.1.0',
902
+ description: 'A LytJS plugin',
903
+ install: (app) => {
904
+ console.log('[${packageName}] Plugin installed');
905
+ },
906
+ });
806
907
  }
807
- </style>
808
- `,card:`<!-- ${e} \u5361\u7247\u7EC4\u4EF6 -->
809
- <template>
810
- <div class="${n}">
811
- <div class="${n}-header" if="$slots.header">
812
- <slot name="header"></slot>
813
- </div>
814
- <div class="${n}-body">
815
- <slot></slot>
816
- </div>
817
- <div class="${n}-footer" if="$slots.footer">
818
- <slot name="footer"></slot>
819
- </div>
820
- </div>
821
- </template>
822
908
 
823
- <script setup>
824
- // \u7EC4\u4EF6\u903B\u8F91
825
- </script>
909
+ /**
910
+ * Direct plugin export
911
+ */
912
+ export default create${pluginName.replace(/-/g, "").replace(/^\w/, (c) => c.toUpperCase())}();
913
+ `;
914
+ }
915
+ if (template === "minimal") {
916
+ files["src/types.ts"] = `/**
917
+ * Plugin types
918
+ */
826
919
 
827
- <style scoped>
828
- .${n} {
829
- background: white;
830
- border-radius: 8px;
831
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
832
- overflow: hidden;
920
+ export interface PluginOptions {
921
+ // Define your plugin options here
833
922
  }
923
+ `;
924
+ }
925
+ files["README.md"] = `# @lytjs/plugin-${pluginName}
834
926
 
835
- .${n}-header,
836
- .${n}-body,
837
- .${n}-footer {
838
- padding: 16px;
839
- }
927
+ A LytJS plugin.
840
928
 
841
- .${n}-header {
842
- border-bottom: 1px solid #e5e7eb;
843
- }
929
+ ## Installation
844
930
 
845
- .${n}-footer {
846
- border-top: 1px solid #e5e7eb;
847
- }
848
- </style>
849
- `};return s[r]||s.functional}function Ne(e){let t=e.charAt(0).toLowerCase()+e.slice(1);return`/**
850
- * ${e} Store
851
- */
931
+ \`\`\`bash
932
+ npm install @lytjs/plugin-${pluginName}
933
+ \`\`\`
852
934
 
853
- import { createStore } from '@lytjs/store';
935
+ ## Usage
854
936
 
855
- export const ${t}Store = createStore('${e}', {
856
- state: {
857
- // \u72B6\u6001\u5B9A\u4E49
858
- count: 0
859
- },
937
+ \`\`\`typescript
938
+ import { createApp } from '@lytjs/core';
939
+ import myPlugin from '@lytjs/plugin-${pluginName}';
860
940
 
861
- getters: {
862
- // \u8BA1\u7B97\u5C5E\u6027
863
- double: state => state.count * 2
864
- },
941
+ const app = createApp(App);
942
+ app.use(myPlugin);
943
+ \`\`\`
865
944
 
866
- actions: {
867
- // \u65B9\u6CD5\u5B9A\u4E49
868
- increment(state) {
869
- state.count++;
870
- },
945
+ ## API
871
946
 
872
- decrement(state) {
873
- state.count--;
874
- }
875
- }
876
- });
877
- `}function ze(e){let t=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();return`<!-- ${e} \u9875\u9762 -->
878
- <template>
879
- <div class="${t}-page">
880
- <h1>${e}</h1>
881
- <slot></slot>
882
- </div>
883
- </template>
947
+ ### createPlugin(options?)
884
948
 
885
- <script setup>
886
- import { ref, computed } from '@lytjs/reactivity';
949
+ Create the plugin with options.
887
950
 
888
- // \u9875\u9762\u903B\u8F91
889
- </script>
951
+ ## License
890
952
 
891
- <style scoped>
892
- .${t}-page {
893
- padding: 20px;
894
- }
895
- </style>
896
- `}function We(e){return`/**
897
- * ${e} API
898
- */
953
+ MIT
954
+ `;
955
+ files[".gitignore"] = `# Logs
956
+ logs
957
+ *.log
958
+ npm-debug.log*
959
+ yarn-debug.log*
960
+ pnpm-debug.log*
899
961
 
900
- export default async function handler(req, res) {
901
- const method = req.method;
962
+ node_modules
963
+ dist
964
+ *.local
902
965
 
903
- switch (method) {
904
- case 'GET':
905
- // \u83B7\u53D6\u8D44\u6E90
906
- res.json({
907
- success: true,
908
- message: 'Get ${e}',
909
- data: []
966
+ # IDE
967
+ .vscode
968
+ .idea
969
+ *.sw?
970
+ `;
971
+ return files;
972
+ }
973
+ async function createPlugin(name, options = {}) {
974
+ const targetDir = resolve(process.cwd(), name);
975
+ const template = options.template || "default";
976
+ if (template !== "default" && template !== "minimal" && template !== "withConfig") {
977
+ logger.error(`Unknown template: ${template}`);
978
+ logger.info("Available templates: default, minimal, withConfig");
979
+ process.exit(1);
980
+ }
981
+ if (existsSync(targetDir) && !isEmptyDir2(targetDir) && !options.force) {
982
+ logger.error(`Directory "${name}" already exists and is not empty.`);
983
+ logger.info("Use --force to overwrite.");
984
+ process.exit(1);
985
+ }
986
+ logger.info(`Creating a new LytJS plugin in ${targetDir}...`);
987
+ ensureDir(targetDir);
988
+ const files = getTemplateContent(template, name);
989
+ for (const [filePath, content] of Object.entries(files)) {
990
+ const fullPath = join(targetDir, filePath);
991
+ const fileDir = resolve(fullPath, "..");
992
+ if (!existsSync(fileDir)) {
993
+ mkdirSync(fileDir, { recursive: true });
994
+ }
995
+ writeFileSync(fullPath, content, "utf-8");
996
+ logger.success(`Created: ${filePath}`);
997
+ }
998
+ if (!options.skipInstall) {
999
+ logger.info("Installing dependencies...");
1000
+ try {
1001
+ execSync("pnpm install", { cwd: targetDir, stdio: "inherit" });
1002
+ logger.success("Dependencies installed!");
1003
+ } catch (_error) {
1004
+ logger.warning("Failed to install dependencies automatically.");
1005
+ logger.info('Please run "pnpm install" manually.');
1006
+ }
1007
+ }
1008
+ logger.success(`Plugin "${name}" created successfully!`);
1009
+ logger.info("");
1010
+ logger.bold("Next steps:");
1011
+ logger.info(` cd ${name}`);
1012
+ logger.info(" pnpm dev # Start development");
1013
+ logger.info(" pnpm build # Build for production");
1014
+ logger.info(" pnpm test # Run tests");
1015
+ }
1016
+ async function buildPlugin(options = {}) {
1017
+ const cwd = process.cwd();
1018
+ const outDir = options.outDir || "dist";
1019
+ const pkgPath = join(cwd, "package.json");
1020
+ if (!existsSync(pkgPath)) {
1021
+ logger.error("No package.json found. Are you in a plugin directory?");
1022
+ process.exit(1);
1023
+ }
1024
+ logger.info("Building plugin...");
1025
+ try {
1026
+ const buildCmd = "tsup";
1027
+ const args = ["--entry", "src/index.ts", "--outDir", outDir, "--format", "esm,cjs", "--dts", "--sourcemap"];
1028
+ if (options.minify) {
1029
+ args.push("--minify");
1030
+ }
1031
+ execSync(`${buildCmd} ${args.join(" ")}`, { cwd, stdio: "inherit" });
1032
+ logger.success("Build completed!");
1033
+ logger.info(`Output: ${join(cwd, outDir)}`);
1034
+ } catch (_error) {
1035
+ logger.error("Build failed. Make sure tsup is installed: pnpm add -D tsup");
1036
+ process.exit(1);
1037
+ }
1038
+ }
1039
+ async function validatePlugin(options = {}) {
1040
+ const cwd = process.cwd();
1041
+ logger.info("Validating plugin...");
1042
+ const errors = [];
1043
+ const warnings = [];
1044
+ const pkgPath = join(cwd, "package.json");
1045
+ if (!existsSync(pkgPath)) {
1046
+ errors.push("package.json not found");
1047
+ } else {
1048
+ try {
1049
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
1050
+ if (!pkg.name) errors.push("package.json: name is required");
1051
+ if (!pkg.version) errors.push("package.json: version is required");
1052
+ if (!pkg.main) errors.push("package.json: main is required");
1053
+ if (!pkg.module) errors.push("package.json: module is required");
1054
+ if (!pkg.types) errors.push("package.json: types is required");
1055
+ if (!pkg.exports) {
1056
+ warnings.push("package.json: exports field is recommended");
1057
+ }
1058
+ if (!pkg.peerDependencies || !pkg.peerDependencies["@lytjs/core"]) {
1059
+ errors.push("package.json: @lytjs/core peerDependency is required");
1060
+ }
1061
+ if (!pkg.keywords || !pkg.keywords.includes("lytjs")) {
1062
+ warnings.push('package.json: "lytjs" keyword is recommended');
1063
+ }
1064
+ } catch (err) {
1065
+ errors.push(`package.json: Invalid JSON - ${err}`);
1066
+ }
1067
+ }
1068
+ const srcPath = join(cwd, "src");
1069
+ if (!existsSync(srcPath)) {
1070
+ errors.push("src directory not found");
1071
+ } else {
1072
+ const indexPath = join(srcPath, "index.ts");
1073
+ if (!existsSync(indexPath)) {
1074
+ errors.push("src/index.ts not found");
1075
+ } else {
1076
+ const content = readFileSync(indexPath, "utf-8");
1077
+ if (!content.includes("definePlugin") && !content.includes("EnhancedPlugin")) {
1078
+ warnings.push("src/index.ts: Consider using definePlugin or EnhancedPlugin");
1079
+ }
1080
+ if (!content.includes("export")) {
1081
+ warnings.push("src/index.ts: No exports found");
1082
+ }
1083
+ }
1084
+ }
1085
+ const tsconfigPath = join(cwd, "tsconfig.json");
1086
+ if (!existsSync(tsconfigPath)) {
1087
+ warnings.push("tsconfig.json not found (recommended)");
1088
+ }
1089
+ const tsupConfigPath = join(cwd, "tsup.config.ts");
1090
+ if (!existsSync(tsupConfigPath)) {
1091
+ warnings.push("tsup.config.ts not found (recommended for builds)");
1092
+ }
1093
+ let hasErrors = errors.length > 0;
1094
+ let hasWarnings = warnings.length > 0;
1095
+ if (hasErrors) {
1096
+ logger.error("Validation failed with errors:");
1097
+ for (const err of errors) {
1098
+ logger.error(` - ${err}`);
1099
+ }
1100
+ }
1101
+ if (hasWarnings && !options.strict) {
1102
+ logger.warning("Warnings:");
1103
+ for (const warn of warnings) {
1104
+ logger.warning(` - ${warn}`);
1105
+ }
1106
+ }
1107
+ if (!hasErrors && !hasWarnings) {
1108
+ logger.success("Plugin validation passed!");
1109
+ } else if (hasWarnings && !hasErrors) {
1110
+ logger.success("Plugin validation passed (with warnings)");
1111
+ if (options.strict) {
1112
+ process.exit(1);
1113
+ }
1114
+ } else {
1115
+ if (options.warningsAsErrors && hasWarnings) {
1116
+ logger.error("Strict mode: treating warnings as errors");
1117
+ }
1118
+ process.exit(1);
1119
+ }
1120
+ }
1121
+ function isEmptyDir2(dir) {
1122
+ if (!existsSync(dir)) return true;
1123
+ const files = __require("fs").readdirSync(dir);
1124
+ return files.length === 0;
1125
+ }
1126
+ function listPluginTemplates() {
1127
+ logger.bold("Available plugin templates:");
1128
+ for (const [name, description] of Object.entries(PLUGIN_TEMPLATES)) {
1129
+ logger.info(` ${name.padEnd(12)} - ${description}`);
1130
+ }
1131
+ }
1132
+
1133
+ // src/commands/run.ts
1134
+ var VERSION = "6.0.0";
1135
+ async function runCli(rawArgs = process.argv.slice(2)) {
1136
+ const { command, args, options } = parseArgs(rawArgs);
1137
+ if (options.help || command === "help") {
1138
+ showHelp();
1139
+ return;
1140
+ }
1141
+ if (options.version || command === "version" || command === "-v" || command === "--version") {
1142
+ console.log(`LytJS CLI v${VERSION}`);
1143
+ return;
1144
+ }
1145
+ switch (command) {
1146
+ case "create":
1147
+ await create(args[0] || "my-lytjs-app", {
1148
+ template: options.template,
1149
+ force: options.force
910
1150
  });
911
1151
  break;
912
-
913
- case 'POST':
914
- // \u521B\u5EFA\u8D44\u6E90
915
- res.status(201).json({
916
- success: true,
917
- message: 'Create ${e}',
918
- data: {}
1152
+ case "templates":
1153
+ listTemplates();
1154
+ break;
1155
+ case "dev":
1156
+ await dev({
1157
+ port: options.port ? parseInt(options.port, 10) : void 0,
1158
+ host: options.host,
1159
+ open: options.open
919
1160
  });
920
1161
  break;
921
-
922
- case 'PUT':
923
- // \u66F4\u65B0\u8D44\u6E90
924
- res.json({
925
- success: true,
926
- message: 'Update ${e}'
1162
+ case "build":
1163
+ await build({
1164
+ outDir: options.outDir,
1165
+ ssr: options.ssr,
1166
+ minify: options.minify !== "false"
927
1167
  });
928
1168
  break;
929
-
930
- case 'DELETE':
931
- // \u5220\u9664\u8D44\u6E90
932
- res.json({
933
- success: true,
934
- message: 'Delete ${e}'
1169
+ case "test":
1170
+ await test({
1171
+ watch: options.watch !== "false",
1172
+ coverage: options.coverage,
1173
+ grep: options.grep
935
1174
  });
936
1175
  break;
937
-
938
- default:
939
- res.status(405).json({
940
- success: false,
941
- message: 'Method not allowed'
1176
+ case "add":
1177
+ if (!args[0] || !["component", "page", "store"].includes(args[0])) {
1178
+ logger.error("Usage: lyt add <component|page|store> <name>");
1179
+ logger.info("Example: lyt add component Button");
1180
+ process.exit(1);
1181
+ }
1182
+ await add(args[0], args[1] || "Unnamed", {
1183
+ force: options.force
942
1184
  });
1185
+ break;
1186
+ case "plugin":
1187
+ if (!args[0]) {
1188
+ logger.error("Usage: lyt plugin <create|build|validate|templates>");
1189
+ logger.info("Example: lyt plugin create my-plugin");
1190
+ process.exit(1);
1191
+ }
1192
+ const subCommand = args[0];
1193
+ switch (subCommand) {
1194
+ case "create":
1195
+ await createPlugin(args[1] || "my-plugin", {
1196
+ template: options.template,
1197
+ force: options.force,
1198
+ skipInstall: options.skipInstall
1199
+ });
1200
+ break;
1201
+ case "build":
1202
+ await buildPlugin({
1203
+ outDir: options.outDir,
1204
+ minify: options.minify,
1205
+ sourcemap: options.sourcemap
1206
+ });
1207
+ break;
1208
+ case "validate":
1209
+ await validatePlugin({
1210
+ strict: options.strict,
1211
+ warningsAsErrors: options.warningsAsErrors
1212
+ });
1213
+ break;
1214
+ case "templates":
1215
+ listPluginTemplates();
1216
+ break;
1217
+ default:
1218
+ logger.error(`Unknown plugin sub-command: ${subCommand}`);
1219
+ logger.info("Supported sub-commands: create, build, validate, templates");
1220
+ process.exit(1);
1221
+ }
1222
+ break;
1223
+ default:
1224
+ if (command) {
1225
+ logger.error(`Unknown command: ${command}`);
1226
+ logger.info('Run "lyt --help" for usage information.');
1227
+ process.exit(1);
1228
+ } else {
1229
+ showHelp();
1230
+ }
1231
+ }
1232
+ }
1233
+ function parseArgs(args) {
1234
+ let command = args[0] ?? "";
1235
+ const positional = [];
1236
+ const options = {};
1237
+ if (command.startsWith("--") || command.startsWith("-")) {
1238
+ command = "";
943
1239
  }
1240
+ const startIndex = command ? 1 : 0;
1241
+ for (let i = startIndex; i < args.length; i++) {
1242
+ const arg = args[i] ?? "";
1243
+ if (arg.startsWith("--")) {
1244
+ const parts = arg.slice(2).split("=");
1245
+ const key = parts[0];
1246
+ const value = parts[1];
1247
+ if (value !== void 0 && key) {
1248
+ options[key] = value;
1249
+ } else if (key && i + 1 < args.length && !(args[i + 1] ?? "").startsWith("-")) {
1250
+ const nextArg = args[++i];
1251
+ if (nextArg) {
1252
+ options[key] = nextArg;
1253
+ }
1254
+ } else if (key) {
1255
+ options[key] = true;
1256
+ }
1257
+ } else if (arg.startsWith("-")) {
1258
+ const key = arg.slice(1);
1259
+ if (key) {
1260
+ options[key] = true;
1261
+ }
1262
+ } else {
1263
+ positional.push(arg);
1264
+ }
1265
+ }
1266
+ return { command, args: positional, options };
1267
+ }
1268
+ function showHelp() {
1269
+ console.log(`
1270
+ ${logger.bold("LytJS CLI")} v${VERSION}
1271
+
1272
+ ${logger.bold("Usage:")}
1273
+ lyt <command> [options]
1274
+
1275
+ ${logger.bold("Commands:")}
1276
+ create <name> Create a new LytJS project
1277
+ templates List available templates
1278
+ dev Start development server
1279
+ build Build for production
1280
+ test Run tests
1281
+ add <type> <name> Generate a component, page, or store
1282
+ plugin <subcmd> Plugin development commands
1283
+ help Show this help message
1284
+
1285
+ ${logger.bold("Options:")}
1286
+ --version, -v Show version number
1287
+ --help Show help
1288
+
1289
+ ${logger.bold("Create Options:")}
1290
+ --template <name> Use a specific template
1291
+ --force Overwrite existing directory
1292
+
1293
+ ${logger.bold("Dev Options:")}
1294
+ --port <number> Specify port (default: 5173)
1295
+ --host <host> Specify host (default: localhost)
1296
+ --open Open browser on start
1297
+
1298
+ ${logger.bold("Build Options:")}
1299
+ --outDir <dir> Output directory (default: dist)
1300
+ --ssr Build for SSR
1301
+ --minify false Disable minification
1302
+
1303
+ ${logger.bold("Test Options:")}
1304
+ --watch false Run tests once (no watch mode)
1305
+ --coverage Generate coverage report
1306
+ --grep <pattern> Filter tests by pattern
1307
+
1308
+ ${logger.bold("Plugin Options:")}
1309
+ --template <name> Use a specific plugin template (default, minimal, withConfig)
1310
+ --force Overwrite existing directory
1311
+ --skipInstall Skip installing dependencies
1312
+ --outDir <dir> Output directory (default: dist)
1313
+ --minify Minify output
1314
+ --sourcemap Generate sourcemaps
1315
+ --strict Strict validation mode
1316
+ --warningsAsErrors Treat warnings as errors
1317
+
1318
+ ${logger.bold("Examples:")}
1319
+ lyt create my-app
1320
+ lyt create my-app --template minimal
1321
+ lyt create my-app --template router
1322
+ lyt create my-app --template full
1323
+ lyt dev --port 3000
1324
+ lyt build --ssr
1325
+ lyt add component Button
1326
+ lyt add page About
1327
+ lyt add store user
1328
+ lyt plugin create my-plugin
1329
+ lyt plugin create my-plugin --template withConfig
1330
+ lyt plugin build
1331
+ lyt plugin validate
1332
+ `);
944
1333
  }
945
- `}async function re(e){let t=Ye(e);t.type||(i.error("\u8BF7\u63D0\u4F9B\u751F\u6210\u7C7B\u578B (component, store, page, api)"),console.log(""),console.log(Y),process.exit(1)),t.name||(i.error("\u8BF7\u63D0\u4F9B\u540D\u79F0"),console.log(""),console.log(Y),process.exit(1)),i.info(`\u751F\u6210 ${t.type}: ${t.name}`),i.info(`\u4F7F\u7528 AI: ${t.useAI?"Yes":"No"}`);let n,r;switch(t.type){case"component":n=Ue(t.name,t),r=`./src/components/${t.name}.lyt`;break;case"store":n=Ne(t.name),r=`./src/stores/${t.name}.js`;break;case"page":n=ze(t.name),r=`./src/pages/${t.name}.lyt`;break;case"api":n=We(t.name),r=`./src/api/${t.name}.js`;break}let s=t.outputPath||r,a=ne.dirname(s);M.existsSync(a)||M.mkdirSync(a,{recursive:!0}),M.writeFileSync(s,n,"utf-8"),i.success(`\u6587\u4EF6\u5DF2\u4FDD\u5B58: ${s}`),t.useAI&&(console.log(""),console.log(o("\u63D0\u793A:","brightYellow")),console.log(" AI \u751F\u6210\u529F\u80FD\u9700\u8981\u5728\u9879\u76EE\u4E2D\u5B89\u88C5 @lytjs/ai"),console.log(" \u8BF7\u5148\u8FD0\u884C: lyt-ai init \u521D\u59CB\u5316\u914D\u7F6E"),console.log(""))}var _e="4.2.0",le="lytx",Je="Lyt.js \u6846\u67B6\u547D\u4EE4\u884C\u5DE5\u5177\uFF08\u589E\u5F3A\u7248\uFF09",se=`
946
- ${o(le,"brightCyan")} - ${Je}
947
-
948
- ${o("\u7528\u6CD5:","brightGreen")}
949
- lytx <command> [options] [args]
950
-
951
- ${o("\u547D\u4EE4:","brightGreen")}
952
- ${o("create","brightYellow")} <name> \u521B\u5EFA\u4E00\u4E2A\u65B0\u7684 Lyt \u9879\u76EE
953
- ${o("dev","brightYellow")} \u542F\u52A8\u672C\u5730\u5F00\u53D1\u670D\u52A1\u5668
954
- ${o("build","brightYellow")} \u6784\u5EFA\u751F\u4EA7\u7248\u672C
955
- ${o("preview","brightYellow")} \u9884\u89C8\u6784\u5EFA\u7ED3\u679C
956
- ${o("generate","brightYellow")} <type> <name> \u751F\u6210\u4EE3\u7801\uFF08\u7EC4\u4EF6\u3001Store\u3001\u9875\u9762\u3001API\uFF09
957
-
958
- ${o("\u5168\u5C40\u9009\u9879:","brightGreen")}
959
- ${o("-h, --help","brightYellow")} \u663E\u793A\u5E2E\u52A9\u4FE1\u606F
960
- ${o("-v, --version","brightYellow")} \u663E\u793A\u7248\u672C\u53F7
961
-
962
- ${o("\u793A\u4F8B:","brightGreen")}
963
- ${o("$","dim")} lytx create my-app
964
- ${o("$","dim")} lytx create my-app --template spa --ts --router --store
965
- ${o("$","dim")} lytx create my-todo --template todo-app
966
- ${o("$","dim")} lytx create my-admin --template admin-dashboard
967
- ${o("$","dim")} lytx dev
968
- ${o("$","dim")} lytx dev --port 8080 --hmr
969
- ${o("$","dim")} lytx build
970
- ${o("$","dim")} lytx build --mode ssr
971
- ${o("$","dim")} lytx preview --port 4173
972
-
973
- `;function Ve(){let e=N(),t="";for(let[n,r]of Object.entries(e))t+=` ${o(n,"brightYellow")} \u2014 ${r}
974
- `;return`
975
- ${o("lytx create","brightCyan")} - \u521B\u5EFA\u65B0\u7684 Lyt \u9879\u76EE
976
-
977
- ${o("\u7528\u6CD5:","brightGreen")}
978
- lytx create <name> [options]
979
-
980
- ${o("\u53C2\u6570:","brightGreen")}
981
- ${o("<name>","brightYellow")} \u9879\u76EE\u540D\u79F0\uFF08\u540C\u65F6\u4F5C\u4E3A\u76EE\u5F55\u540D\uFF09
982
-
983
- ${o("\u9009\u9879:","brightGreen")}
984
- ${o("--template <tpl>","brightYellow")} \u9879\u76EE\u6A21\u677F\uFF08\u9ED8\u8BA4: spa\uFF09
985
- ${t}
986
- ${o("--ts","brightYellow")} \u4F7F\u7528 TypeScript\uFF08\u4EC5\u5185\u7F6E\u6A21\u677F\uFF09
987
- ${o("--router","brightYellow")} \u5305\u542B\u8DEF\u7531\uFF08\u4EC5\u5185\u7F6E\u6A21\u677F\uFF09
988
- ${o("--store","brightYellow")} \u5305\u542B\u72B6\u6001\u7BA1\u7406\uFF08\u4EC5\u5185\u7F6E\u6A21\u677F\uFF09
989
- ${o("--eslint","brightYellow")} \u5305\u542B ESLint \u914D\u7F6E\uFF08\u4EC5\u5185\u7F6E\u6A21\u677F\uFF09
990
-
991
- ${o("\u793A\u4F8B:","brightGreen")}
992
- ${o("$","dim")} lytx create my-app
993
- ${o("$","dim")} lytx create my-app --template spa --ts --router --store
994
- ${o("$","dim")} lytx create my-todo --template todo-app
995
- ${o("$","dim")} lytx create my-admin --template admin-dashboard
996
- ${o("$","dim")} lytx create my-app --template ssr --ts
997
-
998
- `}var Ke=`
999
- ${o("lytx dev","brightCyan")} - \u542F\u52A8\u672C\u5730\u5F00\u53D1\u670D\u52A1\u5668
1000
-
1001
- ${o("\u7528\u6CD5:","brightGreen")}
1002
- lytx dev [options]
1003
-
1004
- ${o("\u9009\u9879:","brightGreen")}
1005
- ${o("-p, --port <port>","brightYellow")} \u670D\u52A1\u7AEF\u53E3\uFF08\u9ED8\u8BA4: 3000\uFF09
1006
- ${o("--hmr","brightYellow")} \u5F00\u542F\u70ED\u66F4\u65B0\uFF08\u9ED8\u8BA4: \u5F00\u542F\uFF09
1007
- ${o("--no-hmr","brightYellow")} \u5173\u95ED\u70ED\u66F4\u65B0
1008
-
1009
- ${o("\u529F\u80FD:","brightGreen")}
1010
- - \u9759\u6001\u6587\u4EF6\u670D\u52A1
1011
- - TypeScript \u5373\u65F6\u7F16\u8BD1
1012
- - \u70ED\u6A21\u5757\u66FF\u6362\uFF08HMR\uFF09
1013
- - WebSocket \u5B9E\u65F6\u901A\u4FE1
1014
-
1015
- ${o("\u793A\u4F8B:","brightGreen")}
1016
- ${o("$","dim")} lytx dev
1017
- ${o("$","dim")} lytx dev --port 8080
1018
- ${o("$","dim")} lytx dev --no-hmr
1019
-
1020
- `,qe=`
1021
- ${o("lytx build","brightCyan")} - \u6784\u5EFA\u751F\u4EA7\u7248\u672C
1022
-
1023
- ${o("\u7528\u6CD5:","brightGreen")}
1024
- lytx build [options]
1025
-
1026
- ${o("\u9009\u9879:","brightGreen")}
1027
- ${o("--mode <mode>","brightYellow")} \u6784\u5EFA\u6A21\u5F0F\uFF08\u9ED8\u8BA4: spa\uFF09
1028
- \u53EF\u9009\u503C: spa, ssr, ssg
1029
- ${o("--minify","brightYellow")} \u538B\u7F29\u4EE3\u7801\uFF08\u53BB\u9664\u7A7A\u767D\u548C\u6CE8\u91CA\uFF09
1030
- ${o("-o, --outDir <dir>","brightYellow")} \u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4: dist\uFF09
1031
- ${o("--entry <file>","brightYellow")} \u5165\u53E3\u6587\u4EF6\uFF08\u9ED8\u8BA4: index.html\uFF09
1032
-
1033
- ${o("\u529F\u80FD:","brightGreen")}
1034
- - TypeScript \u7F16\u8BD1
1035
- - \u6A21\u5757\u6253\u5305\uFF08\u5185\u8054\u4F9D\u8D56\uFF09
1036
- - \u53BB\u9664 console.log
1037
- - Source Map \u751F\u6210
1038
- - \u9759\u6001\u8D44\u6E90\u590D\u5236
1039
-
1040
- ${o("\u793A\u4F8B:","brightGreen")}
1041
- ${o("$","dim")} lytx build
1042
- ${o("$","dim")} lytx build --mode ssr
1043
- ${o("$","dim")} lytx build --minify --outDir ./output
1044
-
1045
- `,Ze=`
1046
- ${o("lytx preview","brightCyan")} - \u9884\u89C8\u6784\u5EFA\u7ED3\u679C
1047
-
1048
- ${o("\u7528\u6CD5:","brightGreen")}
1049
- lytx preview [options]
1050
-
1051
- ${o("\u9009\u9879:","brightGreen")}
1052
- ${o("-p, --port <port>","brightYellow")} \u670D\u52A1\u7AEF\u53E3\uFF08\u9ED8\u8BA4: 4173\uFF09
1053
-
1054
- ${o("\u793A\u4F8B:","brightGreen")}
1055
- ${o("$","dim")} lytx preview
1056
- ${o("$","dim")} lytx preview --port 5000
1057
-
1058
- `;function Xe(){console.log(""),console.log(` ${o(le,"brightCyan")} v${o(_e,"brightWhite")}`),console.log("")}function Qe(e){i.error(`\u672A\u77E5\u547D\u4EE4: ${o(e,"brightRed")}`),console.log(""),console.log(` \u8FD0\u884C ${o("lytx --help","brightCyan")} \u67E5\u770B\u53EF\u7528\u547D\u4EE4`),console.log("")}function et(e){return typeof e=="string"&&z(e)?e:"spa"}async function tt(e){if(e.options.help){console.log(Ve());return}e.args.length===0&&(i.error("\u8BF7\u63D0\u4F9B\u9879\u76EE\u540D\u79F0"),console.log(""),console.log(` \u7528\u6CD5: ${o("lytx create <name>","brightCyan")}`),console.log(""),console.log(` \u8FD0\u884C ${o("lytx create --help","brightCyan")} \u67E5\u770B\u66F4\u591A\u9009\u9879`),console.log(""),process.exit(1));let t=e.args[0],n=typeof e.options.template=="string"?e.options.template:"spa";if(!z(n)){i.error(`\u672A\u77E5\u6A21\u677F: ${o(n,"brightRed")}`),console.log(""),console.log(" \u53EF\u7528\u6A21\u677F\uFF1A");let s=N();for(let[a,p]of Object.entries(s))console.log(` ${o(a,"brightYellow")} \u2014 ${p}`);console.log(""),process.exit(1)}if(e.options.ts===!0||e.options.router===!0||e.options.store===!0||e.options.eslint===!0||typeof e.options.template=="string"&&["ssr","ssg","todo-app","admin-dashboard"].includes(e.options.template)){let s={name:t,template:et(e.options.template),ts:e.options.ts===!0,router:e.options.router===!0,store:e.options.store===!0,eslint:e.options.eslint===!0};await W(s)}else{let s={template:typeof e.options.template=="string"?e.options.template:"spa"};await Z(t,s)}}function ot(e){if(e.options.help){console.log(Ke);return}let t={port:typeof e.options.port=="string"?parseInt(e.options.port,10):typeof e.options.p=="string"?parseInt(e.options.p,10):3e3,hmr:e.options["no-hmr"]!==!0};(isNaN(t.port)||t.port<1||t.port>65535)&&(i.error(`\u65E0\u6548\u7684\u7AEF\u53E3\u53F7: ${e.options.port||e.options.p}`),process.exit(1)),V(t)}async function nt(e){if(e.options.help){console.log(qe);return}let t={minify:e.options.minify===!0,outDir:typeof e.options.outDir=="string"?e.options.outDir:typeof e.options.o=="string"?e.options.o:"dist",entry:typeof e.options.entry=="string"?e.options.entry:"index.html"};await oe(t)}function rt(e){if(e.options.help){console.log(Ze);return}let t=typeof e.options.port=="string"?parseInt(e.options.port,10):typeof e.options.p=="string"?parseInt(e.options.p,10):4173;(isNaN(t)||t<1||t>65535)&&(i.error(`\u65E0\u6548\u7684\u7AEF\u53E3\u53F7: ${e.options.port||e.options.p}`),process.exit(1));let n=ae.resolve(process.cwd(),"dist");ie.existsSync(n)||(i.error("\u672A\u627E\u5230\u6784\u5EFA\u8F93\u51FA\u76EE\u5F55 dist/\uFF0C\u8BF7\u5148\u8FD0\u884C lytx build"),process.exit(1)),V({port:t,root:n,hmr:!1})}async function st(){let e=q(process.argv);if(e.options.version){Xe();return}if(e.options.help&&!e.command){console.log(se);return}e.command||(console.log(se),process.exit(1));try{switch(e.command){case"create":await tt(e);break;case"dev":ot(e);break;case"build":await nt(e);break;case"preview":rt(e);break;case"generate":if(e.options.help){console.log(Y);break}await re(e.args);break;default:Qe(e.command),process.exit(1)}}catch(t){let n=t instanceof Error?t.message:String(t);i.error(`\u6267\u884C\u5931\u8D25: ${n}`),console.log(""),console.log(` ${o("\u63D0\u793A:","brightYellow")} \u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570\u6216\u8FD0\u884C ${o("lytx --help","brightCyan")} \u67E5\u770B\u5E2E\u52A9`),console.log(""),process.exit(1)}}st();export{_ as createHMREndpoint,Fe as createHMRServer,W as createProject,J as getHMRClientScript};
1334
+
1335
+ // src/index.ts
1336
+ if (__require.main === module) {
1337
+ runCli().catch(console.error);
1338
+ }
1339
+
1340
+ export { add, build, buildPlugin, create, createPlugin, detectPackageManager, dev, ensureDir, exists, getAddCommand, getInstallCommand, getRunCommand, listPluginTemplates, listTemplates, logger, readFile, runCli, test, validatePlugin, writeFile };
1341
+ //# sourceMappingURL=index.mjs.map
1342
+ //# sourceMappingURL=index.mjs.map