@betterstore/sdk 0.6.1 → 0.6.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/dist/index.d.mts CHANGED
@@ -127,11 +127,17 @@ declare class Client {
127
127
  }): Promise<LookupAddressResult>;
128
128
  }
129
129
 
130
+ type FormatResponseForSDK<T extends object> = keyof T extends [
131
+ string,
132
+ string,
133
+ ...string[]
134
+ ] ? T : T[keyof T];
135
+
130
136
  declare class Collections {
131
137
  private apiClient;
132
138
  constructor(apiKey: string, proxy?: string);
133
- list<T extends ListCollectionsParams>(params?: T): Promise<ListCollectionsResponse<T>>;
134
- retrieve<T extends RetrieveCollectionParams>(params: T): Promise<RetrieveCollectionResponse<T> | null>;
139
+ list<T extends ListCollectionsParams>(params?: T): Promise<FormatResponseForSDK<ListCollectionsResponse<T>>>;
140
+ retrieve<T extends RetrieveCollectionParams>(params: T): Promise<FormatResponseForSDK<RetrieveCollectionResponse<T>> | null>;
135
141
  }
136
142
 
137
143
  declare class Customer {
@@ -162,17 +168,30 @@ declare class Customer {
162
168
  declare class Discounts {
163
169
  private apiClient;
164
170
  constructor(apiKey: string, proxy?: string);
165
- list<T extends ListDiscountsParams>(params?: T): Promise<ListDiscountsResponse>;
166
- retrieve<T extends RetrieveDiscountParams>(params: T): Promise<RetrieveDiscountResponse | null>;
171
+ list<T extends ListDiscountsParams>(params?: T): Promise<FormatResponseForSDK<ListDiscountsResponse>>;
172
+ retrieve<T extends RetrieveDiscountParams>(params: T): Promise<FormatResponseForSDK<RetrieveDiscountResponse> | null>;
167
173
  }
168
174
 
169
175
  declare class Products {
170
176
  private apiClient;
171
177
  constructor(apiKey: string, proxy?: string);
172
- list<T extends ListProductsParams>(params?: T): Promise<ListProductsResponse<T>>;
173
- retrieve<T extends RetrieveProductParams>(params: T): Promise<RetrieveProductResponse<T> | null>;
178
+ list<T extends ListProductsParams>(params?: T): Promise<FormatResponseForSDK<ListProductsResponse<T>>>;
179
+ retrieve<T extends RetrieveProductParams>(params: T): Promise<FormatResponseForSDK<RetrieveProductResponse<T>> | null>;
174
180
  }
175
181
 
182
+ type Discount = NonNullable<RetrieveDiscountResponse["discount"]>;
183
+ declare function findAutomaticProductDiscount({ productId, priceInCents, discounts, }: {
184
+ productId: string;
185
+ priceInCents: number;
186
+ discounts: Discount[];
187
+ }): {
188
+ finalPrice: number;
189
+ discountAmount: number | undefined;
190
+ originalPrice: number;
191
+ isFree: boolean;
192
+ isDiscounted: boolean;
193
+ };
194
+
176
195
  declare function createBetterStore(config: {
177
196
  apiKey: string;
178
197
  proxy?: string;
@@ -188,4 +207,4 @@ declare function createStoreClient(config?: {
188
207
  proxy?: string;
189
208
  }): Client;
190
209
 
191
- export { createStoreClient, createBetterStore as default };
210
+ export { type Discount, createStoreClient, createBetterStore as default, findAutomaticProductDiscount };
package/dist/index.d.ts CHANGED
@@ -127,11 +127,17 @@ declare class Client {
127
127
  }): Promise<LookupAddressResult>;
128
128
  }
129
129
 
130
+ type FormatResponseForSDK<T extends object> = keyof T extends [
131
+ string,
132
+ string,
133
+ ...string[]
134
+ ] ? T : T[keyof T];
135
+
130
136
  declare class Collections {
131
137
  private apiClient;
132
138
  constructor(apiKey: string, proxy?: string);
133
- list<T extends ListCollectionsParams>(params?: T): Promise<ListCollectionsResponse<T>>;
134
- retrieve<T extends RetrieveCollectionParams>(params: T): Promise<RetrieveCollectionResponse<T> | null>;
139
+ list<T extends ListCollectionsParams>(params?: T): Promise<FormatResponseForSDK<ListCollectionsResponse<T>>>;
140
+ retrieve<T extends RetrieveCollectionParams>(params: T): Promise<FormatResponseForSDK<RetrieveCollectionResponse<T>> | null>;
135
141
  }
136
142
 
137
143
  declare class Customer {
@@ -162,17 +168,30 @@ declare class Customer {
162
168
  declare class Discounts {
163
169
  private apiClient;
164
170
  constructor(apiKey: string, proxy?: string);
165
- list<T extends ListDiscountsParams>(params?: T): Promise<ListDiscountsResponse>;
166
- retrieve<T extends RetrieveDiscountParams>(params: T): Promise<RetrieveDiscountResponse | null>;
171
+ list<T extends ListDiscountsParams>(params?: T): Promise<FormatResponseForSDK<ListDiscountsResponse>>;
172
+ retrieve<T extends RetrieveDiscountParams>(params: T): Promise<FormatResponseForSDK<RetrieveDiscountResponse> | null>;
167
173
  }
168
174
 
169
175
  declare class Products {
170
176
  private apiClient;
171
177
  constructor(apiKey: string, proxy?: string);
172
- list<T extends ListProductsParams>(params?: T): Promise<ListProductsResponse<T>>;
173
- retrieve<T extends RetrieveProductParams>(params: T): Promise<RetrieveProductResponse<T> | null>;
178
+ list<T extends ListProductsParams>(params?: T): Promise<FormatResponseForSDK<ListProductsResponse<T>>>;
179
+ retrieve<T extends RetrieveProductParams>(params: T): Promise<FormatResponseForSDK<RetrieveProductResponse<T>> | null>;
174
180
  }
175
181
 
182
+ type Discount = NonNullable<RetrieveDiscountResponse["discount"]>;
183
+ declare function findAutomaticProductDiscount({ productId, priceInCents, discounts, }: {
184
+ productId: string;
185
+ priceInCents: number;
186
+ discounts: Discount[];
187
+ }): {
188
+ finalPrice: number;
189
+ discountAmount: number | undefined;
190
+ originalPrice: number;
191
+ isFree: boolean;
192
+ isDiscounted: boolean;
193
+ };
194
+
176
195
  declare function createBetterStore(config: {
177
196
  apiKey: string;
178
197
  proxy?: string;
@@ -188,4 +207,4 @@ declare function createStoreClient(config?: {
188
207
  proxy?: string;
189
208
  }): Client;
190
209
 
191
- export { createStoreClient, createBetterStore as default };
210
+ export { type Discount, createStoreClient, createBetterStore as default, findAutomaticProductDiscount };
package/dist/index.js CHANGED
@@ -32,12 +32,13 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  createStoreClient: () => createStoreClient,
34
34
  default: () => createBetterStore,
35
+ findAutomaticProductDiscount: () => findAutomaticProductDiscount,
35
36
  formatCurrency: () => import_bridge.formatCurrency,
36
37
  formatPrice: () => import_bridge.formatPrice
37
38
  });
38
39
  module.exports = __toCommonJS(index_exports);
39
40
 
40
- // src/utils/axios.ts
41
+ // src/_utils/axios.ts
41
42
  var import_axios = __toESM(require("axios"));
42
43
  var API_BASE_URL = "https://v1.betterstore.io";
43
44
  var createApiClient = (apiKey, proxy) => {
@@ -440,11 +441,9 @@ var Collections = class {
440
441
  async list(params) {
441
442
  const data = await this.apiClient.post(`/collections`, params);
442
443
  if (!data || !Array.isArray(data) || "isError" in data && data.isError || !("collections" in data)) {
443
- return {
444
- collections: []
445
- };
444
+ return [];
446
445
  }
447
- return data;
446
+ return data.collections;
448
447
  }
449
448
  async retrieve(params) {
450
449
  const data = await this.apiClient.post(`/collections/retrieve`, params);
@@ -452,7 +451,7 @@ var Collections = class {
452
451
  console.error(`Collection not found`);
453
452
  return null;
454
453
  }
455
- return data;
454
+ return data.collection;
456
455
  }
457
456
  };
458
457
  var collections_default = Collections;
@@ -537,11 +536,9 @@ var Discounts = class {
537
536
  params
538
537
  );
539
538
  if (!data || !Array.isArray(data) || "isError" in data && data.isError || !("discounts" in data)) {
540
- return {
541
- discounts: []
542
- };
539
+ return [];
543
540
  }
544
- return data;
541
+ return data.discounts;
545
542
  }
546
543
  async retrieve(params) {
547
544
  const data = await this.apiClient.post(
@@ -552,7 +549,7 @@ var Discounts = class {
552
549
  console.error(`Discount not found`);
553
550
  return null;
554
551
  }
555
- return data;
552
+ return data.discount;
556
553
  }
557
554
  };
558
555
  var discounts_default = Discounts;
@@ -569,11 +566,9 @@ var Products = class {
569
566
  params
570
567
  );
571
568
  if (!data || !Array.isArray(data) || "isError" in data && data.isError || !("products" in data)) {
572
- return {
573
- products: []
574
- };
569
+ return [];
575
570
  }
576
- return data;
571
+ return data.products;
577
572
  }
578
573
  async retrieve(params) {
579
574
  const data = await this.apiClient.post("/products/retrieve", params);
@@ -581,14 +576,58 @@ var Products = class {
581
576
  console.error(`Product not found`);
582
577
  return null;
583
578
  }
584
- return data;
579
+ return data.product;
585
580
  }
586
581
  };
587
582
  var products_default = Products;
588
583
 
589
- // src/types.ts
584
+ // src/types-and-methods.ts
590
585
  var import_bridge = require("@betterstore/bridge");
591
586
 
587
+ // src/methods/cart-discounts.ts
588
+ function getHighestDiscount(productId, priceInCents, discounts) {
589
+ const applicableDiscounts = discounts.filter(
590
+ (discount) => discount.allowedProductIDs.includes(productId)
591
+ );
592
+ const bestDiscount = applicableDiscounts.length > 1 ? applicableDiscounts.reduce((bestSoFar, currentDiscount) => {
593
+ let currentDiscountValueInCents = currentDiscount.value;
594
+ if (currentDiscount.valueType === "PERCENTAGE") {
595
+ currentDiscountValueInCents = currentDiscount.value / 100 * priceInCents;
596
+ } else if (currentDiscount.valueType === "FREE") {
597
+ currentDiscountValueInCents = priceInCents;
598
+ }
599
+ return (bestSoFar?.value ?? 0) > currentDiscountValueInCents ? bestSoFar : currentDiscount;
600
+ }, applicableDiscounts[0]) : applicableDiscounts[0];
601
+ return bestDiscount;
602
+ }
603
+ function calculateDiscountAmount(originalPrice, discount) {
604
+ let discountValueInCents = discount?.value;
605
+ const isFreeDiscount = discount?.valueType === "FREE";
606
+ if (discount?.valueType === "PERCENTAGE") {
607
+ discountValueInCents = discount.value / 100 * originalPrice;
608
+ } else if (discount?.valueType === "FREE") {
609
+ discountValueInCents = originalPrice;
610
+ }
611
+ const finalPrice = discountValueInCents ? Math.max(originalPrice - discountValueInCents, 0) : originalPrice;
612
+ const isDiscounted = discountValueInCents === 0;
613
+ return {
614
+ finalPrice,
615
+ discountAmount: discountValueInCents,
616
+ originalPrice,
617
+ isFree: isFreeDiscount,
618
+ isDiscounted
619
+ };
620
+ }
621
+ function findAutomaticProductDiscount({
622
+ productId,
623
+ priceInCents,
624
+ discounts
625
+ }) {
626
+ const discount = getHighestDiscount(productId, priceInCents, discounts);
627
+ const result = calculateDiscountAmount(priceInCents, discount);
628
+ return result;
629
+ }
630
+
592
631
  // src/index.ts
593
632
  function createBetterStore(config) {
594
633
  if (!config.apiKey) {
@@ -609,6 +648,7 @@ function createStoreClient(config) {
609
648
  // Annotate the CommonJS export names for ESM import in node:
610
649
  0 && (module.exports = {
611
650
  createStoreClient,
651
+ findAutomaticProductDiscount,
612
652
  formatCurrency,
613
653
  formatPrice
614
654
  });
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // src/utils/axios.ts
1
+ // src/_utils/axios.ts
2
2
  import axios from "axios";
3
3
  var API_BASE_URL = "https://v1.betterstore.io";
4
4
  var createApiClient = (apiKey, proxy) => {
@@ -401,11 +401,9 @@ var Collections = class {
401
401
  async list(params) {
402
402
  const data = await this.apiClient.post(`/collections`, params);
403
403
  if (!data || !Array.isArray(data) || "isError" in data && data.isError || !("collections" in data)) {
404
- return {
405
- collections: []
406
- };
404
+ return [];
407
405
  }
408
- return data;
406
+ return data.collections;
409
407
  }
410
408
  async retrieve(params) {
411
409
  const data = await this.apiClient.post(`/collections/retrieve`, params);
@@ -413,7 +411,7 @@ var Collections = class {
413
411
  console.error(`Collection not found`);
414
412
  return null;
415
413
  }
416
- return data;
414
+ return data.collection;
417
415
  }
418
416
  };
419
417
  var collections_default = Collections;
@@ -498,11 +496,9 @@ var Discounts = class {
498
496
  params
499
497
  );
500
498
  if (!data || !Array.isArray(data) || "isError" in data && data.isError || !("discounts" in data)) {
501
- return {
502
- discounts: []
503
- };
499
+ return [];
504
500
  }
505
- return data;
501
+ return data.discounts;
506
502
  }
507
503
  async retrieve(params) {
508
504
  const data = await this.apiClient.post(
@@ -513,7 +509,7 @@ var Discounts = class {
513
509
  console.error(`Discount not found`);
514
510
  return null;
515
511
  }
516
- return data;
512
+ return data.discount;
517
513
  }
518
514
  };
519
515
  var discounts_default = Discounts;
@@ -530,11 +526,9 @@ var Products = class {
530
526
  params
531
527
  );
532
528
  if (!data || !Array.isArray(data) || "isError" in data && data.isError || !("products" in data)) {
533
- return {
534
- products: []
535
- };
529
+ return [];
536
530
  }
537
- return data;
531
+ return data.products;
538
532
  }
539
533
  async retrieve(params) {
540
534
  const data = await this.apiClient.post("/products/retrieve", params);
@@ -542,14 +536,58 @@ var Products = class {
542
536
  console.error(`Product not found`);
543
537
  return null;
544
538
  }
545
- return data;
539
+ return data.product;
546
540
  }
547
541
  };
548
542
  var products_default = Products;
549
543
 
550
- // src/types.ts
544
+ // src/types-and-methods.ts
551
545
  import { formatCurrency, formatPrice } from "@betterstore/bridge";
552
546
 
547
+ // src/methods/cart-discounts.ts
548
+ function getHighestDiscount(productId, priceInCents, discounts) {
549
+ const applicableDiscounts = discounts.filter(
550
+ (discount) => discount.allowedProductIDs.includes(productId)
551
+ );
552
+ const bestDiscount = applicableDiscounts.length > 1 ? applicableDiscounts.reduce((bestSoFar, currentDiscount) => {
553
+ let currentDiscountValueInCents = currentDiscount.value;
554
+ if (currentDiscount.valueType === "PERCENTAGE") {
555
+ currentDiscountValueInCents = currentDiscount.value / 100 * priceInCents;
556
+ } else if (currentDiscount.valueType === "FREE") {
557
+ currentDiscountValueInCents = priceInCents;
558
+ }
559
+ return (bestSoFar?.value ?? 0) > currentDiscountValueInCents ? bestSoFar : currentDiscount;
560
+ }, applicableDiscounts[0]) : applicableDiscounts[0];
561
+ return bestDiscount;
562
+ }
563
+ function calculateDiscountAmount(originalPrice, discount) {
564
+ let discountValueInCents = discount?.value;
565
+ const isFreeDiscount = discount?.valueType === "FREE";
566
+ if (discount?.valueType === "PERCENTAGE") {
567
+ discountValueInCents = discount.value / 100 * originalPrice;
568
+ } else if (discount?.valueType === "FREE") {
569
+ discountValueInCents = originalPrice;
570
+ }
571
+ const finalPrice = discountValueInCents ? Math.max(originalPrice - discountValueInCents, 0) : originalPrice;
572
+ const isDiscounted = discountValueInCents === 0;
573
+ return {
574
+ finalPrice,
575
+ discountAmount: discountValueInCents,
576
+ originalPrice,
577
+ isFree: isFreeDiscount,
578
+ isDiscounted
579
+ };
580
+ }
581
+ function findAutomaticProductDiscount({
582
+ productId,
583
+ priceInCents,
584
+ discounts
585
+ }) {
586
+ const discount = getHighestDiscount(productId, priceInCents, discounts);
587
+ const result = calculateDiscountAmount(priceInCents, discount);
588
+ return result;
589
+ }
590
+
553
591
  // src/index.ts
554
592
  function createBetterStore(config) {
555
593
  if (!config.apiKey) {
@@ -570,6 +608,7 @@ function createStoreClient(config) {
570
608
  export {
571
609
  createStoreClient,
572
610
  createBetterStore as default,
611
+ findAutomaticProductDiscount,
573
612
  formatCurrency,
574
613
  formatPrice
575
614
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterstore/sdk",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",