@buildbase/sdk 0.0.25 → 0.0.27

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 CHANGED
@@ -11,6 +11,8 @@ A React SDK for [BuildBase](https://www.buildbase.app/) that provides essential
11
11
  - [Role-Based Access Control](#-role-based-access-control)
12
12
  - [Feature Flags](#️-feature-flags)
13
13
  - [Subscription Gates](#-subscription-gates)
14
+ - [Trial Gates](#-trial-gates)
15
+ - [Push Notifications](#-push-notifications)
14
16
  - [User Management](#-user-management)
15
17
  - [Workspace Management](#-complete-workspace-management)
16
18
  - [Public Pricing (No Login)](#-public-pricing-no-login)
@@ -35,6 +37,10 @@ A React SDK for [BuildBase](https://www.buildbase.app/) that provides essential
35
37
  - **👥 Role-Based Access Control** - User roles and workspace-specific permissions
36
38
  - **🎯 Feature Flags** - Workspace-level and user-level feature toggles
37
39
  - **📋 Subscription Gates** - Show or hide UI based on current workspace subscription (plan)
40
+ - **⏳ Trial Gates** - `WhenTrialing`, `WhenNotTrialing`, `WhenTrialEnding` components + `useTrialStatus` hook
41
+ - **🔔 Push Notifications** - Browser push notifications with `usePushNotifications` hook, auto-triggers for billing events, and campaign management
42
+ - **💺 Seat-Based Pricing** - Per-seat billing with included seats, billable seat tracking, and seat limit enforcement
43
+ - **💱 Multi-Currency** - Per-currency pricing variants with workspace billing currency lock
38
44
  - **📊 Quota Usage Tracking** - Record and monitor metered usage (API calls, storage, etc.) with real-time status
39
45
  - **📈 Usage Dashboard** - Built-in workspace settings page showing quota consumption, overage billing breakdowns, and billing period info
40
46
  - **👤 User Management** - User attributes and feature flags management
@@ -442,6 +448,108 @@ function SubscriptionStatus() {
442
448
  - When subscription is updated via SDK (e.g. `useUpdateSubscription`, cancel, resume) — refetch is triggered automatically.
443
449
  - When you call `refetch()` (e.g. after redirect from checkout).
444
450
 
451
+ ## ⏳ Trial Gates
452
+
453
+ Control UI based on trial state. Works with Stripe-native trials (both card-required and no-card).
454
+
455
+ ### Trial Gate Components
456
+
457
+ ```tsx
458
+ import { WhenTrialing, WhenNotTrialing, WhenTrialEnding } from '@buildbase/sdk';
459
+
460
+ function TrialExample() {
461
+ return (
462
+ <div>
463
+ {/* Show only during active trial */}
464
+ <WhenTrialing>
465
+ <TrialBanner />
466
+ </WhenTrialing>
467
+
468
+ {/* Show when NOT trialing (active, canceled, or no subscription) */}
469
+ <WhenNotTrialing>
470
+ <RegularContent />
471
+ </WhenNotTrialing>
472
+
473
+ {/* Show when trial ends within N days (default: 3) */}
474
+ <WhenTrialEnding daysThreshold={7}>
475
+ <UpgradeUrgentBanner />
476
+ </WhenTrialEnding>
477
+ </div>
478
+ );
479
+ }
480
+ ```
481
+
482
+ | Component | Renders when |
483
+ | ----------------- | -------------------------------------------------------- |
484
+ | `WhenTrialing` | Subscription status is `trialing` |
485
+ | `WhenNotTrialing` | Subscription status is NOT `trialing` |
486
+ | `WhenTrialEnding` | Trialing AND trial ends within `daysThreshold` days (default 3) |
487
+
488
+ All trial gates support `loadingComponent` and `fallbackComponent` props.
489
+
490
+ ### useTrialStatus
491
+
492
+ Hook that computes trial information from the subscription context:
493
+
494
+ ```tsx
495
+ import { useTrialStatus } from '@buildbase/sdk';
496
+
497
+ function TrialInfo() {
498
+ const { isTrialing, daysRemaining, trialEndsAt, isTrialEnding } = useTrialStatus();
499
+
500
+ if (!isTrialing) return null;
501
+
502
+ return (
503
+ <div>
504
+ <p>Trial ends in {daysRemaining} days</p>
505
+ {isTrialEnding && <p>Upgrade now to keep access!</p>}
506
+ </div>
507
+ );
508
+ }
509
+ ```
510
+
511
+ | Property | Type | Description |
512
+ | --------------- | -------------- | ------------------------------------------------ |
513
+ | `isTrialing` | `boolean` | Whether subscription is in trial |
514
+ | `daysRemaining` | `number` | Days left in trial (0 if not trialing or expired) |
515
+ | `trialEndsAt` | `Date \| null` | Trial end date |
516
+ | `trialStartedAt`| `Date \| null` | Trial start date |
517
+ | `isTrialEnding` | `boolean` | True when 3 or fewer days remaining |
518
+
519
+ ## 🔔 Push Notifications
520
+
521
+ Browser push notifications — built into the SDK. Users can enable/disable from the **Notifications** tab in workspace settings. Billing events (payment failed, trial ending) auto-send push notifications.
522
+
523
+ **Only setup required:** Create `public/push-sw.js` in your app:
524
+
525
+ ```js
526
+ self.addEventListener('push', function(event) {
527
+ if (!event.data) return;
528
+ try {
529
+ var payload = event.data.json();
530
+ event.waitUntil(self.registration.showNotification(payload.title || 'Notification', {
531
+ body: payload.body || '',
532
+ icon: payload.icon || undefined,
533
+ badge: payload.icon || undefined,
534
+ data: { url: payload.url, ...(payload.data || {}) },
535
+ }));
536
+ } catch (e) { console.error('[PushSW]', e); }
537
+ });
538
+
539
+ self.addEventListener('notificationclick', function(event) {
540
+ event.notification.close();
541
+ var url = event.notification.data && event.notification.data.url;
542
+ if (url) {
543
+ event.waitUntil(clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(list) {
544
+ for (var i = 0; i < list.length; i++) { if (list[i].url === url && 'focus' in list[i]) return list[i].focus(); }
545
+ if (clients.openWindow) return clients.openWindow(url);
546
+ }));
547
+ }
548
+ });
549
+ ```
550
+
551
+ Everything else is built-in — permission handling, subscribe/unsubscribe, settings UI, billing auto-triggers, and browser-specific unblock instructions.
552
+
445
553
  ## 👤 User Management
446
554
 
447
555
  ### User Attributes
@@ -1168,6 +1276,15 @@ All SDK API clients extend a shared base class and are exported from the package
1168
1276
  | `WorkspaceApi` | Workspaces, subscription, invoices, quota usage, users |
1169
1277
  | `SettingsApi` | Organization settings |
1170
1278
 
1279
+ ### Components
1280
+
1281
+ | Component | Purpose |
1282
+ | --- | --- |
1283
+ | `SubscriptionContextProvider` | Provides subscription data to children (included in SaaSOSProvider) |
1284
+ | `WhenSubscription`, `WhenNoSubscription`, `WhenSubscriptionToPlans` | Subscription gate components |
1285
+ | `WhenTrialing`, `WhenNotTrialing`, `WhenTrialEnding` | Trial gate components |
1286
+ | `WhenQuotaAvailable`, `WhenQuotaExhausted`, `WhenQuotaOverage` | Quota gate components |
1287
+
1171
1288
  ### Currency, pricing variant & quota utilities
1172
1289
 
1173
1290
  | Category | Exports |
@@ -1203,6 +1320,8 @@ Prefer these SDK hooks for state and operations instead of `useAppSelector`:
1203
1320
  | `useUserAttributes()` | User attributes and update/refresh |
1204
1321
  | `useUserFeatures()` | User feature flags |
1205
1322
  | `useSubscriptionContext()` | Subscription for current workspace (response, loading, refetch); use inside SubscriptionContextProvider |
1323
+ | `useTrialStatus()` | Trial state: `isTrialing`, `daysRemaining`, `trialEndsAt`, `isTrialEnding` |
1324
+ | `usePushNotifications()` | Push notification state and actions: `isSubscribed`, `subscribe()`, `unsubscribe()` |
1206
1325
  | Subscription hooks | `usePublicPlans`, `useSubscription`, `useSubscriptionManagement`, `usePlanGroup`, `usePlanGroupVersions`, `usePublicPlanGroupVersion`, `useCreateCheckoutSession`, `useUpdateSubscription`, `useCancelSubscription`, `useResumeSubscription`, `useInvoices`, `useInvoice` |
1207
1326
  | `useQuotaUsageContext()` | Quota usage for current workspace (quotas, loading, refetch); use inside QuotaUsageContextProvider |
1208
1327
  | Quota usage hooks | `useRecordUsage`, `useQuotaUsageStatus`, `useAllQuotaUsage`, `useUsageLogs` |
package/dist/index.d.ts CHANGED
@@ -1406,7 +1406,7 @@ declare function useQuotaUsageContext(): QuotaUsageContextValue;
1406
1406
  */
1407
1407
  declare function invalidateQuotaUsage(): void;
1408
1408
 
1409
- type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'usage' | 'features' | 'danger';
1409
+ type WorkspaceSettingsSection = 'profile' | 'general' | 'users' | 'subscription' | 'usage' | 'features' | 'notifications' | 'danger';
1410
1410
 
1411
1411
  declare function useSaaSAuth(): {
1412
1412
  signIn: () => Promise<void>;
@@ -1716,6 +1716,13 @@ declare class WorkspaceApi extends BaseApi {
1716
1716
  * Returns checkout session if payment is required, otherwise returns subscription update response
1717
1717
  */
1718
1718
  updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1719
+ /**
1720
+ * Create a Stripe Customer Portal session for managing payment methods, invoices, etc.
1721
+ * Returns the portal URL — redirect user to it.
1722
+ */
1723
+ createBillingPortalSession(workspaceId: string, returnUrl?: string): Promise<{
1724
+ url: string;
1725
+ }>;
1719
1726
  /**
1720
1727
  * List invoices for a workspace subscription
1721
1728
  * @param workspaceId - The workspace ID
@@ -2268,6 +2275,24 @@ declare const useInvoices: (workspaceId: string | null | undefined, limit?: numb
2268
2275
  error: string | null;
2269
2276
  refetch: () => Promise<void>;
2270
2277
  };
2278
+ /**
2279
+ * Hook to open the Stripe Customer Portal for managing payment methods, invoices, and subscription.
2280
+ *
2281
+ * @example
2282
+ * ```tsx
2283
+ * const { openBillingPortal, loading } = useBillingPortal(workspaceId);
2284
+ * <Button onClick={() => openBillingPortal()} disabled={loading}>
2285
+ * Manage Payment Method
2286
+ * </Button>
2287
+ * ```
2288
+ */
2289
+ declare const useBillingPortal: (workspaceId: string | null | undefined) => {
2290
+ openBillingPortal: (returnUrl?: string) => Promise<{
2291
+ url: string;
2292
+ }>;
2293
+ loading: boolean;
2294
+ error: string | null;
2295
+ };
2271
2296
  /**
2272
2297
  * Hook to get a single invoice by ID.
2273
2298
  * Automatically fetches when workspaceId or invoiceId changes.
@@ -2637,6 +2662,56 @@ declare function useSeatStatus(workspace: {
2637
2662
  billingCurrency?: string | null;
2638
2663
  } | null): SeatStatus;
2639
2664
 
2665
+ interface PushNotificationState {
2666
+ /** Browser's Notification.permission: 'default' | 'granted' | 'denied' */
2667
+ permission: NotificationPermission;
2668
+ /** Whether this device is subscribed to push notifications */
2669
+ isSubscribed: boolean;
2670
+ /** Whether the browser supports push notifications */
2671
+ isSupported: boolean;
2672
+ /** Loading state for subscribe/unsubscribe operations */
2673
+ loading: boolean;
2674
+ /** Error message from the last operation */
2675
+ error: string | null;
2676
+ }
2677
+ interface PushNotificationContextValue extends PushNotificationState {
2678
+ /** Request notification permission from the browser. Returns true if granted. */
2679
+ requestPermission: () => Promise<boolean>;
2680
+ /** Subscribe this device to push notifications (requests permission if needed). */
2681
+ subscribe: () => Promise<void>;
2682
+ /** Unsubscribe this device from push notifications. */
2683
+ unsubscribe: () => Promise<void>;
2684
+ }
2685
+ interface PushNotificationProviderProps {
2686
+ children: react__default.ReactNode;
2687
+ /** Path to the service worker file (default: '/push-sw.js') */
2688
+ serviceWorkerPath?: string;
2689
+ /** Automatically subscribe after permission is granted on login (default: false) */
2690
+ autoSubscribe?: boolean;
2691
+ }
2692
+ declare const PushNotificationProvider: react__default.FC<PushNotificationProviderProps>;
2693
+ /**
2694
+ * Hook to access push notification state and actions.
2695
+ * Must be used within PushNotificationProvider (included in SaaSOSProvider when push config is provided).
2696
+ */
2697
+ declare function usePushNotifications(): PushNotificationContextValue;
2698
+
2699
+ /**
2700
+ * Push notification service worker source code.
2701
+ * Export this string and write it to a file in your app's `public/` directory.
2702
+ *
2703
+ * @example
2704
+ * ```ts
2705
+ * // scripts/generate-sw.ts
2706
+ * import { PUSH_SERVICE_WORKER_SCRIPT } from '@buildbase/sdk';
2707
+ * import fs from 'fs';
2708
+ * fs.writeFileSync('public/push-sw.js', PUSH_SERVICE_WORKER_SCRIPT);
2709
+ * ```
2710
+ *
2711
+ * Or manually create `public/push-sw.js` with this content.
2712
+ */
2713
+ declare const PUSH_SERVICE_WORKER_SCRIPT = "\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n var payload = event.data.json();\n var title = payload.title || 'Notification';\n var options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n var url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (var i = 0; i < clientList.length; i++) {\n var client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n";
2714
+
2640
2715
  /**
2641
2716
  * EventEmitter class to handle and trigger event callbacks
2642
2717
  * This class manages all event listeners and provides methods to trigger events
@@ -2862,5 +2937,5 @@ interface FormatQuotaWithPriceOptions {
2862
2937
  */
2863
2938
  declare function formatQuotaWithPrice(value: QuotaDisplayValue, unitName: string, options?: FormatQuotaWithPriceOptions): string;
2864
2939
 
2865
- export { ApiVersion, AuthStatus, BaseApi, BetaForm, CURRENCY_DISPLAY, CURRENCY_FLAG, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PricingPage, QuotaUsageContextProvider, SaaSOSProvider, SettingsApi, SubscriptionContextProvider, UserApi, WhenAuthenticated, WhenNoSubscription, WhenNotTrialing, WhenQuotaAvailable, WhenQuotaExhausted, WhenQuotaOverage, WhenQuotaThreshold, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenTrialEnding, WhenTrialing, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, invalidateQuotaUsage, invalidateSubscription, useAllQuotaUsage, useCancelSubscription, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, useQuotaUsageContext, useQuotaUsageStatus, useRecordUsage, useResumeSubscription, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSeatStatus, useSubscription, useSubscriptionContext, useSubscriptionManagement, useTrialStatus, useUpdateSubscription, useUsageLogs, useUserAttributes, useUserFeatures };
2940
+ export { ApiVersion, AuthStatus, BaseApi, BetaForm, CURRENCY_DISPLAY, CURRENCY_FLAG, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, PricingPage, PushNotificationProvider, QuotaUsageContextProvider, SaaSOSProvider, SettingsApi, SubscriptionContextProvider, UserApi, WhenAuthenticated, WhenNoSubscription, WhenNotTrialing, WhenQuotaAvailable, WhenQuotaExhausted, WhenQuotaOverage, WhenQuotaThreshold, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenTrialEnding, WhenTrialing, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, invalidateQuotaUsage, invalidateSubscription, useAllQuotaUsage, useBillingPortal, useCancelSubscription, useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, usePushNotifications, useQuotaUsageContext, useQuotaUsageStatus, useRecordUsage, useResumeSubscription, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSeatStatus, useSubscription, useSubscriptionContext, useSubscriptionManagement, useTrialStatus, useUpdateSubscription, useUsageLogs, useUserAttributes, useUserFeatures };
2866
2941
  export type { BillingInterval, CheckoutResult, EventData, EventType, FormatQuotaWithPriceOptions, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IEventCallbacks, IInvoice, IInvoiceListResponse, IInvoiceResponse, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, InvoiceStatus, OnWorkspaceChangeParams, PlanVersionWithPricingVariants, PricingPageDetails, PricingPageProps, QuotaDisplayValue, QuotaDisplayWithOverage, QuotaUsageContextValue, SeatStatus, SubscriptionContextValue, TrialStatus, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };