itd-sdk-js 1.0.8 → 1.1.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.
@@ -8,14 +8,15 @@ export class NotificationsManager {
8
8
  }
9
9
 
10
10
  /**
11
- * Получает список уведомлений
12
- *
11
+ * Получает список уведомлений.
12
+ * GET /api/notifications/?offset=0&limit=20 → { notifications: [], hasMore }
13
+ *
13
14
  * @param {number} limit - Количество уведомлений
14
- * @param {string|null} cursor - Курсор для пагинации
15
- * @param {string|null} type - Фильтр по типу: 'reply', 'like', 'wall_post', 'follow', 'comment' (опционально)
16
- * @returns {Promise<Object|null>} { notifications: [], pagination: {} } или null при ошибке
15
+ * @param {number} offset - Смещение для пагинации
16
+ * @param {string|null} type - Фильтр по типу: 'reply', 'like', 'wall_post', 'follow', 'comment' (на клиенте)
17
+ * @returns {Promise<Object|null>} { notifications: [], hasMore } или null при ошибке
17
18
  */
18
- async getNotifications(limit = 20, cursor = null, type = null) {
19
+ async getNotifications(limit = 20, offset = 0, type = null) {
19
20
  if (!await this.client.auth.checkAuth()) {
20
21
  console.error('Ошибка: необходимо войти в аккаунт');
21
22
  return null;
@@ -23,42 +24,20 @@ export class NotificationsManager {
23
24
 
24
25
  try {
25
26
  const notificationsUrl = `${this.client.baseUrl}/api/notifications`;
26
- const params = { limit };
27
- if (cursor) {
28
- params.cursor = cursor;
29
- }
30
- // Пробуем передать type в параметрах (если API поддерживает)
31
- if (type) {
32
- params.type = type;
33
- }
27
+ const params = { limit, offset };
34
28
 
35
29
  const response = await this.axios.get(notificationsUrl, { params });
36
30
 
37
31
  if (response.status === 200) {
38
32
  const data = response.data;
39
- let notifications = [];
40
- let pagination = {};
41
-
42
- // Предполагаемая структура: { data: { notifications: [...], pagination: {...} } }
43
- if (data.data && data.data.notifications) {
44
- notifications = data.data.notifications;
45
- pagination = data.data.pagination || {};
46
- } else if (Array.isArray(data)) {
47
- notifications = data;
48
- } else if (data.notifications) {
49
- notifications = data.notifications;
50
- pagination = data.pagination || {};
51
- }
52
-
53
- // Фильтруем по типу на клиенте (если API не поддерживает фильтрацию)
33
+ let notifications = Array.isArray(data?.notifications) ? data.notifications : [];
34
+ const hasMore = Boolean(data?.hasMore);
35
+
54
36
  if (type && notifications.length > 0) {
55
37
  notifications = notifications.filter(notif => notif.type === type);
56
38
  }
57
-
58
- return {
59
- notifications: notifications,
60
- pagination: pagination
61
- };
39
+
40
+ return { notifications, hasMore };
62
41
  } else {
63
42
  console.error(`Ошибка получения уведомлений: ${response.status}`);
64
43
  return null;
@@ -73,6 +52,34 @@ export class NotificationsManager {
73
52
  }
74
53
  }
75
54
 
55
+ /**
56
+ * Отмечает несколько уведомлений как прочитанные.
57
+ * POST /api/notifications/read-batch → { success: true, count: number }
58
+ *
59
+ * @param {string[]} ids - Массив ID уведомлений
60
+ * @returns {Promise<Object|null>} { success: true, count } или null при ошибке
61
+ */
62
+ async markAsReadBatch(ids) {
63
+ if (!await this.client.auth.checkAuth()) {
64
+ console.error('Ошибка: необходимо войти в аккаунт');
65
+ return null;
66
+ }
67
+ if (!Array.isArray(ids) || ids.length === 0) {
68
+ return { success: true, count: 0 };
69
+ }
70
+ try {
71
+ const url = `${this.client.baseUrl}/api/notifications/read-batch`;
72
+ const response = await this.axios.post(url, { ids });
73
+ if (response.status === 200) {
74
+ return response.data;
75
+ }
76
+ return null;
77
+ } catch (error) {
78
+ console.error('Исключение при отметке уведомлений:', error.message);
79
+ return null;
80
+ }
81
+ }
82
+
76
83
  /**
77
84
  * Отмечает уведомление как прочитанное
78
85
  *
@@ -143,8 +150,9 @@ export class NotificationsManager {
143
150
  }
144
151
 
145
152
  /**
146
- * Отмечает все уведомления как прочитанные
147
- *
153
+ * Отмечает все уведомления как прочитанные.
154
+ * POST /api/notifications/read-all → { success: true }
155
+ *
148
156
  * @returns {Promise<boolean>} True если успешно
149
157
  */
150
158
  async markAllAsRead() {
@@ -154,12 +162,11 @@ export class NotificationsManager {
154
162
  }
155
163
 
156
164
  try {
157
- // Нужно найти реальный endpoint, пока используем предположительный
158
165
  const readAllUrl = `${this.client.baseUrl}/api/notifications/read-all`;
159
166
  const response = await this.axios.post(readAllUrl);
160
167
 
161
168
  if (response.status === 200 || response.status === 204) {
162
- return true;
169
+ return response.data?.success !== false;
163
170
  } else {
164
171
  console.error(`Ошибка отметки всех уведомлений: ${response.status}`);
165
172
  if (response.data) {
@@ -172,10 +179,6 @@ export class NotificationsManager {
172
179
  if (error.response) {
173
180
  console.error('Response status:', error.response.status);
174
181
  console.error('Response data:', error.response.data);
175
- // Если 404 - значит endpoint неправильный, нужно найти реальный
176
- if (error.response.status === 404) {
177
- console.error('💡 Endpoint не найден. Найди реальный URL в DevTools');
178
- }
179
182
  }
180
183
  return false;
181
184
  }
@@ -195,21 +198,16 @@ export class NotificationsManager {
195
198
 
196
199
  /**
197
200
  * Получает только непрочитанные уведомления (удобный метод)
198
- *
201
+ *
199
202
  * @param {number} limit - Количество уведомлений
200
- * @param {string|null} cursor - Курсор для пагинации
201
- * @returns {Promise<Object|null>} { notifications: [], pagination: {} } или null
203
+ * @param {number} offset - Смещение для пагинации
204
+ * @returns {Promise<Object|null>} { notifications: [], hasMore } или null
202
205
  */
203
- async getUnreadNotifications(limit = 20, cursor = null) {
204
- const all = await this.getNotifications(limit, cursor);
206
+ async getUnreadNotifications(limit = 20, offset = 0) {
207
+ const all = await this.getNotifications(limit, offset);
205
208
  if (!all) return null;
206
-
207
- // Фильтруем только непрочитанные
208
209
  const unread = all.notifications.filter(n => !n.read);
209
- return {
210
- notifications: unread,
211
- pagination: all.pagination
212
- };
210
+ return { notifications: unread, hasMore: all.hasMore };
213
211
  }
214
212
 
215
213
  }
package/src/posts.js CHANGED
@@ -230,6 +230,38 @@ export class PostsManager {
230
230
  }
231
231
  }
232
232
 
233
+ /**
234
+ * Получает лайкнутые посты пользователя.
235
+ * GET /api/posts/user/{username}/liked → { data: { posts: [], pagination: {} } }
236
+ *
237
+ * @param {string} username - Имя пользователя
238
+ * @param {number} limit - Количество постов (по умолчанию 20)
239
+ * @param {string|null} cursor - Курсор для пагинации (pagination.nextCursor)
240
+ * @returns {Promise<Object>} { posts: [], pagination: { limit, nextCursor, hasMore } }
241
+ */
242
+ async getLikedPosts(username, limit = 20, cursor = null) {
243
+ try {
244
+ const url = `${this.client.baseUrl}/api/posts/user/${encodeURIComponent(username)}/liked`;
245
+ const params = { limit };
246
+ if (cursor) params.cursor = cursor;
247
+
248
+ const response = await this.axios.get(url, { params });
249
+
250
+ if (response.status === 200) {
251
+ const data = response.data;
252
+ const inner = data?.data ?? data;
253
+ return {
254
+ posts: inner?.posts || [],
255
+ pagination: inner?.pagination || {}
256
+ };
257
+ }
258
+ return { posts: [], pagination: {} };
259
+ } catch (error) {
260
+ console.error('Ошибка получения лайкнутых постов:', error.message);
261
+ return { posts: [], pagination: {} };
262
+ }
263
+ }
264
+
233
265
  /**
234
266
  * Получает популярные посты (лента популярного)
235
267
  *
@@ -257,6 +289,52 @@ export class PostsManager {
257
289
  }
258
290
 
259
291
 
292
+ /**
293
+ * Отмечает пост как просмотренный. POST /api/posts/{id}/view
294
+ *
295
+ * @param {string} postId - ID поста
296
+ * @returns {Promise<boolean>} True если успешно
297
+ */
298
+ async viewPost(postId) {
299
+ if (!await this.client.auth.checkAuth()) return false;
300
+ try {
301
+ const url = `${this.client.baseUrl}/api/posts/${postId}/view`;
302
+ const response = await this.axios.post(url);
303
+ return response.status === 200 || response.status === 201 || response.status === 204;
304
+ } catch (error) {
305
+ console.error('Исключение при отметке просмотра:', error.message);
306
+ return false;
307
+ }
308
+ }
309
+
310
+ /**
311
+ * Получает посты на стене пользователя. GET /api/posts/user/{username}/wall
312
+ *
313
+ * @param {string} username - Имя пользователя
314
+ * @param {number} limit - Количество
315
+ * @param {string|null} cursor - Курсор пагинации
316
+ * @returns {Promise<Object>} { posts: [], pagination: {} }
317
+ */
318
+ async getWallByUser(username, limit = 20, cursor = null) {
319
+ try {
320
+ const url = `${this.client.baseUrl}/api/posts/user/${encodeURIComponent(username)}/wall`;
321
+ const params = { limit };
322
+ if (cursor) params.cursor = cursor;
323
+ const response = await this.axios.get(url, { params });
324
+ if (response.status === 200) {
325
+ const data = response.data?.data ?? response.data;
326
+ return {
327
+ posts: data?.posts || [],
328
+ pagination: data?.pagination || {}
329
+ };
330
+ }
331
+ return { posts: [], pagination: {} };
332
+ } catch (error) {
333
+ console.error('Ошибка получения постов со стены:', error.message);
334
+ return { posts: [], pagination: {} };
335
+ }
336
+ }
337
+
260
338
  /**
261
339
  * Получает конкретный пост по ID
262
340
  *
@@ -314,7 +392,7 @@ export class PostsManager {
314
392
  const response = await this.axios.put(editUrl, postData);
315
393
 
316
394
  if (response.status === 200) {
317
- return response.data;
395
+ return response.data?.data ?? response.data;
318
396
  } else {
319
397
  console.error(`Ошибка редактирования поста: ${response.status} - ${JSON.stringify(response.data)}`);
320
398
  return null;
@@ -348,26 +426,40 @@ export class PostsManager {
348
426
 
349
427
  if (response.status === 200 || response.status === 204) {
350
428
  return true;
351
- } else {
352
- console.error(`Ошибка удаления поста: ${response.status}`);
353
- if (response.data) {
354
- console.error('Response data:', response.data);
355
- }
356
- return false;
357
429
  }
430
+ return false;
358
431
  } catch (error) {
359
432
  console.error('Исключение при удалении поста:', error.message);
360
- if (error.response) {
361
- console.error('Response status:', error.response.status);
362
- console.error('Response data:', error.response.data);
363
- }
433
+ return false;
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Восстанавливает удалённый пост.
439
+ * POST /api/posts/{id}/restore — пустой ответ при успехе
440
+ *
441
+ * @param {string} postId - ID поста
442
+ * @returns {Promise<boolean>} True если успешно
443
+ */
444
+ async restorePost(postId) {
445
+ if (!await this.client.auth.checkAuth()) {
446
+ console.error('Ошибка: необходимо войти в аккаунт');
447
+ return false;
448
+ }
449
+ try {
450
+ const url = `${this.client.baseUrl}/api/posts/${postId}/restore`;
451
+ const response = await this.axios.post(url);
452
+ return response.status === 200 || response.status === 201 || response.status === 204;
453
+ } catch (error) {
454
+ console.error('Исключение при восстановлении поста:', error.message);
364
455
  return false;
365
456
  }
366
457
  }
367
458
 
368
459
  /**
369
- * Закрепляет пост
370
- *
460
+ * Закрепляет пост.
461
+ * POST /api/posts/{id}/pin → { success: true, pinnedPostId }
462
+ *
371
463
  * @param {string} postId - ID поста
372
464
  * @returns {Promise<boolean>} True если успешно
373
465
  */
@@ -376,27 +468,41 @@ export class PostsManager {
376
468
  console.error('Ошибка: необходимо войти в аккаунт');
377
469
  return false;
378
470
  }
379
-
380
471
  try {
381
472
  const pinUrl = `${this.client.baseUrl}/api/posts/${postId}/pin`;
382
473
  const response = await this.axios.post(pinUrl);
383
-
384
474
  if (response.status === 200 || response.status === 201) {
385
- return true;
386
- } else {
387
- console.error(`Ошибка закрепления поста: ${response.status}`);
388
- if (response.data) {
389
- console.error('Response data:', response.data);
390
- }
391
- return false;
475
+ return response.data?.success !== false;
392
476
  }
477
+ return false;
393
478
  } catch (error) {
394
479
  console.error('Исключение при закреплении поста:', error.message);
395
- if (error.response) {
396
- console.error('Response status:', error.response.status);
397
- console.error('Response data:', error.response.data);
480
+ return false;
481
+ }
482
+ }
483
+
484
+ /**
485
+ * Открепляет пост.
486
+ * DELETE /api/posts/{id}/pin → { success: true, pinnedPostId: null }
487
+ *
488
+ * @param {string} postId - ID поста
489
+ * @returns {Promise<boolean>} True если успешно
490
+ */
491
+ async unpinPost(postId) {
492
+ if (!await this.client.auth.checkAuth()) {
493
+ console.error('Ошибка: необходимо войти в аккаунт');
494
+ return false;
495
+ }
496
+ try {
497
+ const pinUrl = `${this.client.baseUrl}/api/posts/${postId}/pin`;
498
+ const response = await this.axios.delete(pinUrl);
499
+ if (response.status === 200 || response.status === 204) {
500
+ return response.data?.success !== false;
398
501
  }
399
502
  return false;
503
+ } catch (error) {
504
+ console.error('Исключение при откреплении поста:', error.message);
505
+ return false;
400
506
  }
401
507
  }
402
508
 
@@ -424,7 +530,7 @@ export class PostsManager {
424
530
  const response = await this.axios.post(repostUrl, repostData);
425
531
 
426
532
  if (response.status === 200 || response.status === 201) {
427
- return response.data;
533
+ return response.data?.data ?? response.data;
428
534
  } else {
429
535
  console.error(`Ошибка репоста: ${response.status}`);
430
536
  if (response.data) {
package/src/reports.js CHANGED
@@ -8,11 +8,12 @@ export class ReportsManager {
8
8
  }
9
9
 
10
10
  /**
11
- * Отправляет репорт на пост, комментарий или пользователя
12
- *
11
+ * Отправляет репорт на пост, комментарий или пользователя.
12
+ * POST /api/reports → { data: { id, createdAt } }
13
+ *
13
14
  * @param {string} targetType - Тип цели: "post", "comment", "user"
14
15
  * @param {string} targetId - ID цели (поста, комментария или пользователя)
15
- * @param {string} reason - Причина репорта (например, "other", "spam", "harassment", "inappropriate")
16
+ * @param {string} reason - Причина: "spam", "violence", "hate", "adult", "fraud", "other"
16
17
  * @param {string} description - Описание проблемы (опционально)
17
18
  * @returns {Promise<Object|null>} { id, createdAt } или null при ошибке
18
19
  */
@@ -61,9 +62,9 @@ export class ReportsManager {
61
62
 
62
63
  /**
63
64
  * Отправляет репорт на пост
64
- *
65
+ *
65
66
  * @param {string} postId - ID поста
66
- * @param {string} reason - Причина репорта (по умолчанию "other")
67
+ * @param {string} reason - Причина: "spam", "violence", "hate", "adult", "fraud", "other" (по умолчанию "other")
67
68
  * @param {string} description - Описание проблемы
68
69
  * @returns {Promise<Object|null>} { id, createdAt } или null при ошибке
69
70
  */
@@ -75,7 +76,7 @@ export class ReportsManager {
75
76
  * Отправляет репорт на комментарий
76
77
  *
77
78
  * @param {string} commentId - ID комментария
78
- * @param {string} reason - Причина репорта (по умолчанию "other")
79
+ * @param {string} reason - Причина: "spam", "violence", "hate", "adult", "fraud", "other"
79
80
  * @param {string} description - Описание проблемы
80
81
  * @returns {Promise<Object|null>} { id, createdAt } или null при ошибке
81
82
  */
@@ -87,7 +88,7 @@ export class ReportsManager {
87
88
  * Отправляет репорт на пользователя
88
89
  *
89
90
  * @param {string} userId - ID пользователя
90
- * @param {string} reason - Причина репорта (по умолчанию "other")
91
+ * @param {string} reason - Причина: "spam", "violence", "hate", "adult", "fraud", "other"
91
92
  * @param {string} description - Описание проблемы
92
93
  * @returns {Promise<Object|null>} { id, createdAt } или null при ошибке
93
94
  */
package/src/users.js CHANGED
@@ -8,13 +8,16 @@ export class UsersManager {
8
8
  }
9
9
 
10
10
  /**
11
- * Обновляет описание профиля текущего пользователя
12
- *
13
- * @param {string} bio - Новое описание профиля
11
+ * Обновляет профиль текущего пользователя.
12
+ * PUT /api/users/me → { id, username, displayName, bio, updatedAt }
13
+ *
14
+ * @param {string|null} bio - Новое описание профиля (опционально)
14
15
  * @param {string|null} displayName - Новое отображаемое имя (опционально)
16
+ * @param {string|null} username - Новый username (опционально)
17
+ * @param {string|null} bannerId - ID загруженного баннера (опционально)
15
18
  * @returns {Promise<Object|null>} Обновленные данные профиля или null при ошибке
16
19
  */
17
- async updateProfile(bio, displayName = null) {
20
+ async updateProfile(bio = null, displayName = null, username = null, bannerId = null) {
18
21
  if (!await this.client.auth.checkAuth()) {
19
22
  console.error('Ошибка: необходимо войти в аккаунт');
20
23
  return null;
@@ -22,19 +25,19 @@ export class UsersManager {
22
25
 
23
26
  try {
24
27
  const updateUrl = `${this.client.baseUrl}/api/users/me`;
25
-
26
28
  const updateData = {};
27
- if (bio !== null && bio !== undefined) {
28
- updateData.bio = bio;
29
- }
30
- if (displayName !== null && displayName !== undefined) {
31
- updateData.displayName = displayName;
29
+ if (bio != null) updateData.bio = bio;
30
+ if (displayName != null) updateData.displayName = displayName;
31
+ if (username != null) updateData.username = username;
32
+ if (bannerId != null) updateData.bannerId = bannerId;
33
+ if (Object.keys(updateData).length === 0) {
34
+ return await this.getMyProfile();
32
35
  }
33
36
 
34
37
  const response = await this.axios.put(updateUrl, updateData);
35
38
 
36
39
  if (response.status === 200) {
37
- return response.data;
40
+ return response.data?.data ?? response.data;
38
41
  } else {
39
42
  console.error(`Ошибка обновления профиля: ${response.status}`);
40
43
  if (response.data) {
@@ -86,6 +89,60 @@ export class UsersManager {
86
89
  }
87
90
  }
88
91
 
92
+ /**
93
+ * Получает настройки приватности текущего пользователя.
94
+ * GET /api/users/me/privacy → { isPrivate, wallClosed }
95
+ *
96
+ * @returns {Promise<Object|null>} { isPrivate, wallClosed } или null при ошибке
97
+ */
98
+ async getPrivacy() {
99
+ if (!await this.client.auth.checkAuth()) {
100
+ console.error('Ошибка: необходимо войти в аккаунт');
101
+ return null;
102
+ }
103
+ try {
104
+ const url = `${this.client.baseUrl}/api/users/me/privacy`;
105
+ const response = await this.axios.get(url);
106
+ if (response.status === 200) {
107
+ return response.data?.data ?? response.data;
108
+ }
109
+ return null;
110
+ } catch (error) {
111
+ console.error('Ошибка получения приватности:', error.message);
112
+ return null;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Обновляет настройки приватности.
118
+ * PUT /api/users/me/privacy → { isPrivate, wallClosed }
119
+ *
120
+ * @param {Object} options - { isPrivate?: boolean, wallClosed?: boolean }
121
+ * @returns {Promise<Object|null>} { isPrivate, wallClosed } или null при ошибке
122
+ */
123
+ async updatePrivacy(options = {}) {
124
+ if (!await this.client.auth.checkAuth()) {
125
+ console.error('Ошибка: необходимо войти в аккаунт');
126
+ return null;
127
+ }
128
+ try {
129
+ const url = `${this.client.baseUrl}/api/users/me/privacy`;
130
+ const payload = {};
131
+ if (options.isPrivate != null) payload.isPrivate = options.isPrivate;
132
+ if (options.wallClosed != null) payload.wallClosed = options.wallClosed;
133
+ if (Object.keys(payload).length === 0) return await this.getPrivacy();
134
+
135
+ const response = await this.axios.put(url, payload);
136
+ if (response.status === 200) {
137
+ return response.data?.data ?? response.data;
138
+ }
139
+ return null;
140
+ } catch (error) {
141
+ console.error('Ошибка обновления приватности:', error.message);
142
+ return null;
143
+ }
144
+ }
145
+
89
146
  /**
90
147
  * Получает профиль пользователя по username
91
148
  *
@@ -306,9 +363,8 @@ export class UsersManager {
306
363
  const response = await this.axios.get(topClansUrl);
307
364
 
308
365
  if (response.status === 200) {
309
- const data = response.data;
310
- // Структура: { clans: [...] }
311
- return data.clans || [];
366
+ const data = response.data?.data ?? response.data;
367
+ return data?.clans || [];
312
368
  } else {
313
369
  console.error(`Ошибка получения топ кланов: ${response.status}`);
314
370
  return null;
@@ -403,15 +459,4 @@ export class UsersManager {
403
459
  const profile = await this.getMyProfile();
404
460
  return profile ? (profile.avatar || null) : null;
405
461
  }
406
-
407
- /**
408
- * Получает клан пользователя (эмодзи аватара) (удобный метод)
409
- *
410
- * @param {string} username - Имя пользователя
411
- * @returns {Promise<string|null>} Эмодзи клана или null
412
- */
413
- async getUserClan(username) {
414
- const profile = await this.getUserProfile(username);
415
- return profile ? (profile.avatar || null) : null;
416
- }
417
462
  }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Модуль верификации аккаунта
3
+ */
4
+ export class VerificationManager {
5
+ constructor(client) {
6
+ this.client = client;
7
+ this.axios = client.axios;
8
+ }
9
+
10
+ /**
11
+ * Получает статус верификации. GET /api/verification/status
12
+ *
13
+ * @returns {Promise<Object|null>} Статус верификации или null
14
+ */
15
+ async getStatus() {
16
+ if (!await this.client.auth.checkAuth()) return null;
17
+ try {
18
+ const url = `${this.client.baseUrl}/api/verification/status`;
19
+ const response = await this.axios.get(url);
20
+ if (response.status === 200) {
21
+ return response.data?.data ?? response.data;
22
+ }
23
+ return null;
24
+ } catch (error) {
25
+ console.error('Ошибка получения статуса верификации:', error.message);
26
+ return null;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Подаёт заявку на верификацию. POST /api/verification/submit
32
+ *
33
+ * @param {string} videoUrl - URL загруженного видео (из uploadFile)
34
+ * @returns {Promise<Object|null>} { success, request: { id, status, ... } } или null
35
+ */
36
+ async submit(videoUrl) {
37
+ if (!await this.client.auth.checkAuth()) return null;
38
+ try {
39
+ const url = `${this.client.baseUrl}/api/verification/submit`;
40
+ const response = await this.axios.post(url, { videoUrl });
41
+ if (response.status === 200 || response.status === 201) {
42
+ return response.data?.data ?? response.data;
43
+ }
44
+ return null;
45
+ } catch (error) {
46
+ console.error('Ошибка подачи заявки на верификацию:', error.message);
47
+ return null;
48
+ }
49
+ }
50
+ }