ichime-ts-api-client 1.0.0 → 1.0.1

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 (2) hide show
  1. package/README.md +371 -29
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ichime-ts-api-client
2
2
 
3
- TypeScript API client для работы с сайтом [smotret-anime.com](https://smotret-anime.com).
3
+ TypeScript API client для работы с сайтом **anime365**
4
4
 
5
5
  ## Установка
6
6
 
@@ -8,59 +8,401 @@ TypeScript API client для работы с сайтом [smotret-anime.com](ht
8
8
  pnpm add ichime-ts-api-client
9
9
  ```
10
10
 
11
- ## Использование
11
+ ## Быстрый старт
12
12
 
13
13
  ```typescript
14
- import { ApiClient } from "ichime-ts-api-client";
14
+ import { HttpSession, ApiClient, WebClient } from "ichime-ts-api-client";
15
15
 
16
- const client = new ApiClient();
16
+ // Создаем сессию
17
+ const session = new HttpSession("https://smotret-anime.com");
17
18
 
18
- // Получить список серий
19
- const series = await client.listSeries({
20
- query: "naruto",
21
- limit: 10,
22
- offset: 0,
23
- });
19
+ // Используем публичный API
20
+ const apiClient = new ApiClient(session);
21
+ const series = await apiClient.listSeries({ query: "naruto" });
24
22
 
25
- console.log(series);
23
+ // Или веб-клиент с авторизацией
24
+ const webClient = new WebClient(session);
25
+ await webClient.login("username", "password");
26
+ const profile = await webClient.getProfile();
26
27
  ```
27
28
 
28
- ## API
29
+ ## Архитектура
30
+
31
+ Библиотека состоит из трех основных компонентов:
29
32
 
30
- ### ApiClient
33
+ - **HttpSession** — базовый класс для HTTP запросов с поддержкой cookies
34
+ - **ApiClient** — клиент для публичного JSON API (`/api/*`)
35
+ - **WebClient** — клиент для веб-скрапинга HTML страниц (требует авторизации для большинства методов)
31
36
 
32
- Основной класс для работы с API.
37
+ ## HttpSession
33
38
 
34
- #### Конструктор
39
+ Базовый класс для выполнения HTTP запросов с автоматическим управлением cookies.
35
40
 
36
41
  ```typescript
37
- new ApiClient(options?: ApiClientOptions)
42
+ import { HttpSession } from "ichime-ts-api-client";
43
+
44
+ const session = new HttpSession("https://smotret-anime.com");
45
+
46
+ // Выполнить запрос
47
+ const response = await session.request("/api/series", {
48
+ method: "GET",
49
+ timeout: 15000, // таймаут в мс (по умолчанию 10000)
50
+ });
51
+
52
+ // Работа с cookies
53
+ await session.setCookie("name", "value");
54
+ const value = await session.getCookie("name");
55
+ const cookieString = await session.getCookieString();
38
56
  ```
39
57
 
40
- **Параметры:**
41
- - `options.baseURL` - базовый URL API (по умолчанию: `https://smotret-anime.com`)
42
- - `options.timeout` - таймаут запросов в миллисекундах (по умолчанию: `10000`)
58
+ ## ApiClient
59
+
60
+ Клиент для работы с публичным JSON API. Не требует авторизации.
43
61
 
44
- #### Методы
62
+ ### Создание клиента
45
63
 
46
- ##### `listSeries(options?: ListSeriesOptions): Promise<Series[]>`
64
+ ```typescript
65
+ import { HttpSession, ApiClient } from "ichime-ts-api-client";
47
66
 
48
- Получить список серий.
67
+ const session = new HttpSession("https://smotret-anime.com");
68
+ const client = new ApiClient(session);
69
+ ```
49
70
 
50
- **Параметры:**
51
- - `options.query` - поисковый запрос
52
- - `options.limit` - количество результатов
53
- - `options.offset` - смещение для пагинации
54
- - `options.chips` - фильтры в виде объекта ключ-значение
55
- - `options.myAnimeListId` - ID из MyAnimeList
71
+ ### Методы
56
72
 
57
- **Пример:**
73
+ #### `listSeries(options?: ListSeriesOptions): Promise<Series[]>`
74
+
75
+ Поиск сериалов.
76
+
77
+ **Параметры:**
78
+ - `query` — поисковый запрос
79
+ - `limit` — количество результатов
80
+ - `offset` — смещение для пагинации
81
+ - `chips` — фильтры в виде объекта ключ-значение
82
+ - `myAnimeListId` — ID из MyAnimeList
58
83
 
59
84
  ```typescript
60
85
  const series = await client.listSeries({
61
86
  query: "attack on titan",
62
87
  limit: 20,
63
88
  });
89
+
90
+ // Поиск по MyAnimeList ID
91
+ const series = await client.listSeries({
92
+ myAnimeListId: 16498,
93
+ });
94
+ ```
95
+
96
+ #### `getSeries(seriesId: number): Promise<SeriesFull>`
97
+
98
+ Получить полную информацию о сериале.
99
+
100
+ ```typescript
101
+ const series = await client.getSeries(12345);
102
+ console.log(series.titles, series.descriptions, series.genres);
103
+ ```
104
+
105
+ #### `listEpisodes(options?: ListEpisodesOptions): Promise<Episode[]>`
106
+
107
+ Получить список эпизодов.
108
+
109
+ **Параметры:**
110
+ - `seriesId` — ID сериала
111
+ - `limit` — количество результатов
112
+ - `offset` — смещение для пагинации
113
+
114
+ ```typescript
115
+ const episodes = await client.listEpisodes({
116
+ seriesId: 12345,
117
+ limit: 50,
118
+ });
119
+ ```
120
+
121
+ #### `getEpisode(episodeId: number): Promise<EpisodeFull>`
122
+
123
+ Получить полную информацию об эпизоде.
124
+
125
+ ```typescript
126
+ const episode = await client.getEpisode(67890);
127
+ console.log(episode.translations);
128
+ ```
129
+
130
+ #### `getTranslation(translationId: number): Promise<TranslationFull>`
131
+
132
+ Получить информацию о переводе.
133
+
134
+ ```typescript
135
+ const translation = await client.getTranslation(111222);
136
+ console.log(translation.authorsSummary, translation.qualitySummary);
137
+ ```
138
+
139
+ #### `getTranslationEmbed(translationId: number): Promise<TranslationEmbed>`
140
+
141
+ Получить embed-информацию для воспроизведения перевода.
142
+
143
+ ```typescript
144
+ const embed = await client.getTranslationEmbed(111222);
145
+ console.log(embed.stream); // информация о потоках видео
146
+ ```
147
+
148
+ ## WebClient
149
+
150
+ Клиент для работы с веб-страницами через HTML парсинг. Большинство методов требуют авторизации.
151
+
152
+ ### Создание клиента
153
+
154
+ ```typescript
155
+ import { HttpSession, WebClient } from "ichime-ts-api-client";
156
+
157
+ const session = new HttpSession("https://smotret-anime.com");
158
+ const client = new WebClient(session);
159
+ ```
160
+
161
+ ### Авторизация
162
+
163
+ #### `login(username: string, password: string): Promise<void>`
164
+
165
+ Авторизация на сайте.
166
+
167
+ ```typescript
168
+ await client.login("user@example.com", "password123");
169
+ ```
170
+
171
+ ### Профиль
172
+
173
+ #### `getProfile(): Promise<Profile>`
174
+
175
+ Получить профиль текущего пользователя.
176
+
177
+ ```typescript
178
+ const profile = await client.getProfile();
179
+ console.log(profile.id, profile.name, profile.avatarUrl);
180
+ ```
181
+
182
+ ### Эпизоды
183
+
184
+ #### `getPersonalEpisodes(page: number): Promise<NewPersonalEpisode[]>`
185
+
186
+ Получить персональную ленту новых эпизодов (из списка отслеживаемых аниме).
187
+
188
+ ```typescript
189
+ const episodes = await client.getPersonalEpisodes(1);
190
+ for (const ep of episodes) {
191
+ console.log(ep.seriesTitleRu, ep.episodeNumberLabel, ep.episodeUpdateType);
192
+ }
193
+ ```
194
+
195
+ #### `getRecentEpisodes(page: number): Promise<NewRecentEpisode[]>`
196
+
197
+ Получить общую ленту недавно вышедших эпизодов.
198
+
199
+ ```typescript
200
+ const episodes = await client.getRecentEpisodes(1);
201
+ for (const ep of episodes) {
202
+ console.log(ep.seriesTitleRu, ep.episodeNumberLabel, ep.episodeUploadedAt);
203
+ }
204
+ ```
205
+
206
+ #### `markEpisodeAsWatched(translationId: number): Promise<void>`
207
+
208
+ Отметить эпизод как просмотренный.
209
+
210
+ ```typescript
211
+ await client.markEpisodeAsWatched(111222);
212
+ ```
213
+
214
+ ### Список аниме
215
+
216
+ #### `getAnimeList(userId: number, category: AnimeListCategory): Promise<AnimeListEntry[]>`
217
+
218
+ Получить список аниме пользователя по категории.
219
+
220
+ ```typescript
221
+ import type { AnimeListCategory } from "ichime-ts-api-client";
222
+
223
+ const watching = await client.getAnimeList(userId, "watching");
224
+ const completed = await client.getAnimeList(userId, "completed");
225
+ const onHold = await client.getAnimeList(userId, "onHold");
226
+ const dropped = await client.getAnimeList(userId, "dropped");
227
+ const planToWatch = await client.getAnimeList(userId, "planToWatch");
228
+ ```
229
+
230
+ #### `getAnimeListEditableEntry(seriesId: number): Promise<AnimeListEditableEntry>`
231
+
232
+ Получить редактируемую запись из списка аниме.
233
+
234
+ ```typescript
235
+ const entry = await client.getAnimeListEditableEntry(12345);
236
+ console.log(entry.status, entry.episodesWatched, entry.score);
237
+ ```
238
+
239
+ #### `editAnimeListEntry(seriesId, score, episodes, status, comment): Promise<void>`
240
+
241
+ Редактировать запись в списке аниме.
242
+
243
+ ```typescript
244
+ import { AnimeListEntryStatusNumericId } from "ichime-ts-api-client";
245
+
246
+ await client.editAnimeListEntry(
247
+ 12345, // seriesId
248
+ 8, // score (1-10)
249
+ 5, // episodes watched
250
+ AnimeListEntryStatusNumericId.watching, // status
251
+ "Отличное аниме!" // comment
252
+ );
253
+ ```
254
+
255
+ ### Моменты
256
+
257
+ #### `getMoments(page: number, sort?: MomentSorting): Promise<MomentPreview[]>`
258
+
259
+ Получить список моментов.
260
+
261
+ ```typescript
262
+ import type { MomentSorting } from "ichime-ts-api-client";
263
+
264
+ const moments = await client.getMoments(1, "popular");
265
+ for (const moment of moments) {
266
+ console.log(moment.momentTitle, moment.sourceDescription, moment.durationSeconds);
267
+ }
268
+ ```
269
+
270
+ #### `getMomentsBySeries(seriesId: number, page: number): Promise<MomentPreview[]>`
271
+
272
+ Получить моменты по конкретному сериалу.
273
+
274
+ ```typescript
275
+ const moments = await client.getMomentsBySeries(12345, 1);
276
+ ```
277
+
278
+ #### `getMomentDetails(momentId: number): Promise<MomentDetails>`
279
+
280
+ Получить детали момента.
281
+
282
+ ```typescript
283
+ const details = await client.getMomentDetails(99999);
284
+ console.log(details.seriesId, details.seriesTitle, details.episodeId);
285
+ ```
286
+
287
+ #### `getMomentEmbed(momentId: number): Promise<MomentEmbed>`
288
+
289
+ Получить URL видео для момента.
290
+
291
+ ```typescript
292
+ const embed = await client.getMomentEmbed(99999);
293
+ console.log(embed.videoUrl);
294
+ ```
295
+
296
+ ## Типы
297
+
298
+ ### API типы
299
+
300
+ ```typescript
301
+ import type {
302
+ // Сериалы
303
+ Series,
304
+ SeriesFull,
305
+ SeriesFullDescription,
306
+ SeriesFullGenre,
307
+ SeriesType,
308
+ Titles,
309
+ // Эпизоды
310
+ Episode,
311
+ EpisodeFull,
312
+ // Переводы
313
+ Translation,
314
+ TranslationFull,
315
+ TranslationEmbed,
316
+ TranslationEmbedStream,
317
+ } from "ichime-ts-api-client";
318
+ ```
319
+
320
+ ### Web типы
321
+
322
+ ```typescript
323
+ import type {
324
+ // Профиль
325
+ Profile,
326
+ // Эпизоды
327
+ NewPersonalEpisode,
328
+ NewRecentEpisode,
329
+ // Список аниме
330
+ AnimeListCategory,
331
+ AnimeListEntry,
332
+ AnimeListEditableEntry,
333
+ AnimeListEntryStatus,
334
+ EditAnimeListResult,
335
+ // Моменты
336
+ MomentPreview,
337
+ MomentDetails,
338
+ MomentEmbed,
339
+ MomentSorting,
340
+ VideoSource,
341
+ } from "ichime-ts-api-client";
342
+ ```
343
+
344
+ ### Утилиты для типов
345
+
346
+ ```typescript
347
+ import {
348
+ AnimeListCategoryNumericId,
349
+ AnimeListCategoryWebPath,
350
+ AnimeListEntryStatusNumericId,
351
+ animeListCategoryFromNumericId,
352
+ animeListEntryStatusFromNumericId,
353
+ } from "ichime-ts-api-client";
354
+ ```
355
+
356
+ ## Вспомогательные функции
357
+
358
+ ```typescript
359
+ import {
360
+ parseApiDate,
361
+ isEmptyDate,
362
+ parseWebDate,
363
+ parseDurationString,
364
+ extractIdentifiersFromUrl,
365
+ } from "ichime-ts-api-client";
366
+
367
+ // Парсинг дат из API
368
+ const date = parseApiDate("2024-01-15 12:30:00");
369
+
370
+ // Проверка пустой даты
371
+ if (!isEmptyDate("0000-00-00 00:00:00")) {
372
+ // дата валидна
373
+ }
374
+
375
+ // Парсинг даты из веб-страницы
376
+ const webDate = parseWebDate("15 января 12:30");
377
+
378
+ // Парсинг длительности "1:30" -> 90 секунд
379
+ const seconds = parseDurationString("1:30");
380
+
381
+ // Извлечение ID из URL
382
+ const url = new URL("https://smotret-anime.com/catalog/1234-naruto/5678-episode-1");
383
+ const { seriesId, episodeId } = extractIdentifiersFromUrl(url);
384
+ ```
385
+
386
+ ## Обработка ошибок
387
+
388
+ ```typescript
389
+ import { ApiClientError, ApiError, WebClientError } from "ichime-ts-api-client";
390
+
391
+ try {
392
+ await apiClient.getSeries(99999999);
393
+ } catch (error) {
394
+ if (error instanceof ApiClientError) {
395
+ console.error("API client error:", error.message);
396
+ }
397
+ }
398
+
399
+ try {
400
+ await webClient.getProfile();
401
+ } catch (error) {
402
+ if (error instanceof WebClientError) {
403
+ console.error("Web client error:", error.message);
404
+ }
405
+ }
64
406
  ```
65
407
 
66
408
  ## Разработка
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ichime-ts-api-client",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "TypeScript API client for smotret-anime.com",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",