@kiva/kv-shop 1.3.2 → 1.4.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 (56) hide show
  1. package/dist/basket.cjs +44 -15
  2. package/dist/basket.d.ts +4 -4
  3. package/dist/basket.js +5 -8
  4. package/dist/basketCredits.cjs +197 -0
  5. package/dist/basketCredits.d.ts +18 -0
  6. package/dist/basketCredits.js +12 -0
  7. package/dist/basketItems.cjs +70 -33
  8. package/dist/basketItems.d.ts +11 -1
  9. package/dist/basketItems.js +5 -3
  10. package/dist/basketTotals.cjs +228 -0
  11. package/dist/basketTotals.d.ts +37 -0
  12. package/dist/basketTotals.js +12 -0
  13. package/dist/basketVerification.cjs +41 -0
  14. package/dist/basketVerification.d.ts +10 -0
  15. package/dist/basketVerification.js +8 -0
  16. package/dist/checkoutStatus.cjs +110 -0
  17. package/dist/checkoutStatus.d.ts +20 -0
  18. package/dist/checkoutStatus.js +10 -0
  19. package/dist/{chunk-B7RLQXI6.js → chunk-2NC7LGGO.js} +14 -12
  20. package/dist/{chunk-IYCMZ5WV.js → chunk-4ODZGLWK.js} +21 -0
  21. package/dist/chunk-AI6E33YE.js +33 -0
  22. package/dist/chunk-CBJJUUVR.js +121 -0
  23. package/dist/chunk-DZGZX4F6.js +45 -0
  24. package/dist/chunk-EJ5NGYPO.js +145 -0
  25. package/dist/chunk-FCAOCO7O.js +17 -0
  26. package/dist/chunk-JBQ2KNMP.js +50 -0
  27. package/dist/{chunk-SLMBU6L7.js → chunk-JXQPCEKG.js} +9 -2
  28. package/dist/{chunk-TIASV6B2.js → chunk-KV4SOUVF.js} +1 -1
  29. package/dist/chunk-LZ4UMRCV.js +16 -0
  30. package/dist/chunk-MRCBNXPS.js +35 -0
  31. package/dist/chunk-PC4WUPYU.js +78 -0
  32. package/dist/chunk-TPJPGUO7.js +12 -0
  33. package/dist/components/KvPaymentSelect.vue +8 -1
  34. package/dist/index.cjs +489 -56
  35. package/dist/index.d.ts +12 -5
  36. package/dist/index.js +55 -21
  37. package/dist/oneTimeCheckout.cjs +396 -9
  38. package/dist/oneTimeCheckout.d.ts +11 -10
  39. package/dist/oneTimeCheckout.js +10 -5
  40. package/dist/shopError.cjs +21 -0
  41. package/dist/shopError.d.ts +2 -0
  42. package/dist/shopError.js +1 -1
  43. package/dist/shopQueries.cjs +248 -0
  44. package/dist/shopQueries.d.ts +8 -0
  45. package/dist/shopQueries.js +13 -0
  46. package/dist/subscriptionCheckout.cjs +21 -0
  47. package/dist/subscriptionCheckout.js +2 -2
  48. package/dist/useBraintreeDropIn.cjs +29 -1
  49. package/dist/useBraintreeDropIn.d.ts +9 -9
  50. package/dist/useBraintreeDropIn.js +2 -2
  51. package/dist/validatePreCheckout.cjs +210 -0
  52. package/dist/validatePreCheckout.d.ts +22 -0
  53. package/dist/validatePreCheckout.js +13 -0
  54. package/package.json +2 -2
  55. package/dist/chunk-M4CJOCIQ.js +0 -26
  56. package/dist/chunk-NC7RAUNV.js +0 -66
@@ -0,0 +1,248 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/shopQueries.ts
20
+ var shopQueries_exports = {};
21
+ __export(shopQueries_exports, {
22
+ callShopMutation: () => callShopMutation,
23
+ callShopQuery: () => callShopQuery,
24
+ watchShopQuery: () => watchShopQuery
25
+ });
26
+ module.exports = __toCommonJS(shopQueries_exports);
27
+
28
+ // src/basket.ts
29
+ var import_core = require("@apollo/client/core");
30
+
31
+ // src/util/cookie.ts
32
+ var getCookieValue = (name) => {
33
+ if (typeof document !== void 0) {
34
+ return decodeURIComponent(document.cookie.match(`(^|;)\\s*${name}\\s*=\\s*([^;]+)`)?.pop() || "");
35
+ }
36
+ };
37
+ var setCookieValue = (name, value, options = "") => {
38
+ if (typeof document !== void 0) {
39
+ document.cookie = `${name}=${encodeURIComponent(value)};${options}`;
40
+ }
41
+ };
42
+
43
+ // src/shopError.ts
44
+ var ShopError = class extends Error {
45
+ constructor({ code, original }, ...params) {
46
+ super(...params);
47
+ if (Error.captureStackTrace) {
48
+ Error.captureStackTrace(this, ShopError);
49
+ }
50
+ this.name = "ShopError";
51
+ this.code = code;
52
+ this.original = original;
53
+ }
54
+ aggregateErrors(errors) {
55
+ this.errors = errors;
56
+ }
57
+ };
58
+ function parseShopError(error) {
59
+ if (error instanceof ShopError) {
60
+ return error;
61
+ }
62
+ const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
63
+ const errorMessage = typeof error === "string" ? error : error?.message ?? "";
64
+ if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
65
+ return new ShopError({
66
+ code: "paymentMethod.create.invalidMethodParameter",
67
+ original: error
68
+ }, "There was a problem validating your payment information. Please double-check the details and try again.");
69
+ }
70
+ if (errorMessage.includes("Invalid request: ")) {
71
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
72
+ const finalCode = finalError[1];
73
+ const finalMessage = finalError[2];
74
+ return new ShopError({
75
+ code: `paymentMethod.${finalCode}`,
76
+ original: error
77
+ }, finalMessage);
78
+ }
79
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
80
+ return new ShopError({
81
+ code: "shop.insufficientFunds",
82
+ original: error
83
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
84
+ }
85
+ if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
86
+ return new ShopError({
87
+ code: errorCode,
88
+ original: error
89
+ }, "There was a problem with your basket. Please, refresh the page and try again.");
90
+ }
91
+ if (errorCode === "donationAmountTooLarge") {
92
+ return new ShopError({
93
+ code: errorCode,
94
+ original: error
95
+ }, errorMessage);
96
+ }
97
+ return new ShopError({
98
+ code: "shop.unknown",
99
+ original: error
100
+ }, "An unknown error occurred.");
101
+ }
102
+
103
+ // src/basket.ts
104
+ function getBasketID() {
105
+ return getCookieValue("kvbskt");
106
+ }
107
+ function setBasketID(basketId) {
108
+ setCookieValue("kvbskt", basketId, "path=/;secure;");
109
+ }
110
+ async function createBasketHelper(apollo) {
111
+ try {
112
+ return apollo.mutate({
113
+ mutation: import_core.gql`mutation createNewBasketForUser { shop { id createBasket } }`
114
+ }).then(({ data }) => {
115
+ const newBasketId = data.shop?.createBasket ?? null;
116
+ if (newBasketId) {
117
+ setBasketID(newBasketId);
118
+ }
119
+ });
120
+ } catch (error) {
121
+ throw parseShopError(error);
122
+ }
123
+ }
124
+ var activeBasketCreationQuery = null;
125
+ async function createBasket(apollo) {
126
+ if (activeBasketCreationQuery) {
127
+ return activeBasketCreationQuery;
128
+ }
129
+ activeBasketCreationQuery = createBasketHelper(apollo);
130
+ return activeBasketCreationQuery;
131
+ }
132
+ function hasBasketExpired(error) {
133
+ const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
134
+ return ["shop.invalidBasketId", "shop.basketRequired", "shop.alreadyCheckedOut"].includes(errorCode);
135
+ }
136
+
137
+ // src/shopQueries.ts
138
+ var watchQueries = /* @__PURE__ */ new Set();
139
+ async function callShopMutation(apollo, options, maxretries = 2) {
140
+ try {
141
+ const result = await apollo.mutate({
142
+ ...options,
143
+ variables: {
144
+ ...options.variables,
145
+ basketId: getBasketID()
146
+ },
147
+ refetchQueries: options.awaitRefetchQueries ? Array.from(watchQueries) : []
148
+ });
149
+ if (result?.errors?.length) {
150
+ const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
151
+ if (basketErrors.length) {
152
+ if (maxretries > 0) {
153
+ await createBasket(apollo);
154
+ return callShopMutation(apollo, options, maxretries - 1);
155
+ }
156
+ throw basketErrors[0];
157
+ }
158
+ if (result?.errors?.length) {
159
+ throw result.errors[0];
160
+ }
161
+ }
162
+ return result?.data;
163
+ } catch (e) {
164
+ throw parseShopError(e);
165
+ }
166
+ }
167
+ async function callShopQuery(apollo, options, maxretries = 2) {
168
+ try {
169
+ const result = await apollo.query({
170
+ ...options,
171
+ variables: {
172
+ ...options.variables,
173
+ basketId: getBasketID()
174
+ }
175
+ });
176
+ if (result?.errors?.length) {
177
+ const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
178
+ if (basketErrors.length) {
179
+ if (maxretries > 0) {
180
+ await createBasket(apollo);
181
+ return callShopQuery(apollo, options, maxretries - 1);
182
+ }
183
+ throw basketErrors[0];
184
+ }
185
+ if (result?.errors?.length) {
186
+ throw result.errors[0];
187
+ }
188
+ }
189
+ return result?.data;
190
+ } catch (e) {
191
+ throw parseShopError(e);
192
+ }
193
+ }
194
+ function watchShopQuery(apollo, options, maxretries = 2) {
195
+ let retries = 0;
196
+ watchQueries.add(options.query);
197
+ const observable = apollo.watchQuery({
198
+ ...options,
199
+ variables: {
200
+ ...options.variables,
201
+ basketId: getBasketID()
202
+ }
203
+ });
204
+ const oldSubscribe = observable.subscribe.bind(observable);
205
+ observable.subscribe = (...args) => {
206
+ let nextFn;
207
+ let errorFn;
208
+ let completeFn;
209
+ if (typeof args[0] === "function") {
210
+ [nextFn, errorFn, completeFn] = args;
211
+ } else {
212
+ nextFn = args[0]?.next;
213
+ errorFn = args[0]?.error;
214
+ completeFn = args[0]?.complete;
215
+ }
216
+ const newErrorFn = (err) => {
217
+ const basketErrors = err?.graphQLErrors?.filter((e) => hasBasketExpired(e));
218
+ if (basketErrors.length) {
219
+ if (retries < maxretries) {
220
+ createBasket(apollo).then(() => {
221
+ retries += 1;
222
+ observable.refetch({
223
+ ...observable.variables,
224
+ basketId: getBasketID()
225
+ });
226
+ });
227
+ } else {
228
+ errorFn(parseShopError(basketErrors[0]));
229
+ }
230
+ } else {
231
+ if (err?.graphQLErrors?.length) {
232
+ errorFn(parseShopError(err.graphQLErrors[0]));
233
+ }
234
+ if (err?.networkError) {
235
+ errorFn(parseShopError(err.networkError));
236
+ }
237
+ }
238
+ };
239
+ return oldSubscribe(nextFn, newErrorFn, completeFn);
240
+ };
241
+ return observable;
242
+ }
243
+ // Annotate the CommonJS export names for ESM import in node:
244
+ 0 && (module.exports = {
245
+ callShopMutation,
246
+ callShopQuery,
247
+ watchShopQuery
248
+ });
@@ -0,0 +1,8 @@
1
+ import * as _apollo_client_core from '@apollo/client/core';
2
+ import { ApolloClient, MutationOptions, QueryOptions, WatchQueryOptions } from '@apollo/client/core';
3
+
4
+ declare function callShopMutation<TData>(apollo: ApolloClient<any>, options: MutationOptions<TData, any>, maxretries?: number): any;
5
+ declare function callShopQuery<TData>(apollo: ApolloClient<any>, options: QueryOptions<any, TData>, maxretries?: number): any;
6
+ declare function watchShopQuery<TData>(apollo: ApolloClient<any>, options: WatchQueryOptions<any, TData>, maxretries?: number): _apollo_client_core.ObservableQuery<TData, any>;
7
+
8
+ export { callShopMutation, callShopQuery, watchShopQuery };
@@ -0,0 +1,13 @@
1
+ import {
2
+ callShopMutation,
3
+ callShopQuery,
4
+ watchShopQuery
5
+ } from "./chunk-CBJJUUVR.js";
6
+ import "./chunk-2NC7LGGO.js";
7
+ import "./chunk-4ODZGLWK.js";
8
+ import "./chunk-LZ4UMRCV.js";
9
+ export {
10
+ callShopMutation,
11
+ callShopQuery,
12
+ watchShopQuery
13
+ };
@@ -36,8 +36,14 @@ var ShopError = class extends Error {
36
36
  this.code = code;
37
37
  this.original = original;
38
38
  }
39
+ aggregateErrors(errors) {
40
+ this.errors = errors;
41
+ }
39
42
  };
40
43
  function parseShopError(error) {
44
+ if (error instanceof ShopError) {
45
+ return error;
46
+ }
41
47
  const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
42
48
  const errorMessage = typeof error === "string" ? error : error?.message ?? "";
43
49
  if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
@@ -46,6 +52,21 @@ function parseShopError(error) {
46
52
  original: error
47
53
  }, "There was a problem validating your payment information. Please double-check the details and try again.");
48
54
  }
55
+ if (errorMessage.includes("Invalid request: ")) {
56
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
57
+ const finalCode = finalError[1];
58
+ const finalMessage = finalError[2];
59
+ return new ShopError({
60
+ code: `paymentMethod.${finalCode}`,
61
+ original: error
62
+ }, finalMessage);
63
+ }
64
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
65
+ return new ShopError({
66
+ code: "shop.insufficientFunds",
67
+ original: error
68
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
69
+ }
49
70
  if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
50
71
  return new ShopError({
51
72
  code: errorCode,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  checkSubscriptionStatus,
3
3
  executeNewSubscriptionCheckout
4
- } from "./chunk-TIASV6B2.js";
5
- import "./chunk-IYCMZ5WV.js";
4
+ } from "./chunk-KV4SOUVF.js";
5
+ import "./chunk-4ODZGLWK.js";
6
6
  export {
7
7
  checkSubscriptionStatus,
8
8
  executeNewSubscriptionCheckout
@@ -49,8 +49,14 @@ var ShopError = class extends Error {
49
49
  this.code = code;
50
50
  this.original = original;
51
51
  }
52
+ aggregateErrors(errors) {
53
+ this.errors = errors;
54
+ }
52
55
  };
53
56
  function parseShopError(error) {
57
+ if (error instanceof ShopError) {
58
+ return error;
59
+ }
54
60
  const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
55
61
  const errorMessage = typeof error === "string" ? error : error?.message ?? "";
56
62
  if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
@@ -59,6 +65,21 @@ function parseShopError(error) {
59
65
  original: error
60
66
  }, "There was a problem validating your payment information. Please double-check the details and try again.");
61
67
  }
68
+ if (errorMessage.includes("Invalid request: ")) {
69
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
70
+ const finalCode = finalError[1];
71
+ const finalMessage = finalError[2];
72
+ return new ShopError({
73
+ code: `paymentMethod.${finalCode}`,
74
+ original: error
75
+ }, finalMessage);
76
+ }
77
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
78
+ return new ShopError({
79
+ code: "shop.insufficientFunds",
80
+ original: error
81
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
82
+ }
62
83
  if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
63
84
  return new ShopError({
64
85
  code: errorCode,
@@ -93,7 +114,7 @@ async function getClientToken(apollo) {
93
114
  }
94
115
  return data?.shop?.getClientToken;
95
116
  }
96
- function useBraintreeDropIn() {
117
+ function initBraintreeDropin() {
97
118
  let instance;
98
119
  let formattedAmount = "";
99
120
  const paymentMethodRequestable = (0, import_vue_demi.ref)(false);
@@ -223,6 +244,13 @@ function useBraintreeDropIn() {
223
244
  updateAmount
224
245
  };
225
246
  }
247
+ var instances = {};
248
+ function useBraintreeDropIn(key = "default") {
249
+ if (!instances[key]) {
250
+ instances[key] = initBraintreeDropin();
251
+ }
252
+ return instances[key];
253
+ }
226
254
  // Annotate the CommonJS export names for ESM import in node:
227
255
  0 && (module.exports = {
228
256
  defaultPaymentTypes,
@@ -1,6 +1,5 @@
1
- import * as braintree_web_drop_in from 'braintree-web-drop-in';
2
- import { Dropin } from 'braintree-web-drop-in';
3
- import * as _vue_composition_api from '@vue/composition-api';
1
+ import { Ref } from 'vue-demi';
2
+ import { Dropin, PaymentMethodPayload } from 'braintree-web-drop-in';
4
3
 
5
4
  declare type PaymentType = 'card' | 'paypal' | 'paypalCredit' | 'venmo' | 'applePay' | 'googlePay';
6
5
  declare type PayPalFlowType = 'checkout' | 'vault';
@@ -15,11 +14,12 @@ interface DropInInitOptions {
15
14
  preselectVaultedPaymentMethod?: boolean;
16
15
  paypalFlow?: PayPalFlowType;
17
16
  }
18
- declare function useBraintreeDropIn(): {
19
- initDropIn: ({ amount, authToken, container, googlePayMerchantId, paymentTypes, preselectVaultedPaymentMethod, paypalFlow, }: DropInInitOptions) => Promise<Dropin>;
20
- paymentMethodRequestable: _vue_composition_api.Ref<boolean>;
21
- requestPaymentMethod: () => Promise<braintree_web_drop_in.PaymentMethodPayload>;
17
+ interface DropInWrapper {
18
+ initDropIn: (options: DropInInitOptions) => Promise<Dropin>;
19
+ paymentMethodRequestable: Ref<boolean>;
20
+ requestPaymentMethod: () => Promise<PaymentMethodPayload | void>;
22
21
  updateAmount: (amount: string | number) => void;
23
- };
22
+ }
23
+ declare function useBraintreeDropIn(key?: string): DropInWrapper;
24
24
 
25
- export { DropInInitOptions, PayPalFlowType, PaymentType, useBraintreeDropIn as default, defaultPaymentTypes, getClientToken };
25
+ export { DropInInitOptions, DropInWrapper, PayPalFlowType, PaymentType, useBraintreeDropIn as default, defaultPaymentTypes, getClientToken };
@@ -2,8 +2,8 @@ import {
2
2
  defaultPaymentTypes,
3
3
  getClientToken,
4
4
  useBraintreeDropIn
5
- } from "./chunk-SLMBU6L7.js";
6
- import "./chunk-IYCMZ5WV.js";
5
+ } from "./chunk-JXQPCEKG.js";
6
+ import "./chunk-4ODZGLWK.js";
7
7
  export {
8
8
  useBraintreeDropIn as default,
9
9
  defaultPaymentTypes,
@@ -0,0 +1,210 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/validatePreCheckout.ts
20
+ var validatePreCheckout_exports = {};
21
+ __export(validatePreCheckout_exports, {
22
+ validatePreCheckout: () => validatePreCheckout,
23
+ validatePreCheckoutMutation: () => validatePreCheckoutMutation
24
+ });
25
+ module.exports = __toCommonJS(validatePreCheckout_exports);
26
+ var import_core2 = require("@apollo/client/core");
27
+
28
+ // src/basket.ts
29
+ var import_core = require("@apollo/client/core");
30
+
31
+ // src/util/cookie.ts
32
+ var getCookieValue = (name) => {
33
+ if (typeof document !== void 0) {
34
+ return decodeURIComponent(document.cookie.match(`(^|;)\\s*${name}\\s*=\\s*([^;]+)`)?.pop() || "");
35
+ }
36
+ };
37
+ var setCookieValue = (name, value, options = "") => {
38
+ if (typeof document !== void 0) {
39
+ document.cookie = `${name}=${encodeURIComponent(value)};${options}`;
40
+ }
41
+ };
42
+
43
+ // src/shopError.ts
44
+ var ShopError = class extends Error {
45
+ constructor({ code, original }, ...params) {
46
+ super(...params);
47
+ if (Error.captureStackTrace) {
48
+ Error.captureStackTrace(this, ShopError);
49
+ }
50
+ this.name = "ShopError";
51
+ this.code = code;
52
+ this.original = original;
53
+ }
54
+ aggregateErrors(errors) {
55
+ this.errors = errors;
56
+ }
57
+ };
58
+ function parseShopError(error) {
59
+ if (error instanceof ShopError) {
60
+ return error;
61
+ }
62
+ const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
63
+ const errorMessage = typeof error === "string" ? error : error?.message ?? "";
64
+ if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
65
+ return new ShopError({
66
+ code: "paymentMethod.create.invalidMethodParameter",
67
+ original: error
68
+ }, "There was a problem validating your payment information. Please double-check the details and try again.");
69
+ }
70
+ if (errorMessage.includes("Invalid request: ")) {
71
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
72
+ const finalCode = finalError[1];
73
+ const finalMessage = finalError[2];
74
+ return new ShopError({
75
+ code: `paymentMethod.${finalCode}`,
76
+ original: error
77
+ }, finalMessage);
78
+ }
79
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
80
+ return new ShopError({
81
+ code: "shop.insufficientFunds",
82
+ original: error
83
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
84
+ }
85
+ if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
86
+ return new ShopError({
87
+ code: errorCode,
88
+ original: error
89
+ }, "There was a problem with your basket. Please, refresh the page and try again.");
90
+ }
91
+ if (errorCode === "donationAmountTooLarge") {
92
+ return new ShopError({
93
+ code: errorCode,
94
+ original: error
95
+ }, errorMessage);
96
+ }
97
+ return new ShopError({
98
+ code: "shop.unknown",
99
+ original: error
100
+ }, "An unknown error occurred.");
101
+ }
102
+
103
+ // src/basket.ts
104
+ function getBasketID() {
105
+ return getCookieValue("kvbskt");
106
+ }
107
+ function setBasketID(basketId) {
108
+ setCookieValue("kvbskt", basketId, "path=/;secure;");
109
+ }
110
+ async function createBasketHelper(apollo) {
111
+ try {
112
+ return apollo.mutate({
113
+ mutation: import_core.gql`mutation createNewBasketForUser { shop { id createBasket } }`
114
+ }).then(({ data }) => {
115
+ const newBasketId = data.shop?.createBasket ?? null;
116
+ if (newBasketId) {
117
+ setBasketID(newBasketId);
118
+ }
119
+ });
120
+ } catch (error) {
121
+ throw parseShopError(error);
122
+ }
123
+ }
124
+ var activeBasketCreationQuery = null;
125
+ async function createBasket(apollo) {
126
+ if (activeBasketCreationQuery) {
127
+ return activeBasketCreationQuery;
128
+ }
129
+ activeBasketCreationQuery = createBasketHelper(apollo);
130
+ return activeBasketCreationQuery;
131
+ }
132
+ function hasBasketExpired(error) {
133
+ const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
134
+ return ["shop.invalidBasketId", "shop.basketRequired", "shop.alreadyCheckedOut"].includes(errorCode);
135
+ }
136
+
137
+ // src/shopQueries.ts
138
+ var watchQueries = /* @__PURE__ */ new Set();
139
+ async function callShopMutation(apollo, options, maxretries = 2) {
140
+ try {
141
+ const result = await apollo.mutate({
142
+ ...options,
143
+ variables: {
144
+ ...options.variables,
145
+ basketId: getBasketID()
146
+ },
147
+ refetchQueries: options.awaitRefetchQueries ? Array.from(watchQueries) : []
148
+ });
149
+ if (result?.errors?.length) {
150
+ const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
151
+ if (basketErrors.length) {
152
+ if (maxretries > 0) {
153
+ await createBasket(apollo);
154
+ return callShopMutation(apollo, options, maxretries - 1);
155
+ }
156
+ throw basketErrors[0];
157
+ }
158
+ if (result?.errors?.length) {
159
+ throw result.errors[0];
160
+ }
161
+ }
162
+ return result?.data;
163
+ } catch (e) {
164
+ throw parseShopError(e);
165
+ }
166
+ }
167
+
168
+ // src/util/visitorId.ts
169
+ function getVisitorID() {
170
+ return getCookieValue("uiv");
171
+ }
172
+
173
+ // src/validatePreCheckout.ts
174
+ var validatePreCheckoutMutation = import_core2.gql`
175
+ mutation validatePreCheckout($basketId: String, $email: String, $visitorId: String, $emailOptIn: Boolean) {
176
+ shop (basketId: $basketId) {
177
+ id
178
+ validatePreCheckout (email: $email, visitorId: $visitorId, emailOptIn: $emailOptIn) {
179
+ error
180
+ success
181
+ value
182
+ }
183
+ }
184
+ }`;
185
+ async function validatePreCheckout({
186
+ apollo,
187
+ emailAddress,
188
+ emailOptIn
189
+ }) {
190
+ const data = await callShopMutation(apollo, {
191
+ mutation: validatePreCheckoutMutation,
192
+ variables: {
193
+ visitorId: getVisitorID(),
194
+ email: emailAddress,
195
+ emailOptIn
196
+ }
197
+ }, 0);
198
+ const results = data?.shop?.validatePreCheckout;
199
+ const errors = results.filter(({ success }) => !success).map((result) => parseShopError(result));
200
+ if (errors.length) {
201
+ const aggregate = new ShopError({ code: "shop.failedCheckoutValidation" });
202
+ aggregate.aggregateErrors(errors);
203
+ throw aggregate;
204
+ }
205
+ }
206
+ // Annotate the CommonJS export names for ESM import in node:
207
+ 0 && (module.exports = {
208
+ validatePreCheckout,
209
+ validatePreCheckoutMutation
210
+ });
@@ -0,0 +1,22 @@
1
+ import * as graphql_language_ast from 'graphql/language/ast';
2
+ import { ApolloClient } from '@apollo/client/core';
3
+
4
+ declare const validatePreCheckoutMutation: graphql_language_ast.DocumentNode;
5
+ interface ValidatePreCheckoutData {
6
+ shop: {
7
+ id: string;
8
+ validatePreCheckout: Array<{
9
+ error: string;
10
+ success: boolean;
11
+ value: string;
12
+ }>;
13
+ } | null;
14
+ }
15
+ interface ValidatePreCheckoutOptions {
16
+ apollo: ApolloClient<any>;
17
+ emailAddress?: string;
18
+ emailOptIn?: boolean;
19
+ }
20
+ declare function validatePreCheckout({ apollo, emailAddress, emailOptIn, }: ValidatePreCheckoutOptions): Promise<void>;
21
+
22
+ export { ValidatePreCheckoutData, ValidatePreCheckoutOptions, validatePreCheckout, validatePreCheckoutMutation };
@@ -0,0 +1,13 @@
1
+ import {
2
+ validatePreCheckout,
3
+ validatePreCheckoutMutation
4
+ } from "./chunk-JBQ2KNMP.js";
5
+ import "./chunk-CBJJUUVR.js";
6
+ import "./chunk-2NC7LGGO.js";
7
+ import "./chunk-4ODZGLWK.js";
8
+ import "./chunk-TPJPGUO7.js";
9
+ import "./chunk-LZ4UMRCV.js";
10
+ export {
11
+ validatePreCheckout,
12
+ validatePreCheckoutMutation
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiva/kv-shop",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -53,5 +53,5 @@
53
53
  "optional": true
54
54
  }
55
55
  },
56
- "gitHead": "ee5a977ff10eaa7774d2d949e65fa90547e0f7a6"
56
+ "gitHead": "6eb24ec7efc9578791d30a312ec8a201c3934aa8"
57
57
  }