@cexy/hoonfca 1.0.1 → 1.0.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 (170) hide show
  1. package/.travis.yml +6 -0
  2. package/LICENSE-MIT +21 -0
  3. package/index.d.ts +620 -0
  4. package/index.js +778 -1
  5. package/package.json +31 -84
  6. package/src/{apis/addExternalModule.js → addExternalModule.js} +4 -5
  7. package/src/addUserToGroup.js +113 -0
  8. package/src/changeAdminStatus.js +95 -0
  9. package/src/changeApprovalMode.js +79 -0
  10. package/src/changeArchivedStatus.js +55 -0
  11. package/src/changeBio.js +76 -0
  12. package/src/changeBlockedStatus.js +47 -0
  13. package/src/changeBlockedStatusMqtt.js +86 -0
  14. package/src/changeGroupImage.js +133 -0
  15. package/src/changeNickname.js +59 -0
  16. package/src/changeThreadColor.js +71 -0
  17. package/src/{apis/changeThreadEmoji.js → changeThreadEmoji.js} +8 -6
  18. package/src/createNewGroup.js +88 -0
  19. package/src/createPoll.js +130 -0
  20. package/src/deleteMessage.js +56 -0
  21. package/src/deleteThread.js +56 -0
  22. package/src/editMessage.js +63 -0
  23. package/src/forwardAttachment.js +60 -0
  24. package/src/forwardMessage.js +63 -0
  25. package/src/getCurrentUserID.js +7 -0
  26. package/src/getEmojiUrl.js +29 -0
  27. package/src/getFriendsList.js +84 -0
  28. package/src/getGroupsList.js +83 -0
  29. package/src/getMarketplace.js +84 -0
  30. package/src/getNotifications.js +86 -0
  31. package/src/getPagesList.js +83 -0
  32. package/src/getStories.js +88 -0
  33. package/src/getThreadHistory.js +647 -0
  34. package/src/getThreadInfo.js +222 -0
  35. package/src/getThreadList.js +292 -0
  36. package/src/getThreadPictures.js +79 -0
  37. package/src/getUserID.js +66 -0
  38. package/src/getUserInfo.js +128 -0
  39. package/src/handleFriendRequest.js +57 -0
  40. package/src/handleMessageRequest.js +65 -0
  41. package/src/{apis/httpGet.js → httpGet.js} +15 -20
  42. package/src/httpPost.js +58 -0
  43. package/src/listenMqtt.js +1018 -0
  44. package/src/logout.js +75 -0
  45. package/src/markAsDelivered.js +58 -0
  46. package/src/{apis/markAsRead.js → markAsRead.js} +19 -30
  47. package/src/markAsReadAll.js +50 -0
  48. package/src/markAsSeen.js +61 -0
  49. package/src/muteThread.js +52 -0
  50. package/src/pinMessage.js +61 -0
  51. package/src/removeUserFromGroup.js +79 -0
  52. package/src/resolvePhotoUrl.js +45 -0
  53. package/src/searchForThread.js +53 -0
  54. package/src/searchUsers.js +89 -0
  55. package/src/sendComment.js +161 -0
  56. package/src/sendMessage.js +457 -0
  57. package/src/sendTypingIndicator.js +179 -0
  58. package/src/setBio.js +86 -0
  59. package/src/setMessageReaction.js +186 -0
  60. package/src/setPostReaction.js +71 -0
  61. package/src/setTheme.js +313 -0
  62. package/src/setTitle.js +90 -0
  63. package/src/shareContact.js +53 -0
  64. package/src/shareLink.js +62 -0
  65. package/src/threadColors.js +57 -0
  66. package/src/unfriend.js +53 -0
  67. package/src/unsendMessage.js +104 -0
  68. package/utils.js +1447 -0
  69. package/LICENSE +0 -3
  70. package/README.md +0 -491
  71. package/examples/login-with-cookies.js +0 -102
  72. package/examples/verify.js +0 -70
  73. package/src/apis/addUserToGroup.js +0 -108
  74. package/src/apis/changeAdminStatus.js +0 -148
  75. package/src/apis/changeArchivedStatus.js +0 -61
  76. package/src/apis/changeAvatar.js +0 -103
  77. package/src/apis/changeBio.js +0 -69
  78. package/src/apis/changeBlockedStatus.js +0 -54
  79. package/src/apis/changeGroupImage.js +0 -136
  80. package/src/apis/changeThreadColor.js +0 -116
  81. package/src/apis/comment.js +0 -207
  82. package/src/apis/createAITheme.js +0 -129
  83. package/src/apis/createNewGroup.js +0 -79
  84. package/src/apis/createPoll.js +0 -73
  85. package/src/apis/deleteMessage.js +0 -44
  86. package/src/apis/deleteThread.js +0 -52
  87. package/src/apis/e2ee.js +0 -17
  88. package/src/apis/editMessage.js +0 -70
  89. package/src/apis/emoji.js +0 -124
  90. package/src/apis/fetchThemeData.js +0 -82
  91. package/src/apis/follow.js +0 -81
  92. package/src/apis/forwardMessage.js +0 -52
  93. package/src/apis/friend.js +0 -243
  94. package/src/apis/gcmember.js +0 -122
  95. package/src/apis/gcname.js +0 -123
  96. package/src/apis/gcrule.js +0 -119
  97. package/src/apis/getAccess.js +0 -111
  98. package/src/apis/getBotInfo.js +0 -88
  99. package/src/apis/getBotInitialData.js +0 -43
  100. package/src/apis/getFriendsList.js +0 -79
  101. package/src/apis/getMessage.js +0 -423
  102. package/src/apis/getTheme.js +0 -95
  103. package/src/apis/getThemeInfo.js +0 -116
  104. package/src/apis/getThreadHistory.js +0 -239
  105. package/src/apis/getThreadInfo.js +0 -267
  106. package/src/apis/getThreadList.js +0 -232
  107. package/src/apis/getThreadPictures.js +0 -58
  108. package/src/apis/getUserID.js +0 -117
  109. package/src/apis/getUserInfo.js +0 -513
  110. package/src/apis/getUserInfoV2.js +0 -146
  111. package/src/apis/handleMessageRequest.js +0 -50
  112. package/src/apis/httpPost.js +0 -89
  113. package/src/apis/httpPostFormData.js +0 -69
  114. package/src/apis/listenMqtt.js +0 -1236
  115. package/src/apis/listenSpeed.js +0 -179
  116. package/src/apis/logout.js +0 -87
  117. package/src/apis/markAsDelivered.js +0 -47
  118. package/src/apis/markAsReadAll.js +0 -40
  119. package/src/apis/markAsSeen.js +0 -70
  120. package/src/apis/mqttDeltaValue.js +0 -278
  121. package/src/apis/muteThread.js +0 -45
  122. package/src/apis/nickname.js +0 -132
  123. package/src/apis/notes.js +0 -163
  124. package/src/apis/pinMessage.js +0 -150
  125. package/src/apis/produceMetaTheme.js +0 -180
  126. package/src/apis/realtime.js +0 -182
  127. package/src/apis/removeUserFromGroup.js +0 -117
  128. package/src/apis/resolvePhotoUrl.js +0 -58
  129. package/src/apis/searchForThread.js +0 -154
  130. package/src/apis/sendMessage.js +0 -354
  131. package/src/apis/sendMessageMqtt.js +0 -249
  132. package/src/apis/sendTypingIndicator.js +0 -91
  133. package/src/apis/setMessageReaction.js +0 -27
  134. package/src/apis/setMessageReactionMqtt.js +0 -61
  135. package/src/apis/setThreadTheme.js +0 -260
  136. package/src/apis/setThreadThemeMqtt.js +0 -94
  137. package/src/apis/share.js +0 -107
  138. package/src/apis/shareContact.js +0 -66
  139. package/src/apis/stickers.js +0 -257
  140. package/src/apis/story.js +0 -181
  141. package/src/apis/theme.js +0 -233
  142. package/src/apis/unfriend.js +0 -47
  143. package/src/apis/unsendMessage.js +0 -17
  144. package/src/engine/client.js +0 -92
  145. package/src/engine/models/buildAPI.js +0 -152
  146. package/src/engine/models/loginHelper.js +0 -519
  147. package/src/engine/models/setOptions.js +0 -88
  148. package/src/security/e2ee.js +0 -109
  149. package/src/types/index.d.ts +0 -498
  150. package/src/utils/antiSuspension.js +0 -506
  151. package/src/utils/auth-helpers.js +0 -149
  152. package/src/utils/autoReLogin.js +0 -336
  153. package/src/utils/axios.js +0 -436
  154. package/src/utils/cache.js +0 -54
  155. package/src/utils/clients.js +0 -282
  156. package/src/utils/constants.js +0 -410
  157. package/src/utils/formatters/data/formatAttachment.js +0 -370
  158. package/src/utils/formatters/data/formatDelta.js +0 -109
  159. package/src/utils/formatters/index.js +0 -159
  160. package/src/utils/formatters/value/formatCookie.js +0 -91
  161. package/src/utils/formatters/value/formatDate.js +0 -36
  162. package/src/utils/formatters/value/formatID.js +0 -16
  163. package/src/utils/formatters.js +0 -1373
  164. package/src/utils/headers.js +0 -230
  165. package/src/utils/index.js +0 -153
  166. package/src/utils/monitoring.js +0 -333
  167. package/src/utils/rateLimiter.js +0 -319
  168. package/src/utils/tokenRefresh.js +0 -657
  169. package/src/utils/user-agents.js +0 -238
  170. package/src/utils/validation.js +0 -157
@@ -1,436 +0,0 @@
1
- /* eslint-disable no-prototype-builtins */
2
- "use strict";
3
-
4
- const axios = require("axios");
5
- const { CookieJar } = require("tough-cookie");
6
- const { wrapper } = require("axios-cookiejar-support");
7
- const FormData = require("form-data");
8
- const { getHeaders } = require("./headers");
9
- const { getType } = require("./constants");
10
- const { globalRateLimiter } = require("./rateLimiter");
11
-
12
- const jar = new CookieJar();
13
- const client = wrapper(axios.create({ jar }));
14
-
15
- let proxyConfig = {};
16
-
17
- const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
18
-
19
- // Fast path for simple delays - use setImmediate for 0ms delays
20
- const fastDelay = (ms) => {
21
- if (ms <= 0) return Promise.resolve();
22
- if (ms <= 1) return new Promise(resolve => setImmediate(resolve));
23
- return new Promise(resolve => setTimeout(resolve, ms));
24
- };
25
-
26
- function adaptResponse(res) {
27
- const response = res.response || res;
28
- return {
29
- ...response,
30
- body: response.data,
31
- statusCode: response.status,
32
- request: {
33
- uri: new URL(response.config.url),
34
- headers: response.config.headers,
35
- method: response.config.method.toUpperCase(),
36
- form: response.config.data,
37
- formData: response.config.data
38
- },
39
- };
40
- }
41
-
42
- /**
43
- * Inspects an API response body for signs of session expiry or Facebook
44
- * bot-detection checkpoints and emits the appropriate signals on ctx.
45
- *
46
- * Returns true if the response looks like a valid authenticated response,
47
- * false if it signals logout / checkpoint.
48
- *
49
- * When a logout is detected and ctx.performAutoLogin is available the
50
- * function fires it (non-blocking) and throws so the caller knows the
51
- * original response is unusable.
52
- */
53
- async function inspectResponseForSessionIssues(adapted, ctx) {
54
- if (!ctx || ctx._skipSessionInspect) return;
55
-
56
- const body = adapted.body;
57
- if (!body) return;
58
-
59
- const bodyStr = typeof body === 'string' ? body : JSON.stringify(body);
60
-
61
- // Facebook bot-detection checkpoint IDs
62
- const isCheckpoint282 = bodyStr.includes('1501092823525282');
63
- const isCheckpoint956 = bodyStr.includes('828281030927956');
64
- const isScrapingWarning = bodyStr.includes('XCheckpointFBScrapingWarningController');
65
-
66
- if (isCheckpoint282) {
67
- const err = new Error('Bot checkpoint 282 detected. Please verify the account.');
68
- err.error = 'checkpoint_282';
69
- err.res = body;
70
- if (ctx._emitter && typeof ctx._emitter.emit === 'function') {
71
- ctx._emitter.emit('checkpoint_282', { res: body });
72
- }
73
- throw err;
74
- }
75
-
76
- if (isCheckpoint956) {
77
- const err = new Error('Bot checkpoint 956 detected. Please verify the account.');
78
- err.error = 'checkpoint_956';
79
- err.res = body;
80
- if (ctx._emitter && typeof ctx._emitter.emit === 'function') {
81
- ctx._emitter.emit('checkpoint_956', { res: body });
82
- }
83
- throw err;
84
- }
85
-
86
- if (isScrapingWarning) {
87
- const err = new Error('Facebook scraping warning checkpoint detected.');
88
- err.error = 'checkpoint_scraping';
89
- err.res = body;
90
- if (ctx._emitter && typeof ctx._emitter.emit === 'function') {
91
- ctx._emitter.emit('checkpoint', { type: 'scraping_warning', res: body });
92
- }
93
- throw err;
94
- }
95
-
96
- // Detect session expiry / forced logout.
97
- // IMPORTANT: Facebook's authenticated homepage also contains login.php links
98
- // in its nav/footer and has <title>Facebook</title> — any broad HTML-content
99
- // check will produce false positives and break valid sessions.
100
- // We ONLY flag a response as a login redirect when:
101
- // • The page contains the actual login form elements, OR
102
- // • A parsed JSON body explicitly redirects to login.php via a "redirect" field.
103
- const isLoginRedirect =
104
- bodyStr.includes('<form id="login_form"') ||
105
- bodyStr.includes('id="loginbutton"') ||
106
- bodyStr.includes('"login_page"') ||
107
- // JSON responses that carry an explicit redirect to the login page.
108
- // "next" appears alongside login.php only in unauthenticated redirect payloads.
109
- (bodyStr.includes('login.php') && bodyStr.includes('"next":"'));
110
-
111
- const isLoginBlocked =
112
- typeof body === 'object' && body !== null && body.error === 1357001;
113
-
114
- if (isLoginBlocked) {
115
- const err = new Error('Facebook blocked the login.');
116
- err.error = 'login_blocked';
117
- err.res = body;
118
- throw err;
119
- }
120
-
121
- if (isLoginRedirect) {
122
- if (ctx._emitter && typeof ctx._emitter.emit === 'function') {
123
- ctx._emitter.emit('sessionExpired', { res: body });
124
- }
125
-
126
- if (!ctx.auto_login && typeof ctx.performAutoLogin === 'function') {
127
- ctx.auto_login = true;
128
- // Safety: reset the flag after 2 minutes no matter what so future
129
- // session expiries are never silently swallowed.
130
- const autoLoginSafetyTimer = setTimeout(() => { ctx.auto_login = false; }, 120000);
131
- try {
132
- const ok = await ctx.performAutoLogin();
133
- clearTimeout(autoLoginSafetyTimer);
134
- ctx.auto_login = false;
135
- if (!ok) {
136
- const err = new Error('Not logged in. Auto re-login failed.');
137
- err.error = 'Not logged in.';
138
- err.res = body;
139
- throw err;
140
- }
141
- } catch (autoErr) {
142
- clearTimeout(autoLoginSafetyTimer);
143
- ctx.auto_login = false;
144
- throw autoErr;
145
- }
146
- } else {
147
- const err = new Error('Not logged in. Session has expired.');
148
- err.error = 'Not logged in.';
149
- err.res = body;
150
- throw err;
151
- }
152
- }
153
- }
154
-
155
- async function requestWithRetry(requestFunction, retries = 5, endpoint = '', threadID = '', ctx = null) {
156
- // Fast path for simple requests
157
- const isSimpleRequest = !endpoint && !threadID;
158
-
159
- // Acquire rate limit slot with optimized path
160
- let releaseSlot = null;
161
- if (!isSimpleRequest) {
162
- releaseSlot = await globalRateLimiter.checkRateLimit(false, endpoint);
163
- }
164
-
165
- // Check cooldowns efficiently
166
- if (!isSimpleRequest) {
167
- if (globalRateLimiter.isEndpointOnCooldown("__GLOBAL__")) {
168
- const cooldown = globalRateLimiter.getEndpointCooldownRemaining("__GLOBAL__");
169
- if (cooldown > 0) {
170
- console.warn(`Global cooldown active. Waiting ${cooldown}ms...`);
171
- await delay(cooldown);
172
- }
173
- }
174
-
175
- if (endpoint && globalRateLimiter.isEndpointOnCooldown(endpoint)) {
176
- const cooldown = globalRateLimiter.getEndpointCooldownRemaining(endpoint);
177
- if (cooldown > 0) {
178
- console.warn(`Endpoint ${endpoint} on cooldown. Waiting ${cooldown}ms...`);
179
- await delay(cooldown);
180
- }
181
- }
182
-
183
- if (threadID && globalRateLimiter.isThreadOnCooldown(threadID)) {
184
- const cooldown = globalRateLimiter.getCooldownRemaining(threadID);
185
- if (cooldown > 0) {
186
- console.warn(`Thread ${threadID} on cooldown. Waiting ${cooldown}ms...`);
187
- await delay(cooldown);
188
- }
189
- }
190
- }
191
-
192
- const checkAndApplyRateLimitCooldowns = (responseBody) => {
193
- const ERROR_COOLDOWNS = {
194
- 1545012: 60000,
195
- 1675004: 30000,
196
- 368: 120000,
197
- 404: 5000,
198
- 500: 10000,
199
- 503: 30000
200
- };
201
-
202
- const applyCooldown = (errorCode) => {
203
- if (errorCode && ERROR_COOLDOWNS[errorCode]) {
204
- if (threadID) {
205
- globalRateLimiter.setThreadCooldown(threadID, ERROR_COOLDOWNS[errorCode]);
206
- }
207
- if (endpoint) {
208
- globalRateLimiter.setEndpointCooldown(endpoint, ERROR_COOLDOWNS[errorCode]);
209
- }
210
- console.warn(`Rate limit detected (error ${errorCode}). Applied cooldown.`);
211
- return true;
212
- }
213
- return false;
214
- };
215
-
216
- if (!responseBody || typeof responseBody !== 'object') {
217
- return false;
218
- }
219
-
220
- if (applyCooldown(responseBody.error)) {
221
- return true;
222
- }
223
-
224
- if (Array.isArray(responseBody)) {
225
- for (const item of responseBody) {
226
- if (item && typeof item === 'object') {
227
- if (applyCooldown(item.error)) return true;
228
- if (item.errors && Array.isArray(item.errors)) {
229
- for (const err of item.errors) {
230
- const code = err.code || err.extensions?.code;
231
- if (applyCooldown(code)) return true;
232
- }
233
- }
234
- }
235
- }
236
- }
237
-
238
- if (responseBody.errors && Array.isArray(responseBody.errors)) {
239
- for (const err of responseBody.errors) {
240
- const code = err.code || err.extensions?.code;
241
- if (applyCooldown(code)) return true;
242
- }
243
- }
244
-
245
- return false;
246
- };
247
-
248
- try {
249
- for (let i = 0; i < retries; i++) {
250
- try {
251
- const res = await requestFunction();
252
- const adapted = adaptResponse(res);
253
-
254
- checkAndApplyRateLimitCooldowns(adapted.body);
255
-
256
- // Inspect for session expiry / bot-detection checkpoints
257
- await inspectResponseForSessionIssues(adapted, ctx);
258
-
259
- return adapted;
260
- } catch (error) {
261
- // If this is a session/checkpoint error we already raised, propagate immediately
262
- if (error.error === 'Not logged in.' ||
263
- error.error === 'checkpoint_282' ||
264
- error.error === 'checkpoint_956' ||
265
- error.error === 'checkpoint_scraping' ||
266
- error.error === 'login_blocked') {
267
- throw error;
268
- }
269
-
270
- // Abort immediately on invalid header characters - retrying won't help
271
- if (error.code === 'ERR_INVALID_CHAR' ||
272
- (error.message && error.message.includes('Invalid character in header'))) {
273
- const e = new Error('Invalid header content detected. Request aborted.');
274
- e.error = 'invalid_header';
275
- e.code = 'ERR_INVALID_CHAR';
276
- e.originalError = error;
277
- throw e;
278
- }
279
-
280
- // Network errors - might be transient
281
- const isNetworkError = error.code && [
282
- 'ECONNRESET', 'ETIMEDOUT', 'ECONNREFUSED', 'ENETUNREACH',
283
- 'EHOSTUNREACH', 'EAI_AGAIN', 'ENOTFOUND', 'ESOCKETTIMEDOUT'
284
- ].includes(error.code);
285
-
286
- if (error.response) {
287
- const adapted = adaptResponse(error.response);
288
- checkAndApplyRateLimitCooldowns(adapted.body);
289
- }
290
-
291
- if (i === retries - 1) {
292
- console.error(`Request failed after ${retries} attempts:`, error.message);
293
- if (error.response) {
294
- return adaptResponse(error.response);
295
- }
296
- throw error;
297
- }
298
-
299
- // Adaptive backoff: network errors get shorter delays
300
- const baseMultiplier = isNetworkError ? 0.5 : 1;
301
- const backoffTime = Math.min(
302
- (Math.pow(2, i) * 1000 * baseMultiplier) + Math.floor(Math.random() * 1000),
303
- 30000 // Cap at 30 seconds
304
- );
305
-
306
- if (backoffTime > 100) {
307
- console.warn(`Request attempt ${i + 1} failed. Retrying in ${Math.round(backoffTime)}ms...`);
308
- await delay(backoffTime);
309
- } else {
310
- // Fast path for very short delays
311
- await fastDelay(backoffTime);
312
- }
313
- }
314
- }
315
- } finally {
316
- // Always release the concurrency slot regardless of outcome.
317
- if (typeof releaseSlot === 'function') releaseSlot();
318
- }
319
- }
320
-
321
- function setProxy(proxyUrl) {
322
- if (proxyUrl) {
323
- try {
324
- const parsedProxy = new URL(proxyUrl);
325
- proxyConfig = {
326
- proxy: {
327
- host: parsedProxy.hostname,
328
- port: parsedProxy.port,
329
- protocol: parsedProxy.protocol.replace(":", ""),
330
- auth: parsedProxy.username && parsedProxy.password ? {
331
- username: parsedProxy.username,
332
- password: parsedProxy.password,
333
- } : undefined,
334
- },
335
- };
336
- } catch (e) {
337
- console.error("Invalid proxy URL. Please use a full URL format (e.g., http://user:pass@host:port).");
338
- proxyConfig = {};
339
- }
340
- } else {
341
- proxyConfig = {};
342
- }
343
- }
344
-
345
- function cleanGet(url) {
346
- const fn = () => client.get(url, { timeout: 60000, ...proxyConfig });
347
- return requestWithRetry(fn);
348
- }
349
-
350
- async function get(url, reqJar, qs, options, ctx, customHeader) {
351
- const config = {
352
- headers: getHeaders(url, options, ctx, customHeader),
353
- timeout: 60000,
354
- params: qs,
355
- ...proxyConfig,
356
- validateStatus: (status) => status >= 200 && status < 600,
357
- // Enable response compression for faster transfers
358
- decompress: true,
359
- // Optimize for performance
360
- maxContentLength: 50 * 1024 * 1024, // 50MB max
361
- maxBodyLength: 50 * 1024 * 1024
362
- };
363
- const endpoint = new URL(url).pathname;
364
- const threadHint = ctx && ctx.requestThreadID ? String(ctx.requestThreadID) : '';
365
- return requestWithRetry(async () => await client.get(url, config), 3, endpoint, threadHint, ctx);
366
- }
367
-
368
- async function post(url, reqJar, form, options, ctx, customHeader) {
369
- const headers = getHeaders(url, options, ctx, customHeader, 'xhr');
370
- let data = form;
371
- let contentType = headers['Content-Type'] || 'application/x-www-form-urlencoded';
372
-
373
- if (contentType.includes('json')) {
374
- data = JSON.stringify(form);
375
- } else {
376
- // Use URLSearchParams for better performance on large forms
377
- const transformedForm = new URLSearchParams();
378
- for (const key in form) {
379
- if (form.hasOwnProperty(key)) {
380
- let value = form[key];
381
- if (getType(value) === "Object") {
382
- value = JSON.stringify(value);
383
- }
384
- transformedForm.append(key, value);
385
- }
386
- }
387
- data = transformedForm.toString();
388
- }
389
-
390
- headers['Content-Type'] = contentType;
391
-
392
- const config = {
393
- headers,
394
- timeout: 60000,
395
- ...proxyConfig,
396
- validateStatus: (status) => status >= 200 && status < 600,
397
- decompress: true,
398
- maxContentLength: 50 * 1024 * 1024,
399
- maxBodyLength: 50 * 1024 * 1024
400
- };
401
- const endpoint = new URL(url).pathname;
402
- const threadHint = ctx && ctx.requestThreadID ? String(ctx.requestThreadID) : '';
403
- return requestWithRetry(async () => await client.post(url, data, config), 3, endpoint, threadHint, ctx);
404
- }
405
-
406
- async function postFormData(url, reqJar, form, qs, options, ctx) {
407
- const formData = new FormData();
408
- for (const key in form) {
409
- if (form.hasOwnProperty(key)) {
410
- formData.append(key, form[key]);
411
- }
412
- }
413
-
414
- const customHeader = { "Content-Type": `multipart/form-data; boundary=${formData.getBoundary()}` };
415
-
416
- const config = {
417
- headers: getHeaders(url, options, ctx, customHeader, 'xhr'),
418
- timeout: 60000,
419
- params: qs,
420
- ...proxyConfig,
421
- validateStatus: (status) => status >= 200 && status < 600,
422
- };
423
- const endpoint = new URL(url).pathname;
424
- const threadHint = ctx && ctx.requestThreadID ? String(ctx.requestThreadID) : '';
425
- return requestWithRetry(async () => await client.post(url, formData, config), 3, endpoint, threadHint, ctx);
426
- }
427
-
428
- module.exports = {
429
- cleanGet,
430
- get,
431
- post,
432
- postFormData,
433
- getJar: () => jar,
434
- setProxy,
435
- requestWithRetry
436
- };
@@ -1,54 +0,0 @@
1
- "use strict";
2
-
3
- class SimpleCache {
4
- constructor(defaultTTL = 300000) { // 5 minutes default
5
- this.cache = new Map();
6
- this.defaultTTL = defaultTTL;
7
- }
8
-
9
- set(key, value, ttl = this.defaultTTL) {
10
- const expiresAt = Date.now() + ttl;
11
- this.cache.set(key, { value, expiresAt });
12
-
13
- // Clean up expired entries occasionally
14
- if (Math.random() < 0.01) { // 1% chance
15
- this.cleanup();
16
- }
17
- }
18
-
19
- get(key) {
20
- const item = this.cache.get(key);
21
- if (!item) return null;
22
-
23
- if (Date.now() > item.expiresAt) {
24
- this.cache.delete(key);
25
- return null;
26
- }
27
-
28
- return item.value;
29
- }
30
-
31
- delete(key) {
32
- return this.cache.delete(key);
33
- }
34
-
35
- clear() {
36
- this.cache.clear();
37
- }
38
-
39
- cleanup() {
40
- const now = Date.now();
41
- for (const [key, item] of this.cache.entries()) {
42
- if (now > item.expiresAt) {
43
- this.cache.delete(key);
44
- }
45
- }
46
- }
47
-
48
- size() {
49
- this.cleanup();
50
- return this.cache.size;
51
- }
52
- }
53
-
54
- module.exports = SimpleCache;