itd-sdk-js 1.0.5 → 1.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/API_REFERENCE.md +12 -3
- package/README.md +6 -0
- package/package.json +1 -1
- package/src/client.js +13 -1
- package/src/files.js +4 -2
- package/src/posts.js +17 -10
- package/src/users.js +4 -3
package/API_REFERENCE.md
CHANGED
|
@@ -60,15 +60,18 @@ const client = new ITDClient({
|
|
|
60
60
|
baseUrl: 'https://xn--d1ah4a.com',
|
|
61
61
|
userAgent: '...',
|
|
62
62
|
projectRoot: process.cwd(), // корень проекта (по умолчанию process.cwd())
|
|
63
|
-
// либо явные пути:
|
|
64
63
|
// envPath: '/path/to/project/.env',
|
|
65
64
|
// cookiesPath: '/path/to/project/.cookies',
|
|
65
|
+
requestTimeout: 60000, // таймаут обычных запросов, мс (по умолчанию 60 с)
|
|
66
|
+
uploadTimeout: 120000, // таймаут загрузки файлов и создания поста, мс (по умолчанию 120 с)
|
|
66
67
|
});
|
|
67
68
|
client.setAccessToken(process.env.ITD_ACCESS_TOKEN);
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
- `projectRoot` — директория, в которой ищутся `.env` и `.cookies` (по умолчанию `process.cwd()`).
|
|
71
72
|
- `envPath` / `cookiesPath` — при указании переопределяют пути, собранные из `projectRoot`.
|
|
73
|
+
- `requestTimeout` — таймаут обычных запросов в мс (по умолчанию 60000). Предотвращает бесконечное ожидание при «тяжёлой» сети.
|
|
74
|
+
- `uploadTimeout` — таймаут для загрузки файлов и создания поста в мс (по умолчанию 120000). Используется в `uploadFile`, `createPost`, `createWallPost`.
|
|
72
75
|
|
|
73
76
|
### Автоматическое обновление (Refresh Token)
|
|
74
77
|
|
|
@@ -112,6 +115,10 @@ const post = await client.createPost('Текст поста', 'image.jpg');
|
|
|
112
115
|
|
|
113
116
|
Создает новый пост. При указании `imagePath` файл предварительно загружается через `/api/files/upload`, после чего ID файла прикрепляется к посту через поле `attachmentIds`.
|
|
114
117
|
|
|
118
|
+
- **Возвращает:** объект поста при успехе; **`null`** при любой ошибке (сеть, 5xx, 429, не удалось загрузить файл, неверный ответ). Всегда проверяйте результат на `null`.
|
|
119
|
+
- **Таймаут:** для загрузки файла и создания поста используется `uploadTimeout` (по умолчанию 120 с), чтобы запрос не зависал при 504 или медленной сети.
|
|
120
|
+
- **Ретраи:** при 5xx/429 или «API вернул null» рекомендуется повторять запрос в приложении (например, до 3–8 попыток с экспоненциальной задержкой). Встроенных ретраев в SDK нет.
|
|
121
|
+
|
|
115
122
|
**Важно:** API использует поле `attachmentIds` (массив ID файлов), а не `attachments`. SDK автоматически использует правильное поле.
|
|
116
123
|
|
|
117
124
|
- **Параметры**: `text` (string), `imagePath` (string, опционально).
|
|
@@ -120,6 +127,8 @@ const post = await client.createPost('Текст поста', 'image.jpg');
|
|
|
120
127
|
|
|
121
128
|
Создает пост **на стене другого пользователя** (wall post).
|
|
122
129
|
|
|
130
|
+
- **Возвращает:** объект поста при успехе; **`null`** при любой ошибке. Проверяйте результат на `null`; при 5xx/429 рекомендуется ретраи в приложении.
|
|
131
|
+
- **Таймаут:** используется `uploadTimeout` (по умолчанию 120 с).
|
|
123
132
|
- Делается через `POST /api/posts` с телом `{ content, wallRecipientId, attachmentIds? }`.
|
|
124
133
|
- `wallRecipientId` — это **ID пользователя-получателя**, поэтому метод сначала запрашивает профиль через `getUserProfile(username)` и берет `profile.id`.
|
|
125
134
|
- При указании `imagePath` файл загружается и прикрепляется через `attachmentIds`.
|
|
@@ -216,14 +225,14 @@ const post = await client.createPost('Текст поста', 'image.jpg');
|
|
|
216
225
|
- `search(query, userLimit?, hashtagLimit?)` — универсальный поиск пользователей и хэштегов. Возвращает `{ users: [], hashtags: [] }`.
|
|
217
226
|
- `searchUsers(query, limit?)` — поиск только пользователей.
|
|
218
227
|
- `searchHashtags(query, limit?)` — поиск только хэштегов.
|
|
219
|
-
- `getTopClans()` — рейтинг кланов по количеству участников.
|
|
228
|
+
- `getTopClans()` — рейтинг кланов по количеству участников. **Возвращает массив** `Array<{ avatar, memberCount }>` или **`null`** при ошибке (не объект с полем `clans`).
|
|
220
229
|
- `getWhoToFollow()` — рекомендованные пользователи.
|
|
221
230
|
- `getTrendingHashtags(limit)` — список популярных тегов.
|
|
222
231
|
- `getPostsByHashtag(tagName, limit, cursor)` — поиск постов по тегу. Возвращает `{ posts: [], hashtag: {}, pagination: {} }`.
|
|
223
232
|
|
|
224
233
|
### Файлы и репорты
|
|
225
234
|
|
|
226
|
-
- `uploadFile(filePath)` — загрузка файла через `/api/files/upload`. Возвращает `{ id, url, filename, mimeType, size }
|
|
235
|
+
- `uploadFile(filePath)` — загрузка файла через `/api/files/upload`. Возвращает `{ id, url, filename, mimeType, size }` или **`null`** при ошибке. Таймаут — `uploadTimeout` (по умолчанию 120 с). Используется автоматически при создании поста с изображением.
|
|
227
236
|
- `report(targetType, targetId, reason?, description?)` — отправка репорта. `targetType`: `"post"`, `"comment"`, `"user"`. Возвращает `{ id, createdAt }`.
|
|
228
237
|
- `reportPost(postId, reason?, description?)` — репорт поста.
|
|
229
238
|
- `reportComment(commentId, reason?, description?)` — репорт комментария.
|
package/README.md
CHANGED
|
@@ -91,6 +91,12 @@ console.log(`${stats.likes} лайков, ${stats.views} просмотров`);
|
|
|
91
91
|
await client.createWallPost('ITD_API', 'Тестовый пост на чужой стене 🦫');
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
## Рекомендации при создании постов
|
|
95
|
+
|
|
96
|
+
- **createPost** и **createWallPost** при любой ошибке возвращают **`null`** — всегда проверяйте результат.
|
|
97
|
+
- Для загрузки файла и создания поста используется таймаут **120 с** по умолчанию (`uploadTimeout` в опциях клиента), чтобы запрос не зависал при 504 или медленной сети.
|
|
98
|
+
- При 5xx/429 или «API вернул null» рекомендуется повторять запрос в приложении (ретраи с задержкой). Подробнее — в [API_REFERENCE.md](API_REFERENCE.md).
|
|
99
|
+
|
|
94
100
|
## Важно
|
|
95
101
|
|
|
96
102
|
Это неофициальный проект. Если разработчики сайта изменят структуру API или введут новую защиту, методы могут временно перестать работать. Используйте аккуратно и не спамьте запросами.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itd-sdk-js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Unofficial SDK for итд.com - Node.js library for working with API. Automatic token refresh, session management, and convenient methods for posts, comments, users, and notifications.",
|
|
5
5
|
"main": "src/client.js",
|
|
6
6
|
"type": "module",
|
package/src/client.js
CHANGED
|
@@ -32,9 +32,11 @@ export class ITDClient {
|
|
|
32
32
|
* @param {string} [options.projectRoot] - Корень проекта (по умолчанию process.cwd()); .env и .cookies ищутся здесь
|
|
33
33
|
* @param {string} [options.envPath] - Полный путь к .env (переопределяет projectRoot для .env)
|
|
34
34
|
* @param {string} [options.cookiesPath] - Полный путь к .cookies (переопределяет projectRoot для .cookies)
|
|
35
|
+
* @param {number} [options.requestTimeout] - Таймаут обычных запросов в мс (по умолчанию 60000)
|
|
36
|
+
* @param {number} [options.uploadTimeout] - Таймаут загрузки файлов и создания поста в мс (по умолчанию 120000)
|
|
35
37
|
*/
|
|
36
38
|
constructor(baseUrlOrOptions = null, userAgent = null) {
|
|
37
|
-
let baseUrl, projectRoot, envPath, cookiesPath;
|
|
39
|
+
let baseUrl, projectRoot, envPath, cookiesPath, requestTimeout, uploadTimeout;
|
|
38
40
|
|
|
39
41
|
if (baseUrlOrOptions && typeof baseUrlOrOptions === 'object' && !(baseUrlOrOptions instanceof URL)) {
|
|
40
42
|
const opts = baseUrlOrOptions;
|
|
@@ -43,11 +45,15 @@ export class ITDClient {
|
|
|
43
45
|
projectRoot = opts.projectRoot ?? process.cwd();
|
|
44
46
|
envPath = opts.envPath ?? path.join(projectRoot, '.env');
|
|
45
47
|
cookiesPath = opts.cookiesPath ?? path.join(projectRoot, '.cookies');
|
|
48
|
+
requestTimeout = opts.requestTimeout ?? 60000;
|
|
49
|
+
uploadTimeout = opts.uploadTimeout ?? 120000;
|
|
46
50
|
} else {
|
|
47
51
|
projectRoot = process.cwd();
|
|
48
52
|
baseUrl = baseUrlOrOptions || process.env.ITD_BASE_URL || 'https://xn--d1ah4a.com';
|
|
49
53
|
envPath = path.join(projectRoot, '.env');
|
|
50
54
|
cookiesPath = path.join(projectRoot, '.cookies');
|
|
55
|
+
requestTimeout = 60000;
|
|
56
|
+
uploadTimeout = 120000;
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
// Используем реальный домен (IDN: итд.com = xn--d1ah4a.com)
|
|
@@ -59,6 +65,11 @@ export class ITDClient {
|
|
|
59
65
|
this.envPath = envPath;
|
|
60
66
|
this.cookiesPath = cookiesPath;
|
|
61
67
|
|
|
68
|
+
/** Таймаут обычных запросов (мс). Для загрузки и создания поста используется uploadTimeout. */
|
|
69
|
+
this.requestTimeout = requestTimeout;
|
|
70
|
+
/** Таймаут загрузки файлов и создания поста (мс), чтобы не зависать при 504/медленной сети. */
|
|
71
|
+
this.uploadTimeout = uploadTimeout;
|
|
72
|
+
|
|
62
73
|
/** @type {string|null} */
|
|
63
74
|
this.accessToken = null;
|
|
64
75
|
|
|
@@ -78,6 +89,7 @@ export class ITDClient {
|
|
|
78
89
|
// Создание axios instance + cookie jar
|
|
79
90
|
const axiosConfig = {
|
|
80
91
|
baseURL: this.baseUrl,
|
|
92
|
+
timeout: requestTimeout,
|
|
81
93
|
withCredentials: true,
|
|
82
94
|
jar: this.cookieJar,
|
|
83
95
|
headers: {
|
package/src/files.js
CHANGED
|
@@ -11,8 +11,9 @@ export class FilesManager {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Загружает файл (изображение) на
|
|
15
|
-
*
|
|
14
|
+
* Загружает файл (изображение) на сервер.
|
|
15
|
+
* Таймаут — client.uploadTimeout (по умолчанию 120 с). При ошибке возвращает null.
|
|
16
|
+
*
|
|
16
17
|
* @param {string} filePath - Путь к файлу
|
|
17
18
|
* @returns {Promise<Object|null>} { id, url, filename, mimeType, size } или null при ошибке
|
|
18
19
|
*/
|
|
@@ -36,6 +37,7 @@ export class FilesManager {
|
|
|
36
37
|
formData.append('file', fs.createReadStream(filePath));
|
|
37
38
|
|
|
38
39
|
const response = await this.axios.post(uploadUrl, formData, {
|
|
40
|
+
timeout: this.client.uploadTimeout ?? 120000,
|
|
39
41
|
headers: {
|
|
40
42
|
...formData.getHeaders(),
|
|
41
43
|
}
|
package/src/posts.js
CHANGED
|
@@ -16,8 +16,10 @@ export class PostsManager {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Создает новый
|
|
20
|
-
*
|
|
19
|
+
* Создает новый пост.
|
|
20
|
+
* При любой ошибке (сеть, 5xx, 429, не удалось загрузить файл) возвращает null.
|
|
21
|
+
* Таймаут загрузки и создания — client.uploadTimeout (по умолчанию 120 с).
|
|
22
|
+
*
|
|
21
23
|
* @param {string} text - Текст поста
|
|
22
24
|
* @param {string|null} imagePath - Путь к изображению (опционально)
|
|
23
25
|
* @returns {Promise<Object|null>} Данные созданного поста или null при ошибке
|
|
@@ -51,9 +53,11 @@ export class PostsManager {
|
|
|
51
53
|
postData.attachmentIds = [uploadedFile.id];
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
// Создаем пост (с изображением или без)
|
|
55
|
-
const response = await this.axios.post(postUrl, postData
|
|
56
|
-
|
|
56
|
+
// Создаем пост (с изображением или без); увеличенный таймаут для тяжёлых запросов
|
|
57
|
+
const response = await this.axios.post(postUrl, postData, {
|
|
58
|
+
timeout: this.client.uploadTimeout ?? 120000,
|
|
59
|
+
});
|
|
60
|
+
|
|
57
61
|
if (response.status === 200 || response.status === 201) {
|
|
58
62
|
return response.data;
|
|
59
63
|
} else {
|
|
@@ -71,8 +75,9 @@ export class PostsManager {
|
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
/**
|
|
74
|
-
* Создает пост на стене другого пользователя (wall post)
|
|
75
|
-
*
|
|
78
|
+
* Создает пост на стене другого пользователя (wall post).
|
|
79
|
+
* При любой ошибке возвращает null. Таймаут — client.uploadTimeout (по умолчанию 120 с).
|
|
80
|
+
*
|
|
76
81
|
* @param {string} username - Имя пользователя, на чью стену нужно написать
|
|
77
82
|
* @param {string} text - Текст поста
|
|
78
83
|
* @param {string|null} imagePath - Путь к изображению (опционально)
|
|
@@ -117,9 +122,11 @@ export class PostsManager {
|
|
|
117
122
|
postData.attachmentIds = [uploadedFile.id];
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
// Создаем пост на
|
|
121
|
-
const response = await this.axios.post(postUrl, postData
|
|
122
|
-
|
|
125
|
+
// Создаем пост на стене; увеличенный таймаут для тяжёлых запросов
|
|
126
|
+
const response = await this.axios.post(postUrl, postData, {
|
|
127
|
+
timeout: this.client.uploadTimeout ?? 120000,
|
|
128
|
+
});
|
|
129
|
+
|
|
123
130
|
if (response.status === 200 || response.status === 201) {
|
|
124
131
|
return response.data;
|
|
125
132
|
} else {
|
package/src/users.js
CHANGED
|
@@ -295,9 +295,10 @@ export class UsersManager {
|
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
/**
|
|
298
|
-
* Получает топ кланов по количеству
|
|
299
|
-
*
|
|
300
|
-
*
|
|
298
|
+
* Получает топ кланов по количеству участников.
|
|
299
|
+
* Возвращает массив (Array), не объект с полем clans.
|
|
300
|
+
*
|
|
301
|
+
* @returns {Promise<Array|null>} Массив кланов [{ avatar, memberCount }, ...] или null при ошибке
|
|
301
302
|
*/
|
|
302
303
|
async getTopClans() {
|
|
303
304
|
try {
|