UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

57 lines (50 loc) 1.73 kB
import { z } from "alepha"; import { $parameter } from "alepha/api/parameters"; import { BadRequestError } from "alepha/server"; import { type PlanDefinition, planDefinitionSchema, } from "../schemas/planDefinitionSchema.ts"; import { type SubscriptionSettings, subscriptionSettingsSchema, } from "../schemas/subscriptionSettingsSchema.ts"; export class SubscriptionConfig { protected readonly plans = $parameter({ name: "subscriptions.plans", description: "Subscription plan definitions", schema: z.object({ plans: z.array(planDefinitionSchema) }), default: { plans: [] }, }); protected readonly settings = $parameter({ name: "subscriptions.settings", description: "Global subscription settings", schema: subscriptionSettingsSchema, default: { trialDays: 14, gracePeriodDays: 7, dunningSchedule: [1, 3, 5, 7], cancelAtPeriodEnd: true, prorateOnChange: true, }, }); public async getPlans(): Promise<PlanDefinition[]> { return (await this.plans.get()).plans; } public async getSettings(): Promise<SubscriptionSettings> { return this.settings.get(); } public async getPlan(planId: string): Promise<PlanDefinition> { const plans = await this.getPlans(); const plan = plans.find((p) => p.id === planId); if (!plan) throw new BadRequestError(`Plan '${planId}' not found`); return plan; } public async getPlanPricing(planId: string, interval: "monthly" | "yearly") { const plan = await this.getPlan(planId); const pricing = plan.pricing.find((p) => p.interval === interval); if (!pricing) throw new BadRequestError(`No ${interval} pricing for plan '${planId}'`); return pricing; } }