feat: add type safety to AniList fetching methods
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import type { TypedDocumentNode } from "@graphql-typed-document-node/core";
|
||||||
import { DurableObject } from "cloudflare:workers";
|
import { DurableObject } from "cloudflare:workers";
|
||||||
import { type ResultOf } from "gql.tada";
|
import { type ResultOf } from "gql.tada";
|
||||||
import { print } from "graphql";
|
import { print } from "graphql";
|
||||||
@@ -34,11 +35,11 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
super(state, env);
|
super(state, env);
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
async fetch(request: Request): Promise<Response> {
|
async fetch(request: Request) {
|
||||||
return new Response("Not found", { status: 404 });
|
return new Response("Not found", { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTitle(id: number, token?: string): Promise<any> {
|
async getTitle(id: number, token?: string) {
|
||||||
const storageKey = id.toString();
|
const storageKey = id.toString();
|
||||||
const cache = await this.state.storage.get(storageKey);
|
const cache = await this.state.storage.get(storageKey);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
@@ -71,7 +72,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
return media;
|
return media;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNextEpisodeAiringAt(id: number): Promise<any> {
|
async getNextEpisodeAiringAt(id: number) {
|
||||||
const storageKey = `next_airing:${id}`;
|
const storageKey = `next_airing:${id}`;
|
||||||
const TTL = 60 * 60 * 1000;
|
const TTL = 60 * 60 * 1000;
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async search(query: string, page: number, limit: number): Promise<any> {
|
async search(query: string, page: number, limit: number) {
|
||||||
const storageKey = `search:${JSON.stringify({ query, page, limit })}`;
|
const storageKey = `search:${JSON.stringify({ query, page, limit })}`;
|
||||||
const TTL = 60 * 60 * 1000;
|
const TTL = 60 * 60 * 1000;
|
||||||
return this.handleCachedRequest(
|
return this.handleCachedRequest(
|
||||||
@@ -110,7 +111,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
nextSeason: any,
|
nextSeason: any,
|
||||||
nextYear: number,
|
nextYear: number,
|
||||||
limit: number,
|
limit: number,
|
||||||
): Promise<any> {
|
) {
|
||||||
// No caching for browse popular as it returns a Response object in the original code?
|
// No caching for browse popular as it returns a Response object in the original code?
|
||||||
// Wait, the original code had caching logic but it was commented out or mixed?
|
// Wait, the original code had caching logic but it was commented out or mixed?
|
||||||
// The original code returned a Response directly for BrowsePopular without caching in the switch case,
|
// The original code returned a Response directly for BrowsePopular without caching in the switch case,
|
||||||
@@ -129,11 +130,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async nextSeasonPopular(
|
async nextSeasonPopular(nextSeason: any, nextYear: number, limit: number) {
|
||||||
nextSeason: any,
|
|
||||||
nextYear: number,
|
|
||||||
limit: number,
|
|
||||||
): Promise<any> {
|
|
||||||
const storageKey = `next_season:${JSON.stringify({ nextSeason, nextYear, limit })}`;
|
const storageKey = `next_season:${JSON.stringify({ nextSeason, nextYear, limit })}`;
|
||||||
const TTL = 60 * 60 * 1000;
|
const TTL = 60 * 60 * 1000;
|
||||||
return this.handleCachedRequest(
|
return this.handleCachedRequest(
|
||||||
@@ -154,7 +151,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
limit: number,
|
limit: number,
|
||||||
season: any,
|
season: any,
|
||||||
seasonYear: number,
|
seasonYear: number,
|
||||||
): Promise<any> {
|
) {
|
||||||
// The original code had unreachable cache logic.
|
// The original code had unreachable cache logic.
|
||||||
// I will implement it with caching if possible, but let's follow the pattern.
|
// I will implement it with caching if possible, but let's follow the pattern.
|
||||||
// Actually, let's enable caching as it seems intended.
|
// Actually, let's enable caching as it seems intended.
|
||||||
@@ -175,7 +172,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTrendingTitles(page: number, limit: number): Promise<any> {
|
async getTrendingTitles(page: number, limit: number) {
|
||||||
const storageKey = `trending:${JSON.stringify({ page, limit })}`;
|
const storageKey = `trending:${JSON.stringify({ page, limit })}`;
|
||||||
const TTL = 60 * 60 * 1000;
|
const TTL = 60 * 60 * 1000;
|
||||||
return this.handleCachedRequest(
|
return this.handleCachedRequest(
|
||||||
@@ -195,7 +192,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
page: number,
|
page: number,
|
||||||
airingAtLowerBound: number,
|
airingAtLowerBound: number,
|
||||||
airingAtUpperBound: number,
|
airingAtUpperBound: number,
|
||||||
): Promise<any> {
|
) {
|
||||||
const storageKey = `upcoming:${JSON.stringify({ page, airingAtLowerBound, airingAtUpperBound })}`;
|
const storageKey = `upcoming:${JSON.stringify({ page, airingAtLowerBound, airingAtUpperBound })}`;
|
||||||
const TTL = 60 * 60 * 1000;
|
const TTL = 60 * 60 * 1000;
|
||||||
return this.handleCachedRequest(
|
return this.handleCachedRequest(
|
||||||
@@ -212,7 +209,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUser(token: string): Promise<any> {
|
async getUser(token: string) {
|
||||||
const storageKey = `user:${token}`;
|
const storageKey = `user:${token}`;
|
||||||
// 1 month
|
// 1 month
|
||||||
const TTL = 60 * 60 * 24 * 30 * 1000;
|
const TTL = 60 * 60 * 24 * 30 * 1000;
|
||||||
@@ -226,7 +223,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserProfile(token: string): Promise<any> {
|
async getUserProfile(token: string) {
|
||||||
const data = await this.fetchFromAnilist(
|
const data = await this.fetchFromAnilist(
|
||||||
GetUserProfileQuery,
|
GetUserProfileQuery,
|
||||||
{ token },
|
{ token },
|
||||||
@@ -239,7 +236,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
titleId: number,
|
titleId: number,
|
||||||
episodeNumber: number,
|
episodeNumber: number,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<any> {
|
) {
|
||||||
const data = await this.fetchFromAnilist(
|
const data = await this.fetchFromAnilist(
|
||||||
MarkEpisodeAsWatchedMutation,
|
MarkEpisodeAsWatchedMutation,
|
||||||
{ titleId, episodeNumber },
|
{ titleId, episodeNumber },
|
||||||
@@ -248,7 +245,7 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
return data?.SaveMediaListEntry;
|
return data?.SaveMediaListEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
async markTitleAsWatched(titleId: number, token: string): Promise<any> {
|
async markTitleAsWatched(titleId: number, token: string) {
|
||||||
const data = await this.fetchFromAnilist(
|
const data = await this.fetchFromAnilist(
|
||||||
MarkTitleAsWatchedMutation,
|
MarkTitleAsWatchedMutation,
|
||||||
{ titleId },
|
{ titleId },
|
||||||
@@ -258,9 +255,9 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper to handle caching logic
|
// Helper to handle caching logic
|
||||||
async handleCachedRequest(
|
async handleCachedRequest<T>(
|
||||||
key: string,
|
key: string,
|
||||||
fetcher: () => Promise<any>,
|
fetcher: () => Promise<T>,
|
||||||
ttl?: number,
|
ttl?: number,
|
||||||
) {
|
) {
|
||||||
const cache = await this.state.storage.get(key);
|
const cache = await this.state.storage.get(key);
|
||||||
@@ -294,11 +291,11 @@ export class AnilistDurableObject extends DurableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchFromAnilist(
|
async fetchFromAnilist<Result = any, Variables = any>(
|
||||||
query: any,
|
query: TypedDocumentNode<Result, Variables>,
|
||||||
variables: any,
|
variables: Variables,
|
||||||
token?: string | undefined,
|
token?: string | undefined,
|
||||||
): Promise<any> {
|
): Promise<Result> {
|
||||||
const headers: any = {
|
const headers: any = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user