@stackbe/sdk 0.1.0 → 0.3.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 +263 -77
- package/dist/index.d.mts +479 -10
- package/dist/index.d.ts +479 -10
- package/dist/index.js +538 -7
- package/dist/index.mjs +535 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ interface HttpClientConfig {
|
|
|
7
7
|
declare class HttpClient {
|
|
8
8
|
private config;
|
|
9
9
|
constructor(config: HttpClientConfig);
|
|
10
|
+
get baseUrl(): string;
|
|
10
11
|
private request;
|
|
11
12
|
get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T>;
|
|
12
13
|
post<T>(path: string, body?: unknown, params?: Record<string, string | number | undefined>): Promise<T>;
|
|
@@ -109,31 +110,216 @@ interface UpdateCustomerOptions {
|
|
|
109
110
|
name?: string;
|
|
110
111
|
metadata?: Record<string, unknown>;
|
|
111
112
|
}
|
|
113
|
+
interface MagicLinkOptions {
|
|
114
|
+
/** URL to redirect to after authentication */
|
|
115
|
+
redirectUrl?: string;
|
|
116
|
+
/** Use development callback URL (for localhost testing) */
|
|
117
|
+
useDev?: boolean;
|
|
118
|
+
}
|
|
112
119
|
interface MagicLinkResponse {
|
|
113
120
|
success: boolean;
|
|
114
121
|
message: string;
|
|
115
122
|
}
|
|
116
123
|
interface VerifyTokenResponse {
|
|
124
|
+
success: boolean;
|
|
117
125
|
valid: boolean;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
/** Customer ID */
|
|
127
|
+
customerId: string;
|
|
128
|
+
/** Customer email */
|
|
129
|
+
email: string;
|
|
130
|
+
/** Session JWT token - use this for subsequent authenticated requests */
|
|
131
|
+
sessionToken: string;
|
|
132
|
+
/** Tenant ID (your StackBE tenant) */
|
|
133
|
+
tenantId?: string;
|
|
134
|
+
/** Organization ID if in org context */
|
|
135
|
+
organizationId?: string;
|
|
136
|
+
/** Role in the organization */
|
|
137
|
+
orgRole?: 'owner' | 'admin' | 'member';
|
|
138
|
+
/** URL to redirect to after verification */
|
|
139
|
+
redirectUrl?: string;
|
|
121
140
|
}
|
|
122
141
|
interface SessionResponse {
|
|
123
|
-
|
|
142
|
+
valid: boolean;
|
|
143
|
+
/** Customer ID */
|
|
144
|
+
customerId: string;
|
|
145
|
+
/** Customer email */
|
|
146
|
+
email: string;
|
|
147
|
+
/** Session expiration time */
|
|
148
|
+
expiresAt?: string;
|
|
149
|
+
/** Tenant ID (your StackBE tenant) */
|
|
150
|
+
tenantId?: string;
|
|
151
|
+
/** Organization ID if in org context */
|
|
152
|
+
organizationId?: string;
|
|
153
|
+
/** Role in the organization */
|
|
154
|
+
orgRole?: 'owner' | 'admin' | 'member';
|
|
155
|
+
/** Customer details (if included) */
|
|
156
|
+
customer?: Customer;
|
|
157
|
+
/** Current subscription (if any) */
|
|
124
158
|
subscription?: Subscription;
|
|
125
|
-
|
|
159
|
+
/** Feature entitlements */
|
|
160
|
+
entitlements?: Record<string, boolean | number | string>;
|
|
161
|
+
}
|
|
162
|
+
interface CreateCheckoutOptions {
|
|
163
|
+
/** Customer ID or email */
|
|
164
|
+
customer: string | {
|
|
165
|
+
email: string;
|
|
166
|
+
name?: string;
|
|
167
|
+
};
|
|
168
|
+
/** Plan ID to subscribe to */
|
|
169
|
+
planId: string;
|
|
170
|
+
/** URL to redirect after successful checkout */
|
|
171
|
+
successUrl: string;
|
|
172
|
+
/** URL to redirect if checkout is canceled */
|
|
173
|
+
cancelUrl?: string;
|
|
174
|
+
/** Allow promotion codes */
|
|
175
|
+
allowPromotionCodes?: boolean;
|
|
176
|
+
/** Trial period in days */
|
|
177
|
+
trialDays?: number;
|
|
178
|
+
/** Metadata to attach to the subscription */
|
|
179
|
+
metadata?: Record<string, string>;
|
|
180
|
+
}
|
|
181
|
+
interface CheckoutSessionResponse {
|
|
182
|
+
/** Checkout session ID */
|
|
183
|
+
id: string;
|
|
184
|
+
/** URL to redirect customer to for checkout */
|
|
185
|
+
url: string;
|
|
186
|
+
/** Session status */
|
|
187
|
+
status: 'open' | 'complete' | 'expired';
|
|
188
|
+
/** Customer ID */
|
|
189
|
+
customerId: string;
|
|
190
|
+
/** Expiration time */
|
|
191
|
+
expiresAt: string;
|
|
192
|
+
}
|
|
193
|
+
interface SubscriptionWithPlan extends Subscription {
|
|
194
|
+
plan: {
|
|
195
|
+
id: string;
|
|
196
|
+
name: string;
|
|
197
|
+
price: number;
|
|
198
|
+
interval: 'month' | 'year';
|
|
199
|
+
currency: string;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
interface CancelSubscriptionOptions {
|
|
203
|
+
/** Cancel immediately or at end of billing period */
|
|
204
|
+
immediate?: boolean;
|
|
205
|
+
/** Reason for cancellation */
|
|
206
|
+
reason?: string;
|
|
207
|
+
}
|
|
208
|
+
interface CancelSubscriptionResponse {
|
|
209
|
+
success: boolean;
|
|
210
|
+
subscription: Subscription;
|
|
211
|
+
/** When the subscription will actually end */
|
|
212
|
+
endsAt: string;
|
|
213
|
+
}
|
|
214
|
+
interface UpdateSubscriptionOptions {
|
|
215
|
+
/** New plan ID to switch to */
|
|
216
|
+
planId?: string;
|
|
217
|
+
/** Proration behavior */
|
|
218
|
+
prorate?: boolean;
|
|
126
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Error codes returned by StackBE API.
|
|
222
|
+
* Use these to handle specific error cases in your application.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* try {
|
|
227
|
+
* await stackbe.auth.verifyToken(token);
|
|
228
|
+
* } catch (error) {
|
|
229
|
+
* if (error instanceof StackBEError) {
|
|
230
|
+
* switch (error.code) {
|
|
231
|
+
* case 'TOKEN_EXPIRED':
|
|
232
|
+
* return res.redirect('/login?error=expired');
|
|
233
|
+
* case 'TOKEN_ALREADY_USED':
|
|
234
|
+
* return res.redirect('/login?error=used');
|
|
235
|
+
* case 'SESSION_EXPIRED':
|
|
236
|
+
* return res.redirect('/login');
|
|
237
|
+
* default:
|
|
238
|
+
* return res.status(500).json({ error: 'Authentication failed' });
|
|
239
|
+
* }
|
|
240
|
+
* }
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
type StackBEErrorCode = 'TOKEN_EXPIRED' | 'TOKEN_ALREADY_USED' | 'TOKEN_INVALID' | 'SESSION_EXPIRED' | 'SESSION_INVALID' | 'UNAUTHORIZED' | 'NOT_FOUND' | 'CUSTOMER_NOT_FOUND' | 'SUBSCRIPTION_NOT_FOUND' | 'PLAN_NOT_FOUND' | 'APP_NOT_FOUND' | 'VALIDATION_ERROR' | 'MISSING_REQUIRED_FIELD' | 'INVALID_EMAIL' | 'USAGE_LIMIT_EXCEEDED' | 'METRIC_NOT_FOUND' | 'FEATURE_NOT_AVAILABLE' | 'NO_ACTIVE_SUBSCRIPTION' | 'TIMEOUT' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
127
245
|
interface StackBEErrorResponse {
|
|
128
246
|
statusCode: number;
|
|
129
247
|
message: string;
|
|
130
248
|
error: string;
|
|
249
|
+
code?: StackBEErrorCode;
|
|
131
250
|
}
|
|
132
251
|
declare class StackBEError extends Error {
|
|
133
252
|
readonly statusCode: number;
|
|
134
|
-
readonly code:
|
|
135
|
-
constructor(message: string, statusCode: number, code: string);
|
|
253
|
+
readonly code: StackBEErrorCode;
|
|
254
|
+
constructor(message: string, statusCode: number, code: StackBEErrorCode | string);
|
|
255
|
+
/** Check if this is a specific error type */
|
|
256
|
+
is(code: StackBEErrorCode): boolean;
|
|
257
|
+
/** Check if this is an auth-related error */
|
|
258
|
+
isAuthError(): boolean;
|
|
259
|
+
/** Check if this is a "not found" error */
|
|
260
|
+
isNotFoundError(): boolean;
|
|
136
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Webhook event types emitted by StackBE.
|
|
264
|
+
* Subscribe to these events to react to changes in your customers' subscriptions.
|
|
265
|
+
*/
|
|
266
|
+
type WebhookEventType = 'subscription_created' | 'subscription_updated' | 'subscription_cancelled' | 'subscription_renewed' | 'trial_started' | 'trial_ended' | 'payment_succeeded' | 'payment_failed' | 'customer_created' | 'customer_updated';
|
|
267
|
+
/** Base webhook event structure */
|
|
268
|
+
interface WebhookEvent<T extends WebhookEventType = WebhookEventType, P = unknown> {
|
|
269
|
+
/** Event ID */
|
|
270
|
+
id: string;
|
|
271
|
+
/** Event type */
|
|
272
|
+
type: T;
|
|
273
|
+
/** Tenant ID */
|
|
274
|
+
tenantId: string;
|
|
275
|
+
/** App ID */
|
|
276
|
+
appId: string;
|
|
277
|
+
/** Event payload */
|
|
278
|
+
data: P;
|
|
279
|
+
/** When the event was created */
|
|
280
|
+
createdAt: string;
|
|
281
|
+
}
|
|
282
|
+
/** Subscription webhook payload */
|
|
283
|
+
interface SubscriptionWebhookPayload {
|
|
284
|
+
id: string;
|
|
285
|
+
customerId: string;
|
|
286
|
+
planId: string;
|
|
287
|
+
planName: string;
|
|
288
|
+
status: 'active' | 'canceled' | 'past_due' | 'trialing' | 'paused';
|
|
289
|
+
currentPeriodStart: string;
|
|
290
|
+
currentPeriodEnd: string;
|
|
291
|
+
cancelAtPeriodEnd: boolean;
|
|
292
|
+
trialEnd?: string;
|
|
293
|
+
}
|
|
294
|
+
/** Customer webhook payload */
|
|
295
|
+
interface CustomerWebhookPayload {
|
|
296
|
+
id: string;
|
|
297
|
+
email: string;
|
|
298
|
+
name?: string;
|
|
299
|
+
metadata?: Record<string, unknown>;
|
|
300
|
+
}
|
|
301
|
+
/** Payment webhook payload */
|
|
302
|
+
interface PaymentWebhookPayload {
|
|
303
|
+
id: string;
|
|
304
|
+
subscriptionId: string;
|
|
305
|
+
customerId: string;
|
|
306
|
+
amount: number;
|
|
307
|
+
currency: string;
|
|
308
|
+
status: 'succeeded' | 'failed';
|
|
309
|
+
failureReason?: string;
|
|
310
|
+
}
|
|
311
|
+
type SubscriptionCreatedEvent = WebhookEvent<'subscription_created', SubscriptionWebhookPayload>;
|
|
312
|
+
type SubscriptionUpdatedEvent = WebhookEvent<'subscription_updated', SubscriptionWebhookPayload>;
|
|
313
|
+
type SubscriptionCancelledEvent = WebhookEvent<'subscription_cancelled', SubscriptionWebhookPayload>;
|
|
314
|
+
type SubscriptionRenewedEvent = WebhookEvent<'subscription_renewed', SubscriptionWebhookPayload>;
|
|
315
|
+
type TrialStartedEvent = WebhookEvent<'trial_started', SubscriptionWebhookPayload>;
|
|
316
|
+
type TrialEndedEvent = WebhookEvent<'trial_ended', SubscriptionWebhookPayload>;
|
|
317
|
+
type PaymentSucceededEvent = WebhookEvent<'payment_succeeded', PaymentWebhookPayload>;
|
|
318
|
+
type PaymentFailedEvent = WebhookEvent<'payment_failed', PaymentWebhookPayload>;
|
|
319
|
+
type CustomerCreatedEvent = WebhookEvent<'customer_created', CustomerWebhookPayload>;
|
|
320
|
+
type CustomerUpdatedEvent = WebhookEvent<'customer_updated', CustomerWebhookPayload>;
|
|
321
|
+
/** Union of all webhook event types */
|
|
322
|
+
type AnyWebhookEvent = SubscriptionCreatedEvent | SubscriptionUpdatedEvent | SubscriptionCancelledEvent | SubscriptionRenewedEvent | TrialStartedEvent | TrialEndedEvent | PaymentSucceededEvent | PaymentFailedEvent | CustomerCreatedEvent | CustomerUpdatedEvent;
|
|
137
323
|
|
|
138
324
|
declare class UsageClient {
|
|
139
325
|
private http;
|
|
@@ -347,14 +533,287 @@ declare class CustomersClient {
|
|
|
347
533
|
getSession(token: string): Promise<SessionResponse>;
|
|
348
534
|
}
|
|
349
535
|
|
|
536
|
+
declare class CheckoutClient {
|
|
537
|
+
private http;
|
|
538
|
+
private appId;
|
|
539
|
+
constructor(http: HttpClient, appId: string);
|
|
540
|
+
/**
|
|
541
|
+
* Create a checkout session for a customer to subscribe to a plan.
|
|
542
|
+
* Returns a URL to redirect the customer to Stripe checkout.
|
|
543
|
+
*
|
|
544
|
+
* @example
|
|
545
|
+
* ```typescript
|
|
546
|
+
* // With existing customer ID
|
|
547
|
+
* const { url } = await stackbe.checkout.createSession({
|
|
548
|
+
* customer: 'cust_123',
|
|
549
|
+
* planId: 'plan_pro_monthly',
|
|
550
|
+
* successUrl: 'https://myapp.com/success',
|
|
551
|
+
* cancelUrl: 'https://myapp.com/pricing',
|
|
552
|
+
* });
|
|
553
|
+
*
|
|
554
|
+
* // Redirect to checkout
|
|
555
|
+
* res.redirect(url);
|
|
556
|
+
* ```
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```typescript
|
|
560
|
+
* // With new customer (will be created)
|
|
561
|
+
* const { url } = await stackbe.checkout.createSession({
|
|
562
|
+
* customer: { email: 'user@example.com', name: 'John' },
|
|
563
|
+
* planId: 'plan_pro_monthly',
|
|
564
|
+
* successUrl: 'https://myapp.com/success',
|
|
565
|
+
* trialDays: 14,
|
|
566
|
+
* });
|
|
567
|
+
* ```
|
|
568
|
+
*/
|
|
569
|
+
createSession(options: CreateCheckoutOptions): Promise<CheckoutSessionResponse>;
|
|
570
|
+
/**
|
|
571
|
+
* Get an existing checkout session by ID.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```typescript
|
|
575
|
+
* const session = await stackbe.checkout.getSession('cs_123');
|
|
576
|
+
* if (session.status === 'complete') {
|
|
577
|
+
* // Payment successful
|
|
578
|
+
* }
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
getSession(sessionId: string): Promise<CheckoutSessionResponse>;
|
|
582
|
+
/**
|
|
583
|
+
* Generate a checkout URL for a plan.
|
|
584
|
+
* Convenience method that creates a session and returns just the URL.
|
|
585
|
+
*
|
|
586
|
+
* @example
|
|
587
|
+
* ```typescript
|
|
588
|
+
* const checkoutUrl = await stackbe.checkout.getCheckoutUrl({
|
|
589
|
+
* customer: 'cust_123',
|
|
590
|
+
* planId: 'plan_pro_monthly',
|
|
591
|
+
* successUrl: 'https://myapp.com/success',
|
|
592
|
+
* });
|
|
593
|
+
*
|
|
594
|
+
* // Send to frontend
|
|
595
|
+
* res.json({ checkoutUrl });
|
|
596
|
+
* ```
|
|
597
|
+
*/
|
|
598
|
+
getCheckoutUrl(options: CreateCheckoutOptions): Promise<string>;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
declare class SubscriptionsClient {
|
|
602
|
+
private http;
|
|
603
|
+
constructor(http: HttpClient);
|
|
604
|
+
/**
|
|
605
|
+
* Get a customer's current active subscription.
|
|
606
|
+
*
|
|
607
|
+
* @example
|
|
608
|
+
* ```typescript
|
|
609
|
+
* const subscription = await stackbe.subscriptions.get('cust_123');
|
|
610
|
+
*
|
|
611
|
+
* if (subscription) {
|
|
612
|
+
* console.log(`Plan: ${subscription.plan.name}`);
|
|
613
|
+
* console.log(`Status: ${subscription.status}`);
|
|
614
|
+
* console.log(`Renews: ${subscription.currentPeriodEnd}`);
|
|
615
|
+
* } else {
|
|
616
|
+
* console.log('No active subscription');
|
|
617
|
+
* }
|
|
618
|
+
* ```
|
|
619
|
+
*/
|
|
620
|
+
get(customerId: string): Promise<SubscriptionWithPlan | null>;
|
|
621
|
+
/**
|
|
622
|
+
* Get a subscription by ID.
|
|
623
|
+
*
|
|
624
|
+
* @example
|
|
625
|
+
* ```typescript
|
|
626
|
+
* const subscription = await stackbe.subscriptions.getById('sub_123');
|
|
627
|
+
* ```
|
|
628
|
+
*/
|
|
629
|
+
getById(subscriptionId: string): Promise<SubscriptionWithPlan>;
|
|
630
|
+
/**
|
|
631
|
+
* List all subscriptions for a customer.
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```typescript
|
|
635
|
+
* const subscriptions = await stackbe.subscriptions.list('cust_123');
|
|
636
|
+
* ```
|
|
637
|
+
*/
|
|
638
|
+
list(customerId: string): Promise<Subscription[]>;
|
|
639
|
+
/**
|
|
640
|
+
* Cancel a subscription.
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```typescript
|
|
644
|
+
* // Cancel at end of billing period (default)
|
|
645
|
+
* await stackbe.subscriptions.cancel('sub_123');
|
|
646
|
+
*
|
|
647
|
+
* // Cancel immediately
|
|
648
|
+
* await stackbe.subscriptions.cancel('sub_123', { immediate: true });
|
|
649
|
+
*
|
|
650
|
+
* // Cancel with reason
|
|
651
|
+
* await stackbe.subscriptions.cancel('sub_123', {
|
|
652
|
+
* reason: 'Too expensive'
|
|
653
|
+
* });
|
|
654
|
+
* ```
|
|
655
|
+
*/
|
|
656
|
+
cancel(subscriptionId: string, options?: CancelSubscriptionOptions): Promise<CancelSubscriptionResponse>;
|
|
657
|
+
/**
|
|
658
|
+
* Update a subscription (change plan).
|
|
659
|
+
*
|
|
660
|
+
* @example
|
|
661
|
+
* ```typescript
|
|
662
|
+
* // Upgrade/downgrade to a different plan
|
|
663
|
+
* await stackbe.subscriptions.update('sub_123', {
|
|
664
|
+
* planId: 'plan_enterprise_monthly',
|
|
665
|
+
* prorate: true,
|
|
666
|
+
* });
|
|
667
|
+
* ```
|
|
668
|
+
*/
|
|
669
|
+
update(subscriptionId: string, options: UpdateSubscriptionOptions): Promise<Subscription>;
|
|
670
|
+
/**
|
|
671
|
+
* Reactivate a canceled subscription (before it ends).
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* ```typescript
|
|
675
|
+
* // Customer changed their mind
|
|
676
|
+
* await stackbe.subscriptions.reactivate('sub_123');
|
|
677
|
+
* ```
|
|
678
|
+
*/
|
|
679
|
+
reactivate(subscriptionId: string): Promise<Subscription>;
|
|
680
|
+
/**
|
|
681
|
+
* Check if a customer has an active subscription.
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* ```typescript
|
|
685
|
+
* const isActive = await stackbe.subscriptions.isActive('cust_123');
|
|
686
|
+
* if (!isActive) {
|
|
687
|
+
* return res.redirect('/pricing');
|
|
688
|
+
* }
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
isActive(customerId: string): Promise<boolean>;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
declare class AuthClient {
|
|
695
|
+
private http;
|
|
696
|
+
private appId;
|
|
697
|
+
constructor(http: HttpClient, appId: string);
|
|
698
|
+
/**
|
|
699
|
+
* Send a magic link email to a customer for passwordless authentication.
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* // Send magic link
|
|
704
|
+
* await stackbe.auth.sendMagicLink('user@example.com');
|
|
705
|
+
*
|
|
706
|
+
* // With redirect URL
|
|
707
|
+
* await stackbe.auth.sendMagicLink('user@example.com', {
|
|
708
|
+
* redirectUrl: 'https://myapp.com/dashboard',
|
|
709
|
+
* });
|
|
710
|
+
*
|
|
711
|
+
* // For localhost development
|
|
712
|
+
* await stackbe.auth.sendMagicLink('user@example.com', {
|
|
713
|
+
* useDev: true,
|
|
714
|
+
* });
|
|
715
|
+
* ```
|
|
716
|
+
*/
|
|
717
|
+
sendMagicLink(email: string, options?: MagicLinkOptions): Promise<MagicLinkResponse>;
|
|
718
|
+
/**
|
|
719
|
+
* Verify a magic link token and get a session token.
|
|
720
|
+
* Call this when the user clicks the magic link.
|
|
721
|
+
*
|
|
722
|
+
* Returns the session token along with tenant and organization context.
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```typescript
|
|
726
|
+
* // In your /verify route handler
|
|
727
|
+
* const { token } = req.query;
|
|
728
|
+
*
|
|
729
|
+
* try {
|
|
730
|
+
* const result = await stackbe.auth.verifyToken(token);
|
|
731
|
+
*
|
|
732
|
+
* // result includes: customerId, email, sessionToken, tenantId, organizationId
|
|
733
|
+
* res.cookie('session', result.sessionToken, { httpOnly: true });
|
|
734
|
+
* res.redirect('/dashboard');
|
|
735
|
+
* } catch (error) {
|
|
736
|
+
* if (error instanceof StackBEError) {
|
|
737
|
+
* if (error.code === 'TOKEN_EXPIRED') {
|
|
738
|
+
* res.redirect('/login?error=expired');
|
|
739
|
+
* } else if (error.code === 'TOKEN_ALREADY_USED') {
|
|
740
|
+
* res.redirect('/login?error=used');
|
|
741
|
+
* }
|
|
742
|
+
* }
|
|
743
|
+
* }
|
|
744
|
+
* ```
|
|
745
|
+
*/
|
|
746
|
+
verifyToken(token: string): Promise<VerifyTokenResponse>;
|
|
747
|
+
/**
|
|
748
|
+
* Get the current session for an authenticated customer.
|
|
749
|
+
* Use this to validate session tokens and get customer data.
|
|
750
|
+
*
|
|
751
|
+
* Returns session info including tenant and organization context extracted from the JWT.
|
|
752
|
+
*
|
|
753
|
+
* @example
|
|
754
|
+
* ```typescript
|
|
755
|
+
* // Validate session on each request
|
|
756
|
+
* const sessionToken = req.cookies.session;
|
|
757
|
+
*
|
|
758
|
+
* const session = await stackbe.auth.getSession(sessionToken);
|
|
759
|
+
*
|
|
760
|
+
* if (session) {
|
|
761
|
+
* console.log(session.customerId);
|
|
762
|
+
* console.log(session.tenantId); // Tenant context
|
|
763
|
+
* console.log(session.organizationId); // Org context (if applicable)
|
|
764
|
+
* console.log(session.subscription);
|
|
765
|
+
* console.log(session.entitlements);
|
|
766
|
+
* }
|
|
767
|
+
* ```
|
|
768
|
+
*/
|
|
769
|
+
getSession(sessionToken: string): Promise<SessionResponse | null>;
|
|
770
|
+
/**
|
|
771
|
+
* Create Express middleware that validates session tokens.
|
|
772
|
+
*
|
|
773
|
+
* @example
|
|
774
|
+
* ```typescript
|
|
775
|
+
* // Protect routes with authentication
|
|
776
|
+
* app.use('/dashboard', stackbe.auth.middleware({
|
|
777
|
+
* getToken: (req) => req.cookies.session,
|
|
778
|
+
* onUnauthenticated: (req, res) => res.redirect('/login'),
|
|
779
|
+
* }));
|
|
780
|
+
*
|
|
781
|
+
* app.get('/dashboard', (req, res) => {
|
|
782
|
+
* // req.customer is available
|
|
783
|
+
* res.json({ email: req.customer.email });
|
|
784
|
+
* });
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
middleware(options: {
|
|
788
|
+
getToken: (req: any) => string | undefined;
|
|
789
|
+
onUnauthenticated?: (req: any, res: any) => void;
|
|
790
|
+
}): (req: any, res: any, next: any) => Promise<any>;
|
|
791
|
+
/**
|
|
792
|
+
* Check if a session token is valid.
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* ```typescript
|
|
796
|
+
* const isValid = await stackbe.auth.isAuthenticated(sessionToken);
|
|
797
|
+
* ```
|
|
798
|
+
*/
|
|
799
|
+
isAuthenticated(sessionToken: string): Promise<boolean>;
|
|
800
|
+
}
|
|
801
|
+
|
|
350
802
|
declare class StackBE {
|
|
351
803
|
private http;
|
|
804
|
+
private appId;
|
|
352
805
|
/** Usage tracking and limits */
|
|
353
806
|
readonly usage: UsageClient;
|
|
354
807
|
/** Feature entitlements */
|
|
355
808
|
readonly entitlements: EntitlementsClient;
|
|
356
809
|
/** Customer management */
|
|
357
810
|
readonly customers: CustomersClient;
|
|
811
|
+
/** Checkout sessions for Stripe */
|
|
812
|
+
readonly checkout: CheckoutClient;
|
|
813
|
+
/** Subscription management */
|
|
814
|
+
readonly subscriptions: SubscriptionsClient;
|
|
815
|
+
/** Customer authentication (magic links) */
|
|
816
|
+
readonly auth: AuthClient;
|
|
358
817
|
/**
|
|
359
818
|
* Create a new StackBE client.
|
|
360
819
|
*
|
|
@@ -373,8 +832,18 @@ declare class StackBE {
|
|
|
373
832
|
* // Check entitlements
|
|
374
833
|
* const { hasAccess } = await stackbe.entitlements.check('customer_123', 'premium');
|
|
375
834
|
*
|
|
376
|
-
* //
|
|
377
|
-
* const
|
|
835
|
+
* // Create checkout session
|
|
836
|
+
* const { url } = await stackbe.checkout.createSession({
|
|
837
|
+
* customer: 'cust_123',
|
|
838
|
+
* planId: 'plan_pro',
|
|
839
|
+
* successUrl: 'https://myapp.com/success',
|
|
840
|
+
* });
|
|
841
|
+
*
|
|
842
|
+
* // Get subscription
|
|
843
|
+
* const subscription = await stackbe.subscriptions.get('cust_123');
|
|
844
|
+
*
|
|
845
|
+
* // Send magic link
|
|
846
|
+
* await stackbe.auth.sendMagicLink('user@example.com');
|
|
378
847
|
* ```
|
|
379
848
|
*/
|
|
380
849
|
constructor(config: StackBEConfig);
|
|
@@ -445,4 +914,4 @@ declare class StackBE {
|
|
|
445
914
|
}): (req: any, res: any, next: any) => Promise<any>;
|
|
446
915
|
}
|
|
447
916
|
|
|
448
|
-
export { type CheckEntitlementResponse, type CheckUsageResponse, type CreateCustomerOptions, type Customer, type CustomerUsageResponse, type CustomerWithSubscription, CustomersClient, EntitlementsClient, type EntitlementsResponse, type MagicLinkResponse, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorResponse, type Subscription, type TrackUsageOptions, type TrackUsageResponse, type UpdateCustomerOptions, UsageClient, type UsageMetric, type VerifyTokenResponse };
|
|
917
|
+
export { type AnyWebhookEvent, AuthClient, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type CreateCheckoutOptions, type CreateCustomerOptions, type Customer, type CustomerCreatedEvent, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, EntitlementsClient, type EntitlementsResponse, type MagicLinkOptions, type MagicLinkResponse, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialStartedEvent, type UpdateCustomerOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
|