|
|
- import { getDateDifference } from './system/date';
-
- export const enum SubscriptionPlanId {
- Free = 'free',
- FreePlus = 'free+',
- Pro = 'pro',
- Teams = 'teams',
- Enterprise = 'enterprise',
- }
-
- export type FreeSubscriptionPlans = Extract<SubscriptionPlanId, SubscriptionPlanId.Free | SubscriptionPlanId.FreePlus>;
- export type PaidSubscriptionPlans = Exclude<SubscriptionPlanId, SubscriptionPlanId.Free | SubscriptionPlanId.FreePlus>;
- export type RequiredSubscriptionPlans = Exclude<SubscriptionPlanId, SubscriptionPlanId.Free>;
-
- export interface Subscription {
- readonly plan: {
- readonly actual: SubscriptionPlan;
- readonly effective: SubscriptionPlan;
- };
- account: SubscriptionAccount | undefined;
- previewTrial?: SubscriptionPreviewTrial;
-
- state: SubscriptionState;
- }
-
- export interface SubscriptionPlan {
- readonly id: SubscriptionPlanId;
- readonly name: string;
- readonly startedOn: string;
- readonly expiresOn?: string | undefined;
- }
-
- export interface SubscriptionAccount {
- readonly id: string;
- readonly name: string;
- readonly email: string | undefined;
- readonly verified: boolean;
- }
-
- export interface SubscriptionPreviewTrial {
- readonly startedOn: string;
- readonly expiresOn: string;
- }
-
- export const enum SubscriptionState {
- /** Indicates a user who hasn't verified their email address yet */
- VerificationRequired = -1,
- /** Indicates a Free user who hasn't yet started the preview trial */
- Free = 0,
- /** Indicates a Free user who is in preview trial */
- FreeInPreview,
- /** Indicates a Free user who's preview has expired trial */
- FreePreviewExpired,
- /** Indicates a Free+ user with a completed trial */
- FreePlusInTrial,
- /** Indicates a Free+ user who's trial has expired */
- FreePlusTrialExpired,
- /** Indicates a Paid user */
- Paid,
- }
-
- export function computeSubscriptionState(subscription: Optional<Subscription, 'state'>): SubscriptionState {
- const {
- account,
- plan: { actual, effective },
- previewTrial: preview,
- } = subscription;
-
- if (account?.verified === false) return SubscriptionState.VerificationRequired;
-
- if (actual.id === effective.id) {
- switch (effective.id) {
- case SubscriptionPlanId.Free:
- return preview == null ? SubscriptionState.Free : SubscriptionState.FreePreviewExpired;
-
- case SubscriptionPlanId.FreePlus:
- return SubscriptionState.FreePlusTrialExpired;
-
- case SubscriptionPlanId.Pro:
- case SubscriptionPlanId.Teams:
- case SubscriptionPlanId.Enterprise:
- return SubscriptionState.Paid;
- }
- }
-
- switch (effective.id) {
- case SubscriptionPlanId.Free:
- return preview == null ? SubscriptionState.Free : SubscriptionState.FreeInPreview;
-
- case SubscriptionPlanId.FreePlus:
- return SubscriptionState.FreePlusTrialExpired;
-
- case SubscriptionPlanId.Pro:
- return actual.id === SubscriptionPlanId.Free
- ? SubscriptionState.FreeInPreview
- : SubscriptionState.FreePlusInTrial;
-
- case SubscriptionPlanId.Teams:
- case SubscriptionPlanId.Enterprise:
- return SubscriptionState.Paid;
- }
- }
-
- export function getSubscriptionPlan(id: SubscriptionPlanId, startedOn?: Date, expiresOn?: Date): SubscriptionPlan {
- return {
- id: id,
- name: getSubscriptionPlanName(id),
- startedOn: (startedOn ?? new Date()).toISOString(),
- expiresOn: expiresOn != null ? expiresOn.toISOString() : undefined,
- };
- }
-
- export function getSubscriptionPlanName(id: SubscriptionPlanId) {
- switch (id) {
- case SubscriptionPlanId.FreePlus:
- return 'GitLens Free+';
- case SubscriptionPlanId.Pro:
- return 'GitLens Pro';
- case SubscriptionPlanId.Teams:
- return 'GitLens Teams';
- case SubscriptionPlanId.Enterprise:
- return 'GitLens Enterprise';
- case SubscriptionPlanId.Free:
- default:
- return 'GitLens Free';
- }
- }
-
- const plansPriority = new Map<SubscriptionPlanId | undefined, number>([
- [undefined, -1],
- [SubscriptionPlanId.Free, 0],
- [SubscriptionPlanId.FreePlus, 1],
- [SubscriptionPlanId.Pro, 2],
- [SubscriptionPlanId.Teams, 3],
- [SubscriptionPlanId.Enterprise, 4],
- ]);
-
- export function getSubscriptionPlanPriority(id: SubscriptionPlanId | undefined): number {
- return plansPriority.get(id)!;
- }
-
- export function getSubscriptionTimeRemaining(
- subscription: Optional<Subscription, 'state'>,
- unit?: 'days' | 'hours' | 'minutes' | 'seconds',
- ): number | undefined {
- return getTimeRemaining(subscription.plan.effective.expiresOn, unit);
- }
-
- export function getTimeRemaining(
- expiresOn: string | undefined,
- unit?: 'days' | 'hours' | 'minutes' | 'seconds',
- ): number | undefined {
- return expiresOn != null ? getDateDifference(Date.now(), new Date(expiresOn), unit) : undefined;
- }
-
- export function isSubscriptionPaid(subscription: Optional<Subscription, 'state'>): boolean {
- return isSubscriptionPaidPlan(subscription.plan.effective.id);
- }
-
- export function isSubscriptionPaidPlan(id: SubscriptionPlanId): id is PaidSubscriptionPlans {
- return id !== SubscriptionPlanId.Free && id !== SubscriptionPlanId.FreePlus;
- }
-
- export function isSubscriptionExpired(subscription: Optional<Subscription, 'state'>): boolean {
- const remaining = getSubscriptionTimeRemaining(subscription);
- return remaining != null && remaining <= 0;
- }
-
- export function isSubscriptionTrial(subscription: Optional<Subscription, 'state'>): boolean {
- return subscription.plan.actual.id !== subscription.plan.effective.id;
- }
-
- export function isSubscriptionPreviewTrialExpired(subscription: Optional<Subscription, 'state'>): boolean | undefined {
- const remaining = getTimeRemaining(subscription.previewTrial?.expiresOn);
- return remaining != null ? remaining <= 0 : undefined;
- }
|