@betterstore/sdk 0.2.2 → 0.2.3

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/.prettierignore CHANGED
@@ -1,3 +1,3 @@
1
- node_modules
2
- dist
1
+ node_modules
2
+ dist
3
3
  pnpm-lock.yaml
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @betterstore/sdk
2
2
 
3
+ ## 0.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - cors added to next.js handler
8
+
3
9
  ## 0.2.2
4
10
 
5
11
  ### Patch Changes
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Better Store
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Better Store
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.d.mts CHANGED
@@ -204,6 +204,7 @@ declare class Products {
204
204
  }
205
205
 
206
206
  type NextjsRouteConfig = {
207
+ apiKey?: string;
207
208
  productionAllowedOrigins?: string[];
208
209
  };
209
210
  type BSClient = InstanceType<typeof BetterStore>;
package/dist/index.d.ts CHANGED
@@ -204,6 +204,7 @@ declare class Products {
204
204
  }
205
205
 
206
206
  type NextjsRouteConfig = {
207
+ apiKey?: string;
207
208
  productionAllowedOrigins?: string[];
208
209
  };
209
210
  type BSClient = InstanceType<typeof BetterStore>;
package/dist/index.js CHANGED
@@ -374,13 +374,37 @@ var defaultBetterStoreRoutes = {
374
374
  })
375
375
  }
376
376
  };
377
+ function addCORSHeaders(response, origin, allowedOrigins) {
378
+ if (origin && allowedOrigins.includes(origin)) {
379
+ response.headers.set("Access-Control-Allow-Origin", origin);
380
+ }
381
+ response.headers.set(
382
+ "Access-Control-Allow-Methods",
383
+ "GET, POST, PUT, DELETE, OPTIONS"
384
+ );
385
+ response.headers.set(
386
+ "Access-Control-Allow-Headers",
387
+ "Content-Type, Authorization"
388
+ );
389
+ return response;
390
+ }
377
391
  function createNextJSHandler(betterStore, config = {}) {
378
- const { productionAllowedOrigins = [] } = config;
392
+ const { apiKey, productionAllowedOrigins = [] } = config;
379
393
  const isProduction = process.env.NODE_ENV === "production";
380
394
  function validateRequest(req) {
381
395
  return __async(this, null, function* () {
396
+ if (apiKey) {
397
+ const authHeader = req.headers.get("Authorization");
398
+ const providedKey = authHeader == null ? void 0 : authHeader.replace("Bearer ", "");
399
+ if (!providedKey || providedKey !== apiKey) {
400
+ return new Response("Unauthorized", {
401
+ status: 401,
402
+ headers: { "WWW-Authenticate": "Bearer" }
403
+ });
404
+ }
405
+ }
406
+ const origin = req.headers.get("origin");
382
407
  if (isProduction && productionAllowedOrigins.length > 0) {
383
- const origin = req.headers.get("origin");
384
408
  if (!origin || !productionAllowedOrigins.includes(origin)) {
385
409
  return new Response("Unauthorized", { status: 403 });
386
410
  }
@@ -398,52 +422,108 @@ function createNextJSHandler(betterStore, config = {}) {
398
422
  return __async(this, null, function* () {
399
423
  var _a2;
400
424
  const validationError = yield validateRequest(req);
401
- if (validationError) return validationError;
425
+ if (validationError)
426
+ return addCORSHeaders(
427
+ validationError,
428
+ req.headers.get("origin"),
429
+ productionAllowedOrigins
430
+ );
402
431
  const route = getRouteFromPath(new URL(req.url).pathname);
403
432
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.GET;
404
433
  if (!handler) {
405
- return new Response(`Route not found: ${route}`, { status: 404 });
434
+ return addCORSHeaders(
435
+ new Response(`Route not found: ${route}`, { status: 404 }),
436
+ req.headers.get("origin"),
437
+ productionAllowedOrigins
438
+ );
406
439
  }
407
- return handler(req, betterStore);
440
+ const response = yield handler(req, betterStore);
441
+ return addCORSHeaders(
442
+ response,
443
+ req.headers.get("origin"),
444
+ productionAllowedOrigins
445
+ );
408
446
  });
409
447
  },
410
448
  POST(req) {
411
449
  return __async(this, null, function* () {
412
450
  var _a2;
413
451
  const validationError = yield validateRequest(req);
414
- if (validationError) return validationError;
452
+ if (validationError)
453
+ return addCORSHeaders(
454
+ validationError,
455
+ req.headers.get("origin"),
456
+ productionAllowedOrigins
457
+ );
415
458
  const route = getRouteFromPath(new URL(req.url).pathname);
416
459
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.POST;
417
460
  if (!handler) {
418
- return new Response(`Route not found: ${route}`, { status: 404 });
461
+ return addCORSHeaders(
462
+ new Response(`Route not found: ${route}`, { status: 404 }),
463
+ req.headers.get("origin"),
464
+ productionAllowedOrigins
465
+ );
419
466
  }
420
- return handler(req, betterStore);
467
+ const response = yield handler(req, betterStore);
468
+ return addCORSHeaders(
469
+ response,
470
+ req.headers.get("origin"),
471
+ productionAllowedOrigins
472
+ );
421
473
  });
422
474
  },
423
475
  PUT(req) {
424
476
  return __async(this, null, function* () {
425
477
  var _a2;
426
478
  const validationError = yield validateRequest(req);
427
- if (validationError) return validationError;
479
+ if (validationError)
480
+ return addCORSHeaders(
481
+ validationError,
482
+ req.headers.get("origin"),
483
+ productionAllowedOrigins
484
+ );
428
485
  const route = getRouteFromPath(new URL(req.url).pathname);
429
486
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.PUT;
430
487
  if (!handler) {
431
- return new Response(`Route not found: ${route}`, { status: 404 });
488
+ return addCORSHeaders(
489
+ new Response(`Route not found: ${route}`, { status: 404 }),
490
+ req.headers.get("origin"),
491
+ productionAllowedOrigins
492
+ );
432
493
  }
433
- return handler(req, betterStore);
494
+ const response = yield handler(req, betterStore);
495
+ return addCORSHeaders(
496
+ response,
497
+ req.headers.get("origin"),
498
+ productionAllowedOrigins
499
+ );
434
500
  });
435
501
  },
436
502
  DELETE(req) {
437
503
  return __async(this, null, function* () {
438
504
  var _a2;
439
505
  const validationError = yield validateRequest(req);
440
- if (validationError) return validationError;
506
+ if (validationError)
507
+ return addCORSHeaders(
508
+ validationError,
509
+ req.headers.get("origin"),
510
+ productionAllowedOrigins
511
+ );
441
512
  const route = getRouteFromPath(new URL(req.url).pathname);
442
513
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.DELETE;
443
514
  if (!handler) {
444
- return new Response(`Route not found: ${route}`, { status: 404 });
515
+ return addCORSHeaders(
516
+ new Response(`Route not found: ${route}`, { status: 404 }),
517
+ req.headers.get("origin"),
518
+ productionAllowedOrigins
519
+ );
445
520
  }
446
- return handler(req, betterStore);
521
+ const response = yield handler(req, betterStore);
522
+ return addCORSHeaders(
523
+ response,
524
+ req.headers.get("origin"),
525
+ productionAllowedOrigins
526
+ );
447
527
  });
448
528
  }
449
529
  };
package/dist/index.mjs CHANGED
@@ -338,13 +338,37 @@ var defaultBetterStoreRoutes = {
338
338
  })
339
339
  }
340
340
  };
341
+ function addCORSHeaders(response, origin, allowedOrigins) {
342
+ if (origin && allowedOrigins.includes(origin)) {
343
+ response.headers.set("Access-Control-Allow-Origin", origin);
344
+ }
345
+ response.headers.set(
346
+ "Access-Control-Allow-Methods",
347
+ "GET, POST, PUT, DELETE, OPTIONS"
348
+ );
349
+ response.headers.set(
350
+ "Access-Control-Allow-Headers",
351
+ "Content-Type, Authorization"
352
+ );
353
+ return response;
354
+ }
341
355
  function createNextJSHandler(betterStore, config = {}) {
342
- const { productionAllowedOrigins = [] } = config;
356
+ const { apiKey, productionAllowedOrigins = [] } = config;
343
357
  const isProduction = process.env.NODE_ENV === "production";
344
358
  function validateRequest(req) {
345
359
  return __async(this, null, function* () {
360
+ if (apiKey) {
361
+ const authHeader = req.headers.get("Authorization");
362
+ const providedKey = authHeader == null ? void 0 : authHeader.replace("Bearer ", "");
363
+ if (!providedKey || providedKey !== apiKey) {
364
+ return new Response("Unauthorized", {
365
+ status: 401,
366
+ headers: { "WWW-Authenticate": "Bearer" }
367
+ });
368
+ }
369
+ }
370
+ const origin = req.headers.get("origin");
346
371
  if (isProduction && productionAllowedOrigins.length > 0) {
347
- const origin = req.headers.get("origin");
348
372
  if (!origin || !productionAllowedOrigins.includes(origin)) {
349
373
  return new Response("Unauthorized", { status: 403 });
350
374
  }
@@ -362,52 +386,108 @@ function createNextJSHandler(betterStore, config = {}) {
362
386
  return __async(this, null, function* () {
363
387
  var _a2;
364
388
  const validationError = yield validateRequest(req);
365
- if (validationError) return validationError;
389
+ if (validationError)
390
+ return addCORSHeaders(
391
+ validationError,
392
+ req.headers.get("origin"),
393
+ productionAllowedOrigins
394
+ );
366
395
  const route = getRouteFromPath(new URL(req.url).pathname);
367
396
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.GET;
368
397
  if (!handler) {
369
- return new Response(`Route not found: ${route}`, { status: 404 });
398
+ return addCORSHeaders(
399
+ new Response(`Route not found: ${route}`, { status: 404 }),
400
+ req.headers.get("origin"),
401
+ productionAllowedOrigins
402
+ );
370
403
  }
371
- return handler(req, betterStore);
404
+ const response = yield handler(req, betterStore);
405
+ return addCORSHeaders(
406
+ response,
407
+ req.headers.get("origin"),
408
+ productionAllowedOrigins
409
+ );
372
410
  });
373
411
  },
374
412
  POST(req) {
375
413
  return __async(this, null, function* () {
376
414
  var _a2;
377
415
  const validationError = yield validateRequest(req);
378
- if (validationError) return validationError;
416
+ if (validationError)
417
+ return addCORSHeaders(
418
+ validationError,
419
+ req.headers.get("origin"),
420
+ productionAllowedOrigins
421
+ );
379
422
  const route = getRouteFromPath(new URL(req.url).pathname);
380
423
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.POST;
381
424
  if (!handler) {
382
- return new Response(`Route not found: ${route}`, { status: 404 });
425
+ return addCORSHeaders(
426
+ new Response(`Route not found: ${route}`, { status: 404 }),
427
+ req.headers.get("origin"),
428
+ productionAllowedOrigins
429
+ );
383
430
  }
384
- return handler(req, betterStore);
431
+ const response = yield handler(req, betterStore);
432
+ return addCORSHeaders(
433
+ response,
434
+ req.headers.get("origin"),
435
+ productionAllowedOrigins
436
+ );
385
437
  });
386
438
  },
387
439
  PUT(req) {
388
440
  return __async(this, null, function* () {
389
441
  var _a2;
390
442
  const validationError = yield validateRequest(req);
391
- if (validationError) return validationError;
443
+ if (validationError)
444
+ return addCORSHeaders(
445
+ validationError,
446
+ req.headers.get("origin"),
447
+ productionAllowedOrigins
448
+ );
392
449
  const route = getRouteFromPath(new URL(req.url).pathname);
393
450
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.PUT;
394
451
  if (!handler) {
395
- return new Response(`Route not found: ${route}`, { status: 404 });
452
+ return addCORSHeaders(
453
+ new Response(`Route not found: ${route}`, { status: 404 }),
454
+ req.headers.get("origin"),
455
+ productionAllowedOrigins
456
+ );
396
457
  }
397
- return handler(req, betterStore);
458
+ const response = yield handler(req, betterStore);
459
+ return addCORSHeaders(
460
+ response,
461
+ req.headers.get("origin"),
462
+ productionAllowedOrigins
463
+ );
398
464
  });
399
465
  },
400
466
  DELETE(req) {
401
467
  return __async(this, null, function* () {
402
468
  var _a2;
403
469
  const validationError = yield validateRequest(req);
404
- if (validationError) return validationError;
470
+ if (validationError)
471
+ return addCORSHeaders(
472
+ validationError,
473
+ req.headers.get("origin"),
474
+ productionAllowedOrigins
475
+ );
405
476
  const route = getRouteFromPath(new URL(req.url).pathname);
406
477
  const handler = (_a2 = defaultBetterStoreRoutes[route]) == null ? void 0 : _a2.DELETE;
407
478
  if (!handler) {
408
- return new Response(`Route not found: ${route}`, { status: 404 });
479
+ return addCORSHeaders(
480
+ new Response(`Route not found: ${route}`, { status: 404 }),
481
+ req.headers.get("origin"),
482
+ productionAllowedOrigins
483
+ );
409
484
  }
410
- return handler(req, betterStore);
485
+ const response = yield handler(req, betterStore);
486
+ return addCORSHeaders(
487
+ response,
488
+ req.headers.get("origin"),
489
+ productionAllowedOrigins
490
+ );
411
491
  });
412
492
  }
413
493
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterstore/sdk",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "E-commerce for Developers",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -9,6 +9,15 @@
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/index.mjs",
11
11
  "types": "dist/index.d.ts",
12
+ "scripts": {
13
+ "prepublish": "changeset && changeset version && git add .",
14
+ "build": "tsup src/index.ts --format cjs,esm --dts",
15
+ "lint": "tsc",
16
+ "format:check": "prettier --check --ignore-path .prettierignore .",
17
+ "format": "prettier --write --ignore-path .prettierignore .",
18
+ "ci": "pnpm run lint && pnpm run format:check && pnpm run build",
19
+ "release": "pnpm run ci && changeset publish"
20
+ },
12
21
  "keywords": [
13
22
  "betterstore",
14
23
  "ecommerce",
@@ -26,14 +35,6 @@
26
35
  "typescript": "^5.8.2"
27
36
  },
28
37
  "dependencies": {
29
- "axios": "^1.8.1"
30
- },
31
- "scripts": {
32
- "build": "tsup src/index.ts --format cjs,esm --dts",
33
- "lint": "tsc",
34
- "format:check": "prettier --check --ignore-path .prettierignore .",
35
- "format": "prettier --write --ignore-path .prettierignore .",
36
- "ci": "pnpm run lint && pnpm run format:check && pnpm run build",
37
- "release": "pnpm run ci && changeset publish"
38
+ "axios": "^1.8.2"
38
39
  }
39
- }
40
+ }