import { getResolution, RESOLUTIONS } from "./constants"; export type PlanLimits = { monthlyQuota: number; maxBatchSize: number; maxResolutionHeight: number; maxFileSizeBytes: number; watermarkOptional: boolean; /** Custom text / PNG logo + position controls (Pro). */ customWatermark: boolean; /** Pair a unique cover image per audio in a batch (Pro). */ perItemImages: boolean; /** Blurred cover background + art-track layout templates (Pro). */ artTrackLayouts: boolean; allowedAudioExtensions: readonly string[]; id3TagSupport: boolean; }; export const APP_LIMITS: PlanLimits = { monthlyQuota: Number.MAX_SAFE_INTEGER, maxBatchSize: 100, maxResolutionHeight: Math.max(...RESOLUTIONS.map((r) => r.height)), maxFileSizeBytes: 500 * 1024 * 1024, watermarkOptional: true, customWatermark: true, perItemImages: true, artTrackLayouts: true, allowedAudioExtensions: [".mp3", ".wav", ".flac"], id3TagSupport: true, }; export const SUPPORT_EMAIL = "songs2vid@atakanozban.com"; export const GITEA_ISSUES_URL = process.env.NEXT_PUBLIC_GITEA_ISSUES_URL ?? "https://git.atakanozban.com/Songs2VID/songs2vid/issues"; export const GITEA_URL = process.env.NEXT_PUBLIC_GITEA_URL ?? "https://git.atakanozban.com/Songs2VID"; export const DOCKER_HUB_URL = process.env.NEXT_PUBLIC_DOCKER_HUB_URL ?? "https://hub.docker.com/r/atakanozban/songs2vid"; export function resolveDocsUrl(): string { if (process.env.NEXT_PUBLIC_DOCS_URL?.trim()) { return process.env.NEXT_PUBLIC_DOCS_URL.replace(/\/$/, ""); } return "https://docs.songs2vid.com"; } export const DOCS_URL = resolveDocsUrl(); export const API_DOCS_URL = `${DOCS_URL}/docs/api/overview`; export function getPlanLimits(): PlanLimits { return APP_LIMITS; } export function getResolutionsForPlan() { const maxHeight = APP_LIMITS.maxResolutionHeight; return RESOLUTIONS.filter((r) => r.height <= maxHeight); } export function isResolutionAllowedForPlan(resolution: string): boolean { const res = getResolution(resolution); if (!res) return false; return res.height <= APP_LIMITS.maxResolutionHeight; } export function isAudioExtensionAllowed(filename: string): boolean { const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase(); return APP_LIMITS.allowedAudioExtensions.includes(ext); }