@stackbe/sdk 0.12.0 → 0.13.0

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
@@ -174,6 +174,12 @@ await stackbe.auth.sendMagicLink('user@example.com', {
174
174
  useDev: true,
175
175
  });
176
176
 
177
+ // Log user directly into a specific organization
178
+ // Customer must already be a member of the org
179
+ await stackbe.auth.sendMagicLink('user@example.com', {
180
+ organizationId: 'org_abc123',
181
+ });
182
+
177
183
  // Verify magic link token (in your /verify route)
178
184
  const { token } = req.query;
179
185
  const result = await stackbe.auth.verifyToken(token);
@@ -198,6 +204,15 @@ if (session) {
198
204
 
199
205
  // Check if authenticated
200
206
  const isAuthenticated = await stackbe.auth.isAuthenticated(sessionToken);
207
+
208
+ // Switch to a different organization (for multi-org users)
209
+ const orgs = await stackbe.organizations.listByCustomer(customerId);
210
+ if (orgs.length > 1) {
211
+ // User belongs to multiple orgs - show org picker
212
+ const { sessionToken: newToken, organizationId, orgRole } =
213
+ await stackbe.auth.switchOrganization(sessionToken, targetOrgId);
214
+ // Store newToken - it's scoped to the target org
215
+ }
201
216
  ```
202
217
 
203
218
  ### Plans & Products
package/dist/index.d.mts CHANGED
@@ -255,6 +255,12 @@ interface MagicLinkOptions {
255
255
  redirectUrl?: string;
256
256
  /** Use development callback URL (for localhost testing) */
257
257
  useDev?: boolean;
258
+ /**
259
+ * Organization ID to scope the session to after verification.
260
+ * Customer must already be a member of this organization.
261
+ * Use this to log existing members directly into a specific org.
262
+ */
263
+ organizationId?: string;
258
264
  }
259
265
  interface MagicLinkResponse {
260
266
  success: boolean;
@@ -278,6 +284,14 @@ interface VerifyTokenResponse {
278
284
  /** URL to redirect to after verification */
279
285
  redirectUrl?: string;
280
286
  }
287
+ interface SwitchOrganizationResponse {
288
+ /** New session token scoped to the target organization */
289
+ sessionToken: string;
290
+ /** Organization ID the session is now scoped to */
291
+ organizationId: string;
292
+ /** Customer's role in the organization */
293
+ orgRole: 'owner' | 'admin' | 'member';
294
+ }
281
295
  interface SessionResponse {
282
296
  valid: boolean;
283
297
  /** Customer ID */
@@ -1381,6 +1395,11 @@ declare class AuthClient {
1381
1395
  * await stackbe.auth.sendMagicLink('user@example.com', {
1382
1396
  * useDev: true,
1383
1397
  * });
1398
+ *
1399
+ * // Log user directly into a specific organization
1400
+ * await stackbe.auth.sendMagicLink('user@example.com', {
1401
+ * organizationId: 'org_abc123',
1402
+ * });
1384
1403
  * ```
1385
1404
  */
1386
1405
  sendMagicLink(email: string, options?: MagicLinkOptions): Promise<MagicLinkResponse>;
@@ -1469,6 +1488,31 @@ declare class AuthClient {
1469
1488
  * ```
1470
1489
  */
1471
1490
  isAuthenticated(sessionToken: string): Promise<boolean>;
1491
+ /**
1492
+ * Switch the current session to a different organization.
1493
+ * The customer must be a member of the target organization.
1494
+ *
1495
+ * Returns a new session token scoped to the target organization.
1496
+ * The original session token remains valid but is scoped to the previous org (or no org).
1497
+ *
1498
+ * @example
1499
+ * ```typescript
1500
+ * // Get available organizations for the customer
1501
+ * const orgs = await stackbe.organizations.listByCustomer(customerId);
1502
+ *
1503
+ * // Switch to a different organization
1504
+ * const { sessionToken: newToken, organizationId, orgRole } =
1505
+ * await stackbe.auth.switchOrganization(currentSessionToken, targetOrgId);
1506
+ *
1507
+ * // Store the new token - it's scoped to the target org
1508
+ * localStorage.setItem('sessionToken', newToken);
1509
+ * ```
1510
+ *
1511
+ * @throws {StackBEError} with code 'NOT_MEMBER' if customer is not a member of the organization
1512
+ * @throws {StackBEError} with code 'ORG_NOT_FOUND' if organization doesn't exist
1513
+ * @throws {StackBEError} with code 'SESSION_INVALID' if session token is invalid
1514
+ */
1515
+ switchOrganization(sessionToken: string, organizationId: string): Promise<SwitchOrganizationResponse>;
1472
1516
  }
1473
1517
 
1474
1518
  declare class OrganizationsClient {
@@ -1534,15 +1578,25 @@ declare class OrganizationsClient {
1534
1578
  */
1535
1579
  update(orgId: string, options: UpdateOrganizationOptions): Promise<Organization>;
1536
1580
  /**
1537
- * Delete an organization.
1538
- * Note: Organizations with active subscriptions cannot be deleted.
1581
+ * Delete an organization (soft-delete).
1582
+ * By default, fails if org has active subscriptions.
1583
+ * Pass cancelSubscriptions: true to auto-cancel them first.
1539
1584
  *
1540
1585
  * @example
1541
1586
  * ```typescript
1587
+ * // Basic delete (fails if active subscriptions)
1542
1588
  * await stackbe.organizations.delete('org_123');
1589
+ *
1590
+ * // Force delete with subscription cancellation
1591
+ * await stackbe.organizations.delete('org_123', { cancelSubscriptions: true });
1543
1592
  * ```
1544
1593
  */
1545
- delete(orgId: string): Promise<void>;
1594
+ delete(orgId: string, options?: {
1595
+ cancelSubscriptions?: boolean;
1596
+ }): Promise<{
1597
+ success: boolean;
1598
+ cancelledSubscriptions: number;
1599
+ }>;
1546
1600
  /**
1547
1601
  * Add a customer as a member of an organization.
1548
1602
  *
@@ -2315,6 +2369,8 @@ interface CreateCouponOptions {
2315
2369
  interface UpdateCouponOptions {
2316
2370
  name?: string;
2317
2371
  maxRedemptions?: number;
2372
+ /** Reset or adjust the redemption count */
2373
+ timesRedeemed?: number;
2318
2374
  expiresAt?: string;
2319
2375
  validPlanIds?: string[];
2320
2376
  active?: boolean;
@@ -2727,4 +2783,4 @@ declare class StackBE {
2727
2783
  }): (req: any, res: any, next: any) => Promise<any>;
2728
2784
  }
2729
2785
 
2730
- export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, AnalyticsClient, type AnalyticsFilterOptions, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, type DashboardMetrics, type DunningStatus, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type FeatureUsagePoint, type GetSubscriptionOptions, type GrowthChartPoint, type GrowthMetrics, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MRRHistoryPoint, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type PerformanceMetrics, type Plan, type PlanMetrics, PlansClient, type PopularEndpoint, type Product, ProductsClient, type RequestCountPoint, type RevenueByPlan, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TimeRangeOptions, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialMetrics, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
2786
+ export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, AnalyticsClient, type AnalyticsFilterOptions, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, type DashboardMetrics, type DunningStatus, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type FeatureUsagePoint, type GetSubscriptionOptions, type GrowthChartPoint, type GrowthMetrics, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MRRHistoryPoint, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type PerformanceMetrics, type Plan, type PlanMetrics, PlansClient, type PopularEndpoint, type Product, ProductsClient, type RequestCountPoint, type RevenueByPlan, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type SwitchOrganizationResponse, type TimeRangeOptions, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialMetrics, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
package/dist/index.d.ts CHANGED
@@ -255,6 +255,12 @@ interface MagicLinkOptions {
255
255
  redirectUrl?: string;
256
256
  /** Use development callback URL (for localhost testing) */
257
257
  useDev?: boolean;
258
+ /**
259
+ * Organization ID to scope the session to after verification.
260
+ * Customer must already be a member of this organization.
261
+ * Use this to log existing members directly into a specific org.
262
+ */
263
+ organizationId?: string;
258
264
  }
259
265
  interface MagicLinkResponse {
260
266
  success: boolean;
@@ -278,6 +284,14 @@ interface VerifyTokenResponse {
278
284
  /** URL to redirect to after verification */
279
285
  redirectUrl?: string;
280
286
  }
287
+ interface SwitchOrganizationResponse {
288
+ /** New session token scoped to the target organization */
289
+ sessionToken: string;
290
+ /** Organization ID the session is now scoped to */
291
+ organizationId: string;
292
+ /** Customer's role in the organization */
293
+ orgRole: 'owner' | 'admin' | 'member';
294
+ }
281
295
  interface SessionResponse {
282
296
  valid: boolean;
283
297
  /** Customer ID */
@@ -1381,6 +1395,11 @@ declare class AuthClient {
1381
1395
  * await stackbe.auth.sendMagicLink('user@example.com', {
1382
1396
  * useDev: true,
1383
1397
  * });
1398
+ *
1399
+ * // Log user directly into a specific organization
1400
+ * await stackbe.auth.sendMagicLink('user@example.com', {
1401
+ * organizationId: 'org_abc123',
1402
+ * });
1384
1403
  * ```
1385
1404
  */
1386
1405
  sendMagicLink(email: string, options?: MagicLinkOptions): Promise<MagicLinkResponse>;
@@ -1469,6 +1488,31 @@ declare class AuthClient {
1469
1488
  * ```
1470
1489
  */
1471
1490
  isAuthenticated(sessionToken: string): Promise<boolean>;
1491
+ /**
1492
+ * Switch the current session to a different organization.
1493
+ * The customer must be a member of the target organization.
1494
+ *
1495
+ * Returns a new session token scoped to the target organization.
1496
+ * The original session token remains valid but is scoped to the previous org (or no org).
1497
+ *
1498
+ * @example
1499
+ * ```typescript
1500
+ * // Get available organizations for the customer
1501
+ * const orgs = await stackbe.organizations.listByCustomer(customerId);
1502
+ *
1503
+ * // Switch to a different organization
1504
+ * const { sessionToken: newToken, organizationId, orgRole } =
1505
+ * await stackbe.auth.switchOrganization(currentSessionToken, targetOrgId);
1506
+ *
1507
+ * // Store the new token - it's scoped to the target org
1508
+ * localStorage.setItem('sessionToken', newToken);
1509
+ * ```
1510
+ *
1511
+ * @throws {StackBEError} with code 'NOT_MEMBER' if customer is not a member of the organization
1512
+ * @throws {StackBEError} with code 'ORG_NOT_FOUND' if organization doesn't exist
1513
+ * @throws {StackBEError} with code 'SESSION_INVALID' if session token is invalid
1514
+ */
1515
+ switchOrganization(sessionToken: string, organizationId: string): Promise<SwitchOrganizationResponse>;
1472
1516
  }
1473
1517
 
1474
1518
  declare class OrganizationsClient {
@@ -1534,15 +1578,25 @@ declare class OrganizationsClient {
1534
1578
  */
1535
1579
  update(orgId: string, options: UpdateOrganizationOptions): Promise<Organization>;
1536
1580
  /**
1537
- * Delete an organization.
1538
- * Note: Organizations with active subscriptions cannot be deleted.
1581
+ * Delete an organization (soft-delete).
1582
+ * By default, fails if org has active subscriptions.
1583
+ * Pass cancelSubscriptions: true to auto-cancel them first.
1539
1584
  *
1540
1585
  * @example
1541
1586
  * ```typescript
1587
+ * // Basic delete (fails if active subscriptions)
1542
1588
  * await stackbe.organizations.delete('org_123');
1589
+ *
1590
+ * // Force delete with subscription cancellation
1591
+ * await stackbe.organizations.delete('org_123', { cancelSubscriptions: true });
1543
1592
  * ```
1544
1593
  */
1545
- delete(orgId: string): Promise<void>;
1594
+ delete(orgId: string, options?: {
1595
+ cancelSubscriptions?: boolean;
1596
+ }): Promise<{
1597
+ success: boolean;
1598
+ cancelledSubscriptions: number;
1599
+ }>;
1546
1600
  /**
1547
1601
  * Add a customer as a member of an organization.
1548
1602
  *
@@ -2315,6 +2369,8 @@ interface CreateCouponOptions {
2315
2369
  interface UpdateCouponOptions {
2316
2370
  name?: string;
2317
2371
  maxRedemptions?: number;
2372
+ /** Reset or adjust the redemption count */
2373
+ timesRedeemed?: number;
2318
2374
  expiresAt?: string;
2319
2375
  validPlanIds?: string[];
2320
2376
  active?: boolean;
@@ -2727,4 +2783,4 @@ declare class StackBE {
2727
2783
  }): (req: any, res: any, next: any) => Promise<any>;
2728
2784
  }
2729
2785
 
2730
- export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, AnalyticsClient, type AnalyticsFilterOptions, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, type DashboardMetrics, type DunningStatus, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type FeatureUsagePoint, type GetSubscriptionOptions, type GrowthChartPoint, type GrowthMetrics, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MRRHistoryPoint, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type PerformanceMetrics, type Plan, type PlanMetrics, PlansClient, type PopularEndpoint, type Product, ProductsClient, type RequestCountPoint, type RevenueByPlan, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TimeRangeOptions, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialMetrics, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
2786
+ export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, AnalyticsClient, type AnalyticsFilterOptions, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, type DashboardMetrics, type DunningStatus, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type FeatureUsagePoint, type GetSubscriptionOptions, type GrowthChartPoint, type GrowthMetrics, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MRRHistoryPoint, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type PerformanceMetrics, type Plan, type PlanMetrics, PlansClient, type PopularEndpoint, type Product, ProductsClient, type RequestCountPoint, type RevenueByPlan, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type SwitchOrganizationResponse, type TimeRangeOptions, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialMetrics, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
package/dist/index.js CHANGED
@@ -1230,6 +1230,11 @@ var AuthClient = class {
1230
1230
  * await stackbe.auth.sendMagicLink('user@example.com', {
1231
1231
  * useDev: true,
1232
1232
  * });
1233
+ *
1234
+ * // Log user directly into a specific organization
1235
+ * await stackbe.auth.sendMagicLink('user@example.com', {
1236
+ * organizationId: 'org_abc123',
1237
+ * });
1233
1238
  * ```
1234
1239
  */
1235
1240
  async sendMagicLink(email, options = {}) {
@@ -1245,7 +1250,8 @@ var AuthClient = class {
1245
1250
  {
1246
1251
  email,
1247
1252
  redirectUrl,
1248
- useDev
1253
+ useDev,
1254
+ organizationId: options.organizationId
1249
1255
  }
1250
1256
  );
1251
1257
  }
@@ -1460,6 +1466,59 @@ var AuthClient = class {
1460
1466
  const session = await this.getSession(sessionToken);
1461
1467
  return session !== null;
1462
1468
  }
1469
+ /**
1470
+ * Switch the current session to a different organization.
1471
+ * The customer must be a member of the target organization.
1472
+ *
1473
+ * Returns a new session token scoped to the target organization.
1474
+ * The original session token remains valid but is scoped to the previous org (or no org).
1475
+ *
1476
+ * @example
1477
+ * ```typescript
1478
+ * // Get available organizations for the customer
1479
+ * const orgs = await stackbe.organizations.listByCustomer(customerId);
1480
+ *
1481
+ * // Switch to a different organization
1482
+ * const { sessionToken: newToken, organizationId, orgRole } =
1483
+ * await stackbe.auth.switchOrganization(currentSessionToken, targetOrgId);
1484
+ *
1485
+ * // Store the new token - it's scoped to the target org
1486
+ * localStorage.setItem('sessionToken', newToken);
1487
+ * ```
1488
+ *
1489
+ * @throws {StackBEError} with code 'NOT_MEMBER' if customer is not a member of the organization
1490
+ * @throws {StackBEError} with code 'ORG_NOT_FOUND' if organization doesn't exist
1491
+ * @throws {StackBEError} with code 'SESSION_INVALID' if session token is invalid
1492
+ */
1493
+ async switchOrganization(sessionToken, organizationId) {
1494
+ this.sessionCache.delete(sessionToken);
1495
+ const response = await fetch(
1496
+ `${this.http.baseUrl}/v1/apps/${this.appId}/auth/switch-organization`,
1497
+ {
1498
+ method: "POST",
1499
+ headers: {
1500
+ "Authorization": `Bearer ${sessionToken}`,
1501
+ "Content-Type": "application/json"
1502
+ },
1503
+ body: JSON.stringify({ organizationId })
1504
+ }
1505
+ );
1506
+ if (!response.ok) {
1507
+ const errorData = await response.json().catch(() => ({}));
1508
+ const message = errorData.message || errorData.error || "Failed to switch organization";
1509
+ let code = "SWITCH_ORG_FAILED";
1510
+ if (response.status === 401) {
1511
+ code = "SESSION_INVALID";
1512
+ } else if (message.toLowerCase().includes("not a member")) {
1513
+ code = "NOT_MEMBER";
1514
+ } else if (message.toLowerCase().includes("not found")) {
1515
+ code = "ORG_NOT_FOUND";
1516
+ }
1517
+ throw new StackBEError(message, response.status, code);
1518
+ }
1519
+ const data = await response.json();
1520
+ return data;
1521
+ }
1463
1522
  };
1464
1523
 
1465
1524
  // src/organizations.ts
@@ -1549,17 +1608,23 @@ var OrganizationsClient = class {
1549
1608
  );
1550
1609
  }
1551
1610
  /**
1552
- * Delete an organization.
1553
- * Note: Organizations with active subscriptions cannot be deleted.
1611
+ * Delete an organization (soft-delete).
1612
+ * By default, fails if org has active subscriptions.
1613
+ * Pass cancelSubscriptions: true to auto-cancel them first.
1554
1614
  *
1555
1615
  * @example
1556
1616
  * ```typescript
1617
+ * // Basic delete (fails if active subscriptions)
1557
1618
  * await stackbe.organizations.delete('org_123');
1619
+ *
1620
+ * // Force delete with subscription cancellation
1621
+ * await stackbe.organizations.delete('org_123', { cancelSubscriptions: true });
1558
1622
  * ```
1559
1623
  */
1560
- async delete(orgId) {
1624
+ async delete(orgId, options) {
1625
+ const query = options?.cancelSubscriptions ? "?cancelSubscriptions=true" : "";
1561
1626
  return this.http.delete(
1562
- `/v1/apps/${this.appId}/admin/organizations/${orgId}`
1627
+ `/v1/apps/${this.appId}/admin/organizations/${orgId}${query}`
1563
1628
  );
1564
1629
  }
1565
1630
  /**
package/dist/index.mjs CHANGED
@@ -1189,6 +1189,11 @@ var AuthClient = class {
1189
1189
  * await stackbe.auth.sendMagicLink('user@example.com', {
1190
1190
  * useDev: true,
1191
1191
  * });
1192
+ *
1193
+ * // Log user directly into a specific organization
1194
+ * await stackbe.auth.sendMagicLink('user@example.com', {
1195
+ * organizationId: 'org_abc123',
1196
+ * });
1192
1197
  * ```
1193
1198
  */
1194
1199
  async sendMagicLink(email, options = {}) {
@@ -1204,7 +1209,8 @@ var AuthClient = class {
1204
1209
  {
1205
1210
  email,
1206
1211
  redirectUrl,
1207
- useDev
1212
+ useDev,
1213
+ organizationId: options.organizationId
1208
1214
  }
1209
1215
  );
1210
1216
  }
@@ -1419,6 +1425,59 @@ var AuthClient = class {
1419
1425
  const session = await this.getSession(sessionToken);
1420
1426
  return session !== null;
1421
1427
  }
1428
+ /**
1429
+ * Switch the current session to a different organization.
1430
+ * The customer must be a member of the target organization.
1431
+ *
1432
+ * Returns a new session token scoped to the target organization.
1433
+ * The original session token remains valid but is scoped to the previous org (or no org).
1434
+ *
1435
+ * @example
1436
+ * ```typescript
1437
+ * // Get available organizations for the customer
1438
+ * const orgs = await stackbe.organizations.listByCustomer(customerId);
1439
+ *
1440
+ * // Switch to a different organization
1441
+ * const { sessionToken: newToken, organizationId, orgRole } =
1442
+ * await stackbe.auth.switchOrganization(currentSessionToken, targetOrgId);
1443
+ *
1444
+ * // Store the new token - it's scoped to the target org
1445
+ * localStorage.setItem('sessionToken', newToken);
1446
+ * ```
1447
+ *
1448
+ * @throws {StackBEError} with code 'NOT_MEMBER' if customer is not a member of the organization
1449
+ * @throws {StackBEError} with code 'ORG_NOT_FOUND' if organization doesn't exist
1450
+ * @throws {StackBEError} with code 'SESSION_INVALID' if session token is invalid
1451
+ */
1452
+ async switchOrganization(sessionToken, organizationId) {
1453
+ this.sessionCache.delete(sessionToken);
1454
+ const response = await fetch(
1455
+ `${this.http.baseUrl}/v1/apps/${this.appId}/auth/switch-organization`,
1456
+ {
1457
+ method: "POST",
1458
+ headers: {
1459
+ "Authorization": `Bearer ${sessionToken}`,
1460
+ "Content-Type": "application/json"
1461
+ },
1462
+ body: JSON.stringify({ organizationId })
1463
+ }
1464
+ );
1465
+ if (!response.ok) {
1466
+ const errorData = await response.json().catch(() => ({}));
1467
+ const message = errorData.message || errorData.error || "Failed to switch organization";
1468
+ let code = "SWITCH_ORG_FAILED";
1469
+ if (response.status === 401) {
1470
+ code = "SESSION_INVALID";
1471
+ } else if (message.toLowerCase().includes("not a member")) {
1472
+ code = "NOT_MEMBER";
1473
+ } else if (message.toLowerCase().includes("not found")) {
1474
+ code = "ORG_NOT_FOUND";
1475
+ }
1476
+ throw new StackBEError(message, response.status, code);
1477
+ }
1478
+ const data = await response.json();
1479
+ return data;
1480
+ }
1422
1481
  };
1423
1482
 
1424
1483
  // src/organizations.ts
@@ -1508,17 +1567,23 @@ var OrganizationsClient = class {
1508
1567
  );
1509
1568
  }
1510
1569
  /**
1511
- * Delete an organization.
1512
- * Note: Organizations with active subscriptions cannot be deleted.
1570
+ * Delete an organization (soft-delete).
1571
+ * By default, fails if org has active subscriptions.
1572
+ * Pass cancelSubscriptions: true to auto-cancel them first.
1513
1573
  *
1514
1574
  * @example
1515
1575
  * ```typescript
1576
+ * // Basic delete (fails if active subscriptions)
1516
1577
  * await stackbe.organizations.delete('org_123');
1578
+ *
1579
+ * // Force delete with subscription cancellation
1580
+ * await stackbe.organizations.delete('org_123', { cancelSubscriptions: true });
1517
1581
  * ```
1518
1582
  */
1519
- async delete(orgId) {
1583
+ async delete(orgId, options) {
1584
+ const query = options?.cancelSubscriptions ? "?cancelSubscriptions=true" : "";
1520
1585
  return this.http.delete(
1521
- `/v1/apps/${this.appId}/admin/organizations/${orgId}`
1586
+ `/v1/apps/${this.appId}/admin/organizations/${orgId}${query}`
1522
1587
  );
1523
1588
  }
1524
1589
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackbe/sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Official JavaScript/TypeScript SDK for StackBE - the billing backend for your side project",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",