cmyr-template-cli 1.35.2 → 1.36.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/README.md +7 -1
- package/dist/plopfile.js +441 -314
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -73,7 +73,9 @@ ct create
|
|
|
73
73
|
"TWITTER_USERNAME": "",
|
|
74
74
|
"NPM_USERNAME": "",
|
|
75
75
|
"DOCKER_USERNAME": "",
|
|
76
|
-
"
|
|
76
|
+
"DOCKER_PASSWORD": "",
|
|
77
|
+
"CONTACT_EMAIL": "",
|
|
78
|
+
"NPM_TOKEN": ""
|
|
77
79
|
}
|
|
78
80
|
```
|
|
79
81
|
|
|
@@ -97,8 +99,12 @@ NPM_USERNAME:Npm 用户名,可空,默认会使用 `GITHUB_USERNAME` 的用
|
|
|
97
99
|
|
|
98
100
|
DOCKER_USERNAME:Docker Hub 用户名,可空,默认会使用**小写的** `GITHUB_USERNAME` 的用户名
|
|
99
101
|
|
|
102
|
+
DOCKER_PASSWORD:Docker Hub 密码,可空,默认值为空。如果填写,会自动初始化对应的仓库 action secret
|
|
103
|
+
|
|
100
104
|
CONTACT_EMAIL:联系邮箱,可空,默认值为空
|
|
101
105
|
|
|
106
|
+
NPM_TOKEN:Npm 令牌,可空,默认值为空。如果填写,会自动初始化对应的仓库 action secret
|
|
107
|
+
|
|
102
108
|
**如果不使用自动初始化远程仓库功能,可以跳过该配置**
|
|
103
109
|
|
|
104
110
|
## 开发
|
package/dist/plopfile.js
CHANGED
|
@@ -22,26 +22,115 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
|
|
25
|
-
// src/env.ts
|
|
25
|
+
// src/config/env.ts
|
|
26
26
|
var env = process.env;
|
|
27
27
|
var __DEV__ = env.NODE_ENV === "development";
|
|
28
28
|
var PACKAGE_MANAGER = "pnpm";
|
|
29
29
|
|
|
30
|
-
// src/utils.ts
|
|
31
|
-
var
|
|
32
|
-
var
|
|
33
|
-
var
|
|
30
|
+
// src/utils/utils.ts
|
|
31
|
+
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
32
|
+
var import_path2 = __toESM(require("path"));
|
|
33
|
+
var import_ora2 = __toESM(require("ora"));
|
|
34
34
|
var import_download_git_repo = __toESM(require("download-git-repo"));
|
|
35
|
-
var import_axios = __toESM(require("axios"));
|
|
36
35
|
var import_child_process = require("child_process");
|
|
37
36
|
var import_colors = __toESM(require("@colors/colors"));
|
|
38
|
-
var
|
|
37
|
+
var import_ejs2 = __toESM(require("ejs"));
|
|
39
38
|
var import_lodash = require("lodash");
|
|
40
|
-
var import_core = require("@lint-md/core");
|
|
41
39
|
var import_json5 = __toESM(require("json5"));
|
|
42
40
|
var import_os = __toESM(require("os"));
|
|
41
|
+
var import_yaml = __toESM(require("yaml"));
|
|
42
|
+
var import_acorn = __toESM(require("acorn"));
|
|
43
|
+
var import_acorn_walk = __toESM(require("acorn-walk"));
|
|
44
|
+
|
|
45
|
+
// src/utils/constants.ts
|
|
46
|
+
var GITHUB_API_URL = "https://api.github.com";
|
|
47
|
+
var GITEE_API_URL = "https://gitee.com/api/v5";
|
|
48
|
+
var NODEJS_URLS = [
|
|
49
|
+
"https://nodejs.org/zh-cn/download/"
|
|
50
|
+
];
|
|
51
|
+
var NODE_INDEX_URL = "https://cdn.npmmirror.com/binaries/node/index.json";
|
|
52
|
+
var REMOTES = [
|
|
53
|
+
"https://github.com",
|
|
54
|
+
"https://hub.fastgit.xyz",
|
|
55
|
+
"https://download.fastgit.org",
|
|
56
|
+
"https://ghproxy.com/https://github.com",
|
|
57
|
+
"https://gh.ddlc.top/https://github.com",
|
|
58
|
+
"https://gh.flyinbug.top/gh/https://github.com",
|
|
59
|
+
"https://gh.con.sh/https://github.com",
|
|
60
|
+
"https://cors.isteed.cc/github.com",
|
|
61
|
+
"https://ghps.cc/https://github.com",
|
|
62
|
+
"https://download.nuaa.cf",
|
|
63
|
+
"https://kgithub.com",
|
|
64
|
+
"https://github.moeyy.xyz/https://github.com",
|
|
65
|
+
"https://hub.njuu.cf"
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
// src/utils/dependencies.ts
|
|
69
|
+
var COMMON_DEPENDENCIES = {
|
|
70
|
+
devDependencies: {
|
|
71
|
+
"@types/fs-extra": "^9.0.4",
|
|
72
|
+
"@types/lodash": "^4.14.165",
|
|
73
|
+
"@types/lodash-es": "^4.17.4",
|
|
74
|
+
"@types/md5": "^2.3.1"
|
|
75
|
+
},
|
|
76
|
+
dependencies: {
|
|
77
|
+
"await-to-js": "^3.0.0",
|
|
78
|
+
axios: "^1.0.0",
|
|
79
|
+
"cmyr-error-collection": "^1.5.0",
|
|
80
|
+
"cmyr-sign": "^1.1.0",
|
|
81
|
+
dayjs: "^1.9.6",
|
|
82
|
+
"fs-extra": "^10.0.0",
|
|
83
|
+
"isomorphic-unfetch": "^3.1.0",
|
|
84
|
+
lodash: "^4.17.20",
|
|
85
|
+
"lodash-es": "^4.17.21",
|
|
86
|
+
"p-limit": "^6.1.0",
|
|
87
|
+
"p-queue": "^8.0.1",
|
|
88
|
+
"push-all-in-one": "^2.2.0",
|
|
89
|
+
"leancloud-storage": "^4.15.0",
|
|
90
|
+
yaml: "^2.3.3"
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
var NODE_DEPENDENCIES = {
|
|
94
|
+
devDependencies: {
|
|
95
|
+
tsx: "^4.15.7"
|
|
96
|
+
},
|
|
97
|
+
dependencies: {
|
|
98
|
+
cron: "^3.1.7",
|
|
99
|
+
dotenv: "^16.3.1",
|
|
100
|
+
log4js: "^6.9.1",
|
|
101
|
+
md5: "^2.3.0",
|
|
102
|
+
rimraf: "^5.0.0",
|
|
103
|
+
"rss-parser": "^3.12.0",
|
|
104
|
+
zx: "^8.1.0"
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var VUE2_DEPENDENCIES = {
|
|
108
|
+
devDependencies: {},
|
|
109
|
+
dependencies: {
|
|
110
|
+
"@smallwei/avue": "2.9.4",
|
|
111
|
+
"@vueuse/core": "^10.4.1",
|
|
112
|
+
"element-ui": "^2.15.7",
|
|
113
|
+
vuetify: "^2.6.3"
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var VUE3_DEPENDENCIES = {
|
|
117
|
+
devDependencies: {},
|
|
118
|
+
dependencies: {
|
|
119
|
+
"@smallwei/avue": "^3.2.20",
|
|
120
|
+
"@vueuse/core": "^10.4.1",
|
|
121
|
+
"element-plus": "^2.3.14",
|
|
122
|
+
vuetify: "^3.3.14"
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
var WEB_DEPENDENCIES = {
|
|
126
|
+
devDependencies: {},
|
|
127
|
+
dependencies: {
|
|
128
|
+
"animate.css": "^4.1.1",
|
|
129
|
+
"normalize.css": "^8.0.1"
|
|
130
|
+
}
|
|
131
|
+
};
|
|
43
132
|
|
|
44
|
-
// src/constants.ts
|
|
133
|
+
// src/core/constants.ts
|
|
45
134
|
var TEMPLATES_META_LIST = [
|
|
46
135
|
{
|
|
47
136
|
name: "vite-latest-template",
|
|
@@ -49,7 +138,8 @@ var TEMPLATES_META_LIST = [
|
|
|
49
138
|
runtime: "browser",
|
|
50
139
|
vueVersion: 3,
|
|
51
140
|
docker: false,
|
|
52
|
-
priority: 0
|
|
141
|
+
priority: 0,
|
|
142
|
+
tags: ["vite"]
|
|
53
143
|
},
|
|
54
144
|
// {
|
|
55
145
|
// name: 'vite3-template',
|
|
@@ -65,7 +155,8 @@ var TEMPLATES_META_LIST = [
|
|
|
65
155
|
runtime: "browser",
|
|
66
156
|
vueVersion: 2,
|
|
67
157
|
docker: false,
|
|
68
|
-
priority: 0
|
|
158
|
+
priority: 0,
|
|
159
|
+
tags: ["vite"]
|
|
69
160
|
},
|
|
70
161
|
// {
|
|
71
162
|
// name: 'vite2-template',
|
|
@@ -97,7 +188,8 @@ var TEMPLATES_META_LIST = [
|
|
|
97
188
|
runtime: "browser",
|
|
98
189
|
vueVersion: 3,
|
|
99
190
|
docker: false,
|
|
100
|
-
priority: 0
|
|
191
|
+
priority: 0,
|
|
192
|
+
tags: ["electron", "vite"]
|
|
101
193
|
},
|
|
102
194
|
// {
|
|
103
195
|
// name: 'electron-vue-template',
|
|
@@ -140,7 +232,8 @@ var TEMPLATES_META_LIST = [
|
|
|
140
232
|
runtime: "browser",
|
|
141
233
|
vueVersion: 0,
|
|
142
234
|
docker: false,
|
|
143
|
-
priority: 0
|
|
235
|
+
priority: 0,
|
|
236
|
+
tags: ["vite"]
|
|
144
237
|
},
|
|
145
238
|
{
|
|
146
239
|
name: "react-template",
|
|
@@ -173,7 +266,8 @@ var TEMPLATES_META_LIST = [
|
|
|
173
266
|
runtime: "nodejs",
|
|
174
267
|
vueVersion: 0,
|
|
175
268
|
docker: true,
|
|
176
|
-
priority: 0
|
|
269
|
+
priority: 0,
|
|
270
|
+
tags: ["express"]
|
|
177
271
|
},
|
|
178
272
|
// {
|
|
179
273
|
// name: 'koa2-template',
|
|
@@ -282,101 +376,97 @@ var TEMPLATES_META_LIST = [
|
|
|
282
376
|
javaVersion: 17,
|
|
283
377
|
docker: true,
|
|
284
378
|
priority: 0,
|
|
285
|
-
tags: ["spring-boot"]
|
|
379
|
+
tags: ["spring-boot-v3"]
|
|
286
380
|
}
|
|
287
381
|
];
|
|
288
382
|
|
|
289
|
-
// src/utils.ts
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
383
|
+
// src/utils/template.ts
|
|
384
|
+
function getTemplateMeta(templateName) {
|
|
385
|
+
return TEMPLATES_META_LIST.find((t) => t.name === templateName);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/utils/string.ts
|
|
389
|
+
var import_core = require("@lint-md/core");
|
|
390
|
+
function kebabCase(str) {
|
|
391
|
+
return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/_+/g, "-").replace(/\s+/g, "-").toLowerCase();
|
|
392
|
+
}
|
|
293
393
|
var fix = (markdown, rules) => (0, import_core.lintMarkdown)(markdown, rules, true)?.fixedResult?.result;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
dependencies: {
|
|
346
|
-
cron: "^3.1.7",
|
|
347
|
-
dotenv: "^16.3.1",
|
|
348
|
-
log4js: "^6.9.1",
|
|
349
|
-
md5: "^2.3.0",
|
|
350
|
-
rimraf: "^5.0.0",
|
|
351
|
-
"rss-parser": "^3.12.0",
|
|
352
|
-
zx: "^8.1.0"
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
var VUE2_DEPENDENCIES = {
|
|
356
|
-
devDependencies: {},
|
|
357
|
-
dependencies: {
|
|
358
|
-
"@smallwei/avue": "2.9.4",
|
|
359
|
-
"@vueuse/core": "^10.4.1",
|
|
360
|
-
"element-ui": "^2.15.7",
|
|
361
|
-
vuetify: "^2.6.3"
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
var VUE3_DEPENDENCIES = {
|
|
365
|
-
devDependencies: {},
|
|
366
|
-
dependencies: {
|
|
367
|
-
"@smallwei/avue": "^3.2.20",
|
|
368
|
-
"@vueuse/core": "^10.4.1",
|
|
369
|
-
"element-plus": "^2.3.14",
|
|
370
|
-
vuetify: "^3.3.14"
|
|
394
|
+
function lintMd(markdown) {
|
|
395
|
+
const rules = {
|
|
396
|
+
"no-empty-code": 0,
|
|
397
|
+
"no-trailing-punctuation": 0,
|
|
398
|
+
"no-long-code": 0,
|
|
399
|
+
"no-empty-code-lang": 0,
|
|
400
|
+
"no-empty-inlinecode": 0
|
|
401
|
+
};
|
|
402
|
+
const fixed = fix(markdown, rules);
|
|
403
|
+
return fixed;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// src/utils/ejs.ts
|
|
407
|
+
var import_ejs = __toESM(require("ejs"));
|
|
408
|
+
var import_fs_extra = __toESM(require("fs-extra"));
|
|
409
|
+
async function ejsRender(templatePath, data, outputPath) {
|
|
410
|
+
const template = (await import_fs_extra.default.readFile(templatePath, "utf8")).toString();
|
|
411
|
+
const content = await import_ejs.default.render(
|
|
412
|
+
template,
|
|
413
|
+
data,
|
|
414
|
+
{
|
|
415
|
+
debug: false,
|
|
416
|
+
async: true
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
await import_fs_extra.default.writeFile(outputPath, content);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// src/utils/files.ts
|
|
423
|
+
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
424
|
+
var import_path = __toESM(require("path"));
|
|
425
|
+
var import_ora = __toESM(require("ora"));
|
|
426
|
+
async function copyFilesFromTemplates(projectPath, files, lazy = false) {
|
|
427
|
+
const loading = (0, import_ora.default)(`正在复制文件 ${files.join()} ……`).start();
|
|
428
|
+
try {
|
|
429
|
+
for await (const file of files) {
|
|
430
|
+
const templatePath = import_path.default.join(__dirname, "../templates/", file);
|
|
431
|
+
const newPath = import_path.default.join(projectPath, file);
|
|
432
|
+
if (await import_fs_extra2.default.pathExists(newPath)) {
|
|
433
|
+
if (lazy) {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
await import_fs_extra2.default.remove(newPath);
|
|
437
|
+
}
|
|
438
|
+
await import_fs_extra2.default.copyFile(templatePath, newPath);
|
|
439
|
+
}
|
|
440
|
+
loading.succeed(`文件 ${files.join()} 复制成功!`);
|
|
441
|
+
return true;
|
|
442
|
+
} catch (error) {
|
|
443
|
+
loading.fail(`文件 ${files.join()} 复制失败!`);
|
|
444
|
+
throw error;
|
|
371
445
|
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
446
|
+
}
|
|
447
|
+
async function removeFiles(projectPath, files) {
|
|
448
|
+
const loading = (0, import_ora.default)(`正在删除文件 ${files.join()} ……`).start();
|
|
449
|
+
try {
|
|
450
|
+
for await (const file of files) {
|
|
451
|
+
const newPath = import_path.default.join(projectPath, file);
|
|
452
|
+
if (await import_fs_extra2.default.pathExists(newPath)) {
|
|
453
|
+
await import_fs_extra2.default.remove(newPath);
|
|
454
|
+
} else {
|
|
455
|
+
console.log(`文件 ${file} 不存在,已跳过删除`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
loading.succeed(`文件 ${files.join()} 删除成功!`);
|
|
459
|
+
return true;
|
|
460
|
+
} catch (error) {
|
|
461
|
+
loading.fail(`文件 ${files.join()} 删除失败!`);
|
|
462
|
+
throw error;
|
|
378
463
|
}
|
|
379
|
-
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// src/utils/api.ts
|
|
467
|
+
var import_axios = __toESM(require("axios"));
|
|
468
|
+
var import_libsodium_wrappers = __toESM(require("libsodium-wrappers"));
|
|
469
|
+
import_axios.default.defaults.timeout = 15 * 1e3;
|
|
380
470
|
async function createGiteeRepo(data) {
|
|
381
471
|
try {
|
|
382
472
|
const formData = new URLSearchParams();
|
|
@@ -432,12 +522,74 @@ async function replaceGithubRepositoryTopics(authToken, data) {
|
|
|
432
522
|
return null;
|
|
433
523
|
}
|
|
434
524
|
}
|
|
525
|
+
async function getAuthorWebsiteFromGithubAPI(githubUsername) {
|
|
526
|
+
try {
|
|
527
|
+
const userData = (await import_axios.default.get(`${GITHUB_API_URL}/users/${githubUsername}`)).data;
|
|
528
|
+
const authorWebsite = userData?.blog;
|
|
529
|
+
return authorWebsite || "";
|
|
530
|
+
} catch (error) {
|
|
531
|
+
console.error(error);
|
|
532
|
+
return "";
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function getLtsNodeVersionByIndexJson() {
|
|
536
|
+
const resp = await import_axios.default.get(NODE_INDEX_URL);
|
|
537
|
+
return resp.data?.find((e) => e.lts)?.version?.replace("v", "");
|
|
538
|
+
}
|
|
539
|
+
async function getLtsNodeVersionByHtml(url) {
|
|
540
|
+
const html = (await import_axios.default.get(url)).data;
|
|
541
|
+
return html.match(/<strong>(.*)<\/strong>/)?.[1]?.trim();
|
|
542
|
+
}
|
|
543
|
+
async function getFastUrl(urls) {
|
|
544
|
+
const fast = await Promise.any(urls.map((url) => (0, import_axios.default)({
|
|
545
|
+
url,
|
|
546
|
+
method: "HEAD",
|
|
547
|
+
timeout: 15 * 1e3,
|
|
548
|
+
headers: {
|
|
549
|
+
"Accept-Encoding": ""
|
|
550
|
+
}
|
|
551
|
+
})));
|
|
552
|
+
return fast?.config?.url;
|
|
553
|
+
}
|
|
554
|
+
async function getARepositoryPublicKey(token, data) {
|
|
555
|
+
const response = await import_axios.default.get(`https://api.github.com/repos/${data.owner}/${data.repo}/actions/secrets/public-key`, {
|
|
556
|
+
headers: {
|
|
557
|
+
Authorization: `token ${token}`,
|
|
558
|
+
"Content-Type": "application/json"
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
return response.data;
|
|
562
|
+
}
|
|
563
|
+
async function createOrUpdateARepositorySecret(token, data) {
|
|
564
|
+
const { secret_value, secret_name, owner, repo, ...other } = data;
|
|
565
|
+
const { key, key_id } = await getARepositoryPublicKey(token, { owner, repo });
|
|
566
|
+
const binkey = import_libsodium_wrappers.default.from_base64(key, import_libsodium_wrappers.default.base64_variants.ORIGINAL);
|
|
567
|
+
const binsec = import_libsodium_wrappers.default.from_string(secret_value);
|
|
568
|
+
const encBytes = import_libsodium_wrappers.default.crypto_box_seal(binsec, binkey);
|
|
569
|
+
const encrypted_value = import_libsodium_wrappers.default.to_base64(encBytes, import_libsodium_wrappers.default.base64_variants.ORIGINAL);
|
|
570
|
+
const newData = {
|
|
571
|
+
...other,
|
|
572
|
+
owner,
|
|
573
|
+
repo,
|
|
574
|
+
encrypted_value,
|
|
575
|
+
key_id
|
|
576
|
+
};
|
|
577
|
+
const response = await import_axios.default.put(`https://api.github.com/repos/${owner}/${repo}/actions/secrets/${secret_name}`, newData, {
|
|
578
|
+
headers: {
|
|
579
|
+
Authorization: `token ${token}`,
|
|
580
|
+
"Content-Type": "application/json"
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
return response.data;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/utils/utils.ts
|
|
435
587
|
async function loadTemplateCliConfig() {
|
|
436
|
-
const paths = [process.cwd(), import_os.default.homedir()].map((e) =>
|
|
588
|
+
const paths = [process.cwd(), import_os.default.homedir()].map((e) => import_path2.default.join(e, ".ctrc"));
|
|
437
589
|
const [local, home] = (await Promise.all(paths.map(async (p) => {
|
|
438
590
|
try {
|
|
439
|
-
if (await
|
|
440
|
-
return
|
|
591
|
+
if (await import_fs_extra3.default.pathExists(p)) {
|
|
592
|
+
return import_fs_extra3.default.readJSON(p);
|
|
441
593
|
}
|
|
442
594
|
return null;
|
|
443
595
|
} catch (error) {
|
|
@@ -457,7 +609,7 @@ async function loadTemplateCliConfig() {
|
|
|
457
609
|
}
|
|
458
610
|
async function downloadGitRepo(repository, destination, options = {}) {
|
|
459
611
|
const fastRepo = await getFastGitRepo(repository);
|
|
460
|
-
const loading = (0,
|
|
612
|
+
const loading = (0, import_ora2.default)(`正在下载模板 - ${repository}`);
|
|
461
613
|
loading.start();
|
|
462
614
|
return Promise.any([
|
|
463
615
|
new Promise((resolve) => {
|
|
@@ -474,7 +626,7 @@ async function downloadGitRepo(repository, destination, options = {}) {
|
|
|
474
626
|
]);
|
|
475
627
|
}
|
|
476
628
|
async function getFastGitRepo(repository) {
|
|
477
|
-
const loading = (0,
|
|
629
|
+
const loading = (0, import_ora2.default)(`正在选择镜像源 - ${repository}`);
|
|
478
630
|
loading.start();
|
|
479
631
|
try {
|
|
480
632
|
const fastUrl = await getFastUrl(REMOTES.map((remote) => `${remote}/${repository}/archive/refs/heads/master.zip`));
|
|
@@ -507,7 +659,7 @@ async function asyncExec(cmd, options) {
|
|
|
507
659
|
}
|
|
508
660
|
async function initProject(answers) {
|
|
509
661
|
const { name, template } = answers;
|
|
510
|
-
const projectPath =
|
|
662
|
+
const projectPath = import_path2.default.join(process.cwd(), name);
|
|
511
663
|
await downloadGitRepo(`CaoMeiYouRen/${template}`, projectPath);
|
|
512
664
|
await init(projectPath, answers);
|
|
513
665
|
return "- 下载项目模板成功!";
|
|
@@ -643,12 +795,8 @@ async function init(projectPath, answers) {
|
|
|
643
795
|
console.error(import_colors.default.red(error));
|
|
644
796
|
}
|
|
645
797
|
}
|
|
646
|
-
async function getGitUserName() {
|
|
647
|
-
const username = await asyncExec("git config user.name") || "";
|
|
648
|
-
return username?.trim();
|
|
649
|
-
}
|
|
650
798
|
async function initRemoteGitRepo(projectPath, answers) {
|
|
651
|
-
const loading = (0,
|
|
799
|
+
const loading = (0, import_ora2.default)("正在初始化远程 Git 仓库……").start();
|
|
652
800
|
try {
|
|
653
801
|
const { name, description, gitRemoteUrl, isOpenSource, isInitRemoteRepo, keywords, template, isPublishToNpm } = answers;
|
|
654
802
|
const templateMeta = getTemplateMeta(template);
|
|
@@ -696,17 +844,11 @@ async function initRemoteGitRepo(projectPath, answers) {
|
|
|
696
844
|
if (templateMeta.docker) {
|
|
697
845
|
keywords.push("docker");
|
|
698
846
|
}
|
|
699
|
-
if (templateMeta?.language) {
|
|
700
|
-
keywords.push(templateMeta?.language);
|
|
701
|
-
}
|
|
702
847
|
if (templateMeta?.runtime) {
|
|
703
848
|
keywords.push(templateMeta?.runtime);
|
|
704
849
|
}
|
|
705
|
-
if (templateMeta?.
|
|
706
|
-
keywords.push(
|
|
707
|
-
}
|
|
708
|
-
if (templateMeta.tags?.length) {
|
|
709
|
-
keywords.push(...templateMeta.tags);
|
|
850
|
+
if (templateMeta?.language) {
|
|
851
|
+
keywords.push(templateMeta?.language);
|
|
710
852
|
}
|
|
711
853
|
await replaceGithubRepositoryTopics(authToken, {
|
|
712
854
|
owner,
|
|
@@ -714,9 +856,35 @@ async function initRemoteGitRepo(projectPath, answers) {
|
|
|
714
856
|
topics: (0, import_lodash.uniq)(keywords).map((e) => kebabCase(e))
|
|
715
857
|
});
|
|
716
858
|
console.info(import_colors.default.green("仓库 topics 初始化成功!"));
|
|
859
|
+
console.info(import_colors.default.green("正在初始化仓库 action secret !"));
|
|
860
|
+
const { DOCKER_USERNAME, DOCKER_PASSWORD, NPM_TOKEN } = config;
|
|
861
|
+
if (isPublishToNpm && NPM_TOKEN) {
|
|
862
|
+
await createOrUpdateARepositorySecret(authToken, {
|
|
863
|
+
owner,
|
|
864
|
+
repo,
|
|
865
|
+
secret_name: "NPM_TOKEN",
|
|
866
|
+
secret_value: NPM_TOKEN
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
if (templateMeta.docker && DOCKER_USERNAME && DOCKER_PASSWORD) {
|
|
870
|
+
await createOrUpdateARepositorySecret(authToken, {
|
|
871
|
+
owner,
|
|
872
|
+
repo,
|
|
873
|
+
secret_name: "DOCKER_USERNAME",
|
|
874
|
+
secret_value: DOCKER_USERNAME
|
|
875
|
+
});
|
|
876
|
+
await createOrUpdateARepositorySecret(authToken, {
|
|
877
|
+
owner,
|
|
878
|
+
repo,
|
|
879
|
+
secret_name: "DOCKER_PASSWORD",
|
|
880
|
+
secret_value: DOCKER_PASSWORD
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
console.info(import_colors.default.green("仓库 action secret 初始化成功!"));
|
|
884
|
+
return;
|
|
717
885
|
}
|
|
718
|
-
} else {
|
|
719
886
|
loading.fail("远程 Git 仓库初始化失败!");
|
|
887
|
+
return;
|
|
720
888
|
}
|
|
721
889
|
return;
|
|
722
890
|
}
|
|
@@ -751,7 +919,7 @@ async function initRemoteGitRepo(projectPath, answers) {
|
|
|
751
919
|
}
|
|
752
920
|
}
|
|
753
921
|
async function installNpmPackages(projectPath) {
|
|
754
|
-
const loading = (0,
|
|
922
|
+
const loading = (0, import_ora2.default)("正在安装依赖……").start();
|
|
755
923
|
try {
|
|
756
924
|
const files = [".npmrc"];
|
|
757
925
|
await copyFilesFromTemplates(projectPath, files);
|
|
@@ -765,7 +933,7 @@ async function installNpmPackages(projectPath) {
|
|
|
765
933
|
}
|
|
766
934
|
}
|
|
767
935
|
async function initCommonDependencies(projectPath, answers) {
|
|
768
|
-
const loading = (0,
|
|
936
|
+
const loading = (0, import_ora2.default)("正在初始化 常见依赖……").start();
|
|
769
937
|
try {
|
|
770
938
|
const { commonDependencies = [] } = answers;
|
|
771
939
|
const pkg = await getProjectJson(projectPath);
|
|
@@ -811,9 +979,9 @@ async function initDependabot(projectPath, answers) {
|
|
|
811
979
|
} else {
|
|
812
980
|
const pkg = await getProjectJson(projectPath);
|
|
813
981
|
if (pkg?.devDependencies?.["semantic-release"]) {
|
|
814
|
-
const dependabotPath =
|
|
815
|
-
if (await
|
|
816
|
-
const dependabot = import_yaml.default.parse(await
|
|
982
|
+
const dependabotPath = import_path2.default.join(projectPath, ".github/dependabot.yml");
|
|
983
|
+
if (await import_fs_extra3.default.pathExists(dependabotPath)) {
|
|
984
|
+
const dependabot = import_yaml.default.parse(await import_fs_extra3.default.readFile(dependabotPath, "utf-8"));
|
|
817
985
|
if (dependabot?.updates?.[0]["package-ecosystem"] === "npm") {
|
|
818
986
|
dependabot.updates[0].ignore = (0, import_lodash.uniqBy)([
|
|
819
987
|
...dependabot?.updates?.[0].ignore || [],
|
|
@@ -830,7 +998,7 @@ async function initDependabot(projectPath, answers) {
|
|
|
830
998
|
versions: [">= 19.0.0"]
|
|
831
999
|
}
|
|
832
1000
|
], (e) => e["dependency-name"]);
|
|
833
|
-
|
|
1001
|
+
import_fs_extra3.default.writeFile(dependabotPath, import_yaml.default.stringify(dependabot));
|
|
834
1002
|
}
|
|
835
1003
|
}
|
|
836
1004
|
}
|
|
@@ -852,10 +1020,10 @@ async function initYarn(projectPath, answers) {
|
|
|
852
1020
|
}
|
|
853
1021
|
async function initTsconfig(projectPath, answers) {
|
|
854
1022
|
try {
|
|
855
|
-
const tsconfigPath =
|
|
1023
|
+
const tsconfigPath = import_path2.default.join(projectPath, "tsconfig.json");
|
|
856
1024
|
const { jsModuleType } = answers;
|
|
857
|
-
if (await
|
|
858
|
-
const tsconfigStr = await
|
|
1025
|
+
if (await import_fs_extra3.default.pathExists(tsconfigPath)) {
|
|
1026
|
+
const tsconfigStr = await import_fs_extra3.default.readFile(tsconfigPath, "utf8");
|
|
859
1027
|
const tsconfig = import_json5.default.parse(tsconfigStr);
|
|
860
1028
|
if (tsconfig?.compilerOptions?.importHelpers) {
|
|
861
1029
|
const pkg = await getProjectJson(projectPath);
|
|
@@ -893,7 +1061,7 @@ async function initTsconfig(projectPath, answers) {
|
|
|
893
1061
|
break;
|
|
894
1062
|
}
|
|
895
1063
|
if (hasChanges) {
|
|
896
|
-
await
|
|
1064
|
+
await import_fs_extra3.default.writeFile(tsconfigPath, JSON.stringify(newTsconfig, null, 4));
|
|
897
1065
|
}
|
|
898
1066
|
}
|
|
899
1067
|
}
|
|
@@ -902,7 +1070,7 @@ async function initTsconfig(projectPath, answers) {
|
|
|
902
1070
|
}
|
|
903
1071
|
}
|
|
904
1072
|
async function initProjectJson(projectPath, projectInfos) {
|
|
905
|
-
const loading = (0,
|
|
1073
|
+
const loading = (0, import_ora2.default)("正在初始化 package.json ……").start();
|
|
906
1074
|
try {
|
|
907
1075
|
const { packageName, engines, license, homepage, issuesUrl, gitUrl, author, description, keywords = [], isOpenSource, isPublishToNpm = false, jsModuleType } = projectInfos;
|
|
908
1076
|
const pkg = await getProjectJson(projectPath);
|
|
@@ -945,6 +1113,7 @@ async function initProjectJson(projectPath, projectInfos) {
|
|
|
945
1113
|
break;
|
|
946
1114
|
}
|
|
947
1115
|
const newPkg = (0, import_lodash.merge)({}, pkg, pkgData, extData);
|
|
1116
|
+
newPkg.keywords = (0, import_lodash.uniq)(keywords);
|
|
948
1117
|
await saveProjectJson(projectPath, newPkg);
|
|
949
1118
|
loading.succeed("package.json 初始化成功!");
|
|
950
1119
|
return newPkg;
|
|
@@ -955,7 +1124,7 @@ async function initProjectJson(projectPath, projectInfos) {
|
|
|
955
1124
|
}
|
|
956
1125
|
var cleanText = (text) => text.replace(/-/g, "--").replace(/_/g, "__");
|
|
957
1126
|
async function getProjectInfo(projectPath, answers) {
|
|
958
|
-
const loading = (0,
|
|
1127
|
+
const loading = (0, import_ora2.default)("正在获取项目信息 ……").start();
|
|
959
1128
|
try {
|
|
960
1129
|
const { name, author, description, template, isOpenSource, isPublishToNpm, license = "UNLICENSED", isPrivateScopePackage, scopeName, isInitDocker = false } = answers;
|
|
961
1130
|
const templateMeta = getTemplateMeta(template);
|
|
@@ -965,6 +1134,22 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
965
1134
|
const pkg = await getProjectJson(projectPath);
|
|
966
1135
|
const nodeVersion = await getLtsNodeVersion() || "20";
|
|
967
1136
|
const node = Number(nodeVersion) - 4;
|
|
1137
|
+
let keywords = [
|
|
1138
|
+
...answers.keywords || []
|
|
1139
|
+
];
|
|
1140
|
+
if (templateMeta.docker) {
|
|
1141
|
+
keywords.push("docker");
|
|
1142
|
+
}
|
|
1143
|
+
if (templateMeta?.language) {
|
|
1144
|
+
keywords.push(templateMeta?.language);
|
|
1145
|
+
}
|
|
1146
|
+
if (templateMeta?.vueVersion === 3) {
|
|
1147
|
+
keywords.push("vue3");
|
|
1148
|
+
}
|
|
1149
|
+
if (templateMeta.tags?.length) {
|
|
1150
|
+
keywords.push(...templateMeta.tags);
|
|
1151
|
+
}
|
|
1152
|
+
keywords = (0, import_lodash.uniq)(keywords).map((e) => kebabCase(e));
|
|
968
1153
|
const packageName = isPrivateScopePackage ? `@${scopeName}/${name}` : name;
|
|
969
1154
|
const engines = (0, import_lodash.merge)({}, pkg?.engines, { node: `>=${node}` });
|
|
970
1155
|
const version = pkg?.version || "0.1.0";
|
|
@@ -984,7 +1169,9 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
984
1169
|
const patreonUsername = config?.PATREON_USERNAME;
|
|
985
1170
|
const npmUsername = config?.NPM_USERNAME || githubUsername;
|
|
986
1171
|
const dockerUsername = config?.DOCKER_USERNAME || githubUsername?.toLowerCase();
|
|
1172
|
+
const dockerPassword = config?.DOCKER_PASSWORD || "";
|
|
987
1173
|
const contactEmail = config?.CONTACT_EMAIL || "";
|
|
1174
|
+
const npmToken = config?.NPM_TOKEN || "";
|
|
988
1175
|
const repositoryUrl = `https://github.com/${githubUsername}/${projectName}`;
|
|
989
1176
|
const gitUrl = `git+${repositoryUrl}.git`;
|
|
990
1177
|
const issuesUrl = `${repositoryUrl}/issues`;
|
|
@@ -998,6 +1185,7 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
998
1185
|
const authorWebsite = isOpenSource ? await getAuthorWebsiteFromGithubAPI(githubUsername) : "";
|
|
999
1186
|
const projectInfos = {
|
|
1000
1187
|
...answers,
|
|
1188
|
+
keywords,
|
|
1001
1189
|
currentYear: (/* @__PURE__ */ new Date()).getFullYear(),
|
|
1002
1190
|
name,
|
|
1003
1191
|
description,
|
|
@@ -1051,10 +1239,12 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
1051
1239
|
twitterUsername,
|
|
1052
1240
|
npmUsername,
|
|
1053
1241
|
dockerUsername,
|
|
1242
|
+
dockerPassword,
|
|
1054
1243
|
templateMeta,
|
|
1055
1244
|
mainFile,
|
|
1056
1245
|
isInitDocker,
|
|
1057
|
-
contactEmail
|
|
1246
|
+
contactEmail,
|
|
1247
|
+
npmToken
|
|
1058
1248
|
};
|
|
1059
1249
|
loading.succeed("项目信息 初始化成功!");
|
|
1060
1250
|
return projectInfos;
|
|
@@ -1065,12 +1255,12 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
1065
1255
|
}
|
|
1066
1256
|
}
|
|
1067
1257
|
async function initReadme(projectPath, projectInfos) {
|
|
1068
|
-
const loading = (0,
|
|
1258
|
+
const loading = (0, import_ora2.default)("正在初始化 README.md ……").start();
|
|
1069
1259
|
try {
|
|
1070
|
-
const templatePath =
|
|
1071
|
-
const template = (await
|
|
1072
|
-
const newReadmePath =
|
|
1073
|
-
const readmeContent = await
|
|
1260
|
+
const templatePath = import_path2.default.join(__dirname, "../templates/README.md");
|
|
1261
|
+
const template = (await import_fs_extra3.default.readFile(templatePath, "utf8")).toString();
|
|
1262
|
+
const newReadmePath = import_path2.default.join(projectPath, "README.md");
|
|
1263
|
+
const readmeContent = await import_ejs2.default.render(
|
|
1074
1264
|
template,
|
|
1075
1265
|
projectInfos,
|
|
1076
1266
|
{
|
|
@@ -1079,7 +1269,7 @@ async function initReadme(projectPath, projectInfos) {
|
|
|
1079
1269
|
}
|
|
1080
1270
|
);
|
|
1081
1271
|
await removeFiles(projectPath, ["README.md"]);
|
|
1082
|
-
await
|
|
1272
|
+
await import_fs_extra3.default.writeFile(newReadmePath, lintMd((0, import_lodash.unescape)(readmeContent)));
|
|
1083
1273
|
loading.succeed("README.md 初始化成功!");
|
|
1084
1274
|
} catch (error) {
|
|
1085
1275
|
loading.fail("README.md 初始化失败!");
|
|
@@ -1087,12 +1277,12 @@ async function initReadme(projectPath, projectInfos) {
|
|
|
1087
1277
|
}
|
|
1088
1278
|
}
|
|
1089
1279
|
async function initContributing(projectPath, projectInfos) {
|
|
1090
|
-
const loading = (0,
|
|
1280
|
+
const loading = (0, import_ora2.default)("正在初始化 贡献指南 ……").start();
|
|
1091
1281
|
try {
|
|
1092
|
-
const templatePath =
|
|
1093
|
-
const template = (await
|
|
1094
|
-
const newContributingPath =
|
|
1095
|
-
const content = await
|
|
1282
|
+
const templatePath = import_path2.default.join(__dirname, "../templates/CONTRIBUTING.md");
|
|
1283
|
+
const template = (await import_fs_extra3.default.readFile(templatePath, "utf8")).toString();
|
|
1284
|
+
const newContributingPath = import_path2.default.join(projectPath, "CONTRIBUTING.md");
|
|
1285
|
+
const content = await import_ejs2.default.render(
|
|
1096
1286
|
template,
|
|
1097
1287
|
projectInfos,
|
|
1098
1288
|
{
|
|
@@ -1101,7 +1291,7 @@ async function initContributing(projectPath, projectInfos) {
|
|
|
1101
1291
|
}
|
|
1102
1292
|
);
|
|
1103
1293
|
await removeFiles(projectPath, ["CONTRIBUTING.md"]);
|
|
1104
|
-
await
|
|
1294
|
+
await import_fs_extra3.default.writeFile(newContributingPath, lintMd((0, import_lodash.unescape)(content)));
|
|
1105
1295
|
loading.succeed("贡献指南 初始化成功!");
|
|
1106
1296
|
} catch (error) {
|
|
1107
1297
|
loading.fail("贡献指南 初始化失败!");
|
|
@@ -1109,12 +1299,12 @@ async function initContributing(projectPath, projectInfos) {
|
|
|
1109
1299
|
}
|
|
1110
1300
|
}
|
|
1111
1301
|
async function initCodeOfConduct(projectPath, projectInfos) {
|
|
1112
|
-
const loading = (0,
|
|
1302
|
+
const loading = (0, import_ora2.default)("正在初始化 贡献者公约 ……").start();
|
|
1113
1303
|
try {
|
|
1114
|
-
const templatePath =
|
|
1115
|
-
const template = (await
|
|
1116
|
-
const newPath =
|
|
1117
|
-
const content = await
|
|
1304
|
+
const templatePath = import_path2.default.join(__dirname, "../templates/CODE_OF_CONDUCT.md");
|
|
1305
|
+
const template = (await import_fs_extra3.default.readFile(templatePath, "utf8")).toString();
|
|
1306
|
+
const newPath = import_path2.default.join(projectPath, "CODE_OF_CONDUCT.md");
|
|
1307
|
+
const content = await import_ejs2.default.render(
|
|
1118
1308
|
template,
|
|
1119
1309
|
projectInfos,
|
|
1120
1310
|
{
|
|
@@ -1123,7 +1313,7 @@ async function initCodeOfConduct(projectPath, projectInfos) {
|
|
|
1123
1313
|
}
|
|
1124
1314
|
);
|
|
1125
1315
|
await removeFiles(projectPath, ["CODE_OF_CONDUCT.md"]);
|
|
1126
|
-
await
|
|
1316
|
+
await import_fs_extra3.default.writeFile(newPath, lintMd((0, import_lodash.unescape)(content)));
|
|
1127
1317
|
loading.succeed("贡献者公约 初始化成功!");
|
|
1128
1318
|
} catch (error) {
|
|
1129
1319
|
loading.fail("贡献者公约 初始化失败!");
|
|
@@ -1131,17 +1321,17 @@ async function initCodeOfConduct(projectPath, projectInfos) {
|
|
|
1131
1321
|
}
|
|
1132
1322
|
}
|
|
1133
1323
|
async function initLicense(projectPath, projectInfos) {
|
|
1134
|
-
const loading = (0,
|
|
1324
|
+
const loading = (0, import_ora2.default)("正在初始化 LICENSE ……").start();
|
|
1135
1325
|
try {
|
|
1136
1326
|
const { license } = projectInfos;
|
|
1137
|
-
const templatePath =
|
|
1138
|
-
if (!await
|
|
1327
|
+
const templatePath = import_path2.default.join(__dirname, "../templates/licenses/", license);
|
|
1328
|
+
if (!await import_fs_extra3.default.pathExists(templatePath)) {
|
|
1139
1329
|
loading.fail("无效的 LICENSE Name");
|
|
1140
1330
|
return;
|
|
1141
1331
|
}
|
|
1142
|
-
const template = (await
|
|
1143
|
-
const newPath =
|
|
1144
|
-
const content = await
|
|
1332
|
+
const template = (await import_fs_extra3.default.readFile(templatePath, "utf8")).toString();
|
|
1333
|
+
const newPath = import_path2.default.join(projectPath, "LICENSE");
|
|
1334
|
+
const content = await import_ejs2.default.render(
|
|
1145
1335
|
template,
|
|
1146
1336
|
projectInfos,
|
|
1147
1337
|
{
|
|
@@ -1150,7 +1340,7 @@ async function initLicense(projectPath, projectInfos) {
|
|
|
1150
1340
|
}
|
|
1151
1341
|
);
|
|
1152
1342
|
await removeFiles(projectPath, ["LICENSE"]);
|
|
1153
|
-
await
|
|
1343
|
+
await import_fs_extra3.default.writeFile(newPath, (0, import_lodash.unescape)(content));
|
|
1154
1344
|
loading.succeed("LICENSE 初始化成功!");
|
|
1155
1345
|
} catch (error) {
|
|
1156
1346
|
loading.fail("LICENSE 初始化失败!");
|
|
@@ -1167,13 +1357,13 @@ async function initConfig(projectPath) {
|
|
|
1167
1357
|
}
|
|
1168
1358
|
}
|
|
1169
1359
|
async function initGithubWorkflows(projectPath, answers) {
|
|
1170
|
-
const loading = (0,
|
|
1360
|
+
const loading = (0, import_ora2.default)("正在初始化 Github Workflows ……").start();
|
|
1171
1361
|
try {
|
|
1172
1362
|
const { isInitSemanticRelease } = answers;
|
|
1173
1363
|
const files = [".github/workflows/test.yml", ".github/workflows/todo.yml"];
|
|
1174
|
-
const dir =
|
|
1175
|
-
if (!await
|
|
1176
|
-
await
|
|
1364
|
+
const dir = import_path2.default.join(projectPath, ".github/workflows");
|
|
1365
|
+
if (!await import_fs_extra3.default.pathExists(dir)) {
|
|
1366
|
+
await import_fs_extra3.default.mkdirp(dir);
|
|
1177
1367
|
}
|
|
1178
1368
|
const releaseYml = ".github/workflows/release.yml";
|
|
1179
1369
|
if (isInitSemanticRelease) {
|
|
@@ -1190,7 +1380,7 @@ async function initGithubWorkflows(projectPath, answers) {
|
|
|
1190
1380
|
}
|
|
1191
1381
|
}
|
|
1192
1382
|
async function initSemanticRelease(projectPath) {
|
|
1193
|
-
const loading = (0,
|
|
1383
|
+
const loading = (0, import_ora2.default)("正在初始化 semantic-release ……").start();
|
|
1194
1384
|
try {
|
|
1195
1385
|
const pkg = await getProjectJson(projectPath);
|
|
1196
1386
|
const files = [".releaserc.js", ".releaserc.cjs"];
|
|
@@ -1224,12 +1414,12 @@ async function initSemanticRelease(projectPath) {
|
|
|
1224
1414
|
}
|
|
1225
1415
|
}
|
|
1226
1416
|
async function initHusky(projectPath) {
|
|
1227
|
-
const loading = (0,
|
|
1417
|
+
const loading = (0, import_ora2.default)("正在初始化 husky ……").start();
|
|
1228
1418
|
try {
|
|
1229
1419
|
const files = [".husky/commit-msg", ".husky/pre-commit"];
|
|
1230
|
-
const dir =
|
|
1231
|
-
if (!await
|
|
1232
|
-
await
|
|
1420
|
+
const dir = import_path2.default.join(projectPath, ".husky");
|
|
1421
|
+
if (!await import_fs_extra3.default.pathExists(dir)) {
|
|
1422
|
+
await import_fs_extra3.default.mkdirp(dir);
|
|
1233
1423
|
}
|
|
1234
1424
|
await copyFilesFromTemplates(projectPath, files);
|
|
1235
1425
|
const extnames = ["js", "ts"];
|
|
@@ -1270,7 +1460,7 @@ async function initHusky(projectPath) {
|
|
|
1270
1460
|
}
|
|
1271
1461
|
}
|
|
1272
1462
|
async function initEslint(projectPath, answers) {
|
|
1273
|
-
const loading = (0,
|
|
1463
|
+
const loading = (0, import_ora2.default)("正在初始化 eslint ……").start();
|
|
1274
1464
|
try {
|
|
1275
1465
|
const templateMeta = getTemplateMeta(answers.template);
|
|
1276
1466
|
const pkg = await getProjectJson(projectPath);
|
|
@@ -1319,10 +1509,10 @@ async function initEslint(projectPath, answers) {
|
|
|
1319
1509
|
root: true,
|
|
1320
1510
|
extends: '${eslintType}',
|
|
1321
1511
|
}`;
|
|
1322
|
-
const cjsPath =
|
|
1323
|
-
const jsPath =
|
|
1324
|
-
if (!await
|
|
1325
|
-
await
|
|
1512
|
+
const cjsPath = import_path2.default.join(projectPath, ".eslintrc.cjs");
|
|
1513
|
+
const jsPath = import_path2.default.join(projectPath, ".eslintrc.js");
|
|
1514
|
+
if (!await import_fs_extra3.default.pathExists(cjsPath) && !await import_fs_extra3.default.pathExists(jsPath)) {
|
|
1515
|
+
await import_fs_extra3.default.writeFile(jsPath, eslintrc);
|
|
1326
1516
|
}
|
|
1327
1517
|
loading.succeed("eslint 初始化成功!");
|
|
1328
1518
|
} catch (error) {
|
|
@@ -1331,7 +1521,7 @@ async function initEslint(projectPath, answers) {
|
|
|
1331
1521
|
}
|
|
1332
1522
|
}
|
|
1333
1523
|
async function initStylelint(projectPath) {
|
|
1334
|
-
const loading = (0,
|
|
1524
|
+
const loading = (0, import_ora2.default)("正在初始化 stylelint ……").start();
|
|
1335
1525
|
try {
|
|
1336
1526
|
const pkg = await getProjectJson(projectPath);
|
|
1337
1527
|
const extnames = ["html", "css", "scss", "sass"];
|
|
@@ -1376,7 +1566,7 @@ async function initStylelint(projectPath) {
|
|
|
1376
1566
|
}
|
|
1377
1567
|
}
|
|
1378
1568
|
async function initCommitizen(projectPath) {
|
|
1379
|
-
const loading = (0,
|
|
1569
|
+
const loading = (0, import_ora2.default)("正在初始化 commitizen ……").start();
|
|
1380
1570
|
try {
|
|
1381
1571
|
const pkg = await getProjectJson(projectPath);
|
|
1382
1572
|
const devDependencies = {
|
|
@@ -1409,21 +1599,21 @@ async function initCommitizen(projectPath) {
|
|
|
1409
1599
|
}
|
|
1410
1600
|
}
|
|
1411
1601
|
async function initDocker(projectPath, answers) {
|
|
1412
|
-
const loading = (0,
|
|
1602
|
+
const loading = (0, import_ora2.default)("正在初始化 Docker ……").start();
|
|
1413
1603
|
try {
|
|
1414
1604
|
const { name } = answers;
|
|
1415
1605
|
if (answers.template === "hono-template") {
|
|
1416
|
-
const dockerComposePath =
|
|
1417
|
-
if (await
|
|
1418
|
-
let dockerCompose = await
|
|
1606
|
+
const dockerComposePath = import_path2.default.join(projectPath, "docker-compose.yml");
|
|
1607
|
+
if (await import_fs_extra3.default.pathExists(dockerComposePath)) {
|
|
1608
|
+
let dockerCompose = await import_fs_extra3.default.readFile(dockerComposePath, "utf-8");
|
|
1419
1609
|
dockerCompose = dockerCompose.replaceAll("hono-template", name);
|
|
1420
|
-
await
|
|
1610
|
+
await import_fs_extra3.default.writeFile(dockerComposePath, dockerCompose);
|
|
1421
1611
|
}
|
|
1422
|
-
const wranglerPath =
|
|
1423
|
-
if (await
|
|
1424
|
-
let wrangler = await
|
|
1612
|
+
const wranglerPath = import_path2.default.join(projectPath, "wrangler.toml");
|
|
1613
|
+
if (await import_fs_extra3.default.pathExists(wranglerPath)) {
|
|
1614
|
+
let wrangler = await import_fs_extra3.default.readFile(wranglerPath, "utf-8");
|
|
1425
1615
|
wrangler = wrangler.replaceAll("hono-template", name);
|
|
1426
|
-
await
|
|
1616
|
+
await import_fs_extra3.default.writeFile(wranglerPath, wrangler);
|
|
1427
1617
|
}
|
|
1428
1618
|
loading.succeed("Docker 初始化成功!");
|
|
1429
1619
|
return;
|
|
@@ -1432,27 +1622,27 @@ async function initDocker(projectPath, answers) {
|
|
|
1432
1622
|
const files = [".dockerignore", "docker-compose.yml", ".github/workflows/docker.yml"];
|
|
1433
1623
|
await copyFilesFromTemplates(projectPath, files);
|
|
1434
1624
|
let dockerfile = "Dockerfile";
|
|
1435
|
-
const newPath =
|
|
1436
|
-
if (await
|
|
1437
|
-
await
|
|
1625
|
+
const newPath = import_path2.default.join(projectPath, "Dockerfile");
|
|
1626
|
+
if (await import_fs_extra3.default.pathExists(newPath)) {
|
|
1627
|
+
await import_fs_extra3.default.remove(newPath);
|
|
1438
1628
|
}
|
|
1439
1629
|
if (templateMeta?.runtime === "java") {
|
|
1440
|
-
const templatePath =
|
|
1630
|
+
const templatePath = import_path2.default.join(__dirname, "../templates/java/Dockerfile.ejs");
|
|
1441
1631
|
await ejsRender(templatePath, { javaVersion: templateMeta?.javaVersion }, newPath);
|
|
1442
1632
|
loading.succeed("Docker 初始化成功!");
|
|
1443
1633
|
return;
|
|
1444
1634
|
}
|
|
1445
1635
|
if (templateMeta?.runtime === "nodejs") {
|
|
1446
1636
|
if (templateMeta?.runtime === "nodejs") {
|
|
1447
|
-
const scriptsDir =
|
|
1448
|
-
if (!await
|
|
1449
|
-
await
|
|
1637
|
+
const scriptsDir = import_path2.default.join(projectPath, "scripts");
|
|
1638
|
+
if (!await import_fs_extra3.default.pathExists(scriptsDir)) {
|
|
1639
|
+
await import_fs_extra3.default.mkdir(scriptsDir);
|
|
1450
1640
|
}
|
|
1451
1641
|
await copyFilesFromTemplates(projectPath, ["scripts/minify-docker.cjs"]);
|
|
1452
1642
|
}
|
|
1453
1643
|
const pkg = await getProjectJson(projectPath);
|
|
1454
1644
|
const mainFile = pkg?.main;
|
|
1455
|
-
const templatePath =
|
|
1645
|
+
const templatePath = import_path2.default.join(__dirname, "../templates/Dockerfile");
|
|
1456
1646
|
await ejsRender(templatePath, { mainFile }, newPath);
|
|
1457
1647
|
loading.succeed("Docker 初始化成功!");
|
|
1458
1648
|
return;
|
|
@@ -1468,15 +1658,15 @@ async function initDocker(projectPath, answers) {
|
|
|
1468
1658
|
dockerfile = "Dockerfile";
|
|
1469
1659
|
break;
|
|
1470
1660
|
}
|
|
1471
|
-
const dockerfilePath =
|
|
1472
|
-
await
|
|
1661
|
+
const dockerfilePath = import_path2.default.join(__dirname, "../templates/", dockerfile);
|
|
1662
|
+
await import_fs_extra3.default.copyFile(dockerfilePath, newPath);
|
|
1473
1663
|
loading.succeed("Docker 初始化成功!");
|
|
1474
1664
|
} catch (error) {
|
|
1475
1665
|
loading.fail("Docker 初始化失败!");
|
|
1476
1666
|
}
|
|
1477
1667
|
}
|
|
1478
1668
|
async function initTest(projectPath, answers) {
|
|
1479
|
-
const loading = (0,
|
|
1669
|
+
const loading = (0, import_ora2.default)("正在初始化测试 ……").start();
|
|
1480
1670
|
try {
|
|
1481
1671
|
if (answers.isInitTest === "vitest") {
|
|
1482
1672
|
const files = ["vitest.config.ts"];
|
|
@@ -1539,40 +1729,40 @@ async function initTest(projectPath, answers) {
|
|
|
1539
1729
|
}
|
|
1540
1730
|
}
|
|
1541
1731
|
async function jsFileExtRename(projectPath) {
|
|
1542
|
-
const loading = (0,
|
|
1732
|
+
const loading = (0, import_ora2.default)("正在重命名 js 后缀名 ……").start();
|
|
1543
1733
|
try {
|
|
1544
|
-
const jsFiles = (await
|
|
1734
|
+
const jsFiles = (await import_fs_extra3.default.readdir(projectPath)).filter((file) => /\.js$/.test(file)).map((file) => import_path2.default.join(projectPath, file));
|
|
1545
1735
|
const pkg = await getProjectJson(projectPath);
|
|
1546
1736
|
if (pkg.type === "module") {
|
|
1547
1737
|
for await (const filepath of jsFiles) {
|
|
1548
|
-
const fileContent = await
|
|
1738
|
+
const fileContent = await import_fs_extra3.default.readFile(filepath, "utf-8");
|
|
1549
1739
|
const moduleType = getJsModuleType(fileContent);
|
|
1550
1740
|
console.log(`正在判断文件:${filepath} 的模块类型`);
|
|
1551
1741
|
if (moduleType === "CommonJS") {
|
|
1552
|
-
const dirpath =
|
|
1553
|
-
const extname =
|
|
1554
|
-
const basename = `${
|
|
1555
|
-
const newPath =
|
|
1556
|
-
if (await
|
|
1557
|
-
await
|
|
1742
|
+
const dirpath = import_path2.default.dirname(filepath);
|
|
1743
|
+
const extname = import_path2.default.extname(filepath);
|
|
1744
|
+
const basename = `${import_path2.default.basename(filepath, extname)}.cjs`;
|
|
1745
|
+
const newPath = import_path2.default.join(dirpath, basename);
|
|
1746
|
+
if (await import_fs_extra3.default.pathExists(newPath)) {
|
|
1747
|
+
await import_fs_extra3.default.remove(newPath);
|
|
1558
1748
|
}
|
|
1559
|
-
await
|
|
1749
|
+
await import_fs_extra3.default.rename(filepath, newPath);
|
|
1560
1750
|
}
|
|
1561
1751
|
}
|
|
1562
1752
|
} else if (pkg.type === "commonjs") {
|
|
1563
1753
|
for await (const filepath of jsFiles) {
|
|
1564
|
-
const fileContent = await
|
|
1754
|
+
const fileContent = await import_fs_extra3.default.readFile(filepath, "utf-8");
|
|
1565
1755
|
const moduleType = getJsModuleType(fileContent);
|
|
1566
1756
|
console.log(`正在判断文件:${filepath} 的模块类型`);
|
|
1567
1757
|
if (moduleType === "EsModule") {
|
|
1568
|
-
const dirpath =
|
|
1569
|
-
const extname =
|
|
1570
|
-
const basename = `${
|
|
1571
|
-
const newPath =
|
|
1572
|
-
if (await
|
|
1573
|
-
await
|
|
1758
|
+
const dirpath = import_path2.default.dirname(filepath);
|
|
1759
|
+
const extname = import_path2.default.extname(filepath);
|
|
1760
|
+
const basename = `${import_path2.default.basename(filepath, extname)}.mjs`;
|
|
1761
|
+
const newPath = import_path2.default.join(dirpath, basename);
|
|
1762
|
+
if (await import_fs_extra3.default.pathExists(newPath)) {
|
|
1763
|
+
await import_fs_extra3.default.remove(newPath);
|
|
1574
1764
|
}
|
|
1575
|
-
await
|
|
1765
|
+
await import_fs_extra3.default.rename(filepath, newPath);
|
|
1576
1766
|
}
|
|
1577
1767
|
}
|
|
1578
1768
|
}
|
|
@@ -1641,26 +1831,8 @@ async function sortProjectJson(projectPath) {
|
|
|
1641
1831
|
console.error(error);
|
|
1642
1832
|
}
|
|
1643
1833
|
}
|
|
1644
|
-
async function getAuthorWebsiteFromGithubAPI(githubUsername) {
|
|
1645
|
-
try {
|
|
1646
|
-
const userData = (await import_axios.default.get(`${GITHUB_API_URL}/users/${githubUsername}`)).data;
|
|
1647
|
-
const authorWebsite = userData?.blog;
|
|
1648
|
-
return authorWebsite || "";
|
|
1649
|
-
} catch (error) {
|
|
1650
|
-
console.error(error);
|
|
1651
|
-
return "";
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
async function getLtsNodeVersionByIndexJson() {
|
|
1655
|
-
const resp = await import_axios.default.get(NODE_INDEX_URL);
|
|
1656
|
-
return resp.data?.find((e) => e.lts)?.version?.replace("v", "");
|
|
1657
|
-
}
|
|
1658
|
-
async function getLtsNodeVersionByHtml(url) {
|
|
1659
|
-
const html = (await import_axios.default.get(url)).data;
|
|
1660
|
-
return html.match(/<strong>(.*)<\/strong>/)?.[1]?.trim();
|
|
1661
|
-
}
|
|
1662
1834
|
async function getLtsNodeVersion() {
|
|
1663
|
-
const loading = (0,
|
|
1835
|
+
const loading = (0, import_ora2.default)("正在获取 Node.js lts 版本号");
|
|
1664
1836
|
loading.start();
|
|
1665
1837
|
try {
|
|
1666
1838
|
const fastUrl = await getFastUrl([...NODEJS_URLS, NODE_INDEX_URL]);
|
|
@@ -1679,32 +1851,10 @@ async function getLtsNodeVersion() {
|
|
|
1679
1851
|
return "";
|
|
1680
1852
|
}
|
|
1681
1853
|
}
|
|
1682
|
-
async function getFastUrl(urls) {
|
|
1683
|
-
const fast = await Promise.any(urls.map((url) => (0, import_axios.default)({
|
|
1684
|
-
url,
|
|
1685
|
-
method: "HEAD",
|
|
1686
|
-
timeout: 15 * 1e3,
|
|
1687
|
-
headers: {
|
|
1688
|
-
"Accept-Encoding": ""
|
|
1689
|
-
}
|
|
1690
|
-
})));
|
|
1691
|
-
return fast?.config?.url;
|
|
1692
|
-
}
|
|
1693
1854
|
async function getNpmPackageVersion(name) {
|
|
1694
1855
|
const version = await asyncExec(`${PACKAGE_MANAGER} view ${name} version`) || "";
|
|
1695
1856
|
return version.trim();
|
|
1696
1857
|
}
|
|
1697
|
-
function lintMd(markdown) {
|
|
1698
|
-
const rules = {
|
|
1699
|
-
"no-empty-code": 0,
|
|
1700
|
-
"no-trailing-punctuation": 0,
|
|
1701
|
-
"no-long-code": 0,
|
|
1702
|
-
"no-empty-code-lang": 0,
|
|
1703
|
-
"no-empty-inlinecode": 0
|
|
1704
|
-
};
|
|
1705
|
-
const fixed = fix(markdown, rules);
|
|
1706
|
-
return fixed;
|
|
1707
|
-
}
|
|
1708
1858
|
function sortKey(obj) {
|
|
1709
1859
|
const keys = Object.keys(obj).sort((a, b) => a.localeCompare(b));
|
|
1710
1860
|
const obj2 = {};
|
|
@@ -1714,77 +1864,54 @@ function sortKey(obj) {
|
|
|
1714
1864
|
return obj2;
|
|
1715
1865
|
}
|
|
1716
1866
|
async function getProjectJson(projectPath) {
|
|
1717
|
-
const pkgPath =
|
|
1718
|
-
const pkg = await
|
|
1867
|
+
const pkgPath = import_path2.default.join(projectPath, "package.json");
|
|
1868
|
+
const pkg = await import_fs_extra3.default.readJSON(pkgPath);
|
|
1719
1869
|
return pkg;
|
|
1720
1870
|
}
|
|
1721
1871
|
async function saveProjectJson(projectPath, pkgData) {
|
|
1722
|
-
const pkgPath =
|
|
1872
|
+
const pkgPath = import_path2.default.join(projectPath, "package.json");
|
|
1723
1873
|
const pkg = await getProjectJson(projectPath);
|
|
1724
1874
|
const newPkg = Object.assign({}, pkg, pkgData);
|
|
1725
|
-
await
|
|
1875
|
+
await import_fs_extra3.default.writeFile(pkgPath, JSON.stringify(newPkg, null, 2));
|
|
1726
1876
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1877
|
+
|
|
1878
|
+
// src/plopfile.ts
|
|
1879
|
+
var import_fs_extra4 = __toESM(require("fs-extra"));
|
|
1880
|
+
var import_path3 = __toESM(require("path"));
|
|
1881
|
+
|
|
1882
|
+
// src/utils/exec.ts
|
|
1883
|
+
var import_child_process2 = require("child_process");
|
|
1884
|
+
var import_colors2 = __toESM(require("@colors/colors"));
|
|
1885
|
+
async function asyncExec2(cmd, options) {
|
|
1886
|
+
return new Promise((resolve, reject) => {
|
|
1887
|
+
const ls = (0, import_child_process2.exec)(cmd, options, (err, stdout, stderr) => {
|
|
1888
|
+
if (err) {
|
|
1889
|
+
return reject(err);
|
|
1738
1890
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1891
|
+
if (stderr) {
|
|
1892
|
+
return resolve(stderr);
|
|
1893
|
+
}
|
|
1894
|
+
resolve(stdout);
|
|
1895
|
+
});
|
|
1896
|
+
ls.stdout.on("data", (data) => {
|
|
1897
|
+
console.log(data);
|
|
1898
|
+
});
|
|
1899
|
+
ls.stderr.on("data", (data) => {
|
|
1900
|
+
console.log(import_colors2.default.red(data));
|
|
1901
|
+
});
|
|
1902
|
+
});
|
|
1747
1903
|
}
|
|
1748
|
-
|
|
1749
|
-
|
|
1904
|
+
|
|
1905
|
+
// src/utils/git.ts
|
|
1906
|
+
async function getGitUserName() {
|
|
1750
1907
|
try {
|
|
1751
|
-
|
|
1752
|
-
const newPath = import_path.default.join(projectPath, file);
|
|
1753
|
-
if (await import_fs_extra.default.pathExists(newPath)) {
|
|
1754
|
-
await import_fs_extra.default.remove(newPath);
|
|
1755
|
-
} else {
|
|
1756
|
-
console.log(`文件 ${file} 不存在,已跳过删除`);
|
|
1757
|
-
}
|
|
1758
|
-
}
|
|
1759
|
-
loading.succeed(`文件 ${files.join()} 删除成功!`);
|
|
1760
|
-
return true;
|
|
1908
|
+
return (await asyncExec2("git config user.name"))?.trim();
|
|
1761
1909
|
} catch (error) {
|
|
1762
|
-
|
|
1763
|
-
throw error;
|
|
1910
|
+
return "";
|
|
1764
1911
|
}
|
|
1765
1912
|
}
|
|
1766
|
-
function kebabCase(str) {
|
|
1767
|
-
return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/_+/g, "-").replace(/\s+/g, "-").toLowerCase();
|
|
1768
|
-
}
|
|
1769
|
-
function getTemplateMeta(template) {
|
|
1770
|
-
return TEMPLATES_META_LIST.find((e) => e.name === template);
|
|
1771
|
-
}
|
|
1772
|
-
async function ejsRender(templatePath, data, outputPath) {
|
|
1773
|
-
const template = (await import_fs_extra.default.readFile(templatePath, "utf8")).toString();
|
|
1774
|
-
const content = await import_ejs.default.render(
|
|
1775
|
-
template,
|
|
1776
|
-
data,
|
|
1777
|
-
{
|
|
1778
|
-
debug: false,
|
|
1779
|
-
async: true
|
|
1780
|
-
}
|
|
1781
|
-
);
|
|
1782
|
-
await import_fs_extra.default.writeFile(outputPath, content);
|
|
1783
|
-
}
|
|
1784
1913
|
|
|
1785
1914
|
// src/plopfile.ts
|
|
1786
|
-
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
1787
|
-
var import_path2 = __toESM(require("path"));
|
|
1788
1915
|
module.exports = function(plop) {
|
|
1789
1916
|
plop.setActionType("initProject", initProject);
|
|
1790
1917
|
plop.setGenerator("create", {
|
|
@@ -1905,7 +2032,7 @@ module.exports = function(plop) {
|
|
|
1905
2032
|
name: "license",
|
|
1906
2033
|
message: "请选择开源协议",
|
|
1907
2034
|
async choices() {
|
|
1908
|
-
return
|
|
2035
|
+
return import_fs_extra4.default.readdir(import_path3.default.join(__dirname, "../templates/licenses/"));
|
|
1909
2036
|
},
|
|
1910
2037
|
default: "MIT",
|
|
1911
2038
|
when(answers) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cmyr-template-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.1",
|
|
4
4
|
"description": "草梅友仁自制的项目模板创建器",
|
|
5
5
|
"author": "CaoMeiYouRen",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@types/ejs": "^3.1.0",
|
|
39
39
|
"@types/fs-extra": "^11.0.0",
|
|
40
40
|
"@types/inquirer": "^9.0.3",
|
|
41
|
+
"@types/libsodium-wrappers": "^0.7.14",
|
|
41
42
|
"@types/lodash": "^4.14.165",
|
|
42
43
|
"@types/node": "^22.0.0",
|
|
43
44
|
"@typescript-eslint/eslint-plugin": "7.18.0",
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
"ejs": "^3.1.6",
|
|
72
73
|
"fs-extra": "^11.0.0",
|
|
73
74
|
"json5": "^2.2.1",
|
|
75
|
+
"libsodium-wrappers": "^0.7.15",
|
|
74
76
|
"lodash": "^4.17.20",
|
|
75
77
|
"minimist": "^1.2.5",
|
|
76
78
|
"ora": "^5.4.1",
|