@buildbase/sdk 0.0.15 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -98
- package/dist/index.d.ts +395 -168
- package/dist/index.esm.js +5 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/saas-os.css +1 -1
- package/dist/types/api/index.d.ts +6 -0
- package/dist/types/api/quota-utils.d.ts +24 -0
- package/dist/types/api/types.d.ts +40 -15
- package/dist/types/components/beta/api.d.ts +1 -2
- package/dist/types/components/pricing/PricingPage.d.ts +1 -1
- package/dist/types/components/subscription/index.d.ts +108 -0
- package/dist/types/contexts/SubscriptionContext/SubscriptionContext.d.ts +22 -0
- package/dist/types/contexts/SubscriptionContext/index.d.ts +2 -0
- package/dist/types/contexts/SubscriptionContext/subscriptionInvalidation.d.ts +19 -0
- package/dist/types/contexts/SubscriptionContext/types.d.ts +12 -0
- package/dist/types/contexts/index.d.ts +2 -0
- package/dist/types/contexts/shared/types.d.ts +21 -0
- package/dist/types/contexts/shared/useAppDispatch.d.ts +2 -12
- package/dist/types/contexts/shared/useAppSelector.d.ts +2 -12
- package/dist/types/contexts/shared/utils/reducerHelpers.d.ts +2 -2
- package/dist/types/index.d.ts +9 -2
- package/dist/types/lib/api-base.d.ts +49 -0
- package/dist/types/providers/ContextConfigProvider.d.ts +1 -1
- package/dist/types/providers/auth/api.d.ts +12 -0
- package/dist/types/providers/auth/hooks.d.ts +2 -0
- package/dist/types/providers/os/api.d.ts +11 -0
- package/dist/types/providers/os/hooks.d.ts +6 -0
- package/dist/types/providers/os/types.d.ts +2 -0
- package/dist/types/providers/user/api.d.ts +16 -0
- package/dist/types/providers/user/hooks.d.ts +1 -0
- package/dist/types/providers/workspace/api.d.ts +16 -5
- package/dist/types/providers/workspace/hooks.d.ts +10 -0
- package/dist/types/providers/workspace/subscription-hooks.d.ts +81 -1
- package/dist/types/providers/workspace/ui/SubscriptionDialog.d.ts +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ A React SDK for [BuildBase](https://www.buildbase.app/) that provides essential
|
|
|
10
10
|
- [Authentication](#-authentication)
|
|
11
11
|
- [Role-Based Access Control](#-role-based-access-control)
|
|
12
12
|
- [Feature Flags](#️-feature-flags)
|
|
13
|
+
- [Subscription Gates](#-subscription-gates)
|
|
13
14
|
- [User Management](#-user-management)
|
|
14
15
|
- [Workspace Management](#-complete-workspace-management)
|
|
15
16
|
- [Public Pricing (No Login)](#-public-pricing-no-login)
|
|
@@ -22,6 +23,7 @@ A React SDK for [BuildBase](https://www.buildbase.app/) that provides essential
|
|
|
22
23
|
- [Troubleshooting](#-troubleshooting)
|
|
23
24
|
- [API Reference](#-api-reference)
|
|
24
25
|
- [Best Practices](#-best-practices)
|
|
26
|
+
- [Documentation](#further-documentation)
|
|
25
27
|
|
|
26
28
|
## 🚀 Features
|
|
27
29
|
|
|
@@ -29,6 +31,7 @@ A React SDK for [BuildBase](https://www.buildbase.app/) that provides essential
|
|
|
29
31
|
- **🏢 Workspace Management** - Multi-workspace support with switching capabilities
|
|
30
32
|
- **👥 Role-Based Access Control** - User roles and workspace-specific permissions
|
|
31
33
|
- **🎯 Feature Flags** - Workspace-level and user-level feature toggles
|
|
34
|
+
- **📋 Subscription Gates** - Show or hide UI based on current workspace subscription (plan)
|
|
32
35
|
- **👤 User Management** - User attributes and feature flags management
|
|
33
36
|
- **📝 Beta Form** - Pre-built signup/waitlist form component
|
|
34
37
|
- **📡 Event System** - Subscribe to user and workspace events
|
|
@@ -315,6 +318,103 @@ function FeatureExample() {
|
|
|
315
318
|
|
|
316
319
|
Use the `useUserFeatures` hook to check feature flags programmatically:
|
|
317
320
|
|
|
321
|
+
## 📋 Subscription Gates
|
|
322
|
+
|
|
323
|
+
Control UI visibility based on the current workspace’s subscription. Subscription data is loaded once per workspace and refetched when the workspace changes or when the subscription is updated (e.g. upgrade, cancel, resume).
|
|
324
|
+
|
|
325
|
+
**SubscriptionContextProvider** is included in **SaaSOSProvider** by default, so subscription gates work without extra setup.
|
|
326
|
+
|
|
327
|
+
### Subscription Gate Components
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
import { WhenSubscription, WhenNoSubscription, WhenSubscriptionToPlans } from '@buildbase/sdk';
|
|
331
|
+
|
|
332
|
+
function BillingExample() {
|
|
333
|
+
return (
|
|
334
|
+
<div>
|
|
335
|
+
{/* Show when workspace has any active subscription */}
|
|
336
|
+
<WhenSubscription>
|
|
337
|
+
<BillingSettings />
|
|
338
|
+
</WhenSubscription>
|
|
339
|
+
|
|
340
|
+
{/* Show when workspace has no subscription */}
|
|
341
|
+
<WhenNoSubscription>
|
|
342
|
+
<UpgradePrompt />
|
|
343
|
+
</WhenNoSubscription>
|
|
344
|
+
|
|
345
|
+
{/* Show only when subscribed to specific plans (by slug, case-insensitive) */}
|
|
346
|
+
<WhenSubscriptionToPlans plans={['pro', 'enterprise']}>
|
|
347
|
+
<AdvancedAnalytics />
|
|
348
|
+
</WhenSubscriptionToPlans>
|
|
349
|
+
</div>
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
| Component | Renders when |
|
|
355
|
+
| ------------------------- | -------------------------------------------------------------------- |
|
|
356
|
+
| `WhenSubscription` | Current workspace has an active subscription (any plan); not loading |
|
|
357
|
+
| `WhenNoSubscription` | Current workspace has no subscription (or no workspace); not loading |
|
|
358
|
+
| `WhenSubscriptionToPlans` | Current workspace is subscribed to one of the given plan slugs |
|
|
359
|
+
|
|
360
|
+
All gates must be used inside **SubscriptionContextProvider** (included in SaaSOSProvider). By default they return `null` while loading or when the condition is not met. You can pass optional **loadingComponent** (component/element to show while loading) and **fallbackComponent** (component/element to show when condition is not met):
|
|
361
|
+
|
|
362
|
+
```tsx
|
|
363
|
+
<WhenSubscription
|
|
364
|
+
loadingComponent={<Skeleton className="h-20" />}
|
|
365
|
+
fallbackComponent={<UpgradePrompt />}
|
|
366
|
+
>
|
|
367
|
+
<BillingSettings />
|
|
368
|
+
</WhenSubscription>
|
|
369
|
+
|
|
370
|
+
<WhenSubscriptionToPlans
|
|
371
|
+
plans={['pro', 'enterprise']}
|
|
372
|
+
loadingComponent={<Spinner />}
|
|
373
|
+
fallbackComponent={<p>Upgrade to Pro or Enterprise to access this feature.</p>}
|
|
374
|
+
>
|
|
375
|
+
<AdvancedAnalytics />
|
|
376
|
+
</WhenSubscriptionToPlans>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### useSubscriptionContext
|
|
380
|
+
|
|
381
|
+
Use the hook when you need subscription data or a manual refetch (e.g. after returning from Stripe checkout):
|
|
382
|
+
|
|
383
|
+
```tsx
|
|
384
|
+
import { useSubscriptionContext } from '@buildbase/sdk';
|
|
385
|
+
|
|
386
|
+
function SubscriptionStatus() {
|
|
387
|
+
const { response, loading, refetch } = useSubscriptionContext();
|
|
388
|
+
|
|
389
|
+
if (loading) return <Spinner />;
|
|
390
|
+
if (!response?.subscription) return <p>No active subscription</p>;
|
|
391
|
+
|
|
392
|
+
const plan = response.plan ?? response.subscription?.plan;
|
|
393
|
+
return (
|
|
394
|
+
<div>
|
|
395
|
+
<p>Plan: {plan?.name ?? plan?.slug}</p>
|
|
396
|
+
<button onClick={() => refetch()}>Refresh</button>
|
|
397
|
+
</div>
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
| Property | Type | Description |
|
|
403
|
+
| ---------- | ------------------------------- | ------------------------------------------------------ |
|
|
404
|
+
| `response` | `ISubscriptionResponse \| null` | Current subscription data for the current workspace |
|
|
405
|
+
| `loading` | `boolean` | True while subscription is being fetched |
|
|
406
|
+
| `refetch` | `() => Promise<void>` | Manually refetch subscription (e.g. after plan change) |
|
|
407
|
+
|
|
408
|
+
**When subscription refetches**
|
|
409
|
+
|
|
410
|
+
- When the current workspace changes (automatic).
|
|
411
|
+
- When subscription is updated via SDK (e.g. `useUpdateSubscription`, cancel, resume) — refetch is triggered automatically.
|
|
412
|
+
- When you call `refetch()` (e.g. after redirect from checkout).
|
|
413
|
+
|
|
414
|
+
### Feature Flags Hook
|
|
415
|
+
|
|
416
|
+
Use the `useUserFeatures` hook to check feature flags programmatically:
|
|
417
|
+
|
|
318
418
|
```tsx
|
|
319
419
|
import { useUserFeatures } from '@buildbase/sdk';
|
|
320
420
|
|
|
@@ -375,6 +475,7 @@ function WorkspaceManager() {
|
|
|
375
475
|
loading, // Loading state
|
|
376
476
|
refreshing, // Refreshing state
|
|
377
477
|
switching, // True when a workspace switch is in progress
|
|
478
|
+
switchingToId, // Workspace ID currently being switched to (null when not switching)
|
|
378
479
|
error, // Error message
|
|
379
480
|
fetchWorkspaces, // Fetch all workspaces
|
|
380
481
|
refreshWorkspaces, // Background refresh
|
|
@@ -461,12 +562,12 @@ function PublicPricingPage() {
|
|
|
461
562
|
}
|
|
462
563
|
```
|
|
463
564
|
|
|
464
|
-
| Prop
|
|
465
|
-
|
|
466
|
-
| `slug`
|
|
467
|
-
| `children`
|
|
468
|
-
| `loadingFallback` | `ReactNode`
|
|
469
|
-
| `errorFallback`
|
|
565
|
+
| Prop | Type | Description |
|
|
566
|
+
| ----------------- | ------------------------------ | ----------------------------------------------------------------- |
|
|
567
|
+
| `slug` | `string` | Plan group slug (e.g. 'main-pricing', 'enterprise') |
|
|
568
|
+
| `children` | `(details) => ReactNode` | Render prop receiving `{ loading, error, items, plans, refetch }` |
|
|
569
|
+
| `loadingFallback` | `ReactNode` | Custom loading UI (defaults to skeleton) |
|
|
570
|
+
| `errorFallback` | `(error: string) => ReactNode` | Custom error UI |
|
|
470
571
|
|
|
471
572
|
**Response shape**: `items` = subscription item definitions (features, limits, quotas with category); `plans` = plan versions with `pricing`, `quotas`, `features`, `limits`.
|
|
472
573
|
|
|
@@ -539,41 +640,7 @@ import { SaaSOSProvider, eventEmitter } from '@buildbase/sdk';
|
|
|
539
640
|
|
|
540
641
|
## 🛡️ Error Handling
|
|
541
642
|
|
|
542
|
-
The SDK
|
|
543
|
-
|
|
544
|
-
```tsx
|
|
545
|
-
import { ErrorBoundary, SDKError, handleError, errorHandler } from '@buildbase/sdk';
|
|
546
|
-
|
|
547
|
-
// Wrap your app with ErrorBoundary
|
|
548
|
-
function App() {
|
|
549
|
-
return (
|
|
550
|
-
<ErrorBoundary>
|
|
551
|
-
<YourApp />
|
|
552
|
-
</ErrorBoundary>
|
|
553
|
-
);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Configure error handler
|
|
557
|
-
errorHandler.configure({
|
|
558
|
-
enableConsoleLogging: true,
|
|
559
|
-
showUserNotifications: false,
|
|
560
|
-
onError: (error, context) => {
|
|
561
|
-
// Custom error handling
|
|
562
|
-
console.error('SDK Error:', error, context);
|
|
563
|
-
},
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
// Use handleError in your code
|
|
567
|
-
try {
|
|
568
|
-
// Some operation
|
|
569
|
-
} catch (error) {
|
|
570
|
-
handleError(error, {
|
|
571
|
-
component: 'MyComponent',
|
|
572
|
-
action: 'handleSubmit',
|
|
573
|
-
metadata: { userId: '123' },
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
```
|
|
643
|
+
The SDK handles errors internally: API failures, auth errors, and component errors are logged and surfaced through hook states (e.g. `error` from `useSaaSWorkspaces`) and callbacks. Wrap your app in an error boundary of your choice to catch React errors. For failed operations, check the `error` property on hooks and handle it in your UI (e.g. toast or inline message).
|
|
577
644
|
|
|
578
645
|
## ⚙️ Settings
|
|
579
646
|
|
|
@@ -595,6 +662,52 @@ function SettingsExample() {
|
|
|
595
662
|
|
|
596
663
|
## 📚 API Reference
|
|
597
664
|
|
|
665
|
+
### Central APIs
|
|
666
|
+
|
|
667
|
+
All SDK API clients extend a shared base class and are exported from the package:
|
|
668
|
+
|
|
669
|
+
| Export | Purpose |
|
|
670
|
+
| ---------------- | ------------------------------------------------------------------------------- |
|
|
671
|
+
| `BaseApi` | Abstract base (URL, auth, `fetchJson`/`fetchResponse`) – extend for custom APIs |
|
|
672
|
+
| `IBaseApiConfig` | Config type: `serverUrl`, `version`, optional `orgId` |
|
|
673
|
+
| `UserApi` | User attributes and features |
|
|
674
|
+
| `WorkspaceApi` | Workspaces, subscription, invoices, users |
|
|
675
|
+
| `SettingsApi` | Organization settings |
|
|
676
|
+
|
|
677
|
+
Use the hooks (`useUserApi`, `useWorkspaceApi`, etc.) for a ready-made instance with OS config, or instantiate with your own config:
|
|
678
|
+
|
|
679
|
+
```tsx
|
|
680
|
+
import { UserApi, WorkspaceApi, SettingsApi, useSaaSOs } from '@buildbase/sdk';
|
|
681
|
+
|
|
682
|
+
// Via hook (uses OS config from context)
|
|
683
|
+
const api = useWorkspaceApi(); // or useUserApi(), etc.
|
|
684
|
+
|
|
685
|
+
// Or instantiate with config
|
|
686
|
+
const os = useSaaSOs();
|
|
687
|
+
const workspaceApi = new WorkspaceApi({
|
|
688
|
+
serverUrl: os.serverUrl,
|
|
689
|
+
version: os.version,
|
|
690
|
+
orgId: os.orgId,
|
|
691
|
+
});
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Hooks
|
|
695
|
+
|
|
696
|
+
Prefer these SDK hooks for state and operations instead of `useAppSelector`:
|
|
697
|
+
|
|
698
|
+
| Hook | Purpose |
|
|
699
|
+
| -------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
700
|
+
| `useSaaSAuth()` | Auth state (user, session, status), signIn, signOut, openWorkspaceSettings |
|
|
701
|
+
| `useSaaSWorkspaces()` | Workspaces, currentWorkspace, loading, switching/switchingToId, CRUD and switch actions |
|
|
702
|
+
| `useSaaSOs()` | OS config (serverUrl, version, orgId, auth, settings) when you need the full config object |
|
|
703
|
+
| `useSaaSSettings()` | Organization settings and getSettings (prefer this when you only need settings) |
|
|
704
|
+
| `useUserAttributes()` | User attributes and update/refresh |
|
|
705
|
+
| `useUserFeatures()` | User feature flags |
|
|
706
|
+
| `useSubscriptionContext()` | Subscription for current workspace (response, loading, refetch); use inside SubscriptionContextProvider |
|
|
707
|
+
| Subscription hooks | `usePublicPlans`, `useSubscription`, `usePlanGroup`, etc. |
|
|
708
|
+
|
|
709
|
+
Using hooks keeps your code stable if internal state shape changes and avoids direct Redux/context coupling.
|
|
710
|
+
|
|
598
711
|
### Enums
|
|
599
712
|
|
|
600
713
|
- `ApiVersion` - API version enum (currently only `V1`)
|
|
@@ -604,6 +717,11 @@ function SettingsExample() {
|
|
|
604
717
|
|
|
605
718
|
All TypeScript types are exported for type safety. See the [TypeScript definitions](./dist/index.d.ts) for complete type information.
|
|
606
719
|
|
|
720
|
+
### Further documentation
|
|
721
|
+
|
|
722
|
+
- [Architecture](docs/ARCHITECTURE.md) – Layers, APIs (BaseApi, UserApi, WorkspaceApi, SettingsApi), state, auth flow
|
|
723
|
+
- [Error codes](docs/ERROR_CODES.md) – SDK error codes and HTTP status mappings
|
|
724
|
+
|
|
607
725
|
## ⚙️ Configuration Reference
|
|
608
726
|
|
|
609
727
|
### SaaSOSProvider Props
|
|
@@ -752,6 +870,32 @@ function Dashboard() {
|
|
|
752
870
|
}
|
|
753
871
|
```
|
|
754
872
|
|
|
873
|
+
### Pattern 4b: Subscription-Gated UI
|
|
874
|
+
|
|
875
|
+
```tsx
|
|
876
|
+
import { WhenSubscription, WhenNoSubscription, WhenSubscriptionToPlans } from '@buildbase/sdk';
|
|
877
|
+
|
|
878
|
+
function BillingPage() {
|
|
879
|
+
return (
|
|
880
|
+
<div>
|
|
881
|
+
<WhenNoSubscription>
|
|
882
|
+
<UpgradePrompt />
|
|
883
|
+
</WhenNoSubscription>
|
|
884
|
+
|
|
885
|
+
<WhenSubscription>
|
|
886
|
+
<BillingSettings />
|
|
887
|
+
</WhenSubscription>
|
|
888
|
+
|
|
889
|
+
<WhenSubscriptionToPlans plans={['pro', 'enterprise']}>
|
|
890
|
+
<AdvancedBillingFeatures />
|
|
891
|
+
</WhenSubscriptionToPlans>
|
|
892
|
+
</div>
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
SubscriptionContextProvider is included in SaaSOSProvider by default, so no extra wrapper is needed.
|
|
898
|
+
|
|
755
899
|
### Pattern 5: Handling Workspace Changes
|
|
756
900
|
|
|
757
901
|
```tsx
|
|
@@ -769,7 +913,7 @@ function App() {
|
|
|
769
913
|
}
|
|
770
914
|
}, [currentWorkspace]);
|
|
771
915
|
|
|
772
|
-
// Show loading during switch
|
|
916
|
+
// Show loading during switch; use switchingToId for the workspace ID being switched to
|
|
773
917
|
if (switching) return <LoadingOverlay />;
|
|
774
918
|
|
|
775
919
|
return <YourApp />;
|
|
@@ -778,37 +922,9 @@ function App() {
|
|
|
778
922
|
|
|
779
923
|
For token generation or prep before switching, configure `onWorkspaceChange` in auth callbacks (see Quick Start)—it receives `{ workspace, user, role }`.
|
|
780
924
|
|
|
781
|
-
### Pattern 6: Error Boundary
|
|
782
|
-
|
|
783
|
-
```tsx
|
|
784
|
-
import { ErrorBoundary, SDKError } from '@buildbase/sdk';
|
|
785
|
-
|
|
786
|
-
function CustomErrorFallback({ error, resetError }) {
|
|
787
|
-
if (error instanceof SDKError) {
|
|
788
|
-
return (
|
|
789
|
-
<div>
|
|
790
|
-
<h2>SDK Error: {error.message}</h2>
|
|
791
|
-
<button onClick={resetError}>Try Again</button>
|
|
792
|
-
</div>
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
return (
|
|
797
|
-
<div>
|
|
798
|
-
<h2>Something went wrong</h2>
|
|
799
|
-
<button onClick={resetError}>Reload</button>
|
|
800
|
-
</div>
|
|
801
|
-
);
|
|
802
|
-
}
|
|
925
|
+
### Pattern 6: Error Boundary
|
|
803
926
|
|
|
804
|
-
|
|
805
|
-
return (
|
|
806
|
-
<ErrorBoundary fallback={CustomErrorFallback}>
|
|
807
|
-
<YourApp />
|
|
808
|
-
</ErrorBoundary>
|
|
809
|
-
);
|
|
810
|
-
}
|
|
811
|
-
```
|
|
927
|
+
Wrap your app (or a subtree) with an error boundary to catch React errors and show a fallback. Use your framework’s boundary (e.g. React’s `ErrorBoundary` or Next.js error UI). In catch blocks for async operations, show user feedback (e.g. toast or inline message) using the `error` state from hooks.
|
|
812
928
|
|
|
813
929
|
## 🔧 Troubleshooting
|
|
814
930
|
|
|
@@ -984,39 +1100,33 @@ function App() {
|
|
|
984
1100
|
|
|
985
1101
|
### 2. Error Handling
|
|
986
1102
|
|
|
987
|
-
✅ **Do**: Wrap your app with
|
|
1103
|
+
✅ **Do**: Wrap your app with an error boundary (your framework’s or React’s) to catch render errors.
|
|
988
1104
|
|
|
989
|
-
|
|
990
|
-
// ✅ Good
|
|
991
|
-
<ErrorBoundary>
|
|
992
|
-
<SaaSOSProvider {...config}>
|
|
993
|
-
<App />
|
|
994
|
-
</SaaSOSProvider>
|
|
995
|
-
</ErrorBoundary>
|
|
996
|
-
```
|
|
1105
|
+
✅ **Do**: Handle async failures using the `error` from hooks and show user feedback (e.g. toast or inline message).
|
|
997
1106
|
|
|
998
|
-
|
|
1107
|
+
### 3. State Access: Prefer SDK Hooks Over useAppSelector
|
|
1108
|
+
|
|
1109
|
+
✅ **Do**: Use SDK hooks for auth, workspace, and OS state.
|
|
999
1110
|
|
|
1000
1111
|
```tsx
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
action: 'operation',
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1112
|
+
// ✅ Good – use hooks
|
|
1113
|
+
const { user, isAuthenticated } = useSaaSAuth();
|
|
1114
|
+
const { workspaces, currentWorkspace, switchingToId } = useSaaSWorkspaces();
|
|
1115
|
+
const { settings } = useSaaSSettings();
|
|
1116
|
+
const os = useSaaSOs(); // when you need full OS config (serverUrl, version, orgId, etc.)
|
|
1009
1117
|
```
|
|
1010
1118
|
|
|
1011
|
-
|
|
1119
|
+
❌ **Don't**: Use `useAppSelector(state => state.auth)` or similar in app code—prefer the hooks above so the SDK can evolve internal state without breaking you.
|
|
1120
|
+
|
|
1121
|
+
### 4. Workspace Management
|
|
1012
1122
|
|
|
1013
1123
|
✅ **Do**: Use `useSaaSWorkspaces` hook for workspace operations.
|
|
1014
1124
|
|
|
1015
1125
|
```tsx
|
|
1016
1126
|
// ✅ Good
|
|
1017
|
-
const { currentWorkspace, switchToWorkspace, switching } = useSaaSWorkspaces();
|
|
1127
|
+
const { currentWorkspace, switchToWorkspace, switching, switchingToId } = useSaaSWorkspaces();
|
|
1018
1128
|
// switchToWorkspace: runs onWorkspaceChange first (token gen, etc.)
|
|
1019
|
-
// switching: true when switch is in progress
|
|
1129
|
+
// switching: true when switch is in progress; switchingToId: workspace ID being switched to
|
|
1020
1130
|
```
|
|
1021
1131
|
|
|
1022
1132
|
✅ **Do**: Configure `onWorkspaceChange` in auth callbacks for token generation—receives `{ workspace, user, role }`.
|
|
@@ -1028,7 +1138,7 @@ const { currentWorkspace, switchToWorkspace, switching } = useSaaSWorkspaces();
|
|
|
1028
1138
|
const [workspace, setWorkspace] = useState(null); // Don't do this
|
|
1029
1139
|
```
|
|
1030
1140
|
|
|
1031
|
-
###
|
|
1141
|
+
### 5. Feature Flags
|
|
1032
1142
|
|
|
1033
1143
|
✅ **Do**: Use feature flag components for conditional rendering.
|
|
1034
1144
|
|
|
@@ -1049,7 +1159,7 @@ if (isFeatureEnabled('premium')) {
|
|
|
1049
1159
|
}
|
|
1050
1160
|
```
|
|
1051
1161
|
|
|
1052
|
-
###
|
|
1162
|
+
### 6. Authentication
|
|
1053
1163
|
|
|
1054
1164
|
✅ **Do**: Use `WhenAuthenticated`/`WhenUnauthenticated` for route protection.
|
|
1055
1165
|
|
|
@@ -1070,7 +1180,7 @@ const { signIn, status } = useSaaSAuth();
|
|
|
1070
1180
|
</button>;
|
|
1071
1181
|
```
|
|
1072
1182
|
|
|
1073
|
-
###
|
|
1183
|
+
### 7. Event Handling
|
|
1074
1184
|
|
|
1075
1185
|
✅ **Do**: Handle events in your provider configuration. Use `onWorkspaceChange` for prep before switch (e.g. generate token), and `handleEvent` for post-switch notifications.
|
|
1076
1186
|
|
|
@@ -1092,7 +1202,7 @@ const { signIn, status } = useSaaSAuth();
|
|
|
1092
1202
|
>
|
|
1093
1203
|
```
|
|
1094
1204
|
|
|
1095
|
-
###
|
|
1205
|
+
### 8. TypeScript
|
|
1096
1206
|
|
|
1097
1207
|
✅ **Do**: Use TypeScript for better type safety.
|
|
1098
1208
|
|
|
@@ -1105,7 +1215,7 @@ function MyComponent({ workspace }: { workspace: IWorkspace }) {
|
|
|
1105
1215
|
}
|
|
1106
1216
|
```
|
|
1107
1217
|
|
|
1108
|
-
###
|
|
1218
|
+
### 9. Performance
|
|
1109
1219
|
|
|
1110
1220
|
✅ **Do**: Memoize expensive computations.
|
|
1111
1221
|
|