neo-cmp-cli 1.8.7 → 1.8.9

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 (125) hide show
  1. package/bin/index.js +2 -2
  2. package/dist/_virtual/_commonjsHelpers.js +12 -0
  3. package/dist/_virtual/array-set.js +7 -0
  4. package/dist/_virtual/base64-vlq.js +7 -0
  5. package/dist/_virtual/base64.js +7 -0
  6. package/dist/_virtual/binary-search.js +7 -0
  7. package/dist/_virtual/mapping-list.js +7 -0
  8. package/dist/_virtual/quick-sort.js +7 -0
  9. package/dist/_virtual/source-map-consumer.js +7 -0
  10. package/dist/_virtual/source-map-generator.js +7 -0
  11. package/dist/_virtual/source-map-support.js +7 -0
  12. package/dist/_virtual/source-map.js +7 -0
  13. package/dist/_virtual/source-node.js +7 -0
  14. package/dist/_virtual/typescript.js +7 -0
  15. package/dist/_virtual/util.js +7 -0
  16. package/dist/config/auth.config.js +43 -0
  17. package/dist/config/default.config.js +192 -0
  18. package/dist/config/index.js +26 -0
  19. package/dist/main.js +9 -0
  20. package/dist/main2.js +259 -0
  21. package/dist/module/inspect.js +63 -0
  22. package/dist/module/neoInit.js +75 -0
  23. package/dist/module/neoInitByCopy.js +83 -0
  24. package/dist/neo/neoLogin.js +590 -0
  25. package/dist/neo/neoRequire.js +123 -0
  26. package/dist/neo/neoService.js +898 -0
  27. package/dist/node_modules/buffer-from/index.js +86 -0
  28. package/dist/node_modules/source-map/lib/array-set.js +138 -0
  29. package/dist/node_modules/source-map/lib/base64-vlq.js +157 -0
  30. package/dist/node_modules/source-map/lib/base64.js +83 -0
  31. package/dist/node_modules/source-map/lib/binary-search.js +129 -0
  32. package/dist/node_modules/source-map/lib/mapping-list.js +96 -0
  33. package/dist/node_modules/source-map/lib/quick-sort.js +130 -0
  34. package/dist/node_modules/source-map/lib/source-map-consumer.js +1166 -0
  35. package/dist/node_modules/source-map/lib/source-map-generator.js +445 -0
  36. package/dist/node_modules/source-map/lib/source-node.js +431 -0
  37. package/dist/node_modules/source-map/lib/util.js +506 -0
  38. package/dist/node_modules/source-map/source-map.js +27 -0
  39. package/dist/node_modules/source-map-support/source-map-support.js +646 -0
  40. package/dist/node_modules/typescript/lib/typescript.js +174130 -0
  41. package/dist/oss/publish2oss.js +331 -0
  42. package/dist/plugins/AddNeoRequirePlugin.js +195 -0
  43. package/dist/utils/autoEntryRootDir.js +103 -0
  44. package/dist/utils/cmpUtils/createCmpByTemplate.js +82 -0
  45. package/dist/utils/cmpUtils/createCmpByZip.js +433 -0
  46. package/dist/utils/cmpUtils/createCommonModulesCode.js +139 -0
  47. package/dist/utils/cmpUtils/deleteCmp.js +81 -0
  48. package/dist/utils/cmpUtils/getCmpModelRegisterCode.js +47 -0
  49. package/dist/utils/cmpUtils/getCmpPreviewCode.js +60 -0
  50. package/dist/utils/cmpUtils/getCmpRegisterCode.js +47 -0
  51. package/dist/utils/cmpUtils/getCmpTypeByDir.js +59 -0
  52. package/dist/utils/cmpUtils/hasCmpTypeByDir.js +27 -0
  53. package/dist/utils/cmpUtils/previewCmp.js +75 -0
  54. package/dist/utils/cmpUtils/pullCmp.js +126 -0
  55. package/dist/utils/cmpUtils/pushCmp.js +254 -0
  56. package/dist/utils/common.js +125 -0
  57. package/dist/utils/configureNeoBuild.js +129 -0
  58. package/dist/utils/generateEntries.js +80 -0
  59. package/dist/utils/neoConfigInit.js +30 -0
  60. package/dist/utils/neoParams.js +26 -0
  61. package/dist/utils/pathUtils.js +40 -0
  62. package/dist/utils/projectNameValidator.js +90 -0
  63. package/dist/utils/projectUtils/createCmpProjectByTemplate.js +81 -0
  64. package/dist/utils/projectUtils/createCmpProjectZip.js +141 -0
  65. package/dist/utils/projectUtils/getEntries.js +99 -0
  66. package/dist/utils/projectUtils/getEntriesWithAutoRegister.js +129 -0
  67. package/dist/utils/projectUtils/hasNeoProject.js +34 -0
  68. package/dist/utils/projectUtils/openProject.js +117 -0
  69. package/dist/utils/projectUtils/updatePublishLog.js +47 -0
  70. package/dist/utils/replaceInFilesByMap.js +71 -0
  71. package/dist/utils/replaceInPackage.js +151 -0
  72. package/dist/utils/resetPackageVersion.js +132 -0
  73. package/package.json +6 -8
  74. package/test/demo.js +0 -2
  75. package/test/deprecate-versions.js +1 -1
  76. package/src/config/auth.config.js +0 -27
  77. package/src/config/default.config.js +0 -176
  78. package/src/config/index.js +0 -9
  79. package/src/main.js +0 -221
  80. package/src/module/inspect.js +0 -41
  81. package/src/module/neoInit.js +0 -55
  82. package/src/module/neoInitByCopy.js +0 -61
  83. package/src/neo/NeoUMDContent.js +0 -30
  84. package/src/neo/neoLogin.js +0 -565
  85. package/src/neo/neoRequire.js +0 -125
  86. package/src/neo/neoService.js +0 -874
  87. package/src/neo/webpack.mf.js +0 -60
  88. package/src/neo/wrapperContent.js +0 -16
  89. package/src/oss/publish2oss.js +0 -348
  90. package/src/plugins/AddNeoRequirePlugin-v1.js +0 -47
  91. package/src/plugins/AddNeoRequirePlugin.js +0 -179
  92. package/src/plugins/README.md +0 -109
  93. package/src/utils/autoEntryRootDir.js +0 -85
  94. package/src/utils/cmpUtils/createCmpByTemplate.js +0 -60
  95. package/src/utils/cmpUtils/createCmpByZip.js +0 -408
  96. package/src/utils/cmpUtils/createCommonModulesCode.js +0 -121
  97. package/src/utils/cmpUtils/deleteCmp.js +0 -63
  98. package/src/utils/cmpUtils/getCmpModelRegisterCode.js +0 -31
  99. package/src/utils/cmpUtils/getCmpPreviewCode.js +0 -43
  100. package/src/utils/cmpUtils/getCmpRegisterCode.js +0 -31
  101. package/src/utils/cmpUtils/getCmpTypeByDir.js +0 -41
  102. package/src/utils/cmpUtils/hasCmpTypeByDir.js +0 -11
  103. package/src/utils/cmpUtils/previewCmp.js +0 -55
  104. package/src/utils/cmpUtils/pullCmp.js +0 -104
  105. package/src/utils/cmpUtils/pushCmp.js +0 -230
  106. package/src/utils/common.js +0 -107
  107. package/src/utils/configureNeoBuild.js +0 -109
  108. package/src/utils/generateEntries.js +0 -63
  109. package/src/utils/neoConfigInit.js +0 -13
  110. package/src/utils/neoParams.js +0 -12
  111. package/src/utils/pathUtils.js +0 -23
  112. package/src/utils/projectNameValidator.js +0 -76
  113. package/src/utils/projectUtils/createCmpProjectByTemplate.js +0 -59
  114. package/src/utils/projectUtils/createCmpProjectZip.js +0 -120
  115. package/src/utils/projectUtils/getEntries.js +0 -80
  116. package/src/utils/projectUtils/getEntriesWithAutoRegister.js +0 -108
  117. package/src/utils/projectUtils/hasNeoProject.js +0 -17
  118. package/src/utils/projectUtils/openProject.js +0 -96
  119. package/src/utils/projectUtils/updatePublishLog.js +0 -30
  120. package/src/utils/replaceInFiles.js +0 -47
  121. package/src/utils/replaceInFilesByMap.js +0 -54
  122. package/src/utils/replaceInPackage.js +0 -134
  123. package/src/utils/resetPackageVersion.js +0 -115
  124. /package/{src → template}/initData/defaultTemplate.html +0 -0
  125. /package/{src → template}/initData/neo.config.js +0 -0
@@ -1,565 +0,0 @@
1
- const axios = require('axios');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const ora = require('ora');
5
- const http = require('http');
6
- const url = require('url');
7
- const open = require('open');
8
- const net = require('net');
9
- const portfinder = require('portfinder');
10
- const { errorLog, successLog } = require('../utils/common');
11
- const neoAuthConfig = require('../config/auth.config');
12
-
13
- /**
14
- * Neo 登录授权服务类
15
- * 实现 OAuth2 授权码模式的登录/登出功能
16
- */
17
- class NeoLoginService {
18
- /**
19
- * 初始化登录服务
20
- * @param {object} config 授权配置信息
21
- * @param {string} config.loginURL 登录授权 URL
22
- * @param {string} config.tokenAPI Token 获取接口地址
23
- * @param {string} config.response_type 认证类型 (code)
24
- * @param {string} config.client_id 客户端 ID
25
- * @param {string} config.client_secret 客户端秘钥
26
- * @param {string} config.scope 授权范围 (all)
27
- * @param {string} config.oauthType OAuth 类型 (standard)
28
- * @param {string} config.access_type 访问类型 (offline/online)
29
- * @param {string} config.grant_type 授权类型 (authorization_code)
30
- */
31
- constructor(config = {}) {
32
- const { loginURL, tokenAPI } = config;
33
-
34
- // 验证必需的配置项
35
- if (!loginURL || !tokenAPI) {
36
- throw new Error('auth.config.js 配置不完整,需要包含 loginURL、tokenAPI');
37
- }
38
-
39
- this.loginURL = loginURL;
40
- this.tokenAPI = tokenAPI;
41
- this.response_type = neoAuthConfig.response_type || 'code';
42
- this.client_id = neoAuthConfig.client_id;
43
- this.client_secret = neoAuthConfig.client_secret;
44
- this.scope = neoAuthConfig.scope || 'all';
45
- this.oauthType = neoAuthConfig.oauthType || 'standard';
46
- this.access_type = neoAuthConfig.access_type || 'offline';
47
- this.grant_type = neoAuthConfig.grant_type || 'authorization_code';
48
-
49
- // Token 存储路径(在当前项目根目录的 .neo-cli 文件夹下)
50
- this.tokenDir = path.join(process.cwd(), '.neo-cli');
51
- this.tokenFile = path.join(this.tokenDir, 'token.json');
52
- }
53
-
54
- /**
55
- * 确保 token 存储目录存在
56
- */
57
- ensureTokenDir() {
58
- if (!fs.existsSync(this.tokenDir)) {
59
- fs.mkdirSync(this.tokenDir, { recursive: true });
60
- }
61
- }
62
-
63
- /**
64
- * 保存 token 到本地文件
65
- * @param {object} tokenData Token 数据
66
- */
67
- saveToken(tokenData) {
68
- this.ensureTokenDir();
69
- const tokenInfo = {
70
- ...tokenData,
71
- savedAt: Date.now(),
72
- expiresAt: Date.now() + (tokenData.expires_in || 7200) * 1000
73
- };
74
- fs.writeFileSync(this.tokenFile, JSON.stringify(tokenInfo, null, 2), 'utf-8');
75
- }
76
-
77
- /**
78
- * 读取本地保存的 token
79
- * @returns {object|null} Token 数据,如果不存在或已过期则返回 null
80
- */
81
- readToken() {
82
- if (!fs.existsSync(this.tokenFile)) {
83
- return null;
84
- }
85
-
86
- try {
87
- const tokenData = JSON.parse(fs.readFileSync(this.tokenFile, 'utf-8'));
88
- return tokenData;
89
- } catch (error) {
90
- errorLog(`读取 token 文件失败: ${error.message}`);
91
- return null;
92
- }
93
- }
94
-
95
- /**
96
- * 检查 token 是否过期
97
- * @param {object} tokenData Token 数据
98
- * @returns {boolean} true 表示已过期,false 表示未过期
99
- */
100
- isTokenExpired(tokenData) {
101
- if (!tokenData || !tokenData.expiresAt) {
102
- return true;
103
- }
104
- // 提前 5 分钟判断为过期,避免边缘情况
105
- return Date.now() >= tokenData.expiresAt - 5 * 60 * 1000;
106
- }
107
-
108
- /**
109
- * 清除本地保存的 token
110
- */
111
- clearToken() {
112
- if (fs.existsSync(this.tokenFile)) {
113
- fs.unlinkSync(this.tokenFile);
114
- }
115
- }
116
-
117
- /**
118
- * 生成回调地址
119
- * @param {number} port 端口号
120
- * @returns {string} 回调地址
121
- */
122
- getRedirectURI(port) {
123
- return `http://localhost:${port}`;
124
- }
125
-
126
- /**
127
- * 构建授权 URL
128
- * @param {string} redirectUri 回调地址
129
- * @returns {string} 授权 URL
130
- */
131
- buildAuthUrl(redirectUri) {
132
- const params = new URLSearchParams({
133
- response_type: this.response_type,
134
- client_id: this.client_id,
135
- redirect_uri: redirectUri,
136
- scope: this.scope,
137
- oauthType: this.oauthType,
138
- access_type: this.access_type
139
- });
140
-
141
- return `${this.loginURL}?${params.toString()}`;
142
- }
143
-
144
- /**
145
- * 打开浏览器访问授权 URL
146
- * @param {string} authUrl 授权 URL
147
- */
148
- async openBrowser(authUrl) {
149
- try {
150
- await open(authUrl);
151
- } catch (error) {
152
- errorLog(`无法自动打开浏览器: ${error.message}`);
153
- console.log(`\n请手动访问以下 URL 进行授权:\n${authUrl}\n`);
154
- }
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
-
186
- /**
187
- * 启动本地服务器接收授权码(code)
188
- * @returns {Promise<{redirectUri: string, codePromise: Promise<string>}>} 回调地址和授权码Promise
189
- */
190
- async startCallbackServer() {
191
- let redirectUri = neoAuthConfig.redirectUri;
192
- let redirectUrl = new URL(redirectUri);
193
- let port = parseInt(redirectUrl.port, 10);
194
-
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
- }
222
-
223
- const codePromise = new Promise((resolve, reject) => {
224
- const server = http.createServer((req, res) => {
225
- const parsedUrl = url.parse(req.url, true);
226
-
227
- if (parsedUrl.pathname === redirectUrl.pathname || parsedUrl.pathname === '/') {
228
- const code = parsedUrl.query.code;
229
- const error = parsedUrl.query.error;
230
-
231
- if (error) {
232
- res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
233
- res.end(`
234
- <html>
235
- <head>
236
- <title>授权失败</title>
237
- <style>
238
- .container {
239
- margin: 0 auto;
240
- padding-top: 30px;
241
- text-align: center;
242
-
243
- .error-title {
244
- color: red;
245
- }
246
-
247
- h1, p {
248
- text-align: center;
249
- margin-top: 30px;
250
- }
251
- }
252
- </style>
253
- </head>
254
- <body>
255
- <div class="container">
256
- <h1 class="error-title">授权失败</h1>
257
- <img src="https://custom-widgets.bj.bcebos.com/neocrmlogin.png" alt="授权失败" />
258
- <p>错误信息: ${error}</p>
259
- </div>
260
- </body>
261
- </html>
262
- `);
263
- server.close();
264
- reject(new Error(`授权失败: ${error}`));
265
- return;
266
- }
267
-
268
- if (code) {
269
- res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
270
- res.end(`
271
- <html>
272
- <head>
273
- <title>授权成功</title>
274
- <style>
275
- .container {
276
- margin: 0 auto;
277
- padding-top: 30px;
278
- text-align: center;
279
-
280
- .success-title {
281
- color: green;
282
- }
283
-
284
- h1, p {
285
- text-align: center;
286
- margin-top: 30px;
287
- }
288
- }
289
- </style>
290
- </head>
291
- <body>
292
- <div class="container">
293
- <h1 class="success-title">授权成功!</h1>
294
- <img src="https://custom-widgets.bj.bcebos.com/neocrmlogin.png" alt="授权成功" />
295
- <p>您已成功授权开发账户,请关闭此页面。</p>
296
- </div>
297
- </body>
298
- </html>
299
- `);
300
- server.close();
301
- resolve(code);
302
- return;
303
- }
304
-
305
- res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
306
- res.end(`
307
- <html>
308
- <head>
309
- <title>授权失败</title>
310
- <style>
311
- .container {
312
- margin: 0 auto;
313
- padding-top: 30px;
314
- text-align: center;
315
-
316
- .error-title {
317
- color: red;
318
- }
319
-
320
- h1, p {
321
- text-align: center;
322
- margin-top: 30px;
323
- }
324
- }
325
- </style>
326
- </head>
327
- <body>
328
- <div class="container">
329
- <h1 class="error-title">授权失败</h1>
330
- <img src="https://custom-widgets.bj.bcebos.com/neocrmlogin.png" alt="授权失败" />
331
- <p>未获取到授权码。</p>
332
- </div>
333
- </body>
334
- </html>
335
- `);
336
- server.close();
337
- reject(new Error('未获取到授权码'));
338
- } else {
339
- res.writeHead(404, { 'Content-Type': 'text/plain' });
340
- res.end('Not Found');
341
- }
342
- });
343
-
344
- server.on('error', (error) => {
345
- if (error.code === 'EADDRINUSE') {
346
- reject(new Error(`端口 ${port} 已被占用,无法启动回调服务器`));
347
- } else {
348
- reject(error);
349
- }
350
- });
351
-
352
- server.listen(port, () => {
353
- console.log(`\n本地回调服务器已启动,监听端口: ${port}`);
354
- console.log(`回调地址: ${redirectUri}`);
355
- });
356
-
357
- // 设置超时(5 分钟)
358
- setTimeout(() => {
359
- server.close();
360
- reject(new Error('授权超时,请重试'));
361
- }, 5 * 60 * 1000);
362
- });
363
-
364
- return { redirectUri, codePromise };
365
- }
366
-
367
- /**
368
- * 使用授权码获取 token
369
- * @param {string} code 授权码
370
- * @param {string} redirectUri 回调地址
371
- * @returns {Promise<object>} Token 数据
372
- */
373
- async getTokenByCode(code, redirectUri) {
374
- const spinner = ora('正在获取 access token...').start();
375
-
376
- try {
377
- const formData = new URLSearchParams();
378
- formData.append('grant_type', this.grant_type);
379
- formData.append('client_id', this.client_id);
380
- formData.append('client_secret', this.client_secret);
381
- formData.append('code', code);
382
- formData.append('redirect_uri', redirectUri);
383
-
384
- const response = await axios.post(this.tokenAPI, formData.toString(), {
385
- headers: {
386
- 'Content-Type': 'application/x-www-form-urlencoded'
387
- }
388
- });
389
-
390
- const tokenData = response.data;
391
-
392
- if (!tokenData || !tokenData.access_token) {
393
- errorLog('获取 token 失败:响应中未包含 access_token', spinner);
394
- errorLog(`响应数据: ${JSON.stringify(tokenData)}`);
395
- process.exit(1);
396
- }
397
-
398
- successLog('成功获取 access token', spinner);
399
- return tokenData;
400
- } catch (error) {
401
- errorLog('获取 token 失败', spinner);
402
- errorLog(`\n获取 token 失败: ${error.message}`);
403
- if (error.response) {
404
- errorLog(`响应数据: ${JSON.stringify(error.response.data)}`);
405
- }
406
- process.exit(1);
407
- }
408
- }
409
-
410
- /**
411
- * 使用 refresh_token 刷新 token
412
- * @param {string} refreshToken Refresh Token
413
- * @returns {Promise<object>} 新的 Token 数据
414
- */
415
- async refreshToken(refreshToken) {
416
- const spinner = ora('正在刷新授权信息(token)...').start();
417
-
418
- try {
419
- const formData = new URLSearchParams();
420
- formData.append('grant_type', 'refresh_token');
421
- formData.append('client_id', this.client_id);
422
- formData.append('client_secret', this.client_secret);
423
- formData.append('refresh_token', refreshToken);
424
-
425
- const response = await axios.post(this.tokenAPI, formData.toString(), {
426
- headers: {
427
- 'Content-Type': 'application/x-www-form-urlencoded'
428
- }
429
- });
430
-
431
- const tokenData = response.data;
432
-
433
- if (!tokenData || !tokenData.access_token) {
434
- errorLog('刷新授权信息失败:响应中未包含 access_token', spinner);
435
- errorLog(`响应数据: ${JSON.stringify(tokenData)}`);
436
- return null;
437
- }
438
-
439
- successLog('刷新授权信息成功(token)。', spinner);
440
- return tokenData;
441
- } catch (error) {
442
- errorLog('刷新授权信息失败', spinner);
443
- errorLog(`\n刷新授权信息失败: ${error.message}`);
444
- if (error.response) {
445
- errorLog(`响应数据: ${JSON.stringify(error.response.data)}`);
446
- }
447
- return null;
448
- }
449
- }
450
-
451
- /**
452
- * 执行登录流程
453
- */
454
- async login() {
455
- console.log('\n========== NeoCRM 登录授权 ==========\n');
456
-
457
- try {
458
- // 1. 启动本地回调服务器(自动获取可用端口)
459
- const { redirectUri, codePromise } = await this.startCallbackServer();
460
-
461
- // 2. 构建授权 URL
462
- const authUrl = this.buildAuthUrl(redirectUri);
463
- console.log('授权 URL:', authUrl);
464
-
465
- // 3. 打开浏览器进行授权
466
- console.log('\n正在打开浏览器进行授权...');
467
- await this.openBrowser(authUrl);
468
-
469
- // 4. 等待获取授权码
470
- const code = await codePromise;
471
- successLog('\n✓ 已获取授权码');
472
-
473
- // 5. 使用授权码获取 token
474
- const tokenData = await this.getTokenByCode(code, redirectUri);
475
-
476
- // 6. 保存 token 到本地
477
- this.saveToken(tokenData);
478
-
479
- console.log('\n========== 登录成功 ==========\n');
480
- console.log(`已缓存授权信息到: ${this.tokenFile}`);
481
- console.log(`实例地址: ${tokenData.instance_uri || '未返回'}`);
482
- console.log(`租户 ID: ${tokenData.tenant_id || '未返回'}`);
483
- console.log(`授权信息有效期(access_token): ${tokenData.expires_in || 7200} 秒`);
484
- console.log(
485
- `自动刷新授权信息有效期(refresh_token): ${
486
- tokenData.refresh_token_expires_in || 2592000
487
- } 秒`
488
- );
489
-
490
- return tokenData;
491
- } catch (error) {
492
- errorLog(`\n登录失败: ${error.message}`);
493
- process.exit(1);
494
- }
495
- }
496
-
497
- /**
498
- * 执行登出流程
499
- */
500
- async logout() {
501
- console.log('\n========== NeoCRM 登出 ==========\n');
502
-
503
- if (!fs.existsSync(this.tokenFile)) {
504
- console.log('当前未登录,无需登出。');
505
- return;
506
- }
507
-
508
- try {
509
- this.clearToken();
510
- successLog(`已清除授权信息,下次登录需要重新授权。`);
511
- console.log('\n登出成功!\n');
512
- } catch (error) {
513
- errorLog(`登出失败: ${error.message}`);
514
- process.exit(1);
515
- }
516
- }
517
-
518
- /**
519
- * 获取有效的 token(自动刷新)
520
- * @returns {Promise<object>} Token 数据
521
- */
522
- async getValidToken() {
523
- const tokenData = this.readToken();
524
-
525
- if (!tokenData) {
526
- errorLog('未找到授权信息,请先执行 neo login 进行登录。');
527
- process.exit(1);
528
- }
529
-
530
- // 检查 token 是否过期
531
- if (this.isTokenExpired(tokenData)) {
532
- console.log('授权信息已过期,正在尝试刷新...');
533
-
534
- if (!tokenData.refresh_token) {
535
- errorLog('自动刷新授权信息失败,请重新登录(neo login)。');
536
- process.exit(1);
537
- }
538
-
539
- // 使用 refresh_token 刷新
540
- const newTokenData = await this.refreshToken(tokenData.refresh_token);
541
-
542
- if (!newTokenData) {
543
- errorLog('刷新授权信息失败,请重新登录 (neo login)');
544
- process.exit(1);
545
- }
546
-
547
- // 保存新的 token
548
- this.saveToken(newTokenData);
549
- return newTokenData;
550
- }
551
-
552
- return tokenData;
553
- }
554
-
555
- /**
556
- * 获取 access token 字符串
557
- * @returns {Promise<string>} Access Token
558
- */
559
- async getAccessToken() {
560
- const tokenData = await this.getValidToken();
561
- return tokenData.access_token;
562
- }
563
- }
564
-
565
- module.exports = NeoLoginService;
@@ -1,125 +0,0 @@
1
- const _ = require('lodash');
2
-
3
- // Neo 共享出来的依赖模块
4
- const NeoCommonModules = {
5
- react: '^16.13.1',
6
- 'react-dom': '^16.13.1',
7
- mobx: '^6.3.0',
8
- 'mobx-react': '^7.0.0',
9
- 'mobx-state-tree': '^5.4.0',
10
- echarts: '5.4.2',
11
- antd: '4.9.4',
12
- 'antd-mobile': '2.3.4',
13
- '@ant-design/icons': '^4.8.0',
14
- 'video-react': '0.14.1',
15
- axios: '^0.27.2',
16
- classnames: '^2.3.2',
17
- qs: '^6.11.0',
18
- lodash: '^4.17.21',
19
- 'neo-ui-component-web': '^1.0.0',
20
- 'neo-ui-common': '^1.0.0',
21
- 'neo-open-api': '^1.0.11',
22
- amis: '^1.1.5',
23
- };
24
-
25
- // 根据 Neo 共享出来的依赖模块,获取 externals 配置
26
- const getExternalsByNeoCommonModules = (cmpNeoExternals) => {
27
- const externals = {};
28
- Object.keys(NeoCommonModules).forEach(moduleName => {
29
- externals[moduleName] = `commonjs ${moduleName}`;
30
- });
31
-
32
- // 如果自定义组件有共享的依赖模块,则合并到 externals 中
33
- if (cmpNeoExternals && cmpNeoExternals.length > 0) {
34
- cmpNeoExternals.forEach(moduleName => {
35
- externals[moduleName] = `commonjs ${moduleName}`;
36
- });
37
- }
38
-
39
- return externals;
40
- };
41
-
42
- // 用于添加共享的依赖模块
43
- const addNeoCommonModules = (modules) => {
44
- if (!window.__NeoCommonModules) {
45
- window.__NeoCommonModules = {}
46
- }
47
- if (isPlainObject(modules)) {
48
- const moduleIds = Object.keys(modules)
49
- moduleIds.forEach((moduleId) => {
50
- const curModule = modules[moduleId];
51
- const curCommonModule = window.__NeoCommonModules[moduleId];
52
-
53
- /**
54
- * 如果 Neo 共享出来的依赖模块已经存在,则合并到 window.__NeoCommonModules 中
55
- * 目的:解决依赖加载顺序问题,确保存在依赖的组件无论其加载顺序如何都能正常运行。
56
- *
57
- * 疑问1: 为什么 neoRequire 要返回一个 空的默认模块对象?
58
- * 答:组件A 依赖 组件B 时,当 组件A 先加载(挂载对应的 asset 资源脚本)会报错,为了避免挂载时报错返回一个默认的空模块对象。
59
- * 疑问2: 为什么不直接替换已有的模块,而是进行覆盖式合并(保持引用关联)?
60
- * 答:为了避免依赖模块的引用关系被破坏,保持引用关联。确保动态注册进来的模块可以被提前挂载的组件所使用。
61
- */
62
- if (curCommonModule && Object.keys(curCommonModule).length < 3) {
63
- // 如果是默认模块对象,则覆盖式合并(保持引用关联)
64
- window.__NeoCommonModules[moduleId] = Object.assign(window.__NeoCommonModules[moduleId], curModule);
65
-
66
- // 处理模块中的特殊属性
67
- if (curModule.__esModule !== undefined) {
68
- window.__NeoCommonModules[moduleId].__esModule = curModule.__esModule;
69
- }
70
- if (curModule.default !== undefined) {
71
- window.__NeoCommonModules[moduleId].default = curModule.default;
72
- }
73
- } else {
74
- window.__NeoCommonModules[moduleId] = curModule
75
- }
76
- })
77
- }
78
- }
79
-
80
- // 用于添加自定义组件的远程依赖组件
81
- const addNeoRemoteDeps = (remoteDeps) => {
82
- if (!window.__NeoCommonModules) {
83
- window.__NeoCommonModules = {}
84
- }
85
- if (!window.__NeoCommonModules.__neoRemoteDeps) {
86
- window.__NeoCommonModules.__neoRemoteDeps = {}
87
- }
88
- if (_.isPlainObject(remoteDeps)) {
89
- window.__NeoCommonModules.__neoRemoteDeps = Object.assign(window.__NeoCommonModules.__neoRemoteDeps, remoteDeps);
90
- }
91
- }
92
-
93
- const initNeoRequire = () => {
94
- if (!window.neoRequire) {
95
- // 用于加载 Neo 共享出来的依赖模块
96
- window.neoRequire = (moduleName) => {
97
- return window.__NeoCommonModules[moduleName] || window[moduleName];
98
- };
99
- }
100
- };
101
-
102
- /**
103
- * 用于加载 Neo 共享出来的依赖模块
104
- * @param moduleName 模块名称
105
- * @returns 模块对象或 undefined
106
- */
107
- const neoRequire = (moduleName) => {
108
- const defaultModule = { cmpType: moduleName, __esModule: true }; // 默认模块
109
- if (!window.__NeoCommonModules) {
110
- window.__NeoCommonModules = {}
111
- }
112
- if (window.__NeoCommonModules[moduleName]) {
113
- return window.__NeoCommonModules[moduleName]
114
- } else {
115
- window.__NeoCommonModules[moduleName] = defaultModule;
116
- return window.__NeoCommonModules[moduleName];
117
- }
118
- }
119
-
120
- module.exports = {
121
- initNeoRequire,
122
- addNeoCommonModules,
123
- addNeoRemoteDeps,
124
- getExternalsByNeoCommonModules
125
- };