jjb-cmd 2.5.3 → 2.5.4

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/src/publish.js CHANGED
@@ -1 +1,307 @@
1
- function a5_0xb4a2(){const _0x273e46=['platform','stringify','thumbnailPath','28088522XhjyCA','\x20\x201.\x20已充分测试组件各项功能','暴露的配置信息中缺少\x22settings\x22!','input','组件发布失败!根目录缺少\x27package.json\x27文件!','110BNJpaC','项目构建完成','8QsJlvQ','username','发布失败\x20(','2xHaQpx','post','):\x20','path','catch','未检测到认证信息,请先执行登录操作','网络连接失败:\x20无法连接到服务器或服务器无响应','组件配置解析完成','no\x20message','182421btxDzs','request','发布错误可能导致线上应用产生严重生产故障,请务必确保:','\x20秒...\x20\x20','正在提交发布请求...','dist','message','readmePath','base64','parse','prompt','status','9783872zoWFYS','\x20\x205.\x20发布成功后请立即通知相关人员进行测试和验证','exit','yarn.lock','join','defaultSetting','exports','发布操作已取消','文件验证通过','正在处理缩略图...','未知错误','):\x20认证信息无效或无权限','data','length','../package.json','请在组件根目录添加一个README.md说明文件!','then','match','项目构建失败:\x20','暴露的配置信息中缺少\x22info\x22!','我已充分了解以上可能存在的严重风险,确认继续发布操作?','./config','1626159Zfsneg','assign','836559fxolCg','发布失败:\x20','toString','index.js','组件发布成功','response','distPath','return\x20','请输入此次组件发布的信息:','2718272mJlRdC','inquirer','confirmed','confirm','resolve','认证信息加载成功','服务器授权成功','请求失败\x20(','stdout','write','2589738NEVwWk','\x0d倒计时\x20','网络连接失败:\x20无法连接到服务器','正在验证发布所需文件...','5sfyAHb','thumbnail_base64','组件发布失败!根目录缺少\x27dist/index.js\x27文件!','/api/auth','binary','msg','正在准备发布数据...','password','README.md','thumbnail.png','正在加载认证信息...','正在请求服务器授权...','./utils'];a5_0xb4a2=function(){return _0x273e46;};return a5_0xb4a2();}const a5_0x24e10c=a5_0x213b;(function(_0x1b07d5,_0x135ab1){const _0x36fed0=a5_0x213b,_0x18927f=_0x1b07d5();while(!![]){try{const _0x2dd07a=parseInt(_0x36fed0(0x1c4))/0x1*(-parseInt(_0x36fed0(0x197))/0x2)+parseInt(_0x36fed0(0x1c2))/0x3*(parseInt(_0x36fed0(0x194))/0x4)+-parseInt(_0x36fed0(0x1db))/0x5*(parseInt(_0x36fed0(0x1d7))/0x6)+-parseInt(_0x36fed0(0x1ac))/0x7+-parseInt(_0x36fed0(0x1cd))/0x8+parseInt(_0x36fed0(0x1a0))/0x9*(parseInt(_0x36fed0(0x192))/0xa)+parseInt(_0x36fed0(0x18d))/0xb;if(_0x2dd07a===_0x135ab1)break;else _0x18927f['push'](_0x18927f['shift']());}catch(_0x45a2e0){_0x18927f['push'](_0x18927f['shift']());}}}(a5_0xb4a2,0xd0b79));function a5_0x213b(_0x2409ad,_0x574ae7){const _0xb4a293=a5_0xb4a2();return a5_0x213b=function(_0x213b74,_0x54c4ea){_0x213b74=_0x213b74-0x17f;let _0x40d82a=_0xb4a293[_0x213b74];return _0x40d82a;},a5_0x213b(_0x2409ad,_0x574ae7);}const path=require(a5_0x24e10c(0x19a)),os=require('os'),axios=require('axios'),inquirer=require(a5_0x24e10c(0x1ce)),{getApiHost}=require(a5_0x24e10c(0x1c1)),{CONSTANTS,logInfo,logSuccess,logWarning,logError,executeCommand,fileExists,readFile,writeFile}=require(a5_0x24e10c(0x189)),{loadAuth}=require('./crypto-utils');function parseComponentConfig(_0x4060ac){const _0x40e7b3=a5_0x24e10c,_0x3515aa=_0x4060ac['match'](/(window\[).+?(\.componentKey|.+]={)/img);if(!_0x3515aa||!_0x3515aa[_0x40e7b3(0x1b9)])throw new Error('请在组件入口文件中添加\x22window[props.componentKey]\x22以暴露组件的配置信息!');const _0x5474a6={},_0x4f3a5e=_0x4060ac[_0x40e7b3(0x1bd)](/componentKey.+([{,]info:\s{0,}{)/img);if(!_0x4f3a5e||!_0x4f3a5e[_0x40e7b3(0x1b9)])throw new Error(_0x40e7b3(0x1bf));let _0x352f97='{';const _0x3417df=_0x4060ac['split'](_0x4f3a5e[0x0])[0x1];for(let _0x97525b=0x0;_0x97525b<_0x3417df[_0x40e7b3(0x1b9)];_0x97525b++){_0x352f97+=_0x3417df[_0x97525b];if(_0x3417df[_0x97525b]==='}'){try{const _0x3a8a=new Function('return\x20'+_0x352f97)();Object[_0x40e7b3(0x1c3)](_0x5474a6,_0x3a8a),_0x5474a6['defaultSetting']={};}catch(_0x574ff5){}break;}}const _0x4bc1e0=_0x4060ac[_0x40e7b3(0x1bd)](/componentKey.+([{,]settings:\s{0,}{)/img);if(!_0x4bc1e0||!_0x4bc1e0[_0x40e7b3(0x1b9)])throw new Error(_0x40e7b3(0x18f));let _0x5ef49d='{';const _0x499aa6=_0x4060ac['split'](_0x4bc1e0[0x0])[0x1];for(let _0x474f46=0x0;_0x474f46<_0x499aa6[_0x40e7b3(0x1b9)];_0x474f46++){_0x5ef49d+=_0x499aa6[_0x474f46];if(_0x499aa6[_0x474f46]==='}'){try{_0x5474a6[_0x40e7b3(0x1b1)]=new Function(_0x40e7b3(0x1cb)+_0x5ef49d)();}catch(_0x33dd25){}break;}}return JSON[_0x40e7b3(0x18b)](_0x5474a6);}function executeBuild(_0x25ae93){const _0x4924b8=a5_0x24e10c,_0x1e9689=path[_0x4924b8(0x1b0)](_0x25ae93,_0x4924b8(0x1af));fileExists(_0x1e9689)?executeCommand('yarn\x20build:production',_0x25ae93):executeCommand('npm\x20run\x20build:production',_0x25ae93);}function validateRequiredFiles(_0x345598){const _0x55f8dd=a5_0x24e10c,_0x486931=path[_0x55f8dd(0x1b0)](_0x345598,_0x55f8dd(0x185)),_0x335b6c=path[_0x55f8dd(0x1b0)](_0x345598,_0x55f8dd(0x1a5),_0x55f8dd(0x1c7)),_0x35fe46=path[_0x55f8dd(0x1b0)](_0x345598,'package.json'),_0x3023b3=path[_0x55f8dd(0x1b0)](_0x345598,_0x55f8dd(0x186));if(!fileExists(_0x35fe46))throw new Error(_0x55f8dd(0x191));if(!fileExists(_0x335b6c))throw new Error(_0x55f8dd(0x17f));if(!fileExists(_0x486931))throw new Error(_0x55f8dd(0x1bb));if(!fileExists(_0x3023b3))throw new Error('请在组件根目录为组件添加一个缩略图\x22thumbnail.png\x22文件!');return{'readmePath':_0x486931,'distPath':_0x335b6c,'packageJsonPath':_0x35fe46,'thumbnailPath':_0x3023b3};}const submitFun=function(_0x569bac,_0x17c09e){const _0x1fa526=a5_0x24e10c;_0x17c09e[_0x1fa526(0x1a6)]=_0x569bac||_0x1fa526(0x19f),axios[_0x1fa526(0x198)](getApiHost()+'/api/file/publish',_0x17c09e)[_0x1fa526(0x1bc)](_0x4d83d3=>{const _0x27a104=_0x1fa526;logSuccess(_0x4d83d3['data'][_0x27a104(0x1a6)]||_0x27a104(0x1c8)),process[_0x27a104(0x1ae)](0x0);})[_0x1fa526(0x19b)](_0x2722b5=>{const _0x56fe94=_0x1fa526;if(_0x2722b5&&_0x2722b5['response']){const _0x5a51e9=_0x2722b5['response'][_0x56fe94(0x1ab)],_0x47fefb=_0x2722b5[_0x56fe94(0x1c9)][_0x56fe94(0x1b8)]&&(_0x2722b5[_0x56fe94(0x1c9)][_0x56fe94(0x1b8)][_0x56fe94(0x1a6)]||_0x2722b5[_0x56fe94(0x1c9)][_0x56fe94(0x1b8)][_0x56fe94(0x182)])||'';logError(_0x56fe94(0x196)+_0x5a51e9+_0x56fe94(0x199)+(_0x47fefb||_0x2722b5[_0x56fe94(0x1a6)]));}else _0x2722b5&&_0x2722b5[_0x56fe94(0x1a1)]?logError(_0x56fe94(0x1d9)):logError(_0x56fe94(0x1c5)+(_0x2722b5[_0x56fe94(0x1a6)]||'未知错误'));process[_0x56fe94(0x1ae)](0x1);});};module[a5_0x24e10c(0x1b2)]=_0x5eafb0=>{const _0x3d55bf=a5_0x24e10c,_0x277976=path['join'](__dirname,'../.auth');!fileExists(_0x277976)&&(logError(_0x3d55bf(0x19c)),process[_0x3d55bf(0x1ae)](0x1));let _0x49a14d,_0x3d45db;try{logInfo(_0x3d55bf(0x187));const _0x3a8d8f=loadAuth(_0x277976);_0x49a14d=_0x3a8d8f[_0x3d55bf(0x195)],_0x3d45db=_0x3a8d8f[_0x3d55bf(0x184)],logSuccess(_0x3d55bf(0x1d2));}catch(_0x4e6e9f){logError('读取认证信息失败:\x20'+_0x4e6e9f[_0x3d55bf(0x1a6)]),process[_0x3d55bf(0x1ae)](0x1);}logInfo(_0x3d55bf(0x188)),axios[_0x3d55bf(0x198)](getApiHost()+_0x3d55bf(0x180),{'username':_0x49a14d,'password':_0x3d45db})[_0x3d55bf(0x1bc)](async _0x446d37=>{const _0x36b2c1=_0x3d55bf;if(_0x446d37[_0x36b2c1(0x1b8)]['status']){logSuccess(_0x36b2c1(0x1d3));const _0xe1269a=path[_0x36b2c1(0x1d1)]('./');logInfo('正在执行项目构建...');try{executeBuild(_0xe1269a),logSuccess(_0x36b2c1(0x193));}catch(_0x554b72){logError(_0x36b2c1(0x1be)+_0x554b72[_0x36b2c1(0x1a6)]),process[_0x36b2c1(0x1ae)](0x1);}logInfo(_0x36b2c1(0x1da));let _0x105cae;try{_0x105cae=validateRequiredFiles(_0xe1269a),logSuccess(_0x36b2c1(0x1b4));}catch(_0x2a15b4){logError(_0x2a15b4[_0x36b2c1(0x1a6)]),process[_0x36b2c1(0x1ae)](0x1);}logInfo('正在读取包信息...');const _0x54259c=JSON[_0x36b2c1(0x1a9)](readFile(path[_0x36b2c1(0x1b0)](__dirname,_0x36b2c1(0x1ba)))),{version:_0x189ab6}=_0x54259c;logInfo(_0x36b2c1(0x183));const _0x37a147={'username':_0x49a14d,'cmd_version':_0x189ab6,'hostname':os['hostname'](),'platform':os[_0x36b2c1(0x18a)](),'package_version':_0x5eafb0||0x0,'package_content':readFile(_0x105cae[_0x36b2c1(0x1ca)]),'readme_content':readFile(_0x105cae[_0x36b2c1(0x1a7)])};try{logInfo('正在解析组件配置信息...');const _0x31ae41=readFile(_0x105cae[_0x36b2c1(0x1ca)]);_0x37a147['component_config_content']=parseComponentConfig(_0x31ae41),logSuccess(_0x36b2c1(0x19e));}catch(_0x157dcb){logError(_0x157dcb['message']),process['exit'](0x1);}logInfo(_0x36b2c1(0x1b5));const _0x4897ef=readFile(_0x105cae[_0x36b2c1(0x18c)],_0x36b2c1(0x181));_0x37a147[_0x36b2c1(0x1dc)]=Buffer['from'](_0x4897ef,_0x36b2c1(0x181))[_0x36b2c1(0x1c6)](_0x36b2c1(0x1a8)),logSuccess('缩略图处理完成'),logWarning('警告:您即将进行组件发布操作,此操作不可逆,请谨慎操作'),logWarning(_0x36b2c1(0x1a2)),logWarning(_0x36b2c1(0x18e)),logWarning('\x20\x202.\x20已检查构建产物完整性'),logWarning('\x20\x203.\x20已确认版本号和发布信息正确'),logWarning('\x20\x204.\x20已了解发布后的影响范围'),logWarning(_0x36b2c1(0x1ad)),await new Promise(_0x3d62ae=>{let _0x3251d3=0xa;const _0x436c80=setInterval(()=>{const _0x4ad1ab=a5_0x213b;process[_0x4ad1ab(0x1d5)][_0x4ad1ab(0x1d6)](_0x4ad1ab(0x1d8)+_0x3251d3+_0x4ad1ab(0x1a3)),_0x3251d3--,_0x3251d3<0x0&&(clearInterval(_0x436c80),process['stdout'][_0x4ad1ab(0x1d6)]('\x0d\x0a'),_0x3d62ae());},0x3e8);});const {confirmed:_0x33a235}=await inquirer[_0x36b2c1(0x1aa)]([{'type':_0x36b2c1(0x1d0),'name':_0x36b2c1(0x1cf),'message':_0x36b2c1(0x1c0),'default':![]}]);!_0x33a235&&(logInfo(_0x36b2c1(0x1b3)),process[_0x36b2c1(0x1ae)](0x0));const {message:_0x5a62e8}=await inquirer[_0x36b2c1(0x1aa)]([{'type':_0x36b2c1(0x190),'name':_0x36b2c1(0x1a6),'message':_0x36b2c1(0x1cc),'default':_0x36b2c1(0x19f)}]);logInfo(_0x36b2c1(0x1a4)),submitFun(_0x5a62e8||_0x36b2c1(0x19f),_0x37a147);}else logError('授权失败:\x20'+(_0x446d37[_0x36b2c1(0x1b8)][_0x36b2c1(0x1a6)]||_0x36b2c1(0x1b6))),process[_0x36b2c1(0x1ae)](0x1);})[_0x3d55bf(0x19b)](_0x16c4b7=>{const _0x86db5c=_0x3d55bf;if(_0x16c4b7&&_0x16c4b7[_0x86db5c(0x1c9)]){const _0x1eb3e6=_0x16c4b7[_0x86db5c(0x1c9)][_0x86db5c(0x1ab)];if(_0x1eb3e6===0x191||_0x1eb3e6===0x193)logError('授权失败\x20('+_0x1eb3e6+_0x86db5c(0x1b7));else{const _0x207642=_0x16c4b7[_0x86db5c(0x1c9)]['data']&&(_0x16c4b7[_0x86db5c(0x1c9)]['data'][_0x86db5c(0x1a6)]||_0x16c4b7[_0x86db5c(0x1c9)][_0x86db5c(0x1b8)][_0x86db5c(0x182)])||'';logError(_0x86db5c(0x1d4)+_0x1eb3e6+_0x86db5c(0x199)+(_0x207642||_0x16c4b7['message']));}}else _0x16c4b7&&_0x16c4b7[_0x86db5c(0x1a1)]?logError(_0x86db5c(0x19d)):logError('操作失败:\x20'+(_0x16c4b7?_0x16c4b7['message']:_0x86db5c(0x1b6)));process[_0x86db5c(0x1ae)](0x1);});};
1
+ const path = require('path');
2
+ const os = require('os');
3
+ const axios = require('axios');
4
+ const inquirer = require('inquirer');
5
+ const { getApiHost } = require('./config');
6
+ const {
7
+ CONSTANTS,
8
+ logInfo,
9
+ logSuccess,
10
+ logWarning,
11
+ logError,
12
+ executeCommand,
13
+ fileExists,
14
+ readFile,
15
+ writeFile
16
+ } = require('./utils');
17
+ const { loadAuth } = require('./crypto-utils');
18
+
19
+ /**
20
+ * 解析组件配置信息
21
+ * @param {string} distContent - 构建后的文件内容
22
+ * @returns {Object} 解析后的配置信息
23
+ */
24
+ function parseComponentConfig(distContent) {
25
+ const matches = distContent.match(/(window\[).+?(\.componentKey|.+]={)/img);
26
+ if (!matches || !matches.length) {
27
+ throw new Error('请在组件入口文件中添加"window[props.componentKey]"以暴露组件的配置信息!');
28
+ }
29
+
30
+ const componentConfig = {};
31
+
32
+ // 解析 info 配置
33
+ const infoMatches = distContent.match(/componentKey.+([{,]info:\s{0,}{)/img);
34
+ if (!infoMatches || !infoMatches.length) {
35
+ throw new Error('暴露的配置信息中缺少"info"!');
36
+ }
37
+
38
+ let infoStr = '{';
39
+ const infoStr1 = distContent.split(infoMatches[0])[1];
40
+ for (let i = 0; i < infoStr1.length; i++) {
41
+ infoStr += infoStr1[i];
42
+ if (infoStr1[i] === '}') {
43
+ try {
44
+ const currJson = new Function(`return ${infoStr}`)();
45
+ Object.assign(componentConfig, currJson);
46
+ componentConfig.defaultSetting = {};
47
+ } catch (e) {
48
+ // 忽略解析错误
49
+ }
50
+ break;
51
+ }
52
+ }
53
+
54
+ // 解析 settings 配置
55
+ const settingsMatches = distContent.match(/componentKey.+([{,]settings:\s{0,}{)/img);
56
+ if (!settingsMatches || !settingsMatches.length) {
57
+ throw new Error('暴露的配置信息中缺少"settings"!');
58
+ }
59
+
60
+ let settingsStr = '{';
61
+ const settingsStr1 = distContent.split(settingsMatches[0])[1];
62
+ for (let i = 0; i < settingsStr1.length; i++) {
63
+ settingsStr += settingsStr1[i];
64
+ if (settingsStr1[i] === '}') {
65
+ try {
66
+ componentConfig.defaultSetting = new Function(`return ${settingsStr}`)();
67
+ } catch (e) {
68
+ // 忽略解析错误
69
+ }
70
+ break;
71
+ }
72
+ }
73
+
74
+ return JSON.stringify(componentConfig);
75
+ }
76
+
77
+ /**
78
+ * 执行构建命令
79
+ * @param {string} rootPath - 项目根路径
80
+ */
81
+ function executeBuild(rootPath) {
82
+ const yarnLockPath = path.join(rootPath, 'yarn.lock');
83
+ if (fileExists(yarnLockPath)) {
84
+ executeCommand('yarn build:production', rootPath);
85
+ } else {
86
+ executeCommand('npm run build:production', rootPath);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * 验证必要的文件
92
+ * @param {string} rootPath - 项目根路径
93
+ * @returns {Object} 验证结果和文件路径
94
+ */
95
+ function validateRequiredFiles(rootPath) {
96
+ const readmePath = path.join(rootPath, 'README.md');
97
+ const distPath = path.join(rootPath, 'dist', 'index.js');
98
+ const packageJsonPath = path.join(rootPath, 'package.json');
99
+ const thumbnailPath = path.join(rootPath, 'thumbnail.png');
100
+
101
+ if (!fileExists(packageJsonPath)) {
102
+ throw new Error('组件发布失败!根目录缺少\'package.json\'文件!');
103
+ }
104
+
105
+ if (!fileExists(distPath)) {
106
+ throw new Error('组件发布失败!根目录缺少\'dist/index.js\'文件!');
107
+ }
108
+
109
+ if (!fileExists(readmePath)) {
110
+ throw new Error('请在组件根目录添加一个README.md说明文件!');
111
+ }
112
+
113
+ if (!fileExists(thumbnailPath)) {
114
+ throw new Error('请在组件根目录为组件添加一个缩略图"thumbnail.png"文件!');
115
+ }
116
+
117
+ return {
118
+ readmePath,
119
+ distPath,
120
+ packageJsonPath,
121
+ thumbnailPath
122
+ };
123
+ }
124
+
125
+ /**
126
+ * 提交发布数据
127
+ * @param {string} message - 发布消息
128
+ * @param {Object} pushData - 发布数据
129
+ */
130
+ const submitFun = function (message, pushData) {
131
+ pushData.message = message || 'no message';
132
+ axios.post(`${getApiHost()}/api/file/publish`, pushData).then(res => {
133
+ logSuccess(res.data.message || '组件发布成功');
134
+ process.exit(0);
135
+ }).catch(e => {
136
+ if (e && e.response) {
137
+ const status = e.response.status;
138
+ const serverMsg = (e.response.data && (e.response.data.message || e.response.data.msg)) || '';
139
+ logError(`发布失败 (${status}): ${serverMsg || e.message}`);
140
+ } else if (e && e.request) {
141
+ logError(`网络连接失败: 无法连接到服务器`);
142
+ } else {
143
+ logError(`发布失败: ${e.message || '未知错误'}`);
144
+ }
145
+ process.exit(1);
146
+ });
147
+ };
148
+
149
+ module.exports = version => {
150
+ const authPath = path.join(__dirname, '../.auth');
151
+
152
+ if (!fileExists(authPath)) {
153
+ logError('未检测到认证信息,请先执行登录操作');
154
+ process.exit(1);
155
+ }
156
+
157
+ // 安全读取认证信息
158
+ let username, password;
159
+ try {
160
+ logInfo('正在加载认证信息...');
161
+ const authData = loadAuth(authPath);
162
+ username = authData.username;
163
+ password = authData.password;
164
+ logSuccess('认证信息加载成功');
165
+ } catch (error) {
166
+ logError(`读取认证信息失败: ${error.message}`);
167
+ process.exit(1);
168
+ }
169
+
170
+ logInfo('正在请求服务器授权...');
171
+
172
+ axios.post(`${getApiHost()}/api/auth`, {
173
+ username,
174
+ password
175
+ }).then(async res => {
176
+ if (res.data.status) {
177
+ logSuccess('服务器授权成功');
178
+
179
+ const rootPath = path.resolve('./');
180
+
181
+ // 执行构建
182
+ logInfo('正在执行项目构建...');
183
+ try {
184
+ executeBuild(rootPath);
185
+ logSuccess('项目构建完成');
186
+ } catch (error) {
187
+ logError(`项目构建失败: ${error.message}`);
188
+ process.exit(1);
189
+ }
190
+
191
+ // 验证必要文件
192
+ logInfo('正在验证发布所需文件...');
193
+ let filePaths;
194
+ try {
195
+ filePaths = validateRequiredFiles(rootPath);
196
+ logSuccess('文件验证通过');
197
+ } catch (error) {
198
+ logError(error.message);
199
+ process.exit(1);
200
+ }
201
+
202
+ // 读取包信息
203
+ logInfo('正在读取包信息...');
204
+ const packageJsonFile = JSON.parse(readFile(path.join(__dirname, '../package.json')));
205
+ const { version: cmdVersion } = packageJsonFile;
206
+
207
+ // 准备发布数据
208
+ logInfo('正在准备发布数据...');
209
+ const pushData = {
210
+ username,
211
+ cmd_version: cmdVersion,
212
+ hostname: os.hostname(),
213
+ platform: os.platform(),
214
+ package_version: version || 0,
215
+ package_content: readFile(filePaths.distPath),
216
+ readme_content: readFile(filePaths.readmePath)
217
+ };
218
+
219
+ // 解析组件配置
220
+ try {
221
+ logInfo('正在解析组件配置信息...');
222
+ const distContent = readFile(filePaths.distPath);
223
+ pushData.component_config_content = parseComponentConfig(distContent);
224
+ logSuccess('组件配置解析完成');
225
+ } catch (error) {
226
+ logError(error.message);
227
+ process.exit(1);
228
+ }
229
+
230
+ // 处理缩略图
231
+ logInfo('正在处理缩略图...');
232
+ const thumbnailData = readFile(filePaths.thumbnailPath, 'binary');
233
+ pushData.thumbnail_base64 = Buffer.from(thumbnailData, 'binary').toString('base64');
234
+ logSuccess('缩略图处理完成');
235
+
236
+ // 危险操作警告确认
237
+ logWarning('警告:您即将进行组件发布操作,此操作不可逆,请谨慎操作');
238
+ logWarning('发布错误可能导致线上应用产生严重生产故障,请务必确保:');
239
+ logWarning(' 1. 已充分测试组件各项功能');
240
+ logWarning(' 2. 已检查构建产物完整性');
241
+ logWarning(' 3. 已确认版本号和发布信息正确');
242
+ logWarning(' 4. 已了解发布后的影响范围');
243
+ logWarning(' 5. 发布成功后请立即通知相关人员进行测试和验证');
244
+
245
+ await new Promise((resolve) => {
246
+ let countdown = 10;
247
+ const interval = setInterval(() => {
248
+ process.stdout.write(`\r倒计时 ${countdown} 秒... `);
249
+ countdown--;
250
+ if (countdown < 0) {
251
+ clearInterval(interval);
252
+ process.stdout.write('\r\n');
253
+ resolve();
254
+ }
255
+ }, 1000);
256
+ });
257
+
258
+ const { confirmed } = await inquirer.prompt([
259
+ {
260
+ type: 'confirm',
261
+ name: 'confirmed',
262
+ message: '我已充分了解以上可能存在的严重风险,确认继续发布操作?',
263
+ default: false
264
+ }
265
+ ]);
266
+
267
+ if (!confirmed) {
268
+ logInfo('发布操作已取消');
269
+ process.exit(0);
270
+ }
271
+
272
+ // 提交发布
273
+ const { message } = await inquirer.prompt([
274
+ {
275
+ type: 'input',
276
+ name: 'message',
277
+ message: '请输入此次组件发布的信息:',
278
+ default: 'no message'
279
+ }
280
+ ]);
281
+
282
+ logInfo('正在提交发布请求...');
283
+ submitFun(message || 'no message', pushData);
284
+ } else {
285
+ logError(`授权失败: ${res.data.message || '未知错误'}`);
286
+ process.exit(1);
287
+ }
288
+ }).catch(e => {
289
+ // 更准确的错误分类,避免误导为授权问题
290
+ if (e && e.response) {
291
+ const status = e.response.status;
292
+ if (status === 401 || status === 403) {
293
+ logError(`授权失败 (${status}): 认证信息无效或无权限`);
294
+ } else {
295
+ const serverMsg = (e.response.data && (e.response.data.message || e.response.data.msg)) || '';
296
+ logError(`请求失败 (${status}): ${serverMsg || e.message}`);
297
+ }
298
+ } else if (e && e.request) {
299
+ // 请求已发出但未收到响应,多为网络问题
300
+ logError(`网络连接失败: 无法连接到服务器或服务器无响应`);
301
+ } else {
302
+ // 触发请求前发生的错误
303
+ logError(`操作失败: ${e ? e.message : '未知错误'}`);
304
+ }
305
+ process.exit(1);
306
+ });
307
+ };