localsbnb-mcp-server 1.0.8 → 1.0.10

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 (178) hide show
  1. package/dist/auth/apiKeyManager.js +1 -121
  2. package/dist/auth/index.js +1 -3
  3. package/dist/auth/permissionChecker.js +1 -67
  4. package/dist/client/cacheManager.js +1 -64
  5. package/dist/client/httpClient.js +1 -125
  6. package/dist/client/index.js +1 -4
  7. package/dist/client/retryHandler.js +1 -68
  8. package/dist/config/index.js +1 -39
  9. package/dist/config/tools.js +1 -203
  10. package/dist/index.js +1 -33
  11. package/dist/package.json +4 -3
  12. package/dist/server.js +1 -129
  13. package/dist/start.mjs +1 -33
  14. package/dist/tools/channels/getChannelDetails.js +1 -30
  15. package/dist/tools/channels/index.js +1 -6
  16. package/dist/tools/channels/listChannels.js +1 -29
  17. package/dist/tools/finance/analyzeRevenue.js +1 -30
  18. package/dist/tools/finance/index.js +1 -8
  19. package/dist/tools/finance/queryFinancialData.js +1 -30
  20. package/dist/tools/finance/queryOperationalData.js +1 -30
  21. package/dist/tools/finance/queryOperationalDataV2.js +1 -175
  22. package/dist/tools/orders/cancelOrder.js +1 -27
  23. package/dist/tools/orders/getOrderDetails.js +1 -23
  24. package/dist/tools/orders/getOrderDetailsV2.js +1 -51
  25. package/dist/tools/orders/index.js +1 -12
  26. package/dist/tools/orders/ordersGetShared.js +1 -0
  27. package/dist/tools/orders/queryInHouseOrders.js +1 -0
  28. package/dist/tools/orders/queryOrders.js +1 -37
  29. package/dist/tools/orders/queryOrdersByDateRange.js +1 -0
  30. package/dist/tools/orders/queryPreArrivalOrders.js +1 -0
  31. package/dist/tools/orders/queryPreDepartureOrders.js +1 -0
  32. package/dist/tools/orders/queryTodayOrders.js +1 -393
  33. package/dist/tools/rooms/batchUpdatePrices.js +1 -40
  34. package/dist/tools/rooms/index.js +1 -7
  35. package/dist/tools/rooms/queryRoomPrices.js +1 -75
  36. package/dist/tools/rooms/queryRoomStatusNew.js +1 -70
  37. package/dist/tools/rooms/queryTodayRoomStatus.js +1 -70
  38. package/dist/tools/rooms/updateRoomPrice.js +1 -39
  39. package/dist/types/api.js +1 -3
  40. package/dist/types/index.js +1 -3
  41. package/dist/types/mcp.js +1 -2
  42. package/dist/types/tools.js +1 -2
  43. package/dist/utils/desensitize.js +1 -119
  44. package/dist/utils/errorHandler.js +1 -246
  45. package/dist/utils/index.js +1 -7
  46. package/dist/utils/logger.js +1 -37
  47. package/dist/utils/price.js +1 -9
  48. package/dist/utils/shanghaiDate.js +1 -44
  49. package/dist/utils/validator.js +1 -153
  50. package/package.json +4 -3
  51. package/dist/auth/apiKeyManager.d.ts +0 -61
  52. package/dist/auth/apiKeyManager.d.ts.map +0 -1
  53. package/dist/auth/apiKeyManager.js.map +0 -1
  54. package/dist/auth/index.d.ts +0 -3
  55. package/dist/auth/index.d.ts.map +0 -1
  56. package/dist/auth/index.js.map +0 -1
  57. package/dist/auth/permissionChecker.d.ts +0 -10
  58. package/dist/auth/permissionChecker.d.ts.map +0 -1
  59. package/dist/auth/permissionChecker.js.map +0 -1
  60. package/dist/client/cacheManager.d.ts +0 -24
  61. package/dist/client/cacheManager.d.ts.map +0 -1
  62. package/dist/client/cacheManager.js.map +0 -1
  63. package/dist/client/httpClient.d.ts +0 -12
  64. package/dist/client/httpClient.d.ts.map +0 -1
  65. package/dist/client/httpClient.js.map +0 -1
  66. package/dist/client/index.d.ts +0 -4
  67. package/dist/client/index.d.ts.map +0 -1
  68. package/dist/client/index.js.map +0 -1
  69. package/dist/client/retryHandler.d.ts +0 -18
  70. package/dist/client/retryHandler.d.ts.map +0 -1
  71. package/dist/client/retryHandler.js.map +0 -1
  72. package/dist/config/index.d.ts +0 -24
  73. package/dist/config/index.d.ts.map +0 -1
  74. package/dist/config/index.js.map +0 -1
  75. package/dist/config/tools.d.ts +0 -7
  76. package/dist/config/tools.d.ts.map +0 -1
  77. package/dist/config/tools.js.map +0 -1
  78. package/dist/index.d.ts +0 -3
  79. package/dist/index.d.ts.map +0 -1
  80. package/dist/index.js.map +0 -1
  81. package/dist/logs/combined.log +0 -30
  82. package/dist/logs/error.log +0 -0
  83. package/dist/server.d.ts +0 -26
  84. package/dist/server.d.ts.map +0 -1
  85. package/dist/server.js.map +0 -1
  86. package/dist/tools/channels/getChannelDetails.d.ts +0 -3
  87. package/dist/tools/channels/getChannelDetails.d.ts.map +0 -1
  88. package/dist/tools/channels/getChannelDetails.js.map +0 -1
  89. package/dist/tools/channels/index.d.ts +0 -1
  90. package/dist/tools/channels/index.d.ts.map +0 -1
  91. package/dist/tools/channels/index.js.map +0 -1
  92. package/dist/tools/channels/listChannels.d.ts +0 -3
  93. package/dist/tools/channels/listChannels.d.ts.map +0 -1
  94. package/dist/tools/channels/listChannels.js.map +0 -1
  95. package/dist/tools/finance/analyzeRevenue.d.ts +0 -3
  96. package/dist/tools/finance/analyzeRevenue.d.ts.map +0 -1
  97. package/dist/tools/finance/analyzeRevenue.js.map +0 -1
  98. package/dist/tools/finance/index.d.ts +0 -2
  99. package/dist/tools/finance/index.d.ts.map +0 -1
  100. package/dist/tools/finance/index.js.map +0 -1
  101. package/dist/tools/finance/queryFinancialData.d.ts +0 -3
  102. package/dist/tools/finance/queryFinancialData.d.ts.map +0 -1
  103. package/dist/tools/finance/queryFinancialData.js.map +0 -1
  104. package/dist/tools/finance/queryOperationalData.d.ts +0 -3
  105. package/dist/tools/finance/queryOperationalData.d.ts.map +0 -1
  106. package/dist/tools/finance/queryOperationalData.js.map +0 -1
  107. package/dist/tools/finance/queryOperationalDataV2.d.ts +0 -3
  108. package/dist/tools/finance/queryOperationalDataV2.d.ts.map +0 -1
  109. package/dist/tools/finance/queryOperationalDataV2.js.map +0 -1
  110. package/dist/tools/orders/cancelOrder.d.ts +0 -3
  111. package/dist/tools/orders/cancelOrder.d.ts.map +0 -1
  112. package/dist/tools/orders/cancelOrder.js.map +0 -1
  113. package/dist/tools/orders/getOrderDetails.d.ts +0 -3
  114. package/dist/tools/orders/getOrderDetails.d.ts.map +0 -1
  115. package/dist/tools/orders/getOrderDetails.js.map +0 -1
  116. package/dist/tools/orders/getOrderDetailsV2.d.ts +0 -3
  117. package/dist/tools/orders/getOrderDetailsV2.d.ts.map +0 -1
  118. package/dist/tools/orders/getOrderDetailsV2.js.map +0 -1
  119. package/dist/tools/orders/index.d.ts +0 -3
  120. package/dist/tools/orders/index.d.ts.map +0 -1
  121. package/dist/tools/orders/index.js.map +0 -1
  122. package/dist/tools/orders/queryOrders.d.ts +0 -3
  123. package/dist/tools/orders/queryOrders.d.ts.map +0 -1
  124. package/dist/tools/orders/queryOrders.js.map +0 -1
  125. package/dist/tools/orders/queryTodayOrders.d.ts +0 -3
  126. package/dist/tools/orders/queryTodayOrders.d.ts.map +0 -1
  127. package/dist/tools/orders/queryTodayOrders.js.map +0 -1
  128. package/dist/tools/rooms/batchUpdatePrices.d.ts +0 -3
  129. package/dist/tools/rooms/batchUpdatePrices.d.ts.map +0 -1
  130. package/dist/tools/rooms/batchUpdatePrices.js.map +0 -1
  131. package/dist/tools/rooms/index.d.ts +0 -6
  132. package/dist/tools/rooms/index.d.ts.map +0 -1
  133. package/dist/tools/rooms/index.js.map +0 -1
  134. package/dist/tools/rooms/queryRoomPrices.d.ts +0 -3
  135. package/dist/tools/rooms/queryRoomPrices.d.ts.map +0 -1
  136. package/dist/tools/rooms/queryRoomPrices.js.map +0 -1
  137. package/dist/tools/rooms/queryRoomStatusNew.d.ts +0 -28
  138. package/dist/tools/rooms/queryRoomStatusNew.d.ts.map +0 -1
  139. package/dist/tools/rooms/queryRoomStatusNew.js.map +0 -1
  140. package/dist/tools/rooms/queryTodayRoomStatus.d.ts +0 -3
  141. package/dist/tools/rooms/queryTodayRoomStatus.d.ts.map +0 -1
  142. package/dist/tools/rooms/queryTodayRoomStatus.js.map +0 -1
  143. package/dist/tools/rooms/updateRoomPrice.d.ts +0 -3
  144. package/dist/tools/rooms/updateRoomPrice.d.ts.map +0 -1
  145. package/dist/tools/rooms/updateRoomPrice.js.map +0 -1
  146. package/dist/types/api.d.ts +0 -122
  147. package/dist/types/api.d.ts.map +0 -1
  148. package/dist/types/api.js.map +0 -1
  149. package/dist/types/index.d.ts +0 -5
  150. package/dist/types/index.d.ts.map +0 -1
  151. package/dist/types/index.js.map +0 -1
  152. package/dist/types/mcp.d.ts +0 -41
  153. package/dist/types/mcp.d.ts.map +0 -1
  154. package/dist/types/mcp.js.map +0 -1
  155. package/dist/types/tools.d.ts +0 -93
  156. package/dist/types/tools.d.ts.map +0 -1
  157. package/dist/types/tools.js.map +0 -1
  158. package/dist/utils/desensitize.d.ts +0 -38
  159. package/dist/utils/desensitize.d.ts.map +0 -1
  160. package/dist/utils/desensitize.js.map +0 -1
  161. package/dist/utils/errorHandler.d.ts +0 -36
  162. package/dist/utils/errorHandler.d.ts.map +0 -1
  163. package/dist/utils/errorHandler.js.map +0 -1
  164. package/dist/utils/index.d.ts +0 -7
  165. package/dist/utils/index.d.ts.map +0 -1
  166. package/dist/utils/index.js.map +0 -1
  167. package/dist/utils/logger.d.ts +0 -4
  168. package/dist/utils/logger.d.ts.map +0 -1
  169. package/dist/utils/logger.js.map +0 -1
  170. package/dist/utils/price.d.ts +0 -5
  171. package/dist/utils/price.d.ts.map +0 -1
  172. package/dist/utils/price.js.map +0 -1
  173. package/dist/utils/shanghaiDate.d.ts +0 -31
  174. package/dist/utils/shanghaiDate.d.ts.map +0 -1
  175. package/dist/utils/shanghaiDate.js.map +0 -1
  176. package/dist/utils/validator.d.ts +0 -273
  177. package/dist/utils/validator.d.ts.map +0 -1
  178. package/dist/utils/validator.js.map +0 -1
@@ -1,121 +1 @@
1
- import { logger } from '../utils/logger.js';
2
- export class APIKeyManager {
3
- apiKey = null;
4
- scopes = [];
5
- hudsonAccessToken = null;
6
- campId = null;
7
- /**
8
- * 从环境变量加载API密钥
9
- */
10
- loadFromEnv() {
11
- this.apiKey = process.env.LUKEYUN_API_KEY || null;
12
- const scopesStr = process.env.LUKEYUN_API_SCOPES;
13
- this.scopes = scopesStr ? scopesStr.split(',').map((s) => s.trim()) : [];
14
- // 加载应用鉴权信息(APP_SECRET / APP_ID)
15
- this.hudsonAccessToken = process.env.APP_SECRET || null;
16
- this.campId = process.env.APP_ID || null;
17
- if (!this.apiKey) {
18
- logger.warn('API key not found in environment variables');
19
- }
20
- else {
21
- logger.info('API key loaded from environment', { hasScopes: this.scopes.length > 0 });
22
- }
23
- if (!this.hudsonAccessToken || !this.campId) {
24
- logger.warn('APP_SECRET or APP_ID not found in environment variables');
25
- }
26
- else {
27
- logger.info('Hudson credentials loaded from environment');
28
- }
29
- }
30
- /**
31
- * 从配置文件加载API密钥
32
- */
33
- loadFromConfig(config) {
34
- this.apiKey = config.apiKey || null;
35
- this.scopes = config.scopes || [];
36
- this.hudsonAccessToken = config.hudsonAccessToken || null;
37
- this.campId = config.campId || null;
38
- if (this.apiKey) {
39
- logger.info('API key loaded from config', { hasScopes: this.scopes.length > 0 });
40
- }
41
- if (this.hudsonAccessToken && this.campId) {
42
- logger.info('Hudson credentials loaded from config');
43
- }
44
- }
45
- /**
46
- * 设置API密钥
47
- */
48
- setAPIKey(apiKey, scopes) {
49
- this.apiKey = apiKey;
50
- this.scopes = scopes || [];
51
- logger.info('API key set', { hasScopes: this.scopes.length > 0 });
52
- }
53
- /**
54
- * 设置Hudson认证信息
55
- */
56
- setHudsonCredentials(accessToken, campId) {
57
- this.hudsonAccessToken = accessToken;
58
- this.campId = campId;
59
- logger.info('Hudson credentials set');
60
- }
61
- /**
62
- * 获取API密钥
63
- * 如果未配置,返回空字符串(用于仅使用Hudson认证的场景)
64
- */
65
- getAPIKey() {
66
- return this.apiKey || '';
67
- }
68
- /**
69
- * 检查是否配置了API密钥
70
- */
71
- hasAPIKey() {
72
- return this.apiKey !== null && this.apiKey !== '';
73
- }
74
- /**
75
- * 检查是否有指定权限
76
- */
77
- hasScope(scope) {
78
- // 如果有 * 权限,则拥有所有权限
79
- if (this.scopes.includes('*')) {
80
- return true;
81
- }
82
- return this.scopes.includes(scope);
83
- }
84
- /**
85
- * 获取所有权限范围
86
- */
87
- getScopes() {
88
- return [...this.scopes];
89
- }
90
- /**
91
- * 检查是否已配置
92
- */
93
- isConfigured() {
94
- return this.apiKey !== null;
95
- }
96
- /**
97
- * 检查Hudson认证是否已配置
98
- */
99
- isHudsonConfigured() {
100
- return this.hudsonAccessToken !== null && this.campId !== null;
101
- }
102
- /**
103
- * 获取Hudson访问令牌
104
- */
105
- getHudsonAccessToken() {
106
- if (!this.hudsonAccessToken) {
107
- throw new Error('APP_SECRET not configured. Please set APP_SECRET environment variable.');
108
- }
109
- return this.hudsonAccessToken;
110
- }
111
- /**
112
- * 获取Camp ID
113
- */
114
- getCampId() {
115
- if (!this.campId) {
116
- throw new Error('APP_ID not configured. Please set APP_ID environment variable.');
117
- }
118
- return this.campId;
119
- }
120
- }
121
- //# sourceMappingURL=apiKeyManager.js.map
1
+ function _0x465f(_0x57bcde,_0x258126){const _0x44a058=_0x44a0();return _0x465f=function(_0x465ffc,_0x3815f0){_0x465ffc=_0x465ffc-0x194;let _0x18aff5=_0x44a058[_0x465ffc];return _0x18aff5;},_0x465f(_0x57bcde,_0x258126);}(function(_0x4aa2e3,_0x2ea868){const _0x5de006=_0x4aa2e3();while(!![]){try{const _0x295cc7=parseInt(_0x465f(0x19a))/0x1*(-parseInt(_0x465f(0x1a2))/0x2)+parseInt(_0x465f(0x1a3))/0x3*(parseInt(_0x465f(0x1a4))/0x4)+parseInt(_0x465f(0x19e))/0x5+parseInt(_0x465f(0x1a1))/0x6+parseInt(_0x465f(0x1b2))/0x7*(-parseInt(_0x465f(0x196))/0x8)+parseInt(_0x465f(0x1b3))/0x9+-parseInt(_0x465f(0x1ac))/0xa;if(_0x295cc7===_0x2ea868)break;else _0x5de006['push'](_0x5de006['shift']());}catch(_0x8be641){_0x5de006['push'](_0x5de006['shift']());}}}(_0x44a0,0x9dab2));import{logger}from'../utils/logger.js';export class APIKeyManager{['apiKey']=null;[_0x465f(0x1b0)]=[];[_0x465f(0x1b4)]=null;[_0x465f(0x1ad)]=null;['loadFromEnv'](){this['apiKey']=process[_0x465f(0x1b9)][_0x465f(0x1aa)]||null;const _0x1cf27a=process['env'][_0x465f(0x1b8)];this[_0x465f(0x1b0)]=_0x1cf27a?_0x1cf27a[_0x465f(0x1af)](',')[_0x465f(0x1a6)](_0x27e528=>_0x27e528[_0x465f(0x195)]()):[],this[_0x465f(0x1b4)]=process[_0x465f(0x1b9)][_0x465f(0x1b6)]||null,this['campId']=process[_0x465f(0x1b9)][_0x465f(0x19d)]||null,!this[_0x465f(0x1ab)]?logger[_0x465f(0x194)](_0x465f(0x1a9)):logger[_0x465f(0x1ae)](_0x465f(0x19f),{'hasScopes':this[_0x465f(0x1b0)][_0x465f(0x1ba)]>0x0}),!this[_0x465f(0x1b4)]||!this['campId']?logger[_0x465f(0x194)](_0x465f(0x1b5)):logger[_0x465f(0x1ae)]('Hudson\x20credentials\x20loaded\x20from\x20environment');}[_0x465f(0x1a7)](_0x4ec83f){this['apiKey']=_0x4ec83f['apiKey']||null,this[_0x465f(0x1b0)]=_0x4ec83f[_0x465f(0x1b0)]||[],this[_0x465f(0x1b4)]=_0x4ec83f[_0x465f(0x1b4)]||null,this['campId']=_0x4ec83f[_0x465f(0x1ad)]||null,this[_0x465f(0x1ab)]&&logger[_0x465f(0x1ae)](_0x465f(0x1b7),{'hasScopes':this[_0x465f(0x1b0)]['length']>0x0}),this[_0x465f(0x1b4)]&&this[_0x465f(0x1ad)]&&logger[_0x465f(0x1ae)](_0x465f(0x197));}['setAPIKey'](_0x9b3554,_0x39d9d7){this['apiKey']=_0x9b3554,this[_0x465f(0x1b0)]=_0x39d9d7||[],logger[_0x465f(0x1ae)](_0x465f(0x19c),{'hasScopes':this['scopes'][_0x465f(0x1ba)]>0x0});}[_0x465f(0x1a8)](_0xbbdaeb,_0x662df5){this['hudsonAccessToken']=_0xbbdaeb,this['campId']=_0x662df5,logger[_0x465f(0x1ae)](_0x465f(0x1a5));}['getAPIKey'](){return this[_0x465f(0x1ab)]||'';}[_0x465f(0x1a0)](){return this[_0x465f(0x1ab)]!==null&&this[_0x465f(0x1ab)]!=='';}['hasScope'](_0x3c0a8f){if(this['scopes']['includes']('*'))return!![];return this['scopes']['includes'](_0x3c0a8f);}['getScopes'](){return[...this['scopes']];}[_0x465f(0x199)](){return this['apiKey']!==null;}[_0x465f(0x1b1)](){return this[_0x465f(0x1b4)]!==null&&this['campId']!==null;}[_0x465f(0x19b)](){if(!this['hudsonAccessToken'])throw new Error('APP_SECRET\x20not\x20configured.\x20Please\x20set\x20APP_SECRET\x20environment\x20variable.');return this[_0x465f(0x1b4)];}[_0x465f(0x198)](){if(!this[_0x465f(0x1ad)])throw new Error('APP_ID\x20not\x20configured.\x20Please\x20set\x20APP_ID\x20environment\x20variable.');return this[_0x465f(0x1ad)];}}function _0x44a0(){const _0x2a9afa=['length','warn','trim','83800daATYk','Hudson\x20credentials\x20loaded\x20from\x20config','getCampId','isConfigured','524698kTOlXT','getHudsonAccessToken','API\x20key\x20set','APP_ID','4638045shIoRO','API\x20key\x20loaded\x20from\x20environment','hasAPIKey','5568522oZMvzv','2UnJZJo','22986OShRVn','308MqWjpq','Hudson\x20credentials\x20set','map','loadFromConfig','setHudsonCredentials','API\x20key\x20not\x20found\x20in\x20environment\x20variables','LUKEYUN_API_KEY','apiKey','18566160wljxJG','campId','info','split','scopes','isHudsonConfigured','266JdTfcx','8815536VuFWjf','hudsonAccessToken','APP_SECRET\x20or\x20APP_ID\x20not\x20found\x20in\x20environment\x20variables','APP_SECRET','API\x20key\x20loaded\x20from\x20config','LUKEYUN_API_SCOPES','env'];_0x44a0=function(){return _0x2a9afa;};return _0x44a0();}
@@ -1,3 +1 @@
1
- export { APIKeyManager } from './apiKeyManager.js';
2
- export { PermissionChecker } from './permissionChecker.js';
3
- //# sourceMappingURL=index.js.map
1
+ (function(_0x2a9b4e,_0x4365b6){var _0xdb8b86=_0x2a9b4e();while(!![]){try{var _0x4b0bbd=parseInt(_0x4ac7(0x77))/0x1+-parseInt(_0x4ac7(0x7d))/0x2*(parseInt(_0x4ac7(0x7b))/0x3)+-parseInt(_0x4ac7(0x75))/0x4+parseInt(_0x4ac7(0x7a))/0x5+parseInt(_0x4ac7(0x78))/0x6*(parseInt(_0x4ac7(0x7c))/0x7)+parseInt(_0x4ac7(0x79))/0x8*(parseInt(_0x4ac7(0x76))/0x9)+parseInt(_0x4ac7(0x74))/0xa;if(_0x4b0bbd===_0x4365b6)break;else _0xdb8b86['push'](_0xdb8b86['shift']());}catch(_0x514b4b){_0xdb8b86['push'](_0xdb8b86['shift']());}}}(_0x1265,0x98ff8));function _0x4ac7(_0x48d739,_0x309f74){var _0x1265e8=_0x1265();return _0x4ac7=function(_0x4ac792,_0x2efbd0){_0x4ac792=_0x4ac792-0x74;var _0x48be64=_0x1265e8[_0x4ac792];return _0x48be64;},_0x4ac7(_0x48d739,_0x309f74);}export{APIKeyManager}from'./apiKeyManager.js';export{PermissionChecker}from'./permissionChecker.js';function _0x1265(){var _0xaf0b66=['735808hMoRfS','6GCrlVk','1329440pOsIIK','326230IIblkT','3484131YZormu','1460977yvfOkr','2CAqkEL','18285000ilPLNK','4865552QxIZzP','9bXriSC'];_0x1265=function(){return _0xaf0b66;};return _0x1265();}
@@ -1,67 +1 @@
1
- import { MCPError, ErrorCode, getPermissionDeniedMessage, } from '../utils/errorHandler.js';
2
- import { logger } from '../utils/logger.js';
3
- function toolToPermissionDomain(toolName) {
4
- switch (toolName) {
5
- case 'query_today_orders':
6
- case 'get_order_details_v2':
7
- case 'query_orders':
8
- case 'get_order_details':
9
- return 'orders';
10
- case 'query_operational_data_v2':
11
- return 'finance';
12
- case 'query_today_room_status':
13
- case 'query_room_status_new':
14
- return 'room_status';
15
- case 'query_room_prices':
16
- return 'room_price';
17
- default:
18
- return 'generic';
19
- }
20
- }
21
- export class PermissionChecker {
22
- keyManager;
23
- constructor(keyManager) {
24
- this.keyManager = keyManager;
25
- }
26
- /**
27
- * 检查工具调用权限
28
- */
29
- checkPermission(toolName, requiredScopes) {
30
- if (requiredScopes.length === 0) {
31
- // 如果没有权限要求,则允许
32
- return;
33
- }
34
- // 如果只有Hudson认证(没有API key和权限范围),则允许所有操作
35
- // 因为Hudson认证本身就包含了权限验证
36
- if (!this.keyManager.hasAPIKey() && this.keyManager.isHudsonConfigured()) {
37
- logger.debug('Permission check passed (Hudson auth only)', {
38
- tool: toolName,
39
- requiredScopes,
40
- });
41
- return;
42
- }
43
- const hasPermission = requiredScopes.some((scope) => this.keyManager.hasScope(scope));
44
- if (!hasPermission) {
45
- const scopes = this.keyManager.getScopes();
46
- const domain = toolToPermissionDomain(toolName);
47
- logger.warn('Permission denied', {
48
- tool: toolName,
49
- required: requiredScopes,
50
- current: scopes,
51
- domain,
52
- });
53
- throw new MCPError(ErrorCode.PERMISSION_DENIED, getPermissionDeniedMessage(domain), {
54
- tool: toolName,
55
- requiredScopes,
56
- currentScopes: scopes,
57
- domain,
58
- source: '路客云AI',
59
- });
60
- }
61
- logger.debug('Permission check passed', {
62
- tool: toolName,
63
- scopes: requiredScopes,
64
- });
65
- }
66
- }
67
- //# sourceMappingURL=permissionChecker.js.map
1
+ (function(_0x52bdd7,_0xa37b71){const _0x4fbadc=_0x52bdd7();while(!![]){try{const _0x23af49=parseInt(_0x42a6(0x197))/0x1+parseInt(_0x42a6(0x19d))/0x2*(-parseInt(_0x42a6(0x1ac))/0x3)+parseInt(_0x42a6(0x191))/0x4*(parseInt(_0x42a6(0x1b2))/0x5)+-parseInt(_0x42a6(0x1a4))/0x6+parseInt(_0x42a6(0x192))/0x7+-parseInt(_0x42a6(0x198))/0x8*(parseInt(_0x42a6(0x1a9))/0x9)+parseInt(_0x42a6(0x1a5))/0xa*(parseInt(_0x42a6(0x1a7))/0xb);if(_0x23af49===_0xa37b71)break;else _0x4fbadc['push'](_0x4fbadc['shift']());}catch(_0x3dbe29){_0x4fbadc['push'](_0x4fbadc['shift']());}}}(_0x3604,0x84fb3));function _0x42a6(_0x38e8d9,_0x51f166){const _0x360423=_0x3604();return _0x42a6=function(_0x42a65c,_0x293407){_0x42a65c=_0x42a65c-0x190;let _0x12f9ff=_0x360423[_0x42a65c];return _0x12f9ff;},_0x42a6(_0x38e8d9,_0x51f166);}import{MCPError,ErrorCode,getPermissionDeniedMessage}from'../utils/errorHandler.js';import{logger}from'../utils/logger.js';function toolToPermissionDomain(_0x4b3946){switch(_0x4b3946){case'query_today_orders':case _0x42a6(0x1b1):case _0x42a6(0x195):case _0x42a6(0x1ad):case'query_orders_by_date_range':case _0x42a6(0x1a6):case _0x42a6(0x193):case _0x42a6(0x196):return'orders';case'query_operational_data_v2':return _0x42a6(0x1a1);case _0x42a6(0x190):case _0x42a6(0x19c):return'room_status';case _0x42a6(0x199):return _0x42a6(0x1a2);default:return _0x42a6(0x19e);}}export class PermissionChecker{[_0x42a6(0x1aa)];constructor(_0x2ccb52){this['keyManager']=_0x2ccb52;}[_0x42a6(0x1a0)](_0x502dda,_0x416f08){if(_0x416f08[_0x42a6(0x194)]===0x0)return;if(!this[_0x42a6(0x1aa)]['hasAPIKey']()&&this[_0x42a6(0x1aa)]['isHudsonConfigured']()){logger[_0x42a6(0x1a3)](_0x42a6(0x1b0),{'tool':_0x502dda,'requiredScopes':_0x416f08});return;}const _0x4a3490=_0x416f08[_0x42a6(0x1ab)](_0x5f0d63=>this[_0x42a6(0x1aa)][_0x42a6(0x19a)](_0x5f0d63));if(!_0x4a3490){const _0x544c56=this[_0x42a6(0x1aa)][_0x42a6(0x1a8)](),_0x260492=toolToPermissionDomain(_0x502dda);logger['warn'](_0x42a6(0x19b),{'tool':_0x502dda,'required':_0x416f08,'current':_0x544c56,'domain':_0x260492});throw new MCPError(ErrorCode[_0x42a6(0x1af)],getPermissionDeniedMessage(_0x260492),{'tool':_0x502dda,'requiredScopes':_0x416f08,'currentScopes':_0x544c56,'domain':_0x260492,'source':_0x42a6(0x19f)});}logger[_0x42a6(0x1a3)](_0x42a6(0x1ae),{'tool':_0x502dda,'scopes':_0x416f08});}}function _0x3604(){const _0x51f774=['generic','路客云AI','checkPermission','finance','room_price','debug','3079548crRBHl','25220iWWpCj','get_order_details_v2','5797oxXFDb','getScopes','582291TXtxbA','keyManager','some','171uoCFqi','query_pre_departure_orders','Permission\x20check\x20passed','PERMISSION_DENIED','Permission\x20check\x20passed\x20(Hudson\x20auth\x20only)','query_pre_arrival_orders','5EcrrxE','query_today_room_status','2393000wxtIIv','1942591XZDAmU','query_orders','length','query_in_house_orders','get_order_details','362162zMujjG','104SacJgL','query_room_prices','hasScope','Permission\x20denied','query_room_status_new','23438qoNAIe'];_0x3604=function(){return _0x51f774;};return _0x3604();}
@@ -1,64 +1 @@
1
- import { config } from '../config/index.js';
2
- import { logger } from '../utils/logger.js';
3
- export class CacheManager {
4
- cache = new Map();
5
- /**
6
- * 获取缓存数据
7
- */
8
- get(key) {
9
- if (!config.cache.enabled) {
10
- return null;
11
- }
12
- const entry = this.cache.get(key);
13
- if (!entry) {
14
- return null;
15
- }
16
- // 检查是否过期
17
- if (Date.now() > entry.expiresAt) {
18
- this.cache.delete(key);
19
- logger.debug('Cache expired', { key });
20
- return null;
21
- }
22
- logger.debug('Cache hit', { key });
23
- return entry.data;
24
- }
25
- /**
26
- * 设置缓存数据
27
- */
28
- set(key, data, ttl) {
29
- if (!config.cache.enabled) {
30
- return;
31
- }
32
- const ttlMs = ttl || config.cache.ttl;
33
- this.cache.set(key, {
34
- data,
35
- expiresAt: Date.now() + ttlMs,
36
- });
37
- logger.debug('Cache set', { key, ttl: ttlMs });
38
- }
39
- /**
40
- * 删除缓存
41
- */
42
- delete(key) {
43
- this.cache.delete(key);
44
- logger.debug('Cache deleted', { key });
45
- }
46
- /**
47
- * 清空所有缓存
48
- */
49
- clear() {
50
- this.cache.clear();
51
- logger.debug('Cache cleared');
52
- }
53
- /**
54
- * 生成缓存键
55
- */
56
- static generateKey(prefix, params) {
57
- const sortedParams = Object.keys(params)
58
- .sort()
59
- .map((key) => `${key}=${JSON.stringify(params[key])}`)
60
- .join('&');
61
- return `${prefix}:${sortedParams}`;
62
- }
63
- }
64
- //# sourceMappingURL=cacheManager.js.map
1
+ function _0x1d2e(_0x46aaff,_0x5f3d40){const _0x12f92c=_0x12f9();return _0x1d2e=function(_0x1d2ef0,_0x1bf8fa){_0x1d2ef0=_0x1d2ef0-0xa8;let _0x1f4c15=_0x12f92c[_0x1d2ef0];return _0x1f4c15;},_0x1d2e(_0x46aaff,_0x5f3d40);}function _0x12f9(){const _0x145aa3=['delete','enabled','Cache\x20deleted','2152032aSjHbX','Cache\x20expired','8595064oYknUc','3506dmFhoU','3qPtiVy','get','175aClICN','expiresAt','keys','now','cache','set','3967292IOunaR','378MREpXY','map','data','Cache\x20hit','Cache\x20set','stringify','debug','205660egasSq','clear','31162734WnGVCv','join'];_0x12f9=function(){return _0x145aa3;};return _0x12f9();}(function(_0x51c7ac,_0x506baa){const _0x38c3e5=_0x51c7ac();while(!![]){try{const _0x3930ec=-parseInt(_0x1d2e(0xb6))/0x1*(-parseInt(_0x1d2e(0xb5))/0x2)+-parseInt(_0x1d2e(0xb2))/0x3+-parseInt(_0x1d2e(0xbe))/0x4+-parseInt(_0x1d2e(0xab))/0x5+-parseInt(_0x1d2e(0xbf))/0x6*(-parseInt(_0x1d2e(0xb8))/0x7)+-parseInt(_0x1d2e(0xb4))/0x8+parseInt(_0x1d2e(0xad))/0x9;if(_0x3930ec===_0x506baa)break;else _0x38c3e5['push'](_0x38c3e5['shift']());}catch(_0x461e12){_0x38c3e5['push'](_0x38c3e5['shift']());}}}(_0x12f9,0x9d646));import{config}from'../config/index.js';import{logger}from'../utils/logger.js';export class CacheManager{[_0x1d2e(0xbc)]=new Map();[_0x1d2e(0xb7)](_0x4a6c7e){if(!config[_0x1d2e(0xbc)]['enabled'])return null;const _0x40e180=this[_0x1d2e(0xbc)]['get'](_0x4a6c7e);if(!_0x40e180)return null;if(Date[_0x1d2e(0xbb)]()>_0x40e180[_0x1d2e(0xb9)])return this[_0x1d2e(0xbc)]['delete'](_0x4a6c7e),logger[_0x1d2e(0xaa)](_0x1d2e(0xb3),{'key':_0x4a6c7e}),null;return logger[_0x1d2e(0xaa)](_0x1d2e(0xc2),{'key':_0x4a6c7e}),_0x40e180[_0x1d2e(0xc1)];}[_0x1d2e(0xbd)](_0x1675a5,_0x344d20,_0x43f09d){if(!config[_0x1d2e(0xbc)][_0x1d2e(0xb0)])return;const _0x37dc91=_0x43f09d||config[_0x1d2e(0xbc)]['ttl'];this['cache'][_0x1d2e(0xbd)](_0x1675a5,{'data':_0x344d20,'expiresAt':Date[_0x1d2e(0xbb)]()+_0x37dc91}),logger[_0x1d2e(0xaa)](_0x1d2e(0xa8),{'key':_0x1675a5,'ttl':_0x37dc91});}[_0x1d2e(0xaf)](_0x845e28){this[_0x1d2e(0xbc)][_0x1d2e(0xaf)](_0x845e28),logger[_0x1d2e(0xaa)](_0x1d2e(0xb1),{'key':_0x845e28});}[_0x1d2e(0xac)](){this['cache'][_0x1d2e(0xac)](),logger['debug']('Cache\x20cleared');}static['generateKey'](_0x5cdc33,_0x3b6654){const _0x34ac89=Object[_0x1d2e(0xba)](_0x3b6654)['sort']()[_0x1d2e(0xc0)](_0x242f8e=>_0x242f8e+'='+JSON[_0x1d2e(0xa9)](_0x3b6654[_0x242f8e]))[_0x1d2e(0xae)]('&');return _0x5cdc33+':'+_0x34ac89;}}
@@ -1,125 +1 @@
1
- import axios from 'axios';
2
- import { config } from '../config/index.js';
3
- import { logger } from '../utils/logger.js';
4
- import { MCPError, ErrorCode } from '../utils/errorHandler.js';
5
- import { RetryHandler } from './retryHandler.js';
6
- export class HTTPClient {
7
- client;
8
- apiKey;
9
- hudsonAccessToken;
10
- retryHandler;
11
- constructor(apiKey, hudsonAccessToken) {
12
- this.apiKey = apiKey;
13
- this.hudsonAccessToken = hudsonAccessToken;
14
- this.retryHandler = new RetryHandler(config.retry.maxRetries, config.retry.delay);
15
- this.client = axios.create({
16
- baseURL: config.api.baseURL,
17
- timeout: config.api.timeout,
18
- headers: {
19
- 'Content-Type': 'application/json',
20
- 'X-Client-Type': 'mcp',
21
- 'X-Client-Version': process.env.npm_package_version || '1.0.0',
22
- },
23
- });
24
- this.setupInterceptors();
25
- }
26
- setupInterceptors() {
27
- // 请求拦截器:自动注入API密钥和Hudson token
28
- this.client.interceptors.request.use((config) => {
29
- // 只有在提供了API key时才添加Authorization header
30
- if (this.apiKey) {
31
- config.headers.Authorization = `Bearer ${this.apiKey}`;
32
- }
33
- // 如果提供了Hudson token,添加到header
34
- if (this.hudsonAccessToken) {
35
- config.headers['hudson-access-token'] = this.hudsonAccessToken;
36
- }
37
- logger.debug('API request', {
38
- method: config.method,
39
- url: config.url,
40
- params: config.params,
41
- });
42
- return config;
43
- }, (error) => {
44
- logger.error('Request interceptor error', error);
45
- return Promise.reject(error);
46
- });
47
- // 响应拦截器:错误处理
48
- this.client.interceptors.response.use((response) => {
49
- logger.debug('API response', {
50
- status: response.status,
51
- url: response.config.url,
52
- });
53
- return response;
54
- }, async (error) => {
55
- return this.handleError(error);
56
- });
57
- }
58
- async handleError(error) {
59
- if (error.response) {
60
- // API返回了错误响应
61
- const status = error.response.status;
62
- const data = error.response.data;
63
- logger.error('API error response', {
64
- status,
65
- url: error.config?.url,
66
- message: data.message,
67
- });
68
- switch (status) {
69
- case 401:
70
- throw new MCPError(ErrorCode.AUTH_INVALID, 'API密钥无效或已过期', data);
71
- case 403:
72
- throw new MCPError(ErrorCode.PERMISSION_DENIED, data?.message || '权限不足', {
73
- ...(data != null && typeof data === 'object' ? data : {}),
74
- domain: 'generic',
75
- source: '路客云AI',
76
- });
77
- case 404:
78
- throw new MCPError(ErrorCode.API_NOT_FOUND, '资源不存在', data);
79
- case 429:
80
- throw new MCPError(ErrorCode.API_RATE_LIMIT, '请求频率过高,请稍后重试', data);
81
- case 500:
82
- case 502:
83
- case 503:
84
- case 504:
85
- throw new MCPError(ErrorCode.API_ERROR, '服务器错误,请稍后重试', data);
86
- default:
87
- throw new MCPError(ErrorCode.API_ERROR, data.message || `API错误:${status}`, data);
88
- }
89
- }
90
- else if (error.request) {
91
- // 请求已发出但没有收到响应
92
- logger.error('API request timeout', {
93
- url: error.config?.url,
94
- timeout: config.api.timeout,
95
- });
96
- if (error.code === 'ECONNABORTED') {
97
- throw new MCPError(ErrorCode.API_TIMEOUT, '请求超时,请稍后重试');
98
- }
99
- throw new MCPError(ErrorCode.API_ERROR, '网络错误,请检查网络连接');
100
- }
101
- else {
102
- // 请求配置错误
103
- logger.error('Request configuration error', error);
104
- throw new MCPError(ErrorCode.INTERNAL_ERROR, '请求配置错误');
105
- }
106
- }
107
- async request(requestConfig) {
108
- const axiosConfig = {
109
- method: requestConfig.method,
110
- url: requestConfig.url,
111
- params: requestConfig.params,
112
- data: requestConfig.data,
113
- headers: requestConfig.headers,
114
- };
115
- try {
116
- const response = await this.retryHandler.execute(() => this.client.request(axiosConfig));
117
- return response.data;
118
- }
119
- catch (error) {
120
- // 错误已在拦截器中处理,直接抛出
121
- throw error;
122
- }
123
- }
124
- }
125
- //# sourceMappingURL=httpClient.js.map
1
+ function _0x513a(_0x4d9582,_0x2e4fcb){const _0x4b56b0=_0x4b56();return _0x513a=function(_0x513a00,_0x35bbb1){_0x513a00=_0x513a00-0x13f;let _0x25f3ff=_0x4b56b0[_0x513a00];return _0x25f3ff;},_0x513a(_0x4d9582,_0x2e4fcb);}(function(_0x12262e,_0x48e623){const _0x6876f4=_0x12262e();while(!![]){try{const _0x7ec5ba=-parseInt(_0x513a(0x141))/0x1*(parseInt(_0x513a(0x13f))/0x2)+-parseInt(_0x513a(0x148))/0x3*(parseInt(_0x513a(0x14d))/0x4)+parseInt(_0x513a(0x14e))/0x5+parseInt(_0x513a(0x161))/0x6*(-parseInt(_0x513a(0x175))/0x7)+parseInt(_0x513a(0x177))/0x8*(-parseInt(_0x513a(0x163))/0x9)+parseInt(_0x513a(0x16f))/0xa+-parseInt(_0x513a(0x171))/0xb*(-parseInt(_0x513a(0x159))/0xc);if(_0x7ec5ba===_0x48e623)break;else _0x6876f4['push'](_0x6876f4['shift']());}catch(_0x326da4){_0x6876f4['push'](_0x6876f4['shift']());}}}(_0x4b56,0x678fd));import _0x5e57eb from'axios';import{config}from'../config/index.js';import{logger}from'../utils/logger.js';import{MCPError,ErrorCode}from'../utils/errorHandler.js';import{RetryHandler}from'./retryHandler.js';function _0x4b56(){const _0x37046c=['message','status','权限不足','error','6qNttkP','API错误:','10161UqdcZY','AUTH_INVALID','setupInterceptors','use','retryHandler','PERMISSION_DENIED','请求超时,请稍后重试','API_ERROR','handleError','response','Bearer\x20','retry','3222630ksFqIc','ECONNABORTED','2020777fJqoPy','API\x20error\x20response','headers','baseURL','33243rLEsZy','url','1416psdXLD','hudsonAccessToken','4058mvwaqN','服务器错误,请稍后重试','251ZeWQPA','路客云AI','interceptors','apiKey','Request\x20interceptor\x20error','api','params','3pQZZfv','timeout','code','请求配置错误','method','1354252lLIubp','2097610FYSrwQ','1.0.0','data','object','reject','API\x20response','API\x20request','API_NOT_FOUND','delay','config','client','48SOWkKC','API密钥无效或已过期','request','generic'];_0x4b56=function(){return _0x37046c;};return _0x4b56();}export class HTTPClient{[_0x513a(0x158)];['apiKey'];['hudsonAccessToken'];[_0x513a(0x167)];constructor(_0x17a11c,_0x4f1104){this[_0x513a(0x144)]=_0x17a11c,this[_0x513a(0x178)]=_0x4f1104,this[_0x513a(0x167)]=new RetryHandler(config['retry']['maxRetries'],config[_0x513a(0x16e)][_0x513a(0x156)]),this['client']=_0x5e57eb['create']({'baseURL':config[_0x513a(0x146)][_0x513a(0x174)],'timeout':config[_0x513a(0x146)][_0x513a(0x149)],'headers':{'Content-Type':'application/json','X-Client-Type':'mcp','X-Client-Version':process['env']['npm_package_version']||_0x513a(0x14f)}}),this[_0x513a(0x165)]();}[_0x513a(0x165)](){this[_0x513a(0x158)][_0x513a(0x143)][_0x513a(0x15b)]['use'](_0x3f5ad7=>{return this[_0x513a(0x144)]&&(_0x3f5ad7[_0x513a(0x173)]['Authorization']=_0x513a(0x16d)+this['apiKey']),this[_0x513a(0x178)]&&(_0x3f5ad7['headers']['hudson-access-token']=this[_0x513a(0x178)]),logger['debug'](_0x513a(0x154),{'method':_0x3f5ad7[_0x513a(0x14c)],'url':_0x3f5ad7[_0x513a(0x176)],'params':_0x3f5ad7[_0x513a(0x147)]}),_0x3f5ad7;},_0x234ffe=>{return logger[_0x513a(0x160)](_0x513a(0x145),_0x234ffe),Promise[_0x513a(0x152)](_0x234ffe);}),this[_0x513a(0x158)][_0x513a(0x143)][_0x513a(0x16c)][_0x513a(0x166)](_0x1b04a1=>{return logger['debug'](_0x513a(0x153),{'status':_0x1b04a1[_0x513a(0x15e)],'url':_0x1b04a1[_0x513a(0x157)][_0x513a(0x176)]}),_0x1b04a1;},async _0x32c524=>{return this['handleError'](_0x32c524);});}async[_0x513a(0x16b)](_0x15cb53){if(_0x15cb53[_0x513a(0x16c)]){const _0xdb6beb=_0x15cb53[_0x513a(0x16c)]['status'],_0xeb742d=_0x15cb53['response'][_0x513a(0x150)];logger['error'](_0x513a(0x172),{'status':_0xdb6beb,'url':_0x15cb53[_0x513a(0x157)]?.['url'],'message':_0xeb742d[_0x513a(0x15d)]});switch(_0xdb6beb){case 0x191:throw new MCPError(ErrorCode[_0x513a(0x164)],_0x513a(0x15a),_0xeb742d);case 0x193:throw new MCPError(ErrorCode[_0x513a(0x168)],_0xeb742d?.['message']||_0x513a(0x15f),{..._0xeb742d!=null&&typeof _0xeb742d===_0x513a(0x151)?_0xeb742d:{},'domain':_0x513a(0x15c),'source':_0x513a(0x142)});case 0x194:throw new MCPError(ErrorCode[_0x513a(0x155)],'资源不存在',_0xeb742d);case 0x1ad:throw new MCPError(ErrorCode['API_RATE_LIMIT'],'请求频率过高,请稍后重试',_0xeb742d);case 0x1f4:case 0x1f6:case 0x1f7:case 0x1f8:throw new MCPError(ErrorCode['API_ERROR'],_0x513a(0x140),_0xeb742d);default:throw new MCPError(ErrorCode[_0x513a(0x16a)],_0xeb742d[_0x513a(0x15d)]||_0x513a(0x162)+_0xdb6beb,_0xeb742d);}}else{if(_0x15cb53[_0x513a(0x15b)]){logger[_0x513a(0x160)]('API\x20request\x20timeout',{'url':_0x15cb53[_0x513a(0x157)]?.[_0x513a(0x176)],'timeout':config[_0x513a(0x146)][_0x513a(0x149)]});if(_0x15cb53[_0x513a(0x14a)]===_0x513a(0x170))throw new MCPError(ErrorCode['API_TIMEOUT'],_0x513a(0x169));throw new MCPError(ErrorCode[_0x513a(0x16a)],'网络错误,请检查网络连接');}else{logger[_0x513a(0x160)]('Request\x20configuration\x20error',_0x15cb53);throw new MCPError(ErrorCode['INTERNAL_ERROR'],_0x513a(0x14b));}}}async['request'](_0x2323d5){const _0x593a80={'method':_0x2323d5[_0x513a(0x14c)],'url':_0x2323d5[_0x513a(0x176)],'params':_0x2323d5[_0x513a(0x147)],'data':_0x2323d5['data'],'headers':_0x2323d5[_0x513a(0x173)]};try{const _0x604dda=await this[_0x513a(0x167)]['execute'](()=>this['client']['request'](_0x593a80));return _0x604dda['data'];}catch(_0x44b7cb){throw _0x44b7cb;}}}
@@ -1,4 +1 @@
1
- export { HTTPClient } from './httpClient.js';
2
- export { RetryHandler } from './retryHandler.js';
3
- export { CacheManager } from './cacheManager.js';
4
- //# sourceMappingURL=index.js.map
1
+ (function(_0x230379,_0x5d88b8){var _0x1e2cb8=_0x230379();while(!![]){try{var _0x1bae30=-parseInt(_0x2ce9(0xba))/0x1+parseInt(_0x2ce9(0xb9))/0x2+-parseInt(_0x2ce9(0xb7))/0x3*(-parseInt(_0x2ce9(0xb5))/0x4)+-parseInt(_0x2ce9(0xb8))/0x5*(-parseInt(_0x2ce9(0xb4))/0x6)+-parseInt(_0x2ce9(0xb6))/0x7*(-parseInt(_0x2ce9(0xbb))/0x8)+parseInt(_0x2ce9(0xb3))/0x9*(parseInt(_0x2ce9(0xbd))/0xa)+-parseInt(_0x2ce9(0xbc))/0xb*(parseInt(_0x2ce9(0xb2))/0xc);if(_0x1bae30===_0x5d88b8)break;else _0x1e2cb8['push'](_0x1e2cb8['shift']());}catch(_0x1031cd){_0x1e2cb8['push'](_0x1e2cb8['shift']());}}}(_0x5d2c,0x235f3));function _0x5d2c(){var _0xbcb4f3=['310290vuKcGB','171539MkMgFt','29224iijLGU','574409rRPjVR','10GzZGTD','96XWskyA','477711fhbIFD','6WzdvTZ','786036nExFpM','518YKxAIk','3nwPHpl','295595KqebpG'];_0x5d2c=function(){return _0xbcb4f3;};return _0x5d2c();}export{HTTPClient}from'./httpClient.js';export{RetryHandler}from'./retryHandler.js';function _0x2ce9(_0x57a042,_0x47abab){var _0x5d2c09=_0x5d2c();return _0x2ce9=function(_0x2ce911,_0x11d756){_0x2ce911=_0x2ce911-0xb2;var _0x54cc8d=_0x5d2c09[_0x2ce911];return _0x54cc8d;},_0x2ce9(_0x57a042,_0x47abab);}export{CacheManager}from'./cacheManager.js';
@@ -1,68 +1 @@
1
- import { logger } from '../utils/logger.js';
2
- import { AxiosError } from 'axios';
3
- export class RetryHandler {
4
- maxRetries;
5
- baseDelay;
6
- constructor(maxRetries = 3, baseDelay = 1000) {
7
- this.maxRetries = maxRetries;
8
- this.baseDelay = baseDelay;
9
- }
10
- /**
11
- * 执行带重试的请求
12
- */
13
- async execute(fn) {
14
- let lastError;
15
- for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
16
- try {
17
- return await fn();
18
- }
19
- catch (error) {
20
- lastError = error;
21
- // 如果是最后一次尝试,直接抛出错误
22
- if (attempt === this.maxRetries) {
23
- break;
24
- }
25
- // 检查是否可重试
26
- if (!this.isRetryableError(error)) {
27
- throw error;
28
- }
29
- // 计算延迟时间(指数退避)
30
- const delay = this.baseDelay * Math.pow(2, attempt);
31
- logger.warn(`Request failed, retrying... (attempt ${attempt + 1}/${this.maxRetries})`, {
32
- error: error instanceof Error ? error.message : String(error),
33
- delay,
34
- });
35
- await this.sleep(delay);
36
- }
37
- }
38
- // 所有重试都失败,抛出最后一个错误
39
- throw lastError;
40
- }
41
- /**
42
- * 判断错误是否可重试
43
- */
44
- isRetryableError(error) {
45
- if (error instanceof AxiosError) {
46
- // 网络错误、超时错误可重试
47
- if (error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT' || error.code === 'ECONNABORTED') {
48
- return true;
49
- }
50
- // 5xx服务器错误可重试
51
- if (error.response && error.response.status >= 500) {
52
- return true;
53
- }
54
- // 429速率限制可重试
55
- if (error.response && error.response.status === 429) {
56
- return true;
57
- }
58
- }
59
- return false;
60
- }
61
- /**
62
- * 延迟函数
63
- */
64
- sleep(ms) {
65
- return new Promise((resolve) => setTimeout(resolve, ms));
66
- }
67
- }
68
- //# sourceMappingURL=retryHandler.js.map
1
+ (function(_0x3ad6fe,_0x5501f8){const _0x190a61=_0x3ad6fe();while(!![]){try{const _0x4b96d8=-parseInt(_0x40c6(0x1fb))/0x1*(parseInt(_0x40c6(0x1f0))/0x2)+-parseInt(_0x40c6(0x1f2))/0x3*(parseInt(_0x40c6(0x1ef))/0x4)+parseInt(_0x40c6(0x1f9))/0x5+parseInt(_0x40c6(0x1ff))/0x6+parseInt(_0x40c6(0x1fd))/0x7+parseInt(_0x40c6(0x1f8))/0x8+parseInt(_0x40c6(0x1ec))/0x9*(-parseInt(_0x40c6(0x1ed))/0xa);if(_0x4b96d8===_0x5501f8)break;else _0x190a61['push'](_0x190a61['shift']());}catch(_0x398f84){_0x190a61['push'](_0x190a61['shift']());}}}(_0x46c5,0x38db2));function _0x40c6(_0x36321c,_0x29cb47){const _0x46c52c=_0x46c5();return _0x40c6=function(_0x40c6ff,_0x1e3acf){_0x40c6ff=_0x40c6ff-0x1ea;let _0x5000ca=_0x46c52c[_0x40c6ff];return _0x5000ca;},_0x40c6(_0x36321c,_0x29cb47);}import{logger}from'../utils/logger.js';function _0x46c5(){const _0x2a7bb0=['1rfsWiD','response','2278276AoOuUN','Request\x20failed,\x20retrying...\x20(attempt\x20','2764680sqkngC','message','status','maxRetries','9SQHTBa','9758470NHRptA','sleep','1604wdrHtd','185354piemiI','ECONNRESET','3OWxPgs','pow','code','ECONNABORTED','isRetryableError','execute','2970192ZAVGPV','721425fzXDaR','baseDelay'];_0x46c5=function(){return _0x2a7bb0;};return _0x46c5();}import{AxiosError}from'axios';export class RetryHandler{[_0x40c6(0x1eb)];[_0x40c6(0x1fa)];constructor(_0x2790d0=0x3,_0x962359=0x3e8){this[_0x40c6(0x1eb)]=_0x2790d0,this[_0x40c6(0x1fa)]=_0x962359;}async[_0x40c6(0x1f7)](_0x478842){let _0x43aefb;for(let _0x2d96ef=0x0;_0x2d96ef<=this[_0x40c6(0x1eb)];_0x2d96ef++){try{return await _0x478842();}catch(_0x22f26e){_0x43aefb=_0x22f26e;if(_0x2d96ef===this[_0x40c6(0x1eb)])break;if(!this[_0x40c6(0x1f6)](_0x22f26e))throw _0x22f26e;const _0x23219c=this[_0x40c6(0x1fa)]*Math[_0x40c6(0x1f3)](0x2,_0x2d96ef);logger['warn'](_0x40c6(0x1fe)+(_0x2d96ef+0x1)+'/'+this[_0x40c6(0x1eb)]+')',{'error':_0x22f26e instanceof Error?_0x22f26e[_0x40c6(0x200)]:String(_0x22f26e),'delay':_0x23219c}),await this[_0x40c6(0x1ee)](_0x23219c);}}throw _0x43aefb;}[_0x40c6(0x1f6)](_0x2ec6db){if(_0x2ec6db instanceof AxiosError){if(_0x2ec6db[_0x40c6(0x1f4)]===_0x40c6(0x1f1)||_0x2ec6db[_0x40c6(0x1f4)]==='ETIMEDOUT'||_0x2ec6db[_0x40c6(0x1f4)]===_0x40c6(0x1f5))return!![];if(_0x2ec6db[_0x40c6(0x1fc)]&&_0x2ec6db[_0x40c6(0x1fc)]['status']>=0x1f4)return!![];if(_0x2ec6db['response']&&_0x2ec6db[_0x40c6(0x1fc)][_0x40c6(0x1ea)]===0x1ad)return!![];}return![];}[_0x40c6(0x1ee)](_0x588e0c){return new Promise(_0x51ee59=>setTimeout(_0x51ee59,_0x588e0c));}}
@@ -1,39 +1 @@
1
- import dotenv from 'dotenv';
2
- // 加载环境变量
3
- dotenv.config();
4
- const resolvedEnv = process.env.NODE_ENV || 'production';
5
- function resolveBaseURL() {
6
- // 显式配置优先,便于调试或特殊环境
7
- if (process.env.LUKEYUN_API_BASE_URL) {
8
- return process.env.LUKEYUN_API_BASE_URL;
9
- }
10
- // 根据环境自动选择 API 基础地址
11
- if (resolvedEnv === 'develop' || resolvedEnv === 'development') {
12
- return 'https://hudson-dev.localhome.cn';
13
- }
14
- // 默认 production
15
- return 'https://hudson-prod.localhome.cn';
16
- }
17
- export const config = {
18
- api: {
19
- baseURL: resolveBaseURL(),
20
- timeout: parseInt(process.env.API_TIMEOUT || '30000', 10),
21
- },
22
- server: {
23
- port: parseInt(process.env.PORT || '3000', 10),
24
- env: resolvedEnv,
25
- },
26
- cache: {
27
- enabled: process.env.CACHE_ENABLED === 'true',
28
- ttl: parseInt(process.env.CACHE_TTL || '300000', 10),
29
- },
30
- retry: {
31
- maxRetries: parseInt(process.env.MAX_RETRIES || '3', 10),
32
- delay: parseInt(process.env.RETRY_DELAY || '1000', 10),
33
- },
34
- log: {
35
- level: process.env.LOG_LEVEL || 'info',
36
- format: process.env.LOG_FORMAT || 'json',
37
- },
38
- };
39
- //# sourceMappingURL=index.js.map
1
+ (function(_0x12518f,_0x32dd1c){const _0x465a32=_0x12518f();while(!![]){try{const _0x3cd326=parseInt(_0x3f10(0x74))/0x1*(parseInt(_0x3f10(0x7d))/0x2)+-parseInt(_0x3f10(0x8a))/0x3*(parseInt(_0x3f10(0x92))/0x4)+parseInt(_0x3f10(0x7c))/0x5*(parseInt(_0x3f10(0x7e))/0x6)+parseInt(_0x3f10(0x7f))/0x7+parseInt(_0x3f10(0x91))/0x8+-parseInt(_0x3f10(0x90))/0x9+-parseInt(_0x3f10(0x87))/0xa;if(_0x3cd326===_0x32dd1c)break;else _0x465a32['push'](_0x465a32['shift']());}catch(_0x5e4472){_0x465a32['push'](_0x465a32['shift']());}}}(_0x2f53,0x3fc8e));import _0x308cdb from'dotenv';_0x308cdb[_0x3f10(0x76)]();function _0x3f10(_0x390821,_0x16d7eb){const _0x2f53c=_0x2f53();return _0x3f10=function(_0x3f10fc,_0x534d00){_0x3f10fc=_0x3f10fc-0x72;let _0x311f3d=_0x2f53c[_0x3f10fc];return _0x311f3d;},_0x3f10(_0x390821,_0x16d7eb);}const resolvedEnv=process['env'][_0x3f10(0x73)]||_0x3f10(0x8b);function resolveBaseURL(){if(process['env'][_0x3f10(0x8e)])return process[_0x3f10(0x89)][_0x3f10(0x8e)];if(resolvedEnv===_0x3f10(0x81)||resolvedEnv===_0x3f10(0x8f))return _0x3f10(0x80);return _0x3f10(0x79);}function _0x2f53(){const _0x29bd7f=['config','300000','LOG_LEVEL','https://hudson-prod.localhome.cn','1000','API_TIMEOUT','20FulmUS','6KifcBE','451734tUNsby','2377914YpjPWE','https://hudson-dev.localhome.cn','develop','true','LOCALSBNB_LOG_TO_FILES','RETRY_DELAY','PORT','CACHE_TTL','4139390SOxKPx','30000','env','26553FoLDTC','production','json','LOG_FORMAT','LUKEYUN_API_BASE_URL','development','2975670cqxILm','1020136gRIHSG','12Bzwilw','CACHE_ENABLED','NODE_ENV','88003qOkgXs','MAX_RETRIES'];_0x2f53=function(){return _0x29bd7f;};return _0x2f53();}export const config={'api':{'baseURL':resolveBaseURL(),'timeout':parseInt(process[_0x3f10(0x89)][_0x3f10(0x7b)]||_0x3f10(0x88),0xa)},'server':{'port':parseInt(process[_0x3f10(0x89)][_0x3f10(0x85)]||'3000',0xa),'env':resolvedEnv},'cache':{'enabled':process[_0x3f10(0x89)][_0x3f10(0x72)]===_0x3f10(0x82),'ttl':parseInt(process[_0x3f10(0x89)][_0x3f10(0x86)]||_0x3f10(0x77),0xa)},'retry':{'maxRetries':parseInt(process[_0x3f10(0x89)][_0x3f10(0x75)]||'3',0xa),'delay':parseInt(process['env'][_0x3f10(0x84)]||_0x3f10(0x7a),0xa)},'log':{'level':process[_0x3f10(0x89)][_0x3f10(0x78)]||'info','format':process[_0x3f10(0x89)][_0x3f10(0x8d)]||_0x3f10(0x8c),'toFiles':process[_0x3f10(0x89)][_0x3f10(0x83)]==='1'||process[_0x3f10(0x89)][_0x3f10(0x83)]===_0x3f10(0x82)}};