neo-cmp-cli 1.7.5-beta.1 → 1.7.5-beta.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo-cmp-cli",
3
- "version": "1.7.5-beta.1",
3
+ "version": "1.7.5-beta.2",
4
4
  "description": "前端脚手架:自定义组件开发工具,支持react 和 vue2.0技术栈。",
5
5
  "keywords": [
6
6
  "neo-cli",
@@ -1,23 +1,25 @@
1
1
  const curConfig = require('../config/index'); // 获取当前项目根目录下的配置文件
2
2
 
3
- const authConfig = curConfig.neoConfig || {};
3
+ const neoConfig = curConfig.neoConfig || {};
4
+ const authConfig = neoConfig.auth || {};
4
5
 
5
6
  // NeoCRM 跨 Pod 授权配置
6
7
  module.exports = {
7
- loginURL: authConfig.loginURL || 'https://login-cd.xiaoshouyi.com/auc/oauth2/auth', // 登录 URL,从创建连接器的客户端信息中获取(Login_Url)
8
- tokenAPI: authConfig.tokenAPI || 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
8
+ loginURL: neoConfig.loginURL || 'https://login-cd.xiaoshouyi.com/auc/oauth2/auth', // 登录 URL,从创建连接器的客户端信息中获取(Login_Url)
9
+ tokenAPI: neoConfig.tokenAPI || 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
10
+ redirectUri: neoConfig.redirectUri || 'http://localhost:1028', // 固定端口号,用于接收授权码
9
11
  // 重定向 URI,动态生成
10
12
  getRedirectURI: (port) => {
11
13
  return `http://localhost:${port}`;
12
14
  },
13
15
  // 获取 授权码 相关配置
14
16
  response_type: 'code', // 认证类型;此参数值必须为 code
15
- client_id: '04c8b45c4dbe36426a660bf70d3fe3e7', // 客户端 ID,跨 Pod 级链接器【内置】
17
+ client_id: authConfig.client_id || '04c8b45c4dbe36426a660bf70d3fe3e7', // 客户端 ID,跨 Pod 级链接器【内置】
16
18
  scope: 'all', // 固定值:all
17
19
  oauthType: 'standard', // 固定值:standard
18
20
  access_type: 'offline', // 此参数值为 online 时,不产生 refresh_token ;此参数值为 offline 时,返回refresh_token
19
21
 
20
22
  // 获取 令牌 相关配置
21
- client_secret: '370817d1336a3737f95c671eea39a23b', // 客户端秘钥,跨 Pod 级链接器【内置】
23
+ client_secret: authConfig.client_secret || '370817d1336a3737f95c671eea39a23b', // 客户端秘钥,跨 Pod 级链接器【内置】
22
24
  grant_type: 'authorization_code' // 授权类型;此参数值必须为 authorization_code
23
25
  };
@@ -12,10 +12,10 @@ const mainAction = require('./main.js'); // 入口文件
12
12
  const getCmpTypeByDir = require('../utils/cmpUtils/getCmpTypeByDir.js');
13
13
  const NeoService = require('../neo/neoService.js');
14
14
  const NeoLoginService = require('../neo/neoLogin.js');
15
- const authConfig = require('../config/auth.config.js');
16
15
  const curConfig = require('../config/index'); // 获取当前项目根目录下的配置文件
17
16
  const hasNeoProject = require('../utils/projectUtils/hasNeoProject.js');
18
17
  const consoleTag = require('../utils/neoParams').consoleTag;
18
+ const { errorLog, successLog } = require('../utils/common');
19
19
  // neo 的 package 文件
20
20
  const neoPackage = require('../../package.json');
21
21
 
@@ -59,7 +59,7 @@ yargs
59
59
  (argv) => {
60
60
  if (argv.type && argv.name) {
61
61
  if (hasNeoProject()) {
62
- console.error(
62
+ errorLog(
63
63
  `${consoleTag}创建自定义组件失败,当前目录(${process.cwd()})已经是一个自定义组件项目,请勿重复创建。`
64
64
  );
65
65
  process.exit(1);
@@ -137,7 +137,7 @@ yargs
137
137
  // 验证项目名称是否合法
138
138
  const { isValid, errors } = validateProjectName(ans.name);
139
139
  if (!isValid) {
140
- console.error(errors.join('\n'));
140
+ errorLog(errors.join('\n'));
141
141
  process.exit(1);
142
142
  }
143
143
 
@@ -174,10 +174,10 @@ yargs
174
174
  },
175
175
  async () => {
176
176
  try {
177
- const loginService = new NeoLoginService(authConfig);
177
+ const loginService = new NeoLoginService(curConfig.neoConfig);
178
178
  await loginService.login();
179
179
  } catch (error) {
180
- console.error(chalk.red(`\n登录失败: ${error.message}`));
180
+ errorLog(`\n登录失败: ${error.message}`);
181
181
  process.exit(1);
182
182
  }
183
183
  }
@@ -193,10 +193,10 @@ yargs
193
193
  },
194
194
  async () => {
195
195
  try {
196
- const loginService = new NeoLoginService(authConfig);
196
+ const loginService = new NeoLoginService(curConfig.neoConfig);
197
197
  await loginService.logout();
198
198
  } catch (error) {
199
- console.error(chalk.red(`\n登出失败: ${error.message}`));
199
+ errorLog(`\n登出失败: ${error.message}`);
200
200
  process.exit(1);
201
201
  }
202
202
  }
@@ -232,12 +232,12 @@ yargs
232
232
  // 验证项目名称是否合法
233
233
  const { isValid, errors } = validateProjectName(ans.name);
234
234
  if (!isValid) {
235
- console.error(errors.join('\n'));
235
+ errorLog(errors.join('\n'));
236
236
  process.exit(1);
237
237
  }
238
238
 
239
239
  if (!ans.name) {
240
- console.error('自定义组件项目名称不能为空。');
240
+ errorLog('自定义组件项目名称不能为空。');
241
241
  process.exit(1);
242
242
  } else {
243
243
  mainAction.createCmpProjectByTemplate(ans.name);
@@ -273,7 +273,7 @@ yargs
273
273
 
274
274
  inquirer.prompt(questions).then((ans) => {
275
275
  if (!ans.name) {
276
- console.error('自定义组件名称不能为空。');
276
+ errorLog('自定义组件名称不能为空。');
277
277
  process.exit(1);
278
278
  } else {
279
279
  mainAction.createCmpByTemplate(ans.name);
@@ -305,7 +305,7 @@ yargs
305
305
  const spinner = ora('正在拉取线上自定义组件列表...').start();
306
306
  const cmpList = await neoService.getCustomCmpList();
307
307
  if (cmpList.length === 0) {
308
- console.error('当前租户暂无任何自定义组件。');
308
+ errorLog('当前租户暂无任何自定义组件。');
309
309
  process.exit(1);
310
310
  }
311
311
  spinner.stop('线上自定义组件列表拉取成功。');
@@ -323,7 +323,7 @@ yargs
323
323
  ];
324
324
  inquirer.prompt(questions).then((ans) => {
325
325
  if (!ans.cmpType) {
326
- console.error('自定义组件名称不能为空。');
326
+ errorLog('自定义组件名称不能为空。');
327
327
  process.exit(1);
328
328
  } else {
329
329
  mainAction.pullCmp(ans.cmpType, neoService);
@@ -354,7 +354,7 @@ yargs
354
354
  const spinner = ora('正在获取线上自定义组件列表...').start();
355
355
  const cmpList = await neoService.getCustomCmpList();
356
356
  if (cmpList.length === 0) {
357
- console.error('当前租户暂无任何自定义组件。');
357
+ errorLog('当前租户暂无任何自定义组件。');
358
358
  process.exit(1);
359
359
  }
360
360
  spinner.stop('线上自定义组件列表获取成功。');
@@ -372,7 +372,7 @@ yargs
372
372
  ];
373
373
  inquirer.prompt(questions).then((ans) => {
374
374
  if (!ans.cmpType) {
375
- console.error('自定义组件名称不能为空。');
375
+ errorLog('自定义组件名称不能为空。');
376
376
  process.exit(1);
377
377
  } else {
378
378
  mainAction.deleteCmp(ans.cmpType, neoService);
@@ -400,7 +400,7 @@ yargs
400
400
  } else {
401
401
  const cmpTypes = getCmpTypeByDir();
402
402
  if (cmpTypes.length === 0) {
403
- console.error('当前自定义组件目录中未找到自定义组件。(./src/components 目录下)');
403
+ errorLog('当前自定义组件目录中未找到自定义组件。(./src/components 目录下)');
404
404
  process.exit(1);
405
405
  }
406
406
  const cmpTypeChoices = cmpTypes.map((cmpType) => ({
@@ -417,7 +417,7 @@ yargs
417
417
  ];
418
418
  inquirer.prompt(questions).then((ans) => {
419
419
  if (!ans.cmpType) {
420
- console.error('未选择要预览的自定义组件。');
420
+ errorLog('未选择要预览的自定义组件。');
421
421
  process.exit(1);
422
422
  }
423
423
  mainAction.previewCmp(ans.cmpType);
@@ -496,7 +496,7 @@ yargs
496
496
  } else {
497
497
  const cmpTypes = getCmpTypeByDir();
498
498
  if (cmpTypes.length === 0) {
499
- console.error('当前自定义组件目录中未找到自定义组件。(./src/components 目录下)');
499
+ errorLog('当前自定义组件目录中未找到自定义组件。(./src/components 目录下)');
500
500
  process.exit(1);
501
501
  }
502
502
  const cmpTypeChoices = cmpTypes.map((cmpType) => ({
@@ -513,7 +513,7 @@ yargs
513
513
  ];
514
514
  inquirer.prompt(questions).then((ans) => {
515
515
  if (!ans.cmpType) {
516
- console.error('未选择要发布的自定义组件。');
516
+ errorLog('未选择要发布的自定义组件。');
517
517
  process.exit(1);
518
518
  }
519
519
  mainAction.publish2oss(ans.cmpType);
@@ -540,7 +540,7 @@ yargs
540
540
  } else {
541
541
  const cmpTypes = getCmpTypeByDir();
542
542
  if (cmpTypes.length === 0) {
543
- console.error('当前自定义组件目录中未找到自定义组件。(./src/components 目录下)');
543
+ errorLog('当前自定义组件目录中未找到自定义组件。(./src/components 目录下)');
544
544
  process.exit(1);
545
545
  }
546
546
  const cmpTypeChoices = cmpTypes.map((cmpType) => ({
@@ -557,7 +557,7 @@ yargs
557
557
  ];
558
558
  inquirer.prompt(questions).then((ans) => {
559
559
  if (!ans.cmpType) {
560
- console.error('未选择要发布的自定义组件。');
560
+ errorLog('未选择要发布的自定义组件。');
561
561
  process.exit(1);
562
562
  }
563
563
  mainAction.pushCmp(ans.cmpType);
@@ -628,7 +628,7 @@ yargs
628
628
  .alias('v', 'version')
629
629
  .strict()
630
630
  .fail((msg, err, yargs) => {
631
- console.error(chalk.red(`\n运行命令时发生错误: ${msg}。\n`));
631
+ errorLog(`\n运行命令时发生错误: ${msg}。\n`);
632
632
  console.log(titleTip('当前可用命令列表:'));
633
633
  console.log('');
634
634
  // 定义所有可用命令及其描述
@@ -19,6 +19,7 @@ const createCmpProjectByTemplate = require('../utils/projectUtils/createCmpProje
19
19
  const pullCmp = require('../utils/cmpUtils/pullCmp');
20
20
  const deleteCmp = require('../utils/cmpUtils/deleteCmp');
21
21
  const openProject = require('../utils/projectUtils/openProject');
22
+ const { errorLog, successLog } = require('../utils/common');
22
23
 
23
24
  const getValue = (originValue, defaultValue) => {
24
25
  return originValue !== undefined ? originValue : defaultValue;
@@ -109,7 +110,7 @@ function setupEntries(config, options) {
109
110
  console.info('已自动生成 entry 入口配置:', entries);
110
111
  }
111
112
  } catch (error) {
112
- console.error(error.message);
113
+ errorLog(error.message);
113
114
  process.exit(1);
114
115
  }
115
116
 
@@ -155,7 +156,7 @@ module.exports = {
155
156
  createCmpByTemplate,
156
157
  dev: () => {
157
158
  if (!curConfig.dev) {
158
- console.error('未找到 dev 相关配置。');
159
+ errorLog('未找到 dev 相关配置。');
159
160
  process.exit(1);
160
161
  }
161
162
  akfun.dev(curConfig, consoleTag);
@@ -163,11 +164,11 @@ module.exports = {
163
164
  previewCmp: (cmpName) => {
164
165
  // 预览组件本身内容
165
166
  if (!cmpName) {
166
- console.error('请输入要预览的组件名称。');
167
+ errorLog('请输入要预览的组件名称。');
167
168
  process.exit(1);
168
169
  }
169
170
  if (!curConfig.preview) {
170
- console.error('未找到 preview 相关配置。');
171
+ errorLog('未找到 preview 相关配置。');
171
172
  process.exit(1);
172
173
  }
173
174
  curConfig.dev = Object.assign(curConfig.dev, curConfig.preview); // 将 preview 设置给 dev
@@ -178,7 +179,7 @@ module.exports = {
178
179
  linkDebug: () => {
179
180
  // 外链调试模式
180
181
  if (!curConfig.linkDebug) {
181
- console.error('未找到 debug 相关配置。');
182
+ errorLog('未找到 debug 相关配置。');
182
183
  process.exit(1);
183
184
  }
184
185
  // 将 linkDebug 设置给 dev
@@ -4,6 +4,7 @@ const { consoleTag } = require('../utils/neoParams'); // 输出标记
4
4
  const { replaceInPackage } = require('../utils/replaceInPackage');
5
5
  const { resetPackageVersion } = require('../utils/resetPackageVersion');
6
6
  const autoEntryRootDir = require('../utils/autoEntryRootDir');
7
+ const { errorLog } = require('../utils/common');
7
8
 
8
9
  const templateList = {
9
10
  react: {
@@ -14,7 +15,7 @@ const templateList = {
14
15
  projectName: 'react-ts-custom-cmp-template',
15
16
  dir: path.resolve(__dirname, '../template/react-ts-custom-cmp-template')
16
17
  },
17
- 'antd': {
18
+ antd: {
18
19
  projectName: 'antd-custom-cmp-template',
19
20
  dir: path.resolve(__dirname, '../template/antd-custom-cmp-template')
20
21
  },
@@ -22,7 +23,7 @@ const templateList = {
22
23
  projectName: 'echarts-custom-cmp-template',
23
24
  dir: path.resolve(__dirname, '../template/echarts-custom-cmp-template')
24
25
  },
25
- 'neo': {
26
+ neo: {
26
27
  projectName: 'neo-custom-cmp-template',
27
28
  dir: path.resolve(__dirname, '../template/neo-custom-cmp-template')
28
29
  },
@@ -54,7 +55,7 @@ const neoInitByCopy = function (type, projectName) {
54
55
  // 自动切换到项目根目录
55
56
  autoEntryRootDir(finalProjectPath);
56
57
  })
57
- .catch((err) => console.error(`${consoleTag}自定义组件模板下载失败:`, err));
58
+ .catch((err) => errorLog(`${consoleTag}自定义组件模板下载失败:`, err));
58
59
  };
59
60
 
60
61
  module.exports = neoInitByCopy;
@@ -5,6 +5,7 @@ const ora = require('ora');
5
5
  const http = require('http');
6
6
  const url = require('url');
7
7
  const open = require('open');
8
+ const net = require('net');
8
9
  const portfinder = require('portfinder');
9
10
  const { errorLog, successLog } = require('../utils/common');
10
11
  const neoAuthConfig = require('../config/auth.config');
@@ -119,7 +120,7 @@ class NeoLoginService {
119
120
  * @returns {string} 回调地址
120
121
  */
121
122
  getRedirectURI(port) {
122
- return `http://localhost:${port}/callback`;
123
+ return `http://localhost:${port}`;
123
124
  }
124
125
 
125
126
  /**
@@ -153,20 +154,71 @@ class NeoLoginService {
153
154
  }
154
155
  }
155
156
 
157
+ /**
158
+ * 检测端口是否被占用
159
+ * @param {number} port 端口号
160
+ * @returns {Promise<boolean>} true 表示端口被占用,false 表示端口可用
161
+ */
162
+ async isPortInUse(port) {
163
+ return new Promise((resolve) => {
164
+ const server = net.createServer();
165
+
166
+ server.once('error', (err) => {
167
+ if (err.code === 'EADDRINUSE') {
168
+ resolve(true); // 端口被占用
169
+ } else {
170
+ resolve(false); // 其他错误,假设端口可用
171
+ }
172
+ });
173
+
174
+ server.once('listening', () => {
175
+ // 端口可用,立即关闭服务器
176
+ server.once('close', () => {
177
+ resolve(false); // 端口可用
178
+ });
179
+ server.close();
180
+ });
181
+
182
+ server.listen(port);
183
+ });
184
+ }
185
+
156
186
  /**
157
187
  * 启动本地服务器接收授权码(code)
158
188
  * @returns {Promise<{redirectUri: string, codePromise: Promise<string>}>} 回调地址和授权码Promise
159
189
  */
160
190
  async startCallbackServer() {
161
- // 使用 portfinder 获取可用端口
162
- const port = await portfinder.getPortPromise({
163
- port: 8888, // 起始端口
164
- stopPort: 9999 // 结束端口
165
- });
191
+ let redirectUri = neoAuthConfig.redirectUri;
192
+ let redirectUrl = new URL(redirectUri);
193
+ let port = parseInt(redirectUrl.port, 10);
166
194
 
167
- // 使用获取到的端口生成 redirect_uri
168
- const redirectUri = this.getRedirectURI(port);
169
- const redirectUrl = new URL(redirectUri);
195
+ // 检测端口是否被占用
196
+ const portInUse = await this.isPortInUse(port);
197
+
198
+ if (portInUse) {
199
+ consoleError(
200
+ `\n警告: 端口 ${port} 已被占用,请调整 redirectUri 配置项,使其指向一个未被占用的端口。`
201
+ );
202
+ process.exit(1);
203
+ /*
204
+ // 使用 portfinder 查找可用端口
205
+ try {
206
+ port = await portfinder.getPortPromise({
207
+ port: port, // 从配置的端口开始查找
208
+ stopPort: 9999 // 结束端口
209
+ });
210
+
211
+ // 更新 redirectUri 和 redirectUrl
212
+ redirectUri = this.getRedirectURI(port);
213
+ redirectUrl = new URL(redirectUri);
214
+ console.log(`已找到可用端口: ${port}`);
215
+ console.log(`回调地址已更新为: ${redirectUri}`);
216
+ } catch (error) {
217
+ errorLog(`无法找到可用端口: ${error.message}`);
218
+ throw new Error(`端口 ${port} 已被占用,且无法找到可用端口`);
219
+ }
220
+ */
221
+ }
170
222
 
171
223
  const codePromise = new Promise((resolve, reject) => {
172
224
  const server = http.createServer((req, res) => {
@@ -200,9 +252,8 @@ class NeoLoginService {
200
252
  <head><title>授权成功</title></head>
201
253
  <body>
202
254
  <h1>授权成功!</h1>
203
- <p>已获取授权码,正在获取 token...</p>
255
+ <p>已获取授权码</p>
204
256
  <p>您可以关闭此窗口</p>
205
- <script>window.close();</script>
206
257
  </body>
207
258
  </html>
208
259
  `);
@@ -302,7 +353,7 @@ class NeoLoginService {
302
353
  * @returns {Promise<object>} 新的 Token 数据
303
354
  */
304
355
  async refreshToken(refreshToken) {
305
- const spinner = ora('正在刷新 token...').start();
356
+ const spinner = ora('正在刷新授权信息(token)...').start();
306
357
 
307
358
  try {
308
359
  const formData = new URLSearchParams();
@@ -320,16 +371,16 @@ class NeoLoginService {
320
371
  const tokenData = response.data;
321
372
 
322
373
  if (!tokenData || !tokenData.access_token) {
323
- errorLog('刷新 token 失败:响应中未包含 access_token', spinner);
374
+ errorLog('刷新授权信息失败:响应中未包含 access_token', spinner);
324
375
  errorLog(`响应数据: ${JSON.stringify(tokenData)}`);
325
376
  return null;
326
377
  }
327
378
 
328
- successLog('Token 刷新成功', spinner);
379
+ successLog('刷新授权信息成功(token)。', spinner);
329
380
  return tokenData;
330
381
  } catch (error) {
331
- errorLog('刷新 token 失败', spinner);
332
- errorLog(`\n刷新 token 失败: ${error.message}`);
382
+ errorLog('刷新授权信息失败', spinner);
383
+ errorLog(`\n刷新授权信息失败: ${error.message}`);
333
384
  if (error.response) {
334
385
  errorLog(`响应数据: ${JSON.stringify(error.response.data)}`);
335
386
  }
@@ -366,11 +417,15 @@ class NeoLoginService {
366
417
  this.saveToken(tokenData);
367
418
 
368
419
  console.log('\n========== 登录成功 ==========\n');
369
- console.log(`Token 已保存到: ${this.tokenFile}`);
420
+ console.log(`已缓存授权信息到: ${this.tokenFile}`);
370
421
  console.log(`实例地址: ${tokenData.instance_uri || '未返回'}`);
371
422
  console.log(`租户 ID: ${tokenData.tenant_id || '未返回'}`);
372
- console.log(`Token 有效期: ${tokenData.expires_in || 7200} 秒`);
373
- console.log(`Refresh Token 有效期: ${tokenData.refresh_token_expires_in || 2592000} 秒`);
423
+ console.log(`授权信息有效期(access_token): ${tokenData.expires_in || 7200} 秒`);
424
+ console.log(
425
+ `自动刷新授权信息有效期(refresh_token): ${
426
+ tokenData.refresh_token_expires_in || 2592000
427
+ } 秒`
428
+ );
374
429
  console.log('');
375
430
 
376
431
  return tokenData;
@@ -393,7 +448,7 @@ class NeoLoginService {
393
448
 
394
449
  try {
395
450
  this.clearToken();
396
- successLog(`已清除 token 文件: ${this.tokenFile}`);
451
+ successLog(`已清除授权信息,下次登录需要重新授权。`);
397
452
  console.log('\n登出成功!\n');
398
453
  } catch (error) {
399
454
  errorLog(`登出失败: ${error.message}`);
@@ -409,16 +464,16 @@ class NeoLoginService {
409
464
  const tokenData = this.readToken();
410
465
 
411
466
  if (!tokenData) {
412
- errorLog('未找到本地 token,请先执行 neo login 进行登录');
467
+ errorLog('未找到授权信息,请先执行 neo login 进行登录。');
413
468
  process.exit(1);
414
469
  }
415
470
 
416
471
  // 检查 token 是否过期
417
472
  if (this.isTokenExpired(tokenData)) {
418
- console.log('Token 已过期,正在尝试刷新...');
473
+ console.log('授权信息已过期,正在尝试刷新...');
419
474
 
420
475
  if (!tokenData.refresh_token) {
421
- errorLog('Refresh token 不存在,请重新登录');
476
+ errorLog('自动刷新授权信息失败,请重新登录(neo login)。');
422
477
  process.exit(1);
423
478
  }
424
479
 
@@ -426,7 +481,7 @@ class NeoLoginService {
426
481
  const newTokenData = await this.refreshToken(tokenData.refresh_token);
427
482
 
428
483
  if (!newTokenData) {
429
- errorLog('Token 刷新失败,请重新登录 (neo login)');
484
+ errorLog('刷新授权信息失败,请重新登录 (neo login)');
430
485
  process.exit(1);
431
486
  }
432
487
 
@@ -66,25 +66,29 @@ class NeoService {
66
66
  // 设置授权类型,默认为 oauth2
67
67
  this.authType = authType || 'oauth2';
68
68
 
69
- if (!auth) {
70
- throw new Error('auth 不能为空');
69
+ if (this.authType === 'password' && !auth) {
70
+ errorLog('密码授权模式时,neo.config.js / neoConfig / auth 配置不能为空');
71
+ process.exit(1);
71
72
  }
72
73
 
73
74
  // 根据授权类型验证必需的配置项
74
75
  if (this.authType === 'password') {
75
76
  if (!auth.client_id || !auth.client_secret || !auth.username || !auth.password) {
76
- throw new Error(
77
+ errorLog(
77
78
  'neo.config.js / neoConfig / auth 配置不完整(password 模式),需要包含 client_id、client_secret、username、password'
78
79
  );
80
+ process.exit(1);
79
81
  }
80
82
  } else if (this.authType === 'oauth2') {
81
83
  if (!loginURL || !tokenAPI) {
82
- throw new Error(
84
+ errorLog(
83
85
  'neo.config.js / neoConfig 配置不完整(oauth2 模式),需要包含 loginURL、tokenAPI 配置。'
84
86
  );
87
+ process.exit(1);
85
88
  }
86
89
  } else {
87
- throw new Error(`不支持的授权类型: ${this.authType},可选值:oauth2、password`);
90
+ errorLog(`不支持的授权类型: ${this.authType},可选值:oauth2、password`);
91
+ process.exit(1);
88
92
  }
89
93
 
90
94
  this.assetsRoot = assetsRoot || resolve('dist');
@@ -594,7 +598,8 @@ class NeoService {
594
598
  const { code, message } = response.data || {};
595
599
 
596
600
  if (code && code !== 200) {
597
- throw new Error(`获取自定义组件列表失败: ${message || '未知错误'}`);
601
+ errorLog(`获取自定义组件列表失败: ${message || '未知错误'}`);
602
+ process.exit(1);
598
603
  }
599
604
 
600
605
  this.updateCustomCmpList(response.data.data || []);
@@ -620,7 +625,8 @@ class NeoService {
620
625
  const token = await this.ensureValidToken();
621
626
 
622
627
  if (!cmpType) {
623
- throw new Error('自定义组件名称不能为空。');
628
+ errorLog('自定义组件名称不能为空。');
629
+ process.exit(1);
624
630
  }
625
631
 
626
632
  let fullDeleteAPI = this.buildFullUrl(NeoCrmAPI.delete);
@@ -636,7 +642,8 @@ class NeoService {
636
642
  const { code, message } = response.data || {};
637
643
 
638
644
  if (code && code !== 200) {
639
- throw new Error(`删除自定义组件失败: ${message || '未知错误'}`);
645
+ errorLog(`删除自定义组件失败: ${message || '未知错误'}`);
646
+ process.exit(1);
640
647
  }
641
648
 
642
649
  return response.data;