ani-client 1.7.0 → 1.8.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.
- package/README.md +103 -45
- package/dist/index.d.mts +389 -274
- package/dist/index.d.ts +389 -274
- package/dist/index.js +582 -318
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +582 -318
- package/dist/index.mjs.map +1 -1
- package/package.json +25 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
interface PageInfo {
|
|
2
2
|
total: number | null;
|
|
3
|
-
perPage: number
|
|
4
|
-
currentPage: number
|
|
5
|
-
lastPage: number
|
|
6
|
-
hasNextPage: boolean
|
|
3
|
+
perPage: number;
|
|
4
|
+
currentPage: number;
|
|
5
|
+
lastPage: number;
|
|
6
|
+
hasNextPage: boolean;
|
|
7
7
|
}
|
|
8
8
|
interface PagedResult<T> {
|
|
9
9
|
pageInfo: PageInfo;
|
|
@@ -50,6 +50,12 @@ interface CacheOptions {
|
|
|
50
50
|
maxSize?: number;
|
|
51
51
|
/** Set to false to disable caching entirely */
|
|
52
52
|
enabled?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Stale-while-revalidate grace period in milliseconds (default: 0 = disabled).
|
|
55
|
+
* When set, expired entries are still returned within the grace window,
|
|
56
|
+
* allowing the caller to refresh in the background.
|
|
57
|
+
*/
|
|
58
|
+
staleWhileRevalidateMs?: number;
|
|
53
59
|
}
|
|
54
60
|
/** Rate limiter configuration options. */
|
|
55
61
|
interface RateLimitOptions {
|
|
@@ -111,6 +117,16 @@ interface ResponseMeta {
|
|
|
111
117
|
/** Rate limit information from the API response headers (not present for cached responses). */
|
|
112
118
|
rateLimitInfo?: RateLimitInfo;
|
|
113
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Minimal logger interface for structured log output.
|
|
122
|
+
* Compatible with `console`, `pino`, `winston`, etc.
|
|
123
|
+
*/
|
|
124
|
+
interface Logger {
|
|
125
|
+
debug(message: string, ...args: unknown[]): void;
|
|
126
|
+
info(message: string, ...args: unknown[]): void;
|
|
127
|
+
warn(message: string, ...args: unknown[]): void;
|
|
128
|
+
error(message: string, ...args: unknown[]): void;
|
|
129
|
+
}
|
|
114
130
|
interface AniListClientOptions {
|
|
115
131
|
/** Optional AniList OAuth token for authenticated requests */
|
|
116
132
|
token?: string;
|
|
@@ -126,6 +142,89 @@ interface AniListClientOptions {
|
|
|
126
142
|
hooks?: AniListHooks;
|
|
127
143
|
/** Optional AbortSignal to cancel all requests made by this client */
|
|
128
144
|
signal?: AbortSignal;
|
|
145
|
+
/**
|
|
146
|
+
* Optional logger for structured log output.
|
|
147
|
+
* Accepts any object with `debug`, `info`, `warn`, `error` methods.
|
|
148
|
+
* Compatible with `console`, `pino`, `winston`, etc.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const client = new AniListClient({ logger: console });
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
logger?: Logger;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
declare enum MediaListStatus {
|
|
159
|
+
CURRENT = "CURRENT",
|
|
160
|
+
PLANNING = "PLANNING",
|
|
161
|
+
COMPLETED = "COMPLETED",
|
|
162
|
+
DROPPED = "DROPPED",
|
|
163
|
+
PAUSED = "PAUSED",
|
|
164
|
+
REPEATING = "REPEATING"
|
|
165
|
+
}
|
|
166
|
+
declare enum MediaListSort {
|
|
167
|
+
MEDIA_ID = "MEDIA_ID",
|
|
168
|
+
MEDIA_ID_DESC = "MEDIA_ID_DESC",
|
|
169
|
+
SCORE = "SCORE",
|
|
170
|
+
SCORE_DESC = "SCORE_DESC",
|
|
171
|
+
STATUS = "STATUS",
|
|
172
|
+
STATUS_DESC = "STATUS_DESC",
|
|
173
|
+
PROGRESS = "PROGRESS",
|
|
174
|
+
PROGRESS_DESC = "PROGRESS_DESC",
|
|
175
|
+
PROGRESS_VOLUMES = "PROGRESS_VOLUMES",
|
|
176
|
+
PROGRESS_VOLUMES_DESC = "PROGRESS_VOLUMES_DESC",
|
|
177
|
+
REPEAT = "REPEAT",
|
|
178
|
+
REPEAT_DESC = "REPEAT_DESC",
|
|
179
|
+
PRIORITY = "PRIORITY",
|
|
180
|
+
PRIORITY_DESC = "PRIORITY_DESC",
|
|
181
|
+
STARTED_ON = "STARTED_ON",
|
|
182
|
+
STARTED_ON_DESC = "STARTED_ON_DESC",
|
|
183
|
+
FINISHED_ON = "FINISHED_ON",
|
|
184
|
+
FINISHED_ON_DESC = "FINISHED_ON_DESC",
|
|
185
|
+
ADDED_TIME = "ADDED_TIME",
|
|
186
|
+
ADDED_TIME_DESC = "ADDED_TIME_DESC",
|
|
187
|
+
UPDATED_TIME = "UPDATED_TIME",
|
|
188
|
+
UPDATED_TIME_DESC = "UPDATED_TIME_DESC",
|
|
189
|
+
MEDIA_TITLE_ROMAJI = "MEDIA_TITLE_ROMAJI",
|
|
190
|
+
MEDIA_TITLE_ROMAJI_DESC = "MEDIA_TITLE_ROMAJI_DESC",
|
|
191
|
+
MEDIA_TITLE_ENGLISH = "MEDIA_TITLE_ENGLISH",
|
|
192
|
+
MEDIA_TITLE_ENGLISH_DESC = "MEDIA_TITLE_ENGLISH_DESC",
|
|
193
|
+
MEDIA_TITLE_NATIVE = "MEDIA_TITLE_NATIVE",
|
|
194
|
+
MEDIA_TITLE_NATIVE_DESC = "MEDIA_TITLE_NATIVE_DESC",
|
|
195
|
+
MEDIA_POPULARITY = "MEDIA_POPULARITY",
|
|
196
|
+
MEDIA_POPULARITY_DESC = "MEDIA_POPULARITY_DESC"
|
|
197
|
+
}
|
|
198
|
+
interface MediaListEntry {
|
|
199
|
+
id: number;
|
|
200
|
+
mediaId: number;
|
|
201
|
+
status: MediaListStatus;
|
|
202
|
+
score: number | null;
|
|
203
|
+
progress: number | null;
|
|
204
|
+
progressVolumes: number | null;
|
|
205
|
+
repeat: number | null;
|
|
206
|
+
priority: number | null;
|
|
207
|
+
private: boolean | null;
|
|
208
|
+
notes: string | null;
|
|
209
|
+
startedAt: FuzzyDate | null;
|
|
210
|
+
completedAt: FuzzyDate | null;
|
|
211
|
+
updatedAt: number | null;
|
|
212
|
+
createdAt: number | null;
|
|
213
|
+
media: Media;
|
|
214
|
+
}
|
|
215
|
+
interface GetUserMediaListOptions {
|
|
216
|
+
/** User ID (provide either userId or userName) */
|
|
217
|
+
userId?: number;
|
|
218
|
+
/** Username (provide either userId or userName) */
|
|
219
|
+
userName?: string;
|
|
220
|
+
/** ANIME or MANGA */
|
|
221
|
+
type: MediaType;
|
|
222
|
+
/** Filter by list status (CURRENT, COMPLETED, etc.) */
|
|
223
|
+
status?: MediaListStatus;
|
|
224
|
+
/** Sort order */
|
|
225
|
+
sort?: MediaListSort[];
|
|
226
|
+
page?: number;
|
|
227
|
+
perPage?: number;
|
|
129
228
|
}
|
|
130
229
|
|
|
131
230
|
declare enum StaffSort {
|
|
@@ -232,139 +331,6 @@ interface VoiceActor extends Pick<Staff, "id" | "image" | "gender" | "primaryOcc
|
|
|
232
331
|
languageV2: string | null;
|
|
233
332
|
}
|
|
234
333
|
|
|
235
|
-
declare enum CharacterSort {
|
|
236
|
-
ID = "ID",
|
|
237
|
-
ID_DESC = "ID_DESC",
|
|
238
|
-
ROLE = "ROLE",
|
|
239
|
-
ROLE_DESC = "ROLE_DESC",
|
|
240
|
-
SEARCH_MATCH = "SEARCH_MATCH",
|
|
241
|
-
FAVOURITES = "FAVOURITES",
|
|
242
|
-
FAVOURITES_DESC = "FAVOURITES_DESC"
|
|
243
|
-
}
|
|
244
|
-
declare enum CharacterRole {
|
|
245
|
-
MAIN = "MAIN",
|
|
246
|
-
SUPPORTING = "SUPPORTING",
|
|
247
|
-
BACKGROUND = "BACKGROUND"
|
|
248
|
-
}
|
|
249
|
-
interface CharacterName {
|
|
250
|
-
first: string | null;
|
|
251
|
-
middle: string | null;
|
|
252
|
-
last: string | null;
|
|
253
|
-
full: string | null;
|
|
254
|
-
native: string | null;
|
|
255
|
-
alternative: string[];
|
|
256
|
-
}
|
|
257
|
-
interface CharacterImage {
|
|
258
|
-
large: string | null;
|
|
259
|
-
medium: string | null;
|
|
260
|
-
}
|
|
261
|
-
type CharacterMediaNode = Pick<Media, "id" | "title" | "type" | "coverImage" | "siteUrl">;
|
|
262
|
-
interface CharacterMediaEdge {
|
|
263
|
-
node: CharacterMediaNode;
|
|
264
|
-
voiceActors?: VoiceActor[];
|
|
265
|
-
}
|
|
266
|
-
interface Character {
|
|
267
|
-
id: number;
|
|
268
|
-
name: CharacterName;
|
|
269
|
-
image: CharacterImage;
|
|
270
|
-
description: string | null;
|
|
271
|
-
gender: string | null;
|
|
272
|
-
dateOfBirth: FuzzyDate | null;
|
|
273
|
-
age: string | null;
|
|
274
|
-
bloodType: string | null;
|
|
275
|
-
favourites: number | null;
|
|
276
|
-
siteUrl: string | null;
|
|
277
|
-
media: {
|
|
278
|
-
nodes?: CharacterMediaNode[];
|
|
279
|
-
edges?: CharacterMediaEdge[];
|
|
280
|
-
} | null;
|
|
281
|
-
}
|
|
282
|
-
/** Options for including extra data when fetching a character. */
|
|
283
|
-
interface CharacterIncludeOptions {
|
|
284
|
-
/** Include voice actors for each media the character appears in. */
|
|
285
|
-
voiceActors?: boolean;
|
|
286
|
-
}
|
|
287
|
-
interface SearchCharacterOptions {
|
|
288
|
-
query?: string;
|
|
289
|
-
sort?: CharacterSort[];
|
|
290
|
-
page?: number;
|
|
291
|
-
perPage?: number;
|
|
292
|
-
/** Include voice actors for each media the character appears in. */
|
|
293
|
-
voiceActors?: boolean;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
declare enum MediaListStatus {
|
|
297
|
-
CURRENT = "CURRENT",
|
|
298
|
-
PLANNING = "PLANNING",
|
|
299
|
-
COMPLETED = "COMPLETED",
|
|
300
|
-
DROPPED = "DROPPED",
|
|
301
|
-
PAUSED = "PAUSED",
|
|
302
|
-
REPEATING = "REPEATING"
|
|
303
|
-
}
|
|
304
|
-
declare enum MediaListSort {
|
|
305
|
-
MEDIA_ID = "MEDIA_ID",
|
|
306
|
-
MEDIA_ID_DESC = "MEDIA_ID_DESC",
|
|
307
|
-
SCORE = "SCORE",
|
|
308
|
-
SCORE_DESC = "SCORE_DESC",
|
|
309
|
-
STATUS = "STATUS",
|
|
310
|
-
STATUS_DESC = "STATUS_DESC",
|
|
311
|
-
PROGRESS = "PROGRESS",
|
|
312
|
-
PROGRESS_DESC = "PROGRESS_DESC",
|
|
313
|
-
PROGRESS_VOLUMES = "PROGRESS_VOLUMES",
|
|
314
|
-
PROGRESS_VOLUMES_DESC = "PROGRESS_VOLUMES_DESC",
|
|
315
|
-
REPEAT = "REPEAT",
|
|
316
|
-
REPEAT_DESC = "REPEAT_DESC",
|
|
317
|
-
PRIORITY = "PRIORITY",
|
|
318
|
-
PRIORITY_DESC = "PRIORITY_DESC",
|
|
319
|
-
STARTED_ON = "STARTED_ON",
|
|
320
|
-
STARTED_ON_DESC = "STARTED_ON_DESC",
|
|
321
|
-
FINISHED_ON = "FINISHED_ON",
|
|
322
|
-
FINISHED_ON_DESC = "FINISHED_ON_DESC",
|
|
323
|
-
ADDED_TIME = "ADDED_TIME",
|
|
324
|
-
ADDED_TIME_DESC = "ADDED_TIME_DESC",
|
|
325
|
-
UPDATED_TIME = "UPDATED_TIME",
|
|
326
|
-
UPDATED_TIME_DESC = "UPDATED_TIME_DESC",
|
|
327
|
-
MEDIA_TITLE_ROMAJI = "MEDIA_TITLE_ROMAJI",
|
|
328
|
-
MEDIA_TITLE_ROMAJI_DESC = "MEDIA_TITLE_ROMAJI_DESC",
|
|
329
|
-
MEDIA_TITLE_ENGLISH = "MEDIA_TITLE_ENGLISH",
|
|
330
|
-
MEDIA_TITLE_ENGLISH_DESC = "MEDIA_TITLE_ENGLISH_DESC",
|
|
331
|
-
MEDIA_TITLE_NATIVE = "MEDIA_TITLE_NATIVE",
|
|
332
|
-
MEDIA_TITLE_NATIVE_DESC = "MEDIA_TITLE_NATIVE_DESC",
|
|
333
|
-
MEDIA_POPULARITY = "MEDIA_POPULARITY",
|
|
334
|
-
MEDIA_POPULARITY_DESC = "MEDIA_POPULARITY_DESC"
|
|
335
|
-
}
|
|
336
|
-
interface MediaListEntry {
|
|
337
|
-
id: number;
|
|
338
|
-
mediaId: number;
|
|
339
|
-
status: MediaListStatus;
|
|
340
|
-
score: number | null;
|
|
341
|
-
progress: number | null;
|
|
342
|
-
progressVolumes: number | null;
|
|
343
|
-
repeat: number | null;
|
|
344
|
-
priority: number | null;
|
|
345
|
-
private: boolean | null;
|
|
346
|
-
notes: string | null;
|
|
347
|
-
startedAt: FuzzyDate | null;
|
|
348
|
-
completedAt: FuzzyDate | null;
|
|
349
|
-
updatedAt: number | null;
|
|
350
|
-
createdAt: number | null;
|
|
351
|
-
media: Media;
|
|
352
|
-
}
|
|
353
|
-
interface GetUserMediaListOptions {
|
|
354
|
-
/** User ID (provide either userId or userName) */
|
|
355
|
-
userId?: number;
|
|
356
|
-
/** Username (provide either userId or userName) */
|
|
357
|
-
userName?: string;
|
|
358
|
-
/** ANIME or MANGA */
|
|
359
|
-
type: MediaType;
|
|
360
|
-
/** Filter by list status (CURRENT, COMPLETED, etc.) */
|
|
361
|
-
status?: MediaListStatus;
|
|
362
|
-
/** Sort order */
|
|
363
|
-
sort?: MediaListSort[];
|
|
364
|
-
page?: number;
|
|
365
|
-
perPage?: number;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
334
|
interface Studio {
|
|
369
335
|
id: number;
|
|
370
336
|
name: string;
|
|
@@ -394,6 +360,16 @@ interface SearchStudioOptions {
|
|
|
394
360
|
page?: number;
|
|
395
361
|
perPage?: number;
|
|
396
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Options for controlling embedded media when fetching a single studio.
|
|
365
|
+
* Pass `{ media: { perPage: 50 } }` to fetch more media per studio.
|
|
366
|
+
*/
|
|
367
|
+
interface StudioIncludeOptions {
|
|
368
|
+
/** Customize the number of media returned. `true` = 25 (default), or `{ perPage }`. */
|
|
369
|
+
media?: boolean | {
|
|
370
|
+
perPage?: number;
|
|
371
|
+
};
|
|
372
|
+
}
|
|
397
373
|
|
|
398
374
|
declare enum UserSort {
|
|
399
375
|
ID = "ID",
|
|
@@ -485,6 +461,13 @@ interface UserFavorites {
|
|
|
485
461
|
staff: FavoriteStaffNode[];
|
|
486
462
|
studios: FavoriteStudioNode[];
|
|
487
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* Options for controlling the number of results when fetching user favorites.
|
|
466
|
+
*/
|
|
467
|
+
interface UserFavoritesOptions {
|
|
468
|
+
/** Number of items per category (default: 25, max: 50). */
|
|
469
|
+
perPage?: number;
|
|
470
|
+
}
|
|
488
471
|
|
|
489
472
|
declare enum MediaType {
|
|
490
473
|
ANIME = "ANIME",
|
|
@@ -600,6 +583,7 @@ interface MediaTag {
|
|
|
600
583
|
description: string | null;
|
|
601
584
|
category: string | null;
|
|
602
585
|
rank: number | null;
|
|
586
|
+
isAdult: boolean | null;
|
|
603
587
|
isMediaSpoiler: boolean | null;
|
|
604
588
|
}
|
|
605
589
|
declare enum MediaRelationType {
|
|
@@ -841,36 +825,97 @@ interface AiringSchedule {
|
|
|
841
825
|
type DayOfWeek = "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday";
|
|
842
826
|
type WeeklySchedule = Record<DayOfWeek, AiringSchedule[]>;
|
|
843
827
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
828
|
+
declare enum CharacterSort {
|
|
829
|
+
ID = "ID",
|
|
830
|
+
ID_DESC = "ID_DESC",
|
|
831
|
+
ROLE = "ROLE",
|
|
832
|
+
ROLE_DESC = "ROLE_DESC",
|
|
833
|
+
SEARCH_MATCH = "SEARCH_MATCH",
|
|
834
|
+
FAVOURITES = "FAVOURITES",
|
|
835
|
+
FAVOURITES_DESC = "FAVOURITES_DESC"
|
|
836
|
+
}
|
|
837
|
+
declare enum CharacterRole {
|
|
838
|
+
MAIN = "MAIN",
|
|
839
|
+
SUPPORTING = "SUPPORTING",
|
|
840
|
+
BACKGROUND = "BACKGROUND"
|
|
841
|
+
}
|
|
842
|
+
interface CharacterName {
|
|
843
|
+
first: string | null;
|
|
844
|
+
middle: string | null;
|
|
845
|
+
last: string | null;
|
|
846
|
+
full: string | null;
|
|
847
|
+
native: string | null;
|
|
848
|
+
alternative: string[];
|
|
849
|
+
}
|
|
850
|
+
interface CharacterImage {
|
|
851
|
+
large: string | null;
|
|
852
|
+
medium: string | null;
|
|
853
|
+
}
|
|
854
|
+
type CharacterMediaNode = Pick<Media, "id" | "title" | "type" | "coverImage" | "siteUrl">;
|
|
855
|
+
interface CharacterMediaEdge {
|
|
856
|
+
node: CharacterMediaNode;
|
|
857
|
+
voiceActors?: VoiceActor[];
|
|
858
|
+
}
|
|
859
|
+
interface Character {
|
|
860
|
+
id: number;
|
|
861
|
+
name: CharacterName;
|
|
862
|
+
image: CharacterImage;
|
|
863
|
+
description: string | null;
|
|
864
|
+
gender: string | null;
|
|
865
|
+
dateOfBirth: FuzzyDate | null;
|
|
866
|
+
age: string | null;
|
|
867
|
+
bloodType: string | null;
|
|
868
|
+
favourites: number | null;
|
|
869
|
+
siteUrl: string | null;
|
|
870
|
+
media: {
|
|
871
|
+
nodes?: CharacterMediaNode[];
|
|
872
|
+
edges?: CharacterMediaEdge[];
|
|
873
|
+
} | null;
|
|
874
|
+
}
|
|
875
|
+
/** Options for including extra data when fetching a character. */
|
|
876
|
+
interface CharacterIncludeOptions {
|
|
877
|
+
/** Include voice actors for each media the character appears in. */
|
|
878
|
+
voiceActors?: boolean;
|
|
879
|
+
}
|
|
880
|
+
interface SearchCharacterOptions {
|
|
881
|
+
query?: string;
|
|
882
|
+
sort?: CharacterSort[];
|
|
883
|
+
page?: number;
|
|
884
|
+
perPage?: number;
|
|
885
|
+
/** Include voice actors for each media the character appears in. */
|
|
886
|
+
voiceActors?: boolean;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/** Represents a forum thread on AniList. */
|
|
890
|
+
interface Thread {
|
|
891
|
+
id: number;
|
|
892
|
+
title: string;
|
|
893
|
+
body: string | null;
|
|
894
|
+
userId: number;
|
|
895
|
+
replyUserId: number | null;
|
|
896
|
+
replyCommentId: number | null;
|
|
897
|
+
replyCount: number;
|
|
898
|
+
viewCount: number;
|
|
899
|
+
isLocked: boolean;
|
|
900
|
+
isSticky: boolean;
|
|
901
|
+
isSubscribed: boolean;
|
|
902
|
+
repliedAt: number | null;
|
|
903
|
+
createdAt: number;
|
|
904
|
+
updatedAt: number;
|
|
905
|
+
siteUrl: string | null;
|
|
906
|
+
user: {
|
|
907
|
+
id: number;
|
|
908
|
+
name: string;
|
|
909
|
+
avatar: UserAvatar;
|
|
910
|
+
} | null;
|
|
911
|
+
replyUser: {
|
|
912
|
+
id: number;
|
|
913
|
+
name: string;
|
|
914
|
+
avatar: UserAvatar;
|
|
915
|
+
} | null;
|
|
916
|
+
categories: ThreadCategory[] | null;
|
|
917
|
+
mediaCategories: ThreadMediaCategory[] | null;
|
|
918
|
+
likes: {
|
|
874
919
|
id: number;
|
|
875
920
|
name: string;
|
|
876
921
|
}[] | null;
|
|
@@ -921,6 +966,145 @@ interface SearchThreadOptions {
|
|
|
921
966
|
perPage?: number;
|
|
922
967
|
}
|
|
923
968
|
|
|
969
|
+
/** Cache performance statistics. */
|
|
970
|
+
interface CacheStats {
|
|
971
|
+
/** Total cache hits. */
|
|
972
|
+
hits: number;
|
|
973
|
+
/** Total cache misses. */
|
|
974
|
+
misses: number;
|
|
975
|
+
/** Stale entries returned (only with stale-while-revalidate). */
|
|
976
|
+
stales: number;
|
|
977
|
+
/** Hit rate as a ratio 0–1 (NaN if no requests yet). */
|
|
978
|
+
hitRate: number;
|
|
979
|
+
}
|
|
980
|
+
declare class MemoryCache implements CacheAdapter {
|
|
981
|
+
private readonly ttl;
|
|
982
|
+
private readonly maxSize;
|
|
983
|
+
private readonly enabled;
|
|
984
|
+
private readonly swrMs;
|
|
985
|
+
private readonly store;
|
|
986
|
+
private _hits;
|
|
987
|
+
private _misses;
|
|
988
|
+
private _stales;
|
|
989
|
+
constructor(options?: CacheOptions);
|
|
990
|
+
/** Build a deterministic cache key from a query + variables pair. */
|
|
991
|
+
static key(query: string, variables: Record<string, unknown>): string;
|
|
992
|
+
/**
|
|
993
|
+
* Retrieve a cached value, or `undefined` if missing / expired.
|
|
994
|
+
* With stale-while-revalidate enabled, returns stale data within the grace window
|
|
995
|
+
* and flags it so the caller can refresh in the background.
|
|
996
|
+
*/
|
|
997
|
+
get<T>(key: string): T | undefined;
|
|
998
|
+
/** Store a value in the cache. */
|
|
999
|
+
set<T>(key: string, data: T): void;
|
|
1000
|
+
/** Remove a specific entry. */
|
|
1001
|
+
delete(key: string): boolean;
|
|
1002
|
+
/** Clear the entire cache and reset statistics. */
|
|
1003
|
+
clear(): void;
|
|
1004
|
+
/** Number of entries currently stored. */
|
|
1005
|
+
get size(): number | Promise<number>;
|
|
1006
|
+
/** Return all cache keys. */
|
|
1007
|
+
keys(): string[];
|
|
1008
|
+
/**
|
|
1009
|
+
* Get cache performance statistics.
|
|
1010
|
+
*
|
|
1011
|
+
* @example
|
|
1012
|
+
* ```ts
|
|
1013
|
+
* const cache = new MemoryCache();
|
|
1014
|
+
* // ... after some usage ...
|
|
1015
|
+
* console.log(cache.stats);
|
|
1016
|
+
* // { hits: 42, misses: 8, stales: 0, hitRate: 0.84 }
|
|
1017
|
+
* ```
|
|
1018
|
+
*/
|
|
1019
|
+
get stats(): CacheStats;
|
|
1020
|
+
/** Reset cache statistics without clearing stored data. */
|
|
1021
|
+
resetStats(): void;
|
|
1022
|
+
/**
|
|
1023
|
+
* Remove all entries whose key matches the given pattern.
|
|
1024
|
+
*
|
|
1025
|
+
* - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
|
|
1026
|
+
* - **RegExp**: tested against each key directly.
|
|
1027
|
+
*
|
|
1028
|
+
* @param pattern — A string (substring match) or RegExp.
|
|
1029
|
+
* @returns Number of entries removed.
|
|
1030
|
+
*/
|
|
1031
|
+
invalidate(pattern: string | RegExp): number;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Minimal interface representing a Redis client.
|
|
1036
|
+
* Compatible with both `ioredis` and `redis` (node-redis v4+).
|
|
1037
|
+
*/
|
|
1038
|
+
interface RedisLikeClient {
|
|
1039
|
+
get(key: string): Promise<string | null>;
|
|
1040
|
+
set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
|
|
1041
|
+
del(...keys: (string | string[])[]): Promise<number>;
|
|
1042
|
+
keys(pattern: string): Promise<string[]>;
|
|
1043
|
+
/** Optional SCAN-based iteration — used when available to avoid blocking the server. */
|
|
1044
|
+
scanIterator?(options: {
|
|
1045
|
+
MATCH: string;
|
|
1046
|
+
COUNT?: number;
|
|
1047
|
+
}): AsyncIterable<string>;
|
|
1048
|
+
}
|
|
1049
|
+
interface RedisCacheOptions {
|
|
1050
|
+
/** A Redis client instance (ioredis or node-redis). */
|
|
1051
|
+
client: RedisLikeClient;
|
|
1052
|
+
/** Key prefix to namespace ani-client entries (default: `"ani:"`) */
|
|
1053
|
+
prefix?: string;
|
|
1054
|
+
/** TTL in seconds (default: 86 400 = 24 h) */
|
|
1055
|
+
ttl?: number;
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* Redis-backed cache adapter for AniListClient.
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
* ```ts
|
|
1062
|
+
* import Redis from "ioredis";
|
|
1063
|
+
* import { AniListClient, RedisCache } from "ani-client";
|
|
1064
|
+
*
|
|
1065
|
+
* const redis = new Redis();
|
|
1066
|
+
* const client = new AniListClient({
|
|
1067
|
+
* cacheAdapter: new RedisCache({ client: redis }),
|
|
1068
|
+
* });
|
|
1069
|
+
* ```
|
|
1070
|
+
*/
|
|
1071
|
+
declare class RedisCache implements CacheAdapter {
|
|
1072
|
+
private readonly client;
|
|
1073
|
+
private readonly prefix;
|
|
1074
|
+
private readonly ttl;
|
|
1075
|
+
constructor(options: RedisCacheOptions);
|
|
1076
|
+
private prefixedKey;
|
|
1077
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
1078
|
+
set<T>(key: string, data: T): Promise<void>;
|
|
1079
|
+
delete(key: string): Promise<boolean>;
|
|
1080
|
+
/**
|
|
1081
|
+
* Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.
|
|
1082
|
+
*
|
|
1083
|
+
* **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.
|
|
1084
|
+
* Provide a client with `scanIterator` support for production use.
|
|
1085
|
+
* @internal
|
|
1086
|
+
*/
|
|
1087
|
+
private collectKeys;
|
|
1088
|
+
clear(): Promise<void>;
|
|
1089
|
+
/**
|
|
1090
|
+
* Get the actual number of keys with this prefix in Redis.
|
|
1091
|
+
*/
|
|
1092
|
+
get size(): Promise<number>;
|
|
1093
|
+
/** @internal */
|
|
1094
|
+
private getSize;
|
|
1095
|
+
keys(): Promise<string[]>;
|
|
1096
|
+
/**
|
|
1097
|
+
* Remove all entries whose key matches the given pattern.
|
|
1098
|
+
*
|
|
1099
|
+
* - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
|
|
1100
|
+
* - **RegExp**: tested against each key directly.
|
|
1101
|
+
*
|
|
1102
|
+
* @param pattern — A string (substring match) or RegExp.
|
|
1103
|
+
* @returns Number of entries removed.
|
|
1104
|
+
*/
|
|
1105
|
+
invalidate(pattern: string | RegExp): Promise<number>;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
924
1108
|
/**
|
|
925
1109
|
* Lightweight AniList GraphQL client with built-in caching and rate limiting.
|
|
926
1110
|
*
|
|
@@ -945,6 +1129,7 @@ declare class AniListClient {
|
|
|
945
1129
|
private readonly cacheAdapter;
|
|
946
1130
|
private readonly rateLimiter;
|
|
947
1131
|
private readonly hooks;
|
|
1132
|
+
private readonly logger?;
|
|
948
1133
|
private readonly signal?;
|
|
949
1134
|
private readonly inFlight;
|
|
950
1135
|
private _rateLimitInfo?;
|
|
@@ -1000,6 +1185,13 @@ declare class AniListClient {
|
|
|
1000
1185
|
* @deprecated Use `getRecentlyUpdatedManga` instead. This alias will be removed in v2.
|
|
1001
1186
|
*/
|
|
1002
1187
|
getAiredChapters(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
|
|
1188
|
+
/**
|
|
1189
|
+
* Fetch a media entry by its MyAnimeList (MAL) ID.
|
|
1190
|
+
*
|
|
1191
|
+
* @param malId - The MyAnimeList ID
|
|
1192
|
+
* @param type - Optional media type to disambiguate (some MAL IDs map to both ANIME and MANGA)
|
|
1193
|
+
*/
|
|
1194
|
+
getMediaByMalId(malId: number, type?: MediaType): Promise<Media>;
|
|
1003
1195
|
/** Get the detailed schedule for the current week, sorted by day. */
|
|
1004
1196
|
getWeeklySchedule(date?: Date): Promise<WeeklySchedule>;
|
|
1005
1197
|
/** Get upcoming (not yet released) media. */
|
|
@@ -1030,17 +1222,29 @@ declare class AniListClient {
|
|
|
1030
1222
|
* Fetch a user's favorite anime, manga, characters, staff, and studios.
|
|
1031
1223
|
*
|
|
1032
1224
|
* @param idOrName - AniList user ID (number) or username (string)
|
|
1225
|
+
* @param options - Optional pagination options (perPage per category)
|
|
1033
1226
|
* @returns The user's favorites grouped by category
|
|
1034
1227
|
*
|
|
1035
1228
|
* @example
|
|
1036
1229
|
* ```typescript
|
|
1037
1230
|
* const favs = await client.getUserFavorites("AniList");
|
|
1038
1231
|
* favs.anime.forEach(a => console.log(a.title.romaji));
|
|
1232
|
+
*
|
|
1233
|
+
* // Fetch more results per category
|
|
1234
|
+
* const moreResults = await client.getUserFavorites(1, { perPage: 50 });
|
|
1235
|
+
* ```
|
|
1236
|
+
*/
|
|
1237
|
+
getUserFavorites(idOrName: number | string, options?: UserFavoritesOptions): Promise<UserFavorites>;
|
|
1238
|
+
/**
|
|
1239
|
+
* Fetch a studio by its AniList ID.
|
|
1240
|
+
* Pass `include` to customise the number of media returned.
|
|
1241
|
+
*
|
|
1242
|
+
* @example
|
|
1243
|
+
* ```typescript
|
|
1244
|
+
* const studio = await client.getStudio(21, { media: { perPage: 50 } });
|
|
1039
1245
|
* ```
|
|
1040
1246
|
*/
|
|
1041
|
-
|
|
1042
|
-
/** Fetch a studio by its AniList ID. */
|
|
1043
|
-
getStudio(id: number): Promise<Studio>;
|
|
1247
|
+
getStudio(id: number, include?: StudioIncludeOptions): Promise<Studio>;
|
|
1044
1248
|
/** Search for studios by name. */
|
|
1045
1249
|
searchStudios(options?: SearchStudioOptions): Promise<PagedResult<Studio>>;
|
|
1046
1250
|
/** Fetch a forum thread by its AniList ID. */
|
|
@@ -1076,6 +1280,20 @@ declare class AniListClient {
|
|
|
1076
1280
|
invalidateCache(pattern: string | RegExp): Promise<number>;
|
|
1077
1281
|
/** Clean up resources held by the client. */
|
|
1078
1282
|
destroy(): Promise<void>;
|
|
1283
|
+
/**
|
|
1284
|
+
* Return a scoped view of this client where every request uses the given `AbortSignal`.
|
|
1285
|
+
* The returned object shares the same cache, rate limiter, and hooks.
|
|
1286
|
+
*
|
|
1287
|
+
* @example
|
|
1288
|
+
* ```ts
|
|
1289
|
+
* const controller = new AbortController();
|
|
1290
|
+
* const media = await client.withSignal(controller.signal).getMedia(1);
|
|
1291
|
+
*
|
|
1292
|
+
* // Cancel all in-flight requests made through the scoped view
|
|
1293
|
+
* controller.abort();
|
|
1294
|
+
* ```
|
|
1295
|
+
*/
|
|
1296
|
+
withSignal(signal: AbortSignal): AniListClient;
|
|
1079
1297
|
}
|
|
1080
1298
|
|
|
1081
1299
|
/**
|
|
@@ -1089,109 +1307,6 @@ declare class AniListError extends Error {
|
|
|
1089
1307
|
constructor(message: string, status: number, errors?: unknown[]);
|
|
1090
1308
|
}
|
|
1091
1309
|
|
|
1092
|
-
declare class MemoryCache implements CacheAdapter {
|
|
1093
|
-
private readonly ttl;
|
|
1094
|
-
private readonly maxSize;
|
|
1095
|
-
private readonly enabled;
|
|
1096
|
-
private readonly store;
|
|
1097
|
-
constructor(options?: CacheOptions);
|
|
1098
|
-
/** Build a deterministic cache key from a query + variables pair. */
|
|
1099
|
-
static key(query: string, variables: Record<string, unknown>): string;
|
|
1100
|
-
/** Retrieve a cached value, or `undefined` if missing / expired. */
|
|
1101
|
-
get<T>(key: string): T | undefined;
|
|
1102
|
-
/** Store a value in the cache. */
|
|
1103
|
-
set<T>(key: string, data: T): void;
|
|
1104
|
-
/** Remove a specific entry. */
|
|
1105
|
-
delete(key: string): boolean;
|
|
1106
|
-
/** Clear the entire cache. */
|
|
1107
|
-
clear(): void;
|
|
1108
|
-
/** Number of entries currently stored. */
|
|
1109
|
-
get size(): number | Promise<number>;
|
|
1110
|
-
/** Return all cache keys. */
|
|
1111
|
-
keys(): string[];
|
|
1112
|
-
/**
|
|
1113
|
-
* Remove all entries whose key matches the given pattern.
|
|
1114
|
-
*
|
|
1115
|
-
* - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
|
|
1116
|
-
* - **RegExp**: tested against each key directly.
|
|
1117
|
-
*
|
|
1118
|
-
* @param pattern — A string (substring match) or RegExp.
|
|
1119
|
-
* @returns Number of entries removed.
|
|
1120
|
-
*/
|
|
1121
|
-
invalidate(pattern: string | RegExp): number;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
/**
|
|
1125
|
-
* Minimal interface representing a Redis client.
|
|
1126
|
-
* Compatible with both `ioredis` and `redis` (node-redis v4+).
|
|
1127
|
-
*/
|
|
1128
|
-
interface RedisLikeClient {
|
|
1129
|
-
get(key: string): Promise<string | null>;
|
|
1130
|
-
set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
|
|
1131
|
-
del(...keys: (string | string[])[]): Promise<number>;
|
|
1132
|
-
keys(pattern: string): Promise<string[]>;
|
|
1133
|
-
/** Optional SCAN-based iteration — used when available to avoid blocking the server. */
|
|
1134
|
-
scanIterator?(options: {
|
|
1135
|
-
MATCH: string;
|
|
1136
|
-
COUNT?: number;
|
|
1137
|
-
}): AsyncIterable<string>;
|
|
1138
|
-
}
|
|
1139
|
-
interface RedisCacheOptions {
|
|
1140
|
-
/** A Redis client instance (ioredis or node-redis). */
|
|
1141
|
-
client: RedisLikeClient;
|
|
1142
|
-
/** Key prefix to namespace ani-client entries (default: `"ani:"`) */
|
|
1143
|
-
prefix?: string;
|
|
1144
|
-
/** TTL in seconds (default: 86 400 = 24 h) */
|
|
1145
|
-
ttl?: number;
|
|
1146
|
-
}
|
|
1147
|
-
/**
|
|
1148
|
-
* Redis-backed cache adapter for AniListClient.
|
|
1149
|
-
*
|
|
1150
|
-
* @example
|
|
1151
|
-
* ```ts
|
|
1152
|
-
* import Redis from "ioredis";
|
|
1153
|
-
* import { AniListClient, RedisCache } from "ani-client";
|
|
1154
|
-
*
|
|
1155
|
-
* const redis = new Redis();
|
|
1156
|
-
* const client = new AniListClient({
|
|
1157
|
-
* cacheAdapter: new RedisCache({ client: redis }),
|
|
1158
|
-
* });
|
|
1159
|
-
* ```
|
|
1160
|
-
*/
|
|
1161
|
-
declare class RedisCache implements CacheAdapter {
|
|
1162
|
-
private readonly client;
|
|
1163
|
-
private readonly prefix;
|
|
1164
|
-
private readonly ttl;
|
|
1165
|
-
constructor(options: RedisCacheOptions);
|
|
1166
|
-
private prefixedKey;
|
|
1167
|
-
get<T>(key: string): Promise<T | undefined>;
|
|
1168
|
-
set<T>(key: string, data: T): Promise<void>;
|
|
1169
|
-
delete(key: string): Promise<boolean>;
|
|
1170
|
-
/**
|
|
1171
|
-
* Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.
|
|
1172
|
-
*
|
|
1173
|
-
* **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.
|
|
1174
|
-
* Provide a client with `scanIterator` support for production use.
|
|
1175
|
-
* @internal
|
|
1176
|
-
*/
|
|
1177
|
-
private collectKeys;
|
|
1178
|
-
clear(): Promise<void>;
|
|
1179
|
-
/**
|
|
1180
|
-
* Get the actual number of keys with this prefix in Redis.
|
|
1181
|
-
*/
|
|
1182
|
-
get size(): Promise<number>;
|
|
1183
|
-
/** @internal */
|
|
1184
|
-
private getSize;
|
|
1185
|
-
keys(): Promise<string[]>;
|
|
1186
|
-
/**
|
|
1187
|
-
* Remove all entries whose key matches the given glob pattern.
|
|
1188
|
-
*
|
|
1189
|
-
* @param pattern — A glob pattern (e.g. `"*Media*"`)
|
|
1190
|
-
* @returns Number of entries removed.
|
|
1191
|
-
*/
|
|
1192
|
-
invalidate(pattern: string | RegExp): Promise<number>;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
1310
|
/**
|
|
1196
1311
|
* Rate limiter with automatic retry for AniList API.
|
|
1197
1312
|
*
|
|
@@ -1239,4 +1354,4 @@ declare class RateLimiter {
|
|
|
1239
1354
|
|
|
1240
1355
|
declare function parseAniListMarkdown(text: string): string;
|
|
1241
1356
|
|
|
1242
|
-
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FavoriteCharacterNode, type FavoriteMediaNode, type FavoriteStaffNode, type FavoriteStudioNode, 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, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitInfo, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ResponseMeta, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, StudioSort, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
|
|
1357
|
+
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type CacheStats, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FavoriteCharacterNode, type FavoriteMediaNode, type FavoriteStaffNode, type FavoriteStudioNode, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Logger, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitInfo, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ResponseMeta, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioIncludeOptions, StudioSort, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, type UserFavoritesOptions, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
|