itd-api 0.10.4 → 0.11.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 (79) hide show
  1. package/README.md +2 -1
  2. package/dist/events/index.cjs +27 -25
  3. package/dist/events/index.d.cts +3 -3
  4. package/dist/events/index.d.ts +3 -3
  5. package/dist/events/index.js +5 -5
  6. package/dist/index.cjs +136 -116
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +18 -7
  9. package/dist/index.d.ts +18 -7
  10. package/dist/index.js +46 -30
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +13 -13
  13. package/dist/node/index.cjs.map +1 -1
  14. package/dist/node/index.js +5 -5
  15. package/dist/rest/index.cjs +43 -40
  16. package/dist/rest/index.cjs.map +1 -1
  17. package/dist/rest/index.d.cts +3 -3
  18. package/dist/rest/index.d.ts +3 -3
  19. package/dist/rest/index.js +6 -6
  20. package/dist/shared/{events-B8cjz_Ed.cjs → events-C6tmj8aW.cjs} +63 -59
  21. package/dist/shared/events-C6tmj8aW.cjs.map +1 -0
  22. package/dist/shared/{events-DGdU8q1X.d.ts → events-CAb9G7Sf.d.ts} +2 -2
  23. package/dist/shared/{events-D2n7Yu1P.js → events-MWNcnfrq.js} +19 -15
  24. package/dist/shared/events-MWNcnfrq.js.map +1 -0
  25. package/dist/shared/{events-CK3zHntT.d.cts → events-Sc75x6rT.d.cts} +2 -2
  26. package/dist/shared/{key-value-store-B5GYVEYZ.cjs → key-value-store-DYSPsqwq.cjs} +11 -14
  27. package/dist/shared/key-value-store-DYSPsqwq.cjs.map +1 -0
  28. package/dist/shared/{key-value-store-Bt2PSMxY.js → key-value-store-w1Dn5Pjb.js} +5 -8
  29. package/dist/shared/key-value-store-w1Dn5Pjb.js.map +1 -0
  30. package/dist/shared/{multi-storage-C3Ngtop1.js → multi-storage-BLBrGN9Q.js} +6 -6
  31. package/dist/shared/multi-storage-BLBrGN9Q.js.map +1 -0
  32. package/dist/shared/{multi-storage-s-fPtjoy.cjs → multi-storage-C7-Gz6Z7.cjs} +8 -8
  33. package/dist/shared/multi-storage-C7-Gz6Z7.cjs.map +1 -0
  34. package/dist/shared/{options-DjEtbVaf.cjs → options-5tywTYId.cjs} +13 -13
  35. package/dist/shared/{options-DjEtbVaf.cjs.map → options-5tywTYId.cjs.map} +1 -1
  36. package/dist/shared/{options-i4LrKfqx.js → options-BerKicCs.js} +3 -3
  37. package/dist/shared/{options-i4LrKfqx.js.map → options-BerKicCs.js.map} +1 -1
  38. package/dist/shared/{redact-DJV0XM3n.js → redact-C5oxIvcc.js} +79 -18
  39. package/dist/shared/redact-C5oxIvcc.js.map +1 -0
  40. package/dist/shared/{redact-lAmck1Z6.cjs → redact-DoC7lSsp.cjs} +109 -24
  41. package/dist/shared/redact-DoC7lSsp.cjs.map +1 -0
  42. package/dist/shared/{render-UsOGMRzS.d.ts → render-CBroJPcV.d.ts} +178 -252
  43. package/dist/shared/{render-9F_kR6sq.d.cts → render-DM7AhTZW.d.cts} +178 -252
  44. package/dist/shared/{render-C6CJ343E.js → render-DRh5_aRe.js} +128 -135
  45. package/dist/shared/render-DRh5_aRe.js.map +1 -0
  46. package/dist/shared/{render-BrrZOSV5.cjs → render-Dnc84B4M.cjs} +234 -241
  47. package/dist/shared/render-Dnc84B4M.cjs.map +1 -0
  48. package/dist/shared/{storage-DiDe0PZM.js → storage-86wiHeXD.js} +3 -3
  49. package/dist/shared/{storage-DiDe0PZM.js.map → storage-86wiHeXD.js.map} +1 -1
  50. package/dist/shared/{storage-CZJZoaz9.cjs → storage-CIjejZDt.cjs} +4 -4
  51. package/dist/shared/{storage-CZJZoaz9.cjs.map → storage-CIjejZDt.cjs.map} +1 -1
  52. package/dist/shared/{url-yB6T_H_-.d.ts → url-BOi-_mJT.d.cts} +143 -79
  53. package/dist/shared/{url-yB6T_H_-.d.cts → url-BOi-_mJT.d.ts} +143 -79
  54. package/dist/shared/{url-Dc7wLikf.js → url-Bg61sk_Y.js} +723 -590
  55. package/dist/shared/url-Bg61sk_Y.js.map +1 -0
  56. package/dist/shared/{url-BNTKqBMB.cjs → url-DTgkCWv5.cjs} +830 -709
  57. package/dist/shared/url-DTgkCWv5.cjs.map +1 -0
  58. package/dist/shared/{errors-BmP3TKoW.cjs → validate-CFx2dISs.cjs} +84 -5
  59. package/dist/shared/validate-CFx2dISs.cjs.map +1 -0
  60. package/dist/shared/{errors-GI10kZxk.js → validate-D7_kq3g5.js} +55 -6
  61. package/dist/shared/validate-D7_kq3g5.js.map +1 -0
  62. package/dist/web/index.cjs +4 -4
  63. package/dist/web/index.cjs.map +1 -1
  64. package/dist/web/index.js +3 -3
  65. package/package.json +1 -1
  66. package/dist/shared/errors-BmP3TKoW.cjs.map +0 -1
  67. package/dist/shared/errors-GI10kZxk.js.map +0 -1
  68. package/dist/shared/events-B8cjz_Ed.cjs.map +0 -1
  69. package/dist/shared/events-D2n7Yu1P.js.map +0 -1
  70. package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +0 -1
  71. package/dist/shared/key-value-store-Bt2PSMxY.js.map +0 -1
  72. package/dist/shared/multi-storage-C3Ngtop1.js.map +0 -1
  73. package/dist/shared/multi-storage-s-fPtjoy.cjs.map +0 -1
  74. package/dist/shared/redact-DJV0XM3n.js.map +0 -1
  75. package/dist/shared/redact-lAmck1Z6.cjs.map +0 -1
  76. package/dist/shared/render-BrrZOSV5.cjs.map +0 -1
  77. package/dist/shared/render-C6CJ343E.js.map +0 -1
  78. package/dist/shared/url-BNTKqBMB.cjs.map +0 -1
  79. package/dist/shared/url-Dc7wLikf.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { At as RequestOptions, Ct as PaginationOptions, Dt as RawRequestOptions, It as QueryParams, Rt as ServiceDefinition, Sn as ServiceState, St as OperationRequestOptions, Tn as ViewSource, Tt as RateLimitBucketOverride, Ut as BuiltInOperationId, Vt as ItdClock, _ as PrivacySettings, _n as Loose, _t as OperationMethod, bn as ReportReason, c as NotificationSettings, f as Author, fn as FeedTab, g as PinsResult, gt as OperationMetadata, ht as OperationContract, in as UserRef, lt as Unsubscribe, m as MyProfile, mn as InteractionType, mt as OperationAnnotations, nn as Span, nt as AuthIdentity, on as AttachmentType, p as FollowResult, pn as IncidentKind, qt as OperationId, rn as UserId, s as Notification, tn as IsoDate, tt as ClientConnection, un as CommentSort, v as Profile, vt as RetrySafety, wn as ViewReason, x as UserSummary, xn as ReportTargetType, xt as Logger, y as PublicProfile, yn as QrLocationPrecision, yt as ClientHooks } from "./url-yB6T_H_-.js";
1
+ import { At as RequestOptions, Cn as ReportTargetType, Ct as PaginationOptions, Dn as ViewSource, Dt as RawRequestOptions, En as ViewReason, Gt as BuiltInOperationId, Ht as Logger, It as QueryParams, Rt as ServiceDefinition, Sn as ReportReason, St as OperationRequestOptions, Tt as RateLimitBucketOverride, Ut as ItdClock, Yt as OperationId, _ as PrivacySettings, _t as OperationMetadata, an as UserId, at as ClientConnection, bt as ClientHooks, c as NotificationSettings, cn as AttachmentType, f as Author, fn as CommentSort, g as PinsResult, gn as InteractionType, gt as OperationContract, hn as IncidentKind, ht as OperationAnnotations, in as Span, it as Unsubscribe, m as MyProfile, mn as FeedTab, on as UserRef, ot as AuthIdentity, p as FollowResult, rn as IsoDate, s as Notification, v as Profile, vt as OperationMethod, wn as ServiceState, x as UserSummary, xn as QrLocationPrecision, y as PublicProfile, yn as Loose, yt as RetrySafety } from "./url-BOi-_mJT.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
3
  import { r as KeyValueStore } from "./key-value-store-COZaNHZS.js";
4
4
  //#region src/core/cookies.d.ts
@@ -65,238 +65,6 @@ declare class CookieJar {
65
65
  clear(): void;
66
66
  }
67
67
  //#endregion
68
- //#region src/core/plugins/contracts.d.ts
69
- /**
70
- * Обёртка одной логической операции.
71
- *
72
- * Вызывается один раз независимо от повторов и обновления авторизации. Может изменить
73
- * параметры запроса, обработать публичный результат метода или завершить операцию локально.
74
- * `operationId`, HTTP-метод и безопасность повтора задаются операцией.
75
- *
76
- * @param request описание логической операции; не изменяйте сам объект — передайте копию в `next`
77
- * @param next следующая обёртка либо выполнение операции
78
- * `next()` возвращает результат публичного метода. Если обёртка не вызывает `next`, её
79
- * собственный результат считается готовым и повторно не нормализуется.
80
- * @param context общий lifecycle операции; его signal учитывает timeout и `dispose()` клиента
81
- *
82
- * @returns результат в том виде, в котором его получит вызывающий код
83
- *
84
- * @example Дописать заголовок ко всем операциям
85
- * ```ts
86
- * const transformer: OperationTransformer = (request, next) =>
87
- * next({ ...request, headers: { ...request.headers, 'X-Trace': trace() } });
88
- * ```
89
- */
90
- type OperationTransformer = (request: OperationRequestOptions, next: (request: OperationRequestOptions) => Promise<unknown>, context: OperationTransformContext) => Promise<unknown>;
91
- /** Состояние времени жизни логической операции, не влияющее на её семантические параметры. */
92
- interface OperationTransformContext {
93
- /** Общий сигнал пользовательской отмены, timeout и освобождения клиента. */
94
- readonly signal: AbortSignal;
95
- }
96
- /** Финальные данные одной транспортной попытки. */
97
- interface AttemptContext {
98
- /** Постоянный идентификатор операции. */
99
- readonly operationId: OperationId;
100
- /** Нормализованный HTTP-метод. */
101
- readonly method: string;
102
- /** Исходный путь операции до выбора сервиса или `baseUrl`. */
103
- readonly path: string;
104
- /** Полный URL со строкой запроса. */
105
- readonly url: string;
106
- /** Итоговые изменяемые заголовки. */
107
- readonly headers: Headers;
108
- /** Номер сетевой попытки, начиная с 1. */
109
- readonly attempt: number;
110
- /** Подготовленное тело запроса. Поток нельзя читать заранее. */
111
- readonly body: BodyInit | undefined;
112
- /** Общий сигнал отмены и таймаута этой попытки. */
113
- readonly signal: AbortSignal;
114
- }
115
- /**
116
- * Продолжение цепочки перехватчиков. Можно вызвать только один раз.
117
- */
118
- type AttemptNext = () => Promise<Response>;
119
- /**
120
- * Обёртка одной транспортной попытки.
121
- *
122
- * Получает уже разрешённый URL, итоговые заголовки, подготовленное тело и номер попытки.
123
- * Может изменить заголовки, измерить задержку, обработать сырой `Response` или вернуть
124
- * созданный вручную `Response`.
125
- *
126
- * Вызывается для каждой сетевой попытки. Если перехватчик читает тело ответа, используйте
127
- * `response.clone()`: исходный ответ дальше обрабатывает транспорт.
128
- *
129
- * @param context окончательные данные текущей транспортной попытки
130
- * @param next следующий перехватчик либо вызов `fetch`
131
- * @returns исходный или синтетический сырой `Response`
132
- */
133
- type AttemptInterceptor = (context: AttemptContext, next: AttemptNext) => Promise<Response>;
134
- /** Регистрация расширений логической операции. */
135
- interface OperationExtensions {
136
- /** Возвращает неизменяемые метаданные зарегистрированной операции. */
137
- get(operationId: OperationId): OperationMetadata | undefined;
138
- /**
139
- * Подключает обёртку операции.
140
- *
141
- * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
142
- * идемпотентна и снимает только эту регистрацию.
143
- */
144
- use(transformer: OperationTransformer): Unsubscribe;
145
- }
146
- /** Регистрация расширений транспортной попытки. */
147
- interface AttemptExtensions {
148
- /**
149
- * Подключает перехватчик попытки.
150
- *
151
- * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
152
- * идемпотентна и снимает только эту регистрацию.
153
- */
154
- use(interceptor: AttemptInterceptor): Unsubscribe;
155
- }
156
- /**
157
- * Функция освобождения ресурсов плагина.
158
- */
159
- type PluginTeardown = () => void | Promise<void>;
160
- /** API, доступный плагину при подключении. */
161
- interface PluginApi {
162
- /** Базовый URL клиента — например чтобы разобрать абсолютные ссылки из ответа. */
163
- baseUrl: string;
164
- /** Логгер клиента, если он включён. */
165
- logger: Logger | undefined;
166
- /** Обёртки логической операции. */
167
- operations: OperationExtensions;
168
- /** Перехватчики сетевой попытки. */
169
- attempts: AttemptExtensions;
170
- /**
171
- * Внутренний идентификатор текущей авторизации.
172
- */
173
- getAuthScope?: (() => string) | undefined;
174
- /**
175
- * Загружает сессию и возвращает идентификаторы аккаунта и конкретной сессии из JWT.
176
- *
177
- * Используйте для общего состояния нескольких клиентов одного аккаунта.
178
- */
179
- getAuthIdentity?: (() => Promise<AuthIdentity>) | undefined;
180
- }
181
- /**
182
- * Плагин клиента.
183
- *
184
- * Подключается через `itd.use(plugin)` и регистрирует расширения одного или обоих уровней:
185
- * {@link OperationTransformer} для логической операции и {@link AttemptInterceptor} для
186
- * отдельной транспортной попытки.
187
- *
188
- * Настройки отдельного вызова плагин объявляет своим полем в `RequestExtensions` через
189
- * дополнение интерфейса. Пользователь передаёт их в `RequestOptions.extensions`, а обёртка
190
- * операции читает поле своего плагина.
191
- *
192
- * @example Логирование логических операций
193
- * ```ts
194
- * const logging: ClientPlugin = {
195
- * name: 'logging',
196
- * install({ operations, logger }) {
197
- * operations.use(async (request, next) => {
198
- * logger?.info(`${request.method} ${request.path}`);
199
- * return next(request);
200
- * });
201
- * },
202
- * };
203
- *
204
- * itd.use(logging);
205
- * ```
206
- */
207
- interface ClientPlugin {
208
- /** Имя плагина. Должно быть уникальным: повторное подключение — ошибка. */
209
- name: string;
210
- /** Плагины, которые обязаны быть подключены раньше этого. */
211
- requires?: readonly string[];
212
- /** Несовместимые плагины. Достаточно объявить конфликт с одной стороны. */
213
- conflicts?: readonly string[];
214
- /** Имена плагинов, снаружи которых должны стоять оба вида расширений этого плагина. */
215
- before?: readonly string[];
216
- /** Имена плагинов, внутри которых должны стоять оба вида расширений этого плагина. */
217
- after?: readonly string[];
218
- /**
219
- * Устанавливает плагин.
220
- *
221
- * Может вернуть функцию освобождения ресурсов. Она вызывается при `unuse()` или
222
- * окончательном `dispose()` клиента и может быть асинхронной. Сам `install()` синхронный:
223
- * регистрация расширений завершается до того, как `use()` вернёт управление.
224
- */
225
- install(api: PluginApi): void | PluginTeardown;
226
- }
227
- //#endregion
228
- //#region src/core/plugins/registry.d.ts
229
- /** Что реестру нужно знать об остановке. @internal */
230
- interface PluginRegistryOptions {
231
- /** Срок ожидания операций плагина при его отключении, мс. `0` — ждать без ограничения. */
232
- shutdownTimeout: number;
233
- clock: ItdClock;
234
- /** Возвращает публичные метаданные встроенной или feature-операции. */
235
- operationMetadata: (operationId: OperationRequestOptions['operationId']) => OperationMetadata | undefined;
236
- }
237
- /**
238
- * Список подключённых плагинов и зарегистрированных ими расширений.
239
- *
240
- * {@link run} собирает operation transformers вокруг одной логической операции и прикрепляет
241
- * к ней неизменяемый снимок attempt interceptors. Transport исполняет этот снимок отдельно
242
- * для каждой сетевой попытки. Порядок плагинов одинаков для обеих цепочек.
243
- *
244
- * @internal
245
- */
246
- declare class PluginRegistry {
247
- #private;
248
- constructor(options: PluginRegistryOptions);
249
- /** Сколько плагинов подключено. */
250
- get size(): number;
251
- /** Имена плагинов в фактическом порядке выполнения. */
252
- names(): string[];
253
- /** Подключён ли плагин с таким именем. */
254
- has(name: string): boolean;
255
- /** Проверяет добавление без вызова `install()`. @internal */
256
- assertCanAdd(plugin: ClientPlugin): void;
257
- /** Проверяет удаление без изменения реестра. @internal */
258
- assertCanRemove(name: string): void;
259
- /**
260
- * Подключает плагин.
261
- *
262
- * `install()` выполняется синхронно. Каждая регистрация принадлежит установившему её
263
- * плагину и участвует в общем порядке `before`/`after`.
264
- *
265
- * @throws {ItdConfigError} если плагин задан неверно, уже подключён или нарушает зависимости
266
- */
267
- add(plugin: ClientPlugin, context: Omit<PluginApi, 'operations' | 'attempts'>): void;
268
- /**
269
- * Отключает плагин и вызывает его функцию очистки.
270
- *
271
- * Новые запросы перестают видеть расширения плагина сразу. Снимок уже начавшейся операции,
272
- * включая её будущие retry, остаётся неизменным; очистка дождётся завершения операции,
273
- * но не дольше отведённого срока.
274
- *
275
- * @returns `false`, если такого плагина не было
276
- * @throws {ItdStateError} если операции плагина не завершились за отведённый срок
277
- */
278
- remove(name: string): Promise<boolean>;
279
- /**
280
- * Отключает все плагины окончательно.
281
- *
282
- * Очистка идёт изнутри наружу — в порядке, обратном выполнению расширений. Срок ожидания
283
- * общий на все плагины.
284
- */
285
- dispose(): Promise<void>;
286
- /**
287
- * Прогоняет запрос через operation transformers и прикрепляет attempt interceptors.
288
- *
289
- * Снимки обеих цепочек берутся в начале: `unuse()` влияет на новые операции, но не меняет
290
- * уже выполняющуюся и не удаляет interceptors из её последующих retry.
291
- *
292
- * Каждый `next` одноразовый: transformer может завершить операцию сам, но не может породить
293
- * вторую — для `posts.create` это была бы вторая публикация.
294
- *
295
- * @param execute выполнение логической операции, вызываемое самым внутренним transformer
296
- */
297
- run(request: OperationRequestOptions, execute: (request: OperationRequestOptions) => Promise<unknown>, signal: AbortSignal): Promise<unknown>;
298
- }
299
- //#endregion
300
68
  //#region src/core/execution/pipeline.d.ts
301
69
  /** Тело, заново подготовленное для одной транспортной попытки. */
302
70
  interface PreparedRequestBody {
@@ -316,10 +84,9 @@ type RequestBodyFactory = (context: RequestBodyContext) => PreparedRequestBody |
316
84
  /**
317
85
  * Описание запроса внутри конвейера.
318
86
  *
319
- * Отличается от публичного {@link RawRequestOptions} одним служебным полем: слои конвейера
320
- * должны уметь дописать заголовки так, чтобы пользовательские `headers` всё равно остались
321
- * важнее. Смешивать их в одном объекте нельзя — тогда слой авторизации перебивал бы
322
- * `Authorization`, заданный вызывающим кодом вручную.
87
+ * Отличается от публичного {@link RawRequestOptions} служебными полями. Главное из них —
88
+ * `layerHeaders`: слои конвейера дописывают заголовки так, чтобы пользовательские `headers`
89
+ * остались важнее, иначе слой авторизации перебивал бы `Authorization`, заданный вручную.
323
90
  */
324
91
  interface PipelineRequest extends OperationRequestOptions {
325
92
  /** Изолированный cookie jar конкретного auth-flow. @internal */
@@ -349,37 +116,36 @@ type PipelineRequestInput = Omit<PipelineRequest, 'operationId'> & {
349
116
  type RequestHandler = (request: PipelineRequest) => Promise<unknown>;
350
117
  //#endregion
351
118
  //#region src/core/execution/http.d.ts
352
- /** Что нужно фасаду для работы. */
119
+ /** Что нужно точке входа в конвейер. */
353
120
  interface HttpClientDeps {
354
- /** Готовый обработчик — вся цепочка слоёв поверх транспорта. */
121
+ /** Готовый обработчик — вся цепочка стадий поверх транспорта. */
355
122
  handler: RequestHandler;
356
- plugins: PluginRegistry;
357
123
  baseUrl: string;
358
- timeout: number;
124
+ /** Общий срок логической операции по умолчанию; `0` — без срока. */
125
+ deadline: number;
359
126
  clock: ItdClock;
360
127
  lifetimeSignal?: AbortSignal | undefined;
361
128
  hooks: ClientHooks;
362
129
  assertActive?: (() => void) | undefined;
363
130
  }
364
- /** Параметры операции без ID и метода, заданных её контрактом. @internal */
365
- type HttpOperationOptions = Omit<PipelineRequest, 'operationId' | 'method'>;
131
+ /** Параметры операции без полей, которые задаёт её контракт или проставляют стадии. @internal */
132
+ type HttpOperationOptions = Omit<PipelineRequest, 'operationId' | 'method' | 'layerHeaders' | 'attempt'>;
366
133
  /**
367
134
  * Точка входа ресурсов в конвейер запросов.
368
135
  *
369
- * Принимает готовую цепочку обработки и предоставляет ресурсам методы `request`/`execute`.
370
- * О слоях и их порядке ресурсы не знают.
136
+ * Заводит общий lifecycle логической операции отмену, освобождение клиента и `deadline`, —
137
+ * передаёт запрос собранной цепочке стадий и сообщает в `onError` об ошибках, которые
138
+ * не дошли до транспорта. О стадиях и их порядке ресурсы не знают.
371
139
  */
372
140
  declare class HttpClient {
373
141
  #private;
374
142
  constructor(deps: HttpClientDeps);
375
- /** Базовый URL, к которому обращается клиент. */
376
- get baseUrl(): string;
377
143
  /**
378
- * Выполняет запрос к API через собранный конвейер.
144
+ * Выполняет низкоуровневый запрос через собранный конвейер.
379
145
  *
380
146
  * @typeParam T ожидаемая форма ответа после снятия обёртки `{ data: … }`
381
147
  * @throws {ItdApiError} если сервер ответил статусом ≥ 400
382
- * @throws {ItdTimeoutError} если истёк таймаут
148
+ * @throws {ItdTimeoutError} если истёк `timeout` попытки или `deadline` операции
383
149
  * @throws {ItdAbortError} если запрос отменён через `signal`
384
150
  * @throws {ItdNetworkError} если запрос не дошёл до сервера
385
151
  */
@@ -471,7 +237,7 @@ interface FeatureOperationDefinition<T = unknown> {
471
237
  readonly annotations?: OperationAnnotations | undefined;
472
238
  }
473
239
  /** Начальные ограничения нового серверного счётчика feature. */
474
- interface FeatureBucketDefinition extends RateLimitBucketOverride {}
240
+ type FeatureBucketDefinition = RateLimitBucketOverride;
475
241
  /** Результат синхронной сборки API feature. */
476
242
  interface FeatureInstallation<TApi> {
477
243
  readonly api: TApi;
@@ -521,6 +287,166 @@ interface FeatureContext {
521
287
  assertActive(action: string): void;
522
288
  }
523
289
  //#endregion
290
+ //#region src/core/plugins/contracts.d.ts
291
+ /**
292
+ * Обёртка одной логической операции.
293
+ *
294
+ * Вызывается один раз независимо от повторов и обновления авторизации. Может изменить
295
+ * параметры запроса, обработать публичный результат метода или завершить операцию локально.
296
+ * `operationId`, HTTP-метод и безопасность повтора задаются операцией.
297
+ *
298
+ * @param request описание логической операции; не изменяйте сам объект — передайте копию в `next`
299
+ * @param next следующая обёртка либо выполнение операции
300
+ * `next()` возвращает результат публичного метода. Если обёртка не вызывает `next`, её
301
+ * собственный результат считается готовым и повторно не нормализуется.
302
+ * @param context общий lifecycle операции; его signal учитывает timeout и `dispose()` клиента
303
+ *
304
+ * @returns результат в том виде, в котором его получит вызывающий код
305
+ *
306
+ * @example Дописать заголовок ко всем операциям
307
+ * ```ts
308
+ * const transformer: OperationTransformer = (request, next) =>
309
+ * next({ ...request, headers: { ...request.headers, 'X-Trace': trace() } });
310
+ * ```
311
+ */
312
+ type OperationTransformer = (request: OperationRequestOptions, next: (request: OperationRequestOptions) => Promise<unknown>, context: OperationTransformContext) => Promise<unknown>;
313
+ /** Состояние времени жизни логической операции, не влияющее на её семантические параметры. */
314
+ interface OperationTransformContext {
315
+ /** Общий сигнал пользовательской отмены, timeout и освобождения клиента. */
316
+ readonly signal: AbortSignal;
317
+ }
318
+ /** Финальные данные одной транспортной попытки. */
319
+ interface AttemptContext {
320
+ /** Постоянный идентификатор операции. */
321
+ readonly operationId: OperationId;
322
+ /** Нормализованный HTTP-метод. */
323
+ readonly method: string;
324
+ /** Исходный путь операции до выбора сервиса или `baseUrl`. */
325
+ readonly path: string;
326
+ /** Полный URL со строкой запроса. */
327
+ readonly url: string;
328
+ /** Итоговые изменяемые заголовки. */
329
+ readonly headers: Headers;
330
+ /** Номер сетевой попытки, начиная с 1. */
331
+ readonly attempt: number;
332
+ /** Подготовленное тело запроса. Поток нельзя читать заранее. */
333
+ readonly body: BodyInit | undefined;
334
+ /** Общий сигнал отмены и таймаута этой попытки. */
335
+ readonly signal: AbortSignal;
336
+ }
337
+ /**
338
+ * Продолжение цепочки перехватчиков. Можно вызвать только один раз.
339
+ */
340
+ type AttemptNext = () => Promise<Response>;
341
+ /**
342
+ * Обёртка одной транспортной попытки.
343
+ *
344
+ * Получает уже разрешённый URL, итоговые заголовки, подготовленное тело и номер попытки.
345
+ * Может изменить заголовки, измерить задержку, обработать сырой `Response` или вернуть
346
+ * созданный вручную `Response`.
347
+ *
348
+ * Вызывается для каждой сетевой попытки. Если перехватчик читает тело ответа, используйте
349
+ * `response.clone()`: исходный ответ дальше обрабатывает транспорт.
350
+ *
351
+ * @param context окончательные данные текущей транспортной попытки
352
+ * @param next следующий перехватчик либо вызов `fetch`
353
+ * @returns исходный или синтетический сырой `Response`
354
+ */
355
+ type AttemptInterceptor = (context: AttemptContext, next: AttemptNext) => Promise<Response>;
356
+ /** Регистрация расширений логической операции. */
357
+ interface OperationExtensions {
358
+ /** Возвращает неизменяемые метаданные зарегистрированной операции. */
359
+ get(operationId: OperationId): OperationMetadata | undefined;
360
+ /**
361
+ * Подключает обёртку операции.
362
+ *
363
+ * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
364
+ * идемпотентна и снимает только эту регистрацию.
365
+ */
366
+ use(transformer: OperationTransformer): Unsubscribe;
367
+ }
368
+ /** Регистрация расширений транспортной попытки. */
369
+ interface AttemptExtensions {
370
+ /**
371
+ * Подключает перехватчик попытки.
372
+ *
373
+ * Зарегистрированные раньше оборачивают зарегистрированные позже. Возвращённая функция
374
+ * идемпотентна и снимает только эту регистрацию.
375
+ */
376
+ use(interceptor: AttemptInterceptor): Unsubscribe;
377
+ }
378
+ /**
379
+ * Функция освобождения ресурсов плагина.
380
+ */
381
+ type PluginTeardown = () => void | Promise<void>;
382
+ /** API, доступный плагину при подключении. */
383
+ interface PluginApi {
384
+ /** Базовый URL клиента — например чтобы разобрать абсолютные ссылки из ответа. */
385
+ baseUrl: string;
386
+ /** Логгер клиента, если он включён. */
387
+ logger: Logger | undefined;
388
+ /** Обёртки логической операции. */
389
+ operations: OperationExtensions;
390
+ /** Перехватчики сетевой попытки. */
391
+ attempts: AttemptExtensions;
392
+ /**
393
+ * Внутренний идентификатор текущей авторизации.
394
+ */
395
+ getAuthScope?: (() => string) | undefined;
396
+ /**
397
+ * Загружает сессию и возвращает идентификаторы аккаунта и конкретной сессии из JWT.
398
+ *
399
+ * Используйте для общего состояния нескольких клиентов одного аккаунта.
400
+ */
401
+ getAuthIdentity?: (() => Promise<AuthIdentity>) | undefined;
402
+ }
403
+ /**
404
+ * Плагин клиента.
405
+ *
406
+ * Подключается через `itd.use(plugin)` и регистрирует расширения одного или обоих уровней:
407
+ * {@link OperationTransformer} для логической операции и {@link AttemptInterceptor} для
408
+ * отдельной транспортной попытки.
409
+ *
410
+ * Настройки отдельного вызова плагин объявляет своим полем в `RequestExtensions` через
411
+ * дополнение интерфейса. Пользователь передаёт их в `RequestOptions.extensions`, а обёртка
412
+ * операции читает поле своего плагина.
413
+ *
414
+ * @example Логирование логических операций
415
+ * ```ts
416
+ * const logging: ClientPlugin = {
417
+ * name: 'logging',
418
+ * install({ operations, logger }) {
419
+ * operations.use(async (request, next) => {
420
+ * logger?.info(`${request.method} ${request.path}`);
421
+ * return next(request);
422
+ * });
423
+ * },
424
+ * };
425
+ *
426
+ * itd.use(logging);
427
+ * ```
428
+ */
429
+ interface ClientPlugin {
430
+ /** Имя плагина. Должно быть уникальным: повторное подключение — ошибка. */
431
+ name: string;
432
+ /** Плагины, которые обязаны быть подключены раньше этого. */
433
+ requires?: readonly string[];
434
+ /** Несовместимые плагины. Достаточно объявить конфликт с одной стороны. */
435
+ conflicts?: readonly string[];
436
+ /** Имена плагинов, снаружи которых должны стоять оба вида расширений этого плагина. */
437
+ before?: readonly string[];
438
+ /** Имена плагинов, внутри которых должны стоять оба вида расширений этого плагина. */
439
+ after?: readonly string[];
440
+ /**
441
+ * Устанавливает плагин.
442
+ *
443
+ * Может вернуть функцию освобождения ресурсов. Она вызывается при `unuse()` или
444
+ * окончательном `dispose()` клиента и может быть асинхронной. Сам `install()` синхронный:
445
+ * регистрация расширений завершается до того, как `use()` вернёт управление.
446
+ */
447
+ install(api: PluginApi): void | PluginTeardown;
448
+ }
449
+ //#endregion
524
450
  //#region src/core/scheduling/rate-limit.d.ts
525
451
  /** Снимок одного бакета. */
526
452
  interface RateLimitBucketState {
@@ -2879,5 +2805,5 @@ interface RenderSpansOptions {
2879
2805
  */
2880
2806
  declare function renderSpans(content: string, spans?: readonly Span[] | null | undefined, options?: RenderSpansOptions): string;
2881
2807
  //#endregion
2882
- export { ShopConsentContext as $, PageState as $n, markup as $t, DwellEntry as A, Post as An, report as At, ViewTrackerInput as B, CreatePollInput as Bn, PollBuilder as Bt, fromStream as C, CommentReplyTo as Cn, ClientPlugin as Cr, ShopSizeChart as Ct, UpdateProfileInput as D, PinPostResult as Dn, PluginApi as Dr, ReportsResource as Dt, UpdatePrivacyInput as E, LikeResult as En, OperationTransformer as Er, SearchResult as Et, TelemetryClock as F, comment as Fn, CreatePostInput as Ft, ShopConsentsResource as G, QrLoginTarget as Gn, parseMarkdown as Gt, SubscriptionResource as H, CreateReportInput as Hn, poll as Ht, TelemetryOptions as I, BuilderInput as In, PostBuilder as It, ShopOrdersResource as J, NotificationListParams as Jn, MarkupContent as Jt, ShopDeliveryResource as K, Session as Kn, AutoSpansOptions as Kt, TelemetryResource as L, ItdBuilder as Ln, PostInput as Lt, PhotoOpenInput as M, PostUpdateResult as Mn, FeedParams as Mt, TelemetryBatch as N, CommentBuilder as Nn, PostsResource as Nt, UserListParams as O, Poll as On, PluginTeardown as Or, ReportBuilder as Ot, TelemetryBatchOptions as P, CommentInput as Pn, UserPostsParams as Pt, ShopConsent as Q, Page as Qn, autoSpans as Qt, VideoProgressInput as R, isBuilder as Rn, PostUpdateInput as Rt, VideoMimeType as S, Comment as Sn, AttemptNext as Sr, ShopRecipient as St, VerificationResource as T, Hashtag as Tn, OperationTransformContext as Tr, SearchResource as Tt, CreateShopOrderOptions as U, UpdatePostInput as Un, ParseMarkupOptions as Ut, ViewTrackerOptions as V, CreatePostData as Vn, PollInput as Vt, PayShopOrderOptions as W, PaymentMethod as Wn, parseHtml as Wt, ShopResource as X, UpdateNotificationSettingsInput as Xn, MarkupSpan as Xt, ShopProductsResource as Y, NotificationsResource as Yn, MarkupInput as Yt, CreateShopOrderInput as Z, BaseResource as Zn, TextMarkup as Zt, AllowedMimeType as _, UploadOptions as _n, ResolveFileOptions as _r, ShopProduct as _t, ShopFeatureOptions as a, StatusDay as an, ClientFeature as ar, ShopDeliveryDestination as at, ImageMimeType as b, RepliesParams as bn, AttemptExtensions as br, ShopProductSpec as bt, ShopOrderAccessStorage as c, AnnouncementButton as cn, FeatureInstallation as cr, ShopOrderAccessSession as ct, statusDays as d, Portal as dn, ManagedClientResource as dr, ShopOrderItem as dt, PlatformClientVersion as en, PaginationMode as er, ShopConsentKind as et, isMyProfile as f, Report as fn, FileResolver as fr, ShopOrderItemInput as ft, AUDIO_MIME_TYPES as g, FilesResource as gn, ResolveFileContext as gr, ShopPayment as gt, ALLOWED_MIME_TYPES as h, HashtagsResource as hn, PreparedStreamSource as hr, ShopOrderSupport as ht, ShopFeatureApi as i, ServiceStatus as in, RateLimitBucketState as ir, ShopDeliveryCountry as it, InteractionEntry as j, PostStats as jn, CommentsParams as jt, UsersResource as k, PollOption as kn, CookieJar as kr, ReportInput as kt, ShopOrderAccessStorageAdapterOptions as l, ChangelogEntry as ln, FeatureOperationDefinition as lr, ShopOrderAccessVerification as lt, utcStampToIso as m, HashtagPostsParams as mn, PreparedFileSource as mr, ShopOrderSummary as mt, SpanRenderFormat as n, PlatformVersions as nn, PaginatorOptions as nr, ShopDeliveryCalculation as nt, createShopFeature as o, StatusIncidentLine as on, FeatureBucketDefinition as or, ShopDeliveryPoint as ot, toDate as p, VerificationStatus as pn, PreparedBufferSource as pr, ShopOrderStatus as pt, ShopOrderRequestOptions as q, Subscription as qn, MarkupBuilder as qt, renderSpans as r, PlatformStatus as rn, mapPage as rr, ShopDeliveryCity as rt, MemoryShopOrderAccessStorage as s, Announcement as sn, FeatureContext as sr, ShopOrder as st, RenderSpansOptions as t, PlatformResource as tn, Paginator as tr, ShopCreatedOrder as tt, createShopOrderAccessStorage as u, Clan as un, FeatureRequestOptions as ur, ShopOrderDelivery as ut, AudioMimeType as v, UploadedFile as vn, HttpClient as vr, ShopProductCategory as vt, fromUrl as w, CommentUpdateResult as wn, OperationExtensions as wr, ShopSizeChartRow as wt, VIDEO_MIME_TYPES as x, Attachment as xn, AttemptInterceptor as xr, ShopProductStatus as xt, IMAGE_MIME_TYPES as y, CommentsResource as yn, AttemptContext as yr, ShopProductColor as yt, ViewTracker as z, CreateCommentInput as zn, post as zt };
2883
- //# sourceMappingURL=render-UsOGMRzS.d.ts.map
2808
+ export { ShopConsentContext as $, PageState as $n, markup as $t, DwellEntry as A, Post as An, report as At, ViewTrackerInput as B, CreatePollInput as Bn, PollBuilder as Bt, fromStream as C, CommentReplyTo as Cn, PreparedBufferSource as Cr, ShopSizeChart as Ct, UpdateProfileInput as D, PinPostResult as Dn, ResolveFileOptions as Dr, ReportsResource as Dt, UpdatePrivacyInput as E, LikeResult as En, ResolveFileContext as Er, SearchResult as Et, TelemetryClock as F, comment as Fn, CreatePostInput as Ft, ShopConsentsResource as G, QrLoginTarget as Gn, parseMarkdown as Gt, SubscriptionResource as H, CreateReportInput as Hn, poll as Ht, TelemetryOptions as I, BuilderInput as In, PostBuilder as It, ShopOrdersResource as J, NotificationListParams as Jn, MarkupContent as Jt, ShopDeliveryResource as K, Session as Kn, AutoSpansOptions as Kt, TelemetryResource as L, ItdBuilder as Ln, PostInput as Lt, PhotoOpenInput as M, PostUpdateResult as Mn, FeedParams as Mt, TelemetryBatch as N, CommentBuilder as Nn, PostsResource as Nt, UserListParams as O, Poll as On, HttpClient as Or, ReportBuilder as Ot, TelemetryBatchOptions as P, CommentInput as Pn, UserPostsParams as Pt, ShopConsent as Q, Page as Qn, autoSpans as Qt, VideoProgressInput as R, isBuilder as Rn, PostUpdateInput as Rt, VideoMimeType as S, Comment as Sn, FileResolver as Sr, ShopRecipient as St, VerificationResource as T, Hashtag as Tn, PreparedStreamSource as Tr, SearchResource as Tt, CreateShopOrderOptions as U, UpdatePostInput as Un, ParseMarkupOptions as Ut, ViewTrackerOptions as V, CreatePostData as Vn, PollInput as Vt, PayShopOrderOptions as W, PaymentMethod as Wn, parseHtml as Wt, ShopResource as X, UpdateNotificationSettingsInput as Xn, MarkupSpan as Xt, ShopProductsResource as Y, NotificationsResource as Yn, MarkupInput as Yt, CreateShopOrderInput as Z, BaseResource as Zn, TextMarkup as Zt, AllowedMimeType as _, UploadOptions as _n, FeatureContext as _r, ShopProduct as _t, ShopFeatureOptions as a, StatusDay as an, AttemptContext as ar, ShopDeliveryDestination as at, ImageMimeType as b, RepliesParams as bn, FeatureRequestOptions as br, ShopProductSpec as bt, ShopOrderAccessStorage as c, AnnouncementButton as cn, AttemptNext as cr, ShopOrderAccessSession as ct, statusDays as d, Portal as dn, OperationTransformContext as dr, ShopOrderItem as dt, PlatformClientVersion as en, PaginationMode as er, ShopConsentKind as et, isMyProfile as f, Report as fn, OperationTransformer as fr, ShopOrderItemInput as ft, AUDIO_MIME_TYPES as g, FilesResource as gn, FeatureBucketDefinition as gr, ShopPayment as gt, ALLOWED_MIME_TYPES as h, HashtagsResource as hn, ClientFeature as hr, ShopOrderSupport as ht, ShopFeatureApi as i, ServiceStatus as in, RateLimitBucketState as ir, ShopDeliveryCountry as it, InteractionEntry as j, PostStats as jn, CommentsParams as jt, UsersResource as k, PollOption as kn, CookieJar as kr, ReportInput as kt, ShopOrderAccessStorageAdapterOptions as l, ChangelogEntry as ln, ClientPlugin as lr, ShopOrderAccessVerification as lt, utcStampToIso as m, HashtagPostsParams as mn, PluginTeardown as mr, ShopOrderSummary as mt, SpanRenderFormat as n, PlatformVersions as nn, PaginatorOptions as nr, ShopDeliveryCalculation as nt, createShopFeature as o, StatusIncidentLine as on, AttemptExtensions as or, ShopDeliveryPoint as ot, toDate as p, VerificationStatus as pn, PluginApi as pr, ShopOrderStatus as pt, ShopOrderRequestOptions as q, Subscription as qn, MarkupBuilder as qt, renderSpans as r, PlatformStatus as rn, mapPage as rr, ShopDeliveryCity as rt, MemoryShopOrderAccessStorage as s, Announcement as sn, AttemptInterceptor as sr, ShopOrder as st, RenderSpansOptions as t, PlatformResource as tn, Paginator as tr, ShopCreatedOrder as tt, createShopOrderAccessStorage as u, Clan as un, OperationExtensions as ur, ShopOrderDelivery as ut, AudioMimeType as v, UploadedFile as vn, FeatureInstallation as vr, ShopProductCategory as vt, fromUrl as w, CommentUpdateResult as wn, PreparedFileSource as wr, ShopSizeChartRow as wt, VIDEO_MIME_TYPES as x, Attachment as xn, ManagedClientResource as xr, ShopProductStatus as xt, IMAGE_MIME_TYPES as y, CommentsResource as yn, FeatureOperationDefinition as yr, ShopProductColor as yt, ViewTracker as z, CreateCommentInput as zn, post as zt };
2809
+ //# sourceMappingURL=render-CBroJPcV.d.ts.map