ani-client 1.8.0 → 1.9.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 +1 -3
- package/dist/index.d.mts +328 -323
- package/dist/index.d.ts +328 -323
- package/dist/index.js +384 -357
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +384 -357
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -6
package/dist/index.js
CHANGED
|
@@ -250,6 +250,95 @@ var MemoryCache = class {
|
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
|
|
253
|
+
// src/cache/redis.ts
|
|
254
|
+
var RedisCache = class {
|
|
255
|
+
client;
|
|
256
|
+
prefix;
|
|
257
|
+
ttl;
|
|
258
|
+
constructor(options) {
|
|
259
|
+
this.client = options.client;
|
|
260
|
+
this.prefix = options.prefix ?? "ani:";
|
|
261
|
+
this.ttl = options.ttl ?? 86400;
|
|
262
|
+
}
|
|
263
|
+
prefixedKey(key) {
|
|
264
|
+
return `${this.prefix}${key}`;
|
|
265
|
+
}
|
|
266
|
+
async get(key) {
|
|
267
|
+
const raw = await this.client.get(this.prefixedKey(key));
|
|
268
|
+
if (raw === null) return void 0;
|
|
269
|
+
try {
|
|
270
|
+
return JSON.parse(raw);
|
|
271
|
+
} catch {
|
|
272
|
+
return void 0;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async set(key, data) {
|
|
276
|
+
await this.client.set(this.prefixedKey(key), JSON.stringify(data), "EX", this.ttl);
|
|
277
|
+
}
|
|
278
|
+
async delete(key) {
|
|
279
|
+
const count = await this.client.del(this.prefixedKey(key));
|
|
280
|
+
return count > 0;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.
|
|
284
|
+
*
|
|
285
|
+
* **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.
|
|
286
|
+
* Provide a client with `scanIterator` support for production use.
|
|
287
|
+
* @internal
|
|
288
|
+
*/
|
|
289
|
+
async collectKeys(pattern) {
|
|
290
|
+
if (this.client.scanIterator) {
|
|
291
|
+
const keys = [];
|
|
292
|
+
for await (const key of this.client.scanIterator({ MATCH: pattern, COUNT: 100 })) {
|
|
293
|
+
keys.push(key);
|
|
294
|
+
}
|
|
295
|
+
return keys;
|
|
296
|
+
}
|
|
297
|
+
return this.client.keys(pattern);
|
|
298
|
+
}
|
|
299
|
+
async clear() {
|
|
300
|
+
const keys = await this.collectKeys(`${this.prefix}*`);
|
|
301
|
+
if (keys.length > 0) {
|
|
302
|
+
await this.client.del(...keys);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Get the actual number of keys with this prefix in Redis.
|
|
307
|
+
*/
|
|
308
|
+
get size() {
|
|
309
|
+
return this.getSize();
|
|
310
|
+
}
|
|
311
|
+
/** @internal */
|
|
312
|
+
async getSize() {
|
|
313
|
+
const keys = await this.collectKeys(`${this.prefix}*`);
|
|
314
|
+
return keys.length;
|
|
315
|
+
}
|
|
316
|
+
async keys() {
|
|
317
|
+
const raw = await this.collectKeys(`${this.prefix}*`);
|
|
318
|
+
return raw.map((k) => k.slice(this.prefix.length));
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Remove all entries whose key matches the given pattern.
|
|
322
|
+
*
|
|
323
|
+
* - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
|
|
324
|
+
* - **RegExp**: tested against each key directly.
|
|
325
|
+
*
|
|
326
|
+
* @param pattern — A string (substring match) or RegExp.
|
|
327
|
+
* @returns Number of entries removed.
|
|
328
|
+
*/
|
|
329
|
+
async invalidate(pattern) {
|
|
330
|
+
if (typeof pattern === "string") {
|
|
331
|
+
const keys = await this.collectKeys(`${this.prefix}*${pattern}*`);
|
|
332
|
+
if (keys.length === 0) return 0;
|
|
333
|
+
return this.client.del(...keys);
|
|
334
|
+
}
|
|
335
|
+
const allKeys = await this.collectKeys(`${this.prefix}*`);
|
|
336
|
+
const matching = allKeys.filter((k) => pattern.test(k.slice(this.prefix.length)));
|
|
337
|
+
if (matching.length === 0) return 0;
|
|
338
|
+
return this.client.del(...matching);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
253
342
|
// src/errors/index.ts
|
|
254
343
|
var AniListError = class _AniListError extends Error {
|
|
255
344
|
/** HTTP status code returned by the API */
|
|
@@ -624,8 +713,10 @@ query ($id: Int!) {
|
|
|
624
713
|
var QUERY_MEDIA_SEARCH = `
|
|
625
714
|
query (
|
|
626
715
|
$search: String,
|
|
716
|
+
$countryOfOrigin: CountryCode,
|
|
627
717
|
$type: MediaType,
|
|
628
718
|
$format: MediaFormat,
|
|
719
|
+
$format_in: [MediaFormat],
|
|
629
720
|
$status: MediaStatus,
|
|
630
721
|
$season: MediaSeason,
|
|
631
722
|
$seasonYear: Int,
|
|
@@ -644,8 +735,10 @@ query (
|
|
|
644
735
|
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
645
736
|
media(
|
|
646
737
|
search: $search,
|
|
738
|
+
countryOfOrigin: $countryOfOrigin,
|
|
647
739
|
type: $type,
|
|
648
740
|
format: $format,
|
|
741
|
+
format_in: $format_in,
|
|
649
742
|
status: $status,
|
|
650
743
|
season: $season,
|
|
651
744
|
seasonYear: $seasonYear,
|
|
@@ -755,6 +848,111 @@ query ($mediaId: Int!, $page: Int, $perPage: Int, $sort: [RecommendationSort]) {
|
|
|
755
848
|
}
|
|
756
849
|
}`;
|
|
757
850
|
|
|
851
|
+
// src/queries/builders.ts
|
|
852
|
+
function buildMediaByIdQuery(include) {
|
|
853
|
+
if (!include) return QUERY_MEDIA_BY_ID;
|
|
854
|
+
const extra = [];
|
|
855
|
+
if (include.relations !== false) {
|
|
856
|
+
extra.push(RELATIONS_FIELDS);
|
|
857
|
+
}
|
|
858
|
+
if (include.characters) {
|
|
859
|
+
const opts = typeof include.characters === "object" ? include.characters : {};
|
|
860
|
+
const perPage = clampPerPage(opts.perPage ?? 25);
|
|
861
|
+
const sortClause = opts.sort !== false ? ", sort: [ROLE, RELEVANCE, ID]" : "";
|
|
862
|
+
const voiceActorBlock = opts.voiceActors ? `
|
|
863
|
+
voiceActors {
|
|
864
|
+
${VOICE_ACTOR_FIELDS_COMPACT}
|
|
865
|
+
}` : "";
|
|
866
|
+
extra.push(`
|
|
867
|
+
characters(perPage: ${perPage}${sortClause}) {
|
|
868
|
+
edges {
|
|
869
|
+
role
|
|
870
|
+
node {
|
|
871
|
+
${CHARACTER_FIELDS_COMPACT}
|
|
872
|
+
}${voiceActorBlock}
|
|
873
|
+
}
|
|
874
|
+
}`);
|
|
875
|
+
}
|
|
876
|
+
if (include.staff) {
|
|
877
|
+
const opts = typeof include.staff === "object" ? include.staff : {};
|
|
878
|
+
const perPage = clampPerPage(opts.perPage ?? 25);
|
|
879
|
+
const sortClause = opts.sort !== false ? ", sort: [RELEVANCE, ID]" : "";
|
|
880
|
+
extra.push(`
|
|
881
|
+
staff(perPage: ${perPage}${sortClause}) {
|
|
882
|
+
edges {
|
|
883
|
+
role
|
|
884
|
+
node {
|
|
885
|
+
${STAFF_FIELDS}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}`);
|
|
889
|
+
}
|
|
890
|
+
if (include.recommendations) {
|
|
891
|
+
const perPage = clampPerPage(
|
|
892
|
+
typeof include.recommendations === "object" ? include.recommendations.perPage ?? 10 : 10
|
|
893
|
+
);
|
|
894
|
+
extra.push(`
|
|
895
|
+
recommendations(perPage: ${perPage}, sort: [RATING_DESC]) {
|
|
896
|
+
nodes {
|
|
897
|
+
id
|
|
898
|
+
rating
|
|
899
|
+
mediaRecommendation {
|
|
900
|
+
id
|
|
901
|
+
title { romaji english native userPreferred }
|
|
902
|
+
type
|
|
903
|
+
format
|
|
904
|
+
coverImage { large medium }
|
|
905
|
+
averageScore
|
|
906
|
+
siteUrl
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}`);
|
|
910
|
+
}
|
|
911
|
+
if (include.streamingEpisodes) {
|
|
912
|
+
extra.push(`
|
|
913
|
+
streamingEpisodes {
|
|
914
|
+
title
|
|
915
|
+
thumbnail
|
|
916
|
+
url
|
|
917
|
+
site
|
|
918
|
+
}`);
|
|
919
|
+
}
|
|
920
|
+
if (include.externalLinks) {
|
|
921
|
+
extra.push(`
|
|
922
|
+
externalLinks {
|
|
923
|
+
id
|
|
924
|
+
url
|
|
925
|
+
site
|
|
926
|
+
type
|
|
927
|
+
icon
|
|
928
|
+
color
|
|
929
|
+
}`);
|
|
930
|
+
}
|
|
931
|
+
if (include.stats) {
|
|
932
|
+
extra.push(`
|
|
933
|
+
stats {
|
|
934
|
+
scoreDistribution { score amount }
|
|
935
|
+
statusDistribution { status amount }
|
|
936
|
+
}`);
|
|
937
|
+
}
|
|
938
|
+
return `
|
|
939
|
+
query ($id: Int!) {
|
|
940
|
+
Media(id: $id) {
|
|
941
|
+
${MEDIA_FIELDS_BASE}
|
|
942
|
+
${extra.join("\n")}
|
|
943
|
+
}
|
|
944
|
+
}`;
|
|
945
|
+
}
|
|
946
|
+
function buildBatchQuery(ids, typeName, fields, prefix) {
|
|
947
|
+
const aliases = ids.map((id, i) => `${prefix}${i}: ${typeName}(id: ${id}) { ${fields} }`).join("\n ");
|
|
948
|
+
return `query {
|
|
949
|
+
${aliases}
|
|
950
|
+
}`;
|
|
951
|
+
}
|
|
952
|
+
var buildBatchMediaQuery = (ids) => buildBatchQuery(ids, "Media", MEDIA_FIELDS, "m");
|
|
953
|
+
var buildBatchCharacterQuery = (ids) => buildBatchQuery(ids, "Character", CHARACTER_FIELDS, "c");
|
|
954
|
+
var buildBatchStaffQuery = (ids) => buildBatchQuery(ids, "Staff", STAFF_FIELDS, "s");
|
|
955
|
+
|
|
758
956
|
// src/queries/character.ts
|
|
759
957
|
var QUERY_CHARACTER_BY_ID = `
|
|
760
958
|
query ($id: Int!) {
|
|
@@ -787,6 +985,22 @@ query ($search: String, $sort: [CharacterSort], $page: Int, $perPage: Int) {
|
|
|
787
985
|
}
|
|
788
986
|
}`;
|
|
789
987
|
|
|
988
|
+
// src/queries/metadata.ts
|
|
989
|
+
var QUERY_GENRES = `
|
|
990
|
+
query {
|
|
991
|
+
GenreCollection
|
|
992
|
+
}`;
|
|
993
|
+
var QUERY_TAGS = `
|
|
994
|
+
query {
|
|
995
|
+
MediaTagCollection {
|
|
996
|
+
id
|
|
997
|
+
name
|
|
998
|
+
description
|
|
999
|
+
category
|
|
1000
|
+
isAdult
|
|
1001
|
+
}
|
|
1002
|
+
}`;
|
|
1003
|
+
|
|
790
1004
|
// src/queries/staff.ts
|
|
791
1005
|
var QUERY_STAFF_BY_ID = `
|
|
792
1006
|
query ($id: Int!) {
|
|
@@ -811,6 +1025,60 @@ query ($search: String, $sort: [StaffSort], $page: Int, $perPage: Int) {
|
|
|
811
1025
|
}
|
|
812
1026
|
}`;
|
|
813
1027
|
|
|
1028
|
+
// src/queries/studio.ts
|
|
1029
|
+
var QUERY_STUDIO_BY_ID = `
|
|
1030
|
+
query ($id: Int!) {
|
|
1031
|
+
Studio(id: $id) {
|
|
1032
|
+
${STUDIO_FIELDS}
|
|
1033
|
+
}
|
|
1034
|
+
}`;
|
|
1035
|
+
function buildStudioByIdQuery(mediaPerPage) {
|
|
1036
|
+
if (mediaPerPage === void 0) return QUERY_STUDIO_BY_ID;
|
|
1037
|
+
const pp = clampPerPage(mediaPerPage);
|
|
1038
|
+
return `
|
|
1039
|
+
query ($id: Int!) {
|
|
1040
|
+
Studio(id: $id) {
|
|
1041
|
+
id
|
|
1042
|
+
name
|
|
1043
|
+
isAnimationStudio
|
|
1044
|
+
siteUrl
|
|
1045
|
+
favourites
|
|
1046
|
+
media(page: 1, perPage: ${pp}, sort: POPULARITY_DESC) {
|
|
1047
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1048
|
+
nodes {
|
|
1049
|
+
${MEDIA_FIELDS_LIGHT}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}`;
|
|
1054
|
+
}
|
|
1055
|
+
var QUERY_STUDIO_SEARCH = `
|
|
1056
|
+
query ($search: String, $sort: [StudioSort], $page: Int, $perPage: Int) {
|
|
1057
|
+
Page(page: $page, perPage: $perPage) {
|
|
1058
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1059
|
+
studios(search: $search, sort: $sort) {
|
|
1060
|
+
${STUDIO_FIELDS}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}`;
|
|
1064
|
+
|
|
1065
|
+
// src/queries/thread.ts
|
|
1066
|
+
var QUERY_THREAD_BY_ID = `
|
|
1067
|
+
query ($id: Int!) {
|
|
1068
|
+
Thread(id: $id) {
|
|
1069
|
+
${THREAD_FIELDS}
|
|
1070
|
+
}
|
|
1071
|
+
}`;
|
|
1072
|
+
var QUERY_THREAD_SEARCH = `
|
|
1073
|
+
query ($search: String, $mediaCategoryId: Int, $categoryId: Int, $sort: [ThreadSort], $page: Int, $perPage: Int) {
|
|
1074
|
+
Page(page: $page, perPage: $perPage) {
|
|
1075
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1076
|
+
threads(search: $search, mediaCategoryId: $mediaCategoryId, categoryId: $categoryId, sort: $sort) {
|
|
1077
|
+
${THREAD_FIELDS}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}`;
|
|
1081
|
+
|
|
814
1082
|
// src/queries/user.ts
|
|
815
1083
|
var QUERY_USER_BY_ID = `
|
|
816
1084
|
query ($id: Int!) {
|
|
@@ -897,199 +1165,24 @@ query (${varDecl}) {
|
|
|
897
1165
|
}
|
|
898
1166
|
}
|
|
899
1167
|
staff(perPage: ${pp}) {
|
|
900
|
-
nodes {
|
|
901
|
-
id
|
|
902
|
-
name { full native }
|
|
903
|
-
image { large medium }
|
|
904
|
-
siteUrl
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
studios(perPage: ${pp}) {
|
|
908
|
-
nodes {
|
|
909
|
-
id
|
|
910
|
-
name
|
|
911
|
-
siteUrl
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}`;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
// src/queries/studio.ts
|
|
920
|
-
var QUERY_STUDIO_BY_ID = `
|
|
921
|
-
query ($id: Int!) {
|
|
922
|
-
Studio(id: $id) {
|
|
923
|
-
${STUDIO_FIELDS}
|
|
924
|
-
}
|
|
925
|
-
}`;
|
|
926
|
-
function buildStudioByIdQuery(mediaPerPage) {
|
|
927
|
-
if (mediaPerPage === void 0) return QUERY_STUDIO_BY_ID;
|
|
928
|
-
const pp = clampPerPage(mediaPerPage);
|
|
929
|
-
return `
|
|
930
|
-
query ($id: Int!) {
|
|
931
|
-
Studio(id: $id) {
|
|
932
|
-
id
|
|
933
|
-
name
|
|
934
|
-
isAnimationStudio
|
|
935
|
-
siteUrl
|
|
936
|
-
favourites
|
|
937
|
-
media(page: 1, perPage: ${pp}, sort: POPULARITY_DESC) {
|
|
938
|
-
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
939
|
-
nodes {
|
|
940
|
-
${MEDIA_FIELDS_LIGHT}
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
}`;
|
|
945
|
-
}
|
|
946
|
-
var QUERY_STUDIO_SEARCH = `
|
|
947
|
-
query ($search: String, $sort: [StudioSort], $page: Int, $perPage: Int) {
|
|
948
|
-
Page(page: $page, perPage: $perPage) {
|
|
949
|
-
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
950
|
-
studios(search: $search, sort: $sort) {
|
|
951
|
-
${STUDIO_FIELDS}
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
}`;
|
|
955
|
-
|
|
956
|
-
// src/queries/metadata.ts
|
|
957
|
-
var QUERY_GENRES = `
|
|
958
|
-
query {
|
|
959
|
-
GenreCollection
|
|
960
|
-
}`;
|
|
961
|
-
var QUERY_TAGS = `
|
|
962
|
-
query {
|
|
963
|
-
MediaTagCollection {
|
|
964
|
-
id
|
|
965
|
-
name
|
|
966
|
-
description
|
|
967
|
-
category
|
|
968
|
-
isAdult
|
|
969
|
-
}
|
|
970
|
-
}`;
|
|
971
|
-
|
|
972
|
-
// src/queries/builders.ts
|
|
973
|
-
function buildMediaByIdQuery(include) {
|
|
974
|
-
if (!include) return QUERY_MEDIA_BY_ID;
|
|
975
|
-
const extra = [];
|
|
976
|
-
if (include.relations !== false) {
|
|
977
|
-
extra.push(RELATIONS_FIELDS);
|
|
978
|
-
}
|
|
979
|
-
if (include.characters) {
|
|
980
|
-
const opts = typeof include.characters === "object" ? include.characters : {};
|
|
981
|
-
const perPage = clampPerPage(opts.perPage ?? 25);
|
|
982
|
-
const sortClause = opts.sort !== false ? ", sort: [ROLE, RELEVANCE, ID]" : "";
|
|
983
|
-
const voiceActorBlock = opts.voiceActors ? `
|
|
984
|
-
voiceActors {
|
|
985
|
-
${VOICE_ACTOR_FIELDS_COMPACT}
|
|
986
|
-
}` : "";
|
|
987
|
-
extra.push(`
|
|
988
|
-
characters(perPage: ${perPage}${sortClause}) {
|
|
989
|
-
edges {
|
|
990
|
-
role
|
|
991
|
-
node {
|
|
992
|
-
${CHARACTER_FIELDS_COMPACT}
|
|
993
|
-
}${voiceActorBlock}
|
|
994
|
-
}
|
|
995
|
-
}`);
|
|
996
|
-
}
|
|
997
|
-
if (include.staff) {
|
|
998
|
-
const opts = typeof include.staff === "object" ? include.staff : {};
|
|
999
|
-
const perPage = clampPerPage(opts.perPage ?? 25);
|
|
1000
|
-
const sortClause = opts.sort !== false ? ", sort: [RELEVANCE, ID]" : "";
|
|
1001
|
-
extra.push(`
|
|
1002
|
-
staff(perPage: ${perPage}${sortClause}) {
|
|
1003
|
-
edges {
|
|
1004
|
-
role
|
|
1005
|
-
node {
|
|
1006
|
-
${STAFF_FIELDS}
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}`);
|
|
1010
|
-
}
|
|
1011
|
-
if (include.recommendations) {
|
|
1012
|
-
const perPage = clampPerPage(
|
|
1013
|
-
typeof include.recommendations === "object" ? include.recommendations.perPage ?? 10 : 10
|
|
1014
|
-
);
|
|
1015
|
-
extra.push(`
|
|
1016
|
-
recommendations(perPage: ${perPage}, sort: [RATING_DESC]) {
|
|
1017
|
-
nodes {
|
|
1018
|
-
id
|
|
1019
|
-
rating
|
|
1020
|
-
mediaRecommendation {
|
|
1021
|
-
id
|
|
1022
|
-
title { romaji english native userPreferred }
|
|
1023
|
-
type
|
|
1024
|
-
format
|
|
1025
|
-
coverImage { large medium }
|
|
1026
|
-
averageScore
|
|
1027
|
-
siteUrl
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
}`);
|
|
1031
|
-
}
|
|
1032
|
-
if (include.streamingEpisodes) {
|
|
1033
|
-
extra.push(`
|
|
1034
|
-
streamingEpisodes {
|
|
1035
|
-
title
|
|
1036
|
-
thumbnail
|
|
1037
|
-
url
|
|
1038
|
-
site
|
|
1039
|
-
}`);
|
|
1040
|
-
}
|
|
1041
|
-
if (include.externalLinks) {
|
|
1042
|
-
extra.push(`
|
|
1043
|
-
externalLinks {
|
|
1044
|
-
id
|
|
1045
|
-
url
|
|
1046
|
-
site
|
|
1047
|
-
type
|
|
1048
|
-
icon
|
|
1049
|
-
color
|
|
1050
|
-
}`);
|
|
1051
|
-
}
|
|
1052
|
-
if (include.stats) {
|
|
1053
|
-
extra.push(`
|
|
1054
|
-
stats {
|
|
1055
|
-
scoreDistribution { score amount }
|
|
1056
|
-
statusDistribution { status amount }
|
|
1057
|
-
}`);
|
|
1058
|
-
}
|
|
1059
|
-
return `
|
|
1060
|
-
query ($id: Int!) {
|
|
1061
|
-
Media(id: $id) {
|
|
1062
|
-
${MEDIA_FIELDS_BASE}
|
|
1063
|
-
${extra.join("\n")}
|
|
1064
|
-
}
|
|
1065
|
-
}`;
|
|
1066
|
-
}
|
|
1067
|
-
function buildBatchQuery(ids, typeName, fields, prefix) {
|
|
1068
|
-
const aliases = ids.map((id, i) => `${prefix}${i}: ${typeName}(id: ${id}) { ${fields} }`).join("\n ");
|
|
1069
|
-
return `query {
|
|
1070
|
-
${aliases}
|
|
1071
|
-
}`;
|
|
1072
|
-
}
|
|
1073
|
-
var buildBatchMediaQuery = (ids) => buildBatchQuery(ids, "Media", MEDIA_FIELDS, "m");
|
|
1074
|
-
var buildBatchCharacterQuery = (ids) => buildBatchQuery(ids, "Character", CHARACTER_FIELDS, "c");
|
|
1075
|
-
var buildBatchStaffQuery = (ids) => buildBatchQuery(ids, "Staff", STAFF_FIELDS, "s");
|
|
1076
|
-
|
|
1077
|
-
// src/queries/thread.ts
|
|
1078
|
-
var QUERY_THREAD_BY_ID = `
|
|
1079
|
-
query ($id: Int!) {
|
|
1080
|
-
Thread(id: $id) {
|
|
1081
|
-
${THREAD_FIELDS}
|
|
1082
|
-
}
|
|
1083
|
-
}`;
|
|
1084
|
-
var QUERY_THREAD_SEARCH = `
|
|
1085
|
-
query ($search: String, $mediaCategoryId: Int, $categoryId: Int, $sort: [ThreadSort], $page: Int, $perPage: Int) {
|
|
1086
|
-
Page(page: $page, perPage: $perPage) {
|
|
1087
|
-
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1088
|
-
threads(search: $search, mediaCategoryId: $mediaCategoryId, categoryId: $categoryId, sort: $sort) {
|
|
1089
|
-
${THREAD_FIELDS}
|
|
1168
|
+
nodes {
|
|
1169
|
+
id
|
|
1170
|
+
name { full native }
|
|
1171
|
+
image { large medium }
|
|
1172
|
+
siteUrl
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
studios(perPage: ${pp}) {
|
|
1176
|
+
nodes {
|
|
1177
|
+
id
|
|
1178
|
+
name
|
|
1179
|
+
siteUrl
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1090
1182
|
}
|
|
1091
1183
|
}
|
|
1092
1184
|
}`;
|
|
1185
|
+
}
|
|
1093
1186
|
|
|
1094
1187
|
// src/rate-limiter/index.ts
|
|
1095
1188
|
var RateLimiter = class {
|
|
@@ -1173,7 +1266,7 @@ var RateLimiter = class {
|
|
|
1173
1266
|
}
|
|
1174
1267
|
}
|
|
1175
1268
|
if (lastResponse) return lastResponse;
|
|
1176
|
-
throw lastError;
|
|
1269
|
+
throw lastError ?? new Error(`Request failed after ${this.maxRetries} retries`);
|
|
1177
1270
|
}
|
|
1178
1271
|
/** @internal — Exponential backoff with jitter, capped at 30s (or custom strategy) */
|
|
1179
1272
|
exponentialDelay(attempt) {
|
|
@@ -1248,6 +1341,68 @@ async function searchCharacters(client, options = {}) {
|
|
|
1248
1341
|
return client.pagedRequest(gqlQuery, { search, sort, page, perPage: clampPerPage(perPage) }, "characters");
|
|
1249
1342
|
}
|
|
1250
1343
|
|
|
1344
|
+
// src/types/character.ts
|
|
1345
|
+
var CharacterSort = /* @__PURE__ */ ((CharacterSort2) => {
|
|
1346
|
+
CharacterSort2["ID"] = "ID";
|
|
1347
|
+
CharacterSort2["ID_DESC"] = "ID_DESC";
|
|
1348
|
+
CharacterSort2["ROLE"] = "ROLE";
|
|
1349
|
+
CharacterSort2["ROLE_DESC"] = "ROLE_DESC";
|
|
1350
|
+
CharacterSort2["SEARCH_MATCH"] = "SEARCH_MATCH";
|
|
1351
|
+
CharacterSort2["FAVOURITES"] = "FAVOURITES";
|
|
1352
|
+
CharacterSort2["FAVOURITES_DESC"] = "FAVOURITES_DESC";
|
|
1353
|
+
return CharacterSort2;
|
|
1354
|
+
})(CharacterSort || {});
|
|
1355
|
+
var CharacterRole = /* @__PURE__ */ ((CharacterRole2) => {
|
|
1356
|
+
CharacterRole2["MAIN"] = "MAIN";
|
|
1357
|
+
CharacterRole2["SUPPORTING"] = "SUPPORTING";
|
|
1358
|
+
CharacterRole2["BACKGROUND"] = "BACKGROUND";
|
|
1359
|
+
return CharacterRole2;
|
|
1360
|
+
})(CharacterRole || {});
|
|
1361
|
+
|
|
1362
|
+
// src/types/lists.ts
|
|
1363
|
+
var MediaListStatus = /* @__PURE__ */ ((MediaListStatus2) => {
|
|
1364
|
+
MediaListStatus2["CURRENT"] = "CURRENT";
|
|
1365
|
+
MediaListStatus2["PLANNING"] = "PLANNING";
|
|
1366
|
+
MediaListStatus2["COMPLETED"] = "COMPLETED";
|
|
1367
|
+
MediaListStatus2["DROPPED"] = "DROPPED";
|
|
1368
|
+
MediaListStatus2["PAUSED"] = "PAUSED";
|
|
1369
|
+
MediaListStatus2["REPEATING"] = "REPEATING";
|
|
1370
|
+
return MediaListStatus2;
|
|
1371
|
+
})(MediaListStatus || {});
|
|
1372
|
+
var MediaListSort = /* @__PURE__ */ ((MediaListSort2) => {
|
|
1373
|
+
MediaListSort2["MEDIA_ID"] = "MEDIA_ID";
|
|
1374
|
+
MediaListSort2["MEDIA_ID_DESC"] = "MEDIA_ID_DESC";
|
|
1375
|
+
MediaListSort2["SCORE"] = "SCORE";
|
|
1376
|
+
MediaListSort2["SCORE_DESC"] = "SCORE_DESC";
|
|
1377
|
+
MediaListSort2["STATUS"] = "STATUS";
|
|
1378
|
+
MediaListSort2["STATUS_DESC"] = "STATUS_DESC";
|
|
1379
|
+
MediaListSort2["PROGRESS"] = "PROGRESS";
|
|
1380
|
+
MediaListSort2["PROGRESS_DESC"] = "PROGRESS_DESC";
|
|
1381
|
+
MediaListSort2["PROGRESS_VOLUMES"] = "PROGRESS_VOLUMES";
|
|
1382
|
+
MediaListSort2["PROGRESS_VOLUMES_DESC"] = "PROGRESS_VOLUMES_DESC";
|
|
1383
|
+
MediaListSort2["REPEAT"] = "REPEAT";
|
|
1384
|
+
MediaListSort2["REPEAT_DESC"] = "REPEAT_DESC";
|
|
1385
|
+
MediaListSort2["PRIORITY"] = "PRIORITY";
|
|
1386
|
+
MediaListSort2["PRIORITY_DESC"] = "PRIORITY_DESC";
|
|
1387
|
+
MediaListSort2["STARTED_ON"] = "STARTED_ON";
|
|
1388
|
+
MediaListSort2["STARTED_ON_DESC"] = "STARTED_ON_DESC";
|
|
1389
|
+
MediaListSort2["FINISHED_ON"] = "FINISHED_ON";
|
|
1390
|
+
MediaListSort2["FINISHED_ON_DESC"] = "FINISHED_ON_DESC";
|
|
1391
|
+
MediaListSort2["ADDED_TIME"] = "ADDED_TIME";
|
|
1392
|
+
MediaListSort2["ADDED_TIME_DESC"] = "ADDED_TIME_DESC";
|
|
1393
|
+
MediaListSort2["UPDATED_TIME"] = "UPDATED_TIME";
|
|
1394
|
+
MediaListSort2["UPDATED_TIME_DESC"] = "UPDATED_TIME_DESC";
|
|
1395
|
+
MediaListSort2["MEDIA_TITLE_ROMAJI"] = "MEDIA_TITLE_ROMAJI";
|
|
1396
|
+
MediaListSort2["MEDIA_TITLE_ROMAJI_DESC"] = "MEDIA_TITLE_ROMAJI_DESC";
|
|
1397
|
+
MediaListSort2["MEDIA_TITLE_ENGLISH"] = "MEDIA_TITLE_ENGLISH";
|
|
1398
|
+
MediaListSort2["MEDIA_TITLE_ENGLISH_DESC"] = "MEDIA_TITLE_ENGLISH_DESC";
|
|
1399
|
+
MediaListSort2["MEDIA_TITLE_NATIVE"] = "MEDIA_TITLE_NATIVE";
|
|
1400
|
+
MediaListSort2["MEDIA_TITLE_NATIVE_DESC"] = "MEDIA_TITLE_NATIVE_DESC";
|
|
1401
|
+
MediaListSort2["MEDIA_POPULARITY"] = "MEDIA_POPULARITY";
|
|
1402
|
+
MediaListSort2["MEDIA_POPULARITY_DESC"] = "MEDIA_POPULARITY_DESC";
|
|
1403
|
+
return MediaListSort2;
|
|
1404
|
+
})(MediaListSort || {});
|
|
1405
|
+
|
|
1251
1406
|
// src/types/media.ts
|
|
1252
1407
|
var MediaType = /* @__PURE__ */ ((MediaType2) => {
|
|
1253
1408
|
MediaType2["ANIME"] = "ANIME";
|
|
@@ -1371,24 +1526,6 @@ var RecommendationSort = /* @__PURE__ */ ((RecommendationSort2) => {
|
|
|
1371
1526
|
return RecommendationSort2;
|
|
1372
1527
|
})(RecommendationSort || {});
|
|
1373
1528
|
|
|
1374
|
-
// src/types/character.ts
|
|
1375
|
-
var CharacterSort = /* @__PURE__ */ ((CharacterSort2) => {
|
|
1376
|
-
CharacterSort2["ID"] = "ID";
|
|
1377
|
-
CharacterSort2["ID_DESC"] = "ID_DESC";
|
|
1378
|
-
CharacterSort2["ROLE"] = "ROLE";
|
|
1379
|
-
CharacterSort2["ROLE_DESC"] = "ROLE_DESC";
|
|
1380
|
-
CharacterSort2["SEARCH_MATCH"] = "SEARCH_MATCH";
|
|
1381
|
-
CharacterSort2["FAVOURITES"] = "FAVOURITES";
|
|
1382
|
-
CharacterSort2["FAVOURITES_DESC"] = "FAVOURITES_DESC";
|
|
1383
|
-
return CharacterSort2;
|
|
1384
|
-
})(CharacterSort || {});
|
|
1385
|
-
var CharacterRole = /* @__PURE__ */ ((CharacterRole2) => {
|
|
1386
|
-
CharacterRole2["MAIN"] = "MAIN";
|
|
1387
|
-
CharacterRole2["SUPPORTING"] = "SUPPORTING";
|
|
1388
|
-
CharacterRole2["BACKGROUND"] = "BACKGROUND";
|
|
1389
|
-
return CharacterRole2;
|
|
1390
|
-
})(CharacterRole || {});
|
|
1391
|
-
|
|
1392
1529
|
// src/types/staff.ts
|
|
1393
1530
|
var StaffSort = /* @__PURE__ */ ((StaffSort2) => {
|
|
1394
1531
|
StaffSort2["ID"] = "ID";
|
|
@@ -1404,20 +1541,6 @@ var StaffSort = /* @__PURE__ */ ((StaffSort2) => {
|
|
|
1404
1541
|
return StaffSort2;
|
|
1405
1542
|
})(StaffSort || {});
|
|
1406
1543
|
|
|
1407
|
-
// src/types/user.ts
|
|
1408
|
-
var UserSort = /* @__PURE__ */ ((UserSort2) => {
|
|
1409
|
-
UserSort2["ID"] = "ID";
|
|
1410
|
-
UserSort2["ID_DESC"] = "ID_DESC";
|
|
1411
|
-
UserSort2["USERNAME"] = "USERNAME";
|
|
1412
|
-
UserSort2["USERNAME_DESC"] = "USERNAME_DESC";
|
|
1413
|
-
UserSort2["WATCHED_TIME"] = "WATCHED_TIME";
|
|
1414
|
-
UserSort2["WATCHED_TIME_DESC"] = "WATCHED_TIME_DESC";
|
|
1415
|
-
UserSort2["CHAPTERS_READ"] = "CHAPTERS_READ";
|
|
1416
|
-
UserSort2["CHAPTERS_READ_DESC"] = "CHAPTERS_READ_DESC";
|
|
1417
|
-
UserSort2["SEARCH_MATCH"] = "SEARCH_MATCH";
|
|
1418
|
-
return UserSort2;
|
|
1419
|
-
})(UserSort || {});
|
|
1420
|
-
|
|
1421
1544
|
// src/types/studio.ts
|
|
1422
1545
|
var StudioSort = /* @__PURE__ */ ((StudioSort2) => {
|
|
1423
1546
|
StudioSort2["ID"] = "ID";
|
|
@@ -1430,50 +1553,6 @@ var StudioSort = /* @__PURE__ */ ((StudioSort2) => {
|
|
|
1430
1553
|
return StudioSort2;
|
|
1431
1554
|
})(StudioSort || {});
|
|
1432
1555
|
|
|
1433
|
-
// src/types/lists.ts
|
|
1434
|
-
var MediaListStatus = /* @__PURE__ */ ((MediaListStatus2) => {
|
|
1435
|
-
MediaListStatus2["CURRENT"] = "CURRENT";
|
|
1436
|
-
MediaListStatus2["PLANNING"] = "PLANNING";
|
|
1437
|
-
MediaListStatus2["COMPLETED"] = "COMPLETED";
|
|
1438
|
-
MediaListStatus2["DROPPED"] = "DROPPED";
|
|
1439
|
-
MediaListStatus2["PAUSED"] = "PAUSED";
|
|
1440
|
-
MediaListStatus2["REPEATING"] = "REPEATING";
|
|
1441
|
-
return MediaListStatus2;
|
|
1442
|
-
})(MediaListStatus || {});
|
|
1443
|
-
var MediaListSort = /* @__PURE__ */ ((MediaListSort2) => {
|
|
1444
|
-
MediaListSort2["MEDIA_ID"] = "MEDIA_ID";
|
|
1445
|
-
MediaListSort2["MEDIA_ID_DESC"] = "MEDIA_ID_DESC";
|
|
1446
|
-
MediaListSort2["SCORE"] = "SCORE";
|
|
1447
|
-
MediaListSort2["SCORE_DESC"] = "SCORE_DESC";
|
|
1448
|
-
MediaListSort2["STATUS"] = "STATUS";
|
|
1449
|
-
MediaListSort2["STATUS_DESC"] = "STATUS_DESC";
|
|
1450
|
-
MediaListSort2["PROGRESS"] = "PROGRESS";
|
|
1451
|
-
MediaListSort2["PROGRESS_DESC"] = "PROGRESS_DESC";
|
|
1452
|
-
MediaListSort2["PROGRESS_VOLUMES"] = "PROGRESS_VOLUMES";
|
|
1453
|
-
MediaListSort2["PROGRESS_VOLUMES_DESC"] = "PROGRESS_VOLUMES_DESC";
|
|
1454
|
-
MediaListSort2["REPEAT"] = "REPEAT";
|
|
1455
|
-
MediaListSort2["REPEAT_DESC"] = "REPEAT_DESC";
|
|
1456
|
-
MediaListSort2["PRIORITY"] = "PRIORITY";
|
|
1457
|
-
MediaListSort2["PRIORITY_DESC"] = "PRIORITY_DESC";
|
|
1458
|
-
MediaListSort2["STARTED_ON"] = "STARTED_ON";
|
|
1459
|
-
MediaListSort2["STARTED_ON_DESC"] = "STARTED_ON_DESC";
|
|
1460
|
-
MediaListSort2["FINISHED_ON"] = "FINISHED_ON";
|
|
1461
|
-
MediaListSort2["FINISHED_ON_DESC"] = "FINISHED_ON_DESC";
|
|
1462
|
-
MediaListSort2["ADDED_TIME"] = "ADDED_TIME";
|
|
1463
|
-
MediaListSort2["ADDED_TIME_DESC"] = "ADDED_TIME_DESC";
|
|
1464
|
-
MediaListSort2["UPDATED_TIME"] = "UPDATED_TIME";
|
|
1465
|
-
MediaListSort2["UPDATED_TIME_DESC"] = "UPDATED_TIME_DESC";
|
|
1466
|
-
MediaListSort2["MEDIA_TITLE_ROMAJI"] = "MEDIA_TITLE_ROMAJI";
|
|
1467
|
-
MediaListSort2["MEDIA_TITLE_ROMAJI_DESC"] = "MEDIA_TITLE_ROMAJI_DESC";
|
|
1468
|
-
MediaListSort2["MEDIA_TITLE_ENGLISH"] = "MEDIA_TITLE_ENGLISH";
|
|
1469
|
-
MediaListSort2["MEDIA_TITLE_ENGLISH_DESC"] = "MEDIA_TITLE_ENGLISH_DESC";
|
|
1470
|
-
MediaListSort2["MEDIA_TITLE_NATIVE"] = "MEDIA_TITLE_NATIVE";
|
|
1471
|
-
MediaListSort2["MEDIA_TITLE_NATIVE_DESC"] = "MEDIA_TITLE_NATIVE_DESC";
|
|
1472
|
-
MediaListSort2["MEDIA_POPULARITY"] = "MEDIA_POPULARITY";
|
|
1473
|
-
MediaListSort2["MEDIA_POPULARITY_DESC"] = "MEDIA_POPULARITY_DESC";
|
|
1474
|
-
return MediaListSort2;
|
|
1475
|
-
})(MediaListSort || {});
|
|
1476
|
-
|
|
1477
1556
|
// src/types/thread.ts
|
|
1478
1557
|
var ThreadSort = /* @__PURE__ */ ((ThreadSort2) => {
|
|
1479
1558
|
ThreadSort2["ID"] = "ID";
|
|
@@ -1495,6 +1574,20 @@ var ThreadSort = /* @__PURE__ */ ((ThreadSort2) => {
|
|
|
1495
1574
|
return ThreadSort2;
|
|
1496
1575
|
})(ThreadSort || {});
|
|
1497
1576
|
|
|
1577
|
+
// src/types/user.ts
|
|
1578
|
+
var UserSort = /* @__PURE__ */ ((UserSort2) => {
|
|
1579
|
+
UserSort2["ID"] = "ID";
|
|
1580
|
+
UserSort2["ID_DESC"] = "ID_DESC";
|
|
1581
|
+
UserSort2["USERNAME"] = "USERNAME";
|
|
1582
|
+
UserSort2["USERNAME_DESC"] = "USERNAME_DESC";
|
|
1583
|
+
UserSort2["WATCHED_TIME"] = "WATCHED_TIME";
|
|
1584
|
+
UserSort2["WATCHED_TIME_DESC"] = "WATCHED_TIME_DESC";
|
|
1585
|
+
UserSort2["CHAPTERS_READ"] = "CHAPTERS_READ";
|
|
1586
|
+
UserSort2["CHAPTERS_READ_DESC"] = "CHAPTERS_READ_DESC";
|
|
1587
|
+
UserSort2["SEARCH_MATCH"] = "SEARCH_MATCH";
|
|
1588
|
+
return UserSort2;
|
|
1589
|
+
})(UserSort || {});
|
|
1590
|
+
|
|
1498
1591
|
// src/client/media.ts
|
|
1499
1592
|
async function getMedia(client, id, include) {
|
|
1500
1593
|
validateId(id, "mediaId");
|
|
@@ -1511,12 +1604,24 @@ async function getMediaByMalId(client, malId, type) {
|
|
|
1511
1604
|
return data.Media;
|
|
1512
1605
|
}
|
|
1513
1606
|
async function searchMedia(client, options = {}) {
|
|
1514
|
-
const {
|
|
1607
|
+
const {
|
|
1608
|
+
query: search,
|
|
1609
|
+
page = 1,
|
|
1610
|
+
perPage = 20,
|
|
1611
|
+
genres,
|
|
1612
|
+
tags,
|
|
1613
|
+
genresExclude,
|
|
1614
|
+
tagsExclude,
|
|
1615
|
+
format,
|
|
1616
|
+
...filters
|
|
1617
|
+
} = options;
|
|
1515
1618
|
return client.pagedRequest(
|
|
1516
1619
|
QUERY_MEDIA_SEARCH,
|
|
1517
1620
|
{
|
|
1518
1621
|
search,
|
|
1519
1622
|
...filters,
|
|
1623
|
+
format: Array.isArray(format) ? void 0 : format,
|
|
1624
|
+
format_in: Array.isArray(format) ? format : void 0,
|
|
1520
1625
|
genre_in: genres,
|
|
1521
1626
|
tag_in: tags,
|
|
1522
1627
|
genre_not_in: genresExclude,
|
|
@@ -1719,7 +1824,7 @@ async function searchUsers(client, options = {}) {
|
|
|
1719
1824
|
}
|
|
1720
1825
|
async function getUserMediaList(client, options) {
|
|
1721
1826
|
if (!options.userId && !options.userName) {
|
|
1722
|
-
throw new
|
|
1827
|
+
throw new TypeError("getUserMediaList requires either userId or userName");
|
|
1723
1828
|
}
|
|
1724
1829
|
if (options.userId) {
|
|
1725
1830
|
validateId(options.userId, "userId");
|
|
@@ -1766,7 +1871,7 @@ function mapFavorites(fav) {
|
|
|
1766
1871
|
|
|
1767
1872
|
// src/client/index.ts
|
|
1768
1873
|
var DEFAULT_API_URL = "https://graphql.anilist.co";
|
|
1769
|
-
var LIB_VERSION = "1.
|
|
1874
|
+
var LIB_VERSION = "1.9.0" ;
|
|
1770
1875
|
var AniListClient = class {
|
|
1771
1876
|
apiUrl;
|
|
1772
1877
|
headers;
|
|
@@ -1854,7 +1959,15 @@ var AniListClient = class {
|
|
|
1854
1959
|
this.hooks.onError?.(error, query, variables);
|
|
1855
1960
|
throw error;
|
|
1856
1961
|
}
|
|
1857
|
-
|
|
1962
|
+
let json;
|
|
1963
|
+
try {
|
|
1964
|
+
json = await res.json();
|
|
1965
|
+
} catch {
|
|
1966
|
+
const error = new AniListError(`Non-JSON response from AniList (HTTP ${res.status})`, res.status, []);
|
|
1967
|
+
this.logger?.error("Request failed", { error: error.message, status: error.status });
|
|
1968
|
+
this.hooks.onError?.(error, query, variables);
|
|
1969
|
+
throw error;
|
|
1970
|
+
}
|
|
1858
1971
|
if (!res.ok || json.errors) {
|
|
1859
1972
|
const message = json.errors?.[0]?.message ?? `AniList API error (HTTP ${res.status})`;
|
|
1860
1973
|
const error = new AniListError(message, res.status, json.errors ?? []);
|
|
@@ -2158,92 +2271,6 @@ var AniListClient = class {
|
|
|
2158
2271
|
}
|
|
2159
2272
|
};
|
|
2160
2273
|
|
|
2161
|
-
// src/cache/redis.ts
|
|
2162
|
-
var RedisCache = class {
|
|
2163
|
-
client;
|
|
2164
|
-
prefix;
|
|
2165
|
-
ttl;
|
|
2166
|
-
constructor(options) {
|
|
2167
|
-
this.client = options.client;
|
|
2168
|
-
this.prefix = options.prefix ?? "ani:";
|
|
2169
|
-
this.ttl = options.ttl ?? 86400;
|
|
2170
|
-
}
|
|
2171
|
-
prefixedKey(key) {
|
|
2172
|
-
return `${this.prefix}${key}`;
|
|
2173
|
-
}
|
|
2174
|
-
async get(key) {
|
|
2175
|
-
const raw = await this.client.get(this.prefixedKey(key));
|
|
2176
|
-
if (raw === null) return void 0;
|
|
2177
|
-
try {
|
|
2178
|
-
return JSON.parse(raw);
|
|
2179
|
-
} catch {
|
|
2180
|
-
return void 0;
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2183
|
-
async set(key, data) {
|
|
2184
|
-
await this.client.set(this.prefixedKey(key), JSON.stringify(data), "EX", this.ttl);
|
|
2185
|
-
}
|
|
2186
|
-
async delete(key) {
|
|
2187
|
-
const count = await this.client.del(this.prefixedKey(key));
|
|
2188
|
-
return count > 0;
|
|
2189
|
-
}
|
|
2190
|
-
/**
|
|
2191
|
-
* Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.
|
|
2192
|
-
*
|
|
2193
|
-
* **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.
|
|
2194
|
-
* Provide a client with `scanIterator` support for production use.
|
|
2195
|
-
* @internal
|
|
2196
|
-
*/
|
|
2197
|
-
async collectKeys(pattern) {
|
|
2198
|
-
if (this.client.scanIterator) {
|
|
2199
|
-
const keys = [];
|
|
2200
|
-
for await (const key of this.client.scanIterator({ MATCH: pattern, COUNT: 100 })) {
|
|
2201
|
-
keys.push(key);
|
|
2202
|
-
}
|
|
2203
|
-
return keys;
|
|
2204
|
-
}
|
|
2205
|
-
return this.client.keys(pattern);
|
|
2206
|
-
}
|
|
2207
|
-
async clear() {
|
|
2208
|
-
const keys = await this.collectKeys(`${this.prefix}*`);
|
|
2209
|
-
if (keys.length > 0) {
|
|
2210
|
-
await this.client.del(...keys);
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
/**
|
|
2214
|
-
* Get the actual number of keys with this prefix in Redis.
|
|
2215
|
-
*/
|
|
2216
|
-
get size() {
|
|
2217
|
-
return this.getSize();
|
|
2218
|
-
}
|
|
2219
|
-
/** @internal */
|
|
2220
|
-
async getSize() {
|
|
2221
|
-
const keys = await this.collectKeys(`${this.prefix}*`);
|
|
2222
|
-
return keys.length;
|
|
2223
|
-
}
|
|
2224
|
-
async keys() {
|
|
2225
|
-
const raw = await this.collectKeys(`${this.prefix}*`);
|
|
2226
|
-
return raw.map((k) => k.slice(this.prefix.length));
|
|
2227
|
-
}
|
|
2228
|
-
/**
|
|
2229
|
-
* Remove all entries whose key matches the given glob pattern.
|
|
2230
|
-
*
|
|
2231
|
-
* @param pattern — A glob pattern (e.g. `"*Media*"`)
|
|
2232
|
-
* @returns Number of entries removed.
|
|
2233
|
-
*/
|
|
2234
|
-
async invalidate(pattern) {
|
|
2235
|
-
if (typeof pattern === "string") {
|
|
2236
|
-
const keys = await this.collectKeys(`${this.prefix}${pattern}`);
|
|
2237
|
-
if (keys.length === 0) return 0;
|
|
2238
|
-
return this.client.del(...keys);
|
|
2239
|
-
}
|
|
2240
|
-
const allKeys = await this.collectKeys(`${this.prefix}*`);
|
|
2241
|
-
const matching = allKeys.filter((k) => pattern.test(k.slice(this.prefix.length)));
|
|
2242
|
-
if (matching.length === 0) return 0;
|
|
2243
|
-
return this.client.del(...matching);
|
|
2244
|
-
}
|
|
2245
|
-
};
|
|
2246
|
-
|
|
2247
2274
|
exports.AiringSort = AiringSort;
|
|
2248
2275
|
exports.AniListClient = AniListClient;
|
|
2249
2276
|
exports.AniListError = AniListError;
|