@simplybusiness/services 0.21.5 → 0.21.7

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 (106) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/index.js +1198 -17
  3. package/dist/esm/index.js +1193 -4
  4. package/package.json +7 -6
  5. package/dist/cjs/address-lookup/index.js +0 -98
  6. package/dist/cjs/address-lookup/index.js.map +0 -1
  7. package/dist/cjs/address-lookup/types.js +0 -7
  8. package/dist/cjs/address-lookup/types.js.map +0 -1
  9. package/dist/cjs/airbrake/index.js +0 -45
  10. package/dist/cjs/airbrake/index.js.map +0 -1
  11. package/dist/cjs/index.js.map +0 -1
  12. package/dist/cjs/mocks/eventDefinitions.js +0 -90
  13. package/dist/cjs/mocks/eventDefinitions.js.map +0 -1
  14. package/dist/cjs/mocks/scripts-mock.js +0 -59
  15. package/dist/cjs/mocks/scripts-mock.js.map +0 -1
  16. package/dist/cjs/mocks/snowplowBrowserTrackerMock.js +0 -7
  17. package/dist/cjs/mocks/snowplowBrowserTrackerMock.js.map +0 -1
  18. package/dist/cjs/snowplow/Snowplow.js +0 -174
  19. package/dist/cjs/snowplow/Snowplow.js.map +0 -1
  20. package/dist/cjs/snowplow/SnowplowContext.js +0 -61
  21. package/dist/cjs/snowplow/SnowplowContext.js.map +0 -1
  22. package/dist/cjs/snowplow/constants.js +0 -13
  23. package/dist/cjs/snowplow/constants.js.map +0 -1
  24. package/dist/cjs/snowplow/contexts.js +0 -68
  25. package/dist/cjs/snowplow/contexts.js.map +0 -1
  26. package/dist/cjs/snowplow/event-definitions/base.js +0 -56
  27. package/dist/cjs/snowplow/event-definitions/base.js.map +0 -1
  28. package/dist/cjs/snowplow/event-definitions/index.js +0 -65
  29. package/dist/cjs/snowplow/event-definitions/index.js.map +0 -1
  30. package/dist/cjs/snowplow/event-definitions/intervention.js +0 -33
  31. package/dist/cjs/snowplow/event-definitions/intervention.js.map +0 -1
  32. package/dist/cjs/snowplow/event-definitions/personalised_cover.js +0 -122
  33. package/dist/cjs/snowplow/event-definitions/personalised_cover.js.map +0 -1
  34. package/dist/cjs/snowplow/event-definitions/qcp.js +0 -348
  35. package/dist/cjs/snowplow/event-definitions/qcp.js.map +0 -1
  36. package/dist/cjs/snowplow/event-definitions/questionnaire.js +0 -115
  37. package/dist/cjs/snowplow/event-definitions/questionnaire.js.map +0 -1
  38. package/dist/cjs/snowplow/event-definitions/redaction.js +0 -154
  39. package/dist/cjs/snowplow/event-definitions/redaction.js.map +0 -1
  40. package/dist/cjs/snowplow/event-definitions/referral.js +0 -37
  41. package/dist/cjs/snowplow/event-definitions/referral.js.map +0 -1
  42. package/dist/cjs/snowplow/getSnowplowConfig.js +0 -16
  43. package/dist/cjs/snowplow/getSnowplowConfig.js.map +0 -1
  44. package/dist/cjs/snowplow/index.js +0 -25
  45. package/dist/cjs/snowplow/index.js.map +0 -1
  46. package/dist/cjs/snowplow/types.js +0 -6
  47. package/dist/cjs/snowplow/types.js.map +0 -1
  48. package/dist/cjs/utils/index.js +0 -21
  49. package/dist/cjs/utils/index.js.map +0 -1
  50. package/dist/cjs/utils/isObject.js +0 -15
  51. package/dist/cjs/utils/isObject.js.map +0 -1
  52. package/dist/cjs/utils/testUtils.js +0 -43
  53. package/dist/cjs/utils/testUtils.js.map +0 -1
  54. package/dist/cjs/utils/text.js +0 -45
  55. package/dist/cjs/utils/text.js.map +0 -1
  56. package/dist/esm/address-lookup/index.js +0 -88
  57. package/dist/esm/address-lookup/index.js.map +0 -1
  58. package/dist/esm/address-lookup/types.js +0 -5
  59. package/dist/esm/address-lookup/types.js.map +0 -1
  60. package/dist/esm/airbrake/index.js +0 -35
  61. package/dist/esm/airbrake/index.js.map +0 -1
  62. package/dist/esm/index.js.map +0 -1
  63. package/dist/esm/mocks/eventDefinitions.js +0 -80
  64. package/dist/esm/mocks/eventDefinitions.js.map +0 -1
  65. package/dist/esm/mocks/scripts-mock.js +0 -49
  66. package/dist/esm/mocks/scripts-mock.js.map +0 -1
  67. package/dist/esm/mocks/snowplowBrowserTrackerMock.js +0 -6
  68. package/dist/esm/mocks/snowplowBrowserTrackerMock.js.map +0 -1
  69. package/dist/esm/snowplow/Snowplow.js +0 -169
  70. package/dist/esm/snowplow/Snowplow.js.map +0 -1
  71. package/dist/esm/snowplow/SnowplowContext.js +0 -43
  72. package/dist/esm/snowplow/SnowplowContext.js.map +0 -1
  73. package/dist/esm/snowplow/constants.js +0 -3
  74. package/dist/esm/snowplow/constants.js.map +0 -1
  75. package/dist/esm/snowplow/contexts.js +0 -47
  76. package/dist/esm/snowplow/contexts.js.map +0 -1
  77. package/dist/esm/snowplow/event-definitions/base.js +0 -66
  78. package/dist/esm/snowplow/event-definitions/base.js.map +0 -1
  79. package/dist/esm/snowplow/event-definitions/index.js +0 -36
  80. package/dist/esm/snowplow/event-definitions/index.js.map +0 -1
  81. package/dist/esm/snowplow/event-definitions/intervention.js +0 -23
  82. package/dist/esm/snowplow/event-definitions/intervention.js.map +0 -1
  83. package/dist/esm/snowplow/event-definitions/personalised_cover.js +0 -131
  84. package/dist/esm/snowplow/event-definitions/personalised_cover.js.map +0 -1
  85. package/dist/esm/snowplow/event-definitions/qcp.js +0 -339
  86. package/dist/esm/snowplow/event-definitions/qcp.js.map +0 -1
  87. package/dist/esm/snowplow/event-definitions/questionnaire.js +0 -106
  88. package/dist/esm/snowplow/event-definitions/questionnaire.js.map +0 -1
  89. package/dist/esm/snowplow/event-definitions/redaction.js +0 -144
  90. package/dist/esm/snowplow/event-definitions/redaction.js.map +0 -1
  91. package/dist/esm/snowplow/event-definitions/referral.js +0 -28
  92. package/dist/esm/snowplow/event-definitions/referral.js.map +0 -1
  93. package/dist/esm/snowplow/getSnowplowConfig.js +0 -7
  94. package/dist/esm/snowplow/getSnowplowConfig.js.map +0 -1
  95. package/dist/esm/snowplow/index.js +0 -8
  96. package/dist/esm/snowplow/index.js.map +0 -1
  97. package/dist/esm/snowplow/types.js +0 -3
  98. package/dist/esm/snowplow/types.js.map +0 -1
  99. package/dist/esm/utils/index.js +0 -4
  100. package/dist/esm/utils/index.js.map +0 -1
  101. package/dist/esm/utils/isObject.js +0 -5
  102. package/dist/esm/utils/isObject.js.map +0 -1
  103. package/dist/esm/utils/testUtils.js +0 -26
  104. package/dist/esm/utils/testUtils.js.map +0 -1
  105. package/dist/esm/utils/text.js +0 -25
  106. package/dist/esm/utils/text.js.map +0 -1
package/dist/esm/index.js CHANGED
@@ -1,5 +1,1194 @@
1
- export * from "./address-lookup";
2
- export * from "./airbrake";
3
- export * from "./snowplow";
1
+ // src/address-lookup/index.ts
2
+ var BASE_URL = "https://api.addressy.com/Capture/Interactive";
3
+ var FIND_URL = `${BASE_URL}/Find/v1.00/json3.ws`;
4
+ var RETRIEVE_URL = `${BASE_URL}/Retrieve/v1.2/json3.ws`;
5
+ var COUNTRIES = ["GB"];
6
+ var LIMIT = 20;
7
+ var AddressLookup = class _AddressLookup {
8
+ constructor({ apiKey, limit, countries }) {
9
+ this.apiKey = apiKey;
10
+ this.limit = limit || LIMIT;
11
+ this.countries = countries || COUNTRIES;
12
+ this.findUrl = `${FIND_URL}?Key=${this.apiKey}&Limit=${this.limit}&Countries=${this.countries}`;
13
+ this.retrieveUrl = `${RETRIEVE_URL}?Key=${this.apiKey}`;
14
+ }
15
+ static async fetchFromApi(url, handleResponse) {
16
+ return new Promise((resolve, reject) => {
17
+ fetch(url).then((response) => response.json()).then((data) => resolve(handleResponse(data))).catch((error) => reject(Error(error)));
18
+ });
19
+ }
20
+ find(partialAddress) {
21
+ return new Promise((resolve, reject) => {
22
+ fetch(`${this.findUrl}&Text=${partialAddress}`).then((response) => response.json()).then((data) => resolve(this.formatItems(data))).catch((error) => reject(Error(error)));
23
+ });
24
+ }
25
+ findById(id) {
26
+ return new Promise((resolve, reject) => {
27
+ fetch(`${this.findUrl}&Container=${id}`).then((response) => response.json()).then((data) => resolve(this.formatItems(data))).catch((error) => reject(Error(error)));
28
+ });
29
+ }
30
+ get(id) {
31
+ return new Promise((resolve, reject) => {
32
+ fetch(`${this.retrieveUrl}&Id=${id}`).then((response) => response.json()).then((data) => resolve(_AddressLookup.formatUkAddress(data))).catch((error) => reject(Error(error)));
33
+ });
34
+ }
35
+ formatItems({ Items }) {
36
+ if (!Items || !Array.isArray(Items)) {
37
+ throw Error("No address found");
38
+ }
39
+ if (Items[0].Error) {
40
+ throw Error(Items[0].Description);
41
+ }
42
+ return Items.map(
43
+ (item) => ({
44
+ id: item.Id,
45
+ label: `${item.Text}, ${item.Description}`,
46
+ value: item.Text,
47
+ // Add a callback to trigger secondary search
48
+ // if the address type is not "Address"
49
+ callback: item.Type === "Address" ? void 0 : () => this.findById(item.Id)
50
+ })
51
+ );
52
+ }
53
+ static formatUkAddress({ Items }) {
54
+ if (!Items || !Array.isArray(Items)) {
55
+ throw Error("No address found");
56
+ }
57
+ if (Items[0].Error) {
58
+ throw Error(Items[0].Description);
59
+ }
60
+ const { Line1, Line2, City, PostalCode } = Items[0];
61
+ return {
62
+ address_1: Line1,
63
+ address_2: Line2,
64
+ town: City,
65
+ uk_postcode: PostalCode
66
+ };
67
+ }
68
+ };
4
69
 
5
- //# sourceMappingURL=index.js.map
70
+ // src/airbrake/index.ts
71
+ import { Notifier } from "@airbrake/browser";
72
+ var defaultProjectId = 512949;
73
+ var defaultProjectKey = "4e25197d8faea61c10fbb97702200780";
74
+ var notifierInstance;
75
+ var fakeAirbrake = {
76
+ notify: console.error
77
+ };
78
+ var shouldUseAirbrake = () => {
79
+ const { location } = globalThis;
80
+ const isTest = false;
81
+ return isTest || location?.hostname.indexOf("quote.") > -1;
82
+ };
83
+ function getAirbrake(options) {
84
+ const { projectId, projectKey, forceSend } = options;
85
+ if (!forceSend || !shouldUseAirbrake()) {
86
+ return fakeAirbrake;
87
+ }
88
+ if (!notifierInstance) {
89
+ notifierInstance = new Notifier({
90
+ projectId: projectId ?? defaultProjectId,
91
+ projectKey: projectKey ?? defaultProjectKey,
92
+ environment: "development",
93
+ instrumentation: {
94
+ onerror: false
95
+ }
96
+ });
97
+ }
98
+ return notifierInstance;
99
+ }
100
+
101
+ // src/utils/text.ts
102
+ var snakeCaseKeys = (object) => Object.entries(object || {}).reduce(
103
+ (acc, [key, value]) => {
104
+ const newKey = camelToSnakeCase(key);
105
+ if (Array.isArray(value) && value.every(isObject)) {
106
+ return {
107
+ ...acc,
108
+ [newKey]: value.map((v) => snakeCaseKeys(v))
109
+ };
110
+ }
111
+ if (isObject(value)) {
112
+ return {
113
+ ...acc,
114
+ [newKey]: snakeCaseKeys(value)
115
+ };
116
+ }
117
+ return {
118
+ ...acc,
119
+ [newKey]: value
120
+ };
121
+ },
122
+ {}
123
+ );
124
+ var snakeCase = (text = "") => text.toLowerCase().replace(/ /g, "_");
125
+ var camelToSnakeCase = (text) => text.charAt(0).toLowerCase() + text.slice(1).replace(
126
+ /(\[.*?\])|[A-Z]/g,
127
+ (match, group) => group ? match : `_${match.toLowerCase()}`
128
+ );
129
+
130
+ // src/utils/isObject.tsx
131
+ function isObject(value) {
132
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
133
+ }
134
+
135
+ // src/snowplow/contexts.ts
136
+ var getContexts = (config) => {
137
+ const contextEntries = Object.entries(config || {}).filter(([key]) => key.includes("Context") && key !== "includeGAContext").reduce((acc, [key, value]) => {
138
+ if (typeof value === "object") {
139
+ return { ...acc, [key]: snakeCaseKeys({ ...value }) };
140
+ }
141
+ return {
142
+ ...acc,
143
+ [key]: snakeCaseKeys({ data: { service_channel_identifier: value } })
144
+ };
145
+ }, {});
146
+ return contextEntries;
147
+ };
148
+ var updateIdentityContext = (contexts, uid) => {
149
+ const index = Object.keys(contexts).findIndex(
150
+ (ctx) => contexts[ctx].schema?.includes("identity_context")
151
+ );
152
+ if (index > -1) {
153
+ const key = Object.keys(contexts)[index];
154
+ return {
155
+ ...contexts,
156
+ [key]: {
157
+ ...contexts[key],
158
+ data: {
159
+ ...contexts[key].data,
160
+ domain_userid: uid
161
+ }
162
+ }
163
+ };
164
+ }
165
+ return contexts;
166
+ };
167
+ var makeContexts = (keys, config) => (keys || []).map((key) => config[key]);
168
+
169
+ // src/snowplow/event-definitions/base.ts
170
+ var baseEventDefinitions = [
171
+ // Mobile link in header
172
+ {
173
+ name: "mobileLinkClick",
174
+ type: "structured",
175
+ makePayload: () => ({
176
+ category: "marketing",
177
+ action: "link-click",
178
+ label: "mobile_call_button",
179
+ property: window.location.href
180
+ })
181
+ },
182
+ // Operating hours link in footer
183
+ {
184
+ name: "operatingHoursClick",
185
+ type: "unstructured",
186
+ makePayload: () => ({
187
+ schema: "iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0",
188
+ data: {
189
+ schema: "iglu:com.simplybusiness/operating_hours_clicked/jsonschema/1-0-2",
190
+ data: {}
191
+ }
192
+ })
193
+ },
194
+ {
195
+ name: "progressbarClicked",
196
+ type: "unstructured",
197
+ makePayload: (params) => {
198
+ const {
199
+ section,
200
+ context,
201
+ fromStepIndex,
202
+ fromStepName,
203
+ stepIndex,
204
+ stepName
205
+ } = params;
206
+ return {
207
+ schema: "iglu:com.simplybusiness/progressbar_clicked/jsonschema/1-1-0",
208
+ data: {
209
+ source_page_index: fromStepIndex,
210
+ source_page_name: fromStepName,
211
+ page_index: stepIndex,
212
+ page_name: stepName,
213
+ site: context.site,
214
+ section_name: section,
215
+ vertical: context.vertical
216
+ }
217
+ };
218
+ }
219
+ }
220
+ ];
221
+
222
+ // src/snowplow/event-definitions/qcp.ts
223
+ var qcpEventDefinitions = [
224
+ {
225
+ // QDP details button
226
+ name: "detailsClicked",
227
+ type: "structured",
228
+ makePayload: () => ({
229
+ category: "comparison_cta",
230
+ action: "link_click",
231
+ label: "Details"
232
+ })
233
+ },
234
+ {
235
+ // Buy button
236
+ name: "selectClicked",
237
+ type: "structured",
238
+ makePayload: () => ({
239
+ category: "comparison_cta",
240
+ action: "link_click",
241
+ label: "Buy"
242
+ })
243
+ },
244
+ {
245
+ // Quote Details Slider Next steps button
246
+ name: "nextStepsClicked",
247
+ type: "structured",
248
+ makePayload: () => ({
249
+ category: "quote_details_slider_next_step_cta",
250
+ action: "link_click",
251
+ label: "Next steps"
252
+ })
253
+ },
254
+ {
255
+ // Toggle deductibles accordion
256
+ name: "deductiblesClicked",
257
+ type: "structured",
258
+ makePayload: () => ({
259
+ category: "us-qcp-react",
260
+ action: "view_deductables_clicked",
261
+ label: "view_deductables_clicked",
262
+ property: window.location.href
263
+ })
264
+ },
265
+ {
266
+ name: "deductiblesClickedUk",
267
+ type: "structured",
268
+ makePayload: (params) => {
269
+ const { label, deviceType } = params;
270
+ const urlFriendlyLabel = label.replace(/ /g, "-").toLowerCase();
271
+ return {
272
+ category: `uk-qcp-react-${deviceType}-${urlFriendlyLabel}-view-excess-toggle`,
273
+ action: "view_excess_clicked",
274
+ label,
275
+ property: window.location.href
276
+ };
277
+ }
278
+ },
279
+ {
280
+ // Quote Details Slider opened
281
+ name: "sliderOpened",
282
+ type: "structured",
283
+ makePayload: (params) => {
284
+ const { label } = params;
285
+ return {
286
+ category: "comparison_cta",
287
+ action: "quote_details_slider_opened",
288
+ label
289
+ };
290
+ }
291
+ },
292
+ {
293
+ // Coverage modal opened
294
+ name: "coverageModalOpened",
295
+ type: "structured",
296
+ makePayload: (params) => {
297
+ const {
298
+ category,
299
+ product = "extra_coverage",
300
+ title
301
+ } = params;
302
+ const productLabel = snakeCase(product);
303
+ return {
304
+ category,
305
+ action: `${productLabel}_${snakeCase(title)}_popup_opened`,
306
+ label: productLabel,
307
+ property: window.location.href
308
+ };
309
+ }
310
+ },
311
+ {
312
+ // Toggle cover select
313
+ name: "coverChanged",
314
+ type: "unstructured",
315
+ makePayload: (params) => {
316
+ const { name = "", fromValue = "", toValue = "" } = params;
317
+ let action = "change";
318
+ if (fromValue === "0") {
319
+ action = "add";
320
+ }
321
+ if (toValue === "0") {
322
+ action = "remove";
323
+ }
324
+ return {
325
+ schema: "iglu:com.simplybusiness/comparison_page_cover_changed/jsonschema/1-0-0",
326
+ data: {
327
+ name,
328
+ action,
329
+ from_value: fromValue,
330
+ to_value: toValue
331
+ }
332
+ };
333
+ },
334
+ contexts: ["distributionChannelContext"]
335
+ },
336
+ {
337
+ name: "ratingsModalOpened",
338
+ type: "structured",
339
+ makePayload: (params) => {
340
+ const { category, label } = params;
341
+ return {
342
+ category,
343
+ action: "insurer_rating_help_popup_triggered",
344
+ label,
345
+ property: window.location.href
346
+ };
347
+ }
348
+ },
349
+ {
350
+ name: "coverToggleOpened",
351
+ type: "structured",
352
+ makePayload: () => ({
353
+ category: "qcp_limit_interaction",
354
+ label: "limit_interaction",
355
+ action: "limit_interaction_clicked",
356
+ property: window.location.href
357
+ })
358
+ },
359
+ {
360
+ name: "paymentToggleClicked",
361
+ type: "structured",
362
+ makePayload: (params) => {
363
+ const { category, label } = params;
364
+ return {
365
+ category,
366
+ action: "button_click",
367
+ label,
368
+ property: window.location.href
369
+ };
370
+ }
371
+ },
372
+ {
373
+ name: "insurerDetailsAccordionClicked",
374
+ type: "structured",
375
+ makePayload: () => ({
376
+ category: "quote_details_slider_insurer_details_description",
377
+ action: "accordion_clicked",
378
+ label: "accordion_clicked",
379
+ property: window.location.href
380
+ })
381
+ },
382
+ {
383
+ name: "priceDetailsPopUpOpened",
384
+ type: "structured",
385
+ makePayload: () => ({
386
+ category: "price_details",
387
+ action: "price_details_popup_opened",
388
+ label: "Price details",
389
+ property: window.location.href
390
+ })
391
+ },
392
+ {
393
+ name: "editLimitButtonClicked",
394
+ type: "structured",
395
+ makePayload: () => ({
396
+ category: "cover_limit_changes",
397
+ action: "edit_limit_button_clicked",
398
+ label: "Edit Limit",
399
+ property: window.location.href
400
+ })
401
+ },
402
+ {
403
+ name: "applyButtonClicked",
404
+ type: "structured",
405
+ makePayload: () => ({
406
+ category: "cover_limit_changes",
407
+ action: "apply_button_clicked",
408
+ label: "Apply Button Clicked",
409
+ property: window.location.href
410
+ })
411
+ },
412
+ {
413
+ name: "coverageInfoClicked",
414
+ type: "structured",
415
+ makePayload: (params) => {
416
+ const { deviceType } = params;
417
+ return {
418
+ action: "show_coverage_info_clicked",
419
+ category: `uk-qcp-react-${deviceType}-show-coverage-info-toggle`,
420
+ label: "show_coverage_info_clicked",
421
+ property: window.location.href
422
+ };
423
+ }
424
+ },
425
+ {
426
+ name: "backToApplication",
427
+ type: "unstructured",
428
+ makePayload: (params) => {
429
+ const { journeyId, vertical } = params;
430
+ return {
431
+ schema: "iglu:com.simplybusiness/qcp_back_to_application/jsonschema/1-0-0",
432
+ data: {
433
+ journey_id: journeyId,
434
+ vertical
435
+ }
436
+ };
437
+ },
438
+ contexts: ["serviceChannelContext"]
439
+ },
440
+ {
441
+ name: "helpChatLinkClicked",
442
+ type: "structured",
443
+ makePayload: () => ({
444
+ category: "help chat for question",
445
+ action: "help_chat_for_question_clicked",
446
+ property: window.location.href
447
+ })
448
+ },
449
+ // No quotes referral
450
+ {
451
+ name: "coverOptionsLinkClicked",
452
+ type: "structured",
453
+ makePayload: () => ({
454
+ category: "uk-qcp-react-cover-options-link",
455
+ action: "cover_options_link_clicked",
456
+ label: "cover_options_link_clicked",
457
+ property: window.location.href
458
+ })
459
+ },
460
+ {
461
+ name: "referralReasonsVariantBCoverOptionsLinkClicked",
462
+ type: "structured",
463
+ makePayload: () => ({
464
+ category: "uk-24-12-qcp-mvt-referral-reasons",
465
+ action: "cover_options_link_clicked_variant_b",
466
+ label: "cover_options_link_clicked_variant_b",
467
+ property: window.location.href
468
+ })
469
+ },
470
+ {
471
+ name: "referralReasonsVariantCCoverOptionsLinkClicked",
472
+ type: "structured",
473
+ makePayload: () => ({
474
+ category: "uk-24-12-qcp-mvt-referral-reasons",
475
+ action: "cover_options_link_clicked_variant_c",
476
+ label: "cover_options_link_clicked_variant_c",
477
+ property: window.location.href
478
+ })
479
+ },
480
+ {
481
+ name: "phoneNumberLinkClicked",
482
+ type: "structured",
483
+ makePayload: () => ({
484
+ category: "uk-qcp-react-phone-number-link",
485
+ action: "phone_number_link_clicked",
486
+ label: "phone_number_link_clicked",
487
+ property: window.location.href
488
+ })
489
+ },
490
+ {
491
+ name: "stickyFooterClick",
492
+ type: "structured",
493
+ makePayload: () => ({
494
+ category: "marketing",
495
+ action: "link-click",
496
+ label: "sticky_footer_button",
497
+ property: window.location.href
498
+ })
499
+ },
500
+ {
501
+ name: "linkClicked",
502
+ type: "unstructured",
503
+ makePayload: (params) => {
504
+ const { targetUrl, elementContent } = params;
505
+ return {
506
+ schema: "iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1",
507
+ data: {
508
+ targetUrl,
509
+ elementContent
510
+ }
511
+ };
512
+ }
513
+ },
514
+ {
515
+ name: "qcpUpsellAccordionClicked",
516
+ type: "structured",
517
+ makePayload: (params) => ({
518
+ category: "us-qcp-upsells",
519
+ action: "accordion_clicked_qcp",
520
+ label: params?.label,
521
+ property: window.location.href
522
+ })
523
+ },
524
+ {
525
+ name: "qdsUpsellAccordionClicked",
526
+ type: "structured",
527
+ makePayload: (params) => ({
528
+ category: "us-qcp-upsells",
529
+ action: "accordion_clicked_slider",
530
+ label: params?.label,
531
+ property: window.location.href
532
+ })
533
+ },
534
+ {
535
+ name: "qcpUpsellTooltipHelperClicked",
536
+ type: "structured",
537
+ makePayload: (params) => ({
538
+ category: "us-qcp-upsells",
539
+ action: "tooltip_helper_clicked_qcp",
540
+ label: params?.label,
541
+ property: window.location.href
542
+ })
543
+ },
544
+ {
545
+ name: "qdsUpsellTooltipHelperClicked",
546
+ type: "structured",
547
+ makePayload: (params) => ({
548
+ category: "us-qcp-upsells",
549
+ action: "tooltip_helper_clicked_slider",
550
+ label: params?.label,
551
+ property: window.location.href
552
+ })
553
+ }
554
+ ];
555
+
556
+ // src/snowplow/event-definitions/referral.ts
557
+ var referralEventDefinitions = [
558
+ {
559
+ name: "nextCoverageClicked",
560
+ type: "structured",
561
+ makePayload: (params) => {
562
+ const { url } = params;
563
+ const eventName = "post_referral_workers_compensation_continuation_link";
564
+ return {
565
+ category: eventName,
566
+ action: "link_click",
567
+ label: eventName,
568
+ property: url
569
+ };
570
+ }
571
+ },
572
+ {
573
+ name: "helpChatLinkClicked",
574
+ type: "structured",
575
+ makePayload: () => ({
576
+ category: "help chat for question",
577
+ action: "help_chat_for_question_clicked",
578
+ property: window.location.href
579
+ })
580
+ }
581
+ ];
582
+
583
+ // src/snowplow/event-definitions/intervention.ts
584
+ var interventionEventDefinitions = [
585
+ {
586
+ name: "interventionInteraction",
587
+ type: "unstructured",
588
+ makePayload: (params) => {
589
+ const {
590
+ interventionId,
591
+ interventionName,
592
+ category,
593
+ userUniqueIdentifier,
594
+ userUniqueIdentifierType,
595
+ action,
596
+ site
597
+ } = params;
598
+ return {
599
+ schema: "iglu:com.simplybusiness/intervention_interaction/jsonschema/2-1-0",
600
+ data: {
601
+ intervention_id: interventionId,
602
+ intervention_name: interventionName,
603
+ category,
604
+ user_unique_identifier: userUniqueIdentifier,
605
+ user_unique_identifier_type: userUniqueIdentifierType,
606
+ action,
607
+ site
608
+ }
609
+ };
610
+ }
611
+ }
612
+ ];
613
+
614
+ // src/snowplow/constants.ts
615
+ var DELIMITER = "|";
616
+
617
+ // src/snowplow/event-definitions/redaction.ts
618
+ var PII_ANSWER = [
619
+ "customer_title",
620
+ "customer_first_name",
621
+ "customer_last_name",
622
+ "customer_email_address",
623
+ "preapp_email_address",
624
+ "customer_telephone_number",
625
+ "customer_alternative_telephone_number",
626
+ "uk_address_lookup",
627
+ "uk_correspondence_address_lookup",
628
+ "customer_address_1_pre_quote",
629
+ "customer_address_2_pre_quote",
630
+ "customer_town_pre_quote",
631
+ "customer_postcode_pre_quote",
632
+ "customer_address_1",
633
+ "customer_address_2",
634
+ "customer_town",
635
+ "customer_postcode",
636
+ "address_1_pre_quote",
637
+ "address_2_pre_quote",
638
+ "uk_postcode_pre_quote",
639
+ "town_pre_quote",
640
+ "owner_first_name",
641
+ "owner_last_name",
642
+ "beneficiary_first_name",
643
+ "beneficiary_last_name",
644
+ "gender",
645
+ "dynamic_ssn_fein",
646
+ "ssn",
647
+ "fein",
648
+ "sof_county_court_judgement_online_yes",
649
+ "sof_county_court_judgement_online_no",
650
+ "sof_ccj_count",
651
+ "sof_ccj_value",
652
+ "sof_ccj_date",
653
+ "sof_court_judgement_yes",
654
+ "sof_court_judgement_no",
655
+ "ccj_date",
656
+ "sof_single_ccj_no",
657
+ "sof_single_ccj_yes",
658
+ "sof_ccj_yes",
659
+ "sof_ccj_no",
660
+ "ccj_count",
661
+ "sof_bankrupt_yes",
662
+ "sof_bankrupt_no",
663
+ "sof_multiple_bankruptcies_yes",
664
+ "sof_multiple_bankruptcies_no",
665
+ "bankruptcy_date",
666
+ "sof_single_bankruptcy_no",
667
+ "sof_single_bankruptcy_yes",
668
+ "sof_bankruptcy_yes",
669
+ "sof_bankruptcy_no",
670
+ "bankruptcy_discharged",
671
+ "sof_liquidation_yes",
672
+ "sof_liquidation_no",
673
+ "sof_multiple_liquidations",
674
+ "liquidation_date",
675
+ "sof_criminal_offence_yes",
676
+ "sof_criminal_offence_no",
677
+ "sof_criminal_yes",
678
+ "sof_criminal_no",
679
+ "hcp_date_of_birth_1",
680
+ "hcp_date_of_birth_2",
681
+ "hcp_date_of_birth_3",
682
+ "hcp_date_of_birth_4",
683
+ "hcp_date_of_birth_5",
684
+ "hcp_date_of_birth_6",
685
+ "hcp_date_of_birth_7",
686
+ "hcp_date_of_birth_8",
687
+ "hcp_date_of_birth_9",
688
+ "hcp_date_of_birth_10",
689
+ "sof_previous_claims_yes",
690
+ "sof_previous_claims_no",
691
+ "sof_claims_yes",
692
+ "sof_claims_no",
693
+ "sof_property_claims_in_the_last_5_years_yes",
694
+ "sof_property_claims_in_the_last_5_years_no",
695
+ "sof_property_claims_in_the_last_0_to_4_years_yes",
696
+ "sof_property_claims_in_the_last_0_to_4_years_no",
697
+ "claim_count",
698
+ "sof_number_of_claims",
699
+ "number_of_claims_in_last_5_years",
700
+ "number_of_claims_in_time_owned",
701
+ "date_of_incident_1",
702
+ "date_of_incident_2",
703
+ "date_of_incident_3",
704
+ "date_of_incident_4",
705
+ "date_of_incident_5",
706
+ "type_of_incident_1",
707
+ "type_of_incident_2",
708
+ "type_of_incident_3",
709
+ "type_of_incident_4",
710
+ "type_of_incident_5",
711
+ "incident_value_1",
712
+ "incident_value_2",
713
+ "incident_value_3",
714
+ "incident_value_4",
715
+ "incident_value_5",
716
+ "sof_pollution_disease_claims_yes",
717
+ "sof_pollution_disease_claims_no",
718
+ "sof_potential_claims_yes",
719
+ "sof_potential_claims_no",
720
+ "sof_previous_circumstances_yes",
721
+ "sof_previous_circumstances_no",
722
+ "sof_possible_claims_yes",
723
+ "sof_possible_claims_no",
724
+ "date_of_possible_incident",
725
+ "type_of_possible_incident",
726
+ "possible_incident_value",
727
+ "sof_property_claims_yes",
728
+ "sof_property_claims_no",
729
+ "sof_liability_claims_yes",
730
+ "sof_liability_claims_no",
731
+ "van_registration",
732
+ "sof_disqualified_director_yes",
733
+ "sof_disqualified_director_no",
734
+ "sof_insurance_refused_yes",
735
+ "sof_insurance_refused_no",
736
+ "sof_insurance_declined_yes",
737
+ "sof_insurance_declined_no",
738
+ "insurance_refused"
739
+ ];
740
+ var RADIO_ANSWER_FROM_QUESTIONS = [
741
+ "have_secondary_trade_yes",
742
+ "have_secondary_trade_no"
743
+ ];
744
+ var ANSWER_SUFFIX_PATTERN = /_(yes|no)$/;
745
+ var redact = (params) => {
746
+ let { question, answer } = params;
747
+ const piiAnswer = new Set(PII_ANSWER);
748
+ const radioAnswerFromQuestions = new Set(RADIO_ANSWER_FROM_QUESTIONS);
749
+ if (piiAnswer.has(question)) {
750
+ answer = "REDACTED";
751
+ question = question?.replace(ANSWER_SUFFIX_PATTERN, "");
752
+ } else if (radioAnswerFromQuestions.has(question)) {
753
+ question = question?.replace(ANSWER_SUFFIX_PATTERN, "");
754
+ }
755
+ return { question, answer };
756
+ };
757
+
758
+ // src/snowplow/event-definitions/questionnaire.ts
759
+ var questionnaireEventDefinitions = [
760
+ {
761
+ name: "questionAnswered",
762
+ type: "unstructured",
763
+ makePayload: (params) => {
764
+ const { section, context } = params;
765
+ const { question, answer } = redact(params);
766
+ const flatAnswer = Array.isArray(answer) ? answer.join(DELIMITER) : answer;
767
+ return {
768
+ schema: "iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-3",
769
+ data: {
770
+ site: context.site,
771
+ page_index: 1,
772
+ page_name: "quick_to_quote",
773
+ submitted_from: "quick_to_quote_experiment",
774
+ section_name: section,
775
+ question,
776
+ answer: flatAnswer,
777
+ vertical: context.vertical
778
+ }
779
+ };
780
+ }
781
+ },
782
+ {
783
+ name: "primaryDetailSelected",
784
+ type: "unstructured",
785
+ makePayload: (params) => {
786
+ const { context, answer, vertical } = params;
787
+ const { site } = context;
788
+ let verticalName = vertical || context.vertical;
789
+ if (verticalName.toLowerCase().indexOf("landlord") > -1) {
790
+ verticalName = answer === "residential" ? "Landlord" : "Commercial landlord";
791
+ }
792
+ return {
793
+ schema: "iglu:com.simplybusiness/primary_detail_selected/jsonschema/1-3-0",
794
+ data: {
795
+ site,
796
+ vertical: verticalName,
797
+ primary_detail: answer
798
+ }
799
+ };
800
+ },
801
+ contexts: ["distributionChannelContext"]
802
+ },
803
+ {
804
+ name: "helpTextOpened",
805
+ type: "unstructured",
806
+ makePayload: (params) => {
807
+ const { primaryText, label, context, helpText } = params;
808
+ return {
809
+ schema: "iglu:com.simplybusiness/help_text_opened/jsonschema/1-1-0",
810
+ data: {
811
+ vertical: context.vertical,
812
+ site: context.site,
813
+ primary_text: primaryText,
814
+ help_text: helpText,
815
+ label,
816
+ page_name: "quick_to_quote"
817
+ }
818
+ };
819
+ }
820
+ },
821
+ {
822
+ name: "assumptionsButtonClicked",
823
+ type: "structured",
824
+ makePayload: (params) => {
825
+ const { source, presentationGroup } = params;
826
+ return {
827
+ action: source,
828
+ category: presentationGroup
829
+ };
830
+ }
831
+ },
832
+ {
833
+ name: "navButtonClicked",
834
+ type: "structured",
835
+ makePayload: (params) => {
836
+ const { label, category } = params;
837
+ return {
838
+ label,
839
+ action: "link_click",
840
+ category
841
+ };
842
+ }
843
+ },
844
+ {
845
+ name: "manualAddressClicked",
846
+ type: "structured",
847
+ makePayload: (params) => {
848
+ const { category } = params;
849
+ return {
850
+ action: "link_click",
851
+ category,
852
+ label: "Enter address manually"
853
+ };
854
+ }
855
+ }
856
+ ];
857
+
858
+ // src/snowplow/event-definitions/personalised_cover.ts
859
+ var personalisedCoverEventDefinitions = [
860
+ {
861
+ name: "seeMoreClicked",
862
+ type: "structured",
863
+ makePayload: (_) => ({
864
+ category: "personalised_cover",
865
+ action: "see_more_clicked",
866
+ label: "page",
867
+ property: "personalised_cover"
868
+ })
869
+ },
870
+ {
871
+ name: "selectPackageClicked",
872
+ type: "structured",
873
+ makePayload: (_) => ({
874
+ category: "personalised_cover",
875
+ action: "select_package_clicked",
876
+ label: "page",
877
+ property: "personalised_cover"
878
+ })
879
+ },
880
+ {
881
+ name: "validationShown",
882
+ type: "structured",
883
+ makePayload: (params) => {
884
+ const { cover, question } = params;
885
+ return {
886
+ category: "personalised_cover",
887
+ action: "validation_shown",
888
+ label: "cover_question",
889
+ property: `${snakeCase(cover)}_${snakeCase(question)}`
890
+ };
891
+ }
892
+ },
893
+ {
894
+ name: "coverQuestionAnswered",
895
+ type: "unstructured",
896
+ makePayload: (params) => {
897
+ const { context } = params;
898
+ const { question, answer } = redact(params);
899
+ const flatAnswer = Array.isArray(answer) ? answer.join(DELIMITER) : answer;
900
+ return {
901
+ schema: "iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-1",
902
+ data: {
903
+ site: context.site,
904
+ page_name: "personalised_cover",
905
+ section_name: "Personalised Cover Questions",
906
+ question,
907
+ answer: flatAnswer
908
+ }
909
+ };
910
+ }
911
+ },
912
+ {
913
+ name: "limitLinkClicked",
914
+ type: "structured",
915
+ makePayload: (params) => {
916
+ const { label } = params;
917
+ return {
918
+ category: "personalised_cover",
919
+ action: "limit_link_clicked",
920
+ label,
921
+ property: "link_clicked"
922
+ };
923
+ }
924
+ },
925
+ {
926
+ name: "limitChanged",
927
+ type: "structured",
928
+ makePayload: (params) => {
929
+ const { label, limit } = params;
930
+ return {
931
+ category: "personalised_cover",
932
+ action: "limit_changed",
933
+ label,
934
+ property: limit
935
+ };
936
+ }
937
+ },
938
+ {
939
+ name: "coverPresented",
940
+ type: "structured",
941
+ makePayload: (params) => {
942
+ const { property } = params;
943
+ return {
944
+ category: "personalised_cover",
945
+ action: "cover_presented",
946
+ label: "cover_name",
947
+ property
948
+ };
949
+ }
950
+ },
951
+ {
952
+ name: "moreInfoClicked",
953
+ type: "structured",
954
+ makePayload: (params) => {
955
+ const { property } = params;
956
+ return {
957
+ category: "personalised_cover",
958
+ action: "more_info_clicked",
959
+ label: "cover_name",
960
+ property
961
+ };
962
+ }
963
+ }
964
+ ];
965
+
966
+ // src/snowplow/event-definitions/index.ts
967
+ var eventDefinitions = [
968
+ ...baseEventDefinitions,
969
+ ...qcpEventDefinitions,
970
+ ...referralEventDefinitions,
971
+ ...interventionEventDefinitions,
972
+ ...questionnaireEventDefinitions,
973
+ ...personalisedCoverEventDefinitions
974
+ ];
975
+ var qcpPageEvents = [...baseEventDefinitions, ...qcpEventDefinitions];
976
+ var referralPageEvents = [
977
+ ...baseEventDefinitions,
978
+ ...referralEventDefinitions
979
+ ];
980
+ var personalisedCoverPageEvents = [
981
+ ...baseEventDefinitions,
982
+ ...personalisedCoverEventDefinitions
983
+ ];
984
+ var interventionPageEvents = [...interventionEventDefinitions];
985
+ var questionnairePageEvents = [...questionnaireEventDefinitions];
986
+
987
+ // src/snowplow/getSnowplowConfig.ts
988
+ var getSnowplowConfig = (pageData) => pageData.scripts?.find(({ metadata }) => metadata.name === "snowplow")?.props;
989
+
990
+ // src/snowplow/Snowplow.ts
991
+ import {
992
+ newTracker,
993
+ setCookiePath,
994
+ setUserId,
995
+ trackPageView,
996
+ trackSelfDescribingEvent,
997
+ trackStructEvent
998
+ } from "@snowplow/browser-tracker";
999
+ var Snowplow = class _Snowplow {
1000
+ constructor(props) {
1001
+ this.avalancheTrackerName = "sb-ava";
1002
+ this.bronzeAvalancheTrackerName = "sb-ava-br";
1003
+ this.pvAvalancheTrackerName = "sb-ava-pv";
1004
+ this.uid = "";
1005
+ this.trackPageView = false;
1006
+ this.contexts = {};
1007
+ this.pvContext = [];
1008
+ this.structContext = [];
1009
+ this.serverData = {};
1010
+ this.eventHandlers = {};
1011
+ if (!props) return;
1012
+ const {
1013
+ appId,
1014
+ cookieDomain,
1015
+ avalancheCollector,
1016
+ eventMethod,
1017
+ uid,
1018
+ postPath,
1019
+ trackPageView: tpv
1020
+ } = props;
1021
+ this.uid = uid;
1022
+ this.trackPageView = tpv;
1023
+ this.serverData = props?.pageViewContext?.data || {};
1024
+ const stateStorageStrategy = "cookieAndLocalStorage";
1025
+ const baseOptions = {
1026
+ appId,
1027
+ cookieDomain,
1028
+ eventMethod,
1029
+ stateStorageStrategy,
1030
+ postPath
1031
+ };
1032
+ newTracker(this.avalancheTrackerName, avalancheCollector, baseOptions);
1033
+ newTracker(
1034
+ this.bronzeAvalancheTrackerName,
1035
+ avalancheCollector,
1036
+ baseOptions
1037
+ );
1038
+ newTracker(this.pvAvalancheTrackerName, avalancheCollector, {
1039
+ ...baseOptions,
1040
+ eventMethod: eventMethod === "post" ? "beacon" : eventMethod
1041
+ });
1042
+ setCookiePath("/");
1043
+ if (uid) {
1044
+ setUserId(uid);
1045
+ }
1046
+ _Snowplow.instance = this;
1047
+ }
1048
+ setContexts(contexts) {
1049
+ this.contexts = updateIdentityContext(contexts, this.uid);
1050
+ this.pvContext = Object.values(this.contexts);
1051
+ this.structContext = makeContexts(
1052
+ ["distributionChannelContext", "serviceChannelContext"],
1053
+ this.contexts
1054
+ );
1055
+ return this;
1056
+ }
1057
+ // Send a page view event
1058
+ async trackView(event) {
1059
+ if (this.trackPageView) {
1060
+ await trackPageView({ ...event, context: this.pvContext }, [
1061
+ this.avalancheTrackerName
1062
+ ]);
1063
+ }
1064
+ return this;
1065
+ }
1066
+ // Send a structured event with contexts
1067
+ async trackEvent(event) {
1068
+ await trackStructEvent({ ...event, context: this.structContext }, [
1069
+ this.bronzeAvalancheTrackerName
1070
+ ]);
1071
+ return this;
1072
+ }
1073
+ // Send a custom event with defined schema and optional contexts
1074
+ async trackUnstructEvent(event, contexts) {
1075
+ if (!event) {
1076
+ return this;
1077
+ }
1078
+ if (contexts && Array.isArray(contexts) && contexts.length > 0) {
1079
+ const context = makeContexts(contexts, this.contexts);
1080
+ await trackSelfDescribingEvent({ event, context }, [
1081
+ this.avalancheTrackerName
1082
+ ]);
1083
+ } else {
1084
+ await trackSelfDescribingEvent({ event }, [this.avalancheTrackerName]);
1085
+ }
1086
+ return this;
1087
+ }
1088
+ addEventHandlers(eventDefinitions2) {
1089
+ const context = this.serverData;
1090
+ eventDefinitions2.forEach(({ name, type, makePayload, contexts }) => {
1091
+ if (type === "structured") {
1092
+ this.addEventHandler(name, (params) => {
1093
+ this.trackEvent(
1094
+ makePayload({
1095
+ ...params,
1096
+ context
1097
+ })
1098
+ );
1099
+ });
1100
+ } else {
1101
+ this.addEventHandler(name, (params) => {
1102
+ const payload = makePayload({
1103
+ ...params,
1104
+ context
1105
+ });
1106
+ if (contexts && Array.isArray(contexts) && contexts.length > 0) {
1107
+ this.trackUnstructEvent(payload, contexts);
1108
+ } else {
1109
+ this.trackUnstructEvent(payload);
1110
+ }
1111
+ });
1112
+ }
1113
+ });
1114
+ return this;
1115
+ }
1116
+ addEventHandler(name, handler) {
1117
+ this.eventHandlers[name] = handler;
1118
+ return this;
1119
+ }
1120
+ removeEventHandler(name) {
1121
+ delete this.eventHandlers[name];
1122
+ return this;
1123
+ }
1124
+ trigger(name, params) {
1125
+ const handler = this.eventHandlers[name];
1126
+ if (Object.prototype.hasOwnProperty.call(this.eventHandlers, name) && typeof handler === "function") {
1127
+ handler(params);
1128
+ }
1129
+ return this;
1130
+ }
1131
+ static getInstance(props) {
1132
+ if (!_Snowplow.instance) {
1133
+ _Snowplow.instance = new _Snowplow(props);
1134
+ }
1135
+ return _Snowplow.instance;
1136
+ }
1137
+ };
1138
+
1139
+ // src/snowplow/SnowplowContext.tsx
1140
+ import {
1141
+ createContext,
1142
+ useContext,
1143
+ useEffect,
1144
+ useMemo,
1145
+ useRef,
1146
+ useState
1147
+ } from "react";
1148
+ import { jsx } from "react/jsx-runtime";
1149
+ var SnowplowContext = createContext(null);
1150
+ var SnowplowProvider = ({ scripts, children }) => {
1151
+ const [config, _setConfig] = useState(scripts);
1152
+ const snowplow = useRef(Snowplow.getInstance(config));
1153
+ useEffect(() => {
1154
+ if (snowplow.current && scripts) {
1155
+ const contexts = getContexts(config);
1156
+ snowplow.current.setContexts(contexts).addEventHandlers(eventDefinitions);
1157
+ if (config.trackPageView) snowplow.current.trackView();
1158
+ }
1159
+ }, [config, snowplow, scripts]);
1160
+ const value = useMemo(
1161
+ () => ({
1162
+ config,
1163
+ snowplow: snowplow.current
1164
+ }),
1165
+ [config, snowplow]
1166
+ );
1167
+ return /* @__PURE__ */ jsx(SnowplowContext.Provider, { value, children });
1168
+ };
1169
+ function useSnowplowContext() {
1170
+ const context = useContext(SnowplowContext);
1171
+ if (!context) {
1172
+ throw new Error(
1173
+ "useSnowplowContext must be used inside a `SnowplowProvider`"
1174
+ );
1175
+ }
1176
+ return context;
1177
+ }
1178
+ export {
1179
+ AddressLookup,
1180
+ Snowplow,
1181
+ SnowplowProvider,
1182
+ eventDefinitions,
1183
+ getAirbrake,
1184
+ getContexts,
1185
+ getSnowplowConfig,
1186
+ interventionPageEvents,
1187
+ makeContexts,
1188
+ personalisedCoverPageEvents,
1189
+ qcpPageEvents,
1190
+ questionnairePageEvents,
1191
+ referralPageEvents,
1192
+ updateIdentityContext,
1193
+ useSnowplowContext
1194
+ };