@buildbase/sdk 0.0.28 → 0.0.29

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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- import * as react from 'react';
2
- import react__default, { ReactNode } from 'react';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import { z } from 'zod';
4
2
 
5
3
  interface IDocument {
6
4
  _id: string;
@@ -27,6 +25,32 @@ interface IUser extends IDocument {
27
25
  currency?: string;
28
26
  attributes?: Record<string, string | number | boolean>;
29
27
  }
28
+ interface IAsset extends IDocument {
29
+ _id: string;
30
+ createdAt: string;
31
+ updatedAt: string;
32
+ deleted: boolean;
33
+ name: string;
34
+ uniqueName: string;
35
+ mimeType: string;
36
+ size: number;
37
+ encoding: string;
38
+ bucket: {
39
+ name: string;
40
+ url: string;
41
+ path: string;
42
+ };
43
+ metadata: {
44
+ [key: string]: string | number | boolean | object | null;
45
+ };
46
+ image?: {
47
+ width: number;
48
+ height: number;
49
+ };
50
+ tags: string[];
51
+ public: boolean;
52
+ creator: string | IUser;
53
+ }
30
54
  type BillingInterval = 'monthly' | 'yearly' | 'quarterly';
31
55
  interface ISubscription {
32
56
  _id: string;
@@ -595,11 +619,6 @@ interface AuthUser {
595
619
  role: string;
596
620
  image?: string;
597
621
  }
598
- interface AuthSession {
599
- user: AuthUser;
600
- sessionId: string;
601
- expires: string;
602
- }
603
622
  interface IAuthConfig {
604
623
  clientId: string;
605
624
  redirectUrl: string;
@@ -610,6 +629,23 @@ interface IAuthCallbacks {
610
629
  sessionId: string;
611
630
  }>;
612
631
  onSignOut: () => Promise<void>;
632
+ /**
633
+ * Called on page refresh to restore the session.
634
+ * Return the sessionId if the user is still authenticated, or null to log out.
635
+ *
636
+ * The SDK calls this instead of reading from localStorage.
637
+ * Implement this to read from an httpOnly cookie via a server endpoint.
638
+ *
639
+ * @example Next.js — read from httpOnly cookie via API route
640
+ * ```ts
641
+ * getSession: async () => {
642
+ * const res = await fetch('/api/auth/session')
643
+ * const data = await res.json()
644
+ * return data.sessionId ?? null
645
+ * }
646
+ * ```
647
+ */
648
+ getSession: () => Promise<string | null>;
613
649
  /**
614
650
  * Event handler for User and Workspace events
615
651
  * @param eventType - The type of event that occurred
@@ -655,975 +691,232 @@ interface IOsState extends IOsConfig {
655
691
  settings?: ISettings | null;
656
692
  }
657
693
 
658
- interface SaaSOSProviderProps extends IOsState {
659
- children: react__default.ReactNode;
660
- }
661
- declare const SaaSOSProvider: react__default.FC<SaaSOSProviderProps>;
662
-
663
- type Language = 'en' | 'es' | 'fr' | 'de' | 'zh' | 'ja' | 'ko';
664
- interface FormText {
665
- nameLabel: string;
666
- emailLabel: string;
667
- submitText: string;
668
- submittingText: string;
669
- errorMessage: string;
670
- }
671
- interface BetaFormProps {
672
- onSuccess?: () => void;
673
- onError?: (error: string) => void;
674
- className?: string;
675
- fieldClassName?: string;
676
- language?: Language;
677
- customTexts?: Partial<FormText>;
678
- autoFocus?: boolean;
679
- showSuccessMessage?: boolean;
680
- successMessageDuration?: number;
681
- hideLogo?: boolean;
682
- hideTitles?: boolean;
683
- }
684
- declare const BetaForm: react__default.FC<BetaFormProps>;
685
-
686
- interface PricingPageDetails {
687
- /** Whether plan data is being fetched */
688
- loading: boolean;
689
- /** Error message if fetch failed */
690
- error: string | null;
691
- /** Subscription items (features, limits, quotas) */
692
- items: IPublicPlanItem[];
693
- /** Plan versions with pricing, features, limits, quotas */
694
- plans: IPublicPlanVersion[];
695
- /** Optional note from API (e.g. "Pricing is in cents. Please convert to dollars for display.") */
696
- notes?: string;
697
- /** Refetch plan data */
698
- refetch: () => Promise<void>;
699
- }
700
- interface PricingPageProps {
701
- /** Plan group slug (e.g. 'main-pricing', 'enterprise') */
702
- slug: string;
703
- /** Render prop receiving plan details - construct layout from items and plans */
704
- children: (details: PricingPageDetails) => ReactNode;
705
- /** Custom loading UI. Defaults to skeleton. */
706
- loadingFallback?: ReactNode;
707
- /** Custom error UI. Receives error message. */
708
- errorFallback?: (error: string) => ReactNode;
709
- }
710
694
  /**
711
- * Fetches and provides plan/pricing details for public pricing pages (no login required).
712
- * Returns items (features, limits, quotas) and plans (with pricing) - user constructs layout.
695
+ * Base API client for SDK endpoints.
696
+ * All domain API classes (WorkspaceApi, UserApi, etc.) extend this to share
697
+ * URL building, auth headers, and request/response handling.
713
698
  *
714
- * @example
715
- * ```tsx
716
- * <PricingPage slug="main-pricing">
717
- * {({ loading, error, items, plans, refetch }) => {
718
- * if (loading) return <Loading />;
719
- * if (error) return <Error message={error} />;
699
+ * Supports two auth modes:
700
+ * 1. **Client-side (default):** reads sessionId from localStorage automatically.
701
+ * 2. **Server-side:** pass `sessionId` in config — no localStorage access.
720
702
  *
721
- * return (
722
- * <div>
723
- * {plans.map(plan => (
724
- * <PlanCard key={plan._id} plan={plan} items={items} />
725
- * ))}
726
- * </div>
727
- * );
728
- * }}
729
- * </PricingPage>
703
+ * @example Server-side usage
704
+ * ```ts
705
+ * const api = new WorkspaceApi({
706
+ * serverUrl: "https://api.buildbase.app",
707
+ * version: "v1",
708
+ * orgId: "...",
709
+ * sessionId: req.headers["x-session-id"], // from your request
710
+ * });
711
+ * const sub = await api.getCurrentSubscription(workspaceId);
730
712
  * ```
731
713
  */
732
- declare function PricingPage({ slug, children, loadingFallback, errorFallback }: PricingPageProps): react_jsx_runtime.JSX.Element;
733
714
 
734
- interface IProps$2 {
735
- children: React.ReactNode;
715
+ interface IBaseApiConfig {
716
+ serverUrl: string;
717
+ version: ApiVersion;
718
+ orgId?: string;
719
+ /** When true, ensureReady() also requires orgId. Used by WorkspaceApi and SettingsApi. */
720
+ requireOrgId?: boolean;
721
+ /** API path segment after version (default 'public'). e.g. 'public' => .../v1/public, 'beta' => .../v1/beta */
722
+ basePath?: string;
723
+ /**
724
+ * Session ID for server-side usage. When provided, this is used for auth
725
+ * instead of reading from localStorage. Pass the session token from your
726
+ * request headers, cookies, or any server-side session store.
727
+ */
728
+ sessionId?: string;
729
+ /** Request timeout in milliseconds. 0 = no timeout. */
730
+ timeout?: number;
731
+ /** Max automatic retries for network errors / 5xx. */
732
+ maxRetries?: number;
733
+ /** Enable debug logging for all requests. */
734
+ debug?: boolean;
735
+ /** Custom headers merged into every request. */
736
+ headers?: Record<string, string>;
737
+ /** Error callback — called before error is thrown. */
738
+ onError?: (error: Error, context: {
739
+ method: string;
740
+ path: string;
741
+ }) => void;
742
+ /** Custom fetch implementation. */
743
+ fetch?: typeof globalThis.fetch;
736
744
  }
737
745
  /**
738
- * Conditional component that renders children only when user is authenticated.
739
- * Returns null if user is not authenticated or authentication status is still loading.
740
- *
741
- * @param props - Component props
742
- * @param props.children - Content to render when authenticated
743
- *
744
- * @example
745
- * ```tsx
746
- * function App() {
747
- * return (
748
- * <SaaSOSProvider {...config}>
749
- * <WhenAuthenticated>
750
- * <Dashboard />
751
- * </WhenAuthenticated>
752
- * <WhenUnauthenticated>
753
- * <LoginPage />
754
- * </WhenUnauthenticated>
755
- * </SaaSOSProvider>
756
- * );
757
- * }
758
- * ```
759
- */
760
- declare const WhenAuthenticated: {
761
- (props: IProps$2): react.ReactNode;
762
- displayName: string;
763
- };
764
- /**
765
- * Conditional component that renders children only when user is NOT authenticated.
766
- * Returns null if user is authenticated.
767
- * Note: Also renders during loading/redirecting states (when not yet authenticated).
768
- *
769
- * @param props - Component props
770
- * @param props.children - Content to render when unauthenticated
771
- *
772
- * @example
773
- * ```tsx
774
- * function App() {
775
- * return (
776
- * <SaaSOSProvider {...config}>
777
- * <WhenUnauthenticated>
778
- * <LoginPage />
779
- * </WhenUnauthenticated>
780
- * <WhenAuthenticated>
781
- * <Dashboard />
782
- * </WhenAuthenticated>
783
- * </SaaSOSProvider>
784
- * );
785
- * }
786
- * ```
787
- *
788
- * @example
789
- * ```tsx
790
- * // Handle loading state separately
791
- * function App() {
792
- * const { isLoading } = useSaaSAuth();
793
- *
794
- * if (isLoading) return <LoadingSpinner />;
795
- *
796
- * return (
797
- * <>
798
- * <WhenUnauthenticated><LoginPage /></WhenUnauthenticated>
799
- * <WhenAuthenticated><Dashboard /></WhenAuthenticated>
800
- * </>
801
- * );
802
- * }
803
- * ```
746
+ * Base class for SDK API clients.
747
+ * Provides:
748
+ * - baseUrl: `${serverUrl}/api/${version}/public`
749
+ * - getAuthHeaders()
750
+ * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
751
+ * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
804
752
  */
805
- declare const WhenUnauthenticated: {
806
- (props: IProps$2): react.ReactNode;
807
- displayName: string;
808
- };
809
-
810
- interface IProps$1 {
811
- roles: string[];
812
- children: React.ReactNode;
813
- fallback?: React.ReactNode;
753
+ declare abstract class BaseApi {
754
+ protected readonly serverUrl: string;
755
+ protected readonly version: ApiVersion;
756
+ protected readonly orgId: string | undefined;
757
+ private readonly requireOrgId;
758
+ private readonly basePath;
759
+ private readonly _sessionId;
760
+ private readonly _timeout;
761
+ private readonly _maxRetries;
762
+ private readonly _debug;
763
+ private readonly _customHeaders;
764
+ private readonly _onError?;
765
+ private readonly _fetch;
766
+ constructor(config: IBaseApiConfig);
767
+ /** Throws if config is not ready for API calls. Called automatically by fetchJson/fetchResponse. */
768
+ protected ensureReady(): void;
769
+ /** Base URL: ${serverUrl}/api/${version}/${basePath} */
770
+ protected get baseUrl(): string;
771
+ /**
772
+ * Auth headers (x-session-id).
773
+ * Uses injected sessionId (server-side) or falls back to localStorage (client-side).
774
+ * Subclasses can override to add more headers.
775
+ */
776
+ protected getAuthHeaders(): Record<string, string>;
777
+ /** Build full URL from path (path can be "workspaces" or "/workspaces"). */
778
+ protected url(path: string): string;
779
+ /** Merge auth + custom + per-request headers. */
780
+ private buildHeaders;
781
+ /** Execute fetch with timeout, retries, debug logging, and error callback. */
782
+ private executeFetch;
783
+ /**
784
+ * Execute request and parse JSON with handleApiResponse (throws on !response.ok).
785
+ * Use for standard JSON APIs.
786
+ */
787
+ protected fetchJson<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
788
+ /**
789
+ * Execute request and return raw Response (for custom parsing or error handling).
790
+ * Caller is responsible for checking response.ok and parsing body.
791
+ */
792
+ protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
814
793
  }
794
+
815
795
  /**
816
- * Conditional component that renders children only when user has one of the specified roles.
817
- * Checks the user's global role (not workspace-specific).
818
- *
819
- * @param props - Component props
820
- * @param props.roles - Array of role strings to check against user's role
821
- * @param props.children - Content to render when user has matching role
822
- * @param props.fallback - Optional content to render when user doesn't have matching role (default: null)
823
- *
824
- * @example
825
- * ```tsx
826
- * function AdminPanel() {
827
- * return (
828
- * <WhenRoles roles={['admin', 'super-admin']}>
829
- * <AdminContent />
830
- * </WhenRoles>
831
- * );
832
- * }
833
- * ```
834
- *
835
- * @example
836
- * ```tsx
837
- * // With fallback
838
- * function SettingsPage() {
839
- * return (
840
- * <WhenRoles
841
- * roles={['admin']}
842
- * fallback={<p>You don't have permission to access this page.</p>}
843
- * >
844
- * <AdminSettings />
845
- * </WhenRoles>
846
- * );
847
- * }
848
- * ```
849
- */
850
- declare const WhenRoles: {
851
- (props: IProps$1): react.ReactNode;
852
- displayName: string;
853
- };
854
- /**
855
- * Conditional component that renders children only when user has one of the specified roles
856
- * in the current workspace. Checks workspace-specific role, not global role.
857
- *
858
- * @param props - Component props
859
- * @param props.roles - Array of role strings to check against user's workspace role
860
- * @param props.children - Content to render when user has matching workspace role
861
- * @param props.fallback - Optional content to render when user doesn't have matching role (default: null)
862
- *
863
- * @example
864
- * ```tsx
865
- * function WorkspaceSettings() {
866
- * return (
867
- * <WhenWorkspaceRoles roles={['owner', 'admin']}>
868
- * <SettingsContent />
869
- * </WhenWorkspaceRoles>
870
- * );
871
- * }
872
- * ```
873
- *
874
- * @example
875
- * ```tsx
876
- * // Edge case: User not in current workspace
877
- * function WorkspaceContent() {
878
- * return (
879
- * <WhenWorkspaceRoles
880
- * roles={['member']}
881
- * fallback={<p>You are not a member of this workspace.</p>}
882
- * >
883
- * <WorkspaceDashboard />
884
- * </WhenWorkspaceRoles>
885
- * );
886
- * }
887
- * ```
796
+ * API client for authentication.
797
+ * Extends BaseApi for shared URL/auth/request handling.
888
798
  */
889
- declare const WhenWorkspaceRoles: {
890
- (props: IProps$1): react.ReactNode;
891
- displayName: string;
892
- };
893
799
 
894
- interface IProps {
895
- slug: string;
896
- children: React.ReactNode;
800
+ interface AuthRequestParams {
801
+ orgId: string;
802
+ clientId: string;
803
+ redirect: {
804
+ success: string;
805
+ error: string;
806
+ };
807
+ }
808
+ interface AuthRequestResponse {
809
+ success: boolean;
810
+ data: {
811
+ redirectUrl: string;
812
+ };
813
+ message: string;
814
+ }
815
+ declare class AuthApi extends BaseApi {
816
+ constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'> & {
817
+ sessionId?: string;
818
+ });
819
+ /**
820
+ * Initiate OAuth sign-in flow. Returns redirect URL to the auth provider.
821
+ * Uses /api/v1/auth/request (no 'public' prefix — auth endpoints are at the root).
822
+ */
823
+ requestAuth(params: AuthRequestParams): Promise<AuthRequestResponse>;
824
+ /** Fetch user profile with the given session ID (used after OAuth redirect or from storage). */
825
+ getProfile(sessionId: string, signal?: AbortSignal): Promise<IUser>;
897
826
  }
898
- /**
899
- * Conditional component that renders children only when the specified workspace feature is enabled.
900
- * Checks feature flags at the workspace level.
901
- *
902
- * @param props - Component props
903
- * @param props.slug - Feature flag slug/key to check
904
- * @param props.children - Content to render when feature is enabled
905
- *
906
- * @example
907
- * ```tsx
908
- * function PremiumFeature() {
909
- * return (
910
- * <WhenWorkspaceFeatureEnabled slug="premium-analytics">
911
- * <AnalyticsDashboard />
912
- * </WhenWorkspaceFeatureEnabled>
913
- * );
914
- * }
915
- * ```
916
- *
917
- * @example
918
- * ```tsx
919
- * // Multiple features
920
- * function FeatureContent() {
921
- * return (
922
- * <>
923
- * <WhenWorkspaceFeatureEnabled slug="feature-a">
924
- * <FeatureA />
925
- * </WhenWorkspaceFeatureEnabled>
926
- * <WhenWorkspaceFeatureEnabled slug="feature-b">
927
- * <FeatureB />
928
- * </WhenWorkspaceFeatureEnabled>
929
- * </>
930
- * );
931
- * }
932
- * ```
933
- */
934
- declare const WhenWorkspaceFeatureEnabled: {
935
- (props: IProps): react.ReactNode;
936
- displayName: string;
937
- };
938
- /**
939
- * Conditional component that renders children only when the specified workspace feature is disabled.
940
- * Checks feature flags at the workspace level.
941
- *
942
- * @param props - Component props
943
- * @param props.slug - Feature flag slug/key to check
944
- * @param props.children - Content to render when feature is disabled
945
- *
946
- * @example
947
- * ```tsx
948
- * function UpgradePrompt() {
949
- * return (
950
- * <WhenWorkspaceFeatureDisabled slug="premium-feature">
951
- * <UpgradeButton />
952
- * </WhenWorkspaceFeatureDisabled>
953
- * );
954
- * }
955
- * ```
956
- */
957
- declare const WhenWorkspaceFeatureDisabled: {
958
- (props: IProps): react.ReactNode;
959
- displayName: string;
960
- };
961
- /**
962
- * Conditional component that renders children only when the specified user feature is enabled.
963
- * Checks feature flags at the user level (from UserProvider).
964
- *
965
- * @param props - Component props
966
- * @param props.slug - Feature flag slug/key to check
967
- * @param props.children - Content to render when feature is enabled
968
- *
969
- * @example
970
- * ```tsx
971
- * function BetaFeature() {
972
- * return (
973
- * <WhenUserFeatureEnabled slug="beta-access">
974
- * <BetaContent />
975
- * </WhenUserFeatureEnabled>
976
- * );
977
- * }
978
- * ```
979
- *
980
- * @example
981
- * ```tsx
982
- * // Edge case: Feature not loaded yet
983
- * function FeatureContent() {
984
- * const { isLoading } = useUserFeatures();
985
- *
986
- * if (isLoading) return <Loading />;
987
- *
988
- * return (
989
- * <WhenUserFeatureEnabled slug="feature-x">
990
- * <FeatureX />
991
- * </WhenUserFeatureEnabled>
992
- * );
993
- * }
994
- * ```
995
- */
996
- declare const WhenUserFeatureEnabled: {
997
- (props: IProps): react.ReactNode;
998
- displayName: string;
999
- };
1000
- /**
1001
- * Conditional component that renders children only when the specified user feature is disabled.
1002
- * Checks feature flags at the user level (from UserProvider).
1003
- *
1004
- * @param props - Component props
1005
- * @param props.slug - Feature flag slug/key to check
1006
- * @param props.children - Content to render when feature is disabled
1007
- *
1008
- * @example
1009
- * ```tsx
1010
- * function UpgradePrompt() {
1011
- * return (
1012
- * <WhenUserFeatureDisabled slug="premium-access">
1013
- * <UpgradeButton />
1014
- * </WhenUserFeatureDisabled>
1015
- * );
1016
- * }
1017
- * ```
1018
- */
1019
- declare const WhenUserFeatureDisabled: {
1020
- (props: IProps): react.ReactNode;
1021
- displayName: string;
1022
- };
1023
827
 
1024
- interface IWhenSubscriptionProps {
1025
- /** Content to render when the condition is met (workspace has an active subscription). */
1026
- children: React.ReactNode;
1027
- /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
1028
- loadingComponent?: React.ReactNode;
1029
- /** Optional component/element to show when condition is not met (e.g. <UpgradePrompt />). */
1030
- fallbackComponent?: React.ReactNode;
828
+ interface IScreenDetail {
829
+ title: string;
830
+ description: string;
1031
831
  }
1032
- /**
1033
- * Renders children only when the current workspace has an active subscription (any plan).
1034
- * Optionally pass loadingComponent (while loading) or fallbackComponent (when not subscribed).
1035
- * Must be used within SubscriptionContextProvider.
1036
- *
1037
- * @param props - Component props
1038
- * @param props.children - Content to render when subscribed
1039
- * @param props.loadingComponent - Optional component/element to show while loading
1040
- * @param props.fallbackComponent - Optional component/element to show when not subscribed
1041
- * @returns ReactNode - children when subscribed, loadingComponent when loading, fallbackComponent when not subscribed, or null
1042
- *
1043
- * @example
1044
- * ```tsx
1045
- * <WhenSubscription>
1046
- * <BillingSettings />
1047
- * </WhenSubscription>
1048
- * ```
1049
- *
1050
- * @example
1051
- * ```tsx
1052
- * <WhenSubscription
1053
- * loadingComponent={<Skeleton />}
1054
- * fallbackComponent={<UpgradePrompt />}
1055
- * >
1056
- * <BillingSettings />
1057
- * </WhenSubscription>
1058
- * ```
1059
- */
1060
- declare const WhenSubscription: {
1061
- (props: IWhenSubscriptionProps): react.ReactNode;
1062
- displayName: string;
1063
- };
1064
- /**
1065
- * Renders children only when the current workspace has no subscription (or no current workspace).
1066
- * Optionally pass loadingComponent (while loading) or fallbackComponent (when already subscribed).
1067
- * Must be used within SubscriptionContextProvider.
1068
- *
1069
- * @param props - Component props
1070
- * @param props.children - Content to render when not subscribed
1071
- * @param props.loadingComponent - Optional component/element to show while loading
1072
- * @param props.fallbackComponent - Optional component/element to show when already subscribed
1073
- * @returns ReactNode - children when not subscribed, loadingComponent when loading, fallbackComponent when subscribed, or null
1074
- *
1075
- * @example
1076
- * ```tsx
1077
- * <WhenNoSubscription>
1078
- * <UpgradePrompt />
1079
- * </WhenNoSubscription>
1080
- * ```
1081
- *
1082
- * @example
1083
- * ```tsx
1084
- * <WhenNoSubscription
1085
- * loadingComponent={<Spinner />}
1086
- * fallbackComponent={null}
1087
- * >
1088
- * <UpgradePrompt />
1089
- * </WhenNoSubscription>
1090
- * ```
1091
- */
1092
- declare const WhenNoSubscription: {
1093
- (props: IWhenSubscriptionProps): react.ReactNode;
1094
- displayName: string;
1095
- };
1096
- interface IWhenSubscriptionToPlansProps {
1097
- /** Plan slugs to match (e.g. ['pro', 'enterprise']). Matching is case-insensitive. */
1098
- plans: string[];
1099
- /** Content to render when the workspace is on one of the given plans. */
1100
- children: React.ReactNode;
1101
- /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
1102
- loadingComponent?: React.ReactNode;
1103
- /** Optional component/element to show when not on a matching plan (e.g. <UpgradeToPro />). */
1104
- fallbackComponent?: React.ReactNode;
832
+ interface IBetaConfig extends IDocument {
833
+ name: string;
834
+ smallName: string;
835
+ description: string;
836
+ logoFallBack: string;
837
+ logo: string | IAsset;
838
+ privacyPolicy: string;
839
+ termsOfService: string;
840
+ enabled: boolean;
841
+ screen: {
842
+ register: IScreenDetail;
843
+ thankYou: IScreenDetail;
844
+ };
1105
845
  }
1106
- /**
1107
- * Renders children only when the current workspace is subscribed to one of the given plans.
1108
- * Matches by plan slug only. Optionally pass loadingComponent (while loading) or fallbackComponent (when not on a matching plan).
1109
- * Must be used within SubscriptionContextProvider.
1110
- *
1111
- * @param props - Component props
1112
- * @param props.plans - Plan slugs to match (e.g. ['pro', 'enterprise'])
1113
- * @param props.children - Content to render when on a matching plan
1114
- * @param props.loadingComponent - Optional component/element to show while loading
1115
- * @param props.fallbackComponent - Optional component/element to show when not on a matching plan
1116
- * @returns ReactNode - children when on a matching plan, loadingComponent when loading, fallbackComponent when not matching, or null
1117
- *
1118
- * @example
1119
- * ```tsx
1120
- * <WhenSubscriptionToPlans plans={['pro', 'enterprise']}>
1121
- * <AdvancedAnalytics />
1122
- * </WhenSubscriptionToPlans>
1123
- * ```
1124
- *
1125
- * @example
1126
- * ```tsx
1127
- * <WhenSubscriptionToPlans
1128
- * plans={['pro', 'enterprise']}
1129
- * loadingComponent={<Skeleton />}
1130
- * fallbackComponent={<UpgradeToPro />}
1131
- * >
1132
- * <AdvancedAnalytics />
1133
- * </WhenSubscriptionToPlans>
1134
- * ```
1135
- */
1136
- declare const WhenSubscriptionToPlans: {
1137
- (props: IWhenSubscriptionToPlansProps): react.ReactNode;
1138
- displayName: string;
1139
- };
1140
- interface IWhenTrialingProps {
1141
- /** Content to render when the condition is met. */
1142
- children: React.ReactNode;
1143
- /** Optional component/element to show while subscription is loading. */
1144
- loadingComponent?: React.ReactNode;
1145
- /** Optional component/element to show when condition is not met. */
1146
- fallbackComponent?: React.ReactNode;
846
+ interface ApiResponse {
847
+ status: string;
848
+ message: string;
849
+ data?: {
850
+ submissionId: string;
851
+ status: string;
852
+ };
853
+ code: string;
854
+ config?: IBetaConfig;
855
+ submissionId?: string;
1147
856
  }
1148
- /**
1149
- * Renders children only when the current workspace subscription is in trial (status === 'trialing').
1150
- * Must be used within SubscriptionContextProvider.
1151
- *
1152
- * @example
1153
- * ```tsx
1154
- * <WhenTrialing fallbackComponent={<NormalContent />}>
1155
- * <TrialBanner />
1156
- * </WhenTrialing>
1157
- * ```
1158
- */
1159
- declare const WhenTrialing: {
1160
- (props: IWhenTrialingProps): react.ReactNode;
1161
- displayName: string;
1162
- };
1163
- /**
1164
- * Renders children only when the current workspace subscription is NOT in trial.
1165
- * This includes: no subscription, active, canceled, past_due, etc.
1166
- * Must be used within SubscriptionContextProvider.
1167
- *
1168
- * @example
1169
- * ```tsx
1170
- * <WhenNotTrialing>
1171
- * <RegularPricingPage />
1172
- * </WhenNotTrialing>
1173
- * ```
1174
- */
1175
- declare const WhenNotTrialing: {
1176
- (props: IWhenTrialingProps): react.ReactNode;
1177
- displayName: string;
1178
- };
1179
- interface IWhenTrialEndingProps {
1180
- /** Content to render when trial is ending soon. */
1181
- children: React.ReactNode;
1182
- /** Optional component/element to show while subscription is loading. */
1183
- loadingComponent?: React.ReactNode;
1184
- /** Optional component/element to show when trial is not ending soon. */
1185
- fallbackComponent?: React.ReactNode;
1186
- /** Number of days threshold to consider "ending soon". Defaults to 3. */
1187
- daysThreshold?: number;
857
+ declare class BetaForm {
858
+ private api;
859
+ private orgId;
860
+ constructor(config: IOsConfig);
861
+ fetchConfig(): Promise<IBetaConfig>;
862
+ submitBetaUser(formData: {
863
+ name: string;
864
+ email: string;
865
+ context?: {
866
+ country?: string;
867
+ language?: string;
868
+ timezone?: string;
869
+ currency?: string;
870
+ };
871
+ }): Promise<ApiResponse>;
1188
872
  }
1189
- /**
1190
- * Renders children only when the subscription is trialing AND the trial ends within
1191
- * the given threshold (default 3 days). Useful for showing urgent upgrade prompts.
1192
- * Must be used within SubscriptionContextProvider.
1193
- *
1194
- * @example
1195
- * ```tsx
1196
- * <WhenTrialEnding daysThreshold={5}>
1197
- * <UpgradeBanner />
1198
- * </WhenTrialEnding>
1199
- * ```
1200
- */
1201
- declare const WhenTrialEnding: {
1202
- (props: IWhenTrialEndingProps): react.ReactNode;
1203
- displayName: string;
1204
- };
1205
873
 
1206
- interface IWhenQuotaProps {
1207
- /** Quota slug to check (e.g. 'api_calls', 'emails', 'storage'). */
1208
- slug: string;
1209
- /** Content to render when the condition is met. */
1210
- children: React.ReactNode;
1211
- /** Optional component/element to show while quota usage is loading (e.g. <Skeleton />). */
1212
- loadingComponent?: React.ReactNode;
1213
- /** Optional component/element to show when condition is not met (e.g. <UpgradePrompt />). */
1214
- fallbackComponent?: React.ReactNode;
1215
- }
1216
- interface IWhenQuotaThresholdProps extends IWhenQuotaProps {
1217
- /** Usage percentage threshold (0-100). Children render when usage >= this percentage. */
1218
- threshold: number;
874
+ declare class PushApi extends BaseApi {
875
+ constructor(config: Pick<IBaseApiConfig, 'serverUrl' | 'version' | 'orgId' | 'sessionId'>);
876
+ getVapidPublicKey(): Promise<{
877
+ publicKey: string;
878
+ }>;
879
+ subscribe(subscription: {
880
+ endpoint: string;
881
+ keys: {
882
+ p256dh: string;
883
+ auth: string;
884
+ };
885
+ }, userAgent: string): Promise<void>;
886
+ unsubscribe(endpoint: string): Promise<void>;
1219
887
  }
888
+
1220
889
  /**
1221
- * Renders children only when the specified quota has remaining units (available > 0).
1222
- * Must be used within QuotaUsageContextProvider (included in SaaSOSProvider by default).
1223
- *
1224
- * @example
1225
- * ```tsx
1226
- * <WhenQuotaAvailable slug="api_calls">
1227
- * <MakeApiCallButton />
1228
- * </WhenQuotaAvailable>
1229
- * ```
1230
- *
1231
- * @example
1232
- * ```tsx
1233
- * <WhenQuotaAvailable
1234
- * slug="emails"
1235
- * loadingComponent={<Skeleton />}
1236
- * fallbackComponent={<p>Email quota exhausted. <UpgradeLink /></p>}
1237
- * >
1238
- * <SendEmailButton />
1239
- * </WhenQuotaAvailable>
1240
- * ```
890
+ * Centralized API client for organization (OS) settings.
891
+ * Extends BaseApi for shared URL/auth/request handling.
1241
892
  */
1242
- declare const WhenQuotaAvailable: {
1243
- (props: IWhenQuotaProps): react.ReactNode;
1244
- displayName: string;
1245
- };
893
+
894
+ declare class SettingsApi extends BaseApi {
895
+ constructor(config: IOsConfig & {
896
+ sessionId?: string;
897
+ });
898
+ getSettings(signal?: AbortSignal): Promise<ISettings>;
899
+ }
900
+
1246
901
  /**
1247
- * Renders children only when the specified quota is fully consumed (available <= 0).
1248
- * Must be used within QuotaUsageContextProvider (included in SaaSOSProvider by default).
1249
- *
1250
- * @example
1251
- * ```tsx
1252
- * <WhenQuotaExhausted slug="api_calls">
1253
- * <UpgradePrompt message="You've used all your API calls this month." />
1254
- * </WhenQuotaExhausted>
1255
- * ```
1256
- *
1257
- * @example
1258
- * ```tsx
1259
- * <WhenQuotaExhausted
1260
- * slug="storage"
1261
- * loadingComponent={<Spinner />}
1262
- * fallbackComponent={null}
1263
- * >
1264
- * <StorageFullBanner />
1265
- * </WhenQuotaExhausted>
1266
- * ```
902
+ * API client for user attributes and features.
903
+ * Extends BaseApi for shared URL/auth/request handling.
1267
904
  */
1268
- declare const WhenQuotaExhausted: {
1269
- (props: IWhenQuotaProps): react.ReactNode;
1270
- displayName: string;
1271
- };
1272
- /**
1273
- * Renders children only when the specified quota is in overage (consumed > included).
1274
- * Must be used within QuotaUsageContextProvider (included in SaaSOSProvider by default).
1275
- *
1276
- * @example
1277
- * ```tsx
1278
- * <WhenQuotaOverage slug="api_calls">
1279
- * <OverageBillingWarning />
1280
- * </WhenQuotaOverage>
1281
- * ```
1282
- *
1283
- * @example
1284
- * ```tsx
1285
- * <WhenQuotaOverage
1286
- * slug="emails"
1287
- * loadingComponent={<Skeleton />}
1288
- * fallbackComponent={null}
1289
- * >
1290
- * <p>You are being billed for overage usage.</p>
1291
- * </WhenQuotaOverage>
1292
- * ```
1293
- */
1294
- declare const WhenQuotaOverage: {
1295
- (props: IWhenQuotaProps): react.ReactNode;
1296
- displayName: string;
1297
- };
1298
- /**
1299
- * Renders children when the specified quota's usage percentage reaches or exceeds the threshold.
1300
- * Usage percentage = (consumed / included) * 100. If included is 0 and consumed > 0, treats as 100%.
1301
- * Must be used within QuotaUsageContextProvider (included in SaaSOSProvider by default).
1302
- *
1303
- * @example
1304
- * ```tsx
1305
- * <WhenQuotaThreshold slug="api_calls" threshold={80}>
1306
- * <p>Warning: You've used over 80% of your API calls.</p>
1307
- * </WhenQuotaThreshold>
1308
- * ```
1309
- *
1310
- * @example
1311
- * ```tsx
1312
- * <WhenQuotaThreshold
1313
- * slug="storage"
1314
- * threshold={90}
1315
- * loadingComponent={<Spinner />}
1316
- * fallbackComponent={null}
1317
- * >
1318
- * <StorageWarningBanner />
1319
- * </WhenQuotaThreshold>
1320
- * ```
1321
- */
1322
- declare const WhenQuotaThreshold: {
1323
- (props: IWhenQuotaThresholdProps): react.ReactNode;
1324
- displayName: string;
1325
- };
1326
-
1327
- /**
1328
- * Value provided by SubscriptionContext and returned by useSubscriptionContext.
1329
- */
1330
- interface SubscriptionContextValue {
1331
- /** Current subscription response for the current workspace, or null if none or not loaded. */
1332
- response: ISubscriptionResponse | null;
1333
- /** True while subscription is being fetched. */
1334
- loading: boolean;
1335
- /** Error message if the last fetch failed, or null. */
1336
- error: string | null;
1337
- /** Refetch subscription for the current workspace. Call after plan change (e.g. upgrade) or when subscription was updated elsewhere. */
1338
- refetch: () => Promise<void>;
1339
- }
1340
-
1341
- /**
1342
- * Provides subscription data for the current workspace to subscription gate components.
1343
- * Fetches when workspace changes; refetches when subscription is invalidated (e.g. after plan change).
1344
- * Must wrap (or be ancestor of) any component that uses WhenSubscription, WhenNoSubscription,
1345
- * WhenSubscriptionToPlans, or useSubscriptionContext. Included in SaaSOSProvider by default.
1346
- *
1347
- * @param props - Component props
1348
- * @param props.children - React tree that may use subscription gates or useSubscriptionContext
1349
- * @returns Provider element that supplies subscription context to descendants
1350
- */
1351
- declare const SubscriptionContextProvider: react__default.FC<{
1352
- children: ReactNode;
1353
- }>;
1354
- /**
1355
- * Returns subscription data for the current workspace. Must be used within SubscriptionContextProvider.
1356
- *
1357
- * @returns SubscriptionContextValue - { response, loading, refetch }
1358
- * @throws Error if used outside SubscriptionContextProvider
1359
- */
1360
- declare function useSubscriptionContext(): SubscriptionContextValue;
1361
-
1362
- /**
1363
- * Notify all subscribers to refetch subscription (e.g. after update/cancel/resume).
1364
- * Called internally by useUpdateSubscription, useCancelSubscription, useResumeSubscription on success.
1365
- */
1366
- declare function invalidateSubscription(): void;
1367
-
1368
- /**
1369
- * Value provided by QuotaUsageContext and returned by useQuotaUsageContext.
1370
- */
1371
- interface QuotaUsageContextValue {
1372
- /** Current quota usage statuses keyed by slug, or null if not loaded. */
1373
- quotas: Record<string, IQuotaUsageStatus> | null;
1374
- /** True while quota usage is being fetched. */
1375
- loading: boolean;
1376
- /** Error message if the last fetch failed, or null. */
1377
- error: string | null;
1378
- /** Refetch all quota usage for the current workspace. Call after recording usage or when usage was updated elsewhere. */
1379
- refetch: () => Promise<void>;
1380
- }
1381
-
1382
- /**
1383
- * Provides quota usage data for the current workspace to quota gate components.
1384
- * Fetches when workspace changes; refetches when quota usage is invalidated (e.g. after recording usage).
1385
- * Must wrap (or be ancestor of) any component that uses WhenQuotaAvailable, WhenQuotaExhausted,
1386
- * WhenQuotaOverage, WhenQuotaThreshold, or useQuotaUsageContext. Included in SaaSOSProvider by default.
1387
- *
1388
- * @param props - Component props
1389
- * @param props.children - React tree that may use quota gates or useQuotaUsageContext
1390
- * @returns Provider element that supplies quota usage context to descendants
1391
- */
1392
- declare const QuotaUsageContextProvider: react__default.FC<{
1393
- children: ReactNode;
1394
- }>;
1395
- /**
1396
- * Returns quota usage data for the current workspace. Must be used within QuotaUsageContextProvider.
1397
- *
1398
- * @returns QuotaUsageContextValue - { quotas, loading, refetch }
1399
- * @throws Error if used outside QuotaUsageContextProvider
1400
- */
1401
- declare function useQuotaUsageContext(): QuotaUsageContextValue;
1402
-
1403
- /**
1404
- * Notify all subscribers to refetch quota usage (e.g. after recording usage).
1405
- * Called internally by useRecordUsage on success.
1406
- */
1407
- declare function invalidateQuotaUsage(): void;
1408
-
1409
- type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'usage' | 'features' | 'notifications' | 'danger';
1410
-
1411
- declare function useSaaSAuth(): {
1412
- signIn: () => Promise<void>;
1413
- signOut: () => Promise<void>;
1414
- openWorkspaceSettings: (section?: WorkspaceSettingsSection) => void;
1415
- isAuthenticated: boolean;
1416
- isLoading: boolean;
1417
- isRedirecting: boolean;
1418
- user: AuthUser | undefined;
1419
- session: AuthSession | null;
1420
- status: AuthStatus;
1421
- };
1422
-
1423
- /**
1424
- * Hook to access OS (organization) state (serverUrl, version, orgId, auth, settings).
1425
- * Prefer useSaaSSettings() when you only need settings.
1426
- */
1427
- declare function useSaaSOs(): IOsState;
1428
- /**
1429
- * Hook to access organization settings from the OS context.
1430
- * Automatically fetches settings when OS config is ready.
1431
- *
1432
- * @returns An object containing:
1433
- * - `settings`: Organization settings object (null if not loaded)
1434
- * - `getSettings(signal?)`: Function to manually fetch settings (supports AbortSignal)
1435
- *
1436
- * @example
1437
- * ```tsx
1438
- * function SettingsDisplay() {
1439
- * const { settings } = useSaaSSettings();
1440
- *
1441
- * if (!settings) return <Loading />;
1442
- *
1443
- * return (
1444
- * <div>
1445
- * <p>Organization: {settings.name}</p>
1446
- * <p>Theme: {settings.theme}</p>
1447
- * </div>
1448
- * );
1449
- * }
1450
- * ```
1451
- *
1452
- * @example
1453
- * ```tsx
1454
- * // Manual fetch with abort signal
1455
- * function SettingsLoader() {
1456
- * const { getSettings } = useSaaSSettings();
1457
- *
1458
- * useEffect(() => {
1459
- * const controller = new AbortController();
1460
- * getSettings(controller.signal);
1461
- *
1462
- * return () => controller.abort();
1463
- * }, [getSettings]);
1464
- * }
1465
- * ```
1466
- */
1467
- declare function useSaaSSettings(): {
1468
- settings: ISettings | null | undefined;
1469
- getSettings: (signal?: AbortSignal) => Promise<ISettings | null>;
1470
- };
1471
-
1472
- interface UserContextValue {
1473
- attributes: Record<string, string | number | boolean>;
1474
- features: Record<string, boolean>;
1475
- isLoading: boolean;
1476
- error: Error | null;
1477
- updateAttributes: (updates: Record<string, string | number | boolean>) => Promise<IUser>;
1478
- updateAttribute: (attributeKey: string, value: string | number | boolean) => Promise<IUser>;
1479
- refreshAttributes: () => Promise<void>;
1480
- refreshFeatures: () => Promise<void>;
1481
- }
1482
-
1483
- /**
1484
- * Base API client for SDK endpoints.
1485
- * All domain API classes (WorkspaceApi, UserApi, etc.) extend this to share
1486
- * URL building, auth headers, and request/response handling.
1487
- */
1488
-
1489
- interface IBaseApiConfig {
1490
- serverUrl: string;
1491
- version: ApiVersion;
1492
- orgId?: string;
1493
- /** When true, ensureReady() also requires orgId. Used by WorkspaceApi and SettingsApi. */
1494
- requireOrgId?: boolean;
1495
- /** API path segment after version (default 'public'). e.g. 'public' => .../v1/public, 'beta' => .../v1/beta */
1496
- basePath?: string;
1497
- }
1498
- /**
1499
- * Base class for SDK API clients.
1500
- * Provides:
1501
- * - baseUrl: `${serverUrl}/api/${version}/public`
1502
- * - getAuthHeaders()
1503
- * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
1504
- * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
1505
- */
1506
- declare abstract class BaseApi {
1507
- protected readonly serverUrl: string;
1508
- protected readonly version: ApiVersion;
1509
- protected readonly orgId: string | undefined;
1510
- private readonly requireOrgId;
1511
- private readonly basePath;
1512
- constructor(config: IBaseApiConfig);
1513
- /** Throws if config is not ready for API calls. Called automatically by fetchJson/fetchResponse. */
1514
- protected ensureReady(): void;
1515
- /** Base URL: ${serverUrl}/api/${version}/${basePath} */
1516
- protected get baseUrl(): string;
1517
- /** Auth headers (x-session-id). Subclasses can override to add more. */
1518
- protected getAuthHeaders(): Record<string, string>;
1519
- /** Build full URL from path (path can be "workspaces" or "/workspaces"). */
1520
- protected url(path: string): string;
1521
- /**
1522
- * Execute request and parse JSON with handleApiResponse (throws on !response.ok).
1523
- * Use for standard JSON APIs.
1524
- */
1525
- protected fetchJson<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
1526
- /**
1527
- * Execute request and return raw Response (for custom parsing or error handling).
1528
- * Caller is responsible for checking response.ok and parsing body.
1529
- */
1530
- protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
1531
- }
1532
905
 
1533
- /**
1534
- * Centralized API client for user attributes and features.
1535
- * Extends BaseApi for shared URL/auth/request handling.
1536
- */
1537
906
  declare class UserApi extends BaseApi {
1538
- constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'>);
907
+ constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'> & {
908
+ sessionId?: string;
909
+ });
1539
910
  getAttributes(signal?: AbortSignal): Promise<Record<string, string | number | boolean>>;
1540
911
  updateAttributes(updates: Record<string, string | number | boolean>): Promise<IUser>;
1541
912
  updateAttribute(attributeKey: string, value: string | number | boolean): Promise<IUser>;
1542
913
  getFeatures(signal?: AbortSignal): Promise<Record<string, boolean>>;
1543
914
  }
1544
915
 
1545
- /**
1546
- * Hook to access user attributes from the UserProvider.
1547
- * Must be used within a UserProvider component.
1548
- *
1549
- * @returns User context object containing:
1550
- * - `attributes`: Record of user attribute key-value pairs
1551
- * - `isLoading`: Boolean indicating if attributes are being loaded
1552
- * - `error`: Error message string (null if no error)
1553
- * - `refreshAttributes()`: Function to manually refresh attributes
1554
- *
1555
- * @throws {Error} If used outside of UserProvider
1556
- *
1557
- * @example
1558
- * ```tsx
1559
- * function UserProfile() {
1560
- * const { attributes, isLoading } = useUserAttributes();
1561
- *
1562
- * if (isLoading) return <Loading />;
1563
- *
1564
- * return (
1565
- * <div>
1566
- * <p>Plan: {attributes?.plan}</p>
1567
- * <p>Company: {attributes?.company}</p>
1568
- * </div>
1569
- * );
1570
- * }
1571
- * ```
1572
- */
1573
- declare function useUserAttributes(): UserContextValue;
1574
- /**
1575
- * Hook to access user feature flags from the UserProvider.
1576
- * Must be used within a UserProvider component.
1577
- *
1578
- * @returns An object containing:
1579
- * - `features`: Record of feature flag key-value pairs (boolean values)
1580
- * - `isLoading`: Boolean indicating if features are being loaded
1581
- * - `error`: Error message string (null if no error)
1582
- * - `refreshFeatures()`: Function to manually refresh features
1583
- * - `isFeatureEnabled(featureId)`: Function to check if a specific feature is enabled
1584
- *
1585
- * @throws {Error} If used outside of UserProvider
1586
- *
1587
- * @example
1588
- * ```tsx
1589
- * function FeatureContent() {
1590
- * const { isFeatureEnabled, isLoading } = useUserFeatures();
1591
- *
1592
- * if (isLoading) return <Loading />;
1593
- *
1594
- * if (isFeatureEnabled('premium-feature')) {
1595
- * return <PremiumFeature />;
1596
- * }
1597
- *
1598
- * return <BasicFeature />;
1599
- * }
1600
- * ```
1601
- *
1602
- * @example
1603
- * ```tsx
1604
- * // Check multiple features
1605
- * function Dashboard() {
1606
- * const { isFeatureEnabled } = useUserFeatures();
1607
- *
1608
- * return (
1609
- * <div>
1610
- * {isFeatureEnabled('analytics') && <Analytics />}
1611
- * {isFeatureEnabled('reports') && <Reports />}
1612
- * </div>
1613
- * );
1614
- * }
1615
- * ```
1616
- */
1617
- declare function useUserFeatures(): {
1618
- features: Record<string, boolean>;
1619
- isLoading: boolean;
1620
- error: Error | null;
1621
- refreshFeatures: () => Promise<void>;
1622
- isFeatureEnabled: (featureId: string) => boolean;
1623
- };
1624
-
1625
916
  declare class WorkspaceApi extends BaseApi {
1626
- constructor(config: IOsConfig);
917
+ constructor(config: IOsConfig & {
918
+ sessionId?: string;
919
+ });
1627
920
  getWorkspaces(): Promise<IWorkspace[]>;
1628
921
  createWorkspace(data: {
1629
922
  name: string;
@@ -1781,843 +1074,165 @@ declare class WorkspaceApi extends BaseApi {
1781
1074
  getUsageLogs(workspaceId: string, query?: IUsageLogsQuery): Promise<IUsageLogsResponse>;
1782
1075
  }
1783
1076
 
1784
- declare const useSaaSWorkspaces: () => {
1785
- workspaces: IWorkspace[];
1786
- loading: boolean;
1787
- error: string | null;
1788
- fetchWorkspaces: () => Promise<void>;
1789
- refreshWorkspaces: () => Promise<void>;
1790
- refreshing: boolean;
1791
- currentWorkspace: IWorkspace | null;
1792
- setCurrentWorkspace: (ws: IWorkspace, options?: {
1793
- forceEmit?: boolean;
1794
- }) => void;
1795
- switchToWorkspace: (ws: IWorkspace, options?: {
1796
- forceEmit?: boolean;
1797
- }) => Promise<void>;
1798
- resetCurrentWorkspace: () => void;
1799
- createWorkspace: (name: string, image?: string) => Promise<void>;
1800
- allFeatures: IWorkspaceFeature[];
1801
- getFeatures: () => Promise<IWorkspaceFeature[] | null>;
1802
- updateFeature: (workspaceId: string, key: string, value: boolean) => Promise<IWorkspace>;
1803
- getWorkspace: (workspaceId: string) => Promise<IWorkspace>;
1804
- updateWorkspace: (ws: IWorkspace, _data: Partial<IWorkspace>) => Promise<void>;
1805
- getUsers: (workspaceId: string) => Promise<IWorkspaceUser[]>;
1806
- addUser: (workspaceId: string, email: string, role: string) => Promise<{
1807
- userId: string;
1808
- workspace: IWorkspace;
1809
- message: string;
1810
- }>;
1811
- removeUser: (workspaceId: string, userId: string) => Promise<{
1812
- userId: string;
1813
- workspace: IWorkspace;
1814
- message: string;
1815
- }>;
1816
- updateUser: (workspaceId: string, userId: string, config: Partial<IWorkspaceUser>) => Promise<{
1817
- userId: string;
1818
- workspace: IWorkspace;
1819
- message: string;
1820
- }>;
1821
- getProfile: () => Promise<IUser>;
1822
- updateUserProfile: (config: Partial<IUser>) => Promise<IUser>;
1823
- deleteWorkspace: (workspaceId: string) => Promise<{
1824
- success: boolean;
1825
- }>;
1826
- switching: boolean;
1827
- switchingToId: string | null;
1828
- };
1829
-
1830
- declare function WorkspaceSwitcher(props: {
1831
- trigger: (isLoading: boolean, currentWorkspace: IWorkspace | null) => ReactNode;
1832
- }): react_jsx_runtime.JSX.Element;
1833
-
1834
- /**
1835
- * Hook to get public plans by slug (no auth required).
1836
- * Returns items (features, limits, quotas) and plans (with pricing).
1837
- * Uses orgId from SaaSOSProvider - must be inside provider.
1838
- *
1839
- * @param slug - Plan group slug (e.g. 'main-pricing', 'enterprise')
1840
- * @returns { items, plans, loading, error, refetch }
1841
- */
1842
- declare const usePublicPlans: (slug: string) => {
1843
- items: IPublicPlanItem[];
1844
- plans: IPublicPlanVersion[];
1845
- notes: string | undefined;
1846
- loading: boolean;
1847
- error: string | null;
1848
- refetch: () => Promise<void>;
1849
- };
1850
- /**
1851
- * Hook to get a single plan group version by ID (no auth required).
1852
- * Use this for public pricing pages when you have the groupVersionId (e.g. from config or URL).
1853
- *
1854
- * @param groupVersionId - The plan group version ID to fetch. Pass null/undefined to disable fetching.
1855
- * @returns An object containing:
1856
- * - `planGroupVersion`: Plan group version data (null if not loaded)
1857
- * - `loading`: Boolean indicating if data is being fetched
1858
- * - `error`: Error message string (null if no error)
1859
- * - `refetch()`: Function to manually refetch
1860
- *
1861
- * @example
1862
- * ```tsx
1863
- * function PublicPricingPage() {
1864
- * const groupVersionId = 'your-plan-group-version-id'; // from config or URL
1865
- * const { planGroupVersion, loading } = usePublicPlanGroupVersion(groupVersionId);
1866
- *
1867
- * if (loading) return <Loading />;
1868
- * if (!planGroupVersion) return null;
1869
- *
1870
- * const plans = Array.isArray(planGroupVersion.planVersionIds)
1871
- * ? planGroupVersion.planVersionIds.filter((p): p is IPlanVersionWithPlan => typeof p !== 'string')
1872
- * : [];
1873
- *
1874
- * return (
1875
- * <div>
1876
- * {plans.map(plan => <PlanCard key={plan._id} plan={plan} />)}
1877
- * </div>
1878
- * );
1879
- * }
1880
- * ```
1881
- */
1882
- declare const usePublicPlanGroupVersion: (groupVersionId: string | null | undefined) => {
1883
- planGroupVersion: IPlanGroupVersion | null;
1884
- loading: boolean;
1885
- error: string | null;
1886
- refetch: () => Promise<void>;
1887
- };
1888
- /**
1889
- * Hook to get and manage the current subscription for a workspace.
1890
- * Automatically fetches subscription when workspaceId changes.
1891
- *
1892
- * @param workspaceId - The workspace ID to get subscription for. Can be null/undefined to disable fetching.
1893
- * @returns An object containing:
1894
- * - `subscription`: Current subscription data (null if no subscription or not loaded)
1895
- * - `loading`: Boolean indicating if subscription is being fetched
1896
- * - `error`: Error message string (null if no error)
1897
- * - `refetch()`: Function to manually refetch the subscription
1898
- *
1899
- * @example
1900
- * ```tsx
1901
- * function SubscriptionStatus() {
1902
- * const { currentWorkspace } = useSaaSWorkspaces();
1903
- * const { subscription, loading, error } = useSubscription(currentWorkspace?._id);
1904
- *
1905
- * if (loading) return <Loading />;
1906
- * if (error) return <Error message={error} />;
1907
- * if (!subscription) return <p>No active subscription</p>;
1908
- *
1909
- * return <p>Plan: {subscription.plan.name}</p>;
1910
- * }
1911
- * ```
1912
- *
1913
- * @example
1914
- * ```tsx
1915
- * // Edge case: Workspace ID changes
1916
- * function SubscriptionComponent({ workspaceId }) {
1917
- * const { subscription, refetch } = useSubscription(workspaceId);
1918
- *
1919
- * // Subscription automatically refetches when workspaceId changes
1920
- * // Use refetch() to manually refresh after mutations
1921
- * return <SubscriptionDetails subscription={subscription} />;
1922
- * }
1923
- * ```
1924
- */
1925
- declare const useSubscription: (workspaceId: string | null | undefined) => {
1926
- subscription: ISubscriptionResponse | null;
1927
- loading: boolean;
1928
- error: string | null;
1929
- refetch: () => Promise<void>;
1930
- };
1931
- /**
1932
- * Hook to get the plan group for a workspace.
1933
- * Returns the plan group containing the current plan if subscription exists,
1934
- * otherwise returns the latest published group.
1935
- * Automatically fetches when workspaceId or groupVersionId changes.
1936
- *
1937
- * @param workspaceId - The workspace ID to get plan group for. Can be null/undefined to disable fetching.
1938
- * @param groupVersionId - Optional: specific group version ID to fetch (for viewing historical versions)
1939
- * @returns An object containing:
1940
- * - `planGroup`: Plan group data (null if not loaded)
1941
- * - `loading`: Boolean indicating if plan group is being fetched
1942
- * - `error`: Error message string (null if no error)
1943
- * - `refetch()`: Function to manually refetch the plan group
1944
- *
1945
- * @example
1946
- * ```tsx
1947
- * function PlanGroupDisplay() {
1948
- * const { currentWorkspace } = useSaaSWorkspaces();
1949
- * const { planGroup, loading } = usePlanGroup(currentWorkspace?._id);
1950
- *
1951
- * if (loading) return <Loading />;
1952
- * if (!planGroup) return <p>No plan group available</p>;
1953
- *
1954
- * return (
1955
- * <div>
1956
- * <h3>{planGroup.group.name}</h3>
1957
- * {planGroup.plans.map(plan => (
1958
- * <PlanCard key={plan._id} plan={plan} />
1959
- * ))}
1960
- * </div>
1961
- * );
1962
- * }
1963
- * ```
1964
- *
1965
- * @example
1966
- * ```tsx
1967
- * // Fetch specific version for comparison
1968
- * function PlanVersionComparison() {
1969
- * const { currentWorkspace } = useSaaSWorkspaces();
1970
- * const current = usePlanGroup(currentWorkspace?._id);
1971
- * const previous = usePlanGroup(currentWorkspace?._id, 'previous-version-id');
1972
- *
1973
- * return <ComparePlans current={current.planGroup} previous={previous.planGroup} />;
1974
- * }
1975
- * ```
1976
- */
1977
- declare const usePlanGroup: (workspaceId: string | null | undefined, groupVersionId?: string | null) => {
1978
- planGroup: IPlanGroupResponse | null;
1979
- loading: boolean;
1980
- error: string | null;
1981
- refetch: () => Promise<void>;
1982
- };
1983
- /**
1984
- * Hook to get all available versions of a plan group for a workspace.
1985
- * Shows current version and available newer versions for upgrade paths.
1986
- * Automatically fetches when workspaceId changes.
1987
- *
1988
- * @param workspaceId - The workspace ID to get plan group versions for. Can be null/undefined to disable fetching.
1989
- * @returns An object containing:
1990
- * - `versions`: Plan group versions response with currentVersion and availableVersions
1991
- * - `loading`: Boolean indicating if versions are being fetched
1992
- * - `error`: Error message string (null if no error)
1993
- * - `refetch()`: Function to manually refetch the versions
1994
- *
1995
- * @example
1996
- * ```tsx
1997
- * function UpgradeOptions() {
1998
- * const { currentWorkspace } = useSaaSWorkspaces();
1999
- * const { versions, loading } = usePlanGroupVersions(currentWorkspace?._id);
2000
- *
2001
- * if (loading) return <Loading />;
2002
- *
2003
- * return (
2004
- * <div>
2005
- * <p>Current: {versions?.currentVersion.name}</p>
2006
- * <h4>Available Upgrades:</h4>
2007
- * {versions?.availableVersions.map(version => (
2008
- * <UpgradeCard key={version._id} version={version} />
2009
- * ))}
2010
- * </div>
2011
- * );
2012
- * }
2013
- * ```
2014
- */
2015
- declare const usePlanGroupVersions: (workspaceId: string | null | undefined) => {
2016
- versions: IPlanGroupVersionsResponse | null;
2017
- loading: boolean;
2018
- error: string | null;
2019
- refetch: () => Promise<void>;
2020
- };
2021
1077
  /**
2022
- * Hook to create a checkout session for a new subscription.
2023
- * Returns a function to initiate the checkout process.
2024
- *
2025
- * @param workspaceId - The workspace ID to create checkout session for. Can be null/undefined.
2026
- * @returns An object containing:
2027
- * - `createCheckoutSession(request)`: Function to create checkout session (throws if workspaceId is null)
2028
- * - `loading`: Boolean indicating if checkout session is being created
2029
- * - `error`: Error message string (null if no error)
2030
- *
2031
- * @example
2032
- * ```tsx
2033
- * function SubscribeButton({ planVersionId }) {
2034
- * const { currentWorkspace } = useSaaSWorkspaces();
2035
- * const { createCheckoutSession, loading } = useCreateCheckoutSession(currentWorkspace?._id);
2036
- *
2037
- * const handleSubscribe = async () => {
2038
- * try {
2039
- * const result = await createCheckoutSession({
2040
- * planVersionId,
2041
- * successUrl: window.location.href,
2042
- * cancelUrl: window.location.href,
2043
- * });
2044
- * // Redirect to checkout
2045
- * window.location.href = result.checkoutUrl;
2046
- * } catch (error) {
2047
- * console.error('Failed to create checkout:', error);
2048
- * }
2049
- * };
2050
- *
2051
- * return (
2052
- * <button onClick={handleSubscribe} disabled={loading}>
2053
- * {loading ? 'Loading...' : 'Subscribe'}
2054
- * </button>
2055
- * );
2056
- * }
2057
- * ```
2058
- *
2059
- * @example
2060
- * ```tsx
2061
- * // Edge case: Workspace ID not available
2062
- * function SubscribeButton() {
2063
- * const { currentWorkspace } = useSaaSWorkspaces();
2064
- * const { createCheckoutSession } = useCreateCheckoutSession(currentWorkspace?._id);
2065
- *
2066
- * const handleSubscribe = async () => {
2067
- * try {
2068
- * await createCheckoutSession({ planVersionId: 'plan-123' });
2069
- * } catch (error) {
2070
- * // Error: "Workspace ID is required"
2071
- * alert('Please select a workspace first');
2072
- * }
2073
- * };
2074
- *
2075
- * return <button onClick={handleSubscribe}>Subscribe</button>;
2076
- * }
2077
- * ```
1078
+ * EventEmitter class to handle and trigger event callbacks
1079
+ * This class manages all event listeners and provides methods to trigger events
2078
1080
  */
2079
- declare const useCreateCheckoutSession: (workspaceId: string | null | undefined) => {
2080
- createCheckoutSession: (request: ICheckoutSessionRequest) => Promise<CheckoutResult>;
2081
- loading: boolean;
2082
- error: string | null;
2083
- };
2084
- /**
2085
- * Hook to update subscription (upgrade/downgrade).
2086
- * Returns checkout session if payment is required, otherwise returns subscription update response.
2087
- *
2088
- * @param workspaceId - The workspace ID to update subscription for. Can be null/undefined.
2089
- * @returns An object containing:
2090
- * - `updateSubscription(planVersionId, options?)`: Function to update subscription (throws if workspaceId is null)
2091
- * - `loading`: Boolean indicating if subscription is being updated
2092
- * - `error`: Error message string (null if no error)
2093
- *
2094
- * @example
2095
- * ```tsx
2096
- * function UpgradeButton({ planVersionId }) {
2097
- * const { currentWorkspace } = useSaaSWorkspaces();
2098
- * const { updateSubscription, loading } = useUpdateSubscription(currentWorkspace?._id);
2099
- *
2100
- * const handleUpgrade = async () => {
2101
- * try {
2102
- * const result = await updateSubscription(planVersionId, {
2103
- * billingInterval: 'monthly',
2104
- * successUrl: window.location.href,
2105
- * cancelUrl: window.location.href,
2106
- * });
2107
- *
2108
- * // Check if payment is required
2109
- * if ('checkoutUrl' in result) {
2110
- * window.location.href = result.checkoutUrl;
2111
- * } else {
2112
- * // Subscription updated without payment
2113
- * alert('Subscription updated successfully!');
2114
- * }
2115
- * } catch (error) {
2116
- * console.error('Failed to update subscription:', error);
2117
- * }
2118
- * };
2119
- *
2120
- * return (
2121
- * <button onClick={handleUpgrade} disabled={loading}>
2122
- * {loading ? 'Upgrading...' : 'Upgrade'}
2123
- * </button>
2124
- * );
2125
- * }
2126
- * ```
2127
- *
2128
- * @example
2129
- * ```tsx
2130
- * // Handle both checkout and direct update responses
2131
- * function SubscriptionUpdater({ planVersionId }) {
2132
- * const { updateSubscription } = useUpdateSubscription(workspaceId);
2133
- *
2134
- * const handleUpdate = async () => {
2135
- * const result = await updateSubscription(planVersionId);
2136
- *
2137
- * // Type guard to check response type
2138
- * if ('checkoutUrl' in result) {
2139
- * // Redirect to payment
2140
- * window.location.href = result.checkoutUrl;
2141
- * } else {
2142
- * // Direct update successful
2143
- * console.log('Updated subscription:', result.subscription);
2144
- * }
2145
- * };
2146
- *
2147
- * return <button onClick={handleUpdate}>Update</button>;
2148
- * }
2149
- * ```
2150
- */
2151
- declare const useUpdateSubscription: (workspaceId: string | null | undefined) => {
2152
- updateSubscription: (planVersionId: string, options?: {
2153
- billingInterval?: BillingInterval;
2154
- successUrl?: string;
2155
- cancelUrl?: string;
2156
- }) => Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
2157
- loading: boolean;
2158
- error: string | null;
2159
- };
2160
- /**
2161
- * Combined hook that provides both subscription and plan group data.
2162
- * Useful for subscription management pages that need both pieces of data.
2163
- * Combines useSubscription, usePlanGroup, and useUpdateSubscription.
2164
- *
2165
- * @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
2166
- * @param groupVersionId - Optional: specific group version ID to fetch
2167
- * @returns An object containing:
2168
- * - `subscription`: Current subscription data (from useSubscription)
2169
- * - `planGroup`: Plan group data (from usePlanGroup)
2170
- * - `loading`: Boolean indicating if any operation is in progress
2171
- * - `error`: Error message string (null if no error)
2172
- * - `updateSubscription(planVersionId, options?)`: Function to update subscription
2173
- * - `refetch()`: Function to refetch both subscription and plan group
2174
- *
2175
- * @example
2176
- * ```tsx
2177
- * function SubscriptionManagementPage() {
2178
- * const { currentWorkspace } = useSaaSWorkspaces();
2179
- * const {
2180
- * subscription,
2181
- * planGroup,
2182
- * loading,
2183
- * updateSubscription,
2184
- * refetch,
2185
- * } = useSubscriptionManagement(currentWorkspace?._id);
2186
- *
2187
- * if (loading) return <Loading />;
2188
- *
2189
- * return (
2190
- * <div>
2191
- * <CurrentPlan subscription={subscription} />
2192
- * <AvailablePlans planGroup={planGroup} onSelect={updateSubscription} />
2193
- * <button onClick={refetch}>Refresh</button>
2194
- * </div>
2195
- * );
2196
- * }
2197
- * ```
2198
- */
2199
- declare const useSubscriptionManagement: (workspaceId: string | null | undefined, groupVersionId?: string | null) => {
2200
- subscription: ISubscriptionResponse | null;
2201
- planGroup: IPlanGroupResponse | null;
2202
- loading: boolean;
2203
- error: string | null;
2204
- updateSubscription: (planVersionId: string, options?: {
2205
- billingInterval?: BillingInterval;
2206
- successUrl?: string;
2207
- cancelUrl?: string;
2208
- }) => Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
2209
- refetch: () => Promise<void>;
2210
- };
2211
- /**
2212
- * Hook to list invoices for a workspace subscription with pagination support.
2213
- * Automatically fetches when workspaceId, limit, or startingAfter changes.
2214
- *
2215
- * @param workspaceId - The workspace ID to get invoices for. Can be null/undefined to disable fetching.
2216
- * @param limit - Number of invoices to return (default: 10)
2217
- * @param startingAfter - Invoice ID to start after (for pagination)
2218
- * @returns An object containing:
2219
- * - `invoices`: Array of invoice objects
2220
- * - `hasMore`: Boolean indicating if there are more invoices to load
2221
- * - `loading`: Boolean indicating if invoices are being fetched
2222
- * - `error`: Error message string (null if no error)
2223
- * - `refetch()`: Function to manually refetch invoices
2224
- *
2225
- * @example
2226
- * ```tsx
2227
- * function InvoiceList() {
2228
- * const { currentWorkspace } = useSaaSWorkspaces();
2229
- * const { invoices, hasMore, loading, refetch } = useInvoices(currentWorkspace?._id, 10);
2230
- *
2231
- * if (loading) return <Loading />;
2232
- *
2233
- * return (
2234
- * <div>
2235
- * {invoices.map(invoice => (
2236
- * <InvoiceCard key={invoice._id} invoice={invoice} />
2237
- * ))}
2238
- * {hasMore && <button onClick={() => refetch()}>Load More</button>}
2239
- * </div>
2240
- * );
2241
- * }
2242
- * ```
2243
- *
2244
- * @example
2245
- * ```tsx
2246
- * // Pagination example
2247
- * function PaginatedInvoices() {
2248
- * const [lastInvoiceId, setLastInvoiceId] = useState<string | undefined>();
2249
- * const { currentWorkspace } = useSaaSWorkspaces();
2250
- * const { invoices, hasMore, refetch } = useInvoices(
2251
- * currentWorkspace?._id,
2252
- * 10,
2253
- * lastInvoiceId
2254
- * );
2255
- *
2256
- * const loadMore = () => {
2257
- * if (invoices.length > 0) {
2258
- * setLastInvoiceId(invoices[invoices.length - 1]._id);
2259
- * }
2260
- * };
2261
- *
2262
- * return (
2263
- * <div>
2264
- * {invoices.map(invoice => <InvoiceCard key={invoice._id} invoice={invoice} />)}
2265
- * {hasMore && <button onClick={loadMore}>Load More</button>}
2266
- * </div>
2267
- * );
2268
- * }
2269
- * ```
2270
- */
2271
- declare const useInvoices: (workspaceId: string | null | undefined, limit?: number, startingAfter?: string) => {
2272
- invoices: IInvoice[];
2273
- hasMore: boolean;
2274
- loading: boolean;
2275
- error: string | null;
2276
- refetch: () => Promise<void>;
2277
- };
1081
+ declare class EventEmitter {
1082
+ private callbacks;
1083
+ /**
1084
+ * Set the event callbacks
1085
+ * @param callbacks - The event callbacks to register
1086
+ */
1087
+ setCallbacks(callbacks: IEventCallbacks | null): void;
1088
+ /**
1089
+ * Get the current event callbacks
1090
+ * @returns The current event callbacks or null
1091
+ */
1092
+ getCallbacks(): IEventCallbacks | null;
1093
+ /**
1094
+ * Emit an event
1095
+ * @param eventType - The type of event
1096
+ * @param data - The event data
1097
+ */
1098
+ private emit;
1099
+ /**
1100
+ * Trigger user created event
1101
+ * @param user - The newly created user
1102
+ */
1103
+ emitUserCreated(user: IUser): Promise<void>;
1104
+ /**
1105
+ * Trigger user updated event
1106
+ * @param user - The updated user
1107
+ * @param previousUser - The user data before the update (optional)
1108
+ */
1109
+ emitUserUpdated(user: IUser, previousUser?: IUser): Promise<void>;
1110
+ /**
1111
+ * Trigger workspace changed event
1112
+ * @param workspace - The newly selected workspace
1113
+ * @param previousWorkspace - The previously selected workspace (optional)
1114
+ */
1115
+ emitWorkspaceChanged(workspace: IWorkspace, previousWorkspace?: IWorkspace | null): Promise<void>;
1116
+ /**
1117
+ * Trigger workspace updated event
1118
+ * @param workspace - The updated workspace
1119
+ */
1120
+ emitWorkspaceUpdated(workspace: IWorkspace): Promise<void>;
1121
+ /**
1122
+ * Trigger workspace user added event
1123
+ * @param userId - The ID of the user that was added
1124
+ * @param workspace - The workspace the user was added to
1125
+ * @param role - The role assigned to the user
1126
+ */
1127
+ emitWorkspaceUserAdded(userId: string, workspace: IWorkspace, role: string): Promise<void>;
1128
+ /**
1129
+ * Trigger workspace user removed event
1130
+ * @param userId - The ID of the user that was removed
1131
+ * @param workspace - The workspace the user was removed from
1132
+ * @param role - The role the user had in the workspace
1133
+ */
1134
+ emitWorkspaceUserRemoved(userId: string, workspace: IWorkspace, role: string): Promise<void>;
1135
+ /**
1136
+ * Trigger workspace user role changed event
1137
+ * @param userId - The ID of the user whose role was changed
1138
+ * @param workspace - The workspace where the role was changed
1139
+ * @param previousRole - The previous role of the user
1140
+ * @param newRole - The new role of the user
1141
+ */
1142
+ emitWorkspaceUserRoleChanged(userId: string, workspace: IWorkspace, previousRole: string, newRole: string): Promise<void>;
1143
+ /**
1144
+ * Trigger workspace created event
1145
+ * @param workspace - The newly created workspace
1146
+ */
1147
+ emitWorkspaceCreated(workspace: IWorkspace): Promise<void>;
1148
+ /**
1149
+ * Trigger workspace deleted event
1150
+ * @param workspace - The deleted workspace
1151
+ */
1152
+ emitWorkspaceDeleted(workspace: IWorkspace): Promise<void>;
1153
+ }
1154
+ declare const eventEmitter: EventEmitter;
1155
+
2278
1156
  /**
2279
- * Hook to open the Stripe Customer Portal for managing payment methods, invoices, and subscription.
2280
- *
2281
- * @example
2282
- * ```tsx
2283
- * const { openBillingPortal, loading } = useBillingPortal(workspaceId);
2284
- * <Button onClick={() => openBillingPortal()} disabled={loading}>
2285
- * Manage Payment Method
2286
- * </Button>
2287
- * ```
1157
+ * Notify all subscribers to refetch subscription (e.g. after update/cancel/resume).
1158
+ * Called internally by useUpdateSubscription, useCancelSubscription, useResumeSubscription on success.
2288
1159
  */
2289
- declare const useBillingPortal: (workspaceId: string | null | undefined) => {
2290
- openBillingPortal: (returnUrl?: string) => Promise<{
2291
- url: string;
2292
- }>;
2293
- loading: boolean;
2294
- error: string | null;
2295
- };
1160
+ declare function invalidateSubscription(): void;
1161
+
2296
1162
  /**
2297
- * Hook to get a single invoice by ID.
2298
- * Automatically fetches when workspaceId or invoiceId changes.
2299
- *
2300
- * @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
2301
- * @param invoiceId - The invoice ID to fetch. Can be null/undefined to disable fetching.
2302
- * @returns An object containing:
2303
- * - `invoice`: Invoice data object (null if not loaded)
2304
- * - `loading`: Boolean indicating if invoice is being fetched
2305
- * - `error`: Error message string (null if no error)
2306
- * - `refetch()`: Function to manually refetch the invoice
2307
- *
2308
- * @example
2309
- * ```tsx
2310
- * function InvoiceDetails({ invoiceId }) {
2311
- * const { currentWorkspace } = useSaaSWorkspaces();
2312
- * const { invoice, loading, error } = useInvoice(currentWorkspace?._id, invoiceId);
2313
- *
2314
- * if (loading) return <Loading />;
2315
- * if (error) return <Error message={error} />;
2316
- * if (!invoice) return <p>Invoice not found</p>;
2317
- *
2318
- * return (
2319
- * <div>
2320
- * <h2>Invoice #{invoice.invoiceNumber}</h2>
2321
- * <p>Amount: ${invoice.amount}</p>
2322
- * <p>Status: {invoice.status}</p>
2323
- * </div>
2324
- * );
2325
- * }
2326
- * ```
1163
+ * Notify all subscribers to refetch quota usage (e.g. after recording usage).
1164
+ * Called internally by useRecordUsage on success.
2327
1165
  */
2328
- declare const useInvoice: (workspaceId: string | null | undefined, invoiceId: string | null | undefined) => {
2329
- invoice: IInvoice | null;
2330
- loading: boolean;
2331
- error: string | null;
2332
- refetch: () => Promise<void>;
2333
- };
1166
+ declare function invalidateQuotaUsage(): void;
1167
+
2334
1168
  /**
2335
- * Hook to cancel a subscription at the end of the current billing period.
2336
- * Sets cancelAtPeriodEnd: true - subscription remains active until period ends.
2337
- *
2338
- * @param workspaceId - The workspace ID. Can be null/undefined.
2339
- * @returns An object containing:
2340
- * - `cancelSubscription()`: Function to cancel subscription at period end
2341
- * - `loading`: Boolean indicating if cancellation is in progress
2342
- * - `error`: Error message string (null if no error)
2343
- *
2344
- * @example
2345
- * ```tsx
2346
- * function CancelSubscriptionButton() {
2347
- * const { currentWorkspace } = useSaaSWorkspaces();
2348
- * const { cancelSubscription, loading } = useCancelSubscription(currentWorkspace?._id);
2349
- * const { refetch } = useSubscription(currentWorkspace?._id);
2350
- *
2351
- * const handleCancel = async () => {
2352
- * try {
2353
- * await cancelSubscription();
2354
- * await refetch(); // Refresh subscription data
2355
- * alert('Subscription will be canceled at the end of the billing period');
2356
- * } catch (error) {
2357
- * console.error('Failed to cancel:', error);
2358
- * }
2359
- * };
2360
- *
2361
- * return (
2362
- * <button onClick={handleCancel} disabled={loading}>
2363
- * {loading ? 'Canceling...' : 'Cancel Subscription'}
2364
- * </button>
2365
- * );
2366
- * }
2367
- * ```
1169
+ * Centralized formatting for subscription/quota display: cents, overage rates, included + overage text.
1170
+ * Currency must be provided by the caller (e.g. workspace.billingCurrency, plan.currency, or selected currency).
2368
1171
  */
2369
- declare const useCancelSubscription: (workspaceId: string | null | undefined) => {
2370
- cancelSubscription: () => Promise<ISubscriptionResponse>;
2371
- loading: boolean;
2372
- error: string | null;
2373
- };
1172
+ /** Common currency display (code or symbol). Use lowercase Stripe codes (usd, eur, etc.). */
1173
+ declare const CURRENCY_DISPLAY: Record<string, string>;
1174
+ /** Currency code to flag emoji (country/region associated with the currency). Use for dropdowns. */
1175
+ declare const CURRENCY_FLAG: Record<string, string>;
1176
+ /** Get flag emoji for a currency code. Returns empty string when unknown or empty. */
1177
+ declare function getCurrencyFlag(currency: string): string;
1178
+ /** Get currency symbol for display. Use lowercase Stripe codes (usd, eur). Returns code when unknown; empty string when currency is empty. */
1179
+ declare function getCurrencySymbol(currency: string): string;
1180
+ /** Allowed plan/pricing currency codes (must match server ALLOWED_BILLING_CURRENCIES). Use for dropdowns and validation. */
1181
+ 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"];
1182
+ /** Options for plan currency select: { value, label } with symbol. Use in CreateOrEditPlan and anywhere a currency dropdown is needed. */
1183
+ declare const PLAN_CURRENCY_OPTIONS: {
1184
+ value: "usd" | "eur" | "gbp" | "jpy" | "cad" | "aud" | "chf" | "cny" | "hkd" | "sgd" | "inr" | "mxn" | "brl" | "nzd" | "sek" | "nok" | "dkk" | "pln" | "thb";
1185
+ label: string;
1186
+ }[];
1187
+ /** Format cents as money string (e.g. 1999, "usd" -> "$19.99"). Caller must pass currency (e.g. from plan or workspace). */
1188
+ declare function formatCents(cents: number, currency: string): string;
2374
1189
  /**
2375
- * Hook to resume a subscription that was scheduled for cancellation.
2376
- * Sets cancelAtPeriodEnd: false - subscription will continue after period ends.
2377
- *
2378
- * @param workspaceId - The workspace ID. Can be null/undefined.
2379
- * @returns An object containing:
2380
- * - `resumeSubscription()`: Function to resume subscription
2381
- * - `loading`: Boolean indicating if resume is in progress
2382
- * - `error`: Error message string (null if no error)
2383
- *
2384
- * @example
2385
- * ```tsx
2386
- * function ResumeSubscriptionButton() {
2387
- * const { currentWorkspace } = useSaaSWorkspaces();
2388
- * const { resumeSubscription, loading } = useResumeSubscription(currentWorkspace?._id);
2389
- * const { refetch } = useSubscription(currentWorkspace?._id);
2390
- *
2391
- * const handleResume = async () => {
2392
- * try {
2393
- * await resumeSubscription();
2394
- * await refetch(); // Refresh subscription data
2395
- * alert('Subscription has been resumed');
2396
- * } catch (error) {
2397
- * console.error('Failed to resume:', error);
2398
- * }
2399
- * };
2400
- *
2401
- * return (
2402
- * <button onClick={handleResume} disabled={loading}>
2403
- * {loading ? 'Resuming...' : 'Resume Subscription'}
2404
- * </button>
2405
- * );
2406
- * }
2407
- * ```
1190
+ * Format overage rate for display. When unitSize > 1: "$1.00/1,000 units"; else "$1.00/unit".
1191
+ * Returns null if overageCents is missing or negative.
2408
1192
  */
2409
- declare const useResumeSubscription: (workspaceId: string | null | undefined) => {
2410
- resumeSubscription: () => Promise<ISubscriptionResponse>;
2411
- loading: boolean;
2412
- error: string | null;
2413
- };
1193
+ declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string): string | null;
2414
1194
  /**
2415
- * Hook to record quota usage for a workspace.
2416
- * Returns a function to record usage (mutation pattern).
2417
- *
2418
- * @param workspaceId - The workspace ID. Can be null/undefined.
2419
- * @returns An object containing:
2420
- * - `recordUsage(request)`: Function to record usage (throws if workspaceId is null)
2421
- * - `loading`: Boolean indicating if recording is in progress
2422
- * - `error`: Error message string (null if no error)
2423
- *
2424
- * @example
2425
- * ```tsx
2426
- * function RecordUsageButton() {
2427
- * const { currentWorkspace } = useSaaSWorkspaces();
2428
- * const { recordUsage, loading } = useRecordUsage(currentWorkspace?._id);
2429
- *
2430
- * const handleRecord = async () => {
2431
- * try {
2432
- * const result = await recordUsage({
2433
- * quotaSlug: 'api_calls',
2434
- * quantity: 1,
2435
- * source: 'web-app',
2436
- * });
2437
- * console.log(`Used: ${result.consumed}/${result.included}`);
2438
- * } catch (error) {
2439
- * console.error('Failed to record usage:', error);
2440
- * }
2441
- * };
2442
- *
2443
- * return (
2444
- * <button onClick={handleRecord} disabled={loading}>
2445
- * {loading ? 'Recording...' : 'Record Usage'}
2446
- * </button>
2447
- * );
2448
- * }
2449
- * ```
1195
+ * Format overage rate with optional unit label for comparison/preview UIs.
1196
+ * e.g. formatOverageRateWithLabel(50, 1000, "video") -> "$0.50/1,000 videos"
1197
+ * formatOverageRateWithLabel(46, 1, "video") -> "$0.46/video"
1198
+ * When unitLabel is omitted, falls back to formatOverageRate behavior.
2450
1199
  */
2451
- declare const useRecordUsage: (workspaceId: string | null | undefined) => {
2452
- recordUsage: (request: IRecordUsageRequest) => Promise<IRecordUsageResponse>;
2453
- loading: boolean;
2454
- error: string | null;
2455
- };
1200
+ declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string): string | null;
2456
1201
  /**
2457
- * Hook to get usage status for a single quota.
2458
- * Automatically fetches when workspaceId or quotaSlug changes.
2459
- *
2460
- * @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
2461
- * @param quotaSlug - The quota slug to check. Can be null/undefined to disable fetching.
2462
- * @returns An object containing:
2463
- * - `status`: Quota usage status (null if not loaded)
2464
- * - `loading`: Boolean indicating if status is being fetched
2465
- * - `error`: Error message string (null if no error)
2466
- * - `refetch()`: Function to manually refetch the status
2467
- *
2468
- * @example
2469
- * ```tsx
2470
- * function QuotaStatusDisplay() {
2471
- * const { currentWorkspace } = useSaaSWorkspaces();
2472
- * const { status, loading } = useQuotaUsageStatus(currentWorkspace?._id, 'api_calls');
2473
- *
2474
- * if (loading) return <Loading />;
2475
- * if (!status) return null;
2476
- *
2477
- * return (
2478
- * <div>
2479
- * <p>Used: {status.consumed} / {status.included}</p>
2480
- * <p>Available: {status.available}</p>
2481
- * {status.hasOverage && <p>Overage: {status.overage}</p>}
2482
- * </div>
2483
- * );
2484
- * }
2485
- * ```
1202
+ * Get singular unit label from item name or slug (e.g. "Videos" -> "video", "reels" -> "reel").
1203
+ * Used for quota display in comparison and preview.
2486
1204
  */
2487
- declare const useQuotaUsageStatus: (workspaceId: string | null | undefined, quotaSlug: string | null | undefined) => {
2488
- status: IQuotaUsageStatusResponse | null;
2489
- loading: boolean;
2490
- error: string | null;
2491
- refetch: () => Promise<void>;
2492
- };
1205
+ declare function getQuotaUnitLabelFromName(nameOrSlug: string): string;
2493
1206
  /**
2494
- * Hook to get usage status for all quotas in the workspace's current plan.
2495
- * Automatically fetches when workspaceId changes.
2496
- *
2497
- * @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
2498
- * @returns An object containing:
2499
- * - `quotas`: Record of quota usage statuses keyed by slug (null if not loaded)
2500
- * - `loading`: Boolean indicating if statuses are being fetched
2501
- * - `error`: Error message string (null if no error)
2502
- * - `refetch()`: Function to manually refetch all statuses
2503
- *
2504
- * @example
2505
- * ```tsx
2506
- * function AllQuotasDisplay() {
2507
- * const { currentWorkspace } = useSaaSWorkspaces();
2508
- * const { quotas, loading } = useAllQuotaUsage(currentWorkspace?._id);
2509
- *
2510
- * if (loading) return <Loading />;
2511
- * if (!quotas) return null;
2512
- *
2513
- * return (
2514
- * <div>
2515
- * {Object.entries(quotas).map(([slug, usage]) => (
2516
- * <div key={slug}>
2517
- * <p>{slug}: {usage.consumed}/{usage.included}</p>
2518
- * {usage.hasOverage && <p>Overage: {usage.overage}</p>}
2519
- * </div>
2520
- * ))}
2521
- * </div>
2522
- * );
2523
- * }
2524
- * ```
1207
+ * Format quota "included + overage" for display.
1208
+ * When unitSize >= 2: "Included: 1,000, after that $1.00/1,000 emails".
1209
+ * Otherwise: "Included: 5, after that $0.30/image".
2525
1210
  */
2526
- declare const useAllQuotaUsage: (workspaceId: string | null | undefined) => {
2527
- quotas: Record<string, IQuotaUsageStatus> | null;
2528
- loading: boolean;
2529
- error: string | null;
2530
- refetch: () => Promise<void>;
2531
- };
1211
+ declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number): string;
1212
+
1213
+ type QuotaDisplayValue = {
1214
+ included: number;
1215
+ overage?: number;
1216
+ unitSize?: number;
1217
+ } | null;
2532
1218
  /**
2533
- * Hook to get paginated usage logs for a workspace.
2534
- * Automatically fetches when workspaceId or filter params change.
2535
- *
2536
- * @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
2537
- * @param quotaSlug - Optional quota slug to filter logs by.
2538
- * @param options - Optional filters: from, to, source, page, limit
2539
- * @returns An object containing:
2540
- * - `logs`: Array of usage log entries
2541
- * - `totalDocs`: Total number of log entries matching the query
2542
- * - `totalPages`: Total number of pages
2543
- * - `page`: Current page number
2544
- * - `hasNextPage`: Whether there are more pages after the current one
2545
- * - `hasPrevPage`: Whether there are pages before the current one
2546
- * - `loading`: Boolean indicating if logs are being fetched
2547
- * - `error`: Error message string (null if no error)
2548
- * - `refetch()`: Function to manually refetch logs
2549
- *
2550
- * @example
2551
- * ```tsx
2552
- * function UsageLogsTable() {
2553
- * const { currentWorkspace } = useSaaSWorkspaces();
2554
- * const { logs, totalPages, page, hasNextPage, loading } = useUsageLogs(
2555
- * currentWorkspace?._id,
2556
- * 'api_calls',
2557
- * { limit: 20 }
2558
- * );
2559
- *
2560
- * if (loading) return <Loading />;
2561
- *
2562
- * return (
2563
- * <div>
2564
- * {logs.map(log => (
2565
- * <div key={log._id}>
2566
- * {log.quotaSlug}: {log.quantity} ({log.createdAt})
2567
- * </div>
2568
- * ))}
2569
- * <p>Page {page} of {totalPages}</p>
2570
- * </div>
2571
- * );
2572
- * }
2573
- * ```
1219
+ * Normalize a per-interval quota value to a display shape for the given billing interval.
2574
1220
  */
2575
- declare const useUsageLogs: (workspaceId: string | null | undefined, quotaSlug?: string, options?: {
2576
- from?: string;
2577
- to?: string;
2578
- source?: string;
2579
- page?: number;
2580
- limit?: number;
2581
- }) => {
2582
- logs: IUsageLogEntry[];
2583
- totalDocs: number;
2584
- totalPages: number;
2585
- page: number;
2586
- hasNextPage: boolean;
2587
- hasPrevPage: boolean;
2588
- loading: boolean;
2589
- error: string | null;
2590
- refetch: () => Promise<void>;
2591
- };
2592
-
2593
- interface TrialStatus {
2594
- /** Whether the current subscription is in trial. */
2595
- isTrialing: boolean;
2596
- /** Number of days remaining in the trial. 0 if not trialing or expired. */
2597
- daysRemaining: number;
2598
- /** Trial end date as a Date object. null if not trialing. */
2599
- trialEndsAt: Date | null;
2600
- /** Trial start date as a Date object. null if not trialing. */
2601
- trialStartedAt: Date | null;
2602
- /** Whether the trial is ending soon (<= 3 days remaining). */
2603
- isTrialEnding: boolean;
1221
+ declare function getQuotaDisplayValue(value: IQuotaByInterval | null | undefined, interval?: BillingInterval): QuotaDisplayValue;
1222
+ /** Options for formatting quota with price. */
1223
+ interface FormatQuotaWithPriceOptions {
1224
+ /** If true, overage is in cents (Stripe); format as dollars. Default true. */
1225
+ overageInCents?: boolean;
1226
+ /** Currency symbol override. When omitted, derived from `currency` (empty if no currency). */
1227
+ currencySymbol?: string;
1228
+ /** Stripe currency code (e.g. 'usd', 'inr'). Used to resolve symbol when currencySymbol is not set. */
1229
+ currency?: string;
2604
1230
  }
2605
1231
  /**
2606
- * Hook that computes trial status from the current subscription context.
2607
- * Must be used within SubscriptionContextProvider.
2608
- *
2609
- * @returns TrialStatus — computed trial information
2610
- *
2611
- * @example
2612
- * ```tsx
2613
- * const { isTrialing, daysRemaining, isTrialEnding } = useTrialStatus();
2614
- *
2615
- * if (isTrialEnding) {
2616
- * return <UpgradeBanner daysLeft={daysRemaining} />;
2617
- * }
2618
- * ```
1232
+ * Format a quota display value as "X included, then $Y.YY / unit" (e.g. "10 included, then $10.00 / video").
1233
+ * Assumes overage is the per-unit price (in cents when overageInCents is true).
2619
1234
  */
2620
- declare function useTrialStatus(): TrialStatus;
1235
+ declare function formatQuotaWithPrice(value: QuotaDisplayValue, unitName: string, options?: FormatQuotaWithPriceOptions): string;
2621
1236
 
2622
1237
  /**
2623
1238
  * Helpers for multi-currency plan version pricing (pricingVariants).
@@ -2729,100 +1344,6 @@ declare function validateInvite(opts: {
2729
1344
  requireSubscription?: boolean;
2730
1345
  }): InviteValidation;
2731
1346
 
2732
- interface SeatStatus {
2733
- /** Whether the current plan uses seat-based pricing. */
2734
- hasSeatPricing: boolean;
2735
- /** Total workspace members. */
2736
- memberCount: number;
2737
- /** Seats included in the base price (free). */
2738
- includedSeats: number;
2739
- /** Maximum users allowed (resolved from seat pricing, plan limits, or settings). 0 = unlimited. */
2740
- maxUsers: number;
2741
- /**
2742
- * Maximum seats allowed from seat pricing config. 0 = unlimited.
2743
- * @deprecated Use `maxUsers` for the unified limit.
2744
- */
2745
- maxSeats: number;
2746
- /** Where the max user limit comes from. */
2747
- limitSource: MaxUsersConfig['source'];
2748
- /** Seats beyond included that are being billed. */
2749
- billableSeats: number;
2750
- /** Remaining seats before hitting max. Infinity if unlimited. */
2751
- availableSeats: number;
2752
- /** Whether workspace is at max seat/user capacity. */
2753
- isAtMax: boolean;
2754
- /** Whether workspace is near max (>= 80% used). */
2755
- isNearMax: boolean;
2756
- /** Per-seat price in cents for the current billing interval. Null if not applicable. */
2757
- perSeatPriceCents: number | null;
2758
- /** Billing currency. */
2759
- currency: string;
2760
- /** Whether a new member can be invited. */
2761
- canInvite: boolean;
2762
- /** Reason the invite is blocked, or null if allowed. */
2763
- inviteBlockReason: InviteBlockReason;
2764
- /** Human-readable message for why invite is blocked. */
2765
- inviteBlockMessage: string | null;
2766
- }
2767
- /**
2768
- * Hook that computes seat status from subscription context and workspace data.
2769
- * Resolves max user limits from seat pricing, plan limits, and settings in priority order.
2770
- * Must be used within SubscriptionContextProvider.
2771
- *
2772
- * @param workspace - The current workspace (needs users array, limits, billingCurrency)
2773
- * @param options - Optional overrides (e.g. settingsMaxUsers fallback)
2774
- * @returns SeatStatus — computed seat and invite information
2775
- *
2776
- * @example
2777
- * ```tsx
2778
- * const { isAtMax, canInvite, inviteBlockMessage, availableSeats } = useSeatStatus(workspace);
2779
- *
2780
- * if (!canInvite) {
2781
- * return <div>{inviteBlockMessage}</div>;
2782
- * }
2783
- * ```
2784
- */
2785
- declare function useSeatStatus(workspace: {
2786
- users?: any[];
2787
- billingCurrency?: string | null;
2788
- } | null, options?: {
2789
- settingsMaxUsers?: number | null;
2790
- }): SeatStatus;
2791
-
2792
- interface PushNotificationState {
2793
- /** Browser's Notification.permission: 'default' | 'granted' | 'denied' */
2794
- permission: NotificationPermission;
2795
- /** Whether this device is subscribed to push notifications */
2796
- isSubscribed: boolean;
2797
- /** Whether the browser supports push notifications */
2798
- isSupported: boolean;
2799
- /** Loading state for subscribe/unsubscribe operations */
2800
- loading: boolean;
2801
- /** Error message from the last operation */
2802
- error: string | null;
2803
- }
2804
- interface PushNotificationContextValue extends PushNotificationState {
2805
- /** Request notification permission from the browser. Returns true if granted. */
2806
- requestPermission: () => Promise<boolean>;
2807
- /** Subscribe this device to push notifications (requests permission if needed). */
2808
- subscribe: () => Promise<void>;
2809
- /** Unsubscribe this device from push notifications. */
2810
- unsubscribe: () => Promise<void>;
2811
- }
2812
- interface PushNotificationProviderProps {
2813
- children: react__default.ReactNode;
2814
- /** Path to the service worker file (default: '/push-sw.js') */
2815
- serviceWorkerPath?: string;
2816
- /** Automatically subscribe after permission is granted on login (default: false) */
2817
- autoSubscribe?: boolean;
2818
- }
2819
- declare const PushNotificationProvider: react__default.FC<PushNotificationProviderProps>;
2820
- /**
2821
- * Hook to access push notification state and actions.
2822
- * Must be used within PushNotificationProvider (included in SaaSOSProvider when push config is provided).
2823
- */
2824
- declare function usePushNotifications(): PushNotificationContextValue;
2825
-
2826
1347
  /**
2827
1348
  * Push notification service worker source code.
2828
1349
  * Export this string and write it to a file in your app's `public/` directory.
@@ -2839,163 +1360,301 @@ declare function usePushNotifications(): PushNotificationContextValue;
2839
1360
  */
2840
1361
  declare const PUSH_SERVICE_WORKER_SCRIPT = "\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n var payload = event.data.json();\n var title = payload.title || 'Notification';\n var options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n var url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (var i = 0; i < clientList.length; i++) {\n var client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n";
2841
1362
 
1363
+ declare const countries: {
1364
+ value: string;
1365
+ flag: string;
1366
+ text: string;
1367
+ currencyCode: string;
1368
+ currencyIcon: string;
1369
+ }[];
1370
+
1371
+ declare const uniqueCurrencies: {
1372
+ value: string;
1373
+ text: string;
1374
+ icon: any;
1375
+ }[];
1376
+
1377
+ declare const languages: {
1378
+ value: string;
1379
+ label: string;
1380
+ flag: string;
1381
+ }[];
1382
+
1383
+ declare const timezones: {
1384
+ value: string;
1385
+ abbr: string;
1386
+ offset: number;
1387
+ isdst: boolean;
1388
+ text: string;
1389
+ utc: string[];
1390
+ }[];
1391
+
1392
+ declare const formSchema: z.ZodObject<{
1393
+ name: z.ZodString;
1394
+ email: z.ZodString;
1395
+ }, z.core.$strip>;
1396
+ type formValuesType = z.infer<typeof formSchema>;
1397
+
1398
+ interface BetaFormData {
1399
+ name?: string;
1400
+ email: string;
1401
+ }
1402
+ interface BetaFormResponse {
1403
+ success: boolean;
1404
+ message: string;
1405
+ }
1406
+
2842
1407
  /**
2843
- * EventEmitter class to handle and trigger event callbacks
2844
- * This class manages all event listeners and provides methods to trigger events
1408
+ * Server-side BuildBase SDK Auth.js-style configuration pattern.
1409
+ *
1410
+ * Configure once, use everywhere. Session is resolved automatically.
1411
+ *
1412
+ * @example 1. Configure once (lib/buildbase.ts)
1413
+ * ```ts
1414
+ * import BuildBase from "@buildbase/sdk"
1415
+ * import { cookies } from "next/headers"
1416
+ *
1417
+ * export const { auth, workspace, subscription, usage } = BuildBase({
1418
+ * serverUrl: process.env.BUILDBASE_URL!,
1419
+ * orgId: process.env.BUILDBASE_ORG_ID!,
1420
+ * getSessionId: async () => {
1421
+ * const c = await cookies()
1422
+ * return c.get("bb-session-id")?.value ?? null
1423
+ * },
1424
+ * })
1425
+ * ```
1426
+ *
1427
+ * @example 2. Use in API routes — no sessionId passing needed
1428
+ * ```ts
1429
+ * import { auth, workspace, subscription } from "@/lib/buildbase"
1430
+ *
1431
+ * export async function GET() {
1432
+ * const session = await auth()
1433
+ * if (!session) return Response.json({ error: "Unauthorized" }, { status: 401 })
1434
+ *
1435
+ * const workspaces = await workspace.list()
1436
+ * const sub = await subscription.get(workspaceId)
1437
+ * return Response.json({ workspaces, sub })
1438
+ * }
1439
+ * ```
1440
+ *
1441
+ * @example 3. Background jobs — override session for service accounts
1442
+ * ```ts
1443
+ * import { client } from "@/lib/buildbase"
1444
+ *
1445
+ * const api = client.forSession(process.env.SERVICE_SESSION_ID!)
1446
+ * await api.workspace.recordUsage(workspaceId, { quotaSlug: "uploads", quantity: 1 })
1447
+ * ```
2845
1448
  */
2846
- declare class EventEmitter {
2847
- private callbacks;
2848
- /**
2849
- * Set the event callbacks
2850
- * @param callbacks - The event callbacks to register
2851
- */
2852
- setCallbacks(callbacks: IEventCallbacks | null): void;
2853
- /**
2854
- * Get the current event callbacks
2855
- * @returns The current event callbacks or null
2856
- */
2857
- getCallbacks(): IEventCallbacks | null;
2858
- /**
2859
- * Emit an event
2860
- * @param eventType - The type of event
2861
- * @param data - The event data
2862
- */
2863
- private emit;
1449
+
1450
+ interface BuildBaseConfig {
1451
+ /** Base URL of the BuildBase API server */
1452
+ serverUrl: string;
1453
+ /** Organization ID */
1454
+ orgId: string;
1455
+ /** API version (default: 'v1') */
1456
+ version?: ApiVersion;
2864
1457
  /**
2865
- * Trigger user created event
2866
- * @param user - The newly created user
1458
+ * Async callback to resolve the current session ID.
1459
+ * Called automatically before each authenticated API call.
1460
+ *
1461
+ * @example Next.js (httpOnly cookie)
1462
+ * ```ts
1463
+ * getSessionId: async () => {
1464
+ * const c = await cookies()
1465
+ * return c.get("bb-session-id")?.value ?? null
1466
+ * }
1467
+ * ```
1468
+ *
1469
+ * @example Express (from request — use withSession() instead)
1470
+ * ```ts
1471
+ * // Don't set getSessionId for Express. Use withSession(req.sessionId) per-request.
1472
+ * ```
2867
1473
  */
2868
- emitUserCreated(user: IUser): Promise<void>;
1474
+ getSessionId?: () => Promise<string | null>;
2869
1475
  /**
2870
- * Trigger user updated event
2871
- * @param user - The updated user
2872
- * @param previousUser - The user data before the update (optional)
1476
+ * Request timeout in milliseconds. (default: 30000 — 30 seconds)
1477
+ * Set to 0 to disable timeout.
2873
1478
  */
2874
- emitUserUpdated(user: IUser, previousUser?: IUser): Promise<void>;
1479
+ timeout?: number;
2875
1480
  /**
2876
- * Trigger workspace changed event
2877
- * @param workspace - The newly selected workspace
2878
- * @param previousWorkspace - The previously selected workspace (optional)
1481
+ * Maximum number of automatic retries for transient network failures.
1482
+ * Uses exponential backoff. (default: 0 no retries)
1483
+ * Only retries on network errors and 5xx responses, never on 4xx.
2879
1484
  */
2880
- emitWorkspaceChanged(workspace: IWorkspace, previousWorkspace?: IWorkspace | null): Promise<void>;
1485
+ maxRetries?: number;
2881
1486
  /**
2882
- * Trigger workspace updated event
2883
- * @param workspace - The updated workspace
1487
+ * Enable debug logging. Logs all API requests/responses to console.
1488
+ * (default: false)
2884
1489
  */
2885
- emitWorkspaceUpdated(workspace: IWorkspace): Promise<void>;
1490
+ debug?: boolean;
2886
1491
  /**
2887
- * Trigger workspace user added event
2888
- * @param userId - The ID of the user that was added
2889
- * @param workspace - The workspace the user was added to
2890
- * @param role - The role assigned to the user
1492
+ * Custom headers merged into every request.
1493
+ * Useful for proxies, tracing, or custom auth schemes.
1494
+ *
1495
+ * @example
1496
+ * ```ts
1497
+ * headers: {
1498
+ * 'X-Request-Source': 'backend-cron',
1499
+ * 'X-Trace-Id': traceId,
1500
+ * }
1501
+ * ```
2891
1502
  */
2892
- emitWorkspaceUserAdded(userId: string, workspace: IWorkspace, role: string): Promise<void>;
1503
+ headers?: Record<string, string>;
2893
1504
  /**
2894
- * Trigger workspace user removed event
2895
- * @param userId - The ID of the user that was removed
2896
- * @param workspace - The workspace the user was removed from
2897
- * @param role - The role the user had in the workspace
1505
+ * Called when any API request fails. Use for centralized error logging.
1506
+ * The error is still thrown after this callback runs.
1507
+ *
1508
+ * @example
1509
+ * ```ts
1510
+ * onError: (error, context) => {
1511
+ * Sentry.captureException(error, { extra: context })
1512
+ * }
1513
+ * ```
2898
1514
  */
2899
- emitWorkspaceUserRemoved(userId: string, workspace: IWorkspace, role: string): Promise<void>;
1515
+ onError?: (error: Error, context: {
1516
+ method: string;
1517
+ path: string;
1518
+ }) => void;
2900
1519
  /**
2901
- * Trigger workspace user role changed event
2902
- * @param userId - The ID of the user whose role was changed
2903
- * @param workspace - The workspace where the role was changed
2904
- * @param previousRole - The previous role of the user
2905
- * @param newRole - The new role of the user
1520
+ * Custom fetch implementation. Replaces the global `fetch`.
1521
+ * Useful for testing, proxying, or adding middleware.
1522
+ *
1523
+ * @example Using undici for Node.js
1524
+ * ```ts
1525
+ * import { fetch } from 'undici'
1526
+ * { fetch: fetch as any }
1527
+ * ```
2906
1528
  */
2907
- emitWorkspaceUserRoleChanged(userId: string, workspace: IWorkspace, previousRole: string, newRole: string): Promise<void>;
1529
+ fetch?: typeof globalThis.fetch;
1530
+ }
1531
+ interface BuildBaseSession {
1532
+ sessionId: string;
1533
+ }
1534
+ interface WorkspaceActions {
1535
+ list(): Promise<IWorkspace[]>;
1536
+ get(workspaceId: string): Promise<IWorkspace>;
1537
+ create(data: {
1538
+ name: string;
1539
+ image?: string;
1540
+ }): Promise<IWorkspace>;
1541
+ update(workspaceId: string, data: Partial<IWorkspace>): Promise<IWorkspace>;
1542
+ delete(workspaceId: string): Promise<{
1543
+ success: boolean;
1544
+ }>;
1545
+ }
1546
+ interface UserActions {
1547
+ list(workspaceId: string): Promise<IWorkspaceUser[]>;
1548
+ invite(workspaceId: string, email: string, role: string): Promise<{
1549
+ userId: string;
1550
+ workspace: IWorkspace;
1551
+ message: string;
1552
+ }>;
1553
+ remove(workspaceId: string, userId: string): Promise<{
1554
+ userId: string;
1555
+ workspace: IWorkspace;
1556
+ message: string;
1557
+ }>;
1558
+ updateRole(workspaceId: string, userId: string, role: string): Promise<{
1559
+ userId: string;
1560
+ workspace: IWorkspace;
1561
+ message: string;
1562
+ }>;
1563
+ getProfile(): Promise<IUser>;
1564
+ updateProfile(data: Partial<IUser>): Promise<IUser>;
1565
+ }
1566
+ interface SubscriptionActions {
1567
+ get(workspaceId: string): Promise<ISubscriptionResponse>;
1568
+ checkout(workspaceId: string, request: ICheckoutSessionRequest): Promise<CheckoutResult | ICheckoutSessionResponse>;
1569
+ update(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1570
+ cancel(workspaceId: string): Promise<ISubscriptionResponse>;
1571
+ resume(workspaceId: string): Promise<ISubscriptionResponse>;
1572
+ getBillingPortalUrl(workspaceId: string, returnUrl?: string): Promise<{
1573
+ url: string;
1574
+ }>;
1575
+ }
1576
+ interface PlanActions {
1577
+ getGroup(workspaceId: string): Promise<IPlanGroupResponse>;
1578
+ getVersions(workspaceId: string): Promise<IPlanGroupVersionsResponse>;
1579
+ /** No auth required */
1580
+ getPublic(slug: string): Promise<IPublicPlansResponse>;
1581
+ /** No auth required */
1582
+ getVersion(groupVersionId: string): Promise<IPlanGroupVersion>;
1583
+ }
1584
+ interface InvoiceActions {
1585
+ list(workspaceId: string, limit?: number, startingAfter?: string): Promise<IInvoiceListResponse>;
1586
+ get(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
1587
+ }
1588
+ interface UsageActions {
1589
+ record(workspaceId: string, request: IRecordUsageRequest): Promise<IRecordUsageResponse>;
1590
+ getQuota(workspaceId: string, quotaSlug: string): Promise<IQuotaUsageStatusResponse>;
1591
+ getAll(workspaceId: string): Promise<IAllQuotaUsageResponse>;
1592
+ getLogs(workspaceId: string, query?: IUsageLogsQuery): Promise<IUsageLogsResponse>;
1593
+ }
1594
+ interface SettingsActions {
1595
+ get(): Promise<ISettings>;
1596
+ }
1597
+ interface FeatureActions {
1598
+ list(): Promise<IWorkspaceFeature[]>;
1599
+ update(workspaceId: string, key: string, value: boolean): Promise<IWorkspace>;
1600
+ }
1601
+ /** All action modules bound to a specific session. Returned by `withSession()`. */
1602
+ interface ScopedActions {
1603
+ workspace: WorkspaceActions;
1604
+ users: UserActions;
1605
+ subscription: SubscriptionActions;
1606
+ plans: PlanActions;
1607
+ invoices: InvoiceActions;
1608
+ usage: UsageActions;
1609
+ settings: SettingsActions;
1610
+ features: FeatureActions;
1611
+ }
1612
+ interface BuildBaseResult extends ScopedActions {
2908
1613
  /**
2909
- * Trigger workspace created event
2910
- * @param workspace - The newly created workspace
1614
+ * Check authentication. Returns session or null.
1615
+ * Uses the `getSessionId` callback from config.
1616
+ *
1617
+ * ```ts
1618
+ * const session = await auth()
1619
+ * if (!session) return Response.json({ error: "Unauthorized" }, { status: 401 })
1620
+ * ```
2911
1621
  */
2912
- emitWorkspaceCreated(workspace: IWorkspace): Promise<void>;
1622
+ auth(): Promise<BuildBaseSession | null>;
2913
1623
  /**
2914
- * Trigger workspace deleted event
2915
- * @param workspace - The deleted workspace
1624
+ * Create a scoped client bound to a specific session ID.
1625
+ * Returns all the same action modules (workspace, subscription, etc.)
1626
+ * but using the provided session instead of the `getSessionId` callback.
1627
+ *
1628
+ * Use this for frameworks without async request context (Express, Hono, Fastify)
1629
+ * or for background jobs / service accounts.
1630
+ *
1631
+ * @example Express
1632
+ * ```ts
1633
+ * app.get("/api/workspaces", async (req, res) => {
1634
+ * const bb = withSession(req.headers["x-session-id"])
1635
+ * const workspaces = await bb.workspace.list()
1636
+ * res.json(workspaces)
1637
+ * })
1638
+ * ```
1639
+ *
1640
+ * @example Background job
1641
+ * ```ts
1642
+ * const bb = withSession(process.env.SERVICE_SESSION_ID!)
1643
+ * await bb.usage.record(workspaceId, { quotaSlug: "uploads", quantity: 5 })
1644
+ * ```
2916
1645
  */
2917
- emitWorkspaceDeleted(workspace: IWorkspace): Promise<void>;
2918
- }
2919
- declare const eventEmitter: EventEmitter;
2920
-
2921
- /**
2922
- * Centralized API client for organization (OS) settings.
2923
- * Extends BaseApi for shared URL/auth/request handling.
2924
- */
2925
-
2926
- declare class SettingsApi extends BaseApi {
2927
- constructor(config: IOsConfig);
2928
- getSettings(signal?: AbortSignal): Promise<ISettings>;
2929
- }
2930
-
2931
- /**
2932
- * Centralized formatting for subscription/quota display: cents, overage rates, included + overage text.
2933
- * Currency must be provided by the caller (e.g. workspace.billingCurrency, plan.currency, or selected currency).
2934
- */
2935
- /** Common currency display (code or symbol). Use lowercase Stripe codes (usd, eur, etc.). */
2936
- declare const CURRENCY_DISPLAY: Record<string, string>;
2937
- /** Currency code to flag emoji (country/region associated with the currency). Use for dropdowns. */
2938
- declare const CURRENCY_FLAG: Record<string, string>;
2939
- /** Get flag emoji for a currency code. Returns empty string when unknown or empty. */
2940
- declare function getCurrencyFlag(currency: string): string;
2941
- /** Get currency symbol for display. Use lowercase Stripe codes (usd, eur). Returns code when unknown; empty string when currency is empty. */
2942
- declare function getCurrencySymbol(currency: string): string;
2943
- /** Allowed plan/pricing currency codes (must match server ALLOWED_BILLING_CURRENCIES). Use for dropdowns and validation. */
2944
- 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"];
2945
- /** Options for plan currency select: { value, label } with symbol. Use in CreateOrEditPlan and anywhere a currency dropdown is needed. */
2946
- declare const PLAN_CURRENCY_OPTIONS: {
2947
- value: "usd" | "eur" | "gbp" | "jpy" | "cad" | "aud" | "chf" | "cny" | "hkd" | "sgd" | "inr" | "mxn" | "brl" | "nzd" | "sek" | "nok" | "dkk" | "pln" | "thb";
2948
- label: string;
2949
- }[];
2950
- /** Format cents as money string (e.g. 1999, "usd" -> "$19.99"). Caller must pass currency (e.g. from plan or workspace). */
2951
- declare function formatCents(cents: number, currency: string): string;
2952
- /**
2953
- * Format overage rate for display. When unitSize > 1: "$1.00/1,000 units"; else "$1.00/unit".
2954
- * Returns null if overageCents is missing or negative.
2955
- */
2956
- declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string): string | null;
2957
- /**
2958
- * Format overage rate with optional unit label for comparison/preview UIs.
2959
- * e.g. formatOverageRateWithLabel(50, 1000, "video") -> "$0.50/1,000 videos"
2960
- * formatOverageRateWithLabel(46, 1, "video") -> "$0.46/video"
2961
- * When unitLabel is omitted, falls back to formatOverageRate behavior.
2962
- */
2963
- declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string): string | null;
2964
- /**
2965
- * Get singular unit label from item name or slug (e.g. "Videos" -> "video", "reels" -> "reel").
2966
- * Used for quota display in comparison and preview.
2967
- */
2968
- declare function getQuotaUnitLabelFromName(nameOrSlug: string): string;
2969
- /**
2970
- * Format quota "included + overage" for display.
2971
- * When unitSize >= 2: "Included: 1,000, after that $1.00/1,000 emails".
2972
- * Otherwise: "Included: 5, after that $0.30/image".
2973
- */
2974
- declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number): string;
2975
-
2976
- type QuotaDisplayValue = {
2977
- included: number;
2978
- overage?: number;
2979
- unitSize?: number;
2980
- } | null;
2981
- /**
2982
- * Normalize a per-interval quota value to a display shape for the given billing interval.
2983
- */
2984
- declare function getQuotaDisplayValue(value: IQuotaByInterval | null | undefined, interval?: BillingInterval): QuotaDisplayValue;
2985
- /** Options for formatting quota with price. */
2986
- interface FormatQuotaWithPriceOptions {
2987
- /** If true, overage is in cents (Stripe); format as dollars. Default true. */
2988
- overageInCents?: boolean;
2989
- /** Currency symbol override. When omitted, derived from `currency` (empty if no currency). */
2990
- currencySymbol?: string;
2991
- /** Stripe currency code (e.g. 'usd', 'inr'). Used to resolve symbol when currencySymbol is not set. */
2992
- currency?: string;
1646
+ withSession(sessionId: string): ScopedActions;
1647
+ /** Low-level API classes bound to a specific session */
1648
+ client: {
1649
+ forSession(sessionId: string): {
1650
+ workspace: WorkspaceApi;
1651
+ user: UserApi;
1652
+ settings: SettingsApi;
1653
+ push: PushApi;
1654
+ };
1655
+ };
2993
1656
  }
2994
- /**
2995
- * Format a quota display value as "X included, then $Y.YY / unit" (e.g. "10 included, then $10.00 / video").
2996
- * Assumes overage is the per-unit price (in cents when overageInCents is true).
2997
- */
2998
- declare function formatQuotaWithPrice(value: QuotaDisplayValue, unitName: string, options?: FormatQuotaWithPriceOptions): string;
1657
+ declare function BuildBase(config: BuildBaseConfig): BuildBaseResult;
2999
1658
 
3000
- export { ApiVersion, AuthStatus, BaseApi, BetaForm, CURRENCY_DISPLAY, CURRENCY_FLAG, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, PricingPage, PushNotificationProvider, QuotaUsageContextProvider, SaaSOSProvider, SettingsApi, SubscriptionContextProvider, UserApi, WhenAuthenticated, WhenNoSubscription, WhenNotTrialing, WhenQuotaAvailable, WhenQuotaExhausted, WhenQuotaOverage, WhenQuotaThreshold, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenTrialEnding, WhenTrialing, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, invalidateQuotaUsage, invalidateSubscription, resolveMaxUsers, useAllQuotaUsage, useBillingPortal, useCancelSubscription, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, usePushNotifications, useQuotaUsageContext, useQuotaUsageStatus, useRecordUsage, useResumeSubscription, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSeatStatus, useSubscription, useSubscriptionContext, useSubscriptionManagement, useTrialStatus, useUpdateSubscription, useUsageLogs, useUserAttributes, useUserFeatures, validateInvite };
3001
- export type { BillingInterval, CheckoutResult, EventData, EventType, FormatQuotaWithPriceOptions, IAllQuotaUsageResponse, 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, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, InviteBlockReason, InviteValidation, InvoiceStatus, MaxUsersConfig, OnWorkspaceChangeParams, PlanVersionWithPricingVariants, PricingPageDetails, PricingPageProps, QuotaDisplayValue, QuotaDisplayWithOverage, QuotaUsageContextValue, SeatStatus, SubscriptionContextValue, TrialStatus, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
1659
+ export { ApiVersion, AuthApi, AuthStatus, BaseApi, BetaForm, BuildBase, CURRENCY_DISPLAY, CURRENCY_FLAG, EventEmitter, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, PushApi, SettingsApi, UserApi, WorkspaceApi, formSchema as betaFormSchema, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, countries, uniqueCurrencies as currencies, BuildBase as default, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, invalidateQuotaUsage, invalidateSubscription, languages, resolveMaxUsers, timezones, validateInvite };
1660
+ export type { BetaFormData, BetaFormResponse, formValuesType as BetaFormValues, BillingInterval, BuildBaseConfig, BuildBaseResult, BuildBaseSession, CheckoutResult, EventData, EventType, FeatureActions, FormatQuotaWithPriceOptions, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, IEventCallbacks, IInvoice, IInvoiceListResponse, IInvoiceResponse, IOsConfig, IOsState, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, InviteBlockReason, InviteValidation, InvoiceActions, InvoiceStatus, MaxUsersConfig, OnWorkspaceChangeParams, PlanActions, PlanVersionWithPricingVariants, QuotaDisplayValue, QuotaDisplayWithOverage, ScopedActions, SettingsActions, SubscriptionActions, UsageActions, UserActions, UserCreatedEventData, UserUpdatedEventData, WorkspaceActions, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };