import { D as UsageRecord, E as UpdateSubscriptionInput, T as UpdatePlanInput, a as CreateSubscriptionInput, b as SubscriptionStatus, d as Invoice, g as Plan, i as CreatePlanInput, m as InvoiceWithDetails, r as CreateInvoiceInput, s as FeatureRegistry, w as UpdateInvoiceInput, x as SubscriptionWithPlan, y as Subscription } from "./types-3EaBC58c.js"; //#region src/core/coupons.d.ts /** * How the coupon discount is computed * * - `percent`: percentage off (value is 1-100) * - `fixed`: fixed amount off in the coupon's currency */ type CouponType = 'percent' | 'fixed'; /** * How long a coupon discount applies to a subscription * * - `once`: applies to a single invoice only * - `repeating`: applies for `durationInMonths` billing periods * - `forever`: applies for the lifetime of the subscription */ type CouponDuration = 'once' | 'repeating' | 'forever'; /** * A discount coupon that can be applied to plans and invoices */ interface Coupon { id: string; /** * Unique redemption code. Stored uppercase (normalized on create). */ code: string; type: CouponType; /** * Discount value: percentage (1-100) for `percent` coupons, * amount in `currency` units for `fixed` coupons. */ value: number; /** * Currency for `fixed` coupons. Null for `percent` coupons. */ currency: string | null; duration: CouponDuration; /** * Number of billing periods the discount applies for. * Only meaningful when `duration` is `repeating`. */ durationInMonths: number | null; /** * Maximum number of times the coupon can be redeemed. * Null means unlimited redemptions. */ maxRedemptions: number | null; /** * Expiration date. Null means the coupon never expires. */ expiresAt: Date | null; isActive: boolean; /** * Number of times the coupon has been redeemed so far. */ timesRedeemed: number; metadata: Record | null; createdAt: Date; updatedAt: Date; } interface CreateCouponInput { /** * Redemption code. Normalized to uppercase. */ code: string; type: CouponType; /** * Percentage (1-100) for `percent`, amount in currency units for `fixed`. */ value: number; /** * Currency for `fixed` coupons. Defaults to the service default currency. */ currency?: string | undefined; /** * @default 'once' */ duration?: CouponDuration | undefined; /** * Required when `duration` is `repeating`. */ durationInMonths?: number | undefined; maxRedemptions?: number | undefined; expiresAt?: Date | undefined; /** * @default true */ isActive?: boolean | undefined; metadata?: Record | undefined; } interface UpdateCouponInput { type?: CouponType; value?: number; currency?: string | null; duration?: CouponDuration; durationInMonths?: number | null; maxRedemptions?: number | null; expiresAt?: Date | null; isActive?: boolean; metadata?: Record; } /** * Result of applying a coupon to an amount */ interface AppliedCoupon { coupon: Coupon; /** * Discount amount (always >= 0, never exceeds the original amount). */ discountAmount: number; /** * Final amount after the discount. */ total: number; } //#endregion //#region src/adapters/database.adapter.d.ts /** * Query options for listing subscriptions */ interface SubscriptionQueryOptions { status?: SubscriptionStatus | SubscriptionStatus[]; planId?: string; limit?: number; offset?: number; } /** * Query options for admin listing plans */ interface PlanQueryOptions { /** Filter by active status (true = active only, false = inactive only, undefined = all) */ isActive?: boolean; /** Filter by billing interval (monthly, yearly, etc.) */ interval?: string; /** Pagination limit */ limit?: number; /** Pagination offset */ offset?: number; } /** * Database adapter interface * * Implement this interface to connect the subscriptions package to your database. * The package ships with a Prisma adapter, but you can implement your own. */ interface DatabaseAdapter { plans: { /** * Find a plan by ID */ findById(id: string): Promise | null>; /** * List all plans */ findAll(options?: { activeOnly?: boolean; }): Promise[]>; /** * List all plans with advanced filtering for admin * Returns plans and total count for pagination */ findAllForAdmin(options?: PlanQueryOptions): Promise<{ plans: Plan[]; total: number; }>; /** * Create a new plan */ create(data: CreatePlanInput): Promise>; /** * Update an existing plan */ update(id: string, data: UpdatePlanInput): Promise>; /** * Delete a plan (soft delete recommended) */ delete(id: string): Promise; /** * Check if a plan has active subscribers */ hasActiveSubscribers(id: string): Promise; /** * Check if a plan is referenced by any pending downgrade */ hasPendingDowngrades(id: string): Promise; }; subscriptions: { /** * Find a subscription by ID */ findById(id: string): Promise | null>; /** * Find subscription by subscriber ID (returns the active subscription) */ findBySubscriber(subscriberId: string): Promise | null>; /** * List subscriptions with optional filters */ findAll(options?: SubscriptionQueryOptions): Promise; /** * Create a new subscription */ create(data: CreateSubscriptionInput): Promise; /** * Update an existing subscription */ update(id: string, data: UpdateSubscriptionInput): Promise; /** * Delete a subscription */ delete(id: string): Promise; /** * Find subscriptions expiring within the given days */ findExpiring(withinDays: number): Promise; }; invoices: { /** * Find an invoice by ID */ findById(id: string): Promise; /** * Find an invoice by ID with subscription and plan details */ findByIdWithDetails(id: string): Promise | null>; /** * Find an invoice by its gateway payment/invoice ID. * * Optional. When implemented, it enables idempotent webhook handling so * that a single gateway payment never produces duplicate invoices or * duplicate subscription renewals. Adapters that cannot support this can * omit it; the package degrades gracefully (without idempotency). */ findByGatewayInvoiceId?(gatewayInvoiceId: string): Promise; /** * Find invoices for a subscription */ findBySubscription(subscriptionId: string): Promise; /** * Find invoices for a subscriber (by subscriber ID) */ findBySubscriber(subscriberId: string): Promise; /** * Create a new invoice */ create(data: CreateInvoiceInput): Promise; /** * Update an invoice */ update(id: string, data: UpdateInvoiceInput): Promise; /** * Atomically generate the next sequential invoice number. * * Optional. When implemented, `InvoicesService.create()` assigns a * human-readable `invoiceNumber` (e.g. `INV-000123`) to new invoices. * Adapters that cannot guarantee atomic sequencing can omit it; the * package degrades gracefully by leaving `invoiceNumber` null. * * @param prefix - Number prefix (e.g. 'INV-'), provided by the service */ nextInvoiceNumber?(prefix: string): Promise; }; /** * Coupon persistence. * * Optional. When omitted, `CouponsService` degrades gracefully by throwing * a helpful setup error telling the integrator to implement this section * (or to add the `Coupon` model when using the Prisma adapter — see * docs/prisma-schema.md). */ coupons?: { /** * Find a coupon by its (uppercase) redemption code */ findByCode(code: string): Promise; /** * Find a coupon by ID */ findById(id: string): Promise; /** * Create a new coupon */ create(data: CreateCouponInput): Promise; /** * Update an existing coupon */ update(id: string, data: UpdateCouponInput): Promise; /** * Atomically increment the redemption counter * @returns The updated coupon */ incrementRedemptions(id: string): Promise; }; usage: { /** * Get current usage count for a feature * @param subscriberId - The subscriber ID (user who owns the subscription) * @param feature - The feature key * @param options - Optional: period date and tenantId for tenant-scoped features */ get(subscriberId: string, feature: string, options?: { period?: Date; tenantId?: string | null; }): Promise; /** * Increment usage count atomically * @param subscriberId - The subscriber ID * @param feature - The feature key * @param options - Optional: count and tenantId for tenant-scoped features * @returns The new count after increment */ increment(subscriberId: string, feature: string, options?: { count?: number; tenantId?: string | null; }): Promise; /** * Decrement usage count atomically * @param subscriberId - The subscriber ID * @param feature - The feature key * @param options - Optional: count and tenantId for tenant-scoped features * @returns The new count after decrement (never goes below 0) */ decrement(subscriberId: string, feature: string, options?: { count?: number; tenantId?: string | null; }): Promise; /** * Set usage count to a specific value * @param subscriberId - The subscriber ID * @param feature - The feature key * @param count - The count to set * @param tenantId - Optional tenantId for tenant-scoped features */ set(subscriberId: string, feature: string, count: number, tenantId?: string | null): Promise; /** * Reset usage for a subscriber (optionally for a specific feature) * @param subscriberId - The subscriber ID * @param options - Optional: feature to reset and tenantId */ reset(subscriberId: string, options?: { feature?: string; tenantId?: string | null; }): Promise; /** * Get all usage records for a subscriber * @param subscriberId - The subscriber ID * @param tenantId - Optional tenantId to filter by tenant */ getAll(subscriberId: string, tenantId?: string | null): Promise; }; /** * Execute operations within a transaction */ transaction(fn: (tx: DatabaseAdapter) => Promise): Promise; } //#endregion export { Coupon as a, CreateCouponInput as c, AppliedCoupon as i, UpdateCouponInput as l, PlanQueryOptions as n, CouponDuration as o, SubscriptionQueryOptions as r, CouponType as s, DatabaseAdapter as t }; //# sourceMappingURL=database.adapter-oL35G_XI.d.ts.map