itd-api 0.0.11 → 0.2.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 (60) hide show
  1. package/README.md +114 -485
  2. package/dist/index.cjs +8781 -415
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +4990 -1
  5. package/dist/index.d.ts +4990 -1
  6. package/dist/index.js +8688 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/multi-storage-BhcA2Izn.d.ts +198 -0
  9. package/dist/multi-storage-CyMe404l.js +805 -0
  10. package/dist/multi-storage-CyMe404l.js.map +1 -0
  11. package/dist/multi-storage-D1keK2Op.cjs +930 -0
  12. package/dist/multi-storage-D1keK2Op.cjs.map +1 -0
  13. package/dist/multi-storage-NDqzRQcD.d.cts +198 -0
  14. package/dist/node.cjs +225 -548
  15. package/dist/node.cjs.map +1 -1
  16. package/dist/node.d.cts +46 -59
  17. package/dist/node.d.ts +46 -59
  18. package/dist/node.js +223 -126
  19. package/dist/node.js.map +1 -1
  20. package/dist/runtime-CFEsf-jD.cjs +185 -0
  21. package/dist/runtime-CFEsf-jD.cjs.map +1 -0
  22. package/dist/runtime-DHxDn8gf.js +126 -0
  23. package/dist/runtime-DHxDn8gf.js.map +1 -0
  24. package/dist/storage-BjNRlkbE.d.cts +82 -0
  25. package/dist/storage-BjNRlkbE.d.ts +82 -0
  26. package/dist/storage-D9tfHx7Z.js +424 -0
  27. package/dist/storage-D9tfHx7Z.js.map +1 -0
  28. package/dist/storage-ycBqLBRB.cjs +615 -0
  29. package/dist/storage-ycBqLBRB.cjs.map +1 -0
  30. package/dist/web.cjs +87 -0
  31. package/dist/web.cjs.map +1 -0
  32. package/dist/web.d.cts +27 -0
  33. package/dist/web.d.ts +27 -0
  34. package/dist/web.js +86 -0
  35. package/dist/web.js.map +1 -0
  36. package/package.json +34 -14
  37. package/dist/chunk-QD4UHJFF.cjs +0 -7387
  38. package/dist/chunk-QD4UHJFF.cjs.map +0 -1
  39. package/dist/chunk-TB7HW3VX.js +0 -7277
  40. package/dist/chunk-TB7HW3VX.js.map +0 -1
  41. package/dist/index-CrlTO7sR.d.cts +0 -4858
  42. package/dist/index-CrlTO7sR.d.ts +0 -4858
  43. package/guides/README.md +0 -22
  44. package/guides/authentication/README.md +0 -176
  45. package/guides/authentication/examples/bot-with-session.mjs +0 -98
  46. package/guides/authentication/examples/turnstile-login.mjs +0 -56
  47. package/guides/integrations/README.md +0 -62
  48. package/guides/integrations/examples/proxy.mjs +0 -26
  49. package/guides/multi-accounts/README.md +0 -142
  50. package/guides/multi-accounts/examples/multi-accounts.mjs +0 -71
  51. package/guides/plugins/README.md +0 -162
  52. package/guides/plugins/examples/cache.mjs +0 -33
  53. package/guides/plugins/examples/crypto.mjs +0 -54
  54. package/guides/quickstart/README.md +0 -124
  55. package/guides/quickstart/examples/quick-start.mjs +0 -44
  56. package/guides/quickstart/examples/typescript.ts +0 -90
  57. package/guides/realtime/README.md +0 -109
  58. package/guides/realtime/examples/notifications.mjs +0 -62
  59. package/guides/text-markup/README.md +0 -214
  60. package/guides/text-markup/examples/create-post.mjs +0 -64
package/README.md CHANGED
@@ -1,529 +1,158 @@
1
- # itd-api
2
-
3
- Клиент REST и realtime API социальной сети **итд.com** для JavaScript и TypeScript.
4
-
5
- - **Ноль зависимостей** у установленного пакета
6
- - **Работает везде**: Node 18+, браузер, Bun, Deno, React Native — только web-стандарты
7
- - **ESM и CommonJS**, полные `.d.ts` с описаниями на русском
8
- - Авторизация, продление токена, повторы и очередь запросов — **сами**
9
- - Три схемы пагинации спрятаны за одним `for await`
10
- - Уведомления из REST и из потока приведены к **одной форме**
11
-
12
- ```bash
13
- npm install itd-api
14
- ```
15
-
16
- ---
17
-
18
- ## Быстрый старт
19
-
20
- ```ts
21
- import { ItdClient, FeedTab } from 'itd-api';
22
-
23
- const itd = new ItdClient({ auth: process.env.ITD_TOKEN });
24
-
25
- const me = await itd.users.me();
26
- console.log(`@${me.username}, подписчиков: ${me.followersCount}`);
27
-
28
- for await (const post of itd.posts.iterate({ tab: FeedTab.Following })) {
29
- if (!post.isLiked) await itd.posts.like(post.id);
30
- }
31
- ```
32
-
33
- В Node, Bun и Deno импортируйте `itd-api/node` — оттуда доступны загрузка файлов по пути
34
- и хранение сессии в файле:
35
-
36
- ```ts
37
- import { ItdClient, FileTokenStorage } from 'itd-api/node';
38
-
39
- // Сессия из файла: продлевается сама, `auth` не нужен. Как её туда положить —
40
- // в разделе «Авторизация»: вход требует капчи, поэтому делается один раз.
41
- const itd = new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });
42
-
43
- await itd.posts.create((p) => p.content('привет').attach('./photo.jpg'));
44
- ```
45
-
46
- Продолжение с запускаемыми примерами — в [руководстве по быстрому старту](./guides/quickstart/README.md).
47
- Все тематические материалы собраны в [`guides/`](./guides/README.md).
48
-
49
- ---
50
-
51
- ## Авторизация
52
-
53
- Клиент может взять доступ из `auth`, сохранённой сессии или явного вызова `itd.auth`:
54
-
55
- ```ts
56
- new ItdClient({ auth: '<accessToken>' });
57
- new ItdClient({ auth: { accessToken, refreshToken } });
58
- new ItdClient({ auth: { email, password, getTurnstileToken } });
59
- new ItdClient({ storage: new FileTokenStorage('./.itd-session.json') });
60
- ```
61
-
62
- При `401` сессия продлевается, исходный запрос повторяется, а новое состояние сохраняется.
63
- Параллельные запросы ждут одного refresh. Потерю сессии можно отследить:
64
-
65
- ```ts
66
- itd.on('authError', ({ error }) => {
67
- if (isItdApiError(error)) console.error('Сессия потеряна:', error.code);
68
- });
69
- ```
70
-
71
- Вход, регистрация и восстановление пароля требуют одноразовый Turnstile token. Подробности
72
- о cookie, `deviceId`, OTP, собственном storage и автоматическом решателе:
73
- [руководство по авторизации](./guides/authentication/README.md).
74
-
75
- ---
76
-
77
- ## Несколько аккаунтов
78
-
79
- `ItdAccounts` хранит именованные клиенты с отдельными tokens, cookie и `deviceId`, но одним
80
- `MultiTokenStorage`:
81
-
82
- ```ts
83
- import { ItdAccounts, FileMultiTokenStorage } from 'itd-api/node';
84
-
85
- const accounts = new ItdAccounts({
86
- storage: new FileMultiTokenStorage('./.itd-sessions.json'),
87
- rateLimit: { concurrency: 4 },
88
- });
89
-
90
- // Поднимаем тех, кто уже входил раньше: ни auth, ни капча не нужны.
91
- await accounts.restore();
92
-
93
- if (!accounts.has('kiow')) {
94
- accounts.addAccount('kiow', { auth: { email, password, getTurnstileToken } });
95
- }
96
-
97
- const itd = accounts.account('kiow'); // обычный ItdClient со всеми разделами
98
- await itd.posts.create({ content: 'привет' });
99
- await accounts.close();
100
- ```
101
-
102
- Личные прокси, общая или раздельные очереди, собственное хранилище и события контейнера
103
- описаны в [руководстве по нескольким аккаунтам](./guides/multi-accounts/README.md).
104
-
105
- ---
106
-
107
- ## Пагинация
108
-
109
- Три разные схемы API (курсор, страницы, смещение) выглядят одинаково:
110
-
111
- ```ts
112
- // по элементам
113
- for await (const post of itd.posts.iterate({ tab: 'popular' })) { … }
114
-
115
- // по страницам — когда нужны сведения о самой странице
116
- for await (const page of itd.posts.iterateComments(postId).pages()) {
117
- console.log(page.items.length, 'из', page.total);
118
- }
119
-
120
- // набрать нужное количество и остановиться
121
- const posts = await itd.posts.iterate({ tab: 'popular' }).collect(100);
122
- ```
123
-
124
- Отдельные страницы тоже доступны:
125
-
126
- ```ts
127
- const page = await itd.posts.list({ tab: 'popular', limit: 20 });
128
- const next = await itd.posts.list({ tab: 'popular', cursor: page.nextCursor ?? undefined });
129
- ```
130
-
131
- Курсор непрозрачен: у вкладки `popular` это номер страницы, у `following` — отметка времени.
132
- Передавайте его обратно как есть.
133
-
134
- Перебор одноразовый: позиция хранится внутри, поэтому второй `for await` по тому же объекту
135
- ничего не выдаст. Нужен ещё проход — возьмите новый перебор у того же метода.
136
-
137
- ### Чего API не умеет
138
-
139
- **Подписчики, подписки и заблокированные не листаются.** Сервер отдаёт первые 20 записей
140
- и на этом всё: `page` он игнорирует, `limit` больше 20 молча уменьшает, а `hasMore` всегда
141
- `false`. Числу `total` там тоже верить нельзя: оно расходится с `followersCount` из профиля.
142
-
143
- ```ts
144
- // вернёт 20 записей и остановится — это предел API, а не библиотеки
145
- const all = await itd.users.iterateFollowers('durov').collect();
146
- ```
147
-
148
- **`posts.byUser()` — это стена, а не авторские посты.** В неё входят и записи, которые
149
- другие оставили на странице пользователя, поэтому записей обычно больше, чем `postsCount`
150
- в профиле. Нужны только свои — отфильтруйте по `post.author.id`.
151
-
152
- ---
153
-
154
- ## Публикация
155
-
156
- Три равноправные формы, проверки одинаковы для каждой:
157
-
158
- ```ts
159
- // обычный объект
160
- await itd.posts.create({ content: 'привет' });
161
-
162
- // функция-настройщик — импорты не нужны
163
- await itd.posts.create((p) =>
164
- p.content('привет')
165
- .attach('./photo.jpg')
166
- .poll((q) => q.question('нравится?').options('да', 'нет')),
167
- );
168
-
169
- // билдер — когда объект готовится заранее
170
- import { post, poll } from 'itd-api';
171
-
172
- const draft = post().onWall(userId);
173
- await itd.posts.create(draft.content('первый'));
174
- await itd.posts.create(draft.content('второй')); // заготовка не испорчена
175
- ```
176
-
177
- Файлы из `attach()` загружаются автоматически, порядок вложений сохраняется, MIME-тип
178
- проверяется до отправки.
179
-
180
- ### Разметка текста
181
-
182
- Билдер собирает текст и сам считает смещения:
183
-
184
- ```ts
185
- import { post, renderSpans } from 'itd-api';
186
-
187
- const created = await itd.posts.create(
188
- post().markup((m) =>
189
- m
190
- .text('смотрите ')
191
- .hashtag('котики')
192
- .text(' от ')
193
- .mention('durov')
194
- .text(': ')
195
- .bold('важно'),
196
- ),
197
- );
198
-
199
- renderSpans(created.content, created.spans); // безопасный HTML по умолчанию
200
- ```
201
-
202
- Доступны `bold`, `italic`, `underline`, `strike`, `spoiler`, `monospace`, `quote`, `link`,
203
- `hashtag`, `mention`, `span()` и несколько стилей сразу через `styled()`. Вложенные и
204
- пересекающиеся spans поддерживаются. Смещения измеряются в единицах UTF-16, как индексы
205
- строк и DOM Selection в JavaScript.
206
-
207
- Для обычного текста есть автоматическое обнаружение ссылок, хэштегов и упоминаний:
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/KiowDev/itd-api/main/guides/web/public/logos/itd-api-logo-horizontal-dark.svg">
4
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/KiowDev/itd-api/main/guides/web/public/logos/itd-api-logo-horizontal.svg">
5
+ <img alt="itd-api" src="https://raw.githubusercontent.com/KiowDev/itd-api/main/guides/web/public/logos/itd-api-logo-horizontal.svg" width="560">
6
+ </picture>
7
+ </p>
208
8
 
209
- ```ts
210
- await itd.posts.create(post('#котики от @durov: https://example.com').autoSpans());
211
- ```
212
-
213
- `renderSpans()` также выводит Markdown и ANSI и позволяет настроить маршруты упоминаний,
214
- хэштегов и префикс CSS-классов. Вызов `postBuilder.content(newText)` сбрасывает прежние
215
- spans, поскольку они рассчитаны для другого текста. `posts.update()` принимает тот же билдер,
216
- но требует явно заданный `content`.
217
-
218
- Авторазметка, пересекающиеся стили, обновление и настройка рендера подробно разобраны
219
- в [руководстве по разметке](./guides/text-markup/README.md).
220
-
221
- Билдеры есть у разметки, поста, комментария, опроса и жалобы. Все они неизменяемые, а `build()`
222
- проверяет данные и бросает `ItdConfigError` **до** обращения к сети:
223
-
224
- ```ts
225
- post('привет').onWall('durov');
226
- // ItdConfigError: wallRecipientId должен быть UUID, а не именем пользователя
227
- // (получено: «durov»). Идентификатор можно взять из профиля:
228
- // (await itd.users.get(username)).id
229
- ```
230
-
231
- ---
232
-
233
- ## Уведомления и realtime
234
-
235
- ```ts
236
- import { formatNotificationText, resolveNotificationUrl } from 'itd-api';
237
-
238
- const stream = itd.realtime();
239
-
240
- stream.on('notification', ({ notification }) => {
241
- console.log(formatNotificationText(notification)); // «Аня и ещё 2 оценили ваш пост»
242
- console.log(resolveNotificationUrl(notification)); // '/@anya/post/9f1c…'
243
- });
244
-
245
- await stream.connect();
246
- ```
247
-
248
- REST и поток используют одну форму уведомления. Переподключение, refresh token, keep-alive
249
- и fallback на polling обрабатываются внутри. Эксплуатационные настройки и счётчик
250
- непрочитанных разобраны в [руководстве по realtime](./guides/realtime/README.md).
251
-
252
- ---
253
-
254
- ## Статус сервисов
255
-
256
- `itd.platform.status()` отдаёт состояние платформы и историю доступности за 90 суток.
257
- Авторизация не нужна, ответ кэшируется сервером на минуту.
9
+ # itd-api
258
10
 
259
- ```ts
260
- import { statusDays } from 'itd-api';
11
+ [![npm version](https://img.shields.io/npm/v/itd-api.svg)](https://www.npmjs.com/package/itd-api)
12
+ [![npm downloads](https://img.shields.io/npm/dm/itd-api.svg)](https://www.npmjs.com/package/itd-api)
13
+ [![CI](https://github.com/KiowDev/itd-api/actions/workflows/ci.yml/badge.svg)](https://github.com/KiowDev/itd-api/actions/workflows/ci.yml)
14
+ [![Node.js](https://img.shields.io/node/v/itd-api.svg)](https://www.npmjs.com/package/itd-api)
15
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-3178c6.svg)](./tsconfig.json)
16
+ [![license](https://img.shields.io/npm/l/itd-api.svg)](./LICENSE)
261
17
 
262
- const status = await itd.platform.status();
18
+ Независимый TypeScript-клиент REST и realtime API социальной сети **итд.com**.
19
+ Проект не является официальным SDK и не аффилирован с итд.com.
263
20
 
264
- status.overall_status; // 'operational' | 'degraded' | 'downtime'
265
- status.services.map((s) => s.current_status);
21
+ [Документация](https://kiowdev.github.io/itd-api/) ·
22
+ [Быстрый старт](https://kiowdev.github.io/itd-api/quickstart/) ·
23
+ [Руководства](https://kiowdev.github.io/itd-api/guides/) ·
24
+ [Справочник API](https://kiowdev.github.io/itd-api/reference/) ·
25
+ [Совместимость](#совместимость) ·
26
+ [Сеть и доверие](#сеть-и-доверие) ·
27
+ [Пакеты проекта](#пакеты-проекта)
266
28
 
267
- const auth = status.services.find((s) => s.id === 'auth');
268
- auth?.uptime_90d; // 97.92
269
- auth?.last_checked; // '2026-07-23T23:14:25Z'
29
+ ## Установка
270
30
 
271
- const days = auth ? statusDays(auth) : []; // 90 элементов, [0] — сегодня
272
- days[0]?.uptime; // 100
273
- days[0]?.lines; // [{ t: 'down', text: 'недоступен 6 мин (12:00–12:06)' }]
31
+ ```bash
32
+ npm install itd-api
274
33
  ```
275
34
 
276
- Поле `days` приходит объектом с числовыми ключами, и сутки без данных сервер пропускает —
277
- `statusDays()` разворачивает его в массив, где пропуски равны `null`. Строки в `lines`
278
- готовы к показу как есть: длительность и границы интервала отдельными полями не приходят,
279
- время в них московское, тогда как `date_key` суток нарезан по UTC.
280
-
281
- ### Сервисы платформы
282
-
283
- Статус живёт на отдельном домене — `статус.итд.com`. Такие домены описываются как сервисы:
284
- у каждого своё имя, хост, заголовки и признак публичности. Запрос выбирает сервис
285
- полем `service`.
35
+ Передайте access token и запросите посты со стены пользователя:
286
36
 
287
37
  ```ts
288
- const itd = new ItdClient({
289
- services: {
290
- pb: {
291
- baseUrl: 'https://pbapi.xn--d1ah4a.com',
292
- headers: { Referer: 'https://pixel.xn--d1ah4a.com/' },
293
- },
294
- },
295
- });
296
-
297
- await itd.request({ method: 'GET', service: 'pb', path: '/api/pixel-info', query: { x: 1, y: 2 } });
298
- ```
299
-
300
- То же самое после создания клиента — `itd.defineService({ name, baseUrl, headers, auth })`;
301
- базовый URL сервиса отдаёт `itd.serviceBaseUrl(name)`.
302
-
303
- Bearer-токен по умолчанию отправляется только основному хосту и его поддоменам.
304
- Публичный или сторонний сервис его не получает. То же правило действует для разового
305
- `itd.request({ baseUrl })`; если внешнему хосту действительно нужна авторизация,
306
- разрешите её явно через `skipAuth: false`.
307
-
308
- У каждого сервиса своя очередь `rateLimit`: лимит частоты сервер считает по хосту, поэтому
309
- `429` от статуса не тормозит основной API и наоборот.
310
-
311
- ---
312
-
313
- ## Ошибки
38
+ import { ItdClient } from 'itd-api';
314
39
 
315
- Обе формы ошибок API сведены к одному классу:
40
+ const itd = new ItdClient({ auth: '<accessToken>' });
41
+ const page = await itd.posts.byUser('nowkie', { limit: 10 });
316
42
 
317
- ```ts
318
- import { ItdValidationError, ItdRateLimitError, isItdApiError } from 'itd-api';
319
-
320
- try {
321
- await itd.users.updateMe({ username: 'занятое_имя' });
322
- } catch (error) {
323
- if (error instanceof ItdValidationError) {
324
- console.log(error.fieldErrors.username); // ['Имя уже занято']
325
- } else if (error instanceof ItdRateLimitError) {
326
- console.log(error.retryAfter); // мс
327
- } else if (isItdApiError(error)) {
328
- console.log(error.status, error.code, error.message);
329
- }
43
+ for (const post of page.items) {
44
+ console.log(post.author.username, post.content);
330
45
  }
331
46
  ```
332
47
 
333
- `ItdApiError` `ItdValidationError`, `ItdAuthError`, `ItdForbiddenError`, `ItdNotFoundError`,
334
- `ItdConflictError`, `ItdRateLimitError`, `ItdPhoneVerificationError`, `ItdServerError`.
335
- Отдельно: `ItdNetworkError`, `ItdTimeoutError`, `ItdAbortError`, `ItdConfigError`.
336
-
337
- ---
338
-
339
- ## Настройка
340
-
341
- ```ts
342
- const itd = new ItdClient({
343
- baseUrl: 'https://xn--d1ah4a.com', // свой прокси, если работаете из браузера
344
- auth: { email, password, getTurnstileToken },
345
- storage: new FileTokenStorage('./.itd-session.json'),
346
- timeout: 30_000,
347
- retry: { attempts: 3, retryWrites: false },
348
- rateLimit: { concurrency: 4, rps: 8 },
349
- // Заголовки латиницей: кириллица в них запрещена самим HTTP.
350
- userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36', // по умолчанию itd-api/<версия>; false — не слать
351
- deviceId: '3f2a…-uuid', // по умолчанию заводится сам и живёт в сессии
352
- services: { pb: 'https://pbapi.xn--d1ah4a.com' }, // домены сервисов платформы, см. ниже
353
- logger: true, // токены и пароли в логах маскируются
354
- hooks: {
355
- onRequest: (ctx) => console.log(ctx.method, ctx.path),
356
- onRetry: (ctx) => console.log('повтор через', ctx.delay),
357
- },
358
- });
359
- ```
360
-
361
- **Повторы.** Обрыв сети и `5xx` не гарантируют, что запрос не был обработан, поэтому запись
362
- по умолчанию не повторяется (`retryWrites: false`): повтор мог бы создать дубль поста.
363
- Чтения повторяются с экспоненциальным откатом.
48
+ Для долгоживущего приложения восстановите сохранённую сессию или настройте вход по
49
+ [руководству по авторизации](https://kiowdev.github.io/itd-api/authentication/).
364
50
 
365
- **Очередь: `concurrency` и `rps` решают разные задачи.** Все запросы идут через одну очередь
366
- клиента, поэтому достаточно **одного экземпляра `ItdClient` на приложение** — разложите его
367
- по модулям, и темп будет общим.
51
+ ## Возможности
368
52
 
369
- `concurrency` (по умолчанию 6) ограничивает только одновременность. От ограничения частоты
370
- он почти не спасает: десять запросов подряд при `concurrency: 1` уходят за ~150 мс,
371
- а окно сервера измеряется десятками секунд. Темп задаёт `rps`:
372
-
373
- ```ts
374
- rateLimit: { concurrency: 2, rps: 0.5 } // не чаще одного запроса в 2 секунды
375
- ```
376
-
377
- Ставить `concurrency: 1` без нужды не стоит: загрузка видео с таймаутом в 300 секунд
378
- заблокирует на это время вообще всё остальное.
379
-
380
- **Ограничение частоты — отдельный механизм.** Лимит у каждого эндпоинта свой: замеры по
381
- `x-ratelimit-limit` дали 90 у `/api/posts`, 40 у `/api/users/me` и `/api/notifications/`,
382
- 25 у `/api/v1/auth/refresh` и всего 15 у `/api/files/upload`. Сервер
383
- не присылает `Retry-After` и не сообщает, когда окно сбросится: есть только заголовки
384
- `x-ratelimit-limit` и `x-ratelimit-remaining` (доступны на `ItdRateLimitError` как
385
- `rateLimit` и `rateLimitRemaining`).
386
-
387
- Экспоненциальный откат в сотни миллисекунд при окне около минуты бесполезен, поэтому
388
- для `429` используется лестница пауз:
389
-
390
- ```ts
391
- rateLimit: { retryDelays: [1000, 5000, 30_000, 60_000, 90_000] } // по умолчанию
392
- ```
393
-
394
- Первый шаг короткий — вдруг окно уже истекло, тогда работа продолжится почти сразу.
395
- Дальше паузы выходят на масштаб окна. Когда лестница кончилась, `ItdRateLimitError`
396
- пробрасывается вам. Список не зависит от `retry.attempts` и переопределяется одной строкой.
397
-
398
- Дополнительно очередь **тормозит заранее**: как только `x-ratelimit-remaining` доходит
399
- до нуля, запросы придерживаются, не дожидаясь отказа. Отключается через
400
- `rateLimit: { respectHeaders: false }`.
401
-
402
- ### Про CORS
403
-
404
- **Напрямую из браузера запросы работать не будут.** Проверено запросами к боевому API:
405
- на preflight сервер отвечает `204` с `Access-Control-Allow-Methods` и
406
- `Access-Control-Allow-Credentials`, но **без `Access-Control-Allow-Origin`** — браузер
407
- такой ответ отвергает.
408
-
409
- Поэтому в браузерном приложении укажите в `baseUrl` адрес своего прокси. В Node, Bun,
410
- Deno и React Native ограничение не действует.
411
-
412
- Исключение — `itd.platform.status()`: страница статуса отдаёт
413
- `Access-Control-Allow-Origin: *`, и этот метод работает из браузера напрямую.
414
-
415
- ### Прокси (HTTP/SOCKS5)
53
+ | Область | Что поддерживается |
54
+ |---|---|
55
+ | REST API | пользователи, посты, комментарии, файлы, уведомления, поиск, жалобы, верификация и подписка |
56
+ | Авторизация | access/refresh token, автоматическое обновление, OTP, хранение сессии и несколько аккаунтов |
57
+ | Realtime | SSE с переподключением и fallback на polling |
58
+ | Пагинация | разные серверные схемы через единый `for await` |
59
+ | Публикация | билдеры постов, комментариев, опросов, разметки текста и загрузки файлов |
60
+ | Надёжность | таймауты, отмена, очередь, rate limiting, безопасные повторы, хуки и типизированные ошибки |
61
+ | Расширение | плагины, собственный `fetch`, сервисы и произвольные запросы |
62
+ | Платформа | версии приложений, changelog, анонсы, портал и состояние сервисов |
416
63
 
417
- Чтобы направить запросы клиента через прокси, возьмите `fetch` из пакета
418
- [`@itd-api/proxy`](./proxy/README.md):
64
+ У основного пакета нет runtime-зависимостей. Он поставляется как ESM и CommonJS с
65
+ полными TypeScript-типами.
419
66
 
420
- ```sh
421
- npm i @itd-api/proxy
422
- ```
67
+ ## Пакеты проекта
423
68
 
424
- ```ts
425
- import { ItdClient } from 'itd-api';
426
- import { proxyFetch } from '@itd-api/proxy';
69
+ Все пакеты в таблице поддерживаются проектом itd-api.
427
70
 
428
- const fetch = proxyFetch('socks5://127.0.0.1:1080');
429
- // http://…, https://…, socks5://… — можно с user:pass@
430
- const itd = new ItdClient({ fetch });
71
+ | Пакет | Назначение | Среда | npm | Документация |
72
+ |---|---|---|---|---|
73
+ | `itd-api` | REST/realtime-клиент | Node.js 18+, браузер, Bun, Deno, React Native | [npm](https://www.npmjs.com/package/itd-api) | [быстрый старт](https://kiowdev.github.io/itd-api/quickstart/) |
74
+ | `@itd-api/cache` | TTL/LRU-кэш и дедупликация запросов | среды основного клиента | [npm](https://www.npmjs.com/package/@itd-api/cache) | [документация](https://kiowdev.github.io/itd-api/packages/cache) |
75
+ | `@itd-api/crypto` | скрытые сообщения в постах, комментариях и профилях | среды основного клиента | [npm](https://www.npmjs.com/package/@itd-api/crypto) | [документация](https://kiowdev.github.io/itd-api/packages/crypto) |
76
+ | `@itd-api/proxy` | HTTP/HTTPS- и SOCKS5-транспорт | Node.js 18+, Bun, Deno | [npm](https://www.npmjs.com/package/@itd-api/proxy) | [документация](https://kiowdev.github.io/itd-api/packages/proxy) |
77
+ | `@itd-api/turnstile` | получение Turnstile-токена в локальном браузере | Node.js 18+, Bun, Deno + Playwright | [npm](https://www.npmjs.com/package/@itd-api/turnstile) | [документация](https://kiowdev.github.io/itd-api/packages/turnstile) |
431
78
 
432
- // …работа…
79
+ ## Документация
433
80
 
434
- await itd.close();
435
- await fetch.close(); // закрывает пул соединений
436
- ```
81
+ | Раздел | Содержание |
82
+ |---|---|
83
+ | [Быстрый старт](https://kiowdev.github.io/itd-api/quickstart/) | создание клиента, чтение и публикация, пагинация, ошибки |
84
+ | [Авторизация](https://kiowdev.github.io/itd-api/authentication/) | токены, Turnstile, OTP, refresh и хранение сессии |
85
+ | [Конфигурация](https://kiowdev.github.io/itd-api/configuration/) | таймауты, повторы, очереди, сервисы, hooks и lifecycle |
86
+ | [Несколько аккаунтов](https://kiowdev.github.io/itd-api/multi-accounts/) | `ItdAccounts`, общее хранилище и отдельные сессии |
87
+ | [Разметка текста](https://kiowdev.github.io/itd-api/text-markup/) | spans, автоматическая разметка и отображение |
88
+ | [Realtime](https://kiowdev.github.io/itd-api/realtime/) | события, SSE, polling и переподключение |
89
+ | [Интеграции](https://kiowdev.github.io/itd-api/integrations/) | browser proxy и Turnstile |
90
+ | [Плагины](https://kiowdev.github.io/itd-api/plugins/) | cache, crypto и создание плагина |
91
+ | [Справочник API](https://kiowdev.github.io/itd-api/reference/) | ресурсы, методы, типы, ошибки и билдеры |
437
92
 
438
- Через тот же `fetch` пойдут авторизация, cookie, очередь, повторы и поток уведомлений.
439
- Только для Node/Bun/Deno. Подключение proxy и Turnstile разобрано в
440
- [руководстве по интеграциям](./guides/integrations/README.md), параметры транспорта — в
441
- [README пакета](./proxy/README.md).
93
+ ## Совместимость
442
94
 
443
- ---
95
+ | Среда | Поддержка |
96
+ |---|---|
97
+ | Node.js 18+ | полная, включая файловую точку входа `itd-api/node` |
98
+ | Bun, Deno | полная |
99
+ | Браузер | кроме файловой системы; хранилище сессии — `itd-api/web`; для основного API нужен server-side proxy из-за CORS |
100
+ | React Native | полная; realtime переключается на polling без потокового чтения |
444
101
 
445
- ## Плагины
102
+ TypeScript 5.0+. Пакет проверяется в Node.js 18, 20, 22, 24 и 26, а корректность
103
+ публикации — через `publint` и `@arethetypeswrong/cli`.
446
104
 
447
- Плагин оборачивает запросы и ответы сразу всех ресурсов:
105
+ ## Сеть и доверие
448
106
 
449
- ```ts
450
- import { ItdClient } from 'itd-api';
451
- import { cache } from '@itd-api/cache';
452
-
453
- const itd = new ItdClient({ auth: token });
454
- itd.use(
455
- cache({
456
- ttl: 60_000,
457
- routes: ['users.get', 'posts.get', 'posts.list'],
458
- }),
459
- );
460
- ```
107
+ По умолчанию основной пакет обращается ровно к двум хостам:
461
108
 
462
- Официальные плагины Cache и Crypto, полный контракт `ItdPlugin`, собственные опции и
463
- структура пакета описаны в
464
- [руководстве по плагинам](./guides/plugins/README.md).
109
+ | Хост | Назначение | Автоматическая передача Bearer-токена |
110
+ |---|---|---|
111
+ | `https://xn--d1ah4a.com` (`итд.com`) | REST API, авторизация и realtime | да, для защищённых REST-методов и realtime |
112
+ | `https://xn--80a7abcbg.xn--d1ah4a.com` (`статус.итд.com`) | публичное состояние сервисов | нет |
465
113
 
466
- ---
114
+ Опциональный `@itd-api/turnstile` дополнительно загружает виджет с
115
+ `https://challenges.cloudflare.com`; пакет не передаёт пароль странице браузера.
116
+ `@itd-api/cache` и `@itd-api/crypto` сами не создают сетевые запросы, а
117
+ `@itd-api/proxy` использует только адрес proxy, заданный пользователем.
467
118
 
468
- ## Что доступно
119
+ Пользовательские настройки меняют границу доверия:
469
120
 
470
- | Раздел | Методы |
121
+ | Настройка | Последствие |
471
122
  |---|---|
472
- | `itd.auth` | вход, регистрация, OTP, пароли, сессии, OAuth-ссылки |
473
- | `itd.users` | профили, подписки, блокировки, приватность, значки |
474
- | `itd.posts` | лента, публикация, реакции, репосты, опросы, комментарии к постам |
475
- | `itd.comments` | ответы, редактирование, реакции |
476
- | `itd.notifications` | список, счётчик, отметки о прочтении, настройки |
477
- | `itd.files` | загрузка медиа |
478
- | `itd.hashtags` · `itd.search` | хэштеги, трендовые, глобальный поиск |
479
- | `itd.reports` · `itd.verification` | жалобы, заявка на верификацию |
480
- | `itd.subscription` · `itd.platform` | подписка, способы оплаты, анонсы, статус сервисов |
481
- | `itd.realtime()` | поток уведомлений |
482
- | `itd.use()` | плагины: обёртки вокруг запроса и ответа |
483
- | `itd.request()` | произвольный запрос, если метода ещё нет |
484
- | `ItdAccounts` | несколько аккаунтов с общим хранилищем сессий |
485
-
486
- Метода не хватает или ответ разошёлся с документацией — есть запасной путь:
487
-
488
- ```ts
489
- const raw = await itd.request({ method: 'GET', path: '/api/что-то', raw: true });
490
- ```
123
+ | `baseUrl` | становится основным API-хостом; на него идут авторизация, сессия, защищённые запросы и realtime |
124
+ | `fetch` | получает URL, заголовки и body всех запросов клиента; передавайте только доверенную реализацию |
125
+ | `proxyFetch(...)` | направляет запросы через указанный вами proxy, которому будут доступны соединения с API |
126
+ | `defineService({ auth: true })` | явно разрешает отправлять Bearer-токен на хост этого сервиса |
127
+ | `request({ baseUrl })` | внешний хост не получает Bearer автоматически; `skipAuth: false` явно разрешает его передачу |
491
128
 
492
- ---
129
+ Уязвимости следует отправлять приватно по
130
+ [политике безопасности](./.github/SECURITY.md).
493
131
 
494
- ## Совместимость
132
+ ## Известные ограничения платформы
495
133
 
496
- | Среда | Поддержка |
134
+ | Ограничение | Что учитывать |
497
135
  |---|---|
498
- | Node.js 18+ | полная, включая `itd-api/node` |
499
- | Bun, Deno | полная |
500
- | Браузер | всё, кроме файловой системы; нужен прокси из-за CORS |
501
- | React Native | полная; realtime автоматически переключается на опрос, если нет потокового чтения |
136
+ | CORS основного API | браузерному приложению нужен собственный серверный proxy; [подробнее](https://kiowdev.github.io/itd-api/integrations/#браузер-и-cors) |
137
+ | Подписчики, подписки и блокировки | сервер возвращает только первые 20 записей; [подробнее](https://kiowdev.github.io/itd-api/reference/users) |
138
+ | Посты пользователя | `posts.byUser()` возвращает стену, включая чужие публикации на ней; [подробнее](https://kiowdev.github.io/itd-api/reference/posts) |
139
+ | Rate limiting | лимиты различаются по endpoint, а сервер не сообщает время сброса окна; [настройка очереди](https://kiowdev.github.io/itd-api/configuration/#очередь-и-rate-limiting) |
502
140
 
503
- TypeScript 5.0+. Пакет собран в ESM и CommonJS, типы корректны во всех режимах
504
- резолвинга (проверено `publint` и `@arethetypeswrong/cli`).
141
+ Матрица известных маршрутов, wire-контрактов и статуса поддержки находится в
142
+ [справочнике endpoint](https://kiowdev.github.io/itd-api/reference/endpoints).
505
143
 
506
- ---
144
+ ## Проект
507
145
 
508
- ## Разработка
146
+ - [CI](https://github.com/KiowDev/itd-api/actions/workflows/ci.yml)
147
+ - [История релизов](https://github.com/KiowDev/itd-api/releases)
148
+ - [Как внести вклад](./.github/CONTRIBUTING.md)
149
+ - [Политика безопасности](./.github/SECURITY.md)
150
+ - [MIT License](./LICENSE) и [NOTICE](./NOTICE)
509
151
 
510
- ```bash
511
- npm install
512
- npm test # 611 тестов
513
- npm run test:all # вместе с пакетами workspace
514
- npm run typecheck
515
- npm run lint
516
- npm run build
517
- npm run check:pack # publint + attw
518
- npm run docs # сайт документации из TSDoc
519
- ```
520
-
521
- Тесты не обращаются к сети: `fetch` подменяется через опцию конфигурации.
522
-
523
- ---
152
+ Публикация `itd-api@0.1.0` содержит проверяемое
153
+ [npm provenance](https://registry.npmjs.org/-/npm/v1/attestations/itd-api@0.1.0).
524
154
 
525
155
  ## Лицензия
526
156
 
527
- MIT. Библиотека не связана с итд.com и разработана независимо.
528
-
529
- Сторонний код, включённый в сборку, перечислен в [NOTICE](./NOTICE).
157
+ MIT © Kiow. Проект использует независимо восстановленные сведения о публичном
158
+ интерфейсе платформы; товарные знаки и сама платформа принадлежат их владельцам.