@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/index.d.ts
CHANGED
|
@@ -38,7 +38,13 @@ interface ISubscriptionItem {
|
|
|
38
38
|
}
|
|
39
39
|
interface IQuotaValue {
|
|
40
40
|
included: number;
|
|
41
|
-
overage
|
|
41
|
+
overage?: number;
|
|
42
|
+
stripePriceId?: string;
|
|
43
|
+
}
|
|
44
|
+
interface IBasePricing {
|
|
45
|
+
monthly: number;
|
|
46
|
+
yearly: number;
|
|
47
|
+
quarterly: number;
|
|
42
48
|
}
|
|
43
49
|
interface IPlanVersion {
|
|
44
50
|
_id: string;
|
|
@@ -48,7 +54,11 @@ interface IPlanVersion {
|
|
|
48
54
|
features?: Record<string, boolean>;
|
|
49
55
|
limits?: Record<string, number>;
|
|
50
56
|
quotas?: Record<string, number | IQuotaValue>;
|
|
57
|
+
basePricing?: IBasePricing;
|
|
51
58
|
stripePrices?: {
|
|
59
|
+
monthlyPriceId?: string;
|
|
60
|
+
yearlyPriceId?: string;
|
|
61
|
+
quarterlyPriceId?: string;
|
|
52
62
|
monthly?: string;
|
|
53
63
|
yearly?: string;
|
|
54
64
|
};
|
|
@@ -129,13 +139,59 @@ interface ISubscriptionResponse {
|
|
|
129
139
|
interface IPlanVersionWithPlan extends IPlanVersion {
|
|
130
140
|
plan: IPlan;
|
|
131
141
|
}
|
|
132
|
-
interface
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
interface IPlanGroupVersionWithPlans {
|
|
143
|
+
_id: string;
|
|
144
|
+
version: number;
|
|
145
|
+
description?: string;
|
|
135
146
|
plans: IPlanVersionWithPlan[];
|
|
147
|
+
isCurrent?: boolean;
|
|
148
|
+
whatsNew?: {
|
|
149
|
+
newPlans: IPlanVersionWithPlan[];
|
|
150
|
+
updatedPlans: IPlanVersionWithPlan[];
|
|
151
|
+
removedPlans: IPlanVersionWithPlan[];
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
interface IPlanGroupResponse {
|
|
155
|
+
group: {
|
|
156
|
+
_id: string;
|
|
157
|
+
name: string;
|
|
158
|
+
slug: string;
|
|
159
|
+
};
|
|
160
|
+
currentVersion: IPlanGroupVersionWithPlans;
|
|
161
|
+
availableVersions: IPlanGroupVersionWithPlans[];
|
|
162
|
+
}
|
|
163
|
+
interface IPlanGroupVersionsResponse {
|
|
164
|
+
group: {
|
|
165
|
+
_id: string;
|
|
166
|
+
name: string;
|
|
167
|
+
slug: string;
|
|
168
|
+
};
|
|
169
|
+
currentVersion: IPlanGroupVersionWithPlans;
|
|
170
|
+
availableVersions: IPlanGroupVersionWithPlans[];
|
|
171
|
+
}
|
|
172
|
+
type BillingInterval = 'monthly' | 'yearly' | 'quarterly';
|
|
173
|
+
interface ICheckoutSessionRequest {
|
|
174
|
+
planVersionId: string;
|
|
175
|
+
billingInterval?: BillingInterval;
|
|
176
|
+
successUrl?: string;
|
|
177
|
+
cancelUrl?: string;
|
|
178
|
+
}
|
|
179
|
+
interface ICheckoutSessionResponse {
|
|
180
|
+
success: boolean;
|
|
181
|
+
checkoutUrl: string;
|
|
182
|
+
sessionId: string;
|
|
183
|
+
message: string;
|
|
184
|
+
planVersion?: {
|
|
185
|
+
_id: string;
|
|
186
|
+
version: number;
|
|
187
|
+
name: string;
|
|
188
|
+
};
|
|
136
189
|
}
|
|
137
190
|
interface ISubscriptionUpdateRequest {
|
|
138
191
|
planVersionId: string;
|
|
192
|
+
billingInterval?: BillingInterval;
|
|
193
|
+
successUrl?: string;
|
|
194
|
+
cancelUrl?: string;
|
|
139
195
|
}
|
|
140
196
|
interface ISubscriptionUpdateResponse {
|
|
141
197
|
_id: string;
|
|
@@ -149,6 +205,29 @@ interface ISubscriptionUpdateResponse {
|
|
|
149
205
|
createdAt: string;
|
|
150
206
|
updatedAt: string;
|
|
151
207
|
}
|
|
208
|
+
type InvoiceStatus = 'draft' | 'open' | 'paid' | 'uncollectible' | 'void';
|
|
209
|
+
interface IInvoice {
|
|
210
|
+
id: string;
|
|
211
|
+
amount_due: number;
|
|
212
|
+
amount_paid: number;
|
|
213
|
+
currency: string;
|
|
214
|
+
status: InvoiceStatus;
|
|
215
|
+
created: number;
|
|
216
|
+
due_date: number | null;
|
|
217
|
+
hosted_invoice_url: string;
|
|
218
|
+
invoice_pdf: string | null;
|
|
219
|
+
description: string | null;
|
|
220
|
+
subscription: string;
|
|
221
|
+
}
|
|
222
|
+
interface IInvoiceListResponse {
|
|
223
|
+
success: boolean;
|
|
224
|
+
invoices: IInvoice[];
|
|
225
|
+
has_more: boolean;
|
|
226
|
+
}
|
|
227
|
+
interface IInvoiceResponse {
|
|
228
|
+
success: boolean;
|
|
229
|
+
invoice: IInvoice;
|
|
230
|
+
}
|
|
152
231
|
|
|
153
232
|
interface IWorkspace {
|
|
154
233
|
_id: string;
|
|
@@ -240,6 +319,7 @@ interface IEventCallbacks {
|
|
|
240
319
|
|
|
241
320
|
declare enum AuthStatus {
|
|
242
321
|
loading = "loading",
|
|
322
|
+
redirecting = "redirecting",
|
|
243
323
|
authenticated = "authenticated",
|
|
244
324
|
unauthenticated = "unauthenticated",
|
|
245
325
|
authenticating = "authenticating"
|
|
@@ -334,7 +414,71 @@ declare const BetaForm: react__default.FC<BetaFormProps>;
|
|
|
334
414
|
interface IProps$2 {
|
|
335
415
|
children: React.ReactNode;
|
|
336
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Conditional component that renders children only when user is authenticated.
|
|
419
|
+
* Returns null if user is not authenticated or authentication status is still loading.
|
|
420
|
+
*
|
|
421
|
+
* @param props - Component props
|
|
422
|
+
* @param props.children - Content to render when authenticated
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```tsx
|
|
426
|
+
* function App() {
|
|
427
|
+
* return (
|
|
428
|
+
* <SaaSOSProvider {...config}>
|
|
429
|
+
* <WhenAuthenticated>
|
|
430
|
+
* <Dashboard />
|
|
431
|
+
* </WhenAuthenticated>
|
|
432
|
+
* <WhenUnauthenticated>
|
|
433
|
+
* <LoginPage />
|
|
434
|
+
* </WhenUnauthenticated>
|
|
435
|
+
* </SaaSOSProvider>
|
|
436
|
+
* );
|
|
437
|
+
* }
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
337
440
|
declare const WhenAuthenticated: (props: IProps$2) => react.ReactNode;
|
|
441
|
+
/**
|
|
442
|
+
* Conditional component that renders children only when user is NOT authenticated.
|
|
443
|
+
* Returns null if user is authenticated.
|
|
444
|
+
* Note: Also renders during loading/redirecting states (when not yet authenticated).
|
|
445
|
+
*
|
|
446
|
+
* @param props - Component props
|
|
447
|
+
* @param props.children - Content to render when unauthenticated
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ```tsx
|
|
451
|
+
* function App() {
|
|
452
|
+
* return (
|
|
453
|
+
* <SaaSOSProvider {...config}>
|
|
454
|
+
* <WhenUnauthenticated>
|
|
455
|
+
* <LoginPage />
|
|
456
|
+
* </WhenUnauthenticated>
|
|
457
|
+
* <WhenAuthenticated>
|
|
458
|
+
* <Dashboard />
|
|
459
|
+
* </WhenAuthenticated>
|
|
460
|
+
* </SaaSOSProvider>
|
|
461
|
+
* );
|
|
462
|
+
* }
|
|
463
|
+
* ```
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* ```tsx
|
|
467
|
+
* // Handle loading state separately
|
|
468
|
+
* function App() {
|
|
469
|
+
* const { isLoading } = useSaaSAuth();
|
|
470
|
+
*
|
|
471
|
+
* if (isLoading) return <LoadingSpinner />;
|
|
472
|
+
*
|
|
473
|
+
* return (
|
|
474
|
+
* <>
|
|
475
|
+
* <WhenUnauthenticated><LoginPage /></WhenUnauthenticated>
|
|
476
|
+
* <WhenAuthenticated><Dashboard /></WhenAuthenticated>
|
|
477
|
+
* </>
|
|
478
|
+
* );
|
|
479
|
+
* }
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
338
482
|
declare const WhenUnauthenticated: (props: IProps$2) => react.ReactNode;
|
|
339
483
|
|
|
340
484
|
interface IProps$1 {
|
|
@@ -342,33 +486,312 @@ interface IProps$1 {
|
|
|
342
486
|
children: React.ReactNode;
|
|
343
487
|
fallback?: React.ReactNode;
|
|
344
488
|
}
|
|
489
|
+
/**
|
|
490
|
+
* Conditional component that renders children only when user has one of the specified roles.
|
|
491
|
+
* Checks the user's global role (not workspace-specific).
|
|
492
|
+
*
|
|
493
|
+
* @param props - Component props
|
|
494
|
+
* @param props.roles - Array of role strings to check against user's role
|
|
495
|
+
* @param props.children - Content to render when user has matching role
|
|
496
|
+
* @param props.fallback - Optional content to render when user doesn't have matching role (default: null)
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* ```tsx
|
|
500
|
+
* function AdminPanel() {
|
|
501
|
+
* return (
|
|
502
|
+
* <WhenRoles roles={['admin', 'super-admin']}>
|
|
503
|
+
* <AdminContent />
|
|
504
|
+
* </WhenRoles>
|
|
505
|
+
* );
|
|
506
|
+
* }
|
|
507
|
+
* ```
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```tsx
|
|
511
|
+
* // With fallback
|
|
512
|
+
* function SettingsPage() {
|
|
513
|
+
* return (
|
|
514
|
+
* <WhenRoles
|
|
515
|
+
* roles={['admin']}
|
|
516
|
+
* fallback={<p>You don't have permission to access this page.</p>}
|
|
517
|
+
* >
|
|
518
|
+
* <AdminSettings />
|
|
519
|
+
* </WhenRoles>
|
|
520
|
+
* );
|
|
521
|
+
* }
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
345
524
|
declare const WhenRoles: (props: IProps$1) => react.ReactNode;
|
|
525
|
+
/**
|
|
526
|
+
* Conditional component that renders children only when user has one of the specified roles
|
|
527
|
+
* in the current workspace. Checks workspace-specific role, not global role.
|
|
528
|
+
*
|
|
529
|
+
* @param props - Component props
|
|
530
|
+
* @param props.roles - Array of role strings to check against user's workspace role
|
|
531
|
+
* @param props.children - Content to render when user has matching workspace role
|
|
532
|
+
* @param props.fallback - Optional content to render when user doesn't have matching role (default: null)
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```tsx
|
|
536
|
+
* function WorkspaceSettings() {
|
|
537
|
+
* return (
|
|
538
|
+
* <WhenWorkspaceRoles roles={['owner', 'admin']}>
|
|
539
|
+
* <SettingsContent />
|
|
540
|
+
* </WhenWorkspaceRoles>
|
|
541
|
+
* );
|
|
542
|
+
* }
|
|
543
|
+
* ```
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```tsx
|
|
547
|
+
* // Edge case: User not in current workspace
|
|
548
|
+
* function WorkspaceContent() {
|
|
549
|
+
* return (
|
|
550
|
+
* <WhenWorkspaceRoles
|
|
551
|
+
* roles={['member']}
|
|
552
|
+
* fallback={<p>You are not a member of this workspace.</p>}
|
|
553
|
+
* >
|
|
554
|
+
* <WorkspaceDashboard />
|
|
555
|
+
* </WhenWorkspaceRoles>
|
|
556
|
+
* );
|
|
557
|
+
* }
|
|
558
|
+
* ```
|
|
559
|
+
*/
|
|
346
560
|
declare const WhenWorkspaceRoles: (props: IProps$1) => react.ReactNode;
|
|
347
561
|
|
|
348
562
|
interface IProps {
|
|
349
563
|
slug: string;
|
|
350
564
|
children: React.ReactNode;
|
|
351
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* Conditional component that renders children only when the specified workspace feature is enabled.
|
|
568
|
+
* Checks feature flags at the workspace level.
|
|
569
|
+
*
|
|
570
|
+
* @param props - Component props
|
|
571
|
+
* @param props.slug - Feature flag slug/key to check
|
|
572
|
+
* @param props.children - Content to render when feature is enabled
|
|
573
|
+
*
|
|
574
|
+
* @example
|
|
575
|
+
* ```tsx
|
|
576
|
+
* function PremiumFeature() {
|
|
577
|
+
* return (
|
|
578
|
+
* <WhenWorkspaceFeatureEnabled slug="premium-analytics">
|
|
579
|
+
* <AnalyticsDashboard />
|
|
580
|
+
* </WhenWorkspaceFeatureEnabled>
|
|
581
|
+
* );
|
|
582
|
+
* }
|
|
583
|
+
* ```
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```tsx
|
|
587
|
+
* // Multiple features
|
|
588
|
+
* function FeatureContent() {
|
|
589
|
+
* return (
|
|
590
|
+
* <>
|
|
591
|
+
* <WhenWorkspaceFeatureEnabled slug="feature-a">
|
|
592
|
+
* <FeatureA />
|
|
593
|
+
* </WhenWorkspaceFeatureEnabled>
|
|
594
|
+
* <WhenWorkspaceFeatureEnabled slug="feature-b">
|
|
595
|
+
* <FeatureB />
|
|
596
|
+
* </WhenWorkspaceFeatureEnabled>
|
|
597
|
+
* </>
|
|
598
|
+
* );
|
|
599
|
+
* }
|
|
600
|
+
* ```
|
|
601
|
+
*/
|
|
352
602
|
declare const WhenWorkspaceFeatureEnabled: (props: IProps) => react.ReactNode;
|
|
603
|
+
/**
|
|
604
|
+
* Conditional component that renders children only when the specified workspace feature is disabled.
|
|
605
|
+
* Checks feature flags at the workspace level.
|
|
606
|
+
*
|
|
607
|
+
* @param props - Component props
|
|
608
|
+
* @param props.slug - Feature flag slug/key to check
|
|
609
|
+
* @param props.children - Content to render when feature is disabled
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```tsx
|
|
613
|
+
* function UpgradePrompt() {
|
|
614
|
+
* return (
|
|
615
|
+
* <WhenWorkspaceFeatureDisabled slug="premium-feature">
|
|
616
|
+
* <UpgradeButton />
|
|
617
|
+
* </WhenWorkspaceFeatureDisabled>
|
|
618
|
+
* );
|
|
619
|
+
* }
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
353
622
|
declare const WhenWorkspaceFeatureDisabled: (props: IProps) => react.ReactNode;
|
|
623
|
+
/**
|
|
624
|
+
* Conditional component that renders children only when the specified user feature is enabled.
|
|
625
|
+
* Checks feature flags at the user level (from UserProvider).
|
|
626
|
+
*
|
|
627
|
+
* @param props - Component props
|
|
628
|
+
* @param props.slug - Feature flag slug/key to check
|
|
629
|
+
* @param props.children - Content to render when feature is enabled
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```tsx
|
|
633
|
+
* function BetaFeature() {
|
|
634
|
+
* return (
|
|
635
|
+
* <WhenUserFeatureEnabled slug="beta-access">
|
|
636
|
+
* <BetaContent />
|
|
637
|
+
* </WhenUserFeatureEnabled>
|
|
638
|
+
* );
|
|
639
|
+
* }
|
|
640
|
+
* ```
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```tsx
|
|
644
|
+
* // Edge case: Feature not loaded yet
|
|
645
|
+
* function FeatureContent() {
|
|
646
|
+
* const { isLoading } = useUserFeatures();
|
|
647
|
+
*
|
|
648
|
+
* if (isLoading) return <Loading />;
|
|
649
|
+
*
|
|
650
|
+
* return (
|
|
651
|
+
* <WhenUserFeatureEnabled slug="feature-x">
|
|
652
|
+
* <FeatureX />
|
|
653
|
+
* </WhenUserFeatureEnabled>
|
|
654
|
+
* );
|
|
655
|
+
* }
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
354
658
|
declare const WhenUserFeatureEnabled: (props: IProps) => react.ReactNode;
|
|
659
|
+
/**
|
|
660
|
+
* Conditional component that renders children only when the specified user feature is disabled.
|
|
661
|
+
* Checks feature flags at the user level (from UserProvider).
|
|
662
|
+
*
|
|
663
|
+
* @param props - Component props
|
|
664
|
+
* @param props.slug - Feature flag slug/key to check
|
|
665
|
+
* @param props.children - Content to render when feature is disabled
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* ```tsx
|
|
669
|
+
* function UpgradePrompt() {
|
|
670
|
+
* return (
|
|
671
|
+
* <WhenUserFeatureDisabled slug="premium-access">
|
|
672
|
+
* <UpgradeButton />
|
|
673
|
+
* </WhenUserFeatureDisabled>
|
|
674
|
+
* );
|
|
675
|
+
* }
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
355
678
|
declare const WhenUserFeatureDisabled: (props: IProps) => react.ReactNode;
|
|
356
679
|
|
|
680
|
+
/**
|
|
681
|
+
* Main authentication hook for the SDK.
|
|
682
|
+
* Provides authentication state, user session, and auth actions.
|
|
683
|
+
*
|
|
684
|
+
* @returns An object containing:
|
|
685
|
+
* - `user`: Current authenticated user object (null if not authenticated)
|
|
686
|
+
* - `session`: Full session object with user and token (null if not authenticated)
|
|
687
|
+
* - `status`: Current authentication status (loading, redirecting, authenticating, authenticated, unauthenticated)
|
|
688
|
+
* - `isLoading`: Boolean indicating if auth state is being determined
|
|
689
|
+
* - `isAuthenticated`: Boolean indicating if user is authenticated
|
|
690
|
+
* - `isRedirecting`: Boolean indicating if redirecting to OAuth provider
|
|
691
|
+
* - `signIn()`: Function to initiate OAuth sign-in flow
|
|
692
|
+
* - `signOut()`: Function to sign out the current user
|
|
693
|
+
* - `openWorkspaceSettings(section?)`: Function to open workspace settings dialog
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* ```tsx
|
|
697
|
+
* function MyComponent() {
|
|
698
|
+
* const { user, isAuthenticated, signIn, signOut } = useSaaSAuth();
|
|
699
|
+
*
|
|
700
|
+
* if (!isAuthenticated) {
|
|
701
|
+
* return <button onClick={signIn}>Sign In</button>;
|
|
702
|
+
* }
|
|
703
|
+
*
|
|
704
|
+
* return (
|
|
705
|
+
* <div>
|
|
706
|
+
* <p>Welcome, {user?.name}</p>
|
|
707
|
+
* <button onClick={signOut}>Sign Out</button>
|
|
708
|
+
* </div>
|
|
709
|
+
* );
|
|
710
|
+
* }
|
|
711
|
+
* ```
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* ```tsx
|
|
715
|
+
* // Handle loading state
|
|
716
|
+
* function App() {
|
|
717
|
+
* const { status, isLoading } = useSaaSAuth();
|
|
718
|
+
*
|
|
719
|
+
* if (isLoading) {
|
|
720
|
+
* return <LoadingSpinner />;
|
|
721
|
+
* }
|
|
722
|
+
*
|
|
723
|
+
* return <MainContent />;
|
|
724
|
+
* }
|
|
725
|
+
* ```
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* ```tsx
|
|
729
|
+
* // Open workspace settings
|
|
730
|
+
* function SettingsButton() {
|
|
731
|
+
* const { openWorkspaceSettings } = useSaaSAuth();
|
|
732
|
+
*
|
|
733
|
+
* return (
|
|
734
|
+
* <button onClick={() => openWorkspaceSettings('general')}>
|
|
735
|
+
* Open Settings
|
|
736
|
+
* </button>
|
|
737
|
+
* );
|
|
738
|
+
* }
|
|
739
|
+
* ```
|
|
740
|
+
*/
|
|
357
741
|
declare function useSaaSAuth(): {
|
|
358
|
-
user: AuthUser | undefined;
|
|
359
|
-
session: AuthSession | null;
|
|
360
|
-
isLoading: boolean;
|
|
361
|
-
isAuthenticated: boolean;
|
|
362
|
-
isRedirecting: boolean;
|
|
363
|
-
status: AuthStatus;
|
|
364
742
|
signIn: () => Promise<void>;
|
|
365
743
|
signOut: () => Promise<void>;
|
|
366
744
|
openWorkspaceSettings: (section?: "profile" | "general" | "users" | "features" | "danger") => void;
|
|
745
|
+
isAuthenticated: boolean;
|
|
746
|
+
isLoading: boolean;
|
|
747
|
+
isRedirecting: boolean;
|
|
748
|
+
user: AuthUser | undefined;
|
|
749
|
+
session: AuthSession | null;
|
|
750
|
+
status: AuthStatus;
|
|
367
751
|
};
|
|
368
752
|
|
|
753
|
+
/**
|
|
754
|
+
* Hook to access organization settings from the OS context.
|
|
755
|
+
* Automatically fetches settings when OS config is ready.
|
|
756
|
+
*
|
|
757
|
+
* @returns An object containing:
|
|
758
|
+
* - `settings`: Organization settings object (null if not loaded)
|
|
759
|
+
* - `getSettings(signal?)`: Function to manually fetch settings (supports AbortSignal)
|
|
760
|
+
*
|
|
761
|
+
* @example
|
|
762
|
+
* ```tsx
|
|
763
|
+
* function SettingsDisplay() {
|
|
764
|
+
* const { settings } = useSaaSSettings();
|
|
765
|
+
*
|
|
766
|
+
* if (!settings) return <Loading />;
|
|
767
|
+
*
|
|
768
|
+
* return (
|
|
769
|
+
* <div>
|
|
770
|
+
* <p>Organization: {settings.name}</p>
|
|
771
|
+
* <p>Theme: {settings.theme}</p>
|
|
772
|
+
* </div>
|
|
773
|
+
* );
|
|
774
|
+
* }
|
|
775
|
+
* ```
|
|
776
|
+
*
|
|
777
|
+
* @example
|
|
778
|
+
* ```tsx
|
|
779
|
+
* // Manual fetch with abort signal
|
|
780
|
+
* function SettingsLoader() {
|
|
781
|
+
* const { getSettings } = useSaaSSettings();
|
|
782
|
+
*
|
|
783
|
+
* useEffect(() => {
|
|
784
|
+
* const controller = new AbortController();
|
|
785
|
+
* getSettings(controller.signal);
|
|
786
|
+
*
|
|
787
|
+
* return () => controller.abort();
|
|
788
|
+
* }, [getSettings]);
|
|
789
|
+
* }
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
369
792
|
declare function useSaaSSettings(): {
|
|
370
793
|
settings: ISettings | null | undefined;
|
|
371
|
-
getSettings: () => Promise<ISettings | null>;
|
|
794
|
+
getSettings: (signal?: AbortSignal) => Promise<ISettings | null>;
|
|
372
795
|
};
|
|
373
796
|
|
|
374
797
|
interface UserContextValue {
|
|
@@ -382,7 +805,78 @@ interface UserContextValue {
|
|
|
382
805
|
refreshFeatures: () => Promise<void>;
|
|
383
806
|
}
|
|
384
807
|
|
|
808
|
+
/**
|
|
809
|
+
* Hook to access user attributes from the UserProvider.
|
|
810
|
+
* Must be used within a UserProvider component.
|
|
811
|
+
*
|
|
812
|
+
* @returns User context object containing:
|
|
813
|
+
* - `attributes`: Record of user attribute key-value pairs
|
|
814
|
+
* - `isLoading`: Boolean indicating if attributes are being loaded
|
|
815
|
+
* - `error`: Error message string (null if no error)
|
|
816
|
+
* - `refreshAttributes()`: Function to manually refresh attributes
|
|
817
|
+
*
|
|
818
|
+
* @throws {Error} If used outside of UserProvider
|
|
819
|
+
*
|
|
820
|
+
* @example
|
|
821
|
+
* ```tsx
|
|
822
|
+
* function UserProfile() {
|
|
823
|
+
* const { attributes, isLoading } = useUserAttributes();
|
|
824
|
+
*
|
|
825
|
+
* if (isLoading) return <Loading />;
|
|
826
|
+
*
|
|
827
|
+
* return (
|
|
828
|
+
* <div>
|
|
829
|
+
* <p>Plan: {attributes?.plan}</p>
|
|
830
|
+
* <p>Company: {attributes?.company}</p>
|
|
831
|
+
* </div>
|
|
832
|
+
* );
|
|
833
|
+
* }
|
|
834
|
+
* ```
|
|
835
|
+
*/
|
|
385
836
|
declare function useUserAttributes(): UserContextValue;
|
|
837
|
+
/**
|
|
838
|
+
* Hook to access user feature flags from the UserProvider.
|
|
839
|
+
* Must be used within a UserProvider component.
|
|
840
|
+
*
|
|
841
|
+
* @returns An object containing:
|
|
842
|
+
* - `features`: Record of feature flag key-value pairs (boolean values)
|
|
843
|
+
* - `isLoading`: Boolean indicating if features are being loaded
|
|
844
|
+
* - `error`: Error message string (null if no error)
|
|
845
|
+
* - `refreshFeatures()`: Function to manually refresh features
|
|
846
|
+
* - `isFeatureEnabled(featureId)`: Function to check if a specific feature is enabled
|
|
847
|
+
*
|
|
848
|
+
* @throws {Error} If used outside of UserProvider
|
|
849
|
+
*
|
|
850
|
+
* @example
|
|
851
|
+
* ```tsx
|
|
852
|
+
* function FeatureContent() {
|
|
853
|
+
* const { isFeatureEnabled, isLoading } = useUserFeatures();
|
|
854
|
+
*
|
|
855
|
+
* if (isLoading) return <Loading />;
|
|
856
|
+
*
|
|
857
|
+
* if (isFeatureEnabled('premium-feature')) {
|
|
858
|
+
* return <PremiumFeature />;
|
|
859
|
+
* }
|
|
860
|
+
*
|
|
861
|
+
* return <BasicFeature />;
|
|
862
|
+
* }
|
|
863
|
+
* ```
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```tsx
|
|
867
|
+
* // Check multiple features
|
|
868
|
+
* function Dashboard() {
|
|
869
|
+
* const { isFeatureEnabled } = useUserFeatures();
|
|
870
|
+
*
|
|
871
|
+
* return (
|
|
872
|
+
* <div>
|
|
873
|
+
* {isFeatureEnabled('analytics') && <Analytics />}
|
|
874
|
+
* {isFeatureEnabled('reports') && <Reports />}
|
|
875
|
+
* </div>
|
|
876
|
+
* );
|
|
877
|
+
* }
|
|
878
|
+
* ```
|
|
879
|
+
*/
|
|
386
880
|
declare function useUserFeatures(): {
|
|
387
881
|
features: Record<string, boolean>;
|
|
388
882
|
isLoading: boolean;
|
|
@@ -396,6 +890,111 @@ declare function WorkspaceSwitcher(props: {
|
|
|
396
890
|
onWorkspaceChange: (workspace: IWorkspace) => Promise<void>;
|
|
397
891
|
}): react_jsx_runtime.JSX.Element;
|
|
398
892
|
|
|
893
|
+
/**
|
|
894
|
+
* Main workspace management hook for the SDK.
|
|
895
|
+
* Provides workspace state, CRUD operations, and user management.
|
|
896
|
+
*
|
|
897
|
+
* @returns An object containing:
|
|
898
|
+
* - `workspaces`: Array of all workspaces the user has access to
|
|
899
|
+
* - `currentWorkspace`: Currently selected workspace (null if none selected)
|
|
900
|
+
* - `loading`: Boolean indicating if workspaces are being fetched
|
|
901
|
+
* - `error`: Error message string (null if no error)
|
|
902
|
+
* - `refreshing`: Boolean indicating if workspaces are being refreshed in background
|
|
903
|
+
* - `switching`: Boolean indicating if workspace is being switched
|
|
904
|
+
* - `WorkspaceSwitcher`: Component for switching between workspaces
|
|
905
|
+
* - `fetchWorkspaces()`: Function to fetch all workspaces
|
|
906
|
+
* - `refreshWorkspaces()`: Function to refresh workspaces in background (non-blocking)
|
|
907
|
+
* - `setCurrentWorkspace(workspace)`: Function to set the current workspace
|
|
908
|
+
* - `resetCurrentWorkspace()`: Function to clear the current workspace
|
|
909
|
+
* - `createWorkspace(name, image?)`: Function to create a new workspace
|
|
910
|
+
* - `updateWorkspace(workspace, data)`: Function to update a workspace
|
|
911
|
+
* - `deleteWorkspace(workspaceId)`: Function to delete a workspace (owner only)
|
|
912
|
+
* - `getWorkspace(workspaceId)`: Function to fetch a specific workspace
|
|
913
|
+
* - `getUsers(workspaceId)`: Function to fetch users in a workspace
|
|
914
|
+
* - `addUser(workspaceId, email, role)`: Function to add a user to a workspace
|
|
915
|
+
* - `removeUser(workspaceId, userId)`: Function to remove a user from a workspace
|
|
916
|
+
* - `updateUser(workspaceId, userId, config)`: Function to update a user in a workspace
|
|
917
|
+
* - `getProfile()`: Function to fetch current user profile
|
|
918
|
+
* - `updateUserProfile(config)`: Function to update current user profile
|
|
919
|
+
* - `allFeatures`: Array of all available feature flags
|
|
920
|
+
* - `getFeatures()`: Function to fetch all available features
|
|
921
|
+
* - `updateFeature(workspaceId, key, value)`: Function to update a feature flag
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* ```tsx
|
|
925
|
+
* function WorkspaceList() {
|
|
926
|
+
* const { workspaces, loading, fetchWorkspaces } = useSaaSWorkspaces();
|
|
927
|
+
*
|
|
928
|
+
* useEffect(() => {
|
|
929
|
+
* fetchWorkspaces();
|
|
930
|
+
* }, [fetchWorkspaces]);
|
|
931
|
+
*
|
|
932
|
+
* if (loading) return <Loading />;
|
|
933
|
+
*
|
|
934
|
+
* return (
|
|
935
|
+
* <ul>
|
|
936
|
+
* {workspaces.map(ws => (
|
|
937
|
+
* <li key={ws._id}>{ws.name}</li>
|
|
938
|
+
* ))}
|
|
939
|
+
* </ul>
|
|
940
|
+
* );
|
|
941
|
+
* }
|
|
942
|
+
* ```
|
|
943
|
+
*
|
|
944
|
+
* @example
|
|
945
|
+
* ```tsx
|
|
946
|
+
* // Create a new workspace
|
|
947
|
+
* function CreateWorkspace() {
|
|
948
|
+
* const { createWorkspace } = useSaaSWorkspaces();
|
|
949
|
+
*
|
|
950
|
+
* const handleCreate = async () => {
|
|
951
|
+
* try {
|
|
952
|
+
* await createWorkspace('My Workspace', 'https://example.com/logo.png');
|
|
953
|
+
* } catch (error) {
|
|
954
|
+
* console.error('Failed to create workspace:', error);
|
|
955
|
+
* }
|
|
956
|
+
* };
|
|
957
|
+
*
|
|
958
|
+
* return <button onClick={handleCreate}>Create Workspace</button>;
|
|
959
|
+
* }
|
|
960
|
+
* ```
|
|
961
|
+
*
|
|
962
|
+
* @example
|
|
963
|
+
* ```tsx
|
|
964
|
+
* // Delete workspace (owner only)
|
|
965
|
+
* function DeleteWorkspaceButton({ workspaceId }) {
|
|
966
|
+
* const { deleteWorkspace } = useSaaSWorkspaces();
|
|
967
|
+
*
|
|
968
|
+
* const handleDelete = async () => {
|
|
969
|
+
* if (!confirm('Are you sure?')) return;
|
|
970
|
+
* try {
|
|
971
|
+
* await deleteWorkspace(workspaceId);
|
|
972
|
+
* } catch (error) {
|
|
973
|
+
* // Error: "Only the workspace creator can delete the workspace"
|
|
974
|
+
* alert(error.message);
|
|
975
|
+
* }
|
|
976
|
+
* };
|
|
977
|
+
*
|
|
978
|
+
* return <button onClick={handleDelete}>Delete</button>;
|
|
979
|
+
* }
|
|
980
|
+
* ```
|
|
981
|
+
*
|
|
982
|
+
* @example
|
|
983
|
+
* ```tsx
|
|
984
|
+
* // Edge case: Workspace removed from user's access
|
|
985
|
+
* function WorkspaceContent() {
|
|
986
|
+
* const { currentWorkspace, workspaces } = useSaaSWorkspaces();
|
|
987
|
+
*
|
|
988
|
+
* // If current workspace is not in the list, it was removed
|
|
989
|
+
* // The hook automatically switches to first available workspace
|
|
990
|
+
* if (!currentWorkspace) {
|
|
991
|
+
* return <p>No workspace selected</p>;
|
|
992
|
+
* }
|
|
993
|
+
*
|
|
994
|
+
* return <div>{currentWorkspace.name}</div>;
|
|
995
|
+
* }
|
|
996
|
+
* ```
|
|
997
|
+
*/
|
|
399
998
|
declare const useSaaSWorkspaces: () => {
|
|
400
999
|
workspaces: IWorkspace[];
|
|
401
1000
|
loading: boolean;
|
|
@@ -438,9 +1037,41 @@ declare const useSaaSWorkspaces: () => {
|
|
|
438
1037
|
};
|
|
439
1038
|
|
|
440
1039
|
/**
|
|
441
|
-
* Hook to get and manage the current subscription for a workspace
|
|
442
|
-
*
|
|
443
|
-
*
|
|
1040
|
+
* Hook to get and manage the current subscription for a workspace.
|
|
1041
|
+
* Automatically fetches subscription when workspaceId changes.
|
|
1042
|
+
*
|
|
1043
|
+
* @param workspaceId - The workspace ID to get subscription for. Can be null/undefined to disable fetching.
|
|
1044
|
+
* @returns An object containing:
|
|
1045
|
+
* - `subscription`: Current subscription data (null if no subscription or not loaded)
|
|
1046
|
+
* - `loading`: Boolean indicating if subscription is being fetched
|
|
1047
|
+
* - `error`: Error message string (null if no error)
|
|
1048
|
+
* - `refetch()`: Function to manually refetch the subscription
|
|
1049
|
+
*
|
|
1050
|
+
* @example
|
|
1051
|
+
* ```tsx
|
|
1052
|
+
* function SubscriptionStatus() {
|
|
1053
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1054
|
+
* const { subscription, loading, error } = useSubscription(currentWorkspace?._id);
|
|
1055
|
+
*
|
|
1056
|
+
* if (loading) return <Loading />;
|
|
1057
|
+
* if (error) return <Error message={error} />;
|
|
1058
|
+
* if (!subscription) return <p>No active subscription</p>;
|
|
1059
|
+
*
|
|
1060
|
+
* return <p>Plan: {subscription.plan.name}</p>;
|
|
1061
|
+
* }
|
|
1062
|
+
* ```
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```tsx
|
|
1066
|
+
* // Edge case: Workspace ID changes
|
|
1067
|
+
* function SubscriptionComponent({ workspaceId }) {
|
|
1068
|
+
* const { subscription, refetch } = useSubscription(workspaceId);
|
|
1069
|
+
*
|
|
1070
|
+
* // Subscription automatically refetches when workspaceId changes
|
|
1071
|
+
* // Use refetch() to manually refresh after mutations
|
|
1072
|
+
* return <SubscriptionDetails subscription={subscription} />;
|
|
1073
|
+
* }
|
|
1074
|
+
* ```
|
|
444
1075
|
*/
|
|
445
1076
|
declare const useSubscription: (workspaceId: string | null | undefined) => {
|
|
446
1077
|
subscription: ISubscriptionResponse | null;
|
|
@@ -449,40 +1080,388 @@ declare const useSubscription: (workspaceId: string | null | undefined) => {
|
|
|
449
1080
|
refetch: () => Promise<void>;
|
|
450
1081
|
};
|
|
451
1082
|
/**
|
|
452
|
-
* Hook to get the plan group for a workspace
|
|
1083
|
+
* Hook to get the plan group for a workspace.
|
|
453
1084
|
* Returns the plan group containing the current plan if subscription exists,
|
|
454
|
-
* otherwise returns the latest published group
|
|
455
|
-
*
|
|
456
|
-
*
|
|
1085
|
+
* otherwise returns the latest published group.
|
|
1086
|
+
* Automatically fetches when workspaceId or groupVersionId changes.
|
|
1087
|
+
*
|
|
1088
|
+
* @param workspaceId - The workspace ID to get plan group for. Can be null/undefined to disable fetching.
|
|
1089
|
+
* @param groupVersionId - Optional: specific group version ID to fetch (for viewing historical versions)
|
|
1090
|
+
* @returns An object containing:
|
|
1091
|
+
* - `planGroup`: Plan group data (null if not loaded)
|
|
1092
|
+
* - `loading`: Boolean indicating if plan group is being fetched
|
|
1093
|
+
* - `error`: Error message string (null if no error)
|
|
1094
|
+
* - `refetch()`: Function to manually refetch the plan group
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* ```tsx
|
|
1098
|
+
* function PlanGroupDisplay() {
|
|
1099
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1100
|
+
* const { planGroup, loading } = usePlanGroup(currentWorkspace?._id);
|
|
1101
|
+
*
|
|
1102
|
+
* if (loading) return <Loading />;
|
|
1103
|
+
* if (!planGroup) return <p>No plan group available</p>;
|
|
1104
|
+
*
|
|
1105
|
+
* return (
|
|
1106
|
+
* <div>
|
|
1107
|
+
* <h3>{planGroup.name}</h3>
|
|
1108
|
+
* {planGroup.plans.map(plan => (
|
|
1109
|
+
* <PlanCard key={plan._id} plan={plan} />
|
|
1110
|
+
* ))}
|
|
1111
|
+
* </div>
|
|
1112
|
+
* );
|
|
1113
|
+
* }
|
|
1114
|
+
* ```
|
|
1115
|
+
*
|
|
1116
|
+
* @example
|
|
1117
|
+
* ```tsx
|
|
1118
|
+
* // Fetch specific version for comparison
|
|
1119
|
+
* function PlanVersionComparison() {
|
|
1120
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1121
|
+
* const current = usePlanGroup(currentWorkspace?._id);
|
|
1122
|
+
* const previous = usePlanGroup(currentWorkspace?._id, 'previous-version-id');
|
|
1123
|
+
*
|
|
1124
|
+
* return <ComparePlans current={current.planGroup} previous={previous.planGroup} />;
|
|
1125
|
+
* }
|
|
1126
|
+
* ```
|
|
457
1127
|
*/
|
|
458
|
-
declare const usePlanGroup: (workspaceId: string | null | undefined) => {
|
|
1128
|
+
declare const usePlanGroup: (workspaceId: string | null | undefined, groupVersionId?: string | null) => {
|
|
459
1129
|
planGroup: IPlanGroupResponse | null;
|
|
460
1130
|
loading: boolean;
|
|
461
1131
|
error: string | null;
|
|
462
1132
|
refetch: () => Promise<void>;
|
|
463
1133
|
};
|
|
464
1134
|
/**
|
|
465
|
-
* Hook to
|
|
466
|
-
*
|
|
467
|
-
*
|
|
1135
|
+
* Hook to get all available versions of a plan group for a workspace.
|
|
1136
|
+
* Shows current version and available newer versions for upgrade paths.
|
|
1137
|
+
* Automatically fetches when workspaceId changes.
|
|
1138
|
+
*
|
|
1139
|
+
* @param workspaceId - The workspace ID to get plan group versions for. Can be null/undefined to disable fetching.
|
|
1140
|
+
* @returns An object containing:
|
|
1141
|
+
* - `versions`: Plan group versions response with currentVersion and availableVersions
|
|
1142
|
+
* - `loading`: Boolean indicating if versions are being fetched
|
|
1143
|
+
* - `error`: Error message string (null if no error)
|
|
1144
|
+
* - `refetch()`: Function to manually refetch the versions
|
|
1145
|
+
*
|
|
1146
|
+
* @example
|
|
1147
|
+
* ```tsx
|
|
1148
|
+
* function UpgradeOptions() {
|
|
1149
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1150
|
+
* const { versions, loading } = usePlanGroupVersions(currentWorkspace?._id);
|
|
1151
|
+
*
|
|
1152
|
+
* if (loading) return <Loading />;
|
|
1153
|
+
*
|
|
1154
|
+
* return (
|
|
1155
|
+
* <div>
|
|
1156
|
+
* <p>Current: {versions?.currentVersion.name}</p>
|
|
1157
|
+
* <h4>Available Upgrades:</h4>
|
|
1158
|
+
* {versions?.availableVersions.map(version => (
|
|
1159
|
+
* <UpgradeCard key={version._id} version={version} />
|
|
1160
|
+
* ))}
|
|
1161
|
+
* </div>
|
|
1162
|
+
* );
|
|
1163
|
+
* }
|
|
1164
|
+
* ```
|
|
1165
|
+
*/
|
|
1166
|
+
declare const usePlanGroupVersions: (workspaceId: string | null | undefined) => {
|
|
1167
|
+
versions: IPlanGroupVersionsResponse | null;
|
|
1168
|
+
loading: boolean;
|
|
1169
|
+
error: string | null;
|
|
1170
|
+
refetch: () => Promise<void>;
|
|
1171
|
+
};
|
|
1172
|
+
/**
|
|
1173
|
+
* Hook to create a checkout session for a new subscription.
|
|
1174
|
+
* Returns a function to initiate the checkout process.
|
|
1175
|
+
*
|
|
1176
|
+
* @param workspaceId - The workspace ID to create checkout session for. Can be null/undefined.
|
|
1177
|
+
* @returns An object containing:
|
|
1178
|
+
* - `createCheckoutSession(request)`: Function to create checkout session (throws if workspaceId is null)
|
|
1179
|
+
* - `loading`: Boolean indicating if checkout session is being created
|
|
1180
|
+
* - `error`: Error message string (null if no error)
|
|
1181
|
+
*
|
|
1182
|
+
* @example
|
|
1183
|
+
* ```tsx
|
|
1184
|
+
* function SubscribeButton({ planVersionId }) {
|
|
1185
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1186
|
+
* const { createCheckoutSession, loading } = useCreateCheckoutSession(currentWorkspace?._id);
|
|
1187
|
+
*
|
|
1188
|
+
* const handleSubscribe = async () => {
|
|
1189
|
+
* try {
|
|
1190
|
+
* const result = await createCheckoutSession({
|
|
1191
|
+
* planVersionId,
|
|
1192
|
+
* successUrl: window.location.href,
|
|
1193
|
+
* cancelUrl: window.location.href,
|
|
1194
|
+
* });
|
|
1195
|
+
* // Redirect to checkout
|
|
1196
|
+
* window.location.href = result.checkoutUrl;
|
|
1197
|
+
* } catch (error) {
|
|
1198
|
+
* console.error('Failed to create checkout:', error);
|
|
1199
|
+
* }
|
|
1200
|
+
* };
|
|
1201
|
+
*
|
|
1202
|
+
* return (
|
|
1203
|
+
* <button onClick={handleSubscribe} disabled={loading}>
|
|
1204
|
+
* {loading ? 'Loading...' : 'Subscribe'}
|
|
1205
|
+
* </button>
|
|
1206
|
+
* );
|
|
1207
|
+
* }
|
|
1208
|
+
* ```
|
|
1209
|
+
*
|
|
1210
|
+
* @example
|
|
1211
|
+
* ```tsx
|
|
1212
|
+
* // Edge case: Workspace ID not available
|
|
1213
|
+
* function SubscribeButton() {
|
|
1214
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1215
|
+
* const { createCheckoutSession } = useCreateCheckoutSession(currentWorkspace?._id);
|
|
1216
|
+
*
|
|
1217
|
+
* const handleSubscribe = async () => {
|
|
1218
|
+
* try {
|
|
1219
|
+
* await createCheckoutSession({ planVersionId: 'plan-123' });
|
|
1220
|
+
* } catch (error) {
|
|
1221
|
+
* // Error: "Workspace ID is required"
|
|
1222
|
+
* alert('Please select a workspace first');
|
|
1223
|
+
* }
|
|
1224
|
+
* };
|
|
1225
|
+
*
|
|
1226
|
+
* return <button onClick={handleSubscribe}>Subscribe</button>;
|
|
1227
|
+
* }
|
|
1228
|
+
* ```
|
|
1229
|
+
*/
|
|
1230
|
+
declare const useCreateCheckoutSession: (workspaceId: string | null | undefined) => {
|
|
1231
|
+
createCheckoutSession: (request: ICheckoutSessionRequest) => Promise<ICheckoutSessionResponse>;
|
|
1232
|
+
loading: boolean;
|
|
1233
|
+
error: string | null;
|
|
1234
|
+
};
|
|
1235
|
+
/**
|
|
1236
|
+
* Hook to update subscription (upgrade/downgrade).
|
|
1237
|
+
* Returns checkout session if payment is required, otherwise returns subscription update response.
|
|
1238
|
+
*
|
|
1239
|
+
* @param workspaceId - The workspace ID to update subscription for. Can be null/undefined.
|
|
1240
|
+
* @returns An object containing:
|
|
1241
|
+
* - `updateSubscription(planVersionId, options?)`: Function to update subscription (throws if workspaceId is null)
|
|
1242
|
+
* - `loading`: Boolean indicating if subscription is being updated
|
|
1243
|
+
* - `error`: Error message string (null if no error)
|
|
1244
|
+
*
|
|
1245
|
+
* @example
|
|
1246
|
+
* ```tsx
|
|
1247
|
+
* function UpgradeButton({ planVersionId }) {
|
|
1248
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1249
|
+
* const { updateSubscription, loading } = useUpdateSubscription(currentWorkspace?._id);
|
|
1250
|
+
*
|
|
1251
|
+
* const handleUpgrade = async () => {
|
|
1252
|
+
* try {
|
|
1253
|
+
* const result = await updateSubscription(planVersionId, {
|
|
1254
|
+
* billingInterval: 'monthly',
|
|
1255
|
+
* successUrl: window.location.href,
|
|
1256
|
+
* cancelUrl: window.location.href,
|
|
1257
|
+
* });
|
|
1258
|
+
*
|
|
1259
|
+
* // Check if payment is required
|
|
1260
|
+
* if ('checkoutUrl' in result) {
|
|
1261
|
+
* window.location.href = result.checkoutUrl;
|
|
1262
|
+
* } else {
|
|
1263
|
+
* // Subscription updated without payment
|
|
1264
|
+
* alert('Subscription updated successfully!');
|
|
1265
|
+
* }
|
|
1266
|
+
* } catch (error) {
|
|
1267
|
+
* console.error('Failed to update subscription:', error);
|
|
1268
|
+
* }
|
|
1269
|
+
* };
|
|
1270
|
+
*
|
|
1271
|
+
* return (
|
|
1272
|
+
* <button onClick={handleUpgrade} disabled={loading}>
|
|
1273
|
+
* {loading ? 'Upgrading...' : 'Upgrade'}
|
|
1274
|
+
* </button>
|
|
1275
|
+
* );
|
|
1276
|
+
* }
|
|
1277
|
+
* ```
|
|
1278
|
+
*
|
|
1279
|
+
* @example
|
|
1280
|
+
* ```tsx
|
|
1281
|
+
* // Handle both checkout and direct update responses
|
|
1282
|
+
* function SubscriptionUpdater({ planVersionId }) {
|
|
1283
|
+
* const { updateSubscription } = useUpdateSubscription(workspaceId);
|
|
1284
|
+
*
|
|
1285
|
+
* const handleUpdate = async () => {
|
|
1286
|
+
* const result = await updateSubscription(planVersionId);
|
|
1287
|
+
*
|
|
1288
|
+
* // Type guard to check response type
|
|
1289
|
+
* if ('checkoutUrl' in result) {
|
|
1290
|
+
* // Redirect to payment
|
|
1291
|
+
* window.location.href = result.checkoutUrl;
|
|
1292
|
+
* } else {
|
|
1293
|
+
* // Direct update successful
|
|
1294
|
+
* console.log('Updated subscription:', result.subscription);
|
|
1295
|
+
* }
|
|
1296
|
+
* };
|
|
1297
|
+
*
|
|
1298
|
+
* return <button onClick={handleUpdate}>Update</button>;
|
|
1299
|
+
* }
|
|
1300
|
+
* ```
|
|
468
1301
|
*/
|
|
469
1302
|
declare const useUpdateSubscription: (workspaceId: string | null | undefined) => {
|
|
470
|
-
updateSubscription: (planVersionId: string
|
|
1303
|
+
updateSubscription: (planVersionId: string, options?: {
|
|
1304
|
+
billingInterval?: BillingInterval;
|
|
1305
|
+
successUrl?: string;
|
|
1306
|
+
cancelUrl?: string;
|
|
1307
|
+
}) => Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
|
|
471
1308
|
loading: boolean;
|
|
472
1309
|
error: string | null;
|
|
473
1310
|
};
|
|
474
1311
|
/**
|
|
475
|
-
* Combined hook that provides both subscription and plan group data
|
|
476
|
-
* Useful for subscription management pages
|
|
477
|
-
*
|
|
478
|
-
*
|
|
1312
|
+
* Combined hook that provides both subscription and plan group data.
|
|
1313
|
+
* Useful for subscription management pages that need both pieces of data.
|
|
1314
|
+
* Combines useSubscription, usePlanGroup, and useUpdateSubscription.
|
|
1315
|
+
*
|
|
1316
|
+
* @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
|
|
1317
|
+
* @param groupVersionId - Optional: specific group version ID to fetch
|
|
1318
|
+
* @returns An object containing:
|
|
1319
|
+
* - `subscription`: Current subscription data (from useSubscription)
|
|
1320
|
+
* - `planGroup`: Plan group data (from usePlanGroup)
|
|
1321
|
+
* - `loading`: Boolean indicating if any operation is in progress
|
|
1322
|
+
* - `error`: Error message string (null if no error)
|
|
1323
|
+
* - `updateSubscription(planVersionId, options?)`: Function to update subscription
|
|
1324
|
+
* - `refetch()`: Function to refetch both subscription and plan group
|
|
1325
|
+
*
|
|
1326
|
+
* @example
|
|
1327
|
+
* ```tsx
|
|
1328
|
+
* function SubscriptionManagementPage() {
|
|
1329
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1330
|
+
* const {
|
|
1331
|
+
* subscription,
|
|
1332
|
+
* planGroup,
|
|
1333
|
+
* loading,
|
|
1334
|
+
* updateSubscription,
|
|
1335
|
+
* refetch,
|
|
1336
|
+
* } = useSubscriptionManagement(currentWorkspace?._id);
|
|
1337
|
+
*
|
|
1338
|
+
* if (loading) return <Loading />;
|
|
1339
|
+
*
|
|
1340
|
+
* return (
|
|
1341
|
+
* <div>
|
|
1342
|
+
* <CurrentPlan subscription={subscription} />
|
|
1343
|
+
* <AvailablePlans planGroup={planGroup} onSelect={updateSubscription} />
|
|
1344
|
+
* <button onClick={refetch}>Refresh</button>
|
|
1345
|
+
* </div>
|
|
1346
|
+
* );
|
|
1347
|
+
* }
|
|
1348
|
+
* ```
|
|
479
1349
|
*/
|
|
480
|
-
declare const useSubscriptionManagement: (workspaceId: string | null | undefined) => {
|
|
1350
|
+
declare const useSubscriptionManagement: (workspaceId: string | null | undefined, groupVersionId?: string | null) => {
|
|
481
1351
|
subscription: ISubscriptionResponse | null;
|
|
482
1352
|
planGroup: IPlanGroupResponse | null;
|
|
483
1353
|
loading: boolean;
|
|
484
1354
|
error: string | null;
|
|
485
|
-
updateSubscription: (planVersionId: string
|
|
1355
|
+
updateSubscription: (planVersionId: string, options?: {
|
|
1356
|
+
billingInterval?: BillingInterval;
|
|
1357
|
+
successUrl?: string;
|
|
1358
|
+
cancelUrl?: string;
|
|
1359
|
+
}) => Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
|
|
1360
|
+
refetch: () => Promise<void>;
|
|
1361
|
+
};
|
|
1362
|
+
/**
|
|
1363
|
+
* Hook to list invoices for a workspace subscription with pagination support.
|
|
1364
|
+
* Automatically fetches when workspaceId, limit, or startingAfter changes.
|
|
1365
|
+
*
|
|
1366
|
+
* @param workspaceId - The workspace ID to get invoices for. Can be null/undefined to disable fetching.
|
|
1367
|
+
* @param limit - Number of invoices to return (default: 10)
|
|
1368
|
+
* @param startingAfter - Invoice ID to start after (for pagination)
|
|
1369
|
+
* @returns An object containing:
|
|
1370
|
+
* - `invoices`: Array of invoice objects
|
|
1371
|
+
* - `hasMore`: Boolean indicating if there are more invoices to load
|
|
1372
|
+
* - `loading`: Boolean indicating if invoices are being fetched
|
|
1373
|
+
* - `error`: Error message string (null if no error)
|
|
1374
|
+
* - `refetch()`: Function to manually refetch invoices
|
|
1375
|
+
*
|
|
1376
|
+
* @example
|
|
1377
|
+
* ```tsx
|
|
1378
|
+
* function InvoiceList() {
|
|
1379
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1380
|
+
* const { invoices, hasMore, loading, refetch } = useInvoices(currentWorkspace?._id, 10);
|
|
1381
|
+
*
|
|
1382
|
+
* if (loading) return <Loading />;
|
|
1383
|
+
*
|
|
1384
|
+
* return (
|
|
1385
|
+
* <div>
|
|
1386
|
+
* {invoices.map(invoice => (
|
|
1387
|
+
* <InvoiceCard key={invoice._id} invoice={invoice} />
|
|
1388
|
+
* ))}
|
|
1389
|
+
* {hasMore && <button onClick={() => refetch()}>Load More</button>}
|
|
1390
|
+
* </div>
|
|
1391
|
+
* );
|
|
1392
|
+
* }
|
|
1393
|
+
* ```
|
|
1394
|
+
*
|
|
1395
|
+
* @example
|
|
1396
|
+
* ```tsx
|
|
1397
|
+
* // Pagination example
|
|
1398
|
+
* function PaginatedInvoices() {
|
|
1399
|
+
* const [lastInvoiceId, setLastInvoiceId] = useState<string | undefined>();
|
|
1400
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1401
|
+
* const { invoices, hasMore, refetch } = useInvoices(
|
|
1402
|
+
* currentWorkspace?._id,
|
|
1403
|
+
* 10,
|
|
1404
|
+
* lastInvoiceId
|
|
1405
|
+
* );
|
|
1406
|
+
*
|
|
1407
|
+
* const loadMore = () => {
|
|
1408
|
+
* if (invoices.length > 0) {
|
|
1409
|
+
* setLastInvoiceId(invoices[invoices.length - 1]._id);
|
|
1410
|
+
* }
|
|
1411
|
+
* };
|
|
1412
|
+
*
|
|
1413
|
+
* return (
|
|
1414
|
+
* <div>
|
|
1415
|
+
* {invoices.map(invoice => <InvoiceCard key={invoice._id} invoice={invoice} />)}
|
|
1416
|
+
* {hasMore && <button onClick={loadMore}>Load More</button>}
|
|
1417
|
+
* </div>
|
|
1418
|
+
* );
|
|
1419
|
+
* }
|
|
1420
|
+
* ```
|
|
1421
|
+
*/
|
|
1422
|
+
declare const useInvoices: (workspaceId: string | null | undefined, limit?: number, startingAfter?: string) => {
|
|
1423
|
+
invoices: IInvoice[];
|
|
1424
|
+
hasMore: boolean;
|
|
1425
|
+
loading: boolean;
|
|
1426
|
+
error: string | null;
|
|
1427
|
+
refetch: () => Promise<void>;
|
|
1428
|
+
};
|
|
1429
|
+
/**
|
|
1430
|
+
* Hook to get a single invoice by ID.
|
|
1431
|
+
* Automatically fetches when workspaceId or invoiceId changes.
|
|
1432
|
+
*
|
|
1433
|
+
* @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
|
|
1434
|
+
* @param invoiceId - The invoice ID to fetch. Can be null/undefined to disable fetching.
|
|
1435
|
+
* @returns An object containing:
|
|
1436
|
+
* - `invoice`: Invoice data object (null if not loaded)
|
|
1437
|
+
* - `loading`: Boolean indicating if invoice is being fetched
|
|
1438
|
+
* - `error`: Error message string (null if no error)
|
|
1439
|
+
* - `refetch()`: Function to manually refetch the invoice
|
|
1440
|
+
*
|
|
1441
|
+
* @example
|
|
1442
|
+
* ```tsx
|
|
1443
|
+
* function InvoiceDetails({ invoiceId }) {
|
|
1444
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1445
|
+
* const { invoice, loading, error } = useInvoice(currentWorkspace?._id, invoiceId);
|
|
1446
|
+
*
|
|
1447
|
+
* if (loading) return <Loading />;
|
|
1448
|
+
* if (error) return <Error message={error} />;
|
|
1449
|
+
* if (!invoice) return <p>Invoice not found</p>;
|
|
1450
|
+
*
|
|
1451
|
+
* return (
|
|
1452
|
+
* <div>
|
|
1453
|
+
* <h2>Invoice #{invoice.invoiceNumber}</h2>
|
|
1454
|
+
* <p>Amount: ${invoice.amount}</p>
|
|
1455
|
+
* <p>Status: {invoice.status}</p>
|
|
1456
|
+
* </div>
|
|
1457
|
+
* );
|
|
1458
|
+
* }
|
|
1459
|
+
* ```
|
|
1460
|
+
*/
|
|
1461
|
+
declare const useInvoice: (workspaceId: string | null | undefined, invoiceId: string | null | undefined) => {
|
|
1462
|
+
invoice: IInvoice | null;
|
|
1463
|
+
loading: boolean;
|
|
1464
|
+
error: string | null;
|
|
486
1465
|
refetch: () => Promise<void>;
|
|
487
1466
|
};
|
|
488
1467
|
|
|
@@ -586,8 +1565,55 @@ interface ErrorBoundaryState {
|
|
|
586
1565
|
error: Error | null;
|
|
587
1566
|
}
|
|
588
1567
|
/**
|
|
589
|
-
* Error Boundary component for catching React component errors
|
|
590
|
-
* Wraps SDK components to prevent crashes from propagating
|
|
1568
|
+
* Error Boundary component for catching React component errors.
|
|
1569
|
+
* Wraps SDK components to prevent crashes from propagating to the entire app.
|
|
1570
|
+
* Automatically logs errors using the SDK error handler.
|
|
1571
|
+
*
|
|
1572
|
+
* @example
|
|
1573
|
+
* ```tsx
|
|
1574
|
+
* function App() {
|
|
1575
|
+
* return (
|
|
1576
|
+
* <SDKErrorBoundary
|
|
1577
|
+
* fallback={(error, reset) => (
|
|
1578
|
+
* <div>
|
|
1579
|
+
* <p>Error: {error.message}</p>
|
|
1580
|
+
* <button onClick={reset}>Try Again</button>
|
|
1581
|
+
* </div>
|
|
1582
|
+
* )}
|
|
1583
|
+
* onError={(error, errorInfo) => {
|
|
1584
|
+
* // Custom error reporting
|
|
1585
|
+
* reportError(error, errorInfo);
|
|
1586
|
+
* }}
|
|
1587
|
+
* >
|
|
1588
|
+
* <YourApp />
|
|
1589
|
+
* </SDKErrorBoundary>
|
|
1590
|
+
* );
|
|
1591
|
+
* }
|
|
1592
|
+
* ```
|
|
1593
|
+
*
|
|
1594
|
+
* @example
|
|
1595
|
+
* ```tsx
|
|
1596
|
+
* // Simple usage with default fallback
|
|
1597
|
+
* function App() {
|
|
1598
|
+
* return (
|
|
1599
|
+
* <SDKErrorBoundary>
|
|
1600
|
+
* <YourApp />
|
|
1601
|
+
* </SDKErrorBoundary>
|
|
1602
|
+
* );
|
|
1603
|
+
* }
|
|
1604
|
+
* ```
|
|
1605
|
+
*
|
|
1606
|
+
* @example
|
|
1607
|
+
* ```tsx
|
|
1608
|
+
* // Disable auto-reset on props change
|
|
1609
|
+
* function App() {
|
|
1610
|
+
* return (
|
|
1611
|
+
* <SDKErrorBoundary resetOnPropsChange={false}>
|
|
1612
|
+
* <YourApp />
|
|
1613
|
+
* </SDKErrorBoundary>
|
|
1614
|
+
* );
|
|
1615
|
+
* }
|
|
1616
|
+
* ```
|
|
591
1617
|
*/
|
|
592
1618
|
declare class SDKErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
593
1619
|
constructor(props: ErrorBoundaryProps);
|
|
@@ -655,8 +1681,48 @@ declare class ErrorHandler {
|
|
|
655
1681
|
wrapSync<T extends (...args: any[]) => any>(fn: T, context: SDKErrorContext): T;
|
|
656
1682
|
}
|
|
657
1683
|
declare const errorHandler: ErrorHandler;
|
|
1684
|
+
/**
|
|
1685
|
+
* Convenience function to handle an error with context.
|
|
1686
|
+
* Uses the global error handler instance.
|
|
1687
|
+
*
|
|
1688
|
+
* @param error - The error to handle (Error instance, string, or unknown)
|
|
1689
|
+
* @param context - Optional context about where the error occurred
|
|
1690
|
+
*
|
|
1691
|
+
* @example
|
|
1692
|
+
* ```tsx
|
|
1693
|
+
* try {
|
|
1694
|
+
* await someOperation();
|
|
1695
|
+
* } catch (error) {
|
|
1696
|
+
* handleError(error, {
|
|
1697
|
+
* component: 'MyComponent',
|
|
1698
|
+
* action: 'someOperation',
|
|
1699
|
+
* metadata: { userId: '123' },
|
|
1700
|
+
* });
|
|
1701
|
+
* }
|
|
1702
|
+
* ```
|
|
1703
|
+
*/
|
|
658
1704
|
declare function handleError(error: Error | unknown, context?: SDKErrorContext): void;
|
|
1705
|
+
/**
|
|
1706
|
+
* Creates a new SDKError instance with optional code and context.
|
|
1707
|
+
* Useful for creating standardized errors throughout the SDK.
|
|
1708
|
+
*
|
|
1709
|
+
* @param message - Error message
|
|
1710
|
+
* @param code - Optional error code (e.g., 'AUTH_FAILED', 'NETWORK_ERROR')
|
|
1711
|
+
* @param context - Optional context about where the error occurred
|
|
1712
|
+
* @param originalError - Optional original error that caused this error
|
|
1713
|
+
* @returns A new SDKError instance
|
|
1714
|
+
*
|
|
1715
|
+
* @example
|
|
1716
|
+
* ```tsx
|
|
1717
|
+
* throw createSDKError(
|
|
1718
|
+
* 'Failed to authenticate user',
|
|
1719
|
+
* 'AUTH_FAILED',
|
|
1720
|
+
* { component: 'AuthProvider', action: 'signIn' },
|
|
1721
|
+
* originalError
|
|
1722
|
+
* );
|
|
1723
|
+
* ```
|
|
1724
|
+
*/
|
|
659
1725
|
declare function createSDKError(message: string, code?: string, context?: SDKErrorContext, originalError?: Error): SDKError;
|
|
660
1726
|
|
|
661
|
-
export { ApiVersion, BetaForm, SDKErrorBoundary as ErrorBoundary, SDKError, SDKErrorBoundary, SaaSOSProvider, WhenAuthenticated, WhenRoles, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceSwitcher, createSDKError, errorHandler, eventEmitter, handleError, usePlanGroup, useSaaSAuth, useSaaSSettings, useSaaSWorkspaces, useSubscription, useSubscriptionManagement, useUpdateSubscription, useUserAttributes, useUserFeatures };
|
|
662
|
-
export type { ErrorHandlerConfig, EventData, EventType, IEventCallbacks, IPlan, IPlanGroup, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanVersion, IPlanVersionWithPlan, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, SDKErrorContext, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
|
|
1727
|
+
export { ApiVersion, AuthStatus, BetaForm, SDKErrorBoundary as ErrorBoundary, SDKError, SDKErrorBoundary, SaaSOSProvider, WhenAuthenticated, WhenRoles, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceSwitcher, createSDKError, errorHandler, eventEmitter, handleError, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, useSaaSAuth, useSaaSSettings, useSaaSWorkspaces, useSubscription, useSubscriptionManagement, useUpdateSubscription, useUserAttributes, useUserFeatures };
|
|
1728
|
+
export type { BillingInterval, ErrorHandlerConfig, EventData, EventType, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IEventCallbacks, IInvoice, IInvoiceListResponse, IInvoiceResponse, IPlan, IPlanGroup, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionWithPlan, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, InvoiceStatus, SDKErrorContext, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
|