create-vuepress-theme-plume 1.0.0-rc.146 → 1.0.0-rc.147
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/lib/index.d.ts +1 -2
- package/lib/index.js +490 -514
- package/package.json +4 -4
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { }
|
|
1
|
+
export { };
|
package/lib/index.js
CHANGED
|
@@ -1,566 +1,542 @@
|
|
|
1
|
-
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
2
|
import cac from "cac";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
];
|
|
9
|
-
var bundlerOptions = [
|
|
10
|
-
{ label: "Vite", value: "vite" },
|
|
11
|
-
{ label: "Webpack", value: "webpack" }
|
|
12
|
-
];
|
|
13
|
-
var deployOptions = [
|
|
14
|
-
{ label: "Custom", value: "custom" /* custom */ },
|
|
15
|
-
{ label: "GitHub Pages", value: "github" /* github */ },
|
|
16
|
-
{ label: "Vercel", value: "vercel" /* vercel */ },
|
|
17
|
-
{ label: "Netlify", value: "netlify" /* netlify */ }
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
// src/run.ts
|
|
21
|
-
import path4 from "node:path";
|
|
22
|
-
import process4 from "node:process";
|
|
23
|
-
import { intro, outro, spinner } from "@clack/prompts";
|
|
24
|
-
import { sleep } from "@pengzhanbo/utils";
|
|
25
|
-
import { execaCommand as execaCommand3 } from "execa";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { cancel, confirm, group, intro, outro, select, spinner, text } from "@clack/prompts";
|
|
6
|
+
import { kebabCase, sleep } from "@pengzhanbo/utils";
|
|
7
|
+
import spawn from "nano-spawn";
|
|
26
8
|
import colors from "picocolors";
|
|
27
|
-
|
|
28
|
-
// src/generate.ts
|
|
29
|
-
import fs2 from "node:fs";
|
|
30
|
-
import path3 from "node:path";
|
|
31
|
-
import process2 from "node:process";
|
|
32
|
-
import { execaCommand as execaCommand2 } from "execa";
|
|
33
|
-
|
|
34
|
-
// src/packageJson.ts
|
|
35
|
-
import { kebabCase } from "@pengzhanbo/utils";
|
|
36
|
-
import { execaCommand } from "execa";
|
|
37
|
-
|
|
38
|
-
// src/utils/index.ts
|
|
39
|
-
import path2 from "node:path";
|
|
9
|
+
import fs from "node:fs";
|
|
40
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
+
import fs$1 from "node:fs/promises";
|
|
12
|
+
import handlebars from "handlebars";
|
|
13
|
+
import { osLocale } from "os-locale";
|
|
41
14
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
15
|
+
//#region src/constants.ts
|
|
16
|
+
const languageOptions = [{
|
|
17
|
+
label: "English",
|
|
18
|
+
value: "en-US"
|
|
19
|
+
}, {
|
|
20
|
+
label: "简体中文",
|
|
21
|
+
value: "zh-CN"
|
|
22
|
+
}];
|
|
23
|
+
const bundlerOptions = [{
|
|
24
|
+
label: "Vite",
|
|
25
|
+
value: "vite"
|
|
26
|
+
}, {
|
|
27
|
+
label: "Webpack",
|
|
28
|
+
value: "webpack"
|
|
29
|
+
}];
|
|
30
|
+
let Mode = /* @__PURE__ */ function(Mode$1) {
|
|
31
|
+
Mode$1[Mode$1["init"] = 0] = "init";
|
|
32
|
+
Mode$1[Mode$1["create"] = 1] = "create";
|
|
33
|
+
return Mode$1;
|
|
34
|
+
}({});
|
|
35
|
+
let DeployType = /* @__PURE__ */ function(DeployType$1) {
|
|
36
|
+
DeployType$1["github"] = "github";
|
|
37
|
+
DeployType$1["vercel"] = "vercel";
|
|
38
|
+
DeployType$1["netlify"] = "netlify";
|
|
39
|
+
DeployType$1["custom"] = "custom";
|
|
40
|
+
return DeployType$1;
|
|
41
|
+
}({});
|
|
42
|
+
const deployOptions = [
|
|
43
|
+
{
|
|
44
|
+
label: "Custom",
|
|
45
|
+
value: DeployType.custom
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "GitHub Pages",
|
|
49
|
+
value: DeployType.github
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
label: "Vercel",
|
|
53
|
+
value: DeployType.vercel
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
label: "Netlify",
|
|
57
|
+
value: DeployType.netlify
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/utils/fs.ts
|
|
45
63
|
async function readFiles(root) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
return files;
|
|
64
|
+
const filepaths = await fs$1.readdir(root, { recursive: true });
|
|
65
|
+
const files = [];
|
|
66
|
+
for (const file of filepaths) {
|
|
67
|
+
const filepath = path.join(root, file);
|
|
68
|
+
if ((await fs$1.stat(filepath)).isFile()) files.push({
|
|
69
|
+
filepath: file,
|
|
70
|
+
content: await fs$1.readFile(filepath, "utf-8")
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return files;
|
|
58
74
|
}
|
|
59
75
|
async function writeFiles(files, target, rewrite) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
76
|
+
for (const { filepath, content } of files) {
|
|
77
|
+
let root = path.join(target, filepath).replace(/\.handlebars$/, "");
|
|
78
|
+
if (rewrite) root = rewrite(root);
|
|
79
|
+
await fs$1.mkdir(path.dirname(root), { recursive: true });
|
|
80
|
+
await fs$1.writeFile(root, content);
|
|
81
|
+
}
|
|
67
82
|
}
|
|
68
83
|
async function readJsonFile(filepath) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
try {
|
|
85
|
+
const content = await fs$1.readFile(filepath, "utf-8");
|
|
86
|
+
return JSON.parse(content);
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
75
90
|
}
|
|
76
91
|
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/utils/getPackageManager.ts
|
|
79
94
|
function getPackageManager() {
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
const name = process.env?.npm_config_user_agent || "npm";
|
|
96
|
+
return name.split("/")[0];
|
|
82
97
|
}
|
|
83
98
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/utils/index.ts
|
|
101
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
102
|
+
const resolve = (...args) => path.resolve(__dirname, "../", ...args);
|
|
103
|
+
const getTemplate = (dir) => resolve("templates", dir);
|
|
88
104
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const hasDep = (dep) => pkg.devDependencies?.[dep] || pkg.dependencies?.[dep];
|
|
139
|
-
const context = await readJsonFile(resolve("package.json"));
|
|
140
|
-
const meta = context["plume-deps"];
|
|
141
|
-
pkg.devDependencies[`@vuepress/bundler-${bundler}`] = `${meta.vuepress}`;
|
|
142
|
-
pkg.devDependencies.vuepress = `${meta.vuepress}`;
|
|
143
|
-
pkg.devDependencies["vuepress-theme-plume"] = `${context.version}`;
|
|
144
|
-
const deps = ["http-server"];
|
|
145
|
-
if (!hasDep("vue"))
|
|
146
|
-
deps.push("vue");
|
|
147
|
-
if (bundler === "webpack" && !hasDep("sass-loader"))
|
|
148
|
-
deps.push("sass-loader");
|
|
149
|
-
if (!hasDep("sass-embedded"))
|
|
150
|
-
deps.push("sass-embedded");
|
|
151
|
-
if (useTs)
|
|
152
|
-
deps.push("typescript");
|
|
153
|
-
for (const dep of deps)
|
|
154
|
-
pkg.devDependencies[dep] = meta[dep];
|
|
155
|
-
return {
|
|
156
|
-
filepath: "package.json",
|
|
157
|
-
content: JSON.stringify(pkg, null, 2)
|
|
158
|
-
};
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/packageJson.ts
|
|
107
|
+
async function createPackageJson(mode, pkg, { packageManager, docsDir, siteName, siteDescription, bundler, injectNpmScripts, useTs }) {
|
|
108
|
+
if (mode === Mode.create) {
|
|
109
|
+
pkg.name = kebabCase(siteName);
|
|
110
|
+
pkg.type = "module";
|
|
111
|
+
pkg.version = "1.0.0";
|
|
112
|
+
pkg.description = siteDescription;
|
|
113
|
+
if (packageManager !== "npm") {
|
|
114
|
+
let version = await getPackageManagerVersion(packageManager);
|
|
115
|
+
if (version) {
|
|
116
|
+
if (packageManager === "yarn" && version.startsWith("1")) version = "4.6.0";
|
|
117
|
+
pkg.packageManager = `${packageManager}@${version}`;
|
|
118
|
+
if (packageManager === "pnpm" && version.startsWith("10")) pkg.pnpm = { onlyBuiltDependencies: ["@parcel/watcher", "esbuild"] };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const userInfo = await getUserInfo();
|
|
122
|
+
if (userInfo) pkg.author = userInfo.username + (userInfo.email ? ` <${userInfo.email}>` : "");
|
|
123
|
+
pkg.license = "MIT";
|
|
124
|
+
pkg.engines = { node: "^20.6.0 || >=22.0.0" };
|
|
125
|
+
}
|
|
126
|
+
if (injectNpmScripts) {
|
|
127
|
+
pkg.scripts ??= {};
|
|
128
|
+
pkg.scripts = {
|
|
129
|
+
...pkg.scripts,
|
|
130
|
+
"docs:dev": `vuepress dev ${docsDir}`,
|
|
131
|
+
"docs:dev-clean": `vuepress dev ${docsDir} --clean-cache --clean-temp`,
|
|
132
|
+
"docs:build": `vuepress build ${docsDir} --clean-cache --clean-temp`,
|
|
133
|
+
"docs:preview": `http-server ${docsDir}/.vuepress/dist`
|
|
134
|
+
};
|
|
135
|
+
if (mode === Mode.create) pkg.scripts["vp-update"] = `${packageManager === "npm" ? "npx" : `${packageManager} dlx`} vp-update`;
|
|
136
|
+
}
|
|
137
|
+
pkg.devDependencies ??= {};
|
|
138
|
+
const hasDep = (dep) => pkg.devDependencies?.[dep] || pkg.dependencies?.[dep];
|
|
139
|
+
const context = await readJsonFile(resolve("package.json"));
|
|
140
|
+
const meta = context["plume-deps"];
|
|
141
|
+
pkg.devDependencies[`@vuepress/bundler-${bundler}`] = `${meta.vuepress}`;
|
|
142
|
+
pkg.devDependencies.vuepress = `${meta.vuepress}`;
|
|
143
|
+
pkg.devDependencies["vuepress-theme-plume"] = `${context.version}`;
|
|
144
|
+
const deps = ["http-server"];
|
|
145
|
+
if (!hasDep("vue")) deps.push("vue");
|
|
146
|
+
if (bundler === "webpack" && !hasDep("sass-loader")) deps.push("sass-loader");
|
|
147
|
+
if (!hasDep("sass-embedded")) deps.push("sass-embedded");
|
|
148
|
+
if (useTs) deps.push("typescript");
|
|
149
|
+
for (const dep of deps) pkg.devDependencies[dep] = meta[dep];
|
|
150
|
+
return {
|
|
151
|
+
filepath: "package.json",
|
|
152
|
+
content: JSON.stringify(pkg, null, 2)
|
|
153
|
+
};
|
|
159
154
|
}
|
|
160
155
|
async function getUserInfo() {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
156
|
+
try {
|
|
157
|
+
const { output: username } = await spawn("git", [
|
|
158
|
+
"config",
|
|
159
|
+
"--global",
|
|
160
|
+
"user.name"
|
|
161
|
+
]);
|
|
162
|
+
const { output: email } = await spawn("git", [
|
|
163
|
+
"config",
|
|
164
|
+
"--global",
|
|
165
|
+
"user.email"
|
|
166
|
+
]);
|
|
167
|
+
console.log("userInfo", username, email);
|
|
168
|
+
return {
|
|
169
|
+
username,
|
|
170
|
+
email
|
|
171
|
+
};
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
168
175
|
}
|
|
169
176
|
async function getPackageManagerVersion(pkg) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
177
|
+
try {
|
|
178
|
+
const { output } = await spawn(pkg, ["--version"]);
|
|
179
|
+
return output;
|
|
180
|
+
} catch {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
176
183
|
}
|
|
177
184
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
handlebars.registerHelper("removeLeadingSlash", (path5) => path5.replace(/^\//, ""));
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region src/render.ts
|
|
187
|
+
handlebars.registerHelper("removeLeadingSlash", (path$1) => path$1.replace(/^\//, ""));
|
|
182
188
|
handlebars.registerHelper("equal", (a, b) => a === b);
|
|
183
189
|
function createRender(result) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
190
|
+
const data = {
|
|
191
|
+
...result,
|
|
192
|
+
name: kebabCase(result.siteName),
|
|
193
|
+
isEN: result.defaultLanguage === "en-US",
|
|
194
|
+
locales: result.defaultLanguage === "en-US" ? [{
|
|
195
|
+
path: "/",
|
|
196
|
+
lang: "en-US",
|
|
197
|
+
isEn: true,
|
|
198
|
+
prefix: "en"
|
|
199
|
+
}, {
|
|
200
|
+
path: "/zh/",
|
|
201
|
+
lang: "zh-CN",
|
|
202
|
+
isEn: false,
|
|
203
|
+
prefix: "zh"
|
|
204
|
+
}] : [{
|
|
205
|
+
path: "/",
|
|
206
|
+
lang: "zh-CN",
|
|
207
|
+
isEn: false,
|
|
208
|
+
prefix: "zh"
|
|
209
|
+
}, {
|
|
210
|
+
path: "/en/",
|
|
211
|
+
lang: "en-US",
|
|
212
|
+
isEn: true,
|
|
213
|
+
prefix: "en"
|
|
214
|
+
}]
|
|
215
|
+
};
|
|
216
|
+
return function render(source) {
|
|
217
|
+
try {
|
|
218
|
+
const template = handlebars.compile(source);
|
|
219
|
+
return template(data);
|
|
220
|
+
} catch (e) {
|
|
221
|
+
console.error(e);
|
|
222
|
+
return source;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
205
225
|
}
|
|
206
226
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
filepath: ".yarnrc.yml",
|
|
268
|
-
content: "nodeLinker: 'node-modules'\n"
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
if (data.deploy !== "custom" /* custom */) {
|
|
272
|
-
fileList.push(...await readFiles(getTemplate(`deploy/${data.deploy}`)));
|
|
273
|
-
}
|
|
274
|
-
const render = createRender(data);
|
|
275
|
-
const renderedFiles = fileList.map((file) => {
|
|
276
|
-
if (file.filepath.endsWith(".handlebars"))
|
|
277
|
-
file.content = render(file.content);
|
|
278
|
-
return file;
|
|
279
|
-
});
|
|
280
|
-
const ext = data.useTs ? "" : userPkg.type !== "module" ? ".mjs" : ".js";
|
|
281
|
-
const REG_EXT = /\.ts$/;
|
|
282
|
-
const output = mode === 1 /* create */ ? path3.join(cwd, data.root) : cwd;
|
|
283
|
-
await writeFiles(renderedFiles, output, (filepath) => {
|
|
284
|
-
if (filepath.endsWith(".d.ts"))
|
|
285
|
-
return filepath;
|
|
286
|
-
if (ext)
|
|
287
|
-
return filepath.replace(REG_EXT, ext);
|
|
288
|
-
return filepath;
|
|
289
|
-
});
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/generate.ts
|
|
229
|
+
async function generate(mode, data, cwd = process.cwd()) {
|
|
230
|
+
let userPkg = {};
|
|
231
|
+
if (mode === Mode.init) {
|
|
232
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
233
|
+
if (fs.existsSync(pkgPath)) userPkg = await readJsonFile(pkgPath) || {};
|
|
234
|
+
}
|
|
235
|
+
const fileList = [
|
|
236
|
+
await createPackageJson(mode, userPkg, data),
|
|
237
|
+
...await createDocsFiles(data),
|
|
238
|
+
...updateFileListTarget(await readFiles(getTemplate(".vuepress")), `${data.docsDir}/.vuepress`)
|
|
239
|
+
];
|
|
240
|
+
if (mode === Mode.create) {
|
|
241
|
+
fileList.push(...await readFiles(getTemplate("common")));
|
|
242
|
+
if (data.packageManager === "pnpm") fileList.push({
|
|
243
|
+
filepath: ".npmrc",
|
|
244
|
+
content: "shamefully-hoist=true\nshell-emulator=true"
|
|
245
|
+
});
|
|
246
|
+
if (data.packageManager === "yarn") {
|
|
247
|
+
const { output: output$1 } = await spawn("yarn", ["--version"]);
|
|
248
|
+
if (output$1.startsWith("2")) fileList.push({
|
|
249
|
+
filepath: ".yarnrc.yml",
|
|
250
|
+
content: "nodeLinker: 'node-modules'\n"
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (data.git) {
|
|
255
|
+
const gitFiles = await readFiles(getTemplate("git"));
|
|
256
|
+
if (mode === Mode.init) {
|
|
257
|
+
const gitignorePath = path.join(cwd, ".gitignore");
|
|
258
|
+
const docs = data.docsDir;
|
|
259
|
+
if (fs.existsSync(gitignorePath)) {
|
|
260
|
+
const content = await fs.promises.readFile(gitignorePath, "utf-8");
|
|
261
|
+
fileList.push({
|
|
262
|
+
filepath: ".gitignore",
|
|
263
|
+
content: `${content}\n${docs}/.vuepress/.cache\n${docs}/.vuepress/.temp\n${docs}/.vuepress/dist\n`
|
|
264
|
+
});
|
|
265
|
+
fileList.push(...gitFiles.filter(({ filepath }) => filepath !== ".gitignore"));
|
|
266
|
+
} else fileList.push(...gitFiles);
|
|
267
|
+
} else fileList.push(...gitFiles);
|
|
268
|
+
}
|
|
269
|
+
if (data.packageManager === "yarn") fileList.push({
|
|
270
|
+
filepath: ".yarnrc.yml",
|
|
271
|
+
content: "nodeLinker: 'node-modules'\n"
|
|
272
|
+
});
|
|
273
|
+
if (data.deploy !== DeployType.custom) fileList.push(...await readFiles(getTemplate(`deploy/${data.deploy}`)));
|
|
274
|
+
const render = createRender(data);
|
|
275
|
+
const renderedFiles = fileList.map((file) => {
|
|
276
|
+
if (file.filepath.endsWith(".handlebars")) file.content = render(file.content);
|
|
277
|
+
return file;
|
|
278
|
+
});
|
|
279
|
+
const ext = data.useTs ? "" : userPkg.type !== "module" ? ".mjs" : ".js";
|
|
280
|
+
const REG_EXT = /\.ts$/;
|
|
281
|
+
const output = mode === Mode.create ? path.join(cwd, data.root) : cwd;
|
|
282
|
+
await writeFiles(renderedFiles, output, (filepath) => {
|
|
283
|
+
if (filepath.endsWith(".d.ts")) return filepath;
|
|
284
|
+
if (ext) return filepath.replace(REG_EXT, ext);
|
|
285
|
+
return filepath;
|
|
286
|
+
});
|
|
290
287
|
}
|
|
291
288
|
async function createDocsFiles(data) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
else
|
|
307
|
-
fileList.push(...await readFiles(getTemplate("docs/zh")));
|
|
308
|
-
}
|
|
309
|
-
return updateFileListTarget(fileList, data.docsDir);
|
|
289
|
+
const fileList = [];
|
|
290
|
+
if (data.multiLanguage) {
|
|
291
|
+
const enDocs = await readFiles(getTemplate("docs/en"));
|
|
292
|
+
const zhDocs = await readFiles(getTemplate("docs/zh"));
|
|
293
|
+
if (data.defaultLanguage === "en-US") {
|
|
294
|
+
fileList.push(...enDocs);
|
|
295
|
+
fileList.push(...updateFileListTarget(zhDocs, "zh"));
|
|
296
|
+
} else {
|
|
297
|
+
fileList.push(...zhDocs);
|
|
298
|
+
fileList.push(...updateFileListTarget(enDocs, "en"));
|
|
299
|
+
}
|
|
300
|
+
} else if (data.defaultLanguage === "en-US") fileList.push(...await readFiles(getTemplate("docs/en")));
|
|
301
|
+
else fileList.push(...await readFiles(getTemplate("docs/zh")));
|
|
302
|
+
return updateFileListTarget(fileList, data.docsDir);
|
|
310
303
|
}
|
|
311
304
|
function updateFileListTarget(fileList, target) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
305
|
+
return fileList.map(({ filepath, content }) => ({
|
|
306
|
+
filepath: path.join(target, filepath),
|
|
307
|
+
content
|
|
308
|
+
}));
|
|
316
309
|
}
|
|
317
310
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
"spinner.install": "\u{1F4E6} Installing dependencies...",
|
|
341
|
-
"spinner.command": "\u{1F528} Execute the following command to start:",
|
|
342
|
-
"hint.cancel": "Operation cancelled.",
|
|
343
|
-
"hint.root": "The path cannot be an absolute path, and cannot contain the parent path.",
|
|
344
|
-
"hint.root.illegal": "Project names cannot contain special characters."
|
|
311
|
+
//#endregion
|
|
312
|
+
//#region src/locales/en.ts
|
|
313
|
+
const en = {
|
|
314
|
+
"question.root": "Where would you want to initialize VuePress?",
|
|
315
|
+
"question.site.name": "Site Name:",
|
|
316
|
+
"question.site.description": "Site Description:",
|
|
317
|
+
"question.bundler": "Select a bundler",
|
|
318
|
+
"question.multiLanguage": "Do you want to use multiple languages?",
|
|
319
|
+
"question.defaultLanguage": "Select the default language of the site",
|
|
320
|
+
"question.useTs": "Use TypeScript?",
|
|
321
|
+
"question.injectNpmScripts": "Inject npm scripts?",
|
|
322
|
+
"question.deploy": "Deploy type:",
|
|
323
|
+
"question.git": "Initialize a git repository?",
|
|
324
|
+
"question.installDeps": "Install dependencies?",
|
|
325
|
+
"spinner.start": "🚀 Creating...",
|
|
326
|
+
"spinner.stop": "🎉 Create success!",
|
|
327
|
+
"spinner.git": "📄 Initializing git repository...",
|
|
328
|
+
"spinner.install": "📦 Installing dependencies...",
|
|
329
|
+
"spinner.command": "🔨 Execute the following command to start:",
|
|
330
|
+
"hint.cancel": "Operation cancelled.",
|
|
331
|
+
"hint.root": "The path cannot be an absolute path, and cannot contain the parent path.",
|
|
332
|
+
"hint.root.illegal": "Project names cannot contain special characters."
|
|
345
333
|
};
|
|
346
334
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
335
|
+
//#endregion
|
|
336
|
+
//#region src/locales/zh.ts
|
|
337
|
+
const zh = {
|
|
338
|
+
"question.root": "您想在哪里初始化 VuePress?",
|
|
339
|
+
"question.site.name": "站点名称:",
|
|
340
|
+
"question.site.description": "站点描述信息:",
|
|
341
|
+
"question.bundler": "请选择打包工具",
|
|
342
|
+
"question.multiLanguage": "是否使用多语言?",
|
|
343
|
+
"question.defaultLanguage": "请选择站点默认语言",
|
|
344
|
+
"question.useTs": "是否使用 TypeScript?",
|
|
345
|
+
"question.injectNpmScripts": "是否注入 npm 脚本?",
|
|
346
|
+
"question.deploy": "部署方式:",
|
|
347
|
+
"question.git": "是否初始化 git 仓库?",
|
|
348
|
+
"question.installDeps": "是否安装依赖?",
|
|
349
|
+
"spinner.start": "🚀 正在创建...",
|
|
350
|
+
"spinner.stop": "🎉 创建成功!",
|
|
351
|
+
"spinner.git": "📄 初始化 git 仓库...",
|
|
352
|
+
"spinner.install": "📦 安装依赖...",
|
|
353
|
+
"spinner.command": "🔨 执行以下命令即可启动:",
|
|
354
|
+
"hint.cancel": "操作已取消。",
|
|
355
|
+
"hint.root": "文件路径不能是绝对路径,不能包含父路径。",
|
|
356
|
+
"hint.root.illegal": "文件夹不能包含特殊字符。"
|
|
368
357
|
};
|
|
369
358
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region src/locales/index.ts
|
|
361
|
+
const locales = {
|
|
362
|
+
"zh-CN": zh,
|
|
363
|
+
"en-US": en
|
|
374
364
|
};
|
|
375
365
|
|
|
376
|
-
|
|
366
|
+
//#endregion
|
|
367
|
+
//#region src/translate.ts
|
|
377
368
|
function createTranslate(lang) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
369
|
+
let current = lang || "en-US";
|
|
370
|
+
return {
|
|
371
|
+
setLang: (lang$1) => {
|
|
372
|
+
current = lang$1;
|
|
373
|
+
},
|
|
374
|
+
t: (key) => locales[current][key]
|
|
375
|
+
};
|
|
385
376
|
}
|
|
386
|
-
|
|
377
|
+
const translate = createTranslate();
|
|
378
|
+
const t = translate.t;
|
|
379
|
+
const setLang = translate.setLang;
|
|
387
380
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/prompt.ts
|
|
383
|
+
const require = createRequire(process.cwd());
|
|
384
|
+
const REG_DIR_CHAR = /[<>:"\\|?*[\]]/;
|
|
391
385
|
async function prompt(mode, root) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
return false;
|
|
486
|
-
return confirm({
|
|
487
|
-
message: t("question.git"),
|
|
488
|
-
initialValue: true
|
|
489
|
-
});
|
|
490
|
-
},
|
|
491
|
-
install: () => confirm({
|
|
492
|
-
message: t("question.installDeps"),
|
|
493
|
-
initialValue: true
|
|
494
|
-
})
|
|
495
|
-
}, {
|
|
496
|
-
onCancel: () => {
|
|
497
|
-
cancel(t("hint.cancel"));
|
|
498
|
-
process3.exit(0);
|
|
499
|
-
}
|
|
500
|
-
});
|
|
501
|
-
return result;
|
|
386
|
+
let hasTs = false;
|
|
387
|
+
if (mode === Mode.init) try {
|
|
388
|
+
hasTs = !!require.resolve("typescript");
|
|
389
|
+
} catch {}
|
|
390
|
+
const result = await group({
|
|
391
|
+
displayLang: async () => {
|
|
392
|
+
const locale = await osLocale();
|
|
393
|
+
if (locale === "zh-CN" || locale === "zh-Hans") {
|
|
394
|
+
setLang("zh-CN");
|
|
395
|
+
return "zh-CN";
|
|
396
|
+
}
|
|
397
|
+
if (locale === "en-US") {
|
|
398
|
+
setLang("en-US");
|
|
399
|
+
return "en-US";
|
|
400
|
+
}
|
|
401
|
+
const lang = await select({
|
|
402
|
+
message: "Select a language to display / 选择显示语言",
|
|
403
|
+
options: languageOptions
|
|
404
|
+
});
|
|
405
|
+
if (typeof lang === "string") setLang(lang);
|
|
406
|
+
return lang;
|
|
407
|
+
},
|
|
408
|
+
root: async () => {
|
|
409
|
+
if (root) return root;
|
|
410
|
+
const DEFAULT_ROOT = mode === Mode.init ? "./docs" : "./my-project";
|
|
411
|
+
return await text({
|
|
412
|
+
message: t("question.root"),
|
|
413
|
+
placeholder: DEFAULT_ROOT,
|
|
414
|
+
validate(value) {
|
|
415
|
+
if (value?.startsWith("/") || value?.startsWith("..")) return t("hint.root");
|
|
416
|
+
if (value && REG_DIR_CHAR.test(value)) return t("hint.root.illegal");
|
|
417
|
+
return void 0;
|
|
418
|
+
},
|
|
419
|
+
defaultValue: DEFAULT_ROOT
|
|
420
|
+
});
|
|
421
|
+
},
|
|
422
|
+
siteName: () => text({
|
|
423
|
+
message: t("question.site.name"),
|
|
424
|
+
placeholder: "My Vuepress Site",
|
|
425
|
+
defaultValue: "My Vuepress Site"
|
|
426
|
+
}),
|
|
427
|
+
siteDescription: () => text({ message: t("question.site.description") }),
|
|
428
|
+
multiLanguage: () => confirm({
|
|
429
|
+
message: t("question.multiLanguage"),
|
|
430
|
+
initialValue: false
|
|
431
|
+
}),
|
|
432
|
+
defaultLanguage: () => select({
|
|
433
|
+
message: t("question.defaultLanguage"),
|
|
434
|
+
options: languageOptions
|
|
435
|
+
}),
|
|
436
|
+
useTs: async () => {
|
|
437
|
+
if (mode === Mode.init) return hasTs;
|
|
438
|
+
if (hasTs) return true;
|
|
439
|
+
return await confirm({
|
|
440
|
+
message: t("question.useTs"),
|
|
441
|
+
initialValue: true
|
|
442
|
+
});
|
|
443
|
+
},
|
|
444
|
+
injectNpmScripts: async () => {
|
|
445
|
+
if (mode === Mode.create) return true;
|
|
446
|
+
return await confirm({
|
|
447
|
+
message: t("question.injectNpmScripts"),
|
|
448
|
+
initialValue: true
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
bundler: () => select({
|
|
452
|
+
message: t("question.bundler"),
|
|
453
|
+
options: bundlerOptions
|
|
454
|
+
}),
|
|
455
|
+
deploy: async () => {
|
|
456
|
+
if (mode === Mode.init) return DeployType.custom;
|
|
457
|
+
return await select({
|
|
458
|
+
message: t("question.deploy"),
|
|
459
|
+
options: deployOptions,
|
|
460
|
+
initialValue: DeployType.custom
|
|
461
|
+
});
|
|
462
|
+
},
|
|
463
|
+
git: async () => {
|
|
464
|
+
if (mode === Mode.init) return false;
|
|
465
|
+
return confirm({
|
|
466
|
+
message: t("question.git"),
|
|
467
|
+
initialValue: true
|
|
468
|
+
});
|
|
469
|
+
},
|
|
470
|
+
install: () => confirm({
|
|
471
|
+
message: t("question.installDeps"),
|
|
472
|
+
initialValue: true
|
|
473
|
+
})
|
|
474
|
+
}, { onCancel: () => {
|
|
475
|
+
cancel(t("hint.cancel"));
|
|
476
|
+
process.exit(0);
|
|
477
|
+
} });
|
|
478
|
+
return result;
|
|
502
479
|
}
|
|
503
480
|
|
|
504
|
-
|
|
481
|
+
//#endregion
|
|
482
|
+
//#region src/run.ts
|
|
505
483
|
async function run(mode, root) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
const installCommand = colors.green(`${pm} install`);
|
|
544
|
-
progress.stop(t("spinner.stop"));
|
|
545
|
-
if (mode === 1 /* create */) {
|
|
546
|
-
outro(`${t("spinner.command")}
|
|
484
|
+
intro(colors.cyan("Welcome to VuePress and vuepress-theme-plume !"));
|
|
485
|
+
const result = await prompt(mode, root);
|
|
486
|
+
const data = resolveData(result, mode);
|
|
487
|
+
const progress = spinner();
|
|
488
|
+
progress.start(t("spinner.start"));
|
|
489
|
+
try {
|
|
490
|
+
await generate(mode, data);
|
|
491
|
+
} catch (e) {
|
|
492
|
+
console.error(`${colors.red("generate files error: ")}\n`, e);
|
|
493
|
+
process.exit(1);
|
|
494
|
+
}
|
|
495
|
+
await sleep(200);
|
|
496
|
+
const cwd = path.join(process.cwd(), data.root);
|
|
497
|
+
if (data.git) {
|
|
498
|
+
progress.message(t("spinner.git"));
|
|
499
|
+
try {
|
|
500
|
+
await spawn("git", ["init"], { cwd });
|
|
501
|
+
} catch (e) {
|
|
502
|
+
console.error(`${colors.red("git init error: ")}\n`, e);
|
|
503
|
+
process.exit(1);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
const pm = data.packageManager;
|
|
507
|
+
if (data.install) {
|
|
508
|
+
progress.message(t("spinner.install"));
|
|
509
|
+
try {
|
|
510
|
+
await spawn(pm, ["install"], { cwd });
|
|
511
|
+
} catch (e) {
|
|
512
|
+
console.error(`${colors.red("install dependencies error: ")}\n`, e);
|
|
513
|
+
process.exit(1);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const cdCommand = mode === Mode.create ? colors.green(`cd ${data.root}`) : "";
|
|
517
|
+
const runCommand = colors.green(`${pm} run docs:dev`);
|
|
518
|
+
const installCommand = colors.green(`${pm} install`);
|
|
519
|
+
progress.stop(t("spinner.stop"));
|
|
520
|
+
if (mode === Mode.create) outro(`${t("spinner.command")}
|
|
547
521
|
${cdCommand}
|
|
548
522
|
${data.install ? "" : `${installCommand} && `}${runCommand}`);
|
|
549
|
-
}
|
|
550
523
|
}
|
|
551
524
|
function resolveData(result, mode) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
525
|
+
return {
|
|
526
|
+
...result,
|
|
527
|
+
packageManager: getPackageManager(),
|
|
528
|
+
docsDir: mode === Mode.create ? "docs" : result.root.replace(/^\.\//, "").replace(/\/$/, ""),
|
|
529
|
+
siteDescription: result.siteDescription || ""
|
|
530
|
+
};
|
|
558
531
|
}
|
|
559
532
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
cli
|
|
563
|
-
cli.command("
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region src/index.ts
|
|
535
|
+
const cli = cac("create-vuepress-theme-plume");
|
|
536
|
+
cli.command("[root]", "create a new vuepress-theme-plume project / 创建新的 vuepress-theme-plume 项目").action((root) => run(Mode.create, root));
|
|
537
|
+
cli.command("init [root]", "Initial vuepress-theme-plume in the existing project / 在现有项目中初始化 vuepress-theme-plume").action((root) => run(Mode.init, root));
|
|
564
538
|
cli.help();
|
|
565
|
-
cli.version(
|
|
539
|
+
cli.version(__CLI_VERSION__);
|
|
566
540
|
cli.parse();
|
|
541
|
+
|
|
542
|
+
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-vuepress-theme-plume",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.147",
|
|
5
5
|
"description": "The cli for create vuepress-theme-plume's project",
|
|
6
6
|
"author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo/)",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
"@clack/prompts": "^0.10.1",
|
|
31
31
|
"@pengzhanbo/utils": "^2.1.0",
|
|
32
32
|
"cac": "^6.7.14",
|
|
33
|
-
"execa": "^9.5.2",
|
|
34
33
|
"handlebars": "^4.7.8",
|
|
34
|
+
"nano-spawn": "^1.0.1",
|
|
35
35
|
"os-locale": "^6.0.2",
|
|
36
36
|
"picocolors": "^1.1.1"
|
|
37
37
|
},
|
|
38
38
|
"plume-deps": {
|
|
39
39
|
"vuepress": "2.0.0-rc.22",
|
|
40
40
|
"vue": "^3.5.13",
|
|
41
|
-
"sass-embedded": "^1.
|
|
41
|
+
"sass-embedded": "^1.88.0",
|
|
42
42
|
"sass-loader": "^16.0.5",
|
|
43
43
|
"http-server": "^14.1.1",
|
|
44
44
|
"typescript": "^5.8.3"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
|
-
"build": "
|
|
47
|
+
"build": "tsdown"
|
|
48
48
|
}
|
|
49
49
|
}
|