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.
- package/API_REFERENCE.md +132 -28
- package/examples/quick-start.js +2 -5
- package/package.json +1 -1
- package/src/auth.js +47 -7
- package/src/client.js +220 -46
- package/src/comments.js +48 -13
- package/src/files.js +41 -1
- package/src/notifications.js +51 -53
- package/src/posts.js +132 -26
- package/src/reports.js +8 -7
- package/src/users.js +70 -25
- package/src/verification.js +50 -0
package/src/notifications.js
CHANGED
|
@@ -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 {
|
|
15
|
-
* @param {string|null} type - Фильтр по типу: 'reply', 'like', 'wall_post', 'follow', 'comment' (
|
|
16
|
-
* @returns {Promise<Object|null>} { notifications: [],
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 {
|
|
201
|
-
* @returns {Promise<Object|null>} { notifications: [],
|
|
203
|
+
* @param {number} offset - Смещение для пагинации
|
|
204
|
+
* @returns {Promise<Object|null>} { notifications: [], hasMore } или null
|
|
202
205
|
*/
|
|
203
|
-
async getUnreadNotifications(limit = 20,
|
|
204
|
-
const all = await this.getNotifications(limit,
|
|
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
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
|
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
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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 -
|
|
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 -
|
|
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 -
|
|
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 -
|
|
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
|
-
*
|
|
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
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
|
|
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
|
-
|
|
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
|
+
}
|