@buildbase/sdk 0.0.10 → 0.0.12
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 +2 -1
- package/dist/index.d.ts +1099 -33
- package/dist/index.esm.js +6 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/saas-os.css +1 -1
- package/dist/types/api/types.d.ts +83 -4
- package/dist/types/components/ErrorBoundary.d.ts +49 -2
- package/dist/types/components/features/index.d.ts +109 -0
- package/dist/types/components/user/auth.d.ts +64 -0
- package/dist/types/components/user/role.d.ts +70 -0
- package/dist/types/contexts/AuthContext/actions.d.ts +1 -0
- package/dist/types/contexts/AuthContext/reducer.d.ts +9 -3
- package/dist/types/contexts/AuthContext/types.d.ts +2 -0
- package/dist/types/contexts/shared/useAppSelector.d.ts +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/lib/api-utils.d.ts +164 -0
- package/dist/types/lib/error-handler.d.ts +40 -0
- package/dist/types/providers/auth/hooks.d.ts +67 -6
- package/dist/types/providers/auth/types.d.ts +7 -3
- package/dist/types/providers/os/hooks.d.ts +40 -1
- package/dist/types/providers/user/hooks.d.ts +71 -0
- package/dist/types/providers/workspace/api.d.ts +42 -2
- package/dist/types/providers/workspace/hooks.d.ts +105 -0
- package/dist/types/providers/workspace/subscription-hooks.d.ts +399 -19
- package/package.json +14 -12
package/dist/types/index.d.ts
CHANGED
|
@@ -5,15 +5,16 @@ export { BetaForm } from './components/beta/BetaForm';
|
|
|
5
5
|
export { WhenAuthenticated, WhenUnauthenticated } from './components/user/auth';
|
|
6
6
|
export { WhenRoles, WhenWorkspaceRoles } from './components/user/role';
|
|
7
7
|
export { WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, } from './components/features';
|
|
8
|
+
export { AuthStatus } from './providers/auth/types';
|
|
8
9
|
export { useSaaSAuth } from './providers/auth/hooks';
|
|
9
10
|
export { useSaaSSettings } from './providers/os/hooks';
|
|
10
11
|
export { useUserAttributes, useUserFeatures } from './providers/user/hooks';
|
|
11
12
|
export { useSaaSWorkspaces } from './providers/workspace/hooks';
|
|
12
13
|
export { WorkspaceSwitcher } from './providers/workspace/provider';
|
|
13
|
-
export { usePlanGroup, useSubscription, useSubscriptionManagement, useUpdateSubscription, } from './providers/workspace/subscription-hooks';
|
|
14
|
+
export { useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, useSubscription, useSubscriptionManagement, useUpdateSubscription, } from './providers/workspace/subscription-hooks';
|
|
14
15
|
export { eventEmitter } from './providers/events';
|
|
15
16
|
export type { EventData, EventType, IEventCallbacks, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData, } from './providers/events/types';
|
|
16
17
|
export { default as ErrorBoundary, SDKErrorBoundary } from './components/ErrorBoundary';
|
|
17
18
|
export { SDKError, createSDKError, errorHandler, handleError } from './lib/error-handler';
|
|
18
19
|
export type { ErrorHandlerConfig, SDKErrorContext } from './lib/error-handler';
|
|
19
|
-
export type { IPlan, IPlanGroup, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanVersion, IPlanVersionWithPlan, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, } from './api/types';
|
|
20
|
+
export type { BillingInterval, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, InvoiceStatus, IPlan, IPlanGroup, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionsResponse, IPlanGroupVersionWithPlans, IPlanVersion, IPlanVersionWithPlan, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, } from './api/types';
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API utility functions for consistent error handling and request management
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if an error is from AbortController (request was cancelled).
|
|
6
|
+
* Useful for ignoring abort errors when components unmount or requests are cancelled.
|
|
7
|
+
*
|
|
8
|
+
* @param error - The error to check
|
|
9
|
+
* @returns True if the error is an AbortError, false otherwise
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* try {
|
|
14
|
+
* await safeFetch(url, { signal });
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* if (isAbortError(error)) {
|
|
17
|
+
* // Request was cancelled, ignore
|
|
18
|
+
* return;
|
|
19
|
+
* }
|
|
20
|
+
* // Handle other errors
|
|
21
|
+
* console.error('Request failed:', error);
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function isAbortError(error: unknown): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Safely execute a fetch request with network error handling.
|
|
28
|
+
* Wraps native fetch to provide better error messages for network failures.
|
|
29
|
+
* Supports AbortSignal - when aborted, throws with name 'AbortError' (caller can use isAbortError()).
|
|
30
|
+
* In development mode, automatically logs request/response for debugging (prefixed with [SDK API]).
|
|
31
|
+
* Sensitive data (tokens, passwords) is automatically redacted from logs.
|
|
32
|
+
*
|
|
33
|
+
* @param url - The URL to fetch
|
|
34
|
+
* @param options - Optional fetch options (RequestInit), including AbortSignal
|
|
35
|
+
* @returns Promise resolving to Response object
|
|
36
|
+
* @throws {Error} Network errors with descriptive messages, or AbortError if request was aborted
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* // Basic usage
|
|
41
|
+
* const response = await safeFetch('/api/users');
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* // With abort signal
|
|
47
|
+
* const controller = new AbortController();
|
|
48
|
+
* const response = await safeFetch('/api/users', {
|
|
49
|
+
* signal: controller.signal,
|
|
50
|
+
* method: 'POST',
|
|
51
|
+
* body: JSON.stringify({ name: 'John' }),
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* // Cancel request
|
|
55
|
+
* controller.abort();
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* // Handle network errors
|
|
61
|
+
* try {
|
|
62
|
+
* const response = await safeFetch('/api/users');
|
|
63
|
+
* } catch (error) {
|
|
64
|
+
* if (isAbortError(error)) {
|
|
65
|
+
* // Request was cancelled
|
|
66
|
+
* return;
|
|
67
|
+
* }
|
|
68
|
+
* // Network error: "Network error: Please check your internet connection"
|
|
69
|
+
* console.error(error.message);
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function safeFetch(url: string, options?: RequestInit): Promise<Response>;
|
|
74
|
+
/**
|
|
75
|
+
* Parse JSON response with error handling.
|
|
76
|
+
* Provides better error messages if response is not valid JSON.
|
|
77
|
+
*
|
|
78
|
+
* @param response - The Response object to parse
|
|
79
|
+
* @returns Promise resolving to parsed JSON data
|
|
80
|
+
* @throws {Error} If response body is empty or not valid JSON
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* const response = await safeFetch('/api/users');
|
|
85
|
+
* const users = await parseJsonResponse<User[]>(response);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function parseJsonResponse<T>(response: Response): Promise<T>;
|
|
89
|
+
/**
|
|
90
|
+
* Create a standardized API error from a response.
|
|
91
|
+
* Provides user-friendly error messages based on HTTP status codes.
|
|
92
|
+
*
|
|
93
|
+
* @param response - The Response object with error status
|
|
94
|
+
* @param defaultMessage - Default error message if status-specific message not available
|
|
95
|
+
* @returns Error instance with descriptive message
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```tsx
|
|
99
|
+
* const response = await safeFetch('/api/users');
|
|
100
|
+
* if (!response.ok) {
|
|
101
|
+
* throw createApiError(response, 'Failed to fetch users');
|
|
102
|
+
* // Error message: "Failed to fetch users (401: Unauthorized - Please check your session)"
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export declare function createApiError(response: Response, defaultMessage: string): Error;
|
|
107
|
+
/**
|
|
108
|
+
* Handle API response with consistent error handling.
|
|
109
|
+
* Checks response status, parses JSON, and provides standardized error messages.
|
|
110
|
+
* This is the recommended way to handle API responses in the SDK.
|
|
111
|
+
*
|
|
112
|
+
* @param response - The Response object to handle
|
|
113
|
+
* @param defaultErrorMessage - Default error message if response is not ok
|
|
114
|
+
* @returns Promise resolving to parsed JSON data
|
|
115
|
+
* @throws {Error} If response is not ok or JSON parsing fails
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```tsx
|
|
119
|
+
* const response = await safeFetch('/api/users');
|
|
120
|
+
* const users = await handleApiResponse<User[]>(response, 'Failed to fetch users');
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* // With error handling
|
|
126
|
+
* try {
|
|
127
|
+
* const response = await safeFetch('/api/users');
|
|
128
|
+
* const users = await handleApiResponse<User[]>(response);
|
|
129
|
+
* } catch (error) {
|
|
130
|
+
* // Error message includes status code and descriptive text
|
|
131
|
+
* console.error(error.message);
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export declare function handleApiResponse<T>(response: Response, defaultErrorMessage?: string): Promise<T>;
|
|
136
|
+
/**
|
|
137
|
+
* Fetch with timeout support.
|
|
138
|
+
* Automatically cancels request if it takes longer than specified timeout.
|
|
139
|
+
*
|
|
140
|
+
* @param url - The URL to fetch
|
|
141
|
+
* @param options - Optional fetch options (RequestInit)
|
|
142
|
+
* @param timeout - Timeout in milliseconds (default: 10000ms / 10 seconds)
|
|
143
|
+
* @returns Promise resolving to Response object
|
|
144
|
+
* @throws {Error} If request times out: "Request timeout after {timeout}ms"
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```tsx
|
|
148
|
+
* // 5 second timeout
|
|
149
|
+
* const response = await fetchWithTimeout('/api/users', {}, 5000);
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```tsx
|
|
154
|
+
* // Handle timeout
|
|
155
|
+
* try {
|
|
156
|
+
* const response = await fetchWithTimeout('/api/users', {}, 5000);
|
|
157
|
+
* } catch (error) {
|
|
158
|
+
* if (error.message.includes('timeout')) {
|
|
159
|
+
* console.error('Request took too long');
|
|
160
|
+
* }
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export declare function fetchWithTimeout(url: string, options?: RequestInit, timeout?: number): Promise<Response>;
|
|
@@ -55,6 +55,46 @@ declare class ErrorHandler {
|
|
|
55
55
|
wrapSync<T extends (...args: any[]) => any>(fn: T, context: SDKErrorContext): T;
|
|
56
56
|
}
|
|
57
57
|
export declare const errorHandler: ErrorHandler;
|
|
58
|
+
/**
|
|
59
|
+
* Convenience function to handle an error with context.
|
|
60
|
+
* Uses the global error handler instance.
|
|
61
|
+
*
|
|
62
|
+
* @param error - The error to handle (Error instance, string, or unknown)
|
|
63
|
+
* @param context - Optional context about where the error occurred
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* try {
|
|
68
|
+
* await someOperation();
|
|
69
|
+
* } catch (error) {
|
|
70
|
+
* handleError(error, {
|
|
71
|
+
* component: 'MyComponent',
|
|
72
|
+
* action: 'someOperation',
|
|
73
|
+
* metadata: { userId: '123' },
|
|
74
|
+
* });
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
58
78
|
export declare function handleError(error: Error | unknown, context?: SDKErrorContext): void;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new SDKError instance with optional code and context.
|
|
81
|
+
* Useful for creating standardized errors throughout the SDK.
|
|
82
|
+
*
|
|
83
|
+
* @param message - Error message
|
|
84
|
+
* @param code - Optional error code (e.g., 'AUTH_FAILED', 'NETWORK_ERROR')
|
|
85
|
+
* @param context - Optional context about where the error occurred
|
|
86
|
+
* @param originalError - Optional original error that caused this error
|
|
87
|
+
* @returns A new SDKError instance
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```tsx
|
|
91
|
+
* throw createSDKError(
|
|
92
|
+
* 'Failed to authenticate user',
|
|
93
|
+
* 'AUTH_FAILED',
|
|
94
|
+
* { component: 'AuthProvider', action: 'signIn' },
|
|
95
|
+
* originalError
|
|
96
|
+
* );
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
59
99
|
export declare function createSDKError(message: string, code?: string, context?: SDKErrorContext, originalError?: Error): SDKError;
|
|
60
100
|
export {};
|
|
@@ -1,11 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main authentication hook for the SDK.
|
|
3
|
+
* Provides authentication state, user session, and auth actions.
|
|
4
|
+
*
|
|
5
|
+
* @returns An object containing:
|
|
6
|
+
* - `user`: Current authenticated user object (null if not authenticated)
|
|
7
|
+
* - `session`: Full session object with user and token (null if not authenticated)
|
|
8
|
+
* - `status`: Current authentication status (loading, redirecting, authenticating, authenticated, unauthenticated)
|
|
9
|
+
* - `isLoading`: Boolean indicating if auth state is being determined
|
|
10
|
+
* - `isAuthenticated`: Boolean indicating if user is authenticated
|
|
11
|
+
* - `isRedirecting`: Boolean indicating if redirecting to OAuth provider
|
|
12
|
+
* - `signIn()`: Function to initiate OAuth sign-in flow
|
|
13
|
+
* - `signOut()`: Function to sign out the current user
|
|
14
|
+
* - `openWorkspaceSettings(section?)`: Function to open workspace settings dialog
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* function MyComponent() {
|
|
19
|
+
* const { user, isAuthenticated, signIn, signOut } = useSaaSAuth();
|
|
20
|
+
*
|
|
21
|
+
* if (!isAuthenticated) {
|
|
22
|
+
* return <button onClick={signIn}>Sign In</button>;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <div>
|
|
27
|
+
* <p>Welcome, {user?.name}</p>
|
|
28
|
+
* <button onClick={signOut}>Sign Out</button>
|
|
29
|
+
* </div>
|
|
30
|
+
* );
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* // Handle loading state
|
|
37
|
+
* function App() {
|
|
38
|
+
* const { status, isLoading } = useSaaSAuth();
|
|
39
|
+
*
|
|
40
|
+
* if (isLoading) {
|
|
41
|
+
* return <LoadingSpinner />;
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* return <MainContent />;
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* // Open workspace settings
|
|
51
|
+
* function SettingsButton() {
|
|
52
|
+
* const { openWorkspaceSettings } = useSaaSAuth();
|
|
53
|
+
*
|
|
54
|
+
* return (
|
|
55
|
+
* <button onClick={() => openWorkspaceSettings('general')}>
|
|
56
|
+
* Open Settings
|
|
57
|
+
* </button>
|
|
58
|
+
* );
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
1
62
|
export declare function useSaaSAuth(): {
|
|
2
|
-
user: import("./types").AuthUser | undefined;
|
|
3
|
-
session: import("./types").AuthSession | null;
|
|
4
|
-
isLoading: boolean;
|
|
5
|
-
isAuthenticated: boolean;
|
|
6
|
-
isRedirecting: boolean;
|
|
7
|
-
status: import("./types").AuthStatus;
|
|
8
63
|
signIn: () => Promise<void>;
|
|
9
64
|
signOut: () => Promise<void>;
|
|
10
65
|
openWorkspaceSettings: (section?: "profile" | "general" | "users" | "features" | "danger") => void;
|
|
66
|
+
isAuthenticated: boolean;
|
|
67
|
+
isLoading: boolean;
|
|
68
|
+
isRedirecting: boolean;
|
|
69
|
+
user: import("./types").AuthUser | undefined;
|
|
70
|
+
session: import("./types").AuthSession | null;
|
|
71
|
+
status: import("./types").AuthStatus;
|
|
11
72
|
};
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { EventData, EventType } from '../events/types';
|
|
2
2
|
export declare enum AuthStatus {
|
|
3
3
|
loading = "loading",
|
|
4
|
+
redirecting = "redirecting",
|
|
4
5
|
authenticated = "authenticated",
|
|
5
6
|
unauthenticated = "unauthenticated",
|
|
6
7
|
authenticating = "authenticating"
|
|
7
8
|
}
|
|
9
|
+
/** Derive booleans from status (single source of truth) */
|
|
10
|
+
export declare function getAuthFlags(status: AuthStatus): {
|
|
11
|
+
isAuthenticated: boolean;
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
isRedirecting: boolean;
|
|
14
|
+
};
|
|
8
15
|
export interface AuthUser {
|
|
9
16
|
id: string;
|
|
10
17
|
name: string;
|
|
@@ -22,9 +29,6 @@ export interface AuthSession {
|
|
|
22
29
|
}
|
|
23
30
|
export interface IAuthState {
|
|
24
31
|
session: AuthSession | null;
|
|
25
|
-
isLoading: boolean;
|
|
26
|
-
isAuthenticated: boolean;
|
|
27
|
-
isRedirecting: boolean;
|
|
28
32
|
status: AuthStatus;
|
|
29
33
|
}
|
|
30
34
|
export interface IAuthConfig {
|
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
import type { ISettings } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to access organization settings from the OS context.
|
|
4
|
+
* Automatically fetches settings when OS config is ready.
|
|
5
|
+
*
|
|
6
|
+
* @returns An object containing:
|
|
7
|
+
* - `settings`: Organization settings object (null if not loaded)
|
|
8
|
+
* - `getSettings(signal?)`: Function to manually fetch settings (supports AbortSignal)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* function SettingsDisplay() {
|
|
13
|
+
* const { settings } = useSaaSSettings();
|
|
14
|
+
*
|
|
15
|
+
* if (!settings) return <Loading />;
|
|
16
|
+
*
|
|
17
|
+
* return (
|
|
18
|
+
* <div>
|
|
19
|
+
* <p>Organization: {settings.name}</p>
|
|
20
|
+
* <p>Theme: {settings.theme}</p>
|
|
21
|
+
* </div>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* // Manual fetch with abort signal
|
|
29
|
+
* function SettingsLoader() {
|
|
30
|
+
* const { getSettings } = useSaaSSettings();
|
|
31
|
+
*
|
|
32
|
+
* useEffect(() => {
|
|
33
|
+
* const controller = new AbortController();
|
|
34
|
+
* getSettings(controller.signal);
|
|
35
|
+
*
|
|
36
|
+
* return () => controller.abort();
|
|
37
|
+
* }, [getSettings]);
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
2
41
|
export declare function useSaaSSettings(): {
|
|
3
42
|
settings: ISettings | null | undefined;
|
|
4
|
-
getSettings: () => Promise<ISettings | null>;
|
|
43
|
+
getSettings: (signal?: AbortSignal) => Promise<ISettings | null>;
|
|
5
44
|
};
|
|
@@ -1,4 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook to access user attributes from the UserProvider.
|
|
3
|
+
* Must be used within a UserProvider component.
|
|
4
|
+
*
|
|
5
|
+
* @returns User context object containing:
|
|
6
|
+
* - `attributes`: Record of user attribute key-value pairs
|
|
7
|
+
* - `isLoading`: Boolean indicating if attributes are being loaded
|
|
8
|
+
* - `error`: Error message string (null if no error)
|
|
9
|
+
* - `refreshAttributes()`: Function to manually refresh attributes
|
|
10
|
+
*
|
|
11
|
+
* @throws {Error} If used outside of UserProvider
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* function UserProfile() {
|
|
16
|
+
* const { attributes, isLoading } = useUserAttributes();
|
|
17
|
+
*
|
|
18
|
+
* if (isLoading) return <Loading />;
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <div>
|
|
22
|
+
* <p>Plan: {attributes?.plan}</p>
|
|
23
|
+
* <p>Company: {attributes?.company}</p>
|
|
24
|
+
* </div>
|
|
25
|
+
* );
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
1
29
|
export declare function useUserAttributes(): import("./provider").UserContextValue;
|
|
30
|
+
/**
|
|
31
|
+
* Hook to access user feature flags from the UserProvider.
|
|
32
|
+
* Must be used within a UserProvider component.
|
|
33
|
+
*
|
|
34
|
+
* @returns An object containing:
|
|
35
|
+
* - `features`: Record of feature flag key-value pairs (boolean values)
|
|
36
|
+
* - `isLoading`: Boolean indicating if features are being loaded
|
|
37
|
+
* - `error`: Error message string (null if no error)
|
|
38
|
+
* - `refreshFeatures()`: Function to manually refresh features
|
|
39
|
+
* - `isFeatureEnabled(featureId)`: Function to check if a specific feature is enabled
|
|
40
|
+
*
|
|
41
|
+
* @throws {Error} If used outside of UserProvider
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* function FeatureContent() {
|
|
46
|
+
* const { isFeatureEnabled, isLoading } = useUserFeatures();
|
|
47
|
+
*
|
|
48
|
+
* if (isLoading) return <Loading />;
|
|
49
|
+
*
|
|
50
|
+
* if (isFeatureEnabled('premium-feature')) {
|
|
51
|
+
* return <PremiumFeature />;
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* return <BasicFeature />;
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* // Check multiple features
|
|
61
|
+
* function Dashboard() {
|
|
62
|
+
* const { isFeatureEnabled } = useUserFeatures();
|
|
63
|
+
*
|
|
64
|
+
* return (
|
|
65
|
+
* <div>
|
|
66
|
+
* {isFeatureEnabled('analytics') && <Analytics />}
|
|
67
|
+
* {isFeatureEnabled('reports') && <Reports />}
|
|
68
|
+
* </div>
|
|
69
|
+
* );
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
2
73
|
export declare function useUserFeatures(): {
|
|
3
74
|
features: Record<string, boolean>;
|
|
4
75
|
isLoading: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IPlanGroupResponse, IPlanGroupVersion, ISubscriptionResponse, ISubscriptionUpdateResponse, IUser } from '../../api/types';
|
|
1
|
+
import { ICheckoutSessionRequest, ICheckoutSessionResponse, IInvoiceListResponse, IInvoiceResponse, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionsResponse, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUser } from '../../api/types';
|
|
2
2
|
import { IOsConfig } from '../os/types';
|
|
3
3
|
import type { IWorkspace, IWorkspaceFeature, IWorkspaceUser } from './types';
|
|
4
4
|
export declare class WorkspaceApi {
|
|
@@ -51,14 +51,54 @@ export declare class WorkspaceApi {
|
|
|
51
51
|
* otherwise returns the latest published group
|
|
52
52
|
*/
|
|
53
53
|
getPlanGroup(workspaceId: string): Promise<IPlanGroupResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* Get plan group for a workspace with a specific version
|
|
56
|
+
* @param workspaceId - The workspace ID
|
|
57
|
+
* @param groupVersionId - The plan group version ID to fetch
|
|
58
|
+
* @returns Plan group response with the specified version
|
|
59
|
+
*/
|
|
60
|
+
getPlanGroupByVersion(workspaceId: string, groupVersionId: string): Promise<IPlanGroupResponse>;
|
|
61
|
+
/**
|
|
62
|
+
* Get current group version and available newer versions of the same group
|
|
63
|
+
* - If user has active subscription: returns their current group version + newer versions
|
|
64
|
+
* - If no subscription: returns the latest published group version
|
|
65
|
+
* Shows what's new in newer versions to help users upgrade
|
|
66
|
+
* Example: User on Group v1 (Basic Plan) can see Group v2 (Basic + Pro Plan)
|
|
67
|
+
* @param workspaceId - The workspace ID
|
|
68
|
+
* @returns Plan group versions response with currentVersion and availableVersions
|
|
69
|
+
*/
|
|
70
|
+
getPlanGroupVersions(workspaceId: string): Promise<IPlanGroupVersionsResponse>;
|
|
54
71
|
/**
|
|
55
72
|
* Get plan group version details by ID
|
|
56
73
|
* Returns the full plan group version with populated plan versions
|
|
57
74
|
*/
|
|
58
75
|
getPlanGroupVersion(groupVersionId: string): Promise<IPlanGroupVersion>;
|
|
76
|
+
/**
|
|
77
|
+
* Create checkout session for new subscription
|
|
78
|
+
* @param workspaceId - The workspace ID
|
|
79
|
+
* @param request - Checkout session request with planVersionId and optional billing interval/URLs
|
|
80
|
+
* @returns Checkout session response with checkoutUrl to redirect user
|
|
81
|
+
*/
|
|
82
|
+
createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest): Promise<ICheckoutSessionResponse>;
|
|
59
83
|
/**
|
|
60
84
|
* Update subscription (upgrade/downgrade)
|
|
61
85
|
* Only allows plan changes within the same plan group
|
|
86
|
+
* Returns checkout session if payment is required, otherwise returns subscription update response
|
|
87
|
+
*/
|
|
88
|
+
updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
|
|
89
|
+
/**
|
|
90
|
+
* List invoices for a workspace subscription
|
|
91
|
+
* @param workspaceId - The workspace ID
|
|
92
|
+
* @param limit - Number of invoices to return (default: 10)
|
|
93
|
+
* @param startingAfter - Invoice ID to start after (for pagination)
|
|
94
|
+
* @returns List of invoices with pagination info
|
|
95
|
+
*/
|
|
96
|
+
listInvoices(workspaceId: string, limit?: number, startingAfter?: string): Promise<IInvoiceListResponse>;
|
|
97
|
+
/**
|
|
98
|
+
* Get a single invoice by ID
|
|
99
|
+
* @param workspaceId - The workspace ID
|
|
100
|
+
* @param invoiceId - The invoice ID
|
|
101
|
+
* @returns Invoice details
|
|
62
102
|
*/
|
|
63
|
-
|
|
103
|
+
getInvoice(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
|
|
64
104
|
}
|
|
@@ -1,6 +1,111 @@
|
|
|
1
1
|
import { IUser } from '../../api/types';
|
|
2
2
|
import { WorkspaceSwitcher } from './provider';
|
|
3
3
|
import { IWorkspace, IWorkspaceUser } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Main workspace management hook for the SDK.
|
|
6
|
+
* Provides workspace state, CRUD operations, and user management.
|
|
7
|
+
*
|
|
8
|
+
* @returns An object containing:
|
|
9
|
+
* - `workspaces`: Array of all workspaces the user has access to
|
|
10
|
+
* - `currentWorkspace`: Currently selected workspace (null if none selected)
|
|
11
|
+
* - `loading`: Boolean indicating if workspaces are being fetched
|
|
12
|
+
* - `error`: Error message string (null if no error)
|
|
13
|
+
* - `refreshing`: Boolean indicating if workspaces are being refreshed in background
|
|
14
|
+
* - `switching`: Boolean indicating if workspace is being switched
|
|
15
|
+
* - `WorkspaceSwitcher`: Component for switching between workspaces
|
|
16
|
+
* - `fetchWorkspaces()`: Function to fetch all workspaces
|
|
17
|
+
* - `refreshWorkspaces()`: Function to refresh workspaces in background (non-blocking)
|
|
18
|
+
* - `setCurrentWorkspace(workspace)`: Function to set the current workspace
|
|
19
|
+
* - `resetCurrentWorkspace()`: Function to clear the current workspace
|
|
20
|
+
* - `createWorkspace(name, image?)`: Function to create a new workspace
|
|
21
|
+
* - `updateWorkspace(workspace, data)`: Function to update a workspace
|
|
22
|
+
* - `deleteWorkspace(workspaceId)`: Function to delete a workspace (owner only)
|
|
23
|
+
* - `getWorkspace(workspaceId)`: Function to fetch a specific workspace
|
|
24
|
+
* - `getUsers(workspaceId)`: Function to fetch users in a workspace
|
|
25
|
+
* - `addUser(workspaceId, email, role)`: Function to add a user to a workspace
|
|
26
|
+
* - `removeUser(workspaceId, userId)`: Function to remove a user from a workspace
|
|
27
|
+
* - `updateUser(workspaceId, userId, config)`: Function to update a user in a workspace
|
|
28
|
+
* - `getProfile()`: Function to fetch current user profile
|
|
29
|
+
* - `updateUserProfile(config)`: Function to update current user profile
|
|
30
|
+
* - `allFeatures`: Array of all available feature flags
|
|
31
|
+
* - `getFeatures()`: Function to fetch all available features
|
|
32
|
+
* - `updateFeature(workspaceId, key, value)`: Function to update a feature flag
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* function WorkspaceList() {
|
|
37
|
+
* const { workspaces, loading, fetchWorkspaces } = useSaaSWorkspaces();
|
|
38
|
+
*
|
|
39
|
+
* useEffect(() => {
|
|
40
|
+
* fetchWorkspaces();
|
|
41
|
+
* }, [fetchWorkspaces]);
|
|
42
|
+
*
|
|
43
|
+
* if (loading) return <Loading />;
|
|
44
|
+
*
|
|
45
|
+
* return (
|
|
46
|
+
* <ul>
|
|
47
|
+
* {workspaces.map(ws => (
|
|
48
|
+
* <li key={ws._id}>{ws.name}</li>
|
|
49
|
+
* ))}
|
|
50
|
+
* </ul>
|
|
51
|
+
* );
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```tsx
|
|
57
|
+
* // Create a new workspace
|
|
58
|
+
* function CreateWorkspace() {
|
|
59
|
+
* const { createWorkspace } = useSaaSWorkspaces();
|
|
60
|
+
*
|
|
61
|
+
* const handleCreate = async () => {
|
|
62
|
+
* try {
|
|
63
|
+
* await createWorkspace('My Workspace', 'https://example.com/logo.png');
|
|
64
|
+
* } catch (error) {
|
|
65
|
+
* console.error('Failed to create workspace:', error);
|
|
66
|
+
* }
|
|
67
|
+
* };
|
|
68
|
+
*
|
|
69
|
+
* return <button onClick={handleCreate}>Create Workspace</button>;
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* // Delete workspace (owner only)
|
|
76
|
+
* function DeleteWorkspaceButton({ workspaceId }) {
|
|
77
|
+
* const { deleteWorkspace } = useSaaSWorkspaces();
|
|
78
|
+
*
|
|
79
|
+
* const handleDelete = async () => {
|
|
80
|
+
* if (!confirm('Are you sure?')) return;
|
|
81
|
+
* try {
|
|
82
|
+
* await deleteWorkspace(workspaceId);
|
|
83
|
+
* } catch (error) {
|
|
84
|
+
* // Error: "Only the workspace creator can delete the workspace"
|
|
85
|
+
* alert(error.message);
|
|
86
|
+
* }
|
|
87
|
+
* };
|
|
88
|
+
*
|
|
89
|
+
* return <button onClick={handleDelete}>Delete</button>;
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```tsx
|
|
95
|
+
* // Edge case: Workspace removed from user's access
|
|
96
|
+
* function WorkspaceContent() {
|
|
97
|
+
* const { currentWorkspace, workspaces } = useSaaSWorkspaces();
|
|
98
|
+
*
|
|
99
|
+
* // If current workspace is not in the list, it was removed
|
|
100
|
+
* // The hook automatically switches to first available workspace
|
|
101
|
+
* if (!currentWorkspace) {
|
|
102
|
+
* return <p>No workspace selected</p>;
|
|
103
|
+
* }
|
|
104
|
+
*
|
|
105
|
+
* return <div>{currentWorkspace.name}</div>;
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
4
109
|
export declare const useSaaSWorkspaces: () => {
|
|
5
110
|
workspaces: IWorkspace[];
|
|
6
111
|
loading: boolean;
|