Remove Stripe/billing/pricing/marketing, simplify schema and entitlements for unlimited self-host use, and keep auth, encode, and YouTube upload.
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
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);
|
|
}
|