mod-build 4.0.91 → 4.0.92

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 (137) hide show
  1. package/package.json +1 -2
  2. package/public/resources/scripts/abandonment/abandonment-a4bbb36fbc8ed64042b8.min.js +2 -0
  3. package/public/resources/scripts/abandonment/abandonment.min.js +2 -0
  4. package/public/resources/scripts/callrail/callrail-14011d73b50a928de4b4.min.js +2 -0
  5. package/public/resources/scripts/callrail/callrail.min.js +2 -0
  6. package/public/resources/scripts/footer/footer-component-46dc0d7ca6af4fc3b76b.min.js +2 -0
  7. package/public/resources/scripts/footer/footer-component.min.js +2 -0
  8. package/public/resources/scripts/geolocation/geolocation.min.js +2 -0
  9. package/public/resources/scripts/helpers/addVWOTestQueryParam.min.js +2 -0
  10. package/public/resources/scripts/helpers/addVWOTestQueryParam.min.js.map +1 -0
  11. package/public/resources/scripts/helpers/additionalOpts.min.js +2 -0
  12. package/public/resources/scripts/helpers/additionalOpts.min.js.map +1 -0
  13. package/public/resources/scripts/helpers/calls-only.min.js +2 -0
  14. package/public/resources/scripts/helpers/calls-only.min.js.map +1 -0
  15. package/public/resources/scripts/helpers/getPhoneAssignmentData.min.js +2 -0
  16. package/public/resources/scripts/helpers/getPhoneAssignmentData.min.js.map +1 -0
  17. package/public/resources/scripts/helpers/initNumericOnlyFields.min.js +2 -0
  18. package/public/resources/scripts/helpers/initNumericOnlyFields.min.js.map +1 -0
  19. package/public/resources/scripts/helpers/initQSForm.min.js +2 -0
  20. package/public/resources/scripts/helpers/initQSForm.min.js.map +1 -0
  21. package/public/resources/scripts/helpers/initQuadTransform.min.js +2 -0
  22. package/public/resources/scripts/helpers/initQuadTransform.min.js.map +1 -0
  23. package/public/resources/scripts/helpers/isZipCodeValid.min.js +2 -0
  24. package/public/resources/scripts/helpers/isZipCodeValid.min.js.map +1 -0
  25. package/public/resources/scripts/helpers/observeVWOVariation.min.js +2 -0
  26. package/public/resources/scripts/helpers/observeVWOVariation.min.js.map +1 -0
  27. package/public/resources/scripts/helpers/opts.min.js +2 -0
  28. package/public/resources/scripts/helpers/opts.min.js.map +1 -0
  29. package/public/resources/scripts/jornaya.hbs +35 -0
  30. package/public/resources/scripts/jornaya.html +35 -0
  31. package/public/resources/scripts/mod-alytics/modalytics-be44027508c0438f6709.min.js +2 -0
  32. package/public/resources/scripts/mod-alytics/modalytics.min.js +2 -0
  33. package/public/resources/scripts/mod-form/form/contractor-0918337caf3dfede1609.min.js +2 -0
  34. package/public/resources/scripts/mod-form/form/contractor.min.js +2 -0
  35. package/public/resources/scripts/mod-form/form/homeowner-19a121b0e596042326f4.min.js +2 -0
  36. package/public/resources/scripts/mod-form/form/homeowner.min.js +2 -0
  37. package/public/resources/scripts/mod-utils/modutils-bc275eb41af515f626ef.min.js +2 -0
  38. package/public/resources/scripts/mod-utils/modutils.min.js +2 -0
  39. package/public/resources/scripts/trusted-form.hbs +38 -0
  40. package/public/resources/scripts/trusted-form.html +38 -0
  41. package/public/resources/styles/components/abandonment/abandonment-8a673f060817db6cb7dc.min.css +1 -0
  42. package/public/resources/styles/components/abandonment/abandonment.min.css +1 -0
  43. package/public/resources/styles/components/footer/mod-footer-d233fa64b6c8297c70ec.min.css +1 -0
  44. package/public/resources/styles/components/footer/mod-footer.min.css +1 -0
  45. package/public/resources/styles/components/footer/qs-footer-926e67c28d10c729db46.min.css +1 -0
  46. package/public/resources/styles/components/footer/qs-footer.min.css +1 -0
  47. package/src/resources/data/tcpa.json +4 -0
  48. package/src/resources/templates/modals/about/index.hbs +9 -0
  49. package/src/resources/templates/modals/about/index.html +9 -0
  50. package/src/resources/templates/modals/contact-us/index.hbs +348 -0
  51. package/src/resources/templates/modals/contact-us/index.html +348 -0
  52. package/src/resources/templates/modals/e-sign-consent/index.hbs +35 -0
  53. package/src/resources/templates/modals/e-sign-consent/index.html +35 -0
  54. package/src/resources/templates/modals/faq/index.hbs +9 -0
  55. package/src/resources/templates/modals/faq/index.html +9 -0
  56. package/src/resources/templates/modals/privacy/index.hbs +237 -0
  57. package/src/resources/templates/modals/privacy/index.html +237 -0
  58. package/src/resources/templates/modals/terms/index.hbs +167 -0
  59. package/src/resources/templates/modals/terms/index.html +167 -0
  60. package/src/scripts/retry-fetch.js +39 -0
  61. package/src/shared-components/call-tracking/_call-tracking.scss +311 -0
  62. package/src/shared-components/call-tracking/call-tracking-icon.html +8 -0
  63. package/src/shared-components/call-tracking/call-tracking.html +81 -0
  64. package/src/shared-components/call-tracking/phone.svg +6 -0
  65. package/src/shared-components/card-button/_card-button.scss +49 -0
  66. package/src/shared-components/card-button/card-button.html +9 -0
  67. package/src/shared-components/carousel/_carousel.scss +106 -0
  68. package/src/shared-components/carousel/carousel.html +23 -0
  69. package/src/shared-components/carousel/carousel.js +3573 -0
  70. package/src/shared-components/carousel/carousel.js.map +1 -0
  71. package/src/shared-components/carousel/carousel.min.js +2 -0
  72. package/src/shared-components/carousel/carousel.min.js.map +1 -0
  73. package/src/shared-components/carousel/carousel.min.min.js +2 -0
  74. package/src/shared-components/carousel/carousel.min.min.js.map +1 -0
  75. package/src/shared-components/checkbox/_checkbox.scss +130 -0
  76. package/src/shared-components/checkbox/checkbox.html +10 -0
  77. package/src/shared-components/consent-capture/tcpa.html +12 -0
  78. package/src/shared-components/expand-collapse/_expand-collapse.scss +93 -0
  79. package/src/shared-components/expand-collapse/expand-collapse.html +8 -0
  80. package/src/shared-components/expand-collapse/expand-collapse.js +40 -0
  81. package/src/shared-components/expand-collapse/expand-collapse.min.js +2 -0
  82. package/src/shared-components/expand-collapse/expand-collapse.min.js.map +1 -0
  83. package/src/shared-components/featured-block/_featured-block.scss +191 -0
  84. package/src/shared-components/featured-block/featured-block.html +80 -0
  85. package/src/shared-components/foot-assets/foot-assets.html +107 -0
  86. package/src/shared-components/form-tcpa/form-tcpa-spanish.html +61 -0
  87. package/src/shared-components/form-tcpa/form-tcpa.html +55 -0
  88. package/src/shared-components/gtm-body/gtm-body.html +4 -0
  89. package/src/shared-components/head/head.html +195 -0
  90. package/src/shared-components/header/_header.scss +200 -0
  91. package/src/shared-components/header/header.html +79 -0
  92. package/src/shared-components/hero/_hero.scss +276 -0
  93. package/src/shared-components/hero/hero.html +136 -0
  94. package/src/shared-components/how-it-works/_how-it-works.scss +138 -0
  95. package/src/shared-components/how-it-works/how-it-works.html +19 -0
  96. package/src/shared-components/input/_input.scss +242 -0
  97. package/src/shared-components/input/input.html +30 -0
  98. package/src/shared-components/preloader/_preloader.scss +61 -0
  99. package/src/shared-components/preloader/preloader.html +49 -0
  100. package/src/shared-components/progress-bar/_progress-bar.scss +142 -0
  101. package/src/shared-components/progress-bar/progress-bar.html +20 -0
  102. package/src/shared-components/progress-bar/progress-bar.js +26 -0
  103. package/src/shared-components/progress-bar/progress-bar.min.js +2 -0
  104. package/src/shared-components/progress-bar/progress-bar.min.js.map +1 -0
  105. package/src/shared-components/radio-button/_radio-button.scss +577 -0
  106. package/src/shared-components/radio-button/radio-button.html +25 -0
  107. package/src/shared-components/reviews/_reviews.scss +79 -0
  108. package/src/shared-components/reviews/reviews.html +27 -0
  109. package/src/shared-components/section-deals/sitemap.xml +9 -0
  110. package/src/shared-components/select/_select.scss +61 -0
  111. package/src/shared-components/select/select.html +8 -0
  112. package/src/shared-components/steps/_steps.scss +431 -0
  113. package/src/shared-components/steps/defaultFormFieldConfig.json +64 -0
  114. package/src/shared-components/steps/step-fields.html +36 -0
  115. package/src/shared-components/steps/steps.html +136 -0
  116. package/src/shared-components/textarea/_textarea.scss +96 -0
  117. package/src/shared-components/textarea/textarea.html +13 -0
  118. package/src/shared-components/theme-toggle/_theme-toggle.scss +68 -0
  119. package/src/shared-components/theme-toggle/theme-toggle.html +34 -0
  120. package/src/shared-components/tile/_tile.scss +117 -0
  121. package/src/shared-components/tile/tile.html +27 -0
  122. package/src/shared-components/value-props/_value-props.scss +99 -0
  123. package/src/shared-components/value-props/value-props.html +17 -0
  124. package/src/shared-components/zip-control/_zip-control.scss +42 -0
  125. package/src/shared-components/zip-control/zip-control.html +21 -0
  126. package/tasks/add-editorconfig.js +3 -3
  127. package/tasks/get-default-trade-questions.js +8 -8
  128. package/tasks/grab-b2b-data.js +9 -30
  129. package/tasks/grab-cdn.js +4 -13
  130. package/tasks/grab-code-review-rules.js +4 -3
  131. package/tasks/grab-form-helpers.js +11 -27
  132. package/tasks/grab-global-fonts.js +7 -13
  133. package/tasks/grab-jsdoc.js +10 -30
  134. package/tasks/grab-shared-components.js +10 -19
  135. package/tasks/grab-shared-scripts.js +8 -21
  136. package/tasks/templates.js +28 -41
  137. package/src/scripts/retry-axios.js +0 -23
@@ -1,21 +1,17 @@
1
- import axios from 'axios';
2
1
  import footer from '../src/data/footer.js';
3
2
  import fs from 'node:fs';
4
3
  import merge from 'lodash.merge';
5
4
  import cloneDeep from 'lodash.clonedeep';
6
- import { responseInterceptor } from '../src/scripts/retry-axios.js';
5
+ import { createRetryFetch } from '../src/scripts/retry-fetch.js';
7
6
 
8
7
  import { defaultSettings } from '../src/data/config.js';
9
8
 
10
9
  import setupDevOpsTrackingId from './setupDevOpsTrackingId.js';
11
10
  import addSeasonalchanges from './addSeasonalchanges.js';
12
11
 
13
- const axiosInstance = axios.create();
14
- const tcpaAxiosInstance = axios.create();
15
- const consentCaptureAxiosInstance = axios.create();
16
- const axiosResponseInterceptor = responseInterceptor(axiosInstance);
17
- const tcpaAxiosResponseInterceptor = responseInterceptor(tcpaAxiosInstance);
18
- const consentCaptureAxiosResponseInterceptor = responseInterceptor(consentCaptureAxiosInstance);
12
+ const fetchWithRetryDefault = createRetryFetch();
13
+ const fetchWithRetryTcpa = createRetryFetch();
14
+ const fetchWithRetryConsent = createRetryFetch();
19
15
 
20
16
  async function mergeDefaultFormFieldConfigOnSteps(defaultConfig, data, parentConfig) {
21
17
  if (!data || typeof data !== 'object') {
@@ -75,19 +71,17 @@ const getDefaultFormFieldConfig = async (config, folder = 'accessible-components
75
71
  console.log('Starting fetch-default-form-config: ');
76
72
 
77
73
  await new Promise((resolve) => {
78
- axiosInstance.get(`https://${defaultSettings.nodeEnv}/quote/resources/mod-site/${folder}/steps/defaultFormFieldConfig.json`)
74
+ fetchWithRetryDefault(`https://${defaultSettings.nodeEnv}/quote/resources/mod-site/${folder}/steps/defaultFormFieldConfig.json`)
79
75
  .then(async resp => {
80
76
  if (resp.status !== 200) {
81
77
  throw new Error(`${resp.status}: Error while fetching ${folder}/defaultFormFieldConfig.json`);
82
78
  }
83
- const defaultConfig = resp.data;
79
+ const defaultConfig = await resp.json();
84
80
  mergeDefaultFormFieldConfigOnSteps(defaultConfig, config, config);
85
81
  resolve();
86
82
  }).catch(error => {
87
83
  console.error(error);
88
84
  process.exit(1);
89
- }).finally(() => {
90
- axiosInstance.interceptors.response.eject(axiosResponseInterceptor);
91
85
  });
92
86
  });
93
87
  };
@@ -103,21 +97,15 @@ const fetchTcpaFromSitegenie = async (config, tempConfig, pathSubdirectory) => {
103
97
 
104
98
  const url = `${apiEnv}coreg/getTCPAConsent?website=${website}&service=${service?.replace(/\s/g, '_')}&affiliateKey=${affiliateKey}&c_level=${c_level}`;
105
99
 
106
- const options = {
107
- url,
108
- method: 'get',
109
- timeout: 2000,
110
- };
111
-
112
100
  console.log('Starting fetch-tcpa-from-sitegenie: ', url);
113
101
  return new Promise((resolve) => {
114
- tcpaAxiosInstance(options)
102
+ fetchWithRetryTcpa(url, { signal: AbortSignal.timeout(2000) })
115
103
  .then(async resp => {
116
104
  if (resp.status !== 200) {
117
105
  throw new Error(`${resp.status}: Error while fetching TCPA`);
118
106
  }
119
107
 
120
- const responseJson = resp.data;
108
+ const responseJson = await resp.json();
121
109
  console.log('SiteGenie TCPA response successful: ', responseJson);
122
110
 
123
111
  let finalTCPA = await responseJson.tcpa.replace(/QuinStreet/g, 'Modernize');
@@ -138,7 +126,7 @@ const fetchTcpaFromSitegenie = async (config, tempConfig, pathSubdirectory) => {
138
126
  resolve(finalTCPA);
139
127
  })
140
128
  .catch(error => {
141
- if (error.code === 'ECONNABORTED') {
129
+ if (error?.name === 'AbortError' || error?.name === 'TimeoutError') {
142
130
  console.log('Request timed out...using default TCPA language');
143
131
  } else {
144
132
  console.log('Response error...using default TCPA language');
@@ -162,8 +150,6 @@ const fetchTcpaFromSitegenie = async (config, tempConfig, pathSubdirectory) => {
162
150
 
163
151
  tempConfig.tcpaText = defaultTcpa.tcpaText;
164
152
  resolve(error);
165
- }).finally(() => {
166
- tcpaAxiosInstance.interceptors.response.eject(tcpaAxiosResponseInterceptor);
167
153
  });
168
154
  });
169
155
  };
@@ -193,13 +179,13 @@ function findVendorKey(config) {
193
179
  }
194
180
 
195
181
  async function embedBrandedDisplayName(apiUrl, consentCaptureObject, key, service) {
196
- let resp = '';
197
- const getBrandedDisplayName = await axios.get(apiUrl);
182
+ const getBrandedDisplayName = await fetch(apiUrl);
198
183
  if (getBrandedDisplayName.status !== 200) {
199
- throw new Error(`${resp.status}: Error while getting branded display name from HS Form Service`);
184
+ throw new Error(`${getBrandedDisplayName.status}: Error while getting branded display name from HS Form Service`);
200
185
  }
201
186
 
202
- const brandedDisplayName = getBrandedDisplayName.data.data[key];
187
+ const body = await getBrandedDisplayName.json();
188
+ const brandedDisplayName = body.data[key];
203
189
  consentCaptureObject.brandedConsentCapture.tcpaStart = consentCaptureObject.brandedConsentCapture.tcpaStart.replace(/<span data-branded-consent><\/span>/g, `<span data-branded-consent>${brandedDisplayName}</span>`);
204
190
  consentCaptureObject.brandedIncludeExclusivelyConsentCapture.tcpaStart = consentCaptureObject.brandedIncludeExclusivelyConsentCapture.tcpaStart.replace(/<span data-branded-consent><\/span>/g, `<span data-branded-consent>${brandedDisplayName}</span>`);
205
191
  consentCaptureObject.brandedIncludeServiceConsentCapture.tcpaStart = consentCaptureObject.brandedIncludeServiceConsentCapture.tcpaStart.replace(/<span data-branded-consent><\/span>/g, `<span data-branded-consent>${brandedDisplayName}</span>`).replace(/<span data-service><\/span>/g, `<span data-service>${service}</span>`);
@@ -207,20 +193,22 @@ async function embedBrandedDisplayName(apiUrl, consentCaptureObject, key, servic
207
193
 
208
194
  const getConsentCaptureLanguage = async function(config, tempConfig) {
209
195
  await new Promise((resolve) => {
210
- consentCaptureAxiosInstance.get(`https://${defaultSettings.nodeEnv}/quote/resources/mod-site/consent-capture/tcpa.json`)
196
+ fetchWithRetryConsent(`https://${defaultSettings.nodeEnv}/quote/resources/mod-site/consent-capture/tcpa.json`)
211
197
  .then(async resp => {
212
198
  if (resp.status !== 200) {
213
199
  throw new Error(`${resp.status}: Error while fetching tcpa.json`);
214
200
  }
215
201
 
216
- let consentCaptureObject = resp.data,
202
+ let consentCaptureObject = await resp.json(),
217
203
  service = config.service ? config.service.toLowerCase().replace('_', ' ') : config.primary_trade.toLowerCase().replace('_', ' ');
218
204
 
219
- const brandedSiteIdentifiers = await axios.get(`https://${defaultSettings.nodeEnv}/quote/resources/mod-site/data/branded-site-identifiers.json`);
220
- if (brandedSiteIdentifiers.status !== 200) {
221
- throw new Error(`${resp.status}: Error while fetching branded-site-identifiers.json`);
205
+ const brandedSiteIdentifiersResp = await fetch(`https://${defaultSettings.nodeEnv}/quote/resources/mod-site/data/branded-site-identifiers.json`);
206
+ if (brandedSiteIdentifiersResp.status !== 200) {
207
+ throw new Error(`${brandedSiteIdentifiersResp.status}: Error while fetching branded-site-identifiers.json`);
222
208
  }
223
209
 
210
+ const brandedSiteIdentifiersData = await brandedSiteIdentifiersResp.json();
211
+
224
212
  if (config.isBranded) {
225
213
  const websiteName = config.website_name.toLowerCase(),
226
214
  companyName = config.company_name,
@@ -228,13 +216,13 @@ const getConsentCaptureLanguage = async function(config, tempConfig) {
228
216
 
229
217
  let apiUrl = '';
230
218
 
231
- if (brandedSiteIdentifiers.data[websiteName] && (brandedSiteIdentifiers.data[websiteName].publicKey || brandedSiteIdentifiers.data[websiteName][companyName] && brandedSiteIdentifiers.data[websiteName][companyName].publicKey)) {
232
- const publicKey = brandedSiteIdentifiers.data[websiteName][companyName] ? brandedSiteIdentifiers.data[websiteName][companyName].publicKey : brandedSiteIdentifiers.data[websiteName].publicKey;
219
+ if (brandedSiteIdentifiersData[websiteName] && (brandedSiteIdentifiersData[websiteName].publicKey || brandedSiteIdentifiersData[websiteName][companyName] && brandedSiteIdentifiersData[websiteName][companyName].publicKey)) {
220
+ const publicKey = brandedSiteIdentifiersData[websiteName][companyName] ? brandedSiteIdentifiersData[websiteName][companyName].publicKey : brandedSiteIdentifiersData[websiteName].publicKey;
233
221
 
234
222
  apiUrl = `${apiDomain}utils/vendor-display-name?publicKey=${encodeURIComponent(publicKey)}`;
235
- const getBrandedDisplayName = await axios.get(apiUrl);
223
+ const getBrandedDisplayName = await fetch(apiUrl);
236
224
  if (getBrandedDisplayName.status !== 200) {
237
- throw new Error(`${resp.status}: Error while getting branded display name from HS Form Service`);
225
+ throw new Error(`${getBrandedDisplayName.status}: Error while getting branded display name from HS Form Service`);
238
226
  }
239
227
 
240
228
  await embedBrandedDisplayName(apiUrl, consentCaptureObject, publicKey, service);
@@ -245,11 +233,12 @@ const getConsentCaptureLanguage = async function(config, tempConfig) {
245
233
  profileApiUrl = `${profileApiDomain}v1/client-profiles/profiles?filters[matches][]=${vendorKey},QMP`;
246
234
 
247
235
  if (vendorKey !== null) {
248
- const getBrandedProfileId = await axios.get(profileApiUrl);
236
+ const getBrandedProfileId = await fetch(profileApiUrl);
249
237
  if (getBrandedProfileId.status !== 200) {
250
- throw new Error(`${resp.status}: Error while getting branded display name from HS Form Service`);
238
+ throw new Error(`${getBrandedProfileId.status}: Error while getting branded display name from HS Form Service`);
251
239
  }
252
- const brandedProfileId = getBrandedProfileId.data.data[0].profileId;
240
+ const profileBody = await getBrandedProfileId.json();
241
+ const brandedProfileId = profileBody.data[0].profileId;
253
242
  apiUrl = `${apiDomain}utils/vendor-display-name?profileId=${brandedProfileId}`;
254
243
 
255
244
  await embedBrandedDisplayName(apiUrl, consentCaptureObject, brandedProfileId, service);
@@ -262,8 +251,6 @@ const getConsentCaptureLanguage = async function(config, tempConfig) {
262
251
  }).catch(error => {
263
252
  console.error(error);
264
253
  process.exit(1);
265
- }).finally(() => {
266
- consentCaptureAxiosInstance.interceptors.response.eject(consentCaptureAxiosResponseInterceptor);
267
254
  });
268
255
  });
269
256
  };
@@ -1,23 +0,0 @@
1
- export const responseInterceptor = (instance) => {
2
- let retryCount = 0;
3
-
4
- const interceptorId = instance.interceptors.response.use(
5
- (response) => {
6
- return response;
7
- },
8
- (error) => {
9
- console.error('Response failed:', error.response.status);
10
-
11
- // Retry the request if the error code is 4xx or 5xx and retry count is less than 2
12
- if (error.response && error.response.status >= 400 && error.response.status < 600 && retryCount < 2) {
13
- retryCount++;
14
- console.log('Retrying request...', retryCount);
15
- return instance(error.config);
16
- }
17
-
18
- return Promise.reject(error);
19
- }
20
- );
21
-
22
- return interceptorId;
23
- };