@buildbase/sdk 0.0.11 → 0.0.13
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 +34 -13
- package/dist/index.d.ts +896 -134
- package/dist/index.esm.js +5 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5 -11
- package/dist/index.js.map +1 -1
- package/dist/saas-os.css +1 -1
- package/dist/types/components/ErrorBoundary.d.ts +49 -2
- package/dist/types/components/dropdowns/country/selectCountry.d.ts +2 -2
- package/dist/types/components/dropdowns/currency/selectCurrency.d.ts +2 -2
- package/dist/types/components/dropdowns/language/selectLanguage.d.ts +2 -2
- package/dist/types/components/dropdowns/timezone/selectTimeZone.d.ts +2 -2
- package/dist/types/components/features/index.d.ts +109 -0
- package/dist/types/components/ui/command-select.d.ts +13 -0
- package/dist/types/components/ui/command.d.ts +2 -2
- package/dist/types/components/user/auth.d.ts +64 -0
- package/dist/types/components/user/role.d.ts +70 -0
- package/dist/types/contexts/WorkspaceContext/actions.d.ts +1 -1
- package/dist/types/contexts/WorkspaceContext/types.d.ts +3 -3
- package/dist/types/contexts/shared/useSelectWithEquality.d.ts +10 -0
- package/dist/types/index.d.ts +1 -3
- package/dist/types/lib/api-utils.d.ts +182 -0
- package/dist/types/lib/error-handler.d.ts +58 -0
- package/dist/types/lib/logger.d.ts +27 -0
- package/dist/types/lib/useAsyncEffect.d.ts +29 -0
- package/dist/types/lib/utils.d.ts +5 -0
- package/dist/types/providers/auth/hooks.d.ts +61 -0
- package/dist/types/providers/auth/types.d.ts +12 -0
- package/dist/types/providers/auth/utils.d.ts +7 -2
- package/dist/types/providers/constants.d.ts +1 -0
- 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/hooks.d.ts +112 -4
- package/dist/types/providers/workspace/provider.d.ts +0 -1
- package/dist/types/providers/workspace/subscription-hooks.d.ts +351 -29
- package/dist/types/providers/workspace/types.d.ts +1 -1
- package/package.json +14 -12
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import react__default, { ReactNode
|
|
2
|
+
import react__default, { ReactNode } from 'react';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
interface IDocument {
|
|
@@ -355,6 +355,17 @@ interface IAuthCallbacks {
|
|
|
355
355
|
* @param data - The event data (type varies based on eventType)
|
|
356
356
|
*/
|
|
357
357
|
handleEvent?: (eventType: EventType, data: EventData) => void | Promise<void>;
|
|
358
|
+
/**
|
|
359
|
+
* Called before switching workspace (e.g. generate token, save state).
|
|
360
|
+
* Used when user clicks "Switch to" and when restoring from storage on page refresh.
|
|
361
|
+
* Switch proceeds only when this resolves; reject to abort.
|
|
362
|
+
*/
|
|
363
|
+
onWorkspaceChange?: (params: OnWorkspaceChangeParams) => Promise<void>;
|
|
364
|
+
}
|
|
365
|
+
interface OnWorkspaceChangeParams {
|
|
366
|
+
workspace: IWorkspace;
|
|
367
|
+
user: AuthUser | null;
|
|
368
|
+
role: string | null;
|
|
358
369
|
}
|
|
359
370
|
|
|
360
371
|
interface ISettings {
|
|
@@ -414,7 +425,71 @@ declare const BetaForm: react__default.FC<BetaFormProps>;
|
|
|
414
425
|
interface IProps$2 {
|
|
415
426
|
children: React.ReactNode;
|
|
416
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Conditional component that renders children only when user is authenticated.
|
|
430
|
+
* Returns null if user is not authenticated or authentication status is still loading.
|
|
431
|
+
*
|
|
432
|
+
* @param props - Component props
|
|
433
|
+
* @param props.children - Content to render when authenticated
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```tsx
|
|
437
|
+
* function App() {
|
|
438
|
+
* return (
|
|
439
|
+
* <SaaSOSProvider {...config}>
|
|
440
|
+
* <WhenAuthenticated>
|
|
441
|
+
* <Dashboard />
|
|
442
|
+
* </WhenAuthenticated>
|
|
443
|
+
* <WhenUnauthenticated>
|
|
444
|
+
* <LoginPage />
|
|
445
|
+
* </WhenUnauthenticated>
|
|
446
|
+
* </SaaSOSProvider>
|
|
447
|
+
* );
|
|
448
|
+
* }
|
|
449
|
+
* ```
|
|
450
|
+
*/
|
|
417
451
|
declare const WhenAuthenticated: (props: IProps$2) => react.ReactNode;
|
|
452
|
+
/**
|
|
453
|
+
* Conditional component that renders children only when user is NOT authenticated.
|
|
454
|
+
* Returns null if user is authenticated.
|
|
455
|
+
* Note: Also renders during loading/redirecting states (when not yet authenticated).
|
|
456
|
+
*
|
|
457
|
+
* @param props - Component props
|
|
458
|
+
* @param props.children - Content to render when unauthenticated
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```tsx
|
|
462
|
+
* function App() {
|
|
463
|
+
* return (
|
|
464
|
+
* <SaaSOSProvider {...config}>
|
|
465
|
+
* <WhenUnauthenticated>
|
|
466
|
+
* <LoginPage />
|
|
467
|
+
* </WhenUnauthenticated>
|
|
468
|
+
* <WhenAuthenticated>
|
|
469
|
+
* <Dashboard />
|
|
470
|
+
* </WhenAuthenticated>
|
|
471
|
+
* </SaaSOSProvider>
|
|
472
|
+
* );
|
|
473
|
+
* }
|
|
474
|
+
* ```
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```tsx
|
|
478
|
+
* // Handle loading state separately
|
|
479
|
+
* function App() {
|
|
480
|
+
* const { isLoading } = useSaaSAuth();
|
|
481
|
+
*
|
|
482
|
+
* if (isLoading) return <LoadingSpinner />;
|
|
483
|
+
*
|
|
484
|
+
* return (
|
|
485
|
+
* <>
|
|
486
|
+
* <WhenUnauthenticated><LoginPage /></WhenUnauthenticated>
|
|
487
|
+
* <WhenAuthenticated><Dashboard /></WhenAuthenticated>
|
|
488
|
+
* </>
|
|
489
|
+
* );
|
|
490
|
+
* }
|
|
491
|
+
* ```
|
|
492
|
+
*/
|
|
418
493
|
declare const WhenUnauthenticated: (props: IProps$2) => react.ReactNode;
|
|
419
494
|
|
|
420
495
|
interface IProps$1 {
|
|
@@ -422,18 +497,258 @@ interface IProps$1 {
|
|
|
422
497
|
children: React.ReactNode;
|
|
423
498
|
fallback?: React.ReactNode;
|
|
424
499
|
}
|
|
500
|
+
/**
|
|
501
|
+
* Conditional component that renders children only when user has one of the specified roles.
|
|
502
|
+
* Checks the user's global role (not workspace-specific).
|
|
503
|
+
*
|
|
504
|
+
* @param props - Component props
|
|
505
|
+
* @param props.roles - Array of role strings to check against user's role
|
|
506
|
+
* @param props.children - Content to render when user has matching role
|
|
507
|
+
* @param props.fallback - Optional content to render when user doesn't have matching role (default: null)
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```tsx
|
|
511
|
+
* function AdminPanel() {
|
|
512
|
+
* return (
|
|
513
|
+
* <WhenRoles roles={['admin', 'super-admin']}>
|
|
514
|
+
* <AdminContent />
|
|
515
|
+
* </WhenRoles>
|
|
516
|
+
* );
|
|
517
|
+
* }
|
|
518
|
+
* ```
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```tsx
|
|
522
|
+
* // With fallback
|
|
523
|
+
* function SettingsPage() {
|
|
524
|
+
* return (
|
|
525
|
+
* <WhenRoles
|
|
526
|
+
* roles={['admin']}
|
|
527
|
+
* fallback={<p>You don't have permission to access this page.</p>}
|
|
528
|
+
* >
|
|
529
|
+
* <AdminSettings />
|
|
530
|
+
* </WhenRoles>
|
|
531
|
+
* );
|
|
532
|
+
* }
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
425
535
|
declare const WhenRoles: (props: IProps$1) => react.ReactNode;
|
|
536
|
+
/**
|
|
537
|
+
* Conditional component that renders children only when user has one of the specified roles
|
|
538
|
+
* in the current workspace. Checks workspace-specific role, not global role.
|
|
539
|
+
*
|
|
540
|
+
* @param props - Component props
|
|
541
|
+
* @param props.roles - Array of role strings to check against user's workspace role
|
|
542
|
+
* @param props.children - Content to render when user has matching workspace role
|
|
543
|
+
* @param props.fallback - Optional content to render when user doesn't have matching role (default: null)
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```tsx
|
|
547
|
+
* function WorkspaceSettings() {
|
|
548
|
+
* return (
|
|
549
|
+
* <WhenWorkspaceRoles roles={['owner', 'admin']}>
|
|
550
|
+
* <SettingsContent />
|
|
551
|
+
* </WhenWorkspaceRoles>
|
|
552
|
+
* );
|
|
553
|
+
* }
|
|
554
|
+
* ```
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```tsx
|
|
558
|
+
* // Edge case: User not in current workspace
|
|
559
|
+
* function WorkspaceContent() {
|
|
560
|
+
* return (
|
|
561
|
+
* <WhenWorkspaceRoles
|
|
562
|
+
* roles={['member']}
|
|
563
|
+
* fallback={<p>You are not a member of this workspace.</p>}
|
|
564
|
+
* >
|
|
565
|
+
* <WorkspaceDashboard />
|
|
566
|
+
* </WhenWorkspaceRoles>
|
|
567
|
+
* );
|
|
568
|
+
* }
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
426
571
|
declare const WhenWorkspaceRoles: (props: IProps$1) => react.ReactNode;
|
|
427
572
|
|
|
428
573
|
interface IProps {
|
|
429
574
|
slug: string;
|
|
430
575
|
children: React.ReactNode;
|
|
431
576
|
}
|
|
577
|
+
/**
|
|
578
|
+
* Conditional component that renders children only when the specified workspace feature is enabled.
|
|
579
|
+
* Checks feature flags at the workspace level.
|
|
580
|
+
*
|
|
581
|
+
* @param props - Component props
|
|
582
|
+
* @param props.slug - Feature flag slug/key to check
|
|
583
|
+
* @param props.children - Content to render when feature is enabled
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```tsx
|
|
587
|
+
* function PremiumFeature() {
|
|
588
|
+
* return (
|
|
589
|
+
* <WhenWorkspaceFeatureEnabled slug="premium-analytics">
|
|
590
|
+
* <AnalyticsDashboard />
|
|
591
|
+
* </WhenWorkspaceFeatureEnabled>
|
|
592
|
+
* );
|
|
593
|
+
* }
|
|
594
|
+
* ```
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* ```tsx
|
|
598
|
+
* // Multiple features
|
|
599
|
+
* function FeatureContent() {
|
|
600
|
+
* return (
|
|
601
|
+
* <>
|
|
602
|
+
* <WhenWorkspaceFeatureEnabled slug="feature-a">
|
|
603
|
+
* <FeatureA />
|
|
604
|
+
* </WhenWorkspaceFeatureEnabled>
|
|
605
|
+
* <WhenWorkspaceFeatureEnabled slug="feature-b">
|
|
606
|
+
* <FeatureB />
|
|
607
|
+
* </WhenWorkspaceFeatureEnabled>
|
|
608
|
+
* </>
|
|
609
|
+
* );
|
|
610
|
+
* }
|
|
611
|
+
* ```
|
|
612
|
+
*/
|
|
432
613
|
declare const WhenWorkspaceFeatureEnabled: (props: IProps) => react.ReactNode;
|
|
614
|
+
/**
|
|
615
|
+
* Conditional component that renders children only when the specified workspace feature is disabled.
|
|
616
|
+
* Checks feature flags at the workspace level.
|
|
617
|
+
*
|
|
618
|
+
* @param props - Component props
|
|
619
|
+
* @param props.slug - Feature flag slug/key to check
|
|
620
|
+
* @param props.children - Content to render when feature is disabled
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```tsx
|
|
624
|
+
* function UpgradePrompt() {
|
|
625
|
+
* return (
|
|
626
|
+
* <WhenWorkspaceFeatureDisabled slug="premium-feature">
|
|
627
|
+
* <UpgradeButton />
|
|
628
|
+
* </WhenWorkspaceFeatureDisabled>
|
|
629
|
+
* );
|
|
630
|
+
* }
|
|
631
|
+
* ```
|
|
632
|
+
*/
|
|
433
633
|
declare const WhenWorkspaceFeatureDisabled: (props: IProps) => react.ReactNode;
|
|
634
|
+
/**
|
|
635
|
+
* Conditional component that renders children only when the specified user feature is enabled.
|
|
636
|
+
* Checks feature flags at the user level (from UserProvider).
|
|
637
|
+
*
|
|
638
|
+
* @param props - Component props
|
|
639
|
+
* @param props.slug - Feature flag slug/key to check
|
|
640
|
+
* @param props.children - Content to render when feature is enabled
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```tsx
|
|
644
|
+
* function BetaFeature() {
|
|
645
|
+
* return (
|
|
646
|
+
* <WhenUserFeatureEnabled slug="beta-access">
|
|
647
|
+
* <BetaContent />
|
|
648
|
+
* </WhenUserFeatureEnabled>
|
|
649
|
+
* );
|
|
650
|
+
* }
|
|
651
|
+
* ```
|
|
652
|
+
*
|
|
653
|
+
* @example
|
|
654
|
+
* ```tsx
|
|
655
|
+
* // Edge case: Feature not loaded yet
|
|
656
|
+
* function FeatureContent() {
|
|
657
|
+
* const { isLoading } = useUserFeatures();
|
|
658
|
+
*
|
|
659
|
+
* if (isLoading) return <Loading />;
|
|
660
|
+
*
|
|
661
|
+
* return (
|
|
662
|
+
* <WhenUserFeatureEnabled slug="feature-x">
|
|
663
|
+
* <FeatureX />
|
|
664
|
+
* </WhenUserFeatureEnabled>
|
|
665
|
+
* );
|
|
666
|
+
* }
|
|
667
|
+
* ```
|
|
668
|
+
*/
|
|
434
669
|
declare const WhenUserFeatureEnabled: (props: IProps) => react.ReactNode;
|
|
670
|
+
/**
|
|
671
|
+
* Conditional component that renders children only when the specified user feature is disabled.
|
|
672
|
+
* Checks feature flags at the user level (from UserProvider).
|
|
673
|
+
*
|
|
674
|
+
* @param props - Component props
|
|
675
|
+
* @param props.slug - Feature flag slug/key to check
|
|
676
|
+
* @param props.children - Content to render when feature is disabled
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```tsx
|
|
680
|
+
* function UpgradePrompt() {
|
|
681
|
+
* return (
|
|
682
|
+
* <WhenUserFeatureDisabled slug="premium-access">
|
|
683
|
+
* <UpgradeButton />
|
|
684
|
+
* </WhenUserFeatureDisabled>
|
|
685
|
+
* );
|
|
686
|
+
* }
|
|
687
|
+
* ```
|
|
688
|
+
*/
|
|
435
689
|
declare const WhenUserFeatureDisabled: (props: IProps) => react.ReactNode;
|
|
436
690
|
|
|
691
|
+
/**
|
|
692
|
+
* Main authentication hook for the SDK.
|
|
693
|
+
* Provides authentication state, user session, and auth actions.
|
|
694
|
+
*
|
|
695
|
+
* @returns An object containing:
|
|
696
|
+
* - `user`: Current authenticated user object (null if not authenticated)
|
|
697
|
+
* - `session`: Full session object with user and token (null if not authenticated)
|
|
698
|
+
* - `status`: Current authentication status (loading, redirecting, authenticating, authenticated, unauthenticated)
|
|
699
|
+
* - `isLoading`: Boolean indicating if auth state is being determined
|
|
700
|
+
* - `isAuthenticated`: Boolean indicating if user is authenticated
|
|
701
|
+
* - `isRedirecting`: Boolean indicating if redirecting to OAuth provider
|
|
702
|
+
* - `signIn()`: Function to initiate OAuth sign-in flow
|
|
703
|
+
* - `signOut()`: Function to sign out the current user
|
|
704
|
+
* - `openWorkspaceSettings(section?)`: Function to open workspace settings dialog
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```tsx
|
|
708
|
+
* function MyComponent() {
|
|
709
|
+
* const { user, isAuthenticated, signIn, signOut } = useSaaSAuth();
|
|
710
|
+
*
|
|
711
|
+
* if (!isAuthenticated) {
|
|
712
|
+
* return <button onClick={signIn}>Sign In</button>;
|
|
713
|
+
* }
|
|
714
|
+
*
|
|
715
|
+
* return (
|
|
716
|
+
* <div>
|
|
717
|
+
* <p>Welcome, {user?.name}</p>
|
|
718
|
+
* <button onClick={signOut}>Sign Out</button>
|
|
719
|
+
* </div>
|
|
720
|
+
* );
|
|
721
|
+
* }
|
|
722
|
+
* ```
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```tsx
|
|
726
|
+
* // Handle loading state
|
|
727
|
+
* function App() {
|
|
728
|
+
* const { status, isLoading } = useSaaSAuth();
|
|
729
|
+
*
|
|
730
|
+
* if (isLoading) {
|
|
731
|
+
* return <LoadingSpinner />;
|
|
732
|
+
* }
|
|
733
|
+
*
|
|
734
|
+
* return <MainContent />;
|
|
735
|
+
* }
|
|
736
|
+
* ```
|
|
737
|
+
*
|
|
738
|
+
* @example
|
|
739
|
+
* ```tsx
|
|
740
|
+
* // Open workspace settings
|
|
741
|
+
* function SettingsButton() {
|
|
742
|
+
* const { openWorkspaceSettings } = useSaaSAuth();
|
|
743
|
+
*
|
|
744
|
+
* return (
|
|
745
|
+
* <button onClick={() => openWorkspaceSettings('general')}>
|
|
746
|
+
* Open Settings
|
|
747
|
+
* </button>
|
|
748
|
+
* );
|
|
749
|
+
* }
|
|
750
|
+
* ```
|
|
751
|
+
*/
|
|
437
752
|
declare function useSaaSAuth(): {
|
|
438
753
|
signIn: () => Promise<void>;
|
|
439
754
|
signOut: () => Promise<void>;
|
|
@@ -446,9 +761,48 @@ declare function useSaaSAuth(): {
|
|
|
446
761
|
status: AuthStatus;
|
|
447
762
|
};
|
|
448
763
|
|
|
764
|
+
/**
|
|
765
|
+
* Hook to access organization settings from the OS context.
|
|
766
|
+
* Automatically fetches settings when OS config is ready.
|
|
767
|
+
*
|
|
768
|
+
* @returns An object containing:
|
|
769
|
+
* - `settings`: Organization settings object (null if not loaded)
|
|
770
|
+
* - `getSettings(signal?)`: Function to manually fetch settings (supports AbortSignal)
|
|
771
|
+
*
|
|
772
|
+
* @example
|
|
773
|
+
* ```tsx
|
|
774
|
+
* function SettingsDisplay() {
|
|
775
|
+
* const { settings } = useSaaSSettings();
|
|
776
|
+
*
|
|
777
|
+
* if (!settings) return <Loading />;
|
|
778
|
+
*
|
|
779
|
+
* return (
|
|
780
|
+
* <div>
|
|
781
|
+
* <p>Organization: {settings.name}</p>
|
|
782
|
+
* <p>Theme: {settings.theme}</p>
|
|
783
|
+
* </div>
|
|
784
|
+
* );
|
|
785
|
+
* }
|
|
786
|
+
* ```
|
|
787
|
+
*
|
|
788
|
+
* @example
|
|
789
|
+
* ```tsx
|
|
790
|
+
* // Manual fetch with abort signal
|
|
791
|
+
* function SettingsLoader() {
|
|
792
|
+
* const { getSettings } = useSaaSSettings();
|
|
793
|
+
*
|
|
794
|
+
* useEffect(() => {
|
|
795
|
+
* const controller = new AbortController();
|
|
796
|
+
* getSettings(controller.signal);
|
|
797
|
+
*
|
|
798
|
+
* return () => controller.abort();
|
|
799
|
+
* }, [getSettings]);
|
|
800
|
+
* }
|
|
801
|
+
* ```
|
|
802
|
+
*/
|
|
449
803
|
declare function useSaaSSettings(): {
|
|
450
804
|
settings: ISettings | null | undefined;
|
|
451
|
-
getSettings: () => Promise<ISettings | null>;
|
|
805
|
+
getSettings: (signal?: AbortSignal) => Promise<ISettings | null>;
|
|
452
806
|
};
|
|
453
807
|
|
|
454
808
|
interface UserContextValue {
|
|
@@ -462,7 +816,78 @@ interface UserContextValue {
|
|
|
462
816
|
refreshFeatures: () => Promise<void>;
|
|
463
817
|
}
|
|
464
818
|
|
|
819
|
+
/**
|
|
820
|
+
* Hook to access user attributes from the UserProvider.
|
|
821
|
+
* Must be used within a UserProvider component.
|
|
822
|
+
*
|
|
823
|
+
* @returns User context object containing:
|
|
824
|
+
* - `attributes`: Record of user attribute key-value pairs
|
|
825
|
+
* - `isLoading`: Boolean indicating if attributes are being loaded
|
|
826
|
+
* - `error`: Error message string (null if no error)
|
|
827
|
+
* - `refreshAttributes()`: Function to manually refresh attributes
|
|
828
|
+
*
|
|
829
|
+
* @throws {Error} If used outside of UserProvider
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* ```tsx
|
|
833
|
+
* function UserProfile() {
|
|
834
|
+
* const { attributes, isLoading } = useUserAttributes();
|
|
835
|
+
*
|
|
836
|
+
* if (isLoading) return <Loading />;
|
|
837
|
+
*
|
|
838
|
+
* return (
|
|
839
|
+
* <div>
|
|
840
|
+
* <p>Plan: {attributes?.plan}</p>
|
|
841
|
+
* <p>Company: {attributes?.company}</p>
|
|
842
|
+
* </div>
|
|
843
|
+
* );
|
|
844
|
+
* }
|
|
845
|
+
* ```
|
|
846
|
+
*/
|
|
465
847
|
declare function useUserAttributes(): UserContextValue;
|
|
848
|
+
/**
|
|
849
|
+
* Hook to access user feature flags from the UserProvider.
|
|
850
|
+
* Must be used within a UserProvider component.
|
|
851
|
+
*
|
|
852
|
+
* @returns An object containing:
|
|
853
|
+
* - `features`: Record of feature flag key-value pairs (boolean values)
|
|
854
|
+
* - `isLoading`: Boolean indicating if features are being loaded
|
|
855
|
+
* - `error`: Error message string (null if no error)
|
|
856
|
+
* - `refreshFeatures()`: Function to manually refresh features
|
|
857
|
+
* - `isFeatureEnabled(featureId)`: Function to check if a specific feature is enabled
|
|
858
|
+
*
|
|
859
|
+
* @throws {Error} If used outside of UserProvider
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* ```tsx
|
|
863
|
+
* function FeatureContent() {
|
|
864
|
+
* const { isFeatureEnabled, isLoading } = useUserFeatures();
|
|
865
|
+
*
|
|
866
|
+
* if (isLoading) return <Loading />;
|
|
867
|
+
*
|
|
868
|
+
* if (isFeatureEnabled('premium-feature')) {
|
|
869
|
+
* return <PremiumFeature />;
|
|
870
|
+
* }
|
|
871
|
+
*
|
|
872
|
+
* return <BasicFeature />;
|
|
873
|
+
* }
|
|
874
|
+
* ```
|
|
875
|
+
*
|
|
876
|
+
* @example
|
|
877
|
+
* ```tsx
|
|
878
|
+
* // Check multiple features
|
|
879
|
+
* function Dashboard() {
|
|
880
|
+
* const { isFeatureEnabled } = useUserFeatures();
|
|
881
|
+
*
|
|
882
|
+
* return (
|
|
883
|
+
* <div>
|
|
884
|
+
* {isFeatureEnabled('analytics') && <Analytics />}
|
|
885
|
+
* {isFeatureEnabled('reports') && <Reports />}
|
|
886
|
+
* </div>
|
|
887
|
+
* );
|
|
888
|
+
* }
|
|
889
|
+
* ```
|
|
890
|
+
*/
|
|
466
891
|
declare function useUserFeatures(): {
|
|
467
892
|
features: Record<string, boolean>;
|
|
468
893
|
isLoading: boolean;
|
|
@@ -471,11 +896,111 @@ declare function useUserFeatures(): {
|
|
|
471
896
|
isFeatureEnabled: (featureId: string) => boolean;
|
|
472
897
|
};
|
|
473
898
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
899
|
+
/**
|
|
900
|
+
* Main workspace management hook for the SDK.
|
|
901
|
+
* Provides workspace state, CRUD operations, and user management.
|
|
902
|
+
*
|
|
903
|
+
* @returns An object containing:
|
|
904
|
+
* - `workspaces`: Array of all workspaces the user has access to
|
|
905
|
+
* - `currentWorkspace`: Currently selected workspace (null if none selected)
|
|
906
|
+
* - `loading`: Boolean indicating if workspaces are being fetched
|
|
907
|
+
* - `error`: Error message string (null if no error)
|
|
908
|
+
* - `refreshing`: Boolean indicating if workspaces are being refreshed in background
|
|
909
|
+
* - `switching`: Boolean - true when a workspace switch is in progress
|
|
910
|
+
* - `fetchWorkspaces()`: Function to fetch all workspaces
|
|
911
|
+
* - `refreshWorkspaces()`: Function to refresh workspaces in background (non-blocking)
|
|
912
|
+
* - `setCurrentWorkspace(workspace)`: Function to set the current workspace (direct, no callback)
|
|
913
|
+
* - `switchToWorkspace(workspace)`: Centralized switch - calls onWorkspaceChange first, then sets workspace
|
|
914
|
+
* - `resetCurrentWorkspace()`: Function to clear the current workspace
|
|
915
|
+
* - `createWorkspace(name, image?)`: Function to create a new workspace
|
|
916
|
+
* - `updateWorkspace(workspace, data)`: Function to update a workspace
|
|
917
|
+
* - `deleteWorkspace(workspaceId)`: Function to delete a workspace (owner only)
|
|
918
|
+
* - `getWorkspace(workspaceId)`: Function to fetch a specific workspace
|
|
919
|
+
* - `getUsers(workspaceId)`: Function to fetch users in a workspace
|
|
920
|
+
* - `addUser(workspaceId, email, role)`: Function to add a user to a workspace
|
|
921
|
+
* - `removeUser(workspaceId, userId)`: Function to remove a user from a workspace
|
|
922
|
+
* - `updateUser(workspaceId, userId, config)`: Function to update a user in a workspace
|
|
923
|
+
* - `getProfile()`: Function to fetch current user profile
|
|
924
|
+
* - `updateUserProfile(config)`: Function to update current user profile
|
|
925
|
+
* - `allFeatures`: Array of all available feature flags
|
|
926
|
+
* - `getFeatures()`: Function to fetch all available features
|
|
927
|
+
* - `updateFeature(workspaceId, key, value)`: Function to update a feature flag
|
|
928
|
+
*
|
|
929
|
+
* @example
|
|
930
|
+
* ```tsx
|
|
931
|
+
* function WorkspaceList() {
|
|
932
|
+
* const { workspaces, loading, fetchWorkspaces } = useSaaSWorkspaces();
|
|
933
|
+
*
|
|
934
|
+
* useEffect(() => {
|
|
935
|
+
* fetchWorkspaces();
|
|
936
|
+
* }, [fetchWorkspaces]);
|
|
937
|
+
*
|
|
938
|
+
* if (loading) return <Loading />;
|
|
939
|
+
*
|
|
940
|
+
* return (
|
|
941
|
+
* <ul>
|
|
942
|
+
* {workspaces.map(ws => (
|
|
943
|
+
* <li key={ws._id}>{ws.name}</li>
|
|
944
|
+
* ))}
|
|
945
|
+
* </ul>
|
|
946
|
+
* );
|
|
947
|
+
* }
|
|
948
|
+
* ```
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```tsx
|
|
952
|
+
* // Create a new workspace
|
|
953
|
+
* function CreateWorkspace() {
|
|
954
|
+
* const { createWorkspace } = useSaaSWorkspaces();
|
|
955
|
+
*
|
|
956
|
+
* const handleCreate = async () => {
|
|
957
|
+
* try {
|
|
958
|
+
* await createWorkspace('My Workspace', 'https://example.com/logo.png');
|
|
959
|
+
* } catch (error) {
|
|
960
|
+
* console.error('Failed to create workspace:', error);
|
|
961
|
+
* }
|
|
962
|
+
* };
|
|
963
|
+
*
|
|
964
|
+
* return <button onClick={handleCreate}>Create Workspace</button>;
|
|
965
|
+
* }
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
968
|
+
* @example
|
|
969
|
+
* ```tsx
|
|
970
|
+
* // Delete workspace (owner only)
|
|
971
|
+
* function DeleteWorkspaceButton({ workspaceId }) {
|
|
972
|
+
* const { deleteWorkspace } = useSaaSWorkspaces();
|
|
973
|
+
*
|
|
974
|
+
* const handleDelete = async () => {
|
|
975
|
+
* if (!confirm('Are you sure?')) return;
|
|
976
|
+
* try {
|
|
977
|
+
* await deleteWorkspace(workspaceId);
|
|
978
|
+
* } catch (error) {
|
|
979
|
+
* // Error: "Only the workspace creator can delete the workspace"
|
|
980
|
+
* alert(error.message);
|
|
981
|
+
* }
|
|
982
|
+
* };
|
|
983
|
+
*
|
|
984
|
+
* return <button onClick={handleDelete}>Delete</button>;
|
|
985
|
+
* }
|
|
986
|
+
* ```
|
|
987
|
+
*
|
|
988
|
+
* @example
|
|
989
|
+
* ```tsx
|
|
990
|
+
* // Edge case: Workspace removed from user's access
|
|
991
|
+
* function WorkspaceContent() {
|
|
992
|
+
* const { currentWorkspace, workspaces } = useSaaSWorkspaces();
|
|
993
|
+
*
|
|
994
|
+
* // If current workspace is not in the list, it was removed
|
|
995
|
+
* // The hook automatically switches to first available workspace
|
|
996
|
+
* if (!currentWorkspace) {
|
|
997
|
+
* return <p>No workspace selected</p>;
|
|
998
|
+
* }
|
|
999
|
+
*
|
|
1000
|
+
* return <div>{currentWorkspace.name}</div>;
|
|
1001
|
+
* }
|
|
1002
|
+
* ```
|
|
1003
|
+
*/
|
|
479
1004
|
declare const useSaaSWorkspaces: () => {
|
|
480
1005
|
workspaces: IWorkspace[];
|
|
481
1006
|
loading: boolean;
|
|
@@ -483,16 +1008,19 @@ declare const useSaaSWorkspaces: () => {
|
|
|
483
1008
|
fetchWorkspaces: () => Promise<void>;
|
|
484
1009
|
refreshWorkspaces: () => Promise<void>;
|
|
485
1010
|
refreshing: boolean;
|
|
486
|
-
WorkspaceSwitcher: typeof WorkspaceSwitcher;
|
|
487
1011
|
currentWorkspace: IWorkspace | null;
|
|
488
|
-
setCurrentWorkspace: (ws: IWorkspace
|
|
1012
|
+
setCurrentWorkspace: (ws: IWorkspace, options?: {
|
|
1013
|
+
forceEmit?: boolean;
|
|
1014
|
+
}) => void;
|
|
1015
|
+
switchToWorkspace: (ws: IWorkspace, options?: {
|
|
1016
|
+
forceEmit?: boolean;
|
|
1017
|
+
}) => Promise<void>;
|
|
489
1018
|
resetCurrentWorkspace: () => void;
|
|
490
1019
|
createWorkspace: (name: string, image: string) => Promise<void>;
|
|
491
1020
|
allFeatures: IWorkspaceFeature[];
|
|
492
1021
|
getFeatures: () => Promise<IWorkspaceFeature[] | null>;
|
|
493
1022
|
updateFeature: (workspaceId: string, key: string, value: boolean) => Promise<IWorkspace>;
|
|
494
1023
|
getWorkspace: (workspaceId: string) => Promise<IWorkspace>;
|
|
495
|
-
switching: boolean;
|
|
496
1024
|
updateWorkspace: (ws: IWorkspace, _data: Partial<IWorkspace>) => Promise<void>;
|
|
497
1025
|
getUsers: (workspaceId: string) => Promise<IWorkspaceUser[]>;
|
|
498
1026
|
addUser: (workspaceId: string, email: string, role: string) => Promise<{
|
|
@@ -515,12 +1043,49 @@ declare const useSaaSWorkspaces: () => {
|
|
|
515
1043
|
deleteWorkspace: (workspaceId: string) => Promise<{
|
|
516
1044
|
success: boolean;
|
|
517
1045
|
}>;
|
|
1046
|
+
switching: boolean;
|
|
518
1047
|
};
|
|
519
1048
|
|
|
1049
|
+
declare function WorkspaceSwitcher(props: {
|
|
1050
|
+
trigger: (isLoading: boolean, currentWorkspace: IWorkspace | null) => ReactNode;
|
|
1051
|
+
}): react_jsx_runtime.JSX.Element;
|
|
1052
|
+
|
|
520
1053
|
/**
|
|
521
|
-
* Hook to get and manage the current subscription for a workspace
|
|
522
|
-
*
|
|
523
|
-
*
|
|
1054
|
+
* Hook to get and manage the current subscription for a workspace.
|
|
1055
|
+
* Automatically fetches subscription when workspaceId changes.
|
|
1056
|
+
*
|
|
1057
|
+
* @param workspaceId - The workspace ID to get subscription for. Can be null/undefined to disable fetching.
|
|
1058
|
+
* @returns An object containing:
|
|
1059
|
+
* - `subscription`: Current subscription data (null if no subscription or not loaded)
|
|
1060
|
+
* - `loading`: Boolean indicating if subscription is being fetched
|
|
1061
|
+
* - `error`: Error message string (null if no error)
|
|
1062
|
+
* - `refetch()`: Function to manually refetch the subscription
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```tsx
|
|
1066
|
+
* function SubscriptionStatus() {
|
|
1067
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1068
|
+
* const { subscription, loading, error } = useSubscription(currentWorkspace?._id);
|
|
1069
|
+
*
|
|
1070
|
+
* if (loading) return <Loading />;
|
|
1071
|
+
* if (error) return <Error message={error} />;
|
|
1072
|
+
* if (!subscription) return <p>No active subscription</p>;
|
|
1073
|
+
*
|
|
1074
|
+
* return <p>Plan: {subscription.plan.name}</p>;
|
|
1075
|
+
* }
|
|
1076
|
+
* ```
|
|
1077
|
+
*
|
|
1078
|
+
* @example
|
|
1079
|
+
* ```tsx
|
|
1080
|
+
* // Edge case: Workspace ID changes
|
|
1081
|
+
* function SubscriptionComponent({ workspaceId }) {
|
|
1082
|
+
* const { subscription, refetch } = useSubscription(workspaceId);
|
|
1083
|
+
*
|
|
1084
|
+
* // Subscription automatically refetches when workspaceId changes
|
|
1085
|
+
* // Use refetch() to manually refresh after mutations
|
|
1086
|
+
* return <SubscriptionDetails subscription={subscription} />;
|
|
1087
|
+
* }
|
|
1088
|
+
* ```
|
|
524
1089
|
*/
|
|
525
1090
|
declare const useSubscription: (workspaceId: string | null | undefined) => {
|
|
526
1091
|
subscription: ISubscriptionResponse | null;
|
|
@@ -529,12 +1094,50 @@ declare const useSubscription: (workspaceId: string | null | undefined) => {
|
|
|
529
1094
|
refetch: () => Promise<void>;
|
|
530
1095
|
};
|
|
531
1096
|
/**
|
|
532
|
-
* Hook to get the plan group for a workspace
|
|
1097
|
+
* Hook to get the plan group for a workspace.
|
|
533
1098
|
* Returns the plan group containing the current plan if subscription exists,
|
|
534
|
-
* otherwise returns the latest published group
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
* @
|
|
1099
|
+
* otherwise returns the latest published group.
|
|
1100
|
+
* Automatically fetches when workspaceId or groupVersionId changes.
|
|
1101
|
+
*
|
|
1102
|
+
* @param workspaceId - The workspace ID to get plan group for. Can be null/undefined to disable fetching.
|
|
1103
|
+
* @param groupVersionId - Optional: specific group version ID to fetch (for viewing historical versions)
|
|
1104
|
+
* @returns An object containing:
|
|
1105
|
+
* - `planGroup`: Plan group data (null if not loaded)
|
|
1106
|
+
* - `loading`: Boolean indicating if plan group is being fetched
|
|
1107
|
+
* - `error`: Error message string (null if no error)
|
|
1108
|
+
* - `refetch()`: Function to manually refetch the plan group
|
|
1109
|
+
*
|
|
1110
|
+
* @example
|
|
1111
|
+
* ```tsx
|
|
1112
|
+
* function PlanGroupDisplay() {
|
|
1113
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1114
|
+
* const { planGroup, loading } = usePlanGroup(currentWorkspace?._id);
|
|
1115
|
+
*
|
|
1116
|
+
* if (loading) return <Loading />;
|
|
1117
|
+
* if (!planGroup) return <p>No plan group available</p>;
|
|
1118
|
+
*
|
|
1119
|
+
* return (
|
|
1120
|
+
* <div>
|
|
1121
|
+
* <h3>{planGroup.name}</h3>
|
|
1122
|
+
* {planGroup.plans.map(plan => (
|
|
1123
|
+
* <PlanCard key={plan._id} plan={plan} />
|
|
1124
|
+
* ))}
|
|
1125
|
+
* </div>
|
|
1126
|
+
* );
|
|
1127
|
+
* }
|
|
1128
|
+
* ```
|
|
1129
|
+
*
|
|
1130
|
+
* @example
|
|
1131
|
+
* ```tsx
|
|
1132
|
+
* // Fetch specific version for comparison
|
|
1133
|
+
* function PlanVersionComparison() {
|
|
1134
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1135
|
+
* const current = usePlanGroup(currentWorkspace?._id);
|
|
1136
|
+
* const previous = usePlanGroup(currentWorkspace?._id, 'previous-version-id');
|
|
1137
|
+
*
|
|
1138
|
+
* return <ComparePlans current={current.planGroup} previous={previous.planGroup} />;
|
|
1139
|
+
* }
|
|
1140
|
+
* ```
|
|
538
1141
|
*/
|
|
539
1142
|
declare const usePlanGroup: (workspaceId: string | null | undefined, groupVersionId?: string | null) => {
|
|
540
1143
|
planGroup: IPlanGroupResponse | null;
|
|
@@ -543,9 +1146,36 @@ declare const usePlanGroup: (workspaceId: string | null | undefined, groupVersio
|
|
|
543
1146
|
refetch: () => Promise<void>;
|
|
544
1147
|
};
|
|
545
1148
|
/**
|
|
546
|
-
* Hook to get all available versions of a plan group for a workspace
|
|
547
|
-
*
|
|
548
|
-
*
|
|
1149
|
+
* Hook to get all available versions of a plan group for a workspace.
|
|
1150
|
+
* Shows current version and available newer versions for upgrade paths.
|
|
1151
|
+
* Automatically fetches when workspaceId changes.
|
|
1152
|
+
*
|
|
1153
|
+
* @param workspaceId - The workspace ID to get plan group versions for. Can be null/undefined to disable fetching.
|
|
1154
|
+
* @returns An object containing:
|
|
1155
|
+
* - `versions`: Plan group versions response with currentVersion and availableVersions
|
|
1156
|
+
* - `loading`: Boolean indicating if versions are being fetched
|
|
1157
|
+
* - `error`: Error message string (null if no error)
|
|
1158
|
+
* - `refetch()`: Function to manually refetch the versions
|
|
1159
|
+
*
|
|
1160
|
+
* @example
|
|
1161
|
+
* ```tsx
|
|
1162
|
+
* function UpgradeOptions() {
|
|
1163
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1164
|
+
* const { versions, loading } = usePlanGroupVersions(currentWorkspace?._id);
|
|
1165
|
+
*
|
|
1166
|
+
* if (loading) return <Loading />;
|
|
1167
|
+
*
|
|
1168
|
+
* return (
|
|
1169
|
+
* <div>
|
|
1170
|
+
* <p>Current: {versions?.currentVersion.name}</p>
|
|
1171
|
+
* <h4>Available Upgrades:</h4>
|
|
1172
|
+
* {versions?.availableVersions.map(version => (
|
|
1173
|
+
* <UpgradeCard key={version._id} version={version} />
|
|
1174
|
+
* ))}
|
|
1175
|
+
* </div>
|
|
1176
|
+
* );
|
|
1177
|
+
* }
|
|
1178
|
+
* ```
|
|
549
1179
|
*/
|
|
550
1180
|
declare const usePlanGroupVersions: (workspaceId: string | null | undefined) => {
|
|
551
1181
|
versions: IPlanGroupVersionsResponse | null;
|
|
@@ -554,9 +1184,62 @@ declare const usePlanGroupVersions: (workspaceId: string | null | undefined) =>
|
|
|
554
1184
|
refetch: () => Promise<void>;
|
|
555
1185
|
};
|
|
556
1186
|
/**
|
|
557
|
-
* Hook to create checkout session for new subscription
|
|
558
|
-
*
|
|
559
|
-
*
|
|
1187
|
+
* Hook to create a checkout session for a new subscription.
|
|
1188
|
+
* Returns a function to initiate the checkout process.
|
|
1189
|
+
*
|
|
1190
|
+
* @param workspaceId - The workspace ID to create checkout session for. Can be null/undefined.
|
|
1191
|
+
* @returns An object containing:
|
|
1192
|
+
* - `createCheckoutSession(request)`: Function to create checkout session (throws if workspaceId is null)
|
|
1193
|
+
* - `loading`: Boolean indicating if checkout session is being created
|
|
1194
|
+
* - `error`: Error message string (null if no error)
|
|
1195
|
+
*
|
|
1196
|
+
* @example
|
|
1197
|
+
* ```tsx
|
|
1198
|
+
* function SubscribeButton({ planVersionId }) {
|
|
1199
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1200
|
+
* const { createCheckoutSession, loading } = useCreateCheckoutSession(currentWorkspace?._id);
|
|
1201
|
+
*
|
|
1202
|
+
* const handleSubscribe = async () => {
|
|
1203
|
+
* try {
|
|
1204
|
+
* const result = await createCheckoutSession({
|
|
1205
|
+
* planVersionId,
|
|
1206
|
+
* successUrl: window.location.href,
|
|
1207
|
+
* cancelUrl: window.location.href,
|
|
1208
|
+
* });
|
|
1209
|
+
* // Redirect to checkout
|
|
1210
|
+
* window.location.href = result.checkoutUrl;
|
|
1211
|
+
* } catch (error) {
|
|
1212
|
+
* console.error('Failed to create checkout:', error);
|
|
1213
|
+
* }
|
|
1214
|
+
* };
|
|
1215
|
+
*
|
|
1216
|
+
* return (
|
|
1217
|
+
* <button onClick={handleSubscribe} disabled={loading}>
|
|
1218
|
+
* {loading ? 'Loading...' : 'Subscribe'}
|
|
1219
|
+
* </button>
|
|
1220
|
+
* );
|
|
1221
|
+
* }
|
|
1222
|
+
* ```
|
|
1223
|
+
*
|
|
1224
|
+
* @example
|
|
1225
|
+
* ```tsx
|
|
1226
|
+
* // Edge case: Workspace ID not available
|
|
1227
|
+
* function SubscribeButton() {
|
|
1228
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1229
|
+
* const { createCheckoutSession } = useCreateCheckoutSession(currentWorkspace?._id);
|
|
1230
|
+
*
|
|
1231
|
+
* const handleSubscribe = async () => {
|
|
1232
|
+
* try {
|
|
1233
|
+
* await createCheckoutSession({ planVersionId: 'plan-123' });
|
|
1234
|
+
* } catch (error) {
|
|
1235
|
+
* // Error: "Workspace ID is required"
|
|
1236
|
+
* alert('Please select a workspace first');
|
|
1237
|
+
* }
|
|
1238
|
+
* };
|
|
1239
|
+
*
|
|
1240
|
+
* return <button onClick={handleSubscribe}>Subscribe</button>;
|
|
1241
|
+
* }
|
|
1242
|
+
* ```
|
|
560
1243
|
*/
|
|
561
1244
|
declare const useCreateCheckoutSession: (workspaceId: string | null | undefined) => {
|
|
562
1245
|
createCheckoutSession: (request: ICheckoutSessionRequest) => Promise<ICheckoutSessionResponse>;
|
|
@@ -564,10 +1247,71 @@ declare const useCreateCheckoutSession: (workspaceId: string | null | undefined)
|
|
|
564
1247
|
error: string | null;
|
|
565
1248
|
};
|
|
566
1249
|
/**
|
|
567
|
-
* Hook to update subscription (upgrade/downgrade)
|
|
568
|
-
* Returns checkout session if payment is required, otherwise returns subscription update response
|
|
569
|
-
*
|
|
570
|
-
* @
|
|
1250
|
+
* Hook to update subscription (upgrade/downgrade).
|
|
1251
|
+
* Returns checkout session if payment is required, otherwise returns subscription update response.
|
|
1252
|
+
*
|
|
1253
|
+
* @param workspaceId - The workspace ID to update subscription for. Can be null/undefined.
|
|
1254
|
+
* @returns An object containing:
|
|
1255
|
+
* - `updateSubscription(planVersionId, options?)`: Function to update subscription (throws if workspaceId is null)
|
|
1256
|
+
* - `loading`: Boolean indicating if subscription is being updated
|
|
1257
|
+
* - `error`: Error message string (null if no error)
|
|
1258
|
+
*
|
|
1259
|
+
* @example
|
|
1260
|
+
* ```tsx
|
|
1261
|
+
* function UpgradeButton({ planVersionId }) {
|
|
1262
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1263
|
+
* const { updateSubscription, loading } = useUpdateSubscription(currentWorkspace?._id);
|
|
1264
|
+
*
|
|
1265
|
+
* const handleUpgrade = async () => {
|
|
1266
|
+
* try {
|
|
1267
|
+
* const result = await updateSubscription(planVersionId, {
|
|
1268
|
+
* billingInterval: 'monthly',
|
|
1269
|
+
* successUrl: window.location.href,
|
|
1270
|
+
* cancelUrl: window.location.href,
|
|
1271
|
+
* });
|
|
1272
|
+
*
|
|
1273
|
+
* // Check if payment is required
|
|
1274
|
+
* if ('checkoutUrl' in result) {
|
|
1275
|
+
* window.location.href = result.checkoutUrl;
|
|
1276
|
+
* } else {
|
|
1277
|
+
* // Subscription updated without payment
|
|
1278
|
+
* alert('Subscription updated successfully!');
|
|
1279
|
+
* }
|
|
1280
|
+
* } catch (error) {
|
|
1281
|
+
* console.error('Failed to update subscription:', error);
|
|
1282
|
+
* }
|
|
1283
|
+
* };
|
|
1284
|
+
*
|
|
1285
|
+
* return (
|
|
1286
|
+
* <button onClick={handleUpgrade} disabled={loading}>
|
|
1287
|
+
* {loading ? 'Upgrading...' : 'Upgrade'}
|
|
1288
|
+
* </button>
|
|
1289
|
+
* );
|
|
1290
|
+
* }
|
|
1291
|
+
* ```
|
|
1292
|
+
*
|
|
1293
|
+
* @example
|
|
1294
|
+
* ```tsx
|
|
1295
|
+
* // Handle both checkout and direct update responses
|
|
1296
|
+
* function SubscriptionUpdater({ planVersionId }) {
|
|
1297
|
+
* const { updateSubscription } = useUpdateSubscription(workspaceId);
|
|
1298
|
+
*
|
|
1299
|
+
* const handleUpdate = async () => {
|
|
1300
|
+
* const result = await updateSubscription(planVersionId);
|
|
1301
|
+
*
|
|
1302
|
+
* // Type guard to check response type
|
|
1303
|
+
* if ('checkoutUrl' in result) {
|
|
1304
|
+
* // Redirect to payment
|
|
1305
|
+
* window.location.href = result.checkoutUrl;
|
|
1306
|
+
* } else {
|
|
1307
|
+
* // Direct update successful
|
|
1308
|
+
* console.log('Updated subscription:', result.subscription);
|
|
1309
|
+
* }
|
|
1310
|
+
* };
|
|
1311
|
+
*
|
|
1312
|
+
* return <button onClick={handleUpdate}>Update</button>;
|
|
1313
|
+
* }
|
|
1314
|
+
* ```
|
|
571
1315
|
*/
|
|
572
1316
|
declare const useUpdateSubscription: (workspaceId: string | null | undefined) => {
|
|
573
1317
|
updateSubscription: (planVersionId: string, options?: {
|
|
@@ -579,11 +1323,43 @@ declare const useUpdateSubscription: (workspaceId: string | null | undefined) =>
|
|
|
579
1323
|
error: string | null;
|
|
580
1324
|
};
|
|
581
1325
|
/**
|
|
582
|
-
* Combined hook that provides both subscription and plan group data
|
|
583
|
-
* Useful for subscription management pages
|
|
584
|
-
*
|
|
1326
|
+
* Combined hook that provides both subscription and plan group data.
|
|
1327
|
+
* Useful for subscription management pages that need both pieces of data.
|
|
1328
|
+
* Combines useSubscription, usePlanGroup, and useUpdateSubscription.
|
|
1329
|
+
*
|
|
1330
|
+
* @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
|
|
585
1331
|
* @param groupVersionId - Optional: specific group version ID to fetch
|
|
586
|
-
* @returns
|
|
1332
|
+
* @returns An object containing:
|
|
1333
|
+
* - `subscription`: Current subscription data (from useSubscription)
|
|
1334
|
+
* - `planGroup`: Plan group data (from usePlanGroup)
|
|
1335
|
+
* - `loading`: Boolean indicating if any operation is in progress
|
|
1336
|
+
* - `error`: Error message string (null if no error)
|
|
1337
|
+
* - `updateSubscription(planVersionId, options?)`: Function to update subscription
|
|
1338
|
+
* - `refetch()`: Function to refetch both subscription and plan group
|
|
1339
|
+
*
|
|
1340
|
+
* @example
|
|
1341
|
+
* ```tsx
|
|
1342
|
+
* function SubscriptionManagementPage() {
|
|
1343
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1344
|
+
* const {
|
|
1345
|
+
* subscription,
|
|
1346
|
+
* planGroup,
|
|
1347
|
+
* loading,
|
|
1348
|
+
* updateSubscription,
|
|
1349
|
+
* refetch,
|
|
1350
|
+
* } = useSubscriptionManagement(currentWorkspace?._id);
|
|
1351
|
+
*
|
|
1352
|
+
* if (loading) return <Loading />;
|
|
1353
|
+
*
|
|
1354
|
+
* return (
|
|
1355
|
+
* <div>
|
|
1356
|
+
* <CurrentPlan subscription={subscription} />
|
|
1357
|
+
* <AvailablePlans planGroup={planGroup} onSelect={updateSubscription} />
|
|
1358
|
+
* <button onClick={refetch}>Refresh</button>
|
|
1359
|
+
* </div>
|
|
1360
|
+
* );
|
|
1361
|
+
* }
|
|
1362
|
+
* ```
|
|
587
1363
|
*/
|
|
588
1364
|
declare const useSubscriptionManagement: (workspaceId: string | null | undefined, groupVersionId?: string | null) => {
|
|
589
1365
|
subscription: ISubscriptionResponse | null;
|
|
@@ -598,11 +1374,64 @@ declare const useSubscriptionManagement: (workspaceId: string | null | undefined
|
|
|
598
1374
|
refetch: () => Promise<void>;
|
|
599
1375
|
};
|
|
600
1376
|
/**
|
|
601
|
-
* Hook to list invoices for a workspace subscription
|
|
602
|
-
*
|
|
1377
|
+
* Hook to list invoices for a workspace subscription with pagination support.
|
|
1378
|
+
* Automatically fetches when workspaceId, limit, or startingAfter changes.
|
|
1379
|
+
*
|
|
1380
|
+
* @param workspaceId - The workspace ID to get invoices for. Can be null/undefined to disable fetching.
|
|
603
1381
|
* @param limit - Number of invoices to return (default: 10)
|
|
604
1382
|
* @param startingAfter - Invoice ID to start after (for pagination)
|
|
605
|
-
* @returns
|
|
1383
|
+
* @returns An object containing:
|
|
1384
|
+
* - `invoices`: Array of invoice objects
|
|
1385
|
+
* - `hasMore`: Boolean indicating if there are more invoices to load
|
|
1386
|
+
* - `loading`: Boolean indicating if invoices are being fetched
|
|
1387
|
+
* - `error`: Error message string (null if no error)
|
|
1388
|
+
* - `refetch()`: Function to manually refetch invoices
|
|
1389
|
+
*
|
|
1390
|
+
* @example
|
|
1391
|
+
* ```tsx
|
|
1392
|
+
* function InvoiceList() {
|
|
1393
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1394
|
+
* const { invoices, hasMore, loading, refetch } = useInvoices(currentWorkspace?._id, 10);
|
|
1395
|
+
*
|
|
1396
|
+
* if (loading) return <Loading />;
|
|
1397
|
+
*
|
|
1398
|
+
* return (
|
|
1399
|
+
* <div>
|
|
1400
|
+
* {invoices.map(invoice => (
|
|
1401
|
+
* <InvoiceCard key={invoice._id} invoice={invoice} />
|
|
1402
|
+
* ))}
|
|
1403
|
+
* {hasMore && <button onClick={() => refetch()}>Load More</button>}
|
|
1404
|
+
* </div>
|
|
1405
|
+
* );
|
|
1406
|
+
* }
|
|
1407
|
+
* ```
|
|
1408
|
+
*
|
|
1409
|
+
* @example
|
|
1410
|
+
* ```tsx
|
|
1411
|
+
* // Pagination example
|
|
1412
|
+
* function PaginatedInvoices() {
|
|
1413
|
+
* const [lastInvoiceId, setLastInvoiceId] = useState<string | undefined>();
|
|
1414
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1415
|
+
* const { invoices, hasMore, refetch } = useInvoices(
|
|
1416
|
+
* currentWorkspace?._id,
|
|
1417
|
+
* 10,
|
|
1418
|
+
* lastInvoiceId
|
|
1419
|
+
* );
|
|
1420
|
+
*
|
|
1421
|
+
* const loadMore = () => {
|
|
1422
|
+
* if (invoices.length > 0) {
|
|
1423
|
+
* setLastInvoiceId(invoices[invoices.length - 1]._id);
|
|
1424
|
+
* }
|
|
1425
|
+
* };
|
|
1426
|
+
*
|
|
1427
|
+
* return (
|
|
1428
|
+
* <div>
|
|
1429
|
+
* {invoices.map(invoice => <InvoiceCard key={invoice._id} invoice={invoice} />)}
|
|
1430
|
+
* {hasMore && <button onClick={loadMore}>Load More</button>}
|
|
1431
|
+
* </div>
|
|
1432
|
+
* );
|
|
1433
|
+
* }
|
|
1434
|
+
* ```
|
|
606
1435
|
*/
|
|
607
1436
|
declare const useInvoices: (workspaceId: string | null | undefined, limit?: number, startingAfter?: string) => {
|
|
608
1437
|
invoices: IInvoice[];
|
|
@@ -612,10 +1441,36 @@ declare const useInvoices: (workspaceId: string | null | undefined, limit?: numb
|
|
|
612
1441
|
refetch: () => Promise<void>;
|
|
613
1442
|
};
|
|
614
1443
|
/**
|
|
615
|
-
* Hook to get a single invoice by ID
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
* @
|
|
1444
|
+
* Hook to get a single invoice by ID.
|
|
1445
|
+
* Automatically fetches when workspaceId or invoiceId changes.
|
|
1446
|
+
*
|
|
1447
|
+
* @param workspaceId - The workspace ID. Can be null/undefined to disable fetching.
|
|
1448
|
+
* @param invoiceId - The invoice ID to fetch. Can be null/undefined to disable fetching.
|
|
1449
|
+
* @returns An object containing:
|
|
1450
|
+
* - `invoice`: Invoice data object (null if not loaded)
|
|
1451
|
+
* - `loading`: Boolean indicating if invoice is being fetched
|
|
1452
|
+
* - `error`: Error message string (null if no error)
|
|
1453
|
+
* - `refetch()`: Function to manually refetch the invoice
|
|
1454
|
+
*
|
|
1455
|
+
* @example
|
|
1456
|
+
* ```tsx
|
|
1457
|
+
* function InvoiceDetails({ invoiceId }) {
|
|
1458
|
+
* const { currentWorkspace } = useSaaSWorkspaces();
|
|
1459
|
+
* const { invoice, loading, error } = useInvoice(currentWorkspace?._id, invoiceId);
|
|
1460
|
+
*
|
|
1461
|
+
* if (loading) return <Loading />;
|
|
1462
|
+
* if (error) return <Error message={error} />;
|
|
1463
|
+
* if (!invoice) return <p>Invoice not found</p>;
|
|
1464
|
+
*
|
|
1465
|
+
* return (
|
|
1466
|
+
* <div>
|
|
1467
|
+
* <h2>Invoice #{invoice.invoiceNumber}</h2>
|
|
1468
|
+
* <p>Amount: ${invoice.amount}</p>
|
|
1469
|
+
* <p>Status: {invoice.status}</p>
|
|
1470
|
+
* </div>
|
|
1471
|
+
* );
|
|
1472
|
+
* }
|
|
1473
|
+
* ```
|
|
619
1474
|
*/
|
|
620
1475
|
declare const useInvoice: (workspaceId: string | null | undefined, invoiceId: string | null | undefined) => {
|
|
621
1476
|
invoice: IInvoice | null;
|
|
@@ -703,98 +1558,5 @@ declare class EventEmitter {
|
|
|
703
1558
|
}
|
|
704
1559
|
declare const eventEmitter: EventEmitter;
|
|
705
1560
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
/**
|
|
709
|
-
* Fallback UI to render when an error occurs
|
|
710
|
-
*/
|
|
711
|
-
fallback?: ReactNode | ((error: Error, resetError: () => void) => ReactNode);
|
|
712
|
-
/**
|
|
713
|
-
* Called when an error is caught
|
|
714
|
-
*/
|
|
715
|
-
onError?: (error: Error, errorInfo: react__default.ErrorInfo) => void;
|
|
716
|
-
/**
|
|
717
|
-
* Whether to reset error state when children change
|
|
718
|
-
* @default true
|
|
719
|
-
*/
|
|
720
|
-
resetOnPropsChange?: boolean;
|
|
721
|
-
}
|
|
722
|
-
interface ErrorBoundaryState {
|
|
723
|
-
hasError: boolean;
|
|
724
|
-
error: Error | null;
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* Error Boundary component for catching React component errors
|
|
728
|
-
* Wraps SDK components to prevent crashes from propagating
|
|
729
|
-
*/
|
|
730
|
-
declare class SDKErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
731
|
-
constructor(props: ErrorBoundaryProps);
|
|
732
|
-
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
733
|
-
componentDidCatch(error: Error, errorInfo: react__default.ErrorInfo): void;
|
|
734
|
-
componentDidUpdate(prevProps: ErrorBoundaryProps): void;
|
|
735
|
-
resetError: () => void;
|
|
736
|
-
render(): ReactNode;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
/**
|
|
740
|
-
* Centralized Error Handler for SDK
|
|
741
|
-
* Provides consistent error handling, logging, and user-facing error management
|
|
742
|
-
*/
|
|
743
|
-
interface SDKErrorContext {
|
|
744
|
-
component?: string;
|
|
745
|
-
action?: string;
|
|
746
|
-
metadata?: Record<string, unknown>;
|
|
747
|
-
}
|
|
748
|
-
declare class SDKError extends Error {
|
|
749
|
-
readonly code?: string | undefined;
|
|
750
|
-
readonly context?: SDKErrorContext | undefined;
|
|
751
|
-
readonly originalError?: Error | undefined;
|
|
752
|
-
constructor(message: string, code?: string | undefined, context?: SDKErrorContext | undefined, originalError?: Error | undefined);
|
|
753
|
-
}
|
|
754
|
-
interface ErrorHandlerConfig {
|
|
755
|
-
/**
|
|
756
|
-
* Custom error callback for handling errors
|
|
757
|
-
* @param error - The error that occurred
|
|
758
|
-
* @param context - Additional context about where the error occurred
|
|
759
|
-
*/
|
|
760
|
-
onError?: (error: Error, context: SDKErrorContext) => void;
|
|
761
|
-
/**
|
|
762
|
-
* Whether to log errors to console in development
|
|
763
|
-
* @default true
|
|
764
|
-
*/
|
|
765
|
-
enableConsoleLogging?: boolean;
|
|
766
|
-
/**
|
|
767
|
-
* Whether to show user-facing error notifications
|
|
768
|
-
* @default false
|
|
769
|
-
*/
|
|
770
|
-
showUserNotifications?: boolean;
|
|
771
|
-
}
|
|
772
|
-
declare class ErrorHandler {
|
|
773
|
-
private config;
|
|
774
|
-
/**
|
|
775
|
-
* Configure the error handler
|
|
776
|
-
*/
|
|
777
|
-
configure(config: Partial<ErrorHandlerConfig>): void;
|
|
778
|
-
/**
|
|
779
|
-
* Handle an error with context
|
|
780
|
-
*/
|
|
781
|
-
handleError(error: Error | unknown, context?: SDKErrorContext): void;
|
|
782
|
-
/**
|
|
783
|
-
* Notify user of error (placeholder for notification system)
|
|
784
|
-
*/
|
|
785
|
-
private notifyUser;
|
|
786
|
-
/**
|
|
787
|
-
* Create a safe error handler wrapper for async functions
|
|
788
|
-
*/
|
|
789
|
-
wrapAsync<T extends (...args: any[]) => Promise<any>>(fn: T, context: SDKErrorContext): T;
|
|
790
|
-
/**
|
|
791
|
-
* Create a safe error handler wrapper for sync functions
|
|
792
|
-
*/
|
|
793
|
-
wrapSync<T extends (...args: any[]) => any>(fn: T, context: SDKErrorContext): T;
|
|
794
|
-
}
|
|
795
|
-
declare const errorHandler: ErrorHandler;
|
|
796
|
-
declare function handleError(error: Error | unknown, context?: SDKErrorContext): void;
|
|
797
|
-
declare function createSDKError(message: string, code?: string, context?: SDKErrorContext, originalError?: Error): SDKError;
|
|
798
|
-
|
|
799
|
-
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 };
|
|
800
|
-
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 };
|
|
1561
|
+
export { ApiVersion, AuthStatus, BetaForm, SaaSOSProvider, WhenAuthenticated, WhenRoles, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceSwitcher, eventEmitter, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, useSaaSAuth, useSaaSSettings, useSaaSWorkspaces, useSubscription, useSubscriptionManagement, useUpdateSubscription, useUserAttributes, useUserFeatures };
|
|
1562
|
+
export type { BillingInterval, 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, OnWorkspaceChangeParams, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
|