@betterstore/sdk 0.2.11 → 0.2.13

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @betterstore/sdk
2
2
 
3
+ ## 0.2.13
4
+
5
+ ### Patch Changes
6
+
7
+ - exporting all types
8
+
9
+ ## 0.2.12
10
+
11
+ ### Patch Changes
12
+
13
+ - proxies added back
14
+
3
15
  ## 0.2.11
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { NextRequest } from 'next/server';
2
+
1
3
  interface LineItem {
2
4
  quantity: number;
3
5
  productId?: string;
@@ -71,6 +73,7 @@ interface CheckoutSession {
71
73
  email?: string;
72
74
  };
73
75
  }
76
+
74
77
  declare class Checkout {
75
78
  private apiClient;
76
79
  constructor(apiKey: string);
@@ -125,26 +128,27 @@ interface CustomerUpdateParams {
125
128
  isSubscribedEmail?: boolean;
126
129
  isSubscribedSMS?: boolean;
127
130
  }
128
- interface Customer extends CustomerCreateParams {
131
+ interface Customer$1 extends CustomerCreateParams {
129
132
  id: string;
130
133
  createdAt: string;
131
134
  updatedAt: string;
132
135
  }
136
+
133
137
  declare class Customer {
134
138
  private apiClient;
135
139
  constructor(apiKey: string);
136
140
  /**
137
141
  * Create a new customer
138
142
  */
139
- create(params: CustomerCreateParams): Promise<Customer>;
143
+ create(params: CustomerCreateParams): Promise<Customer$1>;
140
144
  /**
141
145
  * Retrieve a customer by ID or email
142
146
  */
143
- retrieve(idOrEmail: string): Promise<Customer>;
147
+ retrieve(idOrEmail: string): Promise<Customer$1>;
144
148
  /**
145
149
  * Update a customer
146
150
  */
147
- update(customerId: string, params: CustomerUpdateParams): Promise<Customer>;
151
+ update(customerId: string, params: CustomerUpdateParams): Promise<Customer$1>;
148
152
  /**
149
153
  * Delete a customer
150
154
  */
@@ -194,6 +198,7 @@ interface Product {
194
198
  options: ProductOption[];
195
199
  productVariants: ProductVariant[];
196
200
  }
201
+
197
202
  declare class Products {
198
203
  private apiClient;
199
204
  constructor(apiKey: string);
@@ -201,10 +206,16 @@ declare class Products {
201
206
  retrieve(productId: string): Promise<Product>;
202
207
  }
203
208
 
204
- declare function getCheckoutEmbedProps(betterStore: BetterStore): {
205
- retrieveCheckout: InstanceType<typeof BetterStore>["checkout"]["retrieve"];
206
- updateCheckout: InstanceType<typeof BetterStore>["checkout"]["update"];
207
- getShippingRates: InstanceType<typeof BetterStore>["checkout"]["getShippingRates"];
209
+ type NextjsRouteConfig = {
210
+ apiKey?: string;
211
+ productionAllowedOrigins?: string[];
212
+ };
213
+ type BSClient = InstanceType<typeof BetterStore>;
214
+ declare function createNextJSHandler(betterStore: BSClient, config?: NextjsRouteConfig): {
215
+ GET(req: NextRequest): Promise<Response>;
216
+ POST(req: NextRequest): Promise<Response>;
217
+ PUT(req: NextRequest): Promise<Response>;
218
+ DELETE(req: NextRequest): Promise<Response>;
208
219
  };
209
220
 
210
221
  declare class BetterStore {
@@ -214,4 +225,4 @@ declare class BetterStore {
214
225
  constructor(apiKey: string);
215
226
  }
216
227
 
217
- export { BetterStore as default, getCheckoutEmbedProps };
228
+ export { type Address, type CheckoutCreateParams, type CheckoutSession, type CheckoutUpdateParams, type Customer$1 as Customer, type CustomerAddress, type CustomerCreateParams, type CustomerUpdateParams, type LineItem, type Product, type ProductOption, ProductStatus, type ProductVariant, type ShippingRate, type VariantOption, createNextJSHandler, BetterStore as default };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { NextRequest } from 'next/server';
2
+
1
3
  interface LineItem {
2
4
  quantity: number;
3
5
  productId?: string;
@@ -71,6 +73,7 @@ interface CheckoutSession {
71
73
  email?: string;
72
74
  };
73
75
  }
76
+
74
77
  declare class Checkout {
75
78
  private apiClient;
76
79
  constructor(apiKey: string);
@@ -125,26 +128,27 @@ interface CustomerUpdateParams {
125
128
  isSubscribedEmail?: boolean;
126
129
  isSubscribedSMS?: boolean;
127
130
  }
128
- interface Customer extends CustomerCreateParams {
131
+ interface Customer$1 extends CustomerCreateParams {
129
132
  id: string;
130
133
  createdAt: string;
131
134
  updatedAt: string;
132
135
  }
136
+
133
137
  declare class Customer {
134
138
  private apiClient;
135
139
  constructor(apiKey: string);
136
140
  /**
137
141
  * Create a new customer
138
142
  */
139
- create(params: CustomerCreateParams): Promise<Customer>;
143
+ create(params: CustomerCreateParams): Promise<Customer$1>;
140
144
  /**
141
145
  * Retrieve a customer by ID or email
142
146
  */
143
- retrieve(idOrEmail: string): Promise<Customer>;
147
+ retrieve(idOrEmail: string): Promise<Customer$1>;
144
148
  /**
145
149
  * Update a customer
146
150
  */
147
- update(customerId: string, params: CustomerUpdateParams): Promise<Customer>;
151
+ update(customerId: string, params: CustomerUpdateParams): Promise<Customer$1>;
148
152
  /**
149
153
  * Delete a customer
150
154
  */
@@ -194,6 +198,7 @@ interface Product {
194
198
  options: ProductOption[];
195
199
  productVariants: ProductVariant[];
196
200
  }
201
+
197
202
  declare class Products {
198
203
  private apiClient;
199
204
  constructor(apiKey: string);
@@ -201,10 +206,16 @@ declare class Products {
201
206
  retrieve(productId: string): Promise<Product>;
202
207
  }
203
208
 
204
- declare function getCheckoutEmbedProps(betterStore: BetterStore): {
205
- retrieveCheckout: InstanceType<typeof BetterStore>["checkout"]["retrieve"];
206
- updateCheckout: InstanceType<typeof BetterStore>["checkout"]["update"];
207
- getShippingRates: InstanceType<typeof BetterStore>["checkout"]["getShippingRates"];
209
+ type NextjsRouteConfig = {
210
+ apiKey?: string;
211
+ productionAllowedOrigins?: string[];
212
+ };
213
+ type BSClient = InstanceType<typeof BetterStore>;
214
+ declare function createNextJSHandler(betterStore: BSClient, config?: NextjsRouteConfig): {
215
+ GET(req: NextRequest): Promise<Response>;
216
+ POST(req: NextRequest): Promise<Response>;
217
+ PUT(req: NextRequest): Promise<Response>;
218
+ DELETE(req: NextRequest): Promise<Response>;
208
219
  };
209
220
 
210
221
  declare class BetterStore {
@@ -214,4 +225,4 @@ declare class BetterStore {
214
225
  constructor(apiKey: string);
215
226
  }
216
227
 
217
- export { BetterStore as default, getCheckoutEmbedProps };
228
+ export { type Address, type CheckoutCreateParams, type CheckoutSession, type CheckoutUpdateParams, type Customer$1 as Customer, type CustomerAddress, type CustomerCreateParams, type CustomerUpdateParams, type LineItem, type Product, type ProductOption, ProductStatus, type ProductVariant, type ShippingRate, type VariantOption, createNextJSHandler, BetterStore as default };
package/dist/index.js CHANGED
@@ -50,8 +50,9 @@ var __async = (__this, __arguments, generator) => {
50
50
  // src/index.ts
51
51
  var index_exports = {};
52
52
  __export(index_exports, {
53
- default: () => index_default,
54
- getCheckoutEmbedProps: () => getCheckoutEmbedProps
53
+ ProductStatus: () => ProductStatus,
54
+ createNextJSHandler: () => createNextJSHandler,
55
+ default: () => index_default
55
56
  });
56
57
  module.exports = __toCommonJS(index_exports);
57
58
 
@@ -99,7 +100,7 @@ var createApiClient = (apiKey) => {
99
100
  return client;
100
101
  };
101
102
 
102
- // src/checkout.ts
103
+ // src/checkout/index.ts
103
104
  var Checkout = class {
104
105
  constructor(apiKey) {
105
106
  this.apiClient = createApiClient(apiKey);
@@ -164,7 +165,7 @@ var Checkout = class {
164
165
  };
165
166
  var checkout_default = Checkout;
166
167
 
167
- // src/customer.ts
168
+ // src/customer/index.ts
168
169
  var Customer = class {
169
170
  constructor(apiKey) {
170
171
  this.apiClient = createApiClient(apiKey);
@@ -183,7 +184,9 @@ var Customer = class {
183
184
  */
184
185
  retrieve(idOrEmail) {
185
186
  return __async(this, null, function* () {
186
- const data = yield this.apiClient.get(`/customers/${idOrEmail}`);
187
+ const data = yield this.apiClient.get(
188
+ `/customers/${idOrEmail}`
189
+ );
187
190
  if (!data) {
188
191
  throw new Error("Customer not found");
189
192
  }
@@ -213,7 +216,7 @@ var Customer = class {
213
216
  };
214
217
  var customer_default = Customer;
215
218
 
216
- // src/products.ts
219
+ // src/products/index.ts
217
220
  var Products = class {
218
221
  constructor(apiKey) {
219
222
  this.apiClient = createApiClient(apiKey);
@@ -236,15 +239,312 @@ var Products = class {
236
239
  };
237
240
  var products_default = Products;
238
241
 
239
- // src/helpers/react.ts
240
- function getCheckoutEmbedProps(betterStore) {
242
+ // src/proxies/next-js.ts
243
+ var defaultBetterStoreRoutes = {
244
+ checkout: {
245
+ GET: (req, betterStore) => __async(void 0, null, function* () {
246
+ const { searchParams } = new URL(req.url);
247
+ const checkoutId = searchParams.get("checkoutId");
248
+ if (!checkoutId) {
249
+ return new Response("Checkout ID is required", { status: 400 });
250
+ }
251
+ try {
252
+ const checkout = yield betterStore.checkout.retrieve(checkoutId);
253
+ return Response.json(checkout);
254
+ } catch (error) {
255
+ return new Response("Failed to fetch checkout", { status: 500 });
256
+ }
257
+ }),
258
+ POST: (req, betterStore) => __async(void 0, null, function* () {
259
+ try {
260
+ const body = yield req.json();
261
+ const checkout = yield betterStore.checkout.create(body);
262
+ return Response.json(checkout);
263
+ } catch (error) {
264
+ return new Response("Failed to create checkout", { status: 500 });
265
+ }
266
+ }),
267
+ PUT: (req, betterStore) => __async(void 0, null, function* () {
268
+ const { searchParams } = new URL(req.url);
269
+ const checkoutId = searchParams.get("checkoutId");
270
+ if (!checkoutId) {
271
+ return new Response("Checkout ID is required", { status: 400 });
272
+ }
273
+ try {
274
+ const body = yield req.json();
275
+ const checkout = yield betterStore.checkout.update(checkoutId, body);
276
+ return Response.json(checkout);
277
+ } catch (error) {
278
+ return new Response("Failed to update checkout", { status: 500 });
279
+ }
280
+ })
281
+ },
282
+ "checkout/shipping": {
283
+ GET: (req, betterStore) => __async(void 0, null, function* () {
284
+ const { searchParams } = new URL(req.url);
285
+ const checkoutId = searchParams.get("checkoutId");
286
+ if (!checkoutId) {
287
+ return new Response("Checkout ID is required", { status: 400 });
288
+ }
289
+ try {
290
+ const rates = yield betterStore.checkout.getShippingRates(checkoutId);
291
+ return Response.json(rates);
292
+ } catch (error) {
293
+ return new Response("Failed to get shipping rates", { status: 500 });
294
+ }
295
+ })
296
+ },
297
+ "checkout/payment": {
298
+ POST: (req, betterStore) => __async(void 0, null, function* () {
299
+ const { searchParams } = new URL(req.url);
300
+ const checkoutId = searchParams.get("checkoutId");
301
+ if (!checkoutId) {
302
+ return new Response("Checkout ID is required", { status: 400 });
303
+ }
304
+ try {
305
+ const secret = yield betterStore.checkout.generatePaymentSecret(checkoutId);
306
+ return Response.json({ clientSecret: secret });
307
+ } catch (error) {
308
+ return new Response("Failed to generate payment secret", {
309
+ status: 500
310
+ });
311
+ }
312
+ })
313
+ },
314
+ customer: {
315
+ GET: (req, betterStore) => __async(void 0, null, function* () {
316
+ const { searchParams } = new URL(req.url);
317
+ const idOrEmail = searchParams.get("idOrEmail");
318
+ if (!idOrEmail) {
319
+ return new Response("Customer ID or email is required", {
320
+ status: 400
321
+ });
322
+ }
323
+ try {
324
+ const customer = yield betterStore.customer.retrieve(idOrEmail);
325
+ return Response.json(customer);
326
+ } catch (error) {
327
+ return new Response("Failed to fetch customer", { status: 500 });
328
+ }
329
+ }),
330
+ POST: (req, betterStore) => __async(void 0, null, function* () {
331
+ try {
332
+ const body = yield req.json();
333
+ const customer = yield betterStore.customer.create(body);
334
+ return Response.json(customer);
335
+ } catch (error) {
336
+ return new Response("Failed to create customer", { status: 500 });
337
+ }
338
+ }),
339
+ PUT: (req, betterStore) => __async(void 0, null, function* () {
340
+ const { searchParams } = new URL(req.url);
341
+ const customerId = searchParams.get("customerId");
342
+ if (!customerId) {
343
+ return new Response("Customer ID is required", { status: 400 });
344
+ }
345
+ try {
346
+ const body = yield req.json();
347
+ const customer = yield betterStore.customer.update(customerId, body);
348
+ return Response.json(customer);
349
+ } catch (error) {
350
+ return new Response("Failed to update customer", { status: 500 });
351
+ }
352
+ }),
353
+ DELETE: (req, betterStore) => __async(void 0, null, function* () {
354
+ const { searchParams } = new URL(req.url);
355
+ const customerId = searchParams.get("customerId");
356
+ if (!customerId) {
357
+ return new Response("Customer ID is required", { status: 400 });
358
+ }
359
+ try {
360
+ yield betterStore.customer.delete(customerId);
361
+ return new Response(null, { status: 204 });
362
+ } catch (error) {
363
+ return new Response("Failed to delete customer", { status: 500 });
364
+ }
365
+ })
366
+ },
367
+ product: {
368
+ GET: (req, betterStore) => __async(void 0, null, function* () {
369
+ const { searchParams } = new URL(req.url);
370
+ const productId = searchParams.get("productId");
371
+ try {
372
+ if (productId) {
373
+ const product = yield betterStore.products.retrieve(productId);
374
+ return Response.json(product);
375
+ } else {
376
+ const products = yield betterStore.products.list();
377
+ return Response.json(products);
378
+ }
379
+ } catch (error) {
380
+ return new Response("Failed to fetch products", { status: 500 });
381
+ }
382
+ })
383
+ }
384
+ };
385
+ function addCORSHeaders(response, origin, allowedOrigins) {
386
+ if (origin && allowedOrigins.includes(origin)) {
387
+ response.headers.set("Access-Control-Allow-Origin", origin);
388
+ }
389
+ response.headers.set(
390
+ "Access-Control-Allow-Methods",
391
+ "GET, POST, PUT, DELETE, OPTIONS"
392
+ );
393
+ response.headers.set(
394
+ "Access-Control-Allow-Headers",
395
+ "Content-Type, Authorization"
396
+ );
397
+ return response;
398
+ }
399
+ function createNextJSHandler(betterStore, config = {}) {
400
+ const { apiKey, productionAllowedOrigins = [] } = config;
401
+ const isProduction = process.env.NODE_ENV === "production";
402
+ function validateRequest(req) {
403
+ return __async(this, null, function* () {
404
+ if (apiKey) {
405
+ const authHeader = req.headers.get("Authorization");
406
+ const providedKey = authHeader == null ? void 0 : authHeader.replace("Bearer ", "");
407
+ if (!providedKey || providedKey !== apiKey) {
408
+ return new Response("Unauthorized", {
409
+ status: 401,
410
+ headers: { "WWW-Authenticate": "Bearer" }
411
+ });
412
+ }
413
+ }
414
+ const origin = req.headers.get("origin");
415
+ if (isProduction && productionAllowedOrigins.length > 0) {
416
+ if (!origin || !productionAllowedOrigins.includes(origin)) {
417
+ return new Response("Unauthorized", { status: 403 });
418
+ }
419
+ }
420
+ return null;
421
+ });
422
+ }
423
+ function getRouteFromPath(pathname) {
424
+ const cleanPath = pathname.replace(/^\/|\/$/g, "").replace(/^api\//, "");
425
+ const relevantPath = cleanPath.split("betterstore/")[1] || "";
426
+ return relevantPath;
427
+ }
241
428
  return {
242
- retrieveCheckout: betterStore.checkout.retrieve,
243
- updateCheckout: betterStore.checkout.update,
244
- getShippingRates: betterStore.checkout.getShippingRates
429
+ GET(req) {
430
+ return __async(this, null, function* () {
431
+ var _a2;
432
+ const validationError = yield validateRequest(req);
433
+ if (validationError)
434
+ return addCORSHeaders(
435
+ validationError,
436
+ req.headers.get("origin"),
437
+ productionAllowedOrigins
438
+ );
439
+ const route = getRouteFromPath(new URL(req.url).pathname);
440
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.GET;
441
+ if (!handler) {
442
+ return addCORSHeaders(
443
+ new Response(`Route not found: ${route}`, { status: 404 }),
444
+ req.headers.get("origin"),
445
+ productionAllowedOrigins
446
+ );
447
+ }
448
+ const response = yield handler(req, betterStore);
449
+ return addCORSHeaders(
450
+ response,
451
+ req.headers.get("origin"),
452
+ productionAllowedOrigins
453
+ );
454
+ });
455
+ },
456
+ POST(req) {
457
+ return __async(this, null, function* () {
458
+ var _a2;
459
+ const validationError = yield validateRequest(req);
460
+ if (validationError)
461
+ return addCORSHeaders(
462
+ validationError,
463
+ req.headers.get("origin"),
464
+ productionAllowedOrigins
465
+ );
466
+ const route = getRouteFromPath(new URL(req.url).pathname);
467
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.POST;
468
+ if (!handler) {
469
+ return addCORSHeaders(
470
+ new Response(`Route not found: ${route}`, { status: 404 }),
471
+ req.headers.get("origin"),
472
+ productionAllowedOrigins
473
+ );
474
+ }
475
+ const response = yield handler(req, betterStore);
476
+ return addCORSHeaders(
477
+ response,
478
+ req.headers.get("origin"),
479
+ productionAllowedOrigins
480
+ );
481
+ });
482
+ },
483
+ PUT(req) {
484
+ return __async(this, null, function* () {
485
+ var _a2;
486
+ const validationError = yield validateRequest(req);
487
+ if (validationError)
488
+ return addCORSHeaders(
489
+ validationError,
490
+ req.headers.get("origin"),
491
+ productionAllowedOrigins
492
+ );
493
+ const route = getRouteFromPath(new URL(req.url).pathname);
494
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.PUT;
495
+ if (!handler) {
496
+ return addCORSHeaders(
497
+ new Response(`Route not found: ${route}`, { status: 404 }),
498
+ req.headers.get("origin"),
499
+ productionAllowedOrigins
500
+ );
501
+ }
502
+ const response = yield handler(req, betterStore);
503
+ return addCORSHeaders(
504
+ response,
505
+ req.headers.get("origin"),
506
+ productionAllowedOrigins
507
+ );
508
+ });
509
+ },
510
+ DELETE(req) {
511
+ return __async(this, null, function* () {
512
+ var _a2;
513
+ const validationError = yield validateRequest(req);
514
+ if (validationError)
515
+ return addCORSHeaders(
516
+ validationError,
517
+ req.headers.get("origin"),
518
+ productionAllowedOrigins
519
+ );
520
+ const route = getRouteFromPath(new URL(req.url).pathname);
521
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.DELETE;
522
+ if (!handler) {
523
+ return addCORSHeaders(
524
+ new Response(`Route not found: ${route}`, { status: 404 }),
525
+ req.headers.get("origin"),
526
+ productionAllowedOrigins
527
+ );
528
+ }
529
+ const response = yield handler(req, betterStore);
530
+ return addCORSHeaders(
531
+ response,
532
+ req.headers.get("origin"),
533
+ productionAllowedOrigins
534
+ );
535
+ });
536
+ }
245
537
  };
246
538
  }
247
539
 
540
+ // src/products/types.ts
541
+ var ProductStatus = /* @__PURE__ */ ((ProductStatus2) => {
542
+ ProductStatus2["DRAFT"] = "DRAFT";
543
+ ProductStatus2["ACTIVE"] = "ACTIVE";
544
+ ProductStatus2["ARCHIVED"] = "ARCHIVED";
545
+ return ProductStatus2;
546
+ })(ProductStatus || {});
547
+
248
548
  // src/index.ts
249
549
  var BetterStore = class {
250
550
  // private apiKey: string;
@@ -260,5 +560,6 @@ var BetterStore = class {
260
560
  var index_default = BetterStore;
261
561
  // Annotate the CommonJS export names for ESM import in node:
262
562
  0 && (module.exports = {
263
- getCheckoutEmbedProps
563
+ ProductStatus,
564
+ createNextJSHandler
264
565
  });
package/dist/index.mjs CHANGED
@@ -63,7 +63,7 @@ var createApiClient = (apiKey) => {
63
63
  return client;
64
64
  };
65
65
 
66
- // src/checkout.ts
66
+ // src/checkout/index.ts
67
67
  var Checkout = class {
68
68
  constructor(apiKey) {
69
69
  this.apiClient = createApiClient(apiKey);
@@ -128,7 +128,7 @@ var Checkout = class {
128
128
  };
129
129
  var checkout_default = Checkout;
130
130
 
131
- // src/customer.ts
131
+ // src/customer/index.ts
132
132
  var Customer = class {
133
133
  constructor(apiKey) {
134
134
  this.apiClient = createApiClient(apiKey);
@@ -147,7 +147,9 @@ var Customer = class {
147
147
  */
148
148
  retrieve(idOrEmail) {
149
149
  return __async(this, null, function* () {
150
- const data = yield this.apiClient.get(`/customers/${idOrEmail}`);
150
+ const data = yield this.apiClient.get(
151
+ `/customers/${idOrEmail}`
152
+ );
151
153
  if (!data) {
152
154
  throw new Error("Customer not found");
153
155
  }
@@ -177,7 +179,7 @@ var Customer = class {
177
179
  };
178
180
  var customer_default = Customer;
179
181
 
180
- // src/products.ts
182
+ // src/products/index.ts
181
183
  var Products = class {
182
184
  constructor(apiKey) {
183
185
  this.apiClient = createApiClient(apiKey);
@@ -200,15 +202,312 @@ var Products = class {
200
202
  };
201
203
  var products_default = Products;
202
204
 
203
- // src/helpers/react.ts
204
- function getCheckoutEmbedProps(betterStore) {
205
+ // src/proxies/next-js.ts
206
+ var defaultBetterStoreRoutes = {
207
+ checkout: {
208
+ GET: (req, betterStore) => __async(void 0, null, function* () {
209
+ const { searchParams } = new URL(req.url);
210
+ const checkoutId = searchParams.get("checkoutId");
211
+ if (!checkoutId) {
212
+ return new Response("Checkout ID is required", { status: 400 });
213
+ }
214
+ try {
215
+ const checkout = yield betterStore.checkout.retrieve(checkoutId);
216
+ return Response.json(checkout);
217
+ } catch (error) {
218
+ return new Response("Failed to fetch checkout", { status: 500 });
219
+ }
220
+ }),
221
+ POST: (req, betterStore) => __async(void 0, null, function* () {
222
+ try {
223
+ const body = yield req.json();
224
+ const checkout = yield betterStore.checkout.create(body);
225
+ return Response.json(checkout);
226
+ } catch (error) {
227
+ return new Response("Failed to create checkout", { status: 500 });
228
+ }
229
+ }),
230
+ PUT: (req, betterStore) => __async(void 0, null, function* () {
231
+ const { searchParams } = new URL(req.url);
232
+ const checkoutId = searchParams.get("checkoutId");
233
+ if (!checkoutId) {
234
+ return new Response("Checkout ID is required", { status: 400 });
235
+ }
236
+ try {
237
+ const body = yield req.json();
238
+ const checkout = yield betterStore.checkout.update(checkoutId, body);
239
+ return Response.json(checkout);
240
+ } catch (error) {
241
+ return new Response("Failed to update checkout", { status: 500 });
242
+ }
243
+ })
244
+ },
245
+ "checkout/shipping": {
246
+ GET: (req, betterStore) => __async(void 0, null, function* () {
247
+ const { searchParams } = new URL(req.url);
248
+ const checkoutId = searchParams.get("checkoutId");
249
+ if (!checkoutId) {
250
+ return new Response("Checkout ID is required", { status: 400 });
251
+ }
252
+ try {
253
+ const rates = yield betterStore.checkout.getShippingRates(checkoutId);
254
+ return Response.json(rates);
255
+ } catch (error) {
256
+ return new Response("Failed to get shipping rates", { status: 500 });
257
+ }
258
+ })
259
+ },
260
+ "checkout/payment": {
261
+ POST: (req, betterStore) => __async(void 0, null, function* () {
262
+ const { searchParams } = new URL(req.url);
263
+ const checkoutId = searchParams.get("checkoutId");
264
+ if (!checkoutId) {
265
+ return new Response("Checkout ID is required", { status: 400 });
266
+ }
267
+ try {
268
+ const secret = yield betterStore.checkout.generatePaymentSecret(checkoutId);
269
+ return Response.json({ clientSecret: secret });
270
+ } catch (error) {
271
+ return new Response("Failed to generate payment secret", {
272
+ status: 500
273
+ });
274
+ }
275
+ })
276
+ },
277
+ customer: {
278
+ GET: (req, betterStore) => __async(void 0, null, function* () {
279
+ const { searchParams } = new URL(req.url);
280
+ const idOrEmail = searchParams.get("idOrEmail");
281
+ if (!idOrEmail) {
282
+ return new Response("Customer ID or email is required", {
283
+ status: 400
284
+ });
285
+ }
286
+ try {
287
+ const customer = yield betterStore.customer.retrieve(idOrEmail);
288
+ return Response.json(customer);
289
+ } catch (error) {
290
+ return new Response("Failed to fetch customer", { status: 500 });
291
+ }
292
+ }),
293
+ POST: (req, betterStore) => __async(void 0, null, function* () {
294
+ try {
295
+ const body = yield req.json();
296
+ const customer = yield betterStore.customer.create(body);
297
+ return Response.json(customer);
298
+ } catch (error) {
299
+ return new Response("Failed to create customer", { status: 500 });
300
+ }
301
+ }),
302
+ PUT: (req, betterStore) => __async(void 0, null, function* () {
303
+ const { searchParams } = new URL(req.url);
304
+ const customerId = searchParams.get("customerId");
305
+ if (!customerId) {
306
+ return new Response("Customer ID is required", { status: 400 });
307
+ }
308
+ try {
309
+ const body = yield req.json();
310
+ const customer = yield betterStore.customer.update(customerId, body);
311
+ return Response.json(customer);
312
+ } catch (error) {
313
+ return new Response("Failed to update customer", { status: 500 });
314
+ }
315
+ }),
316
+ DELETE: (req, betterStore) => __async(void 0, null, function* () {
317
+ const { searchParams } = new URL(req.url);
318
+ const customerId = searchParams.get("customerId");
319
+ if (!customerId) {
320
+ return new Response("Customer ID is required", { status: 400 });
321
+ }
322
+ try {
323
+ yield betterStore.customer.delete(customerId);
324
+ return new Response(null, { status: 204 });
325
+ } catch (error) {
326
+ return new Response("Failed to delete customer", { status: 500 });
327
+ }
328
+ })
329
+ },
330
+ product: {
331
+ GET: (req, betterStore) => __async(void 0, null, function* () {
332
+ const { searchParams } = new URL(req.url);
333
+ const productId = searchParams.get("productId");
334
+ try {
335
+ if (productId) {
336
+ const product = yield betterStore.products.retrieve(productId);
337
+ return Response.json(product);
338
+ } else {
339
+ const products = yield betterStore.products.list();
340
+ return Response.json(products);
341
+ }
342
+ } catch (error) {
343
+ return new Response("Failed to fetch products", { status: 500 });
344
+ }
345
+ })
346
+ }
347
+ };
348
+ function addCORSHeaders(response, origin, allowedOrigins) {
349
+ if (origin && allowedOrigins.includes(origin)) {
350
+ response.headers.set("Access-Control-Allow-Origin", origin);
351
+ }
352
+ response.headers.set(
353
+ "Access-Control-Allow-Methods",
354
+ "GET, POST, PUT, DELETE, OPTIONS"
355
+ );
356
+ response.headers.set(
357
+ "Access-Control-Allow-Headers",
358
+ "Content-Type, Authorization"
359
+ );
360
+ return response;
361
+ }
362
+ function createNextJSHandler(betterStore, config = {}) {
363
+ const { apiKey, productionAllowedOrigins = [] } = config;
364
+ const isProduction = process.env.NODE_ENV === "production";
365
+ function validateRequest(req) {
366
+ return __async(this, null, function* () {
367
+ if (apiKey) {
368
+ const authHeader = req.headers.get("Authorization");
369
+ const providedKey = authHeader == null ? void 0 : authHeader.replace("Bearer ", "");
370
+ if (!providedKey || providedKey !== apiKey) {
371
+ return new Response("Unauthorized", {
372
+ status: 401,
373
+ headers: { "WWW-Authenticate": "Bearer" }
374
+ });
375
+ }
376
+ }
377
+ const origin = req.headers.get("origin");
378
+ if (isProduction && productionAllowedOrigins.length > 0) {
379
+ if (!origin || !productionAllowedOrigins.includes(origin)) {
380
+ return new Response("Unauthorized", { status: 403 });
381
+ }
382
+ }
383
+ return null;
384
+ });
385
+ }
386
+ function getRouteFromPath(pathname) {
387
+ const cleanPath = pathname.replace(/^\/|\/$/g, "").replace(/^api\//, "");
388
+ const relevantPath = cleanPath.split("betterstore/")[1] || "";
389
+ return relevantPath;
390
+ }
205
391
  return {
206
- retrieveCheckout: betterStore.checkout.retrieve,
207
- updateCheckout: betterStore.checkout.update,
208
- getShippingRates: betterStore.checkout.getShippingRates
392
+ GET(req) {
393
+ return __async(this, null, function* () {
394
+ var _a2;
395
+ const validationError = yield validateRequest(req);
396
+ if (validationError)
397
+ return addCORSHeaders(
398
+ validationError,
399
+ req.headers.get("origin"),
400
+ productionAllowedOrigins
401
+ );
402
+ const route = getRouteFromPath(new URL(req.url).pathname);
403
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.GET;
404
+ if (!handler) {
405
+ return addCORSHeaders(
406
+ new Response(`Route not found: ${route}`, { status: 404 }),
407
+ req.headers.get("origin"),
408
+ productionAllowedOrigins
409
+ );
410
+ }
411
+ const response = yield handler(req, betterStore);
412
+ return addCORSHeaders(
413
+ response,
414
+ req.headers.get("origin"),
415
+ productionAllowedOrigins
416
+ );
417
+ });
418
+ },
419
+ POST(req) {
420
+ return __async(this, null, function* () {
421
+ var _a2;
422
+ const validationError = yield validateRequest(req);
423
+ if (validationError)
424
+ return addCORSHeaders(
425
+ validationError,
426
+ req.headers.get("origin"),
427
+ productionAllowedOrigins
428
+ );
429
+ const route = getRouteFromPath(new URL(req.url).pathname);
430
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.POST;
431
+ if (!handler) {
432
+ return addCORSHeaders(
433
+ new Response(`Route not found: ${route}`, { status: 404 }),
434
+ req.headers.get("origin"),
435
+ productionAllowedOrigins
436
+ );
437
+ }
438
+ const response = yield handler(req, betterStore);
439
+ return addCORSHeaders(
440
+ response,
441
+ req.headers.get("origin"),
442
+ productionAllowedOrigins
443
+ );
444
+ });
445
+ },
446
+ PUT(req) {
447
+ return __async(this, null, function* () {
448
+ var _a2;
449
+ const validationError = yield validateRequest(req);
450
+ if (validationError)
451
+ return addCORSHeaders(
452
+ validationError,
453
+ req.headers.get("origin"),
454
+ productionAllowedOrigins
455
+ );
456
+ const route = getRouteFromPath(new URL(req.url).pathname);
457
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.PUT;
458
+ if (!handler) {
459
+ return addCORSHeaders(
460
+ new Response(`Route not found: ${route}`, { status: 404 }),
461
+ req.headers.get("origin"),
462
+ productionAllowedOrigins
463
+ );
464
+ }
465
+ const response = yield handler(req, betterStore);
466
+ return addCORSHeaders(
467
+ response,
468
+ req.headers.get("origin"),
469
+ productionAllowedOrigins
470
+ );
471
+ });
472
+ },
473
+ DELETE(req) {
474
+ return __async(this, null, function* () {
475
+ var _a2;
476
+ const validationError = yield validateRequest(req);
477
+ if (validationError)
478
+ return addCORSHeaders(
479
+ validationError,
480
+ req.headers.get("origin"),
481
+ productionAllowedOrigins
482
+ );
483
+ const route = getRouteFromPath(new URL(req.url).pathname);
484
+ const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.DELETE;
485
+ if (!handler) {
486
+ return addCORSHeaders(
487
+ new Response(`Route not found: ${route}`, { status: 404 }),
488
+ req.headers.get("origin"),
489
+ productionAllowedOrigins
490
+ );
491
+ }
492
+ const response = yield handler(req, betterStore);
493
+ return addCORSHeaders(
494
+ response,
495
+ req.headers.get("origin"),
496
+ productionAllowedOrigins
497
+ );
498
+ });
499
+ }
209
500
  };
210
501
  }
211
502
 
503
+ // src/products/types.ts
504
+ var ProductStatus = /* @__PURE__ */ ((ProductStatus2) => {
505
+ ProductStatus2["DRAFT"] = "DRAFT";
506
+ ProductStatus2["ACTIVE"] = "ACTIVE";
507
+ ProductStatus2["ARCHIVED"] = "ARCHIVED";
508
+ return ProductStatus2;
509
+ })(ProductStatus || {});
510
+
212
511
  // src/index.ts
213
512
  var BetterStore = class {
214
513
  // private apiKey: string;
@@ -223,6 +522,7 @@ var BetterStore = class {
223
522
  };
224
523
  var index_default = BetterStore;
225
524
  export {
226
- index_default as default,
227
- getCheckoutEmbedProps
525
+ ProductStatus,
526
+ createNextJSHandler,
527
+ index_default as default
228
528
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterstore/sdk",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "E-commerce for Developers",
5
5
  "private": false,
6
6
  "publishConfig": {