itd-api 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +12 -12
  2. package/dist/events/index.cjs +53 -0
  3. package/dist/events/index.d.cts +3 -0
  4. package/dist/events/index.d.ts +3 -0
  5. package/dist/events/index.js +5 -0
  6. package/dist/index.cjs +215 -194
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +66 -63
  9. package/dist/index.d.ts +66 -63
  10. package/dist/index.js +197 -179
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +4 -4
  13. package/dist/node/index.d.cts +1 -1
  14. package/dist/node/index.d.ts +1 -1
  15. package/dist/node/index.js +4 -4
  16. package/dist/rest/index.cjs +20 -26
  17. package/dist/rest/index.cjs.map +1 -1
  18. package/dist/rest/index.d.cts +7 -7
  19. package/dist/rest/index.d.ts +7 -7
  20. package/dist/rest/index.js +14 -20
  21. package/dist/rest/index.js.map +1 -1
  22. package/dist/shared/{errors-DfU8M5eS.cjs → errors-BmP3TKoW.cjs} +3 -3
  23. package/dist/shared/{errors-DfU8M5eS.cjs.map → errors-BmP3TKoW.cjs.map} +1 -1
  24. package/dist/shared/{errors-Bhrd2fJd.js → errors-GI10kZxk.js} +3 -3
  25. package/dist/shared/{errors-Bhrd2fJd.js.map → errors-GI10kZxk.js.map} +1 -1
  26. package/dist/shared/events-Br2r7coi.d.cts +698 -0
  27. package/dist/shared/events-QyhQZrnC.d.ts +698 -0
  28. package/dist/shared/{websocket-BLR8eVJV.js → events-TfhKh26b.js} +770 -490
  29. package/dist/shared/events-TfhKh26b.js.map +1 -0
  30. package/dist/shared/{websocket-C_eI4H2o.cjs → events-iTteVsd_.cjs} +834 -518
  31. package/dist/shared/events-iTteVsd_.cjs.map +1 -0
  32. package/dist/shared/{multi-storage-CkvTUC5m.js → multi-storage-1AEZTczk.js} +4 -4
  33. package/dist/shared/{multi-storage-CkvTUC5m.js.map → multi-storage-1AEZTczk.js.map} +1 -1
  34. package/dist/shared/{multi-storage--yTEqiod.cjs → multi-storage-CCUgkqvI.cjs} +6 -6
  35. package/dist/shared/{multi-storage--yTEqiod.cjs.map → multi-storage-CCUgkqvI.cjs.map} +1 -1
  36. package/dist/shared/{options-DtATYdLr.js → options-BNP633A5.js} +8 -6
  37. package/dist/shared/options-BNP633A5.js.map +1 -0
  38. package/dist/shared/{options-Dg5N3r1V.cjs → options-BUfoHE9G.cjs} +8 -6
  39. package/dist/shared/options-BUfoHE9G.cjs.map +1 -0
  40. package/dist/shared/{cookies-DZwFq6kr.cjs → redact-DB9EMGJx.cjs} +301 -2
  41. package/dist/shared/redact-DB9EMGJx.cjs.map +1 -0
  42. package/dist/shared/{cookies-tX2sNwxb.js → redact-FNK29Fv-.js} +224 -3
  43. package/dist/shared/redact-FNK29Fv-.js.map +1 -0
  44. package/dist/shared/{render-DO0F5YSm.d.cts → render-BszcKF7S.d.cts} +430 -313
  45. package/dist/shared/{render-C6HRPs10.js → render-CiL1VS0b.js} +925 -582
  46. package/dist/shared/render-CiL1VS0b.js.map +1 -0
  47. package/dist/shared/{render-mcuELiYi.cjs → render-DNTESBSl.cjs} +967 -618
  48. package/dist/shared/render-DNTESBSl.cjs.map +1 -0
  49. package/dist/shared/{render-CgwKdOzu.d.ts → render-DVB7T8pm.d.ts} +430 -313
  50. package/dist/shared/{storage-BPJR_k4-.cjs → storage-BLmXmzKF.cjs} +2 -2
  51. package/dist/shared/{storage-BPJR_k4-.cjs.map → storage-BLmXmzKF.cjs.map} +1 -1
  52. package/dist/shared/{storage-D86edNCB.js → storage-CCxn0Kkv.js} +2 -2
  53. package/dist/shared/{storage-D86edNCB.js.map → storage-CCxn0Kkv.js.map} +1 -1
  54. package/dist/shared/{url-IU0xN9wX.js → url-B3ocFlHj.js} +434 -408
  55. package/dist/shared/url-B3ocFlHj.js.map +1 -0
  56. package/dist/shared/{url-DTfZ2toq.d.cts → url-Be9jlWRv.d.cts} +1228 -1188
  57. package/dist/shared/{url-DTfZ2toq.d.ts → url-Be9jlWRv.d.ts} +1228 -1188
  58. package/dist/shared/{url-BaMCQpYH.cjs → url-CFN1sT9S.cjs} +497 -465
  59. package/dist/shared/url-CFN1sT9S.cjs.map +1 -0
  60. package/dist/web/index.cjs +2 -2
  61. package/dist/web/index.js +2 -2
  62. package/package.json +16 -15
  63. package/dist/realtime/index.cjs +0 -165
  64. package/dist/realtime/index.cjs.map +0 -1
  65. package/dist/realtime/index.d.cts +0 -51
  66. package/dist/realtime/index.d.ts +0 -51
  67. package/dist/realtime/index.js +0 -120
  68. package/dist/realtime/index.js.map +0 -1
  69. package/dist/shared/auth-provider-CG8oCQ9F.cjs +0 -108
  70. package/dist/shared/auth-provider-CG8oCQ9F.cjs.map +0 -1
  71. package/dist/shared/auth-provider-mYqxsSVa.js +0 -91
  72. package/dist/shared/auth-provider-mYqxsSVa.js.map +0 -1
  73. package/dist/shared/cookies-DZwFq6kr.cjs.map +0 -1
  74. package/dist/shared/cookies-tX2sNwxb.js.map +0 -1
  75. package/dist/shared/options-Dg5N3r1V.cjs.map +0 -1
  76. package/dist/shared/options-DtATYdLr.js.map +0 -1
  77. package/dist/shared/render-C6HRPs10.js.map +0 -1
  78. package/dist/shared/render-mcuELiYi.cjs.map +0 -1
  79. package/dist/shared/url-BaMCQpYH.cjs.map +0 -1
  80. package/dist/shared/url-IU0xN9wX.js.map +0 -1
  81. package/dist/shared/websocket-BLR8eVJV.js.map +0 -1
  82. package/dist/shared/websocket-C_eI4H2o.cjs.map +0 -1
  83. package/dist/shared/websocket-DF7XIMiX.d.cts +0 -562
  84. package/dist/shared/websocket-DYKBr8HF.d.ts +0 -562
@@ -1,31 +1,229 @@
1
- import { $ as UserSummary, B as Notification, Ct as ReportReason, Dt as ViewReason, Ft as Logger, G as FollowResult, It as OperationRequestOptions, J as PinsResult, K as MyProfile, Lt as PaginationOptions, Mt as Unsubscribe, Ot as ViewSource, Qt as ServiceDefinition, Tt as ServiceState, V as NotificationSettings, Vt as RawRequestOptions, W as Author, Wt as RequestOptions, X as Profile, Xt as QueryParams, Y as PrivacySettings, Z as PublicProfile, _n as RetrySafety, _t as InteractionType, bt as Loose, ct as IsoDate, dt as UserRef, et as AuthIdentity, gn as OperationMethod, gt as IncidentKind, ht as FeedTab, lt as Span, mt as CommentSort, pt as AttachmentType, rn as BuiltInOperationId, sn as OperationId, tn as ItdClock, ut as UserId, wt as ReportTargetType, zt as RateLimitBucketOverride } from "./url-DTfZ2toq.js";
1
+ import { Bt as ItdClock, Et as RawRequestOptions, Ft as QueryParams, Ht as BuiltInOperationId, Kt as OperationId, Lt as ServiceDefinition, St as PaginationOptions, _ as Profile, _n as ServiceState, _t as RetrySafety, an as AttachmentType, b as UserSummary, bn as ViewSource, bt as Logger, c as NotificationSettings, cn as FeedTab, ct as Unsubscribe, d as Author, en as IsoDate, et as ClientConnection, f as FollowResult, g as PrivacySettings, gn as ReportTargetType, gt as OperationMethod, h as PinsResult, hn as ReportReason, ht as OperationMetadata, kt as RequestOptions, ln as IncidentKind, mt as OperationContract, nn as UserId, on as CommentSort, p as MyProfile, pn as Loose, pt as OperationAnnotations, rn as UserRef, s as Notification, tn as Span, tt as AuthIdentity, un as InteractionType, v as PublicProfile, wt as RateLimitBucketOverride, xt as OperationRequestOptions, yn as ViewReason } from "./url-Be9jlWRv.js";
2
2
  import { c as LazyFile, d as UrlFileOptions, i as FileStreamContent, l as StreamFile, n as FileContext, o as FileTransferMode, r as FileInput, s as FromStreamOptions } from "./contracts-BoT7msmq.js";
3
- //#region src/core/catalog.d.ts
3
+ //#region src/core/plugins/contracts.d.ts
4
+ /**
5
+ * Обёртка одной логической операции.
6
+ *
7
+ * Вызывается один раз независимо от повторов и обновления авторизации. Может изменить
8
+ * параметры запроса, обработать публичный результат метода или завершить операцию локально.
9
+ * `operationId`, HTTP-метод и безопасность повтора задаются операцией.
10
+ *
11
+ * @param request описание логической операции; не изменяйте сам объект — передайте копию в `next`
12
+ * @param next следующая обёртка либо выполнение операции
13
+ * `next()` возвращает результат публичного метода. Если обёртка не вызывает `next`, её
14
+ * собственный результат считается готовым и повторно не нормализуется.
15
+ *
16
+ * @returns результат в том виде, в котором его получит вызывающий код
17
+ *
18
+ * @example Дописать заголовок ко всем операциям
19
+ * ```ts
20
+ * const transformer: OperationTransformer = (request, next) =>
21
+ * next({ ...request, headers: { ...request.headers, 'X-Trace': trace() } });
22
+ * ```
23
+ */
24
+ type OperationTransformer = (request: OperationRequestOptions, next: (request: OperationRequestOptions) => Promise<unknown>) => Promise<unknown>;
25
+ /** Финальные данные одной транспортной попытки. */
26
+ interface AttemptContext {
27
+ /** Постоянный идентификатор операции. */
28
+ readonly operationId: OperationId;
29
+ /** Нормализованный HTTP-метод. */
30
+ readonly method: string;
31
+ /** Исходный путь операции до выбора сервиса или `baseUrl`. */
32
+ readonly path: string;
33
+ /** Полный URL со строкой запроса. */
34
+ readonly url: string;
35
+ /** Итоговые изменяемые заголовки. */
36
+ readonly headers: Headers;
37
+ /** Номер сетевой попытки, начиная с 1. */
38
+ readonly attempt: number;
39
+ /** Подготовленное тело запроса. Поток нельзя читать заранее. */
40
+ readonly body: BodyInit | undefined;
41
+ /** Общий сигнал отмены и таймаута этой попытки. */
42
+ readonly signal: AbortSignal;
43
+ }
44
+ /**
45
+ * Продолжение цепочки перехватчиков. Можно вызвать только один раз.
46
+ */
47
+ type AttemptNext = () => Promise<Response>;
4
48
  /**
5
- * Всё, что ядро знает о предметной области.
49
+ * Обёртка одной транспортной попытки.
50
+ *
51
+ * Получает уже разрешённый URL, итоговые заголовки, подготовленное тело и номер попытки.
52
+ * Может изменить заголовки, измерить задержку, обработать сырой `Response` или вернуть
53
+ * созданный вручную `Response`.
6
54
  *
7
- * Ядро исполняет операцию, не зная, что такое пост, комментарий или профиль: оно спрашивает
8
- * каталог о повторяемости, методе и счётчике частоты, а таблицы конкретного API живут
9
- * в доменном слое. Именно эта граница позволяет позже вынести retry и планировщик очереди
10
- * в отдельные слоты executor, не таща за ними каталог эндпоинтов.
55
+ * Вызывается для каждой сетевой попытки. Если перехватчик читает тело ответа, используйте
56
+ * `response.clone()`: исходный ответ дальше обрабатывает транспорт.
57
+ *
58
+ * @param context окончательные данные текущей транспортной попытки
59
+ * @param next следующий перехватчик либо вызов `fetch`
60
+ * @returns исходный или синтетический сырой `Response`
61
+ */
62
+ type AttemptInterceptor = (context: AttemptContext, next: AttemptNext) => Promise<Response>;
63
+ /** Регистрация расширений логической операции. */
64
+ interface OperationExtensions {
65
+ /** Возвращает неизменяемые метаданные зарегистрированной операции. */
66
+ get(operationId: OperationId): OperationMetadata | undefined;
67
+ /**
68
+ * Подключает обёртку операции.
69
+ *
70
+ * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
71
+ * идемпотентна и снимает только эту регистрацию.
72
+ */
73
+ use(transformer: OperationTransformer): Unsubscribe;
74
+ }
75
+ /** Регистрация расширений транспортной попытки. */
76
+ interface AttemptExtensions {
77
+ /**
78
+ * Подключает перехватчик попытки.
79
+ *
80
+ * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
81
+ * идемпотентна и снимает только эту регистрацию.
82
+ */
83
+ use(interceptor: AttemptInterceptor): Unsubscribe;
84
+ }
85
+ /**
86
+ * Функция освобождения ресурсов плагина.
87
+ */
88
+ type PluginTeardown = () => void | Promise<void>;
89
+ /** API, доступный плагину при подключении. */
90
+ interface PluginApi {
91
+ /** Базовый URL клиента — например чтобы разобрать абсолютные ссылки из ответа. */
92
+ baseUrl: string;
93
+ /** Логгер клиента, если он включён. */
94
+ logger: Logger | undefined;
95
+ /** Обёртки логической операции. */
96
+ operations: OperationExtensions;
97
+ /** Перехватчики сетевой попытки. */
98
+ attempts: AttemptExtensions;
99
+ /**
100
+ * Внутренний идентификатор текущей авторизации.
101
+ */
102
+ getAuthScope?: (() => string) | undefined;
103
+ /**
104
+ * Загружает сессию и возвращает идентификаторы аккаунта и конкретной сессии из JWT.
105
+ *
106
+ * Используйте для общего состояния нескольких клиентов одного аккаунта.
107
+ */
108
+ getAuthIdentity?: (() => Promise<AuthIdentity>) | undefined;
109
+ }
110
+ /**
111
+ * Плагин клиента.
112
+ *
113
+ * Подключается через `itd.use(plugin)` и регистрирует расширения одного или обоих уровней:
114
+ * {@link OperationTransformer} для логической операции и {@link AttemptInterceptor} для
115
+ * отдельной транспортной попытки.
116
+ *
117
+ * Настройки отдельного вызова плагин объявляет своим полем в `RequestExtensions` через
118
+ * дополнение интерфейса. Пользователь передаёт их в `RequestOptions.extensions`, а обёртка
119
+ * операции читает поле своего плагина.
120
+ *
121
+ * @example Логирование логических операций
122
+ * ```ts
123
+ * const logging: ClientPlugin = {
124
+ * name: 'logging',
125
+ * install({ operations, logger }) {
126
+ * operations.use(async (request, next) => {
127
+ * logger?.info(`${request.method} ${request.path}`);
128
+ * return next(request);
129
+ * });
130
+ * },
131
+ * };
132
+ *
133
+ * itd.use(logging);
134
+ * ```
135
+ */
136
+ interface ClientPlugin {
137
+ /** Имя плагина. Должно быть уникальным: повторное подключение — ошибка. */
138
+ name: string;
139
+ /** Плагины, которые обязаны быть подключены раньше этого. */
140
+ requires?: readonly string[];
141
+ /** Несовместимые плагины. Достаточно объявить конфликт с одной стороны. */
142
+ conflicts?: readonly string[];
143
+ /** Имена плагинов, снаружи которых должны стоять оба вида расширений этого плагина. */
144
+ before?: readonly string[];
145
+ /** Имена плагинов, внутри которых должны стоять оба вида расширений этого плагина. */
146
+ after?: readonly string[];
147
+ /**
148
+ * Устанавливает плагин.
149
+ *
150
+ * Может вернуть функцию освобождения ресурсов. Она вызывается при `unuse()` или
151
+ * окончательном `dispose()` клиента и может быть асинхронной. Сам `install()` синхронный:
152
+ * регистрация расширений завершается до того, как `use()` вернёт управление.
153
+ */
154
+ install(api: PluginApi): void | PluginTeardown;
155
+ }
156
+ //#endregion
157
+ //#region src/core/plugins/registry.d.ts
158
+ /** Что реестру нужно знать об остановке. @internal */
159
+ interface PluginRegistryOptions {
160
+ /** Срок ожидания операций плагина при его отключении, мс. `0` — ждать без ограничения. */
161
+ shutdownTimeout: number;
162
+ clock: ItdClock;
163
+ /** Возвращает публичные метаданные встроенной или feature-операции. */
164
+ operationMetadata: (operationId: OperationRequestOptions['operationId']) => OperationMetadata | undefined;
165
+ }
166
+ /**
167
+ * Список подключённых плагинов и зарегистрированных ими расширений.
168
+ *
169
+ * {@link run} собирает operation transformers вокруг одной логической операции и прикрепляет
170
+ * к ней неизменяемый снимок attempt interceptors. Transport исполняет этот снимок отдельно
171
+ * для каждой сетевой попытки. Порядок плагинов одинаков для обеих цепочек.
11
172
  *
12
173
  * @internal
13
174
  */
14
- interface OperationCatalog {
15
- /** Безопасность повтора операции. `undefined` — операция каталогу неизвестна. */
16
- retrySafetyOf(id: string): RetrySafety | undefined;
17
- /** HTTP-метод операции. `undefined` — операция каталогу неизвестна. */
18
- methodOf(id: string): OperationMethod | undefined;
19
- /** Счётчик частоты операции. Для неизвестной возвращает {@link defaultBucket}. */
20
- bucketOf(id: string): string;
21
- /** Известно ли каталогу имя бакета. */
22
- isKnownBucket(name: string): boolean;
23
- /** Ёмкость бакетов до первого ответа сервера, запросов в минуту. */
24
- readonly bucketLimits: Readonly<Record<string, number>>;
25
- /** Встроенные поправки бакетов, например предел одновременности загрузки файлов. */
26
- readonly bucketOverrides: Readonly<Record<string, RateLimitBucketOverride>>;
27
- /** Счётчик, из которого списывается путь без собственного правила на сервере. */
28
- readonly defaultBucket: string;
175
+ declare class PluginRegistry {
176
+ #private;
177
+ constructor(options: PluginRegistryOptions);
178
+ /** Сколько плагинов подключено. */
179
+ get size(): number;
180
+ /** Имена плагинов в фактическом порядке выполнения. */
181
+ names(): string[];
182
+ /** Подключён ли плагин с таким именем. */
183
+ has(name: string): boolean;
184
+ /** Проверяет добавление без вызова `install()`. @internal */
185
+ assertCanAdd(plugin: ClientPlugin): void;
186
+ /** Проверяет удаление без изменения реестра. @internal */
187
+ assertCanRemove(name: string): void;
188
+ /**
189
+ * Подключает плагин.
190
+ *
191
+ * `install()` выполняется синхронно. Каждая регистрация принадлежит установившему её
192
+ * плагину и участвует в общем порядке `before`/`after`.
193
+ *
194
+ * @throws {ItdConfigError} если плагин задан неверно, уже подключён или нарушает зависимости
195
+ */
196
+ add(plugin: ClientPlugin, context: Omit<PluginApi, 'operations' | 'attempts'>): void;
197
+ /**
198
+ * Отключает плагин и вызывает его функцию очистки.
199
+ *
200
+ * Новые запросы перестают видеть расширения плагина сразу. Снимок уже начавшейся операции,
201
+ * включая её будущие retry, остаётся неизменным; очистка дождётся завершения операции,
202
+ * но не дольше отведённого срока.
203
+ *
204
+ * @returns `false`, если такого плагина не было
205
+ * @throws {ItdStateError} если операции плагина не завершились за отведённый срок
206
+ */
207
+ remove(name: string): Promise<boolean>;
208
+ /**
209
+ * Отключает все плагины окончательно.
210
+ *
211
+ * Очистка идёт изнутри наружу — в порядке, обратном выполнению расширений. Срок ожидания
212
+ * общий на все плагины.
213
+ */
214
+ dispose(): Promise<void>;
215
+ /**
216
+ * Прогоняет запрос через operation transformers и прикрепляет attempt interceptors.
217
+ *
218
+ * Снимки обеих цепочек берутся в начале: `unuse()` влияет на новые операции, но не меняет
219
+ * уже выполняющуюся и не удаляет interceptors из её последующих retry.
220
+ *
221
+ * Каждый `next` одноразовый: transformer может завершить операцию сам, но не может породить
222
+ * вторую — для `posts.create` это была бы вторая публикация.
223
+ *
224
+ * @param execute выполнение логической операции, вызываемое самым внутренним transformer
225
+ */
226
+ run(request: OperationRequestOptions, execute: (request: OperationRequestOptions) => Promise<unknown>): Promise<unknown>;
29
227
  }
30
228
  //#endregion
31
229
  //#region src/core/execution/pipeline.d.ts
@@ -82,15 +280,15 @@ type RequestHandler = (request: PipelineRequest) => Promise<unknown>;
82
280
  interface HttpClientDeps {
83
281
  /** Готовый обработчик — вся цепочка слоёв поверх транспорта. */
84
282
  handler: RequestHandler;
283
+ plugins: PluginRegistry;
85
284
  baseUrl: string;
86
- /** Каталог, из которого берётся HTTP-метод семантической операции. */
87
- catalog: OperationCatalog;
88
285
  }
286
+ /** Параметры операции без ID и метода, заданных её контрактом. @internal */
287
+ type HttpOperationOptions = Omit<PipelineRequest, 'operationId' | 'method'>;
89
288
  /**
90
289
  * Точка входа ресурсов в конвейер запросов.
91
290
  *
92
- * Принимает готовый обработчик цепочку слоёв поверх транспорта, собранную
93
- * во внутреннем runtime клиента, — и отдаёт ресурсам методы `request`/`operation`.
291
+ * Принимает готовую цепочку обработки и предоставляет ресурсам методы `request`/`execute`.
94
292
  * О слоях и их порядке ресурсы не знают.
95
293
  */
96
294
  declare class HttpClient {
@@ -108,23 +306,91 @@ declare class HttpClient {
108
306
  * @throws {ItdNetworkError} если запрос не дошёл до сервера
109
307
  */
110
308
  request<T = unknown>(options: PipelineRequestInput): Promise<T>;
111
- /** Выполняет встроенную семантическую операцию, подставляя её HTTP-метод из каталога. */
112
- operation<T = unknown>(operationId: BuiltInOperationId, options: Omit<PipelineRequest, 'operationId' | 'method'>): Promise<T>;
309
+ /** Выполняет контракт операции; `next()` плагина возвращает результат после `read`. */
310
+ execute<T, TId extends OperationId>(operation: OperationContract<T, TId>, options: HttpOperationOptions): Promise<T>;
113
311
  /** Выполняет внутреннюю операцию финализации после начала `ItdClient.dispose()`. @internal */
114
- cleanupOperation<T = unknown>(operationId: BuiltInOperationId, options: Omit<PipelineRequest, 'operationId' | 'method'>): Promise<T>;
312
+ cleanupOperation<T, TId extends OperationId>(operation: OperationContract<T, TId>, options: HttpOperationOptions): Promise<T>;
313
+ }
314
+ //#endregion
315
+ //#region src/core/attachments/resolver.d.ts
316
+ /** Дополнительные требования потребителя к подготовленному источнику. */
317
+ interface ResolveFileOptions {
318
+ /** Имя, которое имеет приоритет над именем источника. */
319
+ readonly filename?: string | undefined;
320
+ /** MIME-тип, который имеет приоритет над типом источника. */
321
+ readonly contentType?: string | undefined;
322
+ /** Дополнительный предел размера для любого вида источника. */
323
+ readonly maxBytes?: number | undefined;
324
+ /** Размер очереди библиотеки при потоковом чтении. */
325
+ readonly streamBufferBytes?: number | undefined;
326
+ /** Отклонить поток, размер которого нельзя узнать до чтения. */
327
+ readonly requireKnownSize?: boolean | undefined;
328
+ }
329
+ /** Буфер, полностью принадлежащий вызывающему коду. */
330
+ interface PreparedBufferSource {
331
+ readonly mode: typeof FileTransferMode.Buffer;
332
+ readonly blob: Blob;
333
+ readonly size: number;
334
+ readonly filename?: string | undefined;
335
+ readonly contentType: string | undefined;
336
+ }
337
+ /**
338
+ * Одна открытая сессия чтения потокового источника.
339
+ *
340
+ * Потребитель обязан вызвать {@link close} в `finally`. Повторный вызов безопасен и ждёт
341
+ * тот же результат освобождения ресурсов.
342
+ */
343
+ interface PreparedStreamSource {
344
+ readonly mode: typeof FileTransferMode.Stream;
345
+ readonly stream: ReadableStream<Uint8Array>;
346
+ readonly size: number | undefined;
347
+ readonly filename?: string | undefined;
348
+ readonly contentType: string | undefined;
349
+ close(): Promise<void>;
350
+ }
351
+ /** Подготовленный файловый источник без правил конкретного протокола загрузки. */
352
+ type PreparedFileSource = PreparedBufferSource | PreparedStreamSource;
353
+ /** Контекст одной попытки открытия файлового источника. */
354
+ interface ResolveFileContext {
355
+ readonly signal?: AbortSignal | undefined;
356
+ /** Номер попытки потребителя, начиная с 1. */
357
+ readonly attempt?: number | undefined;
358
+ }
359
+ /** Узкий файловый порт, доступный подключаемым предметным модулям. */
360
+ interface FileResolver {
361
+ resolve(input: FileInput, options?: ResolveFileOptions, context?: ResolveFileContext): Promise<PreparedFileSource>;
362
+ }
363
+ /** Внутренний контракт нужен `FilesResource` для сохранения семантики повторных попыток. */
364
+ interface InternalFileResolver extends FileResolver {
365
+ mode(input: FileInput): FileTransferMode;
366
+ }
367
+ //#endregion
368
+ //#region src/core/managed-resources.d.ts
369
+ /** Долгоживущий ресурс клиента. */
370
+ interface ManagedClientResource {
371
+ /** Короткое имя для диагностики зависшей остановки. */
372
+ readonly kind: string;
373
+ /** Синхронно прекращает принимать новую работу и запускает отмену. */
374
+ stop(): void;
375
+ /** Завершается после остановки обработчиков и освобождения внешних ресурсов. */
376
+ drain(): Promise<void>;
115
377
  }
116
378
  //#endregion
117
379
  //#region src/core/features.d.ts
118
380
  /** Параметры запроса feature: маршрут задаёт ресурс, transport metadata — manifest. */
119
381
  type FeatureRequestOptions = Omit<RawRequestOptions, 'operationId' | 'method' | 'service' | 'baseUrl' | 'retrySafety' | 'rateLimitBucket'>;
120
382
  /** Операция одного feature. Локальный ключ используется в {@link FeatureContext.request}. */
121
- interface FeatureOperationDefinition {
383
+ interface FeatureOperationDefinition<T = unknown> {
122
384
  readonly method: OperationMethod;
123
385
  readonly retrySafety: RetrySafety;
124
386
  /** Имя сервиса из {@link ClientFeature.services}; без него используется основной API. */
125
387
  readonly service?: string | undefined;
126
388
  /** Локальное имя бакета из {@link ClientFeature.buckets}. */
127
389
  readonly bucket?: string | undefined;
390
+ /** Преобразует тело ответа в публичный результат операции. По умолчанию возвращает тело без изменений. */
391
+ readonly read?: OperationContract<T>['read'] | undefined;
392
+ /** Необязательные метаданные, интерпретируемые подключёнными плагинами. */
393
+ readonly annotations?: OperationAnnotations | undefined;
128
394
  }
129
395
  /** Начальные ограничения нового серверного счётчика feature. */
130
396
  interface FeatureBucketDefinition extends RateLimitBucketOverride {}
@@ -151,178 +417,30 @@ interface ClientFeature<TApi> {
151
417
  readonly buckets?: Readonly<Record<string, FeatureBucketDefinition>> | undefined;
152
418
  setup(context: FeatureContext): FeatureInstallation<TApi>;
153
419
  }
154
- /** Ограниченный доступ feature к общему runtime клиента. */
420
+ /** Доступ подключаемого модуля к клиенту. */
155
421
  interface FeatureContext {
156
422
  readonly featureName: string;
157
423
  readonly baseUrl: string;
158
424
  readonly signal: AbortSignal;
159
425
  readonly clock: ItdClock;
160
426
  readonly logger: Logger | undefined;
161
- /** Выполняет объявленную операцию через общие auth, plugins, retry и очереди клиента. */
162
- request<T = unknown>(operation: string, options: FeatureRequestOptions): Promise<T>;
163
- /** Возвращает фактический URL объявленного сервиса с учётом настроек клиента. */
164
- serviceBaseUrl(name: string): string;
165
- }
166
- //#endregion
167
- //#region src/core/plugins/contracts.d.ts
168
- /**
169
- * Обёртка одной логической операции.
170
- *
171
- * Вызывается ровно один раз независимо от retry и auth recovery. Может изменить
172
- * семантический запрос, обработать разобранный результат или завершить операцию локально.
173
- *
174
- * @param request описание логической операции; не изменяйте сам объект — передайте копию в `next`
175
- * @param next следующая обёртка либо выполнение операции
176
- * @returns разобранный результат в том виде, в котором его получит вызывающий код
177
- *
178
- * @example Дописать заголовок ко всем операциям
179
- * ```ts
180
- * const transformer: OperationTransformer = (request, next) =>
181
- * next({ ...request, headers: { ...request.headers, 'X-Trace': trace() } });
182
- * ```
183
- */
184
- type OperationTransformer = (request: OperationRequestOptions, next: (request: OperationRequestOptions) => Promise<unknown>) => Promise<unknown>;
185
- /** Финальные данные одной транспортной попытки. */
186
- interface AttemptContext {
187
- /** Стабильная семантическая операция. */
188
- readonly operationId: OperationId;
189
- /** Нормализованный HTTP-метод. */
190
- readonly method: string;
191
- /** Исходный путь операции до разрешения service/base URL. */
192
- readonly path: string;
193
- /** Полностью разрешённый URL со строкой query. */
194
- readonly url: string;
195
- /** Итоговые заголовки. Сам объект mutable для подписи и diagnostic headers. */
196
- readonly headers: Headers;
197
- /** Номер transport attempt, начиная с 1. */
198
- readonly attempt: number;
199
- /** Тело после сериализации либо подготовки body factory. Поток нельзя читать заранее. */
200
- readonly body: BodyInit | undefined;
201
- /** Общий сигнал отмены и таймаута этой попытки. */
202
- readonly signal: AbortSignal;
203
- }
204
- /**
205
- * Продолжение attempt chain.
206
- *
207
- * В рамках одного interceptor его можно вызвать только один раз. Возвращает сырой ответ:
208
- * transport ещё не проверял status и не читал body.
209
- */
210
- type AttemptNext = () => Promise<Response>;
211
- /**
212
- * Обёртка одной транспортной попытки.
213
- *
214
- * Получает уже разрешённый URL, итоговые заголовки, подготовленное тело и номер попытки.
215
- * Может дописать заголовки, измерить wire latency, обработать сырой `Response` или вернуть
216
- * синтетический `Response`. Семантический input здесь намеренно недоступен для изменения.
217
- *
218
- * Вызывается заново для каждого retry и auth recovery. `next()` разрешено вызвать один раз.
219
- * Если interceptor читает тело ответа, читать нужно `response.clone()`: исходный body после
220
- * цепочки разбирает transport. Исключение interceptor остаётся пользовательской ошибкой и не
221
- * классифицируется как сетевой сбой для автоматического retry.
222
- *
223
- * @param context окончательные данные текущей транспортной попытки
224
- * @param next следующий interceptor либо вызов `fetch`
225
- * @returns исходный или синтетический сырой `Response`
226
- */
227
- type AttemptInterceptor = (context: AttemptContext, next: AttemptNext) => Promise<Response>;
228
- /** Регистрация расширений логической операции. */
229
- interface OperationExtensions {
230
- /**
231
- * Подключает transformer.
232
- *
233
- * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
234
- * идемпотентна и снимает только эту регистрацию.
235
- */
236
- use(transformer: OperationTransformer): Unsubscribe;
237
- }
238
- /** Регистрация расширений транспортной попытки. */
239
- interface AttemptExtensions {
240
- /**
241
- * Подключает interceptor.
242
- *
243
- * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
244
- * идемпотентна и снимает только эту регистрацию.
245
- */
246
- use(interceptor: AttemptInterceptor): Unsubscribe;
247
- }
248
- /**
249
- * Освобождение ресурсов, заведённых плагином при установке.
250
- *
251
- * Вызывается после завершения логических операций, уже вошедших в расширения плагина,
252
- * поэтому может безопасно закрывать используемые ими соединения и хранилища.
253
- */
254
- type PluginTeardown = () => void | Promise<void>;
255
- /** API, доступный плагину при подключении. */
256
- interface PluginApi {
257
- /** Базовый URL клиента — например чтобы разобрать абсолютные ссылки из ответа. */
258
- baseUrl: string;
259
- /** Отладочный вывод клиента, если он включён. */
260
- logger: Logger | undefined;
261
- /** Расширения логической операции: выполняются один раз и могут short-circuit сеть. */
262
- operations: OperationExtensions;
263
- /** Расширения wire attempt: выполняются заново после каждого retry/auth recovery. */
264
- attempts: AttemptExtensions;
265
- /**
266
- * Непрозрачная fallback-область текущей авторизации.
267
- *
268
- * Нужна плагинам, которые обязаны безопасно изолировать непрозрачный токен. Для объединения
269
- * состояния копий одного аккаунта используйте {@link getAuthIdentity}.
270
- */
271
- getAuthScope?: (() => string) | undefined;
272
- /**
273
- * Загружает сессию и возвращает идентификаторы аккаунта и конкретной сессии из JWT.
274
- *
275
- * Предпочтительнее {@link getAuthScope} для состояния, которое должно объединяться между
276
- * несколькими экземплярами клиента одного аккаунта.
277
- */
278
- getAuthIdentity?: (() => Promise<AuthIdentity>) | undefined;
279
- }
280
- /**
281
- * Плагин клиента.
282
- *
283
- * Подключается через `itd.use(plugin)` и регистрирует расширения одного или обоих уровней:
284
- * {@link OperationTransformer} для логической операции и {@link AttemptInterceptor} для
285
- * отдельной транспортной попытки. Core взаимодействует с плагином только через эти контракты
286
- * и его lifecycle, не зная деталей реализации.
287
- *
288
- * Настройки отдельного вызова плагин объявляет своим полем в `RequestExtensions` через
289
- * declaration merging. Пользователь передаёт их в `RequestOptions.extensions`, а operation
290
- * transformer читает только принадлежащий плагину namespace.
291
- *
292
- * @example Логирование логических операций
293
- * ```ts
294
- * const logging: ClientPlugin = {
295
- * name: 'logging',
296
- * install({ operations, logger }) {
297
- * operations.use(async (request, next) => {
298
- * logger?.info(`${request.method} ${request.path}`);
299
- * return next(request);
300
- * });
301
- * },
302
- * };
303
- *
304
- * itd.use(logging);
305
- * ```
306
- */
307
- interface ClientPlugin {
308
- /** Имя плагина. Должно быть уникальным: повторное подключение — ошибка. */
309
- name: string;
310
- /** Плагины, которые обязаны быть подключены раньше этого. */
311
- requires?: readonly string[];
312
- /** Несовместимые плагины. Достаточно объявить конфликт с одной стороны. */
313
- conflicts?: readonly string[];
314
- /** Имена плагинов, снаружи которых должны стоять оба вида расширений этого плагина. */
315
- before?: readonly string[];
316
- /** Имена плагинов, внутри которых должны стоять оба вида расширений этого плагина. */
317
- after?: readonly string[];
427
+ /** Открывает файловый источник без правил конкретного протокола загрузки. */
428
+ readonly files: FileResolver;
318
429
  /**
319
- * Устанавливает плагин.
430
+ * Выполняет объявленную операцию через авторизацию, плагины, повторы и очередь клиента.
320
431
  *
321
- * Может вернуть функцию освобождения ресурсов. Она вызывается при `unuse()` или
322
- * окончательном `dispose()` клиента и может быть асинхронной. Сам `install()` синхронный:
323
- * регистрация расширений завершается до того, как `use()` вернёт управление.
432
+ * Форма результата задаётся один раз полем `read` в описании операции. Плагины получают
433
+ * готовый результат и не видят функцию преобразования.
324
434
  */
325
- install(api: PluginApi): void | PluginTeardown;
435
+ request<T = unknown>(operation: string, options: FeatureRequestOptions): Promise<T>;
436
+ /** Возвращает фактический URL объявленного сервиса с учётом настроек клиента. */
437
+ serviceBaseUrl(name: string): string;
438
+ /** Окружение долговременного соединения объявленного сервиса. */
439
+ connection(name: string): ClientConnection;
440
+ /** Регистрирует активный долгоживущий ресурс до его остановки. */
441
+ manage(resource: ManagedClientResource): () => void;
442
+ /** Проверяет, что создавший модуль клиент ещё работает. */
443
+ assertActive(action: string): void;
326
444
  }
327
445
  //#endregion
328
446
  //#region src/core/scheduling/rate-limit.d.ts
@@ -341,48 +459,6 @@ interface RateLimitBucketState {
341
459
  pending: number;
342
460
  }
343
461
  //#endregion
344
- //#region src/models/account.d.ts
345
- /** Активная сессия входа. */
346
- interface Session {
347
- id: string;
348
- /** Та ли это сессия, из которой выполнен запрос. */
349
- isCurrent: boolean;
350
- createdAt: IsoDate;
351
- lastUsedAt: IsoDate;
352
- expiresAt: IsoDate;
353
- ipAddress: string;
354
- /** Код страны по IP, например `RU`. */
355
- ipCountry: string | null;
356
- ipCity: string | null;
357
- deviceType: Loose<'desktop' | 'mobile'>;
358
- osName: string | null;
359
- osVersion: string | null;
360
- /** Название браузера или приложения. */
361
- clientName: string | null;
362
- clientVersion: string | null;
363
- deviceModel: string | null;
364
- }
365
- /** Состояние платной подписки и её цена. */
366
- interface Subscription {
367
- /** Активна ли подписка сейчас. */
368
- active: boolean;
369
- /** Включено ли автопродление. */
370
- recurringEnabled: boolean;
371
- /** Цена в рублях. */
372
- price: number;
373
- }
374
- /** Сохранённый способ оплаты. */
375
- interface PaymentMethod {
376
- id: string;
377
- /** Последние четыре цифры карты. */
378
- last4?: string;
379
- /** Платёжная система: `visa`, `mastercard`, `mir`. */
380
- brand?: string;
381
- /** Основной ли это способ оплаты. */
382
- isDefault?: boolean;
383
- expiresAt?: IsoDate | null;
384
- }
385
- //#endregion
386
462
  //#region src/resources/pagination.d.ts
387
463
  /**
388
464
  * Страница списка — единая форма для всех трёх схем пагинации API.
@@ -520,13 +596,11 @@ declare class Paginator<T> implements AsyncIterable<T> {
520
596
  */
521
597
  interface ListingSpec<T, P extends object> {
522
598
  /** Стабильная семантическая операция списка. */
523
- operationId: BuiltInOperationId | ((params: P) => BuiltInOperationId);
599
+ operation: OperationContract<Page<T>, BuiltInOperationId> | ((params: P) => OperationContract<Page<T>, BuiltInOperationId>);
524
600
  /** Путь эндпоинта. */
525
601
  path: (params: P) => string;
526
602
  /** Параметры запроса без полей пагинации — их добавит перебор. */
527
603
  query: (params: P) => QueryParams;
528
- /** Читает страницу из ответа. Получает позицию — она нужна схеме со смещением. */
529
- read: (body: unknown, state: PageState) => Page<T>;
530
604
  /** Схема пагинации эндпоинта. */
531
605
  mode: PaginationMode;
532
606
  /** Начальная позиция, вычисленная из параметров (курсор, номер или смещение). */
@@ -544,6 +618,8 @@ declare class BaseResource {
544
618
  /** @internal */
545
619
  protected readonly http: HttpClient;
546
620
  constructor(http: HttpClient);
621
+ /** Выполняет операцию без возвращаемого значения и отбрасывает служебное тело ответа. */
622
+ protected voidOperation(operation: OperationContract<void, BuiltInOperationId>, options: HttpOperationOptions): Promise<void>;
547
623
  /**
548
624
  * Собирает перебор страниц.
549
625
  *
@@ -563,11 +639,10 @@ declare class BaseResource {
563
639
  * @example
564
640
  * ```ts
565
641
  * #feed = this.paginated<Post, FeedParams>({
566
- * operationId: 'posts.list',
642
+ * operation: POSTS_LIST,
567
643
  * path: () => '/api/posts',
568
644
  * query: (p) => ({ tab: p.tab, limit: p.limit }),
569
645
  * start: (p) => (p.cursor ? { cursor: p.cursor } : {}),
570
- * read: (body) => readCursorPage<Post>(body, 'posts'),
571
646
  * mode: PaginationMode.Cursor,
572
647
  * });
573
648
  * ```
@@ -575,6 +650,118 @@ declare class BaseResource {
575
650
  protected paginated<T, P extends object>(spec: ListingSpec<T, P>): Listing<T, P>;
576
651
  }
577
652
  //#endregion
653
+ //#region src/resources/notifications.d.ts
654
+ /** Параметры запроса списка уведомлений. */
655
+ interface NotificationListParams {
656
+ limit?: number;
657
+ /** Смещение от начала списка. */
658
+ offset?: number;
659
+ }
660
+ /** Изменяемые настройки уведомлений. */
661
+ type UpdateNotificationSettingsInput = Partial<NotificationSettings>;
662
+ /**
663
+ * Уведомления: список, счётчик, отметки о прочтении, настройки.
664
+ *
665
+ * Доступна как `itd.notifications`. Все уведомления приведены к единой форме, поэтому
666
+ * объекты отсюда и из потока событий можно складывать в один список.
667
+ */
668
+ declare class NotificationsResource extends BaseResource {
669
+ #private;
670
+ /**
671
+ * Загружает страницу уведомлений.
672
+ *
673
+ * Пагинация здесь основана на смещении.
674
+ *
675
+ * @example
676
+ * ```ts
677
+ * const page = await itd.notifications.list({ limit: 20 });
678
+ * const next = await itd.notifications.list({ limit: 20, offset: page.nextOffset });
679
+ * ```
680
+ */
681
+ list(params?: NotificationListParams, options?: RequestOptions): Promise<Page<Notification>>;
682
+ /**
683
+ * Перебирает уведомления.
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * for await (const notification of itd.notifications.iterate()) {
688
+ * console.log(formatNotificationText(notification));
689
+ * }
690
+ * ```
691
+ */
692
+ iterate(params?: NotificationListParams, options?: PaginationOptions): Paginator<Notification>;
693
+ /** Загружает число непрочитанных уведомлений. */
694
+ count(options?: RequestOptions): Promise<number>;
695
+ /**
696
+ * Отмечает уведомление прочитанным.
697
+ *
698
+ * @returns сколько записей отметил сервер
699
+ */
700
+ markRead(notificationId: string, options?: RequestOptions): Promise<number>;
701
+ /**
702
+ * Отмечает прочитанными сразу несколько уведомлений.
703
+ *
704
+ * Список автоматически режется на части по 20 идентификаторов — столько же отправляет
705
+ * сайт итд.com, поэтому на сервере вероятен предел. Части уходят последовательно,
706
+ * результат суммируется.
707
+ *
708
+ * @returns сколько записей отметил сервер суммарно
709
+ */
710
+ markReadBatch(ids: string[], options?: RequestOptions): Promise<number>;
711
+ /** Отмечает прочитанными все уведомления. */
712
+ markAllRead(options?: RequestOptions): Promise<number>;
713
+ /** Загружает настройки уведомлений. */
714
+ getSettings(options?: RequestOptions): Promise<NotificationSettings>;
715
+ /**
716
+ * Обновляет настройки уведомлений.
717
+ *
718
+ * Отправляются только изменяемые поля, в том же виде, в каком сервер их возвращает.
719
+ */
720
+ updateSettings(input: UpdateNotificationSettingsInput, options?: RequestOptions): Promise<NotificationSettings>;
721
+ }
722
+ //#endregion
723
+ //#region src/models/account.d.ts
724
+ /** Активная сессия входа. */
725
+ interface Session {
726
+ id: string;
727
+ /** Та ли это сессия, из которой выполнен запрос. */
728
+ isCurrent: boolean;
729
+ createdAt: IsoDate;
730
+ lastUsedAt: IsoDate;
731
+ expiresAt: IsoDate;
732
+ ipAddress: string;
733
+ /** Код страны по IP, например `RU`. */
734
+ ipCountry: string | null;
735
+ ipCity: string | null;
736
+ deviceType: Loose<'desktop' | 'mobile'>;
737
+ osName: string | null;
738
+ osVersion: string | null;
739
+ /** Название браузера или приложения. */
740
+ clientName: string | null;
741
+ clientVersion: string | null;
742
+ deviceModel: string | null;
743
+ }
744
+ /** Состояние платной подписки и её цена. */
745
+ interface Subscription {
746
+ /** Активна ли подписка сейчас. */
747
+ active: boolean;
748
+ /** Включено ли автопродление. */
749
+ recurringEnabled: boolean;
750
+ /** Цена в рублях. */
751
+ price: number;
752
+ }
753
+ /** Сохранённый способ оплаты. */
754
+ interface PaymentMethod {
755
+ id: string;
756
+ /** Последние четыре цифры карты. */
757
+ last4?: string;
758
+ /** Платёжная система: `visa`, `mastercard`, `mir`. */
759
+ brand?: string;
760
+ /** Основной ли это способ оплаты. */
761
+ isDefault?: boolean;
762
+ expiresAt?: IsoDate | null;
763
+ }
764
+ //#endregion
578
765
  //#region src/domain/params.d.ts
579
766
  /** Данные для создания опроса. */
580
767
  interface CreatePollInput {
@@ -973,7 +1160,7 @@ interface UploadOptions {
973
1160
  declare class FilesResource extends BaseResource {
974
1161
  #private;
975
1162
  constructor(http: HttpClient, deps: {
976
- fetch: typeof fetch;
1163
+ files: InternalFileResolver;
977
1164
  });
978
1165
  /**
979
1166
  * Загружает файл и возвращает его идентификатор.
@@ -1030,76 +1217,6 @@ declare class HashtagsResource extends BaseResource {
1030
1217
  iteratePosts(tag: string, params?: HashtagPostsParams, options?: PaginationOptions): Paginator<Post>;
1031
1218
  }
1032
1219
  //#endregion
1033
- //#region src/resources/notifications.d.ts
1034
- /** Параметры запроса списка уведомлений. */
1035
- interface NotificationListParams {
1036
- limit?: number;
1037
- /** Смещение от начала списка. */
1038
- offset?: number;
1039
- }
1040
- /** Изменяемые настройки уведомлений. */
1041
- type UpdateNotificationSettingsInput = Partial<NotificationSettings>;
1042
- /**
1043
- * Уведомления: список, счётчик, отметки о прочтении, настройки.
1044
- *
1045
- * Доступна как `itd.notifications`. Все уведомления приведены к единой форме, поэтому
1046
- * объекты отсюда и из потока событий можно складывать в один список.
1047
- */
1048
- declare class NotificationsResource extends BaseResource {
1049
- #private;
1050
- /**
1051
- * Загружает страницу уведомлений.
1052
- *
1053
- * Пагинация здесь основана на смещении.
1054
- *
1055
- * @example
1056
- * ```ts
1057
- * const page = await itd.notifications.list({ limit: 20 });
1058
- * const next = await itd.notifications.list({ limit: 20, offset: page.nextOffset });
1059
- * ```
1060
- */
1061
- list(params?: NotificationListParams, options?: RequestOptions): Promise<Page<Notification>>;
1062
- /**
1063
- * Перебирает уведомления.
1064
- *
1065
- * @example
1066
- * ```ts
1067
- * for await (const notification of itd.notifications.iterate()) {
1068
- * console.log(formatNotificationText(notification));
1069
- * }
1070
- * ```
1071
- */
1072
- iterate(params?: NotificationListParams, options?: PaginationOptions): Paginator<Notification>;
1073
- /** Загружает число непрочитанных уведомлений. */
1074
- count(options?: RequestOptions): Promise<number>;
1075
- /**
1076
- * Отмечает уведомление прочитанным.
1077
- *
1078
- * @returns сколько записей отметил сервер
1079
- */
1080
- markRead(notificationId: string, options?: RequestOptions): Promise<number>;
1081
- /**
1082
- * Отмечает прочитанными сразу несколько уведомлений.
1083
- *
1084
- * Список автоматически режется на части по 20 идентификаторов — столько же отправляет
1085
- * сайт итд.com, поэтому на сервере вероятен предел. Части уходят последовательно,
1086
- * результат суммируется.
1087
- *
1088
- * @returns сколько записей отметил сервер суммарно
1089
- */
1090
- markReadBatch(ids: string[], options?: RequestOptions): Promise<number>;
1091
- /** Отмечает прочитанными все уведомления. */
1092
- markAllRead(options?: RequestOptions): Promise<number>;
1093
- /** Загружает настройки уведомлений. */
1094
- getSettings(options?: RequestOptions): Promise<NotificationSettings>;
1095
- /**
1096
- * Обновляет настройки уведомлений.
1097
- *
1098
- * Отправляются только изменяемые поля, в том же виде, в каком сервер их возвращает.
1099
- */
1100
- updateSettings(input: UpdateNotificationSettingsInput, options?: RequestOptions): Promise<NotificationSettings>;
1101
- }
1102
- //#endregion
1103
1220
  //#region src/models/platform.d.ts
1104
1221
  /** Клан в рейтинге. */
1105
1222
  interface Clan {
@@ -2307,5 +2424,5 @@ interface RenderSpansOptions {
2307
2424
  */
2308
2425
  declare function renderSpans(content: string, spans?: readonly Span[] | null | undefined, options?: RenderSpansOptions): string;
2309
2426
  //#endregion
2310
- export { poll as $, CreatePostData as $t, TelemetryResource as A, FilesResource as At, ReportInput as B, PinPostResult as Bt, DwellEntry as C, FeatureBucketDefinition as Cn, Report as Ct, TelemetryBatchOptions as D, FeatureRequestOptions as Dn, UpdateNotificationSettingsInput as Dt, TelemetryBatch as E, FeatureOperationDefinition as En, NotificationsResource as Et, SubscriptionResource as F, Attachment as Ft, UserPostsParams as G, CommentBuilder as Gt, CommentsParams as H, PollOption as Ht, SearchResource as I, Comment as It, PostInput as J, BuilderInput as Jt, CreatePostInput as K, CommentInput as Kt, SearchResult as L, CommentReplyTo as Lt, ViewTracker as M, UploadedFile as Mt, ViewTrackerInput as N, CommentsResource as Nt, TelemetryClock as O, HttpClient as On, HashtagPostsParams as Ot, ViewTrackerOptions as P, RepliesParams as Pt, PollInput as Q, CreatePollInput as Qt, ReportsResource as R, Hashtag as Rt, UsersResource as S, ClientFeature as Sn, Portal as St, PhotoOpenInput as T, FeatureInstallation as Tn, NotificationListParams as Tt, FeedParams as U, Post as Ut, report as V, Poll as Vt, PostsResource as W, PostStats as Wt, post as X, isBuilder as Xt, PostUpdateInput as Y, ItdBuilder as Yt, PollBuilder as Z, CreateCommentInput as Zt, fromUrl as _, ClientPlugin as _n, StatusIncidentLine as _t, isMyProfile as a, PaginationMode as an, MarkupContent as at, UpdateProfileInput as b, PluginApi as bn, ChangelogEntry as bt, ALLOWED_MIME_TYPES as c, mapPage as cn, TextMarkup as ct, AudioMimeType as d, Subscription as dn, PlatformClientVersion as dt, CreateReportInput as en, ParseMarkupOptions as et, IMAGE_MIME_TYPES as f, RateLimitBucketState as fn, PlatformResource as ft, fromStream as g, AttemptNext as gn, StatusDay as gt, VideoMimeType as h, AttemptInterceptor as hn, ServiceStatus as ht, statusDays as i, PageState as in, MarkupBuilder as it, VideoProgressInput as j, UploadOptions as jt, TelemetryOptions as k, RequestHandler as kn, HashtagsResource as kt, AUDIO_MIME_TYPES as l, PaymentMethod as ln, autoSpans as lt, VIDEO_MIME_TYPES as m, AttemptExtensions as mn, PlatformStatus as mt, SpanRenderFormat as n, BaseResource as nn, parseMarkdown as nt, toDate as o, Paginator as on, MarkupInput as ot, ImageMimeType as p, AttemptContext as pn, PlatformVersions as pt, PostBuilder as q, comment as qt, renderSpans as r, Page as rn, AutoSpansOptions as rt, utcStampToIso as s, PaginatorOptions as sn, MarkupSpan as st, RenderSpansOptions as t, UpdatePostInput as tn, parseHtml as tt, AllowedMimeType as u, Session as un, markup as ut, VerificationResource as v, OperationExtensions as vn, Announcement as vt, InteractionEntry as w, FeatureContext as wn, VerificationStatus as wt, UserListParams as x, PluginTeardown as xn, Clan as xt, UpdatePrivacyInput as y, OperationTransformer as yn, AnnouncementButton as yt, ReportBuilder as z, LikeResult as zt };
2311
- //# sourceMappingURL=render-CgwKdOzu.d.ts.map
2427
+ export { poll as $, PaymentMethod as $t, TelemetryResource as A, AttemptNext as An, CommentsResource as At, ReportInput as B, Post as Bt, DwellEntry as C, PreparedStreamSource as Cn, Report as Ct, TelemetryBatchOptions as D, AttemptContext as Dn, FilesResource as Dt, TelemetryBatch as E, HttpClient as En, HashtagsResource as Et, SubscriptionResource as F, PluginTeardown as Fn, Hashtag as Ft, UserPostsParams as G, BuilderInput as Gt, CommentsParams as H, CommentBuilder as Ht, SearchResource as I, LikeResult as It, PostInput as J, CreateCommentInput as Jt, CreatePostInput as K, ItdBuilder as Kt, SearchResult as L, PinPostResult as Lt, ViewTracker as M, OperationExtensions as Mn, Attachment as Mt, ViewTrackerInput as N, OperationTransformer as Nn, Comment as Nt, TelemetryClock as O, AttemptExtensions as On, UploadOptions as Ot, ViewTrackerOptions as P, PluginApi as Pn, CommentReplyTo as Pt, PollInput as Q, UpdatePostInput as Qt, ReportsResource as R, Poll as Rt, UsersResource as S, PreparedFileSource as Sn, Portal as St, PhotoOpenInput as T, ResolveFileOptions as Tn, HashtagPostsParams as Tt, FeedParams as U, CommentInput as Ut, report as V, PostStats as Vt, PostsResource as W, comment as Wt, post as X, CreatePostData as Xt, PostUpdateInput as Y, CreatePollInput as Yt, PollBuilder as Z, CreateReportInput as Zt, fromUrl as _, FeatureOperationDefinition as _n, StatusIncidentLine as _t, isMyProfile as a, BaseResource as an, MarkupContent as at, UpdateProfileInput as b, FileResolver as bn, ChangelogEntry as bt, ALLOWED_MIME_TYPES as c, PaginationMode as cn, TextMarkup as ct, AudioMimeType as d, mapPage as dn, PlatformClientVersion as dt, Session as en, ParseMarkupOptions as et, IMAGE_MIME_TYPES as f, RateLimitBucketState as fn, PlatformResource as ft, fromStream as g, FeatureInstallation as gn, StatusDay as gt, VideoMimeType as h, FeatureContext as hn, ServiceStatus as ht, statusDays as i, UpdateNotificationSettingsInput as in, MarkupBuilder as it, VideoProgressInput as j, ClientPlugin as jn, RepliesParams as jt, TelemetryOptions as k, AttemptInterceptor as kn, UploadedFile as kt, AUDIO_MIME_TYPES as l, Paginator as ln, autoSpans as lt, VIDEO_MIME_TYPES as m, FeatureBucketDefinition as mn, PlatformStatus as mt, SpanRenderFormat as n, NotificationListParams as nn, parseMarkdown as nt, toDate as o, Page as on, MarkupInput as ot, ImageMimeType as p, ClientFeature as pn, PlatformVersions as pt, PostBuilder as q, isBuilder as qt, renderSpans as r, NotificationsResource as rn, AutoSpansOptions as rt, utcStampToIso as s, PageState as sn, MarkupSpan as st, RenderSpansOptions as t, Subscription as tn, parseHtml as tt, AllowedMimeType as u, PaginatorOptions as un, markup as ut, VerificationResource as v, FeatureRequestOptions as vn, Announcement as vt, InteractionEntry as w, ResolveFileContext as wn, VerificationStatus as wt, UserListParams as x, PreparedBufferSource as xn, Clan as xt, UpdatePrivacyInput as y, ManagedClientResource as yn, AnnouncementButton as yt, ReportBuilder as z, PollOption as zt };
2428
+ //# sourceMappingURL=render-DVB7T8pm.d.ts.map