@saasquatch/squatch-js 2.5.1-8 → 2.6.0-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 (70) hide show
  1. package/.github/workflows/size-limit.yml +15 -0
  2. package/CHANGELOG.md +326 -334
  3. package/LICENSE +20 -20
  4. package/README.md +180 -145
  5. package/babel.config.js +8 -0
  6. package/coverage/clover.xml +888 -0
  7. package/coverage/coverage-final.json +23 -0
  8. package/coverage/lcov-report/api/AnalyticsApi.ts.html +304 -0
  9. package/coverage/lcov-report/api/WidgetApi.ts.html +628 -0
  10. package/coverage/lcov-report/api/graphql.ts.html +130 -0
  11. package/coverage/lcov-report/base.css +224 -0
  12. package/coverage/lcov-report/block-navigation.js +87 -0
  13. package/coverage/lcov-report/favicon.png +0 -0
  14. package/coverage/lcov-report/prettify.css +1 -0
  15. package/coverage/lcov-report/prettify.js +2 -0
  16. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  17. package/coverage/lcov-report/sorter.js +196 -0
  18. package/coverage/lcov-report/utils/cookieUtils.ts.html +415 -0
  19. package/coverage/lcov-report/utils/decodeUserJwt.ts.html +133 -0
  20. package/coverage/lcov-report/utils/domready.ts.html +160 -0
  21. package/coverage/lcov-report/utils/io.ts.html +385 -0
  22. package/coverage/lcov-report/utils/utmUtils.ts.html +277 -0
  23. package/coverage/lcov-report/utils/validate.ts.html +268 -0
  24. package/coverage/lcov-report/validate.ts.html +268 -0
  25. package/coverage/lcov-report/widgets/EmbedWidget.ts.html +436 -0
  26. package/coverage/lcov-report/widgets/PopupWidget.ts.html +625 -0
  27. package/coverage/lcov-report/widgets/Widget.ts.html +1108 -0
  28. package/coverage/lcov-report/widgets/declarative/DeclarativeWidget.ts.html +499 -0
  29. package/coverage/lcov.info +1628 -0
  30. package/demo/sandbox.ts +124 -124
  31. package/demo/toolbar.tsx +526 -526
  32. package/dist/api/AnalyticsApi.d.ts +32 -32
  33. package/dist/api/EventsApi.d.ts +52 -52
  34. package/dist/api/WidgetApi.d.ts +63 -80
  35. package/dist/api/graphql.d.ts +1 -1
  36. package/dist/async.d.ts +15 -11
  37. package/dist/docs.d.ts +1 -1
  38. package/dist/squatch.d.ts +108 -108
  39. package/dist/squatch.esm.js +1105 -1413
  40. package/dist/squatch.esm.js.map +1 -1
  41. package/dist/squatch.js +1105 -1434
  42. package/dist/squatch.js.map +1 -1
  43. package/dist/squatch.min.js +2 -13
  44. package/dist/squatch.min.js.LICENSE.txt +6 -0
  45. package/dist/squatch.min.js.map +1 -1
  46. package/dist/squatch.modern.js +1 -1
  47. package/dist/squatch.modern.js.map +1 -1
  48. package/dist/stats.html +1 -1
  49. package/dist/types.d.ts +107 -106
  50. package/dist/utils/cookieUtils.d.ts +2 -2
  51. package/dist/utils/decodeUserJwt.d.ts +2 -0
  52. package/dist/utils/domUtils.d.ts +1 -0
  53. package/dist/utils/domready.d.ts +6 -6
  54. package/dist/utils/io.d.ts +5 -13
  55. package/dist/utils/loadEvent.d.ts +2 -0
  56. package/dist/utils/utmUtils.d.ts +14 -14
  57. package/dist/utils/validate.d.ts +12 -16
  58. package/dist/widgets/EmbedWidget.d.ts +16 -15
  59. package/dist/widgets/IREmbedWidget.d.ts +29 -0
  60. package/dist/widgets/IRPopupWidget.d.ts +32 -0
  61. package/dist/widgets/PopupWidget.d.ts +25 -23
  62. package/dist/widgets/Widget.d.ts +53 -33
  63. package/dist/widgets/Widgets.d.ts +108 -116
  64. package/dist/widgets/declarative/DeclarativeEmbedWidget.d.ts +12 -0
  65. package/dist/widgets/declarative/DeclarativeWidget.d.ts +32 -0
  66. package/dist/widgets/declarative/DeclarativeWidgets.d.ts +13 -0
  67. package/jest.config.ts +202 -0
  68. package/package.json +123 -105
  69. package/stats.json +1 -0
  70. package/tsconfig.json +2 -2
package/dist/squatch.js CHANGED
@@ -1,35 +1,10 @@
1
1
  var debug = require('debug');
2
- var EventBus = require('eventbusjs');
3
2
  var Cookies = require('js-cookie');
4
- var superagent = require('superagent');
5
3
 
6
4
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
5
 
8
- function _interopNamespace(e) {
9
- if (e && e.__esModule) return e;
10
- var n = Object.create(null);
11
- if (e) {
12
- Object.keys(e).forEach(function (k) {
13
- if (k !== 'default') {
14
- var d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: function () {
18
- return e[k];
19
- }
20
- });
21
- }
22
- });
23
- }
24
- n['default'] = e;
25
- return n;
26
- }
27
-
28
6
  var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
29
- var debug__namespace = /*#__PURE__*/_interopNamespace(debug);
30
- var EventBus__namespace = /*#__PURE__*/_interopNamespace(EventBus);
31
7
  var Cookies__default = /*#__PURE__*/_interopDefaultLegacy(Cookies);
32
- var superagent__namespace = /*#__PURE__*/_interopNamespace(superagent);
33
8
 
34
9
  function _extends() {
35
10
  _extends = Object.assign || function (target) {
@@ -64,159 +39,117 @@ function _objectWithoutPropertiesLoose(source, excluded) {
64
39
  return target;
65
40
  }
66
41
 
67
- function doQuery(url, query, variables, token) {
68
- const headers = _extends({
69
- Accept: "application/json"
42
+ debug.debug("squatch-js:io");
43
+
44
+ async function doQuery(url, query, variables, token) {
45
+ var headers = _extends({
46
+ Accept: "application/json",
47
+ "Content-Type": "application/json"
70
48
  }, token ? {
71
- Authorization: `Bearer ${token}`
49
+ Authorization: "Bearer " + token
72
50
  } : {}, {
73
51
  "X-SaaSquatch-Referrer": window ? window.location.href : ""
74
52
  });
75
53
 
76
- const request = superagent__namespace.post(url).send({
77
- query,
78
- variables
79
- }).set(headers);
80
- return thenableSuperagent(request).then(response => response, error => {
81
- let json;
82
-
83
- try {
84
- json = JSON.parse(error.response.text);
85
- } catch (e) {
86
- }
87
-
88
- throw json;
89
- });
54
+ try {
55
+ var res = await fetch(url, {
56
+ method: "POST",
57
+ body: JSON.stringify({
58
+ query,
59
+ variables
60
+ }),
61
+ headers
62
+ });
63
+ if (!res.ok) throw new Error(await res.text());
64
+ return await res.json();
65
+ } catch (e) {
66
+ throw e;
67
+ }
90
68
  }
91
- function doGet(url, jwt = "") {
92
- const headers = {
69
+ async function doGet(url, jwt) {
70
+ if (jwt === void 0) {
71
+ jwt = "";
72
+ }
73
+
74
+ var headers = {
93
75
  Accept: "application/json",
94
76
  "Content-Type": "application/json"
95
77
  };
96
78
  if (jwt) headers["X-SaaSquatch-User-Token"] = jwt;
97
- const request = superagent__namespace.get(url).withCredentials().set(headers);
98
- return thenableSuperagent(request).then(response => {
99
- if ( //@ts-ignore -- superagent types might just be outdated?
100
- response.headers["content-type"] && //@ts-ignore -- superagent types might just be outdated?
101
- includes(response.headers["content-type"].toLowerCase(), "application/json")) {
102
- return JSON.parse(response.text);
103
- }
104
79
 
105
- return response.text;
106
- }, ({
107
- response
108
- }) => {
109
- const json = JSON.parse(response.text);
110
- throw json;
111
- });
80
+ try {
81
+ var res = await fetch(url, {
82
+ method: "GET",
83
+ credentials: "include",
84
+ headers
85
+ });
86
+ var reply = await res.text();
87
+ if (!res.ok) throw new Error(reply);
88
+ return reply ? JSON.parse(reply) : reply;
89
+ } catch (e) {
90
+ throw e;
91
+ }
112
92
  }
113
- /**
114
- * @hidden
115
- *
116
- * @param url The requested url
117
- * @param data Stringified json object
118
- *
119
- * @returns {Promise} superagent promise
120
- */
121
-
122
- function doPost(url, data, jwt) {
123
- const headers = {
93
+ async function doPost(url, data, jwt) {
94
+ var headers = {
124
95
  Accept: "application/json",
125
96
  "Content-Type": "application/json"
126
97
  };
127
98
  if (jwt) headers["X-SaaSquatch-User-Token"] = jwt;
128
- const request = superagent__namespace.post(url).send(data).set(headers);
129
- return thenableSuperagent(request).then(({
130
- text
131
- }) => text ? JSON.parse(text) : text, error => {
132
- let json;
133
99
 
134
- try {
135
- json = JSON.parse(error.response.text);
136
- } catch (e) {
137
- const out = error || e;
138
- throw out;
139
- }
140
-
141
- throw json;
142
- });
100
+ try {
101
+ var res = await fetch(url, {
102
+ method: "POST",
103
+ body: data,
104
+ headers
105
+ });
106
+ var reply = await res.text();
107
+ if (!res.ok) throw new Error(reply);
108
+ return reply ? JSON.parse(reply) : reply;
109
+ } catch (e) {
110
+ throw e;
111
+ }
143
112
  }
144
- function doPut(url, data, jwt) {
145
- const headers = {
113
+ async function doPut(url, data, jwt) {
114
+ var headers = {
146
115
  Accept: "application/json",
147
116
  "Content-Type": "application/json",
148
117
  "X-SaaSquatch-Referrer": window ? window.location.href : ""
149
118
  };
150
119
  if (jwt) headers["X-SaaSquatch-User-Token"] = jwt;
151
- const request = superagent__namespace.put(url).withCredentials().send(data).set(headers);
152
- return thenableSuperagent(request).then(({
153
- text
154
- }) => text ? JSON.parse(text) : text, error => {
155
- let json;
156
120
 
157
- try {
158
- json = JSON.parse(error.response.text);
159
- } catch (e) {
160
- const out = error || e;
161
- throw out;
162
- }
163
-
164
- throw json;
165
- });
166
- }
167
- /**
168
- * Avoids using superagent's built in `then` method because that relies on a global promise object being valid.
169
- *
170
- * Instead, thanks to babel the promise used in this function should be our custom sandboxed polyfill
171
- */
172
-
173
- function thenableSuperagent(request) {
174
- return new Promise((innerResolve, innerReject) => {
175
- request.on("error", innerReject);
176
- request.end((err, res) => {
177
- if (err) innerReject(err);else innerResolve(res);
121
+ try {
122
+ var res = await fetch(url, {
123
+ headers,
124
+ method: "PUT",
125
+ credentials: "include",
126
+ body: data
178
127
  });
179
- });
180
- }
181
-
182
- function includes(string, search, start) {
183
-
184
- if (typeof start !== "number") {
185
- start = 0;
186
- }
187
-
188
- if (start + search.length > string.length) {
189
- return false;
190
- } else {
191
- return string.indexOf(search, start) !== -1;
128
+ var reply = await res.text();
129
+ if (!res.ok) throw new Error(reply);
130
+ return reply ? JSON.parse(reply) : reply;
131
+ } catch (e) {
132
+ throw e;
192
133
  }
193
134
  }
194
135
 
195
- function hasProps(object, props) {
196
- if (!isObject$1(object)) return false;
197
- const keys = Object.keys(object);
198
- if (!Array.isArray(props)) return object.hasOwnProperty(props);
199
- const hasKeys = props.reduce((acc, cur) => {
200
- return acc && keys.indexOf(cur) >= 0;
201
- }, true);
202
- return hasKeys;
203
- }
204
- function isObject$1(x) {
205
- return typeof x === "object";
206
- }
207
- function assertProp(object, ...props) {
208
- props.forEach(p => {
209
- if (!hasProps(object, props)) throw new Error(p + " is required");
210
- });
211
- return true;
212
- }
213
- function validateConfig(raw) {
214
- if (!isObject$1(raw)) throw new Error("config must be an object");
215
- if (!hasProps(raw, "tenantAlias") || typeof raw.tenantAlias !== "string") throw new Error("tenantAlias not provided");
216
- const tenantAlias = raw.tenantAlias;
217
- const domain = hasProps(raw, "domain") && typeof raw.domain === "string" && raw.domain || "https://app.referralsaasquatch.com";
218
- const debug = hasProps(raw, "debug") && typeof raw.debug === "boolean" && raw.debug || false;
219
- const npmCdn = hasProps(raw, "npmCdn") && typeof raw.npmCdn === "string" && raw.npmCdn || "https://fast.ssqt.io/npm";
136
+ var DEFAULT_DOMAIN = "https://app.referralsaasquatch.com";
137
+ var DEFAULT_NPM_CDN = "https://fast.ssqt.io/npm";
138
+ function validateConfig(_raw) {
139
+ var _window$squatchConfig, _window$squatchConfig2, _window$squatchConfig3;
140
+
141
+ if (typeof _raw !== "object") throw new Error("config must be an object");
142
+ var raw = {
143
+ tenantAlias: (_raw == null ? void 0 : _raw["tenantAlias"]) || window.squatchTenant,
144
+ domain: (_raw == null ? void 0 : _raw["domain"]) || ((_window$squatchConfig = window.squatchConfig) == null ? void 0 : _window$squatchConfig.domain),
145
+ npmCdn: (_raw == null ? void 0 : _raw["npmCdn"]) || ((_window$squatchConfig2 = window.squatchConfig) == null ? void 0 : _window$squatchConfig2.npmCdn),
146
+ debug: (_raw == null ? void 0 : _raw["debug"]) || ((_window$squatchConfig3 = window.squatchConfig) == null ? void 0 : _window$squatchConfig3.debug)
147
+ };
148
+ if (typeof raw.tenantAlias !== "string") throw new Error("tenantAlias not provided");
149
+ var tenantAlias = raw.tenantAlias;
150
+ var domain = typeof raw.domain === "string" && raw.domain || DEFAULT_DOMAIN;
151
+ var debug = typeof raw.debug === "boolean" && raw.debug || false;
152
+ var npmCdn = typeof raw.npmCdn === "string" && raw.npmCdn || DEFAULT_NPM_CDN;
220
153
  return {
221
154
  tenantAlias,
222
155
  domain,
@@ -224,6 +157,9 @@ function validateConfig(raw) {
224
157
  npmCdn
225
158
  };
226
159
  }
160
+ function isObject$1(obj) {
161
+ return typeof obj === "object" && !Array.isArray(obj) && obj !== null;
162
+ }
227
163
  function validateLocale(locale) {
228
164
  if (locale && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(locale)) {
229
165
  return locale;
@@ -231,8 +167,7 @@ function validateLocale(locale) {
231
167
  }
232
168
  function validateWidgetConfig(raw) {
233
169
  if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
234
- if (!assertProp(raw, "user")) ; // TODO: This should be better type checked
235
-
170
+ if (!(raw != null && raw["user"])) throw new Error("Required properties missing.");
236
171
  return raw;
237
172
  }
238
173
  function validatePasswordlessConfig(raw) {
@@ -240,130 +175,120 @@ function validatePasswordlessConfig(raw) {
240
175
  return raw;
241
176
  }
242
177
 
243
- const RENDER_WIDGET_QUERY = `
244
- query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {
245
- renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {
246
- template
247
- user {
248
- id
249
- accountId
250
- }
251
- jsOptions
252
- widgetConfig {
253
- values
254
- }
255
- }
256
- }
257
- `;
178
+ var RENDER_WIDGET_QUERY = "\n query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {\n renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {\n template\n user {\n id\n accountId\n }\n jsOptions\n widgetConfig {\n values\n }\n }\n }\n";
258
179
 
259
- /**
260
- *
261
- * The WidgetApi class is a wrapper around the Widget Endpoints of the SaaSquatch REST API.
262
- *
180
+ /**
181
+ *
182
+ * The WidgetApi class is a wrapper around the Widget Endpoints of the SaaSquatch REST API.
183
+ *
263
184
  */
264
185
 
265
186
  class WidgetApi {
266
- /**
267
- * Initialize a new {@link WidgetApi} instance.
268
- *
269
- * @param {ConfigOptions} config Config details
270
- *
271
- * @example <caption>Browser example</caption>
272
- * var squatchApi = new squatch.WidgetApi({tenantAlias:'test_12b5bo1b25125'});
273
- *
274
- * @example <caption>Browserify/Webpack example</caption>
275
- * var WidgetApi = require('@saasquatch/squatch-js').WidgetApi;
276
- * var squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
277
- *
278
- * @example <caption>Babel+Browserify/Webpack example</caption>
279
- * import {WidgetApi} from '@saasquatch/squatch-js';
280
- * let squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
187
+ // TODO: Support using new window variables for initialisation
188
+
189
+ /**
190
+ * Initialize a new {@link WidgetApi} instance.
191
+ *
192
+ * @param {ConfigOptions} config Config details
193
+ *
194
+ * @example <caption>Browser example</caption>
195
+ * var squatchApi = new squatch.WidgetApi({tenantAlias:'test_12b5bo1b25125'});
196
+ *
197
+ * @example <caption>Browserify/Webpack example</caption>
198
+ * var WidgetApi = require('@saasquatch/squatch-js').WidgetApi;
199
+ * var squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
200
+ *
201
+ * @example <caption>Babel+Browserify/Webpack example</caption>
202
+ * import {WidgetApi} from '@saasquatch/squatch-js';
203
+ * let squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
281
204
  */
282
205
  constructor(config) {
283
- const raw = config; // Flags that we need to validate anything we use from this type
284
-
285
- const clean = validateConfig(raw);
206
+ this.tenantAlias = void 0;
207
+ this.domain = void 0;
208
+ this.npmCdn = void 0;
209
+ var raw = config;
210
+ var clean = validateConfig(raw);
286
211
  this.tenantAlias = clean.tenantAlias;
287
212
  this.domain = clean.domain;
288
213
  this.npmCdn = clean.npmCdn;
289
214
  }
290
- /**
291
- * Creates/upserts user.
292
- *
293
- * @param {Object} params Parameters for request
294
- * @param {Object?} params.user The user details
295
- * @param {string} params.user.id The user id
296
- * @param {string} params.user.accountId The user account id
297
- * @param {WidgetType} params.widgetType The content of the widget.
298
- * @param {EngagementMedium?} params.engagementMedium How to display the widget.
299
- * @param {string?} params.jwt the JSON Web Token (JWT) that is used
300
- * to validate the data (can be disabled)
301
- *
302
- * @return {Promise} string if true, with the widget template, jsOptions and user details.
215
+ /**
216
+ * Creates/upserts user.
217
+ *
218
+ * @param {Object} params Parameters for request
219
+ * @param {Object?} params.user The user details
220
+ * @param {string} params.user.id The user id
221
+ * @param {string} params.user.accountId The user account id
222
+ * @param {WidgetType} params.widgetType The content of the widget.
223
+ * @param {EngagementMedium?} params.engagementMedium How to display the widget.
224
+ * @param {string?} params.jwt the JSON Web Token (JWT) that is used
225
+ * to validate the data (can be disabled)
226
+ *
227
+ * @return {Promise} string if true, with the widget template, jsOptions and user details.
303
228
  */
304
229
 
305
230
 
306
231
  upsertUser(params) {
307
- const raw = params;
308
- const clean = validateWidgetConfig(raw);
309
- const {
232
+ var raw = params;
233
+ var clean = validateWidgetConfig(raw);
234
+ var {
310
235
  widgetType,
311
236
  engagementMedium = "POPUP",
312
237
  jwt,
313
238
  user
314
239
  } = clean;
315
- const tenantAlias = encodeURIComponent(this.tenantAlias);
316
- const accountId = encodeURIComponent(user.accountId);
317
- const userId = encodeURIComponent(user.id);
240
+ var tenantAlias = encodeURIComponent(this.tenantAlias);
241
+ var accountId = encodeURIComponent(user.accountId);
242
+ var userId = encodeURIComponent(user.id);
318
243
 
319
- const optionalParams = _buildParams({
244
+ var optionalParams = _buildParams({
320
245
  widgetType,
321
246
  engagementMedium
322
247
  });
323
248
 
324
- const path = `/api/v1/${tenantAlias}/widget/account/${accountId}/user/${userId}/upsert${optionalParams}`;
325
- const url = this.domain + path;
326
- const cookies = Cookies__default['default'].get("_saasquatch");
249
+ var path = "/api/v1/" + tenantAlias + "/widget/account/" + accountId + "/user/" + userId + "/upsert" + optionalParams;
250
+ var url = this.domain + path;
251
+ var cookies = (Cookies__default['default'] || window.Cookies).get("_saasquatch");
327
252
  if (cookies) user["cookies"] = cookies;
328
253
  return doPut(url, JSON.stringify(user), jwt);
329
254
  }
330
- /**
331
- * Description here.
332
- *
333
- * @param {Object} params Parameters for request
334
- * @param {Object} params.user The user details
335
- * @param {string} params.user.id The user id
336
- * @param {string} params.user.accountId The user account id
337
- * @param {WidgetType} params.widgetType The content of the widget.
338
- * @param {EngagementMedium} params.engagementMedium How to display the widget.
339
- * @param {string} params.jwt the JSON Web Token (JWT) that is used
340
- * to validate the data (can be disabled)
341
- * @return {Promise} template html if true.
255
+ /**
256
+ * Description here.
257
+ *
258
+ * @param {Object} params Parameters for request
259
+ * @param {Object} params.user The user details
260
+ * @param {string} params.user.id The user id
261
+ * @param {string} params.user.accountId The user account id
262
+ * @param {WidgetType} params.widgetType The content of the widget.
263
+ * @param {EngagementMedium} params.engagementMedium How to display the widget.
264
+ * @param {string} params.jwt the JSON Web Token (JWT) that is used
265
+ * to validate the data (can be disabled)
266
+ * @return {Promise} template html if true.
342
267
  */
343
268
 
344
269
 
345
270
  render(params) {
346
271
  var _clean$locale;
347
272
 
348
- const raw = params;
349
- const clean = validatePasswordlessConfig(raw);
350
- const {
273
+ var raw = params;
274
+ var clean = validatePasswordlessConfig(raw);
275
+ var {
351
276
  widgetType,
352
277
  engagementMedium = "POPUP",
353
278
  jwt,
354
279
  user
355
280
  } = clean;
356
- const tenantAlias = encodeURIComponent(this.tenantAlias);
357
- const accountId = user ? encodeURIComponent(user.accountId) : null;
358
- const userId = user ? encodeURIComponent(user.id) : null;
359
- const locale = (_clean$locale = clean.locale) != null ? _clean$locale : validateLocale(navigator.language.replace(/\-/g, "_"));
360
- const path = `/api/v1/${tenantAlias}/graphql`;
361
- const url = this.domain + path;
281
+ var tenantAlias = encodeURIComponent(this.tenantAlias);
282
+ var accountId = user ? encodeURIComponent(user.accountId) : null;
283
+ var userId = user ? encodeURIComponent(user.id) : null;
284
+ var locale = (_clean$locale = clean.locale) != null ? _clean$locale : validateLocale(navigator.language.replace(/\-/g, "_"));
285
+ var path = "/api/v1/" + tenantAlias + "/graphql";
286
+ var url = this.domain + path;
362
287
  return new Promise(async (resolve, reject) => {
363
288
  try {
364
- var _res$body, _res$body$data;
289
+ var _res$data;
365
290
 
366
- const res = await doQuery(url, RENDER_WIDGET_QUERY, {
291
+ var res = await doQuery(url, RENDER_WIDGET_QUERY, {
367
292
  user: userId && accountId ? {
368
293
  id: userId,
369
294
  accountId
@@ -372,56 +297,27 @@ class WidgetApi {
372
297
  widgetType,
373
298
  locale
374
299
  }, jwt);
375
- resolve(res == null ? void 0 : (_res$body = res.body) == null ? void 0 : (_res$body$data = _res$body.data) == null ? void 0 : _res$body$data.renderWidget);
300
+ resolve(res == null ? void 0 : (_res$data = res.data) == null ? void 0 : _res$data.renderWidget);
376
301
  } catch (e) {
377
302
  reject(e);
378
303
  }
379
304
  });
380
305
  }
381
- /**
382
- * An API call to send out referral invites to contacts
383
- *
384
- * @param {Object} params Parameters for request
385
- * @param {Array} params.emailList The list of recipients to send to
386
- * @param {string} params.userId The user id
387
- * @param {string} params.accountId The user account id
388
- * @param {string} params.tenantAlias The tenant alias
389
- *
390
- * @return {Promise} an object containing total accepted / rejected emails send or error
391
- */
392
-
393
-
394
- invite({
395
- emailList = [],
396
- userId,
397
- accountId,
398
- tenantAlias
399
- }) {
400
- const tenantAliasP = encodeURIComponent(tenantAlias);
401
- const path = `/api/v1/${tenantAliasP}/mail/referralinvite`;
402
- const url = this.domain + path;
403
- const request = {
404
- sendingAccountId: accountId,
405
- sendingUserId: userId,
406
- recipients: emailList
407
- };
408
- return doPost(url, JSON.stringify(request));
409
- }
410
- /**
411
- * Looks up the referral code of the current user, if there is any.
412
- *
413
- * @return {Promise<ReferralCookie>} code referral code if true.
306
+ /**
307
+ * Looks up the referral code of the current user, if there is any.
308
+ *
309
+ * @return {Promise<ReferralCookie>} code referral code if true.
414
310
  */
415
311
 
416
312
 
417
313
  async squatchReferralCookie() {
418
- const tenantAlias = encodeURIComponent(this.tenantAlias);
314
+ var tenantAlias = encodeURIComponent(this.tenantAlias);
419
315
 
420
- const _saasquatch = Cookies__default['default'].get("_saasquatch") || "";
316
+ var _saasquatch = (Cookies__default['default'] || window.Cookies).get("_saasquatch") || "";
421
317
 
422
- const cookie = _saasquatch ? `?cookies=${encodeURIComponent(_saasquatch)}` : ``;
423
- const url = `${this.domain}/a/${tenantAlias}/widgets/squatchcookiejson${cookie}`;
424
- const response = await doGet(url);
318
+ var cookie = _saasquatch ? "?cookies=" + encodeURIComponent(_saasquatch) : "";
319
+ var url = this.domain + "/a/" + tenantAlias + "/widgets/squatchcookiejson" + cookie;
320
+ var response = await doGet(url);
425
321
  return Promise.resolve(_extends({}, response, {
426
322
  encodedCookie: _saasquatch
427
323
  }));
@@ -429,84 +325,99 @@ class WidgetApi {
429
325
 
430
326
  } // builds a param string for widgets
431
327
 
432
- function _buildParams({
433
- widgetType,
434
- engagementMedium
435
- }) {
436
- const widgetTypeP = widgetType ? `?widgetType=${encodeURIComponent(widgetType)}` : ``;
437
- const engagementMediumP = `${widgetType ? "&" : "?"}engagementMedium=${encodeURIComponent(engagementMedium)}`;
438
- const optionalParams = widgetTypeP + engagementMediumP;
328
+ function _buildParams(_ref) {
329
+ var {
330
+ widgetType,
331
+ engagementMedium
332
+ } = _ref;
333
+ var widgetTypeP = widgetType ? "?widgetType=" + encodeURIComponent(widgetType) : "";
334
+ var engagementMediumP = (widgetType ? "&" : "?") + "engagementMedium=" + encodeURIComponent(engagementMedium);
335
+ var optionalParams = widgetTypeP + engagementMediumP;
439
336
  return optionalParams;
440
337
  }
441
338
 
442
339
  // @ts-check
443
- /**
444
- *
445
- * The AnalyticsApi class is a wrapper around the Analytics Endpoints of
446
- * the SaaSquatch REST API. Used to record Widget events.
447
- *
448
- * @hidden
340
+ /**
341
+ *
342
+ * The AnalyticsApi class is a wrapper around the Analytics Endpoints of
343
+ * the SaaSquatch REST API. Used to record Widget events.
344
+ *
345
+ * @hidden
449
346
  */
450
347
 
451
348
  class AnalyticsApi {
452
- /**
453
- * Initialize a new {@link AnalyticsApi} instance.
454
- *
455
- * @param {Object} config Config details
456
- * @param {string} [config.domain='https://app.referralsaasquatch.com'] The server domain.
457
- *
349
+ /**
350
+ * Initialize a new {@link AnalyticsApi} instance.
351
+ *
352
+ * @param {Object} config Config details
353
+ * @param {string} [config.domain='https://app.referralsaasquatch.com'] The server domain.
354
+ *
458
355
  */
459
356
  constructor(config) {
460
- const raw = config;
357
+ var _window$squatchConfig;
461
358
 
462
- if (hasProps(raw, "domain") && typeof raw.domain === "string") {
463
- this.domain = raw.domain;
464
- } else {
465
- this.domain = "https://app.referralsaasquatch.com";
466
- }
359
+ this.domain = void 0;
360
+ var raw = config;
361
+
362
+ var clean = _validateAnalyticsConfig(raw);
363
+
364
+ this.domain = (clean == null ? void 0 : clean["domain"]) || ((_window$squatchConfig = window.squatchConfig) == null ? void 0 : _window$squatchConfig.domain) || DEFAULT_DOMAIN;
467
365
  }
468
366
 
469
367
  pushAnalyticsLoadEvent(params) {
470
368
  if (!params.externalUserId || !params.externalAccountId) return;
471
- const tenantAlias = encodeURIComponent(params.tenantAlias);
472
- const accountId = encodeURIComponent(params.externalAccountId);
473
- const userId = encodeURIComponent(params.externalUserId);
474
- const engagementMedium = encodeURIComponent(params.engagementMedium);
475
- const programId = params.programId ? `&programId=${encodeURIComponent(params.programId)}` : ``;
476
- const path = `/a/${tenantAlias}/widgets/analytics/loaded?externalAccountId=${accountId}&externalUserId=${userId}&engagementMedium=${engagementMedium}${programId}`;
477
- const url = this.domain + path;
369
+ var tenantAlias = encodeURIComponent(params.tenantAlias);
370
+ var accountId = encodeURIComponent(params.externalAccountId);
371
+ var userId = encodeURIComponent(params.externalUserId);
372
+ var engagementMedium = encodeURIComponent(params.engagementMedium);
373
+ var programId = params.programId ? "&programId=" + encodeURIComponent(params.programId) : "";
374
+ var path = "/a/" + tenantAlias + "/widgets/analytics/loaded?externalAccountId=" + accountId + "&externalUserId=" + userId + "&engagementMedium=" + engagementMedium + programId;
375
+ var url = this.domain + path;
478
376
  return doPost(url, JSON.stringify({}));
479
377
  }
480
378
 
481
379
  pushAnalyticsShareClickedEvent(params) {
482
- const tenantAlias = encodeURIComponent(params.tenantAlias);
483
- const accountId = encodeURIComponent(params.externalAccountId);
484
- const userId = encodeURIComponent(params.externalUserId);
485
- const engagementMedium = encodeURIComponent(params.engagementMedium);
486
- const shareMedium = encodeURIComponent(params.shareMedium);
487
- const path = `/a/${tenantAlias}/widgets/analytics/shared?externalAccountId=${accountId}&externalUserId=${userId}&engagementMedium=${engagementMedium}&shareMedium=${shareMedium}`;
488
- const url = this.domain + path;
380
+ var tenantAlias = encodeURIComponent(params.tenantAlias);
381
+ var accountId = encodeURIComponent(params.externalAccountId);
382
+ var userId = encodeURIComponent(params.externalUserId);
383
+ var engagementMedium = encodeURIComponent(params.engagementMedium);
384
+ var shareMedium = encodeURIComponent(params.shareMedium);
385
+ var path = "/a/" + tenantAlias + "/widgets/analytics/shared?externalAccountId=" + accountId + "&externalUserId=" + userId + "&engagementMedium=" + engagementMedium + "&shareMedium=" + shareMedium;
386
+ var url = this.domain + path;
489
387
  return doPost(url, JSON.stringify({}));
490
388
  }
491
389
 
492
390
  }
493
391
 
392
+ function _validateAnalyticsConfig(raw) {
393
+ if (!isObject$1(raw)) throw new Error("'options' should be an object");
394
+ return raw;
395
+ }
396
+
494
397
  // @ts-check
495
398
  /** @hidden */
496
399
 
497
- const _log$7 = debug__default['default']("squatch-js:widget");
498
- /*
499
- * The Widget class is the base class for the different widget types available
500
- *
501
- * Creates an `iframe` in which the html content of the widget gets embedded.
502
- * Uses element-resize-detector (https://github.com/wnr/element-resize-detector)
503
- * for listening to the height of the widget content and make the iframe responsive.
504
- *
400
+ var _log$7 = debug.debug("squatch-js:widget");
401
+ /*
402
+ * The Widget class is the base class for the different widget types available
403
+ *
404
+ * Creates an `iframe` in which the html content of the widget gets embedded.
405
+ * Uses element-resize-detector (https://github.com/wnr/element-resize-detector)
406
+ * for listening to the height of the widget content and make the iframe responsive.
407
+ *
505
408
  */
506
409
 
507
410
 
508
411
  class Widget {
509
412
  constructor(params) {
413
+ this.type = void 0;
414
+ this.content = void 0;
415
+ this.analyticsApi = void 0;
416
+ this.widgetApi = void 0;
417
+ this.context = void 0;
418
+ this.npmCdn = void 0;
419
+ this.container = void 0;
420
+
510
421
  _log$7("widget initializing ...");
511
422
 
512
423
  this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
@@ -516,12 +427,47 @@ class Widget {
516
427
  this.analyticsApi = new AnalyticsApi({
517
428
  domain: params.domain
518
429
  });
519
- this.frame = document.createElement("iframe");
520
- this.frame["squatchJsApi"] = this;
521
- this.frame.width = "100%";
522
- this.frame.scrolling = "no";
523
- this.frame.setAttribute("style", "border: 0; background-color: none; width: 1px; min-width: 100%;");
524
430
  this.context = params.context;
431
+ this.container = params.container;
432
+ }
433
+
434
+ _findElement() {
435
+ var element;
436
+
437
+ if (typeof this.container === "string") {
438
+ // selector is a string
439
+ element = document.querySelector(this.container);
440
+
441
+ _log$7("loading widget with selector", element); // selector is an HTML element
442
+
443
+ } else if (this.container instanceof HTMLElement) {
444
+ element = this.container;
445
+
446
+ _log$7("loading widget with container", element); // garbage container found
447
+
448
+ } else if (this.container) {
449
+ element = null;
450
+
451
+ _log$7("container must be an HTMLElement or string", this.container); // find element on page
452
+
453
+ } else {
454
+ element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed");
455
+
456
+ _log$7("loading widget with default selector", element);
457
+ }
458
+
459
+ if (!(element instanceof HTMLElement)) throw new Error("element with selector '" + (this.container || "#squatchembed or .squatchembed") + "' not found.'");
460
+ return element;
461
+ }
462
+
463
+ _createFrame() {
464
+ var frame = document.createElement("iframe");
465
+ frame["squatchJsApi"] = this;
466
+ frame.width = "100%";
467
+ frame.src = "about:blank";
468
+ frame.scrolling = "no";
469
+ frame.setAttribute("style", "border: 0; background-color: none; width: 1px; min-width: 100%;");
470
+ return frame;
525
471
  }
526
472
 
527
473
  _loadEvent(sqh) {
@@ -533,13 +479,10 @@ class Widget {
533
479
  throw new Error("Widget Load event identity property is not an object");
534
480
  }
535
481
 
536
- let params;
537
-
538
- if (hasProps(sqh, "programId")) {
539
- if (!hasProps(sqh, ["tenantAlias", "accountId", "userId", "engagementMedium"])) {
540
- throw new Error("Widget Load event missing required properties");
541
- }
482
+ var params;
542
483
 
484
+ if ("programId" in sqh) {
485
+ if (!sqh.tenantAlias || !sqh.accountId || !sqh.userId || !sqh.engagementMedium) throw new Error("Widget Load event missing required properties");
543
486
  params = {
544
487
  tenantAlias: sqh.tenantAlias,
545
488
  externalAccountId: sqh.accountId,
@@ -548,7 +491,7 @@ class Widget {
548
491
  programId: sqh.programId
549
492
  };
550
493
  } else {
551
- const {
494
+ var {
552
495
  analytics,
553
496
  mode
554
497
  } = sqh;
@@ -561,9 +504,9 @@ class Widget {
561
504
  }
562
505
 
563
506
  (_this$analyticsApi$pu = this.analyticsApi.pushAnalyticsLoadEvent(params)) == null ? void 0 : _this$analyticsApi$pu.then(response => {
564
- _log$7(`${params.engagementMedium} loaded event recorded.`);
507
+ _log$7(params.engagementMedium + " loaded event recorded.");
565
508
  }).catch(ex => {
566
- _log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
509
+ _log$7(new Error("pushAnalyticsLoadEvent() " + ex));
567
510
  });
568
511
  }
569
512
 
@@ -576,80 +519,44 @@ class Widget {
576
519
  engagementMedium: sqh.mode.widgetMode,
577
520
  shareMedium: medium
578
521
  }).then(response => {
579
- _log$7(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
522
+ _log$7(sqh.mode.widgetMode + " share " + medium + " event recorded. " + response);
580
523
  }).catch(ex => {
581
- _log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
524
+ _log$7(new Error("pushAnalyticsLoadEvent() " + ex));
582
525
  });
583
526
  }
584
- }
527
+ } // TODO: CA: Refactor how error templates are shown
585
528
 
586
- _inviteContacts(sqh, emailList) {
587
- if (sqh) {
588
- this.widgetApi.invite({
589
- tenantAlias: sqh.analytics.attributes.tenant,
590
- accountId: sqh.analytics.attributes.accountId,
591
- userId: sqh.analytics.attributes.userId,
592
- emailList
593
- }).then(response => {
594
- _log$7(`Sent email invites to share ${emailList}. ${response}`);
595
- }).catch(ex => {
596
- _log$7(new Error(`invite() ${ex}`));
597
- });
529
+
530
+ _error(rs, mode, style) {
531
+ if (mode === void 0) {
532
+ mode = "modal";
598
533
  }
599
- }
600
534
 
601
- _error(rs, mode = "modal", style = "") {
602
- const errorTemplate = `<!DOCTYPE html>
603
- <!--[if IE 7]><html class="ie7 oldie" lang="en"><![endif]-->
604
- <!--[if IE 8]><html class="ie8 oldie" lang="en"><![endif]-->
605
- <!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
606
- <head>
607
- <link rel="stylesheet" media="all" href="https://fast.ssqt.io/assets/css/widget/errorpage.css">
608
- <style>
609
- ${style}
610
- </style>
611
- </head>
612
- <body>
613
-
614
- <div class="squatch-container ${mode}" style="width:100%">
615
- <div class="errorheader">
616
- <button type="button" class="close" onclick="window.frameElement.squatchJsApi.close();">&times;</button>
617
- <p class="errortitle">Error</p>
618
- </div>
619
- <div class="errorbody">
620
- <div class="sadface"><img src="https://fast.ssqt.io/assets/images/face.png"></div>
621
- <h4>Our referral program is temporarily unavailable.</h4><br>
622
- <p>Please reload the page or check back later.</p>
623
- <p>If the persists please contact our support team.</p>
624
- <br>
625
- <br>
626
- <div class="right-align errtxt">
627
- Error Code: ${rs}
628
- </div>
629
- </div>
630
- </div>
631
- </body>
632
- </html>`;
535
+ if (style === void 0) {
536
+ style = "";
537
+ }
538
+
539
+ var errorTemplate = "<!DOCTYPE html>\n <!--[if IE 7]><html class=\"ie7 oldie\" lang=\"en\"><![endif]-->\n <!--[if IE 8]><html class=\"ie8 oldie\" lang=\"en\"><![endif]-->\n <!--[if gt IE 8]><!--><html lang=\"en\"><!--<![endif]-->\n <head>\n <link rel=\"stylesheet\" media=\"all\" href=\"https://fast.ssqt.io/assets/css/widget/errorpage.css\">\n <style>\n " + style + "\n </style>\n </head>\n <body>\n\n <div class=\"squatch-container " + mode + "\" style=\"width:100%\">\n <div class=\"errorheader\">\n <button type=\"button\" class=\"close\" onclick=\"window.frameElement.squatchJsApi.close();\">&times;</button>\n <p class=\"errortitle\">Error</p>\n </div>\n <div class=\"errorbody\">\n <div class=\"sadface\"><img src=\"https://fast.ssqt.io/assets/images/face.png\"></div>\n <h4>Our referral program is temporarily unavailable.</h4><br>\n <p>Please reload the page or check back later.</p>\n <p>If the persists please contact our support team.</p>\n <br>\n <br>\n <div class=\"right-align errtxt\">\n Error Code: " + rs + "\n </div>\n </div>\n </div>\n </body>\n </html>";
633
540
  return errorTemplate;
634
541
  }
635
542
 
636
- async _findInnerContainer() {
637
- const {
543
+ async _findInnerContainer(frame) {
544
+ var {
638
545
  contentWindow
639
- } = this.frame;
546
+ } = frame;
640
547
  if (!contentWindow) throw new Error("Squatch.js frame inner frame is empty");
641
- const frameDoc = contentWindow.document;
548
+ var frameDoc = contentWindow.document;
642
549
 
643
550
  function search() {
644
- const containers = frameDoc.getElementsByTagName("sqh-global-container");
645
- const legacyContainers = frameDoc.getElementsByClassName("squatch-container");
646
- const fallback = containers.length > 0 ? containers[0] : legacyContainers.length > 0 ? legacyContainers[0] : null;
551
+ var containers = frameDoc.getElementsByTagName("sqh-global-container");
552
+ var legacyContainers = frameDoc.getElementsByClassName("squatch-container");
553
+ var fallback = containers.length > 0 ? containers[0] : legacyContainers.length > 0 ? legacyContainers[0] : null;
647
554
  return fallback;
648
555
  }
649
556
 
650
- let found = null;
557
+ var found = null;
651
558
 
652
- for (let i = 0; i < 5; i++) {
559
+ for (var i = 0; i < 5; i++) {
653
560
  found = search();
654
561
  if (found) break;
655
562
  await delay(100);
@@ -661,28 +568,34 @@ class Widget {
661
568
 
662
569
  return found;
663
570
  }
571
+ /**
572
+ * Reloads the current widget, makes updated request to API and renders result.
573
+ * Primarily for Classic widgets with registration
574
+ * @param param0 Form field values
575
+ * @param jwt JWT for API authentication
576
+ */
664
577
 
665
- reload({
666
- email,
667
- firstName,
668
- lastName
669
- }, jwt) {
670
- const frameWindow = this.frame.contentWindow;
671
- const engagementMedium = this.context.engagementMedium || "POPUP";
578
+
579
+ reload(frame, _ref, jwt) {
580
+ var {
581
+ email,
582
+ firstName,
583
+ lastName
584
+ } = _ref;
585
+ var frameWindow = frame.contentWindow;
586
+ var engagementMedium = this.context.engagementMedium || "POPUP";
672
587
 
673
588
  if (!frameWindow) {
674
589
  throw new Error("Frame needs a content window");
675
590
  }
676
591
 
677
- const frameDoc = frameWindow.document;
678
- let response;
592
+ var response;
679
593
 
680
594
  if (this.context.type === "upsert") {
681
- let userObj = {
595
+ var userObj = {
682
596
  email: email || null,
683
597
  firstName: firstName || null,
684
598
  lastName: lastName || null,
685
- // FIXME: Double check this
686
599
  id: this.context.user.id,
687
600
  accountId: this.context.user.accountId
688
601
  };
@@ -703,66 +616,80 @@ class Widget {
703
616
  throw new Error("can't reload an error widget");
704
617
  }
705
618
 
706
- response.then(({
707
- template
708
- }) => {
709
- if (template) {
710
- this.content = template;
711
- const showStatsBtn = frameDoc.createElement("button");
712
- const registerForm = frameDoc.getElementsByClassName("squatch-register")[0];
713
-
714
- if (registerForm) {
715
- showStatsBtn.className = "btn btn-primary";
716
- showStatsBtn.id = "show-stats-btn";
717
- showStatsBtn.textContent = this.type === "REFERRER_WIDGET" ? "Show Stats" : "Show Reward";
718
- const widgetStyle = engagementMedium === "POPUP" ? "margin-top: 10px; max-width: 130px; width: 100%;" : "margin-top: 10px;";
719
- showStatsBtn.setAttribute("style", widgetStyle);
619
+ response.then(_ref2 => {
620
+ var {
621
+ template
622
+ } = _ref2;
720
623
 
721
- showStatsBtn.onclick = () => {
722
- this.load(); // @ts-ignore -- open exists in the PopupWidget, so this call will always exist when it's called.
723
-
724
- engagementMedium === "POPUP" && this.open();
725
- }; // @ts-ignore -- expect register form to be a stylable element
624
+ if (template) {
625
+ this.content = template; // Support for classic widget registration forms
726
626
 
627
+ this.__deprecated__register(frame, {
628
+ email,
629
+ engagementMedium
630
+ }, () => {
631
+ this.load(frame); // @ts-ignore -- open exists in the PopupWidget, so this call will always exist when it's called.
727
632
 
728
- registerForm.style.paddingTop = "30px";
729
- registerForm.innerHTML = `<p><strong>${email}</strong><br>Has been successfully registered</p>`;
730
- registerForm.appendChild(showStatsBtn);
731
- }
633
+ engagementMedium === "POPUP" && this.open(frame);
634
+ });
732
635
  }
733
- }).catch(({
734
- message
735
- }) => {
736
- _log$7(`${message}`);
636
+ }).catch(_ref3 => {
637
+ var {
638
+ message
639
+ } = _ref3;
640
+
641
+ _log$7("" + message);
737
642
  });
738
643
  }
739
644
 
645
+ __deprecated__register(frame, params, onClick) {
646
+ var frameWindow = frame.contentWindow;
647
+ var frameDoc = frameWindow.document;
648
+ var showStatsBtn = frameDoc.createElement("button");
649
+ var registerForm = frameDoc.getElementsByClassName("squatch-register")[0];
650
+
651
+ if (registerForm) {
652
+ showStatsBtn.className = "btn btn-primary";
653
+ showStatsBtn.id = "show-stats-btn";
654
+ showStatsBtn.textContent = this.type === "REFERRER_WIDGET" ? "Show Stats" : "Show Reward";
655
+ var widgetStyle = params.engagementMedium === "POPUP" ? "margin-top: 10px; max-width: 130px; width: 100%;" : "margin-top: 10px;";
656
+ showStatsBtn.setAttribute("style", widgetStyle);
657
+ showStatsBtn.onclick = onClick; // @ts-ignore -- expect register form to be a stylable element
658
+
659
+ registerForm.style.paddingTop = "30px";
660
+ registerForm.innerHTML = "<p><strong>" + params.email + "</strong><br>Has been successfully registered</p>";
661
+ registerForm.appendChild(showStatsBtn);
662
+ }
663
+ }
664
+
740
665
  }
741
666
 
742
667
  function delay(duration) {
743
668
  return new Promise(function (resolve, reject) {
744
669
  setTimeout(function () {
745
- resolve();
670
+ resolve(() => {});
746
671
  }, duration);
747
672
  });
748
673
  }
749
674
 
750
- /*!
751
- * domready (c) Dustin Diaz 2014 - License MIT
752
- *
675
+ /*!
676
+ * domready (c) Dustin Diaz 2014 - License MIT
677
+ *
753
678
  */
754
679
  function domready(targetDoc, fn) {
755
- let fns = [];
756
- let listener;
757
- let doc = targetDoc;
758
- let hack = doc.documentElement.doScroll;
759
- let domContentLoaded = "DOMContentLoaded";
760
- let loaded = (hack ? /^loaded|^c/ : /^loaded|^i|^c/).test(doc.readyState);
680
+ var fns = [];
681
+ var listener;
682
+ var doc = targetDoc;
683
+ var hack = doc.documentElement.doScroll;
684
+ var domContentLoaded = "DOMContentLoaded";
685
+ var loaded = (hack ? /^loaded|^c/ : /^loaded|^i|^c/).test(doc.readyState);
761
686
  if (!loaded) doc.addEventListener(domContentLoaded, listener = () => {
762
687
  doc.removeEventListener(domContentLoaded, listener);
763
688
  loaded = true;
764
689
 
765
- while (listener = fns.shift()) listener();
690
+ while (listener = fns.shift()) {
691
+ listener();
692
+ }
766
693
  }); // @ts-ignore
767
694
 
768
695
  return loaded ? setTimeout(fn, 0) : fns.push(fn);
@@ -770,78 +697,55 @@ function domready(targetDoc, fn) {
770
697
 
771
698
  // @ts-check
772
699
 
773
- const _log$6 = debug__default['default']("squatch-js:EMBEDwidget");
774
- /**
775
- * An EmbedWidget is displayed inline in part of your page.
776
- *
777
- * To create an EmbedWidget use {@link Widgets}
778
- *
700
+ var _log$6 = debug.debug("squatch-js:EMBEDwidget");
701
+ /**
702
+ * An EmbedWidget is displayed inline in part of your page.
703
+ *
704
+ * To create an EmbedWidget use {@link Widgets}
705
+ *
779
706
  */
780
707
 
781
708
 
782
709
  class EmbedWidget extends Widget {
783
710
  constructor(params, container) {
784
711
  super(params);
785
- let element;
786
-
787
- if (typeof container === "string") {
788
- // selector is a string
789
- element = document.querySelector(container);
790
-
791
- _log$6("loading widget with selector", element); // selector is an HTML element
792
-
793
- } else if (container instanceof HTMLElement) {
794
- element = container;
795
-
796
- _log$6("loading widget with container", element); // garbage container found
797
-
798
- } else if (container) {
799
- element = null;
800
-
801
- _log$6("container must be an HTMLElement or string", container); // find element on page
802
-
803
- } else {
804
- element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed");
805
-
806
- _log$6("loading widget with default selector", element);
807
- }
808
-
809
- if (!(element instanceof HTMLElement)) throw new Error(`element with selector '${container}' not found.'`);
810
- this.element = element;
712
+ this.show = this.open;
713
+ this.hide = this.close;
811
714
  }
812
715
 
813
- async load() {
814
- if (this.context.container) {
815
- this.element.style.visibility = "hidden";
816
- this.element.style.height = "0";
817
- this.element.style["overflow-y"] = "hidden"; // Widget reloaded - replace existing element
716
+ async load(frame) {
717
+ var element = this._findElement();
818
718
 
819
- if (this.element.firstChild) {
820
- this.element.replaceChild(this.frame, this.element.firstChild); // Add iframe for the first time
719
+ if (this.container) {
720
+ if (element.shadowRoot) {
721
+ element.shadowRoot.appendChild(frame);
722
+ } // Widget reloaded - replace existing element
723
+ else if (element.firstChild) {
724
+ element.replaceChild(frame, element.firstChild); // Add iframe for the first time
821
725
  } else {
822
- this.element.appendChild(this.frame);
726
+ element.appendChild(frame);
823
727
  }
824
- } else if (!this.element.firstChild || this.element.firstChild.nodeName === "#text") {
825
- this.element.appendChild(this.frame);
728
+ } else if (!element.firstChild || element.firstChild.nodeName === "#text") {
729
+ element.appendChild(frame);
826
730
  }
827
731
 
828
- const {
732
+ var {
829
733
  contentWindow
830
- } = this.frame;
734
+ } = frame;
831
735
 
832
736
  if (!contentWindow) {
833
737
  throw new Error("Frame needs a content window");
834
738
  }
835
739
 
836
- const frameDoc = contentWindow.document;
740
+ var frameDoc = contentWindow.document;
837
741
  frameDoc.open();
838
742
  frameDoc.write(this.content);
839
- frameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
743
+ frameDoc.write("<script src=\"" + this.npmCdn + "/resize-observer-polyfill@1.5.x\"></script>");
840
744
  frameDoc.close();
841
745
  domready(frameDoc, async () => {
842
- const _sqh = contentWindow.squatch || contentWindow.widgetIdent;
746
+ var _sqh = contentWindow.squatch || contentWindow.widgetIdent;
843
747
 
844
- const ctaElement = frameDoc.getElementById("cta");
748
+ var ctaElement = frameDoc.getElementById("cta");
845
749
 
846
750
  if (ctaElement) {
847
751
  if (!ctaElement.parentNode) {
@@ -852,21 +756,20 @@ class EmbedWidget extends Widget {
852
756
  } // @ts-ignore -- number will be cast to string by browsers
853
757
 
854
758
 
855
- this.frame.height = frameDoc.body.scrollHeight; // Adjust frame height when size of body changes
856
- // @ts-ignore
759
+ frame.height = frameDoc.body.scrollHeight; // Adjust frame height when size of body changes
857
760
 
858
- const ro = new contentWindow["ResizeObserver"](entries => {
859
- for (const entry of entries) {
860
- const {
761
+ var ro = new contentWindow["ResizeObserver"](entries => {
762
+ for (var entry of entries) {
763
+ var {
861
764
  height
862
765
  } = entry.contentRect; // @ts-ignore -- number will be cast to string by browsers
863
766
 
864
- this.frame.height = height;
767
+ frame.height = height;
865
768
  }
866
769
  });
867
- ro.observe(await this._findInnerContainer()); // Regular load - trigger event
770
+ ro.observe(await this._findInnerContainer(frame)); // Regular load - trigger event
868
771
 
869
- if (!this.context.container) {
772
+ if (!this.container) {
870
773
  this._loadEvent(_sqh);
871
774
 
872
775
  _log$6("loaded");
@@ -875,32 +778,46 @@ class EmbedWidget extends Widget {
875
778
  } // Un-hide if element is available and refresh data
876
779
 
877
780
 
878
- open() {
879
- var _this$frame, _this$frame$contentDo, _this$frame2, _this$frame2$contentW, _this$frame3, _this$frame3$contentW;
781
+ open(frame) {
782
+ var _frame$contentDocumen, _frame$contentWindow, _frame$contentWindow2;
880
783
 
881
- if (!this.frame) return _log$6("no target element to open");
882
- this.element.style.visibility = "unset";
883
- this.element.style.height = "auto";
884
- this.element.style["overflow-y"] = "auto";
885
- (_this$frame = this.frame) == null ? void 0 : (_this$frame$contentDo = _this$frame.contentDocument) == null ? void 0 : _this$frame$contentDo.dispatchEvent(new CustomEvent("sq:refresh"));
784
+ if (!frame) return _log$6("no target element to open");
886
785
 
887
- const _sqh = ((_this$frame2 = this.frame) == null ? void 0 : (_this$frame2$contentW = _this$frame2.contentWindow) == null ? void 0 : _this$frame2$contentW.squatch) || ((_this$frame3 = this.frame) == null ? void 0 : (_this$frame3$contentW = _this$frame3.contentWindow) == null ? void 0 : _this$frame3$contentW.widgetIdent);
786
+ var element = this._findElement();
787
+
788
+ element.style.visibility = "unset";
789
+ element.style.height = "auto";
790
+ element.style["overflow-y"] = "auto";
791
+ frame == null ? void 0 : (_frame$contentDocumen = frame.contentDocument) == null ? void 0 : _frame$contentDocumen.dispatchEvent(new CustomEvent("sq:refresh"));
792
+
793
+ var _sqh = (frame == null ? void 0 : (_frame$contentWindow = frame.contentWindow) == null ? void 0 : _frame$contentWindow.squatch) || (frame == null ? void 0 : (_frame$contentWindow2 = frame.contentWindow) == null ? void 0 : _frame$contentWindow2.widgetIdent);
888
794
 
889
795
  this._loadEvent(_sqh);
890
796
 
891
797
  _log$6("loaded");
892
798
  }
893
799
 
894
- close() {
895
- if (!this.frame) return _log$6("no target element to close");
896
- this.element.style.visibility = "hidden";
897
- this.element.style.height = "0";
898
- this.element.style["overflow-y"] = "hidden";
800
+ close(frame) {
801
+ if (!frame) return _log$6("no target element to close");
802
+
803
+ var element = this._findElement();
804
+
805
+ element.style.visibility = "hidden";
806
+ element.style.height = "0";
807
+ element.style["overflow-y"] = "hidden";
899
808
 
900
809
  _log$6("Embed widget closed");
901
810
  }
902
811
 
903
- _error(rs, mode = "embed", style = "") {
812
+ _error(rs, mode, style) {
813
+ if (mode === void 0) {
814
+ mode = "embed";
815
+ }
816
+
817
+ if (style === void 0) {
818
+ style = "";
819
+ }
820
+
904
821
  return super._error(rs, mode, style);
905
822
  }
906
823
 
@@ -908,78 +825,117 @@ class EmbedWidget extends Widget {
908
825
 
909
826
  // @ts-check
910
827
 
911
- const _log$5 = debug__default['default']("squatch-js:POPUPwidget");
912
- /**
913
- * The PopupWidget is used to display popups (also known as "Modals").
914
- * Popups widgets are rendered on top of other elements in a page.
915
- *
916
- * To create a PopupWidget use {@link Widgets}
917
- *
918
- */
828
+ var _log$5 = debug.debug("squatch-js:POPUPwidget");
919
829
 
830
+ var popupId = 0;
831
+ /**
832
+ * The PopupWidget is used to display popups (also known as "Modals").
833
+ * Popups widgets are rendered on top of other elements in a page.
834
+ *
835
+ * To create a PopupWidget use {@link Widgets}
836
+ *
837
+ */
920
838
 
921
839
  class PopupWidget extends Widget {
922
- constructor(params, trigger = ".squatchpop") {
840
+ constructor(params, trigger) {
841
+ if (trigger === void 0) {
842
+ trigger = ".squatchpop";
843
+ }
844
+
923
845
  super(params);
846
+ this.trigger = void 0;
847
+ this.id = void 0;
848
+ this.show = this.open;
849
+ this.hide = this.close;
850
+ this.trigger = trigger;
851
+
852
+ if (this.container) {
853
+ this.id = "squatchModal";
854
+ } else {
855
+ this.id = popupId === 0 ? "squatchModal" : "squatchModal__" + popupId;
856
+ popupId = popupId + 1;
857
+ }
858
+
859
+ document.head.insertAdjacentHTML("beforeend", "<style>#" + this.id + "::-webkit-scrollbar { display: none; }</style>");
860
+ }
861
+
862
+ _initialiseCTA(frame) {
863
+ var triggerElement;
924
864
 
925
865
  try {
926
- this.triggerElement
866
+ triggerElement
927
867
  /* HTMLButton */
928
- = document.querySelector(trigger);
929
- if (trigger && !this.triggerElement) _log$5("No element found with trigger selector", trigger);
868
+ = document.querySelector(this.trigger);
869
+ if (this.trigger && !triggerElement) _log$5("No element found with trigger selector", this.trigger);
930
870
  } catch (_unused) {
931
- _log$5("Not a valid selector", trigger);
871
+ _log$5("Not a valid selector", this.trigger);
932
872
  } // Trigger is optional
933
873
 
934
874
 
935
- if (this.triggerElement) {
936
- this.triggerElement.onclick = () => {
937
- this.open();
875
+ if (triggerElement) {
876
+ triggerElement.onclick = () => {
877
+ this.open(frame);
938
878
  };
939
- } // If widget is loaded with CTA, look for a 'squatchpop' element to use
879
+ }
880
+
881
+ var element = this._findElement(); // If widget is loaded with CTA, look for a 'squatchpop' element to use
940
882
  // that element as a trigger as well.
941
883
 
942
884
 
943
- this.triggerWhenCTA = document.querySelector(".squatchpop");
885
+ var triggerWhenCTA = element.querySelector(".squatchpop");
944
886
 
945
- if (trigger === "#cta" && this.triggerWhenCTA) {
946
- this.triggerWhenCTA.onclick = () => {
947
- this.open();
887
+ if (this.trigger === "#cta" && triggerWhenCTA) {
888
+ triggerWhenCTA.onclick = () => {
889
+ this.open(frame);
948
890
  };
949
891
  }
892
+ }
950
893
 
951
- this.popupdiv = document.createElement("div");
952
- this.popupdiv.id = "squatchModal";
953
- this.popupdiv.setAttribute("style", "display: none; position: fixed; z-index: 1; padding-top: 5%; left: 0; top: -2000px; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4);");
954
- document.head.insertAdjacentHTML("beforeend", `<style>#squatchModal::-webkit-scrollbar { display: none; }</style>`);
955
- this.popupcontent = document.createElement("div");
956
- this.popupcontent.setAttribute("style", "margin: auto; width: 80%; max-width: 500px; position: relative;");
894
+ _createPopupDialog() {
895
+ var dialog = document.createElement("dialog");
896
+ dialog.id = this.id;
897
+ dialog.setAttribute("style", "width: 100%; max-width: 500px; border: none; padding: 0;");
957
898
 
958
- this.popupdiv.onclick = event => {
959
- this._clickedOutside(event);
899
+ var onClick = e => {
900
+ if (e.target === dialog) dialog.close();
960
901
  };
902
+
903
+ dialog.addEventListener("click", onClick);
904
+ return dialog;
961
905
  }
962
906
 
963
- load() {
964
- this.popupdiv.appendChild(this.popupcontent);
965
- document.body.appendChild(this.popupdiv);
966
- this.popupcontent.appendChild(this.frame); //@ts-ignore -- will occasionally throw a null pointer exception at runtime
907
+ load(frame) {
908
+ this._initialiseCTA(frame);
909
+
910
+ var element = this._findElement();
911
+
912
+ var dialogParent = element.shadowRoot || element;
913
+
914
+ var dialog = this._createPopupDialog();
967
915
 
968
- const frameDoc = this.frame.contentWindow.document;
916
+ dialog.appendChild(frame);
917
+ dialogParent.appendChild(dialog);
918
+ var {
919
+ contentWindow
920
+ } = frame;
921
+
922
+ if (!contentWindow) {
923
+ throw new Error("Frame needs a content window");
924
+ }
925
+
926
+ var frameDoc = contentWindow.document;
969
927
  frameDoc.open();
970
928
  frameDoc.write(this.content);
971
- frameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
929
+ frameDoc.write("<script src=\"" + this.npmCdn + "/resize-observer-polyfill@1.5.x\"></script>");
972
930
  frameDoc.close();
973
931
 
974
932
  _log$5("Popup template loaded into iframe");
975
933
 
976
- this._setupResizeHandler();
934
+ this._setupResizeHandler(frame);
977
935
  }
978
936
 
979
- _setupResizeHandler() {
980
- const popupdiv = this.popupdiv;
981
- const frame = this.frame;
982
- const {
937
+ _setupResizeHandler(frame) {
938
+ var {
983
939
  contentWindow
984
940
  } = frame;
985
941
 
@@ -987,59 +943,46 @@ class PopupWidget extends Widget {
987
943
  throw new Error("Frame needs a content window");
988
944
  }
989
945
 
990
- const frameDoc = contentWindow.document; // Adjust frame height when size of body changes
946
+ var frameDoc = contentWindow.document; // Adjust frame height when size of body changes
991
947
 
992
948
  domready(frameDoc, async () => {
993
949
  frameDoc.body.style.overflowY = "hidden";
994
- popupdiv.style.visibility = "hidden";
995
- popupdiv.style.display = "block";
996
- frame.height = `${frameDoc.body.offsetHeight}px`; // Adjust frame height when size of body changes
950
+ frame.height = frameDoc.body.offsetHeight + "px"; // Adjust frame height when size of body changes
997
951
 
998
- const ro = new contentWindow["ResizeObserver"](entries => {
999
- for (const entry of entries) {
1000
- const {
952
+ var ro = new contentWindow["ResizeObserver"](entries => {
953
+ for (var entry of entries) {
954
+ var {
1001
955
  top,
1002
956
  bottom
1003
957
  } = entry.contentRect;
1004
- const computedHeight = bottom + top;
958
+ var computedHeight = bottom + top;
1005
959
  frame.height = computedHeight + ""; // Don't let anything else set the height of this element
1006
960
 
1007
- entry.target.style = ``;
1008
-
1009
- if (window.innerHeight > Number(frame.height)) {
1010
- popupdiv.style.paddingTop = `${(window.innerHeight - Number(frame.height)) / 2}px`;
1011
- } else {
1012
- popupdiv.style.paddingTop = "5px";
1013
- }
961
+ entry.target.style = "";
1014
962
  }
1015
963
  });
1016
- ro.observe(await this._findInnerContainer());
964
+ ro.observe(await this._findInnerContainer(frame));
1017
965
  });
1018
966
  }
1019
967
 
1020
- open() {
1021
- const popupdiv = this.popupdiv;
1022
- const frame = this.frame;
1023
- const {
968
+ open(frame) {
969
+ var element = this._findElement();
970
+
971
+ var parent = element.shadowRoot || element;
972
+ var dialog = parent.querySelector("#" + this.id);
973
+ if (!dialog) throw new Error("Could not determine container div");
974
+ dialog.showModal();
975
+ var {
1024
976
  contentWindow
1025
977
  } = frame;
1026
978
  if (!contentWindow) throw new Error("Squatch.js has an empty iframe");
1027
- const frameDoc = contentWindow.document; // Adjust frame height when size of body changes
979
+ var frameDoc = contentWindow.document; // Adjust frame height when size of body changes
1028
980
 
1029
981
  domready(frameDoc, () => {
1030
982
  var _frame$contentDocumen;
1031
983
 
1032
- const _sqh = contentWindow.squatch || contentWindow.widgetIdent;
1033
-
1034
- const ctaElement = frameDoc.getElementById("cta");
984
+ var _sqh = contentWindow.squatch || contentWindow.widgetIdent;
1035
985
 
1036
- if (ctaElement) {
1037
- //@ts-ignore -- will occasionally throw a null pointer exception at runtime
1038
- ctaElement.parentNode.removeChild(ctaElement);
1039
- }
1040
-
1041
- popupdiv.style.visibility = "visible";
1042
- popupdiv.style.top = "0px";
1043
986
  (_frame$contentDocumen = frame.contentDocument) == null ? void 0 : _frame$contentDocumen.dispatchEvent(new CustomEvent("sq:refresh"));
1044
987
 
1045
988
  this._loadEvent(_sqh);
@@ -1049,218 +992,92 @@ class PopupWidget extends Widget {
1049
992
  }
1050
993
 
1051
994
  close() {
1052
- this.popupdiv.style.visibility = "hidden";
1053
- this.popupdiv.style.top = "-2000px";
995
+ var dialog = document.getElementById(this.id);
996
+ if (!dialog) throw new Error("Could not determine container div");
997
+ dialog.close();
1054
998
 
1055
999
  _log$5("Popup closed");
1056
1000
  }
1057
1001
 
1058
- _clickedOutside({
1059
- target
1060
- }) {
1061
- if (target === this.popupdiv) {
1062
- this.close();
1063
- }
1002
+ _clickedOutside(_ref) {
1064
1003
  }
1065
1004
 
1066
- _error(rs, mode = "modal", style = "") {
1067
- const _style = "body { margin: 0; } .modal { box-shadow: none; border: 0; }";
1068
- return super._error(rs, mode, style || _style);
1069
- }
1070
-
1071
- }
1072
-
1073
- const _log$4 = debug__namespace("squatch-js:CTAwidget");
1074
- /**
1075
- * A CtaWidget is displayed on top of your page
1076
- *
1077
- * To create a CtaWidget use {@link Widgets}
1078
- *
1079
- */
1080
-
1081
-
1082
- class CtaWidget extends PopupWidget {
1083
- constructor(params, opts) {
1084
- _log$4("CTA constructor");
1085
-
1086
- const ctaElement = document.createElement("div");
1087
- ctaElement.id = "cta";
1088
- document.body.appendChild(ctaElement);
1089
- super(params, "#cta");
1090
-
1091
- if (!opts.side && !opts.position) {
1092
- opts.position = "bottom";
1093
- opts.side = "right";
1094
- }
1095
-
1096
- if (opts.position === "middle") {
1097
- this.position = "top: 45%;";
1098
- this.side = opts.side === "center" ? "right: 45%;" : `${opts.side}: -10px;`;
1099
- } else {
1100
- this.position = `${opts.position}: -10px;`;
1101
- this.side = opts.side === "center" ? "right: 45%;" : `${opts.side}: 20px;`;
1005
+ _error(rs, mode, style) {
1006
+ if (mode === void 0) {
1007
+ mode = "modal";
1102
1008
  }
1103
1009
 
1104
- this.positionClass = opts.position;
1105
- this.ctaFrame = document.createElement("iframe"); // @ts-ignore - we are creating this pass-through
1106
-
1107
- this.ctaFrame.squatchJsApi = this;
1108
- this.ctaFrame.scrolling = "no";
1109
- this.ctaFrame.setAttribute("style", `border:0; background-color:transparent; position:fixed; display:none;${this.side}${this.position}`);
1110
- document.body.appendChild(this.ctaFrame);
1111
-
1112
- _log$4("ctaframe appended to body");
1113
- }
1114
-
1115
- load() {
1116
- super.load();
1117
-
1118
- if (!this.frame.contentWindow) {
1119
- throw new Error("frame requires a contentWindow");
1010
+ if (style === void 0) {
1011
+ style = "";
1120
1012
  }
1121
1013
 
1122
- const widgetFrameDoc = this.frame.contentWindow.document;
1123
- const ctaFrame = this.ctaFrame;
1124
- const positionClass = this.positionClass; // Wait for widget doc to be ready to grab the cta HTML
1125
-
1126
- domready(widgetFrameDoc, () => {
1127
- const ctaElement = widgetFrameDoc.getElementById("cta");
1128
-
1129
- if (ctaElement) {
1130
- if (!ctaElement.parentNode) {
1131
- throw new Error("ctaElement requires a parentNode");
1132
- }
1133
-
1134
- ctaElement.parentNode.removeChild(ctaElement);
1135
- const ctaFrameWindow = ctaFrame.contentWindow;
1136
-
1137
- if (!ctaFrameWindow) {
1138
- throw new Error("ctaFrame requires a contentWindow");
1139
- }
1140
-
1141
- const ctaFrameDoc = ctaFrameWindow.document;
1142
- ctaFrameDoc.open();
1143
- ctaFrameDoc.write(ctaElement.innerHTML);
1144
- ctaFrameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
1145
- ctaFrameDoc.close(); // Figure out size of CTA as well
1146
-
1147
- domready(ctaFrameDoc, () => {
1148
- const ctaContainer = ctaFrameDoc.getElementsByClassName("cta-container")[0]; // @ts-ignore - Assume it's a stylable element, die otherwise
1149
-
1150
- ctaContainer.style.position = "fixed"; // @ts-ignore - Assume it's an element with offsetHeight
1151
-
1152
- ctaFrame.height = ctaContainer.offsetHeight; // @ts-ignore - Browser will cast from number to string (we hope)
1153
-
1154
- ctaFrame.width = ctaContainer.scrollWidth;
1155
- ctaFrame.style.display = "block";
1156
-
1157
- if (!ctaContainer.classList.contains(positionClass)) {
1158
- ctaContainer.className += ` ${positionClass}`;
1159
- } // Adjust frame height when size of body changes
1160
-
1161
-
1162
- const ro = new ctaFrameWindow["ResizeObserver"](entries => {
1163
- for (const entry of entries) {
1164
- const {
1165
- height,
1166
- width
1167
- } = entry.contentRect; // @ts-ignore - Browser will cast from number to string (we hope)
1168
-
1169
- ctaFrame.height = height; // @ts-ignore - Browser will cast from number to string (we hope)
1170
-
1171
- ctaFrame.width = width;
1172
- }
1173
- });
1174
- ro.observe(ctaContainer);
1175
-
1176
- _log$4("CTA template loaded into iframe");
1177
- });
1178
- } else {
1179
- _log$4(new Error("CTA element not found in theme"));
1180
- }
1181
- });
1182
- }
1183
- /**
1184
- * @inheritdoc
1185
- */
1186
-
1187
-
1188
- open() {
1189
- super.open();
1190
- }
1191
- /**
1192
- * @inheritdoc
1193
- */
1194
-
1195
-
1196
- close() {
1197
- super.close();
1014
+ var _style = "body { margin: 0; } .modal { box-shadow: none; border: 0; }";
1015
+ return super._error(rs, mode, style || _style);
1198
1016
  }
1199
1017
 
1200
1018
  }
1201
1019
 
1202
- const _log$3 = debug__default['default']("squatch-js:widgets");
1203
- /**
1204
- *
1205
- * `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
1206
- * {@link WidgetApi} but most people will prefer to use these easy methods.
1207
- *
1020
+ var _log$4 = debug.debug("squatch-js:widgets");
1021
+ /**
1022
+ *
1023
+ * `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
1024
+ * {@link WidgetApi} but most people will prefer to use these easy methods.
1025
+ *
1208
1026
  */
1209
1027
 
1210
1028
 
1211
1029
  class Widgets {
1212
- /**
1213
- * Initialize a new {@link Widgets} instance.
1214
- *
1215
- * @param {ConfigOptions} config Config details
1216
- *
1217
- * @example <caption>Browser example</caption>
1218
- * var widgets = new squatch.Widgets({tenantAlias:'test_12b5bo1b25125'});
1219
- *
1220
- * @example <caption>Browserify/Webpack example</caption>
1221
- * var Widgets = require('@saasquatch/squatch-js').Widgets;
1222
- * var widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1223
- *
1224
- * @example <caption>Babel+Browserify/Webpack example</caption>
1225
- * import {Widgets} from '@saasquatch/squatch-js';
1226
- * let widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1030
+ /**
1031
+ * Initialize a new {@link Widgets} instance.
1032
+ *
1033
+ * @param {ConfigOptions} config Config details
1034
+ *
1035
+ * @example <caption>Browser example</caption>
1036
+ * var widgets = new squatch.Widgets({tenantAlias:'test_12b5bo1b25125'});
1037
+ *
1038
+ * @example <caption>Browserify/Webpack example</caption>
1039
+ * var Widgets = require('@saasquatch/squatch-js').Widgets;
1040
+ * var widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1041
+ *
1042
+ * @example <caption>Babel+Browserify/Webpack example</caption>
1043
+ * import {Widgets} from '@saasquatch/squatch-js';
1044
+ * let widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1227
1045
  */
1228
1046
  constructor(configin) {
1229
- const raw = configin;
1230
- const config = validateConfig(raw);
1047
+ this.api = void 0;
1048
+ this.tenantAlias = void 0;
1049
+ this.domain = void 0;
1050
+ this.npmCdn = void 0;
1051
+ var config = validateConfig(configin);
1231
1052
  this.tenantAlias = config.tenantAlias;
1232
1053
  this.domain = config.domain;
1233
- this.npmCdn = config.npmCdn; // for with locals custom theme, can be removed once with locals isnt' using eventBus anymore.
1234
-
1235
- this.eventBus = EventBus__namespace;
1054
+ this.npmCdn = config.npmCdn;
1236
1055
  this.api = new WidgetApi(config); // listens to a 'submit_email' event in the theme.
1237
-
1238
- EventBus__namespace.addEventListener("submit_email", Widgets._cb);
1239
- }
1240
- /**
1241
- * This function calls the {@link WidgetApi.upsertUser} method, and it renders
1242
- * the widget if it is successful. Otherwise it shows the "error" widget.
1243
- *
1244
- * @param {Object} config Config details
1245
- * @param {Object} config.user The user details
1246
- * @param {string} config.user.id The user id
1247
- * @param {string} config.user.accountId The user account id
1248
- * @param {WidgetType} config.widgetType The content of the widget.
1249
- * @param {EngagementMedium} config.engagementMedium How to display the widget.
1250
- * @param {string} config.jwt the JSON Web Token (JWT) that is used to validate the data (can be disabled)
1251
- * @param {HTMLElement | string | undefined} config.container Element to load the widget into
1252
- * @param {string | undefined} config.trigger Trigger element for opening the popup widget
1253
- *
1254
- * @return {Promise<WidgetResult>} json object if true, with a Widget and user details.
1056
+ }
1057
+ /**
1058
+ * This function calls the {@link WidgetApi.upsertUser} method, and it renders
1059
+ * the widget if it is successful. Otherwise it shows the "error" widget.
1060
+ *
1061
+ * @param {Object} config Config details
1062
+ * @param {Object} config.user The user details
1063
+ * @param {string} config.user.id The user id
1064
+ * @param {string} config.user.accountId The user account id
1065
+ * @param {WidgetType} config.widgetType The content of the widget.
1066
+ * @param {EngagementMedium} config.engagementMedium How to display the widget.
1067
+ * @param {string} config.jwt the JSON Web Token (JWT) that is used to validate the data (can be disabled)
1068
+ * @param {HTMLElement | string | undefined} config.container Element to load the widget into
1069
+ * @param {string | undefined} config.trigger Trigger element for opening the popup widget
1070
+ *
1071
+ * @return {Promise<WidgetResult>} json object if true, with a Widget and user details.
1255
1072
  */
1256
1073
 
1257
1074
 
1258
1075
  async upsertUser(config) {
1259
- const raw = config;
1260
- const clean = validateWidgetConfig(raw);
1076
+ var raw = config;
1077
+ var clean = validateWidgetConfig(raw);
1261
1078
 
1262
1079
  try {
1263
- const response = await this.api.upsertUser(clean);
1080
+ var response = await this.api.upsertUser(clean);
1264
1081
  return {
1265
1082
  widget: this._renderWidget(response, clean, {
1266
1083
  type: "upsert",
@@ -1272,7 +1089,7 @@ class Widgets {
1272
1089
  user: response.user
1273
1090
  };
1274
1091
  } catch (err) {
1275
- _log$3(err);
1092
+ _log$4(err);
1276
1093
 
1277
1094
  if (err.apiErrorCode) {
1278
1095
  this._renderErrorWidget(err, config.engagementMedium);
@@ -1281,29 +1098,29 @@ class Widgets {
1281
1098
  throw err;
1282
1099
  }
1283
1100
  }
1284
- /**
1285
- * This function calls the {@link WidgetApi.render} method, and it renders
1286
- * the widget if it is successful. Otherwise it shows the "error" widget.
1287
- *
1288
- * @param {Object} config Config details
1289
- * @param {Object} config.user The user details
1290
- * @param {string} config.user.id The user id
1291
- * @param {string} config.user.accountId The user account id
1292
- * @param {WidgetType} config.widgetType The content of the widget.
1293
- * @param {EngagementMedium} config.engagementMedium How to display the widget.
1294
- * @param {string} config.jwt the JSON Web Token (JWT) that is used
1295
- * to validate the data (can be disabled)
1296
- *
1297
- * @return {Promise<WidgetResult>} json object if true, with a Widget and user details.
1101
+ /**
1102
+ * This function calls the {@link WidgetApi.render} method, and it renders
1103
+ * the widget if it is successful. Otherwise it shows the "error" widget.
1104
+ *
1105
+ * @param {Object} config Config details
1106
+ * @param {Object} config.user The user details
1107
+ * @param {string} config.user.id The user id
1108
+ * @param {string} config.user.accountId The user account id
1109
+ * @param {WidgetType} config.widgetType The content of the widget.
1110
+ * @param {EngagementMedium} config.engagementMedium How to display the widget.
1111
+ * @param {string} config.jwt the JSON Web Token (JWT) that is used
1112
+ * to validate the data (can be disabled)
1113
+ *
1114
+ * @return {Promise<WidgetResult>} json object if true, with a Widget and user details.
1298
1115
  */
1299
1116
 
1300
1117
 
1301
1118
  async render(config) {
1302
- const raw = config;
1303
- const clean = validatePasswordlessConfig(raw);
1119
+ var raw = config;
1120
+ var clean = validatePasswordlessConfig(raw);
1304
1121
 
1305
1122
  try {
1306
- const response = await this.api.render(clean);
1123
+ var response = await this.api.render(clean);
1307
1124
  return {
1308
1125
  widget: this._renderWidget(response, clean, {
1309
1126
  type: "passwordless",
@@ -1319,21 +1136,23 @@ class Widgets {
1319
1136
  throw err;
1320
1137
  }
1321
1138
  }
1322
- /**
1323
- * Autofills a referral code into an element when someone has been referred.
1324
- * Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
1325
- *
1326
- * @param selector Element class/id selector, or a callback function
1327
- * @returns
1139
+ /**
1140
+ * Autofills a referral code into an element when someone has been referred.
1141
+ * Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
1142
+ *
1143
+ * @param selector Element class/id selector, or a callback function
1144
+ * @returns
1328
1145
  */
1329
1146
 
1330
1147
 
1331
1148
  autofill(selector) {
1332
- const input = selector;
1149
+ var input = selector;
1333
1150
 
1334
1151
  if (typeof input === "function") {
1335
- this.api.squatchReferralCookie().then((...args) => input(...args)).catch(ex => {
1336
- _log$3("Autofill error", ex);
1152
+ this.api.squatchReferralCookie().then(function () {
1153
+ return input(...arguments);
1154
+ }).catch(ex => {
1155
+ _log$4("Autofill error", ex);
1337
1156
 
1338
1157
  throw ex;
1339
1158
  });
@@ -1341,59 +1160,45 @@ class Widgets {
1341
1160
  }
1342
1161
 
1343
1162
  if (typeof input !== "string") throw new Error("Autofill accepts a string or function");
1344
- let elems = document.querySelectorAll(input);
1345
- let elem;
1163
+ var elems = document.querySelectorAll(input);
1164
+ var elem;
1346
1165
 
1347
1166
  if (elems.length > 0) {
1348
1167
  // Only use the first element found
1349
1168
  elem = elems[0];
1350
1169
  } else {
1351
- _log$3("Element id/class or function missing");
1170
+ _log$4("Element id/class or function missing");
1352
1171
 
1353
1172
  throw new Error("Element id/class or function missing");
1354
1173
  }
1355
1174
 
1356
- this.api.squatchReferralCookie() //@ts-ignore
1357
- .then(({
1358
- code
1359
- }) => {
1360
- elem.value = code;
1175
+ this.api.squatchReferralCookie().then(_ref => {
1176
+ var {
1177
+ codes
1178
+ } = _ref;
1179
+ elem.value = codes[0];
1361
1180
  }).catch(ex => {
1362
1181
  throw ex;
1363
1182
  });
1364
1183
  }
1365
- /**
1366
- * Overrides the default function that submits the user email. If you have
1367
- * Security enabled, the email needs to be signed before it's submitted.
1368
- *
1369
- * @param {function} fn Callback function for the 'submit_email' event.
1370
- * @returns {void}
1371
- */
1372
-
1373
-
1374
- submitEmail(fn) {
1375
- EventBus__namespace.removeEventListener("submit_email", Widgets._cb);
1376
- EventBus__namespace.addEventListener("submit_email", fn);
1377
- }
1378
- /**
1379
- * @hidden
1380
- * @param {Object} response The json object return from the WidgetApi
1381
- * @param {Object} config Config details
1382
- * @param {string} config.widgetType The widget type (REFERRER_WIDGET, CONVERSION_WIDGET)
1383
- * @param {string} config.engagementMedium (POPUP, EMBED)
1384
- * @returns {Widget} widget (PopupWidget, EmbedWidget, or CtaWidget)
1184
+ /**
1185
+ * @hidden
1186
+ * @param {Object} response The json object return from the WidgetApi
1187
+ * @param {Object} config Config details
1188
+ * @param {string} config.widgetType The widget type (REFERRER_WIDGET, CONVERSION_WIDGET)
1189
+ * @param {string} config.engagementMedium (POPUP, EMBED)
1190
+ * @returns {Widget} widget (PopupWidget or EmbedWidget)
1385
1191
  */
1386
1192
 
1387
1193
 
1388
1194
  _renderWidget(response, config, context) {
1389
- _log$3("Rendering Widget...");
1195
+ _log$4("Rendering Widget...");
1390
1196
 
1391
1197
  if (!response) throw new Error("Unable to get a response");
1392
- let widget;
1393
- let displayOnLoad = !!config.displayOnLoad;
1394
- let displayCTA = false;
1395
- const opts = response.jsOptions || "";
1396
- const params = {
1198
+ var widget;
1199
+ var displayOnLoad = !!config.displayOnLoad;
1200
+ var opts = response.jsOptions || "";
1201
+ var params = {
1397
1202
  content: response.template,
1398
1203
  type: config.widgetType || opts.widget.defaultWidgetType,
1399
1204
  api: this.api,
@@ -1407,67 +1212,47 @@ class Widgets {
1407
1212
  if (Widgets._matchesUrl(rule.url)) {
1408
1213
  if (rule.widgetType !== "CONVERSION_WIDGET" || response.user.referredBy && response.user.referredBy.code) {
1409
1214
  displayOnLoad = rule.displayOnLoad;
1410
- displayCTA = rule.showAsCTA;
1411
1215
 
1412
- _log$3(`Display ${rule.widgetType} on ${rule.url}`);
1216
+ _log$4("Display " + rule.widgetType + " on " + rule.url);
1413
1217
  } else {
1414
- _log$3(`Don't display ${rule.widgetType} when no referral on widget rule match ${rule.url}`);
1218
+ _log$4("Don't display " + rule.widgetType + " when no referral on widget rule match " + rule.url);
1415
1219
  }
1416
1220
  }
1417
1221
  });
1418
1222
  }
1419
1223
 
1420
- if (opts.conversionUrls) {
1421
- opts.conversionUrls.forEach(rule => {
1422
- if (response.user.referredBy && Widgets._matchesUrl(rule)) {
1423
- _log$3("This is a conversion URL", rule);
1424
- }
1425
- });
1426
- }
1427
-
1428
1224
  if (opts.fuelTankAutofillUrls) {
1429
- _log$3("We found a fuel tank autofill!");
1225
+ _log$4("We found a fuel tank autofill!");
1226
+
1227
+ opts.fuelTankAutofillUrls.forEach(_ref2 => {
1228
+ var {
1229
+ url,
1230
+ formSelector
1231
+ } = _ref2;
1430
1232
 
1431
- opts.fuelTankAutofillUrls.forEach(({
1432
- url,
1433
- formSelector
1434
- }) => {
1435
1233
  if (Widgets._matchesUrl(url)) {
1436
- _log$3("Fuel Tank URL matches");
1234
+ _log$4("Fuel Tank URL matches");
1437
1235
 
1438
1236
  if (response.user.referredBy && response.user.referredBy.code) {
1439
- const formAutofill = document.querySelector(formSelector);
1237
+ var formAutofill = document.querySelector(formSelector);
1440
1238
 
1441
1239
  if (formAutofill) {
1442
1240
  formAutofill.value = response.user.referredBy.referredReward.fuelTankCode || "";
1443
1241
  } else {
1444
- _log$3(new Error(`Element with id/class ${formSelector} was not found.`));
1242
+ _log$4(new Error("Element with id/class " + formSelector + " was not found."));
1445
1243
  }
1446
1244
  }
1447
1245
  }
1448
1246
  });
1449
1247
  }
1450
1248
 
1451
- if (!displayCTA && config.engagementMedium === "EMBED") {
1452
- widget = new EmbedWidget(params, params.context.container);
1453
- widget.load();
1454
- } else if (!displayCTA && config.engagementMedium === "POPUP") {
1455
- widget = new PopupWidget(params, params.context.trigger);
1456
- widget.load();
1457
- if (displayOnLoad) widget.open();
1458
- } else if (displayCTA) {
1459
- _log$3("display CTA");
1460
-
1461
- const side = opts.cta.content.buttonSide;
1462
- const position = opts.cta.content.buttonPosition;
1463
- widget = new CtaWidget(params, {
1464
- side,
1465
- position
1466
- });
1467
- widget.load();
1249
+ if (config.engagementMedium === "EMBED") {
1250
+ this._renderEmbedWidget(params, params.context.container);
1251
+ } else if (config.engagementMedium === "POPUP") {
1252
+ widget = this._renderPopupWidget(params);
1468
1253
  if (displayOnLoad) widget.open();
1469
1254
  } else {
1470
- _log$3("display popup on load");
1255
+ _log$4("display popup on load");
1471
1256
 
1472
1257
  widget = new PopupWidget(params);
1473
1258
  widget.load();
@@ -1476,24 +1261,45 @@ class Widgets {
1476
1261
 
1477
1262
  return widget;
1478
1263
  }
1479
- /**
1480
- * @hidden
1481
- * @param {Object} error The json object containing the error details
1482
- * @param {string} em The engagementMedium
1483
- * @returns {void}
1264
+
1265
+ _renderPopupWidget(params) {
1266
+ var widget = new PopupWidget(params, params.context.trigger);
1267
+
1268
+ var frame = widget._createFrame();
1269
+
1270
+ widget.load(frame);
1271
+ return widget;
1272
+ }
1273
+
1274
+ _renderEmbedWidget(params, container) {
1275
+ var widget = new EmbedWidget(params);
1276
+
1277
+ var frame = widget._createFrame();
1278
+
1279
+ widget.load(frame);
1280
+ }
1281
+ /**
1282
+ * @hidden
1283
+ * @param {Object} error The json object containing the error details
1284
+ * @param {string} em The engagementMedium
1285
+ * @returns {void}
1484
1286
  */
1485
1287
 
1486
1288
 
1487
- _renderErrorWidget(props, em = "POPUP") {
1488
- const {
1289
+ _renderErrorWidget(props, em) {
1290
+ if (em === void 0) {
1291
+ em = "POPUP";
1292
+ }
1293
+
1294
+ var {
1489
1295
  apiErrorCode,
1490
1296
  rsCode,
1491
1297
  message
1492
1298
  } = props;
1493
1299
 
1494
- _log$3(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
1300
+ _log$4(new Error(apiErrorCode + " (" + rsCode + ") " + message));
1495
1301
 
1496
- const params = {
1302
+ var params = {
1497
1303
  content: "error",
1498
1304
  rsCode,
1499
1305
  api: this.api,
@@ -1504,20 +1310,26 @@ class Widgets {
1504
1310
  type: "error"
1505
1311
  }
1506
1312
  };
1507
- let widget;
1313
+ var widget;
1508
1314
 
1509
1315
  if (em === "EMBED") {
1510
1316
  widget = new EmbedWidget(params);
1511
- widget.load();
1317
+
1318
+ var frame = widget._createFrame();
1319
+
1320
+ widget.load(frame);
1512
1321
  } else if (em === "POPUP") {
1513
1322
  widget = new PopupWidget(params);
1514
- widget.load();
1323
+
1324
+ var _frame = widget._createFrame();
1325
+
1326
+ widget.load(_frame);
1515
1327
  }
1516
1328
  }
1517
- /**
1518
- * @hidden
1519
- * @param {string} rule A regular expression
1520
- * @returns {boolean} true if rule matches Url, false otherwise
1329
+ /**
1330
+ * @hidden
1331
+ * @param {string} rule A regular expression
1332
+ * @returns {boolean} true if rule matches Url, false otherwise
1521
1333
  */
1522
1334
 
1523
1335
 
@@ -1525,18 +1337,18 @@ class Widgets {
1525
1337
  // If there were no matches, null is returned.
1526
1338
  return window.location.href.match(new RegExp(rule)) ? true : false;
1527
1339
  }
1528
- /**
1529
- * @hidden
1530
- * @param {Object} target Object containing the target DOM element
1531
- * @param {Widget} widget A widget (EmbedWidget, PopupWidget, CtaWidget)
1532
- * @param {Object} params An object with valid parameters
1533
- * (e.g) {email:'email', firstName:'firstName'}
1534
- * @returns {void}
1340
+ /**
1341
+ * @hidden
1342
+ * @param {Object} target Object containing the target DOM element
1343
+ * @param {Widget} widget A widget (EmbedWidget, PopupWidget)
1344
+ * @param {Object} params An object with valid parameters
1345
+ * (e.g) {email:'email', firstName:'firstName'}
1346
+ * @returns {void}
1535
1347
  */
1536
1348
 
1537
1349
 
1538
1350
  static _cb(target, widget, params) {
1539
- let paramsObj; // If params is a string, then it should be an email
1351
+ var paramsObj; // If params is a string, then it should be an email
1540
1352
 
1541
1353
  if (typeof params === "string" || params instanceof String) {
1542
1354
  paramsObj = {
@@ -1552,71 +1364,76 @@ class Widgets {
1552
1364
 
1553
1365
  }
1554
1366
 
1555
- /**
1556
- *
1557
- * The EventsApi class is a wrapper around the open endpoints of the SaaSquatch REST API.
1558
- *
1367
+ /**
1368
+ *
1369
+ * The EventsApi class is a wrapper around the open endpoints of the SaaSquatch REST API.
1370
+ *
1559
1371
  */
1560
1372
 
1561
1373
  class EventsApi {
1562
- /**
1563
- * Initialize a new {@link EventsApi} instance.
1564
- *
1565
- * @param {ConfigOptions} config Config details
1566
- *
1567
- * @example <caption>Browser example</caption>
1568
- * var squatchApi = new squatch.EventsApi({tenantAlias:'test_12b5bo1b25125'});
1569
- *
1570
- * @example <caption>Browserify/Webpack example</caption>
1571
- * var EventsApi = require('@saasquatch/squatch-js').EventsApi;
1572
- * var squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1573
- *
1574
- * @example <caption>Babel+Browserify/Webpack example</caption>
1575
- * import {EventsApi} from '@saasquatch/squatch-js';
1576
- * let squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1374
+ /**
1375
+ * Initialize a new {@link EventsApi} instance.
1376
+ *
1377
+ * @param {ConfigOptions} config Config details
1378
+ *
1379
+ * @example <caption>Browser example</caption>
1380
+ * var squatchApi = new squatch.EventsApi({tenantAlias:'test_12b5bo1b25125'});
1381
+ *
1382
+ * @example <caption>Browserify/Webpack example</caption>
1383
+ * var EventsApi = require('@saasquatch/squatch-js').EventsApi;
1384
+ * var squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1385
+ *
1386
+ * @example <caption>Babel+Browserify/Webpack example</caption>
1387
+ * import {EventsApi} from '@saasquatch/squatch-js';
1388
+ * let squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1577
1389
  */
1578
1390
  constructor(config) {
1579
- const raw = config; // Flags that we need to validate anything we use from this type
1391
+ this.tenantAlias = void 0;
1392
+ this.domain = void 0;
1393
+ var raw = config; // Flags that we need to validate anything we use from this type
1580
1394
 
1581
- const clean = validateConfig(raw);
1395
+ var clean = validateConfig(raw);
1582
1396
  this.tenantAlias = clean.tenantAlias;
1583
1397
  this.domain = clean.domain;
1584
1398
  }
1585
- /**
1586
- * Track an event for a user
1587
- *
1588
- * @param params Parameters for request
1589
- * @param options.jwt the JSON Web Token (JWT) that is used to authenticate the user
1590
- *
1591
- * @return An ID to confirm the event has been accepted for asynchronous processing
1399
+ /**
1400
+ * Track an event for a user
1401
+ *
1402
+ * @param params Parameters for request
1403
+ * @param options.jwt the JSON Web Token (JWT) that is used to authenticate the user
1404
+ *
1405
+ * @return An ID to confirm the event has been accepted for asynchronous processing
1592
1406
  */
1593
1407
 
1594
1408
 
1595
1409
  track(params, options) {
1596
- const raw = params;
1597
- const rawOpts = options;
1410
+ var raw = params;
1411
+ var rawOpts = options;
1598
1412
 
1599
- const body = _validateEvent(raw);
1413
+ var body = _validateEvent(raw);
1600
1414
 
1601
- const {
1415
+ var {
1602
1416
  jwt
1603
1417
  } = _validateTrackOptions(rawOpts);
1604
1418
 
1605
- const ta = encodeURIComponent(this.tenantAlias);
1606
- const userId = encodeURIComponent(body.userId);
1607
- const accountId = encodeURIComponent(body.accountId);
1608
- const path = `/api/v1/${ta}/open/account/${accountId}/user/${userId}/events`;
1609
- const url = this.domain + path;
1419
+ var ta = encodeURIComponent(this.tenantAlias);
1420
+ var userId = encodeURIComponent(body.userId);
1421
+ var accountId = encodeURIComponent(body.accountId);
1422
+ var path = "/api/v1/" + ta + "/open/account/" + accountId + "/user/" + userId + "/events";
1423
+ var url = this.domain + path;
1610
1424
  return doPost(url, JSON.stringify(body), jwt);
1611
1425
  }
1612
1426
 
1613
1427
  }
1614
1428
 
1615
1429
  function _validateEvent(raw) {
1616
- if (!assertProp(raw, "accountId", "events", "userId")) ;
1617
- if (!Array.isArray(raw.events)) throw new Error("'events' should be an array"); // TODO: Better type checking
1618
-
1619
- return raw;
1430
+ if (!isObject$1(raw)) throw new Error("tracking parameter must be an object");
1431
+ if (!(raw != null && raw["accountId"])) throw new Error("accountId field is required");
1432
+ if (!(raw != null && raw["events"])) throw new Error("events field is required");
1433
+ if (!(raw != null && raw["userId"])) throw new Error("userId field is required");
1434
+ var clean = raw;
1435
+ if (!Array.isArray(clean.events)) throw new Error("'events' should be an array");
1436
+ return clean;
1620
1437
  }
1621
1438
 
1622
1439
  function _validateTrackOptions(raw) {
@@ -1626,12 +1443,13 @@ function _validateTrackOptions(raw) {
1626
1443
 
1627
1444
  /** @hidden */
1628
1445
  function asyncLoad() {
1629
- const loaded = window.squatch || null;
1630
- const cached = window._squatch || null;
1446
+ var loaded = window.squatch || null;
1447
+ var cached = window._squatch || null;
1631
1448
 
1632
1449
  if (loaded && cached) {
1633
- const ready = cached.ready || [];
1634
- ready.forEach(cb => setTimeout(() => cb(), 0)); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
1450
+ var ready = cached.ready || [];
1451
+ ready.forEach(cb => setTimeout(() => cb(), 0));
1452
+ setTimeout(() => window.squatch._auto(), 0); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
1635
1453
 
1636
1454
  window._squatch = undefined;
1637
1455
 
@@ -1643,392 +1461,16 @@ function asyncLoad() {
1643
1461
  }
1644
1462
  }
1645
1463
 
1646
- /*! (c) Andrea Giammarchi - ISC */
1647
- var self = undefined || /* istanbul ignore next */ {};
1648
- try {
1649
- (function (URLSearchParams, plus) {
1650
- if (
1651
- new URLSearchParams('q=%2B').get('q') !== plus ||
1652
- new URLSearchParams({q: plus}).get('q') !== plus ||
1653
- new URLSearchParams([['q', plus]]).get('q') !== plus ||
1654
- new URLSearchParams('q=\n').toString() !== 'q=%0A' ||
1655
- new URLSearchParams({q: ' &'}).toString() !== 'q=+%26' ||
1656
- new URLSearchParams({q: '%zx'}).toString() !== 'q=%25zx'
1657
- )
1658
- throw URLSearchParams;
1659
- self.URLSearchParams = URLSearchParams;
1660
- }(URLSearchParams, '+'));
1661
- } catch(URLSearchParams) {
1662
- (function (Object, String, isArray) { var create = Object.create;
1663
- var defineProperty = Object.defineProperty;
1664
- var find = /[!'\(\)~]|%20|%00/g;
1665
- var findPercentSign = /%(?![0-9a-fA-F]{2})/g;
1666
- var plus = /\+/g;
1667
- var replace = {
1668
- '!': '%21',
1669
- "'": '%27',
1670
- '(': '%28',
1671
- ')': '%29',
1672
- '~': '%7E',
1673
- '%20': '+',
1674
- '%00': '\x00'
1675
- };
1676
- var proto = {
1677
- append: function (key, value) {
1678
- appendTo(this._ungap, key, value);
1679
- },
1680
- delete: function (key) {
1681
- delete this._ungap[key];
1682
- },
1683
- get: function (key) {
1684
- return this.has(key) ? this._ungap[key][0] : null;
1685
- },
1686
- getAll: function (key) {
1687
- return this.has(key) ? this._ungap[key].slice(0) : [];
1688
- },
1689
- has: function (key) {
1690
- return key in this._ungap;
1691
- },
1692
- set: function (key, value) {
1693
- this._ungap[key] = [String(value)];
1694
- },
1695
- forEach: function (callback, thisArg) {
1696
- var self = this;
1697
- for (var key in self._ungap)
1698
- self._ungap[key].forEach(invoke, key);
1699
- function invoke(value) {
1700
- callback.call(thisArg, value, String(key), self);
1701
- }
1702
- },
1703
- toJSON: function () {
1704
- return {};
1705
- },
1706
- toString: function () {
1707
- var query = [];
1708
- for (var key in this._ungap) {
1709
- var encoded = encode(key);
1710
- for (var
1711
- i = 0,
1712
- value = this._ungap[key];
1713
- i < value.length; i++
1714
- ) {
1715
- query.push(encoded + '=' + encode(value[i]));
1716
- }
1717
- }
1718
- return query.join('&');
1719
- }
1720
- };
1721
- for (var key in proto)
1722
- defineProperty(URLSearchParams.prototype, key, {
1723
- configurable: true,
1724
- writable: true,
1725
- value: proto[key]
1726
- });
1727
- self.URLSearchParams = URLSearchParams;
1728
- function URLSearchParams(query) {
1729
- var dict = create(null);
1730
- defineProperty(this, '_ungap', {value: dict});
1731
- switch (true) {
1732
- case !query:
1733
- break;
1734
- case typeof query === 'string':
1735
- if (query.charAt(0) === '?') {
1736
- query = query.slice(1);
1737
- }
1738
- for (var
1739
- pairs = query.split('&'),
1740
- i = 0,
1741
- length = pairs.length; i < length; i++
1742
- ) {
1743
- var value = pairs[i];
1744
- var index = value.indexOf('=');
1745
- if (-1 < index) {
1746
- appendTo(
1747
- dict,
1748
- decode(value.slice(0, index)),
1749
- decode(value.slice(index + 1))
1750
- );
1751
- } else if (value.length){
1752
- appendTo(
1753
- dict,
1754
- decode(value),
1755
- ''
1756
- );
1757
- }
1758
- }
1759
- break;
1760
- case isArray(query):
1761
- for (var
1762
- i = 0,
1763
- length = query.length; i < length; i++
1764
- ) {
1765
- var value = query[i];
1766
- appendTo(dict, value[0], value[1]);
1767
- }
1768
- break;
1769
- case 'forEach' in query:
1770
- query.forEach(addEach, dict);
1771
- break;
1772
- default:
1773
- for (var key in query)
1774
- appendTo(dict, key, query[key]);
1775
- }
1776
- }
1777
-
1778
- function addEach(value, key) {
1779
- appendTo(this, key, value);
1780
- }
1781
-
1782
- function appendTo(dict, key, value) {
1783
- var res = isArray(value) ? value.join(',') : value;
1784
- if (key in dict)
1785
- dict[key].push(res);
1786
- else
1787
- dict[key] = [res];
1788
- }
1789
-
1790
- function decode(str) {
1791
- return decodeURIComponent(str.replace(findPercentSign, '%25').replace(plus, ' '));
1792
- }
1793
-
1794
- function encode(str) {
1795
- return encodeURIComponent(str).replace(find, replacer);
1796
- }
1797
-
1798
- function replacer(match) {
1799
- return replace[match];
1800
- }
1801
-
1802
- }(Object, String, Array.isArray));
1803
- }
1804
-
1805
- (function (URLSearchParamsProto) {
1806
-
1807
- var iterable = false;
1808
- try { iterable = !!Symbol.iterator; } catch (o_O) {}
1809
-
1810
- /* istanbul ignore else */
1811
- if (!('forEach' in URLSearchParamsProto)) {
1812
- URLSearchParamsProto.forEach = function forEach(callback, thisArg) {
1813
- var self = this;
1814
- var names = Object.create(null);
1815
- this.toString()
1816
- .replace(/=[\s\S]*?(?:&|$)/g, '=')
1817
- .split('=')
1818
- .forEach(function (name) {
1819
- if (!name.length || name in names)
1820
- return;
1821
- (names[name] = self.getAll(name)).forEach(function(value) {
1822
- callback.call(thisArg, value, name, self);
1823
- });
1824
- });
1825
- };
1826
- }
1827
-
1828
- /* istanbul ignore else */
1829
- if (!('keys' in URLSearchParamsProto)) {
1830
- URLSearchParamsProto.keys = function keys() {
1831
- return iterator(this, function(value, key) { this.push(key); });
1832
- };
1833
- }
1834
-
1835
- /* istanbul ignore else */
1836
- if (!('values' in URLSearchParamsProto)) {
1837
- URLSearchParamsProto.values = function values() {
1838
- return iterator(this, function(value, key) { this.push(value); });
1839
- };
1840
- }
1841
-
1842
- /* istanbul ignore else */
1843
- if (!('entries' in URLSearchParamsProto)) {
1844
- URLSearchParamsProto.entries = function entries() {
1845
- return iterator(this, function(value, key) { this.push([key, value]); });
1846
- };
1847
- }
1848
-
1849
- /* istanbul ignore else */
1850
- if (iterable && !(Symbol.iterator in URLSearchParamsProto)) {
1851
- URLSearchParamsProto[Symbol.iterator] = URLSearchParamsProto.entries;
1852
- }
1853
-
1854
- /* istanbul ignore else */
1855
- if (!('sort' in URLSearchParamsProto)) {
1856
- URLSearchParamsProto.sort = function sort() {
1857
- var
1858
- entries = this.entries(),
1859
- entry = entries.next(),
1860
- done = entry.done,
1861
- keys = [],
1862
- values = Object.create(null),
1863
- i, key, value
1864
- ;
1865
- while (!done) {
1866
- value = entry.value;
1867
- key = value[0];
1868
- keys.push(key);
1869
- if (!(key in values)) {
1870
- values[key] = [];
1871
- }
1872
- values[key].push(value[1]);
1873
- entry = entries.next();
1874
- done = entry.done;
1875
- }
1876
- // not the champion in efficiency
1877
- // but these two bits just do the job
1878
- keys.sort();
1879
- for (i = 0; i < keys.length; i++) {
1880
- this.delete(keys[i]);
1881
- }
1882
- for (i = 0; i < keys.length; i++) {
1883
- key = keys[i];
1884
- this.append(key, values[key].shift());
1885
- }
1886
- };
1887
- }
1888
-
1889
- function iterator(self, callback) {
1890
- var items = [];
1891
- self.forEach(callback, items);
1892
- /* istanbul ignore next */
1893
- return iterable ?
1894
- items[Symbol.iterator]() :
1895
- {
1896
- next: function() {
1897
- var value = items.shift();
1898
- return {done: value === void 0, value: value};
1899
- }
1900
- };
1901
- }
1902
-
1903
- /* istanbul ignore next */
1904
- (function (Object) {
1905
- var
1906
- dP = Object.defineProperty,
1907
- gOPD = Object.getOwnPropertyDescriptor,
1908
- createSearchParamsPollute = function (search) {
1909
- function append(name, value) {
1910
- URLSearchParamsProto.append.call(this, name, value);
1911
- name = this.toString();
1912
- search.set.call(this._usp, name ? ('?' + name) : '');
1913
- }
1914
- function del(name) {
1915
- URLSearchParamsProto.delete.call(this, name);
1916
- name = this.toString();
1917
- search.set.call(this._usp, name ? ('?' + name) : '');
1918
- }
1919
- function set(name, value) {
1920
- URLSearchParamsProto.set.call(this, name, value);
1921
- name = this.toString();
1922
- search.set.call(this._usp, name ? ('?' + name) : '');
1923
- }
1924
- return function (sp, value) {
1925
- sp.append = append;
1926
- sp.delete = del;
1927
- sp.set = set;
1928
- return dP(sp, '_usp', {
1929
- configurable: true,
1930
- writable: true,
1931
- value: value
1932
- });
1933
- };
1934
- },
1935
- createSearchParamsCreate = function (polluteSearchParams) {
1936
- return function (obj, sp) {
1937
- dP(
1938
- obj, '_searchParams', {
1939
- configurable: true,
1940
- writable: true,
1941
- value: polluteSearchParams(sp, obj)
1942
- }
1943
- );
1944
- return sp;
1945
- };
1946
- },
1947
- updateSearchParams = function (sp) {
1948
- var append = sp.append;
1949
- sp.append = URLSearchParamsProto.append;
1950
- URLSearchParams.call(sp, sp._usp.search.slice(1));
1951
- sp.append = append;
1952
- },
1953
- verifySearchParams = function (obj, Class) {
1954
- if (!(obj instanceof Class)) throw new TypeError(
1955
- "'searchParams' accessed on an object that " +
1956
- "does not implement interface " + Class.name
1957
- );
1958
- },
1959
- upgradeClass = function (Class) {
1960
- var
1961
- ClassProto = Class.prototype,
1962
- searchParams = gOPD(ClassProto, 'searchParams'),
1963
- href = gOPD(ClassProto, 'href'),
1964
- search = gOPD(ClassProto, 'search'),
1965
- createSearchParams
1966
- ;
1967
- if (!searchParams && search && search.set) {
1968
- createSearchParams = createSearchParamsCreate(
1969
- createSearchParamsPollute(search)
1970
- );
1971
- Object.defineProperties(
1972
- ClassProto,
1973
- {
1974
- href: {
1975
- get: function () {
1976
- return href.get.call(this);
1977
- },
1978
- set: function (value) {
1979
- var sp = this._searchParams;
1980
- href.set.call(this, value);
1981
- if (sp) updateSearchParams(sp);
1982
- }
1983
- },
1984
- search: {
1985
- get: function () {
1986
- return search.get.call(this);
1987
- },
1988
- set: function (value) {
1989
- var sp = this._searchParams;
1990
- search.set.call(this, value);
1991
- if (sp) updateSearchParams(sp);
1992
- }
1993
- },
1994
- searchParams: {
1995
- get: function () {
1996
- verifySearchParams(this, Class);
1997
- return this._searchParams || createSearchParams(
1998
- this,
1999
- new URLSearchParams(this.search.slice(1))
2000
- );
2001
- },
2002
- set: function (sp) {
2003
- verifySearchParams(this, Class);
2004
- createSearchParams(this, sp);
2005
- }
2006
- }
2007
- }
2008
- );
2009
- }
2010
- }
2011
- ;
2012
- try {
2013
- upgradeClass(HTMLAnchorElement);
2014
- if (/^function|object$/.test(typeof URL) && URL.prototype)
2015
- upgradeClass(URL);
2016
- } catch (meh) {}
2017
- }(Object));
2018
-
2019
- }(self.URLSearchParams.prototype));
2020
- var URLSearchParams$1 = self.URLSearchParams;
2021
-
2022
1464
  /** @hidden */
2023
1465
 
2024
- const _log$2 = debug__default['default']("squatch-js");
1466
+ var _log$3 = debug.debug("squatch-js");
2025
1467
 
2026
- const isObject = item => typeof item === "object" && !Array.isArray(item);
1468
+ var isObject = item => typeof item === "object" && !Array.isArray(item);
2027
1469
 
2028
- const deepMerge = (target, source) => {
2029
- const isDeep = prop => isObject(source[prop]) && target.hasOwnProperty(prop) && isObject(target[prop]);
1470
+ var deepMerge = (target, source) => {
1471
+ var isDeep = prop => isObject(source[prop]) && target.hasOwnProperty(prop) && isObject(target[prop]);
2030
1472
 
2031
- const replaced = Object.getOwnPropertyNames(source).map(prop => ({
1473
+ var replaced = Object.getOwnPropertyNames(source).map(prop => ({
2032
1474
  [prop]: isDeep(prop) ? deepMerge(target[prop], source[prop]) : source[prop]
2033
1475
  })).reduce((a, b) => _extends({}, a, b), {});
2034
1476
  return _extends({}, target, replaced);
@@ -2062,19 +1504,19 @@ function getTopDomain() {
2062
1504
  }
2063
1505
 
2064
1506
  function _pushCookie() {
2065
- const queryString = window.location.search;
2066
- const urlParams = new URLSearchParams$1(queryString);
2067
- const refParam = urlParams.get("_saasquatch") || ""; // do nothing if no params
1507
+ var queryString = window.location.search;
1508
+ var urlParams = new URLSearchParams(queryString);
1509
+ var refParam = urlParams.get("_saasquatch") || ""; // do nothing if no params
2068
1510
 
2069
1511
  if (refParam) {
2070
- let paramsJSON = "",
1512
+ var paramsJSON = "",
2071
1513
  existingCookie = "",
2072
1514
  reEncodedCookie = "";
2073
1515
 
2074
1516
  try {
2075
1517
  paramsJSON = JSON.parse(b64decode(refParam));
2076
1518
  } catch (error) {
2077
- _log$2("Unable to decode params", error); // don't merge invalid params
1519
+ _log$3("Unable to decode params", error); // don't merge invalid params
2078
1520
 
2079
1521
 
2080
1522
  return;
@@ -2083,26 +1525,26 @@ function _pushCookie() {
2083
1525
  try {
2084
1526
  existingCookie = JSON.parse(b64decode(Cookies__default['default'].get("_saasquatch")));
2085
1527
 
2086
- _log$2("existing cookie", existingCookie);
1528
+ _log$3("existing cookie", existingCookie);
2087
1529
  } catch (error) {
2088
- _log$2("Unable to retrieve cookie", error);
1530
+ _log$3("Unable to retrieve cookie", error);
2089
1531
  } // don't merge if there's no existing object
2090
1532
 
2091
1533
 
2092
1534
  try {
2093
- const domain = getTopDomain();
1535
+ var domain = getTopDomain();
2094
1536
 
2095
- _log$2("domain retrieved:", domain);
1537
+ _log$3("domain retrieved:", domain);
2096
1538
 
2097
1539
  if (existingCookie) {
2098
- const newCookie = deepMerge(existingCookie, paramsJSON);
1540
+ var newCookie = deepMerge(existingCookie, paramsJSON);
2099
1541
  reEncodedCookie = b64encode(JSON.stringify(newCookie));
2100
1542
 
2101
- _log$2("cookie to store:", newCookie);
1543
+ _log$3("cookie to store:", newCookie);
2102
1544
  } else {
2103
1545
  reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
2104
1546
 
2105
- _log$2("cookie to store:", paramsJSON);
1547
+ _log$3("cookie to store:", paramsJSON);
2106
1548
  }
2107
1549
 
2108
1550
  Cookies__default['default'].set("_saasquatch", reEncodedCookie, {
@@ -2113,52 +1555,52 @@ function _pushCookie() {
2113
1555
  path: "/"
2114
1556
  });
2115
1557
  } catch (error) {
2116
- _log$2("Unable to set cookie", error);
1558
+ _log$3("Unable to set cookie", error);
2117
1559
  }
2118
1560
  }
2119
1561
  }
2120
1562
 
2121
1563
  /** @hidden */
2122
1564
 
2123
- const _log$1 = debug__default['default']("squatch-js");
1565
+ var _log$2 = debug.debug("squatch-js");
2124
1566
 
2125
1567
  function _getAutoConfig(configIn) {
2126
- const queryString = window.location.search;
2127
- const urlParams = new URLSearchParams(queryString);
2128
- const refParam = urlParams.get("_saasquatchExtra") || "";
1568
+ var queryString = window.location.search;
1569
+ var urlParams = new URLSearchParams(queryString);
1570
+ var refParam = urlParams.get("_saasquatchExtra") || "";
2129
1571
 
2130
1572
  if (!refParam) {
2131
- _log$1("No _saasquatchExtra param");
1573
+ _log$2("No _saasquatchExtra param");
2132
1574
 
2133
1575
  return;
2134
1576
  }
2135
1577
 
2136
- let raw;
1578
+ var raw;
2137
1579
 
2138
1580
  try {
2139
1581
  raw = JSON.parse(b64decode(refParam));
2140
1582
  } catch (e) {
2141
- _log$1("Unable to decode _saasquatchExtra config");
1583
+ _log$2("Unable to decode _saasquatchExtra config");
2142
1584
 
2143
1585
  return;
2144
1586
  }
2145
1587
 
2146
- const {
1588
+ var {
2147
1589
  domain,
2148
1590
  tenantAlias,
2149
1591
  widgetConfig
2150
1592
  } = convertExtraToConfig(raw);
2151
1593
 
2152
1594
  if (!domain || !tenantAlias || !widgetConfig) {
2153
- _log$1("_saasquatchExtra did not have an expected structure");
1595
+ _log$2("_saasquatchExtra did not have an expected structure");
2154
1596
 
2155
1597
  return undefined;
2156
1598
  }
2157
1599
 
2158
- const {
1600
+ var {
2159
1601
  autoPopupWidgetType
2160
1602
  } = widgetConfig,
2161
- rest = _objectWithoutPropertiesLoose(widgetConfig, ["autoPopupWidgetType"]);
1603
+ rest = _objectWithoutPropertiesLoose(widgetConfig, ["autoPopupWidgetType"]);
2162
1604
 
2163
1605
  return {
2164
1606
  widgetConfig: _extends({
@@ -2173,19 +1615,19 @@ function _getAutoConfig(configIn) {
2173
1615
  })
2174
1616
  };
2175
1617
  }
2176
- /**
2177
- * Deconstructs _saasquatchExtra into domain, tenantAlias, and widgetConfig
2178
- * @param obj {Record<string, any>} Expected to be of the form `{ [appDomain]: { [tenantAlias]: { autoPopupWidgetType: [widgetType], [rest]?: ... } } }`
1618
+ /**
1619
+ * Deconstructs _saasquatchExtra into domain, tenantAlias, and widgetConfig
1620
+ * @param obj {Record<string, any>} Expected to be of the form `{ [appDomain]: { [tenantAlias]: { autoPopupWidgetType: [widgetType], [rest]?: ... } } }`
2179
1621
  */
2180
1622
 
2181
1623
  function convertExtraToConfig(obj) {
2182
1624
  var _obj$_domain;
2183
1625
 
2184
- const _domain = Object.keys(obj || {})[0];
2185
- const tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
2186
- const widgetConfig = obj == null ? void 0 : (_obj$_domain = obj[_domain]) == null ? void 0 : _obj$_domain[tenantAlias]; // domain in _saasquatchExtra doesn't contain "https://"
1626
+ var _domain = Object.keys(obj || {})[0];
1627
+ var tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
1628
+ var widgetConfig = obj == null ? void 0 : (_obj$_domain = obj[_domain]) == null ? void 0 : _obj$_domain[tenantAlias]; // domain in _saasquatchExtra doesn't contain "https://"
2187
1629
 
2188
- const domain = _domain ? `https://${_domain}` : undefined;
1630
+ var domain = _domain ? "https://" + _domain : undefined;
2189
1631
  return {
2190
1632
  domain,
2191
1633
  tenantAlias,
@@ -2193,9 +1635,240 @@ function convertExtraToConfig(obj) {
2193
1635
  };
2194
1636
  }
2195
1637
 
1638
+ var _log$1 = debug.debug("squatch-js:decodeJwt");
1639
+
1640
+ function decodeUserJwt(tokenStr) {
1641
+ try {
1642
+ var _JSON$parse;
1643
+
1644
+ var base64Url = tokenStr.split(".")[1];
1645
+ if (base64Url === undefined) return null;
1646
+ var jsonStr = b64decode(base64Url);
1647
+ return (_JSON$parse = JSON.parse(jsonStr)) == null ? void 0 : _JSON$parse.user;
1648
+ } catch (e) {
1649
+ _log$1(e);
1650
+
1651
+ return null;
1652
+ }
1653
+ }
1654
+
1655
+ debug__default['default']("sqh:DeclarativeWidget");
1656
+
1657
+ class DeclarativeWidget extends HTMLElement {
1658
+ constructor() {
1659
+ super();
1660
+ this.config = void 0;
1661
+ this.token = void 0;
1662
+ this.tenant = void 0;
1663
+ this.widgetType = void 0;
1664
+ this.widgetApi = void 0;
1665
+ this.analyticsApi = void 0;
1666
+ this.type = void 0;
1667
+ this.widgetInstance = void 0;
1668
+ this.frame = void 0;
1669
+ this.container = void 0;
1670
+ this.element = void 0;
1671
+
1672
+ this._setWidget = (template, config) => {
1673
+ var _this$config;
1674
+
1675
+ if (!this.widgetType) throw new Error("Widget was no specified");
1676
+ var Widget = this.type === "EMBED" ? EmbedWidget : PopupWidget;
1677
+ return new Widget({
1678
+ api: this.widgetApi,
1679
+ content: template,
1680
+ context: {
1681
+ type: config.type,
1682
+ engagementMedium: this.type
1683
+ },
1684
+ type: this.widgetType,
1685
+ domain: ((_this$config = this.config) == null ? void 0 : _this$config.domain) || DEFAULT_DOMAIN,
1686
+ npmCdn: DEFAULT_NPM_CDN,
1687
+ container: this.container || this
1688
+ });
1689
+ };
1690
+
1691
+ this.setErrorWidget = e => {
1692
+ var _this$config2;
1693
+
1694
+ var Widget = this.type === "EMBED" ? EmbedWidget : PopupWidget;
1695
+ return new Widget({
1696
+ api: this.widgetApi,
1697
+ content: "error",
1698
+ context: {
1699
+ type: "error"
1700
+ },
1701
+ type: "ERROR_WIDGET",
1702
+ domain: ((_this$config2 = this.config) == null ? void 0 : _this$config2.domain) || DEFAULT_DOMAIN,
1703
+ npmCdn: DEFAULT_NPM_CDN,
1704
+ container: this.container || this
1705
+ });
1706
+ };
1707
+
1708
+ this.show = this.open;
1709
+ this.hide = this.close;
1710
+ this.attachShadow({
1711
+ mode: "open"
1712
+ }).innerHTML = "<style>:host { display: contents; }</style><slot></slot>";
1713
+ this.config = window.squatchConfig;
1714
+ this.token = window.squatchToken;
1715
+ this.tenant = window.squatchTenant;
1716
+ this.container = this;
1717
+ }
1718
+
1719
+ _setupApis(config) {
1720
+ var _this$config3, _this$config4;
1721
+
1722
+ if (!this.tenant) throw new Error("Requires tenantAlias");
1723
+ this.widgetApi = new WidgetApi({
1724
+ tenantAlias: (config == null ? void 0 : config.tenantAlias) || this.tenant,
1725
+ domain: (config == null ? void 0 : config.domain) || ((_this$config3 = this.config) == null ? void 0 : _this$config3.domain) || DEFAULT_DOMAIN
1726
+ });
1727
+ this.analyticsApi = new AnalyticsApi({
1728
+ domain: (config == null ? void 0 : config.domain) || ((_this$config4 = this.config) == null ? void 0 : _this$config4.domain) || DEFAULT_DOMAIN
1729
+ });
1730
+ }
1731
+
1732
+ renderPasswordlessVariant() {
1733
+ var _configs$widgetConfig, _configs$widgetConfig2;
1734
+
1735
+ var configs = _getAutoConfig();
1736
+
1737
+ this._setupApis(configs == null ? void 0 : configs.squatchConfig);
1738
+
1739
+ return this.widgetApi.render({
1740
+ engagementMedium: (configs == null ? void 0 : (_configs$widgetConfig = configs.widgetConfig) == null ? void 0 : _configs$widgetConfig.engagementMedium) || this.type,
1741
+ widgetType: (configs == null ? void 0 : (_configs$widgetConfig2 = configs.widgetConfig) == null ? void 0 : _configs$widgetConfig2.widgetType) || this.widgetType
1742
+ }).then(res => this._setWidget(res.template, {
1743
+ type: "passwordless"
1744
+ })).catch(this.setErrorWidget);
1745
+ }
1746
+
1747
+ async renderUserUpsertVariant() {
1748
+ if (!this.widgetType) throw new Error("Widget must be specified");
1749
+
1750
+ this._setupApis();
1751
+
1752
+ var userObj = decodeUserJwt(this.token);
1753
+ if (!userObj) throw new Error("Could not load user information from jwt");
1754
+ var widgetInstance = await this.widgetApi.upsertUser({
1755
+ user: userObj,
1756
+ engagementMedium: this.type,
1757
+ widgetType: this.widgetType,
1758
+ jwt: this.token
1759
+ }).then(res => this._setWidget(res.template, {
1760
+ type: "upsert"
1761
+ })).catch(this.setErrorWidget);
1762
+ return widgetInstance;
1763
+ }
1764
+
1765
+ async getWidgetInstance() {
1766
+ var widgetInstance;
1767
+ this.widgetType = this.getAttribute("widget") || undefined;
1768
+ if (!this.widgetType) throw new Error("No widget has been specified");
1769
+
1770
+ if (!this.token) {
1771
+ widgetInstance = await this.renderPasswordlessVariant();
1772
+ } else {
1773
+ widgetInstance = await this.renderUserUpsertVariant();
1774
+ }
1775
+
1776
+ if (!widgetInstance) throw new Error("Could not create widget.");
1777
+ this.widgetInstance = widgetInstance;
1778
+ return widgetInstance;
1779
+ }
1780
+
1781
+ async renderWidget() {
1782
+ await this.getWidgetInstance();
1783
+ this.element = this.widgetInstance._findElement();
1784
+ this.frame = this.widgetInstance._createFrame();
1785
+ await this.widgetInstance.load(this.frame);
1786
+ }
1787
+
1788
+ open() {
1789
+ this.widgetInstance.open(this.frame);
1790
+ }
1791
+
1792
+ close() {
1793
+ this.widgetInstance.close(this.frame);
1794
+ }
1795
+
1796
+ }
1797
+
1798
+ class DeclarativeEmbedWidget extends DeclarativeWidget {
1799
+ constructor() {
1800
+ super();
1801
+ this.type = "EMBED";
1802
+ this.container = this.getAttribute("container") || this;
1803
+ }
1804
+
1805
+ static get observedAttributes() {
1806
+ return ["widget", "container"];
1807
+ }
1808
+
1809
+ attributeChangedCallback(attr, oldVal, newVal) {
1810
+ if (oldVal === newVal || !oldVal) return; // nothing to do
1811
+
1812
+ switch (attr) {
1813
+ case "widget":
1814
+ this.connectedCallback();
1815
+ break;
1816
+ // Specific to embed widgets
1817
+
1818
+ case "container":
1819
+ if (this.element) this.close();
1820
+ this.connectedCallback();
1821
+ break;
1822
+ }
1823
+ }
1824
+
1825
+ async connectedCallback() {
1826
+ var _ref, _this$shadowRoot;
1827
+
1828
+ await this.renderWidget();
1829
+ var slot = (_ref = this.shadowRoot && Array.from(this.shadowRoot.children)) == null ? void 0 : _ref.find(c => c.tagName === "SLOT");
1830
+ (_this$shadowRoot = this.shadowRoot) == null ? void 0 : _this$shadowRoot.removeChild(slot);
1831
+ }
1832
+
1833
+ }
1834
+ class DeclarativePopupWidget extends DeclarativeWidget {
1835
+ constructor() {
1836
+ super();
1837
+ this.type = "POPUP";
1838
+ this.addEventListener("click", e => {
1839
+ e.stopPropagation(); // SQUATCH-POPUP target means something in the shadowDOM was clicked (i.e. the dialog element)
1840
+
1841
+ if (e.target.tagName !== "SQUATCH-POPUP") this.open();
1842
+ });
1843
+ }
1844
+
1845
+ static get observedAttributes() {
1846
+ return ["widget", "id", "open"];
1847
+ }
1848
+
1849
+ attributeChangedCallback(attr, oldVal, newVal) {
1850
+ if (oldVal === newVal || !oldVal) return; // nothing to do
1851
+
1852
+ switch (attr) {
1853
+ case "open":
1854
+ case "widget":
1855
+ this.connectedCallback();
1856
+ break;
1857
+ }
1858
+ }
1859
+
1860
+ async connectedCallback() {
1861
+ await this.renderWidget();
1862
+ if (this.getAttribute("open") !== null) this.open();
1863
+ }
1864
+
1865
+ }
1866
+ window.customElements.define("squatch-embed", DeclarativeEmbedWidget);
1867
+ window.customElements.define("squatch-popup", DeclarativePopupWidget);
1868
+
2196
1869
  // @ts-check
2197
1870
  function help() {
2198
- console.log(`Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.`);
1871
+ console.log("Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.");
2199
1872
  }
2200
1873
 
2201
1874
  // @ts-check
@@ -2203,51 +1876,54 @@ function help() {
2203
1876
 
2204
1877
  /** @hidden */
2205
1878
 
2206
- const _log = debug__default['default']("squatch-js");
1879
+ var _log = debug.debug("squatch-js");
2207
1880
  /** @hidden */
2208
1881
 
2209
- let _api = null;
1882
+ var _api = null;
2210
1883
  /** @hidden */
2211
1884
 
2212
- let _widgets = null;
1885
+ var _widgets = null;
2213
1886
  /** @hidden */
2214
1887
 
2215
- let _events = null;
2216
- /**
2217
- * A static instance of the {@link WidgetApi} created when you call {@link #init init}.
2218
- *
2219
- * Read the {@link WidgetApi} docs.
2220
- *
2221
- * @returns WidgetApi static instance
1888
+ var _events = null;
1889
+ /**
1890
+ * A static instance of the {@link WidgetApi} created when you call {@link #init init}.
1891
+ *
1892
+ * Read the {@link WidgetApi} docs.
1893
+ *
1894
+ * @returns WidgetApi static instance
2222
1895
  */
2223
1896
 
2224
1897
  function api() {
1898
+ if (!_api) this.init({});
2225
1899
  return _api;
2226
1900
  }
2227
- /**
2228
- * A static instance of the {@link Widgets} created when you call {@link #init init}.
2229
- *
2230
- * Read the {@link Widgets} docs.
2231
- *
2232
- * @returns static instance
1901
+ /**
1902
+ * A static instance of the {@link Widgets} created when you call {@link #init init}.
1903
+ *
1904
+ * Read the {@link Widgets} docs.
1905
+ *
1906
+ * @returns static instance
2233
1907
  */
2234
1908
 
2235
1909
  function widgets() {
1910
+ if (!_widgets) this.init({});
2236
1911
  return _widgets;
2237
1912
  }
2238
- /**
2239
- * A static instance of the {@link EventsApi} created when you call {@link #init init}.
2240
- *
2241
- * Read the {@link EventsApi} docs.
2242
- *
2243
- * @returns EventsApi static instance
1913
+ /**
1914
+ * A static instance of the {@link EventsApi} created when you call {@link #init init}.
1915
+ *
1916
+ * Read the {@link EventsApi} docs.
1917
+ *
1918
+ * @returns EventsApi static instance
2244
1919
  */
2245
1920
 
2246
1921
  function events() {
1922
+ if (!_events) this.init({});
2247
1923
  return _events;
2248
1924
  }
2249
- /**
2250
- * Entry-point for high level API to render a widget using the instance of {@link Widgets} created when you call {@link #init init}.
1925
+ /**
1926
+ * Entry-point for high level API to render a widget using the instance of {@link Widgets} created when you call {@link #init init}.
2251
1927
  */
2252
1928
 
2253
1929
  function widget(widgetConfig) {
@@ -2255,21 +1931,17 @@ function widget(widgetConfig) {
2255
1931
 
2256
1932
  return (_widgets2 = widgets()) == null ? void 0 : _widgets2.render(widgetConfig);
2257
1933
  }
2258
- /**
2259
- * Extracts widget configuration from `_saasquatchExtra` UTM parameter. Initialises `squatch` and renders the widget as a {@link PopupWidget} via static instanct of {@link Widgets}.
1934
+ /**
1935
+ * Extracts widget configuration from `_saasquatchExtra` UTM parameter. Initialises `squatch` and renders the widget as a {@link PopupWidget} via static instanct of {@link Widgets}.
2260
1936
  */
2261
1937
 
2262
1938
  function _auto(configIn) {
2263
- console.log({
2264
- configIn
2265
- });
2266
-
2267
- const configs = _getAutoConfig(configIn);
1939
+ var configs = _getAutoConfig(configIn);
2268
1940
 
2269
1941
  if (configs) {
2270
1942
  var _widgets3;
2271
1943
 
2272
- const {
1944
+ var {
2273
1945
  squatchConfig,
2274
1946
  widgetConfig
2275
1947
  } = configs;
@@ -2277,25 +1949,25 @@ function _auto(configIn) {
2277
1949
  return (_widgets3 = widgets()) == null ? void 0 : _widgets3.render(widgetConfig);
2278
1950
  }
2279
1951
  }
2280
- /**
2281
- * Initializes the static `squatch` global. This sets up:
2282
- *
2283
- * - `squatch.api()` a static instance of the {@link WidgetApi}
2284
- * - `squatch.widgets()` a static instance of {@link Widgets}
2285
- * - `squatch.events()` a static instance of {@link EventsApi}
2286
- *
2287
- * @param config Configuration details
2288
- *
2289
- * @example
2290
- * squatch.init({tenantAlias:'test_basbtabstq51v'});
1952
+ /**
1953
+ * Initializes the static `squatch` global. This sets up:
1954
+ *
1955
+ * - `squatch.api()` a static instance of the {@link WidgetApi}
1956
+ * - `squatch.widgets()` a static instance of {@link Widgets}
1957
+ * - `squatch.events()` a static instance of {@link EventsApi}
1958
+ *
1959
+ * @param config Configuration details
1960
+ *
1961
+ * @example
1962
+ * squatch.init({tenantAlias:'test_basbtabstq51v'});
2291
1963
  */
2292
1964
 
2293
1965
  function init(configIn) {
2294
- const raw = configIn;
2295
- const config = validateConfig(raw);
1966
+ var raw = configIn;
1967
+ var config = validateConfig(raw);
2296
1968
 
2297
1969
  if (config.tenantAlias.match("^test") || config.debug) {
2298
- debug__default['default'].enable("squatch-js*");
1970
+ debug.debug.enable("squatch-js*");
2299
1971
  }
2300
1972
 
2301
1973
  _log("initializing ...");
@@ -2310,67 +1982,65 @@ function init(configIn) {
2310
1982
 
2311
1983
  _log("Events API instance", _events);
2312
1984
  }
2313
- /**
2314
- * Squatch.js can't start safely making operations until it's "ready". This
2315
- * function detects that state.
2316
- *
2317
- * @param fn A callback once Squatch.js is ready.
2318
- *
2319
- * @example
2320
- * squatch.ready(function() {
2321
- * console.log("ready!");
2322
- * squatch.api().upsertUser();
2323
- * });
1985
+ /**
1986
+ * Squatch.js can't start safely making operations until it's "ready". This
1987
+ * function detects that state.
1988
+ *
1989
+ * @param fn A callback once Squatch.js is ready.
1990
+ *
1991
+ * @example
1992
+ * squatch.ready(function() {
1993
+ * console.log("ready!");
1994
+ * squatch.api().upsertUser();
1995
+ * });
2324
1996
  */
2325
1997
 
2326
1998
  function ready(fn) {
2327
1999
  fn();
2328
-
2329
- window.squatch._auto();
2330
2000
  }
2331
- /**
2332
- * Autofills a referral code into an element when someone has been referred.
2333
- * Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
2334
- *
2335
- * @param {string} selector Element class/id
2336
- * @returns {void}
2001
+ /**
2002
+ * Autofills a referral code into an element when someone has been referred.
2003
+ * Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
2004
+ *
2005
+ * @param {string} selector Element class/id
2006
+ * @returns {void}
2337
2007
  */
2338
2008
 
2339
2009
  function autofill(selector) {
2340
2010
  // @ts-ignore -- will throw occasionally throw a null pointer exception at runtime
2341
2011
  widgets().autofill(selector);
2342
2012
  }
2343
- /**
2344
- * Overrides the default function that submits the user email. If you have
2345
- * Security enabled, the email needs to be signed before it's submitted.
2346
- *
2347
- * @param {function} fn Callback function for the 'submit_email' event.
2348
- * @returns {void}
2349
- *
2350
- * @example
2351
- * squatch.submitEmail(function(target, widget, email) {
2352
- * // Sign email and generate jwt token
2353
- * var jwt = 'token';
2354
- * widget.reload(email, jwt);
2355
- * });
2013
+ /**
2014
+ * Overrides the default function that submits the user email. If you have
2015
+ * Security enabled, the email needs to be signed before it's submitted.
2016
+ *
2017
+ * @param {function} fn Callback function for the 'submit_email' event.
2018
+ * @returns {void}
2019
+ *
2020
+ * @example
2021
+ * squatch.submitEmail(function(target, widget, email) {
2022
+ * // Sign email and generate jwt token
2023
+ * var jwt = 'token';
2024
+ * widget.reload(email, jwt);
2025
+ * });
2356
2026
  */
2357
2027
 
2358
2028
  function submitEmail(fn) {
2359
2029
  // @ts-ignore -- will throw occasionally throw a null pointer exception at runtime
2360
2030
  widgets().submitEmail(fn);
2361
2031
  }
2362
- /**
2363
- * Manually set the _saasquatch cookie as a 1st party cookie if available as a URL parameter on the current page.
2364
- * This runs automatically immediately when squatch-js is loaded, except when window.SaaSquatchDoNotAutoDrop is true.
2365
- * Use this function manually if you have a single page application or custom routing that causes the `_saasquatch` URL parameter to not be set when Squatch.js loads.
2032
+ /**
2033
+ * Manually set the _saasquatch cookie as a 1st party cookie if available as a URL parameter on the current page.
2034
+ * This runs automatically immediately when squatch-js is loaded, except when window.SaaSquatchDoNotAutoDrop is true.
2035
+ * Use this function manually if you have a single page application or custom routing that causes the `_saasquatch` URL parameter to not be set when Squatch.js loads.
2366
2036
 
2367
- * It is safe to run this function multiple times. If the `_saasquatch` URL parameter is invalid or missing it will not clear the 1st party cookie.
2037
+ * It is safe to run this function multiple times. If the `_saasquatch` URL parameter is invalid or missing it will not clear the 1st party cookie.
2368
2038
 
2369
- *
2370
- * @returns {void}
2371
- *
2372
- * @example
2373
- * squatch.pushCookie();
2039
+ *
2040
+ * @returns {void}
2041
+ *
2042
+ * @example
2043
+ * squatch.pushCookie();
2374
2044
  */
2375
2045
 
2376
2046
  function pushCookie() {
@@ -2383,7 +2053,8 @@ if (typeof document !== "undefined" && !window.SaaSquatchDoNotAutoDrop) {
2383
2053
 
2384
2054
  if (typeof document !== "undefined") asyncLoad();
2385
2055
 
2386
- exports.CtaWidget = CtaWidget;
2056
+ exports.DeclarativeEmbedWidget = DeclarativeEmbedWidget;
2057
+ exports.DeclarativePopupWidget = DeclarativePopupWidget;
2387
2058
  exports.EmbedWidget = EmbedWidget;
2388
2059
  exports.PopupWidget = PopupWidget;
2389
2060
  exports.WidgetApi = WidgetApi;