@merchi/cart 1.4.4 → 1.4.6

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 (49) hide show
  1. package/esm/CartProvider.js +58 -20
  2. package/esm/forms/FormShipmentAddressAndNotes.js +24 -3
  3. package/esm/stripe/LegacyStripeCardForm.js +11 -4
  4. package/esm/stripe/StripeCardForm.js +122 -16
  5. package/esm/stripe/actions.js +155 -57
  6. package/esm/stripe/actions.test.js +120 -0
  7. package/esm/utilities/cookie.js +15 -12
  8. package/esm/utilities/index.js +2 -0
  9. package/esm/utilities/job_source.js +139 -0
  10. package/esm/utilities/job_source.test.js +75 -0
  11. package/esm/utilities/shipment.js +22 -0
  12. package/esm/utilities/shipment.test.js +60 -0
  13. package/esm/utilities/test_checkout.js +25 -0
  14. package/esm/utilities/test_checkout.test.js +31 -0
  15. package/lib/CartProvider.js +58 -20
  16. package/lib/forms/FormShipmentAddressAndNotes.js +22 -1
  17. package/lib/stripe/LegacyStripeCardForm.js +10 -3
  18. package/lib/stripe/StripeCardForm.js +123 -17
  19. package/lib/stripe/actions.d.ts +2 -0
  20. package/lib/stripe/actions.js +157 -57
  21. package/lib/stripe/actions.test.d.ts +1 -0
  22. package/lib/utilities/cookie.d.ts +3 -3
  23. package/lib/utilities/cookie.js +15 -12
  24. package/lib/utilities/index.d.ts +2 -0
  25. package/lib/utilities/index.js +22 -0
  26. package/lib/utilities/job_source.d.ts +23 -0
  27. package/lib/utilities/job_source.js +152 -0
  28. package/lib/utilities/job_source.test.d.ts +1 -0
  29. package/lib/utilities/shipment.d.ts +15 -0
  30. package/lib/utilities/shipment.js +24 -0
  31. package/lib/utilities/shipment.test.d.ts +1 -0
  32. package/lib/utilities/test_checkout.d.ts +6 -0
  33. package/lib/utilities/test_checkout.js +34 -0
  34. package/lib/utilities/test_checkout.test.d.ts +1 -0
  35. package/package.json +8 -5
  36. package/src/CartProvider.tsx +42 -4
  37. package/src/forms/FormShipmentAddressAndNotes.tsx +34 -2
  38. package/src/stripe/LegacyStripeCardForm.tsx +9 -3
  39. package/src/stripe/StripeCardForm.tsx +92 -8
  40. package/src/stripe/actions.test.ts +50 -0
  41. package/src/stripe/actions.ts +41 -0
  42. package/src/utilities/cookie.ts +9 -6
  43. package/src/utilities/index.ts +2 -0
  44. package/src/utilities/job_source.test.ts +86 -0
  45. package/src/utilities/job_source.ts +165 -0
  46. package/src/utilities/shipment.test.ts +68 -0
  47. package/src/utilities/shipment.ts +34 -0
  48. package/src/utilities/test_checkout.test.ts +39 -0
  49. package/src/utilities/test_checkout.ts +27 -0
@@ -0,0 +1,139 @@
1
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
4
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
5
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
9
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
11
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
12
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
13
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
14
+ export var JOB_SOURCE_STORAGE_KEY = 'merchi_job_source';
15
+ var CLICK_ID_PARAMS = ['gclid', 'gbraid', 'wbraid', 'fbclid', 'msclkid'];
16
+ var UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
17
+ function trimTo(value, limit) {
18
+ if (!value) return undefined;
19
+ var text = value.trim().slice(0, limit);
20
+ return text || undefined;
21
+ }
22
+ function readSearchParams() {
23
+ if (typeof window === 'undefined') return new URLSearchParams();
24
+ try {
25
+ return new URLSearchParams(window.location.search);
26
+ } catch (_unused) {
27
+ return new URLSearchParams();
28
+ }
29
+ }
30
+ function readStoredSource() {
31
+ if (typeof window === 'undefined') return null;
32
+ try {
33
+ var raw = window.localStorage.getItem(JOB_SOURCE_STORAGE_KEY);
34
+ if (!raw) return null;
35
+ var parsed = JSON.parse(raw);
36
+ if (!parsed || _typeof(parsed) !== 'object') return null;
37
+ return parsed;
38
+ } catch (_unused2) {
39
+ return null;
40
+ }
41
+ }
42
+ function writeStoredSource(source) {
43
+ if (typeof window === 'undefined') return;
44
+ try {
45
+ window.localStorage.setItem(JOB_SOURCE_STORAGE_KEY, JSON.stringify(source));
46
+ } catch (_unused3) {
47
+ // Ignore quota / private-mode failures.
48
+ }
49
+ }
50
+ function currentLanding() {
51
+ if (typeof window === 'undefined') return undefined;
52
+ try {
53
+ var path = "".concat(window.location.pathname || '/').concat(window.location.search || '');
54
+ return trimTo(path, 512);
55
+ } catch (_unused4) {
56
+ return undefined;
57
+ }
58
+ }
59
+ function currentReferrer() {
60
+ if (typeof document === 'undefined') return undefined;
61
+ try {
62
+ return trimTo(document.referrer, 512);
63
+ } catch (_unused5) {
64
+ return undefined;
65
+ }
66
+ }
67
+ export function sourceFromLocation() {
68
+ var params = readSearchParams();
69
+ var source = {
70
+ utmSource: trimTo(params.get('utm_source'), 256),
71
+ utmMedium: trimTo(params.get('utm_medium'), 256),
72
+ utmCampaign: trimTo(params.get('utm_campaign'), 256),
73
+ utmContent: trimTo(params.get('utm_content'), 256),
74
+ utmTerm: trimTo(params.get('utm_term'), 256),
75
+ sourceLanding: currentLanding(),
76
+ sourceReferrer: currentReferrer()
77
+ };
78
+ var _iterator = _createForOfIteratorHelper(CLICK_ID_PARAMS),
79
+ _step;
80
+ try {
81
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
82
+ var key = _step.value;
83
+ var value = trimTo(params.get(key), 256);
84
+ if (value) {
85
+ source.sourceClickId = value;
86
+ break;
87
+ }
88
+ }
89
+ } catch (err) {
90
+ _iterator.e(err);
91
+ } finally {
92
+ _iterator.f();
93
+ }
94
+ return source;
95
+ }
96
+ export function hasPaidClick(source) {
97
+ return Boolean(source === null || source === void 0 ? void 0 : source.sourceClickId);
98
+ }
99
+ export function hasSourceData(source) {
100
+ if (!source) return false;
101
+ return Boolean(source.utmSource || source.utmMedium || source.utmCampaign || source.utmContent || source.utmTerm || source.sourceClickId || source.sourceLanding || source.sourceReferrer);
102
+ }
103
+ export function captureAndReadJobSource() {
104
+ var incoming = sourceFromLocation();
105
+ var stored = readStoredSource();
106
+ if (hasPaidClick(incoming) || !hasSourceData(stored)) {
107
+ var next = _objectSpread(_objectSpread({}, stored || {}), Object.fromEntries(Object.entries(incoming).filter(function (_ref) {
108
+ var _ref2 = _slicedToArray(_ref, 2),
109
+ value = _ref2[1];
110
+ return Boolean(value);
111
+ })));
112
+ if (hasSourceData(next)) writeStoredSource(next);
113
+ return next;
114
+ }
115
+ return stored || incoming;
116
+ }
117
+ export function jobSourceFieldsForApi(source) {
118
+ var resolved = source || captureAndReadJobSource();
119
+ var out = {};
120
+ Object.keys(resolved).forEach(function (key) {
121
+ var value = resolved[key];
122
+ if (value) out[key] = value;
123
+ });
124
+ return out;
125
+ }
126
+ export function cartNeedsSourceUpdate(cart, source) {
127
+ if (!hasSourceData(source)) return false;
128
+ if (!(cart !== null && cart !== void 0 && cart.utmSource) && !(cart !== null && cart !== void 0 && cart.sourceClickId) && !(cart !== null && cart !== void 0 && cart.sourceChannel)) return true;
129
+ return Boolean(source.sourceClickId && !(cart !== null && cart !== void 0 && cart.sourceClickId));
130
+ }
131
+ export var JOB_SOURCE_URL_KEYS = [].concat(UTM_PARAMS, CLICK_ID_PARAMS);
132
+ export function appendJobSourceToFormData(data, source) {
133
+ var fields = jobSourceFieldsForApi(source);
134
+ Object.keys(fields).forEach(function (key) {
135
+ var value = fields[key];
136
+ if (value) data.append(key, value);
137
+ });
138
+ return data;
139
+ }
@@ -0,0 +1,75 @@
1
+ import { JOB_SOURCE_STORAGE_KEY, captureAndReadJobSource, cartNeedsSourceUpdate, hasPaidClick } from './job_source';
2
+ describe('job source capture', function () {
3
+ var originalLocation = window.location;
4
+ var originalReferrer = document.referrer;
5
+ beforeEach(function () {
6
+ window.localStorage.clear();
7
+ delete window.location;
8
+ window.location = {
9
+ search: '',
10
+ pathname: '/tyvek-wristbands'
11
+ };
12
+ Object.defineProperty(document, 'referrer', {
13
+ configurable: true,
14
+ value: ''
15
+ });
16
+ });
17
+ afterEach(function () {
18
+ window.location = originalLocation;
19
+ Object.defineProperty(document, 'referrer', {
20
+ configurable: true,
21
+ value: originalReferrer
22
+ });
23
+ window.localStorage.clear();
24
+ });
25
+ it('captures google ads click ids and landing path', function () {
26
+ window.location = {
27
+ search: '?utm_source=google&utm_medium=cpc&gclid=EAIa&utm_campaign=bands',
28
+ pathname: '/tyvek-wristbands'
29
+ };
30
+ var source = captureAndReadJobSource();
31
+ expect(source.utmSource).toBe('google');
32
+ expect(source.utmMedium).toBe('cpc');
33
+ expect(source.utmCampaign).toBe('bands');
34
+ expect(source.sourceClickId).toBe('EAIa');
35
+ expect(source.sourceLanding).toBe('/tyvek-wristbands?utm_source=google&utm_medium=cpc&gclid=EAIa&utm_campaign=bands');
36
+ expect(hasPaidClick(source)).toBe(true);
37
+ });
38
+ it('keeps first-touch UTMs unless a paid click arrives later', function () {
39
+ window.location = {
40
+ search: '?utm_source=newsletter&utm_medium=email',
41
+ pathname: '/'
42
+ };
43
+ captureAndReadJobSource();
44
+ window.location = {
45
+ search: '?utm_source=google&utm_medium=cpc',
46
+ pathname: '/product'
47
+ };
48
+ expect(captureAndReadJobSource().utmSource).toBe('newsletter');
49
+ window.location = {
50
+ search: '?gclid=NEWCLICK&utm_source=google',
51
+ pathname: '/product'
52
+ };
53
+ expect(captureAndReadJobSource().sourceClickId).toBe('NEWCLICK');
54
+ expect(window.localStorage.getItem(JOB_SOURCE_STORAGE_KEY)).toContain('NEWCLICK');
55
+ });
56
+ it('knows when an existing cart still needs source fields', function () {
57
+ expect(cartNeedsSourceUpdate({}, {
58
+ utmSource: 'google',
59
+ sourceClickId: 'x'
60
+ })).toBe(true);
61
+ expect(cartNeedsSourceUpdate({
62
+ utmSource: 'google'
63
+ }, {
64
+ utmSource: 'google',
65
+ sourceClickId: 'x'
66
+ })).toBe(true);
67
+ expect(cartNeedsSourceUpdate({
68
+ utmSource: 'google',
69
+ sourceClickId: 'x'
70
+ }, {
71
+ utmSource: 'google',
72
+ sourceClickId: 'x'
73
+ })).toBe(false);
74
+ });
75
+ });
@@ -1,3 +1,4 @@
1
+ import { addressHasContent } from './local_storage';
1
2
  export var shipmentFormId = '_shipment-address-form-id';
2
3
  export function cartItemsNeedShipment(cart) {
3
4
  var _cart$cartItems = cart.cartItems,
@@ -8,4 +9,25 @@ export function cartItemsNeedShipment(cart) {
8
9
  }
9
10
  }
10
11
  return false;
12
+ }
13
+ export function shipmentGroupsHaveQuotes(groups) {
14
+ if (!(groups !== null && groups !== void 0 && groups.length)) return false;
15
+ return groups.some(function (group) {
16
+ return Array.isArray(group === null || group === void 0 ? void 0 : group.quotes) && group.quotes.length > 0;
17
+ });
18
+ }
19
+ /**
20
+ * When checkout hydrates a saved address (localStorage) the form shows it,
21
+ * but quotes are only fetched after the user edits the field. Returning
22
+ * `apply-saved-address` means the cart still needs that address applied so
23
+ * quotes can be generated; `refresh-quotes` means the cart already has an
24
+ * address but no usable shipment options.
25
+ */
26
+ export function checkoutShipmentHydrationAction(options) {
27
+ var hasCartAddress = addressHasContent(options.cartAddress);
28
+ var hasSavedAddress = addressHasContent(options.savedAddress);
29
+ var hasQuotes = shipmentGroupsHaveQuotes(options.shipmentGroups);
30
+ if (!hasCartAddress && hasSavedAddress) return 'apply-saved-address';
31
+ if (hasCartAddress && !hasQuotes) return 'refresh-quotes';
32
+ return null;
11
33
  }
@@ -0,0 +1,60 @@
1
+ import { checkoutShipmentHydrationAction, shipmentGroupsHaveQuotes } from './shipment';
2
+ var savedAddress = {
3
+ lineOne: '32 Bridge St',
4
+ city: 'Brighton',
5
+ state: 'VIC',
6
+ postcode: '3186',
7
+ country: 'AU'
8
+ };
9
+ describe('shipmentGroupsHaveQuotes', function () {
10
+ it('is false when groups are missing or empty', function () {
11
+ expect(shipmentGroupsHaveQuotes(undefined)).toBe(false);
12
+ expect(shipmentGroupsHaveQuotes([])).toBe(false);
13
+ expect(shipmentGroupsHaveQuotes([{
14
+ quotes: []
15
+ }])).toBe(false);
16
+ });
17
+ it('is true when any group has quotes', function () {
18
+ expect(shipmentGroupsHaveQuotes([{
19
+ quotes: []
20
+ }, {
21
+ quotes: [{
22
+ id: 1
23
+ }]
24
+ }])).toBe(true);
25
+ });
26
+ });
27
+ describe('checkoutShipmentHydrationAction', function () {
28
+ it('applies a localStorage address when the cart has none', function () {
29
+ expect(checkoutShipmentHydrationAction({
30
+ cartAddress: {},
31
+ savedAddress: savedAddress,
32
+ shipmentGroups: []
33
+ })).toBe('apply-saved-address');
34
+ });
35
+ it('refreshes quotes when the cart already has an address but no options', function () {
36
+ expect(checkoutShipmentHydrationAction({
37
+ cartAddress: savedAddress,
38
+ savedAddress: savedAddress,
39
+ shipmentGroups: []
40
+ })).toBe('refresh-quotes');
41
+ });
42
+ it('does nothing when quotes are already available', function () {
43
+ expect(checkoutShipmentHydrationAction({
44
+ cartAddress: savedAddress,
45
+ savedAddress: savedAddress,
46
+ shipmentGroups: [{
47
+ quotes: [{
48
+ id: 9
49
+ }]
50
+ }]
51
+ })).toBe(null);
52
+ });
53
+ it('does nothing when neither cart nor localStorage has an address', function () {
54
+ expect(checkoutShipmentHydrationAction({
55
+ cartAddress: {},
56
+ savedAddress: {},
57
+ shipmentGroups: []
58
+ })).toBe(null);
59
+ });
60
+ });
@@ -0,0 +1,25 @@
1
+ export var TEST_CHECKOUT_QUERY = 'merchi_test_checkout';
2
+ export var TEST_CHECKOUT_STORAGE_KEY = 'merchi_test_checkout';
3
+ export var TEST_CARD_NUMBER = '4242 4242 4242 4242';
4
+ export function readTestCheckoutFlag() {
5
+ if (typeof window === 'undefined') {
6
+ return false;
7
+ }
8
+ try {
9
+ var params = new URLSearchParams(window.location.search);
10
+ if (params.get(TEST_CHECKOUT_QUERY) === '1') {
11
+ window.localStorage.setItem(TEST_CHECKOUT_STORAGE_KEY, '1');
12
+ return true;
13
+ }
14
+ return window.localStorage.getItem(TEST_CHECKOUT_STORAGE_KEY) === '1';
15
+ } catch (_unused) {
16
+ return false;
17
+ }
18
+ }
19
+ export function persistTestCheckoutFlag() {
20
+ return readTestCheckoutFlag();
21
+ }
22
+ export function cartCookieName(domainId) {
23
+ var isTest = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
24
+ return isTest ? "cart-".concat(domainId, "-test") : "cart-".concat(domainId);
25
+ }
@@ -0,0 +1,31 @@
1
+ import { TEST_CARD_NUMBER, TEST_CHECKOUT_QUERY, TEST_CHECKOUT_STORAGE_KEY, cartCookieName, readTestCheckoutFlag } from './test_checkout';
2
+ describe('test checkout helpers', function () {
3
+ var originalLocation = window.location;
4
+ beforeEach(function () {
5
+ window.localStorage.clear();
6
+ delete window.location;
7
+ window.location = {
8
+ search: ''
9
+ };
10
+ });
11
+ afterEach(function () {
12
+ window.location = originalLocation;
13
+ window.localStorage.clear();
14
+ });
15
+ it('builds a separate cookie name for test carts', function () {
16
+ expect(cartCookieName(12)).toBe('cart-12');
17
+ expect(cartCookieName(12, true)).toBe('cart-12-test');
18
+ });
19
+ it('persists the query flag and exposes the test card number', function () {
20
+ window.location = {
21
+ search: "?".concat(TEST_CHECKOUT_QUERY, "=1")
22
+ };
23
+ expect(readTestCheckoutFlag()).toBe(true);
24
+ expect(window.localStorage.getItem(TEST_CHECKOUT_STORAGE_KEY)).toBe('1');
25
+ expect(TEST_CARD_NUMBER).toBe('4242 4242 4242 4242');
26
+ });
27
+ it('reads the stored flag when the query is absent', function () {
28
+ window.localStorage.setItem(TEST_CHECKOUT_STORAGE_KEY, '1');
29
+ expect(readTestCheckoutFlag()).toBe(true);
30
+ });
31
+ });
@@ -18,6 +18,8 @@ var _job = require("./utilities/job");
18
18
  var _product = require("./utilities/product");
19
19
  var _local_storage = require("./utilities/local_storage");
20
20
  var _user = require("./utilities/user");
21
+ var _test_checkout = require("./utilities/test_checkout");
22
+ var _job_source = require("./utilities/job_source");
21
23
  var _jsxRuntime = require("react/jsx-runtime");
22
24
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t9 in e) "default" !== _t9 && {}.hasOwnProperty.call(e, _t9) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t9)) && (i.get || i.set) ? o(f, _t9, i) : f[_t9] = e[_t9]); return f; })(e, t); }
23
25
  function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
@@ -503,27 +505,36 @@ var CartProvider = function CartProvider(_ref) {
503
505
  }
504
506
  function _createCartAndCookie() {
505
507
  _createCartAndCookie = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(callback) {
506
- var _cart, cartJson, _t3;
508
+ var isTest, jobSource, _cart, query, created, cartJson, _t3;
507
509
  return _regenerator().w(function (_context2) {
508
510
  while (1) switch (_context2.p = _context2.n) {
509
511
  case 0:
510
512
  setFetchingCart(true);
511
513
  _context2.p = 1;
514
+ isTest = (0, _test_checkout.readTestCheckoutFlag)();
515
+ jobSource = (0, _job_source.jobSourceFieldsForApi)((0, _job_source.captureAndReadJobSource)());
512
516
  _cart = (0, _cart3.makeCart)({
513
517
  domain: {
514
518
  id: domainId
515
- }
519
+ },
520
+ isTest: isTest
516
521
  }, true);
522
+ query = [['embed', JSON.stringify(_helpers.cartEmbed)], ['skip_rights', 'y']];
523
+ if (isTest) query.push(['is_test', 'true']);
517
524
  _context2.n = 2;
518
- return _cart.create({
519
- embed: _helpers.cartEmbed
525
+ return merchi.authenticatedFetch('/carts/', {
526
+ method: 'POST',
527
+ body: (0, _job_source.appendJobSourceToFormData)(_cart.toFormData(), jobSource),
528
+ query: query
520
529
  });
521
530
  case 2:
531
+ created = _context2.v;
532
+ _cart.fromJson(created.cart);
522
533
  _context2.n = 3;
523
534
  return _cart.toJson();
524
535
  case 3:
525
536
  cartJson = _context2.v;
526
- if (domainId) (0, _cookie.setCartCookie)(Number(domainId), cartJson, undefined);
537
+ if (domainId) (0, _cookie.setCartCookie)(Number(domainId), cartJson, undefined, isTest);
527
538
  _context2.n = 4;
528
539
  return attachSavedClientIfNeeded(cartJson);
529
540
  case 4:
@@ -552,7 +563,7 @@ var CartProvider = function CartProvider(_ref) {
552
563
  }
553
564
  function _getCart() {
554
565
  _getCart = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(cartIdAndToken) {
555
- var id, _cart2, cartJson, _t4;
566
+ var id, _cart2, cartJson, isTest, jobSource, saved, _t4;
556
567
  return _regenerator().w(function (_context3) {
557
568
  while (1) switch (_context3.p = _context3.n) {
558
569
  case 0:
@@ -570,36 +581,62 @@ var CartProvider = function CartProvider(_ref) {
570
581
  return _cart2.toJson();
571
582
  case 3:
572
583
  cartJson = _context3.v;
573
- if (!(0, _cart3.stripeIsValidAndActive)(cartJson)) {
584
+ isTest = (0, _test_checkout.readTestCheckoutFlag)();
585
+ if (!(Boolean(cartJson.isTest) !== isTest)) {
574
586
  _context3.n = 5;
575
587
  break;
576
588
  }
577
589
  _context3.n = 4;
578
- return attachSavedClientIfNeeded(cartJson);
590
+ return createCartAndCookie();
579
591
  case 4:
592
+ return _context3.a(2);
593
+ case 5:
594
+ jobSource = (0, _job_source.jobSourceFieldsForApi)((0, _job_source.captureAndReadJobSource)());
595
+ if (!(0, _job_source.cartNeedsSourceUpdate)(cartJson, jobSource)) {
596
+ _context3.n = 7;
597
+ break;
598
+ }
599
+ _context3.n = 6;
600
+ return merchi.authenticatedFetch("/carts/".concat(_cart2.id, "/"), {
601
+ method: 'PATCH',
602
+ body: (0, _job_source.appendJobSourceToFormData)(_cart2.toFormData(), jobSource),
603
+ query: [['embed', JSON.stringify(_helpers.cartEmbed)], ['skip_rights', 'y']]
604
+ });
605
+ case 6:
606
+ saved = _context3.v;
607
+ _cart2.fromJson(saved.cart);
608
+ cartJson = _cart2.toJson();
609
+ case 7:
610
+ if (!((0, _cart3.stripeIsValidAndActive)(cartJson) || isTest)) {
611
+ _context3.n = 9;
612
+ break;
613
+ }
614
+ _context3.n = 8;
615
+ return attachSavedClientIfNeeded(cartJson);
616
+ case 8:
580
617
  cartJson = _context3.v;
581
618
  setCart(_objectSpread({}, cartJson));
582
- _context3.n = 6;
619
+ _context3.n = 10;
583
620
  break;
584
- case 5:
621
+ case 9:
585
622
  console.error("MErhci cart error: Stripe payment " + "options have not been correctly set up. " + "Check the company profile payment options tab " + "to set and edit stripe payment options.");
586
623
  setCartSettingsInvalid(true);
587
- case 6:
588
- _context3.n = 8;
624
+ case 10:
625
+ _context3.n = 12;
589
626
  break;
590
- case 7:
591
- _context3.p = 7;
627
+ case 11:
628
+ _context3.p = 11;
592
629
  _t4 = _context3.v;
593
- _context3.n = 8;
630
+ _context3.n = 12;
594
631
  return createCartAndCookie();
595
- case 8:
596
- _context3.p = 8;
632
+ case 12:
633
+ _context3.p = 12;
597
634
  setFetchingCart(false);
598
- return _context3.f(8);
599
- case 9:
635
+ return _context3.f(12);
636
+ case 13:
600
637
  return _context3.a(2);
601
638
  }
602
- }, _callee3, null, [[1, 7, 8, 9]]);
639
+ }, _callee3, null, [[1, 11, 12, 13]]);
603
640
  }));
604
641
  return _getCart.apply(this, arguments);
605
642
  }
@@ -962,6 +999,7 @@ var CartProvider = function CartProvider(_ref) {
962
999
  window.createCartAndCookie = createCartAndCookie;
963
1000
  }
964
1001
  (0, _react.useEffect)(function () {
1002
+ (0, _test_checkout.persistTestCheckoutFlag)();
965
1003
  if (domainId) actionGetMerchiCart();
966
1004
  if (domainId && includeTheme) actionFetchTheme();
967
1005
  }, [domainId]);
@@ -129,7 +129,9 @@ function ActiveFormShipmentAddressAndNotes() {
129
129
  cart = _useCartContext2.cart,
130
130
  setCart = _useCartContext2.setCart,
131
131
  setLoadingTotals = _useCartContext2.setLoadingTotals,
132
- setActiveTabAndEditDisabled = _useCartContext2.setActiveTabAndEditDisabled;
132
+ setActiveTabAndEditDisabled = _useCartContext2.setActiveTabAndEditDisabled,
133
+ updateCartShipmentAddress = _useCartContext2.updateCartShipmentAddress,
134
+ getCartShipmentOptions = _useCartContext2.getCartShipmentOptions;
133
135
  var saved = (0, _local_storage.getSavedCheckoutAddress)(domainId);
134
136
  var cartAddress = cart === null || cart === void 0 ? void 0 : cart.receiverAddress;
135
137
  var receiverAddress = (0, _local_storage.addressHasContent)(cartAddress) ? cartAddress : saved.address || {};
@@ -138,6 +140,25 @@ function ActiveFormShipmentAddressAndNotes() {
138
140
  _useState2 = _slicedToArray(_useState, 2),
139
141
  addressFieldsOpen = _useState2[0],
140
142
  setAddressFieldsOpen = _useState2[1];
143
+ var hydratedShipmentOptionsRef = (0, _react.useRef)(false);
144
+ (0, _react.useEffect)(function () {
145
+ if (hydratedShipmentOptionsRef.current || !(cart !== null && cart !== void 0 && cart.id)) return;
146
+ var draft = (0, _local_storage.getSavedCheckoutAddress)(domainId);
147
+ var action = (0, _shipment.checkoutShipmentHydrationAction)({
148
+ cartAddress: cart === null || cart === void 0 ? void 0 : cart.receiverAddress,
149
+ savedAddress: draft.address,
150
+ shipmentGroups: cart === null || cart === void 0 ? void 0 : cart.shipmentGroups
151
+ });
152
+ if (!action) return;
153
+ hydratedShipmentOptionsRef.current = true;
154
+ if (action === "apply-saved-address" && draft.address) {
155
+ updateCartShipmentAddress(draft.address);
156
+ return;
157
+ }
158
+ if (action === "refresh-quotes") {
159
+ getCartShipmentOptions === null || getCartShipmentOptions === void 0 || getCartShipmentOptions();
160
+ }
161
+ }, [cart === null || cart === void 0 ? void 0 : cart.id, cart === null || cart === void 0 ? void 0 : cart.receiverAddress, cart === null || cart === void 0 ? void 0 : cart.shipmentGroups, domainId, getCartShipmentOptions, updateCartShipmentAddress]);
141
162
  function saveCartShipmentAddressAndGoToNextTab(_x) {
142
163
  return _saveCartShipmentAddressAndGoToNextTab.apply(this, arguments);
143
164
  }
@@ -56,6 +56,7 @@ function StripeCardForm() {
56
56
  error = _useState2[0],
57
57
  setError = _useState2[1];
58
58
  var company = domain.company;
59
+ var isTestCheckout = Boolean(cart.isTest);
59
60
  var hasCompanyPubKey = Boolean(company.isStripeValid && (0, _utils.companyStripePubKeyOrTestPubKey)(company));
60
61
  var companyPubKey = hasCompanyPubKey ? (0, _utils.companyStripePubKeyOrTestPubKey)(company) : '';
61
62
  var canUseConnect = !!company.stripeAccountId;
@@ -142,15 +143,21 @@ function StripeCardForm() {
142
143
  }));
143
144
  return _doStripePaymentRequestForButton.apply(this, arguments);
144
145
  }
145
- var _useState7 = (0, _react.useState)(companyPubKey),
146
+ var _useState7 = (0, _react.useState)(isTestCheckout ? '' : companyPubKey),
146
147
  _useState8 = _slicedToArray(_useState7, 2),
147
148
  stripePublicKey = _useState8[0],
148
149
  setStripePublicKey = _useState8[1];
149
150
  (0, _react.useEffect)(function () {
151
+ if (isTestCheckout) {
152
+ (0, _actions.fetchTestPublishableKey)(url).then(setStripePublicKey)["catch"](function () {
153
+ return setStripePublicKey('');
154
+ });
155
+ return;
156
+ }
150
157
  if (!stripePublicKey && canUseConnect) (0, _actions.stripeInitPromise)(url).then(setStripePublicKey);
151
- }, [stripePublicKey, canUseConnect]);
158
+ }, [stripePublicKey, canUseConnect, isTestCheckout, url]);
152
159
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
153
- children: [company.isTesting && badgeTestMode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_StripeCardFields["default"], {
160
+ children: [!isTestCheckout && company.isTesting && badgeTestMode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_StripeCardFields["default"], {
154
161
  doStripePayment: doStripePayment,
155
162
  doStripePaymentRequestForButton: doStripePaymentRequestForButton,
156
163
  cart: cart,