@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/README.md +236 -90
- package/dist/index.d.ts +650 -1991
- package/dist/index.js +1 -29
- package/dist/index.mjs +1 -0
- package/dist/react/index.d.ts +3180 -0
- package/dist/react/index.js +36 -0
- package/dist/react/index.mjs +36 -0
- package/package.json +13 -8
- package/dist/index.esm.js +0 -29
- /package/dist/{saas-os.css → css/styles.css} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
-
*
|
|
712
|
-
*
|
|
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
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
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
|
-
*
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
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
|
|
735
|
-
|
|
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
|
-
*
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
*
|
|
742
|
-
*
|
|
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
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
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
|
-
*
|
|
817
|
-
*
|
|
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
|
|
895
|
-
|
|
896
|
-
|
|
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
|
|
1025
|
-
|
|
1026
|
-
|
|
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
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
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
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
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
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
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
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
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
|
-
*
|
|
1222
|
-
*
|
|
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
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
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
|
-
*
|
|
1248
|
-
*
|
|
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
|
-
*
|
|
2023
|
-
*
|
|
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
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
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
|
-
*
|
|
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
|
|
2290
|
-
|
|
2291
|
-
url: string;
|
|
2292
|
-
}>;
|
|
2293
|
-
loading: boolean;
|
|
2294
|
-
error: string | null;
|
|
2295
|
-
};
|
|
1160
|
+
declare function invalidateSubscription(): void;
|
|
1161
|
+
|
|
2296
1162
|
/**
|
|
2297
|
-
*
|
|
2298
|
-
*
|
|
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
|
|
2329
|
-
|
|
2330
|
-
loading: boolean;
|
|
2331
|
-
error: string | null;
|
|
2332
|
-
refetch: () => Promise<void>;
|
|
2333
|
-
};
|
|
1166
|
+
declare function invalidateQuotaUsage(): void;
|
|
1167
|
+
|
|
2334
1168
|
/**
|
|
2335
|
-
*
|
|
2336
|
-
*
|
|
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
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
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
|
-
*
|
|
2376
|
-
*
|
|
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
|
|
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
|
-
*
|
|
2416
|
-
*
|
|
2417
|
-
*
|
|
2418
|
-
*
|
|
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
|
|
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
|
-
*
|
|
2458
|
-
*
|
|
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
|
|
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
|
-
*
|
|
2495
|
-
*
|
|
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
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
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
|
-
*
|
|
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
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
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
|
-
*
|
|
2607
|
-
*
|
|
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
|
|
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
|
-
*
|
|
2844
|
-
*
|
|
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
|
-
|
|
2847
|
-
|
|
2848
|
-
/**
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
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
|
-
*
|
|
2866
|
-
*
|
|
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
|
-
|
|
1474
|
+
getSessionId?: () => Promise<string | null>;
|
|
2869
1475
|
/**
|
|
2870
|
-
*
|
|
2871
|
-
*
|
|
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
|
-
|
|
1479
|
+
timeout?: number;
|
|
2875
1480
|
/**
|
|
2876
|
-
*
|
|
2877
|
-
*
|
|
2878
|
-
*
|
|
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
|
-
|
|
1485
|
+
maxRetries?: number;
|
|
2881
1486
|
/**
|
|
2882
|
-
*
|
|
2883
|
-
*
|
|
1487
|
+
* Enable debug logging. Logs all API requests/responses to console.
|
|
1488
|
+
* (default: false)
|
|
2884
1489
|
*/
|
|
2885
|
-
|
|
1490
|
+
debug?: boolean;
|
|
2886
1491
|
/**
|
|
2887
|
-
*
|
|
2888
|
-
*
|
|
2889
|
-
*
|
|
2890
|
-
* @
|
|
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
|
-
|
|
1503
|
+
headers?: Record<string, string>;
|
|
2893
1504
|
/**
|
|
2894
|
-
*
|
|
2895
|
-
*
|
|
2896
|
-
*
|
|
2897
|
-
* @
|
|
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
|
-
|
|
1515
|
+
onError?: (error: Error, context: {
|
|
1516
|
+
method: string;
|
|
1517
|
+
path: string;
|
|
1518
|
+
}) => void;
|
|
2900
1519
|
/**
|
|
2901
|
-
*
|
|
2902
|
-
*
|
|
2903
|
-
*
|
|
2904
|
-
* @
|
|
2905
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
2910
|
-
*
|
|
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
|
-
|
|
1622
|
+
auth(): Promise<BuildBaseSession | null>;
|
|
2913
1623
|
/**
|
|
2914
|
-
*
|
|
2915
|
-
*
|
|
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
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
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,
|
|
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,
|
|
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 };
|