@kiva/kv-shop 1.3.1 → 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 +3 -3
  55. package/dist/chunk-M4CJOCIQ.js +0 -26
  56. package/dist/chunk-NC7RAUNV.js +0 -66
package/dist/index.d.ts CHANGED
@@ -1,9 +1,16 @@
1
- export { createBasket, getBasketID, getCookieValue, hasBasketExpired, setBasketID, setCookieValue } from './basket.js';
2
- export { SetTipDonationOptions, setTipDonation } from './basketItems.js';
3
- export { OneTimeCheckoutOptions, WaitOnTransactionOptions, executeOneTimeCheckout, waitOnTransaction } from './oneTimeCheckout.js';
1
+ export { createBasket, getBasketID, hasBasketExpired, setBasketID } from './basket.js';
2
+ export { ApplyKivaCreditData, RemoveKivaCreditData, applyKivaCredit, removeKivaCredit } from './basketCredits.js';
3
+ export { SetTipDonationData, SetTipDonationOptions, setTipDonation } from './basketItems.js';
4
+ export { BasketTotalsData, basketTotalsQuery, watchBasketTotals } from './basketTotals.js';
5
+ export { VerificationState, isBasketVerified } from './basketVerification.js';
6
+ export { CheckoutStatusQueryResult, GetCheckoutStatusOptions, PollForCheckoutStatusOptions, getCheckoutStatus, pollForFinishedCheckout } from './checkoutStatus.js';
7
+ export { OneTimeCheckoutOptions, executeOneTimeCheckout } from './oneTimeCheckout.js';
4
8
  export { ShopError, ShopErrorOptions, parseShopError } from './shopError.js';
9
+ export { callShopMutation, callShopQuery, watchShopQuery } from './shopQueries.js';
5
10
  export { SubscriptionCheckoutOptions, checkSubscriptionStatus, executeNewSubscriptionCheckout } from './subscriptionCheckout.js';
6
- export { DropInInitOptions, PayPalFlowType, PaymentType, defaultPaymentTypes, getClientToken, default as useBraintreeDropIn } from './useBraintreeDropIn.js';
11
+ export { DropInInitOptions, DropInWrapper, PayPalFlowType, PaymentType, defaultPaymentTypes, getClientToken, default as useBraintreeDropIn } from './useBraintreeDropIn.js';
12
+ export { ValidatePreCheckoutData, ValidatePreCheckoutOptions, validatePreCheckout, validatePreCheckoutMutation } from './validatePreCheckout.js';
7
13
  import '@apollo/client/core';
14
+ import 'graphql/language/ast';
8
15
  import 'braintree-web-drop-in';
9
- import '@vue/composition-api';
16
+ import 'vue-demi';
package/dist/index.js CHANGED
@@ -1,46 +1,80 @@
1
- import {
2
- setTipDonation
3
- } from "./chunk-NC7RAUNV.js";
4
- import {
5
- createBasket,
6
- getBasketID,
7
- getCookieValue,
8
- hasBasketExpired,
9
- setBasketID,
10
- setCookieValue
11
- } from "./chunk-B7RLQXI6.js";
12
- import {
13
- executeOneTimeCheckout,
14
- waitOnTransaction
15
- } from "./chunk-M4CJOCIQ.js";
16
1
  import {
17
2
  checkSubscriptionStatus,
18
3
  executeNewSubscriptionCheckout
19
- } from "./chunk-TIASV6B2.js";
4
+ } from "./chunk-KV4SOUVF.js";
20
5
  import {
21
6
  defaultPaymentTypes,
22
7
  getClientToken,
23
8
  useBraintreeDropIn
24
- } from "./chunk-SLMBU6L7.js";
9
+ } from "./chunk-JXQPCEKG.js";
10
+ import {
11
+ applyKivaCredit,
12
+ removeKivaCredit
13
+ } from "./chunk-MRCBNXPS.js";
14
+ import {
15
+ setTipDonation
16
+ } from "./chunk-AI6E33YE.js";
17
+ import {
18
+ basketTotalsQuery,
19
+ watchBasketTotals
20
+ } from "./chunk-DZGZX4F6.js";
21
+ import {
22
+ VerificationState,
23
+ isBasketVerified
24
+ } from "./chunk-FCAOCO7O.js";
25
+ import {
26
+ executeOneTimeCheckout
27
+ } from "./chunk-EJ5NGYPO.js";
28
+ import {
29
+ validatePreCheckout,
30
+ validatePreCheckoutMutation
31
+ } from "./chunk-JBQ2KNMP.js";
32
+ import {
33
+ callShopMutation,
34
+ callShopQuery,
35
+ watchShopQuery
36
+ } from "./chunk-CBJJUUVR.js";
37
+ import {
38
+ createBasket,
39
+ getBasketID,
40
+ hasBasketExpired,
41
+ setBasketID
42
+ } from "./chunk-2NC7LGGO.js";
25
43
  import {
26
44
  ShopError,
27
45
  parseShopError
28
- } from "./chunk-IYCMZ5WV.js";
46
+ } from "./chunk-4ODZGLWK.js";
47
+ import {
48
+ getCheckoutStatus,
49
+ pollForFinishedCheckout
50
+ } from "./chunk-PC4WUPYU.js";
51
+ import "./chunk-TPJPGUO7.js";
52
+ import "./chunk-LZ4UMRCV.js";
29
53
  export {
30
54
  ShopError,
55
+ VerificationState,
56
+ applyKivaCredit,
57
+ basketTotalsQuery,
58
+ callShopMutation,
59
+ callShopQuery,
31
60
  checkSubscriptionStatus,
32
61
  createBasket,
33
62
  defaultPaymentTypes,
34
63
  executeNewSubscriptionCheckout,
35
64
  executeOneTimeCheckout,
36
65
  getBasketID,
66
+ getCheckoutStatus,
37
67
  getClientToken,
38
- getCookieValue,
39
68
  hasBasketExpired,
69
+ isBasketVerified,
40
70
  parseShopError,
71
+ pollForFinishedCheckout,
72
+ removeKivaCredit,
41
73
  setBasketID,
42
- setCookieValue,
43
74
  setTipDonation,
44
75
  useBraintreeDropIn,
45
- waitOnTransaction
76
+ validatePreCheckout,
77
+ validatePreCheckoutMutation,
78
+ watchBasketTotals,
79
+ watchShopQuery
46
80
  };
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -14,37 +16,422 @@ var __copyProps = (to, from, except, desc) => {
14
16
  }
15
17
  return to;
16
18
  };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
17
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
28
 
19
29
  // src/oneTimeCheckout.ts
20
30
  var oneTimeCheckout_exports = {};
21
31
  __export(oneTimeCheckout_exports, {
22
- executeOneTimeCheckout: () => executeOneTimeCheckout,
23
- waitOnTransaction: () => waitOnTransaction
32
+ executeOneTimeCheckout: () => executeOneTimeCheckout
24
33
  });
25
34
  module.exports = __toCommonJS(oneTimeCheckout_exports);
35
+ var import_core4 = require("@apollo/client/core");
36
+ var import_numeral = __toESM(require("numeral"), 1);
37
+
38
+ // src/checkoutStatus.ts
26
39
  var import_core = require("@apollo/client/core");
27
- async function executeOneTimeCheckout({ apollo }) {
40
+
41
+ // src/util/poll.ts
42
+ function wait(ms) {
43
+ return new Promise((resolve) => setTimeout(resolve, ms));
44
+ }
45
+ async function poll(fn, fnCondition, interval, timeout) {
46
+ const endTime = Date.now() + timeout;
47
+ let result = await fn();
48
+ while (!fnCondition(result)) {
49
+ if (Date.now() > endTime) {
50
+ throw new Error("Polling timed out");
51
+ }
52
+ await wait(interval);
53
+ result = await fn();
54
+ }
55
+ return result;
56
+ }
57
+
58
+ // src/util/cookie.ts
59
+ var getCookieValue = (name) => {
60
+ if (typeof document !== void 0) {
61
+ return decodeURIComponent(document.cookie.match(`(^|;)\\s*${name}\\s*=\\s*([^;]+)`)?.pop() || "");
62
+ }
63
+ };
64
+ var setCookieValue = (name, value, options = "") => {
65
+ if (typeof document !== void 0) {
66
+ document.cookie = `${name}=${encodeURIComponent(value)};${options}`;
67
+ }
68
+ };
69
+
70
+ // src/util/visitorId.ts
71
+ function getVisitorID() {
72
+ return getCookieValue("uiv");
28
73
  }
29
- async function waitOnTransaction({ apollo, transactionId }) {
30
- const result = await apollo.query({
74
+
75
+ // src/checkoutStatus.ts
76
+ async function getCheckoutStatus({ apollo, transactionSagaId }) {
77
+ return apollo.query({
31
78
  query: import_core.gql`
32
- query checkoutStatus($transactionId: String!, $visitorId: string) {
79
+ query checkoutStatus($transactionId: String!, $visitorId: String) {
33
80
  checkoutStatus(transactionId: $transactionId, visitorId: $visitorId) {
81
+ basketId
34
82
  errorCode
35
83
  errorMessage
84
+ receipt {
85
+ checkoutId
86
+ }
87
+ requestedAt
36
88
  status
37
89
  transactionId
90
+ updatedAt
38
91
  }
39
92
  }
40
93
  `,
41
94
  variables: {
42
- transactionId
95
+ transactionId: transactionSagaId,
96
+ visitorId: getVisitorID()
97
+ }
98
+ });
99
+ }
100
+ async function pollForFinishedCheckout({
101
+ apollo,
102
+ transactionSagaId,
103
+ interval = 1e3,
104
+ timeout = 6e4
105
+ }) {
106
+ return poll(
107
+ // function to poll
108
+ () => getCheckoutStatus({
109
+ apollo,
110
+ transactionSagaId
111
+ }),
112
+ // function to check for completed status
113
+ (result) => {
114
+ const { status, errorCode, errorMessage } = result?.data?.checkoutStatus;
115
+ if (status === "COMPLETED" || errorCode || errorMessage) {
116
+ return true;
117
+ }
118
+ return false;
119
+ },
120
+ interval,
121
+ timeout
122
+ );
123
+ }
124
+
125
+ // src/shopError.ts
126
+ var ShopError = class extends Error {
127
+ constructor({ code, original }, ...params) {
128
+ super(...params);
129
+ if (Error.captureStackTrace) {
130
+ Error.captureStackTrace(this, ShopError);
131
+ }
132
+ this.name = "ShopError";
133
+ this.code = code;
134
+ this.original = original;
135
+ }
136
+ aggregateErrors(errors) {
137
+ this.errors = errors;
138
+ }
139
+ };
140
+ function parseShopError(error) {
141
+ if (error instanceof ShopError) {
142
+ return error;
143
+ }
144
+ const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
145
+ const errorMessage = typeof error === "string" ? error : error?.message ?? "";
146
+ if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
147
+ return new ShopError({
148
+ code: "paymentMethod.create.invalidMethodParameter",
149
+ original: error
150
+ }, "There was a problem validating your payment information. Please double-check the details and try again.");
151
+ }
152
+ if (errorMessage.includes("Invalid request: ")) {
153
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
154
+ const finalCode = finalError[1];
155
+ const finalMessage = finalError[2];
156
+ return new ShopError({
157
+ code: `paymentMethod.${finalCode}`,
158
+ original: error
159
+ }, finalMessage);
160
+ }
161
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
162
+ return new ShopError({
163
+ code: "shop.insufficientFunds",
164
+ original: error
165
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
166
+ }
167
+ if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
168
+ return new ShopError({
169
+ code: errorCode,
170
+ original: error
171
+ }, "There was a problem with your basket. Please, refresh the page and try again.");
172
+ }
173
+ if (errorCode === "donationAmountTooLarge") {
174
+ return new ShopError({
175
+ code: errorCode,
176
+ original: error
177
+ }, errorMessage);
178
+ }
179
+ return new ShopError({
180
+ code: "shop.unknown",
181
+ original: error
182
+ }, "An unknown error occurred.");
183
+ }
184
+
185
+ // src/basket.ts
186
+ var import_core2 = require("@apollo/client/core");
187
+ function getBasketID() {
188
+ return getCookieValue("kvbskt");
189
+ }
190
+ function setBasketID(basketId) {
191
+ setCookieValue("kvbskt", basketId, "path=/;secure;");
192
+ }
193
+ async function createBasketHelper(apollo) {
194
+ try {
195
+ return apollo.mutate({
196
+ mutation: import_core2.gql`mutation createNewBasketForUser { shop { id createBasket } }`
197
+ }).then(({ data }) => {
198
+ const newBasketId = data.shop?.createBasket ?? null;
199
+ if (newBasketId) {
200
+ setBasketID(newBasketId);
201
+ }
202
+ });
203
+ } catch (error) {
204
+ throw parseShopError(error);
205
+ }
206
+ }
207
+ var activeBasketCreationQuery = null;
208
+ async function createBasket(apollo) {
209
+ if (activeBasketCreationQuery) {
210
+ return activeBasketCreationQuery;
211
+ }
212
+ activeBasketCreationQuery = createBasketHelper(apollo);
213
+ return activeBasketCreationQuery;
214
+ }
215
+ function hasBasketExpired(error) {
216
+ const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
217
+ return ["shop.invalidBasketId", "shop.basketRequired", "shop.alreadyCheckedOut"].includes(errorCode);
218
+ }
219
+
220
+ // src/shopQueries.ts
221
+ var watchQueries = /* @__PURE__ */ new Set();
222
+ async function callShopMutation(apollo, options, maxretries = 2) {
223
+ try {
224
+ const result = await apollo.mutate({
225
+ ...options,
226
+ variables: {
227
+ ...options.variables,
228
+ basketId: getBasketID()
229
+ },
230
+ refetchQueries: options.awaitRefetchQueries ? Array.from(watchQueries) : []
231
+ });
232
+ if (result?.errors?.length) {
233
+ const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
234
+ if (basketErrors.length) {
235
+ if (maxretries > 0) {
236
+ await createBasket(apollo);
237
+ return callShopMutation(apollo, options, maxretries - 1);
238
+ }
239
+ throw basketErrors[0];
240
+ }
241
+ if (result?.errors?.length) {
242
+ throw result.errors[0];
243
+ }
244
+ }
245
+ return result?.data;
246
+ } catch (e) {
247
+ throw parseShopError(e);
248
+ }
249
+ }
250
+ async function callShopQuery(apollo, options, maxretries = 2) {
251
+ try {
252
+ const result = await apollo.query({
253
+ ...options,
254
+ variables: {
255
+ ...options.variables,
256
+ basketId: getBasketID()
257
+ }
258
+ });
259
+ if (result?.errors?.length) {
260
+ const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
261
+ if (basketErrors.length) {
262
+ if (maxretries > 0) {
263
+ await createBasket(apollo);
264
+ return callShopQuery(apollo, options, maxretries - 1);
265
+ }
266
+ throw basketErrors[0];
267
+ }
268
+ if (result?.errors?.length) {
269
+ throw result.errors[0];
270
+ }
271
+ }
272
+ return result?.data;
273
+ } catch (e) {
274
+ throw parseShopError(e);
275
+ }
276
+ }
277
+
278
+ // src/validatePreCheckout.ts
279
+ var import_core3 = require("@apollo/client/core");
280
+ var validatePreCheckoutMutation = import_core3.gql`
281
+ mutation validatePreCheckout($basketId: String, $email: String, $visitorId: String, $emailOptIn: Boolean) {
282
+ shop (basketId: $basketId) {
283
+ id
284
+ validatePreCheckout (email: $email, visitorId: $visitorId, emailOptIn: $emailOptIn) {
285
+ error
286
+ success
287
+ value
288
+ }
289
+ }
290
+ }`;
291
+ async function validatePreCheckout({
292
+ apollo,
293
+ emailAddress,
294
+ emailOptIn
295
+ }) {
296
+ const data = await callShopMutation(apollo, {
297
+ mutation: validatePreCheckoutMutation,
298
+ variables: {
299
+ visitorId: getVisitorID(),
300
+ email: emailAddress,
301
+ emailOptIn
43
302
  }
303
+ }, 0);
304
+ const results = data?.shop?.validatePreCheckout;
305
+ const errors = results.filter(({ success }) => !success).map((result) => parseShopError(result));
306
+ if (errors.length) {
307
+ const aggregate = new ShopError({ code: "shop.failedCheckoutValidation" });
308
+ aggregate.aggregateErrors(errors);
309
+ throw aggregate;
310
+ }
311
+ }
312
+
313
+ // src/oneTimeCheckout.ts
314
+ async function creditAmountNeeded(apollo) {
315
+ const data = await callShopQuery(apollo, {
316
+ query: import_core4.gql`
317
+ query creditAmountNeeded($basketId: String) {
318
+ shop (basketId: $basketId) {
319
+ id
320
+ basket {
321
+ id
322
+ totals {
323
+ creditAmountNeeded
324
+ }
325
+ }
326
+ }
327
+ }
328
+ `
329
+ }, 0);
330
+ return data?.shop?.basket?.totals?.creditAmountNeeded;
331
+ }
332
+ var creditCheckoutMutation = import_core4.gql`
333
+ mutation creditCheckout(
334
+ $basketId: String,
335
+ $visitorId: String
336
+ ) {
337
+ shop (basketId: $basketId) {
338
+ id
339
+ transactionId: checkoutAsync (visitorId: $visitorId)
340
+ }
341
+ }
342
+ `;
343
+ var depositCheckoutMutation = import_core4.gql`
344
+ mutation depositCheckout(
345
+ $basketId: String,
346
+ $amount: Money!,
347
+ $nonce: String!,
348
+ $savePaymentMethod: Boolean,
349
+ $deviceData: String,
350
+ $visitorId: String
351
+ ) {
352
+ shop (basketId: $basketId) {
353
+ id
354
+ transactionId: doNoncePaymentDepositAndCheckoutAsync(
355
+ amount: $amount,
356
+ nonce: $nonce,
357
+ savePaymentMethod: $savePaymentMethod,
358
+ deviceData: $deviceData,
359
+ visitorId: $visitorId
360
+ )
361
+ }
362
+ }
363
+ `;
364
+ function creditCheckout(apollo) {
365
+ return callShopMutation(apollo, {
366
+ mutation: creditCheckoutMutation,
367
+ variables: {
368
+ visitorId: getVisitorID()
369
+ }
370
+ }, 0);
371
+ }
372
+ async function depositCheckout({
373
+ apollo,
374
+ braintree,
375
+ amount
376
+ }) {
377
+ try {
378
+ const paymentMethod = await braintree.requestPaymentMethod();
379
+ if (!paymentMethod) {
380
+ throw new ShopError(
381
+ { code: "shop.dropinNoPaymentMethod" },
382
+ "No payment method returned from braintree dropin"
383
+ );
384
+ }
385
+ const { nonce, deviceData } = paymentMethod;
386
+ return callShopMutation(apollo, {
387
+ mutation: depositCheckoutMutation,
388
+ variables: {
389
+ nonce,
390
+ amount,
391
+ savePaymentMethod: false,
392
+ // save payment methods handled by braintree drop in UI
393
+ deviceData,
394
+ visitorId: getVisitorID()
395
+ }
396
+ }, 0);
397
+ } catch (e) {
398
+ throw parseShopError(e);
399
+ }
400
+ }
401
+ async function executeOneTimeCheckout({
402
+ apollo,
403
+ braintree,
404
+ emailAddress,
405
+ emailOptIn
406
+ }) {
407
+ await validatePreCheckout({
408
+ apollo,
409
+ emailAddress,
410
+ emailOptIn
44
411
  });
412
+ const creditNeeded = await creditAmountNeeded(apollo);
413
+ const creditRequired = (0, import_numeral.default)(creditNeeded).value() > 0;
414
+ if (creditRequired && !braintree) {
415
+ throw new ShopError({ code: "shop.dropinRequired" }, "Braintree dropin required for credit deposit checkout");
416
+ }
417
+ const data = creditRequired ? await depositCheckout({
418
+ apollo,
419
+ braintree,
420
+ amount: creditNeeded
421
+ }) : await creditCheckout(apollo);
422
+ const transactionId = data?.shop?.transactionId;
423
+ const result = await pollForFinishedCheckout({
424
+ apollo,
425
+ transactionSagaId: transactionId,
426
+ timeout: 3e5
427
+ // five minutes
428
+ });
429
+ if (result.errors?.length) {
430
+ throw parseShopError(result.errors[0]);
431
+ }
432
+ window.location.href = `/checkout/post-purchase?kiva_transaction_id=${transactionId}`;
45
433
  }
46
434
  // Annotate the CommonJS export names for ESM import in node:
47
435
  0 && (module.exports = {
48
- executeOneTimeCheckout,
49
- waitOnTransaction
436
+ executeOneTimeCheckout
50
437
  });
@@ -1,13 +1,14 @@
1
+ import { ApolloClient } from '@apollo/client/core';
2
+ import { DropInWrapper } from './useBraintreeDropIn.js';
3
+ import 'vue-demi';
4
+ import 'braintree-web-drop-in';
5
+
1
6
  interface OneTimeCheckoutOptions {
2
- apollo: any;
3
- basketId: string;
4
- visitorId: string | null | undefined;
5
- }
6
- declare function executeOneTimeCheckout({ apollo }: OneTimeCheckoutOptions): Promise<void>;
7
- interface WaitOnTransactionOptions {
8
- apollo: any;
9
- transactionId: string;
7
+ apollo: ApolloClient<any>;
8
+ braintree?: DropInWrapper;
9
+ emailAddress?: string;
10
+ emailOptIn?: boolean;
10
11
  }
11
- declare function waitOnTransaction({ apollo, transactionId }: WaitOnTransactionOptions): Promise<void>;
12
+ declare function executeOneTimeCheckout({ apollo, braintree, emailAddress, emailOptIn, }: OneTimeCheckoutOptions): Promise<void>;
12
13
 
13
- export { OneTimeCheckoutOptions, WaitOnTransactionOptions, executeOneTimeCheckout, waitOnTransaction };
14
+ export { OneTimeCheckoutOptions, executeOneTimeCheckout };
@@ -1,8 +1,13 @@
1
1
  import {
2
- executeOneTimeCheckout,
3
- waitOnTransaction
4
- } from "./chunk-M4CJOCIQ.js";
2
+ executeOneTimeCheckout
3
+ } from "./chunk-EJ5NGYPO.js";
4
+ import "./chunk-JBQ2KNMP.js";
5
+ import "./chunk-CBJJUUVR.js";
6
+ import "./chunk-2NC7LGGO.js";
7
+ import "./chunk-4ODZGLWK.js";
8
+ import "./chunk-PC4WUPYU.js";
9
+ import "./chunk-TPJPGUO7.js";
10
+ import "./chunk-LZ4UMRCV.js";
5
11
  export {
6
- executeOneTimeCheckout,
7
- waitOnTransaction
12
+ executeOneTimeCheckout
8
13
  };
@@ -33,8 +33,14 @@ var ShopError = class extends Error {
33
33
  this.code = code;
34
34
  this.original = original;
35
35
  }
36
+ aggregateErrors(errors) {
37
+ this.errors = errors;
38
+ }
36
39
  };
37
40
  function parseShopError(error) {
41
+ if (error instanceof ShopError) {
42
+ return error;
43
+ }
38
44
  const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
39
45
  const errorMessage = typeof error === "string" ? error : error?.message ?? "";
40
46
  if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
@@ -43,6 +49,21 @@ function parseShopError(error) {
43
49
  original: error
44
50
  }, "There was a problem validating your payment information. Please double-check the details and try again.");
45
51
  }
52
+ if (errorMessage.includes("Invalid request: ")) {
53
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
54
+ const finalCode = finalError[1];
55
+ const finalMessage = finalError[2];
56
+ return new ShopError({
57
+ code: `paymentMethod.${finalCode}`,
58
+ original: error
59
+ }, finalMessage);
60
+ }
61
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
62
+ return new ShopError({
63
+ code: "shop.insufficientFunds",
64
+ original: error
65
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
66
+ }
46
67
  if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
47
68
  return new ShopError({
48
69
  code: errorCode,
@@ -5,7 +5,9 @@ interface ShopErrorOptions {
5
5
  declare class ShopError extends Error {
6
6
  code: string;
7
7
  original?: object;
8
+ errors?: Array<ShopError>;
8
9
  constructor({ code, original }: ShopErrorOptions, ...params: any[]);
10
+ aggregateErrors(errors: Array<ShopError>): void;
9
11
  }
10
12
  declare function parseShopError(error: any): ShopError;
11
13
 
package/dist/shopError.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ShopError,
3
3
  parseShopError
4
- } from "./chunk-IYCMZ5WV.js";
4
+ } from "./chunk-4ODZGLWK.js";
5
5
  export {
6
6
  ShopError,
7
7
  parseShopError