create-unibest 2.5.1 → 3.0.1

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/index.js ADDED
@@ -0,0 +1,748 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import process4 from "process";
5
+ import minimist from "minimist";
6
+
7
+ // src/commands/create/prompts.ts
8
+ import { text, multiselect, select, confirm, cancel, isCancel } from "@clack/prompts";
9
+
10
+ // src/utils/logger.ts
11
+ import { bold, green, red, yellow, cyan } from "kolorist";
12
+ var logger = {
13
+ /** 普通信息日志 */
14
+ info: (message) => {
15
+ console.log(`[${cyan("INFO")}] ${message}`);
16
+ },
17
+ /** 成功日志 */
18
+ success: (message) => {
19
+ console.log(`[${green("SUCCESS")}] ${bold(message)}`);
20
+ },
21
+ /** 错误日志 */
22
+ error: (message) => {
23
+ console.error(`[${red("ERROR")}] ${bold(message)}`);
24
+ },
25
+ /** 警告日志 */
26
+ warn: (message) => {
27
+ console.log(`[${yellow("WARN")}] ${message}`);
28
+ },
29
+ /** 提示日志 */
30
+ tip: (message) => {
31
+ console.log(`[${cyan("TIP")}] ${message}`);
32
+ }
33
+ };
34
+
35
+ // src/utils/validate.ts
36
+ import { existsSync } from "fs";
37
+ import { yellow as yellow2 } from "kolorist";
38
+ import { join } from "path";
39
+ function validateProjectName(name) {
40
+ const reg = /^[a-z0-9_-]+$/;
41
+ if (!reg.test(name)) {
42
+ return false;
43
+ }
44
+ if (name.startsWith("-") || name.endsWith("-")) {
45
+ return false;
46
+ }
47
+ return true;
48
+ }
49
+ function checkProjectNameExistAndValidate(_projectName) {
50
+ const projectName = _projectName.trim();
51
+ if (existsSync(join(process.cwd(), projectName))) {
52
+ return `\u76EE\u5F55 ${yellow2(projectName)} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u540D\u79F0`;
53
+ }
54
+ if (!validateProjectName(projectName)) {
55
+ return `\u9879\u76EE\u540D\u79F0 ${yellow2(projectName)} \u4E0D\u7B26\u5408\u89C4\u8303\uFF0C\u8BF7\u4F7F\u7528\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\u6216\u4E0B\u5212\u7EBF`;
56
+ }
57
+ return "";
58
+ }
59
+
60
+ // src/commands/create/prompts.ts
61
+ import { green as green2 } from "kolorist";
62
+ async function promptUser(projectName, argv = {}) {
63
+ try {
64
+ if (!projectName) {
65
+ const inputProjectName = await text({
66
+ message: `\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0${green2("[\u9879\u76EE\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u77ED\u6A2A\u7EBF\uFF0C\u5343\u4E07\u522B\u5199\u4E2D\u6587]")}`,
67
+ initialValue: "",
68
+ validate: (value) => {
69
+ if (!value.trim()) return "\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
70
+ const errorMessage = checkProjectNameExistAndValidate(value);
71
+ if (errorMessage) return errorMessage;
72
+ return;
73
+ }
74
+ });
75
+ if (isCancel(inputProjectName)) {
76
+ cancel("\u64CD\u4F5C\u5DF2\u53D6\u6D88");
77
+ process.exit(0);
78
+ }
79
+ projectName = inputProjectName;
80
+ }
81
+ const platforms = await multiselect({
82
+ message: `\u8BF7\u9009\u62E9\u9700\u8981\u652F\u6301\u7684\u5E73\u53F0\uFF08\u591A\u9009\uFF09${green2("[\u811A\u624B\u67B6\u5C06\u6839\u636E\u6240\u9009\u5E73\u53F0\u751F\u6210\u5BF9\u5E94\u7684\u5E73\u53F0\u4EE3\u7801\uFF0C\u8BF7\u6839\u636E\u5B9E\u9645\u60C5\u51B5\u9009\u62E9]")}`,
83
+ options: [
84
+ { value: "h5", label: "H5" },
85
+ { value: "mp-weixin", label: "\u5FAE\u4FE1\u5C0F\u7A0B\u5E8F" },
86
+ { value: "app", label: "APP" },
87
+ { value: "mp-alipay", label: "\u652F\u4ED8\u5B9D\u5C0F\u7A0B\u5E8F\uFF08\u5305\u542B\u9489\u9489\uFF09" },
88
+ { value: "mp-toutiao", label: "\u6296\u97F3\u5C0F\u7A0B\u5E8F" }
89
+ ],
90
+ initialValues: ["h5"],
91
+ // 默认选择 H5
92
+ required: true
93
+ });
94
+ if (isCancel(platforms)) {
95
+ cancel("\u64CD\u4F5C\u5DF2\u53D6\u6D88");
96
+ process.exit(0);
97
+ }
98
+ const uiLibrary = await select({
99
+ message: "\u8BF7\u9009\u62E9UI\u5E93",
100
+ options: [
101
+ { value: "none", label: "\u65E0UI\u5E93" },
102
+ { value: "wot-ui", label: "wot-ui" },
103
+ { value: "uview-pro", label: "uview-pro" },
104
+ { value: "sard-uniapp", label: "sard-uniapp" },
105
+ { value: "uv-ui", label: "uv-ui" },
106
+ { value: "uview-plus", label: "uview-plus" }
107
+ ],
108
+ initialValue: "none"
109
+ });
110
+ if (isCancel(uiLibrary)) {
111
+ cancel("\u64CD\u4F5C\u5DF2\u53D6\u6D88");
112
+ process.exit(0);
113
+ }
114
+ const loginStrategy = await confirm({
115
+ message: `\u662F\u5426\u9700\u8981\u767B\u5F55\u7B56\u7565\uFF08\u9ED1\u767D\u540D\u5355\u3001\u767B\u5F55\u62E6\u622A\u7B49\uFF09\uFF1F${green2("[\u6682\u4E0D\u77E5\u9053\u7684\uFF0C\u9009No\u5373\u53EF\uFF0C\u9879\u76EE\u751F\u6210\u540E\u4E5F\u53EF\u4EE5\u52A0\u8BE5\u7B56\u7565]")}`,
116
+ initialValue: false
117
+ });
118
+ if (isCancel(loginStrategy)) {
119
+ cancel("\u64CD\u4F5C\u5DF2\u53D6\u6D88");
120
+ process.exit(0);
121
+ }
122
+ const i18n = await confirm({
123
+ message: "\u662F\u5426\u9700\u8981\u591A\u8BED\u8A00i18n\uFF1F",
124
+ initialValue: false
125
+ });
126
+ if (isCancel(i18n)) {
127
+ cancel("\u64CD\u4F5C\u5DF2\u53D6\u6D88");
128
+ process.exit(0);
129
+ }
130
+ return {
131
+ projectName,
132
+ platforms,
133
+ uiLibrary,
134
+ loginStrategy,
135
+ i18n
136
+ // requestLibrary: requestLibrary as RequestLibrary,
137
+ // tokenStrategy: tokenStrategy as TokenStrategy,
138
+ // formatPlugin: formatPlugin as FormatPlugin,
139
+ };
140
+ } catch (error) {
141
+ logger.error(`\u8BE2\u95EE\u8FC7\u7A0B\u51FA\u9519: ${error.message}`);
142
+ process.exit(1);
143
+ }
144
+ }
145
+
146
+ // src/commands/create/generate.ts
147
+ import process3 from "process";
148
+
149
+ // src/utils/cloneRepo.ts
150
+ import { exec } from "child_process";
151
+ import { promises as fs } from "fs";
152
+ import { join as join3 } from "path";
153
+ import process2 from "process";
154
+ import { red as red2 } from "kolorist";
155
+
156
+ // src/utils/replacePackageJson.ts
157
+ import { readFileSync, writeFileSync } from "fs";
158
+ import { join as join2 } from "path";
159
+ function replaceContent(filePath, projectName, version2) {
160
+ const fileContent = JSON.parse(readFileSync(filePath, "utf8"));
161
+ fileContent.name = projectName;
162
+ fileContent.version = version2;
163
+ writeFileSync(filePath, JSON.stringify(fileContent, null, 2));
164
+ }
165
+ function replacePackageJson(root2, name, version2) {
166
+ const projectName = name.toLocaleLowerCase().replace(/\s/g, "-");
167
+ const pkgPath = join2(root2, "package.json");
168
+ replaceContent(pkgPath, projectName, version2);
169
+ }
170
+
171
+ // src/utils/cloneRepo.ts
172
+ async function removeGitFolder(localPath) {
173
+ const gitFolderPath = join3(localPath, ".git");
174
+ await fs.rm(gitFolderPath, { recursive: true, force: true });
175
+ }
176
+ var REPO_URL = "https://gitee.com/feige996/unibest.git";
177
+ async function cloneRepo(projectName, branch) {
178
+ try {
179
+ await new Promise((resolve, reject) => {
180
+ const execStr = `git clone --depth=1 -b ${branch} ${REPO_URL} "${projectName}"`;
181
+ exec(execStr, async (error) => {
182
+ if (error) {
183
+ console.error(`${red2("exec error:")} ${error}`);
184
+ reject(error);
185
+ return;
186
+ }
187
+ try {
188
+ await removeGitFolder(projectName);
189
+ resolve();
190
+ } catch (error2) {
191
+ reject(error2);
192
+ }
193
+ });
194
+ });
195
+ return;
196
+ } catch (error) {
197
+ console.error(`${red2("cloneRepo error:")} ${error}`);
198
+ throw new Error("cloneRepo error");
199
+ }
200
+ }
201
+ async function cloneRepoByBranch(root2, name, branch) {
202
+ try {
203
+ await cloneRepo(name, branch);
204
+ } catch (error) {
205
+ console.error(`${red2(`\u6A21\u677F\u7C7B\u578B${branch}\u4E0B\u8F7D\u5931\u8D25\uFF01`)} ${error}`);
206
+ process2.exit(1);
207
+ }
208
+ const projectPath = join3(root2, name);
209
+ replacePackageJson(projectPath, name, "1.0.0");
210
+ }
211
+
212
+ // src/utils/uiLibrary.ts
213
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
214
+ import { join as join4 } from "path";
215
+ var UI_LIBRARY_CONFIGS = {
216
+ none: null,
217
+ "wot-ui": {
218
+ packageName: "wot-design-uni",
219
+ easycom: {
220
+ pattern: "^wd-(.*)",
221
+ path: "wot-design-uni/components/wd-$1/wd-$1.vue"
222
+ },
223
+ types: ["wot-design-uni/global.d.ts"]
224
+ },
225
+ "sard-uniapp": {
226
+ packageName: "sard-uniapp",
227
+ easycom: {
228
+ pattern: "^sar-(.*)",
229
+ path: "sard-uniapp/components/$1/$1.vue"
230
+ },
231
+ types: ["sard-uniapp/global"]
232
+ },
233
+ "uview-pro": {
234
+ packageName: "uview-pro",
235
+ easycom: {
236
+ pattern: "^u-(.*)",
237
+ path: "uview-pro/components/u-$1/u-$1.vue"
238
+ },
239
+ needMainImport: true,
240
+ mainImport: "import uViewPro from 'uview-pro';",
241
+ needUniScss: true,
242
+ uniScssImport: "@import 'uview-pro/theme.scss';",
243
+ needAppVue: true,
244
+ appVueImport: "@import 'uview-pro/index.scss';"
245
+ },
246
+ "uv-ui": {
247
+ packageName: "@climblee/uv-ui",
248
+ easycom: {
249
+ pattern: "^uv-(.*)",
250
+ path: "@climblee/uv-ui/components/uv-$1/uv-$1.vue"
251
+ },
252
+ types: ["@ttou/uv-typings/shim", "@ttou/uv-typings/v2"]
253
+ },
254
+ "uview-plus": {
255
+ packageName: "uview-plus",
256
+ // uview-plus 需要多个 easycom 配置
257
+ easycom: {
258
+ pattern: "^u--(.*)",
259
+ path: "uview-plus/components/u-$1/u-$1.vue"
260
+ },
261
+ types: ["uview-plus/types"],
262
+ needUniScss: true,
263
+ uniScssImport: "@import 'uview-plus/theme.scss'; // /* \u884C\u4E3A\u76F8\u5173\u989C\u8272 */"
264
+ }
265
+ };
266
+ function getUILibraryConfig(uiLibrary) {
267
+ return UI_LIBRARY_CONFIGS[uiLibrary];
268
+ }
269
+ async function applyUILibraryConfig(projectPath, uiLibrary) {
270
+ if (uiLibrary === "none") {
271
+ return;
272
+ }
273
+ const config = getUILibraryConfig(uiLibrary);
274
+ if (!config) {
275
+ return;
276
+ }
277
+ await updatePackageJson(projectPath, config.packageName);
278
+ if (config.easycom) {
279
+ await updatePagesConfig(projectPath, config.easycom);
280
+ if (uiLibrary === "uview-plus") {
281
+ await updatePagesConfig(projectPath, {
282
+ pattern: "^up-(.*)",
283
+ path: "uview-plus/components/u-$1/u-$1.vue"
284
+ });
285
+ await updatePagesConfig(projectPath, {
286
+ pattern: "^u-([^-].*)",
287
+ path: "uview-plus/components/u-$1/u-$1.vue"
288
+ });
289
+ }
290
+ }
291
+ if (config.types && config.types.length > 0) {
292
+ await updateTsConfig(projectPath, config.types);
293
+ }
294
+ if (config.needMainImport && config.mainImport) {
295
+ await updateMainTs(projectPath, config.mainImport);
296
+ }
297
+ if (config.needUniScss && config.uniScssImport) {
298
+ await updateUniScss(projectPath, config.uniScssImport);
299
+ }
300
+ if (config.needAppVue && config.appVueImport) {
301
+ await updateAppVue(projectPath, config.appVueImport);
302
+ }
303
+ }
304
+ async function updatePackageJson(projectPath, packageName) {
305
+ const packageJsonPath = join4(projectPath, "package.json");
306
+ if (!existsSync2(packageJsonPath)) {
307
+ return;
308
+ }
309
+ const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
310
+ if (!packageJson.dependencies) {
311
+ packageJson.dependencies = {};
312
+ }
313
+ if (!packageJson.dependencies[packageName]) {
314
+ packageJson.dependencies[packageName] = "latest";
315
+ }
316
+ writeFileSync2(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
317
+ }
318
+ async function updatePagesConfig(projectPath, easycom) {
319
+ const pagesConfigPath = join4(projectPath, "pages.config.ts");
320
+ if (!existsSync2(pagesConfigPath)) {
321
+ return;
322
+ }
323
+ const originalContent = readFileSync2(pagesConfigPath, "utf8");
324
+ let content = originalContent;
325
+ const patternLiteral = escapeSingleQuotes(easycom.pattern);
326
+ const pathLiteral = escapeSingleQuotes(easycom.path);
327
+ const existingEntryRegex = new RegExp(
328
+ `["']${escapeForRegExp(patternLiteral)}["']\\s*:\\s*["']${escapeForRegExp(pathLiteral)}["']`
329
+ );
330
+ if (existingEntryRegex.test(content)) {
331
+ return;
332
+ }
333
+ const entry = { pattern: patternLiteral, path: pathLiteral };
334
+ content = addToExistingCustomBlock(content, entry) ?? addCustomBlock(content, entry) ?? addEasycomBlock(content, entry) ?? appendEasycomBlock(content, entry);
335
+ if (content !== originalContent) {
336
+ writeFileSync2(pagesConfigPath, ensureTrailingNewline(content));
337
+ }
338
+ }
339
+ async function updateTsConfig(projectPath, types) {
340
+ const tsConfigPath = join4(projectPath, "tsconfig.json");
341
+ if (!existsSync2(tsConfigPath)) {
342
+ return;
343
+ }
344
+ const tsConfig = JSON.parse(readFileSync2(tsConfigPath, "utf8"));
345
+ if (!tsConfig.compilerOptions) {
346
+ tsConfig.compilerOptions = {};
347
+ }
348
+ if (!tsConfig.compilerOptions.types) {
349
+ tsConfig.compilerOptions.types = [];
350
+ }
351
+ const existingTypes = tsConfig.compilerOptions.types;
352
+ for (const type of types) {
353
+ if (!existingTypes.includes(type)) {
354
+ existingTypes.push(type);
355
+ }
356
+ }
357
+ writeFileSync2(tsConfigPath, JSON.stringify(tsConfig, null, 2) + "\n");
358
+ }
359
+ async function updateMainTs(projectPath, importCode) {
360
+ const mainTsPath = join4(projectPath, "src", "main.ts");
361
+ if (!existsSync2(mainTsPath)) {
362
+ return;
363
+ }
364
+ let content = readFileSync2(mainTsPath, "utf8");
365
+ const firstLine = importCode.split("\n")[0];
366
+ if (content.includes(firstLine)) {
367
+ return;
368
+ }
369
+ const vueImportRegex = /(import\s+.*from\s+['"]vue['"];?\s*\n)/;
370
+ const match = content.match(vueImportRegex);
371
+ if (match) {
372
+ content = content.replace(vueImportRegex, `$1${importCode}
373
+ `);
374
+ } else {
375
+ content = `${importCode}
376
+
377
+ ${content}`;
378
+ }
379
+ if (importCode.includes("uview-pro")) {
380
+ const appUseRegex = /(const\s+app\s*=\s*createSSRApp\(App\);?\s*\n)/;
381
+ const appUseMatch = content.match(appUseRegex);
382
+ if (appUseMatch && !content.includes("app.use(uViewPro)")) {
383
+ content = content.replace(appUseRegex, `$1 app.use(uViewPro);
384
+ `);
385
+ }
386
+ }
387
+ writeFileSync2(mainTsPath, content);
388
+ }
389
+ async function updateUniScss(projectPath, importCode) {
390
+ const uniScssPath = join4(projectPath, "src", "style", "uni.scss");
391
+ if (!existsSync2(uniScssPath)) {
392
+ const altPath = join4(projectPath, "uni.scss");
393
+ if (existsSync2(altPath)) {
394
+ await updateScssFile(altPath, importCode);
395
+ }
396
+ return;
397
+ }
398
+ await updateScssFile(uniScssPath, importCode);
399
+ }
400
+ async function updateScssFile(filePath, importCode) {
401
+ let content = readFileSync2(filePath, "utf8");
402
+ if (content.includes(importCode)) {
403
+ return;
404
+ }
405
+ content = `${content.trim()}
406
+ ${importCode}
407
+ `;
408
+ writeFileSync2(filePath, content);
409
+ }
410
+ async function updateAppVue(projectPath, importCode) {
411
+ const appVuePath = join4(projectPath, "src", "App.vue");
412
+ if (!existsSync2(appVuePath)) {
413
+ return;
414
+ }
415
+ let content = readFileSync2(appVuePath, "utf8");
416
+ if (content.includes(importCode)) {
417
+ return;
418
+ }
419
+ const styleRegex = /(<style[^>]*>)/s;
420
+ const match = content.match(styleRegex);
421
+ if (match) {
422
+ content = content.replace(styleRegex, `$1
423
+ ${importCode}`);
424
+ } else {
425
+ content = `${content}
426
+ <style lang="scss">
427
+ ${importCode}
428
+ </style>`;
429
+ }
430
+ writeFileSync2(appVuePath, content);
431
+ }
432
+ function addToExistingCustomBlock(content, entry) {
433
+ const customIndex = content.indexOf("custom:");
434
+ if (customIndex === -1) {
435
+ return null;
436
+ }
437
+ const braceIndex = content.indexOf("{", customIndex);
438
+ if (braceIndex === -1) {
439
+ return null;
440
+ }
441
+ const closingIndex = findMatchingBrace(content, braceIndex);
442
+ if (closingIndex === -1) {
443
+ return null;
444
+ }
445
+ const inside = content.slice(braceIndex + 1, closingIndex);
446
+ const hasEntries = inside.trim().length > 0;
447
+ const entryIndent = getLineIndent(content, braceIndex) + " ";
448
+ const entryLine = `${entryIndent}'${entry.pattern}': '${entry.path}',`;
449
+ if (!hasEntries) {
450
+ const closingIndent = getLineIndent(content, closingIndex);
451
+ return content.slice(0, braceIndex + 1) + `
452
+ ${entryLine}
453
+ ${closingIndent}` + content.slice(closingIndex);
454
+ }
455
+ const beforeRaw = content.slice(0, closingIndex).replace(/\s*$/, "");
456
+ const separator = beforeRaw.endsWith("\n") ? "" : "\n";
457
+ const after = content.slice(closingIndex);
458
+ return `${beforeRaw}${separator}${entryLine}
459
+ ${after}`;
460
+ }
461
+ function addCustomBlock(content, entry) {
462
+ const easycomIndex = content.indexOf("easycom:");
463
+ if (easycomIndex === -1) {
464
+ return null;
465
+ }
466
+ const braceIndex = content.indexOf("{", easycomIndex);
467
+ if (braceIndex === -1) {
468
+ return null;
469
+ }
470
+ const closingIndex = findMatchingBrace(content, braceIndex);
471
+ if (closingIndex === -1) {
472
+ return null;
473
+ }
474
+ const easycomIndent = getLineIndent(content, braceIndex);
475
+ const customIndent = easycomIndent + " ";
476
+ const entryIndent = customIndent + " ";
477
+ const customBlock = `${customIndent}custom: {
478
+ ${entryIndent}'${entry.pattern}': '${entry.path}',
479
+ ${customIndent}},`;
480
+ const beforeRaw = content.slice(0, closingIndex).replace(/\s*$/, "");
481
+ const separator = beforeRaw.endsWith("\n") ? "" : "\n";
482
+ const after = content.slice(closingIndex);
483
+ return `${beforeRaw}${separator}${customBlock}
484
+ ${after}`;
485
+ }
486
+ function addEasycomBlock(content, entry) {
487
+ const exportIndex = content.indexOf("export default");
488
+ if (exportIndex === -1) {
489
+ return null;
490
+ }
491
+ const braceIndex = content.indexOf("{", exportIndex);
492
+ if (braceIndex === -1) {
493
+ return null;
494
+ }
495
+ const closingIndex = findMatchingBrace(content, braceIndex);
496
+ if (closingIndex === -1) {
497
+ return null;
498
+ }
499
+ const blockIndent = getLineIndent(content, braceIndex) + " ";
500
+ const entryIndent = blockIndent + " ";
501
+ const block = `${blockIndent}easycom: {
502
+ ${blockIndent} autoscan: true,
503
+ ${blockIndent} custom: {
504
+ ${entryIndent}'${entry.pattern}': '${entry.path}',
505
+ ${blockIndent} },
506
+ ${blockIndent}},`;
507
+ const before = content.slice(0, braceIndex + 1);
508
+ const after = content.slice(braceIndex + 1);
509
+ const prefix = before.endsWith("\n") ? before : `${before}
510
+ `;
511
+ return `${prefix}${block}
512
+ ${after}`;
513
+ }
514
+ function appendEasycomBlock(content, entry) {
515
+ const block = `
516
+ export const easycom = {
517
+ autoscan: true,
518
+ custom: {
519
+ '${entry.pattern}': '${entry.path}',
520
+ },
521
+ }
522
+ `;
523
+ return `${content}${block}`;
524
+ }
525
+ function findMatchingBrace(content, startIndex) {
526
+ let depth = 0;
527
+ for (let i = startIndex; i < content.length; i += 1) {
528
+ const char = content[i];
529
+ if (char === "{") {
530
+ depth += 1;
531
+ } else if (char === "}") {
532
+ depth -= 1;
533
+ if (depth === 0) {
534
+ return i;
535
+ }
536
+ }
537
+ }
538
+ return -1;
539
+ }
540
+ function getLineIndent(content, index) {
541
+ const lineStart = content.lastIndexOf("\n", index) + 1;
542
+ const line = content.slice(lineStart, index);
543
+ const match = line.match(/^\s*/);
544
+ return match ? match[0] : "";
545
+ }
546
+ function escapeSingleQuotes(value) {
547
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
548
+ }
549
+ function escapeForRegExp(value) {
550
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
551
+ }
552
+ function ensureTrailingNewline(value) {
553
+ return value.endsWith("\n") ? value : `${value}
554
+ `;
555
+ }
556
+
557
+ // src/utils/debug.ts
558
+ import { magenta } from "kolorist";
559
+ function debug(...args) {
560
+ const isDev = process.env.NODE_ENV === "development";
561
+ if (isDev) {
562
+ const debugPrefix = magenta("[debug]");
563
+ console.log(debugPrefix, ...args);
564
+ }
565
+ }
566
+
567
+ // src/commands/create/generate.ts
568
+ import path from "path";
569
+ var root = process3.cwd();
570
+ async function generateProject(options) {
571
+ debug("generateProject options", options);
572
+ const { projectName, platforms, uiLibrary, loginStrategy, i18n } = options;
573
+ if (!loginStrategy && !i18n) {
574
+ debug("\u62C9\u53D6 base \u5206\u652F");
575
+ await cloneRepoByBranch(root, projectName, "base");
576
+ } else if (!loginStrategy && i18n) {
577
+ debug("\u62C9\u53D6 base-i18n \u5206\u652F");
578
+ await cloneRepoByBranch(root, projectName, "base-i18n");
579
+ } else if (loginStrategy && !i18n) {
580
+ debug("\u62C9\u53D6 base-login \u5206\u652F");
581
+ await cloneRepoByBranch(root, projectName, "base-login");
582
+ } else if (loginStrategy && i18n) {
583
+ debug("\u62C9\u53D6 base-login-i18n \u5206\u652F");
584
+ await cloneRepoByBranch(root, projectName, "base-login-i18n");
585
+ }
586
+ const projectPath = path.join(root, projectName);
587
+ if (uiLibrary === "none") {
588
+ debug("\u4E0D\u5F15\u5165\u4EFB\u4F55UI\u5E93");
589
+ } else {
590
+ debug(`\u914D\u7F6E UI \u5E93: ${uiLibrary}`);
591
+ try {
592
+ await applyUILibraryConfig(projectPath, uiLibrary);
593
+ logger.success(`UI \u5E93 ${uiLibrary} \u914D\u7F6E\u5B8C\u6210`);
594
+ } catch (error) {
595
+ logger.warn(`UI \u5E93 ${uiLibrary} \u914D\u7F6E\u5931\u8D25: ${error.message}`);
596
+ logger.info("\u60A8\u53EF\u4EE5\u5728\u9879\u76EE\u521B\u5EFA\u540E\u624B\u52A8\u914D\u7F6E UI \u5E93");
597
+ }
598
+ }
599
+ try {
600
+ logger.success(`\u9879\u76EE${projectName}\u521B\u5EFA\u6210\u529F\uFF01`);
601
+ logger.info("\u4E0B\u4E00\u6B65:");
602
+ logger.info(` cd ${projectName}`);
603
+ logger.info(" pnpm install");
604
+ logger.info(" pnpm dev");
605
+ logger.info(" \u8FD0\u884C\u5B8C\u4EE5\u4E0A\u547D\u4EE4\u540E\uFF0C\u5373\u53EF\u5728\u5BF9\u5E94\u5E73\u53F0\u4E0A\u8FD0\u884C\u9879\u76EE");
606
+ logger.info(" \u5982\uFF1Apnpm dev:mp, pnpm dev:app \u7B49");
607
+ } catch (error) {
608
+ logger.error(`\u751F\u6210\u9879\u76EE\u5931\u8D25: ${error.message}`);
609
+ throw error;
610
+ }
611
+ }
612
+
613
+ // package.json
614
+ var version = "3.0.1";
615
+
616
+ // src/commands/create.ts
617
+ import { intro, log } from "@clack/prompts";
618
+ import { bold as bold3, yellow as yellow3, green as green3 } from "kolorist";
619
+
620
+ // src/utils/unibestVersion.ts
621
+ import fetch from "node-fetch";
622
+ async function getUnibestVersion() {
623
+ try {
624
+ const apiUrl = `https://gitee.com/api/v5/repos/feige996/unibest/contents/package.json?ref=main`;
625
+ const response = await fetch(apiUrl, {
626
+ method: "GET",
627
+ headers: {
628
+ "Content-Type": "application/json"
629
+ }
630
+ });
631
+ if (response.ok) {
632
+ const data = await response.json();
633
+ const { content, encoding } = data;
634
+ if (encoding === "base64") {
635
+ const decodedContent = Buffer.from(content, "base64").toString("utf8");
636
+ const packageJson = JSON.parse(decodedContent);
637
+ return packageJson.version || null;
638
+ } else {
639
+ return null;
640
+ }
641
+ } else {
642
+ return null;
643
+ }
644
+ } catch (error) {
645
+ return null;
646
+ }
647
+ }
648
+ var unibestVersion_default = getUnibestVersion;
649
+
650
+ // src/commands/create.ts
651
+ async function createCommand(args) {
652
+ const projectName = args._[1];
653
+ const versionUnibest = await unibestVersion_default() || "3.18.3";
654
+ intro(bold3(green3(`create-unibest@v${version} \u5FEB\u901F\u521B\u5EFA ${yellow3(`unibest@v${versionUnibest}`)} \u9879\u76EE`)));
655
+ if (projectName) {
656
+ const errorMessage = checkProjectNameExistAndValidate(projectName);
657
+ if (errorMessage) {
658
+ log.error(errorMessage);
659
+ process.exit(1);
660
+ }
661
+ }
662
+ try {
663
+ const projectOptions = await promptUser(projectName, args);
664
+ await generateProject(projectOptions);
665
+ log.success("\u9879\u76EE\u521B\u5EFA\u6210\u529F\uFF01");
666
+ } catch (error) {
667
+ log.error(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${error.message}`);
668
+ process.exit(1);
669
+ }
670
+ }
671
+
672
+ // src/utils/color.ts
673
+ import { blue, green as green4, magenta as magenta2, red as red3, yellow as yellow4 } from "kolorist";
674
+ var color = {
675
+ blue,
676
+ green: green4,
677
+ magenta: magenta2,
678
+ red: red3,
679
+ yellow: yellow4
680
+ };
681
+
682
+ // src/utils/help.ts
683
+ function printHelp() {
684
+ console.log(color.green("\nunibest - \u8DE8\u5E73\u53F0\u5F00\u53D1\u6846\u67B6\u811A\u624B\u67B6"));
685
+ console.log("");
686
+ console.log(color.blue("\u7528\u6CD5:"));
687
+ console.log(" unibest <command> [options]");
688
+ console.log("");
689
+ console.log(color.blue("\u547D\u4EE4:"));
690
+ console.log(" create <project-name> \u521B\u5EFA\u65B0\u7684unibest\u9879\u76EE");
691
+ console.log(" help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F");
692
+ console.log(" version \u663E\u793A\u7248\u672C\u4FE1\u606F");
693
+ console.log("");
694
+ console.log(color.blue("\u9009\u9879:"));
695
+ console.log(" --ui, --ui-library \u6307\u5B9AUI\u5E93");
696
+ console.log(" --ts, --typescript \u4F7F\u7528TypeScript\uFF08\u9ED8\u8BA4\uFF09");
697
+ console.log(" --js, --javascript \u4F7F\u7528JavaScript");
698
+ console.log(" --i18n \u542F\u7528i18n");
699
+ console.log("");
700
+ console.log(color.blue("\u793A\u4F8B:"));
701
+ console.log(" unibest create my-project");
702
+ console.log(" unibest create my-project --ui uv-ui --ts --i18n");
703
+ console.log(" unibest create my-project --ui wot-ui --js");
704
+ }
705
+
706
+ // src/index.ts
707
+ import { green as green5 } from "kolorist";
708
+ import { yellow as yellow5 } from "kolorist";
709
+ function main() {
710
+ const args = minimist(process4.argv.slice(2));
711
+ const command = args._[0];
712
+ debug("command:", command);
713
+ debug("args:", args);
714
+ if (args.v || args.version) {
715
+ printVersion();
716
+ return;
717
+ }
718
+ switch (command) {
719
+ case "create":
720
+ case "new":
721
+ createCommand(args);
722
+ break;
723
+ case "-h":
724
+ case "--help":
725
+ printHelp();
726
+ break;
727
+ case "-v":
728
+ case "--version":
729
+ printVersion();
730
+ break;
731
+ default:
732
+ if (command) {
733
+ console.log(color.red(`\u672A\u77E5\u547D\u4EE4: ${command}`));
734
+ }
735
+ printHelp();
736
+ break;
737
+ }
738
+ }
739
+ async function printVersion() {
740
+ console.log(green5(`create-unibest: `) + yellow5(version));
741
+ try {
742
+ const unibestVersion = await unibestVersion_default();
743
+ console.log(green5(`unibest: `) + yellow5(unibestVersion || "1.0.0"));
744
+ } catch (error) {
745
+ console.log(green5(`unibest: \u672A\u80FD\u83B7\u53D6\u5230\u7248\u672C\u53F7`));
746
+ }
747
+ }
748
+ main();