neo-cmp-cli 1.8.6-beta.2 → 1.8.6-beta.3

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 (154) hide show
  1. package/dist/_virtual/AddNeoRequirePlugin.js +8 -0
  2. package/dist/_virtual/OverloadYield.js +5 -0
  3. package/dist/_virtual/_commonjsHelpers.js +40 -0
  4. package/dist/_virtual/array-set.js +5 -0
  5. package/dist/_virtual/base64-vlq.js +5 -0
  6. package/dist/_virtual/base64.js +5 -0
  7. package/dist/_virtual/binary-search.js +5 -0
  8. package/dist/_virtual/createCmpByZip.js +8 -0
  9. package/dist/_virtual/deleteCmp.js +8 -0
  10. package/dist/_virtual/index.js +9 -0
  11. package/dist/_virtual/mapping-list.js +5 -0
  12. package/dist/_virtual/neoLogin.js +8 -0
  13. package/dist/_virtual/neoService.js +8 -0
  14. package/dist/_virtual/openProject.js +8 -0
  15. package/dist/_virtual/publish2oss.js +8 -0
  16. package/dist/_virtual/pullCmp.js +8 -0
  17. package/dist/_virtual/pushCmp.js +8 -0
  18. package/dist/_virtual/quick-sort.js +5 -0
  19. package/dist/_virtual/regenerator.js +5 -0
  20. package/dist/_virtual/regeneratorAsync.js +5 -0
  21. package/dist/_virtual/regeneratorAsyncGen.js +5 -0
  22. package/dist/_virtual/regeneratorAsyncIterator.js +5 -0
  23. package/dist/_virtual/regeneratorDefine.js +5 -0
  24. package/dist/_virtual/regeneratorKeys.js +5 -0
  25. package/dist/_virtual/regeneratorRuntime.js +5 -0
  26. package/dist/_virtual/regeneratorValues.js +5 -0
  27. package/dist/_virtual/source-map-consumer.js +5 -0
  28. package/dist/_virtual/source-map-generator.js +5 -0
  29. package/dist/_virtual/source-map-support.js +5 -0
  30. package/dist/_virtual/source-map.js +5 -0
  31. package/dist/_virtual/source-node.js +5 -0
  32. package/dist/_virtual/typeof.js +5 -0
  33. package/dist/_virtual/typescript.js +5 -0
  34. package/dist/_virtual/util.js +5 -0
  35. package/dist/config/auth.config.js +50 -0
  36. package/dist/config/default.config.js +225 -0
  37. package/dist/config/index.js +27 -0
  38. package/dist/main.js +9 -0
  39. package/dist/main2.js +261 -0
  40. package/dist/module/inspect.js +64 -0
  41. package/dist/module/neoInit.js +69 -0
  42. package/dist/module/neoInitByCopy.js +81 -0
  43. package/dist/neo/neoLogin.js +663 -0
  44. package/dist/neo/neoRequire.js +118 -0
  45. package/dist/neo/neoService.js +1246 -0
  46. package/dist/node_modules/@babel/runtime/helpers/OverloadYield.js +19 -0
  47. package/dist/node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js +29 -0
  48. package/dist/node_modules/@babel/runtime/helpers/esm/extends.js +13 -0
  49. package/dist/node_modules/@babel/runtime/helpers/regenerator.js +105 -0
  50. package/dist/node_modules/@babel/runtime/helpers/regeneratorAsync.js +24 -0
  51. package/dist/node_modules/@babel/runtime/helpers/regeneratorAsyncGen.js +23 -0
  52. package/dist/node_modules/@babel/runtime/helpers/regeneratorAsyncIterator.js +50 -0
  53. package/dist/node_modules/@babel/runtime/helpers/regeneratorDefine.js +37 -0
  54. package/dist/node_modules/@babel/runtime/helpers/regeneratorKeys.js +25 -0
  55. package/dist/node_modules/@babel/runtime/helpers/regeneratorRuntime.js +98 -0
  56. package/dist/node_modules/@babel/runtime/helpers/regeneratorValues.js +35 -0
  57. package/dist/node_modules/@babel/runtime/helpers/typeof.js +25 -0
  58. package/dist/node_modules/@babel/runtime/regenerator/index.js +29 -0
  59. package/dist/node_modules/buffer-from/index.js +57 -0
  60. package/dist/node_modules/source-map/lib/array-set.js +134 -0
  61. package/dist/node_modules/source-map/lib/base64-vlq.js +144 -0
  62. package/dist/node_modules/source-map/lib/base64.js +81 -0
  63. package/dist/node_modules/source-map/lib/binary-search.js +122 -0
  64. package/dist/node_modules/source-map/lib/mapping-list.js +94 -0
  65. package/dist/node_modules/source-map/lib/quick-sort.js +126 -0
  66. package/dist/node_modules/source-map/lib/source-map-consumer.js +1018 -0
  67. package/dist/node_modules/source-map/lib/source-map-generator.js +385 -0
  68. package/dist/node_modules/source-map/lib/source-node.js +400 -0
  69. package/dist/node_modules/source-map/lib/util.js +449 -0
  70. package/dist/node_modules/source-map/source-map.js +25 -0
  71. package/dist/node_modules/source-map-support/source-map-support.js +610 -0
  72. package/dist/node_modules/typescript/lib/typescript.js +22376 -0
  73. package/dist/oss/publish2oss.js +378 -0
  74. package/dist/plugins/AddNeoRequirePlugin.js +178 -0
  75. package/dist/utils/autoEntryRootDir.js +98 -0
  76. package/dist/utils/cmpUtils/createCmpByTemplate.js +73 -0
  77. package/dist/utils/cmpUtils/createCmpByZip.js +530 -0
  78. package/dist/utils/cmpUtils/createCommonModulesCode.js +84 -0
  79. package/dist/utils/cmpUtils/deleteCmp.js +98 -0
  80. package/dist/utils/cmpUtils/getCmpModelRegisterCode.js +38 -0
  81. package/dist/utils/cmpUtils/getCmpPreviewCode.js +37 -0
  82. package/dist/utils/cmpUtils/getCmpRegisterCode.js +38 -0
  83. package/dist/utils/cmpUtils/getCmpTypeByDir.js +58 -0
  84. package/dist/utils/cmpUtils/hasCmpTypeByDir.js +25 -0
  85. package/dist/utils/cmpUtils/previewCmp.js +74 -0
  86. package/dist/utils/cmpUtils/pullCmp.js +144 -0
  87. package/dist/utils/cmpUtils/pushCmp.js +290 -0
  88. package/dist/utils/common.js +121 -0
  89. package/dist/utils/configureNeoBuild.js +153 -0
  90. package/dist/utils/generateEntries.js +73 -0
  91. package/dist/utils/neoConfigInit.js +25 -0
  92. package/dist/utils/neoParams.js +23 -0
  93. package/dist/utils/pathUtils.js +48 -0
  94. package/dist/utils/projectNameValidator.js +89 -0
  95. package/dist/utils/projectUtils/createCmpProjectByTemplate.js +74 -0
  96. package/dist/utils/projectUtils/createCmpProjectZip.js +135 -0
  97. package/dist/utils/projectUtils/getEntries.js +99 -0
  98. package/dist/utils/projectUtils/getEntriesWithAutoRegister.js +127 -0
  99. package/dist/utils/projectUtils/hasNeoProject.js +31 -0
  100. package/dist/utils/projectUtils/openProject.js +168 -0
  101. package/dist/utils/projectUtils/updatePublishLog.js +45 -0
  102. package/dist/utils/replaceInFilesByMap.js +70 -0
  103. package/dist/utils/replaceInPackage.js +151 -0
  104. package/dist/utils/resetPackageVersion.js +134 -0
  105. package/package.json +2 -2
  106. package/src/config/auth.config.js +0 -27
  107. package/src/config/default.config.js +0 -176
  108. package/src/config/index.js +0 -9
  109. package/src/initData/defaultTemplate.html +0 -13
  110. package/src/initData/neo.config.js +0 -138
  111. package/src/module/inspect.js +0 -41
  112. package/src/module/neoInit.js +0 -55
  113. package/src/module/neoInitByCopy.js +0 -61
  114. package/src/neo/NeoUMDContent.js +0 -30
  115. package/src/neo/neoLogin.js +0 -565
  116. package/src/neo/neoRequire.js +0 -125
  117. package/src/neo/neoService.js +0 -874
  118. package/src/neo/webpack.mf.js +0 -60
  119. package/src/neo/wrapperContent.js +0 -16
  120. package/src/oss/publish2oss.js +0 -348
  121. package/src/plugins/AddNeoRequirePlugin-v1.js +0 -47
  122. package/src/plugins/AddNeoRequirePlugin.js +0 -179
  123. package/src/plugins/README.md +0 -109
  124. package/src/utils/autoEntryRootDir.js +0 -85
  125. package/src/utils/cmpUtils/createCmpByTemplate.js +0 -60
  126. package/src/utils/cmpUtils/createCmpByZip.js +0 -408
  127. package/src/utils/cmpUtils/createCommonModulesCode.js +0 -121
  128. package/src/utils/cmpUtils/deleteCmp.js +0 -63
  129. package/src/utils/cmpUtils/getCmpModelRegisterCode.js +0 -31
  130. package/src/utils/cmpUtils/getCmpPreviewCode.js +0 -43
  131. package/src/utils/cmpUtils/getCmpRegisterCode.js +0 -31
  132. package/src/utils/cmpUtils/getCmpTypeByDir.js +0 -41
  133. package/src/utils/cmpUtils/hasCmpTypeByDir.js +0 -11
  134. package/src/utils/cmpUtils/previewCmp.js +0 -55
  135. package/src/utils/cmpUtils/pullCmp.js +0 -104
  136. package/src/utils/cmpUtils/pushCmp.js +0 -230
  137. package/src/utils/common.js +0 -107
  138. package/src/utils/configureNeoBuild.js +0 -109
  139. package/src/utils/generateEntries.js +0 -63
  140. package/src/utils/neoConfigInit.js +0 -13
  141. package/src/utils/neoParams.js +0 -12
  142. package/src/utils/pathUtils.js +0 -23
  143. package/src/utils/projectNameValidator.js +0 -76
  144. package/src/utils/projectUtils/createCmpProjectByTemplate.js +0 -59
  145. package/src/utils/projectUtils/createCmpProjectZip.js +0 -120
  146. package/src/utils/projectUtils/getEntries.js +0 -80
  147. package/src/utils/projectUtils/getEntriesWithAutoRegister.js +0 -108
  148. package/src/utils/projectUtils/hasNeoProject.js +0 -17
  149. package/src/utils/projectUtils/openProject.js +0 -94
  150. package/src/utils/projectUtils/updatePublishLog.js +0 -30
  151. package/src/utils/replaceInFiles.js +0 -47
  152. package/src/utils/replaceInFilesByMap.js +0 -54
  153. package/src/utils/replaceInPackage.js +0 -134
  154. package/src/utils/resetPackageVersion.js +0 -115
@@ -0,0 +1,663 @@
1
+ 'use strict';
2
+
3
+ var require$$0$1 = require('axios');
4
+ var require$$0 = require('node:fs');
5
+ var require$$1 = require('node:path');
6
+ var require$$3 = require('ora');
7
+ var require$$4 = require('node:http');
8
+ var require$$5 = require('node:url');
9
+ var require$$2 = require('open');
10
+ var require$$7 = require('node:net');
11
+ require('portfinder');
12
+ var common = require('../utils/common.js');
13
+ var auth_config = require('../config/auth.config.js');
14
+ var asyncToGenerator = require('../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js');
15
+ var _extends = require('../node_modules/@babel/runtime/helpers/esm/extends.js');
16
+ var index = require('../_virtual/index.js');
17
+
18
+ var axios = require$$0$1;
19
+ var fs = require$$0;
20
+ var path = require$$1;
21
+ var ora = require$$3;
22
+ var http = require$$4;
23
+ var url = require$$5;
24
+ var open = require$$2;
25
+ var net = require$$7;
26
+ var _require = common.__require(),
27
+ errorLog = _require.errorLog,
28
+ successLog = _require.successLog;
29
+ var neoAuthConfig = auth_config.__require();
30
+
31
+ /**
32
+ * Neo 登录授权服务类
33
+ * 实现 OAuth2 授权码模式的登录/登出功能
34
+ */
35
+ var NeoLoginService = /*#__PURE__*/function () {
36
+ /**
37
+ * 初始化登录服务
38
+ * @param {object} config 授权配置信息
39
+ * @param {string} config.loginURL 登录授权 URL
40
+ * @param {string} config.tokenAPI Token 获取接口地址
41
+ * @param {string} config.response_type 认证类型 (code)
42
+ * @param {string} config.client_id 客户端 ID
43
+ * @param {string} config.client_secret 客户端秘钥
44
+ * @param {string} config.scope 授权范围 (all)
45
+ * @param {string} config.oauthType OAuth 类型 (standard)
46
+ * @param {string} config.access_type 访问类型 (offline/online)
47
+ * @param {string} config.grant_type 授权类型 (authorization_code)
48
+ */
49
+ function NeoLoginService(config) {
50
+ if (config === void 0) {
51
+ config = {};
52
+ }
53
+ var _config = config,
54
+ loginURL = _config.loginURL,
55
+ tokenAPI = _config.tokenAPI;
56
+
57
+ // 验证必需的配置项
58
+ if (!loginURL || !tokenAPI) {
59
+ throw new Error('auth.config.js 配置不完整,需要包含 loginURL、tokenAPI');
60
+ }
61
+ this.loginURL = loginURL;
62
+ this.tokenAPI = tokenAPI;
63
+ this.response_type = neoAuthConfig.response_type || 'code';
64
+ this.client_id = neoAuthConfig.client_id;
65
+ this.client_secret = neoAuthConfig.client_secret;
66
+ this.scope = neoAuthConfig.scope || 'all';
67
+ this.oauthType = neoAuthConfig.oauthType || 'standard';
68
+ this.access_type = neoAuthConfig.access_type || 'offline';
69
+ this.grant_type = neoAuthConfig.grant_type || 'authorization_code';
70
+
71
+ // Token 存储路径(在当前项目根目录的 .neo-cli 文件夹下)
72
+ this.tokenDir = path.join(process.cwd(), '.neo-cli');
73
+ this.tokenFile = path.join(this.tokenDir, 'token.json');
74
+ }
75
+
76
+ /**
77
+ * 确保 token 存储目录存在
78
+ */
79
+ var _proto = NeoLoginService.prototype;
80
+ _proto.ensureTokenDir = function ensureTokenDir() {
81
+ if (!fs.existsSync(this.tokenDir)) {
82
+ fs.mkdirSync(this.tokenDir, {
83
+ recursive: true
84
+ });
85
+ }
86
+ }
87
+
88
+ /**
89
+ * 保存 token 到本地文件
90
+ * @param {object} tokenData Token 数据
91
+ */;
92
+ _proto.saveToken = function saveToken(tokenData) {
93
+ this.ensureTokenDir();
94
+ var tokenInfo = _extends({}, tokenData, {
95
+ savedAt: Date.now(),
96
+ expiresAt: Date.now() + (tokenData.expires_in || 7200) * 1000
97
+ });
98
+ fs.writeFileSync(this.tokenFile, JSON.stringify(tokenInfo, null, 2), 'utf-8');
99
+ }
100
+
101
+ /**
102
+ * 读取本地保存的 token
103
+ * @returns {object|null} Token 数据,如果不存在或已过期则返回 null
104
+ */;
105
+ _proto.readToken = function readToken() {
106
+ if (!fs.existsSync(this.tokenFile)) {
107
+ return null;
108
+ }
109
+ try {
110
+ var tokenData = JSON.parse(fs.readFileSync(this.tokenFile, 'utf-8'));
111
+ return tokenData;
112
+ } catch (error) {
113
+ errorLog("\u8BFB\u53D6 token \u6587\u4EF6\u5931\u8D25: " + error.message);
114
+ return null;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * 检查 token 是否过期
120
+ * @param {object} tokenData Token 数据
121
+ * @returns {boolean} true 表示已过期,false 表示未过期
122
+ */;
123
+ _proto.isTokenExpired = function isTokenExpired(tokenData) {
124
+ if (!tokenData || !tokenData.expiresAt) {
125
+ return true;
126
+ }
127
+ // 提前 5 分钟判断为过期,避免边缘情况
128
+ return Date.now() >= tokenData.expiresAt - 5 * 60 * 1000;
129
+ }
130
+
131
+ /**
132
+ * 清除本地保存的 token
133
+ */;
134
+ _proto.clearToken = function clearToken() {
135
+ if (fs.existsSync(this.tokenFile)) {
136
+ fs.unlinkSync(this.tokenFile);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * 生成回调地址
142
+ * @param {number} port 端口号
143
+ * @returns {string} 回调地址
144
+ */;
145
+ _proto.getRedirectURI = function getRedirectURI(port) {
146
+ return "http://localhost:" + port;
147
+ }
148
+
149
+ /**
150
+ * 构建授权 URL
151
+ * @param {string} redirectUri 回调地址
152
+ * @returns {string} 授权 URL
153
+ */;
154
+ _proto.buildAuthUrl = function buildAuthUrl(redirectUri) {
155
+ var params = new URLSearchParams({
156
+ response_type: this.response_type,
157
+ client_id: this.client_id,
158
+ redirect_uri: redirectUri,
159
+ scope: this.scope,
160
+ oauthType: this.oauthType,
161
+ access_type: this.access_type
162
+ });
163
+ return this.loginURL + "?" + params.toString();
164
+ }
165
+
166
+ /**
167
+ * 打开浏览器访问授权 URL
168
+ * @param {string} authUrl 授权 URL
169
+ */;
170
+ _proto.openBrowser =
171
+ /*#__PURE__*/
172
+ function () {
173
+ var _openBrowser = asyncToGenerator(/*#__PURE__*/index.mark(function _callee(authUrl) {
174
+ var _t;
175
+ return index.wrap(function (_context) {
176
+ while (1) switch (_context.prev = _context.next) {
177
+ case 0:
178
+ _context.prev = 0;
179
+ _context.next = 1;
180
+ return open(authUrl);
181
+ case 1:
182
+ _context.next = 3;
183
+ break;
184
+ case 2:
185
+ _context.prev = 2;
186
+ _t = _context["catch"](0);
187
+ errorLog("\u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668: " + _t.message);
188
+ console.log("\n\u8BF7\u624B\u52A8\u8BBF\u95EE\u4EE5\u4E0B URL \u8FDB\u884C\u6388\u6743:\n" + authUrl + "\n");
189
+ case 3:
190
+ case "end":
191
+ return _context.stop();
192
+ }
193
+ }, _callee, null, [[0, 2]]);
194
+ }));
195
+ function openBrowser(_x) {
196
+ return _openBrowser.apply(this, arguments);
197
+ }
198
+ return openBrowser;
199
+ }()
200
+ /**
201
+ * 检测端口是否被占用
202
+ * @param {number} port 端口号
203
+ * @returns {Promise<boolean>} true 表示端口被占用,false 表示端口可用
204
+ */
205
+ ;
206
+ _proto.isPortInUse =
207
+ /*#__PURE__*/
208
+ function () {
209
+ var _isPortInUse = asyncToGenerator(/*#__PURE__*/index.mark(function _callee2(port) {
210
+ return index.wrap(function (_context2) {
211
+ while (1) switch (_context2.prev = _context2.next) {
212
+ case 0:
213
+ return _context2.abrupt("return", new Promise(function (resolve) {
214
+ var server = net.createServer();
215
+ server.once('error', function (err) {
216
+ if (err.code === 'EADDRINUSE') {
217
+ resolve(true); // 端口被占用
218
+ } else {
219
+ resolve(false); // 其他错误,假设端口可用
220
+ }
221
+ });
222
+ server.once('listening', function () {
223
+ // 端口可用,立即关闭服务器
224
+ server.once('close', function () {
225
+ resolve(false); // 端口可用
226
+ });
227
+ server.close();
228
+ });
229
+ server.listen(port);
230
+ }));
231
+ case 1:
232
+ case "end":
233
+ return _context2.stop();
234
+ }
235
+ }, _callee2);
236
+ }));
237
+ function isPortInUse(_x2) {
238
+ return _isPortInUse.apply(this, arguments);
239
+ }
240
+ return isPortInUse;
241
+ }()
242
+ /**
243
+ * 启动本地服务器接收授权码(code)
244
+ * @returns {Promise<{redirectUri: string, codePromise: Promise<string>}>} 回调地址和授权码Promise
245
+ */
246
+ ;
247
+ _proto.startCallbackServer =
248
+ /*#__PURE__*/
249
+ function () {
250
+ var _startCallbackServer = asyncToGenerator(/*#__PURE__*/index.mark(function _callee3() {
251
+ var redirectUri, redirectUrl, port, portInUse, codePromise;
252
+ return index.wrap(function (_context3) {
253
+ while (1) switch (_context3.prev = _context3.next) {
254
+ case 0:
255
+ redirectUri = neoAuthConfig.redirectUri;
256
+ redirectUrl = new URL(redirectUri);
257
+ port = parseInt(redirectUrl.port, 10); // 检测端口是否被占用
258
+ _context3.next = 1;
259
+ return this.isPortInUse(port);
260
+ case 1:
261
+ portInUse = _context3.sent;
262
+ if (portInUse) {
263
+ consoleError("\n\u8B66\u544A: \u7AEF\u53E3 " + port + " \u5DF2\u88AB\u5360\u7528\uFF0C\u8BF7\u8C03\u6574 redirectUri \u914D\u7F6E\u9879\uFF0C\u4F7F\u5176\u6307\u5411\u4E00\u4E2A\u672A\u88AB\u5360\u7528\u7684\u7AEF\u53E3\u3002");
264
+ process.exit(1);
265
+ /*
266
+ // 使用 portfinder 查找可用端口
267
+ try {
268
+ port = await portfinder.getPortPromise({
269
+ port: port, // 从配置的端口开始查找
270
+ stopPort: 9999 // 结束端口
271
+ });
272
+
273
+ // 更新 redirectUri 和 redirectUrl
274
+ redirectUri = this.getRedirectURI(port);
275
+ redirectUrl = new URL(redirectUri);
276
+ console.log(`已找到可用端口: ${port}`);
277
+ console.log(`回调地址已更新为: ${redirectUri}`);
278
+ } catch (error) {
279
+ errorLog(`无法找到可用端口: ${error.message}`);
280
+ throw new Error(`端口 ${port} 已被占用,且无法找到可用端口`);
281
+ }
282
+ */
283
+ }
284
+ codePromise = new Promise(function (resolve, reject) {
285
+ var server = http.createServer(function (req, res) {
286
+ var parsedUrl = url.parse(req.url, true);
287
+ if (parsedUrl.pathname === redirectUrl.pathname || parsedUrl.pathname === '/') {
288
+ var code = parsedUrl.query.code;
289
+ var error = parsedUrl.query.error;
290
+ if (error) {
291
+ res.writeHead(400, {
292
+ 'Content-Type': 'text/html; charset=utf-8'
293
+ });
294
+ res.end("\n <html>\n <head>\n <title>\u6388\u6743\u5931\u8D25</title>\n <style>\n .container {\n margin: 0 auto;\n padding-top: 30px;\n text-align: center;\n\n .error-title {\n color: red;\n }\n\n h1, p {\n text-align: center;\n margin-top: 30px;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1 class=\"error-title\">\u6388\u6743\u5931\u8D25</h1>\n <img src=\"https://custom-widgets.bj.bcebos.com/neocrmlogin.png\" alt=\"\u6388\u6743\u5931\u8D25\" />\n <p>\u9519\u8BEF\u4FE1\u606F: " + error + "</p>\n </div>\n </body>\n </html>\n ");
295
+ server.close();
296
+ reject(new Error("\u6388\u6743\u5931\u8D25: " + error));
297
+ return;
298
+ }
299
+ if (code) {
300
+ res.writeHead(200, {
301
+ 'Content-Type': 'text/html; charset=utf-8'
302
+ });
303
+ res.end("\n <html>\n <head>\n <title>\u6388\u6743\u6210\u529F</title>\n <style>\n .container {\n margin: 0 auto;\n padding-top: 30px;\n text-align: center;\n\n .success-title {\n color: green;\n }\n\n h1, p {\n text-align: center;\n margin-top: 30px;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1 class=\"success-title\">\u6388\u6743\u6210\u529F!</h1>\n <img src=\"https://custom-widgets.bj.bcebos.com/neocrmlogin.png\" alt=\"\u6388\u6743\u6210\u529F\" />\n <p>\u60A8\u5DF2\u6210\u529F\u6388\u6743\u5F00\u53D1\u8D26\u6237\uFF0C\u8BF7\u5173\u95ED\u6B64\u9875\u9762\u3002</p>\n </div>\n </body>\n </html>\n ");
304
+ server.close();
305
+ resolve(code);
306
+ return;
307
+ }
308
+ res.writeHead(400, {
309
+ 'Content-Type': 'text/html; charset=utf-8'
310
+ });
311
+ res.end("\n <html>\n <head>\n <title>\u6388\u6743\u5931\u8D25</title>\n <style>\n .container {\n margin: 0 auto;\n padding-top: 30px;\n text-align: center;\n\n .error-title {\n color: red;\n }\n\n h1, p {\n text-align: center;\n margin-top: 30px;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1 class=\"error-title\">\u6388\u6743\u5931\u8D25</h1>\n <img src=\"https://custom-widgets.bj.bcebos.com/neocrmlogin.png\" alt=\"\u6388\u6743\u5931\u8D25\" />\n <p>\u672A\u83B7\u53D6\u5230\u6388\u6743\u7801\u3002</p>\n </div>\n </body>\n </html>\n ");
312
+ server.close();
313
+ reject(new Error('未获取到授权码'));
314
+ } else {
315
+ res.writeHead(404, {
316
+ 'Content-Type': 'text/plain'
317
+ });
318
+ res.end('Not Found');
319
+ }
320
+ });
321
+ server.on('error', function (error) {
322
+ if (error.code === 'EADDRINUSE') {
323
+ reject(new Error("\u7AEF\u53E3 " + port + " \u5DF2\u88AB\u5360\u7528\uFF0C\u65E0\u6CD5\u542F\u52A8\u56DE\u8C03\u670D\u52A1\u5668"));
324
+ } else {
325
+ reject(error);
326
+ }
327
+ });
328
+ server.listen(port, function () {
329
+ console.log("\n\u672C\u5730\u56DE\u8C03\u670D\u52A1\u5668\u5DF2\u542F\u52A8\uFF0C\u76D1\u542C\u7AEF\u53E3: " + port);
330
+ console.log("\u56DE\u8C03\u5730\u5740: " + redirectUri);
331
+ });
332
+
333
+ // 设置超时(5 分钟)
334
+ setTimeout(function () {
335
+ server.close();
336
+ reject(new Error('授权超时,请重试'));
337
+ }, 5 * 60 * 1000);
338
+ });
339
+ return _context3.abrupt("return", {
340
+ redirectUri: redirectUri,
341
+ codePromise: codePromise
342
+ });
343
+ case 2:
344
+ case "end":
345
+ return _context3.stop();
346
+ }
347
+ }, _callee3, this);
348
+ }));
349
+ function startCallbackServer() {
350
+ return _startCallbackServer.apply(this, arguments);
351
+ }
352
+ return startCallbackServer;
353
+ }()
354
+ /**
355
+ * 使用授权码获取 token
356
+ * @param {string} code 授权码
357
+ * @param {string} redirectUri 回调地址
358
+ * @returns {Promise<object>} Token 数据
359
+ */
360
+ ;
361
+ _proto.getTokenByCode =
362
+ /*#__PURE__*/
363
+ function () {
364
+ var _getTokenByCode = asyncToGenerator(/*#__PURE__*/index.mark(function _callee4(code, redirectUri) {
365
+ var spinner, formData, response, tokenData, _t2;
366
+ return index.wrap(function (_context4) {
367
+ while (1) switch (_context4.prev = _context4.next) {
368
+ case 0:
369
+ spinner = ora('正在获取 access token...').start();
370
+ _context4.prev = 1;
371
+ formData = new URLSearchParams();
372
+ formData.append('grant_type', this.grant_type);
373
+ formData.append('client_id', this.client_id);
374
+ formData.append('client_secret', this.client_secret);
375
+ formData.append('code', code);
376
+ formData.append('redirect_uri', redirectUri);
377
+ _context4.next = 2;
378
+ return axios.post(this.tokenAPI, formData.toString(), {
379
+ headers: {
380
+ 'Content-Type': 'application/x-www-form-urlencoded'
381
+ }
382
+ });
383
+ case 2:
384
+ response = _context4.sent;
385
+ tokenData = response.data;
386
+ if (!tokenData || !tokenData.access_token) {
387
+ errorLog('获取 token 失败:响应中未包含 access_token', spinner);
388
+ errorLog("\u54CD\u5E94\u6570\u636E: " + JSON.stringify(tokenData));
389
+ process.exit(1);
390
+ }
391
+ successLog('成功获取 access token', spinner);
392
+ return _context4.abrupt("return", tokenData);
393
+ case 3:
394
+ _context4.prev = 3;
395
+ _t2 = _context4["catch"](1);
396
+ errorLog('获取 token 失败', spinner);
397
+ errorLog("\n\u83B7\u53D6 token \u5931\u8D25: " + _t2.message);
398
+ if (_t2.response) {
399
+ errorLog("\u54CD\u5E94\u6570\u636E: " + JSON.stringify(_t2.response.data));
400
+ }
401
+ process.exit(1);
402
+ case 4:
403
+ case "end":
404
+ return _context4.stop();
405
+ }
406
+ }, _callee4, this, [[1, 3]]);
407
+ }));
408
+ function getTokenByCode(_x3, _x4) {
409
+ return _getTokenByCode.apply(this, arguments);
410
+ }
411
+ return getTokenByCode;
412
+ }()
413
+ /**
414
+ * 使用 refresh_token 刷新 token
415
+ * @param {string} refreshToken Refresh Token
416
+ * @returns {Promise<object>} 新的 Token 数据
417
+ */
418
+ ;
419
+ _proto.refreshToken =
420
+ /*#__PURE__*/
421
+ function () {
422
+ var _refreshToken2 = asyncToGenerator(/*#__PURE__*/index.mark(function _callee5(_refreshToken) {
423
+ var spinner, formData, response, tokenData, _t3;
424
+ return index.wrap(function (_context5) {
425
+ while (1) switch (_context5.prev = _context5.next) {
426
+ case 0:
427
+ spinner = ora('正在刷新授权信息(token)...').start();
428
+ _context5.prev = 1;
429
+ formData = new URLSearchParams();
430
+ formData.append('grant_type', 'refresh_token');
431
+ formData.append('client_id', this.client_id);
432
+ formData.append('client_secret', this.client_secret);
433
+ formData.append('refresh_token', _refreshToken);
434
+ _context5.next = 2;
435
+ return axios.post(this.tokenAPI, formData.toString(), {
436
+ headers: {
437
+ 'Content-Type': 'application/x-www-form-urlencoded'
438
+ }
439
+ });
440
+ case 2:
441
+ response = _context5.sent;
442
+ tokenData = response.data;
443
+ if (!(!tokenData || !tokenData.access_token)) {
444
+ _context5.next = 3;
445
+ break;
446
+ }
447
+ errorLog('刷新授权信息失败:响应中未包含 access_token', spinner);
448
+ errorLog("\u54CD\u5E94\u6570\u636E: " + JSON.stringify(tokenData));
449
+ return _context5.abrupt("return", null);
450
+ case 3:
451
+ successLog('刷新授权信息成功(token)。', spinner);
452
+ return _context5.abrupt("return", tokenData);
453
+ case 4:
454
+ _context5.prev = 4;
455
+ _t3 = _context5["catch"](1);
456
+ errorLog('刷新授权信息失败', spinner);
457
+ errorLog("\n\u5237\u65B0\u6388\u6743\u4FE1\u606F\u5931\u8D25: " + _t3.message);
458
+ if (_t3.response) {
459
+ errorLog("\u54CD\u5E94\u6570\u636E: " + JSON.stringify(_t3.response.data));
460
+ }
461
+ return _context5.abrupt("return", null);
462
+ case 5:
463
+ case "end":
464
+ return _context5.stop();
465
+ }
466
+ }, _callee5, this, [[1, 4]]);
467
+ }));
468
+ function refreshToken(_x5) {
469
+ return _refreshToken2.apply(this, arguments);
470
+ }
471
+ return refreshToken;
472
+ }()
473
+ /**
474
+ * 执行登录流程
475
+ */
476
+ ;
477
+ _proto.login =
478
+ /*#__PURE__*/
479
+ function () {
480
+ var _login = asyncToGenerator(/*#__PURE__*/index.mark(function _callee6() {
481
+ var _yield$this$startCall, redirectUri, codePromise, authUrl, code, tokenData, _t4;
482
+ return index.wrap(function (_context6) {
483
+ while (1) switch (_context6.prev = _context6.next) {
484
+ case 0:
485
+ console.log('\n========== NeoCRM 登录授权 ==========\n');
486
+ _context6.prev = 1;
487
+ _context6.next = 2;
488
+ return this.startCallbackServer();
489
+ case 2:
490
+ _yield$this$startCall = _context6.sent;
491
+ redirectUri = _yield$this$startCall.redirectUri;
492
+ codePromise = _yield$this$startCall.codePromise;
493
+ // 2. 构建授权 URL
494
+ authUrl = this.buildAuthUrl(redirectUri);
495
+ console.log('授权 URL:', authUrl);
496
+
497
+ // 3. 打开浏览器进行授权
498
+ console.log('\n正在打开浏览器进行授权...');
499
+ _context6.next = 3;
500
+ return this.openBrowser(authUrl);
501
+ case 3:
502
+ _context6.next = 4;
503
+ return codePromise;
504
+ case 4:
505
+ code = _context6.sent;
506
+ successLog('\n✓ 已获取授权码');
507
+
508
+ // 5. 使用授权码获取 token
509
+ _context6.next = 5;
510
+ return this.getTokenByCode(code, redirectUri);
511
+ case 5:
512
+ tokenData = _context6.sent;
513
+ // 6. 保存 token 到本地
514
+ this.saveToken(tokenData);
515
+ console.log('\n========== 登录成功 ==========\n');
516
+ console.log("\u5DF2\u7F13\u5B58\u6388\u6743\u4FE1\u606F\u5230: " + this.tokenFile);
517
+ console.log("\u5B9E\u4F8B\u5730\u5740: " + (tokenData.instance_uri || '未返回'));
518
+ console.log("\u79DF\u6237 ID: " + (tokenData.tenant_id || '未返回'));
519
+ console.log("\u6388\u6743\u4FE1\u606F\u6709\u6548\u671F\uFF08access_token\uFF09: " + (tokenData.expires_in || 7200) + " \u79D2");
520
+ console.log("\u81EA\u52A8\u5237\u65B0\u6388\u6743\u4FE1\u606F\u6709\u6548\u671F\uFF08refresh_token): " + (tokenData.refresh_token_expires_in || 2592000) + " \u79D2");
521
+ return _context6.abrupt("return", tokenData);
522
+ case 6:
523
+ _context6.prev = 6;
524
+ _t4 = _context6["catch"](1);
525
+ errorLog("\n\u767B\u5F55\u5931\u8D25: " + _t4.message);
526
+ process.exit(1);
527
+ case 7:
528
+ case "end":
529
+ return _context6.stop();
530
+ }
531
+ }, _callee6, this, [[1, 6]]);
532
+ }));
533
+ function login() {
534
+ return _login.apply(this, arguments);
535
+ }
536
+ return login;
537
+ }()
538
+ /**
539
+ * 执行登出流程
540
+ */
541
+ ;
542
+ _proto.logout =
543
+ /*#__PURE__*/
544
+ function () {
545
+ var _logout = asyncToGenerator(/*#__PURE__*/index.mark(function _callee7() {
546
+ return index.wrap(function (_context7) {
547
+ while (1) switch (_context7.prev = _context7.next) {
548
+ case 0:
549
+ console.log('\n========== NeoCRM 登出 ==========\n');
550
+ if (fs.existsSync(this.tokenFile)) {
551
+ _context7.next = 1;
552
+ break;
553
+ }
554
+ console.log('当前未登录,无需登出。');
555
+ return _context7.abrupt("return");
556
+ case 1:
557
+ try {
558
+ this.clearToken();
559
+ successLog("\u5DF2\u6E05\u9664\u6388\u6743\u4FE1\u606F\uFF0C\u4E0B\u6B21\u767B\u5F55\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002");
560
+ console.log('\n登出成功!\n');
561
+ } catch (error) {
562
+ errorLog("\u767B\u51FA\u5931\u8D25: " + error.message);
563
+ process.exit(1);
564
+ }
565
+ case 2:
566
+ case "end":
567
+ return _context7.stop();
568
+ }
569
+ }, _callee7, this);
570
+ }));
571
+ function logout() {
572
+ return _logout.apply(this, arguments);
573
+ }
574
+ return logout;
575
+ }()
576
+ /**
577
+ * 获取有效的 token(自动刷新)
578
+ * @returns {Promise<object>} Token 数据
579
+ */
580
+ ;
581
+ _proto.getValidToken =
582
+ /*#__PURE__*/
583
+ function () {
584
+ var _getValidToken = asyncToGenerator(/*#__PURE__*/index.mark(function _callee8() {
585
+ var tokenData, newTokenData;
586
+ return index.wrap(function (_context8) {
587
+ while (1) switch (_context8.prev = _context8.next) {
588
+ case 0:
589
+ tokenData = this.readToken();
590
+ if (!tokenData) {
591
+ errorLog('未找到授权信息,请先执行 neo login 进行登录。');
592
+ process.exit(1);
593
+ }
594
+
595
+ // 检查 token 是否过期
596
+ if (!this.isTokenExpired(tokenData)) {
597
+ _context8.next = 2;
598
+ break;
599
+ }
600
+ console.log('授权信息已过期,正在尝试刷新...');
601
+ if (!tokenData.refresh_token) {
602
+ errorLog('自动刷新授权信息失败,请重新登录(neo login)。');
603
+ process.exit(1);
604
+ }
605
+
606
+ // 使用 refresh_token 刷新
607
+ _context8.next = 1;
608
+ return this.refreshToken(tokenData.refresh_token);
609
+ case 1:
610
+ newTokenData = _context8.sent;
611
+ if (!newTokenData) {
612
+ errorLog('刷新授权信息失败,请重新登录 (neo login)');
613
+ process.exit(1);
614
+ }
615
+
616
+ // 保存新的 token
617
+ this.saveToken(newTokenData);
618
+ return _context8.abrupt("return", newTokenData);
619
+ case 2:
620
+ return _context8.abrupt("return", tokenData);
621
+ case 3:
622
+ case "end":
623
+ return _context8.stop();
624
+ }
625
+ }, _callee8, this);
626
+ }));
627
+ function getValidToken() {
628
+ return _getValidToken.apply(this, arguments);
629
+ }
630
+ return getValidToken;
631
+ }()
632
+ /**
633
+ * 获取 access token 字符串
634
+ * @returns {Promise<string>} Access Token
635
+ */
636
+ ;
637
+ _proto.getAccessToken =
638
+ /*#__PURE__*/
639
+ function () {
640
+ var _getAccessToken = asyncToGenerator(/*#__PURE__*/index.mark(function _callee9() {
641
+ var tokenData;
642
+ return index.wrap(function (_context9) {
643
+ while (1) switch (_context9.prev = _context9.next) {
644
+ case 0:
645
+ _context9.next = 1;
646
+ return this.getValidToken();
647
+ case 1:
648
+ tokenData = _context9.sent;
649
+ return _context9.abrupt("return", tokenData.access_token);
650
+ case 2:
651
+ case "end":
652
+ return _context9.stop();
653
+ }
654
+ }, _callee9, this);
655
+ }));
656
+ function getAccessToken() {
657
+ return _getAccessToken.apply(this, arguments);
658
+ }
659
+ return getAccessToken;
660
+ }();
661
+ return NeoLoginService;
662
+ }();
663
+ module.exports = NeoLoginService;