itd-api 0.3.0 → 0.4.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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as createTokenStorage, n as MemoryTokenStorage, r as TokenStorage, t as ItdSession } from "./storage-BjNRlkbE.cjs";
2
- import { _ as StreamFile, a as createRecordMultiStorage, b as fromStream, c as DEFAULT_URL_FILE_MAX_BYTES, d as FileInput, f as FileStreamContent, g as LazyFile, h as FromStreamOptions, i as createMultiTokenStorage, l as FileContent, m as FileTransferMode, n as MultiTokenStorage, o as scopedTokenStorage, p as FileStreamOptions, r as RecordStorageSource, s as DEFAULT_FILE_STREAM_BUFFER_BYTES, t as MemoryMultiTokenStorage, u as FileContext, v as UrlFile, x as fromUrl, y as UrlFileOptions } from "./multi-storage-NDqzRQcD.cjs";
2
+ import { _ as StreamFile, a as createRecordMultiStorage, c as DEFAULT_URL_FILE_MAX_BYTES, d as FileInput, f as FileStreamContent, g as LazyFile, h as FromStreamOptions, i as createMultiTokenStorage, l as FileContent, m as FileTransferMode, n as MultiTokenStorage, o as scopedTokenStorage, p as FileStreamOptions, r as RecordStorageSource, s as DEFAULT_FILE_STREAM_BUFFER_BYTES, t as MemoryMultiTokenStorage, u as FileContext, v as UrlFile, y as UrlFileOptions } from "./multi-storage-DP_ujJw1.cjs";
3
3
  //#region src/types/enums.d.ts
4
4
  /**
5
5
  * Перечисления API итд.com.
@@ -326,12 +326,12 @@ declare const ItdErrorCode: Readonly<{
326
326
  }>;
327
327
  type ItdErrorCode = Loose<(typeof ItdErrorCode)[keyof typeof ItdErrorCode]>;
328
328
  //#endregion
329
- //#region src/types/models.d.ts
329
+ //#region src/models/common.d.ts
330
330
  /**
331
331
  * Дата и время в формате ISO-8601, например `2026-07-21T14:30:00.000Z`.
332
332
  *
333
333
  * Библиотека не превращает такие поля в `Date`: строку проще сравнивать, логировать
334
- * и передавать дальше без потерь. Для разбора есть {@link toDate}.
334
+ * и передавать дальше без потерь. Для разбора есть `toDate()`.
335
335
  */
336
336
  type IsoDate = string;
337
337
  /**
@@ -371,579 +371,6 @@ interface Span {
371
371
  /** Идентификатор пользователя у некоторых ответов API с `mention`. */
372
372
  id?: string;
373
373
  }
374
- /**
375
- * Значок-«пин» в профиле — награда или отметка платформы.
376
- */
377
- interface Pin {
378
- /** Постоянный идентификатор, например `epepuy_202605_59`. */
379
- slug: string;
380
- /** Отображаемое название. */
381
- name: string;
382
- /** Описание, за что выдан. */
383
- description: string;
384
- /** Адрес изображения. */
385
- url: string;
386
- /** Когда выдан. Приходит только в списке своих пинов. */
387
- grantedAt?: IsoDate;
388
- }
389
- /**
390
- * Автор поста или комментария.
391
- *
392
- * Встречается внутри `post.author` и `comment.author`.
393
- */
394
- interface Author {
395
- id: UserId;
396
- username: string;
397
- displayName: string;
398
- /**
399
- * **Эмодзи, а не картинка.**
400
- *
401
- * На итд.com аватар — это символ клана (`🩵`, `🦎`), а не адрес изображения.
402
- * Отрисовывать его нужно как текст.
403
- */
404
- avatar: string;
405
- /** Пройдена ли верификация. */
406
- verified: boolean;
407
- /** Активный значок профиля. Может отсутствовать. */
408
- pin?: Pin | null;
409
- /** Есть ли премиум-подписка (значок NUKSTA). */
410
- hasNuksta?: boolean;
411
- }
412
- /**
413
- * Участник события в уведомлении.
414
- *
415
- * Отличается от {@link Author} набором полей: вместо значков приходит связь с вами.
416
- */
417
- interface Actor {
418
- id: UserId;
419
- username: string;
420
- displayName: string;
421
- /** Эмодзи-аватар, см. {@link Author.avatar}. */
422
- avatar: string;
423
- /** Подписаны ли вы на этого пользователя. */
424
- isFollowing?: boolean;
425
- /** Подписан ли он на вас. */
426
- isFollowedBy?: boolean;
427
- }
428
- /**
429
- * Пользователь в списках.
430
- *
431
- * Набор полей зависит от эндпоинта: подписчики и подписки приносят `isFollowing`,
432
- * поиск и рекомендации — `followersCount` и `hasNuksta`. Необязательные поля отражают
433
- * это различие.
434
- */
435
- interface UserSummary {
436
- id: UserId;
437
- username: string;
438
- displayName: string;
439
- /** Эмодзи-аватар, см. {@link Author.avatar}. */
440
- avatar: string;
441
- verified: boolean;
442
- /** Подписаны ли вы. Приходит в списках подписчиков и подписок. */
443
- isFollowing?: boolean;
444
- /** Есть ли премиум. Приходит в поиске и рекомендациях. */
445
- hasNuksta?: boolean;
446
- /** Число подписчиков. Приходит в поиске и рекомендациях. */
447
- followersCount?: number;
448
- }
449
- /** Поля профиля, общие для своего и чужого. */
450
- interface ProfileBase {
451
- id: UserId;
452
- username: string;
453
- displayName: string;
454
- /** Эмодзи-аватар, см. {@link Author.avatar}. */
455
- avatar: string;
456
- /** URL изображения баннера либо `null`. */
457
- banner: string | null;
458
- /** Описание профиля. */
459
- bio: string;
460
- verified: boolean;
461
- pin?: Pin | null;
462
- /** Кто может писать на стену. */
463
- wallAccess: WallAccess;
464
- /** Кто видит реакции. */
465
- likesVisibility: LikesVisibility;
466
- followersCount: number;
467
- followingCount: number;
468
- postsCount: number;
469
- createdAt: IsoDate;
470
- }
471
- /** Состояние подписки на премиум. */
472
- interface SubscriptionState {
473
- isActive: boolean;
474
- expiresAt: IsoDate | null;
475
- autoRenewal: boolean;
476
- }
477
- /**
478
- * Свой профиль — ответ `GET /api/users/me`.
479
- *
480
- * Отличается от чужого наличием {@link subscription} и {@link isPhoneVerified}
481
- * и отсутствием полей связи (`isFollowing`, `online`).
482
- */
483
- interface MyProfile extends ProfileBase {
484
- /** Закрыт ли профиль. */
485
- isPrivate: boolean;
486
- /** Подтверждён ли телефон. Без него часть действий недоступна. */
487
- isPhoneVerified: boolean;
488
- /** Своя премиум-подписка. */
489
- subscription: SubscriptionState;
490
- }
491
- /**
492
- * Состояние авторизации — ответ `GET /api/profile`.
493
- *
494
- * Endpoint доступен без сессии: в этом случае `authenticated` равен `false`,
495
- * а `user` — `null`.
496
- */
497
- interface AuthState {
498
- /** Есть ли действующая сессия. */
499
- authenticated: boolean;
500
- /** Заблокирован ли текущий аккаунт. */
501
- banned: boolean;
502
- /** Текущий пользователь либо `null` без действующей сессии. */
503
- user: MyProfile | null;
504
- }
505
- /**
506
- * Чужой профиль — ответ `GET /api/users/{id|username}`.
507
- *
508
- * Вместо своей подписки содержит связь с вами и присутствие.
509
- */
510
- interface PublicProfile extends ProfileBase {
511
- hasNuksta?: boolean;
512
- /** Закреплённый пост, если он есть. */
513
- pinnedPostId: string | null;
514
- /** Подписаны ли вы на него. */
515
- isFollowing: boolean;
516
- /** Подписан ли он на вас. */
517
- isFollowedBy: boolean;
518
- /** Сейчас ли пользователь в сети. */
519
- online: boolean;
520
- /** Когда был в сети. `null`, если скрыто настройками приватности. */
521
- lastSeen: IsoDate | null;
522
- }
523
- /** Профиль: свой либо чужой. Различаются функцией {@link isMyProfile}. */
524
- type Profile = MyProfile | PublicProfile;
525
- /**
526
- * Свой ли это профиль.
527
- *
528
- * @example
529
- * ```ts
530
- * if (isMyProfile(profile)) console.log(profile.subscription.isActive);
531
- * ```
532
- */
533
- declare function isMyProfile(profile: Profile): profile is MyProfile;
534
- /** Вложение поста или комментария. */
535
- interface Attachment {
536
- id: string;
537
- type: AttachmentType;
538
- /** Адрес файла на CDN. */
539
- url: string;
540
- /** Ширина изображения или видео в пикселях. */
541
- width?: number;
542
- /** Высота изображения или видео в пикселях. */
543
- height?: number;
544
- mimeType: string;
545
- /** Исходное имя файла. Приходит не всегда. */
546
- filename?: string;
547
- /** Размер в байтах. Приходит не всегда. */
548
- size?: number;
549
- /** Длительность аудио или видео в секундах. */
550
- duration?: number | null;
551
- /** Порядковый номер во вложениях поста. */
552
- order?: number;
553
- }
554
- /** Вариант ответа в опросе. */
555
- interface PollOption {
556
- id: string;
557
- text: string;
558
- /** Сколько голосов отдано за этот вариант. */
559
- votesCount: number;
560
- /** Порядковый номер варианта, начиная с нуля. */
561
- position: number;
562
- }
563
- /** Опрос внутри поста. */
564
- interface Poll {
565
- id: string;
566
- /** Пост, которому принадлежит опрос. */
567
- postId: string;
568
- question: string;
569
- /** Можно ли выбрать несколько вариантов. */
570
- multipleChoice: boolean;
571
- options: PollOption[];
572
- totalVotes: number;
573
- /** Голосовали ли вы. */
574
- hasVoted: boolean;
575
- /** За что проголосовали вы. Пустой массив, если голоса не было. */
576
- votedOptionIds: string[];
577
- createdAt: IsoDate;
578
- }
579
- /** Пост ленты, стены или профиля. */
580
- interface Post {
581
- id: string;
582
- content: string;
583
- /** Разметка текста. Передаётся без изменений, см. {@link Span}. */
584
- spans: Span[];
585
- author: Author;
586
- attachments: Attachment[];
587
- likesCount: number;
588
- commentsCount: number;
589
- repostsCount: number;
590
- viewsCount: number;
591
- /** Чья это стена, если пост опубликован не у себя. */
592
- wallRecipientId: UserId | null;
593
- /** Владелец стены. Приходит не во всех ответах. */
594
- wallRecipient?: Author | null;
595
- /** Поставили ли вы реакцию. */
596
- isLiked: boolean;
597
- /** Делали ли вы репост. */
598
- isReposted: boolean;
599
- /** Засчитан ли просмотр. */
600
- isViewed: boolean;
601
- /** Ваш ли это пост. */
602
- isOwner: boolean;
603
- /** Исходный пост, если это репост. */
604
- originalPost?: Post | null;
605
- poll?: Poll | null;
606
- /** Преобладающая реакция — эмодзи либо `null`. */
607
- dominantEmoji?: string | null;
608
- /** Когда пост отредактировали. `null`, если не редактировали. */
609
- editedAt: IsoDate | null;
610
- createdAt: IsoDate;
611
- /**
612
- * Служебная метка показа для телеметрии.
613
- *
614
- * Нужна только эндпоинтам `itd.telemetry.*`. В остальных случаях игнорируйте.
615
- */
616
- vs?: string;
617
- /**
618
- * Топовые комментарии. Приходят только в ответе `GET /api/posts/{id}`.
619
- *
620
- * В списках постов поле отсутствует.
621
- */
622
- comments?: Comment[];
623
- }
624
- /** На чей комментарий дан ответ. */
625
- interface CommentReplyTo {
626
- id: string;
627
- username: string;
628
- displayName: string;
629
- }
630
- /** Комментарий к посту или ответ на комментарий. */
631
- interface Comment {
632
- id: string;
633
- /** Текст. У голосового комментария пустой. */
634
- content: string;
635
- /**
636
- * Разметка текста, включая автоматически найденные сервером хэштеги и упоминания.
637
- *
638
- * Методы создания и редактирования комментария принимают только `content`, поэтому
639
- * библиотека не отправляет ручные spans в этих операциях.
640
- * Поле необязательно: отдельные ответы сервера могут его не содержать.
641
- */
642
- spans?: Span[];
643
- author: Author;
644
- likesCount: number;
645
- repliesCount: number;
646
- isLiked: boolean;
647
- createdAt: IsoDate;
648
- /** Вложения. У голосового — одно аудио с `mimeType: 'audio/ogg'`. */
649
- attachments?: Attachment[];
650
- /** Вложенные ответы. В списках приходит превью, полный список — через `itd.comments.replies()`. */
651
- replies?: Comment[];
652
- /** Заполнено только у ответов. */
653
- replyTo?: CommentReplyTo;
654
- }
655
- /**
656
- * Уведомление в единой форме.
657
- *
658
- * REST-список и SSE-поток отдают уведомления по-разному — разные имена типов, разные имена
659
- * полей, один участник против массива. Библиотека приводит оба вида к этой структуре,
660
- * поэтому объекты из `itd.notifications.list()` и из потока можно складывать в один список.
661
- *
662
- * Исходные данные не теряются: сервeрное имя типа остаётся в {@link rawType},
663
- * а весь необработанный объект — в {@link raw}.
664
- */
665
- interface Notification {
666
- id: string;
667
- /** Канонический тип. Старые имена (`like`, `comment`) приведены к новым. */
668
- type: NotificationType;
669
- /** Имя типа в том виде, в каком его прислал сервер. */
670
- rawType: string;
671
- /** Объект события: пост, комментарий, пользователь. */
672
- entityId: string | null;
673
- /** Пост, которому принадлежит комментарий, если событие о комментарии. */
674
- parentEntityId: string | null;
675
- /** Прочитано ли уведомление. */
676
- isRead: boolean;
677
- /** Кто совершил действие. Для схлопнутых уведомлений — несколько человек. */
678
- actors: Actor[];
679
- /** Сколько участников схлопнуто в одно уведомление. Минимум 1. */
680
- count: number;
681
- /** Текст или заголовок объекта события. */
682
- preview: string | null;
683
- /** Ссылка перехода, предложенная сервером. Обычно точнее её `resolveNotificationUrl()`. */
684
- clickUrl?: string;
685
- createdAt: IsoDate;
686
- /** Когда уведомление изменилось — например было прочитано. */
687
- updatedAt: IsoDate;
688
- /** Исходный объект как он пришёл от сервера. */
689
- raw: unknown;
690
- }
691
- /** Настройки приватности профиля. */
692
- interface PrivacySettings {
693
- /** Закрыт ли профиль: подписка требует одобрения. */
694
- isPrivate: boolean;
695
- wallAccess: WallAccess;
696
- likesVisibility: LikesVisibility;
697
- /** Показывать ли время последнего посещения. */
698
- showLastSeen: boolean;
699
- }
700
- /**
701
- * Настройки уведомлений.
702
- *
703
- * Сервер отдаёт плоский объект, но исторически знает два набора имён для одних и тех же
704
- * настроек (`likes` и `reactions`, `comments` и `replies`). При сохранении библиотека
705
- * отправляет оба, при чтении принимает любой.
706
- */
707
- interface NotificationSettings {
708
- /** Общий выключатель доставки. */
709
- enabled: boolean;
710
- /** Звук уведомления. */
711
- sound: boolean;
712
- /** Новые подписчики. */
713
- follows: boolean;
714
- /** Записи на вашей стене. */
715
- wallPosts: boolean;
716
- /** Реакции на ваши записи. */
717
- likes: boolean;
718
- /** Комментарии и ответы. */
719
- comments: boolean;
720
- /** Упоминания. */
721
- mentions: boolean;
722
- }
723
- /** Активная сессия входа. */
724
- interface Session {
725
- id: string;
726
- /** Та ли это сессия, из которой выполнен запрос. */
727
- isCurrent: boolean;
728
- createdAt: IsoDate;
729
- lastUsedAt: IsoDate;
730
- expiresAt: IsoDate;
731
- ipAddress: string;
732
- /** Код страны по IP, например `RU`. */
733
- ipCountry: string | null;
734
- ipCity: string | null;
735
- deviceType: Loose<'desktop' | 'mobile'>;
736
- osName: string | null;
737
- osVersion: string | null;
738
- /** Название браузера или приложения. */
739
- clientName: string | null;
740
- clientVersion: string | null;
741
- deviceModel: string | null;
742
- }
743
- /** Состояние платной подписки и её цена. */
744
- interface Subscription {
745
- /** Активна ли подписка сейчас. */
746
- active: boolean;
747
- /** Включено ли автопродление. */
748
- recurringEnabled: boolean;
749
- /** Цена в рублях. */
750
- price: number;
751
- }
752
- /** Сохранённый способ оплаты. */
753
- interface PaymentMethod {
754
- id: string;
755
- /** Последние четыре цифры карты. */
756
- last4?: string;
757
- /** Платёжная система: `visa`, `mastercard`, `mir`. */
758
- brand?: string;
759
- /** Основной ли это способ оплаты. */
760
- isDefault?: boolean;
761
- expiresAt?: IsoDate | null;
762
- }
763
- /** Хэштег. */
764
- interface Hashtag {
765
- id: string;
766
- /** Название без решётки. */
767
- name: string;
768
- /** Сколько постов с этим хэштегом. */
769
- postsCount: number;
770
- }
771
- /** Клан в рейтинге. */
772
- interface Clan {
773
- /** Эмодзи клана — оно же аватар его участников. */
774
- avatar: string;
775
- memberCount: number;
776
- }
777
- /**
778
- * Результат подписки на пользователя.
779
- *
780
- * @example
781
- * ```ts
782
- * const result = await itd.users.follow('nowkie');
783
- * // { following: true, followersCount: 11 }
784
- * ```
785
- */
786
- interface FollowResult {
787
- /** Подписка оформлена. У закрытого профиля отправляется заявка, и здесь будет `false`. */
788
- following: boolean;
789
- /** Сколько подписчиков стало у пользователя после действия. */
790
- followersCount?: number;
791
- /** Статус заявки, если профиль закрыт. */
792
- status?: Loose<'following' | 'requested'>;
793
- }
794
- /** Запись журнала изменений платформы. */
795
- interface ChangelogEntry {
796
- version: string;
797
- date: string;
798
- changes: string[];
799
- }
800
- /** Кнопка в анонсе платформы. */
801
- interface AnnouncementButton {
802
- title: string;
803
- /** Оформление: `primary`, `secondary` и другие. */
804
- style: string;
805
- action: {
806
- type: string;
807
- [key: string]: unknown;
808
- };
809
- }
810
- /** Анонс на главной странице платформы. */
811
- interface Announcement {
812
- id: string;
813
- image: {
814
- url: string;
815
- width: number;
816
- height: number;
817
- };
818
- title: string;
819
- description: string;
820
- /** Дополнительный текст мелким шрифтом. */
821
- additional_text?: string;
822
- buttons: AnnouncementButton[];
823
- }
824
- /** Баннер текущего события — виджет «портал». */
825
- interface Portal {
826
- active: boolean;
827
- title: string;
828
- url: string;
829
- }
830
- /** Происшествие в истории сервиса. */
831
- interface StatusIncidentLine {
832
- /** Вид происшествия. */
833
- t: IncidentKind;
834
- /**
835
- * Готовая строка для показа: `недоступен 6 мин (12:00–12:06)`. Время московское.
836
- * Длительность и границы интервала отдельными полями не приходят.
837
- */
838
- text: string;
839
- }
840
- /** Одни сутки в истории сервиса. */
841
- interface StatusDay {
842
- /** Худшее состояние за сутки. */
843
- type: ServiceState;
844
- /** Дата суток, `YYYY-MM-DD`. Сутки нарезаны по UTC. */
845
- date_key: string;
846
- /** Доступность за сутки в процентах. */
847
- uptime: number;
848
- /** Происшествия за сутки. */
849
- lines: StatusIncidentLine[];
850
- }
851
- /** Сервис платформы и его история доступности. */
852
- interface ServiceStatus {
853
- /** Идентификатор: `auth`, `main`, `media` и прочие. */
854
- id: string;
855
- /** Отображаемое название. */
856
- name: string;
857
- current_status: ServiceState;
858
- /** Пояснение к текущему состоянию, например `No downtime`. */
859
- current_message: string;
860
- /** Задержка последней проверки в миллисекундах. */
861
- latency_ms: number;
862
- /**
863
- * Момент последней проверки. Сервер отдаёт `YYYY-MM-DD HH:mm:ss` в UTC, библиотека
864
- * приводит значение к ISO.
865
- */
866
- last_checked: IsoDate;
867
- /** Доступность за 90 суток в процентах. */
868
- uptime_90d: number;
869
- /**
870
- * История по суткам. Ключ — сколько суток назад, `'0'` — сегодня.
871
- *
872
- * Объект разреженный: сутки без данных сервер пропускает. Ровный массив даёт
873
- * {@link statusDays}.
874
- */
875
- days: Record<string, StatusDay | undefined>;
876
- }
877
- /** Состояние платформы — ответ `itd.platform.status()`. */
878
- interface PlatformStatus {
879
- /** Худшее состояние среди сервисов. */
880
- overall_status: ServiceState;
881
- /** Когда данные последний раз пересчитаны. */
882
- updated_at: IsoDate;
883
- services: ServiceStatus[];
884
- }
885
- /** Статус заявки на верификацию. `none` означает, что заявка не подавалась. */
886
- interface VerificationStatus {
887
- status: Loose<'none' | 'pending' | 'approved' | 'rejected'>;
888
- }
889
- /** Созданная жалоба. */
890
- interface Report {
891
- id: string;
892
- createdAt: IsoDate;
893
- }
894
- /** Счётчики поста из `itd.posts.stats()`. */
895
- interface PostStats {
896
- id: string;
897
- likesCount: number;
898
- commentsCount: number;
899
- repostsCount: number;
900
- viewsCount: number;
901
- /** Преобладающая реакция — эмодзи либо `null`. */
902
- dominantEmoji: string | null;
903
- }
904
- /** Результат реакции на пост. */
905
- interface LikeResult {
906
- liked: boolean;
907
- likesCount: number;
908
- }
909
- /** Результат закрепления поста в профиле. */
910
- interface PinPostResult {
911
- success: boolean;
912
- pinnedPostId: string | null;
913
- }
914
- /** Закреплённые значки профиля и выбранный из них. */
915
- interface PinsResult {
916
- pins: Pin[];
917
- /** Идентификатор активного значка — строка, а не объект. */
918
- activePin: string | null;
919
- }
920
- /**
921
- * Разбирает дату API в объект `Date`.
922
- *
923
- * @returns `null`, если строки нет или она не разбирается
924
- *
925
- * @example
926
- * ```ts
927
- * const created = toDate(post.createdAt);
928
- * ```
929
- */
930
- declare function toDate(value: IsoDate | null | undefined): Date | null;
931
- /**
932
- * Разворачивает историю сервиса в массив на 90 суток.
933
- * Сутки без данных становятся `null`.
934
- *
935
- * @returns массив, где индекс — сколько суток назад: `[0]` — сегодня
936
- *
937
- * @example
938
- * ```ts
939
- * const status = await itd.platform.status();
940
- * const days = statusDays(status.services[0]);
941
- *
942
- * days[0]?.uptime; // доступность за сегодня
943
- * days.filter((day) => day === null).length; // за сколько суток данных нет
944
- * ```
945
- */
946
- declare function statusDays(service: ServiceStatus): (StatusDay | null)[];
947
374
  //#endregion
948
375
  //#region src/core/clock.d.ts
949
376
  /**
@@ -1344,7 +771,7 @@ interface RawRequestOptions extends RequestOptions {
1344
771
  //#endregion
1345
772
  //#region src/core/version.d.ts
1346
773
  /** Версия библиотеки. Попадает в `User-Agent`. */
1347
- declare const LIBRARY_VERSION = "0.3.0";
774
+ declare const LIBRARY_VERSION = "0.4.0";
1348
775
  //#endregion
1349
776
  //#region src/core/config.d.ts
1350
777
  /** Базовый URL API итд.com. Домен записан в punycode: `итд.com`. */
@@ -1367,7 +794,7 @@ declare const DEFAULT_TIMEOUT = 30000;
1367
794
  * В браузере заголовок не выставляется — `User-Agent` там запрещён к изменению, и среда
1368
795
  * молча его игнорирует.
1369
796
  */
1370
- declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; itd-api/0.3.0; +https://github.com/KiowDev/itd-api)";
797
+ declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; itd-api/0.4.0; +https://github.com/KiowDev/itd-api)";
1371
798
  /** Настройки очереди со всеми значениями по умолчанию. */
1372
799
  interface ResolvedRateLimitOptions {
1373
800
  concurrency: number;
@@ -1708,7 +1135,7 @@ declare class AuthManager {
1708
1135
  clear(): Promise<void>;
1709
1136
  }
1710
1137
  //#endregion
1711
- //#region src/core/plugins.d.ts
1138
+ //#region src/core/plugins/contracts.d.ts
1712
1139
  /**
1713
1140
  * Обёртка вокруг запроса.
1714
1141
  *
@@ -1817,116 +1244,301 @@ interface ItdPlugin {
1817
1244
  */
1818
1245
  install(context: PluginContext): unknown;
1819
1246
  }
1247
+ //#endregion
1248
+ //#region src/core/rate-limit.d.ts
1820
1249
  /**
1821
- * Список подключённых плагинов и собранная из них цепочка обёрток.
1250
+ * Очередь запросов: ограничивает одновременность и частоту.
1822
1251
  *
1823
- * Живёт в клиенте, а работает в транспорте: {@link HttpClient} прогоняет через `run`
1824
- * каждый запрос, если плагины есть.
1252
+ * Нужна прежде всего ботам: без неё цикл по сотне постов уходит в API одним залпом
1253
+ * и упирается в `RATE_LIMIT_EXCEEDED`.
1254
+ *
1255
+ * Частота выдерживается равномерным разносом стартов (`1000 / rps` между запросами),
1256
+ * а не окном со счётчиком: так нагрузка ровная, без всплеска в начале каждой секунды.
1257
+ *
1258
+ * @internal
1259
+ */
1260
+ declare class RequestQueue {
1261
+ #private;
1262
+ constructor(options: ResolvedRateLimitOptions, clock?: ItdClock);
1263
+ /** Сколько задач выполняется прямо сейчас. */
1264
+ get active(): number;
1265
+ /** Сколько задач ждёт очереди. */
1266
+ get pending(): number;
1267
+ /**
1268
+ * Ставит задачу в очередь.
1269
+ *
1270
+ * @returns результат задачи; ошибка задачи пробрасывается без изменений
1271
+ */
1272
+ schedule<T>(task: () => Promise<T>, signal?: AbortSignal): Promise<T>;
1273
+ /**
1274
+ * Останавливает очередь: снимает отложенную паузу и отклоняет ещё не начатые задачи
1275
+ * ошибкой `ItdAbortError`. Уже выполняющиеся задачи доводятся до конца.
1276
+ */
1277
+ stop(): void;
1278
+ /**
1279
+ * Придерживает всю очередь на заданное время.
1280
+ *
1281
+ * Вызывается при получении `429` с заголовком `Retry-After`: тормозить нужно все запросы,
1282
+ * а не только тот, который наткнулся на лимит, — иначе остальные продолжат добивать API.
1283
+ */
1284
+ pause(ms: number): void;
1285
+ }
1286
+ /**
1287
+ * Очереди по хостам: основная и по одной на каждый сервис платформы.
1288
+ *
1289
+ * @internal
1290
+ */
1291
+ declare class RequestQueuePool {
1292
+ #private;
1293
+ constructor(options: ResolvedRateLimitOptions, clock?: ItdClock);
1294
+ /** Очередь хоста. */
1295
+ for(service: string | undefined): RequestQueue;
1296
+ /** Останавливает все очереди. */
1297
+ stop(): void;
1298
+ }
1299
+ //#endregion
1300
+ //#region src/models/users.d.ts
1301
+ /** Значок-«пин» в профиле — награда или отметка платформы. */
1302
+ interface Pin {
1303
+ /** Постоянный идентификатор, например `epepuy_202605_59`. */
1304
+ slug: string;
1305
+ /** Отображаемое название. */
1306
+ name: string;
1307
+ /** Описание, за что выдан. */
1308
+ description: string;
1309
+ /** Адрес изображения. */
1310
+ url: string;
1311
+ /** Когда выдан. Приходит только в списке своих пинов. */
1312
+ grantedAt?: IsoDate;
1313
+ }
1314
+ /**
1315
+ * Автор поста или комментария.
1316
+ *
1317
+ * Встречается внутри `post.author` и `comment.author`.
1318
+ */
1319
+ interface Author {
1320
+ id: UserId;
1321
+ username: string;
1322
+ displayName: string;
1323
+ /**
1324
+ * **Эмодзи, а не картинка.**
1325
+ *
1326
+ * На итд.com аватар — это символ клана (`🩵`, `🦎`), а не адрес изображения.
1327
+ * Отрисовывать его нужно как текст.
1328
+ */
1329
+ avatar: string;
1330
+ /** Пройдена ли верификация. */
1331
+ verified: boolean;
1332
+ /** Активный значок профиля. Может отсутствовать. */
1333
+ pin?: Pin | null;
1334
+ /** Есть ли премиум-подписка (значок NUKSTA). */
1335
+ hasNuksta?: boolean;
1336
+ }
1337
+ /**
1338
+ * Участник события в уведомлении.
1339
+ *
1340
+ * Отличается от {@link Author} набором полей: вместо значков приходит связь с вами.
1341
+ */
1342
+ interface Actor {
1343
+ id: UserId;
1344
+ username: string;
1345
+ displayName: string;
1346
+ /** Эмодзи-аватар, см. {@link Author.avatar}. */
1347
+ avatar: string;
1348
+ /** Подписаны ли вы на этого пользователя. */
1349
+ isFollowing?: boolean;
1350
+ /** Подписан ли он на вас. */
1351
+ isFollowedBy?: boolean;
1352
+ }
1353
+ /**
1354
+ * Пользователь в списках.
1355
+ *
1356
+ * Набор полей зависит от эндпоинта: подписчики и подписки приносят `isFollowing`,
1357
+ * поиск и рекомендации — `followersCount` и `hasNuksta`. Необязательные поля отражают
1358
+ * это различие.
1359
+ */
1360
+ interface UserSummary {
1361
+ id: UserId;
1362
+ username: string;
1363
+ displayName: string;
1364
+ /** Эмодзи-аватар, см. {@link Author.avatar}. */
1365
+ avatar: string;
1366
+ verified: boolean;
1367
+ /** Подписаны ли вы. Приходит в списках подписчиков и подписок. */
1368
+ isFollowing?: boolean;
1369
+ /** Есть ли премиум. Приходит в поиске и рекомендациях. */
1370
+ hasNuksta?: boolean;
1371
+ /** Число подписчиков. Приходит в поиске и рекомендациях. */
1372
+ followersCount?: number;
1373
+ }
1374
+ /** Поля профиля, общие для своего и чужого. */
1375
+ interface ProfileBase {
1376
+ id: UserId;
1377
+ username: string;
1378
+ displayName: string;
1379
+ /** Эмодзи-аватар, см. {@link Author.avatar}. */
1380
+ avatar: string;
1381
+ /** URL изображения баннера либо `null`. */
1382
+ banner: string | null;
1383
+ /** Описание профиля. */
1384
+ bio: string;
1385
+ verified: boolean;
1386
+ pin?: Pin | null;
1387
+ /** Кто может писать на стену. */
1388
+ wallAccess: WallAccess;
1389
+ /** Кто видит реакции. */
1390
+ likesVisibility: LikesVisibility;
1391
+ followersCount: number;
1392
+ followingCount: number;
1393
+ postsCount: number;
1394
+ createdAt: IsoDate;
1395
+ }
1396
+ /** Состояние подписки на премиум. */
1397
+ interface SubscriptionState {
1398
+ isActive: boolean;
1399
+ expiresAt: IsoDate | null;
1400
+ autoRenewal: boolean;
1401
+ }
1402
+ /**
1403
+ * Свой профиль — ответ `GET /api/users/me`.
1404
+ *
1405
+ * Отличается от чужого наличием {@link subscription} и {@link isPhoneVerified}
1406
+ * и отсутствием полей связи (`isFollowing`, `online`).
1407
+ */
1408
+ interface MyProfile extends ProfileBase {
1409
+ /** Закрыт ли профиль. */
1410
+ isPrivate: boolean;
1411
+ /** Подтверждён ли телефон. Без него часть действий недоступна. */
1412
+ isPhoneVerified: boolean;
1413
+ /** Своя премиум-подписка. */
1414
+ subscription: SubscriptionState;
1415
+ }
1416
+ /**
1417
+ * Состояние авторизации — ответ `GET /api/profile`.
1418
+ *
1419
+ * Endpoint доступен без сессии: в этом случае `authenticated` равен `false`,
1420
+ * а `user` — `null`.
1421
+ */
1422
+ interface AuthState {
1423
+ /** Есть ли действующая сессия. */
1424
+ authenticated: boolean;
1425
+ /** Заблокирован ли текущий аккаунт. */
1426
+ banned: boolean;
1427
+ /** Текущий пользователь либо `null` без действующей сессии. */
1428
+ user: MyProfile | null;
1429
+ }
1430
+ /**
1431
+ * Чужой профиль — ответ `GET /api/users/{id|username}`.
1432
+ *
1433
+ * Вместо своей подписки содержит связь с вами и присутствие.
1434
+ */
1435
+ interface PublicProfile extends ProfileBase {
1436
+ hasNuksta?: boolean;
1437
+ /** Закреплённый пост, если он есть. */
1438
+ pinnedPostId: string | null;
1439
+ /** Подписаны ли вы на него. */
1440
+ isFollowing: boolean;
1441
+ /** Подписан ли он на вас. */
1442
+ isFollowedBy: boolean;
1443
+ /** Сейчас ли пользователь в сети. */
1444
+ online: boolean;
1445
+ /** Когда был в сети. `null`, если скрыто настройками приватности. */
1446
+ lastSeen: IsoDate | null;
1447
+ }
1448
+ /** Профиль: свой либо чужой. Различаются функцией `isMyProfile()`. */
1449
+ type Profile = MyProfile | PublicProfile;
1450
+ /** Настройки приватности профиля. */
1451
+ interface PrivacySettings {
1452
+ /** Закрыт ли профиль: подписка требует одобрения. */
1453
+ isPrivate: boolean;
1454
+ wallAccess: WallAccess;
1455
+ likesVisibility: LikesVisibility;
1456
+ /** Показывать ли время последнего посещения. */
1457
+ showLastSeen: boolean;
1458
+ }
1459
+ /**
1460
+ * Результат подписки на пользователя.
1461
+ *
1462
+ * @example
1463
+ * ```ts
1464
+ * const result = await itd.users.follow('nowkie');
1465
+ * // { following: true, followersCount: 11 }
1466
+ * ```
1825
1467
  */
1826
- declare class PluginRegistry {
1827
- #private;
1828
- /** Сколько плагинов подключено. */
1829
- get size(): number;
1830
- /** Имена опций активных плагинов. */
1831
- get optionKeys(): ReadonlySet<string>;
1832
- /** Имена плагинов в фактическом порядке выполнения. */
1833
- names(): string[];
1834
- /** Подключён ли плагин с таким именем. */
1835
- has(name: string): boolean;
1836
- /** Проверяет добавление без вызова `install()`. @internal */
1837
- assertCanAdd(plugin: ItdPlugin): void;
1838
- /** Проверяет удаление без изменения реестра. @internal */
1839
- assertCanRemove(name: string): void;
1840
- /**
1841
- * Подключает плагин.
1842
- *
1843
- * @throws {ItdConfigError} если плагин задан неверно, уже подключён, нарушает зависимости
1844
- * или заявил занятое имя опции
1845
- */
1846
- add(plugin: ItdPlugin, context: Omit<PluginContext, 'use' | 'useHooks'>): void;
1847
- /**
1848
- * Отключает плагин и вызывает его функцию очистки.
1849
- *
1850
- * Новые запросы перестают видеть плагин сразу. Если его обёртка уже выполняется,
1851
- * очистка дождётся завершения этого логического запроса.
1852
- *
1853
- * @returns `false`, если такого плагина не было
1854
- */
1855
- remove(name: string): Promise<boolean>;
1856
- /**
1857
- * Отключает все плагины окончательно.
1858
- *
1859
- * Очистка идёт изнутри наружу — в порядке, обратном выполнению обёрток.
1860
- */
1861
- dispose(): Promise<void>;
1862
- /**
1863
- * Объединяет конструкторские хуки с хуками подключаемых плагинов.
1864
- *
1865
- * Возвращённый объект динамический: подключение и отключение плагина начинает действовать
1866
- * со следующего логического запроса без пересоздания транспорта.
1867
- */
1868
- hooks(base: ClientHooks): ClientHooks;
1869
- /**
1870
- * Прогоняет запрос через цепочку обёрток.
1871
- *
1872
- * Снимок цепочки берётся в начале: `unuse()` влияет на новые запросы, но не обрывает
1873
- * уже выполняющийся посередине.
1874
- *
1875
- * @param execute настоящий запрос, вызывается самой внутренней обёрткой
1876
- */
1877
- run(request: RawRequestOptions, execute: (request: RawRequestOptions) => Promise<unknown>): Promise<unknown>;
1468
+ interface FollowResult {
1469
+ /** Подписка оформлена. У закрытого профиля отправляется заявка, и здесь будет `false`. */
1470
+ following: boolean;
1471
+ /** Сколько подписчиков стало у пользователя после действия. */
1472
+ followersCount?: number;
1473
+ /** Статус заявки, если профиль закрыт. */
1474
+ status?: Loose<'following' | 'requested'>;
1475
+ }
1476
+ /** Закреплённые значки профиля и выбранный из них. */
1477
+ interface PinsResult {
1478
+ pins: Pin[];
1479
+ /** Идентификатор активного значка — строка, а не объект. */
1480
+ activePin: string | null;
1878
1481
  }
1879
1482
  //#endregion
1880
- //#region src/core/rate-limit.d.ts
1483
+ //#region src/models/notifications.d.ts
1881
1484
  /**
1882
- * Очередь запросов: ограничивает одновременность и частоту.
1883
- *
1884
- * Нужна прежде всего ботам: без неё цикл по сотне постов уходит в API одним залпом
1885
- * и упирается в `RATE_LIMIT_EXCEEDED`.
1485
+ * Уведомление в единой форме.
1886
1486
  *
1887
- * Частота выдерживается равномерным разносом стартов (`1000 / rps` между запросами),
1888
- * а не окном со счётчиком: так нагрузка ровная, без всплеска в начале каждой секунды.
1487
+ * REST-список и SSE-поток отдают уведомления по-разному разные имена типов, разные имена
1488
+ * полей, один участник против массива. Библиотека приводит оба вида к этой структуре,
1489
+ * поэтому объекты из `itd.notifications.list()` и из потока можно складывать в один список.
1889
1490
  *
1890
- * @internal
1491
+ * Исходные данные не теряются: серверное имя типа остаётся в {@link rawType},
1492
+ * а весь необработанный объект — в {@link raw}.
1891
1493
  */
1892
- declare class RequestQueue {
1893
- #private;
1894
- constructor(options: ResolvedRateLimitOptions, clock?: ItdClock);
1895
- /** Сколько задач выполняется прямо сейчас. */
1896
- get active(): number;
1897
- /** Сколько задач ждёт очереди. */
1898
- get pending(): number;
1899
- /**
1900
- * Ставит задачу в очередь.
1901
- *
1902
- * @returns результат задачи; ошибка задачи пробрасывается без изменений
1903
- */
1904
- schedule<T>(task: () => Promise<T>, signal?: AbortSignal): Promise<T>;
1905
- /**
1906
- * Останавливает очередь: снимает отложенную паузу и отклоняет ещё не начатые задачи
1907
- * ошибкой `ItdAbortError`. Уже выполняющиеся задачи доводятся до конца.
1908
- */
1909
- stop(): void;
1910
- /**
1911
- * Придерживает всю очередь на заданное время.
1912
- *
1913
- * Вызывается при получении `429` с заголовком `Retry-After`: тормозить нужно все запросы,
1914
- * а не только тот, который наткнулся на лимит, — иначе остальные продолжат добивать API.
1915
- */
1916
- pause(ms: number): void;
1494
+ interface Notification {
1495
+ id: string;
1496
+ /** Канонический тип. Старые имена (`like`, `comment`) приведены к новым. */
1497
+ type: NotificationType;
1498
+ /** Имя типа в том виде, в каком его прислал сервер. */
1499
+ rawType: string;
1500
+ /** Объект события: пост, комментарий, пользователь. */
1501
+ entityId: string | null;
1502
+ /** Пост, которому принадлежит комментарий, если событие о комментарии. */
1503
+ parentEntityId: string | null;
1504
+ /** Прочитано ли уведомление. */
1505
+ isRead: boolean;
1506
+ /** Кто совершил действие. Для схлопнутых уведомлений — несколько человек. */
1507
+ actors: Actor[];
1508
+ /** Сколько участников схлопнуто в одно уведомление. Минимум 1. */
1509
+ count: number;
1510
+ /** Текст или заголовок объекта события. */
1511
+ preview: string | null;
1512
+ /** Ссылка перехода, предложенная сервером. Обычно точнее её `resolveNotificationUrl()`. */
1513
+ clickUrl?: string;
1514
+ createdAt: IsoDate;
1515
+ /** Когда уведомление изменилось например было прочитано. */
1516
+ updatedAt: IsoDate;
1517
+ /** Исходный объект как он пришёл от сервера. */
1518
+ raw: unknown;
1917
1519
  }
1918
1520
  /**
1919
- * Очереди по хостам: основная и по одной на каждый сервис платформы.
1521
+ * Настройки уведомлений.
1920
1522
  *
1921
- * @internal
1523
+ * Сервер отдаёт плоский объект, но исторически знает два набора имён для одних и тех же
1524
+ * настроек (`likes` и `reactions`, `comments` и `replies`). При сохранении библиотека
1525
+ * отправляет оба, при чтении принимает любой.
1922
1526
  */
1923
- declare class RequestQueuePool {
1924
- #private;
1925
- constructor(options: ResolvedRateLimitOptions, clock?: ItdClock);
1926
- /** Очередь хоста. */
1927
- for(service: string | undefined): RequestQueue;
1928
- /** Останавливает все очереди. */
1929
- stop(): void;
1527
+ interface NotificationSettings {
1528
+ /** Общий выключатель доставки. */
1529
+ enabled: boolean;
1530
+ /** Звук уведомления. */
1531
+ sound: boolean;
1532
+ /** Новые подписчики. */
1533
+ follows: boolean;
1534
+ /** Записи на вашей стене. */
1535
+ wallPosts: boolean;
1536
+ /** Реакции на ваши записи. */
1537
+ likes: boolean;
1538
+ /** Комментарии и ответы. */
1539
+ comments: boolean;
1540
+ /** Упоминания. */
1541
+ mentions: boolean;
1930
1542
  }
1931
1543
  //#endregion
1932
1544
  //#region src/notifications/normalize.d.ts
@@ -2359,6 +1971,67 @@ declare class ItdRealtime {
2359
1971
  removeAllListeners(): void;
2360
1972
  }
2361
1973
  //#endregion
1974
+ //#region src/core/plugins/registry.d.ts
1975
+ /**
1976
+ * Список подключённых плагинов и собранная из них цепочка обёрток.
1977
+ *
1978
+ * Живёт в клиенте, а работает в транспорте: {@link HttpClient} прогоняет через `run`
1979
+ * каждый запрос, если плагины есть.
1980
+ */
1981
+ declare class PluginRegistry {
1982
+ #private;
1983
+ /** Сколько плагинов подключено. */
1984
+ get size(): number;
1985
+ /** Имена опций активных плагинов. */
1986
+ get optionKeys(): ReadonlySet<string>;
1987
+ /** Имена плагинов в фактическом порядке выполнения. */
1988
+ names(): string[];
1989
+ /** Подключён ли плагин с таким именем. */
1990
+ has(name: string): boolean;
1991
+ /** Проверяет добавление без вызова `install()`. @internal */
1992
+ assertCanAdd(plugin: ItdPlugin): void;
1993
+ /** Проверяет удаление без изменения реестра. @internal */
1994
+ assertCanRemove(name: string): void;
1995
+ /**
1996
+ * Подключает плагин.
1997
+ *
1998
+ * @throws {ItdConfigError} если плагин задан неверно, уже подключён, нарушает зависимости
1999
+ * или заявил занятое имя опции
2000
+ */
2001
+ add(plugin: ItdPlugin, context: Omit<PluginContext, 'use' | 'useHooks'>): void;
2002
+ /**
2003
+ * Отключает плагин и вызывает его функцию очистки.
2004
+ *
2005
+ * Новые запросы перестают видеть плагин сразу. Если его обёртка уже выполняется,
2006
+ * очистка дождётся завершения этого логического запроса.
2007
+ *
2008
+ * @returns `false`, если такого плагина не было
2009
+ */
2010
+ remove(name: string): Promise<boolean>;
2011
+ /**
2012
+ * Отключает все плагины окончательно.
2013
+ *
2014
+ * Очистка идёт изнутри наружу — в порядке, обратном выполнению обёрток.
2015
+ */
2016
+ dispose(): Promise<void>;
2017
+ /**
2018
+ * Объединяет конструкторские хуки с хуками подключаемых плагинов.
2019
+ *
2020
+ * Возвращённый объект динамический: подключение и отключение плагина начинает действовать
2021
+ * со следующего логического запроса без пересоздания транспорта.
2022
+ */
2023
+ hooks(base: ClientHooks): ClientHooks;
2024
+ /**
2025
+ * Прогоняет запрос через цепочку обёрток.
2026
+ *
2027
+ * Снимок цепочки берётся в начале: `unuse()` влияет на новые запросы, но не обрывает
2028
+ * уже выполняющийся посередине.
2029
+ *
2030
+ * @param execute настоящий запрос, вызывается самой внутренней обёрткой
2031
+ */
2032
+ run(request: RawRequestOptions, execute: (request: RawRequestOptions) => Promise<unknown>): Promise<unknown>;
2033
+ }
2034
+ //#endregion
2362
2035
  //#region src/core/http.d.ts
2363
2036
  /** Что нужно фасаду для работы. */
2364
2037
  interface HttpClientDeps {
@@ -2399,6 +2072,48 @@ declare class HttpClient {
2399
2072
  request<T = unknown>(options: PipelineRequest): Promise<T>;
2400
2073
  }
2401
2074
  //#endregion
2075
+ //#region src/models/account.d.ts
2076
+ /** Активная сессия входа. */
2077
+ interface Session {
2078
+ id: string;
2079
+ /** Та ли это сессия, из которой выполнен запрос. */
2080
+ isCurrent: boolean;
2081
+ createdAt: IsoDate;
2082
+ lastUsedAt: IsoDate;
2083
+ expiresAt: IsoDate;
2084
+ ipAddress: string;
2085
+ /** Код страны по IP, например `RU`. */
2086
+ ipCountry: string | null;
2087
+ ipCity: string | null;
2088
+ deviceType: Loose<'desktop' | 'mobile'>;
2089
+ osName: string | null;
2090
+ osVersion: string | null;
2091
+ /** Название браузера или приложения. */
2092
+ clientName: string | null;
2093
+ clientVersion: string | null;
2094
+ deviceModel: string | null;
2095
+ }
2096
+ /** Состояние платной подписки и её цена. */
2097
+ interface Subscription {
2098
+ /** Активна ли подписка сейчас. */
2099
+ active: boolean;
2100
+ /** Включено ли автопродление. */
2101
+ recurringEnabled: boolean;
2102
+ /** Цена в рублях. */
2103
+ price: number;
2104
+ }
2105
+ /** Сохранённый способ оплаты. */
2106
+ interface PaymentMethod {
2107
+ id: string;
2108
+ /** Последние четыре цифры карты. */
2109
+ last4?: string;
2110
+ /** Платёжная система: `visa`, `mastercard`, `mir`. */
2111
+ brand?: string;
2112
+ /** Основной ли это способ оплаты. */
2113
+ isDefault?: boolean;
2114
+ expiresAt?: IsoDate | null;
2115
+ }
2116
+ //#endregion
2402
2117
  //#region src/core/pagination.d.ts
2403
2118
  /**
2404
2119
  * Страница списка — единая форма для всех трёх схем пагинации API.
@@ -2815,92 +2530,6 @@ declare class AuthResource extends BaseResource {
2815
2530
  revokeOtherSessions(options?: RequestOptions): Promise<void>;
2816
2531
  }
2817
2532
  //#endregion
2818
- //#region src/builders/base.d.ts
2819
- /** Метка билдера. Через `Symbol.for` — чтобы распознавание переживало смешивание ESM и CJS. */
2820
- declare const BUILDER: unique symbol;
2821
- /**
2822
- * Билдер входных данных.
2823
- *
2824
- * Билдеры необязательны: любой метод, принимающий билдер, принимает и обычный объект.
2825
- * Проверки одинаковы в обоих случаях.
2826
- */
2827
- interface ItdBuilder<T> {
2828
- /** @internal */
2829
- readonly [BUILDER]: true;
2830
- /**
2831
- * Собирает и проверяет результат.
2832
- *
2833
- * @throws {ItdConfigError} если нарушены требования к данным
2834
- */
2835
- build(): T;
2836
- /** Чтобы билдер корректно вёл себя внутри `JSON.stringify`. */
2837
- toJSON(): T;
2838
- }
2839
- /**
2840
- * Три равноправные формы входа: обычный объект, готовый билдер или функция-настройщик.
2841
- *
2842
- * @example
2843
- * ```ts
2844
- * itd.posts.create({ content: 'привет' }); // объект
2845
- * itd.posts.create(post().content('привет')); // билдер
2846
- * itd.posts.create((p) => p.content('привет')); // функция
2847
- * ```
2848
- */
2849
- type BuilderInput<T, B extends ItdBuilder<T>> = T | B | ((builder: B) => B | T);
2850
- /** Является ли значение билдером. */
2851
- declare function isBuilder<T>(value: unknown): value is ItdBuilder<T>;
2852
- //#endregion
2853
- //#region src/builders/poll.d.ts
2854
- /**
2855
- * Билдер опроса.
2856
- *
2857
- * Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
2858
- * переиспользовать, не боясь её испортить. Создаётся функцией {@link poll}.
2859
- */
2860
- declare class PollBuilder implements ItdBuilder<CreatePollInput> {
2861
- #private;
2862
- /** @internal */
2863
- readonly [BUILDER]: true;
2864
- /** @internal Создавайте билдер функцией {@link poll}. */
2865
- constructor(state: CreatePollInput);
2866
- /** Задаёт вопрос. */
2867
- question(text: string): PollBuilder;
2868
- /** Добавляет один вариант ответа. */
2869
- option(text: string): PollBuilder;
2870
- /**
2871
- * Добавляет несколько вариантов сразу.
2872
- *
2873
- * @example
2874
- * ```ts
2875
- * poll('ну как?').options('да', 'нет', 'не знаю');
2876
- * ```
2877
- */
2878
- options(...texts: string[]): PollBuilder;
2879
- /** Разрешает выбор нескольких вариантов. */
2880
- multipleChoice(enabled?: boolean): PollBuilder;
2881
- build(): CreatePollInput;
2882
- toJSON(): CreatePollInput;
2883
- }
2884
- /**
2885
- * Начинает сборку опроса.
2886
- *
2887
- * @param question вопрос; можно задать позже методом {@link PollBuilder.question}
2888
- *
2889
- * @example
2890
- * ```ts
2891
- * import { poll } from 'itd-api';
2892
- *
2893
- * const q = poll('Какой язык лучше?')
2894
- * .options('TypeScript', 'JavaScript')
2895
- * .multipleChoice();
2896
- *
2897
- * await itd.posts.create({ content: 'голосуем', poll: q });
2898
- * ```
2899
- */
2900
- declare function poll(question?: string): PollBuilder;
2901
- /** Что принимает параметр опроса: объект, билдер или функция-настройщик. */
2902
- type PollInput = BuilderInput<CreatePollInput, PollBuilder>;
2903
- //#endregion
2904
2533
  //#region src/types/params.d.ts
2905
2534
  /** Данные для создания опроса. */
2906
2535
  interface CreatePollInput {
@@ -2913,8 +2542,13 @@ interface CreatePollInput {
2913
2542
  /** Разрешить выбор нескольких вариантов. По умолчанию `false`. */
2914
2543
  multipleChoice?: boolean;
2915
2544
  }
2916
- /** Данные для создания поста. */
2917
- interface CreatePostInput {
2545
+ /**
2546
+ * Нормализованные данные для создания поста.
2547
+ *
2548
+ * Это форма, которую возвращают `PostBuilder.build()` и `resolvePost()` после
2549
+ * преобразования вложенных builders. Для входа `itd.posts.create()` см. {@link CreatePostInput}.
2550
+ */
2551
+ interface CreatePostData {
2918
2552
  /** Текст поста. */
2919
2553
  content?: string;
2920
2554
  /**
@@ -2933,8 +2567,8 @@ interface CreatePostInput {
2933
2567
  attachmentIds?: string[];
2934
2568
  /** Файлы, которые нужно загрузить перед публикацией. Порядок сохраняется. */
2935
2569
  files?: FileInput[];
2936
- /** Опрос: обычный объект, {@link PollBuilder} или функция-настройщик. */
2937
- poll?: PollInput;
2570
+ /** Готовые данные опроса. */
2571
+ poll?: CreatePollInput;
2938
2572
  }
2939
2573
  /** Поля поста, которые принимает `itd.posts.update()`. */
2940
2574
  interface UpdatePostInput {
@@ -2970,6 +2604,41 @@ interface CreateReportInput {
2970
2604
  description?: string;
2971
2605
  }
2972
2606
  //#endregion
2607
+ //#region src/builders/base.d.ts
2608
+ /** Метка билдера. Через `Symbol.for` — чтобы распознавание переживало смешивание ESM и CJS. */
2609
+ declare const BUILDER: unique symbol;
2610
+ /**
2611
+ * Билдер входных данных.
2612
+ *
2613
+ * Билдеры необязательны: любой метод, принимающий билдер, принимает и обычный объект.
2614
+ * Проверки одинаковы в обоих случаях.
2615
+ */
2616
+ interface ItdBuilder<T> {
2617
+ /** @internal */
2618
+ readonly [BUILDER]: true;
2619
+ /**
2620
+ * Собирает и проверяет результат.
2621
+ *
2622
+ * @throws {ItdConfigError} если нарушены требования к данным
2623
+ */
2624
+ build(): T;
2625
+ /** Чтобы билдер корректно вёл себя внутри `JSON.stringify`. */
2626
+ toJSON(): T;
2627
+ }
2628
+ /**
2629
+ * Три равноправные формы входа: обычный объект, готовый билдер или функция-настройщик.
2630
+ *
2631
+ * @example
2632
+ * ```ts
2633
+ * itd.posts.create({ content: 'привет' }); // объект
2634
+ * itd.posts.create(post().content('привет')); // билдер
2635
+ * itd.posts.create((p) => p.content('привет')); // функция
2636
+ * ```
2637
+ */
2638
+ type BuilderInput<T, B extends ItdBuilder<T>> = T | B | ((builder: B) => B | T);
2639
+ /** Является ли значение билдером. */
2640
+ declare function isBuilder<T>(value: unknown): value is ItdBuilder<T>;
2641
+ //#endregion
2973
2642
  //#region src/builders/comment.d.ts
2974
2643
  /** Внутреннее состояние {@link CommentBuilder}. */
2975
2644
  interface CommentState extends CreateCommentInput {
@@ -3020,21 +2689,172 @@ declare class CommentBuilder implements ItdBuilder<CreateCommentInput> {
3020
2689
  build(): CreateCommentInput;
3021
2690
  toJSON(): CreateCommentInput;
3022
2691
  }
3023
- /**
3024
- * Начинает сборку комментария.
3025
- *
3026
- * @param content текст; можно задать позже методом {@link CommentBuilder.content}
3027
- *
3028
- * @example
3029
- * ```ts
3030
- * import { comment } from 'itd-api';
3031
- *
3032
- * await itd.posts.comment(postId, comment('согласен').attach({ url: memeUrl }));
3033
- * ```
3034
- */
3035
- declare function comment(content?: string): CommentBuilder;
3036
- /** Что принимает параметр комментария: объект, билдер или функция-настройщик. */
3037
- type CommentInput = BuilderInput<CreateCommentInput, CommentBuilder>;
2692
+ /**
2693
+ * Начинает сборку комментария.
2694
+ *
2695
+ * @param content текст; можно задать позже методом {@link CommentBuilder.content}
2696
+ *
2697
+ * @example
2698
+ * ```ts
2699
+ * import { comment } from 'itd-api';
2700
+ *
2701
+ * await itd.posts.comment(postId, comment('согласен').attach({ url: memeUrl }));
2702
+ * ```
2703
+ */
2704
+ declare function comment(content?: string): CommentBuilder;
2705
+ /** Что принимает параметр комментария: объект, билдер или функция-настройщик. */
2706
+ type CommentInput = BuilderInput<CreateCommentInput, CommentBuilder>;
2707
+ //#endregion
2708
+ //#region src/models/content.d.ts
2709
+ /** Вложение поста или комментария. */
2710
+ interface Attachment {
2711
+ id: string;
2712
+ type: AttachmentType;
2713
+ /** Адрес файла на CDN. */
2714
+ url: string;
2715
+ /** Ширина изображения или видео в пикселях. */
2716
+ width?: number;
2717
+ /** Высота изображения или видео в пикселях. */
2718
+ height?: number;
2719
+ mimeType: string;
2720
+ /** Исходное имя файла. Приходит не всегда. */
2721
+ filename?: string;
2722
+ /** Размер в байтах. Приходит не всегда. */
2723
+ size?: number;
2724
+ /** Длительность аудио или видео в секундах. */
2725
+ duration?: number | null;
2726
+ /** Порядковый номер во вложениях поста. */
2727
+ order?: number;
2728
+ }
2729
+ /** Вариант ответа в опросе. */
2730
+ interface PollOption {
2731
+ id: string;
2732
+ text: string;
2733
+ /** Сколько голосов отдано за этот вариант. */
2734
+ votesCount: number;
2735
+ /** Порядковый номер варианта, начиная с нуля. */
2736
+ position: number;
2737
+ }
2738
+ /** Опрос внутри поста. */
2739
+ interface Poll {
2740
+ id: string;
2741
+ /** Пост, которому принадлежит опрос. */
2742
+ postId: string;
2743
+ question: string;
2744
+ /** Можно ли выбрать несколько вариантов. */
2745
+ multipleChoice: boolean;
2746
+ options: PollOption[];
2747
+ totalVotes: number;
2748
+ /** Голосовали ли вы. */
2749
+ hasVoted: boolean;
2750
+ /** За что проголосовали вы. Пустой массив, если голоса не было. */
2751
+ votedOptionIds: string[];
2752
+ createdAt: IsoDate;
2753
+ }
2754
+ /** Пост ленты, стены или профиля. */
2755
+ interface Post {
2756
+ id: string;
2757
+ content: string;
2758
+ /** Разметка текста. Передаётся без изменений, см. {@link Span}. */
2759
+ spans: Span[];
2760
+ author: Author;
2761
+ attachments: Attachment[];
2762
+ likesCount: number;
2763
+ commentsCount: number;
2764
+ repostsCount: number;
2765
+ viewsCount: number;
2766
+ /** Чья это стена, если пост опубликован не у себя. */
2767
+ wallRecipientId: UserId | null;
2768
+ /** Владелец стены. Приходит не во всех ответах. */
2769
+ wallRecipient?: Author | null;
2770
+ /** Поставили ли вы реакцию. */
2771
+ isLiked: boolean;
2772
+ /** Делали ли вы репост. */
2773
+ isReposted: boolean;
2774
+ /** Засчитан ли просмотр. */
2775
+ isViewed: boolean;
2776
+ /** Ваш ли это пост. */
2777
+ isOwner: boolean;
2778
+ /** Исходный пост, если это репост. */
2779
+ originalPost?: Post | null;
2780
+ poll?: Poll | null;
2781
+ /** Преобладающая реакция — эмодзи либо `null`. */
2782
+ dominantEmoji?: string | null;
2783
+ /** Когда пост отредактировали. `null`, если не редактировали. */
2784
+ editedAt: IsoDate | null;
2785
+ createdAt: IsoDate;
2786
+ /**
2787
+ * Служебная метка показа для телеметрии.
2788
+ *
2789
+ * Нужна только эндпоинтам `itd.telemetry.*`. В остальных случаях игнорируйте.
2790
+ */
2791
+ vs?: string;
2792
+ /**
2793
+ * Топовые комментарии. Приходят только в ответе `GET /api/posts/{id}`.
2794
+ *
2795
+ * В списках постов поле отсутствует.
2796
+ */
2797
+ comments?: Comment[];
2798
+ }
2799
+ /** На чей комментарий дан ответ. */
2800
+ interface CommentReplyTo {
2801
+ id: string;
2802
+ username: string;
2803
+ displayName: string;
2804
+ }
2805
+ /** Комментарий к посту или ответ на комментарий. */
2806
+ interface Comment {
2807
+ id: string;
2808
+ /** Текст. У голосового комментария пустой. */
2809
+ content: string;
2810
+ /**
2811
+ * Разметка текста, включая автоматически найденные сервером хэштеги и упоминания.
2812
+ *
2813
+ * Методы создания и редактирования комментария принимают только `content`, поэтому
2814
+ * библиотека не отправляет ручные spans в этих операциях.
2815
+ * Поле необязательно: отдельные ответы сервера могут его не содержать.
2816
+ */
2817
+ spans?: Span[];
2818
+ author: Author;
2819
+ likesCount: number;
2820
+ repliesCount: number;
2821
+ isLiked: boolean;
2822
+ createdAt: IsoDate;
2823
+ /** Вложения. У голосового — одно аудио с `mimeType: 'audio/ogg'`. */
2824
+ attachments?: Attachment[];
2825
+ /** Вложенные ответы. В списках приходит превью, полный список — через `itd.comments.replies()`. */
2826
+ replies?: Comment[];
2827
+ /** Заполнено только у ответов. */
2828
+ replyTo?: CommentReplyTo;
2829
+ }
2830
+ /** Хэштег. */
2831
+ interface Hashtag {
2832
+ id: string;
2833
+ /** Название без решётки. */
2834
+ name: string;
2835
+ /** Сколько постов с этим хэштегом. */
2836
+ postsCount: number;
2837
+ }
2838
+ /** Счётчики поста из `itd.posts.stats()`. */
2839
+ interface PostStats {
2840
+ id: string;
2841
+ likesCount: number;
2842
+ commentsCount: number;
2843
+ repostsCount: number;
2844
+ viewsCount: number;
2845
+ /** Преобладающая реакция — эмодзи либо `null`. */
2846
+ dominantEmoji: string | null;
2847
+ }
2848
+ /** Результат реакции на пост. */
2849
+ interface LikeResult {
2850
+ liked: boolean;
2851
+ likesCount: number;
2852
+ }
2853
+ /** Результат закрепления поста в профиле. */
2854
+ interface PinPostResult {
2855
+ success: boolean;
2856
+ pinnedPostId: string | null;
2857
+ }
3038
2858
  //#endregion
3039
2859
  //#region src/resources/comments.d.ts
3040
2860
  /** Параметры запроса ответов на комментарий. */
@@ -3240,6 +3060,116 @@ declare class NotificationsResource extends BaseResource {
3240
3060
  updateSettings(input: UpdateNotificationSettingsInput, options?: RequestOptions): Promise<NotificationSettings>;
3241
3061
  }
3242
3062
  //#endregion
3063
+ //#region src/models/platform.d.ts
3064
+ /** Клан в рейтинге. */
3065
+ interface Clan {
3066
+ /** Эмодзи клана — оно же аватар его участников. */
3067
+ avatar: string;
3068
+ memberCount: number;
3069
+ }
3070
+ /** Запись журнала изменений платформы. */
3071
+ interface ChangelogEntry {
3072
+ version: string;
3073
+ date: string;
3074
+ changes: string[];
3075
+ }
3076
+ /** Кнопка в анонсе платформы. */
3077
+ interface AnnouncementButton {
3078
+ title: string;
3079
+ /** Оформление: `primary`, `secondary` и другие. */
3080
+ style: string;
3081
+ action: {
3082
+ type: string;
3083
+ [key: string]: unknown;
3084
+ };
3085
+ }
3086
+ /** Анонс на главной странице платформы. */
3087
+ interface Announcement {
3088
+ id: string;
3089
+ image: {
3090
+ url: string;
3091
+ width: number;
3092
+ height: number;
3093
+ };
3094
+ title: string;
3095
+ description: string;
3096
+ /** Дополнительный текст мелким шрифтом. */
3097
+ additional_text?: string;
3098
+ buttons: AnnouncementButton[];
3099
+ }
3100
+ /** Баннер текущего события — виджет «портал». */
3101
+ interface Portal {
3102
+ active: boolean;
3103
+ title: string;
3104
+ url: string;
3105
+ }
3106
+ /** Статус заявки на верификацию. `none` означает, что заявка не подавалась. */
3107
+ interface VerificationStatus {
3108
+ status: Loose<'none' | 'pending' | 'approved' | 'rejected'>;
3109
+ }
3110
+ /** Созданная жалоба. */
3111
+ interface Report {
3112
+ id: string;
3113
+ createdAt: IsoDate;
3114
+ }
3115
+ //#endregion
3116
+ //#region src/models/status.d.ts
3117
+ /** Происшествие в истории сервиса. */
3118
+ interface StatusIncidentLine {
3119
+ /** Вид происшествия. */
3120
+ t: IncidentKind;
3121
+ /**
3122
+ * Готовая строка для показа: `недоступен 6 мин (12:00–12:06)`. Время московское.
3123
+ * Длительность и границы интервала отдельными полями не приходят.
3124
+ */
3125
+ text: string;
3126
+ }
3127
+ /** Одни сутки в истории сервиса. */
3128
+ interface StatusDay {
3129
+ /** Худшее состояние за сутки. */
3130
+ type: ServiceState;
3131
+ /** Дата суток, `YYYY-MM-DD`. Сутки нарезаны по UTC. */
3132
+ date_key: string;
3133
+ /** Доступность за сутки в процентах. */
3134
+ uptime: number;
3135
+ /** Происшествия за сутки. */
3136
+ lines: StatusIncidentLine[];
3137
+ }
3138
+ /** Сервис платформы и его история доступности. */
3139
+ interface ServiceStatus {
3140
+ /** Идентификатор: `auth`, `main`, `media` и прочие. */
3141
+ id: string;
3142
+ /** Отображаемое название. */
3143
+ name: string;
3144
+ current_status: ServiceState;
3145
+ /** Пояснение к текущему состоянию, например `No downtime`. */
3146
+ current_message: string;
3147
+ /** Задержка последней проверки в миллисекундах. */
3148
+ latency_ms: number;
3149
+ /**
3150
+ * Момент последней проверки. Сервер отдаёт `YYYY-MM-DD HH:mm:ss` в UTC, библиотека
3151
+ * приводит значение к ISO.
3152
+ */
3153
+ last_checked: IsoDate;
3154
+ /** Доступность за 90 суток в процентах. */
3155
+ uptime_90d: number;
3156
+ /**
3157
+ * История по суткам. Ключ — сколько суток назад, `'0'` — сегодня.
3158
+ *
3159
+ * Объект разреженный: сутки без данных сервер пропускает. Ровный массив даёт
3160
+ * `statusDays()`.
3161
+ */
3162
+ days: Record<string, StatusDay | undefined>;
3163
+ }
3164
+ /** Состояние платформы — ответ `itd.platform.status()`. */
3165
+ interface PlatformStatus {
3166
+ /** Худшее состояние среди сервисов. */
3167
+ overall_status: ServiceState;
3168
+ /** Когда данные последний раз пересчитаны. */
3169
+ updated_at: IsoDate;
3170
+ services: ServiceStatus[];
3171
+ }
3172
+ //#endregion
3243
3173
  //#region src/resources/platform.d.ts
3244
3174
  /** Требования к версии одного приложения платформы. */
3245
3175
  interface PlatformClientVersion {
@@ -3415,8 +3345,64 @@ declare function parseMarkdown(source: string, options?: ParseMarkupOptions): Te
3415
3345
  */
3416
3346
  declare function parseHtml(source: string, options?: ParseMarkupOptions): TextMarkup;
3417
3347
  //#endregion
3348
+ //#region src/builders/poll.d.ts
3349
+ /**
3350
+ * Билдер опроса.
3351
+ *
3352
+ * Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
3353
+ * переиспользовать, не боясь её испортить. Создаётся функцией {@link poll}.
3354
+ */
3355
+ declare class PollBuilder implements ItdBuilder<CreatePollInput> {
3356
+ #private;
3357
+ /** @internal */
3358
+ readonly [BUILDER]: true;
3359
+ /** @internal Создавайте билдер функцией {@link poll}. */
3360
+ constructor(state: CreatePollInput);
3361
+ /** Задаёт вопрос. */
3362
+ question(text: string): PollBuilder;
3363
+ /** Добавляет один вариант ответа. */
3364
+ option(text: string): PollBuilder;
3365
+ /**
3366
+ * Добавляет несколько вариантов сразу.
3367
+ *
3368
+ * @example
3369
+ * ```ts
3370
+ * poll('ну как?').options('да', 'нет', 'не знаю');
3371
+ * ```
3372
+ */
3373
+ options(...texts: string[]): PollBuilder;
3374
+ /** Разрешает выбор нескольких вариантов. */
3375
+ multipleChoice(enabled?: boolean): PollBuilder;
3376
+ build(): CreatePollInput;
3377
+ toJSON(): CreatePollInput;
3378
+ }
3379
+ /**
3380
+ * Начинает сборку опроса.
3381
+ *
3382
+ * @param question вопрос; можно задать позже методом {@link PollBuilder.question}
3383
+ *
3384
+ * @example
3385
+ * ```ts
3386
+ * import { poll } from 'itd-api';
3387
+ *
3388
+ * const q = poll('Какой язык лучше?')
3389
+ * .options('TypeScript', 'JavaScript')
3390
+ * .multipleChoice();
3391
+ *
3392
+ * await itd.posts.create({ content: 'голосуем', poll: q });
3393
+ * ```
3394
+ */
3395
+ declare function poll(question?: string): PollBuilder;
3396
+ /** Что принимает параметр опроса: объект, билдер или функция-настройщик. */
3397
+ type PollInput = BuilderInput<CreatePollInput, PollBuilder>;
3398
+ //#endregion
3418
3399
  //#region src/builders/post.d.ts
3419
3400
  declare const BUILD_UPDATE: unique symbol;
3401
+ /** Данные для создания поста, включая поддерживаемые builder-формы вложенного опроса. */
3402
+ interface CreatePostInput extends Omit<CreatePostData, 'poll'> {
3403
+ /** Опрос: обычный объект, {@link PollBuilder} или функция-настройщик. */
3404
+ poll?: PollInput;
3405
+ }
3420
3406
  /** Внутреннее состояние {@link PostBuilder}. */
3421
3407
  interface PostState extends CreatePostInput {
3422
3408
  content: string;
@@ -3438,7 +3424,7 @@ interface PostState extends CreatePostInput {
3438
3424
  * await itd.posts.create(onWall.content('второй')); // заготовка не испорчена
3439
3425
  * ```
3440
3426
  */
3441
- declare class PostBuilder implements ItdBuilder<CreatePostInput> {
3427
+ declare class PostBuilder implements ItdBuilder<CreatePostData> {
3442
3428
  #private;
3443
3429
  /** @internal */
3444
3430
  readonly [BUILDER]: true;
@@ -3504,10 +3490,10 @@ declare class PostBuilder implements ItdBuilder<CreatePostInput> {
3504
3490
  * ```
3505
3491
  */
3506
3492
  poll(input: PollInput): PostBuilder;
3507
- build(): CreatePostInput;
3493
+ build(): CreatePostData;
3508
3494
  /** @internal Собирает данные по правилам `posts.update`, не применяя правила создания. */
3509
3495
  [BUILD_UPDATE](): UpdatePostInput;
3510
- toJSON(): CreatePostInput;
3496
+ toJSON(): CreatePostData;
3511
3497
  }
3512
3498
  /**
3513
3499
  * Начинает сборку поста.
@@ -4664,6 +4650,22 @@ declare class ItdAccounts {
4664
4650
  */
4665
4651
  declare function createAccounts(options?: ItdAccountsOptions): ItdAccounts;
4666
4652
  //#endregion
4653
+ //#region src/core/attachments/factories.d.ts
4654
+ /** Создаёт URL-источник в выбранном режиме. */
4655
+ declare function fromUrl(url: string, options: UrlFileOptions & {
4656
+ mode: typeof FileTransferMode.Stream;
4657
+ }): StreamFile;
4658
+ declare function fromUrl(url: string, options?: UrlFileOptions & {
4659
+ mode?: typeof FileTransferMode.Buffer;
4660
+ }): LazyFile;
4661
+ declare function fromUrl(url: string, options: UrlFileOptions): LazyFile | StreamFile;
4662
+ /**
4663
+ * Создаёт повторяемый пользовательский поток.
4664
+ *
4665
+ * Фабрика вызывается заново для каждой попытки; возвращать один и тот же поток нельзя.
4666
+ */
4667
+ declare function fromStream(factory: (context: FileContext) => ReadableStream<Uint8Array> | FileStreamContent | Promise<ReadableStream<Uint8Array> | FileStreamContent>, options?: FromStreamOptions): StreamFile;
4668
+ //#endregion
4667
4669
  //#region src/core/errors.d.ts
4668
4670
  /** Бренд, по которому ошибки библиотеки распознаются надёжнее, чем через `instanceof`. */
4669
4671
  declare const ITD_ERROR: unique symbol;
@@ -5009,6 +5011,46 @@ type AllowedMimeType = (typeof ALLOWED_MIME_TYPES)[number];
5009
5011
  * ```
5010
5012
  */
5011
5013
  declare function utcStampToIso(value: string): string;
5014
+ /**
5015
+ * Разбирает дату API в объект `Date`.
5016
+ *
5017
+ * @returns `null`, если строки нет или она не разбирается
5018
+ *
5019
+ * @example
5020
+ * ```ts
5021
+ * const created = toDate(post.createdAt);
5022
+ * ```
5023
+ */
5024
+ declare function toDate(value: IsoDate | null | undefined): Date | null;
5025
+ //#endregion
5026
+ //#region src/models/guards.d.ts
5027
+ /**
5028
+ * Свой ли это профиль.
5029
+ *
5030
+ * @example
5031
+ * ```ts
5032
+ * if (isMyProfile(profile)) console.log(profile.subscription.isActive);
5033
+ * ```
5034
+ */
5035
+ declare function isMyProfile(profile: Profile): profile is MyProfile;
5036
+ //#endregion
5037
+ //#region src/models/status-helpers.d.ts
5038
+ /**
5039
+ * Разворачивает историю сервиса в массив на 90 суток.
5040
+ * Сутки без данных становятся `null`.
5041
+ *
5042
+ * @returns массив, где индекс — сколько суток назад: `[0]` — сегодня
5043
+ *
5044
+ * @example
5045
+ * ```ts
5046
+ * const status = await itd.platform.status();
5047
+ * const days = statusDays(status.services[0]);
5048
+ *
5049
+ * days[0]?.uptime; // доступность за сегодня
5050
+ * days.filter((day) => day === null).length; // за сколько суток данных нет
5051
+ * ```
5052
+ */
5053
+ declare function statusDays(service: ServiceStatus): (StatusDay | null)[];
5012
5054
  //#endregion
5013
5055
  //#region src/notifications/text.d.ts
5014
5056
  /**
@@ -5087,7 +5129,7 @@ interface PollTransportOptions {
5087
5129
  //#endregion
5088
5130
  //#region src/realtime/router.d.ts
5089
5131
  /** Выбирает маршрут обновления. `undefined` и `null` означают отсутствие маршрута. */
5090
- type RealtimeRouteSelector<K extends PropertyKey> = (context: RealtimeContext) => K | null | undefined | Promise<K | null | undefined>;
5132
+ type RealtimeRouteSelector<K extends PropertyKey, C extends RealtimeContext = RealtimeContext> = (context: C) => K | null | undefined | Promise<K | null | undefined>;
5091
5133
  /**
5092
5134
  * Направляет обновления потока в именованные цепочки промежуточных обработчиков.
5093
5135
  *
@@ -5105,15 +5147,15 @@ type RealtimeRouteSelector<K extends PropertyKey> = (context: RealtimeContext) =
5105
5147
  * stream.use(router.middleware());
5106
5148
  * ```
5107
5149
  */
5108
- declare class RealtimeRouter<K extends PropertyKey = PropertyKey> {
5150
+ declare class RealtimeRouter<K extends PropertyKey = PropertyKey, C extends RealtimeContext = RealtimeContext> {
5109
5151
  #private;
5110
- constructor(selector: RealtimeRouteSelector<K>);
5152
+ constructor(selector: RealtimeRouteSelector<K, C>);
5111
5153
  /** Добавляет промежуточные обработчики к маршруту и возвращает функцию их удаления. */
5112
- route(key: K, ...middleware: readonly RealtimeMiddleware[]): Unsubscribe;
5154
+ route(key: K, ...middleware: readonly RealtimeMiddleware<C>[]): Unsubscribe;
5113
5155
  /** Добавляет промежуточные обработчики для обновлений без зарегистрированного маршрута. */
5114
- otherwise(...middleware: readonly RealtimeMiddleware[]): Unsubscribe;
5156
+ otherwise(...middleware: readonly RealtimeMiddleware<C>[]): Unsubscribe;
5115
5157
  /** Возвращает промежуточный обработчик для `stream.use()`. */
5116
- middleware(): RealtimeMiddleware;
5158
+ middleware(): RealtimeMiddleware<C>;
5117
5159
  }
5118
5160
  //#endregion
5119
5161
  //#region src/realtime/sse.d.ts
@@ -5172,5 +5214,5 @@ interface RenderSpansOptions {
5172
5214
  */
5173
5215
  declare function renderSpans(content: string, spans?: readonly Span[] | null | undefined, options?: RenderSpansOptions): string;
5174
5216
  //#endregion
5175
- export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AUTH_FLAG_COOKIE, AUTH_PATHS, AccessType, type AccountEvents, type Actor, type AddAccountOptions, type AllowedMimeType, type Announcement, type AnnouncementButton, type Attachment, AttachmentType, type AudioMimeType, type AuthEvents, type AuthIdentity, type AuthInput, type AuthResource, type AuthState, type Author, type AutoSpansOptions, BUILT_IN_SERVICES, type BuilderInput, type CaptchaCredentials, type ChangelogEntry, type Clan, type ClientHooks, type Comment, type CommentBuilder, type CommentInput, type CommentReplyTo, CommentSort, type CommentsParams, type CommentsResource, type CreateCommentInput, type CreatePollInput, type CreatePostInput, type CreateReportInput, type Credentials, type CredentialsAuth, DEFAULT_BASE_URL, DEFAULT_FILE_STREAM_BUFFER_BYTES, DEFAULT_STATUS_BASE_URL, DEFAULT_TIMEOUT, DEFAULT_UPLOAD_TIMEOUT, DEFAULT_URL_FILE_MAX_BYTES, DEFAULT_USER_AGENT, DEVICE_ID_HEADER, DetectedRuntime, type DwellEntry, type ErrorContextHook, type FeedParams, FeedTab, type FileContent, type FileContext, type FileInput, type FileStreamContent, type FileStreamOptions, FileTransferMode, type FilesResource, type FollowResult, type ForgotPasswordInput, type FromStreamOptions, type Hashtag, type HashtagPostsParams, type HashtagsResource, IMAGE_MIME_TYPES, type ImageMimeType, IncidentKind, type InteractionEntry, InteractionType, type IsoDate, ItdAbortError, ItdAccounts, type ItdAccountsOptions, ItdApiError, type ItdApiErrorInit, ItdApiErrorKind, ItdAuthError, type ItdBuilder, ItdClient, type ItdClientOptions, type ItdClock, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, type ItdFieldErrors, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, type ItdPlugin, ItdRateLimitError, ItdRealtime, ItdServerError, type ItdSession, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, type LazyFile, type LikeResult, LikesVisibility, type Listener, type Logger, type Loose, MAX_RECONNECT_ATTEMPTS, type MarkupBuilder, type MarkupContent, type MarkupInput, type MarkupSpan, MemoryMultiTokenStorage, MemoryTokenStorage, type MultiTokenStorage, type MyProfile, NOTIFICATION_TYPE_ALIASES, type Notification, type NotificationEvent, type NotificationEventOfType, type NotificationListParams, type NotificationOfType, type NotificationSettings, NotificationType, type NotificationsResource, type Page, type PageState, PaginationMode, Paginator, type PaginatorOptions, type ParseMarkupOptions, type PaymentMethod, type PhotoOpenInput, type Pin, type PinPostResult, type PinsResult, type PlatformClientVersion, type PlatformResource, type PlatformStatus, type PlatformVersions, type PluginContext, type PluginTeardown, type Poll, type PollBuilder, type PollInput, type PollOption, type PollTransportOptions, type Portal, type Post, type PostBuilder, type PostInput, type PostStats, type PostUpdateInput, type PostsResource, type PrivacySettings, type Profile, type PublicProfile, type QueryParams, type QueryValue, RECONNECT_BACKOFF, RECONNECT_JITTER, REFRESH_COOKIE, REFRESH_COOKIE_PATH, REQUEST_OPTION_KEYS, type RateLimitOptions, type RateLimitScope, type RawRequestOptions, type RealtimeContext, type RealtimeDeps, type RealtimeEvents, type RealtimeHandler, type RealtimeMiddleware, type RealtimeNext, type RealtimeNotificationContext, type RealtimeNotificationFilter, type RealtimeNotificationSelector, type RealtimeNotificationUpdate, type RealtimeOptions, type RealtimePredicate, type RealtimeRouteSelector, RealtimeRouter, type RealtimeSequentializer, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, type RealtimeTypeGuard, type RealtimeUnknownUpdate, type RealtimeUnreadCountUpdate, type RealtimeUpdate, type RealtimeUpdateOfType, RealtimeUpdateOrigin, RealtimeUpdateType, type ReconnectOptions, type RecordStorageSource, type RemoveAccountOptions, type RenderSpansOptions, type RepliesParams, type Report, type ReportBuilder, type ReportInput, ReportReason, ReportTargetType, type ReportsResource, type RequestContext, type RequestOptions, type ResetPasswordInput, type ResponseContext, type RetryContext, type RetryOptions, RuntimeMode, STATUS_SERVICE, STREAM_PATH, type SearchResource, type SearchResult, type ServiceDefinition, ServiceRegistry, ServiceState, type ServiceStatus, type Session, type SignInResult, SignInStatus, type Span, SpanRenderFormat, SpanType, type SseTransportOptions, type StatusDay, type StatusIncidentLine, type StreamFile, type Subscription, type SubscriptionResource, type SubscriptionState, TURNSTILE_SITE_KEY, type TelemetryBatch, type TelemetryBatchOptions, type TelemetryClock, type TelemetryOptions, type TelemetryResource, type TextMarkup, type TokenStorage, type Transformer, type TransportContext, type TransportEvent, UnauthorizedStreamError, type Unsubscribe, type UpdateNotificationSettingsInput, type UpdatePostInput, type UpdatePrivacyInput, type UpdateProfileInput, type UploadOptions, type UploadedFile, type UrlFile, type UrlFileOptions, type UserId, type UserListParams, type UserPostsParams, type UserRef, type UserSummary, type UsersResource, VIDEO_MIME_TYPES, type VerificationResource, type VerificationStatus, type VideoMimeType, type VideoProgressInput, ViewReason, ViewSource, type ViewTracker, type ViewTrackerInput, type ViewTrackerOptions, WallAccess, autoSpans, canonicalNotificationType, comment, createAccounts, createClient, createMultiTokenStorage, createRecordMultiStorage, createTokenStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, parseHtml, parseMarkdown, poll, post, readNotificationEvent, readUnreadCountEvent, renderSpans, report, resolveNotificationUrl, scopedTokenStorage, statusDays, systemClock, toDate, utcStampToIso };
5217
+ export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AUTH_FLAG_COOKIE, AUTH_PATHS, AccessType, type AccountEvents, type Actor, type AddAccountOptions, type AllowedMimeType, type Announcement, type AnnouncementButton, type Attachment, AttachmentType, type AudioMimeType, type AuthEvents, type AuthIdentity, type AuthInput, type AuthResource, type AuthState, type Author, type AutoSpansOptions, BUILT_IN_SERVICES, type BuilderInput, type CaptchaCredentials, type ChangelogEntry, type Clan, type ClientHooks, type Comment, type CommentBuilder, type CommentInput, type CommentReplyTo, CommentSort, type CommentsParams, type CommentsResource, type CreateCommentInput, type CreatePollInput, type CreatePostData, type CreatePostInput, type CreateReportInput, type Credentials, type CredentialsAuth, DEFAULT_BASE_URL, DEFAULT_FILE_STREAM_BUFFER_BYTES, DEFAULT_STATUS_BASE_URL, DEFAULT_TIMEOUT, DEFAULT_UPLOAD_TIMEOUT, DEFAULT_URL_FILE_MAX_BYTES, DEFAULT_USER_AGENT, DEVICE_ID_HEADER, DetectedRuntime, type DwellEntry, type ErrorContextHook, type FeedParams, FeedTab, type FileContent, type FileContext, type FileInput, type FileStreamContent, type FileStreamOptions, FileTransferMode, type FilesResource, type FollowResult, type ForgotPasswordInput, type FromStreamOptions, type Hashtag, type HashtagPostsParams, type HashtagsResource, IMAGE_MIME_TYPES, type ImageMimeType, IncidentKind, type InteractionEntry, InteractionType, type IsoDate, ItdAbortError, ItdAccounts, type ItdAccountsOptions, ItdApiError, type ItdApiErrorInit, ItdApiErrorKind, ItdAuthError, type ItdBuilder, ItdClient, type ItdClientOptions, type ItdClock, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, type ItdFieldErrors, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, type ItdPlugin, ItdRateLimitError, ItdRealtime, ItdServerError, type ItdSession, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, type LazyFile, type LikeResult, LikesVisibility, type Listener, type Logger, type Loose, MAX_RECONNECT_ATTEMPTS, type MarkupBuilder, type MarkupContent, type MarkupInput, type MarkupSpan, MemoryMultiTokenStorage, MemoryTokenStorage, type MultiTokenStorage, type MyProfile, NOTIFICATION_TYPE_ALIASES, type Notification, type NotificationEvent, type NotificationEventOfType, type NotificationListParams, type NotificationOfType, type NotificationSettings, NotificationType, type NotificationsResource, type Page, type PageState, PaginationMode, Paginator, type PaginatorOptions, type ParseMarkupOptions, type PaymentMethod, type PhotoOpenInput, type Pin, type PinPostResult, type PinsResult, type PlatformClientVersion, type PlatformResource, type PlatformStatus, type PlatformVersions, type PluginContext, type PluginTeardown, type Poll, type PollBuilder, type PollInput, type PollOption, type PollTransportOptions, type Portal, type Post, type PostBuilder, type PostInput, type PostStats, type PostUpdateInput, type PostsResource, type PrivacySettings, type Profile, type PublicProfile, type QueryParams, type QueryValue, RECONNECT_BACKOFF, RECONNECT_JITTER, REFRESH_COOKIE, REFRESH_COOKIE_PATH, REQUEST_OPTION_KEYS, type RateLimitOptions, type RateLimitScope, type RawRequestOptions, type RealtimeContext, type RealtimeDeps, type RealtimeEvents, type RealtimeHandler, type RealtimeMiddleware, type RealtimeNext, type RealtimeNotificationContext, type RealtimeNotificationFilter, type RealtimeNotificationSelector, type RealtimeNotificationUpdate, type RealtimeOptions, type RealtimePredicate, type RealtimeRouteSelector, RealtimeRouter, type RealtimeSequentializer, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, type RealtimeTypeGuard, type RealtimeUnknownUpdate, type RealtimeUnreadCountUpdate, type RealtimeUpdate, type RealtimeUpdateOfType, RealtimeUpdateOrigin, RealtimeUpdateType, type ReconnectOptions, type RecordStorageSource, type RemoveAccountOptions, type RenderSpansOptions, type RepliesParams, type Report, type ReportBuilder, type ReportInput, ReportReason, ReportTargetType, type ReportsResource, type RequestContext, type RequestOptions, type ResetPasswordInput, type ResponseContext, type RetryContext, type RetryOptions, RuntimeMode, STATUS_SERVICE, STREAM_PATH, type SearchResource, type SearchResult, type ServiceDefinition, ServiceRegistry, ServiceState, type ServiceStatus, type Session, type SignInResult, SignInStatus, type Span, SpanRenderFormat, SpanType, type SseTransportOptions, type StatusDay, type StatusIncidentLine, type StreamFile, type Subscription, type SubscriptionResource, type SubscriptionState, TURNSTILE_SITE_KEY, type TelemetryBatch, type TelemetryBatchOptions, type TelemetryClock, type TelemetryOptions, type TelemetryResource, type TextMarkup, type TokenStorage, type Transformer, type TransportContext, type TransportEvent, UnauthorizedStreamError, type Unsubscribe, type UpdateNotificationSettingsInput, type UpdatePostInput, type UpdatePrivacyInput, type UpdateProfileInput, type UploadOptions, type UploadedFile, type UrlFile, type UrlFileOptions, type UserId, type UserListParams, type UserPostsParams, type UserRef, type UserSummary, type UsersResource, VIDEO_MIME_TYPES, type VerificationResource, type VerificationStatus, type VideoMimeType, type VideoProgressInput, ViewReason, ViewSource, type ViewTracker, type ViewTrackerInput, type ViewTrackerOptions, WallAccess, autoSpans, canonicalNotificationType, comment, createAccounts, createClient, createMultiTokenStorage, createRecordMultiStorage, createTokenStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, parseHtml, parseMarkdown, poll, post, readNotificationEvent, readUnreadCountEvent, renderSpans, report, resolveNotificationUrl, scopedTokenStorage, statusDays, systemClock, toDate, utcStampToIso };
5176
5218
  //# sourceMappingURL=index.d.cts.map