@buildbase/sdk 0.0.16 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +201 -98
  2. package/dist/index.d.ts +594 -198
  3. package/dist/index.esm.js +5 -5
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +5 -5
  6. package/dist/index.js.map +1 -1
  7. package/dist/saas-os.css +1 -1
  8. package/dist/types/api/currency-utils.d.ts +44 -0
  9. package/dist/types/api/index.d.ts +11 -0
  10. package/dist/types/api/pricing-variant-utils.d.ts +53 -0
  11. package/dist/types/api/quota-utils.d.ts +24 -0
  12. package/dist/types/api/types.d.ts +118 -43
  13. package/dist/types/components/beta/api.d.ts +1 -2
  14. package/dist/types/components/pricing/PricingPage.d.ts +3 -1
  15. package/dist/types/components/subscription/index.d.ts +108 -0
  16. package/dist/types/contexts/SubscriptionContext/SubscriptionContext.d.ts +22 -0
  17. package/dist/types/contexts/SubscriptionContext/index.d.ts +2 -0
  18. package/dist/types/contexts/SubscriptionContext/subscriptionInvalidation.d.ts +19 -0
  19. package/dist/types/contexts/SubscriptionContext/types.d.ts +12 -0
  20. package/dist/types/contexts/index.d.ts +2 -0
  21. package/dist/types/contexts/shared/types.d.ts +21 -0
  22. package/dist/types/contexts/shared/useAppDispatch.d.ts +2 -12
  23. package/dist/types/contexts/shared/useAppSelector.d.ts +2 -12
  24. package/dist/types/contexts/shared/utils/reducerHelpers.d.ts +2 -2
  25. package/dist/types/index.d.ts +12 -2
  26. package/dist/types/lib/api-base.d.ts +49 -0
  27. package/dist/types/providers/ContextConfigProvider.d.ts +1 -1
  28. package/dist/types/providers/auth/api.d.ts +12 -0
  29. package/dist/types/providers/auth/hooks.d.ts +2 -0
  30. package/dist/types/providers/os/api.d.ts +11 -0
  31. package/dist/types/providers/os/hooks.d.ts +6 -0
  32. package/dist/types/providers/os/types.d.ts +2 -0
  33. package/dist/types/providers/user/api.d.ts +16 -0
  34. package/dist/types/providers/user/hooks.d.ts +1 -0
  35. package/dist/types/providers/workspace/api.d.ts +2 -5
  36. package/dist/types/providers/workspace/hooks.d.ts +11 -1
  37. package/dist/types/providers/workspace/subscription-hooks.d.ts +2 -1
  38. package/dist/types/providers/workspace/types.d.ts +18 -1
  39. package/dist/types/providers/workspace/ui/SubscriptionDialog.d.ts +7 -1
  40. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  interface IDocument {
6
6
  _id: string;
7
- id: string;
7
+ /** Optional; some APIs only return _id. Prefer _id for identity. */
8
+ id?: string;
8
9
  createdAt: string;
9
10
  updatedAt: string;
10
11
  deleted: boolean;
@@ -13,12 +14,17 @@ interface IUser extends IDocument {
13
14
  _id: string;
14
15
  name: string;
15
16
  email: string;
16
- image: string;
17
+ /** Profile image URL. Often omitted or empty from API. */
18
+ image?: string;
17
19
  role: string;
18
- country: string;
19
- timezone: string;
20
- language: string;
21
- currency: string;
20
+ /** ISO country code. May be omitted. */
21
+ country?: string;
22
+ /** IANA timezone. May be omitted. */
23
+ timezone?: string;
24
+ /** Language code. May be omitted. */
25
+ language?: string;
26
+ /** Currency code. May be omitted. */
27
+ currency?: string;
22
28
  attributes?: Record<string, string | number | boolean>;
23
29
  }
24
30
  type BillingInterval = 'monthly' | 'yearly' | 'quarterly';
@@ -28,6 +34,7 @@ interface ISubscription {
28
34
  stripePriceId?: string;
29
35
  stripeCurrentPeriodEnd?: string;
30
36
  cancelAtPeriodEnd: boolean;
37
+ billingInterval?: BillingInterval;
31
38
  createdAt: string;
32
39
  updatedAt: string;
33
40
  plan?: {
@@ -35,6 +42,8 @@ interface ISubscription {
35
42
  name: string;
36
43
  slug: string;
37
44
  description?: string;
45
+ /** Stripe currency code (e.g. 'usd', 'inr', 'eur'). */
46
+ currency?: string;
38
47
  };
39
48
  }
40
49
  interface ISubscriptionItem {
@@ -45,16 +54,62 @@ interface ISubscriptionItem {
45
54
  description?: string;
46
55
  category: string;
47
56
  }
48
- interface IQuotaValue {
57
+ /** Per-interval quota value (plan-group/versions and public plans schema). */
58
+ interface IQuotaIntervalValue {
49
59
  included: number;
60
+ /** Overage price in cents. Omitted in public plans; use pricingVariant.quotaOverages for display. */
50
61
  overage?: number;
51
- stripePriceId?: string;
62
+ /** Stripe price ID for overage. Omitted in public plans; use pricingVariant.quotaOveragePriceIds. */
63
+ priceId?: string;
64
+ /** Unit size for overage pricing (e.g. 1000 = price per 1000 units). */
65
+ unitSize?: number;
66
+ }
67
+ /** Quota defined per billing interval (new plan-group/versions schema) */
68
+ interface IQuotaByInterval {
69
+ monthly?: IQuotaIntervalValue;
70
+ yearly?: IQuotaIntervalValue;
71
+ quarterly?: IQuotaIntervalValue;
52
72
  }
73
+ /** Base pricing per interval. Values are often in cents (Stripe); convert for display. */
53
74
  interface IBasePricing {
54
75
  monthly: number;
55
76
  yearly: number;
56
77
  quarterly: number;
57
78
  }
79
+ /** Stripe price IDs per billing interval (for a single currency variant). */
80
+ interface IStripePricesByInterval {
81
+ monthlyPriceId?: string;
82
+ yearlyPriceId?: string;
83
+ quarterlyPriceId?: string;
84
+ monthly?: string;
85
+ yearly?: string;
86
+ }
87
+ /** Overage amounts in cents per interval, keyed by quota slug. Used in pricing variants. */
88
+ type IQuotaOveragesByInterval = Record<string, {
89
+ monthly?: number;
90
+ yearly?: number;
91
+ quarterly?: number;
92
+ }>;
93
+ /** Overage Stripe price IDs per interval, keyed by quota slug. Used in pricing variants. */
94
+ type IQuotaOveragePriceIdsByInterval = Record<string, {
95
+ monthly?: string;
96
+ yearly?: string;
97
+ quarterly?: string;
98
+ }>;
99
+ /**
100
+ * Multi-currency pricing variant at plan version level.
101
+ * Each plan version can have multiple variants (e.g. usd, eur, inr, sgd).
102
+ */
103
+ interface IPricingVariant {
104
+ _id: string;
105
+ currency: string;
106
+ basePricing: IBasePricing;
107
+ stripePrices: IStripePricesByInterval;
108
+ /** Overage cents per quota slug per interval. */
109
+ quotaOverages?: IQuotaOveragesByInterval;
110
+ /** Stripe price IDs for overage per quota slug per interval. */
111
+ quotaOveragePriceIds?: IQuotaOveragePriceIdsByInterval;
112
+ }
58
113
  interface IPlanVersion {
59
114
  _id: string;
60
115
  version: number;
@@ -62,15 +117,10 @@ interface IPlanVersion {
62
117
  status: 'draft' | 'published';
63
118
  features?: Record<string, boolean>;
64
119
  limits?: Record<string, number>;
65
- quotas?: Record<string, number | IQuotaValue>;
66
- basePricing?: IBasePricing;
67
- stripePrices?: {
68
- monthlyPriceId?: string;
69
- yearlyPriceId?: string;
70
- quarterlyPriceId?: string;
71
- monthly?: string;
72
- yearly?: string;
73
- };
120
+ /** Per-interval quotas (included, unitSize; overage from pricingVariant.quotaOverages). */
121
+ quotas?: Record<string, IQuotaByInterval>;
122
+ /** Multi-currency pricing. Each variant has currency, basePricing, stripePrices, quotaOverages. */
123
+ pricingVariants?: IPricingVariant[];
74
124
  subscriptionItems?: ISubscriptionItem[];
75
125
  isCurrent?: boolean;
76
126
  isLegacy?: boolean;
@@ -79,13 +129,20 @@ interface IPlanVersion {
79
129
  createdAt?: string;
80
130
  updatedAt?: string;
81
131
  id?: string;
132
+ stripeProductId?: string;
133
+ }
134
+ /** Plan version summary (e.g. plan.latestVersion from subscription API) with subscriptionItems as IDs. */
135
+ interface IPlanVersionSummary extends Omit<IPlanVersion, 'subscriptionItems'> {
136
+ subscriptionItems?: string[];
82
137
  }
83
138
  interface IPlan {
84
139
  _id: string;
85
140
  name: string;
86
141
  slug: string;
87
142
  description?: string;
88
- latestVersion?: IPlanVersion;
143
+ /** Stripe currency code (e.g. 'usd', 'inr', 'eur'). Used for pricing display. */
144
+ currency?: string;
145
+ latestVersion?: IPlanVersionSummary;
89
146
  archived?: boolean;
90
147
  deleted?: boolean;
91
148
  createdAt?: string;
@@ -145,13 +202,19 @@ interface ISubscriptionResponse {
145
202
  group: IPlanGroup | null;
146
203
  groupVersion: IPlanGroupVersion | null;
147
204
  }
205
+ /** Plan version with nested plan info (name, slug, currency for display). */
148
206
  interface IPlanVersionWithPlan extends IPlanVersion {
149
207
  plan: IPlan;
150
208
  }
209
+ /**
210
+ * Plan group version with full plan versions (for GET .../plan-group/versions).
211
+ * Each plan has plan, subscriptionItems, quotas (per-interval), pricingVariants.
212
+ */
151
213
  interface IPlanGroupVersionWithPlans {
152
214
  _id: string;
153
215
  version: number;
154
216
  description?: string;
217
+ /** Full plan versions with nested plan (name, slug, currency). */
155
218
  plans: IPlanVersionWithPlan[];
156
219
  isCurrent?: boolean;
157
220
  whatsNew?: {
@@ -160,24 +223,35 @@ interface IPlanGroupVersionWithPlans {
160
223
  removedPlans: IPlanVersionWithPlan[];
161
224
  };
162
225
  }
226
+ interface IPlanGroupInfo {
227
+ _id: string;
228
+ name: string;
229
+ slug: string;
230
+ description?: string;
231
+ }
232
+ /** Response from GET workspaces/:id/subscription/plan-group (and by version). */
163
233
  interface IPlanGroupResponse {
164
- group: {
165
- _id: string;
166
- name: string;
167
- slug: string;
168
- };
169
- currentVersion: IPlanGroupVersionWithPlans;
170
- availableVersions: IPlanGroupVersionWithPlans[];
234
+ /** Plan group with latestVersion, archived, deleted, timestamps. May be null in some API responses. */
235
+ group: IPlanGroup | null;
236
+ /** Current group version with populated planVersionIds (or IDs). */
237
+ groupVersion: IPlanGroupVersion;
238
+ /** Full plan versions for display (subscriptionItems, pricingVariants, quotas). */
239
+ plans: IPlanVersionWithPlan[];
171
240
  }
241
+ /**
242
+ * Response from GET workspaces/:workspaceId/subscription/plan-group/versions.
243
+ * Group summary plus current and available group versions; each version has plans with
244
+ * per-interval quotas and pricingVariants.
245
+ */
172
246
  interface IPlanGroupVersionsResponse {
173
- group: {
174
- _id: string;
175
- name: string;
176
- slug: string;
177
- };
247
+ /** Plan group summary (_id, name, slug). */
248
+ group: IPlanGroupInfo;
249
+ /** Current group version (user's version when subscribed, or latest published when not). */
178
250
  currentVersion: IPlanGroupVersionWithPlans;
251
+ /** Newer versions when user has subscription; empty when no subscription. */
179
252
  availableVersions: IPlanGroupVersionWithPlans[];
180
253
  }
254
+ /** Request body for POST .../workspaces/:id/subscription/checkout. Only these fields are allowed. */
181
255
  interface ICheckoutSessionRequest {
182
256
  planVersionId: string;
183
257
  billingInterval?: BillingInterval;
@@ -195,6 +269,7 @@ interface ICheckoutSessionResponse {
195
269
  name: string;
196
270
  };
197
271
  }
272
+ /** Request body for PATCH .../workspaces/:id/subscription. Only these fields are allowed. */
198
273
  interface ISubscriptionUpdateRequest {
199
274
  planVersionId: string;
200
275
  billingInterval?: BillingInterval;
@@ -221,33 +296,33 @@ interface IPublicPlanItem {
221
296
  _id: string;
222
297
  name: string;
223
298
  slug: string;
224
- description: string;
299
+ description?: string;
225
300
  type: 'feature' | 'limit' | 'quota';
226
301
  category: IPublicPlanItemCategory;
227
302
  }
228
- interface IPublicPlanPricing {
229
- monthly: number;
230
- yearly: number;
231
- quarterly: number;
232
- }
233
- interface IPublicPlanQuotaValue {
234
- included: number;
235
- overage: number;
236
- stripePriceId?: string;
237
- }
303
+ /**
304
+ * Public plan version (e.g. from GET /api/v1/public/:orgId/plans/:slug).
305
+ * Each plan has _id, name (plan display name), version, status, pricingVariants, quotas, features, limits.
306
+ * Pricing is in cents (see response.notes).
307
+ */
238
308
  interface IPublicPlanVersion {
239
309
  _id: string;
310
+ /** Plan display name (e.g. "Pro", "Base Plan"). */
240
311
  name: string;
241
312
  version: number;
242
313
  status: 'draft' | 'published';
243
- pricing: IPublicPlanPricing;
244
- quotas: Record<string, IPublicPlanQuotaValue>;
314
+ /** Multi-currency pricing. Use getBasePriceCents(plan, currency, interval) and getQuotaDisplayWithVariant for display. */
315
+ pricingVariants?: IPricingVariant[];
316
+ /** Keyed by item slug. Per-interval: included, unitSize; overage from pricingVariant.quotaOverages. */
317
+ quotas: Record<string, IQuotaByInterval>;
245
318
  features: Record<string, boolean>;
246
319
  limits: Record<string, number>;
247
320
  }
248
321
  interface IPublicPlansResponse {
249
322
  items: IPublicPlanItem[];
250
323
  plans: IPublicPlanVersion[];
324
+ /** Optional note from API (e.g. "Pricing is in cents. Please convert to dollars for display."). */
325
+ notes?: string;
251
326
  }
252
327
  type InvoiceStatus = 'draft' | 'open' | 'paid' | 'uncollectible' | 'void';
253
328
  interface IInvoice {
@@ -283,7 +358,24 @@ interface IWorkspace {
283
358
  roles: string[];
284
359
  createdBy: string | IUser;
285
360
  features: Record<string, boolean>;
286
- subscription?: ISubscription | null;
361
+ /**
362
+ * Quota usage tracking: { [quotaSlug]: number } – how much of each quota has been used.
363
+ */
364
+ quotas?: Record<string, number>;
365
+ /**
366
+ * Subscription limits snapshot: { [limitSlug]: number | null } – synced from subscription plan.
367
+ * Limits are maximum values (e.g. max-users, max-workspaces). Updated when subscription is assigned/updated.
368
+ */
369
+ limits?: Record<string, number | null>;
370
+ subscription?: ISubscription | string | null;
371
+ /** Stripe Customer ID for this workspace. */
372
+ stripeCustomerId?: string;
373
+ /**
374
+ * Billing currency locked for this workspace (set on first subscription).
375
+ * Stripe allows one currency per customer; all future subscriptions must use this currency.
376
+ * When set, subscription UI only shows/uses this currency.
377
+ */
378
+ billingCurrency?: string | null;
287
379
  }
288
380
  interface IWorkspaceFeature {
289
381
  _id: string;
@@ -477,6 +569,8 @@ interface PricingPageDetails {
477
569
  items: IPublicPlanItem[];
478
570
  /** Plan versions with pricing, features, limits, quotas */
479
571
  plans: IPublicPlanVersion[];
572
+ /** Optional note from API (e.g. "Pricing is in cents. Please convert to dollars for display.") */
573
+ notes?: string;
480
574
  /** Refetch plan data */
481
575
  refetch: () => Promise<void>;
482
576
  }
@@ -512,7 +606,7 @@ interface PricingPageProps {
512
606
  * </PricingPage>
513
607
  * ```
514
608
  */
515
- declare function PricingPage({ slug, children, loadingFallback, errorFallback, }: PricingPageProps): react_jsx_runtime.JSX.Element;
609
+ declare function PricingPage({ slug, children, loadingFallback, errorFallback }: PricingPageProps): react_jsx_runtime.JSX.Element;
516
610
 
517
611
  interface IProps$2 {
518
612
  children: React.ReactNode;
@@ -780,69 +874,149 @@ declare const WhenUserFeatureEnabled: (props: IProps) => react.ReactNode;
780
874
  */
781
875
  declare const WhenUserFeatureDisabled: (props: IProps) => react.ReactNode;
782
876
 
783
- type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'features' | 'danger';
784
-
877
+ interface IWhenSubscriptionProps {
878
+ /** Content to render when the condition is met (workspace has an active subscription). */
879
+ children: React.ReactNode;
880
+ /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
881
+ loadingComponent?: React.ReactNode;
882
+ /** Optional component/element to show when condition is not met (e.g. <UpgradePrompt />). */
883
+ fallbackComponent?: React.ReactNode;
884
+ }
785
885
  /**
786
- * Main authentication hook for the SDK.
787
- * Provides authentication state, user session, and auth actions.
886
+ * Renders children only when the current workspace has an active subscription (any plan).
887
+ * Optionally pass loadingComponent (while loading) or fallbackComponent (when not subscribed).
888
+ * Must be used within SubscriptionContextProvider.
788
889
  *
789
- * @returns An object containing:
790
- * - `user`: Current authenticated user object (null if not authenticated)
791
- * - `session`: Full session object with user and token (null if not authenticated)
792
- * - `status`: Current authentication status (loading, redirecting, authenticating, authenticated, unauthenticated)
793
- * - `isLoading`: Boolean indicating if auth state is being determined
794
- * - `isAuthenticated`: Boolean indicating if user is authenticated
795
- * - `isRedirecting`: Boolean indicating if redirecting to OAuth provider
796
- * - `signIn()`: Function to initiate OAuth sign-in flow
797
- * - `signOut()`: Function to sign out the current user
798
- * - `openWorkspaceSettings(section?)`: Function to open workspace settings dialog
890
+ * @param props - Component props
891
+ * @param props.children - Content to render when subscribed
892
+ * @param props.loadingComponent - Optional component/element to show while loading
893
+ * @param props.fallbackComponent - Optional component/element to show when not subscribed
894
+ * @returns ReactNode - children when subscribed, loadingComponent when loading, fallbackComponent when not subscribed, or null
799
895
  *
800
896
  * @example
801
897
  * ```tsx
802
- * function MyComponent() {
803
- * const { user, isAuthenticated, signIn, signOut } = useSaaSAuth();
898
+ * <WhenSubscription>
899
+ * <BillingSettings />
900
+ * </WhenSubscription>
901
+ * ```
804
902
  *
805
- * if (!isAuthenticated) {
806
- * return <button onClick={signIn}>Sign In</button>;
807
- * }
903
+ * @example
904
+ * ```tsx
905
+ * <WhenSubscription
906
+ * loadingComponent={<Skeleton />}
907
+ * fallbackComponent={<UpgradePrompt />}
908
+ * >
909
+ * <BillingSettings />
910
+ * </WhenSubscription>
911
+ * ```
912
+ */
913
+ declare const WhenSubscription: (props: IWhenSubscriptionProps) => react.ReactNode;
914
+ /**
915
+ * Renders children only when the current workspace has no subscription (or no current workspace).
916
+ * Optionally pass loadingComponent (while loading) or fallbackComponent (when already subscribed).
917
+ * Must be used within SubscriptionContextProvider.
808
918
  *
809
- * return (
810
- * <div>
811
- * <p>Welcome, {user?.name}</p>
812
- * <button onClick={signOut}>Sign Out</button>
813
- * </div>
814
- * );
815
- * }
919
+ * @param props - Component props
920
+ * @param props.children - Content to render when not subscribed
921
+ * @param props.loadingComponent - Optional component/element to show while loading
922
+ * @param props.fallbackComponent - Optional component/element to show when already subscribed
923
+ * @returns ReactNode - children when not subscribed, loadingComponent when loading, fallbackComponent when subscribed, or null
924
+ *
925
+ * @example
926
+ * ```tsx
927
+ * <WhenNoSubscription>
928
+ * <UpgradePrompt />
929
+ * </WhenNoSubscription>
816
930
  * ```
817
931
  *
818
932
  * @example
819
933
  * ```tsx
820
- * // Handle loading state
821
- * function App() {
822
- * const { status, isLoading } = useSaaSAuth();
934
+ * <WhenNoSubscription
935
+ * loadingComponent={<Spinner />}
936
+ * fallbackComponent={null}
937
+ * >
938
+ * <UpgradePrompt />
939
+ * </WhenNoSubscription>
940
+ * ```
941
+ */
942
+ declare const WhenNoSubscription: (props: IWhenSubscriptionProps) => react.ReactNode;
943
+ interface IWhenSubscriptionToPlansProps {
944
+ /** Plan slugs to match (e.g. ['pro', 'enterprise']). Matching is case-insensitive. */
945
+ plans: string[];
946
+ /** Content to render when the workspace is on one of the given plans. */
947
+ children: React.ReactNode;
948
+ /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
949
+ loadingComponent?: React.ReactNode;
950
+ /** Optional component/element to show when not on a matching plan (e.g. <UpgradeToPro />). */
951
+ fallbackComponent?: React.ReactNode;
952
+ }
953
+ /**
954
+ * Renders children only when the current workspace is subscribed to one of the given plans.
955
+ * Matches by plan slug only. Optionally pass loadingComponent (while loading) or fallbackComponent (when not on a matching plan).
956
+ * Must be used within SubscriptionContextProvider.
823
957
  *
824
- * if (isLoading) {
825
- * return <LoadingSpinner />;
826
- * }
958
+ * @param props - Component props
959
+ * @param props.plans - Plan slugs to match (e.g. ['pro', 'enterprise'])
960
+ * @param props.children - Content to render when on a matching plan
961
+ * @param props.loadingComponent - Optional component/element to show while loading
962
+ * @param props.fallbackComponent - Optional component/element to show when not on a matching plan
963
+ * @returns ReactNode - children when on a matching plan, loadingComponent when loading, fallbackComponent when not matching, or null
827
964
  *
828
- * return <MainContent />;
829
- * }
965
+ * @example
966
+ * ```tsx
967
+ * <WhenSubscriptionToPlans plans={['pro', 'enterprise']}>
968
+ * <AdvancedAnalytics />
969
+ * </WhenSubscriptionToPlans>
830
970
  * ```
831
971
  *
832
972
  * @example
833
973
  * ```tsx
834
- * // Open workspace settings
835
- * function SettingsButton() {
836
- * const { openWorkspaceSettings } = useSaaSAuth();
837
- *
838
- * return (
839
- * <button onClick={() => openWorkspaceSettings('general')}>
840
- * Open Settings
841
- * </button>
842
- * );
843
- * }
974
+ * <WhenSubscriptionToPlans
975
+ * plans={['pro', 'enterprise']}
976
+ * loadingComponent={<Skeleton />}
977
+ * fallbackComponent={<UpgradeToPro />}
978
+ * >
979
+ * <AdvancedAnalytics />
980
+ * </WhenSubscriptionToPlans>
844
981
  * ```
845
982
  */
983
+ declare const WhenSubscriptionToPlans: (props: IWhenSubscriptionToPlansProps) => react.ReactNode;
984
+
985
+ /**
986
+ * Value provided by SubscriptionContext and returned by useSubscriptionContext.
987
+ */
988
+ interface SubscriptionContextValue {
989
+ /** Current subscription response for the current workspace, or null if none or not loaded. */
990
+ response: ISubscriptionResponse | null;
991
+ /** True while subscription is being fetched. */
992
+ loading: boolean;
993
+ /** Refetch subscription for the current workspace. Call after plan change (e.g. upgrade) or when subscription was updated elsewhere. */
994
+ refetch: () => Promise<void>;
995
+ }
996
+
997
+ /**
998
+ * Provides subscription data for the current workspace to subscription gate components.
999
+ * Fetches when workspace changes; refetches when subscription is invalidated (e.g. after plan change).
1000
+ * Must wrap (or be ancestor of) any component that uses WhenSubscription, WhenNoSubscription,
1001
+ * WhenSubscriptionToPlans, or useSubscriptionContext. Included in SaaSOSProvider by default.
1002
+ *
1003
+ * @param props - Component props
1004
+ * @param props.children - React tree that may use subscription gates or useSubscriptionContext
1005
+ * @returns Provider element that supplies subscription context to descendants
1006
+ */
1007
+ declare const SubscriptionContextProvider: react__default.FC<{
1008
+ children: ReactNode;
1009
+ }>;
1010
+ /**
1011
+ * Returns subscription data for the current workspace. Must be used within SubscriptionContextProvider.
1012
+ *
1013
+ * @returns SubscriptionContextValue - { response, loading, refetch }
1014
+ * @throws Error if used outside SubscriptionContextProvider
1015
+ */
1016
+ declare function useSubscriptionContext(): SubscriptionContextValue;
1017
+
1018
+ type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'features' | 'danger';
1019
+
846
1020
  declare function useSaaSAuth(): {
847
1021
  signIn: () => Promise<void>;
848
1022
  signOut: () => Promise<void>;
@@ -855,6 +1029,11 @@ declare function useSaaSAuth(): {
855
1029
  status: AuthStatus;
856
1030
  };
857
1031
 
1032
+ /**
1033
+ * Hook to access OS (organization) state (serverUrl, version, orgId, auth, settings).
1034
+ * Prefer useSaaSSettings() when you only need settings.
1035
+ */
1036
+ declare function useSaaSOs(): IOsState;
858
1037
  /**
859
1038
  * Hook to access organization settings from the OS context.
860
1039
  * Automatically fetches settings when OS config is ready.
@@ -910,6 +1089,68 @@ interface UserContextValue {
910
1089
  refreshFeatures: () => Promise<void>;
911
1090
  }
912
1091
 
1092
+ /**
1093
+ * Base API client for SDK endpoints.
1094
+ * All domain API classes (WorkspaceApi, UserApi, etc.) extend this to share
1095
+ * URL building, auth headers, and request/response handling.
1096
+ */
1097
+
1098
+ interface IBaseApiConfig {
1099
+ serverUrl: string;
1100
+ version: ApiVersion;
1101
+ orgId?: string;
1102
+ /** When true, ensureReady() also requires orgId. Used by WorkspaceApi and SettingsApi. */
1103
+ requireOrgId?: boolean;
1104
+ /** API path segment after version (default 'public'). e.g. 'public' => .../v1/public, 'beta' => .../v1/beta */
1105
+ basePath?: string;
1106
+ }
1107
+ /**
1108
+ * Base class for SDK API clients.
1109
+ * Provides:
1110
+ * - baseUrl: `${serverUrl}/api/${version}/public`
1111
+ * - getAuthHeaders()
1112
+ * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
1113
+ * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
1114
+ */
1115
+ declare abstract class BaseApi {
1116
+ protected readonly serverUrl: string;
1117
+ protected readonly version: ApiVersion;
1118
+ protected readonly orgId: string | undefined;
1119
+ private readonly requireOrgId;
1120
+ private readonly basePath;
1121
+ constructor(config: IBaseApiConfig);
1122
+ /** Throws if config is not ready for API calls. Called automatically by fetchJson/fetchResponse. */
1123
+ protected ensureReady(): void;
1124
+ /** Base URL: ${serverUrl}/api/${version}/${basePath} */
1125
+ protected get baseUrl(): string;
1126
+ /** Auth headers (x-session-id). Subclasses can override to add more. */
1127
+ protected getAuthHeaders(): Record<string, string>;
1128
+ /** Build full URL from path (path can be "workspaces" or "/workspaces"). */
1129
+ protected url(path: string): string;
1130
+ /**
1131
+ * Execute request and parse JSON with handleApiResponse (throws on !response.ok).
1132
+ * Use for standard JSON APIs.
1133
+ */
1134
+ protected fetchJson<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
1135
+ /**
1136
+ * Execute request and return raw Response (for custom parsing or error handling).
1137
+ * Caller is responsible for checking response.ok and parsing body.
1138
+ */
1139
+ protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
1140
+ }
1141
+
1142
+ /**
1143
+ * Centralized API client for user attributes and features.
1144
+ * Extends BaseApi for shared URL/auth/request handling.
1145
+ */
1146
+ declare class UserApi extends BaseApi {
1147
+ constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'>);
1148
+ getAttributes(signal?: AbortSignal): Promise<Record<string, string | number | boolean>>;
1149
+ updateAttributes(updates: Record<string, string | number | boolean>): Promise<IUser>;
1150
+ updateAttribute(attributeKey: string, value: string | number | boolean): Promise<IUser>;
1151
+ getFeatures(signal?: AbortSignal): Promise<Record<string, boolean>>;
1152
+ }
1153
+
913
1154
  /**
914
1155
  * Hook to access user attributes from the UserProvider.
915
1156
  * Must be used within a UserProvider component.
@@ -990,111 +1231,131 @@ declare function useUserFeatures(): {
990
1231
  isFeatureEnabled: (featureId: string) => boolean;
991
1232
  };
992
1233
 
993
- /**
994
- * Main workspace management hook for the SDK.
995
- * Provides workspace state, CRUD operations, and user management.
996
- *
997
- * @returns An object containing:
998
- * - `workspaces`: Array of all workspaces the user has access to
999
- * - `currentWorkspace`: Currently selected workspace (null if none selected)
1000
- * - `loading`: Boolean indicating if workspaces are being fetched
1001
- * - `error`: Error message string (null if no error)
1002
- * - `refreshing`: Boolean indicating if workspaces are being refreshed in background
1003
- * - `switching`: Boolean - true when a workspace switch is in progress
1004
- * - `fetchWorkspaces()`: Function to fetch all workspaces
1005
- * - `refreshWorkspaces()`: Function to refresh workspaces in background (non-blocking)
1006
- * - `setCurrentWorkspace(workspace)`: Function to set the current workspace (direct, no callback)
1007
- * - `switchToWorkspace(workspace)`: Centralized switch - calls onWorkspaceChange first, then sets workspace
1008
- * - `resetCurrentWorkspace()`: Function to clear the current workspace
1009
- * - `createWorkspace(name, image?)`: Function to create a new workspace
1010
- * - `updateWorkspace(workspace, data)`: Function to update a workspace
1011
- * - `deleteWorkspace(workspaceId)`: Function to delete a workspace (owner only)
1012
- * - `getWorkspace(workspaceId)`: Function to fetch a specific workspace
1013
- * - `getUsers(workspaceId)`: Function to fetch users in a workspace
1014
- * - `addUser(workspaceId, email, role)`: Function to add a user to a workspace
1015
- * - `removeUser(workspaceId, userId)`: Function to remove a user from a workspace
1016
- * - `updateUser(workspaceId, userId, config)`: Function to update a user in a workspace
1017
- * - `getProfile()`: Function to fetch current user profile
1018
- * - `updateUserProfile(config)`: Function to update current user profile
1019
- * - `allFeatures`: Array of all available feature flags
1020
- * - `getFeatures()`: Function to fetch all available features
1021
- * - `updateFeature(workspaceId, key, value)`: Function to update a feature flag
1022
- *
1023
- * @example
1024
- * ```tsx
1025
- * function WorkspaceList() {
1026
- * const { workspaces, loading, fetchWorkspaces } = useSaaSWorkspaces();
1027
- *
1028
- * useEffect(() => {
1029
- * fetchWorkspaces();
1030
- * }, [fetchWorkspaces]);
1031
- *
1032
- * if (loading) return <Loading />;
1033
- *
1034
- * return (
1035
- * <ul>
1036
- * {workspaces.map(ws => (
1037
- * <li key={ws._id}>{ws.name}</li>
1038
- * ))}
1039
- * </ul>
1040
- * );
1041
- * }
1042
- * ```
1043
- *
1044
- * @example
1045
- * ```tsx
1046
- * // Create a new workspace
1047
- * function CreateWorkspace() {
1048
- * const { createWorkspace } = useSaaSWorkspaces();
1049
- *
1050
- * const handleCreate = async () => {
1051
- * try {
1052
- * await createWorkspace('My Workspace', 'https://example.com/logo.png');
1053
- * } catch (error) {
1054
- * console.error('Failed to create workspace:', error);
1055
- * }
1056
- * };
1057
- *
1058
- * return <button onClick={handleCreate}>Create Workspace</button>;
1059
- * }
1060
- * ```
1061
- *
1062
- * @example
1063
- * ```tsx
1064
- * // Delete workspace (owner only)
1065
- * function DeleteWorkspaceButton({ workspaceId }) {
1066
- * const { deleteWorkspace } = useSaaSWorkspaces();
1067
- *
1068
- * const handleDelete = async () => {
1069
- * if (!confirm('Are you sure?')) return;
1070
- * try {
1071
- * await deleteWorkspace(workspaceId);
1072
- * } catch (error) {
1073
- * // Error: "Only the workspace creator can delete the workspace"
1074
- * alert(error.message);
1075
- * }
1076
- * };
1077
- *
1078
- * return <button onClick={handleDelete}>Delete</button>;
1079
- * }
1080
- * ```
1081
- *
1082
- * @example
1083
- * ```tsx
1084
- * // Edge case: Workspace removed from user's access
1085
- * function WorkspaceContent() {
1086
- * const { currentWorkspace, workspaces } = useSaaSWorkspaces();
1087
- *
1088
- * // If current workspace is not in the list, it was removed
1089
- * // The hook automatically switches to first available workspace
1090
- * if (!currentWorkspace) {
1091
- * return <p>No workspace selected</p>;
1092
- * }
1093
- *
1094
- * return <div>{currentWorkspace.name}</div>;
1095
- * }
1096
- * ```
1097
- */
1234
+ declare class WorkspaceApi extends BaseApi {
1235
+ constructor(config: IOsConfig);
1236
+ getWorkspaces(): Promise<IWorkspace[]>;
1237
+ createWorkspace(data: {
1238
+ name: string;
1239
+ image?: string;
1240
+ }): Promise<IWorkspace>;
1241
+ updateWorkspace(id: string, data: Partial<IWorkspace>): Promise<IWorkspace>;
1242
+ deleteWorkspace(id: string): Promise<{
1243
+ success: boolean;
1244
+ }>;
1245
+ getWorkspaceUsers(workspaceId: string): Promise<IWorkspaceUser[]>;
1246
+ addUser(workspaceId: string, config: {
1247
+ email: string;
1248
+ role: string;
1249
+ }): Promise<{
1250
+ userId: string;
1251
+ workspace: IWorkspace;
1252
+ message: string;
1253
+ }>;
1254
+ removeUser(workspaceId: string, userId: string): Promise<{
1255
+ userId: string;
1256
+ workspace: IWorkspace;
1257
+ message: string;
1258
+ }>;
1259
+ updateUser(workspaceId: string, userId: string, data: Partial<IWorkspaceUser>): Promise<{
1260
+ userId: string;
1261
+ workspace: IWorkspace;
1262
+ message: string;
1263
+ }>;
1264
+ getFeatures(): Promise<IWorkspaceFeature[]>;
1265
+ updateFeature(workspaceId: string, key: string, value: boolean): Promise<IWorkspace>;
1266
+ getWorkspace(workspaceId: string): Promise<IWorkspace>;
1267
+ getProfile(): Promise<IUser>;
1268
+ updateUserProfile(config: Partial<IUser>): Promise<IUser>;
1269
+ /**
1270
+ * Get current subscription for a workspace
1271
+ * Returns subscription details including plan, plan version, and group information
1272
+ */
1273
+ getCurrentSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1274
+ /**
1275
+ * Get plan group for a workspace
1276
+ * Returns the plan group containing the current plan if subscription exists,
1277
+ * otherwise returns the latest published group
1278
+ */
1279
+ getPlanGroup(workspaceId: string): Promise<IPlanGroupResponse>;
1280
+ /**
1281
+ * Get plan group for a workspace with a specific version
1282
+ * @param workspaceId - The workspace ID
1283
+ * @param groupVersionId - The plan group version ID to fetch
1284
+ * @returns Plan group response with the specified version
1285
+ */
1286
+ getPlanGroupByVersion(workspaceId: string, groupVersionId: string): Promise<IPlanGroupResponse>;
1287
+ /**
1288
+ * Get current group version and available newer versions of the same group
1289
+ * - If user has active subscription: returns their current group version + newer versions
1290
+ * - If no subscription: returns the latest published group version
1291
+ * Shows what's new in newer versions to help users upgrade
1292
+ * Example: User on Group v1 (Basic Plan) can see Group v2 (Basic + Pro Plan)
1293
+ * @param workspaceId - The workspace ID
1294
+ * @returns Plan group versions response with currentVersion and availableVersions
1295
+ */
1296
+ getPlanGroupVersions(workspaceId: string): Promise<IPlanGroupVersionsResponse>;
1297
+ /**
1298
+ * Get plan group versions by slug (public, no auth required).
1299
+ * Returns the latest published plan group versions for the given plan group slug.
1300
+ * Use this for public pricing pages when you want to show a specific plan group.
1301
+ *
1302
+ * @param slug - Plan group slug (e.g. 'default', 'enterprise')
1303
+ * @returns Plan group versions response with currentVersion and availableVersions
1304
+ */
1305
+ getPublicPlans(slug: string): Promise<IPublicPlansResponse>;
1306
+ /**
1307
+ * Get plan group version details by ID (public, no auth required).
1308
+ * Returns the full plan group version with populated plan versions.
1309
+ * Use this for public pricing pages when you have the groupVersionId (e.g. from config or URL).
1310
+ *
1311
+ * @param groupVersionId - The plan group version ID to fetch
1312
+ * @returns Plan group version with populated plan versions
1313
+ */
1314
+ getPlanGroupVersion(groupVersionId: string): Promise<IPlanGroupVersion>;
1315
+ /**
1316
+ * Create checkout session for new subscription
1317
+ * @param workspaceId - The workspace ID
1318
+ * @param request - Checkout session request with planVersionId and optional billing interval/URLs
1319
+ * @returns Checkout session response with checkoutUrl to redirect user
1320
+ */
1321
+ createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest): Promise<ICheckoutSessionResponse>;
1322
+ /**
1323
+ * Update subscription (upgrade/downgrade)
1324
+ * Only allows plan changes within the same plan group
1325
+ * Returns checkout session if payment is required, otherwise returns subscription update response
1326
+ */
1327
+ updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1328
+ /**
1329
+ * List invoices for a workspace subscription
1330
+ * @param workspaceId - The workspace ID
1331
+ * @param limit - Number of invoices to return (default: 10)
1332
+ * @param startingAfter - Invoice ID to start after (for pagination)
1333
+ * @returns List of invoices with pagination info
1334
+ */
1335
+ listInvoices(workspaceId: string, limit?: number, startingAfter?: string): Promise<IInvoiceListResponse>;
1336
+ /**
1337
+ * Get a single invoice by ID
1338
+ * @param workspaceId - The workspace ID
1339
+ * @param invoiceId - The invoice ID
1340
+ * @returns Invoice details
1341
+ */
1342
+ getInvoice(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
1343
+ /**
1344
+ * Cancel subscription at the end of the current billing period
1345
+ * Sets cancelAtPeriodEnd: true - subscription remains active until period ends
1346
+ * @param workspaceId - The workspace ID
1347
+ * @returns Updated subscription with cancelAtPeriodEnd and stripeCurrentPeriodEnd
1348
+ */
1349
+ cancelSubscriptionAtPeriodEnd(workspaceId: string): Promise<ISubscriptionResponse>;
1350
+ /**
1351
+ * Resume a subscription that was scheduled for cancellation
1352
+ * Sets cancelAtPeriodEnd: false - subscription will continue after period ends
1353
+ * @param workspaceId - The workspace ID
1354
+ * @returns Updated subscription with cancelAtPeriodEnd set to false
1355
+ */
1356
+ resumeSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1357
+ }
1358
+
1098
1359
  declare const useSaaSWorkspaces: () => {
1099
1360
  workspaces: IWorkspace[];
1100
1361
  loading: boolean;
@@ -1110,7 +1371,7 @@ declare const useSaaSWorkspaces: () => {
1110
1371
  forceEmit?: boolean;
1111
1372
  }) => Promise<void>;
1112
1373
  resetCurrentWorkspace: () => void;
1113
- createWorkspace: (name: string, image: string) => Promise<void>;
1374
+ createWorkspace: (name: string, image?: string) => Promise<void>;
1114
1375
  allFeatures: IWorkspaceFeature[];
1115
1376
  getFeatures: () => Promise<IWorkspaceFeature[] | null>;
1116
1377
  updateFeature: (workspaceId: string, key: string, value: boolean) => Promise<IWorkspace>;
@@ -1138,6 +1399,7 @@ declare const useSaaSWorkspaces: () => {
1138
1399
  success: boolean;
1139
1400
  }>;
1140
1401
  switching: boolean;
1402
+ switchingToId: string | null;
1141
1403
  };
1142
1404
 
1143
1405
  declare function WorkspaceSwitcher(props: {
@@ -1155,6 +1417,7 @@ declare function WorkspaceSwitcher(props: {
1155
1417
  declare const usePublicPlans: (slug: string) => {
1156
1418
  items: IPublicPlanItem[];
1157
1419
  plans: IPublicPlanVersion[];
1420
+ notes: string | undefined;
1158
1421
  loading: boolean;
1159
1422
  error: string | null;
1160
1423
  refetch: () => Promise<void>;
@@ -1265,7 +1528,7 @@ declare const useSubscription: (workspaceId: string | null | undefined) => {
1265
1528
  *
1266
1529
  * return (
1267
1530
  * <div>
1268
- * <h3>{planGroup.name}</h3>
1531
+ * <h3>{planGroup.group.name}</h3>
1269
1532
  * {planGroup.plans.map(plan => (
1270
1533
  * <PlanCard key={plan._id} plan={plan} />
1271
1534
  * ))}
@@ -1705,5 +1968,138 @@ declare class EventEmitter {
1705
1968
  }
1706
1969
  declare const eventEmitter: EventEmitter;
1707
1970
 
1708
- export { ApiVersion, AuthStatus, BetaForm, PricingPage, SaaSOSProvider, WhenAuthenticated, WhenRoles, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceSwitcher, eventEmitter, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, useSaaSAuth, useSaaSSettings, useSaaSWorkspaces, useSubscription, useSubscriptionManagement, useUpdateSubscription, useUserAttributes, useUserFeatures };
1709
- export type { BillingInterval, EventData, EventType, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IEventCallbacks, IInvoice, IInvoiceListResponse, IInvoiceResponse, IPlan, IPlanGroup, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionWithPlan, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanPricing, IPublicPlanQuotaValue, IPublicPlanVersion, IPublicPlansResponse, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, InvoiceStatus, OnWorkspaceChangeParams, PricingPageDetails, PricingPageProps, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
1971
+ /**
1972
+ * Centralized API client for organization (OS) settings.
1973
+ * Extends BaseApi for shared URL/auth/request handling.
1974
+ */
1975
+
1976
+ declare class SettingsApi extends BaseApi {
1977
+ constructor(config: IOsConfig);
1978
+ getSettings(signal?: AbortSignal): Promise<ISettings>;
1979
+ }
1980
+
1981
+ /**
1982
+ * Centralized formatting for subscription/quota display: cents, overage rates, included + overage text.
1983
+ * Currency must be provided by the caller (e.g. workspace.billingCurrency, plan.currency, or selected currency).
1984
+ */
1985
+ /** Common currency display (code or symbol). Use lowercase Stripe codes (usd, eur, etc.). */
1986
+ declare const CURRENCY_DISPLAY: Record<string, string>;
1987
+ /** Currency code to flag emoji (country/region associated with the currency). Use for dropdowns. */
1988
+ declare const CURRENCY_FLAG: Record<string, string>;
1989
+ /** Get flag emoji for a currency code. Returns empty string when unknown or empty. */
1990
+ declare function getCurrencyFlag(currency: string): string;
1991
+ /** Get currency symbol for display. Use lowercase Stripe codes (usd, eur). Returns code when unknown; empty string when currency is empty. */
1992
+ declare function getCurrencySymbol(currency: string): string;
1993
+ /** Allowed plan/pricing currency codes (must match server ALLOWED_BILLING_CURRENCIES). Use for dropdowns and validation. */
1994
+ declare const PLAN_CURRENCY_CODES: readonly ["usd", "eur", "gbp", "jpy", "cad", "aud", "chf", "cny", "hkd", "sgd", "inr", "mxn", "brl", "nzd", "sek", "nok", "dkk", "pln", "thb"];
1995
+ /** Options for plan currency select: { value, label } with symbol. Use in CreateOrEditPlan and anywhere a currency dropdown is needed. */
1996
+ declare const PLAN_CURRENCY_OPTIONS: {
1997
+ value: "usd" | "eur" | "gbp" | "jpy" | "cad" | "aud" | "chf" | "cny" | "hkd" | "sgd" | "inr" | "mxn" | "brl" | "nzd" | "sek" | "nok" | "dkk" | "pln" | "thb";
1998
+ label: string;
1999
+ }[];
2000
+ /** Format cents as money string (e.g. 1999, "usd" -> "$19.99"). Caller must pass currency (e.g. from plan or workspace). */
2001
+ declare function formatCents(cents: number, currency: string): string;
2002
+ /**
2003
+ * Format overage rate for display. When unitSize > 1: "$1.00/1,000 units"; else "$1.00/unit".
2004
+ * Returns null if overageCents is missing or negative.
2005
+ */
2006
+ declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string): string | null;
2007
+ /**
2008
+ * Format overage rate with optional unit label for comparison/preview UIs.
2009
+ * e.g. formatOverageRateWithLabel(50, 1000, "video") -> "$0.50/1,000 videos"
2010
+ * formatOverageRateWithLabel(46, 1, "video") -> "$0.46/video"
2011
+ * When unitLabel is omitted, falls back to formatOverageRate behavior.
2012
+ */
2013
+ declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string): string | null;
2014
+ /**
2015
+ * Get singular unit label from item name or slug (e.g. "Videos" -> "video", "reels" -> "reel").
2016
+ * Used for quota display in comparison and preview.
2017
+ */
2018
+ declare function getQuotaUnitLabelFromName(nameOrSlug: string): string;
2019
+ /**
2020
+ * Format quota "included + overage" for display.
2021
+ * When unitSize >= 2: "Included: 1,000, after that $1.00/1,000 emails".
2022
+ * Otherwise: "Included: 5, after that $0.30/image".
2023
+ */
2024
+ declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number): string;
2025
+
2026
+ /**
2027
+ * Helpers for multi-currency plan version pricing (pricingVariants).
2028
+ */
2029
+
2030
+ /** Get the pricing variant for a currency, or null if not available. */
2031
+ declare function getPricingVariant(planVersion: IPlanVersion, currency: string): IPricingVariant | null;
2032
+ /**
2033
+ * Get base price in cents for a plan version and currency/interval.
2034
+ */
2035
+ declare function getBasePriceCents(planVersion: IPlanVersion, currency: string, interval: BillingInterval): number | null;
2036
+ /**
2037
+ * Get Stripe price ID for the given plan version, currency, and interval.
2038
+ */
2039
+ declare function getStripePriceIdForInterval(planVersion: IPlanVersion, currency: string, interval: BillingInterval): string | null;
2040
+ /**
2041
+ * Get overage amount in cents for a quota in a given currency and interval.
2042
+ * Returns undefined if not defined in the pricing variant.
2043
+ */
2044
+ declare function getQuotaOverageCents(planVersion: IPlanVersion, currency: string, quotaSlug: string, interval: BillingInterval): number | undefined;
2045
+ /**
2046
+ * Get display currency for a plan version when using a given currency.
2047
+ * Returns the requested currency if the variant exists; otherwise plan.currency or null.
2048
+ */
2049
+ declare function getDisplayCurrency(planVersion: IPlanVersionWithPlan, currency: string): string;
2050
+ /** Minimal shape for extracting currencies (IPlanVersionWithPlan or IPublicPlanVersion). */
2051
+ type PlanVersionWithPricingVariants = {
2052
+ pricingVariants?: IPricingVariant[];
2053
+ };
2054
+ /**
2055
+ * Collect all unique currency codes from plan versions (from their pricingVariants).
2056
+ * Use for currency selector. Accepts IPlanVersionWithPlan[] or IPublicPlanVersion[].
2057
+ */
2058
+ declare function getAvailableCurrenciesFromPlans(planVersions: PlanVersionWithPricingVariants[]): string[];
2059
+ /**
2060
+ * Quota display shape: included count and optional overage (cents) and unitSize from plan + variant.
2061
+ */
2062
+ type QuotaDisplayWithOverage = {
2063
+ included: number;
2064
+ overage?: number;
2065
+ unitSize?: number;
2066
+ } | null;
2067
+ /**
2068
+ * Get quota display value for a slug/interval, merging plan version quotas (included, unitSize)
2069
+ * with pricing variant overage (cents) when available.
2070
+ */
2071
+ declare function getQuotaDisplayWithVariant(planVersion: IPlanVersion, currency: string, quotaSlug: string, interval: BillingInterval): QuotaDisplayWithOverage;
2072
+ /**
2073
+ * Resolve billing interval and currency from a Stripe price ID by checking all plan versions' pricingVariants.
2074
+ */
2075
+ declare function getBillingIntervalAndCurrencyFromPriceId(priceId: string | null | undefined, planVersions: IPlanVersionWithPlan[]): {
2076
+ interval: BillingInterval;
2077
+ currency: string;
2078
+ } | null;
2079
+
2080
+ type QuotaDisplayValue = {
2081
+ included: number;
2082
+ overage?: number;
2083
+ unitSize?: number;
2084
+ } | null;
2085
+ /**
2086
+ * Normalize a per-interval quota value to a display shape for the given billing interval.
2087
+ */
2088
+ declare function getQuotaDisplayValue(value: IQuotaByInterval | null | undefined, interval?: BillingInterval): QuotaDisplayValue;
2089
+ /** Options for formatting quota with price. */
2090
+ interface FormatQuotaWithPriceOptions {
2091
+ /** If true, overage is in cents (Stripe); format as dollars. Default true. */
2092
+ overageInCents?: boolean;
2093
+ /** Currency symbol override. When omitted, derived from `currency` (empty if no currency). */
2094
+ currencySymbol?: string;
2095
+ /** Stripe currency code (e.g. 'usd', 'inr'). Used to resolve symbol when currencySymbol is not set. */
2096
+ currency?: string;
2097
+ }
2098
+ /**
2099
+ * Format a quota display value as "X included, then $Y.YY / unit" (e.g. "10 included, then $10.00 / video").
2100
+ * Assumes overage is the per-unit price (in cents when overageInCents is true).
2101
+ */
2102
+ declare function formatQuotaWithPrice(value: QuotaDisplayValue, unitName: string, options?: FormatQuotaWithPriceOptions): string;
2103
+
2104
+ export { ApiVersion, AuthStatus, BaseApi, BetaForm, CURRENCY_DISPLAY, CURRENCY_FLAG, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PricingPage, SaaSOSProvider, SettingsApi, SubscriptionContextProvider, UserApi, WhenAuthenticated, WhenNoSubscription, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getStripePriceIdForInterval, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSubscription, useSubscriptionContext, useSubscriptionManagement, useUpdateSubscription, useUserAttributes, useUserFeatures };
2105
+ export type { BillingInterval, EventData, EventType, FormatQuotaWithPriceOptions, IBaseApiConfig, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IEventCallbacks, IInvoice, IInvoiceListResponse, IInvoiceResponse, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, InvoiceStatus, OnWorkspaceChangeParams, PlanVersionWithPricingVariants, PricingPageDetails, PricingPageProps, QuotaDisplayValue, QuotaDisplayWithOverage, SubscriptionContextValue, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };