@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.
- package/dist/create.cjs +522 -0
- package/dist/create.cjs.map +1 -0
- package/dist/create.d.mts +2 -0
- package/dist/create.d.ts +2 -0
- package/dist/create.mjs +520 -0
- package/dist/create.mjs.map +1 -0
- package/dist/index.cjs +1363 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +188 -0
- package/dist/index.d.ts +188 -0
- package/dist/index.mjs +1219 -935
- package/dist/index.mjs.map +1 -0
- package/dist/lyt.cjs +1363 -0
- package/dist/lyt.cjs.map +1 -0
- package/dist/lyt.d.mts +1 -0
- package/dist/lyt.d.ts +1 -0
- package/dist/lyt.mjs +1342 -0
- package/dist/lyt.mjs.map +1 -0
- package/lyt-cli.js +3 -0
- package/package.json +34 -31
- package/README.md +0 -227
- package/dist/bin/cli.cjs +0 -2
- package/dist/bin/cli.js +0 -2
- package/dist/bin/cli.mjs +0 -1
- package/dist/index.js +0 -1058
- package/dist/types/bin/cli.d.ts +0 -9
- package/dist/types/bin/cli.d.ts.map +0 -1
- package/dist/types/build.d.ts +0 -30
- package/dist/types/build.d.ts.map +0 -1
- package/dist/types/create.d.ts +0 -19
- package/dist/types/create.d.ts.map +0 -1
- package/dist/types/dev.d.ts +0 -24
- package/dist/types/dev.d.ts.map +0 -1
- package/dist/types/generate.d.ts +0 -14
- package/dist/types/generate.d.ts.map +0 -1
- package/dist/types/hmr.d.ts +0 -55
- package/dist/types/hmr.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -20
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/scaffold.d.ts +0 -67
- package/dist/types/scaffold.d.ts.map +0 -1
- package/dist/types/utils.d.ts +0 -92
- 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
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
font-weight: 700;
|
|
56
|
+
function writeFile(filePath, content) {
|
|
57
|
+
ensureDir(dirname(filePath));
|
|
58
|
+
writeFileSync(filePath, content, "utf-8");
|
|
161
59
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
letter-spacing: 2px;
|
|
60
|
+
function readFile(filePath) {
|
|
61
|
+
return readFileSync(filePath, "utf-8");
|
|
165
62
|
}
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
176
|
-
|
|
66
|
+
function isEmptyDir(dir) {
|
|
67
|
+
if (!existsSync(dir)) return true;
|
|
68
|
+
const files = readdirSync(dir);
|
|
69
|
+
return files.length === 0;
|
|
177
70
|
}
|
|
178
|
-
|
|
179
|
-
.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
.
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
|
|
236
|
-
|
|
237
|
-
|
|
290
|
+
<script setup>
|
|
291
|
+
const title = 'Hello LytJS!';
|
|
292
|
+
</script>
|
|
238
293
|
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
311
|
+
<script setup lang="ts">
|
|
312
|
+
import { RouterLink, RouterView } from '@lytjs/router';
|
|
313
|
+
</script>
|
|
246
314
|
|
|
247
|
-
|
|
248
|
-
|
|
315
|
+
<style scoped>
|
|
316
|
+
.app {
|
|
317
|
+
text-align: center;
|
|
318
|
+
padding: 2rem;
|
|
249
319
|
}
|
|
250
320
|
|
|
251
|
-
.
|
|
252
|
-
|
|
321
|
+
.nav {
|
|
322
|
+
margin-bottom: 2rem;
|
|
253
323
|
}
|
|
254
324
|
|
|
255
|
-
.
|
|
256
|
-
|
|
325
|
+
.nav a {
|
|
326
|
+
margin: 0 1rem;
|
|
327
|
+
color: #42b883;
|
|
328
|
+
text-decoration: none;
|
|
257
329
|
}
|
|
258
330
|
|
|
259
|
-
.
|
|
260
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
344
|
+
<script setup>
|
|
345
|
+
const title = 'Hello LytJS!';
|
|
346
|
+
</script>
|
|
267
347
|
|
|
268
|
-
|
|
348
|
+
<style scoped>
|
|
349
|
+
.app {
|
|
269
350
|
text-align: center;
|
|
270
|
-
|
|
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
|
-
|
|
291
|
-
|
|
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
|
-
|
|
299
|
-
.welcome-section h1 {
|
|
300
|
-
font-size: 2rem;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
.app-main {
|
|
304
|
-
padding: 2rem 1rem;
|
|
357
|
+
</style>
|
|
358
|
+
`;
|
|
305
359
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
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
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
<
|
|
405
|
-
</
|
|
406
|
-
<
|
|
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
|
-
.
|
|
438
|
-
|
|
439
|
-
padding: 20px;
|
|
400
|
+
.about {
|
|
401
|
+
padding: 1rem;
|
|
440
402
|
}
|
|
441
403
|
</style>
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
message: 'Hello Lyt!',
|
|
503
|
-
},
|
|
411
|
+
export const useCounterStore = defineStore('counter', () => {
|
|
412
|
+
// State
|
|
413
|
+
const count = signal(0);
|
|
504
414
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
state.count++
|
|
508
|
-
},
|
|
415
|
+
// Getters
|
|
416
|
+
const doubleCount = computed(() => count.value * 2);
|
|
509
417
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
418
|
+
// Actions
|
|
419
|
+
function increment() {
|
|
420
|
+
count.value++;
|
|
421
|
+
}
|
|
514
422
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
},
|
|
519
|
-
},
|
|
423
|
+
function decrement() {
|
|
424
|
+
count.value--;
|
|
425
|
+
}
|
|
520
426
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
}
|
|
524
|
-
})
|
|
525
|
-
`}function Te(){return`/* \u5168\u5C40\u6837\u5F0F */
|
|
427
|
+
function reset() {
|
|
428
|
+
count.value = 0;
|
|
429
|
+
}
|
|
526
430
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
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
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
-
|
|
547
|
-
|
|
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
|
-
|
|
595
|
-
|
|
596
|
-
scheduleReconnect();
|
|
597
|
-
};
|
|
470
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
471
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
598
472
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
}
|
|
473
|
+
async function createServer() {
|
|
474
|
+
let resolve: any;
|
|
475
|
+
let vite: any;
|
|
603
476
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
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
|
-
|
|
616
|
-
|
|
617
|
-
|
|
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
|
-
|
|
630
|
-
|
|
631
|
-
|
|
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
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
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
|
-
|
|
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
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
${
|
|
675
|
-
|
|
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
|
-
|
|
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
|
-
.${
|
|
700
|
-
/*
|
|
661
|
+
.${name} {
|
|
662
|
+
/* styles */
|
|
701
663
|
}
|
|
702
664
|
</style>
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
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
|
-
|
|
678
|
+
<script setup lang="ts">
|
|
679
|
+
// Page logic here
|
|
680
|
+
</script>
|
|
712
681
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
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
|
-
|
|
709
|
+
function decrement() {
|
|
710
|
+
count.value--;
|
|
711
|
+
}
|
|
721
712
|
|
|
722
|
-
function
|
|
723
|
-
|
|
724
|
-
}
|
|
725
|
-
</script>
|
|
713
|
+
function reset() {
|
|
714
|
+
count.value = 0;
|
|
715
|
+
}
|
|
726
716
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
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
|
-
|
|
739
|
-
|
|
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
|
-
|
|
743
|
-
|
|
744
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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
|
-
|
|
762
|
-
import {
|
|
835
|
+
import { definePlugin } from '@lytjs/core';
|
|
836
|
+
import type { ConfigSchema } from '@lytjs/core';
|
|
763
837
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
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
|
-
|
|
778
|
-
|
|
779
|
-
default: false
|
|
780
|
-
}
|
|
781
|
-
});
|
|
855
|
+
additionalProperties: false,
|
|
856
|
+
};
|
|
782
857
|
|
|
783
|
-
|
|
858
|
+
${pluginName.replace(/-/g, "")}Options\`;
|
|
784
859
|
|
|
785
|
-
|
|
786
|
-
|
|
860
|
+
export interface ${pluginName.replace(/-/g, "")}Options {
|
|
861
|
+
debug?: boolean;
|
|
862
|
+
option1?: string;
|
|
787
863
|
}
|
|
788
864
|
|
|
789
|
-
|
|
790
|
-
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
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
|
-
|
|
804
|
-
|
|
805
|
-
|
|
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
|
-
|
|
824
|
-
|
|
825
|
-
|
|
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
|
-
|
|
828
|
-
|
|
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
|
-
|
|
836
|
-
.${n}-body,
|
|
837
|
-
.${n}-footer {
|
|
838
|
-
padding: 16px;
|
|
839
|
-
}
|
|
927
|
+
A LytJS plugin.
|
|
840
928
|
|
|
841
|
-
|
|
842
|
-
border-bottom: 1px solid #e5e7eb;
|
|
843
|
-
}
|
|
929
|
+
## Installation
|
|
844
930
|
|
|
845
|
-
|
|
846
|
-
|
|
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
|
-
|
|
935
|
+
## Usage
|
|
854
936
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
count: 0
|
|
859
|
-
},
|
|
937
|
+
\`\`\`typescript
|
|
938
|
+
import { createApp } from '@lytjs/core';
|
|
939
|
+
import myPlugin from '@lytjs/plugin-${pluginName}';
|
|
860
940
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
},
|
|
941
|
+
const app = createApp(App);
|
|
942
|
+
app.use(myPlugin);
|
|
943
|
+
\`\`\`
|
|
865
944
|
|
|
866
|
-
|
|
867
|
-
// \u65B9\u6CD5\u5B9A\u4E49
|
|
868
|
-
increment(state) {
|
|
869
|
-
state.count++;
|
|
870
|
-
},
|
|
945
|
+
## API
|
|
871
946
|
|
|
872
|
-
|
|
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
|
-
|
|
886
|
-
import { ref, computed } from '@lytjs/reactivity';
|
|
949
|
+
Create the plugin with options.
|
|
887
950
|
|
|
888
|
-
|
|
889
|
-
</script>
|
|
951
|
+
## License
|
|
890
952
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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
|
-
|
|
901
|
-
|
|
962
|
+
node_modules
|
|
963
|
+
dist
|
|
964
|
+
*.local
|
|
902
965
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
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
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
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
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
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
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
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
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
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
|