@zhin.js/cli 1.0.8 → 1.0.9
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/CHANGELOG.md +6 -0
- package/lib/commands/install.d.ts.map +1 -1
- package/lib/commands/install.js +45 -22
- package/lib/commands/install.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/install.ts +108 -82
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2FpC,eAAO,MAAM,cAAc,SAMG,CAAC;AAG/B,eAAO,MAAM,UAAU,SAMO,CAAC"}
|
package/lib/commands/install.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { logger } from '../utils/logger.js';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
3
5
|
import inquirer from 'inquirer';
|
|
4
6
|
import { execSync } from 'node:child_process';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.option('-D, --save-dev', '安装到 devDependencies', false)
|
|
10
|
-
.option('-g, --global', '全局安装', false)
|
|
11
|
-
.action(async (plugin, options) => {
|
|
7
|
+
/**
|
|
8
|
+
* 安装插件的核心逻辑
|
|
9
|
+
*/
|
|
10
|
+
async function installPluginAction(plugin, options) {
|
|
12
11
|
try {
|
|
13
12
|
let pluginToInstall = plugin;
|
|
14
13
|
// 如果没有指定插件,交互式输入
|
|
@@ -72,7 +71,14 @@ export const installCommand = new Command('install')
|
|
|
72
71
|
logger.error(`安装插件失败: ${error.message}`);
|
|
73
72
|
process.exit(1);
|
|
74
73
|
}
|
|
75
|
-
}
|
|
74
|
+
}
|
|
75
|
+
export const installCommand = new Command('install')
|
|
76
|
+
.description('安装插件(npm 包或 git 仓库)')
|
|
77
|
+
.argument('[plugin]', '插件名称或 git 地址')
|
|
78
|
+
.option('-S, --save', '安装到 dependencies(默认)', true)
|
|
79
|
+
.option('-D, --save-dev', '安装到 devDependencies', false)
|
|
80
|
+
.option('-g, --global', '全局安装', false)
|
|
81
|
+
.action(installPluginAction);
|
|
76
82
|
// 别名命令
|
|
77
83
|
export const addCommand = new Command('add')
|
|
78
84
|
.description('安装插件(install 的别名)')
|
|
@@ -80,9 +86,7 @@ export const addCommand = new Command('add')
|
|
|
80
86
|
.option('-S, --save', '安装到 dependencies(默认)', true)
|
|
81
87
|
.option('-D, --save-dev', '安装到 devDependencies', false)
|
|
82
88
|
.option('-g, --global', '全局安装', false)
|
|
83
|
-
.action(
|
|
84
|
-
await installCommand.parseAsync(['node', 'zhin', 'install', plugin || '', ...buildOptionsArray(options)], { from: 'user' });
|
|
85
|
-
});
|
|
89
|
+
.action(installPluginAction);
|
|
86
90
|
/**
|
|
87
91
|
* 检测插件类型
|
|
88
92
|
*/
|
|
@@ -108,6 +112,32 @@ function detectPluginType(plugin) {
|
|
|
108
112
|
// 默认为 npm 包
|
|
109
113
|
return 'npm';
|
|
110
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* 检查是否在 workspace root
|
|
117
|
+
*/
|
|
118
|
+
function isWorkspaceRoot() {
|
|
119
|
+
try {
|
|
120
|
+
const cwd = process.cwd();
|
|
121
|
+
const pkgJsonPath = path.join(cwd, 'package.json');
|
|
122
|
+
const workspacePath = path.join(cwd, 'pnpm-workspace.yaml');
|
|
123
|
+
// 检查是否存在 pnpm-workspace.yaml
|
|
124
|
+
if (!fs.existsSync(workspacePath)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
// 检查 package.json 是否存在
|
|
128
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const pkgJson = fs.readJsonSync(pkgJsonPath);
|
|
132
|
+
// 如果 package.json 有 workspaces 字段或者存在 pnpm-workspace.yaml,
|
|
133
|
+
// 并且 package.json 中没有明确表示这是一个子包(没有 workspace:* 依赖),
|
|
134
|
+
// 则认为当前在 workspace root
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
111
141
|
/**
|
|
112
142
|
* 构建安装命令
|
|
113
143
|
*/
|
|
@@ -120,6 +150,10 @@ function buildInstallCommand(plugin, type, options) {
|
|
|
120
150
|
if (options.global) {
|
|
121
151
|
parts.push('-g');
|
|
122
152
|
}
|
|
153
|
+
else if (isWorkspaceRoot()) {
|
|
154
|
+
// 如果在 workspace root 且不是全局安装,添加 -w 标志
|
|
155
|
+
parts.push('-w');
|
|
156
|
+
}
|
|
123
157
|
// 处理不同类型的插件
|
|
124
158
|
let packageSpec = plugin;
|
|
125
159
|
switch (type) {
|
|
@@ -195,15 +229,4 @@ function extractPluginName(plugin, type) {
|
|
|
195
229
|
return null;
|
|
196
230
|
}
|
|
197
231
|
}
|
|
198
|
-
/**
|
|
199
|
-
* 构建选项数组
|
|
200
|
-
*/
|
|
201
|
-
function buildOptionsArray(options) {
|
|
202
|
-
const arr = [];
|
|
203
|
-
if (options.saveDev)
|
|
204
|
-
arr.push('-D');
|
|
205
|
-
if (options.global)
|
|
206
|
-
arr.push('-g');
|
|
207
|
-
return arr;
|
|
208
|
-
}
|
|
209
232
|
//# sourceMappingURL=install.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/commands/install.ts
CHANGED
|
@@ -11,86 +11,91 @@ interface InstallOptions {
|
|
|
11
11
|
global?: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
validate: (input: string) => {
|
|
32
|
-
if (!input.trim()) {
|
|
33
|
-
return '插件名称或地址不能为空';
|
|
34
|
-
}
|
|
35
|
-
return true;
|
|
14
|
+
/**
|
|
15
|
+
* 安装插件的核心逻辑
|
|
16
|
+
*/
|
|
17
|
+
async function installPluginAction(plugin: string, options: InstallOptions) {
|
|
18
|
+
try {
|
|
19
|
+
let pluginToInstall = plugin;
|
|
20
|
+
|
|
21
|
+
// 如果没有指定插件,交互式输入
|
|
22
|
+
if (!pluginToInstall) {
|
|
23
|
+
const { input } = await inquirer.prompt([
|
|
24
|
+
{
|
|
25
|
+
type: 'input',
|
|
26
|
+
name: 'input',
|
|
27
|
+
message: '请输入插件名称或 git 地址:',
|
|
28
|
+
validate: (input: string) => {
|
|
29
|
+
if (!input.trim()) {
|
|
30
|
+
return '插件名称或地址不能为空';
|
|
36
31
|
}
|
|
32
|
+
return true;
|
|
37
33
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// 判断插件类型
|
|
43
|
-
const pluginType = detectPluginType(pluginToInstall);
|
|
44
|
-
|
|
45
|
-
logger.info(`检测到插件类型: ${pluginType}`);
|
|
46
|
-
logger.info(`正在安装: ${pluginToInstall}`);
|
|
47
|
-
logger.log('');
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
pluginToInstall = input;
|
|
37
|
+
}
|
|
48
38
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
// 判断插件类型
|
|
40
|
+
const pluginType = detectPluginType(pluginToInstall);
|
|
41
|
+
|
|
42
|
+
logger.info(`检测到插件类型: ${pluginType}`);
|
|
43
|
+
logger.info(`正在安装: ${pluginToInstall}`);
|
|
44
|
+
logger.log('');
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
46
|
+
// 构建安装命令
|
|
47
|
+
const installCmd = buildInstallCommand(pluginToInstall, pluginType, options);
|
|
48
|
+
|
|
49
|
+
logger.log(`执行命令: ${installCmd}`);
|
|
50
|
+
logger.log('');
|
|
61
51
|
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
// 执行安装
|
|
53
|
+
try {
|
|
54
|
+
execSync(installCmd, {
|
|
55
|
+
cwd: process.cwd(),
|
|
56
|
+
stdio: 'inherit'
|
|
57
|
+
});
|
|
64
58
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
logger.log('📝 Git 插件已安装到 node_modules/');
|
|
68
|
-
logger.log('');
|
|
69
|
-
}
|
|
59
|
+
logger.success('✓ 插件安装成功!');
|
|
60
|
+
logger.log('');
|
|
70
61
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
logger.log('');
|
|
77
|
-
logger.log(' export default defineConfig({');
|
|
78
|
-
logger.log(' plugins: [');
|
|
79
|
-
logger.log(` '${pluginName}'`);
|
|
80
|
-
logger.log(' ]');
|
|
81
|
-
logger.log(' });');
|
|
82
|
-
}
|
|
62
|
+
// 如果是 git 插件,提供额外说明
|
|
63
|
+
if (pluginType === 'git') {
|
|
64
|
+
logger.log('📝 Git 插件已安装到 node_modules/');
|
|
65
|
+
logger.log('');
|
|
66
|
+
}
|
|
83
67
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
68
|
+
// 提示如何启用插件
|
|
69
|
+
const pluginName = extractPluginName(pluginToInstall, pluginType);
|
|
70
|
+
if (pluginName) {
|
|
71
|
+
logger.log('🔌 启用插件:');
|
|
72
|
+
logger.log(`在 zhin.config.ts 中添加:`);
|
|
73
|
+
logger.log('');
|
|
74
|
+
logger.log(' export default defineConfig({');
|
|
75
|
+
logger.log(' plugins: [');
|
|
76
|
+
logger.log(` '${pluginName}'`);
|
|
77
|
+
logger.log(' ]');
|
|
78
|
+
logger.log(' });');
|
|
87
79
|
}
|
|
88
80
|
|
|
89
|
-
} catch (error
|
|
90
|
-
logger.error(
|
|
91
|
-
|
|
81
|
+
} catch (error) {
|
|
82
|
+
logger.error('安装失败');
|
|
83
|
+
throw error;
|
|
92
84
|
}
|
|
93
|
-
|
|
85
|
+
|
|
86
|
+
} catch (error: any) {
|
|
87
|
+
logger.error(`安装插件失败: ${error.message}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const installCommand = new Command('install')
|
|
93
|
+
.description('安装插件(npm 包或 git 仓库)')
|
|
94
|
+
.argument('[plugin]', '插件名称或 git 地址')
|
|
95
|
+
.option('-S, --save', '安装到 dependencies(默认)', true)
|
|
96
|
+
.option('-D, --save-dev', '安装到 devDependencies', false)
|
|
97
|
+
.option('-g, --global', '全局安装', false)
|
|
98
|
+
.action(installPluginAction);
|
|
94
99
|
|
|
95
100
|
// 别名命令
|
|
96
101
|
export const addCommand = new Command('add')
|
|
@@ -99,9 +104,7 @@ export const addCommand = new Command('add')
|
|
|
99
104
|
.option('-S, --save', '安装到 dependencies(默认)', true)
|
|
100
105
|
.option('-D, --save-dev', '安装到 devDependencies', false)
|
|
101
106
|
.option('-g, --global', '全局安装', false)
|
|
102
|
-
.action(
|
|
103
|
-
await installCommand.parseAsync(['node', 'zhin', 'install', plugin || '', ...buildOptionsArray(options)], { from: 'user' });
|
|
104
|
-
});
|
|
107
|
+
.action(installPluginAction);
|
|
105
108
|
|
|
106
109
|
/**
|
|
107
110
|
* 检测插件类型
|
|
@@ -129,6 +132,36 @@ function detectPluginType(plugin: string): 'npm' | 'git' | 'github' | 'gitlab' |
|
|
|
129
132
|
return 'npm';
|
|
130
133
|
}
|
|
131
134
|
|
|
135
|
+
/**
|
|
136
|
+
* 检查是否在 workspace root
|
|
137
|
+
*/
|
|
138
|
+
function isWorkspaceRoot(): boolean {
|
|
139
|
+
try {
|
|
140
|
+
const cwd = process.cwd();
|
|
141
|
+
const pkgJsonPath = path.join(cwd, 'package.json');
|
|
142
|
+
const workspacePath = path.join(cwd, 'pnpm-workspace.yaml');
|
|
143
|
+
|
|
144
|
+
// 检查是否存在 pnpm-workspace.yaml
|
|
145
|
+
if (!fs.existsSync(workspacePath)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 检查 package.json 是否存在
|
|
150
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const pkgJson = fs.readJsonSync(pkgJsonPath);
|
|
155
|
+
|
|
156
|
+
// 如果 package.json 有 workspaces 字段或者存在 pnpm-workspace.yaml,
|
|
157
|
+
// 并且 package.json 中没有明确表示这是一个子包(没有 workspace:* 依赖),
|
|
158
|
+
// 则认为当前在 workspace root
|
|
159
|
+
return true;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
132
165
|
/**
|
|
133
166
|
* 构建安装命令
|
|
134
167
|
*/
|
|
@@ -142,6 +175,9 @@ function buildInstallCommand(plugin: string, type: string, options: InstallOptio
|
|
|
142
175
|
|
|
143
176
|
if (options.global) {
|
|
144
177
|
parts.push('-g');
|
|
178
|
+
} else if (isWorkspaceRoot()) {
|
|
179
|
+
// 如果在 workspace root 且不是全局安装,添加 -w 标志
|
|
180
|
+
parts.push('-w');
|
|
145
181
|
}
|
|
146
182
|
|
|
147
183
|
// 处理不同类型的插件
|
|
@@ -230,13 +266,3 @@ function extractPluginName(plugin: string, type: string): string | null {
|
|
|
230
266
|
}
|
|
231
267
|
}
|
|
232
268
|
|
|
233
|
-
/**
|
|
234
|
-
* 构建选项数组
|
|
235
|
-
*/
|
|
236
|
-
function buildOptionsArray(options: InstallOptions): string[] {
|
|
237
|
-
const arr: string[] = [];
|
|
238
|
-
if (options.saveDev) arr.push('-D');
|
|
239
|
-
if (options.global) arr.push('-g');
|
|
240
|
-
return arr;
|
|
241
|
-
}
|
|
242
|
-
|