itd-api 0.0.8 → 0.0.10
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 +155 -253
- package/dist/{chunk-ATCZ4T2K.cjs → chunk-BN4AC3DP.cjs} +3303 -1628
- package/dist/chunk-BN4AC3DP.cjs.map +1 -0
- package/dist/{chunk-JIYN33FG.js → chunk-SMV7TF5P.js} +3283 -1629
- package/dist/chunk-SMV7TF5P.js.map +1 -0
- package/dist/{index-Duh31Wnx.d.cts → index-CSjDNGCE.d.cts} +1298 -410
- package/dist/{index-Duh31Wnx.d.ts → index-CSjDNGCE.d.ts} +1298 -410
- package/dist/index.cjs +169 -89
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node.cjs +266 -124
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +42 -4
- package/dist/node.d.ts +42 -4
- package/dist/node.js +106 -39
- package/dist/node.js.map +1 -1
- package/guides/README.md +22 -0
- package/guides/authentication/README.md +176 -0
- package/guides/authentication/examples/bot-with-session.mjs +98 -0
- package/guides/authentication/examples/turnstile-login.mjs +56 -0
- package/guides/integrations/README.md +62 -0
- package/guides/integrations/examples/proxy.mjs +26 -0
- package/guides/multi-accounts/README.md +142 -0
- package/guides/multi-accounts/examples/multi-accounts.mjs +71 -0
- package/guides/plugins/README.md +162 -0
- package/guides/plugins/examples/cache.mjs +33 -0
- package/guides/plugins/examples/crypto.mjs +54 -0
- package/guides/quickstart/README.md +124 -0
- package/guides/quickstart/examples/quick-start.mjs +44 -0
- package/guides/quickstart/examples/typescript.ts +90 -0
- package/guides/realtime/README.md +109 -0
- package/guides/realtime/examples/notifications.mjs +62 -0
- package/guides/text-markup/README.md +214 -0
- package/guides/text-markup/examples/create-post.mjs +64 -0
- package/package.json +6 -4
- package/dist/chunk-ATCZ4T2K.cjs.map +0 -1
- package/dist/chunk-JIYN33FG.js.map +0 -1
|
@@ -1,37 +1,3 @@
|
|
|
1
|
-
/** Метка билдера. Через `Symbol.for` — чтобы распознавание переживало смешивание ESM и CJS. */
|
|
2
|
-
declare const BUILDER: unique symbol;
|
|
3
|
-
/**
|
|
4
|
-
* Билдер входных данных.
|
|
5
|
-
*
|
|
6
|
-
* Билдеры необязательны: любой метод, принимающий билдер, принимает и обычный объект.
|
|
7
|
-
* Проверки одинаковы в обоих случаях.
|
|
8
|
-
*/
|
|
9
|
-
interface ItdBuilder<T> {
|
|
10
|
-
/** @internal */
|
|
11
|
-
readonly [BUILDER]: true;
|
|
12
|
-
/**
|
|
13
|
-
* Собирает и проверяет результат.
|
|
14
|
-
*
|
|
15
|
-
* @throws {ItdConfigError} если нарушены требования к данным
|
|
16
|
-
*/
|
|
17
|
-
build(): T;
|
|
18
|
-
/** Чтобы билдер корректно вёл себя внутри `JSON.stringify`. */
|
|
19
|
-
toJSON(): T;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Три равноправные формы входа: обычный объект, готовый билдер или функция-настройщик.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* itd.posts.create({ content: 'привет' }); // объект
|
|
27
|
-
* itd.posts.create(post().content('привет')); // билдер
|
|
28
|
-
* itd.posts.create((p) => p.content('привет')); // функция
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
type BuilderInput<T, B extends ItdBuilder<T>> = T | B | ((builder: B) => B | T);
|
|
32
|
-
/** Является ли значение билдером. */
|
|
33
|
-
declare function isBuilder<T>(value: unknown): value is ItdBuilder<T>;
|
|
34
|
-
|
|
35
1
|
/**
|
|
36
2
|
* Перечисления API итд.com.
|
|
37
3
|
*
|
|
@@ -155,6 +121,24 @@ declare const RealtimeStatus: Readonly<{
|
|
|
155
121
|
readonly Disconnected: "disconnected";
|
|
156
122
|
}>;
|
|
157
123
|
type RealtimeStatus = (typeof RealtimeStatus)[keyof typeof RealtimeStatus];
|
|
124
|
+
/** Состояние сервиса платформы. Тип открытый. */
|
|
125
|
+
declare const ServiceState: Readonly<{
|
|
126
|
+
/** Работает штатно. */
|
|
127
|
+
readonly Operational: "operational";
|
|
128
|
+
/** Работает с деградацией. */
|
|
129
|
+
readonly Degraded: "degraded";
|
|
130
|
+
/** Недоступен. */
|
|
131
|
+
readonly Downtime: "downtime";
|
|
132
|
+
}>;
|
|
133
|
+
type ServiceState = Loose<(typeof ServiceState)[keyof typeof ServiceState]>;
|
|
134
|
+
/** Вид происшествия в истории сервиса. Тип открытый. */
|
|
135
|
+
declare const IncidentKind: Readonly<{
|
|
136
|
+
/** Недоступен. */
|
|
137
|
+
readonly Down: "down";
|
|
138
|
+
/** Деградация. */
|
|
139
|
+
readonly Degraded: "deg";
|
|
140
|
+
}>;
|
|
141
|
+
type IncidentKind = Loose<(typeof IncidentKind)[keyof typeof IncidentKind]>;
|
|
158
142
|
/**
|
|
159
143
|
* Уровень доступа к разделу профиля.
|
|
160
144
|
*
|
|
@@ -361,13 +345,11 @@ type UserId = string;
|
|
|
361
345
|
*/
|
|
362
346
|
type UserRef = string;
|
|
363
347
|
/**
|
|
364
|
-
* Разметка в тексте
|
|
348
|
+
* Разметка в тексте поста или комментария.
|
|
365
349
|
*
|
|
366
|
-
*
|
|
367
|
-
* и
|
|
368
|
-
*
|
|
369
|
-
* Единицы `offset` и `length` в документации API не уточнены (UTF-16 или кодовые точки),
|
|
370
|
-
* поэтому при работе с эмодзи проверяйте результат.
|
|
350
|
+
* `offset` и `length` измеряются в UTF-16 code units: это те же индексы, которые используют
|
|
351
|
+
* `String#slice`, `substring` и DOM Selection в JavaScript. Эмодзи вне BMP обычно занимают
|
|
352
|
+
* две единицы.
|
|
371
353
|
*/
|
|
372
354
|
interface Span {
|
|
373
355
|
/** Тип фрагмента — см. {@link SpanType}. */
|
|
@@ -376,10 +358,14 @@ interface Span {
|
|
|
376
358
|
offset: number;
|
|
377
359
|
/** Длина фрагмента. */
|
|
378
360
|
length: number;
|
|
379
|
-
/** Имя хэштега без
|
|
361
|
+
/** Имя хэштега без решётки. У старых mention-объектов может содержать username. */
|
|
380
362
|
tag?: string;
|
|
381
363
|
/** Адрес ссылки. Только у `link`: у него вместо `tag` отдельное поле. */
|
|
382
364
|
url?: string;
|
|
365
|
+
/** Имя пользователя у `mention`. */
|
|
366
|
+
username?: string;
|
|
367
|
+
/** Идентификатор пользователя у некоторых ответов API с `mention`. */
|
|
368
|
+
id?: string;
|
|
383
369
|
}
|
|
384
370
|
/**
|
|
385
371
|
* Значок-«пин» в профиле — награда или отметка платформы.
|
|
@@ -628,6 +614,14 @@ interface Comment {
|
|
|
628
614
|
id: string;
|
|
629
615
|
/** Текст. У голосового комментария пустой. */
|
|
630
616
|
content: string;
|
|
617
|
+
/**
|
|
618
|
+
* Разметка текста, включая автоматически найденные сервером хэштеги и упоминания.
|
|
619
|
+
*
|
|
620
|
+
* Скачанный клиент читает это поле, но comment endpoints принимают только `content`,
|
|
621
|
+
* поэтому библиотека не отправляет ручные spans при создании и редактировании комментария.
|
|
622
|
+
* Поле необязательно: отдельные ответы сервера могут его не содержать.
|
|
623
|
+
*/
|
|
624
|
+
spans?: Span[];
|
|
631
625
|
author: Author;
|
|
632
626
|
likesCount: number;
|
|
633
627
|
repliesCount: number;
|
|
@@ -815,6 +809,61 @@ interface Portal {
|
|
|
815
809
|
title: string;
|
|
816
810
|
url: string;
|
|
817
811
|
}
|
|
812
|
+
/** Происшествие в истории сервиса. */
|
|
813
|
+
interface StatusIncidentLine {
|
|
814
|
+
/** Вид происшествия. */
|
|
815
|
+
t: IncidentKind;
|
|
816
|
+
/**
|
|
817
|
+
* Готовая строка для показа: `недоступен 6 мин (12:00–12:06)`. Время московское.
|
|
818
|
+
* Длительность и границы интервала отдельными полями не приходят.
|
|
819
|
+
*/
|
|
820
|
+
text: string;
|
|
821
|
+
}
|
|
822
|
+
/** Одни сутки в истории сервиса. */
|
|
823
|
+
interface StatusDay {
|
|
824
|
+
/** Худшее состояние за сутки. */
|
|
825
|
+
type: ServiceState;
|
|
826
|
+
/** Дата суток, `YYYY-MM-DD`. Сутки нарезаны по UTC. */
|
|
827
|
+
date_key: string;
|
|
828
|
+
/** Доступность за сутки в процентах. */
|
|
829
|
+
uptime: number;
|
|
830
|
+
/** Происшествия за сутки. */
|
|
831
|
+
lines: StatusIncidentLine[];
|
|
832
|
+
}
|
|
833
|
+
/** Сервис платформы и его история доступности. */
|
|
834
|
+
interface ServiceStatus {
|
|
835
|
+
/** Идентификатор: `auth`, `main`, `media` и прочие. */
|
|
836
|
+
id: string;
|
|
837
|
+
/** Отображаемое название. */
|
|
838
|
+
name: string;
|
|
839
|
+
current_status: ServiceState;
|
|
840
|
+
/** Пояснение к текущему состоянию, например `No downtime`. */
|
|
841
|
+
current_message: string;
|
|
842
|
+
/** Задержка последней проверки в миллисекундах. */
|
|
843
|
+
latency_ms: number;
|
|
844
|
+
/**
|
|
845
|
+
* Момент последней проверки. Сервер отдаёт `YYYY-MM-DD HH:mm:ss` в UTC, библиотека
|
|
846
|
+
* приводит значение к ISO.
|
|
847
|
+
*/
|
|
848
|
+
last_checked: IsoDate;
|
|
849
|
+
/** Доступность за 90 суток в процентах. */
|
|
850
|
+
uptime_90d: number;
|
|
851
|
+
/**
|
|
852
|
+
* История по суткам. Ключ — сколько суток назад, `'0'` — сегодня.
|
|
853
|
+
*
|
|
854
|
+
* Объект разреженный: сутки без данных сервер пропускает. Ровный массив даёт
|
|
855
|
+
* {@link statusDays}.
|
|
856
|
+
*/
|
|
857
|
+
days: Record<string, StatusDay | undefined>;
|
|
858
|
+
}
|
|
859
|
+
/** Состояние платформы — ответ `itd.platform.status()`. */
|
|
860
|
+
interface PlatformStatus {
|
|
861
|
+
/** Худшее состояние среди сервисов. */
|
|
862
|
+
overall_status: ServiceState;
|
|
863
|
+
/** Когда данные последний раз пересчитаны. */
|
|
864
|
+
updated_at: IsoDate;
|
|
865
|
+
services: ServiceStatus[];
|
|
866
|
+
}
|
|
818
867
|
/** Статус заявки на верификацию. `none` означает, что заявка не подавалась. */
|
|
819
868
|
interface VerificationStatus {
|
|
820
869
|
status: Loose<'none' | 'pending' | 'approved' | 'rejected'>;
|
|
@@ -861,380 +910,137 @@ interface PinsResult {
|
|
|
861
910
|
* ```
|
|
862
911
|
*/
|
|
863
912
|
declare function toDate(value: IsoDate | null | undefined): Date | null;
|
|
864
|
-
|
|
865
|
-
/**
|
|
866
|
-
* Билдер опроса.
|
|
867
|
-
*
|
|
868
|
-
* Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
|
|
869
|
-
* переиспользовать, не боясь её испортить. Создаётся функцией {@link poll}.
|
|
870
|
-
*/
|
|
871
|
-
declare class PollBuilder implements ItdBuilder<CreatePollInput> {
|
|
872
|
-
#private;
|
|
873
|
-
/** @internal */
|
|
874
|
-
readonly [BUILDER]: true;
|
|
875
|
-
/** @internal Создавайте билдер функцией {@link poll}. */
|
|
876
|
-
constructor(state: CreatePollInput);
|
|
877
|
-
/** Задаёт вопрос. */
|
|
878
|
-
question(text: string): PollBuilder;
|
|
879
|
-
/** Добавляет один вариант ответа. */
|
|
880
|
-
option(text: string): PollBuilder;
|
|
881
|
-
/**
|
|
882
|
-
* Добавляет несколько вариантов сразу.
|
|
883
|
-
*
|
|
884
|
-
* @example
|
|
885
|
-
* ```ts
|
|
886
|
-
* poll('ну как?').options('да', 'нет', 'не знаю');
|
|
887
|
-
* ```
|
|
888
|
-
*/
|
|
889
|
-
options(...texts: string[]): PollBuilder;
|
|
890
|
-
/** Разрешает выбор нескольких вариантов. */
|
|
891
|
-
multipleChoice(enabled?: boolean): PollBuilder;
|
|
892
|
-
build(): CreatePollInput;
|
|
893
|
-
toJSON(): CreatePollInput;
|
|
894
|
-
}
|
|
895
913
|
/**
|
|
896
|
-
*
|
|
914
|
+
* Разворачивает историю сервиса в массив на 90 суток.
|
|
915
|
+
* Сутки без данных становятся `null`.
|
|
897
916
|
*
|
|
898
|
-
* @
|
|
917
|
+
* @returns массив, где индекс — сколько суток назад: `[0]` — сегодня
|
|
899
918
|
*
|
|
900
919
|
* @example
|
|
901
920
|
* ```ts
|
|
902
|
-
*
|
|
903
|
-
*
|
|
904
|
-
* const q = poll('Какой язык лучше?')
|
|
905
|
-
* .options('TypeScript', 'JavaScript')
|
|
906
|
-
* .multipleChoice();
|
|
921
|
+
* const status = await itd.platform.status();
|
|
922
|
+
* const days = statusDays(status.services[0]);
|
|
907
923
|
*
|
|
908
|
-
*
|
|
924
|
+
* days[0]?.uptime; // доступность за сегодня
|
|
925
|
+
* days.filter((day) => day === null).length; // за сколько суток данных нет
|
|
909
926
|
* ```
|
|
910
927
|
*/
|
|
911
|
-
declare function
|
|
912
|
-
/** Что принимает параметр опроса: объект, билдер или функция-настройщик. */
|
|
913
|
-
type PollInput = BuilderInput<CreatePollInput, PollBuilder>;
|
|
928
|
+
declare function statusDays(service: ServiceStatus): (StatusDay | null)[];
|
|
914
929
|
|
|
915
930
|
/**
|
|
916
|
-
*
|
|
931
|
+
* Как библиотека обращается с cookie.
|
|
917
932
|
*
|
|
918
|
-
*
|
|
919
|
-
*
|
|
933
|
+
* - `browser` — cookie ведёт браузер, запросы уходят с `credentials: 'include'`;
|
|
934
|
+
* - `server` — cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную;
|
|
935
|
+
* - `auto` — определяется по среде исполнения (значение по умолчанию).
|
|
920
936
|
*/
|
|
921
|
-
|
|
922
|
-
/**
|
|
923
|
-
|
|
924
|
-
/**
|
|
925
|
-
|
|
926
|
-
/**
|
|
927
|
-
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
/**
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
937
|
+
declare const RuntimeMode: Readonly<{
|
|
938
|
+
/** Определяется по среде исполнения. Значение по умолчанию. */
|
|
939
|
+
readonly Auto: "auto";
|
|
940
|
+
/** Cookie ведёт браузер, запросы уходят с `credentials: 'include'`. */
|
|
941
|
+
readonly Browser: "browser";
|
|
942
|
+
/** Cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную. */
|
|
943
|
+
readonly Server: "server";
|
|
944
|
+
}>;
|
|
945
|
+
type RuntimeMode = (typeof RuntimeMode)[keyof typeof RuntimeMode];
|
|
946
|
+
/** Распознанная среда исполнения. */
|
|
947
|
+
declare const DetectedRuntime: Readonly<{
|
|
948
|
+
readonly Browser: "browser";
|
|
949
|
+
/** Есть `window`, но нет `document`; cookie ведёт нативный сетевой слой. */
|
|
950
|
+
readonly ReactNative: "react-native";
|
|
951
|
+
readonly Server: "server";
|
|
952
|
+
}>;
|
|
953
|
+
type DetectedRuntime = (typeof DetectedRuntime)[keyof typeof DetectedRuntime];
|
|
954
|
+
|
|
955
|
+
/** Сервис платформы на отдельном домене. */
|
|
956
|
+
interface ServiceDefinition {
|
|
957
|
+
/** Имя, по которому запрос выбирает сервис: `{ service: 'status' }`. */
|
|
958
|
+
name: string;
|
|
959
|
+
/** Базовый URL сервиса. */
|
|
960
|
+
baseUrl: string;
|
|
961
|
+
/** Заголовки, добавляемые к каждому запросу сервиса. Заголовки вызова важнее. */
|
|
962
|
+
headers?: Record<string, string> | undefined;
|
|
946
963
|
/**
|
|
947
|
-
*
|
|
964
|
+
* Слать ли заголовок авторизации.
|
|
948
965
|
*
|
|
949
|
-
*
|
|
950
|
-
*
|
|
966
|
+
* По умолчанию включено для основного хоста и его поддоменов. Для остальных хостов
|
|
967
|
+
* авторизацию нужно разрешить явно: `auth: true`.
|
|
951
968
|
*/
|
|
952
|
-
|
|
953
|
-
/** Идентификаторы заранее загруженных вложений. */
|
|
954
|
-
attachmentIds?: string[];
|
|
955
|
-
/** Файлы, которые нужно загрузить перед публикацией. Порядок сохраняется. */
|
|
956
|
-
files?: FileInput[];
|
|
957
|
-
/** Опрос: обычный объект, {@link PollBuilder} или функция-настройщик. */
|
|
958
|
-
poll?: PollInput;
|
|
969
|
+
auth?: boolean | undefined;
|
|
959
970
|
}
|
|
960
|
-
/**
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
attachmentIds?: string[];
|
|
966
|
-
/** Файлы, которые нужно загрузить перед отправкой. */
|
|
967
|
-
files?: FileInput[];
|
|
971
|
+
/** Именованные сервисы клиента. */
|
|
972
|
+
declare class ServiceRegistry {
|
|
973
|
+
#private;
|
|
974
|
+
/** @param primaryBaseUrl базовый URL клиента */
|
|
975
|
+
constructor(primaryBaseUrl?: string);
|
|
968
976
|
/**
|
|
969
|
-
*
|
|
977
|
+
* Регистрирует сервис. Имя очищается от краевых пробелов, базовый URL приводится
|
|
978
|
+
* к каноничному виду, а незаданный `auth` выводится из хоста.
|
|
970
979
|
*
|
|
971
|
-
*
|
|
980
|
+
* @throws {ItdConfigError} если имя пустое, имя занято или `baseUrl` не абсолютный URL
|
|
972
981
|
*/
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
982
|
+
define(definition: ServiceDefinition): void;
|
|
983
|
+
/** Определение сервиса либо `undefined`, если такого нет. */
|
|
984
|
+
get(name: string): ServiceDefinition | undefined;
|
|
985
|
+
/** Зарегистрирован ли сервис с таким именем. */
|
|
986
|
+
has(name: string): boolean;
|
|
987
|
+
/**
|
|
988
|
+
* Определение сервиса.
|
|
989
|
+
*
|
|
990
|
+
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
991
|
+
*/
|
|
992
|
+
require(name: string): ServiceDefinition;
|
|
993
|
+
/**
|
|
994
|
+
* Базовый URL сервиса.
|
|
995
|
+
*
|
|
996
|
+
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
997
|
+
*/
|
|
998
|
+
resolveBaseUrl(name: string): string;
|
|
999
|
+
/**
|
|
1000
|
+
* Принадлежит ли URL основному хосту клиента или его поддомену.
|
|
1001
|
+
*
|
|
1002
|
+
* Используется для безопасного значения по умолчанию у разового `baseUrl`: Bearer-токен
|
|
1003
|
+
* не должен уходить на посторонний хост без явного `skipAuth: false`.
|
|
1004
|
+
*
|
|
1005
|
+
* @internal
|
|
1006
|
+
*/
|
|
1007
|
+
isPrimarySite(baseUrl: string): boolean;
|
|
985
1008
|
}
|
|
986
1009
|
|
|
987
|
-
/** Внутреннее состояние {@link CommentBuilder}. */
|
|
988
|
-
interface CommentState extends CreateCommentInput {
|
|
989
|
-
content: string;
|
|
990
|
-
attachmentIds: string[];
|
|
991
|
-
files: FileInput[];
|
|
992
|
-
/** Голосовой комментарий: текста быть не должно, вложение ровно одно. */
|
|
993
|
-
voice: boolean;
|
|
994
|
-
}
|
|
995
1010
|
/**
|
|
996
|
-
*
|
|
1011
|
+
* Сохранённая сессия.
|
|
997
1012
|
*
|
|
998
|
-
*
|
|
1013
|
+
* Кроме токенов сюда попадают cookie: refresh-токен итд.com живёт именно в cookie, и без них
|
|
1014
|
+
* восстановить сессию после перезапуска процесса невозможно.
|
|
999
1015
|
*/
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
readonly [BUILDER]: true;
|
|
1004
|
-
/** @internal Создавайте билдер функцией {@link comment}. */
|
|
1005
|
-
constructor(state: CommentState);
|
|
1006
|
-
/** Задаёт текст комментария. */
|
|
1007
|
-
content(text: string): CommentBuilder;
|
|
1008
|
-
/** Прикладывает файл — он будет загружен перед отправкой. */
|
|
1009
|
-
attach(file: FileInput): CommentBuilder;
|
|
1010
|
-
/** Прикладывает уже загруженное вложение. */
|
|
1011
|
-
attachId(attachmentId: string): CommentBuilder;
|
|
1016
|
+
interface ItdSession {
|
|
1017
|
+
/** Токен доступа для заголовка `Authorization: Bearer`. */
|
|
1018
|
+
accessToken?: string | undefined;
|
|
1012
1019
|
/**
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1015
|
-
* Текста у такого комментария быть не должно, а вложение ровно одно — аудио в формате
|
|
1016
|
-
* `audio/ogg`. Так его принимает API.
|
|
1020
|
+
* Refresh-токен, если удалось получить его явным значением.
|
|
1017
1021
|
*
|
|
1018
|
-
*
|
|
1019
|
-
*
|
|
1020
|
-
* await itd.posts.comment(postId, (c) => c.voice('./answer.ogg'));
|
|
1021
|
-
* ```
|
|
1022
|
+
* Обычно сервер держит его в httpOnly-cookie и наружу не отдаёт — тогда поле останется
|
|
1023
|
+
* пустым, а обновление пойдёт через {@link ItdSession.cookies}.
|
|
1022
1024
|
*/
|
|
1023
|
-
|
|
1025
|
+
refreshToken?: string | undefined;
|
|
1026
|
+
/** Сырые cookie в форме `имя=значение`, привязанные к origin API. */
|
|
1027
|
+
cookies?: string[] | undefined;
|
|
1024
1028
|
/**
|
|
1025
|
-
*
|
|
1029
|
+
* Идентификатор устройства для заголовка `X-Device-Id`.
|
|
1026
1030
|
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1031
|
+
* Сервер различает по нему записи в списке сессий, поэтому значение должно пережить
|
|
1032
|
+
* перезапуск процесса — иначе каждый старт бота порождает новую сессию. Библиотека
|
|
1033
|
+
* заводит его сама при первом запросе и хранит здесь.
|
|
1029
1034
|
*/
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1035
|
+
deviceId?: string | undefined;
|
|
1036
|
+
/** Когда сессия получена, мс с начала эпохи. Нужно для диагностики. */
|
|
1037
|
+
obtainedAt?: number | undefined;
|
|
1033
1038
|
}
|
|
1034
1039
|
/**
|
|
1035
|
-
*
|
|
1040
|
+
* Хранилище сессии.
|
|
1036
1041
|
*
|
|
1037
|
-
*
|
|
1038
|
-
*
|
|
1039
|
-
* @example
|
|
1040
|
-
* ```ts
|
|
1041
|
-
* import { comment } from 'itd-api';
|
|
1042
|
-
*
|
|
1043
|
-
* await itd.posts.comment(postId, comment('согласен').attach('./meme.png'));
|
|
1044
|
-
* ```
|
|
1045
|
-
*/
|
|
1046
|
-
declare function comment(content?: string): CommentBuilder;
|
|
1047
|
-
/** Что принимает параметр комментария: объект, билдер или функция-настройщик. */
|
|
1048
|
-
type CommentInput = BuilderInput<CreateCommentInput, CommentBuilder>;
|
|
1049
|
-
|
|
1050
|
-
/** Внутреннее состояние {@link PostBuilder}. */
|
|
1051
|
-
interface PostState extends CreatePostInput {
|
|
1052
|
-
content: string;
|
|
1053
|
-
attachmentIds: string[];
|
|
1054
|
-
files: FileInput[];
|
|
1055
|
-
}
|
|
1056
|
-
/**
|
|
1057
|
-
* Билдер поста.
|
|
1058
|
-
*
|
|
1059
|
-
* Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
|
|
1060
|
-
* переиспользовать. Создаётся функцией {@link post}.
|
|
1061
|
-
*
|
|
1062
|
-
* @example Заготовка для нескольких постов
|
|
1063
|
-
* ```ts
|
|
1064
|
-
* const onWall = post().onWall(userId);
|
|
1065
|
-
*
|
|
1066
|
-
* await itd.posts.create(onWall.content('первый'));
|
|
1067
|
-
* await itd.posts.create(onWall.content('второй')); // заготовка не испорчена
|
|
1068
|
-
* ```
|
|
1069
|
-
*/
|
|
1070
|
-
declare class PostBuilder implements ItdBuilder<CreatePostInput> {
|
|
1071
|
-
#private;
|
|
1072
|
-
/** @internal */
|
|
1073
|
-
readonly [BUILDER]: true;
|
|
1074
|
-
/** @internal Создавайте билдер функцией {@link post}. */
|
|
1075
|
-
constructor(state: PostState);
|
|
1076
|
-
/** Задаёт текст поста, заменяя прежний. */
|
|
1077
|
-
content(text: string): PostBuilder;
|
|
1078
|
-
/** Дописывает текст к уже заданному. */
|
|
1079
|
-
append(text: string): PostBuilder;
|
|
1080
|
-
/**
|
|
1081
|
-
* Задаёт разметку текста.
|
|
1082
|
-
*
|
|
1083
|
-
* Библиотека разметку не генерирует: хэштеги и упоминания нужно размечать самостоятельно
|
|
1084
|
-
* либо не размечать вовсе.
|
|
1085
|
-
*/
|
|
1086
|
-
spans(spans: Span[]): PostBuilder;
|
|
1087
|
-
/**
|
|
1088
|
-
* Публикует пост на стене другого пользователя.
|
|
1089
|
-
*
|
|
1090
|
-
* @param userId **UUID** пользователя; имя пользователя не подойдёт
|
|
1091
|
-
*/
|
|
1092
|
-
onWall(userId: UserId): PostBuilder;
|
|
1093
|
-
/**
|
|
1094
|
-
* Прикладывает файл — он будет загружен перед публикацией.
|
|
1095
|
-
*
|
|
1096
|
-
* Порядок вызовов сохраняется в порядке вложений.
|
|
1097
|
-
*/
|
|
1098
|
-
attach(file: FileInput): PostBuilder;
|
|
1099
|
-
/** Прикладывает уже загруженное вложение по его идентификатору. */
|
|
1100
|
-
attachId(attachmentId: string): PostBuilder;
|
|
1101
|
-
/**
|
|
1102
|
-
* Добавляет опрос.
|
|
1103
|
-
*
|
|
1104
|
-
* Принимает объект, {@link PollBuilder} или функцию-настройщик.
|
|
1105
|
-
*
|
|
1106
|
-
* @example
|
|
1107
|
-
* ```ts
|
|
1108
|
-
* post('голосуем').poll((q) => q.question('ну как?').options('да', 'нет'));
|
|
1109
|
-
* ```
|
|
1110
|
-
*/
|
|
1111
|
-
poll(input: PollInput): PostBuilder;
|
|
1112
|
-
build(): CreatePostInput;
|
|
1113
|
-
toJSON(): CreatePostInput;
|
|
1114
|
-
}
|
|
1115
|
-
/**
|
|
1116
|
-
* Начинает сборку поста.
|
|
1117
|
-
*
|
|
1118
|
-
* @param content текст; можно задать позже методом {@link PostBuilder.content}
|
|
1119
|
-
*
|
|
1120
|
-
* @example
|
|
1121
|
-
* ```ts
|
|
1122
|
-
* import { post } from 'itd-api';
|
|
1123
|
-
*
|
|
1124
|
-
* await itd.posts.create(
|
|
1125
|
-
* post('смотрите что нашёл')
|
|
1126
|
-
* .attach('./photo.jpg')
|
|
1127
|
-
* .poll((q) => q.question('нравится?').options('да', 'нет')),
|
|
1128
|
-
* );
|
|
1129
|
-
* ```
|
|
1130
|
-
*/
|
|
1131
|
-
declare function post(content?: string): PostBuilder;
|
|
1132
|
-
/** Что принимает параметр поста: объект, билдер или функция-настройщик. */
|
|
1133
|
-
type PostInput = BuilderInput<CreatePostInput, PostBuilder>;
|
|
1134
|
-
|
|
1135
|
-
/**
|
|
1136
|
-
* Билдер жалобы.
|
|
1137
|
-
*
|
|
1138
|
-
* Точка входа задаёт объект жалобы и его тип одновременно, поэтому рассогласовать
|
|
1139
|
-
* `targetType` и `targetId` невозможно. Создаётся объектом {@link report}.
|
|
1140
|
-
*/
|
|
1141
|
-
declare class ReportBuilder implements ItdBuilder<CreateReportInput> {
|
|
1142
|
-
#private;
|
|
1143
|
-
/** @internal */
|
|
1144
|
-
readonly [BUILDER]: true;
|
|
1145
|
-
/** @internal Создавайте билдер через {@link report}. */
|
|
1146
|
-
constructor(state: Partial<CreateReportInput>);
|
|
1147
|
-
/** Указывает причину жалобы. */
|
|
1148
|
-
reason(reason: ReportReason): ReportBuilder;
|
|
1149
|
-
/** Добавляет пояснение в свободной форме. */
|
|
1150
|
-
description(text: string): ReportBuilder;
|
|
1151
|
-
build(): CreateReportInput;
|
|
1152
|
-
toJSON(): CreateReportInput;
|
|
1153
|
-
}
|
|
1154
|
-
/**
|
|
1155
|
-
* Начинает сборку жалобы.
|
|
1156
|
-
*
|
|
1157
|
-
* Тип объекта выбирается точкой входа, так что указать идентификатор комментария
|
|
1158
|
-
* с типом «пост» нельзя в принципе.
|
|
1159
|
-
*
|
|
1160
|
-
* @example
|
|
1161
|
-
* ```ts
|
|
1162
|
-
* import { report, ReportReason } from 'itd-api';
|
|
1163
|
-
*
|
|
1164
|
-
* await itd.reports.create(report.post(postId).reason(ReportReason.Spam));
|
|
1165
|
-
* await itd.reports.create(report.user(userId).reason('fraud').description('пишет в личку'));
|
|
1166
|
-
* ```
|
|
1167
|
-
*/
|
|
1168
|
-
declare const report: Readonly<{
|
|
1169
|
-
/** Жалоба на пост. */
|
|
1170
|
-
post: (postId: string) => ReportBuilder;
|
|
1171
|
-
/** Жалоба на комментарий. */
|
|
1172
|
-
comment: (commentId: string) => ReportBuilder;
|
|
1173
|
-
/** Жалоба на пользователя. */
|
|
1174
|
-
user: (userId: string) => ReportBuilder;
|
|
1175
|
-
}>;
|
|
1176
|
-
/** Что принимает параметр жалобы: объект, билдер или функция-настройщик. */
|
|
1177
|
-
type ReportInput = BuilderInput<CreateReportInput, ReportBuilder>;
|
|
1178
|
-
|
|
1179
|
-
/**
|
|
1180
|
-
* Как библиотека обращается с cookie.
|
|
1181
|
-
*
|
|
1182
|
-
* - `browser` — cookie ведёт браузер, запросы уходят с `credentials: 'include'`;
|
|
1183
|
-
* - `server` — cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную;
|
|
1184
|
-
* - `auto` — определяется по среде исполнения (значение по умолчанию).
|
|
1185
|
-
*/
|
|
1186
|
-
declare const RuntimeMode: Readonly<{
|
|
1187
|
-
/** Определяется по среде исполнения. Значение по умолчанию. */
|
|
1188
|
-
readonly Auto: "auto";
|
|
1189
|
-
/** Cookie ведёт браузер, запросы уходят с `credentials: 'include'`. */
|
|
1190
|
-
readonly Browser: "browser";
|
|
1191
|
-
/** Cookie ведёт встроенный jar, заголовок `Cookie` подставляется вручную. */
|
|
1192
|
-
readonly Server: "server";
|
|
1193
|
-
}>;
|
|
1194
|
-
type RuntimeMode = (typeof RuntimeMode)[keyof typeof RuntimeMode];
|
|
1195
|
-
/** Распознанная среда исполнения. */
|
|
1196
|
-
declare const DetectedRuntime: Readonly<{
|
|
1197
|
-
readonly Browser: "browser";
|
|
1198
|
-
/** Есть `window`, но нет `document`; cookie ведёт нативный сетевой слой. */
|
|
1199
|
-
readonly ReactNative: "react-native";
|
|
1200
|
-
readonly Server: "server";
|
|
1201
|
-
}>;
|
|
1202
|
-
type DetectedRuntime = (typeof DetectedRuntime)[keyof typeof DetectedRuntime];
|
|
1203
|
-
|
|
1204
|
-
/**
|
|
1205
|
-
* Сохранённая сессия.
|
|
1206
|
-
*
|
|
1207
|
-
* Кроме токенов сюда попадают cookie: refresh-токен итд.com живёт именно в cookie, и без них
|
|
1208
|
-
* восстановить сессию после перезапуска процесса невозможно.
|
|
1209
|
-
*/
|
|
1210
|
-
interface ItdSession {
|
|
1211
|
-
/** Токен доступа для заголовка `Authorization: Bearer`. */
|
|
1212
|
-
accessToken?: string | undefined;
|
|
1213
|
-
/**
|
|
1214
|
-
* Refresh-токен, если удалось получить его явным значением.
|
|
1215
|
-
*
|
|
1216
|
-
* Обычно сервер держит его в httpOnly-cookie и наружу не отдаёт — тогда поле останется
|
|
1217
|
-
* пустым, а обновление пойдёт через {@link ItdSession.cookies}.
|
|
1218
|
-
*/
|
|
1219
|
-
refreshToken?: string | undefined;
|
|
1220
|
-
/** Сырые cookie в форме `имя=значение`, привязанные к origin API. */
|
|
1221
|
-
cookies?: string[] | undefined;
|
|
1222
|
-
/**
|
|
1223
|
-
* Идентификатор устройства для заголовка `X-Device-Id`.
|
|
1224
|
-
*
|
|
1225
|
-
* Сервер различает по нему записи в списке сессий, поэтому значение должно пережить
|
|
1226
|
-
* перезапуск процесса — иначе каждый старт бота порождает новую сессию. Библиотека
|
|
1227
|
-
* заводит его сама при первом запросе и хранит здесь.
|
|
1228
|
-
*/
|
|
1229
|
-
deviceId?: string | undefined;
|
|
1230
|
-
/** Когда сессия получена, мс с начала эпохи. Нужно для диагностики. */
|
|
1231
|
-
obtainedAt?: number | undefined;
|
|
1232
|
-
}
|
|
1233
|
-
/**
|
|
1234
|
-
* Хранилище сессии.
|
|
1235
|
-
*
|
|
1236
|
-
* Подключаемый компонент: библиотека не знает, где вы держите токены, и обращается к ним
|
|
1237
|
-
* только через этот интерфейс. Все методы могут быть как синхронными, так и асинхронными.
|
|
1042
|
+
* Подключаемый компонент: библиотека не знает, где вы держите токены, и обращается к ним
|
|
1043
|
+
* только через этот интерфейс. Все методы могут быть как синхронными, так и асинхронными.
|
|
1238
1044
|
*
|
|
1239
1045
|
* @example Своё хранилище поверх AsyncStorage в React Native
|
|
1240
1046
|
* ```ts
|
|
@@ -1274,6 +1080,9 @@ declare class MemoryTokenStorage implements TokenStorage {
|
|
|
1274
1080
|
*
|
|
1275
1081
|
* Помните, что `localStorage` доступен любому скрипту на странице: не используйте его,
|
|
1276
1082
|
* если для вашего приложения это неприемлемый риск.
|
|
1083
|
+
*
|
|
1084
|
+
* После ошибки записи или удаления хранилище переключается на память до конца
|
|
1085
|
+
* своего жизненного цикла.
|
|
1277
1086
|
*/
|
|
1278
1087
|
declare class LocalStorageTokenStorage implements TokenStorage {
|
|
1279
1088
|
#private;
|
|
@@ -1455,6 +1264,23 @@ interface ItdClientOptions {
|
|
|
1455
1264
|
* источников на итд.com, скорее всего, не настроен.
|
|
1456
1265
|
*/
|
|
1457
1266
|
baseUrl?: string | undefined;
|
|
1267
|
+
/**
|
|
1268
|
+
* Сервисы платформы на отдельных доменах.
|
|
1269
|
+
*
|
|
1270
|
+
* Ключ — имя сервиса, значение — базовый URL или определение целиком. Имя встроенного
|
|
1271
|
+
* сервиса задаёт его хост. Встроен один: `status` — хост `itd.platform.status()`.
|
|
1272
|
+
*
|
|
1273
|
+
* @example
|
|
1274
|
+
* ```ts
|
|
1275
|
+
* const itd = new ItdClient({
|
|
1276
|
+
* services: {
|
|
1277
|
+
* status: 'https://my-proxy.example/status',
|
|
1278
|
+
* pb: { baseUrl: 'https://pbapi.xn--d1ah4a.com', headers: { Referer: 'https://pixel.xn--d1ah4a.com/' } },
|
|
1279
|
+
* },
|
|
1280
|
+
* });
|
|
1281
|
+
* ```
|
|
1282
|
+
*/
|
|
1283
|
+
services?: Record<string, string | Omit<ServiceDefinition, 'name'>> | undefined;
|
|
1458
1284
|
/** Авторизация. Без неё доступны только публичные эндпоинты. */
|
|
1459
1285
|
auth?: AuthInput | undefined;
|
|
1460
1286
|
/** Где хранить сессию. По умолчанию {@link MemoryTokenStorage}. */
|
|
@@ -1516,15 +1342,46 @@ interface RequestOptions {
|
|
|
1516
1342
|
/** Повторы только для этого запроса. Переопределяют глобальную настройку `retry`. */
|
|
1517
1343
|
retry?: RetryOptions | false | undefined;
|
|
1518
1344
|
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Имена полей {@link RequestOptions} — единственный источник истины.
|
|
1347
|
+
*
|
|
1348
|
+
* Ресурсы переносят в описание запроса только эти поля (плюс заявленные плагинами),
|
|
1349
|
+
* потому что параметры методов подмешивают к ним `limit`, `cursor` и прочее, чему
|
|
1350
|
+
* в транспорте делать нечего. Список стоит рядом с интерфейсом, чтобы новое поле нельзя
|
|
1351
|
+
* было забыть.
|
|
1352
|
+
*
|
|
1353
|
+
* `satisfies` гарантирует, что каждое имя в списке — действительно поле `RequestOptions`.
|
|
1354
|
+
* Обратную полноту (не забыто ли новое поле) проверяет тип {@link RequestOptionKeysComplete}
|
|
1355
|
+
* в тесте: здесь её проверять нельзя — плагины расширяют `RequestOptions` своими опциями
|
|
1356
|
+
* (`encrypt`, `decrypt` и подобными), которых в этом списке быть и не должно.
|
|
1357
|
+
*/
|
|
1358
|
+
declare const REQUEST_OPTION_KEYS: readonly ["signal", "timeout", "headers", "retry"];
|
|
1519
1359
|
/** Полное описание запроса для низкоуровневого `itd.request()`. */
|
|
1520
1360
|
interface RawRequestOptions extends RequestOptions {
|
|
1521
1361
|
method: string;
|
|
1522
1362
|
/** Путь с ведущим слэшем, например `/api/posts`. Завершающий слэш значим. */
|
|
1523
1363
|
path: string;
|
|
1364
|
+
/**
|
|
1365
|
+
* Имя сервиса, на хост которого уйдёт запрос. Без него запрос идёт на основной `baseUrl`
|
|
1366
|
+
* клиента. Сервисы задаются опцией {@link ItdClientOptions.services}.
|
|
1367
|
+
*/
|
|
1368
|
+
service?: string | undefined;
|
|
1369
|
+
/**
|
|
1370
|
+
* Хост этого запроса. Важнее, чем {@link RawRequestOptions.service}.
|
|
1371
|
+
*
|
|
1372
|
+
* На посторонний основному API хост Bearer-токен по умолчанию не отправляется.
|
|
1373
|
+
* Для осознанного разрешения укажите `skipAuth: false`.
|
|
1374
|
+
*/
|
|
1375
|
+
baseUrl?: string | undefined;
|
|
1524
1376
|
query?: QueryParams | undefined;
|
|
1525
1377
|
/** Тело: будет отправлено как JSON. Для загрузки файлов передайте `FormData`. */
|
|
1526
1378
|
body?: unknown;
|
|
1527
|
-
/**
|
|
1379
|
+
/**
|
|
1380
|
+
* Не подставлять заголовок авторизации.
|
|
1381
|
+
*
|
|
1382
|
+
* Явное `false` разрешает авторизацию и для разового внешнего `baseUrl`; без него
|
|
1383
|
+
* токен автоматически отправляется только основному хосту и его поддоменам.
|
|
1384
|
+
*/
|
|
1528
1385
|
skipAuth?: boolean | undefined;
|
|
1529
1386
|
/** Не пытаться обновить токен при `401` — используется самими эндпоинтами авторизации. */
|
|
1530
1387
|
skipAuthRefresh?: boolean | undefined;
|
|
@@ -1541,10 +1398,16 @@ interface RawRequestOptions extends RequestOptions {
|
|
|
1541
1398
|
}
|
|
1542
1399
|
|
|
1543
1400
|
/** Версия библиотеки. Попадает в `User-Agent`. */
|
|
1544
|
-
declare const LIBRARY_VERSION = "0.0.
|
|
1401
|
+
declare const LIBRARY_VERSION = "0.0.10";
|
|
1545
1402
|
|
|
1546
1403
|
/** Базовый URL API итд.com. Домен записан в punycode: `итд.com`. */
|
|
1547
1404
|
declare const DEFAULT_BASE_URL = "https://xn--d1ah4a.com";
|
|
1405
|
+
/** Базовый URL страницы статуса. Домен записан в punycode: `статус.итд.com`. */
|
|
1406
|
+
declare const DEFAULT_STATUS_BASE_URL = "https://xn--80a7abcbg.xn--d1ah4a.com";
|
|
1407
|
+
/** Имя встроенного сервиса статуса. */
|
|
1408
|
+
declare const STATUS_SERVICE = "status";
|
|
1409
|
+
/** Сервисы, зарегистрированные у любого клиента. */
|
|
1410
|
+
declare const BUILT_IN_SERVICES: readonly ServiceDefinition[];
|
|
1548
1411
|
/** Таймаут запроса по умолчанию. Столько же использует официальный клиент итд.com. */
|
|
1549
1412
|
declare const DEFAULT_TIMEOUT = 30000;
|
|
1550
1413
|
|
|
@@ -1558,7 +1421,14 @@ declare const DEFAULT_TIMEOUT = 30000;
|
|
|
1558
1421
|
* В браузере заголовок не выставляется — `User-Agent` там запрещён к изменению, и среда
|
|
1559
1422
|
* молча его игнорирует.
|
|
1560
1423
|
*/
|
|
1561
|
-
declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; itd-api/0.0.
|
|
1424
|
+
declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; itd-api/0.0.10; +https://github.com/KiowDev/itd-api)";
|
|
1425
|
+
/** Настройки очереди со всеми значениями по умолчанию. */
|
|
1426
|
+
interface ResolvedRateLimitOptions {
|
|
1427
|
+
concurrency: number;
|
|
1428
|
+
rps: number | undefined;
|
|
1429
|
+
retryDelays: readonly number[];
|
|
1430
|
+
respectHeaders: boolean;
|
|
1431
|
+
}
|
|
1562
1432
|
/**
|
|
1563
1433
|
* Срез конфигурации, нужный слою авторизации.
|
|
1564
1434
|
*
|
|
@@ -1649,7 +1519,7 @@ declare class CookieJar {
|
|
|
1649
1519
|
|
|
1650
1520
|
/** Обработчик события. */
|
|
1651
1521
|
type Listener<T> = (payload: T) => void;
|
|
1652
|
-
/** Функция отписки, которую возвращает
|
|
1522
|
+
/** Функция отписки, которую возвращает подписка на событие. */
|
|
1653
1523
|
type Unsubscribe = () => void;
|
|
1654
1524
|
/**
|
|
1655
1525
|
* Минимальный типизированный источник событий.
|
|
@@ -1716,10 +1586,20 @@ interface PipelineRequest extends RawRequestOptions {
|
|
|
1716
1586
|
/** Обработчик запроса. Самый внутренний в цепочке — транспорт. */
|
|
1717
1587
|
type RequestHandler = (request: PipelineRequest) => Promise<unknown>;
|
|
1718
1588
|
|
|
1719
|
-
/** Пути авторизации.
|
|
1589
|
+
/** Пути эндпоинтов авторизации. */
|
|
1720
1590
|
declare const AUTH_PATHS: {
|
|
1591
|
+
readonly signUp: "/api/v1/auth/sign-up";
|
|
1721
1592
|
readonly signIn: "/api/v1/auth/sign-in";
|
|
1593
|
+
readonly verifyOtp: "/api/v1/auth/verify-otp";
|
|
1594
|
+
readonly resendOtp: "/api/v1/auth/resend-otp";
|
|
1722
1595
|
readonly refresh: "/api/v1/auth/refresh";
|
|
1596
|
+
readonly logout: "/api/v1/auth/logout";
|
|
1597
|
+
readonly forgotPassword: "/api/v1/auth/forgot-password";
|
|
1598
|
+
readonly resetPassword: "/api/v1/auth/reset-password";
|
|
1599
|
+
readonly changePassword: "/api/v1/auth/change-password";
|
|
1600
|
+
readonly sessions: "/api/v1/auth/sessions";
|
|
1601
|
+
/** Префикс внешнего входа: к нему дописывается имя провайдера. */
|
|
1602
|
+
readonly oauthLogin: "/api/v1/auth/login";
|
|
1723
1603
|
};
|
|
1724
1604
|
/**
|
|
1725
1605
|
* Публичный ключ Cloudflare Turnstile платформы итд.com.
|
|
@@ -1770,6 +1650,8 @@ declare class AuthManager {
|
|
|
1770
1650
|
get on(): Emitter<AuthEvents>['on'];
|
|
1771
1651
|
/** Подписка на одно срабатывание. */
|
|
1772
1652
|
get once(): Emitter<AuthEvents>['once'];
|
|
1653
|
+
/** Непрозрачная область авторизации; токен и идентификатор пользователя не раскрываются. */
|
|
1654
|
+
getAuthScope(): string;
|
|
1773
1655
|
/**
|
|
1774
1656
|
* Есть ли признак живой refresh-сессии.
|
|
1775
1657
|
*
|
|
@@ -1816,7 +1698,14 @@ declare class AuthManager {
|
|
|
1816
1698
|
setAccessToken(accessToken: string): Promise<void>;
|
|
1817
1699
|
/** Текущая сессия целиком. Полезно, чтобы сохранить её самому. */
|
|
1818
1700
|
getSession(): Promise<ItdSession | null>;
|
|
1819
|
-
/**
|
|
1701
|
+
/**
|
|
1702
|
+
* Идентификатор владельца сессии.
|
|
1703
|
+
*
|
|
1704
|
+
* Считается непосредственно из текущего токена и отдельно не сохраняется: после замены
|
|
1705
|
+
* токена идентификатор прежнего владельца остаться не может.
|
|
1706
|
+
*/
|
|
1707
|
+
getUserId(): Promise<UserId | undefined>;
|
|
1708
|
+
/** Заменяет сессию и связанные с ней cookie целиком. */
|
|
1820
1709
|
setSession(session: ItdSession): Promise<void>;
|
|
1821
1710
|
/**
|
|
1822
1711
|
* Забывает сессию и cookie. Сетевой запрос не выполняется.
|
|
@@ -1850,6 +1739,14 @@ interface PluginContext {
|
|
|
1850
1739
|
baseUrl: string;
|
|
1851
1740
|
/** Отладочный вывод клиента, если он включён. */
|
|
1852
1741
|
logger: Logger | undefined;
|
|
1742
|
+
/**
|
|
1743
|
+
* Непрозрачная область текущей авторизации.
|
|
1744
|
+
*
|
|
1745
|
+
* Значение уникально для клиента и меняется при замене либо очистке его сессии. Плагин может
|
|
1746
|
+
* использовать его только для разделения состояния; идентификатор пользователя и токен в нём
|
|
1747
|
+
* не раскрываются.
|
|
1748
|
+
*/
|
|
1749
|
+
getAuthScope?: (() => string) | undefined;
|
|
1853
1750
|
/** Добавляет обёртку запроса. Подключённые раньше оказываются снаружи. */
|
|
1854
1751
|
use(transformer: Transformer): void;
|
|
1855
1752
|
}
|
|
@@ -1929,6 +1826,57 @@ declare class PluginRegistry {
|
|
|
1929
1826
|
run(request: RawRequestOptions, execute: (request: RawRequestOptions) => Promise<unknown>): Promise<unknown>;
|
|
1930
1827
|
}
|
|
1931
1828
|
|
|
1829
|
+
/**
|
|
1830
|
+
* Очередь запросов: ограничивает одновременность и частоту.
|
|
1831
|
+
*
|
|
1832
|
+
* Нужна прежде всего ботам: без неё цикл по сотне постов уходит в API одним залпом
|
|
1833
|
+
* и упирается в `RATE_LIMIT_EXCEEDED`.
|
|
1834
|
+
*
|
|
1835
|
+
* Частота выдерживается равномерным разносом стартов (`1000 / rps` между запросами),
|
|
1836
|
+
* а не окном со счётчиком: так нагрузка ровная, без всплеска в начале каждой секунды.
|
|
1837
|
+
*
|
|
1838
|
+
* @internal
|
|
1839
|
+
*/
|
|
1840
|
+
declare class RequestQueue {
|
|
1841
|
+
#private;
|
|
1842
|
+
constructor(options: ResolvedRateLimitOptions);
|
|
1843
|
+
/** Сколько задач выполняется прямо сейчас. */
|
|
1844
|
+
get active(): number;
|
|
1845
|
+
/** Сколько задач ждёт очереди. */
|
|
1846
|
+
get pending(): number;
|
|
1847
|
+
/**
|
|
1848
|
+
* Ставит задачу в очередь.
|
|
1849
|
+
*
|
|
1850
|
+
* @returns результат задачи; ошибка задачи пробрасывается без изменений
|
|
1851
|
+
*/
|
|
1852
|
+
schedule<T>(task: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
1853
|
+
/**
|
|
1854
|
+
* Останавливает очередь: снимает отложенную паузу и отклоняет ещё не начатые задачи
|
|
1855
|
+
* ошибкой `ItdAbortError`. Уже выполняющиеся задачи доводятся до конца.
|
|
1856
|
+
*/
|
|
1857
|
+
stop(): void;
|
|
1858
|
+
/**
|
|
1859
|
+
* Придерживает всю очередь на заданное время.
|
|
1860
|
+
*
|
|
1861
|
+
* Вызывается при получении `429` с заголовком `Retry-After`: тормозить нужно все запросы,
|
|
1862
|
+
* а не только тот, который наткнулся на лимит, — иначе остальные продолжат добивать API.
|
|
1863
|
+
*/
|
|
1864
|
+
pause(ms: number): void;
|
|
1865
|
+
}
|
|
1866
|
+
/**
|
|
1867
|
+
* Очереди по хостам: основная и по одной на каждый сервис платформы.
|
|
1868
|
+
*
|
|
1869
|
+
* @internal
|
|
1870
|
+
*/
|
|
1871
|
+
declare class RequestQueuePool {
|
|
1872
|
+
#private;
|
|
1873
|
+
constructor(options: ResolvedRateLimitOptions);
|
|
1874
|
+
/** Очередь хоста. */
|
|
1875
|
+
for(service: string | undefined): RequestQueue;
|
|
1876
|
+
/** Останавливает все очереди. */
|
|
1877
|
+
stop(): void;
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1932
1880
|
/** Событие потока уведомлений после разбора. */
|
|
1933
1881
|
interface NotificationEvent {
|
|
1934
1882
|
/** Само уведомление в единой форме. */
|
|
@@ -2018,6 +1966,11 @@ interface TransportContext {
|
|
|
2018
1966
|
baseUrl: string;
|
|
2019
1967
|
/** Реализация `fetch`. */
|
|
2020
1968
|
fetch: typeof fetch;
|
|
1969
|
+
/**
|
|
1970
|
+
* Общие заголовки клиента: `User-Agent`, `X-Device-Id`, заголовки конфигурации
|
|
1971
|
+
* и cookie для указанного адреса.
|
|
1972
|
+
*/
|
|
1973
|
+
baseHeaders: (url: string) => Promise<Headers>;
|
|
2021
1974
|
/** Текущий токен доступа. */
|
|
2022
1975
|
getToken: () => Promise<string | null>;
|
|
2023
1976
|
/** Отмена подключения. */
|
|
@@ -2149,6 +2102,8 @@ interface RealtimeOptions extends ReconnectOptions {
|
|
|
2149
2102
|
interface RealtimeDeps {
|
|
2150
2103
|
baseUrl: string;
|
|
2151
2104
|
fetch: typeof fetch;
|
|
2105
|
+
/** Общие заголовки клиента для адреса — см. {@link TransportContext.baseHeaders}. */
|
|
2106
|
+
baseHeaders: (url: string) => Promise<Headers>;
|
|
2152
2107
|
getToken: () => Promise<string | null>;
|
|
2153
2108
|
/** Обновляет токен после отказа авторизации. Возвращает `true`, если удалось. */
|
|
2154
2109
|
refresh: () => Promise<boolean>;
|
|
@@ -2283,6 +2238,8 @@ declare const PaginationMode: Readonly<{
|
|
|
2283
2238
|
readonly Offset: "offset";
|
|
2284
2239
|
}>;
|
|
2285
2240
|
type PaginationMode = (typeof PaginationMode)[keyof typeof PaginationMode];
|
|
2241
|
+
/** Применяет преобразование к элементам страницы, сохраняя сведения о пагинации. */
|
|
2242
|
+
declare function mapPage<T, R>(page: Page<T>, map: (item: T) => R): Page<R>;
|
|
2286
2243
|
/** Позиция, с которой запрашивается очередная страница. */
|
|
2287
2244
|
interface PageState {
|
|
2288
2245
|
cursor?: string | undefined;
|
|
@@ -2494,10 +2451,10 @@ type SignInStatus = (typeof SignInStatus)[keyof typeof SignInStatus];
|
|
|
2494
2451
|
* объединение делает оба случая явными.
|
|
2495
2452
|
*/
|
|
2496
2453
|
type SignInResult = {
|
|
2497
|
-
status:
|
|
2454
|
+
status: 'authenticated';
|
|
2498
2455
|
accessToken: string;
|
|
2499
2456
|
} | {
|
|
2500
|
-
status:
|
|
2457
|
+
status: 'otp_required';
|
|
2501
2458
|
flowToken: string | undefined;
|
|
2502
2459
|
};
|
|
2503
2460
|
/**
|
|
@@ -2636,9 +2593,14 @@ declare class AuthResource extends BaseResource {
|
|
|
2636
2593
|
* Меняет пароль. Требует действующей сессии.
|
|
2637
2594
|
*
|
|
2638
2595
|
* При неверном текущем пароле сервер отвечает `ACCOUNT_CURRENT_PASSWORD_INCORRECT`.
|
|
2596
|
+
*
|
|
2597
|
+
* @example
|
|
2598
|
+
* ```ts
|
|
2599
|
+
* await itd.auth.changePassword({ currentPassword, newPassword });
|
|
2600
|
+
* ```
|
|
2639
2601
|
*/
|
|
2640
2602
|
changePassword(input: {
|
|
2641
|
-
|
|
2603
|
+
currentPassword: string;
|
|
2642
2604
|
newPassword: string;
|
|
2643
2605
|
}, options?: RequestOptions): Promise<void>;
|
|
2644
2606
|
/**
|
|
@@ -2661,9 +2623,238 @@ declare class AuthResource extends BaseResource {
|
|
|
2661
2623
|
revokeOtherSessions(options?: RequestOptions): Promise<void>;
|
|
2662
2624
|
}
|
|
2663
2625
|
|
|
2664
|
-
/**
|
|
2665
|
-
|
|
2666
|
-
|
|
2626
|
+
/** Метка билдера. Через `Symbol.for` — чтобы распознавание переживало смешивание ESM и CJS. */
|
|
2627
|
+
declare const BUILDER: unique symbol;
|
|
2628
|
+
/**
|
|
2629
|
+
* Билдер входных данных.
|
|
2630
|
+
*
|
|
2631
|
+
* Билдеры необязательны: любой метод, принимающий билдер, принимает и обычный объект.
|
|
2632
|
+
* Проверки одинаковы в обоих случаях.
|
|
2633
|
+
*/
|
|
2634
|
+
interface ItdBuilder<T> {
|
|
2635
|
+
/** @internal */
|
|
2636
|
+
readonly [BUILDER]: true;
|
|
2637
|
+
/**
|
|
2638
|
+
* Собирает и проверяет результат.
|
|
2639
|
+
*
|
|
2640
|
+
* @throws {ItdConfigError} если нарушены требования к данным
|
|
2641
|
+
*/
|
|
2642
|
+
build(): T;
|
|
2643
|
+
/** Чтобы билдер корректно вёл себя внутри `JSON.stringify`. */
|
|
2644
|
+
toJSON(): T;
|
|
2645
|
+
}
|
|
2646
|
+
/**
|
|
2647
|
+
* Три равноправные формы входа: обычный объект, готовый билдер или функция-настройщик.
|
|
2648
|
+
*
|
|
2649
|
+
* @example
|
|
2650
|
+
* ```ts
|
|
2651
|
+
* itd.posts.create({ content: 'привет' }); // объект
|
|
2652
|
+
* itd.posts.create(post().content('привет')); // билдер
|
|
2653
|
+
* itd.posts.create((p) => p.content('привет')); // функция
|
|
2654
|
+
* ```
|
|
2655
|
+
*/
|
|
2656
|
+
type BuilderInput<T, B extends ItdBuilder<T>> = T | B | ((builder: B) => B | T);
|
|
2657
|
+
/** Является ли значение билдером. */
|
|
2658
|
+
declare function isBuilder<T>(value: unknown): value is ItdBuilder<T>;
|
|
2659
|
+
|
|
2660
|
+
/**
|
|
2661
|
+
* Билдер опроса.
|
|
2662
|
+
*
|
|
2663
|
+
* Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
|
|
2664
|
+
* переиспользовать, не боясь её испортить. Создаётся функцией {@link poll}.
|
|
2665
|
+
*/
|
|
2666
|
+
declare class PollBuilder implements ItdBuilder<CreatePollInput> {
|
|
2667
|
+
#private;
|
|
2668
|
+
/** @internal */
|
|
2669
|
+
readonly [BUILDER]: true;
|
|
2670
|
+
/** @internal Создавайте билдер функцией {@link poll}. */
|
|
2671
|
+
constructor(state: CreatePollInput);
|
|
2672
|
+
/** Задаёт вопрос. */
|
|
2673
|
+
question(text: string): PollBuilder;
|
|
2674
|
+
/** Добавляет один вариант ответа. */
|
|
2675
|
+
option(text: string): PollBuilder;
|
|
2676
|
+
/**
|
|
2677
|
+
* Добавляет несколько вариантов сразу.
|
|
2678
|
+
*
|
|
2679
|
+
* @example
|
|
2680
|
+
* ```ts
|
|
2681
|
+
* poll('ну как?').options('да', 'нет', 'не знаю');
|
|
2682
|
+
* ```
|
|
2683
|
+
*/
|
|
2684
|
+
options(...texts: string[]): PollBuilder;
|
|
2685
|
+
/** Разрешает выбор нескольких вариантов. */
|
|
2686
|
+
multipleChoice(enabled?: boolean): PollBuilder;
|
|
2687
|
+
build(): CreatePollInput;
|
|
2688
|
+
toJSON(): CreatePollInput;
|
|
2689
|
+
}
|
|
2690
|
+
/**
|
|
2691
|
+
* Начинает сборку опроса.
|
|
2692
|
+
*
|
|
2693
|
+
* @param question вопрос; можно задать позже методом {@link PollBuilder.question}
|
|
2694
|
+
*
|
|
2695
|
+
* @example
|
|
2696
|
+
* ```ts
|
|
2697
|
+
* import { poll } from 'itd-api';
|
|
2698
|
+
*
|
|
2699
|
+
* const q = poll('Какой язык лучше?')
|
|
2700
|
+
* .options('TypeScript', 'JavaScript')
|
|
2701
|
+
* .multipleChoice();
|
|
2702
|
+
*
|
|
2703
|
+
* await itd.posts.create({ content: 'голосуем', poll: q });
|
|
2704
|
+
* ```
|
|
2705
|
+
*/
|
|
2706
|
+
declare function poll(question?: string): PollBuilder;
|
|
2707
|
+
/** Что принимает параметр опроса: объект, билдер или функция-настройщик. */
|
|
2708
|
+
type PollInput = BuilderInput<CreatePollInput, PollBuilder>;
|
|
2709
|
+
|
|
2710
|
+
/**
|
|
2711
|
+
* Файл для загрузки.
|
|
2712
|
+
*
|
|
2713
|
+
* Строка означает **путь на диске** и работает только в Node, Bun и Deno — для этого
|
|
2714
|
+
* подключите `itd-api/node`. В браузере и React Native передавайте `File` или `Blob`.
|
|
2715
|
+
*/
|
|
2716
|
+
type FileInput = Blob | ArrayBuffer | Uint8Array | string | {
|
|
2717
|
+
/** Содержимое файла. */
|
|
2718
|
+
data: Blob | ArrayBuffer | Uint8Array;
|
|
2719
|
+
/** Имя файла. Влияет на определение типа, если `contentType` не задан. */
|
|
2720
|
+
filename?: string;
|
|
2721
|
+
/** MIME-тип. Если не указан, определяется по расширению или по самому `Blob`. */
|
|
2722
|
+
contentType?: string;
|
|
2723
|
+
};
|
|
2724
|
+
/** Данные для создания опроса. */
|
|
2725
|
+
interface CreatePollInput {
|
|
2726
|
+
/** Вопрос. Не может быть пустым. */
|
|
2727
|
+
question: string;
|
|
2728
|
+
/** Варианты ответа. Требуется минимум два. */
|
|
2729
|
+
options: {
|
|
2730
|
+
text: string;
|
|
2731
|
+
}[];
|
|
2732
|
+
/** Разрешить выбор нескольких вариантов. По умолчанию `false`. */
|
|
2733
|
+
multipleChoice?: boolean;
|
|
2734
|
+
}
|
|
2735
|
+
/** Данные для создания поста. */
|
|
2736
|
+
interface CreatePostInput {
|
|
2737
|
+
/** Текст поста. */
|
|
2738
|
+
content?: string;
|
|
2739
|
+
/**
|
|
2740
|
+
* Разметка текста. Сырые spans проверяются относительно `content`;
|
|
2741
|
+
* для автоматического построения доступны `post().markup()` и `post().autoSpans()`.
|
|
2742
|
+
*/
|
|
2743
|
+
spans?: Span[];
|
|
2744
|
+
/**
|
|
2745
|
+
* Чья стена, если пост публикуется не у себя.
|
|
2746
|
+
*
|
|
2747
|
+
* Требуется **UUID**: имя пользователя здесь не работает, его можно получить
|
|
2748
|
+
* из профиля через `itd.users.get(username)`.
|
|
2749
|
+
*/
|
|
2750
|
+
wallRecipientId?: UserId | null;
|
|
2751
|
+
/** Идентификаторы заранее загруженных вложений. */
|
|
2752
|
+
attachmentIds?: string[];
|
|
2753
|
+
/** Файлы, которые нужно загрузить перед публикацией. Порядок сохраняется. */
|
|
2754
|
+
files?: FileInput[];
|
|
2755
|
+
/** Опрос: обычный объект, {@link PollBuilder} или функция-настройщик. */
|
|
2756
|
+
poll?: PollInput;
|
|
2757
|
+
}
|
|
2758
|
+
/** Поля поста, которые принимает `itd.posts.update()`. */
|
|
2759
|
+
interface UpdatePostInput {
|
|
2760
|
+
/** Новый текст поста. Обязателен, чтобы обновление одних spans не стёрло текущий текст. */
|
|
2761
|
+
content: string;
|
|
2762
|
+
/** Разметка нового текста. */
|
|
2763
|
+
spans?: Span[];
|
|
2764
|
+
}
|
|
2765
|
+
/** Данные для создания комментария или ответа. */
|
|
2766
|
+
interface CreateCommentInput {
|
|
2767
|
+
/** Текст. У голосового комментария должен быть пустым. */
|
|
2768
|
+
content?: string;
|
|
2769
|
+
/** Идентификаторы заранее загруженных вложений. */
|
|
2770
|
+
attachmentIds?: string[];
|
|
2771
|
+
/** Файлы, которые нужно загрузить перед отправкой. */
|
|
2772
|
+
files?: FileInput[];
|
|
2773
|
+
/**
|
|
2774
|
+
* Кому адресован ответ.
|
|
2775
|
+
*
|
|
2776
|
+
* Применимо только в `itd.comments.reply()`; в комментарии к посту поле не имеет смысла.
|
|
2777
|
+
*/
|
|
2778
|
+
replyToUserId?: UserId;
|
|
2779
|
+
}
|
|
2780
|
+
/** Данные для создания жалобы. */
|
|
2781
|
+
interface CreateReportInput {
|
|
2782
|
+
/** На что жалоба. */
|
|
2783
|
+
targetType: ReportTargetType;
|
|
2784
|
+
/** Идентификатор объекта жалобы. */
|
|
2785
|
+
targetId: string;
|
|
2786
|
+
/** Причина. */
|
|
2787
|
+
reason: ReportReason;
|
|
2788
|
+
/** Пояснение в свободной форме. */
|
|
2789
|
+
description?: string;
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
/** Внутреннее состояние {@link CommentBuilder}. */
|
|
2793
|
+
interface CommentState extends CreateCommentInput {
|
|
2794
|
+
content: string;
|
|
2795
|
+
attachmentIds: string[];
|
|
2796
|
+
files: FileInput[];
|
|
2797
|
+
/** Голосовой комментарий: текста быть не должно, вложение ровно одно. */
|
|
2798
|
+
voice: boolean;
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Билдер комментария и ответа на комментарий.
|
|
2802
|
+
*
|
|
2803
|
+
* Неизменяемый: каждый вызов возвращает новый экземпляр. Создаётся функцией {@link comment}.
|
|
2804
|
+
*/
|
|
2805
|
+
declare class CommentBuilder implements ItdBuilder<CreateCommentInput> {
|
|
2806
|
+
#private;
|
|
2807
|
+
/** @internal */
|
|
2808
|
+
readonly [BUILDER]: true;
|
|
2809
|
+
/** @internal Создавайте билдер функцией {@link comment}. */
|
|
2810
|
+
constructor(state: CommentState);
|
|
2811
|
+
/** Задаёт текст комментария. */
|
|
2812
|
+
content(text: string): CommentBuilder;
|
|
2813
|
+
/** Прикладывает файл — он будет загружен перед отправкой. */
|
|
2814
|
+
attach(file: FileInput): CommentBuilder;
|
|
2815
|
+
/** Прикладывает уже загруженное вложение. */
|
|
2816
|
+
attachId(attachmentId: string): CommentBuilder;
|
|
2817
|
+
/**
|
|
2818
|
+
* Делает комментарий голосовым.
|
|
2819
|
+
*
|
|
2820
|
+
* Текста у такого комментария быть не должно, а вложение ровно одно — аудио в формате
|
|
2821
|
+
* `audio/ogg`. Так его принимает API.
|
|
2822
|
+
*
|
|
2823
|
+
* @example
|
|
2824
|
+
* ```ts
|
|
2825
|
+
* await itd.posts.comment(postId, (c) => c.voice('./answer.ogg'));
|
|
2826
|
+
* ```
|
|
2827
|
+
*/
|
|
2828
|
+
voice(audio: FileInput): CommentBuilder;
|
|
2829
|
+
/**
|
|
2830
|
+
* Кому адресован ответ.
|
|
2831
|
+
*
|
|
2832
|
+
* Имеет смысл только в `itd.comments.reply()`; при отправке комментария к посту
|
|
2833
|
+
* это поле вызовет ошибку.
|
|
2834
|
+
*/
|
|
2835
|
+
replyTo(userId: UserId): CommentBuilder;
|
|
2836
|
+
build(): CreateCommentInput;
|
|
2837
|
+
toJSON(): CreateCommentInput;
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* Начинает сборку комментария.
|
|
2841
|
+
*
|
|
2842
|
+
* @param content текст; можно задать позже методом {@link CommentBuilder.content}
|
|
2843
|
+
*
|
|
2844
|
+
* @example
|
|
2845
|
+
* ```ts
|
|
2846
|
+
* import { comment } from 'itd-api';
|
|
2847
|
+
*
|
|
2848
|
+
* await itd.posts.comment(postId, comment('согласен').attach('./meme.png'));
|
|
2849
|
+
* ```
|
|
2850
|
+
*/
|
|
2851
|
+
declare function comment(content?: string): CommentBuilder;
|
|
2852
|
+
/** Что принимает параметр комментария: объект, билдер или функция-настройщик. */
|
|
2853
|
+
type CommentInput = BuilderInput<CreateCommentInput, CommentBuilder>;
|
|
2854
|
+
|
|
2855
|
+
/** Параметры запроса ответов на комментарий. */
|
|
2856
|
+
interface RepliesParams extends RequestOptions {
|
|
2857
|
+
limit?: number;
|
|
2667
2858
|
page?: number;
|
|
2668
2859
|
maxPages?: number;
|
|
2669
2860
|
}
|
|
@@ -2728,6 +2919,13 @@ interface UploadOptions extends RequestOptions {
|
|
|
2728
2919
|
*/
|
|
2729
2920
|
validateMime?: boolean;
|
|
2730
2921
|
}
|
|
2922
|
+
/**
|
|
2923
|
+
* Таймаут загрузки файла по умолчанию.
|
|
2924
|
+
*
|
|
2925
|
+
* Заметно больше обычного: видео на несколько десятков мегабайт не укладывается
|
|
2926
|
+
* в стандартные 30 секунд, и запрос обрывался бы на середине.
|
|
2927
|
+
*/
|
|
2928
|
+
declare const DEFAULT_UPLOAD_TIMEOUT = 300000;
|
|
2731
2929
|
/** Чтение файла по пути — подставляется точкой входа `itd-api/node`. */
|
|
2732
2930
|
type FileReader = (path: string) => Promise<{
|
|
2733
2931
|
data: Uint8Array;
|
|
@@ -2894,16 +3092,231 @@ declare class NotificationsResource extends BaseResource {
|
|
|
2894
3092
|
/**
|
|
2895
3093
|
* Сведения о платформе: изменения, анонсы, баннер события.
|
|
2896
3094
|
*
|
|
2897
|
-
* Доступна как `itd.platform`.
|
|
3095
|
+
* Доступна как `itd.platform`.
|
|
3096
|
+
*/
|
|
3097
|
+
declare class PlatformResource extends BaseResource {
|
|
3098
|
+
/** Загружает журнал изменений. */
|
|
3099
|
+
changelog(options?: RequestOptions): Promise<ChangelogEntry[]>;
|
|
3100
|
+
/** Загружает анонсы платформы. */
|
|
3101
|
+
announcements(options?: RequestOptions): Promise<Announcement[]>;
|
|
3102
|
+
/** Загружает баннер текущего события — виджет «портал». */
|
|
3103
|
+
portal(options?: RequestOptions): Promise<Portal>;
|
|
3104
|
+
/**
|
|
3105
|
+
* Загружает состояние сервисов платформы за последние 90 суток.
|
|
3106
|
+
*
|
|
3107
|
+
* Идёт на хост `статус.итд.com` без авторизации. Ответ кэшируется сервером на минуту.
|
|
3108
|
+
* История по суткам приходит разреженной, ровный массив даёт `statusDays`.
|
|
3109
|
+
*
|
|
3110
|
+
* @example
|
|
3111
|
+
* ```ts
|
|
3112
|
+
* const status = await itd.platform.status();
|
|
3113
|
+
*
|
|
3114
|
+
* if (status.overall_status !== 'operational') {
|
|
3115
|
+
* const broken = status.services.filter((s) => s.current_status !== 'operational');
|
|
3116
|
+
* console.log('лежит:', broken.map((s) => s.name).join(', '));
|
|
3117
|
+
* }
|
|
3118
|
+
* ```
|
|
3119
|
+
*/
|
|
3120
|
+
status(options?: RequestOptions): Promise<PlatformStatus>;
|
|
3121
|
+
}
|
|
3122
|
+
|
|
3123
|
+
/** Текст вместе с рассчитанной разметкой. */
|
|
3124
|
+
interface TextMarkup {
|
|
3125
|
+
content: string;
|
|
3126
|
+
spans: Span[];
|
|
3127
|
+
}
|
|
3128
|
+
/** Описание фрагмента без смещения: его вычисляет {@link MarkupBuilder}. */
|
|
3129
|
+
type MarkupSpan = Omit<Span, 'offset' | 'length'>;
|
|
3130
|
+
/** Что принимает метод разметки: результат, билдер или функция-настройщик. */
|
|
3131
|
+
type MarkupInput = BuilderInput<TextMarkup, MarkupBuilder>;
|
|
3132
|
+
/**
|
|
3133
|
+
* Содержимое форматированного фрагмента.
|
|
3134
|
+
*
|
|
3135
|
+
* Строка создаёт простой фрагмент. Билдер, готовая разметка или функция позволяют вложить
|
|
3136
|
+
* одни spans в другие, как при последовательном форматировании выделения в редакторе сайта.
|
|
3137
|
+
*/
|
|
3138
|
+
type MarkupContent = string | MarkupInput;
|
|
3139
|
+
/** Какие сущности искать в {@link autoSpans}. */
|
|
3140
|
+
interface AutoSpansOptions {
|
|
3141
|
+
/** Находить `#хэштеги`. По умолчанию `true`. */
|
|
3142
|
+
hashtags?: boolean;
|
|
3143
|
+
/** Находить `@упоминания`. По умолчанию `true`. */
|
|
3144
|
+
mentions?: boolean;
|
|
3145
|
+
/** Находить абсолютные HTTP(S)-ссылки. По умолчанию `true`. */
|
|
3146
|
+
links?: boolean;
|
|
3147
|
+
}
|
|
3148
|
+
/**
|
|
3149
|
+
* Неизменяемый билдер текста с разметкой.
|
|
3150
|
+
*
|
|
3151
|
+
* Каждый метод дописывает фрагмент и сам считает `offset` и `length` в единицах UTF-16 —
|
|
3152
|
+
* именно такие индексы использует JavaScript-редактор сайта.
|
|
3153
|
+
*/
|
|
3154
|
+
declare class MarkupBuilder implements ItdBuilder<TextMarkup> {
|
|
3155
|
+
#private;
|
|
3156
|
+
/** @internal */
|
|
3157
|
+
readonly [BUILDER]: true;
|
|
3158
|
+
/** @internal Создавайте билдер функцией {@link markup}. */
|
|
3159
|
+
constructor(content: string, spans: Span[]);
|
|
3160
|
+
/** Дописывает обычный текст без разметки. */
|
|
3161
|
+
text(value: string): MarkupBuilder;
|
|
3162
|
+
/** Дописывает переводы строк. */
|
|
3163
|
+
newline(count?: number): MarkupBuilder;
|
|
3164
|
+
/**
|
|
3165
|
+
* Дописывает фрагмент с произвольным типом разметки.
|
|
3166
|
+
*
|
|
3167
|
+
* Вложенный билдер позволяет форматировать часть фрагмента дополнительным стилем.
|
|
3168
|
+
* Для нескольких стилей на всём фрагменте используйте {@link styled}.
|
|
3169
|
+
*/
|
|
3170
|
+
span(value: MarkupContent, span: MarkupSpan): MarkupBuilder;
|
|
3171
|
+
/**
|
|
3172
|
+
* Дописывает фрагмент с несколькими стилями на одном диапазоне.
|
|
3173
|
+
*
|
|
3174
|
+
* Для `link`, которому нужен `url`, используйте {@link link}; произвольные spans с
|
|
3175
|
+
* метаданными можно объединять через вложенные вызовы {@link span}.
|
|
3176
|
+
*/
|
|
3177
|
+
styled(value: MarkupContent, ...types: Span['type'][]): MarkupBuilder;
|
|
3178
|
+
/** Дописывает `#хэштег` и сохраняет имя без решётки в `tag`. */
|
|
3179
|
+
hashtag(tag: string): MarkupBuilder;
|
|
3180
|
+
/** Дописывает `@username` и сохраняет имя пользователя в `username`. */
|
|
3181
|
+
mention(username: string): MarkupBuilder;
|
|
3182
|
+
/**
|
|
3183
|
+
* Дописывает ссылку.
|
|
3184
|
+
*
|
|
3185
|
+
* Для строки адрес по умолчанию становится и текстом ссылки. Вложенному форматированному
|
|
3186
|
+
* фрагменту URL нужно передать явно.
|
|
3187
|
+
*/
|
|
3188
|
+
link(content: MarkupContent, url?: string): MarkupBuilder;
|
|
3189
|
+
bold(content: MarkupContent): MarkupBuilder;
|
|
3190
|
+
italic(content: MarkupContent): MarkupBuilder;
|
|
3191
|
+
underline(content: MarkupContent): MarkupBuilder;
|
|
3192
|
+
strike(content: MarkupContent): MarkupBuilder;
|
|
3193
|
+
spoiler(content: MarkupContent): MarkupBuilder;
|
|
3194
|
+
monospace(content: MarkupContent): MarkupBuilder;
|
|
3195
|
+
quote(content: MarkupContent): MarkupBuilder;
|
|
3196
|
+
build(): TextMarkup;
|
|
3197
|
+
toJSON(): TextMarkup;
|
|
3198
|
+
}
|
|
3199
|
+
/** Начинает сборку текста с автоматически вычисляемыми смещениями. */
|
|
3200
|
+
declare function markup(content?: string): MarkupBuilder;
|
|
3201
|
+
/**
|
|
3202
|
+
* Находит в тексте те сущности, которые сайт получает после серверного разбора:
|
|
3203
|
+
* HTTP(S)-ссылки, `#хэштеги` и `@упоминания`.
|
|
3204
|
+
*
|
|
3205
|
+
* Смещения выражены в UTF-16 code units, поэтому совпадают с `String#slice`,
|
|
3206
|
+
* `substring`, DOM Selection и wire-форматом сайта даже при наличии эмодзи.
|
|
3207
|
+
*/
|
|
3208
|
+
declare function autoSpans(text: string, options?: AutoSpansOptions): Span[];
|
|
3209
|
+
|
|
3210
|
+
declare const BUILD_UPDATE: unique symbol;
|
|
3211
|
+
/** Внутреннее состояние {@link PostBuilder}. */
|
|
3212
|
+
interface PostState extends CreatePostInput {
|
|
3213
|
+
content: string;
|
|
3214
|
+
contentSet: boolean;
|
|
3215
|
+
attachmentIds: string[];
|
|
3216
|
+
files: FileInput[];
|
|
3217
|
+
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Билдер поста.
|
|
3220
|
+
*
|
|
3221
|
+
* Неизменяемый: каждый вызов возвращает новый экземпляр, поэтому заготовку можно
|
|
3222
|
+
* переиспользовать. Создаётся функцией {@link post}.
|
|
3223
|
+
*
|
|
3224
|
+
* @example Заготовка для нескольких постов
|
|
3225
|
+
* ```ts
|
|
3226
|
+
* const onWall = post().onWall(userId);
|
|
3227
|
+
*
|
|
3228
|
+
* await itd.posts.create(onWall.content('первый'));
|
|
3229
|
+
* await itd.posts.create(onWall.content('второй')); // заготовка не испорчена
|
|
3230
|
+
* ```
|
|
3231
|
+
*/
|
|
3232
|
+
declare class PostBuilder implements ItdBuilder<CreatePostInput> {
|
|
3233
|
+
#private;
|
|
3234
|
+
/** @internal */
|
|
3235
|
+
readonly [BUILDER]: true;
|
|
3236
|
+
/** @internal Создавайте билдер функцией {@link post}. */
|
|
3237
|
+
constructor(state: PostState);
|
|
3238
|
+
/**
|
|
3239
|
+
* Задаёт текст поста, заменяя прежний вместе с его разметкой.
|
|
3240
|
+
*
|
|
3241
|
+
* Spans привязаны к конкретному тексту, поэтому после замены их нужно задать заново
|
|
3242
|
+
* через {@link spans}, {@link markup} или {@link autoSpans}.
|
|
3243
|
+
*/
|
|
3244
|
+
content(text: string): PostBuilder;
|
|
3245
|
+
/** Дописывает текст к уже заданному. */
|
|
3246
|
+
append(text: string): PostBuilder;
|
|
3247
|
+
/**
|
|
3248
|
+
* Задаёт готовую разметку текста. Смещения проверяются при {@link build}.
|
|
3249
|
+
*
|
|
3250
|
+
* Для автоматического поиска сущностей есть {@link autoSpans}, а для вычисления смещений
|
|
3251
|
+
* при сборке текста — {@link markup}.
|
|
3252
|
+
*/
|
|
3253
|
+
spans(spans: Span[]): PostBuilder;
|
|
3254
|
+
/**
|
|
3255
|
+
* Заменяет текст и разметку результатом {@link MarkupBuilder}.
|
|
3256
|
+
*
|
|
3257
|
+
* @example
|
|
3258
|
+
* ```ts
|
|
3259
|
+
* post().markup((m) => m.text('смотрите ').hashtag('котики').text(' от ').mention('durov'));
|
|
3260
|
+
* ```
|
|
3261
|
+
*/
|
|
3262
|
+
markup(input: MarkupInput): PostBuilder;
|
|
3263
|
+
/**
|
|
3264
|
+
* Находит HTTP(S)-ссылки, хэштеги и упоминания в уже заданном тексте.
|
|
3265
|
+
*
|
|
3266
|
+
* Ручные стили сохраняются. Повторный вызов не дублирует уже найденные сущности.
|
|
3267
|
+
*/
|
|
3268
|
+
autoSpans(options?: AutoSpansOptions): PostBuilder;
|
|
3269
|
+
/**
|
|
3270
|
+
* Публикует пост на стене другого пользователя.
|
|
3271
|
+
*
|
|
3272
|
+
* @param userId **UUID** пользователя; имя пользователя не подойдёт
|
|
3273
|
+
*/
|
|
3274
|
+
onWall(userId: UserId): PostBuilder;
|
|
3275
|
+
/**
|
|
3276
|
+
* Прикладывает файл — он будет загружен перед публикацией.
|
|
3277
|
+
*
|
|
3278
|
+
* Порядок вызовов сохраняется в порядке вложений.
|
|
3279
|
+
*/
|
|
3280
|
+
attach(file: FileInput): PostBuilder;
|
|
3281
|
+
/** Прикладывает уже загруженное вложение по его идентификатору. */
|
|
3282
|
+
attachId(attachmentId: string): PostBuilder;
|
|
3283
|
+
/**
|
|
3284
|
+
* Добавляет опрос.
|
|
3285
|
+
*
|
|
3286
|
+
* Принимает объект, {@link PollBuilder} или функцию-настройщик.
|
|
3287
|
+
*
|
|
3288
|
+
* @example
|
|
3289
|
+
* ```ts
|
|
3290
|
+
* post('голосуем').poll((q) => q.question('ну как?').options('да', 'нет'));
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
poll(input: PollInput): PostBuilder;
|
|
3294
|
+
build(): CreatePostInput;
|
|
3295
|
+
/** @internal Собирает данные по правилам `posts.update`, не применяя правила создания. */
|
|
3296
|
+
[BUILD_UPDATE](): UpdatePostInput;
|
|
3297
|
+
toJSON(): CreatePostInput;
|
|
3298
|
+
}
|
|
3299
|
+
/**
|
|
3300
|
+
* Начинает сборку поста.
|
|
3301
|
+
*
|
|
3302
|
+
* @param content текст; можно задать позже методом {@link PostBuilder.content}
|
|
3303
|
+
*
|
|
3304
|
+
* @example
|
|
3305
|
+
* ```ts
|
|
3306
|
+
* import { post } from 'itd-api';
|
|
3307
|
+
*
|
|
3308
|
+
* await itd.posts.create(
|
|
3309
|
+
* post('смотрите что нашёл')
|
|
3310
|
+
* .attach('./photo.jpg')
|
|
3311
|
+
* .poll((q) => q.question('нравится?').options('да', 'нет')),
|
|
3312
|
+
* );
|
|
3313
|
+
* ```
|
|
2898
3314
|
*/
|
|
2899
|
-
declare
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
/** Загружает баннер текущего события — виджет «портал». */
|
|
2905
|
-
portal(options?: RequestOptions): Promise<Portal>;
|
|
2906
|
-
}
|
|
3315
|
+
declare function post(content?: string): PostBuilder;
|
|
3316
|
+
/** Что принимает параметр поста: объект, билдер или функция-настройщик. */
|
|
3317
|
+
type PostInput = BuilderInput<CreatePostInput, PostBuilder>;
|
|
3318
|
+
/** Что принимает `posts.update`: объект, билдер поста или функция-настройщик. */
|
|
3319
|
+
type PostUpdateInput = UpdatePostInput | PostBuilder | ((builder: PostBuilder) => PostBuilder | UpdatePostInput);
|
|
2907
3320
|
|
|
2908
3321
|
/** Параметры запроса ленты. */
|
|
2909
3322
|
interface FeedParams extends RequestOptions {
|
|
@@ -2992,8 +3405,14 @@ declare class PostsResource extends BaseResource {
|
|
|
2992
3405
|
* В отличие от списков, здесь у поста заполнено поле `comments`.
|
|
2993
3406
|
*/
|
|
2994
3407
|
get(postId: string, options?: RequestOptions): Promise<Post>;
|
|
2995
|
-
/**
|
|
2996
|
-
|
|
3408
|
+
/**
|
|
3409
|
+
* Редактирует текст и разметку поста.
|
|
3410
|
+
*
|
|
3411
|
+
* Как и {@link create}, принимает объект, готовый {@link PostBuilder} или
|
|
3412
|
+
* функцию-настройщик. Поля создания поста, которые update endpoint не поддерживает
|
|
3413
|
+
* (вложения, опрос и стена), отвергаются до запроса.
|
|
3414
|
+
*/
|
|
3415
|
+
update(postId: string, input: PostUpdateInput, options?: RequestOptions): Promise<Post>;
|
|
2997
3416
|
/** Удаляет пост. Восстановить его можно через {@link restore}. */
|
|
2998
3417
|
remove(postId: string, options?: RequestOptions): Promise<void>;
|
|
2999
3418
|
/** Восстанавливает удалённый пост. */
|
|
@@ -3073,6 +3492,50 @@ declare class PostsResource extends BaseResource {
|
|
|
3073
3492
|
voiceComment(postId: string, audio: FileInput, options?: RequestOptions): Promise<Comment>;
|
|
3074
3493
|
}
|
|
3075
3494
|
|
|
3495
|
+
/**
|
|
3496
|
+
* Билдер жалобы.
|
|
3497
|
+
*
|
|
3498
|
+
* Точка входа задаёт объект жалобы и его тип одновременно, поэтому рассогласовать
|
|
3499
|
+
* `targetType` и `targetId` невозможно. Создаётся объектом {@link report}.
|
|
3500
|
+
*/
|
|
3501
|
+
declare class ReportBuilder implements ItdBuilder<CreateReportInput> {
|
|
3502
|
+
#private;
|
|
3503
|
+
/** @internal */
|
|
3504
|
+
readonly [BUILDER]: true;
|
|
3505
|
+
/** @internal Создавайте билдер через {@link report}. */
|
|
3506
|
+
constructor(state: Partial<CreateReportInput>);
|
|
3507
|
+
/** Указывает причину жалобы. */
|
|
3508
|
+
reason(reason: ReportReason): ReportBuilder;
|
|
3509
|
+
/** Добавляет пояснение в свободной форме. */
|
|
3510
|
+
description(text: string): ReportBuilder;
|
|
3511
|
+
build(): CreateReportInput;
|
|
3512
|
+
toJSON(): CreateReportInput;
|
|
3513
|
+
}
|
|
3514
|
+
/**
|
|
3515
|
+
* Начинает сборку жалобы.
|
|
3516
|
+
*
|
|
3517
|
+
* Тип объекта выбирается точкой входа, так что указать идентификатор комментария
|
|
3518
|
+
* с типом «пост» нельзя в принципе.
|
|
3519
|
+
*
|
|
3520
|
+
* @example
|
|
3521
|
+
* ```ts
|
|
3522
|
+
* import { report, ReportReason } from 'itd-api';
|
|
3523
|
+
*
|
|
3524
|
+
* await itd.reports.create(report.post(postId).reason(ReportReason.Spam));
|
|
3525
|
+
* await itd.reports.create(report.user(userId).reason('fraud').description('пишет в личку'));
|
|
3526
|
+
* ```
|
|
3527
|
+
*/
|
|
3528
|
+
declare const report: Readonly<{
|
|
3529
|
+
/** Жалоба на пост. */
|
|
3530
|
+
post: (postId: string) => ReportBuilder;
|
|
3531
|
+
/** Жалоба на комментарий. */
|
|
3532
|
+
comment: (commentId: string) => ReportBuilder;
|
|
3533
|
+
/** Жалоба на пользователя. */
|
|
3534
|
+
user: (userId: string) => ReportBuilder;
|
|
3535
|
+
}>;
|
|
3536
|
+
/** Что принимает параметр жалобы: объект, билдер или функция-настройщик. */
|
|
3537
|
+
type ReportInput = BuilderInput<CreateReportInput, ReportBuilder>;
|
|
3538
|
+
|
|
3076
3539
|
/**
|
|
3077
3540
|
* Жалобы на контент и пользователей.
|
|
3078
3541
|
*
|
|
@@ -3188,13 +3651,13 @@ interface InteractionEntry {
|
|
|
3188
3651
|
vs: string;
|
|
3189
3652
|
/** Идентификатор поста. Поле `ai`. */
|
|
3190
3653
|
postId: string;
|
|
3191
|
-
/** Индекс вложения (с нуля) — для {@link InteractionType
|
|
3654
|
+
/** Индекс вложения (с нуля) — для `InteractionType.PhotoOpen` ({@link InteractionType}). Поле `mi`. */
|
|
3192
3655
|
mediaIndex?: number;
|
|
3193
3656
|
/** Источник показа. Поле `s`. */
|
|
3194
3657
|
source?: ViewSource;
|
|
3195
|
-
/** Просмотрено мс — для {@link InteractionType
|
|
3658
|
+
/** Просмотрено мс — для `InteractionType.VideoProgress` ({@link InteractionType}). Поле `pm`. */
|
|
3196
3659
|
positionMs?: number;
|
|
3197
|
-
/** Длительность видео в мс — для {@link InteractionType
|
|
3660
|
+
/** Длительность видео в мс — для `InteractionType.VideoProgress` ({@link InteractionType}). Поле `dm`. */
|
|
3198
3661
|
durationMs?: number;
|
|
3199
3662
|
}
|
|
3200
3663
|
/**
|
|
@@ -3394,6 +3857,12 @@ declare global {
|
|
|
3394
3857
|
*/
|
|
3395
3858
|
interface ItdClientInternals {
|
|
3396
3859
|
fileReader?: FileReader | undefined;
|
|
3860
|
+
/**
|
|
3861
|
+
* Готовая очередь запросов — так {@link ItdAccounts} с `rateLimitScope: 'shared'` даёт
|
|
3862
|
+
* нескольким клиентам одну на всех. Свою клиент в этом случае не заводит и, что важнее,
|
|
3863
|
+
* не гасит при `close()`: чужие ожидающие запросы это отменило бы.
|
|
3864
|
+
*/
|
|
3865
|
+
queues?: RequestQueuePool | undefined;
|
|
3397
3866
|
}
|
|
3398
3867
|
/**
|
|
3399
3868
|
* Клиент API итд.com.
|
|
@@ -3484,13 +3953,43 @@ declare class ItdClient {
|
|
|
3484
3953
|
*
|
|
3485
3954
|
* @example
|
|
3486
3955
|
* ```ts
|
|
3487
|
-
* import { crypt } from 'itd-api
|
|
3956
|
+
* import { crypt } from '@itd-api/crypto';
|
|
3488
3957
|
*
|
|
3489
3958
|
* itd.use(crypt());
|
|
3490
3959
|
* await itd.posts.create({ content: 'секрет' }, { encrypt: 'invis' });
|
|
3491
3960
|
* ```
|
|
3492
3961
|
*/
|
|
3493
3962
|
use(plugin: ItdPlugin): this;
|
|
3963
|
+
/**
|
|
3964
|
+
* Регистрирует сервис платформы — домен, отличный от основного.
|
|
3965
|
+
*
|
|
3966
|
+
* Запросы с `{ service: 'имя' }` уходят на его хост с его заголовками. То же самое умеет
|
|
3967
|
+
* опция `services` конструктора. Занятое имя не переопределяется — ни своё, ни встроенное:
|
|
3968
|
+
* разовому запросу хост задаётся полем `baseUrl`.
|
|
3969
|
+
*
|
|
3970
|
+
* Заголовок авторизации по умолчанию уходит только своим — домену клиента и его
|
|
3971
|
+
* поддоменам. Стороннему хосту токен нужно разрешить явно: `auth: true`.
|
|
3972
|
+
*
|
|
3973
|
+
* @throws {ItdConfigError} если определение неверно или имя уже занято
|
|
3974
|
+
*
|
|
3975
|
+
* @example Сервис платформы на поддомене — токен уходит сам
|
|
3976
|
+
* ```ts
|
|
3977
|
+
* itd.defineService({
|
|
3978
|
+
* name: 'pb',
|
|
3979
|
+
* baseUrl: 'https://pbapi.xn--d1ah4a.com',
|
|
3980
|
+
* headers: { Referer: 'https://pixel.xn--d1ah4a.com/' },
|
|
3981
|
+
* });
|
|
3982
|
+
*
|
|
3983
|
+
* await itd.request({ method: 'GET', service: 'pb', path: '/api/pixel-info' });
|
|
3984
|
+
* ```
|
|
3985
|
+
*/
|
|
3986
|
+
defineService(definition: ServiceDefinition): this;
|
|
3987
|
+
/**
|
|
3988
|
+
* Базовый URL зарегистрированного сервиса.
|
|
3989
|
+
*
|
|
3990
|
+
* @throws {ItdConfigError} если сервис не зарегистрирован
|
|
3991
|
+
*/
|
|
3992
|
+
serviceBaseUrl(name: string): string;
|
|
3494
3993
|
/**
|
|
3495
3994
|
* Подписывается на события авторизации.
|
|
3496
3995
|
*
|
|
@@ -3532,6 +4031,9 @@ declare class ItdClient {
|
|
|
3532
4031
|
* После вызова клиентом можно пользоваться снова — новые запросы поднимут всё заново,
|
|
3533
4032
|
* но уже созданные потоки останутся закрытыми.
|
|
3534
4033
|
*
|
|
4034
|
+
* Общая очередь, полученная от {@link ItdAccounts}, не останавливается: её гасит сам
|
|
4035
|
+
* контейнер, когда закрывает все аккаунты разом.
|
|
4036
|
+
*
|
|
3535
4037
|
* @example
|
|
3536
4038
|
* ```ts
|
|
3537
4039
|
* await using itd = new ItdClient({ auth: token });
|
|
@@ -3544,6 +4046,20 @@ declare class ItdClient {
|
|
|
3544
4046
|
[Symbol.asyncDispose](): Promise<void>;
|
|
3545
4047
|
/** Текущая сессия целиком — чтобы сохранить её самостоятельно. */
|
|
3546
4048
|
getSession(): Promise<ItdSession | null>;
|
|
4049
|
+
/**
|
|
4050
|
+
* Идентификатор аккаунта, под которым работает клиент.
|
|
4051
|
+
*
|
|
4052
|
+
* Читается из токена доступа и не стоит ни одного запроса. `undefined`, когда сессии
|
|
4053
|
+
* ещё нет или токен выдан не в формате JWT. Полезен прежде всего с {@link ItdAccounts}:
|
|
4054
|
+
* показывает, какому профилю соответствует восстановленная из хранилища запись.
|
|
4055
|
+
* Свежий профиль целиком отдаёт `itd.users.me()`.
|
|
4056
|
+
*
|
|
4057
|
+
* @example
|
|
4058
|
+
* ```ts
|
|
4059
|
+
* for (const [name, itd] of accounts) console.log(name, await itd.getUserId());
|
|
4060
|
+
* ```
|
|
4061
|
+
*/
|
|
4062
|
+
getUserId(): Promise<UserId | undefined>;
|
|
3547
4063
|
/** Восстанавливает сохранённую сессию, включая cookie. */
|
|
3548
4064
|
setSession(session: ItdSession): Promise<void>;
|
|
3549
4065
|
}
|
|
@@ -3559,6 +4075,340 @@ declare class ItdClient {
|
|
|
3559
4075
|
*/
|
|
3560
4076
|
declare function createClient(options?: ItdClientOptions): ItdClient;
|
|
3561
4077
|
|
|
4078
|
+
/**
|
|
4079
|
+
* Хранилище сессий нескольких аккаунтов.
|
|
4080
|
+
*
|
|
4081
|
+
* Отличается от {@link TokenStorage} тем, что каждый метод получает **имя аккаунта**:
|
|
4082
|
+
* так адаптер сам решает, как строить ключ, и Redis, БД или связка ключей получают то,
|
|
4083
|
+
* что им нужно. Имя приходит ровно тем, под которым аккаунт заведён в {@link ItdAccounts}:
|
|
4084
|
+
* библиотека его не нормализует и не экранирует — префиксы, экранирование и ограничения
|
|
4085
|
+
* на длину ключа остаются за адаптером.
|
|
4086
|
+
*
|
|
4087
|
+
* Все методы могут быть как синхронными, так и асинхронными.
|
|
4088
|
+
*
|
|
4089
|
+
* @example Своё хранилище поверх Redis
|
|
4090
|
+
* ```ts
|
|
4091
|
+
* const storage = createMultiTokenStorage({
|
|
4092
|
+
* get: async (account) => JSON.parse((await redis.get(`itd:session:${account}`)) ?? 'null'),
|
|
4093
|
+
* set: async (account, session) => {
|
|
4094
|
+
* await redis.set(`itd:session:${account}`, JSON.stringify(session));
|
|
4095
|
+
* await redis.sadd('itd:accounts', account);
|
|
4096
|
+
* },
|
|
4097
|
+
* clear: async (account) => {
|
|
4098
|
+
* await redis.del(`itd:session:${account}`);
|
|
4099
|
+
* await redis.srem('itd:accounts', account);
|
|
4100
|
+
* },
|
|
4101
|
+
* accounts: () => redis.smembers('itd:accounts'),
|
|
4102
|
+
* });
|
|
4103
|
+
* ```
|
|
4104
|
+
*/
|
|
4105
|
+
interface MultiTokenStorage {
|
|
4106
|
+
/** Прочитать сессию аккаунта. `null`, если её нет. */
|
|
4107
|
+
get(account: string): ItdSession | null | Promise<ItdSession | null>;
|
|
4108
|
+
/** Сохранить сессию аккаунта целиком. */
|
|
4109
|
+
set(account: string, session: ItdSession): void | Promise<void>;
|
|
4110
|
+
/** Удалить сессию аккаунта. Вызывается при выходе и при неудачном обновлении токена. */
|
|
4111
|
+
clear(account: string): void | Promise<void>;
|
|
4112
|
+
/**
|
|
4113
|
+
* Имена сохранённых записей — по ним `ItdAccounts.restore()` находит кандидатов
|
|
4114
|
+
* после перезапуска процесса.
|
|
4115
|
+
*
|
|
4116
|
+
* Список ведёт сам адаптер: у файлового и памятного он виден из самой записи,
|
|
4117
|
+
* а хранилищу «ключ — значение» придётся держать множество имён рядом с сессиями.
|
|
4118
|
+
* Перед восстановлением контейнер читает каждую запись и пропускает оставшийся после
|
|
4119
|
+
* выхода одинокий `deviceId`: без токена или refresh-сессии авторизоваться невозможно.
|
|
4120
|
+
* Пустой список означает лишь то, что кандидатов нет, — сами записи при этом могут быть
|
|
4121
|
+
* доступны по имени.
|
|
4122
|
+
*/
|
|
4123
|
+
accounts(): readonly string[] | Promise<readonly string[]>;
|
|
4124
|
+
}
|
|
4125
|
+
/**
|
|
4126
|
+
* Срез мультихранилища как обычное {@link TokenStorage} — в таком виде его получает
|
|
4127
|
+
* отдельный `ItdClient`, который про соседние аккаунты ничего не знает.
|
|
4128
|
+
*/
|
|
4129
|
+
declare function scopedTokenStorage(storage: MultiTokenStorage, account: string): TokenStorage;
|
|
4130
|
+
/**
|
|
4131
|
+
* Мультихранилище в памяти процесса — вариант по умолчанию.
|
|
4132
|
+
*
|
|
4133
|
+
* Сессии теряются при перезапуске. Для долгоживущих ботов возьмите `FileMultiTokenStorage`
|
|
4134
|
+
* из `itd-api/node` либо соберите своё через {@link createMultiTokenStorage}.
|
|
4135
|
+
*/
|
|
4136
|
+
declare class MemoryMultiTokenStorage implements MultiTokenStorage {
|
|
4137
|
+
#private;
|
|
4138
|
+
constructor(initial?: Readonly<Record<string, ItdSession>> | null);
|
|
4139
|
+
get(account: string): ItdSession | null;
|
|
4140
|
+
set(account: string, session: ItdSession): void;
|
|
4141
|
+
clear(account: string): void;
|
|
4142
|
+
accounts(): string[];
|
|
4143
|
+
}
|
|
4144
|
+
/**
|
|
4145
|
+
* Собирает {@link MultiTokenStorage} из четырёх функций — когда заводить класс избыточно.
|
|
4146
|
+
* Аналог `createTokenStorage` для нескольких аккаунтов.
|
|
4147
|
+
*/
|
|
4148
|
+
declare function createMultiTokenStorage(handlers: MultiTokenStorage): MultiTokenStorage;
|
|
4149
|
+
/** Источник, который читается и пишется целиком: файл, ключ в `localStorage`, строка в БД. */
|
|
4150
|
+
interface RecordStorageSource {
|
|
4151
|
+
/** Прочитать все сессии разом. `null` — записи ещё нет. */
|
|
4152
|
+
read(): Promise<Record<string, ItdSession> | null>;
|
|
4153
|
+
/** Записать все сессии разом. */
|
|
4154
|
+
write(record: Record<string, ItdSession>): Promise<void>;
|
|
4155
|
+
/** Вызывается вместо {@link RecordStorageSource.write}, когда не осталось ни одной сессии. */
|
|
4156
|
+
remove?(): Promise<void>;
|
|
4157
|
+
}
|
|
4158
|
+
/**
|
|
4159
|
+
* Мультихранилище поверх источника, который читается и пишется целиком.
|
|
4160
|
+
*
|
|
4161
|
+
* Решает главную проблему такого способа хранения — **гонку «прочитать, изменить,
|
|
4162
|
+
* записать»**: десять аккаунтов пишут в одну запись, и наивная реализация теряла бы
|
|
4163
|
+
* чужие сессии. Источник читается один раз, дальше слепок живёт в памяти, а записи
|
|
4164
|
+
* выстраиваются в цепочку и идут по очереди.
|
|
4165
|
+
*
|
|
4166
|
+
* Внутри процесса этого достаточно. Несколько процессов, пишущих в одну запись,
|
|
4167
|
+
* по-прежнему затирают друг друга — как и несколько экземпляров этого адаптера,
|
|
4168
|
+
* направленных на один источник в одном процессе.
|
|
4169
|
+
*/
|
|
4170
|
+
declare function createRecordMultiStorage(source: RecordStorageSource): MultiTokenStorage;
|
|
4171
|
+
|
|
4172
|
+
/** Как аккаунты делят между собой очередь запросов. */
|
|
4173
|
+
type RateLimitScope = 'account' | 'shared';
|
|
4174
|
+
/**
|
|
4175
|
+
* Опции конструктора {@link ItdAccounts}.
|
|
4176
|
+
*
|
|
4177
|
+
* Всё, что понимает `ItdClient`, кроме `auth` и `deviceId`: они у каждого аккаунта свои
|
|
4178
|
+
* и задаются в {@link ItdAccounts.addAccount}. Обычный `TokenStorage` клиента здесь заменён
|
|
4179
|
+
* общей опцией {@link ItdAccountsOptions.storage} типа {@link MultiTokenStorage}; контейнер
|
|
4180
|
+
* сам выдаёт каждому клиенту изолированный срез по имени. Общий `deviceId` особенно вреден —
|
|
4181
|
+
* сервер различает по нему записи в списке сессий, и один на всех сложил бы все аккаунты
|
|
4182
|
+
* в одну.
|
|
4183
|
+
*/
|
|
4184
|
+
interface ItdAccountsOptions extends Omit<ItdClientOptions, 'auth' | 'storage' | 'deviceId'> {
|
|
4185
|
+
/** Общее хранилище сессий всех аккаунтов. По умолчанию {@link MemoryMultiTokenStorage}. */
|
|
4186
|
+
storage?: MultiTokenStorage | undefined;
|
|
4187
|
+
/** Плагины, подключаемые каждому аккаунту, в том числе добавленному позже. */
|
|
4188
|
+
plugins?: readonly ItdPlugin[] | undefined;
|
|
4189
|
+
/**
|
|
4190
|
+
* Как делить очередь запросов. По умолчанию `'account'` — своя у каждого.
|
|
4191
|
+
*
|
|
4192
|
+
* Лимиты итд.com считаются по аккаунту, а при работе через разные прокси общая очередь
|
|
4193
|
+
* только мешает. Она нужна в другом случае: когда все аккаунты сидят на одном IP
|
|
4194
|
+
* и упираются в ограничение по адресу, — тогда `'shared'` разводит их запросы во времени
|
|
4195
|
+
* все разом, а не поаккаунтно.
|
|
4196
|
+
*
|
|
4197
|
+
* Настройки самой очереди берутся из общей опции `rateLimit`. Личный объект `rateLimit`
|
|
4198
|
+
* в этом режиме запрещён, потому что не может изменить уже созданную очередь;
|
|
4199
|
+
* `rateLimit: false` у отдельного аккаунта выводит его из неё.
|
|
4200
|
+
*/
|
|
4201
|
+
rateLimitScope?: RateLimitScope | undefined;
|
|
4202
|
+
}
|
|
4203
|
+
/**
|
|
4204
|
+
* Настройки одного аккаунта. Общее мультихранилище задаёт контейнер, а аккаунт получает
|
|
4205
|
+
* свой срез автоматически; остальное — как у `ItdClient`.
|
|
4206
|
+
*
|
|
4207
|
+
* При `rateLimitScope: 'shared'` объект `rateLimit` задаётся только контейнеру; аккаунту
|
|
4208
|
+
* разрешено передать `false`, чтобы не ставить его запросы в общую очередь.
|
|
4209
|
+
*/
|
|
4210
|
+
type AddAccountOptions = Omit<ItdClientOptions, 'storage'>;
|
|
4211
|
+
/** Что можно уточнить при удалении аккаунта. */
|
|
4212
|
+
interface RemoveAccountOptions {
|
|
4213
|
+
/**
|
|
4214
|
+
* Удалить и сохранённую сессию. По умолчанию `false` — аккаунт убирается только
|
|
4215
|
+
* из памяти, а его токены остаются в хранилище и переживут перезапуск.
|
|
4216
|
+
*/
|
|
4217
|
+
forget?: boolean | undefined;
|
|
4218
|
+
}
|
|
4219
|
+
/**
|
|
4220
|
+
* События авторизации всех аккаунтов сразу.
|
|
4221
|
+
*
|
|
4222
|
+
* Те же, что у одиночного клиента, плюс имя аккаунта: подписка на контейнер избавляет
|
|
4223
|
+
* от нужды вешать обработчик на каждого.
|
|
4224
|
+
*/
|
|
4225
|
+
interface AccountEvents {
|
|
4226
|
+
/** Токен получен или обновлён. */
|
|
4227
|
+
tokens: {
|
|
4228
|
+
account: string;
|
|
4229
|
+
accessToken: string;
|
|
4230
|
+
};
|
|
4231
|
+
/** Выполнен вход. */
|
|
4232
|
+
signIn: {
|
|
4233
|
+
account: string;
|
|
4234
|
+
accessToken: string;
|
|
4235
|
+
};
|
|
4236
|
+
/** Сессия очищена — вручную или из-за неудачного обновления. */
|
|
4237
|
+
signOut: {
|
|
4238
|
+
account: string;
|
|
4239
|
+
};
|
|
4240
|
+
/** Обновить сессию не удалось; дальнейшие запросы этого аккаунта будут падать с 401. */
|
|
4241
|
+
authError: {
|
|
4242
|
+
account: string;
|
|
4243
|
+
error: unknown;
|
|
4244
|
+
};
|
|
4245
|
+
}
|
|
4246
|
+
/**
|
|
4247
|
+
* Скрытые параметры конструктора — не часть публичного API.
|
|
4248
|
+
*
|
|
4249
|
+
* Через них точка входа `itd-api/node` подставляет свою фабрику клиентов, чтобы аккаунты
|
|
4250
|
+
* умели читать файлы с диска.
|
|
4251
|
+
*
|
|
4252
|
+
* @internal
|
|
4253
|
+
*/
|
|
4254
|
+
interface ItdAccountsInternals {
|
|
4255
|
+
createClient?: ((options: ItdClientOptions, internals: ItdClientInternals) => ItdClient) | undefined;
|
|
4256
|
+
}
|
|
4257
|
+
/**
|
|
4258
|
+
* Несколько аккаунтов итд.com в одном месте.
|
|
4259
|
+
*
|
|
4260
|
+
* Контейнер именованных `ItdClient`: каждый аккаунт получает собственный токен, cookie
|
|
4261
|
+
* и `deviceId`, а сессии всех складываются в одно хранилище — обычно в один файл, а не
|
|
4262
|
+
* в десяток. Имя аккаунта выбираете вы; сервер о нём ничего не знает.
|
|
4263
|
+
*
|
|
4264
|
+
* @example Бот на нескольких аккаунтах
|
|
4265
|
+
* ```ts
|
|
4266
|
+
* import { ItdAccounts, FileMultiTokenStorage } from 'itd-api/node';
|
|
4267
|
+
*
|
|
4268
|
+
* await using accounts = new ItdAccounts({
|
|
4269
|
+
* storage: new FileMultiTokenStorage('./.itd-sessions.json'),
|
|
4270
|
+
* rateLimit: { concurrency: 4 },
|
|
4271
|
+
* });
|
|
4272
|
+
*
|
|
4273
|
+
* // Восстанавливаем тех, кто уже входил раньше: токен возьмётся из хранилища.
|
|
4274
|
+
* await accounts.restore();
|
|
4275
|
+
*
|
|
4276
|
+
* if (!accounts.has('kiow')) {
|
|
4277
|
+
* accounts.addAccount('kiow', { auth: { email, password, getTurnstileToken } });
|
|
4278
|
+
* }
|
|
4279
|
+
*
|
|
4280
|
+
* await accounts.account('kiow').posts.create({ content: 'привет' });
|
|
4281
|
+
*
|
|
4282
|
+
* for (const [name, itd] of accounts) {
|
|
4283
|
+
* console.log(name, await itd.getUserId());
|
|
4284
|
+
* }
|
|
4285
|
+
* ```
|
|
4286
|
+
*/
|
|
4287
|
+
declare class ItdAccounts {
|
|
4288
|
+
#private;
|
|
4289
|
+
constructor(options?: ItdAccountsOptions, internals?: ItdAccountsInternals);
|
|
4290
|
+
/** Общее хранилище сессий — то же, что передано опцией `storage`. */
|
|
4291
|
+
get storage(): MultiTokenStorage;
|
|
4292
|
+
/** Сколько аккаунтов заведено. */
|
|
4293
|
+
get size(): number;
|
|
4294
|
+
/** Имена заведённых аккаунтов в порядке добавления. */
|
|
4295
|
+
names(): string[];
|
|
4296
|
+
/** Заведён ли аккаунт с таким именем. */
|
|
4297
|
+
has(name: string): boolean;
|
|
4298
|
+
/**
|
|
4299
|
+
* Заводит аккаунт.
|
|
4300
|
+
*
|
|
4301
|
+
* Возвращается обычный `ItdClient` — со всеми ресурсами, плагинами и `realtime()`.
|
|
4302
|
+
* Хранилище ему подставляется само: срез общего по имени аккаунта.
|
|
4303
|
+
*
|
|
4304
|
+
* Опция `auth` не обязательна: когда сессия этого аккаунта уже лежит в хранилище,
|
|
4305
|
+
* токен возьмётся оттуда, а истёкший продлится сам.
|
|
4306
|
+
*
|
|
4307
|
+
* @throws {ItdConfigError} если имя пустое или уже занято
|
|
4308
|
+
*
|
|
4309
|
+
* @example
|
|
4310
|
+
* ```ts
|
|
4311
|
+
* accounts.addAccount('bot', { auth: { email, password, getTurnstileToken } });
|
|
4312
|
+
* accounts.addAccount('reader', { auth: '<accessToken>' });
|
|
4313
|
+
* accounts.addAccount('через-прокси', { fetch: proxyFetch('socks5://…') });
|
|
4314
|
+
* ```
|
|
4315
|
+
*/
|
|
4316
|
+
addAccount(name: string, options?: AddAccountOptions): ItdClient;
|
|
4317
|
+
/**
|
|
4318
|
+
* Клиент аккаунта.
|
|
4319
|
+
*
|
|
4320
|
+
* @throws {ItdConfigError} если такого аккаунта нет
|
|
4321
|
+
*
|
|
4322
|
+
* @example
|
|
4323
|
+
* ```ts
|
|
4324
|
+
* await accounts.account('kiow').posts.like(postId);
|
|
4325
|
+
* ```
|
|
4326
|
+
*/
|
|
4327
|
+
account(name: string): ItdClient;
|
|
4328
|
+
/**
|
|
4329
|
+
* Поднимает аккаунты, сессии которых уже лежат в хранилище.
|
|
4330
|
+
*
|
|
4331
|
+
* То, ради чего мультихранилище знает свой состав: после перезапуска процесса
|
|
4332
|
+
* ни `auth`, ни капча не нужны — токен, `deviceId` и cookie берутся из сохранённого.
|
|
4333
|
+
* Уже заведённые аккаунты не трогаются. Записи, в которых после выхода остался только
|
|
4334
|
+
* `deviceId`, пропускаются: авторизованной сессии в них уже нет.
|
|
4335
|
+
*
|
|
4336
|
+
* @returns имена добавленных аккаунтов
|
|
4337
|
+
*
|
|
4338
|
+
* @example
|
|
4339
|
+
* ```ts
|
|
4340
|
+
* const restored = await accounts.restore();
|
|
4341
|
+
* console.log(`подняли ${restored.length} аккаунтов без единого входа`);
|
|
4342
|
+
* ```
|
|
4343
|
+
*/
|
|
4344
|
+
restore(): Promise<string[]>;
|
|
4345
|
+
/**
|
|
4346
|
+
* Убирает аккаунт: закрывает его клиента и, если попросить, забывает сессию.
|
|
4347
|
+
*
|
|
4348
|
+
* Сетевого запроса не выполняет. Чтобы завершить сессию на сервере, вызовите
|
|
4349
|
+
* `itd.auth.logout()` до удаления.
|
|
4350
|
+
*
|
|
4351
|
+
* @returns `false`, если такого аккаунта и не было
|
|
4352
|
+
*/
|
|
4353
|
+
removeAccount(name: string, options?: RemoveAccountOptions): Promise<boolean>;
|
|
4354
|
+
/**
|
|
4355
|
+
* Подключает плагин всем аккаунтам — и заведённым, и будущим.
|
|
4356
|
+
*
|
|
4357
|
+
* @throws {ItdConfigError} если плагин задан неверно или уже подключён
|
|
4358
|
+
*
|
|
4359
|
+
* @example
|
|
4360
|
+
* ```ts
|
|
4361
|
+
* accounts.use(crypt());
|
|
4362
|
+
* ```
|
|
4363
|
+
*/
|
|
4364
|
+
use(plugin: ItdPlugin): this;
|
|
4365
|
+
/**
|
|
4366
|
+
* Подписывается на события авторизации всех аккаунтов сразу.
|
|
4367
|
+
*
|
|
4368
|
+
* @returns функция отписки
|
|
4369
|
+
*
|
|
4370
|
+
* @example
|
|
4371
|
+
* ```ts
|
|
4372
|
+
* accounts.on('authError', ({ account }) => console.warn(`${account}: сессия потеряна`));
|
|
4373
|
+
* ```
|
|
4374
|
+
*/
|
|
4375
|
+
on<K extends keyof AccountEvents>(event: K, listener: Listener<AccountEvents[K]>): Unsubscribe;
|
|
4376
|
+
/**
|
|
4377
|
+
* Перебор аккаунтов парами «имя — клиент».
|
|
4378
|
+
*
|
|
4379
|
+
* @example
|
|
4380
|
+
* ```ts
|
|
4381
|
+
* for (const [name, itd] of accounts) {
|
|
4382
|
+
* const me = await itd.users.me();
|
|
4383
|
+
* console.log(name, me.nickname);
|
|
4384
|
+
* }
|
|
4385
|
+
* ```
|
|
4386
|
+
*/
|
|
4387
|
+
[Symbol.iterator](): IterableIterator<[string, ItdClient]>;
|
|
4388
|
+
/**
|
|
4389
|
+
* Закрывает все аккаунты и останавливает общую очередь.
|
|
4390
|
+
*
|
|
4391
|
+
* Аккаунты остаются в контейнере и работоспособны: новые запросы поднимут всё заново,
|
|
4392
|
+
* но уже созданные потоки уведомлений останутся закрытыми.
|
|
4393
|
+
*
|
|
4394
|
+
* @example
|
|
4395
|
+
* ```ts
|
|
4396
|
+
* await using accounts = new ItdAccounts({ storage });
|
|
4397
|
+
* // …работа…
|
|
4398
|
+
* // close() вызовется сам на выходе из блока
|
|
4399
|
+
* ```
|
|
4400
|
+
*/
|
|
4401
|
+
close(): Promise<void>;
|
|
4402
|
+
/** Позволяет использовать контейнер с `await using`. */
|
|
4403
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
4404
|
+
}
|
|
4405
|
+
/**
|
|
4406
|
+
* Создаёт контейнер аккаунтов.
|
|
4407
|
+
*
|
|
4408
|
+
* То же, что `new ItdAccounts(options)`, — для тех, кому привычнее фабрика.
|
|
4409
|
+
*/
|
|
4410
|
+
declare function createAccounts(options?: ItdAccountsOptions): ItdAccounts;
|
|
4411
|
+
|
|
3562
4412
|
/** Бренд, по которому ошибки библиотеки распознаются надёжнее, чем через `instanceof`. */
|
|
3563
4413
|
declare const ITD_ERROR: unique symbol;
|
|
3564
4414
|
/**
|
|
@@ -3846,6 +4696,19 @@ type AudioMimeType = (typeof AUDIO_MIME_TYPES)[number];
|
|
|
3846
4696
|
declare const ALLOWED_MIME_TYPES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp", "image/avif", "image/heic", "image/heif", "video/mp4", "video/webm", "video/quicktime", "audio/ogg"];
|
|
3847
4697
|
type AllowedMimeType = (typeof ALLOWED_MIME_TYPES)[number];
|
|
3848
4698
|
|
|
4699
|
+
/**
|
|
4700
|
+
* Приводит отметку времени без часового пояса к ISO-8601, считая её временем UTC.
|
|
4701
|
+
*
|
|
4702
|
+
* Строку другого вида возвращает нетронутой.
|
|
4703
|
+
*
|
|
4704
|
+
* @example
|
|
4705
|
+
* ```ts
|
|
4706
|
+
* utcStampToIso('2026-07-23 23:14:25'); // '2026-07-23T23:14:25Z'
|
|
4707
|
+
* utcStampToIso('2026-07-23T23:14:25Z'); // без изменений
|
|
4708
|
+
* ```
|
|
4709
|
+
*/
|
|
4710
|
+
declare function utcStampToIso(value: string): string;
|
|
4711
|
+
|
|
3849
4712
|
/**
|
|
3850
4713
|
* Собирает текст уведомления на русском.
|
|
3851
4714
|
*
|
|
@@ -3930,4 +4793,29 @@ interface SseTransportOptions {
|
|
|
3930
4793
|
idleTimeout?: number;
|
|
3931
4794
|
}
|
|
3932
4795
|
|
|
3933
|
-
|
|
4796
|
+
/** Формат результата {@link renderSpans}. */
|
|
4797
|
+
type SpanRenderFormat = 'html' | 'markdown' | 'ansi';
|
|
4798
|
+
interface RenderSpansOptions {
|
|
4799
|
+
/** Формат результата. По умолчанию `html`. */
|
|
4800
|
+
format?: SpanRenderFormat;
|
|
4801
|
+
/** Строит адрес упоминания. `null` или `undefined` отключает ссылку. */
|
|
4802
|
+
mentionUrl?: (username: string) => string | null | undefined;
|
|
4803
|
+
/** Строит адрес хэштега. `null` или `undefined` отключает ссылку. */
|
|
4804
|
+
hashtagUrl?: (tag: string) => string | null | undefined;
|
|
4805
|
+
/**
|
|
4806
|
+
* Префикс HTML-классов. По умолчанию `itd`; пустая строка или `null` отключает классы.
|
|
4807
|
+
*
|
|
4808
|
+
* Например, `app` создаёт `app-mention`, `app-hashtag`, `app-quote` и `app-spoiler`.
|
|
4809
|
+
*/
|
|
4810
|
+
classPrefix?: string | null;
|
|
4811
|
+
}
|
|
4812
|
+
/**
|
|
4813
|
+
* Преобразует текст и wire-разметку API в безопасный HTML, Markdown или ANSI.
|
|
4814
|
+
*
|
|
4815
|
+
* Некорректные серверные spans игнорируются либо обрезаются по границам строки. Пересекающиеся
|
|
4816
|
+
* spans разбиваются на независимые сегменты, поэтому HTML остаётся корректно вложенным.
|
|
4817
|
+
* Отсутствующий массив считается пустым; формат по умолчанию — HTML.
|
|
4818
|
+
*/
|
|
4819
|
+
declare function renderSpans(content: string, spans?: readonly Span[] | null | undefined, options?: RenderSpansOptions): string;
|
|
4820
|
+
|
|
4821
|
+
export { DetectedRuntime as $, ALLOWED_MIME_TYPES as A, BUILT_IN_SERVICES as B, type CaptchaCredentials as C, type ClientHooks as D, type Comment as E, type FileReader as F, CommentBuilder as G, type CommentInput as H, type ItdSession as I, type CommentReplyTo as J, CommentSort as K, type CommentsParams as L, type MultiTokenStorage as M, CommentsResource as N, type CreateCommentInput as O, type CreatePollInput as P, type CreatePostInput as Q, type CreateReportInput as R, type Credentials as S, type TokenStorage as T, type CredentialsAuth as U, DEFAULT_BASE_URL as V, DEFAULT_STATUS_BASE_URL as W, DEFAULT_TIMEOUT as X, DEFAULT_UPLOAD_TIMEOUT as Y, DEFAULT_USER_AGENT as Z, DEVICE_ID_HEADER as _, ItdAccounts as a, type PageState as a$, type DwellEntry as a0, type ErrorContextHook as a1, type FeedParams as a2, FeedTab as a3, type FileInput as a4, FilesResource as a5, type FollowResult as a6, type ForgotPasswordInput as a7, type Hashtag as a8, type HashtagPostsParams as a9, ItdServerError as aA, ItdTimeoutError as aB, ItdValidationError as aC, LIBRARY_VERSION as aD, type LikeResult as aE, LikesVisibility as aF, type Listener as aG, LocalStorageTokenStorage as aH, type Logger as aI, type Loose as aJ, MAX_RECONNECT_ATTEMPTS as aK, MarkupBuilder as aL, type MarkupContent as aM, type MarkupInput as aN, type MarkupSpan as aO, MemoryMultiTokenStorage as aP, MemoryTokenStorage as aQ, type MyProfile as aR, NOTIFICATION_TYPE_ALIASES as aS, type Notification as aT, type NotificationEvent as aU, type NotificationListParams as aV, type NotificationSettings as aW, NotificationType as aX, NotificationsResource as aY, OAuthProvider as aZ, type Page as a_, HashtagsResource as aa, IMAGE_MIME_TYPES as ab, type ImageMimeType as ac, IncidentKind as ad, type InteractionEntry as ae, InteractionType as af, type IsoDate as ag, ItdAbortError as ah, ItdApiError as ai, type ItdApiErrorInit as aj, ItdApiErrorKind as ak, ItdAuthError as al, type ItdBuilder as am, ItdConfigError as an, ItdConflictError as ao, ItdError as ap, ItdErrorCode as aq, ItdErrorKind as ar, type ItdFieldErrors as as, ItdForbiddenError as at, ItdNetworkError as au, ItdNotFoundError as av, ItdPhoneVerificationError as aw, type ItdPlugin as ax, ItdRateLimitError as ay, ItdRealtime as az, type ItdAccountsOptions as b, type ServiceDefinition as b$, PaginationMode as b0, Paginator as b1, type PaginatorOptions as b2, type PaymentMethod as b3, type Pin as b4, type PinPostResult as b5, type PinsResult as b6, PlatformResource as b7, type PlatformStatus as b8, type PluginContext as b9, type RealtimeEvents as bA, type RealtimeOptions as bB, RealtimeStatus as bC, type RealtimeTransport as bD, RealtimeTransportKind as bE, type ReconnectOptions as bF, type RecordStorageSource as bG, type RemoveAccountOptions as bH, type RenderSpansOptions as bI, type RepliesParams as bJ, type Report as bK, ReportBuilder as bL, type ReportInput as bM, ReportReason as bN, ReportTargetType as bO, ReportsResource as bP, type RequestContext as bQ, type RequestOptions as bR, type ResetPasswordInput as bS, type ResponseContext as bT, type RetryContext as bU, type RetryOptions as bV, RuntimeMode as bW, STATUS_SERVICE as bX, STREAM_PATH as bY, SearchResource as bZ, type SearchResult as b_, type Poll as ba, PollBuilder as bb, type PollInput as bc, type PollOption as bd, type PollTransportOptions as be, type Portal as bf, type Post as bg, PostBuilder as bh, type PostInput as bi, type PostStats as bj, type PostUpdateInput as bk, PostsResource as bl, type PrivacySettings as bm, type Profile as bn, type PublicProfile as bo, type QueryParams as bp, type QueryValue as bq, RECONNECT_BACKOFF as br, RECONNECT_JITTER as bs, REFRESH_COOKIE as bt, REFRESH_COOKIE_PATH as bu, REQUEST_OPTION_KEYS as bv, type RateLimitOptions as bw, type RateLimitScope as bx, type RawRequestOptions as by, type RealtimeDeps as bz, ItdClient as c, mapPage as c$, ServiceRegistry as c0, ServiceState as c1, type ServiceStatus as c2, type Session as c3, type SignInResult as c4, SignInStatus as c5, type Span as c6, type SpanRenderFormat as c7, SpanType as c8, type SseTransportOptions as c9, VIDEO_MIME_TYPES as cA, VerificationResource as cB, type VerificationStatus as cC, type VideoMimeType as cD, ViewReason as cE, ViewSource as cF, WallAccess as cG, autoSpans as cH, canonicalNotificationType as cI, comment as cJ, createMultiTokenStorage as cK, createRecordMultiStorage as cL, createTokenStorage as cM, formatNotificationText as cN, isBuilder as cO, isItdApiError as cP, isItdAuthError as cQ, isItdConflictError as cR, isItdError as cS, isItdForbiddenError as cT, isItdNotFoundError as cU, isItdPhoneVerificationError as cV, isItdRateLimitError as cW, isItdServerError as cX, isItdValidationError as cY, isKnownNotificationType as cZ, isMyProfile as c_, type StatusDay as ca, type StatusIncidentLine as cb, type Subscription as cc, SubscriptionResource as cd, type SubscriptionState as ce, TURNSTILE_SITE_KEY as cf, type TelemetryOptions as cg, TelemetryResource as ch, type TextMarkup as ci, type Transformer as cj, type TransportContext as ck, type TransportEvent as cl, UnauthorizedStreamError as cm, type Unsubscribe as cn, type UpdateNotificationSettingsInput as co, type UpdatePostInput as cp, type UpdatePrivacyInput as cq, type UpdateProfileInput as cr, type UploadOptions as cs, type UploadedFile as ct, type UserId as cu, type UserListParams as cv, type UserPostsParams as cw, type UserRef as cx, type UserSummary as cy, UsersResource as cz, type ItdClientOptions as d, markup as d0, normalizeNotification as d1, poll as d2, post as d3, readNotificationEvent as d4, readUnreadCountEvent as d5, renderSpans as d6, report as d7, resolveNotificationUrl as d8, scopedTokenStorage as d9, statusDays as da, toDate as db, utcStampToIso as dc, createAccounts as dd, createClient as de, type ItdClientInternals as e, AUDIO_MIME_TYPES as f, AUTH_FLAG_COOKIE as g, AUTH_PATHS as h, AccessType as i, type AccountEvents as j, type Actor as k, type AddAccountOptions as l, type AllowedMimeType as m, type Announcement as n, type AnnouncementButton as o, type Attachment as p, AttachmentType as q, type AudioMimeType as r, type AuthEvents as s, type AuthInput as t, AuthResource as u, type Author as v, type AutoSpansOptions as w, type BuilderInput as x, type ChangelogEntry as y, type Clan as z };
|