@zoxllc/shopify-checkout-extensions 0.0.8 → 0.2.0

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.
Files changed (164) hide show
  1. package/CLAUDE.md +136 -0
  2. package/EXAMPLES.md +463 -0
  3. package/INTEGRATION.md +482 -0
  4. package/README.md +5 -1
  5. package/dist/common/AndSelector.d.ts +11 -0
  6. package/dist/common/AndSelector.d.ts.map +1 -0
  7. package/dist/common/AndSelector.js +30 -0
  8. package/dist/common/Campaign.d.ts +24 -0
  9. package/dist/common/Campaign.d.ts.map +1 -0
  10. package/dist/common/Campaign.js +41 -0
  11. package/dist/common/CampaignConfiguration.d.ts +10 -0
  12. package/dist/common/CampaignConfiguration.d.ts.map +1 -0
  13. package/dist/common/CampaignConfiguration.js +7 -0
  14. package/dist/common/CampaignFactory.d.ts +22 -0
  15. package/dist/common/CampaignFactory.d.ts.map +1 -0
  16. package/dist/common/CampaignFactory.js +98 -0
  17. package/dist/common/CartAmountQualifier.d.ts +22 -0
  18. package/dist/common/CartAmountQualifier.d.ts.map +1 -0
  19. package/dist/common/CartAmountQualifier.js +46 -0
  20. package/dist/common/CartHasItemQualifier.d.ts +21 -0
  21. package/dist/common/CartHasItemQualifier.d.ts.map +1 -0
  22. package/dist/common/CartHasItemQualifier.js +54 -0
  23. package/dist/common/CartQuantityQualifier.d.ts +22 -0
  24. package/dist/common/CartQuantityQualifier.d.ts.map +1 -0
  25. package/dist/common/CartQuantityQualifier.js +62 -0
  26. package/dist/common/ConfigSchema.d.ts +71 -0
  27. package/dist/common/ConfigSchema.d.ts.map +1 -0
  28. package/dist/common/ConfigSchema.js +69 -0
  29. package/dist/common/ConfigValidator.d.ts +29 -0
  30. package/dist/common/ConfigValidator.d.ts.map +1 -0
  31. package/dist/common/ConfigValidator.js +84 -0
  32. package/dist/common/CountryCodeQualifier.d.ts +15 -0
  33. package/dist/common/CountryCodeQualifier.d.ts.map +1 -0
  34. package/dist/common/CountryCodeQualifier.js +30 -0
  35. package/dist/common/CustomerEmailQualifier.d.ts +16 -0
  36. package/dist/common/CustomerEmailQualifier.d.ts.map +1 -0
  37. package/dist/common/CustomerEmailQualifier.js +52 -0
  38. package/dist/common/CustomerSubscriberQualifier.d.ts +18 -0
  39. package/dist/common/CustomerSubscriberQualifier.d.ts.map +1 -0
  40. package/dist/common/CustomerSubscriberQualifier.js +28 -0
  41. package/dist/common/CustomerTagQualifier.d.ts +16 -0
  42. package/dist/common/CustomerTagQualifier.d.ts.map +1 -0
  43. package/dist/common/CustomerTagQualifier.js +45 -0
  44. package/dist/common/DiscountCart.d.ts +23 -0
  45. package/dist/common/DiscountCart.d.ts.map +1 -0
  46. package/dist/common/DiscountCart.js +103 -0
  47. package/dist/common/DiscountInterface.d.ts +17 -0
  48. package/dist/common/DiscountInterface.d.ts.map +1 -0
  49. package/dist/common/DiscountInterface.js +2 -0
  50. package/dist/common/OrSelector.d.ts +11 -0
  51. package/dist/common/OrSelector.d.ts.map +1 -0
  52. package/dist/common/OrSelector.js +30 -0
  53. package/dist/common/PostCartAmountQualifier.d.ts +9 -0
  54. package/dist/common/PostCartAmountQualifier.d.ts.map +1 -0
  55. package/dist/common/PostCartAmountQualifier.js +17 -0
  56. package/dist/common/ProductHandleSelector.d.ts +8 -0
  57. package/dist/common/ProductHandleSelector.d.ts.map +1 -0
  58. package/dist/common/ProductHandleSelector.js +22 -0
  59. package/dist/common/ProductIdSelector.d.ts +8 -0
  60. package/dist/common/ProductIdSelector.d.ts.map +1 -0
  61. package/dist/common/ProductIdSelector.js +22 -0
  62. package/dist/common/ProductTagSelector.d.ts +10 -0
  63. package/dist/common/ProductTagSelector.d.ts.map +1 -0
  64. package/dist/common/ProductTagSelector.js +39 -0
  65. package/dist/common/ProductTypeSelector.d.ts +8 -0
  66. package/dist/common/ProductTypeSelector.d.ts.map +1 -0
  67. package/dist/common/ProductTypeSelector.js +25 -0
  68. package/dist/common/Qualifier.d.ts +30 -0
  69. package/dist/common/Qualifier.d.ts.map +1 -0
  70. package/dist/common/Qualifier.js +61 -0
  71. package/dist/common/SaleItemSelector.d.ts +11 -0
  72. package/dist/common/SaleItemSelector.d.ts.map +1 -0
  73. package/dist/common/SaleItemSelector.js +30 -0
  74. package/dist/common/Selector.d.ts +27 -0
  75. package/dist/common/Selector.d.ts.map +1 -0
  76. package/dist/common/Selector.js +51 -0
  77. package/dist/common/SubscriptionItemSelector.d.ts +7 -0
  78. package/dist/common/SubscriptionItemSelector.d.ts.map +1 -0
  79. package/dist/common/SubscriptionItemSelector.js +19 -0
  80. package/dist/form/CampaignForm.d.ts +1 -0
  81. package/dist/form/CampaignForm.d.ts.map +1 -0
  82. package/dist/form/CampaignForm.js +1 -0
  83. package/{src/index.ts → dist/index.d.ts} +23 -27
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +80 -0
  86. package/dist/lineItem/BuyXGetY.d.ts +18 -0
  87. package/dist/lineItem/BuyXGetY.d.ts.map +1 -0
  88. package/dist/lineItem/BuyXGetY.js +85 -0
  89. package/dist/lineItem/ConditionalDiscount.d.ts +14 -0
  90. package/dist/lineItem/ConditionalDiscount.d.ts.map +1 -0
  91. package/dist/lineItem/ConditionalDiscount.js +81 -0
  92. package/dist/lineItem/FixedItemDiscount.d.ts +9 -0
  93. package/dist/lineItem/FixedItemDiscount.d.ts.map +1 -0
  94. package/dist/lineItem/FixedItemDiscount.js +35 -0
  95. package/dist/lineItem/MultiTierDiscount.d.ts +47 -0
  96. package/dist/lineItem/MultiTierDiscount.d.ts.map +1 -0
  97. package/dist/lineItem/MultiTierDiscount.js +150 -0
  98. package/dist/lineItem/PercentageDiscount.d.ts +8 -0
  99. package/dist/lineItem/PercentageDiscount.d.ts.map +1 -0
  100. package/dist/lineItem/PercentageDiscount.js +32 -0
  101. package/dist/lineItem/api.d.ts +2026 -0
  102. package/dist/lineItem/api.d.ts.map +1 -0
  103. package/dist/lineItem/api.js +1157 -0
  104. package/dist/shipping/FixedDiscount.d.ts +8 -0
  105. package/dist/shipping/FixedDiscount.d.ts.map +1 -0
  106. package/dist/shipping/FixedDiscount.js +30 -0
  107. package/dist/shipping/RateNameSelector.d.ts +10 -0
  108. package/dist/shipping/RateNameSelector.d.ts.map +1 -0
  109. package/dist/shipping/RateNameSelector.js +45 -0
  110. package/dist/shipping/ShippingDiscount.d.ts +14 -0
  111. package/dist/shipping/ShippingDiscount.d.ts.map +1 -0
  112. package/dist/shipping/ShippingDiscount.js +48 -0
  113. package/dist/shipping/api.d.ts +2019 -0
  114. package/dist/shipping/api.d.ts.map +1 -0
  115. package/dist/shipping/api.js +1147 -0
  116. package/package.json +26 -7
  117. package/migrate.ts +0 -64
  118. package/src/common/AndSelector.ts +0 -42
  119. package/src/common/Campaign.ts +0 -70
  120. package/src/common/CampaignConfiguration.ts +0 -10
  121. package/src/common/CampaignFactory.ts +0 -233
  122. package/src/common/CartAmountQualifier.ts +0 -64
  123. package/src/common/CartHasItemQualifier.ts +0 -80
  124. package/src/common/CartQuantityQualifier.ts +0 -94
  125. package/src/common/CountryCodeQualifier.ts +0 -49
  126. package/src/common/CustomerEmailQualifier.ts +0 -67
  127. package/src/common/CustomerSubscriberQualifier.ts +0 -32
  128. package/src/common/CustomerTagQualifier.ts +0 -69
  129. package/src/common/DiscountCart.ts +0 -161
  130. package/src/common/DiscountInterface.ts +0 -26
  131. package/src/common/OrSelector.ts +0 -40
  132. package/src/common/PostCartAmountQualifier.ts +0 -21
  133. package/src/common/ProductHandleSelector.ts +0 -32
  134. package/src/common/ProductIdSelector.ts +0 -34
  135. package/src/common/ProductTagSelector.ts +0 -63
  136. package/src/common/ProductTypeSelector.ts +0 -40
  137. package/src/common/Qualifier.ts +0 -67
  138. package/src/common/SaleItemSelector.ts +0 -36
  139. package/src/common/Selector.ts +0 -66
  140. package/src/common/SubscriptionItemSelector.ts +0 -23
  141. package/src/lineItem/BuyXGetY.ts +0 -131
  142. package/src/lineItem/ConditionalDiscount.ts +0 -102
  143. package/src/lineItem/FixedItemDiscount.ts +0 -51
  144. package/src/lineItem/PercentageDiscount.ts +0 -44
  145. package/src/lineItem/api.ts +0 -2103
  146. package/src/shipping/FixedDiscount.ts +0 -37
  147. package/src/shipping/RateNameSelector.ts +0 -54
  148. package/src/shipping/ShippingDiscount.ts +0 -75
  149. package/src/shipping/api.ts +0 -2014
  150. package/tests/AndSelector.test.ts +0 -27
  151. package/tests/CartQuantityQualifier.test.ts +0 -381
  152. package/tests/CountryCodeQualifier.test.ts +0 -55
  153. package/tests/CustomerSubscriberQualifier.test.ts +0 -101
  154. package/tests/CustomerTagQualifier.test.ts +0 -71
  155. package/tests/DiscountCart.test.ts +0 -115
  156. package/tests/OrSelector.test.ts +0 -27
  157. package/tests/ProductIdSelector.test.ts +0 -83
  158. package/tests/ProductTagSelector.test.ts +0 -75
  159. package/tests/Qualifier.test.ts +0 -193
  160. package/tests/RateNameSelector.test.ts +0 -107
  161. package/tests/SaleItemSelector.test.ts +0 -113
  162. package/tests/Selector.test.ts +0 -83
  163. package/tests/ShippingDiscount.test.ts +0 -147
  164. package/tsconfig.json +0 -25
@@ -1,94 +0,0 @@
1
- import type { CartLine } from '../lineItem/api';
2
- import type { DiscountCart } from './DiscountCart';
3
- import {
4
- type NumericalComparisonType,
5
- Qualifier,
6
- } from './Qualifier';
7
- import { type Selector } from './Selector';
8
-
9
- export enum CartQuantityBehavior {
10
- CART = ':cart',
11
- ITEM = ':item',
12
- LINE_ANY = ':line_any',
13
- LINE_ALL = ':line_all',
14
- }
15
-
16
- export class CartQuantityQualifier extends Qualifier {
17
- totalMethod: CartQuantityBehavior;
18
- comparisonType: NumericalComparisonType;
19
- quantity: number;
20
-
21
- constructor(
22
- totalMethod: CartQuantityBehavior,
23
- comparisonType: NumericalComparisonType,
24
- quantity: number
25
- ) {
26
- super();
27
- this.totalMethod = totalMethod;
28
- this.comparisonType = comparisonType;
29
- this.quantity = quantity;
30
- }
31
-
32
- /**
33
- * Determines if the carts amount
34
- * @param cart
35
- * @param selector
36
- */
37
- match(discountCart: DiscountCart, selector?: Selector) {
38
- let total = 0;
39
-
40
- switch (this.totalMethod) {
41
- case CartQuantityBehavior.ITEM:
42
- total = discountCart.cart.lines.reduce(
43
- (totalQty, line) => {
44
- return (
45
- totalQty +
46
- ((
47
- selector
48
- ? selector.match(line as CartLine)
49
- : true
50
- )
51
- ? line.quantity
52
- : 0)
53
- );
54
- },
55
- 0
56
- );
57
- break;
58
- case CartQuantityBehavior.CART:
59
- total =
60
- discountCart.totalLineItemQuantityExcludingGifts();
61
- break;
62
- }
63
-
64
- if (
65
- this.totalMethod == CartQuantityBehavior.LINE_ANY ||
66
- this.totalMethod == CartQuantityBehavior.LINE_ALL
67
- ) {
68
- const qualifiedItems = discountCart.cart.lines
69
- .filter((line) =>
70
- selector ? selector.match(line as CartLine) : true
71
- )
72
- .map((line) =>
73
- this.compareAmounts(
74
- line.quantity,
75
- this.comparisonType,
76
- this.quantity
77
- )
78
- );
79
-
80
- switch (this.totalMethod) {
81
- case CartQuantityBehavior.LINE_ANY:
82
- return qualifiedItems.indexOf(true) > -1;
83
- case CartQuantityBehavior.LINE_ALL:
84
- return qualifiedItems.indexOf(false) == -1;
85
- }
86
- } else {
87
- return this.compareAmounts(
88
- total,
89
- this.comparisonType,
90
- this.quantity
91
- );
92
- }
93
- }
94
- }
@@ -1,49 +0,0 @@
1
- import type { DiscountCart } from './DiscountCart';
2
- import {
3
- StringComparisonType,
4
- QualifierMatchType,
5
- Qualifier,
6
- } from './Qualifier';
7
- import { type Selector } from './Selector';
8
-
9
- export class CountryCodeQualifier extends Qualifier {
10
- invert: boolean;
11
- countryCodes: string[];
12
-
13
- constructor(
14
- matchType: QualifierMatchType,
15
- countryCodes: string[]
16
- ) {
17
- super();
18
- this.invert = matchType == QualifierMatchType.DOES_NOT;
19
- this.countryCodes = countryCodes.map((e) =>
20
- e.toLowerCase()
21
- );
22
- }
23
-
24
- /**
25
- * Determines if the customer has specified tags
26
- * @param discountCart DiscountCart
27
- * @param selector Selector
28
- */
29
- match(discountCart: DiscountCart, selector?: Selector) {
30
- const matchResult =
31
- (
32
- discountCart.cart.deliveryGroups.filter(
33
- (deliveryGroup) => {
34
- const countryCode =
35
- deliveryGroup?.deliveryAddress?.countryCode?.toLowerCase() ||
36
- '';
37
-
38
- return this.countryCodes.includes(countryCode);
39
- }
40
- ) || []
41
- ).length > 0;
42
-
43
- if (this.invert) {
44
- return !matchResult;
45
- }
46
-
47
- return matchResult;
48
- }
49
- }
@@ -1,67 +0,0 @@
1
- import type { DiscountCart } from './DiscountCart';
2
- import {
3
- StringComparisonType,
4
- QualifierMatchType,
5
- Qualifier,
6
- } from './Qualifier';
7
- import { type Selector } from './Selector';
8
-
9
- export class CustomerEmailQualifier extends Qualifier {
10
- invert: boolean;
11
- matchCondition: StringComparisonType;
12
- emails: string[];
13
-
14
- constructor(
15
- matchType: QualifierMatchType,
16
- matchCondition: StringComparisonType,
17
- emails: string[]
18
- ) {
19
- super();
20
- this.invert = matchType == QualifierMatchType.DOES_NOT;
21
- this.matchCondition = matchCondition;
22
- this.emails = emails.map((e) => e.toLowerCase());
23
- }
24
-
25
- /**
26
- * Determines if the customer's email matches
27
- * @param discountCart DiscountCart
28
- * @param selector Selector
29
- */
30
- match(discountCart: DiscountCart, selector?: Selector) {
31
- if (!discountCart.cart.buyerIdentity?.customer?.email) {
32
- return false;
33
- }
34
-
35
- let matchResult = false;
36
-
37
- const email =
38
- discountCart.cart.buyerIdentity.customer.email.toLowerCase();
39
-
40
- switch (this.matchCondition) {
41
- case StringComparisonType.MATCH:
42
- matchResult = this.emails.includes(email);
43
- break;
44
- case StringComparisonType.CONTAINS:
45
- matchResult =
46
- this.emails.filter((e) => email.includes(e))
47
- .length > 0;
48
- break;
49
- case StringComparisonType.START_WITH:
50
- matchResult =
51
- this.emails.filter((e) => email.startsWith(e))
52
- .length > 0;
53
- break;
54
- case StringComparisonType.END_WITH:
55
- matchResult =
56
- this.emails.filter((e) => email.endsWith(e))
57
- .length > 0;
58
- break;
59
- }
60
-
61
- if (this.invert) {
62
- return !matchResult;
63
- }
64
-
65
- return matchResult;
66
- }
67
- }
@@ -1,32 +0,0 @@
1
- import type { DiscountCart } from "./DiscountCart";
2
- import { QualifierMatchType, Qualifier } from "./Qualifier";
3
- import { type Selector } from "./Selector";
4
-
5
- export class CustomerSubscriberQualifier extends Qualifier {
6
- invert: boolean;
7
-
8
- /**
9
- * Whether the customer contains an active subscription or not.
10
- * @param matchType Pass :DOES or :DOES_NOT respectively
11
- */
12
- constructor(matchType: QualifierMatchType) {
13
- super();
14
- this.invert = matchType == QualifierMatchType.DOES_NOT;
15
- }
16
-
17
- /**
18
- * Determines if the customer has specified tags
19
- * @param discountCart DiscountCart
20
- * @param selector Selector
21
- */
22
- match(discountCart: DiscountCart, selector?: Selector) {
23
- const matchResult =
24
- discountCart.cart.buyerIdentity?.customer?.isActiveSubscriber || false;
25
-
26
- if (this.invert) {
27
- return !matchResult;
28
- }
29
-
30
- return matchResult;
31
- }
32
- }
@@ -1,69 +0,0 @@
1
- import type { DiscountCart } from './DiscountCart';
2
- import {
3
- StringComparisonType,
4
- QualifierMatchType,
5
- Qualifier,
6
- } from './Qualifier';
7
- import { type Selector } from './Selector';
8
-
9
- export class CustomerTagQualifier extends Qualifier {
10
- invert: boolean;
11
- matchCondition: StringComparisonType;
12
- tags: string[];
13
-
14
- constructor(
15
- matchType: QualifierMatchType,
16
- matchCondition: StringComparisonType,
17
- tags: string[]
18
- ) {
19
- super();
20
- this.invert = matchType == QualifierMatchType.DOES_NOT;
21
- this.matchCondition = matchCondition;
22
- this.tags = tags.map((e) => e.toLowerCase());
23
- }
24
-
25
- /**
26
- * Determines if the customer has specified tags
27
- * @param discountCart DiscountCart
28
- * @param selector Selector
29
- */
30
- match(discountCart: DiscountCart, selector?: Selector) {
31
- const matchResult =
32
- (
33
- discountCart.cart.buyerIdentity?.customer?.hasTags.filter(
34
- (t) => {
35
- if (t.hasTag) {
36
- const tag = t.tag.toLowerCase();
37
- switch (this.matchCondition) {
38
- case StringComparisonType.MATCH:
39
- return this.tags.includes(tag);
40
- case StringComparisonType.CONTAINS:
41
- return (
42
- this.tags.filter((e) => tag.includes(e))
43
- .length > 0
44
- );
45
- case StringComparisonType.START_WITH:
46
- return (
47
- this.tags.filter((e) =>
48
- tag.startsWith(e)
49
- ).length > 0
50
- );
51
- case StringComparisonType.END_WITH:
52
- return (
53
- this.tags.filter((e) => tag.endsWith(e))
54
- .length > 0
55
- );
56
- }
57
- }
58
- return false;
59
- }
60
- ) || []
61
- ).length > 0;
62
-
63
- if (this.invert) {
64
- return !matchResult;
65
- }
66
-
67
- return matchResult;
68
- }
69
- }
@@ -1,161 +0,0 @@
1
- import type {
2
- RunInput as LineItemRunInput,
3
- Discount as DiscountItem,
4
- } from '../lineItem/api';
5
- import type {
6
- RunInput as ShippingRunInput,
7
- Discount as DiscountShipping,
8
- } from '../shipping/api';
9
- import { Discount } from './DiscountInterface';
10
-
11
- type RunInput = {
12
- cart: LineItemRunInput['cart'] & ShippingRunInput['cart'];
13
- };
14
-
15
- export class DiscountCart {
16
- cart: RunInput['cart'];
17
- subtotalAmount: number;
18
- appliedDiscountTotal: number;
19
- discounts: Discount[];
20
-
21
- constructor(cart: RunInput['cart']) {
22
- this.cart = cart;
23
- this.subtotalAmount = 0;
24
- this.appliedDiscountTotal = 0;
25
- this.discounts = [];
26
-
27
- this.setupCart(cart);
28
- }
29
-
30
- subtotalExcludingVariants(variants: string[]) {
31
- return this.cart.lines.reduce((prev, curr) => {
32
- if (curr.merchandise.__typename == 'ProductVariant') {
33
- if (variants.indexOf(curr.merchandise.id) > -1) {
34
- return prev - curr.cost.subtotalAmount.amount;
35
- }
36
- }
37
-
38
- return prev;
39
- }, this.subtotalExcludingGifts());
40
- }
41
-
42
- private subtotalExcludingGifts() {
43
- return this.cart.lines.reduce((prev, curr) => {
44
- if (curr.merchandise.__typename == 'ProductVariant') {
45
- if (
46
- curr.merchandise.product.hasTags.filter(
47
- (t) => t.hasTag && t.tag == 'meta-exclude-gift'
48
- ).length
49
- ) {
50
- return prev - curr.cost.subtotalAmount.amount;
51
- }
52
- }
53
-
54
- return prev;
55
- }, this.subtotalAmount);
56
- }
57
-
58
- totalLineItemQuantity() {
59
- return this.cart.lines.reduce(
60
- (total, item) => total + item.quantity,
61
- 0
62
- );
63
- }
64
-
65
- totalLineItemQuantityExcludingGifts() {
66
- return this.cart.lines.reduce((total, item) => {
67
- if (item.merchandise.__typename == 'ProductVariant') {
68
- if (
69
- item.merchandise.product.hasTags.filter(
70
- (t) => t.hasTag && t.tag == 'meta-exclude-gift'
71
- ).length
72
- ) {
73
- return total;
74
- }
75
- }
76
- return total + item.quantity;
77
- }, 0);
78
- }
79
-
80
- private setupCart(cart: RunInput['cart']) {
81
- this.subtotalAmount = cart.cost.subtotalAmount
82
- .amount as number;
83
- // Adjust the subtotal amount by excluding the value from gift items
84
- this.subtotalAmount = this.subtotalExcludingGifts();
85
- this.appliedDiscountTotal = 0;
86
- this.discounts = [];
87
- }
88
-
89
- addShippingDiscount(discount: DiscountShipping) {
90
- this.discounts.push(discount as Discount);
91
- }
92
-
93
- addDiscount(discount: DiscountItem) {
94
- // Figure out how much discount has been applied
95
- const totalDiscounts = discount.targets.reduce(
96
- (total, target) => {
97
- // gather target lineItem
98
- const lineItems = this.cart.lines.filter((line) =>
99
- line.merchandise.__typename == 'ProductVariant'
100
- ? line.merchandise.id ==
101
- target.productVariant.id
102
- : false
103
- );
104
-
105
- // loop over the line items and do maths
106
- lineItems.forEach((line) => {
107
- let discountableItems = target.productVariant
108
- .quantity
109
- ? target.productVariant.quantity
110
- : line.quantity;
111
-
112
- const lineItemCost = parseFloat(
113
- line.cost.amountPerQuantity.amount
114
- );
115
-
116
- // When it's a fixed amount, calculate the items per but only if it applies to each individual item...
117
- if (discount.value.fixedAmount) {
118
- if (
119
- discount.value.fixedAmount.appliesToEachItem
120
- ) {
121
- total +=
122
- lineItemCost -
123
- discount.value.fixedAmount?.amount >
124
- 0
125
- ? discount.value.fixedAmount?.amount *
126
- discountableItems
127
- : lineItemCost * discountableItems;
128
- } else {
129
- total +=
130
- lineItemCost -
131
- discount.value.fixedAmount?.amount >
132
- 0
133
- ? discount.value.fixedAmount?.amount
134
- : lineItemCost;
135
- }
136
- } else if (discount.value.percentage) {
137
- total +=
138
- lineItemCost *
139
- (discount.value.percentage?.value / 100) *
140
- discountableItems;
141
- }
142
- });
143
-
144
- return total;
145
- },
146
- 0
147
- );
148
-
149
- this.appliedDiscountTotal += totalDiscounts;
150
- console.error(
151
- 'appliedDiscountTotal',
152
- this.appliedDiscountTotal
153
- );
154
-
155
- this.discounts.push(discount as Discount);
156
- }
157
-
158
- reset() {
159
- this.setupCart(this.cart);
160
- }
161
- }
@@ -1,26 +0,0 @@
1
- import type {
2
- CartDeliveryOption,
3
- CartLine,
4
- } from '../lineItem/api';
5
-
6
- import type { Discount as DiscountItem } from '../lineItem/api';
7
- import type { Discount as DiscountShipping } from '../shipping/api';
8
-
9
- export type Discount = DiscountItem & DiscountShipping;
10
-
11
-
12
- type ApplyLineItemDiscount = {
13
- lineItem: CartLine;
14
- maxDiscounts?: number;
15
- };
16
-
17
- type ApplyShippingDiscount = {
18
- deliveryOption: CartDeliveryOption;
19
- };
20
-
21
- export type ApplyDiscount = ApplyLineItemDiscount &
22
- ApplyShippingDiscount;
23
-
24
- export interface DiscountInterface {
25
- apply(items: ApplyDiscount[]): Discount;
26
- }
@@ -1,40 +0,0 @@
1
- import type { DiscountCart } from './DiscountCart';
2
- import type { Qualifier } from './Qualifier';
3
- import type { Selector } from './Selector';
4
- import type { CartLine } from '../lineItem/api';
5
-
6
- export class OrSelector {
7
- is_a: 'OrSelector';
8
- conditions: (Selector | Qualifier)[];
9
-
10
- constructor(conditions: (Selector | Qualifier)[]) {
11
- this.is_a = 'OrSelector';
12
- this.conditions = conditions;
13
- }
14
-
15
- match(
16
- item: CartLine | DiscountCart,
17
- selector?: Selector
18
- ) {
19
- try {
20
- const conditionsResult = this.conditions
21
- .map((condition) => {
22
- if (selector) {
23
- return (condition as Qualifier).match(
24
- item as DiscountCart,
25
- selector
26
- );
27
- } else {
28
- return (condition as Selector).match(
29
- item as CartLine
30
- );
31
- }
32
- })
33
- .filter((result) => result === true);
34
-
35
- return conditionsResult.length > 0;
36
- } catch (e) {
37
- return false;
38
- }
39
- }
40
- }
@@ -1,21 +0,0 @@
1
- import type { DiscountCart } from "./DiscountCart";
2
- import { type NumericalComparisonType, Qualifier } from "./Qualifier";
3
-
4
- export class PostCartAmountQualifier extends Qualifier {
5
- comparisonType: NumericalComparisonType;
6
- amount: number;
7
-
8
- constructor(comparisonType: NumericalComparisonType, amount: number) {
9
- super();
10
- this.comparisonType = comparisonType;
11
- this.amount = amount;
12
- }
13
-
14
- match(discountCart: DiscountCart) {
15
- return this.compareAmounts(
16
- discountCart.subtotalAmount - discountCart.appliedDiscountTotal,
17
- this.comparisonType,
18
- this.amount
19
- );
20
- }
21
- }
@@ -1,32 +0,0 @@
1
- import type {
2
- CartLine,
3
- ProductVariant,
4
- } from '../lineItem/api';
5
- import { MatchType, Selector } from './Selector';
6
-
7
- export class ProductHandleSelector extends Selector {
8
- invert: boolean;
9
- handles: string[];
10
-
11
- constructor(matchType: MatchType, handles: string[]) {
12
- super();
13
- this.invert = matchType == MatchType.NOT_ONE;
14
- this.handles = handles.map((t) => t.toLowerCase());
15
- }
16
-
17
- match(lineItem: unknown): boolean;
18
- match(lineItem: CartLine) {
19
- const variant = lineItem.merchandise as ProductVariant;
20
-
21
- const matchResult =
22
- this.handles.indexOf(
23
- variant.product.handle.toLowerCase()
24
- ) > -1;
25
-
26
- if (this.invert) {
27
- return !matchResult;
28
- }
29
-
30
- return matchResult;
31
- }
32
- }
@@ -1,34 +0,0 @@
1
- import type {
2
- CartLine,
3
- ProductVariant,
4
- } from '../lineItem/api';
5
- import { MatchType, Selector } from './Selector';
6
-
7
- export class ProductIdSelector extends Selector {
8
- invert: boolean;
9
- productIds: string[];
10
-
11
- constructor(
12
- matchType: MatchType.IS_ONE | MatchType.NOT_ONE,
13
- productIds: string[]
14
- ) {
15
- super();
16
- this.invert = matchType == MatchType.NOT_ONE;
17
- this.productIds = productIds;
18
- }
19
-
20
- match(subject: unknown): boolean;
21
- match(lineItem: CartLine) {
22
- const variant = lineItem.merchandise as ProductVariant;
23
-
24
- const matchResult = this.productIds.includes(
25
- variant.product.id
26
- );
27
-
28
- if (this.invert) {
29
- return !matchResult;
30
- }
31
-
32
- return matchResult;
33
- }
34
- }
@@ -1,63 +0,0 @@
1
- import type {
2
- CartLine,
3
- ProductVariant,
4
- } from '../lineItem/api';
5
- import { Selector } from './Selector';
6
- import {
7
- QualifierMatchType,
8
- StringComparisonType,
9
- } from './Qualifier';
10
-
11
- export class ProductTagSelector extends Selector {
12
- invert: boolean;
13
- matchCondition: StringComparisonType;
14
- tags: string[];
15
-
16
- constructor(
17
- matchType: QualifierMatchType,
18
- matchCondition: StringComparisonType,
19
- tags: string[]
20
- ) {
21
- super();
22
- this.matchCondition = matchCondition;
23
- this.invert = matchType == QualifierMatchType.DOES_NOT;
24
- this.tags = tags.map((t) => t.toLowerCase());
25
- }
26
-
27
- match(subject: unknown): boolean;
28
- match(lineItem: CartLine) {
29
- const variant = lineItem.merchandise as ProductVariant;
30
- const productTags = variant.product.hasTags.reduce(
31
- (tags, t) => {
32
- if (t.hasTag) {
33
- tags.push(t.tag.toLowerCase());
34
- }
35
- return tags;
36
- },
37
- [] as string[]
38
- );
39
-
40
- let matchResult: boolean;
41
-
42
- switch (this.matchCondition) {
43
- case StringComparisonType.MATCH:
44
- matchResult =
45
- productTags.filter((tag) =>
46
- this.tags.includes(tag)
47
- ).length > 0;
48
- break;
49
- default:
50
- matchResult = this.partialMatch(
51
- this.matchCondition,
52
- productTags,
53
- this.tags
54
- );
55
- }
56
-
57
- if (this.invert) {
58
- return !matchResult;
59
- }
60
-
61
- return matchResult;
62
- }
63
- }