@xubill/xx-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.
Potentially problematic release.
This version of @xubill/xx-cli might be problematic. Click here for more details.
- package/bin/cli.js +87 -0
- package/lib/core/base-plugin.js +292 -0
- package/lib/core/index.js +583 -0
- package/lib/utils/config-manager.js +185 -0
- package/lib/utils/history-manager.js +118 -0
- package/lib/utils/logger.js +28 -0
- package/lib/utils/plugin-config.js +158 -0
- package/lib/utils/transformers/getInput.js +76 -0
- package/lib/utils/transformers/index.js +43 -0
- package/lib/utils/transformers/renderLists.js +94 -0
- package/lib/utils/transformers/sfcMaterial.js +113 -0
- package/lib/utils/transformers/transformFilter.js +95 -0
- package/lib/utils/transformers/transformList.js +120 -0
- package/lib/utils/transformers/transformMock.js +43 -0
- package/lib/utils/transformers/transformRoutes.js +36 -0
- package/lib/utils/transformers/transformTable.js +81 -0
- package/lib/utils/transformers/transformTemplate.js +129 -0
- package/lib/utils/validator.js +96 -0
- package/package.json +62 -0
- package/readme.md +5 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一配置管理模块
|
|
3
|
+
* 提供标准化的配置加载、保存、验证功能
|
|
4
|
+
* 支持配置优先级:命令行参数 > 本地配置 > 全局配置
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const chalk = require('chalk').default;
|
|
10
|
+
|
|
11
|
+
class ConfigManager {
|
|
12
|
+
/**
|
|
13
|
+
* 构造函数
|
|
14
|
+
* @param {string} pluginName - 插件名称
|
|
15
|
+
* @param {Object} options - 配置选项
|
|
16
|
+
*/
|
|
17
|
+
constructor(pluginName, options = {}) {
|
|
18
|
+
this.homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
19
|
+
this.globalConfigDir = path.join(this.homeDir, '.xx', pluginName);
|
|
20
|
+
this.localConfigPath = options.localConfigPath || `.${pluginName}Config`;
|
|
21
|
+
this.ensureConfigDir();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 确保配置目录存在
|
|
26
|
+
*/
|
|
27
|
+
ensureConfigDir() {
|
|
28
|
+
if (!fs.existsSync(this.globalConfigDir)) {
|
|
29
|
+
fs.mkdirSync(this.globalConfigDir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 加载配置
|
|
35
|
+
* @param {string} configName - 配置名称
|
|
36
|
+
* @param {Object} cliOptions - 命令行选项
|
|
37
|
+
* @returns {Object} 合并后的配置对象
|
|
38
|
+
*/
|
|
39
|
+
loadConfig(configName = 'config', cliOptions = {}) {
|
|
40
|
+
// 1. 加载全局配置
|
|
41
|
+
const globalConfig = this.loadGlobalConfig(configName);
|
|
42
|
+
|
|
43
|
+
// 2. 加载本地配置
|
|
44
|
+
const localConfig = this.loadLocalConfig(configName);
|
|
45
|
+
|
|
46
|
+
// 3. 合并配置:本地配置覆盖全局配置,命令行选项覆盖本地配置
|
|
47
|
+
const mergedConfig = {
|
|
48
|
+
...globalConfig,
|
|
49
|
+
...localConfig,
|
|
50
|
+
...cliOptions
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return mergedConfig;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 加载全局配置
|
|
58
|
+
* @param {string} configName - 配置名称
|
|
59
|
+
* @returns {Object} 全局配置对象
|
|
60
|
+
*/
|
|
61
|
+
loadGlobalConfig(configName = 'config') {
|
|
62
|
+
const configPath = path.join(this.globalConfigDir, `${configName}.json`);
|
|
63
|
+
if (fs.existsSync(configPath)) {
|
|
64
|
+
try {
|
|
65
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error(chalk.red(`解析全局配置文件失败: ${error.message}`));
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 加载本地配置
|
|
76
|
+
* @param {string} configName - 配置名称
|
|
77
|
+
* @returns {Object} 本地配置对象
|
|
78
|
+
*/
|
|
79
|
+
loadLocalConfig(configName = 'config') {
|
|
80
|
+
const configPath = path.resolve(this.localConfigPath);
|
|
81
|
+
if (fs.existsSync(configPath)) {
|
|
82
|
+
try {
|
|
83
|
+
const localConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
84
|
+
// 如果是多环境配置,返回指定环境的配置
|
|
85
|
+
if (localConfig[configName]) {
|
|
86
|
+
return localConfig[configName];
|
|
87
|
+
}
|
|
88
|
+
return localConfig;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error(chalk.red(`解析本地配置文件失败: ${error.message}`));
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 保存配置
|
|
99
|
+
* @param {Object} config - 配置对象
|
|
100
|
+
* @param {string} configName - 配置名称
|
|
101
|
+
* @param {boolean} isGlobal - 是否保存到全局配置
|
|
102
|
+
*/
|
|
103
|
+
saveConfig(config, configName = 'config', isGlobal = true) {
|
|
104
|
+
try {
|
|
105
|
+
const configPath = isGlobal
|
|
106
|
+
? path.join(this.globalConfigDir, `${configName}.json`)
|
|
107
|
+
: path.resolve(this.localConfigPath);
|
|
108
|
+
|
|
109
|
+
// 确保目录存在
|
|
110
|
+
if (isGlobal) {
|
|
111
|
+
this.ensureConfigDir();
|
|
112
|
+
} else {
|
|
113
|
+
const configDir = path.dirname(configPath);
|
|
114
|
+
if (!fs.existsSync(configDir)) {
|
|
115
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
120
|
+
console.log(chalk.green(`配置保存成功: ${configPath}`));
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error(chalk.red(`保存配置失败: ${error.message}`));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 验证配置
|
|
128
|
+
* @param {Object} config - 配置对象
|
|
129
|
+
* @param {Object} schema - 配置 schema
|
|
130
|
+
* @returns {Object} 验证结果
|
|
131
|
+
*/
|
|
132
|
+
validateConfig(config, schema) {
|
|
133
|
+
if (!schema) {
|
|
134
|
+
return { valid: true, data: config };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 这里可以集成 Joi 等验证库
|
|
138
|
+
// 暂时返回简单验证
|
|
139
|
+
return { valid: true, data: config };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 获取配置路径
|
|
144
|
+
* @param {string} configName - 配置名称
|
|
145
|
+
* @param {boolean} isGlobal - 是否获取全局配置路径
|
|
146
|
+
* @returns {string} 配置文件路径
|
|
147
|
+
*/
|
|
148
|
+
getConfigPath(configName = 'config', isGlobal = true) {
|
|
149
|
+
return isGlobal
|
|
150
|
+
? path.join(this.globalConfigDir, `${configName}.json`)
|
|
151
|
+
: path.resolve(this.localConfigPath);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 检查配置是否存在
|
|
156
|
+
* @param {string} configName - 配置名称
|
|
157
|
+
* @param {boolean} isGlobal - 是否检查全局配置
|
|
158
|
+
* @returns {boolean} 配置是否存在
|
|
159
|
+
*/
|
|
160
|
+
hasConfig(configName = 'config', isGlobal = true) {
|
|
161
|
+
const configPath = this.getConfigPath(configName, isGlobal);
|
|
162
|
+
return fs.existsSync(configPath);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 删除配置
|
|
167
|
+
* @param {string} configName - 配置名称
|
|
168
|
+
* @param {boolean} isGlobal - 是否删除全局配置
|
|
169
|
+
*/
|
|
170
|
+
deleteConfig(configName = 'config', isGlobal = true) {
|
|
171
|
+
try {
|
|
172
|
+
const configPath = this.getConfigPath(configName, isGlobal);
|
|
173
|
+
if (fs.existsSync(configPath)) {
|
|
174
|
+
fs.unlinkSync(configPath);
|
|
175
|
+
console.log(chalk.green(`配置删除成功: ${configPath}`));
|
|
176
|
+
} else {
|
|
177
|
+
console.log(chalk.yellow(`配置文件不存在: ${configPath}`));
|
|
178
|
+
}
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error(chalk.red(`删除配置失败: ${error.message}`));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = ConfigManager;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 命令历史记录管理
|
|
3
|
+
* 用于存储和读取命令历史
|
|
4
|
+
* 支持浏览和重复执行之前的命令
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
// 历史记录文件路径
|
|
11
|
+
const historyPath = path.join(process.env.HOME || process.env.USERPROFILE, '.xx-cli', 'history.json');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 确保历史记录目录存在
|
|
15
|
+
*/
|
|
16
|
+
function ensureHistoryDir() {
|
|
17
|
+
const historyDir = path.dirname(historyPath);
|
|
18
|
+
if (!fs.existsSync(historyDir)) {
|
|
19
|
+
fs.mkdirSync(historyDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 读取命令历史
|
|
25
|
+
* @returns {Array} 命令历史数组
|
|
26
|
+
*/
|
|
27
|
+
exports.readHistory = () => {
|
|
28
|
+
ensureHistoryDir();
|
|
29
|
+
|
|
30
|
+
if (fs.existsSync(historyPath)) {
|
|
31
|
+
try {
|
|
32
|
+
const history = fs.readFileSync(historyPath, 'utf8');
|
|
33
|
+
return JSON.parse(history);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error('读取命令历史失败:', error.message);
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return [];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 写入命令历史
|
|
45
|
+
* @param {Array} history - 命令历史数组
|
|
46
|
+
*/
|
|
47
|
+
exports.writeHistory = (history) => {
|
|
48
|
+
ensureHistoryDir();
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
fs.writeFileSync(historyPath, JSON.stringify(history, null, 2));
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('写入命令历史失败:', error.message);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 添加命令到历史记录
|
|
59
|
+
* @param {string} command - 命令字符串
|
|
60
|
+
*/
|
|
61
|
+
exports.addHistory = (command) => {
|
|
62
|
+
// 不记录空命令、帮助命令和 history 命令本身
|
|
63
|
+
if (!command ||
|
|
64
|
+
command.trim() === '' ||
|
|
65
|
+
command.includes('--help') ||
|
|
66
|
+
command.includes('-h') ||
|
|
67
|
+
command.startsWith('history') ||
|
|
68
|
+
command.startsWith('h ') ||
|
|
69
|
+
command === 'h') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const history = exports.readHistory();
|
|
74
|
+
|
|
75
|
+
// 移除重复的命令
|
|
76
|
+
const filteredHistory = history.filter(item => item.command !== command);
|
|
77
|
+
|
|
78
|
+
// 添加新命令到开头
|
|
79
|
+
const newHistory = [
|
|
80
|
+
{
|
|
81
|
+
command,
|
|
82
|
+
timestamp: new Date().toISOString()
|
|
83
|
+
},
|
|
84
|
+
...filteredHistory
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
// 限制历史记录数量
|
|
88
|
+
const limitedHistory = newHistory.slice(0, 100);
|
|
89
|
+
|
|
90
|
+
exports.writeHistory(limitedHistory);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 清除命令历史
|
|
95
|
+
*/
|
|
96
|
+
exports.clearHistory = () => {
|
|
97
|
+
exports.writeHistory([]);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 获取命令历史
|
|
102
|
+
* @param {number} limit - 限制数量
|
|
103
|
+
* @returns {Array} 命令历史数组
|
|
104
|
+
*/
|
|
105
|
+
exports.getHistory = (limit = 10) => {
|
|
106
|
+
const history = exports.readHistory();
|
|
107
|
+
return history.slice(0, limit);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 搜索命令历史
|
|
112
|
+
* @param {string} keyword - 搜索关键词
|
|
113
|
+
* @returns {Array} 匹配的命令历史数组
|
|
114
|
+
*/
|
|
115
|
+
exports.searchHistory = (keyword) => {
|
|
116
|
+
const history = exports.readHistory();
|
|
117
|
+
return history.filter(item => item.command.includes(keyword));
|
|
118
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日志工具模块
|
|
3
|
+
* 使用 winston 实现日志功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const winston = require('winston');
|
|
7
|
+
|
|
8
|
+
// 自定义日志格式化
|
|
9
|
+
const consoleFormat = winston.format.combine(
|
|
10
|
+
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
|
11
|
+
winston.format.printf(({ timestamp, level, message }) => {
|
|
12
|
+
return `[${timestamp}] [${level.toUpperCase()}] ${message}`;
|
|
13
|
+
})
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
// 创建日志实例
|
|
17
|
+
const logger = winston.createLogger({
|
|
18
|
+
level: 'info',
|
|
19
|
+
format: winston.format.json(),
|
|
20
|
+
transports: [
|
|
21
|
+
// 控制台输出
|
|
22
|
+
new winston.transports.Console({
|
|
23
|
+
format: consoleFormat
|
|
24
|
+
})
|
|
25
|
+
]
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
module.exports = logger;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件配置管理
|
|
3
|
+
* 用于管理插件的启用/禁用状态
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
// 插件配置文件路径
|
|
10
|
+
const configPath = path.join(process.env.HOME || process.env.USERPROFILE, '.xx-cli', 'plugin-config.json');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 确保配置目录存在
|
|
14
|
+
*/
|
|
15
|
+
function ensureConfigDir() {
|
|
16
|
+
const configDir = path.dirname(configPath);
|
|
17
|
+
if (!fs.existsSync(configDir)) {
|
|
18
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 读取插件配置
|
|
24
|
+
* @returns {Object} 插件配置
|
|
25
|
+
*/
|
|
26
|
+
exports.readConfig = () => {
|
|
27
|
+
ensureConfigDir();
|
|
28
|
+
|
|
29
|
+
if (fs.existsSync(configPath)) {
|
|
30
|
+
try {
|
|
31
|
+
const config = fs.readFileSync(configPath, 'utf8');
|
|
32
|
+
return JSON.parse(config);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('读取插件配置失败:', error.message);
|
|
35
|
+
return { disabled: [] };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return { disabled: [] };
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 写入插件配置
|
|
44
|
+
* @param {Object} config - 插件配置
|
|
45
|
+
*/
|
|
46
|
+
exports.writeConfig = (config) => {
|
|
47
|
+
ensureConfigDir();
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('写入插件配置失败:', error.message);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 检查插件是否已禁用
|
|
58
|
+
* @param {string} pluginName - 插件名称
|
|
59
|
+
* @returns {boolean} 是否已禁用
|
|
60
|
+
*/
|
|
61
|
+
exports.isPluginDisabled = (pluginName) => {
|
|
62
|
+
const config = exports.readConfig();
|
|
63
|
+
return config.disabled.includes(pluginName);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 禁用插件
|
|
68
|
+
* @param {string} pluginName - 插件名称
|
|
69
|
+
*/
|
|
70
|
+
exports.disablePlugin = (pluginName) => {
|
|
71
|
+
const config = exports.readConfig();
|
|
72
|
+
if (!config.disabled.includes(pluginName)) {
|
|
73
|
+
config.disabled.push(pluginName);
|
|
74
|
+
exports.writeConfig(config);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 启用插件
|
|
80
|
+
* @param {string} pluginName - 插件名称
|
|
81
|
+
*/
|
|
82
|
+
exports.enablePlugin = (pluginName) => {
|
|
83
|
+
const config = exports.readConfig();
|
|
84
|
+
config.disabled = config.disabled.filter(name => name !== pluginName);
|
|
85
|
+
exports.writeConfig(config);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 从配置中移除插件
|
|
90
|
+
* @param {string} pluginName - 插件名称
|
|
91
|
+
*/
|
|
92
|
+
exports.removePluginFromConfig = (pluginName) => {
|
|
93
|
+
const config = exports.readConfig();
|
|
94
|
+
config.disabled = config.disabled.filter(name => name !== pluginName);
|
|
95
|
+
|
|
96
|
+
// 同时移除插件的配置
|
|
97
|
+
if (config.plugins && config.plugins[pluginName]) {
|
|
98
|
+
delete config.plugins[pluginName];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
exports.writeConfig(config);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 设置插件配置
|
|
106
|
+
* @param {string} pluginName - 插件名称
|
|
107
|
+
* @param {string} key - 配置键
|
|
108
|
+
* @param {string} value - 配置值
|
|
109
|
+
*/
|
|
110
|
+
exports.setPluginConfig = (pluginName, key, value) => {
|
|
111
|
+
const config = exports.readConfig();
|
|
112
|
+
|
|
113
|
+
// 确保 plugins 对象存在
|
|
114
|
+
if (!config.plugins) {
|
|
115
|
+
config.plugins = {};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 确保插件的配置对象存在
|
|
119
|
+
if (!config.plugins[pluginName]) {
|
|
120
|
+
config.plugins[pluginName] = {};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 设置配置值
|
|
124
|
+
config.plugins[pluginName][key] = value;
|
|
125
|
+
|
|
126
|
+
exports.writeConfig(config);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 获取插件配置
|
|
131
|
+
* @param {string} pluginName - 插件名称
|
|
132
|
+
* @param {string} key - 配置键
|
|
133
|
+
* @returns {*} 配置值
|
|
134
|
+
*/
|
|
135
|
+
exports.getPluginConfig = (pluginName, key) => {
|
|
136
|
+
const config = exports.readConfig();
|
|
137
|
+
|
|
138
|
+
if (config.plugins && config.plugins[pluginName]) {
|
|
139
|
+
return config.plugins[pluginName][key];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return undefined;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 获取插件所有配置
|
|
147
|
+
* @param {string} pluginName - 插件名称
|
|
148
|
+
* @returns {Object} 插件配置对象
|
|
149
|
+
*/
|
|
150
|
+
exports.getPluginConfigs = (pluginName) => {
|
|
151
|
+
const config = exports.readConfig();
|
|
152
|
+
|
|
153
|
+
if (config.plugins && config.plugins[pluginName]) {
|
|
154
|
+
return config.plugins[pluginName];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {};
|
|
158
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 获取输入配置
|
|
3
|
+
* 处理用户输入的模板配置,转换为标准格式
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 处理模板配置
|
|
8
|
+
* @param {Object} config - 原始模板配置
|
|
9
|
+
* @returns {Object} 处理后的模板配置
|
|
10
|
+
*/
|
|
11
|
+
function processTemplateConfig(config) {
|
|
12
|
+
// 确保配置对象存在
|
|
13
|
+
if (!config) {
|
|
14
|
+
return {
|
|
15
|
+
dir: '.lists',
|
|
16
|
+
pages: {},
|
|
17
|
+
routes: { isRender: false },
|
|
18
|
+
mock: false
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 处理默认值
|
|
23
|
+
return {
|
|
24
|
+
dir: config.dir || '.lists',
|
|
25
|
+
pages: config.pages || {},
|
|
26
|
+
routes: {
|
|
27
|
+
isRender: config.routes?.isRender ?? false,
|
|
28
|
+
...config.routes
|
|
29
|
+
},
|
|
30
|
+
mock: config.mock ?? false,
|
|
31
|
+
templateType: config.templateType || 'element-ui'
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 处理页面配置
|
|
37
|
+
* @param {Object} pageConfig - 原始页面配置
|
|
38
|
+
* @returns {Object} 处理后的页面配置
|
|
39
|
+
*/
|
|
40
|
+
function processPageConfig(pageConfig) {
|
|
41
|
+
// 确保配置对象存在
|
|
42
|
+
if (!pageConfig) {
|
|
43
|
+
return {
|
|
44
|
+
template: {
|
|
45
|
+
cn: '列表页面',
|
|
46
|
+
en: 'list',
|
|
47
|
+
top: false,
|
|
48
|
+
bottom: false,
|
|
49
|
+
select: false,
|
|
50
|
+
btn: []
|
|
51
|
+
},
|
|
52
|
+
filter: {},
|
|
53
|
+
table: {}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 处理默认值
|
|
58
|
+
return {
|
|
59
|
+
template: {
|
|
60
|
+
cn: pageConfig.template?.cn || '列表页面',
|
|
61
|
+
en: pageConfig.template?.en || 'list',
|
|
62
|
+
top: pageConfig.template?.top ?? false,
|
|
63
|
+
bottom: pageConfig.template?.bottom ?? false,
|
|
64
|
+
select: pageConfig.template?.select ?? false,
|
|
65
|
+
btn: pageConfig.template?.btn || [],
|
|
66
|
+
...pageConfig.template
|
|
67
|
+
},
|
|
68
|
+
filter: pageConfig.filter || {},
|
|
69
|
+
table: pageConfig.table || {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
processTemplateConfig,
|
|
75
|
+
processPageConfig
|
|
76
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transformers 统一入口
|
|
3
|
+
* 导出所有转换逻辑方法
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导出筛选器转换
|
|
7
|
+
const { transformFilter, generateFieldName } = require('./transformFilter');
|
|
8
|
+
|
|
9
|
+
// 导出表格转换
|
|
10
|
+
const { transformTable } = require('./transformTable');
|
|
11
|
+
|
|
12
|
+
// 导出列表页面转换
|
|
13
|
+
const { transformList } = require('./transformList');
|
|
14
|
+
|
|
15
|
+
// 导出路由转换
|
|
16
|
+
const { transformRoutes } = require('./transformRoutes');
|
|
17
|
+
|
|
18
|
+
// 导出 Mock 数据转换
|
|
19
|
+
const { transformMock } = require('./transformMock');
|
|
20
|
+
|
|
21
|
+
// 导出渲染列表页面
|
|
22
|
+
const { renderLists } = require('./renderLists');
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
// 筛选器相关
|
|
26
|
+
transformFilter,
|
|
27
|
+
generateFieldName,
|
|
28
|
+
|
|
29
|
+
// 表格相关
|
|
30
|
+
transformTable,
|
|
31
|
+
|
|
32
|
+
// 列表页面相关
|
|
33
|
+
transformList,
|
|
34
|
+
|
|
35
|
+
// 路由相关
|
|
36
|
+
transformRoutes,
|
|
37
|
+
|
|
38
|
+
// Mock 数据相关
|
|
39
|
+
transformMock,
|
|
40
|
+
|
|
41
|
+
// 渲染相关
|
|
42
|
+
renderLists
|
|
43
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 渲染列表页面的主入口
|
|
3
|
+
* 协调各个转换模块,生成完整的页面文件
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导入转换模块
|
|
7
|
+
const { processTemplateConfig, processPageConfig } = require('./getInput');
|
|
8
|
+
const { getSfcMaterial, getTransformersByType } = require('./sfcMaterial');
|
|
9
|
+
const { transformList } = require('./transformList');
|
|
10
|
+
const { transformRoutes } = require('./transformRoutes');
|
|
11
|
+
const { transformMock } = require('./transformMock');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 渲染列表页面
|
|
15
|
+
* @param {Object} config - 模板配置
|
|
16
|
+
* @returns {Object} 生成的文件内容
|
|
17
|
+
*/
|
|
18
|
+
function renderLists(config) {
|
|
19
|
+
// 处理模板配置
|
|
20
|
+
const processedConfig = processTemplateConfig(config);
|
|
21
|
+
|
|
22
|
+
// 获取模板类型
|
|
23
|
+
const templateType = processedConfig.templateType;
|
|
24
|
+
|
|
25
|
+
// 获取组件材料
|
|
26
|
+
const material = getSfcMaterial(templateType);
|
|
27
|
+
|
|
28
|
+
// 获取转换函数
|
|
29
|
+
const transformers = getTransformersByType(templateType);
|
|
30
|
+
|
|
31
|
+
const results = {
|
|
32
|
+
pages: {},
|
|
33
|
+
routes: null,
|
|
34
|
+
mock: {}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// 处理每个页面
|
|
38
|
+
const pages = processedConfig.pages;
|
|
39
|
+
for (const [pageName, pageConfig] of Object.entries(pages)) {
|
|
40
|
+
// 处理页面配置
|
|
41
|
+
const processedPageConfig = processPageConfig(pageConfig);
|
|
42
|
+
const { template, filter, table } = processedPageConfig;
|
|
43
|
+
|
|
44
|
+
// 生成 Vue 文件内容
|
|
45
|
+
const vueContent = transformList(template, filter, table, material);
|
|
46
|
+
results.pages[pageName] = {
|
|
47
|
+
content: vueContent,
|
|
48
|
+
fileName: `${template.en}.vue`
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// 生成 Mock 数据(如果需要)
|
|
52
|
+
if (processedConfig.mock) {
|
|
53
|
+
const mockContent = transformMock(template);
|
|
54
|
+
results.mock[pageName] = {
|
|
55
|
+
content: mockContent,
|
|
56
|
+
fileName: `${template.en}.mock.js`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 生成路由配置(如果需要)
|
|
62
|
+
if (processedConfig.routes?.isRender) {
|
|
63
|
+
const routesContent = transformRoutes(processedConfig);
|
|
64
|
+
results.routes = {
|
|
65
|
+
content: routesContent,
|
|
66
|
+
fileName: 'routes.js'
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return results;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 渲染单个页面
|
|
75
|
+
* @param {Object} pageConfig - 页面配置
|
|
76
|
+
* @param {string} templateType - 模板类型
|
|
77
|
+
* @returns {string} Vue 文件内容
|
|
78
|
+
*/
|
|
79
|
+
function renderSinglePage(pageConfig, templateType = 'element-ui') {
|
|
80
|
+
// 处理页面配置
|
|
81
|
+
const processedPageConfig = processPageConfig(pageConfig);
|
|
82
|
+
const { template, filter, table } = processedPageConfig;
|
|
83
|
+
|
|
84
|
+
// 获取组件材料
|
|
85
|
+
const material = getSfcMaterial(templateType);
|
|
86
|
+
|
|
87
|
+
// 生成 Vue 文件内容
|
|
88
|
+
return transformList(template, filter, table, material);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
renderLists,
|
|
93
|
+
renderSinglePage
|
|
94
|
+
};
|