import path from "path"; import type { Plan } from "@prisma/client"; import { hasProFeatures } from "./edition"; import { DEFAULT_WATERMARK, normalizeWatermarkSettings, type WatermarkSettings, } from "./watermark"; /** Free users get this many lifetime watermark-free successful videos. */ export const FREE_UNWATERMARKED_VIDEO_LIMIT = 2; export type SubscriptionStatusLabel = "free" | "pro"; export function subscriptionStatusFromPlan(plan: Plan): SubscriptionStatusLabel { return hasProFeatures(plan) ? "pro" : "free"; } /** * Whether the Songs2VID brand watermark must be applied for this render slot. * Pro / self-hosted: never forced. Free: forced after FREE_UNWATERMARKED_VIDEO_LIMIT. */ export function shouldApplyBrandWatermark(options: { plan: Plan; createdVideoCount: number; /** 0-based index within the current batch (accounts for multi-file jobs). */ itemIndex?: number; }): boolean { if (hasProFeatures(options.plan)) return false; const slot = options.createdVideoCount + (options.itemIndex ?? 0); return slot >= FREE_UNWATERMARKED_VIDEO_LIMIT; } /** * Apply free/pro brand-watermark policy to normalized settings. * - Pro: strip default brand watermark (custom text/logo kept). * - Free under limit: force mode `none`. * - Free at/over limit: force default brand overlay (bottom-right). */ export function applyBrandWatermarkPolicy( input: Partial | null | undefined, includeWatermarkFallback: boolean, options: { plan: Plan; createdVideoCount: number; itemIndex?: number; }, ): WatermarkSettings { const base = normalizeWatermarkSettings(input, includeWatermarkFallback); if (hasProFeatures(options.plan)) { if (base.mode === "default") { return { ...base, mode: "none" }; } return base; } if (shouldApplyBrandWatermark(options)) { return { ...DEFAULT_WATERMARK, mode: "default", position: "bottom-right", offsetX: 20, offsetY: 20, }; } return { ...base, mode: "none", }; } export function watermarkFreeRendersRemaining(createdVideoCount: number): number { return Math.max(0, FREE_UNWATERMARKED_VIDEO_LIMIT - createdVideoCount); } /** Absolute path to the Songs2VID brand watermark asset (PNG). */ export const WATERMARK_FILE_PATH = path.join(process.cwd(), "assets", "watermark.png");