qwen-api-proxy 1.0.11 → 1.0.13

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.
@@ -13,8 +13,8 @@ const TOKENS_FILE = path.join(SESSION_PATH, 'tokens.json');
13
13
  let pointer = 0;
14
14
 
15
15
  function ensureSessionDir() {
16
- if (!fs.existsSync(SESSION_PATH)) fs.mkdirSync(SESSION_PATH, { recursive: true });
17
- if (!fs.existsSync(ACCOUNTS_PATH)) fs.mkdirSync(ACCOUNTS_PATH, { recursive: true });
16
+ if (!fs.existsSync(SESSION_PATH)) {fs.mkdirSync(SESSION_PATH, { recursive: true });}
17
+ if (!fs.existsSync(ACCOUNTS_PATH)) {fs.mkdirSync(ACCOUNTS_PATH, { recursive: true });}
18
18
  }
19
19
 
20
20
  /**
@@ -34,28 +34,28 @@ export function hasCookies(accountId) {
34
34
  */
35
35
  function decodeJwtExpiry(token) {
36
36
  try {
37
- if (!token || typeof token !== 'string') return null;
38
-
37
+ if (!token || typeof token !== 'string') {return null;}
38
+
39
39
  const parts = token.split('.');
40
- if (parts.length !== 3) return null;
41
-
40
+ if (parts.length !== 3) {return null;}
41
+
42
42
  // Декодируем payload (вторая часть JWT)
43
43
  // JWT использует URL-safe base64, нужно заменить - на + и _ на /
44
44
  let base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');
45
-
45
+
46
46
  // Добавляем padding если нужно
47
47
  while (base64.length % 4) {
48
48
  base64 += '=';
49
49
  }
50
-
50
+
51
51
  const payload = Buffer.from(base64, 'base64').toString('utf8');
52
52
  const decoded = JSON.parse(payload);
53
-
53
+
54
54
  // JWT использует поле 'exp' для времени истечения (в секундах)
55
55
  if (decoded.exp) {
56
56
  return decoded.exp * 1000; // Конвертируем в миллисекунды
57
57
  }
58
-
58
+
59
59
  return null;
60
60
  } catch (error) {
61
61
  // Если не удалось декодировать, возвращаем null
@@ -65,12 +65,12 @@ function decodeJwtExpiry(token) {
65
65
 
66
66
  export function loadTokens() {
67
67
  ensureSessionDir();
68
- if (!fs.existsSync(TOKENS_FILE)) return [];
68
+ if (!fs.existsSync(TOKENS_FILE)) {return [];}
69
69
  try {
70
70
  const tokens = JSON.parse(fs.readFileSync(TOKENS_FILE, 'utf8'));
71
-
71
+
72
72
  // Добавляем expiryTime для каждого токена, если его нет
73
- return tokens.map(token => {
73
+ return tokens.map((token) => {
74
74
  if (!token.expiryTime && token.token) {
75
75
  token.expiryTime = decodeJwtExpiry(token.token);
76
76
  }
@@ -99,25 +99,25 @@ export function saveTokens(tokens) {
99
99
  export async function getAvailableToken() {
100
100
  const tokens = loadTokens();
101
101
  const now = Date.now();
102
-
102
+
103
103
  // Фильтруем токены: не rate-limited, не invalid, JWT не истёк, и есть cookies
104
- const valid = tokens.filter(t => {
104
+ const valid = tokens.filter((t) => {
105
105
  // Пропускаем недействительные токены
106
- if (t.invalid) return false;
107
-
106
+ if (t.invalid) {return false;}
107
+
108
108
  // Пропускаем токены с rate limit в будущем
109
- if (t.resetAt && new Date(t.resetAt).getTime() > now) return false;
110
-
109
+ if (t.resetAt && new Date(t.resetAt).getTime() > now) {return false;}
110
+
111
111
  // Пропускаем токены с истёкшим JWT
112
- if (t.expiryTime && t.expiryTime <= now) return false;
113
-
112
+ if (t.expiryTime && t.expiryTime <= now) {return false;}
113
+
114
114
  // Пропускаем токены без cookies.json
115
- if (!hasCookies(t.id)) return false;
116
-
115
+ if (!hasCookies(t.id)) {return false;}
116
+
117
117
  return true;
118
118
  });
119
-
120
- if (!valid.length) return null;
119
+
120
+ if (!valid.length) {return null;}
121
121
  const token = valid[pointer % valid.length];
122
122
  pointer = (pointer + 1) % valid.length;
123
123
  return token;
@@ -126,28 +126,28 @@ export async function getAvailableToken() {
126
126
  export function hasValidTokens() {
127
127
  const tokens = loadTokens();
128
128
  const now = Date.now();
129
-
129
+
130
130
  // Проверяем, есть ли хотя бы один валидный токен с cookies
131
- return tokens.some(t => {
131
+ return tokens.some((t) => {
132
132
  // Пропускаем недействительные токены
133
- if (t.invalid) return false;
134
-
133
+ if (t.invalid) {return false;}
134
+
135
135
  // Пропускаем токены с rate limit в будущем
136
- if (t.resetAt && new Date(t.resetAt).getTime() > now) return false;
137
-
136
+ if (t.resetAt && new Date(t.resetAt).getTime() > now) {return false;}
137
+
138
138
  // Пропускаем токены с истёкшим JWT
139
- if (t.expiryTime && t.expiryTime <= now) return false;
140
-
139
+ if (t.expiryTime && t.expiryTime <= now) {return false;}
140
+
141
141
  // Пропускаем токены без cookies.json
142
- if (!hasCookies(t.id)) return false;
143
-
142
+ if (!hasCookies(t.id)) {return false;}
143
+
144
144
  return true;
145
145
  });
146
146
  }
147
147
 
148
148
  export function markRateLimited(id, hours = 24) {
149
149
  const tokens = loadTokens();
150
- const idx = tokens.findIndex(t => t.id === id);
150
+ const idx = tokens.findIndex((t) => t.id === id);
151
151
  if (idx !== -1) {
152
152
  tokens[idx].resetAt = new Date(Date.now() + hours * 3600 * 1000).toISOString();
153
153
  saveTokens(tokens);
@@ -155,24 +155,24 @@ export function markRateLimited(id, hours = 24) {
155
155
  }
156
156
 
157
157
  export function removeToken(id) {
158
- saveTokens(loadTokens().filter(t => t.id !== id));
158
+ saveTokens(loadTokens().filter((t) => t.id !== id));
159
159
  }
160
160
 
161
161
  export { removeToken as removeInvalidToken };
162
162
 
163
163
  export function markInvalid(id) {
164
164
  const tokens = loadTokens();
165
- const idx = tokens.findIndex(t => t.id === id);
165
+ const idx = tokens.findIndex((t) => t.id === id);
166
166
  if (idx !== -1) { tokens[idx].invalid = true; saveTokens(tokens); }
167
167
  }
168
168
 
169
169
  export function markValid(id, newToken) {
170
170
  const tokens = loadTokens();
171
- const idx = tokens.findIndex(t => t.id === id);
171
+ const idx = tokens.findIndex((t) => t.id === id);
172
172
  if (idx !== -1) {
173
173
  tokens[idx].invalid = false;
174
174
  tokens[idx].resetAt = null;
175
- if (newToken) tokens[idx].token = newToken;
175
+ if (newToken) {tokens[idx].token = newToken;}
176
176
  saveTokens(tokens);
177
177
  }
178
178
  }
@@ -188,20 +188,20 @@ export function listTokens() {
188
188
  export function getValidTokens() {
189
189
  const tokens = loadTokens();
190
190
  const now = Date.now();
191
-
192
- return tokens.filter(t => {
191
+
192
+ return tokens.filter((t) => {
193
193
  // Пропускаем недействительные токены
194
- if (t.invalid) return false;
195
-
194
+ if (t.invalid) {return false;}
195
+
196
196
  // Пропускаем токены с rate limit в будущем
197
- if (t.resetAt && new Date(t.resetAt).getTime() > now) return false;
198
-
197
+ if (t.resetAt && new Date(t.resetAt).getTime() > now) {return false;}
198
+
199
199
  // Пропускаем токены с истёкшим JWT
200
- if (t.expiryTime && t.expiryTime <= now) return false;
201
-
200
+ if (t.expiryTime && t.expiryTime <= now) {return false;}
201
+
202
202
  // Пропускаем токены без cookies.json
203
- if (!hasCookies(t.id)) return false;
204
-
203
+ if (!hasCookies(t.id)) {return false;}
204
+
205
205
  return true;
206
206
  });
207
207
  }
@@ -215,14 +215,14 @@ export function getValidTokens() {
215
215
  */
216
216
  export function checkTokenExpiry(tokenId, warningMs = TOKEN_EXPIRY_WARNING_MS) {
217
217
  const tokens = loadTokens();
218
- const token = tokens.find(t => t.id === tokenId);
219
-
218
+ const token = tokens.find((t) => t.id === tokenId);
219
+
220
220
  if (!token) {
221
221
  return { willExpireSoon: false, expiresAt: null, timeLeft: null, tokenFound: false };
222
222
  }
223
223
 
224
224
  const now = Date.now();
225
-
225
+
226
226
  // Если токен помечен как недействительный
227
227
  if (token.invalid) {
228
228
  return { willExpireSoon: true, expiresAt: null, timeLeft: null, tokenFound: true, isInvalid: true };
@@ -231,25 +231,25 @@ export function checkTokenExpiry(tokenId, warningMs = TOKEN_EXPIRY_WARNING_MS) {
231
231
  // Проверяем JWT expiry time (если есть)
232
232
  if (token.expiryTime) {
233
233
  const jwtTimeLeft = token.expiryTime - now;
234
-
234
+
235
235
  // Если JWT уже истёк
236
236
  if (jwtTimeLeft <= 0) {
237
- return {
238
- willExpireSoon: true,
239
- expiresAt: new Date(token.expiryTime),
240
- timeLeft: 0,
241
- tokenFound: true,
237
+ return {
238
+ willExpireSoon: true,
239
+ expiresAt: new Date(token.expiryTime),
240
+ timeLeft: 0,
241
+ tokenFound: true,
242
242
  isExpired: true,
243
243
  expiredType: 'jwt'
244
244
  };
245
245
  }
246
-
246
+
247
247
  // Если JWT истекает в ближайшее время
248
248
  if (jwtTimeLeft <= warningMs) {
249
- return {
250
- willExpireSoon: true,
251
- expiresAt: new Date(token.expiryTime),
252
- timeLeft: jwtTimeLeft,
249
+ return {
250
+ willExpireSoon: true,
251
+ expiresAt: new Date(token.expiryTime),
252
+ timeLeft: jwtTimeLeft,
253
253
  tokenFound: true,
254
254
  isExpiringSoon: true,
255
255
  expiredType: 'jwt'
@@ -261,35 +261,35 @@ export function checkTokenExpiry(tokenId, warningMs = TOKEN_EXPIRY_WARNING_MS) {
261
261
  if (token.resetAt) {
262
262
  const resetTime = new Date(token.resetAt).getTime();
263
263
  const timeLeft = resetTime - now;
264
-
264
+
265
265
  // Если уже истёк или истекает в ближайшее время
266
266
  if (timeLeft <= 0) {
267
- return {
268
- willExpireSoon: true,
269
- expiresAt: new Date(token.resetAt),
270
- timeLeft: 0,
271
- tokenFound: true,
267
+ return {
268
+ willExpireSoon: true,
269
+ expiresAt: new Date(token.resetAt),
270
+ timeLeft: 0,
271
+ tokenFound: true,
272
272
  isExpired: true,
273
273
  expiredType: 'rate_limit'
274
274
  };
275
275
  }
276
-
276
+
277
277
  if (timeLeft <= warningMs) {
278
- return {
279
- willExpireSoon: true,
280
- expiresAt: new Date(token.resetAt),
281
- timeLeft,
278
+ return {
279
+ willExpireSoon: true,
280
+ expiresAt: new Date(token.resetAt),
281
+ timeLeft,
282
282
  tokenFound: true,
283
283
  isExpiringSoon: true,
284
284
  expiredType: 'rate_limit'
285
285
  };
286
286
  }
287
-
288
- return {
289
- willExpireSoon: false,
290
- expiresAt: new Date(token.resetAt),
291
- timeLeft,
292
- tokenFound: true
287
+
288
+ return {
289
+ willExpireSoon: false,
290
+ expiresAt: new Date(token.resetAt),
291
+ timeLeft,
292
+ tokenFound: true
293
293
  };
294
294
  }
295
295
 
@@ -305,13 +305,13 @@ export function checkTokenExpiry(tokenId, warningMs = TOKEN_EXPIRY_WARNING_MS) {
305
305
  export function checkAllTokensExpiry(warningMs = TOKEN_EXPIRY_WARNING_MS) {
306
306
  const tokens = loadTokens();
307
307
  const now = Date.now();
308
-
308
+
309
309
  const expiringTokens = [];
310
310
  let activeTokens = 0;
311
311
 
312
- tokens.forEach(token => {
312
+ tokens.forEach((token) => {
313
313
  const expiryInfo = checkTokenExpiry(token.id, warningMs);
314
-
314
+
315
315
  if (expiryInfo.willExpireSoon) {
316
316
  expiringTokens.push({
317
317
  ...token,
@@ -340,15 +340,15 @@ export function checkAllTokensExpiry(warningMs = TOKEN_EXPIRY_WARNING_MS) {
340
340
  export async function getSafeToken(warningMs = TOKEN_EXPIRY_WARNING_MS) {
341
341
  const tokens = loadTokens();
342
342
  const now = Date.now();
343
-
343
+
344
344
  // Фильтруем токены, которые не истекают в ближайшее время и имеют cookies
345
- const safeTokens = tokens.filter(t => {
345
+ const safeTokens = tokens.filter((t) => {
346
346
  // Пропускаем недействительные токены
347
- if (t.invalid) return false;
348
-
347
+ if (t.invalid) {return false;}
348
+
349
349
  // Пропускаем токены без cookies.json
350
- if (!hasCookies(t.id)) return false;
351
-
350
+ if (!hasCookies(t.id)) {return false;}
351
+
352
352
  // Проверяем rate limit reset time
353
353
  if (t.resetAt) {
354
354
  const resetTime = new Date(t.resetAt).getTime();
@@ -357,7 +357,7 @@ export async function getSafeToken(warningMs = TOKEN_EXPIRY_WARNING_MS) {
357
357
  return false;
358
358
  }
359
359
  }
360
-
360
+
361
361
  // Проверяем JWT expiry time (если есть)
362
362
  if (t.expiryTime) {
363
363
  const jwtTimeLeft = t.expiryTime - now;
@@ -366,7 +366,7 @@ export async function getSafeToken(warningMs = TOKEN_EXPIRY_WARNING_MS) {
366
366
  return false;
367
367
  }
368
368
  }
369
-
369
+
370
370
  return true;
371
371
  });
372
372
 
@@ -376,7 +376,7 @@ export async function getSafeToken(warningMs = TOKEN_EXPIRY_WARNING_MS) {
376
376
 
377
377
  const token = safeTokens[pointer % safeTokens.length];
378
378
  pointer = (pointer + 1) % safeTokens.length;
379
-
379
+
380
380
  logInfo(`Использован безопасный токен: ${token.id}`);
381
381
  return token;
382
382
  }
@@ -4,20 +4,20 @@ import { extractAuthToken } from '../api/chat.js';
4
4
  import { logInfo, logError, logWarn } from '../logger/index.js';
5
5
  import { CHAT_PAGE_URL, AUTH_SIGNIN_URL, PAGE_TIMEOUT, RETRY_DELAY } from '../config.js';
6
6
 
7
- const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
7
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
8
8
 
9
9
  function isPlaywright(context) {
10
10
  return context && typeof context.newPage === 'function';
11
11
  }
12
12
 
13
13
  async function getPage(context) {
14
- if (context && typeof context.goto === 'function') return context;
15
- if (context && typeof context.newPage === 'function') return await context.newPage();
14
+ if (context && typeof context.goto === 'function') {return context;}
15
+ if (context && typeof context.newPage === 'function') {return await context.newPage();}
16
16
  throw new Error('Неверный контекст: не страница Puppeteer, не контекст Playwright');
17
17
  }
18
18
 
19
19
  async function promptUser(question) {
20
- return new Promise(resolve => {
20
+ return new Promise((resolve) => {
21
21
  process.stdout.write(question);
22
22
  const onData = (data) => {
23
23
  process.stdin.removeListener('data', onData);
@@ -30,13 +30,13 @@ async function promptUser(question) {
30
30
  }
31
31
 
32
32
  async function countLoginContainers(page, isPW) {
33
- if (isPW) return page.locator('.login-container').count();
33
+ if (isPW) {return page.locator('.login-container').count();}
34
34
  return (await page.$$('.login-container')).length;
35
35
  }
36
36
 
37
37
  export async function checkAuthentication(context) {
38
38
  try {
39
- if (getAuthenticationStatus()) return true;
39
+ if (getAuthenticationStatus()) {return true;}
40
40
 
41
41
  const page = await getPage(context);
42
42
  const isPW = isPlaywright(context);
@@ -45,7 +45,7 @@ export async function checkAuthentication(context) {
45
45
 
46
46
  try {
47
47
  await page.goto(CHAT_PAGE_URL, { waitUntil: 'domcontentloaded', timeout: PAGE_TIMEOUT });
48
- if (isPW) await page.waitForLoadState('domcontentloaded');
48
+ if (isPW) {await page.waitForLoadState('domcontentloaded');}
49
49
  await delay(RETRY_DELAY);
50
50
 
51
51
  const pageTitle = await page.title();
@@ -65,7 +65,7 @@ export async function checkAuthentication(context) {
65
65
  await saveSession(context);
66
66
  logInfo('Сессия обновлена');
67
67
  } catch (e) { logError('Не удалось обновить сессию', e); }
68
- if (isPW) await page.close();
68
+ if (isPW) {await page.close();}
69
69
  return true;
70
70
  }
71
71
 
@@ -90,7 +90,7 @@ export async function checkAuthentication(context) {
90
90
  setAuthenticationStatus(true);
91
91
  await saveSession(context);
92
92
  await extractAuthToken(context, true);
93
- if (isPW) await page.close();
93
+ if (isPW) {await page.close();}
94
94
  return true;
95
95
  }
96
96
 
@@ -98,7 +98,7 @@ export async function checkAuthentication(context) {
98
98
  setAuthenticationStatus(false);
99
99
  return false;
100
100
  } catch (error) {
101
- if (isPW) await page.close().catch(() => {});
101
+ if (isPW) {await page.close().catch(() => {});}
102
102
  throw error;
103
103
  }
104
104
  } catch (error) {
@@ -139,8 +139,8 @@ export async function startManualAuthentication(context, skipRestart = false) {
139
139
  await saveSession(context);
140
140
  await extractAuthToken(context, true);
141
141
  logInfo('Сессия сохранена успешно!');
142
- if (isPW) await page.close();
143
- if (!skipRestart) await restartBrowserInHeadlessMode();
142
+ if (isPW) {await page.close();}
143
+ if (!skipRestart) {await restartBrowserInHeadlessMode();}
144
144
  return true;
145
145
  }
146
146
 
@@ -148,7 +148,7 @@ export async function startManualAuthentication(context, skipRestart = false) {
148
148
  setAuthenticationStatus(false);
149
149
  return false;
150
150
  } catch (error) {
151
- if (isPW) await page.close().catch(() => {});
151
+ if (isPW) {await page.close().catch(() => {});}
152
152
  throw error;
153
153
  }
154
154
  } catch (error) {
@@ -18,10 +18,10 @@ let browserInstance = null;
18
18
  let browserContext = null;
19
19
  export let isAuthenticated = false;
20
20
 
21
- const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
21
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
22
22
 
23
23
  export async function initBrowser(visibleMode = true, skipManualRestart = false) {
24
- if (browserInstance) return true;
24
+ if (browserInstance) {return true;}
25
25
 
26
26
  logInfo('Инициализация браузера с Puppeteer Stealth...');
27
27
  try {
@@ -117,11 +117,11 @@ async function saveSessionPuppeteer(page) {
117
117
  try {
118
118
  const cookies = await page.cookies();
119
119
  const sessionDir = path.join(process.cwd(), SESSION_DIR, ACCOUNTS_DIR);
120
- if (!fs.existsSync(sessionDir)) fs.mkdirSync(sessionDir, { recursive: true });
120
+ if (!fs.existsSync(sessionDir)) {fs.mkdirSync(sessionDir, { recursive: true });}
121
121
 
122
122
  const accountId = `acc_${Date.now()}`;
123
123
  const accountDir = path.join(sessionDir, accountId);
124
- if (!fs.existsSync(accountDir)) fs.mkdirSync(accountDir, { recursive: true });
124
+ if (!fs.existsSync(accountDir)) {fs.mkdirSync(accountDir, { recursive: true });}
125
125
 
126
126
  fs.writeFileSync(path.join(accountDir, 'cookies.json'), JSON.stringify(cookies, null, 2));
127
127
  logInfo(`Cookies сохранены для аккаунта ${accountId}`);
@@ -151,7 +151,7 @@ async function startManualAuthenticationPuppeteer(page, skipManualRestart) {
151
151
  console.log('После успешной авторизации нажмите ENTER для продолжения...');
152
152
 
153
153
  await new Promise((resolve) => {
154
- if (process.stdin.isTTY) process.stdin.setRawMode(false);
154
+ if (process.stdin.isTTY) {process.stdin.setRawMode(false);}
155
155
  process.stdin.resume();
156
156
  process.stdin.setEncoding('utf8');
157
157
  const onData = (key) => {
@@ -180,7 +180,7 @@ async function startManualAuthenticationPuppeteer(page, skipManualRestart) {
180
180
  } else {
181
181
  logWarn('Токен не найден в localStorage/sessionStorage');
182
182
  logInfo('Попытка извлечь токен из cookies...');
183
- const tokenCookie = cookies.find(c => c.name.toLowerCase().includes('token') || c.name.toLowerCase().includes('auth'));
183
+ const tokenCookie = cookies.find((c) => c.name.toLowerCase().includes('token') || c.name.toLowerCase().includes('auth'));
184
184
  if (tokenCookie) {
185
185
  logInfo(`Токен найден в cookie: ${tokenCookie.name}`);
186
186
  saveAuthToken(tokenCookie.value);
@@ -188,12 +188,12 @@ async function startManualAuthenticationPuppeteer(page, skipManualRestart) {
188
188
  }
189
189
 
190
190
  const accountId = await saveSessionPuppeteer(page);
191
- if (accountId) logInfo(`Сессия сохранена с ID: ${accountId}`);
191
+ if (accountId) {logInfo(`Сессия сохранена с ID: ${accountId}`);}
192
192
 
193
193
  setAuthenticationStatus(true);
194
194
  logInfo('Авторизация завершена успешно');
195
195
 
196
- if (!skipManualRestart) await restartBrowserInHeadlessMode();
196
+ if (!skipManualRestart) {await restartBrowserInHeadlessMode();}
197
197
  } catch (error) {
198
198
  logError('Ошибка при ручной авторизации', error);
199
199
  throw error;
@@ -216,7 +216,7 @@ export async function shutdownBrowser() {
216
216
  if (browserInstance) {
217
217
  try {
218
218
  const pages = await browserInstance.pages();
219
- for (const page of pages) await page.close().catch(() => {});
219
+ for (const page of pages) {await page.close().catch(() => {});}
220
220
  await browserInstance.close();
221
221
  } catch (e) { logError('Ошибка при закрытии браузера', e); }
222
222
  }
@@ -16,7 +16,7 @@ function getSessionFilePath(accountId, fileName) {
16
16
  }
17
17
 
18
18
  function ensureDir(dirPath) {
19
- if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath, { recursive: true });
19
+ if (!fs.existsSync(dirPath)) {fs.mkdirSync(dirPath, { recursive: true });}
20
20
  }
21
21
 
22
22
  export function initSessionDirectory() {
@@ -91,7 +91,7 @@ export function clearSession(accountId = null) {
91
91
  for (const p of paths) {
92
92
  if (fs.existsSync(p)) { fs.unlinkSync(p); cleared = true; }
93
93
  }
94
- if (cleared) logInfo('Сессия очищена');
94
+ if (cleared) {logInfo('Сессия очищена');}
95
95
  return cleared;
96
96
  } catch (error) {
97
97
  logError('Ошибка при очистке сессии', error);
@@ -103,7 +103,7 @@ export function hasSession(accountId = null) {
103
103
  return [
104
104
  getSessionFilePath(accountId, 'state.json'),
105
105
  getSessionFilePath(accountId, 'cookies.json')
106
- ].some(p => fs.existsSync(p));
106
+ ].some((p) => fs.existsSync(p));
107
107
  }
108
108
 
109
109
  export function saveAuthToken(token) {
package/src/config.js CHANGED
@@ -24,9 +24,9 @@ if (dotenvResult.error) {
24
24
  // Все значения читаются из env-переменных с фоллбэками на дефолты.
25
25
 
26
26
  function toBoolean(value) {
27
- if (typeof value === 'boolean') return value;
28
- if (typeof value === 'number') return value === 1;
29
- if (typeof value !== 'string') return false;
27
+ if (typeof value === 'boolean') {return value;}
28
+ if (typeof value === 'number') {return value === 1;}
29
+ if (typeof value !== 'string') {return false;}
30
30
  return ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase());
31
31
  }
32
32
 
@@ -92,7 +92,7 @@ export const LOG_MAX_FILES = Number(process.env.LOG_MAX_FILES) || 5;
92
92
  // ─── Telegram уведомления ───────────────────────────────────────────────────
93
93
  export const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN || null;
94
94
  export const TELEGRAM_USER_IDS = process.env.TELEGRAM_USER_IDS
95
- ? process.env.TELEGRAM_USER_IDS.split(',').map(id => id.trim()).filter(id => id)
95
+ ? process.env.TELEGRAM_USER_IDS.split(',').map((id) => id.trim()).filter((id) => id)
96
96
  : [];
97
97
  export const TOKEN_EXPIRY_WARNING_MS = Number(process.env.TOKEN_EXPIRY_WARNING_MS) || 3600000; // 1 hour
98
98
 
@@ -14,7 +14,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
14
 
15
15
  function ensureAccountDir(id) {
16
16
  const accountDir = path.resolve(__dirname, '..', '..', SESSION_DIR, ACCOUNTS_DIR, id);
17
- if (!fs.existsSync(accountDir)) fs.mkdirSync(accountDir, { recursive: true });
17
+ if (!fs.existsSync(accountDir)) {fs.mkdirSync(accountDir, { recursive: true });}
18
18
  return accountDir;
19
19
  }
20
20
 
@@ -35,7 +35,7 @@ export async function addAccountInteractive() {
35
35
 
36
36
  if (!token) {
37
37
  token = loadAuthToken();
38
- if (token) logInfo('Токен получен из сохранённого файла.');
38
+ if (token) {logInfo('Токен получен из сохранённого файла.');}
39
39
  }
40
40
 
41
41
  if (!token) {
@@ -65,15 +65,15 @@ export async function interactiveAccountMenu() {
65
65
  console.log('1 - Добавить новый аккаунт');
66
66
  console.log('2 - Завершить');
67
67
  const choice = await prompt('Ваш выбор (1/2): ');
68
- if (choice === '1') await addAccountInteractive();
69
- else if (choice === '2') break;
70
- else console.log('Неверный выбор.');
68
+ if (choice === '1') {await addAccountInteractive();}
69
+ else if (choice === '2') {break;}
70
+ else {console.log('Неверный выбор.');}
71
71
  }
72
72
  }
73
73
 
74
74
  export async function reloginAccountInteractive() {
75
75
  const tokens = loadTokens();
76
- const invalids = tokens.filter(t => t.invalid);
76
+ const invalids = tokens.filter((t) => t.invalid);
77
77
  if (!invalids.length) {
78
78
  console.log('Нет аккаунтов, требующих повторного входа.');
79
79
  await prompt('Нажмите ENTER чтобы вернуться в меню...');
@@ -113,13 +113,13 @@ export async function removeAccountInteractive() {
113
113
  }
114
114
 
115
115
  const now = Date.now();
116
- const validTokens = tokens.filter(t => {
117
- if (t.invalid) return false;
118
- if (t.resetAt && new Date(t.resetAt).getTime() > now) return false;
119
- if (t.expiryTime && t.expiryTime <= now) return false;
116
+ const validTokens = tokens.filter((t) => {
117
+ if (t.invalid) {return false;}
118
+ if (t.resetAt && new Date(t.resetAt).getTime() > now) {return false;}
119
+ if (t.expiryTime && t.expiryTime <= now) {return false;}
120
120
  // Проверяем наличие cookies.json
121
121
  const cookiesPath = path.resolve(__dirname, '..', '..', SESSION_DIR, ACCOUNTS_DIR, t.id, 'cookies.json');
122
- if (!fs.existsSync(cookiesPath)) return false;
122
+ if (!fs.existsSync(cookiesPath)) {return false;}
123
123
  return true;
124
124
  });
125
125
 
@@ -132,7 +132,7 @@ export async function removeAccountInteractive() {
132
132
  console.log('\nДоступные аккаунты:');
133
133
  validTokens.forEach((t, idx) => console.log(`${idx + 1} - ${t.id}`));
134
134
  const choice = await prompt('Номер аккаунта, который нужно удалить (или ENTER для отмены): ');
135
- if (!choice) return;
135
+ if (!choice) {return;}
136
136
  const num = parseInt(choice, 10);
137
137
  if (isNaN(num) || num < 1 || num > validTokens.length) {
138
138
  console.log('Неверный выбор.');
@@ -142,11 +142,11 @@ export async function removeAccountInteractive() {
142
142
 
143
143
  const acc = validTokens[num - 1];
144
144
  const confirm = await prompt(`Точно удалить ${acc.id}? (y/N): `);
145
- if (confirm.toLowerCase() !== 'y') return;
145
+ if (confirm.toLowerCase() !== 'y') {return;}
146
146
 
147
147
  removeToken(acc.id);
148
148
  const dir = path.resolve(__dirname, '..', '..', SESSION_DIR, ACCOUNTS_DIR, acc.id);
149
- if (fs.existsSync(dir)) fs.rmSync(dir, { recursive: true, force: true });
149
+ if (fs.existsSync(dir)) {fs.rmSync(dir, { recursive: true, force: true });}
150
150
 
151
151
  logInfo(`Аккаунт ${acc.id} удалён.`);
152
152
  await prompt('ENTER чтобы вернуться...');