itd-api 0.2.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/README.md +8 -6
- package/dist/index.cjs +1220 -588
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1307 -1079
- package/dist/index.d.ts +1307 -1079
- package/dist/index.js +1210 -582
- package/dist/index.js.map +1 -1
- package/dist/{multi-storage-D1keK2Op.cjs → multi-storage-C8R5Crwo.cjs} +33 -219
- package/dist/multi-storage-C8R5Crwo.cjs.map +1 -0
- package/dist/{multi-storage-CyMe404l.js → multi-storage-D4h6QA-w.js} +26 -200
- package/dist/multi-storage-D4h6QA-w.js.map +1 -0
- package/dist/{multi-storage-NDqzRQcD.d.cts → multi-storage-DP_ujJw1.d.cts} +3 -17
- package/dist/{multi-storage-BhcA2Izn.d.ts → multi-storage-DwaIh24p.d.ts} +3 -17
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
- package/dist/multi-storage-CyMe404l.js.map +0 -1
- package/dist/multi-storage-D1keK2Op.cjs.map +0 -1
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,
|
|
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/
|
|
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
|
-
* и передавать дальше без потерь. Для разбора есть
|
|
334
|
+
* и передавать дальше без потерь. Для разбора есть `toDate()`.
|
|
335
335
|
*/
|
|
336
336
|
type IsoDate = string;
|
|
337
337
|
/**
|
|
@@ -371,705 +371,148 @@ interface Span {
|
|
|
371
371
|
/** Идентификатор пользователя у некоторых ответов API с `mention`. */
|
|
372
372
|
id?: string;
|
|
373
373
|
}
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/core/clock.d.ts
|
|
374
376
|
/**
|
|
375
|
-
*
|
|
377
|
+
* Часы, которыми клиент измеряет время и планирует отложенную работу.
|
|
378
|
+
*
|
|
379
|
+
* Своя реализация нужна прежде всего в тестах: она позволяет проверять тайм-ауты,
|
|
380
|
+
* повторы и переподключение без ожидания в реальном времени.
|
|
376
381
|
*/
|
|
377
|
-
interface
|
|
378
|
-
/**
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
|
|
382
|
-
/** Описание, за что выдан. */
|
|
383
|
-
description: string;
|
|
384
|
-
/** Адрес изображения. */
|
|
385
|
-
url: string;
|
|
386
|
-
/** Когда выдан. Приходит только в списке своих пинов. */
|
|
387
|
-
grantedAt?: IsoDate;
|
|
382
|
+
interface ItdClock {
|
|
383
|
+
/** Текущее время в миллисекундах с начала эпохи Unix. */
|
|
384
|
+
now(): number;
|
|
385
|
+
/** Планирует вызов после завершения текущего стека и возвращает функцию отмены. */
|
|
386
|
+
schedule(callback: () => void, delay: number): () => void;
|
|
388
387
|
}
|
|
388
|
+
/** Системные часы, используемые клиентом по умолчанию. */
|
|
389
|
+
declare const systemClock: ItdClock;
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/core/runtime.d.ts
|
|
389
392
|
/**
|
|
390
|
-
*
|
|
393
|
+
* Как библиотека обращается с cookie.
|
|
391
394
|
*
|
|
392
|
-
*
|
|
395
|
+
* - `browser` — cookie ведёт браузер, запросы уходят с `credentials: 'include'`;
|
|
396
|
+
* - `server` — cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную;
|
|
397
|
+
* - `auto` — определяется по среде исполнения (значение по умолчанию).
|
|
393
398
|
*/
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
399
|
+
declare const RuntimeMode: Readonly<{
|
|
400
|
+
/** Определяется по среде исполнения. Значение по умолчанию. */
|
|
401
|
+
readonly Auto: "auto";
|
|
402
|
+
/** Cookie ведёт браузер, запросы уходят с `credentials: 'include'`. */
|
|
403
|
+
readonly Browser: "browser";
|
|
404
|
+
/** Cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную. */
|
|
405
|
+
readonly Server: "server";
|
|
406
|
+
}>;
|
|
407
|
+
type RuntimeMode = (typeof RuntimeMode)[keyof typeof RuntimeMode];
|
|
408
|
+
/** Распознанная среда исполнения. */
|
|
409
|
+
declare const DetectedRuntime: Readonly<{
|
|
410
|
+
readonly Browser: "browser";
|
|
411
|
+
/** Есть `window`, но нет `document`; cookie ведёт нативный сетевой слой. */
|
|
412
|
+
readonly ReactNative: "react-native";
|
|
413
|
+
readonly Server: "server";
|
|
414
|
+
}>;
|
|
415
|
+
type DetectedRuntime = (typeof DetectedRuntime)[keyof typeof DetectedRuntime];
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/core/services.d.ts
|
|
418
|
+
/** Сервис платформы на отдельном домене. */
|
|
419
|
+
interface ServiceDefinition {
|
|
420
|
+
/** Имя, по которому запрос выбирает сервис: `{ service: 'status' }`. */
|
|
421
|
+
name: string;
|
|
422
|
+
/** Базовый URL сервиса. */
|
|
423
|
+
baseUrl: string;
|
|
424
|
+
/** Заголовки, добавляемые к каждому запросу сервиса. Заголовки вызова важнее. */
|
|
425
|
+
headers?: Record<string, string> | undefined;
|
|
398
426
|
/**
|
|
399
|
-
*
|
|
427
|
+
* Слать ли заголовок авторизации.
|
|
400
428
|
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
429
|
+
* По умолчанию включено для основного хоста и его поддоменов. Для остальных хостов
|
|
430
|
+
* авторизацию нужно разрешить явно: `auth: true`.
|
|
403
431
|
*/
|
|
404
|
-
|
|
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;
|
|
432
|
+
auth?: boolean | undefined;
|
|
427
433
|
}
|
|
428
434
|
/**
|
|
429
|
-
*
|
|
435
|
+
* Именованные сервисы клиента.
|
|
430
436
|
*
|
|
431
|
-
*
|
|
432
|
-
* поиск и рекомендации — `followersCount` и `hasNuksta`. Необязательные поля отражают
|
|
433
|
-
* это различие.
|
|
437
|
+
* @internal
|
|
434
438
|
*/
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
/** Состояние подписки на премиум. */
|
|
472
|
-
interface SubscriptionState {
|
|
473
|
-
isActive: boolean;
|
|
474
|
-
expiresAt: IsoDate | null;
|
|
475
|
-
autoRenewal: boolean;
|
|
439
|
+
declare class ServiceRegistry {
|
|
440
|
+
#private;
|
|
441
|
+
/** @param primaryBaseUrl базовый URL клиента */
|
|
442
|
+
constructor(primaryBaseUrl?: string);
|
|
443
|
+
/**
|
|
444
|
+
* Регистрирует сервис. Имя очищается от краевых пробелов, базовый URL приводится
|
|
445
|
+
* к каноничному виду, а незаданный `auth` выводится из хоста.
|
|
446
|
+
*
|
|
447
|
+
* @throws {ItdConfigError} если имя пустое, имя занято или `baseUrl` не абсолютный URL
|
|
448
|
+
*/
|
|
449
|
+
define(definition: ServiceDefinition): void;
|
|
450
|
+
/** Определение сервиса либо `undefined`, если такого нет. */
|
|
451
|
+
get(name: string): ServiceDefinition | undefined;
|
|
452
|
+
/** Зарегистрирован ли сервис с таким именем. */
|
|
453
|
+
has(name: string): boolean;
|
|
454
|
+
/**
|
|
455
|
+
* Определение сервиса.
|
|
456
|
+
*
|
|
457
|
+
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
458
|
+
*/
|
|
459
|
+
require(name: string): ServiceDefinition;
|
|
460
|
+
/**
|
|
461
|
+
* Базовый URL сервиса.
|
|
462
|
+
*
|
|
463
|
+
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
464
|
+
*/
|
|
465
|
+
resolveBaseUrl(name: string): string;
|
|
466
|
+
/**
|
|
467
|
+
* Принадлежит ли URL основному хосту клиента или его поддомену.
|
|
468
|
+
*
|
|
469
|
+
* Используется для безопасного значения по умолчанию у разового `baseUrl`: Bearer-токен
|
|
470
|
+
* не должен уходить на посторонний хост без явного `skipAuth: false`.
|
|
471
|
+
*
|
|
472
|
+
* @internal
|
|
473
|
+
*/
|
|
474
|
+
isPrimarySite(baseUrl: string): boolean;
|
|
476
475
|
}
|
|
476
|
+
//#endregion
|
|
477
|
+
//#region src/core/url.d.ts
|
|
478
|
+
/** Значение параметра запроса. `undefined` и `null` в строку не попадают. */
|
|
479
|
+
type QueryValue = string | number | boolean | null | undefined | readonly (string | number | boolean)[];
|
|
480
|
+
/** Параметры строки запроса. */
|
|
481
|
+
type QueryParams = Record<string, QueryValue>;
|
|
482
|
+
//#endregion
|
|
483
|
+
//#region src/types/options.d.ts
|
|
477
484
|
/**
|
|
478
|
-
*
|
|
485
|
+
* Вход по логину и паролю.
|
|
479
486
|
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
487
|
+
* Вход требует токен капчи Cloudflare Turnstile, поэтому полностью автоматическим он быть
|
|
488
|
+
* не может: капчу должен решить кто-то снаружи. Токен одноразовый и живёт несколько минут,
|
|
489
|
+
* так что долгоживущему клиенту нужен `getTurnstileToken` — он спрашивается заново перед
|
|
490
|
+
* каждой попыткой входа. Одиночный `turnstileToken` годится для разового скрипта.
|
|
482
491
|
*/
|
|
483
|
-
interface
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
|
|
492
|
+
interface CredentialsAuth {
|
|
493
|
+
email: string;
|
|
494
|
+
password: string;
|
|
495
|
+
/** Разовый токен капчи. Для повторного входа после истечения сессии не подойдёт. */
|
|
496
|
+
turnstileToken?: string | undefined;
|
|
497
|
+
/** Источник свежего токена капчи. Спрашивается перед каждым входом. */
|
|
498
|
+
getTurnstileToken?: (() => string | Promise<string>) | undefined;
|
|
490
499
|
}
|
|
491
500
|
/**
|
|
492
|
-
*
|
|
501
|
+
* Как клиент получает доступ к API.
|
|
493
502
|
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
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}`.
|
|
503
|
+
* Четыре формы — от разового вызова с готовым токеном до полноценной сессии, которую
|
|
504
|
+
* библиотека заводит и продлевает сама.
|
|
507
505
|
*
|
|
508
|
-
*
|
|
509
|
-
|
|
510
|
-
|
|
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
|
-
* Свой ли это профиль.
|
|
506
|
+
* Опция необязательна: если {@link ItdClientOptions.storage} уже содержит сессию, доступ
|
|
507
|
+
* берётся оттуда. Когда заданы обе, хранилище главнее — оно отражает текущее состояние
|
|
508
|
+
* сессии, — а недостающие поля берутся отсюда.
|
|
527
509
|
*
|
|
528
510
|
* @example
|
|
529
511
|
* ```ts
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
|
|
533
|
-
|
|
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
|
-
//#endregion
|
|
948
|
-
//#region src/core/runtime.d.ts
|
|
949
|
-
/**
|
|
950
|
-
* Как библиотека обращается с cookie.
|
|
951
|
-
*
|
|
952
|
-
* - `browser` — cookie ведёт браузер, запросы уходят с `credentials: 'include'`;
|
|
953
|
-
* - `server` — cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную;
|
|
954
|
-
* - `auto` — определяется по среде исполнения (значение по умолчанию).
|
|
955
|
-
*/
|
|
956
|
-
declare const RuntimeMode: Readonly<{
|
|
957
|
-
/** Определяется по среде исполнения. Значение по умолчанию. */
|
|
958
|
-
readonly Auto: "auto";
|
|
959
|
-
/** Cookie ведёт браузер, запросы уходят с `credentials: 'include'`. */
|
|
960
|
-
readonly Browser: "browser";
|
|
961
|
-
/** Cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную. */
|
|
962
|
-
readonly Server: "server";
|
|
963
|
-
}>;
|
|
964
|
-
type RuntimeMode = (typeof RuntimeMode)[keyof typeof RuntimeMode];
|
|
965
|
-
/** Распознанная среда исполнения. */
|
|
966
|
-
declare const DetectedRuntime: Readonly<{
|
|
967
|
-
readonly Browser: "browser";
|
|
968
|
-
/** Есть `window`, но нет `document`; cookie ведёт нативный сетевой слой. */
|
|
969
|
-
readonly ReactNative: "react-native";
|
|
970
|
-
readonly Server: "server";
|
|
971
|
-
}>;
|
|
972
|
-
type DetectedRuntime = (typeof DetectedRuntime)[keyof typeof DetectedRuntime];
|
|
973
|
-
//#endregion
|
|
974
|
-
//#region src/core/services.d.ts
|
|
975
|
-
/** Сервис платформы на отдельном домене. */
|
|
976
|
-
interface ServiceDefinition {
|
|
977
|
-
/** Имя, по которому запрос выбирает сервис: `{ service: 'status' }`. */
|
|
978
|
-
name: string;
|
|
979
|
-
/** Базовый URL сервиса. */
|
|
980
|
-
baseUrl: string;
|
|
981
|
-
/** Заголовки, добавляемые к каждому запросу сервиса. Заголовки вызова важнее. */
|
|
982
|
-
headers?: Record<string, string> | undefined;
|
|
983
|
-
/**
|
|
984
|
-
* Слать ли заголовок авторизации.
|
|
985
|
-
*
|
|
986
|
-
* По умолчанию включено для основного хоста и его поддоменов. Для остальных хостов
|
|
987
|
-
* авторизацию нужно разрешить явно: `auth: true`.
|
|
988
|
-
*/
|
|
989
|
-
auth?: boolean | undefined;
|
|
990
|
-
}
|
|
991
|
-
/**
|
|
992
|
-
* Именованные сервисы клиента.
|
|
993
|
-
*
|
|
994
|
-
* @internal
|
|
995
|
-
*/
|
|
996
|
-
declare class ServiceRegistry {
|
|
997
|
-
#private;
|
|
998
|
-
/** @param primaryBaseUrl базовый URL клиента */
|
|
999
|
-
constructor(primaryBaseUrl?: string);
|
|
1000
|
-
/**
|
|
1001
|
-
* Регистрирует сервис. Имя очищается от краевых пробелов, базовый URL приводится
|
|
1002
|
-
* к каноничному виду, а незаданный `auth` выводится из хоста.
|
|
1003
|
-
*
|
|
1004
|
-
* @throws {ItdConfigError} если имя пустое, имя занято или `baseUrl` не абсолютный URL
|
|
1005
|
-
*/
|
|
1006
|
-
define(definition: ServiceDefinition): void;
|
|
1007
|
-
/** Определение сервиса либо `undefined`, если такого нет. */
|
|
1008
|
-
get(name: string): ServiceDefinition | undefined;
|
|
1009
|
-
/** Зарегистрирован ли сервис с таким именем. */
|
|
1010
|
-
has(name: string): boolean;
|
|
1011
|
-
/**
|
|
1012
|
-
* Определение сервиса.
|
|
1013
|
-
*
|
|
1014
|
-
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
1015
|
-
*/
|
|
1016
|
-
require(name: string): ServiceDefinition;
|
|
1017
|
-
/**
|
|
1018
|
-
* Базовый URL сервиса.
|
|
1019
|
-
*
|
|
1020
|
-
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
1021
|
-
*/
|
|
1022
|
-
resolveBaseUrl(name: string): string;
|
|
1023
|
-
/**
|
|
1024
|
-
* Принадлежит ли URL основному хосту клиента или его поддомену.
|
|
1025
|
-
*
|
|
1026
|
-
* Используется для безопасного значения по умолчанию у разового `baseUrl`: Bearer-токен
|
|
1027
|
-
* не должен уходить на посторонний хост без явного `skipAuth: false`.
|
|
1028
|
-
*
|
|
1029
|
-
* @internal
|
|
1030
|
-
*/
|
|
1031
|
-
isPrimarySite(baseUrl: string): boolean;
|
|
1032
|
-
}
|
|
1033
|
-
//#endregion
|
|
1034
|
-
//#region src/core/url.d.ts
|
|
1035
|
-
/** Значение параметра запроса. `undefined` и `null` в строку не попадают. */
|
|
1036
|
-
type QueryValue = string | number | boolean | null | undefined | readonly (string | number | boolean)[];
|
|
1037
|
-
/** Параметры строки запроса. */
|
|
1038
|
-
type QueryParams = Record<string, QueryValue>;
|
|
1039
|
-
//#endregion
|
|
1040
|
-
//#region src/types/options.d.ts
|
|
1041
|
-
/**
|
|
1042
|
-
* Вход по логину и паролю.
|
|
1043
|
-
*
|
|
1044
|
-
* Вход требует токен капчи Cloudflare Turnstile, поэтому полностью автоматическим он быть
|
|
1045
|
-
* не может: капчу должен решить кто-то снаружи. Токен одноразовый и живёт несколько минут,
|
|
1046
|
-
* так что долгоживущему клиенту нужен `getTurnstileToken` — он спрашивается заново перед
|
|
1047
|
-
* каждой попыткой входа. Одиночный `turnstileToken` годится для разового скрипта.
|
|
1048
|
-
*/
|
|
1049
|
-
interface CredentialsAuth {
|
|
1050
|
-
email: string;
|
|
1051
|
-
password: string;
|
|
1052
|
-
/** Разовый токен капчи. Для повторного входа после истечения сессии не подойдёт. */
|
|
1053
|
-
turnstileToken?: string | undefined;
|
|
1054
|
-
/** Источник свежего токена капчи. Спрашивается перед каждым входом. */
|
|
1055
|
-
getTurnstileToken?: (() => string | Promise<string>) | undefined;
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Как клиент получает доступ к API.
|
|
1059
|
-
*
|
|
1060
|
-
* Четыре формы — от разового вызова с готовым токеном до полноценной сессии, которую
|
|
1061
|
-
* библиотека заводит и продлевает сама.
|
|
1062
|
-
*
|
|
1063
|
-
* Опция необязательна: если {@link ItdClientOptions.storage} уже содержит сессию, доступ
|
|
1064
|
-
* берётся оттуда. Когда заданы обе, хранилище главнее — оно отражает текущее состояние
|
|
1065
|
-
* сессии, — а недостающие поля берутся отсюда.
|
|
1066
|
-
*
|
|
1067
|
-
* @example
|
|
1068
|
-
* ```ts
|
|
1069
|
-
* new ItdClient({ auth: '<accessToken>' }); // разовый вызов
|
|
1070
|
-
* new ItdClient({ auth: { accessToken, refreshToken } }); // восстановить сессию
|
|
1071
|
-
* new ItdClient({ auth: { email, password, getTurnstileToken } }); // залогиниться самому
|
|
1072
|
-
* new ItdClient({ auth: { getToken: () => vault.read() } }); // токен из внешнего источника
|
|
512
|
+
* new ItdClient({ auth: '<accessToken>' }); // разовый вызов
|
|
513
|
+
* new ItdClient({ auth: { accessToken, refreshToken } }); // восстановить сессию
|
|
514
|
+
* new ItdClient({ auth: { email, password, getTurnstileToken } }); // залогиниться самому
|
|
515
|
+
* new ItdClient({ auth: { getToken: () => vault.read() } }); // токен из внешнего источника
|
|
1073
516
|
* ```
|
|
1074
517
|
*/
|
|
1075
518
|
type AuthInput = string | {
|
|
@@ -1227,6 +670,8 @@ interface ItdClientOptions {
|
|
|
1227
670
|
reloginOnRefreshFailure?: boolean | undefined;
|
|
1228
671
|
/** Своя реализация `fetch`: для Deno, React Native, тестов или прокси. */
|
|
1229
672
|
fetch?: typeof fetch | undefined;
|
|
673
|
+
/** Часы для тайм-аутов, повторов и очередей. Обычно подменяются только в тестах. */
|
|
674
|
+
clock?: ItdClock | undefined;
|
|
1230
675
|
/** Таймаут запроса в мс. По умолчанию 30000 — столько же использует сайт итд.com. `0` снимает ограничение. */
|
|
1231
676
|
timeout?: number | undefined;
|
|
1232
677
|
/** Повторные попытки. `false` отключает их полностью. */
|
|
@@ -1326,7 +771,7 @@ interface RawRequestOptions extends RequestOptions {
|
|
|
1326
771
|
//#endregion
|
|
1327
772
|
//#region src/core/version.d.ts
|
|
1328
773
|
/** Версия библиотеки. Попадает в `User-Agent`. */
|
|
1329
|
-
declare const LIBRARY_VERSION = "0.
|
|
774
|
+
declare const LIBRARY_VERSION = "0.4.0";
|
|
1330
775
|
//#endregion
|
|
1331
776
|
//#region src/core/config.d.ts
|
|
1332
777
|
/** Базовый URL API итд.com. Домен записан в punycode: `итд.com`. */
|
|
@@ -1349,7 +794,7 @@ declare const DEFAULT_TIMEOUT = 30000;
|
|
|
1349
794
|
* В браузере заголовок не выставляется — `User-Agent` там запрещён к изменению, и среда
|
|
1350
795
|
* молча его игнорирует.
|
|
1351
796
|
*/
|
|
1352
|
-
declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; itd-api/0.
|
|
797
|
+
declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; itd-api/0.4.0; +https://github.com/KiowDev/itd-api)";
|
|
1353
798
|
/** Настройки очереди со всеми значениями по умолчанию. */
|
|
1354
799
|
interface ResolvedRateLimitOptions {
|
|
1355
800
|
concurrency: number;
|
|
@@ -1366,6 +811,7 @@ interface ResolvedRateLimitOptions {
|
|
|
1366
811
|
*/
|
|
1367
812
|
interface AuthConfig {
|
|
1368
813
|
baseUrl: string;
|
|
814
|
+
clock: ItdClock;
|
|
1369
815
|
auth: AuthInput | undefined;
|
|
1370
816
|
storage: TokenStorage;
|
|
1371
817
|
useCookieJar: boolean;
|
|
@@ -1672,242 +1118,427 @@ declare class AuthManager {
|
|
|
1672
1118
|
/** Текущая сессия целиком. Полезно, чтобы сохранить её самому. */
|
|
1673
1119
|
getSession(): Promise<ItdSession | null>;
|
|
1674
1120
|
/**
|
|
1675
|
-
* Идентификатор владельца сессии.
|
|
1121
|
+
* Идентификатор владельца сессии.
|
|
1122
|
+
*
|
|
1123
|
+
* Считается непосредственно из текущего токена и отдельно не сохраняется: после замены
|
|
1124
|
+
* токена идентификатор прежнего владельца остаться не может.
|
|
1125
|
+
*/
|
|
1126
|
+
getUserId(): Promise<UserId | undefined>;
|
|
1127
|
+
/** Заменяет сессию и связанные с ней cookie целиком. */
|
|
1128
|
+
setSession(session: ItdSession): Promise<void>;
|
|
1129
|
+
/**
|
|
1130
|
+
* Забывает сессию и cookie. Сетевой запрос не выполняется.
|
|
1131
|
+
*
|
|
1132
|
+
* Идентификатор устройства выход переживает: иначе каждая пара «выход — вход» плодила бы
|
|
1133
|
+
* новую запись в списке сессий.
|
|
1134
|
+
*/
|
|
1135
|
+
clear(): Promise<void>;
|
|
1136
|
+
}
|
|
1137
|
+
//#endregion
|
|
1138
|
+
//#region src/core/plugins/contracts.d.ts
|
|
1139
|
+
/**
|
|
1140
|
+
* Обёртка вокруг запроса.
|
|
1141
|
+
*
|
|
1142
|
+
* Получает описание запроса и продолжение цепочки. Может изменить запрос перед отправкой,
|
|
1143
|
+
* посмотреть и подменить разобранный ответ или вовсе не вызывать `next` и вернуть своё.
|
|
1144
|
+
*
|
|
1145
|
+
* @param request что уходит на сервер; изменять сам объект не нужно — передайте копию в `next`
|
|
1146
|
+
* @param next продолжение: либо следующая обёртка, либо настоящий запрос
|
|
1147
|
+
* @returns тело ответа в том виде, в каком его получит вызывающий код
|
|
1148
|
+
*
|
|
1149
|
+
* @example Дописать заголовок ко всем запросам
|
|
1150
|
+
* ```ts
|
|
1151
|
+
* const transformer: Transformer = (request, next) =>
|
|
1152
|
+
* next({ ...request, headers: { ...request.headers, 'X-Trace': trace() } });
|
|
1153
|
+
* ```
|
|
1154
|
+
*/
|
|
1155
|
+
type Transformer = (request: RawRequestOptions, next: (request: RawRequestOptions) => Promise<unknown>) => Promise<unknown>;
|
|
1156
|
+
/** Освобождение ресурсов, заведённых плагином при установке. */
|
|
1157
|
+
type PluginTeardown = () => void | Promise<void>;
|
|
1158
|
+
/** Что плагин получает при подключении. */
|
|
1159
|
+
interface PluginContext {
|
|
1160
|
+
/** Базовый URL клиента — например чтобы разобрать абсолютные ссылки из ответа. */
|
|
1161
|
+
baseUrl: string;
|
|
1162
|
+
/** Отладочный вывод клиента, если он включён. */
|
|
1163
|
+
logger: Logger | undefined;
|
|
1164
|
+
/**
|
|
1165
|
+
* Непрозрачная fallback-область текущей авторизации.
|
|
1166
|
+
*
|
|
1167
|
+
* Нужна плагинам, которые обязаны безопасно изолировать непрозрачный токен. Для объединения
|
|
1168
|
+
* состояния копий одного аккаунта используйте {@link getAuthIdentity}.
|
|
1169
|
+
*/
|
|
1170
|
+
getAuthScope?: (() => string) | undefined;
|
|
1171
|
+
/**
|
|
1172
|
+
* Загружает сессию и возвращает идентификаторы аккаунта и конкретной сессии из JWT.
|
|
1173
|
+
*
|
|
1174
|
+
* Предпочтительнее {@link getAuthScope} для состояния, которое должно объединяться между
|
|
1175
|
+
* несколькими экземплярами клиента одного аккаунта.
|
|
1176
|
+
*/
|
|
1177
|
+
getAuthIdentity?: (() => Promise<AuthIdentity>) | undefined;
|
|
1178
|
+
/** Добавляет обёртку запроса. Подключённые раньше оказываются снаружи. */
|
|
1179
|
+
use(transformer: Transformer): void;
|
|
1180
|
+
/**
|
|
1181
|
+
* Добавляет перехватчики отдельных сетевых попыток.
|
|
1182
|
+
*
|
|
1183
|
+
* В отличие от {@link use}, они видят каждый retry и сырой `Response` до чтения тела.
|
|
1184
|
+
* Несколько наборов хуков одного плагина вызываются в порядке регистрации.
|
|
1185
|
+
*/
|
|
1186
|
+
useHooks(hooks: ClientHooks): void;
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* Плагин клиента.
|
|
1190
|
+
*
|
|
1191
|
+
* Подключается через `itd.use(plugin)` и работает на уровне транспорта: видит запрос
|
|
1192
|
+
* до отправки и разобранный ответ. Библиотека не знает, что именно делает плагин, —
|
|
1193
|
+
* ей достаточно списка обёрток и имён опций, которые он читает.
|
|
1194
|
+
*
|
|
1195
|
+
* @example
|
|
1196
|
+
* ```ts
|
|
1197
|
+
* const logging: ItdPlugin = {
|
|
1198
|
+
* name: 'logging',
|
|
1199
|
+
* install({ use, logger }) {
|
|
1200
|
+
* use(async (request, next) => {
|
|
1201
|
+
* logger?.info(`${request.method} ${request.path}`);
|
|
1202
|
+
* return next(request);
|
|
1203
|
+
* });
|
|
1204
|
+
* },
|
|
1205
|
+
* };
|
|
1206
|
+
*
|
|
1207
|
+
* itd.use(logging);
|
|
1208
|
+
* ```
|
|
1209
|
+
*/
|
|
1210
|
+
interface ItdPlugin {
|
|
1211
|
+
/** Имя плагина. Должно быть уникальным: повторное подключение — ошибка. */
|
|
1212
|
+
name: string;
|
|
1213
|
+
/**
|
|
1214
|
+
* Имена опций запроса, которые плагин читает у методов ресурсов.
|
|
1676
1215
|
*
|
|
1677
|
-
*
|
|
1678
|
-
*
|
|
1216
|
+
* Библиотека этих опций не понимает и ничего с ними не делает — только доносит
|
|
1217
|
+
* от вызова метода до обёртки нетронутыми. Без такого списка чужие поля отсеиваются,
|
|
1218
|
+
* чтобы случайная опечатка в параметрах не уезжала на сервер.
|
|
1219
|
+
*
|
|
1220
|
+
* Имена полей самого запроса (`path`, `body`, `headers`, `signal` и прочие из
|
|
1221
|
+
* `RawRequestOptions`) заявить нельзя: подключение такого плагина завершится ошибкой.
|
|
1222
|
+
*
|
|
1223
|
+
* Типы для них плагин объявляет сам, дополняя `RequestOptions`:
|
|
1224
|
+
* ```ts
|
|
1225
|
+
* declare module 'itd-api' {
|
|
1226
|
+
* interface RequestOptions { encrypt?: string | undefined }
|
|
1227
|
+
* }
|
|
1228
|
+
* ```
|
|
1679
1229
|
*/
|
|
1680
|
-
|
|
1681
|
-
/**
|
|
1682
|
-
|
|
1230
|
+
optionKeys?: readonly string[];
|
|
1231
|
+
/** Плагины, которые обязаны быть подключены раньше этого. */
|
|
1232
|
+
requires?: readonly string[];
|
|
1233
|
+
/** Несовместимые плагины. Достаточно объявить конфликт с одной стороны. */
|
|
1234
|
+
conflicts?: readonly string[];
|
|
1235
|
+
/** Имена плагинов, снаружи которых должна стоять эта обёртка. */
|
|
1236
|
+
before?: readonly string[];
|
|
1237
|
+
/** Имена плагинов, внутри которых должна стоять эта обёртка. */
|
|
1238
|
+
after?: readonly string[];
|
|
1683
1239
|
/**
|
|
1684
|
-
*
|
|
1240
|
+
* Устанавливает плагин.
|
|
1685
1241
|
*
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
1242
|
+
* Может вернуть функцию освобождения ресурсов. Она вызывается при `unuse()` или
|
|
1243
|
+
* окончательном `dispose()` клиента и может быть асинхронной.
|
|
1688
1244
|
*/
|
|
1689
|
-
|
|
1245
|
+
install(context: PluginContext): unknown;
|
|
1690
1246
|
}
|
|
1691
1247
|
//#endregion
|
|
1692
|
-
//#region src/core/
|
|
1248
|
+
//#region src/core/rate-limit.d.ts
|
|
1693
1249
|
/**
|
|
1694
|
-
*
|
|
1250
|
+
* Очередь запросов: ограничивает одновременность и частоту.
|
|
1695
1251
|
*
|
|
1696
|
-
*
|
|
1697
|
-
*
|
|
1252
|
+
* Нужна прежде всего ботам: без неё цикл по сотне постов уходит в API одним залпом
|
|
1253
|
+
* и упирается в `RATE_LIMIT_EXCEEDED`.
|
|
1698
1254
|
*
|
|
1699
|
-
*
|
|
1700
|
-
*
|
|
1701
|
-
* @returns тело ответа в том виде, в каком его получит вызывающий код
|
|
1255
|
+
* Частота выдерживается равномерным разносом стартов (`1000 / rps` между запросами),
|
|
1256
|
+
* а не окном со счётчиком: так нагрузка ровная, без всплеска в начале каждой секунды.
|
|
1702
1257
|
*
|
|
1703
|
-
* @
|
|
1704
|
-
* ```ts
|
|
1705
|
-
* const transformer: Transformer = (request, next) =>
|
|
1706
|
-
* next({ ...request, headers: { ...request.headers, 'X-Trace': trace() } });
|
|
1707
|
-
* ```
|
|
1258
|
+
* @internal
|
|
1708
1259
|
*/
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
/**
|
|
1713
|
-
|
|
1714
|
-
/**
|
|
1715
|
-
|
|
1716
|
-
/** Отладочный вывод клиента, если он включён. */
|
|
1717
|
-
logger: Logger | undefined;
|
|
1260
|
+
declare class RequestQueue {
|
|
1261
|
+
#private;
|
|
1262
|
+
constructor(options: ResolvedRateLimitOptions, clock?: ItdClock);
|
|
1263
|
+
/** Сколько задач выполняется прямо сейчас. */
|
|
1264
|
+
get active(): number;
|
|
1265
|
+
/** Сколько задач ждёт очереди. */
|
|
1266
|
+
get pending(): number;
|
|
1718
1267
|
/**
|
|
1719
|
-
*
|
|
1268
|
+
* Ставит задачу в очередь.
|
|
1720
1269
|
*
|
|
1721
|
-
*
|
|
1722
|
-
* состояния копий одного аккаунта используйте {@link getAuthIdentity}.
|
|
1270
|
+
* @returns результат задачи; ошибка задачи пробрасывается без изменений
|
|
1723
1271
|
*/
|
|
1724
|
-
|
|
1272
|
+
schedule<T>(task: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
1725
1273
|
/**
|
|
1726
|
-
*
|
|
1274
|
+
* Останавливает очередь: снимает отложенную паузу и отклоняет ещё не начатые задачи
|
|
1275
|
+
* ошибкой `ItdAbortError`. Уже выполняющиеся задачи доводятся до конца.
|
|
1276
|
+
*/
|
|
1277
|
+
stop(): void;
|
|
1278
|
+
/**
|
|
1279
|
+
* Придерживает всю очередь на заданное время.
|
|
1727
1280
|
*
|
|
1728
|
-
*
|
|
1729
|
-
*
|
|
1281
|
+
* Вызывается при получении `429` с заголовком `Retry-After`: тормозить нужно все запросы,
|
|
1282
|
+
* а не только тот, который наткнулся на лимит, — иначе остальные продолжат добивать API.
|
|
1730
1283
|
*/
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
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;
|
|
1734
1323
|
/**
|
|
1735
|
-
*
|
|
1324
|
+
* **Эмодзи, а не картинка.**
|
|
1736
1325
|
*
|
|
1737
|
-
*
|
|
1738
|
-
*
|
|
1326
|
+
* На итд.com аватар — это символ клана (`🩵`, `🦎`), а не адрес изображения.
|
|
1327
|
+
* Отрисовывать его нужно как текст.
|
|
1739
1328
|
*/
|
|
1740
|
-
|
|
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;
|
|
1741
1458
|
}
|
|
1742
1459
|
/**
|
|
1743
|
-
*
|
|
1744
|
-
*
|
|
1745
|
-
* Подключается через `itd.use(plugin)` и работает на уровне транспорта: видит запрос
|
|
1746
|
-
* до отправки и разобранный ответ. Библиотека не знает, что именно делает плагин, —
|
|
1747
|
-
* ей достаточно списка обёрток и имён опций, которые он читает.
|
|
1460
|
+
* Результат подписки на пользователя.
|
|
1748
1461
|
*
|
|
1749
1462
|
* @example
|
|
1750
1463
|
* ```ts
|
|
1751
|
-
* const
|
|
1752
|
-
*
|
|
1753
|
-
* install({ use, logger }) {
|
|
1754
|
-
* use(async (request, next) => {
|
|
1755
|
-
* logger?.info(`${request.method} ${request.path}`);
|
|
1756
|
-
* return next(request);
|
|
1757
|
-
* });
|
|
1758
|
-
* },
|
|
1759
|
-
* };
|
|
1760
|
-
*
|
|
1761
|
-
* itd.use(logging);
|
|
1464
|
+
* const result = await itd.users.follow('nowkie');
|
|
1465
|
+
* // { following: true, followersCount: 11 }
|
|
1762
1466
|
* ```
|
|
1763
1467
|
*/
|
|
1764
|
-
interface
|
|
1765
|
-
/**
|
|
1766
|
-
|
|
1767
|
-
/**
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
* от вызова метода до обёртки нетронутыми. Без такого списка чужие поля отсеиваются,
|
|
1772
|
-
* чтобы случайная опечатка в параметрах не уезжала на сервер.
|
|
1773
|
-
*
|
|
1774
|
-
* Имена полей самого запроса (`path`, `body`, `headers`, `signal` и прочие из
|
|
1775
|
-
* `RawRequestOptions`) заявить нельзя: подключение такого плагина завершится ошибкой.
|
|
1776
|
-
*
|
|
1777
|
-
* Типы для них плагин объявляет сам, дополняя `RequestOptions`:
|
|
1778
|
-
* ```ts
|
|
1779
|
-
* declare module 'itd-api' {
|
|
1780
|
-
* interface RequestOptions { encrypt?: string | undefined }
|
|
1781
|
-
* }
|
|
1782
|
-
* ```
|
|
1783
|
-
*/
|
|
1784
|
-
optionKeys?: readonly string[];
|
|
1785
|
-
/** Плагины, которые обязаны быть подключены раньше этого. */
|
|
1786
|
-
requires?: readonly string[];
|
|
1787
|
-
/** Несовместимые плагины. Достаточно объявить конфликт с одной стороны. */
|
|
1788
|
-
conflicts?: readonly string[];
|
|
1789
|
-
/** Имена плагинов, снаружи которых должна стоять эта обёртка. */
|
|
1790
|
-
before?: readonly string[];
|
|
1791
|
-
/** Имена плагинов, внутри которых должна стоять эта обёртка. */
|
|
1792
|
-
after?: readonly string[];
|
|
1793
|
-
/**
|
|
1794
|
-
* Устанавливает плагин.
|
|
1795
|
-
*
|
|
1796
|
-
* Может вернуть функцию освобождения ресурсов. Она вызывается при `unuse()` или
|
|
1797
|
-
* окончательном `dispose()` клиента и может быть асинхронной.
|
|
1798
|
-
*/
|
|
1799
|
-
install(context: PluginContext): unknown;
|
|
1468
|
+
interface FollowResult {
|
|
1469
|
+
/** Подписка оформлена. У закрытого профиля отправляется заявка, и здесь будет `false`. */
|
|
1470
|
+
following: boolean;
|
|
1471
|
+
/** Сколько подписчиков стало у пользователя после действия. */
|
|
1472
|
+
followersCount?: number;
|
|
1473
|
+
/** Статус заявки, если профиль закрыт. */
|
|
1474
|
+
status?: Loose<'following' | 'requested'>;
|
|
1800
1475
|
}
|
|
1801
|
-
/**
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
*/
|
|
1807
|
-
declare class PluginRegistry {
|
|
1808
|
-
#private;
|
|
1809
|
-
/** Сколько плагинов подключено. */
|
|
1810
|
-
get size(): number;
|
|
1811
|
-
/** Имена опций активных плагинов. */
|
|
1812
|
-
get optionKeys(): ReadonlySet<string>;
|
|
1813
|
-
/** Имена плагинов в фактическом порядке выполнения. */
|
|
1814
|
-
names(): string[];
|
|
1815
|
-
/** Подключён ли плагин с таким именем. */
|
|
1816
|
-
has(name: string): boolean;
|
|
1817
|
-
/** Проверяет добавление без вызова `install()`. @internal */
|
|
1818
|
-
assertCanAdd(plugin: ItdPlugin): void;
|
|
1819
|
-
/** Проверяет удаление без изменения реестра. @internal */
|
|
1820
|
-
assertCanRemove(name: string): void;
|
|
1821
|
-
/**
|
|
1822
|
-
* Подключает плагин.
|
|
1823
|
-
*
|
|
1824
|
-
* @throws {ItdConfigError} если плагин задан неверно, уже подключён, нарушает зависимости
|
|
1825
|
-
* или заявил занятое имя опции
|
|
1826
|
-
*/
|
|
1827
|
-
add(plugin: ItdPlugin, context: Omit<PluginContext, 'use' | 'useHooks'>): void;
|
|
1828
|
-
/**
|
|
1829
|
-
* Отключает плагин и вызывает его функцию очистки.
|
|
1830
|
-
*
|
|
1831
|
-
* Новые запросы перестают видеть плагин сразу. Если его обёртка уже выполняется,
|
|
1832
|
-
* очистка дождётся завершения этого логического запроса.
|
|
1833
|
-
*
|
|
1834
|
-
* @returns `false`, если такого плагина не было
|
|
1835
|
-
*/
|
|
1836
|
-
remove(name: string): Promise<boolean>;
|
|
1837
|
-
/**
|
|
1838
|
-
* Отключает все плагины окончательно.
|
|
1839
|
-
*
|
|
1840
|
-
* Очистка идёт изнутри наружу — в порядке, обратном выполнению обёрток.
|
|
1841
|
-
*/
|
|
1842
|
-
dispose(): Promise<void>;
|
|
1843
|
-
/**
|
|
1844
|
-
* Объединяет конструкторские хуки с хуками подключаемых плагинов.
|
|
1845
|
-
*
|
|
1846
|
-
* Возвращённый объект динамический: подключение и отключение плагина начинает действовать
|
|
1847
|
-
* со следующего логического запроса без пересоздания транспорта.
|
|
1848
|
-
*/
|
|
1849
|
-
hooks(base: ClientHooks): ClientHooks;
|
|
1850
|
-
/**
|
|
1851
|
-
* Прогоняет запрос через цепочку обёрток.
|
|
1852
|
-
*
|
|
1853
|
-
* Снимок цепочки берётся в начале: `unuse()` влияет на новые запросы, но не обрывает
|
|
1854
|
-
* уже выполняющийся посередине.
|
|
1855
|
-
*
|
|
1856
|
-
* @param execute настоящий запрос, вызывается самой внутренней обёрткой
|
|
1857
|
-
*/
|
|
1858
|
-
run(request: RawRequestOptions, execute: (request: RawRequestOptions) => Promise<unknown>): Promise<unknown>;
|
|
1476
|
+
/** Закреплённые значки профиля и выбранный из них. */
|
|
1477
|
+
interface PinsResult {
|
|
1478
|
+
pins: Pin[];
|
|
1479
|
+
/** Идентификатор активного значка — строка, а не объект. */
|
|
1480
|
+
activePin: string | null;
|
|
1859
1481
|
}
|
|
1860
1482
|
//#endregion
|
|
1861
|
-
//#region src/
|
|
1483
|
+
//#region src/models/notifications.d.ts
|
|
1862
1484
|
/**
|
|
1863
|
-
*
|
|
1864
|
-
*
|
|
1865
|
-
* Нужна прежде всего ботам: без неё цикл по сотне постов уходит в API одним залпом
|
|
1866
|
-
* и упирается в `RATE_LIMIT_EXCEEDED`.
|
|
1485
|
+
* Уведомление в единой форме.
|
|
1867
1486
|
*
|
|
1868
|
-
*
|
|
1869
|
-
*
|
|
1487
|
+
* REST-список и SSE-поток отдают уведомления по-разному — разные имена типов, разные имена
|
|
1488
|
+
* полей, один участник против массива. Библиотека приводит оба вида к этой структуре,
|
|
1489
|
+
* поэтому объекты из `itd.notifications.list()` и из потока можно складывать в один список.
|
|
1870
1490
|
*
|
|
1871
|
-
* @
|
|
1491
|
+
* Исходные данные не теряются: серверное имя типа остаётся в {@link rawType},
|
|
1492
|
+
* а весь необработанный объект — в {@link raw}.
|
|
1872
1493
|
*/
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
/**
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
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;
|
|
1898
1519
|
}
|
|
1899
1520
|
/**
|
|
1900
|
-
*
|
|
1521
|
+
* Настройки уведомлений.
|
|
1901
1522
|
*
|
|
1902
|
-
*
|
|
1523
|
+
* Сервер отдаёт плоский объект, но исторически знает два набора имён для одних и тех же
|
|
1524
|
+
* настроек (`likes` и `reactions`, `comments` и `replies`). При сохранении библиотека
|
|
1525
|
+
* отправляет оба, при чтении принимает любой.
|
|
1903
1526
|
*/
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
/**
|
|
1908
|
-
|
|
1909
|
-
/**
|
|
1910
|
-
|
|
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;
|
|
1911
1542
|
}
|
|
1912
1543
|
//#endregion
|
|
1913
1544
|
//#region src/notifications/normalize.d.ts
|
|
@@ -1952,39 +1583,13 @@ declare function normalizeNotification(input: unknown): Notification;
|
|
|
1952
1583
|
* Кроме самого уведомления событие несёт служебные поля уровня конверта: актуальный
|
|
1953
1584
|
* счётчик непрочитанных и признак звука.
|
|
1954
1585
|
*/
|
|
1955
|
-
declare function readNotificationEvent(data: unknown): NotificationEvent;
|
|
1956
|
-
/**
|
|
1957
|
-
* Разбирает событие `unread_count` из потока.
|
|
1958
|
-
*
|
|
1959
|
-
* Возвращает `undefined`, если сервер прислал событие без вложенного `payload`.
|
|
1960
|
-
*/
|
|
1961
|
-
declare function readUnreadCountEvent(data: unknown): number | undefined;
|
|
1962
|
-
//#endregion
|
|
1963
|
-
//#region src/realtime/reconnect.d.ts
|
|
1964
|
-
/**
|
|
1965
|
-
* Паузы перед попытками переподключения, мс.
|
|
1966
|
-
*
|
|
1967
|
-
* Значения совпадают с теми, что использует сайт итд.com, — поведение библиотеки
|
|
1968
|
-
* не отличается от привычного пользователю.
|
|
1969
|
-
*/
|
|
1970
|
-
declare const RECONNECT_BACKOFF: readonly number[];
|
|
1971
|
-
/** Доля случайного разброса паузы. */
|
|
1972
|
-
declare const RECONNECT_JITTER = 0.3;
|
|
1973
|
-
/**
|
|
1974
|
-
* Сколько раз пытаться переподключиться подряд.
|
|
1975
|
-
*
|
|
1976
|
-
* После исчерпания поток сообщает `giveup` и ждёт ручного `connect()`.
|
|
1977
|
-
*/
|
|
1978
|
-
declare const MAX_RECONNECT_ATTEMPTS = 15;
|
|
1979
|
-
/** Настройки переподключения. */
|
|
1980
|
-
interface ReconnectOptions {
|
|
1981
|
-
/** Таблица пауз. Последнее значение действует для всех дальнейших попыток. */
|
|
1982
|
-
backoff?: readonly number[];
|
|
1983
|
-
/** Доля разброса, 0…1. */
|
|
1984
|
-
jitter?: number;
|
|
1985
|
-
/** Предел числа попыток. */
|
|
1986
|
-
maxAttempts?: number;
|
|
1987
|
-
}
|
|
1586
|
+
declare function readNotificationEvent(data: unknown): NotificationEvent;
|
|
1587
|
+
/**
|
|
1588
|
+
* Разбирает событие `unread_count` из потока.
|
|
1589
|
+
*
|
|
1590
|
+
* Возвращает `undefined`, если сервер прислал событие без вложенного `payload`.
|
|
1591
|
+
*/
|
|
1592
|
+
declare function readUnreadCountEvent(data: unknown): number | undefined;
|
|
1988
1593
|
//#endregion
|
|
1989
1594
|
//#region src/realtime/transport.d.ts
|
|
1990
1595
|
/** Событие, пришедшее по каналу реального времени. */
|
|
@@ -2041,6 +1646,120 @@ declare class UnauthorizedStreamError extends Error {
|
|
|
2041
1646
|
constructor();
|
|
2042
1647
|
}
|
|
2043
1648
|
//#endregion
|
|
1649
|
+
//#region src/realtime/updates.d.ts
|
|
1650
|
+
/** Типы нормализованных обновлений потока. */
|
|
1651
|
+
declare const RealtimeUpdateType: Readonly<{
|
|
1652
|
+
readonly Notification: "notification";
|
|
1653
|
+
readonly UnreadCount: "unreadCount";
|
|
1654
|
+
readonly Unknown: "unknown";
|
|
1655
|
+
}>;
|
|
1656
|
+
/** Источники нормализованных обновлений потока. */
|
|
1657
|
+
declare const RealtimeUpdateOrigin: Readonly<{
|
|
1658
|
+
readonly Stream: "stream";
|
|
1659
|
+
readonly Sync: "sync";
|
|
1660
|
+
}>;
|
|
1661
|
+
type RealtimeUpdateOrigin = (typeof RealtimeUpdateOrigin)[keyof typeof RealtimeUpdateOrigin];
|
|
1662
|
+
/** Уведомление с типом, суженным фильтром потока. */
|
|
1663
|
+
type NotificationOfType<T extends NotificationType> = Omit<Notification, 'type'> & {
|
|
1664
|
+
type: T;
|
|
1665
|
+
};
|
|
1666
|
+
/** Конверт уведомления с типом, суженным фильтром потока. */
|
|
1667
|
+
type NotificationEventOfType<T extends NotificationType> = Omit<NotificationEvent, 'notification'> & {
|
|
1668
|
+
notification: NotificationOfType<T>;
|
|
1669
|
+
};
|
|
1670
|
+
/** Нормализованное уведомление из потока. */
|
|
1671
|
+
interface RealtimeNotificationUpdate<T extends NotificationType = NotificationType> {
|
|
1672
|
+
readonly type: typeof RealtimeUpdateType.Notification;
|
|
1673
|
+
readonly data: NotificationEventOfType<T>;
|
|
1674
|
+
}
|
|
1675
|
+
/** Актуальное число непрочитанных уведомлений. */
|
|
1676
|
+
interface RealtimeUnreadCountUpdate {
|
|
1677
|
+
readonly type: typeof RealtimeUpdateType.UnreadCount;
|
|
1678
|
+
readonly data: number;
|
|
1679
|
+
}
|
|
1680
|
+
/** Неизвестное библиотеке событие потока. */
|
|
1681
|
+
interface RealtimeUnknownUpdate {
|
|
1682
|
+
readonly type: typeof RealtimeUpdateType.Unknown;
|
|
1683
|
+
readonly name: string;
|
|
1684
|
+
readonly data: unknown;
|
|
1685
|
+
}
|
|
1686
|
+
/** Данные, проходящие через промежуточные обработчики потока. */
|
|
1687
|
+
type RealtimeUpdate = RealtimeNotificationUpdate | RealtimeUnreadCountUpdate | RealtimeUnknownUpdate;
|
|
1688
|
+
/** Тип нормализованного обновления потока. */
|
|
1689
|
+
type RealtimeUpdateType = RealtimeUpdate['type'];
|
|
1690
|
+
/** Обновление потока указанного типа. */
|
|
1691
|
+
type RealtimeUpdateOfType<T extends RealtimeUpdateType> = Extract<RealtimeUpdate, {
|
|
1692
|
+
type: T;
|
|
1693
|
+
}>;
|
|
1694
|
+
/** Контекст обработки одного обновления потока. */
|
|
1695
|
+
interface RealtimeContext<U extends RealtimeUpdate = RealtimeUpdate> {
|
|
1696
|
+
/** Нормализованные данные обновления. */
|
|
1697
|
+
readonly update: U;
|
|
1698
|
+
/** Поток, который получил обновление. */
|
|
1699
|
+
readonly stream: ItdRealtime;
|
|
1700
|
+
/** Исходный кадр транспорта. Для начальной REST-синхронизации равен `undefined`. */
|
|
1701
|
+
readonly raw: TransportEvent | undefined;
|
|
1702
|
+
/** Откуда получены данные. */
|
|
1703
|
+
readonly origin: RealtimeUpdateOrigin;
|
|
1704
|
+
}
|
|
1705
|
+
/** Контекст уведомления с типом, суженным фильтром. */
|
|
1706
|
+
type RealtimeNotificationContext<T extends NotificationType = NotificationType> = RealtimeContext<RealtimeNotificationUpdate<T>>;
|
|
1707
|
+
/** Условия отбора уведомлений. Все указанные поля объединяются через логическое И. */
|
|
1708
|
+
interface RealtimeNotificationFilter<T extends NotificationType = NotificationType> {
|
|
1709
|
+
/** Один или несколько канонических типов уведомления. */
|
|
1710
|
+
type?: T | readonly T[];
|
|
1711
|
+
/** Идентификатор хотя бы одного участника уведомления. */
|
|
1712
|
+
actorId?: string;
|
|
1713
|
+
/** Идентификатор объекта события. */
|
|
1714
|
+
entityId?: string | null;
|
|
1715
|
+
/** Идентификатор родительского объекта. */
|
|
1716
|
+
parentEntityId?: string | null;
|
|
1717
|
+
/** Дополнительная проверка после сопоставления полей. */
|
|
1718
|
+
predicate?: (context: RealtimeNotificationContext<T>) => boolean;
|
|
1719
|
+
}
|
|
1720
|
+
/** Краткая или объектная форма фильтра уведомлений. */
|
|
1721
|
+
type RealtimeNotificationSelector<T extends NotificationType = NotificationType> = T | readonly T[] | RealtimeNotificationFilter<T>;
|
|
1722
|
+
//#endregion
|
|
1723
|
+
//#region src/realtime/middleware.d.ts
|
|
1724
|
+
/** Продолжает цепочку промежуточных обработчиков потока. */
|
|
1725
|
+
type RealtimeNext = () => Promise<void>;
|
|
1726
|
+
/** Обрабатывает обновление потока до его передачи подписчикам. */
|
|
1727
|
+
type RealtimeMiddleware<C extends RealtimeContext = RealtimeContext> = (context: C, next: RealtimeNext) => void | Promise<void>;
|
|
1728
|
+
/** Асинхронный обработчик нормализованного обновления потока. */
|
|
1729
|
+
type RealtimeHandler<C extends RealtimeContext = RealtimeContext> = (context: C) => unknown | Promise<unknown>;
|
|
1730
|
+
/** Условие отбора контекста потока. */
|
|
1731
|
+
type RealtimePredicate = (context: RealtimeContext) => boolean;
|
|
1732
|
+
/** Проверка, сужающая тип контекста потока. */
|
|
1733
|
+
type RealtimeTypeGuard<C extends RealtimeContext> = (context: RealtimeContext) => context is C;
|
|
1734
|
+
/** Ключи, по которым обновления нельзя обрабатывать одновременно. */
|
|
1735
|
+
type RealtimeSequentializer = (context: RealtimeContext) => PropertyKey | readonly PropertyKey[] | undefined;
|
|
1736
|
+
//#endregion
|
|
1737
|
+
//#region src/realtime/reconnect.d.ts
|
|
1738
|
+
/**
|
|
1739
|
+
* Паузы перед попытками переподключения, мс.
|
|
1740
|
+
*
|
|
1741
|
+
* Значения совпадают с теми, что использует сайт итд.com, — поведение библиотеки
|
|
1742
|
+
* не отличается от привычного пользователю.
|
|
1743
|
+
*/
|
|
1744
|
+
declare const RECONNECT_BACKOFF: readonly number[];
|
|
1745
|
+
/** Доля случайного разброса паузы. */
|
|
1746
|
+
declare const RECONNECT_JITTER = 0.3;
|
|
1747
|
+
/**
|
|
1748
|
+
* Сколько раз пытаться переподключиться подряд.
|
|
1749
|
+
*
|
|
1750
|
+
* После исчерпания поток сообщает `giveup` и ждёт ручного `connect()`.
|
|
1751
|
+
*/
|
|
1752
|
+
declare const MAX_RECONNECT_ATTEMPTS = 15;
|
|
1753
|
+
/** Настройки переподключения. */
|
|
1754
|
+
interface ReconnectOptions {
|
|
1755
|
+
/** Таблица пауз. Последнее значение действует для всех дальнейших попыток. */
|
|
1756
|
+
backoff?: readonly number[];
|
|
1757
|
+
/** Доля разброса, 0…1. */
|
|
1758
|
+
jitter?: number;
|
|
1759
|
+
/** Предел числа попыток. */
|
|
1760
|
+
maxAttempts?: number;
|
|
1761
|
+
}
|
|
1762
|
+
//#endregion
|
|
2044
1763
|
//#region src/realtime/stream.d.ts
|
|
2045
1764
|
/** События потока уведомлений. */
|
|
2046
1765
|
interface RealtimeEvents {
|
|
@@ -2081,10 +1800,17 @@ interface RealtimeEvents {
|
|
|
2081
1800
|
};
|
|
2082
1801
|
/** Попытки исчерпаны — соединение восстановится только ручным `connect()`. */
|
|
2083
1802
|
giveup: undefined;
|
|
2084
|
-
/**
|
|
2085
|
-
message:
|
|
2086
|
-
|
|
2087
|
-
|
|
1803
|
+
/** Любой исходный кадр транспорта. Отправляется до нормализации и промежуточных обработчиков. */
|
|
1804
|
+
message: TransportEvent;
|
|
1805
|
+
/** Промежуточный обработчик потока завершился исключением. */
|
|
1806
|
+
middlewareError: {
|
|
1807
|
+
error: unknown;
|
|
1808
|
+
context: RealtimeContext;
|
|
1809
|
+
};
|
|
1810
|
+
/** Обработчик `onUpdate` завершился исключением. */
|
|
1811
|
+
handlerError: {
|
|
1812
|
+
error: unknown;
|
|
1813
|
+
context: RealtimeContext;
|
|
2088
1814
|
};
|
|
2089
1815
|
}
|
|
2090
1816
|
/** Способ получения событий. */
|
|
@@ -2138,11 +1864,16 @@ interface RealtimeOptions extends ReconnectOptions {
|
|
|
2138
1864
|
reconnectOnVisible?: boolean;
|
|
2139
1865
|
/** Переподключаться при восстановлении сети. По умолчанию `true`. Только в браузере. */
|
|
2140
1866
|
reconnectOnOnline?: boolean;
|
|
1867
|
+
/** Максимальное число одновременно обрабатываемых обновлений. По умолчанию 1. */
|
|
1868
|
+
concurrency?: number;
|
|
1869
|
+
/** Возвращает ключи обновлений, которые нельзя обрабатывать одновременно. */
|
|
1870
|
+
sequentialize?: RealtimeSequentializer;
|
|
2141
1871
|
}
|
|
2142
1872
|
/** Что поток получает от клиента. */
|
|
2143
1873
|
interface RealtimeDeps {
|
|
2144
1874
|
baseUrl: string;
|
|
2145
1875
|
fetch: typeof fetch;
|
|
1876
|
+
clock?: ItdClock;
|
|
2146
1877
|
/** Общие заголовки клиента для адреса — см. {@link TransportContext.baseHeaders}. */
|
|
2147
1878
|
baseHeaders: (url: string) => Promise<Headers>;
|
|
2148
1879
|
/** Идентификаторы аккаунта и сессии создавшего поток клиента. */
|
|
@@ -2156,6 +1887,8 @@ interface RealtimeDeps {
|
|
|
2156
1887
|
fetchUnreadCount: () => Promise<number>;
|
|
2157
1888
|
/** Вызывается при явном закрытии потока. */
|
|
2158
1889
|
onClose?: (() => void) | undefined;
|
|
1890
|
+
/** Вызывается при запуске ранее закрытого потока. */
|
|
1891
|
+
onConnect?: (() => void) | undefined;
|
|
2159
1892
|
logger?: Logger | undefined;
|
|
2160
1893
|
}
|
|
2161
1894
|
/**
|
|
@@ -2166,16 +1899,19 @@ interface RealtimeDeps {
|
|
|
2166
1899
|
*
|
|
2167
1900
|
* @example
|
|
2168
1901
|
* ```ts
|
|
1902
|
+
* import { NotificationType } from 'itd-api';
|
|
1903
|
+
*
|
|
2169
1904
|
* const stream = itd.realtime();
|
|
2170
1905
|
*
|
|
2171
|
-
* stream.
|
|
2172
|
-
*
|
|
1906
|
+
* stream.onNotification(NotificationType.PostComment, async ({ update }) => {
|
|
1907
|
+
* await saveCommentNotification(update.data.notification);
|
|
2173
1908
|
* });
|
|
2174
1909
|
* stream.on('status', (status) => console.log('соединение:', status));
|
|
2175
1910
|
*
|
|
2176
1911
|
* await stream.connect();
|
|
2177
1912
|
* // …позже
|
|
2178
1913
|
* stream.disconnect();
|
|
1914
|
+
* await stream.drain();
|
|
2179
1915
|
* ```
|
|
2180
1916
|
*/
|
|
2181
1917
|
declare class ItdRealtime {
|
|
@@ -2195,6 +1931,29 @@ declare class ItdRealtime {
|
|
|
2195
1931
|
on<K extends keyof RealtimeEvents>(event: K, listener: Listener<RealtimeEvents[K]>): Unsubscribe;
|
|
2196
1932
|
/** Подписывается на одно срабатывание. */
|
|
2197
1933
|
once<K extends keyof RealtimeEvents>(event: K, listener: Listener<RealtimeEvents[K]>): Unsubscribe;
|
|
1934
|
+
/**
|
|
1935
|
+
* Добавляет промежуточный обработчик нормализованных обновлений.
|
|
1936
|
+
*
|
|
1937
|
+
* Обработчики выполняются в порядке регистрации. Если `next()` не вызван, обновление не
|
|
1938
|
+
* передаётся дальше по цепочке, асинхронным обработчикам и слушателям событий.
|
|
1939
|
+
*
|
|
1940
|
+
* @returns функция удаления обработчика
|
|
1941
|
+
*/
|
|
1942
|
+
use(middleware: RealtimeMiddleware): Unsubscribe;
|
|
1943
|
+
/** Подписывает асинхронный обработчик на все нормализованные обновления. */
|
|
1944
|
+
onUpdate(handler: RealtimeHandler): Unsubscribe;
|
|
1945
|
+
/** Подписывает асинхронный обработчик на обновление указанного типа. */
|
|
1946
|
+
onUpdate<T extends RealtimeUpdateType>(type: T, handler: RealtimeHandler<RealtimeContext<RealtimeUpdateOfType<T>>>): Unsubscribe;
|
|
1947
|
+
/** Подписывает асинхронный обработчик по функции сужения типа. */
|
|
1948
|
+
onUpdate<C extends RealtimeContext>(guard: RealtimeTypeGuard<C>, handler: RealtimeHandler<C>): Unsubscribe;
|
|
1949
|
+
/** Подписывает асинхронный обработчик по пользовательскому условию. */
|
|
1950
|
+
onUpdate(predicate: RealtimePredicate, handler: RealtimeHandler): Unsubscribe;
|
|
1951
|
+
/** Подписывает асинхронный обработчик на уведомления, подходящие под фильтр. */
|
|
1952
|
+
onNotification<T extends NotificationType>(selector: RealtimeNotificationSelector<T>, handler: RealtimeHandler<RealtimeNotificationContext<T>>): Unsubscribe;
|
|
1953
|
+
/** Подписывает асинхронный обработчик по функции сужения типа уведомления. */
|
|
1954
|
+
onNotification<C extends RealtimeNotificationContext>(guard: (context: RealtimeNotificationContext) => context is C, handler: RealtimeHandler<C>): Unsubscribe;
|
|
1955
|
+
/** Подписывает асинхронный обработчик по пользовательскому условию. */
|
|
1956
|
+
onNotification(predicate: (context: RealtimeNotificationContext) => boolean, handler: RealtimeHandler<RealtimeNotificationContext>): Unsubscribe;
|
|
2198
1957
|
/**
|
|
2199
1958
|
* Поднимает соединение.
|
|
2200
1959
|
*
|
|
@@ -2206,10 +1965,73 @@ declare class ItdRealtime {
|
|
|
2206
1965
|
connect(): Promise<void>;
|
|
2207
1966
|
/** Закрывает соединение и отменяет запланированные попытки. */
|
|
2208
1967
|
disconnect(): void;
|
|
2209
|
-
/**
|
|
1968
|
+
/** Ждёт завершения всех принятых обновлений. */
|
|
1969
|
+
drain(): Promise<void>;
|
|
1970
|
+
/** Снимает подписки `on()` и `once()`. Остальные обработчики остаются. */
|
|
2210
1971
|
removeAllListeners(): void;
|
|
2211
1972
|
}
|
|
2212
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
|
|
2213
2035
|
//#region src/core/http.d.ts
|
|
2214
2036
|
/** Что нужно фасаду для работы. */
|
|
2215
2037
|
interface HttpClientDeps {
|
|
@@ -2250,6 +2072,48 @@ declare class HttpClient {
|
|
|
2250
2072
|
request<T = unknown>(options: PipelineRequest): Promise<T>;
|
|
2251
2073
|
}
|
|
2252
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
|
|
2253
2117
|
//#region src/core/pagination.d.ts
|
|
2254
2118
|
/**
|
|
2255
2119
|
* Страница списка — единая форма для всех трёх схем пагинации API.
|
|
@@ -2609,148 +2473,62 @@ declare class AuthResource extends BaseResource {
|
|
|
2609
2473
|
* отзывать было бы уже нечем.
|
|
2610
2474
|
*/
|
|
2611
2475
|
logoutAll(options?: RequestOptions): Promise<void>;
|
|
2612
|
-
/** Забывает сессию локально, не обращаясь к серверу. */
|
|
2613
|
-
signOut(): Promise<void>;
|
|
2614
|
-
/**
|
|
2615
|
-
* Запрашивает письмо с кодом для сброса пароля.
|
|
2616
|
-
*
|
|
2617
|
-
* @returns `flowToken`, который нужно передать в {@link resetPassword}
|
|
2618
|
-
*/
|
|
2619
|
-
forgotPassword(input: ForgotPasswordInput, options?: RequestOptions): Promise<string>;
|
|
2620
|
-
/**
|
|
2621
|
-
* Устанавливает новый пароль по коду из письма.
|
|
2622
|
-
*
|
|
2623
|
-
* Сервер ждёт все четыре поля сразу — `email`, `otp`, `flowToken` и `newPassword`;
|
|
2624
|
-
* при нехватке любого отвечает `422`.
|
|
2625
|
-
*/
|
|
2626
|
-
resetPassword(input: ResetPasswordInput, options?: RequestOptions): Promise<void>;
|
|
2627
|
-
/**
|
|
2628
|
-
* Полный сброс пароля с кодом из письма.
|
|
2629
|
-
*
|
|
2630
|
-
* Тот же приём, что и {@link signInWithOtp}: код запрашивается функцией `getOtp`,
|
|
2631
|
-
* остальное библиотека делает сама.
|
|
2632
|
-
*
|
|
2633
|
-
* @example
|
|
2634
|
-
* ```ts
|
|
2635
|
-
* await itd.auth.resetPasswordWithOtp({
|
|
2636
|
-
* email,
|
|
2637
|
-
* turnstileToken,
|
|
2638
|
-
* newPassword,
|
|
2639
|
-
* getOtp: () => rl.question('Код из письма: '),
|
|
2640
|
-
* });
|
|
2641
|
-
* ```
|
|
2642
|
-
*/
|
|
2643
|
-
resetPasswordWithOtp(input: ForgotPasswordInput & {
|
|
2644
|
-
newPassword: string;
|
|
2645
|
-
getOtp: () => string | Promise<string>;
|
|
2646
|
-
}, options?: RequestOptions): Promise<void>;
|
|
2647
|
-
/**
|
|
2648
|
-
* Меняет пароль. Требует действующей сессии.
|
|
2649
|
-
*
|
|
2650
|
-
* При неверном текущем пароле сервер отвечает `ACCOUNT_CURRENT_PASSWORD_INCORRECT`.
|
|
2651
|
-
*
|
|
2652
|
-
* @example
|
|
2653
|
-
* ```ts
|
|
2654
|
-
* await itd.auth.changePassword({ currentPassword, newPassword });
|
|
2655
|
-
* ```
|
|
2656
|
-
*/
|
|
2657
|
-
changePassword(input: {
|
|
2658
|
-
currentPassword: string;
|
|
2659
|
-
newPassword: string;
|
|
2660
|
-
}, options?: RequestOptions): Promise<void>;
|
|
2661
|
-
/** Загружает список активных сессий. У текущей поле `isCurrent` равно `true`. */
|
|
2662
|
-
sessions(options?: RequestOptions): Promise<Session[]>;
|
|
2663
|
-
/** Завершает указанную сессию. */
|
|
2664
|
-
revokeSession(sessionId: string, options?: RequestOptions): Promise<void>;
|
|
2665
|
-
/** Завершает все сессии, кроме текущей. */
|
|
2666
|
-
revokeOtherSessions(options?: RequestOptions): Promise<void>;
|
|
2667
|
-
}
|
|
2668
|
-
//#endregion
|
|
2669
|
-
//#region src/builders/base.d.ts
|
|
2670
|
-
/** Метка билдера. Через `Symbol.for` — чтобы распознавание переживало смешивание ESM и CJS. */
|
|
2671
|
-
declare const BUILDER: unique symbol;
|
|
2672
|
-
/**
|
|
2673
|
-
* Билдер входных данных.
|
|
2674
|
-
*
|
|
2675
|
-
* Билдеры необязательны: любой метод, принимающий билдер, принимает и обычный объект.
|
|
2676
|
-
* Проверки одинаковы в обоих случаях.
|
|
2677
|
-
*/
|
|
2678
|
-
interface ItdBuilder<T> {
|
|
2679
|
-
/** @internal */
|
|
2680
|
-
readonly [BUILDER]: true;
|
|
2681
|
-
/**
|
|
2682
|
-
* Собирает и проверяет результат.
|
|
2683
|
-
*
|
|
2684
|
-
* @throws {ItdConfigError} если нарушены требования к данным
|
|
2685
|
-
*/
|
|
2686
|
-
build(): T;
|
|
2687
|
-
/** Чтобы билдер корректно вёл себя внутри `JSON.stringify`. */
|
|
2688
|
-
toJSON(): T;
|
|
2689
|
-
}
|
|
2690
|
-
/**
|
|
2691
|
-
* Три равноправные формы входа: обычный объект, готовый билдер или функция-настройщик.
|
|
2692
|
-
*
|
|
2693
|
-
* @example
|
|
2694
|
-
* ```ts
|
|
2695
|
-
* itd.posts.create({ content: 'привет' }); // объект
|
|
2696
|
-
* itd.posts.create(post().content('привет')); // билдер
|
|
2697
|
-
* itd.posts.create((p) => p.content('привет')); // функция
|
|
2698
|
-
* ```
|
|
2699
|
-
*/
|
|
2700
|
-
type BuilderInput<T, B extends ItdBuilder<T>> = T | B | ((builder: B) => B | T);
|
|
2701
|
-
/** Является ли значение билдером. */
|
|
2702
|
-
declare function isBuilder<T>(value: unknown): value is ItdBuilder<T>;
|
|
2703
|
-
//#endregion
|
|
2704
|
-
//#region src/builders/poll.d.ts
|
|
2705
|
-
/**
|
|
2706
|
-
* Билдер опроса.
|
|
2707
|
-
*
|
|
2708
|
-
* Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
|
|
2709
|
-
* переиспользовать, не боясь её испортить. Создаётся функцией {@link poll}.
|
|
2710
|
-
*/
|
|
2711
|
-
declare class PollBuilder implements ItdBuilder<CreatePollInput> {
|
|
2712
|
-
#private;
|
|
2713
|
-
/** @internal */
|
|
2714
|
-
readonly [BUILDER]: true;
|
|
2715
|
-
/** @internal Создавайте билдер функцией {@link poll}. */
|
|
2716
|
-
constructor(state: CreatePollInput);
|
|
2717
|
-
/** Задаёт вопрос. */
|
|
2718
|
-
question(text: string): PollBuilder;
|
|
2719
|
-
/** Добавляет один вариант ответа. */
|
|
2720
|
-
option(text: string): PollBuilder;
|
|
2476
|
+
/** Забывает сессию локально, не обращаясь к серверу. */
|
|
2477
|
+
signOut(): Promise<void>;
|
|
2721
2478
|
/**
|
|
2722
|
-
*
|
|
2479
|
+
* Запрашивает письмо с кодом для сброса пароля.
|
|
2480
|
+
*
|
|
2481
|
+
* @returns `flowToken`, который нужно передать в {@link resetPassword}
|
|
2482
|
+
*/
|
|
2483
|
+
forgotPassword(input: ForgotPasswordInput, options?: RequestOptions): Promise<string>;
|
|
2484
|
+
/**
|
|
2485
|
+
* Устанавливает новый пароль по коду из письма.
|
|
2486
|
+
*
|
|
2487
|
+
* Сервер ждёт все четыре поля сразу — `email`, `otp`, `flowToken` и `newPassword`;
|
|
2488
|
+
* при нехватке любого отвечает `422`.
|
|
2489
|
+
*/
|
|
2490
|
+
resetPassword(input: ResetPasswordInput, options?: RequestOptions): Promise<void>;
|
|
2491
|
+
/**
|
|
2492
|
+
* Полный сброс пароля с кодом из письма.
|
|
2493
|
+
*
|
|
2494
|
+
* Тот же приём, что и {@link signInWithOtp}: код запрашивается функцией `getOtp`,
|
|
2495
|
+
* остальное библиотека делает сама.
|
|
2723
2496
|
*
|
|
2724
2497
|
* @example
|
|
2725
2498
|
* ```ts
|
|
2726
|
-
*
|
|
2499
|
+
* await itd.auth.resetPasswordWithOtp({
|
|
2500
|
+
* email,
|
|
2501
|
+
* turnstileToken,
|
|
2502
|
+
* newPassword,
|
|
2503
|
+
* getOtp: () => rl.question('Код из письма: '),
|
|
2504
|
+
* });
|
|
2727
2505
|
* ```
|
|
2728
2506
|
*/
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2507
|
+
resetPasswordWithOtp(input: ForgotPasswordInput & {
|
|
2508
|
+
newPassword: string;
|
|
2509
|
+
getOtp: () => string | Promise<string>;
|
|
2510
|
+
}, options?: RequestOptions): Promise<void>;
|
|
2511
|
+
/**
|
|
2512
|
+
* Меняет пароль. Требует действующей сессии.
|
|
2513
|
+
*
|
|
2514
|
+
* При неверном текущем пароле сервер отвечает `ACCOUNT_CURRENT_PASSWORD_INCORRECT`.
|
|
2515
|
+
*
|
|
2516
|
+
* @example
|
|
2517
|
+
* ```ts
|
|
2518
|
+
* await itd.auth.changePassword({ currentPassword, newPassword });
|
|
2519
|
+
* ```
|
|
2520
|
+
*/
|
|
2521
|
+
changePassword(input: {
|
|
2522
|
+
currentPassword: string;
|
|
2523
|
+
newPassword: string;
|
|
2524
|
+
}, options?: RequestOptions): Promise<void>;
|
|
2525
|
+
/** Загружает список активных сессий. У текущей поле `isCurrent` равно `true`. */
|
|
2526
|
+
sessions(options?: RequestOptions): Promise<Session[]>;
|
|
2527
|
+
/** Завершает указанную сессию. */
|
|
2528
|
+
revokeSession(sessionId: string, options?: RequestOptions): Promise<void>;
|
|
2529
|
+
/** Завершает все сессии, кроме текущей. */
|
|
2530
|
+
revokeOtherSessions(options?: RequestOptions): Promise<void>;
|
|
2734
2531
|
}
|
|
2735
|
-
/**
|
|
2736
|
-
* Начинает сборку опроса.
|
|
2737
|
-
*
|
|
2738
|
-
* @param question вопрос; можно задать позже методом {@link PollBuilder.question}
|
|
2739
|
-
*
|
|
2740
|
-
* @example
|
|
2741
|
-
* ```ts
|
|
2742
|
-
* import { poll } from 'itd-api';
|
|
2743
|
-
*
|
|
2744
|
-
* const q = poll('Какой язык лучше?')
|
|
2745
|
-
* .options('TypeScript', 'JavaScript')
|
|
2746
|
-
* .multipleChoice();
|
|
2747
|
-
*
|
|
2748
|
-
* await itd.posts.create({ content: 'голосуем', poll: q });
|
|
2749
|
-
* ```
|
|
2750
|
-
*/
|
|
2751
|
-
declare function poll(question?: string): PollBuilder;
|
|
2752
|
-
/** Что принимает параметр опроса: объект, билдер или функция-настройщик. */
|
|
2753
|
-
type PollInput = BuilderInput<CreatePollInput, PollBuilder>;
|
|
2754
2532
|
//#endregion
|
|
2755
2533
|
//#region src/types/params.d.ts
|
|
2756
2534
|
/** Данные для создания опроса. */
|
|
@@ -2764,8 +2542,13 @@ interface CreatePollInput {
|
|
|
2764
2542
|
/** Разрешить выбор нескольких вариантов. По умолчанию `false`. */
|
|
2765
2543
|
multipleChoice?: boolean;
|
|
2766
2544
|
}
|
|
2767
|
-
/**
|
|
2768
|
-
|
|
2545
|
+
/**
|
|
2546
|
+
* Нормализованные данные для создания поста.
|
|
2547
|
+
*
|
|
2548
|
+
* Это форма, которую возвращают `PostBuilder.build()` и `resolvePost()` после
|
|
2549
|
+
* преобразования вложенных builders. Для входа `itd.posts.create()` см. {@link CreatePostInput}.
|
|
2550
|
+
*/
|
|
2551
|
+
interface CreatePostData {
|
|
2769
2552
|
/** Текст поста. */
|
|
2770
2553
|
content?: string;
|
|
2771
2554
|
/**
|
|
@@ -2784,8 +2567,8 @@ interface CreatePostInput {
|
|
|
2784
2567
|
attachmentIds?: string[];
|
|
2785
2568
|
/** Файлы, которые нужно загрузить перед публикацией. Порядок сохраняется. */
|
|
2786
2569
|
files?: FileInput[];
|
|
2787
|
-
/**
|
|
2788
|
-
poll?:
|
|
2570
|
+
/** Готовые данные опроса. */
|
|
2571
|
+
poll?: CreatePollInput;
|
|
2789
2572
|
}
|
|
2790
2573
|
/** Поля поста, которые принимает `itd.posts.update()`. */
|
|
2791
2574
|
interface UpdatePostInput {
|
|
@@ -2821,6 +2604,41 @@ interface CreateReportInput {
|
|
|
2821
2604
|
description?: string;
|
|
2822
2605
|
}
|
|
2823
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
|
|
2824
2642
|
//#region src/builders/comment.d.ts
|
|
2825
2643
|
/** Внутреннее состояние {@link CommentBuilder}. */
|
|
2826
2644
|
interface CommentState extends CreateCommentInput {
|
|
@@ -2871,21 +2689,172 @@ declare class CommentBuilder implements ItdBuilder<CreateCommentInput> {
|
|
|
2871
2689
|
build(): CreateCommentInput;
|
|
2872
2690
|
toJSON(): CreateCommentInput;
|
|
2873
2691
|
}
|
|
2874
|
-
/**
|
|
2875
|
-
* Начинает сборку комментария.
|
|
2876
|
-
*
|
|
2877
|
-
* @param content текст; можно задать позже методом {@link CommentBuilder.content}
|
|
2878
|
-
*
|
|
2879
|
-
* @example
|
|
2880
|
-
* ```ts
|
|
2881
|
-
* import { comment } from 'itd-api';
|
|
2882
|
-
*
|
|
2883
|
-
* await itd.posts.comment(postId, comment('согласен').attach({ url: memeUrl }));
|
|
2884
|
-
* ```
|
|
2885
|
-
*/
|
|
2886
|
-
declare function comment(content?: string): CommentBuilder;
|
|
2887
|
-
/** Что принимает параметр комментария: объект, билдер или функция-настройщик. */
|
|
2888
|
-
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
|
+
}
|
|
2889
2858
|
//#endregion
|
|
2890
2859
|
//#region src/resources/comments.d.ts
|
|
2891
2860
|
/** Параметры запроса ответов на комментарий. */
|
|
@@ -3091,6 +3060,116 @@ declare class NotificationsResource extends BaseResource {
|
|
|
3091
3060
|
updateSettings(input: UpdateNotificationSettingsInput, options?: RequestOptions): Promise<NotificationSettings>;
|
|
3092
3061
|
}
|
|
3093
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
|
|
3094
3173
|
//#region src/resources/platform.d.ts
|
|
3095
3174
|
/** Требования к версии одного приложения платформы. */
|
|
3096
3175
|
interface PlatformClientVersion {
|
|
@@ -3266,8 +3345,64 @@ declare function parseMarkdown(source: string, options?: ParseMarkupOptions): Te
|
|
|
3266
3345
|
*/
|
|
3267
3346
|
declare function parseHtml(source: string, options?: ParseMarkupOptions): TextMarkup;
|
|
3268
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
|
|
3269
3399
|
//#region src/builders/post.d.ts
|
|
3270
3400
|
declare const BUILD_UPDATE: unique symbol;
|
|
3401
|
+
/** Данные для создания поста, включая поддерживаемые builder-формы вложенного опроса. */
|
|
3402
|
+
interface CreatePostInput extends Omit<CreatePostData, 'poll'> {
|
|
3403
|
+
/** Опрос: обычный объект, {@link PollBuilder} или функция-настройщик. */
|
|
3404
|
+
poll?: PollInput;
|
|
3405
|
+
}
|
|
3271
3406
|
/** Внутреннее состояние {@link PostBuilder}. */
|
|
3272
3407
|
interface PostState extends CreatePostInput {
|
|
3273
3408
|
content: string;
|
|
@@ -3289,7 +3424,7 @@ interface PostState extends CreatePostInput {
|
|
|
3289
3424
|
* await itd.posts.create(onWall.content('второй')); // заготовка не испорчена
|
|
3290
3425
|
* ```
|
|
3291
3426
|
*/
|
|
3292
|
-
declare class PostBuilder implements ItdBuilder<
|
|
3427
|
+
declare class PostBuilder implements ItdBuilder<CreatePostData> {
|
|
3293
3428
|
#private;
|
|
3294
3429
|
/** @internal */
|
|
3295
3430
|
readonly [BUILDER]: true;
|
|
@@ -3355,10 +3490,10 @@ declare class PostBuilder implements ItdBuilder<CreatePostInput> {
|
|
|
3355
3490
|
* ```
|
|
3356
3491
|
*/
|
|
3357
3492
|
poll(input: PollInput): PostBuilder;
|
|
3358
|
-
build():
|
|
3493
|
+
build(): CreatePostData;
|
|
3359
3494
|
/** @internal Собирает данные по правилам `posts.update`, не применяя правила создания. */
|
|
3360
3495
|
[BUILD_UPDATE](): UpdatePostInput;
|
|
3361
|
-
toJSON():
|
|
3496
|
+
toJSON(): CreatePostData;
|
|
3362
3497
|
}
|
|
3363
3498
|
/**
|
|
3364
3499
|
* Начинает сборку поста.
|
|
@@ -4189,10 +4324,12 @@ declare class ItdClient {
|
|
|
4189
4324
|
*
|
|
4190
4325
|
* @example
|
|
4191
4326
|
* ```ts
|
|
4327
|
+
* import { NotificationType } from 'itd-api';
|
|
4328
|
+
*
|
|
4192
4329
|
* const stream = itd.realtime();
|
|
4193
4330
|
*
|
|
4194
|
-
* stream.
|
|
4195
|
-
*
|
|
4331
|
+
* stream.onNotification(NotificationType.PostComment, async ({ update }) => {
|
|
4332
|
+
* await handleComment(update.data.notification);
|
|
4196
4333
|
* });
|
|
4197
4334
|
* stream.on('unreadCount', (count) => setBadge(count));
|
|
4198
4335
|
*
|
|
@@ -4204,8 +4341,8 @@ declare class ItdClient {
|
|
|
4204
4341
|
* Освобождает ресурсы клиента: закрывает все потоки уведомлений, отправляет открытые
|
|
4205
4342
|
* накопители {@link telemetry}, затем останавливает очередь запросов.
|
|
4206
4343
|
*
|
|
4207
|
-
* После вызова клиентом можно пользоваться
|
|
4208
|
-
*
|
|
4344
|
+
* Метод дожидается активных обработчиков потока. После вызова клиентом можно пользоваться
|
|
4345
|
+
* снова; ранее созданный поток можно запустить повторным `connect()`.
|
|
4209
4346
|
*
|
|
4210
4347
|
* Общая очередь, полученная от {@link ItdAccounts}, не останавливается: её гасит сам
|
|
4211
4348
|
* контейнер, когда закрывает все аккаунты разом.
|
|
@@ -4513,6 +4650,22 @@ declare class ItdAccounts {
|
|
|
4513
4650
|
*/
|
|
4514
4651
|
declare function createAccounts(options?: ItdAccountsOptions): ItdAccounts;
|
|
4515
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
|
|
4516
4669
|
//#region src/core/errors.d.ts
|
|
4517
4670
|
/** Бренд, по которому ошибки библиотеки распознаются надёжнее, чем через `instanceof`. */
|
|
4518
4671
|
declare const ITD_ERROR: unique symbol;
|
|
@@ -4858,6 +5011,46 @@ type AllowedMimeType = (typeof ALLOWED_MIME_TYPES)[number];
|
|
|
4858
5011
|
* ```
|
|
4859
5012
|
*/
|
|
4860
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)[];
|
|
4861
5054
|
//#endregion
|
|
4862
5055
|
//#region src/notifications/text.d.ts
|
|
4863
5056
|
/**
|
|
@@ -4926,17 +5119,52 @@ declare function resolveNotificationUrl(notification: Notification): string;
|
|
|
4926
5119
|
//#region src/realtime/poll.d.ts
|
|
4927
5120
|
/** Настройки опроса. */
|
|
4928
5121
|
interface PollTransportOptions {
|
|
5122
|
+
/** Часы опроса. Обычно подменяются только в тестах. */
|
|
5123
|
+
clock?: ItdClock;
|
|
4929
5124
|
/** Как часто опрашивать сервер, мс. По умолчанию 15 000. */
|
|
4930
5125
|
interval?: number;
|
|
4931
5126
|
/** Сколько уведомлений запрашивать за раз. По умолчанию 20. */
|
|
4932
5127
|
limit?: number;
|
|
4933
5128
|
}
|
|
4934
5129
|
//#endregion
|
|
5130
|
+
//#region src/realtime/router.d.ts
|
|
5131
|
+
/** Выбирает маршрут обновления. `undefined` и `null` означают отсутствие маршрута. */
|
|
5132
|
+
type RealtimeRouteSelector<K extends PropertyKey, C extends RealtimeContext = RealtimeContext> = (context: C) => K | null | undefined | Promise<K | null | undefined>;
|
|
5133
|
+
/**
|
|
5134
|
+
* Направляет обновления потока в именованные цепочки промежуточных обработчиков.
|
|
5135
|
+
*
|
|
5136
|
+
* @example
|
|
5137
|
+
* ```ts
|
|
5138
|
+
* import { RealtimeRouter, RealtimeUpdateType } from 'itd-api';
|
|
5139
|
+
*
|
|
5140
|
+
* const router = new RealtimeRouter((context) => context.update.type);
|
|
5141
|
+
* router.route(RealtimeUpdateType.Notification, async (context, next) => {
|
|
5142
|
+
* if (context.update.type === RealtimeUpdateType.Notification) {
|
|
5143
|
+
* await handleNotification(context.update.data.notification);
|
|
5144
|
+
* }
|
|
5145
|
+
* await next();
|
|
5146
|
+
* });
|
|
5147
|
+
* stream.use(router.middleware());
|
|
5148
|
+
* ```
|
|
5149
|
+
*/
|
|
5150
|
+
declare class RealtimeRouter<K extends PropertyKey = PropertyKey, C extends RealtimeContext = RealtimeContext> {
|
|
5151
|
+
#private;
|
|
5152
|
+
constructor(selector: RealtimeRouteSelector<K, C>);
|
|
5153
|
+
/** Добавляет промежуточные обработчики к маршруту и возвращает функцию их удаления. */
|
|
5154
|
+
route(key: K, ...middleware: readonly RealtimeMiddleware<C>[]): Unsubscribe;
|
|
5155
|
+
/** Добавляет промежуточные обработчики для обновлений без зарегистрированного маршрута. */
|
|
5156
|
+
otherwise(...middleware: readonly RealtimeMiddleware<C>[]): Unsubscribe;
|
|
5157
|
+
/** Возвращает промежуточный обработчик для `stream.use()`. */
|
|
5158
|
+
middleware(): RealtimeMiddleware<C>;
|
|
5159
|
+
}
|
|
5160
|
+
//#endregion
|
|
4935
5161
|
//#region src/realtime/sse.d.ts
|
|
4936
5162
|
/** Путь потока уведомлений. */
|
|
4937
5163
|
declare const STREAM_PATH = "/api/notifications/stream";
|
|
4938
5164
|
/** Настройки SSE-транспорта. */
|
|
4939
5165
|
interface SseTransportOptions {
|
|
5166
|
+
/** Часы потока. Обычно подменяются только в тестах. */
|
|
5167
|
+
clock?: ItdClock;
|
|
4940
5168
|
/**
|
|
4941
5169
|
* Сколько миллисекунд ждать данных, прежде чем считать соединение мёртвым.
|
|
4942
5170
|
*
|
|
@@ -4986,5 +5214,5 @@ interface RenderSpansOptions {
|
|
|
4986
5214
|
*/
|
|
4987
5215
|
declare function renderSpans(content: string, spans?: readonly Span[] | null | undefined, options?: RenderSpansOptions): string;
|
|
4988
5216
|
//#endregion
|
|
4989
|
-
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, 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 NotificationListParams, 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 RealtimeDeps, type RealtimeEvents, type RealtimeOptions, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, 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, 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 };
|
|
4990
5218
|
//# sourceMappingURL=index.d.cts.map
|