@buildbase/sdk 0.0.16 → 0.0.18

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 (35) hide show
  1. package/README.md +208 -98
  2. package/dist/index.d.ts +392 -167
  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/types/api/index.d.ts +6 -0
  8. package/dist/types/api/quota-utils.d.ts +24 -0
  9. package/dist/types/api/types.d.ts +37 -14
  10. package/dist/types/components/beta/api.d.ts +1 -2
  11. package/dist/types/components/pricing/PricingPage.d.ts +1 -1
  12. package/dist/types/components/subscription/index.d.ts +108 -0
  13. package/dist/types/contexts/SubscriptionContext/SubscriptionContext.d.ts +22 -0
  14. package/dist/types/contexts/SubscriptionContext/index.d.ts +2 -0
  15. package/dist/types/contexts/SubscriptionContext/subscriptionInvalidation.d.ts +19 -0
  16. package/dist/types/contexts/SubscriptionContext/types.d.ts +12 -0
  17. package/dist/types/contexts/index.d.ts +2 -0
  18. package/dist/types/contexts/shared/types.d.ts +21 -0
  19. package/dist/types/contexts/shared/useAppDispatch.d.ts +2 -12
  20. package/dist/types/contexts/shared/useAppSelector.d.ts +2 -12
  21. package/dist/types/contexts/shared/utils/reducerHelpers.d.ts +2 -2
  22. package/dist/types/index.d.ts +9 -2
  23. package/dist/types/lib/api-base.d.ts +49 -0
  24. package/dist/types/providers/ContextConfigProvider.d.ts +1 -1
  25. package/dist/types/providers/auth/api.d.ts +12 -0
  26. package/dist/types/providers/auth/hooks.d.ts +2 -0
  27. package/dist/types/providers/os/api.d.ts +11 -0
  28. package/dist/types/providers/os/hooks.d.ts +6 -0
  29. package/dist/types/providers/os/types.d.ts +2 -0
  30. package/dist/types/providers/user/api.d.ts +16 -0
  31. package/dist/types/providers/user/hooks.d.ts +1 -0
  32. package/dist/types/providers/workspace/api.d.ts +2 -5
  33. package/dist/types/providers/workspace/hooks.d.ts +10 -0
  34. package/dist/types/providers/workspace/subscription-hooks.d.ts +1 -1
  35. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ interface ISubscription {
28
28
  stripePriceId?: string;
29
29
  stripeCurrentPeriodEnd?: string;
30
30
  cancelAtPeriodEnd: boolean;
31
+ billingInterval?: BillingInterval;
31
32
  createdAt: string;
32
33
  updatedAt: string;
33
34
  plan?: {
@@ -50,6 +51,20 @@ interface IQuotaValue {
50
51
  overage?: number;
51
52
  stripePriceId?: string;
52
53
  }
54
+ /** Per-interval quota value (new plan-group/versions schema) */
55
+ interface IQuotaIntervalValue {
56
+ included: number;
57
+ overage: number;
58
+ priceId: string;
59
+ /** Optional unit size for overage pricing (e.g. 1000 = price per 1000 units). */
60
+ unitSize?: number;
61
+ }
62
+ /** Quota defined per billing interval (new plan-group/versions schema) */
63
+ interface IQuotaByInterval {
64
+ monthly?: IQuotaIntervalValue;
65
+ yearly?: IQuotaIntervalValue;
66
+ quarterly?: IQuotaIntervalValue;
67
+ }
53
68
  interface IBasePricing {
54
69
  monthly: number;
55
70
  yearly: number;
@@ -62,7 +77,8 @@ interface IPlanVersion {
62
77
  status: 'draft' | 'published';
63
78
  features?: Record<string, boolean>;
64
79
  limits?: Record<string, number>;
65
- quotas?: Record<string, number | IQuotaValue>;
80
+ /** Legacy: number | IQuotaValue. New schema: IQuotaByInterval (per-interval included/overage/priceId) */
81
+ quotas?: Record<string, number | IQuotaValue | IQuotaByInterval>;
66
82
  basePricing?: IBasePricing;
67
83
  stripePrices?: {
68
84
  monthlyPriceId?: string;
@@ -79,13 +95,18 @@ interface IPlanVersion {
79
95
  createdAt?: string;
80
96
  updatedAt?: string;
81
97
  id?: string;
98
+ stripeProductId?: string;
99
+ }
100
+ /** Plan version summary (e.g. plan.latestVersion from subscription API) with subscriptionItems as IDs. */
101
+ interface IPlanVersionSummary extends Omit<IPlanVersion, 'subscriptionItems'> {
102
+ subscriptionItems?: string[];
82
103
  }
83
104
  interface IPlan {
84
105
  _id: string;
85
106
  name: string;
86
107
  slug: string;
87
108
  description?: string;
88
- latestVersion?: IPlanVersion;
109
+ latestVersion?: IPlanVersionSummary;
89
110
  archived?: boolean;
90
111
  deleted?: boolean;
91
112
  createdAt?: string;
@@ -160,21 +181,23 @@ interface IPlanGroupVersionWithPlans {
160
181
  removedPlans: IPlanVersionWithPlan[];
161
182
  };
162
183
  }
184
+ interface IPlanGroupInfo {
185
+ _id: string;
186
+ name: string;
187
+ slug: string;
188
+ description?: string;
189
+ }
190
+ /** Response from GET workspaces/:id/subscription/plan-group (and by version). */
163
191
  interface IPlanGroupResponse {
164
- group: {
165
- _id: string;
166
- name: string;
167
- slug: string;
168
- };
169
- currentVersion: IPlanGroupVersionWithPlans;
170
- availableVersions: IPlanGroupVersionWithPlans[];
192
+ /** Plan group with latestVersion, archived, deleted, timestamps. */
193
+ group: IPlanGroup;
194
+ /** Current group version with populated planVersionIds (or IDs). */
195
+ groupVersion: IPlanGroupVersion;
196
+ /** Full plan versions for display (subscriptionItems, basePricing, quotas, etc.). */
197
+ plans: IPlanVersionWithPlan[];
171
198
  }
172
199
  interface IPlanGroupVersionsResponse {
173
- group: {
174
- _id: string;
175
- name: string;
176
- slug: string;
177
- };
200
+ group: IPlanGroupInfo;
178
201
  currentVersion: IPlanGroupVersionWithPlans;
179
202
  availableVersions: IPlanGroupVersionWithPlans[];
180
203
  }
@@ -512,7 +535,7 @@ interface PricingPageProps {
512
535
  * </PricingPage>
513
536
  * ```
514
537
  */
515
- declare function PricingPage({ slug, children, loadingFallback, errorFallback, }: PricingPageProps): react_jsx_runtime.JSX.Element;
538
+ declare function PricingPage({ slug, children, loadingFallback, errorFallback }: PricingPageProps): react_jsx_runtime.JSX.Element;
516
539
 
517
540
  interface IProps$2 {
518
541
  children: React.ReactNode;
@@ -780,69 +803,149 @@ declare const WhenUserFeatureEnabled: (props: IProps) => react.ReactNode;
780
803
  */
781
804
  declare const WhenUserFeatureDisabled: (props: IProps) => react.ReactNode;
782
805
 
783
- type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'features' | 'danger';
784
-
806
+ interface IWhenSubscriptionProps {
807
+ /** Content to render when the condition is met (workspace has an active subscription). */
808
+ children: React.ReactNode;
809
+ /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
810
+ loadingComponent?: React.ReactNode;
811
+ /** Optional component/element to show when condition is not met (e.g. <UpgradePrompt />). */
812
+ fallbackComponent?: React.ReactNode;
813
+ }
785
814
  /**
786
- * Main authentication hook for the SDK.
787
- * Provides authentication state, user session, and auth actions.
815
+ * Renders children only when the current workspace has an active subscription (any plan).
816
+ * Optionally pass loadingComponent (while loading) or fallbackComponent (when not subscribed).
817
+ * Must be used within SubscriptionContextProvider.
788
818
  *
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
819
+ * @param props - Component props
820
+ * @param props.children - Content to render when subscribed
821
+ * @param props.loadingComponent - Optional component/element to show while loading
822
+ * @param props.fallbackComponent - Optional component/element to show when not subscribed
823
+ * @returns ReactNode - children when subscribed, loadingComponent when loading, fallbackComponent when not subscribed, or null
799
824
  *
800
825
  * @example
801
826
  * ```tsx
802
- * function MyComponent() {
803
- * const { user, isAuthenticated, signIn, signOut } = useSaaSAuth();
827
+ * <WhenSubscription>
828
+ * <BillingSettings />
829
+ * </WhenSubscription>
830
+ * ```
804
831
  *
805
- * if (!isAuthenticated) {
806
- * return <button onClick={signIn}>Sign In</button>;
807
- * }
832
+ * @example
833
+ * ```tsx
834
+ * <WhenSubscription
835
+ * loadingComponent={<Skeleton />}
836
+ * fallbackComponent={<UpgradePrompt />}
837
+ * >
838
+ * <BillingSettings />
839
+ * </WhenSubscription>
840
+ * ```
841
+ */
842
+ declare const WhenSubscription: (props: IWhenSubscriptionProps) => react.ReactNode;
843
+ /**
844
+ * Renders children only when the current workspace has no subscription (or no current workspace).
845
+ * Optionally pass loadingComponent (while loading) or fallbackComponent (when already subscribed).
846
+ * Must be used within SubscriptionContextProvider.
808
847
  *
809
- * return (
810
- * <div>
811
- * <p>Welcome, {user?.name}</p>
812
- * <button onClick={signOut}>Sign Out</button>
813
- * </div>
814
- * );
815
- * }
848
+ * @param props - Component props
849
+ * @param props.children - Content to render when not subscribed
850
+ * @param props.loadingComponent - Optional component/element to show while loading
851
+ * @param props.fallbackComponent - Optional component/element to show when already subscribed
852
+ * @returns ReactNode - children when not subscribed, loadingComponent when loading, fallbackComponent when subscribed, or null
853
+ *
854
+ * @example
855
+ * ```tsx
856
+ * <WhenNoSubscription>
857
+ * <UpgradePrompt />
858
+ * </WhenNoSubscription>
816
859
  * ```
817
860
  *
818
861
  * @example
819
862
  * ```tsx
820
- * // Handle loading state
821
- * function App() {
822
- * const { status, isLoading } = useSaaSAuth();
863
+ * <WhenNoSubscription
864
+ * loadingComponent={<Spinner />}
865
+ * fallbackComponent={null}
866
+ * >
867
+ * <UpgradePrompt />
868
+ * </WhenNoSubscription>
869
+ * ```
870
+ */
871
+ declare const WhenNoSubscription: (props: IWhenSubscriptionProps) => react.ReactNode;
872
+ interface IWhenSubscriptionToPlansProps {
873
+ /** Plan slugs to match (e.g. ['pro', 'enterprise']). Matching is case-insensitive. */
874
+ plans: string[];
875
+ /** Content to render when the workspace is on one of the given plans. */
876
+ children: React.ReactNode;
877
+ /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
878
+ loadingComponent?: React.ReactNode;
879
+ /** Optional component/element to show when not on a matching plan (e.g. <UpgradeToPro />). */
880
+ fallbackComponent?: React.ReactNode;
881
+ }
882
+ /**
883
+ * Renders children only when the current workspace is subscribed to one of the given plans.
884
+ * Matches by plan slug only. Optionally pass loadingComponent (while loading) or fallbackComponent (when not on a matching plan).
885
+ * Must be used within SubscriptionContextProvider.
823
886
  *
824
- * if (isLoading) {
825
- * return <LoadingSpinner />;
826
- * }
887
+ * @param props - Component props
888
+ * @param props.plans - Plan slugs to match (e.g. ['pro', 'enterprise'])
889
+ * @param props.children - Content to render when on a matching plan
890
+ * @param props.loadingComponent - Optional component/element to show while loading
891
+ * @param props.fallbackComponent - Optional component/element to show when not on a matching plan
892
+ * @returns ReactNode - children when on a matching plan, loadingComponent when loading, fallbackComponent when not matching, or null
827
893
  *
828
- * return <MainContent />;
829
- * }
894
+ * @example
895
+ * ```tsx
896
+ * <WhenSubscriptionToPlans plans={['pro', 'enterprise']}>
897
+ * <AdvancedAnalytics />
898
+ * </WhenSubscriptionToPlans>
830
899
  * ```
831
900
  *
832
901
  * @example
833
902
  * ```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
- * }
903
+ * <WhenSubscriptionToPlans
904
+ * plans={['pro', 'enterprise']}
905
+ * loadingComponent={<Skeleton />}
906
+ * fallbackComponent={<UpgradeToPro />}
907
+ * >
908
+ * <AdvancedAnalytics />
909
+ * </WhenSubscriptionToPlans>
844
910
  * ```
845
911
  */
912
+ declare const WhenSubscriptionToPlans: (props: IWhenSubscriptionToPlansProps) => react.ReactNode;
913
+
914
+ /**
915
+ * Value provided by SubscriptionContext and returned by useSubscriptionContext.
916
+ */
917
+ interface SubscriptionContextValue {
918
+ /** Current subscription response for the current workspace, or null if none or not loaded. */
919
+ response: ISubscriptionResponse | null;
920
+ /** True while subscription is being fetched. */
921
+ loading: boolean;
922
+ /** Refetch subscription for the current workspace. Call after plan change (e.g. upgrade) or when subscription was updated elsewhere. */
923
+ refetch: () => Promise<void>;
924
+ }
925
+
926
+ /**
927
+ * Provides subscription data for the current workspace to subscription gate components.
928
+ * Fetches when workspace changes; refetches when subscription is invalidated (e.g. after plan change).
929
+ * Must wrap (or be ancestor of) any component that uses WhenSubscription, WhenNoSubscription,
930
+ * WhenSubscriptionToPlans, or useSubscriptionContext. Included in SaaSOSProvider by default.
931
+ *
932
+ * @param props - Component props
933
+ * @param props.children - React tree that may use subscription gates or useSubscriptionContext
934
+ * @returns Provider element that supplies subscription context to descendants
935
+ */
936
+ declare const SubscriptionContextProvider: react__default.FC<{
937
+ children: ReactNode;
938
+ }>;
939
+ /**
940
+ * Returns subscription data for the current workspace. Must be used within SubscriptionContextProvider.
941
+ *
942
+ * @returns SubscriptionContextValue - { response, loading, refetch }
943
+ * @throws Error if used outside SubscriptionContextProvider
944
+ */
945
+ declare function useSubscriptionContext(): SubscriptionContextValue;
946
+
947
+ type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'features' | 'danger';
948
+
846
949
  declare function useSaaSAuth(): {
847
950
  signIn: () => Promise<void>;
848
951
  signOut: () => Promise<void>;
@@ -855,6 +958,11 @@ declare function useSaaSAuth(): {
855
958
  status: AuthStatus;
856
959
  };
857
960
 
961
+ /**
962
+ * Hook to access OS (organization) state (serverUrl, version, orgId, auth, settings).
963
+ * Prefer useSaaSSettings() when you only need settings.
964
+ */
965
+ declare function useSaaSOs(): IOsState;
858
966
  /**
859
967
  * Hook to access organization settings from the OS context.
860
968
  * Automatically fetches settings when OS config is ready.
@@ -910,6 +1018,68 @@ interface UserContextValue {
910
1018
  refreshFeatures: () => Promise<void>;
911
1019
  }
912
1020
 
1021
+ /**
1022
+ * Base API client for SDK endpoints.
1023
+ * All domain API classes (WorkspaceApi, UserApi, etc.) extend this to share
1024
+ * URL building, auth headers, and request/response handling.
1025
+ */
1026
+
1027
+ interface IBaseApiConfig {
1028
+ serverUrl: string;
1029
+ version: ApiVersion;
1030
+ orgId?: string;
1031
+ /** When true, ensureReady() also requires orgId. Used by WorkspaceApi and SettingsApi. */
1032
+ requireOrgId?: boolean;
1033
+ /** API path segment after version (default 'public'). e.g. 'public' => .../v1/public, 'beta' => .../v1/beta */
1034
+ basePath?: string;
1035
+ }
1036
+ /**
1037
+ * Base class for SDK API clients.
1038
+ * Provides:
1039
+ * - baseUrl: `${serverUrl}/api/${version}/public`
1040
+ * - getAuthHeaders()
1041
+ * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
1042
+ * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
1043
+ */
1044
+ declare abstract class BaseApi {
1045
+ protected readonly serverUrl: string;
1046
+ protected readonly version: ApiVersion;
1047
+ protected readonly orgId: string | undefined;
1048
+ private readonly requireOrgId;
1049
+ private readonly basePath;
1050
+ constructor(config: IBaseApiConfig);
1051
+ /** Throws if config is not ready for API calls. Called automatically by fetchJson/fetchResponse. */
1052
+ protected ensureReady(): void;
1053
+ /** Base URL: ${serverUrl}/api/${version}/${basePath} */
1054
+ protected get baseUrl(): string;
1055
+ /** Auth headers (x-session-id). Subclasses can override to add more. */
1056
+ protected getAuthHeaders(): Record<string, string>;
1057
+ /** Build full URL from path (path can be "workspaces" or "/workspaces"). */
1058
+ protected url(path: string): string;
1059
+ /**
1060
+ * Execute request and parse JSON with handleApiResponse (throws on !response.ok).
1061
+ * Use for standard JSON APIs.
1062
+ */
1063
+ protected fetchJson<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
1064
+ /**
1065
+ * Execute request and return raw Response (for custom parsing or error handling).
1066
+ * Caller is responsible for checking response.ok and parsing body.
1067
+ */
1068
+ protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
1069
+ }
1070
+
1071
+ /**
1072
+ * Centralized API client for user attributes and features.
1073
+ * Extends BaseApi for shared URL/auth/request handling.
1074
+ */
1075
+ declare class UserApi extends BaseApi {
1076
+ constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'>);
1077
+ getAttributes(signal?: AbortSignal): Promise<Record<string, string | number | boolean>>;
1078
+ updateAttributes(updates: Record<string, string | number | boolean>): Promise<IUser>;
1079
+ updateAttribute(attributeKey: string, value: string | number | boolean): Promise<IUser>;
1080
+ getFeatures(signal?: AbortSignal): Promise<Record<string, boolean>>;
1081
+ }
1082
+
913
1083
  /**
914
1084
  * Hook to access user attributes from the UserProvider.
915
1085
  * Must be used within a UserProvider component.
@@ -990,111 +1160,131 @@ declare function useUserFeatures(): {
990
1160
  isFeatureEnabled: (featureId: string) => boolean;
991
1161
  };
992
1162
 
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
- */
1163
+ declare class WorkspaceApi extends BaseApi {
1164
+ constructor(config: IOsConfig);
1165
+ getWorkspaces(): Promise<IWorkspace[]>;
1166
+ createWorkspace(data: {
1167
+ name: string;
1168
+ image?: string;
1169
+ }): Promise<IWorkspace>;
1170
+ updateWorkspace(id: string, data: Partial<IWorkspace>): Promise<IWorkspace>;
1171
+ deleteWorkspace(id: string): Promise<{
1172
+ success: boolean;
1173
+ }>;
1174
+ getWorkspaceUsers(workspaceId: string): Promise<IWorkspaceUser[]>;
1175
+ addUser(workspaceId: string, config: {
1176
+ email: string;
1177
+ role: string;
1178
+ }): Promise<{
1179
+ userId: string;
1180
+ workspace: IWorkspace;
1181
+ message: string;
1182
+ }>;
1183
+ removeUser(workspaceId: string, userId: string): Promise<{
1184
+ userId: string;
1185
+ workspace: IWorkspace;
1186
+ message: string;
1187
+ }>;
1188
+ updateUser(workspaceId: string, userId: string, data: Partial<IWorkspaceUser>): Promise<{
1189
+ userId: string;
1190
+ workspace: IWorkspace;
1191
+ message: string;
1192
+ }>;
1193
+ getFeatures(): Promise<IWorkspaceFeature[]>;
1194
+ updateFeature(workspaceId: string, key: string, value: boolean): Promise<IWorkspace>;
1195
+ getWorkspace(workspaceId: string): Promise<IWorkspace>;
1196
+ getProfile(): Promise<IUser>;
1197
+ updateUserProfile(config: Partial<IUser>): Promise<IUser>;
1198
+ /**
1199
+ * Get current subscription for a workspace
1200
+ * Returns subscription details including plan, plan version, and group information
1201
+ */
1202
+ getCurrentSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1203
+ /**
1204
+ * Get plan group for a workspace
1205
+ * Returns the plan group containing the current plan if subscription exists,
1206
+ * otherwise returns the latest published group
1207
+ */
1208
+ getPlanGroup(workspaceId: string): Promise<IPlanGroupResponse>;
1209
+ /**
1210
+ * Get plan group for a workspace with a specific version
1211
+ * @param workspaceId - The workspace ID
1212
+ * @param groupVersionId - The plan group version ID to fetch
1213
+ * @returns Plan group response with the specified version
1214
+ */
1215
+ getPlanGroupByVersion(workspaceId: string, groupVersionId: string): Promise<IPlanGroupResponse>;
1216
+ /**
1217
+ * Get current group version and available newer versions of the same group
1218
+ * - If user has active subscription: returns their current group version + newer versions
1219
+ * - If no subscription: returns the latest published group version
1220
+ * Shows what's new in newer versions to help users upgrade
1221
+ * Example: User on Group v1 (Basic Plan) can see Group v2 (Basic + Pro Plan)
1222
+ * @param workspaceId - The workspace ID
1223
+ * @returns Plan group versions response with currentVersion and availableVersions
1224
+ */
1225
+ getPlanGroupVersions(workspaceId: string): Promise<IPlanGroupVersionsResponse>;
1226
+ /**
1227
+ * Get plan group versions by slug (public, no auth required).
1228
+ * Returns the latest published plan group versions for the given plan group slug.
1229
+ * Use this for public pricing pages when you want to show a specific plan group.
1230
+ *
1231
+ * @param slug - Plan group slug (e.g. 'default', 'enterprise')
1232
+ * @returns Plan group versions response with currentVersion and availableVersions
1233
+ */
1234
+ getPublicPlans(slug: string): Promise<IPublicPlansResponse>;
1235
+ /**
1236
+ * Get plan group version details by ID (public, no auth required).
1237
+ * Returns the full plan group version with populated plan versions.
1238
+ * Use this for public pricing pages when you have the groupVersionId (e.g. from config or URL).
1239
+ *
1240
+ * @param groupVersionId - The plan group version ID to fetch
1241
+ * @returns Plan group version with populated plan versions
1242
+ */
1243
+ getPlanGroupVersion(groupVersionId: string): Promise<IPlanGroupVersion>;
1244
+ /**
1245
+ * Create checkout session for new subscription
1246
+ * @param workspaceId - The workspace ID
1247
+ * @param request - Checkout session request with planVersionId and optional billing interval/URLs
1248
+ * @returns Checkout session response with checkoutUrl to redirect user
1249
+ */
1250
+ createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest): Promise<ICheckoutSessionResponse>;
1251
+ /**
1252
+ * Update subscription (upgrade/downgrade)
1253
+ * Only allows plan changes within the same plan group
1254
+ * Returns checkout session if payment is required, otherwise returns subscription update response
1255
+ */
1256
+ updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1257
+ /**
1258
+ * List invoices for a workspace subscription
1259
+ * @param workspaceId - The workspace ID
1260
+ * @param limit - Number of invoices to return (default: 10)
1261
+ * @param startingAfter - Invoice ID to start after (for pagination)
1262
+ * @returns List of invoices with pagination info
1263
+ */
1264
+ listInvoices(workspaceId: string, limit?: number, startingAfter?: string): Promise<IInvoiceListResponse>;
1265
+ /**
1266
+ * Get a single invoice by ID
1267
+ * @param workspaceId - The workspace ID
1268
+ * @param invoiceId - The invoice ID
1269
+ * @returns Invoice details
1270
+ */
1271
+ getInvoice(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
1272
+ /**
1273
+ * Cancel subscription at the end of the current billing period
1274
+ * Sets cancelAtPeriodEnd: true - subscription remains active until period ends
1275
+ * @param workspaceId - The workspace ID
1276
+ * @returns Updated subscription with cancelAtPeriodEnd and stripeCurrentPeriodEnd
1277
+ */
1278
+ cancelSubscriptionAtPeriodEnd(workspaceId: string): Promise<ISubscriptionResponse>;
1279
+ /**
1280
+ * Resume a subscription that was scheduled for cancellation
1281
+ * Sets cancelAtPeriodEnd: false - subscription will continue after period ends
1282
+ * @param workspaceId - The workspace ID
1283
+ * @returns Updated subscription with cancelAtPeriodEnd set to false
1284
+ */
1285
+ resumeSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1286
+ }
1287
+
1098
1288
  declare const useSaaSWorkspaces: () => {
1099
1289
  workspaces: IWorkspace[];
1100
1290
  loading: boolean;
@@ -1138,6 +1328,7 @@ declare const useSaaSWorkspaces: () => {
1138
1328
  success: boolean;
1139
1329
  }>;
1140
1330
  switching: boolean;
1331
+ switchingToId: string | null;
1141
1332
  };
1142
1333
 
1143
1334
  declare function WorkspaceSwitcher(props: {
@@ -1265,7 +1456,7 @@ declare const useSubscription: (workspaceId: string | null | undefined) => {
1265
1456
  *
1266
1457
  * return (
1267
1458
  * <div>
1268
- * <h3>{planGroup.name}</h3>
1459
+ * <h3>{planGroup.group.name}</h3>
1269
1460
  * {planGroup.plans.map(plan => (
1270
1461
  * <PlanCard key={plan._id} plan={plan} />
1271
1462
  * ))}
@@ -1705,5 +1896,39 @@ declare class EventEmitter {
1705
1896
  }
1706
1897
  declare const eventEmitter: EventEmitter;
1707
1898
 
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 };
1899
+ /**
1900
+ * Centralized API client for organization (OS) settings.
1901
+ * Extends BaseApi for shared URL/auth/request handling.
1902
+ */
1903
+
1904
+ declare class SettingsApi extends BaseApi {
1905
+ constructor(config: IOsConfig);
1906
+ getSettings(signal?: AbortSignal): Promise<ISettings>;
1907
+ }
1908
+
1909
+ type QuotaDisplayValue = {
1910
+ included: number;
1911
+ overage?: number;
1912
+ unitSize?: number;
1913
+ } | number | null;
1914
+ /**
1915
+ * Normalize a quota value (legacy or per-interval) to a display shape for a given billing interval.
1916
+ * - Legacy: number or IQuotaValue → use as-is (interval ignored).
1917
+ * - New schema: IQuotaByInterval → pick the interval slice (e.g. monthly, yearly, quarterly).
1918
+ */
1919
+ declare function getQuotaDisplayValue(value: number | IQuotaValue | IQuotaByInterval | null | undefined, interval?: BillingInterval): QuotaDisplayValue;
1920
+ /** Options for formatting quota with price. */
1921
+ interface FormatQuotaWithPriceOptions {
1922
+ /** If true, overage is in cents (Stripe); format as dollars. Default true. */
1923
+ overageInCents?: boolean;
1924
+ /** Currency symbol. Default '$'. */
1925
+ currencySymbol?: string;
1926
+ }
1927
+ /**
1928
+ * Format a quota display value as "X included, then $Y.YY / unit" (e.g. "10 included, then $10.00 / video").
1929
+ * Assumes overage is the per-unit price (in cents when overageInCents is true).
1930
+ */
1931
+ declare function formatQuotaWithPrice(value: QuotaDisplayValue, unitName: string, options?: FormatQuotaWithPriceOptions): string;
1932
+
1933
+ export { ApiVersion, AuthStatus, BaseApi, BetaForm, PricingPage, SaaSOSProvider, SettingsApi, SubscriptionContextProvider, UserApi, WhenAuthenticated, WhenNoSubscription, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, eventEmitter, formatQuotaWithPrice, getQuotaDisplayValue, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSubscription, useSubscriptionContext, useSubscriptionManagement, useUpdateSubscription, useUserAttributes, useUserFeatures };
1934
+ 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, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanPricing, IPublicPlanQuotaValue, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, InvoiceStatus, OnWorkspaceChangeParams, PricingPageDetails, PricingPageProps, QuotaDisplayValue, SubscriptionContextValue, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };