coda-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +9 -0
- package/README.md +76 -0
- package/package.json +45 -0
- package/src/bin/index.js +4 -0
- package/src/bin/index.ts +2 -0
- package/src/cli-api/cmd.js +86 -0
- package/src/cli-api/cmd.ts +104 -0
- package/src/cli-api/data.js +135 -0
- package/src/cli-api/data.ts +146 -0
- package/src/cli-api/date.js +23 -0
- package/src/cli-api/date.ts +22 -0
- package/src/cli-api/event.js +6 -0
- package/src/cli-api/event.ts +6 -0
- package/src/cli-api/fs.js +236 -0
- package/src/cli-api/fs.ts +213 -0
- package/src/cli-api/git.js +328 -0
- package/src/cli-api/git.ts +397 -0
- package/src/cli-api/index.js +22 -0
- package/src/cli-api/index.ts +10 -0
- package/src/cli-api/packages.js +69 -0
- package/src/cli-api/packages.ts +73 -0
- package/src/cli-api/request.js +55 -0
- package/src/cli-api/request.ts +67 -0
- package/src/cli-core/cli.js +135 -0
- package/src/cli-core/cli.ts +145 -0
- package/src/cli-core/index.js +51 -0
- package/src/cli-core/index.ts +58 -0
- package/src/cli-core/queue.js +60 -0
- package/src/cli-core/queue.ts +68 -0
- package/src/cli-core/watcher.js +31 -0
- package/src/cli-core/watcher.ts +31 -0
- package/src/config/commands.json +20 -0
- package/src/generator/cmd-create/index.js +170 -0
- package/src/generator/cmd-create/index.ts +164 -0
- package/src/generator/cmd-create/tmpl/index.js +39 -0
- package/src/generator/cmd-create/tmpl/index.ts +46 -0
- package/src/generator/cmd-delete/index.js +129 -0
- package/src/generator/cmd-delete/index.ts +122 -0
- package/src/generator/startup.js +253 -0
- package/src/generator/startup.ts +225 -0
- package/src/service/lang.js +73 -0
- package/src/service/lang.ts +71 -0
- package/src/service/util.js +120 -0
- package/src/service/util.ts +91 -0
- package/src/types/index.js +2 -0
- package/src/types/index.ts +29 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import {fork} from 'child_process';
|
|
3
|
+
import {CLI, ChildProcess} from '@/cli-core';
|
|
4
|
+
import {packages} from '@/cli-api';
|
|
5
|
+
import {Lang} from '@/service/lang';
|
|
6
|
+
import CLIConfigData from '@/config/commands.json';
|
|
7
|
+
import {CLIConfigType, CommandItem, LikeCommandResult} from '@/types';
|
|
8
|
+
|
|
9
|
+
const CLIConfig: CLIConfigType = CLIConfigData as CLIConfigType;
|
|
10
|
+
|
|
11
|
+
CLI.loading.start(Lang.BUILDIN.CORE_STRTUP_READY);
|
|
12
|
+
|
|
13
|
+
// 判断是否为 VS Code 本地调试环境
|
|
14
|
+
const isDebug = process.env.DEBUG_ENV === 'true';
|
|
15
|
+
const globalNpmRoot = ChildProcess.syncCmdExecuteResult('npm root -g');
|
|
16
|
+
|
|
17
|
+
// 如果是本地调试,根目录指向当前项目根目录;否则指向全局包目录
|
|
18
|
+
let currentProjectRoot = isDebug
|
|
19
|
+
? path.resolve(__dirname, '../../') // 从 src/bin 往上两级到达项目根目录
|
|
20
|
+
: path.join(globalNpmRoot, CLIConfig.packageName);
|
|
21
|
+
|
|
22
|
+
let npmRootPath = isDebug ? currentProjectRoot : globalNpmRoot;
|
|
23
|
+
let cliRoootPath = currentProjectRoot;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 获取 CLI 配置对象
|
|
27
|
+
*/
|
|
28
|
+
function getCLIConfig(): CLIConfigType {
|
|
29
|
+
return {
|
|
30
|
+
packageName: CLIConfigData.packageName,
|
|
31
|
+
wordsLen: CLIConfigData.wordsLen,
|
|
32
|
+
name: CLIConfigData.name,
|
|
33
|
+
commands: CLIConfigData.commands as CommandItem[],
|
|
34
|
+
inAnyPath: CLIConfigData.inAnyPath,
|
|
35
|
+
buildIn: CLIConfigData.buildIn,
|
|
36
|
+
store: CLIConfigData.store,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 显示帮助信息
|
|
42
|
+
* @param name CLI 名称
|
|
43
|
+
* @param commands 命令列表
|
|
44
|
+
*/
|
|
45
|
+
function showHelp(name: string, commands: CommandItem[]): void {
|
|
46
|
+
let helpList: string[] = [];
|
|
47
|
+
commands.forEach(cmd => {
|
|
48
|
+
helpList.push(`${name} ${cmd.command} : ${cmd.description}`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
helpList.push(name + ' ' + Lang.HELP_MESSAGE);
|
|
52
|
+
const helps = `Usage: ${name} [command] \nCommands:\n\t${helpList.join('\n\t')}`;
|
|
53
|
+
CLI.loading.succeed(Lang.BUILDIN.CLI_HAS_READY);
|
|
54
|
+
CLI.log.info(helps);
|
|
55
|
+
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 检查是否存在相似或匹配的命令
|
|
61
|
+
* @param input 输入的命令
|
|
62
|
+
* @param commands 命令列表
|
|
63
|
+
*/
|
|
64
|
+
function hasLikeCommand(input: string, commands: CommandItem[]): LikeCommandResult {
|
|
65
|
+
let exsited = false;
|
|
66
|
+
let likeList = commands.filter(cmd => {
|
|
67
|
+
if (cmd['command'] === input) {
|
|
68
|
+
exsited = true;
|
|
69
|
+
return false;
|
|
70
|
+
} else {
|
|
71
|
+
let temp = input.split(' ');
|
|
72
|
+
if (cmd['command'].includes(temp[0])) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
exsited,
|
|
81
|
+
likeList,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 验证命令合法性
|
|
87
|
+
* @param option 选项/输入内容
|
|
88
|
+
* @param name CLI 名称
|
|
89
|
+
* @param commands 命令列表
|
|
90
|
+
*/
|
|
91
|
+
function validateCommand(option: string, name: string, commands: CommandItem[]): LikeCommandResult {
|
|
92
|
+
const {exsited, likeList} = hasLikeCommand(option, commands);
|
|
93
|
+
|
|
94
|
+
if (!exsited) {
|
|
95
|
+
let formatVal = option.toLowerCase();
|
|
96
|
+
switch (formatVal) {
|
|
97
|
+
case '--h':
|
|
98
|
+
showHelp(name, commands);
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
if (likeList.length !== 0) {
|
|
102
|
+
let likes: string[] = [];
|
|
103
|
+
likeList.forEach(cmd => {
|
|
104
|
+
likes.push(`${name} ${cmd.command}`);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (likes.length !== 0) {
|
|
108
|
+
CLI.loading.succeed(Lang.BUILDIN.CLI_HAS_READY);
|
|
109
|
+
CLI.log.error(
|
|
110
|
+
Lang.MSG_ERROR,
|
|
111
|
+
`${Lang.BUILDIN.NO_COMMAND} "${name} ${option}"`,
|
|
112
|
+
`${Lang.BUILDIN.MEAN_SUCH}\n\t${likes.join('\n\t')}`,
|
|
113
|
+
);
|
|
114
|
+
process.exit();
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
CLI.loading.succeed(Lang.BUILDIN.CLI_HAS_READY);
|
|
118
|
+
CLI.log.error(Lang.MSG_ERROR, `${Lang.BUILDIN.NO_COMMAND} "${name} ${option}".`);
|
|
119
|
+
process.exit();
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
exsited,
|
|
127
|
+
likeList,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* 检查并自动更新 CLI 或相关依赖
|
|
133
|
+
*/
|
|
134
|
+
async function autoUpdate(): Promise<void> {
|
|
135
|
+
let pkg = path.join(cliRoootPath, 'package.json'); // 找到 CLI 自身的 PKG,真实位置在 NPM 全局安装目录下
|
|
136
|
+
CLI.loading.start(Lang.BUILDIN.CORE_CHECKING_UPDATE);
|
|
137
|
+
|
|
138
|
+
let pkgJSON = require('../package.json');
|
|
139
|
+
let storeUrl = CLIConfig.store;
|
|
140
|
+
let url = path.join(storeUrl, CLIConfig.packageName);
|
|
141
|
+
let cliVersion = await packages.checkVersion(url, pkgJSON.version);
|
|
142
|
+
if (JSON.stringify(cliVersion) === '{}') {
|
|
143
|
+
CLI.loading.info(Lang.BUILDIN.CORE_LATEST_VERSION);
|
|
144
|
+
|
|
145
|
+
/** 以下是检测 code-agent 依赖包版本的预留逻辑 */
|
|
146
|
+
} else {
|
|
147
|
+
CLI.loading.info(Lang.BUILDIN.CORE_UPDATE_READY); // 升级 CLI 需要切换目录到 NPM 全局安装目录
|
|
148
|
+
CLI.log.printObject(cliVersion);
|
|
149
|
+
const task = 'npm install -g code-agent --loglevel info --timing';
|
|
150
|
+
if (process.platform === 'win32') {
|
|
151
|
+
ChildProcess.taskInNewWindow(task, npmRootPath, true);
|
|
152
|
+
} else {
|
|
153
|
+
CLI.log.warn(Lang.BUILDIN.CORE_LINUX_INPUT_ROOT_USER_PASSWORD);
|
|
154
|
+
ChildProcess.taskInNewWindow(`sudo ${task}`, npmRootPath, true);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 引导和执行命令的主逻辑
|
|
161
|
+
*/
|
|
162
|
+
async function guideCommand(): Promise<void> {
|
|
163
|
+
const {wordsLen, name, commands, inAnyPath, buildIn} = getCLIConfig();
|
|
164
|
+
const currArgs = process.argv.slice(2);
|
|
165
|
+
const cmdLen = currArgs.length;
|
|
166
|
+
if (cmdLen === 0) {
|
|
167
|
+
showHelp(name, commands);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (cmdLen <= wordsLen) {
|
|
171
|
+
let cmdOptions = currArgs.join(' ');
|
|
172
|
+
|
|
173
|
+
let main = `${path.join('extensions', currArgs.join('-'), 'index.js')}`;
|
|
174
|
+
if (buildIn.indexOf(cmdOptions) > -1) {
|
|
175
|
+
main = `${path.join('generator', currArgs.join('-'), 'index.js')}`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const {exsited} = validateCommand(cmdOptions, name, commands);
|
|
179
|
+
|
|
180
|
+
if (exsited) {
|
|
181
|
+
let baseEnvConfig = JSON.stringify({
|
|
182
|
+
input: cmdOptions,
|
|
183
|
+
commands,
|
|
184
|
+
wordsLen,
|
|
185
|
+
name,
|
|
186
|
+
inAnyPath,
|
|
187
|
+
});
|
|
188
|
+
process.env['CLI_ENV'] = baseEnvConfig;
|
|
189
|
+
CLI.loading.succeed(Lang.BUILDIN.CLI_VOLIDATE_CMD_SUCCESS);
|
|
190
|
+
|
|
191
|
+
const loadProgram = (): void => {
|
|
192
|
+
let programPath = isDebug
|
|
193
|
+
? path.join(currentProjectRoot, 'src', main)
|
|
194
|
+
: path.join(globalNpmRoot, CLIConfig.packageName, 'src', main);
|
|
195
|
+
|
|
196
|
+
let child = fork(programPath, [npmRootPath], {
|
|
197
|
+
silent: false,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
child.on('error', (error: Error) => {
|
|
201
|
+
console.clear();
|
|
202
|
+
CLI.log.error(error.message, error.stack);
|
|
203
|
+
autoUpdate();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
child.on('exit', (code: number | null) => {
|
|
207
|
+
if (code === 0) {
|
|
208
|
+
autoUpdate();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
loadProgram();
|
|
213
|
+
} else {
|
|
214
|
+
CLI.loading.succeed(Lang.BUILDIN.CLI_HAS_READY);
|
|
215
|
+
CLI.log.error(Lang.MSG_ERROR, `${Lang.BUILDIN.NO_COMMAND} "${name} ${currArgs.join(' ')}"`);
|
|
216
|
+
process.exit();
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
CLI.loading.succeed(Lang.BUILDIN.CLI_HAS_READY);
|
|
220
|
+
CLI.log.error(Lang.MSG_ERROR, Lang.BUILDIN.COMMAND_LENGTH_TOO_LONG);
|
|
221
|
+
process.exit();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
guideCommand();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Lang = void 0;
|
|
4
|
+
const Lang = {
|
|
5
|
+
MSG_SUCCESS: '成功:',
|
|
6
|
+
MSG_ERROR: '错误: ',
|
|
7
|
+
HELP_MESSAGE: '--h: 帮助信息',
|
|
8
|
+
BUILDIN: {
|
|
9
|
+
CORE_STRTUP: 'code-agent正在启动',
|
|
10
|
+
CORE_STRTUP_DONE: 'code-agent启动完成,通过coda --h 查看所有命令',
|
|
11
|
+
CORE_STRTUP_READY: 'code-agent准备启动,请稍等...',
|
|
12
|
+
CORE_CHECKING_UPDATE: 'code-agent正在检查更新...',
|
|
13
|
+
CORE_LATEST_VERSION: 'code-agent是最新版本.',
|
|
14
|
+
CORE_CHECKING_PACKAGES_VERSION: 'code-agent正在检测依赖包版本...',
|
|
15
|
+
CORE_PACKAGES_LATEST_VERSION: 'code-agent依赖包是最新版本.',
|
|
16
|
+
CORE_PACKAGES_FOUND_NEW_VERSION: 'code-agent依赖包有新版本:',
|
|
17
|
+
CORE_UPDATE_PACKAGES: 'code-agent即将更新依赖包,不要关闭当前命令窗口.',
|
|
18
|
+
CORE_UPDATE_READY: 'code-agent有新版本,即将打开新的命令窗口进行版本升级.',
|
|
19
|
+
CORE_LINUX_INPUT_ROOT_USER_PASSWORD: '注意观察命令行窗口:Linux用户需要输入root密码.',
|
|
20
|
+
CMD_NAME: '输入文件夹名称',
|
|
21
|
+
CMD_DESCRIPTION: '输入命令的描述',
|
|
22
|
+
EXSITED: '已存在',
|
|
23
|
+
NOT_EXSITED: '不存在',
|
|
24
|
+
IS_CREATD_TMPL_FOLDER: '需要创建临时目录',
|
|
25
|
+
IS_RUN_ANNY_PATH: '只能运行在项目根目录',
|
|
26
|
+
CMD_CREATE_SUCCESS: '命令文件创建成功',
|
|
27
|
+
NAME_NO_WHITESPACE: '文件名不能有空格',
|
|
28
|
+
NAME_NO_SPECIAL_CHARACTER: '文件名仅支持"-"或"_"特殊符号',
|
|
29
|
+
NAME_LOWERCASE: '文件名必须小写',
|
|
30
|
+
ADD_CMD_CONFIG: '添加到配置命令文件',
|
|
31
|
+
ADD_CMD_CONFIG_SUCCESS: '添加到配置命令文件成功',
|
|
32
|
+
ADD_CMD_EXTENSIONS: '添加到扩展命令',
|
|
33
|
+
ADD_CMD_EXTENSIONS_SUCCESS: '添加到扩展命令成功',
|
|
34
|
+
ADD_CMD_PACKAGE: '添加到package.json',
|
|
35
|
+
ADD_CMD_PACKAGE_SUCCESS: '添加到package.json成功',
|
|
36
|
+
NO_COMMAND: '没有该名称的命令',
|
|
37
|
+
MEAN_SUCH: '你的意思是:',
|
|
38
|
+
COMMAND_LENGTH_TOO_LONG: '命令单词长度太长',
|
|
39
|
+
NO_THIS_FOLDER: '没有找到该名称的目录',
|
|
40
|
+
DELETE_COMMAND_TIPS: '即将删除命令文件',
|
|
41
|
+
DELETE_COMMAND_SUCCESS: '删除命令文件成功',
|
|
42
|
+
DELETE_COMMAND_FLOW_SUCCESS: '删除命令流程已结束',
|
|
43
|
+
CLI_HAS_READY: 'code-agent准备就绪,即将执行命令',
|
|
44
|
+
CLI_VOLIDATING_CMD: 'code-agent校验命令',
|
|
45
|
+
CLI_VOLIDATE_CMD_SUCCESS: 'code-agent校验命令成功',
|
|
46
|
+
},
|
|
47
|
+
EXTENSION: {
|
|
48
|
+
CHOICE_PROJECT_TYPE: '选择项目类型',
|
|
49
|
+
CHOICE_PROJECT_STACK: '选择项目技术栈',
|
|
50
|
+
SUPORT_LATER: '暂不支持',
|
|
51
|
+
PROJECT_NAME: '输入项目名称',
|
|
52
|
+
PROJECT_WILL_CREATE: '项目文件即将被创建',
|
|
53
|
+
PROJECT_CREATE_SUCCESS: '项目我呢见创建成功',
|
|
54
|
+
PROJECT_INSTALL_TIPS: '项目即将安装依赖包,不要关闭当前命令窗口',
|
|
55
|
+
PROJECT_CREATE_FLOW_DONE: '创建项目流程结束',
|
|
56
|
+
CREATE_PKG_DONE: '创建项目package.json结束',
|
|
57
|
+
CREATE_WEBPACK_DONE: '创建项目webpack相关配置结束',
|
|
58
|
+
CREATE_PROJECT_DONE: '创建项目文件结束',
|
|
59
|
+
PROJECT_FOLDER_PATH: '项目目录在',
|
|
60
|
+
TMPL_NOT_EXSITED: '模板文件不存在',
|
|
61
|
+
PROJECT_SUBAPP_NAME: '输入子应用的名称',
|
|
62
|
+
PROJECT_DEV_SERVER: '选择打包工具',
|
|
63
|
+
COPY_PLAYER_CODE: '是否复制视频播放器代码到项目',
|
|
64
|
+
COPY_PLAYER_CODE_PATH: '输入相对路径',
|
|
65
|
+
INSTALL_PLAYER_PACKAGE: '正在安装视频播放器依赖包',
|
|
66
|
+
COPY_PLAYER_CODE_START: '开始复制视频播放器代码',
|
|
67
|
+
COPY_PLAYER_CODE_SUCCESS: '复制视频播放器代码成功',
|
|
68
|
+
ADD_PLAYER_FLOW_DONE: '添加视频播放器流程结束',
|
|
69
|
+
NOT_EXSITED_PKGJSON: '在当前根目录不存在package.json',
|
|
70
|
+
FFMPEG_NOT_SUPPORT_WIN: '仅支持Ubuntu系统',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
exports.Lang = Lang;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const Lang = {
|
|
2
|
+
MSG_SUCCESS: '成功:',
|
|
3
|
+
MSG_ERROR: '错误: ',
|
|
4
|
+
HELP_MESSAGE: '--h: 帮助信息',
|
|
5
|
+
BUILDIN: {
|
|
6
|
+
CORE_STRTUP: 'code-agent正在启动',
|
|
7
|
+
CORE_STRTUP_DONE: 'code-agent启动完成,通过coda --h 查看所有命令',
|
|
8
|
+
CORE_STRTUP_READY: 'code-agent准备启动,请稍等...',
|
|
9
|
+
CORE_CHECKING_UPDATE: 'code-agent正在检查更新...',
|
|
10
|
+
CORE_LATEST_VERSION: 'code-agent是最新版本.',
|
|
11
|
+
CORE_CHECKING_PACKAGES_VERSION: 'code-agent正在检测依赖包版本...',
|
|
12
|
+
CORE_PACKAGES_LATEST_VERSION: 'code-agent依赖包是最新版本.',
|
|
13
|
+
CORE_PACKAGES_FOUND_NEW_VERSION: 'code-agent依赖包有新版本:',
|
|
14
|
+
CORE_UPDATE_PACKAGES: 'code-agent即将更新依赖包,不要关闭当前命令窗口.',
|
|
15
|
+
CORE_UPDATE_READY: 'code-agent有新版本,即将打开新的命令窗口进行版本升级.',
|
|
16
|
+
CORE_LINUX_INPUT_ROOT_USER_PASSWORD: '注意观察命令行窗口:Linux用户需要输入root密码.',
|
|
17
|
+
CMD_NAME: '输入文件夹名称',
|
|
18
|
+
CMD_DESCRIPTION: '输入命令的描述',
|
|
19
|
+
EXSITED: '已存在',
|
|
20
|
+
NOT_EXSITED: '不存在',
|
|
21
|
+
IS_CREATD_TMPL_FOLDER: '需要创建临时目录',
|
|
22
|
+
IS_RUN_ANNY_PATH: '只能运行在项目根目录',
|
|
23
|
+
CMD_CREATE_SUCCESS: '命令文件创建成功',
|
|
24
|
+
NAME_NO_WHITESPACE: '文件名不能有空格',
|
|
25
|
+
NAME_NO_SPECIAL_CHARACTER: '文件名仅支持"-"或"_"特殊符号',
|
|
26
|
+
NAME_LOWERCASE: '文件名必须小写',
|
|
27
|
+
ADD_CMD_CONFIG: '添加到配置命令文件',
|
|
28
|
+
ADD_CMD_CONFIG_SUCCESS: '添加到配置命令文件成功',
|
|
29
|
+
ADD_CMD_EXTENSIONS: '添加到扩展命令',
|
|
30
|
+
ADD_CMD_EXTENSIONS_SUCCESS: '添加到扩展命令成功',
|
|
31
|
+
ADD_CMD_PACKAGE: '添加到package.json',
|
|
32
|
+
ADD_CMD_PACKAGE_SUCCESS: '添加到package.json成功',
|
|
33
|
+
NO_COMMAND: '没有该名称的命令',
|
|
34
|
+
MEAN_SUCH: '你的意思是:',
|
|
35
|
+
COMMAND_LENGTH_TOO_LONG: '命令单词长度太长',
|
|
36
|
+
NO_THIS_FOLDER: '没有找到该名称的目录',
|
|
37
|
+
DELETE_COMMAND_TIPS: '即将删除命令文件',
|
|
38
|
+
DELETE_COMMAND_SUCCESS: '删除命令文件成功',
|
|
39
|
+
DELETE_COMMAND_FLOW_SUCCESS: '删除命令流程已结束',
|
|
40
|
+
CLI_HAS_READY: 'code-agent准备就绪,即将执行命令',
|
|
41
|
+
CLI_VOLIDATING_CMD: 'code-agent校验命令',
|
|
42
|
+
CLI_VOLIDATE_CMD_SUCCESS: 'code-agent校验命令成功',
|
|
43
|
+
},
|
|
44
|
+
EXTENSION: {
|
|
45
|
+
CHOICE_PROJECT_TYPE: '选择项目类型',
|
|
46
|
+
CHOICE_PROJECT_STACK: '选择项目技术栈',
|
|
47
|
+
SUPORT_LATER: '暂不支持',
|
|
48
|
+
PROJECT_NAME: '输入项目名称',
|
|
49
|
+
PROJECT_WILL_CREATE: '项目文件即将被创建',
|
|
50
|
+
PROJECT_CREATE_SUCCESS: '项目我呢见创建成功',
|
|
51
|
+
PROJECT_INSTALL_TIPS: '项目即将安装依赖包,不要关闭当前命令窗口',
|
|
52
|
+
PROJECT_CREATE_FLOW_DONE: '创建项目流程结束',
|
|
53
|
+
CREATE_PKG_DONE: '创建项目package.json结束',
|
|
54
|
+
CREATE_WEBPACK_DONE: '创建项目webpack相关配置结束',
|
|
55
|
+
CREATE_PROJECT_DONE: '创建项目文件结束',
|
|
56
|
+
PROJECT_FOLDER_PATH: '项目目录在',
|
|
57
|
+
TMPL_NOT_EXSITED: '模板文件不存在',
|
|
58
|
+
PROJECT_SUBAPP_NAME: '输入子应用的名称',
|
|
59
|
+
PROJECT_DEV_SERVER: '选择打包工具',
|
|
60
|
+
COPY_PLAYER_CODE: '是否复制视频播放器代码到项目',
|
|
61
|
+
COPY_PLAYER_CODE_PATH: '输入相对路径',
|
|
62
|
+
INSTALL_PLAYER_PACKAGE: '正在安装视频播放器依赖包',
|
|
63
|
+
COPY_PLAYER_CODE_START: '开始复制视频播放器代码',
|
|
64
|
+
COPY_PLAYER_CODE_SUCCESS: '复制视频播放器代码成功',
|
|
65
|
+
ADD_PLAYER_FLOW_DONE: '添加视频播放器流程结束',
|
|
66
|
+
NOT_EXSITED_PKGJSON: '在当前根目录不存在package.json',
|
|
67
|
+
FFMPEG_NOT_SUPPORT_WIN: '仅支持Ubuntu系统',
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export { Lang };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Util = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const lang_1 = require("./lang");
|
|
40
|
+
exports.Util = {
|
|
41
|
+
/**
|
|
42
|
+
* 验证文件名
|
|
43
|
+
* @param input 输入的文件名
|
|
44
|
+
* @returns 验证通过返回 true,否则返回错误提示字符串
|
|
45
|
+
*/
|
|
46
|
+
volidateFileName(input) {
|
|
47
|
+
if (/\s/.test(input)) {
|
|
48
|
+
return lang_1.Lang.BUILDIN.NAME_NO_WHITESPACE;
|
|
49
|
+
}
|
|
50
|
+
if (/[A-Z]/.test(input)) {
|
|
51
|
+
return lang_1.Lang.BUILDIN.NAME_LOWERCASE;
|
|
52
|
+
}
|
|
53
|
+
const regex = /[\s~`!@#$%^&*()\_=+[\]{}|;:'",<.>/?]/; // 只允许使用 - 作为文件名分隔符
|
|
54
|
+
if (regex.test(input)) {
|
|
55
|
+
return lang_1.Lang.BUILDIN.NAME_NO_SPECIAL_CHARACTER;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* 验证路径是否存在及合法性
|
|
61
|
+
* @param input 输入的文件名
|
|
62
|
+
* @param root 根目录路径
|
|
63
|
+
* @returns 验证通过返回 true,否则返回错误提示字符串
|
|
64
|
+
*/
|
|
65
|
+
validatePath(input, root) {
|
|
66
|
+
const commonValidate = exports.Util.volidateFileName(input);
|
|
67
|
+
if (commonValidate === true) {
|
|
68
|
+
const tempPath = path.join(root, input);
|
|
69
|
+
if (fs.existsSync(tempPath)) {
|
|
70
|
+
return `${input} ${lang_1.Lang.BUILDIN.EXSITED}`;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return commonValidate;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* 将中划线命名转换为驼峰命名 (camelCase)
|
|
82
|
+
* @param input 输入的字符串
|
|
83
|
+
*/
|
|
84
|
+
convertWordsToHump(input) {
|
|
85
|
+
let text = '';
|
|
86
|
+
const index = input.indexOf('-');
|
|
87
|
+
if (index > -1) {
|
|
88
|
+
input.split('-').forEach((item, index) => {
|
|
89
|
+
if (index === 0) {
|
|
90
|
+
text = item;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const newText = item.charAt(0).toUpperCase() + item.slice(1);
|
|
94
|
+
text += newText;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
text = input;
|
|
100
|
+
}
|
|
101
|
+
return text;
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* 将中划线命名转换为大驼峰/类名命名 (PascalCase)
|
|
105
|
+
* @param input 输入的字符串
|
|
106
|
+
*/
|
|
107
|
+
convertWordsToClassname(input) {
|
|
108
|
+
let text = '';
|
|
109
|
+
const index = input.indexOf('-');
|
|
110
|
+
if (index > -1) {
|
|
111
|
+
input.split('-').forEach(item => {
|
|
112
|
+
text += item.charAt(0).toUpperCase() + item.slice(1);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
text = input.charAt(0).toUpperCase() + input.slice(1);
|
|
117
|
+
}
|
|
118
|
+
return text;
|
|
119
|
+
},
|
|
120
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import {Lang} from './lang';
|
|
4
|
+
|
|
5
|
+
export const Util = {
|
|
6
|
+
/**
|
|
7
|
+
* 验证文件名
|
|
8
|
+
* @param input 输入的文件名
|
|
9
|
+
* @returns 验证通过返回 true,否则返回错误提示字符串
|
|
10
|
+
*/
|
|
11
|
+
volidateFileName(input: string): true | string {
|
|
12
|
+
if (/\s/.test(input)) {
|
|
13
|
+
return Lang.BUILDIN.NAME_NO_WHITESPACE;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (/[A-Z]/.test(input)) {
|
|
17
|
+
return Lang.BUILDIN.NAME_LOWERCASE;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const regex = /[\s~`!@#$%^&*()\_=+[\]{}|;:'",<.>/?]/; // 只允许使用 - 作为文件名分隔符
|
|
21
|
+
if (regex.test(input)) {
|
|
22
|
+
return Lang.BUILDIN.NAME_NO_SPECIAL_CHARACTER;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return true;
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 验证路径是否存在及合法性
|
|
30
|
+
* @param input 输入的文件名
|
|
31
|
+
* @param root 根目录路径
|
|
32
|
+
* @returns 验证通过返回 true,否则返回错误提示字符串
|
|
33
|
+
*/
|
|
34
|
+
validatePath(input: string, root: string): true | string {
|
|
35
|
+
const commonValidate = Util.volidateFileName(input);
|
|
36
|
+
|
|
37
|
+
if (commonValidate === true) {
|
|
38
|
+
const tempPath = path.join(root, input);
|
|
39
|
+
if (fs.existsSync(tempPath)) {
|
|
40
|
+
return `${input} ${Lang.BUILDIN.EXSITED}`;
|
|
41
|
+
} else {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
return commonValidate;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 将中划线命名转换为驼峰命名 (camelCase)
|
|
51
|
+
* @param input 输入的字符串
|
|
52
|
+
*/
|
|
53
|
+
convertWordsToHump(input: string): string {
|
|
54
|
+
let text = '';
|
|
55
|
+
const index = input.indexOf('-');
|
|
56
|
+
|
|
57
|
+
if (index > -1) {
|
|
58
|
+
input.split('-').forEach((item, index) => {
|
|
59
|
+
if (index === 0) {
|
|
60
|
+
text = item;
|
|
61
|
+
} else {
|
|
62
|
+
const newText = item.charAt(0).toUpperCase() + item.slice(1);
|
|
63
|
+
text += newText;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
text = input;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return text;
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 将中划线命名转换为大驼峰/类名命名 (PascalCase)
|
|
75
|
+
* @param input 输入的字符串
|
|
76
|
+
*/
|
|
77
|
+
convertWordsToClassname(input: string): string {
|
|
78
|
+
let text = '';
|
|
79
|
+
const index = input.indexOf('-');
|
|
80
|
+
|
|
81
|
+
if (index > -1) {
|
|
82
|
+
input.split('-').forEach(item => {
|
|
83
|
+
text += item.charAt(0).toUpperCase() + item.slice(1);
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
text = input.charAt(0).toUpperCase() + input.slice(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return text;
|
|
90
|
+
},
|
|
91
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 命令项接口
|
|
3
|
+
*/
|
|
4
|
+
export interface CommandItem {
|
|
5
|
+
command: string; //命令名称
|
|
6
|
+
description: string; //命令描述
|
|
7
|
+
custom: boolean; //是否是用户扩展的命令
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* CLI 配置文件接口
|
|
12
|
+
*/
|
|
13
|
+
export interface CLIConfigType {
|
|
14
|
+
packageName: string; //工具名称
|
|
15
|
+
wordsLen: number; //命令单词数目
|
|
16
|
+
name: string; //命令开头的单词
|
|
17
|
+
commands: CommandItem[]; //全部命令
|
|
18
|
+
inAnyPath: string[]; //能在任何路径执行的命令
|
|
19
|
+
buildIn: string[]; //工具内置的命令
|
|
20
|
+
store: string; //npm仓库地址
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 相似命令检查结果接口
|
|
25
|
+
*/
|
|
26
|
+
export interface LikeCommandResult {
|
|
27
|
+
exsited: boolean;
|
|
28
|
+
likeList: CommandItem[];
|
|
29
|
+
}
|