refactor: ♻️emoves Env parameter

Removes the `Env` parameter from several functions to simplify their signatures and rely on the global `env` for configuration.

This change reduces the number of arguments passed around, making the code cleaner and easier to maintain.
This commit is contained in:
2025-08-10 19:22:14 -04:00
parent 0b0078328c
commit 8175d73df1
26 changed files with 8716 additions and 184 deletions

View File

@@ -1,13 +1,12 @@
import { env as cloudflareEnv } from "cloudflare:workers";
import mapKeys from "lodash.mapkeys";
import type { Env } from "~/types/env";
import { Case, changeStringCase } from "../changeStringCase";
import { readEnvVariable } from "../readEnvVariable";
export function getAdminSdkCredentials(env: Env) {
export function getAdminSdkCredentials(env: Cloudflare.Env = cloudflareEnv) {
return mapKeys(
readEnvVariable<AdminSdkCredentials>(env, "ADMIN_SDK_JSON"),
readEnvVariable<AdminSdkCredentials>("ADMIN_SDK_JSON", env),
(_, key) => changeStringCase(key, Case.snake_case, Case.camelCase),
) as unknown as AdminSdkCredentials;
}

View File

@@ -5,14 +5,12 @@ import {
addUnreleasedTitle,
removeUnreleasedTitle,
} from "~/models/unreleasedTitles";
import type { Env } from "~/types/env";
import { getNextEpisodeTimeUntilAiring } from "./anilist/getNextEpisodeAiringAt";
import { getCurrentDomain } from "./getCurrentDomain";
import { queueTask } from "./tasks/queueTask";
export async function maybeScheduleNextAiringEpisode(
env: Env,
req: HonoRequest,
aniListId: number,
) {
@@ -27,7 +25,7 @@ export async function maybeScheduleNextAiringEpisode(
DateTime.fromSeconds(nextAiring.airingAt).diffNow("hours").hours >= 720
) {
if (status === "NOT_YET_RELEASED") {
await addUnreleasedTitle(env, aniListId);
await addUnreleasedTitle(aniListId);
}
return;
@@ -35,10 +33,9 @@ export async function maybeScheduleNextAiringEpisode(
const { airingAt, episode: nextEpisode } = nextAiring;
await queueTask(
env,
"new-episode",
{ aniListId, episodeNumber: nextEpisode },
{ req, scheduleConfig: { epochTime: airingAt } },
);
await removeUnreleasedTitle(env, aniListId);
await removeUnreleasedTitle(aniListId);
}

View File

@@ -6,31 +6,30 @@ describe("readEnvVariable", () => {
describe("env & variable defined", () => {
it("returns boolean", () => {
expect(
readEnvVariable<boolean>({ ENABLE_ANIFY: "false" }, "ENABLE_ANIFY"),
readEnvVariable<boolean>("ENABLE_ANIFY", { ENABLE_ANIFY: "false" }),
).toBe(false);
});
it("returns string", () => {
expect(
readEnvVariable<string>(
{ QSTASH_TOKEN: "ehf73g8gyriuvnieojwicbg83hc" },
"QSTASH_TOKEN",
),
readEnvVariable<string>("QSTASH_TOKEN", {
QSTASH_TOKEN: "ehf73g8gyriuvnieojwicbg83hc",
}),
).toBe("ehf73g8gyriuvnieojwicbg83hc");
});
it("returns number", () => {
expect(
readEnvVariable<number>({ NUM_RETRIES: "123" }, "NUM_RETRIES"),
readEnvVariable<number>("NUM_RETRIES", { NUM_RETRIES: "123" }),
).toBe(123);
});
});
it("env defined but variable not defined, returns default value", () => {
expect(readEnvVariable<boolean>({ FOO: "bar" }, "ENABLE_ANIFY")).toBe(true);
expect(readEnvVariable<boolean>("ENABLE_ANIFY", { FOO: "bar" })).toBe(true);
});
it("env not defined, returns default value", () => {
expect(readEnvVariable<boolean>(undefined, "ENABLE_ANIFY")).toBe(true);
expect(readEnvVariable<boolean>("ENABLE_ANIFY", undefined)).toBe(true);
});
});

View File

@@ -1,15 +1,14 @@
import { env as cloudflareEnv } from "cloudflare:workers";
import type { Bindings } from "hono/types";
import type { Env } from "~/types/env";
type EnvVariable = keyof Omit<Env, "Bindings" | "Variables">;
type EnvVariable = keyof Cloudflare.Env;
const defaultValues: Record<EnvVariable, any> = {
ENABLE_ANIFY: true,
};
export function readEnvVariable<T>(
env: Bindings | undefined,
envVariable: EnvVariable,
env: Bindings | undefined = cloudflareEnv,
): T {
try {
return JSON.parse(env?.[envVariable] ?? null) ?? defaultValues[envVariable];

View File

@@ -1,8 +1,8 @@
import { env as cloudflareEnv } from "cloudflare:workers";
import type { HonoRequest } from "hono";
import isEqual from "lodash.isequal";
import { DateTime, type DurationLike } from "luxon";
import type { Env } from "~/types/env";
import type { WatchStatus } from "~/types/title/watchStatus";
import { FailedToQueueTaskError } from "../errors/FailedToQueueTask";
@@ -24,20 +24,20 @@ type QueueBody = {
};
type ScheduleConfig =
| { delay: DurationLike; epochTime: never }
| { epochTime: number; delay: never };
| { delay: DurationLike; epochTime?: never }
| { epochTime: number; delay?: never };
interface QueueTaskOptionalArgs {
scheduleConfig?: ScheduleConfig;
/** when req is not provided, that means the task is being created locally */
req?: HonoRequest;
env?: Cloudflare.Env;
}
export async function queueTask(
env: Env,
queueName: QueueName,
body: QueueBody[QueueName],
{ scheduleConfig, req }: QueueTaskOptionalArgs = {},
{ scheduleConfig, req, env = cloudflareEnv }: QueueTaskOptionalArgs = {},
) {
const domain = req
? getCurrentDomain(req)
@@ -114,7 +114,7 @@ export async function queueTask(
}
async function checkIfTaskExists(
env: Env,
env: Cloudflare.Env,
queueName: QueueName,
taskId: string,
expectedBody: QueueBody[QueueName],

View File

@@ -1,14 +1,10 @@
import type { Env } from "~/types/env";
import { env } from "cloudflare:workers";
import { getAdminSdkCredentials } from "../gcloud/getAdminSdkCredentials";
import { getGoogleAuthToken } from "../gcloud/getGoogleAuthToken";
import type { QueueName } from "./queueName";
export async function removeTask(
env: Env,
queueName: QueueName,
taskId: string,
) {
export async function removeTask(queueName: QueueName, taskId: string) {
const adminSdkCredentials = getAdminSdkCredentials(env);
const { projectId } = adminSdkCredentials;

View File

@@ -1,7 +1,5 @@
import type { Env } from "~/types/env";
/** Should only be used when it doesn't make sense for 'Bindings' or 'Variables' to be set. Otherwise, use getTestEnv(). */
export function getTestEnvVariables(): Omit<Env, "Bindings" | "Variables"> {
export function getTestEnvVariables(): Cloudflare.Env {
return getTestEnv();
}
@@ -10,7 +8,7 @@ export function getTestEnv({
ENABLE_ANIFY = "true",
TURSO_AUTH_TOKEN = "123",
TURSO_URL = "http://127.0.0.1:3001",
}: Partial<Env> = {}): Env {
}: Partial<Cloudflare.Env> = {}): Cloudflare.Env {
return {
ADMIN_SDK_JSON,
ENABLE_ANIFY,