(subscription: any)
| 81 | } |
| 82 | |
| 83 | export function getEffectiveSeats(subscription: any): number { |
| 84 | if (!subscription) { |
| 85 | return 0 |
| 86 | } |
| 87 | |
| 88 | if (isEnterprise(subscription.plan)) { |
| 89 | const metadata = parseEnterpriseSubscriptionMetadata(subscription.metadata) |
| 90 | if (metadata) { |
| 91 | return metadata.seats |
| 92 | } |
| 93 | return 0 |
| 94 | } |
| 95 | |
| 96 | // Mirrors the Stripe subscription's `quantity`. For personal Pro this |
| 97 | // is null in practice, so `?? 0` returns 0. For Team, fall back to 1 |
| 98 | // while the seat value has not yet been synced from Stripe so invite |
| 99 | // and seat-validation flows don't transiently read as zero seats. |
| 100 | if (isTeam(subscription.plan)) { |
| 101 | return subscription.seats ?? (hasPaidSubscriptionStatus(subscription.status) ? 1 : 0) |
| 102 | } |
| 103 | |
| 104 | if (isPro(subscription.plan)) { |
| 105 | return subscription.seats ?? 0 |
| 106 | } |
| 107 | |
| 108 | return 0 |
| 109 | } |
| 110 | |
| 111 | export function checkProPlan(subscription: any): boolean { |
| 112 | return isPro(subscription?.plan) && hasPaidSubscriptionStatus(subscription?.status) |
no test coverage detected