@buildbase/sdk 0.0.16 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +208 -98
  2. package/dist/index.d.ts +392 -167
  3. package/dist/index.esm.js +5 -5
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +5 -5
  6. package/dist/index.js.map +1 -1
  7. package/dist/types/api/index.d.ts +6 -0
  8. package/dist/types/api/quota-utils.d.ts +24 -0
  9. package/dist/types/api/types.d.ts +37 -14
  10. package/dist/types/components/beta/api.d.ts +1 -2
  11. package/dist/types/components/pricing/PricingPage.d.ts +1 -1
  12. package/dist/types/components/subscription/index.d.ts +108 -0
  13. package/dist/types/contexts/SubscriptionContext/SubscriptionContext.d.ts +22 -0
  14. package/dist/types/contexts/SubscriptionContext/index.d.ts +2 -0
  15. package/dist/types/contexts/SubscriptionContext/subscriptionInvalidation.d.ts +19 -0
  16. package/dist/types/contexts/SubscriptionContext/types.d.ts +12 -0
  17. package/dist/types/contexts/index.d.ts +2 -0
  18. package/dist/types/contexts/shared/types.d.ts +21 -0
  19. package/dist/types/contexts/shared/useAppDispatch.d.ts +2 -12
  20. package/dist/types/contexts/shared/useAppSelector.d.ts +2 -12
  21. package/dist/types/contexts/shared/utils/reducerHelpers.d.ts +2 -2
  22. package/dist/types/index.d.ts +9 -2
  23. package/dist/types/lib/api-base.d.ts +49 -0
  24. package/dist/types/providers/ContextConfigProvider.d.ts +1 -1
  25. package/dist/types/providers/auth/api.d.ts +12 -0
  26. package/dist/types/providers/auth/hooks.d.ts +2 -0
  27. package/dist/types/providers/os/api.d.ts +11 -0
  28. package/dist/types/providers/os/hooks.d.ts +6 -0
  29. package/dist/types/providers/os/types.d.ts +2 -0
  30. package/dist/types/providers/user/api.d.ts +16 -0
  31. package/dist/types/providers/user/hooks.d.ts +1 -0
  32. package/dist/types/providers/workspace/api.d.ts +2 -5
  33. package/dist/types/providers/workspace/hooks.d.ts +10 -0
  34. package/dist/types/providers/workspace/subscription-hooks.d.ts +1 -1
  35. package/package.json +1 -1
@@ -1 +1,7 @@
1
1
  export type { IBetaConfig } from '../components/beta/api';
2
+ /** Central SDK APIs – all extend BaseApi for shared URL/auth/request handling. */
3
+ export { BaseApi } from '../lib/api-base';
4
+ export type { IBaseApiConfig } from '../lib/api-base';
5
+ export { SettingsApi } from '../providers/os/api';
6
+ export { UserApi } from '../providers/user/api';
7
+ export { WorkspaceApi } from '../providers/workspace/api';
@@ -0,0 +1,24 @@
1
+ import type { BillingInterval, IQuotaByInterval, IQuotaValue } from './types';
2
+ export type QuotaDisplayValue = {
3
+ included: number;
4
+ overage?: number;
5
+ unitSize?: number;
6
+ } | number | null;
7
+ /**
8
+ * Normalize a quota value (legacy or per-interval) to a display shape for a given billing interval.
9
+ * - Legacy: number or IQuotaValue → use as-is (interval ignored).
10
+ * - New schema: IQuotaByInterval → pick the interval slice (e.g. monthly, yearly, quarterly).
11
+ */
12
+ export declare function getQuotaDisplayValue(value: number | IQuotaValue | IQuotaByInterval | null | undefined, interval?: BillingInterval): QuotaDisplayValue;
13
+ /** Options for formatting quota with price. */
14
+ export interface FormatQuotaWithPriceOptions {
15
+ /** If true, overage is in cents (Stripe); format as dollars. Default true. */
16
+ overageInCents?: boolean;
17
+ /** Currency symbol. Default '$'. */
18
+ currencySymbol?: string;
19
+ }
20
+ /**
21
+ * Format a quota display value as "X included, then $Y.YY / unit" (e.g. "10 included, then $10.00 / video").
22
+ * Assumes overage is the per-unit price (in cents when overageInCents is true).
23
+ */
24
+ export declare function formatQuotaWithPrice(value: QuotaDisplayValue, unitName: string, options?: FormatQuotaWithPriceOptions): string;
@@ -55,6 +55,7 @@ export interface ISubscription {
55
55
  stripePriceId?: string;
56
56
  stripeCurrentPeriodEnd?: string;
57
57
  cancelAtPeriodEnd: boolean;
58
+ billingInterval?: BillingInterval;
58
59
  createdAt: string;
59
60
  updatedAt: string;
60
61
  plan?: {
@@ -77,6 +78,20 @@ export interface IQuotaValue {
77
78
  overage?: number;
78
79
  stripePriceId?: string;
79
80
  }
81
+ /** Per-interval quota value (new plan-group/versions schema) */
82
+ export interface IQuotaIntervalValue {
83
+ included: number;
84
+ overage: number;
85
+ priceId: string;
86
+ /** Optional unit size for overage pricing (e.g. 1000 = price per 1000 units). */
87
+ unitSize?: number;
88
+ }
89
+ /** Quota defined per billing interval (new plan-group/versions schema) */
90
+ export interface IQuotaByInterval {
91
+ monthly?: IQuotaIntervalValue;
92
+ yearly?: IQuotaIntervalValue;
93
+ quarterly?: IQuotaIntervalValue;
94
+ }
80
95
  export interface IBasePricing {
81
96
  monthly: number;
82
97
  yearly: number;
@@ -89,7 +104,8 @@ export interface IPlanVersion {
89
104
  status: 'draft' | 'published';
90
105
  features?: Record<string, boolean>;
91
106
  limits?: Record<string, number>;
92
- quotas?: Record<string, number | IQuotaValue>;
107
+ /** Legacy: number | IQuotaValue. New schema: IQuotaByInterval (per-interval included/overage/priceId) */
108
+ quotas?: Record<string, number | IQuotaValue | IQuotaByInterval>;
93
109
  basePricing?: IBasePricing;
94
110
  stripePrices?: {
95
111
  monthlyPriceId?: string;
@@ -106,13 +122,18 @@ export interface IPlanVersion {
106
122
  createdAt?: string;
107
123
  updatedAt?: string;
108
124
  id?: string;
125
+ stripeProductId?: string;
126
+ }
127
+ /** Plan version summary (e.g. plan.latestVersion from subscription API) with subscriptionItems as IDs. */
128
+ export interface IPlanVersionSummary extends Omit<IPlanVersion, 'subscriptionItems'> {
129
+ subscriptionItems?: string[];
109
130
  }
110
131
  export interface IPlan {
111
132
  _id: string;
112
133
  name: string;
113
134
  slug: string;
114
135
  description?: string;
115
- latestVersion?: IPlanVersion;
136
+ latestVersion?: IPlanVersionSummary;
116
137
  archived?: boolean;
117
138
  deleted?: boolean;
118
139
  createdAt?: string;
@@ -187,21 +208,23 @@ export interface IPlanGroupVersionWithPlans {
187
208
  removedPlans: IPlanVersionWithPlan[];
188
209
  };
189
210
  }
211
+ export interface IPlanGroupInfo {
212
+ _id: string;
213
+ name: string;
214
+ slug: string;
215
+ description?: string;
216
+ }
217
+ /** Response from GET workspaces/:id/subscription/plan-group (and by version). */
190
218
  export interface IPlanGroupResponse {
191
- group: {
192
- _id: string;
193
- name: string;
194
- slug: string;
195
- };
196
- currentVersion: IPlanGroupVersionWithPlans;
197
- availableVersions: IPlanGroupVersionWithPlans[];
219
+ /** Plan group with latestVersion, archived, deleted, timestamps. */
220
+ group: IPlanGroup;
221
+ /** Current group version with populated planVersionIds (or IDs). */
222
+ groupVersion: IPlanGroupVersion;
223
+ /** Full plan versions for display (subscriptionItems, basePricing, quotas, etc.). */
224
+ plans: IPlanVersionWithPlan[];
198
225
  }
199
226
  export interface IPlanGroupVersionsResponse {
200
- group: {
201
- _id: string;
202
- name: string;
203
- slug: string;
204
- };
227
+ group: IPlanGroupInfo;
205
228
  currentVersion: IPlanGroupVersionWithPlans;
206
229
  availableVersions: IPlanGroupVersionWithPlans[];
207
230
  }
@@ -30,9 +30,8 @@ interface ApiResponse {
30
30
  submissionId?: string;
31
31
  }
32
32
  export declare class BetaForm {
33
- private version;
33
+ private api;
34
34
  private orgId;
35
- private serverUrl;
36
35
  constructor(config: IOsConfig);
37
36
  fetchConfig(): Promise<IBetaConfig>;
38
37
  submitBetaUser(formData: {
@@ -44,4 +44,4 @@ export interface PricingPageProps {
44
44
  * </PricingPage>
45
45
  * ```
46
46
  */
47
- export declare function PricingPage({ slug, children, loadingFallback, errorFallback, }: PricingPageProps): import("react/jsx-runtime").JSX.Element;
47
+ export declare function PricingPage({ slug, children, loadingFallback, errorFallback }: PricingPageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,108 @@
1
+ interface IWhenSubscriptionProps {
2
+ /** Content to render when the condition is met (workspace has an active subscription). */
3
+ children: React.ReactNode;
4
+ /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
5
+ loadingComponent?: React.ReactNode;
6
+ /** Optional component/element to show when condition is not met (e.g. <UpgradePrompt />). */
7
+ fallbackComponent?: React.ReactNode;
8
+ }
9
+ /**
10
+ * Renders children only when the current workspace has an active subscription (any plan).
11
+ * Optionally pass loadingComponent (while loading) or fallbackComponent (when not subscribed).
12
+ * Must be used within SubscriptionContextProvider.
13
+ *
14
+ * @param props - Component props
15
+ * @param props.children - Content to render when subscribed
16
+ * @param props.loadingComponent - Optional component/element to show while loading
17
+ * @param props.fallbackComponent - Optional component/element to show when not subscribed
18
+ * @returns ReactNode - children when subscribed, loadingComponent when loading, fallbackComponent when not subscribed, or null
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <WhenSubscription>
23
+ * <BillingSettings />
24
+ * </WhenSubscription>
25
+ * ```
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <WhenSubscription
30
+ * loadingComponent={<Skeleton />}
31
+ * fallbackComponent={<UpgradePrompt />}
32
+ * >
33
+ * <BillingSettings />
34
+ * </WhenSubscription>
35
+ * ```
36
+ */
37
+ export declare const WhenSubscription: (props: IWhenSubscriptionProps) => import("react").ReactNode;
38
+ /**
39
+ * Renders children only when the current workspace has no subscription (or no current workspace).
40
+ * Optionally pass loadingComponent (while loading) or fallbackComponent (when already subscribed).
41
+ * Must be used within SubscriptionContextProvider.
42
+ *
43
+ * @param props - Component props
44
+ * @param props.children - Content to render when not subscribed
45
+ * @param props.loadingComponent - Optional component/element to show while loading
46
+ * @param props.fallbackComponent - Optional component/element to show when already subscribed
47
+ * @returns ReactNode - children when not subscribed, loadingComponent when loading, fallbackComponent when subscribed, or null
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * <WhenNoSubscription>
52
+ * <UpgradePrompt />
53
+ * </WhenNoSubscription>
54
+ * ```
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * <WhenNoSubscription
59
+ * loadingComponent={<Spinner />}
60
+ * fallbackComponent={null}
61
+ * >
62
+ * <UpgradePrompt />
63
+ * </WhenNoSubscription>
64
+ * ```
65
+ */
66
+ export declare const WhenNoSubscription: (props: IWhenSubscriptionProps) => import("react").ReactNode;
67
+ interface IWhenSubscriptionToPlansProps {
68
+ /** Plan slugs to match (e.g. ['pro', 'enterprise']). Matching is case-insensitive. */
69
+ plans: string[];
70
+ /** Content to render when the workspace is on one of the given plans. */
71
+ children: React.ReactNode;
72
+ /** Optional component/element to show while subscription is loading (e.g. <Skeleton />). */
73
+ loadingComponent?: React.ReactNode;
74
+ /** Optional component/element to show when not on a matching plan (e.g. <UpgradeToPro />). */
75
+ fallbackComponent?: React.ReactNode;
76
+ }
77
+ /**
78
+ * Renders children only when the current workspace is subscribed to one of the given plans.
79
+ * Matches by plan slug only. Optionally pass loadingComponent (while loading) or fallbackComponent (when not on a matching plan).
80
+ * Must be used within SubscriptionContextProvider.
81
+ *
82
+ * @param props - Component props
83
+ * @param props.plans - Plan slugs to match (e.g. ['pro', 'enterprise'])
84
+ * @param props.children - Content to render when on a matching plan
85
+ * @param props.loadingComponent - Optional component/element to show while loading
86
+ * @param props.fallbackComponent - Optional component/element to show when not on a matching plan
87
+ * @returns ReactNode - children when on a matching plan, loadingComponent when loading, fallbackComponent when not matching, or null
88
+ *
89
+ * @example
90
+ * ```tsx
91
+ * <WhenSubscriptionToPlans plans={['pro', 'enterprise']}>
92
+ * <AdvancedAnalytics />
93
+ * </WhenSubscriptionToPlans>
94
+ * ```
95
+ *
96
+ * @example
97
+ * ```tsx
98
+ * <WhenSubscriptionToPlans
99
+ * plans={['pro', 'enterprise']}
100
+ * loadingComponent={<Skeleton />}
101
+ * fallbackComponent={<UpgradeToPro />}
102
+ * >
103
+ * <AdvancedAnalytics />
104
+ * </WhenSubscriptionToPlans>
105
+ * ```
106
+ */
107
+ export declare const WhenSubscriptionToPlans: (props: IWhenSubscriptionToPlansProps) => import("react").ReactNode;
108
+ export {};
@@ -0,0 +1,22 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { SubscriptionContextValue } from './types';
3
+ /**
4
+ * Provides subscription data for the current workspace to subscription gate components.
5
+ * Fetches when workspace changes; refetches when subscription is invalidated (e.g. after plan change).
6
+ * Must wrap (or be ancestor of) any component that uses WhenSubscription, WhenNoSubscription,
7
+ * WhenSubscriptionToPlans, or useSubscriptionContext. Included in SaaSOSProvider by default.
8
+ *
9
+ * @param props - Component props
10
+ * @param props.children - React tree that may use subscription gates or useSubscriptionContext
11
+ * @returns Provider element that supplies subscription context to descendants
12
+ */
13
+ export declare const SubscriptionContextProvider: React.FC<{
14
+ children: ReactNode;
15
+ }>;
16
+ /**
17
+ * Returns subscription data for the current workspace. Must be used within SubscriptionContextProvider.
18
+ *
19
+ * @returns SubscriptionContextValue - { response, loading, refetch }
20
+ * @throws Error if used outside SubscriptionContextProvider
21
+ */
22
+ export declare function useSubscriptionContext(): SubscriptionContextValue;
@@ -0,0 +1,2 @@
1
+ export { SubscriptionContextProvider, useSubscriptionContext } from './SubscriptionContext';
2
+ export type { SubscriptionContextValue } from './types';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Internal notifier for subscription data invalidation.
3
+ * When subscription is updated (plan change, cancel, resume), call invalidateSubscription()
4
+ * so SubscriptionContextProvider refetches and gates stay in sync.
5
+ */
6
+ type Listener = () => void;
7
+ /**
8
+ * Subscribe a refetch callback to be called when subscription is invalidated.
9
+ *
10
+ * @param fn - Callback (e.g. refetch) to run when invalidateSubscription() is called
11
+ * @returns Unsubscribe function to remove the callback
12
+ */
13
+ export declare function subscribeSubscriptionInvalidate(fn: Listener): () => void;
14
+ /**
15
+ * Notify all subscribers to refetch subscription (e.g. after update/cancel/resume).
16
+ * Called internally by useUpdateSubscription, useCancelSubscription, useResumeSubscription on success.
17
+ */
18
+ export declare function invalidateSubscription(): void;
19
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { ISubscriptionResponse } from '../../api/types';
2
+ /**
3
+ * Value provided by SubscriptionContext and returned by useSubscriptionContext.
4
+ */
5
+ export interface SubscriptionContextValue {
6
+ /** Current subscription response for the current workspace, or null if none or not loaded. */
7
+ response: ISubscriptionResponse | null;
8
+ /** True while subscription is being fetched. */
9
+ loading: boolean;
10
+ /** Refetch subscription for the current workspace. Call after plan change (e.g. upgrade) or when subscription was updated elsewhere. */
11
+ refetch: () => Promise<void>;
12
+ }
@@ -6,6 +6,8 @@ export { WorkspaceContextProvider, getInitialWorkspaceState, useWorkspaceContext
6
6
  export type { WorkspaceAction, WorkspaceContextValue, WorkspaceState } from './WorkspaceContext';
7
7
  export { SDKContextProvider } from './SDKContext';
8
8
  export type { SDKContextValue } from './SDKContext';
9
+ export { SubscriptionContextProvider, useSubscriptionContext } from './SubscriptionContext';
10
+ export type { SubscriptionContextValue } from './SubscriptionContext';
9
11
  export { useAppSelector } from './shared/useAppSelector';
10
12
  export type { SDKState } from './shared/useAppSelector';
11
13
  export { useAppDispatch } from './shared/useAppDispatch';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Combined SDK state and dispatch types.
3
+ * Single source of truth for the shape used by useAppSelector and useAppDispatch.
4
+ */
5
+ import type { IAuthState } from '../../providers/auth/types';
6
+ import type { IOsState } from '../../providers/os/types';
7
+ import type { AuthAction } from '../AuthContext/types';
8
+ import type { OSAction } from '../OSContext/types';
9
+ import type { WorkspaceAction, WorkspaceState } from '../WorkspaceContext/types';
10
+ /** Combined SDK state (state only, no dispatch). Used by useAppSelector. */
11
+ export interface SDKState {
12
+ os: IOsState;
13
+ auth: IAuthState;
14
+ workspaces: WorkspaceState;
15
+ }
16
+ /** Combined SDK dispatch. Used by useAppDispatch. */
17
+ export interface SDKDispatch {
18
+ auth: (action: AuthAction) => void;
19
+ os: (action: OSAction) => void;
20
+ workspaces: (action: WorkspaceAction) => void;
21
+ }
@@ -1,15 +1,5 @@
1
- import type { AuthAction } from '../AuthContext/types';
2
- import type { OSAction } from '../OSContext/types';
3
- import type { WorkspaceAction } from '../WorkspaceContext/types';
4
- /**
5
- * Combined SDK Dispatch
6
- * Provides dispatch functions for all contexts
7
- */
8
- export interface SDKDispatch {
9
- auth: (action: AuthAction) => void;
10
- os: (action: OSAction) => void;
11
- workspaces: (action: WorkspaceAction) => void;
12
- }
1
+ import type { SDKDispatch } from './types';
2
+ export type { SDKDispatch } from './types';
13
3
  /**
14
4
  * Combined dispatch hook - dispatch actions to all contexts
15
5
  *
@@ -1,15 +1,5 @@
1
- import type { IAuthState } from '../../providers/auth/types';
2
- import type { IOsState } from '../../providers/os/types';
3
- import type { WorkspaceState } from '../WorkspaceContext/types';
4
- /**
5
- * Combined SDK State
6
- * Represents the complete state structure across all contexts
7
- */
8
- export interface SDKState {
9
- os: IOsState;
10
- auth: IAuthState;
11
- workspaces: WorkspaceState;
12
- }
1
+ import type { SDKState } from './types';
2
+ export type { SDKState } from './types';
13
3
  /**
14
4
  * Combined selector hook - select from all contexts at once
15
5
  *
@@ -4,8 +4,8 @@
4
4
  /**
5
5
  * Creates a simple reducer case that updates a single field
6
6
  */
7
- export declare function updateField<State extends Record<string, any>>(state: State, field: keyof State, value: any): State;
7
+ export declare function updateField<State, K extends keyof State>(state: State, field: K, value: State[K]): State;
8
8
  /**
9
9
  * Creates a reducer case that updates multiple fields
10
10
  */
11
- export declare function updateFields<State extends Record<string, any>>(state: State, updates: Partial<State>): State;
11
+ export declare function updateFields<State extends object>(state: State, updates: Partial<State>): State;
@@ -7,14 +7,21 @@ export type { PricingPageDetails, PricingPageProps } from './components/pricing'
7
7
  export { WhenAuthenticated, WhenUnauthenticated } from './components/user/auth';
8
8
  export { WhenRoles, WhenWorkspaceRoles } from './components/user/role';
9
9
  export { WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, } from './components/features';
10
+ export { WhenNoSubscription, WhenSubscription, WhenSubscriptionToPlans, } from './components/subscription';
11
+ export { SubscriptionContextProvider, useSubscriptionContext, } from './contexts/SubscriptionContext';
12
+ export type { SubscriptionContextValue } from './contexts/SubscriptionContext';
10
13
  export { AuthStatus } from './providers/auth/types';
11
14
  export type { OnWorkspaceChangeParams } from './providers/auth/types';
12
15
  export { useSaaSAuth } from './providers/auth/hooks';
13
- export { useSaaSSettings } from './providers/os/hooks';
16
+ export { useSaaSOs, useSaaSSettings } from './providers/os/hooks';
14
17
  export { useUserAttributes, useUserFeatures } from './providers/user/hooks';
15
18
  export { useSaaSWorkspaces } from './providers/workspace/hooks';
16
19
  export { WorkspaceSwitcher } from './providers/workspace/provider';
17
20
  export { useCreateCheckoutSession, useInvoice, useInvoices, usePlanGroup, usePlanGroupVersions, usePublicPlanGroupVersion, usePublicPlans, useSubscription, useSubscriptionManagement, useUpdateSubscription, } from './providers/workspace/subscription-hooks';
18
21
  export { eventEmitter } from './providers/events';
19
22
  export type { EventData, EventType, IEventCallbacks, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData, } from './providers/events/types';
20
- export type { BillingInterval, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, InvoiceStatus, IPlan, IPlanGroup, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionsResponse, IPlanGroupVersionWithPlans, IPlanVersion, IPlanVersionWithPlan, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanPricing, IPublicPlanQuotaValue, IPublicPlansResponse, IPublicPlanVersion, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, } from './api/types';
23
+ export { BaseApi, SettingsApi, UserApi, WorkspaceApi } from './api';
24
+ export type { IBaseApiConfig } from './api';
25
+ export { formatQuotaWithPrice, getQuotaDisplayValue } from './api/quota-utils';
26
+ export type { FormatQuotaWithPriceOptions, QuotaDisplayValue, } from './api/quota-utils';
27
+ export type { BillingInterval, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanPricing, IPublicPlanQuotaValue, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaValue, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, InvoiceStatus, } from './api/types';
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Base API client for SDK endpoints.
3
+ * All domain API classes (WorkspaceApi, UserApi, etc.) extend this to share
4
+ * URL building, auth headers, and request/response handling.
5
+ */
6
+ import type { ApiVersion } from '../providers/os/types';
7
+ export interface IBaseApiConfig {
8
+ serverUrl: string;
9
+ version: ApiVersion;
10
+ orgId?: string;
11
+ /** When true, ensureReady() also requires orgId. Used by WorkspaceApi and SettingsApi. */
12
+ requireOrgId?: boolean;
13
+ /** API path segment after version (default 'public'). e.g. 'public' => .../v1/public, 'beta' => .../v1/beta */
14
+ basePath?: string;
15
+ }
16
+ /**
17
+ * Base class for SDK API clients.
18
+ * Provides:
19
+ * - baseUrl: `${serverUrl}/api/${version}/public`
20
+ * - getAuthHeaders()
21
+ * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
22
+ * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
23
+ */
24
+ export declare abstract class BaseApi {
25
+ protected readonly serverUrl: string;
26
+ protected readonly version: ApiVersion;
27
+ protected readonly orgId: string | undefined;
28
+ private readonly requireOrgId;
29
+ private readonly basePath;
30
+ constructor(config: IBaseApiConfig);
31
+ /** Throws if config is not ready for API calls. Called automatically by fetchJson/fetchResponse. */
32
+ protected ensureReady(): void;
33
+ /** Base URL: ${serverUrl}/api/${version}/${basePath} */
34
+ protected get baseUrl(): string;
35
+ /** Auth headers (x-session-id). Subclasses can override to add more. */
36
+ protected getAuthHeaders(): Record<string, string>;
37
+ /** Build full URL from path (path can be "workspaces" or "/workspaces"). */
38
+ protected url(path: string): string;
39
+ /**
40
+ * Execute request and parse JSON with handleApiResponse (throws on !response.ok).
41
+ * Use for standard JSON APIs.
42
+ */
43
+ protected fetchJson<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
44
+ /**
45
+ * Execute request and return raw Response (for custom parsing or error handling).
46
+ * Caller is responsible for checking response.ok and parsing body.
47
+ */
48
+ protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
49
+ }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { IAuthConfig } from './auth/types';
3
- import type { IOsState } from './os/types';
3
+ import { type IOsState } from './os/types';
4
4
  interface ContextConfigProviderProps {
5
5
  config: IOsState;
6
6
  auth?: IAuthConfig;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Centralized API client for auth (profile).
3
+ * Extends BaseApi; uses explicit sessionId for profile (e.g. after redirect or hydration).
4
+ */
5
+ import { IUser } from '../../api/types';
6
+ import { BaseApi } from '../../lib/api-base';
7
+ import type { IOsConfig } from '../os/types';
8
+ export declare class AuthApi extends BaseApi {
9
+ constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'>);
10
+ /** Fetch user profile with the given session ID (used after OAuth redirect or from storage). */
11
+ getProfile(sessionId: string, signal?: AbortSignal): Promise<IUser>;
12
+ }
@@ -60,6 +60,8 @@ import { WorkspaceSettingsSection } from '../workspace/ui/SettingsDialog';
60
60
  * }
61
61
  * ```
62
62
  */
63
+ /** Internal: select auth slice. Used by AuthProviderWrapper and useSaaSAuth. */
64
+ export declare function useAuthState(): import("./types").IAuthState;
63
65
  export declare function useSaaSAuth(): {
64
66
  signIn: () => Promise<void>;
65
67
  signOut: () => Promise<void>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Centralized API client for organization (OS) settings.
3
+ * Extends BaseApi for shared URL/auth/request handling.
4
+ */
5
+ import { BaseApi } from '../../lib/api-base';
6
+ import type { ISettings } from '../types';
7
+ import type { IOsConfig } from './types';
8
+ export declare class SettingsApi extends BaseApi {
9
+ constructor(config: IOsConfig);
10
+ getSettings(signal?: AbortSignal): Promise<ISettings>;
11
+ }
@@ -1,4 +1,10 @@
1
1
  import type { ISettings } from '../types';
2
+ import { type IOsState } from './types';
3
+ /**
4
+ * Hook to access OS (organization) state (serverUrl, version, orgId, auth, settings).
5
+ * Prefer useSaaSSettings() when you only need settings.
6
+ */
7
+ export declare function useSaaSOs(): IOsState;
2
8
  /**
3
9
  * Hook to access organization settings from the OS context.
4
10
  * Automatically fetches settings when OS config is ready.
@@ -11,6 +11,8 @@ export interface IOsConfig {
11
11
  version: ApiVersion;
12
12
  orgId: string;
13
13
  }
14
+ /** True when OS config has serverUrl, version, and orgId (ready for API calls). */
15
+ export declare function isOsConfigReady(config: Pick<IOsConfig, 'serverUrl' | 'version' | 'orgId'> | null | undefined): boolean;
14
16
  export interface IOsState extends IOsConfig {
15
17
  auth?: IAuthConfig;
16
18
  settings?: ISettings | null;
@@ -0,0 +1,16 @@
1
+ import { IUser } from '../../api/types';
2
+ import { BaseApi } from '../../lib/api-base';
3
+ import type { IOsConfig } from '../os/types';
4
+ /**
5
+ * Centralized API client for user attributes and features.
6
+ * Extends BaseApi for shared URL/auth/request handling.
7
+ */
8
+ export declare class UserApi extends BaseApi {
9
+ constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'>);
10
+ getAttributes(signal?: AbortSignal): Promise<Record<string, string | number | boolean>>;
11
+ updateAttributes(updates: Record<string, string | number | boolean>): Promise<IUser>;
12
+ updateAttribute(attributeKey: string, value: string | number | boolean): Promise<IUser>;
13
+ getFeatures(signal?: AbortSignal): Promise<Record<string, boolean>>;
14
+ }
15
+ /** Memoized UserApi instance. Recreates only when serverUrl or version change. BaseApi.ensureReady() throws if config is not set. */
16
+ export declare function useUserApi(): UserApi;
@@ -1,3 +1,4 @@
1
+ export { useUserApi } from './api';
1
2
  /**
2
3
  * Hook to access user attributes from the UserProvider.
3
4
  * Must be used within a UserProvider component.
@@ -1,12 +1,9 @@
1
1
  import { ICheckoutSessionRequest, ICheckoutSessionResponse, IInvoiceListResponse, IInvoiceResponse, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionsResponse, IPublicPlansResponse, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUser } from '../../api/types';
2
+ import { BaseApi } from '../../lib/api-base';
2
3
  import { IOsConfig } from '../os/types';
3
4
  import type { IWorkspace, IWorkspaceFeature, IWorkspaceUser } from './types';
4
- export declare class WorkspaceApi {
5
- private version;
6
- private orgId;
7
- private serverUrl;
5
+ export declare class WorkspaceApi extends BaseApi {
8
6
  constructor(config: IOsConfig);
9
- getAuthHeader(): Record<string, string>;
10
7
  getWorkspaces(): Promise<IWorkspace[]>;
11
8
  createWorkspace(data: {
12
9
  name: string;
@@ -1,4 +1,6 @@
1
1
  import { IUser } from '../../api/types';
2
+ import type { IOsConfig, IOsState } from '../os/types';
3
+ import { WorkspaceApi } from './api';
2
4
  import { IWorkspace, IWorkspaceUser } from './types';
3
5
  /**
4
6
  * Main workspace management hook for the SDK.
@@ -105,6 +107,13 @@ import { IWorkspace, IWorkspaceUser } from './types';
105
107
  * }
106
108
  * ```
107
109
  */
110
+ /** Memoized WorkspaceApi instance. Recreates only when serverUrl, version, or orgId change. */
111
+ export declare function useWorkspaceApi(os: IOsConfig): WorkspaceApi;
112
+ /** OS state + memoized WorkspaceApi. BaseApi.ensureReady() throws if config is not set. Use when a hook needs both (e.g. subscription hooks, useSaaSWorkspaces). */
113
+ export declare function useWorkspaceApiWithOs(): {
114
+ os: IOsState;
115
+ api: WorkspaceApi;
116
+ };
108
117
  export declare const useSaaSWorkspaces: () => {
109
118
  workspaces: IWorkspace[];
110
119
  loading: boolean;
@@ -148,4 +157,5 @@ export declare const useSaaSWorkspaces: () => {
148
157
  success: boolean;
149
158
  }>;
150
159
  switching: boolean;
160
+ switchingToId: string | null;
151
161
  };
@@ -120,7 +120,7 @@ export declare const useSubscription: (workspaceId: string | null | undefined) =
120
120
  *
121
121
  * return (
122
122
  * <div>
123
- * <h3>{planGroup.name}</h3>
123
+ * <h3>{planGroup.group.name}</h3>
124
124
  * {planGroup.plans.map(plan => (
125
125
  * <PlanCard key={plan._id} plan={plan} />
126
126
  * ))}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildbase/sdk",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "type": "module",
5
5
  "description": "A SDK for Buildbase",
6
6
  "main": "dist/index.js",