mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 01:35:39 -04:00
Extract shared constants into lib/constants.ts
- Add `lib/constants.ts` exporting `DATA_DIR`, `DATABASE_URL`, `CACHE_DIR`, `BACKUP_DIR`, `AVATAR_DIR`, `TMDB_API_BASE_URL`, and `TMDB_IMAGE_BASE_URL` - Replace inline `process.env` derivations in `db/client`, `backup`, `image-cache`, `system-health`, `tmdb/client`, `actions/settings`, and `api/avatars` with imports from the new module
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { type NextRequest, NextResponse } from "next/server";
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
|
import { AVATAR_DIR } from "@/lib/constants";
|
||||||
const DATA_DIR = process.env.DATA_DIR || "./data";
|
|
||||||
const AVATAR_DIR = path.join(DATA_DIR, "avatars");
|
|
||||||
|
|
||||||
const IMMUTABLE_CACHE = "public, max-age=31536000, immutable";
|
const IMMUTABLE_CACHE = "public, max-age=31536000, immutable";
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { headers } from "next/headers";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { auth } from "@/lib/auth/server";
|
import { auth } from "@/lib/auth/server";
|
||||||
import { requireAdmin, requireSession } from "@/lib/auth/session";
|
import { requireAdmin, requireSession } from "@/lib/auth/session";
|
||||||
|
import { AVATAR_DIR } from "@/lib/constants";
|
||||||
import { type BackupFrequency, rescheduleBackup, triggerJob } from "@/lib/cron";
|
import { type BackupFrequency, rescheduleBackup, triggerJob } from "@/lib/cron";
|
||||||
import { db } from "@/lib/db/client";
|
import { db } from "@/lib/db/client";
|
||||||
import { integrations } from "@/lib/db/schema";
|
import { integrations } from "@/lib/db/schema";
|
||||||
@@ -268,8 +269,6 @@ export async function getUpdateCheckAction(): Promise<UpdateCheckResult | null>
|
|||||||
|
|
||||||
// --- Avatar actions ---
|
// --- Avatar actions ---
|
||||||
|
|
||||||
const DATA_DIR = process.env.DATA_DIR || "./data";
|
|
||||||
const AVATAR_DIR = path.join(DATA_DIR, "avatars");
|
|
||||||
const MAX_AVATAR_SIZE = 2 * 1024 * 1024; // 2MB
|
const MAX_AVATAR_SIZE = 2 * 1024 * 1024; // 2MB
|
||||||
const ALLOWED_AVATAR_TYPES = new Set([
|
const ALLOWED_AVATAR_TYPES = new Set([
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
|
||||||
|
export const DATA_DIR = process.env.DATA_DIR || "./data";
|
||||||
|
|
||||||
|
export const DATABASE_URL =
|
||||||
|
process.env.DATABASE_URL || path.join(DATA_DIR, "sqlite.db");
|
||||||
|
|
||||||
|
export const CACHE_DIR = process.env.CACHE_DIR
|
||||||
|
? path.join(process.env.CACHE_DIR, "images")
|
||||||
|
: path.join(DATA_DIR, "images");
|
||||||
|
|
||||||
|
export const BACKUP_DIR = path.join(DATA_DIR, "backups");
|
||||||
|
|
||||||
|
export const AVATAR_DIR = path.join(DATA_DIR, "avatars");
|
||||||
|
|
||||||
|
export const TMDB_API_BASE_URL =
|
||||||
|
process.env.TMDB_API_BASE_URL || "https://api.themoviedb.org/3";
|
||||||
|
|
||||||
|
export const TMDB_IMAGE_BASE_URL =
|
||||||
|
process.env.TMDB_IMAGE_BASE_URL || "https://image.tmdb.org/t/p";
|
||||||
+1
-5
@@ -1,7 +1,7 @@
|
|||||||
import { Database } from "bun:sqlite";
|
import { Database } from "bun:sqlite";
|
||||||
import path from "node:path";
|
|
||||||
import type { Logger } from "drizzle-orm";
|
import type { Logger } from "drizzle-orm";
|
||||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||||
|
import { DATABASE_URL } from "@/lib/constants";
|
||||||
import { createLogger } from "@/lib/logger";
|
import { createLogger } from "@/lib/logger";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
|
|
||||||
@@ -29,10 +29,6 @@ const globalForDb = globalThis as unknown as {
|
|||||||
_client: Database | undefined;
|
_client: Database | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DATABASE_URL =
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
path.join(process.env.DATA_DIR || "./data", "sqlite.db");
|
|
||||||
|
|
||||||
function getClient() {
|
function getClient() {
|
||||||
if (!globalForDb._client) {
|
if (!globalForDb._client) {
|
||||||
globalForDb._client = new Database(DATABASE_URL);
|
globalForDb._client = new Database(DATABASE_URL);
|
||||||
|
|||||||
@@ -4,17 +4,13 @@ import { mkdir, readdir } from "node:fs/promises";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { sql } from "drizzle-orm";
|
import { sql } from "drizzle-orm";
|
||||||
|
import { BACKUP_DIR, DATABASE_URL } from "@/lib/constants";
|
||||||
import { closeDatabase, db } from "@/lib/db/client";
|
import { closeDatabase, db } from "@/lib/db/client";
|
||||||
import { runMigrations } from "@/lib/db/migrate";
|
import { runMigrations } from "@/lib/db/migrate";
|
||||||
import { createLogger } from "@/lib/logger";
|
import { createLogger } from "@/lib/logger";
|
||||||
|
|
||||||
const log = createLogger("backup");
|
const log = createLogger("backup");
|
||||||
|
|
||||||
const DATA_DIR = process.env.DATA_DIR || "./data";
|
|
||||||
const DATABASE_URL =
|
|
||||||
process.env.DATABASE_URL || path.join(DATA_DIR, "sqlite.db");
|
|
||||||
const BACKUP_DIR = path.join(DATA_DIR, "backups");
|
|
||||||
|
|
||||||
const MANUAL_PATTERN = /^sofa-manual-\d{4}-\d{2}-\d{2}-\d{6}(?:\d{3})?\.db$/;
|
const MANUAL_PATTERN = /^sofa-manual-\d{4}-\d{2}-\d{2}-\d{6}(?:\d{3})?\.db$/;
|
||||||
const SCHEDULED_PATTERN =
|
const SCHEDULED_PATTERN =
|
||||||
/^sofa-scheduled-\d{4}-\d{2}-\d{2}-\d{6}(?:\d{3})?\.db$/;
|
/^sofa-scheduled-\d{4}-\d{2}-\d{2}-\d{6}(?:\d{3})?\.db$/;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { mkdir, rename } from "node:fs/promises";
|
import { mkdir, rename } from "node:fs/promises";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { eq, inArray } from "drizzle-orm";
|
import { eq, inArray } from "drizzle-orm";
|
||||||
|
import { CACHE_DIR, TMDB_IMAGE_BASE_URL } from "@/lib/constants";
|
||||||
import { db } from "@/lib/db/client";
|
import { db } from "@/lib/db/client";
|
||||||
import {
|
import {
|
||||||
availabilityOffers,
|
availabilityOffers,
|
||||||
@@ -29,14 +30,6 @@ const CATEGORY_SIZES: Record<ImageCategory, string> = {
|
|||||||
profiles: "w185",
|
profiles: "w185",
|
||||||
};
|
};
|
||||||
|
|
||||||
const IMAGE_BASE_URL =
|
|
||||||
process.env.TMDB_IMAGE_BASE_URL || "https://image.tmdb.org/t/p";
|
|
||||||
|
|
||||||
const DATA_DIR = process.env.DATA_DIR || "./data";
|
|
||||||
const CACHE_DIR = process.env.CACHE_DIR
|
|
||||||
? path.join(process.env.CACHE_DIR, "images")
|
|
||||||
: path.join(DATA_DIR, "images");
|
|
||||||
|
|
||||||
export function imageCacheEnabled(): boolean {
|
export function imageCacheEnabled(): boolean {
|
||||||
return process.env.IMAGE_CACHE_ENABLED !== "false";
|
return process.env.IMAGE_CACHE_ENABLED !== "false";
|
||||||
}
|
}
|
||||||
@@ -76,7 +69,7 @@ export async function downloadAndCacheImage(
|
|||||||
category: ImageCategory,
|
category: ImageCategory,
|
||||||
): Promise<Buffer | null> {
|
): Promise<Buffer | null> {
|
||||||
const size = CATEGORY_SIZES[category];
|
const size = CATEGORY_SIZES[category];
|
||||||
const url = `${IMAGE_BASE_URL}/${size}${tmdbPath}`;
|
const url = `${TMDB_IMAGE_BASE_URL}/${size}${tmdbPath}`;
|
||||||
|
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@@ -121,7 +114,7 @@ export async function fetchAndMaybeCache(
|
|||||||
|
|
||||||
// Fetch from TMDB
|
// Fetch from TMDB
|
||||||
const size = CATEGORY_SIZES[category];
|
const size = CATEGORY_SIZES[category];
|
||||||
const url = `${IMAGE_BASE_URL}/${size}${tmdbPath}`;
|
const url = `${TMDB_IMAGE_BASE_URL}/${size}${tmdbPath}`;
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
log.warn(`Fetch failed: ${url} -> ${res.status}`);
|
log.warn(`Fetch failed: ${url} -> ${res.status}`);
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { access, constants, readdir } from "node:fs/promises";
|
import { access, constants, readdir } from "node:fs/promises";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { count, desc, eq } from "drizzle-orm";
|
import { count, desc, eq } from "drizzle-orm";
|
||||||
|
import {
|
||||||
|
CACHE_DIR,
|
||||||
|
DATA_DIR,
|
||||||
|
DATABASE_URL,
|
||||||
|
TMDB_API_BASE_URL,
|
||||||
|
} from "@/lib/constants";
|
||||||
import { db } from "@/lib/db/client";
|
import { db } from "@/lib/db/client";
|
||||||
import { cronRuns, episodes, titles, user } from "@/lib/db/schema";
|
import { cronRuns, episodes, titles, user } from "@/lib/db/schema";
|
||||||
import { listBackups } from "@/lib/services/backup";
|
import { listBackups } from "@/lib/services/backup";
|
||||||
@@ -8,15 +14,6 @@ import { imageCacheEnabled } from "@/lib/services/image-cache";
|
|||||||
import { getSetting } from "@/lib/services/settings";
|
import { getSetting } from "@/lib/services/settings";
|
||||||
import { isUpdateCheckEnabled } from "@/lib/services/update-check";
|
import { isUpdateCheckEnabled } from "@/lib/services/update-check";
|
||||||
|
|
||||||
const DATA_DIR = process.env.DATA_DIR || "./data";
|
|
||||||
const DATABASE_URL =
|
|
||||||
process.env.DATABASE_URL || path.join(DATA_DIR, "sqlite.db");
|
|
||||||
const CACHE_DIR = process.env.CACHE_DIR
|
|
||||||
? path.join(process.env.CACHE_DIR, "images")
|
|
||||||
: path.join(DATA_DIR, "images");
|
|
||||||
const TMDB_API_BASE_URL =
|
|
||||||
process.env.TMDB_API_BASE_URL || "https://api.themoviedb.org/3";
|
|
||||||
|
|
||||||
export interface SystemHealthData {
|
export interface SystemHealthData {
|
||||||
database: {
|
database: {
|
||||||
dbSizeBytes: number;
|
dbSizeBytes: number;
|
||||||
|
|||||||
+2
-4
@@ -1,3 +1,4 @@
|
|||||||
|
import { TMDB_API_BASE_URL } from "@/lib/constants";
|
||||||
import { createLogger } from "@/lib/logger";
|
import { createLogger } from "@/lib/logger";
|
||||||
import type {
|
import type {
|
||||||
TmdbExternalIds,
|
TmdbExternalIds,
|
||||||
@@ -18,9 +19,6 @@ import type {
|
|||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
const log = createLogger("tmdb");
|
const log = createLogger("tmdb");
|
||||||
|
|
||||||
const BASE_URL =
|
|
||||||
process.env.TMDB_API_BASE_URL || "https://api.themoviedb.org/3";
|
|
||||||
function getApiKey() {
|
function getApiKey() {
|
||||||
const key = process.env.TMDB_API_READ_ACCESS_TOKEN;
|
const key = process.env.TMDB_API_READ_ACCESS_TOKEN;
|
||||||
if (!key) throw new Error("TMDB_API_READ_ACCESS_TOKEN is not set");
|
if (!key) throw new Error("TMDB_API_READ_ACCESS_TOKEN is not set");
|
||||||
@@ -32,7 +30,7 @@ async function tmdbFetch<T>(
|
|||||||
params?: Record<string, string>,
|
params?: Record<string, string>,
|
||||||
fetchOptions?: RequestInit,
|
fetchOptions?: RequestInit,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = new URL(`${BASE_URL}${path}`);
|
const url = new URL(`${TMDB_API_BASE_URL}${path}`);
|
||||||
if (params) {
|
if (params) {
|
||||||
for (const [k, v] of Object.entries(params)) {
|
for (const [k, v] of Object.entries(params)) {
|
||||||
url.searchParams.set(k, v);
|
url.searchParams.set(k, v);
|
||||||
|
|||||||
Reference in New Issue
Block a user