@buildbase/sdk 0.0.16 → 0.0.19

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 (40) hide show
  1. package/README.md +201 -98
  2. package/dist/index.d.ts +594 -198
  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/saas-os.css +1 -1
  8. package/dist/types/api/currency-utils.d.ts +44 -0
  9. package/dist/types/api/index.d.ts +11 -0
  10. package/dist/types/api/pricing-variant-utils.d.ts +53 -0
  11. package/dist/types/api/quota-utils.d.ts +24 -0
  12. package/dist/types/api/types.d.ts +118 -43
  13. package/dist/types/components/beta/api.d.ts +1 -2
  14. package/dist/types/components/pricing/PricingPage.d.ts +3 -1
  15. package/dist/types/components/subscription/index.d.ts +108 -0
  16. package/dist/types/contexts/SubscriptionContext/SubscriptionContext.d.ts +22 -0
  17. package/dist/types/contexts/SubscriptionContext/index.d.ts +2 -0
  18. package/dist/types/contexts/SubscriptionContext/subscriptionInvalidation.d.ts +19 -0
  19. package/dist/types/contexts/SubscriptionContext/types.d.ts +12 -0
  20. package/dist/types/contexts/index.d.ts +2 -0
  21. package/dist/types/contexts/shared/types.d.ts +21 -0
  22. package/dist/types/contexts/shared/useAppDispatch.d.ts +2 -12
  23. package/dist/types/contexts/shared/useAppSelector.d.ts +2 -12
  24. package/dist/types/contexts/shared/utils/reducerHelpers.d.ts +2 -2
  25. package/dist/types/index.d.ts +12 -2
  26. package/dist/types/lib/api-base.d.ts +49 -0
  27. package/dist/types/providers/ContextConfigProvider.d.ts +1 -1
  28. package/dist/types/providers/auth/api.d.ts +12 -0
  29. package/dist/types/providers/auth/hooks.d.ts +2 -0
  30. package/dist/types/providers/os/api.d.ts +11 -0
  31. package/dist/types/providers/os/hooks.d.ts +6 -0
  32. package/dist/types/providers/os/types.d.ts +2 -0
  33. package/dist/types/providers/user/api.d.ts +16 -0
  34. package/dist/types/providers/user/hooks.d.ts +1 -0
  35. package/dist/types/providers/workspace/api.d.ts +2 -5
  36. package/dist/types/providers/workspace/hooks.d.ts +11 -1
  37. package/dist/types/providers/workspace/subscription-hooks.d.ts +2 -1
  38. package/dist/types/providers/workspace/types.d.ts +18 -1
  39. package/dist/types/providers/workspace/ui/SubscriptionDialog.d.ts +7 -1
  40. package/package.json +1 -1
@@ -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,24 @@ 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 { CURRENCY_DISPLAY, CURRENCY_FLAG, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, getCurrencyFlag, getCurrencySymbol, getQuotaUnitLabelFromName, } from './api/currency-utils';
26
+ export { formatQuotaWithPrice, getQuotaDisplayValue } from './api/quota-utils';
27
+ export type { FormatQuotaWithPriceOptions, QuotaDisplayValue } from './api/quota-utils';
28
+ export { getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getDisplayCurrency, getPricingVariant, getQuotaDisplayWithVariant, getQuotaOverageCents, getStripePriceIdForInterval, } from './api/pricing-variant-utils';
29
+ export type { PlanVersionWithPricingVariants, QuotaDisplayWithOverage, } from './api/pricing-variant-utils';
30
+ export type { BillingInterval, IBasePricing, ICheckoutSessionRequest, ICheckoutSessionResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IStripePricesByInterval, 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;
@@ -120,7 +129,7 @@ export declare const useSaaSWorkspaces: () => {
120
129
  forceEmit?: boolean;
121
130
  }) => Promise<void>;
122
131
  resetCurrentWorkspace: () => void;
123
- createWorkspace: (name: string, image: string) => Promise<void>;
132
+ createWorkspace: (name: string, image?: string) => Promise<void>;
124
133
  allFeatures: import("./types").IWorkspaceFeature[];
125
134
  getFeatures: () => Promise<import("./types").IWorkspaceFeature[] | null>;
126
135
  updateFeature: (workspaceId: string, key: string, value: boolean) => Promise<IWorkspace>;
@@ -148,4 +157,5 @@ export declare const useSaaSWorkspaces: () => {
148
157
  success: boolean;
149
158
  }>;
150
159
  switching: boolean;
160
+ switchingToId: string | null;
151
161
  };
@@ -10,6 +10,7 @@ import { BillingInterval, ICheckoutSessionRequest, ICheckoutSessionResponse, IIn
10
10
  export declare const usePublicPlans: (slug: string) => {
11
11
  items: import("../..").IPublicPlanItem[];
12
12
  plans: import("../..").IPublicPlanVersion[];
13
+ notes: string | undefined;
13
14
  loading: boolean;
14
15
  error: string | null;
15
16
  refetch: () => Promise<void>;
@@ -120,7 +121,7 @@ export declare const useSubscription: (workspaceId: string | null | undefined) =
120
121
  *
121
122
  * return (
122
123
  * <div>
123
- * <h3>{planGroup.name}</h3>
124
+ * <h3>{planGroup.group.name}</h3>
124
125
  * {planGroup.plans.map(plan => (
125
126
  * <PlanCard key={plan._id} plan={plan} />
126
127
  * ))}
@@ -7,7 +7,24 @@ export interface IWorkspace {
7
7
  roles: string[];
8
8
  createdBy: string | IUser;
9
9
  features: Record<string, boolean>;
10
- subscription?: ISubscription | null;
10
+ /**
11
+ * Quota usage tracking: { [quotaSlug]: number } – how much of each quota has been used.
12
+ */
13
+ quotas?: Record<string, number>;
14
+ /**
15
+ * Subscription limits snapshot: { [limitSlug]: number | null } – synced from subscription plan.
16
+ * Limits are maximum values (e.g. max-users, max-workspaces). Updated when subscription is assigned/updated.
17
+ */
18
+ limits?: Record<string, number | null>;
19
+ subscription?: ISubscription | string | null;
20
+ /** Stripe Customer ID for this workspace. */
21
+ stripeCustomerId?: string;
22
+ /**
23
+ * Billing currency locked for this workspace (set on first subscription).
24
+ * Stripe allows one currency per customer; all future subscriptions must use this currency.
25
+ * When set, subscription UI only shows/uses this currency.
26
+ */
27
+ billingCurrency?: string | null;
11
28
  }
12
29
  export interface IWorkspaceFeature {
13
30
  _id: string;
@@ -6,7 +6,13 @@ interface SubscriptionDialogProps {
6
6
  planVersions: IPlanVersionWithPlan[];
7
7
  currentPlanVersionId?: string | null;
8
8
  currentStripePriceId?: string | null;
9
- onSelectPlan: (planVersionId: string, billingInterval: BillingInterval) => Promise<void>;
9
+ /**
10
+ * When set, only this currency is allowed (workspace has existing Stripe billing; Stripe does not allow multiple currencies per customer).
11
+ * When null/undefined, all plan currencies are available.
12
+ */
13
+ billingCurrency?: string | null;
14
+ /** Called when user selects a plan. Currency is optional (for display/logging only; not sent to API). */
15
+ onSelectPlan: (planVersionId: string, billingInterval: BillingInterval, currency?: string) => Promise<void>;
10
16
  loading?: boolean;
11
17
  }
12
18
  declare const SubscriptionDialog: React.FC<SubscriptionDialogProps>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildbase/sdk",
3
- "version": "0.0.16",
3
+ "version": "0.0.19",
4
4
  "type": "module",
5
5
  "description": "A SDK for Buildbase",
6
6
  "main": "dist/index.js",