@stackbe/sdk 0.1.0 → 0.2.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/dist/index.d.mts +339 -3
- package/dist/index.d.ts +339 -3
- package/dist/index.js +398 -2
- package/dist/index.mjs +395 -2
- package/package.json +1 -1
package/dist/index.d.mts
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,6 +110,12 @@ 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;
|
|
@@ -124,6 +131,64 @@ interface SessionResponse {
|
|
|
124
131
|
subscription?: Subscription;
|
|
125
132
|
entitlements: Record<string, boolean | number | string>;
|
|
126
133
|
}
|
|
134
|
+
interface CreateCheckoutOptions {
|
|
135
|
+
/** Customer ID or email */
|
|
136
|
+
customer: string | {
|
|
137
|
+
email: string;
|
|
138
|
+
name?: string;
|
|
139
|
+
};
|
|
140
|
+
/** Plan ID to subscribe to */
|
|
141
|
+
planId: string;
|
|
142
|
+
/** URL to redirect after successful checkout */
|
|
143
|
+
successUrl: string;
|
|
144
|
+
/** URL to redirect if checkout is canceled */
|
|
145
|
+
cancelUrl?: string;
|
|
146
|
+
/** Allow promotion codes */
|
|
147
|
+
allowPromotionCodes?: boolean;
|
|
148
|
+
/** Trial period in days */
|
|
149
|
+
trialDays?: number;
|
|
150
|
+
/** Metadata to attach to the subscription */
|
|
151
|
+
metadata?: Record<string, string>;
|
|
152
|
+
}
|
|
153
|
+
interface CheckoutSessionResponse {
|
|
154
|
+
/** Checkout session ID */
|
|
155
|
+
id: string;
|
|
156
|
+
/** URL to redirect customer to for checkout */
|
|
157
|
+
url: string;
|
|
158
|
+
/** Session status */
|
|
159
|
+
status: 'open' | 'complete' | 'expired';
|
|
160
|
+
/** Customer ID */
|
|
161
|
+
customerId: string;
|
|
162
|
+
/** Expiration time */
|
|
163
|
+
expiresAt: string;
|
|
164
|
+
}
|
|
165
|
+
interface SubscriptionWithPlan extends Subscription {
|
|
166
|
+
plan: {
|
|
167
|
+
id: string;
|
|
168
|
+
name: string;
|
|
169
|
+
price: number;
|
|
170
|
+
interval: 'month' | 'year';
|
|
171
|
+
currency: string;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
interface CancelSubscriptionOptions {
|
|
175
|
+
/** Cancel immediately or at end of billing period */
|
|
176
|
+
immediate?: boolean;
|
|
177
|
+
/** Reason for cancellation */
|
|
178
|
+
reason?: string;
|
|
179
|
+
}
|
|
180
|
+
interface CancelSubscriptionResponse {
|
|
181
|
+
success: boolean;
|
|
182
|
+
subscription: Subscription;
|
|
183
|
+
/** When the subscription will actually end */
|
|
184
|
+
endsAt: string;
|
|
185
|
+
}
|
|
186
|
+
interface UpdateSubscriptionOptions {
|
|
187
|
+
/** New plan ID to switch to */
|
|
188
|
+
planId?: string;
|
|
189
|
+
/** Proration behavior */
|
|
190
|
+
prorate?: boolean;
|
|
191
|
+
}
|
|
127
192
|
interface StackBEErrorResponse {
|
|
128
193
|
statusCode: number;
|
|
129
194
|
message: string;
|
|
@@ -347,14 +412,275 @@ declare class CustomersClient {
|
|
|
347
412
|
getSession(token: string): Promise<SessionResponse>;
|
|
348
413
|
}
|
|
349
414
|
|
|
415
|
+
declare class CheckoutClient {
|
|
416
|
+
private http;
|
|
417
|
+
private appId;
|
|
418
|
+
constructor(http: HttpClient, appId: string);
|
|
419
|
+
/**
|
|
420
|
+
* Create a checkout session for a customer to subscribe to a plan.
|
|
421
|
+
* Returns a URL to redirect the customer to Stripe checkout.
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* ```typescript
|
|
425
|
+
* // With existing customer ID
|
|
426
|
+
* const { url } = await stackbe.checkout.createSession({
|
|
427
|
+
* customer: 'cust_123',
|
|
428
|
+
* planId: 'plan_pro_monthly',
|
|
429
|
+
* successUrl: 'https://myapp.com/success',
|
|
430
|
+
* cancelUrl: 'https://myapp.com/pricing',
|
|
431
|
+
* });
|
|
432
|
+
*
|
|
433
|
+
* // Redirect to checkout
|
|
434
|
+
* res.redirect(url);
|
|
435
|
+
* ```
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```typescript
|
|
439
|
+
* // With new customer (will be created)
|
|
440
|
+
* const { url } = await stackbe.checkout.createSession({
|
|
441
|
+
* customer: { email: 'user@example.com', name: 'John' },
|
|
442
|
+
* planId: 'plan_pro_monthly',
|
|
443
|
+
* successUrl: 'https://myapp.com/success',
|
|
444
|
+
* trialDays: 14,
|
|
445
|
+
* });
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
createSession(options: CreateCheckoutOptions): Promise<CheckoutSessionResponse>;
|
|
449
|
+
/**
|
|
450
|
+
* Get an existing checkout session by ID.
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```typescript
|
|
454
|
+
* const session = await stackbe.checkout.getSession('cs_123');
|
|
455
|
+
* if (session.status === 'complete') {
|
|
456
|
+
* // Payment successful
|
|
457
|
+
* }
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
getSession(sessionId: string): Promise<CheckoutSessionResponse>;
|
|
461
|
+
/**
|
|
462
|
+
* Generate a checkout URL for a plan.
|
|
463
|
+
* Convenience method that creates a session and returns just the URL.
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* ```typescript
|
|
467
|
+
* const checkoutUrl = await stackbe.checkout.getCheckoutUrl({
|
|
468
|
+
* customer: 'cust_123',
|
|
469
|
+
* planId: 'plan_pro_monthly',
|
|
470
|
+
* successUrl: 'https://myapp.com/success',
|
|
471
|
+
* });
|
|
472
|
+
*
|
|
473
|
+
* // Send to frontend
|
|
474
|
+
* res.json({ checkoutUrl });
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
getCheckoutUrl(options: CreateCheckoutOptions): Promise<string>;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
declare class SubscriptionsClient {
|
|
481
|
+
private http;
|
|
482
|
+
constructor(http: HttpClient);
|
|
483
|
+
/**
|
|
484
|
+
* Get a customer's current active subscription.
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```typescript
|
|
488
|
+
* const subscription = await stackbe.subscriptions.get('cust_123');
|
|
489
|
+
*
|
|
490
|
+
* if (subscription) {
|
|
491
|
+
* console.log(`Plan: ${subscription.plan.name}`);
|
|
492
|
+
* console.log(`Status: ${subscription.status}`);
|
|
493
|
+
* console.log(`Renews: ${subscription.currentPeriodEnd}`);
|
|
494
|
+
* } else {
|
|
495
|
+
* console.log('No active subscription');
|
|
496
|
+
* }
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
get(customerId: string): Promise<SubscriptionWithPlan | null>;
|
|
500
|
+
/**
|
|
501
|
+
* Get a subscription by ID.
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* const subscription = await stackbe.subscriptions.getById('sub_123');
|
|
506
|
+
* ```
|
|
507
|
+
*/
|
|
508
|
+
getById(subscriptionId: string): Promise<SubscriptionWithPlan>;
|
|
509
|
+
/**
|
|
510
|
+
* List all subscriptions for a customer.
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```typescript
|
|
514
|
+
* const subscriptions = await stackbe.subscriptions.list('cust_123');
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
list(customerId: string): Promise<Subscription[]>;
|
|
518
|
+
/**
|
|
519
|
+
* Cancel a subscription.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```typescript
|
|
523
|
+
* // Cancel at end of billing period (default)
|
|
524
|
+
* await stackbe.subscriptions.cancel('sub_123');
|
|
525
|
+
*
|
|
526
|
+
* // Cancel immediately
|
|
527
|
+
* await stackbe.subscriptions.cancel('sub_123', { immediate: true });
|
|
528
|
+
*
|
|
529
|
+
* // Cancel with reason
|
|
530
|
+
* await stackbe.subscriptions.cancel('sub_123', {
|
|
531
|
+
* reason: 'Too expensive'
|
|
532
|
+
* });
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
cancel(subscriptionId: string, options?: CancelSubscriptionOptions): Promise<CancelSubscriptionResponse>;
|
|
536
|
+
/**
|
|
537
|
+
* Update a subscription (change plan).
|
|
538
|
+
*
|
|
539
|
+
* @example
|
|
540
|
+
* ```typescript
|
|
541
|
+
* // Upgrade/downgrade to a different plan
|
|
542
|
+
* await stackbe.subscriptions.update('sub_123', {
|
|
543
|
+
* planId: 'plan_enterprise_monthly',
|
|
544
|
+
* prorate: true,
|
|
545
|
+
* });
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
update(subscriptionId: string, options: UpdateSubscriptionOptions): Promise<Subscription>;
|
|
549
|
+
/**
|
|
550
|
+
* Reactivate a canceled subscription (before it ends).
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* ```typescript
|
|
554
|
+
* // Customer changed their mind
|
|
555
|
+
* await stackbe.subscriptions.reactivate('sub_123');
|
|
556
|
+
* ```
|
|
557
|
+
*/
|
|
558
|
+
reactivate(subscriptionId: string): Promise<Subscription>;
|
|
559
|
+
/**
|
|
560
|
+
* Check if a customer has an active subscription.
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* ```typescript
|
|
564
|
+
* const isActive = await stackbe.subscriptions.isActive('cust_123');
|
|
565
|
+
* if (!isActive) {
|
|
566
|
+
* return res.redirect('/pricing');
|
|
567
|
+
* }
|
|
568
|
+
* ```
|
|
569
|
+
*/
|
|
570
|
+
isActive(customerId: string): Promise<boolean>;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
declare class AuthClient {
|
|
574
|
+
private http;
|
|
575
|
+
private appId;
|
|
576
|
+
constructor(http: HttpClient, appId: string);
|
|
577
|
+
/**
|
|
578
|
+
* Send a magic link email to a customer for passwordless authentication.
|
|
579
|
+
*
|
|
580
|
+
* @example
|
|
581
|
+
* ```typescript
|
|
582
|
+
* // Send magic link
|
|
583
|
+
* await stackbe.auth.sendMagicLink('user@example.com');
|
|
584
|
+
*
|
|
585
|
+
* // With redirect URL
|
|
586
|
+
* await stackbe.auth.sendMagicLink('user@example.com', {
|
|
587
|
+
* redirectUrl: 'https://myapp.com/dashboard',
|
|
588
|
+
* });
|
|
589
|
+
*
|
|
590
|
+
* // For localhost development
|
|
591
|
+
* await stackbe.auth.sendMagicLink('user@example.com', {
|
|
592
|
+
* useDev: true,
|
|
593
|
+
* });
|
|
594
|
+
* ```
|
|
595
|
+
*/
|
|
596
|
+
sendMagicLink(email: string, options?: MagicLinkOptions): Promise<MagicLinkResponse>;
|
|
597
|
+
/**
|
|
598
|
+
* Verify a magic link token and get a session token.
|
|
599
|
+
* Call this when the user clicks the magic link.
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```typescript
|
|
603
|
+
* // In your /verify route handler
|
|
604
|
+
* const { token } = req.query;
|
|
605
|
+
*
|
|
606
|
+
* const result = await stackbe.auth.verifyToken(token);
|
|
607
|
+
*
|
|
608
|
+
* if (result.valid) {
|
|
609
|
+
* // Set session cookie
|
|
610
|
+
* res.cookie('session', result.token, { httpOnly: true });
|
|
611
|
+
* res.redirect('/dashboard');
|
|
612
|
+
* } else {
|
|
613
|
+
* res.redirect('/login?error=invalid_token');
|
|
614
|
+
* }
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
verifyToken(token: string): Promise<VerifyTokenResponse>;
|
|
618
|
+
/**
|
|
619
|
+
* Get the current session for an authenticated customer.
|
|
620
|
+
* Use this to validate session tokens and get customer data.
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```typescript
|
|
624
|
+
* // Validate session on each request
|
|
625
|
+
* const sessionToken = req.cookies.session;
|
|
626
|
+
*
|
|
627
|
+
* const session = await stackbe.auth.getSession(sessionToken);
|
|
628
|
+
*
|
|
629
|
+
* if (session) {
|
|
630
|
+
* req.customer = session.customer;
|
|
631
|
+
* req.subscription = session.subscription;
|
|
632
|
+
* req.entitlements = session.entitlements;
|
|
633
|
+
* }
|
|
634
|
+
* ```
|
|
635
|
+
*/
|
|
636
|
+
getSession(sessionToken: string): Promise<SessionResponse | null>;
|
|
637
|
+
/**
|
|
638
|
+
* Create Express middleware that validates session tokens.
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* ```typescript
|
|
642
|
+
* // Protect routes with authentication
|
|
643
|
+
* app.use('/dashboard', stackbe.auth.middleware({
|
|
644
|
+
* getToken: (req) => req.cookies.session,
|
|
645
|
+
* onUnauthenticated: (req, res) => res.redirect('/login'),
|
|
646
|
+
* }));
|
|
647
|
+
*
|
|
648
|
+
* app.get('/dashboard', (req, res) => {
|
|
649
|
+
* // req.customer is available
|
|
650
|
+
* res.json({ email: req.customer.email });
|
|
651
|
+
* });
|
|
652
|
+
* ```
|
|
653
|
+
*/
|
|
654
|
+
middleware(options: {
|
|
655
|
+
getToken: (req: any) => string | undefined;
|
|
656
|
+
onUnauthenticated?: (req: any, res: any) => void;
|
|
657
|
+
}): (req: any, res: any, next: any) => Promise<any>;
|
|
658
|
+
/**
|
|
659
|
+
* Check if a session token is valid.
|
|
660
|
+
*
|
|
661
|
+
* @example
|
|
662
|
+
* ```typescript
|
|
663
|
+
* const isValid = await stackbe.auth.isAuthenticated(sessionToken);
|
|
664
|
+
* ```
|
|
665
|
+
*/
|
|
666
|
+
isAuthenticated(sessionToken: string): Promise<boolean>;
|
|
667
|
+
}
|
|
668
|
+
|
|
350
669
|
declare class StackBE {
|
|
351
670
|
private http;
|
|
671
|
+
private appId;
|
|
352
672
|
/** Usage tracking and limits */
|
|
353
673
|
readonly usage: UsageClient;
|
|
354
674
|
/** Feature entitlements */
|
|
355
675
|
readonly entitlements: EntitlementsClient;
|
|
356
676
|
/** Customer management */
|
|
357
677
|
readonly customers: CustomersClient;
|
|
678
|
+
/** Checkout sessions for Stripe */
|
|
679
|
+
readonly checkout: CheckoutClient;
|
|
680
|
+
/** Subscription management */
|
|
681
|
+
readonly subscriptions: SubscriptionsClient;
|
|
682
|
+
/** Customer authentication (magic links) */
|
|
683
|
+
readonly auth: AuthClient;
|
|
358
684
|
/**
|
|
359
685
|
* Create a new StackBE client.
|
|
360
686
|
*
|
|
@@ -373,8 +699,18 @@ declare class StackBE {
|
|
|
373
699
|
* // Check entitlements
|
|
374
700
|
* const { hasAccess } = await stackbe.entitlements.check('customer_123', 'premium');
|
|
375
701
|
*
|
|
376
|
-
* //
|
|
377
|
-
* const
|
|
702
|
+
* // Create checkout session
|
|
703
|
+
* const { url } = await stackbe.checkout.createSession({
|
|
704
|
+
* customer: 'cust_123',
|
|
705
|
+
* planId: 'plan_pro',
|
|
706
|
+
* successUrl: 'https://myapp.com/success',
|
|
707
|
+
* });
|
|
708
|
+
*
|
|
709
|
+
* // Get subscription
|
|
710
|
+
* const subscription = await stackbe.subscriptions.get('cust_123');
|
|
711
|
+
*
|
|
712
|
+
* // Send magic link
|
|
713
|
+
* await stackbe.auth.sendMagicLink('user@example.com');
|
|
378
714
|
* ```
|
|
379
715
|
*/
|
|
380
716
|
constructor(config: StackBEConfig);
|
|
@@ -445,4 +781,4 @@ declare class StackBE {
|
|
|
445
781
|
}): (req: any, res: any, next: any) => Promise<any>;
|
|
446
782
|
}
|
|
447
783
|
|
|
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 };
|
|
784
|
+
export { AuthClient, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type CreateCheckoutOptions, type CreateCustomerOptions, type Customer, type CustomerUsageResponse, type CustomerWithSubscription, CustomersClient, EntitlementsClient, type EntitlementsResponse, type MagicLinkOptions, type MagicLinkResponse, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorResponse, type Subscription, type SubscriptionWithPlan, SubscriptionsClient, type TrackUsageOptions, type TrackUsageResponse, type UpdateCustomerOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type VerifyTokenResponse };
|