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/client.js
CHANGED
|
@@ -16,6 +16,7 @@ import { HashtagsManager } from './hashtags.js';
|
|
|
16
16
|
import { FilesManager } from './files.js';
|
|
17
17
|
import { ReportsManager } from './reports.js';
|
|
18
18
|
import { SearchManager } from './search.js';
|
|
19
|
+
import { VerificationManager } from './verification.js';
|
|
19
20
|
|
|
20
21
|
dotenv.config();
|
|
21
22
|
|
|
@@ -199,7 +200,8 @@ export class ITDClient {
|
|
|
199
200
|
this.hashtags = new HashtagsManager(this);
|
|
200
201
|
this.files = new FilesManager(this);
|
|
201
202
|
this.reports = new ReportsManager(this);
|
|
202
|
-
this.
|
|
203
|
+
this.searchManager = new SearchManager(this);
|
|
204
|
+
this.verification = new VerificationManager(this);
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
/**
|
|
@@ -343,6 +345,17 @@ export class ITDClient {
|
|
|
343
345
|
async logout() {
|
|
344
346
|
return await this.auth.logout();
|
|
345
347
|
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Смена пароля. POST /api/v1/auth/change-password. Требует cookies (refresh_token).
|
|
351
|
+
*
|
|
352
|
+
* @param {string} oldPassword - Текущий пароль
|
|
353
|
+
* @param {string} newPassword - Новый пароль
|
|
354
|
+
* @returns {Promise<Object|null>} Ответ API или null
|
|
355
|
+
*/
|
|
356
|
+
async changePassword(oldPassword, newPassword) {
|
|
357
|
+
return await this.auth.changePassword(oldPassword, newPassword);
|
|
358
|
+
}
|
|
346
359
|
|
|
347
360
|
/**
|
|
348
361
|
* Создает пост (удобный метод)
|
|
@@ -383,7 +396,7 @@ export class ITDClient {
|
|
|
383
396
|
*
|
|
384
397
|
* @param {string|null} username - Имя пользователя (null = лента/свои посты)
|
|
385
398
|
* @param {number} limit - Количество постов
|
|
386
|
-
* @param {string} sort - Сортировка: "
|
|
399
|
+
* @param {string} sort - Сортировка: "newest", "oldest", "popular"
|
|
387
400
|
* @param {string|null} cursor - Курсор для пагинации
|
|
388
401
|
* @param {string|null} tab - Тип ленты: "popular" (популярные), "following" (из подписок), null (обычная лента)
|
|
389
402
|
* @returns {Promise<Object>} { posts: [], pagination: {} }
|
|
@@ -413,6 +426,19 @@ export class ITDClient {
|
|
|
413
426
|
async getFeedFollowing(limit = 20, cursor = null) {
|
|
414
427
|
return await this.posts.getFeedFollowing(limit, cursor);
|
|
415
428
|
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Получает лайкнутые посты пользователя.
|
|
432
|
+
* GET /api/posts/user/{username}/liked → { posts: [], pagination: {} }
|
|
433
|
+
*
|
|
434
|
+
* @param {string} username - Имя пользователя
|
|
435
|
+
* @param {number} limit - Количество постов
|
|
436
|
+
* @param {string|null} cursor - Курсор для пагинации
|
|
437
|
+
* @returns {Promise<Object>} { posts: [], pagination: {} }
|
|
438
|
+
*/
|
|
439
|
+
async getLikedPosts(username, limit = 20, cursor = null) {
|
|
440
|
+
return await this.posts.getLikedPosts(username, limit, cursor);
|
|
441
|
+
}
|
|
416
442
|
|
|
417
443
|
/**
|
|
418
444
|
* Получает список постов (простой вариант - только массив)
|
|
@@ -435,6 +461,28 @@ export class ITDClient {
|
|
|
435
461
|
async getPost(postId) {
|
|
436
462
|
return await this.posts.getPost(postId);
|
|
437
463
|
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Отмечает пост как просмотренный. POST /api/posts/{id}/view
|
|
467
|
+
*
|
|
468
|
+
* @param {string} postId - ID поста
|
|
469
|
+
* @returns {Promise<boolean>} True если успешно
|
|
470
|
+
*/
|
|
471
|
+
async viewPost(postId) {
|
|
472
|
+
return await this.posts.viewPost(postId);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Получает посты на стене пользователя. GET /api/posts/user/{username}/wall
|
|
477
|
+
*
|
|
478
|
+
* @param {string} username - Имя пользователя
|
|
479
|
+
* @param {number} limit - Количество
|
|
480
|
+
* @param {string|null} cursor - Курсор пагинации
|
|
481
|
+
* @returns {Promise<Object>} { posts: [], pagination: {} }
|
|
482
|
+
*/
|
|
483
|
+
async getWallByUser(username, limit = 20, cursor = null) {
|
|
484
|
+
return await this.posts.getWallByUser(username, limit, cursor);
|
|
485
|
+
}
|
|
438
486
|
|
|
439
487
|
/**
|
|
440
488
|
* Удаляет пост (удобный метод)
|
|
@@ -445,16 +493,36 @@ export class ITDClient {
|
|
|
445
493
|
async deletePost(postId) {
|
|
446
494
|
return await this.posts.deletePost(postId);
|
|
447
495
|
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Восстанавливает удалённый пост. POST /api/posts/{id}/restore
|
|
499
|
+
*
|
|
500
|
+
* @param {string} postId - ID поста
|
|
501
|
+
* @returns {Promise<boolean>} True если успешно
|
|
502
|
+
*/
|
|
503
|
+
async restorePost(postId) {
|
|
504
|
+
return await this.posts.restorePost(postId);
|
|
505
|
+
}
|
|
448
506
|
|
|
449
507
|
/**
|
|
450
|
-
* Закрепляет
|
|
451
|
-
*
|
|
508
|
+
* Закрепляет пост. POST /api/posts/{id}/pin → { success: true, pinnedPostId }
|
|
509
|
+
*
|
|
452
510
|
* @param {string} postId - ID поста
|
|
453
511
|
* @returns {Promise<boolean>} True если успешно
|
|
454
512
|
*/
|
|
455
513
|
async pinPost(postId) {
|
|
456
514
|
return await this.posts.pinPost(postId);
|
|
457
515
|
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Открепляет пост. DELETE /api/posts/{id}/pin → { success: true, pinnedPostId: null }
|
|
519
|
+
*
|
|
520
|
+
* @param {string} postId - ID поста
|
|
521
|
+
* @returns {Promise<boolean>} True если успешно
|
|
522
|
+
*/
|
|
523
|
+
async unpinPost(postId) {
|
|
524
|
+
return await this.posts.unpinPost(postId);
|
|
525
|
+
}
|
|
458
526
|
|
|
459
527
|
/**
|
|
460
528
|
* Делает репост (удобный метод)
|
|
@@ -537,12 +605,25 @@ export class ITDClient {
|
|
|
537
605
|
* Добавляет комментарий к посту
|
|
538
606
|
*
|
|
539
607
|
* @param {string} postId - ID поста
|
|
540
|
-
* @param {string} text - Текст
|
|
608
|
+
* @param {string} text - Текст (пустая строка для голосового)
|
|
541
609
|
* @param {string|null} replyToCommentId - ID комментария для ответа (опционально)
|
|
610
|
+
* @param {string[]|null} attachmentIds - ID загруженных файлов (audio/ogg для голосовых)
|
|
542
611
|
* @returns {Promise<Object|null>} Данные комментария
|
|
543
612
|
*/
|
|
544
|
-
async addComment(postId, text, replyToCommentId = null) {
|
|
545
|
-
return await this.comments.addComment(postId, text, replyToCommentId);
|
|
613
|
+
async addComment(postId, text, replyToCommentId = null, attachmentIds = null) {
|
|
614
|
+
return await this.comments.addComment(postId, text, replyToCommentId, attachmentIds);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Добавляет голосовое сообщение в комментарий. Загружает audio/ogg и создаёт комментарий.
|
|
619
|
+
*
|
|
620
|
+
* @param {string} postId - ID поста
|
|
621
|
+
* @param {string} audioPath - Путь к аудиофайлу (audio/ogg)
|
|
622
|
+
* @param {string|null} replyToCommentId - ID комментария для ответа (опционально)
|
|
623
|
+
* @returns {Promise<Object|null>} Данные созданного комментария или null
|
|
624
|
+
*/
|
|
625
|
+
async addVoiceComment(postId, audioPath, replyToCommentId = null) {
|
|
626
|
+
return await this.comments.addVoiceComment(postId, audioPath, replyToCommentId);
|
|
546
627
|
}
|
|
547
628
|
|
|
548
629
|
/**
|
|
@@ -586,6 +667,16 @@ export class ITDClient {
|
|
|
586
667
|
async deleteComment(commentId) {
|
|
587
668
|
return await this.comments.deleteComment(commentId);
|
|
588
669
|
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Восстанавливает удалённый комментарий. POST /api/comments/{id}/restore
|
|
673
|
+
*
|
|
674
|
+
* @param {string} commentId - ID комментария
|
|
675
|
+
* @returns {Promise<boolean>} True если успешно
|
|
676
|
+
*/
|
|
677
|
+
async restoreComment(commentId) {
|
|
678
|
+
return await this.comments.restoreComment(commentId);
|
|
679
|
+
}
|
|
589
680
|
|
|
590
681
|
/**
|
|
591
682
|
* Получает комментарии к посту
|
|
@@ -600,14 +691,38 @@ export class ITDClient {
|
|
|
600
691
|
}
|
|
601
692
|
|
|
602
693
|
/**
|
|
603
|
-
* Обновляет
|
|
604
|
-
*
|
|
605
|
-
*
|
|
694
|
+
* Обновляет профиль текущего пользователя.
|
|
695
|
+
* PUT /api/users/me → { id, username, displayName, bio, updatedAt }
|
|
696
|
+
*
|
|
697
|
+
* @param {string|null} bio - Новое описание профиля (опционально)
|
|
606
698
|
* @param {string|null} displayName - Новое отображаемое имя (опционально)
|
|
699
|
+
* @param {string|null} username - Новый username (опционально)
|
|
700
|
+
* @param {string|null} bannerId - ID загруженного баннера (опционально)
|
|
607
701
|
* @returns {Promise<Object|null>} Обновленные данные профиля или null при ошибке
|
|
608
702
|
*/
|
|
609
|
-
async updateProfile(bio, displayName = null) {
|
|
610
|
-
return await this.users.updateProfile(bio, displayName);
|
|
703
|
+
async updateProfile(bio = null, displayName = null, username = null, bannerId = null) {
|
|
704
|
+
return await this.users.updateProfile(bio, displayName, username, bannerId);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Получает настройки приватности.
|
|
709
|
+
* GET /api/users/me/privacy → { isPrivate, wallClosed }
|
|
710
|
+
*
|
|
711
|
+
* @returns {Promise<Object|null>} { isPrivate, wallClosed } или null
|
|
712
|
+
*/
|
|
713
|
+
async getPrivacy() {
|
|
714
|
+
return await this.users.getPrivacy();
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Обновляет настройки приватности.
|
|
719
|
+
* PUT /api/users/me/privacy → { isPrivate, wallClosed }
|
|
720
|
+
*
|
|
721
|
+
* @param {Object} options - { isPrivate?: boolean, wallClosed?: boolean }
|
|
722
|
+
* @returns {Promise<Object|null>} { isPrivate, wallClosed } или null
|
|
723
|
+
*/
|
|
724
|
+
async updatePrivacy(options = {}) {
|
|
725
|
+
return await this.users.updatePrivacy(options);
|
|
611
726
|
}
|
|
612
727
|
|
|
613
728
|
/**
|
|
@@ -684,27 +799,39 @@ export class ITDClient {
|
|
|
684
799
|
}
|
|
685
800
|
|
|
686
801
|
/**
|
|
687
|
-
* Получает список
|
|
688
|
-
*
|
|
802
|
+
* Получает список уведомлений.
|
|
803
|
+
* GET /api/notifications/?offset=0&limit=20 → { notifications: [], hasMore }
|
|
804
|
+
*
|
|
689
805
|
* @param {number} limit - Количество уведомлений
|
|
690
|
-
* @param {
|
|
691
|
-
* @param {string|null} type - Фильтр по типу: 'reply', 'like', 'wall_post', 'follow', 'comment'
|
|
692
|
-
* @returns {Promise<Object|null>} { notifications: [],
|
|
806
|
+
* @param {number} offset - Смещение для пагинации
|
|
807
|
+
* @param {string|null} type - Фильтр по типу: 'reply', 'like', 'wall_post', 'follow', 'comment'
|
|
808
|
+
* @returns {Promise<Object|null>} { notifications: [], hasMore } или null
|
|
693
809
|
*/
|
|
694
|
-
async getNotifications(limit = 20,
|
|
695
|
-
return await this.notifications.getNotifications(limit,
|
|
810
|
+
async getNotifications(limit = 20, offset = 0, type = null) {
|
|
811
|
+
return await this.notifications.getNotifications(limit, offset, type);
|
|
696
812
|
}
|
|
697
|
-
|
|
813
|
+
|
|
698
814
|
/**
|
|
699
815
|
* Получает уведомления определенного типа
|
|
700
|
-
*
|
|
701
|
-
* @param {string} type -
|
|
702
|
-
* @param {number} limit - Количество
|
|
703
|
-
* @param {
|
|
704
|
-
* @returns {Promise<Object|null>} { notifications: [],
|
|
816
|
+
*
|
|
817
|
+
* @param {string} type - Тип: 'reply', 'like', 'wall_post', 'follow', 'comment'
|
|
818
|
+
* @param {number} limit - Количество
|
|
819
|
+
* @param {number} offset - Смещение
|
|
820
|
+
* @returns {Promise<Object|null>} { notifications: [], hasMore } или null
|
|
821
|
+
*/
|
|
822
|
+
async getNotificationsByType(type, limit = 20, offset = 0) {
|
|
823
|
+
return await this.notifications.getNotifications(limit, offset, type);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Отмечает несколько уведомлений как прочитанные.
|
|
828
|
+
* POST /api/notifications/read-batch → { success: true, count }
|
|
829
|
+
*
|
|
830
|
+
* @param {string[]} ids - Массив ID уведомлений
|
|
831
|
+
* @returns {Promise<Object|null>} { success: true, count } или null
|
|
705
832
|
*/
|
|
706
|
-
async
|
|
707
|
-
return await this.notifications.
|
|
833
|
+
async markNotificationsAsReadBatch(ids) {
|
|
834
|
+
return await this.notifications.markAsReadBatch(ids);
|
|
708
835
|
}
|
|
709
836
|
|
|
710
837
|
/**
|
|
@@ -784,6 +911,26 @@ export class ITDClient {
|
|
|
784
911
|
async uploadFile(filePath) {
|
|
785
912
|
return await this.files.uploadFile(filePath);
|
|
786
913
|
}
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Получает информацию о файле. GET /api/files/{id}
|
|
917
|
+
*
|
|
918
|
+
* @param {string} fileId - ID файла
|
|
919
|
+
* @returns {Promise<Object|null>} { id, url, filename, mimeType, size } или null
|
|
920
|
+
*/
|
|
921
|
+
async getFile(fileId) {
|
|
922
|
+
return await this.files.getFile(fileId);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Удаляет файл. DELETE /api/files/{id}
|
|
927
|
+
*
|
|
928
|
+
* @param {string} fileId - ID файла
|
|
929
|
+
* @returns {Promise<boolean>} True если успешно
|
|
930
|
+
*/
|
|
931
|
+
async deleteFile(fileId) {
|
|
932
|
+
return await this.files.deleteFile(fileId);
|
|
933
|
+
}
|
|
787
934
|
|
|
788
935
|
/**
|
|
789
936
|
* Отправляет репорт на пост, комментарий или пользователя
|
|
@@ -833,6 +980,43 @@ export class ITDClient {
|
|
|
833
980
|
async reportUser(userId, reason = 'other', description = '') {
|
|
834
981
|
return await this.reports.reportUser(userId, reason, description);
|
|
835
982
|
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Получает статус верификации. GET /api/verification/status
|
|
986
|
+
*
|
|
987
|
+
* @returns {Promise<Object|null>} Статус верификации или null
|
|
988
|
+
*/
|
|
989
|
+
async getVerificationStatus() {
|
|
990
|
+
return await this.verification.getStatus();
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* Подаёт заявку на верификацию. POST /api/verification/submit
|
|
995
|
+
*
|
|
996
|
+
* @param {string} videoUrl - URL загруженного видео (из uploadFile)
|
|
997
|
+
* @returns {Promise<Object|null>} { success, request } или null
|
|
998
|
+
*/
|
|
999
|
+
async submitVerification(videoUrl) {
|
|
1000
|
+
return await this.verification.submit(videoUrl);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/**
|
|
1004
|
+
* Получает статус платформы. GET /api/platform/status
|
|
1005
|
+
*
|
|
1006
|
+
* @returns {Promise<Object|null>} Статус платформы или null
|
|
1007
|
+
*/
|
|
1008
|
+
async getPlatformStatus() {
|
|
1009
|
+
try {
|
|
1010
|
+
const response = await this.axios.get('/api/platform/status');
|
|
1011
|
+
if (response.status === 200) {
|
|
1012
|
+
return response.data?.data ?? response.data;
|
|
1013
|
+
}
|
|
1014
|
+
return null;
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
console.error('Ошибка получения статуса платформы:', error.message);
|
|
1017
|
+
return null;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
836
1020
|
|
|
837
1021
|
/**
|
|
838
1022
|
* Выполняет поиск пользователей и хэштегов
|
|
@@ -843,7 +1027,7 @@ export class ITDClient {
|
|
|
843
1027
|
* @returns {Promise<Object|null>} { users: [], hashtags: [] } или null при ошибке
|
|
844
1028
|
*/
|
|
845
1029
|
async search(query, userLimit = 5, hashtagLimit = 5) {
|
|
846
|
-
return await this.
|
|
1030
|
+
return await this.searchManager.search(query, userLimit, hashtagLimit);
|
|
847
1031
|
}
|
|
848
1032
|
|
|
849
1033
|
/**
|
|
@@ -854,7 +1038,7 @@ export class ITDClient {
|
|
|
854
1038
|
* @returns {Promise<Array|null>} Массив пользователей или null при ошибке
|
|
855
1039
|
*/
|
|
856
1040
|
async searchUsers(query, limit = 5) {
|
|
857
|
-
return await this.
|
|
1041
|
+
return await this.searchManager.searchUsers(query, limit);
|
|
858
1042
|
}
|
|
859
1043
|
|
|
860
1044
|
/**
|
|
@@ -865,7 +1049,7 @@ export class ITDClient {
|
|
|
865
1049
|
* @returns {Promise<Array|null>} Массив хэштегов или null при ошибке
|
|
866
1050
|
*/
|
|
867
1051
|
async searchHashtags(query, limit = 5) {
|
|
868
|
-
return await this.
|
|
1052
|
+
return await this.searchManager.searchHashtags(query, limit);
|
|
869
1053
|
}
|
|
870
1054
|
|
|
871
1055
|
// ========== USER-FRIENDLY МЕТОДЫ ==========
|
|
@@ -995,16 +1179,6 @@ export class ITDClient {
|
|
|
995
1179
|
return await this.users.getMyClan();
|
|
996
1180
|
}
|
|
997
1181
|
|
|
998
|
-
/**
|
|
999
|
-
* Получает клан пользователя (эмодзи аватара) (удобный метод)
|
|
1000
|
-
*
|
|
1001
|
-
* @param {string} username - Имя пользователя
|
|
1002
|
-
* @returns {Promise<string|null>} Эмодзи клана или null
|
|
1003
|
-
*/
|
|
1004
|
-
async getUserClan(username) {
|
|
1005
|
-
return await this.users.getUserClan(username);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
1182
|
// === Комментарии ===
|
|
1009
1183
|
|
|
1010
1184
|
/**
|
|
@@ -1040,12 +1214,12 @@ export class ITDClient {
|
|
|
1040
1214
|
|
|
1041
1215
|
/**
|
|
1042
1216
|
* Получает только непрочитанные уведомления (удобный метод)
|
|
1043
|
-
*
|
|
1044
|
-
* @param {number} limit - Количество
|
|
1045
|
-
* @param {
|
|
1046
|
-
* @returns {Promise<Object|null>} { notifications: [],
|
|
1217
|
+
*
|
|
1218
|
+
* @param {number} limit - Количество
|
|
1219
|
+
* @param {number} offset - Смещение
|
|
1220
|
+
* @returns {Promise<Object|null>} { notifications: [], hasMore } или null
|
|
1047
1221
|
*/
|
|
1048
|
-
async getUnreadNotifications(limit = 20,
|
|
1049
|
-
return await this.notifications.getUnreadNotifications(limit,
|
|
1222
|
+
async getUnreadNotifications(limit = 20, offset = 0) {
|
|
1223
|
+
return await this.notifications.getUnreadNotifications(limit, offset);
|
|
1050
1224
|
}
|
|
1051
1225
|
}
|
package/src/comments.js
CHANGED
|
@@ -13,30 +13,28 @@ export class CommentsManager {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Добавляет комментарий к
|
|
17
|
-
*
|
|
16
|
+
* Добавляет комментарий к посту.
|
|
17
|
+
* POST /api/posts/{postId}/comments → { id, content, author, attachments, ... }
|
|
18
|
+
* Поддерживает текст, голосовые (attachmentIds с audio/ogg) и ответы (replyTo).
|
|
19
|
+
*
|
|
18
20
|
* @param {string} postId - ID поста
|
|
19
|
-
* @param {string} text - Текст комментария
|
|
21
|
+
* @param {string} text - Текст комментария (пустая строка для голосового)
|
|
20
22
|
* @param {string|null} replyToCommentId - ID комментария для ответа (опционально)
|
|
23
|
+
* @param {string[]|null} attachmentIds - ID загруженных файлов (audio/ogg для голосовых)
|
|
21
24
|
* @returns {Promise<Object|null>} Данные созданного комментария или null
|
|
22
25
|
*/
|
|
23
|
-
async addComment(postId, text, replyToCommentId = null) {
|
|
26
|
+
async addComment(postId, text, replyToCommentId = null, attachmentIds = null) {
|
|
24
27
|
if (!await this.client.auth.checkAuth()) {
|
|
25
28
|
console.error('Ошибка: необходимо войти в аккаунт');
|
|
26
29
|
return null;
|
|
27
30
|
}
|
|
28
|
-
|
|
29
31
|
try {
|
|
30
32
|
const commentUrl = `${this.client.baseUrl}/api/posts/${postId}/comments`;
|
|
31
|
-
const commentData = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// Если это ответ на комментарий
|
|
36
|
-
if (replyToCommentId) {
|
|
37
|
-
commentData.replyTo = replyToCommentId;
|
|
33
|
+
const commentData = { content: text ?? '' };
|
|
34
|
+
if (replyToCommentId) commentData.replyTo = replyToCommentId;
|
|
35
|
+
if (Array.isArray(attachmentIds) && attachmentIds.length > 0) {
|
|
36
|
+
commentData.attachmentIds = attachmentIds;
|
|
38
37
|
}
|
|
39
|
-
|
|
40
38
|
const response = await this.axios.post(commentUrl, commentData);
|
|
41
39
|
|
|
42
40
|
if (response.status === 200 || response.status === 201) {
|
|
@@ -55,6 +53,25 @@ export class CommentsManager {
|
|
|
55
53
|
}
|
|
56
54
|
}
|
|
57
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Добавляет голосовое сообщение в комментарий.
|
|
58
|
+
* Загружает audio/ogg через /api/files/upload и создаёт комментарий с attachmentIds.
|
|
59
|
+
*
|
|
60
|
+
* @param {string} postId - ID поста
|
|
61
|
+
* @param {string} audioPath - Путь к аудиофайлу (audio/ogg)
|
|
62
|
+
* @param {string|null} replyToCommentId - ID комментария для ответа (опционально)
|
|
63
|
+
* @returns {Promise<Object|null>} Данные созданного комментария или null
|
|
64
|
+
*/
|
|
65
|
+
async addVoiceComment(postId, audioPath, replyToCommentId = null) {
|
|
66
|
+
if (!await this.client.auth.checkAuth()) {
|
|
67
|
+
console.error('Ошибка: необходимо войти в аккаунт');
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const uploaded = await this.client.files.uploadFile(audioPath);
|
|
71
|
+
if (!uploaded) return null;
|
|
72
|
+
return await this.addComment(postId, '', replyToCommentId, [uploaded.id]);
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
/**
|
|
59
76
|
* Ответ на комментарий (отдельный эндпоинт /api/comments/:id/replies).
|
|
60
77
|
*
|
|
@@ -257,6 +274,24 @@ export class CommentsManager {
|
|
|
257
274
|
return false;
|
|
258
275
|
}
|
|
259
276
|
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Восстанавливает удалённый комментарий. POST /api/comments/{id}/restore
|
|
280
|
+
*
|
|
281
|
+
* @param {string} commentId - ID комментария
|
|
282
|
+
* @returns {Promise<boolean>} True если успешно
|
|
283
|
+
*/
|
|
284
|
+
async restoreComment(commentId) {
|
|
285
|
+
if (!await this.client.auth.checkAuth()) return false;
|
|
286
|
+
try {
|
|
287
|
+
const url = `${this.client.baseUrl}/api/comments/${commentId}/restore`;
|
|
288
|
+
const response = await this.axios.post(url);
|
|
289
|
+
return response.status === 200 || response.status === 201 || response.status === 204;
|
|
290
|
+
} catch (error) {
|
|
291
|
+
console.error('Исключение при восстановлении комментария:', error.message);
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
260
295
|
|
|
261
296
|
// ========== USER-FRIENDLY МЕТОДЫ ==========
|
|
262
297
|
|
package/src/files.js
CHANGED
|
@@ -11,7 +11,8 @@ export class FilesManager {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Загружает файл
|
|
14
|
+
* Загружает файл на сервер. POST /api/files/upload.
|
|
15
|
+
* Поддерживает изображения и аудио (audio/ogg для голосовых в комментариях).
|
|
15
16
|
* Таймаут — client.uploadTimeout (по умолчанию 120 с). При ошибке возвращает null.
|
|
16
17
|
*
|
|
17
18
|
* @param {string} filePath - Путь к файлу
|
|
@@ -58,4 +59,43 @@ export class FilesManager {
|
|
|
58
59
|
return null;
|
|
59
60
|
}
|
|
60
61
|
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Получает информацию о файле. GET /api/files/{id}
|
|
65
|
+
*
|
|
66
|
+
* @param {string} fileId - ID файла
|
|
67
|
+
* @returns {Promise<Object|null>} { id, url, filename, mimeType, size, ... } или null
|
|
68
|
+
*/
|
|
69
|
+
async getFile(fileId) {
|
|
70
|
+
if (!await this.client.auth.checkAuth()) return null;
|
|
71
|
+
try {
|
|
72
|
+
const url = `${this.client.baseUrl}/api/files/${fileId}`;
|
|
73
|
+
const response = await this.axios.get(url);
|
|
74
|
+
if (response.status === 200) {
|
|
75
|
+
return response.data?.data ?? response.data;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error('Ошибка получения файла:', error.message);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Удаляет файл. DELETE /api/files/{id}
|
|
86
|
+
*
|
|
87
|
+
* @param {string} fileId - ID файла
|
|
88
|
+
* @returns {Promise<boolean>} True если успешно
|
|
89
|
+
*/
|
|
90
|
+
async deleteFile(fileId) {
|
|
91
|
+
if (!await this.client.auth.checkAuth()) return false;
|
|
92
|
+
try {
|
|
93
|
+
const url = `${this.client.baseUrl}/api/files/${fileId}`;
|
|
94
|
+
const response = await this.axios.delete(url);
|
|
95
|
+
return response.status === 200 || response.status === 204;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error('Ошибка удаления файла:', error.message);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
61
101
|
}
|