@solvapay/next 1.0.0-preview.8 → 1.0.1-preview.1

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.cts CHANGED
@@ -1,14 +1,14 @@
1
- import { NextResponse } from 'next/server';
2
- import { SolvaPay } from '@solvapay/server';
1
+ import { NextResponse, NextRequest } from 'next/server';
2
+ import * as _solvapay_server from '@solvapay/server';
3
+ import { AuthenticatedUser, SolvaPay } from '@solvapay/server';
4
+ import { AuthAdapter } from '@solvapay/auth';
3
5
 
4
6
  /**
5
- * SolvaPay Next.js SDK
7
+ * Purchase Cache Utilities
6
8
  *
7
- * Framework-specific helpers and utilities for Next.js API routes.
8
- * These utilities provide common patterns with built-in optimizations
9
- * like request deduplication and caching.
9
+ * Cache management functions for purchase data.
10
+ * Separated from index.ts to avoid circular dependencies.
10
11
  */
11
-
12
12
  /**
13
13
  * Request deduplication and caching options
14
14
  */
@@ -30,28 +30,443 @@ interface RequestDeduplicationOptions {
30
30
  cacheErrors?: boolean;
31
31
  }
32
32
  /**
33
- * Subscription check result
33
+ * Purchase check result
34
34
  */
35
- interface SubscriptionCheckResult {
35
+ interface PurchaseCheckResult {
36
36
  customerRef: string;
37
37
  email?: string;
38
38
  name?: string;
39
- subscriptions: Array<{
39
+ purchases: Array<{
40
40
  reference: string;
41
- planName?: string;
42
- agentName?: string;
41
+ productName?: string;
42
+ productReference?: string;
43
43
  status?: string;
44
44
  startDate?: string;
45
+ planSnapshot?: {
46
+ meterId?: string;
47
+ limit?: number;
48
+ freeUnits?: number;
49
+ };
50
+ usage?: {
51
+ used?: number;
52
+ overageUnits?: number;
53
+ overageCost?: number;
54
+ periodStart?: string;
55
+ periodEnd?: string;
56
+ };
45
57
  [key: string]: unknown;
46
58
  }>;
47
59
  }
48
60
  /**
49
- * Options for checking subscriptions
61
+ * Clear purchase cache for a specific user.
62
+ *
63
+ * Useful when you know purchase status has changed (e.g., after a successful
64
+ * checkout, purchase update, or cancellation). This forces the next
65
+ * `checkPurchase()` call to fetch fresh data from the backend.
66
+ *
67
+ * @param userId - User ID to clear cache for
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * import { clearPurchaseCache } from '@solvapay/next';
72
+ *
73
+ * // After successful payment
74
+ * await processPayment(request, body);
75
+ * clearPurchaseCache(userId); // Force refresh on next check
76
+ * ```
77
+ *
78
+ * @see {@link checkPurchase} for purchase checking
79
+ * @see {@link clearAllPurchaseCache} to clear all cache entries
80
+ * @since 1.0.0
81
+ */
82
+ declare function clearPurchaseCache(userId: string): void;
83
+ /**
84
+ * Clear all purchase cache entries.
85
+ *
86
+ * Useful for testing, debugging, or when you need to force fresh lookups
87
+ * for all users. This clears both the in-flight request cache and the
88
+ * result cache.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { clearAllPurchaseCache } from '@solvapay/next';
93
+ *
94
+ * // In a test setup
95
+ * beforeEach(() => {
96
+ * clearAllPurchaseCache();
97
+ * });
98
+ * ```
99
+ *
100
+ * @see {@link clearPurchaseCache} to clear cache for a specific user
101
+ * @see {@link getPurchaseCacheStats} for cache monitoring
102
+ * @since 1.0.0
103
+ */
104
+ declare function clearAllPurchaseCache(): void;
105
+ /**
106
+ * Get purchase cache statistics for monitoring and debugging.
107
+ *
108
+ * Returns the current state of the purchase cache, including:
109
+ * - Number of in-flight requests (being deduplicated)
110
+ * - Number of cached results
111
+ *
112
+ * @returns Cache statistics object
113
+ * @returns inFlight - Number of currently in-flight requests
114
+ * @returns cached - Number of cached results
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * import { getPurchaseCacheStats } from '@solvapay/next';
119
+ *
120
+ * // In a monitoring endpoint
121
+ * export async function GET() {
122
+ * const stats = getPurchaseCacheStats();
123
+ * return Response.json({
124
+ * cache: {
125
+ * inFlight: stats.inFlight,
126
+ * cached: stats.cached
127
+ * }
128
+ * });
129
+ * }
130
+ * ```
131
+ *
132
+ * @see {@link checkPurchase} for purchase checking
133
+ * @since 1.0.0
134
+ */
135
+ declare function getPurchaseCacheStats(): {
136
+ inFlight: number;
137
+ cached: number;
138
+ };
139
+
140
+ /**
141
+ * Next.js Authentication Helpers
142
+ *
143
+ * Next.js-specific wrappers for authentication helpers.
144
+ */
145
+
146
+ /**
147
+ * Get authenticated user information from a Next.js request.
148
+ *
149
+ * This is a Next.js-specific wrapper around `getAuthenticatedUserCore` that
150
+ * returns NextResponse for errors instead of ErrorResult. Extracts user ID,
151
+ * email, and name from authenticated requests.
152
+ *
153
+ * @param request - Next.js request object (NextRequest or Request)
154
+ * @param options - Configuration options
155
+ * @param options.includeEmail - Whether to extract email from JWT token (default: true)
156
+ * @param options.includeName - Whether to extract name from JWT token (default: true)
157
+ * @returns Authenticated user info or NextResponse error
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * import { NextRequest, NextResponse } from 'next/server';
162
+ * import { getAuthenticatedUser } from '@solvapay/next';
163
+ *
164
+ * export async function GET(request: NextRequest) {
165
+ * const userResult = await getAuthenticatedUser(request);
166
+ *
167
+ * if (userResult instanceof NextResponse) {
168
+ * return userResult; // Error response
169
+ * }
170
+ *
171
+ * const { userId, email, name } = userResult;
172
+ * return NextResponse.json({ userId, email, name });
173
+ * }
174
+ * ```
175
+ *
176
+ * @see {@link getAuthenticatedUserCore} for the core implementation
177
+ * @since 1.0.0
178
+ */
179
+ declare function getAuthenticatedUser(request: globalThis.Request, options?: {
180
+ includeEmail?: boolean;
181
+ includeName?: boolean;
182
+ }): Promise<AuthenticatedUser | NextResponse>;
183
+
184
+ /**
185
+ * Next.js Customer Helpers
186
+ *
187
+ * Next.js-specific wrappers for customer helpers.
188
+ */
189
+
190
+ /**
191
+ * Sync customer - Next.js wrapper
192
+ *
193
+ * @param request - Next.js request object
194
+ * @param options - Configuration options
195
+ * @returns Customer reference or NextResponse error
196
+ */
197
+ declare function syncCustomer(request: globalThis.Request, options?: {
198
+ solvaPay?: SolvaPay;
199
+ includeEmail?: boolean;
200
+ includeName?: boolean;
201
+ }): Promise<string | NextResponse>;
202
+
203
+ declare function createPaymentIntent(request: globalThis.Request, body: {
204
+ planRef: string;
205
+ productRef: string;
206
+ }, options?: {
207
+ solvaPay?: SolvaPay;
208
+ includeEmail?: boolean;
209
+ includeName?: boolean;
210
+ }): Promise<{
211
+ id: string;
212
+ clientSecret: string;
213
+ publishableKey: string;
214
+ accountId?: string;
215
+ customerRef: string;
216
+ } | NextResponse>;
217
+ declare function processPaymentIntent(request: globalThis.Request, body: {
218
+ paymentIntentId: string;
219
+ productRef: string;
220
+ planRef?: string;
221
+ }, options?: {
222
+ solvaPay?: SolvaPay;
223
+ }): Promise<_solvapay_server.ProcessPaymentResult | NextResponse>;
224
+
225
+ /**
226
+ * Next.js Checkout Helpers
227
+ */
228
+
229
+ declare function createCheckoutSession(request: globalThis.Request, body: {
230
+ productRef: string;
231
+ planRef?: string;
232
+ returnUrl?: string;
233
+ }, options?: {
234
+ solvaPay?: SolvaPay;
235
+ includeEmail?: boolean;
236
+ includeName?: boolean;
237
+ returnUrl?: string;
238
+ }): Promise<{
239
+ sessionId: string;
240
+ checkoutUrl: string;
241
+ } | NextResponse>;
242
+ declare function createCustomerSession(request: globalThis.Request, options?: {
243
+ solvaPay?: SolvaPay;
244
+ includeEmail?: boolean;
245
+ includeName?: boolean;
246
+ }): Promise<{
247
+ sessionId: string;
248
+ customerUrl: string;
249
+ } | NextResponse>;
250
+
251
+ /**
252
+ * Next.js Purchase Cancellation Helpers
253
+ */
254
+ /**
255
+ * Cancel purchase - Next.js wrapper
256
+ *
257
+ * @param request - Next.js request object
258
+ * @param body - Cancellation parameters
259
+ * @param options - Configuration options
260
+ * @returns Cancelled purchase response or NextResponse error
261
+ */
262
+ declare function cancelRenewal(request: globalThis.Request, body: {
263
+ purchaseRef: string;
264
+ reason?: string;
265
+ }, options?: {
266
+ solvaPay?: SolvaPay;
267
+ }): Promise<Record<string, unknown> | NextResponse>;
268
+
269
+ /**
270
+ * Next.js Plans Helper
271
+ */
272
+ declare function listPlans(request: globalThis.Request): Promise<{
273
+ plans: Array<Record<string, unknown>>;
274
+ productRef: string;
275
+ } | NextResponse>;
276
+
277
+ /**
278
+ * Next.js Middleware Helpers
279
+ *
280
+ * Helpers for creating authentication middleware in Next.js.
281
+ * Works with any AuthAdapter implementation (Supabase, custom, etc.)
282
+ */
283
+
284
+ /**
285
+ * Configuration options for authentication middleware
286
+ */
287
+ interface AuthMiddlewareOptions {
288
+ /**
289
+ * Auth adapter instance to use for extracting user IDs from requests
290
+ * You can use SupabaseAuthAdapter, MockAuthAdapter, or create your own
291
+ */
292
+ adapter: AuthAdapter;
293
+ /**
294
+ * Public routes that don't require authentication
295
+ * Routes are matched using pathname.startsWith()
296
+ */
297
+ publicRoutes?: string[];
298
+ /**
299
+ * Header name to store the user ID (default: 'x-user-id')
300
+ */
301
+ userIdHeader?: string;
302
+ }
303
+ /**
304
+ * Creates a Next.js middleware function for authentication
305
+ *
306
+ * This helper:
307
+ * 1. Uses the provided AuthAdapter to extract userId from requests
308
+ * 2. Handles public vs protected routes
309
+ * 3. Adds userId to request headers for downstream routes
310
+ * 4. Returns appropriate error responses for auth failures
311
+ *
312
+ * @param options - Configuration options
313
+ * @returns Next.js middleware function (can be exported as `middleware` or `proxy`)
314
+ *
315
+ * @example Next.js 15
316
+ * ```typescript
317
+ * // middleware.ts (at project root)
318
+ * import { createAuthMiddleware } from '@solvapay/next';
319
+ * import { SupabaseAuthAdapter } from '@solvapay/auth/supabase';
320
+ *
321
+ * const adapter = new SupabaseAuthAdapter({
322
+ * jwtSecret: process.env.SUPABASE_JWT_SECRET!,
323
+ * });
324
+ *
325
+ * export const middleware = createAuthMiddleware({
326
+ * adapter,
327
+ * publicRoutes: ['/api/list-plans'],
328
+ * });
329
+ *
330
+ * export const config = {
331
+ * matcher: ['/api/:path*'],
332
+ * };
333
+ * ```
334
+ *
335
+ * @example Next.js 16 with src/ folder
336
+ * ```typescript
337
+ * // src/proxy.ts (in src/ folder, not project root)
338
+ * import { createAuthMiddleware } from '@solvapay/next';
339
+ * import { SupabaseAuthAdapter } from '@solvapay/auth/supabase';
340
+ *
341
+ * const adapter = new SupabaseAuthAdapter({
342
+ * jwtSecret: process.env.SUPABASE_JWT_SECRET!,
343
+ * });
344
+ *
345
+ * // Use 'proxy' export for Next.js 16 (no deprecation warning)
346
+ * export const proxy = createAuthMiddleware({
347
+ * adapter,
348
+ * publicRoutes: ['/api/list-plans'],
349
+ * });
350
+ *
351
+ * export const config = {
352
+ * matcher: ['/api/:path*'],
353
+ * };
354
+ * ```
355
+ *
356
+ * @example Custom adapter
357
+ * ```typescript
358
+ * import { createAuthMiddleware } from '@solvapay/next';
359
+ * import type { AuthAdapter } from '@solvapay/auth';
360
+ *
361
+ * const myAdapter: AuthAdapter = {
362
+ * async getUserIdFromRequest(req) {
363
+ * // Your custom auth logic
364
+ * return userId;
365
+ * },
366
+ * };
367
+ *
368
+ * export const middleware = createAuthMiddleware({
369
+ * adapter: myAdapter,
370
+ * });
371
+ * ```
372
+ *
373
+ * **File Location Notes:**
374
+ * - **Next.js 15**: Place `middleware.ts` at project root
375
+ * - **Next.js 16 without `src/` folder**: Place `middleware.ts` or `proxy.ts` at project root
376
+ * - **Next.js 16 with `src/` folder**: Place `src/proxy.ts` or `src/middleware.ts` (in `src/` folder, not root)
377
+ *
378
+ * **Note:** Next.js 16 renamed "middleware" to "proxy". You can export the return value as either
379
+ * `middleware` or `proxy` - both work, but `proxy` is recommended to avoid deprecation warnings.
380
+ */
381
+ declare function createAuthMiddleware(options: AuthMiddlewareOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;
382
+ /**
383
+ * Configuration options for Supabase authentication middleware
384
+ */
385
+ interface SupabaseAuthMiddlewareOptions {
386
+ /**
387
+ * Supabase JWT secret (from Supabase dashboard: Settings → API → JWT Secret)
388
+ * If not provided, will use SUPABASE_JWT_SECRET environment variable
389
+ */
390
+ jwtSecret?: string;
391
+ /**
392
+ * Public routes that don't require authentication
393
+ * Routes are matched using pathname.startsWith()
394
+ */
395
+ publicRoutes?: string[];
396
+ /**
397
+ * Header name to store the user ID (default: 'x-user-id')
398
+ */
399
+ userIdHeader?: string;
400
+ }
401
+ /**
402
+ * Creates a Next.js middleware function for Supabase authentication
403
+ *
404
+ * Convenience function that creates a SupabaseAuthAdapter and wraps it with createAuthMiddleware.
405
+ * Only use this if you're using Supabase - otherwise use createAuthMiddleware with your own adapter.
406
+ *
407
+ * Uses dynamic import to avoid requiring Supabase as a dependency in @solvapay/next.
408
+ *
409
+ * @param options - Configuration options
410
+ * @returns Next.js middleware function (can be exported as `middleware` or `proxy`)
411
+ *
412
+ * @example Next.js 15
413
+ * ```typescript
414
+ * // middleware.ts (at project root)
415
+ * import { createSupabaseAuthMiddleware } from '@solvapay/next';
416
+ *
417
+ * export const middleware = createSupabaseAuthMiddleware({
418
+ * publicRoutes: ['/api/list-plans'],
419
+ * });
420
+ *
421
+ * export const config = {
422
+ * matcher: ['/api/:path*'],
423
+ * };
424
+ * ```
425
+ *
426
+ * @example Next.js 16 with src/ folder
427
+ * ```typescript
428
+ * // src/proxy.ts (in src/ folder, not project root)
429
+ * import { createSupabaseAuthMiddleware } from '@solvapay/next';
430
+ *
431
+ * // Use 'proxy' export for Next.js 16 (no deprecation warning)
432
+ * export const proxy = createSupabaseAuthMiddleware({
433
+ * publicRoutes: ['/api/list-plans'],
434
+ * });
435
+ *
436
+ * export const config = {
437
+ * matcher: ['/api/:path*'],
438
+ * };
439
+ * ```
440
+ *
441
+ * **File Location Notes:**
442
+ * - **Next.js 15**: Place `middleware.ts` at project root
443
+ * - **Next.js 16 without `src/` folder**: Place `middleware.ts` or `proxy.ts` at project root
444
+ * - **Next.js 16 with `src/` folder**: Place `src/proxy.ts` or `src/middleware.ts` (in `src/` folder, not root)
445
+ *
446
+ * **Note:** Next.js 16 renamed "middleware" to "proxy". You can export the return value as either
447
+ * `middleware` or `proxy` - both work, but `proxy` is recommended to avoid deprecation warnings.
448
+ */
449
+ declare function createSupabaseAuthMiddleware(options?: SupabaseAuthMiddlewareOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;
450
+
451
+ /**
452
+ * SolvaPay Next.js SDK
453
+ *
454
+ * Framework-specific helpers and utilities for Next.js API routes.
455
+ * These utilities provide common patterns with built-in optimizations
456
+ * like request deduplication and caching.
457
+ */
458
+
459
+ /**
460
+ * Options for checking purchases
50
461
  */
51
- interface CheckSubscriptionOptions {
462
+ interface CheckPurchaseOptions {
52
463
  /**
53
464
  * Request deduplication options
54
- * Default: { cacheTTL: 2000, maxCacheSize: 1000, cacheErrors: true }
465
+ *
466
+ * Default values:
467
+ * - `cacheTTL`: 2000ms
468
+ * - `maxCacheSize`: 1000
469
+ * - `cacheErrors`: true
55
470
  */
56
471
  deduplication?: RequestDeduplicationOptions;
57
472
  /**
@@ -71,59 +486,49 @@ interface CheckSubscriptionOptions {
71
486
  includeName?: boolean;
72
487
  }
73
488
  /**
74
- * Check user subscription status
489
+ * Check user purchase status with automatic deduplication and caching.
490
+ *
491
+ * This Next.js helper function provides optimized purchase checking with:
492
+ * - Automatic request deduplication (concurrent requests share the same promise)
493
+ * - Short-term caching (2 seconds) to prevent duplicate sequential requests
494
+ * - Fast path optimization using cached customer references from client
495
+ * - Automatic customer creation if needed
75
496
  *
76
- * This helper function:
497
+ * The function:
77
498
  * 1. Extracts user ID from request (via requireUserId from @solvapay/auth)
78
- * 2. Gets user email and name from Supabase JWT token
79
- * 3. Ensures customer exists in SolvaPay
80
- * 4. Returns customer subscription information
81
- * 5. Handles deduplication automatically
499
+ * 2. Gets user email and name from Supabase JWT token (if available)
500
+ * 3. Validates cached customer reference (if provided via header)
501
+ * 4. Ensures customer exists in SolvaPay backend
502
+ * 5. Returns customer purchase information
82
503
  *
83
- * @param request - Next.js request object (NextRequest extends Request, so Request is accepted)
504
+ * @param request - Next.js request object (NextRequest extends Request)
84
505
  * @param options - Configuration options
85
- * @returns Subscription check result or error response
506
+ * @param options.deduplication - Request deduplication options (see {@link RequestDeduplicationOptions})
507
+ * @param options.solvaPay - Optional SolvaPay instance (creates new one if not provided)
508
+ * @param options.includeEmail - Whether to include email in response (default: true)
509
+ * @param options.includeName - Whether to include name in response (default: true)
510
+ * @returns Purchase check result with customer data and purchases, or NextResponse error
86
511
  *
87
512
  * @example
88
513
  * ```typescript
89
- * import { NextRequest } from 'next/server';
90
- * import { checkSubscription } from '@solvapay/next';
514
+ * import { NextRequest, NextResponse } from 'next/server';
515
+ * import { checkPurchase } from '@solvapay/next';
91
516
  *
92
517
  * export async function GET(request: NextRequest) {
93
- * const result = await checkSubscription(request);
518
+ * const result = await checkPurchase(request);
519
+ *
94
520
  * if (result instanceof NextResponse) {
95
521
  * return result; // Error response
96
522
  * }
523
+ *
97
524
  * return NextResponse.json(result);
98
525
  * }
99
526
  * ```
100
- */
101
- declare function checkSubscription(request: Request, options?: CheckSubscriptionOptions): Promise<SubscriptionCheckResult | NextResponse>;
102
- /**
103
- * Clear subscription cache for a specific user
104
527
  *
105
- * Useful when you know subscription status has changed
106
- * (e.g., after a successful checkout or subscription update)
107
- *
108
- * @param userId - User ID to clear cache for
109
- */
110
- declare function clearSubscriptionCache(userId: string): void;
111
- /**
112
- * Clear all subscription cache entries
113
- *
114
- * Useful for testing or when you need to force fresh lookups
115
- */
116
- declare function clearAllSubscriptionCache(): void;
117
- /**
118
- * Get subscription cache statistics
119
- *
120
- * Useful for monitoring and debugging
121
- *
122
- * @returns Cache statistics
528
+ * @see {@link clearPurchaseCache} for cache management
529
+ * @see {@link getPurchaseCacheStats} for cache monitoring
530
+ * @since 1.0.0
123
531
  */
124
- declare function getSubscriptionCacheStats(): {
125
- inFlight: number;
126
- cached: number;
127
- };
532
+ declare function checkPurchase(request: Request, options?: CheckPurchaseOptions): Promise<PurchaseCheckResult | NextResponse>;
128
533
 
129
- export { type CheckSubscriptionOptions, type RequestDeduplicationOptions, type SubscriptionCheckResult, checkSubscription, clearAllSubscriptionCache, clearSubscriptionCache, getSubscriptionCacheStats };
534
+ export { type AuthMiddlewareOptions, type CheckPurchaseOptions, type PurchaseCheckResult, type RequestDeduplicationOptions, type SupabaseAuthMiddlewareOptions, cancelRenewal, checkPurchase, clearAllPurchaseCache, clearPurchaseCache, createAuthMiddleware, createCheckoutSession, createCustomerSession, createPaymentIntent, createSupabaseAuthMiddleware, getAuthenticatedUser, getPurchaseCacheStats, listPlans, processPaymentIntent, syncCustomer };