@buildbase/sdk 0.0.15 → 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 (37) hide show
  1. package/README.md +208 -98
  2. package/dist/index.d.ts +395 -168
  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/index.d.ts +6 -0
  9. package/dist/types/api/quota-utils.d.ts +24 -0
  10. package/dist/types/api/types.d.ts +40 -15
  11. package/dist/types/components/beta/api.d.ts +1 -2
  12. package/dist/types/components/pricing/PricingPage.d.ts +1 -1
  13. package/dist/types/components/subscription/index.d.ts +108 -0
  14. package/dist/types/contexts/SubscriptionContext/SubscriptionContext.d.ts +22 -0
  15. package/dist/types/contexts/SubscriptionContext/index.d.ts +2 -0
  16. package/dist/types/contexts/SubscriptionContext/subscriptionInvalidation.d.ts +19 -0
  17. package/dist/types/contexts/SubscriptionContext/types.d.ts +12 -0
  18. package/dist/types/contexts/index.d.ts +2 -0
  19. package/dist/types/contexts/shared/types.d.ts +21 -0
  20. package/dist/types/contexts/shared/useAppDispatch.d.ts +2 -12
  21. package/dist/types/contexts/shared/useAppSelector.d.ts +2 -12
  22. package/dist/types/contexts/shared/utils/reducerHelpers.d.ts +2 -2
  23. package/dist/types/index.d.ts +9 -2
  24. package/dist/types/lib/api-base.d.ts +49 -0
  25. package/dist/types/providers/ContextConfigProvider.d.ts +1 -1
  26. package/dist/types/providers/auth/api.d.ts +12 -0
  27. package/dist/types/providers/auth/hooks.d.ts +2 -0
  28. package/dist/types/providers/os/api.d.ts +11 -0
  29. package/dist/types/providers/os/hooks.d.ts +6 -0
  30. package/dist/types/providers/os/types.d.ts +2 -0
  31. package/dist/types/providers/user/api.d.ts +16 -0
  32. package/dist/types/providers/user/hooks.d.ts +1 -0
  33. package/dist/types/providers/workspace/api.d.ts +16 -5
  34. package/dist/types/providers/workspace/hooks.d.ts +10 -0
  35. package/dist/types/providers/workspace/subscription-hooks.d.ts +81 -1
  36. package/dist/types/providers/workspace/ui/SubscriptionDialog.d.ts +3 -2
  37. package/package.json +1 -1
@@ -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;
@@ -114,4 +111,18 @@ export declare class WorkspaceApi {
114
111
  * @returns Invoice details
115
112
  */
116
113
  getInvoice(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
114
+ /**
115
+ * Cancel subscription at the end of the current billing period
116
+ * Sets cancelAtPeriodEnd: true - subscription remains active until period ends
117
+ * @param workspaceId - The workspace ID
118
+ * @returns Updated subscription with cancelAtPeriodEnd and stripeCurrentPeriodEnd
119
+ */
120
+ cancelSubscriptionAtPeriodEnd(workspaceId: string): Promise<ISubscriptionResponse>;
121
+ /**
122
+ * Resume a subscription that was scheduled for cancellation
123
+ * Sets cancelAtPeriodEnd: false - subscription will continue after period ends
124
+ * @param workspaceId - The workspace ID
125
+ * @returns Updated subscription with cancelAtPeriodEnd set to false
126
+ */
127
+ resumeSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
117
128
  }
@@ -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
  * ))}
@@ -480,3 +480,83 @@ export declare const useInvoice: (workspaceId: string | null | undefined, invoic
480
480
  error: string | null;
481
481
  refetch: () => Promise<void>;
482
482
  };
483
+ /**
484
+ * Hook to cancel a subscription at the end of the current billing period.
485
+ * Sets cancelAtPeriodEnd: true - subscription remains active until period ends.
486
+ *
487
+ * @param workspaceId - The workspace ID. Can be null/undefined.
488
+ * @returns An object containing:
489
+ * - `cancelSubscription()`: Function to cancel subscription at period end
490
+ * - `loading`: Boolean indicating if cancellation is in progress
491
+ * - `error`: Error message string (null if no error)
492
+ *
493
+ * @example
494
+ * ```tsx
495
+ * function CancelSubscriptionButton() {
496
+ * const { currentWorkspace } = useSaaSWorkspaces();
497
+ * const { cancelSubscription, loading } = useCancelSubscription(currentWorkspace?._id);
498
+ * const { refetch } = useSubscription(currentWorkspace?._id);
499
+ *
500
+ * const handleCancel = async () => {
501
+ * try {
502
+ * await cancelSubscription();
503
+ * await refetch(); // Refresh subscription data
504
+ * alert('Subscription will be canceled at the end of the billing period');
505
+ * } catch (error) {
506
+ * console.error('Failed to cancel:', error);
507
+ * }
508
+ * };
509
+ *
510
+ * return (
511
+ * <button onClick={handleCancel} disabled={loading}>
512
+ * {loading ? 'Canceling...' : 'Cancel Subscription'}
513
+ * </button>
514
+ * );
515
+ * }
516
+ * ```
517
+ */
518
+ export declare const useCancelSubscription: (workspaceId: string | null | undefined) => {
519
+ cancelSubscription: () => Promise<ISubscriptionResponse>;
520
+ loading: boolean;
521
+ error: string | null;
522
+ };
523
+ /**
524
+ * Hook to resume a subscription that was scheduled for cancellation.
525
+ * Sets cancelAtPeriodEnd: false - subscription will continue after period ends.
526
+ *
527
+ * @param workspaceId - The workspace ID. Can be null/undefined.
528
+ * @returns An object containing:
529
+ * - `resumeSubscription()`: Function to resume subscription
530
+ * - `loading`: Boolean indicating if resume is in progress
531
+ * - `error`: Error message string (null if no error)
532
+ *
533
+ * @example
534
+ * ```tsx
535
+ * function ResumeSubscriptionButton() {
536
+ * const { currentWorkspace } = useSaaSWorkspaces();
537
+ * const { resumeSubscription, loading } = useResumeSubscription(currentWorkspace?._id);
538
+ * const { refetch } = useSubscription(currentWorkspace?._id);
539
+ *
540
+ * const handleResume = async () => {
541
+ * try {
542
+ * await resumeSubscription();
543
+ * await refetch(); // Refresh subscription data
544
+ * alert('Subscription has been resumed');
545
+ * } catch (error) {
546
+ * console.error('Failed to resume:', error);
547
+ * }
548
+ * };
549
+ *
550
+ * return (
551
+ * <button onClick={handleResume} disabled={loading}>
552
+ * {loading ? 'Resuming...' : 'Resume Subscription'}
553
+ * </button>
554
+ * );
555
+ * }
556
+ * ```
557
+ */
558
+ export declare const useResumeSubscription: (workspaceId: string | null | undefined) => {
559
+ resumeSubscription: () => Promise<ISubscriptionResponse>;
560
+ loading: boolean;
561
+ error: string | null;
562
+ };
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
- import { IPlanVersionWithPlan } from '../../../api/types';
2
+ import { BillingInterval, IPlanVersionWithPlan } from '../../../api/types';
3
3
  interface SubscriptionDialogProps {
4
4
  open: boolean;
5
5
  onOpenChange: (open: boolean) => void;
6
6
  planVersions: IPlanVersionWithPlan[];
7
7
  currentPlanVersionId?: string | null;
8
- onSelectPlan: (planVersionId: string) => Promise<void>;
8
+ currentStripePriceId?: string | null;
9
+ onSelectPlan: (planVersionId: string, billingInterval: BillingInterval) => Promise<void>;
9
10
  loading?: boolean;
10
11
  }
11
12
  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.15",
3
+ "version": "0.0.18",
4
4
  "type": "module",
5
5
  "description": "A SDK for Buildbase",
6
6
  "main": "dist/index.js",