80 lines
2.6 KiB
TypeScript
80 lines
2.6 KiB
TypeScript
import { Plan } from "@prisma/client";
|
|
import { getResolution, RESOLUTIONS } from "./constants";
|
|
import { isSelfHostedEdition } from "./edition";
|
|
|
|
export type PlanLimits = {
|
|
monthlyQuota: number;
|
|
maxBatchSize: number;
|
|
maxResolutionHeight: number;
|
|
maxFileSizeBytes: number;
|
|
watermarkOptional: boolean;
|
|
allowedAudioExtensions: readonly string[];
|
|
id3TagSupport: boolean;
|
|
};
|
|
|
|
export const PLAN_LIMITS: Record<Plan, PlanLimits> = {
|
|
FREE: {
|
|
monthlyQuota: 14,
|
|
maxBatchSize: 3,
|
|
maxResolutionHeight: 720,
|
|
maxFileSizeBytes: 30 * 1024 * 1024,
|
|
watermarkOptional: true,
|
|
allowedAudioExtensions: [".mp3"],
|
|
id3TagSupport: true,
|
|
},
|
|
PREMIUM: {
|
|
monthlyQuota: 50,
|
|
maxBatchSize: 5,
|
|
maxResolutionHeight: 1080,
|
|
maxFileSizeBytes: 30 * 1024 * 1024,
|
|
watermarkOptional: true,
|
|
allowedAudioExtensions: [".mp3", ".wav", ".flac"],
|
|
id3TagSupport: true,
|
|
},
|
|
};
|
|
|
|
export const SELFHOSTED_LIMITS: PlanLimits = {
|
|
monthlyQuota: 1_000_000,
|
|
maxBatchSize: 100,
|
|
maxResolutionHeight: Math.max(...RESOLUTIONS.map((r) => r.height)),
|
|
maxFileSizeBytes: 500 * 1024 * 1024,
|
|
watermarkOptional: true,
|
|
allowedAudioExtensions: [".mp3", ".wav", ".flac"],
|
|
id3TagSupport: true,
|
|
};
|
|
|
|
export const SALES_EMAIL = "songs2yt@atakanozban.com";
|
|
export const SUPPORT_EMAIL = "songs2yt@atakanozban.com";
|
|
export const UPGRADE_URL = "/#pricing";
|
|
export const GITEA_ISSUES_URL =
|
|
process.env.NEXT_PUBLIC_GITEA_ISSUES_URL ?? "https://git.atakanozban.com/Songs2YT/issues";
|
|
export const GITEA_URL =
|
|
process.env.NEXT_PUBLIC_GITEA_URL ?? "https://git.atakanozban.com/Songs2YT";
|
|
export const DOCKER_HUB_URL =
|
|
process.env.NEXT_PUBLIC_DOCKER_HUB_URL ?? "https://hub.docker.com/r/atakanozban/songs2yt";
|
|
|
|
export function getPlanLimits(plan: Plan): PlanLimits {
|
|
if (isSelfHostedEdition()) return SELFHOSTED_LIMITS;
|
|
return PLAN_LIMITS[plan];
|
|
}
|
|
|
|
export function getResolutionsForPlan(plan: Plan) {
|
|
const maxHeight = getPlanLimits(plan).maxResolutionHeight;
|
|
return RESOLUTIONS.filter((r) => r.height <= maxHeight);
|
|
}
|
|
|
|
export function isResolutionAllowedForPlan(resolution: string, plan: Plan): boolean {
|
|
const res = getResolution(resolution);
|
|
if (!res) return false;
|
|
return res.height <= getPlanLimits(plan).maxResolutionHeight;
|
|
}
|
|
|
|
export function isAudioExtensionAllowed(filename: string, plan: Plan): boolean {
|
|
const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase();
|
|
return getPlanLimits(plan).allowedAudioExtensions.includes(ext);
|
|
}
|
|
|
|
export function getNextMonthlyQuotaReset(from: Date = new Date()): Date {
|
|
return new Date(from.getFullYear(), from.getMonth() + 1, 1, 0, 0, 0, 0);
|
|
}
|