neo-cmp-cli 1.5.6 → 1.6.0-beta.1

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.
Files changed (28) hide show
  1. package/README.md +62 -47
  2. package/package.json +1 -1
  3. package/src/cmpUtils/createCmpByTemplate.js +2 -2
  4. package/src/cmpUtils/createCmpByZip.js +87 -0
  5. package/src/cmpUtils/pullCmp.js +96 -0
  6. package/src/cmpUtils/pushCmp.js +76 -67
  7. package/src/module/index.js +54 -5
  8. package/src/module/main.js +7 -1
  9. package/src/neo/NeoUMDContent.js +1 -0
  10. package/src/neo/neoService.js +148 -40
  11. package/src/projectUtils/createCmpProjectZip.js +18 -18
  12. package/src/projectUtils/hasNeoProject.js +2 -2
  13. package/src/template/antd-custom-cmp-template/neo.config.js +7 -4
  14. package/src/template/antd-custom-cmp-template/package.json +1 -0
  15. package/src/template/echarts-custom-cmp-template/neo.config.js +7 -4
  16. package/src/template/echarts-custom-cmp-template/package.json +1 -0
  17. package/src/template/empty-custom-cmp-template/neo.config.js +7 -4
  18. package/src/template/empty-custom-cmp-template/package.json +1 -0
  19. package/src/template/neo-custom-cmp-template/neo.config.js +12 -9
  20. package/src/template/neo-custom-cmp-template/package.json +2 -1
  21. package/src/template/neo-custom-cmp-template/pushCmp.js +166 -0
  22. package/src/template/react-custom-cmp-template/neo.config.js +7 -4
  23. package/src/template/react-custom-cmp-template/package.json +1 -0
  24. package/src/template/react-ts-custom-cmp-template/neo.config.js +7 -4
  25. package/src/template/react-ts-custom-cmp-template/package.json +1 -0
  26. package/src/template/vue2-custom-cmp-template/neo.config.js +7 -4
  27. package/src/template/vue2-custom-cmp-template/package.json +1 -0
  28. package/src/utils/common.js +48 -0
@@ -2,6 +2,7 @@ const figlet = require('figlet'); // 用于输出图形文字
2
2
  const yargs = require('yargs'); // 命令行工具
3
3
  const chalk = require('chalk'); // 带样式的log输出
4
4
  const inquirer = require('inquirer'); // 问答式交互
5
+ const ora = require('ora');
5
6
 
6
7
  const neoInit = require('./neoInit.js');
7
8
  const neoInitByCopy = require('./neoInitByCopy.js');
@@ -10,6 +11,7 @@ const neoConfigInit = require('../utils/neoConfigInit.js');
10
11
  const { validateProjectName } = require('../utils/projectNameValidator.js');
11
12
  const mainAction = require('./main.js'); // 入口文件
12
13
  const getCmpTypeByDir = require('../cmpUtils/getCmpTypeByDir.js');
14
+ const NeoService = require('../neo/neoService.js');
13
15
 
14
16
  // neo 的 package 文件
15
17
  const neoPackage = require('../../package.json');
@@ -67,6 +69,11 @@ yargs
67
69
  value: 'react-ts',
68
70
  short: 'react-ts'
69
71
  },
72
+ {
73
+ name: 'Neo 自定义组件(使用平台实体数据源)',
74
+ value: 'neo',
75
+ short: 'neo'
76
+ },
70
77
  {
71
78
  name: 'antd 自定义组件',
72
79
  value: 'antd',
@@ -77,11 +84,6 @@ yargs
77
84
  value: 'echarts',
78
85
  short: 'echarts'
79
86
  },
80
- {
81
- name: 'Neo 自定义组件',
82
- value: 'neo',
83
- short: 'neo'
84
- },
85
87
  /*
86
88
  // 暂不提供 react js 模板(react js 模板已废弃)
87
89
  {
@@ -227,6 +229,53 @@ yargs
227
229
  }
228
230
  }
229
231
  )
232
+ .command(
233
+ 'pullCmp [options]',
234
+ '拉取线上自定义组件',
235
+ (yargs) => {
236
+ yargs
237
+ .reset()
238
+ .usage(titleTip('Usage') + ': $0 preview [options]')
239
+ .option('name', {
240
+ alias: 'n',
241
+ describe: '自定义组件名称'
242
+ })
243
+ .alias('h', 'help');
244
+ },
245
+ async (argv) => {
246
+ if (argv.name) {
247
+ mainAction.pullCmp(argv.name);
248
+ } else {
249
+ // 创建 neoService 实例
250
+ const neoService = new NeoService(authConfig);
251
+ const spinner = ora('正在获取自定义组件列表...').start();
252
+ const cmpList = await neoService.getCustomCmpList();
253
+ if (cmpList.length === 0) {
254
+ console.error('当前租户暂无任何自定义组件。');
255
+ process.exit(1);
256
+ }
257
+ spinner.clear();
258
+ const cmpTypeChoices = cmpList.map((cmpType) => ({
259
+ name: cmpType,
260
+ value: cmpType
261
+ }));
262
+ questions.push({
263
+ name: 'cmpType',
264
+ type: 'list',
265
+ message: '请选择要拉取的自定义组件:',
266
+ choices: cmpTypeChoices
267
+ });
268
+ inquirer.prompt(questions).then((ans) => {
269
+ if (!ans.name) {
270
+ console.error('自定义组件名称不能为空。');
271
+ process.exit(1);
272
+ } else {
273
+ mainAction.pullCmp(ans.name, neoService);
274
+ }
275
+ });
276
+ }
277
+ }
278
+ )
230
279
  .command(
231
280
  'preview [options]',
232
281
  '预览指定自定义组件(仅预览组件本身内容)',
@@ -17,6 +17,7 @@ const { getExternalsByNeoCommonModules } = require('../neo/neoRequire');
17
17
  const createCommonModulesCode = require('../cmpUtils/createCommonModulesCode');
18
18
  const createCmpByTemplate = require('../cmpUtils/createCmpByTemplate');
19
19
  const createCmpProjectByTemplate = require('../projectUtils/createCmpProjectByTemplate');
20
+ const pullCmp = require('../cmpUtils/pullCmp');
20
21
 
21
22
  const getValue = (originValue, defaultValue) => {
22
23
  return originValue !== undefined ? originValue : defaultValue;
@@ -277,8 +278,9 @@ module.exports = {
277
278
  },
278
279
  // 发布组件到 NeoCRM 平台
279
280
  pushCmp: (cmpType) => {
281
+ const { neoConfig, pushCmp: _pushCmpConfig } = curConfig;
282
+ const pushCmpConfig = Object.assign({}, _pushCmpConfig, neoConfig);
280
283
  // 将 pushCmp 相关配置设置给 build2lib
281
- const pushCmpConfig = curConfig.pushCmp;
282
284
  curConfig.build2lib = Object.assign(curConfig.build2lib, pushCmpConfig);
283
285
 
284
286
  const curEntry = curConfig.build2lib.entry;
@@ -363,5 +365,9 @@ module.exports = {
363
365
  pushCmp(pushCmpConfig, cmpType);
364
366
  });
365
367
  },
368
+ // 从 NeoCRM 平台拉取组件
369
+ pullCmp: (cmpType, neoService) => {
370
+ pullCmp(cmpType, curConfig.neoConfig, neoService);
371
+ },
366
372
  build2esm: (fileName) => akfun.build2esm(fileName, curConfig, consoleTag) // 构建esm输出模块
367
373
  };
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * 内置 UMD 模块,用于在 Node cli 端加载自定义组件模型
3
3
  * 特别说明:这个文件内容会通过 AddNeoRequirePlugin 插入的构建代码中。
4
+ * 暂未使用,保留备用。
4
5
  */
5
6
  (function (root, factory) {
6
7
  // AMD 环境检测
@@ -2,17 +2,44 @@ const axios = require('axios');
2
2
  const FormData = require('form-data');
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
+ const ora = require('ora');
5
6
  const _ = require('lodash');
7
+ const { resolve } = require('akfun');
6
8
  const updatePublishLog = require('../projectUtils/updatePublishLog');
9
+ const { getFramework } = require('../utils/common');
7
10
 
8
11
  // NeoCRM 平台默认 API 配置
9
12
  const NeoCrmAPI = {
10
13
  neoBaseURL: 'https://crm.xiaoshouyi.com', // 平台根地址
11
14
  tokenAPI: 'https://login.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址
12
15
  uploadAPI: '/rest/metadata/v3.0/ui/customComponents/actions/upload', // 文件上传接口地址
16
+ delete: '/rest/metadata/v3.0/ui/customComponents',
17
+ query: '/rest/metadata/v3.0/ui/customComponents/actions/queryCustomComponents', // 带分页
18
+ queryAll: '/rest/metadata/v3.0/ui/customComponents/actions/queryAllCustomComponents', // 不带分页
13
19
  saveAPI: '/rest/metadata/v3.0/ui/customComponents/actions/saveOrUpdateComponent' // 创建或者保存接口地址
14
20
  };
15
21
 
22
+ const cmpFields = [
23
+ 'cmpType',
24
+ 'label',
25
+ 'componentCategory',
26
+ 'description',
27
+ 'framework',
28
+ 'icon',
29
+ 'orderNo',
30
+ 'version',
31
+ 'propsSchema',
32
+ 'defaultProps',
33
+ 'previewProps',
34
+ 'events',
35
+ 'actions',
36
+ 'asset',
37
+ 'plugin',
38
+ 'modelAsset',
39
+ 'cssAsset',
40
+ 'codeLib',
41
+ ];
42
+
16
43
  /**
17
44
  * Neo 平台服务类
18
45
  * 提供 token 管理、文件上传、组件更新等功能
@@ -23,32 +50,34 @@ class NeoService {
23
50
  * @param {object} config 配置信息
24
51
  * @param {string} config.neoBaseURL Neo 平台根地址
25
52
  * @param {string} config.tokenAPI Token 获取接口地址
26
- * @param {object} config.authConfig 授权信息
27
- * @param {string} config.authConfig.client_id 客户端 ID
28
- * @param {string} config.authConfig.client_secret 客户端密钥
29
- * @param {string} config.authConfig.username 用户名
30
- * @param {string} config.authConfig.password 密码
53
+ * @param {object} config.auth 授权信息
54
+ * @param {string} config.auth.client_id 客户端 ID
55
+ * @param {string} config.auth.client_secret 客户端密钥
56
+ * @param {string} config.auth.username 用户名
57
+ * @param {string} config.auth.password 密码
31
58
  */
32
59
  constructor(config = {}) {
33
- const { assetsRoot, neoBaseURL, tokenAPI, authConfig } = config;
34
- if (!authConfig) {
35
- throw new Error('authConfig 不能为空');
60
+ const { assetsRoot, neoBaseURL, tokenAPI, auth } = config;
61
+ if (!auth) {
62
+ throw new Error('auth 不能为空');
36
63
  }
37
64
  if (
38
- !authConfig.client_id ||
39
- !authConfig.client_secret ||
40
- !authConfig.username ||
41
- !authConfig.password
65
+ !auth.client_id ||
66
+ !auth.client_secret ||
67
+ !auth.username ||
68
+ !auth.password
42
69
  ) {
43
70
  throw new Error(
44
- 'authConfig 配置不完整,需要包含 client_id、client_secret、username、password'
71
+ 'auth 配置不完整,需要包含 client_id、client_secret、username、password'
45
72
  );
46
73
  }
47
74
 
48
- this.assetsRoot = assetsRoot;
75
+ this.assetsRoot = assetsRoot || resolve('dist');
49
76
  this.neoBaseURL = neoBaseURL || NeoCrmAPI.neoBaseURL;
50
77
  this.tokenAPI = tokenAPI || NeoCrmAPI.tokenAPI;
51
- this.authConfig = authConfig;
78
+ this.auth = auth;
79
+ this.cmpList = [];
80
+ this.cmpInfoMap = {};
52
81
 
53
82
  // Token 缓存
54
83
  this.tokenCache = {
@@ -96,20 +125,20 @@ class NeoService {
96
125
  * @returns {Promise<string>} token
97
126
  */
98
127
  async getToken() {
128
+ const spinner = ora('获取 token...').start();
99
129
  // 检查缓存是否有效
100
130
  if (!this.isTokenExpired()) {
101
- console.info('使用缓存的 token');
131
+ spinner.succeed('使用缓存的 token');
102
132
  return this.tokenCache.token;
103
133
  }
104
- console.info('获取 token...');
105
134
 
106
135
  // 构建表单数据格式的请求参数
107
136
  const formData = new URLSearchParams();
108
137
  formData.append('grant_type', 'password');
109
- formData.append('client_id', this.authConfig.client_id);
110
- formData.append('client_secret', this.authConfig.client_secret);
111
- formData.append('username', this.authConfig.username);
112
- formData.append('password', this.authConfig.password);
138
+ formData.append('client_id', this.auth.client_id);
139
+ formData.append('client_secret', this.auth.client_secret);
140
+ formData.append('username', this.auth.username);
141
+ formData.append('password', this.auth.password);
113
142
 
114
143
  const tokenUrl = this.buildFullUrl(this.tokenAPI);
115
144
 
@@ -123,7 +152,7 @@ class NeoService {
123
152
  const { access_token, expires_in } = response.data || {};
124
153
 
125
154
  if (!access_token) {
126
- console.error('\n获取 token 失败(授权配置错误):响应中未包含 access_token', response.data);
155
+ spinner.fail('获取 token 失败(授权配置错误):响应中未包含 access_token', response.data);
127
156
  process.exit(1);
128
157
  }
129
158
 
@@ -133,6 +162,7 @@ class NeoService {
133
162
  token: access_token,
134
163
  expiresAt: Date.now() + (expiresIn - 60) * 1000
135
164
  };
165
+ spinner.succeed('获取 token 成功。');
136
166
  return access_token;
137
167
  } catch (error) {
138
168
  console.error('\n获取 token 失败:', error.message);
@@ -167,8 +197,10 @@ class NeoService {
167
197
  if (!this.tokenCache.token) {
168
198
  return await this.getToken();
169
199
  } else if (this.isTokenExpired()) {
170
- console.info('token 已过期,正在刷新...');
171
- return await this.refreshToken();
200
+ const spinner = ora('token 已过期,正在刷新...').start();
201
+ const token = await this.refreshToken();
202
+ spinner.succeed('token 刷新成功。');
203
+ return token;
172
204
  }
173
205
  return this.tokenCache.token;
174
206
  }
@@ -216,13 +248,13 @@ class NeoService {
216
248
 
217
249
  const fileName = path.basename(filePath);
218
250
  const fileSizeKB = (fileStat.size / 1024).toFixed(2);
219
- console.info(`正在上传文件: ${fileName} (${fileSizeKB}KB)...`);
251
+ const spinner = ora(`正在上传文件: ${fileName} (${fileSizeKB}KB)...`).start();
220
252
 
221
253
  try {
222
254
  // 创建 FormData
223
255
  const formData = new FormData();
224
256
  const fieldName = options.fieldName || 'customComponentCode';
225
-
257
+
226
258
  // 使用文件流而不是读取整个文件到内存(对大文件更友好)
227
259
  const fileContent = fs.createReadStream(filePath);
228
260
 
@@ -265,7 +297,11 @@ class NeoService {
265
297
  resultData = responseData.trim();
266
298
  } else if (responseData && typeof responseData === 'object') {
267
299
  // 检查是否有错误码
268
- if (responseData.code !== undefined && responseData.code !== 200 && responseData.code !== 0) {
300
+ if (
301
+ responseData.code !== undefined &&
302
+ responseData.code !== 200 &&
303
+ responseData.code !== 0
304
+ ) {
269
305
  const errorMsg = responseData.message || responseData.msg || '未知错误';
270
306
  throw new Error(`上传失败: ${errorMsg} (code: ${responseData.code})`);
271
307
  }
@@ -296,36 +332,35 @@ class NeoService {
296
332
  } else if (resultData && typeof resultData === 'object' && resultData.url) {
297
333
  fileUrl = resultData.url;
298
334
  }
299
- console.info(`\n文件上传成功: ${fileName} -> ${fileUrl}`);
335
+ spinner.succeed(`文件上传成功: ${fileName} -> ${fileUrl}`);
300
336
  return fileUrl;
301
337
  } catch (error) {
302
- console.error(`\n上传文件失败: ${error.message},`);
303
- console.error(`文件路径: ${filePath}。\n`);
304
-
338
+ spinner.fail(`上传文件失败: ${error.message}, 文件路径: ${filePath}`);
339
+
305
340
  // 输出详细的错误信息
306
341
  if (error.response) {
307
342
  const status = error.response.status;
308
343
  const statusText = error.response.statusText;
309
344
  const responseData = error.response.data;
310
345
  const requestUrl = error.config?.url || this.uploadAPI();
311
-
346
+
312
347
  console.error(`\n========== 上传请求详情 ==========`);
313
348
  console.error(`请求 URL: ${requestUrl}`);
314
349
  console.error(`HTTP 状态码: ${status} ${statusText}`);
315
350
  console.error(`响应数据:`, responseData);
316
351
  console.error(`==================================\n`);
317
-
352
+
318
353
  if (status === 404) {
319
354
  throw new Error(
320
355
  `上传 API 不存在 (404): ${requestUrl}\n` +
321
- `请检查 neo.config.js 中的 neoBaseURL 配置是否正确,或者 API 路径是否存在。\n` +
322
- `当前配置的 API 路径: ${NeoCrmAPI.uploadAPI}`
356
+ `请检查 neo.config.js 中的 neoBaseURL 配置是否正确,或者 API 路径是否存在。\n` +
357
+ `当前配置的 API 路径: ${NeoCrmAPI.uploadAPI}`
323
358
  );
324
359
  }
325
360
  } else if (error.request) {
326
361
  console.error('请求已发送但未收到响应,请检查网络连接或代理配置。');
327
362
  }
328
-
363
+
329
364
  throw error;
330
365
  }
331
366
  }
@@ -410,7 +445,7 @@ class NeoService {
410
445
  throw new Error('componentData 不能为空');
411
446
  }
412
447
 
413
- console.info('正在更新自定义组件...');
448
+ const spinner = ora('正在更新自定义组件...').start();
414
449
 
415
450
  try {
416
451
  const fullUpdateAPI = this.saveAPI();
@@ -421,15 +456,15 @@ class NeoService {
421
456
  'Content-Type': 'application/json'
422
457
  }
423
458
  });
424
- const {code, message} = response.data || {};
459
+ const { code, message } = response.data || {};
425
460
 
426
461
  if (code && code !== 200) {
427
462
  throw new Error(`更新组件失败: ${response.data.message || '未知错误'}`);
428
463
  }
429
-
430
464
 
431
- console.info(message ? `组件更新成功: ${message}。` : '组件更新成功。');
465
+ spinner.succeed(message ? `组件更新成功: ${message}。` : '组件更新成功。');
432
466
  } catch (error) {
467
+ spinner.fail('更新组件失败。');
433
468
  if (error.message) {
434
469
  console.error('更新组件失败:', error.message);
435
470
  } else {
@@ -439,6 +474,79 @@ class NeoService {
439
474
  }
440
475
  }
441
476
 
477
+ /**
478
+ * 获取线上自定义组件列表
479
+ * @returns {Promise<array>} 自定义组件列表
480
+ */
481
+ async getCustomCmpList() {
482
+ // 确保 token 有效
483
+ const token = await this.ensureValidToken();
484
+
485
+ /*
486
+ // 如果自定义组件列表已存在,则直接返回
487
+ if (this.cmpList && this.cmpList.length > 0) {
488
+ return this.cmpList;
489
+ }
490
+ */
491
+
492
+ try {
493
+ let queryAllAPI = this.buildFullUrl(NeoCrmAPI.queryAll);
494
+ queryAllAPI += `?fields=${cmpFields.join(',')}`;
495
+ const response = await axios.post(queryAllAPI, {}, {
496
+ headers: {
497
+ Authorization: `Bearer ${token}`,
498
+ 'xsy-inner-source': 'bff',
499
+ 'Content-Type': 'application/json'
500
+ }
501
+ });
502
+ const { code, message } = response.data || {};
503
+
504
+ if (code && code !== 200) {
505
+ throw new Error(`获取自定义组件列表失败: ${message || '未知错误'}`);
506
+ }
507
+
508
+ this.updateCustomCmpList(response.data.data || []);
509
+
510
+ } catch (error) {
511
+ if (error.message) {
512
+ console.error('获取自定义组件列表失败:', error.message);
513
+ } else {
514
+ console.error('响应数据:', error);
515
+ }
516
+ process.exit(1);
517
+ }
518
+
519
+ return this.cmpList || [];
520
+ }
521
+
522
+ // 获取指定框架的自定义组件列表
523
+ getCmpListByFramework(framework) {
524
+ if (!framework) {
525
+ return this.cmpList;
526
+ }
527
+ const curFramework = getFramework(framework);
528
+ return this.cmpList.filter((cmp) => cmp.framework === curFramework);
529
+ }
530
+
531
+ // 获取自定义组件信息
532
+ getCmpInfoByCmpType(cmpType) {
533
+ if (!cmpType) {
534
+ return null;
535
+ }
536
+ return this.cmpInfoMap[cmpType] || null;
537
+ }
538
+
539
+ // 更新自定义组件 Map
540
+ updateCustomCmpList(cmpList) {
541
+ if (!cmpList || !Array.isArray(cmpList)) {
542
+ return;
543
+ }
544
+ this.cmpList = cmpList;
545
+ cmpList.forEach((cmp) => {
546
+ this.cmpInfoMap[cmp.cmpType] = cmp;
547
+ });
548
+ }
549
+
442
550
  /**
443
551
  * 通用请求方法(确保 token 有效)
444
552
  * @param {string} method HTTP 方法
@@ -13,7 +13,7 @@ const hasNeoProject = require('./hasNeoProject');
13
13
  module.exports = function (cmpType, _projectPath, assetsRoot) {
14
14
  const projectRoot = _projectPath || process.cwd();
15
15
  const finalAssetsRoot = assetsRoot || path.join(projectRoot, 'dist');
16
-
16
+
17
17
  if (!hasNeoProject(_projectPath)) {
18
18
  console.error(`${consoleTag}当前目录不是自定义组件项目,请在自定义组件项目目录下执行。`);
19
19
  process.exit(1);
@@ -25,11 +25,11 @@ module.exports = function (cmpType, _projectPath, assetsRoot) {
25
25
  }
26
26
 
27
27
  const zip = new AdmZip();
28
-
28
+
29
29
  // 需要排除的目录和文件
30
30
  const excludeDirs = ['node_modules', '.neo-cli', 'dist'];
31
31
  const excludeFiles = ['.eslintcache', 'auth.config.js'];
32
-
32
+
33
33
  /**
34
34
  * 判断文件/目录是否应该被排除
35
35
  * @param {string} filePath 文件路径
@@ -39,17 +39,17 @@ module.exports = function (cmpType, _projectPath, assetsRoot) {
39
39
  const shouldExclude = (filePath, relativePath) => {
40
40
  const name = path.basename(filePath);
41
41
  const stat = fs.statSync(filePath);
42
-
42
+
43
43
  // 排除指定的目录
44
44
  if (stat.isDirectory() && excludeDirs.includes(name)) {
45
45
  return true;
46
46
  }
47
-
47
+
48
48
  // 排除指定的文件
49
49
  if (stat.isFile() && excludeFiles.includes(name)) {
50
50
  return true;
51
51
  }
52
-
52
+
53
53
  // 对于 src/components 目录,只包含 cmpType 子目录
54
54
  // 处理逻辑:如果路径是 src/components/xxx,且 xxx 不是 cmpType,则排除
55
55
  if (relativePath.startsWith('src/components')) {
@@ -63,10 +63,10 @@ module.exports = function (cmpType, _projectPath, assetsRoot) {
63
63
  }
64
64
  }
65
65
  }
66
-
66
+
67
67
  return false;
68
68
  };
69
-
69
+
70
70
  /**
71
71
  * 递归遍历目录并添加到 zip
72
72
  * @param {string} dirPath 目录路径
@@ -75,18 +75,18 @@ module.exports = function (cmpType, _projectPath, assetsRoot) {
75
75
  const addDirectoryToZip = (dirPath, relativePath = '') => {
76
76
  try {
77
77
  const items = fs.readdirSync(dirPath);
78
-
78
+
79
79
  items.forEach((item) => {
80
80
  const itemPath = path.join(dirPath, item);
81
81
  const itemRelativePath = relativePath ? path.join(relativePath, item) : item;
82
-
82
+
83
83
  // 检查是否应该排除
84
84
  if (shouldExclude(itemPath, itemRelativePath)) {
85
85
  return;
86
86
  }
87
-
87
+
88
88
  const stat = fs.statSync(itemPath);
89
-
89
+
90
90
  if (stat.isDirectory()) {
91
91
  // 递归处理子目录
92
92
  addDirectoryToZip(itemPath, itemRelativePath);
@@ -100,23 +100,23 @@ module.exports = function (cmpType, _projectPath, assetsRoot) {
100
100
  console.error(`${consoleTag}遍历目录失败 (${dirPath}):`, error.message);
101
101
  }
102
102
  };
103
-
103
+
104
104
  // 开始遍历项目根目录
105
105
  addDirectoryToZip(projectRoot);
106
-
106
+
107
107
  // 生成 zip 文件名
108
108
  const zipFileName = `${_.camelCase(cmpType)}Source.zip`;
109
109
  const zipPath = path.join(finalAssetsRoot, zipFileName);
110
-
110
+
111
111
  // 如果已存在同名 zip 文件,先删除
112
112
  if (fs.existsSync(zipPath)) {
113
113
  fs.removeSync(zipPath);
114
114
  }
115
-
115
+
116
116
  // 写入 zip 文件
117
117
  zip.writeZip(zipPath);
118
-
118
+
119
119
  console.log(`${consoleTag}已创建自定义组件源码 zip 包: ${zipFileName}`);
120
-
120
+
121
121
  return zipPath;
122
122
  };
@@ -2,8 +2,8 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
 
4
4
  /**
5
- * 判断当前是否存在 neo 项目
6
- * 备注:neo.config.js 和 package.json 必须同时存在才算作 neo 项目
5
+ * 判断当前是否存在 自定义组件项目
6
+ * 备注:neo.config.js 和 package.json 必须同时存在才算作 自定义组件项目
7
7
  */
8
8
  module.exports = function (_projectPath) {
9
9
  const projectPath = _projectPath || process.cwd();
@@ -97,12 +97,12 @@ module.exports = {
97
97
  }
98
98
  */
99
99
  },
100
- pushCmp: {
101
- // 用于构建并发布至 NeoCRM 的相关配置
100
+ // NeoCRM 平台配置
101
+ neoConfig: {
102
102
  neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
103
103
  tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
104
104
  // NeoCRM 授权配置
105
- authConfig: {
105
+ auth: {
106
106
  client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
107
107
  client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
108
108
  username: 'xx', // 用户在销售易系统中的用户名
@@ -111,7 +111,10 @@ module.exports = {
111
111
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
112
112
  */
113
113
  password: 'xx xx' // 用户账户密码 + 8 位安全令牌
114
- },
114
+ }
115
+ },
116
+ pushCmp: {
117
+ // 用于构建并发布至 NeoCRM 的相关配置
115
118
  /*
116
119
  【特别说明】以下配置项都自带默认值,非必填。如需自定义请自行配置。
117
120
  NODE_ENV: 'production',
@@ -2,6 +2,7 @@
2
2
  "name": "antd-custom-cmp-template",
3
3
  "version": "1.1.9",
4
4
  "description": "neo自定义组件模板(react&ts技术栈)",
5
+ "framework": "react-ts",
5
6
  "keywords": [
6
7
  "自定义组件模板",
7
8
  "react&ts技术栈",
@@ -98,12 +98,12 @@ module.exports = {
98
98
  }
99
99
  */
100
100
  },
101
- pushCmp: {
102
- // 用于构建并发布至 NeoCRM 的相关配置
101
+ // NeoCRM 平台配置
102
+ neoConfig: {
103
103
  neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
104
104
  tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
105
105
  // NeoCRM 授权配置
106
- authConfig: {
106
+ auth: {
107
107
  client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
108
108
  client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
109
109
  username: 'xx', // 用户在销售易系统中的用户名
@@ -112,7 +112,10 @@ module.exports = {
112
112
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
113
113
  */
114
114
  password: 'xx xx' // 用户账户密码 + 8 位安全令牌
115
- },
115
+ }
116
+ },
117
+ pushCmp: {
118
+ // 用于构建并发布至 NeoCRM 的相关配置
116
119
  /*
117
120
  【特别说明】以下配置项都自带默认值,非必填。如需自定义请自行配置。
118
121
  NODE_ENV: 'production',
@@ -2,6 +2,7 @@
2
2
  "name": "echarts-custom-cmp-template",
3
3
  "version": "1.1.19",
4
4
  "description": "neo自定义组件模板(react&ts技术栈)",
5
+ "framework": "react-ts",
5
6
  "keywords": [
6
7
  "自定义组件模板",
7
8
  "react&ts技术栈",