@solvapay/next 1.0.0-preview.18 → 1.0.0-preview.20

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.cjs CHANGED
@@ -30,19 +30,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- cancelSubscription: () => cancelSubscription,
34
- checkSubscription: () => checkSubscription,
35
- clearAllSubscriptionCache: () => clearAllSubscriptionCache,
36
- clearSubscriptionCache: () => clearSubscriptionCache,
33
+ cancelRenewal: () => cancelRenewal,
34
+ checkPurchase: () => checkPurchase,
35
+ clearAllPurchaseCache: () => clearAllPurchaseCache,
36
+ clearPurchaseCache: () => clearPurchaseCache,
37
37
  createAuthMiddleware: () => createAuthMiddleware,
38
38
  createCheckoutSession: () => createCheckoutSession,
39
39
  createCustomerSession: () => createCustomerSession,
40
40
  createPaymentIntent: () => createPaymentIntent,
41
41
  createSupabaseAuthMiddleware: () => createSupabaseAuthMiddleware,
42
42
  getAuthenticatedUser: () => getAuthenticatedUser,
43
- getSubscriptionCacheStats: () => getSubscriptionCacheStats,
43
+ getPurchaseCacheStats: () => getPurchaseCacheStats,
44
44
  listPlans: () => listPlans,
45
- processPayment: () => processPayment,
45
+ processPaymentIntent: () => processPaymentIntent,
46
46
  syncCustomer: () => syncCustomer
47
47
  });
48
48
  module.exports = __toCommonJS(index_exports);
@@ -50,6 +50,136 @@ var import_server16 = require("next/server");
50
50
  var import_server17 = require("@solvapay/server");
51
51
  var import_core = require("@solvapay/core");
52
52
 
53
+ // src/cache.ts
54
+ function createRequestDeduplicator(options = {}) {
55
+ const { cacheTTL = 2e3, maxCacheSize = 1e3, cacheErrors = true } = options;
56
+ const inFlightRequests = /* @__PURE__ */ new Map();
57
+ const resultCache = /* @__PURE__ */ new Map();
58
+ const cacheInvalidatedAt = /* @__PURE__ */ new Map();
59
+ if (cacheTTL > 0) {
60
+ setInterval(
61
+ () => {
62
+ const now = Date.now();
63
+ const entriesToDelete = [];
64
+ for (const [key, cached] of resultCache.entries()) {
65
+ if (now - cached.timestamp >= cacheTTL) {
66
+ entriesToDelete.push(key);
67
+ }
68
+ }
69
+ for (const key of entriesToDelete) {
70
+ resultCache.delete(key);
71
+ cacheInvalidatedAt.delete(key);
72
+ }
73
+ if (resultCache.size > maxCacheSize) {
74
+ const sortedEntries = Array.from(resultCache.entries()).sort(
75
+ (a, b) => a[1].timestamp - b[1].timestamp
76
+ );
77
+ const toRemove = sortedEntries.slice(0, resultCache.size - maxCacheSize);
78
+ for (const [key] of toRemove) {
79
+ resultCache.delete(key);
80
+ cacheInvalidatedAt.delete(key);
81
+ }
82
+ }
83
+ },
84
+ Math.min(cacheTTL, 1e3)
85
+ );
86
+ }
87
+ const deduplicate = async (key, fn) => {
88
+ if (cacheTTL > 0) {
89
+ const cached = resultCache.get(key);
90
+ if (cached && Date.now() - cached.timestamp < cacheTTL) {
91
+ return cached.data;
92
+ } else if (cached) {
93
+ resultCache.delete(key);
94
+ }
95
+ }
96
+ let requestPromise = inFlightRequests.get(key);
97
+ if (!requestPromise) {
98
+ const requestStartTime = Date.now();
99
+ requestPromise = (async () => {
100
+ try {
101
+ const result = await fn();
102
+ const invalidatedAt = cacheInvalidatedAt.get(key);
103
+ const shouldCache = !invalidatedAt || invalidatedAt < requestStartTime;
104
+ if (cacheTTL > 0 && shouldCache) {
105
+ resultCache.set(key, {
106
+ data: result,
107
+ timestamp: Date.now()
108
+ });
109
+ }
110
+ return result;
111
+ } catch (error) {
112
+ const invalidatedAt = cacheInvalidatedAt.get(key);
113
+ const shouldCache = !invalidatedAt || invalidatedAt < requestStartTime;
114
+ if (cacheTTL > 0 && cacheErrors && shouldCache) {
115
+ resultCache.set(key, {
116
+ data: error,
117
+ timestamp: Date.now()
118
+ });
119
+ }
120
+ throw error;
121
+ } finally {
122
+ inFlightRequests.delete(key);
123
+ }
124
+ })();
125
+ const existingPromise = inFlightRequests.get(key);
126
+ if (existingPromise) {
127
+ requestPromise = existingPromise;
128
+ } else {
129
+ inFlightRequests.set(key, requestPromise);
130
+ }
131
+ }
132
+ return requestPromise;
133
+ };
134
+ const clearCache = (key) => {
135
+ resultCache.delete(key);
136
+ cacheInvalidatedAt.set(key, Date.now());
137
+ inFlightRequests.delete(key);
138
+ };
139
+ const clearAllCache = () => {
140
+ resultCache.clear();
141
+ cacheInvalidatedAt.clear();
142
+ inFlightRequests.clear();
143
+ };
144
+ const getStats = () => ({
145
+ inFlight: inFlightRequests.size,
146
+ cached: resultCache.size
147
+ });
148
+ return {
149
+ deduplicate,
150
+ clearCache,
151
+ clearAllCache,
152
+ getStats
153
+ };
154
+ }
155
+ var sharedPurchaseDeduplicator = null;
156
+ function getSharedDeduplicator(options) {
157
+ if (!sharedPurchaseDeduplicator) {
158
+ sharedPurchaseDeduplicator = createRequestDeduplicator({
159
+ cacheTTL: 2e3,
160
+ // Cache results for 2 seconds
161
+ maxCacheSize: 1e3,
162
+ // Maximum cache entries
163
+ cacheErrors: true,
164
+ // Cache error results too
165
+ ...options
166
+ });
167
+ }
168
+ return sharedPurchaseDeduplicator;
169
+ }
170
+ function clearPurchaseCache(userId) {
171
+ const deduplicator = getSharedDeduplicator();
172
+ deduplicator.clearCache(userId);
173
+ }
174
+ function clearAllPurchaseCache() {
175
+ const deduplicator = getSharedDeduplicator();
176
+ deduplicator.clearAllCache();
177
+ }
178
+ function getPurchaseCacheStats() {
179
+ const deduplicator = getSharedDeduplicator();
180
+ return deduplicator.getStats();
181
+ }
182
+
53
183
  // src/helpers/auth.ts
54
184
  var import_server = require("next/server");
55
185
  var import_server2 = require("@solvapay/server");
@@ -93,14 +223,14 @@ async function createPaymentIntent(request, body, options = {}) {
93
223
  try {
94
224
  const userResult = await (0, import_server7.getAuthenticatedUserCore)(request);
95
225
  if (!(0, import_server6.isErrorResult)(userResult)) {
96
- clearSubscriptionCache(userResult.userId);
226
+ clearPurchaseCache(userResult.userId);
97
227
  }
98
228
  } catch {
99
229
  }
100
230
  return result;
101
231
  }
102
- async function processPayment(request, body, options = {}) {
103
- const result = await (0, import_server6.processPaymentCore)(request, body, options);
232
+ async function processPaymentIntent(request, body, options = {}) {
233
+ const result = await (0, import_server6.processPaymentIntentCore)(request, body, options);
104
234
  if ((0, import_server6.isErrorResult)(result)) {
105
235
  return import_server5.NextResponse.json(
106
236
  { error: result.error, details: result.details },
@@ -110,7 +240,7 @@ async function processPayment(request, body, options = {}) {
110
240
  try {
111
241
  const userResult = await (0, import_server7.getAuthenticatedUserCore)(request);
112
242
  if (!(0, import_server6.isErrorResult)(userResult)) {
113
- clearSubscriptionCache(userResult.userId);
243
+ clearPurchaseCache(userResult.userId);
114
244
  }
115
245
  } catch {
116
246
  }
@@ -141,12 +271,12 @@ async function createCustomerSession(request, options = {}) {
141
271
  return result;
142
272
  }
143
273
 
144
- // src/helpers/subscription.ts
274
+ // src/helpers/renewal.ts
145
275
  var import_server10 = require("next/server");
146
276
  var import_server11 = require("@solvapay/server");
147
277
  var import_server12 = require("@solvapay/server");
148
- async function cancelSubscription(request, body, options = {}) {
149
- const result = await (0, import_server11.cancelSubscriptionCore)(request, body, options);
278
+ async function cancelRenewal(request, body, options = {}) {
279
+ const result = await (0, import_server11.cancelPurchaseCore)(request, body, options);
150
280
  if ((0, import_server11.isErrorResult)(result)) {
151
281
  return import_server10.NextResponse.json(
152
282
  { error: result.error, details: result.details },
@@ -156,7 +286,7 @@ async function cancelSubscription(request, body, options = {}) {
156
286
  try {
157
287
  const userResult = await (0, import_server12.getAuthenticatedUserCore)(request);
158
288
  if (!(0, import_server11.isErrorResult)(userResult)) {
159
- clearSubscriptionCache(userResult.userId);
289
+ clearPurchaseCache(userResult.userId);
160
290
  }
161
291
  } catch {
162
292
  }
@@ -180,20 +310,17 @@ async function listPlans(request) {
180
310
  // src/helpers/middleware.ts
181
311
  var import_server15 = require("next/server");
182
312
  function createAuthMiddleware(options) {
183
- const {
184
- adapter,
185
- publicRoutes = [],
186
- userIdHeader = "x-user-id"
187
- } = options;
313
+ const { adapter, publicRoutes = [], userIdHeader = "x-user-id" } = options;
188
314
  return async function middleware(request) {
189
- const { pathname } = request.nextUrl;
315
+ const req = request;
316
+ const { pathname } = req.nextUrl;
190
317
  if (!pathname.startsWith("/api")) {
191
318
  return import_server15.NextResponse.next();
192
319
  }
193
320
  const isPublicRoute = publicRoutes.some((route) => pathname.startsWith(route));
194
- const userId = await adapter.getUserIdFromRequest(request);
321
+ const userId = await adapter.getUserIdFromRequest(req);
195
322
  if (isPublicRoute) {
196
- const requestHeaders2 = new Headers(request.headers);
323
+ const requestHeaders2 = new Headers(req.headers);
197
324
  if (userId) {
198
325
  requestHeaders2.set(userIdHeader, userId);
199
326
  }
@@ -209,7 +336,7 @@ function createAuthMiddleware(options) {
209
336
  { status: 401 }
210
337
  );
211
338
  }
212
- const requestHeaders = new Headers(request.headers);
339
+ const requestHeaders = new Headers(req.headers);
213
340
  requestHeaders.set(userIdHeader, userId);
214
341
  return import_server15.NextResponse.next({
215
342
  request: {
@@ -219,11 +346,7 @@ function createAuthMiddleware(options) {
219
346
  };
220
347
  }
221
348
  function createSupabaseAuthMiddleware(options = {}) {
222
- const {
223
- jwtSecret,
224
- publicRoutes = [],
225
- userIdHeader = "x-user-id"
226
- } = options;
349
+ const { jwtSecret, publicRoutes = [], userIdHeader = "x-user-id" } = options;
227
350
  let authAdapter = null;
228
351
  let adapterPromise = null;
229
352
  const lazyAdapter = {
@@ -255,123 +378,7 @@ function createSupabaseAuthMiddleware(options = {}) {
255
378
  }
256
379
 
257
380
  // src/index.ts
258
- function createRequestDeduplicator(options = {}) {
259
- const {
260
- cacheTTL = 2e3,
261
- maxCacheSize = 1e3,
262
- cacheErrors = true
263
- } = options;
264
- const inFlightRequests = /* @__PURE__ */ new Map();
265
- const resultCache = /* @__PURE__ */ new Map();
266
- const cacheInvalidatedAt = /* @__PURE__ */ new Map();
267
- let cleanupInterval = null;
268
- if (cacheTTL > 0) {
269
- cleanupInterval = setInterval(() => {
270
- const now = Date.now();
271
- const entriesToDelete = [];
272
- for (const [key, cached] of resultCache.entries()) {
273
- if (now - cached.timestamp >= cacheTTL) {
274
- entriesToDelete.push(key);
275
- }
276
- }
277
- for (const key of entriesToDelete) {
278
- resultCache.delete(key);
279
- cacheInvalidatedAt.delete(key);
280
- }
281
- if (resultCache.size > maxCacheSize) {
282
- const sortedEntries = Array.from(resultCache.entries()).sort((a, b) => a[1].timestamp - b[1].timestamp);
283
- const toRemove = sortedEntries.slice(0, resultCache.size - maxCacheSize);
284
- for (const [key] of toRemove) {
285
- resultCache.delete(key);
286
- cacheInvalidatedAt.delete(key);
287
- }
288
- }
289
- }, Math.min(cacheTTL, 1e3));
290
- }
291
- const deduplicate = async (key, fn) => {
292
- if (cacheTTL > 0) {
293
- const cached = resultCache.get(key);
294
- if (cached && Date.now() - cached.timestamp < cacheTTL) {
295
- return cached.data;
296
- } else if (cached) {
297
- resultCache.delete(key);
298
- }
299
- }
300
- let requestPromise = inFlightRequests.get(key);
301
- if (!requestPromise) {
302
- const requestStartTime = Date.now();
303
- requestPromise = (async () => {
304
- try {
305
- const result = await fn();
306
- const invalidatedAt = cacheInvalidatedAt.get(key);
307
- const shouldCache = !invalidatedAt || invalidatedAt < requestStartTime;
308
- if (cacheTTL > 0 && shouldCache) {
309
- resultCache.set(key, {
310
- data: result,
311
- timestamp: Date.now()
312
- });
313
- }
314
- return result;
315
- } catch (error) {
316
- const invalidatedAt = cacheInvalidatedAt.get(key);
317
- const shouldCache = !invalidatedAt || invalidatedAt < requestStartTime;
318
- if (cacheTTL > 0 && cacheErrors && shouldCache) {
319
- resultCache.set(key, {
320
- data: error,
321
- timestamp: Date.now()
322
- });
323
- }
324
- throw error;
325
- } finally {
326
- inFlightRequests.delete(key);
327
- }
328
- })();
329
- const existingPromise = inFlightRequests.get(key);
330
- if (existingPromise) {
331
- requestPromise = existingPromise;
332
- } else {
333
- inFlightRequests.set(key, requestPromise);
334
- }
335
- }
336
- return requestPromise;
337
- };
338
- const clearCache = (key) => {
339
- resultCache.delete(key);
340
- cacheInvalidatedAt.set(key, Date.now());
341
- inFlightRequests.delete(key);
342
- };
343
- const clearAllCache = () => {
344
- resultCache.clear();
345
- cacheInvalidatedAt.clear();
346
- inFlightRequests.clear();
347
- };
348
- const getStats = () => ({
349
- inFlight: inFlightRequests.size,
350
- cached: resultCache.size
351
- });
352
- return {
353
- deduplicate,
354
- clearCache,
355
- clearAllCache,
356
- getStats
357
- };
358
- }
359
- var sharedSubscriptionDeduplicator = null;
360
- function getSharedDeduplicator(options) {
361
- if (!sharedSubscriptionDeduplicator) {
362
- sharedSubscriptionDeduplicator = createRequestDeduplicator({
363
- cacheTTL: 2e3,
364
- // Cache results for 2 seconds
365
- maxCacheSize: 1e3,
366
- // Maximum cache entries
367
- cacheErrors: true,
368
- // Cache error results too
369
- ...options
370
- });
371
- }
372
- return sharedSubscriptionDeduplicator;
373
- }
374
- async function checkSubscription(request, options = {}) {
381
+ async function checkPurchase(request, options = {}) {
375
382
  try {
376
383
  const { requireUserId, getUserEmailFromRequest, getUserNameFromRequest } = await import("@solvapay/auth");
377
384
  const userIdOrError = requireUserId(request);
@@ -390,18 +397,18 @@ async function checkSubscription(request, options = {}) {
390
397
  const customer = await solvaPay.getCustomer({ customerRef: cachedCustomerRef });
391
398
  if (customer && customer.customerRef) {
392
399
  if (customer.externalRef && customer.externalRef === userId) {
393
- const filteredSubscriptions = (customer.subscriptions || []).filter(
394
- (sub) => sub.status === "active"
400
+ const filteredPurchases = (customer.purchases || []).filter(
401
+ (p) => p.status === "active"
395
402
  );
396
403
  return {
397
404
  customerRef: customer.customerRef,
398
405
  email: customer.email,
399
406
  name: customer.name,
400
- subscriptions: filteredSubscriptions
407
+ purchases: filteredPurchases
401
408
  };
402
409
  }
403
410
  }
404
- } catch (error) {
411
+ } catch {
405
412
  }
406
413
  }
407
414
  const deduplicator = getSharedDeduplicator(options.deduplication);
@@ -412,66 +419,51 @@ async function checkSubscription(request, options = {}) {
412
419
  name: name || void 0
413
420
  });
414
421
  const customer = await solvaPay.getCustomer({ customerRef: ensuredCustomerRef });
415
- const filteredSubscriptions = (customer.subscriptions || []).filter(
416
- (sub) => sub.status === "active"
422
+ const filteredPurchases = (customer.purchases || []).filter(
423
+ (p) => p.status === "active"
417
424
  );
418
425
  const result = {
419
426
  customerRef: customer.customerRef || userId,
420
427
  email: customer.email,
421
428
  name: customer.name,
422
- subscriptions: filteredSubscriptions
429
+ purchases: filteredPurchases
423
430
  };
424
431
  return result;
425
432
  } catch (error) {
426
- console.error("[checkSubscription] Error fetching customer:", error);
433
+ console.error("[checkPurchase] Error fetching customer:", error);
427
434
  return {
428
435
  customerRef: userId,
429
- subscriptions: []
436
+ purchases: []
430
437
  };
431
438
  }
432
439
  });
433
440
  return response;
434
441
  } catch (error) {
435
- console.error("Check subscription failed:", error);
442
+ console.error("Check purchase failed:", error);
436
443
  if (error instanceof import_core.SolvaPayError) {
437
- return import_server16.NextResponse.json(
438
- { error: error.message },
439
- { status: 500 }
440
- );
444
+ return import_server16.NextResponse.json({ error: error.message }, { status: 500 });
441
445
  }
442
446
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
443
447
  return import_server16.NextResponse.json(
444
- { error: "Failed to check subscription", details: errorMessage },
448
+ { error: "Failed to check purchase", details: errorMessage },
445
449
  { status: 500 }
446
450
  );
447
451
  }
448
452
  }
449
- function clearSubscriptionCache(userId) {
450
- const deduplicator = getSharedDeduplicator();
451
- deduplicator.clearCache(userId);
452
- }
453
- function clearAllSubscriptionCache() {
454
- const deduplicator = getSharedDeduplicator();
455
- deduplicator.clearAllCache();
456
- }
457
- function getSubscriptionCacheStats() {
458
- const deduplicator = getSharedDeduplicator();
459
- return deduplicator.getStats();
460
- }
461
453
  // Annotate the CommonJS export names for ESM import in node:
462
454
  0 && (module.exports = {
463
- cancelSubscription,
464
- checkSubscription,
465
- clearAllSubscriptionCache,
466
- clearSubscriptionCache,
455
+ cancelRenewal,
456
+ checkPurchase,
457
+ clearAllPurchaseCache,
458
+ clearPurchaseCache,
467
459
  createAuthMiddleware,
468
460
  createCheckoutSession,
469
461
  createCustomerSession,
470
462
  createPaymentIntent,
471
463
  createSupabaseAuthMiddleware,
472
464
  getAuthenticatedUser,
473
- getSubscriptionCacheStats,
465
+ getPurchaseCacheStats,
474
466
  listPlans,
475
- processPayment,
467
+ processPaymentIntent,
476
468
  syncCustomer
477
469
  });