create-vuepress-theme-plume 1.0.0-rc.91
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/LICENSE +21 -0
- package/README.md +14 -0
- package/bin/index.js +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +506 -0
- package/package.json +43 -0
- package/templates/.vuepress/client.ts.handlebars +12 -0
- package/templates/.vuepress/config.ts.handlebars +90 -0
- package/templates/.vuepress/navbar.ts.handlebars +28 -0
- package/templates/.vuepress/notes.ts.handlebars +32 -0
- package/templates/.vuepress/plume.config.ts.handlebars +57 -0
- package/templates/.vuepress/public/plume.svg +8 -0
- package/templates/.vuepress/theme/components/Custom.vue +11 -0
- package/templates/.vuepress/theme/shim.d.ts +6 -0
- package/templates/.vuepress/theme/styles/custom.css +50 -0
- package/templates/common/README.md.handlebars +57 -0
- package/templates/common/README.zh-CN.md.handlebars +57 -0
- package/templates/deploy/github/.github/workflows/deploy.yml.handlebars +70 -0
- package/templates/deploy/netlify/netlify.toml.handlebars +9 -0
- package/templates/deploy/vercel/vercel.json.handlebars +6 -0
- package/templates/docs/en/README.md.handlebars +22 -0
- package/templates/docs/en/notes/demo/README.md +6 -0
- package/templates/docs/en/notes/demo/bar.md +5 -0
- package/templates/docs/en/notes/demo/foo.md +5 -0
- package/templates/docs/en/preview/custom-component.example.md +8 -0
- package/templates/docs/en/preview/markdown.md +312 -0
- package/templates/docs/zh/README.md.handlebars +22 -0
- package/templates/docs/zh/notes/demo/README.md +6 -0
- package/templates/docs/zh/notes/demo/bar.md +5 -0
- package/templates/docs/zh/notes/demo/foo.md +5 -0
- package/templates/docs/zh/preview/custom-component.example.md +8 -0
- package/templates/docs/zh/preview/markdown.md +312 -0
- package/templates/git/.gitattributes.handlebars +10 -0
- package/templates/git/.gitignore.handlebars +8 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2021 - PRESENT by pengzhanbo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# create-vuepress-theme-plume
|
|
2
|
+
|
|
3
|
+
The cli for create vuepress-theme-plume's project
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
# npm
|
|
9
|
+
npm init vuepress-theme-plume@latest
|
|
10
|
+
# pnpm
|
|
11
|
+
pnpm create vuepress-theme-plume@latest
|
|
12
|
+
# yarn
|
|
13
|
+
yarn create vuepress-theme-plume@latest
|
|
14
|
+
```
|
package/bin/index.js
ADDED
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import cac from "cac";
|
|
3
|
+
|
|
4
|
+
// src/run.ts
|
|
5
|
+
import { intro, outro, spinner } from "@clack/prompts";
|
|
6
|
+
import { execaCommand as execaCommand3 } from "execa";
|
|
7
|
+
import colors from "picocolors";
|
|
8
|
+
|
|
9
|
+
// src/prompt.ts
|
|
10
|
+
import process from "node:process";
|
|
11
|
+
import { createRequire } from "node:module";
|
|
12
|
+
import { cancel, confirm, group, select, text } from "@clack/prompts";
|
|
13
|
+
|
|
14
|
+
// src/locales/en.ts
|
|
15
|
+
var en = {
|
|
16
|
+
"question.root": "Where would you want to initialize VuePress?",
|
|
17
|
+
"question.site.name": "Site Name:",
|
|
18
|
+
"question.site.description": "Site Description:",
|
|
19
|
+
"question.bundler": "Select a bundler",
|
|
20
|
+
"question.multiLanguage": "Do you want to use multiple languages?",
|
|
21
|
+
"question.defaultLanguage": "Select the default language of the site",
|
|
22
|
+
"question.useTs": "Use TypeScript?",
|
|
23
|
+
"question.injectNpmScripts": "Inject npm scripts?",
|
|
24
|
+
"question.deploy": "Deploy type:",
|
|
25
|
+
"question.git": "Initialize a git repository?",
|
|
26
|
+
"question.installDeps": "Install dependencies?",
|
|
27
|
+
"spinner.start": "\u{1F680} Creating...",
|
|
28
|
+
"spinner.stop": "\u{1F389} Create success!",
|
|
29
|
+
"spinner.git": "\u{1F4C4} Initializing git repository...",
|
|
30
|
+
"spinner.install": "\u{1F4E6} Installing dependencies...",
|
|
31
|
+
"spinner.command": "\u{1F528} Execute the following command to start:",
|
|
32
|
+
"hint.cancel": "Operation cancelled.",
|
|
33
|
+
"hint.root": "The path cannot be an absolute path, and cannot contain the parent path.",
|
|
34
|
+
"hint.root.illegal": "Project names cannot contain special characters."
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/locales/zh.ts
|
|
38
|
+
var zh = {
|
|
39
|
+
"question.root": "\u60A8\u60F3\u5728\u54EA\u91CC\u521D\u59CB\u5316 VuePress\uFF1F",
|
|
40
|
+
"question.site.name": "\u7AD9\u70B9\u540D\u79F0\uFF1A",
|
|
41
|
+
"question.site.description": "\u7AD9\u70B9\u63CF\u8FF0\u4FE1\u606F\uFF1A",
|
|
42
|
+
"question.bundler": "\u8BF7\u9009\u62E9\u6253\u5305\u5DE5\u5177",
|
|
43
|
+
"question.multiLanguage": "\u662F\u5426\u4F7F\u7528\u591A\u8BED\u8A00\uFF1F",
|
|
44
|
+
"question.defaultLanguage": "\u8BF7\u9009\u62E9\u7AD9\u70B9\u9ED8\u8BA4\u8BED\u8A00",
|
|
45
|
+
"question.useTs": "\u662F\u5426\u4F7F\u7528 TypeScript\uFF1F",
|
|
46
|
+
"question.injectNpmScripts": "\u662F\u5426\u6CE8\u5165 npm \u811A\u672C\uFF1F",
|
|
47
|
+
"question.deploy": "\u90E8\u7F72\u65B9\u5F0F\uFF1A",
|
|
48
|
+
"question.git": "\u662F\u5426\u521D\u59CB\u5316 git \u4ED3\u5E93\uFF1F",
|
|
49
|
+
"question.installDeps": "\u662F\u5426\u5B89\u88C5\u4F9D\u8D56\uFF1F",
|
|
50
|
+
"spinner.start": "\u{1F680} \u6B63\u5728\u521B\u5EFA...",
|
|
51
|
+
"spinner.stop": "\u{1F389} \u521B\u5EFA\u6210\u529F!",
|
|
52
|
+
"spinner.git": "\u{1F4C4} \u521D\u59CB\u5316 git \u4ED3\u5E93...",
|
|
53
|
+
"spinner.install": "\u{1F4E6} \u5B89\u88C5\u4F9D\u8D56...",
|
|
54
|
+
"spinner.command": "\u{1F528} \u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5373\u53EF\u542F\u52A8\uFF1A",
|
|
55
|
+
"hint.cancel": "\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002",
|
|
56
|
+
"hint.root": "\u6587\u4EF6\u8DEF\u5F84\u4E0D\u80FD\u662F\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4E0D\u80FD\u5305\u542B\u7236\u8DEF\u5F84\u3002",
|
|
57
|
+
"hint.root.illegal": "\u6587\u4EF6\u5939\u4E0D\u80FD\u5305\u542B\u7279\u6B8A\u5B57\u7B26\u3002"
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/locales/index.ts
|
|
61
|
+
var locales = {
|
|
62
|
+
"zh-CN": zh,
|
|
63
|
+
"en-US": en
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/translate.ts
|
|
67
|
+
function createTranslate(lang) {
|
|
68
|
+
let current = lang || "en-US";
|
|
69
|
+
return {
|
|
70
|
+
setLang: (lang2) => {
|
|
71
|
+
current = lang2;
|
|
72
|
+
},
|
|
73
|
+
t: (key) => locales[current][key]
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
var { t, setLang } = createTranslate();
|
|
77
|
+
|
|
78
|
+
// src/constants.ts
|
|
79
|
+
var languageOptions = [
|
|
80
|
+
{ label: "English", value: "en-US" },
|
|
81
|
+
{ label: "\u7B80\u4F53\u4E2D\u6587", value: "zh-CN" }
|
|
82
|
+
];
|
|
83
|
+
var bundlerOptions = [
|
|
84
|
+
{ label: "Vite", value: "vite" },
|
|
85
|
+
{ label: "Webpack", value: "webpack" }
|
|
86
|
+
];
|
|
87
|
+
var deployOptions = [
|
|
88
|
+
{ label: "Custom", value: "custom" /* custom */ },
|
|
89
|
+
{ label: "GitHub Pages", value: "github" /* github */ },
|
|
90
|
+
{ label: "Vercel", value: "vercel" /* vercel */ },
|
|
91
|
+
{ label: "Netlify", value: "netlify" /* netlify */ }
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
// src/prompt.ts
|
|
95
|
+
var require2 = createRequire(process.cwd());
|
|
96
|
+
var REG_DIR_CHAR = /[<>:"\\|?*[\]]/;
|
|
97
|
+
async function prompt(mode, root) {
|
|
98
|
+
let hasTs = false;
|
|
99
|
+
if (mode === 0 /* init */) {
|
|
100
|
+
try {
|
|
101
|
+
hasTs = !!require2.resolve("typescript");
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const result = await group({
|
|
106
|
+
displayLang: async () => {
|
|
107
|
+
const lang = await select({
|
|
108
|
+
message: "Select a language to display / \u9009\u62E9\u663E\u793A\u8BED\u8A00",
|
|
109
|
+
options: languageOptions
|
|
110
|
+
});
|
|
111
|
+
if (typeof lang === "string")
|
|
112
|
+
setLang(lang);
|
|
113
|
+
return lang;
|
|
114
|
+
},
|
|
115
|
+
root: async () => {
|
|
116
|
+
if (root)
|
|
117
|
+
return root;
|
|
118
|
+
const DEFAULT_ROOT = mode === 0 /* init */ ? "./docs" : "./my-project";
|
|
119
|
+
return await text({
|
|
120
|
+
message: t("question.root"),
|
|
121
|
+
placeholder: DEFAULT_ROOT,
|
|
122
|
+
validate(value) {
|
|
123
|
+
if (value?.startsWith("/") || value?.startsWith(".."))
|
|
124
|
+
return t("hint.root");
|
|
125
|
+
if (value && REG_DIR_CHAR.test(value))
|
|
126
|
+
return t("hint.root.illegal");
|
|
127
|
+
return void 0;
|
|
128
|
+
},
|
|
129
|
+
defaultValue: DEFAULT_ROOT
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
siteName: () => text({
|
|
133
|
+
message: t("question.site.name"),
|
|
134
|
+
placeholder: "My Vuepress Site",
|
|
135
|
+
defaultValue: "My Vuepress Site"
|
|
136
|
+
}),
|
|
137
|
+
siteDescription: () => text({
|
|
138
|
+
message: t("question.site.description")
|
|
139
|
+
}),
|
|
140
|
+
multiLanguage: () => confirm({
|
|
141
|
+
message: t("question.multiLanguage"),
|
|
142
|
+
initialValue: false
|
|
143
|
+
}),
|
|
144
|
+
defaultLanguage: () => select({
|
|
145
|
+
message: t("question.defaultLanguage"),
|
|
146
|
+
options: languageOptions
|
|
147
|
+
}),
|
|
148
|
+
useTs: async () => {
|
|
149
|
+
if (mode === 0 /* init */)
|
|
150
|
+
return hasTs;
|
|
151
|
+
if (hasTs)
|
|
152
|
+
return true;
|
|
153
|
+
return await confirm({
|
|
154
|
+
message: t("question.useTs"),
|
|
155
|
+
initialValue: true
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
injectNpmScripts: async () => {
|
|
159
|
+
if (mode === 1 /* create */)
|
|
160
|
+
return true;
|
|
161
|
+
return await confirm({
|
|
162
|
+
message: t("question.injectNpmScripts"),
|
|
163
|
+
initialValue: true
|
|
164
|
+
});
|
|
165
|
+
},
|
|
166
|
+
bundler: () => select({
|
|
167
|
+
message: t("question.bundler"),
|
|
168
|
+
options: bundlerOptions
|
|
169
|
+
}),
|
|
170
|
+
deploy: async () => {
|
|
171
|
+
if (mode === 0 /* init */) {
|
|
172
|
+
return "custom" /* custom */;
|
|
173
|
+
}
|
|
174
|
+
return await select({
|
|
175
|
+
message: t("question.deploy"),
|
|
176
|
+
options: deployOptions,
|
|
177
|
+
initialValue: "custom" /* custom */
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
git: async () => {
|
|
181
|
+
if (mode === 0 /* init */)
|
|
182
|
+
return false;
|
|
183
|
+
return confirm({
|
|
184
|
+
message: t("question.git"),
|
|
185
|
+
initialValue: true
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
install: () => confirm({
|
|
189
|
+
message: t("question.installDeps"),
|
|
190
|
+
initialValue: true
|
|
191
|
+
})
|
|
192
|
+
}, {
|
|
193
|
+
onCancel: () => {
|
|
194
|
+
cancel(t("hint.cancel"));
|
|
195
|
+
process.exit(0);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// src/generate.ts
|
|
202
|
+
import path3 from "node:path";
|
|
203
|
+
import process3 from "node:process";
|
|
204
|
+
import fs2 from "node:fs";
|
|
205
|
+
import { execaCommand as execaCommand2 } from "execa";
|
|
206
|
+
|
|
207
|
+
// src/packageJson.ts
|
|
208
|
+
import { execaCommand } from "execa";
|
|
209
|
+
import { kebabCase } from "@pengzhanbo/utils";
|
|
210
|
+
|
|
211
|
+
// src/utils/index.ts
|
|
212
|
+
import { fileURLToPath } from "node:url";
|
|
213
|
+
import path2 from "node:path";
|
|
214
|
+
|
|
215
|
+
// src/utils/fs.ts
|
|
216
|
+
import path from "node:path";
|
|
217
|
+
import fs from "node:fs/promises";
|
|
218
|
+
async function readFiles(root) {
|
|
219
|
+
const filepaths = await fs.readdir(root, { recursive: true });
|
|
220
|
+
const files = [];
|
|
221
|
+
for (const file of filepaths) {
|
|
222
|
+
const filepath = path.join(root, file);
|
|
223
|
+
if ((await fs.stat(filepath)).isFile()) {
|
|
224
|
+
files.push({
|
|
225
|
+
filepath: file,
|
|
226
|
+
content: await fs.readFile(filepath, "utf-8")
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return files;
|
|
231
|
+
}
|
|
232
|
+
async function writeFiles(files, target, rewrite) {
|
|
233
|
+
for (const { filepath, content } of files) {
|
|
234
|
+
let root = path.join(target, filepath).replace(/\.handlebars$/, "");
|
|
235
|
+
if (rewrite)
|
|
236
|
+
root = rewrite(root);
|
|
237
|
+
await fs.mkdir(path.dirname(root), { recursive: true });
|
|
238
|
+
await fs.writeFile(root, content);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async function readJsonFile(filepath) {
|
|
242
|
+
try {
|
|
243
|
+
const content = await fs.readFile(filepath, "utf-8");
|
|
244
|
+
return JSON.parse(content);
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// src/utils/depsVersion.ts
|
|
251
|
+
var api = "https://api.pengzhanbo.cn/npm/dependencies/version";
|
|
252
|
+
async function getDependenciesVersion(dependencies, version = "latest") {
|
|
253
|
+
const result = await fetch(api, {
|
|
254
|
+
method: "POST",
|
|
255
|
+
headers: { "content-type": "application/json" },
|
|
256
|
+
body: JSON.stringify({ dependencies, version })
|
|
257
|
+
}).then((res) => res.json());
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/utils/getPackageManager.ts
|
|
262
|
+
import process2 from "node:process";
|
|
263
|
+
function getPackageManager() {
|
|
264
|
+
const name = process2.env?.npm_config_user_agent || "npm";
|
|
265
|
+
return name.split("/")[0];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/utils/index.ts
|
|
269
|
+
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
270
|
+
var resolve = (...args) => path2.resolve(__dirname, "../", ...args);
|
|
271
|
+
var getTemplate = (dir) => resolve("templates", dir);
|
|
272
|
+
|
|
273
|
+
// src/packageJson.ts
|
|
274
|
+
async function createPackageJson(mode, pkg, {
|
|
275
|
+
docsDir,
|
|
276
|
+
siteName,
|
|
277
|
+
siteDescription,
|
|
278
|
+
bundler,
|
|
279
|
+
injectNpmScripts
|
|
280
|
+
}) {
|
|
281
|
+
if (mode === 1 /* create */) {
|
|
282
|
+
pkg.name = kebabCase(siteName);
|
|
283
|
+
pkg.type = "module";
|
|
284
|
+
pkg.version = "1.0.0";
|
|
285
|
+
pkg.description = siteDescription;
|
|
286
|
+
const userInfo = await getUserInfo();
|
|
287
|
+
if (userInfo) {
|
|
288
|
+
pkg.author = userInfo.username + (userInfo.email ? ` <${userInfo.email}>` : "");
|
|
289
|
+
}
|
|
290
|
+
pkg.license = "MIT";
|
|
291
|
+
}
|
|
292
|
+
if (injectNpmScripts) {
|
|
293
|
+
pkg.scripts ??= {};
|
|
294
|
+
pkg.scripts = {
|
|
295
|
+
...pkg.scripts,
|
|
296
|
+
"docs:dev": `vuepress dev ${docsDir}`,
|
|
297
|
+
"docs:dev-clean": `vuepress dev ${docsDir} --clean-cache --clean-temp`,
|
|
298
|
+
"docs:build": `vuepress build ${docsDir} --clean-cache --clean-temp`,
|
|
299
|
+
"docs:preview": `http-server ${docsDir}/.vuepress/dist`
|
|
300
|
+
};
|
|
301
|
+
if (mode === 1 /* create */) {
|
|
302
|
+
pkg.scripts["vp-update"] = "vp-update";
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
pkg.devDependencies ??= {};
|
|
306
|
+
const context = await readJsonFile(resolve("package.json"));
|
|
307
|
+
const meta = context["theme-plume"];
|
|
308
|
+
pkg.devDependencies.vuepress = `${meta.vuepress}`;
|
|
309
|
+
pkg.devDependencies["vuepress-theme-plume"] = `${context.version}`;
|
|
310
|
+
pkg.devDependencies[`@vuepress/bundler-${bundler}`] = `${meta.vuepress}`;
|
|
311
|
+
pkg.devDependencies["http-server"] = "^14.1.1";
|
|
312
|
+
const deps = [];
|
|
313
|
+
if (!pkg.dependencies?.vue && !pkg.devDependencies.vue)
|
|
314
|
+
deps.push("vue");
|
|
315
|
+
if (bundler === "webpack" && !pkg.dependencies?.["sass-loader"] && !pkg.devDependencies["sass-loader"])
|
|
316
|
+
deps.push("sass-loader");
|
|
317
|
+
const dv = await getDependenciesVersion(deps);
|
|
318
|
+
for (const [d, v] of Object.entries(dv))
|
|
319
|
+
pkg.devDependencies[d] = `^${v}`;
|
|
320
|
+
return {
|
|
321
|
+
filepath: "package.json",
|
|
322
|
+
content: JSON.stringify(pkg, null, 2)
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
async function getUserInfo() {
|
|
326
|
+
try {
|
|
327
|
+
const { stdout: username } = await execaCommand("git config --global user.name");
|
|
328
|
+
const { stdout: email } = await execaCommand("git config --global user.email");
|
|
329
|
+
return { username, email };
|
|
330
|
+
} catch {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// src/render.ts
|
|
336
|
+
import handlebars from "handlebars";
|
|
337
|
+
import { kebabCase as kebabCase2 } from "@pengzhanbo/utils";
|
|
338
|
+
handlebars.registerHelper("removeLeadingSlash", (path4) => path4.replace(/^\//, ""));
|
|
339
|
+
handlebars.registerHelper("equal", (a, b) => a === b);
|
|
340
|
+
function createRender(result) {
|
|
341
|
+
const data = {
|
|
342
|
+
...result,
|
|
343
|
+
name: kebabCase2(result.siteName),
|
|
344
|
+
isEN: result.defaultLanguage === "en-US",
|
|
345
|
+
locales: result.defaultLanguage === "en-US" ? [
|
|
346
|
+
{ path: "/", lang: "en-US", isEn: true, prefix: "en" },
|
|
347
|
+
{ path: "/zh/", lang: "zh-CN", isEn: false, prefix: "zh" }
|
|
348
|
+
] : [
|
|
349
|
+
{ path: "/", lang: "zh-CN", isEn: false, prefix: "zh" },
|
|
350
|
+
{ path: "/en/", lang: "en-US", isEn: true, prefix: "en" }
|
|
351
|
+
]
|
|
352
|
+
};
|
|
353
|
+
return function render(source) {
|
|
354
|
+
try {
|
|
355
|
+
const template = handlebars.compile(source);
|
|
356
|
+
return template(data);
|
|
357
|
+
} catch (e) {
|
|
358
|
+
console.error(e);
|
|
359
|
+
return source;
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// src/generate.ts
|
|
365
|
+
async function generate(mode, data) {
|
|
366
|
+
const cwd = process3.cwd();
|
|
367
|
+
let userPkg = {};
|
|
368
|
+
if (mode === 0 /* init */) {
|
|
369
|
+
const pkgPath = path3.join(cwd, "package.json");
|
|
370
|
+
if (fs2.existsSync(pkgPath)) {
|
|
371
|
+
userPkg = await readJsonFile(pkgPath) || {};
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const fileList = [
|
|
375
|
+
// add package.json
|
|
376
|
+
await createPackageJson(mode, userPkg, data),
|
|
377
|
+
// add docs files
|
|
378
|
+
...await createDocsFiles(data),
|
|
379
|
+
// add vuepress and theme-plume configs
|
|
380
|
+
...updateFileListTarget(await readFiles(getTemplate(".vuepress")), `${data.docsDir}/.vuepress`)
|
|
381
|
+
];
|
|
382
|
+
if (mode === 1 /* create */) {
|
|
383
|
+
fileList.push(...await readFiles(getTemplate("common")));
|
|
384
|
+
if (data.packageManager === "pnpm") {
|
|
385
|
+
fileList.push({
|
|
386
|
+
filepath: ".npmrc",
|
|
387
|
+
content: "shamefully-hoist=true\nshell-emulator=true"
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
if (data.packageManager === "yarn") {
|
|
391
|
+
const { stdout: yarnVersion } = await execaCommand2("yarn --version");
|
|
392
|
+
if (yarnVersion.startsWith("2")) {
|
|
393
|
+
fileList.push({
|
|
394
|
+
filepath: ".yarnrc.yml",
|
|
395
|
+
content: "nodeLinker: 'node-modules'\n"
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (data.git)
|
|
401
|
+
fileList.push(...await readFiles(getTemplate("git")));
|
|
402
|
+
if (mode === 0 /* init */) {
|
|
403
|
+
const gitignorePath = path3.join(cwd, ".gitignore");
|
|
404
|
+
const docs = data.docsDir;
|
|
405
|
+
if (fs2.existsSync(gitignorePath)) {
|
|
406
|
+
const content = await fs2.promises.readFile(gitignorePath, "utf-8");
|
|
407
|
+
fileList.push({
|
|
408
|
+
filepath: ".gitignore",
|
|
409
|
+
content: `${content}
|
|
410
|
+
${docs}/.vuepress/.cache
|
|
411
|
+
${docs}/.vuepress/.temp
|
|
412
|
+
${docs}/.vuepress/dist
|
|
413
|
+
`
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (data.deploy !== "custom" /* custom */) {
|
|
418
|
+
fileList.push(...await readFiles(getTemplate(`deploy/${data.deploy}`)));
|
|
419
|
+
}
|
|
420
|
+
const render = createRender(data);
|
|
421
|
+
const renderedFiles = fileList.map((file) => {
|
|
422
|
+
if (file.filepath.endsWith(".handlebars"))
|
|
423
|
+
file.content = render(file.content);
|
|
424
|
+
return file;
|
|
425
|
+
});
|
|
426
|
+
const ext = data.useTs ? "" : userPkg.type !== "module" ? ".mjs" : ".js";
|
|
427
|
+
const REG_EXT = /\.ts$/;
|
|
428
|
+
const output = mode === 1 /* create */ ? path3.join(cwd, data.root) : cwd;
|
|
429
|
+
await writeFiles(renderedFiles, output, (filepath) => {
|
|
430
|
+
if (filepath.endsWith(".d.ts"))
|
|
431
|
+
return filepath;
|
|
432
|
+
if (ext)
|
|
433
|
+
return filepath.replace(REG_EXT, ext);
|
|
434
|
+
return filepath;
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
async function createDocsFiles(data) {
|
|
438
|
+
const fileList = [];
|
|
439
|
+
if (data.multiLanguage) {
|
|
440
|
+
const enDocs = await readFiles(getTemplate("docs/en"));
|
|
441
|
+
const zhDocs = await readFiles(getTemplate("docs/zh"));
|
|
442
|
+
if (data.defaultLanguage === "en-US") {
|
|
443
|
+
fileList.push(...enDocs);
|
|
444
|
+
fileList.push(...updateFileListTarget(zhDocs, "zh"));
|
|
445
|
+
} else {
|
|
446
|
+
fileList.push(...zhDocs);
|
|
447
|
+
fileList.push(...updateFileListTarget(enDocs, "en"));
|
|
448
|
+
}
|
|
449
|
+
} else {
|
|
450
|
+
if (data.defaultLanguage === "en-US")
|
|
451
|
+
fileList.push(...await readFiles(getTemplate("docs/en")));
|
|
452
|
+
else
|
|
453
|
+
fileList.push(...await readFiles(getTemplate("docs/zh")));
|
|
454
|
+
}
|
|
455
|
+
return updateFileListTarget(fileList, data.docsDir);
|
|
456
|
+
}
|
|
457
|
+
function updateFileListTarget(fileList, target) {
|
|
458
|
+
return fileList.map(({ filepath, content }) => ({
|
|
459
|
+
filepath: path3.join(target, filepath),
|
|
460
|
+
content
|
|
461
|
+
}));
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// src/run.ts
|
|
465
|
+
async function run(mode, root) {
|
|
466
|
+
intro(colors.cyan("Welcome to VuePress and vuepress-theme-plume !"));
|
|
467
|
+
const result = await prompt(mode, root);
|
|
468
|
+
const data = resolveData(result, mode);
|
|
469
|
+
const progress = spinner();
|
|
470
|
+
progress.start(t("spinner.start"));
|
|
471
|
+
await generate(mode, data);
|
|
472
|
+
if (data.git) {
|
|
473
|
+
progress.message(t("spinner.git"));
|
|
474
|
+
await execaCommand3("git init");
|
|
475
|
+
}
|
|
476
|
+
const pm = data.packageManager;
|
|
477
|
+
if (data.install) {
|
|
478
|
+
progress.message(t("spinner.install"));
|
|
479
|
+
await execaCommand3(pm === "yarn" ? "yarn" : `${pm} install`);
|
|
480
|
+
}
|
|
481
|
+
const cdCommand = mode === 1 /* create */ ? colors.green(`cd ${data.root}`) : "";
|
|
482
|
+
const runCommand = colors.green(pm === "yarn" ? "yarn dev" : `${pm} run dev`);
|
|
483
|
+
const installCommand = colors.green(pm === "yarn" ? "yarn" : `${pm} install`);
|
|
484
|
+
progress.stop(t("spinner.stop"));
|
|
485
|
+
if (mode === 1 /* create */) {
|
|
486
|
+
outro(`${t("spinner.command")}
|
|
487
|
+
${cdCommand}
|
|
488
|
+
${data.install ? "" : `${installCommand} && `}${runCommand}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function resolveData(result, mode) {
|
|
492
|
+
return {
|
|
493
|
+
...result,
|
|
494
|
+
packageManager: getPackageManager(),
|
|
495
|
+
docsDir: mode === 1 /* create */ ? "docs" : result.root.replace(/^\.\//, "").replace(/\/$/, ""),
|
|
496
|
+
siteDescription: result.siteDescription || ""
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// src/index.ts
|
|
501
|
+
var cli = cac("create-vuepress-theme-plume");
|
|
502
|
+
cli.command("[root]", "create a new vuepress-theme-plume project / \u521B\u5EFA\u65B0\u7684 vuepress-theme-plume \u9879\u76EE").action((root) => run(1 /* create */, root));
|
|
503
|
+
cli.command("init [root]", "Initial vuepress-theme-plume in the existing project / \u5728\u73B0\u6709\u9879\u76EE\u4E2D\u521D\u59CB\u5316 vuepress-theme-plume").action((root) => run(0 /* init */, root));
|
|
504
|
+
cli.help();
|
|
505
|
+
cli.version("1.0.0-rc.90");
|
|
506
|
+
cli.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-vuepress-theme-plume",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.0.0-rc.91",
|
|
5
|
+
"description": "The cli for create vuepress-theme-plume's project",
|
|
6
|
+
"author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo/)",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://theme-plume.vuejs.press/",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/pengzhanbo/vuepress-theme-plume.git",
|
|
12
|
+
"directory": "cli"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/pengzhanbo/vuepress-theme-plume/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"VuePress",
|
|
19
|
+
"theme",
|
|
20
|
+
"plume",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"bin": "./bin/index.js",
|
|
24
|
+
"files": [
|
|
25
|
+
"bin",
|
|
26
|
+
"lib",
|
|
27
|
+
"templates"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@clack/prompts": "^0.7.0",
|
|
31
|
+
"@pengzhanbo/utils": "^1.1.2",
|
|
32
|
+
"cac": "^6.7.14",
|
|
33
|
+
"execa": "^9.3.1",
|
|
34
|
+
"handlebars": "^4.7.8",
|
|
35
|
+
"picocolors": "^1.0.1"
|
|
36
|
+
},
|
|
37
|
+
"theme-plume": {
|
|
38
|
+
"vuepress": "2.0.0-rc.15"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineClientConfig } from 'vuepress/client'
|
|
2
|
+
import RepoCard from 'vuepress-theme-plume/features/RepoCard.vue'
|
|
3
|
+
import CustomComponent from './theme/components/Custom.vue'
|
|
4
|
+
|
|
5
|
+
import './theme/styles/custom.css'
|
|
6
|
+
|
|
7
|
+
export default defineClientConfig({
|
|
8
|
+
enhance({ app }) {
|
|
9
|
+
app.component('RepoCard', RepoCard)
|
|
10
|
+
app.component('CustomComponent', CustomComponent)
|
|
11
|
+
},
|
|
12
|
+
})
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { defineUserConfig } from 'vuepress'
|
|
2
|
+
import { {{ bundler }}Bundler } from '@vuepress/bundler-{{ bundler }}'
|
|
3
|
+
import { plumeTheme } from 'vuepress-theme-plume'
|
|
4
|
+
|
|
5
|
+
export default defineUserConfig({
|
|
6
|
+
base: '/',
|
|
7
|
+
lang: '{{ defaultLanguage }}',
|
|
8
|
+
{{#if multiLanguage}}
|
|
9
|
+
locales: {
|
|
10
|
+
{{#each locales}}
|
|
11
|
+
'{{ path }}': {
|
|
12
|
+
title: '{{ ../siteName }}',
|
|
13
|
+
lang: '{{ lang }}',
|
|
14
|
+
description: '{{ ../siteDescription }}',
|
|
15
|
+
},
|
|
16
|
+
{{/each}}
|
|
17
|
+
},
|
|
18
|
+
{{else}}
|
|
19
|
+
title: '{{ siteName }}',
|
|
20
|
+
description: '{{ siteDescription }}',
|
|
21
|
+
{{/if}}
|
|
22
|
+
|
|
23
|
+
bundler: {{ bundler }}Bundler(),
|
|
24
|
+
|
|
25
|
+
theme: plumeTheme({
|
|
26
|
+
// 添加您的部署域名
|
|
27
|
+
// hostname: 'https://your_site_url',
|
|
28
|
+
|
|
29
|
+
plugins: {
|
|
30
|
+
/**
|
|
31
|
+
* Shiki 代码高亮
|
|
32
|
+
* @see https://theme-plume.vuejs.press/config/plugins/code-highlight/
|
|
33
|
+
*/
|
|
34
|
+
// shiki: {
|
|
35
|
+
// languages: ['shell', 'bash', 'typescript', 'javascript'],
|
|
36
|
+
// twoslash: true,
|
|
37
|
+
// },
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* markdown enhance
|
|
41
|
+
* @see https://theme-plume.vuejs.press/config/plugins/markdown-enhance/
|
|
42
|
+
*/
|
|
43
|
+
markdownEnhance: {
|
|
44
|
+
demo: true,
|
|
45
|
+
// include: true,
|
|
46
|
+
// chart: true,
|
|
47
|
+
// echarts: true,
|
|
48
|
+
// mermaid: true,
|
|
49
|
+
// flowchart: true,
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* markdown power
|
|
54
|
+
* @see https://theme-plume.vuejs.press/config/plugin/markdown-power/
|
|
55
|
+
*/
|
|
56
|
+
// markdownPower: {
|
|
57
|
+
// pdf: true,
|
|
58
|
+
// caniuse: true,
|
|
59
|
+
// plot: true,
|
|
60
|
+
// bilibili: true,
|
|
61
|
+
// youtube: true,
|
|
62
|
+
// icons: true,
|
|
63
|
+
// codepen: true,
|
|
64
|
+
// replit: true,
|
|
65
|
+
// codeSandbox: true,
|
|
66
|
+
// jsfiddle: true,
|
|
67
|
+
// repl: {
|
|
68
|
+
// go: true,
|
|
69
|
+
// rust: true,
|
|
70
|
+
// kotlin: true,
|
|
71
|
+
// },
|
|
72
|
+
// },
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* comments
|
|
76
|
+
* @see https://theme-plume.vuejs.press/guide/features/comments/
|
|
77
|
+
*/
|
|
78
|
+
// comment: {
|
|
79
|
+
// provider: '', // "Artalk" | "Giscus" | "Twikoo" | "Waline"
|
|
80
|
+
// comment: true,
|
|
81
|
+
// repo: '',
|
|
82
|
+
// repoId: '',
|
|
83
|
+
// categoryId: '',
|
|
84
|
+
// mapping: 'pathname',
|
|
85
|
+
// reactionsEnabled: true,
|
|
86
|
+
// inputPosition: 'top',
|
|
87
|
+
// },
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
})
|