itd-api 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -9
- package/dist/{chunk-JV75JWOX.js → chunk-CCRQI3ON.js} +218 -16
- package/dist/chunk-CCRQI3ON.js.map +1 -0
- package/dist/{chunk-XG43KEYF.cjs → chunk-K7NBFQEE.cjs} +218 -15
- package/dist/chunk-K7NBFQEE.cjs.map +1 -0
- package/dist/{index-olL_q_yu.d.cts → index-CDGXKy8r.d.cts} +218 -16
- package/dist/{index-olL_q_yu.d.ts → index-CDGXKy8r.d.ts} +218 -16
- package/dist/index.cjs +88 -84
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node.cjs +87 -83
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/package.json +8 -3
- package/dist/chunk-JV75JWOX.js.map +0 -1
- package/dist/chunk-XG43KEYF.cjs.map +0 -1
|
@@ -579,6 +579,24 @@ var AttachmentType = Object.freeze({
|
|
|
579
579
|
/** Голосовые комментарии: `audio/ogg`, с полем `duration`. */
|
|
580
580
|
Audio: "audio"
|
|
581
581
|
});
|
|
582
|
+
var SpanType = Object.freeze({
|
|
583
|
+
/** Хэштег. Название без решётки лежит в `tag`. */
|
|
584
|
+
Hashtag: "hashtag",
|
|
585
|
+
/** Упоминание. Имя пользователя лежит в `tag`. */
|
|
586
|
+
Mention: "mention",
|
|
587
|
+
/** Ссылка. Адрес лежит в `url`, а не в `tag`. */
|
|
588
|
+
Link: "link",
|
|
589
|
+
Bold: "bold",
|
|
590
|
+
Italic: "italic",
|
|
591
|
+
Underline: "underline",
|
|
592
|
+
/** Зачёркнутый. */
|
|
593
|
+
Strike: "strike",
|
|
594
|
+
/** Спойлер: текст скрыт до нажатия. */
|
|
595
|
+
Spoiler: "spoiler",
|
|
596
|
+
/** Моноширинный. */
|
|
597
|
+
Monospace: "monospace",
|
|
598
|
+
Quote: "quote"
|
|
599
|
+
});
|
|
582
600
|
var ReportTargetType = Object.freeze({
|
|
583
601
|
Post: "post",
|
|
584
602
|
Comment: "comment",
|
|
@@ -1556,7 +1574,7 @@ var AuthManager = class {
|
|
|
1556
1574
|
}
|
|
1557
1575
|
if (credentials.turnstileToken) return credentials.turnstileToken;
|
|
1558
1576
|
throw new ItdConfigError(
|
|
1559
|
-
"\u0412\u0445\u043E\u0434 \u043F\u043E email \u0438 \u043F\u0430\u0440\u043E\u043B\u044E \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0442\u043E\u043A\u0435\u043D \u043A\u0430\u043F\u0447\u0438 Cloudflare Turnstile: \u0431\u0435\u0437 \u043D\u0435\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 422. \u041F\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 auth.getTurnstileToken (\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u0441\u0432\u0435\u0436\u0435\u0433\u043E \u0442\u043E\u043A\u0435\u043D\u0430) \u043B\u0438\u0431\u043E \u0440\u0430\u0437\u043E\u0432\u044B\u0439 auth.turnstileToken. \u041A\u043B\u044E\u0447 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u2014 TURNSTILE_SITE_KEY."
|
|
1577
|
+
"\u0412\u0445\u043E\u0434 \u043F\u043E email \u0438 \u043F\u0430\u0440\u043E\u043B\u044E \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0442\u043E\u043A\u0435\u043D \u043A\u0430\u043F\u0447\u0438 Cloudflare Turnstile: \u0431\u0435\u0437 \u043D\u0435\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 422. \u041F\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 auth.getTurnstileToken (\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u0441\u0432\u0435\u0436\u0435\u0433\u043E \u0442\u043E\u043A\u0435\u043D\u0430) \u043B\u0438\u0431\u043E \u0440\u0430\u0437\u043E\u0432\u044B\u0439 auth.turnstileToken. \u041A\u043B\u044E\u0447 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u2014 TURNSTILE_SITE_KEY. \u0412 Node \u0442\u043E\u043A\u0435\u043D \u0443\u043C\u0435\u0435\u0442 \u0434\u043E\u0431\u044B\u0432\u0430\u0442\u044C \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u044B\u0439 \u043F\u0430\u043A\u0435\u0442: npm i itd-api-turnstile, \u0437\u0430\u0442\u0435\u043C getTurnstileToken: createTurnstileSolver()."
|
|
1560
1578
|
);
|
|
1561
1579
|
}
|
|
1562
1580
|
async #performSignIn(credentials) {
|
|
@@ -1698,7 +1716,7 @@ function normalizeBaseUrl(baseUrl) {
|
|
|
1698
1716
|
// src/core/config.ts
|
|
1699
1717
|
var DEFAULT_BASE_URL = "https://xn--d1ah4a.com";
|
|
1700
1718
|
var DEFAULT_TIMEOUT = 3e4;
|
|
1701
|
-
var LIBRARY_VERSION = "0.0.
|
|
1719
|
+
var LIBRARY_VERSION = "0.0.6";
|
|
1702
1720
|
var DEFAULT_USER_AGENT = `Mozilla/5.0 (compatible; itd-api/${LIBRARY_VERSION}; +https://github.com/KiowDev/itd-api)`;
|
|
1703
1721
|
var DEFAULT_RATE_LIMIT_DELAYS = Object.freeze([1e3, 5e3, 3e4, 6e4, 9e4]);
|
|
1704
1722
|
function requirePositive(value, name) {
|
|
@@ -2093,6 +2111,7 @@ function createApiError(context) {
|
|
|
2093
2111
|
function sleep(ms) {
|
|
2094
2112
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2095
2113
|
}
|
|
2114
|
+
var EMPTY_KEYS = /* @__PURE__ */ new Set();
|
|
2096
2115
|
function setHeader(headers, name, value) {
|
|
2097
2116
|
try {
|
|
2098
2117
|
headers.set(name, value);
|
|
@@ -2146,6 +2165,7 @@ function createAbortBundle(userSignal, timeout) {
|
|
|
2146
2165
|
var HttpClient = class {
|
|
2147
2166
|
#config;
|
|
2148
2167
|
#collaborators;
|
|
2168
|
+
#plugins;
|
|
2149
2169
|
constructor(config, collaborators = {}) {
|
|
2150
2170
|
this.#config = config;
|
|
2151
2171
|
this.#collaborators = collaborators;
|
|
@@ -2154,6 +2174,19 @@ var HttpClient = class {
|
|
|
2154
2174
|
get baseUrl() {
|
|
2155
2175
|
return this.#config.baseUrl;
|
|
2156
2176
|
}
|
|
2177
|
+
/**
|
|
2178
|
+
* Имена опций запроса, заявленные плагинами.
|
|
2179
|
+
*
|
|
2180
|
+
* Читается ресурсами: они переносят в транспорт только известные поля, а чужие,
|
|
2181
|
+
* если их никто не заявил, отсеивают.
|
|
2182
|
+
*/
|
|
2183
|
+
get pluginOptionKeys() {
|
|
2184
|
+
return this.#plugins?.optionKeys ?? EMPTY_KEYS;
|
|
2185
|
+
}
|
|
2186
|
+
/** Подключает список плагинов. Реестр общий с клиентом и пополняется через `itd.use()`. */
|
|
2187
|
+
usePlugins(plugins) {
|
|
2188
|
+
this.#plugins = plugins;
|
|
2189
|
+
}
|
|
2157
2190
|
/**
|
|
2158
2191
|
* Подключает недостающие части конвейера.
|
|
2159
2192
|
*
|
|
@@ -2173,10 +2206,22 @@ var HttpClient = class {
|
|
|
2173
2206
|
* @throws {ItdNetworkError} если запрос не дошёл до сервера
|
|
2174
2207
|
*/
|
|
2175
2208
|
async request(options) {
|
|
2176
|
-
const task = () => this.#
|
|
2209
|
+
const task = () => this.#withPlugins(options);
|
|
2177
2210
|
if (!this.#collaborators.schedule || options.skipQueue) return task();
|
|
2178
2211
|
return this.#collaborators.schedule(task);
|
|
2179
2212
|
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Прогоняет запрос через обёртки плагинов.
|
|
2215
|
+
*
|
|
2216
|
+
* Цепочка стоит **снаружи повторов и внутри очереди**: плагин должен увидеть запрос
|
|
2217
|
+
* и ответ по одному разу, независимо от того, сколько попыток понадобилось, — иначе,
|
|
2218
|
+
* например, текст поста зашифруется повторно на второй попытке.
|
|
2219
|
+
*/
|
|
2220
|
+
#withPlugins(options) {
|
|
2221
|
+
const plugins = this.#plugins;
|
|
2222
|
+
if (!plugins || plugins.size === 0) return this.#withRetries(options);
|
|
2223
|
+
return plugins.run(options, (request) => this.#withRetries(request));
|
|
2224
|
+
}
|
|
2180
2225
|
async #withRetries(options) {
|
|
2181
2226
|
const method = options.method.toUpperCase();
|
|
2182
2227
|
for (let attempt = 1; ; attempt++) {
|
|
@@ -2322,6 +2367,97 @@ var HttpClient = class {
|
|
|
2322
2367
|
}
|
|
2323
2368
|
};
|
|
2324
2369
|
|
|
2370
|
+
// src/core/plugins.ts
|
|
2371
|
+
var NO_KEYS = /* @__PURE__ */ new Set();
|
|
2372
|
+
var RESERVED_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
2373
|
+
"signal",
|
|
2374
|
+
"timeout",
|
|
2375
|
+
"headers",
|
|
2376
|
+
"retry",
|
|
2377
|
+
"method",
|
|
2378
|
+
"path",
|
|
2379
|
+
"query",
|
|
2380
|
+
"body",
|
|
2381
|
+
"skipAuth",
|
|
2382
|
+
"skipAuthRefresh",
|
|
2383
|
+
"skipQueue",
|
|
2384
|
+
"raw"
|
|
2385
|
+
]);
|
|
2386
|
+
var PluginRegistry = class {
|
|
2387
|
+
#transformers = [];
|
|
2388
|
+
#optionKeys = /* @__PURE__ */ new Set();
|
|
2389
|
+
#names = /* @__PURE__ */ new Set();
|
|
2390
|
+
/** Сколько обёрток подключено. Ноль означает, что запрос идёт прежним путём. */
|
|
2391
|
+
get size() {
|
|
2392
|
+
return this.#transformers.length;
|
|
2393
|
+
}
|
|
2394
|
+
/** Имена опций запроса, заявленные плагинами. */
|
|
2395
|
+
get optionKeys() {
|
|
2396
|
+
return this.#optionKeys.size === 0 ? NO_KEYS : this.#optionKeys;
|
|
2397
|
+
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Подключает плагин.
|
|
2400
|
+
*
|
|
2401
|
+
* @throws {ItdConfigError} если плагин задан неверно, уже подключён или заявил занятое
|
|
2402
|
+
* имя опции
|
|
2403
|
+
*/
|
|
2404
|
+
add(plugin, context) {
|
|
2405
|
+
if (typeof plugin?.install !== "function") {
|
|
2406
|
+
throw new ItdConfigError("\u041F\u043B\u0430\u0433\u0438\u043D \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u043C \u0441 \u043C\u0435\u0442\u043E\u0434\u043E\u043C install()");
|
|
2407
|
+
}
|
|
2408
|
+
const name = plugin.name;
|
|
2409
|
+
if (typeof name !== "string" || name.trim() === "") {
|
|
2410
|
+
throw new ItdConfigError("\u0423 \u043F\u043B\u0430\u0433\u0438\u043D\u0430 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435\u043F\u0443\u0441\u0442\u043E\u0435 \u0438\u043C\u044F");
|
|
2411
|
+
}
|
|
2412
|
+
if (this.#names.has(name)) {
|
|
2413
|
+
throw new ItdConfigError(`\u041F\u043B\u0430\u0433\u0438\u043D \xAB${name}\xBB \u0443\u0436\u0435 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0451\u043D`);
|
|
2414
|
+
}
|
|
2415
|
+
const keys = plugin.optionKeys ?? [];
|
|
2416
|
+
for (const key of keys) {
|
|
2417
|
+
if (typeof key !== "string" || key.trim() === "") {
|
|
2418
|
+
throw new ItdConfigError(`\u041F\u043B\u0430\u0433\u0438\u043D \xAB${name}\xBB \u0437\u0430\u044F\u0432\u0438\u043B \u043F\u0443\u0441\u0442\u043E\u0435 \u0438\u043C\u044F \u043E\u043F\u0446\u0438\u0438`);
|
|
2419
|
+
}
|
|
2420
|
+
if (RESERVED_OPTION_KEYS.has(key)) {
|
|
2421
|
+
throw new ItdConfigError(
|
|
2422
|
+
`\u041F\u043B\u0430\u0433\u0438\u043D \xAB${name}\xBB \u0437\u0430\u044F\u0432\u0438\u043B \u043E\u043F\u0446\u0438\u044E \xAB${key}\xBB: \u044D\u0442\u043E \u043F\u043E\u043B\u0435 \u0437\u0430\u043F\u0440\u043E\u0441\u0430, \u0438\u043C\u044F \u0437\u0430\u043D\u044F\u0442\u043E. \u0417\u0430\u043D\u044F\u0442\u044B\u0435 \u0438\u043C\u0435\u043D\u0430: ${[...RESERVED_OPTION_KEYS].join(", ")}`
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
const before = this.#transformers.length;
|
|
2427
|
+
try {
|
|
2428
|
+
plugin.install({
|
|
2429
|
+
...context,
|
|
2430
|
+
use: (transformer) => {
|
|
2431
|
+
if (typeof transformer !== "function") {
|
|
2432
|
+
throw new ItdConfigError(`\u041F\u043B\u0430\u0433\u0438\u043D \xAB${name}\xBB \u043F\u0435\u0440\u0435\u0434\u0430\u043B \u0432 use() \u043D\u0435 \u0444\u0443\u043D\u043A\u0446\u0438\u044E`);
|
|
2433
|
+
}
|
|
2434
|
+
this.#transformers.push(transformer);
|
|
2435
|
+
}
|
|
2436
|
+
});
|
|
2437
|
+
} catch (error) {
|
|
2438
|
+
this.#transformers.length = before;
|
|
2439
|
+
throw error;
|
|
2440
|
+
}
|
|
2441
|
+
this.#names.add(name);
|
|
2442
|
+
for (const key of keys) this.#optionKeys.add(key);
|
|
2443
|
+
}
|
|
2444
|
+
/**
|
|
2445
|
+
* Прогоняет запрос через цепочку обёрток.
|
|
2446
|
+
*
|
|
2447
|
+
* Цепочка собирается на каждый запрос заново: плагин можно подключить в любой момент,
|
|
2448
|
+
* а обёрток единицы — экономить тут не на чем.
|
|
2449
|
+
*
|
|
2450
|
+
* @param execute настоящий запрос, вызывается самой внутренней обёрткой
|
|
2451
|
+
*/
|
|
2452
|
+
run(request, execute) {
|
|
2453
|
+
const chain = this.#transformers.reduceRight(
|
|
2454
|
+
(next, transformer) => (current) => transformer(current, next),
|
|
2455
|
+
execute
|
|
2456
|
+
);
|
|
2457
|
+
return chain(request);
|
|
2458
|
+
}
|
|
2459
|
+
};
|
|
2460
|
+
|
|
2325
2461
|
// src/core/rate-limit.ts
|
|
2326
2462
|
var RequestQueue = class {
|
|
2327
2463
|
#concurrency;
|
|
@@ -3242,15 +3378,31 @@ var BaseResource = class {
|
|
|
3242
3378
|
constructor(http) {
|
|
3243
3379
|
this.http = http;
|
|
3244
3380
|
}
|
|
3245
|
-
/**
|
|
3381
|
+
/**
|
|
3382
|
+
* Переносит общие поля опций запроса в параметры транспорта.
|
|
3383
|
+
*
|
|
3384
|
+
* Поля перечислены поимённо, а не скопированы целиком: параметры методов наследуют
|
|
3385
|
+
* {@link RequestOptions} и приносят с собой `limit`, `cursor` и прочее, чему в описании
|
|
3386
|
+
* запроса делать нечего. Исключение — опции, заявленные плагинами: их библиотека
|
|
3387
|
+
* не понимает, но обязана донести до обёрток нетронутыми.
|
|
3388
|
+
*/
|
|
3246
3389
|
requestOptions(options) {
|
|
3247
3390
|
if (!options) return {};
|
|
3248
|
-
|
|
3391
|
+
const result = {
|
|
3249
3392
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
3250
3393
|
...options.timeout !== void 0 ? { timeout: options.timeout } : {},
|
|
3251
3394
|
...options.headers !== void 0 ? { headers: options.headers } : {},
|
|
3252
3395
|
...options.retry !== void 0 ? { retry: options.retry } : {}
|
|
3253
3396
|
};
|
|
3397
|
+
const pluginKeys = this.http.pluginOptionKeys;
|
|
3398
|
+
if (pluginKeys.size === 0) return result;
|
|
3399
|
+
const source = options;
|
|
3400
|
+
const target = result;
|
|
3401
|
+
for (const key of pluginKeys) {
|
|
3402
|
+
const value = source[key];
|
|
3403
|
+
if (value !== void 0) target[key] = value;
|
|
3404
|
+
}
|
|
3405
|
+
return result;
|
|
3254
3406
|
}
|
|
3255
3407
|
/**
|
|
3256
3408
|
* Собирает перебор страниц.
|
|
@@ -4477,7 +4629,16 @@ var PostsResource = class extends BaseResource {
|
|
|
4477
4629
|
});
|
|
4478
4630
|
return pickArray(body, "posts");
|
|
4479
4631
|
}
|
|
4480
|
-
/**
|
|
4632
|
+
/**
|
|
4633
|
+
* Загружает страницу стены пользователя.
|
|
4634
|
+
*
|
|
4635
|
+
* Это **не только его собственные посты**: сюда попадают и записи, которые другие
|
|
4636
|
+
* оставили на его стене — у них `author` чужой, а `wallRecipient` указывает на владельца
|
|
4637
|
+
* стены. Поэтому число записей обычно больше, чем `postsCount` из профиля; чтобы
|
|
4638
|
+
* получить только авторские посты, отфильтруйте по `post.author.id`.
|
|
4639
|
+
*
|
|
4640
|
+
* Принимает и UUID, и имя пользователя.
|
|
4641
|
+
*/
|
|
4481
4642
|
async byUser(user, params = {}) {
|
|
4482
4643
|
const body = await this.http.request({
|
|
4483
4644
|
method: "GET",
|
|
@@ -4492,7 +4653,7 @@ var PostsResource = class extends BaseResource {
|
|
|
4492
4653
|
});
|
|
4493
4654
|
return readCursorPage(body, "posts");
|
|
4494
4655
|
}
|
|
4495
|
-
/** Перебирает
|
|
4656
|
+
/** Перебирает стену пользователя. Что именно в неё входит — см. {@link byUser}. */
|
|
4496
4657
|
iterateByUser(user, params = {}) {
|
|
4497
4658
|
const path = `/api/posts/user/${encodePathSegment(user, "user")}`;
|
|
4498
4659
|
return this.paginate(
|
|
@@ -4735,19 +4896,34 @@ var UsersResource = class extends BaseResource {
|
|
|
4735
4896
|
...this.requestOptions(options)
|
|
4736
4897
|
});
|
|
4737
4898
|
}
|
|
4738
|
-
/**
|
|
4899
|
+
/**
|
|
4900
|
+
* Загружает подписчиков пользователя.
|
|
4901
|
+
*
|
|
4902
|
+
* ⚠️ **Сервер этот список не листает.** Возвращаются первые 20 записей и только они:
|
|
4903
|
+
* параметр `page` игнорируется (любая страница отдаёт те же записи и `pagination.page: 1`),
|
|
4904
|
+
* `limit` больше 20 молча уменьшается, а `hasMore` всегда `false`. Последнее честно —
|
|
4905
|
+
* получить продолжение нечем.
|
|
4906
|
+
*
|
|
4907
|
+
* Числу `total` доверять тоже не стоит: оно расходится с `followersCount` из профиля —
|
|
4908
|
+
* на проверенных аккаунтах занижено примерно на 1–4%.
|
|
4909
|
+
*/
|
|
4739
4910
|
followers(user, params = {}) {
|
|
4740
4911
|
return this.#userPage(`/api/users/${encodePathSegment(user, "user")}/followers`, params);
|
|
4741
4912
|
}
|
|
4742
|
-
/**
|
|
4913
|
+
/**
|
|
4914
|
+
* Перебирает подписчиков.
|
|
4915
|
+
*
|
|
4916
|
+
* ⚠️ Перебор закончится после первых 20 записей: сервер список не листает —
|
|
4917
|
+
* см. {@link followers}. Метод оставлен на случай, если пагинацию починят.
|
|
4918
|
+
*/
|
|
4743
4919
|
iterateFollowers(user, params = {}) {
|
|
4744
4920
|
return this.#userPaginator(`/api/users/${encodePathSegment(user, "user")}/followers`, params);
|
|
4745
4921
|
}
|
|
4746
|
-
/** Загружает
|
|
4922
|
+
/** Загружает подписки пользователя. Ограничения те же, что у {@link followers}. */
|
|
4747
4923
|
following(user, params = {}) {
|
|
4748
4924
|
return this.#userPage(`/api/users/${encodePathSegment(user, "user")}/following`, params);
|
|
4749
4925
|
}
|
|
4750
|
-
/** Перебирает подписки. */
|
|
4926
|
+
/** Перебирает подписки. Закончится после первых 20 записей — см. {@link followers}. */
|
|
4751
4927
|
iterateFollowing(user, params = {}) {
|
|
4752
4928
|
return this.#userPaginator(`/api/users/${encodePathSegment(user, "user")}/following`, params);
|
|
4753
4929
|
}
|
|
@@ -4787,11 +4963,11 @@ var UsersResource = class extends BaseResource {
|
|
|
4787
4963
|
...this.requestOptions(options)
|
|
4788
4964
|
});
|
|
4789
4965
|
}
|
|
4790
|
-
/** Загружает
|
|
4966
|
+
/** Загружает заблокированных пользователей. Ограничения те же, что у {@link followers}. */
|
|
4791
4967
|
blocked(params = {}) {
|
|
4792
4968
|
return this.#userPage("/api/users/me/blocked", params);
|
|
4793
4969
|
}
|
|
4794
|
-
/** Перебирает
|
|
4970
|
+
/** Перебирает заблокированных. Закончится после первых 20 записей — см. {@link followers}. */
|
|
4795
4971
|
iterateBlocked(params = {}) {
|
|
4796
4972
|
return this.#userPaginator("/api/users/me/blocked", params);
|
|
4797
4973
|
}
|
|
@@ -4852,6 +5028,9 @@ var UsersResource = class extends BaseResource {
|
|
|
4852
5028
|
* Имена полей перечислены с запасом: списки подписчиков и заблокированных приходят
|
|
4853
5029
|
* под `users`, но альтернативное имя ничего не стоит и спасает, если эндпоинт назовёт
|
|
4854
5030
|
* список по-своему.
|
|
5031
|
+
*
|
|
5032
|
+
* `page` уходит в запрос, хотя сервер его сейчас не читает (см. {@link followers}):
|
|
5033
|
+
* когда пагинацию починят, работать начнёт само.
|
|
4855
5034
|
*/
|
|
4856
5035
|
async #loadUserPage(path, params, state) {
|
|
4857
5036
|
const body = await this.http.request({
|
|
@@ -4884,6 +5063,7 @@ var ItdClient = class {
|
|
|
4884
5063
|
#authManager;
|
|
4885
5064
|
#jar;
|
|
4886
5065
|
#queue;
|
|
5066
|
+
#plugins = new PluginRegistry();
|
|
4887
5067
|
/** Авторизация, сессии и пароли. */
|
|
4888
5068
|
auth;
|
|
4889
5069
|
/** Профили, подписки, блокировки, приватность. */
|
|
@@ -4920,6 +5100,7 @@ var ItdClient = class {
|
|
|
4920
5100
|
this.#http = new HttpClient(this.#config);
|
|
4921
5101
|
this.#authManager = new AuthManager(this.#config, this.#http, this.#jar);
|
|
4922
5102
|
this.#queue = this.#config.rateLimit ? new RequestQueue(this.#config.rateLimit) : void 0;
|
|
5103
|
+
this.#http.usePlugins(this.#plugins);
|
|
4923
5104
|
this.#http.setCollaborators({
|
|
4924
5105
|
getAuthHeaders: () => this.#authManager.getAuthHeaders(),
|
|
4925
5106
|
getDeviceId: () => this.#authManager.getDeviceId(),
|
|
@@ -4965,6 +5146,27 @@ var ItdClient = class {
|
|
|
4965
5146
|
request(options) {
|
|
4966
5147
|
return this.#http.request(options);
|
|
4967
5148
|
}
|
|
5149
|
+
/**
|
|
5150
|
+
* Подключает плагин.
|
|
5151
|
+
*
|
|
5152
|
+
* Плагин работает на уровне транспорта: видит запрос до отправки и разобранный ответ,
|
|
5153
|
+
* поэтому одна обёртка охватывает сразу все методы клиента. Подключать можно в любой
|
|
5154
|
+
* момент, но обычно это делают сразу после создания клиента.
|
|
5155
|
+
*
|
|
5156
|
+
* @throws {ItdConfigError} если плагин задан неверно или уже подключён
|
|
5157
|
+
*
|
|
5158
|
+
* @example
|
|
5159
|
+
* ```ts
|
|
5160
|
+
* import { crypt } from 'itd-api-crypto';
|
|
5161
|
+
*
|
|
5162
|
+
* itd.use(crypt());
|
|
5163
|
+
* await itd.posts.create({ content: 'секрет' }, { encrypt: 'invis' });
|
|
5164
|
+
* ```
|
|
5165
|
+
*/
|
|
5166
|
+
use(plugin) {
|
|
5167
|
+
this.#plugins.add(plugin, { baseUrl: this.#config.baseUrl, logger: this.#config.logger });
|
|
5168
|
+
return this;
|
|
5169
|
+
}
|
|
4968
5170
|
/**
|
|
4969
5171
|
* Подписывается на события авторизации.
|
|
4970
5172
|
*
|
|
@@ -5244,6 +5446,7 @@ exports.ReportTargetType = ReportTargetType;
|
|
|
5244
5446
|
exports.RuntimeMode = RuntimeMode;
|
|
5245
5447
|
exports.STREAM_PATH = STREAM_PATH;
|
|
5246
5448
|
exports.SignInStatus = SignInStatus;
|
|
5449
|
+
exports.SpanType = SpanType;
|
|
5247
5450
|
exports.TURNSTILE_SITE_KEY = TURNSTILE_SITE_KEY;
|
|
5248
5451
|
exports.UnauthorizedStreamError = UnauthorizedStreamError;
|
|
5249
5452
|
exports.VIDEO_MIME_TYPES = VIDEO_MIME_TYPES;
|
|
@@ -5274,5 +5477,5 @@ exports.readUnreadCountEvent = readUnreadCountEvent;
|
|
|
5274
5477
|
exports.report = report;
|
|
5275
5478
|
exports.resolveNotificationUrl = resolveNotificationUrl;
|
|
5276
5479
|
exports.toDate = toDate;
|
|
5277
|
-
//# sourceMappingURL=chunk-
|
|
5278
|
-
//# sourceMappingURL=chunk-
|
|
5480
|
+
//# sourceMappingURL=chunk-K7NBFQEE.cjs.map
|
|
5481
|
+
//# sourceMappingURL=chunk-K7NBFQEE.cjs.map
|