@blotoutio/providers-blotout-wallet-sdk 0.62.0 → 0.63.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.
package/index.js CHANGED
@@ -37,6 +37,54 @@ var ProvidersBlotoutWalletSdk = (function () {
37
37
 
38
38
  const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
39
39
 
40
+ const createEnabled = () => ({
41
+ name: 'enabled',
42
+ groupNames: new Set(),
43
+ segment: 0,
44
+ groupName: '',
45
+ isEnabled: true,
46
+ });
47
+ const createDisabled = () => ({
48
+ name: 'disabled',
49
+ groupNames: new Set(),
50
+ segment: 0,
51
+ groupName: '',
52
+ isEnabled: false,
53
+ });
54
+ const createABTest = ({ userId }) => {
55
+ const [sample] = userId.split('-');
56
+ const segment = parseInt(sample, 16) % 2;
57
+ return {
58
+ name: 'ab-test',
59
+ groupNames: new Set(['enabled', 'control']),
60
+ segment,
61
+ groupName: segment == 1 ? 'enabled' : 'control',
62
+ isEnabled: segment == 1,
63
+ };
64
+ };
65
+ const createPreview = ({ previewKey, userPreviewKey }) => {
66
+ const isEnabled = !!(previewKey && previewKey === userPreviewKey);
67
+ return {
68
+ name: 'preview',
69
+ groupNames: new Set(['preview']),
70
+ groupName: isEnabled ? 'preview' : '',
71
+ segment: isEnabled ? 1 : 0,
72
+ isEnabled,
73
+ };
74
+ };
75
+ const createExperiment = (props) => {
76
+ switch (props.name) {
77
+ case 'enabled':
78
+ return createEnabled();
79
+ case 'disabled':
80
+ return createDisabled();
81
+ case 'ab-test':
82
+ return createABTest(props);
83
+ case 'preview':
84
+ return createPreview(props);
85
+ }
86
+ };
87
+
40
88
  const customAttributes = {
41
89
  '--bw-primary': { type: 'color', defaultValue: '#000000' },
42
90
  '--bw-title-color': { type: 'color', defaultValue: '#000000' },
@@ -62,143 +110,37 @@ var ProvidersBlotoutWalletSdk = (function () {
62
110
  };
63
111
 
64
112
  const packageName = 'blotoutWallet';
65
- const cartTokenCookie = 'cart';
66
- const cartTokenTwoCookie = 'cart2';
67
- const cartTokenLinkCookie = 'bwCartLinkToken';
113
+ const PREVIEW_KEY_NAME = '_blotoutWalletPreview';
68
114
 
69
- const getCookieValue = (key) => {
70
- var _a;
71
- try {
72
- if (!document || !document.cookie) {
73
- return '';
74
- }
75
- const cookies = parseCookies(document.cookie);
76
- return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
77
- }
78
- catch {
79
- return '';
80
- }
81
- };
82
- const parseCookies = (cookie) => {
83
- return Object.fromEntries(cookie
84
- .split(/;\s+/)
85
- .map((r) => r.split('=').map((str) => str.trim()))
86
- .map(([cookieKey, cookieValue]) => {
87
- if (!cookieKey) {
88
- return [];
89
- }
90
- let decodedValue = '';
91
- if (cookieValue) {
92
- try {
93
- decodedValue = decodeURIComponent(cookieValue);
94
- }
95
- catch (e) {
96
- console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
97
- decodedValue = cookieValue;
98
- }
99
- }
100
- return [cookieKey, decodedValue];
101
- }));
102
- };
103
- const setCookie = (key, value, options) => {
104
- var _a;
105
- try {
106
- if (!document) {
107
- return;
108
- }
109
- const extras = [`path=${(_a = options === null || options === void 0 ? void 0 : options.path) !== null && _a !== void 0 ? _a : '/'}`];
110
- if (options === null || options === void 0 ? void 0 : options['maxAge']) {
111
- extras.push(`max-age=${options['maxAge']}`);
112
- }
113
- if (options === null || options === void 0 ? void 0 : options.expires) {
114
- extras.push(`expires=${options.expires}`);
115
- }
116
- if (options === null || options === void 0 ? void 0 : options.partitioned) {
117
- extras.push('partitioned');
118
- }
119
- if (options === null || options === void 0 ? void 0 : options.samesite) {
120
- extras.push(`samesite=${options.samesite}`);
121
- }
122
- if (options === null || options === void 0 ? void 0 : options.secure) {
123
- extras.push('secure');
124
- }
125
- document.cookie = `${key}=${value};${extras.join(';')}`;
126
- }
127
- catch {
128
- return;
129
- }
130
- };
115
+ var _a;
116
+ const registryKey = Symbol.for('blotout-wallet');
117
+ (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
131
118
 
132
- const canLog = () => {
119
+ // eslint-disable-next-line @nx/enforce-module-boundaries
120
+ const getPreviewKey = () => {
121
+ let key = null;
133
122
  try {
134
- return localStorage.getItem('edgeTagDebug') === '1';
123
+ key = localStorage.getItem(PREVIEW_KEY_NAME) || null;
135
124
  }
136
125
  catch {
137
- return false;
126
+ /* do nothing */
138
127
  }
128
+ return key;
139
129
  };
140
- const logger = {
141
- log: (...args) => {
142
- if (canLog()) {
143
- console.log(...args);
144
- }
145
- },
146
- error: (...args) => {
147
- if (canLog()) {
148
- console.error(...args);
149
- }
150
- },
151
- info: (...args) => {
152
- if (canLog()) {
153
- console.info(...args);
154
- }
155
- },
156
- trace: (...args) => {
157
- if (canLog()) {
158
- console.trace(...args);
159
- }
160
- },
161
- table: (...args) => {
162
- if (canLog()) {
163
- console.table(...args);
164
- }
165
- },
166
- dir: (...args) => {
167
- if (canLog()) {
168
- console.dir(...args);
169
- }
170
- },
171
- };
172
-
173
- var _a;
174
- const registryKey = Symbol.for('blotout-wallet');
175
- (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
176
130
 
177
- // eslint-disable-next-line @nx/enforce-module-boundaries
178
- const tag = ({ eventName }) => {
131
+ const tag = () => {
132
+ const result = {
133
+ cartToken: null,
134
+ previewKey: getPreviewKey(),
135
+ };
179
136
  if (!window) {
180
- return;
137
+ return result;
181
138
  }
182
- const platform = window[registryKey].platform;
183
- switch (platform) {
184
- case 'SHOPIFY': {
185
- let cartToken = getCookieValue(cartTokenCookie);
186
- const cartTokenLink = getCookieValue(cartTokenLinkCookie);
187
- if (!cartToken) {
188
- cartToken = getCookieValue(cartTokenTwoCookie);
189
- }
190
- if (eventName === 'Purchase') {
191
- setCookie(cartTokenTwoCookie, cartToken, { path: '/', maxAge: 10 });
192
- }
193
- if (cartTokenLink) {
194
- setCookie(cartTokenLinkCookie, '', { maxAge: 0 });
195
- }
196
- return { cartToken, cartTokenLink };
197
- }
198
- default: {
199
- return {};
200
- }
139
+ const store = window[registryKey].storeAPI;
140
+ if (store) {
141
+ result.cartToken = store.getCartToken();
201
142
  }
143
+ return result;
202
144
  };
203
145
 
204
146
  /******************************************************************************
@@ -418,6 +360,111 @@ var ProvidersBlotoutWalletSdk = (function () {
418
360
  return animation.finished;
419
361
  };
420
362
 
363
+ const getCookieValue = (key) => {
364
+ var _a;
365
+ try {
366
+ if (!document || !document.cookie) {
367
+ return '';
368
+ }
369
+ const cookies = parseCookies(document.cookie);
370
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
371
+ }
372
+ catch {
373
+ return '';
374
+ }
375
+ };
376
+ const parseCookies = (cookie) => {
377
+ return Object.fromEntries(cookie
378
+ .split(/;\s+/)
379
+ .map((r) => r.split('=').map((str) => str.trim()))
380
+ .map(([cookieKey, ...cookieValues]) => {
381
+ const cookieValue = cookieValues.join('=');
382
+ if (!cookieKey) {
383
+ return [];
384
+ }
385
+ let decodedValue = '';
386
+ if (cookieValue) {
387
+ try {
388
+ decodedValue = decodeURIComponent(cookieValue);
389
+ }
390
+ catch (e) {
391
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
392
+ decodedValue = cookieValue;
393
+ }
394
+ }
395
+ return [cookieKey, decodedValue];
396
+ }));
397
+ };
398
+ const setCookie = (key, value, options) => {
399
+ var _a;
400
+ try {
401
+ if (!document) {
402
+ return;
403
+ }
404
+ const extras = [`path=${(_a = options === null || options === void 0 ? void 0 : options.path) !== null && _a !== void 0 ? _a : '/'}`];
405
+ if (options === null || options === void 0 ? void 0 : options['maxAge']) {
406
+ extras.push(`max-age=${options['maxAge']}`);
407
+ }
408
+ if (options === null || options === void 0 ? void 0 : options.expires) {
409
+ extras.push(`expires=${options.expires}`);
410
+ }
411
+ if (options === null || options === void 0 ? void 0 : options.partitioned) {
412
+ extras.push('partitioned');
413
+ }
414
+ if (options === null || options === void 0 ? void 0 : options.samesite) {
415
+ extras.push(`samesite=${options.samesite}`);
416
+ }
417
+ if (options === null || options === void 0 ? void 0 : options.secure) {
418
+ extras.push('secure');
419
+ }
420
+ document.cookie = `${key}=${encodeURIComponent(value)};${extras.join(';')}`;
421
+ }
422
+ catch {
423
+ return;
424
+ }
425
+ };
426
+
427
+ const canLog = () => {
428
+ try {
429
+ return localStorage.getItem('edgeTagDebug') === '1';
430
+ }
431
+ catch {
432
+ return false;
433
+ }
434
+ };
435
+ const logger = {
436
+ log: (...args) => {
437
+ if (canLog()) {
438
+ console.log(...args);
439
+ }
440
+ },
441
+ error: (...args) => {
442
+ if (canLog()) {
443
+ console.error(...args);
444
+ }
445
+ },
446
+ info: (...args) => {
447
+ if (canLog()) {
448
+ console.info(...args);
449
+ }
450
+ },
451
+ trace: (...args) => {
452
+ if (canLog()) {
453
+ console.trace(...args);
454
+ }
455
+ },
456
+ table: (...args) => {
457
+ if (canLog()) {
458
+ console.table(...args);
459
+ }
460
+ },
461
+ dir: (...args) => {
462
+ if (canLog()) {
463
+ console.dir(...args);
464
+ }
465
+ },
466
+ };
467
+
421
468
  const cart = (attrs) => b `<svg class=${attrs === null || attrs === void 0 ? void 0 : attrs.class} style=${attrs === null || attrs === void 0 ? void 0 : attrs.style} width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
422
469
  <g clip-path="url(#clip0_10367_379)">
423
470
  <path d="M20 60C22.2091 60 24 58.2091 24 56C24 53.7909 22.2091 52 20 52C17.7909 52 16 53.7909 16 56C16 58.2091 17.7909 60 20 60Z" fill="currentColor"/>
@@ -450,6 +497,7 @@ var ProvidersBlotoutWalletSdk = (function () {
450
497
  <path d="M47.5332 12.334L51.2443 16.0451L15.5379 51.7515L11.8268 48.0404L47.5332 12.334Z" fill="currentColor"/>
451
498
  </svg>
452
499
  `;
500
+ const logoImage = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAgCAYAAABU1PscAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEt0lEQVRYhdWYX4hUdRTHP+d358+6azNGqUVqilrQXaNIClKSQHsQpJceSu4IBSFIvQRWLwWW9dBD0IMYvUTNSAUGGVRYGLFQQU8aO2VhhVpBlOHcdXd2Z+b+vj3MrG6z7c7OpO32hTt/DjO/+/2ec37nnPszgJEoXCvYB2w3WCIwFi5+B44AB3Kl8nEbKYTrJT4ZSLlV1cSb13zzmx2BGWlneGmo5rUvJfH8QMqtGm34hez1i0gkvBeIzUDkgO3V5P9BfhISYDgzdqQMFrenjQGZwDAgEdQXYF5J4IxrXTs1ZyCojHs9UU30QN3rlZSzsXlh2QFe4NqNzgzgvEnFfKn8ruCoQW2h5tg0AS0YWF8lCg3I/JeEukVqvgmYzezFuWBeBQRmeClJoAokvawxbwICMzz6WbAf7BhQp4cJYE4CDEg7I3CGJERzs0ui7kXSQ5UNHJjsq4b0ea40fKr7FZqYi4Ag5Yxqw39X8zoKHBfEhpYCdwPbsoEtq3k5dSNEgPCtT8RRuBK4AUhP2i6PAOOPsYbfCxwWVsmXhqcu/mqlEK6ZSLQ37WxnIuV9FxraUMg4e9wZ1xmGEA0vGppdTEcB+WJ5CBia/D5S2JAWygJjueKwzxfLPwF74ig8lQnsqbrXsq4icQlBzavevJd+aHG73ZndhJSZack5b+KRaPB6occkfx+wBPgljsJDwDu5UjnOlcovx1G4OhvYrrpXvofpw4DXgTdypfKPAHEUbnLGCx62zOSUOZXgkcLgeqEjAyn3ZNbZxrSzdX2B25IN7DVnvBRH4XIAwcGJRKfpIofb0P6/oFOb6BiB8d0brTZafbE/5W4da/jU5B3qCGcQmO0GfR1HYSlXKn8bR+GXKbPVDZTrMgoCHgG2xlF4BgiADYlYyyxPWB0F1MaqG4B7qonPtvPxgowzEmkH8AEQA8PO7AJSriv6kGScpZ2xCdgkoOFFIolZItp5D8hWpB2ZxgzuTCQkVgDZlumcGY0uyQMUa16fctnLKDqfNOv1P8IZmBFLF0kvphn+2WGt1xbVXKl8Fjjbmc/fMYc+YCe89H0msI31RKl21zgMB8c8qrRM673U32nZxINHdwKb4yic4EqNErni8Ggchc/VEhWzgV1T92o9DRl9gTGe+C8ScUimP+PC4FKku+qeqzr1gkQiMFvp0QH9i2FuTmU0Vyp/hLFzItGQF+MtAiOjDf9WIh4WnMoXvxFSIRvYzTA9UjOJwAgCY3Fg5Hu55tzIcsXyx5Vdt3xm3tYLloD9CpzNlYYbACOFwa2S9tS9lndTPqUeXd/CTAIEjOdLZVUK4ToTi4CTuTfLNaA89Yf+0dvsQrX+kKT9zuxG9ThH9AqLo9AzZfM4Ay8qwNPAGWAbUADea10nMRszKS+4A3gw7exeSf2Jem/BPQsYiULf3ugMSLmmSYAk0s5R955EjNGsGH2ZwDImrOY7jIxXCM6MlCB2xt+GL9E8CzIueTRJPAY4o3/SXuvlSeYywQyEzjngw0XBtOMhYHo6iOb4kKj5Pl+wpge9xGEn7NnRhj89kHJyC/XwZwoCM7LOkXY2BLxtAJUoXGPwDHC/wdUL8Xi9lbYe+A14HziYK5VP/AXU+TX099lFgwAAAABJRU5ErkJggg==`;
453
501
 
454
502
  /**
455
503
  * Sets the max-age for the dismissed popup cookie
@@ -474,7 +522,8 @@ var ProvidersBlotoutWalletSdk = (function () {
474
522
  this.transitionTo = (newState) => {
475
523
  return flipOut(this.dialog)
476
524
  .then(() => (this.state = newState))
477
- .then(() => flipIn(this.dialog));
525
+ .then(() => flipIn(this.dialog))
526
+ .catch(logger.error);
478
527
  };
479
528
  this.restoreCart = async () => {
480
529
  if (!this.lastExpiredCart) {
@@ -500,8 +549,6 @@ var ProvidersBlotoutWalletSdk = (function () {
500
549
  }
501
550
  await this.storeApi.addItems(this.lastExpiredCart.items);
502
551
  const expiredCartId = this.lastExpiredCart.cartId;
503
- // this cookie will be cleared once the next event is processed
504
- setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
505
552
  // We attempt to mark the cart as restored, but if the request fails,
506
553
  // we log the error in the console and let the user continue. Since the
507
554
  // problem is probably in the `/cart/restore` endpoint, further attempts
@@ -634,7 +681,13 @@ var ProvidersBlotoutWalletSdk = (function () {
634
681
  method: 'POST',
635
682
  headers: this.getHeaders(),
636
683
  body: JSON.stringify({ action: 'popupDismissed' }),
637
- }).catch(logger.error);
684
+ })
685
+ .then(async (response) => {
686
+ if (!response.ok) {
687
+ throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
688
+ }
689
+ })
690
+ .catch(logger.error);
638
691
  }
639
692
  connectedCallback() {
640
693
  var _a;
@@ -702,7 +755,13 @@ var ProvidersBlotoutWalletSdk = (function () {
702
755
  method: 'POST',
703
756
  headers: this.getHeaders(),
704
757
  body: JSON.stringify({ action: 'popupShown' }),
705
- }).catch(logger.error);
758
+ })
759
+ .then(async (response) => {
760
+ if (!response.ok) {
761
+ throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
762
+ }
763
+ })
764
+ .catch(logger.error);
706
765
  }
707
766
  hideModal(action) {
708
767
  fadeOutToBottom(this.dialog)
@@ -722,8 +781,14 @@ var ProvidersBlotoutWalletSdk = (function () {
722
781
  getUrl(path) {
723
782
  const url = new URL(`/providers/blotoutWallet${path}`, this.edgeURL);
724
783
  if (this.storeApi) {
725
- const { cartToken } = this.storeApi.getCartInfo();
726
- url.searchParams.set('t', cartToken);
784
+ const cartToken = this.storeApi.getCartToken();
785
+ if (cartToken) {
786
+ url.searchParams.set('t', cartToken);
787
+ }
788
+ const previewKey = getPreviewKey();
789
+ if (previewKey) {
790
+ url.searchParams.set('pk', previewKey);
791
+ }
727
792
  }
728
793
  return url;
729
794
  }
@@ -920,8 +985,25 @@ var ProvidersBlotoutWalletSdk = (function () {
920
985
  t$1('blotout-wallet')
921
986
  ], BlotoutWallet);
922
987
 
988
+ const logStyles = `
989
+ padding: 4px 8px 4px 36px;
990
+ border: 1px dashed red;
991
+ border-radius: 3px;
992
+ font-weight: bold;
993
+ background: url(${logoImage}) 8px 50% no-repeat;
994
+ background-size: 24px 16px;
995
+ `;
996
+ const log = (message) => console.log(`%c${message}`, logStyles);
923
997
  const init = (params) => {
924
998
  var _a, _b, _c, _d, _e, _f;
999
+ let store = window[registryKey].storeAPI;
1000
+ if (!store) {
1001
+ store = window[registryKey].storeAPI =
1002
+ (_b = (_a = window[registryKey]).storeAPIFactory) === null || _b === void 0 ? void 0 : _b.call(_a);
1003
+ }
1004
+ if (!store) {
1005
+ throw new Error('Implementation for store API missing!');
1006
+ }
925
1007
  if (
926
1008
  // if loaded in non-browser SDKs
927
1009
  !window ||
@@ -929,15 +1011,22 @@ var ProvidersBlotoutWalletSdk = (function () {
929
1011
  window.top !== window) {
930
1012
  return;
931
1013
  }
932
- let store = window[registryKey].storeAPI;
933
- if (!store) {
934
- store = window[registryKey].storeAPI =
935
- (_b = (_a = window[registryKey]).storeAPIFactory) === null || _b === void 0 ? void 0 : _b.call(_a);
936
- if (!store) {
937
- throw new Error('Implementation for store API missing!');
1014
+ const { enabled, previewKey, mode = 'disabled', } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
1015
+ const experiment = createExperiment({
1016
+ name: mode,
1017
+ userId: params.userId,
1018
+ previewKey,
1019
+ userPreviewKey: getPreviewKey(),
1020
+ });
1021
+ if (experiment.name == 'preview') {
1022
+ if (experiment.isEnabled) {
1023
+ log('Previewing functionality using preview key');
1024
+ }
1025
+ else {
1026
+ log('Preview key set but does not match the configured key');
938
1027
  }
939
1028
  }
940
- if ((_c = params.manifest.variables) === null || _c === void 0 ? void 0 : _c['enabled']) {
1029
+ if (enabled || experiment.isEnabled) {
941
1030
  // if the component is already defined, skip creating the element to avoid
942
1031
  // layering multiple widgets
943
1032
  if (window[registryKey].wallet) {