@lumiflora/fsdk 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -96
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +20 -15
- package/dist/index.js +4 -4
- package/package.json +6 -3
- package/scripts/postinstall.js +271 -0
package/README.md
CHANGED
|
@@ -1,122 +1,107 @@
|
|
|
1
|
-
# @lumiflora/fsdk
|
|
2
|
-
|
|
3
1
|
Vue 3 前端项目脚手架 CLI 工具,快速创建包含最佳技术栈的项目骨架。
|
|
4
2
|
|
|
5
3
|
## 安装
|
|
6
4
|
|
|
7
5
|
```bash
|
|
6
|
+
# 方式一:本地开发模式
|
|
7
|
+
cd /path/to/fsdk
|
|
8
|
+
pnpm install
|
|
9
|
+
pnpm dev
|
|
10
|
+
|
|
11
|
+
# 方式二:全局安装(发布后)
|
|
12
|
+
pnpm build
|
|
8
13
|
npm install -g @lumiflora/fsdk
|
|
9
14
|
```
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## 使用命令
|
|
12
17
|
|
|
13
18
|
```bash
|
|
14
|
-
#
|
|
15
|
-
fsdk create
|
|
16
|
-
|
|
17
|
-
# 指定参数创建
|
|
19
|
+
# 创建新项目
|
|
20
|
+
fsdk create my-project # 交互式创建
|
|
18
21
|
fsdk create my-project --template full --package-manager pnpm
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## 命令
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
# 添加页面
|
|
24
|
+
fsdk add-page --page-name user --router-path /user
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
fsdk
|
|
27
|
-
|
|
28
|
-
Options:
|
|
29
|
-
--template <name> 模板名称 (base|full) [default: base]
|
|
30
|
-
--package-manager <pm> 包管理器 (npm|pnpm|yarn|bun) [default: pnpm]
|
|
31
|
-
--eslint 启用 ESLint [default: true]
|
|
32
|
-
--no-git 跳过 git 初始化
|
|
33
|
-
--no-install 跳过依赖安装
|
|
34
|
-
```
|
|
26
|
+
# 添加组件
|
|
27
|
+
fsdk add-component --name Header --type common
|
|
35
28
|
|
|
36
|
-
|
|
29
|
+
# 添加 Store
|
|
30
|
+
fsdk add-store --name user
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
fsdk
|
|
32
|
+
# 校验配置和模板
|
|
33
|
+
fsdk validate
|
|
40
34
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
--router-path <path> 路由路径
|
|
44
|
-
```
|
|
35
|
+
# 预览模板
|
|
36
|
+
fsdk preview --port 3000
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
# 生成并安装补全脚本
|
|
39
|
+
fsdk completion bash # 生成 bash 补全脚本
|
|
40
|
+
fsdk completion zsh # 生成 zsh 补全脚本
|
|
41
|
+
fsdk completion fish # 生成 fish 补全脚本
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
fsdk
|
|
43
|
+
# 自动安装到 shell 配置文件(推荐)
|
|
44
|
+
fsdk completion bash --install
|
|
45
|
+
fsdk completion zsh --install
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
--dir <dir> 子目录
|
|
47
|
+
# 查看帮助
|
|
48
|
+
fsdk --help
|
|
49
|
+
fsdk create --help
|
|
55
50
|
```
|
|
56
51
|
|
|
57
|
-
|
|
52
|
+
## Shell 补全
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
fsdk add-store [options]
|
|
61
|
-
|
|
62
|
-
Options:
|
|
63
|
-
--name <name> Store 名称
|
|
64
|
-
--type <type> Store 类型 (pinia|redux) [default: pinia]
|
|
65
|
-
```
|
|
54
|
+
fsdk 支持 bash、zsh 和 fish 的命令行补全。安装后,输入 `fsdk ` 后按 Tab 键可自动补全命令和选项。
|
|
66
55
|
|
|
67
|
-
###
|
|
56
|
+
### Bash(Linux / macOS)
|
|
68
57
|
|
|
69
58
|
```bash
|
|
70
|
-
|
|
59
|
+
# 方式一:自动安装(推荐)
|
|
60
|
+
fsdk completion bash --install
|
|
61
|
+
source ~/.bashrc
|
|
71
62
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
# 方式二:手动安装
|
|
64
|
+
fsdk completion bash
|
|
65
|
+
echo 'source ~/.fsdk-completion.bash' >> ~/.bashrc
|
|
66
|
+
source ~/.bashrc
|
|
76
67
|
```
|
|
77
68
|
|
|
78
|
-
###
|
|
69
|
+
### Zsh(macOS 默认)
|
|
79
70
|
|
|
80
71
|
```bash
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
72
|
+
# 方式一:自动安装(推荐)
|
|
73
|
+
fsdk completion zsh --install
|
|
74
|
+
source ~/.zshrc
|
|
75
|
+
|
|
76
|
+
# 方式二:手动安装
|
|
77
|
+
fsdk completion zsh
|
|
78
|
+
# 添加以下内容到 ~/.zshrc:
|
|
79
|
+
# fpath=("$HOME/.zsh/completion" $fpath)
|
|
80
|
+
# autoload -U compinit && compinit
|
|
81
|
+
source ~/.zshrc
|
|
88
82
|
```
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
fsdk
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
--template <name> 模板名称
|
|
97
|
-
--force 强制同步
|
|
98
|
-
```
|
|
84
|
+
> **注意**:如果使用 Oh My Zsh,可以将补全文件复制到 `~/.oh-my-zsh/completions/` 目录:
|
|
85
|
+
> ```bash
|
|
86
|
+
> mkdir -p ~/.oh-my-zsh/completions
|
|
87
|
+
> fsdk completion zsh --output ~/.oh-my-zsh/completions/_fsdk
|
|
88
|
+
> exec zsh
|
|
89
|
+
> ```
|
|
99
90
|
|
|
100
|
-
###
|
|
91
|
+
### Fish
|
|
101
92
|
|
|
102
93
|
```bash
|
|
103
|
-
fsdk completion
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
--install 自动安装到 shell 配置
|
|
107
|
-
|
|
108
|
-
# 示例
|
|
109
|
-
fsdk completion --install # 自动配置当前 shell
|
|
110
|
-
fsdk completion zsh --install
|
|
111
|
-
fsdk completion bash --install
|
|
94
|
+
fsdk completion fish
|
|
95
|
+
# 补全文件自动生成到 ~/.config/fish/completions/fsdk.fish
|
|
96
|
+
# 重启 fish 或打开新终端即可生效
|
|
112
97
|
```
|
|
113
98
|
|
|
114
99
|
## 模板
|
|
115
100
|
|
|
116
101
|
| 模板 | 说明 |
|
|
117
102
|
|------|------|
|
|
103
|
+
| `full` | Vue 3.5 + Vite 6 + Element Plus + Pinia + Vue Router + SCSS |
|
|
118
104
|
| `base` | Vue 3.5 + Vite 6 基础版 |
|
|
119
|
-
| `full` | Vue 3.5 + Vite 6 + Element Plus + Pinia + Vue Router + SCSS + ESLint |
|
|
120
105
|
|
|
121
106
|
## 技术栈
|
|
122
107
|
|
|
@@ -129,22 +114,3 @@ fsdk completion bash --install
|
|
|
129
114
|
| Vite | ^6.0.0 | 构建工具 |
|
|
130
115
|
| TypeScript | ~5.6.0 | 类型系统 |
|
|
131
116
|
| ESLint | ^9.0.0 | 代码检查 |
|
|
132
|
-
|
|
133
|
-
## 开发
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
# 本地开发
|
|
137
|
-
cd packages/cli
|
|
138
|
-
pnpm install
|
|
139
|
-
pnpm dev
|
|
140
|
-
|
|
141
|
-
# 构建
|
|
142
|
-
pnpm build
|
|
143
|
-
|
|
144
|
-
# 类型检查
|
|
145
|
-
pnpm typecheck
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## License
|
|
149
|
-
|
|
150
|
-
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA8KD,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCvF"}
|
|
@@ -45,14 +45,11 @@ _fsdk_completion() {
|
|
|
45
45
|
|
|
46
46
|
complete -F _fsdk_completion fsdk
|
|
47
47
|
`;
|
|
48
|
-
const ZSH_COMPLETION = `#fsdk
|
|
49
|
-
autoload -Uz compinit
|
|
50
|
-
compinit 2>/dev/null
|
|
48
|
+
const ZSH_COMPLETION = `#compdef fsdk
|
|
51
49
|
|
|
52
|
-
# Define the completion function
|
|
53
50
|
_fsdk() {
|
|
54
|
-
local -a
|
|
55
|
-
|
|
51
|
+
local -a commands
|
|
52
|
+
commands=(
|
|
56
53
|
'create:Create a new application'
|
|
57
54
|
'add-page:Add a new page'
|
|
58
55
|
'add-component:Add a new component'
|
|
@@ -70,7 +67,7 @@ _fsdk() {
|
|
|
70
67
|
|
|
71
68
|
case "$state" in
|
|
72
69
|
command)
|
|
73
|
-
_describe 'command'
|
|
70
|
+
_describe 'command' commands
|
|
74
71
|
;;
|
|
75
72
|
args)
|
|
76
73
|
case $words[1] in
|
|
@@ -126,9 +123,6 @@ _fsdk() {
|
|
|
126
123
|
;;
|
|
127
124
|
esac
|
|
128
125
|
}
|
|
129
|
-
|
|
130
|
-
# Register the completion function for fsdk command
|
|
131
|
-
compdef _fsdk fsdk
|
|
132
126
|
`;
|
|
133
127
|
const FISH_COMPLETION = `# fish completion for fsdk
|
|
134
128
|
|
|
@@ -192,7 +186,13 @@ export async function generateCompletion(options = {}) {
|
|
|
192
186
|
await installToShellRc(shell, outputPath);
|
|
193
187
|
}
|
|
194
188
|
else if (!install) {
|
|
195
|
-
if (shell
|
|
189
|
+
if (shell === 'zsh') {
|
|
190
|
+
const completionDir = path.dirname(outputPath);
|
|
191
|
+
logger.info(`Add the following lines to your ~/.zshrc:`);
|
|
192
|
+
logger.info(` fpath=("${completionDir}" $fpath)`);
|
|
193
|
+
logger.info(` autoload -U compinit && compinit`);
|
|
194
|
+
}
|
|
195
|
+
else if (shell !== 'fish') {
|
|
196
196
|
logger.info(`Add the following line to your shell configuration:`);
|
|
197
197
|
logger.info(` source ${outputPath}`);
|
|
198
198
|
}
|
|
@@ -210,12 +210,16 @@ export async function generateCompletion(options = {}) {
|
|
|
210
210
|
async function installToShellRc(shell, completionPath) {
|
|
211
211
|
const home = process.env.HOME || '';
|
|
212
212
|
let rcFile = '';
|
|
213
|
-
let sourceLine =
|
|
213
|
+
let sourceLine = '';
|
|
214
214
|
if (shell === 'bash') {
|
|
215
215
|
rcFile = path.resolve(home, '.bashrc');
|
|
216
|
+
sourceLine = `source ${completionPath}`;
|
|
216
217
|
}
|
|
217
218
|
else if (shell === 'zsh') {
|
|
218
219
|
rcFile = path.resolve(home, '.zshrc');
|
|
220
|
+
// For zsh, add to fpath and compinit
|
|
221
|
+
const completionDir = path.dirname(completionPath);
|
|
222
|
+
sourceLine = `# Add fsdk completion to fpath\nfpath=("${completionDir}" $fpath)\nautoload -U compinit && compinit`;
|
|
219
223
|
}
|
|
220
224
|
else {
|
|
221
225
|
logger.warning(`--install is not supported for fish shell yet`);
|
|
@@ -226,12 +230,12 @@ async function installToShellRc(shell, completionPath) {
|
|
|
226
230
|
if (await fs.pathExists(rcFile)) {
|
|
227
231
|
rcContent = await fs.readFile(rcFile, 'utf-8');
|
|
228
232
|
}
|
|
229
|
-
const pattern = shell === 'bash' ? /\.fsdk-completion/ : 'fsdk
|
|
233
|
+
const pattern = shell === 'bash' ? /\.fsdk-completion/ : 'fsdk completion';
|
|
230
234
|
if (rcContent.includes(pattern)) {
|
|
231
235
|
logger.info(`Completion already installed in ${rcFile}`);
|
|
232
236
|
return;
|
|
233
237
|
}
|
|
234
|
-
await fs.appendFile(rcFile, `\n# fsdk completion\n${sourceLine}\n`);
|
|
238
|
+
await fs.appendFile(rcFile, `\n# ${shell} fsdk completion\n${sourceLine}\n`);
|
|
235
239
|
logger.success(`Completion installed to ${rcFile}`);
|
|
236
240
|
logger.info(`Run "source ${rcFile}" or restart your shell to apply`);
|
|
237
241
|
}
|
|
@@ -254,7 +258,8 @@ function getDefaultOutputPath(shell) {
|
|
|
254
258
|
case 'bash':
|
|
255
259
|
return path.resolve(home, '.fsdk-completion.bash');
|
|
256
260
|
case 'zsh':
|
|
257
|
-
|
|
261
|
+
// zsh completion must be in fpath directory with _command name
|
|
262
|
+
return path.resolve(home, '.zsh', 'completion', '_fsdk');
|
|
258
263
|
case 'fish':
|
|
259
264
|
return path.resolve(home, '.config', 'fish', 'completions', 'fsdk.fish');
|
|
260
265
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import
|
|
4
|
+
import fs from 'fs';
|
|
5
5
|
import cac from 'cac';
|
|
6
6
|
import { logger, enableDebugMode, resolveCwd } from './utils/index.js';
|
|
7
7
|
import { configLoader, pluginSystem } from './core/index.js';
|
|
@@ -12,9 +12,9 @@ import { createApp, addPage, addComponent, addStore, syncTemplate, validate, pre
|
|
|
12
12
|
const cliEntryPath = fileURLToPath(import.meta.url);
|
|
13
13
|
const cliRoot = path.dirname(path.dirname(cliEntryPath));
|
|
14
14
|
global.__cliRoot = cliRoot;
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
const pkg =
|
|
15
|
+
// Read package.json to get version
|
|
16
|
+
const pkgPath = path.join(cliRoot, 'package.json');
|
|
17
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
18
18
|
const cli = cac('fsdk');
|
|
19
19
|
cli
|
|
20
20
|
.version(pkg.version)
|
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumiflora/fsdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"fsdk": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist"
|
|
10
|
+
"dist",
|
|
11
|
+
"scripts/postinstall.js",
|
|
12
|
+
"README.md"
|
|
11
13
|
],
|
|
12
14
|
"scripts": {
|
|
13
15
|
"dev": "tsx src/index.ts",
|
|
14
16
|
"build": "tsc && node scripts/fix-bin.js",
|
|
15
|
-
"typecheck": "tsc --noEmit"
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"postinstall": "node scripts/postinstall.js"
|
|
16
19
|
},
|
|
17
20
|
"dependencies": {
|
|
18
21
|
"cac": "^6.7.14",
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
const detectShell = () => {
|
|
8
|
+
const shell = process.env.SHELL || '';
|
|
9
|
+
if (shell.includes('zsh')) return 'zsh';
|
|
10
|
+
if (shell.includes('fish')) return 'fish';
|
|
11
|
+
return 'bash';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const generateCompletion = (shell) => {
|
|
15
|
+
if (shell === 'bash') {
|
|
16
|
+
return `#!/bin/bash
|
|
17
|
+
# fsdk bash completion
|
|
18
|
+
|
|
19
|
+
_fsdk_completion() {
|
|
20
|
+
local cur prev opts
|
|
21
|
+
COMPREPLY=()
|
|
22
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
23
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
24
|
+
opts="create add-page add-component add-store sync-template validate preview completion"
|
|
25
|
+
case "\${prev}" in
|
|
26
|
+
create)
|
|
27
|
+
opts="--template --package-manager --eslint --no-git --no-install"
|
|
28
|
+
;;
|
|
29
|
+
add-page)
|
|
30
|
+
opts="--router-path --page-name"
|
|
31
|
+
;;
|
|
32
|
+
add-component)
|
|
33
|
+
opts="--type --name --dir"
|
|
34
|
+
;;
|
|
35
|
+
add-store)
|
|
36
|
+
opts="--type --name"
|
|
37
|
+
;;
|
|
38
|
+
sync-template)
|
|
39
|
+
opts="--template --force"
|
|
40
|
+
;;
|
|
41
|
+
validate)
|
|
42
|
+
opts="--config --templates --strict"
|
|
43
|
+
;;
|
|
44
|
+
preview)
|
|
45
|
+
opts="--port --host --open --template"
|
|
46
|
+
;;
|
|
47
|
+
completion)
|
|
48
|
+
opts="bash zsh fish"
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
51
|
+
COMPREPLY=($(compgen -W "\${opts}" -- "\${cur}"))
|
|
52
|
+
return 0
|
|
53
|
+
}
|
|
54
|
+
complete -F _fsdk_completion fsdk`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (shell === 'zsh') {
|
|
58
|
+
return `#compdef fsdk
|
|
59
|
+
|
|
60
|
+
_fsdk() {
|
|
61
|
+
local -a commands
|
|
62
|
+
commands=(
|
|
63
|
+
'create:Create a new application'
|
|
64
|
+
'add-page:Add a new page'
|
|
65
|
+
'add-component:Add a new component'
|
|
66
|
+
'add-store:Add a new store'
|
|
67
|
+
'sync-template:Sync template files'
|
|
68
|
+
'validate:Validate configuration and templates'
|
|
69
|
+
'preview:Preview template'
|
|
70
|
+
'completion:Generate shell completion script'
|
|
71
|
+
)
|
|
72
|
+
_arguments -C \
|
|
73
|
+
'1: :->command' \
|
|
74
|
+
'2: :->args' \
|
|
75
|
+
'*: :->rest'
|
|
76
|
+
case "$state" in
|
|
77
|
+
command)
|
|
78
|
+
_describe 'command' commands
|
|
79
|
+
;;
|
|
80
|
+
args)
|
|
81
|
+
case $words[1] in
|
|
82
|
+
create)
|
|
83
|
+
_arguments -s \
|
|
84
|
+
'--template[Template name]' \
|
|
85
|
+
'--package-manager[Package manager: npm|pnpm|yarn|bun]' \
|
|
86
|
+
'--eslint[Enable ESLint]' \
|
|
87
|
+
'--no-git[Skip git initialization]' \
|
|
88
|
+
'--no-install[Skip dependency installation]'
|
|
89
|
+
;;
|
|
90
|
+
add-page)
|
|
91
|
+
_arguments -s \
|
|
92
|
+
'--router-path[Router path]' \
|
|
93
|
+
'--page-name[Page name]'
|
|
94
|
+
;;
|
|
95
|
+
add-component)
|
|
96
|
+
_arguments -s \
|
|
97
|
+
'--type[Component type: page|common|business]' \
|
|
98
|
+
'--name[Component name]' \
|
|
99
|
+
'--dir[Subdirectory]'
|
|
100
|
+
;;
|
|
101
|
+
add-store)
|
|
102
|
+
_arguments -s \
|
|
103
|
+
'--type[Store type: pinia|redux]' \
|
|
104
|
+
'--name[Store name]'
|
|
105
|
+
;;
|
|
106
|
+
sync-template)
|
|
107
|
+
_arguments -s \
|
|
108
|
+
'--template[Template name]' \
|
|
109
|
+
'--force[Force sync]'
|
|
110
|
+
;;
|
|
111
|
+
validate)
|
|
112
|
+
_arguments -s \
|
|
113
|
+
'--config[Validate config only]' \
|
|
114
|
+
'--templates[Validate templates only]' \
|
|
115
|
+
'--strict[Strict validation]'
|
|
116
|
+
;;
|
|
117
|
+
preview)
|
|
118
|
+
_arguments -s \
|
|
119
|
+
'--port[Port number]' \
|
|
120
|
+
'--host[Host address]' \
|
|
121
|
+
'--open[Open browser]' \
|
|
122
|
+
'--template[Template name]'
|
|
123
|
+
;;
|
|
124
|
+
completion)
|
|
125
|
+
_arguments -s \
|
|
126
|
+
'bash:Generate bash completion' \
|
|
127
|
+
'zsh:Generate zsh completion' \
|
|
128
|
+
'fish:Generate fish completion'
|
|
129
|
+
;;
|
|
130
|
+
esac
|
|
131
|
+
;;
|
|
132
|
+
esac
|
|
133
|
+
}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (shell === 'fish') {
|
|
137
|
+
return `# fish completion for fsdk
|
|
138
|
+
|
|
139
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'create' -d 'Create a new application'
|
|
140
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'add-page' -d 'Add a new page'
|
|
141
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'add-component' -d 'Add a new component'
|
|
142
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'add-store' -d 'Add a new store'
|
|
143
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'sync-template' -d 'Sync template files'
|
|
144
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'validate' -d 'Validate configuration and templates'
|
|
145
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'preview' -d 'Preview template'
|
|
146
|
+
complete -c fsdk -n '__fish_use_subcommand' -a 'completion' -d 'Generate shell completion script'
|
|
147
|
+
|
|
148
|
+
complete -c fsdk -n '__fish_seen_subcommand_from create' -l template -d 'Template name'
|
|
149
|
+
complete -c fsdk -n '__fish_seen_subcommand_from create' -l package-manager -d 'Package manager' -a 'npm pnpm yarn bun'
|
|
150
|
+
complete -c fsdk -n '__fish_seen_subcommand_from create' -l eslint -d 'Enable ESLint'
|
|
151
|
+
complete -c fsdk -n '__fish_seen_subcommand_from create' -l no-git -d 'Skip git initialization'
|
|
152
|
+
complete -c fsdk -n '__fish_seen_subcommand_from create' -l no-install -d 'Skip dependency installation'
|
|
153
|
+
|
|
154
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-page' -l router-path -d 'Router path'
|
|
155
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-page' -l page-name -d 'Page name'
|
|
156
|
+
|
|
157
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-component' -l type -d 'Component type' -a 'page common business'
|
|
158
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-component' -l name -d 'Component name'
|
|
159
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-component' -l dir -d 'Subdirectory'
|
|
160
|
+
|
|
161
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-store' -l type -d 'Store type' -a 'pinia redux'
|
|
162
|
+
complete -c fsdk -n '__fish_seen_subcommand_from add-store' -l name -d 'Store name'
|
|
163
|
+
|
|
164
|
+
complete -c fsdk -n '__fish_seen_subcommand_from sync-template' -l template -d 'Template name'
|
|
165
|
+
complete -c fsdk -n '__fish_seen_subcommand_from sync-template' -l force -d 'Force sync'
|
|
166
|
+
|
|
167
|
+
complete -c fsdk -n '__fish_seen_subcommand_from validate' -l config -d 'Validate config only'
|
|
168
|
+
complete -c fsdk -n '__fish_seen_subcommand_from validate' -l templates -d 'Validate templates only'
|
|
169
|
+
complete -c fsdk -n '__fish_seen_subcommand_from validate' -l strict -d 'Strict validation'
|
|
170
|
+
|
|
171
|
+
complete -c fsdk -n '__fish_seen_subcommand_from preview' -l port -d 'Port number'
|
|
172
|
+
complete -c fsdk -n '__fish_seen_subcommand_from preview' -l host -d 'Host address'
|
|
173
|
+
complete -c fsdk -n '__fish_seen_subcommand_from preview' -l open -d 'Open browser'
|
|
174
|
+
complete -c fsdk -n '__fish_seen_subcommand_from preview' -l template -d 'Template name'`;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const installCompletion = () => {
|
|
179
|
+
const shell = detectShell();
|
|
180
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
181
|
+
let rcFile = '';
|
|
182
|
+
let completionFile = '';
|
|
183
|
+
let configLine = '';
|
|
184
|
+
|
|
185
|
+
if (shell === 'bash') {
|
|
186
|
+
rcFile = path.resolve(home, '.bashrc');
|
|
187
|
+
completionFile = path.resolve(home, '.fsdk-completion.bash');
|
|
188
|
+
configLine = 'source ~/.fsdk-completion.bash';
|
|
189
|
+
} else if (shell === 'zsh') {
|
|
190
|
+
rcFile = path.resolve(home, '.zshrc');
|
|
191
|
+
completionFile = path.resolve(home, '.zsh', 'completion', '_fsdk');
|
|
192
|
+
configLine = 'fpath=("~/.zsh/completion" $fpath)';
|
|
193
|
+
} else if (shell === 'fish') {
|
|
194
|
+
rcFile = path.resolve(home, '.config', 'fish', 'config.fish');
|
|
195
|
+
completionFile = path.resolve(home, '.config', 'fish', 'completions', 'fsdk.fish');
|
|
196
|
+
configLine = '';
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// 生成补全文件
|
|
200
|
+
try {
|
|
201
|
+
const content = generateCompletion(shell);
|
|
202
|
+
writeFileSync(completionFile, content, 'utf-8');
|
|
203
|
+
if (shell === 'bash') {
|
|
204
|
+
import('fs').then(fs => { fs.chmodSync(completionFile, 0o755); });
|
|
205
|
+
}
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.error('Failed to write completion file:', err.message);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Fish 不需要额外配置
|
|
212
|
+
if (shell === 'fish') {
|
|
213
|
+
console.log('✓ fsdk completion installed to', completionFile);
|
|
214
|
+
console.log(' Restart your fish shell or open a new terminal to apply');
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 读取现有配置
|
|
219
|
+
let rcContent = '';
|
|
220
|
+
if (existsSync(rcFile)) {
|
|
221
|
+
rcContent = readFileSync(rcFile, 'utf-8');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 先检测原始内容是否已有有效配置
|
|
225
|
+
const alreadyHasValidConfig = (shell === 'bash' && rcContent.includes('source ~/.fsdk-completion.bash')) ||
|
|
226
|
+
(shell === 'zsh' && /fpath=.*\.zsh\/completion/.test(rcContent));
|
|
227
|
+
|
|
228
|
+
if (alreadyHasValidConfig) {
|
|
229
|
+
console.log('✓ fsdk completion already configured in', rcFile);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 清理旧的 fsdk completion 配置
|
|
234
|
+
const lines = rcContent.split('\n');
|
|
235
|
+
const newLines = [];
|
|
236
|
+
let skipLines = false;
|
|
237
|
+
for (const line of lines) {
|
|
238
|
+
if (line.includes('# fsdk completion') || line.includes('# zsh fsdk completion') || line.includes('# bash fsdk completion')) {
|
|
239
|
+
skipLines = true;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (skipLines) {
|
|
243
|
+
if (line.trim() === '') {
|
|
244
|
+
skipLines = false;
|
|
245
|
+
}
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
newLines.push(line);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const newContent = newLines.join('\n');
|
|
252
|
+
|
|
253
|
+
// 检查是否已有 compinit(使用原始 rcContent)
|
|
254
|
+
const alreadyHasCompinit = rcContent.includes('autoload -U compinit');
|
|
255
|
+
|
|
256
|
+
// 决定添加什么配置
|
|
257
|
+
let configToAdd = '';
|
|
258
|
+
if (shell === 'zsh' && alreadyHasCompinit) {
|
|
259
|
+
// 已有 compinit,只添加 fpath
|
|
260
|
+
configToAdd = '# zsh fsdk completion\n' + configLine + '\n';
|
|
261
|
+
} else if (configLine) {
|
|
262
|
+
configToAdd = `# ${shell} fsdk completion\n${configLine}\n`;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// 写入新配置
|
|
266
|
+
writeFileSync(rcFile, (newContent ? newContent + '\n' : '') + configToAdd, 'utf-8');
|
|
267
|
+
console.log('✓ fsdk completion installed to', rcFile);
|
|
268
|
+
console.log(' Run "source', rcFile, '" or restart your shell to apply');
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
installCompletion();
|