surya-sahil-fca 1.0.0
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.
- package/CHANGELOG.md +175 -0
- package/DOCS.md +2636 -0
- package/LICENSE-MIT +21 -0
- package/README.md +107 -0
- package/func/checkUpdate.js +222 -0
- package/func/logger.js +48 -0
- package/index.d.ts +746 -0
- package/index.js +8 -0
- package/module/config.js +34 -0
- package/module/login.js +126 -0
- package/module/loginHelper.js +747 -0
- package/module/options.js +45 -0
- package/package.json +82 -0
- package/src/api/messaging/changeGroupImage.js +90 -0
- package/src/api/messaging/changeNickname.js +70 -0
- package/src/api/messaging/changeThreadName.js +123 -0
- package/src/api/messaging/createCommentPost.js +207 -0
- package/src/api/messaging/sendMessage.js +272 -0
- package/src/api/messaging/sendTypingIndicator.js +67 -0
- package/src/api/messaging/setMessageReaction.js +76 -0
- package/src/api/messaging/setTitle.js +119 -0
- package/src/api/messaging/stickers.js +257 -0
- package/src/core/sendReqMqtt.js +96 -0
- package/src/database/models/index.js +49 -0
- package/src/database/models/thread.js +31 -0
- package/src/database/models/user.js +32 -0
- package/src/database/threadData.js +98 -0
- package/src/database/userData.js +89 -0
- package/src/utils/client.js +320 -0
- package/src/utils/constants.js +23 -0
- package/src/utils/format.js +1115 -0
- package/src/utils/headers.js +115 -0
- package/src/utils/request.js +305 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Sanitize header value to remove invalid characters
|
|
4
|
+
function sanitizeHeaderValue(value) {
|
|
5
|
+
if (value === null || value === undefined) return "";
|
|
6
|
+
let str = String(value);
|
|
7
|
+
|
|
8
|
+
// Remove array-like strings (e.g., "["performAutoLogin"]")
|
|
9
|
+
// This handles cases where arrays were accidentally stringified
|
|
10
|
+
if (str.trim().startsWith("[") && str.trim().endsWith("]")) {
|
|
11
|
+
// Try to detect if it's a stringified array and remove it
|
|
12
|
+
try {
|
|
13
|
+
const parsed = JSON.parse(str);
|
|
14
|
+
if (Array.isArray(parsed)) {
|
|
15
|
+
// If it's an array, return empty string (invalid header value)
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
} catch {
|
|
19
|
+
// Not valid JSON, continue with normal sanitization
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Remove invalid characters for HTTP headers:
|
|
24
|
+
// - Control characters (0x00-0x1F, except HTAB 0x09)
|
|
25
|
+
// - DEL character (0x7F)
|
|
26
|
+
// - Newlines and carriage returns
|
|
27
|
+
// - Square brackets (often indicate array stringification issues)
|
|
28
|
+
str = str.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F\r\n\[\]]/g, "").trim();
|
|
29
|
+
|
|
30
|
+
return str;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Sanitize header name to ensure it's valid
|
|
34
|
+
function sanitizeHeaderName(name) {
|
|
35
|
+
if (!name || typeof name !== "string") return "";
|
|
36
|
+
// Remove invalid characters for HTTP header names
|
|
37
|
+
return name.replace(/[^\x21-\x7E]/g, "").trim();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getHeaders(url, options, ctx, customHeader) {
|
|
41
|
+
const u = new URL(url);
|
|
42
|
+
const ua = options?.userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36";
|
|
43
|
+
const referer = options?.referer || "https://www.facebook.com/";
|
|
44
|
+
const origin = referer.replace(/\/+$/, "");
|
|
45
|
+
const contentType = options?.contentType || "application/x-www-form-urlencoded";
|
|
46
|
+
const acceptLang = options?.acceptLanguage || "en-US,en;q=0.9,vi;q=0.8";
|
|
47
|
+
const headers = {
|
|
48
|
+
Host: sanitizeHeaderValue(u.host),
|
|
49
|
+
Origin: sanitizeHeaderValue(origin),
|
|
50
|
+
Referer: sanitizeHeaderValue(referer),
|
|
51
|
+
"User-Agent": sanitizeHeaderValue(ua),
|
|
52
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,application/json;q=0.8,*/*;q=0.7",
|
|
53
|
+
"Accept-Language": sanitizeHeaderValue(acceptLang),
|
|
54
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
55
|
+
"Content-Type": sanitizeHeaderValue(contentType),
|
|
56
|
+
Connection: "keep-alive",
|
|
57
|
+
DNT: "1",
|
|
58
|
+
"Upgrade-Insecure-Requests": "1",
|
|
59
|
+
"sec-ch-ua": "\"Chromium\";v=\"139\", \"Not;A=Brand\";v=\"24\", \"Google Chrome\";v=\"139\"",
|
|
60
|
+
"sec-ch-ua-mobile": "?0",
|
|
61
|
+
"sec-ch-ua-platform": "\"Windows\"",
|
|
62
|
+
"sec-ch-ua-arch": "\"x86\"",
|
|
63
|
+
"sec-ch-ua-bitness": "\"64\"",
|
|
64
|
+
"sec-ch-ua-full-version-list": "\"Chromium\";v=\"139.0.0.0\", \"Not;A=Brand\";v=\"24.0.0.0\", \"Google Chrome\";v=\"139.0.0.0\"",
|
|
65
|
+
"sec-ch-ua-platform-version": "\"15.0.0\"",
|
|
66
|
+
"Sec-Fetch-Site": "same-origin",
|
|
67
|
+
"Sec-Fetch-Mode": "cors",
|
|
68
|
+
"Sec-Fetch-Dest": "empty",
|
|
69
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
70
|
+
Pragma: "no-cache",
|
|
71
|
+
"Cache-Control": "no-cache"
|
|
72
|
+
};
|
|
73
|
+
if (ctx?.region) {
|
|
74
|
+
const regionValue = sanitizeHeaderValue(ctx.region);
|
|
75
|
+
if (regionValue) headers["X-MSGR-Region"] = regionValue;
|
|
76
|
+
}
|
|
77
|
+
if (customHeader && typeof customHeader === "object") {
|
|
78
|
+
// Filter customHeader to only include valid HTTP header values (strings, numbers, booleans)
|
|
79
|
+
// Exclude functions, objects, arrays, and other non-serializable values
|
|
80
|
+
for (const [key, value] of Object.entries(customHeader)) {
|
|
81
|
+
// Skip null, undefined, functions, objects, and arrays
|
|
82
|
+
if (value === null || value === undefined || typeof value === "function") {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (typeof value === "object") {
|
|
86
|
+
// Arrays are objects in JavaScript, so check for arrays explicitly
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// Skip plain objects (but allow null which is already handled above)
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// Only allow strings, numbers, and booleans - convert to string and sanitize
|
|
94
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
95
|
+
const sanitizedKey = sanitizeHeaderName(key);
|
|
96
|
+
const sanitizedValue = sanitizeHeaderValue(value);
|
|
97
|
+
if (sanitizedKey && sanitizedValue !== "") {
|
|
98
|
+
headers[sanitizedKey] = sanitizedValue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Final pass: sanitize all header values to ensure no invalid characters
|
|
104
|
+
const sanitizedHeaders = {};
|
|
105
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
106
|
+
const sanitizedKey = sanitizeHeaderName(key);
|
|
107
|
+
const sanitizedValue = sanitizeHeaderValue(value);
|
|
108
|
+
if (sanitizedKey && sanitizedValue !== "") {
|
|
109
|
+
sanitizedHeaders[sanitizedKey] = sanitizedValue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return sanitizedHeaders;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { getHeaders };
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const { CookieJar } = require("tough-cookie");
|
|
3
|
+
const { wrapper } = require("axios-cookiejar-support");
|
|
4
|
+
const FormData = require("form-data");
|
|
5
|
+
const { HttpsProxyAgent } = require("https-proxy-agent");
|
|
6
|
+
const { Readable } = require("stream");
|
|
7
|
+
|
|
8
|
+
const headersMod = require("./headers");
|
|
9
|
+
const getHeaders = headersMod.getHeaders || headersMod;
|
|
10
|
+
const formatMod = require("./format");
|
|
11
|
+
const getType = formatMod.getType || formatMod;
|
|
12
|
+
const constMod = require("./constants");
|
|
13
|
+
const getFrom = constMod.getFrom || constMod;
|
|
14
|
+
|
|
15
|
+
// Sanitize header value to remove invalid characters
|
|
16
|
+
function sanitizeHeaderValue(value) {
|
|
17
|
+
if (value === null || value === undefined) return "";
|
|
18
|
+
const str = String(value);
|
|
19
|
+
// Remove invalid characters for HTTP headers:
|
|
20
|
+
// - Control characters (0x00-0x1F, except HTAB 0x09)
|
|
21
|
+
// - DEL character (0x7F)
|
|
22
|
+
// - Newlines and carriage returns
|
|
23
|
+
return str.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F\r\n]/g, "").trim();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Sanitize header name to ensure it's valid
|
|
27
|
+
function sanitizeHeaderName(name) {
|
|
28
|
+
if (!name || typeof name !== "string") return "";
|
|
29
|
+
// Remove invalid characters for HTTP header names
|
|
30
|
+
return name.replace(/[^\x21-\x7E]/g, "").trim();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Sanitize all headers in an object
|
|
34
|
+
function sanitizeHeaders(headers) {
|
|
35
|
+
if (!headers || typeof headers !== "object") return {};
|
|
36
|
+
const sanitized = {};
|
|
37
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
38
|
+
const sanitizedKey = sanitizeHeaderName(key);
|
|
39
|
+
if (!sanitizedKey) continue;
|
|
40
|
+
|
|
41
|
+
// Handle arrays - skip them entirely
|
|
42
|
+
if (Array.isArray(value)) continue;
|
|
43
|
+
|
|
44
|
+
// Handle objects - skip them
|
|
45
|
+
if (value !== null && typeof value === "object") continue;
|
|
46
|
+
|
|
47
|
+
// Handle functions - skip them
|
|
48
|
+
if (typeof value === "function") continue;
|
|
49
|
+
|
|
50
|
+
// Check if string value looks like a stringified array (e.g., "["performAutoLogin"]")
|
|
51
|
+
if (typeof value === "string") {
|
|
52
|
+
const trimmed = value.trim();
|
|
53
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
54
|
+
// Try to parse as JSON array - if successful, skip this header
|
|
55
|
+
try {
|
|
56
|
+
const parsed = JSON.parse(trimmed);
|
|
57
|
+
if (Array.isArray(parsed)) {
|
|
58
|
+
continue; // Skip stringified arrays
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
// Not valid JSON array, continue with normal sanitization
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Sanitize the value
|
|
67
|
+
const sanitizedValue = sanitizeHeaderValue(value);
|
|
68
|
+
if (sanitizedValue !== "") {
|
|
69
|
+
sanitized[sanitizedKey] = sanitizedValue;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return sanitized;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const jar = new CookieJar();
|
|
76
|
+
const client = wrapper(axios.create({
|
|
77
|
+
jar,
|
|
78
|
+
withCredentials: true,
|
|
79
|
+
timeout: 60000,
|
|
80
|
+
validateStatus: s => s >= 200 && s < 600,
|
|
81
|
+
maxRedirects: 5,
|
|
82
|
+
maxContentLength: Infinity,
|
|
83
|
+
maxBodyLength: Infinity
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
const delay = ms => new Promise(r => setTimeout(r, ms));
|
|
87
|
+
|
|
88
|
+
async function requestWithRetry(fn, retries = 3, baseDelay = 1000) {
|
|
89
|
+
let lastError;
|
|
90
|
+
for (let i = 0; i < retries; i++) {
|
|
91
|
+
try {
|
|
92
|
+
return await fn();
|
|
93
|
+
} catch (e) {
|
|
94
|
+
lastError = e;
|
|
95
|
+
|
|
96
|
+
// Handle ERR_INVALID_CHAR and other header errors - don't retry, return error immediately
|
|
97
|
+
if (e?.code === "ERR_INVALID_CHAR" || (e?.message && e.message.includes("Invalid character in header"))) {
|
|
98
|
+
const err = new Error("Invalid header content detected. Request aborted to prevent crash.");
|
|
99
|
+
err.error = "Invalid header content";
|
|
100
|
+
err.originalError = e;
|
|
101
|
+
err.code = "ERR_INVALID_CHAR";
|
|
102
|
+
return Promise.reject(err);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Don't retry on client errors (4xx) except 429 (rate limit)
|
|
106
|
+
const status = e?.response?.status || e?.statusCode || 0;
|
|
107
|
+
if (status >= 400 && status < 500 && status !== 429) {
|
|
108
|
+
return e.response || Promise.reject(e);
|
|
109
|
+
}
|
|
110
|
+
// Don't retry on last attempt
|
|
111
|
+
if (i === retries - 1) {
|
|
112
|
+
return e.response || Promise.reject(e);
|
|
113
|
+
}
|
|
114
|
+
// Exponential backoff with jitter
|
|
115
|
+
const backoffDelay = Math.min(
|
|
116
|
+
baseDelay * Math.pow(2, i) + Math.floor(Math.random() * 200),
|
|
117
|
+
30000 // Max 30 seconds
|
|
118
|
+
);
|
|
119
|
+
await delay(backoffDelay);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Return error instead of throwing to prevent uncaught exception
|
|
123
|
+
const finalError = lastError || new Error("Request failed after retries");
|
|
124
|
+
return Promise.reject(finalError);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function cfg(base = {}) {
|
|
128
|
+
const { reqJar, headers, params, agent, timeout } = base;
|
|
129
|
+
return {
|
|
130
|
+
headers: sanitizeHeaders(headers),
|
|
131
|
+
params,
|
|
132
|
+
jar: reqJar || jar,
|
|
133
|
+
withCredentials: true,
|
|
134
|
+
timeout: timeout || 60000,
|
|
135
|
+
httpAgent: agent || client.defaults.httpAgent,
|
|
136
|
+
httpsAgent: agent || client.defaults.httpsAgent,
|
|
137
|
+
proxy: false,
|
|
138
|
+
validateStatus: s => s >= 200 && s < 600
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function toStringVal(v) {
|
|
143
|
+
if (v === undefined || v === null) return "";
|
|
144
|
+
if (typeof v === "bigint") return v.toString();
|
|
145
|
+
if (typeof v === "boolean") return v ? "true" : "false";
|
|
146
|
+
return String(v);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isStream(v) {
|
|
150
|
+
return v && typeof v === "object" && typeof v.pipe === "function" && typeof v.on === "function";
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function isBlobLike(v) {
|
|
154
|
+
return v && typeof v.arrayBuffer === "function" && (typeof v.type === "string" || typeof v.name === "string");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function isPairArrayList(arr) {
|
|
158
|
+
return Array.isArray(arr) && arr.length > 0 && arr.every(x => Array.isArray(x) && x.length === 2 && typeof x[0] === "string");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function cleanGet(url) {
|
|
162
|
+
return requestWithRetry(() => client.get(url, cfg()), 3, 1000);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function get(url, reqJar, qs, options, ctx, customHeader) {
|
|
166
|
+
const headers = getHeaders(url, options, ctx, customHeader);
|
|
167
|
+
return requestWithRetry(() => client.get(url, cfg({ reqJar, headers, params: qs })), 3, 1000);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function post(url, reqJar, form, options, ctx, customHeader) {
|
|
171
|
+
const headers = getHeaders(url, options, ctx, customHeader);
|
|
172
|
+
const ct = String(headers["Content-Type"] || headers["content-type"] || "application/x-www-form-urlencoded").toLowerCase();
|
|
173
|
+
let data;
|
|
174
|
+
if (ct.includes("json")) {
|
|
175
|
+
data = JSON.stringify(form || {});
|
|
176
|
+
headers["Content-Type"] = "application/json";
|
|
177
|
+
} else {
|
|
178
|
+
const p = new URLSearchParams();
|
|
179
|
+
if (form && typeof form === "object") {
|
|
180
|
+
for (const k of Object.keys(form)) {
|
|
181
|
+
let v = form[k];
|
|
182
|
+
if (isPairArrayList(v)) {
|
|
183
|
+
for (const [kk, vv] of v) p.append(`${k}[${kk}]`, toStringVal(vv));
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (Array.isArray(v)) {
|
|
187
|
+
for (const x of v) {
|
|
188
|
+
if (Array.isArray(x) && x.length === 2 && typeof x[1] !== "object") p.append(k, toStringVal(x[1]));
|
|
189
|
+
else p.append(k, toStringVal(x));
|
|
190
|
+
}
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (getType(v) === "Object") v = JSON.stringify(v);
|
|
194
|
+
p.append(k, toStringVal(v));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
data = p.toString();
|
|
198
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
199
|
+
}
|
|
200
|
+
return requestWithRetry(() => client.post(url, data, cfg({ reqJar, headers })), 3, 1000);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function postFormData(url, reqJar, form, qs, options, ctx) {
|
|
204
|
+
const fd = new FormData();
|
|
205
|
+
if (form && typeof form === "object") {
|
|
206
|
+
for (const k of Object.keys(form)) {
|
|
207
|
+
const v = form[k];
|
|
208
|
+
if (v === undefined || v === null) continue;
|
|
209
|
+
if (isPairArrayList(v)) {
|
|
210
|
+
for (const [kk, vv] of v) fd.append(`${k}[${kk}]`, typeof vv === "object" && !Buffer.isBuffer(vv) && !isStream(vv) ? JSON.stringify(vv) : vv);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (Array.isArray(v)) {
|
|
214
|
+
for (const x of v) {
|
|
215
|
+
if (Array.isArray(x) && x.length === 2 && x[1] && typeof x[1] === "object" && !Buffer.isBuffer(x[1]) && !isStream(x[1])) {
|
|
216
|
+
fd.append(k, x[0], x[1]);
|
|
217
|
+
} else if (Array.isArray(x) && x.length === 2 && typeof x[1] !== "object") {
|
|
218
|
+
fd.append(k, toStringVal(x[1]));
|
|
219
|
+
} else if (x && typeof x === "object" && "value" in x && "options" in x) {
|
|
220
|
+
fd.append(k, x.value, x.options || {});
|
|
221
|
+
} else if (isStream(x) || Buffer.isBuffer(x) || typeof x === "string") {
|
|
222
|
+
fd.append(k, x);
|
|
223
|
+
} else if (isBlobLike(x)) {
|
|
224
|
+
const buf = Buffer.from(await x.arrayBuffer());
|
|
225
|
+
fd.append(k, buf, { filename: x.name || k, contentType: x.type || undefined });
|
|
226
|
+
} else {
|
|
227
|
+
fd.append(k, JSON.stringify(x));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (v && typeof v === "object" && "value" in v && "options" in v) {
|
|
233
|
+
fd.append(k, v.value, v.options || {});
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (isStream(v) || Buffer.isBuffer(v) || typeof v === "string") {
|
|
237
|
+
fd.append(k, v);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (isBlobLike(v)) {
|
|
241
|
+
const buf = Buffer.from(await v.arrayBuffer());
|
|
242
|
+
fd.append(k, buf, { filename: v.name || k, contentType: v.type || undefined });
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (typeof v === "number" || typeof v === "boolean") {
|
|
246
|
+
fd.append(k, toStringVal(v));
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
fd.append(k, JSON.stringify(v));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const headers = { ...getHeaders(url, options, ctx), ...fd.getHeaders() };
|
|
253
|
+
return requestWithRetry(() => client.post(url, fd, cfg({ reqJar, headers, params: qs })), 3, 1000);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function makeDefaults(html, userID, ctx) {
|
|
257
|
+
let reqCounter = 1;
|
|
258
|
+
const revision = getFrom(html || "", 'revision":', ",") || getFrom(html || "", '"client_revision":', ",") || "";
|
|
259
|
+
function mergeWithDefaults(obj) {
|
|
260
|
+
const base = {
|
|
261
|
+
av: userID,
|
|
262
|
+
__user: userID,
|
|
263
|
+
__req: (reqCounter++).toString(36),
|
|
264
|
+
__rev: revision,
|
|
265
|
+
__a: 1
|
|
266
|
+
};
|
|
267
|
+
if (ctx?.fb_dtsg) base.fb_dtsg = ctx.fb_dtsg;
|
|
268
|
+
if (ctx?.jazoest) base.jazoest = ctx.jazoest;
|
|
269
|
+
if (!obj) return base;
|
|
270
|
+
for (const k of Object.keys(obj)) if (!(k in base)) base[k] = obj[k];
|
|
271
|
+
return base;
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
get: (url, j, qs, ctxx, customHeader = {}) =>
|
|
275
|
+
get(url, j, mergeWithDefaults(qs), ctx?.globalOptions, ctxx || ctx, customHeader),
|
|
276
|
+
post: (url, j, form, ctxx, customHeader = {}) =>
|
|
277
|
+
post(url, j, mergeWithDefaults(form), ctx?.globalOptions, ctxx || ctx, customHeader),
|
|
278
|
+
postFormData: (url, j, form, qs, ctxx) =>
|
|
279
|
+
postFormData(url, j, mergeWithDefaults(form), mergeWithDefaults(qs), ctx?.globalOptions, ctxx || ctx)
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function setProxy(proxyUrl) {
|
|
284
|
+
if (!proxyUrl) {
|
|
285
|
+
client.defaults.httpAgent = undefined;
|
|
286
|
+
client.defaults.httpsAgent = undefined;
|
|
287
|
+
client.defaults.proxy = false;
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const agent = new HttpsProxyAgent(proxyUrl);
|
|
291
|
+
client.defaults.httpAgent = agent;
|
|
292
|
+
client.defaults.httpsAgent = agent;
|
|
293
|
+
client.defaults.proxy = false;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
module.exports = {
|
|
297
|
+
cleanGet,
|
|
298
|
+
get,
|
|
299
|
+
post,
|
|
300
|
+
postFormData,
|
|
301
|
+
jar,
|
|
302
|
+
setProxy,
|
|
303
|
+
makeDefaults,
|
|
304
|
+
client
|
|
305
|
+
};
|