84 lines
2.1 KiB
TypeScript
84 lines
2.1 KiB
TypeScript
import { graphql } from "gql.tada";
|
|
import { GraphQLClient } from "graphql-request";
|
|
|
|
import { sleep } from "~/libs/sleep";
|
|
|
|
const SearchQuery = graphql(`
|
|
query Search($query: String!, $page: Int!, $limit: Int!) {
|
|
Page(page: $page, perPage: $limit) {
|
|
media(search: $query, type: ANIME, sort: [POPULARITY_DESC, SCORE_DESC]) {
|
|
id
|
|
title {
|
|
userPreferred
|
|
english
|
|
}
|
|
coverImage {
|
|
extraLarge
|
|
large
|
|
medium
|
|
}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
}
|
|
}
|
|
}
|
|
`);
|
|
|
|
export async function fetchSearchResultsFromAnilist(
|
|
query: string,
|
|
page: number,
|
|
limit: number,
|
|
): Promise<SearchResultsResponse | undefined> {
|
|
const client = new GraphQLClient("https://graphql.anilist.co/");
|
|
|
|
return client
|
|
.request(SearchQuery, { page, query, limit })
|
|
.then((data) => data?.Page)
|
|
.then((page) => {
|
|
if (!page || page.media?.length === 0) {
|
|
return undefined;
|
|
}
|
|
|
|
const { media: results, pageInfo } = page;
|
|
return {
|
|
results: results?.map((result) => {
|
|
if (!result) return null;
|
|
|
|
return {
|
|
id: result.id,
|
|
title: result.title?.userPreferred ?? result.title?.english,
|
|
coverImage: result.coverImage,
|
|
};
|
|
}),
|
|
hasNextPage: pageInfo?.hasNextPage,
|
|
};
|
|
})
|
|
.catch((err) => {
|
|
const response = err.response;
|
|
if (response.status === 429) {
|
|
console.log("429, retrying in", response.headers.get("Retry-After"));
|
|
return sleep(Number(response.headers.get("Retry-After")!) * 1000).then(
|
|
() => fetchSearchResultsFromAnilist(query, page, limit),
|
|
);
|
|
}
|
|
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
type SearchResultsResponse = {
|
|
results:
|
|
| ({
|
|
id: number;
|
|
title: { userPreferred: string | null; english: string | null } | null;
|
|
coverImage: {
|
|
extraLarge: string | null;
|
|
large: string | null;
|
|
medium: string | null;
|
|
} | null;
|
|
} | null)[]
|
|
| null;
|
|
hasNextPage: boolean | null | undefined;
|
|
};
|