@blotoutio/providers-blotout-wallet-sdk 0.62.1 → 0.63.1

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,144 +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, ...cookieValues]) => {
87
- const cookieValue = cookieValues.join('=');
88
- if (!cookieKey) {
89
- return [];
90
- }
91
- let decodedValue = '';
92
- if (cookieValue) {
93
- try {
94
- decodedValue = decodeURIComponent(cookieValue);
95
- }
96
- catch (e) {
97
- console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
98
- decodedValue = cookieValue;
99
- }
100
- }
101
- return [cookieKey, decodedValue];
102
- }));
103
- };
104
- const setCookie = (key, value, options) => {
105
- var _a;
106
- try {
107
- if (!document) {
108
- return;
109
- }
110
- const extras = [`path=${(_a = options === null || options === void 0 ? void 0 : options.path) !== null && _a !== void 0 ? _a : '/'}`];
111
- if (options === null || options === void 0 ? void 0 : options['maxAge']) {
112
- extras.push(`max-age=${options['maxAge']}`);
113
- }
114
- if (options === null || options === void 0 ? void 0 : options.expires) {
115
- extras.push(`expires=${options.expires}`);
116
- }
117
- if (options === null || options === void 0 ? void 0 : options.partitioned) {
118
- extras.push('partitioned');
119
- }
120
- if (options === null || options === void 0 ? void 0 : options.samesite) {
121
- extras.push(`samesite=${options.samesite}`);
122
- }
123
- if (options === null || options === void 0 ? void 0 : options.secure) {
124
- extras.push('secure');
125
- }
126
- document.cookie = `${key}=${encodeURIComponent(value)};${extras.join(';')}`;
127
- }
128
- catch {
129
- return;
130
- }
131
- };
115
+ var _a;
116
+ const registryKey = Symbol.for('blotout-wallet');
117
+ (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
132
118
 
133
- const canLog = () => {
119
+ // eslint-disable-next-line @nx/enforce-module-boundaries
120
+ const getPreviewKey = () => {
121
+ let key = null;
134
122
  try {
135
- return localStorage.getItem('edgeTagDebug') === '1';
123
+ key = localStorage.getItem(PREVIEW_KEY_NAME) || null;
136
124
  }
137
125
  catch {
138
- return false;
126
+ /* do nothing */
139
127
  }
128
+ return key;
140
129
  };
141
- const logger = {
142
- log: (...args) => {
143
- if (canLog()) {
144
- console.log(...args);
145
- }
146
- },
147
- error: (...args) => {
148
- if (canLog()) {
149
- console.error(...args);
150
- }
151
- },
152
- info: (...args) => {
153
- if (canLog()) {
154
- console.info(...args);
155
- }
156
- },
157
- trace: (...args) => {
158
- if (canLog()) {
159
- console.trace(...args);
160
- }
161
- },
162
- table: (...args) => {
163
- if (canLog()) {
164
- console.table(...args);
165
- }
166
- },
167
- dir: (...args) => {
168
- if (canLog()) {
169
- console.dir(...args);
170
- }
171
- },
172
- };
173
-
174
- var _a;
175
- const registryKey = Symbol.for('blotout-wallet');
176
- (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
177
130
 
178
- // eslint-disable-next-line @nx/enforce-module-boundaries
179
- const tag = ({ eventName }) => {
131
+ const tag = () => {
132
+ const result = {
133
+ cartToken: null,
134
+ previewKey: getPreviewKey(),
135
+ };
180
136
  if (!window) {
181
- return;
137
+ return result;
182
138
  }
183
- const platform = window[registryKey].platform;
184
- switch (platform) {
185
- case 'SHOPIFY': {
186
- let cartToken = getCookieValue(cartTokenCookie);
187
- const cartTokenLink = getCookieValue(cartTokenLinkCookie);
188
- if (!cartToken) {
189
- cartToken = getCookieValue(cartTokenTwoCookie);
190
- }
191
- if (eventName === 'Purchase') {
192
- setCookie(cartTokenTwoCookie, cartToken, { path: '/', maxAge: 10 });
193
- }
194
- if (cartTokenLink) {
195
- setCookie(cartTokenLinkCookie, '', { maxAge: 0 });
196
- }
197
- return { cartToken, cartTokenLink };
198
- }
199
- default: {
200
- return {};
201
- }
139
+ const store = window[registryKey].storeAPI;
140
+ if (store) {
141
+ result.cartToken = store.getCartToken();
202
142
  }
143
+ return result;
203
144
  };
204
145
 
205
146
  /******************************************************************************
@@ -419,6 +360,111 @@ var ProvidersBlotoutWalletSdk = (function () {
419
360
  return animation.finished;
420
361
  };
421
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
+
422
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">
423
469
  <g clip-path="url(#clip0_10367_379)">
424
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"/>
@@ -451,6 +497,7 @@ var ProvidersBlotoutWalletSdk = (function () {
451
497
  <path d="M47.5332 12.334L51.2443 16.0451L15.5379 51.7515L11.8268 48.0404L47.5332 12.334Z" fill="currentColor"/>
452
498
  </svg>
453
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==`;
454
501
 
455
502
  /**
456
503
  * Sets the max-age for the dismissed popup cookie
@@ -475,7 +522,8 @@ var ProvidersBlotoutWalletSdk = (function () {
475
522
  this.transitionTo = (newState) => {
476
523
  return flipOut(this.dialog)
477
524
  .then(() => (this.state = newState))
478
- .then(() => flipIn(this.dialog));
525
+ .then(() => flipIn(this.dialog))
526
+ .catch(logger.error);
479
527
  };
480
528
  this.restoreCart = async () => {
481
529
  if (!this.lastExpiredCart) {
@@ -501,8 +549,6 @@ var ProvidersBlotoutWalletSdk = (function () {
501
549
  }
502
550
  await this.storeApi.addItems(this.lastExpiredCart.items);
503
551
  const expiredCartId = this.lastExpiredCart.cartId;
504
- // this cookie will be cleared once the next event is processed
505
- setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
506
552
  // We attempt to mark the cart as restored, but if the request fails,
507
553
  // we log the error in the console and let the user continue. Since the
508
554
  // problem is probably in the `/cart/restore` endpoint, further attempts
@@ -635,7 +681,13 @@ var ProvidersBlotoutWalletSdk = (function () {
635
681
  method: 'POST',
636
682
  headers: this.getHeaders(),
637
683
  body: JSON.stringify({ action: 'popupDismissed' }),
638
- }).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);
639
691
  }
640
692
  connectedCallback() {
641
693
  var _a;
@@ -703,7 +755,13 @@ var ProvidersBlotoutWalletSdk = (function () {
703
755
  method: 'POST',
704
756
  headers: this.getHeaders(),
705
757
  body: JSON.stringify({ action: 'popupShown' }),
706
- }).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);
707
765
  }
708
766
  hideModal(action) {
709
767
  fadeOutToBottom(this.dialog)
@@ -723,8 +781,14 @@ var ProvidersBlotoutWalletSdk = (function () {
723
781
  getUrl(path) {
724
782
  const url = new URL(`/providers/blotoutWallet${path}`, this.edgeURL);
725
783
  if (this.storeApi) {
726
- const { cartToken } = this.storeApi.getCartInfo();
727
- 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
+ }
728
792
  }
729
793
  return url;
730
794
  }
@@ -921,8 +985,26 @@ var ProvidersBlotoutWalletSdk = (function () {
921
985
  t$1('blotout-wallet')
922
986
  ], BlotoutWallet);
923
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);
924
997
  const init = (params) => {
925
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
+ console.error('Implementation for store API missing!');
1006
+ return;
1007
+ }
926
1008
  if (
927
1009
  // if loaded in non-browser SDKs
928
1010
  !window ||
@@ -930,15 +1012,22 @@ var ProvidersBlotoutWalletSdk = (function () {
930
1012
  window.top !== window) {
931
1013
  return;
932
1014
  }
933
- let store = window[registryKey].storeAPI;
934
- if (!store) {
935
- store = window[registryKey].storeAPI =
936
- (_b = (_a = window[registryKey]).storeAPIFactory) === null || _b === void 0 ? void 0 : _b.call(_a);
937
- if (!store) {
938
- throw new Error('Implementation for store API missing!');
1015
+ const { enabled, previewKey, mode = 'disabled', } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
1016
+ const experiment = createExperiment({
1017
+ name: mode,
1018
+ userId: params.userId,
1019
+ previewKey,
1020
+ userPreviewKey: getPreviewKey(),
1021
+ });
1022
+ if (experiment.name == 'preview') {
1023
+ if (experiment.isEnabled) {
1024
+ log('Previewing functionality using preview key');
1025
+ }
1026
+ else if (getPreviewKey()) {
1027
+ log('Preview key set but does not match the configured key');
939
1028
  }
940
1029
  }
941
- if ((_c = params.manifest.variables) === null || _c === void 0 ? void 0 : _c['enabled']) {
1030
+ if (enabled || experiment.isEnabled) {
942
1031
  // if the component is already defined, skip creating the element to avoid
943
1032
  // layering multiple widgets
944
1033
  if (window[registryKey].wallet) {