ani-client 1.3.0 → 1.4.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.
- package/README.md +74 -5
- package/dist/index.d.mts +241 -60
- package/dist/index.d.ts +241 -60
- package/dist/index.js +430 -191
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +430 -192
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
> A simple, typed client to fetch anime, manga, character, staff and user data from [AniList](https://anilist.co).
|
|
8
8
|
|
|
9
9
|
- **Zero dependencies** — uses the native `fetch` API
|
|
10
|
-
- **Universal** — Node.js ≥
|
|
10
|
+
- **Universal** — Node.js ≥ 20, Bun, Deno and modern browsers
|
|
11
11
|
- **Dual format** — ships ESM + CJS with full TypeScript declarations
|
|
12
12
|
- **Built-in caching** — in-memory LRU with optional Redis adapter
|
|
13
13
|
- **Rate-limit aware** — auto-retry on 429, configurable timeout & network error retry
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- [Client options](#client-options)
|
|
23
23
|
- [API reference](#api-reference)
|
|
24
24
|
- [Media](#media)
|
|
25
|
+
- [Include options](#include-options)
|
|
25
26
|
- [Characters](#characters)
|
|
26
27
|
- [Staff](#staff)
|
|
27
28
|
- [Users](#users)
|
|
@@ -145,15 +146,27 @@ const client = new AniListClient({
|
|
|
145
146
|
|
|
146
147
|
| Method | Description |
|
|
147
148
|
| --- | --- |
|
|
148
|
-
| `getMedia(id)` | Fetch a single anime / manga by ID |
|
|
149
|
+
| `getMedia(id, include?)` | Fetch a single anime / manga by ID with optional extra data |
|
|
149
150
|
| `searchMedia(options?)` | Search & filter anime / manga |
|
|
150
151
|
| `getTrending(type?, page?, perPage?)` | Currently trending entries |
|
|
151
152
|
| `getMediaBySeason(options)` | Anime/manga for a given season & year |
|
|
152
153
|
| `getRecommendations(mediaId, options?)` | User recommendations for a media |
|
|
153
154
|
|
|
154
155
|
```ts
|
|
156
|
+
// Simple — same as before
|
|
155
157
|
const anime = await client.getMedia(1);
|
|
156
158
|
|
|
159
|
+
// With extra data
|
|
160
|
+
const anime = await client.getMedia(1, {
|
|
161
|
+
characters: { perPage: 25, sort: true },
|
|
162
|
+
staff: true,
|
|
163
|
+
relations: true,
|
|
164
|
+
streamingEpisodes: true,
|
|
165
|
+
externalLinks: true,
|
|
166
|
+
stats: true,
|
|
167
|
+
recommendations: { perPage: 5 },
|
|
168
|
+
});
|
|
169
|
+
|
|
157
170
|
const results = await client.searchMedia({
|
|
158
171
|
query: "Naruto",
|
|
159
172
|
type: MediaType.ANIME,
|
|
@@ -163,6 +176,56 @@ const results = await client.searchMedia({
|
|
|
163
176
|
});
|
|
164
177
|
```
|
|
165
178
|
|
|
179
|
+
### Include options
|
|
180
|
+
|
|
181
|
+
The second parameter of `getMedia()` lets you opt-in to additional data. By default, only `relations` are included for backward compatibility.
|
|
182
|
+
|
|
183
|
+
| Option | Type | Default | Description |
|
|
184
|
+
| --- | --- | --- | --- |
|
|
185
|
+
| `characters` | `boolean \| { perPage?, sort? }` | — | Characters with their roles (MAIN, SUPPORTING, BACKGROUND) |
|
|
186
|
+
| `staff` | `boolean \| { perPage?, sort? }` | — | Staff members with their roles |
|
|
187
|
+
| `relations` | `boolean` | `true` | Sequels, prequels, adaptations, etc. Set `false` to exclude |
|
|
188
|
+
| `streamingEpisodes` | `boolean` | — | Streaming links (Crunchyroll, Funimation, etc.) |
|
|
189
|
+
| `externalLinks` | `boolean` | — | External links (MAL, official site, etc.) |
|
|
190
|
+
| `stats` | `boolean` | — | Score & status distribution |
|
|
191
|
+
| `recommendations` | `boolean \| { perPage? }` | — | User recommendations |
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// Include characters sorted by role (25 per page by default)
|
|
195
|
+
const anime = await client.getMedia(1, { characters: true });
|
|
196
|
+
anime.characters?.edges.forEach((e) =>
|
|
197
|
+
console.log(`${e.node.name.full} (${e.role})`)
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// 50 characters, no sorting
|
|
201
|
+
const anime = await client.getMedia(1, {
|
|
202
|
+
characters: { perPage: 50, sort: false },
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Staff members
|
|
206
|
+
const anime = await client.getMedia(1, { staff: true });
|
|
207
|
+
anime.staff?.edges.forEach((e) =>
|
|
208
|
+
console.log(`${e.node.name.full} — ${e.role}`)
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// Everything at once
|
|
212
|
+
const anime = await client.getMedia(1, {
|
|
213
|
+
characters: { perPage: 50 },
|
|
214
|
+
staff: { perPage: 25 },
|
|
215
|
+
relations: true,
|
|
216
|
+
streamingEpisodes: true,
|
|
217
|
+
externalLinks: true,
|
|
218
|
+
stats: true,
|
|
219
|
+
recommendations: { perPage: 10 },
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Lightweight — exclude relations
|
|
223
|
+
const anime = await client.getMedia(1, {
|
|
224
|
+
characters: true,
|
|
225
|
+
relations: false,
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
166
229
|
### Characters
|
|
167
230
|
|
|
168
231
|
| Method | Description |
|
|
@@ -266,13 +329,16 @@ recs.results.forEach((r) =>
|
|
|
266
329
|
|
|
267
330
|
### Relations
|
|
268
331
|
|
|
269
|
-
|
|
332
|
+
Relations (sequels, prequels, spin-offs, etc.) are included by default when using `getMedia()`. You can also explicitly request them via the `include` parameter, or exclude them with `relations: false`.
|
|
270
333
|
|
|
271
334
|
```ts
|
|
272
335
|
const anime = await client.getMedia(1);
|
|
273
336
|
anime.relations?.edges.forEach((edge) =>
|
|
274
337
|
console.log(`${edge.relationType}: ${edge.node.title.romaji}`)
|
|
275
338
|
);
|
|
339
|
+
|
|
340
|
+
// Exclude relations for a lighter response
|
|
341
|
+
const anime = await client.getMedia(1, { relations: false });
|
|
276
342
|
```
|
|
277
343
|
|
|
278
344
|
Available types: `ADAPTATION`, `PREQUEL`, `SEQUEL`, `PARENT`, `SIDE_STORY`, `CHARACTER`, `SUMMARY`, `ALTERNATIVE`, `SPIN_OFF`, `OTHER`, `SOURCE`, `COMPILATION`, `CONTAINS`.
|
|
@@ -474,7 +540,10 @@ All types and enums are exported:
|
|
|
474
540
|
import type {
|
|
475
541
|
Media, Character, Staff, User,
|
|
476
542
|
AiringSchedule, MediaListEntry, Recommendation, StudioDetail,
|
|
477
|
-
MediaEdge, MediaConnection,
|
|
543
|
+
MediaEdge, MediaConnection, MediaCharacterEdge, MediaCharacterConnection,
|
|
544
|
+
MediaStaffEdge, MediaStaffConnection, MediaIncludeOptions,
|
|
545
|
+
StreamingEpisode, ExternalLink, MediaStats, MediaRecommendationNode,
|
|
546
|
+
PageInfo, PagedResult,
|
|
478
547
|
CacheAdapter, AniListHooks, AniListClientOptions,
|
|
479
548
|
SearchMediaOptions, SearchCharacterOptions, SearchStaffOptions,
|
|
480
549
|
SearchStudioOptions, GetAiringOptions, GetRecentChaptersOptions,
|
|
@@ -484,7 +553,7 @@ import type {
|
|
|
484
553
|
|
|
485
554
|
import {
|
|
486
555
|
MediaType, MediaFormat, MediaStatus, MediaSeason, MediaSort,
|
|
487
|
-
CharacterSort, AiringSort, RecommendationSort,
|
|
556
|
+
CharacterSort, CharacterRole, AiringSort, RecommendationSort,
|
|
488
557
|
MediaRelationType, MediaListStatus, MediaListSort,
|
|
489
558
|
} from "ani-client";
|
|
490
559
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -29,21 +29,37 @@ declare enum MediaSeason {
|
|
|
29
29
|
}
|
|
30
30
|
declare enum MediaSort {
|
|
31
31
|
ID = "ID",
|
|
32
|
+
ID_DESC = "ID_DESC",
|
|
32
33
|
TITLE_ROMAJI = "TITLE_ROMAJI",
|
|
34
|
+
TITLE_ROMAJI_DESC = "TITLE_ROMAJI_DESC",
|
|
33
35
|
TITLE_ENGLISH = "TITLE_ENGLISH",
|
|
36
|
+
TITLE_ENGLISH_DESC = "TITLE_ENGLISH_DESC",
|
|
34
37
|
TITLE_NATIVE = "TITLE_NATIVE",
|
|
38
|
+
TITLE_NATIVE_DESC = "TITLE_NATIVE_DESC",
|
|
35
39
|
TYPE = "TYPE",
|
|
40
|
+
TYPE_DESC = "TYPE_DESC",
|
|
36
41
|
FORMAT = "FORMAT",
|
|
42
|
+
FORMAT_DESC = "FORMAT_DESC",
|
|
37
43
|
START_DATE = "START_DATE",
|
|
44
|
+
START_DATE_DESC = "START_DATE_DESC",
|
|
38
45
|
END_DATE = "END_DATE",
|
|
46
|
+
END_DATE_DESC = "END_DATE_DESC",
|
|
39
47
|
SCORE = "SCORE",
|
|
48
|
+
SCORE_DESC = "SCORE_DESC",
|
|
40
49
|
POPULARITY = "POPULARITY",
|
|
50
|
+
POPULARITY_DESC = "POPULARITY_DESC",
|
|
41
51
|
TRENDING = "TRENDING",
|
|
52
|
+
TRENDING_DESC = "TRENDING_DESC",
|
|
42
53
|
EPISODES = "EPISODES",
|
|
54
|
+
EPISODES_DESC = "EPISODES_DESC",
|
|
43
55
|
DURATION = "DURATION",
|
|
56
|
+
DURATION_DESC = "DURATION_DESC",
|
|
44
57
|
STATUS = "STATUS",
|
|
58
|
+
STATUS_DESC = "STATUS_DESC",
|
|
45
59
|
FAVOURITES = "FAVOURITES",
|
|
60
|
+
FAVOURITES_DESC = "FAVOURITES_DESC",
|
|
46
61
|
UPDATED_AT = "UPDATED_AT",
|
|
62
|
+
UPDATED_AT_DESC = "UPDATED_AT_DESC",
|
|
47
63
|
SEARCH_MATCH = "SEARCH_MATCH"
|
|
48
64
|
}
|
|
49
65
|
declare enum AiringSort {
|
|
@@ -58,9 +74,17 @@ declare enum AiringSort {
|
|
|
58
74
|
}
|
|
59
75
|
declare enum CharacterSort {
|
|
60
76
|
ID = "ID",
|
|
77
|
+
ID_DESC = "ID_DESC",
|
|
61
78
|
ROLE = "ROLE",
|
|
79
|
+
ROLE_DESC = "ROLE_DESC",
|
|
62
80
|
SEARCH_MATCH = "SEARCH_MATCH",
|
|
63
|
-
FAVOURITES = "FAVOURITES"
|
|
81
|
+
FAVOURITES = "FAVOURITES",
|
|
82
|
+
FAVOURITES_DESC = "FAVOURITES_DESC"
|
|
83
|
+
}
|
|
84
|
+
declare enum CharacterRole {
|
|
85
|
+
MAIN = "MAIN",
|
|
86
|
+
SUPPORTING = "SUPPORTING",
|
|
87
|
+
BACKGROUND = "BACKGROUND"
|
|
64
88
|
}
|
|
65
89
|
interface MediaTitle {
|
|
66
90
|
romaji: string | null;
|
|
@@ -135,6 +159,51 @@ interface CharacterImage {
|
|
|
135
159
|
large: string | null;
|
|
136
160
|
medium: string | null;
|
|
137
161
|
}
|
|
162
|
+
interface MediaCharacterEdge {
|
|
163
|
+
role: CharacterRole;
|
|
164
|
+
node: Omit<Character, "media">;
|
|
165
|
+
}
|
|
166
|
+
interface MediaCharacterConnection {
|
|
167
|
+
edges: MediaCharacterEdge[];
|
|
168
|
+
}
|
|
169
|
+
interface MediaStaffEdge {
|
|
170
|
+
role: string;
|
|
171
|
+
node: Staff;
|
|
172
|
+
}
|
|
173
|
+
interface MediaStaffConnection {
|
|
174
|
+
edges: MediaStaffEdge[];
|
|
175
|
+
}
|
|
176
|
+
interface StreamingEpisode {
|
|
177
|
+
title: string | null;
|
|
178
|
+
thumbnail: string | null;
|
|
179
|
+
url: string | null;
|
|
180
|
+
site: string | null;
|
|
181
|
+
}
|
|
182
|
+
interface ExternalLink {
|
|
183
|
+
id: number;
|
|
184
|
+
url: string | null;
|
|
185
|
+
site: string;
|
|
186
|
+
type: string | null;
|
|
187
|
+
icon: string | null;
|
|
188
|
+
color: string | null;
|
|
189
|
+
}
|
|
190
|
+
interface ScoreDistribution {
|
|
191
|
+
score: number;
|
|
192
|
+
amount: number;
|
|
193
|
+
}
|
|
194
|
+
interface StatusDistribution {
|
|
195
|
+
status: MediaListStatus | string;
|
|
196
|
+
amount: number;
|
|
197
|
+
}
|
|
198
|
+
interface MediaStats {
|
|
199
|
+
scoreDistribution: ScoreDistribution[];
|
|
200
|
+
statusDistribution: StatusDistribution[];
|
|
201
|
+
}
|
|
202
|
+
interface MediaRecommendationNode {
|
|
203
|
+
id: number;
|
|
204
|
+
rating: number | null;
|
|
205
|
+
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "siteUrl">;
|
|
206
|
+
}
|
|
138
207
|
interface Media {
|
|
139
208
|
id: number;
|
|
140
209
|
idMal: number | null;
|
|
@@ -168,6 +237,14 @@ interface Media {
|
|
|
168
237
|
tags: MediaTag[];
|
|
169
238
|
studios: StudioConnection;
|
|
170
239
|
relations: MediaConnection | null;
|
|
240
|
+
characters?: MediaCharacterConnection;
|
|
241
|
+
staff?: MediaStaffConnection;
|
|
242
|
+
streamingEpisodes?: StreamingEpisode[];
|
|
243
|
+
externalLinks?: ExternalLink[];
|
|
244
|
+
stats?: MediaStats;
|
|
245
|
+
recommendations?: {
|
|
246
|
+
nodes: MediaRecommendationNode[];
|
|
247
|
+
};
|
|
171
248
|
isAdult: boolean | null;
|
|
172
249
|
siteUrl: string | null;
|
|
173
250
|
}
|
|
@@ -207,7 +284,7 @@ interface Staff {
|
|
|
207
284
|
gender: string | null;
|
|
208
285
|
dateOfBirth: FuzzyDate | null;
|
|
209
286
|
dateOfDeath: FuzzyDate | null;
|
|
210
|
-
age:
|
|
287
|
+
age: string | null;
|
|
211
288
|
yearsActive: number[];
|
|
212
289
|
homeTown: string | null;
|
|
213
290
|
bloodType: string | null;
|
|
@@ -280,6 +357,7 @@ interface SearchCharacterOptions {
|
|
|
280
357
|
}
|
|
281
358
|
interface SearchStaffOptions {
|
|
282
359
|
query?: string;
|
|
360
|
+
sort?: CharacterSort[];
|
|
283
361
|
page?: number;
|
|
284
362
|
perPage?: number;
|
|
285
363
|
}
|
|
@@ -435,6 +513,36 @@ interface SearchStudioOptions {
|
|
|
435
513
|
page?: number;
|
|
436
514
|
perPage?: number;
|
|
437
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Options to include additional related data when fetching a media entry.
|
|
518
|
+
* Pass `true` to include with defaults, or an object to customize.
|
|
519
|
+
*/
|
|
520
|
+
interface MediaIncludeOptions {
|
|
521
|
+
/** Include characters with their roles (MAIN, SUPPORTING, BACKGROUND).
|
|
522
|
+
* `true` = 25 results sorted by role. Object form to customize. */
|
|
523
|
+
characters?: boolean | {
|
|
524
|
+
perPage?: number;
|
|
525
|
+
sort?: boolean;
|
|
526
|
+
};
|
|
527
|
+
/** Include staff members with their roles.
|
|
528
|
+
* `true` = 25 results sorted by relevance. Object form to customize. */
|
|
529
|
+
staff?: boolean | {
|
|
530
|
+
perPage?: number;
|
|
531
|
+
sort?: boolean;
|
|
532
|
+
};
|
|
533
|
+
/** Include relations (default: `true` for backward compat). Set to `false` to exclude. */
|
|
534
|
+
relations?: boolean;
|
|
535
|
+
/** Include streaming episode links (Crunchyroll, Funimation, etc.) */
|
|
536
|
+
streamingEpisodes?: boolean;
|
|
537
|
+
/** Include external links (MAL, official site, etc.) */
|
|
538
|
+
externalLinks?: boolean;
|
|
539
|
+
/** Include score & status distribution stats */
|
|
540
|
+
stats?: boolean;
|
|
541
|
+
/** Include user recommendations. `true` = 10 results, or customize with `{ perPage }`. */
|
|
542
|
+
recommendations?: boolean | {
|
|
543
|
+
perPage?: number;
|
|
544
|
+
};
|
|
545
|
+
}
|
|
438
546
|
/**
|
|
439
547
|
* Interface that all cache adapters must implement.
|
|
440
548
|
* Methods may return sync values or Promises — the client awaits all calls.
|
|
@@ -451,10 +559,36 @@ interface CacheAdapter {
|
|
|
451
559
|
/** Number of entries currently stored (sync). Returns -1 if unknown. */
|
|
452
560
|
readonly size: number;
|
|
453
561
|
/** Return all cache keys. */
|
|
454
|
-
keys():
|
|
562
|
+
keys(): string[] | Promise<string[]>;
|
|
455
563
|
/** Bulk-remove entries matching a pattern. Optional — the client provides a fallback. */
|
|
456
564
|
invalidate?(pattern: string | RegExp): number | Promise<number>;
|
|
457
565
|
}
|
|
566
|
+
/** Cache configuration options. */
|
|
567
|
+
interface CacheOptions {
|
|
568
|
+
/** Time-to-live in milliseconds (default: 86 400 000 = 24h) */
|
|
569
|
+
ttl?: number;
|
|
570
|
+
/** Maximum number of cached entries (default: 500, 0 = unlimited) */
|
|
571
|
+
maxSize?: number;
|
|
572
|
+
/** Set to false to disable caching entirely */
|
|
573
|
+
enabled?: boolean;
|
|
574
|
+
}
|
|
575
|
+
/** Rate limiter configuration options. */
|
|
576
|
+
interface RateLimitOptions {
|
|
577
|
+
/** Max requests per window (default: 85) */
|
|
578
|
+
maxRequests?: number;
|
|
579
|
+
/** Window size in ms (default: 60 000) */
|
|
580
|
+
windowMs?: number;
|
|
581
|
+
/** Max retries on 429 (default: 3) */
|
|
582
|
+
maxRetries?: number;
|
|
583
|
+
/** Retry delay in ms when Retry-After header is absent (default: 2000) */
|
|
584
|
+
retryDelayMs?: number;
|
|
585
|
+
/** Set to false to disable rate limiting entirely */
|
|
586
|
+
enabled?: boolean;
|
|
587
|
+
/** Timeout per request in ms (default: 30 000). 0 = no timeout. */
|
|
588
|
+
timeoutMs?: number;
|
|
589
|
+
/** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
|
|
590
|
+
retryOnNetworkError?: boolean;
|
|
591
|
+
}
|
|
458
592
|
/** Event hooks for logging, debugging, and monitoring. */
|
|
459
593
|
interface AniListHooks {
|
|
460
594
|
/** Called before every API request. */
|
|
@@ -474,33 +608,11 @@ interface AniListClientOptions {
|
|
|
474
608
|
/** Custom API endpoint (defaults to https://graphql.anilist.co) */
|
|
475
609
|
apiUrl?: string;
|
|
476
610
|
/** Cache configuration (enabled by default, 24h TTL) */
|
|
477
|
-
cache?:
|
|
478
|
-
/** Time-to-live in milliseconds (default: 86 400 000 = 24h) */
|
|
479
|
-
ttl?: number;
|
|
480
|
-
/** Maximum number of cached entries (default: 500, 0 = unlimited) */
|
|
481
|
-
maxSize?: number;
|
|
482
|
-
/** Set to false to disable caching entirely */
|
|
483
|
-
enabled?: boolean;
|
|
484
|
-
};
|
|
611
|
+
cache?: CacheOptions;
|
|
485
612
|
/** Custom cache adapter (e.g. RedisCache). Takes precedence over `cache`. */
|
|
486
613
|
cacheAdapter?: CacheAdapter;
|
|
487
614
|
/** Rate limiter configuration (enabled by default, 85 req/min) */
|
|
488
|
-
rateLimit?:
|
|
489
|
-
/** Max requests per window (default: 85) */
|
|
490
|
-
maxRequests?: number;
|
|
491
|
-
/** Window size in ms (default: 60 000) */
|
|
492
|
-
windowMs?: number;
|
|
493
|
-
/** Max retries on 429 (default: 3) */
|
|
494
|
-
maxRetries?: number;
|
|
495
|
-
/** Retry delay in ms when Retry-After header is absent (default: 2000) */
|
|
496
|
-
retryDelayMs?: number;
|
|
497
|
-
/** Set to false to disable rate limiting entirely */
|
|
498
|
-
enabled?: boolean;
|
|
499
|
-
/** Timeout per request in ms (default: 30 000). 0 = no timeout. */
|
|
500
|
-
timeoutMs?: number;
|
|
501
|
-
/** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
|
|
502
|
-
retryOnNetworkError?: boolean;
|
|
503
|
-
};
|
|
615
|
+
rateLimit?: RateLimitOptions;
|
|
504
616
|
/** Event hooks for logging, debugging, and monitoring */
|
|
505
617
|
hooks?: AniListHooks;
|
|
506
618
|
}
|
|
@@ -542,13 +654,44 @@ declare class AniListClient {
|
|
|
542
654
|
* Shorthand for paginated queries that follow the `Page { pageInfo, <field>[] }` pattern.
|
|
543
655
|
*/
|
|
544
656
|
private pagedRequest;
|
|
657
|
+
/**
|
|
658
|
+
* @internal
|
|
659
|
+
* Clamp perPage to AniList's maximum of 50.
|
|
660
|
+
*/
|
|
661
|
+
private clampPerPage;
|
|
545
662
|
/**
|
|
546
663
|
* Fetch a single media entry by its AniList ID.
|
|
547
664
|
*
|
|
665
|
+
* Optionally include related data (characters, staff, relations, etc.) via the `include` parameter.
|
|
666
|
+
*
|
|
548
667
|
* @param id - The AniList media ID
|
|
668
|
+
* @param include - Optional related data to include
|
|
549
669
|
* @returns The media object
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```ts
|
|
673
|
+
* // Basic usage — same as before (includes relations by default)
|
|
674
|
+
* const anime = await client.getMedia(1);
|
|
675
|
+
*
|
|
676
|
+
* // Include characters sorted by role, 25 results
|
|
677
|
+
* const anime = await client.getMedia(1, { characters: true });
|
|
678
|
+
*
|
|
679
|
+
* // Full control
|
|
680
|
+
* const anime = await client.getMedia(1, {
|
|
681
|
+
* characters: { perPage: 50, sort: true },
|
|
682
|
+
* staff: true,
|
|
683
|
+
* relations: true,
|
|
684
|
+
* streamingEpisodes: true,
|
|
685
|
+
* externalLinks: true,
|
|
686
|
+
* stats: true,
|
|
687
|
+
* recommendations: { perPage: 5 },
|
|
688
|
+
* });
|
|
689
|
+
*
|
|
690
|
+
* // Exclude relations for a lighter response
|
|
691
|
+
* const anime = await client.getMedia(1, { characters: true, relations: false });
|
|
692
|
+
* ```
|
|
550
693
|
*/
|
|
551
|
-
getMedia(id: number): Promise<Media>;
|
|
694
|
+
getMedia(id: number, include?: MediaIncludeOptions): Promise<Media>;
|
|
552
695
|
/**
|
|
553
696
|
* Search for anime or manga.
|
|
554
697
|
*
|
|
@@ -575,26 +718,78 @@ declare class AniListClient {
|
|
|
575
718
|
getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
576
719
|
/**
|
|
577
720
|
* Fetch a character by AniList ID.
|
|
721
|
+
*
|
|
722
|
+
* @param id - The AniList character ID
|
|
723
|
+
* @returns The character object
|
|
724
|
+
*
|
|
725
|
+
* @example
|
|
726
|
+
* ```ts
|
|
727
|
+
* const spike = await client.getCharacter(1);
|
|
728
|
+
* console.log(spike.name.full); // "Spike Spiegel"
|
|
729
|
+
* ```
|
|
578
730
|
*/
|
|
579
731
|
getCharacter(id: number): Promise<Character>;
|
|
580
732
|
/**
|
|
581
733
|
* Search for characters by name.
|
|
734
|
+
*
|
|
735
|
+
* @param options - Search / pagination parameters
|
|
736
|
+
* @returns Paginated results with matching characters
|
|
737
|
+
*
|
|
738
|
+
* @example
|
|
739
|
+
* ```ts
|
|
740
|
+
* const result = await client.searchCharacters({ query: "Luffy", perPage: 5 });
|
|
741
|
+
* ```
|
|
582
742
|
*/
|
|
583
743
|
searchCharacters(options?: SearchCharacterOptions): Promise<PagedResult<Character>>;
|
|
584
744
|
/**
|
|
585
745
|
* Fetch a staff member by AniList ID.
|
|
746
|
+
*
|
|
747
|
+
* @param id - The AniList staff ID
|
|
748
|
+
* @returns The staff object
|
|
749
|
+
*
|
|
750
|
+
* @example
|
|
751
|
+
* ```ts
|
|
752
|
+
* const staff = await client.getStaff(95001);
|
|
753
|
+
* console.log(staff.name.full);
|
|
754
|
+
* ```
|
|
586
755
|
*/
|
|
587
756
|
getStaff(id: number): Promise<Staff>;
|
|
588
757
|
/**
|
|
589
758
|
* Search for staff (voice actors, directors, etc.).
|
|
759
|
+
*
|
|
760
|
+
* @param options - Search / pagination parameters
|
|
761
|
+
* @returns Paginated results with matching staff
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* ```ts
|
|
765
|
+
* const result = await client.searchStaff({ query: "Miyazaki", perPage: 5 });
|
|
766
|
+
* ```
|
|
590
767
|
*/
|
|
591
768
|
searchStaff(options?: SearchStaffOptions): Promise<PagedResult<Staff>>;
|
|
592
769
|
/**
|
|
593
770
|
* Fetch a user by AniList ID.
|
|
771
|
+
*
|
|
772
|
+
* @param id - The AniList user ID
|
|
773
|
+
* @returns The user object
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* ```ts
|
|
777
|
+
* const user = await client.getUser(1);
|
|
778
|
+
* console.log(user.name);
|
|
779
|
+
* ```
|
|
594
780
|
*/
|
|
595
781
|
getUser(id: number): Promise<User>;
|
|
596
782
|
/**
|
|
597
783
|
* Fetch a user by username.
|
|
784
|
+
*
|
|
785
|
+
* @param name - The AniList username
|
|
786
|
+
* @returns The user object
|
|
787
|
+
*
|
|
788
|
+
* @example
|
|
789
|
+
* ```ts
|
|
790
|
+
* const user = await client.getUserByName("AniList");
|
|
791
|
+
* console.log(user.statistics);
|
|
792
|
+
* ```
|
|
598
793
|
*/
|
|
599
794
|
getUserByName(name: string): Promise<User>;
|
|
600
795
|
/**
|
|
@@ -830,18 +1025,6 @@ declare class AniListError extends Error {
|
|
|
830
1025
|
constructor(message: string, status: number, errors?: unknown[]);
|
|
831
1026
|
}
|
|
832
1027
|
|
|
833
|
-
/**
|
|
834
|
-
* Simple in-memory cache with configurable TTL.
|
|
835
|
-
* Used internally by AniListClient to avoid redundant API calls.
|
|
836
|
-
*/
|
|
837
|
-
interface CacheOptions {
|
|
838
|
-
/** Time-to-live in milliseconds (default: 24 hours) */
|
|
839
|
-
ttl?: number;
|
|
840
|
-
/** Maximum number of entries to keep (default: 500, 0 = unlimited) */
|
|
841
|
-
maxSize?: number;
|
|
842
|
-
/** Disable caching entirely (default: false) */
|
|
843
|
-
enabled?: boolean;
|
|
844
|
-
}
|
|
845
1028
|
declare class MemoryCache implements CacheAdapter {
|
|
846
1029
|
private readonly ttl;
|
|
847
1030
|
private readonly maxSize;
|
|
@@ -860,8 +1043,8 @@ declare class MemoryCache implements CacheAdapter {
|
|
|
860
1043
|
clear(): void;
|
|
861
1044
|
/** Number of entries currently stored. */
|
|
862
1045
|
get size(): number;
|
|
863
|
-
/** Return
|
|
864
|
-
keys():
|
|
1046
|
+
/** Return all cache keys. */
|
|
1047
|
+
keys(): string[];
|
|
865
1048
|
/**
|
|
866
1049
|
* Remove all entries whose key matches the given pattern.
|
|
867
1050
|
*
|
|
@@ -880,6 +1063,11 @@ interface RedisLikeClient {
|
|
|
880
1063
|
set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
|
|
881
1064
|
del(...keys: (string | string[])[]): Promise<number>;
|
|
882
1065
|
keys(pattern: string): Promise<string[]>;
|
|
1066
|
+
/** Optional SCAN-based iteration — used when available to avoid blocking the server. */
|
|
1067
|
+
scanIterator?(options: {
|
|
1068
|
+
MATCH: string;
|
|
1069
|
+
COUNT?: number;
|
|
1070
|
+
}): AsyncIterable<string>;
|
|
883
1071
|
}
|
|
884
1072
|
interface RedisCacheOptions {
|
|
885
1073
|
/** A Redis client instance (ioredis or node-redis). */
|
|
@@ -912,6 +1100,14 @@ declare class RedisCache implements CacheAdapter {
|
|
|
912
1100
|
get<T>(key: string): Promise<T | undefined>;
|
|
913
1101
|
set<T>(key: string, data: T): Promise<void>;
|
|
914
1102
|
delete(key: string): Promise<boolean>;
|
|
1103
|
+
/**
|
|
1104
|
+
* Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.
|
|
1105
|
+
*
|
|
1106
|
+
* **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.
|
|
1107
|
+
* Provide a client with `scanIterator` support for production use.
|
|
1108
|
+
* @internal
|
|
1109
|
+
*/
|
|
1110
|
+
private collectKeys;
|
|
915
1111
|
clear(): Promise<void>;
|
|
916
1112
|
/**
|
|
917
1113
|
* Returns -1 because Redis keys can expire silently via TTL.
|
|
@@ -927,7 +1123,7 @@ declare class RedisCache implements CacheAdapter {
|
|
|
927
1123
|
* @param pattern — A glob pattern (e.g. `"*Media*"`)
|
|
928
1124
|
* @returns Number of entries removed.
|
|
929
1125
|
*/
|
|
930
|
-
invalidate(pattern: string): Promise<number>;
|
|
1126
|
+
invalidate(pattern: string | RegExp): Promise<number>;
|
|
931
1127
|
}
|
|
932
1128
|
|
|
933
1129
|
/**
|
|
@@ -937,22 +1133,7 @@ declare class RedisCache implements CacheAdapter {
|
|
|
937
1133
|
* When a 429 (Too Many Requests) is received, the client
|
|
938
1134
|
* waits for the Retry-After header and retries automatically.
|
|
939
1135
|
*/
|
|
940
|
-
|
|
941
|
-
/** Max requests per window (default: 85, conservative under AniList's 90/min) */
|
|
942
|
-
maxRequests?: number;
|
|
943
|
-
/** Window size in milliseconds (default: 60 000 = 1 minute) */
|
|
944
|
-
windowMs?: number;
|
|
945
|
-
/** Max number of retries on 429 responses (default: 3) */
|
|
946
|
-
maxRetries?: number;
|
|
947
|
-
/** Default retry delay in ms when Retry-After header is missing (default: 2000) */
|
|
948
|
-
retryDelayMs?: number;
|
|
949
|
-
/** Disable rate limiting entirely (default: false) */
|
|
950
|
-
enabled?: boolean;
|
|
951
|
-
/** Timeout per request in milliseconds (default: 30 000). 0 = no timeout. */
|
|
952
|
-
timeoutMs?: number;
|
|
953
|
-
/** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
|
|
954
|
-
retryOnNetworkError?: boolean;
|
|
955
|
-
}
|
|
1136
|
+
|
|
956
1137
|
declare class RateLimiter {
|
|
957
1138
|
private readonly maxRequests;
|
|
958
1139
|
private readonly windowMs;
|
|
@@ -980,4 +1161,4 @@ declare class RateLimiter {
|
|
|
980
1161
|
private sleep;
|
|
981
1162
|
}
|
|
982
1163
|
|
|
983
|
-
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaListEntry, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };
|
|
1164
|
+
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterRole, CharacterSort, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };
|