mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
feat: add create-vuepress-theme-plume package (#153)
* feat: add `create-vuepress-theme-plume` package * feat(cli): add support deploy
This commit is contained in:
parent
a4dc03f736
commit
74079390f6
21
cli/LICENSE
Normal file
21
cli/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (C) 2021 - PRESENT by pengzhanbo
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
14
cli/README.md
Normal file
14
cli/README.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# create-vuepress-theme-plume
|
||||||
|
|
||||||
|
The cli for create vuepress-theme-plume's project
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# npm
|
||||||
|
npm init vuepress-theme-plume@latest
|
||||||
|
# pnpm
|
||||||
|
pnpm create vuepress-theme-plume@latest
|
||||||
|
# yarn
|
||||||
|
yarn create vuepress-theme-plume@latest
|
||||||
|
```
|
||||||
2
cli/bin/index.js
Executable file
2
cli/bin/index.js
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
import '../lib/index.js'
|
||||||
43
cli/package.json
Normal file
43
cli/package.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "create-vuepress-theme-plume",
|
||||||
|
"type": "module",
|
||||||
|
"version": "1.0.0-rc.90",
|
||||||
|
"description": "The cli for create vuepress-theme-plume's project",
|
||||||
|
"author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo/)",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://theme-plume.vuejs.press/",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/pengzhanbo/vuepress-theme-plume.git",
|
||||||
|
"directory": "cli"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/pengzhanbo/vuepress-theme-plume/issues"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"VuePress",
|
||||||
|
"theme",
|
||||||
|
"plume",
|
||||||
|
"cli"
|
||||||
|
],
|
||||||
|
"bin": "./bin/index.js",
|
||||||
|
"files": [
|
||||||
|
"bin",
|
||||||
|
"lib",
|
||||||
|
"templates"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsup"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@clack/prompts": "^0.7.0",
|
||||||
|
"@pengzhanbo/utils": "^1.1.2",
|
||||||
|
"cac": "^6.7.14",
|
||||||
|
"execa": "^9.3.1",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"picocolors": "^1.0.1"
|
||||||
|
},
|
||||||
|
"theme-plume": {
|
||||||
|
"vuepress": "2.0.0-rc.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
cli/src/constants.ts
Normal file
30
cli/src/constants.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import type { Bundler, Langs, Options } from './types.js'
|
||||||
|
|
||||||
|
export const languageOptions: Options<Langs> = [
|
||||||
|
{ label: 'English', value: 'en-US' },
|
||||||
|
{ label: '简体中文', value: 'zh-CN' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export const bundlerOptions: Options<Bundler> = [
|
||||||
|
{ label: 'Vite', value: 'vite' },
|
||||||
|
{ label: 'Webpack', value: 'webpack' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export enum Mode {
|
||||||
|
init,
|
||||||
|
create,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DeployType {
|
||||||
|
github = 'github',
|
||||||
|
vercel = 'vercel',
|
||||||
|
netlify = 'netlify',
|
||||||
|
custom = 'custom',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deployOptions: Options<DeployType> = [
|
||||||
|
{ label: 'Custom', value: DeployType.custom },
|
||||||
|
{ label: 'GitHub Pages', value: DeployType.github },
|
||||||
|
{ label: 'Vercel', value: DeployType.vercel },
|
||||||
|
{ label: 'Netlify', value: DeployType.netlify },
|
||||||
|
]
|
||||||
123
cli/src/generate.ts
Normal file
123
cli/src/generate.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import process from 'node:process'
|
||||||
|
import fs from 'node:fs'
|
||||||
|
import { execaCommand } from 'execa'
|
||||||
|
import { createPackageJson } from './packageJson.js'
|
||||||
|
import { createRender } from './render.js'
|
||||||
|
import { getTemplate, readFiles, readJsonFile, writeFiles } from './utils/index.js'
|
||||||
|
import type { File, ResolvedData } from './types.js'
|
||||||
|
import { DeployType, Mode } from './constants.js'
|
||||||
|
|
||||||
|
export async function generate(mode: Mode, data: ResolvedData): Promise<void> {
|
||||||
|
const cwd = process.cwd()
|
||||||
|
|
||||||
|
let userPkg: Record<string, any> = {}
|
||||||
|
if (mode === Mode.init) {
|
||||||
|
const pkgPath = path.join(cwd, 'package.json')
|
||||||
|
if (fs.existsSync(pkgPath)) {
|
||||||
|
userPkg = (await readJsonFile(pkgPath)) || {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileList: File[] = [
|
||||||
|
// add package.json
|
||||||
|
await createPackageJson(mode, userPkg, data),
|
||||||
|
// add docs files
|
||||||
|
...await createDocsFiles(data),
|
||||||
|
// add vuepress and theme-plume configs
|
||||||
|
...updateFileListTarget(await readFiles(getTemplate('.vuepress')), `${data.docsDir}/.vuepress`),
|
||||||
|
]
|
||||||
|
|
||||||
|
// add repo root files
|
||||||
|
if (mode === Mode.create) {
|
||||||
|
fileList.push(...await readFiles(getTemplate('common')))
|
||||||
|
if (data.packageManager === 'pnpm') {
|
||||||
|
fileList.push({
|
||||||
|
filepath: '.npmrc',
|
||||||
|
content: 'shamefully-hoist=true\nshell-emulator=true',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (data.packageManager === 'yarn') {
|
||||||
|
const { stdout: yarnVersion } = await execaCommand('yarn --version')
|
||||||
|
if (yarnVersion.startsWith('2')) {
|
||||||
|
fileList.push({
|
||||||
|
filepath: '.yarnrc.yml',
|
||||||
|
content: 'nodeLinker: \'node-modules\'\n',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewrite git files begin ==================================
|
||||||
|
if (data.git)
|
||||||
|
fileList.push(...await readFiles(getTemplate('git')))
|
||||||
|
|
||||||
|
if (mode === Mode.init) {
|
||||||
|
const gitignorePath = path.join(cwd, '.gitignore')
|
||||||
|
const docs = data.docsDir
|
||||||
|
if (fs.existsSync(gitignorePath)) {
|
||||||
|
const content = await fs.promises.readFile(gitignorePath, 'utf-8')
|
||||||
|
fileList.push({
|
||||||
|
filepath: '.gitignore',
|
||||||
|
content: `${content}\n${docs}/.vuepress/.cache\n${docs}/.vuepress/.temp\n${docs}/.vuepress/dist\n`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// rewrite git files end ====================================
|
||||||
|
|
||||||
|
if (data.deploy !== DeployType.custom) {
|
||||||
|
fileList.push(...await readFiles(getTemplate(`deploy/${data.deploy}`)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const render = createRender(data)
|
||||||
|
|
||||||
|
const renderedFiles = fileList.map((file) => {
|
||||||
|
if (file.filepath.endsWith('.handlebars'))
|
||||||
|
file.content = render(file.content)
|
||||||
|
|
||||||
|
return file
|
||||||
|
})
|
||||||
|
|
||||||
|
const ext = data.useTs ? '' : userPkg.type !== 'module' ? '.mjs' : '.js'
|
||||||
|
const REG_EXT = /\.ts$/
|
||||||
|
const output = mode === Mode.create ? path.join(cwd, data.root) : cwd
|
||||||
|
await writeFiles(renderedFiles, output, (filepath) => {
|
||||||
|
if (filepath.endsWith('.d.ts'))
|
||||||
|
return filepath
|
||||||
|
if (ext)
|
||||||
|
return filepath.replace(REG_EXT, ext)
|
||||||
|
return filepath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createDocsFiles(data: ResolvedData): Promise<File[]> {
|
||||||
|
const fileList: File[] = []
|
||||||
|
if (data.multiLanguage) {
|
||||||
|
const enDocs = await readFiles(getTemplate('docs/en'))
|
||||||
|
const zhDocs = await readFiles(getTemplate('docs/zh'))
|
||||||
|
|
||||||
|
if (data.defaultLanguage === 'en-US') {
|
||||||
|
fileList.push(...enDocs)
|
||||||
|
fileList.push(...updateFileListTarget(zhDocs, 'zh'))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fileList.push(...zhDocs)
|
||||||
|
fileList.push(...updateFileListTarget(enDocs, 'en'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (data.defaultLanguage === 'en-US')
|
||||||
|
fileList.push(...await readFiles(getTemplate('docs/en')))
|
||||||
|
else
|
||||||
|
fileList.push(...await readFiles(getTemplate('docs/zh')))
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateFileListTarget(fileList, data.docsDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFileListTarget(fileList: File[], target: string): File[] {
|
||||||
|
return fileList.map(({ filepath, content }) => ({
|
||||||
|
filepath: path.join(target, filepath),
|
||||||
|
content,
|
||||||
|
}))
|
||||||
|
}
|
||||||
21
cli/src/index.ts
Normal file
21
cli/src/index.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import cac from 'cac'
|
||||||
|
import { run } from './run.js'
|
||||||
|
import { Mode } from './constants.js'
|
||||||
|
|
||||||
|
declare const __CLI_VERSION__: string
|
||||||
|
|
||||||
|
const cli = cac('create-vuepress-theme-plume')
|
||||||
|
|
||||||
|
cli
|
||||||
|
.command('[root]', 'create a new vuepress-theme-plume project / 创建新的 vuepress-theme-plume 项目')
|
||||||
|
.action((root: string) => run(Mode.create, root))
|
||||||
|
|
||||||
|
cli
|
||||||
|
.command('init [root]', 'Initial vuepress-theme-plume in the existing project / 在现有项目中初始化 vuepress-theme-plume')
|
||||||
|
.action((root: string) => run(Mode.init, root))
|
||||||
|
|
||||||
|
cli.help()
|
||||||
|
|
||||||
|
cli.version(__CLI_VERSION__)
|
||||||
|
|
||||||
|
cli.parse()
|
||||||
25
cli/src/locales/en.ts
Normal file
25
cli/src/locales/en.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import type { Locale } from '../types.js'
|
||||||
|
|
||||||
|
export const en: Locale = {
|
||||||
|
'question.root': 'Where would you want to initialize VuePress?',
|
||||||
|
'question.site.name': 'Site Name:',
|
||||||
|
'question.site.description': 'Site Description:',
|
||||||
|
'question.bundler': 'Select a bundler',
|
||||||
|
'question.multiLanguage': 'Do you want to use multiple languages?',
|
||||||
|
'question.defaultLanguage': 'Select the default language of the site',
|
||||||
|
'question.useTs': 'Use TypeScript?',
|
||||||
|
'question.injectNpmScripts': 'Inject npm scripts?',
|
||||||
|
'question.deploy': 'Deploy type:',
|
||||||
|
'question.git': 'Initialize a git repository?',
|
||||||
|
'question.installDeps': 'Install dependencies?',
|
||||||
|
|
||||||
|
'spinner.start': '🚀 Creating...',
|
||||||
|
'spinner.stop': '🎉 Create success!',
|
||||||
|
'spinner.git': '📄 Initializing git repository...',
|
||||||
|
'spinner.install': '📦 Installing dependencies...',
|
||||||
|
'spinner.command': '🔨 Execute the following command to start:',
|
||||||
|
|
||||||
|
'hint.cancel': 'Operation cancelled.',
|
||||||
|
'hint.root': 'The path cannot be an absolute path, and cannot contain the parent path.',
|
||||||
|
'hint.root.illegal': 'Project names cannot contain special characters.',
|
||||||
|
}
|
||||||
8
cli/src/locales/index.ts
Normal file
8
cli/src/locales/index.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import type { Langs, Locale } from '../types.js'
|
||||||
|
import { en } from './en.js'
|
||||||
|
import { zh } from './zh.js'
|
||||||
|
|
||||||
|
export const locales: Record<Langs, Locale> = {
|
||||||
|
'zh-CN': zh,
|
||||||
|
'en-US': en,
|
||||||
|
}
|
||||||
25
cli/src/locales/zh.ts
Normal file
25
cli/src/locales/zh.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import type { Locale } from '../types.js'
|
||||||
|
|
||||||
|
export const zh: Locale = {
|
||||||
|
'question.root': '您想在哪里初始化 VuePress?',
|
||||||
|
'question.site.name': '站点名称:',
|
||||||
|
'question.site.description': '站点描述信息:',
|
||||||
|
'question.bundler': '请选择打包工具',
|
||||||
|
'question.multiLanguage': '是否使用多语言?',
|
||||||
|
'question.defaultLanguage': '请选择站点默认语言',
|
||||||
|
'question.useTs': '是否使用 TypeScript?',
|
||||||
|
'question.injectNpmScripts': '是否注入 npm 脚本?',
|
||||||
|
'question.deploy': '部署方式:',
|
||||||
|
'question.git': '是否初始化 git 仓库?',
|
||||||
|
'question.installDeps': '是否安装依赖?',
|
||||||
|
|
||||||
|
'spinner.start': '🚀 正在创建...',
|
||||||
|
'spinner.stop': '🎉 创建成功!',
|
||||||
|
'spinner.git': '📄 初始化 git 仓库...',
|
||||||
|
'spinner.install': '📦 安装依赖...',
|
||||||
|
'spinner.command': '🔨 执行以下命令即可启动:',
|
||||||
|
|
||||||
|
'hint.cancel': '操作已取消。',
|
||||||
|
'hint.root': '文件路径不能是绝对路径,不能包含父路径。',
|
||||||
|
'hint.root.illegal': '文件夹不能包含特殊字符。',
|
||||||
|
}
|
||||||
79
cli/src/packageJson.ts
Normal file
79
cli/src/packageJson.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { execaCommand } from 'execa'
|
||||||
|
import { kebabCase } from '@pengzhanbo/utils'
|
||||||
|
import { getDependenciesVersion, readJsonFile, resolve } from './utils/index.js'
|
||||||
|
import type { File, ResolvedData } from './types.js'
|
||||||
|
import { Mode } from './constants.js'
|
||||||
|
|
||||||
|
export async function createPackageJson(
|
||||||
|
mode: Mode,
|
||||||
|
pkg: Record<string, any>,
|
||||||
|
{
|
||||||
|
docsDir,
|
||||||
|
siteName,
|
||||||
|
siteDescription,
|
||||||
|
bundler,
|
||||||
|
injectNpmScripts,
|
||||||
|
}: ResolvedData,
|
||||||
|
): Promise<File> {
|
||||||
|
if (mode === Mode.create) {
|
||||||
|
pkg.name = kebabCase(siteName)
|
||||||
|
pkg.type = 'module'
|
||||||
|
pkg.version = '1.0.0'
|
||||||
|
pkg.description = siteDescription
|
||||||
|
const userInfo = await getUserInfo()
|
||||||
|
if (userInfo) {
|
||||||
|
pkg.author = userInfo.username + (userInfo.email ? ` <${userInfo.email}>` : '')
|
||||||
|
}
|
||||||
|
pkg.license = 'MIT'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (injectNpmScripts) {
|
||||||
|
pkg.scripts ??= {}
|
||||||
|
pkg.scripts = {
|
||||||
|
...pkg.scripts,
|
||||||
|
'docs:dev': `vuepress dev ${docsDir}`,
|
||||||
|
'docs:dev-clean': `vuepress dev ${docsDir} --clean-cache --clean-temp`,
|
||||||
|
'docs:build': `vuepress build ${docsDir} --clean-cache --clean-temp`,
|
||||||
|
'docs:preview': `http-server ${docsDir}/.vuepress/dist`,
|
||||||
|
}
|
||||||
|
if (mode === Mode.create) {
|
||||||
|
pkg.scripts['vp-update'] = 'vp-update'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg.devDependencies ??= {}
|
||||||
|
|
||||||
|
const context = (await readJsonFile(resolve('package.json')))!
|
||||||
|
const meta = context['theme-plume']
|
||||||
|
pkg.devDependencies.vuepress = `${meta.vuepress}`
|
||||||
|
pkg.devDependencies['vuepress-theme-plume'] = `${context.version}`
|
||||||
|
pkg.devDependencies[`@vuepress/bundler-${bundler}`] = `${meta.vuepress}`
|
||||||
|
pkg.devDependencies['http-server'] = '^14.1.1'
|
||||||
|
|
||||||
|
const deps: string[] = []
|
||||||
|
if (!pkg.dependencies?.vue && !pkg.devDependencies.vue)
|
||||||
|
deps.push('vue')
|
||||||
|
if (bundler === 'webpack' && !pkg.dependencies?.['sass-loader'] && !pkg.devDependencies['sass-loader'])
|
||||||
|
deps.push('sass-loader')
|
||||||
|
|
||||||
|
const dv = await getDependenciesVersion(deps)
|
||||||
|
|
||||||
|
for (const [d, v] of Object.entries(dv))
|
||||||
|
pkg.devDependencies[d] = `^${v}`
|
||||||
|
|
||||||
|
return {
|
||||||
|
filepath: 'package.json',
|
||||||
|
content: JSON.stringify(pkg, null, 2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getUserInfo() {
|
||||||
|
try {
|
||||||
|
const { stdout: username } = await execaCommand('git config --global user.name')
|
||||||
|
const { stdout: email } = await execaCommand('git config --global user.email')
|
||||||
|
return { username, email }
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
165
cli/src/prompt.ts
Normal file
165
cli/src/prompt.ts
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import process from 'node:process'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { createRequire } from 'node:module'
|
||||||
|
import { cancel, confirm, group, select, text } from '@clack/prompts'
|
||||||
|
import { setLang, t } from './translate.js'
|
||||||
|
import type { Bundler, Langs, Options, PromptResult } from './types.js'
|
||||||
|
import { DeployType, Mode, bundlerOptions, deployOptions, languageOptions } from './constants.js'
|
||||||
|
|
||||||
|
const require = createRequire(process.cwd())
|
||||||
|
|
||||||
|
const REG_DIR_CHAR = /[<>:"\\|?*[\]]/
|
||||||
|
|
||||||
|
export async function prompt(mode: Mode, root?: string): Promise<PromptResult> {
|
||||||
|
let hasTs = false
|
||||||
|
if (mode === Mode.init) {
|
||||||
|
try {
|
||||||
|
hasTs = !!require.resolve('typescript')
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: PromptResult = await group({
|
||||||
|
displayLang: async () => {
|
||||||
|
const lang = await select<Options<Langs>, Langs>({
|
||||||
|
message: 'Select a language to display / 选择显示语言',
|
||||||
|
options: languageOptions,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (typeof lang === 'string')
|
||||||
|
setLang(lang)
|
||||||
|
|
||||||
|
return lang
|
||||||
|
},
|
||||||
|
|
||||||
|
root: async () => {
|
||||||
|
if (root)
|
||||||
|
return root
|
||||||
|
const DEFAULT_ROOT = mode === Mode.init ? './docs' : './my-project'
|
||||||
|
return await text({
|
||||||
|
message: t('question.root'),
|
||||||
|
placeholder: DEFAULT_ROOT,
|
||||||
|
validate(value) {
|
||||||
|
// not absolute path or parent path
|
||||||
|
if (value?.startsWith('/') || value?.startsWith('..'))
|
||||||
|
return t('hint.root')
|
||||||
|
|
||||||
|
// not contains illegal characters
|
||||||
|
if (value && REG_DIR_CHAR.test(value))
|
||||||
|
return t('hint.root.illegal')
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
defaultValue: DEFAULT_ROOT,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
siteName: () => text({
|
||||||
|
message: t('question.site.name'),
|
||||||
|
placeholder: 'My Vuepress Site',
|
||||||
|
defaultValue: 'My Vuepress Site',
|
||||||
|
}),
|
||||||
|
|
||||||
|
siteDescription: () => text({
|
||||||
|
message: t('question.site.description'),
|
||||||
|
}),
|
||||||
|
|
||||||
|
multiLanguage: () => confirm({
|
||||||
|
message: t('question.multiLanguage'),
|
||||||
|
initialValue: false,
|
||||||
|
}),
|
||||||
|
|
||||||
|
defaultLanguage: () => select<Options<Langs>, Langs>({
|
||||||
|
message: t('question.defaultLanguage'),
|
||||||
|
options: languageOptions,
|
||||||
|
}),
|
||||||
|
|
||||||
|
useTs: async () => {
|
||||||
|
if (mode === Mode.init)
|
||||||
|
return hasTs
|
||||||
|
if (hasTs)
|
||||||
|
return true
|
||||||
|
return await confirm({
|
||||||
|
message: t('question.useTs'),
|
||||||
|
initialValue: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
injectNpmScripts: async () => {
|
||||||
|
if (mode === Mode.create)
|
||||||
|
return true
|
||||||
|
return await confirm({
|
||||||
|
message: t('question.injectNpmScripts'),
|
||||||
|
initialValue: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
bundler: () => select<Options<Bundler>, Bundler>({
|
||||||
|
message: t('question.bundler'),
|
||||||
|
options: bundlerOptions,
|
||||||
|
}),
|
||||||
|
|
||||||
|
deploy: async () => {
|
||||||
|
if (mode === Mode.init) {
|
||||||
|
return DeployType.custom
|
||||||
|
}
|
||||||
|
return await select<Options<DeployType>, DeployType>({
|
||||||
|
message: t('question.deploy'),
|
||||||
|
options: deployOptions,
|
||||||
|
initialValue: DeployType.custom,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
git: async () => {
|
||||||
|
if (mode === Mode.init)
|
||||||
|
return false
|
||||||
|
return confirm({
|
||||||
|
message: t('question.git'),
|
||||||
|
initialValue: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
install: () => confirm({
|
||||||
|
message: t('question.installDeps'),
|
||||||
|
initialValue: true,
|
||||||
|
}),
|
||||||
|
}, {
|
||||||
|
onCancel: () => {
|
||||||
|
cancel(t('hint.cancel'))
|
||||||
|
process.exit(0)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getTargetDir(cwd: string, dir?: string) {
|
||||||
|
if (dir === '.')
|
||||||
|
return cwd
|
||||||
|
|
||||||
|
if (typeof dir === 'string' && dir) {
|
||||||
|
return path.resolve(cwd, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_DIR = 'my-project'
|
||||||
|
|
||||||
|
const dirPath = await text({
|
||||||
|
message: t('question.root'),
|
||||||
|
placeholder: DEFAULT_DIR,
|
||||||
|
validate(value) {
|
||||||
|
if (value && REG_DIR_CHAR.test(value))
|
||||||
|
return t('hint.root.illegal')
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
defaultValue: DEFAULT_DIR,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (typeof dirPath === 'string') {
|
||||||
|
if (dirPath === '.')
|
||||||
|
return cwd
|
||||||
|
|
||||||
|
return path.join(cwd, dirPath || DEFAULT_DIR)
|
||||||
|
}
|
||||||
|
return dirPath
|
||||||
|
}
|
||||||
40
cli/src/render.ts
Normal file
40
cli/src/render.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import handlebars from 'handlebars'
|
||||||
|
import { kebabCase } from '@pengzhanbo/utils'
|
||||||
|
import type { ResolvedData } from './types.js'
|
||||||
|
|
||||||
|
export interface RenderData extends ResolvedData {
|
||||||
|
name: string
|
||||||
|
siteName: string
|
||||||
|
locales: { path: string, lang: string, isEn: boolean, prefix: string }[]
|
||||||
|
isEN: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
handlebars.registerHelper('removeLeadingSlash', (path: string) => path.replace(/^\//, ''))
|
||||||
|
handlebars.registerHelper('equal', (a: string, b: string) => a === b)
|
||||||
|
|
||||||
|
export function createRender(result: ResolvedData) {
|
||||||
|
const data: RenderData = {
|
||||||
|
...result,
|
||||||
|
name: kebabCase(result.siteName),
|
||||||
|
isEN: result.defaultLanguage === 'en-US',
|
||||||
|
locales: result.defaultLanguage === 'en-US'
|
||||||
|
? [
|
||||||
|
{ path: '/', lang: 'en-US', isEn: true, prefix: 'en' },
|
||||||
|
{ path: '/zh/', lang: 'zh-CN', isEn: false, prefix: 'zh' },
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{ path: '/', lang: 'zh-CN', isEn: false, prefix: 'zh' },
|
||||||
|
{ path: '/en/', lang: 'en-US', isEn: true, prefix: 'en' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
return function render(source: string): string {
|
||||||
|
try {
|
||||||
|
const template = handlebars.compile(source)
|
||||||
|
return template(data)
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
cli/src/run.ts
Normal file
54
cli/src/run.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { intro, outro, spinner } from '@clack/prompts'
|
||||||
|
import { execaCommand } from 'execa'
|
||||||
|
import colors from 'picocolors'
|
||||||
|
import { prompt } from './prompt.js'
|
||||||
|
import { generate } from './generate.js'
|
||||||
|
import { t } from './translate.js'
|
||||||
|
import { Mode } from './constants.js'
|
||||||
|
import type { PromptResult, ResolvedData } from './types.js'
|
||||||
|
import { getPackageManager } from './utils/index.js'
|
||||||
|
|
||||||
|
export async function run(mode: Mode, root?: string) {
|
||||||
|
intro(colors.cyan('Welcome to VuePress and vuepress-theme-plume !'))
|
||||||
|
|
||||||
|
const result = await prompt(mode, root)
|
||||||
|
const data = resolveData(result, mode)
|
||||||
|
|
||||||
|
const progress = spinner()
|
||||||
|
progress.start(t('spinner.start'))
|
||||||
|
|
||||||
|
await generate(mode, data)
|
||||||
|
|
||||||
|
if (data.git) {
|
||||||
|
progress.message(t('spinner.git'))
|
||||||
|
await execaCommand('git init')
|
||||||
|
}
|
||||||
|
|
||||||
|
const pm = data.packageManager
|
||||||
|
|
||||||
|
if (data.install) {
|
||||||
|
progress.message(t('spinner.install'))
|
||||||
|
await execaCommand(pm === 'yarn' ? 'yarn' : `${pm} install`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cdCommand = mode === Mode.create ? colors.green(`cd ${data.root}`) : ''
|
||||||
|
const runCommand = colors.green(pm === 'yarn' ? 'yarn dev' : `${pm} run dev`)
|
||||||
|
const installCommand = colors.green(pm === 'yarn' ? 'yarn' : `${pm} install`)
|
||||||
|
|
||||||
|
progress.stop(t('spinner.stop'))
|
||||||
|
|
||||||
|
if (mode === Mode.create) {
|
||||||
|
outro(`${t('spinner.command')}
|
||||||
|
${cdCommand}
|
||||||
|
${data.install ? '' : `${installCommand} && `}${runCommand}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveData(result: PromptResult, mode: Mode): ResolvedData {
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
packageManager: getPackageManager(),
|
||||||
|
docsDir: mode === Mode.create ? 'docs' : result.root.replace(/^\.\//, '').replace(/\/$/, ''),
|
||||||
|
siteDescription: result.siteDescription || '',
|
||||||
|
}
|
||||||
|
}
|
||||||
15
cli/src/translate.ts
Normal file
15
cli/src/translate.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import type { Langs, Locale } from './types.js'
|
||||||
|
import { locales } from './locales/index.js'
|
||||||
|
|
||||||
|
function createTranslate(lang?: Langs) {
|
||||||
|
let current: Langs = lang || 'en-US'
|
||||||
|
|
||||||
|
return {
|
||||||
|
setLang: (lang: Langs) => {
|
||||||
|
current = lang
|
||||||
|
},
|
||||||
|
t: (key: keyof Locale) => locales[current][key],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const { t, setLang } = createTranslate()
|
||||||
57
cli/src/types.ts
Normal file
57
cli/src/types.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import type { DeployType } from './constants.js'
|
||||||
|
|
||||||
|
export type Langs = 'zh-CN' | 'en-US'
|
||||||
|
|
||||||
|
export interface Locale {
|
||||||
|
'question.root': string
|
||||||
|
'question.site.name': string
|
||||||
|
'question.site.description': string
|
||||||
|
'question.multiLanguage': string
|
||||||
|
'question.defaultLanguage': string
|
||||||
|
'question.bundler': string
|
||||||
|
'question.useTs': string
|
||||||
|
'question.injectNpmScripts': string
|
||||||
|
'question.git': string
|
||||||
|
'question.deploy': string
|
||||||
|
'question.installDeps': string
|
||||||
|
|
||||||
|
'spinner.start': string
|
||||||
|
'spinner.stop': string
|
||||||
|
'spinner.git': string
|
||||||
|
'spinner.install': string
|
||||||
|
'spinner.command': string
|
||||||
|
|
||||||
|
'hint.cancel': string
|
||||||
|
'hint.root': string
|
||||||
|
'hint.root.illegal': string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PackageManager = 'npm' | 'yarn' | 'pnpm'
|
||||||
|
export type Bundler = 'vite' | 'webpack'
|
||||||
|
|
||||||
|
export type Options<Value = string, Label = string> = { label: Label, value: Value }[]
|
||||||
|
|
||||||
|
export interface File {
|
||||||
|
filepath: string
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PromptResult {
|
||||||
|
displayLang: string // cli display language
|
||||||
|
root: string
|
||||||
|
siteName: string
|
||||||
|
siteDescription: string
|
||||||
|
bundler: Bundler
|
||||||
|
multiLanguage: boolean
|
||||||
|
defaultLanguage: Langs
|
||||||
|
useTs: boolean
|
||||||
|
injectNpmScripts: boolean
|
||||||
|
deploy: DeployType
|
||||||
|
git: boolean
|
||||||
|
install: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResolvedData extends PromptResult {
|
||||||
|
packageManager: PackageManager
|
||||||
|
docsDir: string
|
||||||
|
}
|
||||||
16
cli/src/utils/depsVersion.ts
Normal file
16
cli/src/utils/depsVersion.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export type DependencyVersion = 'latest' | 'next' | 'pre' | string
|
||||||
|
|
||||||
|
const api = 'https://api.pengzhanbo.cn/npm/dependencies/version'
|
||||||
|
|
||||||
|
export async function getDependenciesVersion(
|
||||||
|
dependencies: string[],
|
||||||
|
version: DependencyVersion = 'latest',
|
||||||
|
): Promise<Record<string, string>> {
|
||||||
|
const result = await fetch(api, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'content-type': 'application/json' },
|
||||||
|
body: JSON.stringify({ dependencies, version }),
|
||||||
|
}).then(res => res.json())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
43
cli/src/utils/fs.ts
Normal file
43
cli/src/utils/fs.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import fs from 'node:fs/promises'
|
||||||
|
import type { File } from '../types.js'
|
||||||
|
|
||||||
|
export async function readFiles(root: string): Promise<File[]> {
|
||||||
|
const filepaths = await fs.readdir(root, { recursive: true })
|
||||||
|
const files: File[] = []
|
||||||
|
for (const file of filepaths) {
|
||||||
|
const filepath = path.join(root, file)
|
||||||
|
if ((await fs.stat(filepath)).isFile()) {
|
||||||
|
files.push({
|
||||||
|
filepath: file,
|
||||||
|
content: await fs.readFile(filepath, 'utf-8'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function writeFiles(
|
||||||
|
files: File[],
|
||||||
|
target: string,
|
||||||
|
rewrite?: (path: string) => string,
|
||||||
|
) {
|
||||||
|
for (const { filepath, content } of files) {
|
||||||
|
let root = path.join(target, filepath).replace(/\.handlebars$/, '')
|
||||||
|
if (rewrite)
|
||||||
|
root = rewrite(root)
|
||||||
|
await fs.mkdir(path.dirname(root), { recursive: true })
|
||||||
|
await fs.writeFile(root, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function readJsonFile<T extends Record<string, any> = Record<string, any>>(filepath: string): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const content = await fs.readFile(filepath, 'utf-8')
|
||||||
|
return JSON.parse(content)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
7
cli/src/utils/getPackageManager.ts
Normal file
7
cli/src/utils/getPackageManager.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import process from 'node:process'
|
||||||
|
import type { PackageManager } from '../types.js'
|
||||||
|
|
||||||
|
export function getPackageManager(): PackageManager {
|
||||||
|
const name = process.env?.npm_config_user_agent || 'npm'
|
||||||
|
return name.split('/')[0] as PackageManager
|
||||||
|
}
|
||||||
12
cli/src/utils/index.ts
Normal file
12
cli/src/utils/index.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import path from 'node:path'
|
||||||
|
|
||||||
|
export const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
export const resolve = (...args: string[]) => path.resolve(__dirname, '../', ...args)
|
||||||
|
|
||||||
|
export const getTemplate = (dir: string) => resolve('templates', dir)
|
||||||
|
|
||||||
|
export * from './fs.js'
|
||||||
|
export * from './depsVersion.js'
|
||||||
|
export * from './getPackageManager.js'
|
||||||
12
cli/templates/.vuepress/client.ts.handlebars
Normal file
12
cli/templates/.vuepress/client.ts.handlebars
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { defineClientConfig } from 'vuepress/client'
|
||||||
|
import RepoCard from 'vuepress-theme-plume/features/RepoCard.vue'
|
||||||
|
import CustomComponent from './theme/components/Custom.vue'
|
||||||
|
|
||||||
|
import './theme/styles/custom.css'
|
||||||
|
|
||||||
|
export default defineClientConfig({
|
||||||
|
enhance({ app }) {
|
||||||
|
app.component('RepoCard', RepoCard)
|
||||||
|
app.component('CustomComponent', CustomComponent)
|
||||||
|
},
|
||||||
|
})
|
||||||
90
cli/templates/.vuepress/config.ts.handlebars
Normal file
90
cli/templates/.vuepress/config.ts.handlebars
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { defineUserConfig } from 'vuepress'
|
||||||
|
import { {{ bundler }}Bundler } from '@vuepress/bundler-{{ bundler }}'
|
||||||
|
import { plumeTheme } from 'vuepress-theme-plume'
|
||||||
|
|
||||||
|
export default defineUserConfig({
|
||||||
|
base: '/',
|
||||||
|
lang: '{{ defaultLanguage }}',
|
||||||
|
{{#if multiLanguage}}
|
||||||
|
locales: {
|
||||||
|
{{#each locales}}
|
||||||
|
'{{ path }}': {
|
||||||
|
title: '{{ ../siteName }}',
|
||||||
|
lang: '{{ lang }}',
|
||||||
|
description: '{{ ../siteDescription }}',
|
||||||
|
},
|
||||||
|
{{/each}}
|
||||||
|
},
|
||||||
|
{{else}}
|
||||||
|
title: '{{ siteName }}',
|
||||||
|
description: '{{ siteDescription }}',
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
bundler: {{ bundler }}Bundler(),
|
||||||
|
|
||||||
|
theme: plumeTheme({
|
||||||
|
// 添加您的部署域名
|
||||||
|
// hostname: 'https://your_site_url',
|
||||||
|
|
||||||
|
plugins: {
|
||||||
|
/**
|
||||||
|
* Shiki 代码高亮
|
||||||
|
* @see https://theme-plume.vuejs.press/config/plugins/code-highlight/
|
||||||
|
*/
|
||||||
|
// shiki: {
|
||||||
|
// languages: ['shell', 'bash', 'typescript', 'javascript'],
|
||||||
|
// twoslash: true,
|
||||||
|
// },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* markdown enhance
|
||||||
|
* @see https://theme-plume.vuejs.press/config/plugins/markdown-enhance/
|
||||||
|
*/
|
||||||
|
markdownEnhance: {
|
||||||
|
demo: true,
|
||||||
|
// include: true,
|
||||||
|
// chart: true,
|
||||||
|
// echarts: true,
|
||||||
|
// mermaid: true,
|
||||||
|
// flowchart: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* markdown power
|
||||||
|
* @see https://theme-plume.vuejs.press/config/plugin/markdown-power/
|
||||||
|
*/
|
||||||
|
// markdownPower: {
|
||||||
|
// pdf: true,
|
||||||
|
// caniuse: true,
|
||||||
|
// plot: true,
|
||||||
|
// bilibili: true,
|
||||||
|
// youtube: true,
|
||||||
|
// icons: true,
|
||||||
|
// codepen: true,
|
||||||
|
// replit: true,
|
||||||
|
// codeSandbox: true,
|
||||||
|
// jsfiddle: true,
|
||||||
|
// repl: {
|
||||||
|
// go: true,
|
||||||
|
// rust: true,
|
||||||
|
// kotlin: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* comments
|
||||||
|
* @see https://theme-plume.vuejs.press/guide/features/comments/
|
||||||
|
*/
|
||||||
|
// comment: {
|
||||||
|
// provider: '', // "Artalk" | "Giscus" | "Twikoo" | "Waline"
|
||||||
|
// comment: true,
|
||||||
|
// repo: '',
|
||||||
|
// repoId: '',
|
||||||
|
// categoryId: '',
|
||||||
|
// mapping: 'pathname',
|
||||||
|
// reactionsEnabled: true,
|
||||||
|
// inputPosition: 'top',
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
28
cli/templates/.vuepress/navbar.ts.handlebars
Normal file
28
cli/templates/.vuepress/navbar.ts.handlebars
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { defineNavbarConfig } from 'vuepress-theme-plume'
|
||||||
|
|
||||||
|
{{#if multiLanguage}}
|
||||||
|
{{#each locales}}
|
||||||
|
export const {{prefix}}Navbar = defineNavbarConfig([
|
||||||
|
{ text: '{{#if isEn}}Home{{else}}首页{{/if}}', link: '{{ path }}' },
|
||||||
|
{ text: '{{#if isEn}}Blog{{else}}博客{{/if}}', link: '{{ path }}blog/' },
|
||||||
|
{ text: '{{#if isEn}}Tags{{else}}标签{{/if}}', link: '{{ path }}blog/tags/' },
|
||||||
|
{ text: '{{#if isEn}}Archives{{else}}归档{{/if}}', link: '{{ path }}blog/archives/' },
|
||||||
|
{
|
||||||
|
text: '{{#if isEn}}Notes{{else}}笔记{{/if}}',
|
||||||
|
items: [{ text: '{{#if isEn}}Demo{{else}}示例{{/if}}', link: '{{ path }}notes/demo/README.md' }]
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
{{/each}}
|
||||||
|
{{else}}
|
||||||
|
export const navbar = defineNavbarConfig([
|
||||||
|
{ text: '{{#if isEn}}Home{{else}}首页{{/if}}', link: '/' },
|
||||||
|
{ text: '{{#if isEn}}Blog{{else}}博客{{/if}}', link: '/blog/' },
|
||||||
|
{ text: '{{#if isEn}}Tags{{else}}标签{{/if}}', link: '/blog/tags/' },
|
||||||
|
{ text: '{{#if isEn}}Archives{{else}}归档{{/if}}', link: '/blog/archives/' },
|
||||||
|
{
|
||||||
|
text: '{{#if isEn}}Notes{{else}}笔记{{/if}}',
|
||||||
|
items: [{ text: '{{#if isEn}}Demo{{else}}示例{{/if}}', link: '/notes/demo/README.md' }]
|
||||||
|
},
|
||||||
|
])
|
||||||
|
{{/if}}
|
||||||
32
cli/templates/.vuepress/notes.ts.handlebars
Normal file
32
cli/templates/.vuepress/notes.ts.handlebars
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { defineNoteConfig, defineNotesConfig } from 'vuepress-theme-plume'
|
||||||
|
|
||||||
|
{{#if multiLanguage}}
|
||||||
|
{{#each locales}}
|
||||||
|
/* =================== locale: {{ lang }} ======================= */
|
||||||
|
|
||||||
|
const {{ prefix }}DemoNote = defineNoteConfig({
|
||||||
|
dir: 'demo',
|
||||||
|
link: '/demo',
|
||||||
|
sidebar: ['', 'foo', 'bar'],
|
||||||
|
})
|
||||||
|
|
||||||
|
export const {{ prefix }}Notes = defineNotesConfig({
|
||||||
|
dir: '{{ removeLeadingSlash path }}notes',
|
||||||
|
link: '{{ path }}',
|
||||||
|
notes: [{{ prefix }}DemoNote],
|
||||||
|
})
|
||||||
|
|
||||||
|
{{/each}}
|
||||||
|
{{else}}
|
||||||
|
const demoNote = defineNoteConfig({
|
||||||
|
dir: 'demo',
|
||||||
|
link: '/demo',
|
||||||
|
sidebar: ['', 'foo', 'bar'],
|
||||||
|
})
|
||||||
|
|
||||||
|
export const notes = defineNotesConfig({
|
||||||
|
dir: 'notes',
|
||||||
|
link: '/',
|
||||||
|
notes: [demoNote],
|
||||||
|
})
|
||||||
|
{{/if}}
|
||||||
57
cli/templates/.vuepress/plume.config.ts.handlebars
Normal file
57
cli/templates/.vuepress/plume.config.ts.handlebars
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { defineThemeConfig } from 'vuepress-theme-plume'
|
||||||
|
{{#if multiLanguage}}
|
||||||
|
import { enNavbar, zhNavbar } from './navbar'
|
||||||
|
import { enNotes, zhNotes } from './notes'
|
||||||
|
{{else}}
|
||||||
|
import { navbar } from './navbar'
|
||||||
|
import { notes } from './notes'
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://theme-plume.vuejs.press/config/basic/
|
||||||
|
*/
|
||||||
|
export default defineThemeConfig({
|
||||||
|
logo: 'https://theme-plume.vuejs.press/plume.png',
|
||||||
|
// your git repo url
|
||||||
|
docsRepo: '',
|
||||||
|
docsDir: '{{ docsDir }}',
|
||||||
|
|
||||||
|
appearance: true,
|
||||||
|
|
||||||
|
{{#unless multiLanguage}}
|
||||||
|
profile: {
|
||||||
|
avatar: 'https://theme-plume.vuejs.press/plume.png',
|
||||||
|
name: '{{ siteName }}',
|
||||||
|
description: '{{ siteDescription }}',
|
||||||
|
// circle: true,
|
||||||
|
// location: '',
|
||||||
|
// organization: '',
|
||||||
|
},
|
||||||
|
|
||||||
|
navbar,
|
||||||
|
notes,
|
||||||
|
{{/unless}}
|
||||||
|
social: [
|
||||||
|
{ icon: 'github', link: '/' },
|
||||||
|
],
|
||||||
|
|
||||||
|
{{#if multiLanguage}}
|
||||||
|
locales: {
|
||||||
|
{{#each locales}}
|
||||||
|
'{{ path }}': {
|
||||||
|
profile: {
|
||||||
|
avatar: 'https://theme-plume.vuejs.press/plume.png',
|
||||||
|
name: '{{ ../siteName }}',
|
||||||
|
description: '{{ ../siteDescription }}',
|
||||||
|
// circle: true,
|
||||||
|
// location: '',
|
||||||
|
// organization: '',
|
||||||
|
},
|
||||||
|
|
||||||
|
navbar: {{ prefix }}Navbar,
|
||||||
|
notes: {{ prefix }}Notes,
|
||||||
|
},
|
||||||
|
{{/each}}
|
||||||
|
},
|
||||||
|
{{/if}}
|
||||||
|
})
|
||||||
8
cli/templates/.vuepress/public/plume.svg
Normal file
8
cli/templates/.vuepress/public/plume.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 72 72">
|
||||||
|
<path fill="#5086a1" d="M42.334 49.147a29.945 29.945 0 0 1-19.338-8.151c-8.014-7.365-8.378-18.076-8.533-22.649l-.022-.627a2.904 2.904 0 0 1 3.457-2.951c17.005 3.355 21.695 16.324 22.056 17.4a49.543 49.543 0 0 1 3.574 15.922a1 1 0 0 1-.967 1.052c-.029.001-.106.004-.227.004" />
|
||||||
|
<path fill="#8cccd5" d="M44.436 55.316c-11.646 0-17.376-6.974-17.653-7.354a1 1 0 0 1 .262-1.424a11.103 11.103 0 0 1 12.774-1.574c-1.465-9.078 1.877-13.568 2.031-13.77a.998.998 0 0 1 .75-.39a.97.97 0 0 1 .78.325c8.944 9.771 8.793 16.532 7.908 19.691c-.034.14-1.062 4.092-4.772 4.406c-.711.062-1.405.09-2.08.09" />
|
||||||
|
<g fill="none" stroke="#333" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
|
||||||
|
<path d="M55.184 57.69S34.96 45.877 23.097 24.206m22.131 30.096c-11.93.46-17.628-6.88-17.628-6.88" />
|
||||||
|
<path d="M40.528 42.483c-.56-7.195 2.116-10.679 2.116-10.679c8.834 9.654 8.406 16.162 7.681 18.747m-13.311-3.129a30.15 30.15 0 0 1-13.341-7.162c-8.072-7.419-8.067-18.241-8.232-22.577a1.903 1.903 0 0 1 2.264-1.932C34.694 19.103 39.02 32.528 39.02 32.528" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
11
cli/templates/.vuepress/theme/components/Custom.vue
Normal file
11
cli/templates/.vuepress/theme/components/Custom.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const message = ref('Hello World!')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="my-custom-content">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
6
cli/templates/.vuepress/theme/shim.d.ts
vendored
Normal file
6
cli/templates/.vuepress/theme/shim.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
declare module '*.vue' {
|
||||||
|
import type { ComponentOptions } from 'vue'
|
||||||
|
|
||||||
|
const comp: ComponentOptions
|
||||||
|
export default comp
|
||||||
|
}
|
||||||
50
cli/templates/.vuepress/theme/styles/custom.css
Normal file
50
cli/templates/.vuepress/theme/styles/custom.css
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
:root {
|
||||||
|
/** 主题颜色 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
--vp-c-brand-1: #5086a1;
|
||||||
|
--vp-c-brand-2: #6aa1b7;
|
||||||
|
--vp-c-brand-3: #8cccd5;
|
||||||
|
--vp-c-brand-soft: rgba(131, 208, 218, 0.314);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 背景颜色 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
--vp-c-bg: #fff;
|
||||||
|
--vp-c-bg-alt: #f6f6f7;
|
||||||
|
--vp-c-bg-elv: #fff;
|
||||||
|
--vp-c-bg-soft: #f6f6f7;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 文本颜色 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
--vp-c-text-1: rgba(60, 60, 67);
|
||||||
|
--vp-c-text-2: rgba(60, 60, 67, 0.78);
|
||||||
|
--vp-c-text-3: rgba(60, 60, 67, 0.56);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 深色模式 */
|
||||||
|
.dark {
|
||||||
|
/*
|
||||||
|
--vp-c-brand-1: #8cccd5;
|
||||||
|
--vp-c-brand-2: #6aa1b7;
|
||||||
|
--vp-c-brand-3: #5086a1;
|
||||||
|
--vp-c-brand-soft: rgba(131, 208, 218, 0.314);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
--vp-c-bg: #1b1b1f;
|
||||||
|
--vp-c-bg-alt: #161618;
|
||||||
|
--vp-c-bg-elv: #202127;
|
||||||
|
--vp-c-bg-soft: #202127;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
--vp-c-text-1: rgba(255, 255, 245, 0.86);
|
||||||
|
--vp-c-text-2: rgba(235, 235, 245, 0.6);
|
||||||
|
--vp-c-text-3: rgba(235, 235, 245, 0.38);
|
||||||
|
*/
|
||||||
|
}
|
||||||
57
cli/templates/common/README.md.handlebars
Normal file
57
cli/templates/common/README.md.handlebars
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# {{ name }}
|
||||||
|
|
||||||
|
The Site is generated using [vuepress](https://vuepress.vuejs.org/) and [vuepress-theme-plume](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
{{#if (equal packageManager "pnpm")}}
|
||||||
|
pnpm i
|
||||||
|
{{else if (equal packageManager "yarn")}}
|
||||||
|
yarn
|
||||||
|
{{else}}
|
||||||
|
npm i
|
||||||
|
{{/if}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
{{#if (equal packageManager "pnpm")}}
|
||||||
|
```sh
|
||||||
|
# start dev server
|
||||||
|
pnpm docs:dev
|
||||||
|
# build for production
|
||||||
|
pnpm docs:build
|
||||||
|
# preview production build in local
|
||||||
|
pnpm docs:preview
|
||||||
|
# update vuepress and theme
|
||||||
|
pnpm vp-update
|
||||||
|
```
|
||||||
|
{{else if (equal packageManager "yarn")}}
|
||||||
|
```sh
|
||||||
|
# start dev server
|
||||||
|
yarn docs:dev
|
||||||
|
# build for production
|
||||||
|
yarn docs:build
|
||||||
|
# preview production build in local
|
||||||
|
yarn docs:preview
|
||||||
|
# update vuepress and theme
|
||||||
|
yarn vp-update
|
||||||
|
```
|
||||||
|
{{else}}
|
||||||
|
```sh
|
||||||
|
# start dev server
|
||||||
|
npm run docs:dev
|
||||||
|
# build for production
|
||||||
|
npm run docs:build
|
||||||
|
# preview production build in local
|
||||||
|
npm run docs:preview
|
||||||
|
# update vuepress and theme
|
||||||
|
npm run vp-update
|
||||||
|
```
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
## Documents
|
||||||
|
|
||||||
|
- [vuepress](https://vuepress.vuejs.org/)
|
||||||
|
- [vuepress-theme-plume](https://theme-plume.vuejs.press/)
|
||||||
57
cli/templates/common/README.zh-CN.md.handlebars
Normal file
57
cli/templates/common/README.zh-CN.md.handlebars
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# {{ name }}
|
||||||
|
|
||||||
|
网站使用 [vuepress](https://vuepress.vuejs.org/) 和 [vuepress-theme-plume](https://github.com/pengzhanbo/vuepress-theme-plume) 构建生成。
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
{{#if (equal packageManager "pnpm")}}
|
||||||
|
pnpm i
|
||||||
|
{{else if (equal packageManager "yarn")}}
|
||||||
|
yarn
|
||||||
|
{{else}}
|
||||||
|
npm i
|
||||||
|
{{/if}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
{{#if (equal packageManager "pnpm")}}
|
||||||
|
```sh
|
||||||
|
# 启动开发服务
|
||||||
|
pnpm docs:dev
|
||||||
|
# 构建生产包
|
||||||
|
pnpm docs:build
|
||||||
|
# 本地预览生产服务
|
||||||
|
pnpm docs:preview
|
||||||
|
# 更新 vuepress 和主题
|
||||||
|
pnpm vp-update
|
||||||
|
```
|
||||||
|
{{else if (equal packageManager "yarn")}}
|
||||||
|
```sh
|
||||||
|
# 启动开发服务
|
||||||
|
yarn docs:dev
|
||||||
|
# 构建生产包
|
||||||
|
yarn docs:build
|
||||||
|
# 本地预览生产服务
|
||||||
|
yarn docs:preview
|
||||||
|
# update vuepress and theme
|
||||||
|
yarn vp-update
|
||||||
|
```
|
||||||
|
{{else}}
|
||||||
|
```sh
|
||||||
|
# 启动开发服务
|
||||||
|
npm run docs:dev
|
||||||
|
# 构建生产包
|
||||||
|
npm run docs:build
|
||||||
|
# 本地预览生产服务
|
||||||
|
npm run docs:preview
|
||||||
|
# 更新 vuepress 和主题
|
||||||
|
npm run vp-update
|
||||||
|
```
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
- [vuepress](https://vuepress.vuejs.org/)
|
||||||
|
- [vuepress-theme-plume](https://theme-plume.vuejs.press/)
|
||||||
70
cli/templates/deploy/github/.github/workflows/deploy.yml.handlebars
vendored
Normal file
70
cli/templates/deploy/github/.github/workflows/deploy.yml.handlebars
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
name: deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
# 每当 push 到 main 分支时触发部署
|
||||||
|
# Deployment is triggered whenever a push is made to the main branch.
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
# 手动触发部署
|
||||||
|
# Manually trigger deployment
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
# “最近更新时间” 等 git 日志相关信息,需要拉取全部提交记录
|
||||||
|
# "Last updated time" and other git log-related information require fetching all commit records.
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
{{#if (equal packageManager "pnpm")}}
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
# 选择要使用的 pnpm 版本
|
||||||
|
version: 9
|
||||||
|
# 使用 pnpm 安装依赖
|
||||||
|
run_install: true
|
||||||
|
{{/if}}
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
# 选择要使用的 node 版本
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
{{#if (equal packageManager "yarn")}}
|
||||||
|
- name: Run install
|
||||||
|
uses: borales/actions-yarn@v4
|
||||||
|
with:
|
||||||
|
cmd: install
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
# 运行构建脚本
|
||||||
|
# Run the build script
|
||||||
|
{{#unless (equal packageManager "yarn")}}
|
||||||
|
- name: Build VuePress site
|
||||||
|
run: {{packageManager}} run docs:build
|
||||||
|
{{/unless}}
|
||||||
|
{{#if (equal packageManager "yarn")}}
|
||||||
|
- name: Build VuePress site
|
||||||
|
uses: borales/actions-yarn@v4
|
||||||
|
with:
|
||||||
|
cmd: docs:build
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
# 查看 workflow 的文档来获取更多信息
|
||||||
|
# @see https://github.com/crazy-max/ghaction-github-pages
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
uses: crazy-max/ghaction-github-pages@v4
|
||||||
|
with:
|
||||||
|
# 部署到 gh-pages 分支
|
||||||
|
target_branch: gh-pages
|
||||||
|
# 部署目录为 VuePress 的默认输出目录
|
||||||
|
build_dir: {{docsDir}}/.vuepress/dist
|
||||||
|
env:
|
||||||
|
# @see https://docs.github.com/cn/actions/reference/authentication-in-a-workflow#about-the-github_token-secret
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
9
cli/templates/deploy/netlify/netlify.toml.handlebars
Normal file
9
cli/templates/deploy/netlify/netlify.toml.handlebars
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# prevent Netlify npm install
|
||||||
|
|
||||||
|
[build]
|
||||||
|
publish = "{{ docsDir }}/.vuepress/dist"
|
||||||
|
command = "{{#if (equal packageManager 'yarn')}}yarn && yarn{{else}}{{packageManager}} run{{/if}} docs:build"
|
||||||
|
|
||||||
|
[build.environment]
|
||||||
|
NODE_VERSION = "20"
|
||||||
|
NPM_FLAGS = "--version"
|
||||||
6
cli/templates/deploy/vercel/vercel.json.handlebars
Normal file
6
cli/templates/deploy/vercel/vercel.json.handlebars
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"framework": null,
|
||||||
|
"buildCommand": "{{#if (equal packageManager 'yarn')}}yarn{{else}}{{packageManager}} run{{/if}} docs:build",
|
||||||
|
"installCommand": "{{#if (equal packageManager 'yarn')}}yarn{{else}}{{packageManager}} install{{/if}}",
|
||||||
|
"outputDirectory": "{{ docsDir }}/.vuepress/dist"
|
||||||
|
}
|
||||||
22
cli/templates/docs/en/README.md.handlebars
Normal file
22
cli/templates/docs/en/README.md.handlebars
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
pageLayout: home
|
||||||
|
externalLinkIcon: false
|
||||||
|
config:
|
||||||
|
-
|
||||||
|
type: hero
|
||||||
|
full: true
|
||||||
|
background: tint-plate
|
||||||
|
hero:
|
||||||
|
name: Theme Plume
|
||||||
|
tagline: VuePress Next Theme
|
||||||
|
text: A simple, feature-rich, document & blog
|
||||||
|
actions:
|
||||||
|
-
|
||||||
|
theme: brand
|
||||||
|
text: Blog
|
||||||
|
link: {{#if (equal defaultLanguage 'en-US')}}/{{else}}/en/{{/if}}blog/
|
||||||
|
-
|
||||||
|
theme: alt
|
||||||
|
text: Github →
|
||||||
|
link: https://github.com/pengzhanbo/vuepress-theme-plume
|
||||||
|
---
|
||||||
6
cli/templates/docs/en/notes/demo/README.md
Normal file
6
cli/templates/docs/en/notes/demo/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Demo
|
||||||
|
---
|
||||||
|
|
||||||
|
- [bar](./bar.md)
|
||||||
|
- [foo](./foo.md)
|
||||||
5
cli/templates/docs/en/notes/demo/bar.md
Normal file
5
cli/templates/docs/en/notes/demo/bar.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: bar
|
||||||
|
---
|
||||||
|
|
||||||
|
[foo](./foo.md)
|
||||||
5
cli/templates/docs/en/notes/demo/foo.md
Normal file
5
cli/templates/docs/en/notes/demo/foo.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: foo
|
||||||
|
---
|
||||||
|
|
||||||
|
[bar](./bar.md)
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: Custom Component
|
||||||
|
tags:
|
||||||
|
- preview
|
||||||
|
- component
|
||||||
|
---
|
||||||
|
|
||||||
|
<CustomComponent />
|
||||||
312
cli/templates/docs/en/preview/markdown.md
Normal file
312
cli/templates/docs/en/preview/markdown.md
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
---
|
||||||
|
title: Markdown
|
||||||
|
tags:
|
||||||
|
- markdown
|
||||||
|
---
|
||||||
|
|
||||||
|
## Heading 2
|
||||||
|
|
||||||
|
### Heading 3
|
||||||
|
|
||||||
|
#### Heading 4
|
||||||
|
|
||||||
|
##### Heading 5
|
||||||
|
|
||||||
|
###### Heading 6
|
||||||
|
|
||||||
|
Bold: **Bold text**
|
||||||
|
|
||||||
|
Italic: _Italic text_
|
||||||
|
|
||||||
|
~~Deleted text~~
|
||||||
|
|
||||||
|
Content ==Highlight==
|
||||||
|
|
||||||
|
Mathematical expression: $-(2^{n-1})$ ~ $2^{n-1} -1$
|
||||||
|
|
||||||
|
$\frac {\partial^r} {\partial \omega^r} \left(\frac {y^{\omega}} {\omega}\right)
|
||||||
|
= \left(\frac {y^{\omega}} {\omega}\right) \left\{(\log y)^r + \sum_{i=1}^r \frac {(-1)^ Ir \cdots (r-i+1) (\log y)^{ri}} {\omega^i} \right\}$
|
||||||
|
|
||||||
|
19^th^
|
||||||
|
|
||||||
|
H~2~O
|
||||||
|
|
||||||
|
::: center
|
||||||
|
content center
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: right
|
||||||
|
content right
|
||||||
|
:::
|
||||||
|
|
||||||
|
- Unordered List 1
|
||||||
|
- Unordered List 2
|
||||||
|
- Unordered List 3
|
||||||
|
|
||||||
|
1. Ordered List 1
|
||||||
|
2. Ordered List 2
|
||||||
|
3. Ordered List 3
|
||||||
|
|
||||||
|
- [ ] Task List 1
|
||||||
|
- [ ] Task List 2
|
||||||
|
- [x] Task List 3
|
||||||
|
- [x] Task List 4
|
||||||
|
|
||||||
|
| Tables | Are | Cool |
|
||||||
|
| ------------- |:-------------:| -----:|
|
||||||
|
| col 3 is | right-aligned | $1600 |
|
||||||
|
| col 2 is | centered | $12 |
|
||||||
|
| zebra stripes | are neat | $1 |
|
||||||
|
|
||||||
|
> quote content
|
||||||
|
>
|
||||||
|
> quote content
|
||||||
|
|
||||||
|
[links](/)
|
||||||
|
|
||||||
|
[outside links](https://github.com/pengzhanbo)
|
||||||
|
|
||||||
|
**Badge:**
|
||||||
|
|
||||||
|
- <Badge type="info" text="info badge" />
|
||||||
|
- <Badge type="tip" text="tip badge" />
|
||||||
|
- <Badge type="warning" text="warning badge" />
|
||||||
|
- <Badge type="danger" text="danger badge" />
|
||||||
|
|
||||||
|
**icons:**
|
||||||
|
|
||||||
|
- home - <Icon name="material-symbols:home" color="currentColor" size="1em" />
|
||||||
|
- vscode - <Icon name="skill-icons:vscode-dark" size="2em" />
|
||||||
|
- twitter - <Icon name="skill-icons:twitter" size="2em" />
|
||||||
|
|
||||||
|
**demo wrapper:**
|
||||||
|
|
||||||
|
::: demo-wrapper title="Demo" no-padding height="200px"
|
||||||
|
<style scoped>
|
||||||
|
.open-door {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.open-door .main {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="open-door">
|
||||||
|
<div class="main">main</div>
|
||||||
|
<div class="aside">aside</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**code block:**
|
||||||
|
|
||||||
|
```js whitespace
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
|
||||||
|
// [!code word:obj]
|
||||||
|
const obj = {
|
||||||
|
toLong: {
|
||||||
|
deep: {
|
||||||
|
deep: {
|
||||||
|
deep: {
|
||||||
|
value: 'this is to long text. this is to long text. this is to long text. this is to long text.', // [!code highlight]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**code groups:**
|
||||||
|
|
||||||
|
::: code-tabs
|
||||||
|
@tab tab1
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab tab2
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const a: number = 1
|
||||||
|
const b: number = 2
|
||||||
|
const c: number = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**code highlight:**
|
||||||
|
|
||||||
|
```ts
|
||||||
|
function foo() {
|
||||||
|
const a = 1 // [!code highlight]
|
||||||
|
|
||||||
|
console.log(a)
|
||||||
|
|
||||||
|
const b = 2 // [!code ++]
|
||||||
|
const c = 3 // [!code --]
|
||||||
|
|
||||||
|
console.log(a + b + c) // [!code error]
|
||||||
|
console.log(a + b) // [!code warning]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**code focus:**
|
||||||
|
|
||||||
|
```ts
|
||||||
|
function foo() {
|
||||||
|
const a = 1 // [!code focus]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
::: note
|
||||||
|
note content [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: info
|
||||||
|
content [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
content [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
content [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: caution
|
||||||
|
content [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: important
|
||||||
|
content [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**GFM alert:**
|
||||||
|
|
||||||
|
> [!note]
|
||||||
|
> note
|
||||||
|
|
||||||
|
> [!info]
|
||||||
|
> info
|
||||||
|
|
||||||
|
> [!tip]
|
||||||
|
> tip
|
||||||
|
|
||||||
|
> [!warning]
|
||||||
|
> warning
|
||||||
|
|
||||||
|
> [!caution]
|
||||||
|
> caution
|
||||||
|
|
||||||
|
> [!important]
|
||||||
|
> important
|
||||||
|
|
||||||
|
**code demo:**
|
||||||
|
|
||||||
|
::: normal-demo Demo 演示
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h1>Hello Word!</h1>
|
||||||
|
<p><span id="very">Very</span>Powerful!</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
document.querySelector('#very').addEventListener('click', () => {
|
||||||
|
alert('Very Powerful')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```css
|
||||||
|
span {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**tab card:**
|
||||||
|
|
||||||
|
::: tabs
|
||||||
|
@tab title 1
|
||||||
|
content block
|
||||||
|
|
||||||
|
@tab title 2
|
||||||
|
content block
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::: warning
|
||||||
|
::: tabs
|
||||||
|
@tab title 1
|
||||||
|
content block
|
||||||
|
|
||||||
|
@tab title 2
|
||||||
|
content block
|
||||||
|
:::
|
||||||
|
::::
|
||||||
|
|
||||||
|
**footnote:**
|
||||||
|
|
||||||
|
footnote 1 link[^first]。
|
||||||
|
|
||||||
|
footnote 2 link[^second]。
|
||||||
|
|
||||||
|
inline footnote ^[^first] definition。
|
||||||
|
|
||||||
|
Repeated footnote definition[^second]。
|
||||||
|
|
||||||
|
[^first]: footnote **you can contain special mark**
|
||||||
|
|
||||||
|
also can contain paragraph
|
||||||
|
|
||||||
|
[^second]: footnote content.
|
||||||
22
cli/templates/docs/zh/README.md.handlebars
Normal file
22
cli/templates/docs/zh/README.md.handlebars
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
pageLayout: home
|
||||||
|
externalLinkIcon: false
|
||||||
|
config:
|
||||||
|
-
|
||||||
|
type: hero
|
||||||
|
full: true
|
||||||
|
background: tint-plate
|
||||||
|
hero:
|
||||||
|
name: Theme Plume
|
||||||
|
tagline: VuePress Next Theme
|
||||||
|
text: 一个简约的,功能丰富的 vuepress 文档&博客 主题
|
||||||
|
actions:
|
||||||
|
-
|
||||||
|
theme: brand
|
||||||
|
text: 博客
|
||||||
|
link: {{#if (equal defaultLanguage 'zh-CN')}}/{{else}}/zh/{{/if}}blog/
|
||||||
|
-
|
||||||
|
theme: alt
|
||||||
|
text: Github →
|
||||||
|
link: https://github.com/pengzhanbo/vuepress-theme-plume
|
||||||
|
---
|
||||||
6
cli/templates/docs/zh/notes/demo/README.md
Normal file
6
cli/templates/docs/zh/notes/demo/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Demo
|
||||||
|
---
|
||||||
|
|
||||||
|
- [bar](./bar.md)
|
||||||
|
- [foo](./foo.md)
|
||||||
5
cli/templates/docs/zh/notes/demo/bar.md
Normal file
5
cli/templates/docs/zh/notes/demo/bar.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: bar
|
||||||
|
---
|
||||||
|
|
||||||
|
[foo](./foo.md)
|
||||||
5
cli/templates/docs/zh/notes/demo/foo.md
Normal file
5
cli/templates/docs/zh/notes/demo/foo.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: foo
|
||||||
|
---
|
||||||
|
|
||||||
|
[bar](./bar.md)
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: 自定义组件
|
||||||
|
tags:
|
||||||
|
- 预览
|
||||||
|
- 组件
|
||||||
|
---
|
||||||
|
|
||||||
|
<CustomComponent />
|
||||||
312
cli/templates/docs/zh/preview/markdown.md
Normal file
312
cli/templates/docs/zh/preview/markdown.md
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
---
|
||||||
|
title: Markdown
|
||||||
|
tags:
|
||||||
|
- markdown
|
||||||
|
---
|
||||||
|
|
||||||
|
## 标题 2
|
||||||
|
|
||||||
|
### 标题 3
|
||||||
|
|
||||||
|
#### 标题 4
|
||||||
|
|
||||||
|
##### 标题 5
|
||||||
|
|
||||||
|
###### 标题 6
|
||||||
|
|
||||||
|
加粗:**加粗文字**
|
||||||
|
|
||||||
|
斜体: _斜体文字_
|
||||||
|
|
||||||
|
~~删除文字~~
|
||||||
|
|
||||||
|
内容 ==标记==
|
||||||
|
|
||||||
|
数学表达式: $-(2^{n-1})$ ~ $2^{n-1} -1$
|
||||||
|
|
||||||
|
$\frac {\partial^r} {\partial \omega^r} \left(\frac {y^{\omega}} {\omega}\right)
|
||||||
|
= \left(\frac {y^{\omega}} {\omega}\right) \left\{(\log y)^r + \sum_{i=1}^r \frac {(-1)^ Ir \cdots (r-i+1) (\log y)^{ri}} {\omega^i} \right\}$
|
||||||
|
|
||||||
|
19^th^
|
||||||
|
|
||||||
|
H~2~O
|
||||||
|
|
||||||
|
::: center
|
||||||
|
内容居中
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: right
|
||||||
|
内容右对齐
|
||||||
|
:::
|
||||||
|
|
||||||
|
- 无序列表1
|
||||||
|
- 无序列表2
|
||||||
|
- 无序列表3
|
||||||
|
|
||||||
|
1. 有序列表1
|
||||||
|
2. 有序列表2
|
||||||
|
3. 有序列表3
|
||||||
|
|
||||||
|
- [ ] 任务列表1
|
||||||
|
- [ ] 任务列表2
|
||||||
|
- [x] 任务列表3
|
||||||
|
- [x] 任务列表4
|
||||||
|
|
||||||
|
| Tables | Are | Cool |
|
||||||
|
| ------------- |:-------------:| -----:|
|
||||||
|
| col 3 is | right-aligned | $1600 |
|
||||||
|
| col 2 is | centered | $12 |
|
||||||
|
| zebra stripes | are neat | $1 |
|
||||||
|
|
||||||
|
> 引用内容
|
||||||
|
>
|
||||||
|
> 引用内容
|
||||||
|
|
||||||
|
[链接](/)
|
||||||
|
|
||||||
|
[外部链接](https://github.com/pengzhanbo)
|
||||||
|
|
||||||
|
**Badge:**
|
||||||
|
|
||||||
|
- <Badge type="info" text="info badge" />
|
||||||
|
- <Badge type="tip" text="tip badge" />
|
||||||
|
- <Badge type="warning" text="warning badge" />
|
||||||
|
- <Badge type="danger" text="danger badge" />
|
||||||
|
|
||||||
|
**图标:**
|
||||||
|
|
||||||
|
- home - <Icon name="material-symbols:home" color="currentColor" size="1em" />
|
||||||
|
- vscode - <Icon name="skill-icons:vscode-dark" size="2em" />
|
||||||
|
- twitter - <Icon name="skill-icons:twitter" size="2em" />
|
||||||
|
|
||||||
|
**demo wrapper:**
|
||||||
|
|
||||||
|
::: demo-wrapper title="示例" no-padding height="200px"
|
||||||
|
<style scoped>
|
||||||
|
.open-door {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.open-door .main {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="open-door">
|
||||||
|
<div class="main">main</div>
|
||||||
|
<div class="aside">aside</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**代码:**
|
||||||
|
|
||||||
|
```js whitespace
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
|
||||||
|
// [!code word:obj]
|
||||||
|
const obj = {
|
||||||
|
toLong: {
|
||||||
|
deep: {
|
||||||
|
deep: {
|
||||||
|
deep: {
|
||||||
|
value: 'this is to long text. this is to long text. this is to long text. this is to long text.', // [!code highlight]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**代码分组:**
|
||||||
|
|
||||||
|
::: code-tabs
|
||||||
|
@tab tab1
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab tab2
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const a: number = 1
|
||||||
|
const b: number = 2
|
||||||
|
const c: number = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**代码块高亮:**
|
||||||
|
|
||||||
|
```ts
|
||||||
|
function foo() {
|
||||||
|
const a = 1 // [!code highlight]
|
||||||
|
|
||||||
|
console.log(a)
|
||||||
|
|
||||||
|
const b = 2 // [!code ++]
|
||||||
|
const c = 3 // [!code --]
|
||||||
|
|
||||||
|
console.log(a + b + c) // [!code error]
|
||||||
|
console.log(a + b) // [!code warning]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**代码块聚焦:**
|
||||||
|
|
||||||
|
```ts
|
||||||
|
function foo() {
|
||||||
|
const a = 1 // [!code focus]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
::: note 注释
|
||||||
|
注释内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: info 信息
|
||||||
|
信息内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: tip 提示
|
||||||
|
提示内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: warning 警告
|
||||||
|
警告内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: caution 错误
|
||||||
|
错误内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: important 重要
|
||||||
|
重要内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const a = 1
|
||||||
|
const b = 2
|
||||||
|
const c = a + b
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**GFM alert:**
|
||||||
|
|
||||||
|
> [!note]
|
||||||
|
> note
|
||||||
|
|
||||||
|
> [!info]
|
||||||
|
> info
|
||||||
|
|
||||||
|
> [!tip]
|
||||||
|
> tip
|
||||||
|
|
||||||
|
> [!warning]
|
||||||
|
> warning
|
||||||
|
|
||||||
|
> [!caution]
|
||||||
|
> caution
|
||||||
|
|
||||||
|
> [!important]
|
||||||
|
> important
|
||||||
|
|
||||||
|
**代码演示:**
|
||||||
|
|
||||||
|
::: normal-demo Demo 演示
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h1>Hello Word!</h1>
|
||||||
|
<p><span id="very">非常</span>强大!</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
document.querySelector('#very').addEventListener('click', () => {
|
||||||
|
alert('非常强大')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```css
|
||||||
|
span {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
**选项卡:**
|
||||||
|
|
||||||
|
::: tabs
|
||||||
|
@tab 标题1
|
||||||
|
内容区块
|
||||||
|
|
||||||
|
@tab 标题2
|
||||||
|
内容区块
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::: warning
|
||||||
|
::: tabs
|
||||||
|
@tab 标题1
|
||||||
|
内容区块
|
||||||
|
|
||||||
|
@tab 标题2
|
||||||
|
内容区块
|
||||||
|
:::
|
||||||
|
::::
|
||||||
|
|
||||||
|
**脚注:**
|
||||||
|
|
||||||
|
脚注 1 链接[^first]。
|
||||||
|
|
||||||
|
脚注 2 链接[^second]。
|
||||||
|
|
||||||
|
行内的脚注^[行内脚注文本] 定义。
|
||||||
|
|
||||||
|
重复的页脚定义[^second]。
|
||||||
|
|
||||||
|
[^first]: 脚注 **可以包含特殊标记**
|
||||||
|
|
||||||
|
也可以由多个段落组成
|
||||||
|
|
||||||
|
[^second]: 脚注文字。
|
||||||
10
cli/templates/git/.gitattributes.handlebars
Normal file
10
cli/templates/git/.gitattributes.handlebars
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
* text eol=lf
|
||||||
|
*.txt text eol=crlf
|
||||||
|
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.jpeg binary
|
||||||
|
*.ico binary
|
||||||
|
*.tff binary
|
||||||
|
*.woff binary
|
||||||
|
*.woff2 binary
|
||||||
8
cli/templates/git/.gitignore.handlebars
Normal file
8
cli/templates/git/.gitignore.handlebars
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
node_modules
|
||||||
|
|
||||||
|
{{ docsDir }}/.vuepress/.cache
|
||||||
|
{{ docsDir }}/.vuepress/.temp
|
||||||
|
{{ docsDir }}/.vuepress/dist
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
15
cli/tsup.config.ts
Normal file
15
cli/tsup.config.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { defineConfig } from 'tsup'
|
||||||
|
import { version } from './package.json'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
entry: ['src/index.ts'],
|
||||||
|
outDir: 'lib',
|
||||||
|
dts: true,
|
||||||
|
format: 'esm',
|
||||||
|
sourcemap: false,
|
||||||
|
splitting: false,
|
||||||
|
clean: true,
|
||||||
|
define: {
|
||||||
|
__CLI_VERSION__: JSON.stringify(version),
|
||||||
|
},
|
||||||
|
})
|
||||||
@ -9,7 +9,7 @@ const packages = fs.readdirSync(path.resolve(__dirname, 'plugins'))
|
|||||||
export default {
|
export default {
|
||||||
extends: ['@commitlint/config-conventional'],
|
extends: ['@commitlint/config-conventional'],
|
||||||
rules: {
|
rules: {
|
||||||
'scope-enum': [2, 'always', ['docs', 'theme', ...packages]],
|
'scope-enum': [2, 'always', ['docs', 'theme', 'cli', ...packages]],
|
||||||
'footer-max-line-length': [0],
|
'footer-max-line-length': [0],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
84
pnpm-lock.yaml
generated
84
pnpm-lock.yaml
generated
@ -72,6 +72,27 @@ importers:
|
|||||||
specifier: ^8.0.0
|
specifier: ^8.0.0
|
||||||
version: 8.0.0
|
version: 8.0.0
|
||||||
|
|
||||||
|
cli:
|
||||||
|
dependencies:
|
||||||
|
'@clack/prompts':
|
||||||
|
specifier: ^0.7.0
|
||||||
|
version: 0.7.0
|
||||||
|
'@pengzhanbo/utils':
|
||||||
|
specifier: ^1.1.2
|
||||||
|
version: 1.1.2
|
||||||
|
cac:
|
||||||
|
specifier: ^6.7.14
|
||||||
|
version: 6.7.14
|
||||||
|
execa:
|
||||||
|
specifier: ^9.3.1
|
||||||
|
version: 9.3.1
|
||||||
|
handlebars:
|
||||||
|
specifier: ^4.7.8
|
||||||
|
version: 4.7.8
|
||||||
|
picocolors:
|
||||||
|
specifier: ^1.0.1
|
||||||
|
version: 1.0.1
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@iconify/json':
|
'@iconify/json':
|
||||||
@ -463,6 +484,14 @@ packages:
|
|||||||
'@braintree/sanitize-url@6.0.4':
|
'@braintree/sanitize-url@6.0.4':
|
||||||
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
|
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
|
||||||
|
|
||||||
|
'@clack/core@0.3.4':
|
||||||
|
resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==}
|
||||||
|
|
||||||
|
'@clack/prompts@0.7.0':
|
||||||
|
resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==}
|
||||||
|
bundledDependencies:
|
||||||
|
- is-unicode-supported
|
||||||
|
|
||||||
'@commitlint/cli@19.4.0':
|
'@commitlint/cli@19.4.0':
|
||||||
resolution: {integrity: sha512-sJX4J9UioVwZHq7JWM9tjT5bgWYaIN3rC4FP7YwfEwBYiIO+wMyRttRvQLNkow0vCdM0D67r9NEWU0Ui03I4Eg==}
|
resolution: {integrity: sha512-sJX4J9UioVwZHq7JWM9tjT5bgWYaIN3rC4FP7YwfEwBYiIO+wMyRttRvQLNkow0vCdM0D67r9NEWU0Ui03I4Eg==}
|
||||||
engines: {node: '>=v18'}
|
engines: {node: '>=v18'}
|
||||||
@ -2965,10 +2994,6 @@ packages:
|
|||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
escalade@3.1.1:
|
|
||||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
|
|
||||||
escalade@3.1.2:
|
escalade@3.1.2:
|
||||||
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -3204,6 +3229,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==}
|
resolution: {integrity: sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==}
|
||||||
engines: {node: ^18.19.0 || >=20.5.0}
|
engines: {node: ^18.19.0 || >=20.5.0}
|
||||||
|
|
||||||
|
execa@9.3.1:
|
||||||
|
resolution: {integrity: sha512-gdhefCCNy/8tpH/2+ajP9IQc14vXchNdd0weyzSJEFURhRMGncQ+zKFxwjAufIewPEJm9BPOaJnvg2UtlH2gPQ==}
|
||||||
|
engines: {node: ^18.19.0 || >=20.5.0}
|
||||||
|
|
||||||
expand-tilde@2.0.2:
|
expand-tilde@2.0.2:
|
||||||
resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==}
|
resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -3581,6 +3610,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==}
|
resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==}
|
||||||
engines: {node: '>=18.18.0'}
|
engines: {node: '>=18.18.0'}
|
||||||
|
|
||||||
|
human-signals@8.0.0:
|
||||||
|
resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==}
|
||||||
|
engines: {node: '>=18.18.0'}
|
||||||
|
|
||||||
husky@9.1.5:
|
husky@9.1.5:
|
||||||
resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==}
|
resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@ -4629,9 +4662,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==}
|
resolution: {integrity: sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==}
|
||||||
engines: {node: '>= 0.12.0'}
|
engines: {node: '>= 0.12.0'}
|
||||||
|
|
||||||
picocolors@1.0.0:
|
|
||||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
|
||||||
|
|
||||||
picocolors@1.0.1:
|
picocolors@1.0.1:
|
||||||
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
||||||
|
|
||||||
@ -5868,6 +5898,17 @@ snapshots:
|
|||||||
|
|
||||||
'@braintree/sanitize-url@6.0.4': {}
|
'@braintree/sanitize-url@6.0.4': {}
|
||||||
|
|
||||||
|
'@clack/core@0.3.4':
|
||||||
|
dependencies:
|
||||||
|
picocolors: 1.0.1
|
||||||
|
sisteransi: 1.0.5
|
||||||
|
|
||||||
|
'@clack/prompts@0.7.0':
|
||||||
|
dependencies:
|
||||||
|
'@clack/core': 0.3.4
|
||||||
|
picocolors: 1.0.1
|
||||||
|
sisteransi: 1.0.5
|
||||||
|
|
||||||
'@commitlint/cli@19.4.0(@types/node@20.12.10)(typescript@5.5.4)':
|
'@commitlint/cli@19.4.0(@types/node@20.12.10)(typescript@5.5.4)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@commitlint/format': 19.3.0
|
'@commitlint/format': 19.3.0
|
||||||
@ -5999,7 +6040,7 @@ snapshots:
|
|||||||
'@conventional-changelog/git-client@1.0.0(conventional-commits-parser@6.0.0)':
|
'@conventional-changelog/git-client@1.0.0(conventional-commits-parser@6.0.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/semver': 7.5.8
|
'@types/semver': 7.5.8
|
||||||
semver: 7.6.0
|
semver: 7.6.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
conventional-commits-parser: 6.0.0
|
conventional-commits-parser: 6.0.0
|
||||||
|
|
||||||
@ -8496,8 +8537,6 @@ snapshots:
|
|||||||
'@esbuild/win32-ia32': 0.23.1
|
'@esbuild/win32-ia32': 0.23.1
|
||||||
'@esbuild/win32-x64': 0.23.1
|
'@esbuild/win32-x64': 0.23.1
|
||||||
|
|
||||||
escalade@3.1.1: {}
|
|
||||||
|
|
||||||
escalade@3.1.2: {}
|
escalade@3.1.2: {}
|
||||||
|
|
||||||
escape-string-regexp@1.0.5: {}
|
escape-string-regexp@1.0.5: {}
|
||||||
@ -8838,6 +8877,21 @@ snapshots:
|
|||||||
strip-final-newline: 4.0.0
|
strip-final-newline: 4.0.0
|
||||||
yoctocolors: 2.0.0
|
yoctocolors: 2.0.0
|
||||||
|
|
||||||
|
execa@9.3.1:
|
||||||
|
dependencies:
|
||||||
|
'@sindresorhus/merge-streams': 4.0.0
|
||||||
|
cross-spawn: 7.0.3
|
||||||
|
figures: 6.1.0
|
||||||
|
get-stream: 9.0.1
|
||||||
|
human-signals: 8.0.0
|
||||||
|
is-plain-obj: 4.1.0
|
||||||
|
is-stream: 4.0.1
|
||||||
|
npm-run-path: 5.3.0
|
||||||
|
pretty-ms: 9.0.0
|
||||||
|
signal-exit: 4.1.0
|
||||||
|
strip-final-newline: 4.0.0
|
||||||
|
yoctocolors: 2.0.0
|
||||||
|
|
||||||
expand-tilde@2.0.2:
|
expand-tilde@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
homedir-polyfill: 1.0.3
|
homedir-polyfill: 1.0.3
|
||||||
@ -9266,6 +9320,8 @@ snapshots:
|
|||||||
|
|
||||||
human-signals@7.0.0: {}
|
human-signals@7.0.0: {}
|
||||||
|
|
||||||
|
human-signals@8.0.0: {}
|
||||||
|
|
||||||
husky@9.1.5: {}
|
husky@9.1.5: {}
|
||||||
|
|
||||||
iconv-lite@0.4.24:
|
iconv-lite@0.4.24:
|
||||||
@ -10481,8 +10537,6 @@ snapshots:
|
|||||||
|
|
||||||
photoswipe@5.4.4: {}
|
photoswipe@5.4.4: {}
|
||||||
|
|
||||||
picocolors@1.0.0: {}
|
|
||||||
|
|
||||||
picocolors@1.0.1: {}
|
picocolors@1.0.1: {}
|
||||||
|
|
||||||
picomatch@2.3.1: {}
|
picomatch@2.3.1: {}
|
||||||
@ -10570,7 +10624,7 @@ snapshots:
|
|||||||
postcss@8.4.38:
|
postcss@8.4.38:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.7
|
nanoid: 3.3.7
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.1
|
||||||
source-map-js: 1.2.0
|
source-map-js: 1.2.0
|
||||||
|
|
||||||
postcss@8.4.40:
|
postcss@8.4.40:
|
||||||
@ -11330,8 +11384,8 @@ snapshots:
|
|||||||
update-browserslist-db@1.0.13(browserslist@4.23.0):
|
update-browserslist-db@1.0.13(browserslist@4.23.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.23.0
|
browserslist: 4.23.0
|
||||||
escalade: 3.1.1
|
escalade: 3.1.2
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.1
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
packages:
|
packages:
|
||||||
- docs
|
- docs
|
||||||
- theme
|
- theme
|
||||||
|
- cli
|
||||||
- plugins/*
|
- plugins/*
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import type { Page, Theme } from 'vuepress/core'
|
import type { Page, Theme } from 'vuepress/core'
|
||||||
|
import { sleep } from '@pengzhanbo/utils'
|
||||||
import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
|
import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
|
||||||
import { getPlugins } from './plugins/index.js'
|
import { getPlugins } from './plugins/index.js'
|
||||||
import { extendsPageData, setupPage } from './setupPages.js'
|
import { extendsPageData, setupPage } from './setupPages.js'
|
||||||
@ -47,9 +48,10 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
waitForConfigLoaded().then(({ autoFrontmatter }) => {
|
waitForConfigLoaded().then(async ({ autoFrontmatter }) => {
|
||||||
autoFrontmatter ??= pluginOptions.frontmatter
|
autoFrontmatter ??= pluginOptions.frontmatter
|
||||||
if (autoFrontmatter !== false) {
|
if (autoFrontmatter !== false) {
|
||||||
|
await sleep(100)
|
||||||
generateAutoFrontmatter(app)
|
generateAutoFrontmatter(app)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
"plugins/**/*",
|
"plugins/**/*",
|
||||||
"theme/**/*",
|
"theme/**/*",
|
||||||
"docs/.vuepress/**/*",
|
"docs/.vuepress/**/*",
|
||||||
"scripts/**/*"
|
"cli/**/*"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"**/node_modules/**",
|
"**/node_modules/**",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user